@@ -670,6 +670,11 @@ void MyMesh::onRawDataRecv(mesh::Packet *packet) {
670670
671671void MyMesh::onTraceRecv (mesh::Packet *packet, uint32_t tag, uint32_t auth_code, uint8_t flags,
672672 const uint8_t *path_snrs, const uint8_t *path_hashes, uint8_t path_len) {
673+ uint8_t path_sz = flags & 0x03 ; // NEW v1.11+
674+ if (12 + path_len + (path_len >> path_sz) + 1 > sizeof (out_frame)) {
675+ MESH_DEBUG_PRINTLN (" onTraceRecv(), path_len is too long: %d" , (uint32_t )path_len);
676+ return ;
677+ }
673678 int i = 0 ;
674679 out_frame[i++] = PUSH_CODE_TRACE_DATA;
675680 out_frame[i++] = 0 ; // reserved
@@ -681,8 +686,9 @@ void MyMesh::onTraceRecv(mesh::Packet *packet, uint32_t tag, uint32_t auth_code,
681686 i += 4 ;
682687 memcpy (&out_frame[i], path_hashes, path_len);
683688 i += path_len;
684- memcpy (&out_frame[i], path_snrs, path_len);
685- i += path_len;
689+
690+ memcpy (&out_frame[i], path_snrs, path_len >> path_sz);
691+ i += path_len >> path_sz;
686692 out_frame[i++] = (int8_t )(packet->getSNR () * 4 ); // extra/final SNR (to this node)
687693
688694 if (_serial->isConnected ()) {
@@ -1446,25 +1452,31 @@ void MyMesh::handleCmdFrame(size_t len) {
14461452 } else {
14471453 writeErrFrame (ERR_CODE_BAD_STATE);
14481454 }
1449- } else if (cmd_frame[0 ] == CMD_SEND_TRACE_PATH && len > 10 && len - 10 < MAX_PATH_SIZE) {
1450- uint32_t tag, auth;
1451- memcpy (&tag, &cmd_frame[1 ], 4 );
1452- memcpy (&auth, &cmd_frame[5 ], 4 );
1453- auto pkt = createTrace (tag, auth, cmd_frame[9 ]);
1454- if (pkt) {
1455- uint8_t path_len = len - 10 ;
1456- sendDirect (pkt, &cmd_frame[10 ], path_len);
1455+ } else if (cmd_frame[0 ] == CMD_SEND_TRACE_PATH && len > 10 && len - 10 < MAX_PACKET_PAYLOAD-5 ) {
1456+ uint8_t path_len = len - 10 ;
1457+ uint8_t flags = cmd_frame[9 ];
1458+ uint8_t path_sz = flags & 0x03 ; // NEW v1.11+
1459+ if ((path_len >> path_sz) > MAX_PATH_SIZE || (path_len % (1 << path_sz)) != 0 ) { // make sure is multiple of path_sz
1460+ writeErrFrame (ERR_CODE_ILLEGAL_ARG);
1461+ } else {
1462+ uint32_t tag, auth;
1463+ memcpy (&tag, &cmd_frame[1 ], 4 );
1464+ memcpy (&auth, &cmd_frame[5 ], 4 );
1465+ auto pkt = createTrace (tag, auth, flags);
1466+ if (pkt) {
1467+ sendDirect (pkt, &cmd_frame[10 ], path_len);
14571468
1458- uint32_t t = _radio->getEstAirtimeFor (pkt->payload_len + pkt->path_len + 2 );
1459- uint32_t est_timeout = calcDirectTimeoutMillisFor (t, path_len);
1469+ uint32_t t = _radio->getEstAirtimeFor (pkt->payload_len + pkt->path_len + 2 );
1470+ uint32_t est_timeout = calcDirectTimeoutMillisFor (t, path_len);
14601471
1461- out_frame[0 ] = RESP_CODE_SENT;
1462- out_frame[1 ] = 0 ;
1463- memcpy (&out_frame[2 ], &tag, 4 );
1464- memcpy (&out_frame[6 ], &est_timeout, 4 );
1465- _serial->writeFrame (out_frame, 10 );
1466- } else {
1467- writeErrFrame (ERR_CODE_TABLE_FULL);
1472+ out_frame[0 ] = RESP_CODE_SENT;
1473+ out_frame[1 ] = 0 ;
1474+ memcpy (&out_frame[2 ], &tag, 4 );
1475+ memcpy (&out_frame[6 ], &est_timeout, 4 );
1476+ _serial->writeFrame (out_frame, 10 );
1477+ } else {
1478+ writeErrFrame (ERR_CODE_TABLE_FULL);
1479+ }
14681480 }
14691481 } else if (cmd_frame[0 ] == CMD_SET_DEVICE_PIN && len >= 5 ) {
14701482
0 commit comments