Skip to content

Commit fe4073b

Browse files
author
Jarkko Paso
authored
Merge pull request ARMmbed#2030 from ARMmbed/IOTTHD-3340
Iotthd 3340
2 parents 902fdd8 + 6023d7b commit fe4073b

File tree

10 files changed

+79
-9
lines changed

10 files changed

+79
-9
lines changed

nanostack/mlme.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ typedef enum {
264264
macAutoRequestKeyIndex = 0x7b, /*<The index of the key used for automatic data*/
265265
macDefaultKeySource = 0x7c, /*<Default key source*/
266266
//NON standard extension
267+
macMultiCSMAParameters = 0xfa, /*<Multi CSMA parameters*/
267268
macRfConfiguration = 0xfb, /*<RF channel configuration parameters*/
268269
macAcceptByPassUnknowDevice = 0xfc, /*< Accept data trough MAC if packet is data can be authenticated by group key nad MIC. Security enforsment point must be handled carefully these packets */
269270
macLoadBalancingBeaconTx = 0xfd, /*< Trig Beacon from load balance module periodic */
@@ -499,4 +500,14 @@ typedef struct mlme_poll_conf_s {
499500
uint8_t status; /**< Status of Poll operation */
500501
} mlme_poll_conf_t;
501502

503+
/**
504+
* @brief struct mlme_multi_csma_ca_param_s Set multi CSMA-CA parameters
505+
*
506+
* Non standard extension to perform CCA multiple times before transmission
507+
*/
508+
typedef struct mlme_multi_csma_ca_s {
509+
uint8_t number_of_csma_ca_periods; /**< Number of CSMA-CA periods */
510+
uint16_t multi_cca_interval; /**< Length of the additional CSMA-CA period(s) in microseconds */
511+
} mlme_multi_csma_ca_param_t;
512+
502513
#endif /* MLME_H_ */

nanostack/platform/arm_hal_phy.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
extern "C" {
3030
#endif
3131

32+
/** PHY_LINK_CCA_PREPARE status definitions */
33+
#define PHY_TX_NOT_ALLOWED -1 /**< TX not allowed. Do not continue to CCA process. */
34+
#define PHY_TX_ALLOWED 0 /**< TX allowed. Continue to CCA process. */
35+
#define PHY_RESTART_CSMA 1 /**< Restart CSMA-CA timer. CSMA-CA period must be calculated using given backoff time (PHY_EXTENSION_SET_CSMA_PARAMETERS) */
36+
3237
/** Interface states */
3338
typedef enum {
3439
PHY_INTERFACE_RESET, /**< Reset PHY driver and set to idle. */
@@ -45,7 +50,8 @@ typedef enum {
4550
PHY_LINK_TX_SUCCESS, /**< MAC TX complete. MAC will a make decision to enter wait ACK or TX done state. */
4651
PHY_LINK_TX_FAIL, /**< Link TX process fail. */
4752
PHY_LINK_CCA_FAIL, /**< RF link CCA process fail. */
48-
PHY_LINK_CCA_PREPARE, /**< RX Tx timeout prepare operation like channel switch to Tx channel from Receive one If operation fail must return not zero*/
53+
PHY_LINK_CCA_OK, /**< RF link CCA process ok. */
54+
PHY_LINK_CCA_PREPARE, /**< Prepare for CCA after CSMA-CA: changes to CCA channel and gives permission to TX. See PHY_LINK_CCA_PREPARE status definitions for return values */
4955
} phy_link_tx_status_e;
5056

5157
/** Extension types */

source/6LoWPAN/ws/ws_bootstrap.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,6 +1580,12 @@ int ws_bootstrap_set_rf_config(protocol_interface_info_entry_t *cur, phy_rf_chan
15801580
set_request.value_pointer = &ack_wait_symbols;
15811581
set_request.value_size = sizeof(ack_wait_symbols);
15821582
cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_request);
1583+
// Set multi CSMA-CA configuration
1584+
mlme_multi_csma_ca_param_t multi_csma_params = {WS_NUMBER_OF_CSMA_PERIODS, WS_CSMA_MULTI_CCA_INTERVAL};
1585+
set_request.attr = macMultiCSMAParameters;
1586+
set_request.value_pointer = &multi_csma_params;
1587+
set_request.value_size = sizeof(mlme_multi_csma_ca_param_t);
1588+
cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_request);
15831589
return 0;
15841590
}
15851591

source/6LoWPAN/ws/ws_common_defines.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,11 @@ typedef struct ws_bs_ie {
232232
*/
233233
#define WS_TACK_MAX_MS 5
234234

235+
// With FHSS we need to check CCA twice on TX channel
236+
#define WS_NUMBER_OF_CSMA_PERIODS 1
237+
// Interval between two CCA checks
238+
#define WS_CSMA_MULTI_CCA_INTERVAL 1000
239+
235240
/* Default FHSS timing information
236241
*
237242
*/

source/MAC/IEEE802_15_4/mac_defines.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@ typedef struct protocol_interface_rf_mac_setup {
219219
uint16_t mac_ack_wait_duration;
220220
uint8_t mac_mlme_retry_max;
221221
uint8_t aUnitBackoffPeriod;
222+
uint8_t number_of_csma_ca_periods; /**< Number of CSMA-CA periods */
223+
uint16_t multi_cca_interval; /**< Length of the additional CSMA-CA period(s) in microseconds */
222224
/* Indirect queue parameters */
223225
struct mac_pre_build_frame *indirect_pd_data_request_queue;
224226
arm_event_t mac_mcps_timer_event;

source/MAC/IEEE802_15_4/mac_mcps_sap.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1828,6 +1828,13 @@ static int8_t mcps_pd_data_cca_trig(protocol_interface_rf_mac_setup_s *rf_ptr, m
18281828
}
18291829
cca_enabled = true;
18301830
}
1831+
// Use double CCA check with FHSS for data packets only
1832+
if (rf_ptr->fhss_api && !rf_ptr->mac_ack_tx_active && !rf_ptr->active_pd_data_request->asynch_request) {
1833+
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)) {
1834+
buffer->csma_periods_left = rf_ptr->number_of_csma_ca_periods;
1835+
buffer->tx_time -= (rf_ptr->multi_cca_interval * (rf_ptr->number_of_csma_ca_periods - 1));
1836+
}
1837+
}
18311838
mac_pd_sap_set_phy_tx_time(rf_ptr, buffer->tx_time, cca_enabled);
18321839
if (mac_plme_cca_req(rf_ptr) != 0) {
18331840
if (buffer->fcf_dsn.frametype == MAC_FRAME_ACK) {

source/MAC/IEEE802_15_4/mac_mcps_sap.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ typedef enum {
5757
#define MAC_SAP_TRIG_TX 7
5858
#define MCPS_SAP_DATA_ACK_CNF_EVENT 8
5959

60+
// Default number of CSMA-CA periods
61+
#define MAC_DEFAULT_NUMBER_OF_CSMA_PERIODS 1
62+
// Interval between two CCA checks
63+
#define MAC_DEFAULT_CSMA_MULTI_CCA_INTERVAL 1000
64+
6065
/**
6166
* @brief struct mac_aux_security_header_t MAC auxiliarity security header structure
6267
* INTERNAL use only
@@ -126,6 +131,7 @@ typedef struct mac_pre_build_frame {
126131
uint8_t *mac_payload;
127132
uint8_t status;
128133
uint8_t asynch_channel;
134+
uint8_t csma_periods_left;
129135
uint32_t tx_time;
130136
bool upper_layer_request;
131137
bool mac_allocated_payload_ptr: 1;

source/MAC/IEEE802_15_4/mac_mlme.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,16 @@ static int8_t mac_mlme_handle_set_values(protocol_interface_rf_mac_setup_s *rf_m
724724
return -1;
725725
}
726726

727+
static int8_t mac_mlme_set_multi_csma_parameters(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mlme_set_t *set_req)
728+
{
729+
mlme_multi_csma_ca_param_t multi_csma_params;
730+
memcpy(&multi_csma_params, set_req->value_pointer, sizeof(mlme_multi_csma_ca_param_t));
731+
rf_mac_setup->multi_cca_interval = multi_csma_params.multi_cca_interval;
732+
rf_mac_setup->number_of_csma_ca_periods = multi_csma_params.number_of_csma_ca_periods;
733+
tr_debug("Multi CSMA-CA, interval: %u, periods %u", rf_mac_setup->multi_cca_interval, rf_mac_setup->number_of_csma_ca_periods);
734+
return 0;
735+
}
736+
727737
int8_t mac_mlme_set_req(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mlme_set_t *set_req)
728738
{
729739
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
749759
memcpy(rf_mac_setup->coord_long_address, set_req->value_pointer, 8);
750760
}
751761
return 0;
762+
case macMultiCSMAParameters:
763+
return mac_mlme_set_multi_csma_parameters(rf_mac_setup, set_req);
752764
case macRfConfiguration:
753765
rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_RF_CONFIGURATION, (uint8_t *) set_req->value_pointer);
754766
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
10721084
entry->mac_interface_id = -1;
10731085
entry->dev_driver = dev_driver;
10741086
entry->aUnitBackoffPeriod = 20; //This can be different in some Platform 20 comes from 12-symbol turnaround and 8 symbol CCA read
1087+
entry->number_of_csma_ca_periods = MAC_DEFAULT_NUMBER_OF_CSMA_PERIODS;
1088+
entry->multi_cca_interval = MAC_DEFAULT_CSMA_MULTI_CCA_INTERVAL;
10751089

10761090
if (mac_sec_mib_init(entry, storage_sizes) != 0) {
10771091
mac_mlme_data_base_deallocate(entry);

source/MAC/IEEE802_15_4/mac_pd_sap.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ uint32_t mac_csma_backoff_get(protocol_interface_rf_mac_setup_s *rf_mac_setup)
101101
if (backoff_in_us < MIN_FHSS_CSMA_PERIOD_US) {
102102
backoff_in_us += MIN_FHSS_CSMA_PERIOD_US;
103103
}
104+
// Backoff must be long enough to make multiple CCA checks
105+
if (backoff_in_us < (uint32_t)(rf_mac_setup->multi_cca_interval * (rf_mac_setup->number_of_csma_ca_periods - 1))) {
106+
backoff_in_us += ((rf_mac_setup->multi_cca_interval * (rf_mac_setup->number_of_csma_ca_periods - 1)) - backoff_in_us);
107+
}
104108
}
105109
return backoff_in_us;
106110
}
@@ -405,17 +409,17 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r
405409
if (status == PHY_LINK_CCA_PREPARE) {
406410

407411
if (rf_ptr->mac_ack_tx_active) {
408-
return 0;
412+
return PHY_TX_ALLOWED;
409413
}
410414

411415
if (mac_data_asynch_channel_switch(rf_ptr, rf_ptr->active_pd_data_request)) {
412-
return 0;
416+
return PHY_TX_ALLOWED;
413417
}
414418

415419
if (rf_ptr->fhss_api) {
416420
mac_pre_build_frame_t *active_buf = rf_ptr->active_pd_data_request;
417421
if (!active_buf) {
418-
return -1;
422+
return PHY_TX_NOT_ALLOWED;
419423
}
420424

421425
// Change to destination channel and write synchronization info to Beacon frames here
@@ -426,16 +430,21 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r
426430
// When FHSS TX handle returns -1, transmission of the packet is currently not allowed -> restart CCA timer
427431
if (tx_handle_retval == -1) {
428432
mac_sap_cca_fail_cb(rf_ptr);
429-
return -2;
433+
return PHY_TX_NOT_ALLOWED;
430434
}
431435
// When FHSS TX handle returns -3, we are trying to transmit broadcast packet on unicast channel -> push back
432436
// to queue by using CCA fail event
433437
if (tx_handle_retval == -3) {
434438
mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL);
435-
return -3;
439+
return PHY_TX_NOT_ALLOWED;
436440
} else if (tx_handle_retval == -2) {
437441
mac_tx_done_state_set(rf_ptr, MAC_UNKNOWN_DESTINATION);
438-
return -2;
442+
return PHY_TX_NOT_ALLOWED;
443+
}
444+
if (--active_buf->csma_periods_left > 0) {
445+
active_buf->tx_time += rf_ptr->multi_cca_interval;
446+
mac_pd_sap_set_phy_tx_time(rf_ptr, active_buf->tx_time, true);
447+
return PHY_RESTART_CSMA;
439448
}
440449
}
441450

@@ -497,6 +506,9 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r
497506
mac_sap_cca_fail_cb(rf_ptr);
498507
break;
499508

509+
case PHY_LINK_CCA_OK:
510+
break;
511+
500512
case PHY_LINK_TX_FAIL:
501513
mac_sap_no_ack_cb(rf_ptr);
502514
break;

test/nanostack/unittest/mac/mac_pd_sap/test_mac_pd_sap.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -829,17 +829,18 @@ bool test_mac_cca_prepare_cb()
829829

830830
memset(&test_packet, 0, sizeof(mac_pre_build_frame_t));
831831
rf_ptr.active_pd_data_request = &test_packet;
832+
test_packet.csma_periods_left = 1;
832833
test_packet.fcf_dsn.frametype = FC_BEACON_FRAME;
833834
test_packet.asynch_request = false;
834835
fhss_callback_response = -1;
835836
ret = mac_pd_sap_data_cb(&rf_ptr, &phy_message);
836-
if (ret != -2) {
837+
if (ret != -1) {
837838
return false;
838839
}
839840
fhss_callback_response = -3;
840841
rf_ptr.macRfRadioTxActive = true;
841842
ret = mac_pd_sap_data_cb(&rf_ptr, &phy_message);
842-
if (ret != -3) {
843+
if (ret != -1) {
843844
return false;
844845
}
845846

0 commit comments

Comments
 (0)