Mac开发之HID通讯开发

1.Frameworks:IOKit.framework

2.导入头文件

#import <IOKit/hid/IOHIDLib.h>

3.初始化IOHIDManager

IOHIDManagerRef managerRef = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);

4.进行配对设置,可以过滤其他USB设备。

1).无配对设备

IOHIDManagerSetDeviceMatching(managerRef, NULL);

2).单类设备配对

NSMutableDictionary* dict= [NSMutableDictionary dictionary];
[dict setValue:[NSNumber numberWithLong:pid] forKey:[NSString stringWithCString:kIOHIDProductIDKey encoding:NSUTF8StringEncoding]];
[dict setValue:[NSNumber numberWithLong:vid] forKey:[NSString stringWithCString:kIOHIDVendorIDKey encoding:NSUTF8StringEncoding]];
IOHIDManagerSetDeviceMatching(managerRef, (__bridge CFMutableDictionaryRef)dict);

3).多种设备配对设置

NSMutableArray *arr = [NSMutableArray array];
[arr addObject:dict];
IOHIDManagerSetDeviceMatchingMultiple(managerRef, (__bridge CFMutableArrayRef)arr);

5.注册插拔设备的callback

IOHIDManagerRegisterDeviceMatchingCallback(managerRef, &HandleDeviceMatchingCallback, NULL);
IOHIDManagerRegisterDeviceRemovalCallback(managerRef, &HandleDeviceRemovalCallback, NULL);

6.加入RunLoop

IOHIDManagerScheduleWithRunLoop(managerRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);

7.打开IOHIDManager

IOReturn IOReturn = IOHIDManagerOpen(managerRef, kIOHIDOptionsTypeNone);
if(kIOReturnSuccess != IOReturn) puts("IOHIDManagerOpen failed.");

8.实现插拔callback

void Handle_DeviceMatchingCallback(void *inContext, IOReturn inResult, void *inSender, IOHIDDeviceRef inIOHIDDeviceRef)
{
    CFTypeRef ref;
    int32_t nVendorID, nProductID;
    ref = IOHIDDeviceGetProperty(inIOHIDDeviceRef, CFSTR(kIOHIDVendorIDKey));
    if (CFGetTypeID(ref) == CFNumberGetTypeID()) {
        CFNumberGetValue((CFNumberRef) ref, kCFNumberSInt32Type, &nVendorID);
    }
    ref = IOHIDDeviceGetProperty(inIOHIDDeviceRef, CFSTR(kIOHIDProductIDKey));
    if (CFGetTypeID(ref) == CFNumberGetTypeID()) {
        CFNumberGetValue((CFNumberRef) ref, kCFNumberSInt32Type, &nProductID);
    }
    NSLog(@"insert hid, vid is:%d, pid is:%d",nVendorID, nProductID);
    CFRelease(ref);
}

void Handle_DeviceRemovalCallback(void *inContext, IOReturn inResult, void *inSender, IOHIDDeviceRef inIOHIDDeviceRef)
{
    CFTypeRef ref;
    int32_t nVendorID, nProductID;
    ref = IOHIDDeviceGetProperty(inIOHIDDeviceRef, CFSTR(kIOHIDVendorIDKey));
    if (CFGetTypeID(ref) == CFNumberGetTypeID()) {
        CFNumberGetValue((CFNumberRef) ref, kCFNumberSInt32Type, &nVendorID);
    }
    ref = IOHIDDeviceGetProperty(inIOHIDDeviceRef, CFSTR(kIOHIDProductIDKey));
    if (CFGetTypeID(ref) == CFNumberGetTypeID()) {
        CFNumberGetValue((CFNumberRef) ref, kCFNumberSInt32Type, &nProductID);
    }
    NSLog(@"remove hid, vid is:%d, pid is:%d",nVendorID, nProductID);
    CFRelease(ref);
}

9.插入设备获取到IOHIDDeviceRef inIOHIDDeviceRef后,打开IOHIDDeviceRef

IOReturn ret = IOHIDDeviceOpen(inIOHIDDeviceRef,options);
if (ret != kIOReturnSuccess)
{
    printf("Open device failed!\n");return;
}

10.注册接收数据方法,即可接收数据

unsigned char InputBuffer[64];
IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef, InputBuffer, sizeof(InputBuffer), MyInputCallback, NULL);

11.接收数据callback,处理usb发送来的数据

unsigned char ReceiveData[64];
void
MyInputCallback(void* context, IOReturn result, void* sender, IOHIDReportType type, uint32_t reportID, uint8_t *report,CFIndex reportLength) {    memcpy(ReceiveData,report,sizeof(ReceiveData));
}

12.向USB设备发送指令

IOReturn ret = IOHIDDeviceSetReport(inIOHIDDeviceRef, kIOHIDReportTypeOutput, 0, (uint8_t*)outbuffer, size);
if (ret != kIOReturnSuccess) {
    PRINTMSG("发送hid数据失败,error number: %x\r\n",ret);
    return ret;
}

13.断开设备

IOReturn ret = IOHIDDeviceClose(inIOHIDDeviceRef,0L);
if (ret == kIOReturnSuccess) {
  NSLog(@"断开成功");
}

 14.可能出现的问题

1)

TCC deny IOHIDDeviceOpen

Open device failed!

需要赋予输入监听权限

 

 

2)赋予权限后依然不能打开hid

 

 需要sandbox页赋予USB权限

posted @ 2021-08-30 10:54  fansai  阅读(1234)  评论(0编辑  收藏  举报