From 3bfeff29bd206531dc400e6a182e66e54c0de9c5 Mon Sep 17 00:00:00 2001 From: kunthawat Date: Sat, 3 Oct 2026 16:36:41 +0700 Subject: [PATCH] =?UTF-8?q?docs:=20Phase=202=20=E2=80=94=20firmware=20hand?= =?UTF-8?q?shake/OTA=20spec=20verified=20from=20source,=20build=20in=20pro?= =?UTF-8?q?gress?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plan.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/plan.md b/plan.md index 95f8b8e..487fcd7 100644 --- a/plan.md +++ b/plan.md @@ -62,3 +62,21 @@ Status: **Phase 1 complete** — testable skeleton green. Next (voice-server): r - Push fixed (Cloudflare cleared): b00312c + e91d185 on origin/main. - Module-level app + 0.0.0.0 bind; live wss://zhi.moreminimore.com handshake OK. - Device flashed (xiaozhi v2.5.0), COM3. OTA config → device next. + +## Phase 2 (2026-10-03) — firmware-compatible bridge + pre-flash config build +CON-003 OVERRIDE in force: build xiaozhi-esp32 v2.5.0 with ESP-IDF, set Kconfig BEFORE flash (no source rewrite). + +- [x] Verified firmware handshake from source (`main/protocols/websocket_protocol.cc`, `main/ota.cc`): + - WS auth via HTTP headers `Authorization: Bearer ` + `Device-Id` (= MAC) + `Protocol-Version`; hello frame carries NO auth. + - Server hello reply MUST have `transport:"websocket"` + `session_id` + `audio_params` (ParseServerHello). + - OTA: device POSTs `CONFIG_OTA_URL`; response `{websocket:{url,token,version}, server_time:{timestamp,timezone_offset(min)}, firmware:{version[,url]}}`. `server_time` is an OBJECT (not scalar). No `firmware.url` → no forced OTA update (has_new_version_ stays false). + - Firmware sends raw 20ms opus frames after hello (no per-turn JSON markers); device-side VAD. +- [x] Bridge: header auth (frame fallback kept), server hello `transport=websocket`+session_id, `/ota` GET+POST returning the exact contract, config.yaml device by MAC + ota block. **21 tests pass.** +- [x] ESP-IDF v6.1 installed; `export`/`set-target esp32s3` OK. +- [x] `sdkconfig.defaults` (appended to upstream): BOARD_TYPE_SPOTPEAR_ESP32_S3_1_54_MUMA=y, OTA_URL="https://zhi.moreminimore.com/ota", LANGUAGE_TH_TH=y. +- [~] Firmware build RUNNING (proc, log esp/xiaozhi_build.log). Generated sdkconfig CONFIRMED: OTA_URL / LANGUAGE_TH_TH=y / ZH_CN unset / MUMA board all set. +- [ ] Flash built bin to COM3 (esptool, after build). +- [ ] Device end-to-end: OTA fetch OK → WS connect → converse. + +Known gap (converse path): websocket receive loop calls run_turn per binary frame; real device streams continuous 20ms audio → needs VAD-driven end-of-speech accumulation before STT. Session.feed_audio/end_of_speech exist; wire in loop. Onboarding (OTA+handshake) is done — converse loop is the remaining runtime gap. +Next action: finish build → flash → live device connect test.