From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH BlueZ v1 1/4] shared/uhid: Add bt_uhid_create
Date: Fri, 8 Mar 2024 17:10:04 -0500 [thread overview]
Message-ID: <20240308221007.250681-1-luiz.dentz@gmail.com> (raw)
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This adds bt_uhid_create which uses UHID_CREATE2 and tracks progress of
when the device is ready to receive events and in the meantime queues
them while waiting for UHID_START.
---
src/shared/uhid.c | 134 ++++++++++++++++++++++++++++++++++++++++++++--
src/shared/uhid.h | 8 +++
2 files changed, 138 insertions(+), 4 deletions(-)
diff --git a/src/shared/uhid.c b/src/shared/uhid.c
index 1f15443cd6d0..65e2d018a82e 100644
--- a/src/shared/uhid.c
+++ b/src/shared/uhid.c
@@ -31,6 +31,9 @@ struct bt_uhid {
struct io *io;
unsigned int notify_id;
struct queue *notify_list;
+ struct queue *input;
+ bool created;
+ bool started;
};
struct uhid_notify {
@@ -48,6 +51,9 @@ static void uhid_free(struct bt_uhid *uhid)
if (uhid->notify_list)
queue_destroy(uhid->notify_list, free);
+ if (uhid->input)
+ queue_destroy(uhid->input, free);
+
free(uhid);
}
@@ -215,14 +221,11 @@ bool bt_uhid_unregister_all(struct bt_uhid *uhid)
return true;
}
-int bt_uhid_send(struct bt_uhid *uhid, const struct uhid_event *ev)
+static int uhid_send(struct bt_uhid *uhid, const struct uhid_event *ev)
{
ssize_t len;
struct iovec iov;
- if (!uhid->io)
- return -ENOTCONN;
-
iov.iov_base = (void *) ev;
iov.iov_len = sizeof(*ev);
@@ -233,3 +236,126 @@ int bt_uhid_send(struct bt_uhid *uhid, const struct uhid_event *ev)
/* uHID kernel driver does not handle partial writes */
return len != sizeof(*ev) ? -EIO : 0;
}
+
+int bt_uhid_send(struct bt_uhid *uhid, const struct uhid_event *ev)
+{
+ if (!uhid->io)
+ return -ENOTCONN;
+
+ /* Queue events if uhid has not been created yet */
+ if (!uhid->started) {
+ if (!uhid->input)
+ uhid->input = queue_new();
+
+ queue_push_tail(uhid->input, util_memdup(&ev, sizeof(ev)));
+ return 0;
+ }
+
+ return uhid_send(uhid, ev);
+}
+
+static bool input_dequeue(const void *data, const void *match_data)
+{
+ struct uhid_event *ev = (void *)data;
+ struct bt_uhid *uhid = (void *)match_data;
+
+ return bt_uhid_send(uhid, ev) == 0;
+}
+
+static void uhid_start(struct uhid_event *ev, void *user_data)
+{
+ struct bt_uhid *uhid = user_data;
+
+ uhid->started = true;
+
+ /* dequeue input events send while UHID_CREATE2 was in progress */
+ queue_remove_all(uhid->input, input_dequeue, uhid, free);
+}
+
+int bt_uhid_create(struct bt_uhid *uhid, const char *name, bdaddr_t *src,
+ bdaddr_t *dst, uint32_t vendor, uint32_t product,
+ uint32_t version, uint32_t country, void *rd_data,
+ size_t rd_size)
+{
+ struct uhid_event ev;
+ int err;
+
+ if (!uhid || !name || rd_size > sizeof(ev.u.create2.rd_data))
+ return -EINVAL;
+
+ if (uhid->created)
+ return 0;
+
+ memset(&ev, 0, sizeof(ev));
+ ev.type = UHID_CREATE2;
+ strncpy((char *) ev.u.create2.name, name,
+ sizeof(ev.u.create2.name) - 1);
+ if (src)
+ sprintf((char *)ev.u.create2.phys,
+ "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
+ src->b[5], src->b[4], src->b[3], src->b[2], src->b[1],
+ src->b[0]);
+ if (dst)
+ sprintf((char *)ev.u.create2.uniq,
+ "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
+ dst->b[5], dst->b[4], dst->b[3], dst->b[2], dst->b[1],
+ dst->b[0]);
+ ev.u.create2.vendor = vendor;
+ ev.u.create2.product = product;
+ ev.u.create2.version = version;
+ ev.u.create2.country = country;
+ ev.u.create2.bus = BUS_BLUETOOTH;
+ if (rd_size)
+ memcpy(ev.u.create2.rd_data, rd_data, rd_size);
+ ev.u.create2.rd_size = rd_size;
+
+ err = uhid_send(uhid, &ev);
+ if (err)
+ return err;
+
+ bt_uhid_register(uhid, UHID_START, uhid_start, uhid);
+
+ uhid->created = true;
+ uhid->started = false;
+
+ return 0;
+}
+
+bool bt_uhid_created(struct bt_uhid *uhid)
+{
+ if (!uhid)
+ return false;
+
+ return uhid->created;
+}
+
+bool bt_uhid_started(struct bt_uhid *uhid)
+{
+ if (!uhid)
+ return false;
+
+ return uhid->started;
+}
+
+int bt_uhid_destroy(struct bt_uhid *uhid)
+{
+ struct uhid_event ev;
+ int err;
+
+ if (!uhid)
+ return -EINVAL;
+
+ if (!uhid->created)
+ return 0;
+
+ memset(&ev, 0, sizeof(ev));
+ ev.type = UHID_DESTROY;
+
+ err = bt_uhid_send(uhid, &ev);
+ if (err < 0)
+ return err;
+
+ uhid->created = false;
+
+ return err;
+}
diff --git a/src/shared/uhid.h b/src/shared/uhid.h
index 55ae839f3017..8d5dfd6e45c9 100644
--- a/src/shared/uhid.h
+++ b/src/shared/uhid.h
@@ -11,6 +11,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <linux/uhid.h>
+#include <bluetooth/bluetooth.h>
struct bt_uhid;
@@ -29,3 +30,10 @@ bool bt_uhid_unregister(struct bt_uhid *uhid, unsigned int id);
bool bt_uhid_unregister_all(struct bt_uhid *uhid);
int bt_uhid_send(struct bt_uhid *uhid, const struct uhid_event *ev);
+int bt_uhid_create(struct bt_uhid *uhid, const char *name, bdaddr_t *src,
+ bdaddr_t *dst, uint32_t vendor, uint32_t product,
+ uint32_t version, uint32_t country, void *rd_data,
+ size_t rd_size);
+bool bt_uhid_created(struct bt_uhid *uhid);
+bool bt_uhid_started(struct bt_uhid *uhid);
+int bt_uhid_destroy(struct bt_uhid *uhid);
--
2.43.0
next reply other threads:[~2024-03-08 22:10 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-08 22:10 Luiz Augusto von Dentz [this message]
2024-03-08 22:10 ` [PATCH BlueZ v1 2/4] hog-lib: Use bt_uhid_create instead of UHID_CREATE2 Luiz Augusto von Dentz
2024-03-08 22:10 ` [PATCH BlueZ v1 3/4] input: Use bt_uhid_create instead of UHID_CREATE Luiz Augusto von Dentz
2024-03-08 22:10 ` [PATCH BlueZ v1 4/4] test-uhid: Test bt_uhid_create and bt_uhid_destroy Luiz Augusto von Dentz
2024-03-09 0:53 ` [BlueZ,v1,1/4] shared/uhid: Add bt_uhid_create bluez.test.bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240308221007.250681-1-luiz.dentz@gmail.com \
--to=luiz.dentz@gmail.com \
--cc=linux-bluetooth@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).