chore: move firmware skills in-repo + AGENTS.md
- Migrates tactility-firmware and tactility-bluetooth from ~/.hermes/skills/ into .claude/skills/ for repo co-location - Adds AGENTS.md with local workstation context, board table, board-direct build rule, Hermes PYTHONPATH pitfall, common Tactility pitfalls, and in-repo skill index Refs: personal Gitea mirror
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
# WebServer + DevelopmentService Collision Debugging
|
||||
|
||||
Session: 2026-07-11 — Dashboard server started but MCP tools 404, dev service blocked.
|
||||
|
||||
## Symptoms
|
||||
- Dashboard (port 80) loads, but POST /api/mcp returns 404 even with mcpEnabled=true
|
||||
- Development service (6666 /info) not reachable
|
||||
- MCP screen not appearing on RLCD board (Waveshare 4.2" monochrome ST7305)
|
||||
|
||||
## Root Causes Found
|
||||
|
||||
### 1. httpd ctrl_port collision
|
||||
`HttpServer::startInternal()` used `HTTPD_DEFAULT_CONFIG()` → ctrl_port 32768 fixed for all instances.
|
||||
When WebServer (80) + DevServer (6666) start near-simultaneously (service manager dispatches), second bind fails → `httpd_start` returns error → `httpServer` stays null → handlers never registered.
|
||||
Fix: unique ctrl_port per server: `32768 + (port % 1000)` → 80→32848, 6666→33434.
|
||||
|
||||
Src: `Tactility/Source/network/HttpServer.cpp`
|
||||
|
||||
### 2. max URI handlers too low
|
||||
ESP-IDF default CONFIG_HTTPD_MAX_URI_HANDLERS=8.
|
||||
WebServer registers 7 handlers: `/`, `/filebrowser`, `/fs/*` GET, `/fs/*` POST, `/admin/*`, `/api/*` GET, `/api/*` POST, `/api/*` PUT, `/*` = 7, plus 2 internal slots → config.max_uri_handlers = 9.
|
||||
If Kconfig max 8 < 9, `httpd_start` fails or later `httpd_register_uri_handler` fails → "no slots left".
|
||||
Fix: `Buildscripts/sdkconfig/default.properties` → `CONFIG_HTTPD_MAX_URI_HANDLERS=20`.
|
||||
|
||||
### 3. DisplayIdle early return killed MCP on RLCD
|
||||
`D3919344` added:
|
||||
```cpp
|
||||
if (!supportsBacklightDuty()) return true;
|
||||
```
|
||||
in `onStart()` — disables timer + settings load for ST7305 (no backlight fn). `startMcpScreensaver()` depends on settings + timer for update/auto-off.
|
||||
Fix: always load settings + start timer; only skip auto-backlight logic via existing `if (supportsBacklightDuty())` guard in `tick()`.
|
||||
|
||||
Files: `Tactility/Source/service/displayidle/DisplayIdle.cpp:235-250`, `303-353`
|
||||
|
||||
### 4. Video stream task overflow
|
||||
Stack 4096 + SPIRAM allocs + LVGL lock + socket loops → stack overflow → heap corruption blocking other tasks.
|
||||
Also tight loop `vTaskDelay(5)` even idle.
|
||||
Fix: 8192 + idle delay 50ms, busy 5ms.
|
||||
|
||||
## Verification Commands
|
||||
```bash
|
||||
source ~/esp/esp-idf/export.sh
|
||||
cd firmware
|
||||
python device.py waveshare-esp32-s3-rlcd --dev
|
||||
idf.py build
|
||||
idf.py -p /dev/cu.usbmodem101 flash monitor
|
||||
# Monitor logs:
|
||||
# - Started on port 80 (ctrl_port 32848)
|
||||
# - Started on port 6666 (ctrl_port 33434)
|
||||
# - Mono TCP Video stream server started on port 8081
|
||||
# - Color TCP Video stream server started on port 8083
|
||||
# - Monochrome/RLCD detected: idle timer will run but auto-backlight off disabled
|
||||
curl http://<ip>/api/sysinfo # public
|
||||
curl -X POST http://<ip>/api/mcp -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
|
||||
curl http://<ip>:6666/info
|
||||
```
|
||||
|
||||
## Related Incidents
|
||||
- Upstream #547 merged 2026-07-04 changed settings load to check isFile first — more correct but didn't cause this.
|
||||
- Board mis-ID: user has both ES3C28P color (240x320) and Waveshare RLCD mono (400x300). Wrong sdkconfig → wrong display driver → blank screen misattributed to MCP bug. Always verify `grep CONFIG_TT_DEVICE_ID sdkconfig`.
|
||||
Reference in New Issue
Block a user