14 在ZStack里的网络广播传输
来源:互联网 发布:linux 卸载 工具 编辑:程序博客网 时间:2024/06/10 17:30
ZStack里的网络传输功能比较像系统上的udp socket编程. 它可以支持广播,组播,及点到点的单播传输方式。
网络传输的功能所用的主要数据类型及函数在工程的”profile/AF.h”里.
typedef enum{ afAddrNotPresent = AddrNotPresent, //表示地址不存在 afAddr16Bit = Addr16Bit, //表示目的地址是一个16位地址 afAddr64Bit = Addr64Bit, //表示目的地址是一个64位地址 afAddrGroup = AddrGroup, //表示目的地址是组播的 afAddrBroadcast = AddrBroadcast //表示目的地址是广播的} afAddrMode_t; //地址模式类型, 相应相当于socket里指定IP地址是IPV4地址还是IPV6地址typedef struct{ union { uint16 shortAddr; //16位地址, 广播地址就是0xffff ZLongAddr_t extAddr; //64位地址 } addr; afAddrMode_t addrMode; //指定使用的地址模式类型 uint8 endPoint; //指定目的端点, 也就是相当于目的端口号 uint16 panId; //由网络层自动设置此成员} afAddrType_t; //地址类型. 不管是要发出广播,组播或单播网络数据都是使用此类型的对象来指定, 其它完全一样。typedef uint16 cId_t;typedef struct{ uint8 EndPoint; //端口号(1 ~ 240) uint16 AppProfId; // app profile id uint16 AppDeviceId; // app device id uint8 AppDevVer:4; // app device version // AppProfId, AppDeviceId, AppDevVer这三项可以随便设置,只要收发两方一致即可 uint8 Reserved:4; // AF_V1_SUPPORT uses for AppFlags:4. // Cluster(簇,群)表示在收发一个endPoint端口号上的数据时再进一步的分类,发出数据时需指定Cluster的值是多少 uint8 AppNumInClusters; //指定本端口号支持多少个输入的Cluster个数. cId_t *pAppInClusterList; //指向支持输入的具体Cluster值的数组首地址 uint8 AppNumOutClusters; //指定本端口支持多少个输出的Cluster个 cId_t *pAppOutClusterList; //指定支持输入的具体Cluster值的数组首地址} SimpleDescriptionFormat_t; //此类型用于描述一个端口号里的具体设置typedef struct{ uint8 endPoint; //使用的端口号 uint8 *task_id; // 指向任务的id SimpleDescriptionFormat_t *simpleDesc; //描述一个端口号里的具体设置 afNetworkLatencyReq_t latencyReq; //收发网络数据后的延时策略,通常设noLatencyReqs} endPointDesc_t; //描述在任务里绑定使用的endPoint端口号的相关配置.---------- extern afStatus_t afRegister( endPointDesc_t *epDesc ); //此函数用于任务里绑定端口号使用,当网络协议本里接收此端口号的数据后,会设置绑定任务里的事件(SYS_EVENT_MSG), 并把接收到的网络数据通过发消息(消息事件类型为AF_INCOMING_MSG_CMD)到任务里。 任务里通过接收消息的方式就可以获取到接收到网络数据了。//发出风络数据的函数 afStatus_t AF_DataRequest( afAddrType_t *dstAddr, endPointDesc_t *srcEP, uint16 cID, uint16 len, uint8 *buf, uint8 *transID, uint8 options, uint8 radius ); // dstAddr指定目的地址及目的端口号, srcEP指定源端口号的配置, cID指定使用具体哪一个Cluster, len表示发出数据长度, buf指向要发出的数据缓冲区, transID用于存放返回的网络数据包的序号, options表示发出时的使用的选项, radius通常设为AF_DEFAULT_RADIUS// options有:#define AF_PREPROCESS 0x04 // Will force APS to callback to preprocess before calling NWK layer#define AF_LIMIT_CONCENTRATOR 0x08#define AF_ACK_REQUEST 0x10#define AF_DISCV_ROUTE 0x20 #define AF_EN_SECURITY 0x40#define AF_SKIP_ROUTING 0x80
//当任务调用afRegister函数绑定端口号后,网络协议栈里接收到此端口号的数据时,会设置任务有SYS_EVENT_MSG事件并把接收的网络数据通过发消息的方式传到任务。 在任务事件处理函数里通过接收消息来获取到接收的网络数据.typedef struct{ osal_event_hdr_t hdr; //hdr的event为 AF_INCOMING_MSG_CMD 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; //cmd里的Data成员指向接收到数据缓冲区首地址, cmd里的DataLength为接收到数据长度.} afIncomingMSGPacket_t; //接收到网络数据的消息类型----------//当网络状态发生变化时(如网络掉线,加入网络等), 网络协议栈会设置任务的SYS_EVENT_MSG事件, 并发出消息到任务里。消息类型为ZDO_STATE_CHANGE. 如: afIncomingMSGPacket_t *MSGpkt; MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive(mytask_id); if (MSGpkt->hdr.event == ZDO_STATE_CHANGE) { int status = (devStates_t)(MSGpkt->hdr.status); }----------//状态有typedef enum{ DEV_HOLD, // Initialized - not started automatically DEV_INIT, // Initialized - not connected to anything DEV_NWK_DISC, // Discovering PAN's to join DEV_NWK_JOINING, // Joining a PAN DEV_NWK_REJOIN, // ReJoining a PAN, only for end devices DEV_END_DEVICE_UNAUTH, // Joined but not yet authenticated by trust center DEV_END_DEVICE, // Started as device after authentication DEV_ROUTER, // Device joined, authenticated and is a router DEV_COORD_STARTING, // Started as Zigbee Coordinator DEV_ZB_COORD, // Started as Zigbee Coordinator DEV_NWK_ORPHAN // Device has lost information about its parent..} devStates_t;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
实现定时网络广播功能的代码:
MyApp.h
#ifndef __MYAPP_H#define __MYAPP_H#include "hal_key.h"#include "OnBoard.h"#include "MT_UART.h"#include "AF.h"#define TIME_OUT 0x0010 //time out event;extern void MyApp_Init(uint8 task_id );extern uint16 MyApp_ProcessEvent(uint8 task_id, uint16 event );extern void Handle_keys(keyChange_t * key_evt);extern void Handle_uart(mtOSALSerialData_t *pmsg);extern void myprintf(char *str);extern void Handle_status(uint8 status);extern void Handle_msg( afIncomingMSGPacket_t *pkt );#endif
MyApp.c
#include "hal_led.h"#include "hal_key.h"#include "MyApp.h"#include "OnBoard.h"#include "AF.h"#include "MT_UART.h"#include "hal_key.h"#include "hal_uart.h"#include "MT.h"#include <stdio.h>#include <string.h>#include "ZDApp.h"#include "AF.h"uint8 mytask_id; //用于记录任务号uint8 transId;#define TIMER_LEN 5000 // 5s#define MYPOINT 20#define ARRAY_SIZE(a) ((sizeof(a))/sizeof(a[0]))#define CID_BCAST 1#define CID_GROUP 2afAddrType_t Bcast_addr;endPointDesc_t mypoint_desc;cId_t cids[] = { CID_BCAST, CID_GROUP,};const SimpleDescriptionFormat_t simpleDesc = { MYPOINT, 0x1234, //AppProfId 0x0001, //AppDeviceId 0, 0, ARRAY_SIZE(cids), cids, ARRAY_SIZE(cids), cids, };void MyApp_Init(uint8 task_id ){ mytask_id = task_id; // transId = 0;// HalLedSet(HAL_LED_ALL, HAL_LED_MODE_TOGGLE); RegisterForKeys(mytask_id); MT_UartRegisterTaskID(mytask_id); // Bcast_addr 初始化,用于指定发出是广播用 Bcast_addr.addrMode = (afAddrMode_t)AddrBroadcast; Bcast_addr.addr.shortAddr = 0xffff; Bcast_addr.endPoint = MYPOINT; mypoint_desc.endPoint = MYPOINT; mypoint_desc.task_id = &mytask_id; mypoint_desc.simpleDesc = (SimpleDescriptionFormat_t *)&simpleDesc; mypoint_desc.latencyReq = noLatencyReqs; afRegister(&mypoint_desc); osal_start_timerEx(mytask_id, TIME_OUT, TIMER_LEN); }void Handle_keys(keyChange_t * key_evt){ if (key_evt->keys & HAL_KEY_SW_1) { HalLedSet(HAL_LED_1, HAL_LED_MODE_TOGGLE); HalUARTWrite(0, "s1\n\r", 4); } if (key_evt->keys & HAL_KEY_SW_2) { HalLedSet(HAL_LED_2, HAL_LED_MODE_TOGGLE); HalUARTWrite(0, "s2\n\r", 4); }}void myprintf(char *str){ HalUARTWrite(0, str, strlen(str)); }void Handle_uart(mtOSALSerialData_t *pmsg){ uint8 len = pmsg->msg[0]; HalUARTWrite(0, &(pmsg->msg[1]), len);}void Handle_status(uint8 status){ switch(status) { case DEV_ZB_COORD: myprintf("work as coordinator\n\r"); break; case DEV_END_DEVICE: myprintf("work as end_device\n\r"); break; }}void Handle_msg( afIncomingMSGPacket_t *pkt ){ HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength); //接收到网络数据后,通过uart输出}uint16 MyApp_ProcessEvent(uint8 task_id, uint16 events ){ afIncomingMSGPacket_t *MSGpkt; if ( events & SYS_EVENT_MSG ) //系统消息的处理, 也就是调用osal_msg_send产生的事件 { //接收系统消息 MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive(mytask_id); while ( MSGpkt ) { if (MSGpkt->hdr.event == KEY_CHANGE) //按键事件处理 Handle_keys((keyChange_t *)MSGpkt); if (MSGpkt->hdr.event == CMD_SERIAL_MSG) //串口事件处理 Handle_uart((mtOSALSerialData_t*)MSGpkt); if (MSGpkt->hdr.event == AF_INCOMING_MSG_CMD) // zigbee网络数据的接收事件处理 Handle_msg(MSGpkt); if (MSGpkt->hdr.event == ZDO_STATE_CHANGE) //zigbee网络状态事件处理 Handle_status(MSGpkt->hdr.status); osal_msg_deallocate( (uint8 *)MSGpkt ); // free MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive(mytask_id); } return events ^ SYS_EVENT_MSG; } if (events & TIME_OUT) { //定时发出网络广播数据 static int num = 0; char buf[30]; sprintf(buf, "bcast: %d\n\r", num++); if (AF_DataRequest(&Bcast_addr, &mypoint_desc, CID_BCAST, strlen(buf), buf, &transId, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS) != afStatus_SUCCESS) { myprintf("send failed\n\r"); } osal_start_timerEx(mytask_id, TIME_OUT, TIMER_LEN); } return 0;}
阅读全文
0 0
- 14 在ZStack里的网络广播传输
- 09 在ZStack里的定时器应用
- 10 在ZStack里的按键驱动
- 07 在ZStack里创建自己的task
- 08 在ZStack里的led灯控制
- 11 在ZStack里实现uart数据输出功能
- 12 在ZStack里实现uart数据接收功能
- 13 在ZStack里设置pan ID和信号输出功率
- 在Widget里获取系统时间改变的广播
- inet_aton与INADDR_ANY在广播里的应用
- 在广播接收器里启动活动的注意事项
- android 在url里传输汉字的方法
- 在联网时候小米手机收到无网络的广播
- 一个简单的在本地传输文件的网络程序
- 在service代码里实现广播接收者
- JMF+广播协议实现广播视频的传输中的问题
- linux下网络编程3:UDP广播传输文件
- 图像在网络中的传输
- java杂记1
- angular2——前后端交互
- Jsoup学习
- KMP题目分析与总结
- 计蒜客NOIP提高组模拟Day2,Pro1蒜头君的兔子
- 14 在ZStack里的网络广播传输
- javase复习(四)--Arrays.asList()方法的使用
- LeetCode
- 推挽输出、开漏输出、线或、线与、竞争、冒险、毛刺【基本概念】
- python2.7安装mysql的数据驱动
- find与逻辑关系运算
- Event事件对象之动画事件和过渡事件
- 如何自己设计一个高效类似于HashMap的容器
- CSU1561 (More) Multiplication