本实验基于上一章的广播实验的代码,添加了组播功能,效果是endDevice端按下s1按键后发送一个组播包,coordinator收到包后用串口打印出来。下面的代码分为初始化、发送、接收三个部分;
初始化网络:
在TestApp.c的TestApp_Init()中初始化变量TestApp_DstAddr与TestApp_Group,前者是发送时需要的目的地址,后者是加入的组号:
这里将TestApp_DstAddr配置为组播模式,组号为0x0001。后面的代码是加入组播号为1的组播网络,这表示这个节点将接收来自组播号为1的网络的数据包。这里我们需要定义变量TestApp_Group,并加上组播相关头文件:
接收数据部分:
节点加入某个组播网络后会接收此网络的数据包,一旦接收到就会触发一个事件,这个事件会在TestApp_ProcessEvent的AF_INCOMING_MSG_CMD中被处理,即调用函数TestApp_MessageMSGCB()处理:
处理数据包的相关操作就写在这个函数中,这里就是简单使用串口打印出来:
发送数据部分:
实现目的是每按下一次按键s1发送一条组播包,但发送需要再联网成功之后,因此这里需要一个标志位networkState,如果组网成功就置1,在按键处理端只有当此标志位置1后才会发送数据:
定义全局变量networkState
在组网成功后置位此标志位
组网成功后,每次按下按键都会发送一次组播报,按键处理流程如下:
void TestApp_HandleKeys( byte shift, byte keys )
{
static int count = 0;
//stone:add********************/
if( keys & HAL_KEY_SW_6 ) {
if ( networkState == 1 ) {
char str[20] = "send data ---> ";
str[15] = count / 100 % 10 + '0';
str[16] = count / 10 % 10 + '0';
str[17] = count % 10 + '0';
str[18] = '\0';
if( ++count >= 1000 ) count = 0;
//·¢ËÍÊý¾Ý
if ( AF_DataRequest( &TestApp_DstAddr, &TestApp_epDesc,
TESTAPP_CLUSTERID,
(byte)osal_strlen( str ) + 1,
(byte *)&str,
&TestApp_TransID,
AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
// Successfully requested to be sent.
}
else
{
// Error occurred in request to send.
}
}
}
//************end***************/
}
这里的目的地址TestApp_DstAddr就是最开始初始化成组播模式的变量。
实验:
上电coordinator与endDevice,待coordinator串口出现network state change后表示自动组网成功。按下endDevice的s1按键可在coordinator的串口上看到接收到的数据:
尝试更改coordinator或endDevice的组号,如果二者的组号不相同则无法正确通信。