CC2420DK Overview and The ZigBee device objects (ZDO) Real-Time Systems Lab Dea Don Jeon
Context CC2420DK ZigBee example application plan Profile Builder Configurator IEEE Packet sniffer Z-Network Z-Trace ZigBee Specification ZDO
ZigBee example application plan Lower Layer Logical Node Type : PAN Coordinator Beeper GasSensor CompasSensor TempSensor GyroSensor EP=1, ClusterID=1 EP=2, ClusterID=2 EP=3, ClusterID=3 EP=4, ClusterID=4 EP=5, ClusterID=5 ZDO EP=0 Profile ID : 7 Zigbee Stack
Profile Builder
Configurator (Cont) User Devices Files OSAL_SEN.c : adds all the tasks to the task list SEN.c : User Applications SEN.h : Profile ID, Cluster ID and EndPoint are Defined Build Project Project files of Programmers Notepad (Editor)
Programmers Notepad ( Editor )
Configurator Devices
Configurator (Cont) Device Settings
Configurator (Cont) Device Settings Files NLMEDE.h : PHY Channel, Beacon order, related network layer management entity and etc. nwk_globals.h : NIB(Network layer information base) ex) Network topology, Maximum logical node ZDApp.c : ZigBee Device Application ZDApp.h : PAN_ID, Node status and etc Build Project
IEEE Packet sniffer
Z-Network Z-Network is an application that displays the hierarchical topology of a ZigBee network
Z-Trace Development application which can be used to communicate with a ZigBee target device development system.(RS-232)
ZDO ( ZigBee device objects ) is an application which employs Network and application support layer primitives to implement End Devices, Routers and Coordinators in Release 0.75 of the ZigBee protocol.
ZDO functions Initializing the APS, NWK, SSP and any other ZigBee device layer Assembling configuration information from following functions Device and Service Discovery Security Manager Network Manager Binding Manager Node Manager
Device and Service Discovery
Match_Desc_req example code void ZDApp_AutoFindDestination( byte endPoint) { byte ep = 0; zAddrType_t dstAddr; SimpleDescriptionFormat_t *sDesc; ep = endPoint; if ( ep == ZDO_EP ) return; // Can't do for ZDO SetLed( LED4, LED_OFF ); ZDApp_AutoFindMode_epDesc = afFindEndPointDesc( ep ); if ( ZDApp_AutoFindMode_epDesc ) { sDesc = ZDApp_AutoFindMode_epDesc->simpleDesc; // This message is sent to everyone dstAddr.addrMode = AddrBroadcast; dstAddr.addr.shortAddr = sDesc->AppProfId; ZDP_MatchDescReq( &dstAddr, NWK_BROADCAST_SHORTADDR, sDesc->AppProfId, sDesc->AppNumOutClusters, sDesc->pAppOutClusterList, sDesc->AppNumInClusters, sDesc->pAppInClusterList, 0 ); if ( keys & EVAL_SW4 ) { // Initiate a Match Description Request (Service Discovery) // for the mandatory endpoint ZDApp_AutoFindDestination( DLC03395_epDescMandatory.endPoint ); } DLC03395_App.c ZDApp.c
Match_Desc_req example code (Cont) buf = osal_mem_alloc( bufLen ); if ( buf ) { // Fill in the buffer pBuf = buf; *pBuf++ = LO_UINT16( nwkAddr ); // NWKAddrOfInterest *pBuf++ = HI_UINT16( nwkAddr ); *pBuf++ = LO_UINT16( ProfileID ); // Profile ID *pBuf++ = HI_UINT16( ProfileID ); *pBuf++ = NumInClusters; // Input cluster list if ( NumInClusters ) { pBuf = osal_memcpy( pBuf, InClusterList, NumInClusters ); } *pBuf++ = NumOutClusters; // Output cluster list if ( NumOutClusters ) osal_memcpy( pBuf, OutClusterList, NumOutClusters ); // Send the message stat = ZDP_FillAndSend( &afdstAddr, Match_Desc_req, bufLen, buf, AF_TX_OPTIONS_NONE ); // Free the memory osal_mem_free( buf ); } else stat = afStatus_MEM_FAIL; return stat; } #endif // ZDO_MATCH_REQUEST afStatus_t ZDP_MatchDescReq( zAddrType_t *dstAddr, uint16 nwkAddr, uint16 ProfileID, byte NumInClusters, byte *InClusterList, byte NumOutClusters, byte *OutClusterList, byte SecurityEnable ) { byte *buf; byte *pBuf; byte bufLen; afStatus_t stat; afAddrType_t afdstAddr; ZDP_ConvertToAFAddr( &afdstAddr, dstAddr ); // Calculate bufer length needed bufLen = ; // nwkAddr + ProfileID + NumInClusters + NumOutClusters bufLen += (NumInClusters + NumOutClusters); // Allocate the buffer ZDProfile.c
Match_Desc_req example code (Cont) afStatus_t ZDP_FillAndSend( afAddrType_t *dstAddr, byte clusterID, byte DataLength, byte *Data, byte txOptions ) { byte discoverRoute; if ( (dstAddr->addrMode == AddrBroadcast) || ((dstAddr->addrMode == Addr16Bit) && (dstAddr->addr.shortAddr == 0xFFFF)) ) { discoverRoute = true; } else discoverRoute = false; return ( afFillAndSendMessage( dstAddr, // DestAddr ZDP_AF_ENDPOINT, // Endpoint clusterID, // ClusterId 1, // TransCount FRAMETYPE_MSG, // FrameType &ZDP_transID, // TransSeqNumber NULL, // CommandType NULL, // AttribDataType NULL, // AttribId NULL, // ErrorCode DataLength, // DataLength Data, // Data txOptions, discoverRoute, AF_DEFAULT_RADIUS ) ); } ZDProfile.c
Match_Desc_req example code (Cont) afStatus_t afAddOrSendMessage( afAddrType_t *dstAddr, byte srcEndPoint, byte clusterID, afAddOrSend_t AddOrSend, byte FrameType, byte *TransSeqNumber, byte CommandType, byte AttribDataType, uint16 AttribId, byte ErrorCode, byte DataLength, byte *Data, byte txOptions, byte DiscoverRoute, byte RadiusCounter ) { …………………………….. afMultiHdr->frameType = FrameType; afMultiHdr->msgLen = 1; // Seed the size for the tranType/Count afMultiHdr->clusterID = clusterID; afMultiHdr->txOptions = txOptions; afMultiHdr->discoverRoute = DiscoverRoute; afMultiHdr->radiusCounter = RadiusCounter; /* Setup the destination address */ afMultiHdr->dstAddr.addrMode = (byte)dstAddr->addrMode; …………………………….. /* Increase CurrentTransCount */ afMultiHdr->transCount++; if (AddOrSend == SEND_MESSAGE) stat = afSendMulti(); return stat; } AF.c
Match_Desc_req example code (Cont) afStatus_t afSendMulti( void ) { ………………….. if ( afMultiHdr != NULL ) { // Find the single endpoint description epDesc = afFindEndPointDesc( afMultiHdr->srcEP ); if ( epDesc && (afMultiHdr->transCount > 0) ) { // Update the message trans type and count afMultiHdr->msg[0] = BUILD_UINT8( afMultiHdr->frameType, afMultiHdr->transCount ); ……………….. /* Send the packet */ if ( APSDE_DataRequest( &afMultiHdr->dstAddr, afMultiHdr->dstEP, profileID, afMultiHdr->clusterID, afMultiHdr->srcEP, (uint16)(afMultiHdr->msgLen), afMultiHdr->msg, afMultiHdr->txOptions, afMultiHdr->discoverRoute, afMultiHdr->radiusCounter ) == ZSuccess ) { stat = afStatus_SUCCESS; } ………………….. } afMultiHdr_t *afMultiHdr = (afMultiHdr_t*)NULL; // Global variables -- AF.c
Security Manager
Network Manager
Binding Manager
Node Manager
Q&A