feat: Intel BT firmware download, A2dp & Bluetooth audio progress
This commit is contained in:
@@ -30,6 +30,8 @@ namespace Drivers::USB::Bluetooth::Hci {
|
||||
constexpr uint16_t OP_DISCONNECT = 0x0406;
|
||||
constexpr uint16_t OP_ACCEPT_CONN_REQ = 0x0409;
|
||||
constexpr uint16_t OP_REJECT_CONN_REQ = 0x040A;
|
||||
constexpr uint16_t OP_LINK_KEY_REQ_REPLY = 0x040B;
|
||||
constexpr uint16_t OP_LINK_KEY_REQ_NEG_REPLY = 0x040C;
|
||||
constexpr uint16_t OP_AUTH_REQUESTED = 0x0411;
|
||||
constexpr uint16_t OP_SET_CONN_ENCRYPT = 0x0413;
|
||||
constexpr uint16_t OP_IO_CAPABILITY_REPLY = 0x042B;
|
||||
@@ -63,6 +65,8 @@ namespace Drivers::USB::Bluetooth::Hci {
|
||||
constexpr uint16_t OP_INTEL_RESET = 0xFC01;
|
||||
constexpr uint16_t OP_INTEL_SET_EVENT_MASK = 0xFC52;
|
||||
constexpr uint16_t OP_INTEL_DDC_CONFIG_WRITE = 0xFC8B;
|
||||
constexpr uint16_t OP_INTEL_SECURE_SEND = 0xFC09;
|
||||
constexpr uint16_t OP_INTEL_WRITE_BD_ADDR = 0xFC31; // set adapter BD_ADDR
|
||||
|
||||
// =========================================================================
|
||||
// HCI event codes
|
||||
@@ -75,6 +79,8 @@ namespace Drivers::USB::Bluetooth::Hci {
|
||||
constexpr uint8_t EVT_DISCONNECTION_COMPLETE = 0x05;
|
||||
constexpr uint8_t EVT_AUTH_COMPLETE = 0x06;
|
||||
constexpr uint8_t EVT_ENCRYPT_CHANGE = 0x08;
|
||||
constexpr uint8_t EVT_LINK_KEY_REQUEST = 0x17;
|
||||
constexpr uint8_t EVT_LINK_KEY_NOTIFICATION = 0x18;
|
||||
constexpr uint8_t EVT_COMMAND_COMPLETE = 0x0E;
|
||||
constexpr uint8_t EVT_COMMAND_STATUS = 0x0F;
|
||||
constexpr uint8_t EVT_NUM_COMPLETED_PACKETS = 0x13;
|
||||
@@ -163,7 +169,10 @@ namespace Drivers::USB::Bluetooth::Hci {
|
||||
// Initialize HCI transport over USB for the given slot
|
||||
void Initialize(uint8_t slotId);
|
||||
|
||||
// Start receiving HCI events and ACL data (call after HCI init sequence)
|
||||
// Start receiving HCI events and ACL data (call after HCI init sequence).
|
||||
// Arms both the interrupt IN and the bulk IN; the bulk IN must stay armed
|
||||
// through the firmware download (it absorbs the device's ~635 KB cc=4 glitch
|
||||
// and keeps the event pipe alive -- see the definition).
|
||||
void StartEventPipe();
|
||||
|
||||
// Send an HCI command via USB control transfer (EP0)
|
||||
@@ -212,6 +221,53 @@ namespace Drivers::USB::Bluetooth::Hci {
|
||||
// Read Intel-specific version info
|
||||
bool ReadIntelVersion(IntelVersion* ver);
|
||||
|
||||
// =========================================================================
|
||||
// Intel firmware download primitives (bootloader mode)
|
||||
// =========================================================================
|
||||
|
||||
// Read the Intel version response in TLV format (0xFC05 with parameter
|
||||
// 0xFF). Copies the raw return parameters (byte 0 = status, followed by
|
||||
// the TLV stream) into outBuf, bounded by the number of bytes actually
|
||||
// received from the controller. Returns that length, or -1 on failure.
|
||||
int ReadIntelVersionTlv(uint8_t* outBuf, int maxLen);
|
||||
|
||||
// Intel "Secure Send" (0xFC09): pushes one logical fragment to the
|
||||
// bootloader, split into <=252-byte chunks each prefixed with the
|
||||
// fragment type (0x00 CSS init, 0x01 firmware data, 0x02 signature,
|
||||
// 0x03 public key). The bootloader does not Command-Complete these; pacing
|
||||
// is by USB transfer completion and the result arrives asynchronously as a
|
||||
// 0xFF/0x06 secure-send result event (see WaitSecureSendResult).
|
||||
bool IntelSecureSend(uint8_t fragmentType, const uint8_t* data, uint32_t len);
|
||||
|
||||
// Reset / await the Intel "secure send result" vendor event (0xFF/0x06).
|
||||
// Call ClearSecureSendResult() before a download phase, then
|
||||
// WaitSecureSendResult() to read the outcome (result/status, 0 = success).
|
||||
void ClearSecureSendResult();
|
||||
bool WaitSecureSendResult(uint32_t timeoutMs, uint8_t* outResult, uint8_t* outStatus);
|
||||
|
||||
// Bonded-device link key persistence (so pairings survive reboots).
|
||||
// LoadLinkKeys(): read the on-disk store once VFS is up.
|
||||
// FlushLinkKeys(): write the store to disk if it changed -- call from
|
||||
// process context (NOT an event handler), since it does blocking disk I/O.
|
||||
void LoadLinkKeys();
|
||||
void FlushLinkKeys();
|
||||
|
||||
// Non-blocking peek at the most recent 0xFF/0x06 secure-send result without
|
||||
// consuming it. Returns true if one has arrived since the last
|
||||
// ClearSecureSendResult(). The payload loop uses this to catch a mid-stream
|
||||
// rejection -- a healthy bootloader stays silent until the final fragment.
|
||||
bool PeekSecureSendResult(uint8_t* outResult, uint8_t* outStatus);
|
||||
|
||||
// Reset the controller into operational firmware at bootAddr (0xFC01) and
|
||||
// wait for the Intel "bootup" vendor event. Returns true once booted.
|
||||
bool IntelBootFirmware(uint32_t bootAddr, uint32_t timeoutMs = 5000);
|
||||
|
||||
// Apply one DDC parameter record (record[0] = payload length) via 0xFC8B.
|
||||
bool IntelWriteDdcRecord(const uint8_t* record, uint8_t recordLen);
|
||||
|
||||
// Configure the Intel vendor event mask (0xFC52).
|
||||
bool IntelSetEventMask();
|
||||
|
||||
// Set local name
|
||||
bool WriteLocalName(const char* name);
|
||||
|
||||
@@ -227,6 +283,33 @@ namespace Drivers::USB::Bluetooth::Hci {
|
||||
// Accept an incoming connection
|
||||
bool AcceptConnection(const uint8_t* bdAddr, uint8_t role);
|
||||
|
||||
// Request authentication on an ACL link (we are the connection initiator).
|
||||
// Drives Link Key Request -> pairing; needed for bonded-device reconnects.
|
||||
bool AuthenticateLink(uint16_t handle);
|
||||
|
||||
// Set the adapter's BD_ADDR (Intel vendor command 0xFC31). Used to dodge a
|
||||
// remote that holds a stale, un-clearable bond to our real address.
|
||||
bool SetBdAddr(const uint8_t* addr);
|
||||
|
||||
// Lockless HCI-event trace (diagnostic). Reset before a connection attempt,
|
||||
// dump afterwards from top-level to see the pairing/SSP event sequence.
|
||||
void ResetEventTrace();
|
||||
void DumpEventTrace();
|
||||
|
||||
// Send any queued pairing replies (IO-cap / user-confirm / link-key) with
|
||||
// real confirmed transfers. Call from top-level (e.g. the connect loop),
|
||||
// NOT from an event handler -- event handlers only enqueue.
|
||||
void ProcessPendingCommands();
|
||||
|
||||
// Diagnostic: print ACL data-path counters (tx / txDone / rx / pending).
|
||||
void DumpAclStats();
|
||||
|
||||
// ACL TX flow control: outstanding (un-acked) ACL packets, and the
|
||||
// controller's ACL buffer count (Number-Of-Completed-Packets credits). The
|
||||
// media writer throttles on these so it never overruns the controller.
|
||||
uint16_t AclPendingCount();
|
||||
uint16_t AclMaxPackets();
|
||||
|
||||
// Disconnect a connection
|
||||
bool Disconnect(uint16_t handle, uint8_t reason);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user