mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
bluez5: properly handle dbus signals
Fixes pipewire/pipewire#502. Also move media application creating from filter callback to initialization. Application object path and endpoint paths only need to be registered once. Signed-off-by: Huang-Huang Bao <eh5@sokka.cn>
This commit is contained in:
parent
56e2d6a3da
commit
5f561334fb
2 changed files with 245 additions and 90 deletions
|
|
@ -574,9 +574,6 @@ static void register_profile_reply(DBusPendingCall *pending, void *user_data)
|
|||
|
||||
static int register_profile(struct spa_bt_backend *backend, const char *profile, const char *uuid)
|
||||
{
|
||||
static const DBusObjectPathVTable vtable_profile = {
|
||||
.message_function = profile_handler,
|
||||
};
|
||||
DBusMessage *m;
|
||||
DBusMessageIter it[4];
|
||||
dbus_bool_t autoconnect;
|
||||
|
|
@ -586,11 +583,6 @@ static int register_profile(struct spa_bt_backend *backend, const char *profile,
|
|||
|
||||
spa_log_debug(backend->log, NAME": Registering Profile %s %s", profile, uuid);
|
||||
|
||||
if (!dbus_connection_register_object_path(backend->conn,
|
||||
profile,
|
||||
&vtable_profile, backend))
|
||||
return -EIO;
|
||||
|
||||
m = dbus_message_new_method_call(BLUEZ_SERVICE, "/org/bluez",
|
||||
BLUEZ_PROFILE_MANAGER_INTERFACE, "RegisterProfile");
|
||||
if (m == NULL)
|
||||
|
|
@ -649,6 +641,8 @@ void backend_hsp_native_register_profiles(struct spa_bt_backend *backend)
|
|||
|
||||
void backend_hsp_native_free(struct spa_bt_backend *backend)
|
||||
{
|
||||
dbus_connection_unregister_object_path(backend->conn, PROFILE_HSP_AG);
|
||||
dbus_connection_unregister_object_path(backend->conn, PROFILE_HSP_HS);
|
||||
free(backend);
|
||||
}
|
||||
|
||||
|
|
@ -658,6 +652,9 @@ struct spa_bt_backend *backend_hsp_native_new(struct spa_bt_monitor *monitor,
|
|||
uint32_t n_support)
|
||||
{
|
||||
struct spa_bt_backend *backend;
|
||||
static const DBusObjectPathVTable vtable_profile = {
|
||||
.message_function = profile_handler,
|
||||
};
|
||||
|
||||
backend = calloc(1, sizeof(struct spa_bt_backend));
|
||||
if (backend == NULL)
|
||||
|
|
@ -669,5 +666,20 @@ struct spa_bt_backend *backend_hsp_native_new(struct spa_bt_monitor *monitor,
|
|||
backend->main_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Loop);
|
||||
backend->conn = dbus_connection;
|
||||
|
||||
if (!dbus_connection_register_object_path(backend->conn,
|
||||
PROFILE_HSP_AG,
|
||||
&vtable_profile, backend)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!dbus_connection_register_object_path(backend->conn,
|
||||
PROFILE_HSP_HS,
|
||||
&vtable_profile, backend)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return backend;
|
||||
fail:
|
||||
free(backend);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ struct spa_bt_monitor {
|
|||
struct spa_list transport_list;
|
||||
|
||||
unsigned int filters_added:1;
|
||||
unsigned int objects_listed:1;
|
||||
|
||||
struct spa_bt_backend *backend_hsp_native;
|
||||
struct spa_bt_backend *backend_ofono;
|
||||
|
|
@ -85,6 +86,16 @@ static inline void add_dict(struct spa_pod_builder *builder, const char *key, co
|
|||
spa_pod_builder_string(builder, val);
|
||||
}
|
||||
|
||||
static int a2dp_codec_to_endpoint(const struct a2dp_codec *codec,
|
||||
const char * endpoint,
|
||||
char** object_path)
|
||||
{
|
||||
*object_path = spa_aprintf("%s/%s", endpoint, codec->name);
|
||||
if (*object_path == NULL)
|
||||
return -errno;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct a2dp_codec *a2dp_endpoint_to_codec(const char *endpoint)
|
||||
{
|
||||
const char *codec_name;
|
||||
|
|
@ -1194,16 +1205,20 @@ static void append_basic_array_variant_dict_entry(DBusMessageIter *dict, int key
|
|||
}
|
||||
|
||||
static int bluez_register_endpoint(struct spa_bt_monitor *monitor,
|
||||
const char *path, const char *uuid,
|
||||
const struct a2dp_codec *codec, const char *object_path) {
|
||||
char* str;
|
||||
const char *path, const char *endpoint,
|
||||
const char *uuid, const struct a2dp_codec *codec) {
|
||||
char *str, *object_path = NULL;
|
||||
DBusMessage *m;
|
||||
DBusMessageIter object_it, dict_it;
|
||||
DBusPendingCall *call;
|
||||
uint8_t caps[A2DP_MAX_CAPS_SIZE];
|
||||
int caps_size;
|
||||
int ret, caps_size;
|
||||
uint16_t codec_id = codec->codec_id;
|
||||
|
||||
ret = a2dp_codec_to_endpoint(codec, endpoint, &object_path);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
caps_size = codec->fill_caps(codec, 0, caps);
|
||||
if (caps_size < 0)
|
||||
return caps_size;
|
||||
|
|
@ -1233,34 +1248,41 @@ static int bluez_register_endpoint(struct spa_bt_monitor *monitor,
|
|||
dbus_pending_call_set_notify(call, bluez_register_endpoint_reply, monitor, NULL);
|
||||
dbus_message_unref(m);
|
||||
|
||||
free(object_path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int register_a2dp_endpoint(struct spa_bt_monitor *monitor,
|
||||
const struct a2dp_codec *codec, const char *endpoint, char** object_path)
|
||||
const struct a2dp_codec *codec, const char *endpoint)
|
||||
{
|
||||
int ret;
|
||||
char* object_path = NULL;
|
||||
const DBusObjectPathVTable vtable_endpoint = {
|
||||
.message_function = endpoint_handler,
|
||||
};
|
||||
|
||||
*object_path = spa_aprintf("%s/%s", endpoint, codec->name);
|
||||
if (*object_path == NULL)
|
||||
return -errno;
|
||||
ret = a2dp_codec_to_endpoint(codec, endpoint, &object_path);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
spa_log_info(monitor->log, "Registering endpoint: %s", *object_path);
|
||||
spa_log_info(monitor->log, "Registering endpoint: %s", object_path);
|
||||
|
||||
if (!dbus_connection_register_object_path(monitor->conn,
|
||||
*object_path,
|
||||
&vtable_endpoint, monitor))
|
||||
object_path,
|
||||
&vtable_endpoint, monitor)) {
|
||||
free(object_path);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
free(object_path);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int adapter_register_endpoints(struct spa_bt_adapter *a)
|
||||
{
|
||||
struct spa_bt_monitor *monitor = a->monitor;
|
||||
char *endpoint_path = NULL;
|
||||
int i;
|
||||
int err = 0;
|
||||
|
||||
|
|
@ -1282,22 +1304,16 @@ static int adapter_register_endpoints(struct spa_bt_adapter *a)
|
|||
if (codec->codec_id != A2DP_CODEC_SBC)
|
||||
continue;
|
||||
|
||||
if ((err = register_a2dp_endpoint(monitor, codec, A2DP_SOURCE_ENDPOINT, &endpoint_path)))
|
||||
goto out;
|
||||
if ((err = bluez_register_endpoint(monitor, a->path,
|
||||
A2DP_SOURCE_ENDPOINT,
|
||||
SPA_BT_UUID_A2DP_SOURCE,
|
||||
codec,
|
||||
endpoint_path)))
|
||||
codec)))
|
||||
goto out;
|
||||
free(endpoint_path);
|
||||
endpoint_path = NULL;
|
||||
|
||||
if ((err = register_a2dp_endpoint(monitor, codec, A2DP_SINK_ENDPOINT, &endpoint_path)))
|
||||
goto out;
|
||||
if ((err = bluez_register_endpoint(monitor, a->path,
|
||||
A2DP_SINK_ENDPOINT,
|
||||
SPA_BT_UUID_A2DP_SINK,
|
||||
codec,
|
||||
endpoint_path)))
|
||||
codec)))
|
||||
goto out;
|
||||
|
||||
a->endpoints_registered = true;
|
||||
|
|
@ -1314,8 +1330,6 @@ static int adapter_register_endpoints(struct spa_bt_adapter *a)
|
|||
if (err) {
|
||||
spa_log_error(monitor->log, "Failed to register bluez5 endpoints");
|
||||
}
|
||||
if (endpoint_path)
|
||||
free(endpoint_path);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -1388,7 +1402,7 @@ static DBusHandlerResult object_manager_handler(DBusConnection *c, DBusMessage *
|
|||
for (i = 0; a2dp_codecs[i]; i++) {
|
||||
const struct a2dp_codec *codec = a2dp_codecs[i];
|
||||
uint8_t caps[A2DP_MAX_CAPS_SIZE];
|
||||
int caps_size;
|
||||
int caps_size, ret;
|
||||
uint16_t codec_id = codec->codec_id;
|
||||
|
||||
caps_size = codec->fill_caps(codec, 0, caps);
|
||||
|
|
@ -1396,18 +1410,23 @@ static DBusHandlerResult object_manager_handler(DBusConnection *c, DBusMessage *
|
|||
continue;
|
||||
|
||||
if (codec->decode != NULL) {
|
||||
spa_log_info(monitor->log, "register A2DP codec %s", a2dp_codecs[i]->name);
|
||||
endpoint = spa_aprintf("%s/%s", A2DP_SINK_ENDPOINT, codec->name);
|
||||
append_a2dp_object(&array, endpoint, SPA_BT_UUID_A2DP_SINK,
|
||||
codec_id, caps, caps_size);
|
||||
free(endpoint);
|
||||
ret = a2dp_codec_to_endpoint(codec, A2DP_SINK_ENDPOINT, &endpoint);
|
||||
if (ret == 0) {
|
||||
spa_log_info(monitor->log, "register A2DP sink codec %s: %s", a2dp_codecs[i]->name, endpoint);
|
||||
append_a2dp_object(&array, endpoint, SPA_BT_UUID_A2DP_SINK,
|
||||
codec_id, caps, caps_size);
|
||||
free(endpoint);
|
||||
}
|
||||
}
|
||||
|
||||
if (codec->encode != NULL) {
|
||||
endpoint = spa_aprintf("%s/%s", A2DP_SOURCE_ENDPOINT, codec->name);
|
||||
append_a2dp_object(&array, endpoint, SPA_BT_UUID_A2DP_SOURCE,
|
||||
codec_id, caps, caps_size);
|
||||
free(endpoint);
|
||||
ret = a2dp_codec_to_endpoint(codec, A2DP_SOURCE_ENDPOINT, &endpoint);
|
||||
if (ret == 0) {
|
||||
spa_log_info(monitor->log, "register A2DP source codec %s: %s", a2dp_codecs[i]->name, endpoint);
|
||||
append_a2dp_object(&array, endpoint, SPA_BT_UUID_A2DP_SOURCE,
|
||||
codec_id, caps, caps_size);
|
||||
free(endpoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1424,12 +1443,10 @@ static DBusHandlerResult object_manager_handler(DBusConnection *c, DBusMessage *
|
|||
|
||||
static void bluez_register_application_reply(DBusPendingCall *pending, void *user_data)
|
||||
{
|
||||
char *endpoint_path;
|
||||
struct spa_bt_adapter *adapter = user_data;
|
||||
struct spa_bt_monitor *monitor = adapter->monitor;
|
||||
DBusMessage *r;
|
||||
bool fallback = true;
|
||||
int i;
|
||||
|
||||
r = dbus_pending_call_steal_reply(pending);
|
||||
if (r == NULL)
|
||||
|
|
@ -1448,20 +1465,8 @@ static void bluez_register_application_reply(DBusPendingCall *pending, void *use
|
|||
|
||||
fallback = false;
|
||||
adapter->application_registered = true;
|
||||
/* The application was registered in bluez5 - time to register the endpoints */
|
||||
for (i = 0; a2dp_codecs[i]; i++) {
|
||||
const struct a2dp_codec *codec = a2dp_codecs[i];
|
||||
|
||||
register_a2dp_endpoint(monitor, codec, A2DP_SOURCE_ENDPOINT, &endpoint_path);
|
||||
if (endpoint_path)
|
||||
free(endpoint_path);
|
||||
|
||||
register_a2dp_endpoint(monitor, codec, A2DP_SINK_ENDPOINT, &endpoint_path);
|
||||
if (endpoint_path)
|
||||
free(endpoint_path);
|
||||
}
|
||||
|
||||
finish:
|
||||
finish:
|
||||
dbus_message_unref(r);
|
||||
dbus_pending_call_unref(pending);
|
||||
|
||||
|
|
@ -1469,12 +1474,54 @@ static void bluez_register_application_reply(DBusPendingCall *pending, void *use
|
|||
adapter_register_endpoints(adapter);
|
||||
}
|
||||
|
||||
static int adapter_register_application(struct spa_bt_adapter *a) {
|
||||
const char *object_manager_path = A2DP_OBJECT_MANAGER_PATH;
|
||||
struct spa_bt_monitor *monitor = a->monitor;
|
||||
static int register_media_application(struct spa_bt_monitor * monitor)
|
||||
{
|
||||
const DBusObjectPathVTable vtable_object_manager = {
|
||||
.message_function = object_manager_handler,
|
||||
};
|
||||
|
||||
spa_log_info(monitor->log, "Registering media application object: " A2DP_OBJECT_MANAGER_PATH);
|
||||
|
||||
if (!dbus_connection_register_object_path(monitor->conn,
|
||||
A2DP_OBJECT_MANAGER_PATH,
|
||||
&vtable_object_manager, monitor))
|
||||
return -EIO;
|
||||
|
||||
for (int i = 0; a2dp_codecs[i]; i++) {
|
||||
const struct a2dp_codec *codec = a2dp_codecs[i];
|
||||
register_a2dp_endpoint(monitor, codec, A2DP_SOURCE_ENDPOINT);
|
||||
register_a2dp_endpoint(monitor, codec, A2DP_SINK_ENDPOINT);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void unregister_media_application(struct spa_bt_monitor * monitor)
|
||||
{
|
||||
int ret;
|
||||
char *object_path = NULL;
|
||||
dbus_connection_unregister_object_path(monitor->conn, A2DP_OBJECT_MANAGER_PATH);
|
||||
|
||||
for (int i = 0; a2dp_codecs[i]; i++) {
|
||||
const struct a2dp_codec *codec = a2dp_codecs[i];
|
||||
|
||||
ret = a2dp_codec_to_endpoint(codec, A2DP_SOURCE_ENDPOINT, &object_path);
|
||||
if (ret == 0) {
|
||||
dbus_connection_unregister_object_path(monitor->conn, object_path);
|
||||
free(object_path);
|
||||
}
|
||||
|
||||
ret = a2dp_codec_to_endpoint(codec, A2DP_SINK_ENDPOINT, &object_path);
|
||||
if (ret == 0) {
|
||||
dbus_connection_unregister_object_path(monitor->conn, object_path);
|
||||
free(object_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int adapter_register_application(struct spa_bt_adapter *a) {
|
||||
const char *object_manager_path = A2DP_OBJECT_MANAGER_PATH;
|
||||
struct spa_bt_monitor *monitor = a->monitor;
|
||||
DBusMessage *m;
|
||||
DBusMessageIter i, d;
|
||||
DBusPendingCall *call;
|
||||
|
|
@ -1484,19 +1531,12 @@ static int adapter_register_application(struct spa_bt_adapter *a) {
|
|||
|
||||
spa_log_debug(monitor->log, "Registering bluez5 media application on adapter %s", a->path);
|
||||
|
||||
if (!dbus_connection_register_object_path(monitor->conn,
|
||||
object_manager_path,
|
||||
&vtable_object_manager, monitor))
|
||||
return -EIO;
|
||||
|
||||
m = dbus_message_new_method_call(BLUEZ_SERVICE,
|
||||
a->path,
|
||||
BLUEZ_MEDIA_INTERFACE,
|
||||
"RegisterApplication");
|
||||
if (m == NULL) {
|
||||
dbus_connection_unregister_object_path(monitor->conn, object_manager_path);
|
||||
if (m == NULL)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
dbus_message_iter_init_append(m, &i);
|
||||
dbus_message_iter_append_basic(&i, DBUS_TYPE_OBJECT_PATH, &object_manager_path);
|
||||
|
|
@ -1551,6 +1591,60 @@ static void interface_added(struct spa_bt_monitor *monitor,
|
|||
}
|
||||
}
|
||||
|
||||
static void interfaces_added(struct spa_bt_monitor *monitor, DBusMessageIter *arg_iter)
|
||||
{
|
||||
DBusMessageIter it[3];
|
||||
const char *object_path;
|
||||
|
||||
dbus_message_iter_get_basic(arg_iter, &object_path);
|
||||
dbus_message_iter_next(arg_iter);
|
||||
dbus_message_iter_recurse(arg_iter, &it[0]);
|
||||
|
||||
while (dbus_message_iter_get_arg_type(&it[0]) != DBUS_TYPE_INVALID) {
|
||||
const char *interface_name;
|
||||
|
||||
dbus_message_iter_recurse(&it[0], &it[1]);
|
||||
dbus_message_iter_get_basic(&it[1], &interface_name);
|
||||
dbus_message_iter_next(&it[1]);
|
||||
dbus_message_iter_recurse(&it[1], &it[2]);
|
||||
|
||||
interface_added(monitor, monitor->conn,
|
||||
object_path, interface_name,
|
||||
&it[2]);
|
||||
|
||||
dbus_message_iter_next(&it[0]);
|
||||
}
|
||||
}
|
||||
|
||||
static void interfaces_removed(struct spa_bt_monitor *monitor, DBusMessageIter *arg_iter)
|
||||
{
|
||||
const char *object_path;
|
||||
DBusMessageIter it;
|
||||
|
||||
dbus_message_iter_get_basic(arg_iter, &object_path);
|
||||
dbus_message_iter_next(arg_iter);
|
||||
dbus_message_iter_recurse(arg_iter, &it);
|
||||
|
||||
while (dbus_message_iter_get_arg_type(&it) != DBUS_TYPE_INVALID) {
|
||||
const char *interface_name;
|
||||
|
||||
dbus_message_iter_get_basic(&it, &interface_name);
|
||||
|
||||
if (strcmp(interface_name, BLUEZ_DEVICE_INTERFACE) == 0) {
|
||||
struct spa_bt_device *d;
|
||||
spa_list_consume(d, &monitor->device_list, link)
|
||||
device_free(d);
|
||||
} else if (strcmp(interface_name, BLUEZ_ADAPTER_INTERFACE) == 0) {
|
||||
struct spa_bt_adapter *a;
|
||||
spa_list_consume(a, &monitor->adapter_list, link) {
|
||||
adapter_free(a);
|
||||
}
|
||||
}
|
||||
|
||||
dbus_message_iter_next(&it);
|
||||
}
|
||||
}
|
||||
|
||||
static void get_managed_objects_reply(DBusPendingCall *pending, void *user_data)
|
||||
{
|
||||
struct spa_bt_monitor *monitor = user_data;
|
||||
|
|
@ -1581,27 +1675,10 @@ static void get_managed_objects_reply(DBusPendingCall *pending, void *user_data)
|
|||
dbus_message_iter_recurse(&it[0], &it[1]);
|
||||
|
||||
while (dbus_message_iter_get_arg_type(&it[1]) != DBUS_TYPE_INVALID) {
|
||||
const char *object_path;
|
||||
|
||||
dbus_message_iter_recurse(&it[1], &it[2]);
|
||||
dbus_message_iter_get_basic(&it[2], &object_path);
|
||||
dbus_message_iter_next(&it[2]);
|
||||
dbus_message_iter_recurse(&it[2], &it[3]);
|
||||
|
||||
while (dbus_message_iter_get_arg_type(&it[3]) != DBUS_TYPE_INVALID) {
|
||||
const char *interface_name;
|
||||
interfaces_added(monitor, &it[2]);
|
||||
|
||||
dbus_message_iter_recurse(&it[3], &it[4]);
|
||||
dbus_message_iter_get_basic(&it[4], &interface_name);
|
||||
dbus_message_iter_next(&it[4]);
|
||||
dbus_message_iter_recurse(&it[4], &it[5]);
|
||||
|
||||
interface_added(monitor, monitor->conn,
|
||||
object_path, interface_name,
|
||||
&it[5]);
|
||||
|
||||
dbus_message_iter_next(&it[3]);
|
||||
}
|
||||
dbus_message_iter_next(&it[1]);
|
||||
}
|
||||
|
||||
|
|
@ -1634,11 +1711,69 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
|
|||
dbus_error_init(&err);
|
||||
|
||||
if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameOwnerChanged")) {
|
||||
const char *name, *old_owner, *new_owner;
|
||||
|
||||
spa_log_debug(monitor->log, "Name owner changed %s", dbus_message_get_path(m));
|
||||
|
||||
if (!dbus_message_get_args(m, &err,
|
||||
DBUS_TYPE_STRING, &name,
|
||||
DBUS_TYPE_STRING, &old_owner,
|
||||
DBUS_TYPE_STRING, &new_owner,
|
||||
DBUS_TYPE_INVALID)) {
|
||||
spa_log_error(monitor->log, NAME": Failed to parse org.freedesktop.DBus.NameOwnerChanged: %s", err.message);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (strcmp(name, BLUEZ_SERVICE) == 0) {
|
||||
if (old_owner && *old_owner) {
|
||||
struct spa_bt_adapter *a;
|
||||
struct spa_bt_device *d;
|
||||
struct spa_bt_transport *t;
|
||||
|
||||
spa_log_debug(monitor->log, "Bluetooth daemon disappeared");
|
||||
monitor->objects_listed = false;
|
||||
|
||||
spa_list_consume(t, &monitor->transport_list, link)
|
||||
spa_bt_transport_free(t);
|
||||
spa_list_consume(d, &monitor->device_list, link)
|
||||
device_free(d);
|
||||
spa_list_consume(a, &monitor->adapter_list, link)
|
||||
adapter_free(a);
|
||||
}
|
||||
|
||||
if (new_owner && *new_owner) {
|
||||
spa_log_debug(monitor->log, "Bluetooth daemon appeared");
|
||||
get_managed_objects(monitor);
|
||||
}
|
||||
}
|
||||
} else if (dbus_message_is_signal(m, "org.freedesktop.DBus.ObjectManager", "InterfacesAdded")) {
|
||||
DBusMessageIter it;
|
||||
|
||||
spa_log_debug(monitor->log, "interfaces added %s", dbus_message_get_path(m));
|
||||
|
||||
if (!monitor->objects_listed)
|
||||
goto finish;
|
||||
|
||||
if (!dbus_message_iter_init(m, &it) || strcmp(dbus_message_get_signature(m), "oa{sa{sv}}") != 0) {
|
||||
spa_log_error(monitor->log, NAME": Invalid signature found in InterfacesAdded");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
interfaces_added(monitor, &it);
|
||||
} else if (dbus_message_is_signal(m, "org.freedesktop.DBus.ObjectManager", "InterfacesRemoved")) {
|
||||
DBusMessageIter it;
|
||||
|
||||
spa_log_debug(monitor->log, "interfaces removed %s", dbus_message_get_path(m));
|
||||
|
||||
if (!monitor->objects_listed)
|
||||
goto finish;
|
||||
|
||||
if (!dbus_message_iter_init(m, &it) || strcmp(dbus_message_get_signature(m), "oas") != 0) {
|
||||
spa_log_error(monitor->log, NAME": Invalid signature found in InterfacesRemoved");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
interfaces_removed(monitor, &it);
|
||||
} else if (dbus_message_is_signal(m, "org.freedesktop.DBus.Properties", "PropertiesChanged")) {
|
||||
DBusMessageIter it[2];
|
||||
const char *iface, *path;
|
||||
|
|
@ -1646,7 +1781,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
|
|||
if (!dbus_message_iter_init(m, &it[0]) ||
|
||||
strcmp(dbus_message_get_signature(m), "sa{sv}as") != 0) {
|
||||
spa_log_error(monitor->log, "Invalid signature found in PropertiesChanged");
|
||||
goto fail;
|
||||
goto finish;
|
||||
}
|
||||
path = dbus_message_get_path(m);
|
||||
|
||||
|
|
@ -1661,7 +1796,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
|
|||
if (a == NULL) {
|
||||
spa_log_warn(monitor->log,
|
||||
"Properties changed in unknown adapter %s", path);
|
||||
goto fail;
|
||||
goto finish;
|
||||
}
|
||||
spa_log_debug(monitor->log, "Properties changed in adapter %s", path);
|
||||
|
||||
|
|
@ -1674,7 +1809,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
|
|||
if (d == NULL) {
|
||||
spa_log_debug(monitor->log,
|
||||
"Properties changed in unknown device %s", path);
|
||||
goto fail;
|
||||
goto finish;
|
||||
}
|
||||
spa_log_debug(monitor->log, "Properties changed in device %s", path);
|
||||
|
||||
|
|
@ -1687,7 +1822,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
|
|||
if (transport == NULL) {
|
||||
spa_log_warn(monitor->log,
|
||||
"Properties changed in unknown transport %s", path);
|
||||
goto fail;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
spa_log_debug(monitor->log, "Properties changed in transport %s", path);
|
||||
|
|
@ -1697,6 +1832,8 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
|
|||
}
|
||||
|
||||
fail:
|
||||
dbus_error_free(&err);
|
||||
finish:
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
|
||||
|
|
@ -1760,6 +1897,8 @@ impl_device_add_listener(void *object, struct spa_hook *listener,
|
|||
add_filters(this);
|
||||
get_managed_objects(this);
|
||||
|
||||
this->objects_listed = true;
|
||||
|
||||
if (this->backend_ofono)
|
||||
backend_ofono_add_filters(this->backend_ofono);
|
||||
|
||||
|
|
@ -1802,6 +1941,8 @@ static int impl_clear(struct spa_handle *handle)
|
|||
|
||||
monitor = (struct spa_bt_monitor *) handle;
|
||||
|
||||
unregister_media_application(monitor);
|
||||
|
||||
spa_list_consume(t, &monitor->transport_list, link)
|
||||
spa_bt_transport_free(t);
|
||||
spa_list_consume(d, &monitor->device_list, link)
|
||||
|
|
@ -1879,6 +2020,8 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
spa_list_init(&this->device_list);
|
||||
spa_list_init(&this->transport_list);
|
||||
|
||||
register_media_application(this);
|
||||
|
||||
this->backend_hsp_native = backend_hsp_native_new(this, this->conn, support, n_support);
|
||||
this->backend_ofono = backend_ofono_new(this, this->conn, info, support, n_support);
|
||||
this->backend_hsphfpd = backend_hsphfpd_new(this, this->conn, info, support, n_support);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue