/****************************************************************************** * @fn StubNWK_BuildMsg * * @brief This function builds a Stub NWK frame. * * @param nwkHdr - stub NWK header * * @return none */ static void StubNWK_BuildMsg( uint8 *nwkHdr ) { uint16 frmCtrl = 0; uint8 protoVer = NLME_GetProtocolVersion(); // frame type frmCtrl |= (STUB_NWK_FRAME_TYPE << NWK_FC_FRAME_TYPE); // protocol version frmCtrl |= (protoVer << NWK_FC_PROT_VERSION); // set Stub NWK header *nwkHdr++ = LO_UINT16( frmCtrl ); *nwkHdr++ = HI_UINT16( frmCtrl ); } /* StubNWK_BuildMsg */
/**************************************************************************** * @fn INTERP_DataIndication * * @brief This function indicates the transfer of a data SPDU (MSDU) * from the MAC layer to the local application layer entity. * * @param dataInd - data indicate primitive * * @return none */ void INTERP_DataIndication( macMcpsDataInd_t *dataInd ) { NLDE_FrameFormat_t snff; aps_FrameFormat_t saff; zAddrType_t srcAddr; NLDE_Signal_t sig; // parse the Stub NWK header StubNWK_ParseMsg( dataInd->msdu.p, dataInd->msdu.len, &snff ); // Fill in MAC destination address snff.macDstAddr = dataInd->mac.dstAddr.addr.shortAddr; // fill in MAC source address (Stub NWK frame doesn't have address fields) osal_copyAddress( &srcAddr, (zAddrType_t *)&(dataInd->mac.srcAddr) ); // check if incoming frame is of the right type if ( snff.frameType != STUB_NWK_FRAME_TYPE ) return; // check if incoming frame is of the right version if ( snff.protocolVersion != NLME_GetProtocolVersion() ) return; // check if the remaining sun-fields are zero if ( ( snff.discoverRoute != 0 ) || ( snff.multicast != 0 ) || ( snff.secure != 0 ) || ( snff.srcRouteSet != 0 ) || ( snff.dstExtAddrSet != 0 ) || ( snff.srcExtAddrSet != 0 ) ) { return; } // parse the Stub APS header StubAPS_ParseMsg( &snff, &saff ); // check if incoming frame is of the right type if ( ( saff.FrmCtrl & APS_FRAME_TYPE_MASK ) != STUB_APS_FRAME ) return; // check if delivery mode is of the right type if ( ( saff.FrmCtrl & APS_DELIVERYMODE_MASK ) == APS_FC_DM_INDIRECT ) return; // check if incoming frame is unsecured if ( saff.FrmCtrl & APS_FC_SECURITY ) return; // check if there's no extended header if ( saff.FrmCtrl & APS_FC_EXTENDED ) return; // Set the endpoints saff.DstEndPoint = appEndPoint; saff.SrcEndPoint = STUBAPS_INTER_PAN_EP; // Set the signal strength information sig.LinkQuality = dataInd->mac.mpduLinkQuality; sig.correlation = dataInd->mac.correlation; sig.rssi = dataInd->mac.rssi; APSDE_DataIndication( &saff, &srcAddr, dataInd->mac.srcPanId, &sig, snff.broadcastId, FALSE, dataInd->mac.timestamp, 0 ); } /* INTERP_DataIndication */
/********************************************************************* * @fn zdo_MTCB_MgmtLqiRspCB() * * @brief * * Called to send MT callback response for Management LQI response * * @param type - binding type (end device, bind, unbind) * @param SrcAddr - Source address * @param Status - response status * * @return none */ void zdo_MTCB_MgmtLqiRspCB( uint16 SrcAddr, byte Status, byte NeighborLqiEntries, byte StartIndex, byte NeighborLqiCount, neighborLqiItem_t *pList ) { byte *msgPtr; byte *msg; byte len; byte x; byte proVer = NLME_GetProtocolVersion(); /*Allocate a message of size equivalent to the corresponding SPI message (plus a couple of bytes for MT use)so that the same buffer can be sent by MT to the test tool by simply setting the header bytes.*/ /*In order to allocate the message , we need to know the length and this has to be calculated before we allocate the message*/ len = 2 + 1 + 1 + 1 + 1 + (ZDP_NEIGHBORLQI_SIZE * ZDO_MAX_LQI_ITEMS ); // SrcAddr + Status + NeighborLqiEntries + StartIndex + NeighborLqiCount // + (maximum entries * size of struct) msgPtr = osal_mem_alloc( len ); if ( msgPtr ) { msg = msgPtr; //Fill up the data bytes *msg++ = HI_UINT16( SrcAddr ); *msg++ = LO_UINT16( SrcAddr ); *msg++ = Status; *msg++ = NeighborLqiEntries; *msg++ = StartIndex; *msg++ = NeighborLqiCount; osal_memset( msg, 0, (ZDP_NEIGHBORLQI_SIZE * ZDO_MAX_LQI_ITEMS) ); for ( x = 0; x < ZDO_MAX_LQI_ITEMS; x++ ) { if ( x < NeighborLqiCount ) { if ( proVer == ZB_PROT_V1_0 ) { *msg++ = HI_UINT16( pList->PANId ); *msg++ = LO_UINT16( pList->PANId ); } else { osal_cpyExtAddr(msg, pList->extPANId); msg += Z_EXTADDR_LEN; } *msg++ = HI_UINT16( pList->nwkAddr ); *msg++ = LO_UINT16( pList->nwkAddr ); *msg++ = pList->rxLqi; *msg++ = pList->txQuality; pList++; } } MT_BuildAndSendZToolCB( SPI_CB_ZDO_MGMT_LQI_RSP, len, msgPtr ); osal_mem_free( msgPtr ); } }
/********************************************************************* * @fn MT_ZdoCommandProcessing * * @brief * * Process all the ZDO commands that are issued by test tool * * @param cmd_id - Command ID * @param len - Length of received SPI data message * @param pData - pointer to received SPI data message * * @return void */ void MT_ZdoCommandProcessing( uint16 cmd_id , byte len , byte *pData ) { byte i; byte x; byte ret; byte attr; byte attr1; uint16 cID; uint16 shortAddr; uint16 uAttr; byte *ptr; byte *ptr1; zAddrType_t devAddr; zAddrType_t dstAddr; byte respLen; #if defined ( ZDO_MGMT_NWKDISC_REQUEST ) uint32 scanChans; #endif #if defined ( ZDO_USERDESCSET_REQUEST ) UserDescriptorFormat_t userDesc; #endif ret = UNSUPPORTED_COMMAND; len = SPI_0DATA_MSG_LEN + SPI_RESP_LEN_ZDO_DEFAULT; respLen = SPI_RESP_LEN_ZDO_DEFAULT; switch (cmd_id) { case SPI_CMD_ZDO_AUTO_ENDDEVICEBIND_REQ: i = *pData; // Get the endpoint/interface ZDApp_SendEndDeviceBindReq( i ); //Since function type is void, report a succesful operation to the test tool ret = ZSUCCESS; break; case SPI_CMD_ZDO_AUTO_FIND_DESTINATION_REQ: i = *pData; // Get the endpoint/interface ZDApp_AutoFindDestination( i ); //Since function type is void, report a succesful operation to the test tool ret = ZSUCCESS; break; #if defined ( ZDO_NWKADDR_REQUEST ) case SPI_CMD_ZDO_NWK_ADDR_REQ: // Copy and flip incoming 64-bit address pData = zdo_MT_MakeExtAddr( &devAddr, pData ); ptr = (byte*)&devAddr.addr.extAddr; attr = *pData++; // RequestType attr1 = *pData++; // StartIndex x = *pData; ret = (byte)ZDP_NwkAddrReq( ptr, attr, attr1, x ); break; #endif #if defined ( ZDO_IEEEADDR_REQUEST ) case SPI_CMD_ZDO_IEEE_ADDR_REQ: shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += sizeof( shortAddr ); attr = *pData++; // RequestType attr1 = *pData++; // StartIndex x = *pData; // SecuritySuite ret = (byte)ZDP_IEEEAddrReq( shortAddr, attr, attr1, x ); break; #endif #if defined ( ZDO_NODEDESC_REQUEST ) case SPI_CMD_ZDO_NODE_DESC_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData; ret = (byte)ZDP_NodeDescReq( &devAddr, shortAddr, attr ); break; #endif #if defined ( ZDO_POWERDESC_REQUEST ) case SPI_CMD_ZDO_POWER_DESC_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData; ret = (byte)ZDP_PowerDescReq( &devAddr, shortAddr, attr ); break; #endif #if defined ( ZDO_SIMPLEDESC_REQUEST ) case SPI_CMD_ZDO_SIMPLE_DESC_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData++; // endpoint/interface attr1 = *pData; // SecuritySuite ret = (byte)ZDP_SimpleDescReq( &devAddr, shortAddr, attr, attr1 ); break; #endif #if defined ( ZDO_ACTIVEEP_REQUEST ) case SPI_CMD_ZDO_ACTIVE_EPINT_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData; // SecuritySuite ret = (byte)ZDP_ActiveEPReq( &devAddr, shortAddr, attr ); break; #endif #if defined ( ZDO_MATCH_REQUEST ) case SPI_CMD_ZDO_MATCH_DESC_REQ: { uint16 inC[16], outC[16]; // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; uAttr = BUILD_UINT16( pData[1], pData[0] ); // Profile ID pData += 2; attr = *pData++; // NumInClusters for (i=0; i<16; ++i) { inC[i] = BUILD_UINT16(pData[1], pData[0]); pData += 2; } attr1 = *pData++; // NumOutClusters for (i=0; i<16; ++i) { outC[i] = BUILD_UINT16(pData[1], pData[0]); pData += 2; } i = *pData; // SecuritySuite ret = (byte)ZDP_MatchDescReq( &devAddr, shortAddr, uAttr, attr, inC, attr1, outC, i ); } break; #endif #if defined ( ZDO_COMPLEXDESC_REQUEST ) case SPI_CMD_ZDO_COMPLEX_DESC_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData; // SecuritySuite ret = (byte)ZDP_ComplexDescReq( &devAddr, shortAddr, attr ); break; #endif #if defined ( ZDO_USERDESC_REQUEST ) case SPI_CMD_ZDO_USER_DESC_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData; // SecuritySuite ret = (byte)ZDP_UserDescReq( &devAddr, shortAddr, attr ); break; #endif #if defined ( ZDO_ENDDEVICEBIND_REQUEST ) case SPI_CMD_ZDO_END_DEV_BIND_REQ: //TODO: When ZTool supports 16 bits the code below will need to take it into account { uint16 inC[16], outC[16]; // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; x = *pData++; // EPInt uAttr = BUILD_UINT16( pData[1], pData[0] ); // Profile ID pData += 2; attr = *pData++; // NumInClusters for (i=0; i<16; ++i) { inC[i] = BUILD_UINT16(pData[1], pData[0]); pData += 2; } attr1 = *pData++; // NumOutClusters for (i=0; i<16; ++i) { outC[i] = BUILD_UINT16(pData[1], pData[0]); pData += 2; } i = *pData; // SecuritySuite ret = (byte)ZDP_EndDeviceBindReq( &devAddr, shortAddr, x, uAttr, attr, inC, attr1, outC, i ); } break; #endif #if defined ( ZDO_BIND_UNBIND_REQUEST ) case SPI_CMD_ZDO_BIND_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; MT_ReverseBytes( pData, Z_EXTADDR_LEN ); ptr = pData; // SrcAddress pData += Z_EXTADDR_LEN; attr = *pData++; // SrcEPInt cID = BUILD_UINT16( pData[1], pData[0]); // ClusterID pData += 2; dstAddr.addrMode = *pData++; if ( NLME_GetProtocolVersion() == ZB_PROT_V1_0 ) dstAddr.addrMode = Addr64Bit; MT_ReverseBytes( pData, Z_EXTADDR_LEN ); if ( dstAddr.addrMode == Addr64Bit ) { ptr1 = pData; // DstAddress osal_cpyExtAddr( dstAddr.addr.extAddr, ptr1 ); } else { dstAddr.addr.shortAddr = BUILD_UINT16( pData[0], pData[1] ); } // The short address occupies lsb two bytes pData += Z_EXTADDR_LEN; attr1 = *pData++; // DstEPInt x = *pData; // SecuritySuite #if defined ( REFLECTOR ) if ( devAddr.addr.shortAddr == _NIB.nwkDevAddress ) { ZDApp_BindReqCB( 0, &devAddr, ptr, attr, cID, &dstAddr, attr1, x ); ret = ZSuccess; } else #endif ret = (byte)ZDP_BindReq( &devAddr, ptr, attr, cID, &dstAddr, attr1, x ); break; #endif #if defined ( ZDO_BIND_UNBIND_REQUEST ) case SPI_CMD_ZDO_UNBIND_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; MT_ReverseBytes( pData, Z_EXTADDR_LEN ); ptr = pData; // SrcAddress pData += Z_EXTADDR_LEN; attr = *pData++; // SrcEPInt cID = BUILD_UINT16( pData[1], pData[0]); // ClusterID pData += 2; dstAddr.addrMode = *pData++; if ( NLME_GetProtocolVersion() == ZB_PROT_V1_0 ) dstAddr.addrMode = Addr64Bit; MT_ReverseBytes( pData, Z_EXTADDR_LEN ); if ( dstAddr.addrMode == Addr64Bit ) { ptr1 = pData; // DstAddress osal_cpyExtAddr( dstAddr.addr.extAddr, ptr1 ); } else { dstAddr.addr.shortAddr = BUILD_UINT16( pData[0], pData[1] ); } pData += Z_EXTADDR_LEN; attr1 = *pData++; // DstEPInt x = *pData; // SecuritySuite #if defined ( REFLECTOR ) if ( devAddr.addr.shortAddr == _NIB.nwkDevAddress ) { ZDApp_UnbindReqCB( 0, &devAddr, ptr, attr, cID, &dstAddr, attr1, x ); ret = ZSuccess; } else #endif { ret = (byte)ZDP_UnbindReq( &devAddr, ptr, attr, cID, &dstAddr, attr1, x ); } break; #endif #if defined ( ZDO_MGMT_NWKDISC_REQUEST ) case SPI_CMD_ZDO_MGMT_NWKDISC_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; scanChans = BUILD_UINT32( pData[3], pData[2], pData[1], pData[0] ); ret = (byte)ZDP_MgmtNwkDiscReq( &devAddr, scanChans, pData[4], pData[5], false ); break; #endif #if defined ( ZDO_MGMT_LQI_REQUEST ) case SPI_CMD_ZDO_MGMT_LQI_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); ret = (byte)ZDP_MgmtLqiReq( &devAddr, pData[2], false ); break; #endif #if defined ( ZDO_MGMT_RTG_REQUEST ) case SPI_CMD_ZDO_MGMT_RTG_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); ret = (byte)ZDP_MgmtRtgReq( &devAddr, pData[2], false ); break; #endif #if defined ( ZDO_MGMT_BIND_REQUEST ) case SPI_CMD_ZDO_MGMT_BIND_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); ret = (byte)ZDP_MgmtBindReq( &devAddr, pData[2], false ); break; #endif #if defined ( ZDO_MGMT_JOINDIRECT_REQUEST ) case SPI_CMD_ZDO_MGMT_DIRECT_JOIN_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); MT_ReverseBytes( &pData[2], Z_EXTADDR_LEN ); ret = (byte)ZDP_MgmtDirectJoinReq( &devAddr, &pData[2], pData[2 + Z_EXTADDR_LEN], false ); break; #endif #if defined ( ZDO_MGMT_LEAVE_REQUEST ) case SPI_CMD_ZDO_MGMT_LEAVE_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); MT_ReverseBytes( &pData[2], Z_EXTADDR_LEN ); ret = (byte)ZDP_MgmtLeaveReq( &devAddr, &pData[2], false ); break; #endif #if defined ( ZDO_MGMT_PERMIT_JOIN_REQUEST ) case SPI_CMD_ZDO_MGMT_PERMIT_JOIN_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); ret = (byte)ZDP_MgmtPermitJoinReq( &devAddr, pData[2], pData[3], false ); break; #endif #if defined ( ZDO_USERDESCSET_REQUEST ) case SPI_CMD_ZDO_USER_DESC_SET: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // User descriptor userDesc.len = *pData++; osal_memcpy( userDesc.desc, pData, userDesc.len ); pData += 16; // len of user desc ret =(byte)ZDP_UserDescSet( &devAddr, shortAddr, &userDesc, pData[0] ); break; #endif #if defined ( ZDO_ENDDEVICE_ANNCE_REQUEST ) case SPI_CMD_ZDO_END_DEV_ANNCE: // network address shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // extended address ptr = pData; MT_ReverseBytes( ptr, Z_EXTADDR_LEN ); pData += Z_EXTADDR_LEN; // security attr = *pData++; ret = (byte)ZDP_EndDeviceAnnce( shortAddr, ptr, *pData, attr ); break; #endif #if defined (ZDO_SERVERDISC_REQUEST ) case SPI_CMD_ZDO_SERVERDISC_REQ: // Service Mask uAttr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData++; // Security suite ret = (byte) ZDP_ServerDiscReq( uAttr, attr ); break; #endif #if defined (ZDO_NETWORKSTART_REQUEST ) case SPI_CMD_ZDO_NETWORK_START_REQ: ret = ZDApp_StartUpFromApp( ZDAPP_STARTUP_AUTO ); break; #endif default: break; } MT_SendSPIRespMsg( ret, cmd_id, len, respLen ); }
/********************************************************************* * @fn zdo_MTCB_MgmtBindRspCB() * * @brief * * Called to send MT callback response for Management Network * Discover response * * @param SrcAddr - Source address * @param Status - response status * * @return none */ void zdo_MTCB_MgmtBindRspCB( uint16 SrcAddr, byte Status, byte BindCount, byte StartIndex, byte BindListCount, apsBindingItem_t *pList ) { byte *msgPtr; byte *msg; byte len; byte x; uint8 protoVer = NLME_GetProtocolVersion(); /*Allocate a message of size equivalent to the corresponding SPI message (plus a couple of bytes for MT use)so that the same buffer can be sent by MT to the test tool by simply setting the header bytes.*/ /*In order to allocate the message , we need to know the length and this has to be calculated before we allocate the message*/ // One more byte for clusterID and DstAddrMode len = 2 + 1 + 1 + 1 + 1 + ( ( ZDP_BIND_DISCRIPTOR_SIZE + 1 + 1 ) * ZDO_MAX_BIND_ITEMS); // SrcAddr + Status + BindCount + StartIndex + BindListCount // + (maximum entries * size of struct) msgPtr = osal_mem_alloc( len ); if ( msgPtr ) { msg = msgPtr; //Fill up the data bytes *msg++ = HI_UINT16( SrcAddr ); *msg++ = LO_UINT16( SrcAddr ); *msg++ = Status; *msg++ = BindCount; *msg++ = StartIndex; *msg++ = BindListCount; osal_memset( msg, 0, ( ( ZDP_BIND_DISCRIPTOR_SIZE + 1 + 1) * ZDO_MAX_BIND_ITEMS) ); for ( x = 0; x < ZDO_MAX_BIND_ITEMS; x++ ) { if ( x < BindListCount ) { msg = zdo_MT_CopyRevExtAddr( msg, pList->srcAddr ); *msg++ = pList->srcEP; if ( protoVer == ZB_PROT_V1_0 ) { *msg++ = LO_UINT16( pList->clusterID); msg = zdo_MT_CopyRevExtAddr( msg, pList->dstAddr.addr.extAddr ); *msg++ = pList->dstEP; } else { *msg++ = HI_UINT16( pList->clusterID); *msg++ = LO_UINT16( pList->clusterID); *msg++ = pList->dstAddr.addrMode; if ( pList->dstAddr.addrMode == Addr64Bit ) { msg = zdo_MT_CopyRevExtAddr( msg, pList->dstAddr.addr.extAddr ); *msg++ = pList->dstEP; } else { *msg++ = HI_UINT16( pList->dstAddr.addr.shortAddr ); *msg++ = LO_UINT16( pList->dstAddr.addr.shortAddr ); // DstEndpoint will not present if DstAddrMode is not 64-bit extAddr } } pList++; } } MT_BuildAndSendZToolCB( SPI_CB_ZDO_MGMT_BIND_RSP, len, msgPtr ); osal_mem_free( msgPtr ); } }
/********************************************************************* * @fn zdo_MTCB_MgmtNwkDiscRspCB() * * @brief * * Called to send MT callback response for Management Network * Discover response * * @param SrcAddr - Source address * @param Status - response status * * @return none */ void zdo_MTCB_MgmtNwkDiscRspCB( uint16 SrcAddr, byte Status, byte NetworkCount, byte StartIndex, byte networkListCount, mgmtNwkDiscItem_t *pList ) { byte *msgPtr; byte *msg; byte len; byte x; byte proVer = NLME_GetProtocolVersion(); /*Allocate a message of size equivalent to the corresponding SPI message (plus a couple of bytes for MT use)so that the same buffer can be sent by MT to the test tool by simply setting the header bytes.*/ /*In order to allocate the message , we need to know the length and this has to be calculated before we allocate the message*/ if ( proVer == ZB_PROT_V1_0 ) { len = 2 + 1 + 1 + 1 + 1 + (ZDP_NETWORK_DISCRIPTOR_SIZE * ZDO_MAX_NWKDISC_ITEMS); // SrcAddr + Status + NetworkCount + StartIndex + networkListCount // + (maximum entries * size of struct) } else { len = 2 + 1 + 1 + 1 + 1 + (ZDP_NETWORK_EXTENDED_DISCRIPTOR_SIZE * ZDO_MAX_NWKDISC_ITEMS); } msgPtr = osal_mem_alloc( len ); if ( msgPtr ) { msg = msgPtr; //Fill up the data bytes *msg++ = HI_UINT16( SrcAddr ); *msg++ = LO_UINT16( SrcAddr ); *msg++ = Status; *msg++ = NetworkCount; *msg++ = StartIndex; *msg++ = networkListCount; osal_memset( msg, 0, (ZDP_NETWORK_DISCRIPTOR_SIZE * ZDO_MAX_NWKDISC_ITEMS) ); for ( x = 0; x < ZDO_MAX_NWKDISC_ITEMS; x++ ) { if ( x < networkListCount ) { if ( proVer == ZB_PROT_V1_0 ) { *msg++ = HI_UINT16( pList->PANId ); *msg++ = LO_UINT16( pList->PANId ); } else { osal_cpyExtAddr( msg, pList->extendedPANID ); msg += Z_EXTADDR_LEN; } *msg++ = pList->logicalChannel; *msg++ = pList->stackProfile; *msg++ = pList->version; *msg++ = pList->beaconOrder; *msg++ = pList->superFrameOrder; *msg++ = pList->permitJoining; pList++; } } MT_BuildAndSendZToolCB( SPI_CB_ZDO_MGMT_NWKDISC_RSP, len, msgPtr ); osal_mem_free( msgPtr ); } }