广播与单播组建

     Zigbee 网络支持星型,树(簇)型,网状  三个网络拓补结构

功能需求:

     协调器周期性以广播的形式向终端节点发送数据 “I am coordinate”

     加入其网络的终端节点都会收到数据,终端节点分别单播给协调器 “I am endpoint device ”

实现过程:

      复制样本工程

      把串口的相关代码添加

       SampleApp_Init()里将SampleApp_Flash_DstAddr 设置为单播模式,且地址设置为0x000,此地址是协调器的地址

      当网络状态发生改变,触发 SAMPLEAPP_SEND_PERIODIC_MSG_EVT事件,当检测到这个事件时,首先判断设备的逻辑类型:

            协调器则执行 SampleApp_SendPeriodicMessage();

            终端则执行 SampleApp_SendFlashMessage();

 

// SampleApp.c
// 添加头文件

#include "mt_uart.h"
#include "string.h"
// SampleApp.c
void SampleApp_Init(uint8 task_id)
{
    // ...
    MT_UartInit();                                         // 串口初始化
    HalUARTWrite(0, "uart0 is ok ",strlen("uart0 is ok")); // 0端口
    // ...
}

 

// MT_UART.c
void MT_UartInit()
{
    halUARTCfg_t uartConfig;
    
    //...
    uartConfig.baudRate = MT_UART_DEFAULT_BAUDRATE;       // 波特率
    uartConfig.flowControl = MT_UART_DEFAULT_OVERFLOW;    // 流控制
    //...
}

// mt_uart.h

#define    MT_UART_DEFAULT_BAUDRATE    HAL_UART_BR_115200
#define    MT_UART_DEFAULT_OVERFLOW    FALSE                // 关闭

 

// SampleApp.c
// 协调器给终端发送
SampleApp_Periodic_DstAddr.addrMode       = (afAddrMode_t)AddrBroadcast;    //广播模式
SampleApp_Periodic_DstAddr.endPoint       = SAMPLEAPP_ENDPOINT;    
SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF;                   //广播地址

// 终端给协调器发送
SampleApp_Flash_DstAddr.addrMode          = (afAddrMode_t)Addr16Bit;    //单播
SampleApp_Flash_DstAddr.endPoint          = SAMPLEAPP_ENDPOINT;
SampleApp_Flash_DstAddr.addr.shortAddr = 0x0000:                    //协调器地址
// SampleApp.c
// 关闭组播
/*
    SampleApp_Grop.ID = 0x0001;
    osal_memcpy(SampleApp_Group.name, "Group 1", 7);
    aps_AddGroup(SAMPLEAPP_ENDPOINT, &SampleApp_Group);
 */
// SampleApp.c
typedef struct
{
  uint8  event;
  uint8  status;
} osal_event_hdr_t;

typedef struct
{
  osal_event_hdr_t hdr;     /* OSAL Message header */
  uint16 groupId;           /* Message's group ID - 0 if not set */
  uint16 clusterId;         /* Message's cluster ID */
  afAddrType_t srcAddr;     /* Source Address, if endpoint is STUBAPS_INTER_PAN_EP,
                               it's an InterPAN message */
  uint16 macDestAddr;       /* MAC header destination short address */
  uint8 endPoint;           /* destination endpoint */
  uint8 wasBroadcast;       /* TRUE if network destination was a broadcast address */
  uint8 LinkQuality;        /* The link quality of the received data frame */
  uint8 correlation;        /* The raw correlation value of the received data frame */
  int8  rssi;               /* The received RF power in units dBm */
  uint8 SecurityUse;        /* deprecated */
  uint32 timestamp;         /* receipt timestamp from MAC */
  uint8 nwkSeqNum;          /* network header frame sequence number */
  afMSGCommandFormat_t cmd; /* Application Data */
} afIncomingMSGPacket_t;


uint16 SampleApp_ProcessEvent(uint8 task_id,uint16 events)
{
    afIncomingMSGPacket_t *MSGPkt;
    (void)task_id;

    if(events & SYS_EVENT_MSG)    // 检测事件
    {    
        MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive(SampleApp_TaskID);    // 获取信息结构体

        while(MSGpkt)
        {
            switch(MSGpkt -> hdr.event)
            {
                case KEY_CHANGE:
                     SampleApp_HandleKeys(((keyChange_t *)MSGpkt) -> state, 
                                          ((keyChange_t *)MSGpkt) -> keys);
                     break;
                case AF_INCOMING_MSG_CMD:
                     SampleApp_MessageMSGCB(MSGpkt);
                     break;
                case ZDO_STATE_CHANGE:    // 网络状态
                     SampleApp_NwkState = (devStates_t)(MSGpkt -> hdr.status);
            }
            
            osal_msg_deallocate((uint8 *)MSGpkt);
            MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive(SampleApp_TaskID);
        }
        return ();
    }

    if(events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT)
    {
        if(zgDeviceLogicalType == ZG_DEVICETYPE_COORDINATOR)    // 判断协调器
        {
            SampleApp_SendPeriodicMessage();    // 发送数据
        }
        else if(zgDeviceLogicalTyep == ZG_DEVICETYPE_ENDDEVICE)    //判断终端
        {
            SampleApp_SendFlashMessage(0x0000);
        }
        osal_start_timerEx(SampleApp_TaskID,
                           SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
                           (SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + 
                           (osal_read() & 0x00FF)) );
        return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT);
    }
    return 0;
}

 

//SampleApp.c

void SampleApp_SendFlashMessage(uint16 flashTime)    // 终端发送给协调器
{
    uint8 *buffer = "I am endpoint device\n";
    if( AF_DataRequest( &SampleApp_Flash_DstAddr,    // 单步
                        &SampleApp_epDesc,
                        SAMPLEAPP_FLASH_CLUSTERID,    // 命令号
                        strlen(buffer),                // 长度
                        buffer,
                        &SampleApp_TransID,
                        AF_DISCV_ROUTE,
                        AF_DEFAULT_RADIUS) == afStatus_SUCCESS)
    {
        
    }
    else
    {
    }
}

void SampleApp_SendPeriodicMessage(void)    // 协调器
{
    uint8 *buff = "I am coordinator device\n";
    if(AF_DataRequest(&SampleApp_Periodic_DstAddr,
                      &SampleApp_epDesc,
                      SAMPLEAPP_PERIODIC_CLUSTERID,    //命令号
                      strlen(buff),
                      buff,
                      &SampleApp_TransID,
                      AF_DISCV_ROUTE,
                      AF_DEFAULT_RADIUS) == afStatus_SUCCESS)
    {
    }
    else
    {
    }
}

 

// SampleApp.c

void SampleApp_MessageMSGCB(afIncomingMSGPacker_t *pkt)
{
    uint16 flashTime;
    
    switch(pkt -> clusterId)
    {
        //协调器到终端
        case SAMPLEAPP_PFRIODIC_CLUSTERID:
            HalUARTWrite(0 , pkt ->cmd.data , pkt -> cmd.DataLength);    //打印
            break;
        //终端到协调器
        case SAMPLEAPP_FLASH_CLUSTERID:
            HalUARTWrite(0, pkt ->cmd.Data, pkt -> cmd.DataLength);
            break;
    }
}

去除相应的功能模块