Реалізація OTA-оновлення прошивки IoT-пристроїв через мобільний додаток
Ви запустили IoT-пристрої в полі і виявили критичний баг у прошивці. Без OTA-оновлення вам довелося б відкликати всю партію — це тижні терміну та мільйонні втрати. Ми допоможемо реалізувати OTA-оновлення через мобільний додаток: під ключ, від вибору протоколу до деплою в App Store та Google Play. Наш досвід — 5+ років в embedded та мобільній розробці, десятки успішних проєктів.
OTA (Over-The-Air) оновлення прошивки — критично важлива функція для будь-якого IoT-продукту. Баги в прошивці, нові протоколи, патчі безпеки — все це потрібно доставляти на пристрої без фізичного доступу до них. Мобільний додаток тут або ініціює оновлення, або служить транспортом для передачі прошивки безпосередньо через BLE.
Питання: Як вибрати сценарій OTA: Cloud чи BLE?
Cloud OTA: пристрій самостійно завантажує прошивку з сервера, коли знаходиться в Wi-Fi. Мобільний додаток тільки повідомляє користувача про доступне оновлення та показує прогрес. Логіка оновлення — на стороні прошивки (ESP-IDF OTA, Mender, Hawkbit).
BLE OTA: прошивка завантажується на телефон, телефон передає її на пристрій через BLE. Використовується коли пристрій не має прямого виходу в інтернет або коли потрібен жорсткий контроль над процесом оновлення.
| Критерій | BLE OTA | Cloud OTA |
|---|---|---|
| Вимагає Wi-Fi на пристрої | Ні | Так |
| Контроль процесу | Високий | Середній |
| Складність реалізації | Висока (кастомний протокол) | Середня (використання готових SDK) |
| Ризик переривання | Вищий (обрив BLE) | Нижчий (HTTP resume) |
| Швидкість передачі | 50-80 кб/с | Залежить від мережі |
BLE OTA: DFU для Nordic nRF
Для пристроїв на nRF51/nRF52 — Nordic DFU (Device Firmware Update). Офіційна бібліотека від Nordic Semiconductor:
// build.gradle implementation 'no.nordicsemi.android:dfu:2.3.0' // Запуск DFU val starter = DfuServiceInitiator(deviceAddress) .setDeviceName(deviceName) .setKeepBond(true) .setForceDfu(false) .setPacketsReceiptNotificationsEnabled(true) .setNumberOfPackets(12) // PRN - баланс швидкості та надійності .setZip(firmwareUri) // .zip з прошивкою та init packet val controller = starter.start(context, DfuService::class.java) setPacketsReceiptNotificationsEnabled(true) + setNumberOfPackets(12) — пристрій підтверджує кожні 12 пакетів. Без PRN при втраті пакета все доводиться починати заново. З PRN — відновлення з останньої підтвердженої позиції.
DFU-бібліотека запускає DfuService як foreground service — користувач може згорнути додаток, оновлення продовжиться. Прогрес через DfuProgressListenerHelper:
DfuProgressListenerHelper.registerProgressListener(this, object : DfuProgressListener { override fun onDfuProgressChanged(deviceAddress: String, percent: Int, speed: Float, avgSpeed: Float, currentPart: Int, partsTotal: Int) { updateProgress(percent) } override fun onDfuCompleted(deviceAddress: String) { onUpdateSuccess() } override fun onError(deviceAddress: String, error: Int, errorType: Int, message: String) { onUpdateFailed(message) } }) Типова швидкість DFU: 50–80 кб/с для nRF52840. Прошивка 200 кб — близько 3 хвилин.
ESP32 OTA через BLE
Для ESP32 — esp_ota_ops на стороні прошивки + кастомний BLE-сервіс для прийому даних. Espressif не надає готовий BLE DFU SDK (на відміну від Nordic), тому протокол потрібно реалізовувати самостійно або використовувати бібліотеку esp-idf-ble-ota.
Базова схема: телефон відправляє прошивку частинами по MTU-3 байти. Пристрій збирає прошивку в OTA-буфер (esp_ota_begin, esp_ota_write, esp_ota_end), потім перезавантажується з новим образом. При помилці — rollback на попередню версію через esp_ota_mark_app_invalid_rollback_and_reboot().
// Розбивка прошивки на частини та відправка val chunkSize = mtu - 3 val chunks = firmware.toList().chunked(chunkSize) chunks.forEachIndexed { index, chunk -> writeCharacteristic(firmwareDataCharacteristic, chunk.toByteArray()) // Чекати ACK від пристрою перед наступною частиною awaitAck() updateProgress((index + 1) * 100 / chunks.size) } Важно: ніколи не починати OTA при заряді телефона нижче 20% та слабкому BLE-сигналі. Обрив у середині прошивки — потенційно цеглина, якщо на пристрої немає механізму rollback.
Питання: Яку роль відіграє мобільний додаток у Cloud OTA?
При cloud OTA телефон — тільки UI. Користувач бачить повідомлення «Доступне оновлення 2.1.0», натискає «Оновити», слідкує за прогресом.
Прогрес оновлення пристрій відправляє через MQTT або WebSocket. Статуси: idle → downloading (з відсотком) → applying → rebooting → updated / failed.
Не показувати нескінченний спіннер. Оновлення може зайняти 5–15 хвилин (завантаження + запис flash). Потрібен конкретний прогрес з етапами. Після перезавантаження пристрій з'явиться в мережі з новою версією прошивки — це потрібно відобразити в UI негайно.
Безпека OTA
Прошивка має бути підписана — пристрій верифікує підпис перед застосуванням. RSA-2048 або ECDSA-256. При cloud OTA — HTTPS з certificate pinning для захисту від MITM. Для BLE OTA — init packet Nordic DFU вже містить hash та підпис прошивки.
Без верифікації підпису будь-який зловмисник з доступом до BLE може залити шкідливу прошивку. Ми гарантуємо включення підпису прошивки у всіх проєктах — це базовий захист.
Що входить у роботу з реалізації OTA
- Впровадження DFU-модуля для Android/iOS з підтримкою обраного протоколу (Nordic DFU, ESP32 або кастомний).
- Розробка бекенд-частини для Cloud OTA (API версій, управління прошивками).
- Інтеграція прогресу та сповіщень у мобільний додаток.
- Документація зі збірки та підписання прошивки, а також процесу оновлення.
- Тестування на реальних пристроях та підготовка до публікації в стори.
- Консультація з безпеки OTA та допомога в налаштуванні серверної інфраструктури.
Реалізація BLE OTA з Nordic DFU: 2–3 тижні. Cloud OTA UI з прогрес-моніторингом: 1–2 тижні. Кастомний ESP32 BLE OTA протокол: 3–5 тижнів. Терміни розраховуються індивідуально під ваш проєкт. Напишіть нам — оцінимо задачу та запропонуємо рішення.







