diff --git a/examples/simple_repeater/MyMesh.cpp b/examples/simple_repeater/MyMesh.cpp index 261184c5..eb561939 100644 --- a/examples/simple_repeater/MyMesh.cpp +++ b/examples/simple_repeater/MyMesh.cpp @@ -52,6 +52,7 @@ #define RESP_SERVER_LOGIN_OK 0 // response to ANON_REQ #define ANON_REQ_TYPE_REGIONS 0x01 +#define ANON_REQ_TYPE_VER_OWNER 0x02 #define CLI_REPLY_DELAY_MILLIS 600 @@ -142,7 +143,7 @@ uint8_t MyMesh::handleLoginReq(const mesh::Identity& sender, const uint8_t* secr } uint8_t MyMesh::handleAnonRegionsReq(const mesh::Identity& sender, uint32_t sender_timestamp, const uint8_t* data) { - if (regions_limiter.allow(rtc_clock.getCurrentTime())) { + if (anon_limiter.allow(rtc_clock.getCurrentTime())) { // request data has: {reply-path-len}{reply-path} reply_path_len = *data++ & 0x3F; memcpy(reply_path, data, reply_path_len); @@ -159,6 +160,26 @@ uint8_t MyMesh::handleAnonRegionsReq(const mesh::Identity& sender, uint32_t send return 0; } +uint8_t MyMesh::handleAnonVerOwnerReq(const mesh::Identity& sender, uint32_t sender_timestamp, const uint8_t* data) { + if (anon_limiter.allow(rtc_clock.getCurrentTime())) { + // request data has: {reply-path-len}{reply-path} + reply_path_len = *data++ & 0x3F; + memcpy(reply_path, data, reply_path_len); + // data += reply_path_len; + // other params?? + + memcpy(reply_data, &sender_timestamp, 4); // prefix with sender_timestamp, like a tag + + uint32_t now = getRTCClock()->getCurrentTime(); + memcpy(&reply_data[4], &now, 4); // include our clock (for easy clock sync, if this is a trusted node) + + sprintf((char *) &reply_data[8], "%s,%s", FIRMWARE_VERSION, _prefs.owner_info); + + return 8 + strlen((char *) &reply_data[8]); // reply length + } + return 0; +} + int MyMesh::handleRequest(ClientInfo *sender, uint32_t sender_timestamp, uint8_t *payload, size_t payload_len) { // uint32_t now = getRTCClock()->getCurrentTimeUnique(); // memcpy(reply_data, &now, 4); // response packets always prefixed with timestamp @@ -474,6 +495,8 @@ void MyMesh::onAnonDataRecv(mesh::Packet *packet, const uint8_t *secret, const m reply_len = handleLoginReq(sender, secret, timestamp, &data[4], packet->isRouteFlood()); } else if (data[4] == ANON_REQ_TYPE_REGIONS && packet->isRouteDirect()) { reply_len = handleAnonRegionsReq(sender, timestamp, &data[5]); + } else if (data[4] == ANON_REQ_TYPE_VER_OWNER && packet->isRouteDirect()) { + reply_len = handleAnonVerOwnerReq(sender, timestamp, &data[5]); } else { reply_len = 0; // unknown/invalid request type } @@ -694,7 +717,7 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc : mesh::Mesh(radio, ms, rng, rtc, *new StaticPoolPacketManager(32), tables), _cli(board, rtc, sensors, &_prefs, this), telemetry(MAX_PACKET_PAYLOAD - 4), region_map(key_store), temp_map(key_store), discover_limiter(4, 120), // max 4 every 2 minutes - regions_limiter(4, 180) // max 4 every 3 minutes + anon_limiter(4, 180) // max 4 every 3 minutes #if defined(WITH_RS232_BRIDGE) , bridge(&_prefs, WITH_RS232_BRIDGE, _mgr, &rtc) #endif diff --git a/examples/simple_repeater/MyMesh.h b/examples/simple_repeater/MyMesh.h index 49952770..f63aee24 100644 --- a/examples/simple_repeater/MyMesh.h +++ b/examples/simple_repeater/MyMesh.h @@ -95,7 +95,7 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks { RegionMap region_map, temp_map; RegionEntry* load_stack[8]; RegionEntry* recv_pkt_region; - RateLimiter discover_limiter, regions_limiter; + RateLimiter discover_limiter, anon_limiter; bool region_load_active; unsigned long dirty_contacts_expiry; #if MAX_NEIGHBOURS @@ -117,6 +117,7 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks { void putNeighbour(const mesh::Identity& id, uint32_t timestamp, float snr); uint8_t handleLoginReq(const mesh::Identity& sender, const uint8_t* secret, uint32_t sender_timestamp, const uint8_t* data, bool is_flood); uint8_t handleAnonRegionsReq(const mesh::Identity& sender, uint32_t sender_timestamp, const uint8_t* data); + uint8_t handleAnonVerOwnerReq(const mesh::Identity& sender, uint32_t sender_timestamp, const uint8_t* data); int handleRequest(ClientInfo* sender, uint32_t sender_timestamp, uint8_t* payload, size_t payload_len); mesh::Packet* createSelfAdvert(); diff --git a/src/helpers/CommonCLI.cpp b/src/helpers/CommonCLI.cpp index 78e1b5e0..14b67b39 100644 --- a/src/helpers/CommonCLI.cpp +++ b/src/helpers/CommonCLI.cpp @@ -72,7 +72,8 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) { file.read((uint8_t *)&_prefs->advert_loc_policy, sizeof (_prefs->advert_loc_policy)); // 161 file.read((uint8_t *)&_prefs->discovery_mod_timestamp, sizeof(_prefs->discovery_mod_timestamp)); // 162 file.read((uint8_t *)&_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier)); // 166 - // 170 + file.read((uint8_t *)_prefs->owner_info, sizeof(_prefs->owner_info)); // 170 + // 290 // sanitise bad pref values _prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f); @@ -155,7 +156,8 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) { file.write((uint8_t *)&_prefs->advert_loc_policy, sizeof(_prefs->advert_loc_policy)); // 161 file.write((uint8_t *)&_prefs->discovery_mod_timestamp, sizeof(_prefs->discovery_mod_timestamp)); // 162 file.write((uint8_t *)&_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier)); // 166 - // 170 + file.write((uint8_t *)_prefs->owner_info, sizeof(_prefs->owner_info)); // 170 + // 290 file.close(); } @@ -301,6 +303,15 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch sprintf(reply, "> %d", (uint32_t)_prefs->flood_max); } else if (memcmp(config, "direct.txdelay", 14) == 0) { sprintf(reply, "> %s", StrHelper::ftoa(_prefs->direct_tx_delay_factor)); + } else if (memcmp(config, "owner.info", 10) == 0) { + *reply++ = '>'; + *reply++ = ' '; + const char* sp = _prefs->owner_info; + while (*sp) { + *reply++ = (*sp == '\n') ? '|' : *sp; // translate newline back to orig '|' + sp++; + } + *reply = 0; // set null terminator } else if (memcmp(config, "tx", 2) == 0 && (config[2] == 0 || config[2] == ' ')) { sprintf(reply, "> %d", (uint32_t) _prefs->tx_power_dbm); } else if (memcmp(config, "freq", 4) == 0) { @@ -479,6 +490,16 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch } else { strcpy(reply, "Error, cannot be negative"); } + } else if (memcmp(config, "owner.info ", 11) == 0) { + config += 11; + char *dp = _prefs->owner_info; + while (*config && dp - _prefs->owner_info < sizeof(_prefs->owner_info)-1) { + *dp++ = (*config == '|') ? '\n' : *config; // translate '|' to newline chars + config++; + } + *dp = 0; + savePrefs(); + strcpy(reply, "OK"); } else if (memcmp(config, "tx ", 3) == 0) { _prefs->tx_power_dbm = atoi(&config[3]); savePrefs(); diff --git a/src/helpers/CommonCLI.h b/src/helpers/CommonCLI.h index 642a4cce..3b1d05f9 100644 --- a/src/helpers/CommonCLI.h +++ b/src/helpers/CommonCLI.h @@ -50,6 +50,7 @@ struct NodePrefs { // persisted to file uint8_t advert_loc_policy; uint32_t discovery_mod_timestamp; float adc_multiplier; + char owner_info[120]; }; class CommonCLICallbacks {