Skip to content

Commit ffd4db2

Browse files
author
Jarkko Paso
committed
MAC: Implemented double cca check
1 parent 359c7b9 commit ffd4db2

File tree

4 files changed

+38
-7
lines changed

4 files changed

+38
-7
lines changed

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/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 - (MAC_CSMA_MULTI_CCA_INTERVAL * (MAC_NUMBER_OF_CSMA_PERIODS - 1))) > mac_mcps_sap_get_phy_timestamp(rf_ptr)) {
1834+
buffer->csma_periods_left = MAC_NUMBER_OF_CSMA_PERIODS;
1835+
buffer->tx_time -= (MAC_CSMA_MULTI_CCA_INTERVAL * (MAC_NUMBER_OF_CSMA_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+
// With FHSS we need to check CCA twice on TX channel
61+
#define MAC_NUMBER_OF_CSMA_PERIODS 2
62+
// Interval between two CCA checks
63+
#define MAC_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_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 < (MAC_CSMA_MULTI_CCA_INTERVAL * (MAC_NUMBER_OF_CSMA_PERIODS - 1))) {
106+
backoff_in_us += (MAC_CSMA_MULTI_CCA_INTERVAL * (MAC_NUMBER_OF_CSMA_PERIODS - 1));
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 += MAC_CSMA_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;

0 commit comments

Comments
 (0)