views:

313

answers:

2

Hi all, i'm working on a project were i need the usb port to communicate with a external device. I have been looking for exemple on the net (Apple and /developer/IOKit/usb exemple) and trying some other but i can't even find the device. In my code i blocking at the place where the fucntion looks for a next iterator (pointer in fact) with the function getNextIterator but 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 what right now is the communicate or do like a ping to someone on the USB bus!! I blocking in the 'FindDevice'....i can't manage to enter in the while because the variable usbDevice is always = to 0....i have tested my code in a small mac program and it works...

Thanks

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

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.

Claus Broch
A: 

maybe you should try on a jailbroken ipad with the camera connector. Anyone tried?

Regards

Alain