組播
組播描述的就是網絡中所有節點設備被分組后組內相互通信的過程。確定通信對象的就是節點的組號。下面我們在 SampleApp 例程完通過簡單的修改完成組播實驗。數據發送和接收的內容按照點播通訊格式。
組播 afAddrType_t 的類型變量
afAddrType_t SampleApp_Flash_DstAddr; //組播
組播內容的結構體
aps_Group_t SampleApp_Group; //分組內容
組播參數的配置。
// Setup for the flash command's destination address - Group 1 SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup; SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP;
將 ID 修改成組號相對應,方便以后自己擴展分組需要
SampleApp_Group.ID = 0x0001; osal_memcpy( SampleApp_Group.name, "Group 1", 7 ); aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group );
在 SampleApp.h 里面可以看到組號為 0x0001
#define SAMPLEAPP_FLASH_GROUP 0x0001
接下來在 SampleAPP.c 最后面添加自己的組播發送函數,代碼如下
void SampleApp_SendPeriodicMessage( void ) { uint8 data[]={'0','1','2','3','4','5','6','7','8','9'};//自定義數據 if ( AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, sizeof(data),//字節數 data,//指針頭 &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS ) { } else { // Error occurred in request to send. } }
添加函數后別忘了在 SampleApp.c 函數聲明里加入:
void SampleApp_SendGroupMessage(void); //組播通訊發送函數定義.
/*SAMPLEAPP_FLASH_CLUSTERID 的定義如下所示:*/
#define SAMPLEAPP_FLASH_CLUSTERID 2
否則編譯將報錯。
再把剛剛點播的發送和接收函數替換為組播的,
void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ) { //uint16 flashTime; switch ( pkt->clusterId ) { case SAMPLEAPP_PERIODIC_CLUSTERID: HalUARTWrite(0,"I get data\n",11);//用於提示有數據 HalUARTWrite(0, &pkt->cmd.Data[0],10); //打印收到數據 HalUARTWrite(0,"\n",1); //回車換行,便於觀察 break; case SAMPLEAPP_FLASH_CLUSTERID: HalUARTWrite(0,"I get data\n",11);//用於提示有數據 HalUARTWrite(0, &pkt->cmd.Data[0],10); //打印收到數據 HalUARTWrite(0,"\n",1); //回車換行,便於觀察 // flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] ); // HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) ); break; } }
將修改后的程序分別以 1 個協調器、 2 個路由器的方式下載到 3 個設備,把協調器和路由器組號 1 設置成 0x0001,路由器設備 2 組號設成 0x0002。 連接串口,可以觀察到只有 0x0001 的兩個設備相互發送信息。
(注意:終端設備不參與組播實驗,)
SampleAPP 例程中終端設備默認采用睡眠中斷的工作方式,射頻不是一直工作,我們可以下載組播例程到終端,發現不能正常接收組播信息。確實需要使用終端設備參與組播可以參考下面方法:
這個在協議規范里面是有規定的,睡眠中斷不接收組播信息,如果一定想要接收的話,只有將終端的接收機一直打開,這樣就可以接收到了。具體做法為:
將 f8config.cfg 配 置 文 件 中 的 -RFD_RCVC_ALWAYS_ON=FALSE 改 為-RFD_RCVC_ALWAYS_ON=TRUE 就可以了!
廣播
廣播就是任何一個節點設備發出廣播數據,網絡中的任何設備都能收到。有了前面點播和組播的實驗基礎,廣播的實驗進行起來就得心應手了。組播的定義都是協議棧預先定義好的。所以直接來運用就可以了。
在協議棧 SampleApp 中找到廣播參數的配置。代碼如下。
SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast; SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF;
0xFFFF 是廣播地址。協議棧廣播地址主要有 3 種類型:
具體的定義如下:
0xFFFF——數據包將被傳送到網絡上的所有設備,
包括睡眠中的設備。對於睡眠中的設備,數據包將被保留在其父親節點直到查詢
到它,或者消息超時。
0xFFFD——數據包將被傳送到網絡上的所有在空閑時
打開接收的設備(RXONWHENIDLE),也就是說,除了睡眠中的所有設備。
0xFFFC——數據包發送給所有的路由器,包括協調器。
我們使用默認的 為0xFFFF,
發送函數代碼:
void SampleApp_SendPeriodicMessage( void ) { uint8 data[10]={'0','1','2','3','4','5','6','7','8','9'};//自定義數據 if ( AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, 10,//字節數 data,//指針頭 &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS ) { } else { // Error occurred in request to send. } }
/*#define SAMPLEAPP_PERIODIC_CLUSTERID 1 //廣播傳輸編號 */
按照原來代碼保留函數SampleApp_SendGroupMessage();這樣的話就能實現周期性廣播播發送數了 。將修改后的程序分別以協調器、路由器、終端的方式下載到 3 個設備,可以看到各個設備都在廣播發送信息,同時也接收廣播信息。