如今的社会已经从IT时代过渡到了DT时代,数据的重要性不言而喻。将数据安全快速的传输给对方是一件非常重要的事情,如今诞生了很多不同的传输技术,每一种传输技术都是为了和对方进行数据交互。BLE技术也是这样,它的最终目的就是为了在两个设备间进行数据交互。我们从BLE的本质出发,搞清楚它是如何实现数据交互的,也就真正搞清楚了BLE的工作原理。

下面从3个方面,逐步讲解BLE的数据收发过程。

本文结合nordic的代码和蓝牙核心规范5.2来进行介绍。本文认为你对BLE协议栈的各个层已经有了一个大概认识,对BLE协议栈还不太熟悉的朋友可以参看拙作:蓝牙低功耗(BLE)协议栈

一 广播

1.1 从设备

从设备想要别人能够发现自己就需要不停的进行广播。

Host层通过HCI层定义的接口来设置广播数据。

HCI层的命令格式如下图:

设置广播数据的命令格式如下图:

指令详细介绍参看:蓝牙核心卷 5.2 , Vol 4, Part E, 7.8.7

  • OpCode,0x0008,两个字节
  • parameter Total Length,一个字节,也就是Advertising_Data_Length,根据Advertising_Data计算得来
  • Advertising_Data, 由HCI 以上层传下来

事实上只有Advertising_Data会通过空中发送。Advertising_Data的格式如下:

详细介绍参看:蓝牙核心卷 5.2 , Vol 3, Part C, 11

可以看到广播数据可能有多个元素:AD Structure 1,AD Structure 2 … AD Structure N,每一个AD Structure的格式为,1个字节长度,一个字节AD Type,n个字节的AD Data。广播数据包也遵循一定的格式,广播包的数据格式参看:AD Type和Core Specification Supplement

LL层定义的广播报文的格式如下图:

详细介绍参看:蓝牙核心卷 5.2 , Vol 6, Part B, 2.3

  1. 用户设置广播参数和广播内容
    ble_gap.h
//设置广播参数,以及广播类容
uint32_t sd_ble_gap_adv_set_configure(uint8_t *p_adv_handle, ble_gap_adv_data_t const *p_adv_data, ble_gap_adv_params_t const *p_adv_params)
  • 设置广播参数,ocf=0x006,ogf=0x08
    命令格式:

    gap协议层会根据HCI层提供的接口来设置广播参数

  • 设置广播数据,ocf=0x0008,ogf=0x08
    gap协议层会根据HCI层提供的接口来设置广播数据

  1. 开启广播
    命令格式:

    gap层提供的函数接口:uint32_t sd_ble_gap_adv_start(uint8_t adv_handle, uint8_t conn_cfg_tag)
    HCI层提供的接口,ocf=0x00a,ogf=0x08

  2. 广播的具体数据
    通过抓包工具得到的广播包的数据:

  • aa, 前导码

  • d6 be 89 8e,接入地址:0x8e89bed6。(蓝牙传输均使用小端模式)

  • 40 19,报头

    • 0000b,PDU Type,ADV_IND,普通广播. 详见:Vol 6, Part B, 2.3, Table 2.3
    • 0b, RFU,未使用
    • 0b, ChSel, 通道选择,未使用
    • 1b,TxAdd,广播者的mac地址类型,1表示随机地址
    • 0b,RxAdd, 扫描者mac地址类型,未知
    • 19,数据长度,指的是Payload的长度
  • 8b 89 e6 26 c9 4c: 0x4cc926e6898b mac地址, Payload的一部分

  • 02 01 1a , AD Structure 1,广播报文的第一个元素

    • 02,长度
    • 01,类型,«Flags»
    • 1a,数据
  • 02 0a 0c

    • 02, 长度
    • 0a,类型,«Tx Power Level»
    • 0x,数据
  • 0c ff 4c 00 10 07 57 1f 6c 06 2f 1d 98

    • 0c,长度
    • 0xff,自定义类型
    • 4c 00 10 07 57 1f 6c 06 2f 1d 98 ,数据
      • 4c 00, 前两个字节代表厂商,0x004c代表Apple, Inc.厂商定义

      • 10 07 57 1f 6c 06 2f 1d 98, 自定义的数据

  • 7b 53 ef,0xef537b CRC校验

从设备设置的广播数据流向:用户调用GAP提供的接口,GAP调用HCI层接口,HCI层再传给LL层。

1.2 主设备

  • 设置扫描参数
  • 开启扫描

/**@brief GAP scanning parameters. */
typedef struct
{uint8_t               extended               : 1; /**< If 1, the scanner will accept extended advertising packets.If set to 0, the scanner will not receive advertising packetson secondary advertising channels, and will not be ableto receive long advertising PDUs.@note Extended scanning is only supported as an experimental feature in thisSoftDevice. */uint8_t               report_incomplete_evts : 1; /**< If 1, events of type @ref ble_gap_evt_adv_report_t may have@ref ble_gap_adv_report_type_t::status set to@ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA.This parameter is ignored when used with @ref sd_ble_gap_connect@note This may be used to abort receiving more packets from an extendedadvertising event, and is only available for extendedscanning, see @ref sd_ble_gap_scan_start.@note This feature is not supported by this SoftDevice. */uint8_t               active                 : 1; /**< If 1, perform active scanning by sending scan requests.This parameter is ignored when used with @ref sd_ble_gap_connect. */uint8_t               filter_policy          : 2; /**< Scanning filter policy. @sa BLE_GAP_SCAN_FILTER_POLICIES.@note Only @ref BLE_GAP_SCAN_FP_ACCEPT_ALL and@ref BLE_GAP_SCAN_FP_WHITELIST are valid when used with@ref sd_ble_gap_connect */uint8_t               scan_phys;                  /**< Bitfield of PHYs to scan on. If set to @ref BLE_GAP_PHY_AUTO,scan_phys will default to @ref BLE_GAP_PHY_1MBPS.- If @ref ble_gap_scan_params_t::extended is set to 0, the onlysupported PHY is @ref BLE_GAP_PHY_1MBPS.- When used with @ref sd_ble_gap_scan_start,the bitfield indicates the PHYs the scanner will use for scanningon primary advertising channels. The scanner will accept@ref BLE_GAP_PHYS_SUPPORTED as secondary advertising channel PHYs.- When used with @ref sd_ble_gap_connect, thebitfield indicates the PHYs on where a connection may be initiated.If scan_phys contains @ref BLE_GAP_PHY_1MBPS and/or @ref BLE_GAP_PHY_2MBPS,the primary scan PHY is @ref BLE_GAP_PHY_1MBPS.If scan_phys also contains @ref BLE_GAP_PHY_CODED, the primary scanPHY will also contain @ref BLE_GAP_PHY_CODED. If the only scan PHY is@ref BLE_GAP_PHY_CODED, the primary scan PHY is@ref BLE_GAP_PHY_CODED only. */uint16_t              interval;                   /**< Scan interval in 625 us units. @sa BLE_GAP_SCAN_INTERVALS. */uint16_t              window;                     /**< Scan window in 625 us units. @sa BLE_GAP_SCAN_WINDOW. */uint16_t              timeout;                    /**< Scan timeout in 10 ms units. @sa BLE_GAP_SCAN_TIMEOUT. */ble_gap_ch_mask_t     channel_mask;               /**< Channel mask for primary and secondary advertising channels.At least one of the primary channels, that is channel index 37-39, must beset to 0.Masking away secondary channels is not supported. */
} ble_gap_scan_params_t;
/**@brief Data structure. */
typedef struct
{uint8_t     *p_data;  /**< Pointer to the data buffer provided to/from the application. */uint16_t     len;     /**< Length of the data buffer, in bytes. */
} ble_data_t;//用户调用该函数,进行设置扫描参数,同时开始扫描
uint32_t sd_ble_gap_scan_start(ble_gap_scan_params_t const *p_scan_params, ble_data_t const * p_adv_report_buffer);

HCI层提供的接口:

  • 设置扫描参数
    设置扫描参数的指令格式:

    HCI层提供的接口:ogf=0x08,ocf=0x00b
  • 开启扫描

    HCI层提供的接口:ogf=0x08,ocf=0x00c

二 连接

typedef struct
{uint8_t addr_id_peer : 1;       /**< Only valid for peer addresses.Reference to peer in device identities list (as set with @ref sd_ble_gap_device_identities_set) when peer is using privacy. */uint8_t addr_type    : 7;       /**< See @ref BLE_GAP_ADDR_TYPES. */uint8_t addr[BLE_GAP_ADDR_LEN]; /**< 48-bit address, LSB format. */
} ble_gap_addr_t;typedef struct
{uint16_t min_conn_interval;         /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/uint16_t max_conn_interval;         /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/uint16_t slave_latency;             /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/uint16_t conn_sup_timeout;          /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/
} ble_gap_conn_params_t;
/*
p_peer_addr: 对端设备地址
p_scan_params:扫描参数
p_conn_params:连接参数
conn_cfg_tag:连接配置标识
*/
uint32_t sd_ble_gap_connect(ble_gap_addr_t const *p_peer_addr, ble_gap_scan_params_t const *p_scan_params, ble_gap_conn_params_t const *p_conn_params, uint8_t conn_cfg_tag)

HCI层连接命令的格式:

LL层连接请求格式:

HCI层接口:

连接请求

在空中传播的数据:

aa d6 be 89 8e c5 22 81 1b f2 8e 55 68 d0 a3 1a d7 7b d0 cf c5 ca 6a e6 c7 ee 02 16 00 28 00 00 00 f4 01 ff ff ff ff 1f 26 2a de cc

  • aa,前导码
  • d6 be 89 8e,0x8e89bed6接入地址
  • LL 报头 C5(1100 0101) 22
    • 0101b, 数据类型, CONNECT_IND,连接请求
    • 0b, RFU,未使用
    • 0b, ChSel, 通道选择,未使用
    • 1b,TxAdd,发起者的mac地址类型,1表示随机地址
    • 1b,RxAdd, 接收者的mac地址类型,1表示随机地址
    • 22, 0x22 Payload长度
  • Payload
    • 81 1b f2 8e 55 68, 发起者的Mac地址0x68558ef21b81
    • d0 a3 1a d7 7b d0,接受者的mac地址0xd07bd71aa3d0
    • cf c5 ca 6a,用于连接的计入地址0x6acac5cf
    • e6 c7 ee,CRC初始值0xeec7e6
    • 02,传输窗口大小,单位1.25ms
    • 16 00,传输窗口偏移,单位1.25ms
    • 28 00, 连接间隔,0x0028,单位1.25ms
    • 00 00, 从设备延时,0x0000
    • f4 01, 超时时间,0x01f4,单位10ms
    • ff ff ff ff 1f, 通道图,表示哪些信道是好的 0x1f ff ff ff ff,最高的3位保留,其余位表示通信的信道,1表示可用,0表示不可用。
    • 26(001 00110), SCA & Hope
      • 001b, 高三位SCA,主设备时钟精度
    • 00110b,低5位,hope值,6
    • 2a de cc,CRC校验,0xccde2a

HCI层会根据GAP传下来的参数,组合成LL层需要的数据格式,也就是黄色部分的数据。实际上GAP会按照HCI提供的接口所要求的参数格式传参。这里重点是突出空中传播的数据部分,因此统一使用LL层的格式。

三 发现服务

3.1 发现分组服务

发现主服务的过程

用户调用sd_ble_gattc_primary_services_discover:

uint32_t sd_ble_gattc_primary_services_discover(uint16_t conn_handle, uint16_t start_handle, ble_uuid_t const *p_srvc_uuid)

协议栈的调用:

发送的数据aa cc c5 ca 6a 0e 0b 07 00 04 00 10 01 00 ff ff 00 28 cf 2d 83

  • aa: 前导码
  • cc c5 ca 6a: 接入地址,0x6acac5cc
  • 0e 0b,LL层报头
    • 10b,LLID,表示开始报文
    • 1b,NESE(预期序列号)
    • 1b,序列号(SN)
    • 0b,MD(更多数据)
    • 0b,CP(是否包含CTEinfo)
    • 最高两位,RFU保留
    • 0b,Payload长度
  • 07 00 04 00,L2CAP层报头
    • 07 00,Length,Information Payload长度,0x0007
    • 04 00,通道号,0x0004
  • 10 01 00 ff ff 00 28,ATT层数据
    • 10,请求类型,ATT_READ_BY_GROUP_TYPE_REQ
    • 01 00,开始Handle,0x0001
    • ff ff,结束Handle,0xffff
    • 00 28,UUID类型,0x2800,表示主要服务
  • cf 2d 83,CRC校验,0x832dcf


3.2 发现分组服务响应

响应命令的数据格式:

空中传播的数据

aa cc c5 ca 6a 06 12 0e 00 04 00 11 06 01 00 09 00 00 18 0a 00 0a 00 01 18 a8 64 7c

四 数据交互

4.1 主设备写命令

ATT层数据格式:

typedef struct
{uint8_t        write_op;             /**< Write Operation to be performed, see @ref BLE_GATT_WRITE_OPS. */uint8_t        flags;                /**< Flags, see @ref BLE_GATT_EXEC_WRITE_FLAGS. */uint16_t       handle;               /**< Handle to the attribute to be written. */uint16_t       offset;               /**< Offset in bytes. @note For WRITE_CMD and WRITE_REQ, offset must be 0. */uint16_t       len;                  /**< Length of data in bytes. */uint8_t const *p_value;              /**< Pointer to the value data. */
} ble_gattc_write_params_t;
uint32_t sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const *p_write_params)

协议栈处理流程:

  • 用户层设置连接句柄,以及需要发送的数据信息
  • ATT层获得L2CAP层的buffer指针,并填充发送消息类型,需要写的属性句柄,以及真实的数据。消息类型和句柄必须要占用3个字节的空间,因此有效数据长度不能大于MTU_SIZE - 3。调用L2CAP层的装载函数,并指明数据长度和通道ID
  • L2CAP层获取HCI层的数据buffer指针之后首先构建一个HCI的头,并把有效数据装载到buffer中

4.2 从设备发出通知


详解BLE的数据传输过程相关推荐

  1. 详解BLE 空中包格式—兼BLE Link layer协议解析

    BLE有几种空中包格式?常见的PDU命令有哪些?PDU和MTU的区别是什么?DLE又是什么?BLE怎么实现重传的?BLE ACK机制原理是什么?希望这篇文章能帮你回答以上问题. 虽然BLE空中包(pa ...

  2. php里面的socket编程,详解PHP Socket 编程过程

    详解PHP Socket 编程过程 作者:PHPYuan 时间:2019-03-13 03:41:20 概述 Socket用于进程间通信.进程间通信通常基于客户端-服务端模型.此时,客户端-服务端是可 ...

  3. 多图详解freeBSD8.2安装过程

    多图详解freeBSD8.2安装过程 Wmware新建freeBSD虚拟机,光盘挂载freeBSD.iso.真机光驱放freeBSD光盘,修改bios光驱启动,选择1安装系统,选择4则可以修改root ...

  4. XGBRegressor参数详解以及调参过程

    XGBRegressor参数详解以及调参过程 一.参数 1.通用参数booster.nthread 2.学习目标参数 (1)objective (2)eval_metric (3)seed 3.Tre ...

  5. Mac下使用Fiddler抓包详解(个人使用过程)

    Mac下使用Fiddler抓包详解(个人使用过程) 前言 1.VMware Fusion for Mac 2.win7镜像 3.windows版fiddler mac使用Windows fiddler ...

  6. 红黑树操作详解——很形象的过程

    红黑树是一种很好的自平衡二叉排序树,在此,给出一个网友给出的红黑树操作详解: https://segmentfault.com/a/1190000012728513 里面给出了红黑树的详细操作,过程很 ...

  7. response.setHeader()的用法详解及实现文件下载过程中出现问题的分析

    response.setHeader()用法详解,转载记录: 1. HTTP消息头 (1)通用信息头 即能用于请求消息中,也能用于响应信息中,但与被传输的实体内容没有关系的信息头,如Data,Prag ...

  8. C语言详解生成随机数的过程,time函数、时间戳timer、rand函数和srand函数,附猜数字小游戏

    第十一篇:随机数详解 一.准备工作(预备知识) 1.1.生成伪随机数(函数rand) 1.2.伪随机数"变成"随机数(函数time) 1.3.生成确定范围随机数 二.练手随机数经典 ...

  9. 读写分离 mysql_详解MySQL实现主从复制过程及mycat读写分离步骤

    一.什么是主从复制 将主数据库中的DDL和DML操作通过二进制日志(BINLOG)传输到从数据库上,然后将这些日志重新执行(重做):从而使得从数据库的数据与主数据库保持一致. 二.主从复制的作用 1. ...

最新文章

  1. C 函数 toascii
  2. 自由自在公司冰淇淋甜美的健康文化
  3. 后缀数组求最长重复子串
  4. 四、Spring中使用@Conditional按照条件注册Bean
  5. 关于jquery基本过滤器中:eq()无法传变量的问题
  6. 功能安全 李艳文_李艳文:智能网联全新安全问题凸显 相关自动驾驶事故逐年增加...
  7. AngularJS+ASP.NET MVC+SignalR实现消息推送
  8. HDOJ--1596--find the safest road
  9. 【标准】ISO14001:2015新版标准正式发布
  10. 安装protoc教程
  11. 华为OS操作系统,最早今秋面世!
  12. [2011JMAA]Remarks on the regularity criteria for generalized MHD equations
  13. 在计算机中有什么作用,内存是什么在电脑中有什么作用
  14. 1055 集体照 (25 分)(详解)
  15. vue buid打包,修改环境变量
  16. DPDK — 安装部署
  17. 解决-Dmaven.multiModuleProjectDirectory system property is not set. Check $M2_HO问题
  18. C语言中的常用循环语句
  19. win10内置Ubuntu安装图形界面
  20. EverBox 能否成为中国的dropbox

热门文章

  1. 微信公众平台上传图片,自动回复图片
  2. app微博card链接
  3. win10闪讯用户网络图标消失
  4. matlab用进退法写程序,matlab编写的进退法,黄金分割法,抛物线法(二次插值法),wolfe不精确一维搜索...
  5. zabbix--问题
  6. 39页PPT-巷道式堆垛机的结构教程
  7. PMP考试的报名时间
  8. 【Excel】VLOOKUP使用后出现#SPILL!是怎么回事?
  9. 如何用计算机测量图片景深,OPPO AR测量功能上线!R17 Pro实现景深距离测量
  10. AD19原理图电气检测与编译