消息发送到空中:

/********************************************************************** @fn      AF_DataRequest** @brief   Common functionality for invoking APSDE_DataReq() for both*          SendMulti and MSG-Send.** input parameters** @param  *dstAddr - Full ZB destination address: Nwk Addr + End Point.* @param  *srcEP - Origination (i.e. respond to or ack to) End Point Descr.* @param   cID - A valid cluster ID as specified by the Profile.* @param   len - Number of bytes of data pointed to by next param.* @param  *buf - A pointer to the data bytes to send.* @param  *transID - A pointer to a byte which can be modified and which will*                    be used as the transaction sequence number of the msg.* @param   options - Valid bit mask of Tx options.* @param   radius - Normally set to AF_DEFAULT_RADIUS.** output parameters** @param  *transID - Incremented by one if the return value is success.** @return  afStatus_t - See previous definition of afStatus_... types.*/
uint8 AF_DataRequestDiscoverRoute = TRUE;
afStatus_t AF_DataRequest( afAddrType_t *dstAddr, endPointDesc_t *srcEP,uint16 cID, uint16 len, uint8 *buf, uint8 *transID,uint8 options, uint8 radius )
{pDescCB pfnDescCB;ZStatus_t stat;APSDE_DataReq_t req;afDataReqMTU_t mtu;// Verify source end pointif ( srcEP == NULL ){return afStatus_INVALID_PARAMETER;}#if !defined( REFLECTOR )if ( dstAddr->addrMode == afAddrNotPresent ){return afStatus_INVALID_PARAMETER;}
#endif// Validate broadcastingif ( ( dstAddr->addrMode == afAddr16Bit     ) ||( dstAddr->addrMode == afAddrBroadcast )    ){// Check for valid broadcast valuesif( ADDR_NOT_BCAST != NLME_IsAddressBroadcast( dstAddr->addr.shortAddr )  ){// Force mode to broadcastdstAddr->addrMode = afAddrBroadcast;}else{// Address is not a valid broadcast typeif ( dstAddr->addrMode == afAddrBroadcast ){return afStatus_INVALID_PARAMETER;}}}else if ( dstAddr->addrMode != afAddr64Bit &&dstAddr->addrMode != afAddrGroup &&dstAddr->addrMode != afAddrNotPresent ){return afStatus_INVALID_PARAMETER;}// Set destination addressreq.dstAddr.addrMode = dstAddr->addrMode;if ( dstAddr->addrMode == afAddr64Bit )osal_cpyExtAddr( req.dstAddr.addr.extAddr, dstAddr->addr.extAddr );//数组 所以拷贝elsereq.dstAddr.addr.shortAddr = dstAddr->addr.shortAddr;//数字,直接赋值req.profileID = ZDO_PROFILE_ID;if ( (pfnDescCB = afGetDescCB( srcEP )) ){uint16 *pID = (uint16 *)(pfnDescCB(AF_DESCRIPTOR_PROFILE_ID, srcEP->endPoint ));if ( pID ){req.profileID = *pID;osal_mem_free( pID );}}else if ( srcEP->simpleDesc ){req.profileID = srcEP->simpleDesc->AppProfId;}req.txOptions = 0;if ( ( options & AF_ACK_REQUEST              ) &&( req.dstAddr.addrMode != AddrBroadcast ) &&( req.dstAddr.addrMode != AddrGroup     )    ){req.txOptions |=  APS_TX_OPTIONS_ACK;}if ( options & AF_SKIP_ROUTING ){req.txOptions |=  APS_TX_OPTIONS_SKIP_ROUTING;}if ( options & AF_EN_SECURITY ){req.txOptions |= APS_TX_OPTIONS_SECURITY_ENABLE;mtu.aps.secure = TRUE;}else{mtu.aps.secure = FALSE;}mtu.kvp = FALSE;req.transID       = *transID;req.srcEP         = srcEP->endPoint;req.dstEP         = dstAddr->endPoint;req.clusterID     = cID;req.asduLen       = len;req.asdu          = buf;req.discoverRoute = AF_DataRequestDiscoverRoute;//(uint8)((options & AF_DISCV_ROUTE) ? 1 : 0);req.radiusCounter = radius;
#if defined ( INTER_PAN )req.dstPanId      = dstAddr->panId;if ( StubAPS_InterPan( dstAddr->panId, dstAddr->endPoint ) ){if ( len > INTERP_DataReqMTU() ){stat = afStatus_INVALID_PARAMETER;}else{stat = INTERP_DataReq( &req );}}else
#endif // INTER_PAN{if (len > afDataReqMTU( &mtu ) ){if (apsfSendFragmented){stat = (*apsfSendFragmented)( &req );}else{stat = afStatus_INVALID_PARAMETER;}}else{stat = APSDE_DataReq( &req );}}/** If this is an EndPoint-to-EndPoint message on the same device, it will not* get added to the NWK databufs. So it will not go OTA and it will not get* a MACCB_DATA_CONFIRM_CMD callback. Thus it is necessary to generate the* AF_DATA_CONFIRM_CMD here. Note that APSDE_DataConfirm() only generates one* message with the first in line TransSeqNumber, even on a multi message.* Also note that a reflected msg will not have its confirmation generated* here.*/if ( (req.dstAddr.addrMode == Addr16Bit) &&(req.dstAddr.addr.shortAddr == NLME_GetShortAddr()) ){afDataConfirm( srcEP->endPoint, *transID, stat );}if ( stat == afStatus_SUCCESS ){(*transID)++;}return (afStatus_t)stat;
}

指定要发送到的目标地址dstAddr,包括目的网络号,目的短地址或长地址,目的端点

typedef struct
{union{uint16      shortAddr;ZLongAddr_t extAddr;} addr;afAddrMode_t addrMode;byte endPoint;uint16 panId;  // used for the INTER_PAN feature
} afAddrType_t;

指定发送的clustid,cID
指定要发送的数据长度,len
指定要发送的数据,buf,即asdu,应用层负载
指定发送选项options,比如是否加密 AF_SKIP_ROUTING

要向对方说明本地端点描述符:srcEP

typedef struct
{byte endPoint;byte *task_id;  // Pointer to location of the Application task ID.SimpleDescriptionFormat_t *simpleDesc;afNetworkLatencyReq_t latencyReq;
} endPointDesc_t;

其实只用到了结构体里的两个东东
  req.profileID = srcEP->simpleDesc->AppProfId;
  req.srcEP         = srcEP->endPoint;

空中到来的消息:

/********************************************************************** @fn          afIncomingData** @brief       Transfer a data PDU (ASDU) from the APS sub-layer to the AF.** @param       aff  - pointer to APS frame format* @param       SrcAddress  - Source address* @param       sig - incoming message's link quality* @param       SecurityUse - Security enable/disable** @return      none*/
void afIncomingData( aps_FrameFormat_t *aff, zAddrType_t *SrcAddress, uint16 SrcPanId,NLDE_Signal_t *sig, byte SecurityUse, uint32 timestamp )
{endPointDesc_t *epDesc = NULL;uint16 epProfileID = 0xFFFF;  // Invalid Profile IDepList_t *pList = epList;
#if !defined ( APS_NO_GROUPS )    uint8 grpEp = APS_GROUPS_EP_NOT_FOUND;
#endif  if ( ((aff->FrmCtrl & APS_DELIVERYMODE_MASK) == APS_FC_DM_GROUP) ){
#if !defined ( APS_NO_GROUPS )    // Find the first endpoint for this groupgrpEp = aps_FindGroupForEndpoint( aff->GroupID, APS_GROUPS_FIND_FIRST );if ( grpEp == APS_GROUPS_EP_NOT_FOUND )return;   // No endpoint foundepDesc = afFindEndPointDesc( grpEp );if ( epDesc == NULL )return;   // Endpoint descriptor not foundpList = afFindEndPointDescList( epDesc->endPoint );
#elsereturn; // Not supported
#endif    }else if ( aff->DstEndPoint == AF_BROADCAST_ENDPOINT ){// Set the listif ( pList != NULL ){epDesc = pList->epDesc;}}else if ( (epDesc = afFindEndPointDesc( aff->DstEndPoint )) ){pList = afFindEndPointDescList( epDesc->endPoint );}while ( epDesc ){if ( pList->pfnDescCB ){uint16 *pID = (uint16 *)(pList->pfnDescCB(AF_DESCRIPTOR_PROFILE_ID, epDesc->endPoint ));if ( pID ){epProfileID = *pID;osal_mem_free( pID );}}else if ( epDesc->simpleDesc ){epProfileID = epDesc->simpleDesc->AppProfId;}if ( (aff->ProfileID == epProfileID) ||((epDesc->endPoint == ZDO_EP) && (aff->ProfileID == ZDO_PROFILE_ID)) ){{afBuildMSGIncoming( aff, epDesc, SrcAddress, SrcPanId, sig, SecurityUse, timestamp );}}if ( ((aff->FrmCtrl & APS_DELIVERYMODE_MASK) == APS_FC_DM_GROUP) ){
#if !defined ( APS_NO_GROUPS )      // Find the next endpoint for this groupgrpEp = aps_FindGroupForEndpoint( aff->GroupID, grpEp );if ( grpEp == APS_GROUPS_EP_NOT_FOUND )return;   // No endpoint foundepDesc = afFindEndPointDesc( grpEp );if ( epDesc == NULL )return;   // Endpoint descriptor not foundpList = afFindEndPointDescList( epDesc->endPoint );
#elsereturn;
#endif      }else if ( aff->DstEndPoint == AF_BROADCAST_ENDPOINT ){pList = pList->nextDesc;if ( pList )epDesc = pList->epDesc;elseepDesc = NULL;}elseepDesc = NULL;}}

空中到来的消息经过协议栈的秘密传输,终于在af中被暴露出来,
aff,接收到的aps层帧结构,包括如下信息

typedef struct
{byte FrmCtrl;byte XtndFrmCtrl;byte DstEndPoint;byte SrcEndPoint;uint16 GroupID;uint16 ClusterID;uint16 ProfileID;uint16 macDestAddr;byte wasBroadcast;byte apsHdrLen;byte *asdu;byte asduLength;byte ApsCounter;uint8 transID;uint8 BlkCount;uint8 AckBits;
} aps_FrameFormat_t;

其中重要信息有:目的端点,源端点,组号,clustid,profileid,asdu(应用层负载),asdu len

SrcAddress,源地址,包括如下东东

typedef struct
{union{uint16      shortAddr;ZLongAddr_t extAddr;} addr;byte addrMode;
} zAddrType_t;

SrcPanId,源网络号
sig,信号强度
SecurityUse,是否加密
timestamp,时间戳

可见,除了SrcPanId,sig,timestamp这几个元素是下层自动添加的,其他参数和使用afIncomingData发送过来的参数对应。

以下待续:
绑定是  
源端点《--》目的地址+目的端点
每次建立一个绑定,都会在自身设备中创建一条这样的记录,
这样以后在发送数据的时候,只要指定源端点,而不必指定目的地址和目的端点,协议栈会从绑定表中直接读取出来目的地址和目的端点,将数据发给他们

而设备接收时,就跟平常一样接收就行。
但是还有一个clusterlist,似乎有点疑惑?答案:
1.绑定时使用的如果是clusterlist,双方可以通过绑定方式进行clusterid属于clusterlist的数据通信
2.双方简单描述符里的对应clusterlist都有同一个clusterid,则可以通过指定地址方式进行此clusterid的数据通信。
3.一般发命令的是outclusterlist,接收命令并回应的是inclusterlist,但是实验中发现没有这个规定。只要双方通信端点的clusterlist的方向相反,内容一样就可以对clusterlist的clusterid通信。
http://blog.csdn.net/songqqnew/article/details/8684315

转载于:https://www.cnblogs.com/-song/archive/2013/02/24/3331825.html

zigbee 空中消息溯源相关推荐

  1. zigbee学习参考(1~42 )

    [原创]ZigBee学习之1--SPI&LCD - 小组 - EDN China [原创]ZigBee学习之2--SPI&LCD - 小组 - EDN China ZigBee学习之3 ...

  2. zigbee bind, ZDO_RegisterForZDOMsg, zcl_registerForMsg

    绑定方法1: 1.设备A先允许绑定 zb_AllowBind( myAllowBindTimeout ); * @param       timeout - The number of seconds ...

  3. 业务消息中心系统设计与实现(一)

    目录 解决问题场景? 那么这款内部业务消息中心需要满足哪些功能呢? 哈喽小伙伴,我是kilde,和有需要的小伙伴分享一个业务消息中心的设计思想与实现,喜欢的小伙伴可以点赞关注博主,觉得有用的也可以打赏 ...

  4. zigbee----over-the-air-upgrad学习笔记(1)

    这是完全由英文文档翻译的,译得 不好,紧作为自己的学习笔记 ZigBee集群库由单独的章节组成,如本章.有关所有章节和文档的列表,请参见ZigBee集群库中列出的文档列表和所有章节.章节之间的引用使用 ...

  5. 深度解析NRF24L01

    本文将深度解析一款烂大街的无线芯片,NRF24L01(及国产完全兼容的SI24R1).实在是现在网上很多写NRF24L01的文章抓不到重点,一些冷门用法没人写,就写了这个文章.推荐选用SI24R1,原 ...

  6. STM32WL55-NUCLEO开发(1)----STM32WLLoRaWAN介绍

    STM32WL55-NUCLEO开发.1----STM32WL&LoRaWAN介绍 无线通信技术 STM32WL型号分布 STM32WL可优化项 LORA的前身 LORA技术方面 全球LORA ...

  7. silabs tools

    Silabs tools  1.介绍   与大多数嵌入式开发技术一样,Silicon Labs提供了一套工具,允许您(开发人员)使用Silicon Labs无线网络产品创建产品.每个Silicon L ...

  8. 2.4G上的无线共存问题

    2.4 GHz无线共存已经存在至少20年了.真正的问题在于,不同的2.4 GHz无线技术满足了同一设备的不同需求,因此必须要在同时运行而不会出现明显的性能退化.本文针对对WiFi,zigbee和thr ...

  9. Wireshark 4.0.0 如约而至,这些新功能更新的太及时了!

    正如标题所述:Wireshark 4.0.0如约而至! 什么是 Wireshark? Wireshark 是世界上最流行的网络协议分析工具(我们一般称之为"抓包工具"),主要用于故 ...

最新文章

  1. 测试掌握的Linux解压,轻松掌握Linux压缩/解压文件的方法
  2. 过滤选择器——可见性过滤选择器
  3. ImCash:币圈英文术语大全
  4. kotlin集合操作符——总数操作符
  5. 使用实例_EM菌使用实例
  6. 为EasyUI 的Tab 标签添加右键菜单
  7. [zz]libev 简介
  8. 云盘运用了计算机技术,360云盘咋找出来
  9. JAVA ThreadPoolExecutor线程池
  10. NLP—6.数据不平衡处理
  11. XML-RPC协议【转】
  12. .Net中的并行编程-6.常用优化策略
  13. dorado java_[Java教程]dorado 7 使用总结
  14. python自动拨号_python adsl拨号
  15. 简单的微信使用技巧,你需要掌握的技巧
  16. Windows快捷键小记
  17. 【LOJ2542】【PKUWC2018】—随机游走(Min-Max容斥+树形dp+FMT)
  18. ASP.NET增加微信公众号功能
  19. 浅谈二叉查找树、AVL树、红黑树、B树、B+树的原理及应用
  20. python调用DLL/EXE文件截屏的比较

热门文章

  1. apache开源项目--Sirona
  2. 研发和人力资源发展模式对比研究
  3. 数据库升级后,准备使用原有数据文件启动数据库
  4. 踏平RecyclerView使用的各种坑,跟ListView和GridView说拜拜
  5. CSS3 -webkit-animation(动画)
  6. 卷积神经网络(Convolutional Neural Networks,CNNS/ConvNets)
  7. Java基础—反射—简单介绍
  8. JVM学习笔记之-JVM性能监控-JVM监控及诊断工具-命令行方式
  9. [数据结构] - 串
  10. loj10200. 「一本通 6.2 练习 3」Goldbach's Conjecture