Example #1
0
/**
 * \brief Configure the TAL PIB's relevant to the Performance analyzer
 * application
 * \ingroup group_app_init
 */
static void configure_pibs(void)
{
	uint16_t temp_word;
	pib_value_t pib_value;
	uint8_t temp_byte;

	/* Set Default address. */
	temp_word = CCPU_ENDIAN_TO_LE16(DEFAULT_ADDR);
	pib_value.pib_value_16bit = temp_word;
	tal_pib_set(macShortAddress, &pib_value);

	/* Set PAN ID. */
	temp_word = CCPU_ENDIAN_TO_LE16(SRC_PAN_ID);
	pib_value.pib_value_16bit = temp_word;
	tal_pib_set(macPANId, &pib_value);

	/* Set channel. */
	temp_byte = (uint8_t)DEFAULT_CHANNEL;
	pib_value.pib_value_8bit = temp_byte;
	tal_pib_set(phyCurrentChannel, &pib_value);

	/* Set IEEE address - To make sure that trx registers written properly
	**/
	tal_pib_set(macIeeeAddress, (pib_value_t *)&tal_pib.IeeeAddress);
}
Example #2
0
/**
 * \brief Configure the frame to be used for Packet Streaming
 * \param frame_len Length of the frame to be used for Packet Streaming
 */
void configure_pkt_stream_frames(uint16_t frame_len)
{
	uint8_t index;
	uint16_t app_frame_length;
	uint8_t *frame_ptr;
	uint8_t *temp_frame_ptr;
	uint16_t fcf = 0;
	uint16_t temp_value;
	app_payload_t *tmp;

	stream_pkt = (frame_info_t *)pkt_buffer;	
	/*
	 * Fill in PHY frame.
	 */

	/* Get length of current frame. */
	app_frame_length = frame_len - FRAME_OVERHEAD;

	/* Set payload pointer. */
	/* Add 2 octets for FCS. */
	frame_ptr = temp_frame_ptr
				= (uint8_t *)stream_pkt +
					LARGE_BUFFER_SIZE -
					app_frame_length - FCS_LEN; 

	tmp = (app_payload_t *)temp_frame_ptr;

	(tmp->cmd_id) = PKT_STREAM_PKT;

	temp_frame_ptr++;

	/*
	 * Assign dummy payload values.
	 * Payload is stored to the end of the buffer avoiding payload copying
	 * by TAL.
	 */
	/* 1=> cmd ID*/
	for (index = 0; index < (app_frame_length - 1); index++) { 
		*temp_frame_ptr++ = index; /* dummy values */
	}

	/* Source Address */
	temp_value =  tal_pib.ShortAddress;
	frame_ptr -= SHORT_ADDR_LEN;
	convert_16_bit_to_byte_array(temp_value, frame_ptr);

	/* Source PAN-Id */
#if (DST_PAN_ID == SRC_PAN_ID)
	/* No source PAN-Id included, but FCF updated. */
	fcf |= FCF_PAN_ID_COMPRESSION;
#else
	frame_ptr -= PAN_ID_LEN;
	temp_value = CCPU_ENDIAN_TO_LE16(SRC_PAN_ID);
	convert_16_bit_to_byte_array(temp_value, frame_ptr);
#endif

	/* Destination Address */
	temp_value = 0XFFFF;
	frame_ptr -= SHORT_ADDR_LEN;
	convert_16_bit_to_byte_array(temp_value, frame_ptr);

	/* Destination PAN-Id */
	temp_value = CCPU_ENDIAN_TO_LE16(DST_PAN_ID);
	frame_ptr -= PAN_ID_LEN;
	convert_16_bit_to_byte_array(temp_value, frame_ptr);

	/* Set DSN. */
	frame_ptr--;
	*frame_ptr = (uint8_t)rand();

	/* Set the FCF. */ 
// Reserved frame type so that other apps doesnot receive and process this data
	fcf |= 0x04 | FCF_SET_SOURCE_ADDR_MODE(FCF_SHORT_ADDR) |
			FCF_SET_DEST_ADDR_MODE(FCF_SHORT_ADDR);


	frame_ptr -= FCF_LEN;
	convert_16_bit_to_byte_array(CCPU_ENDIAN_TO_LE16(fcf), frame_ptr);

	/* First element shall be length of PHY frame. */
	frame_ptr--;
	*frame_ptr = (uint8_t)frame_len; 

	/* Finished building of frame. */
	stream_pkt->mpdu = frame_ptr;
}
Example #3
0
/**
 * @brief Build and transmits data request command frame
 *
 * This function builds and tranmits a data request command frame.
 *
 *
 * @param expl_poll Data request due to explicit MLME poll request
 * @param force_own_long_addr Forces the usage of the Extended Address as
 *                            Source Address. This a allows for implicitly
 *                            poll for pending data at the coordinator if
 *                            the Extended Address was used in the Beacon frame.
 * @param expl_dest_addr_mode Mode of subsequent destination address to be used
 *                            explicitly (0/2/3).
 *                            0: No explicit destination address attached,
 *                               use either macCoordShortAddress or
 *                               macCoordExtendedAddress
 *                            2: Use explicitly attached address in parameter
 *                               expl_dest_addr as destination address as
 *                               short address
 *                            3: Use explicitly attached address in parameter
 *                               expl_dest_addr as destination address as
 *                               extended address
 * @param expl_dest_addr Explicitly attached destination address for data
 *                       request frame. This is to be treated as either not
 *                       present, short or extended address, depending on
 *                       parameter expl_dest_addr_mode.
 * @param expl_dest_pan_id Explicitly attached destination PAN-Id (Coordinator
 *                         PAN-Id) for data request frame.
 *                         This is to be treated only as present, depending on
 *                         parameter expl_dest_addr_mode.
 *
 * @return True if data request command frame was created and sent to
 *         the TAL successfully, false otherwise.
 */
bool mac_build_and_tx_data_req(bool expl_poll,
                               bool force_own_long_addr,
                               uint8_t expl_dest_addr_mode,
                               address_field_t *expl_dest_addr,
                               uint16_t expl_dest_pan_id)
{
    retval_t tal_tx_status;
    bool intrabit = false;
    uint8_t frame_len;
    uint8_t *frame_ptr;
    uint16_t fcf;
    buffer_t *buf_ptr = bmm_buffer_alloc(LARGE_BUFFER_SIZE);

    if (NULL == buf_ptr)
    {
        return false;
    }

    frame_info_t *transmit_frame = (frame_info_t *)BMM_BUFFER_POINTER(buf_ptr);

    /*
     * If this data request cmd frame was initiated by a device due to implicit
     * poll, set msgtype to DATAREQUEST_IMPL_POLL.
     * If this data request cmd frame was initiated by a MLME poll request,
     * set msgtype to DATAREQUEST.
     */
    if (expl_poll)
    {
        transmit_frame->msg_type = DATAREQUEST;
    }
    else
    {
        transmit_frame->msg_type = DATAREQUEST_IMPL_POLL;
    }

    /*
     * The buffer header is stored as a part of frame_info_t structure before the
     * frame is given to the TAL. After the transmission of the frame, reuse
     * the buffer using this pointer.
     */
    transmit_frame->buffer_header = buf_ptr;

    /* Update the payload length. */
    frame_len = DATA_REQ_PAYLOAD_LEN +
                2 + // Add 2 octets for FCS
                2 + // 2 octets for short Source Address
                2 + // 2 octets for short Destination Address
                2 + // 2 octets for Destination PAN-Id
                3;  // 3 octets DSN and FCF

    /* Get the payload pointer. */
    frame_ptr = (uint8_t *)transmit_frame +
                LARGE_BUFFER_SIZE -
                DATA_REQ_PAYLOAD_LEN - 2;   /* Add 2 octets for FCS. */

    /*
     * Build the command frame id.
     * This is actually being written into "transmit_frame->layload[0]".
     */
    *frame_ptr = DATAREQUEST;

    /* Source Address */
    /*
     * Long address needs to be used if a short address is not present
     * or if we are forced to use the long address.
     *
     * This is used for example in cases where the coordinator indicates
     * pending data for us using our extended address.
     *
     * This is also used for transmitting a data request frame
     * during association, since here we always need to use our
     * extended address.
     */
    if ((BROADCAST == tal_pib.ShortAddress) ||
        (CCPU_ENDIAN_TO_LE16(MAC_NO_SHORT_ADDR_VALUE) == tal_pib.ShortAddress) ||
        force_own_long_addr)
    {
        frame_ptr -= 8;
        frame_len += 6; // Add further 6 octets for long Source Address

        /* Build the Source address. */
        convert_64_bit_to_byte_array(tal_pib.IeeeAddress, frame_ptr);
        fcf = FCF_SET_FRAMETYPE(FCF_FRAMETYPE_MAC_CMD) |
              FCF_SET_SOURCE_ADDR_MODE(FCF_LONG_ADDR) |
              FCF_ACK_REQUEST;
    }
    else
    {
        frame_ptr -= 2;

        /* Build the Source address. */
        convert_16_bit_to_byte_array(tal_pib.ShortAddress, frame_ptr);

        fcf = FCF_SET_FRAMETYPE(FCF_FRAMETYPE_MAC_CMD) |
              FCF_SET_SOURCE_ADDR_MODE(FCF_SHORT_ADDR) |
              FCF_ACK_REQUEST;
    }


    /* Source PAN-Id */
    /*
     * In IEEE 802.15.4 the PAN ID Compression bit may always be set.
     * See page 154:
     * If the data request command is being sent in response to the receipt
     * of a beacon frame indicating that data are pending for that device,
     * the Destination Addressing Mode subfield of the Frame Control field
     * may be set to zero ..."
     * In order to keep the implementation simple the address info is also in
     * this case 2 or 3, i.e. the destination address info is present.
     * This in return means that the PAN ID Compression bit is always set for
     * data request frames, except the expl_dest_pan_id parameter is different from
     * our own PAN-Id PIB attribute.
     */
     if ((expl_dest_addr_mode != FCF_NO_ADDR) &&
        (expl_dest_pan_id != tal_pib.PANId)
       )
     {
        frame_ptr -= 2;
        frame_len += 2;  // Add further 6 octets for long Source Pan-Id

        convert_16_bit_to_byte_array(tal_pib.PANId, frame_ptr);
     }
     else
     {
    /*
     * The source PAN Id is not present since the PAN ID
     * Compression bit is set.
     */
        /* Set intra-PAN bit. */
        intrabit = true;
        fcf |= FCF_PAN_ID_COMPRESSION;
    }


    /* Destination Address */
    if (FCF_SHORT_ADDR == expl_dest_addr_mode)
    {
        /* An explicit short destination address is requested. */
        fcf |= FCF_SET_DEST_ADDR_MODE(FCF_SHORT_ADDR);

        frame_ptr -= 2;
        convert_16_bit_to_byte_array(expl_dest_addr->short_address, frame_ptr);
    }
    else if (FCF_LONG_ADDR == expl_dest_addr_mode)
    {
        /* An explicit long destination address is requested. */
        fcf |= FCF_SET_DEST_ADDR_MODE(FCF_LONG_ADDR);

        frame_ptr -= 8;
        frame_len += 6; // Add further 6 octets for long Destination Address
        convert_64_bit_to_byte_array(expl_dest_addr->long_address, frame_ptr);
    }
    else
    {
        /* No explicit destination address is requested. */
        if (CCPU_ENDIAN_TO_LE16(MAC_NO_SHORT_ADDR_VALUE) != mac_pib.mac_CoordShortAddress)
        {
            /*
             * If current value of short address for coordinator PIB is
             * NOT 0xFFFE, the current value of the short address for
             * coordinator shall be used as desination address.
             */
            fcf |= FCF_SET_DEST_ADDR_MODE(FCF_SHORT_ADDR);

            frame_ptr -= 2;
            convert_16_bit_to_byte_array(mac_pib.mac_CoordShortAddress, frame_ptr);
        }
        else
        {
            /*
             * If current value of short address for coordinator PIB is 0xFFFE,
             * the current value of the extended address for coordinator
             * shall be used as desination address.
             */
            fcf |= FCF_SET_DEST_ADDR_MODE(FCF_LONG_ADDR);

            frame_ptr -= 8;
            frame_len += 6; // Add further 6 octets for long Destination Address
            convert_64_bit_to_byte_array(mac_pib.mac_CoordExtendedAddress, frame_ptr);
        }
    }


    /* Destination PAN-Id */
    frame_ptr -= 2;

    if (intrabit)
    {
        /* Add our PAN-Id. */
        convert_16_bit_to_byte_array(tal_pib.PANId, frame_ptr);
    }
    else
    {
    /*
         * There is an expclicit destination address present AND
         * the destination PAN-Id is different from our own PAN-ID,
         * so include the source PAN-id into the frame.
     */
        convert_16_bit_to_byte_array(expl_dest_pan_id, frame_ptr);
    }


    /* Set DSN. */
    frame_ptr--;
    *frame_ptr = mac_pib.mac_DSN++;


    /* Set the FCF. */
    frame_ptr -= 2;
    convert_spec_16_bit_to_byte_array(fcf, frame_ptr);


    /* First element shall be length of PHY frame. */
    frame_ptr--;
    *frame_ptr = frame_len;

    /* Finished building of frame. */
    transmit_frame->mpdu = frame_ptr;


    /* Transmission should be done with CSMA-CA and frame retries. */
#ifdef BEACON_SUPPORT
    /*
     * Now it gets tricky:
     * In Beacon network the frame is sent with slotted CSMA-CA only if:
     * 1) the node is associated, or
     * 2) the node is idle, but synced before association,
     * 3) the node is a Coordinator (we assume, that coordinators are always
     *    in sync with their parents).
     *
     * In all other cases, the frame has to be sent using unslotted CSMA-CA.
     */
    csma_mode_t cur_csma_mode;

    if (NON_BEACON_NWK != tal_pib.BeaconOrder)
    {
        if (
            ((MAC_IDLE == mac_state) && (MAC_SYNC_BEFORE_ASSOC == mac_sync_state)) ||
#if (MAC_START_REQUEST_CONFIRM == 1)
            (MAC_ASSOCIATED == mac_state) ||
            (MAC_COORDINATOR == mac_state)
#else
            (MAC_ASSOCIATED == mac_state)
#endif /* MAC_START_REQUEST_CONFIRM */
           )
        {
            cur_csma_mode = CSMA_SLOTTED;
        }
        else
        {
            cur_csma_mode = CSMA_UNSLOTTED;
        }
    }
    else
    {
        /* In Nonbeacon network the frame is sent with unslotted CSMA-CA. */
        cur_csma_mode = CSMA_UNSLOTTED;
    }

    tal_tx_status = tal_tx_frame(transmit_frame, cur_csma_mode, true);
#else   /* No BEACON_SUPPORT */
    /* In Nonbeacon build the frame is sent with unslotted CSMA-CA. */
    tal_tx_status = tal_tx_frame(transmit_frame, CSMA_UNSLOTTED, true);
#endif  /* BEACON_SUPPORT */

    if (MAC_SUCCESS == tal_tx_status)
    {
        MAKE_MAC_BUSY();
        return true;
    }
    else
    {
        /* TAL is busy, hence the data request could not be transmitted */
        bmm_buffer_free(buf_ptr);

        return false;
    }
} /* mac_build_and_tx_data_req() */
Example #4
0
/*
 * \brief Function to transmit frames as per 802.15.4 std.
 *
 * \param dst_addr_mode     destination address mode - can be 16 or 64 bit
 * \param dst_addr          destination address
 * \param src_addr_mode     source address mode - can be 16 or 64 bit
 * \param msdu_handle       msdu handle for the upper layers to track packets
 * \param payload           data payload pointer
 * \param payload_length    data length
 * \param ack_req           specifies ack requested for frame if set to 1
 *
 * \return MAC_SUCCESS      if the TAL has accepted the data for frame
 * transmission
 *         TAL_BUSY         if the TAL is busy servicing the previous tx request
 */
retval_t transmit_frame(uint8_t dst_addr_mode,
		uint8_t *dst_addr,
		uint8_t src_addr_mode,
		uint8_t msdu_handle,
		uint8_t *payload,
		uint8_t payload_length,
		uint8_t ack_req)
{
	uint8_t i;
	uint16_t temp_value;
	uint8_t frame_length;
	uint8_t *frame_ptr;
	uint8_t *temp_frame_ptr;
	uint16_t fcf = 0;

	/* Prevent multiple transmissions , this code is not reentrant*/
	if (node_info.transmitting) {
		return FAILURE;
	}

	node_info.transmitting = true;

	/* Get length of current frame. */
	frame_length = (FRAME_OVERHEAD + payload_length);

	/* Set payload pointer. */
	frame_ptr = temp_frame_ptr = (uint8_t *)node_info.tx_frame_info +
					LARGE_BUFFER_SIZE -
					payload_length - FCS_LEN;

	/*
	 * Payload is stored to the end of the buffer avoiding payload
	 * copying by TAL.
	 */
	for (i = 0; i < payload_length; i++) {
		*temp_frame_ptr++ = *(payload + i);
	}

	/* Source address */
	if (FCF_SHORT_ADDR == src_addr_mode) {
		frame_ptr -= SHORT_ADDR_LEN;
		convert_16_bit_to_byte_array(tal_pib.ShortAddress, frame_ptr);

		fcf |= FCF_SET_SOURCE_ADDR_MODE(FCF_SHORT_ADDR);
	} else {
		frame_ptr -= EXT_ADDR_LEN;
		frame_length += FCF_2_SOURCE_ADDR_OFFSET;

		convert_64_bit_to_byte_array(tal_pib.IeeeAddress, frame_ptr);

		fcf |= FCF_SET_SOURCE_ADDR_MODE(FCF_LONG_ADDR);
	}

	/* Source PAN-Id */
#if (DST_PAN_ID == SRC_PAN_ID)
	/* No source PAN-Id included, but FCF updated. */
	fcf |= FCF_PAN_ID_COMPRESSION;
#else
	frame_ptr -= PAN_ID_LEN;
	temp_value = CCPU_ENDIAN_TO_LE16(SRC_PAN_ID);
	convert_16_bit_to_byte_array(temp_value, frame_ptr);
#endif

	/* Destination address */
	if (FCF_SHORT_ADDR == dst_addr_mode) {
		frame_ptr -= SHORT_ADDR_LEN;
		//convert_16_bit_to_byte_array(*((uint16_t *)dst_addr),
		//		frame_ptr);
	memcpy(frame_ptr, (uint8_t *)dst_addr, sizeof(uint16_t));
		fcf |= FCF_SET_DEST_ADDR_MODE(FCF_SHORT_ADDR);
	} else {
		frame_ptr -= EXT_ADDR_LEN;
		frame_length += PL_POS_DST_ADDR_START;

		//convert_64_bit_to_byte_array(*((uint64_t *)dst_addr),
		//		frame_ptr);
		memcpy(frame_ptr, (uint8_t *)dst_addr, sizeof(uint64_t));
		fcf |= FCF_SET_DEST_ADDR_MODE(FCF_LONG_ADDR);
	}

	/* Destination PAN-Id */
	temp_value = CCPU_ENDIAN_TO_LE16(DST_PAN_ID);
	frame_ptr -= PAN_ID_LEN;
	convert_16_bit_to_byte_array(temp_value, frame_ptr);

	/* Set DSN. */
	frame_ptr--;
	*frame_ptr = node_info.msg_seq_num;
	node_info.msg_seq_num++;

	/* Set the FCF. */
	fcf |= FCF_FRAMETYPE_DATA;
	if (ack_req) {
		fcf |= FCF_ACK_REQUEST;
	}

	frame_ptr -= FCF_LEN;
	convert_16_bit_to_byte_array(CCPU_ENDIAN_TO_LE16(fcf), frame_ptr);

	/* First element shall be length of PHY frame. */
	frame_ptr--;
	*frame_ptr = frame_length;

	/* Finished building of frame. */
	node_info.tx_frame_info->mpdu = frame_ptr;

	/* Place msdu handle for tracking */
	node_info.tx_frame_info->msduHandle = msdu_handle;

	/* transmit the frame */
	return(tal_tx_frame(node_info.tx_frame_info, CSMA_UNSLOTTED, true));
}