* support for GroupChannels in BaseChatMesh, and terminal chat

This commit is contained in:
Scott Powell 2025-01-26 00:46:36 +11:00
parent e58d866949
commit 6d5e69ae04
4 changed files with 82 additions and 0 deletions

View file

@ -1,4 +1,6 @@
#include <helpers/BaseChatMesh.h>
#include <base64.hpp>
#include <Utils.h>
mesh::Packet* BaseChatMesh::createSelfAdvert(const char* name) {
uint8_t app_data[MAX_ADVERT_DATA_SIZE];
@ -150,6 +152,30 @@ 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 < num_channels && n < max_matches; i++) {
if (channels[i].hash[0] == hash[0]) {
dest[n++] = channels[i];
}
}
return n;
}
void BaseChatMesh::onGroupDataRecv(mesh::Packet* packet, uint8_t type, const mesh::GroupChannel& channel, uint8_t* data, size_t len) {
uint8_t txt_type = data[4];
if (type == PAYLOAD_TYPE_GRP_TXT && len > 5 && (txt_type >> 2) == 0) { // 0 = plain text msg
uint32_t timestamp;
memcpy(&timestamp, data, 4);
// len can be > original length, but 'text' will be padded with zeroes
data[len] = 0; // need to make a C string again, with null terminator
// notify UI of this new message
onChannelMessageRecv(channel, packet->isRouteFlood() ? packet->path_len : -1, timestamp, (const char *) &data[5]); // let UI know
}
}
mesh::Packet* BaseChatMesh::composeMsgPacket(const ContactInfo& recipient, uint8_t attempt, const char *text, uint32_t& expected_ack) {
int text_len = strlen(text);
if (text_len > MAX_TEXT_LEN) return NULL;
@ -240,6 +266,21 @@ bool BaseChatMesh::addContact(const ContactInfo& contact) {
return false;
}
mesh::GroupChannel* BaseChatMesh::addChannel(const char* psk_base64) {
if (num_channels < MAX_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);
if (len == 32 || len == 16) {
mesh::Utils::sha256(dest->hash, sizeof(dest->hash), dest->secret, len);
num_channels++;
return dest;
}
}
return NULL;
}
bool ContactsIterator::hasNext(const BaseChatMesh* mesh, ContactInfo& dest) {
if (next_idx >= mesh->num_contacts) return false;

View file

@ -48,6 +48,8 @@ class BaseChatMesh : public mesh::Mesh {
int sort_array[MAX_CONTACTS];
int matching_peer_indexes[MAX_SEARCH_RESULTS];
unsigned long txt_send_timeout;
mesh::GroupChannel channels[MAX_CHANNELS];
int num_channels;
mesh::Packet* composeMsgPacket(const ContactInfo& recipient, uint8_t attempt, const char *text, uint32_t& expected_ack);
@ -56,6 +58,7 @@ protected:
: mesh::Mesh(radio, ms, rng, rtc, mgr, tables)
{
num_contacts = 0;
num_channels = 0;
txt_send_timeout = 0;
}
@ -67,6 +70,7 @@ protected:
virtual uint32_t calcFloodTimeoutMillisFor(uint32_t pkt_airtime_millis) const = 0;
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, int in_path_len, uint32_t timestamp, const char *text) = 0;
// Mesh overrides
void onAdvertRecv(mesh::Packet* packet, const mesh::Identity& id, uint32_t timestamp, const uint8_t* app_data, size_t app_data_len) override;
@ -75,6 +79,8 @@ protected:
void onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender_idx, const uint8_t* secret, uint8_t* data, size_t len) override;
bool onPeerPathRecv(mesh::Packet* packet, int sender_idx, const uint8_t* secret, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) override;
void onAckRecv(mesh::Packet* packet, uint32_t ack_crc) override;
int searchChannelsByHash(const uint8_t* hash, mesh::GroupChannel channels[], int max_matches) override;
void onGroupDataRecv(mesh::Packet* packet, uint8_t type, const mesh::GroupChannel& channel, uint8_t* data, size_t len) override;
public:
mesh::Packet* createSelfAdvert(const char* name);
@ -83,6 +89,7 @@ public:
void scanRecentContacts(int last_n, ContactVisitor* visitor);
ContactInfo* searchContactsByPrefix(const char* name_prefix);
bool addContact(const ContactInfo& contact);
mesh::GroupChannel* addChannel(const char* psk_base64);
void loop();
};