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.

[参考译文] CC2530:如果 ZR/ZED 收到的传输密钥(TCLK)没有请求密钥、默认行为是什么?

Guru**** 2587365 points
Other Parts Discussed in Thread: Z-STACK, CC2530

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum/993942/cc2530-what-s-default-behaviour-if-zr-zed-received-tranport-key-tclk-without-request-key

器件型号:CC2530
Thread 中讨论的其他器件: Z-stack

尊敬的 Ryan Brown1和 YK:

 很长时间了、很抱歉中断、我们在 CC2530的 Z-stack 3.0.2上遇到了一个奇怪的行为、这导致我们的器件(ZR)丢失 ZigBee 网络(看起来像是离开、但没有收到任何离开请求) 在下一个下电上电周期中、众所周知、z-stack 3.0.2一直非常稳定 、直到现在、即使没有更新、也至少有3年以上的时间、因此我们不认为堆栈有一些缺陷。

因此、我们 必须研究 BDB 规格文档才能找到一些事实。 ZigBee Alliance 的 BDB 规范

"10.2.6接收新的链路密钥" BDB 文档表格描述了如果节点接收 到传输密钥包含 TCLK 但尚未发送请求密钥时的行为、它应忽略该消息以及变量 acceptNewUnrequestedTrustCenterLinkKey
 看起来就像在 ZDSecMgr.c 源文件中找到的、但 它是注释、因此我们不知道 z-stack 中的行为。

附件是我们的 OTA 捕获、ubiqua、0xE46C 和0xA1D7会在下一个下电上电周期中丢失 ZigBee 网络信息。

非常感谢。

e2e.ti.com/.../0xE46C-and-0xA1D7-loss-network-information.zip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、

    感谢您分享本节的 BDB 规格。  在 Z-Stack 3.0.2或 SimpleLink SDK 中、Z-Stack 解决方案中似乎不存在这种情况。  很可能会错过、因为它不在任何测试用例中、与平台认证无关。  无论如何、都应该解决这个问题、我已经通知软件开发团队、他们可以相应地实施解决方案。    尽管  Z-Stack 代码中没有特定的 RequestNewTrustCenterLinkKey 布尔值、但我建议您将其添加到 ZDSecMgr.c 中、该值在 bdb.c 中的 bdb_acceptTCLinkKey 期间初始化为 false、然后在 ZDSecMgrTransportKeyInd 中进行检查和重置。

    此致、
    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我将把我的更改粘贴到 z-stack 中、这可能会对更多工程师有所帮助。

    BDB.c

    extern bool acceptNewUnsolicitedApplicationLinkKey;
    
    
    
    
    /*********************************************************************
     * @fn      bdb_ProcessNodeDescRsp
     *
     * @brief   Process Node Descriptor response to validate the stack version of the
     *
     * @param   zdoIncomingMsg_t *pMsg
     *
     * @return  none
     */
    void bdb_ProcessNodeDescRsp(zdoIncomingMsg_t *pMsg)
    {
      //Avoid processing unintended messages
      if(requestNewTrustCenterLinkKey && 
        (bdbCommissioningProcedureState.bdbCommissioningState == BDB_COMMISSIONING_STATE_TC_LINK_KEY_EXCHANGE))
      {
        if(!APSME_IsDistributedSecurity())
        {
          //Is this from the coordinator?
          if(pMsg->srcAddr.addr.shortAddr == 0x0000)
          {
            ZDO_NodeDescRsp_t NDRsp;
            uint8 StackComplianceRev;
    
            //Stop timer to avoid unintended resets
            osal_stop_timerEx( bdb_TaskID, BDB_PROCESS_TIMEOUT);
            
            ZDO_ParseNodeDescRsp(pMsg, &NDRsp);
            
            StackComplianceRev = NDRsp.nodeDesc.ServerMask >> STACK_COMPLIANCE_CURRENT_REV_POS;
            
            if( StackComplianceRev >= STACK_COMPL_REV_21 )
            {
              acceptNewUnsolicitedApplicationLinkKey = TRUE;
              bdb_tcLinkKeyExchangeAttempt(TRUE,BDB_REQ_TC_LINK_KEY);
            }
            else
            {
              APSME_TCLKDevEntry_t TCLKDevEntry;
              
              //Save the KeyAttribute for joining device that it has joined non-R21 nwk
              TCLKDevEntry.keyAttributes = ZG_NON_R21_NWK_JOINED;
              osal_nv_write(ZCD_NV_TCLK_TABLE_START,osal_offsetof(APSME_TCLKDevEntry_t,keyAttributes),sizeof(uint8),&TCLKDevEntry.keyAttributes);
              
              bdb_setNodeJoinLinkKeyType(BDB_DEFAULT_GLOBAL_TRUST_CENTER_LINK_KEY);
              bdb_reportCommissioningState(BDB_COMMISSIONING_STATE_TC_LINK_KEY_EXCHANGE, TRUE);
            }
          }
        }
      }
    }

    ZDSecMgr.c

    bool acceptNewUnsolicitedApplicationLinkKey = FALSE;
    
    
    
    /******************************************************************************
     * @fn          ZDSecMgrTransportKeyInd
     *
     * @brief       Process the ZDO_TransportKeyInd_t message.
     *
     * @param       ind - [in] ZDO_TransportKeyInd_t indication
     *
     * @return      none
     */
    void ZDSecMgrTransportKeyInd( ZDO_TransportKeyInd_t* ind )
    {
      uint8 index;
      uint8 zgPreConfigKey[SEC_KEY_LEN];
    
      ZDSecMgrUpdateTCAddress( ind->srcExtAddr );
      
    #if ZG_BUILD_JOINING_TYPE
      if(ZG_DEVICE_JOINING_TYPE)
      {
        //Update the TC address in the entry
        osal_nv_write(ZCD_NV_TCLK_TABLE_START, osal_offsetof(APSME_TCLKDevEntry_t,extAddr), Z_EXTADDR_LEN, ind->srcExtAddr);
      }
    #endif
      
      // check for distributed security
      if ( ( ZG_BUILD_RTR_TYPE ) && osal_isbufset( ind->srcExtAddr, 0xFF, Z_EXTADDR_LEN ) )
      {
        ZDSecMgrPermitJoiningEnabled = TRUE;  
      }
      
      // load Trust Center data if needed
      ZDSecMgrTCDataLoad( ind->srcExtAddr );
      
      if ( ( ind->keyType == KEY_TYPE_NWK ) ||
           ( ind->keyType == 6            ) )
      {
        // check for dummy NWK key (all zeros)
        for ( index = 0;
              ( (index < SEC_KEY_LEN) && (ind->key[index] == 0) );
              index++ );
    
        if ( index == SEC_KEY_LEN )
        {
          // load preconfigured key - once!!
          if ( !_NIB.nwkKeyLoaded )
          {
            ZDSecMgrReadKeyFromNv(ZCD_NV_PRECFGKEY, zgPreConfigKey);
            SSP_UpdateNwkKey( zgPreConfigKey, 0 );
            SSP_SwitchNwkKey( 0 );
    
            // clear local copy of key
            osal_memset(zgPreConfigKey, 0x00, SEC_KEY_LEN);
          }
        }
        else
        {
          SSP_UpdateNwkKey( ind->key, ind->keySeqNum );
          if ( !_NIB.nwkKeyLoaded )
          {
            SSP_SwitchNwkKey( ind->keySeqNum );
          }
        }
    
        // handle next step in authentication process
        ZDSecMgrAuthNwkKey();
      }
      else if ( ind->keyType == KEY_TYPE_TC_LINK )
      {
        uint16 entryIndex;
        uint8 found;
        APSME_TCLKDevEntry_t TCLKDevEntry;
        
        // according to BDB specification (zigbeealliance.org/.../docs-13-0402-13-00zi-Base-Device-Behavior-Specification-2-1.pdf)
        // chapter "10.2.6 Receiving new Link Keys"
        // node has not sent a request for one and acceptNewUnsolicitedTrustCenterLinkKey is set to FALSE,we SHALL ignore the message
        if(acceptNewUnsolicitedApplicationLinkKey == TRUE)
        {
          //Search the entry, which should exist at this point
          entryIndex = APSME_SearchTCLinkKeyEntry(ind->srcExtAddr, &found, &TCLKDevEntry);
    
          if(found)
          {
            //If the key was an IC, then erase the entry since that will not longer be used.
            if(TCLKDevEntry.keyAttributes == ZG_PROVISIONAL_KEY)
            {
              APSME_EraseICEntry(&TCLKDevEntry.SeedShift_IcIndex);
            }
            
            TCLKDevEntry.keyAttributes = ZG_UNVERIFIED_KEY;
            TCLKDevEntry.keyType = ZG_UNIQUE_LINK_KEY;
            TCLKDevEntry.rxFrmCntr = 0;
            TCLKDevEntry.txFrmCntr = 0;
            TCLKDevEntry.SeedShift_IcIndex = 0;
            
            //Update the entry
            osal_nv_write(entryIndex,0,sizeof(APSME_TCLKDevEntry_t),&TCLKDevEntry);
    
            //Create the entry for the key
            if(ZSUCCESS == osal_nv_item_init(ZCD_NV_TCLK_JOIN_DEV,SEC_KEY_LEN,ind->key) )
            {
              //Or replace it if already existed
              osal_nv_write(ZCD_NV_TCLK_JOIN_DEV,0,SEC_KEY_LEN,ind->key);
            }
            
            acceptNewUnsolicitedApplicationLinkKey = FALSE;
            bdb_tcLinkKeyExchangeAttempt(TRUE,BDB_REQ_VERIFY_TC_LINK_KEY);
          }
        }
      }
      else if ( ind->keyType == KEY_TYPE_APP_LINK )
      {
        if ( ZG_CHECK_SECURITY_MODE == ZG_SECURITY_SE_STANDARD )
        {
          uint16           ami;
          ZDSecMgrEntry_t* entry;
    
          // get the address index
          if ( ZDSecMgrExtAddrLookup( ind->srcExtAddr, &ami ) != ZSuccess )
          {
            // store new EXT address
            ZDSecMgrAddrStore( INVALID_NODE_ADDR, ind->srcExtAddr, &ami );
            ZDP_NwkAddrReq( ind->srcExtAddr, ZDP_ADDR_REQTYPE_SINGLE, 0, 0 );
          }
    
          ZDSecMgrEntryLookupAMI( ami, &entry );
    
          if ( entry == NULL )
          {
            // get new entry
            if ( ZDSecMgrEntryNew( &entry ) == ZSuccess )
            {
              // finish setting up entry
              entry->ami = ami;
            }
          }
    
          ZDSecMgrLinkKeySet( ind->srcExtAddr, ind->key );
    
    #if defined NV_RESTORE
          ZDSecMgrWriteNV();  // Write the control record for the new established link key to NV.
    #endif
        }
      }
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您分享。