5757#define S2_NONCE_REPORT_MOS_SOS_INDEX 3
5858#define S2_NONCE_REPORT_MOS_SOS_MASK 0x3
5959
60+ // Number of nodes per byte in NLS state node mask
61+ #define NLS_ENABLED_NODES_PER_BYTE 8
62+
6063struct S2 * s2_ctx ;
6164
6265typedef enum { SINGLECAST , MULTICAST } zwave_s2_current_transmission_type_t ;
@@ -84,6 +87,17 @@ static s2_transport_session_state_t state = {};
8487static uint8_t secure_nif [ZWAVE_MAX_FRAME_SIZE ];
8588static uint8_t secure_nif_length ;
8689
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+
87101static uint8_t
88102 encapsulation_to_class (zwave_controller_encapsulation_scheme_t encap )
89103{
@@ -414,18 +428,17 @@ uint8_t S2_send_frame_multi(struct S2 *ctxt,
414428 0 );
415429}
416430
417-
418431void S2_notify_nls_state_report (node_t srcNode , uint8_t class_id , bool nls_capability , bool nls_state )
419432{
420433 (void )class_id ;
421434
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 );
423436
424437 if (zwave_store_nls_support ((zwave_node_id_t )srcNode ,
425- ( bool ) nls_capability ,
438+ nls_capability ,
426439 REPORTED_ATTRIBUTE )
427440 || zwave_store_nls_state ((zwave_node_id_t )srcNode ,
428- ( bool ) nls_state ,
441+ nls_state ,
429442 REPORTED_ATTRIBUTE )) {
430443 sl_log_error (LOG_TAG , "Error setting NLS attributes" );
431444 return ;
@@ -443,24 +456,171 @@ void S2_save_nls_state(void)
443456 // not relevant for ZPC
444457}
445458
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 )
447460{
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 ;
452472}
453473
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 )
455475{
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+
461566 return 0 ;
462567}
463568
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+
464624/************************* Our interface functions ****************************/
465625
466626sl_status_t
0 commit comments