summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2008-10-04 13:00:38 +0200
committerJohan Hedberg <johan.hedberg@nokia.com>2008-10-04 13:00:38 +0200
commit79c4a0e6df03808898cf3c1b592a02e5585c6bc9 (patch)
tree2aba5de800eb3f7a6a6f10a951ff6d910366ed35
parentffcd40c827921adc5865b2bbf9662e1f259b15d1 (diff)
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.
-rw-r--r--audio/main.c56
-rw-r--r--audio/manager.c56
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 <errno.h>
#include <sys/socket.h>
+#include <unistd.h>
+#include <fcntl.h>
#include <bluetooth/bluetooth.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
#include <glib.h>
#include <dbus/dbus.h>
+#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;