zbSize_t Mgmt_Direct_Join_req ( zbMgmtDirectJoinRequest_t *pMsgComingIn ) { zdoNlmeMessage_t *pZdoNlmeMsg; #if ((gStandardSecurity_d || gHighSecurity_d) && gApsMaxEntriesForPermissionsTable_c) nlmeZdoMessage_t zdoMsg; #endif #if ((gStandardSecurity_d || gHighSecurity_d) && gApsMaxEntriesForPermissionsTable_c) if (!CommandHasPermission(NlmeGetRequest(gNwkShortAddress_c), gNetworkSettingsPermission_c)) { zdoMsg.msgData.directJoinConf.status = gZdpNotAuthorized_c; Zdp_Mgmt_Direct_Join_conf((void *)&zdoMsg); return 0; } #endif pZdoNlmeMsg = MSG_Alloc(MbrSizeof(zdoNlmeMessage_t, msgType) + sizeof(nlmeDirectJoinReq_t)); if (pZdoNlmeMsg) { pZdoNlmeMsg->msgType = gNlmeDirectJoinRequest_c; FLib_MemCpy(&pZdoNlmeMsg->msgData.directJoinReq, pMsgComingIn, sizeof(nlmeDirectJoinReq_t)); ZDO_SendEvent(gZdoEvent_ManagementCommand_c); (void)ZDO_NLME_SapHandler((void *)pZdoNlmeMsg); } return 0; }
/*-------------------- Mgmt_Permit_Joining_req -------------------- IN: The package with the request information. OUT: The size in bytes of the request payload. */ zbSize_t Mgmt_Permit_Joining_req ( zbMgmtPermitJoiningRequest_t *pMessageComingIn, /*IN The package with the request information. */ zbNwkAddr_t aDestAddr /* IN: The destination address where to send the request. */ ) { zdoNlmeMessage_t * pZdoNlmeMsg; /* If the destiantion address is to all awake devices, first turn it on locally and then send it OTA. */ if(FLib_MemCmp((uint8_t *)gaBroadcastZCnZR, aDestAddr, sizeof(zbNwkAddr_t))) { /* Do the permit joinig locally as well. */ pZdoNlmeMsg = MSG_AllocType(zdoNlmeMessage_t); /* If we can not set this locally is highly probably that we are not able to send packets OTA. */ if(pZdoNlmeMsg == NULL) return 0; if (NlmeGetRequest(gDevType_c) != gEndDevice_c) { /* Build the NLME request using the incoming info. */ BeeUtilZeroMemory(pZdoNlmeMsg,sizeof(zdoNlmeMessage_t )); pZdoNlmeMsg->msgData.permitJoiningReq.permitDuration = pMessageComingIn->PermitDuration; pZdoNlmeMsg->msgType = gNlmePermitJoiningRequest_c; (void)ZDO_NLME_SapHandler(pZdoNlmeMsg); } } /* By returning the size ZDP send out the request. */ return sizeof(zbMgmtPermitJoiningRequest_t); }
/************************************************************************************ * Does a local energy scan, pass the confirm to the application using the ZDP_APP * Sap handler. Not available to ZEDs * * Interface assumptions: * The parameter aChannelList, is a valid channel list and is on little endian. * The parameter duration, is a non zero value. * * Return value: * NONE. * * Revison history: * Date Author Comments * ------ ------ -------- * 180208 MN Created ************************************************************************************/ void ZdoNwkMng_EnergyScanRequest ( zbChannels_t aChannelList, uint8_t duration ) { uintn32_t localList = 0; zdoNlmeMessage_t *pEnergyScan; nlmeEnergyScanReq_t *pEnergyRequest; pEnergyScan = MSG_Alloc(sizeof(nlmeEnergyScanReq_t) + sizeof(zbMsgId_t)); if (!pEnergyScan) return; /* NOTE: this function is used on FA and on regular ZDO state machine some times it receives the parameter on little endian and some times on big endian. */ /* Check if it's a valid channel list */ if( aChannelList[0] & 0xFF || aChannelList[1] & 0x07 || aChannelList[3] & 0xF8 ) { #ifdef __IAR_SYSTEMS_ICC__ FLib_MemCpyReverseOrder(&localList, aChannelList, sizeof(uint32_t)); #else localList = *((uint32_t *)aChannelList); localList = Native2OTA32(localList); #endif } pEnergyScan->msgType = gNlmeEnergyScanRequest_c; pEnergyRequest = &pEnergyScan->msgData.EnergyScanReq; if (localList) { FLib_MemCpy(pEnergyRequest->aScanChannels, &localList, sizeof(localList)); } else { FLib_MemCpy(pEnergyRequest->aScanChannels, aChannelList, sizeof(localList)); } pEnergyRequest->scanDuration = duration; if(ZDO_NLME_SapHandler(pEnergyScan)) { } }
/* Start the ZC or ZR. Turns on the radio. Calls NLME-START-ROUTER.request */ void ZdoNwkMng_GenerateStartRouterReq ( void /*IN: No Input Parameters*/ ) { zdoNlmeMessage_t *pMsg; nlmeStartRouterReq_t sStartRouterReq; /*Create the Start as Router request and sent to the network Layer*/ pMsg = MSG_AllocType(zdoNlmeMessage_t); if(NULL == pMsg) return; pMsg->msgType = gNlmeStartRouterRequest_c; sStartRouterReq.beaconOrder = sStartRouterReq.superframeOrder = gBeeStackConfig.beaconOrder; sStartRouterReq.batteryLifeExtension = gBeeStackConfig.batteryLifeExtn; FLib_MemCpy(&pMsg->msgData.startRouterReq,&sStartRouterReq,sizeof(nlmeStartRouterReq_t)); ( void ) ZDO_NLME_SapHandler(pMsg); }
/************************************************************************************ * Using the default values of the ApsCahnnelMask and ScandDuration, Generates an * Nlme command to discover the ZigBee networks that may exist on the current * channel list. * * Interface assumptions: * Uses APS channel mask (gApsChannelMask_c) * * Return value: * NONE. * * Revison history: * Date Author Comments * ------ ------ -------- * 280208 MN Updated ************************************************************************************/ void ZdoNwkMng_GenerateNetworkFormation ( void /*IN: No Input Parameters*/ ) { nlmeNetworkFormationReq_t *pNwkFormationReq; zdoNlmeMessage_t *pNwkMsg; uint8_t *pChannelList = (uint8_t *)ApsmeGetRequest(gApsChannelMask_c); #if gComboDeviceCapability_d if (NlmeGetRequest(gDevType_c) != gCoordinator_c) return; #endif /* every single command needs it own buffer to be passed down to next layer. */ pNwkMsg = MSG_AllocType(zdoNlmeMessage_t); /* If the buffer allocation fails for any reason, that is it, no further processing is needed. */ if ( !pNwkMsg ) return; /* Create the network formation request and sent to the network Layer. */ pNwkMsg->msgType = gNlmeNetworkFormationRequest_c; /* Fast access to the memory where the */ pNwkFormationReq = &pNwkMsg->msgData.networkFormationReq; #if gComboDeviceCapability_d if (NlmeGetRequest(gDevType_c) == gCoordinator_c) #endif { /* We will use the list from the ED if and only if it is a valid list other wise use the current APS channel mask. */ if ((*(uint32_t *)gaScanChannels) != 0) { /* Use only the channels with the best energy levels for the active scan. */ pChannelList = gaScanChannels; } } /* Using the default channel mask, generate the Formation command. */ FLib_MemCpy(pNwkFormationReq->aScanChannels, pChannelList, sizeof(ApsmeGetRequest(gApsChannelMask_c))); /* Get all the parameters neede for this command. */ pNwkFormationReq->scanDuration = gScanDuration_c; FLib_MemCpy(&pNwkFormationReq->beaconOrder, &gBeeStackConfig.beaconOrder, 2); Copy2Bytes(pNwkFormationReq->aPanId, NlmeGetRequest(gNwkPanId_c)); pNwkFormationReq->batteryLifeExtension = gBeeStackConfig.batteryLifeExtn; if (ZDO_NLME_SapHandler( pNwkMsg )) { /* Catch the error if needed. */ } }
/************************************************************************************ * Using the default values of the ApsChannelMask and ScanDuration, generates an * Nlme command to discover the ZigBee networks that may exist on the current * channel list (issues beacon requests and listens to beacon responses). * * Interface assumptions: * NONE. * * Return value: * NONE. * * Revison history: * Date Author Comments * ------ ------ -------- * 140708 DG Updated ************************************************************************************/ void ZdoNwkMng_GenerateNwkDiscoveryReq ( void /* IN: No Input Parameters. */ ) { zdoNlmeMessage_t *pNwkMsg; nlmeNetworkDiscoveryReq_t *pNwkDiscoveryReq; uint8_t *pChannelList = (uint8_t *)ApsmeGetRequest(gApsChannelMask_c); /* We need to generate a message to Nwk layer, a buffer needs to be allocated. */ pNwkMsg = MSG_AllocType( zdoNlmeMessage_t ); /* For some reason we fail to allocate the memory, no further processing can be done. */ if (!pNwkMsg) return; /* We are about to do what in the network layer is named active scan, we need the right list depending on the device type. */ #if gCoordinatorCapability_d || gComboDeviceCapability_d #if gComboDeviceCapability_d if (NlmeGetRequest(gDevType_c) == gCoordinator_c) #endif { /* We will use the list from the ED if and only if it is a valid list other wise use the current APS channel mask. */ if ((*(uint32_t *)gaScanChannels) != 0) { /* Use only the channels with the best energy levels for the active scan. */ pChannelList = gaScanChannels; } } #endif /* Create the network descovery request and sent to the network Layer. */ pNwkMsg->msgType = gNlmeNetworkDiscoveryRequest_c ; /* Fast access to the memory where the message is build, also is less code. */ pNwkDiscoveryReq = &pNwkMsg->msgData.networkDiscoveryReq; /* Set the current and active ApsChannelMask, remember this can be updated during the FA process. */ FLib_MemCpy(pNwkDiscoveryReq->aScanChannels, pChannelList, sizeof(ApsmeGetRequest(gApsChannelMask_c))); /* Get the default duration to use during the scan, remember that is trasnformed to a milliseconds time, down in the Nwk Layer. */ pNwkDiscoveryReq->scanDuration = gScanDuration_c; /* Pass the command down to the Nwk layer. */ if (ZDO_NLME_SapHandler( pNwkMsg )) { /* Catch the error if needed. */ } }
/************************************************************************************ * Generates a local Nlme Leave command to let the nwk layer know that WE as a device * are leaving the network, in other words, is a command to do a self-leave. Only called * from the ZDO state machine. * * NOTE: This function is meant to only be called byt the ZDO State machine on the * leaving state. * * Interface assumptions: * NONE. * * Return value: * NONE. * * Revison history: * Date Author Comments * ------ ------ -------- * 280208 MN Updated ************************************************************************************/ void ZdoNwkMng_GenerateNlmeLeaveRequest ( void /*IN: No Input Parameters*/ ) { /* Pointer to the buffer where the Nlme command will be filled. */ zdoNlmeMessage_t *pZdoNlmeMessage; /* The size for the curretn command to be passed down. */ uint8_t size = (sizeof(zbMsgId_t) + sizeof(nlmeLeaveReq_t)); /* Allocated the exact size memory for the Nlme command, remember this will passed down using a Sap hanlder, the memory will be freed by the next layer. */ pZdoNlmeMessage = MSG_AllocType(size); /* If for any reason the message was unable to be allocated, no further processing is done. */ if(!pZdoNlmeMessage) return; /* Most of the options are filled with a Zero value, lets fill the whole thing with Zeros, and just set the ones that are not Zero (less code). */ BeeUtilZeroMemory(pZdoNlmeMessage, size); /* Build the command. */ pZdoNlmeMessage->msgType = gNlmeLeaveRequest_c; #if gMgmt_Leave_rsp_d /* this would only occur if management leave command came from OTA */ if(zbMgmtOptionRemoveChildren_c & gMgmtSelfLeaveMask) { gMgmtSelfLeaveMask &= ~(zbMgmtOptionRemoveChildren_c); pZdoNlmeMessage->msgData.leaveReq.removeChildren = TRUE; } /* If the mgmt command was sent with the */ if(zbMgmtOptionReJoin_c & gMgmtSelfLeaveMask) { /* don't turn off bit yet in gMgmtSelfLeaveMask, it will be turned off later */ pZdoNlmeMessage->msgData.leaveReq.rejoin = TRUE; gMgmtSelfLeaveMask &= ~(zbMgmtOptionReJoin_c); } #endif /* check if the ZDO or the application needs to remove the children. */ if (gZdoStopMode & gZdoStopMode_RemoveChildren_c) { gZdoStopMode &= ~(gZdoStopMode_RemoveChildren_c); pZdoNlmeMessage->msgData.leaveReq.removeChildren = TRUE; } pZdoNlmeMessage->msgData.leaveReq.reuseAddress = mDefaultReuseAddressPolicy_c; if (ZDO_NLME_SapHandler( pZdoNlmeMessage )) { /* Catch the error message if needed. */ } }
/* Call on the network layer to (re)join the network. Includes orphan join, associate join, etc... */ void ZdoNwkMng_GenerateNwkJoinRequest(zbNwkJoinMode_t joinMode) { zdoNlmeMessage_t *pMsg; nlmeJoinReq_t *pJoinReq; uint8_t *pExtendedPan = (uint8_t *)NlmeGetRequest(gNwkExtendedPanId_c); /* allocate the request */ pMsg = MSG_AllocType(zdoNlmeMessage_t); if (!pMsg) { return; } /* Create the network Join request and sent to the network Layer */ pMsg->msgType = gNlmeJoinRequest_c; pJoinReq = &pMsg->msgData.joinReq; FLib_MemCpy(pJoinReq->aScanChannels, ApsmeGetRequest(gApsChannelMask_c), sizeof(ApsmeGetRequest(gApsChannelMask_c))); gZDO_SecureRejoin = ApsmeGetRequest(gApsUseInsecureJoin_c); /* By default the node will try to keep the behavior established by the SAS attribute, The SAS attribute canbe override by the application through the IB Set and Get. */ pJoinReq->securityEnable = ApsmeGetRequest(gApsUseInsecureJoin_c)? FALSE : TRUE; #if gStandardSecurity_d || gHighSecurity_d /* If we are trying to send a secure packet, then, check if we have a valid Nwk key. */ if (pJoinReq->securityEnable) { pJoinReq->securityEnable = SSP_NwkGotValidKey(); } /* If the rejoin is allowed unsecured then change the APSIB until authentication has arrive. */ if (!pJoinReq->securityEnable) { ApsmeSetRequest(gApsUseInsecureJoin_c, TRUE); } #endif #if gComboDeviceCapability_d pJoinReq->joinAsRouter = (NlmeGetRequest( gDevType_c ) == gRouter_c)? TRUE : FALSE; #elif ( gRouterCapability_d ) pJoinReq->joinAsRouter = TRUE; #else /*gRouterCapability_d*/ pJoinReq->joinAsRouter = FALSE; #endif /*gRouterCapability_d*/ pJoinReq->rejoinNetwork = joinMode; if (joinMode == gZdoStartMode_NwkRejoin_c) { pExtendedPan = (uint8_t *)ApsmeGetRequest(gApsUseExtendedPANID_c); } Copy8Bytes( pJoinReq->aExtendedPanId, pExtendedPan); pJoinReq->scanDuration = gScanDuration_c; pJoinReq->powerSource = ((gBeeStackConfig.currPowerSourceAndLevel & 0x01)? 0 : 1); pJoinReq->rxOnWhenIdle = ((IsLocalDeviceReceiverOnWhenIdle())? TRUE : FALSE); ( void ) ZDO_NLME_SapHandler( pMsg ); }