I'm wondering if there is a way to use a USB Modem (of Huawei E1550 species) on OS X in a generic manner, like a generic USB modem. The problem is that the OS won't recognise it as a legitimate CDC ACM device (which it is, but it doesn't advertise being such).
On Linux, the dongle is automatically recognised as a USB serial device.
There are reasons I don't want neither ZTE nor Huawei vendor drivers on any of my machines: these folks write stuff that barely works (my last experience with ZTE drivers involved spamming my logs, hogging the RAM, and me being unable to disable that), their drivers are not forward-compatible, they neglect to sync them with newer OS version, and they generally intend to distribute those drivers with carrier bloatware.
Apple's developer documentation writes in a vague way that a codeless kext can be written to force a specific driver on a matching device, or prevent a generic driver to load for a matching device. In fact, most searches on codeless kexts yield questions like "how do I prevent my serial dongle to be recognised as a modem?", while what I want is totally opposite!
My tries at writing such a codeless kext so far ended in a fiasco — kextutil tells the kext is loaded successfully, however it's not there, and so is AppleCDCACM.kext (which has the IOClass I want to use).
JFYI, the lsusb information as gathered from Linux:
Bus 004 Device 005: ID 12d1:1001 Huawei Technologies Co., Ltd. E169/E620/E800 HSDPA Modem Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x12d1 Huawei Technologies Co., Ltd. idProduct 0x1001 E169/E620/E800 HSDPA Modem bcdDevice 0.00 iManufacturer 2 HUAWEI Technology iProduct 1 HUAWEI Mobile iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 85 bNumInterfaces 3 bConfigurationValue 1 iConfiguration 3 Qualcomm Configuration bmAttributes 0xe0 Self Powered Remote Wakeup MaxPower 500mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 3 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 255 Vendor Specific Subclass bInterfaceProtocol 255 Vendor Specific Protocol iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 5 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 32 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x01 EP 1 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 32 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 255 Vendor Specific Subclass bInterfaceProtocol 255 Vendor Specific Protocol iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 32 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 32 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 255 Vendor Specific Subclass bInterfaceProtocol 255 Vendor Specific Protocol iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 32 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x03 EP 3 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 32 Device Qualifier (for other device speed): bLength 10 bDescriptorType 6 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 bNumConfigurations 1 can't get debug descriptor: Resource temporarily unavailable Device Status: 0x0001 Self Powered
The interface I want to hook up is interface 0 (modem).
Here's how ioreg
sees it:
| | | | | +-o HUAWEI Mobile@1d110000 | | | | | +-o AppleUSBHostLegacyClient | | | | | +-o AppleUSBHostCompositeDevice | | | | | +-o IOUSBHostInterface@0 | | | | | | { | | | | | | "USBPortType" = 0 | | | | | | "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"} | | | | | | "bcdDevice" = 0 | | | | | | "USBSpeed" = 3 | | | | | | "idProduct" = 4097 | | | | | | "bConfigurationValue" = 1 | | | | | | "bInterfaceSubClass" = 255 | | | | | | "locationID" = 487653376 | | | | | | "IOGeneralInterest" = "IOCommand is not serializable" | | | | | | "IOClassNameOverride" = "IOUSBInterface" | | | | | | "AppleUSBAlternateServiceRegistryID" = 4294969542 | | | | | | "idVendor" = 4817 | | | | | | "bInterfaceProtocol" = 255 | | | | | | "bAlternateSetting" = 0 | | | | | | "bInterfaceNumber" = 0 | | | | | | "bInterfaceClass" = 255 | | | | | | } | | | | | | | | | | | +-o IOUSBHostInterface@1 | | | | | | { | | | | | | "USBPortType" = 0 | | | | | | "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"} | | | | | | "bcdDevice" = 0 | | | | | | "USBSpeed" = 3 | | | | | | "idProduct" = 4097 | | | | | | "bConfigurationValue" = 1 | | | | | | "bInterfaceSubClass" = 255 | | | | | | "locationID" = 487653376 | | | | | | "IOGeneralInterest" = "IOCommand is not serializable" | | | | | | "IOClassNameOverride" = "IOUSBInterface" | | | | | | "AppleUSBAlternateServiceRegistryID" = 4294969544 | | | | | | "idVendor" = 4817 | | | | | | "bInterfaceProtocol" = 255 | | | | | | "bAlternateSetting" = 0 | | | | | | "bInterfaceNumber" = 1 | | | | | | "bInterfaceClass" = 255 | | | | | | } | | | | | | | | | | | +-o IOUSBHostInterface@2 | | | | | { | | | | | "USBPortType" = 0 | | | | | "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"} | | | | | "bcdDevice" = 0 | | | | | "USBSpeed" = 3 | | | | | "idProduct" = 4097 | | | | | "bConfigurationValue" = 1 | | | | | "bInterfaceSubClass" = 255 | | | | | "locationID" = 487653376 | | | | | "IOGeneralInterest" = "IOCommand is not serializable" | | | | | "IOClassNameOverride" = "IOUSBInterface" | | | | | "AppleUSBAlternateServiceRegistryID" = 4294969546 | | | | | "idVendor" = 4817 | | | | | "bInterfaceProtocol" = 255 | | | | | "bAlternateSetting" = 0 | | | | | "bInterfaceNumber" = 2 | | | | | "bInterfaceClass" = 255 | | | | | } | | | | |
So far, the Info.plist looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>15C27b</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>name.fedevych.GenericWWAN</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>GenericWWAN</string>
<key>CFBundlePackageType</key>
<string>KEXT</string>
<key>CFBundleShortVersionString</key>
<string>99.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>99.0.0</string>
<key>IOKitPersonalities</key>
<dict>
<key>HUAWEI_0x12d11001_Control</key>
<dict>
<key>CFBundleIdentifier</key>
<string>com.apple.driver.usb.cdc.acm</string>
<key>IOClass</key>
<string>AppleUSBACMControl</string>
<key>IOProviderClass</key>
<string>IOUSBHostInterface</string>
<key>idVendor</key>
<integer>4817</integer>
<key>idProduct</key>
<integer>4097</integer>
<key>bcdDevice</key>
<integer>0</integer>
<key>bInterfaceNumber</key>
<integer>0</integer>
<key>bConfigurationValue</key>
<integer>1</integer>
<key>IOMatchCategory</key>
<string>com.apple.driver.AppleUSBACMControl</string>
</dict>
<key>HUAWEI_0x12d11001_Data</key>
<dict>
<key>CFBundleIdentifier</key>
<string>com.apple.driver.usb.cdc.acm</string>
<key>IOClass</key>
<string>AppleUSBACMData</string>
<key>IOProviderClass</key>
<string>IOUSBHostInterface</string>
<key>idVendor</key>
<integer>4817</integer>
<key>idProduct</key>
<integer>4097</integer>
<key>bcdDevice</key>
<integer>0</integer>
<key>bInterfaceNumber</key>
<integer>0</integer>
<key>bConfigurationValue</key>
<integer>1</integer>
</dict>
</dict>
<key>OSBundleLibraries</key>
<dict/>
</dict>
</plist>
Any pointers?