ZigBee学习——基于AF的数据通信

文章目录

  • 一、简单描述符
    • 1.1 简单介绍
    • 1.2 简单描述结构体介绍
    • 1.3 结构体中的簇
    • 1.4 应用场景
  • 二、AF通信原理
    • 2.1 通信过程
    • 2.2 端点号分类
    • 2.3 通信方式
    • 2.4 注册简单描述符
  • 三、数据发送API简介
    • 3.1 AF层数据发送API
    • 3.2 基于AF层封装的通信API
      • 3.2.1 点对点通信API
      • 3.2.2 广播通信API
      • 3.2.3 组播通信API
  • 四、实战

一、简单描述符

1.1 简单介绍

  在ZigBee中,简单描述符(Simple Descriptor)是一种数据结构,它提供了关于某个设备的端点(EndPoint)的基本信息。简单描述符包括端点的ID,设备的类型,以及设备支持的簇(Cluster)。
  如果设备是一个智能灯泡,那么它可能有一个简单描述符,其中的设备类型就是"智能灯泡",支持的簇可能包括"开关控制",“亮度控制"等等。这样,当其他设备(比如一个开关或者调光器)想与这个智能灯泡交互时,就可以通过查看这个简单描述符来了解该设备的功能以及如何与其交互。
  比如说,一个智能开关在连接一个智能灯泡时,它可以查看灯泡的简单描述符,发现这个灯泡支持"开关控制"和"亮度控制”,那么,这个开关就知道它可以通过发送特定的信号来控制灯泡的开关和亮度。
  所以,可以说简单描述符在ZigBee网络中起到了"设备说明书"的作用,它描述了设备的功能以及设备之间如何交互,帮助设备之间的正常通信。

1.2 简单描述结构体介绍

  简单描述符结构体

typedef struct{
uint8    EndPoint;//端点号
uint16   AppProfId;//描述所在应用场景,例如家居自动化
uint16   AppDeviceId;//设备ID
uint8    AppDevVer:4;//由开发者自定义,表示版本号
uint8    Reserved:4;//保留字段
uint8    AppNumInClusters;//端点支持的输入簇个数
cId_t    *pAppInClusterList;//指向输入簇列表的指针
uint8    AppNumOutClusters;//端点支持的输出簇个数
cId_t    *pAppOutClusterList;//指向输出簇列表的指针
}SimpleDescriptionFormat_t;
  • 端点号:EndPoint,可以理解为简单描述符的编号,取值范围是0~255。在同一个ZigBee设备中,每一个简单描述符都有一个不同的端点号,可以利用端点号来找到对应的简单描述符。
  • AppProfId:Profile ID,表示这个简单描述符所属的应用场景。这个应用场景可以是家居自动化、智能照明和智慧零售等。ZigBee联盟为不同的场景定义了对应的ID值,称为Profile ID。
  • AppDeviceId:Device ID,表示这个简单描述符所属的设备类型。这个设备类型可以是插座、灯或者传感器等。类似地,ZigBee联盟为不同类型的设备定义了对应的ID值,称为Device ID。
  • AppDevVer:这个值可以由开发者自定义,用来表示版本号。
    Reserved:保留字段,暂时可以忽略。
  • Cluster:簇,或者集群,可以划分为输入簇(In Cluseter)和输出簇(Out Cluster),用来描述这个服务的具体内容。一个简单描述符中可以包含多个Cluster,这些Cluster共同描述了这个服务的具体内容,后续章节将会详细讲解。

1.3 结构体中的簇

  在ZigBee中,"簇"或"集群"是指一组基于某种特定功能组合在一起的设备。这些设备能够按照固定规则进行交互或执行特定任务。
  比如,我们可以把灯泡、开关和调光器看作一个“簇”。开关负责控制灯泡的开启或关闭,调光器则可以调节灯泡的亮度。它们三个围绕着"控制照明"这个功能组成了一个簇。
  在这个簇中,当你使用开关,开关会发送一个信号给灯泡,告诉它要开或者关。如果你用调光器,调光器会发送一个信号给灯泡,告诉它调到什么样的亮度。这就是开关、调光器和灯泡在这个“簇”中的交互方式。
所以,通过设置簇,我们可以更好地将相关设备组织在一起,更有效地实现环境控制、智能家居等复杂应用。不同的簇可以包含不同类型的设备,以满足不同场景的需求。

1.4 应用场景

简单描述符一般定义在App层,如下图所示:
在这里插入图片描述

SimpleDescriptionFormat_t zclSampleSw_SimpleDesc =
{SAMPLESW_ENDPOINT,                  //  端点号ZCL_HA_PROFILE_ID,                  //  设备应用领域IDZCL_HA_DEVICEID_ON_OFF_LIGHT_SWITCH,//  设备类型IDSAMPLESW_DEVICE_VERSION,            //  版本号SAMPLESW_FLAGS,                     //  保留字段ZCLSAMPLESW_MAX_INCLUSTERS,         //  最大输入簇数量(cId_t *)zclSampleSw_InClusterList, //  表示输入簇列表ZCLSAMPLESW_MAX_OUTCLUSTERS,        //  最大输出簇数量(cId_t *)zclSampleSw_OutClusterList //  表示输出簇列表
};

二、AF通信原理

2.1 通信过程

AF的全称是Application Framework,中文意思是应用框架,AF层也就是应用框架层,它在ZigBee协议层次中位置如图所示。开发者可以基于这个层次编写代码,实现ZigBee设备之间的数据通信。
在这里插入图片描述
图片来源于:善学坊

需要知道的是ZigBee在很多情况下是基于服务的,也就是单单依靠网络地址是不够的,还需要端点号来确认通信的最终目的。

处于网络中的ZigBee设备都会被分配一个网络地址,用于标识设备所处的位置。通过这个网络地址就可以找到对应的设备了。我们知道ZigBee 3.0是利用简单描述符来描述特定的服务的,并且设备上的每个简单描述符都配有一个唯一的端点号
在这里插入图片描述
图片来源于:善学坊

  假设现在ZigBee网络中有一个协调器和一个智能插座终端,这个智能插座的网络地址为0x0EF1,并且配有一个简单描述符描述这个插座具备的一些功能,这个简单描述符的端点号是8。

  如果协调器要向这个插座发送一个打开指令,不能简单地使用网络地址0x0EF1来说明把命令发送给这个插座,还需要利用端点号8来说明把命令发送给端点号8对应的服务。

2.2 端点号分类

端点号的分类
端点号的取值范围是0~255,其中:

  • 端点号0被分配给了ZDO(ZigBee Device Object)。
  • 端点号255是广播,也就是向这个端点号发送数据时,设备的所有服务(简单描述符)都会收到这个数据。
  • 端点号241~254是暂时保留起来的端点号,暂时不能使用。
  • 剩下的端点号1~240可以供开发者自由地使用,例如读者一直学习的SampleSwitch这个工程所使用的端点号可以在工程中找到,如图所示。

在这里插入图片描述

2.3 通信方式

ZigBee支持3种通信方式,分别是点对点、广播和组播。

  • 点对点通信(P2P,Peer to Peer):顾名思义,就是两个设备之间一对一通信。
  • 广播:给其他的所有设备发送数据。
  • 组播:给一部分的设备发送数据,这里的“一部分”说的就是一个特定的组。

2.4 注册简单描述符

在使用AF通信前,需要先注册简单描述符并且让对应的端点号生效,或者说让这个简单描述符对应的服务生效。这个流程是:

(1)创建一个简单描述符。在讲解简单描述符的章节中,我们已经看到相关的定义了。

(2)注册这个简单描述符。打开配套的工程,在zcl_samplesw.c文件中的zclSampleSw_Init()这个函数中可以找到以下代码,如图所示。
在这里插入图片描述

在应用层初始化函数zclSampleSw_Init()中,有两种注册简单描述符的方法:
(1)可以调用bdb_RegisterSimpleDescriptor()来在BDB中注册简单描述符。
(2)也可以直接调用afRegister()直接在AF中注册简单描述符。

在注册完简单描述符之后,就可以使用AF层的通信API来收发数据了。

三、数据发送API简介

3.1 AF层数据发送API

  数据发送API
在AF.c这个文件中可以找到一个名为AF_DataRequest()的数据发送API,如图所示。
在这里插入图片描述
  参数说明

/*
* @param dstAddr 目标设备地址,包含网络地址和端点号
* @param srcEP 发送设备的简单描述符
* @param cID Cluster ID,后续章节将会详细讲解
* @param len 待发送数据的长度
* @param buf 待发送的数据
* @param transID 传输ID,可以用来给每一次发送的数据包编一个号
* @param options 附加选项,可以用来给这次数据发送添加一些说明                      
* @param radius 最大的路由跳转级数
*/
afStatus_t AF_DataRequest(afAddrType_t *dstAddr, endPointDesc_t *srcEP,uint16 cID,uint16 len, uint8 *buf,uint8 *transID,uint8 options,uint8 radius );

协议栈里面的SampleSwitch这个例程基于这个API封装出了点对点通信API、广播通信API和组播通信API。

3.2 基于AF层封装的通信API

3.2.1 点对点通信API

/*
* @param destNwkAddr 目标设备的网络地址
* @param cid Cluster ID,后续课程将会详细讲解
* @param len 数据长度
* @param data 数据内容
*/
static void zclSampleSw_AF_P2P(uint16 destNwkAddr, uint16 cid, uint8 len, uint8 *data)
{    afAddrType_t dstAddr; //寻址信息配置 static uint8 transferId = 0;//传输ID,是数据包的标识符/* Destination */    dstAddr.addrMode = afAddr16Bit;// 设置目标地址模式为16位网络地址,表示使用P2P的通信方式dstAddr.addr.shortAddr = destNwkAddr;//目标设备的网络地址  dstAddr.endPoint = SAMPLESW_ENDPOINT;//目标设备的端点号transferId++;    AF_DataRequest(&dstAddr, &sampleSw_TestEp,//已经创建好的简单描述符cid,    len, data,    &transferId,AF_DISCV_ROUTE,//进行路由扫描操作,用于建立发送数据报文的通信路径。关于这个参数,暂时保持例程默认的代码就可以了AF_DEFAULT_RADIUS);//指定最大的路由跳转级数
}

这个API中使用了一个afAddrType_t类型变量,该变量类型被定义在AF.h中,用于配置寻址信息。这个变量定义如下:

typedef struct
{union{uint16      shortAddr;ZLongAddr_t extAddr;} addr;afAddrMode_t addrMode;uint8 endPoint;uint16 panId;  // used for the INTER_PAN feature
}  afAddrType_t;

这个API中也使用了一个afAddrMode_t变量,表示地址模式(类型),用于说明使用的是点对点、广播还是组播的通信方式。同样地,可以查看其定义,代码如下:
在这里插入图片描述

可以看到,afAddrMode_t是一个枚举类型变量。

在zclSampleSw_AF_P2P()函数的的最后,可以看到最终就是调用AF_DataRequest()来发送数据的。开发者也可以基于AF_DataRequest()来编写自己的点对点通信API,而不使用这个工程中的默认的这个zclSampleSw_AF_P2P()。

3.2.2 广播通信API

在zcl_samplesw.c文件中可以找到广播通信API,代码如下:

/*
* @param cid Cluster ID
* @param len 待发送数据的长度
* @param *data 待发送数据的内容
*/
static void zclSampleSw_AF_Broadcast(uint16 cid,uint8 len,uint8 *data)
{afAddrType_t dstAddr;  static uint8 transferId = 0;  /* Destination */  dstAddr.addrMode = afAddrBroadcast;   // 使用广播模式dstAddr.addr.shortAddr = 0xFFFF; // 广播地址dstAddr.endPoint = SAMPLESW_ENDPOINT; // 目标设备的端点号/* Transfer id */  transferId++;  /* Send */  AF_DataRequest(&dstAddr, &sampleSw_TestEp,//已经创建好的简单描述符cid,  len, data,  &transferId,AF_TX_OPTIONS_NONE,AF_DEFAULT_RADIUS );//指定了最大的路由跳转级数
}

从广播通信API的定义可以发现,它和点对点通信API是相似的。广播通信API中使用了网络地址0xFFFF,这表示把数据发送到该网络上的所有设备中。但其实ZigBee的广播地址一共有3个,如下所示:

0xFFFF:广播给该网络中的所有设备
0xFFFD:只广播给该网络中打开收听功能的设备
0xFFFC:只广播给该网络中的协调器和路由设备

同样地,开发者也可以基于AF_DataRequest()来编写自己的广播通信API,而不使用这个工程中的默认的这个zclSampleSw_AF_Broadcast()

3.2.3 组播通信API

使用组播通信API,可以只给指定的一组设备发送数据。在zcl_samplesw.c文件中可以找到组播通信API,代码如下:

/*
* @param groupId 组ID
* @param cid ClusterID,后续章节将会详细讲解
* @param len 待发送数据的长度
* @param data 待发送数据的内容
*/
static void zclSampleSw_AF_Groupcast(uint16 groupId,uint16 cid,uint8 len,uint8 *data)
{    afAddrType_t dstAddr;    static uint8 transferId = 0;    /* Destination */    dstAddr.addrMode = afAddrGroup;//使用组播通信模式dstAddr.addr.shortAddr = groupId;dstAddr.endPoint = SAMPLESW_ENDPOINT;//组中的设备的端点号/* Transfer id */    transferId++;   /* Send */    AF_DataRequest(&dstAddr, &sampleSw_TestEp,//已经创建好的简单描述符cid, len, data,    &transferId, AF_TX_OPTIONS_NONE,AF_DEFAULT_RADIUS );//指定最大的路由跳转级数,暂时可忽略
}

四、实战

在学习完AF层通信API后,本章将以实验的方式讲解如何使用这些API,实验设备包含一个协调器和一个路由器(或终端),内容是:

  • 路由器(或终端)定时地通过点对点的方式向协调器发送数据。
  • 让路由器(或终端)加入到一个组中。
  • 协调器定时地发送广播数据和组播数据。

这部分根据善学坊教程:3.4 ZigBee 3.0 通信实验

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/259798.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux------环境变量

目录 前言 一、环境变量 二、添加PATH环境变量 三、HOME环境变量 四、查看所有环境变量 1.指令获取 2.代码获取 2.1 getenv 2.2main函数的第三个参数 2.3 全局变量environ 五、环境变量存放地点 六、添加自命名环境变量 七、系统环境变量具有全局属性 八、环境变…

Shiro-05-5 分钟入门 shiro 安全框架实战笔记

序言 大家好,我是老马。 前面我们学习了 web 安全之 Spring Security 入门教程 这次我们来一起学习下另一款 java 安全框架 shiro。 什么是Apache Shiro? Apache Shiro是一个功能强大且易于使用的Java安全框架,它为开发人员提供了一种直…

区块链技术和Hyperledger Fabric介绍

1 区块链介绍 1.1 区块链技术形成 1.1.1 起源 在比特币诞生之时,技术专家们开始研究比特币的底层技术,并抽象提取出来,形成区块链技术,或者称分布式账本技术。 1.1.2 定义 简称BT(Blockchain technology&#xff…

8 款顶级开源漏洞扫描工具推荐

1.OpenVAS OpenVAS漏洞扫描器是一种漏洞分析工具,由于其全面的特性,可以使用它来扫描服务器和网络设备。这些扫描器将通过扫描现有设施中的开放端口、错误配置和漏洞来查找IP地址并检查任何开放服务。扫描完成后,将自动生成报告并以电子邮件形…

基于springboot的鞋类商品购物商城系统

文章目录 目录 文章目录 前言 一、功能设计 二、功能实现 2.1 后台功能 2.1.1 管理员登录界面 2.1.2 系统首页 2.1.3 会员管理 2.1.4 栏目管理 2.1.5 商品管理 2.1.6 评价管理 2.1.7 订单管理 2.2 前台功能 2.2.1 新用户注册登录 2.2.2 首页 2.2.3 商品分类 2.2.4 地址管理 2.2…

(AtCoder Beginner Contest 341)(A - D)

比赛地址 : Tasks - Toyota Programming Contest 2024#2&#xff08;AtCoder Beginner Contest 341&#xff09; A . Print 341 模拟就好了 &#xff0c; 先放一个 1 , 然后放 n 个 01 ; #include<bits/stdc.h> #define IOS ios::sync_with_stdio(0);cin.tie(0);cout…

Nature Chemical Engineering 威斯康星大学让机器人科学家做实验,自主设计全新蛋白质

【导读】这个自动化蛋白质设计系统可以自己设计和测试新的蛋白质&#xff0c;不需要人类的帮助。就像一个能自己做实验的机器人科学家。它能通过自主学习自行进行蛋白质设计&#xff0c;同时在实验室里自动进行测试。 AI Agent&#xff0c;已经可以不需要人类帮助&#xff0c;…

数据结构-邻接矩阵

介绍 邻接矩阵&#xff0c;是表示图的一种常见方式&#xff0c;具体表现为一个记录了各顶点连接情况的呈正方形的矩阵。 假设一共有以下顶点&#xff0c;其连接关系如图所示 那么&#xff0c;怎么表示它们之间的连接关系呢&#xff1f; 我们发现&#xff0c;各条边所连接的都…

7.1 Qt 中输入行与按钮

目录 前言&#xff1a; 技能&#xff1a; 内容&#xff1a; 参考&#xff1a; 前言&#xff1a; line edit 与pushbotton的一点联动 当输入行有内容时&#xff0c;按钮才能使用&#xff0c;并能读出输入行的内容 技能&#xff1a; pushButton->setEnabled(false) 按钮不…

django中的中间件

在Django中&#xff0c;中间件&#xff08;Middleware&#xff09;是一个轻量级的、底层的“插件”系统&#xff0c;用于全局地修改Django的输入或输出。每个中间件组件都负责执行一些特定的任务&#xff0c;比如检查用户是否登录、处理日志、GZIP压缩等。Django的中间件提供了…

Python安装GDAL库

目录 一、GDAL介绍 二、GDAL应用 三、python安装GDAL库 一、GDAL介绍 GDAL&#xff08;Geospatial Data Abstraction Library&#xff09;是一个在X/MIT许可协议下的开源栅格空间数据转换库。它利用抽象数据模型来表达所支持的各种文件格式&#xff0c;并且提供了一系列命令…

10分钟带你了解分布式系统的补偿机制

我们知道&#xff0c;应用系统在分布式的情况下&#xff0c;在通信时会有着一个显著的问题&#xff0c;即一个业务流程往往需要组合一组服务&#xff0c;且单单一次通信可能会经过 DNS 服务&#xff0c;网卡、交换机、路由器、负载均衡等设备&#xff0c;而这些服务于设备都不一…

(10)Hive的相关概念——文件格式和数据压缩

目录 一、文件格式 1.1 列式存储和行式存储 1.1.1 行存储的特点 1.1.2 列存储的特点 1.2 TextFile 1.3 SequenceFile 1.4 Parquet 1.5 ORC 二、数据压缩 2.1 数据压缩-概述 2.1.1 压缩的优点 2.1.2 压缩的缺点 2.2 Hive中压缩配置 2.2.1 开启Map输出阶段压缩&…

elementui 中 el-date-picker 控制选择当前年之前或者之后的年份

文章目录 需求分析 需求 对 el-date-picker控件做出判断控制 分析 给 el-date-picker 组件添加 picker-options 属性&#xff0c;并绑定对应数据 pickerOptions html <el-form-item label"雨量年份&#xff1a;" prop"date"><el-date-picker …

洛谷 P6546 [COCI2010-2011#2] PUŽ

讲解&#xff1a; 首先还是正常输入&#xff1a; int a,b,v; cin>>a>>b>>v; 然后经入一个函数num&#xff1a; cout<<num(1.0*(v-a),(a-b))1<<endl; 之所以要乘以1.0是因为要向上取整&#xff01;而这个num函数的两个参数则是“蜗牛白天爬了多…

【智能家居入门2】(MQTT协议、微信小程序、STM32、ONENET云平台)

此篇智能家居入门与前两篇类似&#xff0c;但是是使用MQTT协议接入ONENET云平台&#xff0c;实现微信小程序与下位机的通信&#xff0c;这里相较于使用http协议的那两篇博客&#xff0c;在主程序中添加了独立看门狗防止程序卡死和服务器掉线问题。后续还有使用MQTT协议连接MQTT…

LabVIEW焊缝缺陷超声检测与识别

LabVIEW焊缝缺陷超声检测与识别 介绍基于LabVIEW的焊缝缺陷超声检测与识别系统。该系统利用LabVIEW软件和数据采集卡的强大功能&#xff0c;实现了焊缝缺陷的在线自动检测&#xff0c;具有通用性、模块化、功能化和网络化的特点&#xff0c;显著提高了检测的效率和准确性。 随…

Qt的基本操作

文章目录 1. Qt Hello World 程序1.1 通过图形化界面的方式1.2 通过代码的方式实现 2. Qt 的编码问题3. 使用输入框实现hello world4. 使用按钮实现hello world5. Qt 编程注意事项6. 查询文档的方式7. 认识Qt坐标系 1. Qt Hello World 程序 1.1 通过图形化界面的方式 我们先讲…

8、内网安全-横向移动RDPKerberos攻击SPN扫描WinRMWinRS

用途&#xff1a;个人学习笔记&#xff0c;有所借鉴&#xff0c;欢迎指正 目录 一、域横向移动-RDP-明文&NTLM 1.探针服务&#xff1a; 2.探针连接&#xff1a; 3.连接执行&#xff1a; 二、域横向移动-WinRM&WinRS-明文&NTLM 1.探针可用&#xff1a; 2.连接…

每日一练:LeeCode-501、二叉搜索树中的众数【二叉搜索树+pre辅助节点+DFS】

本文是力扣LeeCode-LeeCode-501、二叉搜索树中的众数【二叉搜索树pre辅助节点DFS】 学习与理解过程&#xff0c;本文仅做学习之用&#xff0c;对本题感兴趣的小伙伴可以出门左拐LeeCode。 给你一个含重复值的二叉搜索树&#xff08;BST&#xff09;的根节点 root &#xff0c;…