/*-------------------- 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); }
/****************************************************************************** * The App_StartScan(scanType) function will start the scan process of the * specified type in the MAC. This is accomplished by allocating a MAC message, * which is then assigned the desired scan parameters and sent to the MLME * service access point. * The function may return either of the following values: * errorNoError: The Scan message was sent successfully. * errorInvalidParameter: The MLME service access point rejected the * message due to an invalid parameter. * errorAllocFailed: A message buffer could not be allocated. * ******************************************************************************/ static uint8_t App_StartScan(uint8_t scanType) { mlmeMessage_t *pMsg; mlmeScanReq_t *pScanReq; UartUtil_Print("Sending the MLME-Scan Request message to the MAC...", gAllowToBlock_d); /* Allocate a message for the MLME (We should check for NULL). */ pMsg = MSG_AllocType(mlmeMessage_t); if(pMsg != NULL) { /* This is a MLME-SCAN.req command */ pMsg->msgType = gMlmeScanReq_c; /* Create the Scan request message data. */ pScanReq = &pMsg->msgData.scanReq; /* gScanModeED_c, gScanModeActive_c, gScanModePassive_c, or gScanModeOrphan_c */ pScanReq->scanType = scanType; /* ChannelsToScan & 0xFF - LSB, always 0x00 */ pScanReq->scanChannels[0] = (uint8_t)((mDefaultValueOfChannel_c) & 0xFF); /* ChannelsToScan>>8 & 0xFF */ pScanReq->scanChannels[1] = (uint8_t)((mDefaultValueOfChannel_c>>8) & 0xFF); /* ChannelsToScan>>16 & 0xFF */ pScanReq->scanChannels[2] = (uint8_t)((mDefaultValueOfChannel_c>>16) & 0xFF); /* ChannelsToScan>>24 & 0xFF - MSB */ pScanReq->scanChannels[3] = (uint8_t)((mDefaultValueOfChannel_c>>24) & 0xFF); /* Duration per channel 0-14 (dc). T[sec] = (16*960*((2^dc)+1))/1000000. A scan duration of 3 on 16 channels approximately takes 2 secs. */ pScanReq->scanDuration = 3; #ifdef gMAC2006_d pScanReq->securityLevel = 0; #endif //gMAC2006_d /* Send the Scan request to the MLME. */ if(MSG_Send(NWK_MLME, pMsg) == gSuccess_c) { UartUtil_Print("Done\n\r", gAllowToBlock_d); return errorNoError; } else { UartUtil_Print("Invalid parameter!\n\r", gAllowToBlock_d); return errorInvalidParameter; } }
/* 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 ); }