2010-06-12 76 views
1

我正在一个项目上工作,我需要USB端口与外部设备进行通信。我一直在网上寻找例子(Apple和/ developer/IOKit/usb exemple)并尝试其他一些,但我甚至找不到该设备。试图找到与IOKit.framework iphone上的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; 
} 
+1

你不能在AppStore上使用IOKit - 你是否在为AppStore编写应用程序? – kennytm 2010-06-12 06:03:16

回答

1

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

+0

克劳斯 - 有趣的看到你堆栈溢出... – nielsbot 2012-08-22 18:12:26

+0

很高兴再次“看到”你Niels;) – 2012-08-22 21:20:53

-1

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