From 79c4a0e6df03808898cf3c1b592a02e5585c6bc9 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 4 Oct 2008 13:00:38 +0200 Subject: Change SCO server socket into a generic one Due to a kernel bug we can't initiate SCO connections if there's a server socket bound to the same adapter. Therefore use a global socket bound to BDADDR_ANY instead. --- audio/main.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ audio/manager.c | 56 -------------------------------------------------------- 2 files changed, 56 insertions(+), 56 deletions(-) diff --git a/audio/main.c b/audio/main.c index 4583ca81..3f335f25 100644 --- a/audio/main.c +++ b/audio/main.c @@ -28,15 +28,21 @@ #include #include +#include +#include #include +#include +#include #include #include +#include "glib-helper.h" #include "plugin.h" #include "logging.h" #include "unix.h" #include "device.h" +#include "headset.h" #include "manager.h" static GKeyFile *load_config_file(const char *file) @@ -56,11 +62,55 @@ static GKeyFile *load_config_file(const char *file) return keyfile; } +static void sco_server_cb(GIOChannel *chan, int err, const bdaddr_t *src, + const bdaddr_t *dst, gpointer data) +{ + int sk; + struct audio_device *device; + char addr[18]; + + if (err < 0) { + error("accept: %s (%d)", strerror(-err), -err); + return; + } + + device = manager_find_device(dst, NULL, FALSE); + if (!device) + goto drop; + + if (headset_get_state(device) < HEADSET_STATE_CONNECTED) { + debug("Refusing SCO from non-connected headset"); + goto drop; + } + + ba2str(dst, addr); + + 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) { + debug("Accepted SCO connection from %s", addr); + headset_set_state(device, HEADSET_STATE_PLAYING); + } + + return; + +drop: + g_io_channel_close(chan); + g_io_channel_unref(chan); +} + static DBusConnection *connection; static int audio_init(void) { GKeyFile *config; + GIOChannel *sco_server; connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); if (connection == NULL) @@ -78,6 +128,12 @@ static int audio_init(void) return -EIO; } + sco_server = bt_sco_listen(BDADDR_ANY, 0, sco_server_cb, NULL); + if (!sco_server) { + error("Unable to start SCO server socket"); + return -EIO; + } + return 0; } diff --git a/audio/manager.c b/audio/manager.c index c4682726..a6a040fe 100644 --- a/audio/manager.c +++ b/audio/manager.c @@ -94,7 +94,6 @@ struct audio_adapter { GIOChannel *hsp_ag_server; GIOChannel *hfp_ag_server; GIOChannel *hsp_hs_server; - GIOChannel *sco_server; }; static DBusConnection *connection = NULL; @@ -470,49 +469,6 @@ static void auth_cb(DBusError *derr, void *user_data) } } -static void sco_server_cb(GIOChannel *chan, int err, const bdaddr_t *src, - const bdaddr_t *dst, gpointer data) -{ - int sk; - struct audio_device *device; - char addr[18]; - - if (err < 0) { - error("accept: %s (%d)", strerror(-err), -err); - return; - } - - device = manager_find_device(dst, NULL, FALSE); - if (!device) - goto drop; - - if (headset_get_state(device) < HEADSET_STATE_CONNECTED) { - debug("Refusing SCO from non-connected headset"); - goto drop; - } - - ba2str(dst, addr); - - 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) { - debug("Accepted SCO connection from %s", addr); - headset_set_state(device, HEADSET_STATE_PLAYING); - } - - return; - -drop: - g_io_channel_close(chan); - g_io_channel_unref(chan); -} - static void ag_io_cb(GIOChannel *chan, int err, const bdaddr_t *src, const bdaddr_t *dst, gpointer data) { @@ -604,13 +560,6 @@ static int headset_server_init(struct audio_adapter *adapter) hfp = tmp; } - adapter->sco_server = bt_sco_listen(&adapter->src, 0, sco_server_cb, - adapter); - if (!adapter->sco_server) { - error("Unable to start SCO server socket"); - return -1; - } - flags = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT; if (master) @@ -662,11 +611,6 @@ static int headset_server_init(struct audio_adapter *adapter) return 0; failed: - if (adapter->sco_server) { - g_io_channel_unref(adapter->sco_server); - adapter->sco_server = NULL; - } - if (adapter->hsp_ag_server) { g_io_channel_unref(adapter->hsp_ag_server); adapter->hsp_ag_server = NULL; -- cgit