广播与单播组建
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;
}
}
去除相应的功能模块