GATT 服务的核心函数bt_gatt_discover的介绍

目录

概述

1 GATT 基本概念

1.1 GATT 的介绍

1.2 GATT 的角色

 1.3 核心组件

1.4 客户端操作

2  bt_gatt_discover函数的功能和应用

2.1 函数介绍

 2.1 发现类型(Discover Type)

3 典型使用流程

3.1 服务发现示例

3.2 级联发现模式

 3.3 按UUID过滤发现

 3.4 发现描述符

4 错误处理 

4.1 常见错误码

4.2 错误处理示例

5 性能优化建议

6 资源管理注意事项

6.1 参数生命周期

6.2 取消发现


概述

本文介绍了蓝牙低功耗(BLE)中的GATT协议及其核心功能。GATT定义了BLE设备通过服务和特征交换数据的标准框架,包含服务器和客户端两种角色。文章详细解析了GATT的核心组件(服务、特性、描述符)及其层级结构,并以Zephyr协议栈中的bt_gatt_discover函数为例,说明其参数配置、发现类型和使用流程,包括服务发现、级联发现、UUID过滤等典型应用场景。最后还列举了常见错误码及处理方法,为BLE应用的开发提供了实用指导。

1 GATT 基本概念

1.1 GATT 的介绍

GATT (Generic Attribute Profile) 是 Bluetooth Low Energy (BLE) 的核心协议,定义了 数据通信的标准框架,使BLE设备能够通过 服务(Services) 和 特征(Characteristics) 交换数据。

1.2 GATT 的角色

角色说明典型设备
GATT 服务器(Server)存储并提供数据(如传感器数据)心率带、温度计
GATT 客户端(Client)读取或写入服务器数据手机、中央设备

 1.3 核心组件

 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.4 客户端操作

操作函数(Zephyr示例)说明
发现服务bt_gatt_discover()扫描远程设备的GATT表
读取特征值bt_gatt_read()读取数据(如电池电量)
写入特征值bt_gatt_write()发送命令或配置
启用通知bt_gatt_subscribe()订阅实时数据(如心率)

2  bt_gatt_discover函数的功能和应用

2.1 函数介绍

bt_gatt_discover 是 Zephyr BLE 协议栈中用于发现远程设备 GATT 服务的核心函数,下面我将从多个维度进行详细说明:

1) 函数原型与参数

int bt_gatt_discover(struct bt_conn *conn,struct bt_gatt_discover_params *params
);

2)参数说明:

  • conn:已建立的BLE连接句柄

  • params:发现参数结构体,包含以下关键字段:

struct bt_gatt_discover_params {const struct bt_uuid *uuid;      // 目标UUID(可选过滤条件)uint16_t start_handle;           // 起始属性句柄(通常0x0001)uint16_t end_handle;             // 结束属性句柄(通常0xFFFF)enum bt_gatt_discover_type type; // 发现类型void (*func)(struct bt_conn *conn,const struct bt_gatt_attr *attr,struct bt_gatt_discover_params *params);
};

 2.1 发现类型(Discover Type)

类型枚举值说明对应ATT操作
BT_GATT_DISCOVER_PRIMARY发现主服务ATT Read By Group Type Req
BT_GATT_DISCOVER_SECONDARY发现次要服务ATT Read By Group Type Req
BT_GATT_DISCOVER_INCLUDE发现包含的服务ATT Read By Type Req
BT_GATT_DISCOVER_CHARACTERISTIC发现特性ATT Read By Type Req
BT_GATT_DISCOVER_DESCRIPTOR发现描述符ATT Find Information Req
BT_GATT_DISCOVER_STD_CHAR_DESC发现标准特性描述符ATT Read By Type Req

3 典型使用流程

3.1 服务发现示例

static struct bt_gatt_discover_params discover_params;static void discover_cb(struct bt_conn *conn,const struct bt_gatt_attr *attr,struct bt_gatt_discover_params *params)
{if (!attr) {printk("Discovery complete\n");return;}switch (params->type) {case BT_GATT_DISCOVER_PRIMARY: {struct bt_gatt_service_val *svc = attr->user_data;printk("Service found: start_handle=0x%04X, end_handle=0x%04X\n",attr->handle, svc->end_handle);break;}case BT_GATT_DISCOVER_CHARACTERISTIC: {struct bt_gatt_chrc *chrc = attr->user_data;printk("Characteristic: handle=0x%04X, properties=0x%02X\n",chrc->value_handle, chrc->properties);break;}}
}void start_discovery(struct bt_conn *conn)
{discover_params.uuid = NULL;  // 发现所有主服务discover_params.start_handle = 0x0001;discover_params.end_handle = 0xFFFF;discover_params.type = BT_GATT_DISCOVER_PRIMARY;discover_params.func = discover_cb;int err = bt_gatt_discover(conn, &discover_params);if (err) {printk("Discovery failed to start (err %d)\n", err);}
}

3.2 级联发现模式

static void discover_chars(struct bt_conn *conn, uint16_t start, uint16_t end)
{static struct bt_gatt_discover_params params;params.start_handle = start;params.end_handle = end;params.type = BT_GATT_DISCOVER_CHARACTERISTIC;params.func = discover_cb;bt_gatt_discover(conn, &params);
}static void discover_cb(...)
{if (params->type == BT_GATT_DISCOVER_PRIMARY) {// 发现主服务后继续发现特性struct bt_gatt_service_val *svc = attr->user_data;discover_chars(conn, attr->handle + 1, svc->end_handle);}
}

 3.3 按UUID过滤发现

static struct bt_uuid_16 find_uuid = BT_UUID_INIT_16(0x180F); // 电池服务void find_battery_service(struct bt_conn *conn)
{discover_params.uuid = &find_uuid.uuid;discover_params.type = BT_GATT_DISCOVER_PRIMARY;bt_gatt_discover(conn, &discover_params);
}

 3.4 发现描述符

void discover_descriptors(struct bt_conn *conn, uint16_t start, uint16_t end)
{discover_params.start_handle = start;discover_params.end_handle = end;discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;bt_gatt_discover(conn, &discover_params);
}

4 错误处理 

4.1 常见错误码

错误码说明
0成功
-ENOTCONN未建立连接
-EINVAL无效参数
-ENOMEM内存不足
-EOPNOTSUPP操作不支持

4.2 错误处理示例

int err = bt_gatt_discover(conn, &params);
if (err) {printk("Error %d during discovery\n", err);switch (err) {case -ENOTCONN:// 处理连接问题break;case -EINVAL:// 检查参数有效性break;}
}

5 性能优化建议

  1. 分阶段发现:先发现服务,再根据需要发现特性和描述符

  2. 缓存发现结果:避免重复发现

  3. 合理设置句柄范围:缩小start_handle/end_handle范围

  4. 使用UUID过滤:减少不必要的发现操作

6 资源管理注意事项

6.1 参数生命周期

// 错误:使用栈变量(函数返回后失效)
void start_temp_discovery(struct bt_conn *conn) {struct bt_gatt_discover_params temp_params = {...};bt_gatt_discover(conn, &temp_params); // 危险!
}// 正确:使用静态或动态分配
static struct bt_gatt_discover_params persistent_params;

6.2 取消发现

void cancel_discovery(struct bt_conn *conn) {bt_gatt_discover_cancel(conn, &discover_params);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/pingmian/82338.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【更新至2023年】1985-2023年全国及各省就业人数数据(无缺失)

1985-2023年全国及各省就业人数数据(无缺失) 1、时间:1985-2023年 2、来源:Z国统计年鉴、各省年鉴、新中国60年 3、指标:就业人数 4、范围:全国及31省 5、缺失情况:无缺失 6、指标解释&am…

0基础学习Linux之揭开朦胧一面:环境基础开发工具

目录 Linux下安装软件的方案: 对于操作系统的理解: 操作系统的生态问题: 什么是好的操作系统(os): 重新理解centos VS ubnutu VS kail: 关于yum: 用 yum 安装软件(安装和卸载软件一定要有r…

YOLO 算法详解:实时目标检测的里程碑

在计算机视觉领域,目标检测一直是一个关键且热门的研究方向,而 YOLO(You Only Look Once)算法凭借其出色的实时性和较高的检测精度,成为了目标检测算法中的明星选手。本文将深入探讨 YOLO 算法的原理、发展历程、技术优…

leetcode98.验证二叉搜索树:递归法中序遍历的递增性验证之道

一、题目深度解析与BST核心性质 题目描述 验证二叉搜索树(BST)是算法中的经典问题,要求判断给定的二叉树是否满足BST的定义: 左子树中所有节点的值严格小于根节点的值右子树中所有节点的值严格大于根节点的值左右子树本身也必须…

MathQ-Verify:数学问题验证的五步流水线,为大模型推理筑牢数据基石

MathQ-Verify:数学问题验证的五步流水线,为大模型推理筑牢数据基石 大语言模型在数学推理领域进展显著,但现有研究多聚焦于生成正确推理路径和答案,却忽视了数学问题本身的有效性。MathQ-Verify,通过五阶段流水线严格…

八股战神-JVM知识速查

1.JVM组成 JVM由那些部分组成,运行流程是什么? JVM是Java程序的运行环境 组成部分: 类加载器:加载字节码文件到内存 运行时数据区:包括方法区,堆,栈,程序计数器,本地…

Maven:在原了解基础上对pom.xml文件进行详细解读

一、pom.xml文件 就像项目管理软件 Make 的 MakeFile、Ant 的 build.xml 一样,Maven 项目的核心是 pom.xml。POM( Project Object Model,项目对象模型 ) 定义了项目的基本信息,用于描述项目如何构建,声明项目依赖,等等…

Spring Cloud项目登录认证从JWT切换到Redis + UUID Token方案

背景介绍 在传统的Spring Boot项目中,用户登录认证常见的方案是使用JWT(JSON Web Token)来实现无状态的身份验证。JWT凭借自包含用户信息、方便前后端分离、性能较好等优势被广泛采用。 然而,在实际项目中,JWT也有一…

MongoDB 快速整合 SpringBoot 示例

1.添加依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spr…

Flyweight(享元)设计模式 软考 享元 和 代理属于结构型设计模式

1.目的&#xff1a;运用共享技术有效地支持大量细粒度的对象 Flyweight&#xff08;享元&#xff09;设计模式 是一种结构型设计模式&#xff0c;它的核心目的是通过共享对象来减少内存消耗&#xff0c;特别是在需要大量相似对象的场景中。Flyweight 模式通过将对象的共享细节与…

002大模型-提示词工程,少样本提示,角色扮演,思维链

一、提示词工程 二、少样本提示 三、角色扮演 四、思维链

华为OD机试真题——传递悄悄话(二叉树最长路径问题)(2025A卷:200分)Java/python/JavaScript/C/C++/GO最佳实现

2025 A卷 200分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…

「读书报告」Spark实时大数据分析

这本书是清华大学出版社2018年出版的&#xff0c;我是2020年读的&#xff0c;说真的的&#xff0c;不怎么喜欢这本书&#xff0c;所以作者我都不想提。有的人可能会奇怪&#xff0c;ailx10&#xff0c;你一个搞网络安全的&#xff0c;怎么会去读大数据相关的书&#xff0c;哎&a…

2025 河北ICPC( D. 金泰园(二分)-- C.年少的誓约(公式转化))

文章目录 2025 河北ICPCD. 金泰园&#xff08;二分&#xff09;C.年少的誓约(公式转化)总结 2025 河北ICPC 题目链接&#xff1a; Attachments - The 9th Hebei Collegiate Programming Contest - Codeforces sdccpc20250522 - Virtual Judge 赛时&#xff1a;5道 D. 金泰…

QT学习一

对于选择qmake还是cmake&#xff0c;现在写的暂时先用qmake 1.命名规范和快捷键 2.按钮控件常用API //创建第一个按钮QPushButton * btn new QPushButton;//让btn对象 依赖在mywidget窗口中btn->setParent(this);//显示文本btn->setText("第一个按钮");//创建…

【Elasticsearch】给所索引创建多个别名

Elasticsearch 是可以给索引创建多个别名的。 为什么可以创建多个别名 1. 灵活性 - 别名可以为索引提供一个更易于理解的名称&#xff0c;方便用户根据不同的业务场景或用途来引用同一个索引。例如&#xff0c;一个索引可能同时服务于多个不同的应用程序或服务&#xff0c;通…

使用 OpenCV 实现哈哈镜效果

在计算机视觉和图像处理领域&#xff0c;OpenCV 提供了非常强大的图像几何变换能力&#xff0c;不仅可以用于纠正图像&#xff0c;还能制造各种“有趣”的视觉效果。今天&#xff0c;我们就来实现一个经典的“哈哈镜”效果&#xff0c;让图像像在游乐园里一样被拉伸、压缩、扭曲…

AI|Java开发 IntelliJ IDEA中接入本地部署的deepseek方法

目录 连接本地部署的deepseek&#xff1a; IntelliJ IDEA中使用deepseek等AI&#xff1a; 用法一&#xff1a;让AI写代码 用法二&#xff1a;选中这段代码&#xff0c;右键&#xff0c;可以让其解释这段代码的含义。这时显示的解释是英文的。 连接本地部署的deepseek&#…

如何使用两块硬盘作为 Ubuntu24 的系统盘,实现坏掉一块不影响系统运行。

最近我想使用Ubuntu组一个NAS系统&#xff0c;想实现系统盘冗余&#xff0c;各位大佬可以给点建议吗。 Deep Seek 为了实现两块硬盘作为 Ubuntu 24 系统盘的冗余配置&#xff08;RAID 1&#xff09;&#xff0c;确保一块硬盘损坏时系统仍可运行&#xff0c;以下是详细步骤&am…

【2025最新】虚拟机安装macos,VMware在Windows11上安装macOS 15完整图文教程 - 新手也能轻松上手

引言 想体验苹果系统但不想买Mac电脑&#xff1f;别担心&#xff01;本教程将手把手教你如何在Windows11环境下&#xff0c;通过VMware虚拟机安装macOS Sequoia15系统。即使你是零基础小白&#xff0c;按照这个步骤操作&#xff0c;也能轻松搞定&#xff01; 准备工作 在开始…