10 Commits
v1.0 ... v1.3

Author SHA1 Message Date
b328ad916c Version 1.3
Removed a lot of unnecessary functions.
2022-12-22 18:27:17 +03:00
1d5198e0ab Minor changes 2022-12-18 18:02:23 +03:00
aae51f907c Minor changes 2022-12-18 09:34:51 +03:00
8942471c6f Minor changes 2022-12-18 09:16:28 +03:00
c1fe139756 Version 1.12
Fixed one minor bug.
2022-12-16 10:41:28 +03:00
4f58a04eae Version 1.11
Minor code optimization.
2022-12-12 18:58:03 +03:00
2ed860b78b Version 1.1
Added stop() function.
2022-12-11 09:39:20 +03:00
425e5035c9 Version 1.02
Minor code optimization.
2022-12-11 09:13:25 +03:00
7a1b67102e Minor changes 2022-12-10 15:18:15 +03:00
67dcf3f407 Version 1.01
Optimizing using RAM on PRINT_LOG mode.
2022-12-10 15:11:11 +03:00
6 changed files with 144 additions and 334 deletions

View File

@ -22,6 +22,11 @@ A simple library for creating ESP-NOW based Mesh network for ESP8266/ESP32.
5. Voila. ;-)
6. P.S. Uncomment #define PRINT_LOG in ZHNetwork.h for display to serial port the full operation log.
## Notes
1. Possibility uses WiFi AP or STA modes at the same time with ESP-NOW using the standard libraries.
2. For correct work at ESP-NOW + STA mode your WiFi router must be set on channel 1.
## Function descriptions
### Sets the callback function for processing a received broadcast message
@ -60,60 +65,14 @@ void onConfirmReceiving(const uint8_t *target, const bool status)
}
```
### Sets one of the three possibility operating modes
* ESP_NOW. Default mode. ESP-NOW Mesh network only.
* ESP_NOW_AP. ESP-NOW Mesh network + access point.
* ESP_NOW_STA. ESP-NOW Mesh network + connect to your WiFi router.
Attention! For correct work on ESP_NOW_STA mode at ESP8266 your WiFi router must be set on channel 1.
```cpp
myNet.setWorkMode(ESP_NOW);
```
### Gets used operating mode
```cpp
myNet.getWorkMode();
```
### Sets ESP-NOW Mesh network name
### ESP-NOW Mesh network initialization
1-20 characters.
Note. If network name not set node will work with all ESP-NOW networks. If set node will work with only one network.
```cpp
myNet.setNetName("ZHNetwork");
```
### Gets used ESP-NOW Mesh network name
```cpp
myNet.getNetName();
```
### Sets WiFi ssid and password for ESP_NOW_STA mode
Note. Must be called before Mesh network initialization.
```cpp
myNet.setStaSetting("SSID", "PASSWORD");
```
### Sets access point ssid and password for ESP_NOW_AP mode
Note. Must be called before Mesh network initialization.
```cpp
myNet.setApSetting("SSID", "PASSWORD");
```
### ESP-NOW Mesh network initialization
```cpp
myNet.begin();
myNet.begin("ZHNetwork");
```
### Sends broadcast message to all nodes
@ -143,12 +102,6 @@ myNet.maintenance();
myNet.getNodeMac();
```
### Gets node IP address
```cpp
myNet.getNodeIp();
```
### Gets version of this library
```cpp
@ -221,7 +174,7 @@ void onConfirmReceiving(const uint8_t *target, const bool status);
ZHNetwork myNet;
uint64_t messagelastTime{0};
uint64_t messageLastTime{0};
uint16_t messageTimerDelay{5000};
const uint8_t target[6]{0xA8, 0x48, 0xFA, 0xDC, 0x5B, 0xFA};
@ -229,27 +182,12 @@ void setup()
{
Serial.begin(115200);
Serial.println();
// *** ESP-NOW mode only.
myNet.setWorkMode(ESP_NOW);
// *** Or ESP-NOW + access point mode.
// myNet.setWorkMode(ESP_NOW_AP);
// myNet.setApSetting("ESP NODE TEST", "12345678");
// *** Or ESP-NOW + connect to your router mode.
// myNet.setWorkMode(ESP_NOW_STA);
// myNet.setStaSetting("SSID", "PASSWORD");
// ***
myNet.setNetName("ZHNetwork"); // Optional.
myNet.setMaxNumberOfAttempts(3); // Optional.
myNet.setMaxWaitingTimeBetweenTransmissions(50); // Optional.
myNet.setMaxWaitingTimeForRoutingInfo(500); // Optional.
myNet.begin();
myNet.begin("ZHNetwork");
myNet.setOnBroadcastReceivingCallback(onBroadcastReceiving);
myNet.setOnUnicastReceivingCallback(onUnicastReceiving);
myNet.setOnConfirmReceivingCallback(onConfirmReceiving);
Serial.print("MAC: ");
Serial.print(myNet.getNodeMac());
Serial.print(". IP: ");
Serial.print(myNet.getNodeIp());
Serial.print(". Firmware version: ");
Serial.print(myNet.getFirmwareVersion());
Serial.println(".");
@ -257,7 +195,7 @@ void setup()
void loop()
{
if ((millis() - messagelastTime) > messageTimerDelay)
if ((millis() - messageLastTime) > messageTimerDelay)
{
Serial.println("Broadcast message sended.");
myNet.sendBroadcastMessage("Hello world!");
@ -269,7 +207,7 @@ void loop()
Serial.print(myNet.macToString(target));
Serial.println(" sended.");
myNet.sendUnicastMessage("Hello world!", target, true);
messagelastTime = millis();
messageLastTime = millis();
}
myNet.maintenance();
}

View File

@ -9,26 +9,11 @@ void setup()
{
Serial.begin(115200);
Serial.println();
// *** ESP-NOW mode only.
myNet.setWorkMode(ESP_NOW);
// *** Or ESP-NOW + access point mode.
// myNet.setWorkMode(ESP_NOW_AP);
// myNet.setApSetting("ESP NODE TEST", "12345678");
// *** Or ESP-NOW + connect to your router mode.
// myNet.setWorkMode(ESP_NOW_STA);
// myNet.setStaSetting("SSID", "PASSWORD");
// ***
myNet.setNetName("ZHNetwork"); // Optional.
myNet.setMaxNumberOfAttempts(3); // Optional.
myNet.setMaxWaitingTimeBetweenTransmissions(50); // Optional.
myNet.setMaxWaitingTimeForRoutingInfo(500); // Optional.
myNet.begin();
myNet.begin("ZHNetwork");
myNet.setOnBroadcastReceivingCallback(onBroadcastReceiving);
myNet.setOnUnicastReceivingCallback(onUnicastReceiving);
Serial.print("MAC: ");
Serial.print(myNet.getNodeMac());
Serial.print(". IP: ");
Serial.print(myNet.getNodeIp());
Serial.print(". Firmware version: ");
Serial.print(myNet.getFirmwareVersion());
Serial.println(".");

View File

@ -4,7 +4,7 @@ void onConfirmReceiving(const uint8_t *target, const bool status);
ZHNetwork myNet;
uint64_t messagelastTime{0};
uint64_t messageLastTime{0};
uint16_t messageTimerDelay{5000};
const uint8_t target[6]{0xA8, 0x48, 0xFA, 0xDC, 0x5B, 0xFA};
@ -12,25 +12,10 @@ void setup()
{
Serial.begin(115200);
Serial.println();
// *** ESP-NOW mode only.
myNet.setWorkMode(ESP_NOW);
// *** Or ESP-NOW + access point mode.
// myNet.setWorkMode(ESP_NOW_AP);
// myNet.setApSetting("ESP NODE TEST", "12345678");
// *** Or ESP-NOW + connect to your router mode.
// myNet.setWorkMode(ESP_NOW_STA);
// myNet.setStaSetting("SSID", "PASSWORD");
// ***
myNet.setNetName("ZHNetwork"); // Optional.
myNet.setMaxNumberOfAttempts(3); // Optional.
myNet.setMaxWaitingTimeBetweenTransmissions(50); // Optional.
myNet.setMaxWaitingTimeForRoutingInfo(500); // Optional.
myNet.begin();
myNet.begin("ZHNetwork");
myNet.setOnConfirmReceivingCallback(onConfirmReceiving);
Serial.print("MAC: ");
Serial.print(myNet.getNodeMac());
Serial.print(". IP: ");
Serial.print(myNet.getNodeIp());
Serial.print(". Firmware version: ");
Serial.print(myNet.getFirmwareVersion());
Serial.println(".");
@ -38,7 +23,7 @@ void setup()
void loop()
{
if ((millis() - messagelastTime) > messageTimerDelay)
if ((millis() - messageLastTime) > messageTimerDelay)
{
Serial.println("Broadcast message sended.");
myNet.sendBroadcastMessage("Hello world!");
@ -50,7 +35,7 @@ void loop()
Serial.print(myNet.macToString(target));
Serial.println(" sended.");
myNet.sendUnicastMessage("Hello world!", target, true);
messagelastTime = millis();
messageLastTime = millis();
}
myNet.maintenance();
}

View File

@ -1,5 +1,5 @@
name=ZHNetwork
version=1.0
version=1.3
author=Alexey Zholtikov
maintainer=Alexey Zholtikov
sentence=ESP-NOW based Mesh network for ESP8266/ESP32

View File

@ -1,31 +1,17 @@
#include "ZHNetwork.h"
routing_vector_t routingVector;
incoming_queue_t queueForIncomingData;
outgoing_queue_t queueForOutgoingData;
waiting_queue_t queueForRoutingVectorWaiting;
routing_vector_t ZHNetwork::routingVector;
incoming_queue_t ZHNetwork::queueForIncomingData;
outgoing_queue_t ZHNetwork::queueForOutgoingData;
waiting_queue_t ZHNetwork::queueForRoutingVectorWaiting;
const String firmware{"1.0"};
const uint8_t broadcastMAC[6]{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
bool criticalProcessSemaphore{false};
bool sentMessageSemaphore{false};
bool confirmReceivingSemaphore{false};
bool confirmReceiving{false};
uint8_t localMAC[6]{0};
uint8_t numberOfAttemptsToSend{1};
uint16_t lastMessageID[10]{0};
uint64_t lastMessageSentTime{0};
work_mode_t workMode_{ESP_NOW};
char netName_[20]{0};
char apSsid_[32]{"ESP-NOW NODE"};
char apPassword_[64]{0};
char staSsid_[32]{0};
char staPassword_[64]{0};
uint8_t maxNumberOfAttempts_{3};
uint8_t maxWaitingTimeBetweenTransmissions_{50};
uint16_t maxTimeForRoutingInfoWaiting_{500};
bool ZHNetwork::criticalProcessSemaphore{false};
bool ZHNetwork::sentMessageSemaphore{false};
bool ZHNetwork::confirmReceivingSemaphore{false};
bool ZHNetwork::confirmReceiving{false};
char ZHNetwork::netName_[20]{0};
uint8_t ZHNetwork::localMAC[6]{0};
uint16_t ZHNetwork::lastMessageID[10]{0};
ZHNetwork &ZHNetwork::setOnBroadcastReceivingCallback(on_message_t onBroadcastReceivingCallback)
{
@ -45,83 +31,15 @@ ZHNetwork &ZHNetwork::setOnConfirmReceivingCallback(on_confirm_t onConfirmReceiv
return *this;
}
error_code_t ZHNetwork::setWorkMode(const work_mode_t workMode)
{
if (workMode < ESP_NOW || workMode > ESP_NOW_STA)
return ERROR;
workMode_ = workMode;
return SUCCESS;
}
work_mode_t ZHNetwork::getWorkMode()
{
return workMode_;
}
error_code_t ZHNetwork::setNetName(const char *netName)
{
if (strlen(netName) < 1 || strlen(netName) > 20)
return ERROR;
memset(&netName_, 0, strlen(netName));
strcpy(netName_, netName);
return SUCCESS;
}
String ZHNetwork::getNetName()
{
return String(netName_);
}
error_code_t ZHNetwork::setStaSetting(const char *ssid, const char *password)
{
if (strlen(ssid) < 1 || strlen(ssid) > 32 || strlen(password) > 64)
return ERROR;
memset(&staSsid_, 0, strlen(ssid));
strcpy(staSsid_, ssid);
memset(&staPassword_, 0, strlen(password));
strcpy(staPassword_, password);
return SUCCESS;
}
error_code_t ZHNetwork::setApSetting(const char *ssid, const char *password)
{
if (strlen(ssid) < 1 || strlen(ssid) > 32 || strlen(password) < 8 || strlen(password) > 64)
return ERROR;
memset(&apSsid_, 0, strlen(ssid));
strcpy(apSsid_, ssid);
memset(&apPassword_, 0, strlen(password));
strcpy(apPassword_, password);
return SUCCESS;
}
error_code_t ZHNetwork::begin()
error_code_t ZHNetwork::begin(const char *netName)
{
randomSeed(analogRead(0));
if (strlen(netName) > 1 && strlen(netName) < 20)
strcpy(netName_, netName);
#ifdef PRINT_LOG
Serial.begin(115200);
#endif
switch (workMode_)
{
case ESP_NOW:
WiFi.mode(WIFI_STA);
break;
case ESP_NOW_AP:
WiFi.mode(WIFI_AP_STA);
WiFi.softAP(apSsid_, apPassword_);
break;
case ESP_NOW_STA:
WiFi.mode(WIFI_STA);
WiFi.begin(staSsid_, staPassword_);
while (WiFi.status() != WL_CONNECTED)
{
if (WiFi.status() == WL_NO_SSID_AVAIL || WiFi.status() == WL_CONNECT_FAILED)
return ERROR;
delay(500);
}
break;
default:
break;
}
esp_now_init();
#if defined(ESP8266)
wifi_get_macaddr(STATION_IF, localMAC);
@ -154,7 +72,7 @@ void ZHNetwork::maintenance()
if (confirmReceiving)
{
#ifdef PRINT_LOG
Serial.println("OK.");
Serial.println(F("OK."));
#endif
outgoing_data_t outgoingData = queueForOutgoingData.front();
queueForOutgoingData.pop();
@ -167,7 +85,7 @@ void ZHNetwork::maintenance()
else
{
#ifdef PRINT_LOG
Serial.println("FAULT.");
Serial.println(F("FAULT."));
#endif
if (numberOfAttemptsToSend < maxNumberOfAttempts_)
++numberOfAttemptsToSend;
@ -186,14 +104,13 @@ void ZHNetwork::maintenance()
{
routingVector.erase(routingVector.begin() + i);
#ifdef PRINT_LOG
Serial.print("CHECKING ROUTING TABLE... Routing to MAC ");
Serial.print(F("CHECKING ROUTING TABLE... Routing to MAC "));
Serial.print(macToString(outgoingData.transmittedData.originalTargetMAC));
Serial.println(" deleted.");
Serial.println(F(" deleted."));
#endif
}
}
waiting_data_t waitingData;
esp_memset(&waitingData, 0, sizeof(waiting_data_t));
waitingData.time = millis();
memcpy(&waitingData.intermediateTargetMAC, &outgoingData.intermediateTargetMAC, 6);
memcpy(&waitingData.transmittedData, &outgoingData.transmittedData, sizeof(transmitted_data_t));
@ -220,33 +137,33 @@ void ZHNetwork::maintenance()
switch (outgoingData.transmittedData.messageType)
{
case BROADCAST:
Serial.print("BROADCAST");
Serial.print(F("BROADCAST"));
break;
case UNICAST:
Serial.print("UNICAST");
Serial.print(F("UNICAST"));
break;
case UNICAST_WITH_CONFIRM:
Serial.print("UNICAST_WITH_CONFIRM");
Serial.print(F("UNICAST_WITH_CONFIRM"));
break;
case DELIVERY_CONFIRM_RESPONSE:
Serial.print("DELIVERY_CONFIRM_RESPONSE");
Serial.print(F("DELIVERY_CONFIRM_RESPONSE"));
break;
case SEARCH_REQUEST:
Serial.print("SEARCH_REQUEST");
Serial.print(F("SEARCH_REQUEST"));
break;
case SEARCH_RESPONSE:
Serial.print("SEARCH_RESPONSE");
Serial.print(F("SEARCH_RESPONSE"));
break;
default:
break;
}
Serial.print(" message from MAC ");
Serial.print(F(" message from MAC "));
Serial.print(macToString(outgoingData.transmittedData.originalSenderMAC));
Serial.print(" to MAC ");
Serial.print(F(" to MAC "));
Serial.print(macToString(outgoingData.transmittedData.originalTargetMAC));
Serial.print(" via MAC ");
Serial.print(F(" via MAC "));
Serial.print(macToString(outgoingData.intermediateTargetMAC));
Serial.print(" sended. Status ");
Serial.print(F(" sended. Status "));
#endif
}
if (!queueForIncomingData.empty())
@ -261,9 +178,9 @@ void ZHNetwork::maintenance()
{
case BROADCAST:
#ifdef PRINT_LOG
Serial.print("BROADCAST message from MAC ");
Serial.print(F("BROADCAST message from MAC "));
Serial.print(macToString(incomingData.transmittedData.originalSenderMAC));
Serial.println(" received.");
Serial.println(F(" received."));
#endif
if (onBroadcastReceivingCallback)
onBroadcastReceivingCallback(incomingData.transmittedData.message, incomingData.transmittedData.originalSenderMAC);
@ -271,13 +188,13 @@ void ZHNetwork::maintenance()
break;
case UNICAST:
#ifdef PRINT_LOG
Serial.print("UNICAST message from MAC ");
Serial.print(F("UNICAST message from MAC "));
Serial.print(macToString(incomingData.transmittedData.originalSenderMAC));
Serial.print(" to MAC ");
Serial.print(F(" to MAC "));
Serial.print(macToString(incomingData.transmittedData.originalTargetMAC));
Serial.print(" via MAC ");
Serial.print(F(" via MAC "));
Serial.print(macToString(incomingData.intermediateSenderMAC));
Serial.println(" received.");
Serial.println(F(" received."));
#endif
if (macToString(incomingData.transmittedData.originalTargetMAC) == macToString(localMAC))
{
@ -289,13 +206,13 @@ void ZHNetwork::maintenance()
break;
case UNICAST_WITH_CONFIRM:
#ifdef PRINT_LOG
Serial.print("UNICAST_WITH_CONFIRM message from MAC ");
Serial.print(F("UNICAST_WITH_CONFIRM message from MAC "));
Serial.print(macToString(incomingData.transmittedData.originalSenderMAC));
Serial.print(" to MAC ");
Serial.print(F(" to MAC "));
Serial.print(macToString(incomingData.transmittedData.originalTargetMAC));
Serial.print(" via MAC ");
Serial.print(F(" via MAC "));
Serial.print(macToString(incomingData.intermediateSenderMAC));
Serial.println(" received.");
Serial.println(F(" received."));
#endif
if (macToString(incomingData.transmittedData.originalTargetMAC) == macToString(localMAC))
{
@ -308,13 +225,13 @@ void ZHNetwork::maintenance()
break;
case DELIVERY_CONFIRM_RESPONSE:
#ifdef PRINT_LOG
Serial.print("DELIVERY_CONFIRM_RESPONSE message from MAC ");
Serial.print(F("DELIVERY_CONFIRM_RESPONSE message from MAC "));
Serial.print(macToString(incomingData.transmittedData.originalSenderMAC));
Serial.print(" to MAC ");
Serial.print(F(" to MAC "));
Serial.print(macToString(incomingData.transmittedData.originalTargetMAC));
Serial.print(" via MAC ");
Serial.print(F(" via MAC "));
Serial.print(macToString(incomingData.intermediateSenderMAC));
Serial.println(" received.");
Serial.println(F(" received."));
#endif
if (macToString(incomingData.transmittedData.originalTargetMAC) == macToString(localMAC))
{
@ -326,11 +243,11 @@ void ZHNetwork::maintenance()
break;
case SEARCH_REQUEST:
#ifdef PRINT_LOG
Serial.print("SEARCH_REQUEST message from MAC ");
Serial.print(F("SEARCH_REQUEST message from MAC "));
Serial.print(macToString(incomingData.transmittedData.originalSenderMAC));
Serial.print(" to MAC ");
Serial.print(F(" to MAC "));
Serial.print(macToString(incomingData.transmittedData.originalTargetMAC));
Serial.println(" received.");
Serial.println(F(" received."));
#endif
if (macToString(incomingData.transmittedData.originalTargetMAC) == macToString(localMAC))
broadcastMessage("", incomingData.transmittedData.originalSenderMAC, SEARCH_RESPONSE);
@ -340,11 +257,11 @@ void ZHNetwork::maintenance()
break;
case SEARCH_RESPONSE:
#ifdef PRINT_LOG
Serial.print("SEARCH_RESPONSE message from MAC ");
Serial.print(F("SEARCH_RESPONSE message from MAC "));
Serial.print(macToString(incomingData.transmittedData.originalSenderMAC));
Serial.print(" to MAC ");
Serial.print(F(" to MAC "));
Serial.print(macToString(incomingData.transmittedData.originalTargetMAC));
Serial.println(" received.");
Serial.println(F(" received."));
#endif
if (macToString(incomingData.transmittedData.originalTargetMAC) != macToString(localMAC))
forward = true;
@ -375,11 +292,11 @@ void ZHNetwork::maintenance()
memcpy(&routingTable.intermediateTargetMAC, &incomingData.intermediateSenderMAC, 6);
routingVector.at(i) = routingTable;
#ifdef PRINT_LOG
Serial.print("CHECKING ROUTING TABLE... Routing to MAC ");
Serial.print(F("CHECKING ROUTING TABLE... Routing to MAC "));
Serial.print(macToString(incomingData.transmittedData.originalSenderMAC));
Serial.print(" updated. Target is ");
Serial.print(F(" updated. Target is "));
Serial.print(macToString(incomingData.intermediateSenderMAC));
Serial.println(".");
Serial.println(F("."));
#endif
}
}
@ -393,11 +310,11 @@ void ZHNetwork::maintenance()
memcpy(&routingTable.intermediateTargetMAC, &incomingData.intermediateSenderMAC, 6);
routingVector.push_back(routingTable);
#ifdef PRINT_LOG
Serial.print("CHECKING ROUTING TABLE... Routing to MAC ");
Serial.print(F("CHECKING ROUTING TABLE... Routing to MAC "));
Serial.print(macToString(incomingData.transmittedData.originalSenderMAC));
Serial.print(" added. Target is ");
Serial.print(F(" added. Target is "));
Serial.print(macToString(incomingData.intermediateSenderMAC));
Serial.println(".");
Serial.println(F("."));
#endif
}
}
@ -413,16 +330,15 @@ void ZHNetwork::maintenance()
{
queueForRoutingVectorWaiting.pop();
outgoing_data_t outgoingData;
esp_memset(&outgoingData, 0, sizeof(outgoing_data_t));
memcpy(&outgoingData.transmittedData, &waitingData.transmittedData, sizeof(transmitted_data_t));
memcpy(&outgoingData.intermediateTargetMAC, &routingTable.intermediateTargetMAC, 6);
queueForOutgoingData.push(outgoingData);
#ifdef PRINT_LOG
Serial.print("CHECKING ROUTING TABLE... Routing to MAC ");
Serial.print(F("CHECKING ROUTING TABLE... Routing to MAC "));
Serial.print(macToString(outgoingData.transmittedData.originalTargetMAC));
Serial.print(" found. Target is ");
Serial.print(F(" found. Target is "));
Serial.print(macToString(outgoingData.intermediateTargetMAC));
Serial.println(".");
Serial.println(F("."));
#endif
return;
}
@ -431,30 +347,30 @@ void ZHNetwork::maintenance()
{
queueForRoutingVectorWaiting.pop();
#ifdef PRINT_LOG
Serial.print("CHECKING ROUTING TABLE... Routing to MAC ");
Serial.print(F("CHECKING ROUTING TABLE... Routing to MAC "));
Serial.print(macToString(waitingData.transmittedData.originalTargetMAC));
Serial.println(" not found.");
Serial.println(F(" not found."));
switch (waitingData.transmittedData.messageType)
{
case UNICAST:
Serial.print("UNICAST");
Serial.print(F("UNICAST"));
break;
case UNICAST_WITH_CONFIRM:
Serial.print("UNICAST_WITH_CONFIRM");
Serial.print(F("UNICAST_WITH_CONFIRM"));
break;
case DELIVERY_CONFIRM_RESPONSE:
Serial.print("DELIVERY_CONFIRM_RESPONSE");
Serial.print(F("DELIVERY_CONFIRM_RESPONSE"));
break;
default:
break;
}
Serial.print(" message from MAC ");
Serial.print(F(" message from MAC "));
Serial.print(macToString(waitingData.transmittedData.originalSenderMAC));
Serial.print(" to MAC ");
Serial.print(F(" to MAC "));
Serial.print(macToString(waitingData.transmittedData.originalTargetMAC));
Serial.print(" via MAC ");
Serial.print(F(" via MAC "));
Serial.print(macToString(waitingData.intermediateTargetMAC));
Serial.println(" undelivered.");
Serial.println(F(" undelivered."));
#endif
if (waitingData.transmittedData.messageType == UNICAST_WITH_CONFIRM && macToString(waitingData.transmittedData.originalSenderMAC) == macToString(localMAC))
if (onConfirmReceivingCallback)
@ -468,15 +384,6 @@ String ZHNetwork::getNodeMac()
return macToString(localMAC);
}
IPAddress ZHNetwork::getNodeIp()
{
if (workMode_ == ESP_NOW_AP)
return WiFi.softAPIP();
if (workMode_ == ESP_NOW_STA)
return WiFi.localIP();
return IPAddress(0, 0, 0, 0);
}
String ZHNetwork::getFirmwareVersion()
{
return firmware;
@ -601,7 +508,6 @@ void IRAM_ATTR ZHNetwork::onDataReceive(uint8_t *mac, uint8_t *data, uint8_t len
void ZHNetwork::broadcastMessage(const char *data, const uint8_t *target, message_type_t type)
{
outgoing_data_t outgoingData;
esp_memset(&outgoingData, 0, sizeof(outgoing_data_t));
outgoingData.transmittedData.messageType = type;
outgoingData.transmittedData.messageID = ((uint16_t)random(32767) << 8) | (uint16_t)random(32767);
memcpy(&outgoingData.transmittedData.netName, &netName_, 20);
@ -614,29 +520,28 @@ void ZHNetwork::broadcastMessage(const char *data, const uint8_t *target, messag
switch (outgoingData.transmittedData.messageType)
{
case BROADCAST:
Serial.print("BROADCAST");
Serial.print(F("BROADCAST"));
break;
case SEARCH_REQUEST:
Serial.print("SEARCH_REQUEST");
Serial.print(F("SEARCH_REQUEST"));
break;
case SEARCH_RESPONSE:
Serial.print("SEARCH_RESPONSE");
Serial.print(F("SEARCH_RESPONSE"));
break;
default:
break;
}
Serial.print(" message from MAC ");
Serial.print(F(" message from MAC "));
Serial.print(macToString(outgoingData.transmittedData.originalSenderMAC));
Serial.print(" to MAC ");
Serial.print(F(" to MAC "));
Serial.print(macToString(outgoingData.transmittedData.originalTargetMAC));
Serial.println(" added to queue.");
Serial.println(F(" added to queue."));
#endif
}
void ZHNetwork::unicastMessage(const char *data, const uint8_t *target, const uint8_t *sender, message_type_t type)
{
outgoing_data_t outgoingData;
esp_memset(&outgoingData, 0, sizeof(outgoing_data_t));
outgoingData.transmittedData.messageType = type;
outgoingData.transmittedData.messageID = ((uint16_t)random(32767) << 8) | (uint16_t)random(32767);
memcpy(&outgoingData.transmittedData.netName, &netName_, 20);
@ -651,32 +556,32 @@ void ZHNetwork::unicastMessage(const char *data, const uint8_t *target, const ui
memcpy(&outgoingData.intermediateTargetMAC, &routingTable.intermediateTargetMAC, 6);
queueForOutgoingData.push(outgoingData);
#ifdef PRINT_LOG
Serial.print("CHECKING ROUTING TABLE... Routing to MAC ");
Serial.print(F("CHECKING ROUTING TABLE... Routing to MAC "));
Serial.print(macToString(outgoingData.transmittedData.originalTargetMAC));
Serial.print(" found. Target is ");
Serial.print(F(" found. Target is "));
Serial.print(macToString(outgoingData.intermediateTargetMAC));
Serial.println(".");
Serial.println(F("."));
switch (outgoingData.transmittedData.messageType)
{
case UNICAST:
Serial.print("UNICAST");
Serial.print(F("UNICAST"));
break;
case UNICAST_WITH_CONFIRM:
Serial.print("UNICAST_WITH_CONFIRM");
Serial.print(F("UNICAST_WITH_CONFIRM"));
break;
case DELIVERY_CONFIRM_RESPONSE:
Serial.print("DELIVERY_CONFIRM_RESPONSE");
Serial.print(F("DELIVERY_CONFIRM_RESPONSE"));
break;
default:
break;
}
Serial.print(" message from MAC ");
Serial.print(F(" message from MAC "));
Serial.print(macToString(outgoingData.transmittedData.originalSenderMAC));
Serial.print(" to MAC ");
Serial.print(F(" to MAC "));
Serial.print(macToString(outgoingData.transmittedData.originalTargetMAC));
Serial.print(" via MAC ");
Serial.print(F(" via MAC "));
Serial.print(macToString(outgoingData.intermediateTargetMAC));
Serial.println(" added to queue.");
Serial.println(F(" added to queue."));
#endif
return;
}
@ -684,31 +589,31 @@ void ZHNetwork::unicastMessage(const char *data, const uint8_t *target, const ui
memcpy(&outgoingData.intermediateTargetMAC, target, 6);
queueForOutgoingData.push(outgoingData);
#ifdef PRINT_LOG
Serial.print("CHECKING ROUTING TABLE... Routing to MAC ");
Serial.print(F("CHECKING ROUTING TABLE... Routing to MAC "));
Serial.print(macToString(outgoingData.transmittedData.originalTargetMAC));
Serial.print(" not found. Target is ");
Serial.print(F(" not found. Target is "));
Serial.print(macToString(outgoingData.intermediateTargetMAC));
Serial.println(".");
Serial.println(F("."));
switch (outgoingData.transmittedData.messageType)
{
case UNICAST:
Serial.print("UNICAST");
Serial.print(F("UNICAST"));
break;
case UNICAST_WITH_CONFIRM:
Serial.print("UNICAST_WITH_CONFIRM");
Serial.print(F("UNICAST_WITH_CONFIRM"));
break;
case DELIVERY_CONFIRM_RESPONSE:
Serial.print("DELIVERY_CONFIRM_RESPONSE");
Serial.print(F("DELIVERY_CONFIRM_RESPONSE"));
break;
default:
break;
}
Serial.print(" message from MAC ");
Serial.print(F(" message from MAC "));
Serial.print(macToString(outgoingData.transmittedData.originalSenderMAC));
Serial.print(" to MAC ");
Serial.print(F(" to MAC "));
Serial.print(macToString(outgoingData.transmittedData.originalTargetMAC));
Serial.print(" via MAC ");
Serial.print(F(" via MAC "));
Serial.print(macToString(outgoingData.intermediateTargetMAC));
Serial.println(" added to queue.");
Serial.println(F(" added to queue."));
#endif
}

View File

@ -15,55 +15,41 @@
// #define PRINT_LOG // Uncomment to display to serial port the full operation log.
#if defined(ESP8266)
#define esp_memset memset // Just for remove the compiler notice for ESP8266 at "memset". I don't know why this is happening...
#endif
#if defined(ESP32)
#define esp_memset memset
#endif
typedef struct
{
uint8_t messageType;
uint16_t messageID;
char netName[20];
uint8_t originalTargetMAC[6];
uint8_t originalSenderMAC[6];
char message[200];
uint8_t messageType{0};
uint16_t messageID{0};
char netName[20]{0};
uint8_t originalTargetMAC[6]{0};
uint8_t originalSenderMAC[6]{0};
char message[200]{0};
} transmitted_data_t;
typedef struct
{
uint8_t intermediateTargetMAC[6];
uint8_t intermediateTargetMAC[6]{0};
transmitted_data_t transmittedData;
} outgoing_data_t;
typedef struct
{
uint8_t intermediateSenderMAC[6];
uint8_t intermediateSenderMAC[6]{0};
transmitted_data_t transmittedData;
} incoming_data_t;
typedef struct
{
uint64_t time;
uint8_t intermediateTargetMAC[6];
uint64_t time{0};
uint8_t intermediateTargetMAC[6]{0};
transmitted_data_t transmittedData;
} waiting_data_t;
typedef struct
{
uint8_t originalTargetMAC[6];
uint8_t intermediateTargetMAC[6];
uint8_t originalTargetMAC[6]{0};
uint8_t intermediateTargetMAC[6]{0};
} routing_table_t;
typedef enum
{
ESP_NOW = 1,
ESP_NOW_AP,
ESP_NOW_STA
} work_mode_t;
typedef enum
{
BROADCAST = 1,
@ -94,16 +80,7 @@ public:
ZHNetwork &setOnUnicastReceivingCallback(on_message_t onUnicastReceivingCallback);
ZHNetwork &setOnConfirmReceivingCallback(on_confirm_t onConfirmReceivingCallback);
error_code_t setWorkMode(const work_mode_t workMode);
work_mode_t getWorkMode(void);
error_code_t setNetName(const char *netName);
String getNetName(void);
error_code_t setStaSetting(const char *ssid, const char *password);
error_code_t setApSetting(const char *ssid, const char *password);
error_code_t begin(void);
error_code_t begin(const char *netName = "");
void sendBroadcastMessage(const char *data);
void sendUnicastMessage(const char *data, const uint8_t *target, const bool confirm = false);
@ -111,7 +88,6 @@ public:
void maintenance(void);
String getNodeMac(void);
IPAddress getNodeIp(void);
String getFirmwareVersion(void);
String readErrorCode(error_code_t code); // Just for further development.
@ -126,6 +102,27 @@ public:
uint16_t getMaxWaitingTimeForRoutingInfo(void);
private:
static routing_vector_t routingVector;
static incoming_queue_t queueForIncomingData;
static outgoing_queue_t queueForOutgoingData;
static waiting_queue_t queueForRoutingVectorWaiting;
static bool criticalProcessSemaphore;
static bool sentMessageSemaphore;
static bool confirmReceivingSemaphore;
static bool confirmReceiving;
static uint8_t localMAC[6];
static uint16_t lastMessageID[10];
static char netName_[20];
const char *firmware{"1.3"};
const uint8_t broadcastMAC[6]{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
uint8_t maxNumberOfAttempts_{3};
uint8_t maxWaitingTimeBetweenTransmissions_{50};
uint8_t numberOfAttemptsToSend{1};
uint16_t maxTimeForRoutingInfoWaiting_{500};
uint32_t lastMessageSentTime{0};
#if defined(ESP8266)
static void onDataSent(uint8_t *mac, uint8_t status);
static void onDataReceive(uint8_t *mac, uint8_t *data, uint8_t length);