当前位置:   article > 正文

详解BLE的数据传输过程_ble数据传输

ble数据传输

如今的社会已经从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 TypeCore 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)
  • 1
  • 2
  • 设置广播参数,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 packets
                                                         on secondary advertising channels, and will not be able
                                                         to receive long advertising PDUs.
                                                         @note Extended scanning is only supported as an experimental feature in this
                                                               SoftDevice. */
  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 extended
                                                               advertising event, and is only available for extended
                                                               scanning, 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 only
                                                           supported 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 scanning
                                                           on 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, the
                                                           bitfield 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 scan
                                                           PHY 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 be
                                                         set 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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

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
  • 1

在这里插入图片描述

  • 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)
  • 1

协议栈的调用:
在这里插入图片描述
发送的数据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
  • 1

在这里插入图片描述

在这里插入图片描述

四 数据交互

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

协议栈处理流程:

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

在这里插入图片描述

在这里插入图片描述

4.2 从设备发出通知

在这里插入图片描述
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/573714
推荐阅读
相关标签
  

闽ICP备14008679号