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.

用zcl_SendReportCmd

Other Parts Discussed in Thread: CC2530, Z-STACK

协议栈: Z-stack 3.0.2 
参考程序为:GenericApp
芯片型号:CC2530

问题:我使用按键触发了一个通过zcl_SendReportCmd报告自定义数据的函数,抓包显示发出去了接收方也ACK了,可是抓到的无线数据包多了9个字节的数据,并且接收方好像没有进入case ZCL_CMD_REPORT里面,求解,感谢。关键以及抓包文件附上。7月30日18_26_33_test1.rar

//发送方发送函数
void GenericApp_SendTheMessage(void)
{
  zclReportCmd_t *pReportCmd;
  uint8 send_data[5] = {0x04,0x11,0x22,0x33,0x99};
  
  afAddrType_t devDstAddr;
  devDstAddr.addrMode=(afAddrMode_t)Addr16Bit;
  devDstAddr.endPoint=GENERICAPP_ENDPOINT;
  devDstAddr.addr.shortAddr=0x0000; 
  
  pReportCmd = osal_mem_alloc( sizeof(zclReportCmd_t) + sizeof(zclReport_t) );
  if ( pReportCmd != NULL )
  {
    pReportCmd->numAttr = 1;
    pReportCmd->attrList[0].attrID = ATTRID_ON_OFF;
    pReportCmd->attrList[0].dataType = ZCL_DATATYPE_UINT64;
    pReportCmd->attrList[0].attrData = (uint8*)send_data;
    
    zcl_SendReportCmd( GENERICAPP_ENDPOINT, &devDstAddr,
                       ZCL_CLUSTER_ID_GEN_ON_OFF,
                        pReportCmd, ZCL_FRAME_SERVER_CLIENT_DIR, TRUE, bdb_getZCLFrameCounter() );
  }
  osal_mem_free(pReportCmd);
}
//接收方
void zclGenericApp_ProcessInReportCmd(  zclIncomingMsg_t *pInMsg )
{
  zclReportCmd_t *pReportCmd;
  pReportCmd=(zclReportCmd_t *)pInMsg->attrCmd;
  
  
  if ( pReportCmd->attrList[0].attrID == ATTRID_ON_OFF )
  { 
    HalUARTWrite(0,pReportCmd->attrList[0].attrData,5 );
    HalUARTWrite(0,"success",sizeof("success") );
  }
  else
  {
    HalUARTWrite(0,"fail",sizeof("fail") );
  }
}

  • 看了你的抓包文件,没有问题。但是数据只有0x04是正常的,如果你想传输一个字符串请使用自定义的cluster。因为你用的是on/off report 上传的应该为light的状态所以只有一位。如果你想使用report 建议去使用SampleTemperatureSensor和SampleThermostat

  •  你好,这抓包里面确实发出了我想要发的数据,照你的意思是有用的数据就只是0x04是吗?

  • 是的,因为按照zcl spec on/off report 是一个状态位,不建议你用已经规定好的去做你自己私有协议。你可以自己去定义一个cluster。
  • 好的,那我接收方是否在case ZCL_CMD_REPORT此处处理传入的report数据呢?感谢
  • static void zclGenericApp_ProcessIncomingMsg( zclIncomingMsg_t *pInMsg )
    {
      switch ( pInMsg->zclHdr.commandID )
      {
    #ifdef ZCL_READ
        case ZCL_CMD_READ_RSP:
          zclGenericApp_ProcessInReadRspCmd( pInMsg );
          break;
    #endif
    #ifdef ZCL_WRITE
        case ZCL_CMD_WRITE_RSP:
          zclGenericApp_ProcessInWriteRspCmd( pInMsg );
          break;
    #endif
        case ZCL_CMD_CONFIG_REPORT:
        case ZCL_CMD_CONFIG_REPORT_RSP:
        case ZCL_CMD_READ_REPORT_CFG:
        case ZCL_CMD_READ_REPORT_CFG_RSP:
          //bdb_ProcessIncomingReportingMsg( pInMsg );
          break;
          
         case ZCL_CMD_REPORT:
          zclGenericApp_ProcessInReportCmd( pInMsg );
         break;
          
        case ZCL_CMD_DEFAULT_RSP:
          zclGenericApp_ProcessInDefaultRspCmd( pInMsg );
          break;
    
        default:
          break;
      }
    
      if ( pInMsg->attrCmd )
        osal_mem_free( pInMsg->attrCmd );
    }

  • 我想请问我接受方定义了ZCL_CLUSTER_ID_GEN_ON_OFF作为输入簇,report的处理程序如题第二段程序,可是我串口看不到预计的字符串,单用串口收发是没有问题的,何解?
  • 串口看不到预计的字符串是什麼意思?你設置斷點在 ZCL_CMD_REPORT會在收到 ZCL report的時候停在斷點上嗎?
  • 就是我在接收方的zclGenericApp_ProcessInReportCmd函数里加了一条打印“success”字符串的语句,结果没有显示我想要的“success”。我感觉接收方并没有进入到ZCL_CMD_REPORT里面。
  • 你設置斷點在 ZCL_CMD_REPORT去調試的話,會在收到 ZCL report的時候停在斷點上嗎?
  • 你好,不会停在 ZCL_INCOMING_MSG,然后我在ZCL_INCOMING_MSG下加了一个串口输出函数也不能输出数据。

    case ZCL_INCOMING_MSG:
             HalUARTWrite(0,"success",sizeof("success") );
            // Incoming ZCL Foundation command/response messages
            zclGenericApp_ProcessIncomingMsg( (zclIncomingMsg_t *)MSGpkt );
            break;

  • 你GenericApp的OutCluster有加上ZCL_CLUSTER_ID_GEN_ON_OFF嗎?

  • 你好,我现在是自定义了一个cluster,能发出数据,但是也和ON/OFF  cluster一样接收方接受不到report,我已在接收方的inclusterlist里添加了自定义的cluster,求解。代码以及抓包文件附上。

    //发送方
    const cId_t zclGenericApp_OutClusterList[] =
    {
      ZCL_CLUSTER_ID_GEN_BASIC,
      ZCL_CLUSTER_ID_HEART,
      
      // GENERICAPP_TODO: Add application specific Output Clusters Here. 
      //       See zcl.h for Cluster ID definitions
    };
    
    void GenericApp_SendTheMessage(void)
    {
      zclReportCmd_t *pReportCmd;
      uint8 send_data[5] = {0x04,0x11,0x22,0x33,0x99};
      
      afAddrType_t devDstAddr;
      devDstAddr.addrMode=(afAddrMode_t)Addr16Bit;
      devDstAddr.endPoint=GENERICAPP_ENDPOINT;
      devDstAddr.addr.shortAddr=0x0000; 
      
      pReportCmd = osal_mem_alloc( sizeof(zclReportCmd_t) + sizeof(zclReport_t) );
      if ( pReportCmd != NULL )
      {
        pReportCmd->numAttr = 1;
        pReportCmd->attrList[0].attrID = ATTRID_HEART_REPORTING;
        pReportCmd->attrList[0].dataType = ZCL_DATATYPE_CHAR_STR;
        pReportCmd->attrList[0].attrData = (uint8*)send_data;
        
        zcl_SendReportCmd( GENERICAPP_ENDPOINT, &devDstAddr,
                           ZCL_CLUSTER_ID_HEART,
                            pReportCmd, ZCL_FRAME_SERVER_CLIENT_DIR, TRUE, bdb_getZCLFrameCounter() );
      }
      osal_mem_free(pReportCmd);
    }
    //接收方
    const cId_t zclGenericApp_InClusterList[] =
    {
      ZCL_CLUSTER_ID_GEN_BASIC,
      ZCL_CLUSTER_ID_GEN_IDENTIFY,
      ZCL_CLUSTER_ID_HEART,
      
      // GENERICAPP_TODO: Add application specific Input Clusters Here. 
      //       See zcl.h for Cluster ID definitions
      
    };
    //接收方对report的处理函数没改变

    7月31日15_41_50_test1_自定义cluster.rar

  • 抱歉,剛剛打錯了,接收方的話要在OutCluster加上ZCL_CLUSTER_ID_GEN_ON_OFF/ZCL_CLUSTER_ID_HEART
  • 接收方是在OUTCLUSTERLIST还是INCLUSTERLIST?发送方不是OUTCLUSTERLIST吗?
  • ZCL report接收方是加在OutCluster
  • 你需要了解一下server和client的概念:
    e2echina.ti.com/.../439927
  • 我在接收方的outclusterlist加上了自定义的cluster测试过不行。

    const cId_t zclGenericApp_OutClusterList[] =
    {
      ZCL_CLUSTER_ID_GEN_BASIC,
      ZCL_CLUSTER_ID_HEART,                   
      
      // GENERICAPP_TODO: Add application specific Output Clusters Here. 
      //       See zcl.h for Cluster ID definitions
    };

  • 你發射端的cluster跟endpoint有設置對嘛?
  • 我不太理解zcl_SendReportCmd函数里面填的这个ZCL_FRAME_SERVER_CLIENT_DIR参数是什么意思。另外,我在发送端我是否添加我的自定义cluster进outclusterlist里面呢?至于endpoint的话发送方以及接受方都只有一个endpoint = 8 。
  • 發送zcl report的這端是server,接收端是client,zcl_SendReportCmd函数里面填的这个ZCL_FRAME_SERVER_CLIENT_DIR代表要從發送端(server)發送report給接收端(client),zcl report发送端應該添加自定义cluster进InCluster
  • 请问我这样设置对了吗,我测试了一下接受方仍然没有接受到数据,求解,感谢。

  • 設置斷點在zcl_event_loop的zcl_ProcessMessageMSG上,調試看看會不會停在斷點
  • 刚刚调试了一下,打了两个断点如图,发现在接收的时候两个断点都没有进入,没有任何反应。求解

  • 你有設置斷點在zcl_event_loop的zcl_ProcessMessageMSG上,調試看看會不會停在斷點嗎?

  • 请问是此处吗?还是别的地方?我调试此处的两个断点接收的时候并不会在此处停止。感谢

  • 不是、zcl_event_loop在zcl.c
  • 你好,调试发现会进入zcl.c的zcl_ProcessMessageMSG里的if ( !interPanMsg && zcl_ProfileCmd( inMsg.hdr.fc.type ) )的一个赋值语句 status = ZCL_STATUS_UNSUP_GENERAL_COMMAND;以及在这个函数的最末尾判断status的时候会返回return ( ZCL_PROC_NOT_HANDLED );求解这是什么情况,zcl_ProcessMessageMSG如何处理了我的数据包导致我接受不到呢?感谢

  • 你發送端怎樣送訊息的?

  • 发送方通过按键触发发送函数GenericApp_SendTheMessage,cluster为自定义的cluster

    #define ZCL_CLUSTER_ID_HEART                       0x2000 

    #define ATTRID_HEART_REPORTING                  0x0000 

    void GenericApp_SendTheMessage(void)
    {
      zclReportCmd_t *pReportCmd;
      uint8 send_data[5] = {0x04,0x11,0x22,0x33,0x99};
      
      afAddrType_t devDstAddr;
      devDstAddr.addrMode=(afAddrMode_t)Addr16Bit;
      devDstAddr.endPoint=GENERICAPP_ENDPOINT;
      devDstAddr.addr.shortAddr=0x0000; 
      
      pReportCmd = osal_mem_alloc( sizeof(zclReportCmd_t) + sizeof(zclReport_t) );
      if ( pReportCmd != NULL )
      {
        pReportCmd->numAttr = 1;
        pReportCmd->attrList[0].attrID = ATTRID_HEART_REPORTING;
        pReportCmd->attrList[0].dataType = ZCL_DATATYPE_CHAR_STR;
        pReportCmd->attrList[0].attrData = (uint8*)send_data;
        
        zcl_SendReportCmd( GENERICAPP_ENDPOINT, &devDstAddr,
                           ZCL_CLUSTER_ID_HEART,
                            pReportCmd, ZCL_FRAME_SERVER_CLIENT_DIR, TRUE, bdb_getZCLFrameCounter() );
      }
      osal_mem_free(pReportCmd);
    }
    // *** Heart Cluster Attributes ***
      {
        ZCL_CLUSTER_ID_HEART,
        { // Attribute record
          ATTRID_HEART_REPORTING,
          ZCL_DATATYPE_CHAR_STR,
          ACCESS_CONTROL_READ | ACCESS_REPORTABLE,
          (void *)&zclGenericApp_HeartReporting
        }
      },
      {
        ZCL_CLUSTER_ID_HEART,
        {  // Attribute record
          ATTRID_CLUSTER_REVISION,
          ZCL_DATATYPE_UINT16,
          ACCESS_CONTROL_READ,
          (void *)&zclGenericApp_clusterRevision_all
        }
      },
    const cId_t zclGenericApp_InClusterList[] =
    {
      ZCL_CLUSTER_ID_GEN_BASIC,
      ZCL_CLUSTER_ID_GEN_IDENTIFY,
      ZCL_CLUSTER_ID_HEART,
      
      // GENERICAPP_TODO: Add application specific Input Clusters Here. 
      //       See zcl.h for Cluster ID definitions
      
    };

  • 建議你詳讀一下 dev.ti.com/.../zigbee_02_custom_devices.html 照著步驟對應到CC2530 GenericApp 例程操作看看
  • Dear YiKai Chen:
    你觉得这个网址的步骤对我用自定义cluster 去zcl_SendReportCmd有什么帮助吗?
    1.接收方什么情况下会ACK了但是没有处理数据?
    2.是丢包了还是去哪里处理了?
    3.是否是我修改例程的时候删除了某处导致接收方不能正确处理的?
    4.处理数据关键需要什么条件或者步骤呢?
  • 請問这个网址的步骤你讀了嘛? 你的協調器是接收端,請問你預編譯上有沒有加上 ZCL_REPORT_DESTINATION_DEVICE
  • 你好,我读了网址的步骤没有发现你说的预编译宏,加上了之后已经成功了。原来只需要一个预编译的宏,讨论了这么多。感谢YiKai Chen以及Alvin Chen。谢谢。
  • 除了网址的的資訊,有時候你要深入看一下源碼才行

  • 谢谢指点,再次感谢。
  • 您好,看来你的贴子,实现了数据的发送和接受。但是我只是实现了一次的数据接受,之后就一直处于掉网掉网状态。 我的做法是在入网成功之后调用了 发送函数 ,从这之后网络就链接不上。

  • 有抓包檔嗎?
  • 從抓包看來你的設備沒有真的入網成功,他一直被leave又rejoin,你應該先解決這個問題
  • 之前是入网成功了,之后才是终端掉网了,之后总端一直入不了网,因该是这个过程吧?如果一开始没有入网成功,那我为什么会收到数据?
  • 没有真正的入网成功,一直被踢然后又rejoin,能收发数据是在入网到被踢的过程中有一个短暂的时间双方的通讯是建立起来的。你是不是用了3.0的协议栈设备去控制HA或者其他版本的协议栈的设备?
  • 没有,我都是用的z-stack 3.0.2 , GenericApp 这个例程,芯片 cc2530F256 。
  • z-stack 3.0.2 沒有修改的GenericApp 例程你就會看到終端設備入網又被leave?

  • #iflGenericApp_Init () (我之前实在这个初始话最底下加的 协调器
    bdb_StartCommissioning( BDB_COMMISSIONING_MODE_NWK_FORMATION |
    BDB_COMMISSIONING_MODE_FINDING_BINDING );
    NLME_PermitJoiningRequest(0xff);
    终端
    bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_STEERING | BDB_COMMISSIONING_MODE_FINDING_BINDING);
    之后在 入网失败的函数 zclGenericApp_ProcessCommissioningStatus(bdbCommissioningModeMsg_t *bdbCommissioningModeMsg)

    case BDB_COMMISSIONING_NWK_STEERING:
    if(bdbCommissioningModeMsg->bdbCommissioningStatus == BDB_COMMISSIONING_SUCCESS)
    {
    #if COORdonator /// COORdonatorEB 1 ; ENDdevice Rount 0 ;
    #else
    GenericApp_SendTheMessage();
    #endif

    //YOUR JOB:
    //We are on the nwk, what now?
    }
    else
    {

    P0SEL &= 0x7F;
    P0DIR |= 0x80;
    LED3 = ~LED3; //点亮LED3

    #if COORdonator /// COORdonatorEB 1 ; ENDdevice Rount 0 ;
    //bdb_StartCommissioning( BDB_COMMISSIONING_MODE_NWK_FORMATION |
    // BDB_COMMISSIONING_MODE_FINDING_BINDING );
    //NLME_PermitJoiningRequest(0xff);
    #else


    bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_STEERING | BDB_COMMISSIONING_MODE_FINDING_BINDING);
    #endif

    // //See the possible errors for nwk steering procedure
    // //No suitable networks found
    // //Want to try other channels?
    // //try with bdb_setChannelAttribute
    }
    break;
    添加了 bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_STEERING | BDB_COMMISSIONING_MODE_FINDING_BINDING); 你的意思是 在 GenericApp 什么都不添加吗?
  • 我好像已經建議過你协调器用
    bdb_StartCommissioning( BDB_COMMISSIONING_MODE_NWK_FORMATION | BDB_COMMISSIONING_MODE_NWK_STEERING);組網及開放入網
    不要用NLME_PermitJoiningRequest(0xff);
    终端用
    bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_STEERING );去入網

    你好像都沒在聽建議耶

  • 听了您的建议,我把程序入网改了,改成您说的,我之前 在OnBoatd.c InitBoard( uint8 level ) 把原先的按键查询发改成中断发了,好像对组网的之后有点影响,具体的原因还不知道。我想用按键的查询发,我现在用的引脚是 P1.5 P1.6 P1.6 。但是我调试发现 上电之后 P 1.5 引脚电平 P1.5 == 0 ; 之后看了初始化 ,例程 GenericApp LCD 用到了 P0_0 P1_1 P1.2 ;SPI P1.5 P1.6 P1.7 ; ?? ;为什么上电之后就执行 if ( keys & HAL_KEY_SW_1 ) {};这个条件的判断就成立,这个到底什么情况?
  • 把HAL_LCD設置為FALSE和從預編譯移除LCD_SUPPORTED再試試
  • 很抱歉,还是不行,貌似 ,上电之后 所有的事件都成立了,所以会这样
  • 很感谢您的帮助,我自己重新把按键I/0 的 相关的配置的初始化放到 用户初始化里面了,反正那个事件一直成立,就相当于定时的扫描,目前自己写的按键能用,就是反应不太灵敏(有扫描的时间),能用。就是不知道组网 跟 按键中断 为什么会有影响,是因为事件冲突(优先级的问题)?这个就不知道了。
1 2