尝试使用IOKit.framework在iphone上找到USB设备

时间:2010-06-12 04:16:32

标签: iphone iterator usb iokit

我正在开展项目,因为我需要USB端口与外部设备进行通信。我一直在网上寻找示例(Apple和/ developer / IOKit / usb示例)并尝试其他一些示例,但我甚至找不到该设备。

在我的代码中,我在函数查找下一个迭代器(实际上是指针)的地方阻塞了函数getNextIterator;但它永远不会返回一个好的值,所以代码是阻塞的。顺便说一句,我正在使用工具链并在我的项目中添加了IOKit.framework。我现在想要的只是与USB总线上的某人通信或做类似的ping操作!我在FindDevice阻止...我无法进入while循环,因为变量usbDevice始终= 0 ...我已经测试了我的代码一个小的mac程序,它的工作原理......

这是我的代码:

IOReturn ConfigureDevice(IOUSBDeviceInterface **dev)  {
    UInt8    numConfig;
    IOReturn    result;
    IOUSBConfigurationDescriptorPtr configDesc;

    //Get the number of configurations
    result = (*dev)->GetNumberOfConfigurations(dev, &numConfig);
    if (!numConfig) {
        return -1;
    }

    // Get the configuration descriptor
    result = (*dev)->GetConfigurationDescriptorPtr(dev, 0, &configDesc);
    if (result) {
        NSLog(@"Couldn't get configuration descriptior for index %d (err=%08x)\n", 0, result);
        return -1;
    }

#ifdef OSX_DEBUG
    NSLog(@"Number of Configurations: %d\n", numConfig);
#endif

    // Configure the device
    result = (*dev)->SetConfiguration(dev, configDesc->bConfigurationValue);
    if (result)
    {
        NSLog(@"Unable to set configuration to value %d (err=%08x)\n", 0, result);
        return -1;
    }

    return kIOReturnSuccess;
}

IOReturn FindInterfaces(IOUSBDeviceInterface **dev, IOUSBInterfaceInterface ***itf) {
    IOReturn     kr;
    IOUSBFindInterfaceRequest request;
    io_iterator_t    iterator;
    io_service_t    usbInterface;
    IOUSBInterfaceInterface  **intf = NULL;
    IOCFPlugInInterface   **plugInInterface = NULL; 
    HRESULT      res;
    SInt32      score;
    UInt8      intfClass;
    UInt8      intfSubClass;
    UInt8      intfNumEndpoints;
    int       pipeRef;
    CFRunLoopSourceRef   runLoopSource;

 NSLog(@"Debut FindInterfaces \n");

    request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
    request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
    request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
    request.bAlternateSetting = kIOUSBFindInterfaceDontCare;

    kr = (*dev)->CreateInterfaceIterator(dev, &request, &iterator);

    usbInterface = IOIteratorNext(iterator);
    IOObjectRelease(iterator);

  NSLog(@"Interface found.\n");

    kr = IOCreatePlugInInterfaceForService(usbInterface, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score);
    kr = IOObjectRelease(usbInterface); // done with the usbInterface object now that I have the plugin
    if ((kIOReturnSuccess != kr) || !plugInInterface)
    {
        NSLog(@"unable to create a plugin (%08x)\n", kr);
        return -1;
    }

    // I have the interface plugin. I need the interface interface
    res = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (LPVOID*) &intf);
    (*plugInInterface)->Release(plugInInterface);   // done with this
    if (res || !intf)
    {
        NSLog(@"couldn't create an IOUSBInterfaceInterface (%08x)\n", (int) res);
        return -1;
    }

    // Now open the interface. This will cause the pipes to be instantiated that are
    // associated with the endpoints defined in the interface descriptor.
    kr = (*intf)->USBInterfaceOpen(intf);
    if (kIOReturnSuccess != kr)
    {
        NSLog(@"unable to open interface (%08x)\n", kr);
        (void) (*intf)->Release(intf);
        return -1;
    }

    kr = (*intf)->CreateInterfaceAsyncEventSource(intf, &runLoopSource);
    if (kIOReturnSuccess != kr)
    {
        NSLog(@"unable to create async event source (%08x)\n", kr);
        (void) (*intf)->USBInterfaceClose(intf);
        (void) (*intf)->Release(intf);
        return -1;
    }
    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode);


    if (!intf) 
 {
        NSLog(@"Interface is NULL!\n");
    } else 
 {
        *itf = intf;
    }

 NSLog(@"End of FindInterface \n \n");
    return kr;
}


unsigned int FindDevice(void *refCon, io_iterator_t iterator)  {
    kern_return_t  kr;
    io_service_t  usbDevice;
    IOCFPlugInInterface  **plugInInterface = NULL;
    HRESULT   result;
    SInt32   score;
    UInt16   vendor;
    UInt16   product;
    UInt16   release;
    unsigned int   count = 0;


    NSLog(@"Searching Device....\n");

    while (usbDevice = IOIteratorNext(iterator)) 
 {
        // create intermediate plug-in

        NSLog(@"Found a device!\n");

        kr = IOCreatePlugInInterfaceForService(usbDevice,
                                               kIOUSBDeviceUserClientTypeID,
                                               kIOCFPlugInInterfaceID,
                                               &plugInInterface, &score);
        kr = IOObjectRelease(usbDevice);
        if ((kIOReturnSuccess != kr) || !plugInInterface) {
            NSLog(@"Unable to create a plug-in (%08x)\n", kr);
            continue;
        }
        // Now create the device interface
        result = (*plugInInterface)->QueryInterface(plugInInterface,
             CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
                                                    (LPVOID)&dev);
        // Don't need intermediate Plug-In Interface
        (*plugInInterface)->Release(plugInInterface);

        if (result || !dev) {
            NSLog(@"Couldn't create a device interface (%08x)\n",
                   (int)result);
            continue;
        }

        // check these values for confirmation
        kr = (*dev)->GetDeviceVendor(dev, &vendor);
        kr = (*dev)->GetDeviceProduct(dev, &product);
        //kr = (*dev)->GetDeviceReleaseNumber(dev, &release);
        //if ((vendor != LegoUSBVendorID) || (product != LegoUSBProductID) || (release != LegoUSBRelease)) {
  if ((vendor != LegoUSBVendorID) || (product != LegoUSBProductID))
  {
            NSLog(@"Found unwanted device (vendor = %d != %d, product = %d != %d, release = %d)\n",
                   vendor, kUSBVendorID, product, LegoUSBProductID, release);
            (void) (*dev)->Release(dev);
            continue;
        }

        // Open the device to change its state
        kr = (*dev)->USBDeviceOpen(dev);
        if (kr == kIOReturnSuccess) {
            count++;
        } else {
            NSLog(@"Unable to open device: %08x\n", kr);
            (void) (*dev)->Release(dev);
            continue;
        }
        // Configure device
        kr = ConfigureDevice(dev);
        if (kr != kIOReturnSuccess) {
            NSLog(@"Unable to configure device: %08x\n", kr);
            (void) (*dev)->USBDeviceClose(dev);
            (void) (*dev)->Release(dev);
            continue;
        }
        break;
    }

    return count;
}

// USB rcx Init
IOUSBInterfaceInterface** osx_usb_rcx_init (void) 
{
    CFMutableDictionaryRef     matchingDict;
    kern_return_t       result;
    IOUSBInterfaceInterface     **intf = NULL;
    unsigned int       device_count = 0;

    // Create master handler
    result = IOMasterPort(MACH_PORT_NULL, &gMasterPort);
  if (result || !gMasterPort) 
  {
   NSLog(@"ERR: Couldn't create master I/O Kit port(%08x)\n", result);
   return NULL;
  }
  else {
   NSLog(@"Created Master Port.\n");
   NSLog(@"Master port 0x:08X \n \n", gMasterPort);
  }

    // Set up the matching dictionary for class IOUSBDevice and its subclasses
    matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
  if (!matchingDict) {
   NSLog(@"Couldn't create a USB matching dictionary \n");
   mach_port_deallocate(mach_task_self(), gMasterPort);
   return NULL;
  }
  else {
   NSLog(@"USB matching dictionary : %08X \n", matchingDict);
  }

    CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID),
                         CFNumberCreate(kCFAllocatorDefault, kCFNumberShortType, &LegoUSBVendorID));
    CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID),
                         CFNumberCreate(kCFAllocatorDefault, kCFNumberShortType, &LegoUSBProductID));

    result = IOServiceGetMatchingServices(gMasterPort, matchingDict, &gRawAddedIter);
    matchingDict = 0;   // this was consumed by the above call

    // Iterate over matching devices to access already present devices
 NSLog(@"RawAddedIter : 0x:%08X \n", &gRawAddedIter);
    device_count = FindDevice(NULL, gRawAddedIter);

    if (device_count == 1) 
 {
        result = FindInterfaces(dev, &intf);
        if (kIOReturnSuccess != result) 
  {
            NSLog(@"unable to find interfaces on device: %08x\n", result);
            (*dev)->USBDeviceClose(dev);
            (*dev)->Release(dev);
            return NULL;
        }
//        osx_usb_rcx_wakeup(intf);
        return intf;
    } 
 else if (device_count > 1) 
  {
   NSLog(@"too many matching devices (%d) !\n", device_count);
  } 
  else 
  {
   NSLog(@"no matching devices found\n");
  }
    return NULL;
}




int main(int argc, char *argv[])
{
 int returnCode;
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

 NSLog(@"Debut du programme \n \n");

 osx_usb_rcx_init();


 NSLog(@"Fin du programme \n \n");
 return 0;


// returnCode = UIApplicationMain(argc, argv, @"Untitled1App", @"Untitled1App");
//    [pool release];
//    return returnCode;
}

2 个答案:

答案 0 :(得分:1)

IOKit不适用于iPhone应用程序。如果您需要通过iPhone连接外部设备,则需要注册MFi Program,这将为您提供所需的API和文档。

答案 1 :(得分:-1)

除了appstore规则,我不认为你甚至可以触摸iOS上的iokit而不违反sdk的协议。