From 1d8e3d7398cbecab5cbaf9a6934cf0f8a800719b Mon Sep 17 00:00:00 2001 From: Juha Heiskanen Date: Wed, 3 Oct 2018 15:14:10 +0300 Subject: [PATCH 1/3] MAC Asynch Data request update Switch channel at cca prepare callback only. Change-Id: I5af62463bd6f3b7c55ccaa0812f8259fae4082d8 --- source/MAC/IEEE802_15_4/mac_mcps_sap.c | 43 +++---------- source/MAC/IEEE802_15_4/mac_mlme.c | 10 +-- source/MAC/IEEE802_15_4/mac_mlme.h | 2 +- source/MAC/IEEE802_15_4/mac_pd_sap.c | 66 +++++++++++++------- test/nanostack/unittest/stub/mac_mlme_stub.c | 2 +- 5 files changed, 58 insertions(+), 65 deletions(-) diff --git a/source/MAC/IEEE802_15_4/mac_mcps_sap.c b/source/MAC/IEEE802_15_4/mac_mcps_sap.c index 608dcd0e89f..1c2be6be349 100644 --- a/source/MAC/IEEE802_15_4/mac_mcps_sap.c +++ b/source/MAC/IEEE802_15_4/mac_mcps_sap.c @@ -88,47 +88,18 @@ static uint32_t mac_mcps_sap_get_phy_timestamp(protocol_interface_rf_mac_setup_s return timestamp; } -static void mac_data_request_init(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer) -{ - rf_mac_setup->active_pd_data_request = buffer; - if (buffer->asynch_request) { - buffer->asynch_channel = rf_mac_setup->mac_channel; //Store Original channel - uint16_t channel = mlme_scan_analyze_next_channel(&buffer->asynch_channel_list); - if (channel <= 0xff) { - uint8_t switch_channel = channel; - if (rf_mac_setup->mac_channel != switch_channel) { - mac_mlme_mac_radio_disabled(rf_mac_setup); - rf_mac_setup->mac_channel = channel; - mac_mlme_mac_radio_enable(rf_mac_setup); - } - } - } -} - static bool mac_data_request_confirmation_finnish(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer) { if (!buffer->asynch_request) { return true; } - uint16_t channel = mlme_scan_analyze_next_channel(&buffer->asynch_channel_list); - uint8_t switch_channel; - bool return_value; - - if (channel > 0x00ff) { - return_value = true; - switch_channel = buffer->asynch_channel; - } else { - switch_channel = channel; - return_value = false; - } - //Set original Channel back if channel is switched - if (rf_mac_setup->mac_channel != switch_channel) { - mac_mlme_mac_radio_disabled(rf_mac_setup); - rf_mac_setup->mac_channel = switch_channel; - mac_mlme_mac_radio_enable(rf_mac_setup); + if (mlme_scan_analyze_next_channel(&buffer->asynch_channel_list, false) > 0x00ff) { + mac_mlme_rf_channel_change(rf_mac_setup, buffer->asynch_channel); + return true; } - return return_value; + + return false; } @@ -1081,7 +1052,7 @@ void mac_mcps_trig_buffer_from_queue(protocol_interface_rf_mac_setup_s *rf_mac_s buffer = mcps_sap_pd_req_queue_read(rf_mac_setup, is_bc_queue, false); if (buffer) { - mac_data_request_init(rf_mac_setup, buffer); + rf_mac_setup->active_pd_data_request = 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); @@ -1923,7 +1894,7 @@ 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); + rf_mac_setup->active_pd_data_request = buffer; if (mcps_pd_data_request(rf_mac_setup, buffer) != 0) { rf_mac_setup->mac_tx_result = MAC_TX_PRECOND_FAIL; rf_mac_setup->macTxRequestAck = false; diff --git a/source/MAC/IEEE802_15_4/mac_mlme.c b/source/MAC/IEEE802_15_4/mac_mlme.c index 409cc102a60..50c20eab564 100644 --- a/source/MAC/IEEE802_15_4/mac_mlme.c +++ b/source/MAC/IEEE802_15_4/mac_mlme.c @@ -85,7 +85,7 @@ static void mac_mlme_energy_scan_start(protocol_interface_rf_mac_setup_s *rf_mac rf_mac_setup->macRfRadioTxActive = false; } -uint16_t mlme_scan_analyze_next_channel(channel_list_s *mac_channel_list) +uint16_t mlme_scan_analyze_next_channel(channel_list_s *mac_channel_list, bool clear_channel) { uint8_t i, j = 0, k = 1; uint32_t mask = 1; @@ -101,7 +101,9 @@ uint16_t mlme_scan_analyze_next_channel(channel_list_s *mac_channel_list) { if (*channel_mask & mask) { - *channel_mask &= ~mask; + if (clear_channel) { + *channel_mask &= ~mask; + } return (i+j*32); } mask <<= 1; @@ -280,7 +282,7 @@ static void mac_mlme_scan_start(protocol_interface_rf_mac_setup_s *rf_mac_setup) { uint8_t channel; - channel = (uint8_t) mlme_scan_analyze_next_channel(&rf_mac_setup->mac_channel_list); + channel = (uint8_t) mlme_scan_analyze_next_channel(&rf_mac_setup->mac_channel_list, true); mac_mlme_scan_init(channel, rf_mac_setup); } @@ -795,7 +797,7 @@ static void mlme_scan_operation(protocol_interface_rf_mac_setup_s *rf_mac_setup) resp->ResultListSize++; } - channel = mlme_scan_analyze_next_channel(&rf_mac_setup->mac_channel_list); + channel = mlme_scan_analyze_next_channel(&rf_mac_setup->mac_channel_list, true); if (channel > 0xff || rf_mac_setup->mac_mlme_scan_resp->ResultListSize == MLME_MAC_RES_SIZE_MAX) { resp->status = MLME_SUCCESS; tr_debug("Scan Complete..Halt MAC"); diff --git a/source/MAC/IEEE802_15_4/mac_mlme.h b/source/MAC/IEEE802_15_4/mac_mlme.h index 41f29601596..5878f702707 100644 --- a/source/MAC/IEEE802_15_4/mac_mlme.h +++ b/source/MAC/IEEE802_15_4/mac_mlme.h @@ -125,6 +125,6 @@ int8_t mac_mlme_beacon_tx(struct protocol_interface_rf_mac_setup *rf_ptr); uint8_t mac_mlme_beacon_req_tx(struct protocol_interface_rf_mac_setup *rf_ptr); int8_t mac_mlme_virtual_confirmation_handle(int8_t driver_id, const uint8_t *data_ptr, uint16_t length); -uint16_t mlme_scan_analyze_next_channel(struct channel_list_s *mac_channel_list); +uint16_t mlme_scan_analyze_next_channel(struct channel_list_s *mac_channel_list, bool clear_channel); #endif /* MAC_MLME_H_ */ diff --git a/source/MAC/IEEE802_15_4/mac_pd_sap.c b/source/MAC/IEEE802_15_4/mac_pd_sap.c index 1b0b57cb278..d935d818014 100644 --- a/source/MAC/IEEE802_15_4/mac_pd_sap.c +++ b/source/MAC/IEEE802_15_4/mac_pd_sap.c @@ -344,6 +344,20 @@ static bool mac_data_counter_too_small(uint32_t current_counter, uint32_t packet } +static bool mac_data_asynch_channel_switch(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *active_buf) +{ + if (!active_buf || !active_buf->asynch_request) { + return false; + } + active_buf->asynch_channel = rf_ptr->mac_channel; //Store Original channel + uint16_t channel = mlme_scan_analyze_next_channel(&active_buf->asynch_channel_list, true); + if (channel <= 0xff) { + mac_mlme_rf_channel_change(rf_ptr, channel); + + } + return true; +} + 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) { @@ -352,10 +366,16 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r } if (status == PHY_LINK_CCA_PREPARE) { + + if (rf_ptr->mac_ack_tx_active) { + return 0; + } + + if (mac_data_asynch_channel_switch(rf_ptr, rf_ptr->active_pd_data_request) ) { + return 0; + } + if (rf_ptr->fhss_api) { - if (rf_ptr->mac_ack_tx_active) { - return 0; - } mac_pre_build_frame_t *active_buf = rf_ptr->active_pd_data_request; if (!active_buf) { return -1; @@ -367,28 +387,28 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r uint8_t *synch_info = tx_buf->buf + rf_ptr->dev_driver->phy_driver->phy_header_length + tx_buf->len - FHSS_SYNCH_INFO_LENGTH; rf_ptr->fhss_api->write_synch_info(rf_ptr->fhss_api, synch_info, 0, FHSS_SYNCH_FRAME, 0); } - if (active_buf->asynch_request == false) { - // Change to destination channel and write synchronization info to Beacon frames here - int tx_handle_retval = rf_ptr->fhss_api->tx_handle(rf_ptr->fhss_api, !mac_is_ack_request_set(active_buf), - active_buf->DstAddr, mac_convert_frame_type_to_fhss(active_buf->fcf_dsn.frametype), - active_buf->mac_payload_length, rf_ptr->dev_driver->phy_driver->phy_header_length, - rf_ptr->dev_driver->phy_driver->phy_tail_length, active_buf->tx_time); - // When FHSS TX handle returns -1, transmission of the packet is currently not allowed -> restart CCA timer - if (tx_handle_retval == -1) { - mac_sap_cca_fail_cb(rf_ptr); - return -2; - } - // When FHSS TX handle returns -3, we are trying to transmit broadcast packet on unicast channel -> push back - // to queue by using CCA fail event - if (tx_handle_retval == -3) { - mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL); - return -3; - } else if (tx_handle_retval == -2) { - mac_tx_done_state_set(rf_ptr, MAC_UNKNOWN_DESTINATION); - return -2; - } + + // Change to destination channel and write synchronization info to Beacon frames here + int tx_handle_retval = rf_ptr->fhss_api->tx_handle(rf_ptr->fhss_api, !mac_is_ack_request_set(active_buf), + active_buf->DstAddr, mac_convert_frame_type_to_fhss(active_buf->fcf_dsn.frametype), + active_buf->mac_payload_length, rf_ptr->dev_driver->phy_driver->phy_header_length, + rf_ptr->dev_driver->phy_driver->phy_tail_length, active_buf->tx_time); + // When FHSS TX handle returns -1, transmission of the packet is currently not allowed -> restart CCA timer + if (tx_handle_retval == -1) { + mac_sap_cca_fail_cb(rf_ptr); + return -2; + } + // When FHSS TX handle returns -3, we are trying to transmit broadcast packet on unicast channel -> push back + // to queue by using CCA fail event + if (tx_handle_retval == -3) { + mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL); + return -3; + } else if (tx_handle_retval == -2) { + mac_tx_done_state_set(rf_ptr, MAC_UNKNOWN_DESTINATION); + return -2; } } + return 0; } diff --git a/test/nanostack/unittest/stub/mac_mlme_stub.c b/test/nanostack/unittest/stub/mac_mlme_stub.c index 3d7c9a745dd..420263d2fa7 100644 --- a/test/nanostack/unittest/stub/mac_mlme_stub.c +++ b/test/nanostack/unittest/stub/mac_mlme_stub.c @@ -174,7 +174,7 @@ int8_t mac_mlme_virtual_confirmation_handle(int8_t driver_id, const uint8_t *dat return 0; } -uint16_t mlme_scan_analyze_next_channel(channel_list_s *mac_channel_list) +uint16_t mlme_scan_analyze_next_channel(channel_list_s *mac_channel_list, bool clear_channel) { return mac_mlme_stub.uint16_value; } From f1e7f06a1c86d2ff3ee439cc3acf244a5cdb6b84 Mon Sep 17 00:00:00 2001 From: Juha Heiskanen Date: Thu, 4 Oct 2018 10:05:55 +0300 Subject: [PATCH 2/3] Fix broken unit test. Change-Id: I4f8db0a958be67c4c3f29f27c3b9d8d596328503 --- .../unittest/mac/mac_mcps_sap/test_mac_mcps_sap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/nanostack/unittest/mac/mac_mcps_sap/test_mac_mcps_sap.c b/test/nanostack/unittest/mac/mac_mcps_sap/test_mac_mcps_sap.c index d3093344afd..2513360bba1 100644 --- a/test/nanostack/unittest/mac/mac_mcps_sap/test_mac_mcps_sap.c +++ b/test/nanostack/unittest/mac/mac_mcps_sap/test_mac_mcps_sap.c @@ -796,7 +796,7 @@ bool test_mac_mcps_data_confirmation() rf_mac_setup->mac_channel = 20; mac_mlme_stub.uint16_value = 11; mcps_sap_data_req_handler_ext(rf_mac_setup, &data_req, &ie_list , &channel_list); - if (!rf_mac_setup->active_pd_data_request || rf_mac_setup->mac_channel != 11) { + if (!rf_mac_setup->active_pd_data_request) { return false; } //Test Confirmation to switch channel @@ -804,7 +804,7 @@ bool test_mac_mcps_data_confirmation() mac_mlme_stub.uint16_value = 15; mcps_sap_pd_confirm(rf_mac_setup); - if (!rf_mac_setup->active_pd_data_request || rf_mac_setup->mac_channel != 15) { + if (!rf_mac_setup->active_pd_data_request ) { return false; } @@ -812,7 +812,7 @@ bool test_mac_mcps_data_confirmation() mac_mlme_stub.uint16_value = 0xffff; mcps_sap_pd_confirm(rf_mac_setup); - if (rf_mac_setup->active_pd_data_request || rf_mac_setup->mac_channel != 20) { + if (rf_mac_setup->active_pd_data_request ) { return false; } rf_mac_setup->mac_extension_enabled = false; @@ -3183,7 +3183,7 @@ bool test_mcps_sap_data_req_handler_ext() } data_req.TxAckReq = false; mcps_sap_data_req_handler_ext(rf_mac_setup, &data_req, &ie_list , &channel_list); - if (!rf_mac_setup->active_pd_data_request || rf_mac_setup->mac_channel != 11) { + if (!rf_mac_setup->active_pd_data_request) { return false; } From 279c7084acf218e18ff7c9c2566833d689f3db9e Mon Sep 17 00:00:00 2001 From: Juha Heiskanen Date: Thu, 4 Oct 2018 12:29:27 +0300 Subject: [PATCH 3/3] Trig a new back off period for pending TX if ACK tx is active Change-Id: Ida77974436f77edb60f7a91146a017a14554f167 --- source/MAC/IEEE802_15_4/mac_pd_sap.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/source/MAC/IEEE802_15_4/mac_pd_sap.c b/source/MAC/IEEE802_15_4/mac_pd_sap.c index d935d818014..7903da01c52 100644 --- a/source/MAC/IEEE802_15_4/mac_pd_sap.c +++ b/source/MAC/IEEE802_15_4/mac_pd_sap.c @@ -290,15 +290,22 @@ void mac_pd_sap_state_machine(protocol_interface_rf_mac_setup_s *rf_mac_setup) static void mac_sap_cca_fail_cb(protocol_interface_rf_mac_setup_s *rf_ptr) { - rf_ptr->macRfRadioTxActive = false; - if (rf_ptr->mac_cca_retry > rf_ptr->macMaxCSMABackoffs || (rf_ptr->active_pd_data_request && rf_ptr->active_pd_data_request->asynch_request)) { - //Send MAC_CCA_FAIL - mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL); + if (rf_ptr->mac_ack_tx_active) { + if (rf_ptr->active_pd_data_request) { + mac_csma_backoff_start(rf_ptr); + } } else { - timer_mac_stop(rf_ptr); - mac_csma_BE_update(rf_ptr); - if (mcps_pd_data_rebuild(rf_ptr, rf_ptr->active_pd_data_request) ) { + + rf_ptr->macRfRadioTxActive = false; + if (rf_ptr->mac_cca_retry > rf_ptr->macMaxCSMABackoffs || (rf_ptr->active_pd_data_request && rf_ptr->active_pd_data_request->asynch_request)) { + //Send MAC_CCA_FAIL mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL); + } else { + timer_mac_stop(rf_ptr); + mac_csma_BE_update(rf_ptr); + if (mcps_pd_data_rebuild(rf_ptr, rf_ptr->active_pd_data_request) ) { + mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL); + } } } }