蓝牙应用开发实战

一. 蓝牙应用的种类

openvela 支持两种蓝牙应用开发模式:基于 Native C API 接口开发和基于快应用 JS API 接口开发。前者可以调用所有蓝牙相关能力,但跨平台移植较困难;后者仅需一次开发,跨平台复用性高,但目前仅提供有限的蓝牙能力调用。

1.基于快应用的开发

快应用蓝牙接口基于 QuickJS 引擎,通过 C++ 封装为第三方应用提供高层 API 接口。蓝牙接口请参考 QuickApp Bluetooth API 文档(https://doc.quickapp.cn/features/system/bluetooth.html)。

目前支持的蓝牙能力包括:打开和关闭蓝牙、查询和监听蓝牙状态、开始和停止蓝牙扫描、查询和监听扫描结果、连接和断开蓝牙、查询已连接的蓝牙设备、查询 BLE 设备的 Services、读写 BLE 设备的特征值(Characteristic)。

2.基于 Native NDK 的开发

另一种是基于 NDK(Native Development Kit)接口直接调用蓝牙系统的全部能力,使用 C 语言进行 Native 应用开发。所有可用的 API 声明位于目录 framework/connectivity/bluetooth/framework/include 中,如下表所示。

头文件 接口描述
bluetooth.h 实例管理:蓝牙 instance 的创建,通过同步或异步方式对蓝牙 Service 执行远程函数调用(RPC),以及向蓝牙 Service 注册 callback
bt_adapter.h 本地适配器管理:包含蓝牙服务对本地 Bluetooth Adapter 的所有 RPC 调用
bt_device.h 远端设备管理:包含蓝牙服务对 Remote Device 的所有 RPC 调用
bt_a2dp_sink.h 包含蓝牙 Service 对 A2DP Sink 服务的所有 RPC 调用
bt_a2dp_source.h 包含蓝牙 Service 对 A2DP Source 服务的所有 RPC 调用
bt_avrcp_control.h 包含蓝牙 Service 对 AVRCP Control 服务的所有 RPC 调用
bt_avrcp_target.h 包含蓝牙 Service 对 AVRCP Target 服务的所有 RPC 调用
bt_hfp_ag.h 包含蓝牙 Service 对 HFP AG 服务的所有 RPC 调用
bt_hfp_hf.h 包含蓝牙 Service 对 HFP HF 服务的所有 RPC 调用
bt_hid_device.h 包含蓝牙 Service 对 HID Device 服务的所有 RPC 调用
bt_spp.h 包含蓝牙 Service 对 SPP 服务的所有 RPC 调用
euv_pipe.h 包含蓝牙 Service 对 SPP 数据文件节点的读写操作
bt_l2cap.h 包含蓝牙 Service 对 LE L2CAP CoC 服务的所有 RPC 调用
bt_le_advertiser.h 包含蓝牙 Service 对 LE Advertising 服务的所有 RPC 调用
bt_le_scan.h 包含蓝牙 Service 对 LE Scan 服务的所有 RPC 调用
bt_gattc.h 包含蓝牙 Service 对 GATT Client 服务的所有 RPC 调用
bt_gatts.h 包含蓝牙 Service 对 GATT Server 服务的所有 RPC 调用

二. 蓝牙原生应用开发

  1. 运行时模型

以下是一个典型的蓝牙应用工作流:

(1)获取蓝牙实例(Instance)

开发者需根据业务场景对实时性的要求,选择创建同步或异步实例。

同步实例通过 bluetooth_create_instance() 获取。该实例用于发送同步命令,调用后会阻塞应用当前线程,直到蓝牙服务执行完毕并返回才继续运行,如下图所示。

异步实例通过 bluetooth_create_async_instance() 获取,调用时需要传入 uv_loop_t 事件循环以及连接和断开的回调函数。该实例用于发送异步命令,调用后不会阻塞应用当前线程,蓝牙服务执行完毕后通过回调通知应用,如下图所示。

(2)注册服务回调(Register Callbacks)

获取实例后,需要根据业务需求向 Bluetooth Service 注册对应模块的回调函数,以便接收服务端的状态更新或数据上报。主要注册接口如下:

基础管理:本地适配器/远程设备使用 bt_adapter_register_callback()。

经典蓝牙音频与通话:A2DP Sink 使用 bt_a2dp_sink_register_callbacks(),A2DP Source 使用 bt_a2dp_source_register_callbacks(),AVRCP Control 使用 bt_avrcp_control_register_callbacks(),AVRCP Target 使用 bt_avrcp_target_register_callbacks(),HFP AG 使用 bt_hfp_ag_register_callbacks(),HFP HF 使用 bt_hfp_hf_register_callbacks()。

低功耗蓝牙(BLE):LE Advertising 在启动时传入回调(bt_le_start_advertising()),LE Scan 在启动时传入回调(bt_le_start_scan()),GATT Client 在连接时传入回调(bt_gattc_create_connect()),GATT Server 在注册服务时传入回调(bt_gatts_register_service()),L2CAP CoC 使用 bt_l2cap_register_callbacks()。

其他协议:HID Device 使用 bt_hid_device_register_callbacks(),SPP 使用 bt_spp_register_app()。

(3)执行远程调用 (RPC)

根据业务需要,向蓝牙 Framework/Service 不同服务发送命令,执行远程函数调用。

(4)回调处理(Callback)

在回调函数中处理蓝牙服务返回的状态变更和数据上报。

2.开发实例

以打开蓝牙为例,介绍蓝牙应用编写的一般思路。更多完整的代码实例,请参考 openvela 官方仓库:https://github.com/open-vela/frameworks_bluetooth/tree/dev/sample_code。

(1)创建蓝牙实例

首先,创建一个同步的蓝牙实例句柄。

复制代码
/* 创建蓝牙 instance */

static bt_instance_t* g_bt_ins = bluetooth_create_instance();

if (g_bt_ins == NULL) {
    LOGE("create instance error");
    goto error;
}

(2)声明并注册回调

定义适配器状态变更的回调函数,并将其注册到系统中。

复制代码
/* 声明 Callback */
const static adapter_callbacks_t app_gap_cbs = {
    .on_adapter_state_changed = gap_adapter_state_changed_callback,
};

/* 注册 Callback */
static void* adapter_callback = bt_adapter_register_callback(g_bt_ins, &app_gap_cbs);
if (adapter_callback == NULL) {
    LOGE("register callback error.");
    goto error;
}

(3)发送命令,远程执行调用

调用 bt_adapter_enable 接口开启蓝牙。由于使用的是同步实例,该函数返回时表示命令已下发(但状态变更可能稍后通过回调上报)。

复制代码
/* 发送命令 */
if (bt_adapter_enable(g_bt_ins) != BT_STATUS_SUCCESS) {
    LOGE("enable adapter error.");
    goto error;
}

(4)回调处理(Callback)

复制代码
/* Callback处理 */
static void gap_adapter_state_changed_callback(void* cookie, bt_adapter_state_t state)
{
    LOGE("Bluetooth Adapter State = %d", state);
}
相关推荐
开源武术3 个月前
使用 J-Link GDB 插件增强 openvela 线程调试
openvela
开源武术3 个月前
openvela 使用 _FORTIFY_SOURCE 增强 C 语言内存安全性
openvela
YaoYuan93234 个月前
openvela——动态管理日志输出通道及其实现原理
openvela
开源武术4 个月前
openvela 使用 VSCode 调试 SIM 环境
openvela
自由的晚风10 个月前
基于小米Open-Vela开源系统的高级计算器实现 | 支持C++数学函数与 LVGL UI
经验分享·物联网·开源·嵌入式·小米·nuttx·openvela
byte轻骑兵1 年前
OpenVela——专为AIoT领域打造的开源操作系统
开源·openvela
一只搬砖的猹1 年前
小米vela系统(基于开源nuttx内核)——openvela开源项目
linux·开源·小米·rtos·nuttx·openvela·apache2.0