From: Mikel Astiz <mikel.astiz@xxxxxxxxxxxx> Transport objects have an associated state even though it's not explicitly exposed in BlueZ's D-Bus API (prior to 5.0). Instead, the state is implicitly represented in the profile-specific D-Bus interface (i.e. org.bluez.Headset, org.bluez.AudioSink, etc.) but it can be convenient that bluetooth-util would abstract this separation. --- src/modules/bluetooth/bluetooth-util.c | 25 +++++++++++++++++++++++++ src/modules/bluetooth/bluetooth-util.h | 8 ++++++++ 2 files changed, 33 insertions(+) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 34def5a..d57f3ee 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -114,6 +114,21 @@ static int profile_from_interface(const char *interface, enum profile *p) { return -1; } +static pa_bluetooth_transport_state_t pa_bt_audio_state_to_transport_state(pa_bt_audio_state_t state) { + switch (state) { + case PA_BT_AUDIO_STATE_INVALID: /* Typically if state hasn't been received yet */ + case PA_BT_AUDIO_STATE_DISCONNECTED: + case PA_BT_AUDIO_STATE_CONNECTING: + return PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED; + case PA_BT_AUDIO_STATE_CONNECTED: + return PA_BLUETOOTH_TRANSPORT_STATE_IDLE; + case PA_BT_AUDIO_STATE_PLAYING: + return PA_BLUETOOTH_TRANSPORT_STATE_PLAYING; + } + + pa_assert_not_reached(); +} + static pa_bluetooth_uuid *uuid_new(const char *uuid) { pa_bluetooth_uuid *u; @@ -456,6 +471,7 @@ static int parse_device_property(pa_bluetooth_device *d, DBusMessageIter *i) { } static int parse_audio_property(pa_bluetooth_device *d, const char *interface, DBusMessageIter *i) { + pa_bluetooth_transport *transport; const char *key; DBusMessageIter variant_i; bool is_audio_interface; @@ -472,6 +488,8 @@ static int parse_audio_property(pa_bluetooth_device *d, const char *interface, D if (key == NULL) return -1; + transport = p == PROFILE_OFF ? NULL : d->transports[p]; + dbus_message_iter_recurse(i, &variant_i); /* pa_log_debug("Parsing property org.bluez.{Audio|AudioSink|AudioSource|Headset}.%s", key); */ @@ -499,6 +517,11 @@ static int parse_audio_property(pa_bluetooth_device *d, const char *interface, D pa_assert(p != PROFILE_OFF); d->profile_state[p] = state; + + if (!transport) + break; + + transport->state = pa_bt_audio_state_to_transport_state(state); } break; @@ -1094,6 +1117,8 @@ static pa_bluetooth_transport *transport_new(pa_bluetooth_device *d, const char memcpy(t->config, config, size); } + t->state = pa_bt_audio_state_to_transport_state(d->profile_state[p]); + for (i = 0; i < PA_BLUETOOTH_TRANSPORT_HOOK_MAX; i++) pa_hook_init(&t->hooks[i], t); diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h index 35f91df..cc8b08b 100644 --- a/src/modules/bluetooth/bluetooth-util.h +++ b/src/modules/bluetooth/bluetooth-util.h @@ -84,6 +84,12 @@ typedef enum pa_bluetooth_transport_hook { PA_BLUETOOTH_TRANSPORT_HOOK_MAX } pa_bluetooth_transport_hook_t; +typedef enum pa_bluetooth_transport_state { + PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED, + PA_BLUETOOTH_TRANSPORT_STATE_IDLE, /* Connected but not playing */ + PA_BLUETOOTH_TRANSPORT_STATE_PLAYING +} pa_bluetooth_transport_state_t; + struct pa_bluetooth_transport { pa_bluetooth_device *device; char *owner; @@ -92,6 +98,8 @@ struct pa_bluetooth_transport { uint8_t codec; uint8_t *config; int config_size; + + pa_bluetooth_transport_state_t state; pa_bool_t nrec; pa_hook hooks[PA_BLUETOOTH_TRANSPORT_HOOK_MAX]; -- 1.7.11.7