數(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 ) 而我們在使用AF_DataRequest() 函數(shù)時只需要了解其參數(shù)便可以非常靈活的以各種方式來發(fā)送數(shù)據(jù)。AF_DataRequest()函數(shù)參數(shù)說明如下: *dstAddr---------------------發(fā)送目的地址、端點地址以及傳送模式 *srcEP -----------------------源端點 cID ---------------------------簇ID len ---------------------------數(shù)據(jù)長度 *buf -------------------------數(shù)據(jù) *transID --------------------序列號 options ----------------------發(fā)送選項 radius -----------------------跳數(shù) *dstAddr決定了消息發(fā)送到那個設(shè)備及那個endpoint,而簇ID(cID)決定了設(shè)備接收到信息如何處理。簇可以理解為是一種約定,約定了信息怎么處理。 重要參數(shù)說明: 1、地址 afAddrType_t typedef struct { union { uint16 shortAddr; //短地址 }addr; afAddrMode_taddrMode; //傳送模式 byteendPoint; //端點號 }afAddrType_t; 2、端點描述符 endPointDesc_t typedef struct { byteendPoint; //端點號 byte*task_id; //那一個任務(wù)的端點號 SimpleDescriptionFormat_t*simpleDesc;//簡單的端點描述 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 的個數(shù) cId_t *pAppInClusterList; //輸入簇ID 的列表 byte AppNumOutClusters; //輸出簇ID 的個數(shù) cId_t *pAppOutClusterList; //輸出簇ID 的列表 }SimpleDescriptionFormat_t; 4、簇ID cID ClusterID--具體應(yīng)用串ID 5、發(fā)送選項 options 發(fā)送選項有如下選項 #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è)備。對于睡眠中的設(shè)備,數(shù)據(jù)包將被保留在其父親節(jié)點直到查詢到它,或者消息超時。 NWK_BROADCAST_SHORTADDR_DEVRXON(0xFFFD)——數(shù)據(jù)包將被傳送到網(wǎng)絡(luò)上的所有接收機的設(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)行點對點發(fā)送。 綁定發(fā)送 綁定發(fā)送目標(biāo)設(shè)備可以是一個設(shè)備、多個設(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ā)實例: 在SampleApp工程中Zstack要周期性的向網(wǎng)絡(luò)所有設(shè)備廣發(fā)送一個信息,其具體代碼如下: 程序代碼: 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. } } 在這個函數(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; …… } 在對事件AF_INCOMING_MSG_CMD進(jìn)行處理時,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 )中會根據(jù)接收到信息的簇ID的不同,進(jìn)行相關(guān)的處理,也就是上面提及的簇是一種約定,約定了信息將如何處理。這個實例中Zstack對周期信息的處理就是什么都沒有做,可以根據(jù)實際需要用戶自己添加相關(guān)代碼。 說明:在Zstack協(xié)議棧中數(shù)據(jù)的發(fā)送函數(shù)為AF_DataRequest(),但是在SimpleApp實例中,Zstack調(diào)用了函數(shù)zb_SendDataRequest ()進(jìn)行數(shù)據(jù)的發(fā)送,其實在函數(shù)zb_SendDataRequest ()中最終還是調(diào)用了AF_DataRequest()對數(shù)據(jù)進(jìn)行的發(fā)送。
|