目前公司商用的协议栈程序是支持分节点地址可配置的,与zigbee2007pro有很大的不同,因此也产生了一些问题,特别严重的就是本篇所讲述的更换设备导致的现象。本篇将深入代码分析冲突检测及处理的流程,并给出修改方法。
一、冲突情况抓包
二、流程分析
第
第
第
第
第
第
第
第
第
第
第
三、代码级分析1.检测冲突
这一小节是对第
a.
//Ifaddressconflictisdetected,noneedtoupdatetheaddressmanager
if(NLME_CheckNewAddrSet(Annce.nwkAddr,Annce.extAddr)==ZFailure)
{
return;
}
该函数说明中有如下明确说明:
*IfZFailureisreturned,thestackalreadysentoutanaddressconflict
*routeerror-alreadycalledNLME_ReportAddressConflict().
b.
目前对于
2.接收到冲突包后的声明处理
这一小节是对第106帧的分析。
该函数处理位于ZDApp_ProcessNetworkJoin函数的最底下。
//Assumefromaddressconflict
if(_NIB.nwkAddrAlloc==NWK_ADDRESSING_STOCHASTIC)
{
//Notifythenetwork
ZDApp_AnnounceNewAddress();
//Notifyapps
osal_set_event(ZDAppTaskID,ZDO_STATE_CHANGE_EVT);
}
这是原生协议栈在接收冲突包后的处理。ZDAPP_AnnounceNewAddress会声明一个随机的地址,并且通知应用任务调用状态改变的事件。
我们为了保证配置的节点地址不被切到随机,此处将ZDAPP_AnnounceNewAddress替换成了自己的声明函数。
四、代码修改
由于无数的声明包不断发出,致使网络异常拥堵,,影响到了正常数据传输。
本次修改还是从根源下手,即第三点的
原生协议栈的做法是:先判断设备声明是否有冲突,有冲突直接丢弃该声明包,无冲突才会将该声明地址更新到地址管理数据库中。
这里的措施就是尽量让新的设备声明能够更新到各个路由设备的地址管理数据库中,保证一次声明过后就以这次的为准,以后不再产生冲突包。修改如下:
1.屏蔽
2.删除旧的关联表项
分析了
if(AddrMgrEntryLookupNwk(&addrEntry))
{
AssocRemove(addrEntry.extAddr);
ZDApp_NVUpdate();
AddrMgrExtAddrSet(addrEntry.extAddr,Annce.extAddr);
AddrMgrEntryUpdate(&addrEntry);
}
五、验证
经过实际验证,发现路由设备更新了该修改之后,可以解决问题。
路由设备在接收一次新声明后便能更新关联表,看到关联表项对应的短地址只有一项,而原来会有两项具有相同的短地址。实际抓包发现不再一直狂发声明包。
走过一段路,风景毕竟不相同。这段惠风和畅,