summaryrefslogtreecommitdiffstats
path: root/audio/control.c
diff options
context:
space:
mode:
authorCidorvan Leite <cidorvan.leite@openbossa.org>2008-05-09 13:18:47 +0000
committerCidorvan Leite <cidorvan.leite@openbossa.org>2008-05-09 13:18:47 +0000
commita59f82bd8a01e83bd7724beccfe2a0383982650c (patch)
tree93b0093a10348c252e3aacdb5133a03187b950b2 /audio/control.c
parent4679885ba99827f4b9836d6b4f7ce0134b82b565 (diff)
AVCTP l2cap connection clean up
Diffstat (limited to 'audio/control.c')
-rw-r--r--audio/control.c114
1 files changed, 23 insertions, 91 deletions
diff --git a/audio/control.c b/audio/control.c
index f79eee9c..1777899e 100644
--- a/audio/control.c
+++ b/audio/control.c
@@ -816,51 +816,36 @@ proceed:
return TRUE;
}
-static gboolean avctp_connect_cb(GIOChannel *chan, GIOCondition cond,
- gpointer data)
+static void avctp_connect_cb(GIOChannel *chan, int err, gpointer data)
{
struct avctp *session = data;
struct l2cap_options l2o;
socklen_t len;
- int ret, err, sk;
+ int sk;
char address[18];
- if (cond & G_IO_NVAL)
- return FALSE;
-
- sk = g_io_channel_unix_get_fd(chan);
-
- ba2str(&session->dst, address);
-
- len = sizeof(ret);
- if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) {
- err = errno;
- error("getsockopt(SO_ERROR): %s (%d)", strerror(err), err);
- goto failed;
- }
-
- if (ret != 0) {
- err = ret;
- error("AVCTP connect(%s): %s (%d)", address, strerror(err),
- err);
- goto failed;
- }
-
- if (cond & G_IO_HUP) {
- err = EIO;
- goto failed;
+ if (err < 0) {
+ avctp_unref(session);
+ error("AVCTP connect(%s): %s (%d)", address, strerror(-err),
+ -err);
+ return;
}
+ ba2str(&session->dst, address);
debug("AVCTP: connected to %s", address);
+ g_io_channel_set_close_on_unref(chan, FALSE);
+ 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) {
+ if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &len) < 0) {
err = errno;
+ avctp_unref(session);
error("getsockopt(L2CAP_OPTIONS): %s (%d)", strerror(err),
err);
- goto failed;
+ return;
}
init_uinput(session);
@@ -875,23 +860,13 @@ static gboolean avctp_connect_cb(GIOChannel *chan, GIOCondition cond,
session->io = g_io_add_watch(chan,
G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
(GIOFunc) session_cb, session);
- return FALSE;
-
-failed:
- close(sk);
-
- avctp_unref(session);
-
- return FALSE;
}
gboolean avrcp_connect(struct device *dev)
{
struct control *control = dev->control;
struct avctp *session;
- struct sockaddr_l2 l2a;
- GIOChannel *io;
- int sk;
+ int err;
if (control->session)
return TRUE;
@@ -903,62 +878,19 @@ gboolean avrcp_connect(struct device *dev)
}
session->dev = dev;
+ session->state = AVCTP_STATE_CONNECTING;
- memset(&l2a, 0, sizeof(l2a));
- l2a.l2_family = AF_BLUETOOTH;
- bacpy(&l2a.l2_bdaddr, &dev->src);
-
- sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
- if (sk < 0) {
- error("Cannot create L2CAP socket. %s(%d)", strerror(errno),
- errno);
- goto failed;
- }
-
- if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a)) < 0) {
- error("Bind failed. %s (%d)", strerror(errno), errno);
- goto failed;
- }
-
- memset(&l2a, 0, sizeof(l2a));
- l2a.l2_family = AF_BLUETOOTH;
- bacpy(&l2a.l2_bdaddr, &dev->dst);
- l2a.l2_psm = htobs(AVCTP_PSM);
-
- if (set_nonblocking(sk) < 0) {
- error("Set non blocking: %s (%d)", strerror(errno), errno);
- goto failed;
+ err = bt_l2cap_connect(&dev->src, &dev->dst, AVCTP_PSM, 0,
+ avctp_connect_cb, session);
+ if (err < 0) {
+ avctp_unref(session);
+ error("Connect failed. %s(%d)", strerror(-err), -err);
+ return FALSE;
}
- io = g_io_channel_unix_new(sk);
- g_io_channel_set_close_on_unref(io, FALSE);
- session->sock = sk;
-
- if (connect(sk, (struct sockaddr *) &l2a, sizeof(l2a)) < 0) {
- if (!(errno == EAGAIN || errno == EINPROGRESS)) {
- error("Connect failed. %s(%d)", strerror(errno),
- errno);
- g_io_channel_close(io);
- g_io_channel_unref(io);
- goto failed;
- }
-
- session->state = AVCTP_STATE_CONNECTING;
-
- g_io_add_watch(io, G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- (GIOFunc) avctp_connect_cb, session);
- } else
- avctp_connect_cb(io, G_IO_OUT, session);
-
- g_io_channel_unref(io);
-
control->session = session;
return TRUE;
-
-failed:
- avctp_unref(session);
- return FALSE;
}
void avrcp_disconnect(struct device *dev)