fix(bt): enforce USB transport matching and isolate Bluetooth driver dependencies
This commit is contained in:
1 parent
9423c21da0
commit
2656af7975
7 files changed
+59
-32
No files matched your search
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -37,23 +37,6 @@
|
|||||||
<key>IOProbeScore</key>
|
<key>IOProbeScore</key>
|
||||||
<integer>5000</integer>
|
<integer>5000</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>QualcommWireless_WiFi</key>
|
|
||||||
<dict>
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>com.nawrhehe.QualcommWireless</string>
|
|
||||||
<key>IOClass</key>
|
|
||||||
<string>QualcommWifi</string>
|
|
||||||
<key>IOMatchCategory</key>
|
|
||||||
<string>IODefaultMatchCategory</string>
|
|
||||||
<key>IONameMatch</key>
|
|
||||||
<string>pci17cb,1107</string>
|
|
||||||
<key>IOPCIPrimaryMatch</key>
|
|
||||||
<string>0x110717cb</string>
|
|
||||||
<key>IOProbeScore</key>
|
|
||||||
<integer>20000</integer>
|
|
||||||
<key>IOProviderClass</key>
|
|
||||||
<string>IOPCIDevice</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
</dict>
|
||||||
<key>OSBundleLibraries</key>
|
<key>OSBundleLibraries</key>
|
||||||
<dict>
|
<dict>
|
||||||
@@ -63,16 +46,10 @@
|
|||||||
<string>15.0</string>
|
<string>15.0</string>
|
||||||
<key>com.apple.kpi.mach</key>
|
<key>com.apple.kpi.mach</key>
|
||||||
<string>15.0</string>
|
<string>15.0</string>
|
||||||
<key>com.apple.iokit.IOUSBHostFamily</key>
|
|
||||||
<string>1.2</string>
|
|
||||||
<key>com.apple.iokit.IOPCIFamily</key>
|
|
||||||
<string>2.9</string>
|
|
||||||
<key>com.apple.iokit.IONetworkingFamily</key>
|
|
||||||
<string>3.2</string>
|
|
||||||
<key>com.apple.iokit.IO80211Family</key>
|
|
||||||
<string>1200.0</string>
|
|
||||||
<key>com.apple.kpi.bsd</key>
|
<key>com.apple.kpi.bsd</key>
|
||||||
<string>15.0</string>
|
<string>15.0</string>
|
||||||
|
<key>com.apple.iokit.IOUSBHostFamily</key>
|
||||||
|
<string>1.2</string>
|
||||||
</dict>
|
</dict>
|
||||||
<key>OSBundleRequired</key>
|
<key>OSBundleRequired</key>
|
||||||
<string>Root</string>
|
<string>Root</string>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "Firmware_WCN7850.h"
|
#include "Firmware_WCN7850.h"
|
||||||
|
|
||||||
#include <IOKit/IOLib.h>
|
#include <IOKit/IOLib.h>
|
||||||
|
#include <IOKit/IODeviceTreeSupport.h>
|
||||||
#include <libkern/OSByteOrder.h>
|
#include <libkern/OSByteOrder.h>
|
||||||
#include <IOKit/usb/IOUSBHostFamily.h>
|
#include <IOKit/usb/IOUSBHostFamily.h>
|
||||||
|
|
||||||
@@ -308,18 +309,31 @@ bool QualcommWireless::start(IOService *provider) {
|
|||||||
IOLog("QualcommWireless: Statut FINAL: 0x%02x (Patch: %s, Syscfg: %s) -> Pret pour macOS !\n",
|
IOLog("QualcommWireless: Statut FINAL: 0x%02x (Patch: %s, Syscfg: %s) -> Pret pour macOS !\n",
|
||||||
finalStatus, (finalStatus & 0x80) ? "OUI" : "NON", (finalStatus & 0x40) ? "OUI" : "NON");
|
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)
|
// 1. Configuration du transport et des propriétés USB pour bluetoothd (macOS Monterey à Sequoia)
|
||||||
// IMPORTANT: Ne JAMAIS nommer "Bluetooth USB Host Controller" sinon Found_USB_Dongle ignore le périphérique.
|
// 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 Product Name", "Qualcomm WCN7850 Bluetooth");
|
||||||
fDevice->setProperty("USB Vendor Name", "Qualcomm");
|
fDevice->setProperty("USB Vendor Name", "Qualcomm");
|
||||||
fDevice->setProperty("FirmwareLoaded", true);
|
fDevice->setProperty("FirmwareLoaded", true);
|
||||||
fDevice->setProperty("kUSBHostPortType", (uint32_t)255, 32);
|
fDevice->setProperty("kUSBHostPortType", (uint32_t)255, 32);
|
||||||
fDevice->setProperty("builtin", (uint32_t)1, 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
|
// Spoof idVendor à 0x0a12 (CSR) dans IORegistry pour validation native par Found_USB_Dongle
|
||||||
// blanche de dongles tiers et active le chipset générique THIRD_PARTY_DONGLE (HCI Transport: USB).
|
// de bluetoothd, évitant ainsi le rejet "Not Broadcom (0x0A5C) nor CSR (0x0A12)".
|
||||||
fDevice->setProperty("idVendor", (uint32_t)0x0a12, 32);
|
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
|
// 2. Propriétés sur le port parent
|
||||||
IOService *hubPort = fDevice->getProvider();
|
IOService *hubPort = fDevice->getProvider();
|
||||||
@@ -338,19 +352,21 @@ bool QualcommWireless::start(IOService *provider) {
|
|||||||
intf->setProperty("USB Product Name", "Qualcomm WCN7850 Bluetooth");
|
intf->setProperty("USB Product Name", "Qualcomm WCN7850 Bluetooth");
|
||||||
intf->setProperty("USB Vendor Name", "Qualcomm");
|
intf->setProperty("USB Vendor Name", "Qualcomm");
|
||||||
intf->setProperty("idVendor", (uint32_t)0x0a12, 32);
|
intf->setProperty("idVendor", (uint32_t)0x0a12, 32);
|
||||||
|
intf->setProperty("transport-encoding", (uint32_t)0, 32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
OSSafeReleaseNULL(intfIter);
|
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.
|
// 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
|
// Libération de l'accès exclusif afin que bluetoothd puisse ouvrir le contrôleur
|
||||||
fDevice->close(this);
|
fDevice->close(this);
|
||||||
|
|
||||||
registerService();
|
registerService();
|
||||||
|
IOLog("QualcommWireless: Service 'Bluetooth USB Host Controller' enregistre et pret pour bluetoothd.\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
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.
|
||||||
|
|
||||||
Reference in new issue
Block a user