summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2009-02-18 19:17:54 -0300
committerJohan Hedberg <johan.hedberg@nokia.com>2009-02-19 14:27:38 +0200
commitd048052453e0a8ea53061e68424f671df8c405a0 (patch)
treee66b94261ad103d0398e79eb914b4ca4a3e115b7 /audio
parent2ecef94bcdd0324da979752352a286be85520059 (diff)
Make audio plugin to use BtIO API.
Diffstat (limited to 'audio')
-rw-r--r--audio/avdtp.c136
-rw-r--r--audio/control.c123
-rw-r--r--audio/headset.c52
-rw-r--r--audio/main.c27
-rw-r--r--audio/manager.c96
5 files changed, 253 insertions, 181 deletions
diff --git a/audio/avdtp.c b/audio/avdtp.c
index a7960f25..da1a4df7 100644
--- a/audio/avdtp.c
+++ b/audio/avdtp.c
@@ -50,6 +50,7 @@
#include "control.h"
#include "avdtp.h"
#include "glib-helper.h"
+#include "btio.h"
#include "sink.h"
#include <bluetooth/l2cap.h>
@@ -1764,22 +1765,20 @@ failed:
return FALSE;
}
-static void l2cap_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,
- const bdaddr_t *dst, gpointer user_data)
+static void l2cap_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
{
struct avdtp *session = user_data;
- struct l2cap_options l2o;
- socklen_t len;
int sk;
char address[18];
+ GError *gerr = NULL;
if (!g_slist_find(sessions, session)) {
debug("l2cap_connect_cb: session got removed");
return;
}
- if (err < 0) {
- error("connect(): %s (%d)", strerror(-err), -err);
+ if (err) {
+ error("%s", err->message);
goto failed;
}
@@ -1790,27 +1789,24 @@ static void l2cap_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,
session->state = AVDTP_SESSION_STATE_CONNECTING;
}
+ bt_io_get(chan, BT_IO_L2CAP, &gerr,
+ BT_IO_OPT_OMTU, &session->omtu,
+ BT_IO_OPT_IMTU, &session->imtu,
+ BT_IO_OPT_INVALID);
+ if (gerr) {
+ error("%s", gerr->message);
+ g_clear_error(&gerr);
+ goto failed;
+ }
+
ba2str(&session->dst, address);
debug("AVDTP: connected %s channel to %s",
session->pending_open ? "transport" : "signaling",
address);
- memset(&l2o, 0, sizeof(l2o));
- len = sizeof(l2o);
- if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o,
- &len) < 0) {
- err = errno;
- error("getsockopt(L2CAP_OPTIONS): %s (%d)", strerror(err),
- err);
- goto failed;
- }
-
if (session->state == AVDTP_SESSION_STATE_CONNECTING) {
struct audio_device *dev;
- session->imtu = l2o.imtu;
- session->omtu = l2o.omtu;
-
debug("AVDTP imtu=%u, omtu=%u", session->imtu, session->omtu);
session->buf = g_malloc0(session->imtu);
@@ -1824,13 +1820,10 @@ static void l2cap_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,
AUDIO_CONTROL_INTERFACE, FALSE);
if (dev)
avrcp_connect(dev);
- }
- else if (session->pending_open)
- handle_transport_connect(session, sk, l2o.imtu, l2o.omtu);
- else {
- err = -EIO;
+ } else if (session->pending_open)
+ handle_transport_connect(session, sk, session->imtu, session->omtu);
+ else
goto failed;
- }
process_queue(session);
@@ -1846,22 +1839,30 @@ failed:
avdtp_sep_set_state(session, stream->lsep,
AVDTP_STATE_IDLE);
} else
- connection_lost(session, -err);
+ connection_lost(session, EIO);
return;
}
static int l2cap_connect(struct avdtp *session)
{
- int err;
+ GError *err = NULL;
+ GIOChannel *io;
- err = bt_l2cap_connect(&session->server->src, &session->dst, AVDTP_PSM,
- 0, l2cap_connect_cb, session);
- if (err < 0) {
- error("Connect failed. %s(%d)", strerror(-err), -err);
- return err;
+ io = bt_io_connect(BT_IO_L2CAP, l2cap_connect_cb, session,
+ NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, &session->server->src,
+ BT_IO_OPT_DEST_BDADDR, &session->dst,
+ BT_IO_OPT_PSM, AVDTP_PSM,
+ BT_IO_OPT_INVALID);
+ if (!io) {
+ error("%s", err->message);
+ g_error_free(err);
+ return -EIO;
}
+ g_io_channel_unref(io);
+
return 0;
}
@@ -2997,38 +2998,43 @@ static void auth_cb(DBusError *derr, void *user_data)
g_io_channel_unref(io);
}
-static void avdtp_server_cb(GIOChannel *chan, int err, const bdaddr_t *src,
- const bdaddr_t *dst, gpointer data)
+static void avdtp_server_cb(GIOChannel *chan, GError *err, gpointer data)
{
int sk;
- socklen_t size;
- struct l2cap_options l2o;
struct avdtp *session;
struct audio_device *dev;
char address[18];
+ bdaddr_t src, dst;
+ uint16_t imtu, omtu;
+ int perr;
+ GError *gerr = NULL;
- if (err < 0) {
- error("accept: %s (%d)", strerror(-err), -err);
+ if (err) {
+ error("%s", err->message);
return;
}
- sk = g_io_channel_unix_get_fd(chan);
+ bt_io_get(chan, BT_IO_L2CAP, &gerr,
+ BT_IO_OPT_SOURCE_BDADDR, &src,
+ BT_IO_OPT_DEST_BDADDR, &dst,
+ BT_IO_OPT_DEST, address,
+ BT_IO_OPT_OMTU, &omtu,
+ BT_IO_OPT_IMTU, &imtu,
+ BT_IO_OPT_INVALID);
+ if (gerr) {
+ error("%s", gerr->message);
+ g_error_free(gerr);
+ goto drop;
+ }
- ba2str(dst, address);
debug("AVDTP: incoming connect from %s", address);
- memset(&l2o, 0, sizeof(l2o));
- size = sizeof(l2o);
- if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &size) < 0) {
- error("getsockopt(L2CAP_OPTIONS): %s (%d)", strerror(errno),
- errno);
- goto drop;
- }
+ session = avdtp_get_internal(&src, &dst);
- session = avdtp_get_internal(src, dst);
+ sk = g_io_channel_unix_get_fd(chan);
if (session->pending_open && session->pending_open->open_acp) {
- handle_transport_connect(session, sk, l2o.imtu, l2o.omtu);
+ handle_transport_connect(session, sk, imtu, omtu);
return;
}
@@ -3037,47 +3043,53 @@ static void avdtp_server_cb(GIOChannel *chan, int err, const bdaddr_t *src,
goto drop;
}
- dev = manager_get_device(src, dst);
+ dev = manager_get_device(&src, &dst);
if (!dev) {
error("Unable to get audio device object for %s", address);
goto drop;
}
- session->imtu = l2o.imtu;
- session->omtu = l2o.omtu;
+ session->imtu = imtu;
+ session->omtu = omtu;
session->sock = sk;
debug("AVDTP imtu=%u, omtu=%u", session->imtu, session->omtu);
session->io = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
(GIOFunc) session_cb, session);
- err = btd_request_authorization(src, dst, ADVANCED_AUDIO_UUID,
+ perr = btd_request_authorization(&src, &dst, ADVANCED_AUDIO_UUID,
auth_cb, session);
- if (err < 0) {
+ if (perr < 0) {
avdtp_unref(session);
goto drop;
}
- g_io_channel_unref(chan);
-
session->state = AVDTP_SESSION_STATE_CONNECTING;
return;
drop:
g_io_channel_close(chan);
- g_io_channel_unref(chan);
}
static GIOChannel *avdtp_server_socket(const bdaddr_t *src, gboolean master)
{
- int lm = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
+ GError *err = NULL;
+ GIOChannel *io;
- if (master)
- lm |= L2CAP_LM_MASTER;
+ io = bt_io_listen(BT_IO_L2CAP, avdtp_server_cb, NULL, NULL,
+ NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, src,
+ BT_IO_OPT_PSM, AVDTP_PSM,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+ BT_IO_OPT_MASTER, master,
+ BT_IO_OPT_INVALID);
+ if (!io) {
+ error("%s", err->message);
+ g_error_free(err);
+ }
- return bt_l2cap_listen(src, AVDTP_PSM, 0, lm, avdtp_server_cb,
- NULL);
+ return io;
}
const char *avdtp_strerror(struct avdtp_error *err)
diff --git a/audio/control.c b/audio/control.c
index 5cf68cdf..941e1477 100644
--- a/audio/control.c
+++ b/audio/control.c
@@ -55,6 +55,7 @@
#include "control.h"
#include "sdpd.h"
#include "glib-helper.h"
+#include "btio.h"
#include "dbus-common.h"
#define AVCTP_PSM 23
@@ -653,36 +654,48 @@ static void auth_cb(DBusError *derr, void *user_data)
avctp_connect_session(session);
}
-static void avctp_server_cb(GIOChannel *chan, int err, const bdaddr_t *src,
- const bdaddr_t *dst, gpointer data)
+static void avctp_server_cb(GIOChannel *chan, GError *err, gpointer data)
{
- socklen_t size;
- struct l2cap_options l2o;
struct avctp *session;
GIOCondition flags = G_IO_ERR | G_IO_HUP | G_IO_NVAL;
struct audio_device *dev;
char address[18];
+ bdaddr_t src, dst;
+ uint16_t imtu;
+ int perr;
+ GError *gerr = NULL;
- if (err < 0) {
- error("AVCTP server socket: %s (%d)", strerror(-err), -err);
+ if (err) {
+ error("%s", err->message);
return;
}
- session = avctp_get(src, dst);
+ bt_io_get(chan, BT_IO_L2CAP, &gerr,
+ BT_IO_OPT_SOURCE_BDADDR, &src,
+ BT_IO_OPT_DEST_BDADDR, &dst,
+ BT_IO_OPT_DEST, address,
+ BT_IO_OPT_IMTU, &imtu,
+ BT_IO_OPT_INVALID);
+ if (gerr) {
+ error("%s", gerr->message);
+ g_error_free(gerr);
+ g_io_channel_close(chan);
+ return;
+ }
+
+ session = avctp_get(&src, &dst);
if (!session) {
error("Unable to create new AVCTP session");
goto drop;
}
- ba2str(dst, address);
-
if (session->sock >= 0) {
error("Refusing unexpected connect from %s", address);
goto drop;
}
- dev = manager_get_device(src, dst);
+ dev = manager_get_device(&src, &dst);
if (!dev) {
error("Unable to get audio device object for %s", address);
goto drop;
@@ -696,27 +709,17 @@ static void avctp_server_cb(GIOChannel *chan, int err, const bdaddr_t *src,
session->state = AVCTP_STATE_CONNECTING;
session->sock = g_io_channel_unix_get_fd(chan);
- memset(&l2o, 0, sizeof(l2o));
- size = sizeof(l2o);
- if (getsockopt(session->sock, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &size) < 0) {
- err = errno;
- error("getsockopt(L2CAP_OPTIONS): %s (%d)", strerror(err),
- err);
- goto drop;
- }
-
- session->mtu = l2o.imtu;
+ session->mtu = imtu;
session->io = g_io_add_watch(chan, flags, (GIOFunc) session_cb,
session);
- g_io_channel_unref(chan);
- if (avdtp_is_connected(src, dst))
+ if (avdtp_is_connected(&src, &dst))
goto proceed;
- err = btd_request_authorization(src, dst, AVRCP_TARGET_UUID,
+ perr = btd_request_authorization(&src, &dst, AVRCP_TARGET_UUID,
auth_cb, session);
- if (err < 0)
+ if (perr < 0)
goto drop;
return;
@@ -734,31 +737,32 @@ drop:
static GIOChannel *avctp_server_socket(const bdaddr_t *src, gboolean master)
{
+ GError *err = NULL;
GIOChannel *io;
- int lm = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT;
- if (master)
- lm |= L2CAP_LM_MASTER;
-
- io = bt_l2cap_listen(src, AVCTP_PSM, 0, lm, avctp_server_cb,
- NULL);
+ io = bt_io_listen(BT_IO_L2CAP, avctp_server_cb, NULL, NULL,
+ NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, src,
+ BT_IO_OPT_PSM, AVCTP_PSM,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+ BT_IO_OPT_MASTER, master,
+ BT_IO_OPT_INVALID);
if (!io) {
- error("Unable to allocate new io channel");
- return NULL;
+ error("%s", err->message);
+ g_error_free(err);
}
return io;
}
-static void avctp_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,
- const bdaddr_t *dst, gpointer data)
+static void avctp_connect_cb(GIOChannel *chan, GError *err, gpointer data)
{
struct control *control = data;
struct avctp *session = control->session;
- struct l2cap_options l2o;
- socklen_t len;
int sk;
char address[18];
+ uint16_t imtu;
+ GError *gerr = NULL;
if (!session) {
debug("avctp_connect_cb: session removed while connecting");
@@ -767,12 +771,21 @@ static void avctp_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,
return;
}
- ba2str(&session->dst, address);
+ if (err) {
+ avctp_unref(session);
+ error("%s", err->message);
+ return;
+ }
- if (err < 0) {
+ bt_io_get(chan, BT_IO_L2CAP, &gerr,
+ BT_IO_OPT_DEST, &address,
+ BT_IO_OPT_IMTU, &imtu,
+ BT_IO_OPT_INVALID);
+ if (gerr) {
avctp_unref(session);
- error("AVCTP connect(%s): %s (%d)", address, strerror(-err),
- -err);
+ error("%s", gerr->message);
+ g_error_free(gerr);
+ g_io_channel_close(chan);
return;
}
@@ -782,17 +795,6 @@ static void avctp_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,
sk = g_io_channel_unix_get_fd(chan);
session->sock = sk;
- memset(&l2o, 0, sizeof(l2o));
- len = sizeof(l2o);
- if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &len) < 0) {
- err = errno;
- g_io_channel_unref(chan);
- avctp_unref(session);
- error("getsockopt(L2CAP_OPTIONS): %s (%d)", strerror(err),
- err);
- return;
- }
-
init_uinput(session);
g_dbus_emit_signal(session->dev->conn, session->dev->path,
@@ -800,7 +802,7 @@ static void avctp_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,
DBUS_TYPE_INVALID);
session->state = AVCTP_STATE_CONNECTED;
- session->mtu = l2o.imtu;
+ session->mtu = imtu;
session->io = g_io_add_watch(chan,
G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
(GIOFunc) session_cb, session);
@@ -811,7 +813,8 @@ gboolean avrcp_connect(struct audio_device *dev)
{
struct control *control = dev->control;
struct avctp *session;
- int err;
+ GError *err = NULL;
+ GIOChannel *io;
if (control->session)
return TRUE;
@@ -827,14 +830,20 @@ gboolean avrcp_connect(struct audio_device *dev)
session->dev = dev;
session->state = AVCTP_STATE_CONNECTING;
- err = bt_l2cap_connect(&dev->src, &dev->dst, AVCTP_PSM, 0,
- avctp_connect_cb, control);
- if (err < 0) {
+ io = bt_io_connect(BT_IO_L2CAP, avctp_connect_cb, control, NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, &dev->src,
+ BT_IO_OPT_DEST_BDADDR, &dev->dst,
+ BT_IO_OPT_PSM, AVCTP_PSM,
+ BT_IO_OPT_INVALID);
+ if (err) {
avctp_unref(session);
- error("Connect failed. %s(%d)", strerror(-err), -err);
+ error("%s", err->message);
+ g_error_free(err);
return FALSE;
}
+ g_io_channel_unref(io);
+
control->session = session;
return TRUE;
diff --git a/audio/headset.c b/audio/headset.c
index 9fdabe4c..b83ce906 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -58,6 +58,7 @@
#include "telephony.h"
#include "headset.h"
#include "glib-helper.h"
+#include "btio.h"
#include "dbus-common.h"
#include "../src/adapter.h"
#include "../src/device.h"
@@ -509,16 +510,15 @@ static gboolean ring_timer_cb(gpointer data)
return TRUE;
}
-static void sco_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,
- const bdaddr_t *dst, gpointer user_data)
+static void sco_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
{
int sk;
struct audio_device *dev = user_data;
struct headset *hs = dev->headset;
struct pending_connect *p = hs->pending;
- if (err < 0) {
- error("connect(): %s (%d)", strerror(-err), -err);
+ if (err) {
+ error("%s", err->message);
if (p->msg)
error_connection_attempt_failed(dev->conn, p->msg, p->err);
@@ -564,17 +564,24 @@ static int sco_connect(struct audio_device *dev, headset_stream_cb_t cb,
void *user_data, unsigned int *cb_id)
{
struct headset *hs = dev->headset;
- int err;
+ GError *err = NULL;
+ GIOChannel *io;
if (hs->state != HEADSET_STATE_CONNECTED)
return -EINVAL;
- err = bt_sco_connect(&dev->src, &dev->dst, sco_connect_cb, dev);
- if (err < 0) {
- error("connect: %s (%d)", strerror(-err), -err);
- return err;
+ io = bt_io_connect(BT_IO_SCO, sco_connect_cb, dev, NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, &dev->src,
+ BT_IO_OPT_DEST_BDADDR, &dev->dst,
+ BT_IO_OPT_INVALID);
+ if (!io) {
+ error("%s", err->message);
+ g_error_free(err);
+ return -EIO;
}
+ g_io_channel_unref(io);
+
headset_set_state(dev, HEADSET_STATE_PLAY_IN_PROGRESS);
pending_connect_init(hs, HEADSET_STATE_PLAYING);
@@ -1221,16 +1228,15 @@ static gboolean sco_cb(GIOChannel *chan, GIOCondition cond,
return FALSE;
}
-static void rfcomm_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,
- const bdaddr_t *dst, gpointer user_data)
+static void rfcomm_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
{
struct audio_device *dev = user_data;
struct headset *hs = dev->headset;
struct pending_connect *p = hs->pending;
char hs_address[18];
- if (err < 0) {
- error("connect(): %s (%d)", strerror(-err), -err);
+ if (err) {
+ error("%s", err->message);
goto failed;
}
@@ -1397,7 +1403,8 @@ static int rfcomm_connect(struct audio_device *dev, headset_stream_cb_t cb,
{
struct headset *hs = dev->headset;
char address[18];
- int err;
+ GError *err = NULL;
+ GIOChannel *io;
if (hs->rfcomm_ch < 0)
return get_records(dev, cb, user_data, cb_id);
@@ -1407,13 +1414,20 @@ static int rfcomm_connect(struct audio_device *dev, headset_stream_cb_t cb,
debug("%s: Connecting to %s channel %d", dev->path, address,
hs->rfcomm_ch);
- err = bt_rfcomm_connect(&dev->src, &dev->dst, hs->rfcomm_ch,
- rfcomm_connect_cb, dev);
- if (err < 0) {
- error("connect() failed: %s (%d)", strerror(-err), -err);
- return err;
+ io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, dev,
+ NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, &dev->src,
+ BT_IO_OPT_DEST_BDADDR, &dev->dst,
+ BT_IO_OPT_CHANNEL, hs->rfcomm_ch,
+ BT_IO_OPT_INVALID);
+ if (!io) {
+ error("%s", err->message);
+ g_error_free(err);
+ return -EIO;
}
+ g_io_channel_unref(io);
+
headset_set_state(dev, HEADSET_STATE_CONNECT_IN_PROGRESS);
pending_connect_init(hs, HEADSET_STATE_CONNECTED);
diff --git a/audio/main.c b/audio/main.c
index 846866a8..0e5afc42 100644
--- a/audio/main.c
+++ b/audio/main.c
@@ -38,6 +38,7 @@
#include <dbus/dbus.h>
#include "glib-helper.h"
+#include "btio.h"
#include "plugin.h"
#include "logging.h"
#include "unix.h"
@@ -64,19 +65,28 @@ 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)
+static void sco_server_cb(GIOChannel *chan, GError *err, gpointer data)
{
int sk;
struct audio_device *device;
char addr[18];
+ bdaddr_t dst;
- if (err < 0) {
- error("accept: %s (%d)", strerror(-err), -err);
+ if (err) {
+ error("sco_server_cb: %s", err->message);
return;
}
- device = manager_find_device(dst, NULL, FALSE);
+ bt_io_get(chan, BT_IO_SCO, &err,
+ BT_IO_OPT_DEST_BDADDR, &dst,
+ BT_IO_OPT_DEST, addr,
+ BT_IO_OPT_INVALID);
+ if (err) {
+ error("bt_io_get: %s", err->message);
+ goto drop;
+ }
+
+ device = manager_find_device(&dst, NULL, FALSE);
if (!device)
goto drop;
@@ -85,8 +95,6 @@ static void sco_server_cb(GIOChannel *chan, int err, const bdaddr_t *src,
goto drop;
}
- ba2str(dst, addr);
-
if (!get_hfp_active(device)) {
error("Refusing non-HFP SCO connect attempt from %s", addr);
goto drop;
@@ -104,7 +112,6 @@ static void sco_server_cb(GIOChannel *chan, int err, const bdaddr_t *src,
drop:
g_io_channel_close(chan);
- g_io_channel_unref(chan);
}
static DBusConnection *connection;
@@ -129,7 +136,9 @@ static int audio_init(void)
return -EIO;
}
- sco_server = bt_sco_listen(BDADDR_ANY, 0, sco_server_cb, NULL);
+ sco_server = bt_io_listen(BT_IO_SCO, sco_server_cb, NULL, NULL,
+ NULL, NULL,
+ BT_IO_OPT_INVALID);
if (!sco_server) {
error("Unable to start SCO server socket");
return -EIO;
diff --git a/audio/manager.c b/audio/manager.c
index 1c7c46b5..8ef04824 100644
--- a/audio/manager.c
+++ b/audio/manager.c
@@ -50,6 +50,7 @@
#include <gdbus.h>
#include "glib-helper.h"
+#include "btio.h"
#include "../src/manager.h"
#include "../src/adapter.h"
#include "../src/device.h"
@@ -423,21 +424,34 @@ static void auth_cb(DBusError *derr, void *user_data)
}
}
-static void ag_io_cb(GIOChannel *chan, int err, const bdaddr_t *src,
- const bdaddr_t *dst, gpointer data)
+static void ag_io_cb(GIOChannel *chan, GError *err, gpointer data)
{
- struct audio_adapter *adapter = data;
const char *server_uuid, *remote_uuid;
uint16_t svclass;
struct audio_device *device;
gboolean hfp_active;
+ bdaddr_t src, dst;
+ int perr;
+ GError *gerr = NULL;
+ uint8_t ch;
- if (err < 0) {
- error("accept: %s (%d)", strerror(-err), -err);
+ if (err) {
+ error("%s", err->message);
return;
}
- if (chan == adapter->hsp_ag_server) {
+ bt_io_get(chan, BT_IO_RFCOMM, &gerr,
+ BT_IO_OPT_SOURCE_BDADDR, &src,
+ BT_IO_OPT_DEST_BDADDR, &dst,
+ BT_IO_OPT_CHANNEL &ch,
+ BT_IO_OPT_INVALID);
+ if (gerr) {
+ error("%s", gerr->message);
+ g_clear_error(&gerr);
+ goto drop;
+ }
+
+ if (ch == DEFAULT_HS_AG_CHANNEL) {
hfp_active = FALSE;
server_uuid = HSP_AG_UUID;
remote_uuid = HSP_HS_UUID;
@@ -449,7 +463,7 @@ static void ag_io_cb(GIOChannel *chan, int err, const bdaddr_t *src,
svclass = HANDSFREE_SVCLASS_ID;
}
- device = manager_get_device(src, dst);
+ device = manager_get_device(&src, &dst);
if (!device)
goto drop;
@@ -478,10 +492,10 @@ static void ag_io_cb(GIOChannel *chan, int err, const bdaddr_t *src,
headset_set_state(device, HEADSET_STATE_CONNECT_IN_PROGRESS);
- err = btd_request_authorization(&device->src, &device->dst,
+ perr = btd_request_authorization(&device->src, &device->dst,
server_uuid, auth_cb, device);
- if (err < 0) {
- debug("Authorization denied: %s", strerror(-err));
+ if (perr < 0) {
+ debug("Authorization denied: %s", strerror(-perr));
headset_set_state(device, HEADSET_STATE_DISCONNECTED);
return;
}
@@ -490,11 +504,9 @@ static void ag_io_cb(GIOChannel *chan, int err, const bdaddr_t *src,
drop:
g_io_channel_close(chan);
- g_io_channel_unref(chan);
}
-static void hs_io_cb(GIOChannel *chan, int err, const bdaddr_t *src,
- const bdaddr_t *dst, void *data)
+static void hs_io_cb(GIOChannel *chan, GError *err, void *data)
{
/*Stub*/
return;
@@ -506,7 +518,8 @@ static int headset_server_init(struct audio_adapter *adapter)
sdp_record_t *record;
gboolean master = TRUE;
GError *err = NULL;
- uint32_t features, flags;
+ uint32_t features;
+ GIOChannel *io;
if (config) {
gboolean tmp;
@@ -520,16 +533,17 @@ static int headset_server_init(struct audio_adapter *adapter)
master = tmp;
}
- flags = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
-
- if (master)
- flags |= RFCOMM_LM_MASTER;
-
- adapter->hsp_ag_server = bt_rfcomm_listen(&adapter->src, chan, flags,
- ag_io_cb, adapter);
- if (!adapter->hsp_ag_server)
+ io = bt_io_listen(BT_IO_RFCOMM, ag_io_cb, NULL, adapter, NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, &adapter->src,
+ BT_IO_OPT_CHANNEL, chan,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+ BT_IO_OPT_MASTER, master,
+ BT_IO_OPT_INVALID);
+ if (!io)
goto failed;
+ adapter->hsp_ag_server = io;
+
record = hsp_ag_record(chan);
if (!record) {
error("Unable to allocate new service record");
@@ -550,11 +564,17 @@ static int headset_server_init(struct audio_adapter *adapter)
chan = DEFAULT_HF_AG_CHANNEL;
- adapter->hfp_ag_server = bt_rfcomm_listen(&adapter->src, chan, flags,
- ag_io_cb, adapter);
- if (!adapter->hfp_ag_server)
+ io = bt_io_listen(BT_IO_RFCOMM, ag_io_cb, NULL, adapter, NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, &adapter->src,
+ BT_IO_OPT_CHANNEL, chan,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+ BT_IO_OPT_MASTER, master,
+ BT_IO_OPT_INVALID);
+ if (!io)
goto failed;
+ adapter->hfp_ag_server = io;
+
record = hfp_ag_record(chan, features);
if (!record) {
error("Unable to allocate new service record");
@@ -571,12 +591,16 @@ static int headset_server_init(struct audio_adapter *adapter)
return 0;
failed:
+ error("%s", err->message);
+ g_clear_error(&err);
if (adapter->hsp_ag_server) {
+ g_io_channel_close(adapter->hsp_ag_server);
g_io_channel_unref(adapter->hsp_ag_server);
adapter->hsp_ag_server = NULL;
}
if (adapter->hfp_ag_server) {
+ g_io_channel_close(adapter->hfp_ag_server);
g_io_channel_unref(adapter->hfp_ag_server);
adapter->hfp_ag_server = NULL;
}
@@ -590,7 +614,7 @@ static int gateway_server_init(struct audio_adapter *adapter)
sdp_record_t *record;
gboolean master = TRUE;
GError *err = NULL;
- uint32_t flags;
+ GIOChannel *io;
if (config) {
gboolean tmp;
@@ -604,15 +628,19 @@ static int gateway_server_init(struct audio_adapter *adapter)
master = tmp;
}
- flags = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
-
- if (master)
- flags |= RFCOMM_LM_MASTER;
-
- adapter->hsp_hs_server = bt_rfcomm_listen(&adapter->src, chan, flags,
- hs_io_cb, adapter);
- if (!adapter->hsp_hs_server)
+ io = bt_io_listen(BT_IO_RFCOMM, hs_io_cb, NULL, adapter, NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, &adapter->src,
+ BT_IO_OPT_CHANNEL, chan,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+ BT_IO_OPT_MASTER, master,
+ BT_IO_OPT_INVALID);
+ if (!io) {
+ error("%s", err->message);
+ g_error_free(err);
return -1;
+ }
+
+ adapter->hsp_hs_server = io;
record = hsp_hs_record(chan);
if (!record) {