aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--include/net/bluetooth/l2cap.h9
-rw-r--r--net/bluetooth/l2cap.c170
2 files changed, 162 insertions, 17 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 9bbfbe74d400..0afde8d22b56 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -34,7 +34,7 @@
34#define L2CAP_DEFAULT_MAX_RECEIVE 1 34#define L2CAP_DEFAULT_MAX_RECEIVE 1
35#define L2CAP_DEFAULT_RETRANS_TO 300 /* 300 milliseconds */ 35#define L2CAP_DEFAULT_RETRANS_TO 300 /* 300 milliseconds */
36#define L2CAP_DEFAULT_MONITOR_TO 1000 /* 1 second */ 36#define L2CAP_DEFAULT_MONITOR_TO 1000 /* 1 second */
37#define L2CAP_DEFAULT_MAX_RX_APDU 0xfff7 37#define L2CAP_DEFAULT_MAX_PDU_SIZE 672
38 38
39#define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */ 39#define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */
40#define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */ 40#define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */
@@ -311,6 +311,7 @@ struct l2cap_pinfo {
311 __u8 conf_req[64]; 311 __u8 conf_req[64];
312 __u8 conf_len; 312 __u8 conf_len;
313 __u8 conf_state; 313 __u8 conf_state;
314 __u8 conn_state;
314 315
315 __u8 next_tx_seq; 316 __u8 next_tx_seq;
316 __u8 expected_ack_seq; 317 __u8 expected_ack_seq;
@@ -318,6 +319,9 @@ struct l2cap_pinfo {
318 __u8 expected_tx_seq; 319 __u8 expected_tx_seq;
319 __u8 unacked_frames; 320 __u8 unacked_frames;
320 __u8 num_to_ack; 321 __u8 num_to_ack;
322 __u16 sdu_len;
323 __u16 partial_sdu_len;
324 struct sk_buff *sdu;
321 325
322 __u8 ident; 326 __u8 ident;
323 327
@@ -346,6 +350,8 @@ struct l2cap_pinfo {
346#define L2CAP_CONF_MAX_CONF_REQ 2 350#define L2CAP_CONF_MAX_CONF_REQ 2
347#define L2CAP_CONF_MAX_CONF_RSP 2 351#define L2CAP_CONF_MAX_CONF_RSP 2
348 352
353#define L2CAP_CONN_SAR_SDU 0x01
354
349static inline int l2cap_tx_window_full(struct sock *sk) 355static inline int l2cap_tx_window_full(struct sock *sk)
350{ 356{
351 struct l2cap_pinfo *pi = l2cap_pi(sk); 357 struct l2cap_pinfo *pi = l2cap_pi(sk);
@@ -363,6 +369,7 @@ static inline int l2cap_tx_window_full(struct sock *sk)
363#define __get_reqseq(ctrl) ((ctrl) & L2CAP_CTRL_REQSEQ) >> 8 369#define __get_reqseq(ctrl) ((ctrl) & L2CAP_CTRL_REQSEQ) >> 8
364#define __is_iframe(ctrl) !((ctrl) & L2CAP_CTRL_FRAME_TYPE) 370#define __is_iframe(ctrl) !((ctrl) & L2CAP_CTRL_FRAME_TYPE)
365#define __is_sframe(ctrl) (ctrl) & L2CAP_CTRL_FRAME_TYPE 371#define __is_sframe(ctrl) (ctrl) & L2CAP_CTRL_FRAME_TYPE
372#define __is_sar_start(ctrl) ((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START
366 373
367void l2cap_load(void); 374void l2cap_load(void);
368 375
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))