再来看控制端SimpleSwitch<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
【OSAL_SampleSw.c】构造系统初始化及其事件循环数据结构。任务初始化队列osalInitTasks中把最后的任务改为开关的任务初始化函数:zclSampleSw_Init( taskID );在事件循环tasksArr中加入开关节点的事件循环函数:zclSampleSw_event_loop。zclSampleSw_Init()实现在【zcl_samplesw.c】中,同样是HA剖面初始化,注册回调函数,应用属性列表,按键等。
void zclSampleSw_Init( byte task_id )
{
zclSampleSw_TaskID = task_id;
//设置目的地址
// Set destination address to indirect
zclSampleSw_DstAddr.addrMode = (afAddrMode_t)AddrNotPresent;
zclSampleSw_DstAddr.endPoint = 0;
zclSampleSw_DstAddr.addr.shortAddr = 0;
// This app is part of the Home Automation Profile
zclHA_Init( &zclSampleSw_SimpleDesc );
// Register the ZCL General Cluster Library callback functions
zclGeneral_RegisterCmdCallbacks( SAMPLESW_ENDPOINT, &zclSampleSw_CmdCallbacks );
// Register the application's attribute list
zcl_registerAttrList( SAMPLESW_ENDPOINT, SAMPLESW_MAX_ATTRIBUTES, zclSampleSw_Attrs );
// Register for all key events - This app will handle all key events
RegisterForKeys( zclSampleSw_TaskID );
// Register for a test endpoint
afRegister( &sampleSw_TestEp );
//注册两个消息。通过ZDO_RegisterForZDOMsg()注册的消息都能够被应用接收,调用此函数请求空中消息,消息的副本将会以系统消息的形式发送到任务,然后任务再解析消息。当注册了一个特定的消息,然后接收到消息(OTA)后,消息将作为ZDO_CB_MSG被发送到应用/任务,消息体(zdoIncomingMsg_t)将包含OTA消息。
ZDO_RegisterForZDOMsg( zclSampleSw_TaskID, End_Device_Bind_rsp );
ZDO_RegisterForZDOMsg( zclSampleSw_TaskID, Match_Desc_rsp );
}
事件处理循环:
uint16 zclSampleSw_event_loop( uint8 task_id, uint16 events )
{
afIncomingMSGPacket_t *MSGpkt;
if ( events & SYS_EVENT_MSG )
{
while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclSampleSw_TaskID )) )
{
switch ( MSGpkt->hdr.event )
{
case ZDO_CB_MSG:
//处理在初始化中注册的那两个消息
zclSampleSw_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
break;
case KEY_CHANGE:
//处理按键事件
zclSampleSw_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
break;
default:
break;
}
//消息处理完后要记得释放掉所有空间
// Release the memory
osal_msg_deallocate( (uint8 *)MSGpkt );
}
………………
}
//按键处理函数是一个关键,在这个函数里面将会出现命令的发送:
static void zclSampleSw_HandleKeys( byte shift, byte keys )
{
zAddrType_t dstAddr;
if ( keys & HAL_KEY_SW_1 )
{
// Using this as the "Light Switch"
//发送切换命令,调用zcl_SendCommand()来发送特定的命令,目的地址在初始化的时候赋了值,给予的是一个不定的地址,所以依靠绑定表来查找。这些发送命令的函数定义在【zcl_general.h】
zclGeneral_SendOnOff_CmdToggle( SAMPLESW_ENDPOINT, &zclSampleSw_DstAddr, false, 0 );
}
if ( keys & HAL_KEY_SW_2 )
{
HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
//关闭LED4并发送绑定请求,这里的绑定请求参数中的输入输出簇只有和要绑定的设备相互补时才能绑定成功。开关设备上没有输入簇,输出簇为:ZCL_HA_CLUSTER_ID_GEN_ON_OFF,那么就只能和输入簇列表中为ZCL_HA_CLUSTER_ID_GEN_ON_OFF的终端发生绑定。在灯设备上输入簇列表为:
static cId_t bindingInClusters[ZCLSAMPLELIGHT_BINDINGLIST] =
{
ZCL_HA_CLUSTER_ID_GEN_ON_OFF,
ZCL_HA_CLUSTER_ID_GEN_LEVEL_CONTROL
};其中存在ZCL_HA_CLUSTER_ID_GEN_ON_OFF,那么这两个设备只要在规定时间内向协调器发送ZDP_EndDeviceBindReq()就能绑定了。这样理解应该没错吧 呵呵
// Initiate an End Device Bind Request, this bind request will
// only use a cluster list that is important to binding.
dstAddr.addrMode = afAddr16Bit;
dstAddr.addr.shortAddr = 0; // Coordinator makes the match
ZDP_EndDeviceBindReq( &dstAddr, NLME_GetShortAddr(),
SAMPLESW_ENDPOINT,
ZCL_HA_PROFILE_ID,
0, NULL, // No incoming clusters to bind
ZCLSAMPLESW_BINDINGLIST, bindingOutClusters,
TRUE );
}
if ( keys & HAL_KEY_SW_3 )
{
}
if ( keys & HAL_KEY_SW_4 )
{
HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
// Initiate a Match Description Request (Service Discovery)
dstAddr.addrMode = AddrBroadcast;
dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR;
ZDP_MatchDescReq( &dstAddr, NWK_BROADCAST_SHORTADDR,
ZCL_HA_PROFILE_ID,
ZCLSAMPLESW_BINDINGLIST, bindingOutClusters,
0, NULL, // No incoming clusters to bind
FALSE );
}
}
文章评论(0条评论)
登录后参与讨论