summaryrefslogtreecommitdiffstats
path: root/audio/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'audio/main.c')
-rw-r--r--audio/main.c56
1 files changed, 56 insertions, 0 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;
}