107 lines
3.1 KiB
C
107 lines
3.1 KiB
C
#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);
|
|
} |