ZigBee按鍵允許入網

1.前言
在德州儀器在線技術支持社區看到有zigbee怎麼加入指定網絡的討論,TI員工講到:“像智能家居等個人消費產品,從安全性考慮,正常運行時一般會關閉網絡的允許加入功能,有新設備需要加入時,纔打開該功能。另外,這些產品一般都會使能網絡加密的功能。” 我們可以通過按鍵來控制Coordinator允許入網;控制Enddevice加入網絡。

2.實驗方法
一、
Coordinator:
step1.  開啓組網(協調器上電後,網絡創建成功,不發送網絡信息廣播,也不允許任何節點加入網絡,只有當連按3次協調器的按鍵,或者上位機發送准許入網的指令,這時候協調器才發送網絡信息廣播,准許設備加入網絡)
setp2. 控制是否允許節點進入網絡(這裏有個時間窗,時間窗內所有的節點都允許正常進入的)

協調器首次上電流程圖:


Enddevice:
step1.開啓網絡發現(連按3次按鍵,設備開啓網絡發現模式,如果有網絡則加入網絡)

協調器/網關流程圖:

二、
通過串口給協調器"11",協調器收到"11"後通過無線發送給終端或者路由器控制終端的LED燈亮起;終端或者路由器收到"11"後,應答協議器AA
通過串口給協調器"10",協調器收到"10"後通過無線發送給終端或者路由器控制終端的LED燈熄滅;終端或者路由器收到"10"後,同樣應答協議器AA

3.代碼
Coordinator:
<span style="font-family:Comic Sans MS;"><span style="font-family:Courier New;"><strong><span style="font-size:14px;"></span>
<span style="font-family:Comic Sans MS;">case ZDO_STATE_CHANGE: 
    if(GenericApp_NwkState==DEV_ZB_COORD)
          {
             GenericApp_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;   
             GenericApp_DstAddr.endPoint = GENERICAPP_ENDPOINT;

             //地址設置爲廣播地址,數據將廣播給網絡中的所有節點
             GenericApp_DstAddr.addr.shortAddr = 0xffff;

             //禁止節點加入
             <span style="background-color: rgb(255, 255, 51);">NLME_PermitJoiningRequest(0);</span>
          }
   break; </span>
<span style="font-family:Comic Sans MS;"></span><span style="font-size: 16px;"> </span></strong></span></span>
分析: 在網絡狀態改變事件裏判斷如果是協調器 GenericApp_NwkState==DEV_ZB_COORD 地址設置爲廣播地址, 禁止所有設備入網。
<span style="font-family:Comic Sans MS;"><span style="font-family:Courier New;font-size:14px;"><strong></span>
<span style="font-family:Comic Sans MS;">if ( keys & HAL_KEY_SW_6 )
    {
       DB_KEY_CNT ++;
       if(DB_KEY_CNT == 3)
       {
          DB_KEY_CNT = 0;
          if(GenericApp_NwkState == DEV_ZB_COORD) //網絡是協調器
          {
             NLME_PermitJoiningRequest(60);        //開啓入網: 1分鐘
             osal_start_timerEx( GenericApp_TaskID,
                                 PermitJOIN_TIMEOUT_EVT,
                                 60000 );
             HalLedBlink ( HAL_LED_1, 0, 50, 500 ); //led 閃爍
             HalUARTWrite( MT_UART_DEFAULT_PORT, "允許入網\r\n", 10);
          }
         else
          {
             static uint8 flag = 0;
             if(flag)
             {
               NLME_LeaveReq_t req;
               req.extAddr = NULL;
               req.rejoin = TRUE;
               req.removeChildren = FALSE;
               req.silent = FALSE;
               NLME_LeaveReq( &req );
               HalLedSet (HAL_LED_1, HAL_LED_MODE_ON);
               HalUARTWrite( MT_UART_DEFAULT_PORT, "離開網絡\r\n", 10);
             }else
             {
               devState = DEV_HOLD;
               ZDOInitDevice( 0 );               //加入網絡
               HalLedBlink ( HAL_LED_1, 0, 50, 500 ); //led 閃爍
               HalUARTWrite( MT_UART_DEFAULT_PORT, "嘗試入網中\r\n", 12);
             }
             flag = !flag;
          }
       }
       osal_start_timerEx( GenericApp_TaskID,KEY_TIMEOUT_EVT,KEY_INTERVAL_MONITOR_TIME );
    }</span>
<span style="font-family:Comic Sans MS;"></strong></span></span>
分析:在按鍵事件處理函數中首先,判斷按鍵的次數,如果爲3次;再次判斷網絡是否爲協調器,如果是協調器開啓入網時窗;否則認爲是終端或者路由器。然後,通過flag 標記是否爲第一次入網。

req.rejoin = TRUE; //TRUE允許設備重新加入網絡;FALSE不允許設備重新加入網絡
req.removeChildren =FALSE; //TRUE 子設備也脫離,FALSE只脫離當前設備

NLME_PermitJoiningRequest(byte PermitDuration)
PermitDuration=0xFF:允許其他設備加入本協調器建立的網絡 
PermitDuration=0x00:禁止
API使用說明:
NLME_PermitJoiningRequest只管本節點是否允許其他設備加入,管不了整個網絡。
所以多級組網或者設備很多的時候,不但協調器的Permit需要打開,下面Router的Permit也要打開,否則一旦設備和協調器之間無法直接通信,或者協調器直接掛載的設備數已經達到最大值,都會導致設備無法入網。
同樣,設備退網的時候,也需要將整個網絡的Permit都關掉,不然的話,設備一退網,如果發入網請求的話,又會加回來,這就是有人說的設備退不了網的情況。
NLME_PermitJoiningRequest  是讓協調器自己關掉入網(是對於自己而言,開啓或者關閉本地端,允許其他設備入網)。
ZDP_MgmtPermitJoinReq  是讓協調器關掉附件路由的入網,地址就是路由器的地址,一般發個廣播就行(是通過地址,告訴某個設備或者所有路由開啓或者關閉,允許其他設備網)。
注意:如果通信是加密的, 那麼 就必須有一個trust center。 一般是協調器,因爲我上面的通信是加密的, 關了協調器 就沒有了 trust center,導致了 終端只能association  不能入網。

Enddevice:
<span style="font-family:Comic Sans MS;"><strong><span style="font-family:Courier New;font-size:14px;"></span>
<span style="font-family:Comic Sans MS;">case ZDO_STATE_CHANGE:         //net state change
     GenericApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
     if(GenericApp_NwkState == DEV_END_DEVICE)
     {
          GenericApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
          GenericApp_DstAddr.endPoint = GENERICAPP_ENDPOINT;
          GenericApp_DstAddr.addr.shortAddr = 0x0;
          HalUARTWrite( MT_UART_DEFAULT_PORT, (uint8*)END_CODD, sizeof(END_CODD));
     }
 break;</span>
<span style="font-family:Comic Sans MS;"></span></strong></span>
按鍵事件處理函數中 加入網絡。
<span style="font-family:Comic Sans MS;"><span style="font-family:Courier New;font-size:14px;"><strong></span>
<span style="font-family:Comic Sans MS;">devState = DEV_HOLD;
ZDOInitDevice( 0 );               //加入網絡
HalLedBlink ( HAL_LED_1, 0, 50, 500 ); //led 閃爍
HalUARTWrite( MT_UART_DEFAULT_PORT, "嘗試入網中\r\n", 12);</span>
<span style="font-family:Comic Sans MS;"></strong></span></span>

硬件連接


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章