zigbee zcl规范及其协议栈实现2

来源:互联网 发布:河南省大数据产业园 编辑:程序博客网 时间:2024/06/10 12:15
对通用命令的处理:
对zcl的通用命令的响应,zcl自己已经实现,比如读取某个clusterid的某个属性值,应用只需将这个属性设置好即可,
通用命令包括,zcl.h
  1. /*** Foundation Command IDs ***/  
  2. #define ZCL_CMD_READ                                    0x00  
  3. #define ZCL_CMD_READ_RSP                                0x01  
  4. #define ZCL_CMD_WRITE                                   0x02  
  5. #define ZCL_CMD_WRITE_UNDIVIDED                         0x03  
  6. #define ZCL_CMD_WRITE_RSP                               0x04  
  7. #define ZCL_CMD_WRITE_NO_RSP                            0x05  
  8. #define ZCL_CMD_CONFIG_REPORT                           0x06  
  9. #define ZCL_CMD_CONFIG_REPORT_RSP                       0x07  
  10. #define ZCL_CMD_READ_REPORT_CFG                         0x08  
  11. #define ZCL_CMD_READ_REPORT_CFG_RSP                     0x09  
  12. #define ZCL_CMD_REPORT                                  0x0a  
  13. #define ZCL_CMD_DEFAULT_RSP                             0x0b  
  14. #define ZCL_CMD_DISCOVER                                0x0c  
  15. #define ZCL_CMD_DISCOVER_RSP                            0x0d  
而zcl.c中默认的处理函数数组是
  1. static CONST zclCmdItems_t zclCmdTable[] =  
  2. {  
  3. #ifdef ZCL_READ  
  4.   /* ZCL_CMD_READ */                { zclParseInReadCmd,             zclProcessInReadCmd             },  
  5.   /* ZCL_CMD_READ_RSP */            { zclParseInReadRspCmd,          zclSendMsg                      },  
  6. #else  
  7.   /* ZCL_CMD_READ */                { NULL,                          NULL                            },  
  8.   /* ZCL_CMD_READ_RSP */            { NULL,                          NULL                            },  
  9. #endif // ZCL_READ  
  10.   
  11. #ifdef ZCL_WRITE  
  12.   /* ZCL_CMD_WRITE */               { zclParseInWriteCmd,            zclProcessInWriteCmd            },  
  13.   /* ZCL_CMD_WRITE_UNDIVIDED */     { zclParseInWriteCmd,            zclProcessInWriteUndividedCmd   },  
  14.   /* ZCL_CMD_WRITE_RSP */           { zclParseInWriteRspCmd,         zclSendMsg                      },  
  15.   /* ZCL_CMD_WRITE_NO_RSP */        { zclParseInWriteCmd,            zclProcessInWriteCmd            },  
  16. #else  
  17.   /* ZCL_CMD_WRITE */               { NULL,                          NULL                            },  
  18.   /* ZCL_CMD_WRITE_UNDIVIDED */     { NULL,                          NULL                            },  
  19.   /* ZCL_CMD_WRITE_RSP */           { NULL,                          NULL                            },  
  20.   /* ZCL_CMD_WRITE_NO_RSP */        { NULL,                          NULL                            },  
  21. #endif // ZCL_WRITE  
  22.   
  23. #ifdef ZCL_REPORT  
  24.   /* ZCL_CMD_CONFIG_REPORT */       { zclParseInConfigReportCmd,     zclSendMsg                      },  
  25.   /* ZCL_CMD_CONFIG_REPORT_RSP */   { zclParseInConfigReportRspCmd,  zclSendMsg                      },  
  26.   /* ZCL_CMD_READ_REPORT_CFG */     { zclParseInReadReportCfgCmd,    zclSendMsg                      },  
  27.   /* ZCL_CMD_READ_REPORT_CFG_RSP */ { zclParseInReadReportCfgRspCmd, zclSendMsg                      },  
  28.   /* ZCL_CMD_REPORT */              { zclParseInReportCmd,           zclSendMsg                      },  
  29. #else  
  30.   /* ZCL_CMD_CONFIG_REPORT */       { NULL,                          NULL                            },  
  31.   /* ZCL_CMD_CONFIG_REPORT_RSP */   { NULL,                          NULL                            },  
  32.   /* ZCL_CMD_READ_REPORT_CFG */     { NULL,                          NULL                            },  
  33.   /* ZCL_CMD_READ_REPORT_CFG_RSP */ { NULL,                          NULL                            },  
  34.   /* ZCL_CMD_REPORT */              { NULL,                          NULL                            },  
  35. #endif // ZCL_REPORT  
  36.   
  37.   /* ZCL_CMD_DEFAULT_RSP */         { zclParseInDefaultRspCmd,       zclSendMsg                      },  
  38.     
  39. #ifdef ZCL_DISCOVER    
  40.   /* ZCL_CMD_DISCOVER */            { zclParseInDiscCmd,             zclProcessInDiscCmd             },  
  41.   /* ZCL_CMD_DISCOVER_RSP */        { zclParseInDiscRspCmd,          zclSendMsg                      }  
  42. #else  
  43.   /* ZCL_CMD_DISCOVER */            { NULL,                          NULL                            },  
  44.   /* ZCL_CMD_DISCOVER_RSP */        { NULL,                          NULL                            }  
  45. #endif // ZCL_DISCOVER  
  46. };  

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
  1. typedef struct zclAttrRecsList  
  2. {  
  3.   struct zclAttrRecsList *next;  
  4.   uint8                  endpoint;      // Used to link it into the endpoint descriptor  
  5.   uint8                  numAttributes; // Number of the following records  
  6.   CONST zclAttrRec_t     *attrs;        // attribute records  
  7. } zclAttrRecsList;  
  8.   
  9. // Attribute record  
  10. typedef struct  
  11. {  
  12.   uint16  attrId;         // Attribute ID  
  13.   uint8   dataType;       // Data Type - defined in AF.h  
  14.   uint8   accessControl;  // Read/write - bit field  
  15.   void    *dataPtr;       // Pointer to data field  
  16. } zclAttribute_t;  
  17.   
  18. typedef struct  
  19. {  
  20.   uint16          clusterID;    // Real cluster ID  
  21.   zclAttribute_t  attr;  
  22. } zclAttrRec_t;  
  23.   
  24. CONST zclAttrRec_t zclSampleLight_Attrs[SAMPLELIGHT_MAX_ATTRIBUTES] =  
  25. {  
  26.   // *** General Basic Cluster Attributes ***  
  27.   {  
  28.     ZCL_CLUSTER_ID_GEN_BASIC,             // Cluster IDs - defined in the foundation (ie. zcl.h)  
  29.     {  // Attribute record  
  30.       ATTRID_BASIC_HW_VERSION,            // Attribute ID - Found in Cluster Library header (ie. zcl_general.h)  
  31.       ZCL_DATATYPE_UINT8,                 // Data Type - found in zcl.h  
  32.       ACCESS_CONTROL_READ,                // Variable access control - found in zcl.h  
  33.       (void *)&zclSampleLight_HWRevision  // Pointer to attribute variable  
  34.     }  
  35.   },  
  36.   {  
  37.     ZCL_CLUSTER_ID_GEN_BASIC,  
  38.     { // Attribute record  
  39.       ATTRID_BASIC_ZCL_VERSION,  
  40.       ZCL_DATATYPE_UINT8,  
  41.       ACCESS_CONTROL_READ,  
  42.       (void *)&zclSampleLight_ZCLVersion  
  43.     }  
  44.   },  
  45.   {  
  46.     ZCL_CLUSTER_ID_GEN_BASIC,  
  47.     { // Attribute record  
  48.       ATTRID_BASIC_MANUFACTURER_NAME,  
  49.       ZCL_DATATYPE_CHAR_STR,  
  50.       ACCESS_CONTROL_READ,  
  51.       (void *)zclSampleLight_ManufacturerName  
  52.     }  
  53.   },  
  54.   {  
  55.     ZCL_CLUSTER_ID_GEN_BASIC,  
  56.     { // Attribute record  
  57.       ATTRID_BASIC_MODEL_ID,  
  58.       ZCL_DATATYPE_CHAR_STR,  
  59.       ACCESS_CONTROL_READ,  
  60.       (void *)zclSampleLight_ModelId  
  61.     }  
  62.   },  
  63.   {  
  64.     ZCL_CLUSTER_ID_GEN_BASIC,  
  65.     { // Attribute record  
  66.       ATTRID_BASIC_DATE_CODE,  
  67.       ZCL_DATATYPE_CHAR_STR,  
  68.       ACCESS_CONTROL_READ,  
  69.       (void *)zclSampleLight_DateCode  
  70.     }  
  71.   },  
  72.   {  
  73.     ZCL_CLUSTER_ID_GEN_BASIC,  
  74.     { // Attribute record  
  75.       ATTRID_BASIC_POWER_SOURCE,  
  76.       ZCL_DATATYPE_UINT8,  
  77.       ACCESS_CONTROL_READ,  
  78.       (void *)&zclSampleLight_PowerSource  
  79.     }  
  80.   },  
  81.   {  
  82.     ZCL_CLUSTER_ID_GEN_BASIC,  
  83.     { // Attribute record  
  84.       ATTRID_BASIC_LOCATION_DESC,  
  85.       ZCL_DATATYPE_CHAR_STR,  
  86.       (ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),  
  87.       (void *)zclSampleLight_LocationDescription  
  88.     }  
  89.   },  
  90.   {  
  91.     ZCL_CLUSTER_ID_GEN_BASIC,  
  92.     { // Attribute record  
  93.       ATTRID_BASIC_PHYSICAL_ENV,  
  94.       ZCL_DATATYPE_UINT8,  
  95.       (ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),  
  96.       (void *)&zclSampleLight_PhysicalEnvironment  
  97.     }  
  98.   },  
  99.   {  
  100.     ZCL_CLUSTER_ID_GEN_BASIC,  
  101.     { // Attribute record  
  102.       ATTRID_BASIC_DEVICE_ENABLED,  
  103.       ZCL_DATATYPE_BOOLEAN,  
  104.       (ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),  
  105.       (void *)&zclSampleLight_DeviceEnable  
  106.     }  
  107.   },  
  108.   
  109.   // *** Identify Cluster Attribute ***  
  110.   {  
  111.     ZCL_CLUSTER_ID_GEN_IDENTIFY,  
  112.     { // Attribute record  
  113.       ATTRID_IDENTIFY_TIME,  
  114.       ZCL_DATATYPE_UINT16,  
  115.       (ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),  
  116.       (void *)&zclSampleLight_IdentifyTime  
  117.     }  
  118.   },  
  119.   
  120.   // *** On/Off Cluster Attributes ***  
  121.   {  
  122.     ZCL_CLUSTER_ID_GEN_ON_OFF,  
  123.     { // Attribute record  
  124.       ATTRID_ON_OFF,  
  125.       ZCL_DATATYPE_UINT8,  
  126.       ACCESS_CONTROL_READ,  
  127.       (void *)&zclSampleLight_OnOff  
  128.     }  
  129.   },  
  130. };  
4.如果zclCmdTable[ZCL_CMD_READ]对应的处理函数是zclSendMsg,则会将这个消息以ZCL_INCOMING_MSG事件发给上层任务去处理,前提是上层任务使用zcl_registerForMsg注册过。

对zcl不同领域的不同clusterid的不同command的处理:
例如服务器端接收到如下的clusterid(通用领域的).和命令号是COMMAND_TOGGLE怎么处理的呢?
  1. // General Clusters  
  2. #define ZCL_CLUSTER_ID_GEN_BASIC                             0x0000  
  3. #define ZCL_CLUSTER_ID_GEN_POWER_CFG                         0x0001  
  4. #define ZCL_CLUSTER_ID_GEN_DEVICE_TEMP_CONFIG                0x0002  
  5. #define ZCL_CLUSTER_ID_GEN_IDENTIFY                          0x0003  
  6. #define ZCL_CLUSTER_ID_GEN_GROUPS                            0x0004  
  7. #define ZCL_CLUSTER_ID_GEN_SCENES                            0x0005  
  8. #define ZCL_CLUSTER_ID_GEN_ON_OFF                            0x0006//this  
  9. #define ZCL_CLUSTER_ID_GEN_ON_OFF_SWITCH_CONFIG              0x0007  
  10. #define ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL                     0x0008  
  11. #define ZCL_CLUSTER_ID_GEN_ALARMS                            0x0009  
  12. #define ZCL_CLUSTER_ID_GEN_TIME                              0x000A  
  13. #define ZCL_CLUSTER_ID_GEN_LOCATION                          0x000B  
  14. #define ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT                 0x0800  

首先要了解general领域的clusterid  onoff 的属性和命令各有哪些
  1. /*********************************/  
  2. /*** On/Off Cluster Attributes ***/  
  3. /*********************************/  
  4. #define ATTRID_ON_OFF                                     0x0000  
  5.   
  6. /*******************************/  
  7. /*** On/Off Cluster Commands ***/  
  8. /*******************************/  
  9. #define COMMAND_OFF                                       0x00  
  10. #define COMMAND_ON                                        0x01  
  11. #define COMMAND_TOGGLE                                    0x02  
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,如下
  1. static ZStatus_t zclGeneral_HdlInSpecificCommands( zclIncoming_t *pInMsg )  
  2. {  
  3.   ZStatus_t stat;  
  4.   zclGeneral_AppCallbacks_t *pCBs;  
  5.   
  6.   // make sure endpoint exists  
  7.   pCBs = zclGeneral_FindCallbacks( pInMsg->msg->endPoint );  
  8.   if ( pCBs == NULL )  
  9.     return ( ZFailure );  
  10.   
  11.   switch ( pInMsg->msg->clusterId )  
  12.   {  
  13. #ifdef ZCL_BASIC  
  14.     case ZCL_CLUSTER_ID_GEN_BASIC:  
  15.       stat = zclGeneral_ProcessInBasic( pInMsg, pCBs );  
  16.       break;  
  17. #endif // ZCL_BASIC  
  18.   
  19. #ifdef ZCL_IDENTIFY  
  20.     case ZCL_CLUSTER_ID_GEN_IDENTIFY:  
  21.       stat = zclGeneral_ProcessInIdentity( pInMsg, pCBs );  
  22.       break;  
  23. #endif // ZCL_IDENTIFY  
  24.   
  25. #ifdef ZCL_GROUPS  
  26.     case ZCL_CLUSTER_ID_GEN_GROUPS:  
  27.       if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )  
  28.         stat = zclGeneral_ProcessInGroupsServer( pInMsg );  
  29.       else  
  30.         stat = zclGeneral_ProcessInGroupsClient( pInMsg, pCBs );  
  31.       break;  
  32. #endif // ZCL_GROUPS  
  33.   
  34. #ifdef ZCL_SCENES  
  35.     case ZCL_CLUSTER_ID_GEN_SCENES:  
  36.       if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )  
  37.         stat = zclGeneral_ProcessInScenesServer( pInMsg, pCBs );  
  38.       else  
  39.         stat = zclGeneral_ProcessInScenesClient( pInMsg, pCBs );  
  40.       break;  
  41. #endif // ZCL_SCENES  
  42.   
  43. #ifdef ZCL_ON_OFF  
  44.     case ZCL_CLUSTER_ID_GEN_ON_OFF:  
  45.       stat = zclGeneral_ProcessInOnOff( pInMsg, pCBs );  
  46.       break;  
  47. #endif // ZCL_ON_OFF  
  48.   
  49. #ifdef ZCL_LEVEL_CTRL  
  50.     case ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL:  
  51.       stat = zclGeneral_ProcessInLevelControl( pInMsg, pCBs );  
  52.       break;  
  53. #endif // ZCL_LEVEL_CTRL  
  54.   
  55. #ifdef ZCL_ALARMS  
  56.     case ZCL_CLUSTER_ID_GEN_ALARMS:  
  57.       if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )  
  58.         stat = zclGeneral_ProcessInAlarmsServer( pInMsg, pCBs );  
  59.       else  
  60.         stat = zclGeneral_ProcessInAlarmsClient( pInMsg, pCBs );  
  61.       break;  
  62. #endif // ZCL_ALARMS  
  63.   
  64. #ifdef ZCL_LOCATION  
  65.     case ZCL_CLUSTER_ID_GEN_LOCATION:  
  66.       if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )  
  67.         stat = zclGeneral_ProcessInLocationServer( pInMsg, pCBs );  
  68.       else  
  69.         stat = zclGeneral_ProcessInLocationClient( pInMsg, pCBs );  
  70.       break;  
  71. #endif // ZCL_LOCATION  
  72.   
  73.     case ZCL_CLUSTER_ID_GEN_POWER_CFG:  
  74.     case ZCL_CLUSTER_ID_GEN_DEVICE_TEMP_CONFIG:  
  75.     case ZCL_CLUSTER_ID_GEN_ON_OFF_SWITCH_CONFIG:  
  76.     case ZCL_CLUSTER_ID_GEN_TIME:  
  77.     default:  
  78.       stat = ZFailure;  
  79.       break;  
  80.   }  
  81.   
  82.   return ( stat );  
  83. }  
此函数会在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
  1. typedef struct zclGenCBRec  
  2. {  
  3.   struct zclGenCBRec        *next;  
  4.   uint8                     endpoint; // Used to link it into the endpoint descriptor  
  5.   zclGeneral_AppCallbacks_t *CBs;     // Pointer to Callback function  
  6. } zclGenCBRec_t;  
  7.   
  8. typedef struct  
  9. {  
  10.   zclGCB_BasicReset_t               pfnBasicReset;                // Basic Cluster Reset command  
  11.   zclGCB_Identify_t                 pfnIdentify;                  // Identify command  
  12.   zclGCB_IdentifyQueryRsp_t         pfnIdentifyQueryRsp;          // Identify Query Response command  
  13.   zclGCB_OnOff_t                    pfnOnOff;                     // On/Off cluster commands  
  14.   zclGCB_LevelControlMoveToLevel_t  pfnLevelControlMoveToLevel;   // Level Control Move to Level command  
  15.   zclGCB_LevelControlMove_t         pfnLevelControlMove;          // Level Control Move command  
  16.   zclGCB_LevelControlStep_t         pfnLevelControlStep;          // Level Control Step command  
  17.   zclGCB_LevelControlStop_t         pfnLevelControlStop;          // Level Control Stop command  
  18.   zclGCB_GroupRsp_t                 pfnGroupRsp;                  // Group Response commands  
  19.   zclGCB_SceneStoreReq_t            pfnSceneStoreReq;             // Scene Store Request command  
  20.   zclGCB_SceneRecallReq_t           pfnSceneRecallReq;            // Scene Recall Request command  
  21.   zclGCB_SceneRsp_t                 pfnSceneRsp;                  // Scene Response command  
  22.   zclGCB_Alarm_t                    pfnAlarm;                     // Alarm (Response) commands  
  23.   zclGCB_Location_t                 pfnLocation;                  // RSSI Location command  
  24.   zclGCB_LocationRsp_t              pfnLocationRsp;               // RSSI Location Response command  
  25. } zclGeneral_AppCallbacks_t;  
  26. //  
  27. static zclGeneral_AppCallbacks_t zclSampleLight_CmdCallbacks =  
  28. {  
  29.   zclSampleLight_BasicResetCB,              // Basic Cluster Reset command  
  30.   zclSampleLight_IdentifyCB,                // Identify command    
  31.   zclSampleLight_IdentifyQueryRspCB,        // Identify Query Response command  
  32.   zclSampleLight_OnOffCB,                   // On/Off cluster command  
  33.   NULL,                                     // Level Control Move to Level command  
  34.   NULL,                                     // Level Control Move command  
  35.   NULL,                                     // Level Control Step command  
  36.   NULL,                                     // Group Response commands  
  37.   NULL,                                     // Scene Store Request command  
  38.   NULL,                                     // Scene Recall Request command  
  39.   NULL,                                     // Scene Response command  
  40.   NULL,                                     // Alarm (Response) command  
  41.   NULL,                                     // RSSI Location commands  
  42.   NULL,                                     // RSSI Location Response commands  
  43. };  

4.在具体的clusterid处理函数中在根据command进行不同处理,比如zclSampleLight_OnOffCB
  1. static void zclSampleLight_OnOffCB( uint8 cmd )  
  2. {  
  3.   // Turn on the light  
  4.   if ( cmd == COMMAND_ON )  
  5.     zclSampleLight_OnOff = LIGHT_ON;  
  6.   
  7.   
  8.   // Turn off the light  
  9.   else if ( cmd == COMMAND_OFF )  
  10.     zclSampleLight_OnOff = LIGHT_OFF;  
  11.   
  12.   
  13.   // Toggle the light  
  14.   else  
  15.   {  
  16.     if ( zclSampleLight_OnOff == LIGHT_OFF )  
  17.       zclSampleLight_OnOff = LIGHT_ON;  
  18.     else  
  19.       zclSampleLight_OnOff = LIGHT_OFF;  
  20.   }  
  21.   
  22.   
  23.   // In this sample app, we use LED4 to simulate the Light  
  24.   if ( zclSampleLight_OnOff == LIGHT_ON )  
  25.     HalLedSet( HAL_LED_4, HAL_LED_MODE_ON );  
  26.   else  
  27.     HalLedSet( HAL_LED_4, HAL_LED_MODE_OFF );  
  28. }  


综上,

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进一步操作
0 0
原创粉丝点击