/* * \brief Starts slotted CSMA */ bool slotted_csma_start(bool perform_frame_retry) { PIN_CSMA_START(); /* debug pin to switch on: define ENABLE_DEBUG_PINS, * pal_config.h */ bool return_val = false; /* Assume error case */ if (check_beacon_reception()) { tal_state = TAL_SLOTTED_CSMA; csma_param_init(); if (perform_frame_retry) { number_of_tx_retries = 0; } else { /* Use the max value to indicate that no retries are * required. */ number_of_tx_retries = tal_pib.MaxFrameRetries; } calculate_transaction_duration(); /* Get a random backoff period duration. */ remaining_backoff_periods = (uint8_t)(rand() & ((1 << BE) - 1)); csma_backoff_calculation(); return_val = true; } return return_val; }
/** * @brief Starts slotted CSMA */ void slotted_csma_start(bool perform_frame_retry) { PIN_CSMA_START(); // debug pin to switch on: define ENABLE_DEBUG_PINS, pal_config.h tal_state = TAL_SLOTTED_CSMA; if (check_beacon_reception() == false) { tal_csma_state = NO_BEACON_TRACKING; return; } csma_param_init(); if (perform_frame_retry) { number_of_tx_retries = 0; } else { // use the max value to indicate that no retries are required number_of_tx_retries = tal_pib_MaxFrameRetries; } calculate_transaction_duration(); /* Get a random backoff period duration. */ remaining_backoff_periods = (uint8_t)(rand() & ((1 << BE) - 1)); csma_backoff_calculation(); }
/** * \brief State machine handling slotted CSMA */ void slotted_csma_state_handling(void) { switch (tal_csma_state) { case BACKOFF_WAITING_FOR_CCA_TIMER: break; case BACKOFF_WAITING_FOR_BEACON: /* * Do not perform any operation and wait until the next beacon * reception. If several beacons are not received, the beacon * loss * timer expires and stops the entire transaction. */ break; case CSMA_HANDLE_BEACON: /* debug pin to switch on: define ENABLE_DEBUG_PINS, * pal_config.h */ PIN_WAITING_FOR_BEACON_END(); PIN_BEACON_LOSS_TIMER_END(); pal_timer_stop(TAL_CSMA_BEACON_LOSS_TIMER); csma_backoff_calculation(); break; case CSMA_ACCESS_FAILURE: NB++; BE++; /* ensure that BE is no more than macMaxBE */ if (BE > tal_pib.MaxBE) { /* macMaxBE */ BE = tal_pib.MaxBE; /* macMaxBE */ } if (NB > macMaxCSMABackoffs) { /* terminate with channel access failure */ tx_done(MAC_CHANNEL_ACCESS_FAILURE); } else { /* restart backoff */ csma_backoff_calculation(); } break; case NO_BEACON_TRACKING: /* terminate with channel access failure */ tx_done(MAC_CHANNEL_ACCESS_FAILURE); break; case FRAME_SENDING: /* waiting for end of frame transmission */ break; case TX_DONE_SUCCESS: tx_done(MAC_SUCCESS); break; case TX_DONE_FRAME_PENDING: tx_done(TAL_FRAME_PENDING); break; case TX_DONE_NO_ACK: if (number_of_tx_retries < tal_pib.MaxFrameRetries) { number_of_tx_retries++; set_trx_state(CMD_RX_AACK_ON); /* * Start the entire CSMA procedure again, * but do not reset the number of transmission attempts. */ BE++; /* ensure that BE is no more than macMaxBE */ if (BE > tal_pib.MaxBE) { /* macMaxBE */ BE = tal_pib.MaxBE; /* macMaxBE */ } NB = 0; remaining_backoff_periods = (uint8_t)(rand() & ((1 << BE) - 1)); csma_backoff_calculation(); } else { tx_done(MAC_NO_ACK); } PIN_NO_ACK_END(); break; default: Assert("INVALID CSMA status" == 0); break; } } /* csma_ca_state_handling() */