/** * \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() */
/* * \brief Parses received frame and create the frame_info_t structure * * This function parses the received frame and creates the frame_info_t * structure to be sent to the MAC as a parameter of tal_rx_frame_cb(). * * \param buf Pointer to the buffer containing the received frame */ void process_incoming_frame(buffer_t *buf_ptr) { #ifndef TRX_REG_RAW_VALUE uint8_t frame_len; uint8_t *frame_ptr; uint8_t ed_level; uint8_t lqi; #endif frame_info_t *receive_frame = (frame_info_t *)BMM_BUFFER_POINTER(buf_ptr); /* The frame is present towards the end of the buffer. */ #ifndef TRX_REG_RAW_VALUE /* * Store the last frame length for IFS handling. * Substract LQI and length fields. */ frame_len = last_frame_length = receive_frame->mpdu[0]; #else last_frame_length = receive_frame->mpdu[0]; #endif #ifdef PROMISCUOUS_MODE if (tal_pib.PromiscuousMode) { #ifndef TRX_REG_RAW_VALUE frame_ptr = &(receive_frame->mpdu[frame_len + LQI_LEN]); /* * The LQI is stored after the FCS. * The ED value is stored after the LQI. */ lqi = *frame_ptr++; ed_level = *frame_ptr; /* * The LQI normalization is done using the ED level measured during * the frame reception. */ #ifdef RSSI_TO_LQI_MAPPING lqi = normalize_lqi(ed_level); #else lqi = normalize_lqi(lqi, ed_level); #endif /* Store normalized LQI value again. */ frame_ptr--; *frame_ptr = lqi; #endif /* #ifndef TRX_REG_RAW_VALUE */ receive_frame->buffer_header = buf_ptr; /* The callback function implemented by MAC is invoked. */ tal_rx_frame_cb(receive_frame); return; } #endif /* #ifdef PROMISCUOUS_MODE */ #ifdef BEACON_SUPPORT /* * Are we waiting for a beacon for slotted CSMA? * Check if received frame is a beacon. */ if ((receive_frame->mpdu[PL_POS_FCF_1] & FCF_FRAMETYPE_MASK) == FCF_FRAMETYPE_BEACON) { /* Debug pin to switch on: define ENABLE_DEBUG_PINS, pal_config.h */ PIN_BEACON_START(); if (tal_csma_state == BACKOFF_WAITING_FOR_BEACON) { /* Debug pin to switch on: define ENABLE_DEBUG_PINS, pal_config.h */ PIN_WAITING_FOR_BEACON_END(); tal_pib.BeaconTxTime = TAL_CONVERT_US_TO_SYMBOLS(receive_frame->time_stamp); tal_csma_state = CSMA_HANDLE_BEACON; } /* Debug pin to switch on: define ENABLE_DEBUG_PINS, pal_config.h */ PIN_BEACON_END(); } #endif /* BEACON_SUPPORT */ #ifndef TRX_REG_RAW_VALUE /* * The LQI is stored after the FCS. * The ED value is stored after the LQI. */ frame_ptr = &(receive_frame->mpdu[frame_len + LQI_LEN]); lqi = *frame_ptr++; ed_level = *frame_ptr; /* * The LQI normalization is done using the ED level measured during * the frame reception. */ #ifdef RSSI_TO_LQI_MAPPING lqi = normalize_lqi(ed_level); #else lqi = normalize_lqi(lqi, ed_level); #endif /* Store normalized LQI value again. */ frame_ptr--; *frame_ptr = lqi; #endif /* #ifndef TRX_REG_RAW_VALUE */ receive_frame->buffer_header = buf_ptr; #ifdef ENABLE_RTB /* The callback function implemented by RTB is invoked. */ rtb_rx_frame_cb(receive_frame); #else /* The callback function implemented by MAC is invoked. */ tal_rx_frame_cb(receive_frame); #endif } /* process_incoming_frame() */