/**
 * @brief Sends a coordinator realignment command frame
 *
 * This function is called either in response to the reception of an orphan
 * notification command from a device (cmd_type = ORPHANREALIGNMENT),
 * or gratuitously whenever the PAN parameters are about to be changed
 * (cmd_type = COORDINATORREALIGNMENT). In the first case, the
 * paramater mor contains a pointer to the respective
 * MLME_ORPHAN.response message, while in the latter case this
 * parameter is unused, and can be passed as NULL.
 *
 * @param cmd_type Determines directed or broadcast mode
 * @param buf_ptr Pointer to the buffer, using which coord_realignment_command
 *                to be sent
 * @param new_panid Contains the new PAN-ID in case there is a network
 *                  realignment
 * @param new_channel Contains the new channel in case there is a network
 *                    realignment
 * @param new_page Contains the new channel page in case there is a network
 *                 realignment
 *
 * @return True if coord_realignment_command is sent successfully,
 *         false otherwise
 */
bool mac_tx_coord_realignment_command(frame_msgtype_t cmd_type,
                                      buffer_t *buf_ptr,
                                      uint16_t new_panid,
                                      uint8_t new_channel,
                                      uint8_t new_page)
{
    retval_t tal_tx_status;
    uint8_t frame_len;
    uint8_t *frame_ptr;
    uint8_t *temp_frame_ptr;
    uint16_t fcf;
    uint16_t bc_addr = BROADCAST;

    /*
     * Orphan request is reused to send coordinator realignment
     * command frame and finally to send comm-status-indication
     */
    mlme_orphan_resp_t orphan_resp;
    memcpy(&orphan_resp,
           (mlme_orphan_resp_t *)BMM_BUFFER_POINTER((buffer_t *)buf_ptr),
           sizeof(mlme_orphan_resp_t));

    frame_info_t *coord_realignment_frame =
            (frame_info_t *)BMM_BUFFER_POINTER((buffer_t *)buf_ptr);

    coord_realignment_frame->msg_type = cmd_type;
    coord_realignment_frame->buffer_header = buf_ptr;

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

    /* Update the payload field. */
    *frame_ptr++ = COORDINATORREALIGNMENT;

    /*
     * The payload of the frame has the parameters of the new PAN
     * configuration
     */
    *frame_ptr++ = new_panid;
    *frame_ptr++ = (new_panid >> 8);

    *frame_ptr++ = tal_pib_ShortAddress;
    *frame_ptr++ = (tal_pib_ShortAddress >> 8);

    *frame_ptr++ = new_channel;

    /*
     * Insert the device's short address, or 0xFFFF if this is a
     * gratuitous realigment.
     */
    if (ORPHANREALIGNMENT == cmd_type)
    {
        *frame_ptr++ = orphan_resp.ShortAddress;
        *frame_ptr++ = (orphan_resp.ShortAddress >> 8);
    }
Пример #2
0
/**
 * @brief Handles an MLME-GET.request
 *
 * This function handles an MLME-GET.request.
 * The MLME-GET.request primitive requests information about a
 * given PIB attribute.
 *
 * @param m Pointer to the request structure
 */
void mlme_get_request(uint8_t *m)
{
	/* Use the mlme get request buffer for mlme get confirmation */
	mlme_get_conf_t *mgc = (mlme_get_conf_t *)BMM_BUFFER_POINTER(
			(buffer_t *)m);
#if ((defined MAC_SECURITY_ZIP)  || (defined MAC_SECURITY_2006))
	uint8_t attribute_index = ((mlme_get_req_t *)mgc)->PIBAttributeIndex;
#endif /* (MAC_SECURITY_ZIP || MAC_SECURITY_2006) */

	/* Do actual PIB attribute reading */
	{
		pib_value_t *attribute_value = &mgc->PIBAttributeValue;
		uint8_t status = MAC_SUCCESS;

#if ((defined MAC_SECURITY_ZIP)  || (defined MAC_SECURITY_2006))
		status = mlme_get(((mlme_get_req_t *)mgc)->PIBAttribute,
				attribute_value, attribute_index);
		mgc->PIBAttributeIndex = attribute_index;
#else
		status = mlme_get(((mlme_get_req_t *)mgc)->PIBAttribute,
				attribute_value);
#endif /* (MAC_SECURITY_ZIP || MAC_SECURITY_2006) */
		mgc->PIBAttribute = ((mlme_get_req_t *)mgc)->PIBAttribute;
		mgc->cmdcode      = MLME_GET_CONFIRM;
		mgc->status       = status;
	}

	/* Append the mlme get confirmation to MAC-NHLE queue */
	qmm_queue_append(&mac_nhle_q, (buffer_t *)m);
}
Пример #3
0
bool wpan_mlme_associate_req(uint8_t LogicalChannel,
                             uint8_t ChannelPage,
                             wpan_addr_spec_t *CoordAddrSpec,
                             uint8_t CapabilityInformation)
{
    buffer_t *buffer_header;
    mlme_associate_req_t *mlme_associate_req;

    /* Allocate a buffer for mlme associate request */
    buffer_header = bmm_buffer_alloc(LARGE_BUFFER_SIZE);

    /* Check for buffer availability */
    if (NULL == buffer_header) {
        return false;
    }

    /* Get the buffer body from buffer header */
    mlme_associate_req = (mlme_associate_req_t *)BMM_BUFFER_POINTER(
                             buffer_header);

    /* Construct mlme_associate_req_t message */
    mlme_associate_req->cmdcode = MLME_ASSOCIATE_REQUEST;

    /* Operating channel */
    mlme_associate_req->LogicalChannel = LogicalChannel;

    /* Coordinator address spec */
    mlme_associate_req->CoordAddrMode = CoordAddrSpec->AddrMode;

#ifdef TEST_HARNESS_BIG_ENDIAN
    mlme_associate_req->CoordPANId
        = CPU_ENDIAN_TO_LE16(CoordAddrSpec->PANId);
#else
    mlme_associate_req->CoordPANId = CoordAddrSpec->PANId;
#endif

    ADDR_COPY_DST_SRC_64(mlme_associate_req->CoordAddress.long_address,
                         CoordAddrSpec->Addr.long_address);

    /* Other fields */
    mlme_associate_req->CapabilityInformation = CapabilityInformation;
    mlme_associate_req->ChannelPage = ChannelPage;

    /* Insert service message into NHLE MLME queue */
#ifdef ENABLE_QUEUE_CAPACITY
    if (MAC_SUCCESS != qmm_queue_append(&nhle_mac_q, buffer_header)) {
        /*
         * MLME-ASSOCIATE.request is not appended into NHLE MAC
         * queue, hence free the buffer allocated
         */
        bmm_buffer_free(buffer_header);
        return false;
    }

#else
    qmm_queue_append(&nhle_mac_q, buffer_header);
#endif  /* ENABLE_QUEUE_CAPACITY */

    return true;
}
Пример #4
0
/**
 * @brief Wrapper function for messages of type mlme_comm_status_ind_t
 *
 * This function is a callback for mlme comm status indication.
 *
 * @param m Pointer to message structure
 */
void mlme_comm_status_ind(uint8_t *m)
{
	mlme_comm_status_ind_t *pmsg;
	wpan_addr_spec_t src_addr;
	wpan_addr_spec_t dst_addr;

	/* Get the buffer body from buffer header */
	pmsg = (mlme_comm_status_ind_t *)BMM_BUFFER_POINTER(((buffer_t *)m));

	/* Source address spec */
	src_addr.PANId = pmsg->PANId;
	src_addr.AddrMode = pmsg->SrcAddrMode;
	ADDR_COPY_DST_SRC_64(src_addr.Addr.long_address, pmsg->SrcAddr);

	/* Destintion address spec */
	dst_addr.PANId = pmsg->PANId;
	dst_addr.AddrMode = pmsg->DstAddrMode;
	ADDR_COPY_DST_SRC_64(dst_addr.Addr.long_address, pmsg->DstAddr);

	/* Callback function */
	usr_mlme_comm_status_ind(&src_addr,
			&dst_addr,
			pmsg->status);

	/* Free the buffer */
	bmm_buffer_free((buffer_t *)m);
}
Пример #5
0
/**
 * @brief ED scan callback function.
 *
 * This function is a callback function from the TAL after ED scan
 * is performed on a specified channel.
 *
 * @param energy_level Maximum energy on the channel
 */
void tal_ed_end_cb(uint8_t energy_level)
{
	MAKE_MAC_NOT_BUSY();

	mlme_scan_conf_t *msc;

	/*
	 * Scan request buffer is used to generate a scan confirm for the ED
	 * scan
	 * which is stored in mac_conf_buf_ptr.
	 */
	msc = (mlme_scan_conf_t *)BMM_BUFFER_POINTER(
			(buffer_t *)mac_conf_buf_ptr);

	uint8_t n_eds;

	n_eds = msc->ResultListSize;
	msc->scan_result_list[0].ed_value[n_eds] = energy_level;
	msc->ResultListSize++;
	msc->scan_result_list[0].ed_value[n_eds + 1] = 0;

	msc->UnscannedChannels &= ~(1UL << scan_curr_channel);

	/* Continue with next channel */
	scan_proceed(MLME_SCAN_TYPE_ED, (buffer_t *)mac_conf_buf_ptr);
}
Пример #6
0
/**
 * @brief Builds the data frame for transmission
 *
 * This function builds the data frame for transmission.
 * The NWK layer has supplied the parameters.
 * The frame_info_t data type is constructed and filled in.
 * Also the FCF is constructed based on the parameters passed.
 *
 * @param msg Pointer to the MCPS-DATA.request parameter
 */
void mcps_data_request(uint8_t *msg)
{
    retval_t status = FAILURE;
    mcps_data_req_t mdr;

    memcpy(&mdr, BMM_BUFFER_POINTER((buffer_t *)msg), sizeof(mcps_data_req_t));

    if ((mdr.TxOptions & WPAN_TXOPT_INDIRECT) == 0)
    {
        /*
         * Data Requests for a coordinator using direct transmission are
         * accepted in all non-transient states (no polling and no scanning
         * is ongoing).
         */
        if ((MAC_POLL_IDLE != mac_poll_state) ||
            (MAC_SCAN_IDLE != mac_scan_state)
           )
        {
            mac_gen_mcps_data_conf((buffer_t *)msg,
                                   (uint8_t)MAC_CHANNEL_ACCESS_FAILURE,
#ifdef ENABLE_TSTAMP
                                   mdr.msduHandle,
                                   0);
#else
                                   mdr.msduHandle);
#endif  /* ENABLE_TSTAMP */
            return;
        }
    }
Пример #7
0
void mac_process_gts_request(buffer_t *gts_req)
{
    /* Use the frame reception buffer for association indication. */
    mlme_gts_ind_t *mgi = (mlme_gts_ind_t *)BMM_BUFFER_POINTER(
                              gts_req);

    mgi->DeviceAddr = mac_parse_data.src_addr.short_address;

    mgi->GtsChar = mac_parse_data.mac_payload_data.gts_req_data;
    mgi->cmdcode = MLME_GTS_INDICATION;

    if (GTS_ALLOCATE == (mgi->GtsChar).GtsCharType) {
        if (mac_gts_allocate(mgi->GtsChar, mgi->DeviceAddr)) {
            /* Append the MLME GTS indication to the MAC-NHLE queue.
             **/
            qmm_queue_append(&mac_nhle_q, gts_req);
        } else {
            bmm_buffer_free(gts_req);
        }
    } else {
        if (mac_gts_deallocate(mgi->GtsChar, mgi->DeviceAddr, false)) {
            /* Append the MLME GTS indication to the MAC-NHLE queue.
             **/
            qmm_queue_append(&mac_nhle_q, gts_req);
        } else {
            bmm_buffer_free(gts_req);
        }
    }
}
Пример #8
0
void rtb_process_data_ind(uint8_t *msg)
{
    buffer_t *buf_ptr = (buffer_t *)msg;
    frame_info_t *frameptr = (frame_info_t *)BMM_BUFFER_POINTER(buf_ptr);
    mac_parse_data.mpdu_length = frameptr->mpdu[0];

    /* First extract LQI. */
    mac_parse_data.ppdu_link_quality = frameptr->mpdu[mac_parse_data.mpdu_length + LQI_LEN];

#ifdef RTB_WITHOUT_MAC
    /* Handle the received frame in case the frame is an RTB frame. */
    handle_rx_rtb_frame_type(frameptr);

    /*
     * Release buffer in any case, since it is not forwarded
     * to any higher layer.
     */
    bmm_buffer_free(buf_ptr);
#else   /* #ifdef RTB_WITHOUT_MAC */
    /* Handle the received frame in case the frame is an RTB frame. */
    if (!handle_rx_rtb_frame_type(frameptr))
    {
        /* This is a not an RTB frame, so it is forwarded to the MAC. */
        frameptr->msg_type = (frame_msgtype_t)TAL_DATA_INDICATION;
        qmm_queue_append(&tal_mac_q, buf_ptr);
    }
    else
    {
        bmm_buffer_free(buf_ptr);
    }
#endif  /* #ifdef RTB_WITHOUT_MAC */
}
/**
 * @brief Obtains the message type from the buffer and calls the respective handler
 *
 * This function decodes all events/messages and calls the appropriate handler.
 *
 * @param event Pointer to the buffer header whose body part holds the message
 * type and message elemnets
 */
void dispatch_event(uint8_t *event)
{
    /*
     * A pointer to the body of the buffer is obtained from the pointer to the
     * received header.
     */
    uint8_t *buffer_body = BMM_BUFFER_POINTER((buffer_t *)event);

    /* Check is done to see if the message type is valid */
    /* Please note:
     * The macro PGM_READ_WORD is only relevant for AVR-GCC builds and
     * reads a DWord from flash, which is the start address of the function.
     *
     * How does this work for builds that are larger than 128K?
     *
     * For IAR builds this statement is fine, since PGM_READ_WORD just
     * turns to "*". The size of the function pointer is automatically
     * 3 byte for MCUs which have more than 128K flash. The the address
     * of the callback is properly derived from this location.
     *
     * AVR-GCC currently does not support function pointers larger than
     * 16 bit. This implies that functions residing in the upper 128K
     * cannot be addressed properly. Therefore this code does not work
     * in these cases.
     * In regular cases, where code is not larger than 128K, the size
     * of a function pointer is 16 bit and properly read via PGM_READ_WORD.
     *
     * Update: In order for this to work, the option -mrelax must be given 
     * on the compiler command-line that is used to link the final ELF file. 
     * (Older compilers did not implement this option for the AVR, 
     * use -Wl,--relax instead.)     */
    /* Check for regular MAC requests. */
    if (buffer_body[CMD_ID_OCTET] <= LAST_MESSAGE)
    {
        /*
         * The following statement reads the address from the dispatch table
         * of the function to be called by utilizing function pointers.
         */
        handler_t handler = (handler_t)PGM_READ_WORD(&dispatch_table[buffer_body[CMD_ID_OCTET]]);

        if (handler != NULL)
        {
            handler(event);
        }
        else
        {
            bmm_buffer_free((buffer_t *)event);
#if (DEBUG > 0)
            ASSERT("Dispatch handler unavailable" == 0);
#endif
        }
    }
#ifdef ENABLE_RTB
    else
    {
        dispatch_rtb_event(event);
    }
#endif  /* ENABLE_RTB */
}
/*
 * @brief Internal function to initiate rx enable confirm message.
 *
 * This function creates the rx enable confirm structure,
 * and appends it into internal event queue.
 *
 * @param buf Buffer for rx enable confirmation.
 * @param status Status of attempt to switch receiver on.
 */
static void gen_rx_enable_conf(buffer_t *buf, uint8_t status)
{
    mlme_rx_enable_conf_t *rec = (mlme_rx_enable_conf_t *)BMM_BUFFER_POINTER(buf);

    rec->cmdcode = MLME_RX_ENABLE_CONFIRM;
    rec->status = status;
    qmm_queue_append(&mac_nhle_q, buf);
}
Пример #11
0
/**
 * @brief Handles an orphan notification
 *
 * This function processes an incoming orphan notification command.
 * A PAN coordinator gets to this function through a TAL data indication
 * message.
 *
 * @param msg Frame reception buffer
 */
void mac_process_orphan_notification(buffer_t *msg)
{
	mlme_orphan_ind_t *moi = (mlme_orphan_ind_t *)BMM_BUFFER_POINTER(msg);

	moi->cmdcode = MLME_ORPHAN_INDICATION;
	ADDR_COPY_DST_SRC_64(moi->OrphanAddress,
			mac_parse_data.src_addr.long_address);

	/* Append the MLME orphan indication message to MAC-NHLE queue */
	qmm_queue_append(&mac_nhle_q, msg);
}
Пример #12
0
/*
 * @brief Sends mlme reset confirm
 *
 * @param m Buffer for reset confirm
 * @param status Status of MAC reset operation
 */
static void send_reset_conf(buffer_t *buf_ptr, uint8_t status)
{
	mlme_reset_conf_t *mrc;

	mrc = (mlme_reset_conf_t *)BMM_BUFFER_POINTER(buf_ptr);

	mrc->status = status;
	mrc->cmdcode = MLME_RESET_CONFIRM;

	/* Append the mlme reset confirm to the MAC-NHLE queue */
	qmm_queue_append(&mac_nhle_q, buf_ptr);
}
Пример #13
0
/**
 * @brief Wrapper function for messages of type mlme_associate_conf_t
 *
 * This function is a callback for mlme associate confirm.
 *
 * @param m Pointer to message structure
 */
void mlme_associate_conf(uint8_t *m)
{
	mlme_associate_conf_t *pmsg;

	/* Get the buffer body from buffer header */
	pmsg = (mlme_associate_conf_t *)BMM_BUFFER_POINTER(((buffer_t *)m));

	usr_mlme_associate_conf(pmsg->AssocShortAddress, pmsg->status);

	/* Free the buffer */
	bmm_buffer_free((buffer_t *)m);
}
Пример #14
0
void mlme_gts_ind(uint8_t *m)
{
	mlme_gts_ind_t *pmsg;

	/* Get the buffer body from buffer header */
	pmsg = (mlme_gts_ind_t *)BMM_BUFFER_POINTER(((buffer_t *)m));

	usr_mlme_gts_ind(pmsg->DeviceAddr, pmsg->GtsChar);

	/* Free the buffer */
	bmm_buffer_free((buffer_t *)m);
}
Пример #15
0
void mac_gen_mlme_gts_conf(buffer_t *buf_ptr, uint8_t status, gts_char_t gts_char)
{
	mlme_gts_conf_t *gts_conf
	= (mlme_gts_conf_t *)BMM_BUFFER_POINTER(buf_ptr);

	gts_conf->cmdcode = MLME_GTS_CONFIRM;
	gts_conf->status = status;
	gts_conf->GtsChar = gts_char;

	/* Append the associate confirm message to MAC-NHLE queue. */
	qmm_queue_append(&mac_nhle_q, buf_ptr);
}
Пример #16
0
void mlme_gts_conf(uint8_t *m)
{
	mlme_gts_conf_t *pmsg;

	/* Get the buffer body from buffer header */
	pmsg = (mlme_gts_conf_t *)BMM_BUFFER_POINTER(((buffer_t *)m));

	usr_mlme_gts_conf(pmsg->GtsChar, pmsg->status);

	/* Free the buffer */
	bmm_buffer_free((buffer_t *)m);
}
Пример #17
0
/**
 * @brief Wrapper function for messages of type mcps_purge_conf_t
 *
 * This function is a callback for mcps purge confirm.
 *
 * @param m Pointer to message structure
 */
void mcps_purge_conf(uint8_t *m)
{
	mcps_purge_conf_t *pmsg;

	/* Get the buffer body from buffer header */
	pmsg = (mcps_purge_conf_t *)BMM_BUFFER_POINTER(((buffer_t *)m));

	usr_mcps_purge_conf(pmsg->msduHandle, pmsg->status);

	/* Free the buffer */
	bmm_buffer_free((buffer_t *)m);
}
Пример #18
0
/**
 * @brief Creates a Communication Status Indication message to the upper layer
 *
 * @param status Status of the last operation
 * @param buf_ptr Buffer for Communication Status Indication to the NHLE
 */
void mac_mlme_comm_status(uint8_t status,
		buffer_t *buf_ptr)
{
	/*
	 * The pointer to the destination address (received as one of the
	 * function
	 * paramters) points to a location in buf_ptr.
	 * As the same buffer is used to generate the comm status
	 * indication, it is typecasted to the 'mlme_comm_status_ind_t'. This
	 * may
	 * result in loosing destination address (which is still a part of this
	 * buffer), hence the destination address is backed up in a stack
	 * variable.
	 */
	frame_info_t *frame_ptr = (frame_info_t *)BMM_BUFFER_POINTER(buf_ptr);
	uint64_t destination_address;
	memcpy(&destination_address,
			&frame_ptr->mpdu[PL_POS_DST_ADDR_START],
			sizeof(uint64_t));
	mlme_comm_status_ind_t *csi
		= (mlme_comm_status_ind_t *)BMM_BUFFER_POINTER(buf_ptr);

	csi->cmdcode = MLME_COMM_STATUS_INDICATION;

	csi->PANId = tal_pib.PANId;

	csi->SrcAddrMode = FCF_LONG_ADDR;

	/* Initialize the source address */
	csi->SrcAddr = tal_pib.IeeeAddress;

	csi->DstAddrMode = FCF_LONG_ADDR;

	/* Initialize the destination address */
	csi->DstAddr = destination_address;

	csi->status = status;

	qmm_queue_append(&mac_nhle_q, buf_ptr);
}
Пример #19
0
/*
 * @brief Internal function to generate confirmation
 * for MLME_START.request
 *
 * @param start_buf_ptr Pointer to MLME_START.request
 * @param start_req_status Status of the MLME_START.request
 */
static void gen_mlme_start_conf(buffer_t *start_buf_ptr,
                                uint8_t start_req_status)
{

    /* Use the same start request buffer for start confirm */
    mlme_start_conf_t *msc = (mlme_start_conf_t *)BMM_BUFFER_POINTER(start_buf_ptr);

    msc->cmdcode = MLME_START_CONFIRM;
    msc->status = start_req_status;

    /* The confirmation message is appended to the MAC-NHLE queue */
    qmm_queue_append(&mac_nhle_q, start_buf_ptr);
}
Пример #20
0
/**
 * @brief Wrapper function for messages of type mlme_orphan_ind_t
 *
 * This function is a callback for mlme orphan indication.
 *
 * @param m Pointer to message structure
 */
void mlme_orphan_ind(uint8_t *m)
{
	mlme_orphan_ind_t *pmsg;

	/* Get the buffer body from buffer header */
	pmsg = (mlme_orphan_ind_t *)BMM_BUFFER_POINTER(((buffer_t *)m));

	/* Callback function */
	usr_mlme_orphan_ind(pmsg->OrphanAddress);

	/* Free the buffer */
	bmm_buffer_free((buffer_t *)m);
}
Пример #21
0
/**
 * @brief Wrapper function for messages of type mlme_disassociate_ind_t
 *
 * This function is a callback for mlme disassociate indication.
 *
 * @param m Pointer to message structure
 */
void mlme_disassociate_ind(uint8_t *m)
{
	mlme_disassociate_ind_t *pmsg;

	/* Get the buffer body from buffer header */
	pmsg = (mlme_disassociate_ind_t *)BMM_BUFFER_POINTER(((buffer_t *)m));

	usr_mlme_disassociate_ind(pmsg->DeviceAddress,
			pmsg->DisassociateReason);

	/* Free the buffer */
	bmm_buffer_free((buffer_t *)m);
}
Пример #22
0
uint8_t pal_sio_init(uint8_t UARTx) 
{

  buffer_t *buffer_header;
  NWK_DataReq_t *nlde_data_req;

  buffer_header = bmm_buffer_alloc(LARGE_BUFFER_SIZE);
  nlde_data_req = (NWK_DataReq_t *)BMM_BUFFER_POINTER(buffer_header);
  uart_0_buffer.rx_buf_head = ((uint8_t *)nlde_data_req) + (LARGE_BUFFER_SIZE - FCS_LEN - TRANSPARENT_IO_BUF_SIZE);
  uart_0_buffer.rx_buf[0] = (uint8_t *)buffer_header;
	UARTx = UARTx;
	return 0;
}
Пример #23
0
/**
 * @brief Wrapper function for messages of type mcps_data_ind_t
 *
 * This function is a callback for mcps data indication
 *
 * @param m Pointer to message structure
 */
void mcps_data_ind(uint8_t *m)
{
	mcps_data_ind_t *pmsg;
	wpan_addr_spec_t src_addr;
	wpan_addr_spec_t dst_addr;

	/* Get the buffer body from buffer header */
	pmsg = (mcps_data_ind_t *)BMM_BUFFER_POINTER(((buffer_t *)m));

	/* Source address spec */
	src_addr.AddrMode = pmsg->SrcAddrMode;
	src_addr.PANId = pmsg->SrcPANId;
	src_addr.Addr.long_address = pmsg->SrcAddr;
	ADDR_COPY_DST_SRC_64(src_addr.Addr.long_address, pmsg->SrcAddr);

	/* Destination address spec */
	dst_addr.AddrMode = pmsg->DstAddrMode;
	dst_addr.PANId = pmsg->DstPANId;
	ADDR_COPY_DST_SRC_64(dst_addr.Addr.long_address, pmsg->DstAddr);

	/* Callback function */
#if ((defined MAC_SECURITY_ZIP)  || (defined MAC_SECURITY_2006))
	usr_mcps_data_ind(&src_addr,
			&dst_addr,
			pmsg->msduLength,
			pmsg->msdu,
			pmsg->mpduLinkQuality,
			pmsg->DSN,
    #ifdef ENABLE_TSTAMP
			pmsg->Timestamp,
    #endif  /* ENABLE_TSTAMP */
			pmsg->SecurityLevel,
			pmsg->KeyIdMode,
			pmsg->KeyIndex);
#else   /* No MAC_SECURITY */
	usr_mcps_data_ind(&src_addr,
			&dst_addr,
			pmsg->msduLength,
			pmsg->msdu,
			pmsg->mpduLinkQuality,
    #ifdef ENABLE_TSTAMP
			pmsg->DSN,
			pmsg->Timestamp);
    #else
			pmsg->DSN);
    #endif  /* ENABLE_TSTAMP */
#endif  /* MAC_SECURITY */

	/* Free the buffer */
	bmm_buffer_free((buffer_t *)m);
}
Пример #24
0
void mac_gts_table_update(void)
{
    uint8_t table_index;

    for (table_index = 0; table_index < mac_pan_gts_table_len;
            table_index++) {
        if (mac_pan_gts_table[table_index].ExpiryCount > 0 &&
                --mac_pan_gts_table[table_index].ExpiryCount ==
                0) {
            gts_char_t gts_char;
            uint16_t dev_addr
                = mac_pan_gts_table[table_index].DevShortAddr;
            gts_char.GtsDirection
                = mac_pan_gts_table[table_index].GtsDesc
                  .GtsDirection;
            gts_char.GtsLength
                = mac_pan_gts_table[table_index].GtsDesc
                  .GtsLength;
            gts_char.GtsCharType = GTS_DEALLOCATE;
            gts_char.Reserved = 0;
            if (mac_gts_deallocate(gts_char,
                                   mac_pan_gts_table[table_index].
                                   DevShortAddr, true)) {
                buffer_t *buffer_header;
                mlme_gts_ind_t *mgi;

                buffer_header = bmm_buffer_alloc(
                                    LARGE_BUFFER_SIZE);

                if (NULL == buffer_header) {
                    /* Buffer is not available */
                    return;
                }

                mgi = (mlme_gts_ind_t *)BMM_BUFFER_POINTER(
                          buffer_header);

                mgi->DeviceAddr = dev_addr;

                mgi->GtsChar = gts_char;
                mgi->cmdcode = MLME_GTS_INDICATION;

                /* Append the MLME GTS indication to the
                 *MAC-NHLE queue. */
                qmm_queue_append(&mac_nhle_q, buffer_header);
                --table_index;
            }
        }
    }
}
Пример #25
0
bool wpan_mlme_associate_resp(uint64_t DeviceAddress,
                              uint16_t AssocShortAddress,
                              uint8_t status)
{
    buffer_t *buffer_header;
    mlme_associate_resp_t *mlme_associate_resp;

    /* Allocate a small buffer for association response */
    buffer_header = bmm_buffer_alloc(LARGE_BUFFER_SIZE);

    if (NULL == buffer_header) {
        /* Buffer is not available */
        return false;
    }

    /* Get the buffer body from buffer header */
    mlme_associate_resp = (mlme_associate_resp_t *)BMM_BUFFER_POINTER(
                              buffer_header);

    /* Construct mlme_associate_resp_t message */
    mlme_associate_resp->cmdcode = MLME_ASSOCIATE_RESPONSE;

    /* Other fields */
#ifdef TEST_HARNESS_BIG_ENDIAN
    mlme_associate_resp->DeviceAddress  = CPU_ENDIAN_TO_LE64(DeviceAddress);
    mlme_associate_resp->AssocShortAddress = CPU_ENDIAN_TO_LE16(
                AssocShortAddress);
#else
    mlme_associate_resp->DeviceAddress  = DeviceAddress;
    mlme_associate_resp->AssocShortAddress = AssocShortAddress;
#endif
    mlme_associate_resp->status = status;

    /* Insert mlme_associate_resp_t into NHLE MAC queue */
#ifdef ENABLE_QUEUE_CAPACITY
    if (MAC_SUCCESS != qmm_queue_append(&nhle_mac_q, buffer_header)) {
        /*
         * MLME-ASSOCIATE.response is not appended into NHLE MAC
         * queue, hence free the buffer allocated
         */
        bmm_buffer_free(buffer_header);
        return false;
    }

#else
    qmm_queue_append(&nhle_mac_q, buffer_header);
#endif  /* ENABLE_QUEUE_CAPACITY */

    return true;
}
Пример #26
0
void mac_gen_mcps_data_conf(buffer_t *buf, uint8_t status, uint8_t handle)
#endif  /* ENABLE_TSTAMP */
{
    mcps_data_conf_t *mdc = (mcps_data_conf_t *)BMM_BUFFER_POINTER(buf);

    mdc->cmdcode = MCPS_DATA_CONFIRM;
    mdc->msduHandle = handle;
    mdc->status = status;
#ifdef ENABLE_TSTAMP
    mdc->Timestamp = timestamp;
#endif  /* ENABLE_TSTAMP */

    qmm_queue_append(&mac_nhle_q, buf);
}
Пример #27
0
bool wpan_mlme_poll_req(wpan_addr_spec_t *CoordAddrSpec)
{
    buffer_t *buffer_header;
    mlme_poll_req_t *mlme_poll_req;

    /* Allocate a small buffer for poll request */
    buffer_header = bmm_buffer_alloc(LARGE_BUFFER_SIZE);

    if (NULL == buffer_header) {
        /* Buffer is not available */
        return false;
    }

    /* Get the buffer body from buffer header */
    mlme_poll_req = (mlme_poll_req_t *)BMM_BUFFER_POINTER(buffer_header);

    /* construct mlme_poll_req_t message */
    mlme_poll_req->cmdcode = MLME_POLL_REQUEST;

    /* Other fileds. */
    mlme_poll_req->CoordAddrMode = CoordAddrSpec->AddrMode;
#ifdef TEST_HARNESS_BIG_ENDIAN
    mlme_poll_req->CoordPANId = CPU_ENDIAN_TO_LE16(CoordAddrSpec->PANId);
#else
    mlme_poll_req->CoordPANId = CoordAddrSpec->PANId;
#endif
    if (WPAN_ADDRMODE_SHORT == CoordAddrSpec->AddrMode) {
        ADDR_COPY_DST_SRC_16(mlme_poll_req->CoordAddress,
                             CoordAddrSpec->Addr.short_address);
    } else {
        ADDR_COPY_DST_SRC_64(mlme_poll_req->CoordAddress,
                             CoordAddrSpec->Addr.long_address);
    }

#ifdef ENABLE_QUEUE_CAPACITY
    if (MAC_SUCCESS != qmm_queue_append(&nhle_mac_q, buffer_header)) {
        /*
         * MLME-POLL.request is not appended into NHLE MAC
         * queue, hence free the buffer allocated and return false
         */
        bmm_buffer_free(buffer_header);
        return false;
    }

#else
    qmm_queue_append(&nhle_mac_q, buffer_header);
#endif  /* ENABLE_QUEUE_CAPACITY */

    return true;
}
Пример #28
0
/**
 * @brief Wrapper function for messages of type mlme_sync_loss_ind_t
 *
 * This function is a callback for mlme sync loss indication.
 *
 * @param m Pointer to message structure
 */
void mlme_sync_loss_ind(uint8_t *m)
{
	mlme_sync_loss_ind_t *pmsg;

	/* Get the buffer body from buffer header */
	pmsg = (mlme_sync_loss_ind_t *)BMM_BUFFER_POINTER(((buffer_t *)m));

	usr_mlme_sync_loss_ind(pmsg->LossReason,
			pmsg->PANId,
			pmsg->LogicalChannel,
			pmsg->ChannelPage);

	/* Uses static buffer for sync loss indication and it is not freed */
}
Пример #29
0
bool wpan_mlme_disassociate_req(wpan_addr_spec_t *DeviceAddrSpec,
                                uint8_t DisassociateReason,
                                bool TxIndirect)
{
    buffer_t *buffer_header;
    mlme_disassociate_req_t *mlme_disassociate_req;

    /* Allocate a small buffer for disassociation request */
    buffer_header = bmm_buffer_alloc(LARGE_BUFFER_SIZE);

    if (NULL == buffer_header) {
        /* Buffer is not available */
        return false;
    }

    /* Get the buffer body from buffer header */
    mlme_disassociate_req = (mlme_disassociate_req_t *)BMM_BUFFER_POINTER(
                                buffer_header);

    /* Update the disassociate request structure */
    mlme_disassociate_req->cmdcode = MLME_DISASSOCIATE_REQUEST;
    mlme_disassociate_req->DisassociateReason = DisassociateReason;
    mlme_disassociate_req->DeviceAddrMode = DeviceAddrSpec->AddrMode;
#ifdef TEST_HARNESS_BIG_ENDIAN
    mlme_disassociate_req->DevicePANId = CPU_ENDIAN_TO_LE16(
            DeviceAddrSpec->PANId);
#else
    mlme_disassociate_req->DevicePANId = DeviceAddrSpec->PANId;
#endif
    ADDR_COPY_DST_SRC_64(mlme_disassociate_req->DeviceAddress,
                         DeviceAddrSpec->Addr.long_address);
    mlme_disassociate_req->TxIndirect = TxIndirect;

#ifdef ENABLE_QUEUE_CAPACITY
    if (MAC_SUCCESS != qmm_queue_append(&nhle_mac_q, buffer_header)) {
        /*
         * MLME-DISASSOCIATE.request is not appended into NHLE MAC
         * queue, hence free the buffer allocated and return false
         */
        bmm_buffer_free(buffer_header);
        return false;
    }

#else
    qmm_queue_append(&nhle_mac_q, buffer_header);
#endif  /* ENABLE_QUEUE_CAPACITY */

    return true;
}
Пример #30
0
/**
 * @brief Wrapper function for messages of type mcps_data_conf_t
 *
 * This function is a callback for mcps data confirm.
 *
 * @param m Pointer to message structure
 */
void mcps_data_conf(uint8_t *m)
{
	mcps_data_conf_t *pmsg;

	/* Get the buffer body from buffer header */
	pmsg = (mcps_data_conf_t *)BMM_BUFFER_POINTER(((buffer_t *)m));

#ifdef ENABLE_TSTAMP
	usr_mcps_data_conf(pmsg->msduHandle, pmsg->status, pmsg->Timestamp);
#else
	usr_mcps_data_conf(pmsg->msduHandle, pmsg->status);
#endif  /* ENABLE_TSTAMP */

	/* Free the buffer */
	bmm_buffer_free((buffer_t *)m);
}