aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-05-03 01:31:10 -0400
committerMarcel Holtmann <marcel@holtmann.org>2009-08-22 17:50:07 -0400
commitc6b03cf986eab00e20d0dbc852b233bb83472138 (patch)
tree94fe92aafca068e3eb1cd6f4c53a3c86801fe7e0 /net
parent44dd46de325c4d47abfd1361e5d84a548edb8e42 (diff)
Bluetooth: Allow setting of L2CAP ERTM via socket option
To enable Enhanced Retransmission mode it needs to be set via a socket option. A different mode can be set on a socket, but on listen() and connect() the mode is checked and ERTM is only allowed if it is enabled via the module parameter. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/l2cap.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 810a3c1a4188..8a59e57d9df1 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -717,12 +717,16 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
717 717
718 pi->imtu = l2cap_pi(parent)->imtu; 718 pi->imtu = l2cap_pi(parent)->imtu;
719 pi->omtu = l2cap_pi(parent)->omtu; 719 pi->omtu = l2cap_pi(parent)->omtu;
720 pi->mode = l2cap_pi(parent)->mode;
721 pi->fcs = l2cap_pi(parent)->fcs;
720 pi->sec_level = l2cap_pi(parent)->sec_level; 722 pi->sec_level = l2cap_pi(parent)->sec_level;
721 pi->role_switch = l2cap_pi(parent)->role_switch; 723 pi->role_switch = l2cap_pi(parent)->role_switch;
722 pi->force_reliable = l2cap_pi(parent)->force_reliable; 724 pi->force_reliable = l2cap_pi(parent)->force_reliable;
723 } else { 725 } else {
724 pi->imtu = L2CAP_DEFAULT_MTU; 726 pi->imtu = L2CAP_DEFAULT_MTU;
725 pi->omtu = 0; 727 pi->omtu = 0;
728 pi->mode = L2CAP_MODE_BASIC;
729 pi->fcs = L2CAP_FCS_CRC16;
726 pi->sec_level = BT_SECURITY_LOW; 730 pi->sec_level = BT_SECURITY_LOW;
727 pi->role_switch = 0; 731 pi->role_switch = 0;
728 pi->force_reliable = 0; 732 pi->force_reliable = 0;
@@ -958,6 +962,18 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
958 goto done; 962 goto done;
959 } 963 }
960 964
965 switch (l2cap_pi(sk)->mode) {
966 case L2CAP_MODE_BASIC:
967 break;
968 case L2CAP_MODE_ERTM:
969 if (enable_ertm)
970 break;
971 /* fall through */
972 default:
973 err = -ENOTSUPP;
974 goto done;
975 }
976
961 switch (sk->sk_state) { 977 switch (sk->sk_state) {
962 case BT_CONNECT: 978 case BT_CONNECT:
963 case BT_CONNECT2: 979 case BT_CONNECT2:
@@ -1009,6 +1025,18 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
1009 goto done; 1025 goto done;
1010 } 1026 }
1011 1027
1028 switch (l2cap_pi(sk)->mode) {
1029 case L2CAP_MODE_BASIC:
1030 break;
1031 case L2CAP_MODE_ERTM:
1032 if (enable_ertm)
1033 break;
1034 /* fall through */
1035 default:
1036 err = -ENOTSUPP;
1037 goto done;
1038 }
1039
1012 if (!l2cap_pi(sk)->psm) { 1040 if (!l2cap_pi(sk)->psm) {
1013 bdaddr_t *src = &bt_sk(sk)->src; 1041 bdaddr_t *src = &bt_sk(sk)->src;
1014 u16 psm; 1042 u16 psm;
@@ -1259,7 +1287,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
1259 opts.imtu = l2cap_pi(sk)->imtu; 1287 opts.imtu = l2cap_pi(sk)->imtu;
1260 opts.omtu = l2cap_pi(sk)->omtu; 1288 opts.omtu = l2cap_pi(sk)->omtu;
1261 opts.flush_to = l2cap_pi(sk)->flush_to; 1289 opts.flush_to = l2cap_pi(sk)->flush_to;
1262 opts.mode = L2CAP_MODE_BASIC; 1290 opts.mode = l2cap_pi(sk)->mode;
1263 1291
1264 len = min_t(unsigned int, sizeof(opts), optlen); 1292 len = min_t(unsigned int, sizeof(opts), optlen);
1265 if (copy_from_user((char *) &opts, optval, len)) { 1293 if (copy_from_user((char *) &opts, optval, len)) {
@@ -1267,8 +1295,9 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
1267 break; 1295 break;
1268 } 1296 }
1269 1297
1270 l2cap_pi(sk)->imtu = opts.imtu; 1298 l2cap_pi(sk)->imtu = opts.imtu;
1271 l2cap_pi(sk)->omtu = opts.omtu; 1299 l2cap_pi(sk)->omtu = opts.omtu;
1300 l2cap_pi(sk)->mode = opts.mode;
1272 break; 1301 break;
1273 1302
1274 case L2CAP_LM: 1303 case L2CAP_LM:
@@ -1381,7 +1410,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
1381 opts.imtu = l2cap_pi(sk)->imtu; 1410 opts.imtu = l2cap_pi(sk)->imtu;
1382 opts.omtu = l2cap_pi(sk)->omtu; 1411 opts.omtu = l2cap_pi(sk)->omtu;
1383 opts.flush_to = l2cap_pi(sk)->flush_to; 1412 opts.flush_to = l2cap_pi(sk)->flush_to;
1384 opts.mode = L2CAP_MODE_BASIC; 1413 opts.mode = l2cap_pi(sk)->mode;
1385 1414
1386 len = min_t(unsigned int, len, sizeof(opts)); 1415 len = min_t(unsigned int, len, sizeof(opts));
1387 if (copy_to_user(optval, (char *) &opts, len)) 1416 if (copy_to_user(optval, (char *) &opts, len))