OSAL处理来自AF的数据包.doc_第1页
OSAL处理来自AF的数据包.doc_第2页
OSAL处理来自AF的数据包.doc_第3页
OSAL处理来自AF的数据包.doc_第4页
OSAL处理来自AF的数据包.doc_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

以下为系统处理来自AF层数据包的大致流程,afIncomingData() afBuildMSGIncoming() osal_msg_send() osal_set_event()根据task_id调用事件处理函数(如SampleApp_ProcessEvent() 判断具体事件类型调用相应回调函数(如SampleApp_MessageMSGCB() 实现具体现象 afIncomingData()函数用来从APS层传递一个ASDU到AF层;中间调用了afBuildMSGIncoming()函数,这个函数是用来为APS层建立一个特定格式的消息包,然后再调用osal_msg_send()把消息(包含了ASDU)传往AF层.AF层规定接收的数据包的类型如下:typedef struct osal_event_hdr_t hdr; uint16 groupId; uint16 clusterId; afAddrType_t srcAddr; byte endPoint; byte wasBroadcast; byte LinkQuality; byte SecurityUse; uint32 timestamp; afMSGCommandFormat_t cmd; afIncomingMSGPacket_t;首先看一下afIncomingData()函数/* * fn afIncomingData * * brief Transfer a data PDU (ASDU) from the APS sub-layer to the AF. * * param aff - pointer to APS frame format * param SrcAddress - Source address * param LinkQuality - incoming messages link quality * param SecurityUse - Security enable/disable * * return none */传输数据:APS-AFvoid afIncomingData( aps_FrameFormat_t *aff, zAddrType_t *SrcAddress, uint8 LinkQuality, byte SecurityUse, uint32 timestamp ) endPointDesc_t *epDesc = NULL; uint16 epProfileID = 0xFFFF; / Invalid Profile ID epList_t *pList; uint8 grpEp;/- /*如果这个帧传递模式是组传递*/ if ( (aff-FrmCtrl & APS_DELIVERYMODE_MASK) = APS_FC_DM_GROUP) ) / Find the first endpoint for this group grpEp = aps_FindGroupForEndpoint( aff-GroupID, APS_GROUPS_FIND_FIRST ); if ( grpEp = APS_GROUPS_EP_NOT_FOUND ) return; / No endpoint found,没找到终端 epDesc = afFindEndPointDesc( grpEp ); /找到终端,接着找终端描述符 if ( epDesc = NULL ) return; / Endpoint descriptor not found,没找到终端描述符 pList = afFindEndPointDescList( epDesc-endPoint ); /找到终端描述符 /pList指向终端列表中的元素/- /*广播到各端点*/ else if ( aff-DstEndPoint = AF_BROADCAST_ENDPOINT ) / Set the list if ( (pList = epList) ) epDesc = pList-epDesc; /- /*单播到特定端点*/ else if ( (epDesc = afFindEndPointDesc( aff-DstEndPoint ) ) pList = afFindEndPointDescList( epDesc-endPoint ); /- while ( epDesc ) if ( pList-pfnDescCB ) /如果有回叫函数 uint16 *pID = (uint16 *)(pList-pfnDescCB( AF_DESCRIPTOR_PROFILE_ID, epDesc-endPoint ); if ( pID ) epProfileID = *pID; osal_mem_free( pID ); else if ( epDesc-simpleDesc ) /简单描述符 epProfileID = epDesc-simpleDesc-AppProfId; if ( (aff-ProfileID = epProfileID) | (epDesc-endPoint = ZDO_EP) & (aff-ProfileID = ZDO_PROFILE_ID) ) /符合各条件 /建立信息传递,注意,这里调用afBuildMSGIncoming()! afBuildMSGIncoming( aff, epDesc, SrcAddress, LinkQuality, SecurityUse, timestamp ); /*组传递模式,找下一个终端*/ if ( (aff-FrmCtrl & APS_DELIVERYMODE_MASK) = APS_FC_DM_GROUP) ) / Find the next endpoint for this group grpEp = aps_FindGroupForEndpoint( aff-GroupID, grpEp ); if ( grpEp = APS_GROUPS_EP_NOT_FOUND ) return; / No endpoint found epDesc = afFindEndPointDesc( grpEp ); if ( epDesc = NULL ) return; / Endpoint descriptor not found pList = afFindEndPointDescList( epDesc-endPoint ); /epDesc != NULL /*广播传递模式,找下一个终端*/ else if ( aff-DstEndPoint = AF_BROADCAST_ENDPOINT ) pList = pList-nextDesc; if ( pList ) epDesc = pList-epDesc; else epDesc = NULL; /*单播模式,无下一终端*/ else epDesc = NULL; /-afBuildMSGIncoming( aff, epDesc, SrcAddress, LinkQuality, SecurityUse, timestamp )afBuildMSGIncoming( aps_FrameFormat_t *aff, endPointDesc_t *epDesc, zAddrType_t *SrcAddress, uint8 LinkQuality, byte SecurityUse, uint32 timestamp )实参形参Aff*affepDesc*epDescSrcAddress*SrcAddressLinkQuality LinkQualitySecurityUse SecurityUseTimestamp timestamp看一下afBuildMSGIncoming()函数/* * fn afBuildMSGIncoming * * brief Build the message for the app * * param * * return pointer to next in data buffer */*/Build the message for the app static void afBuildMSGIncoming( aps_FrameFormat_t *aff, endPointDesc_t *epDesc, zAddrType_t *SrcAddress, uint8 LinkQuality, byte SecurityUse, uint32 timestamp ) afIncomingMSGPacket_t *MSGpkt; /AF层需要接收这种结构体类型的信息包 /下面就通过本函数来为接收到的信息构造这种类型 /信息包,从而可以发送到AF层去 const byte len = sizeof( afIncomingMSGPacket_t ) + aff-asduLength; /长度 byte *asdu = aff-asdu; MSGpkt = (afIncomingMSGPacket_t *)osal_msg_allocate( len ); /分配内存 if ( MSGpkt = NULL ) return; MSGpkt-hdr.event = AF_INCOMING_MSG_CMD; /事件类型 MSGpkt-groupId = aff-GroupID; /组ID MSGpkt-clusterId = aff-ClusterID; /簇ID afCopyAddress( &MSGpkt-srcAddr, SrcAddress ); /源地址 MSGpkt-srcAddr.endPoint = aff-SrcEndPoint; MSGpkt-endPoint = epDesc-endPoint; MSGpkt-wasBroadcast = aff-wasBroadcast; /广播 MSGpkt-LinkQuality = LinkQuality; /链路质量 MSGpkt-SecurityUse = SecurityUse; /安全使能 MSGpkt-timestamp = timestamp; /时间 MSGpkt-cmd.TransSeqNumber = 0; /传送序号 MSGpkt-cmd.DataLength = aff-asduLength; /长度 if ( MSGpkt-cmd.DataLength ) /aff-asduLength MSGpkt-cmd.Data = (byte *)(MSGpkt + 1); /空间 /把长为 MSGpkt-cmd.DataLength数据从asdu赋给MSGpkt-cmd.Data osal_memcpy( MSGpkt-cmd.Data, asdu, MSGpkt-cmd.DataLength ); else /无数据 MSGpkt-cmd.Data = NULL; #if defined ( MT_AF_CB_FUNC ) / If MT has subscribed for this callback, dont send as a message. if AFCB_CHECK(MSGpkt-endPoint, *(epDesc-task_id), SPI_CB_AF_DATA_IND) af_MTCB_IncomingData( (void *)MSGpkt ); / Release the memory. osal_msg_deallocate( (void *)MSGpkt ); else#endif / Send message through task message./数据包构造好后,就要发送到AF层,这里调用osal_msg_send()osal_msg_send( *(epDesc-task_id), (uint8 *)MSGpkt ); /*看下osal_msg_send()函数osal_msg_send( *(epDesc-task_id), (uint8 *)MSGpkt );byte osal_msg_send( byte destination_task, byte *msg_ptr )实参形参*(epDesc-task_id) destination_task(uint8 *)MSGpkt*msg_ptr/* * fn osal_msg_send * * brief * * This function is called by a task to send a command message to * another task or processing element. The sending_task field must * refer to a valid task, since the task ID will be used * for the response message. This function will also set a message * ready event in the destination tasks event list.* * param byte destination task - Send msg to? Task ID 目的任务 * param byte *msg_ptr - pointer to new message buffer 指向消息 * param byte len - length of data in message 消息中的数据长度 * * return ZSUCCESS, INVALID_SENDING_TASK, INVALID_DESTINATION_TASK, * INVALID_MSG_POINTER, INVALID_LEN */*byte osal_msg_send( byte destination_task, byte *msg_ptr )/- if ( msg_ptr = NULL ) /无消息 return ( INVALID_MSG_POINTER );/- if ( destination_task = tasksCnt ) /不在任务条目范围内?任务不合法 osal_msg_deallocate( msg_ptr ); return ( INVALID_TASK ); /- / Check the message header if ( OSAL_MSG_NEXT( msg_ptr ) != NULL | OSAL_MSG_ID( msg_ptr ) != TASK_NO_TASK ) /检查到指针不合法 osal_msg_deallocate( msg_ptr ); /释放这个消息内存 return ( INVALID_MSG_POINTER ); OSAL_MSG_ID( msg_ptr ) = destination_task; /检查到含有合法任务的消息, /则把目的任务的ID赋给消息结构体的dest_id /OSAL_MSG_ID()参见前面 /- / queue message 把当前消息(msg_ptr所指)加入到系统消息列表中 osal_msg_enqueue( &osal_qHead, msg_ptr );/- / Signal the task that a message is waiting osal_set_event( destination_task, SYS_EVENT_MSG ); /设置事件发生标志函数! return ( ZSUCCESS );/*看下osal_set_event()函数osal_set_event( destination_task, SYS_EVENT_MSG )osal_set_event( byte task_id, UINT16 event_flag )实参形参destination_task task_idSYS_EVENT_MSG event_flag/* * fn osal_set_event * * brief * * This function is called to set the event flags for a task. The * event passed in is ORd into the tasks event variable. * * param byte task_id - receiving tasks ID * param byte event_flag - what event to set * * return ZSUCCESS, INVALID_TASK */*/byte osal_set_event( byte task_id, UINT16 event_flag ) if ( task_id hdr.event = AF_INCOMING_MSG_CMD; 因而函数最终调用SampleApp_MessageMSGCB( MSGpkt )进行处理./*uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ) afIncomingMSGPacket_t *MSGpkt; /接收到的消息 /*如果是系统消息*/判断OSAL层的消息类型 if ( events & SYS_EVENT_MSG ) MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID ); /接收属于本用户应用SampleApp的 消息(SampleApp_TaskID来标志) while ( MSGpkt ) /接收到着 /属于这个应用的消息osal_msg_receive( MApp_TaskID ); switch ( MSGpkt-hdr.event ) /判断数据包事件类型 / Received when a key is pressed /*事件:按键事件*/ case KEY_CHANGE: /#define KEY_CHANGE 0xC0 -Key Events SampleApp_HandleKeys( (keyChange_t *)MSGpkt)-state, (keyChange_t *)MSGpkt)-keys ); break; /执行按键处理函数 / Received when a messages is received (OTA:over the air) for this endpoint /*事件:收到信息事件*/ case AF_INCOMING_MSG_CMD: / #define AF_INCOMING_MSG_CMD 0x 1A -Incoming MSG type message SampleApp_MessageMSGCB( MSGpkt ); break; / Received whenever the device changes state in the network /*事件:端点状态变化事件*/ case ZDO_STATE_CHANGE: /#define ZDO_STATE_CHANGE 0xD1 -ZDO has changed the devices network state SampleApp_NwkState = (devStates_t)(MSGpkt-hdr.status); if ( (SampleApp_NwkState = DEV_ZB_COORD) | (SampleApp_NwkState = DEV_ROUTER) | (SampleApp_NwkState = DEV_END_DEVICE) ) / Start sending the periodic message in a regular interval. osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT ); else / Device is no longer in the network break; default: break; / Release the memory /释放消息占用的内存 osal_msg_deallocate( (uint8 *)MSGpkt ); / Next - if one is available MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID ); /end: while ( MSGpkt ) / return unprocessed events / 判断是否有未处理的系统消息,有则接收返回没有处理的事件 return (events SYS_EVENT_MSG); /注意!这里 return到osal_start_system()下 /- / Send a message out - This event is generated by a timer / (setup in SampleApp_Init(). if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT ) /发送周期消息 / Send the periodic message SampleApp_SendPeriodicMessage(); / Setup to send message again in normal period (+ a little jitter) osal_start_timerEx( SampleApp_Tas

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论