feat: Add support for PAYLOAD_TYPE_GRP_DATA

Docs changes are to reflect how it is currently in fw

This adds ability to send datagram data to everyone in channel
This commit is contained in:
Janez T 2026-03-05 13:23:23 +01:00
parent 792f299986
commit 9b84278607
6 changed files with 148 additions and 21 deletions

View file

@ -353,8 +353,10 @@ int BaseChatMesh::searchChannelsByHash(const uint8_t* hash, mesh::GroupChannel d
#endif
void BaseChatMesh::onGroupDataRecv(mesh::Packet* packet, uint8_t type, const mesh::GroupChannel& channel, uint8_t* data, size_t len) {
if (len < 5) return;
uint8_t txt_type = data[4];
if (type == PAYLOAD_TYPE_GRP_TXT && len > 5 && (txt_type >> 2) == 0) { // 0 = plain text msg
if (type == PAYLOAD_TYPE_GRP_TXT && (txt_type >> 2) == 0) { // 0 = plain text msg
uint32_t timestamp;
memcpy(&timestamp, data, 4);
@ -363,6 +365,10 @@ void BaseChatMesh::onGroupDataRecv(mesh::Packet* packet, uint8_t type, const mes
// notify UI of this new message
onChannelMessageRecv(channel, packet, timestamp, (const char *) &data[5]); // let UI know
} else if (type == PAYLOAD_TYPE_GRP_DATA) {
uint32_t timestamp;
memcpy(&timestamp, data, 4);
onChannelDataRecv(channel, packet, timestamp, txt_type, &data[5], len - 5);
}
}
@ -454,6 +460,26 @@ bool BaseChatMesh::sendGroupMessage(uint32_t timestamp, mesh::GroupChannel& chan
return false;
}
bool BaseChatMesh::sendGroupData(uint32_t timestamp, mesh::GroupChannel& channel, uint8_t txt_type, const uint8_t* data, int data_len) {
if (data_len < 0) return false;
// createGroupDatagram() accepts at most (MAX_PACKET_PAYLOAD - CIPHER_BLOCK_SIZE)
// plaintext bytes; subtract our 5-byte {timestamp, txt_type} header.
const int max_group_data_len = (MAX_PACKET_PAYLOAD - CIPHER_BLOCK_SIZE) - 5;
if (data_len > max_group_data_len) data_len = max_group_data_len;
uint8_t temp[MAX_PACKET_PAYLOAD];
memcpy(temp, &timestamp, 4);
temp[4] = txt_type;
if (data_len > 0) memcpy(&temp[5], data, data_len);
auto pkt = createGroupDatagram(PAYLOAD_TYPE_GRP_DATA, channel, temp, 5 + data_len);
if (pkt) {
sendFloodScoped(channel, pkt);
return true;
}
return false;
}
bool BaseChatMesh::shareContactZeroHop(const ContactInfo& contact) {
int plen = getBlobByKey(contact.id.pub_key, PUB_KEY_SIZE, temp_buf); // retrieve last raw advert packet
if (plen == 0) return false; // not found

View file

@ -111,6 +111,8 @@ protected:
virtual uint32_t calcDirectTimeoutMillisFor(uint32_t pkt_airtime_millis, uint8_t path_len) const = 0;
virtual void onSendTimeout() = 0;
virtual void onChannelMessageRecv(const mesh::GroupChannel& channel, mesh::Packet* pkt, uint32_t timestamp, const char *text) = 0;
virtual void onChannelDataRecv(const mesh::GroupChannel& channel, mesh::Packet* pkt, uint32_t timestamp, uint8_t txt_type,
const uint8_t* data, size_t data_len) {}
virtual uint8_t onContactRequest(const ContactInfo& contact, uint32_t sender_timestamp, const uint8_t* data, uint8_t len, uint8_t* reply) = 0;
virtual void onContactResponse(const ContactInfo& contact, const uint8_t* data, uint8_t len) = 0;
virtual void handleReturnPathRetry(const ContactInfo& contact, const uint8_t* path, uint8_t path_len);
@ -148,6 +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(uint32_t timestamp, mesh::GroupChannel& channel, uint8_t txt_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);

View file

@ -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 TXT_TYPE_CUSTOM_BINARY 0xFF // custom app binary payload (group/channel datagrams)
class StrHelper {
public: