attrib: Introduce g_attrib_attach_client
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Thu, 5 Jan 2023 21:59:20 +0000 (13:59 -0800)
committerAyush Garg <ayush.garg@samsung.com>
Fri, 5 Jan 2024 10:11:34 +0000 (15:41 +0530)
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
attrib/gattrib.c
attrib/gattrib.h

index 527d53b..c7301f0 100755 (executable)
@@ -557,9 +557,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 src/bluez-log.c
-unit_test_gattrib_LDADD = lib/libbluetooth-internal.la \
-                       src/libshared-glib.la \
-                       $(GLIB_LIBS) $(DBUS_LIBS) @LIBXML_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
 
index 07f8096..f246240 100755 (executable)
 #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)
index c2877d7..0111bfc 100755 (executable)
@@ -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);