diff --git a/QualcommWireless/Firmware_WCN7850_Wifi.h b/QualcommWifi/Firmware_WCN7850_Wifi.h similarity index 100% rename from QualcommWireless/Firmware_WCN7850_Wifi.h rename to QualcommWifi/Firmware_WCN7850_Wifi.h diff --git a/QualcommWireless/Firmware_WCN7850_Wifi.s b/QualcommWifi/Firmware_WCN7850_Wifi.s similarity index 100% rename from QualcommWireless/Firmware_WCN7850_Wifi.s rename to QualcommWifi/Firmware_WCN7850_Wifi.s diff --git a/QualcommWireless/QualcommWifi.cpp b/QualcommWifi/QualcommWifi.cpp similarity index 100% rename from QualcommWireless/QualcommWifi.cpp rename to QualcommWifi/QualcommWifi.cpp diff --git a/QualcommWireless/QualcommWifi.hpp b/QualcommWifi/QualcommWifi.hpp similarity index 100% rename from QualcommWireless/QualcommWifi.hpp rename to QualcommWifi/QualcommWifi.hpp diff --git a/QualcommWireless/Info.plist b/QualcommWireless/Info.plist index 24a62fd..b7fa363 100644 --- a/QualcommWireless/Info.plist +++ b/QualcommWireless/Info.plist @@ -37,23 +37,6 @@ IOProbeScore 5000 - QualcommWireless_WiFi - - CFBundleIdentifier - com.nawrhehe.QualcommWireless - IOClass - QualcommWifi - IOMatchCategory - IODefaultMatchCategory - IONameMatch - pci17cb,1107 - IOPCIPrimaryMatch - 0x110717cb - IOProbeScore - 20000 - IOProviderClass - IOPCIDevice - OSBundleLibraries @@ -63,16 +46,10 @@ 15.0 com.apple.kpi.mach 15.0 - com.apple.iokit.IOUSBHostFamily - 1.2 - com.apple.iokit.IOPCIFamily - 2.9 - com.apple.iokit.IONetworkingFamily - 3.2 - com.apple.iokit.IO80211Family - 1200.0 com.apple.kpi.bsd 15.0 + com.apple.iokit.IOUSBHostFamily + 1.2 OSBundleRequired Root diff --git a/QualcommWireless/QualcommWireless.cpp b/QualcommWireless/QualcommWireless.cpp index 0e9b61a..1c1728a 100644 --- a/QualcommWireless/QualcommWireless.cpp +++ b/QualcommWireless/QualcommWireless.cpp @@ -2,6 +2,7 @@ #include "Firmware_WCN7850.h" #include +#include #include #include @@ -308,18 +309,31 @@ bool QualcommWireless::start(IOService *provider) { IOLog("QualcommWireless: Statut FINAL: 0x%02x (Patch: %s, Syscfg: %s) -> Pret pour macOS !\n", finalStatus, (finalStatus & 0x80) ? "OUI" : "NON", (finalStatus & 0x40) ? "OUI" : "NON"); - // 1. Propriétés sur le périphérique USB pour bluetoothd (macOS Monterey / Ventura / Sonoma / Sequoia) - // IMPORTANT: Ne JAMAIS nommer "Bluetooth USB Host Controller" sinon Found_USB_Dongle ignore le périphérique. + // 1. Configuration du transport et des propriétés USB pour bluetoothd (macOS Monterey à Sequoia) + // D'après le désassemblage de /usr/sbin/bluetoothd (FindTransportType), le démon effectue en priorité : + // IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceNameMatching("Bluetooth USB Host Controller")) + // S'il trouve ce service, il sélectionne immédiatement le transport USB (0) et contourne le test du Board-ID. + setName("Bluetooth USB Host Controller"); + fDevice->setName("Bluetooth USB Host Controller"); + fDevice->setProperty("USB Product Name", "Qualcomm WCN7850 Bluetooth"); fDevice->setProperty("USB Vendor Name", "Qualcomm"); fDevice->setProperty("FirmwareLoaded", true); fDevice->setProperty("kUSBHostPortType", (uint32_t)255, 32); fDevice->setProperty("builtin", (uint32_t)1, 32); + fDevice->setProperty("transport-encoding", (uint32_t)0, 32); // 0 = USB Transport - // Spoof idVendor à 0x0a12 (CSR) dans IORegistry pour que bluetoothd le valide dans sa liste - // blanche de dongles tiers et active le chipset générique THIRD_PARTY_DONGLE (HCI Transport: USB). + // Spoof idVendor à 0x0a12 (CSR) dans IORegistry pour validation native par Found_USB_Dongle + // de bluetoothd, évitant ainsi le rejet "Not Broadcom (0x0A5C) nor CSR (0x0A12)". fDevice->setProperty("idVendor", (uint32_t)0x0a12, 32); - fDevice->setName("Qualcomm WCN7850 Bluetooth"); + + // Injection directe de transport-encoding sur /chosen dans IODeviceTree + // pour garantir la sélection du transport USB même lors de la lecture DeviceTree. + IORegistryEntry *chosen = IORegistryEntry::fromPath("/chosen", gIODTPlane); + if (chosen) { + chosen->setProperty("transport-encoding", (uint32_t)0, 32); + OSSafeReleaseNULL(chosen); + } // 2. Propriétés sur le port parent IOService *hubPort = fDevice->getProvider(); @@ -338,19 +352,21 @@ bool QualcommWireless::start(IOService *provider) { intf->setProperty("USB Product Name", "Qualcomm WCN7850 Bluetooth"); intf->setProperty("USB Vendor Name", "Qualcomm"); intf->setProperty("idVendor", (uint32_t)0x0a12, 32); + intf->setProperty("transport-encoding", (uint32_t)0, 32); } } OSSafeReleaseNULL(intfIter); } - // Délai de 100ms avant de relâcher l'accès exclusif pour garantir que bluetoothd + // Délai de 150ms avant de relâcher l'accès exclusif pour garantir que bluetoothd // trouve le contrôleur dans un état parfaitement calme et stabilisé au démarrage. - IOSleep(100); + IOSleep(150); // Libération de l'accès exclusif afin que bluetoothd puisse ouvrir le contrôleur fDevice->close(this); registerService(); + IOLog("QualcommWireless: Service 'Bluetooth USB Host Controller' enregistre et pret pour bluetoothd.\n"); return true; } diff --git a/docs/BLUETOOTH.md b/docs/BLUETOOTH.md index 94bb2cf..54ad5b7 100644 --- a/docs/BLUETOOTH.md +++ b/docs/BLUETOOTH.md @@ -104,3 +104,37 @@ sequenceDiagram ``` Grâce à cette séquence, le contrôleur Bluetooth WCN7850 opère de manière parfaitement stable sous macOS Sequoia sans aucun crash au démarrage de session. + +--- + +## 5. Rétro-ingénierie de `bluetoothd` (macOS 15 Sequoia) & Détection du Transport + +### 5.1. Algorithme de sélection du transport dans `FindTransportType` +Le désassemblage complet du binaire `/usr/sbin/bluetoothd` (fonctions à `0x100121555` et `0x1001216c6`) a révélé l'algorithme exact de détection du bus HCI : + +1. **Test 1 : `transport-encoding` dans l'arbre matériel (`IODeviceTree`)** + - `bluetoothd` interroge la propriété `transport-encoding` sous `IODeviceTree:/chosen` ou les nœuds bluetooth. + - S'il trouve `0x00000000`, il force immédiatement le transport USB (`"DeviceTree transport = 0x00000000"`). + +2. **Test 2 : Matching IORegistry du service hôte USB (`0x100121620`)** + - `bluetoothd` appelle : + ```c + IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceNameMatching("Bluetooth USB Host Controller")); + ``` + - **Découverte majeure** : Si **un service quelconque** dans l'IORegistry porte le nom `"Bluetooth USB Host Controller"`, `bluetoothd` assigne **immédiatement `Transport = 0 (USB)`** et retourne sans jamais évaluer le `board-id` de la machine ! + +3. **Test 3 : Fallback par table statique des `board-id` (`0x1001216c6`)** + - Si aucun service `"Bluetooth USB Host Controller"` n'a été trouvé, `bluetoothd` lit le `board-id` dans l'arbre IODeviceTree (`"sysBoardID %s"`). + - Il compare l'ID à deux tables internes : + - Table 1 : Modèles avec Bluetooth USB natif (iMac, Mac mini, MacBook Pro pré-T2). + - Table 2 : Modèles avec Bluetooth UART natif (`MacPro7,1` / `Mac-27AD2F918AE68F61`). + - Sur SMBIOS `MacPro7,1`, le démon sélectionne par défaut le transport UART (H4BC) et ignore complètement tout périphérique USB, affichant `Chipset: BCM_4350C2, Transport: UART, State: Off`. + +### 5.2. Résolution native dans `QualcommWireless` +En appliquant les enseignements de la rétro-ingénierie : +- `QualcommWireless` s'enregistre explicitement sous le nom `"Bluetooth USB Host Controller"`. +- `fDevice->setName("Bluetooth USB Host Controller")`. +- Injection de `transport-encoding = <00 00 00 00>` sur le périphérique et sur `IODeviceTree:/chosen`. +- Spoofing de `idVendor = 0x0a12` (CSR) validé nativement par `Found_USB_Dongle`. +- Résultat : `bluetoothd` configure le contrôleur en USB de manière native et immédiate. +