From 47b6cfeee3335c2d8a25876537071b30630abf4b Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 5 Jan 2023 13:59:20 -0800 Subject: attrib: Introduce g_attrib_attach_client This introduces g_attrib_attach_client which can be used to attach a bt_gatt_client instance to GAttr so it can be used to register notifications. --- attrib/gattrib.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ attrib/gattrib.h | 2 ++ 2 files changed, 48 insertions(+) (limited to 'attrib') diff --git a/attrib/gattrib.c b/attrib/gattrib.c index 041b9d289..997af3699 100644 --- a/attrib/gattrib.c +++ b/attrib/gattrib.c @@ -21,17 +21,23 @@ #include #include "lib/bluetooth.h" +#include "lib/uuid.h" #include "btio/btio.h" #include "src/log.h" #include "src/shared/util.h" #include "src/shared/att.h" +#include "src/shared/gatt-helpers.h" #include "src/shared/queue.h" +#include "src/shared/gatt-db.h" +#include "src/shared/gatt-client.h" +#include "attrib/att.h" #include "attrib/gattrib.h" struct _GAttrib { int ref_count; struct bt_att *att; + struct bt_gatt_client *client; GIOChannel *io; GDestroyNotify destroy; gpointer destroy_user_data; @@ -145,6 +151,7 @@ void g_attrib_unref(GAttrib *attrib) if (attrib->destroy) attrib->destroy(attrib->destroy_user_data); + bt_gatt_client_unref(attrib->client); bt_att_unref(attrib->att); queue_destroy(attrib->callbacks, attrib_callbacks_destroy); @@ -338,6 +345,20 @@ gboolean g_attrib_cancel_all(GAttrib *attrib) return TRUE; } +static void client_notify_cb(uint16_t value_handle, const uint8_t *value, + uint16_t length, void *user_data) +{ + uint8_t *buf = newa(uint8_t, length + 2); + + put_le16(value_handle, buf); + + if (length) + memcpy(buf + 2, value, length); + + attrib_callback_notify(NULL, ATT_OP_HANDLE_NOTIFY, buf, length + 2, + user_data); +} + guint g_attrib_register(GAttrib *attrib, guint8 opcode, guint16 handle, GAttribNotifyFunc func, gpointer user_data, GDestroyNotify notify) @@ -359,6 +380,16 @@ guint g_attrib_register(GAttrib *attrib, guint8 opcode, guint16 handle, queue_push_head(attrib->callbacks, cb); } + if (opcode == ATT_OP_HANDLE_NOTIFY && attrib->client) { + unsigned int id; + + id = bt_gatt_client_register_notify(attrib->client, handle, + NULL, client_notify_cb, cb, + attrib_callbacks_remove); + if (id) + return id; + } + if (opcode == GATTRIB_ALL_REQS) opcode = BT_ATT_ALL_REQUESTS; @@ -410,6 +441,21 @@ gboolean g_attrib_set_mtu(GAttrib *attrib, int mtu) return bt_att_set_mtu(attrib->att, mtu); } +gboolean g_attrib_attach_client(GAttrib *attrib, struct bt_gatt_client *client) +{ + if (!attrib || !client) + return FALSE; + + if (attrib->client) + bt_gatt_client_unref(attrib->client); + + attrib->client = bt_gatt_client_clone(client); + if (!attrib->client) + return FALSE; + + return TRUE; +} + gboolean g_attrib_unregister(GAttrib *attrib, guint id) { if (!attrib) diff --git a/attrib/gattrib.h b/attrib/gattrib.h index c2877d757..0111bfc3f 100644 --- a/attrib/gattrib.h +++ b/attrib/gattrib.h @@ -19,6 +19,7 @@ extern "C" { #define GATTRIB_ALL_HANDLES 0x0000 struct bt_att; /* Forward declaration for compatibility */ +struct bt_gatt_client; /* Forward declaration for compatibility */ struct _GAttrib; typedef struct _GAttrib GAttrib; @@ -53,6 +54,7 @@ guint g_attrib_register(GAttrib *attrib, guint8 opcode, guint16 handle, uint8_t *g_attrib_get_buffer(GAttrib *attrib, size_t *len); gboolean g_attrib_set_mtu(GAttrib *attrib, int mtu); +gboolean g_attrib_attach_client(GAttrib *attrib, struct bt_gatt_client *client); gboolean g_attrib_unregister(GAttrib *attrib, guint id); gboolean g_attrib_unregister_all(GAttrib *attrib); -- cgit v1.2.1