赞
踩
如今的社会已经从IT时代过渡到了DT时代,数据的重要性不言而喻。将数据安全快速的传输给对方是一件非常重要的事情,如今诞生了很多不同的传输技术,每一种传输技术都是为了和对方进行数据交互。BLE技术也是这样,它的最终目的就是为了在两个设备间进行数据交互。我们从BLE的本质出发,搞清楚它是如何实现数据交互的,也就真正搞清楚了BLE的工作原理。
下面从3个方面,逐步讲解BLE的数据收发过程。
本文结合nordic的代码和蓝牙核心规范5.2来进行介绍。本文认为你对BLE协议栈的各个层已经有了一个大概认识,对BLE协议栈还不太熟悉的朋友可以参看拙作:蓝牙低功耗(BLE)协议栈
从设备想要别人能够发现自己就需要不停的进行广播。
Host层通过HCI层定义的接口来设置广播数据。
HCI层的命令格式如下图:
设置广播数据的命令格式如下图:
指令详细介绍参看:蓝牙核心卷 5.2 , Vol 4, Part E, 7.8.7
事实上只有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
//设置广播参数,以及广播类容
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层提供的接口来设置广播数据
开启广播
命令格式:
gap层提供的函数接口:uint32_t sd_ble_gap_adv_start(uint8_t adv_handle, uint8_t conn_cfg_tag)
HCI层提供的接口,ocf=0x00a,ogf=0x08
广播的具体数据
通过抓包工具得到的广播包的数据:
aa, 前导码
d6 be 89 8e,接入地址:0x8e89bed6。(蓝牙传输均使用小端模式)
40 19,报头
8b 89 e6 26 c9 4c: 0x4cc926e6898b mac地址, Payload的一部分
02 01 1a , AD Structure 1,广播报文的第一个元素
02 0a 0c
0c ff 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层。
/**@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);
HCI层提供的接口:
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
HCI层会根据GAP传下来的参数,组合成LL层需要的数据格式,也就是黄色部分的数据。实际上GAP会按照HCI提供的接口所要求的参数格式传参。这里重点是突出空中传播的数据部分,因此统一使用LL层的格式。
发现主服务的过程
用户调用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 06 12 0e 00 04 00 11 06 01 00 09 00 00 18 0a 00 0a 00 01 18 a8 64 7c
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)
协议栈处理流程:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。