Skip to content

Commit

Permalink
Remove recursion from MAC layer (ARMmbed#1826)
Browse files Browse the repository at this point in the history
Failing MCPS write request is calling callback function directly and
a caller would then trigger a new MCPS write request. This recursion
can cause stack overflow in some conditions.

Change failing data request to use event queue when returning status
back to caller.
  • Loading branch information
Arto Kinnunen authored Sep 24, 2018
1 parent 06e3243 commit 2f5a2ce
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 20 deletions.
1 change: 1 addition & 0 deletions source/MAC/IEEE802_15_4/mac_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ typedef enum mac_event_t {
MAC_TX_FAIL,
MAC_TX_TIMEOUT,
MAC_UNKNOWN_DESTINATION,
MAC_TX_PRECOND_FAIL
} mac_event_t;

typedef enum mac_tx_status_type_t {
Expand Down
27 changes: 10 additions & 17 deletions source/MAC/IEEE802_15_4/mac_mcps_sap.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ static void mac_data_poll_radio_disable_check(protocol_interface_rf_mac_setup_s

static void mcps_data_confirm_cb(protocol_interface_rf_mac_setup_s *rf_mac_setup, mcps_data_conf_t *confirm, mac_pre_parsed_frame_t *ack_buf)
{

mac_data_poll_radio_disable_check(rf_mac_setup);

if( get_sw_mac_api(rf_mac_setup) ) {
Expand Down Expand Up @@ -1123,8 +1122,8 @@ static int8_t mac_ack_sap_rx_handler(mac_pre_parsed_frame_t *buf, protocol_inter
return 0;
}

static void mac_pd_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_mac_setup) {

static void mac_pd_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_mac_setup)
{
if (rf_mac_setup->active_pd_data_request) {
mac_pre_build_frame_t *buffer = rf_mac_setup->active_pd_data_request;
if (mac_data_request_confirmation_finnish(rf_mac_setup, buffer) ) {
Expand All @@ -1146,8 +1145,8 @@ static void mac_pd_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_mac
}


static void mac_pd_data_ack_handler(mac_pre_parsed_frame_t *buf) {

static void mac_pd_data_ack_handler(mac_pre_parsed_frame_t *buf)
{
protocol_interface_rf_mac_setup_s *rf_mac_setup = buf->mac_class_ptr;

if (!rf_mac_setup->active_pd_data_request) {
Expand Down Expand Up @@ -1357,7 +1356,9 @@ static void mac_common_data_confirmation_handle (protocol_interface_rf_mac_setup
buf->status = MLME_TRANSACTION_EXPIRED;
} else if (m_event == MAC_UNKNOWN_DESTINATION) {
buf->status = MLME_UNAVAILABLE_KEY;
}
}/** else if (m_event == MAC_TX_PRECOND_FAIL) {
* Nothing to do, status already set to buf->status.
}**/
}
}

Expand Down Expand Up @@ -1904,17 +1905,9 @@ void mcps_sap_pd_req_queue_write(protocol_interface_rf_mac_setup_s *rf_mac_setup
//Start TX process immediately
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;
mcps_data_conf_t confirm;
memset(&confirm, 0, sizeof(mcps_data_conf_t));
confirm.msduHandle = buffer->msduHandle;
confirm.status = buffer->status;
bool requested_from_up = buffer->upper_layer_request;
mcps_sap_prebuild_frame_buffer_free(buffer);
if (requested_from_up) {
mcps_data_confirm_cb(rf_mac_setup, &confirm, NULL);
}
//Call
rf_mac_setup->mac_tx_result = MAC_TX_PRECOND_FAIL;
rf_mac_setup->macTxRequestAck = false;
mcps_sap_pd_confirm(rf_mac_setup);
}

return;
Expand Down
7 changes: 4 additions & 3 deletions test/nanostack/unittest/mac/mac_mcps_sap/test_mac_mcps_sap.c
Original file line number Diff line number Diff line change
Expand Up @@ -2463,11 +2463,11 @@ bool test_mcps_sap_data_req_handler()
nsdynmemlib_stub.returnCounter = 1;
data_req.msduHandle = msdu_handle++;
mcps_sap_data_req_handler(rf_mac_setup, &data_req);
if (rf_mac_setup->active_pd_data_request || !data_confirm_valid) {
/* async callback is not called, active_pd_data_request available in rf_mac_setup */
if (!rf_mac_setup->active_pd_data_request || data_confirm_valid) {
return false;
}


//Test with unknow neighbor
mac_security_mib_stub.key_ptr = &key_description;

Expand All @@ -2477,7 +2477,8 @@ bool test_mcps_sap_data_req_handler()
data_req.TxAckReq = true;
mcps_sap_data_req_handler(rf_mac_setup, &data_req);
data_req.msduHandle = msdu_handle++;
if (rf_mac_setup->active_pd_data_request || !data_confirm_valid) {
/* async callback is not called, active_pd_data_request available in rf_mac_setup */
if (!rf_mac_setup->active_pd_data_request || data_confirm_valid) {
return false;
}

Expand Down

0 comments on commit 2f5a2ce

Please sign in to comment.