feat: A2DP bluetooth audio working

This commit is contained in:
2026-06-10 16:00:42 +02:00
parent 4eb4ba4073
commit e0c8787727
18 changed files with 1312 additions and 4340 deletions
+35 -5
View File
@@ -218,15 +218,32 @@ namespace Drivers::USB::Bluetooth {
// Set local name
Hci::WriteLocalName("MontaukOS");
// Set class of device: Audio (Major Service: Audio, Major Class: Audio/Video)
// CoD: 0x240404 = Rendering | Audio | Wearable Headset (common for audio devices)
// For a computer acting as audio source:
// 0x200408 = Audio service | Audio/Video class | Portable Audio
Hci::WriteClassOfDevice(0x200408);
// Class of Device. The A2DP spec MANDATES the Capturing service bit
// (0x080000) for a source; Audio (0x200000) is customary. Major/minor
// class: Computer/Laptop (0x010C) -- what we actually are. The old
// value 0x200408 (Audio/Video major class, minor "hands-free device",
// no Capturing bit) presented MontaukOS to the headset as ANOTHER
// HEADSET. A sink's connection manager classifies peers by CoD (it
// arrives in its Connection Request event and is cached at pairing),
// and an A2DP/AVRCP dial from a "hands-free unit" is a credible reason
// for it to park those channels at "authorization pending" forever.
// NOTE: the headset caches this from pairing -- it must FORGET the
// device and re-pair to observe the new class.
Hci::WriteClassOfDevice(0x28010C);
// Enable Simple Secure Pairing
Hci::WriteSSPMode(1);
// Allow role switch + sniff on new connections. The controller default
// link policy is 0x0000 (deny both). A multipoint headset (Bose QC
// Ultra) that also holds a link to a phone requests a role switch to
// master on our link to avoid a scatternet; with the switch denied,
// some sink firmwares never grant the A2DP media path. Sniff denial
// similarly upsets CSR-derived stacks that sniff idle links.
uint8_t linkPolicy[2] = {0x05, 0x00}; // bit0 role switch, bit2 sniff
Hci::SendCommand(Hci::OP_WRITE_DEFAULT_LP, linkPolicy, 2);
Hci::WaitCommandComplete(Hci::OP_WRITE_DEFAULT_LP);
// Set event mask to receive relevant events. Octet 6 (events 0x31-0x38)
// MUST be enabled for Secure Simple Pairing: IO Capability Request
// (0x31, bit 48), IO Capability Response (0x32), User Confirmation
@@ -261,6 +278,19 @@ namespace Drivers::USB::Bluetooth {
CompleteInit();
}
// =========================================================================
// ServiceEvents — steady-state event pump (idle loop)
// =========================================================================
void ServiceEvents() {
if (!g_initialized) return;
if (Xhci::InPollContext()) return; // never nest under PollEvents
Xhci::PollEvents();
Hci::DrainEvents();
Hci::ProcessPendingCommands();
A2dp::PumpMedia(); // feed queued media to the link (no-op when idle)
}
// =========================================================================
// Public queries
// =========================================================================