bluez: check dbus service before enumerating objects

First check if the bluez dbus service is active before doing a
GetManagedObjects() call.

Else we might try to activate the bluetooth dbus service, which
should normally only be activated during bootup.
This commit is contained in:
Wim Taymans 2021-11-17 11:56:37 +01:00
parent 7eee45ff41
commit 947ee152d3

View file

@ -3617,6 +3617,71 @@ static void get_managed_objects(struct spa_bt_monitor *monitor)
dbus_message_unref(m);
}
static void check_name_owner_reply(DBusPendingCall *pending, void *user_data)
{
struct spa_bt_monitor *monitor = user_data;
DBusMessage *r;
DBusError error;
bool running;
r = dbus_pending_call_steal_reply(pending);
if (r == NULL)
return;
if (dbus_message_is_error(r, DBUS_ERROR_UNKNOWN_METHOD)) {
spa_log_warn(monitor->log, "BlueZ D-Bus ObjectManager not available");
goto finish;
}
if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
spa_log_error(monitor->log, "NameHasOwner() failed: %s",
dbus_message_get_error_name(r));
goto finish;
}
if (!spa_streq(dbus_message_get_signature(r), "b")) {
spa_log_error(monitor->log, "Invalid reply signature for NameHasOwner()");
goto finish;
}
dbus_error_init(&error);
dbus_message_get_args(r, &error, DBUS_TYPE_BOOLEAN, &running, DBUS_TYPE_INVALID);
if (dbus_error_is_set(&error)) {
spa_log_error(monitor->log, "Could not check bluetooth service: %s", error.message);
dbus_error_free(&error);
goto finish;
}
spa_log_info(monitor->log, "bluetooth service running: %s",
running ? "yes" : "no");
if (running)
get_managed_objects(monitor);
finish:
dbus_message_unref(r);
dbus_pending_call_unref(pending);
return;
}
static void check_name_owner(struct spa_bt_monitor *monitor)
{
DBusMessage *m;
DBusPendingCall *call;
const char *service = BLUEZ_SERVICE;
m = dbus_message_new_method_call("org.freedesktop.DBus",
"/org/freedesktop/DBus",
"org.freedesktop.DBus",
"NameHasOwner");
if (m == NULL)
return;
dbus_message_append_args(m, DBUS_TYPE_STRING, &service, DBUS_TYPE_INVALID);
dbus_connection_send_with_reply(monitor->conn, m, &call, -1);
dbus_pending_call_set_notify(call, check_name_owner_reply, monitor, NULL);
dbus_message_unref(m);
}
static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *user_data)
{
struct spa_bt_monitor *monitor = user_data;
@ -3861,17 +3926,17 @@ impl_device_add_listener(void *object, struct spa_hook *listener,
const struct spa_device_events *events, void *data)
{
struct spa_bt_monitor *this = object;
struct spa_hook_list save;
struct spa_hook_list save;
spa_return_val_if_fail(this != NULL, -EINVAL);
spa_return_val_if_fail(events != NULL, -EINVAL);
spa_hook_list_isolate(&this->hooks, &save, listener, events, data);
spa_hook_list_isolate(&this->hooks, &save, listener, events, data);
add_filters(this);
get_managed_objects(this);
check_name_owner(this);
spa_hook_list_join(&this->hooks, &save);
spa_hook_list_join(&this->hooks, &save);
return 0;
}