基于bluez的蓝牙ble开发

linux蓝牙协议栈bluez(https://github.com/bluez/bluez/tree/master),提供了丰富的蓝牙开发工具和示例。

bluez5主要提供基于HCI和基于DBUS的接口,基于HCI的接口主要用于更细致控制蓝牙硬件模块,而基于DBUS的接口提供大量的蓝牙上层协议,能更好的管理蓝牙。

轻量级开发:不使用glib、dbus,开发周边设备可以借鉴btmgmt.c和btgatt-server.c、btgatt-client.c。

重应用开发:使用glib、dbus开发的话,可以参考gatt-service.c。一般音频、文件传输基于此,提供了丰富接口和上层应用。

一、ble开发

蓝牙低功耗协议给设备定义了若干角色,或称工作模式。小程序蓝牙目前支持的有以下几种:

1) 中心设备/主机 (Central)/client

中心设备可以扫描外围设备,并在发现有外围设备存在后与之建立连接,之后就可以使用外围设备提供的服务(Service)。

一般而言,手机会担任中心设备的角色,利用外围设备提供的数据进行处理或展示等等。小程序提供低功耗蓝牙接口是默认设定手机为中心设备的。

2) 外围设备/从机 (Peripheral)/server

外围设备一直处于广播状态,等待被中心设备搜索和连接,不能主动发起搜索。例如智能手环、传感器等设备。

如果外围设备广播时被设置为不可连接的状态,也被称为广播模式 (Broadcaster),常见的例子是蓝牙信标 (Beacon) 设备。

ble client开发

一般 BLE(低功耗蓝牙)设备的连接流程可以分为以下几个步骤:

启动设备发现:通过 StartDiscovery 方法开始扫描周围的 BLE 设备。
监听设备发现信号:监听 InterfacesAdded 信号,以获取发现的设备对象路径。
停止设备发现:扫描到目标设备后,通过 StopDiscovery 方法停止扫描。
配对设备(可选):如果设备需要配对,可以调用 Pair 方法进行配对。
连接到设备:通过 Connect 方法连接到设备。
发现服务和特征:连接成功后,发现设备上的服务和特征。
操作特征:读取或写入特征,订阅通知等。
hciconfig hci0 reset
hcitool -i hci0 lescan
hcitool -i hci0 leinfo E0:E1:A9:3C:90:2B
hcitool -i hci0 lecc E0:E1:A9:3C:90:2B
hcitool -i hci0 ledc E0:E1:A9:3C:90:2B
hcitool con

./btgatt-client -i hci0 -d E0:E1:A9:3C:90:2B

ble server开发

虽然bluez并没有给c提供直接可用的ble接口,但是通过分析源码和工具可以如下方式实现ble外围设备(server)供手机APP扫描传输数据。

hciconfig hci0 up
hciconfig hci0 name "ble"
hciconfig hci0 leadv
btgatt-server -v -r       // 开启health rate服务

# hciconfig
hci0: Type: Primary Bus: UART
BD Address: 63:E8:09:BF:10:A5 ACL MTU: 1021:8 SCO MTU: 240:3
UP RUNNING
RX bytes:744 acl:0 sco:0 events:51 errors:0
TX bytes:5366 acl:0 sco:0 commands:51 errors:0

btmgmt -i hci0 power off
btmgmt power off
btmgmt le on
btmgmt bredr off
btmgmt name mini_0002
btmgmt connectable on
btmgmt power on
btmgmt advertising on

# btmgmt info
hci0:   Primary controller
        addr E0:E1:A9:3C:90:2B version 7 manufacturer 93 class 0x000000
        supported settings: powered connectable fast-connectable discoverable bondable link-security ssp br/edr hs le advertising secure-conn debug-keys privacy static-addr phy-configuration
        current settings: powered connectable ssp br/edr le advertising secure-conn
        name ble_0000
        short name

在bluez的根目录下有一个peripheral文件夹,里面实现了ble的peripheral角色(server),也就是包含和实现了gap profile和gatt server profile的功能,源码可以参考。

二、hci接口(旧)

HCI提供一套统一的方法来访问Bluetooth底层。

HCI编程就是调用bluez提供的HCI接口来进行编程,只不过编译的时候要注意把蓝牙库链接进去,即-lbluetooth。

HCI有很多命令,可以查看下/usr/include/bluetooth/hci_lib.h文件。

bluez源码中tools目录下的许多文件可以作为HCI编程的参考,例如tools/hcitool.c和tools/hciconfig.c等

HCI是应用程序跟蓝牙驱动进行交互的接口,Linux内核向应用程序提供一个AF_BLUETOOTH的socket来实现蓝牙Host和Controller的交互。

// lib/hci.c
/* Open HCI device.
 * Returns device descriptor (dd). */
int hci_open_dev(int dev_id)
{
    struct sockaddr_hci a;
    int dd, err;

    /* Check for valid device id */
    if (dev_id < 0) {
        errno = ENODEV;
        return -1;
    }

    /* Create HCI socket */
    dd = socket(AF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC, BTPROTO_HCI);
    if (dd < 0)
        return dd;

    /* Bind socket to the HCI device */
    memset(&a, 0, sizeof(a));
    a.hci_family = AF_BLUETOOTH;
    a.hci_dev = dev_id;
    if (bind(dd, (struct sockaddr *) &a, sizeof(a)) < 0)
        goto failed;

    return dd;

failed:
    err = errno;
    close(dd);
    errno = err;

    return -1;
}

int hci_close_dev(int dd)
{
    return close(dd);
}

三、mgmt接口(新)

mgmt接口是什么,为什么要引入,参考:http://www.bluez.org/the-management-interface/

mgmt is a new interface for user space Bluetooth components (like bluetoothd) to talk to the kernel and it aims to replace the existing raw HCI sockets.

mgmt支持的api(commands和event),参考:doc/mgmt-api.txt。

所有mgmt命令都会产生event,而invalid lengths或unknown commands会生成command status response event;给invalid controller index发送commands生成command status event。

As a general rule all commands generate the events as specified below, however invalid lengths or unknown commands will always generate a Command Status response (with Unknown Command or Invalid Parameters status). Sending a command with an invalid Controller Index value will also always generate a Command Status event with the Invalid Index status code.

The Bluetooth management sockets can be created by setting the hci_channel member of struct sockaddr_hci to HCI_CHANNEL_CONTROL (3) when creating a raw HCI socket.

struct mgmt *mgmt_new_default(void)
{
    struct mgmt *mgmt;
    union {
        struct sockaddr common;
        struct sockaddr_hci hci;
    } addr;
    int fd;

    fd = socket(PF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK,
                                BTPROTO_HCI);
    if (fd < 0)
        return NULL;

    memset(&addr, 0, sizeof(addr));
    addr.hci.hci_family = AF_BLUETOOTH;
    addr.hci.hci_dev = HCI_DEV_NONE;
    addr.hci.hci_channel = HCI_CHANNEL_CONTROL;

    if (bind(fd, &addr.common, sizeof(addr.hci)) < 0) {
        close(fd);
        return NULL;
    }

    mgmt = mgmt_new(fd);
    if (!mgmt) {
        close(fd);
        return NULL;
    }

    mgmt->close_on_unref = true;

    return mgmt;
}

使用mgmt接口实现ble_server,思路如下(来自:[BlueZ5] 如何用MGMT接口实现ble slave

[1]  如何实现开关蓝牙.
[2]  如何实现广播,包含广播包和响应包的设定,以及广播参数设定等等。
[3]  如何实现GATT连接.
[4]  如何实现服务注册,即收发数据.
[5]  如何实现状态通知,包含连接成功,断开成功,timeout,terminate等等.
[6]  如何实现更新连接参数,连接间隔设定等等。

需要指出,以上几点可归纳为如何两个文件以及kernel中node的设定等等。
[1][2]      -->bluez-5.5x\tools\btmgmt.c

[3][4][5]   -->bluez-5.5x\tools\btgatt-server.c

[6]         -->部分可从btmgmt.c中获取

 

参考:
1. 低功耗蓝牙ble开发(一)——bluez介绍及源码分析

2. linux下BLE(低功耗蓝牙协议)C语言开发笔记(2)---ble蓝牙扫描-连接-读写

3. 蓝牙低功耗 (Bluetooth Low Energy, BLE) -- 微信小程序 官网文档

4. 蓝牙bluez进行HCI编程

5. linux下bluetooth编程(三)HCI层编程

6. 深入理解Bluez协议栈之“好用的小工具”

7. [BlueZ5] 如何用MGMT接口实现ble slave

posted @ 2024-07-30 11:51  yuxi_o  阅读(65)  评论(0编辑  收藏  举报