diff options
author | Cidorvan Leite <cidorvan.leite@openbossa.org> | 2008-04-28 19:47:29 +0000 |
---|---|---|
committer | Cidorvan Leite <cidorvan.leite@openbossa.org> | 2008-04-28 19:47:29 +0000 |
commit | 87419d4f0e86f4ed66831bfeab77dde1f829455a (patch) | |
tree | 14798346f598cd865917c2e972f5ff3bc9577812 /audio | |
parent | 615594b3d9c8a403e4f6da8aaa3a3633cae679d8 (diff) |
AVDTP l2cap connection clean up in audio plugin
Diffstat (limited to 'audio')
-rw-r--r-- | audio/avdtp.c | 98 |
1 files changed, 19 insertions, 79 deletions
diff --git a/audio/avdtp.c b/audio/avdtp.c index a92d1281..3bab1e33 100644 --- a/audio/avdtp.c +++ b/audio/avdtp.c @@ -46,6 +46,7 @@ #include "manager.h" #include "control.h" #include "avdtp.h" +#include "glib-helper.h" #include <bluetooth/l2cap.h> @@ -1506,41 +1507,29 @@ failed: return FALSE; } -static gboolean l2cap_connect_cb(GIOChannel *chan, GIOCondition cond, - gpointer data) +static void l2cap_connect_cb(GIOChannel *chan, int err, gpointer user_data) { - struct avdtp *session = data; + struct avdtp *session = user_data; struct l2cap_options l2o; socklen_t len; - int ret, err, sk; + int sk; char address[18]; - if (cond & G_IO_NVAL) - return FALSE; - if (!g_slist_find(sessions, session)) { debug("l2cap_connect_cb: session got removed"); - return FALSE; + return; } - sk = g_io_channel_unix_get_fd(chan); - - len = sizeof(ret); - if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) { - err = errno; - error("getsockopt(SO_ERROR): %s (%d)", strerror(err), err); + if (err < 0) { + error("connect(): %s (%d)", strerror(-err), -err); goto failed; } - if (ret != 0) { - err = ret; - error("connect(): %s (%d)", strerror(err), err); - goto failed; - } + sk = g_io_channel_unix_get_fd(chan); - if (cond & G_IO_HUP) { - err = EIO; - goto failed; + if (session->state == AVDTP_SESSION_STATE_DISCONNECTED) { + session->sock = sk; + session->state = AVDTP_SESSION_STATE_CONNECTING; } ba2str(&session->dst, address); @@ -1583,11 +1572,9 @@ static gboolean l2cap_connect_cb(GIOChannel *chan, GIOCondition cond, process_queue(session); - return FALSE; + return; failed: - close(sk); - if (session->pending_open) { avdtp_sep_set_state(session, session->pending_open->lsep, AVDTP_STATE_IDLE); @@ -1595,67 +1582,20 @@ failed: } else connection_lost(session, -err); - return FALSE; + return; } static int l2cap_connect(struct avdtp *session) { - struct sockaddr_l2 l2a; - GIOChannel *io; - int sk; - - memset(&l2a, 0, sizeof(l2a)); - l2a.l2_family = AF_BLUETOOTH; - bacpy(&l2a.l2_bdaddr, &session->src); - - sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); - if (sk < 0) { - error("Cannot create L2CAP socket. %s(%d)", strerror(errno), - errno); - return -errno; - } - - if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a)) < 0) { - error("Bind failed. %s (%d)", strerror(errno), errno); - return -errno; - } - - memset(&l2a, 0, sizeof(l2a)); - l2a.l2_family = AF_BLUETOOTH; - bacpy(&l2a.l2_bdaddr, &session->dst); - l2a.l2_psm = htobs(AVDTP_PSM); + int err; - if (set_nonblocking(sk) < 0) { - error("Set non blocking: %s (%d)", strerror(errno), errno); - return -errno; + err = bt_l2cap_connect(&session->src, &session->dst, htobs(AVDTP_PSM), + l2cap_connect_cb, session); + if (err < 0) { + error("Connect failed. %s(%d)", strerror(-err), -err); + return err; } - io = g_io_channel_unix_new(sk); - g_io_channel_set_close_on_unref(io, FALSE); - - 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); - return -errno; - } - - g_io_add_watch(io, G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - (GIOFunc) l2cap_connect_cb, session); - - if (session->state == AVDTP_SESSION_STATE_DISCONNECTED) { - session->sock = sk; - session->state = AVDTP_SESSION_STATE_CONNECTING; - } - - - } else - l2cap_connect_cb(io, G_IO_OUT, session); - - g_io_channel_unref(io); - return 0; } |