diff --git a/.github/README-zh_Hans.md b/.github/README-zh_Hans.md index 22068bf..b149a2e 100644 --- a/.github/README-zh_Hans.md +++ b/.github/README-zh_Hans.md @@ -5,6 +5,9 @@ - [English](/README.md) - **简体中文** +> [!IMPORTANT] +> 本分支中的 **LE Data Length Change 修复**——用于清除 bluetoothd 在 macOS Tahoe 上卡在 `LE_READY_WAIT_FOR_LENGTH` 的问题,使 BLE HID 设备得以绑定([#514](https://github.com/OpenIntelWireless/IntelBluetoothFirmware/issues/514))——由 **AI 助手 Claude 编写**。该修复按原样提供,不含任何担保;您需自行负责审查、测试,并自担风险使用。 + ## 简介 IntelBluetoothFirmware 是一个用于在 macOS 中启用原生蓝牙的固件上传驱动,固件的二进制文件来自 Linux。 diff --git a/IntelBTPatcher/IntelBTPatcher.cpp b/IntelBTPatcher/IntelBTPatcher.cpp index 79cce98..d2e4f72 100644 --- a/IntelBTPatcher/IntelBTPatcher.cpp +++ b/IntelBTPatcher/IntelBTPatcher.cpp @@ -4,7 +4,7 @@ // // Created by zxystd on 2021/2/8. // - +#define __ACIDANTHERA_MAC_SDK 2600 #include #include #include @@ -66,6 +66,7 @@ static KernelPatcher::KextInfo IntelBTPatcher_IOUsbHostInfo { KernelPatcher::KextInfo::Unloaded }; +void *CIntelBTPatcher::_hookPipeInstance = nullptr; bool CIntelBTPatcher::_randomAddressInit = false; bool CIntelBTPatcher::init() @@ -128,6 +129,46 @@ void CIntelBTPatcher::processKext(KernelPatcher &patcher, size_t index, mach_vm_ SYSLOG(DRV_NAME, "failed to resolve %s, error = %d", hostDeviceRequest.symbol, patcher.getError()); patcher.clearError(); } + + KernelPatcher::RouteRequest asyncIORequest { + "__ZN13IOUSBHostPipe2ioEP18IOMemoryDescriptorjP19IOUSBHostCompletionj", + newAsyncIO, + oldAsyncIO + }; + patcher.routeMultiple(index, &asyncIORequest, 1, address, size); + if (patcher.getError() == KernelPatcher::Error::NoError) { + SYSLOG(DRV_NAME, "routed %s", asyncIORequest.symbol); + } else { + SYSLOG(DRV_NAME, "failed to resolve %s, error = %d", asyncIORequest.symbol, patcher.getError()); + patcher.clearError(); + } + + // macOS 26.5+: third parameter became ConfigurationDescriptor (was SuperSpeedEndpointCompanionDescriptor) + KernelPatcher::RouteRequest initPipeConfigRequest { + "__ZN13IOUSBHostPipe28initWithDescriptorsAndOwnersEPKN11StandardUSB18EndpointDescriptorEPKNS0_23ConfigurationDescriptorEP22AppleUSBHostControllerP15IOUSBHostDeviceP18IOUSBHostInterfaceht", + newInitPipeConfig, + oldInitPipeConfig + }; + patcher.routeMultiple(index, &initPipeConfigRequest, 1, address, size); + if (patcher.getError() == KernelPatcher::Error::NoError) { + SYSLOG(DRV_NAME, "routed %s", initPipeConfigRequest.symbol); + } else { + SYSLOG(DRV_NAME, "failed to resolve %s, error = %d", initPipeConfigRequest.symbol, patcher.getError()); + patcher.clearError(); + } + + KernelPatcher::RouteRequest initPipeRequest { + "__ZN13IOUSBHostPipe28initWithDescriptorsAndOwnersEPKN11StandardUSB18EndpointDescriptorEPKNS0_37SuperSpeedEndpointCompanionDescriptorEP22AppleUSBHostControllerP15IOUSBHostDeviceP18IOUSBHostInterfaceht", + newInitPipe, + oldInitPipe + }; + patcher.routeMultiple(index, &initPipeRequest, 1, address, size); + if (patcher.getError() == KernelPatcher::Error::NoError) { + SYSLOG(DRV_NAME, "routed %s", initPipeRequest.symbol); + } else { + SYSLOG(DRV_NAME, "failed to resolve %s, error = %d", initPipeRequest.symbol, patcher.getError()); + patcher.clearError(); + } } } } @@ -153,11 +194,13 @@ StandardUSB::DeviceRequest randomAddressRequest; const uint8_t randomAddressHci[9] = {0x05, 0x20, 0x06, 0x94, 0x50, 0x64, 0xD0, 0x78, 0x6B}; IOBufferMemoryDescriptor *writeHCIDescriptor = nullptr; -#define MAX_HCI_BUF_LEN 255 -#define HCI_OP_RESET 0x0c03 -#define HCI_OP_LE_SET_SCAN_PARAM 0x200B -#define HCI_OP_LE_SET_SCAN_ENABLE 0x200C +#define MAX_HCI_BUF_LEN 255 +#define HCI_OP_RESET 0x0c03 +#define HCI_OP_LE_SET_SCAN_PARAM 0x200B +#define HCI_OP_LE_SET_SCAN_ENABLE 0x200C +#define HCI_OP_LE_READ_REMOTE_FEATURES 0x2016 +int remoteReadSCount = 0; IOReturn CIntelBTPatcher::newHostDeviceRequest(void *that, IOService *provider, StandardUSB::DeviceRequest &request, void *data, IOMemoryDescriptor *descriptor, unsigned int &length, IOUSBHostCompletion *completion, unsigned int timeout) { HciCommandHdr *hdr = nullptr; @@ -175,7 +218,7 @@ IOReturn CIntelBTPatcher::newHostDeviceRequest(void *that, IOService *provider, descriptor->complete(kIODirectionOut); } hdr = (HciCommandHdr *)hciBuf; - if (hdr->opcode == HCI_OP_LE_SET_SCAN_PARAM) { + if (hdr->opcode == HCI_OP_LE_SET_SCAN_PARAM && hdr->data[5] == 0x1) { if (!_randomAddressInit) { randomAddressRequest.bmRequestType = makeDeviceRequestbmRequestType(kRequestDirectionOut, kRequestTypeClass, kRequestRecipientInterface); randomAddressRequest.bRequest = 0xE0; @@ -184,18 +227,24 @@ IOReturn CIntelBTPatcher::newHostDeviceRequest(void *that, IOService *provider, randomAddressRequest.wLength = 9; length = 9; if (writeHCIDescriptor == nullptr) - writeHCIDescriptor = IOBufferMemoryDescriptor::withBytes(randomAddressHci, 9, kIODirectionOut); - writeHCIDescriptor->prepare(kIODirectionOut); + writeHCIDescriptor = IOBufferMemoryDescriptor::withBytes(randomAddressHci, 9, kIODirectionInOut); + writeHCIDescriptor->prepare(kIODirectionInOut); IOReturn ret = FunctionCast(newHostDeviceRequest, callbackIBTPatcher->oldHostDeviceRequest)(that, provider, randomAddressRequest, nullptr, writeHCIDescriptor, length, nullptr, timeout); - writeHCIDescriptor->complete(); + writeHCIDescriptor->complete(kIODirectionInOut); const char *randAddressDump = _hexDumpHCIData((uint8_t *)randomAddressHci, 9); if (randAddressDump) { - SYSLOG(DRV_NAME, "[PATCH] Sending Random Address HCI %lld %s", ret, randAddressDump); + SYSLOG(DRV_NAME, "[PATCH] Sending Random Address HCI %d %s", ret, randAddressDump); IOFree((void *)randAddressDump, 9 * 3 + 1); } _randomAddressInit = true; - SYSLOG(DRV_NAME, "[PATCH] Resend LE SCAN PARAM HCI %lld", ret); + SYSLOG(DRV_NAME, "[PATCH] Resend LE SCAN PARAM HCI %d", ret); } + } else if (hdr->opcode == HCI_OP_LE_READ_REMOTE_FEATURES) { + // #514: send TWO extra reads -> two duplicate 0x04 events to rewrite + // (1st dup -> fake PHY Update Complete, 2nd dup -> fake LE Data Length Change). + remoteReadSCount += 2; + FunctionCast(newHostDeviceRequest, callbackIBTPatcher->oldHostDeviceRequest)(that, provider, request, nullptr, descriptor, length, nullptr, timeout); + FunctionCast(newHostDeviceRequest, callbackIBTPatcher->oldHostDeviceRequest)(that, provider, request, nullptr, descriptor, length, nullptr, timeout); } } else { hdr = (HciCommandHdr *)data; @@ -218,3 +267,102 @@ IOReturn CIntelBTPatcher::newHostDeviceRequest(void *that, IOService *provider, } return FunctionCast(newHostDeviceRequest, callbackIBTPatcher->oldHostDeviceRequest)(that, provider, request, data, descriptor, length, completion, timeout); } + +#define HCI_EVT_LE_META 0x3E +#define HCI_EVT_LE_META_READ_REMOTE_FEATURES_COMPLETE 0x04 + +uint8_t fakePhyUpdateCompleteEvent[8] = {0x3E, 0x06, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x02}; +// #514: LE Data Length Change (LE Meta subevent 0x07, no status byte -> handle at [3][4]). +// bluetoothd stalls at LE_READY_WAIT_FOR_LENGTH after PHY until it sees this. 27 octets / 328us tx+rx. +// Made by Claude. +uint8_t fakeDataLengthChangeEvent[13] = {0x3E, 0x0B, 0x07, 0x00, 0x00, 0x1B, 0x00, 0x48, 0x01, 0x1B, 0x00, 0x48, 0x01}; +//uint8_t remoteFeaturesStatus[6] = {0x0F, 0x04, 0x00, 0x01, 0x16, 0x20}; + +static void asyncIOCompletion(void* owner, void* parameter, IOReturn status, uint32_t bytesTransferred) +{ + AsyncOwnerData *asyncOwner = (AsyncOwnerData *)owner; + IOMemoryDescriptor* dataBuffer = asyncOwner->dataBuffer; + // #514 3-stage rewrite of the repeated LE Read Remote Features Complete (0x04) events: + // stage 0 = the real one (pass through), 1 = rewrite to fake PHY Update Complete, + // 2 = rewrite to fake LE Data Length Change (clears bluetoothd's LE_READY_WAIT_FOR_LENGTH). + static int leMetaStage = 0; + uint32_t allocLen = bytesTransferred; + + if (dataBuffer && bytesTransferred) { + void *buffer = IOMalloc(allocLen); + if (buffer) { + if (dataBuffer->getLength() > 0 && (getKernelVersion() < KernelVersion::Sequoia || !dataBuffer->prepare(kIODirectionInOut))) { + dataBuffer->readBytes(0, buffer, allocLen); + HciEventHdr *hdr = (HciEventHdr *)buffer; + if (hdr->evt == HCI_EVT_LE_META && hdr->data[0] == HCI_EVT_LE_META_READ_REMOTE_FEATURES_COMPLETE) { + if (leMetaStage == 0) { + leMetaStage = 1; // real features complete -> pass through + } else if (leMetaStage == 1) { // 1st duplicate -> fake PHY Update Complete + fakePhyUpdateCompleteEvent[4] = hdr->data[2]; + fakePhyUpdateCompleteEvent[5] = hdr->data[3]; + dataBuffer->writeBytes(0, fakePhyUpdateCompleteEvent, 8); + bytesTransferred = 8; + leMetaStage = 2; + remoteReadSCount--; + } else { // 2nd duplicate -> fake LE Data Length Change + fakeDataLengthChangeEvent[3] = hdr->data[2]; + fakeDataLengthChangeEvent[4] = hdr->data[3]; + dataBuffer->writeBytes(0, fakeDataLengthChangeEvent, 13); + bytesTransferred = 13; + leMetaStage = 0; + remoteReadSCount--; + } + } + if (getKernelVersion() >= KernelVersion::Sequoia) dataBuffer->complete(kIODirectionInOut); + } + IOFree(buffer, allocLen); + } + } + if (asyncOwner->action) + asyncOwner->action(asyncOwner->owner, parameter, status, bytesTransferred); + delete asyncOwner; +} + +IOReturn CIntelBTPatcher:: +newAsyncIO(void *that, IOMemoryDescriptor* dataBuffer, uint32_t bytesTransferred, IOUSBHostCompletion* completion, uint32_t completionTimeoutMs) +{ + if (remoteReadSCount > 0 && that == _hookPipeInstance && completion) { + AsyncOwnerData *ownerData = new AsyncOwnerData; + ownerData->action = completion->action; + ownerData->owner = completion->owner; + ownerData->dataBuffer = dataBuffer; + completion->action = asyncIOCompletion; + completion->owner = ownerData; + } + return FunctionCast(newAsyncIO, callbackIBTPatcher->oldAsyncIO)(that, dataBuffer, bytesTransferred, completion, completionTimeoutMs); +} + +#define VENDOR_USB_INTEL 0x8087 + +void CIntelBTPatcher::captureIntelInterruptPipe(void *that, StandardUSB::EndpointDescriptor const *descriptor, IOUSBHostDevice *device) +{ + if (!device) + return; + const StandardUSB::DeviceDescriptor *deviceDescriptor = device->getDeviceDescriptor(); + if (deviceDescriptor && deviceDescriptor->idVendor == VENDOR_USB_INTEL) { + uint8_t epType = StandardUSB::getEndpointType(descriptor); + if (epType == kIOUSBEndpointTypeInterrupt) + CIntelBTPatcher::_hookPipeInstance = that; + } +} + +int CIntelBTPatcher:: +newInitPipe(void *that, StandardUSB::EndpointDescriptor const *descriptor, StandardUSB::SuperSpeedEndpointCompanionDescriptor const *superDescriptor, AppleUSBHostController *controller, IOUSBHostDevice *device, IOUSBHostInterface *interface, unsigned char a7, unsigned short a8) +{ + int ret = FunctionCast(newInitPipe, callbackIBTPatcher->oldInitPipe)(that, descriptor, superDescriptor, controller, device, interface, a7, a8); + captureIntelInterruptPipe(that, descriptor, device); + return ret; +} + +int CIntelBTPatcher:: +newInitPipeConfig(void *that, StandardUSB::EndpointDescriptor const *descriptor, StandardUSB::ConfigurationDescriptor const *configDescriptor, AppleUSBHostController *controller, IOUSBHostDevice *device, IOUSBHostInterface *interface, unsigned char a7, unsigned short a8) +{ + int ret = FunctionCast(newInitPipeConfig, callbackIBTPatcher->oldInitPipeConfig)(that, descriptor, configDescriptor, controller, device, interface, a7, a8); + captureIntelInterruptPipe(that, descriptor, device); + return ret; +} diff --git a/IntelBTPatcher/IntelBTPatcher.hpp b/IntelBTPatcher/IntelBTPatcher.hpp index 0e5f7b3..80d18af 100644 --- a/IntelBTPatcher/IntelBTPatcher.hpp +++ b/IntelBTPatcher/IntelBTPatcher.hpp @@ -33,15 +33,8 @@ typedef struct __attribute__((packed)) { uint8_t evt; uint8_t len; -} HciEventHdr; - -typedef struct __attribute__((packed)) -{ - HciEventHdr evt; - uint8_t numCommands; - uint16_t opcode; uint8_t data[]; -} HciResponse; +} HciEventHdr; const char *requestDirectionNames[] = { "OUT", @@ -82,12 +75,21 @@ class CIntelBTPatcher { static IOReturn newFindQueueRequest(void *that, unsigned short arg1, void *addr, unsigned short arg2, bool arg3, void **hciRequestPtr); static IOReturn newHostDeviceRequest(void *that, IOService *provider, StandardUSB::DeviceRequest &request, void *data, IOMemoryDescriptor *descriptor, unsigned int &length,IOUSBHostCompletion *completion, unsigned int timeout); + static IOReturn newAsyncIO(void *that, IOMemoryDescriptor* dataBuffer, uint32_t dataBufferLength, IOUSBHostCompletion* completion, uint32_t completionTimeoutMs); + static int newInitPipe(void *that, StandardUSB::EndpointDescriptor const *descriptor, StandardUSB::SuperSpeedEndpointCompanionDescriptor const *superDescriptor,AppleUSBHostController *controller, IOUSBHostDevice *device, IOUSBHostInterface *interface, unsigned char, unsigned short); + static int newInitPipeConfig(void *that, StandardUSB::EndpointDescriptor const *descriptor, StandardUSB::ConfigurationDescriptor const *configDescriptor, AppleUSBHostController *controller, IOUSBHostDevice *device, IOUSBHostInterface *interface, unsigned char, unsigned short); mach_vm_address_t oldFindQueueRequest {}; mach_vm_address_t oldHostDeviceRequest {}; + mach_vm_address_t oldAsyncIO {}; + mach_vm_address_t oldInitPipe {}; + mach_vm_address_t oldInitPipeConfig {}; private: + static void captureIntelInterruptPipe(void *that, StandardUSB::EndpointDescriptor const *descriptor, IOUSBHostDevice *device); + static void *_hookPipeInstance; + static AsyncOwnerData *_interruptPipeAsyncOwner; static bool _randomAddressInit; }; diff --git a/IntelBluetoothFirmware.xcodeproj/project.pbxproj b/IntelBluetoothFirmware.xcodeproj/project.pbxproj index 989e4e3..39a6bbe 100644 --- a/IntelBluetoothFirmware.xcodeproj/project.pbxproj +++ b/IntelBluetoothFirmware.xcodeproj/project.pbxproj @@ -669,7 +669,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.12; - MODULE_VERSION = 2.5.0; + MODULE_VERSION = 2.5.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; SDKROOT = macosx; @@ -725,7 +725,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.12; - MODULE_VERSION = 2.5.0; + MODULE_VERSION = 2.5.2; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = macosx; diff --git a/IntelBluetoothFirmware/IntelBluetoothOpsGen1.cpp b/IntelBluetoothFirmware/IntelBluetoothOpsGen1.cpp index e7213c3..702b8b9 100644 --- a/IntelBluetoothFirmware/IntelBluetoothOpsGen1.cpp +++ b/IntelBluetoothFirmware/IntelBluetoothOpsGen1.cpp @@ -240,7 +240,7 @@ patching(OSData *fwData, const uint8_t **fw_ptr, bool *disablePatch) * the firmware file is corrupted and it should stop the patching * process. */ - if (remain > HCI_COMMAND_HDR_SIZE && *fw_ptr[0] != 0x01) { + if (remain < HCI_COMMAND_HDR_SIZE || *fw_ptr[0] != 0x01) { XYLog("Intel fw corrupted: invalid cmd read\n"); return false; } diff --git a/IntelBluetoothFirmware/fw/ibt-0040-0041.ddc b/IntelBluetoothFirmware/fw/ibt-0040-0041.ddc index 5acedc5..6e06779 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-0040-0041.ddc and b/IntelBluetoothFirmware/fw/ibt-0040-0041.ddc differ diff --git a/IntelBluetoothFirmware/fw/ibt-0040-0041.sfi b/IntelBluetoothFirmware/fw/ibt-0040-0041.sfi index 934b7e0..6de49e1 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-0040-0041.sfi and b/IntelBluetoothFirmware/fw/ibt-0040-0041.sfi differ diff --git a/IntelBluetoothFirmware/fw/ibt-0040-1020.sfi b/IntelBluetoothFirmware/fw/ibt-0040-1020.sfi index 1b6ab60..107147b 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-0040-1020.sfi and b/IntelBluetoothFirmware/fw/ibt-0040-1020.sfi differ diff --git a/IntelBluetoothFirmware/fw/ibt-0041-0041.sfi b/IntelBluetoothFirmware/fw/ibt-0041-0041.sfi index 652645c..b12c987 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-0041-0041.sfi and b/IntelBluetoothFirmware/fw/ibt-0041-0041.sfi differ diff --git a/IntelBluetoothFirmware/fw/ibt-0180-0041.sfi b/IntelBluetoothFirmware/fw/ibt-0180-0041.sfi index a6b4eee..b51b2d8 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-0180-0041.sfi and b/IntelBluetoothFirmware/fw/ibt-0180-0041.sfi differ diff --git a/IntelBluetoothFirmware/fw/ibt-0180-1050.sfi b/IntelBluetoothFirmware/fw/ibt-0180-1050.sfi index b4a13ec..b51b2d8 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-0180-1050.sfi and b/IntelBluetoothFirmware/fw/ibt-0180-1050.sfi differ diff --git a/IntelBluetoothFirmware/fw/ibt-0180-4150.sfi b/IntelBluetoothFirmware/fw/ibt-0180-4150.sfi index b57c854..b51b2d8 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-0180-4150.sfi and b/IntelBluetoothFirmware/fw/ibt-0180-4150.sfi differ diff --git a/IntelBluetoothFirmware/fw/ibt-0291-0291.ddc b/IntelBluetoothFirmware/fw/ibt-0291-0291.ddc index e9dd562..354146a 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-0291-0291.ddc and b/IntelBluetoothFirmware/fw/ibt-0291-0291.ddc differ diff --git a/IntelBluetoothFirmware/fw/ibt-0291-0291.sfi b/IntelBluetoothFirmware/fw/ibt-0291-0291.sfi index 9d47347..f170c23 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-0291-0291.sfi and b/IntelBluetoothFirmware/fw/ibt-0291-0291.sfi differ diff --git a/IntelBluetoothFirmware/fw/ibt-1040-0041.sfi b/IntelBluetoothFirmware/fw/ibt-1040-0041.sfi index 2312426..6de49e1 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-1040-0041.sfi and b/IntelBluetoothFirmware/fw/ibt-1040-0041.sfi differ diff --git a/IntelBluetoothFirmware/fw/ibt-1040-1020.sfi b/IntelBluetoothFirmware/fw/ibt-1040-1020.sfi index c39a8f1..107147b 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-1040-1020.sfi and b/IntelBluetoothFirmware/fw/ibt-1040-1020.sfi differ diff --git a/IntelBluetoothFirmware/fw/ibt-11-5.sfi b/IntelBluetoothFirmware/fw/ibt-11-5.sfi index 7fb37f1..93c0fc5 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-11-5.sfi and b/IntelBluetoothFirmware/fw/ibt-11-5.sfi differ diff --git a/IntelBluetoothFirmware/fw/ibt-12-16.sfi b/IntelBluetoothFirmware/fw/ibt-12-16.sfi index 1611ea4..267d5b7 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-12-16.sfi and b/IntelBluetoothFirmware/fw/ibt-12-16.sfi differ diff --git a/IntelBluetoothFirmware/fw/ibt-17-16-1.ddc b/IntelBluetoothFirmware/fw/ibt-17-16-1.ddc index f24bb17..6e06779 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-17-16-1.ddc and b/IntelBluetoothFirmware/fw/ibt-17-16-1.ddc differ diff --git a/IntelBluetoothFirmware/fw/ibt-17-16-1.sfi b/IntelBluetoothFirmware/fw/ibt-17-16-1.sfi index 833719b..56ffa13 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-17-16-1.sfi and b/IntelBluetoothFirmware/fw/ibt-17-16-1.sfi differ diff --git a/IntelBluetoothFirmware/fw/ibt-18-16-1.ddc b/IntelBluetoothFirmware/fw/ibt-18-16-1.ddc index f24bb17..6e06779 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-18-16-1.ddc and b/IntelBluetoothFirmware/fw/ibt-18-16-1.ddc differ diff --git a/IntelBluetoothFirmware/fw/ibt-18-16-1.sfi b/IntelBluetoothFirmware/fw/ibt-18-16-1.sfi index 833719b..56ffa13 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-18-16-1.sfi and b/IntelBluetoothFirmware/fw/ibt-18-16-1.sfi differ diff --git a/IntelBluetoothFirmware/fw/ibt-19-0-4.ddc b/IntelBluetoothFirmware/fw/ibt-19-0-4.ddc index 089b791..6e06779 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-19-0-4.ddc and b/IntelBluetoothFirmware/fw/ibt-19-0-4.ddc differ diff --git a/IntelBluetoothFirmware/fw/ibt-19-0-4.sfi b/IntelBluetoothFirmware/fw/ibt-19-0-4.sfi index 8f39866..bab09d2 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-19-0-4.sfi and b/IntelBluetoothFirmware/fw/ibt-19-0-4.sfi differ diff --git a/IntelBluetoothFirmware/fw/ibt-20-0-3.ddc b/IntelBluetoothFirmware/fw/ibt-20-0-3.ddc index 089b791..6e06779 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-20-0-3.ddc and b/IntelBluetoothFirmware/fw/ibt-20-0-3.ddc differ diff --git a/IntelBluetoothFirmware/fw/ibt-20-0-3.sfi b/IntelBluetoothFirmware/fw/ibt-20-0-3.sfi index 8f39866..8aae6a7 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-20-0-3.sfi and b/IntelBluetoothFirmware/fw/ibt-20-0-3.sfi differ diff --git a/IntelBluetoothFirmware/fw/ibt-20-1-3.ddc b/IntelBluetoothFirmware/fw/ibt-20-1-3.ddc index 089b791..6e06779 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-20-1-3.ddc and b/IntelBluetoothFirmware/fw/ibt-20-1-3.ddc differ diff --git a/IntelBluetoothFirmware/fw/ibt-20-1-3.sfi b/IntelBluetoothFirmware/fw/ibt-20-1-3.sfi index 8f39866..8aae6a7 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-20-1-3.sfi and b/IntelBluetoothFirmware/fw/ibt-20-1-3.sfi differ diff --git a/IntelBluetoothFirmware/fw/ibt-20-1-4.ddc b/IntelBluetoothFirmware/fw/ibt-20-1-4.ddc index 089b791..6e06779 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-20-1-4.ddc and b/IntelBluetoothFirmware/fw/ibt-20-1-4.ddc differ diff --git a/IntelBluetoothFirmware/fw/ibt-20-1-4.sfi b/IntelBluetoothFirmware/fw/ibt-20-1-4.sfi index 8f39866..3e86f63 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-20-1-4.sfi and b/IntelBluetoothFirmware/fw/ibt-20-1-4.sfi differ diff --git a/IntelBluetoothFirmware/fw/ibt-hw-37.8.10-fw-22.50.19.14.f.bseq b/IntelBluetoothFirmware/fw/ibt-hw-37.8.10-fw-22.50.19.14.f.bseq index 263296c..3b1831e 100644 Binary files a/IntelBluetoothFirmware/fw/ibt-hw-37.8.10-fw-22.50.19.14.f.bseq and b/IntelBluetoothFirmware/fw/ibt-hw-37.8.10-fw-22.50.19.14.f.bseq differ diff --git a/README.md b/README.md index b821391..0357fdc 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,9 @@ - **English** - [简体中文](/.github/README-zh_Hans.md) +> [!IMPORTANT] +> The **LE Data Length Change fix** in this fork — which clears bluetoothd's `LE_READY_WAIT_FOR_LENGTH` stall so BLE HID devices bind on macOS Tahoe ([#514](https://github.com/OpenIntelWireless/IntelBluetoothFirmware/issues/514)) — was **written by Claude, an AI assistant**. It is provided as-is, with no warranty: you are responsible for reviewing, testing, and using it at your own risk. + ## Intro IntelBluetoothFirmware is a Kernel Extension that uploads Intel Wireless Bluetooth Firmware to provide native Bluetooth in macOS.