數(shù)據(jù)的發(fā)送和接收
一、 數(shù)據(jù)的發(fā)送 在ZStack2006的協(xié)議棧中,我們只需調(diào)用函數(shù)AF_DataRequest()即可完成數(shù)據(jù)的發(fā)送。 afStatus_t AF_DataRequest( afAddrType_t *dstAddr, endPointDesc_t *srcEP, uint16 cID, uint16 len, uint8 *buf, uint8 *transID, uint8 options, uint8 radius ) 而我們?cè)谑褂?font face="Times New Roman">AF_DataRequest() 函數(shù)時(shí)只需要了解其參數(shù)便可以非常靈活的以各種方式來發(fā)送數(shù)據(jù)。AF_DataRequest()函數(shù)參數(shù)說明如下: *dstAddr---------------------發(fā)送目的地址、端點(diǎn)地址以及傳送模式 *srcEP -----------------------源端點(diǎn) cID ---------------------------簇ID len ---------------------------數(shù)據(jù)長度 *buf -------------------------數(shù)據(jù) *transID --------------------序列號(hào) options ----------------------發(fā)送選項(xiàng) radius -----------------------跳數(shù) *dstAddr決定了消息發(fā)送到那個(gè)設(shè)備及那個(gè)endpoint,而簇ID(cID)決定了設(shè)備接收到信息如何處理。簇可以理解為是一種約定,約定了信息怎么處理。 重要參數(shù)說明: 1、地址 afAddrType_t typedef struct { union { uint16 shortAddr; //短地址 }addr; afAddrMode_taddrMode; //傳送模式 byteendPoint; //端點(diǎn)號(hào) }afAddrType_t; 2、端點(diǎn)描述符 endPointDesc_t typedef struct { byteendPoint; //端點(diǎn)號(hào) byte*task_id; //那一個(gè)任務(wù)的端點(diǎn)號(hào) SimpleDescriptionFormat_t*simpleDesc;//簡單的端點(diǎn)描述 afNetworkLatencyReq_tlatencyReq; }endPointDesc_t; 3、簡單描述符 SimpleDescriptionFormat_t typedef struct { byte EndPoint; //EP uint16 AppProfId; //應(yīng)用規(guī)范ID uint16 AppDeviceId; //特定規(guī)范ID 的設(shè)備類型 byte AppDevVer:4; //特定規(guī)范ID 的設(shè)備的版本 byte Reserved:4; //AF_V1_SUPPORTusesforAppFlags:4. byte AppNumInClusters; //輸入簇ID 的個(gè)數(shù) cId_t *pAppInClusterList; //輸入簇ID 的列表 byte AppNumOutClusters; //輸出簇ID 的個(gè)數(shù) cId_t *pAppOutClusterList; //輸出簇ID 的列表 }SimpleDescriptionFormat_t; 4、簇ID cID ClusterID--具體應(yīng)用串ID 5、發(fā)送選項(xiàng) options 發(fā)送選項(xiàng)有如下選項(xiàng) #defineAF_FRAGMENTED 0x01 #defineAF_ACK_REQUEST 0x10 #defineAF_DISCV_ROUTE 0x20 #defineAF_EN_SECURITY 0x40 #defineAF_SKIP_ROUTING 0x80 其中AF_ACK_REQUEST為發(fā)送后需要接收方的確認(rèn) 6、半徑、條數(shù) radius 傳輸跳數(shù)或傳輸半徑,默認(rèn)值為10 數(shù)據(jù)發(fā)送模式說明:在協(xié)議棧數(shù)據(jù)發(fā)送模式有以下幾種:單播、組播、廣播和直接發(fā)送四種模式。 廣播發(fā)送 廣播發(fā)送可以分為三種,如果想使用廣播發(fā)送,則只需將dstAddr->addrMode設(shè)為 AddrBroadcast,dstAddr->addr->shortAddr設(shè)置為相應(yīng)的廣播類型即可。具體的定義如下: NWK_BROADCAST_SHORTADDR_DEVALL(0xFFFF)——數(shù)據(jù)包將被傳送到網(wǎng)絡(luò)上的所有設(shè)備,包括睡眠中的設(shè)備。對(duì)于睡眠中的設(shè)備,數(shù)據(jù)包將被保留在其父親節(jié)點(diǎn)直到查詢到它,或者消息超時(shí)。 NWK_BROADCAST_SHORTADDR_DEVRXON(0xFFFD)——數(shù)據(jù)包將被傳送到網(wǎng)絡(luò)上的所有接收機(jī)的設(shè)備(RXONWHENIDLE),也就是說,除了睡眠中的所有設(shè)備。 NWK_BROADCAST_SHORTADDR_DEVZCZR(0xFFFC)——數(shù)據(jù)包發(fā)送給所有的路由器,包括協(xié)調(diào)器。 組播發(fā)送 如果設(shè)備想傳輸數(shù)據(jù)到某一組設(shè)備,那么只需將dstAddr->addrMode設(shè)為AddrGroup, dstAddr->addr->shortAddr設(shè)置為相應(yīng)的組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; 根據(jù)上面代碼的配置,然后使用AF_DataRequest()函數(shù)來進(jìn)行組播發(fā)送。 單播發(fā)送 單播發(fā)送需要知道目標(biāo)設(shè)備的短地址,需要將 dstAddr-> addrMode 設(shè)為Addr16Bit,dstAddr->addr->shortAddr設(shè)置為目標(biāo)設(shè)備的短地址即可。 代碼如下: SampleApp_Flash_DstAddr.addrMode=(afAddrMode_t)afAddr16Bit; SampleApp_Flash_DstAddr.endPoint=SAMPLEAPP_ENDPOINT; SampleApp_Flash_DstAddr.addr.shortAddr=0x00; 根據(jù)上面代碼的配置,然后使用AF_DataRequest()函數(shù)來進(jìn)行點(diǎn)對(duì)點(diǎn)發(fā)送。 綁定發(fā)送 綁定發(fā)送目標(biāo)設(shè)備可以是一個(gè)設(shè)備、多個(gè)設(shè)備、或者一組設(shè)備,由綁定表中的綁定信息決定。綁定發(fā)送,需要將dstAddr->addrMode設(shè)為AddrNotPresent,dstAddr->addr->shortAddr設(shè)置為無效地址0xFFFE。 代碼如下: ZDAppNwkAddr.addrMode = AddrNotPresent; ZDAppNwkAddr.addr.shortAddr = 0xFFFE; 根據(jù)上面代碼的配置,然后使用AF_DataRequest()函數(shù)來進(jìn)行綁定發(fā)送。 二、 數(shù)據(jù)的接受 在Zstack中,如當(dāng)接收到OTA信息后,將觸發(fā)SYS_EVENT_MSG事件下的AF_INCOMING_MSG_CMD事件。我們只需處理AF_INCOMING_MSG_CMD便可。 數(shù)據(jù)收發(fā)實(shí)例: 在SampleApp工程中Zstack要周期性的向網(wǎng)絡(luò)所有設(shè)備廣發(fā)送一個(gè)信息,其具體代碼如下: 程序代碼: 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. } } 在這個(gè)函數(shù)中調(diào)用了函數(shù)AF_DataRequest()完成數(shù)據(jù)的發(fā)送,發(fā)送地址為SampleApp_Periodic_DstAddr,即SampleApp周期信息地址,該地址為0xFFFF,具體參見SampleApp。而簇ID為SAMPLEAPP_PERIODIC_CLUSTERID。 在接受端觸發(fā)了目標(biāo)設(shè)備的AF_INCOMING_MSG_CMD事件。具體程序代碼如下: 程序代碼: uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ) { …… case AF_INCOMING_MSG_CMD: SampleApp_MessageMSGCB( MSGpkt ) break; …… } 在對(duì)事件AF_INCOMING_MSG_CMD進(jìn)行處理時(shí),Zstack又調(diào)用了函數(shù)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; } } 在函數(shù)SampleApp_MessageMSGCB( MSGpkt )中會(huì)根據(jù)接收到信息的簇ID的不同,進(jìn)行相關(guān)的處理,也就是上面提及的簇是一種約定,約定了信息將如何處理。這個(gè)實(shí)例中Zstack對(duì)周期信息的處理就是什么都沒有做,可以根據(jù)實(shí)際需要用戶自己添加相關(guān)代碼。 說明:在Zstack協(xié)議棧中數(shù)據(jù)的發(fā)送函數(shù)為AF_DataRequest(),但是在SimpleApp實(shí)例中,Zstack調(diào)用了函數(shù)zb_SendDataRequest ()進(jìn)行數(shù)據(jù)的發(fā)送,其實(shí)在函數(shù)zb_SendDataRequest ()中最終還是調(diào)用了AF_DataRequest()對(duì)數(shù)據(jù)進(jìn)行的發(fā)送。
|