14
14
https://github.com/esp8266/Arduino/issues/1143
15
15
https://arduino-esp8266.readthedocs.io/en/latest/PROGMEM.html
16
16
*/
17
- const char exampleMeshName[] PROGMEM = " MeshNode_" ; // The name of the mesh network. Used as prefix for the node SSID and to find other network nodes during ESP-NOW broadcasts and in the example networkFilter function below.
17
+ const char exampleMeshName[] PROGMEM = " MeshNode_" ; // The name of the mesh network. Used as prefix for the node SSID and to find other network nodes in the example networkFilter and broadcastFilter functions below.
18
18
const char exampleWiFiPassword[] PROGMEM = " ChangeThisWiFiPassword_TODO" ; // The password has to be min 8 and max 64 characters long, otherwise an AP which uses it will not be found during scans.
19
19
20
20
// A custom encryption key is required when using encrypted ESP-NOW transmissions. There is always a default Kok set, but it can be replaced if desired.
@@ -32,6 +32,8 @@ uint8_t espnowHashKey[16] = {0xEF, 0x44, 0x33, 0x0C, 0x33, 0x44, 0xFE, 0x44, //
32
32
unsigned int requestNumber = 0 ;
33
33
unsigned int responseNumber = 0 ;
34
34
35
+ const char broadcastMetadataDelimiter = 23 ; // 23 = End-of-Transmission-Block (ETB) control character in ASCII
36
+
35
37
String manageRequest (const String &request, MeshBackendBase &meshInstance);
36
38
transmission_status_t manageResponse (const String &response, MeshBackendBase &meshInstance);
37
39
void networkFilter (int numberOfNetworks, MeshBackendBase &meshInstance);
@@ -96,7 +98,7 @@ transmission_status_t manageResponse(const String &response, MeshBackendBase &me
96
98
// With ESP-NOW there is no guarantee when or if a response will show up, it can happen before or after the stored message is changed.
97
99
// So for ESP-NOW, adding unique identifiers in the response and request is required to associate a response with a request.
98
100
Serial.print (F (" Request sent: " ));
99
- Serial.println (tcpIpInstance->getMessage ().substring (0 , 100 ));
101
+ Serial.println (tcpIpInstance->getCurrentMessage ().substring (0 , 100 ));
100
102
} else {
101
103
Serial.print (" UNKNOWN!: " );
102
104
}
@@ -127,14 +129,18 @@ void networkFilter(int numberOfNetworks, MeshBackendBase &meshInstance) {
127
129
uint64_t targetNodeID = stringToUint64 (currentSSID.substring (meshNameIndex + meshInstance.getMeshName ().length ()));
128
130
129
131
if (targetNodeID < stringToUint64 (meshInstance.getNodeID ())) {
130
- MeshBackendBase::connectionQueue.push_back (NetworkInfo (networkIndex));
132
+ if (EspnowMeshBackend *espnowInstance = meshBackendCast<EspnowMeshBackend *>(&meshInstance)) {
133
+ espnowInstance->connectionQueue ().push_back (networkIndex);
134
+ } else if (TcpIpMeshBackend *tcpIpInstance = meshBackendCast<TcpIpMeshBackend *>(&meshInstance)) {
135
+ tcpIpInstance->connectionQueue ().push_back (networkIndex);
136
+ } else {
137
+ Serial.println (String (F (" Invalid mesh backend!" )));
138
+ }
131
139
}
132
140
}
133
141
}
134
142
}
135
143
136
- const char broadcastMetadataDelimiter = 23 ; // 23 = End-of-Transmission-Block (ETB) control character in ASCII
137
-
138
144
/* *
139
145
Callback used to decide which broadcast messages to accept. Only called for the first transmission in each broadcast.
140
146
If true is returned from this callback, the first broadcast transmission is saved until the entire broadcast message has been received.
@@ -147,10 +153,8 @@ const char broadcastMetadataDelimiter = 23; // 23 = End-of-Transmission-Block (E
147
153
@return True if the broadcast should be accepted. False otherwise.
148
154
*/
149
155
bool broadcastFilter (String &firstTransmission, EspnowMeshBackend &meshInstance) {
150
- /* *
151
- This example broadcastFilter will accept a transmission if it contains the broadcastMetadataDelimiter
152
- and as metaData either no targetMeshName or a targetMeshName that matches the MeshName of meshInstance.
153
- */
156
+ // This example broadcastFilter will accept a transmission if it contains the broadcastMetadataDelimiter
157
+ // and as metaData either no targetMeshName or a targetMeshName that matches the MeshName of meshInstance.
154
158
155
159
int32_t metadataEndIndex = firstTransmission.indexOf (broadcastMetadataDelimiter);
156
160
@@ -230,7 +234,7 @@ void loop() {
230
234
231
235
uint32_t startTime = millis ();
232
236
espnowNode.attemptTransmission (espnowNode.getMessage ());
233
- Serial.println (" Scan and " + String (MeshBackendBase:: latestTransmissionOutcomes.size ()) + " transmissions done in " + String (millis () - startTime) + " ms." );
237
+ Serial.println (" Scan and " + String (espnowNode. latestTransmissionOutcomes () .size ()) + " transmissions done in " + String (millis () - startTime) + " ms." );
234
238
235
239
timeOfLastScan = millis ();
236
240
@@ -239,23 +243,23 @@ void loop() {
239
243
espnowDelay (100 );
240
244
241
245
// One way to check how attemptTransmission worked out
242
- if (MeshBackendBase:: latestTransmissionSuccessful ()) {
246
+ if (espnowNode. latestTransmissionSuccessful ()) {
243
247
Serial.println (F (" Transmission successful." ));
244
248
}
245
249
246
250
// Another way to check how attemptTransmission worked out
247
- if (MeshBackendBase:: latestTransmissionOutcomes.empty ()) {
251
+ if (espnowNode. latestTransmissionOutcomes () .empty ()) {
248
252
Serial.println (F (" No mesh AP found." ));
249
253
} else {
250
- for (TransmissionResult &transmissionResult : MeshBackendBase:: latestTransmissionOutcomes) {
251
- if (transmissionResult .transmissionStatus == TS_TRANSMISSION_FAILED) {
252
- Serial.println (String (F (" Transmission failed to mesh AP " )) + transmissionResult .SSID );
253
- } else if (transmissionResult .transmissionStatus == TS_CONNECTION_FAILED) {
254
- Serial.println (String (F (" Connection failed to mesh AP " )) + transmissionResult .SSID );
255
- } else if (transmissionResult .transmissionStatus == TS_TRANSMISSION_COMPLETE) {
254
+ for (TransmissionOutcome &transmissionOutcome : espnowNode. latestTransmissionOutcomes () ) {
255
+ if (transmissionOutcome .transmissionStatus () == TS_TRANSMISSION_FAILED) {
256
+ Serial.println (String (F (" Transmission failed to mesh AP " )) + transmissionOutcome .SSID () );
257
+ } else if (transmissionOutcome .transmissionStatus () == TS_CONNECTION_FAILED) {
258
+ Serial.println (String (F (" Connection failed to mesh AP " )) + transmissionOutcome .SSID () );
259
+ } else if (transmissionOutcome .transmissionStatus () == TS_TRANSMISSION_COMPLETE) {
256
260
// No need to do anything, transmission was successful.
257
261
} else {
258
- Serial.println (String (F (" Invalid transmission status for " )) + transmissionResult .SSID + String (F (" !" )));
262
+ Serial.println (String (F (" Invalid transmission status for " )) + transmissionOutcome .SSID () + String (F (" !" )));
259
263
assert (F (" Invalid transmission status returned from responseHandler!" ) && false );
260
264
}
261
265
}
@@ -276,26 +280,28 @@ void loop() {
276
280
277
281
Serial.println (" \n Performing encrypted ESP-NOW transmissions." );
278
282
283
+ uint8_t targetBSSID[6 ] {0 };
284
+
279
285
// We can create encrypted connections to individual nodes so that all ESP-NOW communication with the node will be encrypted.
280
- if (espnowNode.requestEncryptedConnection (MeshBackendBase:: connectionQueue[0 ].BSSID ) == ECS_CONNECTION_ESTABLISHED) {
286
+ if (espnowNode.connectionQueue () [0 ].getBSSID (targetBSSID) && espnowNode. requestEncryptedConnection (targetBSSID ) == ECS_CONNECTION_ESTABLISHED) {
281
287
// The WiFi scan will detect the AP MAC, but this will automatically be converted to the encrypted STA MAC by the framework.
282
- String peerMac = macToString (MeshBackendBase::connectionQueue[ 0 ]. BSSID );
288
+ String peerMac = macToString (targetBSSID );
283
289
284
290
Serial.println (" Encrypted ESP-NOW connection with " + peerMac + " established!" );
285
291
286
- // Making a transmission now will cause messages to MeshBackendBase::connectionQueue[0].BSSID to be encrypted.
292
+ // Making a transmission now will cause messages to targetBSSID to be encrypted.
287
293
String espnowMessage = " This message is encrypted only when received by node " + peerMac;
288
294
Serial.println (" \n Transmitting: " + espnowMessage);
289
295
espnowNode.attemptTransmission (espnowMessage, false );
290
296
espnowDelay (100 ); // Wait for response.
291
297
292
298
// A connection can be serialized and stored for later use.
293
299
// Note that this saves the current state only, so if encrypted communication between the nodes happen after this, the stored state is invalid.
294
- String serializedEncryptedConnection = EspnowMeshBackend::serializeEncryptedConnection (MeshBackendBase::connectionQueue[ 0 ]. BSSID );
300
+ String serializedEncryptedConnection = EspnowMeshBackend::serializeEncryptedConnection (targetBSSID );
295
301
296
302
Serial.println ();
297
303
// We can remove an encrypted connection like so.
298
- espnowNode.removeEncryptedConnection (MeshBackendBase::connectionQueue[ 0 ]. BSSID );
304
+ espnowNode.removeEncryptedConnection (targetBSSID );
299
305
300
306
// Note that the peer will still be encrypted, so although we can send unencrypted messages to the peer, we cannot read the encrypted responses it sends back.
301
307
espnowMessage = " This message is no longer encrypted when received by node " + peerMac;
@@ -304,7 +310,7 @@ void loop() {
304
310
espnowDelay (100 ); // Wait for response.
305
311
Serial.println (" Cannot read the encrypted response..." );
306
312
307
- // Let's re-add our stored connection so we can communicate properly with MeshBackendBase::connectionQueue[0].BSSID again!
313
+ // Let's re-add our stored connection so we can communicate properly with targetBSSID again!
308
314
espnowNode.addEncryptedConnection (serializedEncryptedConnection);
309
315
310
316
espnowMessage = " This message is once again encrypted when received by node " + peerMac;
@@ -314,21 +320,28 @@ void loop() {
314
320
315
321
Serial.println ();
316
322
// If we want to remove the encrypted connection on both nodes, we can do it like this.
317
- encrypted_connection_removal_outcome_t removalOutcome = espnowNode.requestEncryptedConnectionRemoval (MeshBackendBase::connectionQueue[ 0 ]. BSSID );
323
+ encrypted_connection_removal_outcome_t removalOutcome = espnowNode.requestEncryptedConnectionRemoval (targetBSSID );
318
324
if (removalOutcome == ECRO_REMOVAL_SUCCEEDED) {
319
- Serial.println (peerMac + " is no longer encrypted!\n " );
325
+ Serial.println (peerMac + " is no longer encrypted!" );
326
+
327
+ espnowMessage = " This message is only received by node " + peerMac + " . Transmitting in this way will not change the transmission state of the sender." ;
328
+ Serial.println (" Transmitting: " + espnowMessage);
329
+ espnowNode.attemptTransmission (espnowMessage, EspnowNetworkInfo (targetBSSID));
330
+ espnowDelay (100 ); // Wait for response.
331
+
332
+ Serial.println ();
320
333
321
334
// Of course, we can also just create a temporary encrypted connection that will remove itself once its duration has passed.
322
- if (espnowNode.requestTemporaryEncryptedConnection (MeshBackendBase::connectionQueue[ 0 ]. BSSID , 1000 ) == ECS_CONNECTION_ESTABLISHED) {
335
+ if (espnowNode.requestTemporaryEncryptedConnection (targetBSSID , 1000 ) == ECS_CONNECTION_ESTABLISHED) {
323
336
espnowDelay (42 );
324
337
uint32_t remainingDuration = 0 ;
325
- EspnowMeshBackend::getConnectionInfo (MeshBackendBase::connectionQueue[ 0 ]. BSSID , &remainingDuration);
338
+ EspnowMeshBackend::getConnectionInfo (targetBSSID , &remainingDuration);
326
339
327
340
espnowMessage = " Messages this node sends to " + peerMac + " will be encrypted for " + String (remainingDuration) + " ms more." ;
328
341
Serial.println (" \n Transmitting: " + espnowMessage);
329
342
espnowNode.attemptTransmission (espnowMessage, false );
330
343
331
- EspnowMeshBackend::getConnectionInfo (MeshBackendBase::connectionQueue[ 0 ]. BSSID , &remainingDuration);
344
+ EspnowMeshBackend::getConnectionInfo (targetBSSID , &remainingDuration);
332
345
espnowDelay (remainingDuration + 100 );
333
346
334
347
espnowMessage = " Due to encrypted connection expiration, this message is no longer encrypted when received by node " + peerMac;
0 commit comments