1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

- Move globals to anonymous namespaces.

- Move private static variables to anonymous namespaces.

- Remove espnow prefix from names where it is not required.
This commit is contained in:
Anders 2020-05-05 16:10:37 +02:00
parent effcc3a2d0
commit e64125a53c
20 changed files with 249 additions and 274 deletions

View File

@ -28,18 +28,21 @@
#include "JsonTranslator.h" #include "JsonTranslator.h"
#include "MeshCryptoInterface.h" #include "MeshCryptoInterface.h"
using EspnowProtocolInterpreter::espnowHashKeyLength; namespace
namespace TypeCast = MeshTypeConversionFunctions; {
using EspnowProtocolInterpreter::hashKeyLength;
namespace TypeCast = MeshTypeConversionFunctions;
}
EncryptedConnectionData::EncryptedConnectionData(const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint64_t peerSessionKey, const uint64_t ownSessionKey, const uint8_t hashKey[espnowHashKeyLength]) EncryptedConnectionData::EncryptedConnectionData(const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint64_t peerSessionKey, const uint64_t ownSessionKey, const uint8_t hashKey[hashKeyLength])
: _peerSessionKey(peerSessionKey), _ownSessionKey(ownSessionKey) : _peerSessionKey(peerSessionKey), _ownSessionKey(ownSessionKey)
{ {
std::copy_n(peerStaMac, 6, _peerStaMac); std::copy_n(peerStaMac, 6, _peerStaMac);
std::copy_n(peerApMac, 6, _peerApMac); std::copy_n(peerApMac, 6, _peerApMac);
std::copy_n(hashKey, espnowHashKeyLength, _hashKey); std::copy_n(hashKey, hashKeyLength, _hashKey);
} }
EncryptedConnectionData::EncryptedConnectionData(const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint64_t peerSessionKey, const uint64_t ownSessionKey, const uint32_t duration, const uint8_t hashKey[espnowHashKeyLength]) EncryptedConnectionData::EncryptedConnectionData(const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint64_t peerSessionKey, const uint64_t ownSessionKey, const uint32_t duration, const uint8_t hashKey[hashKeyLength])
: EncryptedConnectionData(peerStaMac, peerApMac, peerSessionKey, ownSessionKey, hashKey) : EncryptedConnectionData(peerStaMac, peerApMac, peerSessionKey, ownSessionKey, hashKey)
{ {
setRemainingDuration(duration); setRemainingDuration(duration);
@ -106,16 +109,16 @@ bool EncryptedConnectionData::connectedTo(const uint8_t *peerMac) const
return false; return false;
} }
void EncryptedConnectionData::setHashKey(const uint8_t hashKey[espnowHashKeyLength]) void EncryptedConnectionData::setHashKey(const uint8_t hashKey[hashKeyLength])
{ {
assert(hashKey != nullptr); assert(hashKey != nullptr);
std::copy_n(hashKey, espnowHashKeyLength, _hashKey); std::copy_n(hashKey, hashKeyLength, _hashKey);
} }
uint8_t *EncryptedConnectionData::getHashKey(uint8_t *resultArray) const uint8_t *EncryptedConnectionData::getHashKey(uint8_t *resultArray) const
{ {
std::copy_n(_hashKey, espnowHashKeyLength, resultArray); std::copy_n(_hashKey, hashKeyLength, resultArray);
return resultArray; return resultArray;
} }
@ -146,7 +149,7 @@ uint64_t EncryptedConnectionData::incrementSessionKey(const uint64_t sessionKey,
void EncryptedConnectionData::incrementOwnSessionKey() void EncryptedConnectionData::incrementOwnSessionKey()
{ {
setOwnSessionKey(incrementSessionKey(getOwnSessionKey(), _hashKey, EspnowProtocolInterpreter::espnowHashKeyLength)); setOwnSessionKey(incrementSessionKey(getOwnSessionKey(), _hashKey, EspnowProtocolInterpreter::hashKeyLength));
} }
void EncryptedConnectionData::setDesync(const bool desync) { _desync = desync; } void EncryptedConnectionData::setDesync(const bool desync) { _desync = desync; }

View File

@ -37,9 +37,9 @@ public:
virtual ~EncryptedConnectionData() = default; virtual ~EncryptedConnectionData() = default;
EncryptedConnectionData(const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint64_t peerSessionKey, const uint64_t ownSessionKey, EncryptedConnectionData(const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint64_t peerSessionKey, const uint64_t ownSessionKey,
const uint8_t hashKey[EspnowProtocolInterpreter::espnowHashKeyLength]); const uint8_t hashKey[EspnowProtocolInterpreter::hashKeyLength]);
EncryptedConnectionData(const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint64_t peerSessionKey, const uint64_t ownSessionKey, EncryptedConnectionData(const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint64_t peerSessionKey, const uint64_t ownSessionKey,
const uint32_t duration, const uint8_t hashKey[EspnowProtocolInterpreter::espnowHashKeyLength]); const uint32_t duration, const uint8_t hashKey[EspnowProtocolInterpreter::hashKeyLength]);
EncryptedConnectionData(const EncryptedConnectionData &other); EncryptedConnectionData(const EncryptedConnectionData &other);
@ -61,8 +61,8 @@ public:
bool connectedTo(const uint8_t *peerMac) const; bool connectedTo(const uint8_t *peerMac) const;
void setHashKey(const uint8_t hashKey[EspnowProtocolInterpreter::espnowHashKeyLength]); void setHashKey(const uint8_t hashKey[EspnowProtocolInterpreter::hashKeyLength]);
// @param resultArray At least size espnowHashKeyLength. // @param resultArray At least size hashKeyLength.
uint8_t *getHashKey(uint8_t *resultArray) const; uint8_t *getHashKey(uint8_t *resultArray) const;
void setPeerSessionKey(const uint64_t sessionKey); void setPeerSessionKey(const uint64_t sessionKey);
@ -90,7 +90,7 @@ private:
uint8_t _peerApMac[6] {0}; uint8_t _peerApMac[6] {0};
uint64_t _peerSessionKey; uint64_t _peerSessionKey;
uint64_t _ownSessionKey; uint64_t _ownSessionKey;
uint8_t _hashKey[EspnowProtocolInterpreter::espnowHashKeyLength] {0}; uint8_t _hashKey[EspnowProtocolInterpreter::hashKeyLength] {0};
bool _desync = false; bool _desync = false;
std::unique_ptr<ExpiringTimeTracker> _timeTracker = nullptr; std::unique_ptr<ExpiringTimeTracker> _timeTracker = nullptr;
}; };

View File

@ -24,13 +24,16 @@
#include "EncryptedConnectionLog.h" #include "EncryptedConnectionLog.h"
using EspnowProtocolInterpreter::espnowHashKeyLength; namespace
{
using EspnowProtocolInterpreter::hashKeyLength;
}
EncryptedConnectionLog::EncryptedConnectionLog(const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint64_t peerSessionKey, const uint64_t ownSessionKey, const uint8_t hashKey[espnowHashKeyLength]) EncryptedConnectionLog::EncryptedConnectionLog(const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint64_t peerSessionKey, const uint64_t ownSessionKey, const uint8_t hashKey[hashKeyLength])
: EncryptedConnectionData(peerStaMac, peerApMac, peerSessionKey, ownSessionKey, hashKey) : EncryptedConnectionData(peerStaMac, peerApMac, peerSessionKey, ownSessionKey, hashKey)
{ } { }
EncryptedConnectionLog::EncryptedConnectionLog(const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint64_t peerSessionKey, const uint64_t ownSessionKey, const uint32_t duration, const uint8_t hashKey[espnowHashKeyLength]) EncryptedConnectionLog::EncryptedConnectionLog(const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint64_t peerSessionKey, const uint64_t ownSessionKey, const uint32_t duration, const uint8_t hashKey[hashKeyLength])
: EncryptedConnectionData(peerStaMac, peerApMac, peerSessionKey, ownSessionKey, duration, hashKey) : EncryptedConnectionData(peerStaMac, peerApMac, peerSessionKey, ownSessionKey, duration, hashKey)
{ } { }

View File

@ -33,9 +33,9 @@ class EncryptedConnectionLog : public EncryptedConnectionData {
public: public:
EncryptedConnectionLog(const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint64_t peerSessionKey, const uint64_t ownSessionKey, EncryptedConnectionLog(const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint64_t peerSessionKey, const uint64_t ownSessionKey,
const uint8_t hashKey[EspnowProtocolInterpreter::espnowHashKeyLength]); const uint8_t hashKey[EspnowProtocolInterpreter::hashKeyLength]);
EncryptedConnectionLog(const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint64_t peerSessionKey, const uint64_t ownSessionKey, EncryptedConnectionLog(const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint64_t peerSessionKey, const uint64_t ownSessionKey,
const uint32_t duration, const uint8_t hashKey[EspnowProtocolInterpreter::espnowHashKeyLength]); const uint32_t duration, const uint8_t hashKey[EspnowProtocolInterpreter::hashKeyLength]);
// Only guaranteed to expire at the latest when the soonestExpiringConnection does. Can expire before the soonestExpiringConnection since it is not updated on connection removal. // Only guaranteed to expire at the latest when the soonestExpiringConnection does. Can expire before the soonestExpiringConnection since it is not updated on connection removal.
// Needs to be a copy to avoid invalidation during operations on temporaryEncryptedConnections. // Needs to be a copy to avoid invalidation during operations on temporaryEncryptedConnections.

View File

@ -28,76 +28,83 @@ extern "C" {
#include "JsonTranslator.h" #include "JsonTranslator.h"
#include "MeshCryptoInterface.h" #include "MeshCryptoInterface.h"
using EspnowProtocolInterpreter::espnowEncryptedConnectionKeyLength; namespace
using EspnowProtocolInterpreter::espnowHashKeyLength; {
using EspnowProtocolInterpreter::encryptedConnectionKeyLength;
using EspnowProtocolInterpreter::hashKeyLength;
namespace TypeCast = MeshTypeConversionFunctions; namespace TypeCast = MeshTypeConversionFunctions;
static const uint8_t maxEncryptedConnections = 6; // This is limited by the ESP-NOW API. Max 6 in AP or AP+STA mode. Max 10 in STA mode. See "ESP-NOW User Guide" for more info. constexpr uint8_t maxEncryptedConnections = 6; // This is limited by the ESP-NOW API. Max 6 in AP or AP+STA mode. Max 10 in STA mode. See "ESP-NOW User Guide" for more info.
static const uint64_t uint64MSB = 0x8000000000000000; constexpr uint64_t uint64MSB = 0x8000000000000000;
double _transmissionsTotal = 0;
double _transmissionsFailed = 0;
std::shared_ptr<bool> _espnowSendToNodeMutex = std::make_shared<bool>(false);
uint8_t _transmissionTargetBSSID[6] = {0};
uint8_t _espnowEncryptionKok[EspnowProtocolInterpreter::encryptedConnectionKeyLength] = { 0 };
bool _espnowEncryptionKokSet = false;
uint8_t _espnowMessageEncryptionKey[CryptoInterface::ENCRYPTION_KEY_LENGTH] = { 0 };
bool _useEncryptedMessages = false;
uint32_t _unsynchronizedMessageID = 0;
String _ongoingPeerRequestNonce;
uint8_t _ongoingPeerRequestMac[6] = {0};
EspnowMeshBackend *_ongoingPeerRequester = nullptr;
EncryptedConnectionStatus _ongoingPeerRequestResult = EncryptedConnectionStatus::MAX_CONNECTIONS_REACHED_SELF;
ExpiringTimeTracker _ongoingPeerRequestEncryptionTimeout([](){ return EspnowMeshBackend::getEncryptionRequestTimeout(); });
bool _reciprocalPeerRequestConfirmation = false;
// _logEntryLifetimeMs is based on someone storing 40 responses of 750 bytes each = 30 000 bytes (roughly full memory),
// which takes 2000 ms + some margin to send. Also, we want to avoid old entries taking up memory if they cannot be sent,
// so storage duration should not be too long.
uint32_t _logEntryLifetimeMs = 2500;
uint32_t _broadcastResponseTimeoutMs = 1000; // This is shorter than _logEntryLifetimeMs to preserve RAM since broadcasts are not deleted from sentRequests until they expire.
ExpiringTimeTracker _logClearingCooldown(500);
uint32_t _encryptionRequestTimeoutMs = 300;
uint32_t _criticalHeapLevel = 6000; // In bytes
uint32_t _criticalHeapLevelBuffer = 6000; // In bytes
bool _espnowSendConfirmed = false;
std::list<ResponseData> responsesToSend = {};
std::list<PeerRequestLog> peerRequestConfirmationsToSend = {};
std::vector<EncryptedConnectionLog> encryptedConnections = {};
EspnowMeshBackend *_espnowRequestManager = nullptr;
constexpr uint32_t _maxBytesPerTransmission = 250;
uint8_t _maxTransmissionsPerMessage = 3;
uint32_t _espnowTransmissionTimeoutMs = 40;
uint32_t _espnowRetransmissionIntervalMs = 15;
}
const uint8_t EspnowMeshBackend::broadcastMac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; const uint8_t EspnowMeshBackend::broadcastMac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
const uint64_t EspnowMeshBackend::uint64BroadcastMac = 0xFFFFFFFFFFFF;
bool EspnowMeshBackend::_staticVerboseMode = false;
std::shared_ptr<bool> EspnowMeshBackend::_espnowTransmissionMutex = std::make_shared<bool>(false); std::shared_ptr<bool> EspnowMeshBackend::_espnowTransmissionMutex = std::make_shared<bool>(false);
std::shared_ptr<bool> EspnowMeshBackend::_espnowConnectionQueueMutex = std::make_shared<bool>(false); std::shared_ptr<bool> EspnowMeshBackend::_espnowConnectionQueueMutex = std::make_shared<bool>(false);
std::shared_ptr<bool> EspnowMeshBackend::_responsesToSendMutex = std::make_shared<bool>(false); std::shared_ptr<bool> EspnowMeshBackend::_responsesToSendMutex = std::make_shared<bool>(false);
EspnowMeshBackend *EspnowMeshBackend::_espnowRequestManager = nullptr;
std::map<std::pair<EspnowMeshBackend::macAndType_td, EspnowMeshBackend::messageID_td>, MessageData> EspnowMeshBackend::receivedEspnowTransmissions = {}; std::map<std::pair<EspnowMeshBackend::macAndType_td, EspnowMeshBackend::messageID_td>, MessageData> EspnowMeshBackend::receivedEspnowTransmissions = {};
std::map<std::pair<EspnowMeshBackend::peerMac_td, EspnowMeshBackend::messageID_td>, RequestData> EspnowMeshBackend::sentRequests = {}; std::map<std::pair<EspnowMeshBackend::peerMac_td, EspnowMeshBackend::messageID_td>, RequestData> EspnowMeshBackend::sentRequests = {};
std::map<std::pair<EspnowMeshBackend::peerMac_td, EspnowMeshBackend::messageID_td>, TimeTracker> EspnowMeshBackend::receivedRequests = {}; std::map<std::pair<EspnowMeshBackend::peerMac_td, EspnowMeshBackend::messageID_td>, TimeTracker> EspnowMeshBackend::receivedRequests = {};
/*
std::list<ResponseData> EspnowMeshBackend::responsesToSend = {}; std::list<ResponseData> EspnowMeshBackend::responsesToSend = {};
std::list<PeerRequestLog> EspnowMeshBackend::peerRequestConfirmationsToSend = {}; std::list<PeerRequestLog> EspnowMeshBackend::peerRequestConfirmationsToSend = {};*/
std::vector<EncryptedConnectionLog> EspnowMeshBackend::encryptedConnections = {};
std::vector<EspnowNetworkInfo> EspnowMeshBackend::_connectionQueue = {}; std::vector<EspnowNetworkInfo> EspnowMeshBackend::_connectionQueue = {};
std::vector<TransmissionOutcome> EspnowMeshBackend::_latestTransmissionOutcomes = {}; std::vector<TransmissionOutcome> EspnowMeshBackend::_latestTransmissionOutcomes = {};
uint32_t EspnowMeshBackend::_espnowTransmissionTimeoutMs = 40;
uint32_t EspnowMeshBackend::_espnowRetransmissionIntervalMs = 15;
uint32_t EspnowMeshBackend::_encryptionRequestTimeoutMs = 300;
bool EspnowMeshBackend::_espnowSendConfirmed = false;
String EspnowMeshBackend::_ongoingPeerRequestNonce;
uint8_t EspnowMeshBackend::_ongoingPeerRequestMac[6] = {0};
EspnowMeshBackend *EspnowMeshBackend::_ongoingPeerRequester = nullptr;
EncryptedConnectionStatus EspnowMeshBackend::_ongoingPeerRequestResult = EncryptedConnectionStatus::MAX_CONNECTIONS_REACHED_SELF;
ExpiringTimeTracker _ongoingPeerRequestEncryptionTimeout([](){ return EspnowMeshBackend::getEncryptionRequestTimeout(); });
bool EspnowMeshBackend::_reciprocalPeerRequestConfirmation = false;
uint8_t EspnowMeshBackend::_espnowEncryptionKok[espnowEncryptedConnectionKeyLength] = { 0 };
bool EspnowMeshBackend::_espnowEncryptionKokSet = false;
uint8_t EspnowMeshBackend::_espnowMessageEncryptionKey[CryptoInterface::ENCRYPTION_KEY_LENGTH] = { 0 };
bool EspnowMeshBackend::_useEncryptedMessages = false;
uint32_t EspnowMeshBackend::_unsynchronizedMessageID = 0;
// _logEntryLifetimeMs is based on someone storing 40 responses of 750 bytes each = 30 000 bytes (roughly full memory),
// which takes 2000 ms + some margin to send. Also, we want to avoid old entries taking up memory if they cannot be sent,
// so storage duration should not be too long.
uint32_t EspnowMeshBackend::_logEntryLifetimeMs = 2500;
uint32_t EspnowMeshBackend::_broadcastResponseTimeoutMs = 1000; // This is shorter than _logEntryLifetimeMs to preserve RAM since broadcasts are not deleted from sentRequests until they expire.
ExpiringTimeTracker _logClearingCooldown(500);
uint32_t EspnowMeshBackend::_criticalHeapLevel = 6000; // In bytes
uint32_t EspnowMeshBackend::_criticalHeapLevelBuffer = 6000; // In bytes
uint8_t EspnowMeshBackend::_maxTransmissionsPerMessage = 3;
std::shared_ptr<bool> EspnowMeshBackend::_espnowSendToNodeMutex = std::make_shared<bool>(false);
uint8_t EspnowMeshBackend::_transmissionTargetBSSID[6] = {0};
double EspnowMeshBackend::_transmissionsTotal = 0;
double EspnowMeshBackend::_transmissionsFailed = 0;
bool EspnowMeshBackend::_staticVerboseMode = false;
void espnowDelay(uint32_t durationMs) void espnowDelay(uint32_t durationMs)
{ {
ExpiringTimeTracker timeout(durationMs); ExpiringTimeTracker timeout(durationMs);
@ -128,8 +135,8 @@ EspnowMeshBackend::EspnowMeshBackend(const requestHandlerType requestHandler, co
} }
EspnowMeshBackend::EspnowMeshBackend(const requestHandlerType requestHandler, const responseHandlerType responseHandler, const networkFilterType networkFilter, EspnowMeshBackend::EspnowMeshBackend(const requestHandlerType requestHandler, const responseHandlerType responseHandler, const networkFilterType networkFilter,
const broadcastFilterType broadcastFilter, const String &meshPassword, const uint8_t espnowEncryptedConnectionKey[espnowEncryptedConnectionKeyLength], const broadcastFilterType broadcastFilter, const String &meshPassword, const uint8_t espnowEncryptedConnectionKey[encryptedConnectionKeyLength],
const uint8_t espnowHashKey[espnowHashKeyLength], const String &ssidPrefix, const String &ssidSuffix, const bool verboseMode, const uint8_t espnowHashKey[hashKeyLength], const String &ssidPrefix, const String &ssidSuffix, const bool verboseMode,
const uint8 meshWiFiChannel) const uint8 meshWiFiChannel)
: EspnowMeshBackend(requestHandler, responseHandler, networkFilter, broadcastFilter, meshPassword, ssidPrefix, ssidSuffix, verboseMode, meshWiFiChannel) : EspnowMeshBackend(requestHandler, responseHandler, networkFilter, broadcastFilter, meshPassword, ssidPrefix, ssidSuffix, verboseMode, meshWiFiChannel)
{ {
@ -169,7 +176,7 @@ bool EspnowMeshBackend::activateEspnow()
{ {
if (esp_now_init()==0) if (esp_now_init()==0)
{ {
if(_espnowEncryptionKokSet && esp_now_set_kok(_espnowEncryptionKok, espnowEncryptedConnectionKeyLength)) // esp_now_set_kok returns 0 on success. if(_espnowEncryptionKokSet && esp_now_set_kok(_espnowEncryptionKok, encryptedConnectionKeyLength)) // esp_now_set_kok returns 0 on success.
warningPrint(String(F("Failed to set ESP-NOW KoK!"))); warningPrint(String(F("Failed to set ESP-NOW KoK!")));
if(getEspnowRequestManager() == nullptr) if(getEspnowRequestManager() == nullptr)
@ -430,15 +437,15 @@ void EspnowMeshBackend::espnowReceiveCallbackWrapper(uint8_t *macaddr, uint8_t *
// Otherwise we get issues such as _espnowTransmissionMutex will usually be free, but occasionally taken (when callback occurs in a delay() during attemptTransmission). // Otherwise we get issues such as _espnowTransmissionMutex will usually be free, but occasionally taken (when callback occurs in a delay() during attemptTransmission).
MutexTracker captureBanTracker(MutexTracker::captureBan()); MutexTracker captureBanTracker(MutexTracker::captureBan());
if(len >= espnowMetadataSize()) // If we do not receive at least the metadata bytes, the transmission is invalid. if(len >= metadataSize()) // If we do not receive at least the metadata bytes, the transmission is invalid.
{ {
//uint32_t callbackStart = millis(); //uint32_t callbackStart = millis();
// If there is a espnowRequestManager, get it // If there is a espnowRequestManager, get it
EspnowMeshBackend *currentEspnowRequestManager = getEspnowRequestManager(); EspnowMeshBackend *currentEspnowRequestManager = getEspnowRequestManager();
char messageType = espnowGetMessageType(dataArray); char messageType = getMessageType(dataArray);
uint64_t receivedMessageID = espnowGetMessageID(dataArray); uint64_t receivedMessageID = getMessageID(dataArray);
if(currentEspnowRequestManager && !currentEspnowRequestManager->acceptsUnverifiedRequests() if(currentEspnowRequestManager && !currentEspnowRequestManager->acceptsUnverifiedRequests()
&& !usesConstantSessionKey(messageType) && !verifyPeerSessionKey(receivedMessageID, macaddr, messageType)) && !usesConstantSessionKey(messageType) && !verifyPeerSessionKey(receivedMessageID, macaddr, messageType))
@ -450,8 +457,8 @@ void EspnowMeshBackend::espnowReceiveCallbackWrapper(uint8_t *macaddr, uint8_t *
{ {
// chacha20Poly1305Decrypt decrypts dataArray in place. // chacha20Poly1305Decrypt decrypts dataArray in place.
// We are using the protocol bytes as a key salt. // We are using the protocol bytes as a key salt.
if(!CryptoInterface::chacha20Poly1305Decrypt(dataArray + espnowMetadataSize(), len - espnowMetadataSize(), getEspnowMessageEncryptionKey(), dataArray, if(!CryptoInterface::chacha20Poly1305Decrypt(dataArray + metadataSize(), len - metadataSize(), getEspnowMessageEncryptionKey(), dataArray,
espnowProtocolBytesSize, dataArray + espnowProtocolBytesSize, dataArray + espnowProtocolBytesSize + 12)) protocolBytesSize, dataArray + protocolBytesSize, dataArray + protocolBytesSize + 12))
{ {
return; // Decryption of message failed. return; // Decryption of message failed.
} }
@ -511,7 +518,7 @@ void EspnowMeshBackend::espnowReceiveCallbackWrapper(uint8_t *macaddr, uint8_t *
else else
{ {
// An unencrypted transmission was probably sent to the AP interface as a result of a scan. // An unencrypted transmission was probably sent to the AP interface as a result of a scan.
requestMac = espnowGetTransmissionMac(dataArray); requestMac = getTransmissionMac(dataArray);
requestSender = getOwnerOfSentRequest(requestMac, receivedMessageID); requestSender = getOwnerOfSentRequest(requestMac, receivedMessageID);
// But if not, also check if it was sent to the station interface. // But if not, also check if it was sent to the station interface.
@ -572,7 +579,7 @@ void EspnowMeshBackend::handlePeerRequest(const uint8_t *macaddr, uint8_t *dataA
storeReceivedRequest(uint64StationMac, receivedMessageID, TimeTracker(millis())); storeReceivedRequest(uint64StationMac, receivedMessageID, TimeTracker(millis()));
bool encryptedCorrectly = synchronizePeerSessionKey(receivedMessageID, macaddr); bool encryptedCorrectly = synchronizePeerSessionKey(receivedMessageID, macaddr);
String message = espnowGetMessageContent(dataArray, len); String message = getHashKeyLength(dataArray, len);
int32_t messageHeaderEndIndex = message.indexOf(':'); int32_t messageHeaderEndIndex = message.indexOf(':');
String messageHeader = message.substring(0, messageHeaderEndIndex + 1); String messageHeader = message.substring(0, messageHeaderEndIndex + 1);
@ -639,7 +646,7 @@ void EspnowMeshBackend::handlePeerRequest(const uint8_t *macaddr, uint8_t *dataA
} }
uint8_t apMacArray[6] = { 0 }; uint8_t apMacArray[6] = { 0 };
if(correctDestination && JsonTranslator::verifyEncryptionRequestHmac(message, macaddr, espnowGetTransmissionMac(dataArray, apMacArray), currentEspnowRequestManager->getEspnowHashKey(), espnowHashKeyLength)) if(correctDestination && JsonTranslator::verifyEncryptionRequestHmac(message, macaddr, getTransmissionMac(dataArray, apMacArray), currentEspnowRequestManager->getEspnowHashKey(), hashKeyLength))
peerRequestConfirmationsToSend.emplace_back(receivedMessageID, encryptedCorrectly, currentEspnowRequestManager->getMeshPassword(), currentEspnowRequestManager->encryptedConnectionsSoftLimit(), peerRequestConfirmationsToSend.emplace_back(receivedMessageID, encryptedCorrectly, currentEspnowRequestManager->getMeshPassword(), currentEspnowRequestManager->encryptedConnectionsSoftLimit(),
requestNonce, macaddr, apMacArray, currentEspnowRequestManager->getEspnowHashKey()); requestNonce, macaddr, apMacArray, currentEspnowRequestManager->getEspnowHashKey());
} }
@ -669,7 +676,7 @@ void EspnowMeshBackend::handlePeerRequestConfirmation(uint8_t *macaddr, uint8_t
if(!_ongoingPeerRequestNonce.isEmpty()) if(!_ongoingPeerRequestNonce.isEmpty())
{ {
String message = espnowGetMessageContent(dataArray, len); String message = getHashKeyLength(dataArray, len);
String requestNonce; String requestNonce;
if(JsonTranslator::getNonce(message, requestNonce) && requestNonce == _ongoingPeerRequestNonce) if(JsonTranslator::getNonce(message, requestNonce) && requestNonce == _ongoingPeerRequestNonce)
@ -678,13 +685,13 @@ void EspnowMeshBackend::handlePeerRequestConfirmation(uint8_t *macaddr, uint8_t
String messageHeader = message.substring(0, messageHeaderEndIndex + 1); String messageHeader = message.substring(0, messageHeaderEndIndex + 1);
String messageBody = message.substring(messageHeaderEndIndex + 1); String messageBody = message.substring(messageHeaderEndIndex + 1);
uint8_t apMacArray[6] = { 0 }; uint8_t apMacArray[6] = { 0 };
espnowGetTransmissionMac(dataArray, apMacArray); getTransmissionMac(dataArray, apMacArray);
if(messageHeader == FPSTR(basicConnectionInfoHeader)) if(messageHeader == FPSTR(basicConnectionInfoHeader))
{ {
// encryptedConnectionEstablished(_ongoingPeerRequestResult) means we have already received a basicConnectionInfoHeader // encryptedConnectionEstablished(_ongoingPeerRequestResult) means we have already received a basicConnectionInfoHeader
if(!encryptedConnectionEstablished(_ongoingPeerRequestResult) && if(!encryptedConnectionEstablished(_ongoingPeerRequestResult) &&
JsonTranslator::verifyEncryptionRequestHmac(message, macaddr, apMacArray, _ongoingPeerRequester->getEspnowHashKey(), espnowHashKeyLength)) JsonTranslator::verifyEncryptionRequestHmac(message, macaddr, apMacArray, _ongoingPeerRequester->getEspnowHashKey(), hashKeyLength))
{ {
_ongoingPeerRequestEncryptionTimeout.reset(); _ongoingPeerRequestEncryptionTimeout.reset();
@ -749,7 +756,7 @@ void EspnowMeshBackend::handlePeerRequestConfirmation(uint8_t *macaddr, uint8_t
} }
else if(messageHeader == FPSTR(maxConnectionsReachedHeader)) else if(messageHeader == FPSTR(maxConnectionsReachedHeader))
{ {
if(JsonTranslator::verifyEncryptionRequestHmac(message, macaddr, apMacArray, _ongoingPeerRequester->getEspnowHashKey(), espnowHashKeyLength)) if(JsonTranslator::verifyEncryptionRequestHmac(message, macaddr, apMacArray, _ongoingPeerRequester->getEspnowHashKey(), hashKeyLength))
{ {
_ongoingPeerRequestResult = EncryptedConnectionStatus::MAX_CONNECTIONS_REACHED_PEER; _ongoingPeerRequestResult = EncryptedConnectionStatus::MAX_CONNECTIONS_REACHED_PEER;
_ongoingPeerRequestNonce.clear(); _ongoingPeerRequestNonce.clear();
@ -789,19 +796,19 @@ void EspnowMeshBackend::espnowReceiveCallback(const uint8_t *macaddr, uint8_t *d
*/ */
////// </Method overview> ////// ////// </Method overview> //////
char messageType = espnowGetMessageType(dataArray); char messageType = getMessageType(dataArray);
uint8_t transmissionsRemaining = espnowGetTransmissionsRemaining(dataArray); uint8_t transmissionsRemaining = getTransmissionsRemaining(dataArray);
uint64_t uint64Mac = TypeCast::macToUint64(macaddr); uint64_t uint64Mac = TypeCast::macToUint64(macaddr);
// The MAC is 6 bytes so two bytes of uint64Mac are free. We must include the messageType there since it is possible that we will // The MAC is 6 bytes so two bytes of uint64Mac are free. We must include the messageType there since it is possible that we will
// receive both a request and a response that shares the same messageID from the same uint64Mac, being distinguished only by the messageType. // receive both a request and a response that shares the same messageID from the same uint64Mac, being distinguished only by the messageType.
// This would otherwise potentially cause the request and response to be mixed into one message when they are multi-part transmissions sent roughly at the same time. // This would otherwise potentially cause the request and response to be mixed into one message when they are multi-part transmissions sent roughly at the same time.
macAndType_td macAndType = createMacAndTypeValue(uint64Mac, messageType); macAndType_td macAndType = createMacAndTypeValue(uint64Mac, messageType);
uint64_t messageID = espnowGetMessageID(dataArray); uint64_t messageID = getMessageID(dataArray);
//uint32_t methodStart = millis(); //uint32_t methodStart = millis();
if(espnowIsMessageStart(dataArray)) if(isMessageStart(dataArray))
{ {
if(messageType == 'B') if(messageType == 'B')
{ {
@ -809,15 +816,15 @@ void EspnowMeshBackend::espnowReceiveCallback(const uint8_t *macaddr, uint8_t *d
if(receivedEspnowTransmissions.find(key) != receivedEspnowTransmissions.end()) if(receivedEspnowTransmissions.find(key) != receivedEspnowTransmissions.end())
return; // Should not call BroadcastFilter more than once for an accepted message return; // Should not call BroadcastFilter more than once for an accepted message
String message = espnowGetMessageContent(dataArray, len); String message = getHashKeyLength(dataArray, len);
setSenderMac(macaddr); setSenderMac(macaddr);
espnowGetTransmissionMac(dataArray, _senderAPMac); getTransmissionMac(dataArray, _senderAPMac);
setReceivedEncryptedTransmission(usesEncryption(messageID)); setReceivedEncryptedTransmission(usesEncryption(messageID));
bool acceptBroadcast = getBroadcastFilter()(message, *this); bool acceptBroadcast = getBroadcastFilter()(message, *this);
if(acceptBroadcast) if(acceptBroadcast)
{ {
// Does nothing if key already in receivedEspnowTransmissions // Does nothing if key already in receivedEspnowTransmissions
receivedEspnowTransmissions.insert(std::make_pair(key, MessageData(message, espnowGetTransmissionsRemaining(dataArray)))); receivedEspnowTransmissions.insert(std::make_pair(key, MessageData(message, getTransmissionsRemaining(dataArray))));
} }
else else
{ {
@ -877,7 +884,7 @@ void EspnowMeshBackend::espnowReceiveCallback(const uint8_t *macaddr, uint8_t *d
//Serial.println("methodStart request stored " + String(millis() - methodStart)); //Serial.println("methodStart request stored " + String(millis() - methodStart));
setSenderMac(macaddr); setSenderMac(macaddr);
espnowGetTransmissionMac(dataArray, _senderAPMac); getTransmissionMac(dataArray, _senderAPMac);
setReceivedEncryptedTransmission(usesEncryption(messageID)); setReceivedEncryptedTransmission(usesEncryption(messageID));
String response = getRequestHandler()(totalMessage, *this); String response = getRequestHandler()(totalMessage, *this);
//Serial.println("methodStart response acquired " + String(millis() - methodStart)); //Serial.println("methodStart response acquired " + String(millis() - methodStart));
@ -903,7 +910,7 @@ void EspnowMeshBackend::espnowReceiveCallback(const uint8_t *macaddr, uint8_t *d
} }
setSenderMac(macaddr); setSenderMac(macaddr);
espnowGetTransmissionMac(dataArray, _senderAPMac); getTransmissionMac(dataArray, _senderAPMac);
setReceivedEncryptedTransmission(usesEncryption(messageID)); setReceivedEncryptedTransmission(usesEncryption(messageID));
getResponseHandler()(totalMessage, *this); getResponseHandler()(totalMessage, *this);
} }
@ -1138,7 +1145,7 @@ TransmissionStatusType EspnowMeshBackend::espnowSendToNodeUnsynchronized(const S
uint8_t transmissionSize = 0; uint8_t transmissionSize = 0;
bool messageStart = true; bool messageStart = true;
uint8_t metadataSize = espnowMetadataSize(); uint8_t espnowMetadataSize = metadataSize();
do do
{ {
@ -1161,7 +1168,7 @@ TransmissionStatusType EspnowMeshBackend::espnowSendToNodeUnsynchronized(const S
} }
else else
{ {
transmissionSize = metadataSize; transmissionSize = espnowMetadataSize;
if(message.length() > 0) if(message.length() > 0)
{ {
@ -1174,35 +1181,35 @@ TransmissionStatusType EspnowMeshBackend::espnowSendToNodeUnsynchronized(const S
////// Fill protocol bytes ////// ////// Fill protocol bytes //////
transmission[espnowMessageTypeIndex] = messageType; transmission[messageTypeIndex] = messageType;
if(messageStart) if(messageStart)
{ {
transmission[espnowTransmissionsRemainingIndex] = (char)(transmissionsRemaining | 0x80); transmission[transmissionsRemainingIndex] = (char)(transmissionsRemaining | 0x80);
} }
else else
{ {
transmission[espnowTransmissionsRemainingIndex] = (char)transmissionsRemaining; transmission[transmissionsRemainingIndex] = (char)transmissionsRemaining;
} }
// Fills indicies in range [espnowTransmissionMacIndex, espnowTransmissionMacIndex + 5] (6 bytes) with the MAC address of the WiFi AP interface. // Fills indicies in range [transmissionMacIndex, transmissionMacIndex + 5] (6 bytes) with the MAC address of the WiFi AP interface.
// We always transmit from the station interface (due to using ESP_NOW_ROLE_CONTROLLER), so this makes it possible to always know both interface MAC addresses of a node that sends a transmission. // We always transmit from the station interface (due to using ESP_NOW_ROLE_CONTROLLER), so this makes it possible to always know both interface MAC addresses of a node that sends a transmission.
WiFi.softAPmacAddress(transmission + espnowTransmissionMacIndex); WiFi.softAPmacAddress(transmission + transmissionMacIndex);
espnowSetMessageID(transmission, messageID); setMessageID(transmission, messageID);
////// Fill message bytes ////// ////// Fill message bytes //////
int32_t transmissionStartIndex = (transmissionsRequired - transmissionsRemaining - 1) * getMaxMessageBytesPerTransmission(); int32_t transmissionStartIndex = (transmissionsRequired - transmissionsRemaining - 1) * getMaxMessageBytesPerTransmission();
std::copy_n(message.begin() + transmissionStartIndex, transmissionSize - metadataSize, transmission + metadataSize); std::copy_n(message.begin() + transmissionStartIndex, transmissionSize - espnowMetadataSize, transmission + espnowMetadataSize);
if(useEncryptedMessages()) if(useEncryptedMessages())
{ {
// chacha20Poly1305Encrypt encrypts transmission in place. // chacha20Poly1305Encrypt encrypts transmission in place.
// We are using the protocol bytes as a key salt. // We are using the protocol bytes as a key salt.
CryptoInterface::chacha20Poly1305Encrypt(transmission + metadataSize, transmissionSize - metadataSize, getEspnowMessageEncryptionKey(), transmission, CryptoInterface::chacha20Poly1305Encrypt(transmission + espnowMetadataSize, transmissionSize - espnowMetadataSize, getEspnowMessageEncryptionKey(), transmission,
espnowProtocolBytesSize, transmission + espnowProtocolBytesSize, transmission + espnowProtocolBytesSize + 12); protocolBytesSize, transmission + protocolBytesSize, transmission + protocolBytesSize + 12);
} }
////// Transmit ////// ////// Transmit //////
@ -1302,11 +1309,11 @@ uint64_t EspnowMeshBackend::macAndTypeToUint64Mac(const macAndType_td &macAndTyp
return static_cast<uint64_t>(macAndTypeValue) >> 8; return static_cast<uint64_t>(macAndTypeValue) >> 8;
} }
void EspnowMeshBackend::setEspnowEncryptedConnectionKey(const uint8_t espnowEncryptedConnectionKey[espnowEncryptedConnectionKeyLength]) void EspnowMeshBackend::setEspnowEncryptedConnectionKey(const uint8_t espnowEncryptedConnectionKey[encryptedConnectionKeyLength])
{ {
assert(espnowEncryptedConnectionKey != nullptr); assert(espnowEncryptedConnectionKey != nullptr);
for(int i = 0; i < espnowEncryptedConnectionKeyLength; ++i) for(int i = 0; i < encryptedConnectionKeyLength; ++i)
{ {
_espnowEncryptedConnectionKey[i] = espnowEncryptedConnectionKey[i]; _espnowEncryptedConnectionKey[i] = espnowEncryptedConnectionKey[i];
} }
@ -1314,7 +1321,7 @@ void EspnowMeshBackend::setEspnowEncryptedConnectionKey(const uint8_t espnowEncr
void EspnowMeshBackend::setEspnowEncryptedConnectionKey(const String &espnowEncryptedConnectionKeySeed) void EspnowMeshBackend::setEspnowEncryptedConnectionKey(const String &espnowEncryptedConnectionKeySeed)
{ {
MeshCryptoInterface::initializeKey(_espnowEncryptedConnectionKey, espnowEncryptedConnectionKeyLength, espnowEncryptedConnectionKeySeed); MeshCryptoInterface::initializeKey(_espnowEncryptedConnectionKey, encryptedConnectionKeyLength, espnowEncryptedConnectionKeySeed);
} }
const uint8_t *EspnowMeshBackend::getEspnowEncryptedConnectionKey() const const uint8_t *EspnowMeshBackend::getEspnowEncryptedConnectionKey() const
@ -1322,18 +1329,18 @@ const uint8_t *EspnowMeshBackend::getEspnowEncryptedConnectionKey() const
return _espnowEncryptedConnectionKey; return _espnowEncryptedConnectionKey;
} }
uint8_t *EspnowMeshBackend::getEspnowEncryptedConnectionKey(uint8_t resultArray[espnowEncryptedConnectionKeyLength]) const uint8_t *EspnowMeshBackend::getEspnowEncryptedConnectionKey(uint8_t resultArray[encryptedConnectionKeyLength]) const
{ {
std::copy_n(_espnowEncryptedConnectionKey, espnowEncryptedConnectionKeyLength, resultArray); std::copy_n(_espnowEncryptedConnectionKey, encryptedConnectionKeyLength, resultArray);
return resultArray; return resultArray;
} }
bool EspnowMeshBackend::setEspnowEncryptionKok(uint8_t espnowEncryptionKok[espnowEncryptedConnectionKeyLength]) bool EspnowMeshBackend::setEspnowEncryptionKok(uint8_t espnowEncryptionKok[encryptedConnectionKeyLength])
{ {
if(espnowEncryptionKok == nullptr || esp_now_set_kok(espnowEncryptionKok, espnowEncryptedConnectionKeyLength)) // esp_now_set_kok failed if not == 0 if(espnowEncryptionKok == nullptr || esp_now_set_kok(espnowEncryptionKok, encryptedConnectionKeyLength)) // esp_now_set_kok failed if not == 0
return false; return false;
for(int i = 0; i < espnowEncryptedConnectionKeyLength; ++i) for(int i = 0; i < encryptedConnectionKeyLength; ++i)
{ {
_espnowEncryptionKok[i] = espnowEncryptionKok[i]; _espnowEncryptionKok[i] = espnowEncryptionKok[i];
} }
@ -1345,8 +1352,8 @@ bool EspnowMeshBackend::setEspnowEncryptionKok(uint8_t espnowEncryptionKok[espno
bool EspnowMeshBackend::setEspnowEncryptionKok(const String &espnowEncryptionKokSeed) bool EspnowMeshBackend::setEspnowEncryptionKok(const String &espnowEncryptionKokSeed)
{ {
uint8_t espnowEncryptionKok[espnowEncryptedConnectionKeyLength] {}; uint8_t espnowEncryptionKok[encryptedConnectionKeyLength] {};
MeshCryptoInterface::initializeKey(espnowEncryptionKok, espnowEncryptedConnectionKeyLength, espnowEncryptionKokSeed); MeshCryptoInterface::initializeKey(espnowEncryptionKok, encryptedConnectionKeyLength, espnowEncryptionKokSeed);
return setEspnowEncryptionKok(espnowEncryptionKok); return setEspnowEncryptionKok(espnowEncryptionKok);
} }
@ -1359,11 +1366,11 @@ const uint8_t *EspnowMeshBackend::getEspnowEncryptionKok()
return nullptr; return nullptr;
} }
void EspnowMeshBackend::setEspnowHashKey(const uint8_t espnowHashKey[espnowHashKeyLength]) void EspnowMeshBackend::setEspnowHashKey(const uint8_t espnowHashKey[hashKeyLength])
{ {
assert(espnowHashKey != nullptr); assert(espnowHashKey != nullptr);
for(int i = 0; i < espnowHashKeyLength; ++i) for(int i = 0; i < hashKeyLength; ++i)
{ {
_espnowHashKey[i] = espnowHashKey[i]; _espnowHashKey[i] = espnowHashKey[i];
} }
@ -1371,7 +1378,7 @@ void EspnowMeshBackend::setEspnowHashKey(const uint8_t espnowHashKey[espnowHashK
void EspnowMeshBackend::setEspnowHashKey(const String &espnowHashKeySeed) void EspnowMeshBackend::setEspnowHashKey(const String &espnowHashKeySeed)
{ {
MeshCryptoInterface::initializeKey(_espnowHashKey, espnowHashKeyLength, espnowHashKeySeed); MeshCryptoInterface::initializeKey(_espnowHashKey, hashKeyLength, espnowHashKeySeed);
} }
const uint8_t *EspnowMeshBackend::getEspnowHashKey() const const uint8_t *EspnowMeshBackend::getEspnowHashKey() const
@ -1453,8 +1460,8 @@ bool EspnowMeshBackend::synchronizePeerSessionKey(const uint64_t sessionKey, Enc
{ {
if(sessionKey == encryptedConnection.getPeerSessionKey()) if(sessionKey == encryptedConnection.getPeerSessionKey())
{ {
uint8_t hashKey[espnowHashKeyLength] {0}; uint8_t hashKey[hashKeyLength] {0};
encryptedConnection.setPeerSessionKey(EncryptedConnectionLog::incrementSessionKey(sessionKey, encryptedConnection.getHashKey(hashKey), espnowHashKeyLength)); encryptedConnection.setPeerSessionKey(EncryptedConnectionLog::incrementSessionKey(sessionKey, encryptedConnection.getHashKey(hashKey), hashKeyLength));
return true; return true;
} }
} }
@ -1558,7 +1565,7 @@ EncryptedConnectionStatus EspnowMeshBackend::addEncryptedConnection(uint8_t *pee
{ {
assert(encryptedConnections.size() <= maxEncryptedConnections); // If this is not the case, ESP-NOW is no longer in sync with the library assert(encryptedConnections.size() <= maxEncryptedConnections); // If this is not the case, ESP-NOW is no longer in sync with the library
uint8_t encryptionKeyArray[espnowEncryptedConnectionKeyLength] = { 0 }; uint8_t encryptionKeyArray[encryptedConnectionKeyLength] = { 0 };
if(EncryptedConnectionLog *encryptedConnection = getEncryptedConnection(peerStaMac)) if(EncryptedConnectionLog *encryptedConnection = getEncryptedConnection(peerStaMac))
{ {
@ -1566,7 +1573,7 @@ EncryptedConnectionStatus EspnowMeshBackend::addEncryptedConnection(uint8_t *pee
temporaryEncryptedConnectionToPermanent(peerStaMac); temporaryEncryptedConnectionToPermanent(peerStaMac);
encryptedConnection->setPeerSessionKey(peerSessionKey); encryptedConnection->setPeerSessionKey(peerSessionKey);
encryptedConnection->setOwnSessionKey(ownSessionKey); encryptedConnection->setOwnSessionKey(ownSessionKey);
esp_now_set_peer_key(peerStaMac, getEspnowEncryptedConnectionKey(encryptionKeyArray), espnowEncryptedConnectionKeyLength); esp_now_set_peer_key(peerStaMac, getEspnowEncryptedConnectionKey(encryptionKeyArray), encryptedConnectionKeyLength);
encryptedConnection->setHashKey(getEspnowHashKey()); encryptedConnection->setHashKey(getEspnowHashKey());
return EncryptedConnectionStatus::CONNECTION_ESTABLISHED; return EncryptedConnectionStatus::CONNECTION_ESTABLISHED;
@ -1579,7 +1586,7 @@ EncryptedConnectionStatus EspnowMeshBackend::addEncryptedConnection(uint8_t *pee
} }
// returns 0 on success: int esp_now_add_peer(u8 *mac_addr, u8 role, u8 channel, u8 *key, u8 key_len) // returns 0 on success: int esp_now_add_peer(u8 *mac_addr, u8 role, u8 channel, u8 *key, u8 key_len)
// Only MAC, encryption key and key length (16) actually matter. The rest is not used by ESP-NOW. // Only MAC, encryption key and key length (16) actually matter. The rest is not used by ESP-NOW.
else if(0 == esp_now_add_peer(peerStaMac, ESP_NOW_ROLE_CONTROLLER, getWiFiChannel(), getEspnowEncryptedConnectionKey(encryptionKeyArray), espnowEncryptedConnectionKeyLength)) else if(0 == esp_now_add_peer(peerStaMac, ESP_NOW_ROLE_CONTROLLER, getWiFiChannel(), getEspnowEncryptedConnectionKey(encryptionKeyArray), encryptedConnectionKeyLength))
{ {
encryptedConnections.emplace_back(peerStaMac, peerApMac, peerSessionKey, ownSessionKey, getEspnowHashKey()); encryptedConnections.emplace_back(peerStaMac, peerApMac, peerSessionKey, ownSessionKey, getEspnowHashKey());
return EncryptedConnectionStatus::CONNECTION_ESTABLISHED; return EncryptedConnectionStatus::CONNECTION_ESTABLISHED;
@ -1630,7 +1637,7 @@ EncryptedConnectionStatus EspnowMeshBackend::addTemporaryEncryptedConnection(uin
{ {
assert(encryptedConnections.size() <= maxEncryptedConnections); // If this is not the case, ESP-NOW is no longer in sync with the library assert(encryptedConnections.size() <= maxEncryptedConnections); // If this is not the case, ESP-NOW is no longer in sync with the library
uint8_t encryptionKeyArray[espnowEncryptedConnectionKeyLength] = { 0 }; uint8_t encryptionKeyArray[encryptedConnectionKeyLength] = { 0 };
connectionLogIterator encryptedConnection = connectionLogEndIterator(); connectionLogIterator encryptedConnection = connectionLogEndIterator();
@ -1639,7 +1646,7 @@ EncryptedConnectionStatus EspnowMeshBackend::addTemporaryEncryptedConnection(uin
// There is already an encrypted connection to this mac, so no need to replace it, just updating is enough. // There is already an encrypted connection to this mac, so no need to replace it, just updating is enough.
encryptedConnection->setPeerSessionKey(peerSessionKey); encryptedConnection->setPeerSessionKey(peerSessionKey);
encryptedConnection->setOwnSessionKey(ownSessionKey); encryptedConnection->setOwnSessionKey(ownSessionKey);
esp_now_set_peer_key(peerStaMac, getEspnowEncryptedConnectionKey(encryptionKeyArray), espnowEncryptedConnectionKeyLength); esp_now_set_peer_key(peerStaMac, getEspnowEncryptedConnectionKey(encryptionKeyArray), encryptedConnectionKeyLength);
encryptedConnection->setHashKey(getEspnowHashKey()); encryptedConnection->setHashKey(getEspnowHashKey());
if(encryptedConnection->temporary()) if(encryptedConnection->temporary())
@ -1767,7 +1774,7 @@ EncryptedConnectionStatus EspnowMeshBackend::requestEncryptedConnectionKernel(co
else if(_ongoingPeerRequestResult == EncryptedConnectionStatus::SOFT_LIMIT_CONNECTION_ESTABLISHED) else if(_ongoingPeerRequestResult == EncryptedConnectionStatus::SOFT_LIMIT_CONNECTION_ESTABLISHED)
// We will only get a soft limit connection. Adjust future actions based on this. // We will only get a soft limit connection. Adjust future actions based on this.
requestMessage = JsonTranslator::createEncryptionRequestHmacMessage(FPSTR(temporaryEncryptionRequestHeader), requestNonce, getEspnowHashKey(), requestMessage = JsonTranslator::createEncryptionRequestHmacMessage(FPSTR(temporaryEncryptionRequestHeader), requestNonce, getEspnowHashKey(),
espnowHashKeyLength, getAutoEncryptionDuration()); hashKeyLength, getAutoEncryptionDuration());
else else
assert(false && String(F("Unknown _ongoingPeerRequestResult during encrypted connection finalization!"))); assert(false && String(F("Unknown _ongoingPeerRequestResult during encrypted connection finalization!")));
@ -1841,7 +1848,7 @@ String EspnowMeshBackend::defaultEncryptionRequestBuilder(const String &requestH
{ {
(void)existingTimeTracker; // This removes a "unused parameter" compiler warning. Does nothing else. (void)existingTimeTracker; // This removes a "unused parameter" compiler warning. Does nothing else.
return JsonTranslator::createEncryptionRequestHmacMessage(requestHeader, requestNonce, hashKey, espnowHashKeyLength, durationMs); return JsonTranslator::createEncryptionRequestHmacMessage(requestHeader, requestNonce, hashKey, hashKeyLength, durationMs);
} }
String EspnowMeshBackend::flexibleEncryptionRequestBuilder(const uint32_t minDurationMs, const uint8_t *hashKey, String EspnowMeshBackend::flexibleEncryptionRequestBuilder(const uint32_t minDurationMs, const uint8_t *hashKey,
@ -1853,7 +1860,7 @@ String EspnowMeshBackend::flexibleEncryptionRequestBuilder(const uint32_t minDur
uint32_t connectionDuration = minDurationMs >= existingTimeTracker.remainingDuration() ? uint32_t connectionDuration = minDurationMs >= existingTimeTracker.remainingDuration() ?
minDurationMs : existingTimeTracker.remainingDuration(); minDurationMs : existingTimeTracker.remainingDuration();
return createEncryptionRequestHmacMessage(FPSTR(temporaryEncryptionRequestHeader), requestNonce, hashKey, espnowHashKeyLength, connectionDuration); return createEncryptionRequestHmacMessage(FPSTR(temporaryEncryptionRequestHeader), requestNonce, hashKey, hashKeyLength, connectionDuration);
} }
EncryptedConnectionStatus EspnowMeshBackend::requestEncryptedConnection(const uint8_t *peerMac) EncryptedConnectionStatus EspnowMeshBackend::requestEncryptedConnection(const uint8_t *peerMac)
@ -2414,7 +2421,7 @@ void EspnowMeshBackend::sendPeerRequestConfirmations(const ExpiringTimeTracker *
confirmationsIterator->getEncryptedPeerMac(defaultBSSID); confirmationsIterator->getEncryptedPeerMac(defaultBSSID);
uint8_t unencryptedBSSID[6] {0}; uint8_t unencryptedBSSID[6] {0};
confirmationsIterator->getUnencryptedPeerMac(unencryptedBSSID); confirmationsIterator->getUnencryptedPeerMac(unencryptedBSSID);
uint8_t hashKey[espnowHashKeyLength] {0}; uint8_t hashKey[hashKeyLength] {0};
confirmationsIterator->getHashKey(hashKey); confirmationsIterator->getHashKey(hashKey);
EncryptedConnectionLog *existingEncryptedConnection = getEncryptedConnection(defaultBSSID); EncryptedConnectionLog *existingEncryptedConnection = getEncryptedConnection(defaultBSSID);
@ -2431,13 +2438,13 @@ void EspnowMeshBackend::sendPeerRequestConfirmations(const ExpiringTimeTracker *
((reciprocalPeerRequest && encryptedConnections.size() >= maxEncryptedConnections) || (!reciprocalPeerRequest && reservedEncryptedConnections() >= maxEncryptedConnections))) ((reciprocalPeerRequest && encryptedConnections.size() >= maxEncryptedConnections) || (!reciprocalPeerRequest && reservedEncryptedConnections() >= maxEncryptedConnections)))
{ {
espnowSendToNodeUnsynchronized(JsonTranslator::createEncryptionRequestHmacMessage(FPSTR(maxConnectionsReachedHeader), espnowSendToNodeUnsynchronized(JsonTranslator::createEncryptionRequestHmacMessage(FPSTR(maxConnectionsReachedHeader),
confirmationsIterator->getPeerRequestNonce(), hashKey, espnowHashKeyLength), confirmationsIterator->getPeerRequestNonce(), hashKey, hashKeyLength),
defaultBSSID, 'C', generateMessageID(nullptr)); // Generates a new message ID to avoid sending encrypted sessionKeys over unencrypted connections. defaultBSSID, 'C', generateMessageID(nullptr)); // Generates a new message ID to avoid sending encrypted sessionKeys over unencrypted connections.
confirmationsIterator = peerRequestConfirmationsToSend.erase(confirmationsIterator); confirmationsIterator = peerRequestConfirmationsToSend.erase(confirmationsIterator);
} }
else if(espnowSendToNodeUnsynchronized(JsonTranslator::createEncryptionRequestHmacMessage(FPSTR(basicConnectionInfoHeader), else if(espnowSendToNodeUnsynchronized(JsonTranslator::createEncryptionRequestHmacMessage(FPSTR(basicConnectionInfoHeader),
confirmationsIterator->getPeerRequestNonce(), hashKey, espnowHashKeyLength), confirmationsIterator->getPeerRequestNonce(), hashKey, hashKeyLength),
sendToDefaultBSSID ? defaultBSSID : unencryptedBSSID, 'C', generateMessageID(nullptr)) // Generates a new message ID to avoid sending encrypted sessionKeys over unencrypted connections. sendToDefaultBSSID ? defaultBSSID : unencryptedBSSID, 'C', generateMessageID(nullptr)) // Generates a new message ID to avoid sending encrypted sessionKeys over unencrypted connections.
== TransmissionStatusType::TRANSMISSION_COMPLETE) == TransmissionStatusType::TRANSMISSION_COMPLETE)
{ {
@ -2469,7 +2476,7 @@ void EspnowMeshBackend::sendPeerRequestConfirmations(const ExpiringTimeTracker *
{ {
// Send "node full" message // Send "node full" message
espnowSendToNodeUnsynchronized(JsonTranslator::createEncryptionRequestHmacMessage(FPSTR(maxConnectionsReachedHeader), espnowSendToNodeUnsynchronized(JsonTranslator::createEncryptionRequestHmacMessage(FPSTR(maxConnectionsReachedHeader),
confirmationsIterator->getPeerRequestNonce(), hashKey, espnowHashKeyLength), confirmationsIterator->getPeerRequestNonce(), hashKey, hashKeyLength),
defaultBSSID, 'C', generateMessageID(nullptr)); // Generates a new message ID to avoid sending encrypted sessionKeys over unencrypted connections. defaultBSSID, 'C', generateMessageID(nullptr)); // Generates a new message ID to avoid sending encrypted sessionKeys over unencrypted connections.
} }
else else
@ -2584,7 +2591,7 @@ uint32_t EspnowMeshBackend::getMaxBytesPerTransmission()
uint32_t EspnowMeshBackend::getMaxMessageBytesPerTransmission() uint32_t EspnowMeshBackend::getMaxMessageBytesPerTransmission()
{ {
using namespace EspnowProtocolInterpreter; using namespace EspnowProtocolInterpreter;
return getMaxBytesPerTransmission() - espnowMetadataSize(); return getMaxBytesPerTransmission() - metadataSize();
} }
void EspnowMeshBackend::setMaxTransmissionsPerMessage(const uint8_t maxTransmissionsPerMessage) void EspnowMeshBackend::setMaxTransmissionsPerMessage(const uint8_t maxTransmissionsPerMessage)

View File

@ -167,8 +167,8 @@ public:
* *
*/ */
EspnowMeshBackend(const requestHandlerType requestHandler, const responseHandlerType responseHandler, const networkFilterType networkFilter, const broadcastFilterType broadcastFilter, EspnowMeshBackend(const requestHandlerType requestHandler, const responseHandlerType responseHandler, const networkFilterType networkFilter, const broadcastFilterType broadcastFilter,
const String &meshPassword, const uint8_t espnowEncryptedConnectionKey[EspnowProtocolInterpreter::espnowEncryptedConnectionKeyLength], const String &meshPassword, const uint8_t espnowEncryptedConnectionKey[EspnowProtocolInterpreter::encryptedConnectionKeyLength],
const uint8_t espnowHashKey[EspnowProtocolInterpreter::espnowHashKeyLength], const String &ssidPrefix, const uint8_t espnowHashKey[EspnowProtocolInterpreter::hashKeyLength], const String &ssidPrefix,
const String &ssidSuffix, const bool verboseMode = false, const uint8 meshWiFiChannel = 1); const String &ssidSuffix, const bool verboseMode = false, const uint8 meshWiFiChannel = 1);
/** /**
@ -396,9 +396,9 @@ public:
* Both Kok and encrypted connection key must match in an encrypted connection pair for encrypted communication to be possible. * Both Kok and encrypted connection key must match in an encrypted connection pair for encrypted communication to be possible.
* Otherwise the transmissions will never reach the recipient, even though acks are received by the sender. * Otherwise the transmissions will never reach the recipient, even though acks are received by the sender.
* *
* @param espnowEncryptedConnectionKey An array containing the espnowEncryptedConnectionKeyLength bytes that will be used as the encryption key. * @param espnowEncryptedConnectionKey An array containing the encryptedConnectionKeyLength bytes that will be used as the encryption key.
*/ */
void setEspnowEncryptedConnectionKey(const uint8_t espnowEncryptedConnectionKey[EspnowProtocolInterpreter::espnowEncryptedConnectionKeyLength]); void setEspnowEncryptedConnectionKey(const uint8_t espnowEncryptedConnectionKey[EspnowProtocolInterpreter::encryptedConnectionKeyLength]);
/** /**
* Change the key used by this EspnowMeshBackend instance for creating encrypted ESP-NOW connections. * Change the key used by this EspnowMeshBackend instance for creating encrypted ESP-NOW connections.
@ -421,7 +421,7 @@ public:
* @return The current espnowEncryptedConnectionKey for this EspnowMeshBackend instance. * @return The current espnowEncryptedConnectionKey for this EspnowMeshBackend instance.
*/ */
const uint8_t *getEspnowEncryptedConnectionKey() const; const uint8_t *getEspnowEncryptedConnectionKey() const;
uint8_t *getEspnowEncryptedConnectionKey(uint8_t resultArray[EspnowProtocolInterpreter::espnowEncryptedConnectionKeyLength]) const; uint8_t *getEspnowEncryptedConnectionKey(uint8_t resultArray[EspnowProtocolInterpreter::encryptedConnectionKeyLength]) const;
/** /**
* Change the key used to encrypt/decrypt the encrypted connection key when creating encrypted ESP-NOW connections. (Kok = key of keys, perhaps) If no Kok is provided by the user, a default Kok is used. * Change the key used to encrypt/decrypt the encrypted connection key when creating encrypted ESP-NOW connections. (Kok = key of keys, perhaps) If no Kok is provided by the user, a default Kok is used.
@ -433,10 +433,10 @@ public:
* Both Kok and encrypted connection key must match in an encrypted connection pair for encrypted communication to be possible. * Both Kok and encrypted connection key must match in an encrypted connection pair for encrypted communication to be possible.
* Otherwise the transmissions will never reach the recipient, even though acks are received by the sender. * Otherwise the transmissions will never reach the recipient, even though acks are received by the sender.
* *
* @param espnowEncryptionKok An array containing the espnowEncryptedConnectionKeyLength bytes that will be used as the Kok. * @param espnowEncryptionKok An array containing the encryptedConnectionKeyLength bytes that will be used as the Kok.
* @return True if Kok was changed successfully. False if Kok was not changed. * @return True if Kok was changed successfully. False if Kok was not changed.
*/ */
static bool setEspnowEncryptionKok(uint8_t espnowEncryptionKok[EspnowProtocolInterpreter::espnowEncryptedConnectionKeyLength]); static bool setEspnowEncryptionKok(uint8_t espnowEncryptionKok[EspnowProtocolInterpreter::encryptedConnectionKeyLength]);
/** /**
* Change the key used to encrypt/decrypt the encryption key when creating encrypted ESP-NOW connections. (Kok = key of keys, perhaps) If no Kok is provided by the user, a default Kok is used. * Change the key used to encrypt/decrypt the encryption key when creating encrypted ESP-NOW connections. (Kok = key of keys, perhaps) If no Kok is provided by the user, a default Kok is used.
@ -469,9 +469,9 @@ public:
* NOTE: Encrypted connections added before the key change will retain their old key. * NOTE: Encrypted connections added before the key change will retain their old key.
* Only changes the secret hash key used by this EspnowMeshBackend instance, so each instance can use a separate secret key. * Only changes the secret hash key used by this EspnowMeshBackend instance, so each instance can use a separate secret key.
* *
* @param espnowHashKey An array containing the espnowHashKeyLength bytes that will be used as the HMAC key. * @param espnowHashKey An array containing the hashKeyLength bytes that will be used as the HMAC key.
*/ */
void setEspnowHashKey(const uint8_t espnowHashKey[EspnowProtocolInterpreter::espnowHashKeyLength]); void setEspnowHashKey(const uint8_t espnowHashKey[EspnowProtocolInterpreter::hashKeyLength]);
/** /**
* Change the secret key used to generate HMACs for encrypted ESP-NOW connections. * Change the secret key used to generate HMACs for encrypted ESP-NOW connections.
@ -970,7 +970,7 @@ protected:
static connectionLogIterator connectionLogEndIterator(); static connectionLogIterator connectionLogEndIterator();
static const uint8_t broadcastMac[6]; static const uint8_t broadcastMac[6];
static const uint64_t uint64BroadcastMac = 0xFFFFFFFFFFFF; static const uint64_t uint64BroadcastMac;
bool activateEspnow(); bool activateEspnow();
@ -1129,20 +1129,10 @@ private:
static bool synchronizePeerSessionKey(const uint64_t sessionKey, const uint8_t *peerMac); static bool synchronizePeerSessionKey(const uint64_t sessionKey, const uint8_t *peerMac);
static bool synchronizePeerSessionKey(const uint64_t sessionKey, EncryptedConnectionLog &encryptedConnection); static bool synchronizePeerSessionKey(const uint64_t sessionKey, EncryptedConnectionLog &encryptedConnection);
static const uint32_t _maxBytesPerTransmission = 250;
static uint8_t _maxTransmissionsPerMessage;
static uint32_t _espnowTransmissionTimeoutMs;
static uint32_t _espnowRetransmissionIntervalMs;
uint32_t _autoEncryptionDuration = 50; uint32_t _autoEncryptionDuration = 50;
uint8_t _encryptedConnectionsSoftLimit = 6; uint8_t _encryptedConnectionsSoftLimit = 6;
static bool _staticVerboseMode;
static EspnowMeshBackend *_espnowRequestManager;
static std::map<std::pair<macAndType_td, messageID_td>, MessageData> receivedEspnowTransmissions; static std::map<std::pair<macAndType_td, messageID_td>, MessageData> receivedEspnowTransmissions;
static std::map<std::pair<peerMac_td, messageID_td>, RequestData> sentRequests; static std::map<std::pair<peerMac_td, messageID_td>, RequestData> sentRequests;
static std::map<std::pair<peerMac_td, messageID_td>, TimeTracker> receivedRequests; static std::map<std::pair<peerMac_td, messageID_td>, TimeTracker> receivedRequests;
@ -1155,11 +1145,6 @@ private:
*/ */
static uint8_t reservedEncryptedConnections(); static uint8_t reservedEncryptedConnections();
static std::list<ResponseData> responsesToSend;
static std::list<PeerRequestLog> peerRequestConfirmationsToSend;
static std::vector<EncryptedConnectionLog> encryptedConnections;
static EncryptedConnectionLog *getEncryptedConnection(const uint8_t *peerMac); static EncryptedConnectionLog *getEncryptedConnection(const uint8_t *peerMac);
static EncryptedConnectionLog *getTemporaryEncryptedConnection(const uint8_t *peerMac); static EncryptedConnectionLog *getTemporaryEncryptedConnection(const uint8_t *peerMac);
@ -1188,27 +1173,11 @@ private:
template <typename T> template <typename T>
static void deleteExpiredLogEntries(std::list<T> &logEntries, const uint32_t maxEntryLifetimeMs); static void deleteExpiredLogEntries(std::list<T> &logEntries, const uint32_t maxEntryLifetimeMs);
static uint32_t _logEntryLifetimeMs;
static uint32_t _broadcastResponseTimeoutMs;
static uint32_t _encryptionRequestTimeoutMs;
static uint32_t _criticalHeapLevel;
static uint32_t _criticalHeapLevelBuffer;
static bool _espnowSendConfirmed;
broadcastFilterType _broadcastFilter; broadcastFilterType _broadcastFilter;
responseTransmittedHookType _responseTransmittedHook = [](const String &, const uint8_t *, uint32_t, EspnowMeshBackend &){ return true; }; responseTransmittedHookType _responseTransmittedHook = [](const String &, const uint8_t *, uint32_t, EspnowMeshBackend &){ return true; };
uint8_t _broadcastTransmissionRedundancy = 1; uint8_t _broadcastTransmissionRedundancy = 1;
static String _ongoingPeerRequestNonce;
static uint8_t _ongoingPeerRequestMac[6];
static EspnowMeshBackend *_ongoingPeerRequester;
static EncryptedConnectionStatus _ongoingPeerRequestResult;
static bool _reciprocalPeerRequestConfirmation;
template <typename T> template <typename T>
static T *getMapValue(std::map<uint64_t, T> &mapIn, const uint64_t keyIn); static T *getMapValue(std::map<uint64_t, T> &mapIn, const uint64_t keyIn);
@ -1216,21 +1185,13 @@ private:
bool _acceptsUnverifiedRequests = true; bool _acceptsUnverifiedRequests = true;
uint8_t _espnowEncryptedConnectionKey[EspnowProtocolInterpreter::espnowEncryptedConnectionKeyLength] {0}; uint8_t _espnowEncryptedConnectionKey[EspnowProtocolInterpreter::encryptedConnectionKeyLength] {0};
uint8_t _espnowHashKey[EspnowProtocolInterpreter::espnowHashKeyLength] {0}; uint8_t _espnowHashKey[EspnowProtocolInterpreter::hashKeyLength] {0};
static uint8_t _espnowEncryptionKok[EspnowProtocolInterpreter::espnowEncryptedConnectionKeyLength];
static bool _espnowEncryptionKokSet;
static uint8_t _espnowMessageEncryptionKey[CryptoInterface::ENCRYPTION_KEY_LENGTH];
static bool _useEncryptedMessages;
static uint32_t _unsynchronizedMessageID;
uint8_t _senderMac[6] = {0}; uint8_t _senderMac[6] = {0};
uint8_t _senderAPMac[6] = {0}; uint8_t _senderAPMac[6] = {0};
bool _receivedEncryptedTransmission = false; bool _receivedEncryptedTransmission = false;
static std::shared_ptr<bool> _espnowSendToNodeMutex;
static uint8_t _transmissionTargetBSSID[6];
static void storeSentRequest(const uint64_t targetBSSID, const uint64_t messageID, const RequestData &requestData); static void storeSentRequest(const uint64_t targetBSSID, const uint64_t messageID, const RequestData &requestData);
static void storeReceivedRequest(const uint64_t senderBSSID, const uint64_t messageID, const TimeTracker &timeTracker); static void storeReceivedRequest(const uint64_t senderBSSID, const uint64_t messageID, const TimeTracker &timeTracker);
@ -1292,8 +1253,7 @@ private:
uint32_t successfulTransmissions_AT = 0; uint32_t successfulTransmissions_AT = 0;
uint32_t maxTransmissionDuration_AT = 0; uint32_t maxTransmissionDuration_AT = 0;
static double _transmissionsTotal; static bool _staticVerboseMode;
static double _transmissionsFailed;
}; };
#endif #endif

View File

@ -27,63 +27,66 @@
#include <algorithm> #include <algorithm>
#include "EspnowMeshBackend.h" #include "EspnowMeshBackend.h"
namespace TypeCast = MeshTypeConversionFunctions; namespace
{
namespace TypeCast = MeshTypeConversionFunctions;
}
namespace EspnowProtocolInterpreter namespace EspnowProtocolInterpreter
{ {
uint8_t espnowMetadataSize() uint8_t metadataSize()
{ {
return espnowProtocolBytesSize + (EspnowMeshBackend::useEncryptedMessages() ? aeadMetadataSize : 0); return protocolBytesSize + (EspnowMeshBackend::useEncryptedMessages() ? aeadMetadataSize : 0);
} }
String espnowGetMessageContent(uint8_t *transmissionDataArray, const uint8_t transmissionLength) String getHashKeyLength(uint8_t *transmissionDataArray, const uint8_t transmissionLength)
{ {
String messageContent = emptyString; String messageContent = emptyString;
if(transmissionLength >= espnowMetadataSize()) if(transmissionLength >= metadataSize())
{ {
uint8_t messageSize = transmissionLength - espnowMetadataSize(); uint8_t messageSize = transmissionLength - metadataSize();
messageContent = TypeCast::uint8ArrayToMultiString(transmissionDataArray + espnowMetadataSize(), messageSize); messageContent = TypeCast::uint8ArrayToMultiString(transmissionDataArray + metadataSize(), messageSize);
} }
return messageContent; return messageContent;
} }
char espnowGetMessageType(const uint8_t *transmissionDataArray) char getMessageType(const uint8_t *transmissionDataArray)
{ {
return char(transmissionDataArray[espnowMessageTypeIndex]); return char(transmissionDataArray[messageTypeIndex]);
} }
uint8_t espnowGetTransmissionsRemaining(const uint8_t *transmissionDataArray) uint8_t getTransmissionsRemaining(const uint8_t *transmissionDataArray)
{ {
return (transmissionDataArray[espnowTransmissionsRemainingIndex] & 0x7F); return (transmissionDataArray[transmissionsRemainingIndex] & 0x7F);
} }
bool espnowIsMessageStart(const uint8_t *transmissionDataArray) bool isMessageStart(const uint8_t *transmissionDataArray)
{ {
return (transmissionDataArray[espnowTransmissionsRemainingIndex] & 0x80); // If MSB is one we have messageStart return (transmissionDataArray[transmissionsRemainingIndex] & 0x80); // If MSB is one we have messageStart
} }
uint64_t espnowGetTransmissionMac(const uint8_t *transmissionDataArray) uint64_t getTransmissionMac(const uint8_t *transmissionDataArray)
{ {
return TypeCast::macToUint64(transmissionDataArray + espnowTransmissionMacIndex); return TypeCast::macToUint64(transmissionDataArray + transmissionMacIndex);
} }
uint8_t *espnowGetTransmissionMac(const uint8_t *transmissionDataArray, uint8_t *resultArray) uint8_t *getTransmissionMac(const uint8_t *transmissionDataArray, uint8_t *resultArray)
{ {
std::copy_n((transmissionDataArray + espnowTransmissionMacIndex), 6, resultArray); std::copy_n((transmissionDataArray + transmissionMacIndex), 6, resultArray);
return resultArray; return resultArray;
} }
uint64_t espnowGetMessageID(const uint8_t *transmissionDataArray) uint64_t getMessageID(const uint8_t *transmissionDataArray)
{ {
return TypeCast::uint8ArrayToUint64(transmissionDataArray + espnowMessageIDIndex); return TypeCast::uint8ArrayToUint64(transmissionDataArray + messageIDIndex);
} }
uint8_t *espnowSetMessageID(uint8_t *transmissionDataArray, const uint64_t messageID) uint8_t *setMessageID(uint8_t *transmissionDataArray, const uint64_t messageID)
{ {
return TypeCast::uint64ToUint8Array(messageID, transmissionDataArray + espnowMessageIDIndex); return TypeCast::uint64ToUint8Array(messageID, transmissionDataArray + messageIDIndex);
} }
bool usesEncryption(const uint64_t messageID) bool usesEncryption(const uint64_t messageID)

View File

@ -49,29 +49,29 @@ namespace EspnowProtocolInterpreter
constexpr char encryptedConnectionVerificationHeader[] PROGMEM = "ECVerified:"; // Encrypted connection verified constexpr char encryptedConnectionVerificationHeader[] PROGMEM = "ECVerified:"; // Encrypted connection verified
constexpr char encryptedConnectionRemovalRequestHeader[] PROGMEM = "RemoveEC:"; // Remove encrypted connection constexpr char encryptedConnectionRemovalRequestHeader[] PROGMEM = "RemoveEC:"; // Remove encrypted connection
constexpr uint8_t espnowMessageTypeIndex = 0; constexpr uint8_t messageTypeIndex = 0;
constexpr uint8_t espnowTransmissionsRemainingIndex = 1; constexpr uint8_t transmissionsRemainingIndex = 1;
constexpr uint8_t espnowTransmissionMacIndex = 2; constexpr uint8_t transmissionMacIndex = 2;
constexpr uint8_t espnowMessageIDIndex = 8; constexpr uint8_t messageIDIndex = 8;
constexpr uint8_t espnowProtocolBytesSize = 16; constexpr uint8_t protocolBytesSize = 16;
constexpr uint8_t aeadMetadataSize = 28; constexpr uint8_t aeadMetadataSize = 28;
uint8_t espnowMetadataSize(); uint8_t metadataSize();
constexpr uint8_t espnowEncryptedConnectionKeyLength = 16; // This is restricted to exactly 16 bytes by the ESP-NOW API. It should not be changed unless the ESP-NOW API is changed. constexpr uint8_t encryptedConnectionKeyLength = 16; // This is restricted to exactly 16 bytes by the ESP-NOW API. It should not be changed unless the ESP-NOW API is changed.
constexpr uint8_t espnowHashKeyLength = 16; // This can be changed to any value up to 255. Common values are 16 and 32. constexpr uint8_t hashKeyLength = 16; // This can be changed to any value up to 255. Common values are 16 and 32.
constexpr uint64_t uint64LeftmostBits = 0xFFFFFFFF00000000; constexpr uint64_t uint64LeftmostBits = 0xFFFFFFFF00000000;
String espnowGetMessageContent(uint8_t *transmissionDataArray, const uint8_t transmissionLength); String getHashKeyLength(uint8_t *transmissionDataArray, const uint8_t transmissionLength);
char espnowGetMessageType(const uint8_t *transmissionDataArray); char getMessageType(const uint8_t *transmissionDataArray);
uint8_t espnowGetTransmissionsRemaining(const uint8_t *transmissionDataArray); uint8_t getTransmissionsRemaining(const uint8_t *transmissionDataArray);
bool espnowIsMessageStart(const uint8_t *transmissionDataArray); bool isMessageStart(const uint8_t *transmissionDataArray);
uint64_t espnowGetTransmissionMac(const uint8_t *transmissionDataArray); uint64_t getTransmissionMac(const uint8_t *transmissionDataArray);
uint8_t *espnowGetTransmissionMac(const uint8_t *transmissionDataArray, uint8_t *resultArray); uint8_t *getTransmissionMac(const uint8_t *transmissionDataArray, uint8_t *resultArray);
uint64_t espnowGetMessageID(const uint8_t *transmissionDataArray); uint64_t getMessageID(const uint8_t *transmissionDataArray);
// @return a pointer to transmissionDataArray // @return a pointer to transmissionDataArray
uint8_t *espnowSetMessageID(uint8_t *transmissionDataArray, const uint64_t messageID); uint8_t *setMessageID(uint8_t *transmissionDataArray, const uint64_t messageID);
bool usesEncryption(const uint64_t messageID); bool usesEncryption(const uint64_t messageID);
} }

View File

@ -26,18 +26,18 @@
#include "TypeConversionFunctions.h" #include "TypeConversionFunctions.h"
#include "JsonTranslator.h" #include "JsonTranslator.h"
namespace TypeCast = MeshTypeConversionFunctions;
namespace namespace
{ {
namespace TypeCast = MeshTypeConversionFunctions;
constexpr uint8_t MESSAGE_ID_LENGTH = 17; // 16 characters and one delimiter constexpr uint8_t MESSAGE_ID_LENGTH = 17; // 16 characters and one delimiter
constexpr uint8_t MESSAGE_COMPLETE = 255; constexpr uint8_t MESSAGE_COMPLETE = 255;
char _metadataDelimiter = 23; // Defaults to 23 = End-of-Transmission-Block (ETB) control character in ASCII
} }
std::set<FloodingMesh *> FloodingMesh::availableFloodingMeshes = {}; std::set<FloodingMesh *> FloodingMesh::availableFloodingMeshes = {};
char FloodingMesh::_metadataDelimiter = 23;
void floodingMeshDelay(const uint32_t durationMs) void floodingMeshDelay(const uint32_t durationMs)
{ {
ExpiringTimeTracker timeout(durationMs); ExpiringTimeTracker timeout(durationMs);
@ -52,8 +52,8 @@ void floodingMeshDelay(const uint32_t durationMs)
while(!timeout); while(!timeout);
} }
FloodingMesh::FloodingMesh(messageHandlerType messageHandler, const String &meshPassword, const uint8_t espnowEncryptedConnectionKey[EspnowProtocolInterpreter::espnowEncryptedConnectionKeyLength], FloodingMesh::FloodingMesh(messageHandlerType messageHandler, const String &meshPassword, const uint8_t espnowEncryptedConnectionKey[EspnowProtocolInterpreter::encryptedConnectionKeyLength],
const uint8_t espnowHashKey[EspnowProtocolInterpreter::espnowHashKeyLength], const String &ssidPrefix, const uint8_t espnowHashKey[EspnowProtocolInterpreter::hashKeyLength], const String &ssidPrefix,
const String &ssidSuffix, const bool verboseMode, const uint8 meshWiFiChannel) const String &ssidSuffix, const bool verboseMode, const uint8 meshWiFiChannel)
: _espnowBackend( : _espnowBackend(
[this](const String &request, MeshBackendBase &meshInstance){ return _defaultRequestHandler(request, meshInstance); }, [this](const String &request, MeshBackendBase &meshInstance){ return _defaultRequestHandler(request, meshInstance); },
@ -69,16 +69,16 @@ FloodingMesh::FloodingMesh(messageHandlerType messageHandler, const String &mesh
FloodingMesh::FloodingMesh(messageHandlerType messageHandler, const String &meshPassword, const String &espnowEncryptedConnectionKeySeed, const String &espnowHashKeySeed, FloodingMesh::FloodingMesh(messageHandlerType messageHandler, const String &meshPassword, const String &espnowEncryptedConnectionKeySeed, const String &espnowHashKeySeed,
const String &ssidPrefix, const String &ssidSuffix, const bool verboseMode, const uint8 meshWiFiChannel) const String &ssidPrefix, const String &ssidSuffix, const bool verboseMode, const uint8 meshWiFiChannel)
: FloodingMesh(messageHandler, meshPassword, (const uint8_t[EspnowProtocolInterpreter::espnowEncryptedConnectionKeyLength]){0}, : FloodingMesh(messageHandler, meshPassword, (const uint8_t[EspnowProtocolInterpreter::encryptedConnectionKeyLength]){0},
(const uint8_t[EspnowProtocolInterpreter::espnowHashKeyLength]){0}, ssidPrefix, ssidSuffix, verboseMode, meshWiFiChannel) (const uint8_t[EspnowProtocolInterpreter::hashKeyLength]){0}, ssidPrefix, ssidSuffix, verboseMode, meshWiFiChannel)
{ {
getEspnowMeshBackend().setEspnowEncryptedConnectionKey(espnowEncryptedConnectionKeySeed); getEspnowMeshBackend().setEspnowEncryptedConnectionKey(espnowEncryptedConnectionKeySeed);
getEspnowMeshBackend().setEspnowHashKey(espnowHashKeySeed); getEspnowMeshBackend().setEspnowHashKey(espnowHashKeySeed);
} }
FloodingMesh::FloodingMesh(const String &serializedMeshState, messageHandlerType messageHandler, const String &meshPassword, FloodingMesh::FloodingMesh(const String &serializedMeshState, messageHandlerType messageHandler, const String &meshPassword,
const uint8_t espnowEncryptedConnectionKey[EspnowProtocolInterpreter::espnowEncryptedConnectionKeyLength], const uint8_t espnowEncryptedConnectionKey[EspnowProtocolInterpreter::encryptedConnectionKeyLength],
const uint8_t espnowHashKey[EspnowProtocolInterpreter::espnowHashKeyLength], const String &ssidPrefix, const uint8_t espnowHashKey[EspnowProtocolInterpreter::hashKeyLength], const String &ssidPrefix,
const String &ssidSuffix, const bool verboseMode, const uint8 meshWiFiChannel) const String &ssidSuffix, const bool verboseMode, const uint8 meshWiFiChannel)
: FloodingMesh(messageHandler, meshPassword, espnowEncryptedConnectionKey, espnowHashKey, ssidPrefix, ssidSuffix, verboseMode, meshWiFiChannel) : FloodingMesh(messageHandler, meshPassword, espnowEncryptedConnectionKey, espnowHashKey, ssidPrefix, ssidSuffix, verboseMode, meshWiFiChannel)
{ {

View File

@ -67,8 +67,8 @@ public:
* make it impossible for other stations to detect the APs whose WiFi channels have changed. * make it impossible for other stations to detect the APs whose WiFi channels have changed.
* *
*/ */
FloodingMesh(messageHandlerType messageHandler, const String &meshPassword, const uint8_t espnowEncryptedConnectionKey[EspnowProtocolInterpreter::espnowEncryptedConnectionKeyLength], FloodingMesh(messageHandlerType messageHandler, const String &meshPassword, const uint8_t espnowEncryptedConnectionKey[EspnowProtocolInterpreter::encryptedConnectionKeyLength],
const uint8_t espnowHashKey[EspnowProtocolInterpreter::espnowHashKeyLength], const String &ssidPrefix, const uint8_t espnowHashKey[EspnowProtocolInterpreter::hashKeyLength], const String &ssidPrefix,
const String &ssidSuffix, const bool verboseMode = false, const uint8 meshWiFiChannel = 1); const String &ssidSuffix, const bool verboseMode = false, const uint8 meshWiFiChannel = 1);
/** /**
@ -99,8 +99,8 @@ public:
* @param serializedMeshState A String with a serialized mesh node state that the node should use. * @param serializedMeshState A String with a serialized mesh node state that the node should use.
*/ */
FloodingMesh(const String &serializedMeshState, messageHandlerType messageHandler, const String &meshPassword, FloodingMesh(const String &serializedMeshState, messageHandlerType messageHandler, const String &meshPassword,
const uint8_t espnowEncryptedConnectionKey[EspnowProtocolInterpreter::espnowEncryptedConnectionKeyLength], const uint8_t espnowEncryptedConnectionKey[EspnowProtocolInterpreter::encryptedConnectionKeyLength],
const uint8_t espnowHashKey[EspnowProtocolInterpreter::espnowHashKeyLength], const String &ssidPrefix, const uint8_t espnowHashKey[EspnowProtocolInterpreter::hashKeyLength], const String &ssidPrefix,
const String &ssidSuffix, const bool verboseMode = false, const uint8 meshWiFiChannel = 1); const String &ssidSuffix, const bool verboseMode = false, const uint8 meshWiFiChannel = 1);
/** /**
@ -317,8 +317,6 @@ private:
uint8_t _broadcastReceptionRedundancy = 2; uint8_t _broadcastReceptionRedundancy = 2;
static char _metadataDelimiter; // Defaults to 23 = End-of-Transmission-Block (ETB) control character in ASCII
uint8_t _originMac[6] = {0}; uint8_t _originMac[6] = {0};
std::map<uint64_t, uint8_t> _messageIDs = {}; std::map<uint64_t, uint8_t> _messageIDs = {};

View File

@ -27,7 +27,10 @@
#include "TypeConversionFunctions.h" #include "TypeConversionFunctions.h"
#include "MeshCryptoInterface.h" #include "MeshCryptoInterface.h"
namespace TypeCast = MeshTypeConversionFunctions; namespace
{
namespace TypeCast = MeshTypeConversionFunctions;
}
namespace JsonTranslator namespace JsonTranslator
{ {

View File

@ -22,9 +22,12 @@
#include <assert.h> #include <assert.h>
namespace TypeCast = MeshTypeConversionFunctions; namespace
{
namespace TypeCast = MeshTypeConversionFunctions;
MeshBackendBase *MeshBackendBase::apController = nullptr; MeshBackendBase *apController = nullptr;
}
std::shared_ptr<bool> MeshBackendBase::_scanMutex = std::make_shared<bool>(false); std::shared_ptr<bool> MeshBackendBase::_scanMutex = std::make_shared<bool>(false);

View File

@ -318,8 +318,6 @@ private:
MeshBackendType _classType; MeshBackendType _classType;
static MeshBackendBase *apController;
String _SSID; String _SSID;
String _SSIDPrefix; String _SSIDPrefix;
String _SSIDRoot; String _SSIDRoot;

View File

@ -38,15 +38,15 @@ MessageData::MessageData(const String &message, const uint8_t transmissionsRemai
MessageData::MessageData(uint8_t *initialTransmission, const uint8_t transmissionLength, const uint32_t creationTimeMs) : MessageData::MessageData(uint8_t *initialTransmission, const uint8_t transmissionLength, const uint32_t creationTimeMs) :
_timeTracker(creationTimeMs) _timeTracker(creationTimeMs)
{ {
_transmissionsExpected = EspnowProtocolInterpreter::espnowGetTransmissionsRemaining(initialTransmission) + 1; _transmissionsExpected = EspnowProtocolInterpreter::getTransmissionsRemaining(initialTransmission) + 1;
addToMessage(initialTransmission, transmissionLength); addToMessage(initialTransmission, transmissionLength);
} }
bool MessageData::addToMessage(uint8_t *transmission, const uint8_t transmissionLength) bool MessageData::addToMessage(uint8_t *transmission, const uint8_t transmissionLength)
{ {
if(EspnowProtocolInterpreter::espnowGetTransmissionsRemaining(transmission) == getTransmissionsRemaining() - 1) if(EspnowProtocolInterpreter::getTransmissionsRemaining(transmission) == getTransmissionsRemaining() - 1)
{ {
String message = EspnowProtocolInterpreter::espnowGetMessageContent(transmission, transmissionLength); String message = EspnowProtocolInterpreter::getHashKeyLength(transmission, transmissionLength);
assert(message.length() <= EspnowMeshBackend::getMaxMessageBytesPerTransmission()); // Should catch some cases where transmission is not null terminated. assert(message.length() <= EspnowMeshBackend::getMaxMessageBytesPerTransmission()); // Should catch some cases where transmission is not null terminated.
_totalMessage += message; _totalMessage += message;
++_transmissionsReceived; ++_transmissionsReceived;

View File

@ -24,7 +24,10 @@
#include "MutexTracker.h" #include "MutexTracker.h"
std::shared_ptr<bool> MutexTracker::_captureBan = std::make_shared<bool>(false); namespace
{
static std::shared_ptr<bool> _captureBan = std::make_shared<bool>(false);
}
std::shared_ptr<bool> MutexTracker::captureBan() std::shared_ptr<bool> MutexTracker::captureBan()
{ {

View File

@ -65,8 +65,6 @@ class MutexTracker
private: private:
static std::shared_ptr<bool> _captureBan;
std::shared_ptr<bool> _capturedMutex; std::shared_ptr<bool> _capturedMutex;
std::function<void()> _destructorHook = [](){ }; std::function<void()> _destructorHook = [](){ };

View File

@ -25,17 +25,20 @@
#include "PeerRequestLog.h" #include "PeerRequestLog.h"
#include "EspnowMeshBackend.h" #include "EspnowMeshBackend.h"
using EspnowProtocolInterpreter::espnowHashKeyLength; namespace
{
using EspnowProtocolInterpreter::hashKeyLength;
}
PeerRequestLog::PeerRequestLog(const uint64_t requestID, const bool requestEncrypted, const String &authenticationPassword, const uint8_t encryptedConnectionsSoftLimit, PeerRequestLog::PeerRequestLog(const uint64_t requestID, const bool requestEncrypted, const String &authenticationPassword, const uint8_t encryptedConnectionsSoftLimit,
const String &peerRequestNonce, const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint8_t hashKey[espnowHashKeyLength]) const String &peerRequestNonce, const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint8_t hashKey[hashKeyLength])
: EncryptedConnectionData(peerStaMac, peerApMac, 0, 0, EspnowMeshBackend::getEncryptionRequestTimeout(), hashKey), : EncryptedConnectionData(peerStaMac, peerApMac, 0, 0, EspnowMeshBackend::getEncryptionRequestTimeout(), hashKey),
_requestID(requestID), _requestEncrypted(requestEncrypted), _authenticationPassword(authenticationPassword), _requestID(requestID), _requestEncrypted(requestEncrypted), _authenticationPassword(authenticationPassword),
_encryptedConnectionsSoftLimit(encryptedConnectionsSoftLimit), _peerRequestNonce(peerRequestNonce) _encryptedConnectionsSoftLimit(encryptedConnectionsSoftLimit), _peerRequestNonce(peerRequestNonce)
{ } { }
PeerRequestLog::PeerRequestLog(const uint64_t requestID, const bool requestEncrypted, const String &authenticationPassword, const uint8_t encryptedConnectionsSoftLimit, const String &peerRequestNonce, PeerRequestLog::PeerRequestLog(const uint64_t requestID, const bool requestEncrypted, const String &authenticationPassword, const uint8_t encryptedConnectionsSoftLimit, const String &peerRequestNonce,
const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint64_t peerSessionKey, const uint64_t ownSessionKey, const uint8_t hashKey[espnowHashKeyLength]) const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint64_t peerSessionKey, const uint64_t ownSessionKey, const uint8_t hashKey[hashKeyLength])
: EncryptedConnectionData(peerStaMac, peerApMac, peerSessionKey, ownSessionKey, EspnowMeshBackend::getEncryptionRequestTimeout(), hashKey), : EncryptedConnectionData(peerStaMac, peerApMac, peerSessionKey, ownSessionKey, EspnowMeshBackend::getEncryptionRequestTimeout(), hashKey),
_requestID(requestID), _requestEncrypted(requestEncrypted), _authenticationPassword(authenticationPassword), _requestID(requestID), _requestEncrypted(requestEncrypted), _authenticationPassword(authenticationPassword),
_encryptedConnectionsSoftLimit(encryptedConnectionsSoftLimit), _peerRequestNonce(peerRequestNonce) _encryptedConnectionsSoftLimit(encryptedConnectionsSoftLimit), _peerRequestNonce(peerRequestNonce)

View File

@ -33,10 +33,10 @@ class PeerRequestLog : public EncryptedConnectionData {
public: public:
PeerRequestLog(const uint64_t requestID, const bool requestEncrypted, const String &authenticationPassword, const uint8_t encryptedConnectionsSoftLimit, const String &peerRequestNonce, PeerRequestLog(const uint64_t requestID, const bool requestEncrypted, const String &authenticationPassword, const uint8_t encryptedConnectionsSoftLimit, const String &peerRequestNonce,
const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint8_t hashKey[EspnowProtocolInterpreter::espnowHashKeyLength]); const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint8_t hashKey[EspnowProtocolInterpreter::hashKeyLength]);
PeerRequestLog(const uint64_t requestID, const bool requestEncrypted, const String &authenticationPassword, const uint8_t encryptedConnectionsSoftLimit, const String &peerRequestNonce, PeerRequestLog(const uint64_t requestID, const bool requestEncrypted, const String &authenticationPassword, const uint8_t encryptedConnectionsSoftLimit, const String &peerRequestNonce,
const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint64_t peerSessionKey, const uint64_t ownSessionKey, const uint8_t peerStaMac[6], const uint8_t peerApMac[6], const uint64_t peerSessionKey, const uint64_t ownSessionKey,
const uint8_t hashKey[EspnowProtocolInterpreter::espnowHashKeyLength]); const uint8_t hashKey[EspnowProtocolInterpreter::hashKeyLength]);
void setRequestID(const uint64_t requestID); void setRequestID(const uint64_t requestID);
uint64_t getRequestID() const; uint64_t getRequestID() const;

View File

@ -28,6 +28,15 @@
namespace namespace
{ {
constexpr char SERVER_IP_ADDR[] PROGMEM = "192.168.4.1"; constexpr char SERVER_IP_ADDR[] PROGMEM = "192.168.4.1";
String _temporaryMessage;
String lastSSID;
bool staticIPActivated = false;
// IP needs to be at the same subnet as server gateway (192.168.4 in this case). Station gateway ip must match ip for server.
IPAddress staticIP;
IPAddress gateway(192,168,4,1);
IPAddress subnetMask(255,255,255,0);
} }
const IPAddress TcpIpMeshBackend::emptyIP; const IPAddress TcpIpMeshBackend::emptyIP;
@ -35,16 +44,6 @@ const IPAddress TcpIpMeshBackend::emptyIP;
std::shared_ptr<bool> TcpIpMeshBackend::_tcpIpTransmissionMutex = std::make_shared<bool>(false); std::shared_ptr<bool> TcpIpMeshBackend::_tcpIpTransmissionMutex = std::make_shared<bool>(false);
std::shared_ptr<bool> TcpIpMeshBackend::_tcpIpConnectionQueueMutex = std::make_shared<bool>(false); std::shared_ptr<bool> TcpIpMeshBackend::_tcpIpConnectionQueueMutex = std::make_shared<bool>(false);
String TcpIpMeshBackend::lastSSID;
bool TcpIpMeshBackend::staticIPActivated = false;
String TcpIpMeshBackend::_temporaryMessage;
// IP needs to be at the same subnet as server gateway (192.168.4 in this case). Station gateway ip must match ip for server.
IPAddress TcpIpMeshBackend::staticIP;
IPAddress TcpIpMeshBackend::gateway(192,168,4,1);
IPAddress TcpIpMeshBackend::subnetMask(255,255,255,0);
std::vector<TcpIpNetworkInfo> TcpIpMeshBackend::_connectionQueue = {}; std::vector<TcpIpNetworkInfo> TcpIpMeshBackend::_connectionQueue = {};
std::vector<TransmissionOutcome> TcpIpMeshBackend::_latestTransmissionOutcomes = {}; std::vector<TransmissionOutcome> TcpIpMeshBackend::_latestTransmissionOutcomes = {};

View File

@ -261,13 +261,7 @@ private:
int _stationModeTimeoutMs = 5000; // int is the type used in the Arduino core for this particular API, not uint32_t, which is why we use int here. int _stationModeTimeoutMs = 5000; // int is the type used in the Arduino core for this particular API, not uint32_t, which is why we use int here.
uint32_t _apModeTimeoutMs = 4500; uint32_t _apModeTimeoutMs = 4500;
static String _temporaryMessage;
static String lastSSID;
static bool staticIPActivated;
bool useStaticIP; bool useStaticIP;
static IPAddress staticIP;
static IPAddress gateway;
static IPAddress subnetMask;
void fullStop(WiFiClient &currClient); void fullStop(WiFiClient &currClient);
void initiateConnectionToAP(const String &targetSSID, const int targetChannel = NETWORK_INFO_DEFAULT_INT, const uint8_t *targetBSSID = NULL); void initiateConnectionToAP(const String &targetSSID, const int targetChannel = NETWORK_INFO_DEFAULT_INT, const uint8_t *targetBSSID = NULL);