Skip to content

Commit

Permalink
Add RSL check for ETX Calculation for RPL parent selection
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Mika Tervonen authored and Mika Tervonen committed Apr 29, 2021
1 parent c05e1da commit 8a8b407
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 16 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion nanostack/ws_management_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
35 changes: 25 additions & 10 deletions source/6LoWPAN/ws/ws_bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
}
Expand Down
5 changes: 0 additions & 5 deletions source/Service_Libs/etx/etx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down

0 comments on commit 8a8b407

Please sign in to comment.