蓝牙系列十一:HCI层的数据格式

HCI层作为Host和Controlor链接的接口存在。以下是对HCI层的数据格式的解析。

1、参考:蓝牙协议core_v5.0.pdf 《Vol 2: Core System Package [BR/EDR Controller volume]》的“Part E: Host Controller Interface Functional Specification”

2. 协议栈框图

对于被动扫描,周边的外设会给controller发送各种广播包,解析广播包,从而得到设备的信息。

对于主动扫描,除了被动的获得广播包外,controller还可以给某个设备发出扫描请求,设备就会返回一个扫描回应,将更多的信息给controller。

两个蓝牙设备互相通信,涉及两个Controller。Controller是具备一定智能的,它可以自行决定做什么事情:不需要Host决定它的每一个细节。比如说:要想让Controller发出扫描请求(SCAN REQ),Host只需要向Controller发出一个“scan enable”的命令即可,Controller就会根据预设的参数自动发出扫描请求(SCAN REQ)广播包。

Controller就是一个芯片,它封装了LL层、PHY层那些复杂的操作;Host不需要理解芯片内部复杂的操作,只需要遵守Controller的规范,向它提供command,从它获得event,与它交互acl data。

HCI层跟LL层的关系:

a. 有些HCI command只是用来设置本地Controller,不导致无线传输

b. 有些HCI command会导致LL层发出各类广播包,

   比如“LE Set Scan Enable Command”在主动扫描时会导致LL层发出SCAN_REQ广播包,

   比如“LE Create Connection Command”会导致LL层发出CONNECT_REQ广播包

c. 有些HCI command会导致LL层发出数据包,其中的LLID=11b,表示是“LL Control PDU”,

   比如“LE Read Channel Map Command”就会导致LL层发数据给对端设备,以便读取对端设备的信道图。

d. ACL Data是必定导致LL层发数据给对端设备的,

这时的LL层数据,有可能是起始包,LLID=10b;

也可能是延续包,LLID=01b;

也可能是空包,LLID=01b

在上一篇博客里,在传递Command/Event/ACL Data这3类数据时:

1. 对于UART接口的Controller,会在数据前面加上1字节的头部用来分辨是哪一类数据

2. 对于USB接中里的Controller,每类数据对应一个Endpoint,数据会直接发给Endpoint

下面,介绍Command/Event/ACL Data这3类数据的格式。

一、Command格式:

Command前有2字节的头部OpCode,用来表示是哪一个Command。

OGF表示“OpCode Group Field”,即“哪一组命令”,它占据高6位。

OCF表示“OpCode Command Field”,即“这组里的哪一个命令”,它占据低10位。

在蓝牙协议里,每一个OGF用一节来描述,在这节里会描述该组(OGF)的所有命令(OCF),位置如下图:

BTStack示例:

btstack-master\src\hci_cmd.c

 12211分别表示1个字节用来表示扫描类型、2个字节用来表示扫描间隔、2个字节用来表示scan_window、1个字节用来表示own_address_type、1个字节用来表示scanning_filter_policy。

以后发送命令的时候,就需要根据12211这个格式来组装这些参数。在代码中搜索hci_le_set_scan_parameters.

hci_send_cmd(&hci_le_set_scan_parameters, 1, 0x1e0, 0x30, hci_stack->le_own_addr_type, 0);

代码中和文档中OCF的值刚好对应,正好是B。

 再来看一个例子:

 它带有两个参数,每个参数占一个字节,即hci_stack->le_scanning_enabled占一个自己;0占一个字节

 其他的命令也是类似的,具体需要查看蓝牙文档core_5.0

二、Event格式:

在官方协议中对于Event并没有明确的分类,按我的理解可以分为以下3类:

Event分类

说明

Command Status Event

命令状态事件,

表示控制器已经接收到命令并正在处理

Command Complete Event

命令完成事件,

表示命令已经处理完毕并返回结果

Advertising Report Event

广播上报事件,本Event是Controller主动上报的

而上述2个Event都是由command导致的

示例:

有些命令需要一定时间才能执行完,比如LE Create Connection命令。控制器接收到该命令后会首先返回一个“命令状态事件”,随后等待连接建议完成或者失败,再返回“命令完成事件”。

Event的格式:

三、ACL Data格式:

ACL Data是传递给对端设备的数据,在建立连接之后才可以传输ACL Data,格式如下:

Handle表示对端设备:主设备的Controller要与对端设备连接时,会生成一个32位的随机数,它被称为Access Address。在LL层的数据包中,Access Address被用来表示对端设备。但是Host程序并不想使用这个32位的数据,于是Controller又分配一个12位的Handle来表示这个Access Address、表示对端的设备。

Packet_Boundary_Flag:

PB Flag

描述

Host to Controller

Controller to Host

00b

L2CAP PDU起始包

P

01b

L2CAP PDU延续包

P

P

10b

L2CAP PDU起始包

P

Controller在传输ACL Data时,每次传输的字节数是有限制的,这可以通过“Read Buffer Size”命令读到这个值。

当要传输非常大的ACL Data时,需要把数据拆分来传输,这就要用到上面表格中的“PB Flag”来分辨起始包、延续包。

这些起始包、延续包由Host送到Controller后,会马上通过LL层重新编码、发给PHY层发给对端设备,对端设备的L2CAP层再把这些起始包、延续包组装起来。

注意,在LL层的数据包里有LLID域,10b表示起始包、01b表示延续包。

Broadcast_Flag在BLE协议中都是00b,表示“Point-to-point”。

四、示例:

Broadcast_Flag在BLE协议中都是00b,表示“Point-to-point”。

1. 扫描设备

a. Host向Controller发出“LE Set Scan Parameters Command”

b. Controller向Host发送“Command Complete Event”

c. Host向Controller发出“LE Set Scan Enable Command”

d. Controller向Host发送“Command Complete Event”

e. 如果扫描参数为“主动扫描”,对于新发现的设备会,LL层发出“SCAN REQ”广播包

f. Controller接收到各类广播包,比如ADV_IND、SCAN_RSP

   LL层解析后,会通过HCI上报EVENT

2. 连接设备

a. Host向Controller发出“LE Create Connection Command”

b. 不需要对端设备回应数据,发起方就认为连接已经建立

c. Controller向Host发送“Command Status Event”

d. Controller向Host发送“Command Complete Event”

3. 写数据

a. Host向Controller发出ACL数据:Write Command, Handle….

b. Controller的LL层构造数据包(LLID=10b),通过PHY发出无线信号

c. Controller向Host发送“Number of Completed Packets”事件

4. 读数据

a. Host向Controller发出ACL数据:Read Request, Handle….

b. Controller的LL层构造数据包(LLID=10b),通过PHY发出无线信号

c. Controller向Host发送“Number of Completed Packets”事件

d. 对端设备的LL层通过PHY返回数据(LLID=10b)

e. Controller向Host发送ACL数据:Read Response

 问题:右边抓取的空中数据包,在对端设备接收到读请求后,过了一会才回复一个无线信号给本地设备,中间有很多空包,这些空包是谁发起的呢?

是由master发给slave的,

这些空包起什么作用呢?

两个设备建立连接之后,本地设备要知道对端设备什么时候要断开,它是怎么判断对端设备有没有断开呢?

不断的发送空包给对端设备,对端设备收到空包后,要回复一个空包,这样本地设备才知道对端设备还没有断开。当然为了省电,对端设备没有必要每次收到空包都要回复,可以在收到几个空包后回复,但是一定要有回复。这些空包是是由controller自主发起的,与host层没有什么关系。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux:kubernetes(k8s)pod的基础操作(6)

Linux:kubernetes(k8s)允许在任意节点使用kubectl命令(5)-CSDN博客https://blog.csdn.net/w14768855/article/details/136460090?spm1001.2014.3001.5501 我在前两张进行了基础环境的一系列搭建,现在就正…

NIFI从Oracle11G同步数据到Mysql_亲测可用_解决数据重复_数据跟源表不一致的问题---大数据之Nifi工作笔记0065

首先来看一下整体的流程: 可以看到了用到了上面的这些处理器,然后我们主要看看,这里之前 同步的时候,总是出现重复的数据,奇怪. 比如源表中只有166条数据,但是同步过去以后变成了11万条数据了. ${db.table.name:equals(table1):or(${db.table.name:equals(table2)})} 可以看…

职场成功的关键:积极主动,勇于担当

在职场中,每个人都渴望成功。然而,成功并非一蹴而就,而是需要我们在日常工作中不断积累、锻炼和提升。本文将为您揭示职场成功的关键因素,帮助您在职场道路上越走越远。 一、积极主动,主动承担责任 在职场中&#xff0…

吴恩达机器学习笔记十六 如何debug一个学习算法 模型评估 模型选择和训练 交叉验证测试集

如果算法预测出的结果不太好,可以考虑以下几个方面: 获得更多的训练样本 采用更少的特征 尝试获取更多的特征 增加多项式特征 增大或减小 λ 模型评估(evaluate model) 例如房价预测,用五个数据训练出的模型能很好的拟合这几个数据&am…

RocketMQ入门指南:从零开始学习分布式消息队列技术

RocketMQ 1. MQ介绍1.1 为什么要用MQ1.2 MQ的优点和缺点1.3 各种MQ产品的比较 2. RocketMQ快速入门2.1 准备工作2.1.1 下载RocketMQ2.2.2 环境要求 2.2 安装RocketMQ2.2.1 安装步骤2.2.2 目录介绍 2.3 启动RocketMQ2.4 测试RocketMQ2.4.1 发送消息2.4.2 接收消息 2.5 关闭Rocke…

【Python】科研代码学习:七 TrainingArguments,Trainer

【Python】科研代码学习:七 TrainingArguments,Trainer TrainingArguments重要的方法 Trainer重要的方法使用 Trainer 的简单例子 TrainingArguments HF官网API:Training 众所周知,推理是一个大头,训练是另一个大头 之…

【PyTorch实战演练】深入剖析MTCNN(多任务级联卷积神经网络)并使用30行代码实现人脸识别

文章目录 0. 前言1. 级联神经网络介绍2. MTCNN介绍2.1 MTCNN提出背景2.2 MTCNN结构 3. MTCNN PyTorch实战3.1 facenet_pytorch库中的MTCNN3.2 识别图像数据3.3 人脸识别3.4 关键点定位 0. 前言 按照国际惯例,首先声明:本文只是我自己学习的理解&#xff…

【Qt学习笔记】(二)--第一个程序“Hello World”(学习Qt中程序的运行、发布、编译过程)

声明:本人水平有限,博客可能存在部分错误的地方,请广大读者谅解并向本人反馈错误。    因为我个人对Qt也是有一些需求,所以开设本专栏进行学习,希望大家可以一起学习,共同进步。   这篇博客将从一个 He…

算法刷题Day1 | 704.二分查找、27.移除元素

目录 0 引言1 二分查找1.1 我的解题1.2 修改后1.3 总结 2 移除元素2.1 暴力求解2.2 双指针法(快慢指针) 🙋‍♂️ 作者:海码007📜 专栏:算法专栏💥 标题:代码随想录算法训练营第一天…

Vue.js+SpringBoot开发大病保险管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统配置维护2.2 系统参保管理2.3 大病保险管理2.4 大病登记管理2.5 保险审核管理 三、系统详细设计3.1 系统整体配置功能设计3.2 大病人员模块设计3.3 大病保险模块设计3.4 大病登记模块设计3.5 保险审核模块设计 四、…

MySQL三种日志

一、undo log(回滚日志) 1.作用: (1)保证了事物的原子性 (2)通过read view和undo log实现mvcc多版本并发控制 2.在事务提交前,记录更新前的数据到undo log里,回滚的时候读…

数据可视化助力林业智能管理

数据可视化是当下科技发展中的一项重要工具,它在各行各业都展现了强大的应用价值。在智慧林业领域,数据可视化更是发挥了独特的作用,为林业管理和生态保护提供了有效的支持和解决方案。下面我就以可视化从业者的角度,来简单聊聊这…

四节点/八节点四边形单元悬臂梁Matlab有限元编程 | 平面单元 | Matlab源码 | 理论文本

专栏导读 作者简介:工学博士,高级工程师,专注于工业软件算法研究本文已收录于专栏:《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现,并提供所有案例完整源码;2.单元…

关于yolov8的DFL模块(pytorch以及tensorrt)

先看代码 class DFL(nn.Module):"""Integral module of Distribution Focal Loss (DFL).Proposed in Generalized Focal Loss https://ieeexplore.ieee.org/document/9792391"""def __init__(self, c116):"""Initialize a convo…

嵌入式C语言(六)

对齐这个事情在内核中可不是个什么小事,内核中涉及到内存方面的都需要非常的谨慎。 上一篇我们知道了可以通过__attribute__来声明属性,也知道了section这个属性,这篇我们来看看关于内存对齐使用的两个属性–>aligned和packed 地址对齐&…

Altium Designer如何对走线模式进行切换

AD软件提供了比较智能的走线模式切换功能,可以根据个人习惯进行切换,能有效的提高了PCB设计效率。 点击界面右上角系统参数的图标 或者在pcb界面中使用快捷键OP进入到优选项界面,然后选中 PCB Editor-Interactive Routing,在布线…

ubuntu設定QGC獲取pixhawk Mini4(PX4 Mini 4) 的imu信息

ubuntu20.04 QGC使用v4.3.0的版本 飛控pixhawk Mini4 飛控上只使用一條micro USB連接電腦,沒有其他線 安裝命令 sudo apt-get remove modemmanager -y sudo apt install gstreamer1.0-plugins-bad gstreamer1.0-libav gstreamer1.0-gl -y sudo apt install libf…

Vue:纯前端实现文件拖拽上传

先看一下拖拽相关的事件:dragover、dragenter drop和dragleave 。 dragover事件:当被拖动的元素在一个可放置目标上方时,该事件会被触发。 通常,我们会使用event.preventDefault()方法来取消浏览器默认的拖放行为,以便…

amv是什么文件格式?如何播放amv视频?

AMV文件格式源自于中国公司Actions Semiconductor,最初作为其MP4播放器中使用的专有视频格式。产生于数码媒体发展的需求下,AMV格式为小屏幕便携设备提供了一种高度压缩的视频存储方案。 AMV文件格式的主要特性与使用场景 AMV格式以其独特的特性在小尺寸…

复合式统计图绘制方法(7)

复合式统计图绘制方法(7) 常用的统计图有条形图、柱形图、折线图、曲线图、饼图、环形图、扇形图。 前几类图比较容易绘制,饼图环形图绘制较难。 在统计图的应用方面,有时候有两个关联的统计学的样本值要用统计图来表达&#xff0…