3
* BlueZ - Bluetooth protocol stack for Linux
5
* Copyright (C) 2009 Marcel Holtmann <marcel@holtmann.org>
6
* Copyright (C) 2009 Nokia Corporation
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 2 of the License, or
12
* (at your option) any later version.
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29
#include <sys/types.h>
30
#include <sys/socket.h>
32
#include <bluetooth/bluetooth.h>
33
#include <bluetooth/l2cap.h>
34
#include <bluetooth/rfcomm.h>
35
#include <bluetooth/sco.h>
36
#include <bluetooth/hci.h>
37
#include <bluetooth/hci_lib.h>
44
#define ERROR_FAILED(gerr, str, err) \
45
g_set_error(gerr, BT_IO_ERROR, BT_IO_ERROR_FAILED, \
46
str ": %s (%d)", strerror(err), err)
48
#define DEFAULT_DEFER_TIMEOUT 30
66
GDestroyNotify destroy;
72
GDestroyNotify destroy;
79
GDestroyNotify destroy;
82
static void server_remove(struct server *server)
85
server->destroy(server->user_data);
89
static void connect_remove(struct connect *conn)
92
conn->destroy(conn->user_data);
96
static void accept_remove(struct accept *accept)
99
accept->destroy(accept->user_data);
103
static gboolean accept_cb(GIOChannel *io, GIOCondition cond,
106
struct accept *accept = user_data;
109
/* If the user aborted this accept attempt */
110
if (cond & G_IO_NVAL)
113
if (cond & (G_IO_HUP | G_IO_ERR))
114
g_set_error(&err, BT_IO_ERROR, BT_IO_ERROR_DISCONNECTED,
115
"HUP or ERR on socket");
117
accept->connect(io, err, accept->user_data);
124
static gboolean connect_cb(GIOChannel *io, GIOCondition cond,
127
struct connect *conn = user_data;
130
/* If the user aborted this connect attempt */
131
if (cond & G_IO_NVAL)
134
if (cond & G_IO_OUT) {
135
int err = 0, sock = g_io_channel_unix_get_fd(io);
136
socklen_t len = sizeof(err);
138
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &len) < 0)
142
g_set_error(&gerr, BT_IO_ERROR,
143
BT_IO_ERROR_CONNECT_FAILED, "%s (%d)",
145
} else if (cond & (G_IO_HUP | G_IO_ERR))
146
g_set_error(&gerr, BT_IO_ERROR, BT_IO_ERROR_CONNECT_FAILED,
147
"HUP or ERR on socket");
149
conn->connect(io, gerr, conn->user_data);
157
static gboolean server_cb(GIOChannel *io, GIOCondition cond,
160
struct server *server = user_data;
161
int srv_sock, cli_sock;
164
/* If the user closed the server */
165
if (cond & G_IO_NVAL)
168
srv_sock = g_io_channel_unix_get_fd(io);
170
cli_sock = accept(srv_sock, NULL, NULL);
172
error("accept: %s (%d)", strerror(errno), errno);
176
cli_io = g_io_channel_unix_new(cli_sock);
178
g_io_channel_set_close_on_unref(cli_io, TRUE);
179
g_io_channel_set_flags(cli_io, G_IO_FLAG_NONBLOCK, NULL);
182
server->confirm(cli_io, server->user_data);
184
server->connect(cli_io, NULL, server->user_data);
186
g_io_channel_unref(cli_io);
191
static void server_add(GIOChannel *io, BtIOConnect connect,
192
BtIOConfirm confirm, gpointer user_data,
193
GDestroyNotify destroy)
195
struct server *server;
198
server = g_new0(struct server, 1);
199
server->connect = connect;
200
server->confirm = confirm;
201
server->user_data = user_data;
202
server->destroy = destroy;
204
cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
205
g_io_add_watch_full(io, G_PRIORITY_DEFAULT, cond, server_cb, server,
206
(GDestroyNotify) server_remove);
209
static void connect_add(GIOChannel *io, BtIOConnect connect,
210
gpointer user_data, GDestroyNotify destroy)
212
struct connect *conn;
215
conn = g_new0(struct connect, 1);
216
conn->connect = connect;
217
conn->user_data = user_data;
218
conn->destroy = destroy;
220
cond = G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
221
g_io_add_watch_full(io, G_PRIORITY_DEFAULT, cond, connect_cb, conn,
222
(GDestroyNotify) connect_remove);
225
static void accept_add(GIOChannel *io, BtIOConnect connect, gpointer user_data,
226
GDestroyNotify destroy)
228
struct accept *accept;
231
accept = g_new0(struct accept, 1);
232
accept->connect = connect;
233
accept->user_data = user_data;
234
accept->destroy = destroy;
236
cond = G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
237
g_io_add_watch_full(io, G_PRIORITY_DEFAULT, cond, accept_cb, accept,
238
(GDestroyNotify) accept_remove);
241
static int l2cap_bind(int sock, const bdaddr_t *src, uint16_t psm)
243
struct sockaddr_l2 addr;
245
memset(&addr, 0, sizeof(addr));
246
addr.l2_family = AF_BLUETOOTH;
247
bacpy(&addr.l2_bdaddr, src);
248
addr.l2_psm = htobs(psm);
250
return bind(sock, (struct sockaddr *) &addr, sizeof(addr));
253
static int l2cap_connect(int sock, const bdaddr_t *dst, uint16_t psm)
256
struct sockaddr_l2 addr;
258
memset(&addr, 0, sizeof(addr));
259
addr.l2_family = AF_BLUETOOTH;
260
bacpy(&addr.l2_bdaddr, dst);
261
addr.l2_psm = htobs(psm);
263
err = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
264
if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS))
270
static int l2cap_set_master(int sock, int master)
276
if (getsockopt(sock, SOL_L2CAP, L2CAP_LM, &flags, &len) < 0)
280
if (flags & L2CAP_LM_MASTER)
282
flags |= L2CAP_LM_MASTER;
284
if (!(flags & L2CAP_LM_MASTER))
286
flags &= ~L2CAP_LM_MASTER;
289
if (setsockopt(sock, SOL_L2CAP, L2CAP_LM, &flags, sizeof(flags)) < 0)
295
static int rfcomm_set_master(int sock, int master)
301
if (getsockopt(sock, SOL_RFCOMM, RFCOMM_LM, &flags, &len) < 0)
305
if (flags & RFCOMM_LM_MASTER)
307
flags |= RFCOMM_LM_MASTER;
309
if (!(flags & RFCOMM_LM_MASTER))
311
flags &= ~RFCOMM_LM_MASTER;
314
if (setsockopt(sock, SOL_RFCOMM, RFCOMM_LM, &flags, sizeof(flags)) < 0)
320
static int l2cap_set_lm(int sock, int level)
325
L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT,
326
L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE,
327
}, opt = lm_map[level];
329
if (setsockopt(sock, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0)
335
static int rfcomm_set_lm(int sock, int level)
340
RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT,
341
RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE,
342
}, opt = lm_map[level];
344
if (setsockopt(sock, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0)
350
static gboolean set_sec_level(int sock, BtIOType type, int level, GError **err)
352
struct bt_security sec;
355
if (level < BT_SECURITY_LOW || level > BT_SECURITY_HIGH) {
356
g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
357
"Valid security level range is %d-%d",
358
BT_SECURITY_LOW, BT_SECURITY_HIGH);
362
memset(&sec, 0, sizeof(sec));
365
if (setsockopt(sock, SOL_BLUETOOTH, BT_SECURITY, &sec,
369
if (errno != ENOPROTOOPT) {
370
ERROR_FAILED(err, "setsockopt(BT_SECURITY)", errno);
374
if (type == BT_IO_L2CAP)
375
ret = l2cap_set_lm(sock, level);
377
ret = rfcomm_set_lm(sock, level);
380
ERROR_FAILED(err, "setsockopt(LM)", -ret);
387
static int l2cap_get_lm(int sock, int *sec_level)
393
if (getsockopt(sock, SOL_L2CAP, L2CAP_LM, &opt, &len) < 0)
398
if (opt & L2CAP_LM_AUTH)
399
*sec_level = BT_SECURITY_LOW;
400
if (opt & L2CAP_LM_ENCRYPT)
401
*sec_level = BT_SECURITY_MEDIUM;
402
if (opt & L2CAP_LM_SECURE)
403
*sec_level = BT_SECURITY_HIGH;
408
static int rfcomm_get_lm(int sock, int *sec_level)
414
if (getsockopt(sock, SOL_RFCOMM, RFCOMM_LM, &opt, &len) < 0)
419
if (opt & RFCOMM_LM_AUTH)
420
*sec_level = BT_SECURITY_LOW;
421
if (opt & RFCOMM_LM_ENCRYPT)
422
*sec_level = BT_SECURITY_MEDIUM;
423
if (opt & RFCOMM_LM_SECURE)
424
*sec_level = BT_SECURITY_HIGH;
429
static gboolean get_sec_level(int sock, BtIOType type, int *level,
432
struct bt_security sec;
436
memset(&sec, 0, sizeof(sec));
438
if (getsockopt(sock, SOL_BLUETOOTH, BT_SECURITY, &sec, &len) == 0) {
443
if (errno != ENOPROTOOPT) {
444
ERROR_FAILED(err, "getsockopt(BT_SECURITY)", errno);
448
if (type == BT_IO_L2CAP)
449
ret = l2cap_get_lm(sock, level);
451
ret = rfcomm_get_lm(sock, level);
454
ERROR_FAILED(err, "getsockopt(LM)", -ret);
461
static gboolean l2cap_set(int sock, int sec_level, uint16_t imtu,
462
uint16_t omtu, int master, GError **err)
465
struct l2cap_options l2o;
468
memset(&l2o, 0, sizeof(l2o));
470
if (getsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, &l2o,
472
ERROR_FAILED(err, "getsockopt(L2CAP_OPTIONS)", errno);
481
if (setsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, &l2o,
483
ERROR_FAILED(err, "setsockopt(L2CAP_OPTIONS)", errno);
488
if (master >= 0 && l2cap_set_master(sock, master) < 0) {
489
ERROR_FAILED(err, "l2cap_set_master", errno);
493
if (sec_level && !set_sec_level(sock, BT_IO_L2CAP, sec_level, err))
499
static int rfcomm_bind(int sock, const bdaddr_t *src, uint8_t channel)
501
struct sockaddr_rc addr;
503
memset(&addr, 0, sizeof(addr));
504
addr.rc_family = AF_BLUETOOTH;
505
bacpy(&addr.rc_bdaddr, src);
506
addr.rc_channel = channel;
508
return bind(sock, (struct sockaddr *) &addr, sizeof(addr));
511
static int rfcomm_connect(int sock, const bdaddr_t *dst, uint8_t channel)
514
struct sockaddr_rc addr;
516
memset(&addr, 0, sizeof(addr));
517
addr.rc_family = AF_BLUETOOTH;
518
bacpy(&addr.rc_bdaddr, dst);
519
addr.rc_channel = channel;
521
err = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
522
if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS))
528
static gboolean rfcomm_set(int sock, int sec_level, int master, GError **err)
530
if (sec_level && !set_sec_level(sock, BT_IO_RFCOMM, sec_level, err))
533
if (master >= 0 && rfcomm_set_master(sock, master) < 0) {
534
ERROR_FAILED(err, "rfcomm_set_master", errno);
541
static int sco_bind(int sock, const bdaddr_t *src)
543
struct sockaddr_sco addr;
545
memset(&addr, 0, sizeof(addr));
546
addr.sco_family = AF_BLUETOOTH;
547
bacpy(&addr.sco_bdaddr, src);
549
return bind(sock, (struct sockaddr *) &addr, sizeof(addr));
552
static int sco_connect(int sock, const bdaddr_t *dst)
554
struct sockaddr_sco addr;
557
memset(&addr, 0, sizeof(addr));
558
addr.sco_family = AF_BLUETOOTH;
559
bacpy(&addr.sco_bdaddr, dst);
561
err = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
562
if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS))
568
static gboolean sco_set(int sock, uint16_t mtu, GError **err)
570
struct sco_options sco_opt;
576
memset(&sco_opt, 0, len);
577
len = sizeof(sco_opt);
578
if (getsockopt(sock, SOL_SCO, SCO_OPTIONS, &sco_opt, &len) < 0) {
579
ERROR_FAILED(err, "getsockopt(SCO_OPTIONS)", errno);
584
if (setsockopt(sock, SOL_SCO, SCO_OPTIONS, &sco_opt,
585
sizeof(sco_opt)) < 0) {
586
ERROR_FAILED(err, "setsockopt(SCO_OPTIONS)", errno);
593
static gboolean parse_set_opts(struct set_opts *opts, GError **err,
594
BtIOOption opt1, va_list args)
596
BtIOOption opt = opt1;
599
memset(opts, 0, sizeof(*opts));
602
opts->defer = DEFAULT_DEFER_TIMEOUT;
605
while (opt != BT_IO_OPT_INVALID) {
607
case BT_IO_OPT_SOURCE:
608
str = va_arg(args, const char *);
609
if (strncasecmp(str, "hci", 3) == 0)
610
hci_devba(atoi(str + 3), &opts->src);
612
str2ba(str, &opts->src);
614
case BT_IO_OPT_SOURCE_BDADDR:
615
bacpy(&opts->src, va_arg(args, const bdaddr_t *));
618
str2ba(va_arg(args, const char *), &opts->dst);
620
case BT_IO_OPT_DEST_BDADDR:
621
bacpy(&opts->dst, va_arg(args, const bdaddr_t *));
623
case BT_IO_OPT_DEFER_TIMEOUT:
624
opts->defer = va_arg(args, int);
626
case BT_IO_OPT_SEC_LEVEL:
627
opts->sec_level = va_arg(args, int);
629
case BT_IO_OPT_CHANNEL:
630
opts->channel = va_arg(args, int);
633
opts->psm = va_arg(args, int);
636
opts->mtu = va_arg(args, int);
637
opts->imtu = opts->mtu;
638
opts->omtu = opts->mtu;
641
opts->omtu = va_arg(args, int);
643
opts->mtu = opts->omtu;
646
opts->imtu = va_arg(args, int);
648
opts->mtu = opts->imtu;
650
case BT_IO_OPT_MASTER:
651
opts->master = va_arg(args, gboolean);
654
g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
655
"Unknown option %d", opt);
659
opt = va_arg(args, int);
665
static gboolean get_peers(int sock, struct sockaddr *src, struct sockaddr *dst,
666
socklen_t len, GError **err)
672
if (getsockname(sock, src, &olen) < 0) {
673
ERROR_FAILED(err, "getsockname", errno);
679
if (getpeername(sock, dst, &olen) < 0) {
680
ERROR_FAILED(err, "getpeername", errno);
687
static int l2cap_get_info(int sock, uint16_t *handle, uint8_t *dev_class)
689
struct l2cap_conninfo info;
693
if (getsockopt(sock, SOL_L2CAP, L2CAP_CONNINFO, &info, &len) < 0)
697
*handle = info.hci_handle;
700
memcpy(dev_class, info.dev_class, 3);
705
static gboolean l2cap_get(int sock, GError **err, BtIOOption opt1,
708
BtIOOption opt = opt1;
709
struct sockaddr_l2 src, dst;
710
struct l2cap_options l2o;
712
uint8_t dev_class[3];
717
memset(&l2o, 0, len);
718
if (getsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &len) < 0) {
719
ERROR_FAILED(err, "getsockopt(L2CAP_OPTIONS)", errno);
723
if (!get_peers(sock, (struct sockaddr *) &src,
724
(struct sockaddr *) &dst, sizeof(src), err))
727
if (l2cap_get_info(sock, &handle, dev_class) < 0) {
728
ERROR_FAILED(err, "L2CAP_CONNINFO", errno);
732
while (opt != BT_IO_OPT_INVALID) {
734
case BT_IO_OPT_SOURCE:
735
ba2str(&src.l2_bdaddr, va_arg(args, char *));
737
case BT_IO_OPT_SOURCE_BDADDR:
738
bacpy(va_arg(args, bdaddr_t *), &src.l2_bdaddr);
741
ba2str(&dst.l2_bdaddr, va_arg(args, char *));
743
case BT_IO_OPT_DEST_BDADDR:
744
bacpy(va_arg(args, bdaddr_t *), &dst.l2_bdaddr);
746
case BT_IO_OPT_DEFER_TIMEOUT:
748
if (getsockopt(sock, SOL_BLUETOOTH, BT_DEFER_SETUP,
749
va_arg(args, int *), &len) < 0) {
750
ERROR_FAILED(err, "getsockopt(DEFER_SETUP)",
755
case BT_IO_OPT_SEC_LEVEL:
756
if (!get_sec_level(sock, BT_IO_L2CAP,
757
va_arg(args, int *), err))
761
*(va_arg(args, uint16_t *)) = src.l2_psm ?
762
src.l2_psm : dst.l2_psm;
765
*(va_arg(args, uint16_t *)) = l2o.omtu;
768
*(va_arg(args, uint16_t *)) = l2o.imtu;
770
case BT_IO_OPT_MASTER:
772
if (getsockopt(sock, SOL_L2CAP, L2CAP_LM, &flags,
774
ERROR_FAILED(err, "getsockopt(L2CAP_LM)",
778
*(va_arg(args, gboolean *)) =
779
(flags & L2CAP_LM_MASTER) ? TRUE : FALSE;
781
case BT_IO_OPT_HANDLE:
782
*(va_arg(args, uint16_t *)) = handle;
784
case BT_IO_OPT_CLASS:
785
memcpy(va_arg(args, uint8_t *), dev_class, 3);
788
g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
789
"Unknown option %d", opt);
793
opt = va_arg(args, int);
799
static int rfcomm_get_info(int sock, uint16_t *handle, uint8_t *dev_class)
801
struct rfcomm_conninfo info;
805
if (getsockopt(sock, SOL_RFCOMM, RFCOMM_CONNINFO, &info, &len) < 0)
809
*handle = info.hci_handle;
812
memcpy(dev_class, info.dev_class, 3);
817
static gboolean rfcomm_get(int sock, GError **err, BtIOOption opt1,
820
BtIOOption opt = opt1;
821
struct sockaddr_rc src, dst;
824
uint8_t dev_class[3];
827
if (!get_peers(sock, (struct sockaddr *) &src,
828
(struct sockaddr *) &dst, sizeof(src), err))
831
if (rfcomm_get_info(sock, &handle, dev_class) < 0) {
832
ERROR_FAILED(err, "RFCOMM_CONNINFO", errno);
836
while (opt != BT_IO_OPT_INVALID) {
838
case BT_IO_OPT_SOURCE:
839
ba2str(&src.rc_bdaddr, va_arg(args, char *));
841
case BT_IO_OPT_SOURCE_BDADDR:
842
bacpy(va_arg(args, bdaddr_t *), &src.rc_bdaddr);
845
ba2str(&dst.rc_bdaddr, va_arg(args, char *));
847
case BT_IO_OPT_DEST_BDADDR:
848
bacpy(va_arg(args, bdaddr_t *), &dst.rc_bdaddr);
850
case BT_IO_OPT_DEFER_TIMEOUT:
852
if (getsockopt(sock, SOL_BLUETOOTH, BT_DEFER_SETUP,
853
va_arg(args, int *), &len) < 0) {
854
ERROR_FAILED(err, "getsockopt(DEFER_SETUP)",
859
case BT_IO_OPT_SEC_LEVEL:
860
if (!get_sec_level(sock, BT_IO_RFCOMM,
861
va_arg(args, int *), err))
864
case BT_IO_OPT_CHANNEL:
865
*(va_arg(args, uint8_t *)) = src.rc_channel ?
866
src.rc_channel : dst.rc_channel;
868
case BT_IO_OPT_MASTER:
870
if (getsockopt(sock, SOL_RFCOMM, RFCOMM_LM, &flags,
872
ERROR_FAILED(err, "getsockopt(RFCOMM_LM)",
876
*(va_arg(args, gboolean *)) =
877
(flags & RFCOMM_LM_MASTER) ? TRUE : FALSE;
879
case BT_IO_OPT_HANDLE:
880
*(va_arg(args, uint16_t *)) = handle;
882
case BT_IO_OPT_CLASS:
883
memcpy(va_arg(args, uint8_t *), dev_class, 3);
886
g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
887
"Unknown option %d", opt);
891
opt = va_arg(args, int);
897
static int sco_get_info(int sock, uint16_t *handle, uint8_t *dev_class)
899
struct sco_conninfo info;
903
if (getsockopt(sock, SOL_SCO, SCO_CONNINFO, &info, &len) < 0)
907
*handle = info.hci_handle;
910
memcpy(dev_class, info.dev_class, 3);
915
static gboolean sco_get(int sock, GError **err, BtIOOption opt1, va_list args)
917
BtIOOption opt = opt1;
918
struct sockaddr_sco src, dst;
919
struct sco_options sco_opt;
921
uint8_t dev_class[3];
924
len = sizeof(sco_opt);
925
memset(&sco_opt, 0, len);
926
if (getsockopt(sock, SOL_SCO, SCO_OPTIONS, &sco_opt, &len) < 0) {
927
ERROR_FAILED(err, "getsockopt(SCO_OPTIONS)", errno);
931
if (!get_peers(sock, (struct sockaddr *) &src,
932
(struct sockaddr *) &dst, sizeof(src), err))
935
if (sco_get_info(sock, &handle, dev_class) < 0) {
936
ERROR_FAILED(err, "RFCOMM_CONNINFO", errno);
940
while (opt != BT_IO_OPT_INVALID) {
942
case BT_IO_OPT_SOURCE:
943
ba2str(&src.sco_bdaddr, va_arg(args, char *));
945
case BT_IO_OPT_SOURCE_BDADDR:
946
bacpy(va_arg(args, bdaddr_t *), &src.sco_bdaddr);
949
ba2str(&dst.sco_bdaddr, va_arg(args, char *));
951
case BT_IO_OPT_DEST_BDADDR:
952
bacpy(va_arg(args, bdaddr_t *), &dst.sco_bdaddr);
957
*(va_arg(args, uint16_t *)) = sco_opt.mtu;
959
case BT_IO_OPT_HANDLE:
960
*(va_arg(args, uint16_t *)) = handle;
962
case BT_IO_OPT_CLASS:
963
memcpy(va_arg(args, uint8_t *), dev_class, 3);
966
g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
967
"Unknown option %d", opt);
971
opt = va_arg(args, int);
977
static gboolean get_valist(GIOChannel *io, BtIOType type, GError **err,
978
BtIOOption opt1, va_list args)
982
sock = g_io_channel_unix_get_fd(io);
987
return l2cap_get(sock, err, opt1, args);
989
return rfcomm_get(sock, err, opt1, args);
991
return sco_get(sock, err, opt1, args);
994
g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
995
"Unknown BtIO type %d", type);
999
gboolean bt_io_accept(GIOChannel *io, BtIOConnect connect, gpointer user_data,
1000
GDestroyNotify destroy, GError **err)
1006
sock = g_io_channel_unix_get_fd(io);
1008
memset(&pfd, 0, sizeof(pfd));
1010
pfd.events = POLLOUT;
1012
if (poll(&pfd, 1, 0) < 0) {
1013
ERROR_FAILED(err, "poll", errno);
1017
if (!(pfd.revents & POLLOUT)) {
1019
ret = read(sock, &c, 1);
1022
accept_add(io, connect, user_data, destroy);
1027
gboolean bt_io_set(GIOChannel *io, BtIOType type, GError **err,
1028
BtIOOption opt1, ...)
1032
struct set_opts opts;
1035
va_start(args, opt1);
1036
ret = parse_set_opts(&opts, err, opt1, args);
1042
sock = g_io_channel_unix_get_fd(io);
1047
return l2cap_set(sock, opts.sec_level, opts.imtu, opts.omtu,
1050
return rfcomm_set(sock, opts.sec_level, opts.master, err);
1052
return sco_set(sock, opts.mtu, err);
1055
g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
1056
"Unknown BtIO type %d", type);
1060
gboolean bt_io_get(GIOChannel *io, BtIOType type, GError **err,
1061
BtIOOption opt1, ...)
1066
va_start(args, opt1);
1067
ret = get_valist(io, type, err, opt1, args);
1073
static GIOChannel *create_io(BtIOType type, gboolean server,
1074
struct set_opts *opts, GError **err)
1081
sock = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP);
1083
ERROR_FAILED(err, "socket(RAW, L2CAP)", errno);
1086
if (l2cap_bind(sock, &opts->src, server ? opts->psm : 0) < 0) {
1087
ERROR_FAILED(err, "l2cap_bind", errno);
1090
if (!l2cap_set(sock, opts->sec_level, 0, 0, -1, err))
1094
sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
1096
ERROR_FAILED(err, "socket(SEQPACKET, L2CAP)", errno);
1099
if (l2cap_bind(sock, &opts->src, server ? opts->psm : 0) < 0) {
1100
ERROR_FAILED(err, "l2cap_bind", errno);
1103
if (!l2cap_set(sock, opts->sec_level, opts->imtu, opts->omtu,
1108
sock = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1110
ERROR_FAILED(err, "socket(STREAM, RFCOMM)", errno);
1113
if (rfcomm_bind(sock, &opts->src,
1114
server ? opts->channel : 0) < 0) {
1115
ERROR_FAILED(err, "rfcomm_bind", errno);
1118
if (!rfcomm_set(sock, opts->sec_level, opts->master, err))
1122
sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
1124
ERROR_FAILED(err, "socket(SEQPACKET, SCO)", errno);
1127
if (sco_bind(sock, &opts->src) < 0) {
1128
ERROR_FAILED(err, "sco_bind", errno);
1131
if (!sco_set(sock, opts->mtu, err))
1135
g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
1136
"Unknown BtIO type %d", type);
1140
io = g_io_channel_unix_new(sock);
1142
g_io_channel_set_close_on_unref(io, TRUE);
1143
g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
1148
GIOChannel *bt_io_connect(BtIOType type, BtIOConnect connect,
1149
gpointer user_data, GDestroyNotify destroy,
1150
GError **gerr, BtIOOption opt1, ...)
1154
struct set_opts opts;
1158
va_start(args, opt1);
1159
ret = parse_set_opts(&opts, gerr, opt1, args);
1165
io = create_io(type, FALSE, &opts, gerr);
1169
sock = g_io_channel_unix_get_fd(io);
1173
err = l2cap_connect(sock, &opts.dst, 0);
1176
err = l2cap_connect(sock, &opts.dst, opts.psm);
1179
err = rfcomm_connect(sock, &opts.dst, opts.channel);
1182
err = sco_connect(sock, &opts.dst);
1185
g_set_error(gerr, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
1186
"Unknown BtIO type %d", type);
1191
g_set_error(gerr, BT_IO_ERROR, BT_IO_ERROR_CONNECT_FAILED,
1192
"connect: %s (%d)", strerror(-err), -err);
1193
g_io_channel_unref(io);
1197
connect_add(io, connect, user_data, destroy);
1202
GIOChannel *bt_io_listen(BtIOType type, BtIOConnect connect,
1203
BtIOConfirm confirm, gpointer user_data,
1204
GDestroyNotify destroy, GError **err,
1205
BtIOOption opt1, ...)
1209
struct set_opts opts;
1213
if (type == BT_IO_L2RAW) {
1214
g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
1215
"Server L2CAP RAW sockets not supported");
1219
va_start(args, opt1);
1220
ret = parse_set_opts(&opts, err, opt1, args);
1226
io = create_io(type, TRUE, &opts, err);
1230
sock = g_io_channel_unix_get_fd(io);
1233
setsockopt(sock, SOL_BLUETOOTH, BT_DEFER_SETUP, &opts.defer,
1234
sizeof(opts.defer));
1236
if (listen(sock, 5) < 0) {
1237
ERROR_FAILED(err, "listen", errno);
1238
g_io_channel_unref(io);
1242
server_add(io, connect, confirm, user_data, destroy);
1247
GQuark bt_io_error_quark(void)
1249
return g_quark_from_static_string("bt-io-error-quark");