Zephyr OS下GATT的服务端(Server)接口

目录

概述

1 GATT 服务架构

1.1 GATT 核心架构组成

1.2  服务类型

1.3 数据交互模式

1.4 安全架构设计

2 GATT 服务端(Server)接口

2.1 服务定义与注册

2.1.1 静态服务定义宏

2.1.2 动态服务管理

2.2 特性与描述符操作

2.2.1 特性值操作

2.2.2 描述符操作

 2.3 回调函数接口

2.4 服务端安全控制

2.4.1 权限设置

2.4.2  安全级别检查

2.5  高级功能

2.5.1  服务变更指示

2.5.2  数据库浏览

3 服务端示例

3.1 设备信息服务实现

3.2 动态服务注册示例

3.3 Zephyr中的典型实现方式


概述

本文主要介绍Zephyr OS下GATT的服务端(Server)接口 ,GATT(通用属性配置文件)是蓝牙低功耗(BLE)协议中的核心组件,定义了服务端与客户端之间的数据交互架构。其采用层级结构组织服务(Service)、特性(Characteristic)、描述符(Descriptor)等元素,支持读取、写入、通知等多种交互模式。服务端开发涉及静态/动态服务注册、特性值操作、安全权限设置等关键功能,通过回调函数处理客户端请求。示例展示了设备信息服务和动态服务的实现方法,典型应用包括电池状态监测等场景。GATT架构为BLE设备提供了标准化的数据交换机制,支持安全通信和实时数据传输。

1 GATT 服务架构

GATT (Generic Attribute Profile) 是蓝牙低功耗(BLE)协议栈中的关键组成部分,定义了服务(Server)和客户端(Client)之间数据交换的标准架构。

1.1 GATT 核心架构组成

1)层级结构

GATT Profile
├── Services (服务)
│   ├── Characteristics (特性)
│   │   ├── Value (值)
│   │   ├── Descriptors (描述符)
│   │   │   └── Client Characteristic Configuration (CCC)
│   │   └── Properties (属性)
│   └── Includes (包含服务)
└── Attributes (属性)

2) 关键组件说明

组件 说明 示例UUID
服务(Service) 功能逻辑集合 0x180A (设备信息服务)
特性(Characteristic) 服务中的数据项 0x2A29 (厂商名称)
描述符(Descriptor) 特性的元数据 0x2902 (CCC描述符)
属性(Attribute) 数据库基本单元 由协议栈管理

1.2  服务类型

类型 特点 使用场景
主服务(Primary) 设备核心功能 电池服务、设备信息
次要服务(Secondary) 辅助功能 引用服务组件
包含服务(Include) 服务引用 组合复杂功能

1.3 数据交互模式

Server和Client通信方式对比

方式 特点 适用场景
读取(Read) 客户端主动请求 获取静态配置
写入(Write) 客户端修改值 发送控制命令
通知(Notify) 服务端主动推送 实时传感器数据
指示(Indicate) 需确认的推送 关键状态变更

1.4 安全架构设计

权限标志 说明 安全要求
BT_GATT_PERM_READ 允许读取
BT_GATT_PERM_READ_ENCRYPT 需加密读取 加密连接
BT_GATT_PERM_READ_AUTHEN 需认证读取 已配对设备
BT_GATT_PERM_WRITE 允许写入
BT_GATT_PERM_WRITE_ENCRYPT 需加密写入 加密连接

2 GATT 服务端(Server)接口

2.1 服务定义与注册

2.1.1 静态服务定义宏

/* 定义完整的GATT服务(编译时静态注册)*/
BT_GATT_SERVICE_DEFINE(
    service_name,  // 服务变量名
    BT_GATT_PRIMARY_SERVICE(UUID),  // 主服务声明
    BT_GATT_CHARACTERISTIC(        // 特性定义
        UUID,
        properties,
        permissions,
        read_cb, write_cb, value
    ),
    BT_GATT_CCC(ccc_cfg_changed, permissions),  // 客户端特性配置
    // 可添加更多特性或描述符...
);

2.1.2 动态服务管理

/* 动态分配服务结构 */
struct bt_gatt_service *service = bt_gatt_service_alloc(num_attrs);

/* 添加特性到动态服务 */
int bt_gatt_service_add_characteristic(
    struct bt_gatt_service *svc,
    struct bt_gatt_attr *attr
);

/* 注册动态服务 */
int bt_gatt_service_register(struct bt_gatt_service *svc);

/* 注销动态服务 */
int bt_gatt_service_unregister(struct bt_gatt_service *svc);

2.2 特性与描述符操作

2.2.1 特性值操作

/* 通知特性值变化 */
int bt_gatt_notify(
    struct bt_conn *conn,
    const struct bt_gatt_attr *attr,
    const void *data,
    uint16_t len
);

/* 指示特性值变化(需确认)*/
int bt_gatt_indicate(
    struct bt_conn *conn,
    struct bt_gatt_indicate_params *params
);

/* 读取特性值辅助函数 */
ssize_t bt_gatt_attr_read(
    struct bt_conn *conn,
    const struct bt_gatt_attr *attr,
    void *buf,
    uint16_t len,
    uint16_t offset,
    const void *value,
    uint16_t value_len
);

/* 写入特性值辅助函数 */
ssize_t bt_gatt_attr_write(
    struct bt_conn *conn,
    const struct bt_gatt_attr *attr,
    const void *buf,
    uint16_t len,
    uint16_t offset,
    uint8_t flags
);

2.2.2 描述符操作

/* 客户端特性配置描述符(CCC) */
#define BT_GATT_CCC(_changed, _perm) \
    BT_GATT_DESCRIPTOR(BT_UUID_GATT_CCC, _perm, NULL, NULL, _changed)

/* 服务变更描述符 */
#define BT_GATT_SERVICE_CHANGED \
    BT_GATT_DESCRIPTOR(BT_UUID_GATT_SC, BT_GATT_PERM_READ, NULL, NULL, NULL)

 2.3 回调函数接口

/* 读取回调函数类型 */
typedef ssize_t (*bt_gatt_attr_read_func_t)(
    struct bt_conn *conn,
    const struct bt_gatt_attr *attr,
    void *buf,
    uint16_t len,
    uint16_t offset
);

/* 写入回调函数类型 */
typedef ssize_t (*bt_gatt_attr_write_func_t)(
    struct bt_conn *conn,
    const struct bt_gatt_attr *attr,
    const void *buf,
    uint16_t len,
    uint16_t offset,
    uint8_t flags
);

/* CCC配置变更回调 */
typedef void (*bt_gatt_ccc_cfg_changed_t)(
    const struct bt_gatt_attr *attr,
    uint16_t value
);

2.4 服务端安全控制

2.4.1 权限设置

/* 常用权限组合 */
#define BT_GATT_PERM_READ                  BIT(0)
#define BT_GATT_PERM_WRITE                 BIT(1)
#define BT_GATT_PERM_READ_ENCRYPT          (BT_GATT_PERM_READ | BT_GATT_PERM_ENCRYPT)
#define BT_GATT_PERM_WRITE_ENCRYPT         (BT_GATT_PERM_WRITE | BT_GATT_PERM_ENCRYPT)
#define BT_GATT_PERM_READ_AUTHEN           (BT_GATT_PERM_READ | BT_GATT_PERM_AUTHEN)
#define BT_GATT_PERM_WRITE_AUTHEN          (BT_GATT_PERM_WRITE | BT_GATT_PERM_AUTHEN)

2.4.2  安全级别检查

/* 检查连接安全级别 */
int bt_gatt_check_perm(
    struct bt_conn *conn,
    const struct bt_gatt_attr *attr,
    uint8_t mask
);

2.5  高级功能

2.5.1  服务变更指示

/* 标记服务变更范围 */
int bt_gatt_service_changed(struct bt_conn *conn,
                          uint16_t start_handle,
                          uint16_t end_handle);

2.5.2  数据库浏览

/* 遍历GATT数据库 */
void bt_gatt_foreach_attr(
    uint16_t start_handle,
    uint16_t end_handle,
    bt_gatt_attr_func_t func,
    void *user_data
);

3 服务端示例

3.1 设备信息服务实现

#include 
#include 
#include 

static uint8_t device_name[] = "Zephyr Server";

static ssize_t read_device_name(struct bt_conn *conn,
                               const struct bt_gatt_attr *attr,
                               void *buf, uint16_t len, uint16_t offset)
{
    return bt_gatt_attr_read(conn, attr, buf, len, offset, 
                           device_name, sizeof(device_name));
}

static void ccc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
{
    ARG_UNUSED(attr);
    printk("CCC Config Changed: %d\n", value);
}

BT_GATT_SERVICE_DEFINE(device_info_svc,
    BT_GATT_PRIMARY_SERVICE(BT_UUID_DEVICE_INFORMATION),
    BT_GATT_CHARACTERISTIC(BT_UUID_DEVICE_NAME,
                          BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
                          BT_GATT_PERM_READ,
                          read_device_name, NULL, device_name),
    BT_GATT_CCC(ccc_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE)
);

void notify_device_name(struct bt_conn *conn)
{
    bt_gatt_notify(conn, &device_info_svc.attrs[2], device_name, sizeof(device_name));
}

3.2 动态服务注册示例

static uint8_t dynamic_value[20];

static ssize_t read_dynamic_value(struct bt_conn *conn,
                                const struct bt_gatt_attr *attr,
                                void *buf, uint16_t len, uint16_t offset)
{
    return bt_gatt_attr_read(conn, attr, buf, len, offset,
                           dynamic_value, sizeof(dynamic_value));
}

static struct bt_gatt_attr dynamic_attrs[] = {
    BT_GATT_PRIMARY_SERVICE(BT_UUID_DIS),
    BT_GATT_CHARACTERISTIC(BT_UUID_DIS_MODEL_NUMBER,
                          BT_GATT_CHRC_READ,
                          BT_GATT_PERM_READ,
                          read_dynamic_value, NULL, NULL),
};

static struct bt_gatt_service dynamic_service = {
    .attrs = dynamic_attrs,
    .attr_count = ARRAY_SIZE(dynamic_attrs),
};

void register_dynamic_service(void)
{
    int err = bt_gatt_service_register(&dynamic_service);
    if (err) {
        printk("Dynamic service register failed (err %d)\n", err);
    }
}

3.3 Zephyr中的典型实现方式

static uint8_t battery_level = 50;

static ssize_t read_battery(struct bt_conn *conn,
                          const struct bt_gatt_attr *attr,
                          void *buf, uint16_t len, uint16_t offset)
{
    return bt_gatt_attr_read(conn, attr, buf, len, offset,
                           &battery_level, sizeof(battery_level));
}

BT_GATT_SERVICE_DEFINE(battery_svc,
    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_battery, NULL, &battery_level),
    BT_GATT_CCC(battery_ccc_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE)
);

你可能感兴趣的:(zephyr架构蓝牙应用笔记,zephyr架构蓝牙应用笔记)