diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index 48eafbf2..3932ba82 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -113,7 +113,7 @@ static uint32_t _atoi(const char* sp) { #define CMD_IMPORT_CONTACT 18 #define CMD_REBOOT 19 #define CMD_GET_BATTERY_VOLTAGE 20 -#define CMD_SET_TUNING_PARAMS 21 +#define CMD_SET_OTHER_PARAMS 21 #define CMD_DEVICE_QEURY 22 #define CMD_EXPORT_PRIVATE_KEY 23 #define CMD_IMPORT_PRIVATE_KEY 24 @@ -164,6 +164,7 @@ static uint32_t _atoi(const char* sp) { #define PUSH_CODE_STATUS_RESPONSE 0x87 #define PUSH_CODE_LOG_RX_DATA 0x88 #define PUSH_CODE_TRACE_DATA 0x89 +#define PUSH_CODE_NEW_ADVERT 0x8A #define ERR_CODE_UNSUPPORTED_CMD 1 #define ERR_CODE_NOT_FOUND 2 @@ -184,7 +185,7 @@ struct NodePrefs { // persisted to file uint8_t sf; uint8_t cr; uint8_t reserved1; - uint8_t reserved2; + uint8_t manual_add_contacts; float bw; uint8_t tx_power_dbm; uint8_t unused[3]; @@ -499,11 +500,19 @@ protected: } } + bool isAutoAddEnabled() const override { + return (_prefs.manual_add_contacts & 1) == 0; + } + void onDiscoveredContact(ContactInfo& contact, bool is_new) override { if (_serial->isConnected()) { - out_frame[0] = PUSH_CODE_ADVERT; - memcpy(&out_frame[1], contact.id.pub_key, PUB_KEY_SIZE); - _serial->writeFrame(out_frame, 1 + PUB_KEY_SIZE); + if (!isAutoAddEnabled() && is_new) { + writeContactRespFrame(PUSH_CODE_NEW_ADVERT, contact); + } else { + out_frame[0] = PUSH_CODE_ADVERT; + memcpy(&out_frame[1], contact.id.pub_key, PUB_KEY_SIZE); + _serial->writeFrame(out_frame, 1 + PUB_KEY_SIZE); + } } else { soundBuzzer(); } @@ -750,7 +759,7 @@ public: file.read((uint8_t *) &_prefs.sf, sizeof(_prefs.sf)); // 60 file.read((uint8_t *) &_prefs.cr, sizeof(_prefs.cr)); // 61 file.read((uint8_t *) &_prefs.reserved1, sizeof(_prefs.reserved1)); // 62 - file.read((uint8_t *) &_prefs.reserved2, sizeof(_prefs.reserved2)); // 63 + file.read((uint8_t *) &_prefs.manual_add_contacts, sizeof(_prefs.manual_add_contacts)); // 63 file.read((uint8_t *) &_prefs.bw, sizeof(_prefs.bw)); // 64 file.read((uint8_t *) &_prefs.tx_power_dbm, sizeof(_prefs.tx_power_dbm)); // 68 file.read((uint8_t *) _prefs.unused, sizeof(_prefs.unused)); // 69 @@ -851,7 +860,7 @@ public: file.write((uint8_t *) &_prefs.sf, sizeof(_prefs.sf)); // 60 file.write((uint8_t *) &_prefs.cr, sizeof(_prefs.cr)); // 61 file.write((uint8_t *) &_prefs.reserved1, sizeof(_prefs.reserved1)); // 62 - file.write((uint8_t *) &_prefs.reserved2, sizeof(_prefs.reserved2)); // 63 + file.write((uint8_t *) &_prefs.manual_add_contacts, sizeof(_prefs.manual_add_contacts)); // 63 file.write((uint8_t *) &_prefs.bw, sizeof(_prefs.bw)); // 64 file.write((uint8_t *) &_prefs.tx_power_dbm, sizeof(_prefs.tx_power_dbm)); // 68 file.write((uint8_t *) _prefs.unused, sizeof(_prefs.unused)); // 69 @@ -892,12 +901,15 @@ public: out_frame[i++] = MAX_LORA_TX_POWER; memcpy(&out_frame[i], self_id.pub_key, PUB_KEY_SIZE); i += PUB_KEY_SIZE; - int32_t lat, lon, alt = 0; + int32_t lat, lon; lat = (_prefs.node_lat * 1000000.0); lon = (_prefs.node_lon * 1000000.0); memcpy(&out_frame[i], &lat, 4); i += 4; memcpy(&out_frame[i], &lon, 4); i += 4; - memcpy(&out_frame[i], &alt, 4); i += 4; + out_frame[i++] = 0; // reserved + out_frame[i++] = 0; // reserved + out_frame[i++] = 0; // reserved + out_frame[i++] = _prefs.manual_add_contacts; uint32_t freq = _prefs.freq * 1000; memcpy(&out_frame[i], &freq, 4); i += 4; @@ -1172,13 +1184,16 @@ public: radio_set_tx_power(_prefs.tx_power_dbm); writeOKFrame(); } - } else if (cmd_frame[0] == CMD_SET_TUNING_PARAMS) { + } else if (cmd_frame[0] == CMD_SET_OTHER_PARAMS) { int i = 1; uint32_t rx, af; memcpy(&rx, &cmd_frame[i], 4); i += 4; memcpy(&af, &cmd_frame[i], 4); i += 4; _prefs.rx_delay_base = ((float)rx) / 1000.0f; _prefs.airtime_factor = ((float)af) / 1000.0f; + if (i < len) { + _prefs.manual_add_contacts = cmd_frame[i++]; + } savePrefs(); writeOKFrame(); } else if (cmd_frame[0] == CMD_REBOOT && memcmp(&cmd_frame[1], "reboot", 6) == 0) { diff --git a/src/helpers/BaseChatMesh.cpp b/src/helpers/BaseChatMesh.cpp index 989fcb2c..97aefff4 100644 --- a/src/helpers/BaseChatMesh.cpp +++ b/src/helpers/BaseChatMesh.cpp @@ -31,8 +31,29 @@ void BaseChatMesh::onAdvertRecv(mesh::Packet* packet, const mesh::Identity& id, } } + // save a copy of raw advert packet (to support "Share..." function) + int plen = packet->writeTo(temp_buf); + putBlobByKey(id.pub_key, PUB_KEY_SIZE, temp_buf, plen); + bool is_new = false; if (from == NULL) { + if (!isAutoAddEnabled()) { + ContactInfo ci; + memset(&ci, 0, sizeof(ci)); + ci.id = id; + ci.out_path_len = -1; // initially out_path is unknown + StrHelper::strncpy(ci.name, parser.getName(), sizeof(ci.name)); + ci.type = parser.getType(); + if (parser.hasLatLon()) { + ci.gps_lat = parser.getIntLat(); + ci.gps_lon = parser.getIntLon(); + } + ci.last_advert_timestamp = timestamp; + ci.lastmod = getRTCClock()->getCurrentTime(); + onDiscoveredContact(ci, true); // let UI know + return; + } + is_new = true; if (num_contacts < MAX_CONTACTS) { from = &contacts[num_contacts++]; @@ -50,10 +71,6 @@ void BaseChatMesh::onAdvertRecv(mesh::Packet* packet, const mesh::Identity& id, } } - // save a copy of raw advert packet (to support "Share..." function) - int plen = packet->writeTo(temp_buf); - putBlobByKey(id.pub_key, PUB_KEY_SIZE, temp_buf, plen); - // update StrHelper::strncpy(from->name, parser.getName(), sizeof(from->name)); from->type = parser.getType(); diff --git a/src/helpers/BaseChatMesh.h b/src/helpers/BaseChatMesh.h index 30598f6c..ed6e1c3a 100644 --- a/src/helpers/BaseChatMesh.h +++ b/src/helpers/BaseChatMesh.h @@ -103,6 +103,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 bool processAck(const uint8_t *data) = 0; virtual void onContactPathUpdated(const ContactInfo& contact) = 0;