NXP zigbee 学习文档:https://www.nxp.com/pages/jn516x-7x-zigbee-3-0:ZIGBEE-3-0
《关于zigbee设备入网之关联(association)方式入网流程抓包分析》
恩智浦的zigbee 3.0协议栈中,已经实现了zigbee联盟定义的大部分标准Cluster,用户可以直接使用接口开发。这些标准的Cluster可以和其他符合zigbee标准的厂商产品直接对接使用。但是有些客户想实现自己私有的Cluster,NXP的协议栈预留了相应的接口,为了加快开发,本文将演示如何添加私有的Cluster进行透传。
1. 基本概念
Cluster由属性(Attribute)以及命令(Command)组成。属性是一个数据集,由设备保存,可以在设备间传递。
例如一个Thermostat cluster包含的相关属性如下:
A.当前温度
B.最小温度
C.最大温度
Zigbee联盟将定义好的标准Cluster收录到了ZCL库中,每个Cluster被分配了一个唯一的16位Cluster ID,从0xFC00开始则是厂家自定义的Cluster ID。
2. Cluster中的Server和Client
(1) Cluster Server:
用来存储attribute和接收command,并处理它们
(2) Cluster Client
用于通过发送命令来操纵相应Cluster Server中的属性。通常使用“write”命令设置属性值,使用“read”命令获取属性值。
3. 添加自定义的Cluster
增加Cluster的主要步骤如下:
3.1 定义Cluster的相关文件DemoCluster.c和DemoCluster.h
① 在DemoCluster.h中定义CLUSTER_ID_Demo的值为0xFC00
#define CLUSTER_ID_Demo 0xFC00
② 定义Demo Cluster,例如:
③ 定义需要发送的Command,例如:
④ 自定义发送Payload的类型,常见的有字符串,整形。可以是单个,也可以是数组,例如:
⑤ 实现Client以及Server之间的发送和接收函数。
3.2 在Profile中的Endpoint增加对应的Cluster
① 在Switch的Cluster实例结构体中增加Cluster实例:
② 在dimmer_switch.h中Switch的设备结构体tsZLO_DimmerSwitchDevice中增加下面的定义:
③ 在dimmer_switch.c中的eZLO_RegisterDimmerSwitchEndPoint增加以下语句:
④ 增加Cluster实例到Coordinator的Cluster实例结构体中:
⑤ 在control_bridge.h中的设备结构体tsZLO_ControlBridgeDevice增加如下定义:
⑥ 在control_bridge.c中eZLO_RegisterControlBridgeEndPoint增加以下语句:
3.3 在ZPS Config中增加Cluster
(1) 在“DimmableSwitch”中右键点击“End Point ‘SWITCH’ (1)”
(2) 右键点击HOME_AUTOMATION profile
(3) 选择New Child -> Input Cluster以及New Child -> Output Cluster
(4) 选择” undefined “,找到Properties一栏,将Cluster设置为Demo
(5) 选择“apduZCL”作为接收的APDU
(6) 同样在Coordinator的“End Point ‘ZLO’ (1)”中也添加Demo Cluster
3.4 修改JN-AN-1216中的Coordinator的zcl_options.h
增加宏定义CLD_DEMO,DEMO_CLIENT,同样在JN-AN-1219中的Switch中增加CLD_DEMO,DEMO_SERVER宏定义,重新编译固件。
4. 验证增加的Cluster
4.1 Coordinator发送Simple Descriptor Request
通过ubiqua抓空中包,可以看到Simple Descriptor Response包含了定义的Demo Cluster(0xFC00)。
在Sniffer Log中可以看到,添加的自定义Cluster是0xFC00,分别在Application Input Clusters List 以及Application Onput Clusters List中。
4.2 验证Command的发送和接收
Coordinator发送Command给Switch,在Coordinator端调用定义好的发送函数eCLD_DemoCommandClientSend,代码如下:
通过Sniffer,我们可以看到,Coordinator发送的Private Cluster的包,以及Switch发送给Coordinator的Default Response。
在Private Cluster包中的详细信息可以看到,Coordinator发送的Command的值为0,与上面定义的发送函数传递的参数一致。
4.3 Switch发送带有Payload的command给Coordinator
Switch发送Command给Coordinator,在Switch端调用定义好的发送函数eCLD_DemoCommandServerSend,另外Payload中u8DemoId和u8DemoStatus的值分别为1和10。
通过sniffer,我们可以看到,Switch发送的Private Cluster的包,以及Coordinator发送给Switch的Default Response。
在Private Cluster包中的详细信息可以看到,Switch发送的Command的值为2,Payload包括是01 和0A,与上面发送函数传递的参数一致。
至此,添加私有的Cluster已经可以实现Client和Server之间互相通信(发送和接收Command)。
另外关于恩智浦实现的ZCL库的代码,相当于是开源的,位于SDK目录下面。在目录中可以看到ZCL库实现的所有代码。
实际上,不管是私有的,还是标准的Cluster,NXP都提供了相关的接口,例如:命令的发送实际上是由yeZCL_CustomCommandSend完成的,而命令的接收实际上是由eZCL_CustomCommandReceive完成的。
5. 参考资料
(1) JN-UG-3115-ZigBee Cluster Library (for ZigBee 3.0).pdf
(2) ZigBee Cluster Library Specification Revision 6
(3) JN-SW-4170