* [PATCH BlueZ v2 1/6] audio: Fix gateway state check
2012-04-30 8:56 [PATCH BlueZ v2 0/6] Multiple Bluetooth SCO connections (userspace) Mikel Astiz
@ 2012-04-30 8:56 ` Mikel Astiz
2012-04-30 8:56 ` [PATCH BlueZ v2 2/6] audio: Add multiple device search to manager Mikel Astiz
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Mikel Astiz @ 2012-04-30 8:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Mikel Astiz
From: Mikel Astiz <mikel.astiz@bmw-carit.de>
Gateway should be considered active also if connecting or playing.
This could for example lead to manager_find_device() not returning a
device that is connecting, and thus the corresponding endpoint would
never be created in the Media API.
---
audio/device.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/audio/device.c b/audio/device.c
index a9d35f9..ee1ade1 100644
--- a/audio/device.c
+++ b/audio/device.c
@@ -701,7 +701,7 @@ gboolean audio_device_is_active(struct audio_device *dev,
control_is_active(dev))
return TRUE;
else if (!strcmp(interface, AUDIO_GATEWAY_INTERFACE) && dev->gateway &&
- gateway_is_connected(dev))
+ gateway_is_active(dev))
return TRUE;
return FALSE;
--
1.7.7.6
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH BlueZ v2 2/6] audio: Add multiple device search to manager
2012-04-30 8:56 [PATCH BlueZ v2 0/6] Multiple Bluetooth SCO connections (userspace) Mikel Astiz
2012-04-30 8:56 ` [PATCH BlueZ v2 1/6] audio: Fix gateway state check Mikel Astiz
@ 2012-04-30 8:56 ` Mikel Astiz
2012-05-02 18:25 ` Vinicius Costa Gomes
2012-04-30 8:56 ` [PATCH BlueZ v2 3/6] media: Support multiple transports per endpoint Mikel Astiz
` (3 subsequent siblings)
5 siblings, 1 reply; 9+ messages in thread
From: Mikel Astiz @ 2012-04-30 8:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Mikel Astiz
From: Mikel Astiz <mikel.astiz@bmw-carit.de>
This method is useful to search or than one device fulfulling certain
criteria.
---
audio/manager.c | 25 ++++++++++++++++++++++---
audio/manager.h | 6 ++++++
2 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/audio/manager.c b/audio/manager.c
index 20453e6..9c7d0d3 100644
--- a/audio/manager.c
+++ b/audio/manager.c
@@ -1300,12 +1300,13 @@ void audio_manager_exit(void)
btd_unregister_device_driver(&audio_driver);
}
-struct audio_device *manager_find_device(const char *path,
+GSList *manager_find_devices(const char *path,
const bdaddr_t *src,
const bdaddr_t *dst,
const char *interface,
gboolean connected)
{
+ GSList *result = NULL;
GSList *l;
for (l = devices; l != NULL; l = l->next) {
@@ -1343,10 +1344,28 @@ struct audio_device *manager_find_device(const char *path,
if (connected && !audio_device_is_active(dev, interface))
continue;
- return dev;
+ result = g_slist_append(result, dev);
}
- return NULL;
+ return result;
+}
+
+struct audio_device *manager_find_device(const char *path,
+ const bdaddr_t *src,
+ const bdaddr_t *dst,
+ const char *interface,
+ gboolean connected)
+{
+ struct audio_device *result;
+ GSList *l;
+
+ l = manager_find_devices(path, src, dst, interface, connected);
+ if (l == NULL)
+ return NULL;
+
+ result = l->data;
+ g_slist_free(l);
+ return result;
}
struct audio_device *manager_get_device(const bdaddr_t *src,
diff --git a/audio/manager.h b/audio/manager.h
index cfc646c..f1d3021 100644
--- a/audio/manager.h
+++ b/audio/manager.h
@@ -46,6 +46,12 @@ struct audio_device *manager_find_device(const char *path,
const char *interface,
gboolean connected);
+GSList *manager_find_devices(const char *path,
+ const bdaddr_t *src,
+ const bdaddr_t *dst,
+ const char *interface,
+ gboolean connected);
+
struct audio_device *manager_get_device(const bdaddr_t *src,
const bdaddr_t *dst,
gboolean create);
--
1.7.7.6
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH BlueZ v2 2/6] audio: Add multiple device search to manager
2012-04-30 8:56 ` [PATCH BlueZ v2 2/6] audio: Add multiple device search to manager Mikel Astiz
@ 2012-05-02 18:25 ` Vinicius Costa Gomes
0 siblings, 0 replies; 9+ messages in thread
From: Vinicius Costa Gomes @ 2012-05-02 18:25 UTC (permalink / raw)
To: Mikel Astiz; +Cc: linux-bluetooth, Mikel Astiz
Hi Mikel,
On 10:56 Mon 30 Apr, Mikel Astiz wrote:
> From: Mikel Astiz <mikel.astiz@bmw-carit.de>
>
> This method is useful to search or than one device fulfulling certain
I guess you meant "for more than one".
Other than this nitpick the patch looks good.
> criteria.
> ---
> audio/manager.c | 25 ++++++++++++++++++++++---
> audio/manager.h | 6 ++++++
> 2 files changed, 28 insertions(+), 3 deletions(-)
>
> diff --git a/audio/manager.c b/audio/manager.c
> index 20453e6..9c7d0d3 100644
> --- a/audio/manager.c
> +++ b/audio/manager.c
> @@ -1300,12 +1300,13 @@ void audio_manager_exit(void)
> btd_unregister_device_driver(&audio_driver);
> }
>
> -struct audio_device *manager_find_device(const char *path,
> +GSList *manager_find_devices(const char *path,
> const bdaddr_t *src,
> const bdaddr_t *dst,
> const char *interface,
> gboolean connected)
> {
> + GSList *result = NULL;
> GSList *l;
>
> for (l = devices; l != NULL; l = l->next) {
> @@ -1343,10 +1344,28 @@ struct audio_device *manager_find_device(const char *path,
> if (connected && !audio_device_is_active(dev, interface))
> continue;
>
> - return dev;
> + result = g_slist_append(result, dev);
> }
>
> - return NULL;
> + return result;
> +}
> +
> +struct audio_device *manager_find_device(const char *path,
> + const bdaddr_t *src,
> + const bdaddr_t *dst,
> + const char *interface,
> + gboolean connected)
> +{
> + struct audio_device *result;
> + GSList *l;
> +
> + l = manager_find_devices(path, src, dst, interface, connected);
> + if (l == NULL)
> + return NULL;
> +
> + result = l->data;
> + g_slist_free(l);
> + return result;
> }
>
> struct audio_device *manager_get_device(const bdaddr_t *src,
> diff --git a/audio/manager.h b/audio/manager.h
> index cfc646c..f1d3021 100644
> --- a/audio/manager.h
> +++ b/audio/manager.h
> @@ -46,6 +46,12 @@ struct audio_device *manager_find_device(const char *path,
> const char *interface,
> gboolean connected);
>
> +GSList *manager_find_devices(const char *path,
> + const bdaddr_t *src,
> + const bdaddr_t *dst,
> + const char *interface,
> + gboolean connected);
> +
> struct audio_device *manager_get_device(const bdaddr_t *src,
> const bdaddr_t *dst,
> gboolean create);
> --
> 1.7.7.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Cheers,
--
Vinicius
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH BlueZ v2 3/6] media: Support multiple transports per endpoint
2012-04-30 8:56 [PATCH BlueZ v2 0/6] Multiple Bluetooth SCO connections (userspace) Mikel Astiz
2012-04-30 8:56 ` [PATCH BlueZ v2 1/6] audio: Fix gateway state check Mikel Astiz
2012-04-30 8:56 ` [PATCH BlueZ v2 2/6] audio: Add multiple device search to manager Mikel Astiz
@ 2012-04-30 8:56 ` Mikel Astiz
2012-04-30 8:56 ` [PATCH BlueZ v2 4/6] media: Split media_endpoint_create Mikel Astiz
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Mikel Astiz @ 2012-04-30 8:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Mikel Astiz
From: Mikel Astiz <mikel.astiz@bmw-carit.de>
Several transports may exist for each endpoint, for example if several
HFGW are connected. This should be exposed to the endpoint as one
transport each.
---
audio/media.c | 98 +++++++++++++++++++++++++++++++++++++-------------------
1 files changed, 65 insertions(+), 33 deletions(-)
diff --git a/audio/media.c b/audio/media.c
index c0fd0c3..fd5a369 100644
--- a/audio/media.c
+++ b/audio/media.c
@@ -86,8 +86,8 @@ struct media_endpoint {
guint ag_watch;
guint watch;
struct endpoint_request *request;
- struct media_transport *transport;
struct media_adapter *adapter;
+ GSList *transports;
};
struct media_player {
@@ -153,8 +153,8 @@ static void media_endpoint_destroy(struct media_endpoint *endpoint)
if (endpoint->request)
media_endpoint_cancel(endpoint);
- if (endpoint->transport)
- media_transport_destroy(endpoint->transport);
+ g_slist_free_full(endpoint->transports,
+ (GDestroyNotify) media_transport_destroy);
g_dbus_remove_watch(adapter->conn, endpoint->watch);
g_free(endpoint->capabilities);
@@ -200,18 +200,12 @@ static void headset_setconf_cb(struct media_endpoint *endpoint, void *ret,
headset_shutdown(dev);
}
-static void clear_configuration(struct media_endpoint *endpoint)
+static void clear_configuration(struct media_endpoint *endpoint,
+ struct media_transport *transport)
{
DBusConnection *conn;
DBusMessage *msg;
const char *path;
- struct media_transport *transport = endpoint->transport;
-
- if (endpoint->transport == NULL)
- return;
-
- if (endpoint->request)
- media_endpoint_cancel(endpoint);
conn = endpoint->adapter->conn;
@@ -223,15 +217,24 @@ static void clear_configuration(struct media_endpoint *endpoint)
goto done;
}
- path = media_transport_get_path(endpoint->transport);
+ path = media_transport_get_path(transport);
dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID);
g_dbus_send_message(conn, msg);
done:
- endpoint->transport = NULL;
+ endpoint->transports = g_slist_remove(endpoint->transports, transport);
media_transport_destroy(transport);
}
+static void clear_endpoint(struct media_endpoint *endpoint)
+{
+ if (endpoint->request)
+ media_endpoint_cancel(endpoint);
+
+ while (endpoint->transports != NULL)
+ clear_configuration(endpoint, endpoint->transports->data);
+}
+
static void endpoint_reply(DBusPendingCall *call, void *user_data)
{
struct media_endpoint *endpoint = user_data;
@@ -256,7 +259,7 @@ static void endpoint_reply(DBusPendingCall *call, void *user_data)
if (request->cb)
request->cb(endpoint, NULL, size,
request->user_data);
- clear_configuration(endpoint);
+ clear_endpoint(endpoint);
dbus_message_unref(reply);
dbus_error_free(&err);
return;
@@ -369,6 +372,31 @@ static gboolean select_configuration(struct media_endpoint *endpoint,
destroy);
}
+static gint transport_device_cmp(gconstpointer data, gconstpointer user_data)
+{
+ struct media_transport *transport = (struct media_transport *) data;
+ const struct audio_device *device = user_data;
+
+ if (device == media_transport_get_dev(transport))
+ return 0;
+
+ return -1;
+}
+
+static struct media_transport *find_device_transport(
+ struct media_endpoint *endpoint,
+ struct audio_device *device)
+{
+ GSList *match;
+
+ match = g_slist_find_custom(endpoint->transports, device,
+ transport_device_cmp);
+ if (match == NULL)
+ return NULL;
+
+ return match->data;
+}
+
static gboolean set_configuration(struct media_endpoint *endpoint,
struct audio_device *device,
uint8_t *configuration, size_t size,
@@ -380,15 +408,18 @@ static gboolean set_configuration(struct media_endpoint *endpoint,
DBusMessage *msg;
const char *path;
DBusMessageIter iter;
+ struct media_transport *transport;
+
+ transport = find_device_transport(endpoint, device);
- if (endpoint->transport != NULL || endpoint->request != NULL)
+ if (transport != NULL || endpoint->request != NULL)
return FALSE;
conn = endpoint->adapter->conn;
- endpoint->transport = media_transport_create(conn, endpoint, device,
+ transport = media_transport_create(conn, endpoint, device,
configuration, size);
- if (endpoint->transport == NULL)
+ if (transport == NULL)
return FALSE;
msg = dbus_message_new_method_call(endpoint->sender, endpoint->path,
@@ -396,15 +427,18 @@ static gboolean set_configuration(struct media_endpoint *endpoint,
"SetConfiguration");
if (msg == NULL) {
error("Couldn't allocate D-Bus message");
+ media_transport_destroy(transport);
return FALSE;
}
+ endpoint->transports = g_slist_append(endpoint->transports, transport);
+
dbus_message_iter_init_append(msg, &iter);
- path = media_transport_get_path(endpoint->transport);
+ path = media_transport_get_path(transport);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &path);
- transport_get_properties(endpoint->transport, &iter);
+ transport_get_properties(transport, &iter);
return media_endpoint_async_call(conn, msg, endpoint, cb, user_data,
destroy);
@@ -440,16 +474,17 @@ static void headset_state_changed(struct audio_device *dev,
void *user_data)
{
struct media_endpoint *endpoint = user_data;
+ struct media_transport *transport;
DBG("");
switch (new_state) {
case HEADSET_STATE_DISCONNECTED:
- if (endpoint->transport &&
- media_transport_get_dev(endpoint->transport) == dev) {
+ transport = find_device_transport(endpoint, dev);
+ if (transport != NULL) {
DBG("Clear endpoint %p", endpoint);
- clear_configuration(endpoint);
+ clear_configuration(endpoint, transport);
}
break;
case HEADSET_STATE_CONNECTING:
@@ -551,17 +586,17 @@ static void clear_config(struct a2dp_sep *sep, void *user_data)
{
struct media_endpoint *endpoint = user_data;
- clear_configuration(endpoint);
+ clear_endpoint(endpoint);
}
static void set_delay(struct a2dp_sep *sep, uint16_t delay, void *user_data)
{
struct media_endpoint *endpoint = user_data;
- if (endpoint->transport == NULL)
+ if (endpoint->transports == NULL)
return;
- media_transport_update_delay(endpoint->transport, delay);
+ media_transport_update_delay(endpoint->transports->data, delay);
}
static struct a2dp_endpoint a2dp_endpoint = {
@@ -577,10 +612,7 @@ static void a2dp_destroy_endpoint(void *user_data)
{
struct media_endpoint *endpoint = user_data;
- if (endpoint->transport) {
- media_transport_destroy(endpoint->transport);
- endpoint->transport = NULL;
- }
+ clear_endpoint(endpoint);
endpoint->sep = NULL;
release_endpoint(endpoint);
@@ -603,16 +635,16 @@ static void gateway_state_changed(struct audio_device *dev,
void *user_data)
{
struct media_endpoint *endpoint = user_data;
+ struct media_transport *transport;
DBG("");
switch (new_state) {
case GATEWAY_STATE_DISCONNECTED:
- if (endpoint->transport &&
- media_transport_get_dev(endpoint->transport) == dev) {
-
+ transport = find_device_transport(endpoint, dev);
+ if (transport != NULL) {
DBG("Clear endpoint %p", endpoint);
- clear_configuration(endpoint);
+ clear_configuration(endpoint, transport);
}
break;
case GATEWAY_STATE_CONNECTING:
--
1.7.7.6
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH BlueZ v2 4/6] media: Split media_endpoint_create
2012-04-30 8:56 [PATCH BlueZ v2 0/6] Multiple Bluetooth SCO connections (userspace) Mikel Astiz
` (2 preceding siblings ...)
2012-04-30 8:56 ` [PATCH BlueZ v2 3/6] media: Support multiple transports per endpoint Mikel Astiz
@ 2012-04-30 8:56 ` Mikel Astiz
2012-05-02 12:21 ` Luiz Augusto von Dentz
2012-04-30 8:56 ` [PATCH BlueZ v2 5/6] media: Create multiple transports if needed Mikel Astiz
2012-04-30 8:56 ` [PATCH BlueZ v2 6/6] media: Enable parallel requests to endpoint Mikel Astiz
5 siblings, 1 reply; 9+ messages in thread
From: Mikel Astiz @ 2012-04-30 8:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Mikel Astiz
This function is starting to be too long and needs to be split.
After this patch, the resulting code should be exactly equivalent as the
previous implementation.
---
audio/media.c | 119 +++++++++++++++++++++++++++++++++++++-------------------
1 files changed, 78 insertions(+), 41 deletions(-)
diff --git a/audio/media.c b/audio/media.c
index fd5a369..88b994f 100644
--- a/audio/media.c
+++ b/audio/media.c
@@ -658,6 +658,64 @@ static void gateway_state_changed(struct audio_device *dev,
}
}
+static gboolean endpoint_init_a2dp_source(struct media_endpoint *endpoint,
+ gboolean delay_reporting,
+ int *err)
+{
+ endpoint->sep = a2dp_add_sep(&endpoint->adapter->src,
+ AVDTP_SEP_TYPE_SOURCE, endpoint->codec,
+ delay_reporting, &a2dp_endpoint,
+ endpoint, a2dp_destroy_endpoint, err);
+ if (endpoint->sep == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean endpoint_init_a2dp_sink(struct media_endpoint *endpoint,
+ gboolean delay_reporting,
+ int *err)
+{
+ endpoint->sep = a2dp_add_sep(&endpoint->adapter->src,
+ AVDTP_SEP_TYPE_SINK, endpoint->codec,
+ delay_reporting, &a2dp_endpoint,
+ endpoint, a2dp_destroy_endpoint, err);
+ if (endpoint->sep == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean endpoint_init_ag(struct media_endpoint *endpoint, int *err)
+{
+ struct audio_device *dev;
+
+ endpoint->hs_watch = headset_add_state_cb(headset_state_changed,
+ endpoint);
+ dev = manager_find_device(NULL, &endpoint->adapter->src, BDADDR_ANY,
+ AUDIO_HEADSET_INTERFACE, TRUE);
+ if (dev)
+ set_configuration(endpoint, dev, NULL, 0,
+ headset_setconf_cb, dev, NULL);
+
+ return TRUE;
+}
+
+static gboolean endpoint_init_hs(struct media_endpoint *endpoint, int *err)
+{
+ struct audio_device *dev;
+
+ endpoint->ag_watch = gateway_add_state_cb(gateway_state_changed,
+ endpoint);
+ dev = manager_find_device(NULL, &endpoint->adapter->src, BDADDR_ANY,
+ AUDIO_GATEWAY_INTERFACE, TRUE);
+ if (dev)
+ set_configuration(endpoint, dev, NULL, 0,
+ gateway_setconf_cb, dev, NULL);
+
+ return TRUE;
+}
+
static struct media_endpoint *media_endpoint_create(struct media_adapter *adapter,
const char *sender,
const char *path,
@@ -669,6 +727,7 @@ static struct media_endpoint *media_endpoint_create(struct media_adapter *adapte
int *err)
{
struct media_endpoint *endpoint;
+ gboolean succeeded;
endpoint = g_new0(struct media_endpoint, 1);
endpoint->sender = g_strdup(sender);
@@ -684,46 +743,28 @@ static struct media_endpoint *media_endpoint_create(struct media_adapter *adapte
endpoint->adapter = adapter;
- if (strcasecmp(uuid, A2DP_SOURCE_UUID) == 0) {
- endpoint->sep = a2dp_add_sep(&adapter->src,
- AVDTP_SEP_TYPE_SOURCE, codec,
- delay_reporting, &a2dp_endpoint,
- endpoint, a2dp_destroy_endpoint, err);
- if (endpoint->sep == NULL)
- goto failed;
- } else if (strcasecmp(uuid, A2DP_SINK_UUID) == 0) {
- endpoint->sep = a2dp_add_sep(&adapter->src,
- AVDTP_SEP_TYPE_SINK, codec,
- delay_reporting, &a2dp_endpoint,
- endpoint, a2dp_destroy_endpoint, err);
- if (endpoint->sep == NULL)
- goto failed;
- } else if (strcasecmp(uuid, HFP_AG_UUID) == 0 ||
- strcasecmp(uuid, HSP_AG_UUID) == 0) {
- struct audio_device *dev;
-
- endpoint->hs_watch = headset_add_state_cb(headset_state_changed,
- endpoint);
- dev = manager_find_device(NULL, &adapter->src, BDADDR_ANY,
- AUDIO_HEADSET_INTERFACE, TRUE);
- if (dev)
- set_configuration(endpoint, dev, NULL, 0,
- headset_setconf_cb, dev, NULL);
- } else if (strcasecmp(uuid, HFP_HS_UUID) == 0 ||
- strcasecmp(uuid, HSP_HS_UUID) == 0) {
- struct audio_device *dev;
+ if (strcasecmp(uuid, A2DP_SOURCE_UUID) == 0)
+ succeeded = endpoint_init_a2dp_source(endpoint,
+ delay_reporting, err);
+ else if (strcasecmp(uuid, A2DP_SINK_UUID) == 0)
+ succeeded = endpoint_init_a2dp_sink(endpoint,
+ delay_reporting, err);
+ else if (strcasecmp(uuid, HFP_AG_UUID) == 0 ||
+ strcasecmp(uuid, HSP_AG_UUID) == 0)
+ succeeded = endpoint_init_ag(endpoint, err);
+ else if (strcasecmp(uuid, HFP_HS_UUID) == 0 ||
+ strcasecmp(uuid, HSP_HS_UUID) == 0)
+ succeeded = endpoint_init_hs(endpoint, err);
+ else {
+ succeeded = FALSE;
- endpoint->ag_watch = gateway_add_state_cb(gateway_state_changed,
- endpoint);
- dev = manager_find_device(NULL, &adapter->src, BDADDR_ANY,
- AUDIO_GATEWAY_INTERFACE, TRUE);
- if (dev)
- set_configuration(endpoint, dev, NULL, 0,
- gateway_setconf_cb, dev, NULL);
- } else {
if (err)
*err = -EINVAL;
- goto failed;
+ }
+
+ if (!succeeded) {
+ g_free(endpoint);
+ return NULL;
}
endpoint->watch = g_dbus_add_disconnect_watch(adapter->conn, sender,
@@ -736,10 +777,6 @@ static struct media_endpoint *media_endpoint_create(struct media_adapter *adapte
if (err)
*err = 0;
return endpoint;
-
-failed:
- g_free(endpoint);
- return NULL;
}
static struct media_endpoint *media_adapter_find_endpoint(
--
1.7.7.6
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH BlueZ v2 5/6] media: Create multiple transports if needed
2012-04-30 8:56 [PATCH BlueZ v2 0/6] Multiple Bluetooth SCO connections (userspace) Mikel Astiz
` (3 preceding siblings ...)
2012-04-30 8:56 ` [PATCH BlueZ v2 4/6] media: Split media_endpoint_create Mikel Astiz
@ 2012-04-30 8:56 ` Mikel Astiz
2012-04-30 8:56 ` [PATCH BlueZ v2 6/6] media: Enable parallel requests to endpoint Mikel Astiz
5 siblings, 0 replies; 9+ messages in thread
From: Mikel Astiz @ 2012-04-30 8:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Mikel Astiz
From: Mikel Astiz <mikel.astiz@bmw-carit.de>
During endpoint registration one than one device might be connected.
Thus all matching devices should have one transport each.
---
audio/media.c | 26 ++++++++++++++++++++------
1 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/audio/media.c b/audio/media.c
index 88b994f..9c7a103 100644
--- a/audio/media.c
+++ b/audio/media.c
@@ -688,30 +688,44 @@ static gboolean endpoint_init_a2dp_sink(struct media_endpoint *endpoint,
static gboolean endpoint_init_ag(struct media_endpoint *endpoint, int *err)
{
- struct audio_device *dev;
+ GSList *list;
+ GSList *l;
endpoint->hs_watch = headset_add_state_cb(headset_state_changed,
endpoint);
- dev = manager_find_device(NULL, &endpoint->adapter->src, BDADDR_ANY,
+ list = manager_find_devices(NULL, &endpoint->adapter->src, BDADDR_ANY,
AUDIO_HEADSET_INTERFACE, TRUE);
- if (dev)
+
+ for (l = list; l != NULL; l = l->next) {
+ struct audio_device *dev = l->data;
+
set_configuration(endpoint, dev, NULL, 0,
headset_setconf_cb, dev, NULL);
+ }
+
+ g_slist_free(list);
return TRUE;
}
static gboolean endpoint_init_hs(struct media_endpoint *endpoint, int *err)
{
- struct audio_device *dev;
+ GSList *list;
+ GSList *l;
endpoint->ag_watch = gateway_add_state_cb(gateway_state_changed,
endpoint);
- dev = manager_find_device(NULL, &endpoint->adapter->src, BDADDR_ANY,
+ list = manager_find_devices(NULL, &endpoint->adapter->src, BDADDR_ANY,
AUDIO_GATEWAY_INTERFACE, TRUE);
- if (dev)
+
+ for (l = list; l != NULL; l = l->next) {
+ struct audio_device *dev = l->data;
+
set_configuration(endpoint, dev, NULL, 0,
gateway_setconf_cb, dev, NULL);
+ }
+
+ g_slist_free(list);
return TRUE;
}
--
1.7.7.6
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH BlueZ v2 6/6] media: Enable parallel requests to endpoint
2012-04-30 8:56 [PATCH BlueZ v2 0/6] Multiple Bluetooth SCO connections (userspace) Mikel Astiz
` (4 preceding siblings ...)
2012-04-30 8:56 ` [PATCH BlueZ v2 5/6] media: Create multiple transports if needed Mikel Astiz
@ 2012-04-30 8:56 ` Mikel Astiz
5 siblings, 0 replies; 9+ messages in thread
From: Mikel Astiz @ 2012-04-30 8:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Mikel Astiz
From: Mikel Astiz <mikel.astiz@bmw-carit.de>
If endpoint is handling several devices, it should be able to handle
multiple requests, one per each.
---
audio/media.c | 46 ++++++++++++++++++++++++----------------------
1 files changed, 24 insertions(+), 22 deletions(-)
diff --git a/audio/media.c b/audio/media.c
index 9c7a103..61ec153 100644
--- a/audio/media.c
+++ b/audio/media.c
@@ -67,6 +67,7 @@ struct media_adapter {
};
struct endpoint_request {
+ struct media_endpoint *endpoint;
DBusMessage *msg;
DBusPendingCall *call;
media_endpoint_cb_t cb;
@@ -85,7 +86,7 @@ struct media_endpoint {
guint hs_watch;
guint ag_watch;
guint watch;
- struct endpoint_request *request;
+ GSList *requests;
struct media_adapter *adapter;
GSList *transports;
};
@@ -127,15 +128,22 @@ static void endpoint_request_free(struct endpoint_request *request)
g_free(request);
}
-static void media_endpoint_cancel(struct media_endpoint *endpoint)
+static void media_endpoint_cancel(struct endpoint_request *request)
{
- struct endpoint_request *request = endpoint->request;
+ struct media_endpoint *endpoint = request->endpoint;
if (request->call)
dbus_pending_call_cancel(request->call);
+ endpoint->requests = g_slist_remove(endpoint->requests, request);
+
endpoint_request_free(request);
- endpoint->request = NULL;
+}
+
+static void media_endpoint_cancel_all(struct media_endpoint *endpoint)
+{
+ while (endpoint->requests != NULL)
+ media_endpoint_cancel(endpoint->requests->data);
}
static void media_endpoint_destroy(struct media_endpoint *endpoint)
@@ -150,8 +158,7 @@ static void media_endpoint_destroy(struct media_endpoint *endpoint)
if (endpoint->ag_watch)
gateway_remove_state_cb(endpoint->ag_watch);
- if (endpoint->request)
- media_endpoint_cancel(endpoint);
+ media_endpoint_cancel_all(endpoint);
g_slist_free_full(endpoint->transports,
(GDestroyNotify) media_transport_destroy);
@@ -228,8 +235,7 @@ done:
static void clear_endpoint(struct media_endpoint *endpoint)
{
- if (endpoint->request)
- media_endpoint_cancel(endpoint);
+ media_endpoint_cancel_all(endpoint);
while (endpoint->transports != NULL)
clear_configuration(endpoint, endpoint->transports->data);
@@ -237,8 +243,8 @@ static void clear_endpoint(struct media_endpoint *endpoint)
static void endpoint_reply(DBusPendingCall *call, void *user_data)
{
- struct media_endpoint *endpoint = user_data;
- struct endpoint_request *request = endpoint->request;
+ struct endpoint_request *request = user_data;
+ struct media_endpoint *endpoint = request->endpoint;
DBusMessage *reply;
DBusError err;
gboolean value;
@@ -299,9 +305,8 @@ done:
if (request->cb)
request->cb(endpoint, ret, size, request->user_data);
- if (endpoint->request)
- endpoint_request_free(endpoint->request);
- endpoint->request = NULL;
+ endpoint->requests = g_slist_remove(endpoint->requests, request);
+ endpoint_request_free(request);
}
static gboolean media_endpoint_async_call(DBusConnection *conn,
@@ -313,9 +318,6 @@ static gboolean media_endpoint_async_call(DBusConnection *conn,
{
struct endpoint_request *request;
- if (endpoint->request)
- return FALSE;
-
request = g_new0(struct endpoint_request, 1);
/* Timeout should be less than avdtp request timeout (4 seconds) */
@@ -326,13 +328,16 @@ static gboolean media_endpoint_async_call(DBusConnection *conn,
return FALSE;
}
- dbus_pending_call_set_notify(request->call, endpoint_reply, endpoint, NULL);
+ dbus_pending_call_set_notify(request->call, endpoint_reply, request,
+ NULL);
+ request->endpoint = endpoint;
request->msg = msg;
request->cb = cb;
request->destroy = destroy;
request->user_data = user_data;
- endpoint->request = request;
+
+ endpoint->requests = g_slist_append(endpoint->requests, request);
DBG("Calling %s: name = %s path = %s", dbus_message_get_member(msg),
dbus_message_get_destination(msg),
@@ -351,9 +356,6 @@ static gboolean select_configuration(struct media_endpoint *endpoint,
DBusConnection *conn;
DBusMessage *msg;
- if (endpoint->request != NULL)
- return FALSE;
-
conn = endpoint->adapter->conn;
msg = dbus_message_new_method_call(endpoint->sender, endpoint->path,
@@ -412,7 +414,7 @@ static gboolean set_configuration(struct media_endpoint *endpoint,
transport = find_device_transport(endpoint, device);
- if (transport != NULL || endpoint->request != NULL)
+ if (transport != NULL)
return FALSE;
conn = endpoint->adapter->conn;
--
1.7.7.6
^ permalink raw reply related [flat|nested] 9+ messages in thread