From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx> UHID_START callback shall only be registered once otherwise there is a risk of processing input queue multiple times. --- src/shared/uhid.c | 13 ++++++++++--- unit/test-uhid.c | 4 +++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/shared/uhid.c b/src/shared/uhid.c index 1eddc6122990..4f149fdb8c4d 100644 --- a/src/shared/uhid.c +++ b/src/shared/uhid.c @@ -46,6 +46,7 @@ struct bt_uhid { struct queue *input; uint8_t type; bool created; + unsigned int start_id; bool started; struct uhid_replay *replay; }; @@ -246,7 +247,7 @@ unsigned int bt_uhid_register(struct bt_uhid *uhid, uint32_t event, return 0; notify = new0(struct uhid_notify, 1); - notify->id = uhid->notify_id++; + notify->id = ++uhid->notify_id ? uhid->notify_id : ++uhid->notify_id; notify->event = event; notify->func = func; notify->user_data = user_data; @@ -351,6 +352,14 @@ int bt_uhid_create(struct bt_uhid *uhid, const char *name, bdaddr_t *src, if (uhid->created) return 0; + /* Register callback for UHID_START if not registered yet */ + if (!uhid->start_id) { + uhid->start_id = bt_uhid_register(uhid, UHID_START, uhid_start, + uhid); + if (!uhid->start_id) + return -ENOMEM; + } + memset(&ev, 0, sizeof(ev)); ev.type = UHID_CREATE2; strncpy((char *) ev.u.create2.name, name, @@ -378,8 +387,6 @@ int bt_uhid_create(struct bt_uhid *uhid, const char *name, bdaddr_t *src, if (err) return err; - bt_uhid_register(uhid, UHID_START, uhid_start, uhid); - uhid->created = true; uhid->started = false; uhid->type = type; diff --git a/unit/test-uhid.c b/unit/test-uhid.c index b0592d3657a8..573da318d480 100644 --- a/unit/test-uhid.c +++ b/unit/test-uhid.c @@ -233,8 +233,10 @@ static void test_client(gconstpointer data) err = bt_uhid_create(context->uhid, "", NULL, NULL, 0, 0, 0, 0, BT_UHID_NONE, NULL, 0); - if (err < 0) + if (err < 0) { + tester_debug("create failed: %s\n", strerror(-err)); tester_test_failed(); + } if (g_str_equal(context->data->test_name, "/uhid/command/destroy")) { err = bt_uhid_destroy(context->uhid, true); -- 2.46.0