GFPS扩展技术原理(七)-音频切换消息流
音频切换消息流
Seeker和Provider通过消息流来同步音频切换能力,触发连接做切换,获取或设置音频切换偏好,通知连接状态等等。为此专门定义了音频切换消息流Message Group 为0x07,Message codes如下:
MAC of Audio switch Messages
所有的从seeker发送到Provider的消息都需要加上MAC,这样Provider应答这些消息的时候也需要带上MAC:
- Provider应答ACK的消息流格式如下:
- Provider应答NAK的消息流格式如下:
Get capability of Audio switch
这个消息可以由audio switch provider或者seeker发送,用于查询对方是否支持audio switch,消息流格式如下:
Notify capability of Audio switch
在收到get capability of Audio switch消息之后,Seeker或者Provider需要回复这个消息,格式如下:
这里我们主要关注一下Audio switch capability flags,只有Provider发送的时候,这两个字节才有效。这两个字节是标注音频切换能力的:
-
Bit 0 (octet 6, MSB): Audio switch state
1, if Audio switch state is on 0, otherwise
-
Bit 1: multipoint configurability
1, if the device supports multipoint and it can be switched between on and off 0, otherwise (does not support multipoint or multipoint is always on)
-
Bit 2: multipoint current state
1, if multipoint is on 0, otherwise
-
Bit 3: on-head detection
1, if this device supports on-head detection (even if on-head detection is turned off now) 0, otherwise
-
Bit 4: on-head detection current state
1, if on-head detection is turned on 0, otherwise (does not support on-head detection or on-head detection is disabled)
Set multipoint state
这个是audio switch seeker用来打开或关闭Provider multipoint功能的消息,消息流格式如下:
Set switching preference
这个是audio switch seeker用来设置Provider multipoint音频切换偏好的,消息流格式如下:
这里我们主要注意multipoint switching preference flag:
- Bit 0 (MSB): A2DP vs A2DP (default 0)
- Bit 1: HFP vs HFP (default 0)
- Bit 2: A2DP vs HFP (default 0)
- Bit 3: HFP vs A2DP (default 1)
- Bit 4 - 7: reserved
上面表示的形式是“新profile”VS"旧profiler",如果那个bit置上0,代表不能切换,如果置上1,表示可以切换。举个例子Bit 3置上1,表示如果有HFP连接进来,那么需要从原来的A2DP切换到HFP。
Get switching preference
Seeker可以发送Get switching preference消息给Provider,主动获取音频切换偏好,消息流格式如下:
Notify switching preference
Switch active audio source (to connected device)
Audio switch Seekers 可以请求multipoint Provider在连接的设备中切换活跃音频源,消息流格式如下:
这里我们主要关注Switching active audio source event flags这个字节:
- Bit 0 (MSB): 1 切换到当前设备, 0 切换到另外设备
- Bit 1: 1 在切换后恢复播放, 0 反着来。注意: 恢复播放意味着Provider需要通过AVRCP发送一个PLAY notification 给Seeker,如果seeker之前的状态就是停播,那么Provider就要忽略这个标志。
- Bit 2: 1 在切换出去的设备拒绝SCO 连接。 0 反着来。
- Bit 3: 1 在切换出去的设备断开蓝牙连接。0 反着来.
- Bit 4 - 7: 这几个bit保留未用.
如果Audio switch seeker已经是当前活跃音频设备了,然后又发送了switch active audio device 消息给Provider,那么Provider需要回复NAK,理由是0x04-Redundant device action。
对于LE Audio Provider,如果是被切换出去的设备,那么需要断开所有的协调集成员的连接。
Switch back (to disconnected device)
如果用户想切回原来的设备,那么可以发送如下格式消息:
需要注意的是switch back event:
- 0x01:switch back,就是简单的切回去连接上。
- 0x02:切回去然后恢复播放,这里有个前提就是断开的设备,在被断开前的状态也是播放状态才行,否则Provider会忽略这个标志。
Notify multipoint-switch event
audio switch Provider通知Seeker发生的切换事件,消息格式如下:
Get connection status
Seeker从Provider获取当前连接状态,消息格式如下:
Notify connection status
连接状态的改变,除了需要修改BLE广播,还有就是Provider需要通知当前使用共同accout key的连接的audio switch seeker。如果provider连接一个audio switch seeker和一个non-audio switch seeker,并且当前活跃设备是non-audio switch seeker,那么provider也要通知audio switch seeker。Provider发送给Seeker的连接状态的消息,格式如下:
这里注意一下Encrypted connection status,跟之前音频切换广播里的connection status一样:
encrypted_connection_status = connection_status_raw_data ^ AES(Key, IV)
其中:
clike Key = HKDF(account_key, NULL, UTF8("SASS-RRD-KEY"),16)
- IV is concat(Session_nonce, Message_nonce)
- connection_status_raw_data = concat(connection_state, custom_data, connected_devices)
Notify Audio switch initiated connection
这个是Seeker告诉Provider,此连接是audio switch发起的连接,消息格式如下:
Indicate in use account key
如果同一个Seeker上多个account key 账户连接着同一个Provider,那么Seeker使用如下格式消息告诉Provider当前使用哪个account key:
Provider收到消息后,通过校验MAC能够得知当前使用哪个account key。
Send custom data
活跃Audio switch Seeker能够封装音频流信息在custom data里发送给Provider,消息格式如下:
Provider收到custom data之后,会更新广播数据包含custom data。如果是multipoint Provider,它也需要使用相同的account key通知连接状态的改变给另外连接的seeker。
Set drop connection target
在 multipoint headsets, 如果想要断开的连接不是最近常用的连接,那么需要audio switch Seekers 告诉Provider需要断开哪个设备,数据格式如下:
相关文章:

GFPS扩展技术原理(七)-音频切换消息流
音频切换消息流 Seeker和Provider通过消息流来同步音频切换能力,触发连接做切换,获取或设置音频切换偏好,通知连接状态等等。为此专门定义了音频切换消息流Message Group 为0x07,Message codes如下: MAC of Audio s…...
压缩qcow2镜像带来的性能损失简单分析
本文拟对压缩qcow2镜像所带来的虚拟机性能损失进行简单分析 背景 生产中发现使用压缩镜像启动的虚拟机开机总是会慢一些。 qcow2镜像的压缩方式为:qemu-img convert -p -c -O qcow2 zero_disk.qcow2 compress_disk.qcow2 分析 qemu代码:https://down…...
Kali操作系统简单介绍
Kali是一个集成了各种安全工具的操作系统 安全问题的根源 1.分层思想:网络和软件开发的分层方法 2.安全问题:分层思想导致的片面认识和系统脆弱性 3.人的因素:安全问题的最终根源是人的错误 传统安全建设 1.防护型安全建设:关闭不…...
LabVIEW物联网开发实战:专栏总述
本专栏以LabVIEW为开发平台,讲解物联网通信组网原理与开发方法,覆盖RS232、TCP、MQTT、蓝牙、Wi-Fi、NB-IoT等协议。 结合实际案例,展示如何利用LabVIEW和常用模块实现物联网系统的快速开发与原型设计,助你从基础到实战࿰…...

高效处理PDF文件的终极工具:构建一个多功能PDF转换器
在日常工作中,处理PDF文件几乎是每个人都不可避免的任务。无论是从PDF中提取数据、合并多个PDF文件,还是处理文件中的敏感信息和图像,PDF文件的处理都可能成为繁琐且耗时的工作。如果你是数据分析师、工程师,或者从事文档管理的工…...

Y3编辑器教程6:触发器进阶案例
文章目录 一、地形制作1.1 地形制作流程1.2 关卡白盒1.3 场景美化1.4 优化场景 二、触发结构三、玩家指引(函数封装)3.1 项目拆解3.2 功能实现3.2.1 绘制UI界面3.2.2 UI的读取显示和刷新3.2.3 交互功能3.2.4 最终实现 四、NPC对话系统4.1 项目拆解4.2 UI…...

react Ant Design
一、通过项目模版创建一个react项目 set NPM_CONFIG_REGISTRYhttps://registry.npmmirror.com pnpm create vite antd-demo cd antd-demo pnpm install pnpm install antd --save 打开项目: 修改:welcome.tsx import React from react; import { Butto…...

汽车电子零部件(14):APA(自动泊车辅助)/RPA(远程遥控泊车)/AVP(自动代客泊车)
APA: Automated Parking Assist (APA) systems,自动泊车辅助系统,是自动驾驶汽车的一个关键功能。自动泊车辅助系统(APA)利用超声波雷达、视觉传感器和ADAS处理器来定位合适的停车位。它识别适合车辆大小的停车位,规划停车路线,并控制方向盘、变速箱和油门踏板以辅助停…...
Hot100刷题计划-Day2-滑动窗口、双指针、数组、链表、动态规划
LeetCode Hot 100 是最常被考察的题目集合,涵盖了面试中常见的算法和数据结构问题。刷 Hot100可以让你在有限的时间内集中精力解决最常考的问题。不仅要写出代码,还要理解问题的本质、优化解法和复杂度分析。 滑动窗口 438. 找到字符串中所有字母异位词…...

[react 3种方法] 获取ant组件ref用ts如何定义?
获取ant的轮播图组件, 我用ts如何定义? Strongly Type useRef with ElementRef | Total TypeScript import React, { ElementRef } from react; const lunboRef useRef<ElementRef<typeof Carousel>>(null); <Carousel autoplay ref{lunboRef}> 这样就…...

考前倒计时98天
2024年12月21日到2025年3月29日共有 98 天 一、计算机基础 思维分类特征强调学科代表理论思维(推理思维)推理和演绎推理数学实验思维(证实思维)观察和总结自然规律归纳物理学计算思维(构造思维)设计和构造…...

iterm2 focus时灰色蒙层出现的解决办法
问题描述: 当前我的iterm2版本是3.5.10,是我最近才更新的,然后就出现以下页面显示问题,如图所示: 我个人对终端、编辑器等使用存在洁癖,尤其是页面显示效果不满意更是不能忍受,之前找了很久没有…...
合并K个升序链表(最优解)
题目来源 23. 合并 K 个升序链表 - 力扣(LeetCode) 题目描述 给你一个链表数组,每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中,返回合并后的链表。 示例 1: 输入:lists [[1,4,5],[1,3,…...

kubernates实战
使用k8s来部署tomcat 1、创建一个部署,并指定镜像地址 kubectl create deployment tomcat6 --imagetomcat:6.0.53-jre82、查看部署pod状态 kubectl get pods # 获取default名称空间下的pods kubectl get pods --all-namespaces # 获取所有名称空间下的pods kubect…...
How to run Flutter on an Embedded Device
basysKom GmbH | How to run Flutter on an Embedded Device https://github.com/sony/flutter-embedded-linux/wiki/Building-Flutter-Engine-from-source flutter源码下载(最新)-CSDN博客 flutter_engine 交叉编译【自定义编译器(最新)】_flutter。engine 修改-CSDN博客 …...

airflow docker 安装
mkdir -p /root/airflow cd /root/airflow && mkdir -p ./dags ./logs ./plugins ./configcd /root/airflow/ wget https://airflow.apache.org/docs/apache-airflow/2.10.4/docker-compose.yaml nano docker-compose.yamlAIRFLOW__CORE__LOAD_EXAMPLES: false #初始化…...

浅析InnoDB引擎架构(已完结)
大家好,我是此林。 今天来介绍下InnoDB底层架构。 1. 磁盘架构 我们所有的数据库文件都保存在 /var/lib/mysql目录下。 由于我这边是docker部署的mysql,用如下命令查看mysql数据挂载。 docker inspect mysql-master 如下图,目前只有一个数…...

华为云计算HCIE笔记02
第二章:华为云Stack规划设计 交付总流程 准备工作:了解客户的基本现场,并且对客户的需求有基本的认知。 HLD方案BOQ报价设备采购和设备上架 2.安装部署流程 硬件架构设计 硬件设备选配 设备上架与初始化配置 准备相关资料(自动下载…...

鸿蒙项目云捐助第十讲鸿蒙App应用分类页面二级联动功能实现
鸿蒙项目云捐助第十讲鸿蒙App应用分类页面二级联动功能实现 在之前的教程中完成了分类页面的左右两侧的列表结构,如下图所示。 接下来需要实现左侧分类导航项的点击操作,可以友好的提示用户选择了哪一个文字分类导航项。 一、左侧文字分类导航的处理 …...

STM32低功耗模式结合看门狗
STM32低功耗模式结合看门狗 前言 最近做到一个需求要使用STM32的低功耗模式进行长时间待机应用,每隔十分钟发送一次数据到服务器上,当不发送的时候就处于低功耗模式。在经过一段时间的测试以后发现板子过三四天左右就没有数据上传服务器了,…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

【51单片机】4. 模块化编程与LCD1602Debug
1. 什么是模块化编程 传统编程会将所有函数放在main.c中,如果使用的模块多,一个文件内会有很多代码,不利于组织和管理 模块化编程则是将各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数声明,其他.c文…...

PydanticAI快速入门示例
参考链接:https://ai.pydantic.dev/#why-use-pydanticai 示例代码 from pydantic_ai import Agent from pydantic_ai.models.openai import OpenAIModel from pydantic_ai.providers.openai import OpenAIProvider# 配置使用阿里云通义千问模型 model OpenAIMode…...