From 0edb58533e0450c8cacda163439ed20ef8db71e2 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Fri, 29 Mar 2024 01:37:14 -0700 Subject: [PATCH] fix(mouse): Get PTP working on Windows over BLE * Proper characteristic read/write settings for feature reports. * Make our PTP input reports a tiny bit more compact to bring down size. * Minor: Report correct HID version in our service. --- app/include/zmk/mouse/hid.h | 31 +++++++++++++------------------ app/src/mouse/hog.c | 32 +++++++++++++++----------------- 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/app/include/zmk/mouse/hid.h b/app/include/zmk/mouse/hid.h index 76999705253e..086839c3e13a 100644 --- a/app/include/zmk/mouse/hid.h +++ b/app/include/zmk/mouse/hid.h @@ -62,19 +62,17 @@ HID_ITEM(HID_ITEM_TAG_UNIT, HID_ITEM_TYPE_GLOBAL, 2), (a & 0xFF), (a >> 8 & 0xFF) #define TRACKPAD_FINGER_DESC(n, c) \ - HID_USAGE(HID_USAGE_DIGITIZERS_FINGER), HID_COLLECTION(HID_COLLECTION_LOGICAL), \ - HID_LOGICAL_MIN8(0), HID_LOGICAL_MAX8(1), HID_USAGE(HID_USAGE_DIGITIZERS_TOUCH_VALID), \ - HID_USAGE(HID_USAGE_DIGITIZERS_TIP_SWITCH), HID_REPORT_COUNT(2), HID_REPORT_SIZE(1), \ - HID_INPUT(ZMK_HID_MAIN_VAL_DATA | ZMK_HID_MAIN_VAL_VAR | \ - ZMK_HID_MAIN_VAL_ABS), /* Filler Bits */ \ - HID_REPORT_SIZE(1), HID_REPORT_COUNT(6), \ - HID_INPUT(ZMK_HID_MAIN_VAL_CONST | ZMK_HID_MAIN_VAL_ARRAY | ZMK_HID_MAIN_VAL_ABS), \ + HID_USAGE_PAGE(HID_USAGE_DIGITIZERS), HID_USAGE(HID_USAGE_DIGITIZERS_FINGER), \ + HID_COLLECTION(HID_COLLECTION_LOGICAL), HID_LOGICAL_MIN8(0), HID_LOGICAL_MAX8(1), \ + HID_USAGE(HID_USAGE_DIGITIZERS_TOUCH_VALID), HID_USAGE(HID_USAGE_DIGITIZERS_TIP_SWITCH), \ + HID_REPORT_COUNT(2), HID_REPORT_SIZE(1), \ + HID_INPUT(ZMK_HID_MAIN_VAL_DATA | ZMK_HID_MAIN_VAL_VAR | ZMK_HID_MAIN_VAL_ABS), \ \ - HID_REPORT_COUNT(1), HID_REPORT_SIZE(3), HID_LOGICAL_MAX8(CONFIG_ZMK_TRACKPAD_FINGERS), \ + HID_REPORT_COUNT(1), HID_REPORT_SIZE(4), HID_LOGICAL_MAX8(CONFIG_ZMK_TRACKPAD_FINGERS), \ HID_USAGE(HID_USAGE_DIGITIZERS_CONTACT_IDENTIFIER), \ HID_INPUT(ZMK_HID_MAIN_VAL_DATA | ZMK_HID_MAIN_VAL_VAR | \ ZMK_HID_MAIN_VAL_ABS), /* Filler Bits */ \ - HID_REPORT_SIZE(1), HID_REPORT_COUNT(5), \ + HID_REPORT_SIZE(1), HID_REPORT_COUNT(2), \ HID_INPUT(ZMK_HID_MAIN_VAL_CONST | ZMK_HID_MAIN_VAL_ARRAY | ZMK_HID_MAIN_VAL_ABS), \ \ HID_USAGE_PAGE(HID_USAGE_GD), HID_LOGICAL_MIN8(0), \ @@ -139,11 +137,8 @@ static const uint8_t zmk_mouse_hid_report_desc[] = { // Windows Precision Touchpad Input Reports HID_REPORT_ID(ZMK_MOUSE_HID_REPORT_ID_DIGITIZER), - LISTIFY(CONFIG_ZMK_TRACKPAD_FINGERS, TRACKPAD_FINGER_DESC, - (HID_USAGE_PAGE(HID_USAGE_DIGITIZERS), )) + LISTIFY(CONFIG_ZMK_TRACKPAD_FINGERS, TRACKPAD_FINGER_DESC, ()) - HID_USAGE_PAGE(HID_USAGE_DIGITIZERS), - HID_USAGE(HID_USAGE_DIGITIZERS_SCAN_TIME), /* Exponent (-4) */ ZMK_HID_EXPONENT8(0x0C), /* Unit (Linear Seconds) */ @@ -152,6 +147,8 @@ static const uint8_t zmk_mouse_hid_report_desc[] = { ZMK_HID_LOGICAL_MAX32(0xFFFF), HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), + HID_USAGE_PAGE(HID_USAGE_DIGITIZERS), + HID_USAGE(HID_USAGE_DIGITIZERS_SCAN_TIME), HID_INPUT(ZMK_HID_MAIN_VAL_DATA | ZMK_HID_MAIN_VAL_VAR | ZMK_HID_MAIN_VAL_ABS), // Contact Count @@ -193,8 +190,7 @@ static const uint8_t zmk_mouse_hid_report_desc[] = { // PTPHQA Blob: Necessary for < Windows 10 // USAGE_PAGE (Vendor Defined) - ZMK_HID_USAGE_PAGE16(0x00FF), - HID_COLLECTION(HID_COLLECTION_LOGICAL), + ZMK_HID_USAGE_PAGE16(0xFF00), HID_REPORT_ID(ZMK_MOUSE_HID_REPORT_ID_FEATURE_PTPHQA), // Vendor Usage (0xC5) HID_USAGE(0xC5), @@ -208,7 +204,6 @@ static const uint8_t zmk_mouse_hid_report_desc[] = { HID_FEATURE(ZMK_HID_MAIN_VAL_DATA | ZMK_HID_MAIN_VAL_VAR | ZMK_HID_MAIN_VAL_ABS), HID_END_COLLECTION, - HID_END_COLLECTION, // // Configuration collection HID_USAGE_PAGE(HID_USAGE_DIGITIZERS), @@ -272,9 +267,9 @@ struct zmk_ptp_finger { // Touch Valid (bit 0) and tip switch (bit 1) uint8_t touch_valid : 1; uint8_t tip_switch : 1; - uint8_t padding : 6; // Contact ID - uint8_t contact_id; + uint8_t contact_id : 4; + uint8_t padding : 2; // X uint16_t x; // Y diff --git a/app/src/mouse/hog.c b/app/src/mouse/hog.c index 91b6d0d5e25a..d647a28e8d7e 100644 --- a/app/src/mouse/hog.c +++ b/app/src/mouse/hog.c @@ -36,7 +36,7 @@ struct hids_report { } __packed; static struct hids_info info = { - .version = 0x0101, + .version = 0x1101, .code = 0x00, .flags = HIDS_NORMALLY_CONNECTABLE | HIDS_REMOTE_WAKE, }; @@ -223,8 +223,7 @@ BT_GATT_SERVICE_DEFINE( mouse_hog_svc, BT_GATT_PRIMARY_SERVICE(BT_UUID_HIDS), // BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_PROTOCOL_MODE, BT_GATT_CHRC_WRITE_WITHOUT_RESP, // BT_GATT_PERM_WRITE, NULL, write_proto_mode, &proto_mode), - BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_INFO, BT_GATT_CHRC_READ, BT_GATT_PERM_READ, read_hids_info, - NULL, &info), + BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT_MAP, BT_GATT_CHRC_READ, BT_GATT_PERM_READ_ENCRYPT, read_hids_report_map, NULL, NULL), @@ -241,43 +240,42 @@ BT_GATT_SERVICE_DEFINE( BT_GATT_DESCRIPTOR(BT_UUID_HIDS_REPORT_REF, BT_GATT_PERM_READ_ENCRYPT, read_hids_report_ref, NULL, &ptp_input), - BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT, BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, - BT_GATT_PERM_READ_ENCRYPT, read_hids_ptp_caps_report, NULL, NULL), - BT_GATT_CCC(input_ccc_changed, BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT), + BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT, BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE, + BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, + read_hids_ptp_caps_report, NULL, NULL), BT_GATT_DESCRIPTOR(BT_UUID_HIDS_REPORT_REF, BT_GATT_PERM_READ_ENCRYPT, read_hids_report_ref, NULL, &ptp_caps), - BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT, BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, - BT_GATT_PERM_READ_ENCRYPT, read_hids_ptp_hqa_report, NULL, NULL), - BT_GATT_CCC(input_ccc_changed, BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT), + BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT, BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE, + BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, + read_hids_ptp_hqa_report, NULL, NULL), BT_GATT_DESCRIPTOR(BT_UUID_HIDS_REPORT_REF, BT_GATT_PERM_READ_ENCRYPT, read_hids_report_ref, NULL, &ptp_hqa), - BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT, - BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP, + BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT, BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE, BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, read_hids_ptp_mode, write_hids_ptp_mode, NULL), - BT_GATT_CCC(input_ccc_changed, BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT), BT_GATT_DESCRIPTOR(BT_UUID_HIDS_REPORT_REF, BT_GATT_PERM_READ_ENCRYPT, read_hids_report_ref, NULL, &ptp_mode), - BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT, - BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP, + BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT, BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE, BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, read_hids_ptp_sel_reporting, write_hids_ptp_sel_reporting, NULL), - BT_GATT_CCC(input_ccc_changed, BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT), BT_GATT_DESCRIPTOR(BT_UUID_HIDS_REPORT_REF, BT_GATT_PERM_READ_ENCRYPT, read_hids_report_ref, NULL, &ptp_selective_reporting), #endif // IS_ENABLED(CONFIG_ZMK_TRACKPAD) + BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_INFO, BT_GATT_CHRC_READ, BT_GATT_PERM_READ, read_hids_info, + NULL, &info), + BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_CTRL_POINT, BT_GATT_CHRC_WRITE_WITHOUT_RESP, BT_GATT_PERM_WRITE, NULL, write_ctrl_point, &ctrl_point)); static struct bt_conn *destination_connection(void) { struct bt_conn *conn; bt_addr_le_t *addr = zmk_ble_active_profile_addr(); - LOG_DBG("Address pointer %p", addr); + if (!bt_addr_le_cmp(addr, BT_ADDR_LE_ANY)) { LOG_WRN("Not sending, no active address for current profile"); return NULL; @@ -358,7 +356,7 @@ void send_ptp_report_callback(struct k_work *work) { } struct bt_gatt_notify_params notify_params = { - .attr = &mouse_hog_svc.attrs[9], + .attr = &mouse_hog_svc.attrs[7], .data = &report, .len = sizeof(report), };