2015-02-24 12:26:43

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv0 0/6] Audio deduplication part 3

From: Andrei Emeltchenko <[email protected]>

3rd series of patches for avdtp & a2dp deduplication.

Andrei Emeltchenko (6):
tools/gatt: Fix incorrect error check
audio/avdtp: Copy SEP list to avdtp session
audio/avdtp: Refactor avdtp_new
audio/avdtp: Add stream related debugs
audio/avdtp: Remove avdtp_server from avdtp code
audio/avdtp: Move connection logic from avdtp to a2dp

profiles/audio/a2dp.c | 52 +++++++++++++++--
profiles/audio/a2dp.h | 4 ++
profiles/audio/avdtp.c | 137 +++++++++++++++++++++------------------------
profiles/audio/avdtp.h | 7 ++-
profiles/audio/media.c | 2 +
profiles/audio/sink.c | 2 +
profiles/audio/source.c | 2 +
profiles/audio/transport.c | 2 +
tools/btgatt-client.c | 2 +-
9 files changed, 127 insertions(+), 83 deletions(-)

--
2.1.0



2015-02-24 12:57:39

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [RFCv0 3/6] audio/avdtp: Refactor avdtp_new

Hi Andrei,

On Tue, Feb 24, 2015 at 2:26 PM, Andrei Emeltchenko
<[email protected]> wrote:
> From: Andrei Emeltchenko <[email protected]>
>
> avdtp_new() is split to avdtp_new() and avdtp_transport_connect() which
> takes care about opening transport channel.
> ---
> profiles/audio/a2dp.c | 10 +++++++---
> profiles/audio/avdtp.c | 20 ++++++++++++--------
> profiles/audio/avdtp.h | 2 +-
> 3 files changed, 20 insertions(+), 12 deletions(-)
>
> diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
> index 6a86c19..e669f43 100644
> --- a/profiles/audio/a2dp.c
> +++ b/profiles/audio/a2dp.c
> @@ -1222,7 +1222,7 @@ struct avdtp *a2dp_avdtp_get(struct btd_device *device)
> if (server == NULL)
> return NULL;
>
> - session = avdtp_new(server, server->sessions, NULL, device);
> + session = avdtp_new(server, server->sessions, device);
> if (!session)
> return NULL;
>
> @@ -1328,11 +1328,15 @@ static void avdtp_confirm_cb(GIOChannel *chan, gpointer data)
> if (!avdtp_server)
> goto drop;
>
> - session = avdtp_new(avdtp_server, avdtp_server->sessions, chan, device);
> + session = avdtp_new(avdtp_server, avdtp_server->sessions, device);
> if (!session)
> goto drop;
>
> - avdtp_request_authorization(session, &src, &dst, auth_cb);
> +
> + if (avdtp_transport_connect(session, chan)) {
> + btd_device_add_uuid(device, ADVANCED_AUDIO_UUID);
> + avdtp_request_authorization(session, &src, &dst, auth_cb);
> + }

What is going on here, why you are not using the same API as in
android again? what is wrong with avdtp_stream_set_transport?

> return;
>
> diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
> index 1a16170..aaaf3b2 100644
> --- a/profiles/audio/avdtp.c
> +++ b/profiles/audio/avdtp.c
> @@ -2374,7 +2374,6 @@ failed:
> }
>
> struct avdtp *avdtp_new(struct avdtp_server *server, GSList *sessions,
> - GIOChannel *chan,
> struct btd_device *device)
> {
> struct avdtp *session;
> @@ -2396,9 +2395,14 @@ struct avdtp *avdtp_new(struct avdtp_server *server, GSList *sessions,
> server->sessions = g_slist_append(server->sessions, session);
>
> session->lseps = server->seps;
> - if (!chan)
> - return session;
>
> + DBG("Created session %p added to server %p", session, server);
> +
> + return session;
> +}
> +
> +bool avdtp_transport_connect(struct avdtp *session, GIOChannel *chan)
> +{
> /* This state (ie, session is already *connecting*) happens when the
> * device initiates a connect (really a config'd L2CAP channel) even
> * though there is a connect we initiated in progress. In sink.c &
> @@ -2414,7 +2418,7 @@ struct avdtp *avdtp_new(struct avdtp_server *server, GSList *sessions,
> if (!bt_io_accept(chan, avdtp_connect_cb, session, NULL, NULL))
> goto drop;
>
> - return NULL;
> + return false;
> }
>
> if (session->io) {
> @@ -2422,17 +2426,17 @@ struct avdtp *avdtp_new(struct avdtp_server *server, GSList *sessions,
> goto drop;
> }
>
> - btd_device_add_uuid(device, ADVANCED_AUDIO_UUID);
> -
> session->io = g_io_channel_ref(chan);
> avdtp_set_state(session, AVDTP_SESSION_STATE_CONNECTING);
>
> session->io_id = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
> (GIOFunc) session_cb, session);
>
> - return session;
> + return true;
> +
> drop:
> - return NULL;
> + g_io_channel_shutdown(chan, TRUE, NULL);
> + return false;
> }
>
> bool avdtp_request_authorization(struct avdtp *session, const bdaddr_t *src,
> diff --git a/profiles/audio/avdtp.h b/profiles/audio/avdtp.h
> index c2c223a..4aa3936 100644
> --- a/profiles/audio/avdtp.h
> +++ b/profiles/audio/avdtp.h
> @@ -294,8 +294,8 @@ struct btd_device *avdtp_get_device(struct avdtp *session);
> struct avdtp_server *avdtp_get_server(struct avdtp_local_sep *lsep);
>
> struct avdtp *avdtp_new(struct avdtp_server *server, GSList *sessions,
> - GIOChannel *chan,
> struct btd_device *device);
> +bool avdtp_transport_connect(struct avdtp *session, GIOChannel *chan);
> void avdtp_free(void *data);
> void connection_lost(struct avdtp *session, int err);
> void avdtp_accept(struct avdtp *session);
> --
> 2.1.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html



--
Luiz Augusto von Dentz

2015-02-24 12:26:49

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv0 6/6] audio/avdtp: Move connection logic from avdtp to a2dp

From: Andrei Emeltchenko <[email protected]>

l2cap connection logic moved from avdtp.c to a2dp.c
---
profiles/audio/a2dp.c | 24 ++++++++++++++++++++++++
profiles/audio/a2dp.h | 1 +
profiles/audio/avdtp.c | 29 ++---------------------------
profiles/audio/media.c | 2 ++
profiles/audio/sink.c | 2 ++
profiles/audio/source.c | 2 ++
profiles/audio/transport.c | 2 ++
7 files changed, 35 insertions(+), 27 deletions(-)

diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index c96971f..e23455a 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -1265,6 +1265,30 @@ static void avdtp_server_destroy(struct avdtp_server *server)
g_free(server);
}

+GIOChannel *l2cap_connect(struct avdtp *session, BtIOConnect cb)
+{
+ GError *err = NULL;
+ GIOChannel *io;
+ const bdaddr_t *src;
+
+ src = btd_adapter_get_address(avdtp_get_adapter(session));
+
+ io = bt_io_connect(cb, session, NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, src,
+ BT_IO_OPT_DEST_BDADDR,
+ device_get_address(avdtp_get_device(session)),
+ BT_IO_OPT_PSM, AVDTP_PSM,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+ BT_IO_OPT_INVALID);
+ if (!io) {
+ error("%s", err->message);
+ g_error_free(err);
+ return NULL;
+ }
+
+ return io;
+}
+
static void a2dp_clean_lsep(struct a2dp_sep *sep)
{
struct avdtp_local_sep *lsep = sep->lsep;
diff --git a/profiles/audio/a2dp.h b/profiles/audio/a2dp.h
index fdcc528..a4d6947 100644
--- a/profiles/audio/a2dp.h
+++ b/profiles/audio/a2dp.h
@@ -91,3 +91,4 @@ struct avdtp *a2dp_avdtp_get(struct btd_device *device);
void avdtp_server_remove_session(struct avdtp_server *server,
struct avdtp *session);
struct btd_adapter *avdtp_server_get_adapter(struct avdtp_server *server);
+GIOChannel *l2cap_connect(struct avdtp *session, BtIOConnect cb);
diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index 05b3d2c..1ea9fe4 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -2454,31 +2454,6 @@ bool avdtp_request_authorization(struct avdtp *session, const bdaddr_t *src,
return true;
}

-static GIOChannel *l2cap_connect(struct avdtp *session)
-{
- GError *err = NULL;
- GIOChannel *io;
- const bdaddr_t *src;
-
- src = btd_adapter_get_address(avdtp_get_adapter(session));
-
- io = bt_io_connect(avdtp_connect_cb, session,
- NULL, &err,
- BT_IO_OPT_SOURCE_BDADDR, src,
- BT_IO_OPT_DEST_BDADDR,
- device_get_address(session->device),
- BT_IO_OPT_PSM, AVDTP_PSM,
- BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
- BT_IO_OPT_INVALID);
- if (!io) {
- error("%s", err->message);
- g_error_free(err);
- return NULL;
- }
-
- return io;
-}
-
static void queue_request(struct avdtp *session, struct pending_req *req,
gboolean priority)
{
@@ -2614,7 +2589,7 @@ static int send_req(struct avdtp *session, gboolean priority,
int err;

if (session->state == AVDTP_SESSION_STATE_DISCONNECTED) {
- session->io = l2cap_connect(session);
+ session->io = l2cap_connect(session, avdtp_connect_cb);
if (!session->io) {
err = -EIO;
goto failed;
@@ -2796,7 +2771,7 @@ static gboolean avdtp_open_resp(struct avdtp *session, struct avdtp_stream *stre
{
struct avdtp_local_sep *sep = stream->lsep;

- stream->io = l2cap_connect(session);
+ stream->io = l2cap_connect(session, avdtp_connect_cb);
if (!stream->io) {
avdtp_sep_set_state(session, sep, AVDTP_STATE_IDLE);
return FALSE;
diff --git a/profiles/audio/media.c b/profiles/audio/media.c
index 633695c..18fe2c1 100644
--- a/profiles/audio/media.c
+++ b/profiles/audio/media.c
@@ -46,6 +46,8 @@
#include "src/error.h"
#include "src/shared/queue.h"

+#include "btio/btio.h"
+
#include "avdtp.h"
#include "media.h"
#include "transport.h"
diff --git a/profiles/audio/sink.c b/profiles/audio/sink.c
index 7cf22d9..ad4bbaa 100644
--- a/profiles/audio/sink.c
+++ b/profiles/audio/sink.c
@@ -46,6 +46,8 @@
#include "src/dbus-common.h"
#include "src/shared/queue.h"

+#include "btio/btio.h"
+
#include "avdtp.h"
#include "media.h"
#include "a2dp.h"
diff --git a/profiles/audio/source.c b/profiles/audio/source.c
index fd68917..039157c 100644
--- a/profiles/audio/source.c
+++ b/profiles/audio/source.c
@@ -47,6 +47,8 @@
#include "src/dbus-common.h"
#include "src/shared/queue.h"

+#include "btio/btio.h"
+
#include "avdtp.h"
#include "media.h"
#include "a2dp.h"
diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
index a267bfd..ca11a86 100644
--- a/profiles/audio/transport.c
+++ b/profiles/audio/transport.c
@@ -41,6 +41,8 @@
#include "src/error.h"
#include "src/shared/queue.h"

+#include "btio/btio.h"
+
#include "avdtp.h"
#include "media.h"
#include "transport.h"
--
2.1.0


2015-02-24 12:26:44

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv0 1/6] tools/gatt: Fix incorrect error check

From: Andrei Emeltchenko <[email protected]>

---
tools/btgatt-client.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/btgatt-client.c b/tools/btgatt-client.c
index e59d5db..25ace4a 100644
--- a/tools/btgatt-client.c
+++ b/tools/btgatt-client.c
@@ -1021,7 +1021,7 @@ static void cmd_set_sec_level(struct client *cli, char *cmd_str)
return;
}

- if (bt_gatt_client_set_sec_level(cli->gatt, level) < 0)
+ if (!bt_gatt_client_set_sec_level(cli->gatt, level))
printf("Could not set sec level\n");
else
printf("Setting security level %d success\n", level);
--
2.1.0


2015-02-24 12:26:47

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv0 4/6] audio/avdtp: Add stream related debugs

From: Andrei Emeltchenko <[email protected]>

---
profiles/audio/avdtp.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index aaaf3b2..0296700 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -969,7 +969,7 @@ static void avdtp_sep_set_state(struct avdtp *session,
err_ptr = &err;
} else {
err_ptr = NULL;
- DBG("stream state changed: %s -> %s",
+ DBG("stream %p state changed: %s -> %s", stream,
avdtp_statestr(sep->state),
avdtp_statestr(state));
}
@@ -1025,6 +1025,8 @@ static void avdtp_sep_set_state(struct avdtp *session,
if (state == AVDTP_STATE_IDLE &&
g_slist_find(session->streams, stream)) {
session->streams = g_slist_remove(session->streams, stream);
+
+ DBG("stream %p removed from session %p", stream, session);
stream_free(stream);
}
}
@@ -1428,6 +1430,8 @@ static void setconf_cb(struct avdtp *session, struct avdtp_stream *stream,
sep->info.inuse = 1;
session->streams = g_slist_append(session->streams, stream);

+ DBG("stream %p added to session %p", stream, session);
+
avdtp_sep_set_state(session, sep, AVDTP_STATE_CONFIGURED);
}

@@ -1530,6 +1534,8 @@ static gboolean avdtp_setconf_cmd(struct avdtp *session, uint8_t transaction,
sep->info.inuse = 1;
session->streams = g_slist_append(session->streams, stream);

+ DBG("stream %p added to session %p", stream, session);
+
avdtp_sep_set_state(session, sep, AVDTP_STATE_CONFIGURED);
}

@@ -3352,7 +3358,7 @@ int avdtp_set_configuration(struct avdtp *session,
if (!(lsep && rsep))
return -EINVAL;

- DBG("%p: int_seid=%u, acp_seid=%u", session,
+ DBG("session %p: int_seid=%u, acp_seid=%u", session,
lsep->info.seid, rsep->seid);

new_stream = g_new0(struct avdtp_stream, 1);
@@ -3360,6 +3366,8 @@ int avdtp_set_configuration(struct avdtp *session,
new_stream->lsep = lsep;
new_stream->rseid = rsep->seid;

+ DBG("new_stream %p session %p", new_stream, session);
+
if (rsep->delay_reporting && lsep->delay_reporting) {
struct avdtp_service_capability *delay_reporting;

@@ -3399,6 +3407,9 @@ int avdtp_set_configuration(struct avdtp *session,
lsep->stream = new_stream;
rsep->stream = new_stream;
session->streams = g_slist_append(session->streams, new_stream);
+
+ DBG("stream %p added to session %p", new_stream, session);
+
if (stream)
*stream = new_stream;
}
@@ -3445,11 +3456,15 @@ int avdtp_start(struct avdtp *session, struct avdtp_stream *stream)
struct start_req req;
int ret;

- if (!g_slist_find(session->streams, stream))
+ if (!g_slist_find(session->streams, stream)) {
+ DBG("Cannot find stream %p in session %p", stream, session);
return -EINVAL;
+ }

- if (stream->lsep->state != AVDTP_STATE_OPEN)
+ if (stream->lsep->state != AVDTP_STATE_OPEN) {
+ DBG("Wrong stream state %d", stream->lsep->state);
return -EINVAL;
+ }

/* Recommendation 12:
* If the RD has configured and opened a stream it is also responsible
--
2.1.0


2015-02-24 12:26:48

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv0 5/6] audio/avdtp: Remove avdtp_server from avdtp code

From: Andrei Emeltchenko <[email protected]>

Finishing removing avdtp_server code from avdtp.c. At the moment code is
moved to a2dp.c
---
profiles/audio/a2dp.c | 22 ++++++++++++++++++----
profiles/audio/a2dp.h | 3 +++
profiles/audio/avdtp.c | 41 ++++++++++++++++++-----------------------
profiles/audio/avdtp.h | 5 +++--
4 files changed, 42 insertions(+), 29 deletions(-)

diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index e669f43..c96971f 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -120,7 +120,7 @@ struct avdtp_server {
struct btd_adapter *adapter;
GIOChannel *io;
struct queue *seps;
- GSList *sessions;
+ struct queue *sessions;
};

static GSList *servers = NULL;
@@ -1222,7 +1222,7 @@ struct avdtp *a2dp_avdtp_get(struct btd_device *device)
if (server == NULL)
return NULL;

- session = avdtp_new(server, server->sessions, device);
+ session = avdtp_new(server, server->sessions, device, server->seps);
if (!session)
return NULL;

@@ -1240,9 +1240,20 @@ static struct a2dp_server *a2dp_server_register(struct btd_adapter *adapter)
return server;
}

+void avdtp_server_remove_session(struct avdtp_server *server,
+ struct avdtp *session)
+{
+ queue_remove(server->sessions, session);
+}
+
+struct btd_adapter *avdtp_server_get_adapter(struct avdtp_server *server)
+{
+ return server->adapter;
+}
+
static void avdtp_server_destroy(struct avdtp_server *server)
{
- g_slist_free_full(server->sessions, avdtp_free);
+ queue_destroy(server->sessions, avdtp_free);

avdtp_servers = g_slist_remove(avdtp_servers, server);

@@ -1250,6 +1261,7 @@ static void avdtp_server_destroy(struct avdtp_server *server)
g_io_channel_unref(server->io);
btd_adapter_unref(server->adapter);
queue_destroy(server->seps, NULL);
+ queue_destroy(server->sessions, NULL);
g_free(server);
}

@@ -1328,7 +1340,8 @@ static void avdtp_confirm_cb(GIOChannel *chan, gpointer data)
if (!avdtp_server)
goto drop;

- session = avdtp_new(avdtp_server, avdtp_server->sessions, device);
+ session = avdtp_new(avdtp_server, avdtp_server->sessions, device,
+ avdtp_server->seps);
if (!session)
goto drop;

@@ -1379,6 +1392,7 @@ static struct avdtp_server *avdtp_server_init(struct btd_adapter *adapter)

server->adapter = btd_adapter_ref(adapter);
server->seps = queue_new();
+ server->sessions = queue_new();

avdtp_servers = g_slist_append(avdtp_servers, server);

diff --git a/profiles/audio/a2dp.h b/profiles/audio/a2dp.h
index 544eea1..fdcc528 100644
--- a/profiles/audio/a2dp.h
+++ b/profiles/audio/a2dp.h
@@ -88,3 +88,6 @@ gboolean a2dp_sep_unlock(struct a2dp_sep *sep, struct avdtp *session);
struct avdtp_stream *a2dp_sep_get_stream(struct a2dp_sep *sep);
struct btd_device *a2dp_setup_get_device(struct a2dp_setup *setup);
struct avdtp *a2dp_avdtp_get(struct btd_device *device);
+void avdtp_server_remove_session(struct avdtp_server *server,
+ struct avdtp *session);
+struct btd_adapter *avdtp_server_get_adapter(struct avdtp_server *server);
diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index 0296700..05b3d2c 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -50,6 +50,7 @@
#include "src/device.h"

#include "avdtp.h"
+#include "a2dp.h"
#include "sink.h"
#include "source.h"

@@ -324,13 +325,6 @@ struct avdtp_remote_sep {
struct avdtp_stream *stream;
};

-struct avdtp_server {
- struct btd_adapter *adapter;
- GIOChannel *io;
- struct queue *seps;
- GSList *sessions;
-};
-
struct avdtp_local_sep {
avdtp_state_t state;
struct avdtp_stream *stream;
@@ -1132,7 +1126,6 @@ void avdtp_free(void *data)

void connection_lost(struct avdtp *session, int err)
{
- struct avdtp_server *server = session->server;
char address[18];

ba2str(device_get_address(session->device), address);
@@ -1151,7 +1144,7 @@ void connection_lost(struct avdtp *session, int err)
if (session->ref > 0)
return;

- server->sessions = g_slist_remove(server->sessions, session);
+ avdtp_server_remove_session(session->server, session);
avdtp_free(session);
}

@@ -2262,16 +2255,18 @@ failed:
return FALSE;
}

-static struct avdtp *find_session(GSList *list, struct btd_device *device)
+static bool match_by_device(const void *data, const void *user_data)
{
- for (; list != NULL; list = g_slist_next(list)) {
- struct avdtp *s = list->data;
+ const struct avdtp *session = data;
+ const struct btd_device *device = user_data;

- if (s->device == device)
- return s;
- }
+ return session->device == device;
+}

- return NULL;
+static struct avdtp *find_session(struct queue *sessions,
+ struct btd_device *device)
+{
+ return queue_find(sessions, match_by_device, device);
}

static uint16_t get_version(struct avdtp *session)
@@ -2379,8 +2374,9 @@ failed:
connection_lost(session, err_no);
}

-struct avdtp *avdtp_new(struct avdtp_server *server, GSList *sessions,
- struct btd_device *device)
+struct avdtp *avdtp_new(struct avdtp_server *server, struct queue *sessions,
+ struct btd_device *device,
+ struct queue *lseps)
{
struct avdtp *session;

@@ -2397,10 +2393,9 @@ struct avdtp *avdtp_new(struct avdtp_server *server, GSList *sessions,
session->state = AVDTP_SESSION_STATE_DISCONNECTED;

session->version = get_version(session);
+ session->lseps = lseps;

- server->sessions = g_slist_append(server->sessions, session);
-
- session->lseps = server->seps;
+ queue_push_tail(sessions, session);

DBG("Created session %p added to server %p", session, server);

@@ -2465,7 +2460,7 @@ static GIOChannel *l2cap_connect(struct avdtp *session)
GIOChannel *io;
const bdaddr_t *src;

- src = btd_adapter_get_address(session->server->adapter);
+ src = btd_adapter_get_address(avdtp_get_adapter(session));

io = bt_io_connect(avdtp_connect_cb, session,
NULL, &err,
@@ -3724,7 +3719,7 @@ avdtp_state_t avdtp_sep_get_state(struct avdtp_local_sep *sep)

struct btd_adapter *avdtp_get_adapter(struct avdtp *session)
{
- return session->server->adapter;
+ return avdtp_server_get_adapter(session->server);
}

struct btd_device *avdtp_get_device(struct avdtp *session)
diff --git a/profiles/audio/avdtp.h b/profiles/audio/avdtp.h
index 4aa3936..28277cc 100644
--- a/profiles/audio/avdtp.h
+++ b/profiles/audio/avdtp.h
@@ -293,8 +293,9 @@ struct btd_adapter *avdtp_get_adapter(struct avdtp *session);
struct btd_device *avdtp_get_device(struct avdtp *session);
struct avdtp_server *avdtp_get_server(struct avdtp_local_sep *lsep);

-struct avdtp *avdtp_new(struct avdtp_server *server, GSList *sessions,
- struct btd_device *device);
+struct avdtp *avdtp_new(struct avdtp_server *server, struct queue *sessions,
+ struct btd_device *device,
+ struct queue *lseps);
bool avdtp_transport_connect(struct avdtp *session, GIOChannel *chan);
void avdtp_free(void *data);
void connection_lost(struct avdtp *session, int err);
--
2.1.0


2015-02-24 12:26:45

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv0 2/6] audio/avdtp: Copy SEP list to avdtp session

From: Andrei Emeltchenko <[email protected]>

Copying SEP list allows to remove server usage from
find_local_sep_by_seid() and other SEP list code.
---
profiles/audio/avdtp.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index 926f01c..1a16170 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -402,6 +402,7 @@ struct avdtp {
guint io_id;

GSList *seps; /* Elements of type struct avdtp_remote_sep * */
+ struct queue *lseps; /* Elements of type struct avdtp_local_sep * */

GSList *streams; /* Elements of type struct avdtp_stream * */

@@ -1222,10 +1223,10 @@ static bool match_by_seid(const void *data, const void *user_data)
return sep->info.seid == seid;
}

-static struct avdtp_local_sep *find_local_sep_by_seid(struct avdtp_server *server,
+static struct avdtp_local_sep *find_local_sep_by_seid(struct avdtp *session,
uint8_t seid)
{
- return queue_find(server->seps, match_by_seid, INT_TO_PTR(seid));
+ return queue_find(session->lseps, match_by_seid, INT_TO_PTR(seid));
}

struct avdtp_remote_sep *avdtp_find_remote_sep(struct avdtp *session,
@@ -1329,7 +1330,7 @@ static gboolean avdtp_discover_cmd(struct avdtp *session, uint8_t transaction,
struct seid_info *seps, *p;
gboolean ret;

- sep_count = queue_length(session->server->seps);
+ sep_count = queue_length(session->lseps);

if (sep_count == 0) {
uint8_t err = AVDTP_NOT_SUPPORTED_COMMAND;
@@ -1342,7 +1343,7 @@ static gboolean avdtp_discover_cmd(struct avdtp *session, uint8_t transaction,
seps = g_new0(struct seid_info, sep_count);
p = seps;

- queue_foreach(session->server->seps, copy_seps, &p);
+ queue_foreach(session->lseps, copy_seps, &p);

ret = avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT,
AVDTP_DISCOVER, seps, rsp_size);
@@ -1368,7 +1369,7 @@ static gboolean avdtp_getcap_cmd(struct avdtp *session, uint8_t transaction,
goto failed;
}

- sep = find_local_sep_by_seid(session->server, req->acp_seid);
+ sep = find_local_sep_by_seid(session, req->acp_seid);
if (!sep) {
err = AVDTP_BAD_ACP_SEID;
goto failed;
@@ -1445,7 +1446,7 @@ static gboolean avdtp_setconf_cmd(struct avdtp *session, uint8_t transaction,
return FALSE;
}

- sep = find_local_sep_by_seid(session->server, req->acp_seid);
+ sep = find_local_sep_by_seid(session, req->acp_seid);
if (!sep) {
err = AVDTP_BAD_ACP_SEID;
goto failed;
@@ -1560,7 +1561,7 @@ static gboolean avdtp_getconf_cmd(struct avdtp *session, uint8_t transaction,

memset(buf, 0, sizeof(buf));

- sep = find_local_sep_by_seid(session->server, req->acp_seid);
+ sep = find_local_sep_by_seid(session, req->acp_seid);
if (!sep) {
err = AVDTP_BAD_ACP_SEID;
goto failed;
@@ -1676,7 +1677,7 @@ static gboolean avdtp_open_cmd(struct avdtp *session, uint8_t transaction,
return FALSE;
}

- sep = find_local_sep_by_seid(session->server, req->acp_seid);
+ sep = find_local_sep_by_seid(session, req->acp_seid);
if (!sep) {
err = AVDTP_BAD_ACP_SEID;
goto failed;
@@ -1736,8 +1737,7 @@ static gboolean avdtp_start_cmd(struct avdtp *session, uint8_t transaction,
for (i = 0; i < seid_count; i++, seid++) {
failed_seid = seid->seid;

- sep = find_local_sep_by_seid(session->server,
- req->first_seid.seid);
+ sep = find_local_sep_by_seid(session, req->first_seid.seid);
if (!sep || !sep->stream) {
err = AVDTP_BAD_ACP_SEID;
goto failed;
@@ -1787,7 +1787,7 @@ static gboolean avdtp_close_cmd(struct avdtp *session, uint8_t transaction,
return FALSE;
}

- sep = find_local_sep_by_seid(session->server, req->acp_seid);
+ sep = find_local_sep_by_seid(session, req->acp_seid);
if (!sep || !sep->stream) {
err = AVDTP_BAD_ACP_SEID;
goto failed;
@@ -1848,8 +1848,7 @@ static gboolean avdtp_suspend_cmd(struct avdtp *session, uint8_t transaction,
for (i = 0; i < seid_count; i++, seid++) {
failed_seid = seid->seid;

- sep = find_local_sep_by_seid(session->server,
- req->first_seid.seid);
+ sep = find_local_sep_by_seid(session, req->first_seid.seid);
if (!sep || !sep->stream) {
err = AVDTP_BAD_ACP_SEID;
goto failed;
@@ -1896,7 +1895,7 @@ static gboolean avdtp_abort_cmd(struct avdtp *session, uint8_t transaction,
return FALSE;
}

- sep = find_local_sep_by_seid(session->server, req->acp_seid);
+ sep = find_local_sep_by_seid(session, req->acp_seid);
if (!sep || !sep->stream)
return TRUE;

@@ -1934,7 +1933,7 @@ static gboolean avdtp_delayreport_cmd(struct avdtp *session,
return FALSE;
}

- sep = find_local_sep_by_seid(session->server, req->acp_seid);
+ sep = find_local_sep_by_seid(session, req->acp_seid);
if (!sep || !sep->stream) {
err = AVDTP_BAD_ACP_SEID;
goto failed;
@@ -2396,6 +2395,7 @@ struct avdtp *avdtp_new(struct avdtp_server *server, GSList *sessions,

server->sessions = g_slist_append(server->sessions, session);

+ session->lseps = server->seps;
if (!chan)
return session;

--
2.1.0


2015-02-24 12:26:46

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv0 3/6] audio/avdtp: Refactor avdtp_new

From: Andrei Emeltchenko <[email protected]>

avdtp_new() is split to avdtp_new() and avdtp_transport_connect() which
takes care about opening transport channel.
---
profiles/audio/a2dp.c | 10 +++++++---
profiles/audio/avdtp.c | 20 ++++++++++++--------
profiles/audio/avdtp.h | 2 +-
3 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index 6a86c19..e669f43 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -1222,7 +1222,7 @@ struct avdtp *a2dp_avdtp_get(struct btd_device *device)
if (server == NULL)
return NULL;

- session = avdtp_new(server, server->sessions, NULL, device);
+ session = avdtp_new(server, server->sessions, device);
if (!session)
return NULL;

@@ -1328,11 +1328,15 @@ static void avdtp_confirm_cb(GIOChannel *chan, gpointer data)
if (!avdtp_server)
goto drop;

- session = avdtp_new(avdtp_server, avdtp_server->sessions, chan, device);
+ session = avdtp_new(avdtp_server, avdtp_server->sessions, device);
if (!session)
goto drop;

- avdtp_request_authorization(session, &src, &dst, auth_cb);
+
+ if (avdtp_transport_connect(session, chan)) {
+ btd_device_add_uuid(device, ADVANCED_AUDIO_UUID);
+ avdtp_request_authorization(session, &src, &dst, auth_cb);
+ }

return;

diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index 1a16170..aaaf3b2 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -2374,7 +2374,6 @@ failed:
}

struct avdtp *avdtp_new(struct avdtp_server *server, GSList *sessions,
- GIOChannel *chan,
struct btd_device *device)
{
struct avdtp *session;
@@ -2396,9 +2395,14 @@ struct avdtp *avdtp_new(struct avdtp_server *server, GSList *sessions,
server->sessions = g_slist_append(server->sessions, session);

session->lseps = server->seps;
- if (!chan)
- return session;

+ DBG("Created session %p added to server %p", session, server);
+
+ return session;
+}
+
+bool avdtp_transport_connect(struct avdtp *session, GIOChannel *chan)
+{
/* This state (ie, session is already *connecting*) happens when the
* device initiates a connect (really a config'd L2CAP channel) even
* though there is a connect we initiated in progress. In sink.c &
@@ -2414,7 +2418,7 @@ struct avdtp *avdtp_new(struct avdtp_server *server, GSList *sessions,
if (!bt_io_accept(chan, avdtp_connect_cb, session, NULL, NULL))
goto drop;

- return NULL;
+ return false;
}

if (session->io) {
@@ -2422,17 +2426,17 @@ struct avdtp *avdtp_new(struct avdtp_server *server, GSList *sessions,
goto drop;
}

- btd_device_add_uuid(device, ADVANCED_AUDIO_UUID);
-
session->io = g_io_channel_ref(chan);
avdtp_set_state(session, AVDTP_SESSION_STATE_CONNECTING);

session->io_id = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
(GIOFunc) session_cb, session);

- return session;
+ return true;
+
drop:
- return NULL;
+ g_io_channel_shutdown(chan, TRUE, NULL);
+ return false;
}

bool avdtp_request_authorization(struct avdtp *session, const bdaddr_t *src,
diff --git a/profiles/audio/avdtp.h b/profiles/audio/avdtp.h
index c2c223a..4aa3936 100644
--- a/profiles/audio/avdtp.h
+++ b/profiles/audio/avdtp.h
@@ -294,8 +294,8 @@ struct btd_device *avdtp_get_device(struct avdtp *session);
struct avdtp_server *avdtp_get_server(struct avdtp_local_sep *lsep);

struct avdtp *avdtp_new(struct avdtp_server *server, GSList *sessions,
- GIOChannel *chan,
struct btd_device *device);
+bool avdtp_transport_connect(struct avdtp *session, GIOChannel *chan);
void avdtp_free(void *data);
void connection_lost(struct avdtp *session, int err);
void avdtp_accept(struct avdtp *session);
--
2.1.0