1.如果有一个ZCL命令发出,如zclGeneral_SendOnOff_CmdToggle(AT_ZCL_ENDPOINT,&dstAddr,0,1),此函数实际上是zcl_SendCommand函数的宏定义,此函数调用AF_DataRequest函数将信息通过无线发出去。2.在接收端,必须先要对端点描述符和回调函数进行注册,在这里讲一下在初始化函数里调用的一个函数zclGeneral_RegisterCmdCallbacks( AT_ZCL_ENDPOINT, &AT_ZCL_GEN_CmdCallbacks ),即回调注册函数,进入这个函数,有如下代码:
if ( zclGenPluginRegisted == FALSE )
{
zcl_registerPlugin( ZCL_CLUSTER_ID_GEN_BASIC,
ZCL_CLUSTER_ID_GEN_MULTISTATE_VALUE_BASIC,
zclGeneral_HdlIncoming );
......
就是如果没有注册回调函数,则对其进行注册。只要是相应簇注册了回调函数,接收到相关命令就会处理。
3.当AF层收到数据包时,会进入zcl_event_loop处理函数,注意里面这段代码:
if ( *msgPtr == AF_INCOMING_MSG_CMD )
{
rawAFMsg = (afIncomingMSGPacket_t *)msgPtr;
zclProcessMessageMSG( rawAFMsg );
rawAFMsg = NULL;
}
如果收到AF层的消息,则调用zclProcessMessageMSG( rawAFMsg ),那这个函数又干了什么呢?不妨先看看函数体,
epDesc = afFindEndPointDesc( pkt->endPoint );首先是获取相应端点信息,
......
pInPlugin = zclFindPlugin( pkt->clusterId, epDesc->simpleDesc->AppProfId );接着根据簇寻找簇范围内的对应回调函数,
......
else // Not a foundation type message, so it must be specific to the cluster ID.
{
if ( pInPlugin && pInPlugin->pfnIncomingHdlr )
{
// The return value of the plugin function will be
// ZSuccess - Supported and need default response
// ZFailure - Unsupported
// ZCL_STATUS_CMD_HAS_RSP - Supported and do not need default rsp
// ZCL_STATUS_INVALID_FIELD - Supported, but the incoming msg is wrong formatted
// ZCL_STATUS_INVALID_VALUE - Supported, but the request not achievable by the h/w
// ZCL_STATUS_SOFTWARE_FAILURE - Supported but ZStack memory allocation fails
status = pInPlugin->pfnIncomingHdlr( &inMsg );
if ( status == ZCL_STATUS_CMD_HAS_RSP || ( interPanMsg && status == ZSuccess ) )
{
return; // We're done
}
}
这里就是调用函数zclGeneral_HdlIncoming,进入
if ( zcl_ClusterCmd( pInMsg->hdr.fc.type ) )
{
// Is this a manufacturer specific command?
if ( pInMsg->hdr.fc.manuSpecific == 0 )
{
stat = zclGeneral_HdlInSpecificCommands( pInMsg );
}
else
{
// We don't support any manufacturer specific command.
stat = ZFailure;
}
}
这里调用到了zclGeneral_HdlInSpecificCommands( pInMsg ),进入
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 );
}
到这里,是不是都全明白了,原来所有的簇处理函数都可以在这里完成。
|