[PATCH] Close SCO before headset interface state change

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

Attached is a tentative patch proposal, I'm not sure how to make this
modification in a good way.

Maybe the check for G_IO_NVAL in sco_cb should not be removed, but
that is the GIOCondition the callback receives
when shutting down the SCO socket.
It was added in commit
http://git.kernel.org/?p=bluetooth/bluez.git;a=commit;h=6834de18b98fea0e7d370a296318115a659047af

Br,
Daniel
From 608c2d4322fa2a9dbe61f6c97cacd4c73f9d26ef Mon Sep 17 00:00:00 2001
From: Daniel Orstadius <daniel.orstadius@xxxxxxxxx>
Date: Thu, 24 Feb 2011 12:31:34 +0200
Subject: [PATCH] Close SCO before headset interface state change

When the SCO connection is released by the MediaTransport interface,
wait for the SCO callback before entering the
HEADSET_STATE_CONNECTED state.

The reason for the patch is to notify the headset state change on
D-Bus at a later stage in the SCO disconnection process. In case the
user of the Media interface wants to start sending audio over A2DP,
the audio routing switch can be delayed until the D-Bus signal is
received (some headsets have issues if AVDTP Start is sent before
or while the SCO link is being disconnected).
---
 audio/headset.c |   15 ++++++---------
 1 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/audio/headset.c b/audio/headset.c
index bdaa8da..ec6ef08 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -1233,7 +1233,7 @@ static int handle_event(struct audio_device *device, const char *buf)
 	return -EINVAL;
 }
 
-static void close_sco(struct audio_device *device)
+static void close_sco(struct audio_device *device, gboolean remove_callback)
 {
 	struct headset *hs = device->headset;
 
@@ -1245,7 +1245,7 @@ static void close_sco(struct audio_device *device)
 		hs->sco = NULL;
 	}
 
-	if (hs->sco_id) {
+	if (remove_callback && hs->sco_id) {
 		g_source_remove(hs->sco_id);
 		hs->sco_id = 0;
 	}
@@ -1340,9 +1340,6 @@ failed:
 static gboolean sco_cb(GIOChannel *chan, GIOCondition cond,
 			struct audio_device *device)
 {
-	if (cond & G_IO_NVAL)
-		return FALSE;
-
 	error("Audio connection got disconnected");
 
 	headset_set_state(device, HEADSET_STATE_CONNECTED);
@@ -2142,7 +2139,7 @@ static void headset_free(struct audio_device *dev)
 		hs->dc_timer = 0;
 	}
 
-	close_sco(dev);
+	close_sco(dev, TRUE);
 
 	headset_close_rfcomm(dev);
 
@@ -2474,7 +2471,7 @@ void headset_set_state(struct audio_device *dev, headset_state_t state)
 	switch (state) {
 	case HEADSET_STATE_DISCONNECTED:
 		value = FALSE;
-		close_sco(dev);
+		close_sco(dev, TRUE);
 		headset_close_rfcomm(dev);
 		emit_property_changed(dev->conn, dev->path,
 					AUDIO_HEADSET_INTERFACE, "State",
@@ -2497,7 +2494,7 @@ void headset_set_state(struct audio_device *dev, headset_state_t state)
 					DBUS_TYPE_STRING, &state_str);
 		break;
 	case HEADSET_STATE_CONNECTED:
-		close_sco(dev);
+		close_sco(dev, TRUE);
 		if (hs->state != HEADSET_STATE_PLAY_IN_PROGRESS)
 			emit_property_changed(dev->conn, dev->path,
 					AUDIO_HEADSET_INTERFACE, "State",
@@ -2622,7 +2619,7 @@ gboolean headset_unlock(struct audio_device *dev, headset_lock_t lock)
 		return TRUE;
 
 	if (hs->state == HEADSET_STATE_PLAYING)
-		headset_set_state(dev, HEADSET_STATE_CONNECTED);
+		close_sco(dev, FALSE);
 
 	if (hs->auto_dc) {
 		if (hs->state == HEADSET_STATE_CONNECTED)
-- 
1.6.0.4


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux