# Tài liệu Flash Firmware — IoT Firmware Loader ## Tổng quan Ứng dụng tự động hóa quá trình nạp firmware cho thiết bị **OpenWrt Barrier Breaker 14.07** thông qua giao diện web **LuCI**. Thay vì thao tác thủ công trên trình duyệt, ứng dụng thực hiện 3 bước HTTP tự động cho mỗi thiết bị. --- ## Luồng hoạt động ```mermaid flowchart TD A[Chọn Firmware .bin] --> B[Scan LAN] B --> C[Hiển thị danh sách thiết bị] C --> D{Chọn thiết bị ☑} D --> E[Nhấn Flash Selected Devices] E --> F[FlashThread chạy background] F --> G["ThreadPoolExecutor\n(max_workers = N)"] G --> H1[Device 1 → flash_device] G --> H2[Device 2 → flash_device] G --> H3[Device N → flash_device] H1 & H2 & H3 --> I[All Done → Thông báo] ``` ### Chi tiết `flash_device()` cho mỗi thiết bị ```mermaid flowchart TD S1["STEP 1: Login\nGET /cgi-bin/luci\nPOST username=root, password=empty"] --> C1{Thành công?} C1 -->|Có cookie sysauth + stok| S2 C1 -->|403 Denied| F1["FAIL: Login denied (403)"] C1 -->|Không có session| F2["FAIL: Login failed — no session"] S2["STEP 2: Upload Firmware\nPOST /flashops\nField: image=firmware.bin\nkeep=KHÔNG gửi (bỏ tích)"] --> C2{Response?} C2 -->|Trang Verify + Proceed| S3 C2 -->|HTTP ≠ 200| F3["FAIL: Upload HTTP xxx"] C2 -->|invalid image| F4["FAIL: Invalid firmware image"] C2 -->|unsupported| F5["FAIL: Firmware not compatible"] C2 -->|Vẫn hiện form upload| F6["FAIL: Upload ignored by server"] S3["STEP 3: Proceed\nPOST step=2, keep=empty\nXác nhận flash"] --> C3{Response?} C3 -->|200 Flashing...| R["DONE ✅\nThiết bị đang reboot"] C3 -->|Connection dropped| R C3 -->|Read timeout| R ``` --- ## Bảng Status ### Status trên cột "Status" trong bảng thiết bị | Icon | Status | Điều kiện hiển thị | | ---- | ---------------------------------------- | ------------------------------------------------------------- | | — | `READY` | Sau khi scan, thiết bị chưa được flash | | ⏳ | `Logging in...` | Đang POST login vào LuCI | | ⏳ | `Uploading firmware...` | Đang upload file .bin (~30MB) lên thiết bị | | ⏳ | `Confirming (Proceed)...` | Đã upload xong, đang gửi lệnh xác nhận flash | | ⏳ | `Rebooting...` | Thiết bị đang reboot sau khi flash | | ✅ | `DONE` | Flash thành công, thiết bị đang khởi động lại | | ✅ | `DONE (rebooting)` | Flash thành công nhưng timeout khi chờ response (bình thường) | | ❌ | `FAIL: Cannot connect` | Không kết nối được tới thiết bị (sai IP, khác mạng) | | ❌ | `FAIL: Login denied (403)` | Thiết bị từ chối đăng nhập (sai mật khẩu) | | ❌ | `FAIL: Login failed — no session` | Login không trả về cookie hoặc token | | ❌ | `FAIL: Upload HTTP xxx` | Server trả mã lỗi HTTP khi upload | | ❌ | `FAIL: Invalid firmware image` | File firmware không hợp lệ | | ❌ | `FAIL: Firmware not compatible` | Firmware không tương thích với thiết bị | | ❌ | `FAIL: Upload ignored by server` | Server nhận file nhưng không xử lý (sai form field) | | ❌ | `FAIL: Unexpected response after upload` | Không nhận được trang xác nhận Verify | --- ## Chi tiết kỹ thuật HTTP ### Step 1: Login ``` GET http://{IP}/cgi-bin/luci → Lấy trang login, phát hiện field name POST http://{IP}/cgi-bin/luci → Gửi username=root&password= ``` | Kết quả | Điều kiện | | -------------- | ------------------------------------------------------------------ | | **Thành công** | Response chứa `sysauth` cookie VÀ/HOẶC `stok` token trong URL/body | | **Thất bại** | HTTP 403, hoặc không có cookie/token | **Field names tự động phát hiện:** - OpenWrt Barrier Breaker 14.07: `username` / `password` - OpenWrt mới hơn: `luci_username` / `luci_password` ### Step 2: Upload Firmware ``` POST http://{IP}/cgi-bin/luci/;stok={TOKEN}/admin/system/flashops Content-Type: multipart/form-data Fields: image = [firmware.bin] (file upload) keep = (KHÔNG gửi) (bỏ tích Keep Settings) ``` | Kết quả | Điều kiện | | -------------- | ----------------------------------------------------------------------- | | **Thành công** | Response chứa "Flash Firmware - Verify" + "Proceed" + checksum | | **Thất bại** | Response chứa "invalid image", "unsupported", hoặc vẫn hiện form upload | ### Step 3: Proceed (Xác nhận) ``` POST http://{IP}/cgi-bin/luci/;stok={TOKEN}/admin/system/flashops Fields: step = 2 keep = (empty string) ``` | Kết quả | Điều kiện | | -------------- | ------------------------------------------------------------------------------- | | **Thành công** | Response "The system is flashing now" HOẶC connection bị ngắt (thiết bị reboot) | | **Thất bại** | Hiếm khi xảy ra — nếu đã qua Step 2 thì Step 3 gần như luôn thành công | --- ## Xử lý song song ``` FlashThread (QThread - background) └── ThreadPoolExecutor (max_workers = N) ├── Thread 1 → flash_device(IP_1) ├── Thread 2 → flash_device(IP_2) ├── ... └── Thread N → flash_device(IP_N) ``` | Config | Giá trị | Ý nghĩa | | ------------------------- | --------- | ------------------------------ | | Concurrent devices = `10` | Mặc định | Flash 10 thiết bị song song | | Concurrent devices = `0` | Unlimited | Flash tất cả thiết bị cùng lúc | | Concurrent devices = `1` | Tuần tự | Flash từng thiết bị một | **Mỗi thiết bị có session HTTP riêng** → không bị lẫn cookie/token giữa các thiết bị. --- ## Files liên quan | File | Chức năng | | --------------- | --------------------------------------------- | | `flasher.py` | Logic flash 3 bước (login → upload → proceed) | | `main.py` | UI PyQt6, FlashThread, quản lý song song | | `debug_full.py` | Script debug — chạy 3 bước với log chi tiết | | `scanner.py` | Scan mạng LAN tìm thiết bị | """, "Complexity": 3, "Description": "Created flash documentation file with workflow diagrams, status conditions, HTTP details, and parallel processing explanation.", "EmptyFile": false, "IsArtifact": false, "Overwrite": false, "TargetFile": "/Users/nguyennhatminh/Documents/file code/Smatec/iot_fw_loader/FLASH_DOC.md