本实验基于上一章的按键实验的代码,添加了广播功能,效果是endDevice端按下s1按键后发送一个广播包,coordinator收到包后用串口打印出来;
先来看看发送端endDevice的添加的代码,首先修改发送的目的地址,TestApp.c中的TestApp_Init()函数中定义了目的地址,我们把它改成广播模式:
zstack默认会在网络状态改变的时候添加一个定时器,周期发送数据。我们先将这一段注释,以防干扰。这一段在TestApp.c的TestApp_ProcessEvent()函数中:
找到按键处理函数TestApp_HandleKeys(),在这个函数里面添加按下按键后的处理操作:
void TestApp_HandleKeys( byte shift, byte keys )
{
//stone:add********************/
if( keys & HAL_KEY_SW_6 ) {
if( TestApp_NwkState == DEV_END_DEVICE ) {
static int count = 0;
int len;
char MessageData[20] = "stone ---> ";
len = strlen(MessageData);
MessageData[len] = count / 100 % 10 + '0';
MessageData[len + 1] = count / 10 % 10 + '0';
MessageData[len + 2] = count % 10 + '0';
MessageData[len + 3] = '\r';
MessageData[len + 4] = '\n';
MessageData[len + 5] = '\0';
if( ++count >= 1000 ) {
count = 0;
}
if ( AF_DataRequest( &TestApp_DstAddr, &TestApp_epDesc,
TESTAPP_CLUSTERID,
(byte)osal_strlen( MessageData ) + 1,
(byte *)&MessageData,
&TestApp_TransID,
AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
// Successfully requested to be sent.
}
else
{
// Error occurred in request to send.
}
}
}
//************end***************/
}
这一段代码主要就是每检测到一次按键就发送一条广播包,广播包中带有一个id,id每发一次就加1。这里最重要的就是AF_DataRequest(),是zstack协议栈中的发送数据API,声明如下:
afStatus_t AF_DataRequest( afAddrType_t *dstAddr, //目的地址
endPointDesc_t *srcEP, //端口描述
uint16 cID, //簇ID
uint16 len, //数据长度
uint8 *buf, //数据
uint8 *transID, //任务ID
uint8 options, //发送选项
uint8 radius ) //跳数
其中目的地址TestApp_DstAddr变量已在之前配置为广播模式,发送部分就这些,下面是接收部分。
接收部分
接收部分是一个事件触发模式,当收到一条数据后会触发一个事件,最终会导致TestApp_ProcessEvent()被调用,事件名称为AF_INCOMING_MSG_CMD:
因此,当收到一个数据包后TestApp_MessageMSGCB()会被调用处理这个包,处理的代码就添加在这个函数当中:
void TestApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
switch ( pkt->clusterId )
{
case TESTAPP_CLUSTERID:
HalUARTStr(0, "recv:");
HalUARTStr(0, pkt->cmd.Data);
break;
}
}
因为发送的是字符串,因此这就简单的打印出来即可。从这里可以看出最终的数据存储在pkt->cmd.Data中,而afIncomingMSGPacket_t结构保存了收到的包信息:
typedef struct
{
osal_event_hdr_t hdr; /* OSAL 消息头 */
uint16 groupId; /* 消息组ID */
uint16 clusterId; /* 簇ID */
afAddrType_t srcAddr; /* 源地址类型 */
uint16 macDestAddr; /* 目的地址,mac地址 */
uint8 endPoint; /* 目的endPoint */
uint8 wasBroadcast; /* 如果目的地址是广播则为true */
uint8 LinkQuality; /* 链路质量 */
uint8 correlation; /* The raw correlation value of the received data frame */
int8 rssi; /* 信号强度 */
uint8 SecurityUse; /* deprecated */
uint32 timestamp; /* 接收时间 */
afMSGCommandFormat_t cmd; /* 数据 */
} afIncomingMSGPacket_t;
// Generalized MSG Command Format
typedef struct
{
byte TransSeqNumber;
uint16 DataLength; // Number of bytes in TransData
byte *Data;
} afMSGCommandFormat_t;
实验结果
分别将coordinator与endDevice的代码编译、烧录、上电。多次按下endDevice上的s1按键,可以再coordinator的串口信息上看到如下信息:
显示序列号不连续说明有丢包的现象出现。