diff --git a/source/6LoWPAN/ws/ws_bbr_api.c b/source/6LoWPAN/ws/ws_bbr_api.c index a1e47be9729b..ec05d057d96a 100644 --- a/source/6LoWPAN/ws/ws_bbr_api.c +++ b/source/6LoWPAN/ws/ws_bbr_api.c @@ -55,7 +55,7 @@ static void ws_bbr_rpl_root_activate(uint8_t *dodag_prefix, uint8_t *dodag_id) .lifetime_unit = 60, .objective_code_point = 1, // MRHOF algorithm used .authentication = 0, - .path_control_size = 0, + .path_control_size = 1, .dag_max_rank_increase = 2048, .min_hop_rank_increase = 128, // DIO configuration diff --git a/source/6LoWPAN/ws/ws_bootstrap.c b/source/6LoWPAN/ws/ws_bootstrap.c index c169347ade5e..a7350fcacd97 100644 --- a/source/6LoWPAN/ws/ws_bootstrap.c +++ b/source/6LoWPAN/ws/ws_bootstrap.c @@ -368,8 +368,9 @@ uint16_t ws_etx_read(protocol_interface_info_entry_t *interface, addrtype_t addr } attribute_index = mac_neighbor->index; ws_neighbor_class_entry_t *ws_neighbour = ws_neighbor_class_entry_get(&interface->ws_info->neighbor_storage, attribute_index); + etx_storage_t *etx_entry = etx_storage_entry_get(interface->id, attribute_index); - if (!ws_neighbour || + if (!ws_neighbour || !etx_entry || etx_entry->etx_samples < 1 || !ws_neighbour->candidate_parent) { // if RSL value is not good enough candidate parent flag is removed and device not accepted as parent //tr_debug("ws_etx_read not valid parent"); @@ -405,6 +406,8 @@ static int8_t ws_bootstrap_up(protocol_interface_info_entry_t *cur) tr_error("fhss initialization failed"); return -3; } + + // Save FHSS api cur->ws_info->fhss_api = ns_sw_mac_get_fhss_api(cur->mac_api); @@ -420,6 +423,8 @@ static int8_t ws_bootstrap_up(protocol_interface_info_entry_t *cur) cur->ipv6_neighbour_cache.use_eui64_as_slla_in_aro = true; /* Omit sending of NA if ARO SUCCESS */ cur->ipv6_neighbour_cache.omit_aro_success = true; + /* Disable NUD Probes */ + cur->ipv6_neighbour_cache.send_nud_probes = false; ws_bootstrap_event_discovery_start(cur); @@ -722,7 +727,6 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry ws_neighbor_class_neighbor_unicast_schedule_set(neighbor_info.ws_neighbor, ws_us); ws_neighbor_class_neighbor_broadcast_time_info_update(neighbor_info.ws_neighbor, &ws_bt_ie, data->timestamp); ws_neighbor_class_neighbor_broadcast_schedule_set(neighbor_info.ws_neighbor, &ws_bs_ie); - neighbor_info.neighbor->trusted_device = true; if (cur->ws_info->configuration_learned) { // received version is lower se we need to reset the trickle @@ -980,24 +984,55 @@ static void ws_neighbor_entry_remove_notify(mac_neighbor_table_entry_t *entry_pt ws_bootstrap_neighbor_delete(cur,entry_ptr->index); } - static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data) { uint32_t time_from_start = entry_ptr->link_lifetime - entry_ptr->lifetime; bool activate_nud = false; - if ((entry_ptr->link_role == PRIORITY_PARENT_NEIGHBOUR || entry_ptr->link_role == SECONDARY_PARENT_NEIGHBOUR) && time_from_start > WS_NEIGHBOR_NUD_TIMEOUT) { - if (entry_ptr->trusted_device) { + protocol_interface_info_entry_t *cur = user_data; + + 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) { + return false; + } + + if (time_from_start > WS_NEIGHBOR_NUD_TIMEOUT) { + + if (time_from_start > WS_NEIGHBOR_NUD_TIMEOUT * 1.5) { activate_nud = true; + } else { + uint16_t switch_prob = randLIB_get_random_in_range(0, WS_NUD_RANDOM_SAMPLE_LENGTH -1); + //Take Random from time WS_NEIGHBOR_NUD_TIMEOUT - WS_NEIGHBOR_NUD_TIMEOUT*1.5 + if (switch_prob < WS_NUD_RANDOM_COMPARE) { + activate_nud = true; + } + } + } else if (etx_entry->etx_samples < WS_NEIGBOR_ETX_SAMPLE_MAX) { + //Take Random number for trig a prope. + //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); + 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 %u, sample %u", time_from_start, etx_entry->etx_samples); + activate_nud = true; + } } - } + if (!activate_nud) { return false; } - protocol_interface_info_entry_t *cur = user_data; - uint8_t ll_target[16]; memcpy(ll_target, ADDR_LINK_LOCAL_PREFIX, 8); memcpy(ll_target + 8, entry_ptr->mac64, 8); diff --git a/source/6LoWPAN/ws/ws_common_defines.h b/source/6LoWPAN/ws/ws_common_defines.h index 83027a426c90..ae6fb036146d 100644 --- a/source/6LoWPAN/ws/ws_common_defines.h +++ b/source/6LoWPAN/ws/ws_common_defines.h @@ -184,9 +184,19 @@ typedef struct ws_bs_ie { #define WS_FAN_VERSION_1_0 1 -#define WS_NEIGHBOR_LINK_TIMEOUT 240 +#define WS_NEIGHBOR_LINK_TIMEOUT 2200 #define WS_NEIGHBOR_NUD_TIMEOUT WS_NEIGHBOR_LINK_TIMEOUT / 2 +#define WS_NEIGBOR_ETX_SAMPLE_MAX 3 + +#define WS_PROBE_INIT_BASE_SECONDS 8 + +#define WS_NUD_RAND_PROBABILITY 1 + +#define WS_NUD_RANDOM_SAMPLE_LENGTH WS_NEIGHBOR_NUD_TIMEOUT / 2 + +#define WS_NUD_RANDOM_COMPARE (WS_NUD_RAND_PROBABILITY*WS_NUD_RANDOM_SAMPLE_LENGTH) / 100 + /* * Threshold (referenced to DEVICE_MIN_SENS) above which a neighbor node may be considered for inclusion into candidate parent set */ diff --git a/source/6LoWPAN/ws/ws_neighbor_class.c b/source/6LoWPAN/ws/ws_neighbor_class.c index bbacc44b9abe..5c0b2fd36d43 100644 --- a/source/6LoWPAN/ws/ws_neighbor_class.c +++ b/source/6LoWPAN/ws/ws_neighbor_class.c @@ -27,7 +27,7 @@ #ifdef HAVE_WS -#define RSL_UNITITIALIZED 0x7fff + #define TRACE_GROUP "wsne" diff --git a/source/6LoWPAN/ws/ws_neighbor_class.h b/source/6LoWPAN/ws/ws_neighbor_class.h index c05964f00b02..ed1adf89af86 100644 --- a/source/6LoWPAN/ws/ws_neighbor_class.h +++ b/source/6LoWPAN/ws/ws_neighbor_class.h @@ -21,6 +21,8 @@ #include "fhss_ws_extension.h" #include "6LoWPAN/ws/ws_common_defines.h" +#define RSL_UNITITIALIZED 0x7fff + typedef struct ws_neighbor_class_entry { fhss_ws_neighbor_timing_info_t fhss_data; uint16_t rsl_in; /*!< RSL EWMA heard from neighbour*/ diff --git a/source/MAC/IEEE802_15_4/mac_fhss_callbacks.c b/source/MAC/IEEE802_15_4/mac_fhss_callbacks.c index 18363f473fbd..3f09ca01baf7 100644 --- a/source/MAC/IEEE802_15_4/mac_fhss_callbacks.c +++ b/source/MAC/IEEE802_15_4/mac_fhss_callbacks.c @@ -82,7 +82,7 @@ int mac_set_channel(const fhss_api_t *fhss_api, uint8_t channel_number) if (!mac_setup) { return -1; } - if (mac_setup->mac_ack_tx_active || (mac_setup->active_pd_data_request && mac_setup->active_pd_data_request->asynch_request)) { + if (mac_setup->mac_ack_tx_active || (mac_setup->active_pd_data_request && (mac_setup->active_pd_data_request->asynch_request || mac_setup->timer_mac_event == MAC_TIMER_ACK))) { return -1; } return mac_mlme_rf_channel_change(mac_setup, channel_number); diff --git a/source/MAC/IEEE802_15_4/mac_mcps_sap.c b/source/MAC/IEEE802_15_4/mac_mcps_sap.c index 914d4f634d70..ba1e28bc2180 100644 --- a/source/MAC/IEEE802_15_4/mac_mcps_sap.c +++ b/source/MAC/IEEE802_15_4/mac_mcps_sap.c @@ -1053,6 +1053,14 @@ static void mac_data_interface_frame_handler(mac_pre_parsed_frame_t *buf) } +static void mac_mcps_asynch_finish(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer) +{ + if (buffer->asynch_request && rf_mac_setup->fhss_api) { + // Must return to scheduled channel after asynch process by calling TX done + rf_mac_setup->fhss_api->data_tx_done(rf_mac_setup->fhss_api, false, true, buffer->msduHandle); + } +} + void mac_mcps_trig_buffer_from_queue(protocol_interface_rf_mac_setup_s *rf_mac_setup) { if (!rf_mac_setup) { @@ -1075,6 +1083,7 @@ void mac_mcps_trig_buffer_from_queue(protocol_interface_rf_mac_setup_s *rf_mac_s mac_data_request_init(rf_mac_setup, buffer); if (mcps_pd_data_request(rf_mac_setup, buffer) != 0) { rf_mac_setup->active_pd_data_request = NULL; + mac_mcps_asynch_finish(rf_mac_setup, buffer); mcps_data_confirm_handle(rf_mac_setup, buffer, NULL); } else { return; @@ -1120,14 +1129,12 @@ static void mac_pd_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_mac mac_pre_build_frame_t *buffer = rf_mac_setup->active_pd_data_request; if (mac_data_request_confirmation_finnish(rf_mac_setup, buffer) ) { rf_mac_setup->active_pd_data_request = NULL; - if (buffer->asynch_request && rf_mac_setup->fhss_api) { - // Must return to scheduled channel after asynch process by calling TX done - rf_mac_setup->fhss_api->data_tx_done(rf_mac_setup->fhss_api, false, true, buffer->msduHandle); - } + mac_mcps_asynch_finish(rf_mac_setup, buffer); mcps_data_confirm_handle(rf_mac_setup, buffer, NULL); } else { if (mcps_pd_data_request(rf_mac_setup, buffer) != 0) { rf_mac_setup->active_pd_data_request = NULL; + mac_mcps_asynch_finish(rf_mac_setup, buffer); mcps_data_confirm_handle(rf_mac_setup, buffer, NULL); } else { return; @@ -1155,10 +1162,6 @@ static void mac_pd_data_ack_handler(mac_pre_parsed_frame_t *buf) { } rf_mac_setup->active_pd_data_request = NULL; - if (buffer->asynch_request && rf_mac_setup->fhss_api) { - // Must return to scheduled channel after asynch process by calling TX done - rf_mac_setup->fhss_api->data_tx_done(rf_mac_setup->fhss_api, false, true, buffer->msduHandle); - } mcps_data_confirm_handle(rf_mac_setup, buffer, buf); mcps_sap_pre_parsed_frame_buffer_free(buf); @@ -1423,7 +1426,7 @@ static void mcps_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_ptr, sw_mac_stats_update(rf_ptr, STAT_MAC_TX_CCA_ATT, rf_ptr->mac_tx_status.cca_cnt); sw_mac_stats_update(rf_ptr, STAT_MAC_TX_RETRY, rf_ptr->mac_tx_status.retry); mcps_data_conf_t confirm; - if (rf_ptr->fhss_api) { + if (rf_ptr->fhss_api && !buffer->asynch_request) { // FHSS checks if this failed buffer needs to be pushed back to TX queue and retransmitted if ((rf_ptr->mac_tx_result == MAC_TX_FAIL) || (rf_ptr->mac_tx_result == MAC_CCA_FAIL)) { if (rf_ptr->fhss_api->data_tx_fail(rf_ptr->fhss_api, buffer->msduHandle, mac_convert_frame_type_to_fhss(buffer->fcf_dsn.frametype)) == true) { @@ -1989,7 +1992,7 @@ static mac_pre_build_frame_t * mcps_sap_pd_req_queue_read(protocol_interface_rf_ // With FHSS, check TX conditions if (rf_mac_setup->fhss_api) { while (buffer) { - if ((flush == true) || (rf_mac_setup->fhss_api->check_tx_conditions(rf_mac_setup->fhss_api, !mac_is_ack_request_set(buffer), + if (buffer->asynch_request || (flush == true) || (rf_mac_setup->fhss_api->check_tx_conditions(rf_mac_setup->fhss_api, !mac_is_ack_request_set(buffer), buffer->msduHandle, mac_convert_frame_type_to_fhss(buffer->fcf_dsn.frametype), buffer->mac_payload_length, rf_mac_setup->dev_driver->phy_driver->phy_header_length, rf_mac_setup->dev_driver->phy_driver->phy_tail_length) == true)) { break; diff --git a/source/MAC/IEEE802_15_4/mac_pd_sap.c b/source/MAC/IEEE802_15_4/mac_pd_sap.c index 20aec97978f8..e4c887c05ac8 100644 --- a/source/MAC/IEEE802_15_4/mac_pd_sap.c +++ b/source/MAC/IEEE802_15_4/mac_pd_sap.c @@ -387,6 +387,10 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r if (rf_ptr->mac_ack_tx_active) { rf_ptr->mac_ack_tx_active = false; + if (rf_ptr->fhss_api) { + //SET tx completed false because ack isnot never queued + rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, false, false, 0xff); + } if (rf_ptr->active_pd_data_request) { if (rf_ptr->active_pd_data_request->fcf_dsn.securityEnabled) { @@ -464,7 +468,7 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r static int8_t mac_data_interface_tx_done_by_ack_cb(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_parsed_frame_t *buf) { - if (!rf_ptr->macRfRadioTxActive) { + if (!rf_ptr->macRfRadioTxActive || !rf_ptr->active_pd_data_request || rf_ptr->active_pd_data_request->fcf_dsn.DSN != buf->fcf_dsn.DSN) { return -1; } @@ -479,9 +483,7 @@ static int8_t mac_data_interface_tx_done_by_ack_cb(protocol_interface_rf_mac_set mcps_sap_pd_ack(buf); if (rf_ptr->fhss_api) { - if (rf_ptr->active_pd_data_request->asynch_request == false) { - rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, false, true, rf_ptr->active_pd_data_request->msduHandle); - } + rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, false, true, rf_ptr->active_pd_data_request->msduHandle); } return 0; } diff --git a/source/RPL/rpl_structures.h b/source/RPL/rpl_structures.h index 0e518d029f94..4210442fdf83 100644 --- a/source/RPL/rpl_structures.h +++ b/source/RPL/rpl_structures.h @@ -134,6 +134,7 @@ typedef struct rpl_dao_non_root uint32_t refresh_timer; /* Refresh timer (seconds) - 0xFFFFFFFF = infinite, 0 = not yet set */ } rpl_dao_non_root_t; + /* Descriptor for a RPL DAO target */ struct rpl_dao_target { diff --git a/source/RPL/rpl_upward.c b/source/RPL/rpl_upward.c index f38f43a9407f..986eacd81310 100644 --- a/source/RPL/rpl_upward.c +++ b/source/RPL/rpl_upward.c @@ -1555,6 +1555,7 @@ void rpl_instance_slow_timer(rpl_instance_t *instance, uint16_t seconds) } } + void rpl_upward_dio_timer(rpl_instance_t *instance, uint16_t ticks) { rpl_dodag_version_t *dodag_version = instance->current_dodag_version; diff --git a/source/Service_Libs/etx/etx.c b/source/Service_Libs/etx/etx.c index 981ab71ad8e1..084ffaafed6d 100644 --- a/source/Service_Libs/etx/etx.c +++ b/source/Service_Libs/etx/etx.c @@ -81,6 +81,9 @@ void etx_transm_attempts_update(int8_t interface_id, uint8_t attempts, bool succ if (!entry) { return; } + if (entry->etx_samples < 7) { + entry->etx_samples++; + } accumulated_failures = entry->accumulated_failures; diff --git a/source/Service_Libs/etx/etx.h b/source/Service_Libs/etx/etx.h index 12b1ee6117cf..a0216b4a382c 100644 --- a/source/Service_Libs/etx/etx.h +++ b/source/Service_Libs/etx/etx.h @@ -38,6 +38,7 @@ typedef struct etx_storage_s { unsigned accumulated_failures: 5; unsigned tmp_etx: 1; unsigned linkIdr: 4; + unsigned etx_samples: 3; } etx_storage_t; /** diff --git a/source/Service_Libs/fhss/fhss_ws.c b/source/Service_Libs/fhss/fhss_ws.c index 440f9e1aa4ee..61e4c1975346 100644 --- a/source/Service_Libs/fhss/fhss_ws.c +++ b/source/Service_Libs/fhss/fhss_ws.c @@ -652,10 +652,14 @@ int fhss_ws_set_parent(fhss_structure_t *fhss_structure, const uint8_t eui64[8], return -1; } platform_enter_critical(); + fhss_structure->platform_functions.fhss_timer_stop(fhss_broadcast_handler, fhss_structure->fhss_api); uint32_t time_from_reception_ms = (fhss_structure->callbacks.read_timestamp(fhss_structure->fhss_api) - bc_timing_info->bt_rx_timestamp)/1000; uint32_t true_bc_interval_offset = (bc_timing_info->broadcast_interval_offset + time_from_reception_ms) % bc_timing_info->broadcast_interval; uint32_t timeout = ((bc_timing_info->broadcast_interval-true_bc_interval_offset)*1000); - fhss_structure->ws->is_on_bc_channel = false; + + if (fhss_structure->ws->is_on_bc_channel) { + timeout -= ((bc_timing_info->broadcast_interval - bc_timing_info->broadcast_dwell_interval) *1000); + } fhss_start_timer(fhss_structure, timeout, fhss_broadcast_handler); uint16_t slots_since_reception = (bc_timing_info->broadcast_interval_offset + time_from_reception_ms) / bc_timing_info->broadcast_interval; // TODO: Calculate drift error diff --git a/source/Service_Libs/mac_neighbor_table/mac_neighbor_table.c b/source/Service_Libs/mac_neighbor_table/mac_neighbor_table.c index 6b1e548212c6..9e1d69000ec2 100644 --- a/source/Service_Libs/mac_neighbor_table/mac_neighbor_table.c +++ b/source/Service_Libs/mac_neighbor_table/mac_neighbor_table.c @@ -192,6 +192,9 @@ void mac_neighbor_table_neighbor_connected(mac_neighbor_table_t *table_class, ma void mac_neighbor_table_trusted_neighbor(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry, bool trusted_device) { (void)table_class; + if (!neighbor_entry->trusted_device && trusted_device) { + neighbor_entry->lifetime = neighbor_entry->link_lifetime; + } neighbor_entry->trusted_device = trusted_device; } diff --git a/test/nanostack/unittest/service_libs/mac_neighbor_table/test_mac_neighbor_table.c b/test/nanostack/unittest/service_libs/mac_neighbor_table/test_mac_neighbor_table.c index a50e05309ceb..67959aa3b0be 100644 --- a/test/nanostack/unittest/service_libs/mac_neighbor_table/test_mac_neighbor_table.c +++ b/test/nanostack/unittest/service_libs/mac_neighbor_table/test_mac_neighbor_table.c @@ -133,19 +133,19 @@ bool test_mac_neighbor_table_use() mac_neighbor_table_trusted_neighbor(entry, mac_entry3, true); - if (!mac_entry3->trusted_device) { + if (!mac_entry3->trusted_device && mac_entry3->lifetime != 240) { return false; } mac_neighbor_table_neighbor_timeout_update(entry, 31); - if (mac_entry3->lifetime != 199 || mac_entry2->lifetime != 199 || mac_entry1->lifetime != 199) { + if (mac_entry3->lifetime != 209 || mac_entry2->lifetime != 199 || mac_entry1->lifetime != 199) { return false; } mac_neighbor_table_neighbor_timeout_update(entry, 170); - if (mac_entry3->lifetime != 29 || mac_entry2->lifetime != 29 || mac_entry1->lifetime != 29) { + if (mac_entry3->lifetime != 39 || mac_entry2->lifetime != 29 || mac_entry1->lifetime != 29) { return false; }