aboutsummaryrefslogtreecommitdiffstats
path: root/include/net
diff options
context:
space:
mode:
authorGustavo F. Padovan <gustavo@las.ic.unicamp.br>2009-08-20 21:25:57 -0400
committerMarcel Holtmann <marcel@holtmann.org>2009-08-22 17:53:01 -0400
commit1c2acffb76d4bc5fd27c4ea55cc27ad8ead10f9a (patch)
treec196f2acec0fa0ace48483ec99a691b4230f53d2 /include/net
parent22121fc9152ca8f25a2d790860832ccb6a414c4d (diff)
Bluetooth: Add initial support for ERTM packets transfers
This patch adds support for ERTM transfers, without retransmission, with txWindow up to 63 and with acknowledgement of packets received. Now the packets are queued before call l2cap_do_send(), so packets couldn't be sent at the time we call l2cap_sock_sendmsg(). They will be sent in an asynchronous way on later calls of l2cap_ertm_send(). Besides if an error occurs on calling l2cap_do_send() we disconnect the channel. 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 'include/net')
-rw-r--r--include/net/bluetooth/bluetooth.h3
-rw-r--r--include/net/bluetooth/l2cap.h54
2 files changed, 55 insertions, 2 deletions
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 968166a45f86..65a5cf868fd6 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -138,8 +138,9 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock);
138struct bt_skb_cb { 138struct bt_skb_cb {
139 __u8 pkt_type; 139 __u8 pkt_type;
140 __u8 incoming; 140 __u8 incoming;
141 __u8 tx_seq;
141}; 142};
142#define bt_cb(skb) ((struct bt_skb_cb *)(skb->cb)) 143#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
143 144
144static inline struct sk_buff *bt_skb_alloc(unsigned int len, gfp_t how) 145static inline struct sk_buff *bt_skb_alloc(unsigned int len, gfp_t how)
145{ 146{
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 6fc76986d70a..9bbfbe74d400 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -29,7 +29,8 @@
29#define L2CAP_DEFAULT_MTU 672 29#define L2CAP_DEFAULT_MTU 672
30#define L2CAP_DEFAULT_MIN_MTU 48 30#define L2CAP_DEFAULT_MIN_MTU 48
31#define L2CAP_DEFAULT_FLUSH_TO 0xffff 31#define L2CAP_DEFAULT_FLUSH_TO 0xffff
32#define L2CAP_DEFAULT_TX_WINDOW 1 32#define L2CAP_DEFAULT_TX_WINDOW 63
33#define L2CAP_DEFAULT_NUM_TO_ACK (L2CAP_DEFAULT_TX_WINDOW/5)
33#define L2CAP_DEFAULT_MAX_RECEIVE 1 34#define L2CAP_DEFAULT_MAX_RECEIVE 1
34#define L2CAP_DEFAULT_RETRANS_TO 300 /* 300 milliseconds */ 35#define L2CAP_DEFAULT_RETRANS_TO 300 /* 300 milliseconds */
35#define L2CAP_DEFAULT_MONITOR_TO 1000 /* 1 second */ 36#define L2CAP_DEFAULT_MONITOR_TO 1000 /* 1 second */
@@ -94,6 +95,31 @@ struct l2cap_conninfo {
94#define L2CAP_FCS_NONE 0x00 95#define L2CAP_FCS_NONE 0x00
95#define L2CAP_FCS_CRC16 0x01 96#define L2CAP_FCS_CRC16 0x01
96 97
98/* L2CAP Control Field bit masks */
99#define L2CAP_CTRL_SAR 0xC000
100#define L2CAP_CTRL_REQSEQ 0x3F00
101#define L2CAP_CTRL_TXSEQ 0x007E
102#define L2CAP_CTRL_RETRANS 0x0080
103#define L2CAP_CTRL_FINAL 0x0080
104#define L2CAP_CTRL_POLL 0x0010
105#define L2CAP_CTRL_SUPERVISE 0x000C
106#define L2CAP_CTRL_FRAME_TYPE 0x0001 /* I- or S-Frame */
107
108#define L2CAP_CTRL_TXSEQ_SHIFT 1
109#define L2CAP_CTRL_REQSEQ_SHIFT 8
110
111/* L2CAP Supervisory Function */
112#define L2CAP_SUPER_RCV_READY 0x0000
113#define L2CAP_SUPER_REJECT 0x0004
114#define L2CAP_SUPER_RCV_NOT_READY 0x0008
115#define L2CAP_SUPER_SELECT_REJECT 0x000C
116
117/* L2CAP Segmentation and Reassembly */
118#define L2CAP_SDU_UNSEGMENTED 0x0000
119#define L2CAP_SDU_START 0x4000
120#define L2CAP_SDU_END 0x8000
121#define L2CAP_SDU_CONTINUE 0xC000
122
97/* L2CAP structures */ 123/* L2CAP structures */
98struct l2cap_hdr { 124struct l2cap_hdr {
99 __le16 len; 125 __le16 len;
@@ -262,6 +288,7 @@ struct l2cap_conn {
262 288
263/* ----- L2CAP channel and socket info ----- */ 289/* ----- L2CAP channel and socket info ----- */
264#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk) 290#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
291#define TX_QUEUE(sk) (&l2cap_pi(sk)->tx_queue)
265 292
266struct l2cap_pinfo { 293struct l2cap_pinfo {
267 struct bt_sock bt; 294 struct bt_sock bt;
@@ -285,6 +312,13 @@ struct l2cap_pinfo {
285 __u8 conf_len; 312 __u8 conf_len;
286 __u8 conf_state; 313 __u8 conf_state;
287 314
315 __u8 next_tx_seq;
316 __u8 expected_ack_seq;
317 __u8 req_seq;
318 __u8 expected_tx_seq;
319 __u8 unacked_frames;
320 __u8 num_to_ack;
321
288 __u8 ident; 322 __u8 ident;
289 323
290 __u8 remote_tx_win; 324 __u8 remote_tx_win;
@@ -295,6 +329,7 @@ struct l2cap_pinfo {
295 329
296 __le16 sport; 330 __le16 sport;
297 331
332 struct sk_buff_head tx_queue;
298 struct l2cap_conn *conn; 333 struct l2cap_conn *conn;
299 struct sock *next_c; 334 struct sock *next_c;
300 struct sock *prev_c; 335 struct sock *prev_c;
@@ -311,6 +346,23 @@ struct l2cap_pinfo {
311#define L2CAP_CONF_MAX_CONF_REQ 2 346#define L2CAP_CONF_MAX_CONF_REQ 2
312#define L2CAP_CONF_MAX_CONF_RSP 2 347#define L2CAP_CONF_MAX_CONF_RSP 2
313 348
349static inline int l2cap_tx_window_full(struct sock *sk)
350{
351 struct l2cap_pinfo *pi = l2cap_pi(sk);
352 int sub;
353
354 sub = (pi->next_tx_seq - pi->expected_ack_seq) % 64;
355
356 if (sub < 0)
357 sub += 64;
358
359 return (sub == pi->remote_tx_win);
360}
361
362#define __get_txseq(ctrl) ((ctrl) & L2CAP_CTRL_TXSEQ) >> 1
363#define __get_reqseq(ctrl) ((ctrl) & L2CAP_CTRL_REQSEQ) >> 8
364#define __is_iframe(ctrl) !((ctrl) & L2CAP_CTRL_FRAME_TYPE)
365#define __is_sframe(ctrl) (ctrl) & L2CAP_CTRL_FRAME_TYPE
314 366
315void l2cap_load(void); 367void l2cap_load(void);
316 368