【发布时间】:2019-06-11 02:55:51
【问题描述】:
我正在尝试将 iOS 键盘上的主页键用于Esc 键。我可以使用IOHIDManager 读取键盘上的键,iOS 主页键除外。
我的理解是,将NULL 传递给IOHIDManagerSetDeviceMatching 应该匹配IOHIDUsageTables 中的所有类型,如下所示:
// clang -framework coreFoundation -framework IOKit ./HID.c -o hid
// sudo ./hid
#include <IOKit/hid/IOHIDManager.h>
#include <IOKit/hid/IOHIDValue.h>
void myHIDKeyboardCallback(void* context, IOReturn result, void* sender, IOHIDValueRef value)
{
IOHIDElementRef elem = IOHIDValueGetElement(value);
uint32_t scancode = IOHIDElementGetUsage(elem);
long pressed = IOHIDValueGetIntegerValue(value);
printf("scancode: %d, pressed: %ld\n", scancode, pressed);
}
int main(void)
{
IOHIDManagerRef hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
IOHIDManagerSetDeviceMatching(hidManager, NULL);
IOHIDManagerRegisterInputValueCallback(hidManager, myHIDKeyboardCallback, NULL);
IOHIDManagerScheduleWithRunLoop(hidManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
IOHIDManagerOpen(hidManager, kIOHIDOptionsTypeNone);
CFRunLoopRun();
}
使用PacketLogger.app(来自Apple 的Hardware IO Tools)我可以记录以下内容,其中第一个按键是主页键,然后是波形键。
[Jan 16 18:31:06.631] [HII receive] HID Interrupt: [A1] Unknown [03] Event Data [ 01 00 00 ]
[Jan 16 18:31:06.730] [HII receive] HID Interrupt: [A1] Unknown [03] Event Data [ 00 00 00 ]
[Jan 16 18:31:07.805] [HII receive] HID Interrupt: [A1] Keyboard [01] Event Data [ 00 00 35 00 00 00 00 00 ]
[Jan 16 18:31:07.905] [HII receive] HID Interrupt: [A1] Keyboard [01] Event Data [ 00 00 00 00 00 00 00 00 ]
可能是因为Unknown事件,它不能通过IOHIDManager获得。
也可以选择创建内核扩展并直接从蓝牙读取,这是上面的扩展日志:
[Jan 16 18:31:06.631] [HII receive] HID Interrupt: [A1] Unknown [03] Event Data [ 01 00 00 ]
HID Interrupt: [A1] Unknown [03] Event Data [ 01 00 00 ]
[Jan 16 18:31:06.631] [L2CAP RECEIVE] Channel ID: 0x0041 Length: 0x0005 (05) [ A1 03 01 00 00 ]
Channel ID: 0x0041 Length: 0x0005 (05) [ A1 03 01 00 00 ]
00000000: 0500 4100 a103 0100 00 ..A......
[Jan 16 18:31:06.631] [ACL RECEIVE] Data [Handle: 0x000B, Packet Boundary Flags: 0x2, Length: 0x0009 (9)]
Data [Handle: 0x000B, Packet Boundary Flags: 0x2, Length: 0x0009 (9)]
Packet Boundary Flags: [10] 0x02 - First packet of Higher Layer Message (i.e. start of an L2CAP packet)
Broadcast Flags: [00] 0x00 - Point-to-point
Data (0x0009 bytes)
[Jan 16 18:31:06.631] [ACL RECEIVE] 00000000: 0b20 0900 0500 4100 a103 0100 00 . ....A......
00000000: 0b20 0900 0500 4100 a103 0100 00 . ....A......
[Jan 16 18:31:06.730] [HII receive] HID Interrupt: [A1] Unknown [03] Event Data [ 00 00 00 ]
HID Interrupt: [A1] Unknown [03] Event Data [ 00 00 00 ]
[Jan 16 18:31:06.730] [L2CAP RECEIVE] Channel ID: 0x0041 Length: 0x0005 (05) [ A1 03 00 00 00 ]
Channel ID: 0x0041 Length: 0x0005 (05) [ A1 03 00 00 00 ]
00000000: 0500 4100 a103 0000 00 ..A......
[Jan 16 18:31:06.730] [ACL RECEIVE] Data [Handle: 0x000B, Packet Boundary Flags: 0x2, Length: 0x0009 (9)]
Data [Handle: 0x000B, Packet Boundary Flags: 0x2, Length: 0x0009 (9)]
Packet Boundary Flags: [10] 0x02 - First packet of Higher Layer Message (i.e. start of an L2CAP packet)
Broadcast Flags: [00] 0x00 - Point-to-point
Data (0x0009 bytes)
[Jan 16 18:31:06.730] [ACL RECEIVE] 00000000: 0b20 0900 0500 4100 a103 0000 00 . ....A......
00000000: 0b20 0900 0500 4100 a103 0000 00 . ....A......
[Jan 16 18:31:07.805] [HII receive] HID Interrupt: [A1] Keyboard [01] Event Data [ 00 00 35 00 00 00 00 00 ]
HID Interrupt: [A1] Keyboard [01] Event Data [ 00 00 35 00 00 00 00 00 ]
Modifier keys 00
NUM_LOCK [FALSE]
CAPS_LOCK [FALSE]
SCROLL_LOCK [FALSE]
COMPOSE [FALSE]
KANA [FALSE]
Reserved 00
Keycode 1 35 Keycode 2 00 Keycode 3 00 Keycode 4 00 Keycode 5 00 Keycode 6 00
[Jan 16 18:31:07.805] [L2CAP RECEIVE] Channel ID: 0x0041 Length: 0x000A (10) [ A1 01 00 00 35 00 00 00 00 00 ]
Channel ID: 0x0041 Length: 0x000A (10) [ A1 01 00 00 35 00 00 00 00 00 ]
00000000: 0a00 4100 a101 0000 3500 0000 0000 ..A.....5.....
[Jan 16 18:31:07.805] [ACL RECEIVE] Data [Handle: 0x000B, Packet Boundary Flags: 0x2, Length: 0x000E (14)]
Data [Handle: 0x000B, Packet Boundary Flags: 0x2, Length: 0x000E (14)]
Packet Boundary Flags: [10] 0x02 - First packet of Higher Layer Message (i.e. start of an L2CAP packet)
Broadcast Flags: [00] 0x00 - Point-to-point
Data (0x000e bytes)
[Jan 16 18:31:07.805] [ACL RECEIVE] 00000000: 0b20 0e00 0a00 4100 a101 0000 3500 0000 . ....A.....5...
00000000: 0b20 0e00 0a00 4100 a101 0000 3500 0000 . ....A.....5...
00000010: 0000 ..
[Jan 16 18:31:07.905] [HII receive] HID Interrupt: [A1] Keyboard [01] Event Data [ 00 00 00 00 00 00 00 00 ]
HID Interrupt: [A1] Keyboard [01] Event Data [ 00 00 00 00 00 00 00 00 ]
Modifier keys 00
NUM_LOCK [FALSE]
CAPS_LOCK [FALSE]
SCROLL_LOCK [FALSE]
COMPOSE [FALSE]
KANA [FALSE]
Reserved 00
Keycode 1 00 Keycode 2 00 Keycode 3 00 Keycode 4 00 Keycode 5 00 Keycode 6 00
[Jan 16 18:31:07.905] [L2CAP RECEIVE] Channel ID: 0x0041 Length: 0x000A (10) [ A1 01 00 00 00 00 00 00 00 00 ]
Channel ID: 0x0041 Length: 0x000A (10) [ A1 01 00 00 00 00 00 00 00 00 ]
00000000: 0a00 4100 a101 0000 0000 0000 0000 ..A...........
[Jan 16 18:31:07.905] [ACL RECEIVE] Data [Handle: 0x000B, Packet Boundary Flags: 0x2, Length: 0x000E (14)]
Data [Handle: 0x000B, Packet Boundary Flags: 0x2, Length: 0x000E (14)]
Packet Boundary Flags: [10] 0x02 - First packet of Higher Layer Message (i.e. start of an L2CAP packet)
Broadcast Flags: [00] 0x00 - Point-to-point
Data (0x000e bytes)
[Jan 16 18:31:07.905] [ACL RECEIVE] 00000000: 0b20 0e00 0a00 4100 a101 0000 0000 0000 . ....A.........
00000000: 0b20 0e00 0a00 4100 a101 0000 0000 0000 . ....A.........
00000010: 0000 ..
【问题讨论】:
-
使用
IOHIDManager,您是否尝试使用IOHIDManagerRegisterInputReportCallback 并自己解码报告?我想知道IOHIDManagerRegisterInputValueCallback是否不支持解码“未知”表中的值。不幸的是,我手边没有这些键盘,所以我无法自己测试。 -
不幸的是,回调也没有使用
IOHIDManagerRegisterInputReportCallback触发。 -
我发现原始代码确实有效,但在 99% 的情况下都无效。我能够确定密钥是
kHIDUsage_Csmr_ACHome。不过,每次运行sudo packetlogger | grep 'A1.*03.*01 00 00'都有效。 -
很奇怪,我想它归结为通过内核的相关位跟踪事件,以便弄清楚发生了什么以及事件被丢弃的确切位置。
-
如果我断开键盘并按 Home 键重新连接,则会发送一个 kHIDUsage_Csmr_ACHome 事件,但看起来蓝牙控制了。以前,当我能够获得一致的读数时,我也在运行多个
packetlogger实例,所以这可能会破坏蓝牙控制。
标签: macos bluetooth keyboard hid iokit