概述
BLE支持的特性:
蓝牙HOST特性
GAP支持的角色:Peripheral与Central,Observer与Broadcaster
GATT支持的角色:Server与Client
支持配对包括蓝牙4.2中的安全连接特性
支持永久存储蓝牙特定的设置和数据
蓝牙mesh特性
TODO
总共有3个主要层,共同构成了一个完整的蓝牙低能耗协议栈
Host:这一层位于应用程序之下,由多个(非实时)网络和传输协议组成,使应用程序能够以标准和互操作的方式与对等设备通信。
Controller:控制器实现了链路层(LE LL),这是一种低层次的实时协议,它与无线电硬件一起提供了空中通信的标准互操作。LL处理包的接收和传输,保证数据的传递,并处理所有LL控制程序。
Radio Hardware:实现所需的模拟和数字基带功能块,允许链路层固件在频谱的2.4GHz波段发送和接收。
蓝牙Host层实现了所有高级协议和配置文件,最重要的是它为应用程序提供了高级API
HCI:Host与controller接口
L2CAP:逻辑链路控制和适应协议
GATT:通用属性配置层(Generic Attribute Profile)
GAP:通用访问配置层(Generic Access Profile)
SMP:安全管理器配置层(Security Manager Specification)
应用Application
应用层是用户开发实际蓝牙应用的地方,包含必要的协议栈参数设置,以及各种功能函数的调用。我们分别从蓝牙从机和蓝牙主机两种设备来分析。
蓝牙从机
相关硬件和基础服务初始化
设置广播参数:广播数据,广播间隔,扫描回应等参数或者数据
设置Profile:添加从机服务、特征值,还有设置回调函数用于接收主机数据等
设置配对参数(可选)
启动广播,开始运行
等待相关事件,及事件处理,例如收到主机发来的数据,被链接等等
蓝牙主机
相关硬件和基础服务初始化
设置扫描参数
设置连接参数
设置配对参数(可选)
启动协议栈,开始运行
等待相关事件,及事件处理,例如扫描事件,从机的Notify事件等等。
5.2. BLE 接口
5.2.1. ble_controller_init
ble_controller_init 主要是对 ble controller 层初始化。
void ble_controller_init(uint8_t task_priority);
task_priority 任务优先级
5.2.2. hci_driver_init
hci_driver_init 主要是对 HCI 接口驱动初始化。
int hci_driver_init(void);
5.2.3. bt_enable
bt_enable 用来使能 ble 。
int bt_enable(bt_ready_cb_t cb);
cb 注册成功时的回调函数
5.2.4. bt_le_adv_start
bt_le_adv_start 用来开启 BLE 广播。
int bt_le_adv_start(const struct bt_le_adv_param *param,const struct bt_data *ad, size_t ad_len,
const struct bt_data *sd, size_t sd_len);
param 指向广播配置参数指针
ad 指向广播包中数据指针
ad_len 广播包中数据的长度
sd 指向扫描响应包数据指针
sd_len 扫描响应包数据的长度
5.2.5. bt_le_adv_update_data
bt_le_adv_update_data 用来更新 BLE 广播数据。
int bt_le_adv_update_data(const struct bt_data *ad, size_t ad_len,const struct bt_data *sd, size_t sd_len);
ad 指向广播包中数据指针
ad_len 广播包中数据的长度
sd 指向扫描响应包数据指针
sd_len 扫描响应包数据的长度
5.2.6. bt_le_adv_stop
bt_le_adv_stop 用来停止 BLE 广播。
int bt_le_adv_stop(void);
5.2.7. bt_le_scan_start
bt_le_scan_start 用来开启 BLE 扫描。
int bt_le_scan_start(const struct bt_le_scan_param *param, bt_le_scan_cb_t cb);
param 指向扫描参数的指针
cb 扫描回调函数
5.2.8. bt_le_scan_stop
bt_le_scan_stop 用来停止 BLE 扫描。
int bt_le_scan_stop(void);
5.2.9. bt_le_whitelist_add
bt_le_whitelist_add 用来通过地址添加设备到白名单列表中。
int bt_le_whitelist_add(const bt_addr_le_t *addr);
addr 指向需要添加设备地址的指针
5.2.10. bt_le_whitelist_rem
bt_le_whitelist_rem 用来将设备从白名单列表中移除。
int bt_le_whitelist_rem(const bt_addr_le_t *addr);
addr 指向需要移除设备地址的指针
5.2.11. bt_le_whitelist_clear
bt_le_whitelist_clear 用来清除白名单列表。
int bt_le_whitelist_clear(void);
5.2.12. bt_le_set_chan_map
bt_le_set_chan_map 用来设置(LE)通道映射。
int bt_le_set_chan_map(u8_t chan_map[5]);
chan_map 通道数组
5.2.13. bt_unpair
bt_unpair 用来清除配对信息。
int bt_unpair(u8_t id, const bt_addr_le_t *addr);
id 本地标识(大多只是默认的BT ID)
addr 远端设备地址,NULL或者BT_ADDR_LE_ANY清除所有远端设备
5.2.14. bt_conn_get_info
bt_conn_get_info 用来获取当前连接设备的信息。
int bt_conn_get_info(const struct bt_conn *conn, struct bt_conn_info *info);
conn 指向当前连接的指针
info 指向当前连接设备信息的指针
5.2.15. bt_conn_get_remote_dev_info
bt_conn_get_remote_dev_info 用来获取已连接设备的信息。
int bt_conn_get_remote_dev_info(struct bt_conn_info *info);
info 指向当前连接设备信息的指针
5.2.16. bt_conn_le_param_update
bt_conn_le_param_update 用来更新连接参数。
int bt_conn_le_param_update(struct bt_conn *conn,const struct bt_le_conn_param *param);
conn 指向当前连接的指针
param 指向连接参数的指针
5.2.17. bt_conn_disconnect
bt_conn_disconnect 用来断开当前连接。
int bt_conn_disconnect(struct bt_conn *conn, u8_t reason);
conn 指向当前连接的指针
reason 断开当前连接的原因
5.2.18. bt_conn_create_le
bt_conn_create_le 用来创建连接。
struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer,const struct bt_le_conn_param *param);
peer 需要连接设备地址的指针
param 指向连接参数指针
return 成功:有效的连接对象,否则失败
5.2.19. bt_conn_create_auto_le
bt_conn_create_auto_le 用来自动创建连接白名单列表中的设备。
int bt_conn_create_auto_le(const struct bt_le_conn_param *param);
param 指向连接参数指针
5.2.20. bt_conn_create_auto_stop
bt_conn_create_auto_stop 用来停止自动创建连接白名单列表中的设备。
int bt_conn_create_auto_stop(void);
5.2.21. bt_le_set_auto_conn
bt_le_set_auto_conn 用来自动创建连接远端设备。
int bt_le_set_auto_conn(const bt_addr_le_t *addr,const struct bt_le_conn_param *param);
addr 远端设备地址指针
param 指向连接参数指针
5.2.22. bt_conn_create_slave_le
bt_conn_create_slave_le 用来发起定向的广播包给远端设备。
struct bt_conn *bt_conn_create_slave_le(const bt_addr_le_t *peer,const struct bt_le_adv_param *param);
peer 远端设备地址指针
param 指向广播参数的指针
return 成功:有效的连接对象,否则失败
5.2.23. bt_conn_set_security
bt_conn_set_security 用来设置连接安全等级。
int bt_conn_set_security(struct bt_conn *conn, bt_security_t sec);
conn 指向连接对象的指针
sec 安全等级
5.2.24. bt_conn_get_security
bt_conn_get_security 用来获取当前连接的安全等级。
bt_security_t bt_conn_get_security(struct bt_conn *conn);
conn 指向连接对象的指针
5.2.25. bt_conn_enc_key_size
bt_conn_enc_key_size 用来获取当前连接的加密key的大小。
u8_t bt_conn_enc_key_size(struct bt_conn *conn);
conn 指向连接对象的指针
return 加密key的大小
5.2.26. bt_conn_cb_register
bt_conn_cb_register 用来注册连接回调函数。
void bt_conn_cb_register(struct bt_conn_cb *cb);
cb 连接回调函数
5.2.27. bt_set_bondable
bt_set_bondable 用来设置/清除SMP配对请求/响应数据认证需求中的绑定标志。
void bt_set_bondable(bool enable);
enable 1,使能,0:不使能
5.2.28. bt_conn_auth_cb_register
bt_conn_auth_cb_register 用来注册认证回调函数。
int bt_conn_auth_cb_register(const struct bt_conn_auth_cb *cb);
cb 回调函数指针
5.2.29. bt_conn_auth_passkey_entry
bt_conn_auth_passkey_entry 用密钥回复对方。
int bt_conn_auth_passkey_entry(struct bt_conn *conn, unsigned int passkey);
conn 连接对象指针
passkey 输入的密钥
5.2.30. bt_conn_auth_cancel
bt_conn_auth_cancel 用来取消认证过程。
int bt_conn_auth_cancel(struct bt_conn *conn);
conn 连接对象指针
5.2.31. bt_conn_auth_passkey_confirm
bt_conn_auth_passkey_confirm 用来当密码匹配时,回复对方。
int bt_conn_auth_passkey_confirm(struct bt_conn *conn);
conn 连接对象指针
5.2.32. bt_conn_auth_pincode_entry
bt_conn_auth_pincode_entry 用 PIN 码进行回复对方。
int bt_conn_auth_pincode_entry(struct bt_conn *conn, const char *pin);
conn 连接对象指针
pin PIN 码的指针
5.2.33. bt_le_read_rssi
bt_le_read_rssi 用来读取对方 RSSI 值。
int bt_le_read_rssi(u16_t handle,int8_t *rssi);
handle 连接的句柄值
rssi 保存 rssi 的指针
5.2.34. bt_get_local_address
bt_get_local_address 用来读取本机的地址。
int bt_get_local_address(bt_addr_le_t *adv_addr);
adv_addr 保存读取地址的指针
5.2.35. bt_set_tx_pwr
bt_set_tx_pwr 用来设置本机发射功率。
int bt_set_tx_pwr(int8_t power);
power 功率值
5.3. 数据结构参考
bt_le_adv_param 数据结构:
struct bt_le_adv_param {
u8_t id;
u8_t options;
u16_t interval_min;
u16_t interval_max;
#if defined(CONFIG_BT_STACK_PTS)
u8_t addr_type;
#endif
};
此数据结构用来配置广播参数,包括本地识别id、广播选项位域、广播间隙等,其中广播选项位域有如下枚举类型参数可选:
enum {
BT_LE_ADV_OPT_NONE = 0,
BT_LE_ADV_OPT_CONNECTABLE = BIT(0),
BT_LE_ADV_OPT_ONE_TIME = BIT(1),
BT_LE_ADV_OPT_USE_IDENTITY = BIT(2),
BT_LE_ADV_OPT_USE_NAME = BIT(3),
BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY = BIT(4),
BT_LE_ADV_OPT_DIR_ADDR_RPA = BIT(5),
BT_LE_ADV_OPT_FILTER_SCAN_REQ = BIT(6),
BT_LE_ADV_OPT_FILTER_CONN = BIT(7),
};
如果需要发送一个广播包,配置可以如下:
param.id = 0
param.options = (BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_USE_NAME | BT_LE_ADV_OPT_ONE_TIME)
param.interval_min = 0x00a0
param.interval_max = 0x00f0
bt_data 数据结构:
struct bt_data {
u8_t type;
u8_t data_len;
const u8_t *data;
};
此数据结构用来填充广播包中的数据,具体的数据包类型可以参考如下:
Service UUID
Local Name
Flags
Manufacturer Specific Data
TX Power Level
Secure Simple Pairing OOB
Security Manager OOB
Security Manager TK Value
Slave Connection Interval Range
Service Solicitation
Service Data
Appearance
Public Target Address
Random Target Address
Advertising Interval
LE Bluetooth Device Address
LE Role
Uniform Resource Identifier
LE Supported Features
Channel Map Update Indication
用该数据结构配置一个广播包数据,如下所示:
struct bt_data ad_discov[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
BT_DATA(BT_DATA_NAME_COMPLETE, "BL602-BLE-DEV", 13),
};
bt_le_scan_param 数据结构:
struct bt_le_scan_param {
u8_t type;
u8_t filter_dup;
u16_t interval;
u16_t window;
};
此数据结构用来填充扫描参数, type:为扫描类型有2种类型BT_LE_SCAN_TYPE_ACTIVE(0x01)、BT_LE_SCAN_TYPE_PASSIVE(0x00)。 filter_dup:0x00,除定向广告外,接受所有广播和扫描响应,0x01,只接收白名单列表中设备的广播和扫描响应。 interval:扫描间隙。 window:扫描窗口。
如果开启扫描请求,可以配置如下:
scan_param.type = BT_LE_SCAN_TYPE_PASSIVE
scan_param.filter_dup = 0x00
interval=BT_GAP_SCAN_SLOW_INTERVAL_1
window=BT_GAP_SCAN_SLOW_WINDOW_1
bt_le_conn_param 数据结构:
struct bt_le_conn_param {
u16_t interval_min;
u16_t interval_max;
u16_t latency;
u16_t timeout;
#if defined(CONFIG_BT_STACK_PTS)
u8_t own_address_type;
#endif
};
此数据结构用来填充连接参数,interval_min:连接间隙最少值(0x0018),interval_max:连接间隙最大值(0x0028), latency:指定为连接事件数的连接允许的最大从延迟。 timeout:连接超时时间。
配置该数据结构,如下:
interval_min=BT_GAP_INIT_CONN_INT_MIN(0x0018)
interval_max=BT_GAP_INIT_CONN_INT_MAX(0x0028)
latency=0
timeout=400
bt_conn 数据结构:
struct bt_conn {
u16_t handle;
u8_t type;
u8_t role;
ATOMIC_DEFINE(flags, BT_CONN_NUM_FLAGS);
u8_t id;
#if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR)
bt_security_t sec_level;
bt_security_t required_sec_level;
u8_t encrypt;
#endif
u8_t err;
bt_conn_state_t state;
u16_t rx_len;
struct net_buf *rx;
sys_slist_t tx_pending;
u32_t pending_no_cb;
sys_slist_t tx_complete;
struct k_work tx_complete_work;
struct k_fifo tx_queue;
sys_slist_t channels;
atomic_t ref;
struct k_delayed_work update_work;
union {
struct bt_conn_le le;
#if defined(CONFIG_BT_BREDR)
struct bt_conn_br br;
struct bt_conn_sco sco;
#endif
};
#if defined(CONFIG_BT_REMOTE_VERSION)
struct bt_conn_rv {
u8_t version;
u16_t manufacturer;
u16_t subversion;
} rv;
#endif
};
此数据结构为当前连接数据结构,其中包括BLE蓝牙连接相关的参数,连接成功后该数据结构可以被用户调用。
主控Host:
BLE协议栈的架构:
原作者:BL_MCU_SDK 开发指南