14
14
#define DISTANCE_INVALID (0xFF )
15
15
16
16
// Macros for manipulating signing requirement table
17
- #define DO_SIGN (node ) (doSign[node>>4 ]&(node%16 ))
18
- #define SET_SIGN (node ) (doSign[node>>4 ]|= (node%16 ))
19
- #define CLEAR_SIGN (node ) (doSign[node>>4 ]&=~ (node%16 ))
17
+ #define DO_SIGN (node ) (node == 0 ? (~ doSign[0 ]& 1 ) : (~doSign[ node>>4 ]&(node%16 ) ))
18
+ #define SET_SIGN (node ) (node == 0 ? ( doSign[0 ]&=~ 1 ) : (doSign[ node>>4 ]&=~ (node%16 ) ))
19
+ #define CLEAR_SIGN (node ) (node == 0 ? ( doSign[0 ]|= 1 ) : (doSign[ node>>4 ]|= (node%16 ) ))
20
20
21
21
// Inline function and macros
22
22
static inline MyMessage& build (MyMessage &msg, uint8_t sender, uint8_t destination, uint8_t sensor, uint8_t command, uint8_t type, bool enableAck) {
@@ -132,12 +132,17 @@ void MySensor::setupNode() {
132
132
133
133
// Present node and request config
134
134
if (!isGateway && nc.nodeId != AUTO) {
135
- // Send presentation for this radio node (attach
136
- present (NODE_SENSOR_ID, repeaterMode? S_ARDUINO_REPEATER_NODE : S_ARDUINO_NODE);
137
-
138
135
// Notify gateway (and possibly controller) about the signing preferences of this node
139
136
sendRoute (build (msg, nc.nodeId , GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_REQUEST_SIGNING, false ).set (signer.requestSignatures ()));
140
137
138
+ // If we do require signing, wait for the gateway to tell us how it perfer us to transmit our messages
139
+ if (signer.requestSignatures ()) {
140
+ wait (2000 );
141
+ }
142
+
143
+ // Send presentation for this radio node (attach
144
+ present (NODE_SENSOR_ID, repeaterMode? S_ARDUINO_REPEATER_NODE : S_ARDUINO_NODE);
145
+
141
146
// Send a configuration exchange request to controller
142
147
// Node sends parent node. Controller answers with latest node configuration
143
148
// which is picked up in process()
@@ -185,9 +190,12 @@ boolean MySensor::sendRoute(MyMessage &message) {
185
190
186
191
mSetVersion (message, PROTOCOL_VERSION);
187
192
188
- // If destination is known to require signed messages and we are the sender, sign this message unless it is an ACK or a signing handshake message
193
+ // If destination is known to require signed messages and we are the sender, sign this message unless it is an ACK or a handshake message
189
194
if (DO_SIGN (message.destination ) && message.sender == nc.nodeId && !mGetAck (message) && mGetLength (msg) &&
190
- (mGetCommand (message) != C_INTERNAL || (message.type != I_GET_NONCE && message.type != I_GET_NONCE_RESPONSE && message.type != I_REQUEST_SIGNING))) {
195
+ (mGetCommand (message) != C_INTERNAL ||
196
+ (message.type != I_GET_NONCE && message.type != I_GET_NONCE_RESPONSE && message.type != I_REQUEST_SIGNING &&
197
+ message.type != I_ID_REQUEST && message.type != I_ID_RESPONSE &&
198
+ message.type != I_FIND_PARENT && message.type != I_FIND_PARENT_RESPONSE))) {
191
199
if (!sign (message)) {
192
200
debug (PSTR (" Message signing failed\n " ));
193
201
return false ;
@@ -313,10 +321,16 @@ boolean MySensor::process() {
313
321
uint8_t len = radio.receive ((uint8_t *)&msg);
314
322
315
323
// Before processing message, reject unsigned messages if signing is required and check signature (if it is signed and addressed to us)
316
- // Note that we do not care at all about any signature found if we do not require signing
317
- if (signer.requestSignatures () && msg.destination == nc.nodeId && mGetLength (msg) &&
318
- (mGetCommand (msg) != C_INTERNAL || (msg.type != I_GET_NONCE_RESPONSE && msg.type != I_GET_NONCE && msg.type != I_REQUEST_SIGNING))) {
319
- if (!mGetSigned (msg)) return false ; // Received an unsigned message but we do require signing. This message gets nowhere!
324
+ // Note that we do not care at all about any signature found if we do not require signing, nor do we care about ACKs (they are never signed)
325
+ if (signer.requestSignatures () && msg.destination == nc.nodeId && mGetLength (msg) && !mGetAck (msg) &&
326
+ (mGetCommand (msg) != C_INTERNAL ||
327
+ (msg.type != I_GET_NONCE_RESPONSE && msg.type != I_GET_NONCE && msg.type != I_REQUEST_SIGNING &&
328
+ msg.type != I_ID_REQUEST && msg.type != I_ID_RESPONSE &&
329
+ msg.type != I_FIND_PARENT && msg.type != I_FIND_PARENT_RESPONSE))) {
330
+ if (!mGetSigned (msg)) {
331
+ debug (PSTR (" Got unsigned message that should have been signed\n " ));
332
+ return false ;
333
+ }
320
334
else if (!signer.verifyMsg (msg)) {
321
335
debug (PSTR (" Message verification failed\n " ));
322
336
return false ; // This signed message has been tampered with!
@@ -383,10 +397,9 @@ boolean MySensor::process() {
383
397
return false ;
384
398
} else if (type == I_GET_NONCE) {
385
399
if (signer.getNonce (msg)) {
386
- sendRoute (build (msg, nc.nodeId , GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_GET_NONCE_RESPONSE, false ));
387
- } else {
388
- return false ;
400
+ sendRoute (build (msg, nc.nodeId , msg.sender , NODE_SENSOR_ID, C_INTERNAL, I_GET_NONCE_RESPONSE, false ));
389
401
}
402
+ return false ; // Nonce exchange is an internal MySensor protocol message, no need to inform caller about this
390
403
} else if (type == I_REQUEST_SIGNING) {
391
404
if (msg.getBool ()) {
392
405
// We received an indicator that the sender require us to sign all messages we send to it
@@ -407,6 +420,9 @@ boolean MySensor::process() {
407
420
else
408
421
sendRoute (build (msg, nc.nodeId , msg.sender , NODE_SENSOR_ID, C_INTERNAL, I_REQUEST_SIGNING, false ).set (false ));
409
422
}
423
+ return false ; // Signing request is an internal MySensor protocol message, no need to inform caller about this
424
+ } else if (type == I_GET_NONCE_RESPONSE) {
425
+ return true ; // Just pass along nonce silently (no need to call callback for these)
410
426
} else if (sender == GATEWAY_ADDRESS) {
411
427
bool isMetric;
412
428
0 commit comments