/* * Bluetooth.hpp * Top-level Bluetooth subsystem header * Copyright (c) 2026 Daniel Hammer */ #pragma once #include #include "Hci.hpp" namespace Drivers::USB::Bluetooth { // Called by USB enumeration when a Bluetooth adapter is detected void RegisterAdapter(uint8_t slotId); // Complete any firmware-dependent bring-up that was deferred because the // adapter enumerated during the boot port scan, before the ramdisk (which // holds the firmware images) was mounted. Safe to call unconditionally // once the boot filesystems are up; a no-op if nothing is pending. void ServiceDeferredInit(); // Steady-state event service: drains the xHCI event ring + Bluetooth ACL // RX ring and flushes queued HCI replies. Called from the idle loop so // inbound traffic (the headset's SDP/AVRCP queries, AVDTP commands, ACL // credits) is processed even when no syscall happens to be pumping a BT // wait loop. Cheap no-op when the adapter is down; safe from any core // (PollEvents/DrainEvents/ProcessPendingCommands all self-serialize). void ServiceEvents(); // True when boot-deferred initialization or queued HCI control work needs // an idle-context service pass. USB receive events are signaled separately // by xHCI and cause the dispatcher to service Bluetooth in the same pass. bool HasDeferredWork(); // Query adapter state bool IsInitialized(); uint8_t GetSlotId(); // Get Bluetooth device address (6 bytes) const uint8_t* GetBdAddr(); // Change the adapter's BD_ADDR at runtime. Drops any active links (their // pairing/crypto was bound to the old address), issues the Intel vendor // write (0xFC31), re-reads the controller's address into the cache and // re-asserts scan. Returns true only if the controller reports the new // address. Persisting the choice to 0:/config/bluetooth.toml is the // caller's job (userspace); the override is re-applied on boot by // ApplyConfiguredAddress() during init. Bytes are in the same order as // GetBdAddr()/ReadBdAddr (addr[0] = least-significant octet). bool SetAddress(const uint8_t* addr); // Scan for nearby devices (blocking, up to timeoutMs) // Returns number of devices found; results written to buf int Scan(Hci::InquiryDevice* buf, int maxCount, uint32_t timeoutMs); // Initiate connection to a remote device by BD_ADDR // Returns 0 when ACL + A2DP are ready, -1 when the ACL connection failed, // or -2 when ACL connected but A2DP setup did not complete. int Connect(const uint8_t* bdAddr, uint32_t timeoutMs = 10000); // Disconnect a device by BD_ADDR // Returns 0 on success, -1 if not connected int Disconnect(const uint8_t* bdAddr); // List connected devices // Returns number of connected devices; info written to buf int ListConnected(Hci::ConnectionInfo* buf, int maxCount); // List bonded (paired) devices from the persisted link-key store. // Returns number written to buf (paired devices may be disconnected). int ListBonded(Hci::BondInfo* buf, int maxCount); // Forget a paired device: drop the link if connected and remove the bond // (so it must re-pair next time). Returns 0 on success, -1 if not bonded. int ForgetDevice(const uint8_t* bdAddr); }