5 Commits

Author SHA1 Message Date
ea22f2f9db Fix async/await bugs found by headless E2E test
- Make get_client() sync (was async but did no async work). Callers
  that omitted await silently got a coroutine object instead of the
  SerialClient, causing "'coroutine' object has no attribute 'connect'"
  errors on every tool call.

- Fix esp32_connect: use get_client_or_none() for init check and
  client.event_queue.wait_for() for boot event (wait_event() didn't
  exist on SerialClient).

- Normalise Response.data to dict at parse time — firmware returns
  bare strings on some error paths, which broke .get() calls in tool
  error handlers.

- Remove stale await from ble.py (9 calls) and classic.py (4 calls).

Tested with dual-MCP headless claude session: 26/27 PASS.
2026-02-02 15:54:36 -07:00
0e7b8c2ef5 Fix docs to match UART0 firmware implementation
The firmware uses UART0 (via USB bridge) with ESP-IDF console disabled,
not UART1 on GPIO4/GPIO5 as originally documented. Updated both docs to
reflect the actual hardware-verified configuration:

- protocol-spec.md: UART peripheral description
- hardware-setup.md: wiring section, monitor section, sdkconfig table,
  troubleshooting steps
2026-02-02 15:38:20 -07:00
dc6078b296 Fix firmware for ESP-IDF v5.3 and hardware-verified operation
- Switch UART0 for protocol I/O (USB bridge), disable ESP-IDF console
- Wire all 21 command handlers into dispatch table (was only 4)
- Add configure command handler (name, io_cap, device_class)
- Add bt_classic_is_enabled()/bt_ble_is_enabled() for live status
- Fix cJSON_False misuse in get_status (type constant, not boolean)
- Fix esp_bt_gap_set_cod() to use esp_bt_cod_t bitfield struct
- Fix auth_cmpl.auth_mode → lk_type for ESP-IDF v5.3
- Replace deprecated esp_bt_dev_set_device_name with stack-specific API
- Remove unused bytes_to_hex, obsolete kconfig symbols
- Use large partition table (1.5MB) for dual-mode BT stack

Verified on ESP32-D0WD-V3 rev 3.1, /dev/ttyUSB4, all commands tested.
2026-02-02 15:30:54 -07:00
73d3d438a2 Expand test scenarios with step-by-step procedures
Rewrite test-scenarios.md with detailed per-step instructions
including exact tool calls, expected responses, negative test
cases, teardown procedures, and an environment variable reference.
2026-02-02 15:13:36 -07:00
6398a5223a ESP32 Bluetooth test harness MCP server
UART-controlled ESP32 peripheral for automated E2E Bluetooth testing.
Dual-mode (Classic BT + BLE) via Bluedroid on original ESP32.

Firmware (ESP-IDF v5.x, 2511 lines C):
- NDJSON protocol over UART1 (115200 baud)
- System commands: ping, reset, get_info, get_status
- Classic BT: GAP, SPP, all 4 SSP pairing modes
- BLE: GATTS, advertising, GATT service/characteristic management
- 6 device personas: headset, speaker, keyboard, sensor, phone, bare
- Event reporter: thread-safe async event queue to host

Python MCP server (FastMCP, 1626 lines):
- Async serial client with command/response correlation
- Event queue with wait_for pattern matching
- Tools: connection, configure, classic, ble, persona, events
- MCP resources: esp32://status, esp32://events, esp32://personas

Tests: 74 unit tests passing, 5 integration test stubs (skip without hardware)
2026-02-02 15:12:28 -07:00