From 4bf7d7d58f81a7a9573944d55f82cca7ed283500 Mon Sep 17 00:00:00 2001 From: Scott Powell Date: Fri, 17 Jan 2025 02:12:58 +1100 Subject: [PATCH] * chat sample updated to auto-add Chat node advertisements --- examples/simple_secure_chat/main.cpp | 55 ++++++++++++++++++---------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/examples/simple_secure_chat/main.cpp b/examples/simple_secure_chat/main.cpp index 5aa5aba5..91d873eb 100644 --- a/examples/simple_secure_chat/main.cpp +++ b/examples/simple_secure_chat/main.cpp @@ -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