Ejemplo n.º 1
0
/*
 * @brief The MLME-GTS.request primitive makes a request for device to
 * request for GTS or on PANC to allocate or deallocate a GTS for itself
 * or other devices
 *
 * 802.15.4. Section 7.1.7.1.
 *
 * @param m The MLME-GTS.request message.
 */
void mlme_gts_request(uint8_t *m)
{
    mlme_gts_req_t mgr;
    memcpy(&mgr, BMM_BUFFER_POINTER((buffer_t *)m),
           sizeof(mlme_gts_req_t));

    if (MAC_NO_SHORT_ADDR_VALUE <= tal_pib.ShortAddress ||
            (MAC_NO_SHORT_ADDR_VALUE <=
             mac_pib.mac_CoordShortAddress &&
             MAC_PAN_COORD_STARTED != mac_state)) {
        mac_gen_mlme_gts_conf((buffer_t *)m, MAC_NO_SHORT_ADDRESS,
                              mgr.GtsChar);
        return;
    } else if (true != mac_pib.mac_GTSPermit    ||
               (0 == mgr.GtsChar.GtsLength) ||
               (MAC_ASSOCIATED == mac_state &&
                (mgr.DeviceShortAddr != tal_pib.ShortAddress ||
                 MAC_SYNC_TRACKING_BEACON != mac_sync_state ||
                 (mgr.GtsChar.GtsCharType == GTS_DEALLOCATE &&
                  (!mac_dev_gts_table[mgr.GtsChar.GtsDirection].
                   GtsStartingSlot ||
                   mgr.GtsChar.GtsLength !=
                   mac_dev_gts_table[mgr.GtsChar.GtsDirection].GtsLength))
                )
               )
              ) {
        mac_gen_mlme_gts_conf((buffer_t *)m, MAC_INVALID_PARAMETER,
                              mgr.GtsChar);
        return;
    }

#ifdef FFD
    else if (MAC_PAN_COORD_STARTED == mac_state) {
        if (GTS_ALLOCATE & mgr.GtsChar.GtsCharType) {
            if (mac_gts_allocate(mgr.GtsChar,
                                 mgr.DeviceShortAddr)) {
                mac_gen_mlme_gts_conf((buffer_t *)m,
                                      MAC_SUCCESS,
                                      mgr.GtsChar);
                return;
            } else {
                mac_gen_mlme_gts_conf((buffer_t *)m,
                                      MAC_NO_DATA,
                                      mgr.GtsChar);
                return;
            }
        } else {
            if (mac_gts_deallocate(mgr.GtsChar, mgr.DeviceShortAddr,
                                   true)) {
                mac_gen_mlme_gts_conf((buffer_t *)m,
                                      MAC_SUCCESS,
                                      mgr.GtsChar);
                return;
            } else {
                mac_gen_mlme_gts_conf((buffer_t *)m,
                                      MAC_NO_DATA,
                                      mgr.GtsChar);
                return;
            }
        }
    }
#endif /* FFD */
    else if (MAC_ASSOCIATED == mac_state) {
        frame_info_t *transmit_frame
            = (frame_info_t *)BMM_BUFFER_POINTER((buffer_t *)m);

        mac_trx_wakeup();

        /* Build the GTS Request command frame. */
        uint8_t tal_tx_status;
        uint8_t frame_len;
        uint8_t *frame_ptr;
        uint8_t *temp_frame_ptr;
        uint16_t fcf;

        /*
         * Use the mlme gts request buffer for transmitting
         * gts request frame.
         */
        frame_info_t *gts_req_frame
            = (frame_info_t *)(BMM_BUFFER_POINTER((buffer_t *)m));

        gts_req_frame->msg_type = GTSREQUEST;
        gts_req_frame->buffer_header = (buffer_t *)m;

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

        /* Update the payload field. */
        *frame_ptr++ = GTSREQUEST;
        /* Build the GTS characteristics info. */
        *frame_ptr = *((uint8_t *)&mgr.GtsChar);

        /* Get the payload pointer again to add the MHR. */
        frame_ptr = temp_frame_ptr;

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

        /* Source address */
        frame_ptr -= 2;

        convert_16_bit_to_byte_array(tal_pib.ShortAddress, frame_ptr);

        frame_ptr -= 2;
        convert_16_bit_to_byte_array(mac_pib.mac_CoordShortAddress,
                                     frame_ptr);

        fcf = FCF_SET_FRAMETYPE(FCF_FRAMETYPE_MAC_CMD) |
              FCF_SET_DEST_ADDR_MODE(FCF_SHORT_ADDR) |
              FCF_SET_SOURCE_ADDR_MODE(FCF_SHORT_ADDR) |
              FCF_ACK_REQUEST | FCF_PAN_ID_COMPRESSION;

        /* Destination PAN-Id */
        frame_ptr -= 2;
        convert_16_bit_to_byte_array(tal_pib.PANId, 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. */
        gts_req_frame->mpdu = frame_ptr;

        tal_tx_status
            = tal_tx_frame(transmit_frame, CSMA_SLOTTED, true);

        if (MAC_SUCCESS == tal_tx_status) {
            uint8_t update_index = mgr.GtsChar.GtsDirection;

            if (mgr.DeviceShortAddr ==
                    mac_pib.mac_CoordShortAddress) {
                update_index |= 0x02;
            }

            if (GTS_DEALLOCATE == mgr.GtsChar.GtsCharType) {
                mac_dev_gts_table[update_index].GtsLength
                    = 0;
                mac_dev_gts_table[update_index].GtsStartingSlot
                    = 0;
                mac_dev_gts_table[update_index].GtsState
                    = GTS_STATE_IDLE;
                mac_gen_mlme_gts_conf((buffer_t *)m,
                                      MAC_SUCCESS, mgr.GtsChar);
                return;
            } else {
                mac_dev_gts_table[update_index].GtsReq_ptr = m;
                mac_dev_gts_table[update_index].GtsState
                    = GTS_STATE_REQ_SENT;
                mac_dev_gts_table[update_index].GtsPersistCount
                    = aGTSDescPersistenceTime;
                mac_dev_gts_table[update_index].GtsLength
                    = mgr.GtsChar.GtsLength;
                MAKE_MAC_BUSY();
            }
        } else {
            mac_gen_mlme_gts_conf((buffer_t *)m, tal_tx_status,
                                  mgr.GtsChar);
        }
    } else {
        mac_gen_mlme_gts_conf((buffer_t *)m, MAC_INVALID_PARAMETER,
                              mgr.GtsChar);
    }
    return;
}
Ejemplo n.º 2
0
/*
 * @brief Constructs a null data frame
 *
 * @return Pointer to the created null data frame, NULL otherwise.
 */
static buffer_t *build_null_data_frame(void)
{
    bool use_long_addr_dest;
    frame_info_t *transmit_frame;
    uint8_t frame_len;
    uint8_t *frame_ptr;
    uint16_t fcf = 0;
    buffer_t *buf_ptr = bmm_buffer_alloc(LARGE_BUFFER_SIZE);

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

    transmit_frame = (frame_info_t *)BMM_BUFFER_POINTER(buf_ptr);

    /* No data payload, this is a null packet.*/
    transmit_frame->msg_type = NULL_FRAME;
    transmit_frame->buffer_header = buf_ptr;

    /* No indirect transmission. */
    transmit_frame->indirect_in_transit = false;

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

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

    /*
     * Set Source Address.
     */
    if ((BROADCAST == tal_pib.ShortAddress) ||
        (MAC_NO_SHORT_ADDR_VALUE == tal_pib.ShortAddress)
       )
    {
        /* Use long address as source address. */
        frame_ptr -= 8;
        frame_len += 6;
        convert_64_bit_to_byte_array(tal_pib.IeeeAddress, frame_ptr);
        fcf |= FCF_SET_SOURCE_ADDR_MODE(FCF_LONG_ADDR);
    }
    else
    {
        /* Use short address as source address. */
        frame_ptr -= 2;
        convert_16_bit_to_byte_array(tal_pib.ShortAddress, frame_ptr);
        fcf |= FCF_SET_SOURCE_ADDR_MODE(FCF_SHORT_ADDR);
    }

    /* Shall the Intra-PAN bit set? */
    if (tal_pib.PANId == mac_parse_data.src_panid)
    {
        /*
         * Both PAN-Ids are identical.
         * Set intra-PAN bit.
         */
        fcf |= FCF_PAN_ID_COMPRESSION;
    }
    else
    {
        /* Set Source PAN-Id. */
        frame_ptr -= 2;
        frame_len += 2;
        convert_16_bit_to_byte_array(tal_pib.PANId, frame_ptr);
    }


    /* Set Destination Address. */
    use_long_addr_dest = (FCF_LONG_ADDR == mac_parse_data.src_addr_mode);

    /* Destination address is set from source address of received frame. */
    if (use_long_addr_dest)
    {
        frame_ptr -= 8;
        frame_len += 6;
        convert_64_bit_to_byte_array(mac_parse_data.src_addr.long_address, frame_ptr);

        fcf |= FCF_SET_DEST_ADDR_MODE(FCF_LONG_ADDR) |
              FCF_SET_FRAMETYPE(FCF_FRAMETYPE_DATA);
    }
    else
    {
        frame_ptr -= 2;
        convert_16_bit_to_byte_array(mac_parse_data.src_addr.short_address, frame_ptr);
        fcf |= FCF_SET_DEST_ADDR_MODE(FCF_SHORT_ADDR) |
              FCF_SET_FRAMETYPE(FCF_FRAMETYPE_DATA);
    }


    /* Destination PANId is set from source PANId of received frame. */
    frame_ptr -= 2;
    convert_16_bit_to_byte_array(mac_parse_data.src_panid, 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;

    return buf_ptr;
} /* build_null_data_frame() */
Ejemplo n.º 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() */
Ejemplo n.º 4
0
/**
 * @brief Send a beacon request or orphan notification command frame
 *
 * This function sends a beacon request or orphan notification command frame.
 * An MPDU containing either a beacon request or an orphan notification command
 * frame is constructed and sent.
 *
 * @param beacon_req True if a beacon request command frame shall be sent,
 *                   otherwise (false) an orphan notification command frame
 *                   will be sent.
 *
 * @return True if the frame transmission has been initiated, false otherwise.
 */
static bool send_scan_cmd(bool beacon_req)
{
	retval_t tal_tx_status;
	uint8_t frame_len;
	uint8_t *frame_ptr;
	uint16_t fcf;
	uint16_t bc_addr = BROADCAST;

	/*
	 * mac_scan_cmd_buf_ptr holds the buffer allocated for sending beacon
	 * request or orphan notification command. In active scan the scan
	 * request
	 * buffer is used to send a beacon request and in orphan scan new buffer
	 * is
	 * allocated to send an orphan notification.
	 */
	frame_info_t *transmit_frame
		= (frame_info_t *)BMM_BUFFER_POINTER(
			(buffer_t *)mac_scan_cmd_buf_ptr);

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

	transmit_frame->buffer_header = (buffer_t *)mac_scan_cmd_buf_ptr;

	if (beacon_req) {
		fcf = FCF_SET_FRAMETYPE(FCF_FRAMETYPE_MAC_CMD) |
				FCF_SET_DEST_ADDR_MODE(FCF_SHORT_ADDR) |
				FCF_SET_SOURCE_ADDR_MODE(FCF_NO_ADDR);

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

		/* Build the command frame id. */
		*frame_ptr = transmit_frame->msg_type = BEACONREQUEST;
	} else { /* Orphan Notification command */
		fcf = FCF_SET_FRAMETYPE(FCF_FRAMETYPE_MAC_CMD) |
				FCF_SET_DEST_ADDR_MODE(FCF_SHORT_ADDR) |
				FCF_SET_SOURCE_ADDR_MODE(FCF_LONG_ADDR) |
				FCF_PAN_ID_COMPRESSION;

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

		/* Build the command frame id. */
		*frame_ptr = transmit_frame->msg_type = ORPHANNOTIFICATION;

		/* Orphan notification contains long source address. */
		frame_ptr -= 8;
		convert_64_bit_to_byte_array(tal_pib.IeeeAddress, frame_ptr);
	}

	/* Destination address */
	frame_ptr -= 2;
	convert_16_bit_to_byte_array(bc_addr, frame_ptr);

	/* Destination PANid */
	frame_ptr -= 2;
	convert_16_bit_to_byte_array(bc_addr, 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;

#if (TAL_TYPE == AT86RF230B)
	/* Transmit data without CSMA-CA and no frame retry. */
	tal_tx_status = tal_tx_frame(transmit_frame, NO_CSMA_NO_IFS, false);
#else
	/* Transmit data with unslotted CSMA-CA and no frame retry. */
	tal_tx_status = tal_tx_frame(transmit_frame, CSMA_UNSLOTTED, false);
#endif

	if (MAC_SUCCESS == tal_tx_status) {
		MAKE_MAC_BUSY();
		return true;
	} else {
		return false;
	}
} /* send_scan_cmd() */