summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2008-05-15 20:37:45 +0000
committerLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2008-05-15 20:37:45 +0000
commitc30643b049e0d6215f49c77e38092832b5b74179 (patch)
treeb0d3e9e37090b95ee5f2fc52c86ab2117c74083f /audio
parent16ac1a8c833c201e45a59940c7e6073664c1fab5 (diff)
Make audio service to use of bt_*_listen helpers.
Diffstat (limited to 'audio')
-rw-r--r--audio/avdtp.c124
-rw-r--r--audio/headset.c4
-rw-r--r--audio/headset.h2
-rw-r--r--audio/manager.c153
4 files changed, 73 insertions, 210 deletions
diff --git a/audio/avdtp.c b/audio/avdtp.c
index c74c99e0..761cb2f5 100644
--- a/audio/avdtp.c
+++ b/audio/avdtp.c
@@ -2738,140 +2738,79 @@ static void auth_cb_old(DBusPendingCall *call, void *data)
dbus_message_unref(reply);
}
-static gboolean avdtp_server_cb(GIOChannel *chan, GIOCondition cond, void *data)
+static void avdtp_server_cb(GIOChannel *chan, int err, const bdaddr_t *src,
+ const bdaddr_t *dst, gpointer data)
{
- int srv_sk, cli_sk;
+ int sk;
socklen_t size;
- struct sockaddr_l2 addr;
struct l2cap_options l2o;
- bdaddr_t src, dst;
struct avdtp *session;
- GIOChannel *io;
char address[18];
- if (cond & G_IO_NVAL)
- return FALSE;
-
- if (cond & (G_IO_HUP | G_IO_ERR)) {
- error("Hangup or error on AVDTP server socket");
- g_io_channel_close(chan);
- raise(SIGTERM);
- return FALSE;
- }
-
- srv_sk = g_io_channel_unix_get_fd(chan);
-
- size = sizeof(struct sockaddr_l2);
- cli_sk = accept(srv_sk, (struct sockaddr *) &addr, &size);
- if (cli_sk < 0) {
- error("AVDTP accept: %s (%d)", strerror(errno), errno);
- return TRUE;
+ if (err < 0) {
+ error("accept: %s (%d)", strerror(-err), -err);
+ return;
}
- bacpy(&dst, &addr.l2_bdaddr);
+ sk = g_io_channel_unix_get_fd(chan);
- ba2str(&dst, address);
+ ba2str(dst, address);
debug("AVDTP: incoming connect from %s", address);
- size = sizeof(struct sockaddr_l2);
- if (getsockname(cli_sk, (struct sockaddr *) &addr, &size) < 0) {
- error("getsockname: %s (%d)", strerror(errno), errno);
- close(cli_sk);
- return TRUE;
- }
-
- bacpy(&src, &addr.l2_bdaddr);
-
memset(&l2o, 0, sizeof(l2o));
size = sizeof(l2o);
- if (getsockopt(cli_sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &size) < 0) {
+ if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &size) < 0) {
error("getsockopt(L2CAP_OPTIONS): %s (%d)", strerror(errno),
errno);
- close(cli_sk);
- return TRUE;
+ goto drop;
}
- session = avdtp_get_internal(&src, &dst);
+ session = avdtp_get_internal((bdaddr_t *) src, (bdaddr_t *) dst);
if (session->pending_open && session->pending_open->open_acp) {
- handle_transport_connect(session, cli_sk, l2o.imtu, l2o.omtu);
- return TRUE;
+ handle_transport_connect(session, sk, l2o.imtu, l2o.omtu);
+ return;
}
if (session->sock >= 0) {
error("Refusing unexpected connect from %s", address);
- close(cli_sk);
- return TRUE;
+ goto drop;
}
session->mtu = l2o.imtu;
- session->sock = cli_sk;
+ session->sock = sk;
- io = g_io_channel_unix_new(session->sock);
- session->io = g_io_add_watch(io, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ session->io = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
(GIOFunc) session_cb, session);
- g_io_channel_unref(io);
+ g_io_channel_unref(chan);
- if (service_req_auth(&src, &dst, ADVANCED_AUDIO_UUID, auth_cb, session) == 0)
- return TRUE;
- else if (!manager_authorize(&dst, ADVANCED_AUDIO_UUID, auth_cb_old,
+ if (service_req_auth((bdaddr_t *) src, (bdaddr_t *) dst, ADVANCED_AUDIO_UUID,
+ auth_cb, session) == 0)
+ return;
+ else if (!manager_authorize((bdaddr_t *) dst, ADVANCED_AUDIO_UUID, auth_cb_old,
session, &session->pending_auth)) {
- close(cli_sk);
avdtp_unref(session);
+ goto drop;
}
- return TRUE;
+ return;
+
+drop:
+ g_io_channel_close(chan);
+ g_io_channel_unref(chan);
}
static GIOChannel *avdtp_server_socket(gboolean master)
{
- int sock, lm;
- struct sockaddr_l2 addr;
- GIOChannel *io;
-
- sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
- if (sock < 0) {
- error("AVDTP server socket: %s (%d)", strerror(errno), errno);
- return NULL;
- }
+ int lm;
lm = L2CAP_LM_SECURE;
if (master)
lm |= L2CAP_LM_MASTER;
- if (setsockopt(sock, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0) {
- error("AVDTP server setsockopt: %s (%d)", strerror(errno),
- errno);
- close(sock);
- return NULL;
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.l2_family = AF_BLUETOOTH;
- bacpy(&addr.l2_bdaddr, BDADDR_ANY);
- addr.l2_psm = htobs(AVDTP_PSM);
-
- if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- error("AVDTP server bind: %s (%d)", strerror(errno), errno);
- close(sock);
- return NULL;
- }
-
- if (listen(sock, 4) < 0) {
- error("AVDTP server listen: %s (%d)", strerror(errno), errno);
- close(sock);
- return NULL;
- }
-
- io = g_io_channel_unix_new(sock);
- if (!io) {
- error("Unable to allocate new io channel");
- close(sock);
- return NULL;
- }
-
- return io;
+ return bt_l2cap_listen(BDADDR_ANY, AVDTP_PSM, 0, lm, avdtp_server_cb,
+ NULL);
}
const char *avdtp_strerror(struct avdtp_error *err)
@@ -2954,9 +2893,6 @@ int avdtp_init(GKeyFile *config)
if (!avdtp_server)
return -1;
- g_io_add_watch(avdtp_server, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- (GIOFunc) avdtp_server_cb, NULL);
-
return 0;
}
diff --git a/audio/headset.c b/audio/headset.c
index 40a8a0d3..6198ace7 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -1732,11 +1732,11 @@ void set_hfp_active(struct device *dev, gboolean active)
hs->hfp_active = active;
}
-int headset_connect_rfcomm(struct device *dev, int sock)
+int headset_connect_rfcomm(struct device *dev, GIOChannel *io)
{
struct headset *hs = dev->headset;
- hs->tmp_rfcomm = g_io_channel_unix_new(sock);
+ hs->tmp_rfcomm = io;
return hs->tmp_rfcomm ? 0 : -EINVAL;
}
diff --git a/audio/headset.h b/audio/headset.h
index b218b46e..188971a5 100644
--- a/audio/headset.h
+++ b/audio/headset.h
@@ -59,7 +59,7 @@ gboolean get_hfp_active(struct device *dev);
void set_hfp_active(struct device *dev, gboolean active);
void headset_set_authorized(struct device *dev);
-int headset_connect_rfcomm(struct device *dev, int sock);
+int headset_connect_rfcomm(struct device *dev, GIOChannel *chan);
int headset_close_rfcomm(struct device *dev);
headset_state_t headset_get_state(struct device *dev);
diff --git a/audio/manager.c b/audio/manager.c
index f09125f9..260d1bb3 100644
--- a/audio/manager.c
+++ b/audio/manager.c
@@ -1226,32 +1226,16 @@ static void auth_cb_old(DBusPendingCall *call, void *data)
dbus_message_unref(reply);
}
-static gboolean ag_io_cb(GIOChannel *chan, GIOCondition cond, void *data)
+static void ag_io_cb(GIOChannel *chan, int err, const bdaddr_t *src,
+ const bdaddr_t *dst, gpointer data)
{
- int srv_sk, cli_sk;
- struct sockaddr_rc addr;
- socklen_t size;
const char *uuid;
struct device *device;
gboolean hfp_active;
- if (cond & G_IO_NVAL)
- return FALSE;
-
- if (cond & (G_IO_HUP | G_IO_ERR)) {
- error("Hangup or error on rfcomm server socket");
- g_io_channel_close(chan);
- raise(SIGTERM);
- return FALSE;
- }
-
- srv_sk = g_io_channel_unix_get_fd(chan);
-
- size = sizeof(struct sockaddr_rc);
- cli_sk = accept(srv_sk, (struct sockaddr *) &addr, &size);
- if (cli_sk < 0) {
- error("accept: %s (%d)", strerror(errno), errno);
- return TRUE;
+ if (err < 0) {
+ error("accept: %s (%d)", strerror(-err), -err);
+ return;
}
if (chan == hsp_ag_server) {
@@ -1262,103 +1246,42 @@ static gboolean ag_io_cb(GIOChannel *chan, GIOCondition cond, void *data)
uuid = HFP_AG_UUID;
}
- device = manager_device_connected(&addr.rc_bdaddr, uuid);
- if (!device) {
- close(cli_sk);
- return TRUE;
- }
+ device = manager_device_connected(dst, uuid);
+ if (!device)
+ goto drop;
if (headset_get_state(device) > HEADSET_STATE_DISCONNECTED) {
debug("Refusing new connection since one already exists");
- close(cli_sk);
- return TRUE;
+ goto drop;
}
set_hfp_active(device, hfp_active);
- if (headset_connect_rfcomm(device, cli_sk) < 0) {
+ if (headset_connect_rfcomm(device, chan) < 0) {
error("Allocating new GIOChannel failed!");
- close(cli_sk);
- return TRUE;
+ goto drop;
}
if (service_req_auth(&device->src, &device->dst, uuid, auth_cb,
device) == 0)
- goto proceed;
+ headset_set_state(device, HEADSET_STATE_CONNECT_IN_PROGRESS);
else if (!manager_authorize(&device->dst, uuid, auth_cb_old, device,
NULL))
- goto failed;
+ headset_close_rfcomm(device);
-proceed:
- headset_set_state(device, HEADSET_STATE_CONNECT_IN_PROGRESS);
+ return;
- return TRUE;
-
-failed:
- headset_close_rfcomm(device);
-
- return TRUE;
+drop:
+ g_io_channel_close(chan);
+ g_io_channel_unref(chan);
+ return;
}
-static gboolean hs_io_cb(GIOChannel *chan, GIOCondition cond, void *data)
+static void hs_io_cb(GIOChannel *chan, int err, const bdaddr_t *src,
+ const bdaddr_t *dst, void *data)
{
/*Stub*/
- return TRUE;
-}
-
-static GIOChannel *server_socket(uint8_t *channel, gboolean master)
-{
- int sock, lm;
- struct sockaddr_rc addr;
- socklen_t sa_len;
- GIOChannel *io;
-
- sock = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
- if (sock < 0) {
- error("server socket: %s (%d)", strerror(errno), errno);
- return NULL;
- }
-
- lm = RFCOMM_LM_SECURE;
-
- if (master)
- lm |= RFCOMM_LM_MASTER;
-
- if (setsockopt(sock, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0) {
- error("server setsockopt: %s (%d)", strerror(errno), errno);
- close(sock);
- return NULL;
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.rc_family = AF_BLUETOOTH;
- bacpy(&addr.rc_bdaddr, BDADDR_ANY);
- addr.rc_channel = channel ? *channel : 0;
-
- if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- error("server bind: %s (%d)", strerror(errno), errno);
- close(sock);
- return NULL;
- }
-
- if (listen(sock, 1) < 0) {
- error("server listen: %s (%d)", strerror(errno), errno);
- close(sock);
- return NULL;
- }
-
- sa_len = sizeof(struct sockaddr_rc);
- getsockname(sock, (struct sockaddr *) &addr, &sa_len);
- *channel = addr.rc_channel;
-
- io = g_io_channel_unix_new(sock);
- if (!io) {
- error("Unable to allocate new io channel");
- close(sock);
- return NULL;
- }
-
- return io;
+ return;
}
static int headset_server_init(DBusConnection *conn, GKeyFile *config)
@@ -1367,7 +1290,7 @@ static int headset_server_init(DBusConnection *conn, GKeyFile *config)
sdp_record_t *record;
gboolean hfp = TRUE, master = TRUE;
GError *err = NULL;
- uint32_t features;
+ uint32_t features, flags;
if (!enabled.headset)
return 0;
@@ -1394,7 +1317,13 @@ static int headset_server_init(DBusConnection *conn, GKeyFile *config)
hfp = tmp;
}
- hsp_ag_server = server_socket(&chan, master);
+ flags = RFCOMM_LM_SECURE;
+
+ if (master)
+ flags |= RFCOMM_LM_MASTER;
+
+ hsp_ag_server = bt_rfcomm_listen(BDADDR_ANY, chan, flags, ag_io_cb,
+ NULL);
if (!hsp_ag_server)
return -1;
@@ -1413,10 +1342,6 @@ static int headset_server_init(DBusConnection *conn, GKeyFile *config)
}
hsp_ag_record_id = record->handle;
- g_io_add_watch(hsp_ag_server,
- G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- (GIOFunc) ag_io_cb, NULL);
-
features = headset_config_init(config);
if (!hfp)
@@ -1424,7 +1349,8 @@ static int headset_server_init(DBusConnection *conn, GKeyFile *config)
chan = DEFAULT_HF_AG_CHANNEL;
- hfp_ag_server = server_socket(&chan, master);
+ hfp_ag_server = bt_rfcomm_listen(BDADDR_ANY, chan, flags, ag_io_cb,
+ NULL);
if (!hfp_ag_server)
return -1;
@@ -1443,10 +1369,6 @@ static int headset_server_init(DBusConnection *conn, GKeyFile *config)
}
hfp_ag_record_id = record->handle;
- g_io_add_watch(hfp_ag_server,
- G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- (GIOFunc) ag_io_cb, NULL);
-
return 0;
}
@@ -1456,6 +1378,7 @@ static int gateway_server_init(DBusConnection *conn, GKeyFile *config)
sdp_record_t *record;
gboolean master = TRUE;
GError *err = NULL;
+ uint32_t flags;
if (!enabled.gateway)
return 0;
@@ -1473,7 +1396,13 @@ static int gateway_server_init(DBusConnection *conn, GKeyFile *config)
master = tmp;
}
- hsp_hs_server = server_socket(&chan, master);
+ flags = RFCOMM_LM_SECURE;
+
+ if (master)
+ flags |= RFCOMM_LM_MASTER;
+
+ hsp_hs_server = bt_rfcomm_listen(BDADDR_ANY, chan, flags, hs_io_cb,
+ NULL);
if (!hsp_hs_server)
return -1;
@@ -1490,11 +1419,9 @@ static int gateway_server_init(DBusConnection *conn, GKeyFile *config)
hsp_hs_server = NULL;
return -1;
}
+
hsp_hs_record_id = record->handle;
- g_io_add_watch(hsp_hs_server,
- G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- (GIOFunc) hs_io_cb, NULL);
return 0;
}