BLE App 开发指南¶
本文主要通过一些示例,介绍蓝牙应用开发过程中常用的方法以及可能遇到的问题。
1 GAP¶
1.1 使用静态地址¶
开发过程中,我们有时想使用静态(随机)地址,可以在 bt_enable
之前,先设置一下设备地址,如下:
#include <bluetooth/addr.h>
#include <bluetooth/hci_ble.h>
void main(void)
{
bt_addr_t addr = {
.val = { 0x55, 0x44, 0x33, 0x22, 0x11, 0xC0 }
};
bt_static_address_init(&addr);
...
bt_enable(NULL);
...
}
需要注意的是,48-bit 静态地址的最高两位会被强制写为 1。
2 GATT¶
2.1 Service¶
16-bit或128-bit的UUID唯一决定了 Service/Characteristic.
16-bit UUID 用于标准 Bluetooth Service/Characteristic
128-bit UUID 用于厂商自定义的一些服务
2.1.1 Bluetooth Service¶
2.1.1.1 GAP Service¶
这是一个基础服务,默认开启,不建议用户修改。
如果确实需要修改,建议使用 CONFIG_BT_GAP_SERVICE=n
关掉这个服务,然后在应用层重新实现,这样可以避免代码更新导致的冲突。
源码路径:zephyr\subsys\bluetooth\host\gatt.c
。
Service or Characteristics |
Kconfig |
Description |
ROM |
SRAM |
---|---|---|---|---|
GAP Service |
|
Enable GAP service (Enabled by default) |
||
Device Name Characteristic |
|
Device name characteristic (Always enable) |
- |
- |
Appearance Characteristic |
|
Appearance characteristic (Always enable) |
- |
- |
Central Address Resolution Characteristic |
Depends on Central Role & Privacy Feature |
- |
- |
|
Service Changed Characteristic |
Configure peripheral preferred connection parameters |
2.1.1.2 GATT Service¶
这是一个基础服务,默认开启,不建议用户修改。
如果确实需要修改,建议使用 CONFIG_BT_GATT_SERVICE=n
关掉这个服务,然后在应用层重新实现,这样可以避免代码更新导致的冲突。
源码路径:zephyr\subsys\bluetooth\host\gatt.c
。
Service or Characteristics |
Kconfig |
Description |
ROM |
SRAM |
---|---|---|---|---|
GATT Service |
|
Enable GATT service (Enabled by default) |
||
Service Changed Characteristic |
GATT Service Changed support |
|||
Client Supported Features & Database Hash Characteristic |
GATT Caching support |
|||
Server Supported Features Characteristic |
Enhanced ATT Bearers support [EXPERIMENTAL] |
2.1.1.3 Battery Service¶
源码路径:zephyr\subsys\bluetooth\services\bas.c
。
Service or Characteristics |
Kconfig |
Description |
ROM |
SRAM |
---|---|---|---|---|
Battery Service |
Enable GATT Battery service |
|||
Battery Level Characteristic |
|
BAS Battery level characteristic (Always enable) |
- |
- |
APIs
bt_bas_get_battery_level
bt_bas_set_battery_level
需要包含头文件
#include <bluetooth/services/bas.h>
2.1.1.4 Device Information Service¶
源码路径:zephyr\subsys\bluetooth\services\dis.c
。
Service or Characteristics |
Kconfig |
Description |
ROM |
SRAM |
---|---|---|---|---|
Device Information Service |
Enable GATT Device Information service |
|||
Enable Settings usage in Device Information Service |
||||
Maximum size in bytes for DIS strings |
- |
- |
||
Model Number String Characteristic |
|
DIS Model number string characteristic (Always enable) |
- |
- |
Model name |
- |
- |
||
Manufacturer Name String Characteristic |
|
DIS Manufacturer name string characteristic (Always enable) |
- |
- |
Manufacturer name |
- |
- |
||
Firmware Revision String Characteristic |
Enable DIS Firmware Revision characteristic |
|||
Firmware revision |
- |
- |
||
Hardware Revision String Characteristic |
Enable DIS Hardware Revision characteristic |
|||
Hardware revision |
- |
- |
||
PnP ID Characteristic |
Enable PnP_ID characteristic |
|||
Product ID |
- |
- |
||
Product Version |
- |
- |
||
Vendor ID |
- |
- |
||
Vendor ID source |
- |
- |
||
Serial Number String Characteristic |
Enable DIS Serial number characteristic |
|||
Serial Number |
- |
- |
||
Software Revision String Characteristic |
Enable DIS Software Revision characteristic |
|||
Software revision |
- |
- |
2.1.1.5 Heart Rate Service¶
源码路径:zephyr\subsys\bluetooth\services\hrs.c
。
Service or Characteristics |
Kconfig |
Description |
ROM |
SRAM |
---|---|---|---|---|
Heart Rate Service |
Enable GATT Heart Rate service |
|||
Read and write allowed |
||||
Require encryption and authentication for access |
||||
Require encryption for access |
||||
Measurement Interval Characteristic |
|
HRS Measurement interval characteristic (Always enable) |
- |
- |
Body Sensor Location Characteristic |
|
HRS Body sensor location characteristic (Always enable) |
- |
- |
Control Point Characteristic |
|
HRS Control Point characteristic (Always enable) |
- |
- |
APIs
bt_hrs_notify
需要包含头文件
#include <bluetooth/services/hrs.h>
2.1.1.6 Object Transfer Service¶
源码路径:zephyr\subsys\bluetooth\services\ots\*
。
Service or Characteristics |
Kconfig |
Description |
ROM |
SRAM |
---|---|---|---|---|
Object Transfer Service |
Object Transfer Service (OTS) [EXPERIMENTAL] |
|||
Enables the Directory Listing Object |
||||
The object name of the Directory Listing Object |
||||
Size of RX MTU for Object Transfer Channel |
||||
Size of TX MTU for Object Transfer Channel |
||||
Maximum number of available OTS instances |
||||
Maximum number of objects that each service instance can store |
||||
Support OACP Create Operation |
||||
Support OACP Delete Operation |
||||
Support patching of objects |
||||
Support OACP Read Operation |
||||
Support OACP Write Operation |
||||
Maximum object name length |
||||
Support object name write |
||||
Support OLCP Go To Operation |
||||
Register OTS as Secondary Service |
||||
OTS Feature Characteristic |
|
OTS Feature characteristic (Always enable) |
- |
- |
OTS Object Name Characteristic |
|
OTS Object name characteristic (Always enable) |
- |
- |
OTS Object Type Characteristic |
|
OTS Object type characteristic (Always enable) |
- |
- |
OTS Object Size Characteristic |
|
OTS Object size characteristic (Always enable) |
- |
- |
OTS Object ID Characteristic |
|
OTS Object ID characteristic (Always enable) |
- |
- |
OTS Object Properties Characteristic |
|
OTS Object properties characteristic (Always enable) |
- |
- |
OTS Object Action Control Point Characteristic |
|
OTS Object action control point characteristic (Always enable) |
- |
- |
OTS Object List Control Point Characteristic |
|
OTS Object list control point characteristic (Always enable) |
- |
- |
APIs
bt_ots_init
bt_ots_obj_add
bt_ots_obj_delete
bt_ots_svc_decl_get
bt_ots_free_instance_get
bt_ots_obj_id_to_str
需要包含头文件
#include <bluetooth/services/ots.h>
2.1.2 Vendor Service¶
2.2 Notify¶
参考 bt_gatt_indicate 参数计算
。
int notify_send(const void *data, uint16_t len)
{
return bt_gatt_notify(NULL, &cvs.attrs[1], data, len);
}
2.3 Indicate¶
static void indicate_cb(struct bt_conn *conn,
struct bt_gatt_indicate_params *params, uint8_t err)
{
printk("Indication %s\n", err != 0U ? "fail" : "success");
}
static void indicate_destroy(struct bt_gatt_indicate_params *params)
{
printk("Indication complete\n");
}
int indicate_send(const void *data, uint16_t len)
{
static struct bt_gatt_attr *ind_attr;
static struct bt_gatt_indicate_params ind_params;
vnd_ind_attr = bt_gatt_find_by_uuid(svc.attrs, svc.attr_count,
&chr_uuid.uuid);
ind_params.attr = ind_attr;
ind_params.func = indicate_cb;
ind_params.destroy = indicate_destroy;
ind_params.data = data;
ind_params.len = len;
return bt_gatt_indicate(NULL, &ind_params);
}
2.4 Attribute Index¶
我们在使用 bt_gatt_indicate
,bt_gatt_notify
时,需要传入一个参数 attr
,这个参数与 GATT Service 的定义有关。下面介绍一下这个参数如何填写。
Service 是多个 Attribute 的集合,为了方便定义,我们使用宏进行组织服务,每个宏包含1或2个Attribute,如下:
宏 |
描述 |
数量 |
---|---|---|
BT_GATT_PRIMARY_SERVICE |
Primary Service Declaration Macro. |
1 |
BT_GATT_SECONDARY_SERVICE |
Secondary Service Declaration Macro. |
1 |
BT_GATT_INCLUDE_SERVICE |
Include Service Declaration Macro. |
1 |
BT_GATT_CHARACTERISTIC |
Characteristic and Value Declaration Macro. |
2 |
BT_GATT_CCC |
Client Characteristic Configuration Declaration Macro. |
1 |
BT_GATT_CEP |
Characteristic Extended Properties Declaration Macro. |
1 |
BT_GATT_CUD |
Characteristic User Format Descriptor Declaration Macro. |
1 |
BT_GATT_CPF |
Characteristic Presentation Format Descriptor Declaration Macro. |
1 |
BT_GATT_DESCRIPTOR |
Descriptor Declaration Macro. |
1 |
如下是 Battery Service 的定义,源码位置:\subsys\bluetooth\services\bas.c
BT_GATT_SERVICE_DEFINE(bas,
BT_GATT_PRIMARY_SERVICE(BT_UUID_BAS),
BT_GATT_CHARACTERISTIC(BT_UUID_BAS_BATTERY_LEVEL,
BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
BT_GATT_PERM_READ, read_blvl, NULL,
&battery_level),
BT_GATT_CCC(blvl_ccc_cfg_changed,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
);
其 Notify Characteristic Attribute index 为 1 (BT_GATT_PRIMARY_SERVICE
)。
同样的,如下 hog_svc
:
BT_GATT_SERVICE_DEFINE(hog_svc,
BT_GATT_PRIMARY_SERVICE(BT_UUID_HIDS),
BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_INFO, BT_GATT_CHRC_READ,
BT_GATT_PERM_READ, read_info, NULL, &info),
BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT_MAP, BT_GATT_CHRC_READ,
BT_GATT_PERM_READ, read_report_map, NULL, NULL),
BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT,
BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
BT_GATT_PERM_READ_AUTHEN,
read_input_report, NULL, NULL),
BT_GATT_CCC(input_ccc_changed,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
BT_GATT_DESCRIPTOR(BT_UUID_HIDS_REPORT_REF, BT_GATT_PERM_READ,
read_report, NULL, &input),
BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT,
BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
BT_GATT_PERM_READ_AUTHEN,
read_input_report_consumer, NULL, NULL),
BT_GATT_CCC(input_ccc_changed_consumer,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
BT_GATT_DESCRIPTOR(BT_UUID_HIDS_REPORT_REF, BT_GATT_PERM_READ,
read_report_consumer, NULL, &input_consumer),
BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_CTRL_POINT,
BT_GATT_CHRC_WRITE_WITHOUT_RESP,
BT_GATT_PERM_WRITE,
NULL, write_ctrl_point, &ctrl_point),
);
第一个 Notify Characteristic Attribute index 为 5
BT_GATT_PRIMARY_SERVICE
+BT_GATT_CHARACTERISTIC
+BT_GATT_CHARACTERISTIC
= 1+2+2第二个 Notify Characteristic Attribute index 为 9
BT_GATT_PRIMARY_SERVICE
+BT_GATT_CHARACTERISTIC
+BT_GATT_CHARACTERISTIC
+BT_GATT_CHARACTERISTIC
+BT_GATT_CCC
+BT_GATT_DESCRIPTOR
= 1+2+2+2+1+1