蓝牙----蓝牙消息传输_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

相关文章

Java中Springboot集成Kafka实现消息发送和接收功能

《Java中Springboot集成Kafka实现消息发送和接收功能》Kafka是一个高吞吐量的分布式发布-订阅消息系统,主要用于处理大规模数据流,它由生产者、消费者、主题、分区和代理等组件构成,Ka... 目录一、Kafka 简介二、Kafka 功能三、POM依赖四、配置文件五、生产者六、消费者一、Kaf

windos server2022的配置故障转移服务的图文教程

《windosserver2022的配置故障转移服务的图文教程》本文主要介绍了windosserver2022的配置故障转移服务的图文教程,以确保服务和应用程序的连续性和可用性,文中通过图文介绍的非... 目录准备环境:步骤故障转移群集是 Windows Server 2022 中提供的一种功能,用于在多个

解决systemctl reload nginx重启Nginx服务报错:Job for nginx.service invalid问题

《解决systemctlreloadnginx重启Nginx服务报错:Jobfornginx.serviceinvalid问题》文章描述了通过`systemctlstatusnginx.se... 目录systemctl reload nginx重启Nginx服务报错:Job for nginx.javas

SpringBoot 自定义消息转换器使用详解

《SpringBoot自定义消息转换器使用详解》本文详细介绍了SpringBoot消息转换器的知识,并通过案例操作演示了如何进行自定义消息转换器的定制开发和使用,感兴趣的朋友一起看看吧... 目录一、前言二、SpringBoot 内容协商介绍2.1 什么是内容协商2.2 内容协商机制深入理解2.2.1 内容

【区块链 + 人才服务】可信教育区块链治理系统 | FISCO BCOS应用案例

伴随着区块链技术的不断完善,其在教育信息化中的应用也在持续发展。利用区块链数据共识、不可篡改的特性, 将与教育相关的数据要素在区块链上进行存证确权,在确保数据可信的前提下,促进教育的公平、透明、开放,为教育教学质量提升赋能,实现教育数据的安全共享、高等教育体系的智慧治理。 可信教育区块链治理系统的顶层治理架构由教育部、高校、企业、学生等多方角色共同参与建设、维护,支撑教育资源共享、教学质量评估、

【区块链 + 人才服务】区块链集成开发平台 | FISCO BCOS应用案例

随着区块链技术的快速发展,越来越多的企业开始将其应用于实际业务中。然而,区块链技术的专业性使得其集成开发成为一项挑战。针对此,广东中创智慧科技有限公司基于国产开源联盟链 FISCO BCOS 推出了区块链集成开发平台。该平台基于区块链技术,提供一套全面的区块链开发工具和开发环境,支持开发者快速开发和部署区块链应用。此外,该平台还可以提供一套全面的区块链开发教程和文档,帮助开发者快速上手区块链开发。

ActiveMQ—消息特性(延迟和定时消息投递)

ActiveMQ消息特性:延迟和定时消息投递(Delay and Schedule Message Delivery) 转自:http://blog.csdn.net/kimmking/article/details/8443872 有时候我们不希望消息马上被broker投递出去,而是想要消息60秒以后发给消费者,或者我们想让消息没隔一定时间投递一次,一共投递指定的次数。。。 类似

基于SpringBoot的宠物服务系统+uniapp小程序+LW参考示例

系列文章目录 1.基于SSM的洗衣房管理系统+原生微信小程序+LW参考示例 2.基于SpringBoot的宠物摄影网站管理系统+LW参考示例 3.基于SpringBoot+Vue的企业人事管理系统+LW参考示例 4.基于SSM的高校实验室管理系统+LW参考示例 5.基于SpringBoot的二手数码回收系统+原生微信小程序+LW参考示例 6.基于SSM的民宿预订管理系统+LW参考示例 7.基于

开放式耳机好用?平价开放式耳机推荐?四款开放式的蓝牙耳机推荐

开放式耳机好用吗?有平价些的开放式耳机推荐吗?那这两个问题的回答当然是肯定的。 首先开放式耳机好不好用取决于对耳机的需求,因为开放式耳机其实是比较适用于需要注意周围环境、需要‌长时间佩戴舒适以及需要频繁与人交流的场景中,在这些场景下使用开放式耳机的话就会比较有优势。就例如跑步骑行健身等运动的时候,能够兼得佩戴舒适度的同时,增加一定的安全性;还有在办公学习的时候,会很适合长时间佩戴,能够方便和

Golang支持平滑升级的HTTP服务

前段时间用Golang在做一个HTTP的接口,因编译型语言的特性,修改了代码需要重新编译可执行文件,关闭正在运行的老程序,并启动新程序。对于访问量较大的面向用户的产品,关闭、重启的过程中势必会出现无法访问的情况,从而影响用户体验。 使用Golang的系统包开发HTTP服务,是无法支持平滑升级(优雅重启)的,本文将探讨如何解决该问题。 一、平滑升级(优雅重启)的一般思路 一般情况下,要实现平滑