aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/l2cap.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/l2cap.c')
-rw-r--r--net/bluetooth/l2cap.c170
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
1337static struct sk_buff *l2cap_create_ertm_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control) 1337static 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
1371static 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
1366static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len) 1419static 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
2865static 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
2811static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb) 2945static 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
2860static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb) 2994static 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))