[PATCH] re-use the sco_server initiated by audio plugin

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

 



From: root <root@xxxxxxxxxxxxxxxxxxxx>

---
 audio/gateway.c |   63 ++++++++++++++++++++++++++++---------------------------
 audio/gateway.h |    6 +++++
 audio/main.c    |   38 ++++++++++++++++++++++----------
 3 files changed, 64 insertions(+), 43 deletions(-)

diff --git a/audio/gateway.c b/audio/gateway.c
index 73e5a12..b49b13f 100644
--- a/audio/gateway.c
+++ b/audio/gateway.c
@@ -101,10 +101,10 @@ struct indicator {
 };
 
 struct gateway {
+	gateway_state_t state;
 	GIOChannel *rfcomm;
 	guint rfcomm_watch_id;
 	GIOChannel *sco;
-	GIOChannel *sco_server;
 	gateway_stream_cb_t sco_start_cb;
 	void *sco_start_cb_data;
 	DBusMessage *connect_message;
@@ -559,32 +559,24 @@ static void rfcomm_connect_cb(GIOChannel *chan, GError *err,
 	gw->rfcomm = chan;
 
 	if (establish_service_level_conn(dev->gateway)) {
-		GIOChannel *sco_server = bt_io_listen(BT_IO_SCO, sco_connect_cb,
-					NULL, dev, NULL, NULL,
-					BT_IO_OPT_SOURCE_BDADDR, &dev->src,
-					BT_IO_OPT_INVALID);
+		gboolean value = TRUE;
 
-		if (sco_server) {
-			gboolean value = TRUE;
-			debug("%s: Connected to %s", dev->path, gw_addr);
-			rfcomm_start_watch(dev);
-			gw->sco_server = sco_server;
-			if (conn_mes) {
-				DBusMessage *reply =
+		debug("%s: Connected to %s", dev->path, gw_addr);
+		rfcomm_start_watch(dev);
+		if (conn_mes) {
+			DBusMessage *reply =
 				dbus_message_new_method_return(conn_mes);
-				dbus_connection_send(dev->conn, reply, NULL);
-				dbus_message_unref(reply);
-				dbus_message_unref(conn_mes);
-				gw->connect_message = NULL;
-			}
+			dbus_connection_send(dev->conn, reply, NULL);
+			dbus_message_unref(reply);
+			dbus_message_unref(conn_mes);
+			gw->connect_message = NULL;
+		}
 
-			emit_property_changed(dev->conn, dev->path,
-					AUDIO_GATEWAY_INTERFACE,
-					"Connected", DBUS_TYPE_BOOLEAN,	&value);
-			return;
-		} else
-			error("%s: Failed to setup SCO server socket",
-						dev->path);
+		gw->state = GATEWAY_STATE_CONNECTED;
+		emit_property_changed(dev->conn, dev->path,
+				AUDIO_GATEWAY_INTERFACE,
+				"Connected", DBUS_TYPE_BOOLEAN,	&value);
+		return;
 	} else
 		error("%s: Failed to establish service layer connection to %s",
 			dev->path, gw_addr);
@@ -1061,13 +1053,15 @@ struct gateway *gateway_init(struct audio_device *dev)
 	gw->indies = NULL;
 	gw->is_dialing = FALSE;
 	gw->call_active = FALSE;
+	gw->state = GATEWAY_STATE_DISCONNECTED;
 	return gw;
 
 }
 
 gboolean gateway_is_connected(struct audio_device *dev)
 {
-	return (dev && dev->gateway && dev->gateway->rfcomm);
+	return (dev && dev->gateway &&
+			dev->gateway->state == GATEWAY_STATE_CONNECTED);
 }
 
 int gateway_connect_rfcomm(struct audio_device *dev, GIOChannel *io)
@@ -1081,6 +1075,18 @@ int gateway_connect_rfcomm(struct audio_device *dev, GIOChannel *io)
 	return 0;
 }
 
+int gateway_connect_sco(struct audio_device *dev, GIOChannel *io)
+{
+	struct gateway *gw = dev->gateway;
+
+	if (gw->sco)
+		return -EISCONN;
+
+	gw->sco = g_io_channel_ref(io);
+
+	return 0;
+}
+
 void gateway_start_service(struct audio_device *device)
 {
 	rfcomm_connect_cb(device->gateway->rfcomm, NULL, device);
@@ -1096,7 +1102,6 @@ int gateway_close(struct audio_device *device)
 	struct gateway *gw = device->gateway;
 	GIOChannel *rfcomm = gw->rfcomm;
 	GIOChannel *sco = gw->sco;
-	GIOChannel *sco_server = gw->sco_server;
 	gboolean value = FALSE;
 
 	g_slist_foreach(gw->indies, (GFunc) indicator_slice_free, NULL);
@@ -1115,11 +1120,7 @@ int gateway_close(struct audio_device *device)
 		gw->sco_start_cb_data = NULL;
 	}
 
-	if (sco_server) {
-		g_io_channel_close(sco_server);
-		g_io_channel_unref(sco_server);
-		gw->sco_server = NULL;
-	}
+	gw->state = GATEWAY_STATE_DISCONNECTED;
 
 	emit_property_changed(device->conn, device->path,
 				AUDIO_GATEWAY_INTERFACE,
diff --git a/audio/gateway.h b/audio/gateway.h
index 7acad46..e539469 100644
--- a/audio/gateway.h
+++ b/audio/gateway.h
@@ -27,10 +27,16 @@
 #define DEFAULT_HSP_HS_CHANNEL 6
 #define DEFAULT_HFP_HS_CHANNEL 7
 
+typedef enum {
+	GATEWAY_STATE_DISCONNECTED,
+	GATEWAY_STATE_CONNECTED
+} gateway_state_t;
+
 typedef void (*gateway_stream_cb_t) (struct audio_device *dev, void *user_data);
 struct gateway *gateway_init(struct audio_device *device);
 gboolean gateway_is_connected(struct audio_device *dev);
 int gateway_connect_rfcomm(struct audio_device *dev, GIOChannel *chan);
+int gateway_connect_sco(struct audio_device *dev, GIOChannel *chan);
 void gateway_start_service(struct audio_device *device);
 gboolean gateway_request_stream(struct audio_device *dev,
 			gateway_stream_cb_t cb, void *user_data);
diff --git a/audio/main.c b/audio/main.c
index 565c83b..7911697 100644
--- a/audio/main.c
+++ b/audio/main.c
@@ -45,6 +45,7 @@
 #include "unix.h"
 #include "headset.h"
 #include "manager.h"
+#include "gateway.h"
 
 static GIOChannel *sco_server = NULL;
 
@@ -94,24 +95,37 @@ static void sco_server_cb(GIOChannel *chan, GError *err, gpointer data)
 	if (!device)
 		goto drop;
 
-	if (headset_get_state(device) < HEADSET_STATE_CONNECTED) {
-		debug("Refusing SCO from non-connected headset");
+	if (device->headset) {
+		if (headset_get_state(device) < HEADSET_STATE_CONNECTED) {
+			debug("Refusing SCO from non-connected headset");
+			goto drop;
+		}
+
+		if (!get_hfp_active(device)) {
+			error("Refusing non-HFP SCO connect attempt from %s",
+									addr);
+			goto drop;
+		}
+
+		if (headset_connect_sco(device, chan) < 0)
+			goto drop;
+
+		headset_set_state(device, HEADSET_STATE_PLAYING);
+	} else if (device->gateway) {
+		if (!gateway_is_connected(device)) {
+			debug("Refusing SCO from non-connected AG");
+			goto drop;
+		}
+
+		if (gateway_connect_sco(device, chan) < 0)
+			goto drop;
+	} else
 		goto drop;
-	}
-
-	if (!get_hfp_active(device)) {
-		error("Refusing non-HFP SCO connect attempt from %s", addr);
-		goto drop;
-	}
 
 	sk = g_io_channel_unix_get_fd(chan);
 	fcntl(sk, F_SETFL, 0);
 
-	if (headset_connect_sco(device, chan) < 0)
-		goto drop;
-
 	debug("Accepted SCO connection from %s", addr);
-	headset_set_state(device, HEADSET_STATE_PLAYING);
 
 	return;
 
-- 
1.5.4.5

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[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