使用的是NXP公司的JN5169模块,然后SDK是4170的
ZIGBEE 中我犯下的几个问题:
1.认为
错误点:当产生该事件ZPS_EVENT_NWK_JOINED_AS_ROUTER的时候设备就已经算是完整的加入了网络中去
实际上:当该事件BDB_EVENT_NWK_STEERING_SUCCESS产生的时候设备才是真正的加入到了网络中去
NXP的设备入网流程:
这里有一个eNS_State 用来指示 NWK_STERRING 的当前状态,总共有下面几个阶段
E_NS_IDLE,
E_NS_WAIT_DISCOVERY,
E_NS_WAIT_JOIN,
E_NS_TCLK_WAIT_NODE_DESC_RES,
E_NS_WAIT_AFTER_NWK_JOIN,
E_NS_TCLK_WAIT_SEND_REQ_KEY,
E_NS_TCLK_WAIT_LEAVE_CFM,
通过BDB_vNsStateMachine()来对不同的阶段去进行处理
1.通过调用 BDB_eNsStartNwkSteering()判断是否需要执行网络发现
2.vNsDiscoverNwk()使用该函数去查找网络eNS_State = E_NS_WAIT_DISCOVERY; 如果找到了就会返回
BDB_vSetAssociationFilter()在查找网络的时候会通过调用这里去过滤到信号不行的网络
ZPS_bAppPassBeaconToHigherLayer()上面的又会调用该函数,这个函数里面会有LQI的判断的内容,如果检查到得网络的LQI小于
预先设置的值默认是的是30的话那么就会放弃这个网络,所以我也在想这里如果去掉或者把LQI默认值改小一些会不会好一些,
前面在论坛里面也看到过别人发的说是把这部分屏蔽掉之类的用来增加重入网的时候的距离。
相关论坛地址https://community.nxp.com/message/1113798
ZPS_eAplZdoDiscoverNetworks()通过调用该函数去查找具体某个通道下面是否有网络
3.vNsTryNwkJoin() 尝试加入网络这里 eNS_State = E_NS_WAIT_JOIN; 如果成功返回,失败的话 回到“2 ”的部分
在这里的话会去尝试加入所有的之前在同一个通道下面找到的网络,这里选择加入的条件就是首先Permitjoin要是被允许的,然后
要加入的网络的 EXID =0(任意的产生的) 或者是之前已经事先定好的每个网络会重复加入三次
通过调用ZPS_eAplZdoJoinNetwork()函数,但是我之前调用该函数出现过“ZPS_NWK_ENUM_INVALID_REQUEST”这个问题,然后就导致我设备
怎么都加不进去网络,去官方问了他们说是什么参数不正确,但想了下这里我也没有进行操作啊,NXP那边的话不知道是不是放弃
ZIGBEE这块的内容了,FAE那边基本上也给不了什么帮助,SDK也很久每更新了
4. 处理尝试入网返回的结果如果入网失败的话会返回失败的原因然后回到“3”
如果入网失败的话会返回失败的原因
如果成功的话,会产生ZPS_EVENT_NWK_JOINED_AS_ENDDEVICE/ZPS_EVENT_NWK_JOINED_AS_ROUTER这样的事件,之后的话会根据之前
设置的 LINK_KEY ,然后去解密接收到的 NETWORK—KEY
eNS_State = E_NS_WAIT_AFTER_NWK_JOIN;
同时这里会打开一个定时器 ZTIMER_eStart(u8TimerBdbNs, ZTIMER_TIME_MSEC(300));
通过这个定时器的话主要是调用 BDB_vNsTimerCb() 函数
*** 第四步的时候产生了入网宣告 就是004d相关的内容
5.BDB_vNsTimerCb() 这一步其实就是到了这个定时器的回调函数中去进行处理,
case:E_NS_WAIT_AFTER_NWK_JOIN
vNsStartTclk()
vNsTclkSendNodeDescReq()//发送节点描述符请求,作为密钥交换的一部分
6. E_NS_TCLK_WAIT_SEND_REQ_KEY 如果ZPS_EVENT_TC_STATUS 的状态正确的话那么就会vNsAfterNwkJoin()进入该函数,然后
产生BDB_EVENT_NWK_STEERING_SUCCESS时间,同时宣告入网,这个时候才是真正的入网了,如果这个时候收到的是错误的状态的话
会去离网
总结:
可以通过调节BDB_vSetAssociationFilter 调节LQI 来提高获取网络的灵敏度。
附录:
BDB_eNsStartNwkSteering()函数的功能:
1.如果节点已经在网络里面了那么它会打开网络大约180ms,从而允许其他设备加入网络这个时间可以通过 bdbcMinCommissioningTime
进行设置,另外之前在这个方面碰到了个问题就是当设备入网成功之后也会自动打开这个网络180s,因此这个时候之前我们在做设备的时候
就会出现当路由设备加入网络之后(这里默认的是收到004d的消息)关闭了入网许可,但是其实这个时候还没有走完整个流程,因此当设备
真正入网了之后就会打开网络允许其他设备加入网络,这个时候是否允许其他设备入网就变得不可控的,vNsSendPermitJoin()该函数
就是打开网络允许其他设备入网 。
2.如果终端设备和路由设备都不在网络里面
a:在 primary channel 上面去查找网络 首选通道一般就是25 20 15 11 这些的
#define BDB_SECONDARY_CHANNEL_SET (0x07FFF800 ^ BDB_PRIMARY_CHANNEL_SET) /* bdbSecondaryChannelSet e.g. (0x07FFF800 ^ BDB_PRIMARY_CHANNEL_SET) */
#define BDBC_TL_PRIMARY_CHANNEL_SET (0x02108800) /* bdbcTLPrimaryChannelSet */
b:查找网络完成之后会去尝试加入之前在各个通道下面查找到的网络
C:当加入网络成功之后 bbdbNodeIsOnANetwork 将会设置为TRUE
d:如果“b”的过程失败了,那么就会重新选择BDB_SECONDARY_CHANNEL_SET 所对应的通道去进行查找
e:这里说到如果ApsTrustCenterAddress 的地址不是0xfffffffffff这样的,节点描述符就会发送去用来检查R21的信任中心,
如果是的话将会执行TCLK (Trust center link key exchange) 就是密钥交换的流程,如果这个流程中有任何一个环节出错的话
设备就会离网,之前的流程就相当于都不正确,那么这样的话即使收到了入网宣告之后其实设备也并非就一定加进网络里面去了,
所以后面也就会出现收到了004d 之类 又收到8048(离网)这样的情况
f:当设备成功入网了之后,就会产生BDB_EVENT_NWK_STEERING_SUCCESS的事件,同时会广播允许入网