|
|
|
@ -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]); |
|
|
|
|