组播
组播描述的就是网络中所有节点设备被分组后组内相互通信的过程。确定通信对象的就是节点的组号。下面我们在 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 ",11);//用于提示有数据 HalUARTWrite(0, &pkt->cmd.Data[0],10); //打印收到数据 HalUARTWrite(0," ",1); //回车换行,便于观察 break; case SAMPLEAPP_FLASH_CLUSTERID: HalUARTWrite(0,"I get data ",11);//用于提示有数据 HalUARTWrite(0, &pkt->cmd.Data[0],10); //打印收到数据 HalUARTWrite(0," ",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 个设备,可以看到各个设备都在广播发送信息,同时也接收广播信息。