diff --git a/spa/plugins/bluez5/backend-hsphfpd.c b/spa/plugins/bluez5/backend-hsphfpd.c index 4a8fba9db7c9b58c940d0eadaf8fbda40ea5a77c..33112263f2fef34d314ba5105e46c25753ed973c 100644 --- a/spa/plugins/bluez5/backend-hsphfpd.c +++ b/spa/plugins/bluez5/backend-hsphfpd.c @@ -835,12 +835,14 @@ static DBusHandlerResult application_object_manager_handler(DBusConnection *c, D static void hsphfpd_audio_acquire_reply(DBusPendingCall *pending, void *user_data) { - struct impl *backend = user_data; + struct spa_bt_transport *transport = user_data; + struct impl *backend = SPA_CONTAINER_OF(transport->backend, struct impl, this); DBusMessage *r; const char *transport_path; const char *service_id; const char *agent_path; DBusError error; + int ret = 0; dbus_error_init(&error); @@ -853,16 +855,19 @@ static void hsphfpd_audio_acquire_reply(DBusPendingCall *pending, void *user_dat if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) { spa_log_error(backend->log, "RegisterApplication() failed: %s", dbus_message_get_error_name(r)); + ret = -EIO; goto finish; } if (!spa_streq(dbus_message_get_sender(r), backend->hsphfpd_service_id)) { spa_log_error(backend->log, "Reply for " HSPHFPD_ENDPOINT_INTERFACE ".ConnectAudio() from invalid sender"); + ret = -EIO; goto finish; } if (!check_signature(r, "oso")) { spa_log_error(backend->log, "Invalid reply signature for " HSPHFPD_ENDPOINT_INTERFACE ".ConnectAudio()"); + ret = -EIO; goto finish; } @@ -872,11 +877,13 @@ static void hsphfpd_audio_acquire_reply(DBusPendingCall *pending, void *user_dat DBUS_TYPE_OBJECT_PATH, &agent_path, DBUS_TYPE_INVALID) == FALSE) { spa_log_error(backend->log, "Failed to parse " HSPHFPD_ENDPOINT_INTERFACE ".ConnectAudio() reply: %s", error.message); + ret = -EIO; goto finish; } if (!spa_streq(service_id, dbus_bus_get_unique_name(backend->conn))) { spa_log_warn(backend->log, HSPHFPD_ENDPOINT_INTERFACE ".ConnectAudio() failed: Other audio application took audio socket"); + ret = -EIO; goto finish; } @@ -885,6 +892,11 @@ static void hsphfpd_audio_acquire_reply(DBusPendingCall *pending, void *user_dat finish: dbus_message_unref(r); dbus_pending_call_unref(pending); + + if (ret < 0) + spa_bt_transport_set_state(transport, SPA_BT_TRANSPORT_STATE_ERROR); + else + spa_bt_transport_set_state(transport, SPA_BT_TRANSPORT_STATE_ACTIVE); } static int hsphfpd_audio_acquire(void *data, bool optional) @@ -919,15 +931,10 @@ static int hsphfpd_audio_acquire(void *data, bool optional) dbus_error_init(&err); dbus_connection_send_with_reply(backend->conn, m, &call, -1); - dbus_pending_call_set_notify(call, hsphfpd_audio_acquire_reply, backend, NULL); + dbus_pending_call_set_notify(call, hsphfpd_audio_acquire_reply, transport, NULL); dbus_message_unref(m); - /* The ConnectAudio method triggers Introspect and NewConnection calls, - which will set the fd to use for the SCO data. - We need to run the DBus loop to be able to reply to those method calls */ backend->acquire_in_progress = true; - while (backend->acquire_in_progress && dbus_connection_read_write_dispatch(backend->conn, -1)) - ; // empty loop body return 0; } @@ -941,6 +948,8 @@ static int hsphfpd_audio_release(void *data) spa_log_debug(backend->log, "transport %p: Release %s", transport, transport->path); + spa_bt_transport_set_state(transport, SPA_BT_TRANSPORT_STATE_IDLE); + if (transport->sco_io) { spa_bt_sco_io_destroy(transport->sco_io); transport->sco_io = NULL;