diff --git a/nanostack/mlme.h b/nanostack/mlme.h index 5db31f7c3d0..8f0a354514e 100644 --- a/nanostack/mlme.h +++ b/nanostack/mlme.h @@ -264,6 +264,7 @@ typedef enum { macAutoRequestKeyIndex = 0x7b, /*mac_api->mlme_req(cur->mac_api, MLME_SET, &set_request); + // Set multi CSMA-CA configuration + mlme_multi_csma_ca_param_t multi_csma_params = {WS_NUMBER_OF_CSMA_PERIODS, WS_CSMA_MULTI_CCA_INTERVAL}; + set_request.attr = macMultiCSMAParameters; + set_request.value_pointer = &multi_csma_params; + set_request.value_size = sizeof(mlme_multi_csma_ca_param_t); + cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_request); return 0; } diff --git a/source/6LoWPAN/ws/ws_common_defines.h b/source/6LoWPAN/ws/ws_common_defines.h index ec7511cb3c2..31f47352556 100644 --- a/source/6LoWPAN/ws/ws_common_defines.h +++ b/source/6LoWPAN/ws/ws_common_defines.h @@ -232,6 +232,11 @@ typedef struct ws_bs_ie { */ #define WS_TACK_MAX_MS 5 +// With FHSS we need to check CCA twice on TX channel +#define WS_NUMBER_OF_CSMA_PERIODS 2 +// Interval between two CCA checks +#define WS_CSMA_MULTI_CCA_INTERVAL 1000 + /* Default FHSS timing information * */ diff --git a/source/MAC/IEEE802_15_4/mac_defines.h b/source/MAC/IEEE802_15_4/mac_defines.h index d5623049ed1..315dacb6e74 100644 --- a/source/MAC/IEEE802_15_4/mac_defines.h +++ b/source/MAC/IEEE802_15_4/mac_defines.h @@ -219,6 +219,8 @@ typedef struct protocol_interface_rf_mac_setup { uint16_t mac_ack_wait_duration; uint8_t mac_mlme_retry_max; uint8_t aUnitBackoffPeriod; + uint8_t number_of_csma_ca_periods; /**< Number of CSMA-CA periods */ + uint16_t multi_cca_interval; /**< Length of the additional CSMA-CA period(s) in microseconds */ /* Indirect queue parameters */ struct mac_pre_build_frame *indirect_pd_data_request_queue; arm_event_t mac_mcps_timer_event; diff --git a/source/MAC/IEEE802_15_4/mac_mcps_sap.c b/source/MAC/IEEE802_15_4/mac_mcps_sap.c index 0271d52f179..ff39b591c79 100644 --- a/source/MAC/IEEE802_15_4/mac_mcps_sap.c +++ b/source/MAC/IEEE802_15_4/mac_mcps_sap.c @@ -1830,9 +1830,9 @@ static int8_t mcps_pd_data_cca_trig(protocol_interface_rf_mac_setup_s *rf_ptr, m } // Use double CCA check with FHSS for data packets only if (rf_ptr->fhss_api && !rf_ptr->mac_ack_tx_active && !rf_ptr->active_pd_data_request->asynch_request) { - if ((buffer->tx_time - (MAC_CSMA_MULTI_CCA_INTERVAL * (MAC_NUMBER_OF_CSMA_PERIODS - 1))) > mac_mcps_sap_get_phy_timestamp(rf_ptr)) { - buffer->csma_periods_left = MAC_NUMBER_OF_CSMA_PERIODS; - buffer->tx_time -= (MAC_CSMA_MULTI_CCA_INTERVAL * (MAC_NUMBER_OF_CSMA_PERIODS - 1)); + if ((buffer->tx_time - (rf_ptr->multi_cca_interval * (rf_ptr->number_of_csma_ca_periods - 1))) > mac_mcps_sap_get_phy_timestamp(rf_ptr)) { + buffer->csma_periods_left = rf_ptr->number_of_csma_ca_periods; + buffer->tx_time -= (rf_ptr->multi_cca_interval * (rf_ptr->number_of_csma_ca_periods - 1)); } } mac_pd_sap_set_phy_tx_time(rf_ptr, buffer->tx_time, cca_enabled); diff --git a/source/MAC/IEEE802_15_4/mac_mcps_sap.h b/source/MAC/IEEE802_15_4/mac_mcps_sap.h index c039628d56f..e5cd63995ab 100644 --- a/source/MAC/IEEE802_15_4/mac_mcps_sap.h +++ b/source/MAC/IEEE802_15_4/mac_mcps_sap.h @@ -57,10 +57,10 @@ typedef enum { #define MAC_SAP_TRIG_TX 7 #define MCPS_SAP_DATA_ACK_CNF_EVENT 8 -// With FHSS we need to check CCA twice on TX channel -#define MAC_NUMBER_OF_CSMA_PERIODS 2 +// Default number of CSMA-CA periods +#define MAC_DEFAULT_NUMBER_OF_CSMA_PERIODS 1 // Interval between two CCA checks -#define MAC_CSMA_MULTI_CCA_INTERVAL 1000 +#define MAC_DEFAULT_CSMA_MULTI_CCA_INTERVAL 1000 /** * @brief struct mac_aux_security_header_t MAC auxiliarity security header structure diff --git a/source/MAC/IEEE802_15_4/mac_mlme.c b/source/MAC/IEEE802_15_4/mac_mlme.c index cc6fa3d5d50..0e88b3c6434 100644 --- a/source/MAC/IEEE802_15_4/mac_mlme.c +++ b/source/MAC/IEEE802_15_4/mac_mlme.c @@ -724,6 +724,16 @@ static int8_t mac_mlme_handle_set_values(protocol_interface_rf_mac_setup_s *rf_m return -1; } +static int8_t mac_mlme_set_multi_csma_parameters(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mlme_set_t *set_req) +{ + mlme_multi_csma_ca_param_t multi_csma_params; + memcpy(&multi_csma_params, set_req->value_pointer, sizeof(mlme_multi_csma_ca_param_t)); + rf_mac_setup->multi_cca_interval = multi_csma_params.multi_cca_interval; + rf_mac_setup->number_of_csma_ca_periods = multi_csma_params.number_of_csma_ca_periods; + tr_debug("Multi CSMA-CA, interval: %u, periods %u", rf_mac_setup->multi_cca_interval, rf_mac_setup->number_of_csma_ca_periods); + return 0; +} + int8_t mac_mlme_set_req(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mlme_set_t *set_req) { if (!set_req || !rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver) { @@ -749,6 +759,8 @@ int8_t mac_mlme_set_req(protocol_interface_rf_mac_setup_s *rf_mac_setup, const m memcpy(rf_mac_setup->coord_long_address, set_req->value_pointer, 8); } return 0; + case macMultiCSMAParameters: + return mac_mlme_set_multi_csma_parameters(rf_mac_setup, set_req); case macRfConfiguration: rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_RF_CONFIGURATION, (uint8_t *) set_req->value_pointer); mac_mlme_set_symbol_rate(rf_mac_setup); @@ -1072,6 +1084,8 @@ protocol_interface_rf_mac_setup_s *mac_mlme_data_base_allocate(uint8_t *mac64, a entry->mac_interface_id = -1; entry->dev_driver = dev_driver; entry->aUnitBackoffPeriod = 20; //This can be different in some Platform 20 comes from 12-symbol turnaround and 8 symbol CCA read + entry->number_of_csma_ca_periods = MAC_DEFAULT_NUMBER_OF_CSMA_PERIODS; + entry->multi_cca_interval = MAC_DEFAULT_CSMA_MULTI_CCA_INTERVAL; if (mac_sec_mib_init(entry, storage_sizes) != 0) { mac_mlme_data_base_deallocate(entry); diff --git a/source/MAC/IEEE802_15_4/mac_pd_sap.c b/source/MAC/IEEE802_15_4/mac_pd_sap.c index 59e372cb8d8..c6c68ec0661 100644 --- a/source/MAC/IEEE802_15_4/mac_pd_sap.c +++ b/source/MAC/IEEE802_15_4/mac_pd_sap.c @@ -102,8 +102,8 @@ uint32_t mac_csma_backoff_get(protocol_interface_rf_mac_setup_s *rf_mac_setup) backoff_in_us += MIN_FHSS_CSMA_PERIOD_US; } // Backoff must be long enough to make multiple CCA checks - if (backoff_in_us < (MAC_CSMA_MULTI_CCA_INTERVAL * (MAC_NUMBER_OF_CSMA_PERIODS - 1))) { - backoff_in_us += (MAC_CSMA_MULTI_CCA_INTERVAL * (MAC_NUMBER_OF_CSMA_PERIODS - 1)); + if (backoff_in_us < (uint32_t)(rf_mac_setup->multi_cca_interval * (rf_mac_setup->number_of_csma_ca_periods - 1))) { + backoff_in_us += ((rf_mac_setup->multi_cca_interval * (rf_mac_setup->number_of_csma_ca_periods - 1)) - backoff_in_us); } } return backoff_in_us; @@ -442,7 +442,7 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r return PHY_TX_NOT_ALLOWED; } if (--active_buf->csma_periods_left > 0) { - active_buf->tx_time += MAC_CSMA_MULTI_CCA_INTERVAL; + active_buf->tx_time += rf_ptr->multi_cca_interval; mac_pd_sap_set_phy_tx_time(rf_ptr, active_buf->tx_time, true); return PHY_RESTART_CSMA; }