@@ -110,6 +110,7 @@ static int8_t ws_bootstrap_neighbor_set(protocol_interface_info_entry_t *cur, pa
110110
111111static void ws_bootstrap_candidate_table_reset (protocol_interface_info_entry_t * cur );
112112static parent_info_t * ws_bootstrap_candidate_parent_get (struct protocol_interface_info_entry * cur , const uint8_t * addr , bool create );
113+ static void ws_bootstrap_candidate_parent_sort (struct protocol_interface_info_entry * cur , parent_info_t * new_entry );
113114
114115typedef enum {
115116 WS_PARENT_SOFT_SYNCH = 0 , /**< let FHSS make decision if synchronization is needed*/
@@ -289,6 +290,20 @@ static void ws_bootstrap_address_notification_cb(struct protocol_interface_info_
289290 }
290291}
291292
293+ static void ws_bootstrap_configure_max_retries (protocol_interface_info_entry_t * cur , uint8_t max_mac_retries , uint8_t max_channel_retries )
294+ {
295+ mac_helper_mac_mlme_max_retry_set (cur -> id , max_mac_retries );
296+
297+ const fhss_ws_configuration_t * fhss_configuration_cur = ns_fhss_ws_configuration_get (cur -> ws_info -> fhss_api );
298+ if (fhss_configuration_cur && fhss_configuration_cur -> config_parameters .number_of_channel_retries != max_channel_retries ) {
299+ fhss_ws_configuration_t fhss_configuration ;
300+ memset (& fhss_configuration , 0 , sizeof (fhss_ws_configuration_t ));
301+ memcpy (& fhss_configuration , ns_fhss_ws_configuration_get (cur -> ws_info -> fhss_api ), sizeof (fhss_ws_configuration_t ));
302+ fhss_configuration .config_parameters .number_of_channel_retries = max_channel_retries ;
303+ ns_fhss_ws_configuration_set (cur -> ws_info -> fhss_api , & fhss_configuration );
304+ }
305+ }
306+
292307static int ws_bootstrap_tasklet_init (protocol_interface_info_entry_t * cur )
293308{
294309 if (cur -> bootStrapId < 0 ) {
@@ -601,7 +616,6 @@ static int8_t ws_fhss_initialize(protocol_interface_info_entry_t *cur)
601616 fhss_configuration .ws_bc_channel_function = (fhss_ws_channel_functions )cur -> ws_info -> cfg -> fhss .fhss_bc_channel_function ;
602617 fhss_configuration .fhss_bc_dwell_interval = cur -> ws_info -> cfg -> fhss .fhss_bc_dwell_interval ;
603618 fhss_configuration .fhss_broadcast_interval = cur -> ws_info -> cfg -> fhss .fhss_bc_interval ;
604- fhss_configuration .config_parameters .number_of_channel_retries = WS_NUMBER_OF_CHANNEL_RETRIES ;
605619 fhss_api = ns_fhss_ws_create (& fhss_configuration , cur -> ws_info -> fhss_timer_ptr );
606620
607621 if (!fhss_api ) {
@@ -765,7 +779,7 @@ static void ws_bootstrap_primary_parent_set(struct protocol_interface_info_entry
765779
766780void ws_bootstrap_eapol_parent_synch (struct protocol_interface_info_entry * cur , llc_neighbour_req_t * neighbor_info )
767781{
768- if (cur -> ws_info -> configuration_learned || !neighbor_info -> ws_neighbor -> broadcast_shedule_info_stored || !neighbor_info -> ws_neighbor -> broadcast_timing_info_stored ) {
782+ if (cur -> bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER || cur -> ws_info -> configuration_learned || !neighbor_info -> ws_neighbor -> broadcast_shedule_info_stored || !neighbor_info -> ws_neighbor -> broadcast_timing_info_stored ) {
769783 return ;
770784 }
771785
@@ -820,6 +834,7 @@ static void ws_bootstrap_ll_address_validate(struct protocol_interface_info_entr
820834 */
821835uint16_t ws_etx_read (protocol_interface_info_entry_t * interface , addrtype_t addr_type , const uint8_t * addr_ptr )
822836{
837+ uint16_t etx ;
823838
824839 if (!addr_ptr || !interface ) {
825840 return 0 ;
@@ -839,7 +854,16 @@ uint16_t ws_etx_read(protocol_interface_info_entry_t *interface, addrtype_t addr
839854 return 0xffff ;
840855 }
841856
842- return etx_local_etx_read (interface -> id , attribute_index );
857+ etx = etx_local_etx_read (interface -> id , attribute_index );
858+
859+ // If we dont have valid ETX for children we assume good ETX.
860+ // After enough packets is sent to children real calculated ETX is given.
861+ // This might result in ICMP source route errors returned to Border router causing secondary route uses
862+ if (etx == 0xffff && ipv6_neighbour_has_registered_by_eui64 (& interface -> ipv6_neighbour_cache , mac_neighbor -> mac64 )) {
863+ return 0x100 ;
864+ }
865+
866+ return etx ;
843867}
844868bool ws_bootstrap_nd_ns_transmit (protocol_interface_info_entry_t * cur , ipv6_neighbour_t * entry , bool unicast , uint8_t seq )
845869{
@@ -1152,7 +1176,7 @@ static void ws_bootstrap_pan_advertisement_analyse_active(struct protocol_interf
11521176static parent_info_t * ws_bootstrap_candidate_parent_get_best (protocol_interface_info_entry_t * cur )
11531177{
11541178 ns_list_foreach_safe (parent_info_t , entry , & cur -> ws_info -> parent_list_reserved ) {
1155- tr_info ("candidate list a:%s panid:%x cost:%d size:%d rssi:%d age:%" PRIu32 , trace_array (entry -> addr , 8 ), entry -> pan_id , entry -> pan_information .routing_cost , entry -> pan_information .pan_size , entry -> signal_dbm , protocol_core_monotonic_time - entry -> age );
1179+ tr_info ("candidate list a:%s panid:%x cost:%d size:%d rssi:%d txFailure:%u age:%" PRIu32 , trace_array (entry -> addr , 8 ), entry -> pan_id , entry -> pan_information .routing_cost , entry -> pan_information .pan_size , entry -> signal_dbm , entry -> tx_fail , protocol_core_monotonic_time - entry -> age );
11561180 }
11571181
11581182 return ns_list_get_first (& cur -> ws_info -> parent_list_reserved );
@@ -1250,19 +1274,12 @@ static parent_info_t *ws_bootstrap_candidate_parent_allocate(protocol_interface_
12501274 } else {
12511275 // If there is no free entries always allocate the last one of reserved as it is the worst
12521276 entry = ns_list_get_last (& cur -> ws_info -> parent_list_reserved );
1253- }
1254- return entry ;
1255- }
12561277
1257- static void ws_bootstrap_candidate_parent_free (protocol_interface_info_entry_t * cur , const uint8_t * addr )
1258- {
1259- ns_list_foreach_safe (parent_info_t , entry , & cur -> ws_info -> parent_list_reserved ) {
1260- if (memcmp (entry -> addr , addr , 8 ) == 0 ) {
1261- ns_list_remove (& cur -> ws_info -> parent_list_reserved , entry );
1262- ns_list_add_to_end (& cur -> ws_info -> parent_list_free , entry );
1263- return ;
1264- }
12651278 }
1279+ if (entry ) {
1280+ entry -> tx_fail = 0 ;
1281+ }
1282+ return entry ;
12661283}
12671284
12681285static parent_info_t * ws_bootstrap_candidate_parent_get (struct protocol_interface_info_entry * cur , const uint8_t * addr , bool create )
@@ -1278,13 +1295,34 @@ static parent_info_t *ws_bootstrap_candidate_parent_get(struct protocol_interfac
12781295 return NULL ;
12791296}
12801297
1298+ static void ws_bootstrap_candidate_parent_mark_failure (protocol_interface_info_entry_t * cur , const uint8_t * addr )
1299+ {
1300+ parent_info_t * entry = ws_bootstrap_candidate_parent_get (cur , addr , false);
1301+ if (entry ) {
1302+ ns_list_remove (& cur -> ws_info -> parent_list_reserved , entry );
1303+ if (entry -> tx_fail >= 2 ) {
1304+ ns_list_add_to_end (& cur -> ws_info -> parent_list_free , entry );
1305+ } else {
1306+ entry -> tx_fail ++ ;
1307+ //New last
1308+ ns_list_add_to_end (& cur -> ws_info -> parent_list_reserved , entry );
1309+ ws_bootstrap_candidate_parent_sort (cur , entry );
1310+ }
1311+
1312+ }
1313+ }
1314+
12811315static bool ws_bootstrap_candidate_parent_compare (parent_info_t * p1 , parent_info_t * p2 )
12821316{
12831317 // Return true if P2 is better
12841318 // signal lower than threshold for both
12851319 // pan_cost
12861320 // signal quality
12871321
1322+ if (p2 -> tx_fail > p1 -> tx_fail ) {
1323+ return false;
1324+ }
1325+
12881326 if (ws_neighbor_class_rsl_from_dbm_calculate (p1 -> signal_dbm ) < (DEVICE_MIN_SENS + CAND_PARENT_THRESHOLD + CAND_PARENT_HYSTERISIS ) &&
12891327 ws_neighbor_class_rsl_from_dbm_calculate (p2 -> signal_dbm ) > (DEVICE_MIN_SENS + CAND_PARENT_THRESHOLD + CAND_PARENT_HYSTERISIS )) {
12901328 // above threshold is always better than not.
@@ -1336,11 +1374,15 @@ static void ws_bootstrap_candidate_list_clean(struct protocol_interface_info_ent
13361374
13371375static void ws_bootstrap_candidate_parent_sort (struct protocol_interface_info_entry * cur , parent_info_t * new_entry )
13381376{
1377+ //Remove from the list
1378+
13391379 ns_list_foreach_safe (parent_info_t , entry , & cur -> ws_info -> parent_list_reserved ) {
1380+
13401381 if (entry == new_entry ) {
13411382 // own entry skip it
13421383 continue ;
13431384 }
1385+
13441386 if (ws_bootstrap_candidate_parent_compare (entry , new_entry )) {
13451387 // New entry is better
13461388 //tr_debug("candidate list new is better");
@@ -1550,7 +1592,6 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
15501592 }
15511593
15521594 if (neighbour_pointer_valid ) {
1553- etx_lqi_dbm_update (cur -> id , data -> mpduLinkQuality , data -> signal_dbm , neighbor_info .neighbor -> index , neighbor_info .neighbor -> mac64 );
15541595 //Update Neighbor Broadcast and Unicast Parameters
15551596 ws_neighbor_class_neighbor_unicast_time_info_update (neighbor_info .ws_neighbor , ws_utt , data -> timestamp , (uint8_t * ) data -> SrcAddr );
15561597 ws_neighbor_class_neighbor_unicast_schedule_set (neighbor_info .ws_neighbor , ws_us , & cur -> ws_info -> hopping_schdule );
@@ -1639,7 +1680,6 @@ static void ws_bootstrap_pan_config_solicit_analyse(struct protocol_interface_in
16391680
16401681 llc_neighbour_req_t neighbor_info ;
16411682 if (ws_bootstrap_neighbor_info_request (cur , data -> SrcAddr , & neighbor_info , false)) {
1642- etx_lqi_dbm_update (cur -> id , data -> mpduLinkQuality , data -> signal_dbm , neighbor_info .neighbor -> index , neighbor_info .neighbor -> mac64 );
16431683 ws_neighbor_class_neighbor_unicast_time_info_update (neighbor_info .ws_neighbor , ws_utt , data -> timestamp , (uint8_t * ) data -> SrcAddr );
16441684 ws_neighbor_class_neighbor_unicast_schedule_set (neighbor_info .ws_neighbor , ws_us , & cur -> ws_info -> hopping_schdule );
16451685 }
@@ -1901,14 +1941,6 @@ static bool ws_bootstrap_neighbor_info_request(struct protocol_interface_info_en
19011941 return false;
19021942 }
19031943
1904- uint8_t ll_target [16 ];
1905- ws_bootsrap_create_ll_address (ll_target , mac_64 );
1906-
1907- if (blacklist_reject (ll_target )) {
1908- // Rejected by blacklist
1909- return false;
1910- }
1911-
19121944 ws_bootstrap_neighbor_table_clean (interface );
19131945
19141946 neighbor_buffer -> neighbor = ws_bootstrap_mac_neighbor_add (interface , mac_64 );
@@ -1948,6 +1980,15 @@ static void ws_neighbor_entry_remove_notify(mac_neighbor_table_entry_t *entry_pt
19481980 ws_bootstrap_neighbor_delete (cur , entry_ptr );
19491981}
19501982
1983+ static uint32_t ws_probe_init_time_get (protocol_interface_info_entry_t * cur )
1984+ {
1985+ if (cur -> ws_info -> cfg -> gen .network_size <= NETWORK_SIZE_SMALL ) {
1986+ return WS_SMALL_PROBE_INIT_BASE_SECONDS ;
1987+ }
1988+
1989+ return WS_NORMAL_PROBE_INIT_BASE_SECONDS ;
1990+ }
1991+
19511992static bool ws_neighbor_entry_nud_notify (mac_neighbor_table_entry_t * entry_ptr , void * user_data )
19521993{
19531994 uint32_t time_from_start = entry_ptr -> link_lifetime - entry_ptr -> lifetime ;
@@ -2000,17 +2041,23 @@ static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr,
20002041 nud_proces = activate_nud ;
20012042 } else if (etx_entry -> etx_samples < WS_NEIGHBOR_ETX_SAMPLE_MAX ) {
20022043 //Take Random number for trig a prope.
2044+ //Small network
2045+ //ETX Sample 0: random 1-4
2046+ //ETX Sample 1: random 2-8
2047+ //ETX Sample 2: random 4-16
2048+ //Medium and large
20032049 //ETX Sample 0: random 1-8
20042050 //ETX Sample 1: random 2-16
20052051 //ETX Sample 2: random 4-32
2052+
20062053 ws_bootsrap_create_ll_address (ll_address , entry_ptr -> mac64 );
20072054 if (!rpl_control_probe_parent_candidate (cur , ll_address )) {
20082055 return false;
20092056 }
20102057
2011-
2012- uint32_t probe_period = WS_PROBE_INIT_BASE_SECONDS << etx_entry -> etx_samples ;
2058+ uint32_t probe_period = ws_probe_init_time_get (cur ) << etx_entry -> etx_samples ;
20132059 uint32_t time_block = 1 << etx_entry -> etx_samples ;
2060+
20142061 if (time_from_start >= probe_period ) {
20152062 //tr_debug("Link Probe test %u Sample trig", etx_entry->etx_samples);
20162063 activate_nud = true;
@@ -2073,6 +2120,11 @@ int ws_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode)
20732120 return -1 ;
20742121 }
20752122
2123+ if (!etx_allow_drop_for_poor_measurements (WS_ETX_BAD_INIT_LINK_LEVEL , WS_ETX_MAX_BAD_LINK_DROP )) {
2124+ etx_storage_list_allocate (cur -> id , 0 );
2125+ return -1 ;
2126+ }
2127+
20762128 etx_max_update_set (WS_ETX_MAX_UPDATE );
20772129 etx_max_set (WS_ETX_MAX );
20782130
@@ -2182,8 +2234,6 @@ int ws_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode)
21822234 set_req .value_size = sizeof (bool );
21832235 cur -> mac_api -> mlme_req (cur -> mac_api , MLME_SET , & set_req );
21842236
2185- mac_helper_mac_mlme_max_retry_set (cur -> id , WS_MAX_FRAME_RETRIES );
2186-
21872237 // Set the default parameters for MPL
21882238 cur -> mpl_proactive_forwarding = true;
21892239
@@ -2443,7 +2493,8 @@ static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)
24432493 }
24442494
24452495 ws_set_fhss_hop (cur );
2446-
2496+ // Set retry configuration for bootstrap ready state
2497+ ws_bootstrap_configure_max_retries (cur , WS_MAX_FRAME_RETRIES , WS_NUMBER_OF_CHANNEL_RETRIES );
24472498 } else if (event == RPL_EVENT_LOCAL_REPAIR_NO_MORE_DIS ) {
24482499 /*
24492500 * RPL goes to passive mode, but does not require any extra changed
@@ -2643,8 +2694,6 @@ static bool ws_rpl_new_parent_callback(uint8_t *ll_parent_address, void *handle,
26432694 ws_bootstrap_neighbor_set_stable (cur , entry -> mac64 );
26442695 //Copy fhss temporary data
26452696 * ws_neigh = entry -> neigh_info_list ;
2646- //ETX Create here
2647- etx_lqi_dbm_update (cur -> id , entry -> mpduLinkQuality , entry -> signal_dbm , neigh_buffer .neighbor -> index , neigh_buffer .neighbor -> mac64 );
26482697 mac_neighbor_table_trusted_neighbor (mac_neighbor_info (cur ), neigh_buffer .neighbor , true);
26492698 }
26502699 ws_llc_free_multicast_temp_entry (cur , entry );
@@ -2741,9 +2790,6 @@ static void ws_bootstrap_start_discovery(protocol_interface_info_entry_t *cur)
27412790 cur -> ws_info -> pan_timeout_timer = 0 ;
27422791 cur -> ws_info -> weakest_received_rssi = 0 ;
27432792
2744- // Clear learned neighbours
2745- ws_bootstrap_neighbor_list_clean (cur );
2746-
27472793 // Clear learned candidate parents
27482794 ws_bootstrap_candidate_table_reset (cur );
27492795
@@ -2884,7 +2930,7 @@ static void ws_bootstrap_authentication_completed(protocol_interface_info_entry_
28842930 // eapol parent selected is not working
28852931 tr_debug ("authentication TX failed" );
28862932
2887- ws_bootstrap_candidate_parent_free (cur , target_eui_64 );
2933+ ws_bootstrap_candidate_parent_mark_failure (cur , target_eui_64 );
28882934 // Go back for network scanning
28892935 ws_bootstrap_state_change (cur , ER_ACTIVE_SCAN );
28902936
@@ -2906,7 +2952,7 @@ static void ws_bootstrap_authentication_completed(protocol_interface_info_entry_
29062952
29072953static const uint8_t * ws_bootstrap_authentication_next_target (protocol_interface_info_entry_t * cur , const uint8_t * previous_eui_64 , uint16_t * pan_id )
29082954{
2909- ws_bootstrap_candidate_parent_free (cur , previous_eui_64 );
2955+ ws_bootstrap_candidate_parent_mark_failure (cur , previous_eui_64 );
29102956
29112957 // Gets best target
29122958 parent_info_t * parent_info = ws_bootstrap_candidate_parent_get_best (cur );
@@ -3262,14 +3308,20 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
32623308 // Set PAE port to 10254 and authenticator relay to 10253 (and to own ll address)
32633309 ws_pae_controller_authenticator_start (cur , PAE_AUTH_SOCKET_PORT , ll_addr , EAPOL_RELAY_SOCKET_PORT );
32643310
3311+ // Set retry configuration for bootstrap ready state
3312+ ws_bootstrap_configure_max_retries (cur , WS_MAX_FRAME_RETRIES , WS_NUMBER_OF_CHANNEL_RETRIES );
3313+
32653314 ws_bootstrap_event_operation_start (cur );
32663315 break ;
32673316 }
32683317 ws_pae_controller_supp_init (cur );
3269-
3318+ // Clear learned neighbours
3319+ ws_bootstrap_neighbor_list_clean (cur );
32703320 // Configure LLC for network discovery
32713321 ws_bootstrap_network_discovery_configure (cur );
32723322 ws_bootstrap_fhss_activate (cur );
3323+ // Set retry configuration for discovery state
3324+ ws_bootstrap_configure_max_retries (cur , WS_MAX_FRAME_RETRIES_BOOTSTRAP , WS_NUMBER_OF_CHANNEL_RETRIES_BOOTSTRAP );
32733325 // Start network scan
32743326 ws_bootstrap_start_discovery (cur );
32753327 break ;
0 commit comments