Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance requestAddress by looping through poll responses #238

Merged
merged 4 commits into from
Jun 9, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 45 additions & 44 deletions RF24Mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,49 +314,49 @@ bool ESBMesh<network_t, radio_t>::requestAddress(uint8_t level)
{
RF24NetworkHeader header(MESH_MULTICAST_ADDRESS, NETWORK_POLL);
//Find another radio, starting with level 0 multicast
IF_MESH_DEBUG(printf_P(PSTR("%u: MSH Poll\n"), millis()));
IF_MESH_DEBUG(printf_P(PSTR("MSH Poll Level %d\n"), level));
network.multicast(header, 0, 0, level);

uint32_t timr = millis();
uint32_t timeout = millis() + 55;
#define MESH_MAXPOLLS 4
uint16_t contactNode[MESH_MAXPOLLS];
uint8_t pollCount = 0;

while (1) {
while (millis() < timeout && pollCount < MESH_MAXPOLLS) {
#if defined(MESH_DEBUG)
bool goodSignal = radio.testRPD();
#endif

if (network.update() == NETWORK_POLL) {

memcpy(&contactNode[pollCount], &network.frame_buffer[0], sizeof(uint16_t));
if (pollCount > 0 && contactNode[pollCount] != contactNode[pollCount - 1]) { //Drop duplicate polls to help prevent duplicate requests
++pollCount;
uint16_t contact = 0;
memcpy(&contact, &network.frame_buffer[0], sizeof(contact));

// Drop duplicate polls to help prevent duplicate requests
bool isDupe = false;
for (uint8_t i = 0; i < pollCount; ++i) {
if (contact == contactNode[i]) {
isDupe = true;
break;
}
}
else {
if (!isDupe) {
contactNode[pollCount] = contact;
++pollCount;
IF_MESH_DEBUG(printf_P(PSTR("MSH Poll %c -64dbm from 0%o \n"), (goodSignal ? '>' : '<'), contact));
2bndy5 marked this conversation as resolved.
Show resolved Hide resolved
}

IF_MESH_DEBUG(printf_P(PSTR("%u: MSH Poll %c -64dbm\n"), millis(), (goodSignal ? '>' : '<')));
} // end if

if (millis() - timr > 55 || pollCount >= MESH_MAXPOLLS) {
if (!pollCount) {
IF_MESH_DEBUG(printf_P(PSTR("%u: MSH No poll from level %d\n"), millis(), level));
return 0;
}
TMRh20 marked this conversation as resolved.
Show resolved Hide resolved
else {
IF_MESH_DEBUG(printf_P(PSTR("%u: MSH Poll OK\n"), millis()));
break;
}
}
MESH_CALLBACK
} // end while

IF_MESH_DEBUG(printf_P(PSTR("%u: MSH Got poll from level %d count %d\n"), millis(), level, pollCount));
IF_MESH_DEBUG(printf_P(PSTR("MSH Polls from level %d: %d\n"), level, pollCount));

if (!pollCount) return 0;

bool gotResponse = 0;
for (uint8_t i = 0; i < pollCount; i++) {

bool gotResponse = 0;

// Request an address via the contact node
header.type = NETWORK_REQ_ADDRESS;
header.reserved = _nodeID;
Expand All @@ -365,49 +365,50 @@ bool ESBMesh<network_t, radio_t>::requestAddress(uint8_t level)
// Do a direct write (no ack) to the contact node. Include the nodeId and address.
network.write(header, 0, 0, contactNode[i]);

IF_MESH_DEBUG(printf_P(PSTR("%u: MSH Request address from: 0%o\n"), millis(), contactNode[i]));
IF_MESH_DEBUG(printf_P(PSTR("MSH Request address from: 0%o\n"), contactNode[i]));

timr = millis();
timeout = millis() + 225;

while (millis() - timr < 225) {
while (millis() < timeout) {
if (network.update() == NETWORK_ADDR_RESPONSE) {
if (network.frame_buffer[7] == _nodeID) {
uint16_t newAddy = 0;
memcpy(&newAddy, &network.frame_buffer[sizeof(RF24NetworkHeader)], sizeof(newAddy));
uint16_t mask = 0xFFFF;
newAddy &= ~(mask << (3 * getLevel(contactNode[i]))); // Get the level of contact node. Multiply by 3 to get the number of bits to shift (3 per digit)
if (newAddy == contactNode[i]) { // Then shift the mask by this much, and invert it bitwise. Apply the mask to the newly received
i = pollCount; // address to evalute whether 'subnet' of the assigned address matches the contact node address.
gotResponse = 1;
gotResponse = 1; // address to evalute whether 'subnet' of the assigned address matches the contact node address.
break;
}
}
}
MESH_CALLBACK
}
} // end for

if (!gotResponse) {
return 0;
}
if (!gotResponse) {
continue;
}

uint16_t newAddress = 0;
memcpy(&newAddress, network.frame_buffer + sizeof(RF24NetworkHeader), sizeof(newAddress));
uint16_t newAddress = 0;
memcpy(&newAddress, network.frame_buffer + sizeof(RF24NetworkHeader), sizeof(newAddress));

IF_MESH_DEBUG(printf_P(PSTR("Set address 0%o rcvd 0%o\n"), mesh_address, newAddress));
mesh_address = newAddress;
IF_MESH_DEBUG(printf_P(PSTR("Set address: Current: 0%o New: 0%o\n"), mesh_address, newAddress));
mesh_address = newAddress;

radio.stopListening();
network.begin(mesh_address);
radio.stopListening();
network.begin(mesh_address);

// getNodeID() doesn't use auto-ack; do a double-check to manually retry 1 more time
if (getNodeID(mesh_address) != _nodeID) {
// getNodeID() doesn't use auto-ack; do a double-check to manually retry 1 more time
if (getNodeID(mesh_address) != _nodeID) {
beginDefault();
return 0;
if (getNodeID(mesh_address) != _nodeID) {
beginDefault();
continue;
}
}
}
return 1;
return 1;
} // end for

return 0;
}

/*****************************************************/
Expand Down Expand Up @@ -521,7 +522,7 @@ void ESBMesh<network_t, radio_t>::DHCP()

// Get the unique id of the requester (ID is in header.reserved)
if (!header.reserved || header.type != NETWORK_REQ_ADDRESS) {
IF_MESH_DEBUG(printf_P(PSTR("%u: MSH Invalid id or type rcvd\n"), millis()));
IF_MESH_DEBUG(printf_P(PSTR("MSH Invalid id or type rcvd\n")));
return;
}

Expand Down