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

2024-01-28 12:12

本文主要是介绍蓝牙----蓝牙消息传输_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 );

这篇关于蓝牙----蓝牙消息传输_GATT服务发现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/653601

相关文章

SpringBoot服务获取Pod当前IP的两种方案

《SpringBoot服务获取Pod当前IP的两种方案》在Kubernetes集群中,SpringBoot服务获取Pod当前IP的方案主要有两种,通过环境变量注入或通过Java代码动态获取网络接口IP... 目录方案一:通过 Kubernetes Downward API 注入环境变量原理步骤方案二:通过

如何搭建并配置HTTPD文件服务及访问权限控制

《如何搭建并配置HTTPD文件服务及访问权限控制》:本文主要介绍如何搭建并配置HTTPD文件服务及访问权限控制的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、安装HTTPD服务二、HTTPD服务目录结构三、配置修改四、服务启动五、基于用户访问权限控制六、

C++ RabbitMq消息队列组件详解

《C++RabbitMq消息队列组件详解》:本文主要介绍C++RabbitMq消息队列组件的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. RabbitMq介绍2. 安装RabbitMQ3. 安装 RabbitMQ 的 C++客户端库4. A

电脑蓝牙连不上怎么办? 5 招教你轻松修复Mac蓝牙连接问题的技巧

《电脑蓝牙连不上怎么办?5招教你轻松修复Mac蓝牙连接问题的技巧》蓝牙连接问题是一些Mac用户经常遇到的常见问题之一,在本文章中,我们将提供一些有用的提示和技巧,帮助您解决可能出现的蓝牙连接问... 蓝牙作为一种流行的无线技术,已经成为我们连接各种设备的重要工具。在 MAC 上,你可以根据自己的需求,轻松地

SpringCloud整合MQ实现消息总线服务方式

《SpringCloud整合MQ实现消息总线服务方式》:本文主要介绍SpringCloud整合MQ实现消息总线服务方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、背景介绍二、方案实践三、升级版总结一、背景介绍每当修改配置文件内容,如果需要客户端也同步更新,

linux服务之NIS账户管理服务方式

《linux服务之NIS账户管理服务方式》:本文主要介绍linux服务之NIS账户管理服务方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、所需要的软件二、服务器配置1、安装 NIS 服务2、设定 NIS 的域名 (NIS domain name)3、修改主

一文带你搞懂Redis Stream的6种消息处理模式

《一文带你搞懂RedisStream的6种消息处理模式》Redis5.0版本引入的Stream数据类型,为Redis生态带来了强大而灵活的消息队列功能,本文将为大家详细介绍RedisStream的6... 目录1. 简单消费模式(Simple Consumption)基本概念核心命令实现示例使用场景优缺点2

SpringBoot基于配置实现短信服务策略的动态切换

《SpringBoot基于配置实现短信服务策略的动态切换》这篇文章主要为大家详细介绍了SpringBoot在接入多个短信服务商(如阿里云、腾讯云、华为云)后,如何根据配置或环境切换使用不同的服务商,需... 目录目标功能示例配置(application.yml)配置类绑定短信发送策略接口示例:阿里云 & 腾

springboot项目如何开启https服务

《springboot项目如何开启https服务》:本文主要介绍springboot项目如何开启https服务方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录springboot项目开启https服务1. 生成SSL证书密钥库使用keytool生成自签名证书将

Redis消息队列实现异步秒杀功能

《Redis消息队列实现异步秒杀功能》在高并发场景下,为了提高秒杀业务的性能,可将部分工作交给Redis处理,并通过异步方式执行,Redis提供了多种数据结构来实现消息队列,总结三种,本文详细介绍Re... 目录1 Redis消息队列1.1 List 结构1.2 Pub/Sub 模式1.3 Stream 结