蓝牙----蓝牙连接建立_连接建立

蓝牙----蓝牙连接建立_连接建立

  • 蓝牙连接建立过程图
  • 1.主机扫描到广播包
    • 1.1判断是否是自己关心的广播包
    • 1.2广播地址添加到扫描列表
  • 2.主机扫描结束,建立连接
  • 3.主从连接成功后,执行连接建立后事件
    • 3.1.主机将连接句柄和设备地址添加到连接列表
    • 3.2.主机进行GATT服务的发现
    • 3.3.从机获取连接句柄,并发起连接参数更新
  • 4.从机发起连接参数更新
    • 4.1主机收到连接参数更新请求
    • 4.2从机进行连接参数更新


蓝牙连接建立过程图

在这里插入图片描述

1.主机扫描到广播包

执行注册的回调函数,触发APP层SC_EVT_ADV_REPORT事件

      //判断广播包是否是自己关心的if (SimpleCentral_findSvcUuid(SIMPLEPROFILE_SERV_UUID,pAdvRpt->pData, pAdvRpt->dataLen)){//将广播设备的地址和地址类型添加到扫描列表中SimpleCentral_addScanInfo(pAdvRpt->addr, pAdvRpt->addrType);Display_printf(dispHandle, SC_ROW_NON_CONN, 0, "Discovered: %s",Util_convertBdAddr2Str(pAdvRpt->addr));}

1.1判断是否是自己关心的广播包

SimpleCentral_findSvcUuid是查看广播包是否包含自己设置的UUID(SIMPLEPROFILE_SERV_UUID)。
广播包的判断有多种也可以对广播数据判断。

从机的广播数据static uint8_t advertData[] ={0x02,   // length of this dataGAP_ADTYPE_FLAGS,DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,// service UUID, to notify central devices what services are included// in this peripheral0x03,   // length of this dataGAP_ADTYPE_16BIT_MORE,      // some of the UUID's, but not allLO_UINT16(SIMPLEPROFILE_SERV_UUID),HI_UINT16(SIMPLEPROFILE_SERV_UUID)
};
主机扫描UUID判断if ((adType == GAP_ADTYPE_16BIT_MORE) ||   (adType == GAP_ADTYPE_16BIT_COMPLETE)){pData++;adLen--;// For each UUID in listwhile (adLen >= 2 && pData < pEnd){// Check for matchif ((pData[0] == LO_UINT16(uuid)) && (pData[1] == HI_UINT16(uuid))){// Match foundreturn TRUE;}// Go to nextpData += 2;adLen -= 2;}}

1.2广播地址添加到扫描列表

SimpleCentral_addScanInfo(pAdvRpt->addr, pAdvRpt->addrType);

//添加一个设备到扫描列表
static void SimpleCentral_addScanInfo(uint8_t *pAddr, uint8_t addrType)
{uint8_t i;// If result count not at max// DEFAULT_MAX_SCAN_RES扫描结果的最大数目if (numScanRes < DEFAULT_MAX_SCAN_RES){// Check if device is already in scan resultsfor (i = 0; i < numScanRes; i++){if (memcmp(pAddr, scanList[i].addr , B_ADDR_LEN) == 0){return;}}// Add addr to scan result listmemcpy(scanList[numScanRes].addr, pAddr, B_ADDR_LEN);scanList[numScanRes].addrType = addrType;// Increment scan result countnumScanRes++;}
}

当到达最大扫描数目时,执行GapScan_disable(),并执行回调函数,触发SC_EVT_SCAN_DISABLED事件

2.主机扫描结束,建立连接

处理SC_EVT_SCAN_DISABLED事件,进行GAP连接

 GapInit_connect(tempMember->addrType & MASK_ADDRTYPE_ID,tempMember->addr, DEFAULT_INIT_PHY, CONNECTION_TIMEOUT);

3.主从连接成功后,执行连接建立后事件

GapInit_connect成功返回GAP层事件GAP_LINK_Estableished,主机及从机进行事件处理

3.1.主机将连接句柄和设备地址添加到连接列表

SimpleCentral_addConnInfo(connHandle, pAddr);

//添加一个设备到 连接列表
static uint8_t SimpleCentral_addConnInfo(uint16_t connHandle, uint8_t *pAddr)
{uint8_t i;for (i = 0; i < MAX_NUM_BLE_CONNS; i++){if (connList[i].connHandle == CONNHANDLE_INVALID){// Found available entry to put a new connection info inconnList[i].connHandle = connHandle;memcpy(connList[i].addr, pAddr, B_ADDR_LEN);numConn++;break;}}return i;
}

其中connList[]元素结构体定义如下

//连接设备信息
typedef struct
{uint16_t connHandle;        // Connection Handle          连接句柄uint8_t  addr[B_ADDR_LEN];  // Peer Device Address        连接对端设备地址uint8_t  charHandle;        // Characteristic Handle      特征值句柄Clock_Struct *pRssiClock;   // pointer to clock struct
} connRec_t;

3.2.主机进行GATT服务的发现

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

3.3.从机获取连接句柄,并发起连接参数更新

SimplePeripheral_addConn(pPkt->connectionHandle);
从机获取连接句柄,并判断是否到达连接数目,选择继续/停止广播
连接参数更新在自定义的SP_SEND_PARAM_UPDATE_DELAY(6S)后,从机发起

//从机获取连接句柄,进行连接参数更新
static uint8_t SimplePeripheral_addConn(uint16_t connHandle)
{uint8_t i;uint8_t status = bleNoResources;// Try to find an available entryfor (i = 0; i < MAX_NUM_BLE_CONNS; i++){if (connList[i].connHandle == CONNHANDLE_INVALID){// Found available entry to put a new connection info inconnList[i].connHandle = connHandle;// Allocate data to send through clock handlerconnList[i].pParamUpdateEventData = ICall_malloc(sizeof(spClockEventData_t) +sizeof (uint16_t));if(connList[i].pParamUpdateEventData){connList[i].pParamUpdateEventData->event = SP_SEND_PARAM_UPDATE_EVT;*((uint16_t *)connList[i].pParamUpdateEventData->data) = connHandle;// Create a clock object and startconnList[i].pUpdateClock= (Clock_Struct*) ICall_malloc(sizeof(Clock_Struct));//启动连接参数更新if (connList[i].pUpdateClock){Util_constructClock(connList[i].pUpdateClock,SimplePeripheral_clockHandler,SP_SEND_PARAM_UPDATE_DELAY, 0, true,(UArg) (connList[i].pParamUpdateEventData));}else{ICall_free(connList[i].pParamUpdateEventData);}}else{status = bleMemAllocError;}// Set default PHY to 1MconnList[i].currPhy = HCI_PHY_1_MBPS;break;}}return status;
}

4.从机发起连接参数更新

从机发送连接参数更新GAP_UpdateLinkParamReq

4.1主机收到连接参数更新请求

主机GAP收到GAP_UPDATE_LINK_PARAM_REQ_EVENT连接请求事件,获取新的连接参数,执行连接请求回应GAP_UpdateLinkParamReqReply。

 case GAP_UPDATE_LINK_PARAM_REQ_EVENT:{gapUpdateLinkParamReqReply_t rsp;gapUpdateLinkParamReq_t *pReq;pReq = &((gapUpdateLinkParamReqEvent_t *)pMsg)->req;rsp.connectionHandle = pReq->connectionHandle;rsp.signalIdentifier = pReq->signalIdentifier;//允许连接参数更新if (acceptParamUpdateReq){//收到的 新的连接请求参数rsp.intervalMin = pReq->intervalMin;rsp.intervalMax = pReq->intervalMax;rsp.connLatency = pReq->connLatency;rsp.connTimeout = pReq->connTimeout;rsp.accepted = TRUE;}else{// Reject the request.rsp.accepted = FALSE;}// Send Reply// 连接请求回应VOID GAP_UpdateLinkParamReqReply(&rsp);break;}

连接请求回应GAP_UpdateLinkParamReqReply,触发主机的GAP_LINK_PARAM_UPDATE_EVENT事件,对连接参数更新成功与失败情况进行判决。

4.2从机进行连接参数更新

主机向从机连接请求回应GAP_UpdateLinkParamReqReply后,对连接参数更新成功与失败情况进行判决。

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

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

相关文章

Docker 基础篇

目录 一、Docker 简介 1. Docker 2. Linux 容器 3. 传统虚拟机和容器的对比 4. Docker 的作用 5. Docker 的基本组成&#xff08;Docker 三要素&#xff09; 6. Docker 工作原理 7. Docker 架构 8. Docker 下载 二、Docker 安装 1. CentOS Docker 安装 2. CentOS8 …

贝锐蒲公英全新网页认证,保障企业访客无线网络安全

随着企业规模的不断扩大、人员的增长、无线终端数量/类型的增加&#xff0c;传统WiFi无线网络会暴露出越来越多的问题&#xff0c;导致无线网络管理困难。 比如&#xff1a;采用弱密码、安全防护不到位的默认设置、员工缺乏信息安全意识、未经授人员权访问无线网络…… 这些问…

Vue的状态管理Pinia

文章目录 一、介绍二、install三、store1、创建并全局引入2、使用 本人最近在找工作&#xff0c;有推荐的小伙伴私我&#xff0c;不胜感激。 一、介绍 官网&#xff1a;https://pinia.web3doc.top/introduction.htmlPinia 是 Vue 官方团队开发的一个全新状态管理库Vue2和Vue3…

SELINUX导致的网络服务问题解决

第一&#xff1a;开启相关服务&#xff0c;监控SELINUX 相关服务&#xff1a;setroubleshoot,auditd,大多数都是以se开头的 如果没有此服务&#xff0c;先yum下&#xff0c;然后查看状态 这里关于auditd说明&#xff0c;centos7不可以用systemctl重启auditd服务&#xff0c;…

C#-正则表达式

1.C#功能点&#xff1a; 验证格式&#xff1a;通过正则表达式&#xff0c;我们可以检查一个字符串是否符合特定的格式要求&#xff0c;例如验证邮箱、电话号码、身份证号码等。 查找和提取&#xff1a;我们可以使用正则表达式来查找字符串中符合特定模式的部分&#xff0c;并将…

深入了解Matplotlib中的子图创建方法

深入了解Matplotlib中的子图创建方法 一 add_axes( **kwargs):1.1 函数介绍1.2 示例一 创建第一张子图1.2 示例二 polar参数的运用1.3 示例三 创建多张子图 二 add_subplot(*args, **kwargs):2.1 函数介绍2.2 示例一 三 两种方法的区别3.1 参数形式3.2 布局灵活性3.3 适用场景3…

美化背景(拼图小游戏)

package Puzzlegame.com.wxj.ui;import javax.swing.*; import javax.swing.border.BevelBorder; import java.util.Random;public class GameJframe extends JFrame { //游戏主界面 //创建一个二维数组//目的&#xff1a;管理数据//加载图片的时候&#xff0c;会根据二维数组中…

ECRS软件:引领企业走向精益制造的未来

随着科技的快速发展和市场竞争的不断加剧&#xff0c;制造业正面临着前所未有的挑战和机遇。为了在激烈的市场竞争中立于不败之地&#xff0c;越来越多的企业开始寻求转型和升级&#xff0c;精益制造成为了一个备受关注的方向。而在这个过程中&#xff0c;ECRS软件以其独特的作…

vue组件通信方式 provide-inject

Vue提供了一种无需父组件显式传递 props 就能子组件之间共享数据的机制&#xff0c;即provide和inject选项。祖先组件通过provide选项来提供变量&#xff0c;而后代组件则通过inject选项来接收这些变量。这种方法主要用来提供一些通用的数据&#xff0c;如主题、配置信息等&…

linux 主机无法联网问题

主机不能联网 一 查看当前ip ping路由 ifconfig wlan0 wlan0: flags4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.2.78 netmask 255.255.255.0 broadcast 192.168.2.255ping 192.168.2.1查看是否能ping通 二 查看路由表 route -n Destination G…

【C++】对外接口封装以及导出动态链接库DLL

VS 使用C编写对外接口并封装成DLL 一、接口的封装二、VS设置三、查看生成的DLL接口 一、接口的封装 首先创建头文件&#xff0c;包含我们所依赖的库的头文件名称&#xff0c;并且申明我们要对外封装的接口名称&#xff0c;示例&#xff1a; 头文件&#xff1a; #pragma once …

CSAPP shelllab

CSAPP shell lab shell lab 的目标 实现shell 功能&#xff0c;包括解析命令&#xff0c;调用可执行文件和内置命令&#xff0c;(quit, jobs,fg, 和bg)。实现job控制和signal handler。 shell 介绍 Shell中的作业&#xff08;job&#xff09;管理是一种用于跟踪和控制正在运…

2023年:个人年度成长与团队协作成就

文章目录 个人职业发展的喜悦团队成就的辉煌公众号CSDN申请了移动安全领域新星创作者获得6月城市之星北京TOP 10获得23年博客之星TOP 41年度总结 知识星球 开拓新领域的决心免费知识大陆付费知识大陆 展望未来福利时间知识星球会员一年知识星球立减88券 在这个充满挑战与机遇的…

(2)(2.9) Holybro Microhard P900无线电遥测设备

文章目录 前言 1 特点 2 规格 3 包装内包括 前言 Holybro Microhard Radio 集成了 microhard Pico 系列射频模块&#xff0c;能够在强大的拓扑结构中提供高性能无线串行通信&#xff0c;如点对点、点对多点和安全 Mesh&#xff08;P840 不提供 Mesh&#xff09;。 它采用跳…

SQL注入的剩余类型

除了联合查询注入&#xff0c;报错注入&#xff0c;盲注注入 sql注入还有以下几类&#x1f9b9;&#x1f9b9;&#x1f9b9;&#x1f9b9;&#x1f9b9; 开始填坑 1.UA注入 原理&#xff1a;有些网站会把用户的UA信息写入数据库&#xff0c;用来收集和统计用户…

【技术分享】Ubuntu 20.04如何更改用户名

产品简介 本文适用于所有RK3568/RK3588平台产品在Ubuntu 20.04系统上如何更改用户名&#xff0c;本文以IDO-EVB3588开发板为例&#xff0c;在ubuntu20.04系统上修改用户名industio为usernew。 IDO-EVB3588开发板是一款基于RK3588平台的产品。该开发板集成了四核Cortex-A76和四…

扫描电子显微镜电子束辐射损伤和如何减轻

扫描电镜&#xff08;Scanning Electron Microscope, SEM&#xff09;是一种常用的材料表征技术&#xff0c;它通过聚焦电子束扫描样品表面&#xff0c;利用电子与样品相互作用产生的信号来获得高分辨率的形貌图像。然而&#xff0c;电子束的辐射可能会对样品造成损伤&#xff…

Qt6入门教程 13:QPushButton

目录 一.QPushButton 1.多选 2.互斥 3.设置菜单 4.图标按钮 4.1给按钮添加图标 4.2异形按钮 二.设置Qt样式表 一.QPushButton QPushButton是与QAbstractButton最接近的完全体按钮&#xff0c;它具备QAbstractButton的所有特性&#xff0c;并且支持设置菜单。 1.多选 …

2024幻兽帕鲁服务器,阿里云配置

阿里云幻兽帕鲁服务器Palworld服务器推荐4核16G配置&#xff0c;可以选择通用型g7实例或通用算力型u1实例&#xff0c;ECS通用型g7实例4核16G配置价格是502.32元一个月&#xff0c;算力型u1实例4核16G是432.0元/月&#xff0c;经济型e实例是共享型云服务器&#xff0c;价格是32…

docker容器运维命令

文章目录 docker psdocker execdocker inspectdocker topdocker attachdocker waitdocker exportdocker importdocker portdocker cpdocker diffdocker renamedocker statsdocker update总结 docker ps 列出容器。 docker ps [OPTIONS]OPTIONS说明&#xff1a; -a :显示所有的…