/** * @brief The MLME-START.request primitive makes a request for the device to * start using a new superframe configuration * * @param m Pointer to MLME_START.request message issued by the NHLE */ void mlme_start_request(uint8_t *m) { mlme_start_req_t *msg = (mlme_start_req_t *)BMM_BUFFER_POINTER((buffer_t *)m); /* * The MLME_START.request parameters are copied into a global variable * structure, which is used by check_start_parameter() function. */ memcpy(&msr_params, msg, sizeof(msr_params)); if (BROADCAST == tal_pib.ShortAddress) { /* * The device is void of short address. This device cannot start a * network, hence a confirmation is given back. */ gen_mlme_start_conf((buffer_t *)m, MAC_NO_SHORT_ADDRESS); return; } #ifndef REDUCED_PARAM_CHECK if (!check_start_parameter(msg)) { /* * The MLME_START.request parameters are invalid, hence confirmation * is given to NHLE. */ gen_mlme_start_conf((buffer_t *)m, MAC_INVALID_PARAMETER); } else #endif /* REDUCED_PARAM_CHECK */ { /* * All the start parameters are valid, hence MLME_START.request can * proceed. */ set_tal_pib_internal(mac_i_pan_coordinator, (void *)&(msg->PANCoordinator)); if (msr_params.CoordRealignment) { /* First inform our devices of the configuration change */ if (!mac_tx_coord_realignment_command(COORDINATORREALIGNMENT, (buffer_t *)m, msr_params.PANId, msr_params.LogicalChannel, msr_params.ChannelPage)) { /* * The coordinator realignment command was unsuccessful, * hence the confiramtion is given to NHLE. */ gen_mlme_start_conf((buffer_t *)m, MAC_INVALID_PARAMETER); } } else { /* This is a normal MLME_START.request. */ retval_t channel_set_status, channel_page_set_status; /* The new PIBs are set at the TAL. */ set_tal_pib_internal(macBeaconOrder, (void *)&(msg->BeaconOrder)); /* If macBeaconOrder is equal to 15, set also macSuperframeOrder to 15. */ if (msg->BeaconOrder == NON_BEACON_NWK) { msg->SuperframeOrder = NON_BEACON_NWK; } set_tal_pib_internal(macSuperframeOrder, (void *)&(msg->SuperframeOrder)); #ifdef BEACON_SUPPORT /* * Symbol times are calculated according to the new BO and SO * values. */ if (tal_pib.BeaconOrder < NON_BEACON_NWK) { set_tal_pib_internal(macBattLifeExt, (void *)&(msr_params.BatteryLifeExtension)); } #endif /* BEACON_SUPPORT */ /* Wake up radio first */ mac_trx_wakeup(); /* MLME_START.request parameters other than BO and SO are set at TAL */ set_tal_pib_internal(macPANId, (void *)&(msr_params.PANId)); channel_page_set_status = set_tal_pib_internal(phyCurrentPage, (void *)&(msr_params.ChannelPage)); channel_set_status = set_tal_pib_internal(phyCurrentChannel, (void *)&(msr_params.LogicalChannel)); set_tal_pib_internal(mac_i_pan_coordinator, (void *)&(msr_params.PANCoordinator)); if ((MAC_SUCCESS == channel_page_set_status) && (MAC_SUCCESS == channel_set_status) && (PHY_RX_ON == tal_rx_enable(PHY_RX_ON)) ) { if (msr_params.PANCoordinator) { mac_state = MAC_PAN_COORD_STARTED; } else { mac_state = MAC_COORDINATOR; } gen_mlme_start_conf((buffer_t *)m, MAC_SUCCESS); #ifdef BEACON_SUPPORT /* * In case we have a beaconing network, the beacon timer needs * to be started now. */ if (tal_pib.BeaconOrder != NON_BEACON_NWK) { mac_start_beacon_timer(); } #endif /* BEACON_SUPPORT */ } else { /* Start of network failed. */ gen_mlme_start_conf((buffer_t *)m, MAC_INVALID_PARAMETER); } /* Set radio to sleep if allowed */ mac_sleep_trans(); } } }
/* * @brief Set the transceiver state to PHY_TRX_OFF * * This actually turns the radio receiver off - i.e. this is the end * of the PHY_RX_ON period. * * @param callback_parameter Callback parameter */ static void mac_t_rx_off_cb(void *callback_parameter) { uint8_t status; /* * Rx is disabled. * This will make sure that the radio will be put to sleep in function * mac_sleep_trans(). */ mac_rx_enabled = false; /* * In case macRxOnWhenIdle is not set, the radio is put to PHY_TRX_OFF * state, until the return status does not match the desired radio * state, * i.e. PHY_TRX_OFF */ if (!mac_pib.mac_RxOnWhenIdle) { /* * In case the radio is awake, we need to switch RX off. */ if (RADIO_AWAKE == mac_radio_sleep_state) { status = tal_rx_enable(PHY_TRX_OFF); if (status != PHY_TRX_OFF) { /* * The TAL is still busy and cannot set the TRX * to OFF. * In order to get progress this requires * another * round of the TAL task being processed. * Therefore the MAC task needs to stopp here * and pass * controll back to the TAL. * This is reached by starting the Rx-Enable * timer again * for a very short time with the same callback * returning * here very soon. */ pal_timer_start(T_Rx_Enable, MIN_TIMEOUT, TIMEOUT_RELATIVE, (FUNC_PTR)mac_t_rx_off_cb, NULL); /* * Return now, since the TAL is still busy, so * radio cannot go * to sleep for now. */ return; } else { /* Set radio to sleep if allowed */ mac_sleep_trans(); } } } callback_parameter = callback_parameter; /* Keep compiler happy. */ }
/** * @brief Continues handling of MLME_START.request (Coordinator realignment) * command * * This function is called once the coordinator realignment command is * sent out to continue the handling of the MLME_START.request command. * * @param tx_status Status of the coordinator realignment command * transmission * @param buf_ptr Buffer for start confirmation */ void mac_coord_realignment_command_tx_success(uint8_t tx_status, buffer_t *buf_ptr) { uint8_t conf_status = MAC_INVALID_PARAMETER; retval_t channel_set_status, channel_page_set_status; if (MAC_SUCCESS == tx_status) { /* The parameters of the existing PAN are updated. */ channel_page_set_status = set_tal_pib_internal(phyCurrentPage, (void *)&(msr_params.ChannelPage)); #if (_DEBUG_ > 0) Assert(MAC_SUCCESS == channel_page_set_status); #endif channel_set_status = set_tal_pib_internal(phyCurrentChannel, (void *)&msr_params.LogicalChannel); #if (_DEBUG_ > 0) Assert(MAC_SUCCESS == channel_set_status); #endif if ((MAC_SUCCESS == channel_set_status) && (MAC_SUCCESS == channel_page_set_status)) { conf_status = MAC_SUCCESS; set_tal_pib_internal(macPANId, (void *)&(msr_params.PANId)); #ifdef BEACON_SUPPORT /* * Store current beacon order in order to be able to * detect * switching from nonbeacon to beacon network. */ uint8_t cur_beacon_order = tal_pib.BeaconOrder; set_tal_pib_internal(macBeaconOrder, (void *)&(msr_params.BeaconOrder)); set_tal_pib_internal(macSuperframeOrder, (void *)&(msr_params.SuperframeOrder)); /* * New symbol times for beacon time (in sysbols) and * inactive time are * calculated according to the new superframe * configuration. */ if (msr_params.BeaconOrder < NON_BEACON_NWK) { set_tal_pib_internal(macBattLifeExt, (void *)&(msr_params. BatteryLifeExtension)); } if ((NON_BEACON_NWK < cur_beacon_order) && (msr_params.BeaconOrder == NON_BEACON_NWK)) { /* * This is a transition from a beacon enabled * network to * a nonbeacon enabled network. * In this case the broadcast data queue will * never be served. * * Therefore the broadcast queue needs to be * emptied. * The standard does not define what to do now. * The current implementation will try to send * all pending broadcast * data frames immediately, thus giving the * receiving nodes a chance * receive them. */ while (broadcast_q.size > 0) { mac_tx_pending_bc_data(); } } if ((NON_BEACON_NWK == cur_beacon_order) && (msr_params.BeaconOrder < NON_BEACON_NWK)) { /* * This is a transition from a nonbeacon enabled * network to * a beacon enabled network, hence the beacon * timer will be * started. */ mac_start_beacon_timer(); } #endif /* BEACON_SUPPORT */ } } gen_mlme_start_conf(buf_ptr, conf_status); /* Set radio to sleep if allowed */ mac_sleep_trans(); } /* mac_coord_realignment_command_tx_success() */
/** * @brief Initializes the MAC sublayer * * @return MAC_SUCCESS if TAL is intialized successfully else FAILURE */ retval_t mac_init(void) { #ifdef GTS_DEBUG struct port_config config_port_pin; config_port_pin.direction = PORT_PIN_DIR_OUTPUT; port_pin_set_config(DEBUG_PIN1, &config_port_pin); port_pin_set_config(DEBUG_PIN2, &config_port_pin); port_pin_set_config(DEBUG_PIN3, &config_port_pin); port_pin_set_config(DEBUG_PIN4, &config_port_pin); port_pin_set_config(DEBUG_PIN5, &config_port_pin); port_pin_set_config(DEBUG_PIN6, &config_port_pin); port_pin_set_config(DEBUG_PIN7, &config_port_pin); port_pin_set_config(DEBUG_PIN8, &config_port_pin); port_pin_set_config(DEBUG_PIN9, &config_port_pin); port_pin_set_config(DEBUG_PIN10, &config_port_pin); port_pin_set_config(DEBUG_PIN11, &config_port_pin); port_pin_set_config(DEBUG_PIN12, &config_port_pin); port_pin_set_config(DEBUG_PIN13, &config_port_pin); port_pin_set_config(DEBUG_PIN14, &config_port_pin); port_pin_set_config(DEBUG_PIN15, &config_port_pin); /*ioport_configure_pin(DEBUG_PIN1, IOPORT_DIR_OUTPUT | * IOPORT_INIT_LOW); * ioport_configure_pin(DEBUG_PIN2, IOPORT_DIR_OUTPUT | * IOPORT_INIT_LOW); * ioport_configure_pin(DEBUG_PIN3, IOPORT_DIR_OUTPUT | * IOPORT_INIT_LOW); * ioport_configure_pin(DEBUG_PIN4, IOPORT_DIR_OUTPUT | * IOPORT_INIT_LOW);*/ #endif /* Initialize TAL */ if (tal_init() != MAC_SUCCESS) { return FAILURE; } #ifdef STB_ON_SAL stb_init(); #endif #ifdef ENABLE_RTB /* Initialize RTB */ if (rtb_init() != RTB_SUCCESS) { return FAILURE; } #endif /* ENABLE_RTB */ /* Calibrate MCU's RC oscillator */ if (!pal_calibrate_rc_osc()) { return FAILURE; } if (MAC_SUCCESS != mac_timers_init()) { return FAILURE; } mac_soft_reset(true); /* Set radio to sleep if allowed */ mac_sleep_trans(); /* Initialize the queues */ #ifdef ENABLE_QUEUE_CAPACITY qmm_queue_init(&nhle_mac_q, NHLE_MAC_QUEUE_CAPACITY); qmm_queue_init(&tal_mac_q, TAL_MAC_QUEUE_CAPACITY); #if (MAC_INDIRECT_DATA_FFD == 1) qmm_queue_init(&indirect_data_q, INDIRECT_DATA_QUEUE_CAPACITY); #endif /* (MAC_INDIRECT_DATA_FFD == 1) */ #if (MAC_START_REQUEST_CONFIRM == 1) #ifdef BEACON_SUPPORT qmm_queue_init(&broadcast_q, BROADCAST_QUEUE_CAPACITY); #endif /* BEACON_SUPPORT */ #endif /* (MAC_START_REQUEST_CONFIRM == 1) */ #else qmm_queue_init(&nhle_mac_q); qmm_queue_init(&tal_mac_q); #if (MAC_INDIRECT_DATA_FFD == 1) qmm_queue_init(&indirect_data_q); #endif /* (MAC_INDIRECT_DATA_FFD == 1) */ #if (MAC_START_REQUEST_CONFIRM == 1) #ifdef BEACON_SUPPORT qmm_queue_init(&broadcast_q); #endif /* BEACON_SUPPORT */ #endif /* (MAC_START_REQUEST_CONFIRM == 1) */ #endif /* ENABLE_QUEUE_CAPACITY */ return MAC_SUCCESS; }
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) */ #ifdef GTS_SUPPORT case macGTSPermit: mac_pib.mac_GTSPermit = attribute_value->pib_value_8bit; break; #endif /* GTS_SUPPORT */ 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; #if ((defined MAC_SECURITY_ZIP) || (defined MAC_SECURITY_2006)) 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 */ memcpy((uint8_t *)&mac_sec_pib.DeviceTable[ attribute_index].DeviceDescriptor[ 0].PANId, attribute_temp_ptr, sizeof(uint16_t)); /* * *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 */ memcpy((uint8_t *)&mac_sec_pib.DeviceTable[ attribute_index].DeviceDescriptor[ 0].ShortAddress, attribute_temp_ptr, sizeof(uint16_t)); /*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 */ memcpy((uint8_t *)&mac_sec_pib.DeviceTable[ attribute_index].DeviceDescriptor[ 0].ExtAddress, attribute_temp_ptr, sizeof(uint64_t)); /*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_16bit > MAC_ZIP_MAX_DEV_TABLE_ENTRIES) { status = MAC_INVALID_PARAMETER; } else { mac_sec_pib.DeviceTableEntries = attribute_value->pib_value_16bit; } 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; case macPANCoordExtendedAddress: memcpy(mac_sec_pib.PANCoordExtendedAddress, attribute_value, 8); break; case macPANCoordShortAddress: mac_sec_pib.PANCoordShortAddress = attribute_value->pib_value_16bit; break; #endif /* (MAC_SECURITY_ZIP || MAC_SECURITY_2006) */ #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; }
void bc_data_cb(frame_info_t *transmit_frame) { uint8_t index; index = nwkFindPassiveAck(transmit_frame->NwkFrameHeader->srcAddr, transmit_frame->NwkFrameHeader->sequenceNumber); if (index != 0xFF) { if (gNwkPassiveAckTable.table[index].end == false) { do { if (gNwkPassiveAckTable.table[index].realyNeighborNum >= neighborTable.size) break; while (transmit_frame->AppFrameHeader->frameControl.tries != 0)//以后要用这个NWK_MAX_BROADCAST_RETRIES { transmit_frame->AppFrameHeader->AppPayload[transmit_frame->AppFrameHeader->length] ^= transmit_frame->AppFrameHeader->frameControl.tries; transmit_frame->AppFrameHeader->frameControl.tries--; transmit_frame->AppFrameHeader->AppPayload[transmit_frame->AppFrameHeader->length] ^= transmit_frame->AppFrameHeader->frameControl.tries; //mac_trx_wakeup(); retval_t status = FAILURE; transmit_frame->mpdu[3] = mac_pib.mac_DSN++; /* In Nonbeacon build the frame is sent with unslotted CSMA-CA. */ status = tal_tx_frame(transmit_frame, CSMA_UNSLOTTED, true); if (MAC_SUCCESS == status) { MAKE_MAC_BUSY(); /* Start timer to initiate next broadcast data transmission. */ pal_timer_start(gNwkPassiveAckTable.table[index].timerID, ((uint32_t)NWK_PASSIVE_ACK_TIMEOUT), TIMEOUT_RELATIVE, (FUNC_PTR)bc_data_cb, transmit_frame); gNwkPassiveAckTable.table[index].reTryTimes++; } else { break; } return; } }while(0); NwkState = NWK_MODULE_NONE; pal_timer_start(gNwkPassiveAckTable.table[index].timerID, ((uint32_t) (NWK_BROADCAST_DELIVERY_TIME-(gNwkPassiveAckTable.table[index].reTryTimes+1)*NWK_PASSIVE_ACK_TIMEOUT)), TIMEOUT_RELATIVE, (FUNC_PTR)bc_data_cb, transmit_frame); gNwkPassiveAckTable.table[index].end = true; return; } gNwkPassiveAckTable.table[index].end = false; gNwkPassiveAckTable.table[index].reTryTimes = 0; nwkFreePassiveAck(transmit_frame->NwkFrameHeader->srcAddr, transmit_frame->NwkFrameHeader->sequenceNumber); if (transmit_frame != NULL) bmm_buffer_free(transmit_frame->buffer_header); //NwkState = NWK_MODULE_NONE; mac_sleep_trans(); } }
/** * @brief Continues processing a data indication from the TAL for * non-polling and non-scanning states of the MAC * (mac_poll_state == MAC_POLL_IDLE, mac_scan_state == MAC_SCAN_IDLE). * * @param b_ptr Pointer to the buffer header. * @param f_ptr Pointer to the frame_info_t structure. * * @return bool True if frame has been processed, or false otherwise. */ static bool process_data_ind_not_transient(buffer_t *b_ptr, frame_info_t *f_ptr) { bool processed_in_not_transient = false; /* * We are in MAC_POLL_IDLE and MAC_SCAN_IDLE now, * so continue with the real MAC states. */ switch (mac_state) { #if (MAC_START_REQUEST_CONFIRM == 1) case MAC_PAN_COORD_STARTED: { switch (mac_parse_data.frame_type) { case FCF_FRAMETYPE_MAC_CMD: { switch (mac_parse_data.mac_command) { #if (MAC_ASSOCIATION_INDICATION_RESPONSE == 1) case ASSOCIATIONREQUEST: mac_process_associate_request(b_ptr); processed_in_not_transient = true; break; #endif /* (MAC_ASSOCIATION_INDICATION_RESPONSE == 1) */ #if (MAC_DISASSOCIATION_BASIC_SUPPORT == 1) case DISASSOCIATIONNOTIFICATION: mac_process_disassociate_notification(b_ptr); processed_in_not_transient = true; break; #endif /* (MAC_DISASSOCIATION_BASIC_SUPPORT == 1) */ #if (MAC_INDIRECT_DATA_FFD == 1) case DATAREQUEST: if (indirect_data_q.size > 0) { mac_process_data_request(b_ptr); processed_in_not_transient = true; } else { mac_handle_tx_null_data_frame(); } break; #endif /* (MAC_INDIRECT_DATA_FFD == 1) */ #if (MAC_ORPHAN_INDICATION_RESPONSE == 1) case ORPHANNOTIFICATION: mac_process_orphan_notification(b_ptr); processed_in_not_transient = true; break; #endif /* (MAC_ORPHAN_INDICATION_RESPONSE == 1) */ case BEACONREQUEST: mac_process_beacon_request(b_ptr); processed_in_not_transient = true; break; #if (MAC_PAN_ID_CONFLICT_AS_PC == 1) case PANIDCONFLICTNOTIFICAION: mac_sync_loss(MAC_PAN_ID_CONFLICT); break; #endif /* (MAC_PAN_ID_CONFLICT_AS_PC == 1) */ #ifdef GTS_SUPPORT case GTSREQUEST: mac_process_gts_request(b_ptr); processed_in_not_transient = true; #endif /* GTS_SUPPORT */ default: break; } } break; case FCF_FRAMETYPE_DATA: mac_process_data_frame(b_ptr); processed_in_not_transient = true; break; #if (MAC_PAN_ID_CONFLICT_AS_PC == 1) case FCF_FRAMETYPE_BEACON: /* PAN-Id conflict detection as PAN-Coordinator. */ /* Node is not scanning. */ check_for_pan_id_conflict_as_pc(false); break; #endif /* (MAC_PAN_ID_CONFLICT_AS_PC == 1) */ default: break; } } break; /* MAC_PAN_COORD_STARTED */ #endif /* (MAC_START_REQUEST_CONFIRM == 1) */ case MAC_IDLE: #if (MAC_ASSOCIATION_REQUEST_CONFIRM == 1) case MAC_ASSOCIATED: #endif /* (MAC_ASSOCIATION_REQUEST_CONFIRM == 1) */ #if (MAC_START_REQUEST_CONFIRM == 1) case MAC_COORDINATOR: #endif /* (MAC_START_REQUEST_CONFIRM == 1) */ { /* Is it a Beacon from our parent? */ switch (mac_parse_data.frame_type) { #if (MAC_SYNC_REQUEST == 1) case FCF_FRAMETYPE_BEACON: { uint32_t beacon_tx_time_symb; /* Check for PAN-Id conflict being NOT a PAN * Corodinator. */ #if (MAC_PAN_ID_CONFLICT_NON_PC == 1) if (mac_pib.mac_AssociatedPANCoord && (MAC_IDLE != mac_state)) { check_for_pan_id_conflict_non_pc(false); } #endif /* (MAC_PAN_ID_CONFLICT_NON_PC == 1) */ /* Check if the beacon is received from my * parent. */ if ((mac_parse_data.src_panid == tal_pib.PANId) && (((mac_parse_data.src_addr_mode == FCF_SHORT_ADDR) && (mac_parse_data.src_addr. short_address == mac_pib.mac_CoordShortAddress)) || ((mac_parse_data.src_addr_mode == FCF_LONG_ADDR) && (mac_parse_data.src_addr. long_address == mac_pib.mac_CoordExtendedAddress)))) { beacon_tx_time_symb = TAL_CONVERT_US_TO_SYMBOLS( f_ptr->time_stamp); #if (_DEBUG_ > 0) retval_t set_status = #endif set_tal_pib_internal(macBeaconTxTime, (void *)&beacon_tx_time_symb); #if (_DEBUG_ > 0) Assert(MAC_SUCCESS == set_status); #endif if ((MAC_SYNC_TRACKING_BEACON == mac_sync_state) || (MAC_SYNC_BEFORE_ASSOC == mac_sync_state) ) { uint32_t nxt_bcn_tm; uint32_t beacon_int_symb; /* Process a received beacon. */ mac_process_beacon_frame(b_ptr); /* Initialize beacon tracking * timer. */ { retval_t tmr_start_res = FAILURE; #ifdef BEACON_SUPPORT if (tal_pib.BeaconOrder < NON_BEACON_NWK) { beacon_int_symb = TAL_GET_BEACON_INTERVAL_TIME( tal_pib.BeaconOrder); } else #endif /* BEACON_SUPPORT */ { beacon_int_symb = TAL_GET_BEACON_INTERVAL_TIME( BO_USED_FOR_MAC_PERS_TIME); } pal_timer_stop( T_Beacon_Tracking_Period); #if (_DEBUG_ > 0) if (pal_is_timer_running( T_Beacon_Tracking_Period)) { Assert( "Bcn tmr running" == 0); } #endif do { /* * Calculate the * time for next * beacon * transmission */ beacon_tx_time_symb = tal_add_time_symbols( beacon_tx_time_symb, beacon_int_symb); /* * Take into * account the * time taken by * the radio to * wakeup from * sleep state */ nxt_bcn_tm = tal_sub_time_symbols( beacon_tx_time_symb, TAL_RADIO_WAKEUP_TIME_SYM << ( tal_pib . BeaconOrder + 2)); tmr_start_res = pal_timer_start( T_Beacon_Tracking_Period, TAL_CONVERT_SYMBOLS_TO_US( nxt_bcn_tm), TIMEOUT_ABSOLUTE, ( FUNC_PTR)mac_t_tracking_beacons_cb, NULL); } while (MAC_SUCCESS != tmr_start_res); #ifdef GTS_DEBUG port_pin_toggle_output_level( DEBUG_PIN1); port_pin_set_output_level( DEBUG_PIN2, 0); #endif } /* * Initialize superframe timer * if required only * for devices because * Superframe timer is already * running for * coordinator. */ /* TODO */ if (MAC_ASSOCIATED == mac_state) { mac_superframe_state = MAC_ACTIVE_CAP; /* 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); if (tal_pib. SuperFrameOrder < tal_pib . BeaconOrder) { pal_timer_start( T_Superframe, TAL_CONVERT_SYMBOLS_TO_US( TAL_GET_SUPERFRAME_DURATION_TIME( tal_pib . SuperFrameOrder)), TIMEOUT_RELATIVE, ( FUNC_PTR)mac_t_start_inactive_device_cb, NULL); #ifdef GTS_DEBUG port_pin_set_output_level( DEBUG_PIN2, 1); #endif } #ifdef GTS_SUPPORT if (mac_final_cap_slot < FINAL_CAP_SLOT_DEFAULT) { uint32_t gts_tx_time = ( TAL_CONVERT_SYMBOLS_TO_US( TAL_GET_SUPERFRAME_DURATION_TIME( tal_pib . SuperFrameOrder)) >> 4) * ( mac_final_cap_slot + 1); pal_timer_start( T_CAP, gts_tx_time, TIMEOUT_RELATIVE, ( FUNC_PTR)mac_t_gts_cb, NULL); #ifdef GTS_DEBUG port_pin_set_output_level( DEBUG_PIN3, 1); #endif } #endif /* GTS_SUPPORT */ } /* Initialize missed beacon * timer. */ mac_start_missed_beacon_timer(); /* A device that is neither * scanning nor polling shall go * to sleep now. */ if ( (MAC_COORDINATOR != mac_state) && (MAC_SCAN_IDLE == mac_scan_state) && (MAC_POLL_IDLE == mac_poll_state) ) { /* * If the last received * beacon frame from our * parent * has indicated pending * broadbast data, we * need to * stay awake, until the * broadcast data has * been received. */ if (! mac_bc_data_indicated) { /* Set radio to * sleep if * allowed */ mac_sleep_trans(); } } } else if (MAC_SYNC_ONCE == mac_sync_state) { mac_process_beacon_frame(b_ptr); /* Do this after processing the * beacon. */ mac_sync_state = MAC_SYNC_NEVER; /* A device that is neither * scanning nor polling shall go * to sleep now. */ if ( (MAC_COORDINATOR != mac_state) && (MAC_SCAN_IDLE == mac_scan_state) && (MAC_POLL_IDLE == mac_poll_state) ) { /* * If the last received * beacon frame from our * parent * has indicated pending * broadbast data, we * need to * stay awake, until the * broadcast data has * been received. */ if (! mac_bc_data_indicated) { /* Set radio to * sleep if * allowed */ mac_sleep_trans(); } } } else { /* Process the beacon frame */ bmm_buffer_free(b_ptr); } processed_in_not_transient = true; } else {
/* * @brief Continues handling of MLME_SCAN.request once the radio is awake * * @param scan_buf Pointer to Scan request buffer. */ static void mac_awake_scan(buffer_t *scan_buf) { mlme_scan_conf_t *msc; msc = (mlme_scan_conf_t *)BMM_BUFFER_POINTER(scan_buf); /* Set the first channel at which the scan is started */ scan_curr_channel = MIN_CHANNEL; switch (scan_type) { #if (MAC_SCAN_ED_REQUEST_CONFIRM == 1) case MLME_SCAN_TYPE_ED: msc->scan_result_list[0].ed_value[1] = 0; /* First channel's * accumulated energy * level */ mac_scan_state = MAC_SCAN_ED; scan_proceed(MLME_SCAN_TYPE_ED, (buffer_t *)scan_buf); break; #endif /* (MAC_SCAN_ED_REQUEST_CONFIRM == 1) */ #if ((MAC_SCAN_ACTIVE_REQUEST_CONFIRM == 1) || \ (MAC_SCAN_PASSIVE_REQUEST_CONFIRM == 1)) case MLME_SCAN_TYPE_ACTIVE: case MLME_SCAN_TYPE_PASSIVE: { /* * Before commencing an active or passive scan, the MAC sublayer * shall store the value of macPANId and then set it to 0cFFFF * for * the duration of the scan. This enables the receive filter to * accept all beacons rather than just the beacons from its * current PAN (see 7.5.6.2). On completion of the scan, the * MAC sublayer shall restore the value of macPANId to the * value stored before the scan began. */ uint16_t broadcast_panid = BROADCAST; mac_scan_orig_panid = tal_pib.PANId; #if (_DEBUG_ > 0) retval_t set_status = #endif set_tal_pib_internal(macPANId, (void *)&broadcast_panid); #if (_DEBUG_ > 0) Assert(MAC_SUCCESS == set_status); set_status = set_status; #endif if (MLME_SCAN_TYPE_ACTIVE == scan_type) { /* * In active scan reuse the scan request buffer for * sending beacon request. */ mac_scan_cmd_buf_ptr = (uint8_t *)scan_buf; } /* Allocate a large size buffer for scan confirm. */ mac_conf_buf_ptr = (uint8_t *)bmm_buffer_alloc(LARGE_BUFFER_SIZE); if (NULL == mac_conf_buf_ptr) { /* * Large buffer is not available for sending scan * confirmation, * hence the scan request buffer (small buffer) is used * to send * the scan confirmation. */ msc->status = MAC_INVALID_PARAMETER; /* Append scan confirm message to the MAC-NHLE queue */ qmm_queue_append(&mac_nhle_q, scan_buf); /* Set radio to sleep if allowed */ mac_sleep_trans(); return; } if (MLME_SCAN_TYPE_PASSIVE == scan_type) { /* Free the scan request buffer when in passive scan. */ bmm_buffer_free(scan_buf); } msc = (mlme_scan_conf_t *)BMM_BUFFER_POINTER( (buffer_t *)mac_conf_buf_ptr); msc->cmdcode = MLME_SCAN_CONFIRM; msc->ScanType = scan_type; msc->ChannelPage = scan_curr_page; msc->UnscannedChannels = scan_channels; msc->ResultListSize = 0; msc->scan_result_list[0].ed_value[0] = 0; scan_proceed(scan_type, (buffer_t *)mac_conf_buf_ptr); break; } #endif /* ((MAC_SCAN_ACTIVE_REQUEST_CONFIRM == 1) || *(MAC_SCAN_PASSIVE_REQUEST_CONFIRM == 1)) */ #if (MAC_SCAN_ORPHAN_REQUEST_CONFIRM == 1) case MLME_SCAN_TYPE_ORPHAN: /* Buffer allocated for orphan notification command */ mac_scan_cmd_buf_ptr = (uint8_t *)bmm_buffer_alloc(LARGE_BUFFER_SIZE); if (NULL == mac_scan_cmd_buf_ptr) { msc->status = MAC_INVALID_PARAMETER; /* Append scan confirm message to the MAC-NHLE queue */ qmm_queue_append(&mac_nhle_q, scan_buf); /* Set radio to sleep if allowed */ mac_sleep_trans(); return; } scan_proceed(MLME_SCAN_TYPE_ORPHAN, (buffer_t *)mac_conf_buf_ptr); break; #endif /* (MAC_SCAN_ORPHAN_REQUEST_CONFIRM == 1) */ default: msc->status = MAC_INVALID_PARAMETER; /* Append scan confirm message to the MAC-NHLE queue */ qmm_queue_append(&mac_nhle_q, scan_buf); /* Set radio to sleep if allowed */ mac_sleep_trans(); break; } } /* mac_awake_scan() */
/* * @brief Proceed with a scan request * * This function proceeds with the scanning. * The current channel is incremented. It is checked if it belongs to the * list of channels to scan. If so, start scanning. If all channels done, * send out the MLME_SCAN.confirm message. * * @param scanning_type The type of the scan operation to proceed with. * @param buf Buffer to send mlme scan confirm to NHLE. */ static void scan_proceed(uint8_t scanning_type, buffer_t *buf) { retval_t set_status; mlme_scan_conf_t *msc = (mlme_scan_conf_t *)BMM_BUFFER_POINTER(buf); /* Set the channel page to perform scan */ set_status = set_tal_pib_internal(phyCurrentPage, (void *)&scan_curr_page); /* Loop over all channels the MAC has been requested to scan */ for (; scan_curr_channel <= MAX_CHANNEL; scan_curr_channel++) { #if ((MAC_SCAN_PASSIVE_REQUEST_CONFIRM == 1) || \ (MAC_SCAN_ACTIVE_REQUEST_CONFIRM == 1)) if ( ((MAC_SCAN_ACTIVE == mac_scan_state) || (MAC_SCAN_PASSIVE == mac_scan_state)) && mac_pib.mac_AutoRequest ) { /* * For active or passive scans, bail out if we * reached our maximum number of PANDescriptors that * could * be stored. That way, the upper layer will get the * correct set of unscanned channels returned, so it can * continue scanning if desired. * * According to 802.15.4-2006 PAN descriptor are only * present * in the scan confirm message in case the PIB attribute * macAutoRequest is true. */ if (msc->ResultListSize >= MAX_PANDESCRIPTORS) { break; } } #endif /* ((MAC_SCAN_PASSIVE_REQUEST_CONFIRM == 1) || *(MAC_SCAN_ACTIVE_REQUEST_CONFIRM == 1)) */ #if (MAC_SCAN_ORPHAN_REQUEST_CONFIRM == 1) if (MLME_SCAN_TYPE_ORPHAN == scanning_type) { /* * In an orphan scan, terminate if any coordinator * realignment packet has been received. */ if (msc->ResultListSize) { break; } } #endif /* (MAC_SCAN_ORPHAN_REQUEST_CONFIRM == 1) */ if ((msc->UnscannedChannels & (1UL << scan_curr_channel)) != 0) { #if (MAC_SCAN_ACTIVE_REQUEST_CONFIRM == 1) if (MLME_SCAN_TYPE_ACTIVE == scanning_type) { mac_scan_state = MAC_SCAN_ACTIVE; } #endif /* (MAC_SCAN_ACTIVE_REQUEST_CONFIRM == 1) */ #if (MAC_SCAN_PASSIVE_REQUEST_CONFIRM == 1) if (MLME_SCAN_TYPE_PASSIVE == scanning_type) { mac_scan_state = MAC_SCAN_PASSIVE; } #endif /* (MAC_SCAN_PASSIVE_REQUEST_CONFIRM == 1) */ if (MLME_SCAN_TYPE_ORPHAN == scanning_type) { mac_scan_state = MAC_SCAN_ORPHAN; } /* Set the channel to perform scan */ set_status = set_tal_pib_internal(phyCurrentChannel, (void *)&scan_curr_channel); if (MAC_SUCCESS != set_status) { /* * Free the buffer used for sending orphan * notification command */ bmm_buffer_free((buffer_t *)mac_scan_cmd_buf_ptr); mac_scan_cmd_buf_ptr = NULL; /* Set radio to sleep if allowed */ mac_sleep_trans(); msc->status = MAC_NO_BEACON; /* Orphan scan does not return any list. */ msc->ResultListSize = 0; /* Append the scan confirm message to the * MAC-NHLE queue */ qmm_queue_append(&mac_nhle_q, buf); mac_scan_state = MAC_SCAN_IDLE; } #if (_DEBUG_ > 0) Assert(MAC_SUCCESS == set_status); #endif /* Continue scanning, after setting channel */ scan_set_complete(set_status); return; } } /* All channels were scanned. The confirm needs to be prepared */ switch (scanning_type) { #if (MAC_SCAN_ED_REQUEST_CONFIRM == 1) case MLME_SCAN_TYPE_ED: msc->status = MAC_SUCCESS; scan_clean_up(buf); break; #endif /* (MAC_SCAN_ED_REQUEST_CONFIRM == 1) */ #if (MAC_SCAN_ACTIVE_REQUEST_CONFIRM == 1) case MLME_SCAN_TYPE_ACTIVE: { /* * Free the buffer which was received from scan request and * reused * for beacon request frame transmission. */ bmm_buffer_free((buffer_t *)mac_scan_cmd_buf_ptr); mac_scan_cmd_buf_ptr = NULL; if (!mac_pib.mac_AutoRequest) { msc->status = MAC_SUCCESS; } else if (msc->ResultListSize >= MAX_PANDESCRIPTORS) { msc->status = MAC_LIMIT_REACHED; } else if (msc->ResultListSize) { msc->status = MAC_SUCCESS; } else { msc->status = MAC_NO_BEACON; } /* Restore macPANId after active scan completed. */ #if (_DEBUG_ > 0) set_status = #endif set_tal_pib_internal(macPANId, (void *)&mac_scan_orig_panid); #if (_DEBUG_ > 0) Assert(MAC_SUCCESS == set_status); #endif /* Done with scanning */ scan_clean_up((buffer_t *)mac_conf_buf_ptr); } break; #endif /* (MAC_SCAN_ACTIVE_REQUEST_CONFIRM == 1) */ #if (MAC_SCAN_PASSIVE_REQUEST_CONFIRM == 1) case MLME_SCAN_TYPE_PASSIVE: if (!mac_pib.mac_AutoRequest) { msc->status = MAC_SUCCESS; } else if (msc->ResultListSize >= MAX_PANDESCRIPTORS) { msc->status = MAC_LIMIT_REACHED; } else if (msc->ResultListSize) { msc->status = MAC_SUCCESS; } else { msc->status = MAC_NO_BEACON; } /* Restore macPANId after passive scan completed. */ #if (_DEBUG_ > 0) set_status = #endif set_tal_pib_internal(macPANId, (void *)&mac_scan_orig_panid); #if (_DEBUG_ > 0) Assert(MAC_SUCCESS == set_status); #endif scan_clean_up(buf); break; #endif /* (MAC_SCAN_PASSIVE_REQUEST_CONFIRM == 1) */ #if (MAC_SCAN_ORPHAN_REQUEST_CONFIRM == 1) case MLME_SCAN_TYPE_ORPHAN: /* Free the buffer used for sending orphan notification command **/ bmm_buffer_free((buffer_t *)mac_scan_cmd_buf_ptr); mac_scan_cmd_buf_ptr = NULL; if (msc->ResultListSize > 0) { msc->status = MAC_SUCCESS; } else { msc->status = MAC_NO_BEACON; } /* Orphan scan does not return any list. */ msc->ResultListSize = 0; scan_clean_up(buf); break; #endif /* (MAC_SCAN_ORPHAN_REQUEST_CONFIRM == 1) */ default: break; } } /* scan_proceed() */
/** * @brief Processing a coordinator realignment command frame during Orphan scan * * This function processes a coordinator realignment command frame received * as a response to the reception of an orphan notification * command frame (i.e. while being in the middle of an orphan scan procedure). * The PAN ID, coord. short address, logical channel, and the device's new * short address will be written to the PIB. * * @param ind Frame reception buffer */ void mac_process_orphan_realign(buffer_t *buf_ptr) { retval_t set_status; /* Device received a coordinator realignment during an orphan scan */ /* Free the buffer used for sending orphan notification command */ bmm_buffer_free((buffer_t *)mac_scan_cmd_buf_ptr); mac_scan_cmd_buf_ptr = NULL; /* * Scan confirm with scan type orphan is given to the NHLE using the * scan request buffer, which was stored in mac_conf_buf_ptr. */ mlme_scan_conf_t *msc = (mlme_scan_conf_t *)BMM_BUFFER_POINTER( (buffer_t *)mac_conf_buf_ptr); msc->cmdcode = MLME_SCAN_CONFIRM; msc->status = MAC_SUCCESS; msc->ScanType = MLME_SCAN_TYPE_ORPHAN; msc->UnscannedChannels = 0; msc->ResultListSize = 0; /* Append the scan confirmation message to the MAC-NHLE queue */ qmm_queue_append(&mac_nhle_q, (buffer_t *)mac_conf_buf_ptr); mac_scan_state = MAC_SCAN_IDLE; /* Set radio to sleep if allowed */ mac_sleep_trans(); /* * The buffer in which the coordinator realignment is received is * freed up */ bmm_buffer_free(buf_ptr); /* Set the appropriate PIB entries */ set_status = set_tal_pib_internal(macPANId, (void *)&mac_parse_data.mac_payload_data.coord_realign_data.pan_id); #if (_DEBUG_ > 0) Assert(MAC_SUCCESS == set_status); #endif if (BROADCAST != mac_parse_data.mac_payload_data.coord_realign_data. short_addr) { /* Short address only to be set if not broadcast address */ set_status = set_tal_pib_internal(macShortAddress, (void *)&mac_parse_data.mac_payload_data.coord_realign_data.short_addr); #if (_DEBUG_ > 0) Assert(MAC_SUCCESS == set_status); #endif } mac_pib.mac_CoordShortAddress = mac_parse_data.mac_payload_data.coord_realign_data. coord_short_addr; /* * If frame version subfield indicates a 802.15.4-2006 compatible frame, * the channel page is appended as additional information element. */ if (mac_parse_data.fcf & FCF_FRAME_VERSION_2006) { set_status = set_tal_pib_internal(phyCurrentPage, (void *)&mac_parse_data.mac_payload_data.coord_realign_data.channel_page); #if (_DEBUG_ > 0) Assert(MAC_SUCCESS == set_status); #endif } set_status = set_tal_pib_internal(phyCurrentChannel, (void *)&mac_parse_data.mac_payload_data.coord_realign_data.logical_channel); #if (_DEBUG_ > 0) Assert(MAC_SUCCESS == set_status); #endif scan_set_complete(set_status); } /* mac_process_orphan_realign() */