@@ -66,6 +66,10 @@ S2_is_peernode(struct S2* p_context, const s2_connection_t* peer);
66
66
#ifdef ZW_CONTROLLER
67
67
static void S2_send_nls_state_set (struct S2 * p_context , s2_connection_t * con , bool nls_active );
68
68
static 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 );
69
73
#endif /* ZW_CONTROLLER */
70
74
static void S2_send_nls_state_report (struct S2 * p_context , s2_connection_t * con );
71
75
static 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
1432
1436
if (cmd_length == SECURITY_2_V2_NLS_STATE_GET_LENGTH )
1433
1437
{
1434
1438
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
1435
1443
}
1436
1444
break ;
1437
1445
case NLS_STATE_SET_V2 :
@@ -1445,25 +1453,58 @@ static void S2_command_handler(struct S2* p_context, s2_connection_t* src, uint8
1445
1453
case NLS_STATE_REPORT_V2 :
1446
1454
if (cmd_length == SECURITY_2_V2_NLS_STATE_REPORT_LENGTH )
1447
1455
{
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 );
1451
1464
}
1452
1465
break ;
1453
1466
case NLS_NODE_LIST_GET_V2 :
1454
1467
if (cmd_length == SECURITY_2_V2_NLS_NODE_LIST_GET_LENGTH )
1455
1468
{
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
+ }
1457
1488
}
1458
1489
break ;
1459
1490
case NLS_NODE_LIST_REPORT_V2 :
1460
1491
if (cmd_length == SECURITY_2_V2_NLS_NODE_LIST_REPORT_LENGTH )
1461
1492
{
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
+ }
1467
1508
}
1468
1509
break ;
1469
1510
#endif // ZW_CONTROLLER
@@ -1612,6 +1653,51 @@ S2_fsm_post_event(struct S2* p_context, event_t e, event_data_t* d)
1612
1653
{
1613
1654
ctxt -> fsm = IDLE ;
1614
1655
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
1615
1701
}
1616
1702
else if (e == GOT_NONCE_REPORT && !S2_is_peernode (ctxt , d -> con ))
1617
1703
{
@@ -1882,6 +1968,22 @@ S2_is_send_data_multicast_busy(struct S2* p_context)
1882
1968
return ctxt -> fsm != IDLE ;
1883
1969
}
1884
1970
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
+
1885
1987
static void S2_send_nls_state_set (struct S2 * p_context , s2_connection_t * con , bool nls_active )
1886
1988
{
1887
1989
CTX_DEF
@@ -1905,16 +2007,44 @@ static void S2_send_nls_state_get(struct S2* p_context, s2_connection_t* con)
1905
2007
S2_send_data (ctxt , con , plain_text , SECURITY_2_V2_NLS_STATE_GET_LENGTH );
1906
2008
}
1907
2009
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 )
1909
2018
{
1910
2019
CTX_DEF
1911
2020
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 };
1918
2022
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