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.

设备被leave

协议栈:3.0.2

芯片:2530

问题:早上好。我现在有一个EndDevice以及一个Coordinator,这两个设备都开启了NV_RESTORE,当我将EndDevice断电之后重连,发现被ZC踢出网络,在重上电之前这两个设备是能正常通讯的。求解,谢谢。抓包档附上2019年8月16日09_00_20_终端重连被踢出网络.rar

  • 请说明做了什么改动,以及断电时长。 是否用SDK里面的generic demo 测试。
  • 你好,我的改动是GenericAPP的应用层,并没有涉及到网络的主动leave。
  • 你这抓包文件看不出来什么,所以我让你SDK原始demo去对比一下做一下测试
  • 改动这么大原始的demo还有参考价值吗
  • 因为不知道客户具体做了什么改动,只能让客户自己去比对了
  • 那请帮忙看看这个抓包档的第2976行以后是什么情况?协调器最后为什么没有响应终端的data request呢?而且终端为啥不发孤儿节点声明呢?请教,谢谢。2019年8月15日18_06_05_第2976行自动掉线.rar

  • 你打点一下断电在下面看是否又进入到变为orphan
    case ZDO_STATE_CHANGE:
    zclGenericApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
  • 你好,我的意图是当终端变为孤儿节点的时候让他重新加网,所以我在zclGenericApp_NwkState == DEV_NWK_ORPHAN里面让LED灯熄灭,从结果来看灯的确是熄灭了,可是抓包文件没有看到orphan 声明,终端也并没有rejoin网络,我是有开启NV_RESTORE的,代码如下,谢谢。

    case ZDO_STATE_CHANGE:
            zclGenericApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
            
            // now on the network
            if ( (zclGenericApp_NwkState == DEV_ROUTER)   ||
                (zclGenericApp_NwkState == DEV_END_DEVICE) )
            {
              osal_start_timerEx( zclGenericApp_TaskID, SEND_MESSAGE_EVT, 1000);
              osal_stop_timerEx( zclGenericApp_TaskID, JOIN_LED_BLINK_EVT );
              net_blink_flg = FALSE;
            }
            if(zclGenericApp_NwkState == DEV_NWK_ORPHAN)
            {
              HAL_TURN_OFF_RED_LED2();
              HAL_TURN_OFF_BLUE_LED2();
              bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_STEERING ); 
            }
            break;

  • 这部分你是可以不用做的,Stack已经做了orphan的扫描恢复网络的步骤。
    case BDB_COMMISSIONING_PARENT_LOST:
    if(bdbCommissioningModeMsg->bdbCommissioningStatus == BDB_COMMISSIONING_NETWORK_RESTORED)
    {
    //We did recover from losing parent
    }
    else
    {
    //Parent not found, attempt to rejoin again after a fixed delay
    osal_start_timerEx(zclGenericApp_TaskID, GENERICAPP_END_DEVICE_REJOIN_EVT, GENERICAPP_END_DEVICE_REJOIN_DELAY);
    }
    break;

    把下面的补丁打一下,你自己那个扫网可以去掉的,说起来比较奇怪你没有做BDB和ZDO层的改变吧。

    processors.wiki.ti.com/.../Zigbee_Known_Issues_and_Proposed_Fixes
  • 1.是的我没有改变BDB以及ZDO层,我奇怪的是为何我的终端没有像您贴出的代码这样做rejoin动作以及没有发orphan声明。我要如何实现
    终端rejoin呢?
    2.你让我打的补丁是关于协调器leave我的终端的问题吗?可是我的终端设备也就两个,这似乎不存在网络缓冲区溢出的情况吧。
  • 我也不清楚你的原因,我让你去SDK的demo 测试你的板子也不能rejoin吗?
  • 1. 我这边用genericapp的demo,仅仅在应用层的初始化上加了一条bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_STEERING ); 然后测试发现:能成功入网,但是当我将协调器断电的情况下,终端没有发出orphan声明,不过断网之后的beacon request倒好像是10s一次。抓包文件附上2019年8月19日15_33_00_用demo测试终端在协调器断电的情况下是否会发orphan.rar

    2. 我项目的EndDevice为啥在协调器断网之后完全不会发orphan以及beacon request呢,一点动作都没有。

  • 1.
    #define GENERICAPP_END_DEVICE_REJOIN_DELAY 10000
    10S一次是正常的,代码中启动的是一个10 rejion scan 一次就是我上面给你贴的那部分程序。
    2.所以是你应用层做了什么我不得而知很难帮你,你可以自己比对一下。多说一句客户基本无需管理网络部分的操作,入网之后协议栈自己会维护网络。
  • 我知道10s一次是正常的,可是没有发orphan封包是为什么呢
  • 是不是有了 beacon request 每10s
  • 在zigbee 3.0 feature里面
    orphan notification 已经被取消了
  • 或者说弃用了
  • 那请问我并没有改动zclGenericApp_ProcessCommissioningStatus的情况下,为何触发不了osal_start_timerEx(zclGenericApp_TaskID, GENERICAPP_END_DEVICE_REJOIN_EVT, GENERICAPP_END_DEVICE_REJOIN_DELAY);这个rejoin事件呢。我在ZDO层完全没有改动过关于DEV_END_ORPHAN状态的函数。谢谢。
  • 你把你在状态改变为orphan 那段sterring的程序去掉。zclGenericApp_ProcessCommissioningStatus处理的BDB层的应用。
  • 你可以尝试就保留第一次入网的操作,其余关于网络层的操作都去掉。
  • 我照你所说的将关于我自己写的orphan的一段注释掉了

            // now on the network
            if ( (zclGenericApp_NwkState == DEV_ROUTER)   ||
                (zclGenericApp_NwkState == DEV_END_DEVICE) )
            {
              osal_start_timerEx( zclGenericApp_TaskID, SEND_MESSAGE_EVT, 1000);
              osal_stop_timerEx( zclGenericApp_TaskID, JOIN_LED_BLINK_EVT );
              net_blink_flg = FALSE;
            }
    //        if(zclGenericApp_NwkState == DEV_NWK_ORPHAN)
    //        {
    //          HAL_TURN_OFF_RED_LED2();
    //          HAL_TURN_OFF_BLUE_LED2();
    //          bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_STEERING ); 
    //        }
            break;

    然后我在zclGenericApp_ProcessCommissioningStatus函数里面在处理rejoin事件之前加了我自己的闪灯事件

    case BDB_COMMISSIONING_PARENT_LOST:
          if(bdbCommissioningModeMsg->bdbCommissioningStatus == BDB_COMMISSIONING_NETWORK_RESTORED)
          {
            //We did recover from losing parent
          }
          else
          {
            net_blink_flg = TRUE;
            osal_set_event( zclGenericApp_TaskID, JOIN_LED_BLINK_EVT );
            //Parent not found, attempt to rejoin again after a fixed delay
            osal_start_timerEx(zclGenericApp_TaskID, GENERICAPP_END_DEVICE_REJOIN_EVT, GENERICAPP_END_DEVICE_REJOIN_DELAY);
          }

    从结果来看,在协调器掉电之后,的确进入了此处这个else的分支,LED会闪,但是抓包并没有发现EndDevice 做出beacon request的动作,请问这个事件是否是封装不开源的?我全局查找不到这个事件。如果此处不能做rejoin动作,那我该如何在EndDevice掉网之后做出重连机制。谢谢

  • 你没有认真去看程序吧:


    #if ZG_BUILD_ENDDEVICE_TYPE
    if ( events & GENERICAPP_END_DEVICE_REJOIN_EVT )
    {
    bdb_ZedAttemptRecoverNwk();
    return ( events ^ GENERICAPP_END_DEVICE_REJOIN_EVT );
    }



    uint16 zclGenericApp_event_loop( uint8 task_id, uint16 events )
    {
    afIncomingMSGPacket_t *MSGpkt;

    (void)task_id; // Intentionally unreferenced parameter

    if ( events & SYS_EVENT_MSG )
    {
    while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclGenericApp_TaskID )) )
    {
    switch ( MSGpkt->hdr.event )
    {
    case ZCL_INCOMING_MSG:
    // Incoming ZCL Foundation command/response messages
    zclGenericApp_ProcessIncomingMsg( (zclIncomingMsg_t *)MSGpkt );
    break;

    case KEY_CHANGE:
    zclGenericApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
    break;

    case ZDO_STATE_CHANGE:
    zclGenericApp_NwkState = (devStates_t)(MSGpkt->hdr.status);

    // now on the network
    if ( (zclGenericApp_NwkState == DEV_ZB_COORD) ||
    (zclGenericApp_NwkState == DEV_ROUTER) ||
    (zclGenericApp_NwkState == DEV_END_DEVICE) )
    {
    giGenAppScreenMode = GENERIC_MAINMODE;
    zclGenericApp_LcdDisplayUpdate();
    }
    break;

    default:
    break;
    }

    // Release the memory
    osal_msg_deallocate( (uint8 *)MSGpkt );
    }

    // return unprocessed events
    return (events ^ SYS_EVENT_MSG);
    }

    if ( events & GENERICAPP_MAIN_SCREEN_EVT )
    {
    giGenAppScreenMode = GENERIC_MAINMODE;
    zclGenericApp_LcdDisplayUpdate();

    return ( events ^ GENERICAPP_MAIN_SCREEN_EVT );
    }

    #if ZG_BUILD_ENDDEVICE_TYPE
    if ( events & GENERICAPP_END_DEVICE_REJOIN_EVT )
    {
    bdb_ZedAttemptRecoverNwk();
    return ( events ^ GENERICAPP_END_DEVICE_REJOIN_EVT );
    }
    #endif

    /* GENERICAPP_TODO: handle app events here */


    if ( events & GENERICAPP_EVT_1 )
    {
    // toggle LED 2 state, start another timer for 500ms
    HalLedSet ( HAL_LED_2, HAL_LED_MODE_TOGGLE );
    osal_start_timerEx( zclGenericApp_TaskID, GENERICAPP_EVT_1, 500 );

    return ( events ^ GENERICAPP_EVT_1 );
    }

    /*
    if ( events & GENERICAPP_EVT_2 )
    {

    return ( events ^ GENERICAPP_EVT_2 );
    }

    if ( events & GENERICAPP_EVT_3 )
    {

    return ( events ^ GENERICAPP_EVT_3 );
    }
    */

    // Discard unknown events
    return 0;
    }
  • 问题已解决,原来是我裁剪协议栈的时候将这个事件误删,抱歉,谢谢您的解答。