精华内容
下载资源
问答
  • 蓝牙协议栈
    千次阅读
    2021-11-24 09:06:35


      想写这篇文章是源于领导对我提出的一个疑问,而我从未在她想的层面上去思考蓝牙协议栈。

    蓝牙协议栈移植:

      问题1:你这个蓝牙协议栈是什么驱动的咧?像我们串口、can、spi、iic它们都是mcu的一种外设,相关的驱动也非常成熟,你这蓝牙BLE是什么驱动的咧?

      我的第一反应是领导应该是需要通过串口或者can这些外设来驱动我这个蓝牙芯片完成空中数据收发,简单来说蓝牙类似于当个AT指令的外设。经过我几番说明:串口和can以及其他的接口都可以驱动我来完成你想要的功能啊!当然领导知道这些个方式。她明白我没明白,而我不明白她的明白。慢慢的我才知道,她想要的答案是:蓝牙协议栈就是BLE的驱动。这不是最基本的常识吗?【黑人问号脸】,我没考虑到的是她没怎么接触,也没有想过,她认为BLE就是MCU的一个外设,需要一个驱动软件驱动。当然她想的也没错,事实确实这样。我从接触蓝牙到她提出这个问题之前,也没有将BLE当作mcu的外设来思考,至今也没有这么大的想法。

      问题2:供应商提供的demo里的协议栈可能不会很稳定,那只是一个demo,能用的一个状态,那咱能不能做这个驱动呢?或者说将demo里的协议栈剥离出来调试更稳定,打包成为公司的财产呢?以后无论换什么平台,咱们都用我们自己的协议栈去设配移植到其他的蓝牙芯片平台!

      我…,我当时也没敢说话,我也不知道要怎么回答,我知道蓝牙射频类的上游芯片公司花几十上百w去找大佬团队设计蓝牙协议栈,我也没有证据说别人的协议栈稳定不稳定,其二对于我们这些几k月薪的软件工程师了解蓝牙核心规范所有的内容都很难,对于只有我一个做蓝牙相关的科室来说,做是肯定不可能的?但剥离出来移植是不是一个方法呢?如果拿到别人开源(拿到源码)的协议栈,我们能不能够根据物理层修改适配不同芯片平台,而上层的HCI、L2cap、GAP、GATT等无非就是软件逻辑嘛,我们都可以不用变,那是不是就是移植的一个方法呢?我还没有接触过,也没有见过类似的骚操作。这里打个问号。
      有以下的思考:1. 是否各个厂家都会将芯片射频相关的硬件寄存器都开放在datasheet里面呢? 2. 是否有开源的蓝牙协议栈呢?像nxp这样的厂商会将协议栈打包成一个lib库,不开放的。 3. 移植后,适配效果如何呢? 4. 如果要做,给我搭配一个做驱动的大佬(没做过蓝牙方面的驱动软件工程师)我需要花多长时间做出来呢? 以上这些我都没有办法量化回答领导。如果领导坚持说移植这个方法是绝对可行的,我也没有很好的理由来说服领导!
      各位有什么想法和建议可以大家一起讨论哦。

    关于OOB:

      oob对于玩蓝牙协议栈的伙伴应该都不陌生,全称是Out Of Band,中文习惯性称为:带外。

      问题1:OOB一定要使用蓝牙以外的方式传输(Address、ra、Ca)吗?

      一说起OOB我第一时间想到的是NFC、红外、uart、spi这些非蓝牙方式的近场传输方式,这从一定程度上增加了系统的额外成本。OOB无非就是传输三个参数嘛,我能不能直接用蓝牙传输,而这三个函数只能是对端接受的呢?事实上是很难做到的,因为蓝牙的数据是以辐射的形式发送到空中的,任何物理介质都可以捕获这个辐射,然后解码出来。也就是说一定是有第三方窃取你发射出去的oob数据。但是,如果我的oob数据是经过md5、aes或者其他的加密算法加密后发送到空中,对端用同样的加密算法以及秘钥解密出oob数据,这样就算是第三方窃取到我的密文,但没有密钥也不知道我们的加密方法,自然解密不了我的oob数据,而对端能够解密并获取oob数据,建立安全连接。那是不是既符合安全连接oob要求又降低了成本呢。非常的nice,又长见识了。

    关于攻击:

      关于蓝牙安全,我一直以为蓝牙协议栈已经做到很好了,比如MITM、SC、以及协商差生长期秘钥那套理论,似乎都在全方位的做了很好的安全性能,但今天我又听到了一个新名词:中继攻击。
      说中继攻击针对蓝牙的,似乎不太正确,这是使用中低频的传统车钥匙的一种非常有效的攻击手法,就是当你的车是传统的中低频钥匙,并且具有无感进入功能,现在绝大多数车都具备了无感进入功能了吧,无感进入主要是检测钥匙到车段,或者车段到钥匙的中低频信号强度来进行模糊定位的,当接收到的信号强度越高就证明钥匙离车越近,当信号强度达到一定程度就认为车主就在车旁,这时车辆就要做出自动开门的策略并且一键启动少不了了,那么我说一个虚拟的案例:当你的车在你楼下,车端发出广播,你和你的钥匙在楼上22楼,我是攻击者,我站在你家楼下车旁边,我手里拿了一个信号放大器,将你的车的广播信号强度放大若干倍,让你的钥匙接受到非常强信号的广播,这是你的钥匙和你的车都会认为车主和车就是挨着的,达到了无感进入条件,那么你的车将会被盗取(当然这个虚拟案件比较笼统,但大概是这个意思)。这就是中继攻击的NB之处,只是做了一个中继器,你的车就不见了,比起传统的嗅探、伪装和篡改似乎要简单一些。
      今天准甲方粑粑问了我们的蓝牙方案有没有具备了防中继攻击功能,我。。。误认为是嗅探、伪装或者篡改了。因为在此之前我真的想不到还有什么手段可以攻击的了。结果还要甲方粑粑帮着解析了一把,我可能把我们在甲方粑粑的评分成功的拉低了。但幸好的是我、我们的大佬和甲方粑粑都还没见过有蓝牙中继攻击的案例,可能也是甲方粑粑由传统钥匙展开来想到的,不过确实也是个好问题。认真的说,现在有的车厂策略会利用蓝牙广播的强度或者相位做模糊定位,或者单用蓝牙信号强度做模糊定位,采用这样的方式定位的话,面对中继攻击将会是无力回天,和传统钥匙一样的沦陷的。没有办法,蓝牙轻度它又不能加密。

    更多相关内容
  • Linux蓝牙协议栈OpenBT及其应用程序开发.pdf
  • 蓝牙协议栈详解

    2018-05-07 16:13:40
    蓝牙协议栈的详细文档,硬件工程师和嵌入式软件工程师必读的文档
  • nimble 开源蓝牙协议栈

    2020-02-20 15:47:03
    NimBLE 软件包是 RT-Thread 基于 Apache NimBLE 开源蓝牙 5.0 协议栈的移植实现,该协议栈提供完整的 Host 层和 Controller 层支持,目前支持 Nordic nRF51 和 nRF52 系列芯片。
  • 本课程定位是:引领想学习蓝牙协议栈的学生或者从事蓝牙,但是对蓝牙没有一个系统概念的工程师快速入门 课程是多年从事蓝牙经验总结出来的,希望能让你看完有一种醍醐灌顶的感觉。 不要在摸着石头过河了·学习完这些...
  • 蓝牙协议栈

    2018-07-12 20:10:25
    蓝牙协议栈原理和结构,蓝牙协议栈原理和结构,蓝牙协议栈原理和结构,蓝牙协议栈原理和结构。
  • TI 低功耗蓝牙协议栈 SDK 开发资料,支持蓝牙芯片CC2540和CC2541,下载资料包含安装文件“BLE-CC254x-1.5.0.16.exe”,安装后提供相关文档资料和例程代码资料。
  • 蓝牙协议栈移植(arm)

    2018-08-14 15:30:34
    蓝牙协议栈移植,arm板子上面移植过程,非常宝贵的资料。
  • 蓝牙协议栈(Bluetooth stack),蓝牙初学者
  • 对应蓝牙协议栈的初始化一直是大家关注的问题, Nordic 的协议栈的初始化及其调 度机制将是本节的详细探讨内容。 并且通过分析基本原理, 在匹配的 SDK10.0 的蓝牙样例的例子基础上就行分析与 讲解, 使用的协议栈为...
  • CC2650蓝牙协议栈及官方开发者指导手册,从零开始指导学习CC2650蓝牙芯片入门开发
  • Android 蓝牙协议栈消息(bta_sys_sendmsg)发送机制 ---- 全网唯一解析,开始学习蓝牙协议栈的同学,阅读代码时候,遇到的第一个问题就是,当遇到发送event时候,就追踪不到代码了,直接接下来就不知道看啥代码了,...
  • 蓝牙协议栈总结

    2022-06-04 09:07:47
    频带:2400-2483.5MHz,分为79个跳频信道,每个信道带宽为1MHz,上保护带宽3.51MHz,下保护带宽2MHz。蓝牙2.0 EDR模式对分组调制方式的修改:全世界所有蓝牙设备地址...只传输数据分组,不传输蓝牙音频电缆替代协议蓝牙

    蓝牙协议栈

    无线射频

    • 负责数据的发射和接收
    • 采用全向天线,支持点到多点通信,使得多台蓝牙设备可以分享网络资源;
    • 调制方式:高斯滤波二进制频移键控(GFSK)三种可用功率级别:
    功率等级最大输出功率正常输出功率最小输出功率
    1100 mW-1 mW
    22.5 mW1 mW0.25 mW
    31 mW--

    频带:2400-2483.5MHz,分为79个跳频信道,每个信道带宽为1MHz,上保护带宽3.51MHz,下保护带宽2MHz。

    蓝牙2.0 EDR模式对分组调制方式的修改:

    • 分组头和接入码使用GFSK调制,速率为1 Mb/s
    • 同步序列、载荷与尾序列使用增强数据传输速率下的PSK调制,支持的射频数据传输速率为2 Mb/s与3 Mb/s

    基带

    • 与射频一起构成蓝牙协议栈的物理层
    • 发送数据时负责把高层协议的数据编码。接收数据时负责将来自射频的数据解码。
    • 组网(微微网,散射网)
    • 组合了电路交换和分组交换的功能

    蓝牙地址 (BD_ADDR)

    全世界所有蓝牙设备地址唯一

    公司分配号公司ID公司ID
    低位地址LAP(24bit)高位地址UAP(8bit)无意义地址NAP(16bit)

    链路管理

    LM(link manager)将上层的命令转化为基带层的操作。

    基本功能:

    • 处理和协商基带分组的大小,满足特定的服务质量;
    • 链路管理和安全性管理,包括ACL和SCO链路的建立和关闭等。
    • 管理设备功率。

    LMP协议数据单元

    • LMP消息称为LMP_PDU,主要用于链路管理、安全和控制。优先级高,可以优于SCO分组传输。
    • LMP_PDU是ACL分组的净荷,作为单时隙分组在链路管理逻辑信道上传输信息。

    L2CAP

    逻辑链路控制和适配。

    • 将高层使用的大分组拆分成基带可以传输的小分组,并在接收阶段完成组装

    • 支持对不同的高层协议进行多路复用,允许高层协议共享底层链路。

    • L2CAP只支持ACL,最大速率64KBytes。只传输数据分组,不传输蓝牙音频

    RFCOMM

    电缆替代协议

    • 蓝牙最早开发的目的是取消电器之间的连线,替代电缆是最基本、最主要的应用方式
    • 在蓝牙基带上仿真RS232的控制和数据信号,为串行电缆作为传输机制的高级业务提供传输能力
    • 作用类似于TCP/IP中的TCP,为各种高层应用提供接口,实现端到端通信
    • 依靠基带提供可靠、有序的比特流,本身没有纠错能力,流量控制也依赖基带

    服务发现协议

    蓝牙场景具有ad-hoc特征,动态性强

    帮助网络中的设备和服务之间容易彼此发现、相互协商和配置

    SDP是客户机-服务器结构的协议

    • 服务器是为其他蓝牙设备提供服务的设备
    • 客户机是在一个有效通信范围内想要查找服务的设备

    服务查询过程

    1. 建立L2CAP远程连接
    2. 搜索SDP服务器上指定的服务类型,或浏览服务列表
    3. 获得连接到指定服务所需要的属性值
    4. 建立一个单独的连接使用该服务

    SDP数据库

    属性标志符ID 属性值(类型和长度可变)
    服务属性1
    服务属性2
    服务属性n

    强制属性

    • 服务类型,属性标志符为0x0001
    • 服务句柄,32bit无符号证书,是服务记录的指针,唯一地标志了一个SDP服务记录

    通用唯一标志符 UUID

    • 标志服务类型
    • 为开发者自己开发的服务类别分配独特的UUID避免命名冲突。
    • 分布式生成,不重复
    • 传统的UUID是128bit,可以缩减为16bit或32bit。
      • 128_bit_value = 16_bit_value * 296 + Base_UUID
      • 128_bit_value = 32_bit_value * 296 + Base_UUID

    SDP消息

    设计目标:简单易实现,与L2CAP良好兼容

    消息浏览模式

    • 浏览服务器中所有可用服务来查找需要的服务(查找服务列表,返回列表中所有的UUID)
    • 根据查找特定的服务(根据UUID)

    协议子集

    GAP

    • 描述了两个蓝牙设备建立通信时必要的基本操作,包括设备发现、链路建立和配置,以及安全方面的内容。
    • 设备角色
      • 广播者(Broadcaster):周期性发送广播信息
      • 观察者(Observer):侦听信道,接收广播信息
      • 中心设备(Central):发起连接的一方
      • 外设(Peripheral):接收连接的一方

    主设备和从设备之间的链路

    SCO链路(电路交换)

    • 主设备与从设备之间对称、点对点同步链路;

    • 主要用于传送实时性需求较高的语音分组

    • 通过预先保留的时隙连续的传输信息,可以看做电路交换

    • 不允许分组重传(无校验位),保证实时性

    • SCO包使用前向纠错FEC(Forward Error Correction)

      • 分组头:1/3 FEC (每一位重复三次)
      • 负载:2:3 FEC (2:3简要海明码)
    • 不管有无数据发送,系统都会预留固定间隔的时限给主设备与从设备,其他从设备就不能利用此连接上的时隙来发送数据

    ACL链路(异步分组交换)

    • 分组交换只传输数据分组。
    • 主设备在为SCO传输预留时隙后,把异步ACL传输分配在剩下的时隙中
    • ACL比SCO优先级低,一旦系统要SCO传输,ACL必须自动让出预留时隙
    • 支持广播,主设备可以向微微网中所有从设备发送消息。
    • ACL采用CRC校验,接收错误会重传

    蓝牙组网

    蓝牙个域网的ad hoc 特性

    • 独立组网:很短的时间里自动组成一个独立的网络
    • 多跳路由:相互通信范围之外的节点需要经过多跳
    • 拓扑动态变化:某些节点移动、关闭和开启电源,引起节点和链路数量及分布的变化
    • 特殊的信道特征:受无线信道冲突等影响,链路的实际带宽远小于理论带宽,且动态变化
    • 节点能耗受限
    • 安全性:易受到窃听、主动入侵、拒绝服务等攻击

    微微网

    • 首先提出通信要求的为主设备,被动进行通信的设备是从设备(仅在基带有此区分)
    • 一个微微网中有1个主设备,最多有7个从设备
    • 主设备的时钟传送给从设备,从设备加上偏移量

    微微网内部调度

    • 如果主设备没有数据给从设备,就发送POLL分组
    • 如果从设备没有数据给主设备,发送NULL
    • 降低POLL和NULL分组的比例,是提高调度效率的根本

    时钟

    • 每个蓝牙设备有一个独立运行的28bit内部系统时钟,频率为3.2kHz
    • 决定收发器的定时和跳频
    • 与提他设备同步时,在本地时钟上增加一个偏移量

    散射网

    同一个区域中可以同时存在多个微微网,如果有蓝牙设备进入这样的网络,并作为桥接设备,将在空间上重叠的微微网相互连接起来,组成散射网

    循环轮询的改进方法

    • 彻底循环轮询

      • 直到主设备和从设备发完信息后才轮询至下一个设备;(有什么问题?)
      • 公平性问题,一些节点可能一直有数据发送,使得其他设备没法发数据
    • 限制的循环轮询

    • 限制每次连接后的数据传输数量

    • 依赖主设备和从设备状态的轮询

      • 给每一对M-S安排优先级
      • 1代表有数据发送,0代表无数据发送。
      • 1-1优先级最高,其次是1-0和0-1,最低是0-0
        环轮询
      • 直到主设备和从设备发完信息后才轮询至下一个设备;(有什么问题?)
      • 公平性问题,一些节点可能一直有数据发送,使得其他设备没法发数据
    • 限制的循环轮询

    • 限制每次连接后的数据传输数量

    • 依赖主设备和从设备状态的轮询

      • 给每一对M-S安排优先级
      • 1代表有数据发送,0代表无数据发送。
      • 1-1优先级最高,其次是1-0和0-1,最低是0-0
    展开全文
  • BLE-STACK V2.2.5 (Support for CC2640/CC2650),官网最新蓝牙协议栈
  • 智能传感器的蓝牙协议栈与SoC结构设计,通过对蓝牙协议栈和智能传感器功能要求的分析,讨论用于智能传感器设计的嵌入式蓝牙协议栈SoC的基本结构,以及功能组成要求。
  • 这年头协议栈开源的太多了,掌握基础蓝牙协议栈作为嵌入式软件工程师的进阶技能。如果有了解并应用的市面上大部分蓝牙芯片,不妨看看如下内容,对于理解并提升蓝牙协议了解有一定帮助。 本次文章主要说明如何去学习...

    一,前述

    这年头协议栈开源的太多了,掌握基础蓝牙协议栈作为嵌入式软件工程师的进阶技能。如果有了解并应用的市面上大部分蓝牙芯片,不妨看看如下内容,对于理解并提升蓝牙协议了解有一定帮助。

    本次文章主要说明如何去学习蓝牙Host协议栈,controller协议栈仅做参考。(conrtoller涉及PHY层,除非原厂深入,一般我们仅作了解)

    二,关于Host协议栈

    1, 源码链接

    上官方链接:https://mynewt.apache.org/
    上Github链接:https://github.com/apache/mynewt-nimble
    

    Apache Mynewt是一个开源项目,其中Mynewt Nimble是开源5.1蓝牙协议栈,包含host&controller协议栈,可完全替代nordic softdevice(跟zephyr一样的)。
    网上开源协议栈很多,诸如:btstack,bluez,zephyr等等,但是Nimble属轻量级LE Host协议栈,对于初次了解协议栈的朋友非常友好。

    官方介绍:

    NimBLE complies with Bluetooth Core Specification 5.0 which makes it an ideal wireless technology for the Internet of Things (IoT).
    
    LE Advertising Extensions
    
    2Msym/s PHY for higher throughput
    
    Coded PHY for LE Long Range
    
    High Duty Cycle Non-Connectable Advertising
    
    Channel Selection Algorithm #2 to utilize channels in more efficient way.
    
    LE Privacy 1.2 for frequent changes to the device address to make it difficult to track for outsiders
    
    LE Secure Connections featuring FIPS-compliant algorithms.
    
    LE Data Length Extension for higher throughput
    
    Coming Soon: Assigning an Internet Protocol (IP) address (compliant with the IPv6 or 6LoWPAN standard) to a Bluetooth device through Internet Protocol Support Profile (IPSP)
    
    The Bluetooth 5 is backward compatible with previous Bluetooth version 4.2 which is also supported by Apache Mynewt.
    

    2,如何跑通Host协议栈

    本次主要验证如何跑通Host协议栈以及对应源码的简单介绍。
    关于Host的支持项如下:

    Host
    
    Logical Link Control and Adaptation Protocol (L2CAP): provides logical channels, named L2CAP channels, which are multiplexed over one or more logical links to provide packet segmentation and reassembly, flow control, error control, streaming, QoS etc.
    
    Security Manager (SM): uses Security Manager Protocol (SMP) for pairing and transport specific key distribution for securing radio communication
    
    Attribute protocol (ATT): allows a device (Server) to expose certain pieces of data, known as Attributes, to another device (Client)
    
    Generic Attribute Profile (GATT): a framework for using the ATT protocol to exchange attributes encapsulated as Characteristics or Services
    
    Generic Access Profile (GAP): a base profile which all Bluetooth devices implement, which in the case of LE, defines the Physical Layer, Link Layer, L2CAP, Security Manager, Attribute Protocol and Generic Attribute Profile.
    
    Host Controller Interface (HCI): the interface between the host and controller either through software API or by a hardware interface such as SPI, UART or USB.
    

    对于一个Linux子设备,如IPC或者网关蓝牙配网提供wifi ssid/token等等,一份简单的host协议栈即可满足需求。(且可配置无需依赖linux kernel)

    具体流程如下:

    (1)下载源码:

    git clone https://github.com/apache/mynewt-nimble
    

    (2)编译源码:

    root@ubuntu:/home/timcheng/project/mynewt-nimble-latest# cd porting/examples/linux/
    
    // 默认工具链为GCC,本次编译环境为Ubuntu 16.04
    root@ubuntu:/home/timcheng/project/mynewt-nimble-latest/porting/examples/linux# make 
    
    // 生成一个nimble-linux的可执行文件
    root@ubuntu:/home/timcheng/project/mynewt-nimble-latest/porting/examples/linux# ls
    ble.c  ble.o  include  main.c  main.o  Makefile  nimble-linux  README.md
    
    // 直接执行即可。
    // 需说明:由于采用的是HCI SOCKET形式与设备交互,所以如果没有安装驱动需单独安装驱动。
    //如果采用市面上的realtk dongle直插,需重新加载驱动,具体如何安装驱动以及驱动程序在我的附件中。
    

    (3)关于蓝牙服务说明:
    默认服务还是蛮多的,如果需要添加自己的vendor service,可按照任意一个的服务初始化添加即可,比较简单。同时需注释掉如下服务。
    注释掉如下服务

    (4)关于HCI Socket说明:

    索引地址:nimble\transport\socket\src\ble_hci_socket.c
    

    由于直接在ubuntu上编译且不依赖Apache Mynewt框架,所以可以选择性浏览一些代码。hci实现形式非常多,对于前期理解可先易后难。

    三,关于Host源码说明

    1,Host分层

    协议栈分层已经是基础了,我们剖析中间每一层去理解更为深刻。Apache Mynewt Nimble完全按照L2CAP->ATT/SM->GATT Server/Client以及GAP分层。注重说明GATT与GAP源码。

    2,Host协议栈之GAP

    索引地址:nimble\Host\src\ble_gap.c
    
    // 着重注意GAT Event,每一个GAP Event将会通过回调机制返回状态。
    static int gap_event_cb(struct ble_gap_event *event, void *arg)
    
    // 具体包含如下GAP Event事件
    #define BLE_GAP_EVENT_CONNECT               0
    #define BLE_GAP_EVENT_DISCONNECT            1
    /* Reserved                                 2 */
    #define BLE_GAP_EVENT_CONN_UPDATE           3
    ...
    #define BLE_GAP_EVENT_PERIODIC_SYNC_LOST    22
    #define BLE_GAP_EVENT_SCAN_REQ_RCVD         23
    #define BLE_GAP_EVENT_PERIODIC_TRANSFER     24
    
    // 关于GAP接口可参考文件内信息,着重说明如下几个常用接口
    // 开启广播
    int ble_gap_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr,
                          int32_t duration_ms,
                          const struct ble_gap_adv_params *adv_params,
                          ble_gap_event_fn *cb, void *cb_arg);
    
    // 关闭广播
    int ble_gap_adv_stop(void);
    
    // 设置广播信息
    int ble_gap_adv_set_data(const uint8_t *data, int data_len);
    int ble_gap_adv_rsp_set_data(const uint8_t *data, int data_len);
    
    // 连接子设备
    int ble_gap_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr,
                        int32_t duration_ms,
                        const struct ble_gap_conn_params *params,
                        ble_gap_event_fn *cb, void *cb_arg);
    
    // 开启扫描
    int ble_gap_disc(uint8_t own_addr_type, int32_t duration_ms,
                     const struct ble_gap_disc_params *disc_params,
                     ble_gap_event_fn *cb, void *cb_arg);
    
    // 关闭扫描
    int ble_gap_disc_cancel(void);
    

    3,Host协议栈之GATT

    Server索引地址:nimble\Host\src\ble_gatts.c
    Client索引地址:nimble\Host\src\ble_gatts.c
    
    // 常用读写notify接口
    int ble_gattc_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle,
                               struct os_mbuf *om);
                               
    int ble_gattc_write(uint16_t conn_handle, uint16_t attr_handle,
                        struct os_mbuf *om,
                        ble_gatt_attr_fn *cb, void *cb_arg);
    
    int ble_gattc_notify_custom(uint16_t conn_handle, uint16_t att_handle,
                                struct os_mbuf *om);
    
    int ble_gattc_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, struct os_mbuf *txom);
    
    int ble_gattc_read_by_uuid(uint16_t conn_handle, uint16_t start_handle,
                               uint16_t end_handle, const ble_uuid_t *uuid,
                               ble_gatt_attr_fn *cb, void *cb_arg);
    
    // 常用Client端发现服务等接口
    int ble_gattc_disc_all_svcs(uint16_t conn_handle,
                                ble_gatt_disc_svc_fn *cb, void *cb_arg);
    
    int ble_gattc_disc_svc_by_uuid(uint16_t conn_handle, const ble_uuid_t *uuid, ble_gatt_disc_svc_fn *cb, void *cb_arg);
    
    int ble_gattc_find_inc_svcs(uint16_t conn_handle, uint16_t start_handle,
    uint16_t end_handle, ble_gatt_disc_svc_fn *cb, void *cb_arg);
                                
    int ble_gattc_disc_all_chrs(uint16_t conn_handle, uint16_t start_handle,
    uint16_t end_handle, ble_gatt_chr_fn *cb, void *cb_arg);
    
    int ble_gattc_disc_chrs_by_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, const ble_uuid_t *uuid,
    ble_gatt_chr_fn *cb, void *cb_arg);
    
    int ble_gattc_disc_all_dscs(uint16_t conn_handle, uint16_t start_handle,
    uint16_t end_handle, ble_gatt_dsc_fn *cb, void *cb_arg);
    
    

    4,关于Host的一些宏定义

    // 决定了你发送数据/广播/新增服务等的buffer大小
    MYNEWT_VAL_MSYS_1_BLOCK_COUNT
    
    // 决定了你接收数据的buffer大小
    MYNEWT_VAL_BLE_ACL_BUF_COUNT
    
    // 决定了你接收的hci事件的buffer大小,如果包含扫描,务必设定较大。
    MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT
    MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT
    
    

    四,最后说明

    开源协议栈框架仅仅是作为一个基础模型,真正做产品还是需要多加打磨的。无论是协议交互还是内存管理,都需要深度理解,才能打造好的产品。

    关于如何制作Controller与驱动以及协议栈内存管理分配,可参考另外篇幅。

    如果有相关需求,可以联系本人(vx:timcheng93)。可有偿提供整套协议栈服务。

    展开全文
  • 蓝牙( Bluetooth® ):是一种无线技术标准,可实现固定设备、移动设备和楼宇个人域网之间的短距离数据交换(使用2.4—2.485GHz的ISM波段的UHF无线电波)。蓝牙技术最初由电信巨头爱立信公司于1994年创制,当时是...
  • BLE低功耗蓝牙协议栈

    千次阅读 2022-03-14 17:52:42
    BLE低功耗蓝牙协议栈 (1)蓝牙核心协议(Bluetooth Core) (2)蓝牙应用层协议(Bluetooth Application) (3)BLE低功耗蓝牙核心协议层详解(Bluetooth Core) ① 物理层(PHY) ② 链路层(LL) ③ 主机...

    目录

    一. BLE低功耗蓝牙协议栈

    (1)蓝牙核心协议(Bluetooth Core)

    (2)蓝牙应用层协议(Bluetooth Application)

    (3)BLE低功耗蓝牙核心协议层详解(Bluetooth Core)

    ① 物理层(PHY)

    ② 链路层(LL)

    ③ 主机控制接口层(HCI)

    ④ 通用访问配置文件层(GAP)

    ⑤ 逻辑链路控制及自适应协议层(L2CAP)

    ⑥ 安全管理层(SM)

    ⑦ 属性协议层(ATT)

    ⑧ 通用属性配置文件层(GATT)

    (4)ATT协议层中的属性(attribute)

    (4.1)属性的组成(数据结构)

    二. BLE中的GAP和GATT:

    1. 引言:

    2. GAP:

    2.1 设备角色

    2.2 广播数据

    3. GATT

    3.1 GATT通信事务

    3.2 GATT结构

                            Profile

                            Service

                            Characteristic

                            UUID

    三. 一些常见术语概念

    1. ATT PDU(属性协议)

    2. GAP Bond管理

    使用GAPBondMgr

    四. 如何通过无线发送一个数据包

    广播方式

    连接方式


    经典蓝牙(BT):一般用于数据量比较大的传输,如:语音、音乐等较高数据量的传输。

    低功耗蓝牙模块(BLE):最大的特点就是成本和功耗的降低,可应用于实时性要求较高的产品当中,比如:智能家居类(蓝牙锁、蓝牙灯)、传感设备的数据发送(血压计、温度传感器)、消费类电子(电子烟、遥控玩具)等。

    BTBLE两者物理层调制解调方式是不一样的,所以BLE设备和BT设备两者之间是不能相互通信的,选型的时候千万不要搞混,如果主设备是BLE设备,从设备也必须是BLE设备;同样,BT的从设备也只能和BT的主设备进行通信。

    不过市场上还有一种双模蓝牙设备,即同时支持BLE和BT,比如我们天天用到的手机,手机可以和BT设备通信,也可以和BLE设备通信,但这不代表BLE设备可以和BT设备通信。其实是手机使用了分时机制来达到同时和BLE设备以及BT设备通信的目的,即手机让双模蓝牙芯片不断地在BLE模式和BT模式之间进行切换,以同时支持BLE设备和BT设备。

    一. BLE低功耗蓝牙协议栈

    深入浅出讲解低功耗蓝牙(BLE)协议栈 - 知乎

    BLE协议栈主要用来对你的应用数据进行层层封包,以生成一个满足BLE协议的空中数据包。也就是说,把应用数据包裹在一系列的帧头(header)和帧尾(tail)中。

    蓝牙协议规定了两个层次的协议:

    (1)蓝牙核心协议(Bluetooth Core)

    蓝牙核心协议关注对蓝牙核心技术的描述和规范,它只提供基础的机制,并不关心如何使用这些机制。

    蓝牙核心协议又包含BLE Controller和BLE Host两部分。

    • Controller:负责定义RF、Baseband等偏硬件的规范,并在这之上抽象出用于通信的逻辑链路(Logical Link);
    • Host:负责在逻辑链路的基础上,进行更为友好的封装,这样就可以屏蔽掉蓝牙技术的细节,让Bluetooth Application更为方便的使用。

    (2)蓝牙应用层协议(Bluetooth Application)

    蓝牙应用层协议,是在蓝牙核心协议的基础上,根据具体的应用需求,百花齐放,定义出各种各样的策略,如FTP、文件传输、局域网等等。

    (3)BLE低功耗蓝牙核心协议层详解(Bluetooth Core)

    ① 物理层(PHY)

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

    ② 链路层(LL)

    LL层是整个BLE协议栈的核心。

    LL层要做的事情非常多,比如具体选择哪程度 个射频通道进行通信,怎么识别空中数据包,具体在哪个时间点把数据包发送出去,怎么保证数据的完整性,ACK如何接收,如何进行重传,以及如何对链路进行管理和控制等等。

    LL层只负责把数据发出去或者收回来,对数据进行怎样的解析则交给上面的GAP或者ATT。

    ③ 主机控制接口层(HCI)

    HCL是可选的,主要用于两个芯片实现BLE协议栈的场合,用来规范两者之间的通信协议、通信命令等。

    ④ 通用访问配置文件层(GAP)

    主要用来进行广播、扫描和发起连接等。

    ⑤ 逻辑链路控制及自适应协议层(L2CAP)

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

    ⑥ 安全管理层(SM)

    用来管理BLE连接的加密和安全的。

    ⑦ 属性协议层(ATT)

    简单来说,ATT层用来定义用户命令及命令操作的数据,比如读/写某个数据。

    开发者接触最多的就是ATT。BLE引入了attribute(属性)概念,用来描述一条条数据,attribute除了定义数据,还定义该数据可以使用的ATT命令,因此这一层被称为ATT层。

    ⑧ 通用属性配置文件层(GATT)

    用来规范attribute中的数据内容,并用group(分组)的概念进行分类管理。

    (4)ATT协议层中的属性(attribute)

    ATT(Attribute Protocol)属性层是GATT和GAP的基础,它定义了BLE协议栈上层的数据结构和组织方式。

    属性(Attribute)概念是ATT层的核心,ATT层定义了属性的内容,规定了访问属性的方法和权限。以编程的眼光来看,属性是一个数据结构,它包括了数据类型和数据值,就如同C语言结构体的概念,开发者可以设计独特的结构,来描述外部世界实体。

    属性包括三种类型:服务项(service)、特征值(characteristic)和描述符。三者之间存在树状包含关系:服务项包含一个或多个特征值,特征值包含一个或多个描述符,多个服务项组织在一起,构成属性规范(Attribute Profile)。

    对于常用的属性规范,比如体重计、心率计,SIG(蓝牙技术联盟)做了具体定义,这样的话,只要BLE主从设备均遵守某个Profile来进行设计,那么二者就能够优雅的通信。

    (4.1)属性的组成(数据结构)

    属性主要由以下四部分组成:

     属性句柄(Attribute Handler):

    犹如指向属性实体的指针,可通过属性句柄来访问该属性。它是一个2字节长度的十六进制码,起始于0x0001,系统初始化时各个属性的句柄逐步加1,最大不超过0xFFFF。

    属性类型(Attribute Type):

    用以区分当前属性是服务项或是特征值等,用UUID来表示。

    UUID(universally unique identifier,通用唯一识别码)是一个软件构建标准,并非BLE独有的概念,一个合法的UUID,一定是随机的、全球唯一的,不应该出现两个相同的UUID。

    BLE的属性类型是有限的,有四个大类:

    • Primary Service(首要服务项)
    • Secondary Service(次要服务项)
    • Include(包含服务项)
    • Characteristic(特征值)

    这些属性类型分别对应了指定的UUID,BLE对这些UUID与属性类型的映射关系做了规定:

    • 0x1800 – 0x26FF :服务项类型
    • 0x2700 – 0x27FF :单位
    • 0x2800 – 0x28FF :属性类型
    • 0x2900 – 0x29FF :描述符类型
    • 0x2A00 – 0x7FFF :特征值类型

    假如UUID=0x1800,就表示它是一个首要服务项。

    标准的UUID是一串16字节十六进制字符串,但对于一些常用的UUID,为了减少传输的数据量,BLE协议做了一个转换约定,给定一个固定的16字节模板,只设置2个字节为变化量,其他为常量,2字节的UUID在系统内部会被替换,进而转换成标准的16字节UUID。

    UUID模板为:

    0000XXXX-0000-1000-8000-00805F9B34FB

    其中 xxxx 就是变化位,其他为固定位。

    如:UUID=0x2A00在系统内部会转换成00002A00-0000-1000-8000-00805F9B34FB。

    属性值(Attribute Value):

    用于存放数据。

    如果该属性是服务项类型或者是特征值声明类型,那么它的属性值就是UUID等信息。如果是普通的特征值,则属性值是用户的数据。

    操作特征值里的用户数据,就是对那块内存空间进行读写。

    属性权限(Attribute Permissions):

    主要有以下四种:

    • 访问权限(Access Permission)- 只读、只写、读写
    • 加密权限(Encryption Permission) – 加密、不加密
    • 认证权限(Authentication Permission) – 需要认证、无需认证
    • 授权权限(Authorization Permission) – 需要授权、无需授权

    注:

    加密:就是对数据进行加密;

    认证:是指相互确认对方身份,BLE中,认证过程就是配对;

    授权:授权要求设备为Trusted Device(可信任设备)。在实际使用中,经过配对以后设备即为Untrusted Device——认证,在代码中调用API可以设置设备为Trusted Device——授权。

    二. BLE中的GAP和GATT:

    蓝牙BLE: GATT Profile 简介(GATT 与 GAP) - 夜行过客 - 博客园

    1. 引言:

    低功耗蓝牙(BLE)连接都是建立在GATT(Generic Attribute Profile)协议之上。

    GATT是一个蓝牙连接之上的发送和接收很短的数据段的通用规范,这些很短的数据段被称为属性(Attribute)。

    2. GAP:

    介绍GATT之前,需要了解GAP(Generic Access Profile),它用来控制设备连接和广播。GAP使你的设备被其他设备可见,并决定了你的设备是否可以或者怎样与其他设备进行交互。

    2.1 设备角色

    GAP给设备定义了若干角色,主要的两个是:

    ① 外围设备(Peripheral):比如手环。一般是小、简单、低功耗设备,用来提供数据,并连接到一个强大的中心设备上。

    ② 中心设备(Central):比如手机。用来连接其他外围设备。

    2.2 广播数据

    在 GAP 中外围设备通过两种方式向外广播数据: Advertising Data Payload(广播数据)和 Scan Response Data Payload(扫描回复),每种数据最长可以包含 31 byte。这里广播数据是必需的,因为外设必需不停的向外广播,让中心设备知道它的存在。扫描回复是可选的,中心设备可以向外设请求扫描回复,这里包含一些设备额外的信息,例如设备的名字。

     从图中我们可以清晰看出广播数据和扫描回复数据是怎么工作的。外围设备会设定一个广播间隔,每个广播间隔中,它会重新发送自己的广播数据。广播间隔越长,越省电,同时也不太容易扫描到。

    大部分情况下,外设通过广播自己来让中心设备发现自己,并建立GATT连接,从而进行更多的数据交换。

    也有些情况是不需要连接的,只要外设广播自己的数据即可。

    用这种方式主要目的是让外围设备把自己的信息发送给多个中心设备。因为基于GATT连接方式的,只能是一个外设连接一个中心设备。

    3. GATT

    GATT 连接,必须先经过GAP协议。

    一旦两个设备建立起了连接,GATT 就开始起作用了。

    中心设备和外设需要双向通信的话,唯一的方式就是建立GATT 连接。

    GATT 定义两个BLE设备通过Service和Characteristic进行通信。

    GATT使用ATT协议,把Service、Characteristic以及对应的数据保存在一个查找表中,次查找表使用16bit ID作为每一项的索引。

    GATT 连接需要注意的是:GATT 连接是独占的,即一个BLE外设同时只能被一个中心设备连接,一旦外设被连接,它就会立马停止广播,这样它就对其他设备不可见了。

    一旦建立了连接,通信就是双向的了。而前边的GAP广播通信则是单向的(外设进行广播)。

    如果要让两个外设进行通信,就只能通过中心设备中转。

    3.1 GATT通信事务

    GATT通信的双方是C/S关系。

    外设作为GATT服务端(Server),维持了ATT的查找表以及service和characteristic的定义。

    中心设备是GATT客户端(Client),它向Server发起请求。

    需要注意,所有的通信事件,都是由客户端(也叫主设备,Master)发起,并且接收服务端(也叫从设备,Slave)的响应。

    一旦建立连接,外设会给中心设备建议一个连接间隔(Connection Interval),这样中心设备就会在每个间隔尝试去重新连接,检查是否有新数据。这个连接间隔只是个建议。

    下图展示一个外设(GATT服务端)和中心设备(GATT客户端)之间的数据交流流程,可以看到的是,每次都是主设备发起请求:

    3.2 GATT结构

    GATT事务是建立在嵌套的Profiles,Services和Characteristics之上的,如下所示:

    Profile

    一种规范,一种标准的通信协议。每个profile中会包含多个service服务,每个service代表该从机的一种能力。

    Service

    一种服务,也就是从机的能力。例如,蓝牙从机的电量信息服务、系统信息服务等。每个service中又包含多个characteristic特征值,每个具体的characteristic才是BLE通信的主题。

    Characteristic

    特征值,BLE主从机的通信均是通过characteristic来实现,可以理解为一个标签,通过这个标签可以获取或者写入想要的内容。

    举个例子,Heart Rate Measurement Characteristic。

    这个 Characteristic 是Heart Rate Service必须实现的,它的UUID为0x2A37。它的数据结构是,开始8bit定义心率数据格式,后边的是对应格式的实际心率数据。

    UUID

    统一标识码,service 和 characteristic 都需要一个唯一的UUID来标识。

    三. 一些常见术语概念

    1. ATT PDU(属性协议)

    认识BLE 5协议栈 —— 属性协议层 – SYQ

    在ATT层协议框架内,拥有一组属性的设备称为服务端(Server),读写该属性值的设备称为客户端(Client),Server和Client通过ATT PDU进行交互。属性协议共有6种:

    属性PDU方向触发响应
    CommandClient -> Server
    RequestClient -> ServerResponse
    ResponseServer -> Client
    NotificationServer -> Client
    IndicationServer -> ClientConfirmation
    ConfirmationClient -> Server

    解释:

    • 客户端发送Request,服务器需要返回一个Response,表明服务器收到了。
    • 服务器发送Indication,客户端需要返回一个Confirmation,表明客户端收到了。
    • 以上两种方式,均是单线程操作,即下一个Request/Indication操作需要在上一个操作收到Response/Confirmation之后才能开始。
    • 客户端发送Command,服务器无需任何返回。
    • 服务器发送Notification,客户端无需任何返回。

    2. GAP Bond管理

    gap_bond_manager_and_le_secure_connections

    GAP Bond Manager 是一个可配置模块,使用Bond Manager后应用程序可以减少大部分安全机制。

    术语描述
    配对(Pairing)交换密钥的过程
    加密(Encryption)0x02
    认证(Authentication)使用中间人(MITM)保护完成的配对
    Bonding将密钥存储在非易失性存储器中
    授权(Authorization)除了认证之外,还需要额外的应用级密钥交换
    OOB(Out of band)密钥不是通过空中交换,而是通过串行端口或NFC等其他来源进行交换。这也提供了MITM保护。
    MITM(Man in the Middle protection)这可以防止攻击者收听通过空中传输的密钥来破坏加密。
    只是工作(Just work)配对方法,其中密钥在没有MITM的情况下通过空中传送

    在程序中使用GAPBondMgr实现,过程如下:

    • 配对过程通过选择配对模式中描述的方法交换密钥。
    • 使用步骤1的密钥加密连接。
    • 绑定过程将密钥存储在安全闪存(SNV)中。
    • 重新连接时,使用存储在SNV中的密钥来加密连接。

    使用GAPBondMgr

    使用GAPBondMgr模块的一般步骤:

    1. 配置堆栈以包括GAPBondMgr功能,如果需要安全连接。

    2. 堆栈还必须配置为使用1或2个SNV界面。

    3. 如果使用安全连接,则PDU大小必须大于等于69,可用于安全连接的最小堆大小为3690。

    4. 根据需要初始化其参数来配置GAPBondMgr。

    5. 使用GAPBondMgr注册应用程序回调,以便应用程序可以与GAPBondMgr通信并通知事件。

    //Register with bond manager after starting device
    GAPBondMgr_Register(&bondmanager_callbacks);

    一旦GAPBondMgr被配置,它主要从应用程序的角度自主运行。当建立连接时,根据初始化期间设置的配置参数启动配对和绑定,并根据需要通过定义的回调与应用程序通信。

    GAPBondMgr与应用程序之间的大多数通信都是通过在步骤5中注册的回调发生的。

    GAPBondMgr与此应用程序之间的大多数通信都是通过在步骤5中注册的回调发生的。 下图是GAPBondMgr的流程图示例,通知应用程序配对已经完成。对于各种其他事件的发生也是用相同的方法,并将在后面部分进行扩展。

    四. 如何通过无线发送一个数据包

    深入浅出低功耗蓝牙(BLE)协议栈_iini的博客-CSDN博客

    下面以如何发送一个数据包为例来讲解BLE协议栈各层是如何紧密配合,以完成发送任务的。

    假设有设备A、B,A要把自己当前的电量值83%(十六进制表示为0x53)发给设备B,该怎么做呢?对开发者而言,他希望调用一个简单的API就能完成这件事,比如 send(0x53),实际上BLE协议栈就是这样设计的。开发者只需调用API,其余事情BLE协议栈帮你搞定。

    很多人会想,BLE协议栈是不是直接在物理层就把0x53发出去了,就像下图所示:

    实际不是这样的。

    首先他没有考虑用哪一个射频信道来进行传输。在不更改API的情况下,我们只能对协议栈进行分层,因此引入 LL层,开发者还是调用 send(0x53),send(0x53) 里再调用send_LL(0x53, 2402M)(注:2402M为信道频率)。

    这里还有一个问题,设备B怎么知道这个数据包是发给自己的还是其他人的,为此BLE引入access address 概念,用来指明接受者身份。(其中,0x8E89BED6这个access address比较特殊,它表示要发给周边所有设备,即广播)。如果要一对一进行通信(BLE称其为连接),即设备A的数据包只能设备B接收,同样设备B的数据包只能设备A接收,那么就必须生成一个独特的随机access address 以标识设备A和设备B两者之间的连接。

    广播方式

    我们先来看一下简单的广播情况,这种情况下,我们把设备A叫advertiser(广播者),设备B叫scanner或者observer(扫描者)。广播状态下设备A的LL层API将变成 send_LL(0x53,2402M, 0x8E89BED6)。由于设备B可以同时接收到很多设备的广播,因此数据包还必须包含设备A的device address(0xE1022AAB753B)以确认该广播包来自设备A,为此send_LL参数需要变成(0x53,2402M, 0x8E89BED6, 0xE1022AAB753B)。LL层还要检查数据的完整性,为此引入CRC24对数据包进行校验(假设为0xB2C78E)。同时为了调制解调电路工作更高效,每一个数据包的最前面会加上1个字节的帧头(一般为0x55或0xAA)。

    这样,整个空中包就变成:(空中包用小端模式表示)

    上面这个数据包还有如下问题:

    • (1)没有对数据包进行分类组织,设备B无法找到自己想要的数据0x53。为此需要在access address之后加入两个字段:LL header和长度字节。LL header用来表示数据包的LL类型,长度字节用来指明payload的长度。
    • (2)设备B什么时候开启射频窗口以接收空中数据包呢?如上图所示,只有case3的情况,通信才能成功,即设备A的数据包在空中传输时,设备B正好打开射频接收窗口,此时通信才能成功,换句话说,LL层还必须定义通信时序
    • (3)当设备B拿到数据0x53后,该如何解析这个数据呢?这就是GAP层要做的工作,GAP层引入了LTV(Length-Type-Value)结构来定义数据。比如020105, 02-长度,01-类型,05-值。由于广播包最大只能为31个字节,它能定义数据类型极其有限,像上边说的电量,GAP就没有定义,因此要通过广播方式把电量数据发出去,只能使用供应商自定义数据类型0xFF,即04FF590053(小端表示),其中04-长度,FF-自定义数据类型,0x0059-供应商ID(自定义数据中的强制字段,),0x53-数据(设备双方约定0x53就是表示电量)。

    最终,空中传输的数据包变为:(小端表示)

    AA D6BE898E 60 0E 3B75AB2A02E1 02010504FF5900 53 8EC7B2

    • AA – 前导帧(preamble)
    • D6BE898E – 访问地址(access address)
    • 60 – LL帧头字段(LL header)
    • 0E – 有效数据包长度(payload length)
    • 3B75AB2A02E1 – 广播者设备地址(advertiser address)
    • 02010504FF590053 – 广播数据
    • 8EC7B2 – CRC24值

    经过上边过程的封装(PHY、LL和GAP),就可以发送广播包了,但广播包携带的信息极其有限,而且还有如下几大限制:

    (1)无法进行一对一通信;

    (2)由于不支持组包和拆包,因此无法传输大数据;

    (3)通信不可靠。广播信道不能太多,否则将导致扫描效率低下。为此,BLE只使用37(2402MHz)、38(2426MHz)、39(2480MHz)三个信道进行广播和扫描,因此广播不支持跳频。由于广播是一对多,所以广播也无法支持ACK,这些都使得广播通信变得不可靠。

    跳频:收发双方按照同一时序不同变换频率,这个频率的变化规律一般由一个伪随机的序列控制,通信前要先同步,使得双方的序列同步。

    (4)扫描端功耗高。由于扫描端不知道设备端何时广播,也不知道设备端选用哪个频道进行广播,扫描端只能拉长扫描窗口时间,并同时对37/38/39三个通道进行扫描,这样功耗就会比较高。

    而连接则可以很好解决上述问题。

    连接方式

    所谓设备A和设备B建立蓝牙连接,就是指A、B两者“同步”成功,具体包含以下几方面:

    • A、B对接下来要使用的物理通道达成一致;
    • A、B双方建立一个共同的时间锚点,也就是说把双方的时间原点变为同一个点;
    • A、B两者时钟同步成功,即双方都知道什么时候发送/接收数据;

    连接成功后,A、B通信流程如下所示:

    如上图所示,一旦设备A和设备B连接成功(此种情况下,我们把设备A称为Master或者Central,把设备B称为Slave或者Peripheral),设备A将周期性以CI(connection interval)为间隔向设备B发送数据包,而设备B也周期性地以CI为间隔打开射频接收窗口以接收设备A的数据包。同时按照蓝牙spec要求,设备B收到设备A数据包150us后,设备B切换到发送状态,把自己的数据发给设备A;设备A则切换到接收状态,接收设备B发过来的数据。由此可见,连接状态下,设备A和设备B的射频发送和接收窗口都是周期性地有计划地开和关,而且开的时间非常短,从而大大减低系统功耗并大大提高系统效率。

    现在我们看看连接状态下是如何把数据0x53发送出去的,从中大家可以体会到蓝牙协议栈分层的妙处。

    (1)对开发者,很简单,他只需调用 send(0x53);

    (2)GATT层定义数据的类型和分组,我们假设用 0x0013 来表示电量这种数据类型,这样GATT层就把数据打包成 :130053(小端);

    (3)ATT层用来选择具体的通信命令,比如read/write/notify/indicate等,这里选择notify命令0x1B,这样数据包就变成了:1B130053;

    (4)L2CAP用来指定CI(connection interval,连接间隔),比如每10ms同步一次(CI不体现在数据包中),同时指定逻辑通道编号0004(表示ATT命令),最后把ATT数据长度0x0004加在包头,这样数据就变成:040004001B130053;

    (5)LL层要做很多事。

    ① 首先LL层需要指定用哪个物理信道进行传输(物理信道不体现在数据包中),

    ② 然后再给此连接分配一个Access address(0x50655DAB)以标识此连接只为设备A和设备B直连服务,

    ③ 然后加上LL header和payload length字段,LL header标识此packet为数据packet,而不是control packet等,payload length为整个L2CAP字段的长度,最后加上CRC24字段,以保证整个packet的数据完整性,

    所以数据包最后变成:

    AAAB5D65501E08040004001B130053D550F6

    • AA – 前导帧(preamble)
    • 0x50655DAB – 访问地址(access address)
    • 1E – LL帧头字段(LL header)
    • 08 – 有效数据包长度(payload length)
    • 04000400 – ATT数据长度,以及L2CAP通道编号
    • 1B – notify command
    • 0x0013 – 电量数据handle
    • 0x53 – 真正要发送的电量数据
    • 0xF650D5 – CRC24值

    虽然开发者只调用了 send(0x53),但由于低功耗蓝牙协议栈层层打包,最后空中实际传输的数据将变成下图所示的模样,这就既满足了低功耗蓝牙通信的需求,又让用户API变得简单,可谓一箭双雕!

    上面只是对BLE协议栈实现原理做了一个简单概述。对很多开发者来说,他们也不关心BLE协议栈是如何实现的,他们更关心的是BLE协议栈的使用,即怎么开发一个BLE应用。

    展开全文
  • 不同的应用场景有不同的需求,因此不同的应用场景对蓝牙实现方案的要求也不一样,从而催生不同的蓝牙架构实现方案,或者说蓝牙协议栈方案。 架构1:host+controller双芯片标准架构 蓝牙是跟随手机而诞生的,如何在...
  • 吐血推荐历史最全的蓝牙协议栈介绍

    万次阅读 多人点赞 2020-07-21 18:29:00
    第二篇:Transport层介绍,主要介绍蓝牙协议栈跟蓝牙芯片之前的硬件传输协议,比如基于UART的H4,H5,BCSP,基于USB的H2等 第三篇:传统蓝牙controller介绍,主要介绍传统蓝牙芯片的介绍,包括射频层(RF),基带层...
  • lwlibs 是一个小巧的蓝牙、TCPIP协议栈,本资源中包含有其源代码。另外还尝试在MTK平台上做了一次简单移植。 仅供学习。
  • 蓝牙协议栈概述

    2021-01-05 19:37:08
    蓝牙协议栈概述 蓝牙协议栈的信息源头是https://www.bluetooth.com 蓝牙协议栈的所有者是蓝牙技术联盟。它有七个公司为它的核心成员 这些公司包括爱立信,英特尔,微软,联想,东芝,三星、朗讯 蓝牙的版本发展 从...
  • 主要介绍下蓝牙协议栈开发板跑传统蓝牙串口协议SPP AT指令以及上位机操作步骤,以及原理 一. 声明 本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下: 第一篇:蓝牙综合介绍 ,主要介绍蓝牙的一些...
  • 蓝牙协议栈记录—BTStack

    千次阅读 2021-05-24 02:30:05
    简介2.BTStack 架构BTStack在所实现的协议和服务之间采用很多状态机实现相互作用,特点:<1>单线程.BTStack只有一个单独的循环。<2>没有阻塞,采用event事件方式。<3>No artficially limited ...
  • 主要介绍下用Linux ubuntu虚拟机外接我们的蓝牙扩展版跑蓝牙协议栈的初始化以及搜索演示 一. 声明 本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下: 第一篇:蓝牙综合介绍 ,主要介绍蓝牙的一些...
  • 蓝牙协议栈5.0

    2018-04-27 13:55:42
    蓝牙核心协议栈 Core5.0,对蓝牙开发很有帮主。。。。。
  • 蓝牙协议分析(2)_协议架构 摘录自BLE协议框架:这篇文章简单介绍协议栈的内容 1. Physical Layer: 2.LinkLayer: 1.状态和角色的定义:Standby,Initiating,Advertising,Scanning,Connection,五种链路状态 2.Air ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,661
精华内容 5,064
关键字:

蓝牙协议栈