summaryrefslogtreecommitdiff
path: root/audio
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2009-03-19 16:16:19 -0300
committerLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2009-03-25 18:56:20 -0300
commitc5e75a5051967530f29f9fabfb8593ef2723d57e (patch)
tree7aaacfce7d767b3a4bb8feef2bd0b6fd1f684190 /audio
parentbd30e5535a6d713727f8f9433954dcb9dd4b7168 (diff)
downloadbluez-c5e75a5051967530f29f9fabfb8593ef2723d57e.tar.gz
Add lock flag for capabilities.
lock flag permits the unix client to detect if there is someone holding the lock so it can prevent useless attempt of setting a new configuration.
Diffstat (limited to 'audio')
-rw-r--r--audio/a2dp.c42
-rw-r--r--audio/a2dp.h3
-rw-r--r--audio/gstavdtpsink.c3
-rw-r--r--audio/headset.c7
-rw-r--r--audio/headset.h1
-rw-r--r--audio/ipc.h4
-rw-r--r--audio/pcm_bluetooth.c3
-rw-r--r--audio/unix.c27
8 files changed, 85 insertions, 5 deletions
diff --git a/audio/a2dp.c b/audio/a2dp.c
index 0a2030f24..7461f17af 100644
--- a/audio/a2dp.c
+++ b/audio/a2dp.c
@@ -1535,3 +1535,45 @@ gboolean a2dp_sep_unlock(struct a2dp_sep *sep, struct avdtp *session)
return TRUE;
}
+gboolean a2dp_sep_get_lock(struct a2dp_sep *sep)
+{
+ return sep->locked;
+}
+
+static int stream_cmp(gconstpointer data, gconstpointer user_data)
+{
+ const struct a2dp_sep *sep = data;
+ const struct avdtp_stream *stream = user_data;
+
+ return (sep->stream != stream);
+}
+
+struct a2dp_sep *a2dp_get_sep(struct avdtp *session,
+ struct avdtp_stream *stream)
+{
+ struct a2dp_server *server;
+ bdaddr_t src, dst;
+ GSList *l;
+
+ avdtp_get_peers(session, &src, &dst);
+
+ for (l = servers; l; l = l->next) {
+ server = l->data;
+
+ if (bacmp(&src, &server->src) == 0)
+ break;
+ }
+
+ if (!l)
+ return NULL;
+
+ l = g_slist_find_custom(server->sources, stream, stream_cmp);
+ if (l)
+ return l->data;
+
+ l = g_slist_find_custom(server->sinks, stream, stream_cmp);
+ if (l)
+ return l->data;
+
+ return NULL;
+}
diff --git a/audio/a2dp.h b/audio/a2dp.h
index cae00d978..0e5f796e4 100644
--- a/audio/a2dp.h
+++ b/audio/a2dp.h
@@ -145,3 +145,6 @@ gboolean a2dp_source_cancel(struct audio_device *dev, 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);
+gboolean a2dp_sep_get_lock(struct a2dp_sep *sep);
+struct a2dp_sep *a2dp_get_sep(struct avdtp *session,
+ struct avdtp_stream *stream);
diff --git a/audio/gstavdtpsink.c b/audio/gstavdtpsink.c
index ec997f232..eb15f0819 100644
--- a/audio/gstavdtpsink.c
+++ b/audio/gstavdtpsink.c
@@ -250,7 +250,8 @@ static codec_capabilities_t *gst_avdtp_find_caps(GstAvdtpSink *sink,
int bytes_left = rsp->h.length - sizeof(*rsp);
while (bytes_left > 0) {
- if (codec->type == codec_type)
+ if ((codec->type == codec_type) &&
+ !(codec->lock & BT_WRITE_LOCK))
break;
bytes_left -= codec->length;
diff --git a/audio/headset.c b/audio/headset.c
index 66bec0859..8f655c242 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -2499,6 +2499,13 @@ gboolean headset_is_active(struct audio_device *dev)
return FALSE;
}
+headset_lock_t headset_get_lock(struct audio_device *dev)
+{
+ struct headset *hs = dev->headset;
+
+ return hs->lock;
+}
+
gboolean headset_lock(struct audio_device *dev, headset_lock_t lock)
{
struct headset *hs = dev->headset;
diff --git a/audio/headset.h b/audio/headset.h
index b0e96e78b..931739d18 100644
--- a/audio/headset.h
+++ b/audio/headset.h
@@ -85,6 +85,7 @@ gboolean headset_get_sco_hci(struct audio_device *dev);
gboolean headset_is_active(struct audio_device *dev);
+headset_lock_t headset_get_lock(struct audio_device *dev);
gboolean headset_lock(struct audio_device *dev, headset_lock_t lock);
gboolean headset_unlock(struct audio_device *dev, headset_lock_t lock);
gboolean headset_suspend(struct audio_device *dev, void *data);
diff --git a/audio/ipc.h b/audio/ipc.h
index 686637b35..a9ef55398 100644
--- a/audio/ipc.h
+++ b/audio/ipc.h
@@ -170,12 +170,16 @@ struct bt_get_capabilities_req {
#define BT_PCM_FLAG_NREC 0x01
#define BT_PCM_FLAG_PCM_ROUTING 0x02
+#define BT_WRITE_LOCK (1 << 1)
+#define BT_READ_LOCK 1
+
typedef struct {
uint8_t seid;
uint8_t transport;
uint8_t type;
uint8_t length;
uint8_t configured;
+ uint8_t lock;
uint8_t data[0];
} __attribute__ ((packed)) codec_capabilities_t;
diff --git a/audio/pcm_bluetooth.c b/audio/pcm_bluetooth.c
index dcdf4df25..2360ae766 100644
--- a/audio/pcm_bluetooth.c
+++ b/audio/pcm_bluetooth.c
@@ -1623,7 +1623,8 @@ static int bluetooth_parse_capabilities(struct bluetooth_data *data,
return 0;
while (bytes_left > 0) {
- if (codec->type == BT_A2DP_CODEC_SBC)
+ if ((codec->type == BT_A2DP_CODEC_SBC) &&
+ !(codec->lock & BT_WRITE_LOCK))
break;
bytes_left -= codec->length;
diff --git a/audio/unix.c b/audio/unix.c
index 25529f268..56bdc189f 100644
--- a/audio/unix.c
+++ b/audio/unix.c
@@ -248,6 +248,8 @@ static uint8_t headset_generate_capability(struct audio_device *dev,
pcm->flags |= BT_PCM_FLAG_NREC;
if (!headset_get_sco_hci(dev))
pcm->flags |= BT_PCM_FLAG_PCM_ROUTING;
+ codec->configured = headset_is_active(dev);
+ codec->lock = headset_get_lock(dev);
return codec->length;
}
@@ -437,7 +439,8 @@ static void print_sbc(struct sbc_codec_cap *sbc)
static int a2dp_append_codec(struct bt_get_capabilities_rsp *rsp,
struct avdtp_service_capability *cap,
uint8_t seid,
- uint8_t configured)
+ uint8_t configured,
+ uint8_t lock)
{
struct avdtp_media_codec_capability *codec_cap = (void *) cap->data;
codec_capabilities_t *codec = (void *) rsp + rsp->h.length;
@@ -501,6 +504,7 @@ static int a2dp_append_codec(struct bt_get_capabilities_rsp *rsp,
codec->seid = seid;
codec->type = codec_cap->media_codec_type;
codec->configured = configured;
+ codec->lock = lock;
rsp->h.length += codec->length;
debug("Append %s seid %d - length %d - total %d",
@@ -540,9 +544,11 @@ static void a2dp_discovery_complete(struct avdtp *session, GSList *seps,
for (l = seps; l; l = g_slist_next(l)) {
struct avdtp_remote_sep *rsep = l->data;
+ struct a2dp_sep *sep;
struct avdtp_service_capability *cap;
struct avdtp_stream *stream;
- uint8_t seid, configured = 0;
+ uint8_t seid, configured = 0, lock = 0;
+ GSList *cl;
cap = avdtp_get_codec(rsep);
@@ -561,7 +567,22 @@ static void a2dp_discovery_complete(struct avdtp *session, GSList *seps,
cap = avdtp_stream_get_codec(stream);
}
- a2dp_append_codec(rsp, cap, seid, configured);
+ for (cl = clients; cl; cl = cl->next) {
+ struct unix_client *c = cl->data;
+ struct a2dp_data *ca2dp = &c->d.a2dp;
+
+ if (ca2dp && ca2dp->session == session &&
+ c->seid == seid) {
+ lock = c->lock;
+ break;
+ }
+ }
+
+ sep = a2dp_get_sep(session, stream);
+ if (sep && a2dp_sep_get_lock(sep))
+ lock = BT_WRITE_LOCK;
+
+ a2dp_append_codec(rsp, cap, seid, configured, lock);
}
unix_ipc_sendmsg(client, &rsp->h);