获取usb设备的pid, vid, locationid.
大家知道usb设备都有pid,vid,locationid,当USB设备连接电脑时,如果设备名字重新插拔后变化,那么无法获取,就得重新配置信息,然后进行通信。为此写了个程序来获取locationid,pid,vid 每个设备都有唯一的标识,所以具体情况如下:
- 编辑环境xcode8.3以上
- 调用的库文件IOKit.framework
- 语言object-c
打开xcode,新建工程文件名checkusb.
添加IOkit.framework文件。
新建usb.h,usb.mm用来编写获取的vid,pid的方法模块
在xib 布局界面;
然后编辑如下代码:
usb.h
#ifndef Global_USB_h
#define Global_USB_h
UInt32 GetUsbLocation(long vid,long pid);
int CheckUsbDevice(long vid,long pid);
long HexToLong(const char *stringValue);
const char *ToHex(uint16_t tmpid);
int CheckUsbDeviceInPort(long vid,long pid,int port);
char* GetUsbSerialNumber(long vid,long pid);
char *GetUsbVersion(long vid,long pid);
unsigned int CheckUSBHID(unsigned short vendor_id, unsigned short product_id,unsigned int locationid,int itimeout);
void ScanUSB(void *refCon, io_iterator_t iterator);
NSMutableArray* GetUSBDeviceListByDeviceName(NSString *devName);
#endif
usb.mm 部分代码
//
// loopdelegate.h
// checkUsb
//
// Created by Young on 11/30/17.
// Copyright © 2017 com.HY. All rights reserved.
//
#include <iostream>
#include <IOKit/IOKitLib.h>
#include <IOKit/IOMessage.h>
#include <IOKit/IOCFPlugIn.h>
#include <IOKit/usb/IOUSBLib.h>
#import <Cocoa/Cocoa.h>
#define kMyVendorID 0x9011 //0x0424//1351
#define kMyProductID 0x2514 //0x2514//8193
#define FT4232_VID 0x0403
#define FT4232_PID 0x6011
#define TG_CMD_BUFFER_LEN 64
BOOL bScanAllDevice = TRUE;
typedef struct MyPrivateData {
io_object_t notification;
IOUSBDeviceInterface **deviceInterface;
CFStringRef deviceName;
UInt32 locationID;
} MyPrivateData;
static IONotificationPortRef gNotifyPort;
static io_iterator_t gAddedIter;
#define kDeviceName @"device_name"
#define kLocationID @"location_id"
struct Context {
BOOL bScanAlldevice;
NSMutableArray * arrDevList;
};
//================================================================================================
//
// DeviceNotification
//
// This routine will get called whenever any kIOGeneralInterest notification happens. We are
// interested in the kIOMessageServiceIsTerminated message so that's what we look for. Other
// messages are defined in IOMessage.h.
//
//================================================================================================
void DeviceNotification(void *refCon, io_service_t service, natural_t messageType, void *messageArgument)
{
kern_return_t kr;
MyPrivateData *privateDataRef = (MyPrivateData *) refCon;
if (messageType == kIOMessageServiceIsTerminated) {
fprintf(stderr, "Device removed.\n");
// Dump our private data to stderr just to see what it looks like.
fprintf(stderr, "privateDataRef->deviceName: ");
CFShow(privateDataRef->deviceName);
fprintf(stderr, "privateDataRef->locationID: 0x%x.\n\n", (unsigned int)privateDataRef->locationID);
// Free the data we're no longer using now that the device is going away
CFRelease(privateDataRef->deviceName);
if (privateDataRef->deviceInterface) {
kr = (*privateDataRef->deviceInterface)->Release(privateDataRef->deviceInterface);
}
kr = IOObjectRelease(privateDataRef->notification);
free(privateDataRef);
}
}
//================================================================================================
//
// DeviceAdded
//
// This routine is the callback for our IOServiceAddMatchingNotification. When we get called
// we will look at all the devices that were added and we will:
//
// 1. Create some private data to relate to each device (in this case we use the service's name
// and the location ID of the device
// 2. Submit an IOServiceAddInterestNotification of type kIOGeneralInterest for this device,
// using the refCon field to store a pointer to our private data. When we get called with
// this interest notification, we can grab the refCon and access our private data.
//
//================================================================================================
UInt32 usbAddress=0;
char serialnumber[128];
char USBVersion[128];
static bool getUSBVersion(io_service_t hidDevice,io_name_t version)
{
kern_return_t result;
CFMutableDictionaryRef hidProperties = 0;
result = IORegistryEntryCreateCFProperties(hidDevice, &hidProperties, kCFAllocatorSystemDefault, kNilOptions);
if ((result == KERN_SUCCESS) && hidProperties)
{
CFNumberRef versionRef = (CFNumberRef)CFDictionaryGetValue(hidProperties, CFSTR("bcdDevice"));
if (versionRef)
{
int ver=0;
CFNumberGetValue(versionRef, kCFNumberIntType, &ver);
CFRelease(versionRef);
int h=ver/0x100;
int w=ver%0x100;
sprintf(version, "%x.%02x",h,w);
return true;
}
}
return false;
}
//add for get usb serial number
static void getStringDescriptor(IOUSBDeviceInterface182 **deviceInterface,
uint8_t index,
io_name_t stringBuffer)
{
io_name_t buffer;
memset(stringBuffer, 0, 128);
IOUSBDevRequest request = {
.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice),
.bRequest = kUSBRqGetDescriptor,
.wValue = static_cast<UInt16>((kUSBStringDesc << 8) | index),
.wIndex = 0x409,
.wLength = sizeof(buffer),
.pData = buffer
};
kern_return_t result;
result = (*deviceInterface)->DeviceRequest(deviceInterface, &request);
if (result != KERN_SUCCESS) {
return;
}
uint32_t count = 0;
for (uint32_t j = 2; j < request.wLenDone; j += 2) {
stringBuffer[count++] = buffer[j];
}
stringBuffer[count] = '\0';
}
static void getUDID(io_service_t device, io_name_t udidBuffer)
{
kern_return_t result;
SInt32 score;
IOCFPlugInInterface **plugin = NULL;
result = IOCreatePlugInInterfaceForService(device,
kIOUSBDeviceUserClientTypeID,
kIOCFPlugInInterfaceID,
&plugin,
&score);
if (result != KERN_SUCCESS) {