From efeeab95ad87e827c2a801186754df868b598242 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 13 May 2008 18:18:02 +0000 Subject: Introduce bt_l2cap_listen. --- common/glib-helper.c | 90 +++++++++++++++++++++++++++++++++++++++++++--------- common/glib-helper.h | 3 ++ 2 files changed, 78 insertions(+), 15 deletions(-) diff --git a/common/glib-helper.c b/common/glib-helper.c index 1eafbb98..798f8a64 100644 --- a/common/glib-helper.c +++ b/common/glib-helper.c @@ -515,37 +515,78 @@ static int sco_connect(struct io_context *io_ctxt, const bdaddr_t *src, return 0; } -static int l2cap_connect(struct io_context *io_ctxt, const bdaddr_t *src, - const bdaddr_t *dst, uint16_t psm, - uint16_t mtu) +static int l2cap_bind(struct io_context *io_ctxt, const bdaddr_t *src, + uint16_t psm, uint16_t mtu, uint32_t flags, + struct sockaddr_l2 *addr) { - struct l2cap_options l2o; - socklen_t olen; - struct sockaddr_l2 l2a; int sk, err; + struct l2cap_options l2o; - sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); + sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); if (sk < 0) return -errno; if (mtu) { - memset(&l2o, 0, sizeof(l2o)); - olen = sizeof(l2o); + socklen_t olen = sizeof(l2o); + memset(&l2o, 0, olen); getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen); l2o.imtu = l2o.omtu = mtu; setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)); } - memset(&l2a, 0, sizeof(l2a)); - l2a.l2_family = AF_BLUETOOTH; - bacpy(&l2a.l2_bdaddr, src); + if (flags) { + int opt = flags; + err = setsockopt(sk, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)); + if (err < 0) { + close(sk); + return -errno; + } + } + + memset(addr, 0, sizeof(*addr)); + addr->l2_family = AF_BLUETOOTH; + bacpy(&addr->l2_bdaddr, src); + addr->l2_psm = htobs(psm); - err = bind(sk, (struct sockaddr *) &l2a, sizeof(l2a)); + err = bind(sk, (struct sockaddr *) addr, sizeof(*addr)); if (err < 0) { close(sk); return -errno; } + return sk; +} + +static int l2cap_listen(struct io_context *io_ctxt, const bdaddr_t *src, + uint16_t psm, uint16_t mtu, uint32_t flags) +{ + struct sockaddr_l2 addr; + int sk, err; + + sk = l2cap_bind(io_ctxt, src, psm, mtu, flags, &addr); + if (sk < 0) + return sk; + + err = transport_listen(io_ctxt, sk); + if (err < 0) { + close(sk); + return err; + } + + return 0; +} + +static int l2cap_connect(struct io_context *io_ctxt, const bdaddr_t *src, + const bdaddr_t *dst, uint16_t psm, + uint16_t mtu) +{ + struct sockaddr_l2 l2a; + int sk, err; + + sk = l2cap_bind(io_ctxt, src, 0, mtu, 0, &l2a); + if (sk < 0) + return sk; + memset(&l2a, 0, sizeof(l2a)); l2a.l2_family = AF_BLUETOOTH; bacpy(&l2a.l2_bdaddr, dst); @@ -565,14 +606,14 @@ static int rfcomm_bind(struct io_context *io_ctxt, const bdaddr_t *src, uint8_t channel, uint32_t flags, struct sockaddr_rc *addr) { - int sk, err, opt; + int sk, err; sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); if (sk < 0) return -errno; if (flags) { - opt = flags; + int opt = flags; err = setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)); if (err < 0) { close(sk); @@ -698,6 +739,25 @@ int bt_rfcomm_connect(const bdaddr_t *src, const bdaddr_t *dst, return 0; } +GIOChannel *bt_l2cap_listen(const bdaddr_t *src, uint16_t psm, uint16_t mtu, + uint32_t flags, bt_io_callback_t cb, void *user_data) +{ + struct io_context *io_ctxt; + int err; + + err = create_io_context(&io_ctxt, cb, user_data); + if (err < 0) + return NULL; + + err = l2cap_listen(io_ctxt, src, psm, mtu, flags); + if (err < 0) { + io_context_cleanup(io_ctxt); + return NULL; + } + + return io_ctxt->io; +} + int bt_l2cap_connect(const bdaddr_t *src, const bdaddr_t *dst, uint16_t psm, uint16_t mtu, bt_io_callback_t cb, void *user_data) { diff --git a/common/glib-helper.h b/common/glib-helper.h index 71ed67b8..ddc57d4b 100644 --- a/common/glib-helper.h +++ b/common/glib-helper.h @@ -42,6 +42,9 @@ GIOChannel *bt_rfcomm_listen(const bdaddr_t *src, uint8_t channel, uint32_t flags, bt_io_callback_t cb, void *user_data); int bt_rfcomm_connect(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel, bt_io_callback_t cb, void *user_data); + +GIOChannel *bt_l2cap_listen(const bdaddr_t *src, uint16_t psm, uint16_t mtu, + uint32_t flags, bt_io_callback_t cb, void *user_data); int bt_l2cap_connect(const bdaddr_t *src, const bdaddr_t *dst, uint16_t psm, uint16_t mtu, bt_io_callback_t cb, void *user_data); -- cgit