diff --git a/source/6LoWPAN/ND/nd_router_object.c b/source/6LoWPAN/ND/nd_router_object.c index 9c8f50351f21..c397bfa66c83 100644 --- a/source/6LoWPAN/ND/nd_router_object.c +++ b/source/6LoWPAN/ND/nd_router_object.c @@ -855,8 +855,14 @@ static void nd_update_registration(protocol_interface_info_entry_t *cur_interfac */ mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur_interface), ipv6_neighbour_eui64(&cur_interface->ipv6_neighbour_cache, neigh), ADDR_802_15_4_LONG); - if (entry && !entry->ffd_device) { - rpl_control_publish_host_address(protocol_6lowpan_rpl_domain, neigh->ip_address, neigh->lifetime); + if (entry) { + if (ws_info(cur_interface)) { + ws_common_etx_validate(cur_interface, entry); + } + + if (!entry->ffd_device) { + rpl_control_publish_host_address(protocol_6lowpan_rpl_domain, neigh->ip_address, neigh->lifetime); + } } protocol_6lowpan_neighbor_address_state_synch(cur_interface, aro->eui64, neigh->ip_address + 8); diff --git a/source/6LoWPAN/ws/ws_bootstrap.c b/source/6LoWPAN/ws/ws_bootstrap.c index 6c7052083f7f..ca814bb588bb 100644 --- a/source/6LoWPAN/ws/ws_bootstrap.c +++ b/source/6LoWPAN/ws/ws_bootstrap.c @@ -95,6 +95,7 @@ static void ws_bootstrap_authentication_completed(protocol_interface_info_entry_ static void ws_bootstrap_pan_version_increment(protocol_interface_info_entry_t *cur); static ws_nud_table_entry_t *ws_nud_entry_discover(protocol_interface_info_entry_t *cur, void *neighbor); static void ws_nud_entry_remove(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *entry_ptr); +static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data); typedef enum { WS_PARENT_SOFT_SYNCH = 0, /**< let FHSS make decision if synchronization is needed*/ @@ -322,6 +323,8 @@ void ws_nud_active_timer(protocol_interface_info_entry_t *cur, uint16_t ticks) //Convert TICKS to real milliseconds if (ticks > 0xffff / 100) { ticks = 0xffff; + } else if (ticks == 0) { + ticks = 1; } else { ticks *= 100; } @@ -1279,12 +1282,18 @@ static void ws_bootstrap_neighbor_table_clean(struct protocol_interface_info_ent mac_neighbor_table_entry_t *neighbor_entry_ptr = NULL; ns_list_foreach_safe(mac_neighbor_table_entry_t, cur, &mac_neighbor_info(interface)->neighbour_list) { + ws_neighbor_class_entry_t *ws_neighbor = ws_neighbor_class_entry_get(&interface->ws_info->neighbor_storage, cur->index); if (cur->link_role == PRIORITY_PARENT_NEIGHBOUR) { //This is our primary parent we cannot delete continue; } + if (cur->nud_active || ws_neighbor->accelerated_etx_probe || ws_neighbor->negative_aro_send) { + //If NUD process is active do not trig + continue; + } + if (neighbor_entry_ptr && neighbor_entry_ptr->lifetime < cur->lifetime) { // We have already shorter link entry found this cannot replace it continue; @@ -1397,7 +1406,7 @@ static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, ws_neighbor_class_entry_t *ws_neighbor = ws_neighbor_class_entry_get(&cur->ws_info->neighbor_storage, entry_ptr->index); etx_storage_t *etx_entry = etx_storage_entry_get(cur->id, entry_ptr->index); - if (!entry_ptr->trusted_device || !ws_neighbor || !etx_entry) { + if (!entry_ptr->trusted_device || !ws_neighbor || !etx_entry || ws_neighbor->negative_aro_send) { return false; } @@ -1417,17 +1426,22 @@ static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, //ETX Sample 0: random 1-8 //ETX Sample 1: random 2-16 //ETX Sample 2: random 4-32 - uint32_t probe_period = WS_PROBE_INIT_BASE_SECONDS << etx_entry->etx_samples; - uint32_t time_block = 1 << etx_entry->etx_samples; - if (time_from_start >= probe_period) { - //tr_debug("Link Probe test %u Sample trig", etx_entry->etx_samples); + if (etx_entry->etx_samples == 0 && ws_neighbor->accelerated_etx_probe) { + //Accept quick Probe for init ETX activate_nud = true; - } else if (time_from_start > time_block) { - uint16_t switch_prob = randLIB_get_random_in_range(0, probe_period - 1); - //Take Random from time WS_NEIGHBOR_NUD_TIMEOUT - WS_NEIGHBOR_NUD_TIMEOUT*1.5 - if (switch_prob < 2) { - //tr_debug("Link Probe test with jitter %"PRIu32", sample %u", time_from_start, etx_entry->etx_samples); + } else { + uint32_t probe_period = WS_PROBE_INIT_BASE_SECONDS << etx_entry->etx_samples; + uint32_t time_block = 1 << etx_entry->etx_samples; + if (time_from_start >= probe_period) { + //tr_debug("Link Probe test %u Sample trig", etx_entry->etx_samples); activate_nud = true; + } else if (time_from_start > time_block) { + uint16_t switch_prob = randLIB_get_random_in_range(0, probe_period - 1); + //Take Random from time WS_NEIGHBOR_NUD_TIMEOUT - WS_NEIGHBOR_NUD_TIMEOUT*1.5 + if (switch_prob < 2) { + //tr_debug("Link Probe test with jitter %"PRIu32", sample %u", time_from_start, etx_entry->etx_samples); + activate_nud = true; + } } } } @@ -1441,6 +1455,10 @@ static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, return false; } entry->neighbor_info = entry_ptr; + if (ws_neighbor->accelerated_etx_probe) { + ws_neighbor->accelerated_etx_probe = false; + entry->timer = 1; + } if (etx_entry->etx_samples >= WS_NEIGBOR_ETX_SAMPLE_MAX) { entry->nud_process = true; @@ -2626,4 +2644,24 @@ void ws_secondary_parent_update(protocol_interface_info_entry_t *interface) } } +void ws_bootstrap_etx_accelerate(protocol_interface_info_entry_t *interface, mac_neighbor_table_entry_t *neigh) +{ + ws_neighbor_class_entry_t *ws_neighbor = ws_neighbor_class_entry_get(&interface->ws_info->neighbor_storage, neigh->index); + //Enable Faster ETX probing + ws_neighbor->accelerated_etx_probe = true; + //Move Neighbor to first to for accelerate Process + mac_neighbor_table_t *table_class = mac_neighbor_info(interface); + ns_list_remove(&table_class->neighbour_list, neigh); + ns_list_add_to_start(&table_class->neighbour_list, neigh); + //Try to Generate Active NUD Immediately + if (!ws_neighbor_entry_nud_notify(neigh, interface)) { + return;//Return if NUD active is full + } + table_class->active_nud_process++; + neigh->nud_active = true; + //Push NS to send + ws_nud_active_timer(interface, 0); + +} + #endif //HAVE_WS diff --git a/source/6LoWPAN/ws/ws_bootstrap.h b/source/6LoWPAN/ws/ws_bootstrap.h index 789279e0fc03..8df6d4088d2c 100644 --- a/source/6LoWPAN/ws/ws_bootstrap.h +++ b/source/6LoWPAN/ws/ws_bootstrap.h @@ -77,6 +77,8 @@ bool ws_eapol_relay_state_active(protocol_interface_info_entry_t *cur); void ws_bootstrap_eapol_parent_synch(struct protocol_interface_info_entry *cur, struct llc_neighbour_req *neighbor_info); +void ws_bootstrap_etx_accelerate(struct protocol_interface_info_entry *cur, mac_neighbor_table_entry_t *neigh); + #else #define ws_bootstrap_init(interface_id, bootstrap_mode) (-1) @@ -86,6 +88,7 @@ void ws_bootstrap_eapol_parent_synch(struct protocol_interface_info_entry *cur, #define ws_bootstrap_aro_failure(cur, ll_address) #define ws_primary_parent_update(interface, neighbor) #define ws_secondary_parent_update(interface) +#define ws_bootstrap_etx_accelerate(cur, neigh) ((void) 0) #endif //HAVE_WS diff --git a/source/6LoWPAN/ws/ws_common.c b/source/6LoWPAN/ws/ws_common.c index 54cefde9f80c..fa6d3b94778c 100644 --- a/source/6LoWPAN/ws/ws_common.c +++ b/source/6LoWPAN/ws/ws_common.c @@ -27,6 +27,7 @@ #include "6LoWPAN/ws/ws_common.h" #include "6LoWPAN/ws/ws_bootstrap.h" #include "6LoWPAN/ws/ws_bbr_api_internal.h" +#include "Service_Libs/etx/etx.h" #include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" #include "Service_Libs/blacklist/blacklist.h" #include "ws_management_api.h" @@ -398,6 +399,29 @@ bool ws_common_allow_child_registration(protocol_interface_info_entry_t *interfa return true; } +bool ws_common_negative_aro_mark(protocol_interface_info_entry_t *interface, const uint8_t *eui64) +{ + mac_neighbor_table_entry_t *neighbour = mac_neighbor_table_address_discover(mac_neighbor_info(interface), eui64, ADDR_802_15_4_LONG); + if (!neighbour) { + return false; + } + ws_neighbor_class_entry_t *ws_neighbor = ws_neighbor_class_entry_get(&interface->ws_info->neighbor_storage, neighbour->index); + ws_neighbor->negative_aro_send = true; + neighbour->lifetime = 30; //Remove anyway if Packet is freed before MAC push + return true; +} + +void ws_common_etx_validate(protocol_interface_info_entry_t *interface, mac_neighbor_table_entry_t *neigh) +{ + etx_storage_t *etx_entry = etx_storage_entry_get(interface->id, neigh->index); + + if (neigh->nud_active || !neigh->trusted_device || etx_entry->etx_samples) { + return; //Do not trig Second NS if Active NUD already, not trusted or ETX samples already done + } + + ws_bootstrap_etx_accelerate(interface, neigh); +} + #endif // HAVE_WS diff --git a/source/6LoWPAN/ws/ws_common.h b/source/6LoWPAN/ws/ws_common.h index 9e9bfaa8e2b0..6bff87ad34c9 100644 --- a/source/6LoWPAN/ws/ws_common.h +++ b/source/6LoWPAN/ws/ws_common.h @@ -122,6 +122,10 @@ void ws_common_neighbor_remove(protocol_interface_info_entry_t *cur, const uint8 bool ws_common_allow_child_registration(protocol_interface_info_entry_t *cur, const uint8_t *eui64); +void ws_common_etx_validate(protocol_interface_info_entry_t *interface, mac_neighbor_table_entry_t *neigh); + +bool ws_common_negative_aro_mark(protocol_interface_info_entry_t *interface, const uint8_t *eui64); + #define ws_info(cur) ((cur)->ws_info) #else #define ws_info(cur) ((ws_info_t *) NULL) @@ -131,6 +135,8 @@ bool ws_common_allow_child_registration(protocol_interface_info_entry_t *cur, co #define ws_common_neighbor_remove(cur, ll_address) #define ws_common_fast_timer(cur, ticks) ((void) 0) #define ws_common_allow_child_registration(cur, eui64) (false) +#define ws_common_etx_validate(interface, neigh) ((void) 0) +#define ws_common_negative_aro_mark(interface, eui64)(false) #endif //HAVE_WS diff --git a/source/6LoWPAN/ws/ws_neighbor_class.h b/source/6LoWPAN/ws/ws_neighbor_class.h index 23d50454186b..5cf6aac624ce 100644 --- a/source/6LoWPAN/ws/ws_neighbor_class.h +++ b/source/6LoWPAN/ws/ws_neighbor_class.h @@ -32,6 +32,8 @@ typedef struct ws_neighbor_class_entry { bool broadcast_timing_info_stored: 1; bool broadcast_shedule_info_stored: 1; bool synch_done : 1; + bool accelerated_etx_probe : 1; + bool negative_aro_send : 1; } ws_neighbor_class_entry_t; /** diff --git a/source/Common_Protocols/icmpv6.c b/source/Common_Protocols/icmpv6.c index 3dfac3c936cb..7c720208ced7 100644 --- a/source/Common_Protocols/icmpv6.c +++ b/source/Common_Protocols/icmpv6.c @@ -1677,6 +1677,10 @@ buffer_t *icmpv6_build_na(protocol_interface_info_entry_t *cur, bool solicited, } if (ws_info(cur) && aro && aro->status != ARO_SUCCESS) { /*If Aro failed we will kill the neigbour after we have succeeded in sending message*/ + if (!ws_common_negative_aro_mark(cur, aro->eui64)) { + tr_debug("Neighbour removed for negative response send"); + return buffer_free(buf); + } buf->ack_receive_cb = ack_remove_neighbour_cb; } diff --git a/test/nanostack/unittest/stub/ws_bootstrap_stub.c b/test/nanostack/unittest/stub/ws_bootstrap_stub.c index 8263bfcdd95c..1c5f1b55d69a 100644 --- a/test/nanostack/unittest/stub/ws_bootstrap_stub.c +++ b/test/nanostack/unittest/stub/ws_bootstrap_stub.c @@ -120,3 +120,8 @@ void ws_bootstrap_eapol_parent_synch(struct protocol_interface_info_entry *cur, { } + +void ws_bootstrap_etx_accelerate(protocol_interface_info_entry_t *interface, mac_neighbor_table_entry_t *neigh) +{ + +} diff --git a/test/nanostack/unittest/stub/ws_common_stub.c b/test/nanostack/unittest/stub/ws_common_stub.c index 2dbeea10ef7b..ce6810857b01 100644 --- a/test/nanostack/unittest/stub/ws_common_stub.c +++ b/test/nanostack/unittest/stub/ws_common_stub.c @@ -77,3 +77,13 @@ void ws_common_neighbor_remove(protocol_interface_info_entry_t *cur, const uint8 (void) cur; (void) ll_address; } + +bool ws_common_negative_aro_mark(protocol_interface_info_entry_t *interface, const uint8_t *eui64) +{ + return true; +} + +void ws_common_etx_validate(protocol_interface_info_entry_t *interface, mac_neighbor_table_entry_t *neigh) +{ + +}