This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

终端设备无法重入网络 使用 (zstack1.2.2a)

Expert 1850 points
Other Parts Discussed in Thread: Z-STACK

测试环境:

        一个ZC ,5个ZED ,ZED 是电池设备  (均采用 zstack 1.2.2 或1.2.2a)
操作:
        重复重启 ZC, 造成 ZED 断网寻网 。

目的:
        验证  寻网一段时间,然后休眠一段时间  的新逻辑,(rejoin scan====》 rejoin backoff====》rejoin scan)




代码上增加:

       在应用层 loop 中的  ZDO_STATE_CHANGE 事件中,
       当DEV_NWK_DIS 时, 调用HAL_LED_BLINK() 函数     让LED1  一直闪
       当DEV_NWK_BACKOFF 时, 调用HAL_LED_SET() 函数 将LED1 关闭
       这样 断网的时候 LED1 就一直闪, 休眠(rejoin backoff)的时 ,灯就熄灭。

发现问题:
       重刷了很多次之后, 发现 有些设备  断网后,LED1 一直闪,rejoin scan 的时间过完 ,还是无法进入rejoin backoff。
       用抓包软件抓了一下, 发现有两种情况

        情况1 : 设备是有发beacon  request 出来的。 但是ZC 启动完成后, 设备仍然无法进入网络。
        情况2:  设备只是闪LED1 ,但是 实际上没有发beacon request出来

        以上两种情况 只是 设备无法 入网的 现象。

        针对情况1 我的猜测:
        让我不明白的 为甚么,  设备过了rejoin  scan 规定时间后, 无法进入rejoin back off呢?
        
        针对情况2 我的猜测 :
         或者是设备已经 进入rejoin backoff 了,但 LED1 没有关闭。(即 设备的state  改变了 , 但是没有把改变 的状态  传到 应用层 的ZDO_STATE_CHANGE 事件上)    

  • 顺便把数据包附下上去,情况1下设备的devstartmode是什么,有没有可能出现过节点在发rejoin request的时候,刚好把协调器断电了?

    情况2,协议栈里面其他地方也有用到这个LED闪的,

  • 终于等到你!!!

    情况 1  devstart mode????

    devstate 吗??  此时 设备的 状态  是DEV_NWK_DIS,(很抱歉 log 没存起来)

    如果是1.2.2的话,会有两种情况。

    1.  设备发出rejoin  request, 但是 协调器就是永远不response, ( 这个暂时没有log)

    2. 设备发出rejoin request, 协调器也响应了, 但是设备还是依然 处于寻网状态,  除非 协调器开permit join 。

    log:

    情况2, 这个很容易复现的,只要你把 闪灯  的操作  放在 ZDO_STATE_CHANGE 事件里 的DEV_NWK_DIS case 中。

    几个rejoin logic  下来,基本就可以出现了。

    另外有个问题非常想请问你, rejoin backoff 的默认值 设置为30分钟 可以吗?

    1800000  虽然没有超过uint32  , 但真的可以吗?

     

  • VV, 

    情况1 的 log 抓到了。

    52 条: 发orphan notification,

    92 条: 发了rejoin request, 有ACK, 但是没有rejoin  response

    接着就一直 beacon  下去了!!!!

    log :

    另外一个log  说明一下:

    log :

    582条~599条:  终端 发了3次rejoin  request, 协调器才响应了 成功。

    但实际上 它还是 依然 继续 寻网  发beacon

    等到1336条 : 我开了 协调器的permit  join。

    这时 终端设备 才 association  成功 进入网络。。。。

    所以我不明白,既然都 rejoin  response 告诉成功了,为什么后面还要 开permit  join 才能进来

  • 你使用的Rejoin是自己写的吗?怎么是unsecured rejoin,你可以看到你的rejoin是没有加密的,所以是unsecure rejoin,然后还需要trust center去授权的,如果permit join在关掉的情况下,就不允许入网了。

  • 谢谢 VV

    第一 : Rejoin 不是我自己写的。 我也奇怪为什么 就变成 unsecure rejoin 了,  (前面一个 (第592条)还是加密的rejoin。)

    第二,撇开加密的问题,  为什么 不加密的rejoin  request   反倒有  rejoin  response。而且rejoin response的 返回 是允许入网的。

    谢谢!

  • 你的0xF292这个是一个终端设备,但是在发起Rejoin Request确没有Data Request发出来。

    你在协议栈做什么改动?

    这个问题复现的流程是什么

  • VV:      

    1.  rejoin 的code 我没有改动,使用的是HA1.2.2.a 原有的  那套逻辑(rejoin scan ---> resjoin backoff ---> rejoin scan)     

    2.  为什么突然就变成unsecured rejoin, 这个我也很诧异,  加不加密不是 在工程编译的时候 使能 SECURE=1  就开启了吗?           

    程序运行过程中  应用层 的软件难道还可以  修改为不加密 吗?          

     所以 这个肯定不是 客户应用代码 造成的。。。。           

    我怀疑是  NWK key 丢失了,  但是 抓包过程中又无法判断  NWK key 什么时候 更新 什么时候传输到 终端节点!

    3.  所有的终端设备  发起rejoin request 都  必须 发起 data request 吗?         

     这个我倒没留意,  但是如果终端设备 是RFD_RCVC_ALWAYS_ON=TRUE,  难道  发起rejoin  request 还需要  发起data request吗??          

     这个 规定  在zstack 中 哪里说明?      

     

     

  • 4. 我现在 也还不是很清楚  百分百 复现该问题的 流程 是怎样?           

    以下两种情况下 出现过,终端设备无法 rejoin到 网络中, 除非开启ZC的 permijoin 。            

    ====》 边缘节点情况,              

    如下图,我们在一间100平米的房间内 不同位置布置了终端设备,             

    这些终端设备 我们在程序上 设置 每6秒 就发送一条   msg (IEEE request) 到 协调器             

    放置一个晚上之后, 第二天早上 红色 圈中的  终端设备 均出现  断网 无法连接 协调器的情况            

     然后重新开启 permitjoin 的 时候  也基本都可以 重新加入, (只是它们都使用了新的 短地址)     

         
              
                =====》 重复复位协调器 并删除Association List 。              

    (PS: 删除Association List  只是我们自定的一个功能, 主要是防止ZC 列表撑满了僵尸设备,  这里只是说明有过类似操作 造成终端设备无法入网)                           

    多次 操作复位之后, 就出现了 终端设备 无法rejoin的 现象。                         

     具体可以参考 post :https://e2e.ti.com/support/wireless_connectivity/zigbee_6lowpan_802-15-4_mac/f/158/p/506481/1850037#1850037

    谢谢!

  • VV:

          不知道你是否记得 自己 发的一篇关于ZigBee 状态机的文章:http://www.deyisupport.com/question_answer/wireless_connectivity/zigbee/f/104/t/104629.aspx

          在 第 20 点  DEV_NWK_REJOIN状态到DEV_END_DEVICE_UNAUTH(20)

         有这么一句话:

          如果在ZDApp_RestoreNwkKey( uint8 incrFrmCnt ),读取network key错误,或者之前保存的network key已经不在的情况下,那么就发了Unsecure Rejoin的方式

         读取network 可以错误 的几率,我相信 非常少吧!

         那么 network key 不见呢????,这是有可能! 比如终端设备 寻网 过程中 自己把 NWK  KEY 清除, 然后把NV flash 里面的东西全清了!!

        

          我假设 一下, 如果 终端设备发送了Rejoin Request以后,收到父设备回复的Rejoin Response消息,那么程序会次进入到ZDApp_ProcessNetworkJoin( void

    )  , 进行 Verify NWK key is available before sending Device_annce 对吧!

         

    else if ( devState == DEV_NWK_ORPHAN ||
                <strong><span style="color:#ff0000;">devState == DEV_NWK_SEC_REJOIN_CURR_CHANNEL</span></strong> ||
                devState == DEV_NWK_TC_REJOIN_CURR_CHANNEL ||
                devState == DEV_NWK_TC_REJOIN_ALL_CHANNEL ||
                devState == DEV_NWK_SEC_REJOIN_ALL_CHANNEL )
      {
    ......................
     // results of an orphaning attempt by this device
         // results of an orphaning attempt by this device
      <strong><span style="color:#ff0000;"> if (nwkStatus == ZSuccess)</span></strong>
        {
          //When the device has successfully rejoined then reset retryCnt
          retryCnt = 0;
    
          // Verify NWK key is available before sending Device_annce
          if ( ZG_SECURE_ENABLED && ( ZDApp_RestoreNwkKey( TRUE ) == false ) )
          {
            // wait for auth from trust center
            ZDApp_ChangeState( DEV_END_DEVICE_UNAUTH );
    
            // Start the reset timer for MAX UNAUTH time
            ZDApp_ResetTimerStart( MAX_DEVICE_UNAUTH_TIMEOUT );
          }

          但是在此之前  终端设备 进入 predevState == DEV_NWK_SEC_REJOIN_ALL_CHANNEL 时,

          会把NWK KEY 清掉。。。。

          这时ZDApp_ResetTimerStart( MAX_DEVICE_UNAUTH_TIMEOUT ); 时间一到!!!! 是不是就悲剧了!!!!

  • 请问你这个问题解决了吗?     我们做的设备这两天也遇到了同样的问题了,一个协调器组网带了20个end device,过了一个晚上后发现有15个终端设备处于失去父节点状态,一直不能重新入网,其余的5个设备连接状态正常,搜索了相关问题资料,如 http://www.kaleidscope.cn:1020/archives/992   做了修改测试,还是不行,也是要协调器端开启permitjoin才能重新入网。 

  • 你好,http://www.kaleidscope.cn:1020/archives/992这帖子是我的,我使用的是Mesh1.0.0,当时提供的方法,我们几个小伙伴都遇到这样的问题,必须开permitjoin才可以,后来按照的方法修改后是可以解决这个问题的。这种问题当时一般是出现在信号弱的终端节点上。

    如果你们还是不能解决我建议在协调器上做心跳检测,如果检测到某个节点掉线了就自动打开Permitjoin一段时间,等待节点再次加入。

    如果有更好的解决办法望分享。

  • 谢谢回复,我使用的也是Z-Stack Mesh 1.0.0版本,看过代码,其实在ZDApp.c的第1600行左右,当devStartMode = MODE_REJOIN;时紧跟着 _tmpRejoinState = true; 已经对_tmpRejoinState 置成ture了,所以在ZDApp_NetworkInit里面添加的语句这么看是多余的。

    出现的终端掉线重连不了的问题还没解决。 

    分析出来的是终端掉线后若重启有RESUME模式进入orphan状态,发送orphan notification,协调器没有回coord  realignment,而后状态立刻切到rejoin模式搜索网络,这时就必须协调器开启 permit join 才能重新入网。

  • 这个问题我们也碰到的,目前已经解决了。问题的本身其实就是密钥被清除了,代码内可以搜索到,做法上我们是改写了重连的机制,不让他清楚密钥,并且开启Rejoin 为True ,始终允许重连,就可以了。

  • @xiaobo zhang 的回答是正解!

    @我要把牛头上交国家   这种做法只适应老版本的zstack 。  也许老版本的zstack 也有这样的问题,

  • @Xiaobo Zhang @MarS  谢谢! 秘钥清除的函数应该是ZDApp_ResetNwkKey吧,搜了下应用层并没有调用,调用处应该在闭源部分。 如果限制清除秘钥,就只能在这个函数里直接return; 而不做任何动作即可,是这样吗? 

    另外,您说的“开启rejoin为true”, 应该在协调器端修改吧? 如何修改比较合适,能否贴段代码参考呀? 谢了!

  • void ZDApp_ProcessNetworkJoin( void )

    {

      if ( (devState == DEV_NWK_JOINING) ||
          ((devState == DEV_NWK_ORPHAN)  &&
           (ZDO_Config_Node_Descriptor.LogicalType == NODETYPE_ROUTER)) )
     {

      ...

     }

      else if ( devState == DEV_NWK_ORPHAN ||
                devState == DEV_NWK_SEC_REJOIN_CURR_CHANNEL ||
                devState == DEV_NWK_TC_REJOIN_CURR_CHANNEL ||
                devState == DEV_NWK_TC_REJOIN_ALL_CHANNEL ||
                devState == DEV_NWK_SEC_REJOIN_ALL_CHANNEL )
      {
        // results of an orphaning attempt by this device
        if (nwkStatus == ZSuccess)
        {

                ...

         }

         else
        {
          if ( devStartMode == MODE_RESUME )
          {

             ...

          }

          else if(devStartMode == MODE_REJOIN)
          {
            if ( ZSTACK_END_DEVICE_BUILD )
            {
              devStartMode = MODE_REJOIN;
              _tmpRejoinState = true;
              _NIB.nwkState = NWK_INIT;

              if( prevDevState == DEV_NWK_SEC_REJOIN_CURR_CHANNEL )
              {
                runtimeChannel = MAX_CHANNELS_24GHZ;
                prevDevState = DEV_NWK_SEC_REJOIN_ALL_CHANNEL ;
              }
              else if ( prevDevState == DEV_NWK_SEC_REJOIN_ALL_CHANNEL)
              {
                // Set the flag that will ask the device to do trust center network layer rejoin.
                // 网络密钥无需擦除,避免强干扰状态下,
                // 长时间没有收到新的网络密钥,进而复位到未入网状态
                // 造成无法重新入网情况
                //_NIB.nwkKeyLoaded = FALSE;
                //ZDApp_ResetNwkKey(); // Clear up the old network key.
              #ifdef DEBUG_REJOIN
                HalUARTWrite(0,"Don't clearing network key\n", sizeof("Don't clearing network key\n"));
              #endif            
                runtimeChannel = (uint32) (1L << _NIB.nwkLogicalChannel);
                prevDevState = DEV_NWK_TC_REJOIN_CURR_CHANNEL ;
              }

         }

    }

    }

  • 感谢提供思路和解决方法,我已经备份至http://www.kaleidscope.cn:1020/archives/992 ,侵删。

  • 你好,我用zstack不做什么修改(不加按键什么的控制组网)  ,终端什么时候都可以入网,那个Permitjoin是不是一直开着的?

  • 默认一直打开Permitjoin

  • @MarS ,您好!谢谢您的回复,您贴的这部分代码以及关键的那2两行关于nwkkey被清除导致终端掉线后重连不上的代码,我搜索了工程并没有这部分,ZDApp_ResetNwkKey,并没有调用, 我用的是Z-Stack Mesh 1.0.0 版本,请问您用的是哪个版本?

    所以这么看,问题还不是这么简单的,还需继续探讨啊。

  • 我用到 就是 Zstack HA 1.2.2a

    我们用到可能不一样!!!

  • 我使用这种方法的话,还是不行,附件说我的抓包log,请求帮助

  • @VV

    我的网关使用的是ZHA1.2.2的,也是出现无法重入网的,按照http://www.kaleidscope.cn:1020/archives/992这个改了之后,还是一直无法重现入网,附件是我的抓包log,求助一下。

    728log.rar
  • 我使用1.2.2的终端长时间测试也会发生这个问题。突然掉线就再也连不回来了,除非协调器再次开始入网。网络只有一个协调器和一堆终端,并且协调器开始了zgRouterOffAssocCleanup=true,不知道跟这个是否有关系。终端都开启了childage使用datarequest方式。

    根据终端灯闪的情况,以及掉线后灯闪烁情况判断可能就是进入了

    ZDApp_ResetTimerStart( MAX_DEVICE_UNAUTH_TIMEOUT );
    你后面的分析:

    但是在此之前  终端设备 进入 predevState == DEV_NWK_SEC_REJOIN_ALL_CHANNEL 时,

          会把NWK KEY 清掉。。。。

    感觉是可能的,如果终端多次掉线或没有快速连回来,终端会在rejoion模式下面切换当前信道和所有信道。当切换到所有信道时候会清楚key。那么下次rejoin成功的时候就发现key消失了,从而终端恢复出厂设置,除非再次开始入网。

    那你是怎么解决的呢?不让终端扫描所有信道了吗DEV_NWK_SEC_REJOIN_ALL_CHANNEL?只在当前信道吗?

  • 我也遇到这种问题了,请问能不能具体点是怎么解决的?

  • 如果你的zstack比较老,建议用新点的可以避免很多bug。
  • 用的 z-stack home 1.2.2a
  • 我当时用的zstack2.5.多,好像并不比你这个版本新。之前出问题是2.4.x,几年没搞zigbee了,记得当时更新到2.5之后解决了很多bug。后面没出现这个问题了。

  • Hello All,我就是你们提到的www.kaleidscope.cn:1020这个网站的本人,其中对于一直beacon的问题(Mesh1.0.0),我也采取了很多操作,包括重启,但是一直没有从根本上解决问题,直到去年才真正的解决了,我在设备掉线后添加了一些东西,目前设备一直未再出现过掉线后一直beacon request而没有响应的问题。

    由于我已经一年多没写代码了,现在也没有从事编码的工作,需要的朋友可以通过我的网站联系我,上面有我的QQ。我会无偿给大家提供这个问题的解决办法。(这个办法是自己多次试验尝试出来的,不一定是最优解)

    后面这个网站我会继续维护,域名在19年4月份后将取消kaleidscope这个域名改用iot.lh1992.cn,如果明年还有人看到这个帖子,请使用最新的域名访问。

  • 网站地址已经变更为:iot.lh1992.cn/archives/992