From: Mikel Astiz <[email protected]>
The accessrights used in the Acquire() method are not very useful and can thus be removed. This simplifies both the D-Bus API and the internal implementation significantly.
Mikel Astiz (3):
media: Remove transport access type from D-Bus API
media: Remove internal transport locks
media: Remove transport owner list
doc/media-api.txt | 30 ++----
profiles/audio/transport.c | 238 ++++++++++-----------------------------------
2 files changed, 59 insertions(+), 209 deletions(-)
--
1.7.11.7
From: Mikel Astiz <[email protected]>
Transports now have zero or one owners, so there is no need to maintain
a list any more.
---
profiles/audio/transport.c | 80 +++++++++++++---------------------------------
1 file changed, 22 insertions(+), 58 deletions(-)
diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
index ad9270e..2075894 100644
--- a/profiles/audio/transport.c
+++ b/profiles/audio/transport.c
@@ -88,7 +88,7 @@ struct media_transport {
char *path; /* Transport object path */
struct audio_device *device; /* Transport device */
struct media_endpoint *endpoint; /* Transport endpoint */
- GSList *owners; /* Transport owners */
+ struct media_owner *owner; /* Transport owner */
uint8_t *configuration; /* Transport configuration */
int size; /* Transport configuration size */
int fd; /* Transport file descriptor */
@@ -241,24 +241,25 @@ static void media_owner_free(struct media_owner *owner)
g_free(owner);
}
-static void media_transport_remove(struct media_transport *transport,
- struct media_owner *owner)
+static void media_transport_remove_owner(struct media_transport *transport)
{
+ struct media_owner *owner = transport->owner;
+
DBG("Transport %s Owner %s", transport->path, owner->name);
/* Reply if owner has a pending request */
if (owner->pending)
media_request_reply(owner->pending, EIO);
- transport->owners = g_slist_remove(transport->owners, owner);
+ if (transport->owner == owner)
+ transport->owner = NULL;
if (owner->watch)
g_dbus_remove_watch(btd_get_dbus_connection(), owner->watch);
media_owner_free(owner);
- /* Suspend if there is no longer any owner */
- if (transport->owners == NULL && state_in_use(transport->state))
+ if (state_in_use(transport->state))
transport->suspend(transport, NULL);
}
@@ -319,7 +320,7 @@ static void a2dp_resume_complete(struct avdtp *session,
return;
fail:
- media_transport_remove(transport, owner);
+ media_transport_remove_owner(transport);
}
static guint resume_a2dp(struct media_transport *transport,
@@ -366,7 +367,7 @@ static void a2dp_suspend_complete(struct avdtp *session,
a2dp_sep_unlock(sep, a2dp->session);
transport_set_state(transport, TRANSPORT_STATE_IDLE);
- media_transport_remove(transport, owner);
+ media_transport_remove_owner(transport);
}
static guint suspend_a2dp(struct media_transport *transport,
@@ -399,14 +400,14 @@ static void media_owner_exit(DBusConnection *connection, void *user_data)
media_owner_remove(owner);
- media_transport_remove(owner->transport, owner);
+ media_transport_remove_owner(owner->transport);
}
-static void media_transport_add(struct media_transport *transport,
+static void media_transport_set_owner(struct media_transport *transport,
struct media_owner *owner)
{
DBG("Transport %s Owner %s", transport->path, owner->name);
- transport->owners = g_slist_append(transport->owners, owner);
+ transport->owner = owner;
owner->transport = transport;
owner->watch = g_dbus_add_disconnect_watch(btd_get_dbus_connection(),
owner->name,
@@ -435,29 +436,12 @@ static void media_owner_add(struct media_owner *owner,
owner->pending = req;
}
-static struct media_owner *media_transport_find_owner(
- struct media_transport *transport,
- const char *name)
-{
- GSList *l;
-
- for (l = transport->owners; l; l = l->next) {
- struct media_owner *owner = l->data;
-
- if (g_strcmp0(owner->name, name) == 0)
- return owner;
- }
-
- return NULL;
-}
-
static DBusMessage *acquire(DBusConnection *conn, DBusMessage *msg,
void *data)
{
struct media_transport *transport = data;
struct media_owner *owner;
struct media_request *req;
- const char *sender;
dbus_bool_t optional;
guint id;
@@ -466,10 +450,7 @@ static DBusMessage *acquire(DBusConnection *conn, DBusMessage *msg,
DBUS_TYPE_INVALID))
return btd_error_invalid_args(msg);
- sender = dbus_message_get_sender(msg);
-
- owner = media_transport_find_owner(transport, sender);
- if (owner != NULL)
+ if (transport->owner != NULL)
return btd_error_not_authorized(msg);
if (transport->state >= TRANSPORT_STATE_REQUESTING)
@@ -487,7 +468,7 @@ static DBusMessage *acquire(DBusConnection *conn, DBusMessage *msg,
req = media_request_create(msg, id);
media_owner_add(owner, req);
- media_transport_add(transport, owner);
+ media_transport_set_owner(transport, owner);
return NULL;
}
@@ -496,23 +477,16 @@ static DBusMessage *release(DBusConnection *conn, DBusMessage *msg,
void *data)
{
struct media_transport *transport = data;
- struct media_owner *owner;
+ struct media_owner *owner = transport->owner;
const char *sender;
struct media_request *req;
guint id;
sender = dbus_message_get_sender(msg);
- owner = media_transport_find_owner(transport, sender);
- if (owner == NULL)
+ if (owner == NULL || g_strcmp0(owner->name, sender) != 0)
return btd_error_not_authorized(msg);
- /* Not the last owner, no need to suspend */
- if (g_slist_length(transport->owners) != 1) {
- media_transport_remove(transport, owner);
- return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
- }
-
if (owner->pending) {
const char *member;
@@ -528,7 +502,7 @@ static DBusMessage *release(DBusConnection *conn, DBusMessage *msg,
id = transport->suspend(transport, owner);
if (id == 0) {
- media_transport_remove(transport, owner);
+ media_transport_remove_owner(transport);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
@@ -698,15 +672,9 @@ static void destroy_a2dp(void *data)
static void media_transport_free(void *data)
{
struct media_transport *transport = data;
- GSList *l = transport->owners;
- while (l) {
- struct media_owner *owner = l->data;
- l = l->next;
- media_transport_remove(transport, owner);
- }
-
- g_slist_free(transport->owners);
+ if (transport->owner)
+ media_transport_remove_owner(transport);
if (transport->destroy != NULL)
transport->destroy(transport->data);
@@ -726,13 +694,9 @@ static void transport_update_playing(struct media_transport *transport,
if (transport->state == TRANSPORT_STATE_PENDING)
transport_set_state(transport, TRANSPORT_STATE_IDLE);
else if (transport->state == TRANSPORT_STATE_ACTIVE) {
- /* Remove all owners */
- while (transport->owners != NULL) {
- struct media_owner *owner;
-
- owner = transport->owners->data;
- media_transport_remove(transport, owner);
- }
+ /* Remove owner */
+ if (transport->owner != NULL)
+ media_transport_remove_owner(transport);
}
} else if (transport->state == TRANSPORT_STATE_IDLE)
transport_set_state(transport, TRANSPORT_STATE_PENDING);
--
1.7.11.7
From: Mikel Astiz <[email protected]>
The internal transport_lock_t is not needed any more since transports
are now always acquired with read and write permissions.
---
profiles/audio/transport.c | 134 ++++++++++-----------------------------------
1 file changed, 30 insertions(+), 104 deletions(-)
diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
index 5924f73..ad9270e 100644
--- a/profiles/audio/transport.c
+++ b/profiles/audio/transport.c
@@ -51,11 +51,6 @@
#define MEDIA_TRANSPORT_INTERFACE "org.bluez.MediaTransport"
typedef enum {
- TRANSPORT_LOCK_READ = 1,
- TRANSPORT_LOCK_WRITE = 1 << 1,
-} transport_lock_t;
-
-typedef enum {
TRANSPORT_STATE_IDLE, /* Not acquired and suspended */
TRANSPORT_STATE_PENDING, /* Playing but not acquired */
TRANSPORT_STATE_REQUESTING, /* Acquire in progress */
@@ -80,7 +75,6 @@ struct media_owner {
struct media_transport *transport;
struct media_request *pending;
char *name;
- transport_lock_t lock;
guint watch;
};
@@ -100,7 +94,6 @@ struct media_transport {
int fd; /* Transport file descriptor */
uint16_t imtu; /* Transport input mtu */
uint16_t omtu; /* Transport output mtu */
- transport_lock_t lock;
transport_state_t state;
guint hs_watch;
guint source_watch;
@@ -115,18 +108,6 @@ struct media_transport {
void *data;
};
-static const char *lock2str(transport_lock_t lock)
-{
- if (lock == 0)
- return "";
- else if (lock == TRANSPORT_LOCK_READ)
- return "r";
- else if (lock == TRANSPORT_LOCK_WRITE)
- return "w";
- else
- return "rw";
-}
-
static const char *state2str(transport_state_t state)
{
switch (state) {
@@ -229,20 +210,6 @@ static void media_request_reply(struct media_request *req, int err)
g_dbus_send_message(btd_get_dbus_connection(), reply);
}
-static gboolean media_transport_release(struct media_transport *transport,
- transport_lock_t lock)
-{
- transport->lock &= ~lock;
-
- if (lock & TRANSPORT_LOCK_READ)
- DBG("Transport %s: read lock released", transport->path);
-
- if (lock & TRANSPORT_LOCK_WRITE)
- DBG("Transport %s: write lock released", transport->path);
-
- return TRUE;
-}
-
static void media_owner_remove(struct media_owner *owner)
{
struct media_transport *transport = owner->transport;
@@ -279,8 +246,6 @@ static void media_transport_remove(struct media_transport *transport,
{
DBG("Transport %s Owner %s", transport->path, owner->name);
- media_transport_release(transport, owner->lock);
-
/* Reply if owner has a pending request */
if (owner->pending)
media_request_reply(owner->pending, EIO);
@@ -339,12 +304,6 @@ static void a2dp_resume_complete(struct avdtp *session,
media_transport_set_fd(transport, fd, imtu, omtu);
- if ((owner->lock & TRANSPORT_LOCK_READ) == 0)
- imtu = 0;
-
- if ((owner->lock & TRANSPORT_LOCK_WRITE) == 0)
- omtu = 0;
-
ret = g_dbus_send_reply(btd_get_dbus_connection(), req->msg,
DBUS_TYPE_UNIX_FD, &fd,
DBUS_TYPE_UINT16, &imtu,
@@ -443,24 +402,6 @@ static void media_owner_exit(DBusConnection *connection, void *user_data)
media_transport_remove(owner->transport, owner);
}
-static gboolean media_transport_acquire(struct media_transport *transport,
- transport_lock_t lock)
-{
- if (transport->lock & lock)
- return FALSE;
-
- transport->lock |= lock;
-
- if (lock & TRANSPORT_LOCK_READ)
- DBG("Transport %s: read lock acquired", transport->path);
-
- if (lock & TRANSPORT_LOCK_WRITE)
- DBG("Transport %s: write lock acquired", transport->path);
-
-
- return TRUE;
-}
-
static void media_transport_add(struct media_transport *transport,
struct media_owner *owner)
{
@@ -473,17 +414,14 @@ static void media_transport_add(struct media_transport *transport,
owner, NULL);
}
-static struct media_owner *media_owner_create(DBusMessage *msg,
- transport_lock_t lock)
+static struct media_owner *media_owner_create(DBusMessage *msg)
{
struct media_owner *owner;
owner = g_new0(struct media_owner, 1);
owner->name = g_strdup(dbus_message_get_sender(msg));
- owner->lock = lock;
- DBG("Owner created: sender=%s accesstype=%s", owner->name,
- lock2str(lock));
+ DBG("Owner created: sender=%s", owner->name);
return owner;
}
@@ -522,7 +460,6 @@ static DBusMessage *acquire(DBusConnection *conn, DBusMessage *msg,
const char *sender;
dbus_bool_t optional;
guint id;
- transport_lock_t lock = TRANSPORT_LOCK_READ | TRANSPORT_LOCK_WRITE;
if (!dbus_message_get_args(msg, NULL,
DBUS_TYPE_BOOLEAN, &optional,
@@ -535,16 +472,15 @@ static DBusMessage *acquire(DBusConnection *conn, DBusMessage *msg,
if (owner != NULL)
return btd_error_not_authorized(msg);
+ if (transport->state >= TRANSPORT_STATE_REQUESTING)
+ return btd_error_not_authorized(msg);
+
if (transport->state != TRANSPORT_STATE_PENDING && optional)
return btd_error_failed(msg, "Transport not playing");
- if (media_transport_acquire(transport, lock) == FALSE)
- return btd_error_not_authorized(msg);
-
- owner = media_owner_create(msg, lock);
+ owner = media_owner_create(msg);
id = transport->resume(transport, owner);
if (id == 0) {
- media_transport_release(transport, lock);
media_owner_free(owner);
return btd_error_not_authorized(msg);
}
@@ -563,7 +499,7 @@ static DBusMessage *release(DBusConnection *conn, DBusMessage *msg,
struct media_owner *owner;
const char *sender;
struct media_request *req;
- transport_lock_t lock = TRANSPORT_LOCK_READ | TRANSPORT_LOCK_WRITE;
+ guint id;
sender = dbus_message_get_sender(msg);
@@ -571,45 +507,35 @@ static DBusMessage *release(DBusConnection *conn, DBusMessage *msg,
if (owner == NULL)
return btd_error_not_authorized(msg);
- if (owner->lock == lock) {
- guint id;
-
- /* Not the last owner, no need to suspend */
- if (g_slist_length(transport->owners) != 1) {
- media_transport_remove(transport, owner);
- return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
- }
-
- if (owner->pending) {
- const char *member;
+ /* Not the last owner, no need to suspend */
+ if (g_slist_length(transport->owners) != 1) {
+ media_transport_remove(transport, owner);
+ return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+ }
- member = dbus_message_get_member(owner->pending->msg);
- /* Cancel Acquire request if that exist */
- if (g_str_equal(member, "Acquire"))
- media_owner_remove(owner);
- else
- return btd_error_in_progress(msg);
- }
+ if (owner->pending) {
+ const char *member;
- transport_set_state(transport, TRANSPORT_STATE_SUSPENDING);
+ member = dbus_message_get_member(owner->pending->msg);
+ /* Cancel Acquire request if that exist */
+ if (g_str_equal(member, "Acquire"))
+ media_owner_remove(owner);
+ else
+ return btd_error_in_progress(msg);
+ }
- id = transport->suspend(transport, owner);
- if (id == 0) {
- media_transport_remove(transport, owner);
- return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
- }
+ transport_set_state(transport, TRANSPORT_STATE_SUSPENDING);
- req = media_request_create(msg, id);
- media_owner_add(owner, req);
+ id = transport->suspend(transport, owner);
+ if (id == 0) {
+ media_transport_remove(transport, owner);
+ return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+ }
- return NULL;
- } else if ((owner->lock & lock) == lock) {
- media_transport_release(transport, lock);
- owner->lock &= ~lock;
- } else
- return btd_error_not_authorized(msg);
+ req = media_request_create(msg, id);
+ media_owner_add(owner, req);
- return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+ return NULL;
}
static gboolean get_device(const GDBusPropertyTable *property,
--
1.7.11.7
From: Mikel Astiz <[email protected]>
There is no known use-case making use of these access types and
therefore the Media API can be simplified.
>From now on, the transport will always be acquired with read and write
access rights.
---
doc/media-api.txt | 30 ++++++++----------------------
profiles/audio/transport.c | 44 +++++++++-----------------------------------
2 files changed, 17 insertions(+), 57 deletions(-)
diff --git a/doc/media-api.txt b/doc/media-api.txt
index cf69efa..cb5d9a3 100644
--- a/doc/media-api.txt
+++ b/doc/media-api.txt
@@ -261,31 +261,17 @@ Service org.bluez
Interface org.bluez.MediaTransport
Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/fdX
-Methods fd, uint16, uint16 Acquire(string accesstype)
+Methods fd, uint16, uint16 Acquire(boolean optional)
- Acquire transport file descriptor and the MTU for read
- and write respectively.
+ Acquire transport (with read and write rights) and
+ return the file descriptor and the MTU.
- possible accesstype:
+ The optional flag specifies that the transport will be
+ acquired only if it's in "pending" state, and will
+ otherwise fail. This means no request will be sent to
+ the remote side.
- "r" : Read only access
-
- "w" : Write only access
-
- "rw": Read and write access
-
- The accesstype string can also be combined with a "?"
- suffix, which will make the request optional. This
- typically means the transport will only be acquired if
- it is already available (remote-initiated), but
- otherwise no request will be sent to the remote side.
- In this last case the function will fail. Note that,
- due to compatibility issues with older versions of
- BlueZ, clients are encouraged to use exactly the same
- accesstype for Release(), matching the string provided
- to Acquire().
-
- void Release(string accesstype)
+ void Release()
Releases file descriptor.
diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
index 610aca3..5924f73 100644
--- a/profiles/audio/transport.c
+++ b/profiles/audio/transport.c
@@ -127,19 +127,6 @@ static const char *lock2str(transport_lock_t lock)
return "rw";
}
-static transport_lock_t str2lock(const char *str)
-{
- transport_lock_t lock = 0;
-
- if (g_strstr_len(str, -1, "r") != NULL)
- lock |= TRANSPORT_LOCK_READ;
-
- if (g_strstr_len(str, -1, "w") != NULL)
- lock |= TRANSPORT_LOCK_WRITE;
-
- return lock;
-}
-
static const char *state2str(transport_state_t state)
{
switch (state) {
@@ -532,12 +519,13 @@ static DBusMessage *acquire(DBusConnection *conn, DBusMessage *msg,
struct media_transport *transport = data;
struct media_owner *owner;
struct media_request *req;
- const char *accesstype, *sender;
- transport_lock_t lock;
+ const char *sender;
+ dbus_bool_t optional;
guint id;
+ transport_lock_t lock = TRANSPORT_LOCK_READ | TRANSPORT_LOCK_WRITE;
if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_STRING, &accesstype,
+ DBUS_TYPE_BOOLEAN, &optional,
DBUS_TYPE_INVALID))
return btd_error_invalid_args(msg);
@@ -547,12 +535,7 @@ static DBusMessage *acquire(DBusConnection *conn, DBusMessage *msg,
if (owner != NULL)
return btd_error_not_authorized(msg);
- lock = str2lock(accesstype);
- if (lock == 0)
- return btd_error_invalid_args(msg);
-
- if (transport->state != TRANSPORT_STATE_PENDING &&
- g_strstr_len(accesstype, -1, "?") != NULL)
+ if (transport->state != TRANSPORT_STATE_PENDING && optional)
return btd_error_failed(msg, "Transport not playing");
if (media_transport_acquire(transport, lock) == FALSE)
@@ -578,14 +561,9 @@ static DBusMessage *release(DBusConnection *conn, DBusMessage *msg,
{
struct media_transport *transport = data;
struct media_owner *owner;
- const char *accesstype, *sender;
- transport_lock_t lock;
+ const char *sender;
struct media_request *req;
-
- if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_STRING, &accesstype,
- DBUS_TYPE_INVALID))
- return btd_error_invalid_args(msg);
+ transport_lock_t lock = TRANSPORT_LOCK_READ | TRANSPORT_LOCK_WRITE;
sender = dbus_message_get_sender(msg);
@@ -593,8 +571,6 @@ static DBusMessage *release(DBusConnection *conn, DBusMessage *msg,
if (owner == NULL)
return btd_error_not_authorized(msg);
- lock = str2lock(accesstype);
-
if (owner->lock == lock) {
guint id;
@@ -764,13 +740,11 @@ static void set_volume(const GDBusPropertyTable *property,
static const GDBusMethodTable transport_methods[] = {
{ GDBUS_ASYNC_METHOD("Acquire",
- GDBUS_ARGS({ "access_type", "s" }),
+ GDBUS_ARGS({ "optional", "b" }),
GDBUS_ARGS({ "fd", "h" }, { "mtu_r", "q" },
{ "mtu_w", "q" } ),
acquire) },
- { GDBUS_ASYNC_METHOD("Release",
- GDBUS_ARGS({ "access_type", "s" }), NULL,
- release ) },
+ { GDBUS_ASYNC_METHOD("Release", NULL, NULL, release) },
{ },
};
--
1.7.11.7