mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-09-22 10:56:48 +00:00
Merge pull request #2763 from meshcore-dev/anon-contacts-fix
* fix for anon contacts when full
This commit is contained in:
@@ -854,7 +854,7 @@ void MyMesh::onSendTimeout() {}
|
|||||||
|
|
||||||
MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMeshTables &tables, DataStore& store, AbstractUITask* ui)
|
MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMeshTables &tables, DataStore& store, AbstractUITask* ui)
|
||||||
: BaseChatMesh(radio, *new ArduinoMillis(), rng, rtc, *new StaticPoolPacketManager(16), tables),
|
: BaseChatMesh(radio, *new ArduinoMillis(), rng, rtc, *new StaticPoolPacketManager(16), tables),
|
||||||
_serial(NULL), telemetry(MAX_PACKET_PAYLOAD - 4), _store(&store), _ui(ui) {
|
_serial(NULL), telemetry(MAX_PACKET_PAYLOAD - 4), _store(&store), _ui(ui), _iter(0) {
|
||||||
_iter_started = false;
|
_iter_started = false;
|
||||||
_cli_rescue = false;
|
_cli_rescue = false;
|
||||||
offline_queue_len = 0;
|
offline_queue_len = 0;
|
||||||
@@ -1542,6 +1542,7 @@ void MyMesh::handleCmdFrame(size_t len) {
|
|||||||
memcpy(anon.id.pub_key, pub_key, PUB_KEY_SIZE);
|
memcpy(anon.id.pub_key, pub_key, PUB_KEY_SIZE);
|
||||||
anon.out_path_len = 0; // default to zero-hop direct
|
anon.out_path_len = 0; // default to zero-hop direct
|
||||||
anon.type = ADV_TYPE_NONE; // unknown
|
anon.type = ADV_TYPE_NONE; // unknown
|
||||||
|
anon.lastmod = getRTCClock()->getCurrentTime();
|
||||||
|
|
||||||
if (addContact(anon)) recipient = &anon;
|
if (addContact(anon)) recipient = &anon;
|
||||||
}
|
}
|
||||||
@@ -2187,15 +2188,7 @@ void MyMesh::checkSerialInterface() {
|
|||||||
&& !_serial->isWriteBusy() // don't spam the Serial Interface too quickly!
|
&& !_serial->isWriteBusy() // don't spam the Serial Interface too quickly!
|
||||||
) {
|
) {
|
||||||
ContactInfo contact;
|
ContactInfo contact;
|
||||||
bool found = false;
|
if (_iter.hasNext(this, contact)) {
|
||||||
while (_iter.hasNext(this, contact)) {
|
|
||||||
if (contact.type != ADV_TYPE_NONE) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found) {
|
|
||||||
if (contact.lastmod > _iter_filter_since) { // apply the 'since' filter
|
if (contact.lastmod > _iter_filter_since) { // apply the 'since' filter
|
||||||
writeContactRespFrame(RESP_CODE_CONTACT, contact);
|
writeContactRespFrame(RESP_CODE_CONTACT, contact);
|
||||||
if (contact.lastmod > _most_recent_lastmod) {
|
if (contact.lastmod > _most_recent_lastmod) {
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ class MyMesh : public BaseChatMesh, ContactVisitor {
|
|||||||
File file = _fs->open("/contacts", "w", true);
|
File file = _fs->open("/contacts", "w", true);
|
||||||
#endif
|
#endif
|
||||||
if (file) {
|
if (file) {
|
||||||
ContactsIterator iter;
|
ContactsIterator iter = startContactsIterator();
|
||||||
ContactInfo c;
|
ContactInfo c;
|
||||||
uint8_t unused = 0;
|
uint8_t unused = 0;
|
||||||
uint32_t reserved = 0;
|
uint32_t reserved = 0;
|
||||||
|
|||||||
@@ -68,29 +68,36 @@ void BaseChatMesh::bootstrapRTCfromContacts() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ContactInfo* BaseChatMesh::allocateContactSlot(bool transient_only) {
|
ContactInfo* BaseChatMesh::allocateContactSlot(bool transient_only) {
|
||||||
if (num_contacts < MAX_CONTACTS) {
|
int oldest_idx = -1;
|
||||||
return &contacts[num_contacts++];
|
uint32_t oldest_lastmod = 0xFFFFFFFF;
|
||||||
} else if (transient_only || shouldOverwriteWhenFull()) {
|
if (transient_only) {
|
||||||
// Find oldest non-favourite contact by oldest lastmod timestamp
|
// only allocate from first N
|
||||||
int oldest_idx = -1;
|
for (int i = 0; i < MAX_ANON_CONTACTS; i++) {
|
||||||
uint32_t oldest_lastmod = 0xFFFFFFFF;
|
if (contacts[i].type == ADV_TYPE_NONE && contacts[i].lastmod < oldest_lastmod) {
|
||||||
for (int i = 0; i < num_contacts; i++) {
|
oldest_lastmod = contacts[i].lastmod;
|
||||||
if (transient_only) {
|
oldest_idx = i;
|
||||||
if (contacts[i].type == ADV_TYPE_NONE && contacts[i].lastmod < oldest_lastmod) {
|
}
|
||||||
oldest_lastmod = contacts[i].lastmod;
|
}
|
||||||
oldest_idx = i;
|
if (oldest_idx >= 0) {
|
||||||
}
|
// NOTE: do NOT call onContactOverwrite()
|
||||||
} else {
|
return &contacts[oldest_idx];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (num_contacts < MAX_ANON_CONTACTS+MAX_CONTACTS) {
|
||||||
|
return &contacts[num_contacts++];
|
||||||
|
} else if (shouldOverwriteWhenFull()) {
|
||||||
|
// Find oldest non-favourite contact by oldest lastmod timestamp
|
||||||
|
for (int i = MAX_ANON_CONTACTS; i < num_contacts; i++) {
|
||||||
bool is_favourite = (contacts[i].flags & 0x01) != 0;
|
bool is_favourite = (contacts[i].flags & 0x01) != 0;
|
||||||
if (!is_favourite && contacts[i].lastmod < oldest_lastmod && contacts[i].type != ADV_TYPE_NONE) {
|
if (!is_favourite && contacts[i].lastmod < oldest_lastmod) {
|
||||||
oldest_lastmod = contacts[i].lastmod;
|
oldest_lastmod = contacts[i].lastmod;
|
||||||
oldest_idx = i;
|
oldest_idx = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (oldest_idx >= 0) {
|
||||||
if (oldest_idx >= 0) {
|
onContactOverwrite(contacts[oldest_idx].id.pub_key);
|
||||||
onContactOverwrite(contacts[oldest_idx].id.pub_key);
|
return &contacts[oldest_idx];
|
||||||
return &contacts[oldest_idx];
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL; // no space, no overwrite or all contacts are all favourites
|
return NULL; // no space, no overwrite or all contacts are all favourites
|
||||||
@@ -139,6 +146,11 @@ void BaseChatMesh::onAdvertRecv(mesh::Packet* packet, const mesh::Identity& id,
|
|||||||
packet->header = save;
|
packet->header = save;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (from && from->type == ADV_TYPE_NONE) { // already in contacts, but from a temporary ANON_REQ ?
|
||||||
|
memset(from, 0, sizeof(*from)); // clear the anon/temp slot
|
||||||
|
from = NULL; // do normal 'add' flow
|
||||||
|
}
|
||||||
|
|
||||||
bool is_new = false; // true = not in contacts[], false = exists in contacts[]
|
bool is_new = false; // true = not in contacts[], false = exists in contacts[]
|
||||||
if (from == NULL) {
|
if (from == NULL) {
|
||||||
if (!shouldAutoAddContactType(parser.getType())) {
|
if (!shouldAutoAddContactType(parser.getType())) {
|
||||||
@@ -930,11 +942,11 @@ bool BaseChatMesh::getContactByIdx(uint32_t idx, ContactInfo& contact) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ContactsIterator BaseChatMesh::startContactsIterator() {
|
ContactsIterator BaseChatMesh::startContactsIterator() {
|
||||||
return ContactsIterator();
|
return ContactsIterator(MAX_ANON_CONTACTS); // start at offset, skip the anon entries
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ContactsIterator::hasNext(const BaseChatMesh* mesh, ContactInfo& dest) {
|
bool ContactsIterator::hasNext(const BaseChatMesh* mesh, ContactInfo& dest) {
|
||||||
if (next_idx >= mesh->getNumContacts()) return false;
|
if (next_idx >= mesh->getTotalContactSlots()) return false;
|
||||||
|
|
||||||
dest = mesh->contacts[next_idx++];
|
dest = mesh->contacts[next_idx++];
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -28,8 +28,9 @@ public:
|
|||||||
class BaseChatMesh;
|
class BaseChatMesh;
|
||||||
|
|
||||||
class ContactsIterator {
|
class ContactsIterator {
|
||||||
int next_idx = 0;
|
int next_idx;
|
||||||
public:
|
public:
|
||||||
|
ContactsIterator(int start) { next_idx = start; }
|
||||||
bool hasNext(const BaseChatMesh* mesh, ContactInfo& dest);
|
bool hasNext(const BaseChatMesh* mesh, ContactInfo& dest);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -79,8 +80,9 @@ class BaseChatMesh : public mesh::Mesh {
|
|||||||
protected:
|
protected:
|
||||||
BaseChatMesh(mesh::Radio& radio, mesh::MillisecondClock& ms, mesh::RNG& rng, mesh::RTCClock& rtc, mesh::PacketManager& mgr, mesh::MeshTables& tables)
|
BaseChatMesh(mesh::Radio& radio, mesh::MillisecondClock& ms, mesh::RNG& rng, mesh::RTCClock& rtc, mesh::PacketManager& mgr, mesh::MeshTables& tables)
|
||||||
: mesh::Mesh(radio, ms, rng, rtc, mgr, tables)
|
: mesh::Mesh(radio, ms, rng, rtc, mgr, tables)
|
||||||
{
|
{
|
||||||
num_contacts = 0;
|
resetContacts();
|
||||||
|
|
||||||
#ifdef MAX_GROUP_CHANNELS
|
#ifdef MAX_GROUP_CHANNELS
|
||||||
memset(channels, 0, sizeof(channels));
|
memset(channels, 0, sizeof(channels));
|
||||||
num_channels = 0;
|
num_channels = 0;
|
||||||
@@ -91,7 +93,11 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void bootstrapRTCfromContacts();
|
void bootstrapRTCfromContacts();
|
||||||
void resetContacts() { num_contacts = 0; }
|
|
||||||
|
void resetContacts() {
|
||||||
|
memset(contacts, 0, sizeof(contacts[0])*MAX_ANON_CONTACTS); // set all to have type = ADV_TYPE_NONE(0)
|
||||||
|
num_contacts = MAX_ANON_CONTACTS; // seed the first contacts for anon requests
|
||||||
|
}
|
||||||
void populateContactFromAdvert(ContactInfo& ci, const mesh::Identity& id, const AdvertDataParser& parser, uint32_t timestamp);
|
void populateContactFromAdvert(ContactInfo& ci, const mesh::Identity& id, const AdvertDataParser& parser, uint32_t timestamp);
|
||||||
ContactInfo* allocateContactSlot(bool transient_only=false); // helper to find slot for new contact
|
ContactInfo* allocateContactSlot(bool transient_only=false); // helper to find slot for new contact
|
||||||
|
|
||||||
@@ -166,7 +172,8 @@ public:
|
|||||||
ContactInfo* lookupContactByPubKey(const uint8_t* pub_key, int prefix_len);
|
ContactInfo* lookupContactByPubKey(const uint8_t* pub_key, int prefix_len);
|
||||||
bool removeContact(ContactInfo& contact);
|
bool removeContact(ContactInfo& contact);
|
||||||
bool addContact(const ContactInfo& contact);
|
bool addContact(const ContactInfo& contact);
|
||||||
int getNumContacts() const { return num_contacts; }
|
int getTotalContactSlots() const { return num_contacts; }
|
||||||
|
int getNumContacts() const { return num_contacts - MAX_ANON_CONTACTS; } // don't include the reserved slots at start
|
||||||
bool getContactByIdx(uint32_t idx, ContactInfo& contact);
|
bool getContactByIdx(uint32_t idx, ContactInfo& contact);
|
||||||
ContactsIterator startContactsIterator();
|
ContactsIterator startContactsIterator();
|
||||||
ChannelDetails* addChannel(const char* name, const char* psk_base64);
|
ChannelDetails* addChannel(const char* name, const char* psk_base64);
|
||||||
|
|||||||
Reference in New Issue
Block a user