diff options
Diffstat (limited to 'net/bluetooth/l2cap.c')
-rw-r--r-- | net/bluetooth/l2cap.c | 170 |
1 files changed, 154 insertions, 16 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 45b8697a7398..167e02532697 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -1334,7 +1334,7 @@ static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *ms | |||
1334 | return skb; | 1334 | return skb; |
1335 | } | 1335 | } |
1336 | 1336 | ||
1337 | static struct sk_buff *l2cap_create_ertm_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control) | 1337 | static struct sk_buff *l2cap_create_ertm_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen) |
1338 | { | 1338 | { |
1339 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 1339 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; |
1340 | struct sk_buff *skb; | 1340 | struct sk_buff *skb; |
@@ -1343,6 +1343,9 @@ static struct sk_buff *l2cap_create_ertm_pdu(struct sock *sk, struct msghdr *msg | |||
1343 | 1343 | ||
1344 | BT_DBG("sk %p len %d", sk, (int)len); | 1344 | BT_DBG("sk %p len %d", sk, (int)len); |
1345 | 1345 | ||
1346 | if (sdulen) | ||
1347 | hlen += 2; | ||
1348 | |||
1346 | count = min_t(unsigned int, (conn->mtu - hlen), len); | 1349 | count = min_t(unsigned int, (conn->mtu - hlen), len); |
1347 | skb = bt_skb_send_alloc(sk, count + hlen, | 1350 | skb = bt_skb_send_alloc(sk, count + hlen, |
1348 | msg->msg_flags & MSG_DONTWAIT, &err); | 1351 | msg->msg_flags & MSG_DONTWAIT, &err); |
@@ -1354,6 +1357,8 @@ static struct sk_buff *l2cap_create_ertm_pdu(struct sock *sk, struct msghdr *msg | |||
1354 | lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid); | 1357 | lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid); |
1355 | lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE)); | 1358 | lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE)); |
1356 | put_unaligned_le16(control, skb_put(skb, 2)); | 1359 | put_unaligned_le16(control, skb_put(skb, 2)); |
1360 | if (sdulen) | ||
1361 | put_unaligned_le16(sdulen, skb_put(skb, 2)); | ||
1357 | 1362 | ||
1358 | err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb); | 1363 | err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb); |
1359 | if (unlikely(err < 0)) { | 1364 | if (unlikely(err < 0)) { |
@@ -1363,6 +1368,54 @@ static struct sk_buff *l2cap_create_ertm_pdu(struct sock *sk, struct msghdr *msg | |||
1363 | return skb; | 1368 | return skb; |
1364 | } | 1369 | } |
1365 | 1370 | ||
1371 | static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len) | ||
1372 | { | ||
1373 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
1374 | struct sk_buff *skb; | ||
1375 | struct sk_buff_head sar_queue; | ||
1376 | u16 control; | ||
1377 | size_t size = 0; | ||
1378 | |||
1379 | __skb_queue_head_init(&sar_queue); | ||
1380 | control = L2CAP_SDU_START; | ||
1381 | skb = l2cap_create_ertm_pdu(sk, msg, pi->max_pdu_size, control, len); | ||
1382 | if (IS_ERR(skb)) | ||
1383 | return PTR_ERR(skb); | ||
1384 | |||
1385 | __skb_queue_tail(&sar_queue, skb); | ||
1386 | len -= pi->max_pdu_size; | ||
1387 | size +=pi->max_pdu_size; | ||
1388 | control = 0; | ||
1389 | |||
1390 | while (len > 0) { | ||
1391 | size_t buflen; | ||
1392 | |||
1393 | if (len > pi->max_pdu_size) { | ||
1394 | control |= L2CAP_SDU_CONTINUE; | ||
1395 | buflen = pi->max_pdu_size; | ||
1396 | } else { | ||
1397 | control |= L2CAP_SDU_END; | ||
1398 | buflen = len; | ||
1399 | } | ||
1400 | |||
1401 | skb = l2cap_create_ertm_pdu(sk, msg, buflen, control, 0); | ||
1402 | if (IS_ERR(skb)) { | ||
1403 | skb_queue_purge(&sar_queue); | ||
1404 | return PTR_ERR(skb); | ||
1405 | } | ||
1406 | |||
1407 | __skb_queue_tail(&sar_queue, skb); | ||
1408 | len -= buflen; | ||
1409 | size += buflen; | ||
1410 | control = 0; | ||
1411 | } | ||
1412 | skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk)); | ||
1413 | if (sk->sk_send_head == NULL) | ||
1414 | sk->sk_send_head = sar_queue.next; | ||
1415 | |||
1416 | return size; | ||
1417 | } | ||
1418 | |||
1366 | static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len) | 1419 | static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len) |
1367 | { | 1420 | { |
1368 | struct sock *sk = sock->sk; | 1421 | struct sock *sk = sock->sk; |
@@ -1415,21 +1468,22 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
1415 | 1468 | ||
1416 | case L2CAP_MODE_ERTM: | 1469 | case L2CAP_MODE_ERTM: |
1417 | /* Entire SDU fits into one PDU */ | 1470 | /* Entire SDU fits into one PDU */ |
1418 | if (len <= pi->omtu) { | 1471 | if (len <= pi->max_pdu_size) { |
1419 | control = L2CAP_SDU_UNSEGMENTED; | 1472 | control = L2CAP_SDU_UNSEGMENTED; |
1420 | skb = l2cap_create_ertm_pdu(sk, msg, len, control); | 1473 | skb = l2cap_create_ertm_pdu(sk, msg, len, control, 0); |
1421 | if (IS_ERR(skb)) { | 1474 | if (IS_ERR(skb)) { |
1422 | err = PTR_ERR(skb); | 1475 | err = PTR_ERR(skb); |
1423 | goto done; | 1476 | goto done; |
1424 | } | 1477 | } |
1478 | __skb_queue_tail(TX_QUEUE(sk), skb); | ||
1479 | if (sk->sk_send_head == NULL) | ||
1480 | sk->sk_send_head = skb; | ||
1425 | } else { | 1481 | } else { |
1426 | /* FIXME: Segmentation will be added later */ | 1482 | /* Segment SDU into multiples PDUs */ |
1427 | err = -EINVAL; | 1483 | err = l2cap_sar_segment_sdu(sk, msg, len); |
1428 | goto done; | 1484 | if (err < 0) |
1485 | goto done; | ||
1429 | } | 1486 | } |
1430 | __skb_queue_tail(TX_QUEUE(sk), skb); | ||
1431 | if (sk->sk_send_head == NULL) | ||
1432 | sk->sk_send_head = skb; | ||
1433 | 1487 | ||
1434 | err = l2cap_ertm_send(sk); | 1488 | err = l2cap_ertm_send(sk); |
1435 | if (!err) | 1489 | if (!err) |
@@ -2007,7 +2061,7 @@ done: | |||
2007 | rfc.max_transmit = L2CAP_DEFAULT_MAX_RECEIVE; | 2061 | rfc.max_transmit = L2CAP_DEFAULT_MAX_RECEIVE; |
2008 | rfc.retrans_timeout = 0; | 2062 | rfc.retrans_timeout = 0; |
2009 | rfc.monitor_timeout = 0; | 2063 | rfc.monitor_timeout = 0; |
2010 | rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_RX_APDU); | 2064 | rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE); |
2011 | 2065 | ||
2012 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | 2066 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, |
2013 | sizeof(rfc), (unsigned long) &rfc); | 2067 | sizeof(rfc), (unsigned long) &rfc); |
@@ -2019,7 +2073,7 @@ done: | |||
2019 | rfc.max_transmit = 0; | 2073 | rfc.max_transmit = 0; |
2020 | rfc.retrans_timeout = 0; | 2074 | rfc.retrans_timeout = 0; |
2021 | rfc.monitor_timeout = 0; | 2075 | rfc.monitor_timeout = 0; |
2022 | rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_RX_APDU); | 2076 | rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE); |
2023 | 2077 | ||
2024 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | 2078 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, |
2025 | sizeof(rfc), (unsigned long) &rfc); | 2079 | sizeof(rfc), (unsigned long) &rfc); |
@@ -2808,6 +2862,86 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *sk | |||
2808 | kfree_skb(skb); | 2862 | kfree_skb(skb); |
2809 | } | 2863 | } |
2810 | 2864 | ||
2865 | static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control) | ||
2866 | { | ||
2867 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
2868 | struct sk_buff *_skb; | ||
2869 | int err = -EINVAL; | ||
2870 | |||
2871 | switch (control & L2CAP_CTRL_SAR) { | ||
2872 | case L2CAP_SDU_UNSEGMENTED: | ||
2873 | if (pi->conn_state & L2CAP_CONN_SAR_SDU) { | ||
2874 | kfree_skb(pi->sdu); | ||
2875 | break; | ||
2876 | } | ||
2877 | |||
2878 | err = sock_queue_rcv_skb(sk, skb); | ||
2879 | if (!err) | ||
2880 | return 0; | ||
2881 | |||
2882 | break; | ||
2883 | |||
2884 | case L2CAP_SDU_START: | ||
2885 | if (pi->conn_state & L2CAP_CONN_SAR_SDU) { | ||
2886 | kfree_skb(pi->sdu); | ||
2887 | break; | ||
2888 | } | ||
2889 | |||
2890 | pi->sdu_len = get_unaligned_le16(skb->data); | ||
2891 | skb_pull(skb, 2); | ||
2892 | |||
2893 | pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC); | ||
2894 | if (!pi->sdu) { | ||
2895 | err = -ENOMEM; | ||
2896 | break; | ||
2897 | } | ||
2898 | |||
2899 | memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); | ||
2900 | |||
2901 | pi->conn_state |= L2CAP_CONN_SAR_SDU; | ||
2902 | pi->partial_sdu_len = skb->len; | ||
2903 | err = 0; | ||
2904 | break; | ||
2905 | |||
2906 | case L2CAP_SDU_CONTINUE: | ||
2907 | if (!(pi->conn_state & L2CAP_CONN_SAR_SDU)) | ||
2908 | break; | ||
2909 | |||
2910 | memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); | ||
2911 | |||
2912 | pi->partial_sdu_len += skb->len; | ||
2913 | if (pi->partial_sdu_len > pi->sdu_len) | ||
2914 | kfree_skb(pi->sdu); | ||
2915 | else | ||
2916 | err = 0; | ||
2917 | |||
2918 | break; | ||
2919 | |||
2920 | case L2CAP_SDU_END: | ||
2921 | if (!(pi->conn_state & L2CAP_CONN_SAR_SDU)) | ||
2922 | break; | ||
2923 | |||
2924 | memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); | ||
2925 | |||
2926 | pi->conn_state &= ~L2CAP_CONN_SAR_SDU; | ||
2927 | pi->partial_sdu_len += skb->len; | ||
2928 | |||
2929 | if (pi->partial_sdu_len == pi->sdu_len) { | ||
2930 | _skb = skb_clone(pi->sdu, GFP_ATOMIC); | ||
2931 | err = sock_queue_rcv_skb(sk, _skb); | ||
2932 | if (err < 0) | ||
2933 | kfree_skb(_skb); | ||
2934 | } | ||
2935 | kfree_skb(pi->sdu); | ||
2936 | err = 0; | ||
2937 | |||
2938 | break; | ||
2939 | } | ||
2940 | |||
2941 | kfree_skb(skb); | ||
2942 | return err; | ||
2943 | } | ||
2944 | |||
2811 | static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb) | 2945 | static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb) |
2812 | { | 2946 | { |
2813 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 2947 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
@@ -2820,11 +2954,11 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str | |||
2820 | if (tx_seq != pi->expected_tx_seq) | 2954 | if (tx_seq != pi->expected_tx_seq) |
2821 | return -EINVAL; | 2955 | return -EINVAL; |
2822 | 2956 | ||
2823 | pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64; | 2957 | err = l2cap_sar_reassembly_sdu(sk, skb, rx_control); |
2824 | err = sock_queue_rcv_skb(sk, skb); | 2958 | if (err < 0) |
2825 | if (err) | ||
2826 | return err; | 2959 | return err; |
2827 | 2960 | ||
2961 | pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64; | ||
2828 | pi->num_to_ack = (pi->num_to_ack + 1) % L2CAP_DEFAULT_NUM_TO_ACK; | 2962 | pi->num_to_ack = (pi->num_to_ack + 1) % L2CAP_DEFAULT_NUM_TO_ACK; |
2829 | if (pi->num_to_ack == L2CAP_DEFAULT_NUM_TO_ACK - 1) { | 2963 | if (pi->num_to_ack == L2CAP_DEFAULT_NUM_TO_ACK - 1) { |
2830 | tx_control |= L2CAP_CTRL_FRAME_TYPE; | 2964 | tx_control |= L2CAP_CTRL_FRAME_TYPE; |
@@ -2860,7 +2994,7 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str | |||
2860 | static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb) | 2994 | static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb) |
2861 | { | 2995 | { |
2862 | struct sock *sk; | 2996 | struct sock *sk; |
2863 | u16 control; | 2997 | u16 control, len; |
2864 | int err; | 2998 | int err; |
2865 | 2999 | ||
2866 | sk = l2cap_get_chan_by_scid(&conn->chan_list, cid); | 3000 | sk = l2cap_get_chan_by_scid(&conn->chan_list, cid); |
@@ -2891,8 +3025,12 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk | |||
2891 | case L2CAP_MODE_ERTM: | 3025 | case L2CAP_MODE_ERTM: |
2892 | control = get_unaligned_le16(skb->data); | 3026 | control = get_unaligned_le16(skb->data); |
2893 | skb_pull(skb, 2); | 3027 | skb_pull(skb, 2); |
3028 | len = skb->len; | ||
2894 | 3029 | ||
2895 | if (l2cap_pi(sk)->imtu < skb->len) | 3030 | if (__is_sar_start(control)) |
3031 | len -= 2; | ||
3032 | |||
3033 | if (len > L2CAP_DEFAULT_MAX_PDU_SIZE) | ||
2896 | goto drop; | 3034 | goto drop; |
2897 | 3035 | ||
2898 | if (__is_iframe(control)) | 3036 | if (__is_iframe(control)) |