summaryrefslogtreecommitdiff
path: root/profiles
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2022-02-25 14:18:47 -0800
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2022-02-25 15:35:04 -0800
commitd91fe6994f63a861959a79790d166f63e22623bf (patch)
tree02fc89371a8bbd3357afd6f65752254fd44feb21 /profiles
parent2ae3ce9e6d6ff83aa422b10e11fb5d0e5674c1a4 (diff)
downloadbluez-d91fe6994f63a861959a79790d166f63e22623bf.tar.gz
hog-lib: Fix not waiting for UHID_START
With use of UHID_CREATE2 the code needs to wait for UHID_START in order to know if the reports are numbered or not. Fixes: https://github.com/bluez/bluez/issues/298
Diffstat (limited to 'profiles')
-rw-r--r--profiles/input/hog-lib.c41
1 files changed, 22 insertions, 19 deletions
diff --git a/profiles/input/hog-lib.c b/profiles/input/hog-lib.c
index 5af99fcda..b611f6b4a 100644
--- a/profiles/input/hog-lib.c
+++ b/profiles/input/hog-lib.c
@@ -81,6 +81,7 @@ struct bt_hog {
struct bt_uhid *uhid;
int uhid_fd;
bool uhid_created;
+ bool uhid_start;
uint64_t uhid_flags;
uint16_t bcdhid;
uint8_t bcountrycode;
@@ -358,8 +359,8 @@ static void report_value_cb(const guint8 *pdu, guint16 len, gpointer user_data)
ev.u.input.size = len;
}
- /* If uhid had not been created yet queue up the input */
- if (!hog->uhid_created) {
+ /* If uhid had not sent UHID_START yet queue up the input */
+ if (!hog->uhid_created || !hog->uhid_start) {
if (!hog->input)
hog->input = queue_new();
@@ -809,16 +810,34 @@ static void set_numbered(void *data, void *user_data)
}
}
+static bool input_dequeue(const void *data, const void *match_data)
+{
+ const struct uhid_event *ev = data;
+ const struct bt_hog *hog = match_data;
+ int err;
+
+ err = bt_uhid_send(hog->uhid, ev);
+ if (err < 0) {
+ error("bt_uhid_send: %s (%d)", strerror(-err), -err);
+ return false;
+ }
+
+ return true;
+}
+
static void start_flags(struct uhid_event *ev, void *user_data)
{
struct bt_hog *hog = user_data;
+ hog->uhid_start = true;
hog->uhid_flags = ev->u.start.dev_flags;
DBG("uHID device flags: 0x%16" PRIx64, hog->uhid_flags);
if (hog->uhid_flags)
g_slist_foreach(hog->reports, set_numbered, hog);
+
+ queue_remove_all(hog->input, input_dequeue, hog, free);
}
static void set_report_cb(guint8 status, const guint8 *pdu,
@@ -992,21 +1011,6 @@ fail:
report_reply(hog, err, 0, false, 0, NULL);
}
-static bool input_dequeue(const void *data, const void *match_data)
-{
- const struct uhid_event *ev = data;
- const struct bt_hog *hog = match_data;
- int err;
-
- err = bt_uhid_send(hog->uhid, ev);
- if (err < 0) {
- error("bt_uhid_send: %s (%d)", strerror(-err), -err);
- return false;
- }
-
- return true;
-}
-
static void uhid_create(struct bt_hog *hog, uint8_t *report_map,
size_t report_map_len)
{
@@ -1068,10 +1072,9 @@ static void uhid_create(struct bt_hog *hog, uint8_t *report_map,
bt_uhid_register(hog->uhid, UHID_SET_REPORT, set_report, hog);
hog->uhid_created = true;
+ hog->uhid_start = false;
DBG("HoG created uHID device");
-
- queue_remove_all(hog->input, input_dequeue, hog, free);
}
static void db_report_map_write_value_cb(struct gatt_db_attribute *attr,