我要建立的网络比较简单,只有终端和协调器两种设备,但现在遇到一个关于PAN ID冲突的问题,如下:(已定义NV_RESTORE)
1、启动协调器C1,PAN ID设为0xFFFF,假设C1实际所建网络的PAN ID为0x1234。
2、启动终端E1,之后会连接到C1所建的网络0x1234。
3、关闭C1、E1。
4、启动协调器C2,PAN ID设为0x1234,使C2实际所建网络的PAN ID固定位0x1234。
5、启动协调器C1,问题出来了,C1仍然会建立PAN ID为0x1234的网络,与C2的PAN ID冲突。
我抓包发现,只要协调器建立了一个网络并连接过一个设备之后,再将它重启时,就不会再通过发送一个信标请求来进行主动扫描(用于检测PAN ID是否已被占用),这就造成了上面这种情况:C1重启时,不再检测PAN ID是否被占用,而是直接建立网络。
我对协调器的启动过程进行跟踪调试,发现此种情况应该是由NV条目ZCD_NV_STARTUP_OPTION造成的,这个NV条目的值决定了协调器启动时的devStartMode。当这个NV条目指示需要恢复网络状态时,协调器的启动模式为MODE_RESUME,造成在ZDO_StartDevice函数中不会去调用NLME_NetworkFormationRequest(创建网络),而是直接恢复之前的网络,不判断PAN ID是否冲突。
以上是我的测试和推测,可能有误。不知这种情况该怎样解决?
AndyChen:
没人能解答一下吗?
VV:
回复 AndyChen:
你好,确实存在这样的情况。
正常的应用场景是C1建立了一个0x1234的PANID网络,然后C2上电以后会去检测在该信道上面已经存在的网络,如果有PANID和自己想建立的网络的是冲突的,那么就会选择另外一个PANID。
如果现在按照你的情况下,你需要在设备正式启动前,去扫描信道或发现其他网络,然后在选择是否继续前一次的网络,还是重新建一个新的网络。
我之后把相关的API告诉你,可以测试下。
谢谢!
AndyChen:
回复 VV:
非常感谢!!!
有如下两点:
1、如何设置使协调器在启动时扫描其他网络;
2、若发现原先的PAN ID被占用,需要更换PAN ID重新建立网络时,如何将原先所连接的设备都拉入新的网络中。
AndyChen:
回复 VV:
跪求API,谢谢
AndyChen:
回复 VV:
我一直在等待
VV:
回复 AndyChen:
ZDApp_NetworkDiscoveryReq去发现网络,在ZDO_NetworkDiscoveryConfirmCB获取扫描的结果,
如果有冲突可以使用ZDOInitDevice,重新建网
AndyChen:
回复 VV:
似乎这样做只是协调器重新建立了网络,但之前连接的那些终端都不能自动连入新网络中。
在“zigbee2007协议规范”中有讲到,网络层有一个“网络更新”(Network Update Command)命令,可以用来更新网络中所有设备的PAN ID(网络管理器,即协调器,向全网广播新的PAN ID),不知在zstack是否有实现这个功能,API在哪里?
AndyChen:
回复 VV:
NLME_SendNetworkUpdate(),我就说嘛,不应该没有的。
这就说明了zstack是有这个功能的,具体怎么实现,大致看了下,还是不好下手。
你之前给我的两个API(搜索PAN ID,新建网络),和这个API,似乎都不应该是由我来调用的,这样用起来就太麻烦了,还容易出问题。
在zstack应该存在一个更上层、或更简单的方法,来让我执行着一连串的任务:检测PAN ID冲突 — 找出一个可用的PAN ID — 在整个网络更新PAN ID。而不应该是我找各种的API来拼凑。
注明一下我的方案:
一个协调器 — N个终端(无路由器)
协调器配置:HAL_UART=TRUE , NWK_MANAGER, NV_INIT, NV_RESTORE
终端配置:HAL_UART=TRUE, NV_INIT, NV_RESTORE请指教,谢谢
botong Liu:
我也发现了类似的问题,我使用的是ZHA-V1.2.2版本的协议栈;
我在f8wConfig.cfg里面-DZDAPP_CONFIG_PAN_ID=0x64;预编译NV_RESTORE和NV_INIT;编译烧录,实验结果是建网时发现有冲突就会往上加1;复位重启网络之后就只执行MODE_RESUME。
这时擦徐网络信息,CO1先上电,建网成功(信道==11,网络ID==0x64)后断电,CO2再上电,建网也成功(信道==11,网络ID==0x64),CO1接着上电,两个网络之间的PANID冲突了。
TI协议栈重启之后没有再去判断PANID的冲突是有缺陷的,因为在一定范围内,并不知道用户什么时候上电使用的。不知道有没有好的解决方法。
botong Liu:
回复 VV:
您好:VV
我使用ZHA-V1.2.2的协议栈,按照你给的API在if ( startMode == MODE_RESUME )里面添加ZDApp_NetworkDiscoveryReq( runtimeChannel , 5 )去发现网络;但是在ZDO_NetworkDiscoveryConfirmCB里面设断点,仿真都进不去。而且ZDApp_NetworkDiscoveryReq返回值不等于ZSuccess。这该怎么解决冲突的问题呢?
预编译:
SECURE=1TC_LINKKEY_JOINNV_INITNV_RESTORExNWK_MANAGERxHOLD_AUTO_STARTZTOOL_P1MT_TASKMT_APP_FUNCMT_SYS_FUNCMT_ZDO_FUNCLCD_SUPPORTED=DEBUGMULTICAST_ENABLED=FALSEZCL_READZCL_WRITEZCL_REPORTZCL_EZMODEZCL_BASICZCL_IDENTIFYZCL_DOORLOCKZCL_SCENESZCL_GROUPS