ZigBee开发(16)--组网实验组播广播

组播

组播描述的就是网络中所有节点设备被分组后组内相互通信的过程。确定通信对象的就是节点的组号。下面我们在 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 个设备,可以看到各个设备都在广播发送信息,同时也接收广播信息。