From ed326255d545af528d734dfb8c821c322b8eeb40 Mon Sep 17 00:00:00 2001 From: liamcottle Date: Mon, 23 Mar 2026 21:46:21 +1300 Subject: [PATCH 1/3] add support for direct paths when sending group data --- examples/companion_radio/MyMesh.cpp | 17 ++++++++++++++++- src/helpers/BaseChatMesh.cpp | 10 ++++++++-- src/helpers/BaseChatMesh.h | 2 +- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index a98d4b6a9..f151fb30b 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -1110,6 +1110,21 @@ void MyMesh::handleCmdFrame(size_t len) { uint16_t data_type = ((uint16_t)cmd_frame[i]) | (((uint16_t)cmd_frame[i + 1]) << 8); i += 2; uint8_t channel_idx = cmd_frame[i++]; + uint8_t path_len = cmd_frame[i++]; + + // validate path len, allowing 0xFF for flood + if (!mesh::Packet::isValidPathLen(path_len) && path_len != OUT_PATH_UNKNOWN) { + MESH_DEBUG_PRINTLN("CMD_SEND_CHANNEL_DATA invalid path size: %d", path_len); + writeErrFrame(ERR_CODE_ILLEGAL_ARG); + return; + } + + // parse provided path if not flood + uint8_t path[MAX_PATH_SIZE]; + if (path_len != OUT_PATH_UNKNOWN) { + i += mesh::Packet::writePath(path, &cmd_frame[i], path_len); + } + const uint8_t *payload = &cmd_frame[i]; int payload_len = (len > (size_t)i) ? (int)(len - i) : 0; @@ -1121,7 +1136,7 @@ void MyMesh::handleCmdFrame(size_t len) { } else if (payload_len > MAX_CHANNEL_DATA_LENGTH) { MESH_DEBUG_PRINTLN("CMD_SEND_CHANNEL_DATA payload too long: %d > %d", payload_len, MAX_CHANNEL_DATA_LENGTH); writeErrFrame(ERR_CODE_ILLEGAL_ARG); - } else if (sendGroupData(channel.channel, data_type, payload, payload_len)) { + } else if (sendGroupData(channel.channel, path, path_len, data_type, payload, payload_len)) { writeOKFrame(); } else { writeErrFrame(ERR_CODE_TABLE_FULL); diff --git a/src/helpers/BaseChatMesh.cpp b/src/helpers/BaseChatMesh.cpp index 78e197bee..7ddc461d2 100644 --- a/src/helpers/BaseChatMesh.cpp +++ b/src/helpers/BaseChatMesh.cpp @@ -481,7 +481,7 @@ bool BaseChatMesh::sendGroupMessage(uint32_t timestamp, mesh::GroupChannel& chan return false; } -bool BaseChatMesh::sendGroupData(mesh::GroupChannel& channel, uint16_t data_type, const uint8_t* data, int data_len) { +bool BaseChatMesh::sendGroupData(mesh::GroupChannel& channel, uint8_t* path, uint8_t path_len, uint16_t data_type, const uint8_t* data, int data_len) { if (data_len < 0) { MESH_DEBUG_PRINTLN("sendGroupData: invalid negative data_len=%d", data_len); return false; @@ -502,7 +502,13 @@ bool BaseChatMesh::sendGroupData(mesh::GroupChannel& channel, uint16_t data_type MESH_DEBUG_PRINTLN("sendGroupData: unable to create group datagram, data_len=%d", data_len); return false; } - sendFloodScoped(channel, pkt); + + if (path_len == OUT_PATH_UNKNOWN) { + sendFloodScoped(channel, pkt); + } else { + sendDirect(pkt, path, path_len); + } + return true; } diff --git a/src/helpers/BaseChatMesh.h b/src/helpers/BaseChatMesh.h index c2f9d9154..b39e73638 100644 --- a/src/helpers/BaseChatMesh.h +++ b/src/helpers/BaseChatMesh.h @@ -150,7 +150,7 @@ public: int sendMessage(const ContactInfo& recipient, uint32_t timestamp, uint8_t attempt, const char* text, uint32_t& expected_ack, uint32_t& est_timeout); int sendCommandData(const ContactInfo& recipient, uint32_t timestamp, uint8_t attempt, const char* text, uint32_t& est_timeout); bool sendGroupMessage(uint32_t timestamp, mesh::GroupChannel& channel, const char* sender_name, const char* text, int text_len); - bool sendGroupData(mesh::GroupChannel& channel, uint16_t data_type, const uint8_t* data, int data_len); + bool sendGroupData(mesh::GroupChannel& channel, uint8_t* path, uint8_t path_len, uint16_t data_type, const uint8_t* data, int data_len); int sendLogin(const ContactInfo& recipient, const char* password, uint32_t& est_timeout); int sendAnonReq(const ContactInfo& recipient, const uint8_t* data, uint8_t len, uint32_t& tag, uint32_t& est_timeout); int sendRequest(const ContactInfo& recipient, uint8_t req_type, uint32_t& tag, uint32_t& est_timeout); From c78f7133c96315af889c219b9369de029687dcea Mon Sep 17 00:00:00 2001 From: liamcottle Date: Mon, 23 Mar 2026 23:02:24 +1300 Subject: [PATCH 2/3] reorder command args --- examples/companion_radio/MyMesh.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index f151fb30b..590d689b6 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -1107,8 +1107,6 @@ void MyMesh::handleCmdFrame(size_t len) { return; } int i = 1; - uint16_t data_type = ((uint16_t)cmd_frame[i]) | (((uint16_t)cmd_frame[i + 1]) << 8); - i += 2; uint8_t channel_idx = cmd_frame[i++]; uint8_t path_len = cmd_frame[i++]; @@ -1125,6 +1123,8 @@ void MyMesh::handleCmdFrame(size_t len) { i += mesh::Packet::writePath(path, &cmd_frame[i], path_len); } + uint16_t data_type = ((uint16_t)cmd_frame[i]) | (((uint16_t)cmd_frame[i + 1]) << 8); + i += 2; const uint8_t *payload = &cmd_frame[i]; int payload_len = (len > (size_t)i) ? (int)(len - i) : 0; From 1d61df72c3362ad8955752ff343558831aeefa6c Mon Sep 17 00:00:00 2001 From: liamcottle Date: Mon, 23 Mar 2026 23:09:35 +1300 Subject: [PATCH 3/3] add define for reserved group data type --- examples/companion_radio/MyMesh.cpp | 2 +- src/helpers/TxtDataHelpers.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index 590d689b6..60a5a75fe 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -1131,7 +1131,7 @@ void MyMesh::handleCmdFrame(size_t len) { ChannelDetails channel; if (!getChannel(channel_idx, channel)) { writeErrFrame(ERR_CODE_NOT_FOUND); // bad channel_idx - } else if (data_type == 0) { + } else if (data_type == DATA_TYPE_RESERVED) { writeErrFrame(ERR_CODE_ILLEGAL_ARG); } else if (payload_len > MAX_CHANNEL_DATA_LENGTH) { MESH_DEBUG_PRINTLN("CMD_SEND_CHANNEL_DATA payload too long: %d > %d", payload_len, MAX_CHANNEL_DATA_LENGTH); diff --git a/src/helpers/TxtDataHelpers.h b/src/helpers/TxtDataHelpers.h index 47bbc0ded..ece494f29 100644 --- a/src/helpers/TxtDataHelpers.h +++ b/src/helpers/TxtDataHelpers.h @@ -6,6 +6,7 @@ #define TXT_TYPE_PLAIN 0 // a plain text message #define TXT_TYPE_CLI_DATA 1 // a CLI command #define TXT_TYPE_SIGNED_PLAIN 2 // plain text, signed by sender +#define DATA_TYPE_RESERVED 0x0000 // reserved for future use #define DATA_TYPE_DEV 0xFFFF // developer namespace for experimenting with group/channel datagrams and building apps class StrHelper {