diff options
author | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2009-03-19 16:16:19 -0300 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2009-03-25 18:56:20 -0300 |
commit | c5e75a5051967530f29f9fabfb8593ef2723d57e (patch) | |
tree | 7aaacfce7d767b3a4bb8feef2bd0b6fd1f684190 /audio | |
parent | bd30e5535a6d713727f8f9433954dcb9dd4b7168 (diff) | |
download | bluez-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.c | 42 | ||||
-rw-r--r-- | audio/a2dp.h | 3 | ||||
-rw-r--r-- | audio/gstavdtpsink.c | 3 | ||||
-rw-r--r-- | audio/headset.c | 7 | ||||
-rw-r--r-- | audio/headset.h | 1 | ||||
-rw-r--r-- | audio/ipc.h | 4 | ||||
-rw-r--r-- | audio/pcm_bluetooth.c | 3 | ||||
-rw-r--r-- | audio/unix.c | 27 |
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); |