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

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

  • 蓝牙连接建立过程图
  • 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;采用弱密码、安全防护不到位的默认设置、员工缺乏信息安全意识、未经授人员权访问无线网络…… 这些问…

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

第一&#xff1a;开启相关服务&#xff0c;监控SELINUX 相关服务&#xff1a;setroubleshoot,auditd,大多数都是以se开头的 如果没有此服务&#xff0c;先yum下&#xff0c;然后查看状态 这里关于auditd说明&#xff0c;centos7不可以用systemctl重启auditd服务&#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软件以其独特的作…

【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 :显示所有的…

Python列表中的append功能及用法举例

Python列表中的append功能及用法举例 &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333;append()&#x1f333;&#x1f340;功能介绍&#x1f340;&#x1f340;语法&#x1f340;&#x1f340;示例&#x1f340;&#x1f340;注意事项&#x…

总结NB-IoT模块和单片机的区别

在学习了NB-IoT模块后&#xff0c;紧接着又学习了单片机系统&#xff0c;单片机和NB-IoT模块有什么不同之处呢&#xff0c;总结为以下几点。 大纲如图&#xff1a; 一、硬件层面 1、采用芯片不同&#xff0c; &#xff08;1&#xff09;封装&#xff1a;封装尺寸、方式不同&a…

网络原理,网络通信以及网络协议

​​​​&#x1f493; 博客主页&#xff1a;从零开始的-CodeNinja之路 ⏩ 收录专栏&#xff1a;网络原理,网络通信以及网络协议 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 文章目录 网络原理概念网络通信局域网LAN广域网WAN 网络通信IP地址端口号…

VUE3动漫影视视频网站模板源码

文章目录 1.视频设计来源1.1 主界面1.2 动漫、电视剧、电影视频界面1.3 播放视频界面1.4 娱乐前线新闻界面1.5 关于我们界面 2.效果和源码2.1 动态效果2.2 源码结构 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/deta…