mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-11-02 19:02:00 +00:00
refactor(companion): our MyMesh additions in their own headers
Contacts and rooms, the scope list, discovery and ping, APC and screenshots move out of MyMesh.cpp to headers included at its bottom, as MyMeshBot.h and MyMeshCli.h are, so upstream merges meet less of our code. The feature matrix gains the 4.26" in its layout tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
#pragma once
|
||||
// Node discovery and ping (trace) from the UI.
|
||||
// Not part of upstream MyMesh.cpp: included at its bottom, after all class
|
||||
// definitions (as MyMeshBot.h and MyMeshCli.h).
|
||||
|
||||
void MyMesh::sendNodeDiscoverReq() {
|
||||
uint8_t data[10];
|
||||
data[0] = CTL_TYPE_NODE_DISCOVER_REQ;
|
||||
data[1] = (1 << ADV_TYPE_REPEATER) | (1 << ADV_TYPE_SENSOR) | (1 << ADV_TYPE_ROOM);
|
||||
getRNG()->random(&data[2], 4);
|
||||
memcpy(&_pending_node_discover_tag, &data[2], 4);
|
||||
_pending_node_discover_until = futureMillis(8000);
|
||||
_discover_count = 0;
|
||||
uint32_t since = 0;
|
||||
memcpy(&data[6], &since, 4);
|
||||
auto pkt = createControlData(data, sizeof(data));
|
||||
if (pkt) sendZeroHop(pkt);
|
||||
}
|
||||
|
||||
int MyMesh::getDiscoverResults(DiscoverResult dest[], int max_count) {
|
||||
int n = min(_discover_count, max_count);
|
||||
memcpy(dest, _discover_results, n * sizeof(DiscoverResult));
|
||||
return n;
|
||||
}
|
||||
|
||||
// ── Ping/Trace functionality ─────────────────────────────────────────────────
|
||||
|
||||
uint32_t MyMesh::sendPing(const uint8_t* dest_pubkey, uint8_t hash_width) {
|
||||
if (hash_width == 0 || hash_width > 2) return 0;
|
||||
|
||||
// Generate random tag and auth code
|
||||
uint32_t tag, auth;
|
||||
getRNG()->random((uint8_t*)&tag, 4);
|
||||
getRNG()->random((uint8_t*)&auth, 4);
|
||||
|
||||
// Find a free slot in ping results
|
||||
int slot = -1;
|
||||
for (int i = 0; i < PING_RESULT_MAX; i++) {
|
||||
if (!_ping_results[i].received && _ping_results[i].tag == 0) {
|
||||
slot = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (slot < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Initialize ping result tracking
|
||||
PingResult& result = _ping_results[slot];
|
||||
result.tag = tag;
|
||||
result.auth_code = auth;
|
||||
result.snr_out_x4 = 0;
|
||||
result.snr_back_x4 = 0;
|
||||
result.rtt_ms = 0;
|
||||
result.received = false;
|
||||
result.sent_ms = millis();
|
||||
|
||||
// Create path hash from destination public key
|
||||
uint8_t path_len = hash_width;
|
||||
uint8_t path[MAX_PATH_SIZE];
|
||||
memcpy(path, dest_pubkey, path_len);
|
||||
|
||||
// Create and send trace packet
|
||||
auto pkt = createTrace(tag, auth, hash_width - 1); // flags = hash_width - 1
|
||||
if (pkt) {
|
||||
sendDirect(pkt, path, path_len);
|
||||
return tag;
|
||||
}
|
||||
|
||||
// Failed to create packet
|
||||
memset(&result, 0, sizeof(result));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MyMesh::setPingCallback(PingCallback cb, void* arg) {
|
||||
_ping_callback = cb;
|
||||
_ping_callback_arg = arg;
|
||||
}
|
||||
|
||||
void MyMesh::clearPingResult(uint32_t tag) {
|
||||
if (tag == 0) return;
|
||||
for (int i = 0; i < PING_RESULT_MAX; i++) {
|
||||
if (_ping_results[i].tag == tag) {
|
||||
memset(&_ping_results[i], 0, sizeof(_ping_results[i]));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MyMesh::PingResult* MyMesh::getPingResult(uint32_t tag) {
|
||||
for (int i = 0; i < PING_RESULT_MAX; i++) {
|
||||
if (_ping_results[i].tag == tag) {
|
||||
return &_ping_results[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// True when this (tag, responder) pair was already seen recently; records it
|
||||
// otherwise. A discover response is often heard more than once — the zero-hop
|
||||
// direct copy and a re-flooded copy relayed by another repeater carry
|
||||
// different packet hashes, so the mesh duplicate filter passes both. Without
|
||||
// this, the standalone scan appended the same node twice and an app-driven
|
||||
// discover had both copies forwarded, so the app listed one repeater as two.
|
||||
bool MyMesh::isDupDiscoverResp(uint32_t tag, const uint8_t* pub_key) {
|
||||
for (int i = 0; i < DISCOVER_SEEN_MAX; i++) {
|
||||
DiscoverSeen& e = _disc_seen[i];
|
||||
if (e.until != 0 && !millisHasNowPassed(e.until)
|
||||
&& e.tag == tag && memcmp(e.pk, pub_key, sizeof(e.pk)) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
DiscoverSeen& s = _disc_seen[_disc_seen_head];
|
||||
_disc_seen_head = (_disc_seen_head + 1) % DISCOVER_SEEN_MAX;
|
||||
s.tag = tag;
|
||||
memcpy(s.pk, pub_key, sizeof(s.pk));
|
||||
s.until = futureMillis(10000); // copies of one response arrive within seconds
|
||||
return false;
|
||||
}
|
||||
Reference in New Issue
Block a user