數據的發送和接收
一、 數據的發送 在ZStack2006的協議棧中,我們只需調用函數AF_DataRequest()即可完成數據的發送。 afStatus_t AF_DataRequest( afAddrType_t *dstAddr, endPointDesc_t *srcEP, uint16 cID, uint16 len, uint8 *buf, uint8 *transID, uint8 options, uint8 radius ) 而我們在使用AF_DataRequest() 函數時只需要了解其參數便可以非常靈活的以各種方式來發送數據。AF_DataRequest()函數參數說明如下: *dstAddr---------------------發送目的地址、端點地址以及傳送模式 *srcEP -----------------------源端點 cID ---------------------------簇ID len ---------------------------數據長度 *buf -------------------------數據 *transID --------------------序列號 options ----------------------發送選項 radius -----------------------跳數 *dstAddr決定了消息發送到那個設備及那個endpoint,而簇ID(cID)決定了設備接收到信息如何處理。簇可以理解為是一種約定,約定了信息怎么處理。 重要參數說明: 1、地址 afAddrType_t typedef struct { union { uint16 shortAddr; //短地址 }addr; afAddrMode_taddrMode; //傳送模式 byteendPoint; //端點號 }afAddrType_t; 2、端點描述符 endPointDesc_t typedef struct { byteendPoint; //端點號 byte*task_id; //那一個任務的端點號 SimpleDescriptionFormat_t*simpleDesc;//簡單的端點描述 afNetworkLatencyReq_tlatencyReq; }endPointDesc_t; 3、簡單描述符 SimpleDescriptionFormat_t typedef struct { byte EndPoint; //EP uint16 AppProfId; //應用規范ID uint16 AppDeviceId; //特定規范ID 的設備類型 byte AppDevVer:4; //特定規范ID 的設備的版本 byte Reserved:4; //AF_V1_SUPPORTusesforAppFlags:4. byte AppNumInClusters; //輸入簇ID 的個數 cId_t *pAppInClusterList; //輸入簇ID 的列表 byte AppNumOutClusters; //輸出簇ID 的個數 cId_t *pAppOutClusterList; //輸出簇ID 的列表 }SimpleDescriptionFormat_t; 4、簇ID cID ClusterID--具體應用串ID 5、發送選項 options 發送選項有如下選項 #defineAF_FRAGMENTED 0x01 #defineAF_ACK_REQUEST 0x10 #defineAF_DISCV_ROUTE 0x20 #defineAF_EN_SECURITY 0x40 #defineAF_SKIP_ROUTING 0x80 其中AF_ACK_REQUEST為發送后需要接收方的確認 6、半徑、條數 radius 傳輸跳數或傳輸半徑,默認值為10 數據發送模式說明:在協議棧數據發送模式有以下幾種:單播、組播、廣播和直接發送四種模式。 廣播發送 廣播發送可以分為三種,如果想使用廣播發送,則只需將dstAddr->addrMode設為 AddrBroadcast,dstAddr->addr->shortAddr設置為相應的廣播類型即可。具體的定義如下: NWK_BROADCAST_SHORTADDR_DEVALL(0xFFFF)——數據包將被傳送到網絡上的所有設備,包括睡眠中的設備。對于睡眠中的設備,數據包將被保留在其父親節點直到查詢到它,或者消息超時。 NWK_BROADCAST_SHORTADDR_DEVRXON(0xFFFD)——數據包將被傳送到網絡上的所有接收機的設備(RXONWHENIDLE),也就是說,除了睡眠中的所有設備。 NWK_BROADCAST_SHORTADDR_DEVZCZR(0xFFFC)——數據包發送給所有的路由器,包括協調器。 組播發送 如果設備想傳輸數據到某一組設備,那么只需將dstAddr->addrMode設為AddrGroup, dstAddr->addr->shortAddr設置為相應的組ID 即可。 代碼如下: //Setupfortheflash command's destinationaddress-Group1 SampleApp_Flash_DstAddr.addrMode=(afAddrMode_t)afAddrGroup; SampleApp_Flash_DstAddr.endPoint=SAMPLEAPP_ENDPOINT; SampleApp_Flash_DstAddr.addr.shortAddr=SAMPLEAPP_FLASH_GROUP; 根據上面代碼的配置,然后使用AF_DataRequest()函數來進行組播發送。 單播發送 單播發送需要知道目標設備的短地址,需要將 dstAddr-> addrMode 設為Addr16Bit,dstAddr->addr->shortAddr設置為目標設備的短地址即可。 代碼如下: SampleApp_Flash_DstAddr.addrMode=(afAddrMode_t)afAddr16Bit; SampleApp_Flash_DstAddr.endPoint=SAMPLEAPP_ENDPOINT; SampleApp_Flash_DstAddr.addr.shortAddr=0x00; 根據上面代碼的配置,然后使用AF_DataRequest()函數來進行點對點發送。 綁定發送 綁定發送目標設備可以是一個設備、多個設備、或者一組設備,由綁定表中的綁定信息決定。綁定發送,需要將dstAddr->addrMode設為AddrNotPresent,dstAddr->addr->shortAddr設置為無效地址0xFFFE。 代碼如下: ZDAppNwkAddr.addrMode = AddrNotPresent; ZDAppNwkAddr.addr.shortAddr = 0xFFFE; 根據上面代碼的配置,然后使用AF_DataRequest()函數來進行綁定發送。 二、 數據的接受 在Zstack中,如當接收到OTA信息后,將觸發SYS_EVENT_MSG事件下的AF_INCOMING_MSG_CMD事件。我們只需處理AF_INCOMING_MSG_CMD便可。 數據收發實例: 在SampleApp工程中Zstack要周期性的向網絡所有設備廣發送一個信息,其具體代碼如下: 程序代碼: void SampleApp_SendPeriodicMessage( void ) { if ( AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, 1, (uint8*)&SampleAppPeriodicCounter, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS ) { } else { // Error occurred in request to send. } } 在這個函數中調用了函數AF_DataRequest()完成數據的發送,發送地址為SampleApp_Periodic_DstAddr,即SampleApp周期信息地址,該地址為0xFFFF,具體參見SampleApp。而簇ID為SAMPLEAPP_PERIODIC_CLUSTERID。 在接受端觸發了目標設備的AF_INCOMING_MSG_CMD事件。具體程序代碼如下: 程序代碼: uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ) { …… case AF_INCOMING_MSG_CMD: SampleApp_MessageMSGCB( MSGpkt ) break; …… } 在對事件AF_INCOMING_MSG_CMD進行處理時,Zstack又調用了函數SampleApp_MessageMSGCB( MSGpkt ),其代碼如下: 程序代碼: void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ) { uint16 flashTime; switch ( pkt->clusterId ) { case SAMPLEAPP_PERIODIC_CLUSTERID: break; case SAMPLEAPP_FLASH_CLUSTERID: flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] ); HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) ); break; } } 在函數SampleApp_MessageMSGCB( MSGpkt )中會根據接收到信息的簇ID的不同,進行相關的處理,也就是上面提及的簇是一種約定,約定了信息將如何處理。這個實例中Zstack對周期信息的處理就是什么都沒有做,可以根據實際需要用戶自己添加相關代碼。 說明:在Zstack協議棧中數據的發送函數為AF_DataRequest(),但是在SimpleApp實例中,Zstack調用了函數zb_SendDataRequest ()進行數據的發送,其實在函數zb_SendDataRequest ()中最終還是調用了AF_DataRequest()對數據進行的發送。
|