方法一:很多初學者從Zstack 2.5.1開始學習,轉到在stack 3.0.2后,會很不適應。方法一就是在zstack 3.0.2中用在stack 2.5.1a協議棧的方式實現無線接收。
在zstack 3.0.2中無線數據接收處理在如下函數中:
uint16 zcl_event_loop( uint8 task_id, uint16 events )
{
……
if ( *msgPtr == AF_INCOMING_MSG_CMD )
{
zcl_ProcessMessageMSG( (afIncomingMSGPacket_t *)msgPtr ); //此處就是對空中數據的處理
}
……
}
做變形如下:
uint16 zcl_event_loop( uint8 task_id, uint16 events )
{
……
if ( *msgPtr == AF_INCOMING_MSG_CMD )
{
if((((afIncomingMSGPacket_t *)msgPtr)->clusterId >=MYAPP_SENDADDR_CLUSTERID)&&
(((afIncomingMSGPacket_t *)msgPtr)->clusterId <=(MYAPP_SENDADDR_CLUSTERID+100)))
{
Zcl_SendAF_To_GenericApp((afIncomingMSGPacket_t *)msgPtr); //此處是用來處理用戶自定義的CLUSTER ID
}
else
{
zcl_ProcessMessageMSG( (afIncomingMSGPacket_t *)msgPtr ); //此處用來處理zstack 3.0中系統簇ID
}
}
……
}
其中MYAPP_SENDADDR_CLUSTERID就是自己定義的第一個簇ID,MYAPP_SENDADDR_CLUSTERID+100表示用戶最多可以定義100個簇ID。
自己的簇ID定義如下圖所示:
接下來講解自定義的Zcl_SendAF_To_GenericApp(); 函數,此函數的目的是將無線數據從zcl層發送到zclGenericApp_TaskID層。
static void Zcl_SendAF_To_GenericApp(afIncomingMSGPacket_t *pkt)
{
zcl_SendAF_To_Generic *pMsg1;
pMsg1 = (zcl_SendAF_To_Generic *)osal_msg_allocate( sizeof( zcl_SendAF_To_Generic ));
pMsg1->hdr.event = MYAPP_ZCLTOGENERIC;
pMsg1->msg = pkt; // 把數據定位到結構體數據部分
//HalUARTWrite(0,"22222",5);HalUARTWrite(0,pMsg1->msg->cmd.Data,pMsg1->msg->cmd.DataLength);HalUARTWrite(0,"22222",5);
//HalUARTWrite(0,"Zcl_SendAF_To_GenericApp\r\n",strlen("Zcl_SendAF_To_GenericApp\r\n"));
osal_msg_send( zclGenericApp_TaskID, (byte *)pMsg1 ); //登記任務,發往上層
osal_msg_deallocate ( (byte *)pMsg1 ); //釋放內存
}
其中:zcl_SendAF_To_Generic為自定義的結構體類型,在zcl.h中;MYAPP_ZCLTOGENERIC為自定義的zclGenericApp_TaskID層的系統事件,在ZComDef.h中。
如下圖所示:
在zclGenericApp_event_loop函數中添加系統事件的處理函數
uint16 zclGenericApp_event_loop( uint8 task_id, uint16 events )
{
……
if ( events & SYS_EVENT_MSG )
{
while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclGenericApp_TaskID )) )
{
switch ( MSGpkt->hdr.event )
{
……
case KEY_CHANGE:
……
break;
case ZDO_STATE_CHANGE:
……
break;
case MYAPP_ZCLTOGENERIC:
MyApp_MessageMSGCB( (zcl_SendAF_To_Generic*)MSGpkt ); //這個函數就是對自定義簇ID的處理函數
break;
default:
break;
}
// Release the memory
osal_msg_deallocate( (uint8 *)MSGpkt );
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
……
}
繼續:
void MyApp_MessageMSGCB( zcl_SendAF_To_Generic *pkt )
{
uint8 *databuf; //用來接收AF數據的數組
databuf = osal_msg_allocate( sizeof( zcl_SendAF_To_Generic ));
osal_memcpy(databuf,pkt->msg->cmd.Data,pkt->msg->cmd.DataLength); //將接受大的數據,copy到databuf中;
switch ( pkt->msg->clusterId)
{
case MYAPP_SENDADDR_CLUSTERID: //自定義簇ID
HalUARTWrite(0,"MyApp_MessageMSGCB\r\n",strlen("MyApp_MessageMSGCB\r\n")); //此處添加簇ID對應的處理函數即可
break;
default:
break;
}
osal_msg_deallocate ( (byte *)databuf ); //釋放內存
}
上面是接收,順便提一下發送:直接使用函數發送即可,但是有些參數需要自己填加。
比如:
static afAddrType_t MyApp_DstAddr;
endPointDesc_t *MyApp_epDesc;
byte MyApp_TransID;
void zclGenericApp_Init( byte task_id )
{
……
MyApp_epDesc = afFindEndPointDesc( GENERICAPP_ENDPOINT );
}
然后發送時按照就協議棧進行發送即可。
AF_DataRequest(&MyApp_DstAddr, //目的地址,發送之前需要自己賦值
MyApp_epDesc, //設備描述符
MYAPP_SENDADDR_CLUSTERID, //簇ID
14, //長度
buf, //要發送的數組
&MyApp_TransID, //傳輸序列號
AF_TX_OPTIONS_NONE, //發送選項
AF_DEFAULT_RADIUS)==afStatus_SUCCESS)
{
//成功;
}
else
{
//如果不成功,就再發送一次
}
方法二:直接在zstack3.0.2 的基礎上進行無線數據的收發
待更新……