diff --git a/source/MAC/IEEE802_15_4/mac_defines.h b/source/MAC/IEEE802_15_4/mac_defines.h index 1a3e2e4cc119..8a1c2edc9d63 100644 --- a/source/MAC/IEEE802_15_4/mac_defines.h +++ b/source/MAC/IEEE802_15_4/mac_defines.h @@ -91,8 +91,12 @@ typedef enum arm_nwk_mlme_event_type { ARM_NWK_MAC_MLME_INDIRECT_DATA_POLL_AFTER_DATA = 5, } arm_nwk_mlme_event_type_e; +#define ENHANCED_ACK_MAX_LENGTH 255 + typedef struct dev_driver_tx_buffer { uint8_t *buf; + uint8_t *enhanced_ack_buf; + uint16_t ack_len; uint16_t len; unsigned priority:2; } dev_driver_tx_buffer_s; diff --git a/source/MAC/IEEE802_15_4/mac_mcps_sap.c b/source/MAC/IEEE802_15_4/mac_mcps_sap.c index a2cebe4c26d2..f118770c330b 100644 --- a/source/MAC/IEEE802_15_4/mac_mcps_sap.c +++ b/source/MAC/IEEE802_15_4/mac_mcps_sap.c @@ -1688,7 +1688,15 @@ int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, const m //Add MHR length to total length frame_length += buffer->mac_header_length_with_security + buffer->security_mic_len; - if ((frame_length) > dev_driver->phy_MTU - 2) { + uint16_t ack_mtu_size; + if (ENHANCED_ACK_MAX_LENGTH > dev_driver->phy_MTU) { + ack_mtu_size = dev_driver->phy_MTU; + } else { + ack_mtu_size = ENHANCED_ACK_MAX_LENGTH; + } + + + if ((frame_length) > ack_mtu_size - 2) { buffer->status = MLME_FRAME_TOO_LONG; if (buffer->fcf_dsn.securityEnabled) { @@ -1700,12 +1708,12 @@ int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, const m } rf_ptr->mac_tx_status.length = frame_length; - uint8_t *ptr = tx_buf->buf; + uint8_t *ptr = tx_buf->enhanced_ack_buf; if (dev_driver->phy_header_length) { ptr += dev_driver->phy_header_length; } - tx_buf->len = frame_length; + tx_buf->ack_len = frame_length; uint8_t *mhr_start = ptr; buffer->tx_time = mac_mcps_sap_get_phy_timestamp(rf_ptr) + 300; //Send 300 us later @@ -1795,6 +1803,7 @@ static int8_t mcps_generic_packet_rebuild(protocol_interface_rf_mac_setup_s *rf_ static int8_t mcps_pd_data_cca_trig(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer) { + platform_enter_critical(); mac_mlme_mac_radio_enable(rf_ptr); rf_ptr->macTxProcessActive = true; if (rf_ptr->rf_csma_extension_supported) { @@ -1804,6 +1813,11 @@ static int8_t mcps_pd_data_cca_trig(protocol_interface_rf_mac_setup_s *rf_ptr, m cca_enabled = false; rf_ptr->mac_ack_tx_active = true; } else { + if (rf_ptr->mac_ack_tx_active) { + mac_csma_backoff_start(rf_ptr); + platform_exit_critical(); + return -1; + } cca_enabled = true; } mac_pd_sap_set_phy_tx_time(rf_ptr, buffer->tx_time, cca_enabled); @@ -1817,6 +1831,7 @@ static int8_t mcps_pd_data_cca_trig(protocol_interface_rf_mac_setup_s *rf_ptr, m if (rf_ptr->active_pd_data_request) { mac_csma_backoff_start(rf_ptr); } + platform_exit_critical(); return -1; } mac_csma_backoff_start(rf_ptr); @@ -1824,7 +1839,7 @@ static int8_t mcps_pd_data_cca_trig(protocol_interface_rf_mac_setup_s *rf_ptr, m } else { timer_mac_start(rf_ptr, MAC_TIMER_CCA, (uint16_t)(buffer->tx_time / 50)); } - + platform_exit_critical(); return 0; } diff --git a/source/MAC/IEEE802_15_4/mac_mlme.c b/source/MAC/IEEE802_15_4/mac_mlme.c index 057e4fac1a62..51c63f329f09 100644 --- a/source/MAC/IEEE802_15_4/mac_mlme.c +++ b/source/MAC/IEEE802_15_4/mac_mlme.c @@ -983,6 +983,7 @@ void mac_mlme_data_base_deallocate(struct protocol_interface_rf_mac_setup *rf_ma eventOS_callback_timer_unregister(rf_mac->mac_mcps_timer); ns_dyn_mem_free(rf_mac->dev_driver_tx_buffer.buf); + ns_dyn_mem_free(rf_mac->dev_driver_tx_buffer.enhanced_ack_buf); ns_dyn_mem_free(rf_mac->mac_beacon_payload); mac_sec_mib_deinit(rf_mac); diff --git a/source/MAC/IEEE802_15_4/mac_pd_sap.c b/source/MAC/IEEE802_15_4/mac_pd_sap.c index 7903da01c524..8f71f73b3093 100644 --- a/source/MAC/IEEE802_15_4/mac_pd_sap.c +++ b/source/MAC/IEEE802_15_4/mac_pd_sap.c @@ -159,9 +159,19 @@ int8_t mac_plme_cca_req(protocol_interface_rf_mac_setup_s *rf_mac_setup) { return 0; } - if (dev_driver->tx(tx_buf->buf, tx_buf->len, 1, PHY_LAYER_PAYLOAD) == 0) { + uint8_t *buffer; + uint16_t length; + if (rf_mac_setup->mac_ack_tx_active) { + buffer = tx_buf->enhanced_ack_buf; + length = tx_buf->ack_len; + } else { + buffer = tx_buf->buf; + length = tx_buf->len; + } + if (dev_driver->tx(buffer, length, 1, PHY_LAYER_PAYLOAD) == 0) { return 0; } + rf_mac_setup->macRfRadioTxActive = false; return -1; } diff --git a/source/MAC/IEEE802_15_4/sw_mac.c b/source/MAC/IEEE802_15_4/sw_mac.c index fc579a02d340..3c8dee0721c7 100644 --- a/source/MAC/IEEE802_15_4/sw_mac.c +++ b/source/MAC/IEEE802_15_4/sw_mac.c @@ -252,6 +252,22 @@ static int8_t ns_sw_mac_api_enable_mcps_ext(mac_api_t *api, mcps_data_indication cur->data_ind_ext_cb = data_ind_cb; cur->enhanced_ack_data_req_cb = ack_data_req_cb; if (data_cnf_cb && data_ind_cb && ack_data_req_cb) { + arm_device_driver_list_s *dev_driver = mac_store.setup->dev_driver; + ns_dyn_mem_free(mac_store.setup->dev_driver_tx_buffer.enhanced_ack_buf); + + uint16_t total_length; + if (ENHANCED_ACK_MAX_LENGTH > dev_driver->phy_driver->phy_MTU) { + total_length = dev_driver->phy_driver->phy_MTU; + } else { + total_length = ENHANCED_ACK_MAX_LENGTH; + } + + total_length += (dev_driver->phy_driver->phy_header_length + dev_driver->phy_driver->phy_tail_length); + mac_store.setup->dev_driver_tx_buffer.enhanced_ack_buf = ns_dyn_mem_alloc(total_length); + if (!mac_store.setup->dev_driver_tx_buffer.enhanced_ack_buf) { + return -2; + } + mac_store.setup->mac_extension_enabled = true; } else { mac_store.setup->mac_extension_enabled = false; diff --git a/test/nanostack/unittest/mac/mac_mcps_sap/Makefile b/test/nanostack/unittest/mac/mac_mcps_sap/Makefile index ff2085bda092..9605389e2ede 100644 --- a/test/nanostack/unittest/mac/mac_mcps_sap/Makefile +++ b/test/nanostack/unittest/mac/mac_mcps_sap/Makefile @@ -26,6 +26,7 @@ TEST_SRC_FILES = \ ../../stub/mac_pairwise_key_stub.c \ ../../stub/protocol_stats_stub.c \ ../../stub/ccm_security_stub.c \ + ../../stub/platform_stub.c \ ../../stub/fhss_config_stub.c \ include ../../MakefileWorker.mk