Ejemplo n.º 1
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;
}
Ejemplo n.º 2
0
/**
 * @brief Processes received beacon frame
 *
 * This function processes a received beacon frame.
 * When the system is scanning it records PAN descriptor information
 * contained in the beacon. These PAN descriptors will be reported to the
 * next higher layer via MLME_SCAN.confirm.
 * Also this routine constructs the MLME_BEACON_NOTIFY.indication.
 * Additionally when a device is synced with the coordinator, it tracks beacon
 * frames, checks whether the coordinator does have pending data and will
 * initiate the transmission of a data request frame.
 * The routine uses global "parse_data" structure.
 * The PAN descriptors are stored in the mlme_scan_conf_t structure.
 *
 * @param beacon Pointer to the buffer in which the beacon was received
 *
 */
void mac_process_beacon_frame(buffer_t *beacon)
{
    bool matchflag;
    wpan_pandescriptor_t *pand_long_start_p = NULL;
    wpan_pandescriptor_t pand_long;
    mlme_scan_conf_t *msc = NULL;

#if ((MAC_BEACON_NOTIFY_INDICATION == 1) || \
     ((MAC_INDIRECT_DATA_BASIC == 1) && (MAC_SYNC_REQUEST == 1)) \
    )
    uint8_t numaddrshort;
    uint8_t numaddrlong;
#endif

#ifdef BEACON_SUPPORT
    uint16_t beacon_length;

    /*
     * Extract the superframe parameters of the beacon frame only if
     * scanning is NOT ongoing.
     */
    if (MAC_SCAN_IDLE == mac_scan_state)
    {
#if (MAC_START_REQUEST_CONFIRM == 1)
        /* Beacon frames are not of interest for a PAN coordinator. */
        if (MAC_PAN_COORD_STARTED != mac_state)
#endif /* MAC_START_REQUEST_CONFIRM */
        {
            uint8_t superframe_order;
            uint8_t beacon_order;

            /*
             * For a device, the parameters obtained from the beacons are used to
             * update the PIBs at TAL
             */
            beacon_order =
                GET_BEACON_ORDER(mac_parse_data.mac_payload_data.beacon_data.superframe_spec);

#if (_DEBUG_ > 0)
            retval_t set_status =
#endif
            set_tal_pib_internal(macBeaconOrder, (void *)&beacon_order);

#if (_DEBUG_ > 0)
            Assert(MAC_SUCCESS == set_status);
#endif
            superframe_order =
                GET_SUPERFRAME_ORDER(mac_parse_data.mac_payload_data.beacon_data.superframe_spec);
#if (_DEBUG_ > 0)
            set_status =
#endif
            set_tal_pib_internal(macSuperframeOrder, (void *)&superframe_order);

#if (_DEBUG_ > 0)
            Assert(MAC_SUCCESS == set_status);
#endif

            mac_final_cap_slot =
            GET_FINAL_CAP(mac_parse_data.mac_payload_data.beacon_data.superframe_spec);

            /*
             * In a beacon-enabled network with the batterylife extension
             * enabled, the first backoff slot boundary is computed after the
             * end of the beacon's IFS
             */
            if ((tal_pib.BeaconOrder < NON_BEACON_NWK) && tal_pib.BattLifeExt)
            {
                /* Length given in octets */
                beacon_length = mac_parse_data.mpdu_length + PHY_OVERHEAD;

                /* Convert to symbols */
                beacon_length *= SYMBOLS_PER_OCTET;

                /* Space needed for IFS is added to it */
                if (mac_parse_data.mpdu_length <= aMaxSIFSFrameSize)
                {
                    beacon_length += macMinSIFSPeriod_def;
                }
                else
                {
                    beacon_length += macMinLIFSPeriod_def;
                }

                /* Round up to backoff slot boundary */
                beacon_length = (beacon_length + aUnitBackoffPeriod - 1) / aUnitBackoffPeriod;
                beacon_length *= aUnitBackoffPeriod;

                /*
                 * Slotted CSMA-CA with macBattLifeExt must start within
                 * the first macBattLifeExtPeriods backoff slots of the CAP
                 */
                beacon_length += mac_pib.mac_BattLifeExtPeriods * aUnitBackoffPeriod;
            }
        }   /* (MAC_PAN_COORD_STARTED != mac_state) */
    }   /* (MAC_SCAN_IDLE == mac_scan_state) */
#endif  /* BEACON_SUPPORT */

    /*
     * The following section needs to be done when we are
     * either scanning (and look for a new PAN descriptor to be returned
     * as part of the scan confirm message),
     * or we need to create a beacon notification (in which case we are
     * interested in any beacon, but omit the generation of scan confirm).
     */
    {
        uint8_t index;

        /*
         * If we are scanning a scan confirm needs to be created.
         *
         * According to 802.15.4-2006 this is only done in case the PIB
         * attribute macAutoRequest is true. Otherwise the PAN descriptor will
         * NOT be put into the PAN descriptor list of the Scan confirm message.
         */
        if (
            ((MAC_SCAN_ACTIVE == mac_scan_state) || (MAC_SCAN_PASSIVE == mac_scan_state)) &&
            mac_pib.mac_AutoRequest
           )
        {
            /*
             * mac_conf_buf_ptr points to the buffer allocated for scan
             * confirmation.
             */
             msc =  (mlme_scan_conf_t *)BMM_BUFFER_POINTER(
                        ((buffer_t *)mac_conf_buf_ptr));

            /*
             * The PAN descriptor list is updated with the PANDescriptor of the
             * received beacon
             */
            pand_long_start_p = (wpan_pandescriptor_t *)&msc->scan_result_list;
        }

        /*
         * The beacon data received from the parse variable is arranged
         * into a PAN descriptor structure style
         */
        pand_long.CoordAddrSpec.AddrMode = mac_parse_data.src_addr_mode;
        pand_long.CoordAddrSpec.PANId = mac_parse_data.src_panid;

        if (FCF_SHORT_ADDR == pand_long.CoordAddrSpec.AddrMode)
        {
            /* Initially clear the complete address. */
            pand_long.CoordAddrSpec.Addr.long_address = 0;

            ADDR_COPY_DST_SRC_16(pand_long.CoordAddrSpec.Addr.short_address, mac_parse_data.src_addr.short_address);
        }
        else
        {
            ADDR_COPY_DST_SRC_64(pand_long.CoordAddrSpec.Addr.long_address, mac_parse_data.src_addr.long_address);
        }

        pand_long.LogicalChannel = tal_pib.CurrentChannel;
        pand_long.ChannelPage    = tal_pib.CurrentPage;
        pand_long.SuperframeSpec = mac_parse_data.mac_payload_data.beacon_data.superframe_spec;
        pand_long.GTSPermit      = mac_parse_data.mac_payload_data.beacon_data.gts_spec >> 7;
        pand_long.LinkQuality    = mac_parse_data.ppdu_link_quality;
#ifdef ENABLE_TSTAMP
        pand_long.TimeStamp      = mac_parse_data.time_stamp;
#endif  /* ENABLE_TSTAMP */

        /*
         * If we are scanning we need to check whether this is a new
         * PAN descriptor.
         *
         * According to 802.15.4-2006 this is only done in case the PIB
         * attribute macAutoRequest is true. Otherwise the PAN descriptor will
         * NOT be put into the PAN descriptor list of the Scan confirm message.
         */
        if (
            ((MAC_SCAN_ACTIVE == mac_scan_state) || (MAC_SCAN_PASSIVE == mac_scan_state)) &&
            mac_pib.mac_AutoRequest
           )
        {
            /*
             * This flag is used to indicate a match of the current (received) PAN
             * descriptor with one of those present already in the list.
             */
            matchflag = false;

            /*
             * The beacon frame PAN descriptor is compared with the PAN descriptors
             * present in the list and determine if the current PAN
             * descriptor is to be taken as a valid one. A PAN is considered to be
             * the same as an existing one, if all, the PAN Id, the coordinator address
             * mode, the coordinator address, and the Logical Channel are same.
             */
            for (index = 0; index < msc->ResultListSize; index++, pand_long_start_p++)
            {
                if ((pand_long.CoordAddrSpec.PANId == pand_long_start_p->CoordAddrSpec.PANId) &&
                    (pand_long.CoordAddrSpec.AddrMode == pand_long_start_p->CoordAddrSpec.AddrMode) &&
                    (pand_long.LogicalChannel == pand_long_start_p->LogicalChannel) &&
                    (pand_long.ChannelPage == pand_long_start_p->ChannelPage)
                   )
                {
                    if (pand_long.CoordAddrSpec.AddrMode == WPAN_ADDRMODE_SHORT)
                    {
                        if (pand_long.CoordAddrSpec.Addr.short_address == pand_long_start_p->CoordAddrSpec.Addr.short_address)
                        {
                            /* Beacon with same parameters already received */
                            matchflag = true;
                            break;
                        }
                    }
                    else
                    {
                        if (pand_long.CoordAddrSpec.Addr.long_address == pand_long_start_p->CoordAddrSpec.Addr.long_address)
                        {
                            /* Beacon with same parameters already received */
                            matchflag = true;
                            break;
                        }
                    }
                }
            }

            /*
             * If the PAN descriptor is not in the current list, and there is space
             * left, it is put into the list
             */
            if ((!matchflag) && (msc->ResultListSize < MAX_PANDESCRIPTORS))
            {
                memcpy(pand_long_start_p, &pand_long, sizeof(pand_long));
                msc->ResultListSize++;
            }
        }
    }


#if ((MAC_BEACON_NOTIFY_INDICATION == 1) || \
     ((MAC_INDIRECT_DATA_BASIC == 1) && (MAC_SYNC_REQUEST == 1)) \
    )
    /* The short and extended pending addresses are extracted from the beacon */
    numaddrshort =
        NUM_SHORT_PEND_ADDR(mac_parse_data.mac_payload_data.beacon_data.pending_addr_spec);

    numaddrlong =
        NUM_LONG_PEND_ADDR(mac_parse_data.mac_payload_data.beacon_data.pending_addr_spec);
#endif

#if (MAC_BEACON_NOTIFY_INDICATION == 1)
    /*
     * In all cases (PAN or device) if the payload is not equal to zero
     * or macAutoRequest is false, MLME_BEACON_NOTIFY.indication is
     * generated
     */
    if ((mac_parse_data.mac_payload_data.beacon_data.beacon_payload_len > 0) ||
        (!mac_pib.mac_AutoRequest)
       )
    {
        mlme_beacon_notify_ind_t *mbni =
            (mlme_beacon_notify_ind_t *)BMM_BUFFER_POINTER(((buffer_t *)beacon));

        /* The beacon notify indication structure is built */
        mbni->cmdcode       = MLME_BEACON_NOTIFY_INDICATION;
        mbni->BSN           = mac_parse_data.sequence_number;
        mbni->PANDescriptor = pand_long;
        mbni->PendAddrSpec  = mac_parse_data.mac_payload_data.beacon_data.pending_addr_spec;

        if ((numaddrshort > 0) || (numaddrlong > 0))
        {
            mbni->AddrList = mac_parse_data.mac_payload_data.beacon_data.pending_addr_list;
        }

        mbni->sduLength = mac_parse_data.mac_payload_data.beacon_data.beacon_payload_len;
        mbni->sdu = mac_parse_data.mac_payload_data.beacon_data.beacon_payload;

        /*
         * The beacon notify indication is given to the NHLE and then the buffer
         * is freed up.
         */
        qmm_queue_append(&mac_nhle_q, (buffer_t *)beacon);
    }
    else
#endif /* (MAC_BEACON_NOTIFY_INDICATION == 1) */
    {
        /* Payload is not present, hence the buffer is freed here */
        bmm_buffer_free(beacon);
    }


/* Handling of ancounced broadcast traffic by the parent. */
#ifdef BEACON_SUPPORT
    if (MAC_SCAN_IDLE == mac_scan_state)
    {
        /*
         * In case this is a beaconing network, and this node is not scanning,
         * and the FCF indicates pending data thus indicating broadcast data at
         * parent, the node needs to be awake until the received broadcast
         * data has been received.
         */
        if (mac_parse_data.fcf & FCF_FRAME_PENDING)
        {
            mac_bc_data_indicated = true;

            /*
             * Start timer since the broadcast frame is expected within
             * macMaxFrameTotalWaitTime symbols.
             */
            if (MAC_POLL_IDLE == mac_poll_state)
            {
                /*
                 * If the poll state is not idle, there is already an
                 * indirect transaction ongoing.
                 * Since the T_Poll_Wait_Time is going to be re-used,
                 * this timer can only be started, if we are not in
                 * a polling state other than idle.
                 */
                uint32_t response_timer = mac_pib.mac_MaxFrameTotalWaitTime;
                response_timer = TAL_CONVERT_SYMBOLS_TO_US(response_timer);

                if (MAC_SUCCESS != pal_timer_start(T_Poll_Wait_Time,
                                                   response_timer,
                                                   TIMEOUT_RELATIVE,
                                                   (FUNC_PTR)mac_t_wait_for_bc_time_cb,
                                                   NULL))
                {
                    mac_t_wait_for_bc_time_cb(NULL);
                }
            }
            else
            {
                /*
                 * Any indirect poll operation is ongoing, so the timer will
                 * not be started, i.e. nothing to be done here.
                 * Once this ongoing indirect transaction has finished, this
                 * node will go back to sleep anyway.
                 */
            }
        }
        else
        {
            mac_bc_data_indicated = false;
        }

    }   /* (MAC_SCAN_IDLE == mac_scan_state) */
#endif /* BEACON_SUPPORT */


/* Handling of presented indirect traffic by the parent for this node. */
#if ((MAC_INDIRECT_DATA_BASIC == 1) && (MAC_SYNC_REQUEST == 1))
    if (MAC_SCAN_IDLE == mac_scan_state)
    {
        /*
         * If this node is NOT scanning, and is doing a mlme_sync_request,
         * then the pending address list of the beacon is examined to see
         * if the node's parent has data for this node.
         */
        if (mac_pib.mac_AutoRequest)
        {
            if (MAC_SYNC_NEVER != mac_sync_state)
            {
                uint8_t index;
#if (_DEBUG_ > 0)
                bool status;
#endif
                /*
                 * Short address of the device is compared with the
                 * pending short address in the beacon frame
                 */

                /*
                 * PAN-ID and CoordAddress does not have to be checked here,
                 * since the device is already synced with the coordinator, and
                 * only beacon frames passed from data_ind.c (where the first level
                 * filtering is already done) are received. The pending addresses
                 * in the beacon frame are compared with the device address. If a
                 * match is found, it indicates that a data belonging to this
                 * deivce is present with the coordinator and hence a data request
                 * is sent to the coordinator.
                 */
                uint16_t cur_short_addr;

                for (index = 0; index < numaddrshort; index++)
                {
                    cur_short_addr = convert_byte_array_to_16_bit((mac_parse_data.mac_payload_data.beacon_data.pending_addr_list +
                                                    index * sizeof(uint16_t)));
                    if (cur_short_addr == tal_pib.ShortAddress)
                    {
                        /*
                         * Device short address matches with one of the address
                         * in the beacon address list. Implicit poll (using the
                         * device short address) is done to get the pending data
                         */
#if (_DEBUG_ > 0)
                        status =
#endif
                            mac_build_and_tx_data_req(false, false, 0, NULL, 0);

#if (_DEBUG_ > 0)
                        Assert(status == true);
#endif
                        return;
                    }
                }

                /*
                 * Extended address of the device is compared with
                 * the pending extended address in the beacon frame
                 */
                uint64_t cur_long_addr;

                for (index = 0; index < numaddrlong; index++)
                {
                    cur_long_addr = convert_byte_array_to_64_bit((mac_parse_data.mac_payload_data.beacon_data.pending_addr_list +
                                                    numaddrshort * sizeof(uint16_t) + index * sizeof(uint64_t)));

                    if (cur_long_addr == tal_pib.IeeeAddress)
                    {
                        /*
                         * Device extended address matches with one of the
                         * address in the beacon address list. Implicit poll
                         * (using the device extended address) is done to get
                         * the pending data
                         */
#if (_DEBUG_ > 0)
                        status =
#endif
                            mac_build_and_tx_data_req(false, true, 0, NULL, 0);


#if (_DEBUG_ > 0)
                        Assert(status == true);
#endif
                        return;
                    }
                }
            }
        }   /* (mac_pib.mac_AutoRequest) */
    }   /* (MAC_SCAN_IDLE == mac_scan_state) */
#endif /* (MAC_INDIRECT_DATA_BASIC == 1) && (MAC_SYNC_REQUEST == 1)) */
} /* mac_process_beacon_frame() */
Ejemplo n.º 3
0
/**
 * @brief Implements MLME-POLL.request
 *
 * This function handles an MLME-POLL.request primitive.
 * The MLME-POLL.request primitive is generated by the next
 * higher layer and issued to its MLME when data are to be
 * requested from a coordinator.
 *
 * @param m Pointer to the message
 */
void mlme_poll_request(uint8_t *m)
{
	/*
	 * Polling for data is only allowed, if the node
	 * 1) is not a PAN coordinator,
	 * 2) is not polling already, and
	 * 3) is not scanning.
	 */
	if (
		(MAC_POLL_IDLE == mac_poll_state) &&
#if (MAC_START_REQUEST_CONFIRM == 1)
		(MAC_PAN_COORD_STARTED != mac_state) &&
#endif  /* MAC_START_REQUEST_CONFIRM == 1) */
		(MAC_SCAN_IDLE == mac_scan_state)
		) {
		bool status;
		address_field_t coord_addr;

		/* Wake up radio first */
		mac_trx_wakeup();

		/*
		 * Extract the Coordinator address information from the Poll
		 * request.
		 * This is required later for building the proper destination
		 * address
		 * information in the data request frame.
		 */
		mlme_poll_req_t *msg
			= (mlme_poll_req_t *)BMM_BUFFER_POINTER((buffer_t
				*)m);

		{
			uint8_t data_req_addr_mode;

			if (msg->CoordAddrMode == FCF_SHORT_ADDR) {
				data_req_addr_mode = FCF_SHORT_ADDR;
				ADDR_COPY_DST_SRC_16(coord_addr.short_address,
						msg->CoordAddress);
			} else {
				data_req_addr_mode = FCF_LONG_ADDR;
				ADDR_COPY_DST_SRC_64(coord_addr.long_address,
						msg->CoordAddress);
			}

			/* Build and transmit data request frame due to explicit
			 * poll request */
			status = mac_build_and_tx_data_req(true,
					false,
					data_req_addr_mode,
					&coord_addr,
					msg->CoordPANId);
		}

		if (status) {
			/* Store the poll request buffer to give poll confirm */
			mac_conf_buf_ptr = m;
		} else {
			gen_mlme_poll_conf((buffer_t *)m,
					MAC_CHANNEL_ACCESS_FAILURE);
		}
	} else {
		gen_mlme_poll_conf((buffer_t *)m, MAC_CHANNEL_ACCESS_FAILURE);
	}
}
Ejemplo n.º 4
0
static void handle_remote_range_req_frame(uint8_t *curr_frame_ptr)
{
    /*
     * Store addresses for the ongoing transaction.
     * This is required for all cases, also for
     * erroneous cases.
     */
    /* This node is the Initiator. */
    range_param.InitiatorAddrSpec.AddrMode = mac_parse_data.dest_addr_mode;
    range_param.InitiatorAddrSpec.PANId = mac_parse_data.dest_panid;
    /* Long address also covers short address here. */
    ADDR_COPY_DST_SRC_64(range_param.InitiatorAddrSpec.Addr.long_address,
                         mac_parse_data.dest_addr.long_address);

    /* The transmitter of this frame is the Coordinator. */
    /*
     * Note: Setting the Coordinator address mode here to a value different from
     * zero actually indicates, that remote ranging is ongoing.
     */
    range_param.CoordinatorAddrSpec.AddrMode = mac_parse_data.src_addr_mode;
    range_param.CoordinatorAddrSpec.PANId = mac_parse_data.src_panid;
    /* Long address also covers short address here. */
    ADDR_COPY_DST_SRC_64(range_param.CoordinatorAddrSpec.Addr.long_address,
                         mac_parse_data.src_addr.long_address);

    if (RTB_ROLE_NONE != rtb_role)
    {
        /* Ranging is currently already ongoing, do nothing. */
    }
    else if (!rtb_pib.RangingEnabled)
    {
        /* Ranging is currently disabled, reject new request. */
        range_status.range_error = (range_error_t)RTB_UNSUPPORTED_RANGING;
        rtb_state = RTB_INIT_REMOTE_RANGE_CONF_FRAME;
        /*
         * The role needs to be updated even in error
         * case to  be able to properly release the
         * frame buffer after the transmission of the
         * Remote Range confirm frame back to the Coordinator.
         */
        rtb_role = RTB_ROLE_INITIATOR;

        /*
         * Reset the PMU average data since no valid PMU average data are available
         * at this stage.
         */
        reset_pmu_average_data();
    }
    else
    {
        uint8_t frame_len;

        /*
         * Generally ranging is allowed ...
         * Now check requested ranging parameters.
         */

        /* Read Frame length field. */
        frame_len = *curr_frame_ptr++;

        if (RTB_PROTOCOL_VERSION_01 == *curr_frame_ptr++)
        {
            uint8_t refl_addr_len = IE_REFLECTOR_ADDR_SPEC_LEN_MIN;

            /* Currently only one RTB Protocol Version is supported. */

            rtb_role = RTB_ROLE_INITIATOR;

            /*
            * Reset the PMU average data since no valid PMU average data are available
            * at this stage.
            */
            reset_pmu_average_data();

            /* Extract Reflector address information from the frame. */
            refl_addr_t *ra =
                (refl_addr_t *)curr_frame_ptr;

            range_param.ReflectorAddrSpec.AddrMode = ra->refl_addr_mode;
            range_param.ReflectorAddrSpec.PANId = ra->refl_pan_id;
            /* Long address also covers short address here. */

            if (ra->refl_addr_mode == FCF_SHORT_ADDR)
            {
                range_param.ReflectorAddrSpec.Addr.long_address = 0;
                ADDR_COPY_DST_SRC_16(range_param.ReflectorAddrSpec.Addr.short_address,
                                     ra->refl_addr.short_address);
            }
            else
            {
                ADDR_COPY_DST_SRC_64(range_param.ReflectorAddrSpec.Addr.long_address,
                                     ra->refl_addr.long_address);
                refl_addr_len += 6;
            }
            curr_frame_ptr += refl_addr_len;

            /* Check whether requested ranging method is supported. */
            if (RTB_TYPE == *curr_frame_ptr++)
            {
                range_param.method = RTB_TYPE;

                range_param_pmu.f_start = convert_byte_array_to_16_bit(curr_frame_ptr);
                curr_frame_ptr += 2;
                range_param_pmu.f_step = *curr_frame_ptr++;
                range_param_pmu.f_stop = convert_byte_array_to_16_bit(curr_frame_ptr);
                curr_frame_ptr += 2;
                /*
                 * Extract remote range capabilities from
                 * the Coordinator.
                 */
                range_param.remote_caps = *curr_frame_ptr++;
                if (range_param.remote_caps & PMU_REM_CAP_APPLY_MIN_DIST_THRSHLD)
                {
                    range_param_pmu.apply_min_dist_threshold = true;
                }
                else
                {
                    range_param_pmu.apply_min_dist_threshold = false;
                }

                /*
                 * The capabilities for the actual ranging
                 * are not taken from the Coordinator, but
                 * rather from the Initiator itself.
                 */
                SET_INITIATOR_CAPS(range_param.caps);

                /*
                 * Initialize the Ranging Transmit Power to be applied at the
                 * Initiator in case this parameter is not included properly
                 * in this frame.
                 */
                range_param.req_tx_power = rtb_pib.RangingTransmitPower;

                /* Check wether Requested Ranging Transmit Power IE is available. */
                if (frame_len == IE_PMU_RANGING_LEN +
                    refl_addr_len +
                    IE_REQ_RANGING_TX_POWER_LEN)
                {
                    /*
                     * Extract and set requested Ranging Transmit Power
                     * (if changed).
                     */
                    if (REQ_RANGING_TX_POWER_IE == *curr_frame_ptr++)
                    {
                        /* Overwrite Ranging Transmit Power. */
                        range_param.req_tx_power = *curr_frame_ptr++;
                    }
                }

                if (!pmu_check_pmu_params())
                {
                    /* Unsupported ranging parameters, reject new request. */
                    range_status.range_error = (range_error_t)RTB_INVALID_PARAMETER;
                    rtb_state = RTB_INIT_REMOTE_RANGE_CONF_FRAME;
                }
                else
                {
                    /*
                     * Proper Remote Range Request frame received,
                     * so continue as Initiator.
                     */
#if (RTB_TYPE == RTB_PMU_233R)
                    /* Prepare FEC measurement */
                    pmu_enable_fec_measurement();
#endif  /* (RTB_TYPE == RTB_PMU_233R) */

                    configure_ranging();

#ifndef RTB_WITHOUT_MAC
                    /*
                     * Block MAC from doing anything else than ranging
                     * until this procedure is finished.
                     */
                    MAKE_MAC_BUSY();
#endif  /* #ifndef RTB_WITHOUT_MAC */

                    /*
                     * Next a Range Request frame needs to be assembled to be
                     * transmitted to Reflector
                     */
                    range_status.range_error = RANGE_OK;
                    rtb_state = RTB_INIT_RANGE_REQ_FRAME;
                }
            }
            else
            {
                /* Unsupported ranging method, reject new request. */
                range_status.range_error = (range_error_t)RTB_UNSUPPORTED_METHOD;
                rtb_state = RTB_INIT_REMOTE_RANGE_CONF_FRAME;
            }
        }
        else    /* if (RTB_PROTOCOL_VERSION_01 == *curr_frame_ptr++) */
        {
            /* Unsupported RTB Protocol Version, reject new request. */
            range_status.range_error = (range_error_t)RTB_UNSUPPORTED_PROTOCOL;
            rtb_state = RTB_INIT_REMOTE_RANGE_CONF_FRAME;
        }
    }
}
Ejemplo n.º 5
0
static void handle_remote_range_conf_frame(uint8_t *curr_frame_ptr)
{
    if (RTB_ROLE_NONE == rtb_role)
    {
        /*
         * Only if the Coordinator is currently not
         * actively involved itself, the Remote-Range-Confirm
         * is handled, otherwise it is ignored, because this
         * would corrupt our current local ranging related
         * address information.
         */
        /* Set proper ranging address parameter. */
        /* Set received source address address as Initiator address. */
        range_param.InitiatorAddrSpec.AddrMode = mac_parse_data.src_addr_mode;
        range_param.InitiatorAddrSpec.PANId = mac_parse_data.src_panid;
        /* Long address also covers short address here. */
        ADDR_COPY_DST_SRC_64(range_param.InitiatorAddrSpec.Addr.long_address,
                             mac_parse_data.src_addr.long_address);

        refl_addr_t *ra = (refl_addr_t *)curr_frame_ptr;

        /*
         * Set Reflector address received in frame as
         * Reflector address.
         */
        range_param.ReflectorAddrSpec.PANId = ra->refl_pan_id;

        range_remote_answer_t *rra;

        if (ra->refl_addr_mode == FCF_SHORT_ADDR)
        {
            range_param.ReflectorAddrSpec.AddrMode = FCF_SHORT_ADDR;
            range_param.ReflectorAddrSpec.Addr.long_address = 0;    // Init long address first
            ADDR_COPY_DST_SRC_16(range_param.ReflectorAddrSpec.Addr.short_address,
                                 ra->refl_addr.short_address);
            rra = (range_remote_answer_t *)((uint8_t *) & (ra->refl_addr) + 2);
        }
        else
        {
            range_param.ReflectorAddrSpec.AddrMode = FCF_LONG_ADDR;
            ADDR_COPY_DST_SRC_64(range_param.ReflectorAddrSpec.Addr.long_address,
                                 ra->refl_addr.long_address);
            rra = (range_remote_answer_t *)((uint8_t *) & (ra->refl_addr) + 8);
        }

        if (RTB_SUCCESS == rra->status)
        {
            /* Remote ranging was successful. */
            /* Check Additional Results IE type. */
            if (NO_ADDITIONAL_RESULTS == rra->additional_result_ie)
            {
                /* Return remote range confirm. */
                range_gen_rtb_remote_range_conf(RTB_SUCCESS,
                                                rra->distance_cm,
                                                rra->dqf,
                                                0,
                                                NULL);
            }
            else if (ANT_DIV_MEAS_RESULTS == rra->additional_result_ie)
            {
                /* Return remote range confirm with measured values. */
                range_gen_rtb_remote_range_conf(RTB_SUCCESS,
                                                rra->distance_cm,
                                                rra->dqf,
                                                rra->additional_result_fields.
                                                prov_antenna_div_results.
                                                no_of_provided_meas_pairs,
                                                rra->additional_result_fields.
                                                prov_antenna_div_results.
                                                provided_meas_pairs);
            }
        }
        else
        {
            /* Ranging request is NOT accepted. */
            /* Return remote range confirm with error values. */
            range_gen_rtb_remote_range_conf(rra->range_reject_reason,
                                            INVALID_DISTANCE,
                                            DQF_ZERO,
                                            0,
                                            NULL);
        }

        /*
         * Note: range_exit() must not be called here;
         * The remote range confirm is just notified to the
         * application.
         */
    }
}
Ejemplo n.º 6
0
retval_t mlme_get(uint8_t attribute, pib_value_t *attribute_value)
#endif  /* (MAC_SECURITY_ZIP || MAC_SECURITY_2006)  */
{
	/*
	 * Variables indicates whether the transceiver has been woken up for
	 * setting a TAL PIB attribute.
	 */

	retval_t status = MAC_SUCCESS;

	switch (attribute) {
#if (MAC_ASSOCIATION_REQUEST_CONFIRM == 1)
	case macAssociatedPANCoord:
		attribute_value->pib_value_8bit
			= mac_pib.mac_AssociatedPANCoord;
		break;
#endif /* (MAC_ASSOCIATION_REQUEST_CONFIRM == 1) */

	case macMaxBE:
		attribute_value->pib_value_8bit = tal_pib.MaxBE;
		break;

#if ((MAC_INDIRECT_DATA_BASIC == 1) || defined(BEACON_SUPPORT))
	case macMaxFrameTotalWaitTime:
		memcpy(attribute_value,
				&mac_pib.mac_MaxFrameTotalWaitTime,
				sizeof(uint16_t));

		break;
#endif  /* ((MAC_INDIRECT_DATA_BASIC == 1) || defined(BEACON_SUPPORT)) */

	case macMaxFrameRetries:
		attribute_value->pib_value_8bit = tal_pib.MaxFrameRetries;
		break;

	case macResponseWaitTime:
		memcpy(attribute_value,
				&mac_pib.mac_ResponseWaitTime,
				sizeof(uint16_t));

		break;

	case macSecurityEnabled:
		attribute_value->pib_value_8bit = mac_pib.mac_SecurityEnabled;
		break;

	case phyCurrentPage:
		attribute_value->pib_value_8bit = tal_pib.CurrentPage;
		break;

	case phyMaxFrameDuration:
		memcpy(attribute_value, &tal_pib.MaxFrameDuration,
				sizeof(uint16_t));
		break;

	case phySHRDuration:
		attribute_value->pib_value_8bit = tal_pib.SHRDuration;
		break;

	case phySymbolsPerOctet:
		attribute_value->pib_value_8bit = tal_pib.SymbolsPerOctet;
		break;

	case macAutoRequest:
		attribute_value->pib_value_8bit = mac_pib.mac_AutoRequest;
		break;

#ifdef BEACON_SUPPORT
	case macBattLifeExt:
		attribute_value->pib_value_8bit = tal_pib.BattLifeExt;
		break;

	case macBattLifeExtPeriods:
		attribute_value->pib_value_8bit
			= mac_pib.mac_BattLifeExtPeriods;
		break;

	case macBeaconTxTime:
		memcpy(attribute_value,
				&tal_pib.BeaconTxTime,
				sizeof(uint32_t));
		break;

	case macBeaconOrder:
		attribute_value->pib_value_8bit = tal_pib.BeaconOrder;
		break;

	case macSuperframeOrder:
		attribute_value->pib_value_8bit = tal_pib.SuperFrameOrder;
		break;
#endif  /* BEACON_SUPPORT */

#if (MAC_ASSOCIATION_INDICATION_RESPONSE == 1)
	case macAssociationPermit:
		attribute_value->pib_value_8bit = mac_pib.mac_AssociationPermit;
		break;
#endif /* (MAC_ASSOCIATION_INDICATION_RESPONSE == 1) */

#if (MAC_START_REQUEST_CONFIRM == 1)
	case macBeaconPayload:
		memcpy(attribute_value,
				mac_beacon_payload,
				mac_pib.mac_BeaconPayloadLength);
		break;

	case macBeaconPayloadLength:
		attribute_value->pib_value_8bit
			= mac_pib.mac_BeaconPayloadLength;
		break;

	case macBSN:
		attribute_value->pib_value_8bit = mac_pib.mac_BSN;
		break;
#endif  /* (MAC_START_REQUEST_CONFIRM == 1) */

#if (MAC_INDIRECT_DATA_FFD == 1)
	case macTransactionPersistenceTime:
		memcpy(attribute_value,
				&mac_pib.mac_TransactionPersistenceTime,
				sizeof(uint16_t));
		break;
#endif /* (MAC_INDIRECT_DATA_FFD == 1) */

#ifdef PROMISCUOUS_MODE
	case macPromiscuousMode:
		attribute_value->pib_value_8bit = tal_pib.PromiscuousMode;
		break;
#endif  /* PROMISCUOUS_MODE */

	case macCoordExtendedAddress:
		memcpy(attribute_value,
				&mac_pib.mac_CoordExtendedAddress,
				sizeof(uint64_t));
		break;

	case macCoordShortAddress:
		memcpy(attribute_value,
				&mac_pib.mac_CoordShortAddress,
				sizeof(uint16_t));
		break;

	case macDSN:
		attribute_value->pib_value_8bit = mac_pib.mac_DSN;
		break;

	case macMaxCSMABackoffs:
		attribute_value->pib_value_8bit = tal_pib.MaxCSMABackoffs;
		break;

	case macMinBE:
		attribute_value->pib_value_8bit = tal_pib.MinBE;
		break;

	case macPANId:
		memcpy(attribute_value,
				&tal_pib.PANId,
				sizeof(uint16_t));
		break;

	case macRxOnWhenIdle:
		attribute_value->pib_value_8bit = mac_pib.mac_RxOnWhenIdle;
		break;

	case macShortAddress:
		memcpy(attribute_value,
				&tal_pib.ShortAddress,
				sizeof(uint16_t));
		break;

	case macIeeeAddress:
		memcpy(attribute_value,
				&tal_pib.IeeeAddress,
				sizeof(uint64_t));
		break;

	case phyCurrentChannel:
		attribute_value->pib_value_8bit = tal_pib.CurrentChannel;
		break;

	case phyChannelsSupported:
		memcpy(attribute_value,
				&tal_pib.SupportedChannels,
				sizeof(uint32_t));
		break;

	case phyTransmitPower:
		attribute_value->pib_value_8bit = tal_pib.TransmitPower;
		break;

	case phyCCAMode:
		attribute_value->pib_value_8bit = tal_pib.CCAMode;
		break;

	default:
		status = MAC_UNSUPPORTED_ATTRIBUTE;
		break;

#if ((defined MAC_SECURITY_ZIP)  || (defined MAC_SECURITY_2006))
	case macKeyTable:
		if (attribute_index >= mac_sec_pib.KeyTableEntries) {
			status = MAC_INVALID_INDEX;
		} else {
			memcpy(attribute_value,
					&mac_sec_pib.KeyTable[attribute_index],
					sizeof(mac_key_table_t));
		}

		break;

	case macKeyTableEntries:
		attribute_value->pib_value_8bit = mac_sec_pib.KeyTableEntries;
		break;

	case macDeviceTable:
		if (attribute_index >= mac_sec_pib.DeviceTableEntries) {
			status = MAC_INVALID_INDEX;
		} else {
			/*
			 * Since the members of the mac_dev_table_t structure do
			 * contain padding bytes,
			 * each member needs to be filled in separately.
			 */
			uint8_t *attribute_temp_ptr
				= (uint8_t *)attribute_value;

			/*
			 * Since the members of the mac_dev_table_t structure do
			 * contain padding bytes,
			 * each member needs to be filled in separately.
			 */
			/* PAN-Id */
			ADDR_COPY_DST_SRC_16(*(uint16_t *)attribute_temp_ptr,
					mac_sec_pib.DeviceTable[attribute_index].DeviceDescriptor[
						0].PANId);
			attribute_temp_ptr += sizeof(uint16_t);

			/* Short Address */
			ADDR_COPY_DST_SRC_16(*(uint16_t *)attribute_temp_ptr,
					mac_sec_pib.DeviceTable[attribute_index].DeviceDescriptor[
						0].ShortAddress);
			attribute_temp_ptr += sizeof(uint16_t);

			/* Extended Address */
			ADDR_COPY_DST_SRC_64(*(uint64_t *)attribute_temp_ptr,
					mac_sec_pib.DeviceTable[attribute_index].DeviceDescriptor[
						0].ExtAddress);
			attribute_temp_ptr += sizeof(uint64_t);

			/* Extended Address */
			memcpy(attribute_temp_ptr,
					&mac_sec_pib.DeviceTable[attribute_index].DeviceDescriptor[
						0].FrameCounter,
					sizeof(uint32_t));
			attribute_temp_ptr += sizeof(uint32_t);

			/* Exempt */
			*attribute_temp_ptr
				= mac_sec_pib.DeviceTable[attribute_index
					].DeviceDescriptor[0].Exempt;
		}

		break;

	case macDeviceTableEntries:
		MEMCPY_ENDIAN(&attribute_value->pib_value_16bit,
				&mac_sec_pib.DeviceTableEntries, 2);
		break;

	case macSecurityLevelTable:
		if (attribute_index >= mac_sec_pib.SecurityLevelTableEntries) {
			status = MAC_INVALID_INDEX;
		} else {
			memcpy(attribute_value,
					&mac_sec_pib.SecurityLevelTable[
						attribute_index],
					sizeof(mac_sec_lvl_table_t));
		}

		break;

	case macSecurityLevelTableEntries:
		attribute_value->pib_value_8bit
			= mac_sec_pib.SecurityLevelTableEntries;
		break;

	case macFrameCounter:
		memcpy(attribute_value,
				&mac_sec_pib.FrameCounter,
				sizeof(uint32_t));
		break;

	case macDefaultKeySource:
		/* Key Source length is 8 octets. */
		memcpy(attribute_value, mac_sec_pib.DefaultKeySource, 8);
		break;
#endif /* (MAC_SECURITY_ZIP || MAC_SECURITY_2006) */

#ifdef TEST_HARNESS

	/*
	 * The following PIB attributes are privately used for special
	 * test scenarios and are not part of the product code path
	 */
	case macPrivateIllegalFrameType:
		attribute_value->pib_value_8bit
			= mac_pib.privateIllegalFrameType;
		break;

	case macPrivateMACState:
		attribute_value->pib_value_8bit = mac_state;
		break;

	case macPrivateNoDataAfterAssocReq:
		attribute_value->pib_value_8bit
			= mac_pib.privateNoDataAfterAssocReq;
		break;

	case macPrivateVirtualPANs:
		attribute_value->pib_value_8bit = mac_pib.privateVirtualPANs;
		break;

	case macPrivateMACSyncState:
		attribute_value->pib_value_8bit = mac_sync_state;
		break;
#endif /* TEST_HARNESS */
	}
	return status;
}
Ejemplo n.º 7
0
retval_t mlme_set(uint8_t attribute, pib_value_t *attribute_value, bool set_trx_to_sleep)
#endif
{
    /*
     * Variables indicates whether the transceiver has been woken up for
     * setting a TAL PIB attribute.
     */
    static bool trx_pib_wakeup;

    retval_t status = MAC_SUCCESS;

    switch (attribute)
    {
#if (MAC_ASSOCIATION_REQUEST_CONFIRM == 1)
        case macAssociatedPANCoord:
            mac_pib.mac_AssociatedPANCoord = attribute_value->pib_value_8bit;
            break;
#endif /* (MAC_ASSOCIATION_REQUEST_CONFIRM == 1) */

#if ((MAC_INDIRECT_DATA_BASIC == 1) || defined(BEACON_SUPPORT))
        case macMaxFrameTotalWaitTime:
            mac_pib.mac_MaxFrameTotalWaitTime = attribute_value->pib_value_16bit;
            break;
#endif  /* ((MAC_INDIRECT_DATA_BASIC == 1) || defined(BEACON_SUPPORT)) */

        case macResponseWaitTime:
            mac_pib.mac_ResponseWaitTime = attribute_value->pib_value_16bit;
            break;

        case macAutoRequest:
#if (MAC_BEACON_NOTIFY_INDICATION == 1)
            /*
             * If the beacon notification indications are not included
             * in the build, macAutoRequest can be changed as desired, since
             * beacon frames will be indicated to the higher
             * layer if required as defined by IEEE 802.15.4.
             */
            mac_pib.mac_AutoRequest = attribute_value->pib_value_8bit;
            break;
#else
            /*
             * If the beacon notification indications are not included
             * in the build, macAutoRequest must not be changed, since
             * beacon frames will never be indicated to the higher
             * layer, i.e. the higher would not be able to act on
             * received beacon frame information itself.
             */
            status = MAC_INVALID_PARAMETER;
            break;
#endif  /* (MAC_BEACON_NOTIFY_INDICATION == 1) */

        case macBattLifeExtPeriods:
            mac_pib.mac_BattLifeExtPeriods = attribute_value->pib_value_8bit;
            break;

#if (MAC_ASSOCIATION_INDICATION_RESPONSE == 1)
        case macAssociationPermit:
            mac_pib.mac_AssociationPermit = attribute_value->pib_value_8bit;
            break;
#endif /* (MAC_ASSOCIATION_INDICATION_RESPONSE == 1) */

#if (MAC_START_REQUEST_CONFIRM == 1)
        case macBeaconPayload:
            memcpy(mac_beacon_payload, attribute_value,
                   mac_pib.mac_BeaconPayloadLength);
            break;

        case macBeaconPayloadLength:
#ifndef REDUCED_PARAM_CHECK
            /*
             * If the application sits directly  on top of the MAC,
             * this is also checked in mac_api.c.
             */
            if (attribute_value->pib_value_8bit > aMaxBeaconPayloadLength)
            {
                status = MAC_INVALID_PARAMETER;
                break;
            }
#endif  /* REDUCED_PARAM_CHECK */
            mac_pib.mac_BeaconPayloadLength = attribute_value->pib_value_8bit;
            break;

        case macBSN:
            mac_pib.mac_BSN = attribute_value->pib_value_8bit;
            break;
#endif  /* (MAC_START_REQUEST_CONFIRM == 1) */

#if (MAC_INDIRECT_DATA_FFD == 1)
         case macTransactionPersistenceTime:
            mac_pib.mac_TransactionPersistenceTime = attribute_value->pib_value_16bit;
            break;
#endif /* (MAC_INDIRECT_DATA_FFD == 1) */
            case macCoordExtendedAddress:
            mac_pib.mac_CoordExtendedAddress = attribute_value->pib_value_64bit;
            break;

        case macCoordShortAddress:
            mac_pib.mac_CoordShortAddress = attribute_value->pib_value_16bit;
            break;

        case macDSN:
            mac_pib.mac_DSN = attribute_value->pib_value_8bit;
            break;

        case macRxOnWhenIdle:
            mac_pib.mac_RxOnWhenIdle = attribute_value->pib_value_8bit;
            /* Check whether radio state needs to change now, */
            if (mac_pib.mac_RxOnWhenIdle)
            {
                /* Check whether the radio needs to be woken up. */
                mac_trx_wakeup();
                /* Set transceiver in rx mode, otherwise it may stay in TRX_OFF). */
                tal_rx_enable(PHY_RX_ON);
            }
            else
            {
                /* Check whether the radio needs to be put to sleep. */
                mac_sleep_trans();
            }
            break;

        case macBattLifeExt:
        case macBeaconOrder:
        case macMaxCSMABackoffs:
        case macMaxBE:
        case macMaxFrameRetries:
        case macMinBE:
        case macPANId:
#ifdef PROMISCUOUS_MODE
        case macPromiscuousMode:
#endif/* PROMISCUOUS_MODE */
        case macShortAddress:
        case macSuperframeOrder:
        case macIeeeAddress:
        case phyCurrentChannel:
        case phyCurrentPage:
        case phyTransmitPower:
        case phyCCAMode:
#ifdef TEST_HARNESS
        case macPrivateCCAFailure:
        case macPrivateDisableACK:
#endif /* TEST_HARNESS */
            {
                /* Now only TAL PIB attributes are handled anymore. */
                status = tal_pib_set(attribute, attribute_value);

                if (status == TAL_TRX_ASLEEP)
                {
                    /*
                     * Wake up the transceiver and repeat the attempt
                     * to set the TAL PIB attribute.
                     */
                    tal_trx_wakeup();
                    status = tal_pib_set(attribute, attribute_value);
                    if (status == MAC_SUCCESS)
                    {
                        /*
                         * Set flag indicating that the trx has been woken up
                         * during PIB setting.
                         */
                        trx_pib_wakeup = true;
                    }
               }

#if ((MAC_INDIRECT_DATA_BASIC == 1) || defined(BEACON_SUPPORT))
               /*
                * In any case that the PIB setting was successful (no matter
                * whether the trx had to be woken up or not), the PIB attribute
                * recalculation needs to be done.
                */
               if (status == MAC_SUCCESS)
               {
                   /*
                    * The value of the PIB attribute
                    * macMaxFrameTotalWaitTime depends on the values of the
                    * following PIB attributes:
                    * macMinBE
                    * macMaxBE
                    * macMaxCSMABackoffs
                    * phyMaxFrameDuration
                    * In order to save code space and since changing of PIB
                    * attributes is going to happen not too often, this is done
                    * always whenever a PIB attribute residing in TAL is changed
                    * (since all above mentioned PIB attributes are in TAL).
                    */
                   recalc_macMaxFrameTotalWaitTime();
               }
#endif  /* ((MAC_INDIRECT_DATA_BASIC == 1) || defined(BEACON_SUPPORT)) */
            }
            break;

        case macAckWaitDuration:
        default:
            status = MAC_UNSUPPORTED_ATTRIBUTE;
            break;

#ifdef MAC_SECURITY_ZIP
        case macSecurityEnabled:
            mac_pib.mac_SecurityEnabled = attribute_value->pib_value_8bit;
            break;

        case macKeyTable:
            if (attribute_index >= mac_sec_pib.KeyTableEntries)
            {
                status = MAC_INVALID_INDEX;
            }
            else
            {
                memcpy(&mac_sec_pib.KeyTable[attribute_index],
                       attribute_value,
                       sizeof(mac_key_table_t));
            }
            break;

        case macKeyTableEntries:
            if (attribute_value->pib_value_8bit > MAC_ZIP_MAX_KEY_TABLE_ENTRIES)
            {
                status = MAC_INVALID_PARAMETER;
            }
            else
            {
            mac_sec_pib.KeyTableEntries = attribute_value->pib_value_8bit;
            }
            break;

        case macDeviceTable:
            if (attribute_index >= mac_sec_pib.DeviceTableEntries)
            {
                status = MAC_INVALID_INDEX;
            }
            else
            {
                uint8_t *attribute_temp_ptr = (uint8_t *)attribute_value;
                /*
                 * Since the members of the mac_dev_table_t structure do contain padding bytes,
                 * each member needs to be filled in separately.
                 */
                /* PAN-Id */
                ADDR_COPY_DST_SRC_16(mac_sec_pib.DeviceTable[attribute_index].DeviceDescriptor[0].PANId,
                                     *(uint16_t *)attribute_temp_ptr);
                attribute_temp_ptr += sizeof(uint16_t);

                /* Short Address */
                ADDR_COPY_DST_SRC_16(mac_sec_pib.DeviceTable[attribute_index].DeviceDescriptor[0].ShortAddress,
                                     *(uint16_t *)attribute_temp_ptr);
                attribute_temp_ptr += sizeof(uint16_t);

                /* Extended Address */
                ADDR_COPY_DST_SRC_64(mac_sec_pib.DeviceTable[attribute_index].DeviceDescriptor[0].ExtAddress,
                                     *(uint64_t *)attribute_temp_ptr);
                attribute_temp_ptr += sizeof(uint64_t);

                /* Extended Address */
                memcpy(&mac_sec_pib.DeviceTable[attribute_index].DeviceDescriptor[0].FrameCounter,
                       attribute_temp_ptr,
                       sizeof(uint32_t));
                attribute_temp_ptr += sizeof(uint32_t);

                /* Exempt */
                mac_sec_pib.DeviceTable[attribute_index].DeviceDescriptor[0].Exempt = *attribute_temp_ptr;
            }
            break;

        case macDeviceTableEntries:
            if (attribute_value->pib_value_8bit > MAC_ZIP_MAX_DEV_TABLE_ENTRIES)
            {
                status = MAC_INVALID_PARAMETER;
            }
            else
            {
            mac_sec_pib.DeviceTableEntries = attribute_value->pib_value_8bit;
            }
            break;

        case macSecurityLevelTable:
            if (attribute_index >= mac_sec_pib.SecurityLevelTableEntries)
            {
                status = MAC_INVALID_INDEX;
            }
            else
            {
                memcpy(&mac_sec_pib.SecurityLevelTable[attribute_index],
                       attribute_value,
                       sizeof(mac_sec_lvl_table_t));
            }
            break;

        case macSecurityLevelTableEntries:
            if (attribute_value->pib_value_8bit > MAC_ZIP_MAX_SEC_LVL_TABLE_ENTRIES)
            {
                status = MAC_INVALID_PARAMETER;
            }
            else
            {
            mac_sec_pib.SecurityLevelTableEntries = attribute_value->pib_value_8bit;
            }
            break;

        case macFrameCounter:
            mac_sec_pib.FrameCounter = attribute_value->pib_value_32bit;
            break;

        case macDefaultKeySource:
            /* Key Source length is 8 octets. */
            memcpy(mac_sec_pib.DefaultKeySource, attribute_value, 8);
            break;

#endif  /* MAC_SECURITY_ZIP */

#ifdef TEST_HARNESS
        case macPrivateIllegalFrameType:
            mac_pib.privateIllegalFrameType = attribute_value->pib_value_8bit;
            break;

        case macPrivateNoDataAfterAssocReq:
            mac_pib.privateNoDataAfterAssocReq = attribute_value->pib_value_8bit;
            break;

        case macPrivateVirtualPANs:
            mac_pib.privateVirtualPANs = attribute_value->pib_value_8bit;
            break;
#endif /* TEST_HARNESS */
    }

    /*
     * In case the transceiver shall be forced back to sleep and
     * has been woken up, it is put back to sleep again.
     */
    if (set_trx_to_sleep && trx_pib_wakeup && !mac_pib.mac_RxOnWhenIdle)
    {
#ifdef ENABLE_DEEP_SLEEP
        tal_trx_sleep(DEEP_SLEEP_MODE);
#else
        tal_trx_sleep(SLEEP_MODE_1);
#endif
        trx_pib_wakeup = false;
    }

    return status;
}
Ejemplo n.º 8
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);
#ifdef MAC_SECURITY_ZIP
    uint8_t attribute_index = ((mlme_get_req_t *)mgc)->PIBAttributeIndex;
#endif /* MAC_SECURITY_ZIP */

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

        switch (((mlme_get_req_t *)mgc)->PIBAttribute)
        {
#if (MAC_ASSOCIATION_REQUEST_CONFIRM == 1)
            case macAssociatedPANCoord:
                attribute_value->pib_value_8bit = mac_pib.mac_AssociatedPANCoord;
                break;
#endif /* (MAC_ASSOCIATION_REQUEST_CONFIRM == 1) */

            case macMaxBE:
                attribute_value->pib_value_8bit = tal_pib.MaxBE;
                break;

#if ((MAC_INDIRECT_DATA_BASIC == 1) || defined(BEACON_SUPPORT))
            case macMaxFrameTotalWaitTime:
                memcpy(attribute_value,
                       &mac_pib.mac_MaxFrameTotalWaitTime,
                       sizeof(uint16_t));


                break;
#endif  /* ((MAC_INDIRECT_DATA_BASIC == 1) || defined(BEACON_SUPPORT)) */

            case macMaxFrameRetries:
                attribute_value->pib_value_8bit = tal_pib.MaxFrameRetries;
                break;

            case macResponseWaitTime:
                memcpy(attribute_value,
                       &mac_pib.mac_ResponseWaitTime,
                       sizeof(uint16_t));

                break;

            case macSecurityEnabled:
                attribute_value->pib_value_8bit = mac_pib.mac_SecurityEnabled;
                break;

            case phyCurrentPage:
                attribute_value->pib_value_8bit = tal_pib.CurrentPage;
                break;

            case phyMaxFrameDuration:
                memcpy(attribute_value, &tal_pib.MaxFrameDuration,
                       sizeof(uint16_t));
                break;

            case phySHRDuration:
                attribute_value->pib_value_8bit = tal_pib.SHRDuration;
                break;

            case phySymbolsPerOctet:
                attribute_value->pib_value_8bit = tal_pib.SymbolsPerOctet;
                break;

            case macAutoRequest:
                attribute_value->pib_value_8bit = mac_pib.mac_AutoRequest;
                break;

#ifdef BEACON_SUPPORT
            case macBattLifeExt:
                attribute_value->pib_value_8bit = tal_pib.BattLifeExt;
                break;

            case macBattLifeExtPeriods:
                attribute_value->pib_value_8bit = mac_pib.mac_BattLifeExtPeriods;
                break;

            case macBeaconTxTime:
                memcpy(attribute_value,
                       &tal_pib.BeaconTxTime,
                       sizeof(uint32_t));
                break;

            case macBeaconOrder:
                attribute_value->pib_value_8bit = tal_pib.BeaconOrder;
                break;

            case macSuperframeOrder:
                attribute_value->pib_value_8bit = tal_pib.SuperFrameOrder;
                break;
#endif  /* BEACON_SUPPORT */

#if (MAC_ASSOCIATION_INDICATION_RESPONSE == 1)
            case macAssociationPermit:
                attribute_value->pib_value_8bit = mac_pib.mac_AssociationPermit;
                break;
#endif /* (MAC_ASSOCIATION_INDICATION_RESPONSE == 1) */

#if (MAC_START_REQUEST_CONFIRM == 1)
            case macBeaconPayload:
                memcpy(attribute_value,
                       mac_beacon_payload,
                       mac_pib.mac_BeaconPayloadLength);
                break;

            case macBeaconPayloadLength:
                attribute_value->pib_value_8bit = mac_pib.mac_BeaconPayloadLength;
                break;

            case macBSN:
                attribute_value->pib_value_8bit = mac_pib.mac_BSN;
                break;
#endif  /* (MAC_START_REQUEST_CONFIRM == 1) */

#if (MAC_INDIRECT_DATA_FFD == 1)
            case macTransactionPersistenceTime:
                memcpy(attribute_value,
                       &mac_pib.mac_TransactionPersistenceTime,
                       sizeof(uint16_t));
                break;
#endif /* (MAC_INDIRECT_DATA_FFD == 1) */

#ifdef PROMISCUOUS_MODE
            case macPromiscuousMode:
                attribute_value->pib_value_8bit = tal_pib.PromiscuousMode;
                break;
#endif  /* PROMISCUOUS_MODE */

            case macCoordExtendedAddress:
                memcpy(attribute_value,
                       &mac_pib.mac_CoordExtendedAddress,
                       sizeof(uint64_t));
                break;

            case macCoordShortAddress:
                memcpy(attribute_value,
                       &mac_pib.mac_CoordShortAddress,
                       sizeof(uint16_t));
                break;

            case macDSN:
                attribute_value->pib_value_8bit = mac_pib.mac_DSN;
                break;

            case macMaxCSMABackoffs:
                attribute_value->pib_value_8bit = tal_pib.MaxCSMABackoffs;
                break;

            case macMinBE:
                attribute_value->pib_value_8bit = tal_pib.MinBE;
                break;

            case macPANId:
                memcpy(attribute_value,
                       &tal_pib.PANId,
                       sizeof(uint16_t));
                break;

            case macRxOnWhenIdle:
                attribute_value->pib_value_8bit = mac_pib.mac_RxOnWhenIdle;
                break;

            case macShortAddress:
                memcpy(attribute_value,
                       &tal_pib.ShortAddress,
                       sizeof(uint16_t));
                break;

            case macIeeeAddress:
                memcpy(attribute_value,
                       &tal_pib.IeeeAddress,
                       sizeof(uint64_t));
                break;

            case phyCurrentChannel:
                attribute_value->pib_value_8bit = tal_pib.CurrentChannel;
                break;

            case phyChannelsSupported:
                memcpy(attribute_value,
                       &tal_pib.SupportedChannels,
                       sizeof(uint32_t));
                break;

            case phyTransmitPower:
                attribute_value->pib_value_8bit = tal_pib.TransmitPower;
                break;

            case phyCCAMode:
                attribute_value->pib_value_8bit = tal_pib.CCAMode;
                break;

            default:
                status = MAC_UNSUPPORTED_ATTRIBUTE;
                break;

#ifdef MAC_SECURITY_ZIP
            case macKeyTable:
                if (attribute_index >= mac_sec_pib.KeyTableEntries)
                {
                    status = MAC_INVALID_INDEX;
                }
                else
                {
                memcpy(attribute_value,
                           &mac_sec_pib.KeyTable[attribute_index],
                       sizeof(mac_key_table_t));
                }
                break;

            case macKeyTableEntries:
                attribute_value->pib_value_8bit = mac_sec_pib.KeyTableEntries;
                break;

            case macDeviceTable:
                if (attribute_index >= mac_sec_pib.DeviceTableEntries)
                {
                    status = MAC_INVALID_INDEX;
                }
                else
                {
                    /*
                     * Since the members of the mac_dev_table_t structure do contain padding bytes,
                     * each member needs to be filled in separately.
                     */
                    uint8_t *attribute_temp_ptr = (uint8_t *)attribute_value;
                    /*
                     * Since the members of the mac_dev_table_t structure do contain padding bytes,
                     * each member needs to be filled in separately.
                     */
                    /* PAN-Id */
                    ADDR_COPY_DST_SRC_16(*(uint16_t *)attribute_temp_ptr,
                                         mac_sec_pib.DeviceTable[attribute_index].DeviceDescriptor[0].PANId);
                    attribute_temp_ptr += sizeof(uint16_t);

                    /* Short Address */
                    ADDR_COPY_DST_SRC_16(*(uint16_t *)attribute_temp_ptr,
                                         mac_sec_pib.DeviceTable[attribute_index].DeviceDescriptor[0].ShortAddress);
                    attribute_temp_ptr += sizeof(uint16_t);

                    /* Extended Address */
                    ADDR_COPY_DST_SRC_64(*(uint64_t *)attribute_temp_ptr,
                                         mac_sec_pib.DeviceTable[attribute_index].DeviceDescriptor[0].ExtAddress);
                    attribute_temp_ptr += sizeof(uint64_t);

                    /* Extended Address */
                    memcpy(attribute_temp_ptr,
                           &mac_sec_pib.DeviceTable[attribute_index].DeviceDescriptor[0].FrameCounter,
                           sizeof(uint32_t));
                    attribute_temp_ptr += sizeof(uint32_t);

                    /* Exempt */
                    *attribute_temp_ptr = mac_sec_pib.DeviceTable[attribute_index].DeviceDescriptor[0].Exempt;
                }
                break;

            case macDeviceTableEntries:
                attribute_value->pib_value_8bit = mac_sec_pib.DeviceTableEntries;
                break;

            case macSecurityLevelTable:
                if (attribute_index >= mac_sec_pib.SecurityLevelTableEntries)
                {
                    status = MAC_INVALID_INDEX;
                }
                else
                {
                memcpy(attribute_value,
                           &mac_sec_pib.SecurityLevelTable[attribute_index],
                       sizeof(mac_sec_lvl_table_t));
                }
                break;

            case macSecurityLevelTableEntries:
                attribute_value->pib_value_8bit = mac_sec_pib.SecurityLevelTableEntries;
                break;

            case macFrameCounter:
                memcpy(attribute_value,
                       &mac_sec_pib.FrameCounter,
                       sizeof(uint32_t));
                break;

            case macDefaultKeySource:
                /* Key Source length is 8 octets. */
                memcpy(attribute_value, mac_sec_pib.DefaultKeySource, 8);
                break;

#endif  /* MAC_SECURITY_ZIP */

#ifdef TEST_HARNESS
                /*
                 * The following PIB attributes are privately used for special
                 * test scenarios and are not part of the product code path
                 */
            case macPrivateIllegalFrameType:
                attribute_value->pib_value_8bit = mac_pib.privateIllegalFrameType;
                break;

            case macPrivateMACState:
                attribute_value->pib_value_8bit = mac_state;
                break;

            case macPrivateNoDataAfterAssocReq:
                attribute_value->pib_value_8bit = mac_pib.privateNoDataAfterAssocReq;
                break;

            case macPrivateVirtualPANs:
                attribute_value->pib_value_8bit = mac_pib.privateVirtualPANs;
                break;

            case macPrivateMACSyncState:
                attribute_value->pib_value_8bit = mac_sync_state;
                break;
#endif /* TEST_HARNESS */
        }

        mgc->PIBAttribute = ((mlme_get_req_t *)mgc)->PIBAttribute;
#ifdef MAC_SECURITY_ZIP
        mgc->PIBAttributeIndex = attribute_index;
#endif  /* MAC_SECURITY_ZIP */
        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);
}