Linux 藍牙音頻軟件棧實現分析

Linux 藍牙音頻軟件棧實現分析

    • 藍牙協議棧簡介
    • 藍牙控制器探測
    • BlueZ 插件系統及音頻插件

藍牙協議棧簡介

藍牙協議棧是實現藍牙通信功能的軟件架構,它由多個層次組成,每一層負責特定的功能。藍牙協議棧的設計遵循藍牙標準 (由藍牙技術聯盟Bluetooth SIG 定義),支持多種藍牙配置文件 (Profiles),以滿足不同的應用場景 (如音頻傳輸、文件傳輸、健康設備、鍵盤鼠標這樣的輸入輸出設備等)。

藍牙各個應用場景的實現,如音頻傳輸、文件傳輸和鍵盤鼠標這樣的輸入設備,與系統中常規的這些功能的實現大為不同。如對于音頻播放和錄制,通過 USB 連接的音頻設備,或通過 audio codec 實現的音頻播放和錄制,在 Linux 中,基于 ALSA 框架實現,內核通過導出設備文件向用戶空間暴露相應的硬件能力。USB 鍵盤鼠標,在 Linux 中,基于輸入設備框架實現,內核同樣通過導出設備文件向用戶空間暴露相應的硬件能力。

可與藍牙協議棧類比的不是系統中常規的各個功能的實現,而是 TCP/IP 網絡協議棧。在實現上,與 TCP/IP 網絡協議棧類似,藍牙協議棧不同功能的各個協議層次實現分布于硬件、Linux 操作系統內核、BlueZ 這樣的藍牙系統服務和 PulseAudio 這樣系統服務中。

Bluetooth SIG 官方的藍牙核心規范 (藍牙核心規范 6.0) 給出的藍牙核心系統架構如下圖所示:
Bluetooth core system architecture
藍牙協議棧的分層結構如下圖所示:

+--------------------------------------------------------------------------------------------+
|                   Application Layer                                                        |
|  (Profiles: A2DP, HFP, HSP, AVRCP, HAP, BAP, ACS, ACAS, GAP, GATT, FTP, OPP, etc.)         |
+--------------------------------------------------------------------------------------------+
|                   Middleware Layer                                                         |
|  (Protocols: AVDTP, AVCTP, SDP, ATT, RFCOMM, OBEX, TCS, BNEP, etc.)    |
+--------------------------------------------------------------------------------------------+
|                   Host Controller Interface (HCI)                                          |
|  (Protocols: HCI Commands, Events, and Data)                                               |
+--------------------------------------------------------------------------------------------+
|                   Logical Link Control and                                                 |
|                   Adaptation Protocol (L2CAP)                                              |
+--------------------------------------------------------------------------------------------+
|                   Baseband Layer                                                           |
|  (Protocols: Link Manager Protocol (LMP), SCO, eSCO, ACL, ISOC, etc.)                            |
+--------------------------------------------------------------------------------------------+
|                   Radio Layer                                                              |
|  (Physical Layer: Bluetooth Radio)                                                         |
+--------------------------------------------------------------------------------------------+

藍牙協議棧各層次簡單說明如下:

  • 應用層:實現具體的藍牙應用功能 (如音頻傳輸、文件傳輸)。通過藍牙配置文件 (Profiles) 定義設備的行為。常見的應用層協議/配置文件有 A2DP (Advanced Audio Distribution Profile,高質量音頻傳輸),HFP (Hands-Free Profile,免提通話),HSP (Headset Profile,耳機通話),AVRCP (Audio/Video Remote Control Profile,遠程控制音頻/視頻設備),HAP (Hearing Aid Profile,用于助聽器設備),BAP (Bluetooth Audio Profile,用于通用音頻設備),ACS (Audio Control Service,提供音頻控制功能(如音量調節、播放控制),基于 GATT/ATT 實現,通過暴露特性(Characteristics)供應用程序使用),ACAS (Audio Stream Control Service,提供音頻流管理功能(如流的創建、配置、刪除),基于 GATT/ATT 實現,與 Isochronous Channels(ISOC) 協作,實現低延遲音頻流傳輸),GATT (Generic Attribute Profile,定義基于 ATT 的服務和特性,用于數據傳輸,提供邏輯信道管理,支持客戶端-服務器模型),GAP (Generic Access Profile,定義設備角色 (如廣播者、觀察者、中心設備、外圍設備) 和連接流程,負責設備發現、連接建立和安全控制),FTP (File Transfer Profile,文件傳輸),OPP (Object Push Profile,對象推送 (如聯系人、圖片)),PAN (Personal Area Network Profile,個人局域網),HID (Human Interface Device Profile,人機接口設備 (如鍵盤、鼠標) 等。

  • 中間件層:提供高層協議和服務,支持應用層的功能實現。常見的中間件層協議有,SDP (Service Discovery Protocol,服務發現協議,用于查找設備支持的服務),RFCOMM (Radio Frequency Communication,串口仿真協議,用于模擬 RS-232 串口通信),OBEX (Object Exchange Protocol,對象交換協議,用于文件傳輸和數據同步),TCS (Telephony Control Protocol Specification,電話控制協議,用于語音通話),BNEP (Bluetooth Network Encapsulation Protocol,網絡封裝協議,用于藍牙網絡共享),AVDTP (Audio/Video Distribution Transport Protocol,音頻/視頻傳輸協議,負責音頻流的傳輸和控制,它定義了音頻流的建立、配置、啟動、暫停和停止等操作),AVCTP (Audio/Video Remote Control Profile,音頻/視頻遠程控制協議,藍牙協議棧中的控制傳輸協議,負責音頻/視頻控制命令的傳輸,它定義了控制命令的封裝和傳輸機制),ATT (Attribute Protocol,用于在 BLE 設備之間傳輸屬性數據,提供基于客戶端-服務器的數據訪問機制) 等。

  • HCI 層:提供主機和藍牙控制器之間的通信接口。負責傳輸命令、事件和數據。

  • L2CAP 層:提供多路復用、分段和重組功能,支持上層協議的數據傳輸。管理邏輯鏈路,提供可靠的數據傳輸服務。

  • 基帶層:管理物理鏈路,處理藍牙設備的連接和通信。負責頻率跳變、數據包格式化和錯誤檢測。常見的基帶層協議有 LMP (Link Manager Protocol,鏈路管理協議,負責設備之間的連接建立和維護),SCO (Synchronous Connection-Oriented link,同步面向連接鏈路,用于語音傳輸),ACL (Asynchronous Connectionless link,異步無連接鏈路,用于數據傳輸),ISOC (Isochronous Channels,提供同步數據傳輸通道,支持低延遲的音頻流傳輸)。

  • 射頻層:負責藍牙無線電信號的發送和接收。處理頻率跳變、調制和解調。使用藍牙無線電協議,主要工作在 2.4 GHz ISM 頻段。

藍牙協議棧相對于 TCP/IP 網絡協議棧,其各層之間并不是那么的各自獨立,而是緊密關聯的。藍牙協議棧中與音頻相關的有 4 個用于不同場景的子協議棧,它們分別是用于傳輸高質量音頻流的 A2DP,包括 A2DP -> AVDTP -> L2CAP -> ACL;用于通過藍牙遠程控制音頻/視頻設備的 AVRCP,包括 AVRCP -> AVCTP -> L2CAP -> ACLA2DPAVRCP 常協作實現藍牙音頻;用于語音通話的 HFP/HSP,包括 HFP/HSP -> SCO/eSCO;用于低功耗藍牙的 HAP/BAP,包括 HAP/BAP -> ACS/ACAS -> GATT -> ATT -> GAP -> ISOC。 除 HAP/BAP 協議棧外,其它的都是經典藍牙的協議棧。

類比于 TCP/IP 網絡協議棧中的 RTP/RTCP 協議,A2DP/AVDTP 協議類似于 RTP 協議,AVRCP/AVCTP 協議類似于 RTCP 協議,L2CAP/ACL 協議類似于 UDP 協議,只是它們是可靠傳輸協議。

在實現上,HCI 及更下層的協議無疑由 Linux 內核或硬件實現。應用層和中間件層協議的實現則常隨著時間的流逝而變化。低功耗藍牙是比較新的藍牙標準,對低功耗藍牙的支持是從 BlueZ 5.55 版本開始逐步添加的。對于 Linux 內核,則是從 Linux 5.13 版本開始,逐步支持 Isochronous Channels。

在早期的 BlueZ 版本中,PulseAudio 這樣的音頻服務需要將音頻流數據通過 Unix Domain Socket 發送給 BlueZ,再由 BlueZ 通過 A2DP 協議發送給藍牙硬件設備。從 BlueZ 5.0 開始,BlueZ 的音頻功能(如 A2DP)逐漸被移出 BlueZ 核心代碼庫,轉而由 PipeWire 或 PulseAudio 這樣的系統音頻服務器直接處理音頻流的傳輸。BlueZ 不再直接處理音頻流數據,而是通過 D-Bus 接口 與音頻后端(如 PipeWire 或 PulseAudio)交互。AVDTP 的實現由音頻后端負責,BlueZ 僅提供藍牙協議棧的核心功能(如設備管理、連接管理)。音頻后端負責音頻流的編碼、解碼和傳輸。音頻后端直接與藍牙硬件交互,處理音頻流數據。

藍牙控制器探測

BlueZ 是 Linux 官方藍牙協議棧,提供對藍牙無線通信標準的全面支持。核心協議方面,它支持 L2CAP(邏輯鏈路控制與適配協議),RFCOMM(串口仿真協議),SDP(服務發現協議),HCI(主機控制器接口)。配置文件方面,它支持 A2DP(高級音頻分發),AVRCP(音視頻遠程控制),HFP(免提協議),HID(人機接口設備),PAN(個人局域網)。硬件設備類型方面,它支持音頻設備,如藍牙耳機、音箱;輸入設備,如鍵盤、鼠標;網絡連接,如藍牙 PAN;物聯網,如智能家居設備。它還提供一系列與藍牙設備管理控制有關的工具程序,如 bluetoothd,藍牙守護進程,管理設備和服務;bluetoothctl,命令行工具,用于設備配對、連接等操作;hcitool,配置藍牙適配器及查詢設備信息;sdptool,瀏覽和發布 SDP 服務記錄。

BlueZ 整個項目的代碼豐富而復雜,這里主要關注與藍牙音頻有關的邏輯。

BlueZ 系統服務 bluetoothd 啟動時,執行 adapter_init() 函數初始化藍牙適配器,這個調用過程如下:

#0  adapter_init () at src/adapter.c:10337
#1  0x0000aaaaaaac3398 in main (argc=<optimized out>, argv=<optimized out>) at src/main.c:1216

adapter_init() 函數定義 (位于 src/adapter.c) 如下:

int adapter_init(void)
{dbus_conn = btd_get_dbus_connection();mgmt_primary = mgmt_new_default();if (!mgmt_primary) {error("Failed to access management interface");return -EIO;}if (getenv("MGMT_DEBUG"))mgmt_set_debug(mgmt_primary, mgmt_debug, "mgmt: ", NULL);DBG("sending read version command");if (mgmt_send(mgmt_primary, MGMT_OP_READ_VERSION,MGMT_INDEX_NONE, 0, NULL,read_version_complete, NULL, NULL) > 0)return 0;error("Failed to read management version information");return -EIO;
}

adapter_init() 函數訪問一下 DBus 連接,調用 mgmt_new_default() 函數創建并初始化 struct mgmt 對象,設置 struct mgmt 的調試配置,并調用 mgmt_send() 函數向 struct mgmt 發送一個讀取版本號的請求。

mgmt_new_default() 函數定義 (位于 src/shared/mgmt.c) 如下:

struct mgmt {int ref_count;int fd;bool close_on_unref;struct io *io;bool writer_active;struct queue *request_queue;struct queue *reply_queue;struct queue *pending_list;struct queue *notify_list;unsigned int next_request_id;unsigned int next_notify_id;bool need_notify_cleanup;bool in_notify;void *buf;uint16_t len;uint16_t mtu;mgmt_debug_func_t debug_callback;mgmt_destroy_func_t debug_destroy;void *debug_data;
};. . . . . .
static void mgmt_set_mtu(struct mgmt *mgmt)
{socklen_t len = 0;/* Check if kernel support BT_SNDMTU to read the current MTU set */if (getsockopt(mgmt->fd, SOL_BLUETOOTH, BT_SNDMTU, &mgmt->mtu,&len) < 0) {/* If BT_SNDMTU is not supported then MTU cannot be changed and* MTU is fixed to HCI_MAX_ACL_SIZE.*/mgmt->mtu = HCI_MAX_ACL_SIZE;return;}if (mgmt->mtu < UINT16_MAX) {uint16_t mtu = UINT16_MAX;/* Try increasing the MTU since some commands may go* over HCI_MAX_ACL_SIZE (1024)*/if (!setsockopt(mgmt->fd, SOL_BLUETOOTH, BT_SNDMTU, &mtu,sizeof(mtu)))mgmt->mtu = mtu;}
}struct mgmt *mgmt_new(int fd)
{struct mgmt *mgmt;if (fd < 0)return NULL;mgmt = new0(struct mgmt, 1);mgmt->fd = fd;mgmt->close_on_unref = false;mgmt->len = 512;mgmt->buf = malloc(mgmt->len);if (!mgmt->buf) {free(mgmt);return NULL;}mgmt->io = io_new(fd);if (!mgmt->io) {free(mgmt->buf);free(mgmt);return NULL;}mgmt->request_queue = queue_new();mgmt->reply_queue = queue_new();mgmt->pending_list = queue_new();mgmt->notify_list = queue_new();if (!io_set_read_handler(mgmt->io, can_read_data, mgmt, NULL)) {queue_destroy(mgmt->notify_list, NULL);queue_destroy(mgmt->pending_list, NULL);queue_destr

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/72532.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/72532.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/72532.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JetBrains(全家桶: IDEA、WebStorm、GoLand、PyCharm) 2024.3+ 2025 版免費體驗方案

JetBrains&#xff08;全家桶: IDEA、WebStorm、GoLand、PyCharm&#xff09; 2024.3 2025 版免費體驗方案 前言 JetBrains IDE 是許多開發者的主力工具&#xff0c;但從 2024.02 版本起&#xff0c;JetBrains 調整了試用政策&#xff0c;新用戶不再享有默認的 30 天免費試用…

1.8PageTable

頁表的作用 虛擬地址空間映射&#xff1a;頁表記錄了進程的虛擬頁號到物理頁號的映射關系。每個進程都有自己的頁表&#xff0c;操作系統為每個進程維護一個獨立的頁表。內存管理&#xff1a;頁表用于實現虛擬內存管理&#xff0c;支持進程的虛擬地址空間和物理地址空間之間的…

Prosys OPC UA Gateway:實現 OPC Classic 與 OPC UA 無縫連接

在工業自動化的數字化轉型中&#xff0c;設備與系統之間的高效通信至關重要。然而&#xff0c;許多企業仍依賴于基于 COM/DCOM 技術的 OPC 產品&#xff0c;這給與現代化的 OPC UA 架構的集成帶來了挑戰。 Prosys OPC UA Gateway 正是為解決這一問題而生&#xff0c;它作為一款…

數據結構------線性表

一、線性表順序存儲詳解 &#xff08;一&#xff09;線性表核心概念 1. 結構定義 // 數據元素類型 typedef struct person {char name[32];char sex;int age;int score; } DATATYPE;// 順序表結構 typedef struct list {DATATYPE *head; // 存儲空間基地址int tlen; …

【WPF】在System.Drawing.Rectangle中限制鼠標保持在Rectangle中移動?

方案一&#xff0c;在OnMouseMove方法限制 在WPF應用程序中&#xff0c;鼠標在移動過程中保持在這個矩形區域內&#xff0c;可以通過監聽鼠標的移動事件并根據鼠標的當前位置調整其坐標來實現。不過需要注意的是&#xff0c;WPF原生使用的是System.Windows.Rect而不是System.D…

基于銀河麒麟系統ARM架構安裝達夢數據庫并配置主從模式

達夢數據庫簡要概述 達夢數據庫&#xff08;DM Database&#xff09;是一款由武漢達夢公司開發的關系型數據庫管理系統&#xff0c;支持多種高可用性和數據同步方案。在主從模式&#xff08;也稱為 Master-Slave 或 Primary-Secondary 模式&#xff09;中&#xff0c;主要通過…

系統思考全球化落地

感謝加密貨幣公司Bybit的再次邀請&#xff0c;為全球團隊分享系統思考課程&#xff01;雖然大家來自不同國家&#xff0c;線上學習的形式依然讓大家充滿熱情與互動&#xff0c;思維的碰撞不斷激發新的靈感。 盡管時間存在挑戰&#xff0c;但我看到大家的討論異常積極&#xff…

Figma的漢化

Figma的漢化插件有客戶端版本與Chrome版本&#xff0c;大家可根據自己的需要進行選擇。 下載插件 進入Figma軟件漢化-Figma中文版下載-Figma中文社區使用客戶端&#xff1a;直接下載客戶端使用網頁版&#xff1a;安裝chrome瀏覽器漢化插件國外推薦前往chrome商店安裝國內推薦下…

【Go語言圣經2.5】

目標 了解類型定義不僅告訴編譯器如何在內存中存儲和處理數據&#xff0c;還對程序設計產生深遠影響&#xff1a; 內存結構&#xff1a;類型決定了變量的底層存儲&#xff08;比如占用多少字節、內存布局等&#xff09;。操作符與方法集&#xff1a;類型決定了哪些內置運算符…

IDEA 一鍵完成:打包 + 推送 + 部署docker鏡像

1、本方案要解決場景&#xff1f; 想直接通過本地 IDEA 將最新的代碼部署到遠程服務器上。 2、本方案適用于什么樣的項目&#xff1f; 項目是一個 Spring Boot 的 Java 項目。項目用 maven 進行管理。項目的運行基于 docker 容器&#xff08;即項目將被打成 docker image&am…

SpringBoot 第一課(Ⅲ) 配置類注解

目錄 一、PropertySource 二、ImportResource ①SpringConfig &#xff08;Spring框架全注解&#xff09; ②ImportResource注解實現 三、Bean 四、多配置文件 多Profile文件的使用 文件命名約定&#xff1a; 激活Profile&#xff1a; YAML文件支持多文檔塊&#xff…

深度解析React Native底層核心架構

React Native 工作原理深度解析 一、核心架構&#xff1a;三層異構協作體系 React Native 的跨平臺能力源于其獨特的 JS層-Shadow層-Native層 架構設計&#xff0c;三者在不同線程中協同工作&#xff1a; JS層 運行于JavaScriptCore&#xff08;iOS&#xff09;或Hermes&…

對話智能體的正確打開方式:解析主流AI聊天工具的核心能力與使用方式

一、人機對話的黃金法則 在與人工智能對話系統交互時&#xff0c;掌握以下七項核心原則可顯著提升溝通效率&#xff1a;文末有教程分享地址 意圖精準表達術 采用"背景需求限定條件"的結構化表達 示例優化&#xff1a;"請用Python編寫一個網絡爬蟲&#xff08…

Xinference大模型配置介紹并通過git-lfs、hf-mirror安裝

文章目錄 一、Xinference開機服務systemd二、語言&#xff08;LLM&#xff09;模型2.1 配置介紹2.2 DeepSeek-R1-Distill-Qwen-32B&#xff08;大杯&#xff09;工具下載git-lfs&#xff08;可以繞過Hugging Face&#xff09; 2.3 DeepSeek-R1-Distill-Qwen-32B-Q4_K_M-GGUF&am…

MyBatis操縱數據庫-XML實現(補充)

目錄 一.多表查詢二.MyBatis參數賦值(#{ }和${ })2.1 #{ }和${ }的使用2.2 #{ }和${ }的區別2.3 SQL注入2.3 ${ }的應用場景2.3.1 排序功能2.3.2 like查詢 一.多表查詢 多表查詢的操作和單表查詢基本相同&#xff0c;只需改變一下SQL語句&#xff0c;同時也要在實體類中創建出…

快速導出接口設計表——基于DOMParser的Swagger接口詳情半自動化提取方法

作者聲明&#xff1a;不想看作者聲明的&#xff08;需要生成接口設計表的&#xff09;直接前往https://capujin.github.io/A2T/。 注&#xff1a;Github Pages生成的頁面可能會出現訪問不穩定&#xff0c;暫時沒將源碼上傳至Github&#xff0c;如有需要&#xff0c;可聯系我私…

TS常見內置映射類型的實現及應用場景

以下是 TypeScript 在前端項目中 常用的映射類型&#xff08;Mapped Types&#xff09;&#xff0c;結合具體場景和代碼示例&#xff0c;幫助開發者高效處理復雜類型&#xff1a; 一、基礎映射類型 1. Partial<T> 作用&#xff1a;將對象類型 T 的所有屬性變為可選。 實…

介紹如何使用YOLOv8模型進行基于深度學習的吸煙行為檢測

下面為你詳細介紹如何使用YOLOv8模型進行基于深度學習的吸煙行為檢測&#xff0c;包含環境配置、數據準備、模型訓練以及推理等步驟。 1. 環境配置 首先&#xff0c;你需要安裝必要的庫&#xff0c;主要是ultralytics庫&#xff0c;它包含了YOLOv8模型。你可以使用以下命令進…

AI-醫學影像分割方法與流程

AI醫學影像分割方法與流程–基于低場磁共振影像的病灶識別 – 作者:coder_fang AI框架&#xff1a;PaddleSeg 數據準備&#xff0c;使用MedicalLabelMe進行dcm文件標注&#xff0c;產生同名.json文件。 編寫程序生成訓練集圖片&#xff0c;包括掩碼圖。 代碼如下: def doC…

【Python】09、字典

文章目錄 1. 字典簡介2. 字典的使用2.1 字典創建2.2 字典值獲取2.3 字典值修改2.4 字典的刪除 3. 字典的遍歷 1. 字典簡介 字典(dict)屬于一種新的數據結構&#xff0c;稱為映射(mapping)。 字典的作用和列表類似&#xff0c;但是查詢性能比列表好&#xff1b;在字典中每個元…