From 4208bc4d7d387124a245876c5bd5d55297be6f47 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Wed, 27 Mar 2024 16:34:59 +0000 Subject: [PATCH] feat(mouse): HoG PTP expanded support. * Implement more of the PTP bits properly in HoG. --- app/include/zmk/mouse/hog.h | 2 +- app/src/mouse/hog.c | 73 +++++++++++++++++++++++++++++++++---- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/app/include/zmk/mouse/hog.h b/app/include/zmk/mouse/hog.h index 422ed284134d..be22b5d13cec 100644 --- a/app/include/zmk/mouse/hog.h +++ b/app/include/zmk/mouse/hog.h @@ -13,5 +13,5 @@ int zmk_mouse_hog_send_mouse_report(struct zmk_hid_mouse_report_body *body); #endif // IS_ENABLED(CONFIG_ZMK_MOUSE) #if IS_ENABLED(CONFIG_ZMK_TRACKPAD) -int zmk_mouse_hog_send_ptp_report(struct zmk_hid_ptp_report *body); +int zmk_mouse_hog_send_ptp_report(struct zmk_hid_ptp_report_body *body); #endif // IS_ENABLED(CONFIG_ZMK_TRAACKPAD) \ No newline at end of file diff --git a/app/src/mouse/hog.c b/app/src/mouse/hog.c index 79abe37b5cfc..91b6d0d5e25a 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 = 0x0000, + .version = 0x0101, .code = 0x00, .flags = HIDS_NORMALLY_CONNECTABLE | HIDS_REMOTE_WAKE, }; @@ -74,7 +74,12 @@ static struct hids_report ptp_hqa = { // Configuration Collection static struct hids_report ptp_selective_reporting = { - .id = ZMK_MOUSE_HID_REPORT_ID_DIGITIZER_SEL_REPORTING, + .id = ZMK_MOUSE_HID_REPORT_ID_FEATURE_PTP_SELECTIVE, + .type = HIDS_FEATURE, +}; + +static struct hids_report ptp_mode = { + .id = ZMK_MOUSE_HID_REPORT_ID_FEATURE_PTP_MODE, .type = HIDS_FEATURE, }; @@ -113,12 +118,16 @@ static ssize_t read_hids_mouse_input_report(struct bt_conn *conn, const struct b static ssize_t read_hids_ptp_input_report(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { struct zmk_hid_ptp_report_body *report_body = &zmk_mouse_hid_get_ptp_report()->body; + LOG_DBG("Get PT Input at offset %d with len %d to fetch total size %d", offset, len, + sizeof(struct zmk_hid_ptp_report_body)); + LOG_HEXDUMP_DBG(report_body, sizeof(struct zmk_hid_ptp_report_body), "PTP report"); return bt_gatt_attr_read(conn, attr, buf, len, offset, report_body, sizeof(struct zmk_hid_ptp_report_body)); } static ssize_t read_hids_ptp_caps_report(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { + LOG_DBG("Get CAPS"); struct zmk_hid_ptp_feature_capabilities_report_body *report_body = &zmk_mouse_hid_ptp_get_feature_capabilities_report()->body; return bt_gatt_attr_read(conn, attr, buf, len, offset, report_body, @@ -127,17 +136,57 @@ static ssize_t read_hids_ptp_caps_report(struct bt_conn *conn, const struct bt_g static ssize_t read_hids_ptp_hqa_report(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { - struct zmk_hid_ptp_feature_certification *report = &zmk_hid_ptp_feature_certification_report(); - return bt_gatt_attr_read(conn, attr, buf, len, offset, report->blob, sizeof(report->blob)); + struct zmk_hid_ptp_feature_certification_report *report = + zmk_mouse_hid_ptp_get_feature_certification_report(); + LOG_DBG("Get HQA at offset %d with len %d to fetch total size %d", offset, len, + sizeof(report->ptphqa_blob)); + return bt_gatt_attr_read(conn, attr, buf, len, offset, &report->ptphqa_blob, + sizeof(report->ptphqa_blob)); +} + +static ssize_t read_hids_ptp_mode(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, + uint16_t len, uint16_t offset) { + struct zmk_hid_ptp_feature_mode_report *report = zmk_mouse_hid_ptp_get_feature_mode_report(); + LOG_DBG("Get PTP MODE at offset %d with len %d", offset, len); + return bt_gatt_attr_read(conn, attr, buf, len, offset, &report->mode, sizeof(uint8_t)); +} + +static ssize_t write_hids_ptp_mode(struct bt_conn *conn, const struct bt_gatt_attr *attr, + const void *buf, uint16_t len, uint16_t offset, uint8_t flags) { + if (offset != 0) { + LOG_ERR("Funky offset for mode"); + return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); + } + if (len != sizeof(uint8_t)) { + LOG_ERR("Wrong size for mode"); + return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); + } + + uint8_t mode = *(uint8_t *)buf; + LOG_DBG("mode: %d", mode); + // TODO: Do something with it! + + return len; +} + +static ssize_t read_hids_ptp_sel_reporting(struct bt_conn *conn, const struct bt_gatt_attr *attr, + void *buf, uint16_t len, uint16_t offset) { + struct zmk_hid_ptp_feature_selective_report *report = + zmk_mouse_hid_ptp_get_feature_selective_report(); + LOG_DBG("Get PTP sel mode at offset %d with len %d", offset, len); + return bt_gatt_attr_read(conn, attr, buf, len, offset, &report->body, + sizeof(struct zmk_hid_ptp_feature_selective_report_body)); } static ssize_t write_hids_ptp_sel_reporting(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf, uint16_t len, uint16_t offset, uint8_t flags) { if (offset != 0) { + LOG_ERR("Funky offset for sel reporting"); return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); } if (len != sizeof(struct zmk_hid_ptp_feature_selective_report_body)) { + LOG_ERR("Wrong size for sel reporting"); return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); } @@ -152,6 +201,7 @@ static ssize_t write_hids_ptp_sel_reporting(struct bt_conn *conn, const struct b #endif // IS_ENABLED(CONFIG_ZMK_TRACKPAD) static void input_ccc_changed(const struct bt_gatt_attr *attr, uint16_t value) { + LOG_DBG("Input CC changed for %d", attr->handle); host_requests_notification = (value == BT_GATT_CCC_NOTIFY) ? 1 : 0; } @@ -204,8 +254,17 @@ BT_GATT_SERVICE_DEFINE( NULL, &ptp_hqa), BT_GATT_CHARACTERISTIC(BT_UUID_HIDS_REPORT, - BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP, - BT_GATT_PERM_WRITE_ENCRYPT, NULL, write_hids_ptp_sel_reporting, NULL), + BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP, + 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_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), @@ -325,7 +384,7 @@ int zmk_mouse_hog_send_ptp_report(struct zmk_hid_ptp_report_body *report) { LOG_WRN("Consumer message queue full, popping first message and queueing again"); struct zmk_hid_ptp_report_body discarded_report; k_msgq_get(&zmk_hog_ptp_msgq, &discarded_report, K_NO_WAIT); - return zmk_hog_send_ptp_report(report); + return zmk_mouse_hog_send_ptp_report(report); } default: LOG_WRN("Failed to queue mouse report to send (%d)", err);