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.

应用层收不到来自Client的ZCL_CMD_WRITE?

Genius 3030 points
  • 你要到 zclProcessInWriteCmd 去處理
  • 就是到不到这里:
    case ZCL_INCOMING_MSG:
    // Incoming ZCL Foundation command/response messages
    zclNewbitFan_ProcessIncomingMsg( (zclIncomingMsg_t *)MSGpkt );
    break;
  • ZCL_CMD_WRITE在zclProcessInWriteCmd 就被處理走了,不會傳給"case ZCL_INCOMING_MSG:"
  • 那要去更改zcl.c的代码啊,就没有什么回调函数去通知应用层吗?没有的话怎么去实现其他动作?例如开灯之类的。

  • 开灯之类的有專門的callback 可以調用,你可以使用 zclGeneral_RegisterCmdCallbacks去註冊callback
  • 记起来的,在zclGeneral_AppCallbacks_t写Callback,太久没碰
  • cmd命令会过滤到callback 不会进入ZCL_INCOMING_MSG
  • 这个CallBack只针对Command命令吧?有些Cluster并没有Cmd,例如Fan Control,要对它的FanMode属性进行读写要怎么操作呢?
  • static uint8 zclSampleThermostat_ProcessIncomingMsg( zclIncoming_t *pInMsg)
    {
    uint8 handled = FALSE;
    switch ( pInMsg->hdr.commandID )
    {
    #ifdef ZCL_READ
    case ZCL_CMD_READ_RSP:
    zclSampleThermostat_ProcessInReadRspCmd( pInMsg );
    handled = TRUE;
    break;
    #endif
    #ifdef ZCL_WRITE
    case ZCL_CMD_WRITE_RSP:
    zclSampleThermostat_ProcessInWriteRspCmd( pInMsg );
    handled = TRUE;
    break;
    #endif
    #ifdef ZCL_REPORT
    case ZCL_CMD_CONFIG_REPORT:
    //zclSampleThermostat_ProcessInConfigReportCmd( pInMsg );
    break;

    case ZCL_CMD_CONFIG_REPORT_RSP:
    //zclSampleThermostat_ProcessInConfigReportRspCmd( pInMsg );
    break;

    case ZCL_CMD_READ_REPORT_CFG:
    //zclSampleThermostat_ProcessInReadReportCfgCmd( pInMsg );
    break;

    case ZCL_CMD_READ_REPORT_CFG_RSP:
    //zclSampleThermostat_ProcessInReadReportCfgRspCmd( pInMsg );
    break;
    #endif
    #ifdef ZCL_REPORT_DESTINATION_DEVICE
    case ZCL_CMD_REPORT:
    zclSampleThermostat_ProcessInReportCmd( pInMsg );
    handled = TRUE;
    break;
    #endif
    case ZCL_CMD_DEFAULT_RSP:
    zclSampleThermostat_ProcessInDefaultRspCmd( pInMsg );
    handled = TRUE;
    break;

    default:
    break;
    }

    return handled;
    }
  • 我是用#define zcl_SendWrite(a,b,c,d,e,f,g) (zcl_SendWriteRequest( (a), (b), (c), (d), ZCL_CMD_WRITE, (e), (f), (g) ))
    这个函数发送写属性操作的,但是在接收方并没有进入zclSampleThermostat_ProcessIncomingMsg( zclIncoming_t *pInMsg)这个函数
  • 這個你就真的得要去zclProcessInWriteCmd 處理
  • 兜兜转转又回到这里,为甚么TI不直接发送到应用层呢?改动底层文件不是很好啊

  • 如YK所说你使用的是zcl_SendWrite ,需要在

    static uint8 zclProcessInWriteCmd( zclIncoming_t *pInMsg )里面处理。

    static CONST zclCmdItems_t zclCmdTable[] =
    {
    #ifdef ZCL_READ
      /* ZCL_CMD_READ */                { zclParseInReadCmd,             zclProcessInReadCmd             },
      /* ZCL_CMD_READ_RSP */            { zclParseInReadRspCmd,          zcl_HandleExternal              },
    #else
      /* ZCL_CMD_READ */                { (zclParseInProfileCmd_t)NULL,  (zclProcessInProfileCmd_t)NULL  },
      /* ZCL_CMD_READ_RSP */            { (zclParseInProfileCmd_t)NULL,  (zclProcessInProfileCmd_t)NULL  },
    #endif // ZCL_READ
    
    #ifdef ZCL_WRITE
      /* ZCL_CMD_WRITE */               { zclParseInWriteCmd,            zclProcessInWriteCmd            },
      /* ZCL_CMD_WRITE_UNDIVIDED */     { zclParseInWriteCmd,            zclProcessInWriteUndividedCmd   },
      /* ZCL_CMD_WRITE_RSP */           { zclParseInWriteRspCmd,         zcl_HandleExternal              },
      /* ZCL_CMD_WRITE_NO_RSP */        { zclParseInWriteCmd,            zclProcessInWriteCmd            },

  • 可以參考一下 e2e.ti.com/.../2621011 裡面的討論串
  • 正如你所说,我不希望改动底层,但目前好像也没有更好的方法去实现它 。
  • 就是用 zcl_registerReadWriteCB去做啊
  • Hi YK
    zcl_registerReadWriteCB 有一个issue,我在这边备注一下

    BDB reporting doesn't support read/write attribute data callback functions
    Issue description:
    The current BDB reporting implementation doesn't support attributes that use a callback function to read/write attribute data.

    Proposed fix:
    Replace bdb_RepFindAttrEntry() in bdb_reporting.c

    uint8 gAttrDataValue[BDBREPORTING_MAX_ANALOG_ATTR_SIZE];

    static uint8 bdb_RepFindAttrEntry( uint8 endpoint, uint16 cluster, uint16 attrID, zclAttribute_t* attrRes )
    {
    epList_t *epCur = epList;
    uint8 i;

    zcl_memset(gAttrDataValue, 0, BDBREPORTING_MAX_ANALOG_ATTR_SIZE);
    for ( epCur = epList; epCur != NULL; epCur = epCur->nextDesc )
    {
    if( epCur->epDesc->endPoint == endpoint )
    {
    zclAttrRecsList* attrItem = zclFindAttrRecsList( epCur->epDesc->endPoint );

    if( (attrItem != NULL) && ( (attrItem->numAttributes > 0) && (attrItem->attrs != NULL) ) )
    {
    for ( i = 0; i < attrItem->numAttributes; i++ )
    {
    if ( ( attrItem->attrs[i].clusterID == cluster ) && ( attrItem->attrs[i].attr.attrId == attrID ) )
    {
    uint16 dataLen;

    attrRes->attrId = attrItem->attrs[i].attr.attrId;
    attrRes->dataType = attrItem->attrs[i].attr.dataType;
    attrRes->accessControl = attrItem->attrs[i].attr.accessControl;

    dataLen = zclGetDataTypeLength(attrRes->dataType);
    zcl_ReadAttrData( endpoint, cluster, attrRes->attrId, gAttrDataValue, &dataLen );
    attrRes->dataPtr = gAttrDataValue;
    return BDBREPORTING_TRUE;
    }
    }
    }
    }
    }
    return BDBREPORTING_FALSE;
    }
  • #ifdef ZCL_DIAGNOSTIC
    // Register the application's callback function to read/write attribute data.
    // This is only required when the attribute data format is unknown to ZCL.
    zcl_registerReadWriteCB( GENERICAPP_ENDPOINT, zclDiagnostic_ReadWriteAttrCB, NULL );
    这是个例子。