diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2008-09-10 15:34:57 +0300 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2008-09-10 15:34:57 +0300 |
commit | e93757f4c03094145b057c1557825d7652e801ef (patch) | |
tree | d6087640e82b04dbca5dffe0f66eecf406e3fbb9 /common | |
parent | e693267ede0958bd96ab8bb99e46cc51a7e7f96b (diff) |
Implement support for SCO server sockets
Diffstat (limited to 'common')
-rw-r--r-- | common/glib-helper.c | 77 | ||||
-rw-r--r-- | common/glib-helper.h | 2 |
2 files changed, 79 insertions, 0 deletions
diff --git a/common/glib-helper.c b/common/glib-helper.c index c194eb3b..82162685 100644 --- a/common/glib-helper.c +++ b/common/glib-helper.c @@ -952,6 +952,60 @@ static BtIOError rfcomm_connect(BtIO *io, BtIOFunc func) return BT_IO_SUCCESS; } +static int sco_bind(struct io_context *io_ctxt, const char *address, + uint16_t mtu, struct sockaddr_sco *addr) +{ + int err; + struct sco_options sco_opt; + + io_ctxt->fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO); + if (io_ctxt->fd < 0) + return -errno; + + if (mtu) { + socklen_t olen = sizeof(sco_opt); + memset(&sco_opt, 0, olen); + getsockopt(io_ctxt->fd, SOL_SCO, SCO_OPTIONS, &sco_opt, &olen); + sco_opt.mtu = mtu; + setsockopt(io_ctxt->fd, SOL_SCO, SCO_OPTIONS, &sco_opt, + sizeof(sco_opt)); + } + + memset(addr, 0, sizeof(*addr)); + addr->sco_family = AF_BLUETOOTH; + str2ba(address, &addr->sco_bdaddr); + + err = bind(io_ctxt->fd, (struct sockaddr *) addr, sizeof(*addr)); + if (err < 0) { + close(io_ctxt->fd); + return -errno; + } + + return 0; +} + +static BtIOError sco_listen(BtIO *io, BtIOFunc func) +{ + struct io_context *io_ctxt = io->io_ctxt; + struct sockaddr_sco addr; + BtIOError err; + + io_ctxt->func = func; + + err = sco_bind(io_ctxt, io->src, io->mtu, &addr); + if (err < 0) + return err; + + err = transport_listen(io); + if (err < 0) { + close(io_ctxt->fd); + return err; + } + + return BT_IO_SUCCESS; +} + + static int create_io_context(struct io_context **io_ctxt, BtIOFunc func, gpointer cb, gpointer resolver, gpointer user_data) { @@ -1094,6 +1148,28 @@ int bt_l2cap_connect(const bdaddr_t *src, const bdaddr_t *dst, return 0; } +GIOChannel *bt_sco_listen(const bdaddr_t *src, uint16_t mtu, + bt_io_callback_t cb, void *user_data) +{ + BtIO *io; + BtIOError err; + + io = bt_io_create(BT_IO_SCO, user_data, NULL); + if (!io) + return NULL; + + ba2str(src, io->src); + io->io_ctxt->cb = cb; + err = bt_io_listen(io, NULL, NULL); + if (err != BT_IO_SUCCESS) { + bt_io_unref(io); + return NULL; + } + + return io->io_ctxt->io; +} + + int bt_sco_connect(const bdaddr_t *src, const bdaddr_t *dst, bt_io_callback_t cb, void *user_data) { @@ -1146,6 +1222,7 @@ BtIO *bt_io_create(BtIOTransport type, gpointer user_data, GDestroyNotify notify err = create_io_context(&io->io_ctxt, NULL, NULL, sco_resolver, user_data); io->connect = sco_connect; + io->listen = sco_listen; break; default: return NULL; diff --git a/common/glib-helper.h b/common/glib-helper.h index 6b188f7f..8e12bf19 100644 --- a/common/glib-helper.h +++ b/common/glib-helper.h @@ -56,6 +56,8 @@ int bt_l2cap_connect(const bdaddr_t *src, const bdaddr_t *dst, void *user_data); int bt_sco_connect(const bdaddr_t *src, const bdaddr_t *dst, bt_io_callback_t cb, void *user_data); +GIOChannel *bt_sco_listen(const bdaddr_t *src, uint16_t mtu, + bt_io_callback_t cb, void *user_data); /* Experiemental bt_io API */ |