@@ -98,6 +98,8 @@ static ws_nud_table_entry_t *ws_nud_entry_discover(protocol_interface_info_entry
9898static void ws_nud_entry_remove (protocol_interface_info_entry_t * cur , mac_neighbor_table_entry_t * entry_ptr );
9999static bool ws_neighbor_entry_nud_notify (mac_neighbor_table_entry_t * entry_ptr , void * user_data );
100100
101+ static void ws_address_registration_update (protocol_interface_info_entry_t * interface , const uint8_t addr [16 ]);
102+
101103
102104static void ws_bootstrap_candidate_table_reset (protocol_interface_info_entry_t * cur );
103105static parent_info_t * ws_bootstrap_candidate_parent_get (struct protocol_interface_info_entry * cur , const uint8_t * addr , bool create );
@@ -161,7 +163,7 @@ static void ws_bootstrap_address_notification_cb(struct protocol_interface_info_
161163 //Trig Address Registartion only when Bootstrap is ready
162164 if (interface -> nwk_bootstrap_state == ER_BOOTSRAP_DONE && addr -> source != ADDR_SOURCE_DHCP ) {
163165 tr_debug ("Address registration %s" , trace_ipv6 (addr -> address ));
164- rpl_control_register_address (interface , addr -> address );
166+ ws_address_registration_update (interface , addr -> address );
165167 }
166168 if (addr_ipv6_scope (addr -> address , interface ) > IPV6_SCOPE_LINK_LOCAL ) {
167169 // at least ula address available inside mesh.
@@ -192,7 +194,7 @@ static void ws_bootstrap_address_notification_cb(struct protocol_interface_info_
192194 if (addr -> source != ADDR_SOURCE_DHCP ) {
193195 tr_debug ("Address Re registration %s" , trace_ipv6 (addr -> address ));
194196 //Register
195- rpl_control_register_address (interface , addr -> address );
197+ ws_address_registration_update (interface , addr -> address );
196198 }
197199 }
198200}
@@ -1622,12 +1624,19 @@ static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr,
16221624
16231625 if (time_from_start > WS_NEIGHBOR_NUD_TIMEOUT ) {
16241626
1625- if (ipv6_neighbour_has_registered_by_eui64 (& cur -> ipv6_neighbour_cache , entry_ptr -> mac64 )) {
1626- // This is our child with valid ARO registration Change link timeout to future we check at 2 minute intervals
1627- entry_ptr -> lifetime = entry_ptr -> lifetime + 120 ;
1628- if (entry_ptr -> lifetime > entry_ptr -> link_lifetime ) {
1629- entry_ptr -> lifetime = entry_ptr -> link_lifetime ;
1630- }
1627+ /* For parents ARO registration is sent in link timeout times
1628+ * For candidate parents NUD is needed
1629+ * For children NUD is sent only at very close to end
1630+ */
1631+ if (ipv6_neighbour_has_registered_by_eui64 (& cur -> ipv6_neighbour_cache , entry_ptr -> mac64 ) &&
1632+ (time_from_start < WS_NEIGHBOR_NUD_TIMEOUT * 1.8 )) {
1633+ /* This is our child with valid ARO registration send NUD if we are close to delete
1634+ *
1635+ * if ARO was received link is considered active so this is only in case of very long ARO registration times
1636+ *
1637+ * 1.8 means with link timeout of 30 minutes that NUD is sent 6 minutes before timeout
1638+ *
1639+ */
16311640 return false;
16321641 }
16331642
@@ -1993,10 +2002,33 @@ static void ws_set_fhss_hop(protocol_interface_info_entry_t *cur)
19932002 tr_debug ("own hop: %u, own rank: %u, rank inc: %u" , own_hop , own_rank , rank_inc );
19942003}
19952004
1996- static void ws_address_registration_update (protocol_interface_info_entry_t * interface )
2005+ static void ws_address_registration_update (protocol_interface_info_entry_t * interface , const uint8_t addr [16 ])
2006+ {
2007+ rpl_control_register_address (interface , addr );
2008+ // Timer is used only to track full registrations
2009+
2010+ if (addr != NULL && interface -> ws_info -> aro_registration_timer ) {
2011+ // Single address update and timer is running
2012+ return ;
2013+ }
2014+
2015+ if (interface -> ws_info -> aro_registration_timer == 0 ) {
2016+ // Timer expired and check if we have valid address to register
2017+ ns_list_foreach (if_address_entry_t , address , & interface -> ip_addresses ) {
2018+ if (!addr_is_ipv6_link_local (address -> address )) {
2019+ // We have still valid addresses let the timer run for next period
2020+ tr_info ("ARO registration timer start" );
2021+ interface -> ws_info -> aro_registration_timer = WS_NEIGHBOR_NUD_TIMEOUT ;
2022+ return ;
2023+ }
2024+ }
2025+ }
2026+ }
2027+
2028+ static void ws_address_parent_update (protocol_interface_info_entry_t * interface )
19972029{
1998- rpl_control_register_address (interface , NULL );
19992030 tr_info ("RPL parent update ... register ARO" );
2031+ ws_address_registration_update (interface , NULL );
20002032}
20012033
20022034static void ws_bootstrap_rpl_callback (rpl_event_t event , void * handle )
@@ -2042,7 +2074,7 @@ static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)
20422074 */
20432075
20442076 } else if (event == RPL_EVENT_DAO_PARENT_ADD ) {
2045- ws_address_registration_update (cur );
2077+ ws_address_parent_update (cur );
20462078 }
20472079 cur -> ws_info -> rpl_state = event ;
20482080 tr_info ("RPL event %d" , event );
@@ -2057,7 +2089,7 @@ static void ws_dhcp_client_global_adress_cb(int8_t interface, uint8_t dhcp_addr[
20572089 if (register_status ) {
20582090 protocol_interface_info_entry_t * cur = protocol_stack_interface_info_get_by_id (interface );
20592091 if (cur ) {
2060- rpl_control_register_address (cur , prefix );
2092+ ws_address_registration_update (cur , prefix );
20612093 }
20622094 } else {
20632095 //Delete dhcpv6 client
@@ -2283,6 +2315,7 @@ static void ws_bootstrap_rpl_activate(protocol_interface_info_entry_t *cur)
22832315 rpl_control_process_routes (protocol_6lowpan_rpl_domain , false); // Wi-SUN assumes that no default route needed
22842316 rpl_control_request_parent_link_confirmation (true);
22852317 rpl_control_set_dio_multicast_min_config_advertisment_count (WS_MIN_DIO_MULTICAST_CONFIG_ADVERTISMENT_COUNT );
2318+ rpl_control_set_address_registration_timeout ((WS_NEIGHBOR_LINK_TIMEOUT / 60 ) + 1 );
22862319 rpl_control_set_dao_retry_count (WS_MAX_DAO_RETRIES );
22872320 rpl_control_set_initial_dao_ack_wait (WS_MAX_DAO_INITIAL_TIMEOUT );
22882321 rpl_control_set_mrhof_parent_set_size (WS_MAX_PARENT_SET_COUNT );
@@ -3083,6 +3116,16 @@ void ws_bootstrap_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t s
30833116 ws_bootstrap_event_discovery_start (cur );
30843117 }
30853118 }
3119+ if (cur -> ws_info -> aro_registration_timer ) {
3120+ if (cur -> ws_info -> aro_registration_timer > seconds ) {
3121+ cur -> ws_info -> aro_registration_timer -= seconds ;
3122+ } else {
3123+ // Update all addressess. This function will update the timer value if needed
3124+ cur -> ws_info -> aro_registration_timer = 0 ;
3125+ ws_address_registration_update (cur , NULL );
3126+ }
3127+ }
3128+
30863129}
30873130
30883131void ws_primary_parent_update (protocol_interface_info_entry_t * interface , mac_neighbor_table_entry_t * neighbor )
@@ -3105,7 +3148,7 @@ void ws_secondary_parent_update(protocol_interface_info_entry_t *interface)
31053148 if (interface -> ws_info ) {
31063149 ns_list_foreach (if_address_entry_t , address , & interface -> ip_addresses ) {
31073150 if (!addr_is_ipv6_link_local (address -> address )) {
3108- ws_address_registration_update (interface );
3151+ ws_address_parent_update (interface );
31093152 }
31103153 }
31113154 }
0 commit comments