从应用程序级别的xcode中获取usb设备的序列号

时间:2014-09-08 22:35:48

标签: xcode macos usb

我刚开始从事硬件编程,并一直试图从USB设备获取序列号。我正在应用程序级而不是内核级实现所有内容。

我已经有一个与usb设备匹配的词典,所以我知道我有正确的设备。我不确定的是我收到的数据以及如何解释它以及我是否正确地解决了这个问题。

所以这里有一些代码,我一直试图从设备中获取序列号。

IOReturn retSerialIndex;
UInt8 snsi;
retSerialIndex = (*usbDevice)->USBGetSerialNumberStringIndex(usbDevice, &snsi);
if (retSerialIndex != kIOReturnSuccess)
{
    printf("Could not get serial number string index (error: %x)\n", retSerialIndex);
}
printf("Serial string index is %x\n", retSerialIndex);
IOReturn retSerial;
IOUSBConfigurationDescriptorPtr *desc;
if (retSerialIndex)
{
    retSerial = (*usbDevice)->GetConfigurationDescriptorPtr(usbDevice,
                                                            retSerialIndex,
                                                            desc);
    if (retSerial != kIOReturnSuccess)
    {
        printf("Could not get serial number using string index (error: %x)\n", retSerial);
    }
}
printf("Serial number is %x\n", retSerial);
char serialString;
serialString = getUSBStringDescriptor(usbDevice, retSerial);
printf("Serial string is %c\n", serialString);

这是我的getUSBStringDescriptor实现:

char MyClass::getUSBStringDescriptor( IOUSBDeviceInterface300** usbDevice, int idx )
{
   assert( usbDevice );
   UInt32 buffer[32];
   IOUSBDevRequest request;
   request.bmRequestType = USBmakebmRequestType(
                                             kUSBIn,
                                             kUSBStandard,
                                             kUSBDevice );
   request.bRequest = kUSBRqGetDescriptor;
   request.wValue = (3 << 8) | idx;
   request.wIndex = 0x0904; // english
   request.wLength = sizeof( buffer );
   request.pData = buffer;
   kern_return_t err = (*usbDevice)->DeviceRequest( usbDevice, &request );
   if ( err != 0 )
   {
       // the request failed.
       return NULL;
   }
   static char charstring[33];
   int count = ( request.wLenDone - 1 ) / 2;
   int i;
   for ( i = 0; i < count; i++ )
        charstring[i] = buffer[i+1];
    charstring[i] = '\0';
    return charstring[33 - 1];
}

非常感谢任何帮助。谢谢!

1 个答案:

答案 0 :(得分:4)

所以我明白了。我在错误的地方收到了错误的信息,没有充分注意价值的存储位置。以下是修改后的代码,它返回所选设备的序列号。

//My call to get serial number
NSString * serialString;
serialString = getUSBStringDescriptor(usbDevice);
printf("Serial string is %s\n", [serialString UTF8String]);

//My function that gets the serial number for me
NSString * MyUSBClass::getUSBStringDescriptor( IOUSBDeviceInterface300** usbDevice)
{
    UInt8 snsi;
    UInt8 buffer[256];
    IOUSBDevRequest request;
    IOReturn err;
    err = (*usbDevice)->USBGetSerialNumberStringIndex(usbDevice, &snsi);
    if (err != kIOReturnSuccess)
    {
        printf("Could not get serial number string index (error: %x)\n", err);
        return 0;
    }
    request.bmRequestType = USBmakebmRequestType(
                                             kUSBIn,
                                             kUSBStandard,
                                             kUSBDevice );
    request.bRequest = kUSBRqGetDescriptor;
    request.wValue = (kUSBStringDesc << 8) | snsi;
    request.wIndex = 0x409; // english
    request.wLength = sizeof( buffer );
    request.pData = &buffer[0];
    bzero(&buffer[0], sizeof(buffer));
    err = (*usbDevice)->DeviceRequest( usbDevice, &request );
    if ( err != kIOReturnSuccess )
    {
        printf("Could not get serial number string using index\n");
        // the request failed.
        return 0;
    }
    int strLength;
    CFStringRef serialNumberString;
    strLength = buffer[0] -2;
    serialNumberString = CFStringCreateWithBytes(kCFAllocatorDefault, &buffer[2], strLength, kCFStringEncodingUTF16LE, FALSE);
    CFShow(serialNumberString);
    NSString *stringBuffer = (__bridge NSString *)serialNumberString;
    return stringBuffer;
}

我希望这能节省很多时间!我希望在我开始尝试解决这个问题时得到这个答案。