【Android】【Bluetooth Stack】蓝牙电话协议分析(超详细)

1. 精讲蓝牙协议栈(Bluetooth Stack):SPP/A2DP/AVRCP/HFP/PBAP/IAP2/HID/MAP/OPP/PAN/GATTC/GATTS/HOGP等协议理论

2. 欢迎大家关注和订阅,【蓝牙协议栈】和【Android Bluetooth Stack】专栏会持续更新中.....敬请期待!

目录

1. 协议架构

1.1 Profile Dependencies

1.2 HFP Protocol Stack

2. HFP功能支持情况

3. AT 指令集

3.1 GSM 07.07 & 3GPP 27.077 重用的 AT 功能

3.2 蓝牙定义的 AT 功能

3.3 AT+CIND 相关 indicators及范围

3.4 AT+CLCC


1. 协议架构

1.1 Profile Dependencies

在蓝牙电话的数据传输中使用的是SCO协议(同步定向链接)。支持对时延敏感的信息如语音。

使用保留带宽进行同步通信,即两台设备在LMP层利用保留时隙在物理信道上周期传送数据包,这种类型的链接主要用于传送SCO包(语音数据)。SCO不包括CRC码,且不进行重传,主要支持传输有时间限制的信息,例如声音。

仅仅在ACL链接已经建立之后,才可以建立SCO链接;

  • AT CMD:AT指令是应用于终端设备和PC应用之间的连接与通信的指令;

  • SPP:蓝牙串口协议,在蓝牙设备之间建立虚拟的串口进行数据通信,简单的说就是两个蓝牙设备对端发送自定义数据;iPhone不支持SPP协议;

  • GAP:通用访问配置文件,该Profile保证不同的Bluetooth产品可以互相发现对方并建立连接;GAP定义了蓝牙设备如何发现和建立与其他设备的安全/不安全连接,它处理一些一般模式的业务(询问、命名和搜索)和一些安全性问题;GAP一般有4个作用:

    • Profile Role
    • 可发现模式和过程
    • 连接模式和过程
    • 安全模式和过程
  • eSCO:可以简单的理解为和SCO不同点:支持数据包的重传;

  • incoming call:由Phone Network到AG的通话,即称为来电;

  • outgoing call:由AG到Phone Network的通话,即称为拨号,去电;

1.2 HFP Protocol Stack

针对蓝牙电话,涉及到的协议有:HFP、RFCOMM;

目前HFP的使用场景常见的有车载蓝牙、耳机、PDA(Personal Digital Assistant - 掌上电脑,类似于智能手机、平板电脑、手持游戏机等),其中HFP协议中定义了AG和HFP两种角色:

  • AG(Audio Gate):音频网关 - 音频设备输入输出网关;
  • HF(Hands Free):免提 - 该设备作为音频网关的远程音频输入 / 输出机制,并可提供若干遥控功能;

在车载领域,手机侧为AG,车载侧为HF,在Android源码定义中,通常将AG称为HFP/AG,将HF称为HFPClient/HF;

2. HFP功能支持情况

(M代表强制支持,O代表可选)

NumfunctionHFAGNumfunctionHFAG
1连接管理MM14噪声抑制回声消除OO
2电话状态信息MM15语音识别OO
3音频连接处理MM16号码绑定语音标签OO
4接收语音来电MM17传输多音频能力OM
5拒绝语音来电MO18远程音量控制OO
6中断电话MM19回复和保持OO
7通话中音频链路切换MM20描述号码信息OM
8免提设备拨号OM21a扩展电话状态OM
9历史列表拨号OM21b扩展电话控制OO
10拨打最后一个电话OM22特有指示OM
11拨号等待通知OM23宽频语音OO
12三方通话OO24编解码器协商OO
13CLI(呼叫线路识别)OM25手持设备指示器OO

3. AT 指令集

3.1 GSM 07.07 & 3GPP 27.077 重用的 AT 功能

CMD发送方SyntaxResponseNameDescription
ATAOK标准呼叫应答命令
ATDdd...dd车机OK标准AT命令,用于拨打电话号码本规范仅包括语音通话
ATD>nnn...车机OK标准ATD命令的扩展,用于内存拨号本规范仅涉及语音通话
ERROR标准错误指示代码
OK对命令执行的标准确认
NO CARRIER, BUSY, NO ANSWER, DELAYED, BLACKLISTEDAT命令的扩展响应指示代码这些指令由AG向HF发送,作为对HF向AG发出的AT命令的响应,或从AG发出,作为未经请求的结果代码
RING标准来电指示
AT+CCWA车机AT+CCWA=[[,[,]]]+CCWA标准的呼叫等待通知AT命令在该规范中,仅适用参数启动/禁用呼叫等待通知主动结果代码
+CCWA手机标准“呼叫等待通知”主动结果代码该规范中仅包含两个属性:number和type number:文本字符串,并应始终包含在双引号内 type:字段指定提供的电话号码的格式
AT+CHLD车机AT+CHLD=标准呼叫保持和多方处理AT命令的取值范围: 0:释放所有保持的呼叫或将用户确定的用于忙(UDUB)设置为等待呼叫 1:释放所有活动呼叫(如果存在),并接收其他呼叫(保持或等待) 1:释放具有指定索引(索引值为值)的调用 2:保持所有活动呼叫(如果存在)并接受另一个(保持或等待)呼叫 2:使用指定呼叫()请求私人咨询模式。(将所有呼叫置于保持状态,指示的呼叫除外) 3:将保持的呼叫添加到对话中 4:连接两个呼叫并断开用于与两个呼叫的连接(显式呼叫转移)。
AT+CHUP车机标准挂起AT命令执行命令使AG终止当前活动的调用
AT+CIND车机AT+CIND=?:获取对方特性支持情况 AT+CIND?:获取对方特性值+CIND标准指示更新AT命令
+CIND手机当前电话指示器的标准列表
AT+CLCC车机OK标准列表当前呼叫命令
+CLCC手机OK标准列表当前调用结果代码
AT+COPS车机+COPS:,,用于读取网络运营商信息:包含当前模式并且不提供有关操作员名称的信息 :指定参数字符串的格式,在本规范中应始终为0 :以字母数据格式指定带引号的字符串,表示网络运营商的名称。该字符串不得超过16个字符
AT+CMEE车机标准AT命令用于启用
+CME ERROR+CME ERROR:扩展音频网关错误结果代码响应使用结果代码+CME ERROR:作为与AG功能相关的错误的指示
AT+CLIP车机AT+CLIP=+CLIP标准呼叫线路识别通知激活AT命令它启用/禁用呼叫线路识别通知主动结果代码 +CLIP
+CLIP手机+CLIP: , type> [,, [,[] [,]]]标准呼叫线路识别通知主动结果代码:参数应为文本字符串,并应始终包含在双引号内 :字段指定提供的电话号码的格式
AT+CMER车机AT+CMER=[[,[,[, [,]]]]]OK标准事件报告激活/停用AT命令:该参数一般情况下value = 3 :分为两种情况:0代表禁用,1代表激活
+CIEV手机+CIEV: ,标准的指标事件报告主动结果代码:AT+CIND=?命令。列表的第一个元素应具有=1 :指标的当前状态
AT+VTS车机AT+VTS=标准DTMF生成AT命令
AT+CNUM车机AT+CNUM AT+CNUM=?+CNUM检索用户号码信息 测试用户号码信息 - 未实施HF为AG中的“用户号码信息”功能发出的命令。仅使用AT+CNUM格式的动作命令
+CNUM手机+CNUM: [],, ,[ ,]将“订户号码信息”从AG发送到HF的标准响应:不支持此可选字段,应留空 :包含电话号码的引用字符串,格式由指定 :字段指定提供的电话号码的格式 :不支持此可选字段,应留空 :表示此电话号码与哪个服务相关,4代表语音,5代表传真

3.2 蓝牙定义的 AT 功能

CMD发送方SyntaxResponseDesc
AT+BIA车机AT+BIA=[<indrep 1>[,…[,[]]]]]]蓝牙指示激活,单独激活或停用指示器:代表了指标x的状态,1代表激活,0代表禁用
AT+BINP车机AT+BINP=+BINP: …蓝牙输入,用于从AG请求某些特定数据输入的命令收到此命令后,AG应执行适当的操作,以便使用+BINP响应将请求的信息发送回HF :数据请求,其中value = 1对应于HF中记录的最后一个语音标签的电话号码 :AG返回的数据参数。该参数内容取决于,一般情况下为Phone number
AT+BLDN车机AT+BLDN蓝牙最后拨打的号码用于呼叫最后拨打的电话号码。收到此命令后,AG应建立对最后拨打的电话号码的语音呼叫。
AT+BVRA车机AT+BVRA=+BVRA蓝牙语音识别激活启用/禁用AG中的语音识别功能,如果支持增强语音识别状态功能,则此命令用于向AG指示HF已准备号呈现音频输出 :0代表了在AG中禁用语音识别,1代表在AG中启用语音识别,2代表仅当AG和HF都支持增强语音识别状态功能时才应使用该值
+BVRA手机+BVRA: ,蓝牙语音识别激活当AG中的语音识别功能由AG自主激活/停用时,用于通知HF的非请求结果代码 :0代表了在AG中禁用语音识别,1代表在AG中启用语音识别 :反映AG上语音识别引擎当前状态的位掩码 :仅当AG和HF都支持语音识别文本功能,才会出现
AT+BRSF车机AT+BRSF=+BRSF蓝牙检索支持的功能通知AG HF中可用的支持功能,并请求有关AG中支持的功能的信息。支持的特性应以十进制值表示 0:EC / NR 功能 1:三方通话 2:CLI演示功能 3:语音识别激活 4:远程音量控制 5:增强的通话状态 6:增强的呼叫控制 7:编解码器协商 8:HF 指标 9:支持的eSCO S4 设置 10:增强的语音识别状态 11:语音识别文本 12-31:留作将来使用
+BRSF手机+BRSF:蓝牙检索支持的功能AG响应AT+BRSF命令发送的结果码,用于通知HF AG支持哪些功能。支持的特性应以十进制值表示 0:三方通话 1:EC / NR 功能 2:语音识别功能 3:带内铃声功能 4:将号码附加到语音标签 5:拒绝来电的功能 6:增强的通话状态 7:增强的呼叫控制 8:扩展错误结果代码 9:编解码器协商 10:HF 指标 11:支持的 eSCO S4 设置 12:增强的语音识别状态 13:语音识别文本 14-31:留作将来使用
AT+NREC车机AT+NREC=降噪和回声消除发出命令以禁用嵌入AG中的任何回声消除和降噪功能 :0代表了在AG中禁用 EC / NR
AT+VGM车机AT+VGM=+VGM=麦克风增益HF发出的命令,用于向AG报告其当前的麦克风增益级别设置 :是一个十进制数字,与由HF控制的特定(取决于实现)音量级别有关。该命令不会改变AG的麦克风增益,它仅指示HF中麦克风增益的当前值,取值范围:0~15
AT+VGS车机AT+VGS=+VGS=扬声器增益HF发出的命令,用于向AG报告其当前的扬声器增益水平设置 :是一个十进制数字,与由HF控制的特定(取决于实现)音量级别有关。该命令不会改变AG的扬声器增益,它仅指示HF中麦克风增益的当前值,取值范围:0~15
+VGM手机+VGM=麦克风增益由AG主动发出的结果代码,用于设置HF的麦克风增益。
+VGS手机+VGS=扬声器增益由AG主动发出的结果代码,用于设置HF的扬声器增益
+BSIR手机+BSIR:带内铃声的蓝牙设置由AG发出的主动结果代码,用于向HF指示带内铃声设置已在本地更改。HF可以通过改变自己的警报方法作出响应的反应 :0代表了AG不提供带内铃声,1代表AG提供带内铃声
AT+BTRH车机AT+BTRH=:设置指令 AT+BTRH?:读取当前状态+BTRH蓝牙响应和保持功能HF为AG中的“响应和保持”功能发出的命令。本规范定义了set和read命令的使用,AT+BTRH ? HF应使用命令来查询 AG 的当前“响应和保持”状态 :0代表保留来电,1代表接受保持的来电,2代表拒绝保持的来电
+BTRH手机+BTRH=蓝牙响应和保持功能每当来电被搁置或接受或拒绝时,用于通知HF的结果代码。对于AT+BTRH,AG是否也应回复此响应 ? 来自 HF 的命令 :0代表了来电在 AG中保持,1代表了在AG中接受保持的来电,2代表了在AG中拒绝保持的来电
AT+BCC车机AT+BCC蓝牙编解码连接HF使用该命令请求AG启动编解码器连接过程
AT+BCS车机AT+BCS=蓝牙编解码器选择此命令向远程设备(AG)确认编解码器,并隐含地确认将在同步连接上使用哪个同步协议,如果不包含任何值,则该命令无效 :所有可能的Codec ID,将AT+BAC的定义
+BCS手机+BCS:蓝牙编解码器选择该命令将编解码器通知给远程设备(HF),并隐含地通知将在同步连接上使用哪种同步协议 :所有可能的Codec ID,将AT+BAC的定义
AT+BAC车机AT+BAC= [[,[,...[,]]]] (u1,u2, ..., un are a codec IDs)OK蓝牙可用编解码器此命令通知远程设备(AG)HF支持哪些编解码器 :所有可能的Codec ID,将AT+BAC的定义
AT+BIND车机AT+BIND= ,,,...,:列出HF支持的指标 AT+BIND=?:阅读AG支持的指标 AT+BIND?:读取指示的AG启用/禁用状态+BIND蓝牙HF指示功能该命令使HF能够通知AG支持哪些HF到AG指示符。指示器可以启用或禁用。除非“HF 指示器”功能的 AG 和 HF BRSF 位都设置为1,否则不应使用AT+BIND命令 ...:0-65535,作为十进制无符号整数值输入,不带前导零,引用 HF 指示器分配的编号。
+BIND手机+BIND: (,,,...,):响应AT+BIND=? +BIND: ,:主动或响应AT+BIND?蓝牙HF指示功能该响应使AG能够通知HF支持哪些HF指示器及其状态,启用或禁用。 除非“HF 指示器”功能的AG和HF BRSF为都设置为1,否则不应使用+BIND响应 ...:0-65535,作为十进制无符号整数值输入,不带前导零,引用 HF 指示器分配的编号。 :0 - 1,其中0代表了指示器被禁用,不应为此指示器发送值更改,1代表了指示器已启用,可以为该指示器发送值更改
AT+BIEV车机AT+BIEV= ,蓝牙HF指示功能此命令使HF能够将启用的HF指示器的更新值发送到AG

3.3 AT+CIND 相关 indicators及范围

indicatorindexindex 范围Desc
call:Call Status indicator10 1there are no calls in progress — 没有电话在进行中 at least one call is in progress — 至少有一个电话在进行中
callsetup:Call set up status indicator20 1 2 3not currently in call set up — 当前没在呼叫中设置 an incoming call process ongoing — 来电进行中 an outgoing call set up is ongoing — 正在设置一个传出呼叫 remote party being alerted in an outgoing call — 呼叫的对方正在响铃
service:Service availability indication30 1No Home/Roam network available — 没有信号 Home/Roam network available — 有信号服务
signal:Signal Strength indicator40~5电话信号质量
roam:Roaming Status indicator50 1roaming is not active — 没有漫游 a roaming is active — 漫游中
battchg:Battery Charge indicator of AG60~5AG侧的电量值
callheld:Call hold status indicator70 1 2No calls held Call is placed on hold or active/held calls swapped(The AG has both an active AND a held call) — 电话被设置为保持或者电话切换中 Call on hold, no active call — 电话保持中,没有电话处于通话中

3.4 AT+CLCC

HF请求当前的电话信息列表,构造格式:+CLCC: < idx >,< dir >,< status >,< mode >,< mpty >,< number >,< type >,AG侧回复当前的电话信息列表。如果当前没有电话,AG侧也需回复OK指令,不然将电话信息以列表形式发送给HF;

  • < idx >:当前电话是第几路,从 1 开始计数

  • < dir >:电话方向,0代表往外拨打的电话outgoing;1代表来电incoming;

  • < status >:电话状态

    • 0:Active
    • 1:Held
    • 2:Dialing(outgoing calls only)
    • 3:Alerting(outgoing calls only)
    • 4:Incoming(incoming calls only)
    • 5:Waiting(incoming calls only)
    • 6:Call held by Response and Hold
  • < mode >:电话模式

    • 0:voice
    • 1:data
    • 2:FAX
  • < mpty >:是否为多方通话的电话

    • 0:this call is NOT a member of a multi-party(conference)call
    • 1:this call is a member of a multi-party(conference)call
  • < number >:可选项,电话号码

  • < type >:可选项,电话类型

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

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

相关文章

MyBatis框架简述

作用 降低开发人员使用JDBC的难度降低开发人员进行Dao层的开发难度 MyBatis本质上就是对JDBC的封装&#xff0c;通过MyBatis完成CRUD。MyBatis在三层架构中负责持久层的&#xff0c;属于持久层框架。MyBatis的发展历程&#xff1a;【引用百度百科】 MyBatis本是apache的一个开…

图书推荐|高性能Linux网络编程核心技术揭秘

实战基于libevent 的FTP服务器、基于epoll的高并发聊天服务器、基于DPDK的应用案例 本书简介 本书详解高性能Linux网络编程的核心技术及DPDK框架&#xff0c;剖析Nginx高性能服务器架构&#xff0c;实战基于libevent 的FTP服务器、基于epoll的高并发聊天服务器、基于DPDK的应用…

Docker网桥、DockerFile自定义镜像、DockerCompose工具(二)

这里写目录标题 1、网桥1.1、网络相关操作1.1.1、创建网络1.1.2、列出网络1.1.3、加入网络1.1.4、查看网络详情1.1.5、删除网络 2、Dockerfile自定义镜像2.1、镜像结构2.2、Dockerfile语法2.2.1、概述2.2.2、快速入门2.2.1、FROM2.2.2、CMD2.2.3、ENV2.2.4、WORKDIR2.2.5、run2…

关于汽车中网改装需要报备吗?(第二天)

车联网改造需要申报吗&#xff1f; 今天2022年10月20日&#xff0c;小编就给大家介绍一下车联网改装是否需要申报的相关知识。 让我们来看看。 汽车格栅改装无需申报。 这种年检可以直接通过。 您不必担心&#xff0c;因为汽车格栅对于实车的外观来说并不陌生&#xff0c;因此…

设计编程网站集:生活部分:饮食+农业,植物(暂记)

这里写目录标题 植物相关综合教程**大型植物&#xff1a;****高大乔木&#xff08;Trees&#xff09;&#xff1a;** 具有坚硬的木质茎&#xff0c;通常高度超过6米。例如&#xff0c;橡树、松树、榉树等。松树梧桐 **灌木&#xff08;Shrubs&#xff09;&#xff1a;** 比乔木…

flutter使用记录(vscode开发)

1.Gradle-7.6.3-all.zip 下载失败 编辑项目中的 gradle/wrapper/gradle-wrapper.properties 文件&#xff0c;并设置 distributionUrl 的值为可靠的镜像站点&#xff0c;如下所示&#xff1a; distributionUrlhttps\://services.gradle.org/distributions/gradle-7.6.3-all.z…

HarmonyOS ArkTS 基础组件

目录 一、常用组件 二、文本显示&#xff08;Text/Span) 2.1 创建文本 2.2 属性 2.3 添加子组件(Span) 2.4 添加事件 三、按钮&#xff08;Button&#xff09; 3.1 创建按钮 3.2 设置按钮类型 3.3 悬浮按钮 四、文本输入&#xff08;TextInput/TextArea&#xff09;…

个人网站制作 Part 14 添加网站分析工具 | Web开发项目

文章目录 &#x1f469;‍&#x1f4bb; 基础Web开发练手项目系列&#xff1a;个人网站制作&#x1f680; 添加网站分析工具&#x1f528;使用Google Analytics&#x1f527;步骤 1: 注册Google Analytics账户&#x1f527;步骤 2: 获取跟踪代码 &#x1f528;使用Vue.js&#…

分库分表场景下多维查询解决方案(用户+商户)

在采用分库分表设计时&#xff0c;通过一个PartitionKey根据散列策略将数据分散到不同的库表中&#xff0c;从而有效降低海量数据下C端访问数据库的压力。这种方式可以缓解单一数据库的压力&#xff0c;提升了吞吐量&#xff0c;但同时也带来了新的问题。对于B端商户而言&#…

权限提升-Web权限提升篇划分获取资产服务后台系统数据库管理相互转移

知识点 1、权限提升转移-分类&高低&场景 2、Web权限提升及转移-后台&数据库 3、后台权限及转移-转移对象&后台分类 章节点&#xff1a; 1、Web权限提升及转移 2、系统权限提升及转移 3、宿主权限提升及转移 4、域控权限提升及转移 基础点 0、为什么我们要学…

B004-springcloud alibaba 服务容错 Sentinel

目录 高并发带来的问题服务雪崩效应常见容错方案常见的容错思路隔离超时限流熔断降级 常见的容错组件 Sentinel入门什么是Sentinel微服务项目集成Sentinel核心库安装Sentinel控制台实现一个接口的限流 Sentinel的概念和功能基本概念重要功能 Sentinel规则流控规则三种流控模式三…

verilog设计-CDC:单bit脉冲快时钟域到慢时钟域

一、前言 当单bit信号由快时钟域传递给慢时钟域时&#xff0c;快时钟域的异步信号最小可为快时钟信号的一个时钟周期脉冲&#xff0c;快时钟域的单时钟周期脉冲长度小于慢时钟域的时钟周期&#xff0c;很有可能该脉冲信号在慢时钟域的两个时钟上升沿之间&#xff0c;导致该脉冲…

Flask中的Blueprints:模块化和组织大型Web应用【第142篇—Web应用】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 Flask中的Blueprints&#xff1a;模块化和组织大型Web应用 在构建大型Web应用时&#xff0…

数据机构-2(顺序表)

线性表 概念 顺序表 示例&#xff1a;创建一个存储学生信息的顺序表 表头&#xff08;Tlen总长度&#xff0c; Clen当前长度&#xff09; 函数 #include <seqlist.c> #include <stdio.h> #include <stdlib.h> #include "seqlist.h" #include &…

【论文精读】OTA: Optimal Transport Assignment for Object Detection(物体探测的最优传输分配)

OTA最优传输 &#x1f680;&#x1f680;&#x1f680;摘要一、1️⃣ Introduction---介绍二、2️⃣Related Work---相关工作2.1 &#x1f393; Fixed Label Assignment--静态标签分配2.2 ✨Dynamic Label Assignment--动态标签分配 三、3️⃣Method---论文方法3.1 &#x1f39…

Linux - 应用层HTTPS、传输层TCP/IP模型中典型协议解析

目录 应用层&#xff1a;自定制协议实例 HTTP协议首行头部空行正文http服务器的搭建 HTTPS协议 传输层UDP协议TCP协议 应用层&#xff1a; 应用层负责应用程序之间的沟通—程序员自己定义数据的组织格式 应用层协议&#xff1a;如何将多个数据对象组织成为一个二进制数据串进行…

【探讨】基于卷积神经网络深度学习模型的光场显微三维粒子空间分布重建

光场显微粒子图像测速技术通过单光场相机即可实现微尺度三维速度场的测量&#xff0c;但单光场相机角度信息有限&#xff0c;导致粒子重建的轴向分辨率低、重建速度慢。基于此&#xff0c;提出一种基于卷积神经网络深度学习模型的光场显微粒子三维空间分布重建方法&#xff0c;…

说说你对webpack的理解?解决了什么问题?

文章目录 一、背景二、问题三、是什么参考文献 一、背景 Webpack 最初的目标是实现前端项目的模块化&#xff0c;旨在更高效地管理和维护项目中的每一个资源 模块化 最早的时候&#xff0c;我们会通过文件划分的形式实现模块化&#xff0c;也就是将每个功能及其相关状态数据各…

浅谈如何自我实现一个消息队列服务器(2)——实现 broker server 服务器

文章目录 一、实现 broker server 服务器1.1 创建一个SpringBoot项目1.2 创建Java类 二、硬盘持久化存储 broker server 里的数据2.1 数据库存储2.1.1 浅谈SQLiteMyBatis 2.1.2 如何使用SQLite 2.2 使用DataBaseManager类封装数据库操作2.3 文件存储消息2.3.1 存储消息时&#…

Visual Studio 2022进行文件差异比较

前言 Visual Studio 2022在版本17.7.4中发布在解决方案资源管理器中比较文件的功能&#xff0c;通过使用此功能&#xff0c;可以轻松地查看两个文件之间的差异&#xff0c;包括添加、删除和修改的代码行。可以逐行查看差异&#xff0c;并根据需要手动调整和编辑文件内容以进行…