diff options
-rw-r--r-- | include/net/bluetooth/l2cap.h | 8 | ||||
-rw-r--r-- | net/bluetooth/l2cap.c | 37 |
2 files changed, 38 insertions, 7 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index e919fca1072a..06b072fd6d54 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -190,7 +190,7 @@ struct l2cap_conf_rfc { | |||
190 | #define L2CAP_MODE_RETRANS 0x01 | 190 | #define L2CAP_MODE_RETRANS 0x01 |
191 | #define L2CAP_MODE_FLOWCTL 0x02 | 191 | #define L2CAP_MODE_FLOWCTL 0x02 |
192 | #define L2CAP_MODE_ERTM 0x03 | 192 | #define L2CAP_MODE_ERTM 0x03 |
193 | #define L2CAP_MODE_STREAM 0x04 | 193 | #define L2CAP_MODE_STREAMING 0x04 |
194 | 194 | ||
195 | struct l2cap_disconn_req { | 195 | struct l2cap_disconn_req { |
196 | __le16 dcid; | 196 | __le16 dcid; |
@@ -271,9 +271,11 @@ struct l2cap_pinfo { | |||
271 | __u16 imtu; | 271 | __u16 imtu; |
272 | __u16 omtu; | 272 | __u16 omtu; |
273 | __u16 flush_to; | 273 | __u16 flush_to; |
274 | __u8 sec_level; | 274 | __u8 mode; |
275 | __u8 fcs; | ||
276 | __u8 sec_level; | ||
275 | __u8 role_switch; | 277 | __u8 role_switch; |
276 | __u8 force_reliable; | 278 | __u8 force_reliable; |
277 | 279 | ||
278 | __u8 conf_req[64]; | 280 | __u8 conf_req[64]; |
279 | __u8 conf_len; | 281 | __u8 conf_len; |
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)) |