[pulseaudio-commits] [Git][pulseaudio/pulseaudio][master] 7 commits: bluetooth: Keep a list of local adapters' UUIDs
PulseAudio Marge Bot (@pulseaudio-merge-bot)
gitlab at gitlab.freedesktop.org
Fri Jul 30 12:57:51 UTC 2021
PulseAudio Marge Bot pushed to branch master at PulseAudio / pulseaudio
Commits:
4b55b8a9 by João Paulo Rechi Vita at 2021-07-30T12:52:04+00:00
bluetooth: Keep a list of local adapters' UUIDs
This commit stores the UUID list when an adapter is discovered and
updates it whenever a PropertiesChanged signal notifies it has changed.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/593>
- - - - -
a631d4c0 by João Paulo Rechi Vita at 2021-07-30T12:52:04+00:00
bluetooth: backend-native: Rename profile to object in register_profile*
This string contains a object path name, not a profile name, so lets
make this accurate.
This commit brings no functional change apart from a small change in the
text of one log message.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/593>
- - - - -
28fd9bc3 by João Paulo Rechi Vita at 2021-07-30T12:52:04+00:00
bluetooth: backend-native: Pass profile id in register_profile*
Passing the profile id to register_profile and register profile reply
makes a clearer debug and will allow easier tracking of the profile
status changes.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/593>
- - - - -
2f7c4969 by João Paulo Rechi Vita at 2021-07-30T12:52:04+00:00
bluetooth: Add mechanism to track profile's status
Create pa_bluetooth_profile_status_t to represent all stages an external
Bluetooth profile can go through:
0. Inactive: Initial state, no D-Bus object has been registered for
this profile yet.
1. Active: an object implementing the org.bluez.Profile1 interface has
been registered on the system bus.
2. Registering: RegisterProfile has been called.
3. Registered: RegisterProfile succeeded.
This will be useful to handle RegisterProfile failures, as well as
dynamically register and un-register a profile based on the current
active seat.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/593>
- - - - -
a84914f7 by João Paulo Rechi Vita at 2021-07-30T12:52:04+00:00
bluetooth: backend-native: Keep track of profiles' status
Track the profile status changes for the profiles implemented by this
backend.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/593>
- - - - -
cd0a8a5a by João Paulo Rechi Vita at 2021-07-30T12:52:04+00:00
bluetooth: Create PA_BLUETOOTH_HOOK_ADAPTER_UUIDS_CHANGED
This hook will be fired any time the UUIDs property on the adapter
object changes.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/593>
- - - - -
0b9ef4cd by João Paulo Rechi Vita at 2021-07-30T12:52:04+00:00
bluetooth: backend-native: Handle RegisterProfile failure
Try to register profile support again after RegisterProfile fails, when
BlueZ indicates no one else is implementing the profiles we are
interested in.
Ideally this would rely on a list of UUIDs supported by the profile
manager instead of the adapter, but BlueZ has no such API.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/593>
- - - - -
3 changed files:
- src/modules/bluetooth/backend-native.c
- src/modules/bluetooth/bluez5-util.c
- src/modules/bluetooth/bluez5-util.h
Changes:
=====================================
src/modules/bluetooth/backend-native.c
=====================================
@@ -41,6 +41,7 @@ struct pa_bluetooth_backend {
pa_core *core;
pa_dbus_connection *connection;
pa_bluetooth_discovery *discovery;
+ pa_hook_slot *adapter_uuids_changed_slot;
bool enable_shared_profiles;
bool enable_hsp_hs;
bool enable_hfp_hf;
@@ -487,46 +488,50 @@ static void register_profile_reply(DBusPendingCall *pending, void *userdata) {
DBusMessage *r;
pa_dbus_pending *p;
pa_bluetooth_backend *b;
- char *profile;
+ pa_bluetooth_profile_t profile;
pa_assert(pending);
pa_assert_se(p = userdata);
pa_assert_se(b = p->context_data);
- pa_assert_se(profile = p->call_data);
+ pa_assert_se(profile = (pa_bluetooth_profile_t)p->call_data);
pa_assert_se(r = dbus_pending_call_steal_reply(pending));
if (dbus_message_is_error(r, BLUEZ_ERROR_NOT_SUPPORTED)) {
- pa_log_info("Couldn't register profile %s because it is disabled in BlueZ", profile);
+ pa_log_info("Couldn't register profile %s because it is disabled in BlueZ", pa_bluetooth_profile_to_string(profile));
+ profile_status_set(b->discovery, profile, PA_BLUETOOTH_PROFILE_STATUS_ACTIVE);
goto finish;
}
if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
pa_log_error(BLUEZ_PROFILE_MANAGER_INTERFACE ".RegisterProfile() failed: %s: %s", dbus_message_get_error_name(r),
pa_dbus_get_error_message(r));
+ profile_status_set(b->discovery, profile, PA_BLUETOOTH_PROFILE_STATUS_ACTIVE);
goto finish;
}
+ profile_status_set(b->discovery, profile, PA_BLUETOOTH_PROFILE_STATUS_REGISTERED);
+
finish:
dbus_message_unref(r);
PA_LLIST_REMOVE(pa_dbus_pending, b->pending, p);
pa_dbus_pending_free(p);
-
- pa_xfree(profile);
}
-static void register_profile(pa_bluetooth_backend *b, const char *profile, const char *uuid) {
+static void register_profile(pa_bluetooth_backend *b, const char *object, const char *uuid, pa_bluetooth_profile_t profile) {
DBusMessage *m;
DBusMessageIter i, d;
dbus_bool_t autoconnect;
dbus_uint16_t version, chan;
- pa_log_debug("Registering Profile %s %s", profile, uuid);
+ pa_assert(profile_status_get(b->discovery, profile) == PA_BLUETOOTH_PROFILE_STATUS_ACTIVE);
+
+ pa_log_debug("Registering Profile %s %s", pa_bluetooth_profile_to_string(profile), uuid);
pa_assert_se(m = dbus_message_new_method_call(BLUEZ_SERVICE, "/org/bluez", BLUEZ_PROFILE_MANAGER_INTERFACE, "RegisterProfile"));
dbus_message_iter_init_append(m, &i);
- pa_assert_se(dbus_message_iter_append_basic(&i, DBUS_TYPE_OBJECT_PATH, &profile));
+ pa_assert_se(dbus_message_iter_append_basic(&i, DBUS_TYPE_OBJECT_PATH, &object));
pa_assert_se(dbus_message_iter_append_basic(&i, DBUS_TYPE_STRING, &uuid));
dbus_message_iter_open_container(&i, DBUS_TYPE_ARRAY,
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
@@ -546,7 +551,8 @@ static void register_profile(pa_bluetooth_backend *b, const char *profile, const
}
dbus_message_iter_close_container(&i, &d);
- send_and_add_to_pending(b, m, register_profile_reply, pa_xstrdup(profile));
+ profile_status_set(b->discovery, profile, PA_BLUETOOTH_PROFILE_STATUS_REGISTERING);
+ send_and_add_to_pending(b, m, register_profile_reply, (void *)profile);
}
static void transport_put(pa_bluetooth_transport *t)
@@ -1062,6 +1068,26 @@ static DBusHandlerResult profile_handler(DBusConnection *c, DBusMessage *m, void
return DBUS_HANDLER_RESULT_HANDLED;
}
+static pa_hook_result_t adapter_uuids_changed_cb(pa_bluetooth_discovery *y, const pa_bluetooth_adapter *a, pa_bluetooth_backend *b) {
+ pa_assert(y);
+ pa_assert(a);
+ pa_assert(b);
+
+ if (profile_status_get(y, PA_BLUETOOTH_PROFILE_HSP_HS) == PA_BLUETOOTH_PROFILE_STATUS_ACTIVE &&
+ !pa_hashmap_get(a->uuids, PA_BLUETOOTH_UUID_HSP_AG))
+ register_profile(b, HSP_AG_PROFILE, PA_BLUETOOTH_UUID_HSP_AG, PA_BLUETOOTH_PROFILE_HSP_HS);
+
+ if (profile_status_get(y, PA_BLUETOOTH_PROFILE_HSP_AG) == PA_BLUETOOTH_PROFILE_STATUS_ACTIVE &&
+ !pa_hashmap_get(a->uuids, PA_BLUETOOTH_UUID_HSP_HS))
+ register_profile(b, HSP_HS_PROFILE, PA_BLUETOOTH_UUID_HSP_HS, PA_BLUETOOTH_PROFILE_HSP_AG);
+
+ if (profile_status_get(y, PA_BLUETOOTH_PROFILE_HFP_HF) == PA_BLUETOOTH_PROFILE_STATUS_ACTIVE &&
+ !pa_hashmap_get(a->uuids, PA_BLUETOOTH_UUID_HFP_AG))
+ register_profile(b, HFP_AG_PROFILE, PA_BLUETOOTH_UUID_HFP_AG, PA_BLUETOOTH_PROFILE_HFP_HF);
+
+ return PA_HOOK_OK;
+}
+
static void profile_init(pa_bluetooth_backend *b, pa_bluetooth_profile_t profile) {
static const DBusObjectPathVTable vtable_profile = {
.message_function = profile_handler,
@@ -1090,12 +1116,16 @@ static void profile_init(pa_bluetooth_backend *b, pa_bluetooth_profile_t profile
}
pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(b->connection), object_name, &vtable_profile, b));
- register_profile(b, object_name, uuid);
+
+ profile_status_set(b->discovery, profile, PA_BLUETOOTH_PROFILE_STATUS_ACTIVE);
+ register_profile(b, object_name, uuid, profile);
}
static void profile_done(pa_bluetooth_backend *b, pa_bluetooth_profile_t profile) {
pa_assert(b);
+ profile_status_set(b->discovery, profile, PA_BLUETOOTH_PROFILE_STATUS_INACTIVE);
+
switch (profile) {
case PA_BLUETOOTH_PROFILE_HSP_HS:
dbus_connection_unregister_object_path(pa_dbus_connection_get(b->connection), HSP_AG_PROFILE);
@@ -1156,6 +1186,10 @@ pa_bluetooth_backend *pa_bluetooth_native_backend_new(pa_core *c, pa_bluetooth_d
backend->enable_hfp_hf = pa_bluetooth_discovery_get_enable_native_hfp_hf(y);
backend->enable_hsp_hs = pa_bluetooth_discovery_get_enable_native_hsp_hs(y);
+ backend->adapter_uuids_changed_slot =
+ pa_hook_connect(pa_bluetooth_discovery_hook(y, PA_BLUETOOTH_HOOK_ADAPTER_UUIDS_CHANGED), PA_HOOK_NORMAL,
+ (pa_hook_cb_t) adapter_uuids_changed_cb, backend);
+
if (!backend->enable_hsp_hs && !backend->enable_hfp_hf)
pa_log_warn("Both HSP HS and HFP HF bluetooth profiles disabled in native backend. Native backend will not register for headset connections.");
@@ -1173,6 +1207,9 @@ void pa_bluetooth_native_backend_free(pa_bluetooth_backend *backend) {
pa_dbus_free_pending_list(&backend->pending);
+ if (backend->adapter_uuids_changed_slot)
+ pa_hook_slot_free(backend->adapter_uuids_changed_slot);
+
if (backend->enable_shared_profiles)
native_backend_apply_profile_registration_change(backend, false);
=====================================
src/modules/bluetooth/bluez5-util.c
=====================================
@@ -140,6 +140,7 @@ struct pa_bluetooth_discovery {
pa_hashmap *adapters;
pa_hashmap *devices;
pa_hashmap *transports;
+ pa_bluetooth_profile_status_t profiles_status[PA_BLUETOOTH_PROFILE_COUNT];
int headset_backend;
pa_bluetooth_backend *ofono_backend, *native_backend;
@@ -191,6 +192,14 @@ static const char *check_variant_property(DBusMessageIter *i) {
return key;
}
+pa_bluetooth_profile_status_t profile_status_get(pa_bluetooth_discovery *y, pa_bluetooth_profile_t profile) {
+ return y->profiles_status[profile];
+}
+
+void profile_status_set(pa_bluetooth_discovery *y, pa_bluetooth_profile_t profile, pa_bluetooth_profile_status_t status) {
+ y->profiles_status[profile] = status;
+}
+
pa_bluetooth_transport *pa_bluetooth_transport_new(pa_bluetooth_device *d, const char *owner, const char *path,
pa_bluetooth_profile_t p, const uint8_t *config, size_t size) {
pa_bluetooth_transport *t;
@@ -1441,6 +1450,7 @@ static pa_bluetooth_adapter* adapter_create(pa_bluetooth_discovery *y, const cha
a = pa_xnew0(pa_bluetooth_adapter, 1);
a->discovery = y;
a->path = pa_xstrdup(path);
+ a->uuids = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, pa_xfree);
pa_hashmap_put(y->adapters, a->path, a);
@@ -1643,6 +1653,31 @@ static void parse_adapter_properties(pa_bluetooth_adapter *a, DBusMessageIter *i
dbus_message_iter_get_basic(&variant_i, &value);
a->address = pa_xstrdup(value);
a->valid = true;
+ } else if (dbus_message_iter_get_arg_type(&variant_i) == DBUS_TYPE_ARRAY) {
+ DBusMessageIter ai;
+ dbus_message_iter_recurse(&variant_i, &ai);
+
+ if (dbus_message_iter_get_arg_type(&ai) == DBUS_TYPE_STRING && pa_streq(key, "UUIDs")) {
+ pa_hashmap_remove_all(a->uuids);
+ while (dbus_message_iter_get_arg_type(&ai) != DBUS_TYPE_INVALID) {
+ const char *value;
+ char *uuid;
+
+ dbus_message_iter_get_basic(&ai, &value);
+
+ if (pa_hashmap_get(a->uuids, value)) {
+ dbus_message_iter_next(&ai);
+ continue;
+ }
+
+ uuid = pa_xstrdup(value);
+ pa_hashmap_put(a->uuids, uuid, uuid);
+
+ pa_log_debug("%s: %s", key, value);
+ dbus_message_iter_next(&ai);
+ }
+ pa_hook_fire(pa_bluetooth_discovery_hook(a->discovery, PA_BLUETOOTH_HOOK_ADAPTER_UUIDS_CHANGED), a);
+ }
}
dbus_message_iter_next(&element_i);
=====================================
src/modules/bluetooth/bluez5-util.h
=====================================
@@ -64,6 +64,7 @@ typedef struct pa_bluetooth_discovery pa_bluetooth_discovery;
typedef struct pa_bluetooth_backend pa_bluetooth_backend;
typedef enum pa_bluetooth_hook {
+ PA_BLUETOOTH_HOOK_ADAPTER_UUIDS_CHANGED, /* Call data: pa_bluetooth_adapter */
PA_BLUETOOTH_HOOK_DEVICE_CONNECTION_CHANGED, /* Call data: pa_bluetooth_device */
PA_BLUETOOTH_HOOK_DEVICE_UNLINK, /* Call data: pa_bluetooth_device */
PA_BLUETOOTH_HOOK_DEVICE_BATTERY_LEVEL_CHANGED, /* Call data: pa_bluetooth_device */
@@ -84,6 +85,13 @@ typedef enum profile {
} pa_bluetooth_profile_t;
#define PA_BLUETOOTH_PROFILE_COUNT PA_BLUETOOTH_PROFILE_OFF
+typedef enum pa_bluetooth_profile_status {
+ PA_BLUETOOTH_PROFILE_STATUS_INACTIVE,
+ PA_BLUETOOTH_PROFILE_STATUS_ACTIVE,
+ PA_BLUETOOTH_PROFILE_STATUS_REGISTERING,
+ PA_BLUETOOTH_PROFILE_STATUS_REGISTERED
+} pa_bluetooth_profile_status_t;
+
typedef enum pa_bluetooth_transport_state {
PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED,
PA_BLUETOOTH_TRANSPORT_STATE_IDLE,
@@ -163,6 +171,7 @@ struct pa_bluetooth_adapter {
pa_bluetooth_discovery *discovery;
char *path;
char *address;
+ pa_hashmap *uuids; /* char* -> char* (hashmap-as-a-set) */
bool valid;
bool application_registered;
@@ -191,6 +200,9 @@ static inline void pa_bluetooth_native_backend_free(pa_bluetooth_backend *b) {}
static inline void pa_bluetooth_native_backend_enable_shared_profiles(pa_bluetooth_backend *b, bool enable) {}
#endif
+pa_bluetooth_profile_status_t profile_status_get(pa_bluetooth_discovery *y, pa_bluetooth_profile_t profile);
+void profile_status_set(pa_bluetooth_discovery *y, pa_bluetooth_profile_t profile, pa_bluetooth_profile_status_t status);
+
pa_bluetooth_transport *pa_bluetooth_transport_new(pa_bluetooth_device *d, const char *owner, const char *path,
pa_bluetooth_profile_t p, const uint8_t *config, size_t size);
View it on GitLab: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/compare/a246bb77c745ed1d2571120a604a1e9ec6c3f88a...0b9ef4cd0ac2b38f6c2eb9b4673ec8ae16235659
--
View it on GitLab: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/compare/a246bb77c745ed1d2571120a604a1e9ec6c3f88a...0b9ef4cd0ac2b38f6c2eb9b4673ec8ae16235659
You're receiving this email because of your account on gitlab.freedesktop.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/pulseaudio-commits/attachments/20210730/32114c5d/attachment-0001.htm>
More information about the pulseaudio-commits
mailing list