Эх сурвалжийг харах

* companion: new CMD_GET_ADVERT_PATH -> RESP_CODE_ADVERT_PATH

Scott Powell 1 жил өмнө
parent
commit
e6ce3c896d

+ 45 - 1
examples/companion_radio/MyMesh.cpp

@@ -44,6 +44,7 @@
 #define CMD_SEND_TELEMETRY_REQ        39
 #define CMD_GET_CUSTOM_VARS           40
 #define CMD_SET_CUSTOM_VAR            41
+#define CMD_GET_ADVERT_PATH           42
 
 #define RESP_CODE_OK                  0
 #define RESP_CODE_ERR                 1
@@ -67,6 +68,7 @@
 #define RESP_CODE_SIGN_START          19
 #define RESP_CODE_SIGNATURE           20
 #define RESP_CODE_CUSTOM_VARS         21
+#define RESP_CODE_ADVERT_PATH         22
 
 #define SEND_TIMEOUT_BASE_MILLIS        500
 #define FLOOD_SEND_TIMEOUT_FACTOR       16.0f
@@ -219,7 +221,7 @@ bool MyMesh::isAutoAddEnabled() const {
   return (_prefs.manual_add_contacts & 1) == 0;
 }
 
-void MyMesh::onDiscoveredContact(ContactInfo &contact, bool is_new) {
+void MyMesh::onDiscoveredContact(ContactInfo &contact, bool is_new, uint8_t path_len, const uint8_t* path) {
   if (_serial->isConnected()) {
     if (!isAutoAddEnabled() && is_new) {
       writeContactRespFrame(PUSH_CODE_NEW_ADVERT, contact);
@@ -234,6 +236,27 @@ void MyMesh::onDiscoveredContact(ContactInfo &contact, bool is_new) {
 #endif
   }
 
+  // add inbound-path to mem cache
+  if (path && path_len <= sizeof(AdvertPath::path)) {  // check path is valid
+    AdvertPath* p = advert_paths;
+    uint32_t oldest = 0xFFFFFFFF;
+    for (int i = 0; i < ADVERT_PATH_TABLE_SIZE; i++) {   // check if already in table, otherwise evict oldest
+      if (memcmp(advert_paths[i].pubkey_prefix, contact.id.pub_key, sizeof(AdvertPath::pubkey_prefix)) == 0) {
+        p = &advert_paths[i];   // found
+        break;
+      }
+      if (advert_paths[i].recv_timestamp < oldest) {
+        oldest = advert_paths[i].recv_timestamp;
+        p = &advert_paths[i];
+      }
+    }
+
+    memcpy(p->pubkey_prefix, contact.id.pub_key, sizeof(p->pubkey_prefix));
+    p->recv_timestamp = getRTCClock()->getCurrentTime();
+    p->path_len = path_len;
+    memcpy(p->path, path, p->path_len);
+  }
+
   dirty_contacts_expiry = futureMillis(LAZY_CONTACTS_WRITE_DELAY);
 }
 
@@ -541,6 +564,7 @@ MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMe
   next_ack_idx = 0;
   sign_data = NULL;
   dirty_contacts_expiry = 0;
+  memset(advert_paths, 0, sizeof(advert_paths));
 
   // defaults
   memset(&_prefs, 0, sizeof(_prefs));
@@ -1249,6 +1273,26 @@ void MyMesh::handleCmdFrame(size_t len) {
     } else {
       writeErrFrame(ERR_CODE_ILLEGAL_ARG);
     }
+  } else if (cmd_frame[0] == CMD_GET_ADVERT_PATH && len >= PUB_KEY_SIZE+2) {
+    // FUTURE use:  uint8_t reserved = cmd_frame[1];
+    uint8_t *pub_key = &cmd_frame[2];
+    AdvertPath* found = NULL;
+    for (int i = 0; i < ADVERT_PATH_TABLE_SIZE; i++) {
+      auto p = &advert_paths[i];
+      if (memcmp(p->pubkey_prefix, pub_key, sizeof(p->pubkey_prefix)) == 0) {
+        found = p;
+        break;
+      }
+    }
+    if (found) {
+      out_frame[0] = RESP_CODE_ADVERT_PATH;
+      memcpy(&out_frame[1], &found->recv_timestamp, 4);
+      out_frame[5] = found->path_len;
+      memcpy(&out_frame[6], found->path, found->path_len);
+      _serial->writeFrame(out_frame, 6 + found->path_len);
+    } else {
+      writeErrFrame(ERR_CODE_NOT_FOUND);
+    }
   } else {
     writeErrFrame(ERR_CODE_UNSUPPORTED_CMD);
     MESH_DEBUG_PRINTLN("ERROR: unknown command: %02X", cmd_frame[0]);

+ 11 - 2
examples/companion_radio/MyMesh.h

@@ -100,7 +100,7 @@ protected:
 
   void logRxRaw(float snr, float rssi, const uint8_t raw[], int len) override;
   bool isAutoAddEnabled() const override;
-  void onDiscoveredContact(ContactInfo &contact, bool is_new) override;
+  void onDiscoveredContact(ContactInfo &contact, bool is_new, uint8_t path_len, const uint8_t* path) override;
   void onContactPathUpdated(const ContactInfo &contact) override;
   bool processAck(const uint8_t *data) override;
   void queueMessage(const ContactInfo &from, uint8_t txt_type, mesh::Packet *pkt, uint32_t sender_timestamp,
@@ -190,9 +190,18 @@ private:
     unsigned long msg_sent;
     uint32_t ack;
   };
-#define EXPECTED_ACK_TABLE_SIZE 8
+  #define EXPECTED_ACK_TABLE_SIZE 8
   AckTableEntry expected_ack_table[EXPECTED_ACK_TABLE_SIZE]; // circular table
   int next_ack_idx;
+
+  struct AdvertPath {
+    uint8_t pubkey_prefix[7];
+    uint8_t path_len;
+    uint32_t recv_timestamp;
+    uint8_t path[MAX_PATH_SIZE];
+  };
+  #define ADVERT_PATH_TABLE_SIZE   16
+  AdvertPath advert_paths[ADVERT_PATH_TABLE_SIZE]; // circular table
 };
 
 extern MyMesh the_mesh;

+ 1 - 1
examples/simple_secure_chat/main.cpp

@@ -202,7 +202,7 @@ protected:
     return true;
   }
 
-  void onDiscoveredContact(ContactInfo& contact, bool is_new) override {
+  void onDiscoveredContact(ContactInfo& contact, bool is_new, uint8_t path_len, const uint8_t* path) override {
     // TODO: if not in favs,  prompt to add as fav(?)
 
     Serial.printf("ADVERT from -> %s\n", contact.name);

+ 2 - 2
src/helpers/BaseChatMesh.cpp

@@ -58,7 +58,7 @@ void BaseChatMesh::onAdvertRecv(mesh::Packet* packet, const mesh::Identity& id,
       }
       ci.last_advert_timestamp = timestamp;
       ci.lastmod = getRTCClock()->getCurrentTime();
-      onDiscoveredContact(ci, true);       // let UI know
+      onDiscoveredContact(ci, true, packet->path_len, packet->path);       // let UI know
       return;
     }
 
@@ -89,7 +89,7 @@ void BaseChatMesh::onAdvertRecv(mesh::Packet* packet, const mesh::Identity& id,
   from->last_advert_timestamp = timestamp;
   from->lastmod = getRTCClock()->getCurrentTime();
 
-  onDiscoveredContact(*from, is_new);       // let UI know
+  onDiscoveredContact(*from, is_new, packet->path_len, packet->path);       // let UI know
 }
 
 int BaseChatMesh::searchPeersByHash(const uint8_t* hash) {

+ 1 - 1
src/helpers/BaseChatMesh.h

@@ -89,7 +89,7 @@ protected:
 
   // 'UI' concepts, for sub-classes to implement
   virtual bool isAutoAddEnabled() const { return true; }
-  virtual void onDiscoveredContact(ContactInfo& contact, bool is_new) = 0;
+  virtual void onDiscoveredContact(ContactInfo& contact, bool is_new, uint8_t path_len, const uint8_t* path) = 0;
   virtual bool processAck(const uint8_t *data) = 0;
   virtual void onContactPathUpdated(const ContactInfo& contact) = 0;
   virtual void onMessageRecv(const ContactInfo& contact, mesh::Packet* pkt, uint32_t sender_timestamp, const char *text) = 0;