1#include <CoreFoundation/CoreFoundation.h> 2#include <IOKit/hid/IOHIDLib.h> 3 4static bool gReport = TRUE; 5static bool gValue = FALSE; 6static bool gSend = FALSE; 7 8static char * getReportTypeString(IOHIDReportType type) 9{ 10 switch ( type ) { 11 case kIOHIDReportTypeInput: 12 return "INPUT"; 13 case kIOHIDReportTypeOutput: 14 return "OUTPUT"; 15 case kIOHIDReportTypeFeature: 16 return "FEATURE"; 17 default: 18 return "DUH"; 19 } 20} 21 22static void __deviceReportCallback(void * context, IOReturn result, void * sender, IOHIDReportType type, uint32_t reportID, uint8_t * report, CFIndex reportLength) 23{ 24 int index; 25 26 printf("IOHIDDeviceRef[%p]: reportType=%s reportID=%d reportLength=%ld: ", sender, getReportTypeString(type), reportID, reportLength); 27 for (index=0; index<reportLength; index++) 28 printf("%02x ", report[index]); 29 printf("\n"); 30 31 // toggle a report 32 if ( gSend ) { 33 static uint8_t value = 0; 34 IOReturn ret = IOHIDDeviceSetReport((IOHIDDeviceRef)sender, kIOHIDReportTypeOutput, 0, &(value), 1); 35 value = value+1 % 2; 36 printf("Attempt to send data byte. Ret = %d\n", ret); 37 } 38} 39 40void __deviceValueCallback (void * context, IOReturn result, void * sender, IOHIDValueRef value) 41{ 42 IOHIDElementRef element = IOHIDValueGetElement(value); 43 44 printf("IOHIDDeviceRef[%p]: value=%p timestamp=%lld cookie=%d usagePage=0x%02X usage=0x%02X intValue=%ld\n", sender, value, IOHIDValueGetTimeStamp(value), (uint32_t)IOHIDElementGetCookie(element), IOHIDElementGetUsagePage(element), IOHIDElementGetUsage(element), IOHIDValueGetIntegerValue(value)); 45} 46 47 48static void __deviceCallback(void * context, IOReturn result, void * sender, IOHIDDeviceRef device) 49{ 50 printf("IOHIDDeviceRef[%p] %s\n", device, context!=0 ? "matched" : "terminated"); 51} 52 53int main (int argc, const char * argv[]) { 54 55 IOHIDManagerRef manager = IOHIDManagerCreate(kCFAllocatorDefault, 0); 56 int a; 57 for (a=1; a<argc; a++) { 58 if ( 0 == strcmp("-v", argv[a]) ) { 59 gValue = TRUE; 60 printf("Print values supported\n"); 61 } 62 else if ( 0 == strcmp("-s", argv[a]) ) { 63 gSend = TRUE; 64 printf("Send response out data supported\n"); 65 } 66 else if ( 0 == strcmp("-nr", argv[a]) ) { 67 gReport = FALSE; 68 printf("Input report data suppressed\n"); 69 } 70 } 71 72 73 74 IOHIDManagerRegisterDeviceMatchingCallback(manager, __deviceCallback, (void*)TRUE); 75 IOHIDManagerRegisterDeviceRemovalCallback(manager, __deviceCallback, (void*)FALSE); 76 77 if ( gReport ) 78 IOHIDManagerRegisterInputReportCallback(manager, __deviceReportCallback, NULL); 79 if ( gValue ) 80 IOHIDManagerRegisterInputValueCallback(manager, __deviceValueCallback, NULL); 81 82 IOHIDManagerScheduleWithRunLoop(manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); 83 IOHIDManagerSetDeviceMatching(manager, NULL); 84 IOHIDManagerOpen(manager, 0); 85 86 CFRunLoopRun(); 87 88 return 0; 89} 90