微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 无线和射频 > TI Zigbee设计交流 > 终端设备无法重入网络 使用 (zstack1.2.2a)

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

时间:10-02 整理:3721RD 点击:

测试环境:

        一个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:6303.1.2.2断网后response成功但实际无法入网要重开permitjoin.rar

情况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 :3364.rejoin request 有ACK 但没有rejoin response.rar

另外一个log  说明一下:

log :2626.rejoin response成功但实际无法入网要重开permitjoin.rar

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,当时Susan Yang提供的方法,我们几个小伙伴都遇到这样的问题,必须开permitjoin才可以,后来按照Susan Yang的方法修改后是可以解决这个问题的。这种问题当时一般是出现在信号弱的终端节点上。

如果你们还是不能解决我建议在协调器上做心跳检测,如果检测到某个节点掉线了就自动打开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,请求帮助

log抓包文件

@VV

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

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top