@@ -110,6 +110,7 @@ static int8_t ws_bootstrap_neighbor_set(protocol_interface_info_entry_t *cur, pa
110
110
111
111
static void ws_bootstrap_candidate_table_reset (protocol_interface_info_entry_t * cur );
112
112
static 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 );
113
114
114
115
typedef enum {
115
116
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_
289
290
}
290
291
}
291
292
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
+
292
307
static int ws_bootstrap_tasklet_init (protocol_interface_info_entry_t * cur )
293
308
{
294
309
if (cur -> bootStrapId < 0 ) {
@@ -601,7 +616,6 @@ static int8_t ws_fhss_initialize(protocol_interface_info_entry_t *cur)
601
616
fhss_configuration .ws_bc_channel_function = (fhss_ws_channel_functions )cur -> ws_info -> cfg -> fhss .fhss_bc_channel_function ;
602
617
fhss_configuration .fhss_bc_dwell_interval = cur -> ws_info -> cfg -> fhss .fhss_bc_dwell_interval ;
603
618
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 ;
605
619
fhss_api = ns_fhss_ws_create (& fhss_configuration , cur -> ws_info -> fhss_timer_ptr );
606
620
607
621
if (!fhss_api ) {
@@ -765,7 +779,7 @@ static void ws_bootstrap_primary_parent_set(struct protocol_interface_info_entry
765
779
766
780
void ws_bootstrap_eapol_parent_synch (struct protocol_interface_info_entry * cur , llc_neighbour_req_t * neighbor_info )
767
781
{
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 ) {
769
783
return ;
770
784
}
771
785
@@ -820,6 +834,7 @@ static void ws_bootstrap_ll_address_validate(struct protocol_interface_info_entr
820
834
*/
821
835
uint16_t ws_etx_read (protocol_interface_info_entry_t * interface , addrtype_t addr_type , const uint8_t * addr_ptr )
822
836
{
837
+ uint16_t etx ;
823
838
824
839
if (!addr_ptr || !interface ) {
825
840
return 0 ;
@@ -839,7 +854,16 @@ uint16_t ws_etx_read(protocol_interface_info_entry_t *interface, addrtype_t addr
839
854
return 0xffff ;
840
855
}
841
856
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 ;
843
867
}
844
868
bool ws_bootstrap_nd_ns_transmit (protocol_interface_info_entry_t * cur , ipv6_neighbour_t * entry , bool unicast , uint8_t seq )
845
869
{
@@ -1152,7 +1176,7 @@ static void ws_bootstrap_pan_advertisement_analyse_active(struct protocol_interf
1152
1176
static parent_info_t * ws_bootstrap_candidate_parent_get_best (protocol_interface_info_entry_t * cur )
1153
1177
{
1154
1178
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 );
1156
1180
}
1157
1181
1158
1182
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_
1250
1274
} else {
1251
1275
// If there is no free entries always allocate the last one of reserved as it is the worst
1252
1276
entry = ns_list_get_last (& cur -> ws_info -> parent_list_reserved );
1253
- }
1254
- return entry ;
1255
- }
1256
1277
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
- }
1265
1278
}
1279
+ if (entry ) {
1280
+ entry -> tx_fail = 0 ;
1281
+ }
1282
+ return entry ;
1266
1283
}
1267
1284
1268
1285
static 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
1278
1295
return NULL ;
1279
1296
}
1280
1297
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
+
1281
1315
static bool ws_bootstrap_candidate_parent_compare (parent_info_t * p1 , parent_info_t * p2 )
1282
1316
{
1283
1317
// Return true if P2 is better
1284
1318
// signal lower than threshold for both
1285
1319
// pan_cost
1286
1320
// signal quality
1287
1321
1322
+ if (p2 -> tx_fail > p1 -> tx_fail ) {
1323
+ return false;
1324
+ }
1325
+
1288
1326
if (ws_neighbor_class_rsl_from_dbm_calculate (p1 -> signal_dbm ) < (DEVICE_MIN_SENS + CAND_PARENT_THRESHOLD + CAND_PARENT_HYSTERISIS ) &&
1289
1327
ws_neighbor_class_rsl_from_dbm_calculate (p2 -> signal_dbm ) > (DEVICE_MIN_SENS + CAND_PARENT_THRESHOLD + CAND_PARENT_HYSTERISIS )) {
1290
1328
// above threshold is always better than not.
@@ -1336,11 +1374,15 @@ static void ws_bootstrap_candidate_list_clean(struct protocol_interface_info_ent
1336
1374
1337
1375
static void ws_bootstrap_candidate_parent_sort (struct protocol_interface_info_entry * cur , parent_info_t * new_entry )
1338
1376
{
1377
+ //Remove from the list
1378
+
1339
1379
ns_list_foreach_safe (parent_info_t , entry , & cur -> ws_info -> parent_list_reserved ) {
1380
+
1340
1381
if (entry == new_entry ) {
1341
1382
// own entry skip it
1342
1383
continue ;
1343
1384
}
1385
+
1344
1386
if (ws_bootstrap_candidate_parent_compare (entry , new_entry )) {
1345
1387
// New entry is better
1346
1388
//tr_debug("candidate list new is better");
@@ -1550,7 +1592,6 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
1550
1592
}
1551
1593
1552
1594
if (neighbour_pointer_valid ) {
1553
- etx_lqi_dbm_update (cur -> id , data -> mpduLinkQuality , data -> signal_dbm , neighbor_info .neighbor -> index , neighbor_info .neighbor -> mac64 );
1554
1595
//Update Neighbor Broadcast and Unicast Parameters
1555
1596
ws_neighbor_class_neighbor_unicast_time_info_update (neighbor_info .ws_neighbor , ws_utt , data -> timestamp , (uint8_t * ) data -> SrcAddr );
1556
1597
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
1639
1680
1640
1681
llc_neighbour_req_t neighbor_info ;
1641
1682
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 );
1643
1683
ws_neighbor_class_neighbor_unicast_time_info_update (neighbor_info .ws_neighbor , ws_utt , data -> timestamp , (uint8_t * ) data -> SrcAddr );
1644
1684
ws_neighbor_class_neighbor_unicast_schedule_set (neighbor_info .ws_neighbor , ws_us , & cur -> ws_info -> hopping_schdule );
1645
1685
}
@@ -1901,14 +1941,6 @@ static bool ws_bootstrap_neighbor_info_request(struct protocol_interface_info_en
1901
1941
return false;
1902
1942
}
1903
1943
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
-
1912
1944
ws_bootstrap_neighbor_table_clean (interface );
1913
1945
1914
1946
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
1948
1980
ws_bootstrap_neighbor_delete (cur , entry_ptr );
1949
1981
}
1950
1982
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
+
1951
1992
static bool ws_neighbor_entry_nud_notify (mac_neighbor_table_entry_t * entry_ptr , void * user_data )
1952
1993
{
1953
1994
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,
2000
2041
nud_proces = activate_nud ;
2001
2042
} else if (etx_entry -> etx_samples < WS_NEIGHBOR_ETX_SAMPLE_MAX ) {
2002
2043
//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
2003
2049
//ETX Sample 0: random 1-8
2004
2050
//ETX Sample 1: random 2-16
2005
2051
//ETX Sample 2: random 4-32
2052
+
2006
2053
ws_bootsrap_create_ll_address (ll_address , entry_ptr -> mac64 );
2007
2054
if (!rpl_control_probe_parent_candidate (cur , ll_address )) {
2008
2055
return false;
2009
2056
}
2010
2057
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 ;
2013
2059
uint32_t time_block = 1 << etx_entry -> etx_samples ;
2060
+
2014
2061
if (time_from_start >= probe_period ) {
2015
2062
//tr_debug("Link Probe test %u Sample trig", etx_entry->etx_samples);
2016
2063
activate_nud = true;
@@ -2073,6 +2120,11 @@ int ws_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode)
2073
2120
return -1 ;
2074
2121
}
2075
2122
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
+
2076
2128
etx_max_update_set (WS_ETX_MAX_UPDATE );
2077
2129
etx_max_set (WS_ETX_MAX );
2078
2130
@@ -2182,8 +2234,6 @@ int ws_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode)
2182
2234
set_req .value_size = sizeof (bool );
2183
2235
cur -> mac_api -> mlme_req (cur -> mac_api , MLME_SET , & set_req );
2184
2236
2185
- mac_helper_mac_mlme_max_retry_set (cur -> id , WS_MAX_FRAME_RETRIES );
2186
-
2187
2237
// Set the default parameters for MPL
2188
2238
cur -> mpl_proactive_forwarding = true;
2189
2239
@@ -2443,7 +2493,8 @@ static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)
2443
2493
}
2444
2494
2445
2495
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 );
2447
2498
} else if (event == RPL_EVENT_LOCAL_REPAIR_NO_MORE_DIS ) {
2448
2499
/*
2449
2500
* 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,
2643
2694
ws_bootstrap_neighbor_set_stable (cur , entry -> mac64 );
2644
2695
//Copy fhss temporary data
2645
2696
* 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 );
2648
2697
mac_neighbor_table_trusted_neighbor (mac_neighbor_info (cur ), neigh_buffer .neighbor , true);
2649
2698
}
2650
2699
ws_llc_free_multicast_temp_entry (cur , entry );
@@ -2741,9 +2790,6 @@ static void ws_bootstrap_start_discovery(protocol_interface_info_entry_t *cur)
2741
2790
cur -> ws_info -> pan_timeout_timer = 0 ;
2742
2791
cur -> ws_info -> weakest_received_rssi = 0 ;
2743
2792
2744
- // Clear learned neighbours
2745
- ws_bootstrap_neighbor_list_clean (cur );
2746
-
2747
2793
// Clear learned candidate parents
2748
2794
ws_bootstrap_candidate_table_reset (cur );
2749
2795
@@ -2884,7 +2930,7 @@ static void ws_bootstrap_authentication_completed(protocol_interface_info_entry_
2884
2930
// eapol parent selected is not working
2885
2931
tr_debug ("authentication TX failed" );
2886
2932
2887
- ws_bootstrap_candidate_parent_free (cur , target_eui_64 );
2933
+ ws_bootstrap_candidate_parent_mark_failure (cur , target_eui_64 );
2888
2934
// Go back for network scanning
2889
2935
ws_bootstrap_state_change (cur , ER_ACTIVE_SCAN );
2890
2936
@@ -2906,7 +2952,7 @@ static void ws_bootstrap_authentication_completed(protocol_interface_info_entry_
2906
2952
2907
2953
static const uint8_t * ws_bootstrap_authentication_next_target (protocol_interface_info_entry_t * cur , const uint8_t * previous_eui_64 , uint16_t * pan_id )
2908
2954
{
2909
- ws_bootstrap_candidate_parent_free (cur , previous_eui_64 );
2955
+ ws_bootstrap_candidate_parent_mark_failure (cur , previous_eui_64 );
2910
2956
2911
2957
// Gets best target
2912
2958
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)
3262
3308
// Set PAE port to 10254 and authenticator relay to 10253 (and to own ll address)
3263
3309
ws_pae_controller_authenticator_start (cur , PAE_AUTH_SOCKET_PORT , ll_addr , EAPOL_RELAY_SOCKET_PORT );
3264
3310
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
+
3265
3314
ws_bootstrap_event_operation_start (cur );
3266
3315
break ;
3267
3316
}
3268
3317
ws_pae_controller_supp_init (cur );
3269
-
3318
+ // Clear learned neighbours
3319
+ ws_bootstrap_neighbor_list_clean (cur );
3270
3320
// Configure LLC for network discovery
3271
3321
ws_bootstrap_network_discovery_configure (cur );
3272
3322
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 );
3273
3325
// Start network scan
3274
3326
ws_bootstrap_start_discovery (cur );
3275
3327
break ;
0 commit comments