From 8a8b407c47d88e438ccb59e14a9280d704d464ea Mon Sep 17 00:00:00 2001 From: Mika Tervonen Date: Wed, 28 Apr 2021 16:16:49 +0300 Subject: [PATCH] Add RSL check for ETX Calculation for RPL parent selection Separate Wi-SUN ETX function so that all ETX checks have same validation Remove all direct calls to etx_local_etx_read function and replace with Wi-SUN version. Remove check for 0 ack from etx_local_etx_read as it is ok to run the ETX Calculation through even if first probe fails --- CHANGELOG.md | 1 + nanostack/ws_management_api.h | 4 +++- source/6LoWPAN/ws/ws_bootstrap.c | 35 +++++++++++++++++++++++--------- source/Service_Libs/etx/etx.c | 5 ----- 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e6dfe7b1f63..dc6cb1e17c69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Release vXX.X.X ### Features +* Filter RPL parents based on DEVICE_MIN_SENS configuration with Threshold and Hysteresis. * Filter EAPOL parents based on DEVICE_MIN_SENS configuration with Threshold and Hysteresis to prevent EAPOL failures caused by bad signal levels ### Changes diff --git a/nanostack/ws_management_api.h b/nanostack/ws_management_api.h index 92f7cb1bd8de..0d2d75c99bbb 100644 --- a/nanostack/ws_management_api.h +++ b/nanostack/ws_management_api.h @@ -861,7 +861,9 @@ int ws_neighbor_info_get( * level higher than device_min_sens + CAND_PARENT_THRESHOLD + CAND_PARENT_HYSTERESIS * to start authentication. * - * NOTE: Currently not using this value to limit parents as it is only RECOMENDED in specification. + * ETX Calculation gives a maximum ETX if two way EWMA RSL is less than + * device_min_sens + CAND_PARENT_THRESHOLD + CAND_PARENT_HYSTERESIS to + * prevent selecting parents with poor signal quality * * \param interface_id Network interface ID. * \param device_min_sens value used in the parent selections. diff --git a/source/6LoWPAN/ws/ws_bootstrap.c b/source/6LoWPAN/ws/ws_bootstrap.c index 19f4aed8e5e5..830e839c5aff 100644 --- a/source/6LoWPAN/ws/ws_bootstrap.c +++ b/source/6LoWPAN/ws/ws_bootstrap.c @@ -909,17 +909,17 @@ static void ws_bootstrap_ll_address_validate(struct protocol_interface_info_entr * \return 0x0000 address unknown or other error * \return 0x0001 no ETX statistics on this interface */ -uint16_t ws_etx_read(protocol_interface_info_entry_t *interface, addrtype_t addr_type, const uint8_t *addr_ptr) +uint16_t ws_local_etx_read(protocol_interface_info_entry_t *interface, addrtype_t addr_type, const uint8_t *mac_adddress) { uint16_t etx; - if (!addr_ptr || !interface) { + if (!mac_adddress || !interface) { return 0; } uint8_t attribute_index; - mac_neighbor_table_entry_t *mac_neighbor = mac_neighbor_table_address_discover(mac_neighbor_info(interface), addr_ptr + PAN_ID_LEN, addr_type); + mac_neighbor_table_entry_t *mac_neighbor = mac_neighbor_table_address_discover(mac_neighbor_info(interface), mac_adddress, addr_type); if (!mac_neighbor) { return 0xffff; } @@ -933,6 +933,12 @@ uint16_t ws_etx_read(protocol_interface_info_entry_t *interface, addrtype_t addr etx = etx_local_etx_read(interface->id, attribute_index); + // if we have a measurement ready then we will check the RSL validity + if (etx != 0xffff && !ws_neighbour->candidate_parent) { + // RSL value measured is lower than acceptable ETX will be given as MAX + return WS_ETX_MAX << 1; // We use 8 bit fraction and ETX is usually 7 bit fraction + } + // If we dont have valid ETX for children we assume good ETX. // After enough packets is sent to children real calculated ETX is given. // This might result in ICMP source route errors returned to Border router causing secondary route uses @@ -942,6 +948,15 @@ uint16_t ws_etx_read(protocol_interface_info_entry_t *interface, addrtype_t addr return etx; } + +uint16_t ws_etx_read(protocol_interface_info_entry_t *interface, addrtype_t addr_type, const uint8_t *addr_ptr) +{ + if (!addr_ptr || !interface) { + return 0; + } + return ws_local_etx_read(interface, addr_type, addr_ptr + PAN_ID_LEN); +} + bool ws_bootstrap_nd_ns_transmit(protocol_interface_info_entry_t *cur, ipv6_neighbour_t *entry, bool unicast, uint8_t seq) { (void)cur; @@ -3001,17 +3016,17 @@ static bool ws_rpl_new_parent_callback(uint8_t *ll_parent_address, void *handle, return false; } // +2 Is for PAN ID space - memcpy(mac64 + 2, replacing + 8, 8); - mac64[2] ^= 2; + memcpy(mac64, replacing + 8, 8); + mac64[0] ^= 2; - if (ws_etx_read(cur, ADDR_802_15_4_LONG, mac64) == 0xffff) { - //Not proped yet because ETX is 0xffff + if (ws_local_etx_read(cur, ADDR_802_15_4_LONG, mac64) == 0xffff) { + //Not probed yet because ETX is 0xffff return false; } uint16_t etx = 0; if (neigh_buffer.neighbor) { - etx = etx_local_etx_read(cur->id, neigh_buffer.neighbor->index); + etx = ws_local_etx_read(cur, ADDR_802_15_4_LONG, neigh_buffer.neighbor->mac64); } // Accept now only better one's when max candidates selected and max candidate list size is reached @@ -3554,7 +3569,7 @@ static uint16_t ws_bootstrap_routing_cost_calculate(protocol_interface_info_entr return 0xffff; } - uint16_t etx = etx_local_etx_read(cur->id, mac_neighbor->index); + uint16_t etx = ws_local_etx_read(cur, ADDR_802_15_4_LONG, mac_neighbor->mac64); if (etx == 0) { etx = WS_ETX_MAX; //SET maximum value here if ETX is unknown } else { @@ -4254,7 +4269,7 @@ int ws_bootstrap_neighbor_info_get(protocol_interface_info_entry_t *cur, ws_neig neighbor_ptr[count].rsl_out = ws_neighbor_class_rsl_out_get(ws_neighbor); // ETX is shown calculated as 8 bit integer, but more common way is to use 7 bit such that 128 means ETX:1.0 - neighbor_ptr[count].etx = etx_local_etx_read(cur->id, mac_entry->index); + neighbor_ptr[count].etx = ws_local_etx_read(cur, ADDR_802_15_4_LONG, mac_entry->mac64); if (neighbor_ptr[count].etx != 0xffff) { neighbor_ptr[count].etx = neighbor_ptr[count].etx >> 1; } diff --git a/source/Service_Libs/etx/etx.c b/source/Service_Libs/etx/etx.c index 22a86f1cca1a..64a878bd85c9 100644 --- a/source/Service_Libs/etx/etx.c +++ b/source/Service_Libs/etx/etx.c @@ -439,11 +439,6 @@ uint16_t etx_local_etx_read(int8_t interface_id, uint8_t attribute_index) } if (etx_info.cache_sample_requested && entry->etx_samples < etx_info.init_etx_sample_count) { - etx_sample_storage_t *storage = etx_info.etx_cache_storage_list + attribute_index; - if (storage->received_acks == 0 && storage->attempts_count) { - //No ack so return max value - return etx_info.max_etx; - } //Not ready yet return 0xffff; }