diff options
Diffstat (limited to 'src/modules/bluetooth/bluetooth-util.c')
-rw-r--r-- | src/modules/bluetooth/bluetooth-util.c | 83 |
1 files changed, 81 insertions, 2 deletions
diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index e6f6e17e..9c679687 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -714,6 +714,47 @@ static void list_adapters(pa_bluetooth_discovery *y) { send_and_add_to_pending(y, NULL, m, list_adapters_reply); } +int pa_bluetooth_transport_parse_property(pa_bluetooth_transport *t, DBusMessageIter *i) +{ + const char *key; + DBusMessageIter variant_i; + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING) { + pa_log("Property name not a string."); + return -1; + } + + dbus_message_iter_get_basic(i, &key); + + if (!dbus_message_iter_next(i)) { + pa_log("Property value missing"); + return -1; + } + + if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_VARIANT) { + pa_log("Property value not a variant."); + return -1; + } + + dbus_message_iter_recurse(i, &variant_i); + + switch (dbus_message_iter_get_arg_type(&variant_i)) { + + case DBUS_TYPE_BOOLEAN: { + + pa_bool_t *value; + dbus_message_iter_get_basic(&variant_i, &value); + + if (pa_streq(key, "NREC")) + t->nrec = value; + + break; + } + } + + return 0; +} + static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *userdata) { DBusError err; pa_bluetooth_discovery *y; @@ -862,6 +903,28 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } else if (dbus_message_is_signal(m, "org.bluez.MediaTransport", "PropertyChanged")) { + pa_bluetooth_device *d; + pa_bluetooth_transport *t; + void *state = NULL; + DBusMessageIter arg_i; + + while ((d = pa_hashmap_iterate(y->devices, &state, NULL))) + if ((t = pa_hashmap_get(d->transports, dbus_message_get_path(m)))) + break; + + if (!t) + goto fail; + + if (!dbus_message_iter_init(m, &arg_i)) { + pa_log("Failed to parse PropertyChanged: %s", err.message); + goto fail; + } + + if (pa_bluetooth_transport_parse_property(t, &arg_i) < 0) + goto fail; + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } fail: @@ -934,10 +997,11 @@ const pa_bluetooth_transport* pa_bluetooth_device_get_transport(const pa_bluetoo return NULL; } -int pa_bluetooth_transport_acquire(const pa_bluetooth_transport *t, const char *accesstype) { +int pa_bluetooth_transport_acquire(const pa_bluetooth_transport *t, const char *accesstype, size_t *imtu, size_t *omtu) { DBusMessage *m, *r; DBusError err; int ret; + uint16_t i, o; pa_assert(t); pa_assert(t->y); @@ -955,7 +1019,7 @@ int pa_bluetooth_transport_acquire(const pa_bluetooth_transport *t, const char * } #ifdef DBUS_TYPE_UNIX_FD - if (!dbus_message_get_args(r, &err, DBUS_TYPE_UNIX_FD, &ret, DBUS_TYPE_INVALID)) { + if (!dbus_message_get_args(r, &err, DBUS_TYPE_UNIX_FD, &ret, DBUS_TYPE_UINT16, &i, DBUS_TYPE_UINT16, &o, DBUS_TYPE_INVALID)) { pa_log("Failed to parse org.bluez.MediaTransport.Acquire(): %s", err.message); ret = -1; dbus_error_free(&err); @@ -963,6 +1027,12 @@ int pa_bluetooth_transport_acquire(const pa_bluetooth_transport *t, const char * } #endif + if (imtu) + *imtu = i; + + if (omtu) + *omtu = o; + fail: dbus_message_unref(r); return ret; @@ -1028,6 +1098,7 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage const char *path, *dev_path = NULL, *uuid = NULL; uint8_t *config = NULL; int size = 0; + pa_bool_t nrec; enum profile p; DBusMessageIter args, props; DBusMessage *r; @@ -1063,6 +1134,10 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage if (var != DBUS_TYPE_OBJECT_PATH) goto fail; dbus_message_iter_get_basic(&value, &dev_path); + } else if (strcasecmp(key, "NREC") == 0) { + if (var != DBUS_TYPE_BOOLEAN) + goto fail; + dbus_message_iter_get_basic(&value, &nrec); } else if (strcasecmp(key, "Configuration") == 0) { DBusMessageIter array; if (var != DBUS_TYPE_ARRAY) @@ -1086,6 +1161,8 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage p = PROFILE_A2DP_SOURCE; t = transport_new(y, path, p, config, size); + if (nrec) + t->nrec = nrec; pa_hashmap_put(d->transports, t->path, t); pa_log_debug("Transport %s profile %d available", t->path, t->profile); @@ -1395,6 +1472,7 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) { "type='signal',sender='org.bluez',interface='org.bluez.AudioSink',member='PropertyChanged'", "type='signal',sender='org.bluez',interface='org.bluez.AudioSource',member='PropertyChanged'", "type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged'", + "type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged'", NULL) < 0) { pa_log("Failed to add D-Bus matches: %s", err.message); goto fail; @@ -1462,6 +1540,7 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) { "type='signal',sender='org.bluez',interface='org.bluez.AudioSink',member='PropertyChanged'", "type='signal',sender='org.bluez',interface='org.bluez.AudioSource',member='PropertyChanged'", "type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged'", + "type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged'", NULL); if (y->filter_added) |