USBHIDDevice *currentDevice;
@interface USBHIDDevice()
{
IOHIDDeviceRef deviceRef;
}
@end
@implementation USBHIDDevice
-(instancetype)initWithDevice:(IOHIDDeviceRef)deviceRef {
self = [super init];
if (self) {
[self setDeviceRef:deviceRef];
}
return self;
}
-(void)connectHID{
[self openDevice];
}
-(void)disConnectHID {
if(deviceRef){
[self closeDevice];
}
}
-(IOReturn)openDevice {
if (!deviceRef) {
return kIOReturnError;
}
currentDevice = self;
IOReturn ioReturn = IOHIDDeviceOpen(deviceRef, kIOHIDOptionsTypeNone);
if ( kIOReturnSuccess == ioReturn ) {
char *inputbuffer = malloc(64);
IOHIDDeviceRegisterInputReportCallback(deviceRef, (uint8_t*)inputbuffer, 64, inputCallback, NULL);
NSDictionary *inputMatchingDict = @{@(kIOHIDElementUsagePageKey): @(0x09), @(kIOHIDElementUsageKey): @(0x02)};
IOHIDDeviceSetInputValueMatching(deviceRef, (__bridge CFDictionaryRef)inputMatchingDict);
IOHIDDeviceRegisterInputValueCallback(deviceRef, mouseInputValueCallback, NULL);
}else{
[self setDeviceRef:NULL];
}
return ioReturn;
}
-(IOReturn)closeDevice {
IOReturn ioReturn = [self checkHIDDevice];
if (kIOReturnSuccess == ioReturn) {
ioReturn = IOHIDDeviceClose(deviceRef, kIOHIDOptionsTypeNone);
}
[self setDeviceRef:NULL];
return ioReturn;
}
-(IOReturn)checkHIDDevice{
if (!deviceRef) {
NSLog(@"close devie failed(%x).", kIOReturnNotOpen);
return kIOReturnNotOpen;
}
return kIOReturnSuccess;
}
-(NSArray *)getHIDReprots {
if (!deviceRef) {
return nil;
}
NSMutableArray *reports = [[NSMutableArray alloc] init];
CFArrayRef elements;
CFIndex i;
elements = __IOHIDDeviceCopyMatchingInputElements(deviceRef, NULL);
elements = IOHIDDeviceCopyMatchingElements(deviceRef, NULL, kIOHIDOptionsTypeNone);
for (i = 0; i<CFArrayGetCount(elements); i++) {
const IOHIDElementRef element = (void*)CFArrayGetValueAtIndex(elements, i);
IOHIDElementType eleType = IOHIDElementGetType(element);
NSString *eleTypeStr = @"";
switch (eleType) {
case kIOHIDElementTypeInput_Misc:
eleTypeStr = @"kIOHIDElementTypeInput_Misc";
break;
case kIOHIDElementTypeInput_Button:
eleTypeStr = @"kIOHIDElementTypeInput_Button";
break;
case kIOHIDElementTypeInput_Axis:
eleTypeStr = @"kIOHIDElementTypeInput_Axis";
break;
case kIOHIDElementTypeInput_ScanCodes:
eleTypeStr = @"kIOHIDElementTypeInput_ScanCodes";
break;
case kIOHIDElementTypeInput_NULL:
eleTypeStr = @"kIOHIDElementTypeInput_NULL";
break;
case kIOHIDElementTypeOutput:
eleTypeStr = @"kIOHIDElementTypeOutput";
break;
case kIOHIDElementTypeFeature:
eleTypeStr = @"kIOHIDElementTypeFeature";
break;
case kIOHIDElementTypeCollection:
eleTypeStr = @"kIOHIDElementTypeCollection";
break;
default:
break;
}
uint32_t page = IOHIDElementGetUsagePage(element);
uint32_t usage = IOHIDElementGetUsage(element);
uint32_t reportID = IOHIDElementGetReportID(element);
uint32_t reportSize = IOHIDElementGetReportSize(element);
uint32_t reportCount = IOHIDElementGetReportCount(element);
NSString *elementStr = [[NSString alloc] initWithFormat:@" reportID:%d, reportSize:%d, type:%@, UsagePage:%d, usage:%d, reportCount:%d\n\n",reportID, reportSize, eleTypeStr, page, usage, reportCount];
[reports addObject:elementStr];
}
return reports;
}
CFArrayRef __IOHIDDeviceCopyMatchingInputElements(IOHIDDeviceRef device, CFArrayRef multiple)
{
CFMutableArrayRef inputElements = NULL;
CFArrayRef elements = NULL;
CFIndex index, count;
// Grab the matching multiple. If one has not already been specified,
// fallback to the default
if ( multiple ) {
CFRetain(multiple);
} else {
uint32_t inputTypes[] = { kIOHIDElementTypeInput_Misc, kIOHIDElementTypeInput_Button, kIOHIDElementTypeInput_Axis, kIOHIDElementTypeInput_ScanCodes};
count = sizeof(inputTypes) / sizeof(uint32_t);
CFDictionaryRef matching[count];
bzero(matching, sizeof(CFDictionaryRef) * count);
CFStringRef key = CFSTR(kIOHIDElementTypeKey);
for ( index=0; index<count; index++ ) {
CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &inputTypes[index]);
matching[index] = CFDictionaryCreate(kCFAllocatorDefault,
(const void **)&key,
(const void **)&number,
1,
&kCFCopyStringDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFRelease(number);
}
multiple = CFArrayCreate(kCFAllocatorDefault, (const void **)matching, count, &kCFTypeArrayCallBacks);
for ( index=0; index<count; index++ )
CFRelease(matching[index]);
}
if ( !multiple )
return NULL;
count = CFArrayGetCount( multiple );
for ( index=0; index<count; index++) {
elements = IOHIDDeviceCopyMatchingElements( device,
CFArrayGetValueAtIndex(multiple, index),
0);
if ( !elements )
continue;
if ( !inputElements )
inputElements = CFArrayCreateMutableCopy( kCFAllocatorDefault,
0,
elements);
else
CFArrayAppendArray( inputElements,
elements,
CFRangeMake(0, CFArrayGetCount(elements)));
CFRelease(elements);
}
CFRelease(multiple);
return inputElements;
}
static void inputCallback(void* context, IOReturn result, void* sender, IOHIDReportType type, uint32_t reportID, uint8_t *report, CFIndex reportLength) {
[currentDevice sendMessageWithDelegate:report length:reportLength];
}
static void mouseInputValueCallback(void *context, IOReturn result, void *sender, IOHIDValueRef value) {
NSLog(@"handle input value");
}
-(void)sendMessageWithDelegate:(uint8_t*)recvData length:(CFIndex)reportLength{
}
Post
Replies
Boosts
Views
Activity
Is there any technical support from Apple to help answer this question, Thank you!
How do you create a Developer ID Application type of platform that includes DriverKit
This is the "Provisioning Profile" security: "com.apple.developer.driverkit.transport.usb" does not contain our
vendor ID(0x1A86)
Hello, I am the manufacturer of CH340 series chips, these models can all be supported by wch drivers, you can send email to "tech"with domain"wch.cn" to acquire it.