Skip to content

Commit

Permalink
Support composite devices more directly. (Closes #2.)
Browse files Browse the repository at this point in the history
  • Loading branch information
jwise committed Nov 16, 2012
1 parent 6341957 commit 4f85661
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 85 deletions.
19 changes: 17 additions & 2 deletions HoRNDIS-Info.plist
Expand Up @@ -26,12 +26,12 @@
<string>1.0.0d1</string> <string>1.0.0d1</string>
<key>IOKitPersonalities</key> <key>IOKitPersonalities</key>
<dict> <dict>
<key>HoRNDIS</key> <key>HoRNDISDevice</key>
<dict> <dict>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>com.joshuawise.kexts.HoRNDIS</string> <string>com.joshuawise.kexts.HoRNDIS</string>
<key>IOClass</key> <key>IOClass</key>
<string>HoRNDIS</string> <string>AppleUSBComposite</string>
<key>IOProviderClass</key> <key>IOProviderClass</key>
<string>IOUSBDevice</string> <string>IOUSBDevice</string>
<key>bDeviceClass</key> <key>bDeviceClass</key>
Expand All @@ -41,6 +41,21 @@
<key>bDeviceProtocol</key> <key>bDeviceProtocol</key>
<integer>0</integer> <integer>0</integer>
</dict> </dict>
<key>HoRNDISComposite</key>
<dict>
<key>CFBundleIdentifier</key>
<string>com.joshuawise.kexts.HoRNDIS</string>
<key>IOClass</key>
<string>HoRNDISUSBInterface</string>
<key>IOProviderClass</key>
<string>IOUSBInterface</string>
<key>bInterfaceClass</key>
<integer>224</integer>
<key>bInterfaceProtocol</key>
<integer>3</integer>
<key>bInterfaceSubClass</key>
<integer>1</integer>
</dict>
</dict> </dict>
<key>OSBundleLibraries</key> <key>OSBundleLibraries</key>
<dict> <dict>
Expand Down
99 changes: 17 additions & 82 deletions HoRNDIS.cpp
Expand Up @@ -39,6 +39,7 @@
#define super IOEthernetController #define super IOEthernetController


OSDefineMetaClassAndStructors(HoRNDIS, IOEthernetController); OSDefineMetaClassAndStructors(HoRNDIS, IOEthernetController);
OSDefineMetaClassAndStructors(HoRNDISUSBInterface, HoRNDIS);
OSDefineMetaClassAndStructors(HoRNDISInterface, IOEthernetInterface); OSDefineMetaClassAndStructors(HoRNDISInterface, IOEthernetInterface);


bool HoRNDIS::init(OSDictionary *properties) { bool HoRNDIS::init(OSDictionary *properties) {
Expand Down Expand Up @@ -70,38 +71,30 @@ bool HoRNDIS::init(OSDictionary *properties) {


/***** Driver setup and teardown language *****/ /***** Driver setup and teardown language *****/


bool HoRNDIS::start(IOService *provider) { bool HoRNDISUSBInterface::start(IOService *provider) {
int cfg; IOUSBInterface *intf;
int rc;

LOG(V_DEBUG, "starting up");
if(!super::start(provider))
return false;


fpDevice = OSDynamicCast(IOUSBDevice, provider); intf = OSDynamicCast(IOUSBInterface, provider);
if(!fpDevice) { if (!intf) {
stop(provider); LOG(V_ERROR, "cast to IOUSBInterface failed?");
return false; return false;
} }

fpDevice = intf->GetDevice();

return HoRNDIS::start(provider);
}

bool HoRNDIS::start(IOService *provider) {
LOG(V_DEBUG, "starting up");
if(!super::start(provider))
return false;


/* Take control of the device before configuring. */ if (!fpDevice) {
if (!fpDevice->open(this)) {
stop(provider); stop(provider);
return false; return false;
} }

/* Initialize and set the appropriate device configuration. */
cfg = probeConfigurations();
if (cfg < 0)
goto bailout;

rc = fpDevice->SetConfiguration(this, cfg);
if (rc != kIOReturnSuccess) {
LOG(V_ERROR, "SetConfiguration on RNDIS config failed?");
return false;;
}


/* Now do the rest of the work to actually bring it up... */
if (!openInterfaces()) if (!openInterfaces())
goto bailout; goto bailout;
if (!rndisInit()) if (!rndisInit())
Expand Down Expand Up @@ -142,11 +135,6 @@ void HoRNDIS::stop(IOService *provider) {
fDataInterface = NULL; fDataInterface = NULL;
} }


if (fpDevice) {
fpDevice->close(this);
fpDevice = NULL;
}

if (fMediumDict) { if (fMediumDict) {
fMediumDict->release(); fMediumDict->release();
fMediumDict = NULL; fMediumDict = NULL;
Expand All @@ -155,59 +143,6 @@ void HoRNDIS::stop(IOService *provider) {
super::stop(provider); super::stop(provider);
} }


/* Find and activate an RNDIS-looking interface. XXX: wish I could include that in configureDevice, below... */
int HoRNDIS::probeConfigurations() {
int i;
int ncfgs = fpDevice->GetNumConfigurations();

/* XXX: Should probe the string descriptors to make sure that they match with Linux's RNDIS gadget strings; binding to arbitrary RNDIS devices probably won't work. */

LOG(V_DEBUG, "%d possible configs", ncfgs);

for (i = 0; i < ncfgs; i++) {
IOUSBFindInterfaceRequest req;
const IOUSBConfigurationDescriptor *cd;
IOUSBInterfaceDescriptor *intf;
IOReturn ior;

LOG(V_DEBUG, "checking configuration %d", i);

cd = fpDevice->GetFullConfigurationDescriptor(i);
if (!cd) {
LOG(V_ERROR, "error retrieving configuration descriptor");
continue;
}

req.bInterfaceClass = 0xE0;
req.bInterfaceSubClass = 0x01;
req.bInterfaceProtocol = 0x03;
req.bAlternateSetting = kIOUSBFindInterfaceDontCare;
ior = fpDevice->FindNextInterfaceDescriptor(cd, NULL, &req, &intf);
if (ior != kIOReturnSuccess) {
LOG(V_DEBUG, "no control interface for configuration");
continue;
}

req.bInterfaceClass = 0x0A;
req.bInterfaceSubClass = 0x00;
req.bInterfaceProtocol = 0x00;
req.bAlternateSetting = kIOUSBFindInterfaceDontCare;
ior = fpDevice->FindNextInterfaceDescriptor(cd, intf, &req, &intf);
if (ior != kIOReturnSuccess) {
LOG(V_DEBUG, "no data interface for configuration");
continue;
}

LOG(V_DEBUG, "interface descriptor found");

/* Okay, we found it -- all set! */
return cd->bConfigurationValue;
}

LOG(V_ERROR, "no RNDIS configuration that I can drive");
return -1;
}

bool HoRNDIS::openInterfaces() { bool HoRNDIS::openInterfaces() {
IOUSBFindInterfaceRequest req; IOUSBFindInterfaceRequest req;
IOUSBFindEndpointRequest epReq; IOUSBFindEndpointRequest epReq;
Expand Down
8 changes: 7 additions & 1 deletion HoRNDIS.h
Expand Up @@ -271,7 +271,6 @@ class HoRNDIS : public IOEthernetController {
bool allocateResources(void); bool allocateResources(void);
void releaseResources(void); void releaseResources(void);
bool openInterfaces(); bool openInterfaces();
int probeConfigurations();
bool createNetworkInterface(void); bool createNetworkInterface(void);
UInt32 outputPacket(mbuf_t pkt, void *param); UInt32 outputPacket(mbuf_t pkt, void *param);
IOReturn clearPipeStall(IOUSBPipe *thePipe); IOReturn clearPipeStall(IOUSBPipe *thePipe);
Expand All @@ -298,6 +297,13 @@ class HoRNDIS : public IOEthernetController {
virtual IONetworkInterface *createInterface(); virtual IONetworkInterface *createInterface();
}; };


/* If there are other ways to get access to a device, we probably want them here. */
class HoRNDISUSBInterface : public HoRNDIS {
OSDeclareDefaultStructors(HoRNDISUSBInterface);
public:
virtual bool start(IOService *provider);
};

class HoRNDISInterface : public IOEthernetInterface { class HoRNDISInterface : public IOEthernetInterface {
OSDeclareDefaultStructors(HoRNDISInterface); OSDeclareDefaultStructors(HoRNDISInterface);
public: public:
Expand Down

0 comments on commit 4f85661

Please sign in to comment.