* chat sample updated to auto-add Chat node advertisements

This commit is contained in:
Scott Powell 2025-01-17 02:12:58 +11:00
parent 9b09545379
commit 4bf7d7d58f

View file

@ -51,9 +51,10 @@
/* -------------------------------------------------------------------------------------- */
static unsigned long txt_send_timeout;
static int curr_contact_idx = 0;
#define MAX_CONTACTS 1
#define MAX_SEARCH_RESULTS 1
#define MAX_CONTACTS 8
#define MAX_SEARCH_RESULTS 2
#define MAX_TEXT_LEN (10*CIPHER_BLOCK_SIZE) // must be LESS than (MAX_PACKET_PAYLOAD - 4 - CIPHER_MAC_SIZE - 1)
@ -73,8 +74,10 @@ public:
void addContact(const char* name, const mesh::Identity& id) {
if (num_contacts < MAX_CONTACTS) {
curr_contact_idx = num_contacts; // auto-select this contact as current selection
contacts[num_contacts].id = id;
contacts[num_contacts].name = name;
contacts[num_contacts].name = strdup(name);
contacts[num_contacts].last_advert_timestamp = 0;
contacts[num_contacts].out_path_len = -1;
// only need to calculate the shared_secret once, for better performance
@ -96,6 +99,16 @@ protected:
return n;
}
#define ADV_TYPE_NONE 0 // unknown
#define ADV_TYPE_CHAT 1
#define ADV_TYPE_REPEATER 2
//FUTURE: 3..15
#define ADV_LATLON_MASK 0x10
#define ADV_BATTERY_MASK 0x20
#define ADV_TEMPERATURE_MASK 0x40
#define ADV_NAME_MASK 0x80
void onAdvertRecv(mesh::Packet* packet, const mesh::Identity& id, uint32_t timestamp, const uint8_t* app_data, size_t app_data_len) override {
Serial.print("Valid Advertisement -> ");
mesh::Utils::printHex(Serial, id.pub_key, PUB_KEY_SIZE);
@ -103,12 +116,26 @@ protected:
for (int i = 0; i < num_contacts; i++) {
ContactInfo& from = contacts[i];
// check for replay attacks
if (id.matches(from.id) && timestamp > from.last_advert_timestamp) { // is from one of our contacts
from.last_advert_timestamp = timestamp;
Serial.printf(" From contact: %s\n", from.name);
if (id.matches(from.id)) { // is from one of our contacts
if (timestamp > from.last_advert_timestamp) { // check for replay attacks!!
from.last_advert_timestamp = timestamp;
Serial.printf(" From contact: %s\n", from.name);
}
return;
}
}
// unknown node
if (app_data_len > 0 && app_data[0] == (ADV_TYPE_CHAT | ADV_NAME_MASK)) { // is it a 'Chat' node (with a name)?
// automatically add to our contacts
char name[32];
memcpy(name, &app_data[1], app_data_len - 1);
name[app_data_len - 1] = 0; // need null terminator
addContact(name, id);
Serial.printf(" ADDED contact: %s\n", name);
} else {
Serial.printf(" Unknown app_data type: %02X, len=%d\n", app_data[0], app_data_len);
}
}
void getPeerSharedSecret(uint8_t* dest_secret, int peer_idx) override {
@ -234,16 +261,6 @@ public:
return createDatagram(PAYLOAD_TYPE_TXT_MSG, recipient.id, recipient.shared_secret, temp, 5 + text_len);
}
#define ADV_TYPE_NONE 0 // unknown
#define ADV_TYPE_CHAT 1
#define ADV_TYPE_REPEATER 2
//FUTURE: 3..15
#define ADV_LATLON_MASK 0x10
#define ADV_BATTERY_MASK 0x20
#define ADV_TEMPERATURE_MASK 0x40
#define ADV_NAME_MASK 0x80
void sendSelfAdvert() {
uint8_t app_data[32];
app_data[0] = ADV_TYPE_CHAT | ADV_NAME_MASK;
@ -347,7 +364,7 @@ void loop() {
if (memcmp(command, "send ", 5) == 0) {
// TODO: some way to select recipient??
ContactInfo& recipient = the_mesh.contacts[0]; // just send to first contact for now
ContactInfo& recipient = the_mesh.contacts[curr_contact_idx];
const char *text = &command[5];
mesh::Packet* pkt = the_mesh.composeMsgPacket(recipient, 0, text);
@ -383,7 +400,7 @@ void loop() {
if (txt_send_timeout && the_mesh.millisHasNowPassed(txt_send_timeout)) {
// failed to get an ACK
ContactInfo& recipient = the_mesh.contacts[0]; // just the one contact for now
ContactInfo& recipient = the_mesh.contacts[curr_contact_idx];
Serial.println(" ERROR: timed out, no ACK.");
// path to our contact is now possibly broken, fallback to Flood mode