蓝牙BLE学习

news2024/12/26 23:08:46

1. 简介

1.1 蓝牙发展历程

      蓝牙,直接来自于一位国王的名字--King Harald ‘Bluetooth' Gromsson。这位国王因两件事留名于史,其一是在公园958年统一了丹麦和挪威,其二是在其死后,其牙齿呈现出暗蓝色的颜色,因而得名蓝牙为绰号。而蓝牙联盟之所以选择它作为联盟的名字,则是看中了King Harald在统一丹麦和挪威上的贡献。联盟希望,该技术能够像他一样,将PC和无线产业用短距离无线传输连接在一起。

      人们日常使用的蓝牙,是在1996年由英特尔、爱立信和诺基亚共同发起而成立的联盟,意在为短距离无线传输制定标准,低功耗、低成本的无线通信连接的方法,以支持不同产品和行业之间的连通与协作

  • 第一代蓝牙主要是指90年代的V1.0~V1.2版本,是关于段距离通信的早期探索,此时还存在许多问题,应用不是特别广泛
  • 第二代蓝牙主要是00年中V2.0~V2.1版本,新增了EDR(Enhanced Data Rate)技术提高传输速率,以及体验及安全
  • 第三代蓝牙主要是00年末V3.0版本,新增了802.11 WiFi协议,引入了AMP(Generic Alternate MAC/PHY)交替射频技术,极大的提高了传输速率并降低功耗
  • 第四代蓝牙是10年以来的V4.0~V4.2版本,主推LE(Low Energy)低功耗,大约仅消耗十分之一,将三种规格,包括经典蓝牙、高速蓝牙、和蓝牙低功耗,集中在一起形成一套综合协议规范
  • 第五代蓝牙是16年开始提出的V5.0版本,主要是为了支持物联网,在功耗、传输速率、有效传输距离、数据包容量方面都做了极大的提升

1.2 蓝牙技术概述

      蓝牙分为经典蓝牙(BT-Bluetooth)和低功耗蓝牙(BLE-Bluetooth Low Energy)。这两套原理和实现都不一样,也无法实现互通。

Basic Rate(BR)/AMP

       最初的蓝牙技术,包括可选的EDR(Enhanced Data Rate)技术和交替使用的MAC层和PHY层扩展 AMP(Alternate MAC and PHY layer extension)【优化传输速度的过程】

       蓝牙诞生之初使用的BR技术,传输速率很低,随着发展而变得无法支持,所以引入了EDR,这时还没有修改软硬件架构,但是之后又落伍了,所以直接引入了WiFi的底层协议,也就是MAC/PHY扩展,但这部分的实现就无法直接更替,所以BR/EDR只能与AMP交替使用。

       经典蓝牙主要用于数据量较大的传输,如蓝牙耳机/音箱等

Low Energy(LE)

      蓝牙低功耗,则不关心传输速率,而是从降低功耗的角度实现的另一套技术,跟前面的协议没有丝毫关系。

      BLE分了很多个版本,现在用的比较多的就是4.2和5.X。那4.2到5.0之间有哪些升级呢?首先,4.2版本传输速度只有1Mbps,广播包最大长度为31字节。而5.0版本开始,传输速度就已经增加到2Mbps了,并且广播包的最大长度也增加为254字节。除此之外,5.X版本还增加了Mesh的功能,且通讯距离也增加至300米以上。

2. 蓝牙架构

       蓝牙协议将蓝牙整体分成了两层架构,底层是核心协议,描述了蓝牙核心技术的基础和规范,应用层协议则基于具体需求,使用核心协议提供的机制,实现不同的功能策略

       核心协议包含两部分,Host和Controller,这两部分在不同的蓝牙协议版本中略有区别,但大致上是,Controller完成硬件侧的规范制订,包括信号调制解调,会抽象出用于通信的逻辑链路,可能存在一个或多个,如LE Controller、BR/EDR Controller;Host则在逻辑链路的基础上完成更友好的封装,屏蔽掉技术细节,方便应用层对数据的使用。

2.1 蓝牙协议

2.1.1 应用层

应用层(App Layer)为不同场景定义规范,提出Profile(一项服务)的概念,实现各种应用功能

2.1.2 主协议层

L2CAP(Logical Link Control and Adaptation Protocol Layer)

      L2CAP对LL进行了一次简单的封装,LL只关心传输的数据本身,L2CAP就要区分是加密通道还是普通通道,同时还要对连接间隔进行管理。

  • 逻辑链路控制和适配协议,负责管理逻辑链路,使得不同应用可共享一个逻辑链路,类似端口的实现
  • 在逻辑链路的基础上,抽象出与具体技术无关的数据传输信道,如单/广播,然后对上以L2CAP channel endpoints的概念,为不同应用程序提供独立的传输通道
  • 逻辑控制和适配协议的工作就是实现逻辑信道的多路复用(multiplexing),对上层数据进行分割和重组,以及后续的流控、错误控制和重传等
  • 多路复用思想:将要发送的数据分割成一个个数据包(Packet Data Unit,PDU),添加包含特定ID的头部,接收方解析头部ID进行重组
  • 多路复用实现
  • 基于连接:L2CAP会为每个逻辑信道分配一个编号(Channel ID,CID),有些CID会有固定用途.

GAP层(Generic access profile-通用访问配置文件)

       GAP是对LL层payload(有效数据包)如何进行解析的两种方式的一种,而且也是最简单的一种。GAP简单的对LL payload进行一些规范和定义,因此GAP能实现的功能极其有限。GAP目前主要用来进行广播扫描发起连接

  • 通用访问配置文件,定义了蓝牙设备的通用的访问功能,与GATT的数据通信过程对应,处理无连接连接建立过程的通信,也就是为广播、扫描、发起连接这些过程定义统一规范
  • 定义了用户接口的基本参数,包括蓝牙地址、名称、pincode、class等概念
  • 定义了设备的角色:
  1. Broadcaster Role:正在发送advertising events的设备
  2. Observer Role:正在接收advertising events的设备
  3. Peripheral Role:接受Link Layer连接的设备(对应Link Layer的slave角色)
  4. Central Role,发起Link Layer连接的设备(对应Link Layer的master角色)
  • 定义了通信的过程和操作模式:
  1. Broadcast mode and observation procedure:实现单向的、无连接的通信
  2. Discovery modes and procedures:实现蓝牙设备的发现操作
  3. Connection modes and procedures:实现蓝牙设备的连接操作
  4. Bonding modes and procedures:实现蓝牙设备的配对操作

SMP(Secure manager protocol-加密管理协议)

       SMP用来管理BLE连接的加密和安全。如何保证连接的安全性,同时不影响用户的体验,这些都是SMP要考虑的工作。

ATT(Attribute protocol-属性协议)

       简单来说,ATT层用来定义用户命令及命令操作的数据。比如读取某个数据或者写某个数据。BLE协议栈中,开发者接触最多的就是ATT。BLE引入了attribute概念,用来描述一条一条的数据。Attrubute除了定义数据,同时定义该数据可以使用的ATT命令,因此这一层被称为ATT层。

  • 属性协议主要是针对物联网场景,核心思想就是将采集的信息或控制的命令以属性的形式抽象出来,提供接口供远端设备读写
  • 采用C/S形式,信息提供方为ATT Server,如传感器,访问方为ATT Client
  • 为每个Attribute定义了三个属性
  1. Type,即Attribute的类型,使用UUID区分
  2. Handle,服务端用来唯一标识Attribute的16-bit数值
  3. Value,Attribute的值
  • 为每个Attribute定义了一系列权限,方便服务端控制客户端的行为,包括访问/加密/认证/授权
  • 对于不同的Attribute,客户端对服务端的访问方式也不一样,包括Find/Read/Write
  • 传输过程是在L2CAP的基础上,使用基于通道的多路复用,CID为0x0004

GATT(Generic attribute profile-通用属性配置文件)

      GATT用来规范attribute中的数据内容,并运用group(分组)的概念对attribute进行分类管理。没有GATT,BLE协议栈也能跑。但互联互通就会出问题,也正是因为有了GATT和各种各样的应用profile,BLE摆脱了Zigbee等无线协议的兼容性困境,成为了出货量最大的2.4G无线通信产品。

  • 通用属性配置文件,Attribute只是将信息(或者说通信数据)做一下抽象,但是真正对抽象的信息做分类管理则是GATT来完成,形成profile的概念(解决了很多无线协议的兼容问题),profile可以理解成应用场景或者使用方式
  • GATT提供了这样一种通用的、信息存储与共享的profile framework,实现BLE双向通信
  • GATT的层次结构

  • Profile位于最顶层,不是真正存在的配置文件,而是一个或多个场景相关的service的抽象集合
  • Service(服务)是一种行为的抽象,具有唯一标识UUID,每个service包含一个或多个Characteristic,也可以通过include的方式包含其他service
  • Characteristic(特征)可以理解成一个属性,是真正与设备通信相关的,数据发送和接收的最基本单位,通过对特征的读写实现蓝牙双向通信,它由一个Propertities(定义Value的使用规范和Descriptor的访问规范)、一个Value(特征的实际取值)和一个或多个Descriptor(Value相关的描述信息)组成,每个特征也具有自己的唯一标识,但是有三种形式:
  1. 16-bit是官方认证,收费,Bluetooth_Base_UUID 为 00000000-0000-1000-8000-00805F9B34FB
  2. 16-bit转128-bit,格式为 0000xxxx-0000-1000-8000-00805F9B34FB
  3. 32-bit转128-bit,格式为 xxxxxxxx-0000-1000-8000-00805F9B34FB
  • 事实上,目前几乎所有的BLE应用都基于GATT实现通信
  • GATT通信基于C/S模型,外围设备作为Server端,维护ATT结构及产出数据,中心设备作为client端,请求连接获取数据
  • GATT连接对外围设备是独占的,即一个外围设备同时与一个中心设备建立连接,一个中心设备可同时与多个外围设备建立连接.

2.1.3 控制层

物理层(Physical Layer)

     PHY层用来指定BLE所用的无线频段,调制解调方式和方法等。PHY层做的好不好,直接决定了BLE芯片的功耗、灵敏度等射频指标。

  • 负责提供数据传输的物理通道
  • 物理链路(Physical Link):对物理信道的进一步封装
  • 物理信道(Physical channel):三种蓝牙技术都使用相同的频段和频率范围,但是具体实现都不一样
  • Advertisement Broadcast Channel:用于设备间无连接广播通信,包括发现/连接操作
  • Piconet channel:用于连接状态下通信
  • Inquiry Scan Physical Channel:用于发现操作,即搜索/被搜索
  • Page Scan Physical Channel:用于连接操作,即连接/被连接
  • Basic Piconet Physical Channel:用于连接状态下通信,使用79个跳频点
  • Adapted Piconet Physical Channel:用于连接状态下通信,使用较少RF跳频点
  • Synchronization Scan Channel:用于无连接的广播通信
  • BR/EDR频段分成了79个channel,每个占1M带宽;采用跳频技术(Hopping),即物理信道随机占用某一channel;定义了五种物理信道,每次只能在一种物理信道上通信,采用时分方式
  • AMP直接使用WIFI的物理层规范,只有一个物理信道,用于已连接设备之间的高速数据通信
  • LE频段分成了40个channel,每个占2M带宽;有两种物理信道,每次只能在一种物理信道上通信,采用时分方式

LL层(Link Layer-链路层)

       LL层是整个协议栈的核心。LL层要做的事情非常多,比如具体选择哪个射频通道进行通信。怎么识别空中数据包。具体在哪个时间点把数据包发送出去。怎么保证数据的完整性。ACK如何接收。如何进行重发。以及如何对链路进行管理和控制等等。LL层只负责把数据发送出去或者接收回来,对数据进行怎样的解析则由GAP或ATT来负责。

  • 解决在有限物理信道上传输远多实际信道数量的数据,即信道共享,然后为通信实体创建看似独享的逻辑信道,以及解决传输过程中的校验、重传等问题
  • LL中的信道设计:BLE系统基于通信场景,在40个物理信道中选取三个作为广播信道,处理数据量小、发送不频繁、时延不敏感的场景,存在的问题就是不可靠、效率低、不安全;另外的场景则在剩下的37个信道中选取一个为双方建立单独信道,并且为了抗干扰采用跳频技术
  • 为此,LL为通信双方实体定义了以下状态及切换条件

  - Standby:初始状态,不收发数据,接受上层协议命令与其他状态切换
  - Advertising:通过广播发送数据的状态,建立连接后可进入Connection
  - Scanning:接收广播的数据的状态
  - Initiating:特殊的接收状态,类似Scanning,接收Advertiser广播的连接数据,建立连接后进入Connection
  - Connection:建立连接后拥有单独的通道

  • 这里会使用空中接口协议(Air Interface Protocol,AIP)来负责实体之间的数据交换和状态切换

HCI(Host controller interface)

      HCI是可选择的。HCI主要用于2颗芯片实现BLE协议栈的场合,用来规范两者之间的通讯协议和通信命令等。 

 说明:

      ATT和GATT的关系就像车辆和交通规则一样。ATT就是车辆,而GATT就是规范车辆该如何行驶的交通规则。只有GATT存在的时候,多个ATT见面才知道该如何行驶,到底是拐弯让直行还是坐车道超车。

      从上边的名字可以看到,主要分为protocol和profile。其中L2CAP、SMP、ATT属于protocol,而GAP和GATT属于profile。

      profile和protocol有什么区别呢? 在蓝牙核心规范(Bluetooth Core Specification)中,profile的定义不同于protocol的定义。Protocol被定义为各层协议。而Profile从使用蓝牙核心规范中各层协议的角度,定义蓝牙应用互操作性的实现。Profile定义Protocol中的可用特性和功能,以及蓝牙设备互操作性的实现,使蓝牙协议栈适用于各种场景的应用开发。

      在蓝牙核心规范中,Profile和Protocol的关联如下图

      Profile由红色矩形框表示,包括GAP、Profile#1、Profile#2和Profile#3。蓝牙核心规范中的Profile分为两种类型:GAP,途中红色矩形框所示的GAP;基于GATT的Profile,图中红色矩形框所示的Profile#123。

3. 连接和通信

       蓝牙的通信是双向的,为了创建和维护一个BLE通信连接,在蓝牙中引入了“角色”这一概念,一个BLE设备不是主机(集中器)就是从机(外围设备)角色,这是根据是谁发起这个连接来确定的。主机(集中器)设备总是连接的发起者,而从机(外围设备)总是被连接者。整个访问与连接过程都是在GAP(Generic Access Profile-通用访问规范)进行实现的。

3.1 BLE 蓝牙数据包

3.1.1 信道

     BLE的物理通道即“频道,分别是‘f=2402+k*2 MHz, k=0, … ,39’,带宽为2MHz”的40个RF Channel。其中,有3个信道是advertising channel(广播通道),分别是37、38、39,用于发现设备(Scanning devices)、初始化连接(initiating a connection)和广播数据(broadcasting date);其他的37个信道为data channel(数据通道),用于两个连接的设备间的通讯。

3.1.2 数据包格式

       在低功耗蓝牙规范中,数据包格式分广播报文和数据报文两种。

       广播报文:设备发现、连接建立、传输广播

       数据报文:自适应跳频以及设备间数据传输

      设备利用广播报文发现、连接其它设备,而在连接建立之后,便开始使用数据报文。无论是广播报文还是数据报文,链路层只使用一种数据包格式。

     它由“前导码”(preamble)、“访问码”(access code)、”有效载荷“和”循环冗余校验“(Cyclical Redundancy Check,CRC)校验码组成。其中,”访问码“又称为”访问地址/接入地址“(access address)。

 

      前导码:1个字节长度,接收中用于频率同步、数据速率同步、自动增益控制调整。前导是一个8比特的交替序列。对于在LE 1M物理层上发送的数据包前导码为8比特;对于在LE 2M物理层上发送的数据包前导码为16比特。不是01010101就是10101010,取决于接入地址的第一个比特。
若接入地址的第一个比特为0:01010101
若接入地址的第一个比特为1:10101010

      访问地址:4个字节长度,访问地址有两种类型(广播访问地址和数据访问地址)
广播访问地址:固定为0x8E89BED6,在广播、扫描、发起连接时使用。
数据访问地址:随机值地址,不同的连接有不同的值。在连接建立之后的两个设备间使用。

     PDU(Protocol Data Unit): 数据载荷

     CRC:数据循环冗余校验

 3.2 BLE广播

3.2.1 使用场景

  • 单向、无连接的数据通信,发送者使用广播信道发送数据,接受者扫描接收数据
  • 连接建立阶段

3.2.2 协议层次

GAP:以应用程序角度进行功能封装,提供一套统一的、通用的广播规范

HCI:将LL提供的功能抽象成Command/Events的形式,供上层使用

LL:负责广播通信相关功能的定义和实现,包括信道选择、链路状态定义、PDU定义、设备过滤机制等

3.2.3 LL

  • 信道选择。BLE将蓝牙频段分成了40个物理信道,综合考虑(抗干扰等)后将其中三个作为广播信道,频段为0/12/39,编号是37-39
  • 链路状态。参与广播的BLE设备,总是处于这三种状态之一

Advertising:广播状态,周期性地广播,数据发送方

Scanning:扫描状态,扫描并接受广播数据,数据接收方

Initiating:初始化状态,扫描到可连接的广播时,发起连接请求,连接发起方

广播PDU

        Type是指PDU的类型,如不同的状态下也有不同的消息类型,TxAdd和RxAdd都是地址类型flag,针对不同的type有不同的含义,RFU都是保留字段,Length标明payload的长度.

PDU typePDU nameDescription

Physical 

Channel

Permitted PHYs
LE 1MLE 2MLE coded
0000bADV_IND

常规广播,可连接可扫描

【后续建立点对点连接,监听CONNECT_REQ请求】

Primary

0001bADV_DIRECT_IND

点对点连接,已知双方蓝牙地址,无广播数据,可被指定设备连接不可扫描

【快速建立连接,不关心广播数据,监听CONNECT_REQ请求】

Primary
0010bADV_NONCONN_IND

同ADV_IND,不可连接不可扫描

【用于定时传输简单数据】

Primary
0011bSCAN_REQ

接收ADV_IND/ADV_SCAN_IND后,请求更多信息

【接收广播数据后请求更多信息】

Primary
AUX_SCAN_REQSecondary
0100bSCAN_RSPSCAN_REQ的响应,返回更多信息Primary
0101bCONNECT_REQ

接收ADV_IND/ADV_DIRECT_IND后,请求建立连接

【请求建立连接】

Primary
AUX_CONNECT_REQSecondary
0110bADV_SCAN_IND

同ADV_IND,不可连接可扫描

【用于传输额外数据,监SCAN_REQ请求】

Primary
0111bADV_EXT_INDPrimary
AUX_ADV_REQSecondary
AUX_SCAN_RSPSecondary
AUX_SYN_INDSecondary
AUX_Chain_INDSecondary
1000bAUX_CONNECT_RSPSecondary

Payload

ADV_IND

      这个比较经典和常用的 ADV PDU 了,它代表了咱们发出去的这个 ADV 包,是一个可连接的,并且可扫描的广播包。什么是可连接呢?意思是,我发出去这个包,别人想连接我,OK,没问题。可扫描指的是,有人处于 Scanning 状态,收到我的这个 ADV_IND 后,对端发起 SCAN_REQ,咱们回复他 SCAN_RSP。

       AdvA:本机地址 48bits

      AdvData:携带的数据 0 - 31 字节

ADV_DIRECT_IND 

       顾名思义,咱们可以知道这种类型的数据包,是可连接的并且带指向性的(不可扫描),什么叫指向性呢,也就是,我指着对端的鼻子说,我这个包是专门给你准备的(来连接我啊)。所以这个包携带了本机地址和指着的那个地址。同时不允许携带数据: 

      AdvA:本机地址 48bits

     TargetA:对端地址 48bit

ADV_NONCONN_IND

        这种类型的 ADV PDU,属于不可连接,不可扫描,不定向的 ADV 包,包含了本机地址和数据(类似于,在空中散布谣言类型)

    AdvA:本机地址 48bits

    AdvData:携带的数据 0 - 31 字节

ADV_SCAN_IND

    这种类型的 ADV PDU 是只能扫描的不定向的,不连接的 ADV

    AdvA:本机地址 48bits

   AdvData:携带的数据 0 - 31 字节

BLE设备地址类型:

     TxAdd:发送地址字段

     RxAdd:接收地址字段

      发送地址字段和接收地址字段指示了设备使用公共地址(Public Address)还是随机地址(Random Address)。公共地址和随机地址的长度一样,都包含6个字节共48位。BLE设备至少要拥有这两种地址类型中的一种,当然也可以同时拥有这两种地址类型。

       1. 公共地址(Public Address)

       公共地址由两部分组成,如下图。公共地址由制造商从IEEE申请,由IEEE注册机构为该制造商分配的机构唯一标识符OUI(Organizationally Unique Identifier)。这个地址是独一无二,不能修改的。

       2. 随机地址

      随机地址有包含两种:静态地址(Static Device Address)和私有地址(PrivateDevice Address)。

        静态地址有如下要求:

       a)静态地址的最高2位有效位必须是1。

       b)静态地址最高2位有效位之外的其余部分不能全为0和1。

      在私有地址的定义当中,又包含了两个子类:不可解析私有地址(Non-resolvable Private Address)和可解析私有地址(Resolvable Private Address,RPA)。CH57x使用的是静态地址,芯片在出厂时自带全球唯一的48位MAC地址。在提供的driver代码中,有获取MAC的接口,可以直接调用。

   总结:

  • Static Device Address:上电生成,46-bit的random+11,断电后可变

  • Private Device Address:进一步提供定时更新和地址加密提高可靠行和安全性

  • Non-resolvable Private Address:按周期定时更新,46-bit的random+00

  • Resolvable Private Address:通过随机数和IRK(Identity Resolving Key)生成,24-bit的hash+22-bit的random+10

  • Public Device Address:IEEE分配,24-bit的company_id+24-bit的company_assigned,类似MAC

  • Random Device Address:随机生成,解决费用和维护、设备身份绑定的问题

Payload 长度

        广播报文:长度域包含6个比特,有效值的范围是6~37。

        数据报文:长度域包含5个比特,有效值的范围是0~31。

        广播报文和和数据报文的长度域有所不同,主要原因是:广播报文除了最多31个字节的数据之外,还必须要包含6个字节的广播设备地址。6+31=37,所以需要6比特的长度域。

       再次强调:广播时必须要包含6个字节的广播设备地址。

3.2.4 HCI

  • 将Link Layer提供的功能封装成Command/Event组

  • Command格式

        OCF(Opcode Command Field)表示特定的HCI命令,OGF(Opcode Group Field)表示该HCI命令所属组别,他们共同组成16位操作码;

       Parameter Total Length表示所有参数总长度

       所有BLE相关的HCI Command的OGF都是0x08

  • Event格式

  • 这些Command/Event包括广播、扫描、连接建立的相关操作,这些都可以通过hcitool命令进行测试

3.2.5 GAP

  • 会从应用程序角度对各种状态和操作再一次进行封装,包括设备角色,通信的模式和操作的定义

  • 与GAP广播通信相关的是广播和发现模式

    • Broadcast mode and observation procedure,广播模式及对应的解析过程,对应状态下的角色双方就是Broadcaster和Observer

    • Discovery modes and procedures,发现模式及对应的发现过程,对应的角色就是Peripheral和Central

广播数据格式

         广播/扫描应答数据,包含有意义部分和无意义部分(补齐为0),有意义部分是由一个个广播块(AD Structure)组成,每个广播块包含1字节长度(指示数据部分长度)和剩下的数据部分,数据部分又分为数据类型和数据内容,数据类型会指示真实Data部分的内容,例如0x01表示Data内容是描述设备物理连接状态,再例如0x08表示Data内容是设备名称,更多可以参考generic-access-profile.

        蓝牙广播包的最大长度是37个字节,其中设备地址占用了6个字节,只有31个字节是可用的。31个可用的字节又按照一定的格式来组织,被分割为nAD Structure。如下图所示:

每个AD Structure包含又包含三部分:Length(1字节),AD Type(1字节),AD Data(n字节)

其中Length = AD Type 长度 + AD Data 长度

例如广播数据:

0x05,0x09,0x31,0x32,0x33,0x34,0x02,0x0A,0x08,0x06,0xFF,0x41,0x50,0x50,0x4C,0x45

分割后如下所示

0x05,0x09,0x31,0x32,0x33,0x34

0x02,0x0A,0x08

0x06,0xFF,0x41,0x50,0x50,0x4C,0x45

一共可以分割成三个AD Structure:

第一个AD Structure的长度为0x05,类型为0x09(完成的设备名称),那么余下的数据含义就是完整的设备名称,0x31,0x32,0x33,0x34 按照UTF-8编码,就是1234。

第二个AD Structure的长度为0x02,类型为0x0A(发射功率),那么后面的数据0x08表示的就是发射功率。

第三个AD Structure 的长度为 0x06,类型为0xFF(厂商自定义数据),余下的数据0x41,0x50,0x50,0x4C,0x45就是厂商自定义的内容。

 

 3.2.6 从机广播

       从机要被主机连接,那么它就必须先被主机发现。这个时候,从机设备把自身信息通过广播的形式发射出去。

       比如设备A需要先进行广播,即设备A(Advertiser)不断发送广播信号,t 为广播间隔。每发送一次广播包,我们称为一次广播事件(advertising event),因此 t 也称为广播事件间隔。广播事件时间是一段一段的,每次都会持续一段时间,蓝牙芯片也只有在广播事件期间才会打开射频模块发射广播,这个时间功耗比较高(几十毫安),其余时间蓝牙芯片都处于idle待机状态,因此平均功耗就非常低(几微安)。

       当广播发出的时候,每个广播事件包含了三个广播包分别在37/38/39三个广播信道上进行发送。广播的内容是相同的。下图observer为主机观察者,advertiser就是从机广播者。

3.2.7 主机扫描

        设备A不断发送广播给主机(Observer),如果主机不开启扫描窗口,是收不到设备A的广播的。主机不但要开启射频接收窗口,而且主机的射频接收窗口要跟从机的广播发送窗口匹配才行。由于这种配对成功时一个概率事件,所以主机扫到设备A也是一个概率事件。也就是说,从机(Advertiser)可能很快就被主机(Observer)发现,也有可能从机(Advertiser)要很久才能被主机(Observer)发现。

       下图表示了主机主动扫描广播的过程:

        主机设置自身的扫描参数,设置成功后,控制器根据设置参数开启扫描窗口。当控制器收到扫描数据包后,向主机发送给一个广播报告事件(adv_report),该事件同样包括了链路层数据包的广播类型。因此,主机能够判断对端设备是否可以连接或扫描,并且区分出广播数据包和扫描响应数据包。

3.2.8 被动扫描

        既然有主动扫描,当然也就有被动扫描。在被动扫描中,扫描者设备应该仅仅去监听广播包,而不向广播者设备发送任何数据。

        一旦上面的扫描参数设置完毕,主机就可以启动扫描。如果控制器接收到的符合过滤策略和其他规划的广播数据包,则发送一个Advertising Report事件给主机。除了广播者的设备地址外,报告事件还包括广播数据包中的数据,以及接收广播数据包时的信号接收强度。可以利用该信号强度以及位于广播数据包中的发射功率,共同确定信号的路径损失,从而给出大致的范围,这个应用就是防丢器和蓝牙定位。被动扫描不需要向主机发送任何数据。

 

3.3 建立连接

      经典蓝牙中保持连接非常耗费资源,但是每次连接建立效率又非常低,为了优化体验,BLE简化了连接过程(毫秒级),极大的降低了面向连接通信的代价

      蓝牙通信系统中,对于连接的定义是:在约定的时间段内,双方都到一个指定的物理Channel上通信。

  • 角色定义。BLE为处于连接状态的两个设备定义了两个角色,Master和Slave。Master作为连接发起方,定义和连接相关的参数,Slave是连接的接收方,请求连接参数。

3.3.1 PDU格式

      面向连接的通信使用特定的PDU,称为Data channel PDU

LLID(逻辑链路ID):指示Data Channel传输的PDU类型,传输数据是LL Data PDU,传输控制信息是LL Control PDU,0x01表示该数据包是一个帧的延续内容,或者这是一个空的“逻辑链路控制及适配协议”数据包;0x02表示一个“逻辑链路控制及适配协议”数据包的开始;0x03表示这是一个“逻辑链路控制”数据包的内容

NESN:下一个期望的序列号,用于对接收到的数据包进行确认,NESN(Next Expected Sequence Number)和SN(Sequence Number)用于数据传输过程中的应答和流控

MD:更多数据字段,主要是为了说明发送方是否还有要发给接收者的数据,用于关闭连接。

RFU :保留位

Length:用以表示包含“信息完整性校验码”(Message Integrity Check,MIC)在内的“有效载荷数据”的长度,包括Payload和MIC。

数据PDU数据
同广播报文PDU数据

校验码:3个字节长度,“循环冗余校验”(Cyclical Redundancy Check,CRC),可检查数据的正确性。

3.3.2 建立连接

  1. 可连接状态的设备(Advertiser)按照一定周期广播可连接数据包

  2. 主动连接的设备(Initiator)收到广播包后回应一个连接请求(约定时间点、物理信道等)

  3. Initiator发送完毕后进入连接状态,成为Master

  4. Advertiser接收到连接请求后也进入连接状态,成为Slave

  5. 双方按照参数约定,定时切换到某一物理信道,开始依次收发数据,直至连接断开

     主机在收到A1广播包ADV_IND后,以此为初始点,T_IFS时间后,给Advertiser(从机)发送一个connection request命令,即A2数据包,告诉advertiser(从机)将要进行连接,做好准备。Advertiser(从机)根据connect_req命令信息做好接收准备。connect_req其实就是告诉advertiser手机(主机)将在Transmit Window期间发送第一个同步包(P1),请advertiser(从机)在这段时间内打开接收窗口。设备B收到P1后,T_IFS时间后将给手机(主机)回复数据包P2。一旦手机(主机)收到数据包P2,连接即认为建立成功。后续手机(主机)将以P1为锚点(原点),Connection Interval为周期,周期性地给设备B发送Packet。

HCI 

  • 封装Link Layer的功能,主要包括连接的建立、关闭、参数设置和管理,以及数据封装和转发

GAP

  • 定义设备具有的能力和操作

 3.4 发送和接收数据

       连接成功后,主机和从机在每一个connection interval开始的时候,都必须交互一次,即主机给从机发一个包,从机再给主机发一个包。整个交互过程被称为一个connection event。蓝牙芯片只有在connection event期间才把射频模块打开,此时功耗比较高,其余时间蓝牙芯片都处于idle状态,因此平均功耗非常低。

       主机不可能时时刻刻都有数据给从机,所以主机大部分时间都是发的空包(empty packet)给从机。同样从机也不是时时刻刻都有数据给主机。因此从机回复给主机的包,大部分也是空包。另外,一个connection event期间,主机可以发多个包给从机,以提高吞吐率(IOS一个连接间隔最多交互4次,安卓一个连接间隔最多交互6次)。综上所述,连接成功后的通信时序图如下:

       图中,主从数据发送的数据包TX和RX表示方向性的数据通道,也就是蓝牙的空中属性,空中操作时间都是采用蓝牙操作句柄来进行的。因为句柄能够唯一表示各个属性。空中特性的性质包括:

       从机->主机方向:

通知:从机端上报数据给主机,不需要主机回复一个响应

指示:从机端上报数据给主机,需要主机端回复一个确认

通知和指示之间不同之处在于指示有应用层上的确认,而通知没有。

       主机->从机方向:

没有回应的写

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

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

相关文章

【Tauri】(1):使用Tauri1.5版本,进行桌面应用开发,在windows,linux进行桌面GUI应用程序开发,可以打包成功,使用 vite 最方便

1,视频地址: https://www.bilibili.com/video/BV1Pz421d7s4/ 【Tauri】(1):使用Tauri1.5版本,进行桌面应用开发,在windows,linux进行桌面GUI应用程序开发,可以打包成功&…

Educational Codeforces Round 135 (Rated for Div. 2)C. Digital Logarithm(思维)

文章目录 题目链接题意题解代码 题目链接 C. Digital Logarithm 题意 给两个长度位 n n n的数组 a a a、 b b b,一个操作 f f f 定义操作 f f f为, a [ i ] f ( a [ i ] ) a [ i ] a[i]f(a[i])a[i] a[i]f(a[i])a[i]的位数 求最少多少次操作可以使 …

电路设计(16)——纪念馆游客进出自动计数显示器proteus仿真

1.设计要求 设计、制作一个纪念馆游客进出自动计数显示器。 某县,有一个免费参观的“陶渊明故里纪念馆”,游客进出分道而行,如同地铁有确保单向通行的措施。在入口与出口处分别设有红外检测、声响、累加计数器装置,当游人进&#…

fast.ai 机器学习笔记(一)

机器学习 1:第 1 课 原文:medium.com/hiromi_suenaga/machine-learning-1-lesson-1-84a1dc2b5236 译者:飞龙 协议:CC BY-NC-SA 4.0 来自机器学习课程的个人笔记。随着我继续复习课程以“真正”理解它,这些笔记将继续更…

【蓝桥杯省赛真题23】python水仙花数 青少年组蓝桥杯比赛python编程省赛真题解析

目录 python水仙花数 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python水仙花数 第十二届蓝桥杯青少年组python比赛省赛真题 一、题目要求…

【ES6】模块化

nodejs遵循了CommonJs的模块化规范 导入 require() 导出 module.exports 模块化的好处: 模块化可以避免命名冲突的问题大家都遵循同样的模块化写代码,降低了沟通的成本,极大方便了各个模块之间的相互调用需要啥模块,调用就行 …

年底总结:野生码农与辉煌的2023

目录 始于兴趣终与坚持成于热爱2024 flag 始于兴趣 那是在遥远的2018年,我从机械行业跨入IT领域,当时觉得写代码非常酷的事,而且开发出来的功能可以提高机械制造效率,那种成就感油然而生。展望着未来,我觉得自己或许正…

8.【CPP】Vector(扩容问题||迭代器失效问题简述迭代器的种类)

vector是表示可变大小数组的序列容器。就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自…

大数据Doris(六十五):基于Apache Doris的数据中台2.0

文章目录 基于Apache Doris的数据中台2.0 一、​​​​​​​架构升级

117.乐理基础-五线谱-音值组合法(二)

内容参考于:三分钟音乐社 上一个内容:116.乐理基础-五线谱-音值组合法(一)-CSDN博客 分母大于等于八的所有拍号的音值组合法,对于这些大于等于八的,可以用一句话来形容,那就是叫做&#xff0c…

骑砍战团MOD开发(44)-可编程渲染管线shader编程

一.可编程渲染管线 在GPU进行3D模型投射到2D平面过程中,渲染管线算法对开发者开放,目前支持的编程语言有OpenGL的ARB语言(pp文件),Direct3D的HLSL高级shader编程语言(fx文件). Direct3D提供一下API实现程序加载shader着色器文件: D3DXCreateEffectFromFile(gDevice,"fxfn…

使用 MinIO 超级充电 TileDB 引擎

MinIO 是一个强大的主要 TileDB 后端,因为两者都是为性能和规模而构建的。MinIO 是一个单一的 Go 二进制文件,可以在许多不同类型的云和本地环境中启动。它非常轻量级,但也具有复制和加密等功能,并且提供与各种应用程序的集成。Mi…

分享76个时间日期JS特效,总有一款适合您

分享76个时间日期JS特效,总有一款适合您 76个时间日期JS特效下载链接:https://pan.baidu.com/s/1s7tPGT_ItK7dNK5_qbZkug?pwd8888 提取码:8888 Python采集代码下载链接:采集代码.zip - 蓝奏云 学习知识费力气,…

java基础(2) 面向对象编程-java核心类

面向对象 面向对象对应的就是面向过程, 面向过程就是一步一步去操作,你需要知道每一步的步骤。 面向对象的编程以对象为核心,通过定义类描述实体及其行为,并且支持继承、封装和多态等特性 面向对象基础 面向对象编程&#xff0…

C++进阶(十四)智能指针

📘北尘_:个人主页 🌎个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上,不忘来时的初心 文章目录 一、为什么需要智能指针?二、内存泄漏1、 什么是内存泄漏,内存泄漏的危…

探索现代Web前端开发框架:选择最适合你的工具

在当今快速发展的Web开发领域,前端开发框架的选择显得尤为关键。这些框架可以帮助我们更高效地构建出交互性强、性能卓越的用户界面。本文将带你了解几个当前最受欢迎的Web前端开发框架,并帮助你根据自己的需求选择最合适的工具。 1. React React由Fac…

前端面试题——JS实现反转链式表

前言 反转单向链表就是将整个单链表的数据进行倒序的过程。 例如,如果反转之前的单链表是0->1->2->3,那么反转之后的单链表应该是3->2->1->0。这个操作通常是通过改变链表中每个节点的指针方向来实现的,即让每个节点的指…

【经验】PIC16F877A串口发送字符串问题

PIC16F877A串口发送,查询方式,就为了调出这个费了我一天时间,原来是串口芯片电压问题,现总结如下: 1、注意232串口芯片供电电压,有5V和3.3V的 2、注意TXD、RXD接线,单片机的TXD接232芯片的R2O…

docker镜像命令

1、查看docker版本详情 docker version 2、查看本地所有镜像 docker images 名词解释:REPOSITORY - 镜像仓库源TAG - 镜像的标签(就是版本号标识)IMAGE ID - 镜像的idCREATED - 镜像创建时间SIZE - 镜像大小 3、可选项 在执行基础命令时…

代码随想录day19--二叉树的应用7

LeetCode235.二叉搜索树的最近公共祖先 题目描述: 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、…