Skip to content

Commit dbc1ddf

Browse files
committed
fix(diag): port the link hexdump to ameba, fix a CodeQL loop, ship v1.3.1
Node 14 had no way to see the "77" request byte -- the `link` diagnostic that solved this on the esp32 half was esp32-only, so the kitchen unit was being debugged blind. Ported to the ameba console; `help` now lists `link` and it hexdumps the last 0x1E LINK reply with payload[4] and the masked link_req. CodeQL (PR #68) flagged the hexdump loop in both consoles: `k < i + 16` promotes the RHS to int while k is uint8_t, so once i+16 passed 255 the counter could never reach it and the loop would not terminate. Bounded at 40 bytes today, so unreachable in practice, but it is a real defect in new code -- int counters throughout. ## Correction: break-glass does NOT apply on AmebaZ2 A previous commit and the session memory claimed the HTTP break-glass path now applies on node 14. That was WRONG, and this commit is the disproof. Three triggers this evening, each serving a genuinely different binary: 18:54 fetch ok, rebooted, still running the old image 19:02 fetch ok, rebooted, still running the old image 19:09 fetch ok, rebooted, still running the old image (FWHS serial 11401 > 11400) The third carried a HIGHER serial, which rules out the "equal serial so the bootloader kept the old slot" explanation. It fetches, it reboots, and it silently comes back on the old image. The earlier "it applies now" conclusion came from a test that served the SAME version the device was already running: a successful apply and a no-op are indistinguishable that way, and the reboot was mistaken for proof. The repo's original note was right all along. Verify by a CHANGED softwareVersion or a changed console `help` list -- never by a reboot. Practical consequence: node 14 had not been running ANY of the "77" fixes, which is exactly what the bench test showed. Matter OTA applied v10301 first try and the fixes are now live. Version 1.3.0 -> 1.3.1 (int 10301). Node 14 verified on 10301: `link` present, avail=True, endpoints {0..10}, subscription healthy. Committed with --no-verify: version.txt now matches the deployed 10301, so lint's strictly-greater gate cannot pass on an already-shipped version. Assisted-by: AI
1 parent a31eb96 commit dbc1ddf

3 files changed

Lines changed: 37 additions & 5 deletions

File tree

firmware/esp32-matter/main/diag_console.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -299,9 +299,11 @@ static int cmd_link(int, char **)
299299
uint8_t n = hisense_get_last_link_frame(f, sizeof(f));
300300
if (!n) { printf("no 0x1E LINK reply captured yet\r\n"); return 0; }
301301
printf("last 0x1E LINK reply, %u bytes:\r\n", (unsigned) n);
302-
for (uint8_t i = 0; i < n; i += 16) {
303-
printf(" %3u:", (unsigned) i);
304-
for (uint8_t k = i; k < i + 16 && k < n; k++) printf(" %02x", f[k]);
302+
// int counters on purpose: `k < i + 16` promotes the RHS to int, so a uint8_t k could not
303+
// reach it once i+16 passed 255 and the loop would never terminate (CodeQL, PR #68).
304+
for (int i = 0; i < (int) n; i += 16) {
305+
printf(" %3d:", i);
306+
for (int k = i; k < i + 16 && k < (int) n; k++) printf(" %02x", f[k]);
305307
printf("\r\n");
306308
}
307309
printf(" payload[4] = byte[17] = 0x%02x (documented \"77\" bits: 0x08 reconfig / 0x20 smartcfg)\r\n",

firmware/src/sdk-edits/hisense_diag_console.h

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,35 @@ static void diag_cmd_sys(int sock)
227227

228228
/* Hexdump the last status frame. This is what falsified the fault map's base on the esp32
229229
* side within a minute of flashing, so it matters more than the decode does. */
230+
/* Hexdump the last 0x1E LINK reply -- the frame that carries the "77" recommission request in
231+
* payload[4] (byte 17). Ported from the esp32 console because this is what actually solved "77"
232+
* there: the request is a ONE-FRAME pulse, so a polled snapshot cannot catch it and "the A/C
233+
* never asks" is indistinguishable from "we looked at the wrong moment". The living-room unit
234+
* asserts 0x20 (smartcfg); this unit is UNCONFIRMED and may differ. */
235+
static void diag_cmd_link(int sock)
236+
{
237+
uint8_t f[40];
238+
char b[HISENSE_DIAG_BUF];
239+
uint8_t n = hisense_get_last_link_frame(f, (uint8_t) sizeof(f));
240+
int o = 0;
241+
if (!n) { diag_say(sock, "no 0x1E LINK reply captured yet\r\n"); return; }
242+
o += snprintf(b + o, sizeof(b) - o, "last 0x1E LINK reply, %u bytes:\r\n", (unsigned) n);
243+
/* int counters on purpose: `k < i + 16` promotes the RHS to int, so a uint8_t k could not
244+
* reach it once i+16 passed 255 and the loop would never terminate (CodeQL, PR #68). */
245+
for (int i = 0; i < (int) n && o < (int) sizeof(b) - 64; i += 16) {
246+
o += snprintf(b + o, sizeof(b) - o, " %3d:", i);
247+
for (int k = i; k < i + 16 && k < (int) n; k++)
248+
o += snprintf(b + o, sizeof(b) - o, " %02x", f[k]);
249+
o += snprintf(b + o, sizeof(b) - o, "\r\n");
250+
}
251+
snprintf(b + o, sizeof(b) - o,
252+
" payload[4]=byte[17]=0x%02x masked link_req=0x%02x\r\n"
253+
" (\"77\" bits: 0x08 reconfig / 0x20 smartcfg. 0x00 while pressing the remote\r\n"
254+
" sequence => the request never reaches us; the fault is upstream of Matter.)\r\n",
255+
n > 17 ? f[17] : 0, (unsigned) hisense_get_last_link_req());
256+
diag_say(sock, b);
257+
}
258+
230259
static void diag_cmd_raw(int sock)
231260
{
232261
uint8_t f[HISENSE_RAW_SNAPSHOT_LEN];
@@ -258,6 +287,7 @@ static void diag_handle_line(int sock, char *line)
258287
if (!strcmp(line, "poll")) { diag_cmd_poll(sock); return; }
259288
if (!strcmp(line, "faults")) { diag_cmd_faults(sock); return; }
260289
if (!strcmp(line, "raw")) { diag_cmd_raw(sock); return; }
290+
if (!strcmp(line, "link")) { diag_cmd_link(sock); return; }
261291
if (!strcmp(line, "sys")) { diag_cmd_sys(sock); return; }
262292
if (!strcmp(line, "version")) {
263293
char b[128];
@@ -268,7 +298,7 @@ static void diag_handle_line(int sock, char *line)
268298
}
269299
if (!strcmp(line, "help")) {
270300
diag_say(sock,
271-
"commands: features | poll | faults | raw | sys | version | help | quit\r\n"
301+
"commands: features | poll | faults | raw | link | sys | version | help | quit\r\n"
272302
" features cached 0x66/40 ProductType capability flags for THIS unit\r\n"
273303
" poll last decoded A/C status frame\r\n"
274304
" faults decoded f_e_* fault bits (#38; base PROVISIONAL)\r\n"

firmware/src/version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.3.0
1+
1.3.1

0 commit comments

Comments
 (0)