尝试使用 IOKit.framework 在 iPhone 上查找 USB 设备

发布于 2024-09-05 18:14:24 字数 9371 浏览 4 评论 0原文

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

I'm working on a project were I need the USB port to communicate with an external device. I have been looking for examples on the net (Apple and /developer/IOKit/usb exemple) and trying some others, but I can't even find the device.

In my code, I'm blocking at the place where the function looks for a next iterator (pointer in fact) with the function getNextIterator; but it never returns a good value, so the code is blocking. By the way, I am using toolchain and added IOKit.framework in my project. All I want right now is to communicate or do like a ping to someone on the USB bus! I'm blocking in FindDevice... I can't manage to enter in the while loop because the variable usbDevice is always = to 0... I have tested my code in a small mac program and it works...

Here is my code :

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

空城旧梦 2024-09-12 18:14:24

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

IOKit is not available for iPhone applications. If you need to connect with external devices from the iPhone you need to sign up for the MFi Program which will provide you with the needed API's and documentation.

美煞众生 2024-09-12 18:14:24

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

besides the appstore rules i dont think u can even touch iokit on iOS without violating the sdk's agreement.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文