* Repeater: new anon request sub-type: ANON_REQ_TYPE_REGIONS (rate limited to max 4 every 3 mins)

* Companion: new CMD_SEND_ANON_REQ command (reply with existing RESP_CODE_SENT frame)
This commit is contained in:
Scott Powell 2026-01-03 12:02:15 +11:00
parent e31c46ff56
commit 3af25495bb
7 changed files with 104 additions and 12 deletions

View file

@ -477,6 +477,31 @@ int BaseChatMesh::sendLogin(const ContactInfo& recipient, const char* password,
return MSG_SEND_FAILED;
}
int BaseChatMesh::sendAnonReq(const ContactInfo& recipient, const uint8_t* data, uint8_t len, uint32_t& tag, uint32_t& est_timeout) {
mesh::Packet* pkt;
{
uint8_t temp[MAX_PACKET_PAYLOAD];
tag = getRTCClock()->getCurrentTimeUnique();
memcpy(temp, &tag, 4); // tag to match later (also extra blob to help make packet_hash unique)
memcpy(&temp[4], data, len);
pkt = createAnonDatagram(PAYLOAD_TYPE_ANON_REQ, self_id, recipient.id, recipient.getSharedSecret(self_id), temp, 4 + len);
}
if (pkt) {
uint32_t t = _radio->getEstAirtimeFor(pkt->getRawLength());
if (recipient.out_path_len < 0) {
sendFloodScoped(recipient, pkt);
est_timeout = calcFloodTimeoutMillisFor(t);
return MSG_SEND_SENT_FLOOD;
} else {
sendDirect(pkt, recipient.out_path, recipient.out_path_len);
est_timeout = calcDirectTimeoutMillisFor(t, recipient.out_path_len);
return MSG_SEND_SENT_DIRECT;
}
}
return MSG_SEND_FAILED;
}
int BaseChatMesh::sendRequest(const ContactInfo& recipient, const uint8_t* req_data, uint8_t data_len, uint32_t& tag, uint32_t& est_timeout) {
if (data_len > MAX_PACKET_PAYLOAD - 16) return MSG_SEND_FAILED;

View file

@ -141,6 +141,7 @@ public:
int sendCommandData(const ContactInfo& recipient, uint32_t timestamp, uint8_t attempt, const char* text, uint32_t& est_timeout);
bool sendGroupMessage(uint32_t timestamp, mesh::GroupChannel& channel, const char* sender_name, const char* text, int text_len);
int sendLogin(const ContactInfo& recipient, const char* password, uint32_t& est_timeout);
int sendAnonReq(const ContactInfo& recipient, const uint8_t* data, uint8_t len, uint32_t& tag, uint32_t& est_timeout);
int sendRequest(const ContactInfo& recipient, uint8_t req_type, uint32_t& tag, uint32_t& est_timeout);
int sendRequest(const ContactInfo& recipient, const uint8_t* req_data, uint8_t data_len, uint32_t& tag, uint32_t& est_timeout);
bool shareContactZeroHop(const ContactInfo& contact);

View file

@ -24,12 +24,12 @@ static File openWrite(FILESYSTEM* _fs, const char* filename) {
#endif
}
bool RegionMap::load(FILESYSTEM* _fs) {
if (_fs->exists("/regions2")) {
bool RegionMap::load(FILESYSTEM* _fs, const char* path) {
if (_fs->exists(path ? path : "/regions2")) {
#if defined(RP2040_PLATFORM)
File file = _fs->open("/regions2", "r");
File file = _fs->open(path ? path : "/regions2", "r");
#else
File file = _fs->open("/regions2");
File file = _fs->open(path ? path : "/regions2");
#endif
if (file) {
@ -67,8 +67,8 @@ bool RegionMap::load(FILESYSTEM* _fs) {
return false; // failed
}
bool RegionMap::save(FILESYSTEM* _fs) {
File file = openWrite(_fs, "/regions2");
bool RegionMap::save(FILESYSTEM* _fs, const char* path) {
File file = openWrite(_fs, path ? path : "/regions2");
if (file) {
uint8_t pad[128];
memset(pad, 0, sizeof(pad));
@ -235,3 +235,27 @@ void RegionMap::printChildRegions(int indent, const RegionEntry* parent, Stream&
void RegionMap::exportTo(Stream& out) const {
printChildRegions(0, &wildcard, out); // recursive
}
int RegionMap::exportNamesTo(char *dest, int max_len, uint8_t mask) {
char *dp = dest;
if ((wildcard.flags & mask) == 0) {
*dp++ = '*';
*dp++ = ',';
}
for (int i = 0; i < num_regions; i++) {
auto region = &regions[i];
if ((region->flags & mask) == 0) { // region allowed? (per 'mask' param)
int len = strlen(region->name);
if ((dp - dest) + len + 2 < max_len) { // only append if name will fit
memcpy(dp, region->name, len);
dp += len;
*dp++ = ',';
}
}
}
if (dp > dest) { dp--; } // don't include trailing comma
*dp = 0; // set null terminator
return dp - dest; // return length
}

View file

@ -32,8 +32,8 @@ public:
static bool is_name_char(char c);
bool load(FILESYSTEM* _fs);
bool save(FILESYSTEM* _fs);
bool load(FILESYSTEM* _fs, const char* path=NULL);
bool save(FILESYSTEM* _fs, const char* path=NULL);
RegionEntry* putRegion(const char* name, uint16_t parent_id, uint16_t id = 0);
RegionEntry* findMatch(mesh::Packet* packet, uint8_t mask);
@ -47,6 +47,9 @@ public:
bool clear();
void resetFrom(const RegionMap& src) { num_regions = 0; next_id = src.next_id; }
int getCount() const { return num_regions; }
const RegionEntry* getByIdx(int i) const { return &regions[i]; }
const RegionEntry* getRoot() const { return &wildcard; }
int exportNamesTo(char *dest, int max_len, uint8_t mask);
void exportTo(Stream& out) const;
};