input: HID gamepad quirk system for broken SDP records
cover input: HID gamepad quirk system for broken SDP records
Some Bluetooth gamepads (like DualShock 4 v2) have incomplete or malformed HID SDP records, causing BlueZ to fail with -ENOENT. Windows and Android handle this gracefully; Linux does not.
This patch adds a minimal quirk system that only activates for specifically matched devices. When extract_hid_record() fails, the dispatcher tries built-in quirks before giving up. The quirk injects the correct BT HID report descriptor so the kernel's hid-playstation driver can create an input device.
The patch includes one quirk (TG170W / DualShock 4 v2) as an example. The system is modular -- new quirks can be added as separate files in quirks/.
I previously included an external quirk profile system (JSON + HMAC signatures) and a crypto extension to bt_crypto. Based on your feedback, I've stripped those out. The core quirk system works without them.
Questions:
1. Is this approach acceptable for upstream?
2. For external quirk profiles (user-installable via JSON), what crypto approach does BlueZ prefer? The existing bt_crypto uses AF_ALG which is being deprecated. Should I wait for an upstream decision, use a different library, or skip signatures entirely?
Pakrohk (1):
input: add HID gamepad quirk system for broken SDP records
profiles/input/quirk.c | 77 +++++++++++ profiles/input/quirk.h | 37 ++++++ profiles/input/quirks/tg170w.c | 232 +++++++++++++++++++++++++++++++++ 3 files changed, 346 insertions(+) create mode 100644 profiles/input/quirk.c create mode 100644 profiles/input/quirk.h create mode 100644 profiles/input/quirks/tg170w.c
Signature · 1 line
2.54.0
PATCH 1/1 input: add HID gamepad quirk system for broken SDP records
Add a modular quirk system for third-party gamepad controllers that expose incomplete or malformed HID SDP records over Bluetooth.
When BlueZ fails to parse an SDP record (returns -ENOENT), the quirk system checks for known gamepads and injects a fallback HID report descriptor so the kernel HID driver can create an input device.
Currently supported:
- Sony DualShock 4 v2 (CUH-ZCT2x) / VID:054c PID:09cc
The quirk system uses multi-factor matching (VID/PID + device name + SDP provider) to avoid false positives. It does NOT globally weaken HID parsing - quirks only activate for specifically matched controllers.
--- profiles/input/quirk.c | 77 +++++++++++ profiles/input/quirk.h | 37 ++++++ profiles/input/quirks/tg170w.c | 232 +++++++++++++++++++++++++++++++++ 3 files changed, 346 insertions(+) create mode 100644 profiles/input/quirk.c create mode 100644 profiles/input/quirk.h create mode 100644 profiles/input/quirks/tg170w.c
profiles/input/quirk.c new file +77 -0
@@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* +* +* BlueZ - Bluetooth protocol stack for Linux +* +* Copyright (C) 2026 Gamepad Quirk Support +* +* Dispatcher for gamepad HID quirks. When BlueZ fails to parse an SDP +* record for a known gamepad, this layer injects a fallback HID report +* descriptor so the kernel HID driver can create an input device. +* +* This does NOT weaken HID parsing globally — quirks only activate for +* specifically matched controllers. +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> + +#include "bluetooth/bluetooth.h" +#include "bluetooth/hidp.h" + +#include "src/log.h" + +#include "quirk.h" + +/* Individual quirk declarations */ +extern struct gamepad_quirk tg170w_quirk; + +static struct gamepad_quirk *quirks[] = { + &tg170w_quirk, +NULL +}; + +bool gamepad_quirk_match (struct input_device *idev) +{ +int i; + +/* Check built-in quirks first */ +for (i =0 ; quirks[i]; i++) { +if (quirks[i]->match (idev)) +return true; + } + +/* Then check external (file-based) quirks */ +if (external_quirk_match (idev)) +return true; + +return false; +} + +int gamepad_quirk_apply (struct input_device *idev, +struct hidp_connadd_req *req) +{ +int i; + +/* Try built-in quirks first */ +for (i =0 ; quirks[i]; i++) { +if (!quirks[i]->match (idev)) +continue ; + +DBG ("Applying HID quirk: %s" , quirks[i]->name); + +return quirks[i]->apply (idev, req); + } + +/* Try external quirks */ +if (external_quirk_match (idev)) { +return external_quirk_apply (idev, req); + } + +return -1 ; +}
profiles/input/quirk.h new file +37 -0
@@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* +* +* BlueZ - Bluetooth protocol stack for Linux +* +* Copyright (C) 2026 Gamepad Quirk Support +* +* Minimal HID fallback for third-party gamepads with broken SDP records. +* Only activates for specifically matched devices. +*/ + +#ifndef __INPUT_QUIRK_H +#define __INPUT_QUIRK_H + +#include <stdbool.h> + +struct input_device ; +struct hidp_connadd_req ; + +struct gamepad_quirk { +const char *name; +bool (*match)(struct input_device *idev); +int (*apply)(struct input_device *idev, +struct hidp_connadd_req *req); +}; + +bool gamepad_quirk_match (struct input_device *idev); + +int gamepad_quirk_apply (struct input_device *idev, +struct hidp_connadd_req *req); + +/* External quirk support (quirk-profile.c) */ +bool external_quirk_match (struct input_device *idev); +int external_quirk_apply (struct input_device *idev, +struct hidp_connadd_req *req); + +#endif
profiles/input/quirks/tg170w.c new file +232 -0
232 lines not on this page · raw message
Signature · 1 line
2.54.0