summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2008-05-13 18:18:02 +0000
committerLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2008-05-13 18:18:02 +0000
commitefeeab95ad87e827c2a801186754df868b598242 (patch)
treed93e46e60e4b1b686b6296857fd3d5e898fafd5a /common
parenteac653286a4619a0b28614cdde1506997e5d6023 (diff)
Introduce bt_l2cap_listen.
Diffstat (limited to 'common')
-rw-r--r--common/glib-helper.c90
-rw-r--r--common/glib-helper.h3
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);