This shows you the differences between two versions of the page.
|
iothings:laboratoare:2025:lab10 [2025/12/06 19:39] dan.tudose |
iothings:laboratoare:2025:lab10 [2025/12/06 21:35] (current) dan.tudose |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== Lab 10. Secure OTA ====== | ====== Lab 10. Secure OTA ====== | ||
| - | This lab shows how to implement **real remote firmware updates from a browser** for an ESP32-C6 board using **PlatformIO + pioarduino** and an **Async Web OTA** page powered by **ElegantOTA**. | + | Over-the-air (OTA) updates are a core capability of modern IoT devices, enabling firmware improvements, bug fixes, and security patches without physical access to the hardware. In real deployments, devices may be installed in hard-to-reach locations or embedded in larger systems, so requiring a USB connection for every update becomes impractical. OTA solves this by allowing a device to receive new firmware over a network, reducing maintenance costs and shortening the time between discovering an issue and delivering a fix. |
| + | |||
| + | Designing OTA for embedded systems also introduces engineering trade-offs that are less visible in traditional software. Devices must update safely despite limited flash, intermittent connectivity, and the risk of power loss mid-installation. A robust OTA approach typically uses separate firmware slots so a known-good image remains available if an update fails. Just as importantly, OTA is part of a security boundary: update mechanisms must ensure that only authentic, intact firmware can be installed, or they can become a high-impact attack path in an IoT fleet. | ||
| + | |||
| + | {{ :iothings:laboratoare:2025:ota1.jpg?800 |}} | ||
| + | |||
| + | ====== Simple OTA ====== | ||
| + | |||
| + | This first example shows you how to implement **real remote firmware updates from a browser** for an ESP32-C6 board using **PlatformIO + pioarduino**. | ||
| You will: | You will: | ||
| Line 9: | Line 17: | ||
| * verify success with a visible NeoPixel behavior change, | * verify success with a visible NeoPixel behavior change, | ||
| * document basic threat-model thinking. | * document basic threat-model thinking. | ||
| - | |||
| ===== Learning outcomes ===== | ===== Learning outcomes ===== | ||
| Line 21: | Line 28: | ||
| - Identify key security risks for OTA and apply simple mitigations. | - Identify key security risks for OTA and apply simple mitigations. | ||
| - | |||
| - | ===== Concept snapshot ===== | ||
| **What you are building:** | **What you are building:** | ||
| Line 129: | Line 134: | ||
| * exposes a **/status** JSON endpoint. | * exposes a **/status** JSON endpoint. | ||
| + | {{ :iothings:laboratoare:2025:ota2.jpg?800 |}} | ||
| ===== Learning outcomes ===== | ===== Learning outcomes ===== | ||
| Line 160: | Line 166: | ||
| 4. Record telemetry in NVS | 4. Record telemetry in NVS | ||
| + | ===== Platformio Setup ===== | ||
| + | You will need to edit your platformio.ini file to this: | ||
| + | |||
| + | <code ini platformio.ini> | ||
| + | [env:sparrow_c6] | ||
| + | platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip | ||
| + | board = esp32-c6-devkitm-1 | ||
| + | framework = arduino | ||
| + | monitor_speed = 115200 | ||
| + | |||
| + | ; Use OTA-capable partition table | ||
| + | board_build.partitions = sparrow_ota_4mb.csv | ||
| + | |||
| + | ; Optional but often helpful | ||
| + | build_flags = | ||
| + | -D CORE_DEBUG_LEVEL=1 | ||
| + | -D ARDUINO_USB_MODE=1 | ||
| + | -D ARDUINO_USB_CDC_ON_BOOT=1 | ||
| + | -D ESP32_C6_env | ||
| + | |||
| + | lib_deps = | ||
| + | ESP32Async/AsyncTCP@^3.4.9 | ||
| + | ESP32Async/ESPAsyncWebServer@^3.9.2 | ||
| + | adafruit/Adafruit NeoPixel | ||
| + | bblanchon/ArduinoJson | ||
| + | |||
| + | |||
| + | lib_ignore = | ||
| + | AsyncTCP_RP2040W | ||
| + | |||
| + | </code> | ||
| ===== Part A — Update manifest ===== | ===== Part A — Update manifest ===== | ||
| Line 212: | Line 249: | ||
| <code> | <code> | ||
| - | python -m http.server 8000 | + | python3 -m http.server 8000 |
| </code> | </code> | ||
| Line 221: | Line 258: | ||
| ===== Part B — Device firmware (pull OTA + hash + telemetry) ===== | ===== Part B — Device firmware (pull OTA + hash + telemetry) ===== | ||
| - | Create/replace ''src/main.cpp'' with the template below. | + | Create/replace ''src/main.cpp'' with this [[iothings:laboratoare:2025_code:lab10_3|template]]. |
| **You must edit:** | **You must edit:** | ||
| Line 237: | Line 274: | ||
| * ''FW_VERSION = "1.0.1"'' | * ''FW_VERSION = "1.0.1"'' | ||
| - | Also update the homepage text so the new firmware is easy to confirm. | + | Also update the homepage text or the blink color of the Neopixel so the new firmware is easy to confirm. |
| 3) Build in PlatformIO and copy: | 3) Build in PlatformIO and copy: | ||
| Line 257: | Line 294: | ||
| 6) Reboot the device. | 6) Reboot the device. | ||
| - | 7) Open ''http://<device-ip>/status'' | + | 7) Open ''http://DEVICE-IP/status'' and confirm telemetry fields exist. |
| - | + | ||
| - | Confirm telemetry fields exist. | + | |