lesson11 Zigbee MAC地址通信

news2024/9/24 3:26:08

目录

Zigbee MAC地址通信

前言

查看MAC地址(含组网过程抓包分析)

方法1:通过dongle抓包查看MAC地址

方法2:仿真调试查看MAC

实验过程

实现步骤

实验效果

出错分析

最终现象

结果分析 


Zigbee MAC地址通信

前言

1、Zigbee模块在无线网络里两个地址:

  • 2个字节在网络里唯一的网络短地址
  • TI在每个CC2530芯片出厂的时候,每一颗芯片都固化了一个唯一的8个字节的硬件地址、MAC或者IEEE地址

2、本次实验我们通过发送模块(终端),按下S1,通过指定接收方MAC地址的方法发送数据包。当接收模块(协调器)接收到数据后,将接收内容通过串口发给电脑上位机。

3、本实验用到的新知识点:

#include "NLMEDE.h"
extern uint16 NLME_GetShortAddr( void );//获取当前模块的网络地址
extern byte *NLME_GetExtAddr( void );//获取当前模块的MAC

extern uint16 NLME_GetCoordShortAddr( void );//获取父节点的网络地址
extern void NLME_GetCoordExtAddr( byte * );//获取父节点的MAC

查看MAC地址(含组网过程抓包分析)

方法1:通过dongle抓包查看MAC地址

1、协调器模块先上电

第一帧是协调器模块发出的信标请求帧,等待其它模块回复。功能是协调器用于判断周围有没有其它模块(对于终端和路由器,上电也会发此帧,作用是让在它附近的所有具备介绍人资格的节点都回复信标帧,这些返回的信标帧被这个想要加入的无线模块拿到,通过这些信标帧选出最佳介绍人节点,请求加入。)

第二帧是协调器模块发出的网络连接状态帧数据帧,表示协调器创建无线网络成功。

第三帧与第二帧一样,网络连接状态帧如果没有模块回复,会默认每隔15s,重新发送一次,目的是告诉周围模块网络创建成功,等待其它模块的加入

我们可以看见,如果没有模块回应会一直发网络连接状态帧,且每隔15s一次。

2、接着终端上电

创建新页面重新抓包

第一帧还是协调器发出的网络连接状态帧

第二帧是终端模块发出的信标请求帧,用于发现周围的网络,请求加入

第三帧是协调器模块发出的信标帧,终端模块在拿到这一帧之后可以得到协调器模块相对于它自己的信号强度,判断是不是最佳介绍人(其中就包含了协调器的MAC地址)

第四帧——第七帧重复信标请求接收的过程(由于终端还没有正式入网,所以终端发送的所有帧的目的PANID都是0xFFFF;而协调器目的网络PANID是自己创建的网络PANID)

第八帧是由终端模块发送给协调器模块,目的是告诉协调器,你可以作为我的介绍人,并把自己的MAC地址告诉对方

第九帧是协调器模块硬件回复给终端模块的ACK,表明协调器模块已经收到了终端发过来的请求帧,接受成为终端的介绍人

第十帧是终端发给协调器模块的帧,请求协调器,把根据前面发送的MAC地址分频好的网络地址发给终端

第十一帧:协调器模块硬件回复给终端的ACK,表明收到了终端的请求。

第十二帧:协调器把为终端分配好的网络地址发给终端。这个帧需要非常明确地发给终端,但是终端模块还不知道自己的网络地址是多少,所以在指定目标地址的时候用MAC地址。

第十三帧:在终端模块根据自己的MAC地址收到了协调器发过来分频给自己的网络地址,硬件自动回复ACK,表明自己已经收到

第十四帧:终端模块发送的入网宣告帧,目的是协调器我成功入网了,我的网络地址是0xB463。(这里与协调器与路由器组网不同,路由器成功入网后,会主动广播入网宣告;而终端是先发送给协调器,然后再通过协调器来广播转发给网络里所有节点。这里体现了,终端和路由器的差异,终端与父节点之外的模块进行收发消息必须要经过父节点,且终端无法作为父节点)

第十五帧:协调器模块硬件回复给终端的ACK,表明收到了终端的请求。

第十六帧:协调器模块在收到了终端模块发出的入网宣告帧后,将内容进行广播转发(此时已经入网成功)

第十七、十八帧表示协调器模块和终端模块在成功组网后,协调器向子节点终端发送应答命令帧,然后终端回复。这样是为了保持父子节点之间的通信。

之后的所有帧都是重复第十七、十八帧的内容。(终端作为子节点,父子节点每隔固定时间会进行一次询问)

而协调器和终端组网后,协调器依然会每隔15s广播发送网络连接状态帧,来等待其它更多模块的加入(如下图所示)。

协调器和路由器

第十三帧以及之前的入网过程与终端入网相同,之间从第十四帧开始。

第十四和第十五帧是路由器的入网宣告帧,路由器先广播,父节点协调器收到后进行广播转发

第十六帧和第十七帧分别是协调器和路由器发送的网络连接状态帧,目的是表明自己当前状态稳定,可以等待其它模块的加入(成为其子节点入网),与终端不同,路由器入网后,不会直接与父节点进行应答回复,而是通过网络连接状态帧的广播向父节点表示当前连接稳定。

第十八帧开始及之后都是重复第十六、十七帧的内容。

我们记录下这两个模块的MAC

模块A:0x00124B002A59E327

模块B:0x00124B002A59E7FD

 

方法2:仿真调试查看MAC

我们需要用到两个函数,NLME_GetShortAddr用于获取当前模块的网络地址,NLME_GetExtAddr用于获取当前模块的物理地址。在NLMEDE.h中声明。

extern uint16 NLME_GetShortAddr( void );

extern byte *NLME_GetExtAddr( void );

首先在应用层文件定义两个变量并初始化 uint16 NwkAddr=0xFFFF; uint8 MacAddr[8];

然后再协调器上电初始化消息判断处添加函数调用和赋值。

其中用到的memcpy这里做个说明:strcpy和memcpy两者都是C语言里的库函数。strcpy 只能拷贝字符串,它遇到'\0'就结束拷贝;memcpy 是用来做内存拷贝,可以用来拷贝任何数据类型的对象,可以指定拷贝的数据长度。memcpy提供了一般内存的复制,对于需要复制的内容没有限制,用途更广。

接着下载协调器程序,进行仿真,设置断点,Go全速运行

点击add to watch将NwkAdd加入调试变量窗口

此时可以发现NwkAdd的值是初始值0xffff

然后先取消,接着step over,可以发现NwkAdd的值变为了0,因此本机的网络地址为0XFFFF

同样将MacAddr添加到调试窗口

step over后,得到我们当前设备的MAC地址为0x00124B002A59E7FD

此外我们还可以通过下面这两个函数获取当前模块父节点的网络地址和MAC地址。

extern uint16 NLME_GetCoordShortAddr( void );

extern void NLME_GetCoordExtAddr( byte * );

实验过程

实现步骤

编写发送过程有两个地方需要注意:发送模式我们要配置成Addr64Bit(表示通过MAC发送),目标地址我们不用shortAddr,而用extAddr(数组)。因此我们通过自己定义一共DstMac数组来进行Mac地址赋值。

注意:将MAC地址填入数组时要按主机字节序(小端格式)来填,顺序不能反。

接收模块我们不需要怎么改,数据接收处理函数如下即可

实验效果

我将程序分别下载进模块,组网成功后,终端按下按键,接收模块协调器什么反应也没有,上位机也没接收到消息。

通过抓包发现,按下按键的时候确实没有数据包发出。只有协调器模块和终端模块之间进行父子点询问的帧和协调器模块的网络状态帧。并没有我们按下按键通过指定协调器MAC发送的数据帧。

经过半天的百度查阅,但网上关于Zigbee模块MAC地址通信的资料少之又少,困扰了我一晚上,找到了一个可能可行的方法。

我参考了这篇博客https://www.cnblogs.com/gary-guo/p/5737076.html

出错分析

首先我们要搞清楚MAC地址通信的本质是什么:

在网络里面的每一个zigbee模块,它都有一个地址管理器,它会记录与它经常通信的模块的MAC地址以及网络短地址,然后存放到地址管理器里面;

以MAC地址发送数据:在数据发送的时候,它会去检查地址管理器看是否有对应的MAC地址,如果有,那么它会把对应的网络短地址放到无线数据包里面去发送;如果没有对应的MAC地址,为了确保通信成功,那么我们应该怎么做呢?

其中ZDP_NwkAddrReq(DestMac,ZDP_ADDR_REQTYPE_SINGLE,0,0);的作用是让MAC对应的目标模块将当前的网络短地址回复给我

然后收到对应MAC地址的网络短地址后,就可以在地址管理器当中建立这样的映射关系,然后延时30毫秒,发送事件,GENERICAPP_SEND_MSG_EVT,然后进入到该事件里面去发送实际的数据

将程序下载到模块进行抓包

我们发现,按下按键后,请求网络地址的通信过程是正常的,而终端依然无法将数据通过MAC地址发送给协调器。不过至少验证了模块硬件没有问题。

最后我重新安装了一个TI 协议栈:ZStack-CC2530-2.3.0-1.4.0,我原来使用的版本是ZStack-CC2530-2.5.1a。

将我们的原终端程序重新移植到新的新协议栈,通信成功!

     char theMessageData[] = "Zigbee MAC实验";
      uint8 DestMac[8]={0xFD,0xE7,0x59,0x2A,0x00,0x4B,0x12,0x00};//0x00124B002A59E7FD   
                    
      GenericApp_DstAddr.addrMode = (afAddrMode_t)Addr64Bit;//发送模式是MAC
      //StarryApp_DstAddr.addr.shortAddr = 0x0000;
      memcpy(GenericApp_DstAddr.addr.extAddr,DestMac,8);
      // Take the first endpoint, Can be changed to search through endpoints
      GenericApp_DstAddr.endPoint = GENERICAPP_ENDPOINT;
      
      AF_DataRequest( &GenericApp_DstAddr, &GenericApp_epDesc,
                 GENERICAPP_CLUSTERID,
                 (byte)osal_strlen( theMessageData ) + 1,
                 (byte *)&theMessageData,
                 &GenericApp_TransID,
                 AF_DISCV_ROUTE, AF_DEFAULT_RADIUS );

最终现象

抓包发现,按下S1后,终端成功通过协调器的MAC地址发送了数据包给协调器

串口也成功接收到数据

结果分析 

我们可以发现,发送数据包的目标地址不是MAC,而是目标的网络短地址。

这是因为当以MAC地址进行发送的时候,发送模块首先会查看自己的地址管理器有没有节点的MAC与我们所指定通信的MAC地址是一致的。如果发现有,它会将目标节点的网络短地址作为无线数据包的发送地址。如果两个模块之间距离很远,且不怎么互相通信,地址管理器查不到对方的MAC。那我们在发送数据包前就必须使用网络短地址请求函数

ZDP_NwkAddrReq(DestMac,ZDP_ADDR_REQTYPE_SINGLE,0,0);

通过发送一个信号,来让我们的MAC地址对应的模块把网络短地址回复给我们,之后等待30ms再发送(确保发送模块成功获取目标模块网络地址),就一定会成功。这也是我刚刚提到的一个解决数据包发送失败的处理办法。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python中类的变量,一个下划线与两个下划线的区别

形似 功能__xx这是私有变量, 只有内部可以访问,外部不可以访问。但是也不是一定不可以访问,只要以 _类名__xx样式就可以访问 。但最好不要这样做,养成良好编程习惯_x这是实例变量,可以访问,但是不要轻…

STM32MP157-正点原子第六章tf-a使用编译错误

原因:交叉编译工具链选择错误 亲测: gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf.tar.xz 和 gcc-arm-11.2-2022.02-x86_64-arm-none-linux-gnueabihf.tar.xz 可以成功编译 下载网址https://mirrors.tuna.tsinghua.edu.cn/armbian-relea…

全国各城市交通运输邮电业本地电话用户(1999-2020年)

本数据展示了全国各城市的本地电话用户数量。通过对这些数量的分析,可以了解全国各城市通信设施建设的发展情况、人口密度以及工业经济的发展程度等方面的信息。此数据不仅可供政府部门制定信息技术政策,还可以为企业投资提供重要参考。同时,…

Leetcode-每日一题【382.链表随机结点】

题目 给你一个单链表,随机选择链表的一个节点,并返回相应的节点值。每个节点被选中的概率一样 。 实现 Solution 类: Solution(ListNode head) 使用整数数组初始化对象。int getRandom() 从链表中随机选择一个节点并返回该节点的值。链表中所有节点被选中的概率相…

网络空间安全专业未来的发展前景以及薪资待遇如何?

不管是考虑未来报读专业的准大学生,还是初入职场的实习生,亦或是想要跳槽转岗的职场人,当我们开始选择一份工作时,本质上都在考虑以下三个问题: 这份工作的收入水平如何;这份工作有没有发展前景&#xff1…

基于卷积神经网络的目标分类案例

文章目录 一、卷积神经网络二、环境配置及数据集准备三、猫狗数据分类建模1、猫狗图像预处理2、猫狗分类的实例——基准模型3、基准模型的调整 一、卷积神经网络 卷积神经网络(Convolutional Neural Networks, CNN 是一类包含卷积计算且具有深度结构的前馈神经网络…

HashMap源码分析

文章目录 1、put方法流程2 、扩容机制3 、get方法 分析源码我们一般从三个方面入手&#xff1a; 常见属性&#xff08;成员变量&#xff09;构造方法关键方法 下面分析一下HashMap源码&#xff1a; 首先常见属性有&#xff1a; DEFAULT_INITIAL_CAPACITY 1 << 4; // a…

二叉树进阶——搜索二叉树

搜索二叉树 1. 概念2. 二叉搜索树的操作2.1 查找2.2 插入2.3 删除&#xff08;重点&#xff09; 3. 搜索二叉树的应用4. 搜索二叉树的性能分析 1. 概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&am…

《项目实战》构建前后端一体化项目查询CSDN博客Top100文章质量分

系列文章目录 构建前后端一体化项目查询CSDN博客Top100文章质量分 文章目录 系列文章目录前言1、搭建后端框架1.1、 创建RestFull风格接口1.2、创建获取数据服务1.2.1、在个人博客页&#xff0c;找到获取全部博文的路径&#xff08;页面-> network->找到加载博文的地址&…

C# ---委托机制 delegate 和 回调方法 callback

C# --- 委托机制 delegate 和 回调 callback 什么是委托机制委托机制的优点C# 中的Action 和 Func委托机制的主要用处 --- 回调 Callback 什么是委托机制 委托机制相当于C语言中的函数指针, 将一个方法的reference传入另外一个方法中 Example //创建一个方法 //创建一个委托 …

青少年机器人技术一级考试备考重点(二):基础结构与力的基础

随着机器人技术的飞速发展&#xff0c;越来越多的青少年开始关注并参与其中。青少年机器人技术考试作为一项评估学生机器人技术水平的重要考试&#xff0c;备受广大青少年和家长的关注。为了更好地备战青少年机器人技术一级考试&#xff0c;了解考试的学习要点和备考重点是非常…

设计师简历范文

设计师简历范文一&#xff1a; 姓名&#xff1a; 目前所在&#xff1a; 天河区 年  龄&#xff1a; 26 户口所在&#xff1a; 湖南 国  籍&#xff1a; 中国 婚姻状况&#xff1a; 未婚 民  族&#xff1a; 汉族 身  高&#xff1a; 170 cm 体  重&#xff1a; 65 kg…

大学期间,这些证书你考过了吗

目录 一、概览 1、英语方面 第二外语 2、专业资格证书 3、教师资格证 4、普通话证书 5、财务类证书 6、法律职业资格证 7、有备无患的证书 8、技能类证书-驾照 9、发表论文、专利证书、出专业书 10、竞赛类 11、其他 二、写在最后 一、概览 1、英语方面 第二外语 …

Spring AOP讲解及实例

Aop面向切面编程 文章目录 Aop面向切面编程什么是AOPAOP术语Spring AOP 的使用导入依赖编写切面类切面定义语法小细节输出日志成功 什么是AOP AOP&#xff1a;&#xff08;Aspect Oriented Programming&#xff09;面向切面编程&#xff0c;和OOP&#xff08;Object Oriented …

Nginx(6)nginx的缓存集成

缓存集成 Nginx缓存集成缓存的概念Nginx的web缓存服务 缓存设置的相关指令Nginx缓存设置案例 Nginx缓存的清除Nginx设置资源不缓存 Nginx缓存集成 缓存的概念 缓存就是数据交换的缓冲区(称作Cache)&#xff0c;当用户要获取数据的时候&#xff0c;会先从缓存中去查询获取数据…

前端Vue基本语法

尤雨溪 文章目录 前言MVVM框架认识Vue文本渲染指令 v-text属性绑定指令:title属性动态绑定class属性动态绑定style属性动态绑定 事件绑定 事件名条件渲染指令v-ifv-if和v-showv-else和v-else-if 循环遍历指令 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xf…

华为OD机试真题 Python 实现【获取最大软件版本号】【2023Q1 100分】,附详细解题思路

目录 一、题目描述二、输入描述三、输出描述四、补充说明五、解题思路六、Python算法源码七、效果展示1、输入2、输出 一、题目描述 Maven版本号定义&#xff0c;<主版本>.<次版本><增量版本>-<里程碑版本> 举例3.1.4-beta 其中&#xff0c;主版本和次…

华为OD机试真题 Python 实现【货币单位换算】【2023Q1 100分】,附详细解题思路

目录 一、题目描述二、输入描述三、输出描述四、解题思路五、Python算法源码六、效果展示1、输入2、输出3、思路分析4、输入5、输出6、思路分析 一、题目描述 记账本上记录了若干条多国货币金额&#xff0c;需要转换成人民币分 (fen)&#xff0c;汇总后输出每行记录一条金额&a…

红色通信史(三):在战火中成长

上一期我们说到&#xff0c;苏区红军因为第五次反围剿失败&#xff0c;被迫进行战略转移&#xff0c;开始了史无前例的长征。 ▉ 粉碎分裂阴谋&#xff0c;确保长征胜利 在长征的过程中&#xff0c;前有堵截&#xff0c;后有追兵&#xff0c;红军历经艰难险阻&#xff0c;不断与…

Qt Quick系列(7)—Model-View

&#x1f680;作者&#xff1a;CAccept &#x1f382;专栏&#xff1a;Qt Quick 文章目录 前言内置视图ViewRepeaterListViewGridView 代理delegate总结 前言 在QML中&#xff0c;model和view由delegate连接&#xff0c;他们的关系如下&#x1f447; 1、delegate 属性&#…