700 lines
27 KiB
C++
700 lines
27 KiB
C++
#include "ZHNetwork.h"
|
|
|
|
routing_vector_t ZHNetwork::routingVector;
|
|
incoming_queue_t ZHNetwork::queueForIncomingData;
|
|
outgoing_queue_t ZHNetwork::queueForOutgoingData;
|
|
waiting_queue_t ZHNetwork::queueForRoutingVectorWaiting;
|
|
|
|
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)
|
|
{
|
|
this->onBroadcastReceivingCallback = onBroadcastReceivingCallback;
|
|
return *this;
|
|
}
|
|
|
|
ZHNetwork &ZHNetwork::setOnUnicastReceivingCallback(on_message_t onUnicastReceivingCallback)
|
|
{
|
|
this->onUnicastReceivingCallback = onUnicastReceivingCallback;
|
|
return *this;
|
|
}
|
|
|
|
ZHNetwork &ZHNetwork::setOnConfirmReceivingCallback(on_confirm_t onConfirmReceivingCallback)
|
|
{
|
|
this->onConfirmReceivingCallback = onConfirmReceivingCallback;
|
|
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;
|
|
strcpy(netName_, netName);
|
|
return SUCCESS;
|
|
}
|
|
|
|
String ZHNetwork::getNetName()
|
|
{
|
|
return netName_;
|
|
}
|
|
|
|
error_code_t ZHNetwork::setStaSetting(const char *ssid, const char *password)
|
|
{
|
|
if (strlen(ssid) < 1 || strlen(ssid) > 32 || strlen(password) > 64)
|
|
return ERROR;
|
|
strcpy(staSsid_, ssid);
|
|
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;
|
|
strcpy(apSsid_, ssid);
|
|
strcpy(apPassword_, password);
|
|
return SUCCESS;
|
|
}
|
|
|
|
error_code_t ZHNetwork::begin()
|
|
{
|
|
randomSeed(analogRead(0));
|
|
#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);
|
|
esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
|
|
#endif
|
|
#if defined(ESP32)
|
|
esp_wifi_get_mac((wifi_interface_t)ESP_IF_WIFI_STA, localMAC);
|
|
#endif
|
|
esp_now_register_send_cb(onDataSent);
|
|
esp_now_register_recv_cb(onDataReceive);
|
|
return SUCCESS;
|
|
}
|
|
|
|
error_code_t ZHNetwork::stop()
|
|
{
|
|
WiFi.mode(WIFI_OFF);
|
|
esp_now_deinit();
|
|
esp_now_unregister_recv_cb();
|
|
esp_now_unregister_send_cb();
|
|
return SUCCESS;
|
|
}
|
|
|
|
void ZHNetwork::sendBroadcastMessage(const char *data)
|
|
{
|
|
broadcastMessage(data, broadcastMAC, BROADCAST);
|
|
}
|
|
|
|
void ZHNetwork::sendUnicastMessage(const char *data, const uint8_t *target, const bool confirm)
|
|
{
|
|
unicastMessage(data, target, localMAC, confirm ? UNICAST_WITH_CONFIRM : UNICAST);
|
|
}
|
|
|
|
void ZHNetwork::maintenance()
|
|
{
|
|
if (sentMessageSemaphore && confirmReceivingSemaphore)
|
|
{
|
|
sentMessageSemaphore = false;
|
|
confirmReceivingSemaphore = false;
|
|
if (confirmReceiving)
|
|
{
|
|
#ifdef PRINT_LOG
|
|
Serial.println(F("OK."));
|
|
#endif
|
|
outgoing_data_t outgoingData = queueForOutgoingData.front();
|
|
queueForOutgoingData.pop();
|
|
#if defined(ESP32)
|
|
esp_now_del_peer(outgoingData.intermediateTargetMAC);
|
|
#endif
|
|
if (onConfirmReceivingCallback && macToString(outgoingData.transmittedData.originalSenderMAC) == macToString(localMAC) && outgoingData.transmittedData.messageType == BROADCAST)
|
|
onConfirmReceivingCallback(outgoingData.transmittedData.originalTargetMAC, true);
|
|
}
|
|
else
|
|
{
|
|
#ifdef PRINT_LOG
|
|
Serial.println(F("FAULT."));
|
|
#endif
|
|
if (numberOfAttemptsToSend < maxNumberOfAttempts_)
|
|
++numberOfAttemptsToSend;
|
|
else
|
|
{
|
|
outgoing_data_t outgoingData = queueForOutgoingData.front();
|
|
queueForOutgoingData.pop();
|
|
#if defined(ESP32)
|
|
esp_now_del_peer(outgoingData.intermediateTargetMAC);
|
|
#endif
|
|
numberOfAttemptsToSend = 1;
|
|
for (uint16_t i{0}; i < routingVector.size(); ++i)
|
|
{
|
|
routing_table_t routingTable = routingVector[i];
|
|
if (macToString(routingTable.originalTargetMAC) == macToString(outgoingData.transmittedData.originalTargetMAC))
|
|
{
|
|
routingVector.erase(routingVector.begin() + i);
|
|
#ifdef PRINT_LOG
|
|
Serial.print(F("CHECKING ROUTING TABLE... Routing to MAC "));
|
|
Serial.print(macToString(outgoingData.transmittedData.originalTargetMAC));
|
|
Serial.println(F(" deleted."));
|
|
#endif
|
|
}
|
|
}
|
|
waiting_data_t waitingData;
|
|
waitingData.time = millis();
|
|
memcpy(&waitingData.intermediateTargetMAC, &outgoingData.intermediateTargetMAC, 6);
|
|
memcpy(&waitingData.transmittedData, &outgoingData.transmittedData, sizeof(transmitted_data_t));
|
|
queueForRoutingVectorWaiting.push(waitingData);
|
|
broadcastMessage("", outgoingData.transmittedData.originalTargetMAC, SEARCH_REQUEST);
|
|
}
|
|
}
|
|
}
|
|
if (!queueForOutgoingData.empty() && ((millis() - lastMessageSentTime) > maxWaitingTimeBetweenTransmissions_))
|
|
{
|
|
outgoing_data_t outgoingData = queueForOutgoingData.front();
|
|
#if defined(ESP32)
|
|
esp_now_peer_info_t peerInfo;
|
|
memset(&peerInfo, 0, sizeof(peerInfo));
|
|
memcpy(peerInfo.peer_addr, outgoingData.intermediateTargetMAC, 6);
|
|
peerInfo.channel = 1;
|
|
peerInfo.encrypt = false;
|
|
esp_now_add_peer(&peerInfo);
|
|
#endif
|
|
esp_now_send(outgoingData.intermediateTargetMAC, (uint8_t *)&outgoingData.transmittedData, sizeof(transmitted_data_t));
|
|
lastMessageSentTime = millis();
|
|
sentMessageSemaphore = true;
|
|
#ifdef PRINT_LOG
|
|
switch (outgoingData.transmittedData.messageType)
|
|
{
|
|
case BROADCAST:
|
|
Serial.print(F("BROADCAST"));
|
|
break;
|
|
case UNICAST:
|
|
Serial.print(F("UNICAST"));
|
|
break;
|
|
case UNICAST_WITH_CONFIRM:
|
|
Serial.print(F("UNICAST_WITH_CONFIRM"));
|
|
break;
|
|
case DELIVERY_CONFIRM_RESPONSE:
|
|
Serial.print(F("DELIVERY_CONFIRM_RESPONSE"));
|
|
break;
|
|
case SEARCH_REQUEST:
|
|
Serial.print(F("SEARCH_REQUEST"));
|
|
break;
|
|
case SEARCH_RESPONSE:
|
|
Serial.print(F("SEARCH_RESPONSE"));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
Serial.print(F(" message from MAC "));
|
|
Serial.print(macToString(outgoingData.transmittedData.originalSenderMAC));
|
|
Serial.print(F(" to MAC "));
|
|
Serial.print(macToString(outgoingData.transmittedData.originalTargetMAC));
|
|
Serial.print(F(" via MAC "));
|
|
Serial.print(macToString(outgoingData.intermediateTargetMAC));
|
|
Serial.print(F(" sended. Status "));
|
|
#endif
|
|
}
|
|
if (!queueForIncomingData.empty())
|
|
{
|
|
criticalProcessSemaphore = true;
|
|
incoming_data_t incomingData = queueForIncomingData.front();
|
|
queueForIncomingData.pop();
|
|
criticalProcessSemaphore = false;
|
|
bool forward{false};
|
|
bool routingUpdate{false};
|
|
switch (incomingData.transmittedData.messageType)
|
|
{
|
|
case BROADCAST:
|
|
#ifdef PRINT_LOG
|
|
Serial.print(F("BROADCAST message from MAC "));
|
|
Serial.print(macToString(incomingData.transmittedData.originalSenderMAC));
|
|
Serial.println(F(" received."));
|
|
#endif
|
|
if (onBroadcastReceivingCallback)
|
|
onBroadcastReceivingCallback(incomingData.transmittedData.message, incomingData.transmittedData.originalSenderMAC);
|
|
forward = true;
|
|
break;
|
|
case UNICAST:
|
|
#ifdef PRINT_LOG
|
|
Serial.print(F("UNICAST message from MAC "));
|
|
Serial.print(macToString(incomingData.transmittedData.originalSenderMAC));
|
|
Serial.print(F(" to MAC "));
|
|
Serial.print(macToString(incomingData.transmittedData.originalTargetMAC));
|
|
Serial.print(F(" via MAC "));
|
|
Serial.print(macToString(incomingData.intermediateSenderMAC));
|
|
Serial.println(F(" received."));
|
|
#endif
|
|
if (macToString(incomingData.transmittedData.originalTargetMAC) == macToString(localMAC))
|
|
{
|
|
if (onUnicastReceivingCallback)
|
|
onUnicastReceivingCallback(incomingData.transmittedData.message, incomingData.transmittedData.originalSenderMAC);
|
|
}
|
|
else
|
|
unicastMessage(incomingData.transmittedData.message, incomingData.transmittedData.originalTargetMAC, incomingData.transmittedData.originalSenderMAC, UNICAST);
|
|
break;
|
|
case UNICAST_WITH_CONFIRM:
|
|
#ifdef PRINT_LOG
|
|
Serial.print(F("UNICAST_WITH_CONFIRM message from MAC "));
|
|
Serial.print(macToString(incomingData.transmittedData.originalSenderMAC));
|
|
Serial.print(F(" to MAC "));
|
|
Serial.print(macToString(incomingData.transmittedData.originalTargetMAC));
|
|
Serial.print(F(" via MAC "));
|
|
Serial.print(macToString(incomingData.intermediateSenderMAC));
|
|
Serial.println(F(" received."));
|
|
#endif
|
|
if (macToString(incomingData.transmittedData.originalTargetMAC) == macToString(localMAC))
|
|
{
|
|
if (onUnicastReceivingCallback)
|
|
onUnicastReceivingCallback(incomingData.transmittedData.message, incomingData.transmittedData.originalSenderMAC);
|
|
unicastMessage("", incomingData.transmittedData.originalSenderMAC, localMAC, DELIVERY_CONFIRM_RESPONSE);
|
|
}
|
|
else
|
|
unicastMessage(incomingData.transmittedData.message, incomingData.transmittedData.originalTargetMAC, incomingData.transmittedData.originalSenderMAC, UNICAST_WITH_CONFIRM);
|
|
break;
|
|
case DELIVERY_CONFIRM_RESPONSE:
|
|
#ifdef PRINT_LOG
|
|
Serial.print(F("DELIVERY_CONFIRM_RESPONSE message from MAC "));
|
|
Serial.print(macToString(incomingData.transmittedData.originalSenderMAC));
|
|
Serial.print(F(" to MAC "));
|
|
Serial.print(macToString(incomingData.transmittedData.originalTargetMAC));
|
|
Serial.print(F(" via MAC "));
|
|
Serial.print(macToString(incomingData.intermediateSenderMAC));
|
|
Serial.println(F(" received."));
|
|
#endif
|
|
if (macToString(incomingData.transmittedData.originalTargetMAC) == macToString(localMAC))
|
|
{
|
|
if (onConfirmReceivingCallback)
|
|
onConfirmReceivingCallback(incomingData.transmittedData.originalSenderMAC, true);
|
|
}
|
|
else
|
|
unicastMessage(incomingData.transmittedData.message, incomingData.transmittedData.originalTargetMAC, incomingData.transmittedData.originalSenderMAC, DELIVERY_CONFIRM_RESPONSE);
|
|
break;
|
|
case SEARCH_REQUEST:
|
|
#ifdef PRINT_LOG
|
|
Serial.print(F("SEARCH_REQUEST message from MAC "));
|
|
Serial.print(macToString(incomingData.transmittedData.originalSenderMAC));
|
|
Serial.print(F(" to MAC "));
|
|
Serial.print(macToString(incomingData.transmittedData.originalTargetMAC));
|
|
Serial.println(F(" received."));
|
|
#endif
|
|
if (macToString(incomingData.transmittedData.originalTargetMAC) == macToString(localMAC))
|
|
broadcastMessage("", incomingData.transmittedData.originalSenderMAC, SEARCH_RESPONSE);
|
|
else
|
|
forward = true;
|
|
routingUpdate = true;
|
|
break;
|
|
case SEARCH_RESPONSE:
|
|
#ifdef PRINT_LOG
|
|
Serial.print(F("SEARCH_RESPONSE message from MAC "));
|
|
Serial.print(macToString(incomingData.transmittedData.originalSenderMAC));
|
|
Serial.print(F(" to MAC "));
|
|
Serial.print(macToString(incomingData.transmittedData.originalTargetMAC));
|
|
Serial.println(F(" received."));
|
|
#endif
|
|
if (macToString(incomingData.transmittedData.originalTargetMAC) != macToString(localMAC))
|
|
forward = true;
|
|
routingUpdate = true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (forward)
|
|
{
|
|
outgoing_data_t outgoingData;
|
|
memcpy(&outgoingData.transmittedData, &incomingData.transmittedData, sizeof(transmitted_data_t));
|
|
memcpy(&outgoingData.intermediateTargetMAC, &broadcastMAC, 6);
|
|
queueForOutgoingData.push(outgoingData);
|
|
delay(random(10));
|
|
}
|
|
if (routingUpdate)
|
|
{
|
|
bool routeFound{false};
|
|
for (uint16_t i{0}; i < routingVector.size(); ++i)
|
|
{
|
|
routing_table_t routingTable = routingVector[i];
|
|
if (macToString(routingTable.originalTargetMAC) == macToString(incomingData.transmittedData.originalSenderMAC))
|
|
{
|
|
routeFound = true;
|
|
if (macToString(routingTable.intermediateTargetMAC) != macToString(incomingData.intermediateSenderMAC))
|
|
{
|
|
memcpy(&routingTable.intermediateTargetMAC, &incomingData.intermediateSenderMAC, 6);
|
|
routingVector.at(i) = routingTable;
|
|
#ifdef PRINT_LOG
|
|
Serial.print(F("CHECKING ROUTING TABLE... Routing to MAC "));
|
|
Serial.print(macToString(incomingData.transmittedData.originalSenderMAC));
|
|
Serial.print(F(" updated. Target is "));
|
|
Serial.print(macToString(incomingData.intermediateSenderMAC));
|
|
Serial.println(F("."));
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
if (!routeFound)
|
|
{
|
|
if (macToString(incomingData.transmittedData.originalSenderMAC) != macToString(incomingData.intermediateSenderMAC))
|
|
{
|
|
routing_table_t routingTable;
|
|
memcpy(&routingTable.originalTargetMAC, &incomingData.transmittedData.originalSenderMAC, 6);
|
|
memcpy(&routingTable.intermediateTargetMAC, &incomingData.intermediateSenderMAC, 6);
|
|
routingVector.push_back(routingTable);
|
|
#ifdef PRINT_LOG
|
|
Serial.print(F("CHECKING ROUTING TABLE... Routing to MAC "));
|
|
Serial.print(macToString(incomingData.transmittedData.originalSenderMAC));
|
|
Serial.print(F(" added. Target is "));
|
|
Serial.print(macToString(incomingData.intermediateSenderMAC));
|
|
Serial.println(F("."));
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!queueForRoutingVectorWaiting.empty())
|
|
{
|
|
waiting_data_t waitingData = queueForRoutingVectorWaiting.front();
|
|
for (uint16_t i{0}; i < routingVector.size(); ++i)
|
|
{
|
|
routing_table_t routingTable = routingVector[i];
|
|
if (macToString(routingTable.originalTargetMAC) == macToString(waitingData.transmittedData.originalTargetMAC))
|
|
{
|
|
queueForRoutingVectorWaiting.pop();
|
|
outgoing_data_t outgoingData;
|
|
memcpy(&outgoingData.transmittedData, &waitingData.transmittedData, sizeof(transmitted_data_t));
|
|
memcpy(&outgoingData.intermediateTargetMAC, &routingTable.intermediateTargetMAC, 6);
|
|
queueForOutgoingData.push(outgoingData);
|
|
#ifdef PRINT_LOG
|
|
Serial.print(F("CHECKING ROUTING TABLE... Routing to MAC "));
|
|
Serial.print(macToString(outgoingData.transmittedData.originalTargetMAC));
|
|
Serial.print(F(" found. Target is "));
|
|
Serial.print(macToString(outgoingData.intermediateTargetMAC));
|
|
Serial.println(F("."));
|
|
#endif
|
|
return;
|
|
}
|
|
}
|
|
if ((millis() - waitingData.time) > maxTimeForRoutingInfoWaiting_)
|
|
{
|
|
queueForRoutingVectorWaiting.pop();
|
|
#ifdef PRINT_LOG
|
|
Serial.print(F("CHECKING ROUTING TABLE... Routing to MAC "));
|
|
Serial.print(macToString(waitingData.transmittedData.originalTargetMAC));
|
|
Serial.println(F(" not found."));
|
|
switch (waitingData.transmittedData.messageType)
|
|
{
|
|
case UNICAST:
|
|
Serial.print(F("UNICAST"));
|
|
break;
|
|
case UNICAST_WITH_CONFIRM:
|
|
Serial.print(F("UNICAST_WITH_CONFIRM"));
|
|
break;
|
|
case DELIVERY_CONFIRM_RESPONSE:
|
|
Serial.print(F("DELIVERY_CONFIRM_RESPONSE"));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
Serial.print(F(" message from MAC "));
|
|
Serial.print(macToString(waitingData.transmittedData.originalSenderMAC));
|
|
Serial.print(F(" to MAC "));
|
|
Serial.print(macToString(waitingData.transmittedData.originalTargetMAC));
|
|
Serial.print(F(" via MAC "));
|
|
Serial.print(macToString(waitingData.intermediateTargetMAC));
|
|
Serial.println(F(" undelivered."));
|
|
#endif
|
|
if (waitingData.transmittedData.messageType == UNICAST_WITH_CONFIRM && macToString(waitingData.transmittedData.originalSenderMAC) == macToString(localMAC))
|
|
if (onConfirmReceivingCallback)
|
|
onConfirmReceivingCallback(waitingData.transmittedData.originalTargetMAC, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
String ZHNetwork::macToString(const uint8_t *mac)
|
|
{
|
|
String string;
|
|
const char baseChars[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
|
for (uint32_t i{0}; i < 6; ++i)
|
|
{
|
|
string += (char)pgm_read_byte(baseChars + (mac[i] >> 4));
|
|
string += (char)pgm_read_byte(baseChars + mac[i] % 16);
|
|
}
|
|
return string;
|
|
}
|
|
|
|
uint8_t *ZHNetwork::stringToMac(const String &string, uint8_t *mac)
|
|
{
|
|
const uint8_t baseChars[75]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0,
|
|
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 0, 0, 0, 0, 0, 0,
|
|
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35};
|
|
for (uint32_t i = 0; i < 6; ++i)
|
|
mac[i] = (pgm_read_byte(baseChars + string.charAt(i * 2) - '0') << 4) + pgm_read_byte(baseChars + string.charAt(i * 2 + 1) - '0');
|
|
return mac;
|
|
}
|
|
|
|
error_code_t ZHNetwork::setMaxNumberOfAttempts(const uint8_t maxNumberOfAttempts)
|
|
{
|
|
if (maxNumberOfAttempts < 1 || maxNumberOfAttempts > 10)
|
|
return ERROR;
|
|
maxNumberOfAttempts_ = maxNumberOfAttempts;
|
|
return SUCCESS;
|
|
}
|
|
|
|
uint8_t ZHNetwork::getMaxNumberOfAttempts()
|
|
{
|
|
return maxNumberOfAttempts_;
|
|
}
|
|
|
|
error_code_t ZHNetwork::setMaxWaitingTimeBetweenTransmissions(const uint8_t maxWaitingTimeBetweenTransmissions)
|
|
{
|
|
if (maxWaitingTimeBetweenTransmissions < 50 || maxWaitingTimeBetweenTransmissions > 250)
|
|
return ERROR;
|
|
maxWaitingTimeBetweenTransmissions_ = maxWaitingTimeBetweenTransmissions;
|
|
return SUCCESS;
|
|
}
|
|
|
|
uint8_t ZHNetwork::getMaxWaitingTimeBetweenTransmissions()
|
|
{
|
|
return maxWaitingTimeBetweenTransmissions_;
|
|
}
|
|
|
|
error_code_t ZHNetwork::setMaxWaitingTimeForRoutingInfo(const uint16_t maxTimeForRoutingInfoWaiting)
|
|
{
|
|
if (maxTimeForRoutingInfoWaiting < 500 || maxTimeForRoutingInfoWaiting > 5000)
|
|
return ERROR;
|
|
maxTimeForRoutingInfoWaiting_ = maxTimeForRoutingInfoWaiting;
|
|
return SUCCESS;
|
|
}
|
|
|
|
uint16_t ZHNetwork::getMaxWaitingTimeForRoutingInfo()
|
|
{
|
|
return maxTimeForRoutingInfoWaiting_;
|
|
}
|
|
|
|
#if defined(ESP8266)
|
|
void IRAM_ATTR ZHNetwork::onDataSent(uint8_t *mac, uint8_t status)
|
|
#endif
|
|
#if defined(ESP32)
|
|
void IRAM_ATTR ZHNetwork::onDataSent(const uint8_t *mac, esp_now_send_status_t status)
|
|
#endif
|
|
{
|
|
confirmReceivingSemaphore = true;
|
|
confirmReceiving = status ? false : true;
|
|
}
|
|
|
|
#if defined(ESP8266)
|
|
void IRAM_ATTR ZHNetwork::onDataReceive(uint8_t *mac, uint8_t *data, uint8_t length)
|
|
#endif
|
|
#if defined(ESP32)
|
|
void IRAM_ATTR ZHNetwork::onDataReceive(const uint8_t *mac, const uint8_t *data, int length)
|
|
#endif
|
|
{
|
|
if (criticalProcessSemaphore)
|
|
return;
|
|
criticalProcessSemaphore = true;
|
|
if (length != sizeof(transmitted_data_t))
|
|
{
|
|
criticalProcessSemaphore = false;
|
|
return;
|
|
}
|
|
incoming_data_t incomingData;
|
|
memcpy(&incomingData.transmittedData, data, sizeof(transmitted_data_t));
|
|
if (macToString(incomingData.transmittedData.originalSenderMAC) == macToString(localMAC))
|
|
{
|
|
criticalProcessSemaphore = false;
|
|
return;
|
|
}
|
|
if (String(netName_) != "")
|
|
{
|
|
if (String(incomingData.transmittedData.netName) != String(netName_))
|
|
{
|
|
criticalProcessSemaphore = false;
|
|
return;
|
|
}
|
|
}
|
|
for (uint8_t i{0}; i < sizeof(lastMessageID) / 2; ++i)
|
|
if (lastMessageID[i] == incomingData.transmittedData.messageID)
|
|
{
|
|
criticalProcessSemaphore = false;
|
|
return;
|
|
}
|
|
for (uint8_t i{sizeof(lastMessageID) / 2 - 1}; i >= 1; --i)
|
|
lastMessageID[i] = lastMessageID[i - 1];
|
|
lastMessageID[0] = incomingData.transmittedData.messageID;
|
|
memcpy(&incomingData.intermediateSenderMAC, mac, 6);
|
|
queueForIncomingData.push(incomingData);
|
|
criticalProcessSemaphore = false;
|
|
}
|
|
|
|
void ZHNetwork::broadcastMessage(const char *data, const uint8_t *target, message_type_t type)
|
|
{
|
|
outgoing_data_t outgoingData;
|
|
outgoingData.transmittedData.messageType = type;
|
|
outgoingData.transmittedData.messageID = ((uint16_t)random(32767) << 8) | (uint16_t)random(32767);
|
|
memcpy(&outgoingData.transmittedData.netName, &netName_, 20);
|
|
memcpy(&outgoingData.transmittedData.originalTargetMAC, target, 6);
|
|
memcpy(&outgoingData.transmittedData.originalSenderMAC, &localMAC, 6);
|
|
strcpy(outgoingData.transmittedData.message, data);
|
|
memcpy(&outgoingData.intermediateTargetMAC, &broadcastMAC, 6);
|
|
queueForOutgoingData.push(outgoingData);
|
|
#ifdef PRINT_LOG
|
|
switch (outgoingData.transmittedData.messageType)
|
|
{
|
|
case BROADCAST:
|
|
Serial.print(F("BROADCAST"));
|
|
break;
|
|
case SEARCH_REQUEST:
|
|
Serial.print(F("SEARCH_REQUEST"));
|
|
break;
|
|
case SEARCH_RESPONSE:
|
|
Serial.print(F("SEARCH_RESPONSE"));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
Serial.print(F(" message from MAC "));
|
|
Serial.print(macToString(outgoingData.transmittedData.originalSenderMAC));
|
|
Serial.print(F(" to MAC "));
|
|
Serial.print(macToString(outgoingData.transmittedData.originalTargetMAC));
|
|
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;
|
|
outgoingData.transmittedData.messageType = type;
|
|
outgoingData.transmittedData.messageID = ((uint16_t)random(32767) << 8) | (uint16_t)random(32767);
|
|
memcpy(&outgoingData.transmittedData.netName, &netName_, 20);
|
|
memcpy(&outgoingData.transmittedData.originalTargetMAC, target, 6);
|
|
memcpy(&outgoingData.transmittedData.originalSenderMAC, sender, 6);
|
|
strcpy(outgoingData.transmittedData.message, data);
|
|
for (uint16_t i{0}; i < routingVector.size(); ++i)
|
|
{
|
|
routing_table_t routingTable = routingVector[i];
|
|
if (macToString(routingTable.originalTargetMAC) == macToString(target))
|
|
{
|
|
memcpy(&outgoingData.intermediateTargetMAC, &routingTable.intermediateTargetMAC, 6);
|
|
queueForOutgoingData.push(outgoingData);
|
|
#ifdef PRINT_LOG
|
|
Serial.print(F("CHECKING ROUTING TABLE... Routing to MAC "));
|
|
Serial.print(macToString(outgoingData.transmittedData.originalTargetMAC));
|
|
Serial.print(F(" found. Target is "));
|
|
Serial.print(macToString(outgoingData.intermediateTargetMAC));
|
|
Serial.println(F("."));
|
|
switch (outgoingData.transmittedData.messageType)
|
|
{
|
|
case UNICAST:
|
|
Serial.print(F("UNICAST"));
|
|
break;
|
|
case UNICAST_WITH_CONFIRM:
|
|
Serial.print(F("UNICAST_WITH_CONFIRM"));
|
|
break;
|
|
case DELIVERY_CONFIRM_RESPONSE:
|
|
Serial.print(F("DELIVERY_CONFIRM_RESPONSE"));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
Serial.print(F(" message from MAC "));
|
|
Serial.print(macToString(outgoingData.transmittedData.originalSenderMAC));
|
|
Serial.print(F(" to MAC "));
|
|
Serial.print(macToString(outgoingData.transmittedData.originalTargetMAC));
|
|
Serial.print(F(" via MAC "));
|
|
Serial.print(macToString(outgoingData.intermediateTargetMAC));
|
|
Serial.println(F(" added to queue."));
|
|
#endif
|
|
return;
|
|
}
|
|
}
|
|
memcpy(&outgoingData.intermediateTargetMAC, target, 6);
|
|
queueForOutgoingData.push(outgoingData);
|
|
#ifdef PRINT_LOG
|
|
Serial.print(F("CHECKING ROUTING TABLE... Routing to MAC "));
|
|
Serial.print(macToString(outgoingData.transmittedData.originalTargetMAC));
|
|
Serial.print(F(" not found. Target is "));
|
|
Serial.print(macToString(outgoingData.intermediateTargetMAC));
|
|
Serial.println(F("."));
|
|
switch (outgoingData.transmittedData.messageType)
|
|
{
|
|
case UNICAST:
|
|
Serial.print(F("UNICAST"));
|
|
break;
|
|
case UNICAST_WITH_CONFIRM:
|
|
Serial.print(F("UNICAST_WITH_CONFIRM"));
|
|
break;
|
|
case DELIVERY_CONFIRM_RESPONSE:
|
|
Serial.print(F("DELIVERY_CONFIRM_RESPONSE"));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
Serial.print(F(" message from MAC "));
|
|
Serial.print(macToString(outgoingData.transmittedData.originalSenderMAC));
|
|
Serial.print(F(" to MAC "));
|
|
Serial.print(macToString(outgoingData.transmittedData.originalTargetMAC));
|
|
Serial.print(F(" via MAC "));
|
|
Serial.print(macToString(outgoingData.intermediateTargetMAC));
|
|
Serial.println(F(" added to queue."));
|
|
#endif
|
|
} |