2013-07-03 15:15:21

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 00/20] Remove audio_device and introduce policy plugin

From: Luiz Augusto von Dentz <[email protected]>

audio_device is no longer needed as btd_service can be used to track
connection states, in fact audio_device probably obscured direct access
to some data types like btd_device and use btd_service_set_user_data to
set profile private data instead of storing everything inside
audio_device.

There are probably more cleanups to audio after this changes, some
policies that should be moved to policy plugin and a much needed split
of audio plugin into smaller plugins, but I decided to stop right here
otherwise the patch-set will get too big to be properly reviewed.

Also since this refactore the audio policy quite extensively this may
create some IOP issues that why Im using RFC here, but I did test this
with quite a few stacks including:

- iOS 6
- Android 4.2
- WP 8
- Blackberry 10
- MW600
- Nokia Purity Pro
- BlueZ 4

They all seems to be working as before, but I discover some bugs
related to the of btd_service to track connection states those are
fixed in the last 2 patches but there could be more.

Luiz Augusto von Dentz (20):
audio/sink: Use service user_data for private data
audio/source: Use service user_data for private data
audio/control: Use service user_data for private data
audio/sink: Reduce dependency on struct audio_device
audio/source: Reduce dependency on struct audio_device
audio/control: Reduce dependency on struct audio_device
audio/AVCTP: Remove dependency on struct audio_device
audio/AVDTP: Remove dependency on struct audio_device
audio/AVRCP: Remove dependency on struct audio_device
audio/control: Remove dependency on struct audio_device
audio/A2DP: Remove dependency on struct audio_device
audio/sink: Remove dependency on struct audio_device
audio/source: Remove dependency on struct audio_device
audio/media: Remove dependency on struct audio_device
audio/transport: Remove dependency on struct audio_device
audio/manager: Remove dependency on struct audio_device
audio/main: Remove dependency on struct audio_device
plugins/policy: Reword audio policy code in a simple plugin
audio/sink: Fix not notifying service about connection state
audio/source: Fix not notifying service about connection state

Makefile.plugins | 4 +-
plugins/policy.c | 341 +++++++++++++++++++++++++++++++++++++++++++++
profiles/audio/a2dp.c | 110 +++++++--------
profiles/audio/a2dp.h | 4 +-
profiles/audio/avctp.c | 69 ++++-----
profiles/audio/avctp.h | 12 +-
profiles/audio/avdtp.c | 97 ++++++-------
profiles/audio/avdtp.h | 13 +-
profiles/audio/avrcp.c | 89 +++++++-----
profiles/audio/avrcp.h | 8 +-
profiles/audio/control.c | 136 +++++++++---------
profiles/audio/control.h | 19 +--
profiles/audio/device.c | 261 ----------------------------------
profiles/audio/device.h | 43 ------
profiles/audio/main.c | 1 -
profiles/audio/manager.c | 186 ++++++-------------------
profiles/audio/manager.h | 10 --
profiles/audio/media.c | 39 +++---
profiles/audio/sink.c | 113 ++++++++-------
profiles/audio/sink.h | 18 +--
profiles/audio/source.c | 111 +++++++--------
profiles/audio/source.h | 20 +--
profiles/audio/transport.c | 109 +++++++++------
profiles/audio/transport.h | 8 +-
24 files changed, 884 insertions(+), 937 deletions(-)
create mode 100644 plugins/policy.c
delete mode 100644 profiles/audio/device.c
delete mode 100644 profiles/audio/device.h

--
1.8.1.4



2013-07-08 10:00:29

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [RFC 01/20] audio/sink: Use service user_data for private data

Hi Mikel,

On Fri, Jul 5, 2013 at 9:38 AM, Mikel Astiz <[email protected]> wrote:
> Hi Vinicius,
>
> On Thu, Jul 4, 2013 at 4:28 PM, Vinicius Costa Gomes
> <[email protected]> wrote:
>> Hi,
>>
>> On 18:15 Wed 03 Jul, Luiz Augusto von Dentz wrote:
>>> From: Luiz Augusto von Dentz <[email protected]>
>>>
>>> This remove the need of forward declaration of struct sink and prepare
>>> for a complete removal of struct audio_device.
>>> ---
>>> profiles/audio/avdtp.c | 2 +-
>>> profiles/audio/device.c | 54 ++++++++++++++++++++++++++++++-------------------
>>> profiles/audio/device.h | 3 +--
>>> profiles/audio/sink.c | 29 +++++++++++++++-----------
>>> profiles/audio/sink.h | 5 +++--
>>> 5 files changed, 55 insertions(+), 38 deletions(-)
>>>
>>
>> [snip]
>>
>>> @@ -171,30 +175,25 @@ static void device_avdtp_cb(struct audio_device *dev, struct avdtp *session,
>>> }
>>>
>>> static void device_sink_cb(struct audio_device *dev,
>>> - sink_state_t old_state,
>>> - sink_state_t new_state,
>>> - void *user_data)
>>> + btd_service_state_t old_state,
>>> + btd_service_state_t new_state)
>>> {
>>> struct dev_priv *priv = dev->priv;
>>>
>>> - if (!dev->sink)
>>> - return;
>>> -
>>> priv->sink_state = new_state;
>>>
>>> switch (new_state) {
>>> - case SINK_STATE_DISCONNECTED:
>>> + case BTD_SERVICE_STATE_UNAVAILABLE:
>>> + case BTD_SERVICE_STATE_DISCONNECTED:
>>> if (dev->control) {
>>> device_remove_control_timer(dev);
>>> if (priv->avctp_state != AVCTP_STATE_DISCONNECTED)
>>> avrcp_disconnect(dev);
>>> }
>>> break;
>>> - case SINK_STATE_CONNECTING:
>>> - break;
>>> - case SINK_STATE_CONNECTED:
>>> - break;
>>> - case SINK_STATE_PLAYING:
>>> + case BTD_SERVICE_STATE_CONNECTING:
>>> + case BTD_SERVICE_STATE_CONNECTED:
>>> + case BTD_SERVICE_STATE_DISCONNECTING:
>>> break;
>>> }
>>> }
>>> @@ -222,6 +221,20 @@ static void device_avctp_cb(struct audio_device *dev, avctp_state_t old_state,
>>> }
>>> }
>>>
>>> +static void service_cb(struct btd_service *service,
>>> + btd_service_state_t old_state,
>>> + btd_service_state_t new_state,
>>> + void *user_data)
>>> +{
>>> + struct audio_device *dev = user_data;
>>> +
>>> + if (dev->btd_dev != btd_service_get_device(service))
>>> + return;
>>> +
>>> + if (service == dev->sink)
>>> + device_sink_cb(dev, old_state, new_state);
>>> +}
>>> +
>>> struct audio_device *audio_device_register(struct btd_device *device)
>>> {
>>> struct audio_device *dev;
>>> @@ -236,8 +249,7 @@ struct audio_device *audio_device_register(struct btd_device *device)
>>> dev->priv->dc_id = device_add_disconnect_watch(dev->btd_dev,
>>> disconnect_cb, dev,
>>> NULL);
>>> - dev->priv->sink_callback_id = sink_add_state_cb(dev, device_sink_cb,
>>> - NULL);
>>> + dev->priv->service_cb_id = btd_service_add_state_cb(service_cb, dev);
>>
>> I just want to bring up an issue not related to the patch in itself.
>>
>> Wouldn't it be better if the state changed callback were per service? I can
>> see it being used a lot.
>>
>> Or was this point already discussed?
>
> I don't remember this being discussed.
>
> I do however agree with your proposal, there would be several
> interested users of this per-service callback. Perhaps
> btd_service_add_state_cb() can be extended with a pointer than can be
> optionally be NULL to express "any service"?

Yep, I think that is a good idea because I end up with a device list
on policy module to that holds policy private data per device, anyway
we might need a device driver infra similar to adapter driver and we
can probably have info such as class, device id, product id and so on
to probe the right driver, so we could have device/class specific
drivers if needed.

2013-07-05 06:38:42

by Mikel Astiz

[permalink] [raw]
Subject: Re: [RFC 01/20] audio/sink: Use service user_data for private data

Hi Vinicius,

On Thu, Jul 4, 2013 at 4:28 PM, Vinicius Costa Gomes
<[email protected]> wrote:
> Hi,
>
> On 18:15 Wed 03 Jul, Luiz Augusto von Dentz wrote:
>> From: Luiz Augusto von Dentz <[email protected]>
>>
>> This remove the need of forward declaration of struct sink and prepare
>> for a complete removal of struct audio_device.
>> ---
>> profiles/audio/avdtp.c | 2 +-
>> profiles/audio/device.c | 54 ++++++++++++++++++++++++++++++-------------------
>> profiles/audio/device.h | 3 +--
>> profiles/audio/sink.c | 29 +++++++++++++++-----------
>> profiles/audio/sink.h | 5 +++--
>> 5 files changed, 55 insertions(+), 38 deletions(-)
>>
>
> [snip]
>
>> @@ -171,30 +175,25 @@ static void device_avdtp_cb(struct audio_device *dev, struct avdtp *session,
>> }
>>
>> static void device_sink_cb(struct audio_device *dev,
>> - sink_state_t old_state,
>> - sink_state_t new_state,
>> - void *user_data)
>> + btd_service_state_t old_state,
>> + btd_service_state_t new_state)
>> {
>> struct dev_priv *priv = dev->priv;
>>
>> - if (!dev->sink)
>> - return;
>> -
>> priv->sink_state = new_state;
>>
>> switch (new_state) {
>> - case SINK_STATE_DISCONNECTED:
>> + case BTD_SERVICE_STATE_UNAVAILABLE:
>> + case BTD_SERVICE_STATE_DISCONNECTED:
>> if (dev->control) {
>> device_remove_control_timer(dev);
>> if (priv->avctp_state != AVCTP_STATE_DISCONNECTED)
>> avrcp_disconnect(dev);
>> }
>> break;
>> - case SINK_STATE_CONNECTING:
>> - break;
>> - case SINK_STATE_CONNECTED:
>> - break;
>> - case SINK_STATE_PLAYING:
>> + case BTD_SERVICE_STATE_CONNECTING:
>> + case BTD_SERVICE_STATE_CONNECTED:
>> + case BTD_SERVICE_STATE_DISCONNECTING:
>> break;
>> }
>> }
>> @@ -222,6 +221,20 @@ static void device_avctp_cb(struct audio_device *dev, avctp_state_t old_state,
>> }
>> }
>>
>> +static void service_cb(struct btd_service *service,
>> + btd_service_state_t old_state,
>> + btd_service_state_t new_state,
>> + void *user_data)
>> +{
>> + struct audio_device *dev = user_data;
>> +
>> + if (dev->btd_dev != btd_service_get_device(service))
>> + return;
>> +
>> + if (service == dev->sink)
>> + device_sink_cb(dev, old_state, new_state);
>> +}
>> +
>> struct audio_device *audio_device_register(struct btd_device *device)
>> {
>> struct audio_device *dev;
>> @@ -236,8 +249,7 @@ struct audio_device *audio_device_register(struct btd_device *device)
>> dev->priv->dc_id = device_add_disconnect_watch(dev->btd_dev,
>> disconnect_cb, dev,
>> NULL);
>> - dev->priv->sink_callback_id = sink_add_state_cb(dev, device_sink_cb,
>> - NULL);
>> + dev->priv->service_cb_id = btd_service_add_state_cb(service_cb, dev);
>
> I just want to bring up an issue not related to the patch in itself.
>
> Wouldn't it be better if the state changed callback were per service? I can
> see it being used a lot.
>
> Or was this point already discussed?

I don't remember this being discussed.

I do however agree with your proposal, there would be several
interested users of this per-service callback. Perhaps
btd_service_add_state_cb() can be extended with a pointer than can be
optionally be NULL to express "any service"?

Cheers,
Mikel

>
>
>> dev->priv->avdtp_callback_id = avdtp_add_state_cb(dev, device_avdtp_cb);
>> dev->priv->avctp_callback_id = avctp_add_state_cb(dev, device_avctp_cb);
>>
>> diff --git a/profiles/audio/device.h b/profiles/audio/device.h
>> index 286bcdd..e24bdf9 100644
>> --- a/profiles/audio/device.h
>> +++ b/profiles/audio/device.h
>> @@ -25,13 +25,12 @@
>> struct audio_device;
>> struct source;
>> struct control;
>> -struct sink;
>> struct dev_priv;
>>
>> struct audio_device {
>> struct btd_device *btd_dev;
>>
>> - struct sink *sink;
>> + struct btd_service *sink;
>> struct source *source;
>> struct control *control;
>>
>> diff --git a/profiles/audio/sink.c b/profiles/audio/sink.c
>> index 3969417..f5b4e67 100644
>> --- a/profiles/audio/sink.c
>> +++ b/profiles/audio/sink.c
>> @@ -87,7 +87,7 @@ static char *str_state[] = {
>>
>> static void sink_set_state(struct audio_device *dev, sink_state_t new_state)
>> {
>> - struct sink *sink = dev->sink;
>> + struct sink *sink = btd_service_get_user_data(dev->sink);
>> sink_state_t old_state = sink->state;
>> GSList *l;
>>
>> @@ -119,7 +119,7 @@ static void avdtp_state_callback(struct audio_device *dev,
>> avdtp_session_state_t old_state,
>> avdtp_session_state_t new_state)
>> {
>> - struct sink *sink = dev->sink;
>> + struct sink *sink = btd_service_get_user_data(dev->sink);
>>
>> switch (new_state) {
>> case AVDTP_SESSION_STATE_DISCONNECTED:
>> @@ -142,7 +142,7 @@ static void stream_state_changed(struct avdtp_stream *stream,
>> void *user_data)
>> {
>> struct audio_device *dev = user_data;
>> - struct sink *sink = dev->sink;
>> + struct sink *sink = btd_service_get_user_data(dev->sink);
>>
>> if (err)
>> return;
>> @@ -291,8 +291,10 @@ failed:
>> sink->session = NULL;
>> }
>>
>> -gboolean sink_setup_stream(struct sink *sink, struct avdtp *session)
>> +gboolean sink_setup_stream(struct audio_device *dev, struct avdtp *session)
>> {
>> + struct sink *sink = btd_service_get_user_data(dev->sink);
>> +
>> if (sink->connect_id > 0 || sink->disconnect_id > 0)
>> return FALSE;
>>
>> @@ -310,7 +312,7 @@ gboolean sink_setup_stream(struct sink *sink, struct avdtp *session)
>>
>> int sink_connect(struct audio_device *dev)
>> {
>> - struct sink *sink = dev->sink;
>> + struct sink *sink = btd_service_get_user_data(dev->sink);
>>
>> if (!sink->session)
>> sink->session = avdtp_get(dev);
>> @@ -326,7 +328,7 @@ int sink_connect(struct audio_device *dev)
>> if (sink->stream_state >= AVDTP_STATE_OPEN)
>> return -EALREADY;
>>
>> - if (!sink_setup_stream(sink, NULL)) {
>> + if (!sink_setup_stream(dev, NULL)) {
>> DBG("Failed to create a stream");
>> return -EIO;
>> }
>> @@ -338,7 +340,7 @@ int sink_connect(struct audio_device *dev)
>>
>> static void sink_free(struct audio_device *dev)
>> {
>> - struct sink *sink = dev->sink;
>> + struct sink *sink = btd_service_get_user_data(dev->sink);
>>
>> if (sink->cb_id)
>> avdtp_stream_remove_cb(sink->session, sink->stream,
>> @@ -375,7 +377,8 @@ void sink_unregister(struct audio_device *dev)
>> sink_free(dev);
>> }
>>
>> -struct sink *sink_init(struct audio_device *dev, struct btd_service *service)
>> +struct btd_service *sink_init(struct audio_device *dev,
>> + struct btd_service *service)
>> {
>> struct sink *sink;
>>
>> @@ -388,12 +391,14 @@ struct sink *sink_init(struct audio_device *dev, struct btd_service *service)
>>
>> sink->avdtp_callback_id = avdtp_add_state_cb(dev, avdtp_state_callback);
>>
>> - return sink;
>> + btd_service_set_user_data(service, sink);
>> +
>> + return service;
>> }
>>
>> gboolean sink_is_active(struct audio_device *dev)
>> {
>> - struct sink *sink = dev->sink;
>> + struct sink *sink = btd_service_get_user_data(dev->sink);
>>
>> if (sink->session)
>> return TRUE;
>> @@ -404,7 +409,7 @@ gboolean sink_is_active(struct audio_device *dev)
>> gboolean sink_new_stream(struct audio_device *dev, struct avdtp *session,
>> struct avdtp_stream *stream)
>> {
>> - struct sink *sink = dev->sink;
>> + struct sink *sink = btd_service_get_user_data(dev->sink);
>>
>> if (sink->stream)
>> return FALSE;
>> @@ -422,7 +427,7 @@ gboolean sink_new_stream(struct audio_device *dev, struct avdtp *session,
>>
>> int sink_disconnect(struct audio_device *dev, gboolean shutdown)
>> {
>> - struct sink *sink = dev->sink;
>> + struct sink *sink = btd_service_get_user_data(dev->sink);
>>
>> if (!sink->session)
>> return -ENOTCONN;
>> diff --git a/profiles/audio/sink.h b/profiles/audio/sink.h
>> index 1a80756..e3f974b 100644
>> --- a/profiles/audio/sink.h
>> +++ b/profiles/audio/sink.h
>> @@ -40,11 +40,12 @@ unsigned int sink_add_state_cb(struct audio_device *dev, sink_state_cb cb,
>> void *user_data);
>> gboolean sink_remove_state_cb(unsigned int id);
>>
>> -struct sink *sink_init(struct audio_device *dev, struct btd_service *service);
>> +struct btd_service *sink_init(struct audio_device *dev,
>> + struct btd_service *service);
>> void sink_unregister(struct audio_device *dev);
>> gboolean sink_is_active(struct audio_device *dev);
>> int sink_connect(struct audio_device *dev);
>> gboolean sink_new_stream(struct audio_device *dev, struct avdtp *session,
>> struct avdtp_stream *stream);
>> -gboolean sink_setup_stream(struct sink *sink, struct avdtp *session);
>> +gboolean sink_setup_stream(struct audio_device *dev, struct avdtp *session);
>> int sink_disconnect(struct audio_device *dev, gboolean shutdown);
>> --
>> 1.8.1.4
>>
>> --
>> 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
>
>
> Cheers,
> --
> Vinicius
> --
> 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

2013-07-04 14:28:29

by Vinicius Costa Gomes

[permalink] [raw]
Subject: Re: [RFC 01/20] audio/sink: Use service user_data for private data

Hi,

On 18:15 Wed 03 Jul, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <[email protected]>
>
> This remove the need of forward declaration of struct sink and prepare
> for a complete removal of struct audio_device.
> ---
> profiles/audio/avdtp.c | 2 +-
> profiles/audio/device.c | 54 ++++++++++++++++++++++++++++++-------------------
> profiles/audio/device.h | 3 +--
> profiles/audio/sink.c | 29 +++++++++++++++-----------
> profiles/audio/sink.h | 5 +++--
> 5 files changed, 55 insertions(+), 38 deletions(-)
>

[snip]

> @@ -171,30 +175,25 @@ static void device_avdtp_cb(struct audio_device *dev, struct avdtp *session,
> }
>
> static void device_sink_cb(struct audio_device *dev,
> - sink_state_t old_state,
> - sink_state_t new_state,
> - void *user_data)
> + btd_service_state_t old_state,
> + btd_service_state_t new_state)
> {
> struct dev_priv *priv = dev->priv;
>
> - if (!dev->sink)
> - return;
> -
> priv->sink_state = new_state;
>
> switch (new_state) {
> - case SINK_STATE_DISCONNECTED:
> + case BTD_SERVICE_STATE_UNAVAILABLE:
> + case BTD_SERVICE_STATE_DISCONNECTED:
> if (dev->control) {
> device_remove_control_timer(dev);
> if (priv->avctp_state != AVCTP_STATE_DISCONNECTED)
> avrcp_disconnect(dev);
> }
> break;
> - case SINK_STATE_CONNECTING:
> - break;
> - case SINK_STATE_CONNECTED:
> - break;
> - case SINK_STATE_PLAYING:
> + case BTD_SERVICE_STATE_CONNECTING:
> + case BTD_SERVICE_STATE_CONNECTED:
> + case BTD_SERVICE_STATE_DISCONNECTING:
> break;
> }
> }
> @@ -222,6 +221,20 @@ static void device_avctp_cb(struct audio_device *dev, avctp_state_t old_state,
> }
> }
>
> +static void service_cb(struct btd_service *service,
> + btd_service_state_t old_state,
> + btd_service_state_t new_state,
> + void *user_data)
> +{
> + struct audio_device *dev = user_data;
> +
> + if (dev->btd_dev != btd_service_get_device(service))
> + return;
> +
> + if (service == dev->sink)
> + device_sink_cb(dev, old_state, new_state);
> +}
> +
> struct audio_device *audio_device_register(struct btd_device *device)
> {
> struct audio_device *dev;
> @@ -236,8 +249,7 @@ struct audio_device *audio_device_register(struct btd_device *device)
> dev->priv->dc_id = device_add_disconnect_watch(dev->btd_dev,
> disconnect_cb, dev,
> NULL);
> - dev->priv->sink_callback_id = sink_add_state_cb(dev, device_sink_cb,
> - NULL);
> + dev->priv->service_cb_id = btd_service_add_state_cb(service_cb, dev);

I just want to bring up an issue not related to the patch in itself.

Wouldn't it be better if the state changed callback were per service? I can
see it being used a lot.

Or was this point already discussed?


> dev->priv->avdtp_callback_id = avdtp_add_state_cb(dev, device_avdtp_cb);
> dev->priv->avctp_callback_id = avctp_add_state_cb(dev, device_avctp_cb);
>
> diff --git a/profiles/audio/device.h b/profiles/audio/device.h
> index 286bcdd..e24bdf9 100644
> --- a/profiles/audio/device.h
> +++ b/profiles/audio/device.h
> @@ -25,13 +25,12 @@
> struct audio_device;
> struct source;
> struct control;
> -struct sink;
> struct dev_priv;
>
> struct audio_device {
> struct btd_device *btd_dev;
>
> - struct sink *sink;
> + struct btd_service *sink;
> struct source *source;
> struct control *control;
>
> diff --git a/profiles/audio/sink.c b/profiles/audio/sink.c
> index 3969417..f5b4e67 100644
> --- a/profiles/audio/sink.c
> +++ b/profiles/audio/sink.c
> @@ -87,7 +87,7 @@ static char *str_state[] = {
>
> static void sink_set_state(struct audio_device *dev, sink_state_t new_state)
> {
> - struct sink *sink = dev->sink;
> + struct sink *sink = btd_service_get_user_data(dev->sink);
> sink_state_t old_state = sink->state;
> GSList *l;
>
> @@ -119,7 +119,7 @@ static void avdtp_state_callback(struct audio_device *dev,
> avdtp_session_state_t old_state,
> avdtp_session_state_t new_state)
> {
> - struct sink *sink = dev->sink;
> + struct sink *sink = btd_service_get_user_data(dev->sink);
>
> switch (new_state) {
> case AVDTP_SESSION_STATE_DISCONNECTED:
> @@ -142,7 +142,7 @@ static void stream_state_changed(struct avdtp_stream *stream,
> void *user_data)
> {
> struct audio_device *dev = user_data;
> - struct sink *sink = dev->sink;
> + struct sink *sink = btd_service_get_user_data(dev->sink);
>
> if (err)
> return;
> @@ -291,8 +291,10 @@ failed:
> sink->session = NULL;
> }
>
> -gboolean sink_setup_stream(struct sink *sink, struct avdtp *session)
> +gboolean sink_setup_stream(struct audio_device *dev, struct avdtp *session)
> {
> + struct sink *sink = btd_service_get_user_data(dev->sink);
> +
> if (sink->connect_id > 0 || sink->disconnect_id > 0)
> return FALSE;
>
> @@ -310,7 +312,7 @@ gboolean sink_setup_stream(struct sink *sink, struct avdtp *session)
>
> int sink_connect(struct audio_device *dev)
> {
> - struct sink *sink = dev->sink;
> + struct sink *sink = btd_service_get_user_data(dev->sink);
>
> if (!sink->session)
> sink->session = avdtp_get(dev);
> @@ -326,7 +328,7 @@ int sink_connect(struct audio_device *dev)
> if (sink->stream_state >= AVDTP_STATE_OPEN)
> return -EALREADY;
>
> - if (!sink_setup_stream(sink, NULL)) {
> + if (!sink_setup_stream(dev, NULL)) {
> DBG("Failed to create a stream");
> return -EIO;
> }
> @@ -338,7 +340,7 @@ int sink_connect(struct audio_device *dev)
>
> static void sink_free(struct audio_device *dev)
> {
> - struct sink *sink = dev->sink;
> + struct sink *sink = btd_service_get_user_data(dev->sink);
>
> if (sink->cb_id)
> avdtp_stream_remove_cb(sink->session, sink->stream,
> @@ -375,7 +377,8 @@ void sink_unregister(struct audio_device *dev)
> sink_free(dev);
> }
>
> -struct sink *sink_init(struct audio_device *dev, struct btd_service *service)
> +struct btd_service *sink_init(struct audio_device *dev,
> + struct btd_service *service)
> {
> struct sink *sink;
>
> @@ -388,12 +391,14 @@ struct sink *sink_init(struct audio_device *dev, struct btd_service *service)
>
> sink->avdtp_callback_id = avdtp_add_state_cb(dev, avdtp_state_callback);
>
> - return sink;
> + btd_service_set_user_data(service, sink);
> +
> + return service;
> }
>
> gboolean sink_is_active(struct audio_device *dev)
> {
> - struct sink *sink = dev->sink;
> + struct sink *sink = btd_service_get_user_data(dev->sink);
>
> if (sink->session)
> return TRUE;
> @@ -404,7 +409,7 @@ gboolean sink_is_active(struct audio_device *dev)
> gboolean sink_new_stream(struct audio_device *dev, struct avdtp *session,
> struct avdtp_stream *stream)
> {
> - struct sink *sink = dev->sink;
> + struct sink *sink = btd_service_get_user_data(dev->sink);
>
> if (sink->stream)
> return FALSE;
> @@ -422,7 +427,7 @@ gboolean sink_new_stream(struct audio_device *dev, struct avdtp *session,
>
> int sink_disconnect(struct audio_device *dev, gboolean shutdown)
> {
> - struct sink *sink = dev->sink;
> + struct sink *sink = btd_service_get_user_data(dev->sink);
>
> if (!sink->session)
> return -ENOTCONN;
> diff --git a/profiles/audio/sink.h b/profiles/audio/sink.h
> index 1a80756..e3f974b 100644
> --- a/profiles/audio/sink.h
> +++ b/profiles/audio/sink.h
> @@ -40,11 +40,12 @@ unsigned int sink_add_state_cb(struct audio_device *dev, sink_state_cb cb,
> void *user_data);
> gboolean sink_remove_state_cb(unsigned int id);
>
> -struct sink *sink_init(struct audio_device *dev, struct btd_service *service);
> +struct btd_service *sink_init(struct audio_device *dev,
> + struct btd_service *service);
> void sink_unregister(struct audio_device *dev);
> gboolean sink_is_active(struct audio_device *dev);
> int sink_connect(struct audio_device *dev);
> gboolean sink_new_stream(struct audio_device *dev, struct avdtp *session,
> struct avdtp_stream *stream);
> -gboolean sink_setup_stream(struct sink *sink, struct avdtp *session);
> +gboolean sink_setup_stream(struct audio_device *dev, struct avdtp *session);
> int sink_disconnect(struct audio_device *dev, gboolean shutdown);
> --
> 1.8.1.4
>
> --
> 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


Cheers,
--
Vinicius

2013-07-04 07:17:19

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [RFC 19/20] audio/sink: Fix not notifying service about connection state

Hi Mikel,

On Thu, Jul 4, 2013 at 10:05 AM, Mikel Astiz <[email protected]> wrote:
> Hi Luiz,
>
> On Wed, Jul 3, 2013 at 5:15 PM, Luiz Augusto von Dentz
> <[email protected]> wrote:
>> From: Luiz Augusto von Dentz <[email protected]>
>>
>> btd_service_connecting_complete should be called whenever the service
>> is connected otherwise the service state will not be consistent.
>> ---
>> profiles/audio/sink.c | 6 ++----
>> 1 file changed, 2 insertions(+), 4 deletions(-)
>>
>> diff --git a/profiles/audio/sink.c b/profiles/audio/sink.c
>> index bb9ab21..5206920 100644
>> --- a/profiles/audio/sink.c
>> +++ b/profiles/audio/sink.c
>> @@ -164,6 +164,7 @@ static void stream_state_changed(struct avdtp_stream *stream,
>> sink->cb_id = 0;
>> break;
>> case AVDTP_STATE_OPEN:
>> + btd_service_connecting_complete(sink->service, 0);
>> sink_set_state(sink, SINK_STATE_CONNECTED);
>> break;
>> case AVDTP_STATE_STREAMING:
>> @@ -212,11 +213,8 @@ static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep,
>>
>> sink->connect_id = 0;
>>
>> - if (stream) {
>> - DBG("Stream successfully created");
>> - btd_service_connecting_complete(sink->service, 0);
>> + if (stream)
>> return;
>> - }
>>
>> avdtp_unref(sink->session);
>> sink->session = NULL;
>> --
>
> If this is a fix, it'd be good to document the steps to reproduce and
> point out the commit that broke this.
>
> In particular, I'm interested in knowing whether this was introduced
> during the transition to btd_service. If you look at
> 10620c1c0fbb211455fde597a1d2e5e47806f25d, you'll see that the previous
> approach also missed the state notification in stream_state_changed().
>
> If this is indeed an issue introduced by btd_service, other profiles
> might need to be double-checked.

It is quite easy to reproduce, revert these patches and make a
incoming connection, stream_setup_complete is never called for
incoming connection thus causing the policy plugin to not be notified
and AVRCP does not connect for example with WP8 which doesn't connect
AVRCP automatically.


--
Luiz Augusto von Dentz

2013-07-04 07:05:57

by Mikel Astiz

[permalink] [raw]
Subject: Re: [RFC 19/20] audio/sink: Fix not notifying service about connection state

Hi Luiz,

On Wed, Jul 3, 2013 at 5:15 PM, Luiz Augusto von Dentz
<[email protected]> wrote:
> From: Luiz Augusto von Dentz <[email protected]>
>
> btd_service_connecting_complete should be called whenever the service
> is connected otherwise the service state will not be consistent.
> ---
> profiles/audio/sink.c | 6 ++----
> 1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/profiles/audio/sink.c b/profiles/audio/sink.c
> index bb9ab21..5206920 100644
> --- a/profiles/audio/sink.c
> +++ b/profiles/audio/sink.c
> @@ -164,6 +164,7 @@ static void stream_state_changed(struct avdtp_stream *stream,
> sink->cb_id = 0;
> break;
> case AVDTP_STATE_OPEN:
> + btd_service_connecting_complete(sink->service, 0);
> sink_set_state(sink, SINK_STATE_CONNECTED);
> break;
> case AVDTP_STATE_STREAMING:
> @@ -212,11 +213,8 @@ static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep,
>
> sink->connect_id = 0;
>
> - if (stream) {
> - DBG("Stream successfully created");
> - btd_service_connecting_complete(sink->service, 0);
> + if (stream)
> return;
> - }
>
> avdtp_unref(sink->session);
> sink->session = NULL;
> --

If this is a fix, it'd be good to document the steps to reproduce and
point out the commit that broke this.

In particular, I'm interested in knowing whether this was introduced
during the transition to btd_service. If you look at
10620c1c0fbb211455fde597a1d2e5e47806f25d, you'll see that the previous
approach also missed the state notification in stream_state_changed().

If this is indeed an issue introduced by btd_service, other profiles
might need to be double-checked.

Cheers,
Mikel

2013-07-04 06:49:51

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [RFC 01/20] audio/sink: Use service user_data for private data

Hi Mikel,

On Thu, Jul 4, 2013 at 9:36 AM, Mikel Astiz <[email protected]> wrote:
> Hi Luiz,
>
> On Wed, Jul 3, 2013 at 5:15 PM, Luiz Augusto von Dentz
> <[email protected]> wrote:
>> From: Luiz Augusto von Dentz <[email protected]>
>>
>> This remove the need of forward declaration of struct sink and prepare
>> for a complete removal of struct audio_device.
>> ---
>> profiles/audio/avdtp.c | 2 +-
>> profiles/audio/device.c | 54 ++++++++++++++++++++++++++++++-------------------
>> profiles/audio/device.h | 3 +--
>> profiles/audio/sink.c | 29 +++++++++++++++-----------
>> profiles/audio/sink.h | 5 +++--
>> 5 files changed, 55 insertions(+), 38 deletions(-)
>>
>> diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
>> index bd73572..0d67e67 100644
>> --- a/profiles/audio/avdtp.c
>> +++ b/profiles/audio/avdtp.c
>> @@ -1165,7 +1165,7 @@ static gboolean disconnect_timeout(gpointer user_data)
>> dev = manager_get_audio_device(session->device, FALSE);
>>
>> if (dev && dev->sink && stream_setup)
>> - sink_setup_stream(dev->sink, session);
>> + sink_setup_stream(dev, session);
>> else if (dev && dev->source && stream_setup)
>> source_setup_stream(dev->source, session);
>> else
>> diff --git a/profiles/audio/device.c b/profiles/audio/device.c
>> index 3fa49ad..f11c728 100644
>> --- a/profiles/audio/device.c
>> +++ b/profiles/audio/device.c
>> @@ -42,10 +42,12 @@
>> #include <dbus/dbus.h>
>> #include <gdbus/gdbus.h>
>>
>> -#include "log.h"
>> -#include "../src/adapter.h"
>> -#include "../src/device.h"
>> +#include "lib/uuid.h"
>> +#include "src/adapter.h"
>> +#include "src/device.h"
>> +#include "src/service.h"
>>
>> +#include "log.h"
>> #include "error.h"
>> #include "dbus-common.h"
>> #include "device.h"
>> @@ -61,7 +63,7 @@
>> #define AVDTP_CONNECT_TIMEOUT_BOOST 1
>>
>> struct dev_priv {
>> - sink_state_t sink_state;
>> + btd_service_state_t sink_state;
>> avctp_state_t avctp_state;
>>
>> guint control_timer;
>> @@ -69,9 +71,9 @@ struct dev_priv {
>>
>> gboolean disconnecting;
>>
>> + unsigned int service_cb_id;
>> unsigned int avdtp_callback_id;
>> unsigned int avctp_callback_id;
>> - unsigned int sink_callback_id;
>> };
>>
>> static void device_free(struct audio_device *dev)
>> @@ -87,7 +89,7 @@ static void device_free(struct audio_device *dev)
>>
>> avdtp_remove_state_cb(priv->avdtp_callback_id);
>> avctp_remove_state_cb(priv->avctp_callback_id);
>> - sink_remove_state_cb(priv->sink_callback_id);
>> + btd_service_remove_state_cb(priv->service_cb_id);
>>
>> g_free(priv);
>> }
>> @@ -138,6 +140,7 @@ static void disconnect_cb(struct btd_device *btd_dev, gboolean removal,
>> {
>> struct audio_device *dev = user_data;
>> struct dev_priv *priv = dev->priv;
>> + struct btd_service *sink;
>>
>> if (priv->disconnecting)
>> return;
>> @@ -149,7 +152,8 @@ static void disconnect_cb(struct btd_device *btd_dev, gboolean removal,
>> if (dev->control && priv->avctp_state != AVCTP_STATE_DISCONNECTED)
>> avrcp_disconnect(dev);
>>
>> - if (dev->sink && priv->sink_state != SINK_STATE_DISCONNECTED)
>> + sink = btd_device_get_service(btd_dev, A2DP_SINK_UUID);
>> + if (sink)
>> sink_disconnect(dev, TRUE);
>> else
>> priv->disconnecting = FALSE;
>> @@ -171,30 +175,25 @@ static void device_avdtp_cb(struct audio_device *dev, struct avdtp *session,
>> }
>>
>> static void device_sink_cb(struct audio_device *dev,
>> - sink_state_t old_state,
>> - sink_state_t new_state,
>> - void *user_data)
>> + btd_service_state_t old_state,
>> + btd_service_state_t new_state)
>> {
>> struct dev_priv *priv = dev->priv;
>>
>> - if (!dev->sink)
>> - return;
>> -
>> priv->sink_state = new_state;
>>
>> switch (new_state) {
>> - case SINK_STATE_DISCONNECTED:
>> + case BTD_SERVICE_STATE_UNAVAILABLE:
>> + case BTD_SERVICE_STATE_DISCONNECTED:
>> if (dev->control) {
>> device_remove_control_timer(dev);
>> if (priv->avctp_state != AVCTP_STATE_DISCONNECTED)
>> avrcp_disconnect(dev);
>> }
>> break;
>> - case SINK_STATE_CONNECTING:
>> - break;
>> - case SINK_STATE_CONNECTED:
>> - break;
>> - case SINK_STATE_PLAYING:
>> + case BTD_SERVICE_STATE_CONNECTING:
>> + case BTD_SERVICE_STATE_CONNECTED:
>> + case BTD_SERVICE_STATE_DISCONNECTING:
>> break;
>> }
>> }
>> @@ -222,6 +221,20 @@ static void device_avctp_cb(struct audio_device *dev, avctp_state_t old_state,
>> }
>> }
>>
>> +static void service_cb(struct btd_service *service,
>> + btd_service_state_t old_state,
>> + btd_service_state_t new_state,
>> + void *user_data)
>> +{
>> + struct audio_device *dev = user_data;
>> +
>> + if (dev->btd_dev != btd_service_get_device(service))
>> + return;
>> +
>> + if (service == dev->sink)
>> + device_sink_cb(dev, old_state, new_state);
>> +}
>> +
>> struct audio_device *audio_device_register(struct btd_device *device)
>> {
>> struct audio_device *dev;
>> @@ -236,8 +249,7 @@ struct audio_device *audio_device_register(struct btd_device *device)
>> dev->priv->dc_id = device_add_disconnect_watch(dev->btd_dev,
>> disconnect_cb, dev,
>> NULL);
>> - dev->priv->sink_callback_id = sink_add_state_cb(dev, device_sink_cb,
>> - NULL);
>> + dev->priv->service_cb_id = btd_service_add_state_cb(service_cb, dev);
>> dev->priv->avdtp_callback_id = avdtp_add_state_cb(dev, device_avdtp_cb);
>> dev->priv->avctp_callback_id = avctp_add_state_cb(dev, device_avctp_cb);
>>
>> diff --git a/profiles/audio/device.h b/profiles/audio/device.h
>> index 286bcdd..e24bdf9 100644
>> --- a/profiles/audio/device.h
>> +++ b/profiles/audio/device.h
>> @@ -25,13 +25,12 @@
>> struct audio_device;
>> struct source;
>> struct control;
>> -struct sink;
>> struct dev_priv;
>>
>> struct audio_device {
>> struct btd_device *btd_dev;
>>
>> - struct sink *sink;
>> + struct btd_service *sink;
>> struct source *source;
>> struct control *control;
>>
>> diff --git a/profiles/audio/sink.c b/profiles/audio/sink.c
>> index 3969417..f5b4e67 100644
>> --- a/profiles/audio/sink.c
>> +++ b/profiles/audio/sink.c
>> @@ -87,7 +87,7 @@ static char *str_state[] = {
>>
>> static void sink_set_state(struct audio_device *dev, sink_state_t new_state)
>> {
>> - struct sink *sink = dev->sink;
>> + struct sink *sink = btd_service_get_user_data(dev->sink);
>> sink_state_t old_state = sink->state;
>> GSList *l;
>>
>> @@ -119,7 +119,7 @@ static void avdtp_state_callback(struct audio_device *dev,
>> avdtp_session_state_t old_state,
>> avdtp_session_state_t new_state)
>> {
>> - struct sink *sink = dev->sink;
>> + struct sink *sink = btd_service_get_user_data(dev->sink);
>>
>> switch (new_state) {
>> case AVDTP_SESSION_STATE_DISCONNECTED:
>> @@ -142,7 +142,7 @@ static void stream_state_changed(struct avdtp_stream *stream,
>> void *user_data)
>> {
>> struct audio_device *dev = user_data;
>> - struct sink *sink = dev->sink;
>> + struct sink *sink = btd_service_get_user_data(dev->sink);
>>
>> if (err)
>> return;
>> @@ -291,8 +291,10 @@ failed:
>> sink->session = NULL;
>> }
>>
>> -gboolean sink_setup_stream(struct sink *sink, struct avdtp *session)
>> +gboolean sink_setup_stream(struct audio_device *dev, struct avdtp *session)
>> {
>> + struct sink *sink = btd_service_get_user_data(dev->sink);
>> +
>> if (sink->connect_id > 0 || sink->disconnect_id > 0)
>> return FALSE;
>>
>> @@ -310,7 +312,7 @@ gboolean sink_setup_stream(struct sink *sink, struct avdtp *session)
>>
>> int sink_connect(struct audio_device *dev)
>> {
>> - struct sink *sink = dev->sink;
>> + struct sink *sink = btd_service_get_user_data(dev->sink);
>>
>> if (!sink->session)
>> sink->session = avdtp_get(dev);
>> @@ -326,7 +328,7 @@ int sink_connect(struct audio_device *dev)
>> if (sink->stream_state >= AVDTP_STATE_OPEN)
>> return -EALREADY;
>>
>> - if (!sink_setup_stream(sink, NULL)) {
>> + if (!sink_setup_stream(dev, NULL)) {
>> DBG("Failed to create a stream");
>> return -EIO;
>> }
>> @@ -338,7 +340,7 @@ int sink_connect(struct audio_device *dev)
>>
>> static void sink_free(struct audio_device *dev)
>> {
>> - struct sink *sink = dev->sink;
>> + struct sink *sink = btd_service_get_user_data(dev->sink);
>>
>> if (sink->cb_id)
>> avdtp_stream_remove_cb(sink->session, sink->stream,
>> @@ -375,7 +377,8 @@ void sink_unregister(struct audio_device *dev)
>> sink_free(dev);
>> }
>>
>> -struct sink *sink_init(struct audio_device *dev, struct btd_service *service)
>> +struct btd_service *sink_init(struct audio_device *dev,
>> + struct btd_service *service)
>
> Why not make the return type bool or even void?
>
> Another interesting alternative would be to return 'int', such that
> the function eventually matches the btd_profile probe callback, and
> therefore the manager can be bypassed.

They idea here is that it would work as a ref so the return is stored
in audio_device but you are right we can probably return int to match
probe, gonna change this.

>
>> {
>> struct sink *sink;
>>
>> @@ -388,12 +391,14 @@ struct sink *sink_init(struct audio_device *dev, struct btd_service *service)
>>
>> sink->avdtp_callback_id = avdtp_add_state_cb(dev, avdtp_state_callback);
>>
>> - return sink;
>> + btd_service_set_user_data(service, sink);
>> +
>> + return service;
>> }
>>
>> gboolean sink_is_active(struct audio_device *dev)
>> {
>> - struct sink *sink = dev->sink;
>> + struct sink *sink = btd_service_get_user_data(dev->sink);
>>
>> if (sink->session)
>> return TRUE;
>> @@ -404,7 +409,7 @@ gboolean sink_is_active(struct audio_device *dev)
>> gboolean sink_new_stream(struct audio_device *dev, struct avdtp *session,
>> struct avdtp_stream *stream)
>> {
>> - struct sink *sink = dev->sink;
>> + struct sink *sink = btd_service_get_user_data(dev->sink);
>>
>> if (sink->stream)
>> return FALSE;
>> @@ -422,7 +427,7 @@ gboolean sink_new_stream(struct audio_device *dev, struct avdtp *session,
>>
>> int sink_disconnect(struct audio_device *dev, gboolean shutdown)
>> {
>> - struct sink *sink = dev->sink;
>> + struct sink *sink = btd_service_get_user_data(dev->sink);
>>
>> if (!sink->session)
>> return -ENOTCONN;
>> diff --git a/profiles/audio/sink.h b/profiles/audio/sink.h
>> index 1a80756..e3f974b 100644
>> --- a/profiles/audio/sink.h
>> +++ b/profiles/audio/sink.h
>> @@ -40,11 +40,12 @@ unsigned int sink_add_state_cb(struct audio_device *dev, sink_state_cb cb,
>> void *user_data);
>> gboolean sink_remove_state_cb(unsigned int id);
>>
>> -struct sink *sink_init(struct audio_device *dev, struct btd_service *service);
>> +struct btd_service *sink_init(struct audio_device *dev,
>> + struct btd_service *service);
>> void sink_unregister(struct audio_device *dev);
>> gboolean sink_is_active(struct audio_device *dev);
>> int sink_connect(struct audio_device *dev);
>> gboolean sink_new_stream(struct audio_device *dev, struct avdtp *session,
>> struct avdtp_stream *stream);
>> -gboolean sink_setup_stream(struct sink *sink, struct avdtp *session);
>> +gboolean sink_setup_stream(struct audio_device *dev, struct avdtp *session);
>
> Is there any reason not to use btd_service here directly, as later
> changed in patch 4?

The idea is to pack as little changes as possible, but I will take a
look perhaps such a change can be done sooner rather than latter.


--
Luiz Augusto von Dentz

2013-07-04 06:36:16

by Mikel Astiz

[permalink] [raw]
Subject: Re: [RFC 01/20] audio/sink: Use service user_data for private data

Hi Luiz,

On Wed, Jul 3, 2013 at 5:15 PM, Luiz Augusto von Dentz
<[email protected]> wrote:
> From: Luiz Augusto von Dentz <[email protected]>
>
> This remove the need of forward declaration of struct sink and prepare
> for a complete removal of struct audio_device.
> ---
> profiles/audio/avdtp.c | 2 +-
> profiles/audio/device.c | 54 ++++++++++++++++++++++++++++++-------------------
> profiles/audio/device.h | 3 +--
> profiles/audio/sink.c | 29 +++++++++++++++-----------
> profiles/audio/sink.h | 5 +++--
> 5 files changed, 55 insertions(+), 38 deletions(-)
>
> diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
> index bd73572..0d67e67 100644
> --- a/profiles/audio/avdtp.c
> +++ b/profiles/audio/avdtp.c
> @@ -1165,7 +1165,7 @@ static gboolean disconnect_timeout(gpointer user_data)
> dev = manager_get_audio_device(session->device, FALSE);
>
> if (dev && dev->sink && stream_setup)
> - sink_setup_stream(dev->sink, session);
> + sink_setup_stream(dev, session);
> else if (dev && dev->source && stream_setup)
> source_setup_stream(dev->source, session);
> else
> diff --git a/profiles/audio/device.c b/profiles/audio/device.c
> index 3fa49ad..f11c728 100644
> --- a/profiles/audio/device.c
> +++ b/profiles/audio/device.c
> @@ -42,10 +42,12 @@
> #include <dbus/dbus.h>
> #include <gdbus/gdbus.h>
>
> -#include "log.h"
> -#include "../src/adapter.h"
> -#include "../src/device.h"
> +#include "lib/uuid.h"
> +#include "src/adapter.h"
> +#include "src/device.h"
> +#include "src/service.h"
>
> +#include "log.h"
> #include "error.h"
> #include "dbus-common.h"
> #include "device.h"
> @@ -61,7 +63,7 @@
> #define AVDTP_CONNECT_TIMEOUT_BOOST 1
>
> struct dev_priv {
> - sink_state_t sink_state;
> + btd_service_state_t sink_state;
> avctp_state_t avctp_state;
>
> guint control_timer;
> @@ -69,9 +71,9 @@ struct dev_priv {
>
> gboolean disconnecting;
>
> + unsigned int service_cb_id;
> unsigned int avdtp_callback_id;
> unsigned int avctp_callback_id;
> - unsigned int sink_callback_id;
> };
>
> static void device_free(struct audio_device *dev)
> @@ -87,7 +89,7 @@ static void device_free(struct audio_device *dev)
>
> avdtp_remove_state_cb(priv->avdtp_callback_id);
> avctp_remove_state_cb(priv->avctp_callback_id);
> - sink_remove_state_cb(priv->sink_callback_id);
> + btd_service_remove_state_cb(priv->service_cb_id);
>
> g_free(priv);
> }
> @@ -138,6 +140,7 @@ static void disconnect_cb(struct btd_device *btd_dev, gboolean removal,
> {
> struct audio_device *dev = user_data;
> struct dev_priv *priv = dev->priv;
> + struct btd_service *sink;
>
> if (priv->disconnecting)
> return;
> @@ -149,7 +152,8 @@ static void disconnect_cb(struct btd_device *btd_dev, gboolean removal,
> if (dev->control && priv->avctp_state != AVCTP_STATE_DISCONNECTED)
> avrcp_disconnect(dev);
>
> - if (dev->sink && priv->sink_state != SINK_STATE_DISCONNECTED)
> + sink = btd_device_get_service(btd_dev, A2DP_SINK_UUID);
> + if (sink)
> sink_disconnect(dev, TRUE);
> else
> priv->disconnecting = FALSE;
> @@ -171,30 +175,25 @@ static void device_avdtp_cb(struct audio_device *dev, struct avdtp *session,
> }
>
> static void device_sink_cb(struct audio_device *dev,
> - sink_state_t old_state,
> - sink_state_t new_state,
> - void *user_data)
> + btd_service_state_t old_state,
> + btd_service_state_t new_state)
> {
> struct dev_priv *priv = dev->priv;
>
> - if (!dev->sink)
> - return;
> -
> priv->sink_state = new_state;
>
> switch (new_state) {
> - case SINK_STATE_DISCONNECTED:
> + case BTD_SERVICE_STATE_UNAVAILABLE:
> + case BTD_SERVICE_STATE_DISCONNECTED:
> if (dev->control) {
> device_remove_control_timer(dev);
> if (priv->avctp_state != AVCTP_STATE_DISCONNECTED)
> avrcp_disconnect(dev);
> }
> break;
> - case SINK_STATE_CONNECTING:
> - break;
> - case SINK_STATE_CONNECTED:
> - break;
> - case SINK_STATE_PLAYING:
> + case BTD_SERVICE_STATE_CONNECTING:
> + case BTD_SERVICE_STATE_CONNECTED:
> + case BTD_SERVICE_STATE_DISCONNECTING:
> break;
> }
> }
> @@ -222,6 +221,20 @@ static void device_avctp_cb(struct audio_device *dev, avctp_state_t old_state,
> }
> }
>
> +static void service_cb(struct btd_service *service,
> + btd_service_state_t old_state,
> + btd_service_state_t new_state,
> + void *user_data)
> +{
> + struct audio_device *dev = user_data;
> +
> + if (dev->btd_dev != btd_service_get_device(service))
> + return;
> +
> + if (service == dev->sink)
> + device_sink_cb(dev, old_state, new_state);
> +}
> +
> struct audio_device *audio_device_register(struct btd_device *device)
> {
> struct audio_device *dev;
> @@ -236,8 +249,7 @@ struct audio_device *audio_device_register(struct btd_device *device)
> dev->priv->dc_id = device_add_disconnect_watch(dev->btd_dev,
> disconnect_cb, dev,
> NULL);
> - dev->priv->sink_callback_id = sink_add_state_cb(dev, device_sink_cb,
> - NULL);
> + dev->priv->service_cb_id = btd_service_add_state_cb(service_cb, dev);
> dev->priv->avdtp_callback_id = avdtp_add_state_cb(dev, device_avdtp_cb);
> dev->priv->avctp_callback_id = avctp_add_state_cb(dev, device_avctp_cb);
>
> diff --git a/profiles/audio/device.h b/profiles/audio/device.h
> index 286bcdd..e24bdf9 100644
> --- a/profiles/audio/device.h
> +++ b/profiles/audio/device.h
> @@ -25,13 +25,12 @@
> struct audio_device;
> struct source;
> struct control;
> -struct sink;
> struct dev_priv;
>
> struct audio_device {
> struct btd_device *btd_dev;
>
> - struct sink *sink;
> + struct btd_service *sink;
> struct source *source;
> struct control *control;
>
> diff --git a/profiles/audio/sink.c b/profiles/audio/sink.c
> index 3969417..f5b4e67 100644
> --- a/profiles/audio/sink.c
> +++ b/profiles/audio/sink.c
> @@ -87,7 +87,7 @@ static char *str_state[] = {
>
> static void sink_set_state(struct audio_device *dev, sink_state_t new_state)
> {
> - struct sink *sink = dev->sink;
> + struct sink *sink = btd_service_get_user_data(dev->sink);
> sink_state_t old_state = sink->state;
> GSList *l;
>
> @@ -119,7 +119,7 @@ static void avdtp_state_callback(struct audio_device *dev,
> avdtp_session_state_t old_state,
> avdtp_session_state_t new_state)
> {
> - struct sink *sink = dev->sink;
> + struct sink *sink = btd_service_get_user_data(dev->sink);
>
> switch (new_state) {
> case AVDTP_SESSION_STATE_DISCONNECTED:
> @@ -142,7 +142,7 @@ static void stream_state_changed(struct avdtp_stream *stream,
> void *user_data)
> {
> struct audio_device *dev = user_data;
> - struct sink *sink = dev->sink;
> + struct sink *sink = btd_service_get_user_data(dev->sink);
>
> if (err)
> return;
> @@ -291,8 +291,10 @@ failed:
> sink->session = NULL;
> }
>
> -gboolean sink_setup_stream(struct sink *sink, struct avdtp *session)
> +gboolean sink_setup_stream(struct audio_device *dev, struct avdtp *session)
> {
> + struct sink *sink = btd_service_get_user_data(dev->sink);
> +
> if (sink->connect_id > 0 || sink->disconnect_id > 0)
> return FALSE;
>
> @@ -310,7 +312,7 @@ gboolean sink_setup_stream(struct sink *sink, struct avdtp *session)
>
> int sink_connect(struct audio_device *dev)
> {
> - struct sink *sink = dev->sink;
> + struct sink *sink = btd_service_get_user_data(dev->sink);
>
> if (!sink->session)
> sink->session = avdtp_get(dev);
> @@ -326,7 +328,7 @@ int sink_connect(struct audio_device *dev)
> if (sink->stream_state >= AVDTP_STATE_OPEN)
> return -EALREADY;
>
> - if (!sink_setup_stream(sink, NULL)) {
> + if (!sink_setup_stream(dev, NULL)) {
> DBG("Failed to create a stream");
> return -EIO;
> }
> @@ -338,7 +340,7 @@ int sink_connect(struct audio_device *dev)
>
> static void sink_free(struct audio_device *dev)
> {
> - struct sink *sink = dev->sink;
> + struct sink *sink = btd_service_get_user_data(dev->sink);
>
> if (sink->cb_id)
> avdtp_stream_remove_cb(sink->session, sink->stream,
> @@ -375,7 +377,8 @@ void sink_unregister(struct audio_device *dev)
> sink_free(dev);
> }
>
> -struct sink *sink_init(struct audio_device *dev, struct btd_service *service)
> +struct btd_service *sink_init(struct audio_device *dev,
> + struct btd_service *service)

Why not make the return type bool or even void?

Another interesting alternative would be to return 'int', such that
the function eventually matches the btd_profile probe callback, and
therefore the manager can be bypassed.

> {
> struct sink *sink;
>
> @@ -388,12 +391,14 @@ struct sink *sink_init(struct audio_device *dev, struct btd_service *service)
>
> sink->avdtp_callback_id = avdtp_add_state_cb(dev, avdtp_state_callback);
>
> - return sink;
> + btd_service_set_user_data(service, sink);
> +
> + return service;
> }
>
> gboolean sink_is_active(struct audio_device *dev)
> {
> - struct sink *sink = dev->sink;
> + struct sink *sink = btd_service_get_user_data(dev->sink);
>
> if (sink->session)
> return TRUE;
> @@ -404,7 +409,7 @@ gboolean sink_is_active(struct audio_device *dev)
> gboolean sink_new_stream(struct audio_device *dev, struct avdtp *session,
> struct avdtp_stream *stream)
> {
> - struct sink *sink = dev->sink;
> + struct sink *sink = btd_service_get_user_data(dev->sink);
>
> if (sink->stream)
> return FALSE;
> @@ -422,7 +427,7 @@ gboolean sink_new_stream(struct audio_device *dev, struct avdtp *session,
>
> int sink_disconnect(struct audio_device *dev, gboolean shutdown)
> {
> - struct sink *sink = dev->sink;
> + struct sink *sink = btd_service_get_user_data(dev->sink);
>
> if (!sink->session)
> return -ENOTCONN;
> diff --git a/profiles/audio/sink.h b/profiles/audio/sink.h
> index 1a80756..e3f974b 100644
> --- a/profiles/audio/sink.h
> +++ b/profiles/audio/sink.h
> @@ -40,11 +40,12 @@ unsigned int sink_add_state_cb(struct audio_device *dev, sink_state_cb cb,
> void *user_data);
> gboolean sink_remove_state_cb(unsigned int id);
>
> -struct sink *sink_init(struct audio_device *dev, struct btd_service *service);
> +struct btd_service *sink_init(struct audio_device *dev,
> + struct btd_service *service);
> void sink_unregister(struct audio_device *dev);
> gboolean sink_is_active(struct audio_device *dev);
> int sink_connect(struct audio_device *dev);
> gboolean sink_new_stream(struct audio_device *dev, struct avdtp *session,
> struct avdtp_stream *stream);
> -gboolean sink_setup_stream(struct sink *sink, struct avdtp *session);
> +gboolean sink_setup_stream(struct audio_device *dev, struct avdtp *session);

Is there any reason not to use btd_service here directly, as later
changed in patch 4?

> int sink_disconnect(struct audio_device *dev, gboolean shutdown);
> --

Otherwise the patch looks good to me.

Cheers,
Mikel

2013-07-03 15:15:41

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 20/20] audio/source: Fix not notifying service about connection state

From: Luiz Augusto von Dentz <[email protected]>

btd_service_connecting_complete should be called whenever the service
is connected otherwise the service state will not be consistent.
---
profiles/audio/source.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/profiles/audio/source.c b/profiles/audio/source.c
index 64570a6..c171620 100644
--- a/profiles/audio/source.c
+++ b/profiles/audio/source.c
@@ -163,6 +163,7 @@ static void stream_state_changed(struct avdtp_stream *stream,
source->cb_id = 0;
break;
case AVDTP_STATE_OPEN:
+ btd_service_connecting_complete(source->service, 0);
source_set_state(source, SOURCE_STATE_CONNECTED);
break;
case AVDTP_STATE_STREAMING:
@@ -211,11 +212,8 @@ static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep,

source->connect_id = 0;

- if (stream) {
- DBG("Stream successfully created");
- btd_service_connecting_complete(source->service, 0);
+ if (stream)
return;
- }

avdtp_unref(source->session);
source->session = NULL;
--
1.8.1.4


2013-07-03 15:15:39

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 18/20] plugins/policy: Reword audio policy code in a simple plugin

From: Luiz Augusto von Dentz <[email protected]>

This moves audio device policy to a plugin and removes any dependency of
audio plugin to it.
---
Makefile.plugins | 4 +-
plugins/policy.c | 341 ++++++++++++++++++++++++++++++++++++++++++++++++
profiles/audio/device.c | 280 ---------------------------------------
profiles/audio/device.h | 40 ------
4 files changed, 344 insertions(+), 321 deletions(-)
create mode 100644 plugins/policy.c
delete mode 100644 profiles/audio/device.c
delete mode 100644 profiles/audio/device.h

diff --git a/Makefile.plugins b/Makefile.plugins
index 3efe849..7fd9e2d 100644
--- a/Makefile.plugins
+++ b/Makefile.plugins
@@ -8,6 +8,9 @@ builtin_sources += plugins/wiimote.c
builtin_modules += autopair
builtin_sources += plugins/autopair.c

+builtin_modules += policy
+builtin_sources += plugins/policy.c
+
if MAINTAINER_MODE
builtin_modules += gatt_example
builtin_sources += plugins/gatt-example.c
@@ -33,7 +36,6 @@ builtin_sources += profiles/audio/main.c \
profiles/audio/control.h profiles/audio/control.c \
profiles/audio/avctp.h profiles/audio/avctp.c \
profiles/audio/avrcp.h profiles/audio/avrcp.c \
- profiles/audio/device.h profiles/audio/device.c \
profiles/audio/source.h profiles/audio/source.c \
profiles/audio/sink.h profiles/audio/sink.c \
profiles/audio/a2dp.h profiles/audio/a2dp.c \
diff --git a/plugins/policy.c b/plugins/policy.c
new file mode 100644
index 0000000..97393a9
--- /dev/null
+++ b/plugins/policy.c
@@ -0,0 +1,341 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2006-2010 Nokia Corporation
+ * Copyright (C) 2004-2010 Marcel Holtmann <[email protected]>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <glib.h>
+
+#include "lib/uuid.h"
+#include "src/log.h"
+#include "src/plugin.h"
+#include "src/adapter.h"
+#include "src/device.h"
+#include "src/service.h"
+#include "src/profile.h"
+
+#define CONTROL_CONNECT_TIMEOUT 2
+
+static unsigned int service_id = 0;
+static GSList *devices = NULL;
+
+struct policy_data {
+ struct btd_device *dev;
+
+ guint ct_timer;
+ guint tg_timer;
+ guint dc_id;
+};
+
+static void policy_connect(struct policy_data *data,
+ struct btd_service *service)
+{
+ struct btd_profile *profile = btd_service_get_profile(service);
+
+ DBG("%s profile %s", device_get_path(data->dev), profile->name);
+
+ btd_service_connect(service);
+}
+
+static void policy_disconnect(struct policy_data *data,
+ struct btd_service *service)
+{
+ struct btd_profile *profile = btd_service_get_profile(service);
+
+ DBG("%s profile %s", device_get_path(data->dev), profile->name);
+
+ btd_service_disconnect(service);
+}
+
+static gboolean policy_connect_ct(gpointer user_data)
+{
+ struct policy_data *data = user_data;
+ struct btd_service *service;
+
+ data->ct_timer = 0;
+
+ service = btd_device_get_service(data->dev, AVRCP_REMOTE_UUID);
+ if (service != NULL)
+ policy_connect(data, service);
+
+ return FALSE;
+}
+
+static void policy_set_ct_timer(struct policy_data *data)
+{
+ if (data->ct_timer > 0)
+ g_source_remove(data->ct_timer);
+
+ data->ct_timer = g_timeout_add_seconds(CONTROL_CONNECT_TIMEOUT,
+ policy_connect_ct, data);
+}
+
+static struct policy_data *find_data(struct btd_device *dev)
+{
+ GSList *l;
+
+ for (l = devices; l; l = l->next) {
+ struct policy_data *data = l->data;
+
+ if (data->dev == dev)
+ return data;
+ }
+
+ return NULL;
+}
+
+static void policy_data_remove(void *user_data)
+{
+ struct policy_data *data = user_data;
+
+ if (data->ct_timer > 0)
+ g_source_remove(data->ct_timer);
+
+ if (data->tg_timer > 0)
+ g_source_remove(data->tg_timer);
+
+ if (data->dc_id > 0)
+ device_remove_disconnect_watch(data->dev, data->dc_id);
+
+ g_free(data);
+}
+
+static void disconnect_cb(struct btd_device *dev, gboolean removal,
+ void *user_data)
+{
+ struct policy_data *data = user_data;
+
+ devices = g_slist_remove(devices, data);
+
+ policy_data_remove(data);
+}
+
+static struct policy_data *policy_get_data(struct btd_device *dev)
+{
+ struct policy_data *data;
+
+ data = find_data(dev);
+ if (data != NULL)
+ return data;
+
+ data = g_new0(struct policy_data, 1);
+ data->dev = dev;
+ data->dc_id = device_add_disconnect_watch(dev, disconnect_cb, data,
+ NULL);
+
+ return data;
+}
+
+static void sink_cb(struct btd_device *dev, btd_service_state_t old_state,
+ btd_service_state_t new_state)
+{
+ struct policy_data *data;
+ struct btd_service *controller;
+
+ controller = btd_device_get_service(dev, AVRCP_REMOTE_UUID);
+ if (controller == NULL)
+ return;
+
+ data = policy_get_data(dev);
+
+ switch (new_state) {
+ case BTD_SERVICE_STATE_UNAVAILABLE:
+ case BTD_SERVICE_STATE_DISCONNECTED:
+ if (data->ct_timer > 0) {
+ g_source_remove(data->ct_timer);
+ data->ct_timer = 0;
+ } else if (btd_service_get_state(controller) !=
+ BTD_SERVICE_STATE_DISCONNECTED)
+ policy_disconnect(data, controller);
+ break;
+ case BTD_SERVICE_STATE_CONNECTING:
+ break;
+ case BTD_SERVICE_STATE_CONNECTED:
+ /* Check if service initiate the connection then proceed
+ * immediatelly otherwise set timer
+ */
+ if (old_state == BTD_SERVICE_STATE_CONNECTING)
+ policy_connect(data, controller);
+ else if (btd_service_get_state(controller) !=
+ BTD_SERVICE_STATE_CONNECTED)
+ policy_set_ct_timer(data);
+ break;
+ case BTD_SERVICE_STATE_DISCONNECTING:
+ break;
+ }
+}
+
+static gboolean policy_connect_tg(gpointer user_data)
+{
+ struct policy_data *data = user_data;
+ struct btd_service *service;
+
+ data->tg_timer = 0;
+
+ service = btd_device_get_service(data->dev, AVRCP_TARGET_UUID);
+ if (service != NULL)
+ policy_connect(data, service);
+
+ return FALSE;
+}
+
+static void policy_set_tg_timer(struct policy_data *data)
+{
+ if (data->tg_timer > 0)
+ g_source_remove(data->ct_timer);
+
+ data->tg_timer = g_timeout_add_seconds(CONTROL_CONNECT_TIMEOUT,
+ policy_connect_tg,
+ data);
+}
+
+static void source_cb(struct btd_device *dev, btd_service_state_t old_state,
+ btd_service_state_t new_state)
+{
+ struct policy_data *data;
+ struct btd_service *target;
+
+ target = btd_device_get_service(dev, AVRCP_TARGET_UUID);
+ if (target == NULL)
+ return;
+
+ data = policy_get_data(dev);
+
+ switch (new_state) {
+ case BTD_SERVICE_STATE_UNAVAILABLE:
+ case BTD_SERVICE_STATE_DISCONNECTED:
+ if (data->tg_timer > 0) {
+ g_source_remove(data->tg_timer);
+ data->tg_timer = 0;
+ } else if (btd_service_get_state(target) !=
+ BTD_SERVICE_STATE_DISCONNECTED)
+ policy_disconnect(data, target);
+ break;
+ case BTD_SERVICE_STATE_CONNECTING:
+ break;
+ case BTD_SERVICE_STATE_CONNECTED:
+ /* Check if service initiate the connection then proceed
+ * immediatelly otherwise set timer
+ */
+ if (old_state == BTD_SERVICE_STATE_CONNECTING)
+ policy_connect(data, target);
+ else if (btd_service_get_state(target) !=
+ BTD_SERVICE_STATE_CONNECTED)
+ policy_set_tg_timer(data);
+ break;
+ case BTD_SERVICE_STATE_DISCONNECTING:
+ break;
+ }
+}
+
+static void controller_cb(struct btd_device *dev,
+ btd_service_state_t old_state,
+ btd_service_state_t new_state)
+{
+ struct policy_data *data;
+
+ data = find_data(dev);
+ if (data == NULL)
+ return;
+
+ switch (new_state) {
+ case BTD_SERVICE_STATE_UNAVAILABLE:
+ case BTD_SERVICE_STATE_DISCONNECTED:
+ break;
+ case BTD_SERVICE_STATE_CONNECTING:
+ break;
+ case BTD_SERVICE_STATE_CONNECTED:
+ if (data->ct_timer > 0) {
+ g_source_remove(data->ct_timer);
+ data->ct_timer = 0;
+ }
+ case BTD_SERVICE_STATE_DISCONNECTING:
+ break;
+ }
+}
+
+static void target_cb(struct btd_device *dev, btd_service_state_t old_state,
+ btd_service_state_t new_state)
+{
+ struct policy_data *data;
+
+ data = find_data(dev);
+ if (data == NULL)
+ return;
+
+ switch (new_state) {
+ case BTD_SERVICE_STATE_UNAVAILABLE:
+ case BTD_SERVICE_STATE_DISCONNECTED:
+ break;
+ case BTD_SERVICE_STATE_CONNECTING:
+ break;
+ case BTD_SERVICE_STATE_CONNECTED:
+ if (data->tg_timer > 0) {
+ g_source_remove(data->tg_timer);
+ data->tg_timer = 0;
+ }
+ case BTD_SERVICE_STATE_DISCONNECTING:
+ break;
+ }
+}
+
+static void service_cb(struct btd_service *service,
+ btd_service_state_t old_state,
+ btd_service_state_t new_state,
+ void *user_data)
+{
+ struct btd_device *dev = btd_service_get_device(service);
+ struct btd_profile *profile = btd_service_get_profile(service);
+
+ if (g_str_equal(profile->remote_uuid, A2DP_SINK_UUID))
+ sink_cb(dev, old_state, new_state);
+ else if (g_str_equal(profile->remote_uuid, A2DP_SOURCE_UUID))
+ source_cb(dev, old_state, new_state);
+ else if (g_str_equal(profile->remote_uuid, AVRCP_REMOTE_UUID))
+ controller_cb(dev, old_state, new_state);
+ else if (g_str_equal(profile->remote_uuid, AVRCP_TARGET_UUID))
+ target_cb(dev, old_state, new_state);
+}
+
+static int policy_init(void)
+{
+ service_id = btd_service_add_state_cb(service_cb, NULL);
+
+ return 0;
+}
+
+static void policy_exit(void)
+{
+ g_slist_free_full(devices, policy_data_remove);
+
+ btd_service_remove_state_cb(service_id);
+}
+
+BLUETOOTH_PLUGIN_DEFINE(policy, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
+ policy_init, policy_exit)
diff --git a/profiles/audio/device.c b/profiles/audio/device.c
deleted file mode 100644
index 9b2e393..0000000
--- a/profiles/audio/device.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- *
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2006-2010 Nokia Corporation
- * Copyright (C) 2004-2010 Marcel Holtmann <[email protected]>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdbool.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <netinet/in.h>
-
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
-
-#include <glib.h>
-#include <dbus/dbus.h>
-#include <gdbus/gdbus.h>
-
-#include "lib/uuid.h"
-#include "src/adapter.h"
-#include "src/device.h"
-#include "src/service.h"
-
-#include "log.h"
-#include "error.h"
-#include "dbus-common.h"
-#include "device.h"
-#include "avdtp.h"
-#include "control.h"
-#include "avctp.h"
-#include "avrcp.h"
-#include "sink.h"
-#include "source.h"
-
-#define CONTROL_CONNECT_TIMEOUT 2
-#define AVDTP_CONNECT_TIMEOUT 1
-#define AVDTP_CONNECT_TIMEOUT_BOOST 1
-
-struct dev_priv {
- btd_service_state_t sink_state;
- avctp_state_t avctp_state;
-
- guint control_timer;
- guint dc_id;
-
- gboolean disconnecting;
-
- unsigned int service_cb_id;
- unsigned int avdtp_callback_id;
- unsigned int avctp_callback_id;
-};
-
-static void device_free(struct audio_device *dev)
-{
- struct dev_priv *priv = dev->priv;
-
- if (priv) {
- if (priv->control_timer)
- g_source_remove(priv->control_timer);
- if (priv->dc_id)
- device_remove_disconnect_watch(dev->btd_dev,
- priv->dc_id);
-
- avdtp_remove_state_cb(priv->avdtp_callback_id);
- avctp_remove_state_cb(priv->avctp_callback_id);
- btd_service_remove_state_cb(priv->service_cb_id);
-
- g_free(priv);
- }
-
- btd_device_unref(dev->btd_dev);
-
- g_free(dev);
-}
-
-static gboolean control_connect_timeout(gpointer user_data)
-{
- struct audio_device *dev = user_data;
-
- dev->priv->control_timer = 0;
-
- if (dev->control)
- avrcp_connect(dev->btd_dev);
-
- return FALSE;
-}
-
-static gboolean device_set_control_timer(struct audio_device *dev)
-{
- struct dev_priv *priv = dev->priv;
-
- if (!dev->control)
- return FALSE;
-
- if (priv->control_timer)
- return FALSE;
-
- priv->control_timer = g_timeout_add_seconds(CONTROL_CONNECT_TIMEOUT,
- control_connect_timeout,
- dev);
-
- return TRUE;
-}
-
-static void device_remove_control_timer(struct audio_device *dev)
-{
- if (dev->priv->control_timer)
- g_source_remove(dev->priv->control_timer);
- dev->priv->control_timer = 0;
-}
-
-static void disconnect_cb(struct btd_device *btd_dev, gboolean removal,
- void *user_data)
-{
- struct audio_device *dev = user_data;
- struct dev_priv *priv = dev->priv;
- struct btd_service *sink;
-
- if (priv->disconnecting)
- return;
-
- priv->disconnecting = TRUE;
-
- device_remove_control_timer(dev);
-
- if (dev->control && priv->avctp_state != AVCTP_STATE_DISCONNECTED)
- avrcp_disconnect(dev->btd_dev);
-
- sink = btd_device_get_service(btd_dev, A2DP_SINK_UUID);
- if (sink)
- sink_disconnect(sink, TRUE);
- else
- priv->disconnecting = FALSE;
-}
-
-static void device_avdtp_cb(struct btd_device *device, struct avdtp *session,
- avdtp_session_state_t old_state,
- avdtp_session_state_t new_state,
- void *user_data)
-{
- struct audio_device *dev = user_data;
-
- if (!dev->control)
- return;
-
- if (new_state == AVDTP_SESSION_STATE_CONNECTED) {
- if (avdtp_stream_setup_active(session))
- device_set_control_timer(dev);
- else
- avrcp_connect(dev->btd_dev);
- }
-}
-
-static void device_sink_cb(struct audio_device *dev,
- btd_service_state_t old_state,
- btd_service_state_t new_state)
-{
- struct dev_priv *priv = dev->priv;
-
- priv->sink_state = new_state;
-
- switch (new_state) {
- case BTD_SERVICE_STATE_UNAVAILABLE:
- case BTD_SERVICE_STATE_DISCONNECTED:
- if (dev->control) {
- device_remove_control_timer(dev);
- if (priv->avctp_state != AVCTP_STATE_DISCONNECTED)
- avrcp_disconnect(dev->btd_dev);
- }
- break;
- case BTD_SERVICE_STATE_CONNECTING:
- case BTD_SERVICE_STATE_CONNECTED:
- case BTD_SERVICE_STATE_DISCONNECTING:
- break;
- }
-}
-
-static void device_avctp_cb(struct btd_device *device, avctp_state_t old_state,
- avctp_state_t new_state, void *user_data)
-{
- struct audio_device *dev = user_data;
-
- if (!dev->control)
- return;
-
- dev->priv->avctp_state = new_state;
-
- switch (new_state) {
- case AVCTP_STATE_DISCONNECTED:
- break;
- case AVCTP_STATE_CONNECTING:
- device_remove_control_timer(dev);
- break;
- case AVCTP_STATE_CONNECTED:
- break;
- case AVCTP_STATE_BROWSING_CONNECTING:
- break;
- case AVCTP_STATE_BROWSING_CONNECTED:
- break;
- }
-}
-
-static void service_cb(struct btd_service *service,
- btd_service_state_t old_state,
- btd_service_state_t new_state,
- void *user_data)
-{
- struct audio_device *dev = user_data;
-
- if (dev->btd_dev != btd_service_get_device(service))
- return;
-
- if (service == dev->sink)
- device_sink_cb(dev, old_state, new_state);
-}
-
-struct audio_device *audio_device_register(struct btd_device *device)
-{
- struct audio_device *dev;
-
- DBG("%s", device_get_path(device));
-
- dev = g_new0(struct audio_device, 1);
-
- dev->btd_dev = btd_device_ref(device);
- dev->priv = g_new0(struct dev_priv, 1);
-
- dev->priv->dc_id = device_add_disconnect_watch(dev->btd_dev,
- disconnect_cb, dev,
- NULL);
- dev->priv->service_cb_id = btd_service_add_state_cb(service_cb, dev);
- dev->priv->avdtp_callback_id = avdtp_add_state_cb(device,
- device_avdtp_cb, dev);
- dev->priv->avctp_callback_id = avctp_add_state_cb(device,
- device_avctp_cb, dev);
-
- return dev;
-}
-
-void audio_device_unregister(struct audio_device *device)
-{
- DBG("%s", device_get_path(device->btd_dev));
-
- if (device->sink)
- sink_unregister(device->sink);
-
- if (device->source)
- source_unregister(device->source);
-
- if (device->control)
- control_unregister(device->control);
-
- device_free(device);
-}
diff --git a/profiles/audio/device.h b/profiles/audio/device.h
deleted file mode 100644
index 87fc067..0000000
--- a/profiles/audio/device.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2006-2010 Nokia Corporation
- * Copyright (C) 2004-2010 Marcel Holtmann <[email protected]>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-struct audio_device;
-struct dev_priv;
-
-struct audio_device {
- struct btd_device *btd_dev;
-
- struct btd_service *sink;
- struct btd_service *source;
- struct btd_service *control;
-
- struct dev_priv *priv;
-};
-
-struct audio_device *audio_device_register(struct btd_device *device);
-
-void audio_device_unregister(struct audio_device *device);
--
1.8.1.4


2013-07-03 15:15:40

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 19/20] audio/sink: Fix not notifying service about connection state

From: Luiz Augusto von Dentz <[email protected]>

btd_service_connecting_complete should be called whenever the service
is connected otherwise the service state will not be consistent.
---
profiles/audio/sink.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/profiles/audio/sink.c b/profiles/audio/sink.c
index bb9ab21..5206920 100644
--- a/profiles/audio/sink.c
+++ b/profiles/audio/sink.c
@@ -164,6 +164,7 @@ static void stream_state_changed(struct avdtp_stream *stream,
sink->cb_id = 0;
break;
case AVDTP_STATE_OPEN:
+ btd_service_connecting_complete(sink->service, 0);
sink_set_state(sink, SINK_STATE_CONNECTED);
break;
case AVDTP_STATE_STREAMING:
@@ -212,11 +213,8 @@ static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep,

sink->connect_id = 0;

- if (stream) {
- DBG("Stream successfully created");
- btd_service_connecting_complete(sink->service, 0);
+ if (stream)
return;
- }

avdtp_unref(sink->session);
sink->session = NULL;
--
1.8.1.4


2013-07-03 15:15:37

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 16/20] audio/manager: Remove dependency on struct audio_device

From: Luiz Augusto von Dentz <[email protected]>

This is part of the work necessary to completely remove
struct audio_device
---
profiles/audio/manager.c | 132 +++++++++++++----------------------------------
profiles/audio/manager.h | 10 ----
2 files changed, 37 insertions(+), 105 deletions(-)

diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index 4aaf960..785d165 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
@@ -50,13 +50,12 @@

#include "lib/uuid.h"
#include "glib-helper.h"
-#include "../src/adapter.h"
-#include "../src/device.h"
-#include "../src/profile.h"
-#include "../src/service.h"
+#include "src/adapter.h"
+#include "src/device.h"
+#include "src/profile.h"
+#include "src/service.h"

#include "log.h"
-#include "device.h"
#include "error.h"
#include "avdtp.h"
#include "media.h"
@@ -69,107 +68,71 @@
#include "sdpd.h"

static GKeyFile *config = NULL;
-static GSList *devices = NULL;

-static struct audio_device *get_audio_dev(struct btd_device *device)
-{
- return manager_get_audio_device(device, TRUE);
-}
-
-static struct audio_device *manager_find_device(struct btd_device *device)
+static int a2dp_source_probe(struct btd_service *service)
{
- GSList *l;
+ struct btd_device *dev = btd_service_get_device(service);

- for (l = devices; l != NULL; l = l->next) {
- struct audio_device *dev = l->data;
+ DBG("path %s", device_get_path(dev));

- if (dev->btd_dev == device)
- return dev;
- }
+ source_init(service);

- return NULL;
+ return 0;
}

-static void audio_remove(struct btd_service *service)
+static void a2dp_source_remove(struct btd_service *service)
{
- struct btd_device *device = btd_service_get_device(service);
- struct audio_device *dev;
-
- dev = manager_find_device(device);
- if (dev == NULL)
- return;
-
- devices = g_slist_remove(devices, dev);
- audio_device_unregister(dev);
+ source_unregister(service);
}

-static int a2dp_source_probe(struct btd_service *service)
+static int a2dp_sink_probe(struct btd_service *service)
{
- struct btd_device *device = btd_service_get_device(service);
- struct audio_device *audio_dev;
+ struct btd_device *dev = btd_service_get_device(service);

- audio_dev = get_audio_dev(device);
- if (!audio_dev) {
- DBG("unable to get a device object");
- return -1;
- }
+ DBG("path %s", device_get_path(dev));

- audio_dev->source = source_init(service);
+ sink_init(service);

return 0;
}

-static int a2dp_sink_probe(struct btd_service *service)
+static void a2dp_sink_remove(struct btd_service *service)
{
- struct btd_device *device = btd_service_get_device(service);
- struct audio_device *audio_dev;
-
- audio_dev = get_audio_dev(device);
- if (!audio_dev) {
- DBG("unable to get a device object");
- return -1;
- }
-
- audio_dev->sink = sink_init(service);
-
- return 0;
+ sink_unregister(service);
}

static int avrcp_target_probe(struct btd_service *service)
{
- struct btd_device *device = btd_service_get_device(service);
- struct audio_device *audio_dev;
-
- audio_dev = get_audio_dev(device);
- if (!audio_dev) {
- DBG("unable to get a device object");
- return -1;
- }
+ struct btd_device *dev = btd_service_get_device(service);

- audio_dev->control = control_init_target(service);
+ DBG("path %s", device_get_path(dev));

- if (audio_dev->sink && sink_is_active(audio_dev->sink))
- avrcp_connect(audio_dev->btd_dev);
+ control_init_target(service);

return 0;
}

+static void avrcp_target_remove(struct btd_service *service)
+{
+ control_unregister(service);
+}
+
static int avrcp_remote_probe(struct btd_service *service)
{
- struct btd_device *device = btd_service_get_device(service);
- struct audio_device *audio_dev;
+ struct btd_device *dev = btd_service_get_device(service);

- audio_dev = get_audio_dev(device);
- if (!audio_dev) {
- DBG("unable to get a device object");
- return -1;
- }
+ DBG("path %s", device_get_path(dev));

- audio_dev->control = control_init_remote(service);
+ control_init_remote(service);

return 0;
}

+static void avrcp_remote_remove(struct btd_service *service)
+{
+ control_unregister(service);
+}
+
static int a2dp_source_connect(struct btd_service *service)
{
struct btd_device *dev = btd_service_get_device(service);
@@ -314,7 +277,7 @@ static struct btd_profile a2dp_source_profile = {

.remote_uuid = A2DP_SOURCE_UUID,
.device_probe = a2dp_source_probe,
- .device_remove = audio_remove,
+ .device_remove = a2dp_source_remove,

.auto_connect = true,
.connect = a2dp_source_connect,
@@ -330,7 +293,7 @@ static struct btd_profile a2dp_sink_profile = {

.remote_uuid = A2DP_SINK_UUID,
.device_probe = a2dp_sink_probe,
- .device_remove = audio_remove,
+ .device_remove = a2dp_sink_remove,

.auto_connect = true,
.connect = a2dp_sink_connect,
@@ -345,7 +308,7 @@ static struct btd_profile avrcp_target_profile = {

.remote_uuid = AVRCP_TARGET_UUID,
.device_probe = avrcp_target_probe,
- .device_remove = audio_remove,
+ .device_remove = avrcp_target_remove,

.connect = avrcp_target_connect,
.disconnect = avrcp_target_disconnect,
@@ -359,7 +322,7 @@ static struct btd_profile avrcp_remote_profile = {

.remote_uuid = AVRCP_REMOTE_UUID,
.device_probe = avrcp_remote_probe,
- .device_remove = audio_remove,
+ .device_remove = avrcp_remote_remove,

.adapter_probe = avrcp_remote_server_probe,
.adapter_remove = avrcp_remote_server_remove,
@@ -401,27 +364,6 @@ void audio_manager_exit(void)
btd_unregister_adapter_driver(&media_driver);
}

-struct audio_device *manager_get_audio_device(struct btd_device *device,
- gboolean create)
-{
- struct audio_device *dev;
-
- dev = manager_find_device(device);
- if (dev)
- return dev;
-
- if (!create)
- return NULL;
-
- dev = audio_device_register(device);
- if (!dev)
- return NULL;
-
- devices = g_slist_append(devices, dev);
-
- return dev;
-}
-
static void set_fast_connectable(struct btd_adapter *adapter,
gpointer user_data)
{
diff --git a/profiles/audio/manager.h b/profiles/audio/manager.h
index b8d8ef7..de8d791 100644
--- a/profiles/audio/manager.h
+++ b/profiles/audio/manager.h
@@ -22,19 +22,9 @@
*
*/

-struct enabled_interfaces {
- gboolean sink;
- gboolean source;
- gboolean control;
- gboolean media_player;
-};
-
int audio_manager_init(GKeyFile *config);
void audio_manager_exit(void);

-struct audio_device *manager_get_audio_device(struct btd_device *device,
- gboolean create);
-
/* TRUE to enable fast connectable and FALSE to disable fast connectable for all
* audio adapters. */
void manager_set_fast_connectable(gboolean enable);
--
1.8.1.4


2013-07-03 15:15:38

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 17/20] audio/main: Remove dependency on struct audio_device

From: Luiz Augusto von Dentz <[email protected]>

This is part of the work necessary to completely remove
struct audio_device
---
profiles/audio/main.c | 1 -
1 file changed, 1 deletion(-)

diff --git a/profiles/audio/main.c b/profiles/audio/main.c
index adc9e45..996d2af 100644
--- a/profiles/audio/main.c
+++ b/profiles/audio/main.c
@@ -41,7 +41,6 @@
#include "glib-helper.h"
#include "plugin.h"
#include "log.h"
-#include "device.h"
#include "manager.h"

static GKeyFile *load_config_file(const char *file)
--
1.8.1.4


2013-07-03 15:15:36

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 15/20] audio/transport: Remove dependency on struct audio_device

From: Luiz Augusto von Dentz <[email protected]>

This is part of the work necessary to completely remove
struct audio_device
---
profiles/audio/transport.c | 1 -
1 file changed, 1 deletion(-)

diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
index 8d3d91e..087c0ee 100644
--- a/profiles/audio/transport.c
+++ b/profiles/audio/transport.c
@@ -38,7 +38,6 @@

#include "log.h"
#include "error.h"
-#include "device.h"
#include "avdtp.h"
#include "media.h"
#include "transport.h"
--
1.8.1.4


2013-07-03 15:15:34

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 13/20] audio/source: Remove dependency on struct audio_device

From: Luiz Augusto von Dentz <[email protected]>

This is part of the work necessary to completely remove
struct audio_device
---
profiles/audio/manager.c | 2 +-
profiles/audio/source.c | 23 +++++++++--------------
profiles/audio/source.h | 3 +--
3 files changed, 11 insertions(+), 17 deletions(-)

diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index 12c7b10..4aaf960 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
@@ -114,7 +114,7 @@ static int a2dp_source_probe(struct btd_service *service)
return -1;
}

- audio_dev->source = source_init(audio_dev, service);
+ audio_dev->source = source_init(service);

return 0;
}
diff --git a/profiles/audio/source.c b/profiles/audio/source.c
index 87b7309..64570a6 100644
--- a/profiles/audio/source.c
+++ b/profiles/audio/source.c
@@ -40,11 +40,10 @@

#include "log.h"

-#include "../src/adapter.h"
-#include "../src/device.h"
-#include "../src/service.h"
+#include "src/adapter.h"
+#include "src/device.h"
+#include "src/service.h"

-#include "device.h"
#include "avdtp.h"
#include "media.h"
#include "a2dp.h"
@@ -56,7 +55,6 @@
#define STREAM_SETUP_RETRY_TIMER 2

struct source {
- struct audio_device *dev;
struct btd_service *service;
struct avdtp *session;
struct avdtp_stream *stream;
@@ -88,13 +86,13 @@ static char *str_state[] = {

static void source_set_state(struct source *source, source_state_t new_state)
{
- struct audio_device *dev = source->dev;
+ struct btd_device *dev = btd_service_get_device(source->service);
source_state_t old_state = source->state;
GSList *l;

source->state = new_state;

- DBG("State changed %s: %s -> %s", device_get_path(dev->btd_dev),
+ DBG("State changed %s: %s -> %s", device_get_path(dev),
str_state[old_state], str_state[new_state]);

for (l = source_callbacks; l != NULL; l = l->next) {
@@ -345,7 +343,6 @@ int source_connect(struct btd_service *service)
static void source_free(struct btd_service *service)
{
struct source *source = btd_service_get_user_data(service);
- struct audio_device *dev = source->dev;

if (source->cb_id)
avdtp_stream_remove_cb(source->session, source->stream,
@@ -373,7 +370,6 @@ static void source_free(struct btd_service *service)
btd_service_unref(source->service);

g_free(source);
- dev->source = NULL;
}

void source_unregister(struct btd_service *service)
@@ -385,19 +381,18 @@ void source_unregister(struct btd_service *service)
source_free(service);
}

-struct btd_service *source_init(struct audio_device *dev,
- struct btd_service *service)
+struct btd_service *source_init(struct btd_service *service)
{
+ struct btd_device *dev = btd_service_get_device(service);
struct source *source;

- DBG("%s", device_get_path(dev->btd_dev));
+ DBG("%s", device_get_path(dev));

source = g_new0(struct source, 1);

- source->dev = dev;
source->service = btd_service_ref(service);

- source->avdtp_callback_id = avdtp_add_state_cb(dev->btd_dev,
+ source->avdtp_callback_id = avdtp_add_state_cb(dev,
avdtp_state_callback,
source);

diff --git a/profiles/audio/source.h b/profiles/audio/source.h
index b9d4707..4012154 100644
--- a/profiles/audio/source.h
+++ b/profiles/audio/source.h
@@ -41,8 +41,7 @@ unsigned int source_add_state_cb(struct btd_service *service,
source_state_cb cb, void *user_data);
gboolean source_remove_state_cb(unsigned int id);

-struct btd_service *source_init(struct audio_device *dev,
- struct btd_service *service);
+struct btd_service *source_init(struct btd_service *service);
void source_unregister(struct btd_service *service);
int source_connect(struct btd_service *service);
gboolean source_new_stream(struct btd_service *service, struct avdtp *session,
--
1.8.1.4


2013-07-03 15:15:35

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 14/20] audio/media: Remove dependency on struct audio_device

From: Luiz Augusto von Dentz <[email protected]>

This is part of the work necessary to completely remove
struct audio_device
---
profiles/audio/media.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/profiles/audio/media.c b/profiles/audio/media.c
index bb6323d..f1ad439 100644
--- a/profiles/audio/media.c
+++ b/profiles/audio/media.c
@@ -34,15 +34,14 @@
#include <gdbus/gdbus.h>

#include "lib/uuid.h"
-#include "../src/adapter.h"
-#include "../src/device.h"
-#include "../src/dbus-common.h"
-#include "../src/profile.h"
+#include "src/adapter.h"
+#include "src/device.h"
+#include "src/dbus-common.h"
+#include "src/profile.h"

#include "glib-helper.h"
#include "log.h"
#include "error.h"
-#include "device.h"
#include "avdtp.h"
#include "media.h"
#include "transport.h"
--
1.8.1.4


2013-07-03 15:15:33

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 12/20] audio/sink: Remove dependency on struct audio_device

From: Luiz Augusto von Dentz <[email protected]>

This is part of the work necessary to completely remove
struct audio_device
---
profiles/audio/manager.c | 2 +-
profiles/audio/sink.c | 21 ++++++++-------------
profiles/audio/sink.h | 3 +--
3 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index 4940012..12c7b10 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
@@ -130,7 +130,7 @@ static int a2dp_sink_probe(struct btd_service *service)
return -1;
}

- audio_dev->sink = sink_init(audio_dev, service);
+ audio_dev->sink = sink_init(service);

return 0;
}
diff --git a/profiles/audio/sink.c b/profiles/audio/sink.c
index 9578558..bb9ab21 100644
--- a/profiles/audio/sink.c
+++ b/profiles/audio/sink.c
@@ -39,11 +39,10 @@

#include "log.h"

-#include "../src/adapter.h"
-#include "../src/device.h"
-#include "../src/service.h"
+#include "src/adapter.h"
+#include "src/device.h"
+#include "src/service.h"

-#include "device.h"
#include "avdtp.h"
#include "media.h"
#include "a2dp.h"
@@ -55,7 +54,6 @@
#define STREAM_SETUP_RETRY_TIMER 2

struct sink {
- struct audio_device *dev;
struct btd_service *service;
struct avdtp *session;
struct avdtp_stream *stream;
@@ -343,7 +341,6 @@ int sink_connect(struct btd_service *service)
static void sink_free(struct btd_service *service)
{
struct sink *sink = btd_service_get_user_data(service);
- struct audio_device *dev = sink->dev;

if (sink->cb_id)
avdtp_stream_remove_cb(sink->session, sink->stream,
@@ -371,7 +368,6 @@ static void sink_free(struct btd_service *service)
btd_service_unref(sink->service);

g_free(sink);
- dev->sink = NULL;
}

void sink_unregister(struct btd_service *service)
@@ -383,20 +379,19 @@ void sink_unregister(struct btd_service *service)
sink_free(service);
}

-struct btd_service *sink_init(struct audio_device *dev,
- struct btd_service *service)
+struct btd_service *sink_init(struct btd_service *service)
{
+ struct btd_device *dev = btd_service_get_device(service);
struct sink *sink;

- DBG("%s", device_get_path(dev->btd_dev));
+ DBG("%s", device_get_path(dev));

sink = g_new0(struct sink, 1);

- sink->dev = dev;
sink->service = btd_service_ref(service);

- sink->avdtp_callback_id = avdtp_add_state_cb(dev->btd_dev,
- avdtp_state_callback, sink);
+ sink->avdtp_callback_id = avdtp_add_state_cb(dev, avdtp_state_callback,
+ sink);

btd_service_set_user_data(service, sink);

diff --git a/profiles/audio/sink.h b/profiles/audio/sink.h
index b25089a..423bca1 100644
--- a/profiles/audio/sink.h
+++ b/profiles/audio/sink.h
@@ -40,8 +40,7 @@ unsigned int sink_add_state_cb(struct btd_service *service, sink_state_cb cb,
void *user_data);
gboolean sink_remove_state_cb(unsigned int id);

-struct btd_service *sink_init(struct audio_device *dev,
- struct btd_service *service);
+struct btd_service *sink_init(struct btd_service *service);
void sink_unregister(struct btd_service *service);
gboolean sink_is_active(struct btd_service *service);
int sink_connect(struct btd_service *service);
--
1.8.1.4


2013-07-03 15:15:32

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 11/20] audio/A2DP: Remove dependency on struct audio_device

From: Luiz Augusto von Dentz <[email protected]>

This is part of the work necessary to completely remove
struct audio_device
---
profiles/audio/a2dp.c | 111 ++++++++++++++++++++-------------------------
profiles/audio/a2dp.h | 4 +-
profiles/audio/media.c | 27 +++++------
profiles/audio/sink.c | 11 ++---
profiles/audio/source.c | 10 ++--
profiles/audio/transport.c | 109 ++++++++++++++++++++++++++++----------------
profiles/audio/transport.h | 4 +-
7 files changed, 148 insertions(+), 128 deletions(-)

diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index e89be07..8db43f9 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -37,10 +37,12 @@
#include <bluetooth/sdp.h>
#include <bluetooth/sdp_lib.h>

-#include "../src/adapter.h"
+#include "lib/uuid.h"
+#include "src/adapter.h"
+#include "src/device.h"
+#include "src/service.h"

#include "log.h"
-#include "device.h"
#include "manager.h"
#include "avdtp.h"
#include "sink.h"
@@ -83,7 +85,6 @@ struct a2dp_setup_cb {
};

struct a2dp_setup {
- struct audio_device *dev;
struct avdtp *session;
struct a2dp_sep *sep;
struct avdtp_remote_sep *rsep;
@@ -120,25 +121,12 @@ static struct a2dp_setup *setup_ref(struct a2dp_setup *setup)
return setup;
}

-static struct audio_device *a2dp_get_dev(struct avdtp *session)
-{
- return manager_get_audio_device(avdtp_get_device(session), FALSE);
-}
-
static struct a2dp_setup *setup_new(struct avdtp *session)
{
- struct audio_device *dev;
struct a2dp_setup *setup;

- dev = a2dp_get_dev(session);
- if (!dev) {
- error("Unable to create setup");
- return NULL;
- }
-
setup = g_new0(struct a2dp_setup, 1);
setup->session = avdtp_ref(session);
- setup->dev = a2dp_get_dev(session);
setups = g_slist_append(setups, setup);

return setup;
@@ -322,20 +310,6 @@ static struct a2dp_setup *a2dp_setup_get(struct avdtp *session)
return setup_ref(setup);
}

-static struct a2dp_setup *find_setup_by_dev(struct audio_device *dev)
-{
- GSList *l;
-
- for (l = setups; l != NULL; l = l->next) {
- struct a2dp_setup *setup = l->data;
-
- if (setup->dev == dev)
- return setup;
- }
-
- return NULL;
-}
-
static struct a2dp_setup *find_setup_by_stream(struct avdtp_stream *stream)
{
GSList *l;
@@ -403,7 +377,8 @@ static void stream_state_changed(struct avdtp_stream *stream,
static gboolean auto_config(gpointer data)
{
struct a2dp_setup *setup = data;
- struct audio_device *dev = setup->dev;
+ struct btd_device *dev = avdtp_get_device(setup->session);
+ struct btd_service *service;

/* Check if configuration was aborted */
if (setup->sep->stream == NULL)
@@ -415,10 +390,13 @@ static gboolean auto_config(gpointer data)
avdtp_stream_add_cb(setup->session, setup->stream,
stream_state_changed, setup->sep);

- if (setup->sep->type == AVDTP_SEP_TYPE_SOURCE)
- sink_new_stream(dev->sink, setup->session, setup->stream);
- else
- source_new_stream(dev->source, setup->session, setup->stream);
+ if (setup->sep->type == AVDTP_SEP_TYPE_SOURCE) {
+ service = btd_device_get_service(dev, A2DP_SINK_UUID);
+ sink_new_stream(service, setup->session, setup->stream);
+ } else {
+ service = btd_device_get_service(dev, A2DP_SOURCE_UUID);
+ source_new_stream(service, setup->session, setup->stream);
+ }

done:
if (setup->setconf_cb)
@@ -497,7 +475,7 @@ static gboolean endpoint_setconf_ind(struct avdtp *session,
}

ret = a2dp_sep->endpoint->set_configuration(a2dp_sep,
- setup->dev, codec->data,
+ codec->data,
cap->length - sizeof(*codec),
setup,
endpoint_setconf_cb,
@@ -588,7 +566,8 @@ static void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
{
struct a2dp_sep *a2dp_sep = user_data;
struct a2dp_setup *setup;
- struct audio_device *dev;
+ struct btd_device *dev;
+ struct btd_service *service;
int ret;

if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
@@ -615,13 +594,16 @@ static void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
if (!setup)
return;

- dev = a2dp_get_dev(session);
+ dev = avdtp_get_device(session);

/* Notify D-Bus interface of the new stream */
- if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE)
- sink_new_stream(dev->sink, session, setup->stream);
- else
- source_new_stream(dev->source, session, setup->stream);
+ if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE) {
+ service = btd_device_get_service(dev, A2DP_SINK_UUID);
+ sink_new_stream(service, session, setup->stream);
+ } else {
+ service = btd_device_get_service(dev, A2DP_SOURCE_UUID);
+ source_new_stream(service, session, setup->stream);
+ }

/* Notify Endpoint */
if (a2dp_sep->endpoint) {
@@ -632,7 +614,7 @@ static void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
service = avdtp_stream_get_codec(stream);
codec = (struct avdtp_media_codec_capability *) service->data;

- err = a2dp_sep->endpoint->set_configuration(a2dp_sep, dev,
+ err = a2dp_sep->endpoint->set_configuration(a2dp_sep,
codec->data, service->length -
sizeof(*codec),
setup,
@@ -1839,32 +1821,31 @@ failed:
return 0;
}

-gboolean a2dp_cancel(struct audio_device *dev, unsigned int id)
+gboolean a2dp_cancel(unsigned int id)
{
- struct a2dp_setup *setup;
- GSList *l;
+ GSList *ls;

- setup = find_setup_by_dev(dev);
- if (!setup)
- return FALSE;
+ for (ls = setups; ls != NULL; ls = g_slist_next(ls)) {
+ struct a2dp_setup *setup = ls->data;
+ GSList *l;
+ for (l = setup->cb; l != NULL; l = g_slist_next(l)) {
+ struct a2dp_setup_cb *cb = l->data;

- for (l = setup->cb; l != NULL; l = g_slist_next(l)) {
- struct a2dp_setup_cb *cb = l->data;
+ if (cb->id != id)
+ continue;

- if (cb->id != id)
- continue;
+ setup_ref(setup);
+ setup_cb_free(cb);

- setup_ref(setup);
- setup_cb_free(cb);
+ if (!setup->cb) {
+ DBG("aborting setup %p", setup);
+ avdtp_abort(setup->session, setup->stream);
+ return TRUE;
+ }

- if (!setup->cb) {
- DBG("aborting setup %p", setup);
- avdtp_abort(setup->session, setup->stream);
+ setup_unref(setup);
return TRUE;
}
-
- setup_unref(setup);
- return TRUE;
}

return FALSE;
@@ -1926,3 +1907,11 @@ struct avdtp_stream *a2dp_sep_get_stream(struct a2dp_sep *sep)
{
return sep->stream;
}
+
+struct btd_device *a2dp_setup_get_device(struct a2dp_setup *setup)
+{
+ if (setup->session == NULL)
+ return NULL;
+
+ return avdtp_get_device(setup->session);
+}
diff --git a/profiles/audio/a2dp.h b/profiles/audio/a2dp.h
index 4819f7b..2c06f74 100644
--- a/profiles/audio/a2dp.h
+++ b/profiles/audio/a2dp.h
@@ -42,7 +42,6 @@ struct a2dp_endpoint {
a2dp_endpoint_select_t cb,
void *user_data);
int (*set_configuration) (struct a2dp_sep *sep,
- struct audio_device *dev,
uint8_t *configuration,
size_t length,
struct a2dp_setup *setup,
@@ -87,8 +86,9 @@ unsigned int a2dp_resume(struct avdtp *session, struct a2dp_sep *sep,
a2dp_stream_cb_t cb, void *user_data);
unsigned int a2dp_suspend(struct avdtp *session, struct a2dp_sep *sep,
a2dp_stream_cb_t cb, void *user_data);
-gboolean a2dp_cancel(struct audio_device *dev, unsigned int id);
+gboolean a2dp_cancel(unsigned int id);

gboolean a2dp_sep_lock(struct a2dp_sep *sep, struct avdtp *session);
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);
diff --git a/profiles/audio/media.c b/profiles/audio/media.c
index 6fe5e04..bb6323d 100644
--- a/profiles/audio/media.c
+++ b/profiles/audio/media.c
@@ -380,9 +380,9 @@ static int transport_device_cmp(gconstpointer data, gconstpointer user_data)
{
struct media_transport *transport = (struct media_transport *) data;
const struct btd_device *device = user_data;
- const struct audio_device *dev = media_transport_get_dev(transport);
+ const struct btd_device *dev = media_transport_get_dev(transport);

- if (device == dev->btd_dev)
+ if (device == dev)
return 0;

return -1;
@@ -402,20 +402,26 @@ static struct media_transport *find_device_transport(
return match->data;
}

+struct a2dp_config_data {
+ struct a2dp_setup *setup;
+ a2dp_endpoint_config_t cb;
+};
+
static gboolean set_configuration(struct media_endpoint *endpoint,
- struct audio_device *device,
uint8_t *configuration, size_t size,
media_endpoint_cb_t cb,
void *user_data,
GDestroyNotify destroy)
{
+ struct a2dp_config_data *data = user_data;
+ struct btd_device *device = a2dp_setup_get_device(data->setup);
DBusConnection *conn = btd_get_dbus_connection();
DBusMessage *msg;
const char *path;
DBusMessageIter iter;
struct media_transport *transport;

- transport = find_device_transport(endpoint, device->btd_dev);
+ transport = find_device_transport(endpoint, device);

if (transport != NULL)
return FALSE;
@@ -488,11 +494,6 @@ static size_t get_capabilities(struct a2dp_sep *sep, uint8_t **capabilities,
return endpoint->size;
}

-struct a2dp_config_data {
- struct a2dp_setup *setup;
- a2dp_endpoint_config_t cb;
-};
-
struct a2dp_select_data {
struct a2dp_setup *setup;
a2dp_endpoint_select_t cb;
@@ -533,8 +534,8 @@ static void config_cb(struct media_endpoint *endpoint, void *ret, int size,
data->cb(data->setup, ret ? TRUE : FALSE);
}

-static int set_config(struct a2dp_sep *sep, struct audio_device *dev,
- uint8_t *configuration, size_t length,
+static int set_config(struct a2dp_sep *sep, uint8_t *configuration,
+ size_t length,
struct a2dp_setup *setup,
a2dp_endpoint_config_t cb,
void *user_data)
@@ -546,8 +547,8 @@ static int set_config(struct a2dp_sep *sep, struct audio_device *dev,
data->setup = setup;
data->cb = cb;

- if (set_configuration(endpoint, dev, configuration, length,
- config_cb, data, g_free) == TRUE)
+ if (set_configuration(endpoint, configuration, length, config_cb, data,
+ g_free) == TRUE)
return 0;

g_free(data);
diff --git a/profiles/audio/sink.c b/profiles/audio/sink.c
index 58fa137..9578558 100644
--- a/profiles/audio/sink.c
+++ b/profiles/audio/sink.c
@@ -154,7 +154,7 @@ static void stream_state_changed(struct avdtp_stream *stream,
btd_service_disconnecting_complete(sink->service, 0);

if (sink->disconnect_id > 0) {
- a2dp_cancel(sink->dev, sink->disconnect_id);
+ a2dp_cancel(sink->disconnect_id);
sink->disconnect_id = 0;
}

@@ -199,7 +199,7 @@ static gboolean stream_setup_retry(gpointer user_data)
btd_service_connecting_complete(sink->service, err);

if (sink->connect_id > 0) {
- a2dp_cancel(sink->dev, sink->connect_id);
+ a2dp_cancel(sink->connect_id);
sink->connect_id = 0;
}

@@ -354,13 +354,13 @@ static void sink_free(struct btd_service *service)

if (sink->connect_id > 0) {
btd_service_connecting_complete(sink->service, -ECANCELED);
- a2dp_cancel(dev, sink->connect_id);
+ a2dp_cancel(sink->connect_id);
sink->connect_id = 0;
}

if (sink->disconnect_id > 0) {
btd_service_disconnecting_complete(sink->service, -ECANCELED);
- a2dp_cancel(dev, sink->disconnect_id);
+ a2dp_cancel(sink->disconnect_id);
sink->disconnect_id = 0;
}

@@ -435,7 +435,6 @@ gboolean sink_new_stream(struct btd_service *service, struct avdtp *session,
int sink_disconnect(struct btd_service *service, gboolean shutdown)
{
struct sink *sink = btd_service_get_user_data(service);
- struct audio_device *dev = sink->dev;

if (!sink->session)
return -ENOTCONN;
@@ -445,7 +444,7 @@ int sink_disconnect(struct btd_service *service, gboolean shutdown)

/* cancel pending connect */
if (sink->connect_id > 0) {
- a2dp_cancel(dev, sink->connect_id);
+ a2dp_cancel(sink->connect_id);
sink->connect_id = 0;
btd_service_connecting_complete(sink->service, -ECANCELED);

diff --git a/profiles/audio/source.c b/profiles/audio/source.c
index 2e68ee8..87b7309 100644
--- a/profiles/audio/source.c
+++ b/profiles/audio/source.c
@@ -153,7 +153,7 @@ static void stream_state_changed(struct avdtp_stream *stream,
btd_service_disconnecting_complete(source->service, 0);

if (source->disconnect_id > 0) {
- a2dp_cancel(source->dev, source->disconnect_id);
+ a2dp_cancel(source->disconnect_id);
source->disconnect_id = 0;
}

@@ -198,7 +198,7 @@ static gboolean stream_setup_retry(gpointer user_data)
btd_service_connecting_complete(source->service, err);

if (source->connect_id > 0) {
- a2dp_cancel(source->dev, source->connect_id);
+ a2dp_cancel(source->connect_id);
source->connect_id = 0;
}

@@ -356,13 +356,13 @@ static void source_free(struct btd_service *service)

if (source->connect_id > 0) {
btd_service_connecting_complete(source->service, -ECANCELED);
- a2dp_cancel(dev, source->connect_id);
+ a2dp_cancel(source->connect_id);
source->connect_id = 0;
}

if (source->disconnect_id > 0) {
btd_service_disconnecting_complete(source->service, -ECANCELED);
- a2dp_cancel(dev, source->disconnect_id);
+ a2dp_cancel(source->disconnect_id);
source->disconnect_id = 0;
}

@@ -437,7 +437,7 @@ int source_disconnect(struct btd_service *service, gboolean shutdown)

/* cancel pending connect */
if (source->connect_id > 0) {
- a2dp_cancel(source->dev, source->connect_id);
+ a2dp_cancel(source->connect_id);
source->connect_id = 0;
btd_service_connecting_complete(source->service, -ECANCELED);

diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
index c8a806d..8d3d91e 100644
--- a/profiles/audio/transport.c
+++ b/profiles/audio/transport.c
@@ -32,9 +32,9 @@
#include <gdbus/gdbus.h>

#include "lib/uuid.h"
-#include "../src/adapter.h"
-#include "../src/device.h"
-#include "../src/dbus-common.h"
+#include "src/adapter.h"
+#include "src/device.h"
+#include "src/dbus-common.h"

#include "log.h"
#include "error.h"
@@ -85,7 +85,7 @@ struct a2dp_transport {

struct media_transport {
char *path; /* Transport object path */
- struct audio_device *device; /* Transport device */
+ struct btd_device *device; /* Transport device */
struct media_endpoint *endpoint; /* Transport endpoint */
struct media_owner *owner; /* Transport owner */
uint8_t *configuration; /* Transport configuration */
@@ -332,7 +332,7 @@ static guint resume_a2dp(struct media_transport *transport,
guint id;

if (a2dp->session == NULL) {
- a2dp->session = avdtp_get(transport->device->btd_dev);
+ a2dp->session = avdtp_get(transport->device);
if (a2dp->session == NULL)
return 0;
}
@@ -396,7 +396,7 @@ static guint suspend_a2dp(struct media_transport *transport,

static void cancel_a2dp(struct media_transport *transport, guint id)
{
- a2dp_cancel(transport->device, id);
+ a2dp_cancel(id);
}

static void media_owner_exit(DBusConnection *connection, void *user_data)
@@ -545,7 +545,7 @@ static gboolean get_device(const GDBusPropertyTable *property,
DBusMessageIter *iter, void *data)
{
struct media_transport *transport = data;
- const char *path = device_get_path(transport->device->btd_dev);
+ const char *path = device_get_path(transport->device);

dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &path);

@@ -666,7 +666,7 @@ static void set_volume(const GDBusPropertyTable *property,
}

if (a2dp->volume != volume)
- avrcp_set_volume(transport->device->btd_dev, volume);
+ avrcp_set_volume(transport->device, volume);

a2dp->volume = volume;

@@ -770,7 +770,57 @@ static void source_state_changed(struct btd_service *service,
transport_update_playing(transport, FALSE);
}

-struct media_transport *media_transport_create(struct audio_device *device,
+static int media_transport_init_source(struct media_transport *transport)
+{
+ struct btd_service *service;
+ struct a2dp_transport *a2dp;
+
+ service = btd_device_get_service(transport->device, A2DP_SINK_UUID);
+ if (service == NULL)
+ return -EINVAL;
+
+ a2dp = g_new0(struct a2dp_transport, 1);
+
+ transport->resume = resume_a2dp;
+ transport->suspend = suspend_a2dp;
+ transport->cancel = cancel_a2dp;
+ transport->data = a2dp;
+ transport->destroy = destroy_a2dp;
+
+ a2dp->volume = -1;
+ transport->sink_watch = sink_add_state_cb(service, sink_state_changed,
+ transport);
+
+ return 0;
+}
+
+static int media_transport_init_sink(struct media_transport *transport)
+{
+ struct btd_service *service;
+ struct a2dp_transport *a2dp;
+
+ service = btd_device_get_service(transport->device, A2DP_SOURCE_UUID);
+ if (service == NULL)
+ return -EINVAL;
+
+ a2dp = g_new0(struct a2dp_transport, 1);
+
+ transport->resume = resume_a2dp;
+ transport->suspend = suspend_a2dp;
+ transport->cancel = cancel_a2dp;
+ transport->data = a2dp;
+ transport->destroy = destroy_a2dp;
+
+ a2dp->volume = 127;
+ avrcp_set_volume(transport->device, a2dp->volume);
+ transport->source_watch = source_add_state_cb(service,
+ source_state_changed,
+ transport);
+
+ return 0;
+}
+
+struct media_transport *media_transport_create(struct btd_device *device,
uint8_t *configuration,
size_t size, void *data)
{
@@ -785,36 +835,17 @@ struct media_transport *media_transport_create(struct audio_device *device,
transport->configuration = g_new(uint8_t, size);
memcpy(transport->configuration, configuration, size);
transport->size = size;
- transport->path = g_strdup_printf("%s/fd%d",
- device_get_path(device->btd_dev), fd++);
+ transport->path = g_strdup_printf("%s/fd%d", device_get_path(device),
+ fd++);
transport->fd = -1;

uuid = media_endpoint_get_uuid(endpoint);
- if (strcasecmp(uuid, A2DP_SOURCE_UUID) == 0 ||
- strcasecmp(uuid, A2DP_SINK_UUID) == 0) {
- struct a2dp_transport *a2dp;
-
- a2dp = g_new0(struct a2dp_transport, 1);
-
- transport->resume = resume_a2dp;
- transport->suspend = suspend_a2dp;
- transport->cancel = cancel_a2dp;
- transport->data = a2dp;
- transport->destroy = destroy_a2dp;
-
- if (strcasecmp(uuid, A2DP_SOURCE_UUID) == 0) {
- a2dp->volume = -1;
- transport->sink_watch = sink_add_state_cb(device->sink,
- sink_state_changed,
- transport);
- } else {
- a2dp->volume = 127;
- avrcp_set_volume(device->btd_dev, a2dp->volume);
- transport->source_watch = source_add_state_cb(
- device->source,
- source_state_changed,
- transport);
- }
+ if (strcasecmp(uuid, A2DP_SOURCE_UUID) == 0) {
+ if (media_transport_init_source(transport) < 0)
+ goto fail;
+ } else if (strcasecmp(uuid, A2DP_SINK_UUID) == 0) {
+ if (media_transport_init_sink(transport) < 0)
+ goto fail;
} else
goto fail;

@@ -856,7 +887,7 @@ void media_transport_update_delay(struct media_transport *transport,
MEDIA_TRANSPORT_INTERFACE, "Delay");
}

-struct audio_device *media_transport_get_dev(struct media_transport *transport)
+struct btd_device *media_transport_get_dev(struct media_transport *transport)
{
return transport->device;
}
@@ -892,7 +923,7 @@ uint8_t media_transport_get_device_volume(struct btd_device *dev)

for (l = transports; l; l = l->next) {
struct media_transport *transport = l->data;
- if (transport->device->btd_dev != dev)
+ if (transport->device != dev)
continue;

/* Volume is A2DP only */
@@ -913,7 +944,7 @@ void media_transport_update_device_volume(struct btd_device *dev,

for (l = transports; l; l = l->next) {
struct media_transport *transport = l->data;
- if (transport->device->btd_dev != dev)
+ if (transport->device != dev)
continue;

/* Volume is A2DP only */
diff --git a/profiles/audio/transport.h b/profiles/audio/transport.h
index 1501bf4..505ad5c 100644
--- a/profiles/audio/transport.h
+++ b/profiles/audio/transport.h
@@ -24,13 +24,13 @@

struct media_transport;

-struct media_transport *media_transport_create(struct audio_device *device,
+struct media_transport *media_transport_create(struct btd_device *device,
uint8_t *configuration,
size_t size, void *data);

void media_transport_destroy(struct media_transport *transport);
const char *media_transport_get_path(struct media_transport *transport);
-struct audio_device *media_transport_get_dev(struct media_transport *transport);
+struct btd_device *media_transport_get_dev(struct media_transport *transport);
uint16_t media_transport_get_volume(struct media_transport *transport);
void media_transport_update_delay(struct media_transport *transport,
uint16_t delay);
--
1.8.1.4


2013-07-03 15:15:31

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 10/20] audio/control: Remove dependency on struct audio_device

From: Luiz Augusto von Dentz <[email protected]>

This is part of the work necessary to completely remove
struct audio_device
---
profiles/audio/control.c | 82 ++++++++++++++++++++++++++++--------------------
profiles/audio/control.h | 6 ++--
profiles/audio/manager.c | 4 +--
3 files changed, 52 insertions(+), 40 deletions(-)

diff --git a/profiles/audio/control.c b/profiles/audio/control.c
index 86d38f5..bffcb09 100644
--- a/profiles/audio/control.c
+++ b/profiles/audio/control.c
@@ -46,14 +46,13 @@
#include <gdbus/gdbus.h>

#include "lib/uuid.h"
-#include "../src/adapter.h"
-#include "../src/device.h"
-#include "../src/profile.h"
-#include "../src/service.h"
+#include "src/adapter.h"
+#include "src/device.h"
+#include "src/profile.h"
+#include "src/service.h"

#include "log.h"
#include "error.h"
-#include "device.h"
#include "manager.h"
#include "avctp.h"
#include "control.h"
@@ -61,8 +60,10 @@
#include "glib-helper.h"
#include "dbus-common.h"

+static GSList *devices = NULL;
+
struct control {
- struct audio_device *dev;
+ struct btd_device *dev;
struct avctp *session;
struct btd_service *target;
struct btd_service *remote;
@@ -110,7 +111,7 @@ int control_connect(struct btd_service *service)
if (!control->target)
return -ENOTSUP;

- control->session = avctp_connect(control->dev->btd_dev);
+ control->session = avctp_connect(control->dev);
if (!control->session)
return -EIO;

@@ -132,8 +133,7 @@ int control_disconnect(struct btd_service *service)
static DBusMessage *key_pressed(DBusConnection *conn, DBusMessage *msg,
uint8_t op, void *data)
{
- struct audio_device *device = data;
- struct control *control = btd_service_get_user_data(device->control);
+ struct control *control = data;
int err;

if (!control->session)
@@ -207,8 +207,7 @@ static gboolean control_property_get_connected(
const GDBusPropertyTable *property,
DBusMessageIter *iter, void *data)
{
- struct audio_device *device = data;
- struct control *control = btd_service_get_user_data(device->control);
+ struct control *control = data;
dbus_bool_t value = (control->session != NULL);

dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &value);
@@ -236,11 +235,10 @@ static const GDBusPropertyTable control_properties[] = {

static void path_unregister(void *data)
{
- struct audio_device *dev = data;
- struct control *control = btd_service_get_user_data(dev->control);
+ struct control *control = data;

- DBG("Unregistered interface %s on path %s",
- AUDIO_CONTROL_INTERFACE, device_get_path(dev->btd_dev));
+ DBG("Unregistered interface %s on path %s", AUDIO_CONTROL_INTERFACE,
+ device_get_path(control->dev));

if (control->session)
avctp_disconnect(control->session);
@@ -253,8 +251,8 @@ static void path_unregister(void *data)
if (control->remote)
btd_service_unref(control->remote);

+ devices = g_slist_remove(devices, control);
g_free(control);
- dev->control = NULL;
}

void control_unregister(struct btd_service *service)
@@ -266,39 +264,56 @@ void control_unregister(struct btd_service *service)
AUDIO_CONTROL_INTERFACE);
}

-static struct control *control_init(struct audio_device *dev)
+static struct control *find_control(struct btd_device *dev)
+{
+ GSList *l;
+
+ for (l = devices; l; l = l->next) {
+ struct control *control = l->data;
+
+ if (control->dev == dev)
+ return control;
+ }
+
+ return NULL;
+}
+
+static struct control *control_init(struct btd_service *service)
{
struct control *control;
+ struct btd_device *dev = btd_service_get_device(service);

- if (dev->control != NULL)
- return btd_service_get_user_data(dev->control);
+ control = find_control(dev);
+ if (control != NULL)
+ return control;
+
+ control = g_new0(struct control, 1);

if (!g_dbus_register_interface(btd_get_dbus_connection(),
- device_get_path(dev->btd_dev),
+ device_get_path(dev),
AUDIO_CONTROL_INTERFACE,
control_methods, NULL,
- control_properties, dev,
- path_unregister))
+ control_properties, control,
+ path_unregister)) {
+ g_free(control);
return NULL;
+ }

- DBG("Registered interface %s on path %s",
- AUDIO_CONTROL_INTERFACE, device_get_path(dev->btd_dev));
-
- control = g_new0(struct control, 1);
+ DBG("Registered interface %s on path %s", AUDIO_CONTROL_INTERFACE,
+ device_get_path(dev));

control->dev = dev;
- control->avctp_id = avctp_add_state_cb(dev->btd_dev, state_changed,
- control);
+ control->avctp_id = avctp_add_state_cb(dev, state_changed, control);
+ devices = g_slist_prepend(devices, control);

return control;
}

-struct btd_service *control_init_target(struct audio_device *dev,
- struct btd_service *service)
+struct btd_service *control_init_target(struct btd_service *service)
{
struct control *control;

- control = control_init(dev);
+ control = control_init(service);
if (control == NULL)
return NULL;

@@ -309,12 +324,11 @@ struct btd_service *control_init_target(struct audio_device *dev,
return service;
}

-struct btd_service *control_init_remote(struct audio_device *dev,
- struct btd_service *service)
+struct btd_service *control_init_remote(struct btd_service *service)
{
struct control *control;

- control = control_init(dev);
+ control = control_init(service);
if (control == NULL)
return NULL;

diff --git a/profiles/audio/control.h b/profiles/audio/control.h
index 57668f9..ae5baae 100644
--- a/profiles/audio/control.h
+++ b/profiles/audio/control.h
@@ -26,10 +26,8 @@

struct btd_service;

-struct btd_service *control_init_target(struct audio_device *dev,
- struct btd_service *service);
-struct btd_service *control_init_remote(struct audio_device *dev,
- struct btd_service *service);
+struct btd_service *control_init_target(struct btd_service *service);
+struct btd_service *control_init_remote(struct btd_service *service);
void control_unregister(struct btd_service *service);
gboolean control_is_active(struct btd_service *service);

diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index c2898b5..4940012 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
@@ -146,7 +146,7 @@ static int avrcp_target_probe(struct btd_service *service)
return -1;
}

- audio_dev->control = control_init_target(audio_dev, service);
+ audio_dev->control = control_init_target(service);

if (audio_dev->sink && sink_is_active(audio_dev->sink))
avrcp_connect(audio_dev->btd_dev);
@@ -165,7 +165,7 @@ static int avrcp_remote_probe(struct btd_service *service)
return -1;
}

- audio_dev->control = control_init_remote(audio_dev, service);
+ audio_dev->control = control_init_remote(service);

return 0;
}
--
1.8.1.4


2013-07-03 15:15:30

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 09/20] audio/AVRCP: Remove dependency on struct audio_device

From: Luiz Augusto von Dentz <[email protected]>

This is part of the work necessary to completely remove
struct audio_device
---
profiles/audio/avrcp.c | 51 ++++++++++++++++++++++------------------------
profiles/audio/avrcp.h | 8 ++++----
profiles/audio/device.c | 8 ++++----
profiles/audio/manager.c | 2 +-
profiles/audio/media.c | 11 +++++-----
profiles/audio/transport.c | 12 +++++------
profiles/audio/transport.h | 4 ++--
7 files changed, 47 insertions(+), 49 deletions(-)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 1a5c477..cd0a736 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -53,7 +53,6 @@

#include "log.h"
#include "error.h"
-#include "device.h"
#include "manager.h"
#include "avctp.h"
#include "avrcp.h"
@@ -213,7 +212,7 @@ struct avrcp_player {
struct avrcp {
struct avrcp_server *server;
struct avctp *conn;
- struct audio_device *dev;
+ struct btd_device *dev;
struct avrcp_player *player;
gboolean target;
uint16_t version;
@@ -1417,7 +1416,7 @@ static uint8_t avrcp_handle_register_notification(struct avrcp *session,
uint8_t transaction)
{
struct avrcp_player *player = session->player;
- struct audio_device *dev = session->dev;
+ struct btd_device *dev = session->dev;
uint16_t len = ntohs(pdu->params_len);
uint64_t uid;
GList *settings;
@@ -2820,7 +2819,7 @@ static struct avrcp_player *create_ct_player(struct avrcp *session,
player = g_new0(struct avrcp_player, 1);
player->sessions = g_slist_prepend(player->sessions, session);

- path = device_get_path(session->dev->btd_dev);
+ path = device_get_path(session->dev);

mp = media_player_controller_create(path, id);
if (mp == NULL)
@@ -3256,7 +3255,7 @@ static struct avrcp *find_session(GSList *list, struct btd_device *dev)
for (; list; list = list->next) {
struct avrcp *session = list->data;

- if (session->dev->btd_dev == dev)
+ if (session->dev == dev)
return session;
}

@@ -3316,8 +3315,7 @@ static void session_tg_init_control(struct avrcp *session)
avrcp_register_notification(session,
AVRCP_EVENT_VOLUME_CHANGED);

- service = btd_device_get_service(session->dev->btd_dev,
- AVRCP_REMOTE_UUID);
+ service = btd_device_get_service(session->dev, AVRCP_REMOTE_UUID);
if (service != NULL)
btd_service_connecting_complete(service, 0);
}
@@ -3346,9 +3344,7 @@ static void session_ct_init_control(struct avrcp *session)
if (session->version >= 0x0104)
session->supported_events = (1 << AVRCP_EVENT_VOLUME_CHANGED);

-
- service = btd_device_get_service(session->dev->btd_dev,
- AVRCP_TARGET_UUID);
+ service = btd_device_get_service(session->dev, AVRCP_TARGET_UUID);
if (service != NULL)
btd_service_connecting_complete(service, 0);

@@ -3390,8 +3386,7 @@ static void session_tg_destroy(struct avrcp *session)
if (player != NULL)
player->sessions = g_slist_remove(player->sessions, session);

- service = btd_device_get_service(session->dev->btd_dev,
- AVRCP_REMOTE_UUID);
+ service = btd_device_get_service(session->dev, AVRCP_REMOTE_UUID);
if (service == NULL)
return session_destroy(session);

@@ -3411,8 +3406,7 @@ static void session_ct_destroy(struct avrcp *session)

g_slist_free_full(session->players, player_destroy);

- service = btd_device_get_service(session->dev->btd_dev,
- AVRCP_TARGET_UUID);
+ service = btd_device_get_service(session->dev, AVRCP_TARGET_UUID);
if (service == NULL)
return session_destroy(session);

@@ -3431,25 +3425,28 @@ static struct avrcp *session_create(struct avrcp_server *server,
const sdp_record_t *rec;
sdp_list_t *list;
sdp_profile_desc_t *desc;
- struct audio_device *dev = manager_get_audio_device(device, FALSE);
+ struct btd_service *sink, *source;

session = g_new0(struct avrcp, 1);
session->server = server;
session->conn = avctp_connect(device);
- session->dev = dev;
+ session->dev = device;

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

+ sink = btd_device_get_service(device, A2DP_SINK_UUID);
+ source = btd_device_get_service(device, A2DP_SOURCE_UUID);
+
/* If sink and source are not supported assume the controller must
* be the initiator
*/
- if (dev->sink == NULL && dev->source == NULL)
+ if (sink == NULL && source == NULL)
session->target = !avctp_is_initiator(session->conn);
- else if (dev->sink && !dev->source)
+ else if (sink && !source)
session->target = TRUE;
- else if (dev->source && !dev->sink)
+ else if (source && !sink)
session->target = FALSE;
- else if (dev->sink && sink_is_active(dev->sink))
+ else if (sink && sink_is_active(sink))
session->target = TRUE;
else
session->target = FALSE;
@@ -3535,22 +3532,22 @@ static void state_changed(struct btd_device *device, avctp_state_t old_state,
}
}

-gboolean avrcp_connect(struct audio_device *dev)
+gboolean avrcp_connect(struct btd_device *dev)
{
struct avctp *session;

- session = avctp_connect(dev->btd_dev);
+ session = avctp_connect(dev);
if (session)
return FALSE;

return TRUE;
}

-void avrcp_disconnect(struct audio_device *dev)
+void avrcp_disconnect(struct btd_device *dev)
{
struct avctp *session;

- session = avctp_get(dev->btd_dev);
+ session = avctp_get(dev);
if (!session)
return;

@@ -3781,18 +3778,18 @@ static gboolean avrcp_handle_set_volume(struct avctp *conn,
return FALSE;
}

-int avrcp_set_volume(struct audio_device *dev, uint8_t volume)
+int avrcp_set_volume(struct btd_device *dev, uint8_t volume)
{
struct avrcp_server *server;
struct avrcp *session;
uint8_t buf[AVRCP_HEADER_LENGTH + 2];
struct avrcp_header *pdu = (void *) buf;

- server = find_server(servers, device_get_adapter(dev->btd_dev));
+ server = find_server(servers, device_get_adapter(dev));
if (server == NULL)
return -EINVAL;

- session = find_session(server->sessions, dev->btd_dev);
+ session = find_session(server->sessions, dev);
if (session == NULL)
return -ENOTCONN;

diff --git a/profiles/audio/avrcp.h b/profiles/audio/avrcp.h
index 6a435e6..2ec1664 100644
--- a/profiles/audio/avrcp.h
+++ b/profiles/audio/avrcp.h
@@ -91,7 +91,7 @@ struct avrcp_player_cb {
const char *(*get_status) (void *user_data);
uint32_t (*get_position) (void *user_data);
uint32_t (*get_duration) (void *user_data);
- void (*set_volume) (uint8_t volume, struct audio_device *dev,
+ void (*set_volume) (uint8_t volume, struct btd_device *dev,
void *user_data);
bool (*play) (void *user_data);
bool (*stop) (void *user_data);
@@ -105,9 +105,9 @@ void avrcp_target_unregister(struct btd_adapter *adapter);
int avrcp_remote_register(struct btd_adapter *adapter, GKeyFile *config);
void avrcp_remote_unregister(struct btd_adapter *adapter);

-gboolean avrcp_connect(struct audio_device *dev);
-void avrcp_disconnect(struct audio_device *dev);
-int avrcp_set_volume(struct audio_device *dev, uint8_t volume);
+gboolean avrcp_connect(struct btd_device *dev);
+void avrcp_disconnect(struct btd_device *dev);
+int avrcp_set_volume(struct btd_device *dev, uint8_t volume);

struct avrcp_player *avrcp_register_player(struct btd_adapter *adapter,
struct avrcp_player_cb *cb,
diff --git a/profiles/audio/device.c b/profiles/audio/device.c
index e9c36cc..9b2e393 100644
--- a/profiles/audio/device.c
+++ b/profiles/audio/device.c
@@ -106,7 +106,7 @@ static gboolean control_connect_timeout(gpointer user_data)
dev->priv->control_timer = 0;

if (dev->control)
- avrcp_connect(dev);
+ avrcp_connect(dev->btd_dev);

return FALSE;
}
@@ -150,7 +150,7 @@ static void disconnect_cb(struct btd_device *btd_dev, gboolean removal,
device_remove_control_timer(dev);

if (dev->control && priv->avctp_state != AVCTP_STATE_DISCONNECTED)
- avrcp_disconnect(dev);
+ avrcp_disconnect(dev->btd_dev);

sink = btd_device_get_service(btd_dev, A2DP_SINK_UUID);
if (sink)
@@ -173,7 +173,7 @@ static void device_avdtp_cb(struct btd_device *device, struct avdtp *session,
if (avdtp_stream_setup_active(session))
device_set_control_timer(dev);
else
- avrcp_connect(dev);
+ avrcp_connect(dev->btd_dev);
}
}

@@ -191,7 +191,7 @@ static void device_sink_cb(struct audio_device *dev,
if (dev->control) {
device_remove_control_timer(dev);
if (priv->avctp_state != AVCTP_STATE_DISCONNECTED)
- avrcp_disconnect(dev);
+ avrcp_disconnect(dev->btd_dev);
}
break;
case BTD_SERVICE_STATE_CONNECTING:
diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index 386cd88..c2898b5 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
@@ -149,7 +149,7 @@ static int avrcp_target_probe(struct btd_service *service)
audio_dev->control = control_init_target(audio_dev, service);

if (audio_dev->sink && sink_is_active(audio_dev->sink))
- avrcp_connect(audio_dev);
+ avrcp_connect(audio_dev->btd_dev);

return 0;
}
diff --git a/profiles/audio/media.c b/profiles/audio/media.c
index d4d82cf..6fe5e04 100644
--- a/profiles/audio/media.c
+++ b/profiles/audio/media.c
@@ -379,9 +379,10 @@ static gboolean select_configuration(struct media_endpoint *endpoint,
static int transport_device_cmp(gconstpointer data, gconstpointer user_data)
{
struct media_transport *transport = (struct media_transport *) data;
- const struct audio_device *device = user_data;
+ const struct btd_device *device = user_data;
+ const struct audio_device *dev = media_transport_get_dev(transport);

- if (device == media_transport_get_dev(transport))
+ if (device == dev->btd_dev)
return 0;

return -1;
@@ -389,7 +390,7 @@ static int transport_device_cmp(gconstpointer data, gconstpointer user_data)

static struct media_transport *find_device_transport(
struct media_endpoint *endpoint,
- struct audio_device *device)
+ struct btd_device *device)
{
GSList *match;

@@ -414,7 +415,7 @@ static gboolean set_configuration(struct media_endpoint *endpoint,
DBusMessageIter iter;
struct media_transport *transport;

- transport = find_device_transport(endpoint, device);
+ transport = find_device_transport(endpoint, device->btd_dev);

if (transport != NULL)
return FALSE;
@@ -1148,7 +1149,7 @@ static uint32_t get_duration(void *user_data)
return mp->duration;
}

-static void set_volume(uint8_t volume, struct audio_device *dev, void *user_data)
+static void set_volume(uint8_t volume, struct btd_device *dev, void *user_data)
{
struct media_player *mp = user_data;
GSList *l;
diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
index 6aa5d41..c8a806d 100644
--- a/profiles/audio/transport.c
+++ b/profiles/audio/transport.c
@@ -666,7 +666,7 @@ static void set_volume(const GDBusPropertyTable *property,
}

if (a2dp->volume != volume)
- avrcp_set_volume(transport->device, volume);
+ avrcp_set_volume(transport->device->btd_dev, volume);

a2dp->volume = volume;

@@ -809,7 +809,7 @@ struct media_transport *media_transport_create(struct audio_device *device,
transport);
} else {
a2dp->volume = 127;
- avrcp_set_volume(device, a2dp->volume);
+ avrcp_set_volume(device->btd_dev, a2dp->volume);
transport->source_watch = source_add_state_cb(
device->source,
source_state_changed,
@@ -883,7 +883,7 @@ void media_transport_update_volume(struct media_transport *transport,
MEDIA_TRANSPORT_INTERFACE, "Volume");
}

-uint8_t media_transport_get_device_volume(struct audio_device *dev)
+uint8_t media_transport_get_device_volume(struct btd_device *dev)
{
GSList *l;

@@ -892,7 +892,7 @@ uint8_t media_transport_get_device_volume(struct audio_device *dev)

for (l = transports; l; l = l->next) {
struct media_transport *transport = l->data;
- if (transport->device != dev)
+ if (transport->device->btd_dev != dev)
continue;

/* Volume is A2DP only */
@@ -903,7 +903,7 @@ uint8_t media_transport_get_device_volume(struct audio_device *dev)
return 0;
}

-void media_transport_update_device_volume(struct audio_device *dev,
+void media_transport_update_device_volume(struct btd_device *dev,
uint8_t volume)
{
GSList *l;
@@ -913,7 +913,7 @@ void media_transport_update_device_volume(struct audio_device *dev,

for (l = transports; l; l = l->next) {
struct media_transport *transport = l->data;
- if (transport->device != dev)
+ if (transport->device->btd_dev != dev)
continue;

/* Volume is A2DP only */
diff --git a/profiles/audio/transport.h b/profiles/audio/transport.h
index 5e5da20..1501bf4 100644
--- a/profiles/audio/transport.h
+++ b/profiles/audio/transport.h
@@ -39,6 +39,6 @@ void media_transport_update_volume(struct media_transport *transport,
void transport_get_properties(struct media_transport *transport,
DBusMessageIter *iter);

-uint8_t media_transport_get_device_volume(struct audio_device *dev);
-void media_transport_update_device_volume(struct audio_device *dev,
+uint8_t media_transport_get_device_volume(struct btd_device *dev);
+void media_transport_update_device_volume(struct btd_device *dev,
uint8_t volume);
--
1.8.1.4


2013-07-03 15:15:29

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 08/20] audio/AVDTP: Remove dependency on struct audio_device

From: Luiz Augusto von Dentz <[email protected]>

This is part of the work necessary to completely remove
struct audio_device
---
profiles/audio/avdtp.c | 97 +++++++++++++++++++++-------------------------
profiles/audio/avdtp.h | 13 ++++---
profiles/audio/device.c | 10 +++--
profiles/audio/sink.c | 24 ++++++------
profiles/audio/source.c | 31 +++++++--------
profiles/audio/transport.c | 2 +-
6 files changed, 87 insertions(+), 90 deletions(-)

diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index bd73572..07644e5 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -47,10 +47,9 @@
#include "log.h"

#include "lib/uuid.h"
-#include "../src/adapter.h"
-#include "../src/device.h"
+#include "src/adapter.h"
+#include "src/device.h"

-#include "device.h"
#include "manager.h"
#include "control.h"
#include "avdtp.h"
@@ -356,8 +355,9 @@ struct stream_callback {

struct avdtp_state_callback {
avdtp_session_state_cb cb;
- struct audio_device *dev;
+ struct btd_device *dev;
unsigned int id;
+ void *user_data;
};

struct avdtp_stream {
@@ -714,24 +714,17 @@ static void avdtp_set_state(struct avdtp *session,
avdtp_session_state_t new_state)
{
GSList *l;
- struct audio_device *dev;
avdtp_session_state_t old_state = session->state;

session->state = new_state;

- dev = manager_get_audio_device(avdtp_get_device(session), FALSE);
- if (dev == NULL) {
- error("%s(): No matching audio device", __func__);
- return;
- }
-
for (l = avdtp_callbacks; l != NULL; l = l->next) {
struct avdtp_state_callback *cb = l->data;

- if (dev != cb->dev)
+ if (session->device != cb->dev)
continue;

- cb->cb(dev, session, old_state, new_state);
+ cb->cb(cb->dev, session, old_state, new_state, cb->user_data);
}
}

@@ -1155,21 +1148,27 @@ static void avdtp_free(void *data)
static gboolean disconnect_timeout(gpointer user_data)
{
struct avdtp *session = user_data;
- struct audio_device *dev;
+ struct btd_service *service;
gboolean stream_setup;

session->dc_timer = 0;

stream_setup = session->stream_setup;
session->stream_setup = FALSE;
- dev = manager_get_audio_device(session->device, FALSE);

- if (dev && dev->sink && stream_setup)
- sink_setup_stream(dev->sink, session);
- else if (dev && dev->source && stream_setup)
- source_setup_stream(dev->source, session);
- else
- connection_lost(session, ETIMEDOUT);
+ service = btd_device_get_service(session->device, A2DP_SINK_UUID);
+ if (service && stream_setup) {
+ sink_setup_stream(service, session);
+ return FALSE;
+ }
+
+ service = btd_device_get_service(session->device, A2DP_SOURCE_UUID);
+ if (service && stream_setup) {
+ source_setup_stream(service, session);
+ return FALSE;
+ }
+
+ connection_lost(session, ETIMEDOUT);

return FALSE;
}
@@ -1458,7 +1457,7 @@ static gboolean avdtp_setconf_cmd(struct avdtp *session, uint8_t transaction,
struct avdtp_local_sep *sep;
struct avdtp_stream *stream;
uint8_t err, category = 0x00;
- struct audio_device *dev;
+ struct btd_service *service;
GSList *l;

if (size < sizeof(struct setconf_req)) {
@@ -1477,18 +1476,15 @@ static gboolean avdtp_setconf_cmd(struct avdtp *session, uint8_t transaction,
goto failed;
}

- dev = manager_get_audio_device(avdtp_get_device(session), FALSE);
- if (!dev) {
- error("Unable to get a audio device object");
- err = AVDTP_BAD_STATE;
- goto failed;
- }
-
switch (sep->info.type) {
case AVDTP_SEP_TYPE_SOURCE:
- if (!dev->sink) {
- btd_device_add_uuid(dev->btd_dev, A2DP_SINK_UUID);
- if (!dev->sink) {
+ service = btd_device_get_service(session->device,
+ A2DP_SINK_UUID);
+ if (service == NULL) {
+ btd_device_add_uuid(session->device, A2DP_SINK_UUID);
+ service = btd_device_get_service(session->device,
+ A2DP_SINK_UUID);
+ if (service == NULL) {
error("Unable to get a audio sink object");
err = AVDTP_BAD_STATE;
goto failed;
@@ -1496,9 +1492,13 @@ static gboolean avdtp_setconf_cmd(struct avdtp *session, uint8_t transaction,
}
break;
case AVDTP_SEP_TYPE_SINK:
- if (!dev->source) {
- btd_device_add_uuid(dev->btd_dev, A2DP_SOURCE_UUID);
- if (!dev->source) {
+ service = btd_device_get_service(session->device,
+ A2DP_SOURCE_UUID);
+ if (service == NULL) {
+ btd_device_add_uuid(session->device, A2DP_SOURCE_UUID);
+ service = btd_device_get_service(session->device,
+ A2DP_SOURCE_UUID);
+ if (service == NULL) {
error("Unable to get a audio source object");
err = AVDTP_BAD_STATE;
goto failed;
@@ -2348,11 +2348,11 @@ static struct avdtp *avdtp_get_internal(struct btd_device *device)
return session;
}

-struct avdtp *avdtp_get(struct audio_device *device)
+struct avdtp *avdtp_get(struct btd_device *device)
{
struct avdtp *session;

- session = avdtp_get_internal(device->btd_dev);
+ session = avdtp_get_internal(device);

if (!session)
return NULL;
@@ -2465,7 +2465,6 @@ static void auth_cb(DBusError *derr, void *user_data)
static void avdtp_confirm_cb(GIOChannel *chan, gpointer data)
{
struct avdtp *session;
- struct audio_device *dev;
char address[18];
bdaddr_t src, dst;
GError *err = NULL;
@@ -2514,16 +2513,7 @@ static void avdtp_confirm_cb(GIOChannel *chan, gpointer data)
goto drop;
}

- dev = manager_get_audio_device(device, FALSE);
- if (!dev) {
- dev = manager_get_audio_device(device, TRUE);
- if (!dev) {
- error("Unable to get audio device object for %s",
- address);
- goto drop;
- }
- btd_device_add_uuid(dev->btd_dev, ADVANCED_AUDIO_UUID);
- }
+ btd_device_add_uuid(device, ADVANCED_AUDIO_UUID);

session->io = g_io_channel_ref(chan);
avdtp_set_state(session, AVDTP_SESSION_STATE_CONNECTING);
@@ -3186,16 +3176,16 @@ static gboolean avdtp_parse_rej(struct avdtp *session,
}
}

-gboolean avdtp_is_connected(struct audio_device *device)
+gboolean avdtp_is_connected(struct btd_device *device)
{
struct avdtp_server *server;
struct avdtp *session;

- server = find_server(servers, device_get_adapter(device->btd_dev));
+ server = find_server(servers, device_get_adapter(device));
if (!server)
return FALSE;

- session = find_session(server->sessions, device->btd_dev);
+ session = find_session(server->sessions, device);
if (!session)
return FALSE;

@@ -3922,8 +3912,8 @@ void avdtp_set_device_disconnect(struct avdtp *session, gboolean dev_dc)
session->device_disconnect = dev_dc;
}

-unsigned int avdtp_add_state_cb(struct audio_device *dev,
- avdtp_session_state_cb cb)
+unsigned int avdtp_add_state_cb(struct btd_device *dev,
+ avdtp_session_state_cb cb, void *user_data)
{
struct avdtp_state_callback *state_cb;
static unsigned int id = 0;
@@ -3932,6 +3922,7 @@ unsigned int avdtp_add_state_cb(struct audio_device *dev,
state_cb->cb = cb;
state_cb->dev = dev;
state_cb->id = ++id;
+ state_cb->user_data = user_data;

avdtp_callbacks = g_slist_append(avdtp_callbacks, state_cb);

diff --git a/profiles/audio/avdtp.h b/profiles/audio/avdtp.h
index 4e6a597..4d3e6c8 100644
--- a/profiles/audio/avdtp.h
+++ b/profiles/audio/avdtp.h
@@ -116,10 +116,11 @@ struct avdtp_media_codec_capability {
#error "Unknown byte order"
#endif

-typedef void (*avdtp_session_state_cb) (struct audio_device *dev,
+typedef void (*avdtp_session_state_cb) (struct btd_device *dev,
struct avdtp *session,
avdtp_session_state_t old_state,
- avdtp_session_state_t new_state);
+ avdtp_session_state_t new_state,
+ void *user_data);

typedef void (*avdtp_stream_state_cb) (struct avdtp_stream *stream,
avdtp_state_t old_state,
@@ -212,12 +213,12 @@ struct avdtp_sep_ind {
typedef void (*avdtp_discover_cb_t) (struct avdtp *session, GSList *seps,
struct avdtp_error *err, void *user_data);

-struct avdtp *avdtp_get(struct audio_device *device);
+struct avdtp *avdtp_get(struct btd_device *device);

void avdtp_unref(struct avdtp *session);
struct avdtp *avdtp_ref(struct avdtp *session);

-gboolean avdtp_is_connected(struct audio_device *device);
+gboolean avdtp_is_connected(struct btd_device *device);

struct avdtp_service_capability *avdtp_service_cap_new(uint8_t category,
void *data, int size);
@@ -259,8 +260,8 @@ gboolean avdtp_stream_has_capabilities(struct avdtp_stream *stream,
struct avdtp_remote_sep *avdtp_stream_get_remote_sep(
struct avdtp_stream *stream);

-unsigned int avdtp_add_state_cb(struct audio_device *dev,
- avdtp_session_state_cb cb);
+unsigned int avdtp_add_state_cb(struct btd_device *dev,
+ avdtp_session_state_cb cb, void *user_data);

gboolean avdtp_remove_state_cb(unsigned int id);

diff --git a/profiles/audio/device.c b/profiles/audio/device.c
index 0112cd1..e9c36cc 100644
--- a/profiles/audio/device.c
+++ b/profiles/audio/device.c
@@ -159,10 +159,13 @@ static void disconnect_cb(struct btd_device *btd_dev, gboolean removal,
priv->disconnecting = FALSE;
}

-static void device_avdtp_cb(struct audio_device *dev, struct avdtp *session,
+static void device_avdtp_cb(struct btd_device *device, struct avdtp *session,
avdtp_session_state_t old_state,
- avdtp_session_state_t new_state)
+ avdtp_session_state_t new_state,
+ void *user_data)
{
+ struct audio_device *dev = user_data;
+
if (!dev->control)
return;

@@ -252,7 +255,8 @@ struct audio_device *audio_device_register(struct btd_device *device)
disconnect_cb, dev,
NULL);
dev->priv->service_cb_id = btd_service_add_state_cb(service_cb, dev);
- dev->priv->avdtp_callback_id = avdtp_add_state_cb(dev, device_avdtp_cb);
+ dev->priv->avdtp_callback_id = avdtp_add_state_cb(device,
+ device_avdtp_cb, dev);
dev->priv->avctp_callback_id = avctp_add_state_cb(device,
device_avctp_cb, dev);

diff --git a/profiles/audio/sink.c b/profiles/audio/sink.c
index 76bc2ad..58fa137 100644
--- a/profiles/audio/sink.c
+++ b/profiles/audio/sink.c
@@ -85,9 +85,9 @@ static char *str_state[] = {
"SINK_STATE_PLAYING",
};

-static void sink_set_state(struct btd_service *service, sink_state_t new_state)
+static void sink_set_state(struct sink *sink, sink_state_t new_state)
{
- struct sink *sink = btd_service_get_user_data(service);
+ struct btd_service *service = sink->service;
struct btd_device *dev = btd_service_get_device(service);
sink_state_t old_state = sink->state;
GSList *l;
@@ -115,19 +115,20 @@ static void sink_set_state(struct btd_service *service, sink_state_t new_state)
}
}

-static void avdtp_state_callback(struct audio_device *dev,
+static void avdtp_state_callback(struct btd_device *dev,
struct avdtp *session,
avdtp_session_state_t old_state,
- avdtp_session_state_t new_state)
+ avdtp_session_state_t new_state,
+ void *user_data)
{
- struct sink *sink = btd_service_get_user_data(dev->sink);
+ struct sink *sink = user_data;

switch (new_state) {
case AVDTP_SESSION_STATE_DISCONNECTED:
- sink_set_state(dev->sink, SINK_STATE_DISCONNECTED);
+ sink_set_state(sink, SINK_STATE_DISCONNECTED);
break;
case AVDTP_SESSION_STATE_CONNECTING:
- sink_set_state(dev->sink, SINK_STATE_CONNECTING);
+ sink_set_state(sink, SINK_STATE_CONNECTING);
break;
case AVDTP_SESSION_STATE_CONNECTED:
break;
@@ -165,10 +166,10 @@ static void stream_state_changed(struct avdtp_stream *stream,
sink->cb_id = 0;
break;
case AVDTP_STATE_OPEN:
- sink_set_state(service, SINK_STATE_CONNECTED);
+ sink_set_state(sink, SINK_STATE_CONNECTED);
break;
case AVDTP_STATE_STREAMING:
- sink_set_state(service, SINK_STATE_PLAYING);
+ sink_set_state(sink, SINK_STATE_PLAYING);
break;
case AVDTP_STATE_CONFIGURED:
case AVDTP_STATE_CLOSING:
@@ -316,7 +317,7 @@ int sink_connect(struct btd_service *service)
struct sink *sink = btd_service_get_user_data(service);

if (!sink->session)
- sink->session = avdtp_get(sink->dev);
+ sink->session = avdtp_get(btd_service_get_device(service));

if (!sink->session) {
DBG("Unable to get a session");
@@ -394,7 +395,8 @@ struct btd_service *sink_init(struct audio_device *dev,
sink->dev = dev;
sink->service = btd_service_ref(service);

- sink->avdtp_callback_id = avdtp_add_state_cb(dev, avdtp_state_callback);
+ sink->avdtp_callback_id = avdtp_add_state_cb(dev->btd_dev,
+ avdtp_state_callback, sink);

btd_service_set_user_data(service, sink);

diff --git a/profiles/audio/source.c b/profiles/audio/source.c
index d5cd963..2e68ee8 100644
--- a/profiles/audio/source.c
+++ b/profiles/audio/source.c
@@ -86,10 +86,8 @@ static char *str_state[] = {
"SOURCE_STATE_PLAYING",
};

-static void source_set_state(struct btd_service *service,
- source_state_t new_state)
+static void source_set_state(struct source *source, source_state_t new_state)
{
- struct source *source = btd_service_get_user_data(service);
struct audio_device *dev = source->dev;
source_state_t old_state = source->state;
GSList *l;
@@ -102,10 +100,10 @@ static void source_set_state(struct btd_service *service,
for (l = source_callbacks; l != NULL; l = l->next) {
struct source_state_callback *cb = l->data;

- if (cb->service != service)
+ if (cb->service != source->service)
continue;

- cb->cb(service, old_state, new_state, cb->user_data);
+ cb->cb(source->service, old_state, new_state, cb->user_data);
}

if (new_state != SOURCE_STATE_DISCONNECTED)
@@ -117,19 +115,19 @@ static void source_set_state(struct btd_service *service,
}
}

-static void avdtp_state_callback(struct audio_device *dev,
- struct avdtp *session,
+static void avdtp_state_callback(struct btd_device *dev, struct avdtp *session,
avdtp_session_state_t old_state,
- avdtp_session_state_t new_state)
+ avdtp_session_state_t new_state,
+ void *user_data)
{
- struct source *source = btd_service_get_user_data(dev->source);
+ struct source *source = user_data;

switch (new_state) {
case AVDTP_SESSION_STATE_DISCONNECTED:
- source_set_state(dev->source, SOURCE_STATE_DISCONNECTED);
+ source_set_state(source, SOURCE_STATE_DISCONNECTED);
break;
case AVDTP_SESSION_STATE_CONNECTING:
- source_set_state(dev->source, SOURCE_STATE_CONNECTING);
+ source_set_state(source, SOURCE_STATE_CONNECTING);
break;
case AVDTP_SESSION_STATE_CONNECTED:
break;
@@ -167,10 +165,10 @@ static void stream_state_changed(struct avdtp_stream *stream,
source->cb_id = 0;
break;
case AVDTP_STATE_OPEN:
- source_set_state(service, SOURCE_STATE_CONNECTED);
+ source_set_state(source, SOURCE_STATE_CONNECTED);
break;
case AVDTP_STATE_STREAMING:
- source_set_state(service, SOURCE_STATE_PLAYING);
+ source_set_state(source, SOURCE_STATE_PLAYING);
break;
case AVDTP_STATE_CONFIGURED:
case AVDTP_STATE_CLOSING:
@@ -321,7 +319,7 @@ int source_connect(struct btd_service *service)
struct source *source = btd_service_get_user_data(service);

if (!source->session)
- source->session = avdtp_get(source->dev);
+ source->session = avdtp_get(btd_service_get_device(service));

if (!source->session) {
DBG("Unable to get a session");
@@ -399,8 +397,9 @@ struct btd_service *source_init(struct audio_device *dev,
source->dev = dev;
source->service = btd_service_ref(service);

- source->avdtp_callback_id = avdtp_add_state_cb(dev,
- avdtp_state_callback);
+ source->avdtp_callback_id = avdtp_add_state_cb(dev->btd_dev,
+ avdtp_state_callback,
+ source);

btd_service_set_user_data(service, source);

diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
index b4da18d..6aa5d41 100644
--- a/profiles/audio/transport.c
+++ b/profiles/audio/transport.c
@@ -332,7 +332,7 @@ static guint resume_a2dp(struct media_transport *transport,
guint id;

if (a2dp->session == NULL) {
- a2dp->session = avdtp_get(transport->device);
+ a2dp->session = avdtp_get(transport->device->btd_dev);
if (a2dp->session == NULL)
return 0;
}
--
1.8.1.4


2013-07-03 15:15:28

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 07/20] audio/AVCTP: Remove dependency on struct audio_device

From: Luiz Augusto von Dentz <[email protected]>

This is part of the work necessary to completely remove
struct audio_device
---
profiles/audio/avctp.c | 69 +++++++++++++++++-------------------------------
profiles/audio/avctp.h | 12 +++++----
profiles/audio/avrcp.c | 35 ++++++++++++------------
profiles/audio/control.c | 13 ++++-----
profiles/audio/device.c | 9 ++++---
5 files changed, 62 insertions(+), 76 deletions(-)

diff --git a/profiles/audio/avctp.c b/profiles/audio/avctp.c
index a4d0153..627252a 100644
--- a/profiles/audio/avctp.c
+++ b/profiles/audio/avctp.c
@@ -47,14 +47,13 @@
#include <btio/btio.h>

#include "lib/uuid.h"
-#include "adapter.h"
-#include "../src/device.h"
+#include "src/adapter.h"
+#include "src/device.h"

#include "log.h"
#include "error.h"
#include "uinput.h"
#include "manager.h"
-#include "device.h"
#include "avctp.h"
#include "avrcp.h"

@@ -119,8 +118,9 @@ struct avc_header {

struct avctp_state_callback {
avctp_state_cb cb;
- struct audio_device *dev;
+ struct btd_device *dev;
unsigned int id;
+ void *user_data;
};

struct avctp_server {
@@ -530,24 +530,17 @@ static void avctp_disconnected(struct avctp *session)
static void avctp_set_state(struct avctp *session, avctp_state_t new_state)
{
GSList *l;
- struct audio_device *dev;
avctp_state_t old_state = session->state;

- dev = manager_get_audio_device(session->device, FALSE);
- if (dev == NULL) {
- error("%s(): No matching audio device", __func__);
- return;
- }
-
session->state = new_state;

for (l = callbacks; l != NULL; l = l->next) {
struct avctp_state_callback *cb = l->data;

- if (cb->dev && cb->dev != dev)
+ if (cb->dev && cb->dev != session->device)
continue;

- cb->cb(dev, old_state, new_state);
+ cb->cb(session->device, old_state, new_state, cb->user_data);
}

switch (new_state) {
@@ -1059,12 +1052,9 @@ static int uinput_create(char *name)

static void init_uinput(struct avctp *session)
{
- struct audio_device *dev;
char address[18], name[248 + 1];

- dev = manager_get_audio_device(session->device, FALSE);
-
- device_get_name(dev->btd_dev, name, sizeof(name));
+ device_get_name(session->device, name, sizeof(name));
if (g_str_equal(name, "Nokia CK-20W")) {
session->key_quirks[AVC_FORWARD] |= QUIRK_NO_RELEASE;
session->key_quirks[AVC_BACKWARD] |= QUIRK_NO_RELEASE;
@@ -1296,7 +1286,7 @@ static struct avctp *avctp_get_internal(struct btd_device *device)
}

static void avctp_control_confirm(struct avctp *session, GIOChannel *chan,
- struct audio_device *dev)
+ struct btd_device *dev)
{
const bdaddr_t *src;
const bdaddr_t *dst;
@@ -1310,8 +1300,8 @@ static void avctp_control_confirm(struct avctp *session, GIOChannel *chan,
avctp_set_state(session, AVCTP_STATE_CONNECTING);
session->control = avctp_channel_create(session, chan, NULL);

- src = adapter_get_address(device_get_adapter(dev->btd_dev));
- dst = device_get_address(dev->btd_dev);
+ src = adapter_get_address(device_get_adapter(dev));
+ dst = device_get_address(dev);

session->auth_id = btd_request_authorization(src, dst,
AVRCP_TARGET_UUID,
@@ -1328,7 +1318,7 @@ drop:
}

static void avctp_browsing_confirm(struct avctp *session, GIOChannel *chan,
- struct audio_device *dev)
+ struct btd_device *dev)
{
GError *err = NULL;

@@ -1351,7 +1341,6 @@ static void avctp_browsing_confirm(struct avctp *session, GIOChannel *chan,
static void avctp_confirm_cb(GIOChannel *chan, gpointer data)
{
struct avctp *session;
- struct audio_device *dev;
char address[18];
bdaddr_t src, dst;
GError *err = NULL;
@@ -1381,34 +1370,22 @@ static void avctp_confirm_cb(GIOChannel *chan, gpointer data)
if (session == NULL)
return;

- dev = manager_get_audio_device(device, TRUE);
- if (!dev) {
- error("Unable to get audio device object for %s", address);
- goto drop;
- }
+ if (btd_device_get_service(device, AVRCP_REMOTE_UUID) == NULL)
+ btd_device_add_uuid(device, AVRCP_REMOTE_UUID);

- if (dev->control == NULL) {
- btd_device_add_uuid(dev->btd_dev, AVRCP_REMOTE_UUID);
- btd_device_add_uuid(dev->btd_dev, AVRCP_TARGET_UUID);
-
- if (dev->control == NULL)
- goto drop;
- }
+ if (btd_device_get_service(device, AVRCP_TARGET_UUID) == NULL)
+ btd_device_add_uuid(device, AVRCP_TARGET_UUID);

switch (psm) {
case AVCTP_CONTROL_PSM:
- avctp_control_confirm(session, chan, dev);
+ avctp_control_confirm(session, chan, device);
break;
case AVCTP_BROWSING_PSM:
- avctp_browsing_confirm(session, chan, dev);
+ avctp_browsing_confirm(session, chan, device);
break;
}

return;
-
-drop:
- if (psm == AVCTP_CONTROL_PSM)
- avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
}

static GIOChannel *avctp_server_socket(const bdaddr_t *src, gboolean master,
@@ -1721,7 +1698,8 @@ int avctp_send_vendordep_req(struct avctp *session, uint8_t code,
func, user_data);
}

-unsigned int avctp_add_state_cb(struct audio_device *dev, avctp_state_cb cb)
+unsigned int avctp_add_state_cb(struct btd_device *dev, avctp_state_cb cb,
+ void *user_data)
{
struct avctp_state_callback *state_cb;
static unsigned int id = 0;
@@ -1730,6 +1708,7 @@ unsigned int avctp_add_state_cb(struct audio_device *dev, avctp_state_cb cb)
state_cb->cb = cb;
state_cb->dev = dev;
state_cb->id = ++id;
+ state_cb->user_data = user_data;

callbacks = g_slist_append(callbacks, state_cb);

@@ -1919,13 +1898,13 @@ gboolean avctp_unregister_browsing_pdu_handler(unsigned int id)
return FALSE;
}

-struct avctp *avctp_connect(struct audio_device *device)
+struct avctp *avctp_connect(struct btd_device *device)
{
struct avctp *session;
GError *err = NULL;
GIOChannel *io;

- session = avctp_get_internal(device->btd_dev);
+ session = avctp_get_internal(device);
if (!session)
return NULL;

@@ -1999,9 +1978,9 @@ void avctp_disconnect(struct avctp *session)
avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
}

-struct avctp *avctp_get(struct audio_device *device)
+struct avctp *avctp_get(struct btd_device *device)
{
- return avctp_get_internal(device->btd_dev);
+ return avctp_get_internal(device);
}

bool avctp_is_initiator(struct avctp *session)
diff --git a/profiles/audio/avctp.h b/profiles/audio/avctp.h
index cd575cc..f9c665e 100644
--- a/profiles/audio/avctp.h
+++ b/profiles/audio/avctp.h
@@ -90,9 +90,10 @@ typedef enum {
AVCTP_STATE_BROWSING_CONNECTED
} avctp_state_t;

-typedef void (*avctp_state_cb) (struct audio_device *dev,
+typedef void (*avctp_state_cb) (struct btd_device *dev,
avctp_state_t old_state,
- avctp_state_t new_state);
+ avctp_state_t new_state,
+ void *user_data);

typedef bool (*avctp_passthrough_cb) (struct avctp *session,
uint8_t op, bool pressed,
@@ -112,14 +113,15 @@ typedef size_t (*avctp_browsing_pdu_cb) (struct avctp *session,
uint8_t *operands, size_t operand_count,
void *user_data);

-unsigned int avctp_add_state_cb(struct audio_device *dev, avctp_state_cb cb);
+unsigned int avctp_add_state_cb(struct btd_device *dev, avctp_state_cb cb,
+ void *user_data);
gboolean avctp_remove_state_cb(unsigned int id);

int avctp_register(struct btd_adapter *adapter, gboolean master);
void avctp_unregister(struct btd_adapter *adapter);

-struct avctp *avctp_connect(struct audio_device *device);
-struct avctp *avctp_get(struct audio_device *device);
+struct avctp *avctp_connect(struct btd_device *device);
+struct avctp *avctp_get(struct btd_device *device);
bool avctp_is_initiator(struct avctp *session);
int avctp_connect_browsing(struct avctp *session);
void avctp_disconnect(struct avctp *session);
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index cc007c5..1a5c477 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -3251,12 +3251,12 @@ static void avrcp_get_capabilities(struct avrcp *session)
session);
}

-static struct avrcp *find_session(GSList *list, struct audio_device *dev)
+static struct avrcp *find_session(GSList *list, struct btd_device *dev)
{
for (; list; list = list->next) {
struct avrcp *session = list->data;

- if (session->dev == dev)
+ if (session->dev->btd_dev == dev)
return session;
}

@@ -3425,16 +3425,17 @@ static void session_ct_destroy(struct avrcp *session)
}

static struct avrcp *session_create(struct avrcp_server *server,
- struct audio_device *dev)
+ struct btd_device *device)
{
struct avrcp *session;
const sdp_record_t *rec;
sdp_list_t *list;
sdp_profile_desc_t *desc;
+ struct audio_device *dev = manager_get_audio_device(device, FALSE);

session = g_new0(struct avrcp, 1);
session->server = server;
- session->conn = avctp_connect(dev);
+ session->conn = avctp_connect(device);
session->dev = dev;

server->sessions = g_slist_append(server->sessions, session);
@@ -3458,16 +3459,16 @@ static struct avrcp *session_create(struct avrcp_server *server,
session->init_browsing = session_tg_init_browsing;
session->destroy = session_tg_destroy;

- rec = btd_device_get_record(dev->btd_dev, AVRCP_REMOTE_UUID);
+ rec = btd_device_get_record(device, AVRCP_REMOTE_UUID);
if (rec == NULL)
- btd_device_add_uuid(dev->btd_dev, AVRCP_REMOTE_UUID);
+ btd_device_add_uuid(device, AVRCP_REMOTE_UUID);
} else {
session->init_control = session_ct_init_control;
session->init_browsing = session_ct_init_browsing;
session->destroy = session_ct_destroy;
- rec = btd_device_get_record(dev->btd_dev, AVRCP_TARGET_UUID);
+ rec = btd_device_get_record(device, AVRCP_TARGET_UUID);
if (rec == NULL)
- btd_device_add_uuid(dev->btd_dev, AVRCP_TARGET_UUID);
+ btd_device_add_uuid(device, AVRCP_TARGET_UUID);
}

if (rec == NULL)
@@ -3485,17 +3486,17 @@ static struct avrcp *session_create(struct avrcp_server *server,
return session;
}

-static void state_changed(struct audio_device *dev, avctp_state_t old_state,
- avctp_state_t new_state)
+static void state_changed(struct btd_device *device, avctp_state_t old_state,
+ avctp_state_t new_state, void *user_data)
{
struct avrcp_server *server;
struct avrcp *session;

- server = find_server(servers, device_get_adapter(dev->btd_dev));
+ server = find_server(servers, device_get_adapter(device));
if (!server)
return;

- session = find_session(server->sessions, dev);
+ session = find_session(server->sessions, device);

switch (new_state) {
case AVCTP_STATE_DISCONNECTED:
@@ -3509,7 +3510,7 @@ static void state_changed(struct audio_device *dev, avctp_state_t old_state,
if (session != NULL)
break;

- session_create(server, dev);
+ session_create(server, device);

break;
case AVCTP_STATE_CONNECTED:
@@ -3538,7 +3539,7 @@ gboolean avrcp_connect(struct audio_device *dev)
{
struct avctp *session;

- session = avctp_connect(dev);
+ session = avctp_connect(dev->btd_dev);
if (session)
return FALSE;

@@ -3549,7 +3550,7 @@ void avrcp_disconnect(struct audio_device *dev)
{
struct avctp *session;

- session = avctp_get(dev);
+ session = avctp_get(dev->btd_dev);
if (!session)
return;

@@ -3582,7 +3583,7 @@ static struct avrcp_server *avrcp_server_register(struct btd_adapter *adapter,
servers = g_slist_append(servers, server);

if (!avctp_id)
- avctp_id = avctp_add_state_cb(NULL, state_changed);
+ avctp_id = avctp_add_state_cb(NULL, state_changed, NULL);

return server;
}
@@ -3791,7 +3792,7 @@ int avrcp_set_volume(struct audio_device *dev, uint8_t volume)
if (server == NULL)
return -EINVAL;

- session = find_session(server->sessions, dev);
+ session = find_session(server->sessions, dev->btd_dev);
if (session == NULL)
return -ENOTCONN;

diff --git a/profiles/audio/control.c b/profiles/audio/control.c
index 1dffbd8..86d38f5 100644
--- a/profiles/audio/control.c
+++ b/profiles/audio/control.c
@@ -69,12 +69,12 @@ struct control {
unsigned int avctp_id;
};

-static void state_changed(struct audio_device *dev, avctp_state_t old_state,
- avctp_state_t new_state)
+static void state_changed(struct btd_device *dev, avctp_state_t old_state,
+ avctp_state_t new_state, void *user_data)
{
+ struct control *control = user_data;
DBusConnection *conn = btd_get_dbus_connection();
- struct control *control = btd_service_get_user_data(dev->control);
- const char *path = device_get_path(dev->btd_dev);
+ const char *path = device_get_path(dev);

switch (new_state) {
case AVCTP_STATE_DISCONNECTED:
@@ -110,7 +110,7 @@ int control_connect(struct btd_service *service)
if (!control->target)
return -ENOTSUP;

- control->session = avctp_connect(control->dev);
+ control->session = avctp_connect(control->dev->btd_dev);
if (!control->session)
return -EIO;

@@ -287,7 +287,8 @@ static struct control *control_init(struct audio_device *dev)
control = g_new0(struct control, 1);

control->dev = dev;
- control->avctp_id = avctp_add_state_cb(dev, state_changed);
+ control->avctp_id = avctp_add_state_cb(dev->btd_dev, state_changed,
+ control);

return control;
}
diff --git a/profiles/audio/device.c b/profiles/audio/device.c
index 416e1b2..0112cd1 100644
--- a/profiles/audio/device.c
+++ b/profiles/audio/device.c
@@ -198,9 +198,11 @@ static void device_sink_cb(struct audio_device *dev,
}
}

-static void device_avctp_cb(struct audio_device *dev, avctp_state_t old_state,
- avctp_state_t new_state)
+static void device_avctp_cb(struct btd_device *device, avctp_state_t old_state,
+ avctp_state_t new_state, void *user_data)
{
+ struct audio_device *dev = user_data;
+
if (!dev->control)
return;

@@ -251,7 +253,8 @@ struct audio_device *audio_device_register(struct btd_device *device)
NULL);
dev->priv->service_cb_id = btd_service_add_state_cb(service_cb, dev);
dev->priv->avdtp_callback_id = avdtp_add_state_cb(dev, device_avdtp_cb);
- dev->priv->avctp_callback_id = avctp_add_state_cb(dev, device_avctp_cb);
+ dev->priv->avctp_callback_id = avctp_add_state_cb(device,
+ device_avctp_cb, dev);

return dev;
}
--
1.8.1.4


2013-07-03 15:15:27

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 06/20] audio/control: Reduce dependency on struct audio_device

From: Luiz Augusto von Dentz <[email protected]>

This is part of the work necessary to completely remove
struct audio_device
---
profiles/audio/avrcp.c | 39 +++++++++++++++++++++++++++++--------
profiles/audio/control.c | 50 +++++++++++++-----------------------------------
profiles/audio/control.h | 13 ++++---------
profiles/audio/device.c | 2 +-
profiles/audio/manager.c | 18 ++---------------
5 files changed, 51 insertions(+), 71 deletions(-)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 763012d..cc007c5 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -47,8 +47,9 @@
#include <gdbus/gdbus.h>

#include "lib/uuid.h"
-#include "../src/adapter.h"
-#include "../src/device.h"
+#include "src/adapter.h"
+#include "src/device.h"
+#include "src/service.h"

#include "log.h"
#include "error.h"
@@ -3282,6 +3283,7 @@ static void session_tg_init_control(struct avrcp *session)
{
struct avrcp_server *server = session->server;
struct avrcp_player *player;
+ struct btd_service *service;

if (session->version < 0x0103)
return;
@@ -3314,7 +3316,10 @@ static void session_tg_init_control(struct avrcp *session)
avrcp_register_notification(session,
AVRCP_EVENT_VOLUME_CHANGED);

- control_remote_connected(session->dev, 0);
+ service = btd_device_get_service(session->dev->btd_dev,
+ AVRCP_REMOTE_UUID);
+ if (service != NULL)
+ btd_service_connecting_complete(service, 0);
}

static void session_ct_init_browsing(struct avrcp *session)
@@ -3329,6 +3334,7 @@ static void session_ct_init_browsing(struct avrcp *session)
static void session_ct_init_control(struct avrcp *session)
{
struct avrcp_player *player;
+ struct btd_service *service;

DBG("%p version 0x%04x", session, session->version);

@@ -3340,7 +3346,11 @@ static void session_ct_init_control(struct avrcp *session)
if (session->version >= 0x0104)
session->supported_events = (1 << AVRCP_EVENT_VOLUME_CHANGED);

- control_target_connected(session->dev, 0);
+
+ service = btd_device_get_service(session->dev->btd_dev,
+ AVRCP_TARGET_UUID);
+ if (service != NULL)
+ btd_service_connecting_complete(service, 0);

player = create_ct_player(session, 0);
if (player == NULL)
@@ -3373,30 +3383,43 @@ static void session_destroy(struct avrcp *session)
static void session_tg_destroy(struct avrcp *session)
{
struct avrcp_player *player = session->player;
+ struct btd_service *service;

DBG("%p", session);

if (player != NULL)
player->sessions = g_slist_remove(player->sessions, session);

+ service = btd_device_get_service(session->dev->btd_dev,
+ AVRCP_REMOTE_UUID);
+ if (service == NULL)
+ return session_destroy(session);
+
if (session->control_id == 0)
- control_remote_connected(session->dev, -EIO);
+ btd_service_connecting_complete(service, -EIO);
else
- control_remote_disconnected(session->dev, 0);
+ btd_service_disconnecting_complete(service, 0);

session_destroy(session);
}

static void session_ct_destroy(struct avrcp *session)
{
+ struct btd_service *service;
+
DBG("%p", session);

g_slist_free_full(session->players, player_destroy);

+ service = btd_device_get_service(session->dev->btd_dev,
+ AVRCP_TARGET_UUID);
+ if (service == NULL)
+ return session_destroy(session);
+
if (session->control_id == 0)
- control_target_connected(session->dev, -EIO);
+ btd_service_connecting_complete(service, -EIO);
else
- control_target_disconnected(session->dev, 0);
+ btd_service_disconnecting_complete(service, 0);

session_destroy(session);
}
diff --git a/profiles/audio/control.c b/profiles/audio/control.c
index 4c0a978..1dffbd8 100644
--- a/profiles/audio/control.c
+++ b/profiles/audio/control.c
@@ -62,40 +62,13 @@
#include "dbus-common.h"

struct control {
+ struct audio_device *dev;
struct avctp *session;
struct btd_service *target;
struct btd_service *remote;
unsigned int avctp_id;
};

-void control_target_connected(struct audio_device *dev, int err)
-{
- struct control *control = btd_service_get_user_data(dev->control);
-
- btd_service_connecting_complete(control->target, err);
-}
-
-void control_target_disconnected(struct audio_device *dev, int err)
-{
- struct control *control = btd_service_get_user_data(dev->control);
-
- btd_service_disconnecting_complete(control->target, err);
-}
-
-void control_remote_connected(struct audio_device *dev, int err)
-{
- struct control *control = btd_service_get_user_data(dev->control);
-
- btd_service_connecting_complete(control->remote, err);
-}
-
-void control_remote_disconnected(struct audio_device *dev, int err)
-{
- struct control *control = btd_service_get_user_data(dev->control);
-
- btd_service_disconnecting_complete(control->remote, err);
-}
-
static void state_changed(struct audio_device *dev, avctp_state_t old_state,
avctp_state_t new_state)
{
@@ -127,9 +100,9 @@ static void state_changed(struct audio_device *dev, avctp_state_t old_state,
}
}

-int control_connect(struct audio_device *dev)
+int control_connect(struct btd_service *service)
{
- struct control *control = btd_service_get_user_data(dev->control);
+ struct control *control = btd_service_get_user_data(service);

if (control->session)
return -EALREADY;
@@ -137,16 +110,16 @@ int control_connect(struct audio_device *dev)
if (!control->target)
return -ENOTSUP;

- control->session = avctp_connect(dev);
+ control->session = avctp_connect(control->dev);
if (!control->session)
return -EIO;

return 0;
}

-int control_disconnect(struct audio_device *dev)
+int control_disconnect(struct btd_service *service)
{
- struct control *control = btd_service_get_user_data(dev->control);
+ struct control *control = btd_service_get_user_data(service);

if (!control->session)
return -ENOTCONN;
@@ -284,10 +257,12 @@ static void path_unregister(void *data)
dev->control = NULL;
}

-void control_unregister(struct audio_device *dev)
+void control_unregister(struct btd_service *service)
{
+ struct btd_device *dev = btd_service_get_device(service);
+
g_dbus_unregister_interface(btd_get_dbus_connection(),
- device_get_path(dev->btd_dev),
+ device_get_path(dev),
AUDIO_CONTROL_INTERFACE);
}

@@ -311,6 +286,7 @@ static struct control *control_init(struct audio_device *dev)

control = g_new0(struct control, 1);

+ control->dev = dev;
control->avctp_id = avctp_add_state_cb(dev, state_changed);

return control;
@@ -348,9 +324,9 @@ struct btd_service *control_init_remote(struct audio_device *dev,
return service;
}

-gboolean control_is_active(struct audio_device *dev)
+gboolean control_is_active(struct btd_service *service)
{
- struct control *control = btd_service_get_user_data(dev->control);
+ struct control *control = btd_service_get_user_data(service);

if (control && control->session)
return TRUE;
diff --git a/profiles/audio/control.h b/profiles/audio/control.h
index 9d90c74..57668f9 100644
--- a/profiles/audio/control.h
+++ b/profiles/audio/control.h
@@ -30,13 +30,8 @@ struct btd_service *control_init_target(struct audio_device *dev,
struct btd_service *service);
struct btd_service *control_init_remote(struct audio_device *dev,
struct btd_service *service);
-void control_unregister(struct audio_device *dev);
-gboolean control_is_active(struct audio_device *dev);
+void control_unregister(struct btd_service *service);
+gboolean control_is_active(struct btd_service *service);

-int control_connect(struct audio_device *dev);
-int control_disconnect(struct audio_device *dev);
-
-void control_target_connected(struct audio_device *dev, int err);
-void control_target_disconnected(struct audio_device *dev, int err);
-void control_remote_connected(struct audio_device *dev, int err);
-void control_remote_disconnected(struct audio_device *dev, int err);
+int control_connect(struct btd_service *service);
+int control_disconnect(struct btd_service *service);
diff --git a/profiles/audio/device.c b/profiles/audio/device.c
index ea9a771..416e1b2 100644
--- a/profiles/audio/device.c
+++ b/profiles/audio/device.c
@@ -267,7 +267,7 @@ void audio_device_unregister(struct audio_device *device)
source_unregister(device->source);

if (device->control)
- control_unregister(device);
+ control_unregister(device->control);

device_free(device);
}
diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index 59cdecc..386cd88 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
@@ -214,34 +214,20 @@ static int avrcp_target_connect(struct btd_service *service)
{
struct btd_device *dev = btd_service_get_device(service);
const char *path = device_get_path(dev);
- struct audio_device *audio_dev;

DBG("path %s", path);

- audio_dev = get_audio_dev(dev);
- if (!audio_dev) {
- DBG("unable to get a device object");
- return -1;
- }
-
- return control_connect(audio_dev);
+ return control_connect(service);
}

static int avrcp_target_disconnect(struct btd_service *service)
{
struct btd_device *dev = btd_service_get_device(service);
const char *path = device_get_path(dev);
- struct audio_device *audio_dev;

DBG("path %s", path);

- audio_dev = get_audio_dev(dev);
- if (!audio_dev) {
- DBG("unable to get a device object");
- return -1;
- }
-
- return control_disconnect(audio_dev);
+ return control_disconnect(service);
}

static int a2dp_source_server_probe(struct btd_profile *p,
--
1.8.1.4


2013-07-03 15:15:26

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 05/20] audio/source: Reduce dependency on struct audio_device

From: Luiz Augusto von Dentz <[email protected]>

This is part of the work necessary to completely remove
struct audio_device
---
profiles/audio/a2dp.c | 4 +--
profiles/audio/avdtp.c | 2 +-
profiles/audio/device.c | 2 +-
profiles/audio/manager.c | 18 ++----------
profiles/audio/source.c | 69 +++++++++++++++++++++++++---------------------
profiles/audio/source.h | 17 ++++++------
profiles/audio/transport.c | 5 ++--
7 files changed, 55 insertions(+), 62 deletions(-)

diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index 5dc9218..e89be07 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -418,7 +418,7 @@ static gboolean auto_config(gpointer data)
if (setup->sep->type == AVDTP_SEP_TYPE_SOURCE)
sink_new_stream(dev->sink, setup->session, setup->stream);
else
- source_new_stream(setup->dev, setup->session, setup->stream);
+ source_new_stream(dev->source, setup->session, setup->stream);

done:
if (setup->setconf_cb)
@@ -621,7 +621,7 @@ static void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE)
sink_new_stream(dev->sink, session, setup->stream);
else
- source_new_stream(dev, session, setup->stream);
+ source_new_stream(dev->source, session, setup->stream);

/* Notify Endpoint */
if (a2dp_sep->endpoint) {
diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index ca09802..bd73572 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -1167,7 +1167,7 @@ static gboolean disconnect_timeout(gpointer user_data)
if (dev && dev->sink && stream_setup)
sink_setup_stream(dev->sink, session);
else if (dev && dev->source && stream_setup)
- source_setup_stream(dev, session);
+ source_setup_stream(dev->source, session);
else
connection_lost(session, ETIMEDOUT);

diff --git a/profiles/audio/device.c b/profiles/audio/device.c
index bc1ab26..ea9a771 100644
--- a/profiles/audio/device.c
+++ b/profiles/audio/device.c
@@ -264,7 +264,7 @@ void audio_device_unregister(struct audio_device *device)
sink_unregister(device->sink);

if (device->source)
- source_unregister(device);
+ source_unregister(device->source);

if (device->control)
control_unregister(device);
diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index fa0bddd..59cdecc 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
@@ -174,34 +174,20 @@ static int a2dp_source_connect(struct btd_service *service)
{
struct btd_device *dev = btd_service_get_device(service);
const char *path = device_get_path(dev);
- struct audio_device *audio_dev;

DBG("path %s", path);

- audio_dev = get_audio_dev(dev);
- if (!audio_dev) {
- DBG("unable to get a device object");
- return -1;
- }
-
- return source_connect(audio_dev);
+ return source_connect(service);
}

static int a2dp_source_disconnect(struct btd_service *service)
{
struct btd_device *dev = btd_service_get_device(service);
const char *path = device_get_path(dev);
- struct audio_device *audio_dev;

DBG("path %s", path);

- audio_dev = get_audio_dev(dev);
- if (!audio_dev) {
- DBG("unable to get a device object");
- return -1;
- }
-
- return source_disconnect(audio_dev, FALSE);
+ return source_disconnect(service, FALSE);
}

static int a2dp_sink_connect(struct btd_service *service)
diff --git a/profiles/audio/source.c b/profiles/audio/source.c
index 8edb73d..d5cd963 100644
--- a/profiles/audio/source.c
+++ b/profiles/audio/source.c
@@ -72,7 +72,7 @@ struct source {

struct source_state_callback {
source_state_cb cb;
- struct audio_device *dev;
+ struct btd_service *service;
void *user_data;
unsigned int id;
};
@@ -86,9 +86,11 @@ static char *str_state[] = {
"SOURCE_STATE_PLAYING",
};

-static void source_set_state(struct audio_device *dev, source_state_t new_state)
+static void source_set_state(struct btd_service *service,
+ source_state_t new_state)
{
- struct source *source = btd_service_get_user_data(dev->source);
+ struct source *source = btd_service_get_user_data(service);
+ struct audio_device *dev = source->dev;
source_state_t old_state = source->state;
GSList *l;

@@ -100,10 +102,10 @@ static void source_set_state(struct audio_device *dev, source_state_t new_state)
for (l = source_callbacks; l != NULL; l = l->next) {
struct source_state_callback *cb = l->data;

- if (cb->dev != dev)
+ if (cb->service != service)
continue;

- cb->cb(dev, old_state, new_state, cb->user_data);
+ cb->cb(service, old_state, new_state, cb->user_data);
}

if (new_state != SOURCE_STATE_DISCONNECTED)
@@ -124,10 +126,10 @@ static void avdtp_state_callback(struct audio_device *dev,

switch (new_state) {
case AVDTP_SESSION_STATE_DISCONNECTED:
- source_set_state(dev, SOURCE_STATE_DISCONNECTED);
+ source_set_state(dev->source, SOURCE_STATE_DISCONNECTED);
break;
case AVDTP_SESSION_STATE_CONNECTING:
- source_set_state(dev, SOURCE_STATE_CONNECTING);
+ source_set_state(dev->source, SOURCE_STATE_CONNECTING);
break;
case AVDTP_SESSION_STATE_CONNECTED:
break;
@@ -142,8 +144,8 @@ static void stream_state_changed(struct avdtp_stream *stream,
struct avdtp_error *err,
void *user_data)
{
- struct audio_device *dev = user_data;
- struct source *source = btd_service_get_user_data(dev->source);
+ struct btd_service *service = user_data;
+ struct source *source = btd_service_get_user_data(service);

if (err)
return;
@@ -153,7 +155,7 @@ static void stream_state_changed(struct avdtp_stream *stream,
btd_service_disconnecting_complete(source->service, 0);

if (source->disconnect_id > 0) {
- a2dp_cancel(dev, source->disconnect_id);
+ a2dp_cancel(source->dev, source->disconnect_id);
source->disconnect_id = 0;
}

@@ -165,10 +167,10 @@ static void stream_state_changed(struct avdtp_stream *stream,
source->cb_id = 0;
break;
case AVDTP_STATE_OPEN:
- source_set_state(dev, SOURCE_STATE_CONNECTED);
+ source_set_state(service, SOURCE_STATE_CONNECTED);
break;
case AVDTP_STATE_STREAMING:
- source_set_state(dev, SOURCE_STATE_PLAYING);
+ source_set_state(service, SOURCE_STATE_PLAYING);
break;
case AVDTP_STATE_CONFIGURED:
case AVDTP_STATE_CLOSING:
@@ -295,9 +297,9 @@ failed:
source->session = NULL;
}

-gboolean source_setup_stream(struct audio_device *dev, struct avdtp *session)
+gboolean source_setup_stream(struct btd_service *service, struct avdtp *session)
{
- struct source *source = btd_service_get_user_data(dev->source);
+ struct source *source = btd_service_get_user_data(service);

if (source->connect_id > 0 || source->disconnect_id > 0)
return FALSE;
@@ -314,12 +316,12 @@ gboolean source_setup_stream(struct audio_device *dev, struct avdtp *session)
return TRUE;
}

-int source_connect(struct audio_device *dev)
+int source_connect(struct btd_service *service)
{
- struct source *source = btd_service_get_user_data(dev->source);
+ struct source *source = btd_service_get_user_data(service);

if (!source->session)
- source->session = avdtp_get(dev);
+ source->session = avdtp_get(source->dev);

if (!source->session) {
DBG("Unable to get a session");
@@ -332,7 +334,7 @@ int source_connect(struct audio_device *dev)
if (source->stream_state >= AVDTP_STATE_OPEN)
return -EALREADY;

- if (!source_setup_stream(dev, NULL)) {
+ if (!source_setup_stream(service, NULL)) {
DBG("Failed to create a stream");
return -EIO;
}
@@ -342,9 +344,10 @@ int source_connect(struct audio_device *dev)
return 0;
}

-static void source_free(struct audio_device *dev)
+static void source_free(struct btd_service *service)
{
- struct source *source = btd_service_get_user_data(dev->source);
+ struct source *source = btd_service_get_user_data(service);
+ struct audio_device *dev = source->dev;

if (source->cb_id)
avdtp_stream_remove_cb(source->session, source->stream,
@@ -375,11 +378,13 @@ static void source_free(struct audio_device *dev)
dev->source = NULL;
}

-void source_unregister(struct audio_device *dev)
+void source_unregister(struct btd_service *service)
{
- DBG("%s", device_get_path(dev->btd_dev));
+ struct btd_device *dev = btd_service_get_device(service);
+
+ DBG("%s", device_get_path(dev));

- source_free(dev);
+ source_free(service);
}

struct btd_service *source_init(struct audio_device *dev,
@@ -402,10 +407,10 @@ struct btd_service *source_init(struct audio_device *dev,
return service;
}

-gboolean source_new_stream(struct audio_device *dev, struct avdtp *session,
+gboolean source_new_stream(struct btd_service *service, struct avdtp *session,
struct avdtp_stream *stream)
{
- struct source *source = btd_service_get_user_data(dev->source);
+ struct source *source = btd_service_get_user_data(service);

if (source->stream)
return FALSE;
@@ -416,14 +421,14 @@ gboolean source_new_stream(struct audio_device *dev, struct avdtp *session,
source->stream = stream;

source->cb_id = avdtp_stream_add_cb(session, stream,
- stream_state_changed, dev);
+ stream_state_changed, service);

return TRUE;
}

-int source_disconnect(struct audio_device *dev, gboolean shutdown)
+int source_disconnect(struct btd_service *service, gboolean shutdown)
{
- struct source *source = btd_service_get_user_data(dev->source);
+ struct source *source = btd_service_get_user_data(service);

if (!source->session)
return -ENOTCONN;
@@ -433,7 +438,7 @@ int source_disconnect(struct audio_device *dev, gboolean shutdown)

/* cancel pending connect */
if (source->connect_id > 0) {
- a2dp_cancel(dev, source->connect_id);
+ a2dp_cancel(source->dev, source->connect_id);
source->connect_id = 0;
btd_service_connecting_complete(source->service, -ECANCELED);

@@ -453,15 +458,15 @@ int source_disconnect(struct audio_device *dev, gboolean shutdown)
return avdtp_close(source->session, source->stream, FALSE);
}

-unsigned int source_add_state_cb(struct audio_device *dev, source_state_cb cb,
- void *user_data)
+unsigned int source_add_state_cb(struct btd_service *service,
+ source_state_cb cb, void *user_data)
{
struct source_state_callback *state_cb;
static unsigned int id = 0;

state_cb = g_new(struct source_state_callback, 1);
state_cb->cb = cb;
- state_cb->dev = dev;
+ state_cb->service = service;
state_cb->user_data = user_data;
state_cb->id = ++id;

diff --git a/profiles/audio/source.h b/profiles/audio/source.h
index 427de87..b9d4707 100644
--- a/profiles/audio/source.h
+++ b/profiles/audio/source.h
@@ -30,22 +30,23 @@ typedef enum {
SOURCE_STATE_PLAYING,
} source_state_t;

-typedef void (*source_state_cb) (struct audio_device *dev,
+typedef void (*source_state_cb) (struct btd_service *service,
source_state_t old_state,
source_state_t new_state,
void *user_data);

struct btd_service;

-unsigned int source_add_state_cb(struct audio_device *dev, source_state_cb cb,
- void *user_data);
+unsigned int source_add_state_cb(struct btd_service *service,
+ source_state_cb cb, void *user_data);
gboolean source_remove_state_cb(unsigned int id);

struct btd_service *source_init(struct audio_device *dev,
struct btd_service *service);
-void source_unregister(struct audio_device *dev);
-int source_connect(struct audio_device *dev);
-gboolean source_new_stream(struct audio_device *dev, struct avdtp *session,
+void source_unregister(struct btd_service *service);
+int source_connect(struct btd_service *service);
+gboolean source_new_stream(struct btd_service *service, struct avdtp *session,
struct avdtp_stream *stream);
-gboolean source_setup_stream(struct audio_device *dev, struct avdtp *session);
-int source_disconnect(struct audio_device *dev, gboolean shutdown);
+gboolean source_setup_stream(struct btd_service *service,
+ struct avdtp *session);
+int source_disconnect(struct btd_service *service, gboolean shutdown);
diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
index 3e83a95..b4da18d 100644
--- a/profiles/audio/transport.c
+++ b/profiles/audio/transport.c
@@ -757,7 +757,7 @@ static void sink_state_changed(struct btd_service *service,
transport_update_playing(transport, FALSE);
}

-static void source_state_changed(struct audio_device *dev,
+static void source_state_changed(struct btd_service *service,
source_state_t old_state,
source_state_t new_state,
void *user_data)
@@ -810,7 +810,8 @@ struct media_transport *media_transport_create(struct audio_device *device,
} else {
a2dp->volume = 127;
avrcp_set_volume(device, a2dp->volume);
- transport->source_watch = source_add_state_cb(device,
+ transport->source_watch = source_add_state_cb(
+ device->source,
source_state_changed,
transport);
}
--
1.8.1.4


2013-07-03 15:15:24

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 03/20] audio/control: Use service user_data for private data

From: Luiz Augusto von Dentz <[email protected]>

This remove the need of forward declaration of struct control and prepare
for a complete removal of struct audio_device.
---
profiles/audio/avrcp.c | 12 ++++++------
profiles/audio/control.c | 45 +++++++++++++++++++++++++++++----------------
profiles/audio/control.h | 12 ++++++------
profiles/audio/device.h | 3 +--
4 files changed, 42 insertions(+), 30 deletions(-)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index ffc6415..4316f8e 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -3314,7 +3314,7 @@ static void session_tg_init_control(struct avrcp *session)
avrcp_register_notification(session,
AVRCP_EVENT_VOLUME_CHANGED);

- control_remote_connected(session->dev->control, 0);
+ control_remote_connected(session->dev, 0);
}

static void session_ct_init_browsing(struct avrcp *session)
@@ -3340,7 +3340,7 @@ static void session_ct_init_control(struct avrcp *session)
if (session->version >= 0x0104)
session->supported_events = (1 << AVRCP_EVENT_VOLUME_CHANGED);

- control_target_connected(session->dev->control, 0);
+ control_target_connected(session->dev, 0);

player = create_ct_player(session, 0);
if (player == NULL)
@@ -3380,9 +3380,9 @@ static void session_tg_destroy(struct avrcp *session)
player->sessions = g_slist_remove(player->sessions, session);

if (session->control_id == 0)
- control_remote_connected(session->dev->control, -EIO);
+ control_remote_connected(session->dev, -EIO);
else
- control_remote_disconnected(session->dev->control, 0);
+ control_remote_disconnected(session->dev, 0);

session_destroy(session);
}
@@ -3394,9 +3394,9 @@ static void session_ct_destroy(struct avrcp *session)
g_slist_free_full(session->players, player_destroy);

if (session->control_id == 0)
- control_target_connected(session->dev->control, -EIO);
+ control_target_connected(session->dev, -EIO);
else
- control_target_disconnected(session->dev->control, 0);
+ control_target_disconnected(session->dev, 0);

session_destroy(session);
}
diff --git a/profiles/audio/control.c b/profiles/audio/control.c
index c33dcad..4c0a978 100644
--- a/profiles/audio/control.c
+++ b/profiles/audio/control.c
@@ -68,23 +68,31 @@ struct control {
unsigned int avctp_id;
};

-void control_target_connected(struct control *control, int err)
+void control_target_connected(struct audio_device *dev, int err)
{
+ struct control *control = btd_service_get_user_data(dev->control);
+
btd_service_connecting_complete(control->target, err);
}

-void control_target_disconnected(struct control *control, int err)
+void control_target_disconnected(struct audio_device *dev, int err)
{
+ struct control *control = btd_service_get_user_data(dev->control);
+
btd_service_disconnecting_complete(control->target, err);
}

-void control_remote_connected(struct control *control, int err)
+void control_remote_connected(struct audio_device *dev, int err)
{
+ struct control *control = btd_service_get_user_data(dev->control);
+
btd_service_connecting_complete(control->remote, err);
}

-void control_remote_disconnected(struct control *control, int err)
+void control_remote_disconnected(struct audio_device *dev, int err)
{
+ struct control *control = btd_service_get_user_data(dev->control);
+
btd_service_disconnecting_complete(control->remote, err);
}

@@ -92,7 +100,7 @@ static void state_changed(struct audio_device *dev, avctp_state_t old_state,
avctp_state_t new_state)
{
DBusConnection *conn = btd_get_dbus_connection();
- struct control *control = dev->control;
+ struct control *control = btd_service_get_user_data(dev->control);
const char *path = device_get_path(dev->btd_dev);

switch (new_state) {
@@ -121,7 +129,7 @@ static void state_changed(struct audio_device *dev, avctp_state_t old_state,

int control_connect(struct audio_device *dev)
{
- struct control *control = dev->control;
+ struct control *control = btd_service_get_user_data(dev->control);

if (control->session)
return -EALREADY;
@@ -138,7 +146,7 @@ int control_connect(struct audio_device *dev)

int control_disconnect(struct audio_device *dev)
{
- struct control *control = dev->control;
+ struct control *control = btd_service_get_user_data(dev->control);

if (!control->session)
return -ENOTCONN;
@@ -152,7 +160,7 @@ static DBusMessage *key_pressed(DBusConnection *conn, DBusMessage *msg,
uint8_t op, void *data)
{
struct audio_device *device = data;
- struct control *control = device->control;
+ struct control *control = btd_service_get_user_data(device->control);
int err;

if (!control->session)
@@ -227,7 +235,8 @@ static gboolean control_property_get_connected(
DBusMessageIter *iter, void *data)
{
struct audio_device *device = data;
- dbus_bool_t value = (device->control->session != NULL);
+ struct control *control = btd_service_get_user_data(device->control);
+ dbus_bool_t value = (control->session != NULL);

dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &value);

@@ -255,7 +264,7 @@ static const GDBusPropertyTable control_properties[] = {
static void path_unregister(void *data)
{
struct audio_device *dev = data;
- struct control *control = dev->control;
+ struct control *control = btd_service_get_user_data(dev->control);

DBG("Unregistered interface %s on path %s",
AUDIO_CONTROL_INTERFACE, device_get_path(dev->btd_dev));
@@ -287,7 +296,7 @@ static struct control *control_init(struct audio_device *dev)
struct control *control;

if (dev->control != NULL)
- return dev->control;
+ return btd_service_get_user_data(dev->control);

if (!g_dbus_register_interface(btd_get_dbus_connection(),
device_get_path(dev->btd_dev),
@@ -307,7 +316,7 @@ static struct control *control_init(struct audio_device *dev)
return control;
}

-struct control *control_init_target(struct audio_device *dev,
+struct btd_service *control_init_target(struct audio_device *dev,
struct btd_service *service)
{
struct control *control;
@@ -318,10 +327,12 @@ struct control *control_init_target(struct audio_device *dev,

control->target = btd_service_ref(service);

- return control;
+ btd_service_set_user_data(service, control);
+
+ return service;
}

-struct control *control_init_remote(struct audio_device *dev,
+struct btd_service *control_init_remote(struct audio_device *dev,
struct btd_service *service)
{
struct control *control;
@@ -332,12 +343,14 @@ struct control *control_init_remote(struct audio_device *dev,

control->remote = btd_service_ref(service);

- return control;
+ btd_service_set_user_data(service, control);
+
+ return service;
}

gboolean control_is_active(struct audio_device *dev)
{
- struct control *control = dev->control;
+ struct control *control = btd_service_get_user_data(dev->control);

if (control && control->session)
return TRUE;
diff --git a/profiles/audio/control.h b/profiles/audio/control.h
index af6893b..9d90c74 100644
--- a/profiles/audio/control.h
+++ b/profiles/audio/control.h
@@ -26,9 +26,9 @@

struct btd_service;

-struct control *control_init_target(struct audio_device *dev,
+struct btd_service *control_init_target(struct audio_device *dev,
struct btd_service *service);
-struct control *control_init_remote(struct audio_device *dev,
+struct btd_service *control_init_remote(struct audio_device *dev,
struct btd_service *service);
void control_unregister(struct audio_device *dev);
gboolean control_is_active(struct audio_device *dev);
@@ -36,7 +36,7 @@ gboolean control_is_active(struct audio_device *dev);
int control_connect(struct audio_device *dev);
int control_disconnect(struct audio_device *dev);

-void control_target_connected(struct control *control, int err);
-void control_target_disconnected(struct control *control, int err);
-void control_remote_connected(struct control *control, int err);
-void control_remote_disconnected(struct control *control, int err);
+void control_target_connected(struct audio_device *dev, int err);
+void control_target_disconnected(struct audio_device *dev, int err);
+void control_remote_connected(struct audio_device *dev, int err);
+void control_remote_disconnected(struct audio_device *dev, int err);
diff --git a/profiles/audio/device.h b/profiles/audio/device.h
index 9e0147e..87fc067 100644
--- a/profiles/audio/device.h
+++ b/profiles/audio/device.h
@@ -23,7 +23,6 @@
*/

struct audio_device;
-struct control;
struct dev_priv;

struct audio_device {
@@ -31,7 +30,7 @@ struct audio_device {

struct btd_service *sink;
struct btd_service *source;
- struct control *control;
+ struct btd_service *control;

struct dev_priv *priv;
};
--
1.8.1.4


2013-07-03 15:15:23

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 02/20] audio/source: Use service user_data for private data

From: Luiz Augusto von Dentz <[email protected]>

This remove the need of forward declaration of struct source and prepare
for a complete removal of struct audio_device.
---
profiles/audio/avdtp.c | 2 +-
profiles/audio/device.h | 3 +--
profiles/audio/source.c | 26 +++++++++++++++-----------
profiles/audio/source.h | 6 +++---
4 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index 0d67e67..7874cf6 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -1167,7 +1167,7 @@ static gboolean disconnect_timeout(gpointer user_data)
if (dev && dev->sink && stream_setup)
sink_setup_stream(dev, session);
else if (dev && dev->source && stream_setup)
- source_setup_stream(dev->source, session);
+ source_setup_stream(dev, session);
else
connection_lost(session, ETIMEDOUT);

diff --git a/profiles/audio/device.h b/profiles/audio/device.h
index e24bdf9..9e0147e 100644
--- a/profiles/audio/device.h
+++ b/profiles/audio/device.h
@@ -23,7 +23,6 @@
*/

struct audio_device;
-struct source;
struct control;
struct dev_priv;

@@ -31,7 +30,7 @@ struct audio_device {
struct btd_device *btd_dev;

struct btd_service *sink;
- struct source *source;
+ struct btd_service *source;
struct control *control;

struct dev_priv *priv;
diff --git a/profiles/audio/source.c b/profiles/audio/source.c
index 226c372..8edb73d 100644
--- a/profiles/audio/source.c
+++ b/profiles/audio/source.c
@@ -88,7 +88,7 @@ static char *str_state[] = {

static void source_set_state(struct audio_device *dev, source_state_t new_state)
{
- struct source *source = dev->source;
+ struct source *source = btd_service_get_user_data(dev->source);
source_state_t old_state = source->state;
GSList *l;

@@ -120,7 +120,7 @@ static void avdtp_state_callback(struct audio_device *dev,
avdtp_session_state_t old_state,
avdtp_session_state_t new_state)
{
- struct source *source = dev->source;
+ struct source *source = btd_service_get_user_data(dev->source);

switch (new_state) {
case AVDTP_SESSION_STATE_DISCONNECTED:
@@ -143,7 +143,7 @@ static void stream_state_changed(struct avdtp_stream *stream,
void *user_data)
{
struct audio_device *dev = user_data;
- struct source *source = dev->source;
+ struct source *source = btd_service_get_user_data(dev->source);

if (err)
return;
@@ -295,8 +295,10 @@ failed:
source->session = NULL;
}

-gboolean source_setup_stream(struct source *source, struct avdtp *session)
+gboolean source_setup_stream(struct audio_device *dev, struct avdtp *session)
{
+ struct source *source = btd_service_get_user_data(dev->source);
+
if (source->connect_id > 0 || source->disconnect_id > 0)
return FALSE;

@@ -314,7 +316,7 @@ gboolean source_setup_stream(struct source *source, struct avdtp *session)

int source_connect(struct audio_device *dev)
{
- struct source *source = dev->source;
+ struct source *source = btd_service_get_user_data(dev->source);

if (!source->session)
source->session = avdtp_get(dev);
@@ -330,7 +332,7 @@ int source_connect(struct audio_device *dev)
if (source->stream_state >= AVDTP_STATE_OPEN)
return -EALREADY;

- if (!source_setup_stream(source, NULL)) {
+ if (!source_setup_stream(dev, NULL)) {
DBG("Failed to create a stream");
return -EIO;
}
@@ -342,7 +344,7 @@ int source_connect(struct audio_device *dev)

static void source_free(struct audio_device *dev)
{
- struct source *source = dev->source;
+ struct source *source = btd_service_get_user_data(dev->source);

if (source->cb_id)
avdtp_stream_remove_cb(source->session, source->stream,
@@ -380,7 +382,7 @@ void source_unregister(struct audio_device *dev)
source_free(dev);
}

-struct source *source_init(struct audio_device *dev,
+struct btd_service *source_init(struct audio_device *dev,
struct btd_service *service)
{
struct source *source;
@@ -395,13 +397,15 @@ struct source *source_init(struct audio_device *dev,
source->avdtp_callback_id = avdtp_add_state_cb(dev,
avdtp_state_callback);

- return source;
+ btd_service_set_user_data(service, source);
+
+ return service;
}

gboolean source_new_stream(struct audio_device *dev, struct avdtp *session,
struct avdtp_stream *stream)
{
- struct source *source = dev->source;
+ struct source *source = btd_service_get_user_data(dev->source);

if (source->stream)
return FALSE;
@@ -419,7 +423,7 @@ gboolean source_new_stream(struct audio_device *dev, struct avdtp *session,

int source_disconnect(struct audio_device *dev, gboolean shutdown)
{
- struct source *source = dev->source;
+ struct source *source = btd_service_get_user_data(dev->source);

if (!source->session)
return -ENOTCONN;
diff --git a/profiles/audio/source.h b/profiles/audio/source.h
index 8bd20a7..427de87 100644
--- a/profiles/audio/source.h
+++ b/profiles/audio/source.h
@@ -41,11 +41,11 @@ unsigned int source_add_state_cb(struct audio_device *dev, source_state_cb cb,
void *user_data);
gboolean source_remove_state_cb(unsigned int id);

-struct source *source_init(struct audio_device *dev,
- struct btd_service *service);
+struct btd_service *source_init(struct audio_device *dev,
+ struct btd_service *service);
void source_unregister(struct audio_device *dev);
int source_connect(struct audio_device *dev);
gboolean source_new_stream(struct audio_device *dev, struct avdtp *session,
struct avdtp_stream *stream);
-gboolean source_setup_stream(struct source *source, struct avdtp *session);
+gboolean source_setup_stream(struct audio_device *dev, struct avdtp *session);
int source_disconnect(struct audio_device *dev, gboolean shutdown);
--
1.8.1.4


2013-07-03 15:15:25

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 04/20] audio/sink: Reduce dependency on struct audio_device

From: Luiz Augusto von Dentz <[email protected]>

This is part of the work necessary to completely remove
struct audio_device
---
profiles/audio/a2dp.c | 5 ++--
profiles/audio/avdtp.c | 2 +-
profiles/audio/avrcp.c | 2 +-
profiles/audio/device.c | 4 +--
profiles/audio/manager.c | 20 ++-----------
profiles/audio/sink.c | 72 +++++++++++++++++++++++++---------------------
profiles/audio/sink.h | 16 +++++------
profiles/audio/transport.c | 4 +--
8 files changed, 59 insertions(+), 66 deletions(-)

diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index c6973ae..5dc9218 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -403,6 +403,7 @@ static void stream_state_changed(struct avdtp_stream *stream,
static gboolean auto_config(gpointer data)
{
struct a2dp_setup *setup = data;
+ struct audio_device *dev = setup->dev;

/* Check if configuration was aborted */
if (setup->sep->stream == NULL)
@@ -415,7 +416,7 @@ static gboolean auto_config(gpointer data)
stream_state_changed, setup->sep);

if (setup->sep->type == AVDTP_SEP_TYPE_SOURCE)
- sink_new_stream(setup->dev, setup->session, setup->stream);
+ sink_new_stream(dev->sink, setup->session, setup->stream);
else
source_new_stream(setup->dev, setup->session, setup->stream);

@@ -618,7 +619,7 @@ static void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,

/* Notify D-Bus interface of the new stream */
if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE)
- sink_new_stream(dev, session, setup->stream);
+ sink_new_stream(dev->sink, session, setup->stream);
else
source_new_stream(dev, session, setup->stream);

diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index 7874cf6..ca09802 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -1165,7 +1165,7 @@ static gboolean disconnect_timeout(gpointer user_data)
dev = manager_get_audio_device(session->device, FALSE);

if (dev && dev->sink && stream_setup)
- sink_setup_stream(dev, session);
+ sink_setup_stream(dev->sink, session);
else if (dev && dev->source && stream_setup)
source_setup_stream(dev, session);
else
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 4316f8e..763012d 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -3425,7 +3425,7 @@ static struct avrcp *session_create(struct avrcp_server *server,
session->target = TRUE;
else if (dev->source && !dev->sink)
session->target = FALSE;
- else if (dev->sink && sink_is_active(dev))
+ else if (dev->sink && sink_is_active(dev->sink))
session->target = TRUE;
else
session->target = FALSE;
diff --git a/profiles/audio/device.c b/profiles/audio/device.c
index f11c728..bc1ab26 100644
--- a/profiles/audio/device.c
+++ b/profiles/audio/device.c
@@ -154,7 +154,7 @@ static void disconnect_cb(struct btd_device *btd_dev, gboolean removal,

sink = btd_device_get_service(btd_dev, A2DP_SINK_UUID);
if (sink)
- sink_disconnect(dev, TRUE);
+ sink_disconnect(sink, TRUE);
else
priv->disconnecting = FALSE;
}
@@ -261,7 +261,7 @@ void audio_device_unregister(struct audio_device *device)
DBG("%s", device_get_path(device->btd_dev));

if (device->sink)
- sink_unregister(device);
+ sink_unregister(device->sink);

if (device->source)
source_unregister(device);
diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index 7f02fbd..fa0bddd 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
@@ -148,7 +148,7 @@ static int avrcp_target_probe(struct btd_service *service)

audio_dev->control = control_init_target(audio_dev, service);

- if (audio_dev->sink && sink_is_active(audio_dev))
+ if (audio_dev->sink && sink_is_active(audio_dev->sink))
avrcp_connect(audio_dev);

return 0;
@@ -208,34 +208,20 @@ static int a2dp_sink_connect(struct btd_service *service)
{
struct btd_device *dev = btd_service_get_device(service);
const char *path = device_get_path(dev);
- struct audio_device *audio_dev;

DBG("path %s", path);

- audio_dev = get_audio_dev(dev);
- if (!audio_dev) {
- DBG("unable to get a device object");
- return -1;
- }
-
- return sink_connect(audio_dev);
+ return sink_connect(service);
}

static int a2dp_sink_disconnect(struct btd_service *service)
{
struct btd_device *dev = btd_service_get_device(service);
const char *path = device_get_path(dev);
- struct audio_device *audio_dev;

DBG("path %s", path);

- audio_dev = get_audio_dev(dev);
- if (!audio_dev) {
- DBG("unable to get a device object");
- return -1;
- }
-
- return sink_disconnect(audio_dev, FALSE);
+ return sink_disconnect(service, FALSE);
}

static int avrcp_target_connect(struct btd_service *service)
diff --git a/profiles/audio/sink.c b/profiles/audio/sink.c
index f5b4e67..76bc2ad 100644
--- a/profiles/audio/sink.c
+++ b/profiles/audio/sink.c
@@ -71,7 +71,7 @@ struct sink {

struct sink_state_callback {
sink_state_cb cb;
- struct audio_device *dev;
+ struct btd_service *service;
void *user_data;
unsigned int id;
};
@@ -85,24 +85,25 @@ static char *str_state[] = {
"SINK_STATE_PLAYING",
};

-static void sink_set_state(struct audio_device *dev, sink_state_t new_state)
+static void sink_set_state(struct btd_service *service, sink_state_t new_state)
{
- struct sink *sink = btd_service_get_user_data(dev->sink);
+ struct sink *sink = btd_service_get_user_data(service);
+ struct btd_device *dev = btd_service_get_device(service);
sink_state_t old_state = sink->state;
GSList *l;

sink->state = new_state;

- DBG("State changed %s: %s -> %s", device_get_path(dev->btd_dev),
+ DBG("State changed %s: %s -> %s", device_get_path(dev),
str_state[old_state], str_state[new_state]);

for (l = sink_callbacks; l != NULL; l = l->next) {
struct sink_state_callback *cb = l->data;

- if (cb->dev != dev)
+ if (cb->service != service)
continue;

- cb->cb(dev, old_state, new_state, cb->user_data);
+ cb->cb(service, old_state, new_state, cb->user_data);
}

if (new_state != SINK_STATE_DISCONNECTED)
@@ -123,10 +124,10 @@ static void avdtp_state_callback(struct audio_device *dev,

switch (new_state) {
case AVDTP_SESSION_STATE_DISCONNECTED:
- sink_set_state(dev, SINK_STATE_DISCONNECTED);
+ sink_set_state(dev->sink, SINK_STATE_DISCONNECTED);
break;
case AVDTP_SESSION_STATE_CONNECTING:
- sink_set_state(dev, SINK_STATE_CONNECTING);
+ sink_set_state(dev->sink, SINK_STATE_CONNECTING);
break;
case AVDTP_SESSION_STATE_CONNECTED:
break;
@@ -141,8 +142,8 @@ static void stream_state_changed(struct avdtp_stream *stream,
struct avdtp_error *err,
void *user_data)
{
- struct audio_device *dev = user_data;
- struct sink *sink = btd_service_get_user_data(dev->sink);
+ struct btd_service *service = user_data;
+ struct sink *sink = btd_service_get_user_data(service);

if (err)
return;
@@ -152,7 +153,7 @@ static void stream_state_changed(struct avdtp_stream *stream,
btd_service_disconnecting_complete(sink->service, 0);

if (sink->disconnect_id > 0) {
- a2dp_cancel(dev, sink->disconnect_id);
+ a2dp_cancel(sink->dev, sink->disconnect_id);
sink->disconnect_id = 0;
}

@@ -164,10 +165,10 @@ static void stream_state_changed(struct avdtp_stream *stream,
sink->cb_id = 0;
break;
case AVDTP_STATE_OPEN:
- sink_set_state(dev, SINK_STATE_CONNECTED);
+ sink_set_state(service, SINK_STATE_CONNECTED);
break;
case AVDTP_STATE_STREAMING:
- sink_set_state(dev, SINK_STATE_PLAYING);
+ sink_set_state(service, SINK_STATE_PLAYING);
break;
case AVDTP_STATE_CONFIGURED:
case AVDTP_STATE_CLOSING:
@@ -291,9 +292,9 @@ failed:
sink->session = NULL;
}

-gboolean sink_setup_stream(struct audio_device *dev, struct avdtp *session)
+gboolean sink_setup_stream(struct btd_service *service, struct avdtp *session)
{
- struct sink *sink = btd_service_get_user_data(dev->sink);
+ struct sink *sink = btd_service_get_user_data(service);

if (sink->connect_id > 0 || sink->disconnect_id > 0)
return FALSE;
@@ -310,12 +311,12 @@ gboolean sink_setup_stream(struct audio_device *dev, struct avdtp *session)
return TRUE;
}

-int sink_connect(struct audio_device *dev)
+int sink_connect(struct btd_service *service)
{
- struct sink *sink = btd_service_get_user_data(dev->sink);
+ struct sink *sink = btd_service_get_user_data(service);

if (!sink->session)
- sink->session = avdtp_get(dev);
+ sink->session = avdtp_get(sink->dev);

if (!sink->session) {
DBG("Unable to get a session");
@@ -328,7 +329,7 @@ int sink_connect(struct audio_device *dev)
if (sink->stream_state >= AVDTP_STATE_OPEN)
return -EALREADY;

- if (!sink_setup_stream(dev, NULL)) {
+ if (!sink_setup_stream(service, NULL)) {
DBG("Failed to create a stream");
return -EIO;
}
@@ -338,9 +339,10 @@ int sink_connect(struct audio_device *dev)
return 0;
}

-static void sink_free(struct audio_device *dev)
+static void sink_free(struct btd_service *service)
{
- struct sink *sink = btd_service_get_user_data(dev->sink);
+ struct sink *sink = btd_service_get_user_data(service);
+ struct audio_device *dev = sink->dev;

if (sink->cb_id)
avdtp_stream_remove_cb(sink->session, sink->stream,
@@ -371,10 +373,13 @@ static void sink_free(struct audio_device *dev)
dev->sink = NULL;
}

-void sink_unregister(struct audio_device *dev)
+void sink_unregister(struct btd_service *service)
{
- DBG("%s", device_get_path(dev->btd_dev));
- sink_free(dev);
+ struct btd_device *dev = btd_service_get_device(service);
+
+ DBG("%s", device_get_path(dev));
+
+ sink_free(service);
}

struct btd_service *sink_init(struct audio_device *dev,
@@ -396,9 +401,9 @@ struct btd_service *sink_init(struct audio_device *dev,
return service;
}

-gboolean sink_is_active(struct audio_device *dev)
+gboolean sink_is_active(struct btd_service *service)
{
- struct sink *sink = btd_service_get_user_data(dev->sink);
+ struct sink *sink = btd_service_get_user_data(service);

if (sink->session)
return TRUE;
@@ -406,10 +411,10 @@ gboolean sink_is_active(struct audio_device *dev)
return FALSE;
}

-gboolean sink_new_stream(struct audio_device *dev, struct avdtp *session,
+gboolean sink_new_stream(struct btd_service *service, struct avdtp *session,
struct avdtp_stream *stream)
{
- struct sink *sink = btd_service_get_user_data(dev->sink);
+ struct sink *sink = btd_service_get_user_data(service);

if (sink->stream)
return FALSE;
@@ -420,14 +425,15 @@ gboolean sink_new_stream(struct audio_device *dev, struct avdtp *session,
sink->stream = stream;

sink->cb_id = avdtp_stream_add_cb(session, stream,
- stream_state_changed, dev);
+ stream_state_changed, service);

return TRUE;
}

-int sink_disconnect(struct audio_device *dev, gboolean shutdown)
+int sink_disconnect(struct btd_service *service, gboolean shutdown)
{
- struct sink *sink = btd_service_get_user_data(dev->sink);
+ struct sink *sink = btd_service_get_user_data(service);
+ struct audio_device *dev = sink->dev;

if (!sink->session)
return -ENOTCONN;
@@ -457,7 +463,7 @@ int sink_disconnect(struct audio_device *dev, gboolean shutdown)
return avdtp_close(sink->session, sink->stream, FALSE);
}

-unsigned int sink_add_state_cb(struct audio_device *dev, sink_state_cb cb,
+unsigned int sink_add_state_cb(struct btd_service *service, sink_state_cb cb,
void *user_data)
{
struct sink_state_callback *state_cb;
@@ -465,7 +471,7 @@ unsigned int sink_add_state_cb(struct audio_device *dev, sink_state_cb cb,

state_cb = g_new(struct sink_state_callback, 1);
state_cb->cb = cb;
- state_cb->dev = dev;
+ state_cb->service = service;
state_cb->user_data = user_data;
state_cb->id = ++id;

diff --git a/profiles/audio/sink.h b/profiles/audio/sink.h
index e3f974b..b25089a 100644
--- a/profiles/audio/sink.h
+++ b/profiles/audio/sink.h
@@ -29,23 +29,23 @@ typedef enum {
SINK_STATE_PLAYING,
} sink_state_t;

-typedef void (*sink_state_cb) (struct audio_device *dev,
+typedef void (*sink_state_cb) (struct btd_service *service,
sink_state_t old_state,
sink_state_t new_state,
void *user_data);

struct btd_service;

-unsigned int sink_add_state_cb(struct audio_device *dev, sink_state_cb cb,
+unsigned int sink_add_state_cb(struct btd_service *service, sink_state_cb cb,
void *user_data);
gboolean sink_remove_state_cb(unsigned int id);

struct btd_service *sink_init(struct audio_device *dev,
struct btd_service *service);
-void sink_unregister(struct audio_device *dev);
-gboolean sink_is_active(struct audio_device *dev);
-int sink_connect(struct audio_device *dev);
-gboolean sink_new_stream(struct audio_device *dev, struct avdtp *session,
+void sink_unregister(struct btd_service *service);
+gboolean sink_is_active(struct btd_service *service);
+int sink_connect(struct btd_service *service);
+gboolean sink_new_stream(struct btd_service *service, struct avdtp *session,
struct avdtp_stream *stream);
-gboolean sink_setup_stream(struct audio_device *dev, struct avdtp *session);
-int sink_disconnect(struct audio_device *dev, gboolean shutdown);
+gboolean sink_setup_stream(struct btd_service *service, struct avdtp *session);
+int sink_disconnect(struct btd_service *service, gboolean shutdown);
diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
index f585c3a..3e83a95 100644
--- a/profiles/audio/transport.c
+++ b/profiles/audio/transport.c
@@ -744,7 +744,7 @@ static void transport_update_playing(struct media_transport *transport,
transport_set_state(transport, TRANSPORT_STATE_PENDING);
}

-static void sink_state_changed(struct audio_device *dev,
+static void sink_state_changed(struct btd_service *service,
sink_state_t old_state,
sink_state_t new_state,
void *user_data)
@@ -804,7 +804,7 @@ struct media_transport *media_transport_create(struct audio_device *device,

if (strcasecmp(uuid, A2DP_SOURCE_UUID) == 0) {
a2dp->volume = -1;
- transport->sink_watch = sink_add_state_cb(device,
+ transport->sink_watch = sink_add_state_cb(device->sink,
sink_state_changed,
transport);
} else {
--
1.8.1.4


2013-07-03 15:15:22

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [RFC 01/20] audio/sink: Use service user_data for private data

From: Luiz Augusto von Dentz <[email protected]>

This remove the need of forward declaration of struct sink and prepare
for a complete removal of struct audio_device.
---
profiles/audio/avdtp.c | 2 +-
profiles/audio/device.c | 54 ++++++++++++++++++++++++++++++-------------------
profiles/audio/device.h | 3 +--
profiles/audio/sink.c | 29 +++++++++++++++-----------
profiles/audio/sink.h | 5 +++--
5 files changed, 55 insertions(+), 38 deletions(-)

diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index bd73572..0d67e67 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -1165,7 +1165,7 @@ static gboolean disconnect_timeout(gpointer user_data)
dev = manager_get_audio_device(session->device, FALSE);

if (dev && dev->sink && stream_setup)
- sink_setup_stream(dev->sink, session);
+ sink_setup_stream(dev, session);
else if (dev && dev->source && stream_setup)
source_setup_stream(dev->source, session);
else
diff --git a/profiles/audio/device.c b/profiles/audio/device.c
index 3fa49ad..f11c728 100644
--- a/profiles/audio/device.c
+++ b/profiles/audio/device.c
@@ -42,10 +42,12 @@
#include <dbus/dbus.h>
#include <gdbus/gdbus.h>

-#include "log.h"
-#include "../src/adapter.h"
-#include "../src/device.h"
+#include "lib/uuid.h"
+#include "src/adapter.h"
+#include "src/device.h"
+#include "src/service.h"

+#include "log.h"
#include "error.h"
#include "dbus-common.h"
#include "device.h"
@@ -61,7 +63,7 @@
#define AVDTP_CONNECT_TIMEOUT_BOOST 1

struct dev_priv {
- sink_state_t sink_state;
+ btd_service_state_t sink_state;
avctp_state_t avctp_state;

guint control_timer;
@@ -69,9 +71,9 @@ struct dev_priv {

gboolean disconnecting;

+ unsigned int service_cb_id;
unsigned int avdtp_callback_id;
unsigned int avctp_callback_id;
- unsigned int sink_callback_id;
};

static void device_free(struct audio_device *dev)
@@ -87,7 +89,7 @@ static void device_free(struct audio_device *dev)

avdtp_remove_state_cb(priv->avdtp_callback_id);
avctp_remove_state_cb(priv->avctp_callback_id);
- sink_remove_state_cb(priv->sink_callback_id);
+ btd_service_remove_state_cb(priv->service_cb_id);

g_free(priv);
}
@@ -138,6 +140,7 @@ static void disconnect_cb(struct btd_device *btd_dev, gboolean removal,
{
struct audio_device *dev = user_data;
struct dev_priv *priv = dev->priv;
+ struct btd_service *sink;

if (priv->disconnecting)
return;
@@ -149,7 +152,8 @@ static void disconnect_cb(struct btd_device *btd_dev, gboolean removal,
if (dev->control && priv->avctp_state != AVCTP_STATE_DISCONNECTED)
avrcp_disconnect(dev);

- if (dev->sink && priv->sink_state != SINK_STATE_DISCONNECTED)
+ sink = btd_device_get_service(btd_dev, A2DP_SINK_UUID);
+ if (sink)
sink_disconnect(dev, TRUE);
else
priv->disconnecting = FALSE;
@@ -171,30 +175,25 @@ static void device_avdtp_cb(struct audio_device *dev, struct avdtp *session,
}

static void device_sink_cb(struct audio_device *dev,
- sink_state_t old_state,
- sink_state_t new_state,
- void *user_data)
+ btd_service_state_t old_state,
+ btd_service_state_t new_state)
{
struct dev_priv *priv = dev->priv;

- if (!dev->sink)
- return;
-
priv->sink_state = new_state;

switch (new_state) {
- case SINK_STATE_DISCONNECTED:
+ case BTD_SERVICE_STATE_UNAVAILABLE:
+ case BTD_SERVICE_STATE_DISCONNECTED:
if (dev->control) {
device_remove_control_timer(dev);
if (priv->avctp_state != AVCTP_STATE_DISCONNECTED)
avrcp_disconnect(dev);
}
break;
- case SINK_STATE_CONNECTING:
- break;
- case SINK_STATE_CONNECTED:
- break;
- case SINK_STATE_PLAYING:
+ case BTD_SERVICE_STATE_CONNECTING:
+ case BTD_SERVICE_STATE_CONNECTED:
+ case BTD_SERVICE_STATE_DISCONNECTING:
break;
}
}
@@ -222,6 +221,20 @@ static void device_avctp_cb(struct audio_device *dev, avctp_state_t old_state,
}
}

+static void service_cb(struct btd_service *service,
+ btd_service_state_t old_state,
+ btd_service_state_t new_state,
+ void *user_data)
+{
+ struct audio_device *dev = user_data;
+
+ if (dev->btd_dev != btd_service_get_device(service))
+ return;
+
+ if (service == dev->sink)
+ device_sink_cb(dev, old_state, new_state);
+}
+
struct audio_device *audio_device_register(struct btd_device *device)
{
struct audio_device *dev;
@@ -236,8 +249,7 @@ struct audio_device *audio_device_register(struct btd_device *device)
dev->priv->dc_id = device_add_disconnect_watch(dev->btd_dev,
disconnect_cb, dev,
NULL);
- dev->priv->sink_callback_id = sink_add_state_cb(dev, device_sink_cb,
- NULL);
+ dev->priv->service_cb_id = btd_service_add_state_cb(service_cb, dev);
dev->priv->avdtp_callback_id = avdtp_add_state_cb(dev, device_avdtp_cb);
dev->priv->avctp_callback_id = avctp_add_state_cb(dev, device_avctp_cb);

diff --git a/profiles/audio/device.h b/profiles/audio/device.h
index 286bcdd..e24bdf9 100644
--- a/profiles/audio/device.h
+++ b/profiles/audio/device.h
@@ -25,13 +25,12 @@
struct audio_device;
struct source;
struct control;
-struct sink;
struct dev_priv;

struct audio_device {
struct btd_device *btd_dev;

- struct sink *sink;
+ struct btd_service *sink;
struct source *source;
struct control *control;

diff --git a/profiles/audio/sink.c b/profiles/audio/sink.c
index 3969417..f5b4e67 100644
--- a/profiles/audio/sink.c
+++ b/profiles/audio/sink.c
@@ -87,7 +87,7 @@ static char *str_state[] = {

static void sink_set_state(struct audio_device *dev, sink_state_t new_state)
{
- struct sink *sink = dev->sink;
+ struct sink *sink = btd_service_get_user_data(dev->sink);
sink_state_t old_state = sink->state;
GSList *l;

@@ -119,7 +119,7 @@ static void avdtp_state_callback(struct audio_device *dev,
avdtp_session_state_t old_state,
avdtp_session_state_t new_state)
{
- struct sink *sink = dev->sink;
+ struct sink *sink = btd_service_get_user_data(dev->sink);

switch (new_state) {
case AVDTP_SESSION_STATE_DISCONNECTED:
@@ -142,7 +142,7 @@ static void stream_state_changed(struct avdtp_stream *stream,
void *user_data)
{
struct audio_device *dev = user_data;
- struct sink *sink = dev->sink;
+ struct sink *sink = btd_service_get_user_data(dev->sink);

if (err)
return;
@@ -291,8 +291,10 @@ failed:
sink->session = NULL;
}

-gboolean sink_setup_stream(struct sink *sink, struct avdtp *session)
+gboolean sink_setup_stream(struct audio_device *dev, struct avdtp *session)
{
+ struct sink *sink = btd_service_get_user_data(dev->sink);
+
if (sink->connect_id > 0 || sink->disconnect_id > 0)
return FALSE;

@@ -310,7 +312,7 @@ gboolean sink_setup_stream(struct sink *sink, struct avdtp *session)

int sink_connect(struct audio_device *dev)
{
- struct sink *sink = dev->sink;
+ struct sink *sink = btd_service_get_user_data(dev->sink);

if (!sink->session)
sink->session = avdtp_get(dev);
@@ -326,7 +328,7 @@ int sink_connect(struct audio_device *dev)
if (sink->stream_state >= AVDTP_STATE_OPEN)
return -EALREADY;

- if (!sink_setup_stream(sink, NULL)) {
+ if (!sink_setup_stream(dev, NULL)) {
DBG("Failed to create a stream");
return -EIO;
}
@@ -338,7 +340,7 @@ int sink_connect(struct audio_device *dev)

static void sink_free(struct audio_device *dev)
{
- struct sink *sink = dev->sink;
+ struct sink *sink = btd_service_get_user_data(dev->sink);

if (sink->cb_id)
avdtp_stream_remove_cb(sink->session, sink->stream,
@@ -375,7 +377,8 @@ void sink_unregister(struct audio_device *dev)
sink_free(dev);
}

-struct sink *sink_init(struct audio_device *dev, struct btd_service *service)
+struct btd_service *sink_init(struct audio_device *dev,
+ struct btd_service *service)
{
struct sink *sink;

@@ -388,12 +391,14 @@ struct sink *sink_init(struct audio_device *dev, struct btd_service *service)

sink->avdtp_callback_id = avdtp_add_state_cb(dev, avdtp_state_callback);

- return sink;
+ btd_service_set_user_data(service, sink);
+
+ return service;
}

gboolean sink_is_active(struct audio_device *dev)
{
- struct sink *sink = dev->sink;
+ struct sink *sink = btd_service_get_user_data(dev->sink);

if (sink->session)
return TRUE;
@@ -404,7 +409,7 @@ gboolean sink_is_active(struct audio_device *dev)
gboolean sink_new_stream(struct audio_device *dev, struct avdtp *session,
struct avdtp_stream *stream)
{
- struct sink *sink = dev->sink;
+ struct sink *sink = btd_service_get_user_data(dev->sink);

if (sink->stream)
return FALSE;
@@ -422,7 +427,7 @@ gboolean sink_new_stream(struct audio_device *dev, struct avdtp *session,

int sink_disconnect(struct audio_device *dev, gboolean shutdown)
{
- struct sink *sink = dev->sink;
+ struct sink *sink = btd_service_get_user_data(dev->sink);

if (!sink->session)
return -ENOTCONN;
diff --git a/profiles/audio/sink.h b/profiles/audio/sink.h
index 1a80756..e3f974b 100644
--- a/profiles/audio/sink.h
+++ b/profiles/audio/sink.h
@@ -40,11 +40,12 @@ unsigned int sink_add_state_cb(struct audio_device *dev, sink_state_cb cb,
void *user_data);
gboolean sink_remove_state_cb(unsigned int id);

-struct sink *sink_init(struct audio_device *dev, struct btd_service *service);
+struct btd_service *sink_init(struct audio_device *dev,
+ struct btd_service *service);
void sink_unregister(struct audio_device *dev);
gboolean sink_is_active(struct audio_device *dev);
int sink_connect(struct audio_device *dev);
gboolean sink_new_stream(struct audio_device *dev, struct avdtp *session,
struct avdtp_stream *stream);
-gboolean sink_setup_stream(struct sink *sink, struct avdtp *session);
+gboolean sink_setup_stream(struct audio_device *dev, struct avdtp *session);
int sink_disconnect(struct audio_device *dev, gboolean shutdown);
--
1.8.1.4