Diff between 87b332e34c711ab01e9b573f04ae35ec11263619 and f9dddf3f414cc2254a381e35e48c87488765fbc9

Changed Files

File Additions Deletions Status
audio/device.c +8 -1 modified
audio/headset.c +17 -0 modified
audio/headset.h +4 -0 modified
audio/manager.c +1 -0 modified

Full Patch

diff --git a/audio/device.c b/audio/device.c
index 18e873e..1d76a3f 100644
--- a/audio/device.c
+++ b/audio/device.c
@@ -61,6 +61,7 @@
 
 #define CONTROL_CONNECT_TIMEOUT 2
 #define AVDTP_CONNECT_TIMEOUT 1
+#define AVDTP_CONNECT_TIMEOUT_BOOST 1
 #define HEADSET_CONNECT_TIMEOUT 1
 
 typedef enum {
@@ -305,6 +306,7 @@ static gboolean avdtp_connect_timeout(gpointer user_data)
 static gboolean device_set_avdtp_timer(struct audio_device *dev)
 {
 	struct dev_priv *priv = dev->priv;
+	guint timeout = AVDTP_CONNECT_TIMEOUT;
 
 	if (!dev->sink)
 		return FALSE;
@@ -312,7 +314,12 @@ static gboolean device_set_avdtp_timer(struct audio_device *dev)
 	if (priv->avdtp_timer)
 		return FALSE;
 
-	priv->avdtp_timer = g_timeout_add_seconds(AVDTP_CONNECT_TIMEOUT,
+	/* If the headset is the HSP/HFP RFCOMM initiator, give the headset
+	 * time to initiate AVDTP signalling (and avoid further racing) */
+	if (dev->headset && headset_get_rfcomm_initiator(dev))
+		timeout += AVDTP_CONNECT_TIMEOUT_BOOST;
+
+	priv->avdtp_timer = g_timeout_add_seconds(timeout,
 							avdtp_connect_timeout,
 							dev);
 
diff --git a/audio/headset.c b/audio/headset.c
index 8e63afc..b7ad052 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -167,6 +167,7 @@ struct headset {
 
 	gboolean hfp_active;
 	gboolean search_hfp;
+	gboolean rfcomm_initiator;
 
 	headset_state_t state;
 	struct pending_connect *pending;
@@ -1633,6 +1634,7 @@ static int rfcomm_connect(struct audio_device *dev, headset_stream_cb_t cb,
 	}
 
 	hs->hfp_active = hs->hfp_handle != 0 ? TRUE : FALSE;
+	hs->rfcomm_initiator = FALSE;
 
 	headset_set_state(dev, HEADSET_STATE_CONNECTING);
 
@@ -2442,6 +2444,21 @@ void set_hfp_active(struct audio_device *dev, gboolean active)
 	hs->hfp_active = active;
 }
 
+gboolean headset_get_rfcomm_initiator(struct audio_device *dev)
+{
+	struct headset *hs = dev->headset;
+
+	return hs->rfcomm_initiator;
+}
+
+void headset_set_rfcomm_initiator(struct audio_device *dev,
+					gboolean initiator)
+{
+	struct headset *hs = dev->headset;
+
+	hs->rfcomm_initiator = initiator;
+}
+
 GIOChannel *headset_get_rfcomm(struct audio_device *dev)
 {
 	struct headset *hs = dev->headset;
diff --git a/audio/headset.h b/audio/headset.h
index 7ce88c8..8180d69 100644
--- a/audio/headset.h
+++ b/audio/headset.h
@@ -82,6 +82,10 @@ gboolean headset_cancel_stream(struct audio_device *dev, unsigned int id);
 gboolean get_hfp_active(struct audio_device *dev);
 void set_hfp_active(struct audio_device *dev, gboolean active);
 
+gboolean headset_get_rfcomm_initiator(struct audio_device *dev);
+void headset_set_rfcomm_initiator(struct audio_device *dev,
+							gboolean initiator);
+
 void headset_set_authorized(struct audio_device *dev);
 int headset_connect_rfcomm(struct audio_device *dev, GIOChannel *chan);
 int headset_connect_sco(struct audio_device *dev, GIOChannel *io);
diff --git a/audio/manager.c b/audio/manager.c
index 6e583cf..4f654cf 100644
--- a/audio/manager.c
+++ b/audio/manager.c
@@ -511,6 +511,7 @@ static void ag_confirm(GIOChannel *chan, gpointer data)
 	}
 
 	set_hfp_active(device, hfp_active);
+	headset_set_rfcomm_initiator(device, TRUE);
 
 	if (headset_connect_rfcomm(device, chan) < 0) {
 		error("headset_connect_rfcomm failed");