diff --git a/nanostack/mlme.h b/nanostack/mlme.h index 3a4e02d5794..ee6a244172f 100644 --- a/nanostack/mlme.h +++ b/nanostack/mlme.h @@ -264,6 +264,7 @@ typedef enum { macAutoRequestKeyIndex = 0x7b, /* #include #include "Common_Protocols/icmpv6.h" +#include "mac_common_defines.h" +#include "net_interface.h" +#include "6LoWPAN/MAC/mpx_api.h" #include "6LoWPAN/ws/ws_config.h" #include "6LoWPAN/ws/ws_common_defines.h" +#include "6LoWPAN/ws/ws_llc.h" #include "6LoWPAN/ws/ws_common.h" #include "6LoWPAN/ws/ws_bootstrap.h" #include "6LoWPAN/ws/ws_bbr_api_internal.h" @@ -349,6 +353,7 @@ void ws_common_fast_timer(protocol_interface_info_entry_t *cur, uint16_t ticks) { ws_bootstrap_trickle_timer(cur, ticks); ws_nud_active_timer(cur, ticks); + ws_llc_fast_timer(cur, ticks); } diff --git a/source/6LoWPAN/ws/ws_llc.h b/source/6LoWPAN/ws/ws_llc.h index fd3b0105014..e7df162ae49 100644 --- a/source/6LoWPAN/ws/ws_llc.h +++ b/source/6LoWPAN/ws/ws_llc.h @@ -226,6 +226,8 @@ void ws_llc_hopping_schedule_config(struct protocol_interface_info_entry *interf void ws_llc_timer_seconds(struct protocol_interface_info_entry *interface, uint16_t seconds_update); +void ws_llc_fast_timer(struct protocol_interface_info_entry *interface, uint16_t ticks); + bool ws_llc_eapol_relay_forward_filter(struct protocol_interface_info_entry *interface, const uint8_t *joiner_eui64, uint8_t mac_sequency, uint32_t rx_timestamp); ws_neighbor_temp_class_t *ws_llc_get_multicast_temp_entry(struct protocol_interface_info_entry *interface, const uint8_t *mac64); diff --git a/source/6LoWPAN/ws/ws_llc_data_service.c b/source/6LoWPAN/ws/ws_llc_data_service.c index 89b48c4202d..c9ffe9c1d40 100644 --- a/source/6LoWPAN/ws/ws_llc_data_service.c +++ b/source/6LoWPAN/ws/ws_llc_data_service.c @@ -119,7 +119,9 @@ typedef struct { typedef struct { uint8_t mac_handle_base; /**< Mac handle id base this will be updated by 1 after use */ uint8_t llc_message_list_size; /**< llc_message_list list size */ + uint16_t edfe_rx_wait_timer; mpx_class_t mpx_data_base; /**< MPX data be including USER API Class and user call backs */ + llc_message_list_t llc_message_list; /**< Active Message list */ llc_ie_params_t ie_params; /**< LLC IE header and Payload data configuration */ temp_entriest_t *temp_entries; @@ -171,6 +173,30 @@ static ws_neighbor_temp_class_t *ws_allocate_eapol_temp_entry(temp_entriest_t *b static void ws_llc_mpx_eapol_send(llc_data_base_t *base, llc_message_t *message); +static bool test_skip_first_init_response = false; +static uint8_t test_drop_data_message = 0; + + +int8_t ws_test_skip_edfe_data_send(int8_t interface_id, bool skip) +{ + protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); + if (!cur || !ws_info(cur)) { + return -1; + } + test_skip_first_init_response = skip; + return 0; +} + +int8_t ws_test_drop_edfe_data_frames(int8_t interface_id, uint8_t number_of_dropped_frames) +{ + protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); + if (!cur || !ws_info(cur)) { + return -1; + } + test_drop_data_message = number_of_dropped_frames; + return 0; +} + /** Discover Message by message handle id */ static llc_message_t *llc_message_discover_by_mac_handle(uint8_t handle, llc_message_list_t *list) { @@ -949,7 +975,7 @@ static void ws_llc_lowpan_mpx_data_request(llc_data_base_t *base, mpx_user_t *us nested_wp_id.vp_ie = true; } - if (data->ExtendedFrameExchange) { + if (data->ExtendedFrameExchange && data->TxAckReq) { ie_header_mask.fc_ie = true; } if (!data->TxAckReq) { @@ -996,11 +1022,12 @@ static void ws_llc_lowpan_mpx_data_request(llc_data_base_t *base, mpx_user_t *us data_req.msduLength = 0; data_req.msduHandle = message->msg_handle; - if (data->ExtendedFrameExchange) { + if (data->ExtendedFrameExchange && data->TxAckReq) { data_req.SeqNumSuppressed = true; data_req.PanIdSuppressed = true; data_req.TxAckReq = true; // This will be changed inside MAC } else { + data_req.ExtendedFrameExchange = false; //Do not accept EDFE for non unicast traffic if (!data->TxAckReq) { data_req.PanIdSuppressed = false; data_req.DstAddrMode = MAC_ADDR_MODE_NONE; @@ -1500,20 +1527,36 @@ static void ws_llc_mcps_edfe_handler(const mac_api_t *api, mcps_edfe_response_t if (!message) { //tr_debug("FC:Send a Final Frame"); + if (test_drop_data_message) { + test_drop_data_message--; + base->edfe_rx_wait_timer += 99; + response_message->edfe_message_status = MCPS_EDFE_MALFORMED_FRAME; + return; + } fc_ie.rx_flow_ctrl = 0; + base->edfe_rx_wait_timer = 0; ws_llc_build_edfe_response(base, response_message, fc_ie); response_message->edfe_message_status = MCPS_EDFE_FINAL_FRAME_TX; } else { + if (test_skip_first_init_response) { + //Skip data send and test timeout at Slave side + test_skip_first_init_response = false; + response_message->edfe_message_status = MCPS_EDFE_FINAL_FRAME_RX; + return; + } ws_llc_build_edfe_frame(message, response_message, fc_ie); } } else if (fc_ie.tx_flow_ctrl == 0 && fc_ie.rx_flow_ctrl == 0) { //tr_debug("FC:Received a Final Frame"); + base->edfe_rx_wait_timer = 0; response_message->edfe_message_status = MCPS_EDFE_FINAL_FRAME_RX; } else if (fc_ie.tx_flow_ctrl && fc_ie.rx_flow_ctrl) { + base->edfe_rx_wait_timer = fc_ie.tx_flow_ctrl + 99; fc_ie.tx_flow_ctrl = 0; fc_ie.rx_flow_ctrl = 255; //tr_debug("FC:Send a response"); + //Enable or refesh timeout timer ws_llc_build_edfe_response(base, response_message, fc_ie); response_message->edfe_message_status = MCPS_EDFE_RESPONSE_FRAME; } @@ -1771,6 +1814,39 @@ void ws_llc_hopping_schedule_config(struct protocol_interface_info_entry *interf base->ie_params.hopping_schedule = hopping_schedule; } +void ws_llc_fast_timer(struct protocol_interface_info_entry *interface, uint16_t ticks) +{ + llc_data_base_t *base = ws_llc_discover_by_interface(interface); + if (!base || !base->edfe_rx_wait_timer) { + return; + } + + if (ticks > 0xffff / 100) { + ticks = 0xffff; + } else if (ticks == 0) { + ticks = 1; + } else { + ticks *= 100; + } + + if (base->edfe_rx_wait_timer > ticks) { + base->edfe_rx_wait_timer -= ticks; + } else { + base->edfe_rx_wait_timer = 0; + tr_debug("EDFE Data Wait Timeout"); + //MAC edfe wait data timeout + if (interface->mac_api && interface->mac_api->mlme_req) { + mlme_set_t set_req; + uint8_t value = 0; + set_req.attr = macEdfeForceStop; + set_req.attr_index = 0; + set_req.value_pointer = &value; + set_req.value_size = 1; + interface->mac_api->mlme_req(interface->mac_api, MLME_SET, &set_req); + } + } +} + void ws_llc_timer_seconds(struct protocol_interface_info_entry *interface, uint16_t seconds_update) { llc_data_base_t *base = ws_llc_discover_by_interface(interface); diff --git a/source/MAC/IEEE802_15_4/mac_mcps_sap.c b/source/MAC/IEEE802_15_4/mac_mcps_sap.c index 8ae296fac74..086de450347 100644 --- a/source/MAC/IEEE802_15_4/mac_mcps_sap.c +++ b/source/MAC/IEEE802_15_4/mac_mcps_sap.c @@ -1474,6 +1474,22 @@ static void mac_data_interface_internal_tx_confirm_handle(protocol_interface_rf_ } +static bool mcps_buffer_edfe_data_failure(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer) +{ + if (!rf_ptr->mac_edfe_enabled || !buffer->ExtendedFrameExchange) { + return false; + } + + if (rf_ptr->mac_edfe_info->state > MAC_EDFE_FRAME_CONNECTING) { + //Set to idle + tr_debug("Edfe Data send fail"); + return true; + } + + return false; +} + + static void mcps_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer, mac_pre_parsed_frame_t *ack_buf) { @@ -1482,7 +1498,7 @@ static void mcps_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_ptr, mcps_data_conf_t confirm; 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 (!mcps_buffer_edfe_data_failure(rf_ptr, buffer) && ((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), rf_ptr->mac_tx_start_channel) == true) { if (rf_ptr->mac_tx_result == MAC_TX_FAIL) { @@ -1495,6 +1511,11 @@ static void mcps_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_ptr, return; } } + + if (rf_ptr->mac_edfe_enabled && buffer->ExtendedFrameExchange) { + rf_ptr->mac_edfe_info->state = MAC_EDFE_FRAME_IDLE; + } + } confirm.cca_retries = rf_ptr->mac_tx_status.cca_cnt + buffer->fhss_cca_retry_count; confirm.tx_retries = rf_ptr->mac_tx_status.retry + buffer->fhss_retry_count; diff --git a/source/MAC/IEEE802_15_4/mac_mlme.c b/source/MAC/IEEE802_15_4/mac_mlme.c index c49178e2a3e..d8db1d60f66 100644 --- a/source/MAC/IEEE802_15_4/mac_mlme.c +++ b/source/MAC/IEEE802_15_4/mac_mlme.c @@ -512,6 +512,10 @@ static int8_t mac_mlme_boolean_set(protocol_interface_rf_mac_setup_s *rf_mac_set rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_ACCEPT_ANY_BEACON, (uint8_t *)&value); } break; + + case macEdfeForceStop: + return mac_data_edfe_force_stop(rf_mac_setup); + case macAcceptByPassUnknowDevice: rf_mac_setup->mac_security_bypass_unknow_device = value; break; diff --git a/source/MAC/IEEE802_15_4/mac_pd_sap.c b/source/MAC/IEEE802_15_4/mac_pd_sap.c index cee933428af..54669e87945 100644 --- a/source/MAC/IEEE802_15_4/mac_pd_sap.c +++ b/source/MAC/IEEE802_15_4/mac_pd_sap.c @@ -432,6 +432,17 @@ static void mac_data_ack_tx_finish(protocol_interface_rf_mac_setup_s *rf_ptr) } } +int8_t mac_data_edfe_force_stop(protocol_interface_rf_mac_setup_s *rf_ptr) +{ + if (!rf_ptr->mac_edfe_enabled || rf_ptr->mac_edfe_info->state != MAC_EDFE_FRAME_WAIT_DATA) { + return -1; + } + //Set to idle + rf_ptr->mac_edfe_info->state = MAC_EDFE_FRAME_IDLE; + mac_data_ack_tx_finish(rf_ptr); + return 0; +} + static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *rf_ptr, phy_link_tx_status_e status, uint8_t cca_retry, uint8_t tx_retry) { diff --git a/source/MAC/IEEE802_15_4/mac_pd_sap.h b/source/MAC/IEEE802_15_4/mac_pd_sap.h index 9e524ebd101..fdde95acac0 100644 --- a/source/MAC/IEEE802_15_4/mac_pd_sap.h +++ b/source/MAC/IEEE802_15_4/mac_pd_sap.h @@ -59,4 +59,6 @@ void mac_csma_backoff_start(struct protocol_interface_rf_mac_setup *rf_mac_setup */ void mac_pd_sap_state_machine(struct protocol_interface_rf_mac_setup *rf_mac_setup); +int8_t mac_data_edfe_force_stop(struct protocol_interface_rf_mac_setup *rf_ptr); + #endif /* MAC_PD_SAP_H_ */ diff --git a/test/nanostack/unittest/stub/mac_pd_sap_stub.c b/test/nanostack/unittest/stub/mac_pd_sap_stub.c index 2c27fa77da7..01d1be26a2d 100644 --- a/test/nanostack/unittest/stub/mac_pd_sap_stub.c +++ b/test/nanostack/unittest/stub/mac_pd_sap_stub.c @@ -82,3 +82,8 @@ void mac_csma_backoff_start(protocol_interface_rf_mac_setup_s *rf_mac_setup) { } + +int8_t mac_data_edfe_force_stop(struct protocol_interface_rf_mac_setup *rf_ptr) +{ + return 0; +}