From b94fed4e4e9bd9cf50dc5ab45b1794ab4086a93b Mon Sep 17 00:00:00 2001 From: Scott Powell Date: Tue, 11 Mar 2025 17:58:12 +1100 Subject: [PATCH] * companion: channel names --- examples/companion_radio/main.cpp | 47 +++++++++++++++------------- examples/simple_secure_chat/main.cpp | 6 ++-- src/helpers/BaseChatMesh.cpp | 31 +++++++++--------- src/helpers/BaseChatMesh.h | 13 +++++--- 4 files changed, 54 insertions(+), 43 deletions(-) diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index c0b98c7b..05a8c58d 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -315,17 +315,18 @@ class MyMesh : public BaseChatMesh { } void loadChannels() { - if (_fs->exists("/channels")) { - File file = _fs->open("/channels"); + if (_fs->exists("/channels2")) { + File file = _fs->open("/channels2"); if (file) { bool full = false; uint8_t channel_idx = 0; while (!full) { - mesh::GroupChannel ch; + ChannelDetails ch; uint8_t unused[4]; bool success = (file.read(unused, 4) == 4); - success = success && (file.read((uint8_t *) ch.secret, 32) == 32); + success = success && (file.read((uint8_t *) ch.name, 32) == 32); + success = success && (file.read((uint8_t *) ch.channel.secret, 32) == 32); if (!success) break; // EOF @@ -342,20 +343,21 @@ class MyMesh : public BaseChatMesh { void saveChannels() { #if defined(NRF52_PLATFORM) - File file = _fs->open("/channels", FILE_O_WRITE); + File file = _fs->open("/channels2", FILE_O_WRITE); if (file) { file.seek(0); file.truncate(); } #else - File file = _fs->open("/channels", "w", true); + File file = _fs->open("/channels2", "w", true); #endif if (file) { uint8_t channel_idx = 0; - mesh::GroupChannel ch; + ChannelDetails ch; uint8_t unused[4]; memset(unused, 0, 4); while (getChannel(channel_idx, ch)) { bool success = (file.write(unused, 4) == 4); - success = success && (file.write((uint8_t *) ch.secret, 32) == 32); + success = success && (file.write((uint8_t *) ch.name, 32) == 32); + success = success && (file.write((uint8_t *) ch.channel.secret, 32) == 32); if (!success) break; // write failed channel_idx++; @@ -766,7 +768,7 @@ public: _fs->mkdir("/bl"); loadContacts(); - addChannel(PUBLIC_GROUP_PSK); // pre-configure Andy's public channel + addChannel("Public", PUBLIC_GROUP_PSK); // pre-configure Andy's public channel loadChannels(); _phy->setFrequency(_prefs.freq); @@ -905,9 +907,9 @@ public: memcpy(&msg_timestamp, &cmd_frame[i], 4); i += 4; const char *text = (char *) &cmd_frame[i]; - mesh::GroupChannel channel; + ChannelDetails channel; bool success = getChannel(channel_idx, channel); - if (success && txt_type == TXT_TYPE_PLAIN && sendGroupMessage(msg_timestamp, channel, _prefs.node_name, text, len - i)) { + if (success && txt_type == TXT_TYPE_PLAIN && sendGroupMessage(msg_timestamp, channel.channel, _prefs.node_name, text, len - i)) { writeOKFrame(); } else { writeErrFrame(); @@ -1221,22 +1223,25 @@ public: writeOKFrame(); } else if (cmd_frame[0] == CMD_GET_CHANNEL && len >= 2) { uint8_t channel_idx = cmd_frame[1]; - mesh::GroupChannel channel; + ChannelDetails channel; if (getChannel(channel_idx, channel)) { - out_frame[0] = RESP_CODE_CHANNEL_INFO; - out_frame[1] = channel_idx; - memcpy(&out_frame[2], channel.secret, 16); // NOTE: only 128-bit supported - _serial->writeFrame(out_frame, 2 + 16); + int i = 0; + out_frame[i++] = RESP_CODE_CHANNEL_INFO; + out_frame[i++] = channel_idx; + strcpy((char *)&out_frame[i], channel.name); i += 32; + memcpy(&out_frame[i], channel.channel.secret, 16); i += 16; // NOTE: only 128-bit supported + _serial->writeFrame(out_frame, i); } else { writeErrFrame(); } - } else if (cmd_frame[0] == CMD_SET_CHANNEL && len >= 3+32) { + } else if (cmd_frame[0] == CMD_SET_CHANNEL && len >= 2+32+32) { writeErrFrame(); // not supported (yet) - } else if (cmd_frame[0] == CMD_SET_CHANNEL && len >= 3+16) { + } else if (cmd_frame[0] == CMD_SET_CHANNEL && len >= 2+32+16) { uint8_t channel_idx = cmd_frame[1]; - mesh::GroupChannel channel; - memset(channel.secret, 0, sizeof(channel.secret)); - memcpy(channel.secret, &cmd_frame[2], 16); // NOTE: only 128-bit supported + ChannelDetails channel; + StrHelper::strncpy(channel.name, (char *) &cmd_frame[2], 32); + memset(channel.channel.secret, 0, sizeof(channel.channel.secret)); + memcpy(channel.channel.secret, &cmd_frame[2+32], 16); // NOTE: only 128-bit supported if (setChannel(channel_idx, channel)) { saveChannels(); writeOKFrame(); diff --git a/examples/simple_secure_chat/main.cpp b/examples/simple_secure_chat/main.cpp index 951d51dc..3a376e54 100644 --- a/examples/simple_secure_chat/main.cpp +++ b/examples/simple_secure_chat/main.cpp @@ -107,7 +107,7 @@ class MyMesh : public BaseChatMesh, ContactVisitor { FILESYSTEM* _fs; NodePrefs _prefs; uint32_t expected_ack_crc; - mesh::GroupChannel* _public; + ChannelDetails* _public; unsigned long last_msg_sent; ContactInfo* curr_recipient; char command[512+10]; @@ -337,7 +337,7 @@ public: } loadContacts(); - _public = addChannel(PUBLIC_GROUP_PSK); // pre-configure Andy's public channel + _public = addChannel("Public", PUBLIC_GROUP_PSK); // pre-configure Andy's public channel } void savePrefs() { @@ -405,7 +405,7 @@ public: temp[5 + MAX_TEXT_LEN] = 0; // truncate if too long int len = strlen((char *) &temp[5]); - auto pkt = createGroupDatagram(PAYLOAD_TYPE_GRP_TXT, *_public, temp, 5 + len); + auto pkt = createGroupDatagram(PAYLOAD_TYPE_GRP_TXT, _public->channel, temp, 5 + len); if (pkt) { sendFlood(pkt); Serial.println(" Sent."); diff --git a/src/helpers/BaseChatMesh.cpp b/src/helpers/BaseChatMesh.cpp index e44ffcf3..f49c5364 100644 --- a/src/helpers/BaseChatMesh.cpp +++ b/src/helpers/BaseChatMesh.cpp @@ -204,8 +204,8 @@ void BaseChatMesh::onAckRecv(mesh::Packet* packet, uint32_t ack_crc) { int BaseChatMesh::searchChannelsByHash(const uint8_t* hash, mesh::GroupChannel dest[], int max_matches) { int n = 0; for (int i = 0; i < MAX_GROUP_CHANNELS && n < max_matches; i++) { - if (channels[i].hash[0] == hash[0]) { - dest[n++] = channels[i]; + if (channels[i].channel.hash[0] == hash[0]) { + dest[n++] = channels[i].channel; } } return n; @@ -588,36 +588,37 @@ bool BaseChatMesh::removeContact(ContactInfo& contact) { #ifdef MAX_GROUP_CHANNELS #include -mesh::GroupChannel* BaseChatMesh::addChannel(const char* psk_base64) { +ChannelDetails* BaseChatMesh::addChannel(const char* name, const char* psk_base64) { if (num_channels < MAX_GROUP_CHANNELS) { auto dest = &channels[num_channels]; - memset(dest->secret, 0, sizeof(dest->secret)); - int len = decode_base64((unsigned char *) psk_base64, strlen(psk_base64), dest->secret); + memset(dest->channel.secret, 0, sizeof(dest->channel.secret)); + int len = decode_base64((unsigned char *) psk_base64, strlen(psk_base64), dest->channel.secret); if (len == 32 || len == 16) { - mesh::Utils::sha256(dest->hash, sizeof(dest->hash), dest->secret, len); + mesh::Utils::sha256(dest->channel.hash, sizeof(dest->channel.hash), dest->channel.secret, len); + StrHelper::strncpy(dest->name, name, sizeof(dest->name)); num_channels++; return dest; } } return NULL; } -bool BaseChatMesh::getChannel(int idx, mesh::GroupChannel& dest) { +bool BaseChatMesh::getChannel(int idx, ChannelDetails& dest) { if (idx >= 0 && idx < MAX_GROUP_CHANNELS) { dest = channels[idx]; return true; } return false; } -bool BaseChatMesh::setChannel(int idx, const mesh::GroupChannel& src) { +bool BaseChatMesh::setChannel(int idx, const ChannelDetails& src) { static uint8_t zeroes[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; if (idx >= 0 && idx < MAX_GROUP_CHANNELS) { channels[idx] = src; - if (memcmp(&src.secret[16], zeroes, 16) == 0) { - mesh::Utils::sha256(channels[idx].hash, sizeof(channels[idx].hash), src.secret, 16); // 128-bit key + if (memcmp(&src.channel.secret[16], zeroes, 16) == 0) { + mesh::Utils::sha256(channels[idx].channel.hash, sizeof(channels[idx].channel.hash), src.channel.secret, 16); // 128-bit key } else { - mesh::Utils::sha256(channels[idx].hash, sizeof(channels[idx].hash), src.secret, 32); // 256-bit key + mesh::Utils::sha256(channels[idx].channel.hash, sizeof(channels[idx].channel.hash), src.channel.secret, 32); // 256-bit key } return true; } @@ -625,18 +626,18 @@ bool BaseChatMesh::setChannel(int idx, const mesh::GroupChannel& src) { } int BaseChatMesh::findChannelIdx(const mesh::GroupChannel& ch) { for (int i = 0; i < MAX_GROUP_CHANNELS; i++) { - if (memcmp(ch.secret, channels[i].secret, sizeof(ch.secret)) == 0) return i; + if (memcmp(ch.secret, channels[i].channel.secret, sizeof(ch.secret)) == 0) return i; } return -1; // not found } #else -mesh::GroupChannel* BaseChatMesh::addChannel(const char* psk_base64) { +ChannelDetails* BaseChatMesh::addChannel(const char* psk_base64) { return NULL; // not supported } -bool BaseChatMesh::getChannel(int idx, mesh::GroupChannel& dest) { +bool BaseChatMesh::getChannel(int idx, ChannelDetails& dest) { return false; } -bool BaseChatMesh::setChannel(int idx, const mesh::GroupChannel& src) { +bool BaseChatMesh::setChannel(int idx, const ChannelDetails& src) { return false; } int BaseChatMesh::findChannelIdx(const mesh::GroupChannel& ch) { diff --git a/src/helpers/BaseChatMesh.h b/src/helpers/BaseChatMesh.h index c5b60dd1..ec603a7e 100644 --- a/src/helpers/BaseChatMesh.h +++ b/src/helpers/BaseChatMesh.h @@ -61,6 +61,11 @@ struct ConnectionInfo { uint32_t expected_ack; }; +struct ChannelDetails { + mesh::GroupChannel channel; + char name[32]; +}; + /** * \brief abstract Mesh class for common 'chat' client */ @@ -74,7 +79,7 @@ class BaseChatMesh : public mesh::Mesh { int matching_peer_indexes[MAX_SEARCH_RESULTS]; unsigned long txt_send_timeout; #ifdef MAX_GROUP_CHANNELS - mesh::GroupChannel channels[MAX_GROUP_CHANNELS]; + ChannelDetails channels[MAX_GROUP_CHANNELS]; int num_channels; // only for addChannel() #endif mesh::Packet* _pendingLoopback; @@ -152,9 +157,9 @@ public: bool addContact(const ContactInfo& contact); int getNumContacts() const { return num_contacts; } ContactsIterator startContactsIterator(); - mesh::GroupChannel* addChannel(const char* psk_base64); - bool getChannel(int idx, mesh::GroupChannel& dest); - bool setChannel(int idx, const mesh::GroupChannel& src); + ChannelDetails* addChannel(const char* name, const char* psk_base64); + bool getChannel(int idx, ChannelDetails& dest); + bool setChannel(int idx, const ChannelDetails& src); int findChannelIdx(const mesh::GroupChannel& ch); void loop();