2012-12-11 150 views
1

我参与开发Mac OS自定义HID设备支持。 但它不是HID投诉,即被IOUSBCompositeDriver抓住。Mac OS X:自定义HID驱动程序

该设备应该用作输入设备(键盘,鼠标),因此我试图实现驱动程序为kext。我试着子类IOUSBHIDDriver和IOHIDDevice从newReportDescriptor返回以下报告描述符(从Windows团队采取的)()方法:

#define KBD_KEY_CODES  6 

#pragma pack(1) 
typedef struct _VHID_KEYBOARD_REPORT 
{ 
    UInt8  ReportID; 
    // Left Control, Left Shift, Left Alt, Left GUI 
    // Right Control, Right Shift, Right Alt, Right GUI 
    UInt8  ShiftKeyFlags; 
    UInt8  Reserved; 
    UInt8  KeyCodes[KBD_KEY_CODES]; 
} VHID_KEYBOARD_REPORT; 

VHID_KEYBOARD_REPORT keyboardReport; 

bzero(&keyboardReport, sizeof(keyboardReport)); 
keyboardReport.ReportID = REPORTID_KEYBOARD; 
keyboardReport.ShiftKeyFlags = 0; 
keyboardReport.KeyCodes[0] = kHIDUsage_KeyboardA; 

IOBufferMemoryDescriptor *report = IOBufferMemoryDescriptor::withBytes(&keyboardReport, sizeof(keyboardReport), kIODirectionInOut); 

handleReport(report); 

const unsigned char g_ReportDescriptor[] = { 
// Keyboard report 
0x05, 0x01,       // USAGE_PAGE (Generic Desktop) 
0x09, 0x06,       // USAGE (Keyboard) 
0xa1, 0x01,       // COLLECTION (Application) 
0x85, REPORTID_KEYBOARD,   // REPORT_ID (Keyboard)  
0x05, 0x07,       // USAGE_PAGE (Keyboard) 
0x19, 0xe0,       // USAGE_MINIMUM (Keyboard LeftControl) 
0x29, 0xe7,       // USAGE_MAXIMUM (Keyboard Right GUI) 
0x15, 0x00,       // LOGICAL_MINIMUM (0) 
0x25, 0x01,       // LOGICAL_MAXIMUM (1) 
0x75, 0x01,       // REPORT_SIZE (1) 
0x95, 0x08,       // REPORT_COUNT (8) 
0x81, 0x02,       // INPUT (Data,Var,Abs) 
0x95, 0x01,       // REPORT_COUNT (1) 
0x75, 0x08,       // REPORT_SIZE (8) 
0x81, 0x03,       // INPUT (Cnst,Var,Abs) 
0x95, 0x05,       // REPORT_COUNT (5) 
0x75, 0x01,       // REPORT_SIZE (1) 
0x05, 0x08,       // USAGE_PAGE (LEDs) 
0x19, 0x01,       // USAGE_MINIMUM (Num Lock) 
0x29, 0x05,       // USAGE_MAXIMUM (Kana) 
0x91, 0x02,       // OUTPUT (Data,Var,Abs) 
0x95, 0x01,       // REPORT_COUNT (1) 
0x75, 0x03,       // REPORT_SIZE (3) 
0x91, 0x03,       // OUTPUT (Cnst,Var,Abs) 
0x95, 0x06,       // REPORT_COUNT (6) 
0x75, 0x08,       // REPORT_SIZE (8) 
0x15, 0x00,       // LOGICAL_MINIMUM (0) 
0x25, 0x65,       // LOGICAL_MAXIMUM (101) 
0x05, 0x07,       // USAGE_PAGE (Keyboard) 
0x19, 0x00,       // USAGE_MINIMUM (Reserved (no event indicated)) 
0x29, 0x65,       // USAGE_MAXIMUM (Keyboard Application) 
0x81, 0x00,       // INPUT (Data,Ary,Abs) 
0xc0,        // END_COLLECTION 

// Relative Mouse report 
0x05, 0x01,       // USAGE_PAGE (Generic Desktop) 
0x09, 0x02,       // USAGE (Mouse) 
0xa1, 0x01,       // COLLECTION (Application) 
0x85, REPORTID_RELATIVE_MOUSE,  // REPORT_ID (Mouse) 
0x09, 0x01,       // USAGE (Pointer) 
0xa1, 0x00,       // COLLECTION (Physical) 
0x05, 0x09,       //  USAGE_PAGE (Button) 
0x19, 0x01,       //  USAGE_MINIMUM (Button 1) 
0x29, 0x05,       //  USAGE_MAXIMUM (Button 5) 
0x15, 0x00,       //  LOGICAL_MINIMUM (0) 
0x25, 0x01,       //  LOGICAL_MAXIMUM (1) 
0x75, 0x01,       //  REPORT_SIZE (1) 
0x95, 0x05,       //  REPORT_COUNT (5) 
0x81, 0x02,       //  INPUT (Data,Var,Abs) 
0x95, 0x03,       //  REPORT_COUNT (3) 
0x81, 0x03,       //  INPUT (Cnst,Var,Abs) 
0x05, 0x01,       //  USAGE_PAGE (Generic Desktop) 
0x09, 0x30,       //  USAGE (X) 
0x09, 0x31,       //  USAGE (Y) 
0x15, 0x81,       //  Logical Minimum (-127) 
0x25, 0x7F,       //  Logical Maximum (127) 
0x75, 0x08,       //  REPORT_SIZE (8) 
0x95, 0x02,       //  REPORT_COUNT (2) 
0x81, 0x06,       //  INPUT (Data,Var,Rel) 
0x05, 0x01,       //  Usage Page (Generic Desktop) 
0x09, 0x38,       //  Usage (Wheel) 
0x15, 0x81,       //  Logical Minimum (-127) 
0x25, 0x7F,       //  Logical Maximum (127) 
0x75, 0x08,       //  Report Size (8) 
0x95, 0x01,       //  Report Count (1) 
0x81, 0x06,       //  Input (Data, Variable, Relative) 
0xc0,        // END_COLLECTION 
0xc0,        // END_COLLECTION 


// Control report 
0x06, 0x00, 0xff,    // USAGE_PAGE (Vendor Defined Page 1) 
0x09, 0x01,     // USAGE (Vendor Usage 1) 
0xa1, 0x01,     // COLLECTION (Application) 
0x85, REPORTID_VXYCONTROL,  // REPORT_ID() 
0x15, 0x00,     // LOGICAL_MINIMUM (0) 
0x26, 0xff, 0x7f,    // LOGICAL_MAXIMUM (32767) 
0x75, 0x10,     // REPORT_SIZE (16) 
0x95, 0x02,     // REPORT_COUNT (2) 
0x09, 0x01,     // USAGE (Vendor Usage 1) 
0x91, 0x00,     // OUTPUT (Data,Ary,Abs) 
0xc0,       // END_COLLECTION 

// Trigger Macro report 
0x06, 0x00, 0xff,    // USAGE_PAGE (Vendor Defined Page 1) 
0x09, 0x02,     // USAGE (Vendor Usage 2) 
0xa1, 0x01,     // COLLECTION (Application) 
0x85, REPORTID_MACROTRIG,  // REPORT_ID (5) 
0x15, 0x00,     // LOGICAL_MINIMUM (0) 
0x26, 0xff, 0x00,    // LOGICAL_MAXIMUM (255) 
0x75, 0x08,     // REPORT_SIZE (8) 
0x95, 0x01,     // REPORT_COUNT (1) 
0x09, 0x02,     // USAGE (Vendor Usage 2) 
0x81, 0x02,     // INPUT (Data,Var,Abs) 
0xc0       // END_COLLECTION 

}; 

,然后喂以下结构handleReport()方法,但是我没有看到任何影响。我预计会产生按键事件。

我错过了什么?这种驱动程序的一般工作流程是什么?

回答

0

这里有很多事情要做错了...从你的info.plist的IOKitPersonalities ...和OSBundleLibraries开始(你的所有版本都匹配?)你知道你的kext匹配吗? (你可以kextload/kextstat你的驱动程序?)假设这很好,你如何替换报告描述符?假设你正确地覆盖:: newReportDescriptor(你是否调用super :: newReportDescriptor?),你如何返回你的新描述符?

IOBufferMemoryDescriptor* memDesc = IOBufferMemoryDescriptor::withBytes(& g_ReportDescriptor, sizeof(g_ReportDescriptor), kIODirectionOutIn, false); 

它可能有助于撒上一些IOLog通过您的代码,以确保一切都如您所愿地发生。

+0

是的!我的kext与OS匹配并加载。 我使用以下代码重写newReportDescriptor: '{ IOLog(“New Report Descriptor \ n”); * descriptor = IOBufferMemoryDe​​scriptor :: withBytes(&g_ReportDescriptor,sizeof(g_ReportDescriptor),kIODirectionInOut); return kIOReturnSuccess; } ' 此刻我只是试图生成事件,因此我从start()方法调用handleReport()。我仍然期望这个事件会产生。 –

+0

我不认为从start方法调用handleReport会起作用(因为它没有真正的报表来处理)。 – geowar

+0

我最好的建议是联系DTS @ apple.com(无空格)作为'官方'答案。如果可能,发送您的项目。 – geowar