谷动谷力

 找回密码
 立即注册
查看: 1647|回复: 0
打印 上一主题 下一主题
收起左侧

【ZigBee】JN5169 ZigBee3.0设备入网过程

[复制链接]
跳转到指定楼层
楼主
发表于 2022-5-16 13:38:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 fannifu 于 2022-5-25 23:15 编辑

【ZigBee】JN5169 ZigBee3.0设备入网过程

硬件平台:JN5169
SDK:JN-SW-4170
参考文档:ZigBee-Base-Device-Behavior-Specification.pdf

概要:分析设备首次入门的流程(bdbNodeIsOnANetwork属性为FALSE),设备入网规范遵循ZigBee-Base-Device-Behavior-Specification 8.3小节

1  节点首先将bdbcommitoningstatus设置为IN_PROGRESS,将vDoPrimaryScan设置为TRUE,将vScanChannels设置为bdbPrimaryChannelSet
  1. BDB_PRIMARY_CHANNEL_SET = 0x02108800;
  2. BDB_SECONDARY_CHANNEL_SET = 0x07FFF800 ^ 0x02108800;

  3. BDB_eNsStartNwkSteering(void)
  4. {  
  5.         //有省略
  6.         sBDB.sAttrib.ebdbCommissioningStatus = E_BDB_COMMISSIONING_STATUS_IN_PROGRESS;
  7.         bDoPrimaryScan = TRUE;
  8.         u32ScanChannels = sBDB.sAttrib.u32bdbPrimaryChannelSet;
  9.         u8ScanChannel = BDB_CHANNEL_MIN;
  10.         bAssociationJoin = FALSE;
  11.         vNsDiscoverNwk();
  12. }
复制代码

进入vNsDiscoverNwk()函数后,跳到12步进行判断

2  节点应进行信道扫描,以发现其无线电范围内的一组信道上有哪些网络可用
  1. void vNsDiscoverNwk()
  2. {
  3.         //此函数有省略
  4.         eNS_State = E_NS_WAIT_DISCOVERY;    //状态机状态,注意
  5.         ZPS_eAplZdoDiscoverNetworks(u32ScanChannels & (1<<u8ScanChannel));
  6.         8ScanChannel++;
  7. }
复制代码

ZPS_eAplZdoDiscoverNetworks()函数调用最终都会在终端设备或路由器上导致生成堆栈事件ZPS_EVENT_NWK_DISCOVERY_COMPLETE
  1. bdb_taskBDB();
  2.         BDB_vNsStateMachine(&sZpsAfEvent);
  3.                 case E_NS_WAIT_DISCOVERY:
  4.                         case ZPS_EVENT_NWK_DISCOVERY_COMPLETE:
  5.                             //有省略
复制代码

3  如果NLME-NETWORK-DISCOVERY确认原语的状态参数不等于SUCCESS,表明通道扫描不成功,则节点从步骤2继续。
意思就是判断sStackEvent.uEvent.sNwkDiscoveryEvent.eStatus状态不等于MAC_ENUM_SUCCESS,继续执行下面函数:

  1. vNsDiscoverNwk();
复制代码

4  节点通过分析NetworkCount和NetworkDescriptor参数,判断是否有设置为TRUE的permit join flag合适的网络。
  1. eNS_State = E_NS_WAIT_JOIN;
  2. vNsTryNwkJoin(TRUE, &(psZpsAfEvent->sStackEvent.uEvent.sNwkDiscoveryEvent));

  3.         //以下位于vNsTryNwkJoin()函数,有无关代码省略
  4.          if(
  5.                 (pNwkDescr[u8NwkIndex].u8PermitJoining) && \
  6.                 (
  7.                     (0 == ZPS_psAplAibGetAib()->u64ApsUseExtendedPanid) ||\        
  8.                     (pNwkDescr[u8NwkIndex].u64ExtPanId == ZPS_psAplAibGetAib()->u64ApsUseExtendedPanid)
  9.                 )
  10.             ){
  11.                     eNS_State = E_NS_WAIT_JOIN;
  12.                     eStatus = ZPS_eAplZdoJoinNetwork(&pNwkDescr[u8NwkIndex]);
  13.              }
复制代码

5  如果在通道扫描中没有找到合适的网络,节点从步骤2继续
  1. vNsTryNwkJoin(TRUE, &(psZpsAfEvent->sStackEvent.uEvent.sNwkDiscoveryEvent));

  2.         DBG_vPrintf(TRACE_BDB," BDB: No suitable network! Continue Discovery \n");
  3.         vNsDiscoverNwk();
复制代码

6  节点应尝试加入使用MAC关联发现的网络
  1. vNsTryNwkJoin(TRUE, &(psZpsAfEvent->sStackEvent.uEvent.sNwkDiscoveryEvent));

  2.         //以下位于vNsTryNwkJoin()函数,有无关代码省略
  3.         eNS_State = E_NS_WAIT_JOIN;
  4.         eStatus = ZPS_eAplZdoJoinNetwork(&pNwkDescr[u8NwkIndex]);
复制代码

7  允许再次尝试加入同一网络,但每次尝试次数不得超过bdbcmaxsamenetworkretrytrytries次数
  1. vNsTryNwkJoin(TRUE, &(psZpsAfEvent->sStackEvent.uEvent.sNwkDiscoveryEvent));

  2.         //以下位于vNsTryNwkJoin()函数,有无关代码省略
  3.         if(u8RecSameNwkRetryAttempts < BDBC_MAX_SAME_NETWORK_RETRY_ATTEMPTS)
  4.         {
  5.                 eNS_State = E_NS_WAIT_JOIN;
  6.                 eStatus = ZPS_eAplZdoJoinNetwork(&pNwkDescr[u8NwkIndex]);
  7.         }
复制代码

ZPS_eAplZdoJoinNetwork()函数返回堆栈事件
//以下代码有省略,请注意
  1. bdb_taskBDB();
  2.         BDB_vNsStateMachine(&sZpsAfEvent);
  3.                 case E_NS_WAIT_JOIN:
  4.                     switch(psZpsAfEvent->sStackEvent.eType)
  5.                     {
  6.                             case ZPS_EVENT_NWK_FAILED_TO_JOIN:
  7.                                 break;
  8.                             case ZPS_EVENT_NWK_JOINED_AS_ROUTER:
  9.                             case ZPS_EVENT_NWK_JOINED_AS_ENDDEVICE:
  10.                                 break;
  11. }
复制代码

8  如果是堆栈事件为ZPS_EVENT_NWK_FAILED_TO_JOIN,再次尝试同一网络
//以下代码有省略,请注意
  1. bdb_taskBDB();
  2.         BDB_vNsStateMachine(&sZpsAfEvent);
  3.                 case E_NS_WAIT_JOIN:
  4.                     switch(psZpsAfEvent->sStackEvent.eType)
  5.                     {
  6.                             case ZPS_EVENT_NWK_FAILED_TO_JOIN:
  7.                                  vNsTryNwkJoin(FALSE, NULL);
  8.                             break;

  9. }
复制代码

9  如果是堆栈事件为ZPS_EVENT_NWK_JOINED_AS_ROUTER或者ZPS_EVENT_NWK_JOINED_AS_ENDDEVICE,应相应地设置bdbNodeJoinLinkKeyType,以指示用于解密接收到的网络密钥的链路密钥类型。
//以下代码有省略,请注意
  1. bdb_taskBDB();
  2.         BDB_vNsStateMachine(&sZpsAfEvent);
  3.                 case E_NS_WAIT_JOIN:
  4.                     switch(psZpsAfEvent->sStackEvent.eType)
  5.                     {
  6.                             case ZPS_EVENT_NWK_FAILED_TO_JOIN:
  7.                                 break;
  8.                             case ZPS_EVENT_NWK_JOINED_AS_ROUTER:
  9.                             case ZPS_EVENT_NWK_JOINED_AS_ENDDEVICE:
  10.                                 psApsKeyDesc = ZPS_psGetActiveKey(ZPS_u64AplZdoLookupIeeeAddr(psZpsAfEvent->sStackEvent.uEvent.sNwkJoinedEvent.u16Addr), &u32Index);
  11.                                 /*根据接收到的网络密钥的链路密钥类型,相应地设置bdbNodeJoinLinkKeyType*/
  12.                                 if(!memcmp(sBDB.pu8DefaultTCLinkKey, &psApsKeyDesc->au8LinkKey[0], ZPS_SEC_KEY_LENGTH))
  13.                                 {
  14.                                     sBDB.sAttrib.u8bdbNodeJoinLinkKeyType = DEFAULT_GLOBAL_TRUST_CENTER_LINK_KEY;
  15.                                 }
  16.                                 else if(!memcmp(sBDB.pu8DistributedLinkKey, &psApsKeyDesc->au8LinkKey[0], ZPS_SEC_KEY_LENGTH))
  17.                                 {
  18.                                     sBDB.sAttrib.u8bdbNodeJoinLinkKeyType = DISTRIBUTED_SECURITY_GLOBAL_LINK_KEY;
  19.                                 }
  20.                                 else if(!memcmp(sBDB.pu8TouchLinkKey, &psApsKeyDesc->au8LinkKey[0], ZPS_SEC_KEY_LENGTH))
  21.                                 {
  22.                                     sBDB.sAttrib.u8bdbNodeJoinLinkKeyType = TOUCHLINK_PRECONFIGURED_LINK_KEY;
  23.                                 }
  24.                                 else if(!memcmp(sBDB.pu8PreConfgLinkKey, &psApsKeyDesc->au8LinkKey[0], ZPS_SEC_KEY_LENGTH))
  25.                                 {
  26.                                     sBDB.sAttrib.u8bdbNodeJoinLinkKeyType =  INSTALL_CODE_DERIVED_PRECONFIGURED_LINK_KEY;
  27.                                 }
复制代码

10  节点将bdbNodeIsOnANetwork设置为TRUE,然后广播Device_annce ZDO命令。如果apsTrustCenterAddress等于0xffffffffffffff,节点应该并从步骤13继续。
  1. //以下代码有省略,请注意
  2. sBDB.sAttrib.bbdbNodeIsOnANetwork = TRUE;
  3. eNS_State = E_NS_WAIT_AFTER_NWK_JOIN;
  4. ZTIMER_eStart(u8TimerBdbNs, ZTIMER_TIME_MSEC(300)); //启动BDB_vNsTimerCb()任务

  5.         BDB_vNsTimerCb()
  6.         switch(eNS_State)
  7.         {
  8.             case E_NS_WAIT_AFTER_NWK_JOIN:
  9.              if(ZPS_psAplAibGetAib()->u64ApsTrustCenterAddress == 0xFFFFFFFFFFFFFFFFULL)
  10.             {
  11.                 eNS_State = E_NS_IDLE;
  12.                 vNsAfterNwkJoin();
  13.             }

  14.         }
复制代码

11  节点应执行检索新的信任中心链接键的过程(参见子条款10.2.5)。
如果过程成功,节点将从步骤13继续。

如果该过程不成功,则节点应在其旧网络上执行休假请求并重置其网络参数。

然后节点将bdbNodeIsOnANetwork设置为FALSE,并将bdbcommitoningstatus设置为TCLK_EX_FAILURE。

为了执行休假请求,节点发出nlm - leave。向NWK层请求原语,

DeviceAddress参数设置为NULL, RemoveChildren参数设置为FALSE, Rejoin参数设置为FALSE。在收到我的假期。确认原语,通知节点请求离开网络的状态。

节点然后终止
  1. //以下代码有省略,请注意
  2. sBDB.sAttrib.bbdbNodeIsOnANetwork = TRUE;
  3. eNS_State = E_NS_WAIT_AFTER_NWK_JOIN;
  4. ZTIMER_eStart(u8TimerBdbNs, ZTIMER_TIME_MSEC(300)); //启动BDB_vNsTimerCb()任务

  5.         BDB_vNsTimerCb()
  6.         switch(eNS_State)
  7.         {
  8.             case E_NS_WAIT_AFTER_NWK_JOIN:
  9.                 if(ZPS_psAplAibGetAib()->u64ApsTrustCenterAddress == 0xFFFFFFFFFFFFFFFFULL)
  10.                 {
  11.                     eNS_State = E_NS_IDLE;
  12.                     vNsAfterNwkJoin();
  13.                 }
  14.                 if(0x00 == sBDB.sAttrib.u8bdbTCLinkKeyExchangeMethod)
  15.                 {
  16.                     vNsStartTclk();
  17.                 }
  18.                 else                //检索新的信任中心链接键的过程,成功
  19.                 {
  20.                     DBG_vPrintf(TRACE_BDB,"Only ApsReqKey is supported !\n");
  21.                     eNS_State = E_NS_IDLE;
  22.                     vNsAfterNwkJoin();
  23.                 }
  24.         }
复制代码

12  如果vDoPrimaryScan等于FALSE或bdbSecondaryChannelSet等于0x00000000,节点将从步骤16继续。
如果bdbSecondaryChannelSet不等于0x00000000,节点将vDoPrimaryScan设为FALSE,将vScanChannels设为bdbSecondaryChannelSet,从步骤2继续。
  1. bDoPrimaryScan = FALSE;
  2. u32ScanChannels = sBDB.sAttrib.u32bdbSecondaryChannelSet;
  3. u8ScanChannel = BDB_CHANNEL_MIN;
  4. vNsDiscoverNwk();
复制代码

13  节点广播Mgmt_Permit_Joining_req ZDO命令,将 PermitDuration 字段至少设置为bdbcMinCommissioningTime,将TC_Significance字段设置为0x01

  1. vNsAfterNwkJoin();
  2.         vNsSendPermitJoin();
复制代码

14. 如果节点能够允许新节点加入,则应激活其permit join标志。为此,节点发出nlm - permit - join。将PermitDuration参数设置为至少bdbcmincommission oningtime的request原语。收到NWK层的NLME-PERMIT- .confirm原语后,将通知节点激活许可证连接的请求的状态。
  1. vNsAfterNwkJoin();
  2.         vNsSendPermitJoin();
复制代码

15  然后节点将bdbcommitoningstatus设置为SUCCESS。如果节点支持touchlink,它将aplFreeNwkAddrRangeBegin、aplFreeNwkAddrRangeEnd、aplFreeGroupID-RangeBegin和aplFreeGroupIDRangeEnd属性的值设置为0x0000(表示节点使用MAC关联加入了网络)。然后,节点应终止对不在网络上的节点的网络指导过程。
  1. sBDB.sAttrib.ebdbCommissioningStatus = E_BDB_COMMISSIONING_STATUS_SUCCESS;
  2. eNS_State = E_NS_IDLE;
  3. ZPS_eAplAibSetApsUseExtendedPanId(ZPS_u64NwkNibGetEpid( ZPS_pvAplZdoGetNwkHandle()));
  4. sBdbEvent.eEventType = BDB_EVENT_NWK_STEERING_SUCCESS;
  5. APP_vBdbCallback(&sBdbEvent);
  6.         DBG_vPrintf(TRACE_SWITCH_NODE,"GoRunningState!\n");
  7.         vHandleJoinAndRejoin();
  8.                 sDeviceDesc.eNodeState = E_RUNNING;
  9.                 ZTIMER_eStart(u8TimerPoll, POLL_TIME);
  10.                 ZTIMER_eStart(u8TimerTick, ZCL_TICK_TIME);
复制代码

16. 节点可以使用制造商指定的程序重试,或者将bdbcommission oningstatus设置为NO_NETWORK,然后终止不在网络上的节点的网络转向过程。如果尝试制造商特定的过程,bdbcommitoningstatus和bdbNodeIsOnANetwork属性将在其终止时相应地更新,以便调试过程是一致的。
  1. //有省略
  2. vNsDiscoverNwk()
  3. {
  4.     if((!u32ScanChannels) || (u8ScanChannel > BDB_CHANNEL_MAX))
  5.     {     
  6.         if(bDoPrimaryScan == FALSE)
  7.         {
  8.             vNsTerminateNwkSteering();
  9.             return;
  10.         }
  11.     }
  12. }
复制代码


+10
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|深圳市光明谷科技有限公司|光明谷商城|Sunshine Silicon Corpporation ( 粤ICP备14060730号|Sitemap

GMT+8, 2024-11-24 16:08 , Processed in 0.357104 second(s), 38 queries .

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表