Files
Mira_Firmware_Loader/docs/api_flash_docs.md

5.5 KiB

Tài liệu Kỹ thuật: Flash Firmware qua LuCI API (core/api_flash.py)

Module api_flash.py tự động hoá quá trình nạp firmware cho thiết bị OpenWrt thông qua giao diện web LuCI HTTP. Được dùng trong chế độ Nạp Mới FW với method "api".


1. Kiến Trúc — Vai Trò File

File Vai trò
core/api_flash.py Logic flash 3 bước (login → upload → proceed) qua LuCI
core/flash_new_worker.py NewFlashThread — dispatch tới flash_device_api() khi method="api"
main.py UI PyQt6, chọn mode/method, truyền tham số vào worker

2. Sơ Đồ Luồng

flowchart TD
    A[NewFlashThread - method=api] --> B[flash_device_api]

    B --> S1["STEP 1: Login\nGET /cgi-bin/luci — phát hiện field name\nPOST username=root & password="]
    S1 --> C1{Thành công?}
    C1 -->|sysauth cookie + stok| S2
    C1 -->|HTTP 403| F1["FAIL: Login denied (403)"]
    C1 -->|Không có session| F2["FAIL: Login failed — no session"]

    S2["STEP 2: Upload Firmware\nPOST /flashops\nmultipart: image=firmware.bin"] --> 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"] --> C3{Response?}
    C3 -->|Connection dropped / Timeout| R["DONE ✅ — Device đang reboot"]
    C3 -->|200 OK| R

3. Chi Tiết Kỹ Thuật HTTP

Step 1 — Login

GET  http://{IP}/cgi-bin/luci        → Lấy HTML login, phát hiện field name
POST http://{IP}/cgi-bin/luci        → Đăng nhập

Tự động phát hiện field name tương thích:

Phiên bản Field
Barrier Breaker 14.07 username / password
OpenWrt mới hơn luci_username / luci_password

Lấy session: stok token được tìm tuần tự trong URL → body HTML → redirect history. Cookie sysauth là fallback nếu không có stok.

Step 2 — Upload Firmware

POST http://{IP}/cgi-bin/luci/;stok={TOKEN}/admin/system/flashops
Content-Type: multipart/form-data

image = firmware.bin   (file upload)
keep  = (không gửi)    → bỏ tích "Keep Settings" = Clean Flash

Thành công khi response trả về trang "Flash Firmware - Verify" chứa từ khoá verify + proceed.

Step 3 — Confirm (Proceed)

POST http://{IP}/cgi-bin/luci/;stok={TOKEN}/admin/system/flashops

step = 2
keep = (empty)

Đứt kết nối = Thành công: Device bắt đầu flash → SSH/HTTP request bị drop là hành vi mong muốn. ConnectionErrorReadTimeout đều được bắt và trả về "DONE".


4. Bảng Status UI

Icon Status Điều kiện
Logging in... Đang POST login vào LuCI
Uploading firmware... Đang upload file .bin
Confirming (Proceed)... Đang gửi lệnh xác nhận flash
Rebooting... Chờ device khởi động lại
DONE Flash thành công
DONE (rebooting) Flash thành công, timeout khi chờ response
FAIL: Cannot connect Không kết nối được (sai IP / khác mạng)
FAIL: Login denied (403) Sai mật khẩu LuCI
FAIL: Login failed — no session Không có cookie/token sau login
FAIL: Upload HTTP xxx Server trả 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 thiết bị
FAIL: Upload ignored by server Server không xử lý file (sai form field)
FAIL: Unexpected response after upload Không nhận được trang Verify

5. Xử Lý Song Song

NewFlashThread (QThread)
  └── ThreadPoolExecutor (max_workers = N)
        ├── Thread 1 → flash_device_api(IP_1)
        ├── Thread 2 → flash_device_api(IP_2)
        └── Thread N → flash_device_api(IP_N)
Concurrent devices Ý nghĩa
10 (mặc định) Flash 10 thiết bị song song
0 Unlimited — flash tất cả cùng lúc
1 Tuần tự — từng thiết bị một

Mỗi thiết bị có requests.Session() riêng — không bị lẫn cookie/token.