From 32f7c013b8dee33a165672ba246c72b9d7591075 Mon Sep 17 00:00:00 2001 From: Alexey Zholtikov Date: Sat, 14 Jan 2023 09:27:07 +0300 Subject: [PATCH] Version 1.32 Fixed bug with periodically absence a confirmation message. --- README.md | 18 ++++++++--- examples/Transmitter/main.cpp | 12 +++++-- library.properties | 2 +- src/ZHNetwork.cpp | 61 ++++++++++++++++++++++++++++------- src/ZHNetwork.h | 27 ++++++++++++---- 5 files changed, 95 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 5c32b6b..88f5c51 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Note. Called only at broadcast or unicast with confirm message. Status will alwa ```cpp myNet.setOnConfirmReceivingCallback(onConfirmReceiving); -void onConfirmReceiving(const uint8_t *target, const bool status) +void onConfirmReceiving(const uint8_t *target, const uint16_t id, const bool status) { // Do something when receiving a delivery/undelivery confirm message. } @@ -78,12 +78,16 @@ myNet.begin("ZHNetwork", true); // Gateway mode. ### Sends broadcast message to all nodes +Returns message ID. + ```cpp myNet.sendBroadcastMessage("Hello world!"); ``` ### Sends unicast message to node +Returns message ID. + ```cpp myNet.sendUnicastMessage("Hello world!", target); // Without confirm. myNet.sendUnicastMessage("Hello world!", target, true); // With confirm. @@ -171,7 +175,7 @@ myNet.getMaxWaitingTimeForRoutingInfo(); void onBroadcastReceiving(const char *data, const uint8_t *sender); void onUnicastReceiving(const char *data, const uint8_t *sender); -void onConfirmReceiving(const uint8_t *target, const bool status); +void onConfirmReceiving(const uint8_t *target, const uint16_t id, const bool status); ZHNetwork myNet; @@ -200,14 +204,18 @@ void loop() { Serial.println("Broadcast message sended."); myNet.sendBroadcastMessage("Hello world!"); + Serial.print("Unicast message to MAC "); Serial.print(myNet.macToString(target)); Serial.println(" sended."); myNet.sendUnicastMessage("Hello world!", target); + Serial.print("Unicast with confirm message to MAC "); Serial.print(myNet.macToString(target)); + Serial.print(" ID "); + Serial.print(myNet.sendUnicastMessage("Hello world!", target, true)); Serial.println(" sended."); - myNet.sendUnicastMessage("Hello world!", target, true); + messageLastTime = millis(); } myNet.maintenance(); @@ -230,10 +238,12 @@ void onUnicastReceiving(const char *data, const uint8_t *sender) Serial.println(data); } -void onConfirmReceiving(const uint8_t *target, const bool status) +void onConfirmReceiving(const uint8_t *target, const uint16_t id, const bool status) { Serial.print("Message to MAC "); Serial.print(myNet.macToString(target)); + Serial.print(" ID "); + Serial.print(id); Serial.println(status ? " delivered." : " undelivered."); } ``` diff --git a/examples/Transmitter/main.cpp b/examples/Transmitter/main.cpp index 697c572..a1774a2 100644 --- a/examples/Transmitter/main.cpp +++ b/examples/Transmitter/main.cpp @@ -1,6 +1,6 @@ #include "ZHNetwork.h" -void onConfirmReceiving(const uint8_t *target, const bool status); +void onConfirmReceiving(const uint8_t *target, const uint16_t id, const bool status); ZHNetwork myNet; @@ -27,22 +27,28 @@ void loop() { Serial.println("Broadcast message sended."); myNet.sendBroadcastMessage("Hello world!"); + Serial.print("Unicast message to MAC "); Serial.print(myNet.macToString(target)); Serial.println(" sended."); myNet.sendUnicastMessage("Hello world!", target); + Serial.print("Unicast with confirm message to MAC "); Serial.print(myNet.macToString(target)); + Serial.print(" ID "); + Serial.print(myNet.sendUnicastMessage("Hello world!", target, true)); Serial.println(" sended."); - myNet.sendUnicastMessage("Hello world!", target, true); + messageLastTime = millis(); } myNet.maintenance(); } -void onConfirmReceiving(const uint8_t *target, const bool status) +void onConfirmReceiving(const uint8_t *target, const uint16_t id, const bool status) { Serial.print("Message to MAC "); Serial.print(myNet.macToString(target)); + Serial.print(" ID "); + Serial.print(id); Serial.println(status ? " delivered." : " undelivered."); } \ No newline at end of file diff --git a/library.properties b/library.properties index a5ebbe9..9639481 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ZHNetwork -version=1.31 +version=1.32 author=Alexey Zholtikov maintainer=Alexey Zholtikov sentence=ESP-NOW based Mesh network for ESP8266/ESP32 diff --git a/src/ZHNetwork.cpp b/src/ZHNetwork.cpp index 2e0b5cb..e4f13a2 100644 --- a/src/ZHNetwork.cpp +++ b/src/ZHNetwork.cpp @@ -1,6 +1,7 @@ #include "ZHNetwork.h" routing_vector_t ZHNetwork::routingVector; +confirmation_vector_t ZHNetwork::confirmationVector; incoming_queue_t ZHNetwork::queueForIncomingData; outgoing_queue_t ZHNetwork::queueForOutgoingData; waiting_queue_t ZHNetwork::queueForRoutingVectorWaiting; @@ -53,14 +54,14 @@ error_code_t ZHNetwork::begin(const char *netName, const bool gateway) return SUCCESS; } -void ZHNetwork::sendBroadcastMessage(const char *data) +uint16_t ZHNetwork::sendBroadcastMessage(const char *data) { - broadcastMessage(data, broadcastMAC, BROADCAST); + return broadcastMessage(data, broadcastMAC, BROADCAST); } -void ZHNetwork::sendUnicastMessage(const char *data, const uint8_t *target, const bool confirm) +uint16_t ZHNetwork::sendUnicastMessage(const char *data, const uint8_t *target, const bool confirm) { - unicastMessage(data, target, localMAC, confirm ? UNICAST_WITH_CONFIRM : UNICAST); + return unicastMessage(data, target, localMAC, confirm ? UNICAST_WITH_CONFIRM : UNICAST); } void ZHNetwork::maintenance() @@ -80,7 +81,15 @@ void ZHNetwork::maintenance() esp_now_del_peer(outgoingData.intermediateTargetMAC); #endif if (onConfirmReceivingCallback && macToString(outgoingData.transmittedData.originalSenderMAC) == macToString(localMAC) && outgoingData.transmittedData.messageType == BROADCAST) - onConfirmReceivingCallback(outgoingData.transmittedData.originalTargetMAC, true); + onConfirmReceivingCallback(outgoingData.transmittedData.originalTargetMAC, outgoingData.transmittedData.messageID, true); + if (macToString(outgoingData.transmittedData.originalSenderMAC) == macToString(localMAC) && outgoingData.transmittedData.messageType == UNICAST_WITH_CONFIRM) + { + confirmation_waiting_data_t confirmationData; + confirmationData.time = millis(); + memcpy(&confirmationData.targetMAC, &outgoingData.transmittedData.originalTargetMAC, 6); + memcpy(&confirmationData.messageID, &outgoingData.transmittedData.messageID, 2); + confirmationVector.push_back(confirmationData); + } } else { @@ -218,7 +227,11 @@ void ZHNetwork::maintenance() { if (onUnicastReceivingCallback) onUnicastReceivingCallback(incomingData.transmittedData.message, incomingData.transmittedData.originalSenderMAC); - unicastMessage("", incomingData.transmittedData.originalSenderMAC, localMAC, DELIVERY_CONFIRM_RESPONSE); + confirmation_id_t id; + memcpy(&id.messageID, &incomingData.transmittedData.messageID, 2); + char temp[sizeof(transmitted_data_t::message)]; + memcpy(&temp, &id, sizeof(transmitted_data_t::message)); + unicastMessage(temp, incomingData.transmittedData.originalSenderMAC, localMAC, DELIVERY_CONFIRM_RESPONSE); } else unicastMessage(incomingData.transmittedData.message, incomingData.transmittedData.originalTargetMAC, incomingData.transmittedData.originalSenderMAC, UNICAST_WITH_CONFIRM); @@ -236,7 +249,17 @@ void ZHNetwork::maintenance() if (macToString(incomingData.transmittedData.originalTargetMAC) == macToString(localMAC)) { if (onConfirmReceivingCallback) - onConfirmReceivingCallback(incomingData.transmittedData.originalSenderMAC, true); + { + confirmation_id_t id; + memcpy(&id.messageID, &incomingData.transmittedData.message, 2); + for (uint16_t i{0}; i < confirmationVector.size(); ++i) + { + confirmation_waiting_data_t confirmationData = confirmationVector[i]; + if (confirmationData.messageID == id.messageID) + confirmationVector.erase(confirmationVector.begin() + i); + } + onConfirmReceivingCallback(incomingData.transmittedData.originalSenderMAC, id.messageID, true); + } } else unicastMessage(incomingData.transmittedData.message, incomingData.transmittedData.originalTargetMAC, incomingData.transmittedData.originalSenderMAC, DELIVERY_CONFIRM_RESPONSE); @@ -374,7 +397,21 @@ void ZHNetwork::maintenance() #endif if (waitingData.transmittedData.messageType == UNICAST_WITH_CONFIRM && macToString(waitingData.transmittedData.originalSenderMAC) == macToString(localMAC)) if (onConfirmReceivingCallback) - onConfirmReceivingCallback(waitingData.transmittedData.originalTargetMAC, false); + onConfirmReceivingCallback(waitingData.transmittedData.originalTargetMAC, waitingData.transmittedData.messageID, false); + } + } + if (confirmationVector.size()) + { + for (uint16_t i{0}; i < confirmationVector.size(); ++i) + { + confirmation_waiting_data_t confirmationData = confirmationVector[i]; + if ((millis() - confirmationData.time) > 1000) + { + confirmationVector.erase(confirmationVector.begin() + i); + broadcastMessage("", confirmationData.targetMAC, SEARCH_REQUEST); + if (onConfirmReceivingCallback) + onConfirmReceivingCallback(confirmationData.targetMAC, confirmationData.messageID, false); + } } } } @@ -505,7 +542,7 @@ void IRAM_ATTR ZHNetwork::onDataReceive(uint8_t *mac, uint8_t *data, uint8_t len criticalProcessSemaphore = false; } -void ZHNetwork::broadcastMessage(const char *data, const uint8_t *target, message_type_t type) +uint16_t ZHNetwork::broadcastMessage(const char *data, const uint8_t *target, message_type_t type) { outgoing_data_t outgoingData; outgoingData.transmittedData.messageType = type; @@ -537,9 +574,10 @@ void ZHNetwork::broadcastMessage(const char *data, const uint8_t *target, messag Serial.print(macToString(outgoingData.transmittedData.originalTargetMAC)); Serial.println(F(" added to queue.")); #endif + return outgoingData.transmittedData.messageID; } -void ZHNetwork::unicastMessage(const char *data, const uint8_t *target, const uint8_t *sender, message_type_t type) +uint16_t ZHNetwork::unicastMessage(const char *data, const uint8_t *target, const uint8_t *sender, message_type_t type) { outgoing_data_t outgoingData; outgoingData.transmittedData.messageType = type; @@ -583,7 +621,7 @@ void ZHNetwork::unicastMessage(const char *data, const uint8_t *target, const ui Serial.print(macToString(outgoingData.intermediateTargetMAC)); Serial.println(F(" added to queue.")); #endif - return; + return outgoingData.transmittedData.messageID; } } memcpy(&outgoingData.intermediateTargetMAC, target, 6); @@ -616,4 +654,5 @@ void ZHNetwork::unicastMessage(const char *data, const uint8_t *target, const ui Serial.print(macToString(outgoingData.intermediateTargetMAC)); Serial.println(F(" added to queue.")); #endif + return outgoingData.transmittedData.messageID; } \ No newline at end of file diff --git a/src/ZHNetwork.h b/src/ZHNetwork.h index f34be6c..992a023 100644 --- a/src/ZHNetwork.h +++ b/src/ZHNetwork.h @@ -50,6 +50,19 @@ typedef struct uint8_t intermediateTargetMAC[6]{0}; } routing_table_t; +typedef struct +{ + uint16_t messageID{0}; + char empty[198]{0}; // Just only to prevent compiler warnings. +} confirmation_id_t; + +typedef struct +{ + uint64_t time{0}; + uint8_t targetMAC[6]{0}; + uint16_t messageID{0}; +} confirmation_waiting_data_t; + typedef enum { BROADCAST = 1, @@ -67,8 +80,9 @@ typedef enum // Just for further development. } error_code_t; typedef std::function on_message_t; -typedef std::function on_confirm_t; +typedef std::function on_confirm_t; typedef std::vector routing_vector_t; +typedef std::vector confirmation_vector_t; typedef std::queue outgoing_queue_t; typedef std::queue incoming_queue_t; typedef std::queue waiting_queue_t; @@ -82,8 +96,8 @@ public: error_code_t begin(const char *netName = "", const bool gateway = false); - void sendBroadcastMessage(const char *data); - void sendUnicastMessage(const char *data, const uint8_t *target, const bool confirm = false); + uint16_t sendBroadcastMessage(const char *data); + uint16_t sendUnicastMessage(const char *data, const uint8_t *target, const bool confirm = false); void maintenance(void); @@ -103,6 +117,7 @@ public: private: static routing_vector_t routingVector; + static confirmation_vector_t confirmationVector; static incoming_queue_t queueForIncomingData; static outgoing_queue_t queueForOutgoingData; static waiting_queue_t queueForRoutingVectorWaiting; @@ -115,7 +130,7 @@ private: static uint16_t lastMessageID[10]; static char netName_[20]; - const char *firmware{"1.31"}; + const char *firmware{"1.32"}; const uint8_t broadcastMAC[6]{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; uint8_t maxNumberOfAttempts_{3}; uint8_t maxWaitingTimeBetweenTransmissions_{50}; @@ -131,8 +146,8 @@ private: static void onDataSent(const uint8_t *mac, esp_now_send_status_t status); static void onDataReceive(const uint8_t *mac, const uint8_t *data, int length); #endif - void broadcastMessage(const char *data, const uint8_t *target, message_type_t type); - void unicastMessage(const char *data, const uint8_t *target, const uint8_t *sender, message_type_t type); + uint16_t broadcastMessage(const char *data, const uint8_t *target, message_type_t type); + uint16_t unicastMessage(const char *data, const uint8_t *target, const uint8_t *sender, message_type_t type); on_message_t onBroadcastReceivingCallback; on_message_t onUnicastReceivingCallback; on_confirm_t onConfirmReceivingCallback;