Exemplo n.º 1
0
/*
 * \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;
}
Exemplo n.º 2
0
/**
 * @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();
}
Exemplo n.º 3
0
/*
 * \brief Requests to TAL to transmit frame
 *
 * This function is called by the MAC to deliver a frame to the TAL
 * to be transmitted by the transceiver.
 *
 * \param tx_frame Pointer to the frame_info_t structure updated by the MAC
 * layer
 * \param csma_mode Indicates mode of csma-ca to be performed for this frame
 * \param perform_frame_retry Indicates whether to retries are to be performed
 * for
 *                            this frame
 *
 * \return MAC_SUCCESS  if the TAL has accepted the data from the MAC for frame
 *                 transmission
 *         TAL_BUSY if the TAL is busy servicing the previous MAC request
 */
retval_t tal_tx_frame(frame_info_t *tx_frame, csma_mode_t csma_mode,
		bool perform_frame_retry)
{
	if (tal_state != TAL_IDLE) {
		return TAL_BUSY;
	}

	/*
	 * Store the pointer to the provided frame structure.
	 * This is needed for the callback function.
	 */
	mac_frame_ptr = tx_frame;

	/* Set pointer to actual mpdu to be downloaded to the transceiver. */
	tal_frame_to_tx = tx_frame->mpdu;
	last_frame_length = tal_frame_to_tx[0] - 1;

	/*
	 * In case the frame is too large, return immediately indicating
	 * invalid status.
	 */
	if (tal_frame_to_tx == NULL) {
		return MAC_INVALID_PARAMETER;
	}

#ifdef BEACON_SUPPORT
	/* Check if beacon mode is used */
	if (csma_mode == CSMA_SLOTTED) {
		if (!slotted_csma_start(perform_frame_retry)) {
			return MAC_CHANNEL_ACCESS_FAILURE;
		}
	} else {
#if (MAC_INDIRECT_DATA_FFD == 1)

		/*
		 * Check if frame is using indirect transmission, but do not use
		 * the
		 * indirect_in_transit flag. This flag is not set for null data
		 * frames.
		 */
		if ((tal_pib.BeaconOrder < NON_BEACON_NWK) &&
				(csma_mode == NO_CSMA_WITH_IFS) &&
				(perform_frame_retry == false)) {
			/*
			 * Check if indirect transmission can be completed
			 * before the next
			 * beacon transmission.
			 */
			uint32_t time_between_beacons_sym;
			uint32_t next_beacon_time_sym;
			uint32_t now_time_sym;
			uint32_t duration_before_beacon_sym;

			/* Calculate the entire transaction duration. Re-use
			 * function of slotted CSMA.
			 * The additional two backoff periods used for CCA are
			 * kept as a guard time.
			 */
			calculate_transaction_duration();

			/* Calculate the duration until the next beacon needs to
			 * be transmitted. */
			time_between_beacons_sym = TAL_GET_BEACON_INTERVAL_TIME(
					tal_pib.BeaconOrder);
			next_beacon_time_sym = tal_add_time_symbols(
					tal_pib.BeaconTxTime,
					time_between_beacons_sym);
			pal_get_current_time(&now_time_sym);
			now_time_sym = TAL_CONVERT_US_TO_SYMBOLS(now_time_sym);
			duration_before_beacon_sym = tal_sub_time_symbols(
					next_beacon_time_sym, now_time_sym);

			/* Check if transaction can be completed before next
			 * beacon transmission. */
			if ((now_time_sym >= next_beacon_time_sym) ||
					((transaction_duration_periods *
					aUnitBackoffPeriod) >
					duration_before_beacon_sym)) {
				/*
				 * Transaction will not be completed before next
				 * beacon transmission.
				 * Therefore the transmission is not executed.
				 */
				return MAC_CHANNEL_ACCESS_FAILURE;
			}
		}
#endif  /* #if (MAC_INDIRECT_DATA_FFD == 1) */
		send_frame(csma_mode, perform_frame_retry);
	}

#else   /* No BEACON_SUPPORT */
	send_frame(csma_mode, perform_frame_retry);
#endif  /* BEACON_SUPPORT / No BEACON_SUPPORT */

	return MAC_SUCCESS;
}