735aaed648
CI / platformio (pull_request) Failing after 4m36s
Add cmd_exec.c / cmd_exec.h providing cmd_exec_handle() — a tolerant
cJSON-based dispatcher for structured ESP-NOW CMD frames per the D5
wire contract ({"op":"<verb>","a":{<args>}}, ≤200 bytes).
Supported ops (all logged):
screen — renders title/subtitle/symbol on an LVGL full-screen
overlay via bsp_display_lock; "pulse"/"flash" effect
tints the background blue.
play — logs the path + loop flag, emits an 880 Hz beep via
audio_play_tone() (no media_manager on box3_voice).
evt — logs event name (card→master direction, unusual here).
led — logs pattern (stub, no LED ring on box3_voice).
unknown — ESP_LOGW + ESP_ERR_NOT_SUPPORTED, no crash.
Wire-up in main.c:
on_mesh_text() callback installed via scenario_mesh_set_text_cb()
immediately after scenario_mesh_init(). Every SCENARIO_MESH_TEXT_CMD
frame is decoded and dispatched; EVT frames are logged and ignored.
cmd_exec.c added to CMakeLists.txt SRCS.
Channel fix in sdkconfig.defaults:
Document that CONFIG_ZACUS_WIFI_CHANNEL must match the master's
connected WiFi channel (lab: ch11) for ESP-NOW co-channel operation.
Tested on hardware (BOX-3 MAC 90:e5:b1:cc:05:f8, /dev/cu.usbmodem11301):
- Build: 2104/2104 targets, 0 errors, 0 warnings on new files.
- Flash: idf.py -p /dev/cu.usbmodem11301 flash — Done.
- Serial proof:
I (10115) zacus-voice: ESP-NOW CMD executor registered (op: screen/play/evt/led)
I (10115) cmd_exec: CMD op=screen t="ZACUS" u="" y="LA" e="pulse"
I (13327) cmd_exec: CMD op=play path="/spiffs/ambiance.wav" loop=0 (beep fallback)
W (16497) cmd_exec: CMD op="explode" unknown — ignored
All three via POST /game/espnow/cmd on master ({"ok":true,"status":"ESP_OK"}).
34 lines
1.2 KiB
C
34 lines
1.2 KiB
C
// cmd_exec.h — BOX-3 executor for structured ESP-NOW CMD frames (D5 contract).
|
|
//
|
|
// Wire format (SCENARIO_MESH_TEXT_CMD, ≤200 bytes):
|
|
// {"op":"<verb>","a":{<args>}}
|
|
//
|
|
// Supported ops:
|
|
// screen {"t":"title","u":"subtitle","y":"symbol","e":"effect"} — display on LCD
|
|
// play {"p":"<path>","l":0|1} — play media; falls back to beep + log if no file
|
|
// evt {"n":"<name>"} — log the event (future: relay to master)
|
|
// led {"p":"<pattern>"} — log the pattern (stub)
|
|
// <any> unknown op — log warn, ignore
|
|
//
|
|
// Tolerant by design: malformed JSON, missing keys, or unknown ops log a warning
|
|
// and return without crashing. Never asserts on network input.
|
|
|
|
#pragma once
|
|
|
|
#include <stddef.h>
|
|
#include "esp_err.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
// Parse and execute one CMD frame. `data` is the raw UTF-8 payload received via
|
|
// scenario_mesh text callback (NUL-terminated). Returns ESP_OK if the op was
|
|
// recognised and dispatched (even as a stub), ESP_ERR_INVALID_ARG on bad JSON
|
|
// or missing `op`, ESP_ERR_NOT_SUPPORTED for unknown ops (all logged, no crash).
|
|
esp_err_t cmd_exec_handle(const char *data, size_t len);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|