Z-Stack协议栈学习笔记4---广播

      本实验基于上一章的按键实验的代码,添加了广播功能,效果是endDevice端按下s1按键后发送一个广播包,coordinator收到包后用串口打印出来;

      先来看看发送端endDevice的添加的代码,首先修改发送的目的地址,TestApp.c中的TestApp_Init()函数中定义了目的地址,我们把它改成广播模式:

Z-Stack协议栈学习笔记4---广播_第1张图片

     zstack默认会在网络状态改变的时候添加一个定时器,周期发送数据。我们先将这一段注释,以防干扰。这一段在TestApp.c的TestApp_ProcessEvent()函数中:

Z-Stack协议栈学习笔记4---广播_第2张图片

     找到按键处理函数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:

Z-Stack协议栈学习笔记4---广播_第3张图片

因此,当收到一个数据包后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的串口信息上看到如下信息:

Z-Stack协议栈学习笔记4---广播_第4张图片

显示序列号不连续说明有丢包的现象出现。

你可能感兴趣的:(zigbee,Z-Stack,zstack,zigbee,cc2530,广播,发送)