aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorGustavo F. Padovan <gustavo@las.ic.unicamp.br>2009-08-20 21:25:58 -0400
committerMarcel Holtmann <marcel@holtmann.org>2009-08-22 17:53:58 -0400
commitc74e560cd0101455f1889515e1527e4c2e266113 (patch)
treea828b646b60578c1e90580da0d92e5d1ee7e7981 /net
parent1c2acffb76d4bc5fd27c4ea55cc27ad8ead10f9a (diff)
Bluetooth: Add support for Segmentation and Reassembly of SDUs
ERTM should use Segmentation and Reassembly to break down a SDU in many PDUs on sending data to the other side. On sending packets we queue all 'segments' until end of segmentation and just the add them to the queue for sending. On receiving we create a new SKB with the SDU reassembled. Initially based on a patch from Nathan Holstein <nathan@lampreynetworks.com> Signed-off-by: Gustavo F. Padovan <gustavo@las.ic.unicamp.br> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-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))