蓝牙----蓝牙消息传输_GATT服务发现

蓝牙消息传输_GATT服务发现

  • 1.主机和从机GATT服务的发现
  • 2.通知的使用


1.主机和从机GATT服务的发现

GATT服务的发现由主机执行,一共三个阶段
 1.处理交换 MTU 请求和响应,启动对 Simple Service 服务的发现

  if (discState == BLE_DISC_STATE_MTU){// MTU size response received, discover simple serviceif (pMsg->method == ATT_EXCHANGE_MTU_RSP){//获取主服务的UUIDuint8_t uuid[ATT_BT_UUID_SIZE] = { LO_UINT16(SIMPLEPROFILE_SERV_UUID),HI_UINT16(SIMPLEPROFILE_SERV_UUID) };discState = BLE_DISC_STATE_SVC;// 通过UUID寻找主服务----simple serviceVOID GATT_DiscPrimaryServiceByUUID(pMsg->connHandle, uuid,ATT_BT_UUID_SIZE, selfEntity);}}

2.处理发现服务的响应,并存储服务的开始和结束句柄。服务发现过程完成后,启动对特定特征(Characteristic)的发现

else if (discState == BLE_DISC_STATE_SVC){// Service found, store handlesif (pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP &&pMsg->msg.findByTypeValueRsp.numInfo > 0){//存储服务的开始和结束句柄svcStartHdl = ATT_ATTR_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0);svcEndHdl = ATT_GRP_END_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0);}// If procedure completeif (((pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP) &&(pMsg->hdr.status == bleProcedureComplete))  ||(pMsg->method == ATT_ERROR_RSP)){if (svcStartHdl != 0){attReadByTypeReq_t req;// Discover characteristicdiscState = BLE_DISC_STATE_CHAR;req.startHandle = svcStartHdl;req.endHandle = svcEndHdl;req.type.len = ATT_BT_UUID_SIZE;req.type.uuid[0] = LO_UINT16(SIMPLEPROFILE_CHAR1_UUID);req.type.uuid[1] = HI_UINT16(SIMPLEPROFILE_CHAR1_UUID);//根据服务句柄范围和特征UUID,客户端发现服务器上的服务特征VOID GATT_DiscCharsByUUID(pMsg->connHandle, &req, selfEntity);}}}

3.处理发现特征的响应,并存储特征值的句柄。如果特征发现过程完成,触发相应的操作,比如启动通知。

  else if (discState == BLE_DISC_STATE_CHAR){// Characteristic found, store handleif ((pMsg->method == ATT_READ_BY_TYPE_RSP) &&(pMsg->msg.readByTypeRsp.numPairs > 0)){//有多个连接时,获取连接句柄uint8_t connIndex = SimpleCentral_getConnIndex(scConnHandle);// connIndex cannot be equal to or greater than MAX_NUM_BLE_CONNSSIMPLECENTRAL_ASSERT(connIndex < MAX_NUM_BLE_CONNS);// Store the handle of the simpleprofile characteristic 1 value//获取特征句柄connList[connIndex].charHandle= BUILD_UINT16(pMsg->msg.readByTypeRsp.pDataList[3],pMsg->msg.readByTypeRsp.pDataList[4]);Display_printf(dispHandle, SC_ROW_CUR_CONN, 0, "Simple Svc Found");// Now we can use GATT Read/Writetbm_setItemStatus(&scMenuPerConn,SC_ITEM_GATTREAD | SC_ITEM_GATTWRITE, SC_ITEM_NONE);}discState = BLE_DISC_STATE_IDLE;}

通过GATT_Cilent调用三次SimpleCentral_processGATTDiscEvent(gattMsgEvent_t *pMsg)实现。
在这里插入图片描述

因为Handle是由协议栈分配的连续的,所以获取其中一个的Handle就能知道其它的。
区分特征与特征值,特征由特征值、特征声明、用户特征描述、客户特征配置组成,每个组成部分有各自的Handle值

比如与一个连接的两个通知类型的特征值进行数据发送时,获取了第一个特征值的句柄,存储在connList[i].charHandle中。
第一个特征的CCC为charHandle+1
第二个特征的CCC为charHandle+5

if(index ==SIMPLEPROFILE_CHAR1)
{req.handle = connList[i].charHandle+1;
}
else if(index ==SIMPLEPROFILE_CHAR2)
{req.handle = connList[i].charHandle+5;
}

主从机发送消息时,需要将APP的信息发送给协议栈来发送,所以APP的信息要和协议栈的信息在发送和接受时完成同步,APP中的消息类似于缓存。


2.通知的使用

主从消息传输可以通过通知的方式,Notification有两种使用情况,都是由从机发起的

1)GATT_Notification
用在通信时,由从机主动通知,且不需要主机发出请求和回应。
2)GATTServApp_ProcessCharCfg
用在通知启动时,需要主机发送一次“通知请求”给从机,从机收到“通知请求”才发送通知。

1.从机完成通知的初始化

 // 分配客户端特征配置表simpleProfileChar4Config = (gattCharCfg_t *)ICall_malloc( sizeof(gattCharCfg_t) *MAX_NUM_BLE_CONNS );if ( simpleProfileChar4Config == NULL ){return ( bleMemAllocError );}// Initialize Client Characteristic Configuration attributes//初始化客户端特征配置表CCCGATTServApp_InitCharCfg( CONNHANDLE_INVALID, simpleProfileChar4Config );if ( services & SIMPLEPROFILE_SERVICE ){// Register GATT attribute list and CBs with GATT Server App//注册GATT属性列表和CBs与 GATT Server App回调函数status = GATTServApp_RegisterService( simpleProfileAttrTbl,GATT_NUM_ATTRS( simpleProfileAttrTbl ),GATT_MAX_ENCRYPT_KEY_SIZE,&simpleProfileCBs );}

在GATTServApp_InitCharCfg中,使用给定的 connHandle 在 charCfgTbl 中搜索,以找到与连接相关的特征配置项,并将该CCC初始化为GATT_CFG_NO_OPERATION0.

    gattCharCfg_t *pItem = gattServApp_FindCharCfgItem( connHandle, charCfgTbl );if ( pItem != NULL ){pItem->connHandle = CONNHANDLE_INVALID;pItem->value = GATT_CFG_NO_OPERATION;}

2.从机/主机发送一次通知请求,从机开始发送通知,CCC设置为通知:GATT_CLIENT_CFG_NOTIFY
主机发送启动通知命令:

            req.len = 2;req.pValue[0] = LO_UINT16(GATT_CLIENT_CFG_NOTIFY); //0x0001为开notify;req.pValue[1] = HI_UINT16(GATT_CLIENT_CFG_NOTIFY);req.sig = 0;req.cmd = 0;uint8_t status = GATT_WriteCharValue(connList[i].connHandle, &req, selfEntity);

从机启动通知:

status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,offset, GATT_CLIENT_CFG_NOTIFY );

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

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

相关文章

​ PaddleHub 首页图像 - 文字识别chinese_ocr_db_crnn_server​

PaddleHub 便捷地获取PaddlePaddle生态下的预训练模型&#xff0c;完成模型的管理和一键预测。配合使用Fine-tune API&#xff0c;可以基于大规模预训练模型快速完成迁移学习&#xff0c;让预训练模型能更好地服务于用户特定场景的应用 零基础快速开始WindowsLinuxMac Paddle…

【更新】ESG-71个工具变量汇总(2024)

一、引言 收集了CSSCI期刊文本数据&#xff0c;并对“ESG”相关期刊进行文本分析&#xff0c;统计了71个“ESG”相关的工具变量&#xff0c;希望对大家提升研究效率有所帮助 工具变量是一种在统计学和计量经济学中常用的技术&#xff0c;用于处理因果关系研究中的内生性问题。…

452. 用最少数量的箭引爆气球 - 力扣(LeetCode)

题目描述 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points &#xff0c;其中points[i] [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。 一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 …

带大家做一个,易上手的家常麻辣孜然牛蹄筋

首先 我们从冰箱中拿出牛蹄筋 泡水化开 一根大葱 一块生姜 大葱切段 生姜块 一把花椒 七个左右干辣椒 五个左右大料 三瓣蒜 切成蒜片 放入小碗中单独装起来 两个绿辣椒 首选螺丝椒 垃圾切成片 单独装起来 先将牛蹄筋 倒入锅中 然后加水 将牛蹄筋全部泡住即可 然后起锅烧…

RT-Thread: STM32 SPI使用流程

1.添加驱动 ①点开设置界面 ②勾选看门 SPI 驱动 ③点击保存 ④查看添加的驱动文件 drv_spi.c 2.打开驱动头文件定义 ①打开配置文件 ②打开定义 3.打开需要开启的SPI总线 打开 drivers 目录下的 board.h 用SPI搜索&#xff0c;找到如下文字&#xff0c;打开对应的宏。 /*-…

巴厘行记(四)——乌布漫游

欢迎览阅《巴厘行记》系列文章 巴厘行记巴厘行记&#xff08;一&#xff09;——海神庙 巴厘行记&#xff08;二&#xff09;——乌布之夜 巴厘行记&#xff08;三&#xff09;——Auntie和Mudi 巴厘行记&#xff08;四&#xff09;——乌布漫游 巴厘行记&#xff08;五&a…

Pytest单元测试框架

第一章、pytest概述 Pytest is a framework that makes building simple and scalable tests easy. Tests are expressive and readable—no boilerplate code required. Get started in minutes with a small unit test or complex functional test for your application or l…

深入理解与防范C语言中的栈溢出问题

一、引言 栈溢出是计算机安全领域中一个常见的漏洞&#xff0c;特别是在C语言编程中。由于C语言的灵活性和对内存管理的直接操作性&#xff0c;如果程序员在编写代码时不注意&#xff0c;就可能导致栈溢出的发生。本文将全面解析栈溢出的概念、原因、影响以及防范措施。 二、…

springboot+vue3支付宝接口案例-第二节-准备后端数据接口

springbootvue3支付宝接口案例-第二节-准备后端数据接口&#xff01;今天经过2个小时的折腾。准备好了我们这次测试支付宝线上支付接口的后端业务数据接口。下面为大家分享一下&#xff0c;期间发生遇到了一些弯路。 首先&#xff0c;我们本次后端接口使用的持久层框架是JPA。这…

3d合并模型是重名材质---模大狮模型网

当合并3d模型时&#xff0c;如果存在重名的材质&#xff0c;可能会导致加载问题。这是因为3D软件在处理重名材质时可能会出现冲突。你可以尝试以下方法解决这个问题&#xff1a; 重命名材质&#xff1a;检查合并的模型中的材质&#xff0c;确保它们具有唯一的命名。修改重名的材…

Pyroch中transforms 图像增强发方法的应用

1 应用场景 在我们训练模型的时候&#xff0c;有的时候数据不够&#xff0c;就需要通过水平翻转、垂直翻转、镜像、旋转、改变亮度、标准化等方式增加图像的多样性&#xff0c;此时可以调用Pytorch 中的Transforms完成这些操作 2 导入相应的库 from torchvision import tran…

多场景建模:美团HiNet

HiNet: Novel Multi-Scenario & Multi-Task Learning with Hierarchical Information Extraction 背景&#xff1a; 美团的多场景多任务&#xff08;ctr、ctcvr&#xff09; 解决方案 通过分层来分别学习多场景多任务 方案详情 点评&#xff1a;在底层Embedding时用…

如何实现Win系统ssh连接Ubuntu使用vscode远程敲代码

最近&#xff0c;我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念&#xff0c;而且内容风趣幽默。我觉得它对大家可能会有所帮助&#xff0c;所以我在此分享。点击这里跳转到网站。 文章目录 前言1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接…

opencv#35 连通域分析

连通域分割原理 像素领域介绍: 4邻域是指中心的像素与它邻近的上下左右一共有4个像素&#xff0c;那么称这4个像素为中心像素的4邻域。 8邻域是以中心像素周围的8个像素分别是上下左右和对角线上的4个像素。 连通域的定义(分割)分为两种:以4邻域为相邻判定条件的连通域分割和…

让AI帮你说话--GPT-SoVITS教程

有时候我们在录制视频的时候&#xff0c;由于周边环境嘈杂或者录音设备问题需要后期配音&#xff0c;这样就比较麻烦。一个比较直观的想法就是能不能将写好的视频脚本直接转换成我们的声音&#xff0c;让AI帮我们完成配音呢&#xff1f;在语音合成领域已经有很多这类工作了&…

1.Mybatis入门

目录 前言 1入门 1.1 入门程序实现 1.2 数据准备 ​编辑 1.3 配置Mybatis 1.4 编写SQL语句 1.5 单元测试 1.6 解决SQL警告与提示 2. JDBC介绍(了解) 2.1 介绍 2.2 代码 2.3 问题分析 2.4 技术对比 3. 数据库连接池 3.1 介绍 3.2 产品 4. lombok 4.1 介绍 4.…

AOP+Redisson 延时队列,实现缓存延时双删策略

一、缓存延时双删 关于缓存和数据库中的数据保持一致有很多种方案&#xff0c;但不管是单独在修改数据库之前&#xff0c;还是之后去删除缓存都会有一定的风险导致数据不一致。而延迟双删是一种相对简单并且收益比较高的实现最终一致性的方式&#xff0c;即在删除缓存之后&…

哪些 3D 建模软件值得推荐?

云端地球是一款免费的在线实景三维建模软件&#xff0c;不需要复杂的技巧&#xff0c;只要需要手机&#xff0c;多拍几张照片&#xff0c;就可以得到完整的三维模型&#xff01; 无论是大场景倾斜摄影测量还是小场景、小物体建模&#xff0c;都可以通过云端地球将二维数据向三…

【JLU】校园网linux客户端运行方法

终于给这输入法整好了&#xff0c;就像上面图里那样执行命令就行 写一个开机自启的脚本会更方便&#xff0c;每次都运行也挺烦的 补充了一键运行脚本&#xff0c;文件路径需要自己修改 #!/bin/bashrun_per_prog"sudo /home/d0/ubuntu-drclient-64/DrClient/privillege.s…

为什么3d合并的模型不能移动---模大狮模型网

当你在3D软件中合并模型后&#xff0c;如果无法移动合并后的模型&#xff0c;可能有以下几个可能的原因&#xff1a; 模型被锁定或冻结&#xff1a;在3D软件中&#xff0c;你可能会将模型锁定或冻结以防止意外的移动或编辑。请确保解锁或解冻模型&#xff0c;这样你就可以自由地…