清除脫離網絡的 路由節點(stale device)的 殘留在各表中以AssociationDevList為例的殘余信息。
如圖所示拓撲結構中:

路由器1脫離網絡后,通過協調器按鍵操作來 清除 協調器及路由器2 的關聯表中 與路由器1 相關的條目信息。
根據AssociationDevList 條目中的age值來判斷 路由節點是否脫離網絡,若脫離網絡,則先調用AddrMgrEntryGet( ) 獲取丟失節點的短地址 和 擴展地址,然后調用NLME_LeaveReq()/AssocRemove()對表中的條目信息進行清除操作。
Z-stack中關聯表AssociationDevList 主要存儲與該節點有父子關系的相關節點信息,表中信息的 IEEE 地址是唯一的,每個設備加入它的父節點時會在表中添加一個記 錄(一個設備掉電重啟后 sniffer中顯示兩個短地址的一個為掉電前短地址另一個為新獲取的段地址),但是子節點斷電離開網絡時不會刪除該條記錄,如果有多個子節點,頻繁更換父節點會造成
AssociatedDevList 表滿或溢出,使其它子節點無法加入該父節點,因此需要及時的刪除一些已離開的子節點記錄。其條目結構體如下:
typedef struct
{
UINT16 shortAddr; // 關聯設備的短地址
uint16 addrIdx; // 條目索引號 起始為0
byte nodeRelation; //與該節點的關系
byte devStatus; // 設備狀態
byte assocCnt; //聯接次數,相同 IEEE 地址連接時會加 1
byte age; //連續未接收link status 的次數(終端設備始終增加)
linkInfo_t linkInfo;
} associated_devices_t;
nodeRelation 可選值如下:
// Node Relations
#define PARENT 0//父節點 一般指協調器
#define CHILD_RFD 1//簡功能節點 一般指終端
#define CHILD_RFD_RX_IDLE 2//簡功能節點(空閉進 RF 接收開啟) 一般指終端
#define CHILD_FFD 3//全功能節點 一般指路由器
#define CHILD_FFD_RX_IDLE 4//全功能節點(空閉進 RF 接收開啟) 一般指路由器
#define NEIGHBOR 5//鄰居設備
#define OTHER 6//其它設備
#define NOTUSED 0xFF //沒有使用
devStatus可選值如下:
#define DEV_LINK_STATUS 0x01 // 活動聯接
#define DEV_LINK_REPAIR 0x02 //正在修復聯接
#define DEV_SEC_INIT_STATUS 0x04 // 初后的安全
#define DEV_SEC_AUTH_STATUS 0x08 //驗正過的安全
/*
* Remove a device from the list. Uses the extended address.
*/
extern byte AssocRemove( byte *extAddr );
能夠 移除 關聯表 中 所指定擴展地址設備的條目信息;
調用該函數的前提是 獲取相關節點的 擴展地址。
/*
* @fn AddrMgrEntryGet
*
* @brief Get NWK address and EXT address based on index.
*
* @param entry
* ::user - [in] user ID //需要輸入用戶ID
* ::index - [in] index of data //相應表條目 索引號
* ::nwkAddr - [out] NWK address //讀取相應條目 的端地址
* ::extAddr - [out] EXT address //讀取相應條目的擴展地址
*
* @return uint8 - success(TRUE:FALSE) //返回讀取是否成功狀態值
*/
extern uint8 AddrMgrEntryGet( AddrMgrEntry_t* entry );
能夠根據 索引號 讀取關聯表、綁定表等表中的短地址和擴展地址;
其中用戶ID 主要選擇對應的表,其參數為:
// user IDs - use with <AddrMgrEntry_t>
#define ADDRMGR_USER_DEFAULT 0x00 //默認用於讀取Assoc
#define ADDRMGR_USER_ASSOC 0x01
#define ADDRMGR_USER_SECURITY 0x02 //用於讀取安全相關
#define ADDRMGR_USER_BINDING 0x04 //用於讀取綁定表
#define ADDRMGR_USER_PRIVATE1 0x08 //未知
相關代碼如下所示:
HalLedSet ( HAL_LED_1, HAL_LED_MODE_TOGGLE );
uint8 _nodeCounter;
uint8 _nodeIndex;
NLME_LeaveReq_t req;
req.extAddr = removeExtAddr;
req.removeChildren = FALSE;
req.rejoin = FALSE;
req.silent = FALSE;
for ( _nodeCounter = 0; _nodeCounter < NWK_MAX_DEVICES; _nodeCounter++ )
{
if ( (AssociatedDevList[_nodeCounter].nodeRelation == CHILD_FFD_RX_IDLE) || (AssociatedDevList[_nodeCounter].nodeRelation == CHILD_FFD)
|| (AssociatedDevList[_nodeCounter].nodeRelation == PARENT))
{
HalLedSet ( HAL_LED_2, HAL_LED_MODE_TOGGLE );
if ( AssociatedDevList[_nodeCounter].age > NWK_ROUTE_AGE_LIMIT )
{
//HalLedSet ( HAL_LED_2, HAL_LED_MODE_TOGGLE );
AddrMgrEntry_t addrEntry;
addrEntry.user = ADDRMGR_USER_DEFAULT;
addrEntry.index = _nodeCounter;
if ( AddrMgrEntryGet( &addrEntry ) )
{
req.extAddr = addrEntry.extAddr;
NLME_LeaveReq(&req);
//通過leave命令 清除 stale device相關條目;
addrIndex = addrEntry.extAddr[0];
//將擴展地址最后一位無線發射做驗證;
//AssocRemove( addrEntry.extAddr);
/*****
對外進行廣播以清除 活動節點上 丟失節點信息
*****/
Remove_DstAddr.endPoint = 10;
Remove_DstAddr.addr.shortAddr = 0xfffc;
Remove_DstAddr.addrMode = afAddr16Bit;
if ( AF_DataRequest( &Remove_DstAddr, &GenericApp_epDesc,
GENERICAPP_CLUSTERID3,1,&addrIndex, 0,
0, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
// Successfully requested to be sent.
}
}
}
}
網絡中的路由設備接收到該命令后,重復如上代碼清除 stale device相關條目信息,對其他表的操作類似。
測試過程中出現的問題:
1.設備丟失后 重新上電 關聯表 會更新其短地址,很偶爾的出現一次同一個設備 sniffer的 link status 中顯示兩個短地址(原因未知);
2.有時使用NLME_LeaveReq()會出現無效的情況,更換為AssocRemove()則沒問題 (原因未知);
3.對脫離網絡的 終端設備相關條目刪除 需要定時 的通報ED在網絡中,可參考提供的鏈接進行嘗試;
參考鏈接:
http://bbs.feibit.com/thread-3841-1-1.html
http://blog.csdn.net/mahaichao540174345/article/details/7973785
http://e2e.ti.com/support/low_power_rf/f/158/p/105319/676645.aspx
