mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-04-20 22:13:47 +00:00
merge: integrate upstream dev (refactored CLI into handleGetCmd/handleSetCmd)
Resolves conflict in src/helpers/CommonCLI.cpp where upstream extracted the get/set handlers into separate methods. Our region.autotag and region.autotag.max.hops commands are now placed in the new handleGetCmd and handleSetCmd methods.
This commit is contained in:
commit
4751380d4e
30 changed files with 1391 additions and 854 deletions
|
|
@ -413,6 +413,19 @@ bool MyMesh::isLooped(const mesh::Packet* packet, const uint8_t max_counters[])
|
|||
return n >= max_counters[hash_size];
|
||||
}
|
||||
|
||||
void MyMesh::sendFloodReply(mesh::Packet* packet, unsigned long delay_millis, uint8_t path_hash_size) {
|
||||
if (recv_pkt_region && !recv_pkt_region->isWildcard()) { // if _request_ packet scope is known, send reply with same scope
|
||||
TransportKey scope;
|
||||
if (region_map.getTransportKeysFor(*recv_pkt_region, &scope, 1) > 0) {
|
||||
sendFloodScoped(scope, packet, delay_millis, path_hash_size);
|
||||
} else {
|
||||
sendFlood(packet, delay_millis, path_hash_size); // send un-scoped
|
||||
}
|
||||
} else {
|
||||
sendFlood(packet, delay_millis, path_hash_size); // send un-scoped
|
||||
}
|
||||
}
|
||||
|
||||
bool MyMesh::allowPacketForward(const mesh::Packet *packet) {
|
||||
if (_prefs.disable_fwd) return false;
|
||||
if (packet->isRouteFlood() && packet->getPathHashCount() >= _prefs.flood_max) return false;
|
||||
|
|
@ -609,10 +622,10 @@ void MyMesh::onAnonDataRecv(mesh::Packet *packet, const uint8_t *secret, const m
|
|||
// let this sender know path TO here, so they can use sendDirect(), and ALSO encode the response
|
||||
mesh::Packet* path = createPathReturn(sender, secret, packet->path, packet->path_len,
|
||||
PAYLOAD_TYPE_RESPONSE, reply_data, reply_len);
|
||||
if (path) sendFlood(path, SERVER_RESPONSE_DELAY, packet->getPathHashSize());
|
||||
if (path) sendFloodReply(path, SERVER_RESPONSE_DELAY, packet->getPathHashSize());
|
||||
} else if (reply_path_len < 0) {
|
||||
mesh::Packet* reply = createDatagram(PAYLOAD_TYPE_RESPONSE, sender, secret, reply_data, reply_len);
|
||||
if (reply) sendFlood(reply, SERVER_RESPONSE_DELAY, packet->getPathHashSize());
|
||||
if (reply) sendFloodReply(reply, SERVER_RESPONSE_DELAY, packet->getPathHashSize());
|
||||
} else {
|
||||
mesh::Packet* reply = createDatagram(PAYLOAD_TYPE_RESPONSE, sender, secret, reply_data, reply_len);
|
||||
uint8_t path_len = ((reply_path_hash_size - 1) << 6) | (reply_path_len & 63);
|
||||
|
|
@ -685,7 +698,7 @@ void MyMesh::onPeerDataRecv(mesh::Packet *packet, uint8_t type, int sender_idx,
|
|||
// let this sender know path TO here, so they can use sendDirect(), and ALSO encode the response
|
||||
mesh::Packet *path = createPathReturn(client->id, secret, packet->path, packet->path_len,
|
||||
PAYLOAD_TYPE_RESPONSE, reply_data, reply_len);
|
||||
if (path) sendFlood(path, SERVER_RESPONSE_DELAY, packet->getPathHashSize());
|
||||
if (path) sendFloodReply(path, SERVER_RESPONSE_DELAY, packet->getPathHashSize());
|
||||
} else {
|
||||
mesh::Packet *reply =
|
||||
createDatagram(PAYLOAD_TYPE_RESPONSE, client->id, secret, reply_data, reply_len);
|
||||
|
|
@ -693,7 +706,7 @@ void MyMesh::onPeerDataRecv(mesh::Packet *packet, uint8_t type, int sender_idx,
|
|||
if (client->out_path_len != OUT_PATH_UNKNOWN) { // we have an out_path, so send DIRECT
|
||||
sendDirect(reply, client->out_path, client->out_path_len, SERVER_RESPONSE_DELAY);
|
||||
} else {
|
||||
sendFlood(reply, SERVER_RESPONSE_DELAY, packet->getPathHashSize());
|
||||
sendFloodReply(reply, SERVER_RESPONSE_DELAY, packet->getPathHashSize());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -724,7 +737,7 @@ void MyMesh::onPeerDataRecv(mesh::Packet *packet, uint8_t type, int sender_idx,
|
|||
mesh::Packet *ack = createAck(ack_hash);
|
||||
if (ack) {
|
||||
if (client->out_path_len == OUT_PATH_UNKNOWN) {
|
||||
sendFlood(ack, TXT_ACK_DELAY, packet->getPathHashSize());
|
||||
sendFloodReply(ack, TXT_ACK_DELAY, packet->getPathHashSize());
|
||||
} else {
|
||||
sendDirect(ack, client->out_path, client->out_path_len, TXT_ACK_DELAY);
|
||||
}
|
||||
|
|
@ -752,7 +765,7 @@ void MyMesh::onPeerDataRecv(mesh::Packet *packet, uint8_t type, int sender_idx,
|
|||
auto reply = createDatagram(PAYLOAD_TYPE_TXT_MSG, client->id, secret, temp, 5 + text_len);
|
||||
if (reply) {
|
||||
if (client->out_path_len == OUT_PATH_UNKNOWN) {
|
||||
sendFlood(reply, CLI_REPLY_DELAY_MILLIS, packet->getPathHashSize());
|
||||
sendFloodReply(reply, CLI_REPLY_DELAY_MILLIS, packet->getPathHashSize());
|
||||
} else {
|
||||
sendDirect(reply, client->out_path, client->out_path_len, CLI_REPLY_DELAY_MILLIS);
|
||||
}
|
||||
|
|
@ -862,7 +875,9 @@ void MyMesh::sendNodeDiscoverReq() {
|
|||
MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondClock &ms, mesh::RNG &rng,
|
||||
mesh::RTCClock &rtc, mesh::MeshTables &tables)
|
||||
: mesh::Mesh(radio, ms, rng, rtc, *new StaticPoolPacketManager(32), tables),
|
||||
_cli(board, rtc, sensors, acl, &_prefs, this), telemetry(MAX_PACKET_PAYLOAD - 4), region_map(key_store), temp_map(key_store),
|
||||
region_map(key_store), temp_map(key_store),
|
||||
_cli(board, rtc, sensors, region_map, acl, &_prefs, this),
|
||||
telemetry(MAX_PACKET_PAYLOAD - 4),
|
||||
discover_limiter(4, 120), // max 4 every 2 minutes
|
||||
anon_limiter(4, 180) // max 4 every 3 minutes
|
||||
#if defined(WITH_RS232_BRIDGE)
|
||||
|
|
@ -932,6 +947,8 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
|
|||
|
||||
pending_discover_tag = 0;
|
||||
pending_discover_until = 0;
|
||||
|
||||
memset(default_scope.key, 0, sizeof(default_scope.key));
|
||||
}
|
||||
|
||||
void MyMesh::begin(FILESYSTEM *fs) {
|
||||
|
|
@ -943,6 +960,26 @@ void MyMesh::begin(FILESYSTEM *fs) {
|
|||
// TODO: key_store.begin();
|
||||
region_map.load(_fs);
|
||||
|
||||
// establish default-scope
|
||||
{
|
||||
RegionEntry* r = region_map.getDefaultRegion();
|
||||
if (r) {
|
||||
region_map.getTransportKeysFor(*r, &default_scope, 1);
|
||||
} else {
|
||||
#ifdef DEFAULT_FLOOD_SCOPE_NAME
|
||||
r = region_map.findByName(DEFAULT_FLOOD_SCOPE_NAME);
|
||||
if (r == NULL) {
|
||||
r = region_map.putRegion(DEFAULT_FLOOD_SCOPE_NAME, 0); // auto-create the default scope region
|
||||
if (r) { r->flags = 0; } // Allow-flood
|
||||
}
|
||||
if (r) {
|
||||
region_map.setDefaultRegion(r);
|
||||
region_map.getTransportKeysFor(*r, &default_scope, 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(WITH_BRIDGE)
|
||||
if (_prefs.bridge_enabled) {
|
||||
bridge.begin();
|
||||
|
|
@ -966,6 +1003,17 @@ void MyMesh::begin(FILESYSTEM *fs) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void MyMesh::sendFloodScoped(const TransportKey& scope, mesh::Packet* pkt, uint32_t delay_millis, uint8_t path_hash_size) {
|
||||
if (scope.isNull()) {
|
||||
sendFlood(pkt, delay_millis, path_hash_size);
|
||||
} else {
|
||||
uint16_t codes[2];
|
||||
codes[0] = scope.calcTransportCode(pkt);
|
||||
codes[1] = 0; // REVISIT: set to 'home' Region, for sender/return region?
|
||||
sendFlood(pkt, codes, delay_millis, path_hash_size);
|
||||
}
|
||||
}
|
||||
|
||||
void MyMesh::applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) {
|
||||
set_radio_at = futureMillis(2000); // give CLI reply some time to be sent back, before applying temp radio params
|
||||
pending_freq = freq;
|
||||
|
|
@ -993,7 +1041,7 @@ void MyMesh::sendSelfAdvertisement(int delay_millis, bool flood) {
|
|||
mesh::Packet *pkt = createSelfAdvert();
|
||||
if (pkt) {
|
||||
if (flood) {
|
||||
sendFlood(pkt, delay_millis, _prefs.path_hash_mode + 1);
|
||||
sendFloodScoped(default_scope, pkt, delay_millis, _prefs.path_hash_mode + 1);
|
||||
} else {
|
||||
sendZeroHop(pkt, delay_millis);
|
||||
}
|
||||
|
|
@ -1099,6 +1147,25 @@ void MyMesh::removeNeighbor(const uint8_t *pubkey, int key_len) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void MyMesh::startRegionsLoad() {
|
||||
temp_map.resetFrom(region_map); // rebuild regions in a temp instance
|
||||
memset(load_stack, 0, sizeof(load_stack));
|
||||
load_stack[0] = &temp_map.getWildcard();
|
||||
region_load_active = true;
|
||||
}
|
||||
|
||||
bool MyMesh::saveRegions() {
|
||||
return region_map.save(_fs);
|
||||
}
|
||||
|
||||
void MyMesh::onDefaultRegionChanged(const RegionEntry* r) {
|
||||
if (r) {
|
||||
region_map.getTransportKeysFor(*r, &default_scope, 1);
|
||||
} else {
|
||||
memset(default_scope.key, 0, sizeof(default_scope.key));
|
||||
}
|
||||
}
|
||||
|
||||
void MyMesh::formatStatsReply(char *reply) {
|
||||
StatsFormatHelper::formatCoreStats(reply, board, *_ms, _err_flags, _mgr);
|
||||
}
|
||||
|
|
@ -1208,107 +1275,6 @@ void MyMesh::handleCommand(uint32_t sender_timestamp, char *command, char *reply
|
|||
Serial.printf("\n");
|
||||
}
|
||||
reply[0] = 0;
|
||||
} else if (memcmp(command, "region", 6) == 0) {
|
||||
reply[0] = 0;
|
||||
|
||||
const char* parts[4];
|
||||
int n = mesh::Utils::parseTextParts(command, parts, 4, ' ');
|
||||
if (n == 1) {
|
||||
region_map.exportTo(reply, 160);
|
||||
} else if (n >= 2 && strcmp(parts[1], "load") == 0) {
|
||||
temp_map.resetFrom(region_map); // rebuild regions in a temp instance
|
||||
memset(load_stack, 0, sizeof(load_stack));
|
||||
load_stack[0] = &temp_map.getWildcard();
|
||||
region_load_active = true;
|
||||
} else if (n >= 2 && strcmp(parts[1], "save") == 0) {
|
||||
_prefs.discovery_mod_timestamp = rtc_clock.getCurrentTime(); // this node is now 'modified' (for discovery info)
|
||||
savePrefs();
|
||||
bool success = region_map.save(_fs);
|
||||
strcpy(reply, success ? "OK" : "Err - save failed");
|
||||
} else if (n >= 3 && strcmp(parts[1], "allowf") == 0) {
|
||||
auto region = region_map.findByNamePrefix(parts[2]);
|
||||
if (region) {
|
||||
region->flags &= ~REGION_DENY_FLOOD;
|
||||
strcpy(reply, "OK");
|
||||
} else {
|
||||
strcpy(reply, "Err - unknown region");
|
||||
}
|
||||
} else if (n >= 3 && strcmp(parts[1], "denyf") == 0) {
|
||||
auto region = region_map.findByNamePrefix(parts[2]);
|
||||
if (region) {
|
||||
region->flags |= REGION_DENY_FLOOD;
|
||||
strcpy(reply, "OK");
|
||||
} else {
|
||||
strcpy(reply, "Err - unknown region");
|
||||
}
|
||||
} else if (n >= 3 && strcmp(parts[1], "get") == 0) {
|
||||
auto region = region_map.findByNamePrefix(parts[2]);
|
||||
if (region) {
|
||||
auto parent = region_map.findById(region->parent);
|
||||
if (parent && parent->id != 0) {
|
||||
sprintf(reply, " %s (%s) %s", region->name, parent->name, (region->flags & REGION_DENY_FLOOD) ? "" : "F");
|
||||
} else {
|
||||
sprintf(reply, " %s %s", region->name, (region->flags & REGION_DENY_FLOOD) ? "" : "F");
|
||||
}
|
||||
} else {
|
||||
strcpy(reply, "Err - unknown region");
|
||||
}
|
||||
} else if (n >= 3 && strcmp(parts[1], "home") == 0) {
|
||||
auto home = region_map.findByNamePrefix(parts[2]);
|
||||
if (home) {
|
||||
region_map.setHomeRegion(home);
|
||||
sprintf(reply, " home is now %s", home->name);
|
||||
} else {
|
||||
strcpy(reply, "Err - unknown region");
|
||||
}
|
||||
} else if (n == 2 && strcmp(parts[1], "home") == 0) {
|
||||
auto home = region_map.getHomeRegion();
|
||||
sprintf(reply, " home is %s", home ? home->name : "*");
|
||||
} else if (n >= 3 && strcmp(parts[1], "put") == 0) {
|
||||
auto parent = n >= 4 ? region_map.findByNamePrefix(parts[3]) : ®ion_map.getWildcard();
|
||||
if (parent == NULL) {
|
||||
strcpy(reply, "Err - unknown parent");
|
||||
} else {
|
||||
auto region = region_map.putRegion(parts[2], parent->id);
|
||||
if (region == NULL) {
|
||||
strcpy(reply, "Err - unable to put");
|
||||
} else {
|
||||
strcpy(reply, "OK");
|
||||
}
|
||||
}
|
||||
} else if (n >= 3 && strcmp(parts[1], "remove") == 0) {
|
||||
auto region = region_map.findByName(parts[2]);
|
||||
if (region) {
|
||||
if (region_map.removeRegion(*region)) {
|
||||
strcpy(reply, "OK");
|
||||
} else {
|
||||
strcpy(reply, "Err - not empty");
|
||||
}
|
||||
} else {
|
||||
strcpy(reply, "Err - not found");
|
||||
}
|
||||
} else if (n >= 3 && strcmp(parts[1], "list") == 0) {
|
||||
uint8_t mask = 0;
|
||||
bool invert = false;
|
||||
|
||||
if (strcmp(parts[2], "allowed") == 0) {
|
||||
mask = REGION_DENY_FLOOD;
|
||||
invert = false; // list regions that DON'T have DENY flag
|
||||
} else if (strcmp(parts[2], "denied") == 0) {
|
||||
mask = REGION_DENY_FLOOD;
|
||||
invert = true; // list regions that DO have DENY flag
|
||||
} else {
|
||||
strcpy(reply, "Err - use 'allowed' or 'denied'");
|
||||
return;
|
||||
}
|
||||
|
||||
int len = region_map.exportNamesTo(reply, 160, mask, invert);
|
||||
if (len == 0) {
|
||||
strcpy(reply, "-none-");
|
||||
}
|
||||
} else {
|
||||
strcpy(reply, "Err - ??");
|
||||
}
|
||||
} else if (memcmp(command, "discover.neighbors", 18) == 0) {
|
||||
const char* sub = command + 18;
|
||||
while (*sub == ' ') sub++;
|
||||
|
|
@ -1333,7 +1299,7 @@ void MyMesh::loop() {
|
|||
if (next_flood_advert && millisHasNowPassed(next_flood_advert)) {
|
||||
mesh::Packet *pkt = createSelfAdvert();
|
||||
uint32_t delay_millis = 0;
|
||||
if (pkt) sendFlood(pkt, delay_millis, _prefs.path_hash_mode + 1);
|
||||
if (pkt) sendFloodScoped(default_scope, pkt, delay_millis, _prefs.path_hash_mode + 1);
|
||||
|
||||
updateFloodAdvertTimer(); // schedule next flood advert
|
||||
updateAdvertTimer(); // also schedule local advert (so they don't overlap)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue