#include "ch32v30x_rtc.h" #include "meshcore/meshframing.h" #include "meshcore/packetstructs.h" #include "group.h" #include "lib/config.h" #include "util/hexdump.h" #include "util/log.h" #include "string.h" #define TAG "GroupMessage" void sendGroupMessage (const GroupTextMessage *msg) { // Prepare values locally instead of modifying msg Channel *channel = &(persistent.channels[msg->keyIndex]); uint8_t flags = 0; int32_t timestamp = RTC_GetCounter(); FrameStruct frame; frame.header = ROUTE_TYPE_FLOOD | PAYLOAD_TYPE_GRP_TXT | PAYLOAD_VERSION_0; frame.path.pathLen = 0; size_t offset = 0; frame.payload[offset++] = channel->hash; // Build encryption buffer directly on stack (no extra large buffer) uint8_t buf[180]; // enough for timestamp + flags + text size_t buf_offset = 0; memcpy (buf + buf_offset, ×tamp, sizeof (timestamp)); buf_offset += sizeof (timestamp); buf[buf_offset++] = flags; size_t textLen = strlen ((const char *)msg->text); if (buf_offset + textLen > sizeof (buf)) { textLen = sizeof (buf) - buf_offset; } memcpy (buf + buf_offset, msg->text, textLen); buf_offset += textLen; hexdump ("TxDumpDec", buf, buf_offset); // Encrypt and MAC directly into frame payload after channelHash size_t olen = 0; encrypt_then_mac (channel->key, 16, buf, buf_offset, &frame.payload[offset], &olen); frame.payloadLen = olen + 1; // +1 for channelHash channel->timestamp = timestamp; LoRaTransmit (&frame); } void makeSendGroupMessage (char *txt, uint8_t keyIndex) { GroupTextMessage msg; strcpy ((char *)msg.text, persistent.nodeName); strcat ((char *)msg.text, ": "); strcat ((char *)msg.text, txt); msg.keyIndex = keyIndex; sendGroupMessage (&msg); return; } void decodeGroupMessage (const FrameStruct *frame) { GroupTextMessage msg; memset (&msg, 0, sizeof (msg)); if ((frame->header & PAYLOAD_TYPE_MASK) != PAYLOAD_TYPE_GRP_TXT) { MESH_LOGW (TAG, "Not a group text"); return; } unsigned char index = 0; msg.channelHash = frame->payload[index++]; unsigned char tmp[184]; Channel *channel = NULL; uint8_t i = 0; do { channel = getChannel (msg.channelHash, i); if (channel == NULL) { MESH_LOGW (TAG, "Channel hash %d not found", msg.channelHash); return; } if (mac_then_decrypt (channel->key, 16, frame->payload + index, frame->payloadLen - index, tmp) != 0) { MESH_LOGW (TAG, "HMAC failed on grouphash key %d", msg.channelHash); i++; continue; } else { unsigned char plaintextLen = frame->payloadLen - index; index = 0; memcpy (&msg.timestamp, tmp + index, 4); index += 4; msg.flags = tmp[index++]; memcpy (msg.text, tmp + index, plaintextLen - index); channel->timestamp = RTC_GetCounter(); printf ("Message from channel %s: %s\n", channel->name, msg.text); break; } } while (channel != NULL); }