Skip to content

Commit

Permalink
EDFE error handling update
Browse files Browse the repository at this point in the history
Added EDFE data wait timeout and functionality skip data packet send for testing data wait timeout.

Added spossibility to test EDFE sender re-send logic.

EDFE is not ccaepted for brodcast traffic.
  • Loading branch information
Juha Heiskanen committed Aug 14, 2020
1 parent 51bf94e commit 8f1f9d5
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 3 deletions.
1 change: 1 addition & 0 deletions nanostack/mlme.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ typedef enum {
macAutoRequestKeyIndex = 0x7b, /*<The index of the key used for automatic data*/
macDefaultKeySource = 0x7c, /*<Default key source*/
//NON standard extension
macEdfeForceStop = 0xf2, /*< Use this command for Data wait timeout at LLC: Mac stop Edfe session data wait and enable normal FHSS mode */
macSetDataWhitening = 0xf3, /*< Enable or disable data whitening, boolean true for enable, false for disable */
macCCAThresholdStart = 0xf4, /*< Start automatic CCA threshold */
macDevicePendingAckTrig = 0xf5, /*< Trig Pending ACK for Accepted Data packet for temporary neighbour */
Expand Down
26 changes: 26 additions & 0 deletions nanostack/net_ws_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,32 @@ int ws_test_next_gtk_set(int8_t interface_id, uint8_t *gtk[4]);
*/
int ws_test_6lowpan_fragmentation_mtu_size_set(int8_t interface_id, uint16_t mtu_size);

/**
* Disable First EDFE data packet send.
*
* Made only for test purpose for test EDFE client Data wait timeout.
*
* \param interface_id Network interface ID.
* \param skip True for skip first data packet false disable unused flag.
*
* \return 0 Success
* \return <0 Failure
*/
void ws_test_skip_edfe_data_send(int8_t interface_id, bool skip);

/**
* Drop configured EDFE data packets.
*
* Made only for test purpose for test EDFE data sender retry send logic.
*
* \param interface_id Network interface ID.
* \param number_of_dropped_frames How many packets will be dropped.
*
* \return 0 Success
* \return <0 Failure
*/
int8_t ws_test_drop_edfe_data_frames(int8_t interface_id, uint8_t number_of_dropped_frames);

#ifdef __cplusplus
}
#endif
Expand Down
5 changes: 5 additions & 0 deletions source/6LoWPAN/ws/ws_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@
#include <ns_list.h>
#include <nsdynmemLIB.h>
#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"
Expand Down Expand Up @@ -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);
}


Expand Down
2 changes: 2 additions & 0 deletions source/6LoWPAN/ws/ws_llc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
80 changes: 78 additions & 2 deletions source/6LoWPAN/ws/ws_llc_data_service.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down
23 changes: 22 additions & 1 deletion source/MAC/IEEE802_15_4/mac_mcps_sap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{

Expand All @@ -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) {
Expand All @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions source/MAC/IEEE802_15_4/mac_mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
11 changes: 11 additions & 0 deletions source/MAC/IEEE802_15_4/mac_pd_sap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{

Expand Down
2 changes: 2 additions & 0 deletions source/MAC/IEEE802_15_4/mac_pd_sap.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_ */
5 changes: 5 additions & 0 deletions test/nanostack/unittest/stub/mac_pd_sap_stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

0 comments on commit 8f1f9d5

Please sign in to comment.