]> code.delx.au - pulseaudio/blobdiff - src/modules/bluetooth/bluetooth-util.c
bluetooth: Fix sending D-Bus reply before internal callback
[pulseaudio] / src / modules / bluetooth / bluetooth-util.c
index a3f72a4f9d88e145e9a32c629c306af1d42c1989..1a14c9c89200b91d7fcbadee1756a104dc1e5112 100644 (file)
@@ -70,7 +70,7 @@ struct pa_bluetooth_discovery {
     pa_hashmap *devices;
     pa_hashmap *transports;
     pa_hook hooks[PA_BLUETOOTH_HOOK_MAX];
-    pa_bool_t filter_added;
+    bool filter_added;
 };
 
 static void get_properties_reply(DBusPendingCall *pending, void *userdata);
@@ -174,7 +174,7 @@ static pa_bluetooth_device* device_new(pa_bluetooth_discovery *discovery, const
     d = pa_xnew0(pa_bluetooth_device, 1);
 
     d->discovery = discovery;
-    d->dead = FALSE;
+    d->dead = false;
 
     d->device_info_valid = 0;
 
@@ -234,21 +234,6 @@ static void device_free(pa_bluetooth_device *d) {
     pa_xfree(d);
 }
 
-static pa_bool_t device_is_audio_ready(const pa_bluetooth_device *d) {
-    unsigned i;
-
-    pa_assert(d);
-
-    if (!d->device_info_valid || d->audio_state == PA_BT_AUDIO_STATE_INVALID)
-        return FALSE;
-
-    for (i = 0; i < PA_BLUETOOTH_PROFILE_COUNT; i++)
-        if (d->profile_state[i] != PA_BT_AUDIO_STATE_INVALID)
-            return TRUE;
-
-    return FALSE;
-}
-
 static const char *check_variant_property(DBusMessageIter *i) {
     const char *key;
 
@@ -426,7 +411,7 @@ static int parse_device_property(pa_bluetooth_device *d, DBusMessageIter *i) {
 
             if (dbus_message_iter_get_arg_type(&ai) == DBUS_TYPE_STRING && pa_streq(key, "UUIDs")) {
                 DBusMessage *m;
-                pa_bool_t has_audio = FALSE;
+                bool has_audio = false;
 
                 while (dbus_message_iter_get_arg_type(&ai) != DBUS_TYPE_INVALID) {
                     pa_bluetooth_uuid *node;
@@ -452,22 +437,22 @@ static int parse_device_property(pa_bluetooth_device *d, DBusMessageIter *i) {
                         pa_assert_se(m = dbus_message_new_method_call("org.bluez", d->path, "org.bluez.HandsfreeGateway",
                                                                       "GetProperties"));
                         send_and_add_to_pending(d->discovery, m, get_properties_reply, d);
-                        has_audio = TRUE;
+                        has_audio = true;
                     } else if (strcasecmp(HSP_HS_UUID, value) == 0 || strcasecmp(HFP_HS_UUID, value) == 0) {
                         pa_assert_se(m = dbus_message_new_method_call("org.bluez", d->path, "org.bluez.Headset",
                                                                       "GetProperties"));
                         send_and_add_to_pending(d->discovery, m, get_properties_reply, d);
-                        has_audio = TRUE;
+                        has_audio = true;
                     } else if (strcasecmp(A2DP_SINK_UUID, value) == 0) {
                         pa_assert_se(m = dbus_message_new_method_call("org.bluez", d->path, "org.bluez.AudioSink",
                                                                       "GetProperties"));
                         send_and_add_to_pending(d->discovery, m, get_properties_reply, d);
-                        has_audio = TRUE;
+                        has_audio = true;
                     } else if (strcasecmp(A2DP_SOURCE_UUID, value) == 0) {
                         pa_assert_se(m = dbus_message_new_method_call("org.bluez", d->path, "org.bluez.AudioSource",
                                                                       "GetProperties"));
                         send_and_add_to_pending(d->discovery, m, get_properties_reply, d);
-                        has_audio = TRUE;
+                        has_audio = true;
                     }
 
                     dbus_message_iter_next(&ai);
@@ -614,10 +599,10 @@ static int parse_audio_property(pa_bluetooth_device *d, const char *interface, D
     return 0;
 }
 
-static void run_callback(pa_bluetooth_device *d, pa_bool_t dead) {
+static void run_callback(pa_bluetooth_device *d, bool dead) {
     pa_assert(d);
 
-    if (!device_is_audio_ready(d))
+    if (d->device_info_valid != 1)
         return;
 
     d->dead = dead;
@@ -630,7 +615,7 @@ static void remove_all_devices(pa_bluetooth_discovery *y) {
     pa_assert(y);
 
     while ((d = pa_hashmap_steal_first(y->devices))) {
-        run_callback(d, TRUE);
+        run_callback(d, true);
         device_free(d);
     }
 }
@@ -746,7 +731,7 @@ static void get_properties_reply(DBusPendingCall *pending, void *userdata) {
 
 finish:
     if (d != NULL && old_any_connected != pa_bluetooth_device_any_audio_connected(d))
-        run_callback(d, FALSE);
+        run_callback(d, false);
 
 finish2:
     dbus_message_unref(r);
@@ -938,7 +923,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
         pa_log_debug("Device %s removed", path);
 
         if ((d = pa_hashmap_remove(y->devices, path))) {
-            run_callback(d, TRUE);
+            run_callback(d, true);
             device_free(d);
         }
 
@@ -996,7 +981,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
                 goto fail;
 
             if (old_any_connected != pa_bluetooth_device_any_audio_connected(d))
-                run_callback(d, FALSE);
+                run_callback(d, false);
         }
 
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -1060,7 +1045,7 @@ pa_bluetooth_device* pa_bluetooth_discovery_get_by_address(pa_bluetooth_discover
 
     while ((d = pa_hashmap_iterate(y->devices, &state, NULL)))
         if (pa_streq(d->address, address))
-            return device_is_audio_ready(d) ? d : NULL;
+            return d->device_info_valid == 1 ? d : NULL;
 
     return NULL;
 }
@@ -1073,7 +1058,7 @@ pa_bluetooth_device* pa_bluetooth_discovery_get_by_path(pa_bluetooth_discovery *
     pa_assert(path);
 
     if ((d = pa_hashmap_get(y->devices, path)))
-        if (device_is_audio_ready(d))
+        if (d->device_info_valid == 1)
             return d;
 
     return NULL;
@@ -1084,7 +1069,10 @@ bool pa_bluetooth_device_any_audio_connected(const pa_bluetooth_device *d) {
 
     pa_assert(d);
 
-    if (d->dead || !device_is_audio_ready(d))
+    if (d->dead || d->device_info_valid != 1)
+        return false;
+
+    if (d->audio_state == PA_BT_AUDIO_STATE_INVALID)
         return false;
 
     /* Make sure audio_state is *not* in CONNECTING state before we fire the
@@ -1141,7 +1129,7 @@ int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, bool optional, siz
     pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, &accesstype, DBUS_TYPE_INVALID));
     r = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(t->device->discovery->connection), m, -1, &err);
 
-    if (dbus_error_is_set(&err) || !r) {
+    if (!r) {
         dbus_error_free(&err);
         return -1;
     }
@@ -1232,9 +1220,7 @@ static int setup_dbus(pa_bluetooth_discovery *y) {
 
     dbus_error_init(&err);
 
-    y->connection = pa_dbus_bus_get(y->core, DBUS_BUS_SYSTEM, &err);
-
-    if (dbus_error_is_set(&err) || !y->connection) {
+    if (!(y->connection = pa_dbus_bus_get(y->core, DBUS_BUS_SYSTEM, &err))) {
         pa_log("Failed to get D-Bus connection: %s", err.message);
         dbus_error_free(&err);
         return -1;
@@ -1271,23 +1257,25 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage
     const char *sender, *path, *dev_path = NULL, *uuid = NULL;
     uint8_t *config = NULL;
     int size = 0;
-    pa_bool_t nrec = FALSE;
+    bool nrec = false;
     enum profile p;
     DBusMessageIter args, props;
     DBusMessage *r;
     bool old_any_connected;
 
-    dbus_message_iter_init(m, &args);
+    if (!dbus_message_iter_init(m, &args) || !pa_streq(dbus_message_get_signature(m), "oa{sv}")) {
+        pa_log("Invalid signature for method SetConfiguration");
+        goto fail2;
+    }
 
     dbus_message_iter_get_basic(&args, &path);
 
     if (pa_hashmap_get(y->transports, path)) {
         pa_log("org.bluez.MediaEndpoint.SetConfiguration: Transport %s is already configured.", path);
-        goto fail;
+        goto fail2;
     }
 
-    if (!dbus_message_iter_next(&args))
-        goto fail;
+    pa_assert_se(dbus_message_iter_next(&args));
 
     dbus_message_iter_recurse(&args, &props);
     if (dbus_message_iter_get_arg_type(&props) != DBUS_TYPE_DICT_ENTRY)
@@ -1351,7 +1339,7 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage
 
     if (d->transports[p] != NULL) {
         pa_log("Cannot configure transport %s because profile %d is already used", path, p);
-        goto fail;
+        goto fail2;
     }
 
     old_any_connected = pa_bluetooth_device_any_audio_connected(d);
@@ -1368,14 +1356,18 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage
     pa_log_debug("Transport %s profile %d available", t->path, t->profile);
 
     pa_assert_se(r = dbus_message_new_method_return(m));
+    pa_assert_se(dbus_connection_send(pa_dbus_connection_get(y->connection), r, NULL));
+    dbus_message_unref(r);
 
     if (old_any_connected != pa_bluetooth_device_any_audio_connected(d))
-        run_callback(d, FALSE);
+        run_callback(d, false);
 
-    return r;
+    return NULL;
 
 fail:
     pa_log("org.bluez.MediaEndpoint.SetConfiguration: invalid arguments");
+
+fail2:
     pa_assert_se(r = dbus_message_new_error(m, "org.bluez.MediaEndpoint.Error.InvalidArguments",
                                             "Unable to set configuration"));
     return r;
@@ -1406,7 +1398,7 @@ static DBusMessage *endpoint_clear_configuration(DBusConnection *c, DBusMessage
         pa_hook_fire(&y->hooks[PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED], t);
 
         if (old_any_connected != pa_bluetooth_device_any_audio_connected(t->device))
-            run_callback(t->device, FALSE);
+            run_callback(t->device, false);
 
         transport_free(t);
     }
@@ -1674,7 +1666,7 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) {
         goto fail;
     }
 
-    y->filter_added = TRUE;
+    y->filter_added = true;
 
     if (pa_dbus_add_matches(
                 conn, &err,
@@ -1818,7 +1810,7 @@ const char*pa_bluetooth_get_form_factor(uint32_t class) {
 
 char *pa_bluetooth_cleanup_name(const char *name) {
     char *t, *s, *d;
-    pa_bool_t space = FALSE;
+    bool space = false;
 
     pa_assert(name);
 
@@ -1830,13 +1822,13 @@ char *pa_bluetooth_cleanup_name(const char *name) {
     for (s = d = t; *s; s++) {
 
         if (*s <= 32 || *s >= 127 || *s == '_') {
-            space = TRUE;
+            space = true;
             continue;
         }
 
         if (space) {
             *(d++) = ' ';
-            space = FALSE;
+            space = false;
         }
 
         *(d++) = *s;
@@ -1847,15 +1839,15 @@ char *pa_bluetooth_cleanup_name(const char *name) {
     return t;
 }
 
-pa_bool_t pa_bluetooth_uuid_has(pa_bluetooth_uuid *uuids, const char *uuid) {
+bool pa_bluetooth_uuid_has(pa_bluetooth_uuid *uuids, const char *uuid) {
     pa_assert(uuid);
 
     while (uuids) {
         if (strcasecmp(uuids->uuid, uuid) == 0)
-            return TRUE;
+            return true;
 
         uuids = uuids->next;
     }
 
-    return FALSE;
+    return false;
 }