我们使用3.0.2的协议栈,使用2530作为协调器和路由器,在设备入网过程中,出现过几台路由设备入网成功后,剩下的设备均无法入网的情况,抓包看是在设备请求入网,已入网的路由发update device 给协调器,协调器却返回remove device给路由器,路由器随机剔除申请入网的新设备。在代码里设置日志消息后,发现是ZDSecMgrSendNwkKey这个函数返回失败导致的,也就是发送密钥失败。但是第一次碰到剩下所有设备,每次申请入网协调器都是发送密钥失败,主网是一直打开的。以前有碰到偶尔一次设备入网协调器发送密钥失败,但马上就会再次入网成功。
检查这个函数内部,发现无论是密钥发送成功或失败都是运行到71、73这两条日志下对应的内容,请看下图:
碰到这个问题后调用了恢复出厂设置函数(bdb_resetLocalAction()),随后设备便能正常入网,协调器未出现大规模密钥发送失败的问题。想请问各位可能是什么原因,有很么办法避免这个问题
YiKai Chen:
懷疑你加入協調器的路由加上終端數量超過ZDSECMGR_TC_DEVICE_MAX的限制才會出現這個狀況
Alvin Chen:
回复 YiKai Chen:
如YK所言你有多少个设备啊。
user5957818:
回复 YiKai Chen:
应该不是这个问题,这个值设为了60,当时出现这个问题只入网了3个路由,还有25个设备没有入网
user5957818:
回复 Alvin Chen:
入网了三个,后面恢复出厂设置再试,28个设备都入网成功了
YiKai Chen:
回复 user5957818:
可能是之前測試的時候沒有把入网设备正確移除,累積了一段時間後就超過了,所以你才會后面恢复出厂设置再试,28个设备都入网成功了
user5957818:
回复 YiKai Chen:
应该也不是的,协调器在测试之前是刚刚烧录的,第一次就只连接了三台设备就进不来了
Alvin Chen:
回复 user5957818:
你有erase吗?建议你擦除重新烧录试试吧,应该是TCLK验证不通过被踢出,此外不要同时入网太多设备。
user5957818:
回复 Alvin Chen:
有的,每次烧录都是erase and program,但我有一个没说清楚的是,已经入网的三台设备和别的设备原先都在另外一个网络,只是那个网路关闭了主网,我再逐个让路由设备恢复出厂设置,退出原先的网路,加入现在的网络,但是加到第四个就没法加进来了
Alvin Chen:
回复 user5957818:
给你个补丁你打进去试试,你回复出厂设置,退出网络使用用的leave 命令且不包含rejoin 选项对吗?修改ZDSecMgrUpdateDeviceInd 在zd_sec_mgr.c如下:
#if (ZG_BUILD_COORDINATOR_TYPE)uint8found;uint16 keyNvIndex, index;APSME_TCLKDevEntry_t TCLKDevEntry;keyNvIndex = APSME_SearchTCLinkKeyEntry(device.extAddr,&found, &TCLKDevEntry);//If found and it was verified, then allow it to join in a fresh state by erasing the key entryif((found == TRUE) && (TCLKDevEntry.keyAttributes == ZG_VERIFIED_KEY)){TCLKDevEntry.keyAttributes = ZG_DEFAULT_KEY;//Increase the shift by one. Validate the maximum shift of the seed which is 15TCLKDevEntry.SeedShift_IcIndex++;TCLKDevEntry.SeedShift_IcIndex &= 0x0F;TCLKDevEntry.rxFrmCntr = 0;TCLKDevEntry.txFrmCntr = 0;index = keyNvIndex - ZCD_NV_TCLK_TABLE_START;TCLinkKeyFrmCntr[index].rxFrmCntr = 0;TCLinkKeyFrmCntr[index].txFrmCntr = 0;//Update the entryosal_nv_write(keyNvIndex,0,sizeof(APSME_TCLKDevEntry_t), &TCLKDevEntry );}bdb_TCAddJoiningDevice(device.parentAddr,device.extAddr); #endif}ZDSecMgrDeviceJoin( &device );}else{// remove the TCLK NV entry for a device which has left the network #if (ZG_BUILD_COORDINATOR_TYPE)uint8found;uint16 keyNvIndex, index;APSME_TCLKDevEntry_t TCLKDevEntry;keyNvIndex = APSME_SearchTCLinkKeyEntry(device.extAddr,&found, &TCLKDevEntry);//If found and it was verified, erase the key entryif((found == TRUE) && (TCLKDevEntry.keyAttributes == ZG_VERIFIED_KEY)){MAP_osal_memset(&TCLKDevEntry,0,sizeof(APSME_TCLKDevEntry_t));TCLKDevEntry.keyAttributes = ZG_DEFAULT_KEY;index = keyNvIndex - ZCD_NV_TCLK_TABLE_START;TCLinkKeyFrmCntr[index].rxFrmCntr = 0;TCLinkKeyFrmCntr[index].txFrmCntr = 0;//Update the entryosal_nv_write(keyNvIndex,0,sizeof(APSME_TCLKDevEntry_t), &TCLKDevEntry );} #endif} }
user5957818:
回复 Alvin Chen:
谢谢!等把问题复现了测试一下