物联网操作系统AliOS Things 3.3
ble_host

概述

AliOS Things 3.3提供支持符合蓝牙4.0/4.2/5.0核心协议规范的BLE Host软件协议栈组件,方便用户使用蓝牙BLE功能。
ble_host组件功能框图如下图红色部分:
image.png

功能支持

ble_host组件主要支持如下功能:

  • Generic Access Profile(GAP)角色支持
    • Peripheral&Central
    • Observer&Broadcaster
  • Generic Attribute Profile(GATT)连接支持
    • GATT client
    • GATT server
  • Security Manager(SM)支持
    • Legacy Pairing
    • 多安全等级设定Security Level 1, 2, 3, 4
    • 安全连接Security Connection
    • LE Privacy(RPA地址生成)
  • HCI接口支持
    • 标准HCI接口,支持host-only,host通过HCI硬件接口(以UART为主)和controller对接
    • 虚拟HCI接口,支持host+controller,适合SoC的硬件平台

版权说明

Apache license v2.0

目录结构

|-- ble_profiles #BLE服务
|-- bt_crypto #BLE安全
|-- bt_defconfig #BLE配置项
|-- bt_host #BLE Host核心代码
|-- bt_preconfig #BLE预配置项
|-- bt_shell #BLE控制台命令
|-- include #头文件
|-- package.yaml #makefile
|-- README.md #README文档
|-- SConscript
|-- script

依赖组件

  • osal_aos

常用配置

配置列表

配置在组件的package.yaml中定义,均已默认打开,用户可根据需求裁剪。

CONFIG_BT_CENTRALBLE Central角色功能开关
CONFIG_BT_PERIPHERALBLE 外设角色功能开关
CONFIG_BT_SMPBLE SMP功能开关
CONFIG_BT_GATT_CLIENTBLE GATT Client功能开关
CONFIG_BT_OBSERVERBLE 广播扫描功能开关

API说明

API列表

ble_stack_initBLE协议栈初始化
ble_stack_event_register注册BLE事件处理函数
ble_stack_adv_startBLE 广播开始
ble_stack_adv_stopBLE 广播停止
ble_stack_scan_startBLE 扫描开始
ble_stack_scan_stopBLE 扫描停止
ble_stack_gatt_mtu_getGATT,获取当前连接MTU大小
ble_stack_gatt_registe_serviceGATT server,服务注册
ble_stack_gatt_notificateGATT server,属性notificate方式上报
ble_stack_gatt_indicateGATT server,属性indicate方式上报
ble_stack_gatt_mtu_exchangeGATT client,协商MTU大小
ble_stack_gatt_discoveryGATT client,发现对端GATT服务
ble_stack_gatt_readGATT client,读取对端GATT server属性
ble_stack_gatt_read_multipleGATT client,读取对端GATT server多个属性
ble_stack_gatt_writeGATT client,写入对端GATT server属性
ble_stack_connect开始BLE连接
ble_stack_disconnect断开BLE连接
ble_stack_connect_param_updateBLE连接参数协商
ble_stack_securityBLE连接安全等级设置
ble_stack_iocapability_setBLE SMP IO能力配置
ble_stack_smp_cancelBLE SMP配对请求取消
ble_stack_smp_passkey_entryBLE SMP passkey输入
ble_stack_smp_passkey_confirmBLE SMP passkey确认
ble_stack_dev_unpairPIN SMP配对解绑

API详情

ble_stack_init

BLE模块初始化。
函数原型

int ble_stack_init(init_param_t *param)

输入参数

argsdescription
param.dev_name设备名,string类型,不超过28字符
param.dev_addr设备mac地址,仅设置为random类型时生效
param.conn_num_max最大连接数

返回参数
0:成功, 其他值:失败。

ble_stack_event_register

注册BLE协议栈事件回调函数。
注意:入参不能是一个局部变量。
函数原型

int ble_stack_event_register(ble_event_cb_t *callback)

输入参数

argsdescription
callback.callback回调函数
callback.next无需填写,由API函数处理

返回参数
0:成功, 其他值:失败。

ble_stack_adv_start

打开BLE广播功能。
函数原型

int ble_stack_adv_start(adv_param_t *param)

输入参数

argsdescription
param.type广播类型,定义如下
    0x00  普通广播
    0x01  直连广播
    0x02  可连接可扫描广播
    0x03  不可连接广播,
    0x04  低占空直连广播
param.adADV广播内容数组
param.sdScan Response广播内容数组
param.ad_numADV广播内容数组大小
param.sd_numScan Response广播内容数组大小
param.interval_min广播发送间隔最小值
param.interval_max广播发送间隔最大值
param.filter_policy广播过滤开关,定义如下
    0x00  接受所有连接与扫描请求
    0x01  接受所有连接请求,接受白名单设备的扫描请求
    0x02  接受白名单的连接请求,接受所有扫描请求
    0x03  仅接受白名单内的扫描与连接请求
param.channel_map广播信道设置,
    bit0: 37信道
    bit1: 38信道
    bit2: 39信道
param.direct_peer_addr直连广播设备地址,仅在广播类型为直连类型时才生效

返回参数
0:成功, 其他值:失败。

ble_stack_adv_stop

关闭BLE广播功能。
函数原型

int ble_stack_adv_stop()

输入参数

argsdescription

返回参数
0:成功, 其他值:失败。

ble_stack_scan_start

打开BLE扫描功能。
函数原型

int ble_stack_scan_start(const scan_param_t *param)

输入参数

argsdescription
param.type扫描类型,定义如下
    0x00  被动扫描
    0x01   主动扫描
param.filter_dup重复设备上报过滤开关,定义如下
    0x00  关闭过滤
    0x01  开启过滤
param.interval扫描间隔,单位为0.625毫秒
param.window扫描窗大小,单位为0.625毫秒
param.scan_filter扫描过滤类型,定义如下
    0x00  所有广播均上报
    0x01  仅白名单设备的广播上报

返回参数
0:成功, 其他值:失败。

ble_stack_scan_stop

关闭BLE扫描功能。
异步事件,扫描结果在注册的事件回调函数中返回,返回事件EVENT_GAP_DEV_FIND
函数原型

int ble_stack_scan_stop()

输入参数

argsdescription

返回值
0:成功, 其他值:失败。

ble_stack_gatt_mtu_get

获取一个连接的当前MTU大小
函数原型

int ble_stack_gatt_mtu_get(int16_t conn_handle)

输入参数

argsdescription
conn_handle连接句柄,在连接成功后分配

返回值
23-65535: MTU大小

ble_stack_gatt_registe_service

注册一个GATT服务
函数原型

int ble_stack_gatt_registe_service(gatt_service *s, gatt_attr_t attrs[], uint16_t attr_num)

输入参数

argsdescription
s.bt_gatt_attr无需填写,由API赋值
s.attr_count无需填写,由API赋值
s.node无需填写,由API赋值
attrs属性列表
attr_num属性列表大小

返回值
0:成功, 其他值:失败。

ble_stack_gatt_notificate

GATT服务某个属性值上报,此上报方式无需GATT Client回复
函数原型

int ble_stack_gatt_notificate(int16_t conn_handle, uint16_t char_handle, const uint8_t *data, uint16_t len)

输入参数

argsdescription
conn_handle连接句柄,在连接成功后分配
char_handle属性句柄,在注册服务时分配
data上报数据指针
len上报数据长度

返回值
0:成功, 其他值:失败。

ble_stack_gatt_indicate

GATT服务某个属性值上报,此上报方式GATT Client回复confirm。
函数原型

int ble_stack_gatt_indicate(int16_t conn_handle, int16_t char_handle, const uint8_t *data, uint16_t len)

输入参数

argsdescription
conn_handle连接句柄,在连接成功后分配
char_handle属性句柄,在注册服务时分配
data上报数据指针
len上报数据长度

返回值
0:成功, 其他值:失败。

ble_stack_gatt_mtu_exchange

GATT Client功能,确保配置项CONFIG_BT_GATT_CLIENT配置。
GATT协商MTU大小,协商大小由配置项CONFIG_BT_L2CAP_RX_MTU与CONFIG_BT_L2CAP_TX_MTU的最小值以及对端设备的回复决定。
异步事件,执行结果在注册的事件回调函数中返回,返回事件EVENT_GATT_MTU_EXCHANGE
函数原型

int ble_stack_gatt_mtu_exchange(int16_t conn_handle)


输入参数

argsdescription
conn_handle连接句柄,在连接成功后分配


返回值
0:成功, 其他值:失败。

ble_stack_gatt_discovery

GATT Client功能,确保配置项CONFIG_BT_GATT_CLIENT配置。
GATT服务或者属性项发现。
异步事件,执行结果在注册的事件回调函数中返回,返回事件根据入参不同而不同

函数原型

int ble_stack_gatt_discovery(int16_t conn_handle,
gatt_discovery_type_en type,
uuid_t *uuid,
uint16_t start_handle,
uint16_t end_handle)

输入参数

argsdescription
conn_handle连接句柄,在连接成功后分配
typeGATT发现类型,定义如下
    0x00  发现主服务
    0x01  发现包含服务
    0x02  发现属性项
    0x03  发现属性描述项
uuid需要发现的UUID值
start_handle发现起始句柄
end_handle发现结束句柄

返回值
0:成功, 其他值:失败。

ble_stack_gatt_read

GATT Client功能,确保配置项CONFIG_BT_GATT_CLIENT配置。
GATT读取某个属性项的属性值
异步事件,执行结果在注册的事件回调函数中返回,返回事件EVENT_GATT_CHAR_READ_CB
函数原型

int ble_stack_gatt_read(int16_t conn_handle, uint16_t attr_handle, uint16_t offset)

输入参数

argsdescription
conn_handle连接句柄,在连接成功后分配
attr_handle读取的属性项句柄
offset读取起始位置

返回值
0:成功, 其他值:失败。

ble_stack_gatt_read_multiple

GATT Client功能,确保配置项CONFIG_BT_GATT_CLIENT配置。
GATT读取多个属性项的属性值
异步事件,执行结果在注册的事件回调函数中返回,返回事件EVENT_GATT_CHAR_READ_CB
函数原型

int ble_stack_gatt_read_multiple(int16_t conn_handle, uint16_t attr_count, uint16_t attr_handle[])

输入参数

argsdescription
conn_handle连接句柄,在连接成功后分配
attr_count读取的属性项列表大小
attr_handle读取的属性项句柄列表

返回值
0:成功, 其他值:失败。

ble_stack_gatt_write

GATT Client功能,确保配置项CONFIG_BT_GATT_CLIENT配置。
GATT写入某个属性项的属性值
异步事件,执行结果在注册的事件回调函数中返回,返回事件EVENT_GATT_CHAR_WRITE_CB
函数原型

int ble_stack_gatt_write(int16_t conn_handle, uint16_t attr_handle, uint8_t *data, uint16_t len, uint16_t offset, gatt_write_en type)

输入参数

argsdescription
conn_handle连接句柄,在连接成功后分配
attr_handle写入的属性项句柄
data写入的数据指针
len写入的数据长度
offset写入到属性项的起始位置
type写入类型,定义如下
    0x00  带回复写入
    0x01  不带回复写入
    0x02  带签名写入

返回值
0:成功, 其他值:失败。

ble_stack_gatt_read_multiple

GATT Client功能,确保配置项CONFIG_BT_GATT_CLIENT配置。
此函数用于GATT读取多个属性项的属性值。
异步事件,执行结果在注册的事件回调函数中返回,返回事件EVENT_GATT_CHAR_READ_CB
函数原型

int ble_stack_gatt_read_multiple(int16_t conn_handle, uint16_t attr_count, uint16_t attr_handle[])

输入参数

argsdescription
conn_handle连接句柄,在连接成功后分配
attr_count读取的属性项列表大小
attr_handle读取的属性项句柄列表

返回值
0:成功, 其他值:失败。

ble_stack_connect

BLE连接功能,确保配置项CONFIG_BT_CONN配置。
此函数用于BLE连接某个设备。
异步事件,执行结果在注册的事件回调函数中返回,返回事件EVENT_GATT_CONN_CHANGE
函数原型

int ble_stack_connect(dev_addr_t *peer_addr, conn_param_t *param, uint8_t auto_connect)

输入参数

argsdescription
peer_addr.type对端设备的地址类型
peer_addr.val对端设备的蓝牙地址
param.interval_min连接间隔最小值参数,单位是0.625毫秒
param.interval_max连接间隔最大值参数,单位是0.625毫秒
param.lantency连接延迟参数,单位是连接间隔,注意此时间长度不能超过timeout参数的一半。
param.timeout连接超时参数,单位10ms

| auto_connect | 是否自动连接定义如下
    0x00  不自动连接
    0x01  自动连接 | |

返回值
0:成功, 其他值:失败。

ble_stack_disconnect

BLE连接功能,确保配置项CONFIG_BT_CONN配置。
此函数用于BLE断开某个设备的连接。
异步事件,执行结果在注册的事件回调函数中返回,返回事件EVENT_GATT_CONN_CHANGE
函数原型

int ble_stack_disconnect(int16_t conn_handle)

输入参数

argsdescription
conn_handle连接句柄,在连接事件中返回

返回值
0:成功, 其他值:失败。

ble_stack_connect_param_update

BLE连接功能,确保配置项CONFIG_BT_CONN配置。
此函数用于BLE修改某个连接的连接参数。
异步事件,执行结果在注册的事件回调函数中返回,返回事件EVENT_GAP_CONN_PARAM_UPDATE
函数原型

int ble_stack_connect_param_update(int16_t conn_handle, conn_param_t *param)

输入参数

argsdescription
conn_handle连接句柄,在连接事件中返回
param.interval_min连接间隔最小值参数,单位是0.625毫秒
param.interval_max连接间隔最大值参数,单位是0.625毫秒
param.lantency连接延迟参数,单位是连接间隔,注意此时间长度不能超过timeout参数的一半。
param.timeout连接超时参数,单位10ms

返回值
0:成功, 其他值:失败。

ble_stack_security

BLE连接功能,确保配置项CONFIG_BT_CONN配置。
此函数用于BLE修改某个连接的安全参数。
异步事件,执行结果在注册的事件回调函数中返回,返回事件EVENT_GAP_CONN_SECURITY_CHANGE
函数原型

int ble_stack_security(int16_t conn_handle, security_en level)

输入参数

argsdescription
conn_handle连接句柄,在连接事件中返回
level安全等级,定义如下
    0x00  无安全,无加密无鉴权
    0x01  低安全,等同于0x00
    0x02  中安全,有加密无鉴权
    0x03  高安全,有加密有鉴权

返回值
0:成功, 其他值:失败。

ble_stack_iocapability_set

BLE SMP配对功能,确保配置项CONFIG_BT_SMP配置。
此函数用于设置BLE设备设备的IO能力,这个设置会在BLE SMP配对被使用。
函数原型

int ble_stack_iocapability_set(uint8_t io_cap)

输入参数

argsdescription
io_capIO能力,定义如下
    bit0-bit2:
                  0x01  无输入
                  0x02  输入正确/错误
                  0x03  键盘输入
    bit3-bit4:
                  0x00  无输出
                  0x01  显示器输出

返回值
0:成功, 其他值:失败。

ble_stack_smp_cancel

BLE SMP配对功能,确保配置项CONFIG_BT_SMP配置。
此函数用于取消当前BLE的SMP配对请求。
函数原型

int ble_stack_smp_cancel(int16_t conn_handle)

输入参数

argsdescription
conn_handle连接句柄,在连接事件中返回

返回值
0:成功, 其他值:失败。

ble_stack_smp_passkey_entry

BLE SMP配对功能,确保配置项CONFIG_BT_SMP配置。
此函数用于SMP Passkey模式下输入当前passkey,当接收到EVENT_SMP_PASSKEY_ENTER后调用。
函数原型

int ble_stack_smp_passkey_entry(int16_t conn_handle, uint32_t passkey)

输入参数

argsdescription
conn_handle连接句柄,在连接事件中返回
passskey0-999999之间

返回值
0:成功, 其他值:失败。

ble_stack_smp_passkey_confirm

BLE SMP配对功能,确保配置项CONFIG_BT_SMP配置。
此函数用于SMP Passkey模式下确认当前的passkey是否正确,当接收到EVENT_SMP_PASSKEY_CONFIRM后调用。
函数原型

int ble_stack_smp_passkey_confirm(int16_t conn_handle)

输入参数

argsdescription
conn_handle连接句柄,在连接事件中返回

返回值
0:成功, 其他值:失败。

ble_stack_dev_unpair

BLE SMP配对功能,确保配置项CONFIG_BT_SMP配置。
此函数用于解除某台已SMP配对的设备的配对,如果连接存在则断开连接。
函数原型

int ble_stack_dev_unpair(dev_addr_t *peer_addr)

输入参数

argsdescription
peer_addr.type地址类型
peer_addr.val设备地址

返回值
0:成功, 其他值:失败。

使用示例

案例工具

  • 串口工具
  • NRF Connect(手机)

案例修改

以helloworld的案例为例,修改solutions/helloworld_demo/package.yaml的depends,增加ble_host,如下

depends:
- ble_host: master


修改solutions/helloworld_demo/helloworld_demo.c,如下:
头文件修改

#include <aos/ble.h>
#include <atomic.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/gatt.h>
#include <bluetooth/uuid.h>


代码修改

#define EXAMPLE_BLE_DEV_NAME "HaaS BLE"
#define DEVICE_ADDR {0xE8,0x3B,0xE3,0x88,0xB4,0xC8}
int application_start(int argc, char *argv[])
{
int count = 0;
int ret;
dev_addr_t addr = {DEV_ADDR_LE_RANDOM, DEVICE_ADDR};
init_param_t init = {
.dev_name = EXAMPLE_BLE_DEV_NAME,
.dev_addr = &addr, //&addr,
.conn_num_max = 1,
};
printf("nano entry here!\r\n");
#if 1
/* bt stack init */
ret = ble_stack_init(&init);
if (ret) {
printf("error: ble_stack_init!, ret = %x\r\n", ret);
return -1;
}
#endif
while(1) {
printf("hello world! count %d \r\n", count++);
aos_msleep(1000);
};
}

编译烧录

在solutions/helloworld_demo中执行aos make,编译成功后烧录进haas100开发板。

运行观测

打开串口工具,在串口工具中输入ble,可看到ble的cli命令集。
image.png

BLE广播与连接示例

在串口工具中输入ble adv start 020106,可以在串口日志中看到如下打印

adv_type:0;adv_interval_min:160 (*0.625)ms;adv_interval_max:240 (*0.625)ms
Advertising started


此时在手机端打开NRF Connect工具并搜索广播包,可以看到设备。
image.png

点击连接,可以看到Generic Access(GAP)和Generic Attribute(GATT)2个服务,点击GAP服务的Device Name的读取按键(下图红色圈中的箭头),可以读取到数值“HaaS BLE”
image.png

常见问题

Q:此协议栈是否支持蓝牙音乐播放
A:不支持经典蓝牙功能,仅支持BLE功能
Q:常见的GATT Service是否支持
A:支持,包括BAS,DIS,HIDS等等,详情请参考ble_host/ble_profiles文件下的实现。