diff mbox series

[BlueZ,3/4] attrib: Introduce g_attrib_attach_client

Message ID 20230105220944.2373424-3-luiz.dentz@gmail.com
State New
Headers show
Series [BlueZ,1/4] shared/gatt-client: Use parent debug_callback if not set on clone | expand

Commit Message

Luiz Augusto von Dentz Jan. 5, 2023, 10:09 p.m. UTC
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

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.
---
 Makefile.am      |  6 +++---
 attrib/gattrib.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 attrib/gattrib.h |  2 ++
 3 files changed, 51 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/Makefile.am b/Makefile.am
index aa3a5e053cd8..0e8cce249c7d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -565,9 +565,9 @@  unit_tests += unit/test-gattrib
 
 unit_test_gattrib_SOURCES = unit/test-gattrib.c attrib/gattrib.c \
 					$(btio_sources) src/log.h src/log.c
-unit_test_gattrib_LDADD = lib/libbluetooth-internal.la \
-			src/libshared-glib.la \
-			$(GLIB_LIBS) $(DBUS_LIBS) -ldl -lrt
+unit_test_gattrib_LDADD = src/libshared-glib.la \
+				lib/libbluetooth-internal.la \
+				$(GLIB_LIBS) $(DBUS_LIBS) -ldl -lrt
 
 unit_tests += unit/test-bap
 
diff --git a/attrib/gattrib.c b/attrib/gattrib.c
index 041b9d289c64..997af3699c51 100644
--- a/attrib/gattrib.c
+++ b/attrib/gattrib.c
@@ -21,17 +21,23 @@ 
 #include <glib.h>
 
 #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 c2877d757342..0111bfc3f2fa 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);