From: Mikel Astiz <mikel.astiz.oss@gmail.com>
To: linux-bluetooth@vger.kernel.org
Cc: Mikel Astiz <mikel.astiz@bmw-carit.de>
Subject: [RFC v5 2/4] media: Expose transport state in D-Bus
Date: Fri, 14 Sep 2012 14:55:58 +0200 [thread overview]
Message-ID: <1347627360-13997-3-git-send-email-mikel.astiz.oss@gmail.com> (raw)
In-Reply-To: <1347627360-13997-1-git-send-email-mikel.astiz.oss@gmail.com>
From: Mikel Astiz <mikel.astiz@bmw-carit.de>
Extend the Media API to expose the transport state in D-Bus, as a
property of the transport. This way the clients do not have to find
out which is the corresponding profile-specific interface for the
transport.
Additionally, this state along with the automatic release of transports
will allow clients to avoid the "optional release" or "accept remote
release" race condition. For example, with HSP/HFP profiles, the problem
is the following:
1. User suspends SCO in the remote end.
2. BlueZ signals the Playing->Connected state change in D-Bus.
3. Exactly afterwards, the user resumes SCO in the remote end.
4. In parallel, PulseAudio sees the aforementioned transition to
Connected, and thus releases the transport.
5. BlueZ receives a Release() request while SCO is up. So the audio
stream will be suspended.
The last step is an undesired behavior since the user explicitly wanted
to route the audio stream through Bluetooth.
The issue is difficult to reproduce but it can easily be solved by
exposing the transport state in D-Bus.
---
audio/transport.c | 29 +++++++++++++++++++++++++++++
doc/media-api.txt | 8 ++++++++
2 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/audio/transport.c b/audio/transport.c
index e0402ad..742cc72 100644
--- a/audio/transport.c
+++ b/audio/transport.c
@@ -155,6 +155,22 @@ static transport_lock_t str2lock(const char *str)
return lock;
}
+static const char *state2str(transport_state_t state)
+{
+ switch (state) {
+ case TRANSPORT_STATE_IDLE:
+ case TRANSPORT_STATE_REQUESTING:
+ return "idle";
+ case TRANSPORT_STATE_PENDING:
+ return "pending";
+ case TRANSPORT_STATE_ACTIVE:
+ case TRANSPORT_STATE_SUSPENDING:
+ return "active";
+ }
+
+ return NULL;
+}
+
static gboolean state_in_use(transport_state_t state)
{
switch (state) {
@@ -174,6 +190,7 @@ static void transport_set_state(struct media_transport *transport,
transport_state_t state)
{
transport_state_t old_state = transport->state;
+ const char *str;
if (old_state == state)
return;
@@ -182,6 +199,13 @@ static void transport_set_state(struct media_transport *transport,
DBG("State changed %s: %s -> %s", transport->path, str_state[old_state],
str_state[state]);
+
+ str = state2str(state);
+
+ if (g_strcmp0(str, state2str(old_state)) != 0)
+ emit_property_changed(transport->conn, transport->path,
+ MEDIA_TRANSPORT_INTERFACE, "State",
+ DBUS_TYPE_STRING, &str);
}
void media_transport_destroy(struct media_transport *transport)
@@ -1017,6 +1041,7 @@ void transport_get_properties(struct media_transport *transport,
DBusMessageIter dict;
const char *uuid;
uint8_t codec;
+ const char *state;
dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
@@ -1036,6 +1061,10 @@ void transport_get_properties(struct media_transport *transport,
dict_append_array(&dict, "Configuration", DBUS_TYPE_BYTE,
&transport->configuration, transport->size);
+ /* State */
+ state = state2str(transport->state);
+ dict_append_entry(&dict, "State", DBUS_TYPE_STRING, &state);
+
if (transport->get_properties)
transport->get_properties(transport, &dict);
diff --git a/doc/media-api.txt b/doc/media-api.txt
index e5eeaa0..da8ef53 100644
--- a/doc/media-api.txt
+++ b/doc/media-api.txt
@@ -317,6 +317,14 @@ Properties object Device [readonly]
Configuration blob, it is used as it is so the size and
byte order must match.
+ string State [readonly]
+
+ Indicates the state of the transport. Possible
+ values are:
+ "idle": not streaming
+ "pending": streaming but not acquired
+ "active": streaming and acquired
+
uint16 Delay [readwrite]
Optional. Transport delay in 1/10 of millisecond, this
--
1.7.7.6
next prev parent reply other threads:[~2012-09-14 12:55 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-09-14 12:55 [RFC v5 0/4] Optional acquire in Media API and related Mikel Astiz
2012-09-14 12:55 ` [RFC v5 1/4] media: Split transport state based on playing flag Mikel Astiz
2012-09-14 12:55 ` Mikel Astiz [this message]
2012-09-14 12:55 ` [RFC v5 3/4] media: Automatically release transport when HUP Mikel Astiz
2012-09-14 12:56 ` [RFC v5 4/4] media: Extend media API with optional acquire Mikel Astiz
2012-09-17 13:33 ` [RFC v5 0/4] Optional acquire in Media API and related Luiz Augusto von Dentz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1347627360-13997-3-git-send-email-mikel.astiz.oss@gmail.com \
--to=mikel.astiz.oss@gmail.com \
--cc=linux-bluetooth@vger.kernel.org \
--cc=mikel.astiz@bmw-carit.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox