From 1f9d598cbac7025120f244bfa3acb157d6adcaca Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 5 Jul 2026 17:37:18 -0400 Subject: [PATCH] Fix MJ-18: NACK unsupported partial-update (0x76) and buzzer (0x77) commands The BLE client can send partial-update (0x76) and buzzer (0x77) commands that the Silabs firmware does not implement. Both fell through the dispatch switch's default case, which only printed "unknown cmd" and returned nothing. The client then blocked waiting for an ACK until its timeout expired. Reply to both opcodes with a NACK frame {0xFF, cmd_low, 0x07, 0x00} so the client fails fast: for 0x76 this matches parse_nack() and triggers a clean fallback to a full upload; for 0x77 validate_ack_response() rejects it immediately as a non-ACK. Genuinely unknown opcodes keep the existing default (print + drop). Behavior for internal/no-response opcodes is unchanged. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_012g2e8mr132vcizx92WsgiR --- opendisplay_pipe.c | 11 +++++++++++ opendisplay_protocol.h | 3 +++ 2 files changed, 14 insertions(+) diff --git a/opendisplay_pipe.c b/opendisplay_pipe.c index 720d15c..509418b 100644 --- a/opendisplay_pipe.c +++ b/opendisplay_pipe.c @@ -1090,6 +1090,17 @@ static void dispatch(uint8_t connection, uint16_t cmd, const uint8_t *payload, u case CMD_DIRECT_WRITE_END: handle_direct_write_end(connection, payload, payload_len); break; + case CMD_DIRECT_WRITE_PARTIAL_START: + case CMD_BUZZER_ACTIVATE: { + /* Not implemented on Silabs, but the client sends these and blocks + * waiting for a reply. Emit a NACK so it fails fast instead of timing + * out: {0xFF, cmd_low, err, 0x00} matches the client's parse_nack() + * (0x76 falls back to a full upload; 0x77 raises promptly). Error code + * 0x07 = "unsupported" (ERR_PARTIAL_UNSUPPORTED on the client). */ + uint8_t nack[] = { 0xFFu, (uint8_t)(cmd & 0xFFu), 0x07u, 0x00u }; + pipe_send(connection, nack, sizeof(nack)); + break; + } default: printf("[OD] unknown cmd 0x%04X\r\n", (unsigned)cmd); break; diff --git a/opendisplay_protocol.h b/opendisplay_protocol.h index a0eb1ad..61a3c3e 100644 --- a/opendisplay_protocol.h +++ b/opendisplay_protocol.h @@ -13,6 +13,9 @@ #define CMD_DIRECT_WRITE_END 0x0072u #define CMD_LED_ACTIVATE 0x0073u #define CMD_LED_STOP 0x0075u +/* Client-visible but unimplemented on Silabs; dispatch NACKs them (see dispatch()) */ +#define CMD_DIRECT_WRITE_PARTIAL_START 0x0076u +#define CMD_BUZZER_ACTIVATE 0x0077u /* NFC: sub byte0 0=read, 1=write (+rec_type,len16,payload), 0x10/0x11/0x12=chunked write; rec_type OD_NFC_REC_* */ #define CMD_NFC_ENDPOINT 0x0082u #define CMD_REBOOT 0x000Fu