测试环境:
一个ZC ,5个ZED ,ZED 是电池设备 (均采用 zstack 1.2.2 或1.2.2a)
操作:
重复重启 ZC, 造成 ZED 断网寻网 。
目的:
验证 寻网一段时间,然后休眠一段时间 的新逻辑,(rejoin scan====》 rejoin backoff====》rejoin scan)
代码上增加:
在应用层 loop 中的 ZDO_STATE_CHANGE 事件中, 当DEV_NWK_DIS 时, 调用HAL_LED_BLINK() 函数 让LED1 一直闪
当DEV_NWK_BACKOFF 时, 调用HAL_LED_SET() 函数 将LED1 关闭
这样 断网的时候 LED1 就一直闪, 休眠(rejoin backoff)的时 ,灯就熄灭。
发现问题:
重刷了很多次之后, 发现 有些设备 断网后,LED1 一直闪,rejoin scan 的时间过完 ,还是无法进入rejoin backoff。
用抓包软件抓了一下, 发现有两种情况
情况1 : 设备是有发beacon request 出来的。 但是ZC 启动完成后, 设备仍然无法进入网络。 情况2: 设备只是闪LED1 ,但是 实际上没有发beacon request出来
以上两种情况 只是 设备无法 入网的 现象。
针对情况1 我的猜测:
让我不明白的 为甚么, 设备过了rejoin scan 规定时间后, 无法进入rejoin back off呢?
针对情况2 我的猜测 : 或者是设备已经 进入rejoin backoff 了,但 LED1 没有关闭。(即 设备的state 改变了 , 但是没有把改变 的状态 传到 应用层 的ZDO_STATE_CHANGE 事件上)
VV:
顺便把数据包附下上去,情况1下设备的devstartmode是什么,有没有可能出现过节点在发rejoin request的时候,刚好把协调器断电了?
情况2,协议栈里面其他地方也有用到这个LED闪的,
MarS:
回复 VV:
终于等到你!!!
情况 1 devstart mode????
devstate 吗?? 此时 设备的 状态 是DEV_NWK_DIS,(很抱歉 log 没存起来)
如果是1.2.2的话,会有两种情况。
1. 设备发出rejoin request, 但是 协调器就是永远不response, ( 这个暂时没有log)
2. 设备发出rejoin request, 协调器也响应了, 但是设备还是依然 处于寻网状态, 除非 协调器开permit join 。
log:
情况2, 这个很容易复现的,只要你把 闪灯 的操作 放在 ZDO_STATE_CHANGE 事件里 的DEV_NWK_DIS case 中。
几个rejoin logic 下来,基本就可以出现了。
另外有个问题非常想请问你, rejoin backoff 的默认值 设置为30分钟 可以吗?
1800000 虽然没有超过uint32 , 但真的可以吗?
MarS:
回复 VV:
VV,
情况1 的 log 抓到了。
52 条: 发orphan notification,
92 条: 发了rejoin request, 有ACK, 但是没有rejoin response
接着就一直 beacon 下去了!!!!
log :
另外一个log 说明一下:
log :
582条~599条: 终端 发了3次rejoin request, 协调器才响应了 成功。
但实际上 它还是 依然 继续 寻网 发beacon
等到1336条 : 我开了 协调器的permit join。
这时 终端设备 才 association 成功 进入网络。。。。
所以我不明白,既然都 rejoin response 告诉成功了,为什么后面还要 开permit join 才能进来
VV:
回复 MarS:
你使用的Rejoin是自己写的吗?怎么是unsecured rejoin,你可以看到你的rejoin是没有加密的,所以是unsecure rejoin,然后还需要trust center去授权的,如果permit join在关掉的情况下,就不允许入网了。
MarS:
回复 VV:
谢谢 VV
第一 : Rejoin 不是我自己写的。 我也奇怪为什么 就变成 unsecure rejoin 了, (前面一个 (第592条)还是加密的rejoin。)
第二,撇开加密的问题, 为什么 不加密的rejoin request 反倒有 rejoin response。而且rejoin response的 返回 是允许入网的。
谢谢!
VV:
回复 MarS:
你的0xF292这个是一个终端设备,但是在发起Rejoin Request确没有Data Request发出来。
你在协议栈做什么改动?
这个问题复现的流程是什么
MarS:
回复 VV:
VV:
1. rejoin 的code 我没有改动,使用的是HA1.2.2.a 原有的 那套逻辑(rejoin scan —> resjoin backoff —> rejoin scan)
2. 为什么突然就变成unsecured rejoin, 这个我也很诧异, 加不加密不是 在工程编译的时候 使能 SECURE=1 就开启了吗?
程序运行过程中 应用层 的软件难道还可以 修改为不加密 吗?
所以 这个肯定不是 客户应用代码 造成的。。。。
我怀疑是 NWK key 丢失了, 但是 抓包过程中又无法判断 NWK key 什么时候 更新 什么时候传输到 终端节点! 3. 所有的终端设备 发起rejoin request 都 必须 发起 data request 吗?
这个我倒没留意, 但是如果终端设备 是RFD_RCVC_ALWAYS_ON=TRUE, 难道 发起rejoin request 还需要 发起data request吗??
这个 规定 在zstack 中 哪里说明?
MarS:
回复 VV:
4. 我现在 也还不是很清楚 百分百 复现该问题的 流程 是怎样?
以下两种情况下 出现过,终端设备无法 rejoin到 网络中, 除非开启ZC的 permijoin 。
====》 边缘节点情况,
如下图,我们在一间100平米的房间内 不同位置布置了终端设备,
这些终端设备 我们在程序上 设置 每6秒 就发送一条 msg (IEEE request) 到 协调器
放置一个晚上之后, 第二天早上 红色 圈中的 终端设备 均出现 断网 无法连接 协调器的情况
然后重新开启 permitjoin 的 时候 也基本都可以 重新加入, (只是它们都使用了新的 短地址)
=====》 重复复位协调器 并删除Association List 。
(PS: 删除Association List 只是我们自定的一个功能, 主要是防止ZC 列表撑满了僵尸设备, 这里只是说明有过类似操作 造成终端设备无法入网)
多次 操作复位之后, 就出现了 终端设备 无法rejoin的 现象。
具体可以参考 post :https://e2e.ti.com/support/wireless_connectivity/zigbee_6lowpan_802-15-4_mac/f/158/p/506481/1850037#1850037 谢谢!
MarS:
回复 VV:
VV:
不知道你是否记得 自己 发的一篇关于ZigBee 状态机的文章:http://www.deyisupport.com/question_answer/wireless_connectivity/zigbee/f/104/t/104629.aspx
在 第 20 点 DEV_NWK_REJOIN状态到DEV_END_DEVICE_UNAUTH(20)
有这么一句话:
如果在ZDApp_RestoreNwkKey( uint8 incrFrmCnt ),读取network key错误,或者之前保存的network key已经不在的情况下,那么就发了Unsecure Rejoin的方式。
读取network 可以错误 的几率,我相信 非常少吧!
那么 network key 不见呢????,这是有可能! 比如终端设备 寻网 过程中 自己把 NWK KEY 清除, 然后把NV flash 里面的东西全清了!!
我假设 一下, 如果 终端设备发送了Rejoin Request以后,收到父设备回复的Rejoin Response消息,那么程序会次进入到ZDApp_ProcessNetworkJoin( void
) , 进行 Verify NWK key is available before sending Device_annce 对吧!
else if ( devState == DEV_NWK_ORPHAN ||<strong><span style="color:#ff0000;">devState == DEV_NWK_SEC_REJOIN_CURR_CHANNEL</span></strong> ||devState == DEV_NWK_TC_REJOIN_CURR_CHANNEL ||devState == DEV_NWK_TC_REJOIN_ALL_CHANNEL ||devState == DEV_NWK_SEC_REJOIN_ALL_CHANNEL ){ ......................// results of an orphaning attempt by this device// results of an orphaning attempt by this device<strong><span style="color:#ff0000;"> if (nwkStatus == ZSuccess)</span></strong>{//When the device has successfully rejoined then reset retryCntretryCnt = 0;// Verify NWK key is available before sending Device_annceif ( ZG_SECURE_ENABLED && ( ZDApp_RestoreNwkKey( TRUE ) == false ) ){// wait for auth from trust centerZDApp_ChangeState( DEV_END_DEVICE_UNAUTH );// Start the reset timer for MAX UNAUTH timeZDApp_ResetTimerStart( MAX_DEVICE_UNAUTH_TIMEOUT );}但是在此之前 终端设备 进入 predevState == DEV_NWK_SEC_REJOIN_ALL_CHANNEL 时,
会把NWK KEY 清掉。。。。
这时ZDApp_ResetTimerStart( MAX_DEVICE_UNAUTH_TIMEOUT ); 时间一到!!!! 是不是就悲剧了!!!!
chengzi chen:
回复 MarS:
请问你这个问题解决了吗? 我们做的设备这两天也遇到了同样的问题了,一个协调器组网带了20个end device,过了一个晚上后发现有15个终端设备处于失去父节点状态,一直不能重新入网,其余的5个设备连接状态正常,搜索了相关问题资料,如 http://www.kaleidscope.cn:1020/archives/992 做了修改测试,还是不行,也是要协调器端开启permitjoin才能重新入网。