summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2009-04-16 09:59:48 +0300
committerJohan Hedberg <johan.hedberg@nokia.com>2009-04-16 09:59:48 +0300
commitdbfd944d832fbef2fb5ba9a69974697810f36d1a (patch)
treeb6e46b4775f2157f702793f078bc0cf0926075a9
parent1ba4468cc540feda6263c6f981dc88d547032058 (diff)
downloadbluez-dbfd944d832fbef2fb5ba9a69974697810f36d1a.tar.gz
Fix SCO connect attempt tracking
Without this patch bluetothd would segfault if the device is removed while a SCO connect attempt is pending.
-rw-r--r--audio/headset.c14
-rw-r--r--audio/main.c9
2 files changed, 13 insertions, 10 deletions
diff --git a/audio/headset.c b/audio/headset.c
index c8a542148..992668258 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -577,7 +577,6 @@ static void sco_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
sk = g_io_channel_unix_get_fd(chan);
debug("SCO fd=%d", sk);
- hs->sco = g_io_channel_ref(chan);
if (p) {
p->io = NULL;
@@ -623,7 +622,7 @@ static int sco_connect(struct audio_device *dev, headset_stream_cb_t cb,
return -EIO;
}
- g_io_channel_unref(io);
+ hs->sco = io;
headset_set_state(dev, HEADSET_STATE_PLAY_IN_PROGRESS);
@@ -1168,12 +1167,15 @@ static void close_sco(struct audio_device *device)
struct headset *hs = device->headset;
if (hs->sco) {
- g_source_remove(hs->sco_id);
- hs->sco_id = 0;
g_io_channel_shutdown(hs->sco, TRUE, NULL);
g_io_channel_unref(hs->sco);
hs->sco = NULL;
}
+
+ if (hs->sco_id) {
+ g_source_remove(hs->sco_id);
+ hs->sco_id = 0;
+ }
}
static gboolean rfcomm_io_cb(GIOChannel *chan, GIOCondition cond,
@@ -2228,7 +2230,7 @@ unsigned int headset_request_stream(struct audio_device *dev,
struct headset *hs = dev->headset;
unsigned int id;
- if (hs->rfcomm && hs->sco) {
+ if (hs->state == HEADSET_STATE_PLAYING) {
id = connect_cb_new(hs, HEADSET_STATE_PLAYING, cb, user_data);
g_idle_add((GSourceFunc) dummy_connect_complete, dev);
return id;
@@ -2247,7 +2249,7 @@ unsigned int headset_request_stream(struct audio_device *dev,
if (rfcomm_connect(dev, cb, user_data, &id) < 0)
return 0;
hs->auto_dc = TRUE;
- } else {
+ } else if (hs->sco == NULL) {
if (sco_connect(dev, cb, user_data, &id) < 0)
return 0;
}
diff --git a/audio/main.c b/audio/main.c
index 5b891ff96..565c83be7 100644
--- a/audio/main.c
+++ b/audio/main.c
@@ -107,10 +107,11 @@ static void sco_server_cb(GIOChannel *chan, GError *err, gpointer data)
sk = g_io_channel_unix_get_fd(chan);
fcntl(sk, F_SETFL, 0);
- if (headset_connect_sco(device, chan) == 0) {
- debug("Accepted SCO connection from %s", addr);
- headset_set_state(device, HEADSET_STATE_PLAYING);
- }
+ if (headset_connect_sco(device, chan) < 0)
+ goto drop;
+
+ debug("Accepted SCO connection from %s", addr);
+ headset_set_state(device, HEADSET_STATE_PLAYING);
return;