mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-04-20 22:13:47 +00:00
* companion: channel names
This commit is contained in:
parent
adf9b24867
commit
b94fed4e4e
4 changed files with 54 additions and 43 deletions
|
|
@ -315,17 +315,18 @@ class MyMesh : public BaseChatMesh {
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadChannels() {
|
void loadChannels() {
|
||||||
if (_fs->exists("/channels")) {
|
if (_fs->exists("/channels2")) {
|
||||||
File file = _fs->open("/channels");
|
File file = _fs->open("/channels2");
|
||||||
if (file) {
|
if (file) {
|
||||||
bool full = false;
|
bool full = false;
|
||||||
uint8_t channel_idx = 0;
|
uint8_t channel_idx = 0;
|
||||||
while (!full) {
|
while (!full) {
|
||||||
mesh::GroupChannel ch;
|
ChannelDetails ch;
|
||||||
uint8_t unused[4];
|
uint8_t unused[4];
|
||||||
|
|
||||||
bool success = (file.read(unused, 4) == 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
|
if (!success) break; // EOF
|
||||||
|
|
||||||
|
|
@ -342,20 +343,21 @@ class MyMesh : public BaseChatMesh {
|
||||||
|
|
||||||
void saveChannels() {
|
void saveChannels() {
|
||||||
#if defined(NRF52_PLATFORM)
|
#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(); }
|
if (file) { file.seek(0); file.truncate(); }
|
||||||
#else
|
#else
|
||||||
File file = _fs->open("/channels", "w", true);
|
File file = _fs->open("/channels2", "w", true);
|
||||||
#endif
|
#endif
|
||||||
if (file) {
|
if (file) {
|
||||||
uint8_t channel_idx = 0;
|
uint8_t channel_idx = 0;
|
||||||
mesh::GroupChannel ch;
|
ChannelDetails ch;
|
||||||
uint8_t unused[4];
|
uint8_t unused[4];
|
||||||
memset(unused, 0, 4);
|
memset(unused, 0, 4);
|
||||||
|
|
||||||
while (getChannel(channel_idx, ch)) {
|
while (getChannel(channel_idx, ch)) {
|
||||||
bool success = (file.write(unused, 4) == 4);
|
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
|
if (!success) break; // write failed
|
||||||
channel_idx++;
|
channel_idx++;
|
||||||
|
|
@ -766,7 +768,7 @@ public:
|
||||||
_fs->mkdir("/bl");
|
_fs->mkdir("/bl");
|
||||||
|
|
||||||
loadContacts();
|
loadContacts();
|
||||||
addChannel(PUBLIC_GROUP_PSK); // pre-configure Andy's public channel
|
addChannel("Public", PUBLIC_GROUP_PSK); // pre-configure Andy's public channel
|
||||||
loadChannels();
|
loadChannels();
|
||||||
|
|
||||||
_phy->setFrequency(_prefs.freq);
|
_phy->setFrequency(_prefs.freq);
|
||||||
|
|
@ -905,9 +907,9 @@ public:
|
||||||
memcpy(&msg_timestamp, &cmd_frame[i], 4); i += 4;
|
memcpy(&msg_timestamp, &cmd_frame[i], 4); i += 4;
|
||||||
const char *text = (char *) &cmd_frame[i];
|
const char *text = (char *) &cmd_frame[i];
|
||||||
|
|
||||||
mesh::GroupChannel channel;
|
ChannelDetails channel;
|
||||||
bool success = getChannel(channel_idx, 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();
|
writeOKFrame();
|
||||||
} else {
|
} else {
|
||||||
writeErrFrame();
|
writeErrFrame();
|
||||||
|
|
@ -1221,22 +1223,25 @@ public:
|
||||||
writeOKFrame();
|
writeOKFrame();
|
||||||
} else if (cmd_frame[0] == CMD_GET_CHANNEL && len >= 2) {
|
} else if (cmd_frame[0] == CMD_GET_CHANNEL && len >= 2) {
|
||||||
uint8_t channel_idx = cmd_frame[1];
|
uint8_t channel_idx = cmd_frame[1];
|
||||||
mesh::GroupChannel channel;
|
ChannelDetails channel;
|
||||||
if (getChannel(channel_idx, channel)) {
|
if (getChannel(channel_idx, channel)) {
|
||||||
out_frame[0] = RESP_CODE_CHANNEL_INFO;
|
int i = 0;
|
||||||
out_frame[1] = channel_idx;
|
out_frame[i++] = RESP_CODE_CHANNEL_INFO;
|
||||||
memcpy(&out_frame[2], channel.secret, 16); // NOTE: only 128-bit supported
|
out_frame[i++] = channel_idx;
|
||||||
_serial->writeFrame(out_frame, 2 + 16);
|
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 {
|
} else {
|
||||||
writeErrFrame();
|
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)
|
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];
|
uint8_t channel_idx = cmd_frame[1];
|
||||||
mesh::GroupChannel channel;
|
ChannelDetails channel;
|
||||||
memset(channel.secret, 0, sizeof(channel.secret));
|
StrHelper::strncpy(channel.name, (char *) &cmd_frame[2], 32);
|
||||||
memcpy(channel.secret, &cmd_frame[2], 16); // NOTE: only 128-bit supported
|
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)) {
|
if (setChannel(channel_idx, channel)) {
|
||||||
saveChannels();
|
saveChannels();
|
||||||
writeOKFrame();
|
writeOKFrame();
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ class MyMesh : public BaseChatMesh, ContactVisitor {
|
||||||
FILESYSTEM* _fs;
|
FILESYSTEM* _fs;
|
||||||
NodePrefs _prefs;
|
NodePrefs _prefs;
|
||||||
uint32_t expected_ack_crc;
|
uint32_t expected_ack_crc;
|
||||||
mesh::GroupChannel* _public;
|
ChannelDetails* _public;
|
||||||
unsigned long last_msg_sent;
|
unsigned long last_msg_sent;
|
||||||
ContactInfo* curr_recipient;
|
ContactInfo* curr_recipient;
|
||||||
char command[512+10];
|
char command[512+10];
|
||||||
|
|
@ -337,7 +337,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
loadContacts();
|
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() {
|
void savePrefs() {
|
||||||
|
|
@ -405,7 +405,7 @@ public:
|
||||||
temp[5 + MAX_TEXT_LEN] = 0; // truncate if too long
|
temp[5 + MAX_TEXT_LEN] = 0; // truncate if too long
|
||||||
|
|
||||||
int len = strlen((char *) &temp[5]);
|
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) {
|
if (pkt) {
|
||||||
sendFlood(pkt);
|
sendFlood(pkt);
|
||||||
Serial.println(" Sent.");
|
Serial.println(" Sent.");
|
||||||
|
|
|
||||||
|
|
@ -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 BaseChatMesh::searchChannelsByHash(const uint8_t* hash, mesh::GroupChannel dest[], int max_matches) {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (int i = 0; i < MAX_GROUP_CHANNELS && n < max_matches; i++) {
|
for (int i = 0; i < MAX_GROUP_CHANNELS && n < max_matches; i++) {
|
||||||
if (channels[i].hash[0] == hash[0]) {
|
if (channels[i].channel.hash[0] == hash[0]) {
|
||||||
dest[n++] = channels[i];
|
dest[n++] = channels[i].channel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
|
|
@ -588,36 +588,37 @@ bool BaseChatMesh::removeContact(ContactInfo& contact) {
|
||||||
#ifdef MAX_GROUP_CHANNELS
|
#ifdef MAX_GROUP_CHANNELS
|
||||||
#include <base64.hpp>
|
#include <base64.hpp>
|
||||||
|
|
||||||
mesh::GroupChannel* BaseChatMesh::addChannel(const char* psk_base64) {
|
ChannelDetails* BaseChatMesh::addChannel(const char* name, const char* psk_base64) {
|
||||||
if (num_channels < MAX_GROUP_CHANNELS) {
|
if (num_channels < MAX_GROUP_CHANNELS) {
|
||||||
auto dest = &channels[num_channels];
|
auto dest = &channels[num_channels];
|
||||||
|
|
||||||
memset(dest->secret, 0, sizeof(dest->secret));
|
memset(dest->channel.secret, 0, sizeof(dest->channel.secret));
|
||||||
int len = decode_base64((unsigned char *) psk_base64, strlen(psk_base64), dest->secret);
|
int len = decode_base64((unsigned char *) psk_base64, strlen(psk_base64), dest->channel.secret);
|
||||||
if (len == 32 || len == 16) {
|
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++;
|
num_channels++;
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
bool BaseChatMesh::getChannel(int idx, mesh::GroupChannel& dest) {
|
bool BaseChatMesh::getChannel(int idx, ChannelDetails& dest) {
|
||||||
if (idx >= 0 && idx < MAX_GROUP_CHANNELS) {
|
if (idx >= 0 && idx < MAX_GROUP_CHANNELS) {
|
||||||
dest = channels[idx];
|
dest = channels[idx];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
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 };
|
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) {
|
if (idx >= 0 && idx < MAX_GROUP_CHANNELS) {
|
||||||
channels[idx] = src;
|
channels[idx] = src;
|
||||||
if (memcmp(&src.secret[16], zeroes, 16) == 0) {
|
if (memcmp(&src.channel.secret[16], zeroes, 16) == 0) {
|
||||||
mesh::Utils::sha256(channels[idx].hash, sizeof(channels[idx].hash), src.secret, 16); // 128-bit key
|
mesh::Utils::sha256(channels[idx].channel.hash, sizeof(channels[idx].channel.hash), src.channel.secret, 16); // 128-bit key
|
||||||
} else {
|
} 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -625,18 +626,18 @@ bool BaseChatMesh::setChannel(int idx, const mesh::GroupChannel& src) {
|
||||||
}
|
}
|
||||||
int BaseChatMesh::findChannelIdx(const mesh::GroupChannel& ch) {
|
int BaseChatMesh::findChannelIdx(const mesh::GroupChannel& ch) {
|
||||||
for (int i = 0; i < MAX_GROUP_CHANNELS; i++) {
|
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
|
return -1; // not found
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
mesh::GroupChannel* BaseChatMesh::addChannel(const char* psk_base64) {
|
ChannelDetails* BaseChatMesh::addChannel(const char* psk_base64) {
|
||||||
return NULL; // not supported
|
return NULL; // not supported
|
||||||
}
|
}
|
||||||
bool BaseChatMesh::getChannel(int idx, mesh::GroupChannel& dest) {
|
bool BaseChatMesh::getChannel(int idx, ChannelDetails& dest) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool BaseChatMesh::setChannel(int idx, const mesh::GroupChannel& src) {
|
bool BaseChatMesh::setChannel(int idx, const ChannelDetails& src) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int BaseChatMesh::findChannelIdx(const mesh::GroupChannel& ch) {
|
int BaseChatMesh::findChannelIdx(const mesh::GroupChannel& ch) {
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,11 @@ struct ConnectionInfo {
|
||||||
uint32_t expected_ack;
|
uint32_t expected_ack;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ChannelDetails {
|
||||||
|
mesh::GroupChannel channel;
|
||||||
|
char name[32];
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief abstract Mesh class for common 'chat' client
|
* \brief abstract Mesh class for common 'chat' client
|
||||||
*/
|
*/
|
||||||
|
|
@ -74,7 +79,7 @@ class BaseChatMesh : public mesh::Mesh {
|
||||||
int matching_peer_indexes[MAX_SEARCH_RESULTS];
|
int matching_peer_indexes[MAX_SEARCH_RESULTS];
|
||||||
unsigned long txt_send_timeout;
|
unsigned long txt_send_timeout;
|
||||||
#ifdef MAX_GROUP_CHANNELS
|
#ifdef MAX_GROUP_CHANNELS
|
||||||
mesh::GroupChannel channels[MAX_GROUP_CHANNELS];
|
ChannelDetails channels[MAX_GROUP_CHANNELS];
|
||||||
int num_channels; // only for addChannel()
|
int num_channels; // only for addChannel()
|
||||||
#endif
|
#endif
|
||||||
mesh::Packet* _pendingLoopback;
|
mesh::Packet* _pendingLoopback;
|
||||||
|
|
@ -152,9 +157,9 @@ public:
|
||||||
bool addContact(const ContactInfo& contact);
|
bool addContact(const ContactInfo& contact);
|
||||||
int getNumContacts() const { return num_contacts; }
|
int getNumContacts() const { return num_contacts; }
|
||||||
ContactsIterator startContactsIterator();
|
ContactsIterator startContactsIterator();
|
||||||
mesh::GroupChannel* addChannel(const char* psk_base64);
|
ChannelDetails* addChannel(const char* name, const char* psk_base64);
|
||||||
bool getChannel(int idx, mesh::GroupChannel& dest);
|
bool getChannel(int idx, ChannelDetails& dest);
|
||||||
bool setChannel(int idx, const mesh::GroupChannel& src);
|
bool setChannel(int idx, const ChannelDetails& src);
|
||||||
int findChannelIdx(const mesh::GroupChannel& ch);
|
int findChannelIdx(const mesh::GroupChannel& ch);
|
||||||
|
|
||||||
void loop();
|
void loop();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue