[PATCHv2 37/60] bluetooth: Parse BlueZ 5 adapter properties

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Jo?o Paulo Rechi Vita <jprvita@xxxxxxxxxxxxx>

---
 src/modules/bluetooth/bluez5-util.c | 90 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 89 insertions(+), 1 deletion(-)

diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c
index 2b0846e..63bc93d 100644
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -79,12 +79,18 @@ struct pa_bluetooth_discovery {
     bool filter_added;
     bool objects_listed;
     pa_hook hooks[PA_BLUETOOTH_HOOK_MAX];
+    pa_hashmap *adapters;
     pa_hashmap *devices;
     pa_hashmap *transports;
 
     PA_LLIST_HEAD(pa_dbus_pending, pending);
 };
 
+typedef struct pa_bluetooth_adapter {
+    char *path;
+    char *address;
+} pa_bluetooth_adapter;
+
 static pa_dbus_pending* send_and_add_to_pending(pa_bluetooth_discovery *y, DBusMessage *m,
                                                                   DBusPendingCallNotifyFunction func, void *call_data) {
     pa_dbus_pending *p;
@@ -102,6 +108,31 @@ static pa_dbus_pending* send_and_add_to_pending(pa_bluetooth_discovery *y, DBusM
     return p;
 }
 
+static const char *check_variant_property(DBusMessageIter *i) {
+    const char *key;
+
+    pa_assert(i);
+
+    if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING) {
+        pa_log_error("Property name not a string.");
+        return NULL;
+    }
+
+    dbus_message_iter_get_basic(i, &key);
+
+    if (!dbus_message_iter_next(i)) {
+        pa_log_error("Property value missing");
+        return NULL;
+    }
+
+    if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_VARIANT) {
+        pa_log_error("Property value not a variant.");
+        return NULL;
+    }
+
+    return key;
+}
+
 pa_bluetooth_transport *pa_bluetooth_transport_new(pa_bluetooth_device *d, const char *owner, const char *path,
                                                           pa_bluetooth_profile_t p, const uint8_t *config, size_t size) {
     pa_bluetooth_transport *t;
@@ -333,6 +364,56 @@ static void device_remove_all(pa_bluetooth_discovery *y) {
    }
 }
 
+static void adapter_remove_all(pa_bluetooth_discovery *y) {
+    pa_bluetooth_adapter *a;
+
+    pa_assert(y);
+
+    while ((a = pa_hashmap_steal_first(y->adapters))) {
+        pa_xfree(a->path);
+        pa_xfree(a->address);
+        pa_xfree(a);
+    }
+}
+
+static int parse_adapter_properties(pa_bluetooth_discovery *y, const char *adapter, DBusMessageIter *i) {
+    DBusMessageIter element_i;
+
+    pa_assert(y);
+    pa_assert(adapter);
+
+    dbus_message_iter_recurse(i, &element_i);
+
+    while (dbus_message_iter_get_arg_type(&element_i) == DBUS_TYPE_DICT_ENTRY) {
+        DBusMessageIter dict_i, variant_i;
+        const char *key;
+
+        dbus_message_iter_recurse(&element_i, &dict_i);
+
+        key = check_variant_property(&dict_i);
+        if (key == NULL) {
+            pa_log_error("Received invalid property for adapter %s", adapter);
+            return -1;
+        }
+
+        dbus_message_iter_recurse(&dict_i, &variant_i);
+
+        if (dbus_message_iter_get_arg_type(&variant_i) == DBUS_TYPE_STRING && pa_streq(key, "Address")) {
+            char *value;
+            pa_bluetooth_adapter *a = pa_xnew(pa_bluetooth_adapter, 1);
+
+            dbus_message_iter_get_basic(&variant_i, &value);
+            a->path = pa_xstrdup(adapter);
+            a->address = pa_xstrdup(value);
+            pa_hashmap_put(y->adapters, a->path, a);
+        }
+
+        dbus_message_iter_next(&element_i);
+    }
+
+    return 0;
+}
+
 static void parse_interfaces_and_properties(pa_bluetooth_discovery *y, DBusMessageIter *dict_i) {
     DBusMessageIter element_i;
     const char *path;
@@ -359,7 +440,8 @@ static void parse_interfaces_and_properties(pa_bluetooth_discovery *y, DBusMessa
 
         if (pa_streq(interface, BLUEZ_ADAPTER_INTERFACE)) {
             pa_log_debug("Adapter %s found", path);
-            /* TODO: parse adapter properties and register endpoints */
+            /* TODO: register endpoints with adapter */
+            parse_adapter_properties(y, path, &iface_i);
         } else if (pa_streq(interface, BLUEZ_DEVICE_INTERFACE)) {
             pa_bluetooth_device *d;
 
@@ -1010,6 +1092,7 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) {
     y = pa_xnew0(pa_bluetooth_discovery, 1);
     PA_REFCNT_INIT(y);
     y->core = c;
+    y->adapters = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
     y->devices = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
     y->transports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
     PA_LLIST_HEAD_INIT(pa_dbus_pending, y->pending);
@@ -1077,6 +1160,11 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) {
 
     pa_dbus_free_pending_list(&y->pending);
 
+    if (y->adapters) {
+        adapter_remove_all(y);
+        pa_hashmap_free(y->adapters, NULL);
+    }
+
     if (y->devices) {
         device_remove_all(y);
         pa_hashmap_free(y->devices, NULL);
-- 
1.7.11.7



[Index of Archives]     [Linux Audio Users]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux