@@ -66,6 +66,10 @@ S2_is_peernode(struct S2* p_context, const s2_connection_t* peer);
6666#ifdef ZW_CONTROLLER
6767static void S2_send_nls_state_set (struct S2 * p_context , s2_connection_t * con , bool nls_active );
6868static void S2_send_nls_state_get (struct S2 * p_context , s2_connection_t * con );
69+ static void S2_prepare_nls_node_list_get (uint8_t * buf , bool request );
70+ static void S2_send_nls_node_list_get (struct S2 * p_context , s2_connection_t * con , bool request );
71+ static void S2_prepare_nls_node_list_report (uint8_t * buf , bool is_last_node , uint16_t node_id , uint8_t granted_keys , uint8_t nls_state );
72+ static void S2_send_nls_node_list_report (struct S2 * p_context , s2_connection_t * con , bool is_last_node , uint16_t node_id , uint8_t granted_keys , uint8_t nls_state );
6973#endif /* ZW_CONTROLLER */
7074static void S2_send_nls_state_report (struct S2 * p_context , s2_connection_t * con );
7175static void S2_command_handler (struct S2 * p_context , s2_connection_t * src , uint8_t * cmd , uint16_t cmd_length );
@@ -1432,6 +1436,10 @@ static void S2_command_handler(struct S2* p_context, s2_connection_t* src, uint8
14321436 if (cmd_length == SECURITY_2_V2_NLS_STATE_GET_LENGTH )
14331437 {
14341438 S2_send_nls_state_report (ctxt , src );
1439+ #ifdef ZW_CONTROLLER
1440+ ctxt -> delayed_transmission_flags .send_nls_node_list_get = 1 ;
1441+ ctxt -> delayed_transmission_cache .get_nls_node_list .request = 0 ; // request first node
1442+ #endif
14351443 }
14361444 break ;
14371445 case NLS_STATE_SET_V2 :
@@ -1445,25 +1453,58 @@ static void S2_command_handler(struct S2* p_context, s2_connection_t* src, uint8
14451453 case NLS_STATE_REPORT_V2 :
14461454 if (cmd_length == SECURITY_2_V2_NLS_STATE_REPORT_LENGTH )
14471455 {
1448- S2_notify_nls_state_report (src -> r_node , src -> class_id ,
1449- cmd [SECURITY_2_V2_NLS_STATE_REPORT_BITFIELD_POS ] & SECURITY_2_V2_NLS_STATE_REPORT_CAPABILITY_FIELD ,
1450- cmd [SECURITY_2_V2_NLS_STATE_REPORT_BITFIELD_POS ] & SECURITY_2_V2_NLS_STATE_REPORT_STATE_FIELD );
1456+ bool capability = (cmd [SECURITY_2_V2_NLS_STATE_REPORT_BITFIELD_POS ] & SECURITY_2_V2_NLS_STATE_REPORT_CAPABILITY_FIELD ) ? true : false;
1457+ bool state = (cmd [SECURITY_2_V2_NLS_STATE_REPORT_BITFIELD_POS ] & SECURITY_2_V2_NLS_STATE_REPORT_STATE_FIELD ) ? true : false;
1458+
1459+ if (state ) {
1460+ ctxt -> nls_state = 1 ; // There is at least one an NLS-enabled node in the network
1461+ }
1462+
1463+ S2_notify_nls_state_report (src -> r_node , src -> class_id , capability , state );
14511464 }
14521465 break ;
14531466 case NLS_NODE_LIST_GET_V2 :
14541467 if (cmd_length == SECURITY_2_V2_NLS_NODE_LIST_GET_LENGTH )
14551468 {
1456- S2_nls_node_list_get (src -> l_node , src -> class_id , cmd [SECURITY_2_V2_NLS_NODE_LIST_GET_REQUEST_POS ]);
1469+ bool is_last_node = false;
1470+ uint16_t node_id = 0 ;
1471+ uint8_t granted_keys = 0 ;
1472+ bool nls_state = false;
1473+ uint8_t retval ;
1474+ bool request = (cmd [SECURITY_2_V2_NLS_NODE_LIST_GET_REQUEST_POS ] == 1 ) ? true : false;
1475+
1476+ retval = S2_get_nls_node_list (src -> r_node , request , & is_last_node , & node_id , & granted_keys , & nls_state );
1477+ if (nls_state && retval == 0 ) {
1478+ if (S2_is_send_data_busy (ctxt )) {
1479+ ctxt -> delayed_transmission_flags .send_nls_node_list_report = 1 ;
1480+ ctxt -> delayed_transmission_cache .nls_node_report .is_last_node = (uint8_t )is_last_node ;
1481+ ctxt -> delayed_transmission_cache .nls_node_report .node_id = node_id ;
1482+ ctxt -> delayed_transmission_cache .nls_node_report .granted_keys = granted_keys ;
1483+ ctxt -> delayed_transmission_cache .nls_node_report .nls_state = (uint8_t )nls_state ;
1484+ } else {
1485+ S2_send_nls_node_list_report (ctxt , src , is_last_node , node_id , granted_keys , nls_state );
1486+ }
1487+ }
14571488 }
14581489 break ;
14591490 case NLS_NODE_LIST_REPORT_V2 :
14601491 if (cmd_length == SECURITY_2_V2_NLS_NODE_LIST_REPORT_LENGTH )
14611492 {
1462- S2_nls_node_list_report (src -> l_node , src -> class_id ,
1463- cmd [SECURITY_2_V2_NLS_NODE_LIST_REPORT_LAST_NODE_POS ],
1464- (uint16_t ) (cmd [SECURITY_2_V2_NLS_NODE_LIST_REPORT_NODE_ID_MSB_POS ] << 8 | cmd [SECURITY_2_V2_NLS_NODE_LIST_REPORT_NODE_ID_LSB_POS ]),
1465- cmd [SECURITY_2_V2_NLS_NODE_LIST_REPORT_GRANTED_KEYS_POS ],
1466- cmd [SECURITY_2_V2_NLS_NODE_LIST_REPORT_NLS_STATE_POS ]);
1493+ bool is_last_node = (cmd [SECURITY_2_V2_NLS_NODE_LIST_REPORT_LAST_NODE_POS ] & SECURITY_2_V2_NLS_NODE_LIST_REPORT_LAST_NODE_FIELD ) ? true : false;
1494+ bool nls_state = (cmd [SECURITY_2_V2_NLS_NODE_LIST_REPORT_NLS_STATE_POS ] != 0 ) ? true : false;
1495+
1496+ int8_t retval = S2_notify_nls_node_list_report (src -> r_node ,
1497+ (uint16_t )(cmd [SECURITY_2_V2_NLS_NODE_LIST_REPORT_NODE_ID_MSB_POS ] << 8 | cmd [SECURITY_2_V2_NLS_NODE_LIST_REPORT_NODE_ID_LSB_POS ]),
1498+ cmd [SECURITY_2_V2_NLS_NODE_LIST_REPORT_GRANTED_KEYS_POS ],
1499+ nls_state );
1500+ if (!is_last_node && retval == 0 ) {
1501+ if (S2_is_send_data_busy (ctxt )) {
1502+ ctxt -> delayed_transmission_flags .send_nls_node_list_get = 1 ;
1503+ ctxt -> delayed_transmission_cache .get_nls_node_list .request = 1 ; // request next node
1504+ } else {
1505+ S2_send_nls_node_list_get (ctxt , src , true);
1506+ }
1507+ }
14671508 }
14681509 break ;
14691510#endif // ZW_CONTROLLER
@@ -1612,6 +1653,51 @@ S2_fsm_post_event(struct S2* p_context, event_t e, event_data_t* d)
16121653 {
16131654 ctxt -> fsm = IDLE ;
16141655 S2_post_send_done_event (ctxt , d -> d .tx .status );
1656+ #ifdef ZW_CONTROLLER
1657+ if (ctxt -> delayed_transmission_flags .send_nls_node_list_get && ctxt -> nls_state )
1658+ {
1659+ ctxt -> delayed_transmission_flags .send_nls_node_list_get = 0 ;
1660+
1661+ uint8_t buf [SECURITY_2_V2_NLS_NODE_LIST_GET_LENGTH ] = { 0 };
1662+
1663+ S2_prepare_nls_node_list_get (
1664+ buf ,
1665+ ctxt -> delayed_transmission_cache .get_nls_node_list .request );
1666+
1667+ ctxt -> buf = buf ;
1668+ ctxt -> length = sizeof (buf );
1669+
1670+ // Clear cache
1671+ ctxt -> delayed_transmission_cache .get_nls_node_list .request = 0 ;
1672+
1673+ goto send_msg_state_enter ;
1674+ }
1675+
1676+ if (ctxt -> delayed_transmission_flags .send_nls_node_list_report && ctxt -> nls_state )
1677+ {
1678+ ctxt -> delayed_transmission_flags .send_nls_node_list_report = 0 ;
1679+
1680+ uint8_t buf [SECURITY_2_V2_NLS_NODE_LIST_REPORT_LENGTH ] = { 0 };
1681+
1682+ S2_prepare_nls_node_list_report (
1683+ buf ,
1684+ ctxt -> delayed_transmission_cache .nls_node_report .is_last_node ,
1685+ ctxt -> delayed_transmission_cache .nls_node_report .node_id ,
1686+ ctxt -> delayed_transmission_cache .nls_node_report .granted_keys ,
1687+ ctxt -> delayed_transmission_cache .nls_node_report .nls_state );
1688+
1689+ ctxt -> buf = buf ;
1690+ ctxt -> length = sizeof (buf );
1691+
1692+ // Clear cache
1693+ ctxt -> delayed_transmission_cache .nls_node_report .is_last_node = 0 ;
1694+ ctxt -> delayed_transmission_cache .nls_node_report .node_id = 0 ;
1695+ ctxt -> delayed_transmission_cache .nls_node_report .granted_keys = 0 ;
1696+ ctxt -> delayed_transmission_cache .nls_node_report .nls_state = 0 ;
1697+
1698+ goto send_msg_state_enter ;
1699+ }
1700+ #endif
16151701 }
16161702 else if (e == GOT_NONCE_REPORT && !S2_is_peernode (ctxt , d -> con ))
16171703 {
@@ -1882,6 +1968,22 @@ S2_is_send_data_multicast_busy(struct S2* p_context)
18821968 return ctxt -> fsm != IDLE ;
18831969}
18841970
1971+ static void S2_send_nls_state_report (struct S2 * p_context , s2_connection_t * con )
1972+ {
1973+ CTX_DEF
1974+
1975+ uint8_t plain_text [SECURITY_2_V2_NLS_STATE_REPORT_LENGTH ] = { 0 };
1976+ uint8_t nls_bitfield ;
1977+ nls_bitfield = SECURITY_2_V2_NLS_STATE_REPORT_CAPABILITY_FIELD | (ctxt -> nls_state ? SECURITY_2_V2_NLS_STATE_REPORT_STATE_FIELD : 0 ); // A node sending this frame will always support NLS
1978+ plain_text [SECURITY_2_COMMAND_CLASS_POS ] = COMMAND_CLASS_SECURITY_2_V2 ;
1979+ plain_text [SECURITY_2_COMMAND_POS ] = NLS_STATE_REPORT_V2 ;
1980+ plain_text [SECURITY_2_V2_NLS_STATE_REPORT_BITFIELD_POS ] = nls_bitfield ;
1981+
1982+ S2_send_data (ctxt , con , plain_text , SECURITY_2_V2_NLS_STATE_REPORT_LENGTH );
1983+ }
1984+
1985+ #ifdef ZW_CONTROLLER
1986+
18851987static void S2_send_nls_state_set (struct S2 * p_context , s2_connection_t * con , bool nls_active )
18861988{
18871989 CTX_DEF
@@ -1905,16 +2007,44 @@ static void S2_send_nls_state_get(struct S2* p_context, s2_connection_t* con)
19052007 S2_send_data (ctxt , con , plain_text , SECURITY_2_V2_NLS_STATE_GET_LENGTH );
19062008}
19072009
1908- static void S2_send_nls_state_report (struct S2 * p_context , s2_connection_t * con )
2010+ static void S2_prepare_nls_node_list_get (uint8_t * buf , bool request )
2011+ {
2012+ buf [SECURITY_2_COMMAND_CLASS_POS ] = COMMAND_CLASS_SECURITY_2_V2 ;
2013+ buf [SECURITY_2_COMMAND_POS ] = NLS_NODE_LIST_GET_V2 ;
2014+ buf [SECURITY_2_V2_NLS_NODE_LIST_GET_REQUEST_POS ] = (uint8_t )request ;
2015+ }
2016+
2017+ static void S2_send_nls_node_list_get (struct S2 * p_context , s2_connection_t * con , bool request )
19092018{
19102019 CTX_DEF
19112020
1912- uint8_t plain_text [SECURITY_2_V2_NLS_STATE_REPORT_LENGTH ] = { 0 };
1913- uint8_t nls_bitfield ;
1914- nls_bitfield = SECURITY_2_V2_NLS_STATE_REPORT_CAPABILITY_FIELD | (ctxt -> nls_state ? SECURITY_2_V2_NLS_STATE_REPORT_STATE_FIELD : 0 ); // A node sending this frame will always support NLS
1915- plain_text [SECURITY_2_COMMAND_CLASS_POS ] = COMMAND_CLASS_SECURITY_2_V2 ;
1916- plain_text [SECURITY_2_COMMAND_POS ] = NLS_STATE_REPORT_V2 ;
1917- plain_text [SECURITY_2_V2_NLS_STATE_REPORT_BITFIELD_POS ] = nls_bitfield ;
2021+ uint8_t buf [SECURITY_2_V2_NLS_NODE_LIST_GET_LENGTH ] = { 0 };
19182022
1919- S2_send_data (ctxt , con , plain_text , SECURITY_2_V2_NLS_STATE_REPORT_LENGTH );
1920- }
2023+ S2_prepare_nls_node_list_get (buf , request );
2024+
2025+ S2_send_data (ctxt , con , buf , SECURITY_2_V2_NLS_NODE_LIST_GET_LENGTH );
2026+ }
2027+
2028+ static void S2_prepare_nls_node_list_report (uint8_t * buf , bool is_last_node , uint16_t node_id , uint8_t granted_keys , uint8_t nls_state )
2029+ {
2030+ buf [SECURITY_2_COMMAND_CLASS_POS ] = COMMAND_CLASS_SECURITY_2_V2 ;
2031+ buf [SECURITY_2_COMMAND_POS ] = NLS_NODE_LIST_REPORT_V2 ;
2032+ buf [SECURITY_2_V2_NLS_NODE_LIST_REPORT_LAST_NODE_POS ] = (uint8_t )is_last_node ;
2033+ buf [SECURITY_2_V2_NLS_NODE_LIST_REPORT_NODE_ID_MSB_POS ] = (node_id >> 8 ) & 0xFF ;
2034+ buf [SECURITY_2_V2_NLS_NODE_LIST_REPORT_NODE_ID_LSB_POS ] = (node_id >> 0 ) & 0xFF ;
2035+ buf [SECURITY_2_V2_NLS_NODE_LIST_REPORT_GRANTED_KEYS_POS ] = granted_keys ;
2036+ buf [SECURITY_2_V2_NLS_NODE_LIST_REPORT_NLS_STATE_POS ] = nls_state ;
2037+ }
2038+
2039+ static void S2_send_nls_node_list_report (struct S2 * p_context , s2_connection_t * con , bool is_last_node , uint16_t node_id , uint8_t granted_keys , uint8_t nls_state )
2040+ {
2041+ CTX_DEF
2042+
2043+ uint8_t buf [SECURITY_2_V2_NLS_NODE_LIST_REPORT_LENGTH ] = { 0 };
2044+
2045+ S2_prepare_nls_node_list_report (buf , is_last_node , node_id , granted_keys , nls_state );
2046+
2047+ S2_send_data (ctxt , con , buf , SECURITY_2_V2_NLS_NODE_LIST_REPORT_LENGTH );
2048+ }
2049+
2050+ #endif
0 commit comments