对通用命令的处理:
对zcl的通用命令的响应,zcl自己已经实现,比如读取某个clusterid的某个属性值,应用只需将这个属性设置好即可,
通用命令包括,zcl.h
而zcl.c中默认的处理函数数组是
1.比如在发送端(客户端),发出一个个命令是ZCL_CMD_READ,hdr.fc.type=ZCL_FRAME_TYPE_PROFILE_CMD的请求,目的端点是SAMPLELIGHT_ENDPOINT(13)
2.服务端将端点SAMPLELIGHT_ENDPOINT使用zclHA_Init( &zclSampleLight_SimpleDesc )注册在zcl任务,af层从空中接到消息后会转发给SAMPLELIGHT_ENDPOINT所在的任务zcl,然后
zcl_event_loop->zclProcessMessageMSG,
发现hdr.fc.type=ZCL_FRAME_TYPE_PROFILE_CMD,就直接调用zclCmdTable[ZCL_CMD_READ]的那个函数,就是zclProcessInReadCmd,
此函数就在zcl的全局属性链表头部attrList开始寻找对应端点的节点元素的属性指针,返回。。。
if ( zclFindAttrRec( pInMsg->msg->endPoint, pInMsg->msg->clusterId, readCmd->attrID[i], &attrRec ) )
{
statusRec->data = attrRec.attr.dataPtr;
statusRec->status = ZCL_STATUS_SUCCESS;
statusRec->dataType = attrRec.attr.dataType;
}
3. 所以,服务器端需要先将支持的clusterid的各个属性注册一下,比如zcl_samplelight.c
zcl_registerAttrList( SAMPLELIGHT_ENDPOINT, SAMPLELIGHT_MAX_ATTRIBUTES, zclSampleLight_Attrs );
这个端点注册了n个属性值,放在全局属性链表头部attrList所指向的链表的最后(attrList总是指向链表的头部,zclAttrRecsList attrList)
4.如果
zclCmdTable[ZCL_CMD_READ]
对应的处理函数是zclSendMsg,则会将这个消息以ZCL_INCOMING_MSG事件发给上层任务去处理,前提是上层任务使用
zcl_registerForMsg
注册过。
对zcl不同领域的不同clusterid的不同command的处理:
例如服务器端接收到如下的clusterid(通用领域的).和命令号是COMMAND_TOGGLE怎么处理的呢?
首先要了解general领域的clusterid onoff 的属性和命令各有哪些
1.比如在发送端(客户端),发出一个个clusterid是ZCL_CLUSTER_ID_GEN_ON_OFF ,命令是COMMAND_TOGGLE,hdr.fc.type=
ZCL_FRAME_TYPE_SPECIFIC_CMD
的请求,目的端点是
SAMPLELIGHT_ENDPOINT(13)
2.服务器端将端点号 SAMPLELIGHT_ENDPOINT使用zclHA_Init( &zclSampleLight_SimpleDesc ) 注册在zcl任务, af层从空中接到消息后会转发给 SAMPLELIGHT_ENDPOINT所在的任务 zcl, 然后
zcl_event_loop->zclProcessMessageMSG,
发现 hdr.fc.type=ZCL_FRAME_TYPE_SPECIFIC_CMD,就调用zclGeneral_HdlIncoming->zclGeneral_HdlInSpecificCommands,如下
此函数会在zcl_general的全局处理函数数组链表头部zclGenCBs开始寻找对应端点的节点元素的数组指针
static zclGeneral_AppCallbacks_t *zclGeneral_FindCallbacks( uint8 endpoint )
{
zclGenCBRec_t *pCBs;
pCBs = zclGenCBs;
while ( pCBs )
{
if ( pCBs->endpoint == endpoint )
return ( pCBs->CBs );
pCBs = pCBs->next;
}
return ( (zclGeneral_AppCallbacks_t *)NULL );
}
case下的各个函数,看似有点多余,直接调用回调函数数组中的对应函数不就行了-----那些函数里面有判断条件。
3.所以,服务器端需要先将支持的clusterid的处理函数注册一下,比如zcl_samplelight.c
zclGeneral_RegisterCmdCallbacks( SAMPLELIGHT_ENDPOINT, &zclSampleLight_CmdCallbacks );
这个端点注册了回调函数数组zclSampleLight_CmdCallbacks,放在全局回调函数数组链表头部zclGenCBs所指向的链表的最后(zclGenCBs总是指向链表的头部,zclGenCBRec_t zclGenCBs)
4.在具体的clusterid处理函数中在根据command进行不同处理,比如zclSampleLight_OnOffCB
综上,
inMsg.hdr.fc.type=ZCL_FRAME_TYPE_PROFILE_CMD的时候(表示是zcl通用命令):会根据inMsg.hdr.commandID直接调用zcl.c中预定义的函数数组指针zclCmdTable处理之,根据不同的commandid,调用不同的处理函数。如果处理函数是zclSendMsg则会将这个消息以ZCL_INCOMING_MSG事件发给上层任务去处理
从发送函数可以看出
ZStatus_t zcl_SendCommand( uint8 srcEP, afAddrType_t *destAddr,
uint16 clusterID, uint8 cmd, uint8specific, uint8 direction,
uint8 disableDefaultRsp, uint16 manuCode, uint8 seqNum,
uint16 cmdFormatLen, uint8 *cmdFormat )
inMsg.hdr.fc.type=ZCL_FRAME_TYPE_SPECIFIC_CMD的时候(zcl的功能领域专用命令): 会使用 用zclGeneral_RegisterCmdCallbacks( SAMPLELIGHT_ENDPOINT, &zclSampleLight_CmdCallbacks )注册了的函数数组指针 zclSampleLight_CmdCallbacks 处理之,根据不同的 inMsg.msg->clusterId会调用不同的处理函数,然后在处理函数中会根据commandid进一步操作
对zcl的通用命令的响应,zcl自己已经实现,比如读取某个clusterid的某个属性值,应用只需将这个属性设置好即可,
通用命令包括,zcl.h
- /*** Foundation Command IDs ***/
- #define ZCL_CMD_READ 0x00
- #define ZCL_CMD_READ_RSP 0x01
- #define ZCL_CMD_WRITE 0x02
- #define ZCL_CMD_WRITE_UNDIVIDED 0x03
- #define ZCL_CMD_WRITE_RSP 0x04
- #define ZCL_CMD_WRITE_NO_RSP 0x05
- #define ZCL_CMD_CONFIG_REPORT 0x06
- #define ZCL_CMD_CONFIG_REPORT_RSP 0x07
- #define ZCL_CMD_READ_REPORT_CFG 0x08
- #define ZCL_CMD_READ_REPORT_CFG_RSP 0x09
- #define ZCL_CMD_REPORT 0x0a
- #define ZCL_CMD_DEFAULT_RSP 0x0b
- #define ZCL_CMD_DISCOVER 0x0c
- #define ZCL_CMD_DISCOVER_RSP 0x0d
- static CONST zclCmdItems_t zclCmdTable[] =
- {
- #ifdef ZCL_READ
- /* ZCL_CMD_READ */ { zclParseInReadCmd, zclProcessInReadCmd },
- /* ZCL_CMD_READ_RSP */ { zclParseInReadRspCmd, zclSendMsg },
- #else
- /* ZCL_CMD_READ */ { NULL, NULL },
- /* ZCL_CMD_READ_RSP */ { NULL, NULL },
- #endif // ZCL_READ
- #ifdef ZCL_WRITE
- /* ZCL_CMD_WRITE */ { zclParseInWriteCmd, zclProcessInWriteCmd },
- /* ZCL_CMD_WRITE_UNDIVIDED */ { zclParseInWriteCmd, zclProcessInWriteUndividedCmd },
- /* ZCL_CMD_WRITE_RSP */ { zclParseInWriteRspCmd, zclSendMsg },
- /* ZCL_CMD_WRITE_NO_RSP */ { zclParseInWriteCmd, zclProcessInWriteCmd },
- #else
- /* ZCL_CMD_WRITE */ { NULL, NULL },
- /* ZCL_CMD_WRITE_UNDIVIDED */ { NULL, NULL },
- /* ZCL_CMD_WRITE_RSP */ { NULL, NULL },
- /* ZCL_CMD_WRITE_NO_RSP */ { NULL, NULL },
- #endif // ZCL_WRITE
- #ifdef ZCL_REPORT
- /* ZCL_CMD_CONFIG_REPORT */ { zclParseInConfigReportCmd, zclSendMsg },
- /* ZCL_CMD_CONFIG_REPORT_RSP */ { zclParseInConfigReportRspCmd, zclSendMsg },
- /* ZCL_CMD_READ_REPORT_CFG */ { zclParseInReadReportCfgCmd, zclSendMsg },
- /* ZCL_CMD_READ_REPORT_CFG_RSP */ { zclParseInReadReportCfgRspCmd, zclSendMsg },
- /* ZCL_CMD_REPORT */ { zclParseInReportCmd, zclSendMsg },
- #else
- /* ZCL_CMD_CONFIG_REPORT */ { NULL, NULL },
- /* ZCL_CMD_CONFIG_REPORT_RSP */ { NULL, NULL },
- /* ZCL_CMD_READ_REPORT_CFG */ { NULL, NULL },
- /* ZCL_CMD_READ_REPORT_CFG_RSP */ { NULL, NULL },
- /* ZCL_CMD_REPORT */ { NULL, NULL },
- #endif // ZCL_REPORT
- /* ZCL_CMD_DEFAULT_RSP */ { zclParseInDefaultRspCmd, zclSendMsg },
- #ifdef ZCL_DISCOVER
- /* ZCL_CMD_DISCOVER */ { zclParseInDiscCmd, zclProcessInDiscCmd },
- /* ZCL_CMD_DISCOVER_RSP */ { zclParseInDiscRspCmd, zclSendMsg }
- #else
- /* ZCL_CMD_DISCOVER */ { NULL, NULL },
- /* ZCL_CMD_DISCOVER_RSP */ { NULL, NULL }
- #endif // ZCL_DISCOVER
- };
1.比如在发送端(客户端),发出一个个命令是ZCL_CMD_READ,hdr.fc.type=ZCL_FRAME_TYPE_PROFILE_CMD的请求,目的端点是SAMPLELIGHT_ENDPOINT(13)
2.服务端将端点SAMPLELIGHT_ENDPOINT使用zclHA_Init( &zclSampleLight_SimpleDesc )注册在zcl任务,af层从空中接到消息后会转发给SAMPLELIGHT_ENDPOINT所在的任务zcl,然后
zcl_event_loop->zclProcessMessageMSG,
发现hdr.fc.type=ZCL_FRAME_TYPE_PROFILE_CMD,就直接调用zclCmdTable[ZCL_CMD_READ]的那个函数,就是zclProcessInReadCmd,
此函数就在zcl的全局属性链表头部attrList开始寻找对应端点的节点元素的属性指针,返回。。。
if ( zclFindAttrRec( pInMsg->msg->endPoint, pInMsg->msg->clusterId, readCmd->attrID[i], &attrRec ) )
{
statusRec->data = attrRec.attr.dataPtr;
statusRec->status = ZCL_STATUS_SUCCESS;
statusRec->dataType = attrRec.attr.dataType;
}
3. 所以,服务器端需要先将支持的clusterid的各个属性注册一下,比如zcl_samplelight.c
zcl_registerAttrList( SAMPLELIGHT_ENDPOINT, SAMPLELIGHT_MAX_ATTRIBUTES, zclSampleLight_Attrs );
这个端点注册了n个属性值,放在全局属性链表头部attrList所指向的链表的最后(attrList总是指向链表的头部,zclAttrRecsList attrList)
- typedef struct zclAttrRecsList
- {
- struct zclAttrRecsList *next;
- uint8 endpoint; // Used to link it into the endpoint descriptor
- uint8 numAttributes; // Number of the following records
- CONST zclAttrRec_t *attrs; // attribute records
- } zclAttrRecsList;
- // Attribute record
- typedef struct
- {
- uint16 attrId; // Attribute ID
- uint8 dataType; // Data Type - defined in AF.h
- uint8 accessControl; // Read/write - bit field
- void *dataPtr; // Pointer to data field
- } zclAttribute_t;
- typedef struct
- {
- uint16 clusterID; // Real cluster ID
- zclAttribute_t attr;
- } zclAttrRec_t;
- CONST zclAttrRec_t zclSampleLight_Attrs[SAMPLELIGHT_MAX_ATTRIBUTES] =
- {
- // *** General Basic Cluster Attributes ***
- {
- ZCL_CLUSTER_ID_GEN_BASIC, // Cluster IDs - defined in the foundation (ie. zcl.h)
- { // Attribute record
- ATTRID_BASIC_HW_VERSION, // Attribute ID - Found in Cluster Library header (ie. zcl_general.h)
- ZCL_DATATYPE_UINT8, // Data Type - found in zcl.h
- ACCESS_CONTROL_READ, // Variable access control - found in zcl.h
- (void *)&zclSampleLight_HWRevision // Pointer to attribute variable
- }
- },
- {
- ZCL_CLUSTER_ID_GEN_BASIC,
- { // Attribute record
- ATTRID_BASIC_ZCL_VERSION,
- ZCL_DATATYPE_UINT8,
- ACCESS_CONTROL_READ,
- (void *)&zclSampleLight_ZCLVersion
- }
- },
- {
- ZCL_CLUSTER_ID_GEN_BASIC,
- { // Attribute record
- ATTRID_BASIC_MANUFACTURER_NAME,
- ZCL_DATATYPE_CHAR_STR,
- ACCESS_CONTROL_READ,
- (void *)zclSampleLight_ManufacturerName
- }
- },
- {
- ZCL_CLUSTER_ID_GEN_BASIC,
- { // Attribute record
- ATTRID_BASIC_MODEL_ID,
- ZCL_DATATYPE_CHAR_STR,
- ACCESS_CONTROL_READ,
- (void *)zclSampleLight_ModelId
- }
- },
- {
- ZCL_CLUSTER_ID_GEN_BASIC,
- { // Attribute record
- ATTRID_BASIC_DATE_CODE,
- ZCL_DATATYPE_CHAR_STR,
- ACCESS_CONTROL_READ,
- (void *)zclSampleLight_DateCode
- }
- },
- {
- ZCL_CLUSTER_ID_GEN_BASIC,
- { // Attribute record
- ATTRID_BASIC_POWER_SOURCE,
- ZCL_DATATYPE_UINT8,
- ACCESS_CONTROL_READ,
- (void *)&zclSampleLight_PowerSource
- }
- },
- {
- ZCL_CLUSTER_ID_GEN_BASIC,
- { // Attribute record
- ATTRID_BASIC_LOCATION_DESC,
- ZCL_DATATYPE_CHAR_STR,
- (ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),
- (void *)zclSampleLight_LocationDescription
- }
- },
- {
- ZCL_CLUSTER_ID_GEN_BASIC,
- { // Attribute record
- ATTRID_BASIC_PHYSICAL_ENV,
- ZCL_DATATYPE_UINT8,
- (ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),
- (void *)&zclSampleLight_PhysicalEnvironment
- }
- },
- {
- ZCL_CLUSTER_ID_GEN_BASIC,
- { // Attribute record
- ATTRID_BASIC_DEVICE_ENABLED,
- ZCL_DATATYPE_BOOLEAN,
- (ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),
- (void *)&zclSampleLight_DeviceEnable
- }
- },
- // *** Identify Cluster Attribute ***
- {
- ZCL_CLUSTER_ID_GEN_IDENTIFY,
- { // Attribute record
- ATTRID_IDENTIFY_TIME,
- ZCL_DATATYPE_UINT16,
- (ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),
- (void *)&zclSampleLight_IdentifyTime
- }
- },
- // *** On/Off Cluster Attributes ***
- {
- ZCL_CLUSTER_ID_GEN_ON_OFF,
- { // Attribute record
- ATTRID_ON_OFF,
- ZCL_DATATYPE_UINT8,
- ACCESS_CONTROL_READ,
- (void *)&zclSampleLight_OnOff
- }
- },
- };
对zcl不同领域的不同clusterid的不同command的处理:
例如服务器端接收到如下的clusterid(通用领域的).和命令号是COMMAND_TOGGLE怎么处理的呢?
- // General Clusters
- #define ZCL_CLUSTER_ID_GEN_BASIC 0x0000
- #define ZCL_CLUSTER_ID_GEN_POWER_CFG 0x0001
- #define ZCL_CLUSTER_ID_GEN_DEVICE_TEMP_CONFIG 0x0002
- #define ZCL_CLUSTER_ID_GEN_IDENTIFY 0x0003
- #define ZCL_CLUSTER_ID_GEN_GROUPS 0x0004
- #define ZCL_CLUSTER_ID_GEN_SCENES 0x0005
- #define ZCL_CLUSTER_ID_GEN_ON_OFF 0x0006//this
- #define ZCL_CLUSTER_ID_GEN_ON_OFF_SWITCH_CONFIG 0x0007
- #define ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL 0x0008
- #define ZCL_CLUSTER_ID_GEN_ALARMS 0x0009
- #define ZCL_CLUSTER_ID_GEN_TIME 0x000A
- #define ZCL_CLUSTER_ID_GEN_LOCATION 0x000B
- #define ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT 0x0800
首先要了解general领域的clusterid onoff 的属性和命令各有哪些
- /*********************************/
- /*** On/Off Cluster Attributes ***/
- /*********************************/
- #define ATTRID_ON_OFF 0x0000
- /*******************************/
- /*** On/Off Cluster Commands ***/
- /*******************************/
- #define COMMAND_OFF 0x00
- #define COMMAND_ON 0x01
- #define COMMAND_TOGGLE 0x02
2.服务器端将端点号 SAMPLELIGHT_ENDPOINT使用zclHA_Init( &zclSampleLight_SimpleDesc ) 注册在zcl任务, af层从空中接到消息后会转发给 SAMPLELIGHT_ENDPOINT所在的任务 zcl, 然后
zcl_event_loop->zclProcessMessageMSG,
发现 hdr.fc.type=ZCL_FRAME_TYPE_SPECIFIC_CMD,就调用zclGeneral_HdlIncoming->zclGeneral_HdlInSpecificCommands,如下
- static ZStatus_t zclGeneral_HdlInSpecificCommands( zclIncoming_t *pInMsg )
- {
- ZStatus_t stat;
- zclGeneral_AppCallbacks_t *pCBs;
- // make sure endpoint exists
- pCBs = zclGeneral_FindCallbacks( pInMsg->msg->endPoint );
- if ( pCBs == NULL )
- return ( ZFailure );
- switch ( pInMsg->msg->clusterId )
- {
- #ifdef ZCL_BASIC
- case ZCL_CLUSTER_ID_GEN_BASIC:
- stat = zclGeneral_ProcessInBasic( pInMsg, pCBs );
- break;
- #endif // ZCL_BASIC
- #ifdef ZCL_IDENTIFY
- case ZCL_CLUSTER_ID_GEN_IDENTIFY:
- stat = zclGeneral_ProcessInIdentity( pInMsg, pCBs );
- break;
- #endif // ZCL_IDENTIFY
- #ifdef ZCL_GROUPS
- case ZCL_CLUSTER_ID_GEN_GROUPS:
- if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
- stat = zclGeneral_ProcessInGroupsServer( pInMsg );
- else
- stat = zclGeneral_ProcessInGroupsClient( pInMsg, pCBs );
- break;
- #endif // ZCL_GROUPS
- #ifdef ZCL_SCENES
- case ZCL_CLUSTER_ID_GEN_SCENES:
- if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
- stat = zclGeneral_ProcessInScenesServer( pInMsg, pCBs );
- else
- stat = zclGeneral_ProcessInScenesClient( pInMsg, pCBs );
- break;
- #endif // ZCL_SCENES
- #ifdef ZCL_ON_OFF
- case ZCL_CLUSTER_ID_GEN_ON_OFF:
- stat = zclGeneral_ProcessInOnOff( pInMsg, pCBs );
- break;
- #endif // ZCL_ON_OFF
- #ifdef ZCL_LEVEL_CTRL
- case ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL:
- stat = zclGeneral_ProcessInLevelControl( pInMsg, pCBs );
- break;
- #endif // ZCL_LEVEL_CTRL
- #ifdef ZCL_ALARMS
- case ZCL_CLUSTER_ID_GEN_ALARMS:
- if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
- stat = zclGeneral_ProcessInAlarmsServer( pInMsg, pCBs );
- else
- stat = zclGeneral_ProcessInAlarmsClient( pInMsg, pCBs );
- break;
- #endif // ZCL_ALARMS
- #ifdef ZCL_LOCATION
- case ZCL_CLUSTER_ID_GEN_LOCATION:
- if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
- stat = zclGeneral_ProcessInLocationServer( pInMsg, pCBs );
- else
- stat = zclGeneral_ProcessInLocationClient( pInMsg, pCBs );
- break;
- #endif // ZCL_LOCATION
- case ZCL_CLUSTER_ID_GEN_POWER_CFG:
- case ZCL_CLUSTER_ID_GEN_DEVICE_TEMP_CONFIG:
- case ZCL_CLUSTER_ID_GEN_ON_OFF_SWITCH_CONFIG:
- case ZCL_CLUSTER_ID_GEN_TIME:
- default:
- stat = ZFailure;
- break;
- }
- return ( stat );
- }
static zclGeneral_AppCallbacks_t *zclGeneral_FindCallbacks( uint8 endpoint )
{
zclGenCBRec_t *pCBs;
pCBs = zclGenCBs;
while ( pCBs )
{
if ( pCBs->endpoint == endpoint )
return ( pCBs->CBs );
pCBs = pCBs->next;
}
return ( (zclGeneral_AppCallbacks_t *)NULL );
}
case下的各个函数,看似有点多余,直接调用回调函数数组中的对应函数不就行了-----那些函数里面有判断条件。
3.所以,服务器端需要先将支持的clusterid的处理函数注册一下,比如zcl_samplelight.c
zclGeneral_RegisterCmdCallbacks( SAMPLELIGHT_ENDPOINT, &zclSampleLight_CmdCallbacks );
这个端点注册了回调函数数组zclSampleLight_CmdCallbacks,放在全局回调函数数组链表头部zclGenCBs所指向的链表的最后(zclGenCBs总是指向链表的头部,zclGenCBRec_t zclGenCBs)
- typedef struct zclGenCBRec
- {
- struct zclGenCBRec *next;
- uint8 endpoint; // Used to link it into the endpoint descriptor
- zclGeneral_AppCallbacks_t *CBs; // Pointer to Callback function
- } zclGenCBRec_t;
- typedef struct
- {
- zclGCB_BasicReset_t pfnBasicReset; // Basic Cluster Reset command
- zclGCB_Identify_t pfnIdentify; // Identify command
- zclGCB_IdentifyQueryRsp_t pfnIdentifyQueryRsp; // Identify Query Response command
- zclGCB_OnOff_t pfnOnOff; // On/Off cluster commands
- zclGCB_LevelControlMoveToLevel_t pfnLevelControlMoveToLevel; // Level Control Move to Level command
- zclGCB_LevelControlMove_t pfnLevelControlMove; // Level Control Move command
- zclGCB_LevelControlStep_t pfnLevelControlStep; // Level Control Step command
- zclGCB_LevelControlStop_t pfnLevelControlStop; // Level Control Stop command
- zclGCB_GroupRsp_t pfnGroupRsp; // Group Response commands
- zclGCB_SceneStoreReq_t pfnSceneStoreReq; // Scene Store Request command
- zclGCB_SceneRecallReq_t pfnSceneRecallReq; // Scene Recall Request command
- zclGCB_SceneRsp_t pfnSceneRsp; // Scene Response command
- zclGCB_Alarm_t pfnAlarm; // Alarm (Response) commands
- zclGCB_Location_t pfnLocation; // RSSI Location command
- zclGCB_LocationRsp_t pfnLocationRsp; // RSSI Location Response command
- } zclGeneral_AppCallbacks_t;
- //
- static zclGeneral_AppCallbacks_t zclSampleLight_CmdCallbacks =
- {
- zclSampleLight_BasicResetCB, // Basic Cluster Reset command
- zclSampleLight_IdentifyCB, // Identify command
- zclSampleLight_IdentifyQueryRspCB, // Identify Query Response command
- zclSampleLight_OnOffCB, // On/Off cluster command
- NULL, // Level Control Move to Level command
- NULL, // Level Control Move command
- NULL, // Level Control Step command
- NULL, // Group Response commands
- NULL, // Scene Store Request command
- NULL, // Scene Recall Request command
- NULL, // Scene Response command
- NULL, // Alarm (Response) command
- NULL, // RSSI Location commands
- NULL, // RSSI Location Response commands
- };
4.在具体的clusterid处理函数中在根据command进行不同处理,比如zclSampleLight_OnOffCB
- static void zclSampleLight_OnOffCB( uint8 cmd )
- {
- // Turn on the light
- if ( cmd == COMMAND_ON )
- zclSampleLight_OnOff = LIGHT_ON;
- // Turn off the light
- else if ( cmd == COMMAND_OFF )
- zclSampleLight_OnOff = LIGHT_OFF;
- // Toggle the light
- else
- {
- if ( zclSampleLight_OnOff == LIGHT_OFF )
- zclSampleLight_OnOff = LIGHT_ON;
- else
- zclSampleLight_OnOff = LIGHT_OFF;
- }
- // In this sample app, we use LED4 to simulate the Light
- if ( zclSampleLight_OnOff == LIGHT_ON )
- HalLedSet( HAL_LED_4, HAL_LED_MODE_ON );
- else
- HalLedSet( HAL_LED_4, HAL_LED_MODE_OFF );
- }
综上,
inMsg.hdr.fc.type=ZCL_FRAME_TYPE_PROFILE_CMD的时候(表示是zcl通用命令):会根据inMsg.hdr.commandID直接调用zcl.c中预定义的函数数组指针zclCmdTable处理之,根据不同的commandid,调用不同的处理函数。如果处理函数是zclSendMsg则会将这个消息以ZCL_INCOMING_MSG事件发给上层任务去处理
从发送函数可以看出
ZStatus_t zcl_SendCommand( uint8 srcEP, afAddrType_t *destAddr,
uint16 clusterID, uint8 cmd, uint8specific, uint8 direction,
uint8 disableDefaultRsp, uint16 manuCode, uint8 seqNum,
uint16 cmdFormatLen, uint8 *cmdFormat )
inMsg.hdr.fc.type=ZCL_FRAME_TYPE_SPECIFIC_CMD的时候(zcl的功能领域专用命令): 会使用 用zclGeneral_RegisterCmdCallbacks( SAMPLELIGHT_ENDPOINT, &zclSampleLight_CmdCallbacks )注册了的函数数组指针 zclSampleLight_CmdCallbacks 处理之,根据不同的 inMsg.msg->clusterId会调用不同的处理函数,然后在处理函数中会根据commandid进一步操作