微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 无线和射频 > TI Zigbee设计交流 > 协调器发送configure reporting command的问题

协调器发送configure reporting command的问题

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

大神们好,我想实现这样一个场景:手机app可以控制开关面板的打开和关闭,而手动打开和关闭控制面板,app又可收到反馈,及时更新app上的显示。这时就用到了zcl的configure reporting command的指令。

我的平台是这样的:终端节点用的是标准的ZHA协议的设备。协调器用的是TI的cc2530,协调器上的程序是TI的znp,主控程序为TI的am335xsII,上面跑的是Linux开源的znp host framework(做了一点修改)。

问题是这样的:我发送了configure reporting command,收到的回应是 0x08 0x1F 0x07 0x00 与zcl 规定的 Configure Reporting Response Command Frame Format不符(少了direction和Attribute identifier字段),急求大神们解决。谢谢。

主控程序的实现是这样的:
1.绑定onoff cluster,代码如下:

int zcl_register_cluster_ss(){
        unsigned char in_cluster_count = 12;
        unsigned short in_cluster[MAX_CLUSTER_COUNT];
        memset(in_cluster, 0, MAX_CLUSTER_COUNT * sizeof(unsigned short));
        in_cluster[0] = ZCL_CLUSTER_ID_GEN_BASIC;
        in_cluster[1] = ZCL_CLUSTER_ID_GEN_POWER_CFG;
        in_cluster[2] = ZCL_CLUSTER_ID_GEN_IDENTIFY;
        in_cluster[3] = ZCL_CLUSTER_ID_GEN_ON_OFF;
        in_cluster[4] = ZCL_CLUSTER_ID_GEN_COMMISSIONING;
        in_cluster[5] = ZCL_CLUSTER_ID_GEN_POLL_CONTROL;
        in_cluster[6] = ZCL_CLUSTER_ID_HA_DIAGNOSTIC;
        in_cluster[7] = ZCL_CLUSTER_ID_SS_IAS_ZONE;        
        in_cluster[8] = ZCL_CLUSTER_ID_SS_IAS_ACE;
        in_cluster[9] = ZCL_CLUSTER_ID_SS_IAS_WD;
        in_cluster[10] = ZCL_CLUSTER_ID_GEN_ON_OFF_SWITCH_CONFIG;
        in_cluster[11] = ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT;

        unsigned char out_cluster_count = 13;
        unsigned short out_cluster[MAX_CLUSTER_COUNT];
        memset(out_cluster, 0, MAX_CLUSTER_COUNT * sizeof(unsigned short));
        out_cluster[0] = ZCL_CLUSTER_ID_GEN_BASIC;
        out_cluster[1] = ZCL_CLUSTER_ID_GEN_POWER_CFG;
        out_cluster[2] = ZCL_CLUSTER_ID_GEN_IDENTIFY;
        out_cluster[3] = ZCL_CLUSTER_ID_GEN_ON_OFF;
        out_cluster[4] = ZCL_CLUSTER_ID_GEN_COMMISSIONING;
        out_cluster[5] = ZCL_CLUSTER_ID_GEN_POLL_CONTROL;
        out_cluster[6] = ZCL_CLUSTER_ID_HA_DIAGNOSTIC;
        out_cluster[7] = ZCL_CLUSTER_ID_SS_IAS_ZONE;        
        out_cluster[8] = ZCL_CLUSTER_ID_SS_IAS_ACE;
        out_cluster[9] = ZCL_CLUSTER_ID_SS_IAS_WD;
        out_cluster[10] = ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT;
        out_cluster[11] = ZCL_CLUSTER_ID_GEN_ON_OFF_SWITCH_CONFIG;
        out_cluster[12] = ZCL_CLUSTER_ID_GEN_SCENES;


        zcl_register_cluster(in_cluster_count, in_cluster, out_cluster_count, out_cluster, APP_DEVICETYPEID_SS_ENDPOINT, APP_DEVICETYPEID_SS);

        return APP_DEVICETYPEID_SS_ENDPOINT;
}
2. zcl_register_cluster的实现如下:
int zcl_register_cluster(unsigned char in_cluster_count, unsigned short * in_cluster,unsigned char out_cluster_count, unsigned short * out_cluster, unsigned char endpoint, unsigned short appdevicetypeid){ 
	if(in_cluster_count > MAX_CLUSTER_COUNT || out_cluster_count > MAX_CLUSTER_COUNT){
		return 1;
	} 
	RegisterFormat_t req;
	memset(&req, 0, sizeof(RegisterFormat_t)); 
	req.EndPoint= endpoint;
	req.AppProfId = 0x0104;
	req.AppDeviceId = appdevicetypeid;
	req.AppNumInClusters = in_cluster_count;
	memcpy(req.AppInClusterList, in_cluster, sizeof(unsigned short)*in_cluster_count);
	req.AppNumOutClusters = out_cluster_count;
	memcpy(req.AppOutClusterList, out_cluster, sizeof(unsigned short)*out_cluster_count);
	sendcmd((unsigned char *)&req, AF_REGISTER);

	return 0;
}
 

3.调用zcl_SendConfigReportCmd函数,配置onoff report命令:

CfgReportCmd.numAttr = 1;
CfgReportCmd.attrList[0].direction = 0;
CfgReportCmd.attrList[0].attrID = 0x0000;
CfgReportCmd.attrList[0].dataType = 0x10;
CfgReportCmd.attrList[0].minReportInt = 0;
CfgReportCmd.attrList[0].maxReportInt = 30;
CfgReportCmd.attrList[0].timeoutPeriod = 0;
CfgReportCmd.attrList[0].reportableChange = NULL;

struct device *d = gateway_getdevice(getgateway(), test.ieee);
if(d) {
        printf("gateway_get_endpoint\n");
        zcl_SendConfigReportCmd(1, 1, d->shortaddr, 0x0006, &CfgReportCmd, 0, 1, get_sequence());
}

4.zcl_SendConfigReportCmd的实现如下:

ZStatus_t zcl_SendConfigReportCmd( uint8 srcEP, uint8 dstEp, uint16 dstAddr,
                          uint16 clusterID, zclCfgReportCmd_t *cfgReportCmd,
                          uint8 direction, uint8 disableDefaultRsp, uint8 seqNum )
{
  uint8 *buf;
  uint16 dataLen = 0;
  ZStatus_t status;
  uint8 i;

  // Find out the data length
  printf("numAttr is %d\n", cfgReportCmd->numAttr);
  for ( i = 0; i < cfgReportCmd->numAttr; i++ )
  {
    zclCfgReportRec_t *reportRec = &(cfgReportCmd->attrList[i]);

    dataLen += 1 + 2; // Direction + Attribute ID

    if ( reportRec->direction == ZCL_SEND_ATTR_REPORTS )
    {
    printf("ZCL_SEND_ATTR_REPORTS\n");
      dataLen += 1 + 2 + 2; // Data Type + Min + Max Reporting Intervals

      // Find out the size of the Reportable Change field (for Analog data types)
      if ( zclAnalogDataType( reportRec->dataType ) )
      {
        dataLen += zclGetDataTypeLength( reportRec->dataType );
      }
    }
    else
    {
      dataLen += 2; // Timeout Period
    }
  }

  buf = zcl_mem_alloc( dataLen );
  if ( buf != NULL )
  {
    // Load the buffer - serially
    printf("load buffer\n");
    uint8 *pBuf = buf;

    for ( i = 0; i < cfgReportCmd->numAttr; i++ )
    {
      zclCfgReportRec_t *reportRec = &(cfgReportCmd->attrList[i]);

      *pBuf++ = reportRec->direction;
      *pBuf++ = LO_UINT16( reportRec->attrID );
      *pBuf++ = HI_UINT16( reportRec->attrID );

      if ( reportRec->direction == ZCL_SEND_ATTR_REPORTS )
      {
        *pBuf++ = reportRec->dataType;
        *pBuf++ = LO_UINT16( reportRec->minReportInt );
        *pBuf++ = HI_UINT16( reportRec->minReportInt );
        *pBuf++ = LO_UINT16( reportRec->maxReportInt );
        *pBuf++ = HI_UINT16( reportRec->maxReportInt );

        if ( zclAnalogDataType( reportRec->dataType ) )
        {
          pBuf = zclSerializeData( reportRec->dataType, reportRec->reportableChange, pBuf );
        }
      }
      else
      {
        *pBuf++ = LO_UINT16( reportRec->timeoutPeriod );
        *pBuf++ = HI_UINT16( reportRec->timeoutPeriod );
      }
    } // for loop

    status = zcl_sendcommand( srcEP, dstEp, dstAddr, clusterID, ZCL_CMD_CONFIG_REPORT, FALSE,
                              direction, disableDefaultRsp, 0, seqNum, dataLen, buf );
    zcl_mem_free( buf );
  }
  else
  {
    status = ZMemError;
  }

  return ( status );
}


5.zcl_send_command函数如下:

ZStatus_t  zcl_sendcommand( uint8 srcEP, uint8 dstEp, uint16 dstaddr,
                uint16 clusterID, uint8 cmd, uint8 specific, uint8 direction,
                uint8 disableDefaultRsp, uint16 manuCode, uint8 seqNum,
                uint16 cmdFormatLen, uint8 *cmdFormat )
{
        //endPointDesc_t *epDesc;
        struct zclframehdr hdr;
        unsigned char * msgBuf;
        uint16 msgLen;
        uint8 *pBuf;
        //uint8 options;
        ZStatus_t status;

        //  epDesc = afFindEndPointDesc( srcEP );
        //  if ( epDesc == NULL )
        //  {
        //    return ( ZInvalidParameter ); // EMBEDDED RETURN
        //  }
        //
        //#if defined ( INTER_PAN )
        //  if ( StubAPS_InterPan( destAddr->panId, destAddr->endPoint ) )
        //  {
        //    options = AF_TX_OPTIONS_NONE;
        //  }
        //  else
        //#endif
        //  {
        //    options = zclGetClusterOption( srcEP, clusterID );
        //
        //    // The cluster might not have been defined to use security but if this message
        //    // is in response to another message that was using APS security this message
        //    // will be sent with APS security
        //    if ( !( options & AF_EN_SECURITY ) )
        //    {
        //      afIncomingMSGPacket_t *origPkt = zcl_getRawAFMsg();
        //
        //      if ( ( origPkt != NULL ) && ( origPkt->SecurityUse == TRUE ) )
        //      {
        //        options |= AF_EN_SECURITY;
        //      }
        //    }
        //  }

        memset( &hdr, 0, sizeof( struct zclframehdr ) );

        // Not Profile wide command (like READ, WRITE)
        if ( specific )
        {
                hdr.control.type = ZCL_FRAME_TYPE_SPECIFIC_CMD;
        }
        else
        {
                 hdr.control.type = ZCL_FRAME_TYPE_PROFILE_CMD;
        }

        //  if ( ( epDesc->simpleDesc == NULL ) ||
        //       ( zcl_DeviceOperational( srcEP, clusterID, hdr.fc.type,
        //                                cmd, epDesc->simpleDesc->AppProfId ) == FALSE ) )
        //  {
        //    return ( ZFailure ); // EMBEDDED RETURN
        //  }

        // Fill in the Maufacturer Code
        if ( manuCode != 0 )
        {
                hdr.control.manuspecific = 1;
                hdr.manucode = manuCode;
        }

        // Set the Command Direction
        if ( direction )
        {
                hdr.control.direction = ZCL_FRAME_SERVER_CLIENT_DIR;
        }
        else
        {
                hdr.control.direction = ZCL_FRAME_CLIENT_SERVER_DIR;
        }

        // Set the Disable Default Response field
        if ( disableDefaultRsp )
        {
                hdr.control.disabledefaultrsp = 1;
        }
        else
        {
                hdr.control.disabledefaultrsp = 0;
        }

        // Fill in the Transaction Sequence Number
        hdr.transseqnum = seqNum;

        // Fill in the command
        hdr.commandid = cmd;

        // calculate the needed buffer size
        msgLen = zclCalcHdrSize( &hdr );
        msgLen += cmdFormatLen;

        // Allocate the buffer needed
        msgBuf = (unsigned char *)malloc( msgLen );
        memset(msgBuf, 0, msgLen);
        if ( msgBuf != NULL )
        {
                // Fill in the ZCL Header
                pBuf = zclBuildHdr( &hdr, msgBuf );

                // Fill in the command frame
                memcpy( pBuf, cmdFormat, cmdFormatLen );

                DataRequestFormat_t req;
                memset(&req, 0, sizeof(DataRequestFormat_t));
                req.DstAddr = dstaddr;
                req.DstEndpoint = dstEp;
                req.SrcEndpoint = srcEP;
                req.ClusterID = clusterID;
                //        uint8_t TransID;
                //        uint8_t Options;
                //        uint8_t Radius;     
                req.Len = msgLen;
                memcpy(req.Data, msgBuf, msgLen);
                free(msgBuf);
                sendcmd((unsigned char *)&req, AF_DATA_REQUEST);

        }
        else
        {
                status = ZMemError;
        }

        return ( status );
}

开关面板有没有断点调试过,在接收configuration command的时候?

没有,开关控制面板是购买的成熟的过检的产品,不能拆开调试

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

网站地图

Top