2

我正在做一个项目,我需要 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;
}
4

2 回答 2

1

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

于 2010-06-12T09:33:19.657 回答
-1

除了 appstore 规则之外,我认为你甚至不能在不违反 sdk 协议的情况下在 iOS 上触摸 iokit。

于 2013-01-20T08:08:06.907 回答