使用Nordic的nrf52832进行主从机连接抓包分析

news2024/12/23 10:16:51

主机使用例程:nRF5_SDK_17.1.0_ddde560\examples\ble_central\ble_app_blinky_c\pca10040\s132\arm5_no_packs
从机使用例程:nRF5_SDK_17.1.0_ddde560\examples\ble_peripheral\ble_app_blinky\pca10040\s132\arm5_no_packs

nrf52832

  • 1. 空中数据包格式
    • 1.1 Preamble
    • 1.2 Access Address
    • 1.3 PDU
      • 1.3.1 当PDU在主要或者次要广播信道上传输时,PDU格式
      • 1.3.2 当PDU在数据信道上传输时,PDU格式
    • 1.4 CRC
  • 2. 主从机交互过程中SN和NESN变化
    • 2.1 正常交互
    • 2.2 重传
    • 2.3 CRC错误
  • 3. 主从机连接抓包
    • 3.1 从机广播
    • 3.2 主机连接
    • 3.3 主机从机服务句柄值信息交换
      • 3.3.1 主机请求
      • 3.3.2 从机响应
    • 3.4 主机从机服务特征值信息交换
      • 3.4.1 主机请求
      • 3.4.2 从机响应
    • 3.5 其他交互过程
    • 3.6 连接参数更新
      • 3.6.1 从机请求
      • 3.6.2 主机响应
    • 3.7 数据交互
      • 3.7.1 主机向从机写入数据
      • 3.7.2 从机向主机通知

1. 空中数据包格式

在这里插入图片描述

1.1 Preamble

如果在LE 1M物理层上发送或者接收时前导码为1字节;在LE 2M物理层上发送或者接收时为2字节。前导码是由bit位1和bit位0交替组成的,由接入地址的LSB位决定。
LE 1M物理层:
若接入地址的LSB位为0:01010101
若接入地址的LSB位为1:10101010
LE 2M物理层:
若接入地址的LSB位为0:0101010101010101
若接入地址的LSB位为1:1010101010101010
在这里插入图片描述

1.2 Access Address

接入地址为4字节,广播接入地址:
所有广播接入地址的值都是固定的,其值为10001110100010011011111011010110b (0x8E89BED6)
数据接入地址:
这个地址是随机的,目的是使两个设备之间的每个链路层连接或者每个周期性的广播时拥有不同的访问地址。处于初始化状态的链路层将为它发送的每个初始化PDU生成一个新的访问地址;处于广播状态的链路层在每次设置启用周期性广播时,也会生成一个新的访问地址。这种随机的访问地址应该是一个32位的值。链路层生成的新的访问地址满足以下条件:
1.它不得是本设备上任何现有的链路层连接的访问地址。
2.它不得是任何启用的周期性广播的访问地址。
3.它不得有超过六个连续的0或1。
4.它不得是广播信道包的访问地址。
5.它不应是一个与广播信道包访问地址仅相差一位的序列。
6.不得所有4个字节相等。
7.不得超过24个比特位翻转。
8.在最后的6位中至少有2个比特位翻转。

1.3 PDU

PDU为协议数据单元(Protocol Data Unit)。

1.3.1 当PDU在主要或者次要广播信道上传输时,PDU格式

在这里插入图片描述
其中Header格式:
在这里插入图片描述
PDU Type:
在这里插入图片描述
在这里插入图片描述
RFU:1bit,保留给未来使用。
ChSel:1bit,表示通道选择;为1支持通道选择,为0不支持通道选择。
TxAdd:1bit,广播设备地址类型;为0表示公共地址,为1表示随机地址。
RxAdd:1bit,目标设备地址类型;为0表示公共地址,为1表示随机地址。
Length:8bit,表示Payload负载的长度;PDU的Payload负载长度与PDU类型有关。

1.3.2 当PDU在数据信道上传输时,PDU格式

在这里插入图片描述
其中Header格式:
在这里插入图片描述
相关字段的描述:
在这里插入图片描述

1.4 CRC

在每个链路层数据包的末尾都有一个24位的CRC。CRC多项式:x24 + x10 + x9 + x6 + x4 + x3 + x + 1
在这里插入图片描述

2. 主从机交互过程中SN和NESN变化

按照蓝牙核心规范,通信从主设备(设备A )发送一个链路层数据包开始,SN和NESN都设置为零。从这一点开始,在每次发生的数据包交换中,如果一切正常,设备A设置的SN字段的值将在0和1之间交替。因此,次设备(设备B )总是知道下一个要接收的数据包的SN值应该是多少,并对此进行检查。

2.1 正常交互

正常交互时SN和NESN变化图:
在这里插入图片描述
Nordic的协议栈正常交互时同蓝牙核心规范一致。
在这里插入图片描述

2.2 重传

如果设备B接收到一个SN值错误的数据包,则假定该数据包是接收到的前一个数据包的重传,承认该数据包,但不将其上传到协议栈进行进一步处理。如果设备A从设备B的应答中收到了一个未预期的NESN值,或者根本没有收到应答,它会重新发送原来使用相同SN值的数据包。不同的控制器实现可以自由地执行不同的算法,以确定通信失败的次数。
重传时SN和NESN变化图:
在这里插入图片描述
在这里插入图片描述

2.3 CRC错误

每个数据包包含一个CRC字段,加密后的数据包也包含一个MIC字段。在接收到数据包时,链路层检查CRC,如果MIC存在,则检查MIC。如果其中一个检查失败,则不承认该数据包,这通常会导致数据包的发起者重新发送该数据包。
在这里插入图片描述
Nordic的协议栈在出现CRC错误后,下一个连接事件直接把SN和NESN设置为1,跟蓝牙核心规范不相同。
在这里插入图片描述

3. 主从机连接抓包

在这里插入图片描述

3.1 从机广播

PDU Type为ADV_IND时,Payload格式:
在这里插入图片描述
PDU Type为SCAN_RSP时,Payload格式:
在这里插入图片描述
二者前6个字节表示广播设备的地址,后面由0-31个字节组成广播数据。
在这里插入图片描述
广播数据分为有效部分和无效部分,有效部分由一个个广播数据结构体组成,length为结构体长度,AD Type表示AD Data的类型定义。在工程中ble_gap.h文件中对AD Type有定义:
在这里插入图片描述
在这里插入图片描述
如果使用外观的话只能用SIG定义的外观,工程中相关定义在ble_types.h文件中:
在这里插入图片描述
上面3个AD structure中内容由从机在GAP参数初始化函数中设置:
在这里插入图片描述
在广播初始化函数中选择如何广播:
在这里插入图片描述

3.2 主机连接

发起连接的一方称为主机。PDU Type为CONNECT_IND或者AUX_CONNECT_REQ时,Payload格式:
在这里插入图片描述
InitA为主机地址,AdvA为广播地址,其中LLData格式为:
在这里插入图片描述
AA:链路层生成访问地址。
CRCInit:校验的初值,由链路层生成的随机值。
WinSize:建立连接时的连接窗口,值为WinSize1.25ms。
WinOffset:建立连接时的连接窗口偏移量,值为WinOffset
1.25ms。
Interval:连接间隔,值为Interval1.25ms。
Latency:从机握手潜伏期。
Timeout:从机断开超时时间,值为Timeout
10ms。
Chm:信道占用图。
Hop:调频算法的增量,值范围5-16。
SCA:睡眠时钟精度
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
主机工程在扫描初始化函数scan_init中调用了nrf_ble_scan_init函数,如果没有设置连接参数,则会使用默认的连接参数:
在这里插入图片描述

3.3 主机从机服务句柄值信息交换

L2CAP基本信息帧如下:
在这里插入图片描述
Channel ID也就是CID,其中0x0004表示属性协议:
在这里插入图片描述
ATT主机请求服务句柄值信息Payload如下:
在这里插入图片描述
ATT从机响应服务句柄值信息Payload如下:
在这里插入图片描述
句柄信息Handles Information包含如下:
在这里插入图片描述
UUID类型在ble_types.h中定义:
在这里插入图片描述

3.3.1 主机请求

在这里插入图片描述
128位私有服务的UUID就是从机工程中定义的基本UUID加上服务UUID:

#define LBS_UUID_BASE        {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, \
                              0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00}
#define LBS_UUID_SERVICE     0x1523
#define LBS_UUID_BUTTON_CHAR 0x1524
#define LBS_UUID_LED_CHAR    0x1525

3.3.2 从机响应

在这里插入图片描述

3.4 主机从机服务特征值信息交换

ATT主机请求服务特征值信息Payload如下:
在这里插入图片描述
ATT从机响应服务特征值信息Payload如下:
在这里插入图片描述

3.4.1 主机请求

在这里插入图片描述
句柄的值是唯一的,因此本次请求时起始句柄值从服务句柄值开始。

3.4.2 从机响应

在这里插入图片描述
从机工程主服务有两个特征值,一个是按键通知,一个是LED控制,因为MTU的值为默认值23,所以需要分两次交换特征性。

3.5 其他交互过程

此外还有其他的交互过程主要是针对按键服务打开通知功能。
查找信息请求(Find Information Request0x04)及响应(Find Information Response0x05)用于获取属性句柄与其关联类型的映射。这使得客户端可以在服务器上发现属性及其类型的列表。
在这里插入图片描述
在这里插入图片描述
写请求(Write Request0x12)及写响应(Write Response0x13)用于请求服务器写入一个属性的值,并在Write Response中确认已经写入成功。
在这里插入图片描述
在这里插入图片描述

3.6 连接参数更新

连接参数主要包括最小连接间隔、最大连接间隔、从机潜伏周期和连接超时时间。在最大连接间隔内要有一次成功的数据交互,可以是空的PDU;在连接超时时间到达时如果没有一次成功的数据交互,则认为连接断开;从机潜伏周期为从机能忽略多少个主机的连接事件,用于从机达到更好的功耗。设置时最小连接间隔和最大连接间隔步进为1.25ms,范围7.5ms至4s(值6至3200),连接超时时间步进为10ms,范围100ms至32s(值10至3200)。

在未进行连接参数更新时,主机和从机之间使用主机设置的连接间隔来进行交互,默认最大连接间隔为30ms,最小连接间隔为7.5ms。
在这里插入图片描述

3.6.1 从机请求

L2CAP的CID为0x0005,连接参数更新请求代码为0x12。
在这里插入图片描述
连接参数更新由从机发起,格式为:
在这里插入图片描述
其中Identifier字段长度为1字节,响应与请求匹配,请求设备设置此字段,响应设备在其响应中使用相同的值。
在这里插入图片描述
从机请求的这些连接参数就是在GAP参数初始化gap_params_init函数中设置的值。

static void gap_params_init(void)
{
    ret_code_t              err_code;
    ble_gap_conn_params_t   gap_conn_params;
    ble_gap_conn_sec_mode_t sec_mode;

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);//连接模式,主要是是否需要加密

    err_code = sd_ble_gap_device_name_set(&sec_mode,
                                          (const uint8_t *)DEVICE_NAME,
                                          strlen(DEVICE_NAME));//设备名称设置
    APP_ERROR_CHECK(err_code);
										  
	err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_HID_MOUSE);

    memset(&gap_conn_params, 0, sizeof(gap_conn_params));//连接参数设置

    gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;//最小连接间隔
    gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;//最大连接间隔
    gap_conn_params.slave_latency     = SLAVE_LATENCY;//从设备延迟,从设备可以跳过连接事件
    gap_conn_params.conn_sup_timeout  = CONN_SUP_TIMEOUT;//两个成功的连接事件之间的最大间隔,超过后会认为连接丢失(100ms至32s之间)

    err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
    APP_ERROR_CHECK(err_code);
}

3.6.2 主机响应

主机响应格式:
在这里插入图片描述
其中Result定义:
在这里插入图片描述
在这里插入图片描述
连接参数更新完成后,主机和从机之间的连接间隔会以从机请求成功的值来运行,从机设置的最大连接间隔为200ms,最小连接间隔为100ms。
在这里插入图片描述
从机什么时候去更新连接参数是由自己决定的,在从机工程中conn_params_init函数中有设置first_conn_params_update_delay参数表示从连接后多久更新连接参数。ble_conn_params_init函数中会创建一个软件定时器来处理连接参数更新的过程。工程中FIRST_CONN_PARAMS_UPDATE_DELAY宏定义为20s。

static void conn_params_init(void)
{
    ret_code_t             err_code;
    ble_conn_params_init_t cp_init;

    memset(&cp_init, 0, sizeof(cp_init));

    cp_init.p_conn_params                  = NULL;//指向应用程序中设置的GAP连接参数,如果设置为NULL,则连接参数从主机获得
    cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;//初始化事件(连接或启动通知)到第一次连接参数更新的时间
    cp_init.next_conn_params_update_delay  = NEXT_CONN_PARAMS_UPDATE_DELAY;//第一次更新后,下次发起更新申请的间隔时间
    cp_init.max_conn_params_update_count   = MAX_CONN_PARAMS_UPDATE_COUNT;//放弃协商连接参数前最大重试次数
    cp_init.start_on_notify_cccd_handle    = BLE_GATT_HANDLE_INVALID;
    cp_init.disconnect_on_fail             = false;//设置为TRUE时如果连接参数更新失败,则会自动断开连接
    cp_init.evt_handler                    = on_conn_params_evt;//连接参数更新结果对应的处理事件
    cp_init.error_handler                  = conn_params_error_handler;//发生错误时的处理

    err_code = ble_conn_params_init(&cp_init);
    APP_ERROR_CHECK(err_code);
}

连接开始时间:
在这里插入图片描述
连接参数更新时间如下,时间间隔为20s:
在这里插入图片描述

3.7 数据交互

3.7.1 主机向从机写入数据

主机向从机写入数据需要用到写命令:
在这里插入图片描述
在这里插入图片描述

3.7.2 从机向主机通知

服务器可以随时发送属性值的通知。服务器也就是从机,客户端是主机。
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

基于Amlogic 安卓9.0, 驱动简说(二):字符设备驱动,自动创建设备

文章目录一、前言二、系列文章三、替换部分3.1 自动分配设备号3.2 自动创建设备四、解析:完整源码4.1 helloworld_amlogic_char_driver_auto_mknode.c4.2 Makefile五、编译执行(1)编译及部署(2)加载ko文件(…

HCIP作业三

文章目录一,建立拓扑图1,目的:实现全网可达二,在OSPF1区域1,所有路由器配置IP地址(包含OSPF100区域)2,进行O1的宣告,不能宣告ISP网段3,在O1区域的R3写缺省去I…

MIT6.830-2022-lab3实验思路详细讲解

文章目录一、实验概览二、实验过程成本估算(Cost Estimation):基数和选择率Exercise 1: IntHistogramExercise 2: TableStatsExercise 3: Join Cost EstimationExercise 4: Join Cost EstimationExtra Credit总结一、实验概览 对于这次lab&a…

尚医通-数据字典接口-前端列表(十三)

目录: (1)数据字典接口-需求和准备 (2)数据字典接口-列表 (3) 数据字典前端-列表 (1)数据字典接口-需求和准备 前面我们完成了医院设置模块的开发,现在来…

js数组篇

数组定义 var arr1new Array(33,44,55,66); var arr2[A,B,C,D]; var arr3new Array(4); 数组常用方法 splice()方法用于替换数组中的指定项 splice(3,2,X,Y,Z):从下标为3的项开始,连续替换2项 ,插入XYZ var arr[A,B,C,D,E,F,G]; arr.spl…

Java线程间通信机制 (等待唤醒机制)

1.1 线程间通信 概念:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同。 比如:线程A用来生成包子的,线程B用来吃包子的,包子可以理解为同一资源,线程A与线程B处理的动…

[JavaEE] Thread类及其常见方法

专栏简介: JavaEE从入门到进阶 题目来源: leetcode,牛客,剑指offer. 创作目标: 记录学习JavaEE学习历程 希望在提升自己的同时,帮助他人,,与大家一起共同进步,互相成长. 学历代表过去,能力代表现在,学习能力代表未来! 目录 1.Thread 的常见构造方法 2.Thread 的几个常见属性…

机器学习基石2(noise和error)

文章目录一、什么是noise?二、什么是error?三、常用error一、什么是noise? 我们之前的讨论都是一种理想化的说明,比如数据来源于目标函数fff,似乎我们手里拿到的数据是这样得来的,随机取一个输入&#xff0…

DOM算法系列009-判断给定节点是否为块级元素

UID: 20221227215215 aliases: tags: source: cssclass: created: 2022-12-27 块级元素 给定一个节点,如何判定它是否为块级元素呢? 首先,块级元素一定是元素节点,所以它的nodeType 1其次,我们思考,有什…

Redis分布式缓存、秒杀

目录一、单点Redis的问题二、RDB三、AOF四、Redis优化秒杀流程1、秒杀步骤:2、Redis优化秒杀步骤:3、秒杀的lua脚本4、调用秒杀的lua脚本5、通过线程池,操作阻塞队列五、基于Redis实现共享session登录NoSQL数据库进阶实战哪吒精品系列文章一、…

linux常用命令(二)-文件操作

文件创建 - touch 一般使用touch 来创建某个新增的文件 语法 touch [-acfm][文件名]a:改变档案的读取时间记录c:假如目的档案不存在,不会建立新的档案。与 --no-create 的效果一样。f:不使用,是为了与其他 unix 系统…

python的tkinter(图形用户界面)

目录标题什么是图形用户界面(GUI)Tinter函数和参数说明(常用)Lable(标签):效果Button(按钮)效果Entry(文本框)效果Text (多行文本框)Canvas(画布)效果Message(消息弹窗)效果什么是图形用户界面&…

kaggle学习笔记-otto-baseline4-本地CV的构建

总览 步骤 1 - 生成候选 对于每个测试用户,我们生成可能的选择,即候选人。、我们从 5 个来源生成候选人: 点击、购物车、订单的用户历史记录测试周期间最受欢迎的 20 次点击、购物车、订单具有类型权重的点击/购物车/订单到购物车/订单的共…

中国芯片奇才,仅用三年打破欧美垄断,创造奇迹

有这么一位中国人,打破了欧美长达10年的芯片技术垄断。这位最该追的星,她是谁?又是如何让欧美芯片领域闻风丧胆。早在2017年,芯片国产化已接近50%,然而25g以上芯片却仅有3%,该技术一直掌握在欧美等发达国家…

融云任杰:激活组织生命力 让听见炮火的人做决策 | TGO专访

任杰,融云联合创始人兼首席科学家,TGO 鲲鹏会(北京)学员;曾就职于微软和神州泰岳等公司,在微软两次获得全球杰出员工奖,曾负责中国联通搭建 WAP 网关、增值业务管理平台;在神州泰岳期…

数据结构(线性表及顺序表)

目录 线性表 线性结构定义 常见线性结构 线性表 顺序表及其实现 顺序结构 顺序表的存储映像图 顺序表seqList及操作的定义(seqList.h) 顺序表基本操作的实现分析 查找操作 实现代码 插入操作 实现代码 删除操作 实现代码 顺序表应用——…

手绘图说电子元器件-集成电路

集成电路是高度集成化的电子器件,具有集成度高、功能完整、可靠性好、体积小、重量轻、功耗低的特点,已成为现代电子技术中不可或缺的核心器件。 集成电路可分为模拟集成电路和数字集成电路两大类,包括集成运放、时基集成电路、集成稳压器、门电路、触发器、计数器、译码器…

【 uniapp - 黑马优购 | 分类界面 】创建cate分支、数据获取、动态渲染

个人名片: 🐼作者简介:一名大二在校生,讨厌编程🎋 🐻‍❄️个人主页🥇:小新爱学习. 🐼个人WeChat:hmmwx53 🕊️系列专栏:&#x1f5bc…

【Lilishop商城】No4-4.业务逻辑的代码开发,涉及到:会员B端第三方登录的开发-web端第三方授权联合登录接口开发

仅涉及后端,全部目录看顶部专栏,代码、文档、接口路径在: 【Lilishop商城】记录一下B2B2C商城系统学习笔记~_清晨敲代码的博客-CSDN博客 全篇会结合业务介绍重点设计逻辑,其中重点包括接口类、业务类,具体的结合源代…

机器学习——支持向量机(SVM)

文章目录1. 优化目标2. 大间距的直观理解3. 大间距分类背后的数学支持向量机(Support Vector Machines)是广泛应用于工业界和学术界的一种监督学习算法,在学习复杂的非线性方程时提供了一种更为清晰,更加强大的方式。下面从SVM的优…