diff --git a/RF24Mesh.cpp b/RF24Mesh.cpp index 6c6306f..d111c8a 100644 --- a/RF24Mesh.cpp +++ b/RF24Mesh.cpp @@ -299,49 +299,49 @@ bool RF24Mesh::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)); } - 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; - } - 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; @@ -350,11 +350,11 @@ bool RF24Mesh::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; @@ -362,37 +362,38 @@ bool RF24Mesh::requestAddress(uint8_t level) 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; } /*****************************************************/ @@ -500,7 +501,7 @@ void RF24Mesh::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; }