57
57
#define S2_NONCE_REPORT_MOS_SOS_INDEX 3
58
58
#define S2_NONCE_REPORT_MOS_SOS_MASK 0x3
59
59
60
+ // Number of nodes per byte in NLS state node mask
61
+ #define NLS_ENABLED_NODES_PER_BYTE 8
62
+
60
63
struct S2 * s2_ctx ;
61
64
62
65
typedef enum { SINGLECAST , MULTICAST } zwave_s2_current_transmission_type_t ;
@@ -84,6 +87,17 @@ static s2_transport_session_state_t state = {};
84
87
static uint8_t secure_nif [ZWAVE_MAX_FRAME_SIZE ];
85
88
static uint8_t secure_nif_length ;
86
89
90
+ // NLS context
91
+ typedef struct s2_node_nls_context {
92
+ zwave_nodemask_t node_list ; // bitmask containing NLS enabled nodes in the network
93
+ uint16_t node_list_length ; // length of the list in bytes (is not equal to the number of nodes in the network)
94
+ zwave_node_id_t next_sent_node_id ; // node ID of the NLS enabled node to be sent next
95
+ uint16_t nls_enabled_node_cnt ; // total number of NLS enabled nodes in the network
96
+ uint16_t nls_enabled_node_sent_cnt ; // number of NLS enabled nodes already sent to the joining node
97
+ } s2_node_nls_context_t ;
98
+
99
+ static s2_node_nls_context_t node_nls_context = {0 };
100
+
87
101
static uint8_t
88
102
encapsulation_to_class (zwave_controller_encapsulation_scheme_t encap )
89
103
{
@@ -414,18 +428,17 @@ uint8_t S2_send_frame_multi(struct S2 *ctxt,
414
428
0 );
415
429
}
416
430
417
-
418
431
void S2_notify_nls_state_report (node_t srcNode , uint8_t class_id , bool nls_capability , bool nls_state )
419
432
{
420
433
(void )class_id ;
421
434
422
- sl_log_debug (LOG_TAG , "NLS state report received for node %d, capability : %d, state: %d" , srcNode , ( bool ) nls_capability , ( bool ) nls_state );
435
+ sl_log_debug (LOG_TAG , "NLS state report received for node %d, capability : %d, state: %d" , srcNode , nls_capability , nls_state );
423
436
424
437
if (zwave_store_nls_support ((zwave_node_id_t )srcNode ,
425
- ( bool ) nls_capability ,
438
+ nls_capability ,
426
439
REPORTED_ATTRIBUTE )
427
440
|| zwave_store_nls_state ((zwave_node_id_t )srcNode ,
428
- ( bool ) nls_state ,
441
+ nls_state ,
429
442
REPORTED_ATTRIBUTE )) {
430
443
sl_log_error (LOG_TAG , "Error setting NLS attributes" );
431
444
return ;
@@ -443,24 +456,171 @@ void S2_save_nls_state(void)
443
456
// not relevant for ZPC
444
457
}
445
458
446
- int8_t S2_get_nls_node_list ( node_t srcNode , bool request , bool * is_last_node , uint16_t * node_id , uint8_t * granted_keys , bool * nls_state )
459
+ sl_status_t compute_next_nls_enabled_node ( void )
447
460
{
448
- // to be implemented later on
449
- (void )srcNode ;
450
- (void )request ;
451
- return 0 ;
461
+ for (uint16_t i = (node_nls_context .next_sent_node_id + 1 );
462
+ i <= (node_nls_context .node_list_length * NLS_ENABLED_NODES_PER_BYTE );
463
+ i ++ ) {
464
+ uint8_t nls_enabled = ZW_IS_NODE_IN_MASK (i , node_nls_context .node_list );
465
+ if (nls_enabled ) {
466
+ node_nls_context .next_sent_node_id = i ;
467
+ return SL_STATUS_OK ;
468
+ }
469
+ }
470
+
471
+ return SL_STATUS_NOT_FOUND ;
452
472
}
453
473
454
- int8_t S2_notify_nls_node_list_report ( node_t srcNode , uint16_t id_of_node , uint8_t keys_node_bitmask , bool nls_state )
474
+ static uint16_t compute_nls_enabled_node_cnt ( void )
455
475
{
456
- // to be implemented later on
457
- (void )srcNode ;
458
- (void )id_of_node ;
459
- (void )keys_node_bitmask ;
460
- (void )nls_state ;
476
+ for (uint16_t i = 1 ;
477
+ i <= (node_nls_context .node_list_length * NLS_ENABLED_NODES_PER_BYTE );
478
+ i ++ ) {
479
+ uint8_t nls_enabled = ZW_IS_NODE_IN_MASK (i , node_nls_context .node_list );
480
+ if (nls_enabled ) {
481
+ node_nls_context .nls_enabled_node_cnt ++ ;
482
+ }
483
+ }
484
+
485
+ return node_nls_context .nls_enabled_node_cnt ;
486
+ }
487
+
488
+ /*
489
+ This command is received by the trust center (SIS). We can retrieve the list from the controller when the
490
+ joining node requests it for the first node (request flag is set to 0) and then send the cached
491
+ information for the remaining nodes.
492
+
493
+ This function is not supposed to send a frame. It just fills the necessary fields of the report frame of the
494
+ command in question and let libS2 send it.
495
+
496
+ If there is no NLS enabled nodes or last NLS enabled node is sent, `nls_state` is not set to true so libS2
497
+ should not send the report frame.
498
+ */
499
+ int8_t S2_get_nls_node_list (node_t srcNode ,
500
+ bool request ,
501
+ bool * is_last_node ,
502
+ uint16_t * node_id ,
503
+ uint8_t * granted_keys ,
504
+ bool * nls_state )
505
+ {
506
+ sl_status_t status = SL_STATUS_OK ;
507
+ * is_last_node = false;
508
+ * node_id = 0 ;
509
+ * granted_keys = 0 ;
510
+ * nls_state = false;
511
+
512
+ sl_log_debug (LOG_TAG ,
513
+ "NLS Node List Get received from node %d, request: %d" ,
514
+ srcNode ,
515
+ request );
516
+
517
+ if (request == false) {
518
+ memset (& node_nls_context , 0 , sizeof (s2_node_nls_context_t ));
519
+ status = zwapi_get_nls_nodes (& node_nls_context .node_list_length ,
520
+ node_nls_context .node_list );
521
+ if (status != SL_STATUS_OK ) {
522
+ sl_log_error (LOG_TAG , "Error getting NLS nodes, %d" , status );
523
+ return -1 ;
524
+ }
525
+ compute_nls_enabled_node_cnt ();
526
+ }
527
+
528
+ if (node_nls_context .nls_enabled_node_cnt == 0 ) {
529
+ sl_log_warning (LOG_TAG , "No NLS enabled nodes found in the controller NVM" );
530
+ return -1 ;
531
+ }
532
+
533
+ if (node_nls_context .nls_enabled_node_sent_cnt
534
+ == node_nls_context .nls_enabled_node_cnt ) {
535
+ sl_log_warning (LOG_TAG , "All NLS enabled nodes are already sent" );
536
+ return -1 ;
537
+ }
538
+
539
+ if (node_nls_context .nls_enabled_node_sent_cnt
540
+ == node_nls_context .nls_enabled_node_cnt - 1 ) {
541
+ * is_last_node = true;
542
+ }
543
+
544
+ status = compute_next_nls_enabled_node ();
545
+ if (status != SL_STATUS_OK ) {
546
+ sl_log_debug (LOG_TAG , "No NLS enabled nodes found in the controller NVM" );
547
+ return -1 ;
548
+ }
549
+
550
+ zwave_keyset_t keyset = {0 };
551
+ status
552
+ = zwave_get_node_granted_keys (node_nls_context .next_sent_node_id , & keyset );
553
+ if (status != SL_STATUS_OK ) {
554
+ sl_log_error (LOG_TAG ,
555
+ "Error getting granted keys of the node %d" ,
556
+ node_nls_context .next_sent_node_id );
557
+ return -1 ;
558
+ }
559
+ * granted_keys = (uint8_t )keyset ;
560
+
561
+ node_nls_context .nls_enabled_node_sent_cnt ++ ;
562
+
563
+ * node_id = node_nls_context .next_sent_node_id ;
564
+ * nls_state = true;
565
+
461
566
return 0 ;
462
567
}
463
568
569
+ /*
570
+ This command is received by the joining node (secondary controller).
571
+ */
572
+ int8_t S2_notify_nls_node_list_report (node_t srcNode ,
573
+ uint16_t id_of_node ,
574
+ uint8_t keys_node_bitmask ,
575
+ bool nls_state )
576
+ {
577
+ sl_status_t status = SL_STATUS_OK ;
578
+
579
+ sl_log_debug (LOG_TAG ,
580
+ "NLS Node List Report received from the node %d, NLS state: %d" ,
581
+ srcNode ,
582
+ nls_state );
583
+
584
+ if (nls_state ) {
585
+ status = zwapi_enable_node_nls (id_of_node );
586
+ if (SL_STATUS_OK != status ) {
587
+ sl_log_error (
588
+ LOG_TAG ,
589
+ "Error saving NLS state of the node %d in the controller NVM" ,
590
+ id_of_node );
591
+ return -1 ;
592
+ }
593
+
594
+ if (zwave_store_nls_support ((zwave_node_id_t )id_of_node ,
595
+ true,
596
+ REPORTED_ATTRIBUTE )
597
+ || zwave_store_nls_state ((zwave_node_id_t )id_of_node ,
598
+ true,
599
+ REPORTED_ATTRIBUTE )) {
600
+ sl_log_error (LOG_TAG ,
601
+ "Error setting NLS attributes of the node %d" ,
602
+ id_of_node );
603
+ return -1 ;
604
+ }
605
+
606
+ status = zwave_set_node_granted_keys ((zwave_node_id_t )id_of_node ,
607
+ & keys_node_bitmask );
608
+ if (SL_STATUS_OK != status ) {
609
+ sl_log_error (LOG_TAG ,
610
+ "Error setting granted keys of the node %d" ,
611
+ id_of_node );
612
+ return -1 ;
613
+ }
614
+
615
+ sl_log_debug (LOG_TAG , "Saved NLS state of the node %d" , id_of_node );
616
+ return 0 ;
617
+ }
618
+
619
+ // Consider the case as error where NLS state is sent as 0. The protocol
620
+ // should send only NLS enabled nodes.
621
+ return -1 ;
622
+ }
623
+
464
624
/************************* Our interface functions ****************************/
465
625
466
626
sl_status_t
0 commit comments