From 6f74b6f36fc06fafb0c5868563385a59dc22b1b2 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 23 Mar 2012 16:31:50 +0200 Subject: Bluetooth: Comments and style fixes Add comments to timer implementation and style fixes. Signed-off-by: Andrei Emeltchenko Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- include/net/bluetooth/l2cap.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'include/net/bluetooth/l2cap.h') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 9b242c6bf55b..35334a0de070 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -622,21 +622,26 @@ static inline void l2cap_chan_unlock(struct l2cap_chan *chan) } static inline void l2cap_set_timer(struct l2cap_chan *chan, - struct delayed_work *work, long timeout) + struct delayed_work *work, long timeout) { BT_DBG("chan %p state %s timeout %ld", chan, - state_to_string(chan->state), timeout); + state_to_string(chan->state), timeout); + /* If delayed work cancelled do not hold(chan) + since it is already done with previous set_timer */ if (!cancel_delayed_work(work)) l2cap_chan_hold(chan); + schedule_delayed_work(work, timeout); } static inline bool l2cap_clear_timer(struct l2cap_chan *chan, - struct delayed_work *work) + struct delayed_work *work) { bool ret; + /* put(chan) if delayed work cancelled otherwise it + is done in delayed work function */ ret = cancel_delayed_work(work); if (ret) l2cap_chan_put(chan); -- cgit v1.2.3 From d5f7ac38102c12069de247890cfdd357bf845a77 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Fri, 23 Mar 2012 16:56:55 -0700 Subject: Bluetooth: Add definitions and struct members for new ERTM state machine Adds some missing values for control field parsing, additional data for the new state machine, and enumerations for states, incoming packet classification, and state machine events. Signed-off-by: Mat Martineau Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- include/net/bluetooth/l2cap.h | 49 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'include/net/bluetooth/l2cap.h') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 35334a0de070..c988df6f63bf 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -139,6 +139,8 @@ struct l2cap_conninfo { #define L2CAP_CTRL_TXSEQ_SHIFT 1 #define L2CAP_CTRL_SUPER_SHIFT 2 +#define L2CAP_CTRL_POLL_SHIFT 4 +#define L2CAP_CTRL_FINAL_SHIFT 7 #define L2CAP_CTRL_REQSEQ_SHIFT 8 #define L2CAP_CTRL_SAR_SHIFT 14 @@ -152,9 +154,11 @@ struct l2cap_conninfo { #define L2CAP_EXT_CTRL_FINAL 0x00000002 #define L2CAP_EXT_CTRL_FRAME_TYPE 0x00000001 /* I- or S-Frame */ +#define L2CAP_EXT_CTRL_FINAL_SHIFT 1 #define L2CAP_EXT_CTRL_REQSEQ_SHIFT 2 #define L2CAP_EXT_CTRL_SAR_SHIFT 16 #define L2CAP_EXT_CTRL_SUPER_SHIFT 16 +#define L2CAP_EXT_CTRL_POLL_SHIFT 18 #define L2CAP_EXT_CTRL_TXSEQ_SHIFT 18 /* L2CAP Supervisory Function */ @@ -186,6 +190,8 @@ struct l2cap_hdr { #define L2CAP_FCS_SIZE 2 #define L2CAP_SDULEN_SIZE 2 #define L2CAP_PSMLEN_SIZE 2 +#define L2CAP_ENH_CTRL_SIZE 2 +#define L2CAP_EXT_CTRL_SIZE 4 struct l2cap_cmd_hdr { __u8 code; @@ -446,6 +452,9 @@ struct l2cap_chan { __u16 monitor_timeout; __u16 mps; + __u8 tx_state; + __u8 rx_state; + unsigned long conf_state; unsigned long conn_state; unsigned long flags; @@ -456,9 +465,11 @@ struct l2cap_chan { __u16 buffer_seq; __u16 buffer_seq_srej; __u16 srej_save_reqseq; + __u16 last_acked_seq; __u16 frames_sent; __u16 unacked_frames; __u8 retry_count; + __u16 srej_queue_next; __u8 num_acked; __u16 sdu_len; struct sk_buff *sdu; @@ -600,6 +611,44 @@ enum { FLAG_EFS_ENABLE, }; +enum { + L2CAP_TX_STATE_XMIT, + L2CAP_TX_STATE_WAIT_F, +}; + +enum { + L2CAP_RX_STATE_RECV, + L2CAP_RX_STATE_SREJ_SENT, +}; + +enum { + L2CAP_TXSEQ_EXPECTED, + L2CAP_TXSEQ_EXPECTED_SREJ, + L2CAP_TXSEQ_UNEXPECTED, + L2CAP_TXSEQ_UNEXPECTED_SREJ, + L2CAP_TXSEQ_DUPLICATE, + L2CAP_TXSEQ_DUPLICATE_SREJ, + L2CAP_TXSEQ_INVALID, + L2CAP_TXSEQ_INVALID_IGNORE, +}; + +enum { + L2CAP_EV_DATA_REQUEST, + L2CAP_EV_LOCAL_BUSY_DETECTED, + L2CAP_EV_LOCAL_BUSY_CLEAR, + L2CAP_EV_RECV_REQSEQ_AND_FBIT, + L2CAP_EV_RECV_FBIT, + L2CAP_EV_RETRANS_TO, + L2CAP_EV_MONITOR_TO, + L2CAP_EV_EXPLICIT_POLL, + L2CAP_EV_RECV_IFRAME, + L2CAP_EV_RECV_RR, + L2CAP_EV_RECV_REJ, + L2CAP_EV_RECV_RNR, + L2CAP_EV_RECV_SREJ, + L2CAP_EV_RECV_FRAME, +}; + static inline void l2cap_chan_hold(struct l2cap_chan *c) { atomic_inc(&c->refcnt); -- cgit v1.2.3 From eef1d9b668c51dcae58d8bb41ce0c805f866dbbd Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Sun, 25 Mar 2012 13:59:16 -0300 Subject: Bluetooth: Remove sk parameter from l2cap_chan_create() Following the separation if core and sock code this change avoid manipulation of sk inside l2cap_chan_create(). Signed-off-by: Gustavo Padovan --- include/net/bluetooth/l2cap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/net/bluetooth/l2cap.h') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index c988df6f63bf..f6f0500bf370 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -906,7 +906,7 @@ int __l2cap_wait_ack(struct sock *sk); int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm); int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid); -struct l2cap_chan *l2cap_chan_create(struct sock *sk); +struct l2cap_chan *l2cap_chan_create(void); void l2cap_chan_close(struct l2cap_chan *chan, int reason); void l2cap_chan_destroy(struct l2cap_chan *chan); int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, -- cgit v1.2.3 From bd4b165312bacbf1e732cbc22c141362cfb5fda3 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 28 Mar 2012 16:31:25 +0300 Subject: Bluetooth: Adds set_default function in L2CAP setup Some parameters in L2CAP chan are set to default similar way in socket based channels and A2MP channels. Adds common function which sets all defaults. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- include/net/bluetooth/l2cap.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/net/bluetooth/l2cap.h') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index f6f0500bf370..c70e2cf107ff 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -915,5 +915,6 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, u32 priority); void l2cap_chan_busy(struct l2cap_chan *chan, int busy); int l2cap_chan_check_security(struct l2cap_chan *chan); +void l2cap_chan_set_defaults(struct l2cap_chan *chan); #endif /* __L2CAP_H */ -- cgit v1.2.3 From 9033894722ec595053c92bfa4359b37e7bc91b78 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 6 Apr 2012 20:15:47 -0300 Subject: Bluetooth: Remove err parameter from alloc_skb() Use ERR_PTR maginc instead. Signed-off-by: Gustavo Padovan Acked-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/l2cap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/net/bluetooth/l2cap.h') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index c70e2cf107ff..a756c2406306 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -519,7 +519,7 @@ struct l2cap_ops { void (*close) (void *data); void (*state_change) (void *data, int state); struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan, - unsigned long len, int nb, int *err); + unsigned long len, int nb); }; -- cgit v1.2.3 From 3c588192b5e5328cdfc8e299c55477004d397208 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Wed, 11 Apr 2012 10:48:42 -0700 Subject: Bluetooth: Add the l2cap_seq_list structure for tracking frames A sequence list is a data structure used to track frames that need to be retransmitted, and frames that have been requested for retransmission by the remote device. It can compactly represent a list of sequence numbers within the ERTM transmit window. Memory for the list is allocated once at connection time, and common operations in ERTM are O(1). Signed-off-by: Mat Martineau Signed-off-by: Marcel Holtmann --- include/net/bluetooth/l2cap.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include/net/bluetooth/l2cap.h') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index a756c2406306..e33165476e83 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -407,6 +407,16 @@ struct l2cap_conn_param_update_rsp { #define L2CAP_CONN_PARAM_REJECTED 0x0001 /* ----- L2CAP channels and connections ----- */ +struct l2cap_seq_list { + __u16 head; + __u16 tail; + __u16 mask; + __u16 *list; +}; + +#define L2CAP_SEQ_LIST_CLEAR 0xFFFF +#define L2CAP_SEQ_LIST_TAIL 0x8000 + struct srej_list { __u16 tx_seq; struct list_head list; @@ -501,6 +511,8 @@ struct l2cap_chan { struct sk_buff *tx_send_head; struct sk_buff_head tx_q; struct sk_buff_head srej_q; + struct l2cap_seq_list srej_list; + struct l2cap_seq_list retrans_list; struct list_head srej_l; struct list_head list; -- cgit v1.2.3 From 2bbf2968e5cd72d2dd9e229d85c1617b8aa48f4e Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 16 Apr 2012 16:32:03 +0300 Subject: Bluetooth: trivial: Remove empty line Signed-off-by: Andrei Emeltchenko Signed-off-by: Marcel Holtmann --- include/net/bluetooth/l2cap.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/net/bluetooth/l2cap.h') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index e33165476e83..52f7e6a9a237 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -532,7 +532,6 @@ struct l2cap_ops { void (*state_change) (void *data, int state); struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan, unsigned long len, int nb); - }; struct l2cap_conn { -- cgit v1.2.3 From 43ef0b8b8d95c7aab7bb3778351e3591502bf355 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Tue, 24 Apr 2012 21:02:52 -0300 Subject: Bluetooth: Add address type to struct sockaddr_l2 This patch adds the address type info to struct sockaddr_l2 so user-space can inform the remote device address type required to establish LE connections. Soon, instead of looking the advertising cache up to discover the address type, we'll use this address type info to establish LE connections. Signed-off-by: Andre Guedes Acked-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/l2cap.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/net/bluetooth/l2cap.h') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 52f7e6a9a237..bb4e3f66b43c 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -57,6 +57,7 @@ struct sockaddr_l2 { __le16 l2_psm; bdaddr_t l2_bdaddr; __le16 l2_cid; + __u8 l2_bdaddr_type; }; /* L2CAP socket options */ -- cgit v1.2.3 From 8e9f98921c0718cda76bc53c2b51954657b60fa6 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Tue, 24 Apr 2012 21:02:55 -0300 Subject: Bluetooth: Use address type info from user-space In order to establish a LE connection we need the address type information. User-space already pass this information to kernel through struct sockaddr_l2. This patch adds the dst_type parameter to l2cap_chan_connect so we are able to pass the address type info from user-space down to hci_conn layer. Signed-off-by: Andre Guedes Acked-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/l2cap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/net/bluetooth/l2cap.h') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index bb4e3f66b43c..86bb83bc6a4f 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -922,7 +922,7 @@ struct l2cap_chan *l2cap_chan_create(void); void l2cap_chan_close(struct l2cap_chan *chan, int reason); void l2cap_chan_destroy(struct l2cap_chan *chan); int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, - bdaddr_t *dst); + bdaddr_t *dst, u8 dst_type); int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, u32 priority); void l2cap_chan_busy(struct l2cap_chan *chan, int busy); -- cgit v1.2.3 From 5a364bd399d23fe6244de8f84c46f249b763c723 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Wed, 25 Apr 2012 16:36:12 -0700 Subject: Bluetooth: Improve ERTM sequence number offset calculation Instead of using modular division, the offset can be calculated using only addition and subtraction. The previous calculation did not work as intended and was more difficult to understand, involving unsigned integer underflow and a check for a negative value where one was not possible. Signed-off-by: Mat Martineau Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- include/net/bluetooth/l2cap.h | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'include/net/bluetooth/l2cap.h') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 86bb83bc6a4f..084dec001bf2 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -724,13 +724,10 @@ static inline bool l2cap_clear_timer(struct l2cap_chan *chan, static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2) { - int offset; - - offset = (seq1 - seq2) % (chan->tx_win_max + 1); - if (offset < 0) - offset += (chan->tx_win_max + 1); - - return offset; + if (seq1 >= seq2) + return seq1 - seq2; + else + return chan->tx_win_max + 1 - seq2 + seq1; } static inline __u16 __next_seq(struct l2cap_chan *chan, __u16 seq) -- cgit v1.2.3 From 94122bbe9c8c4ad7ba9f02f9a30bfc95672c404e Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Wed, 2 May 2012 09:42:02 -0700 Subject: Bluetooth: Refactor L2CAP ERTM and streaming transmit segmentation Use more common code for ERTM and streaming mode segmentation and transmission, and begin using skb control block data for delaying extended or enhanced header generation until just before the packet is transmitted. This code is also better suited for resegmentation, which is needed when L2CAP links are reconfigured after an AMP channel move. Signed-off-by: Mat Martineau Reviewed-by: Ulisses Furquim Signed-off-by: Gustavo Padovan --- include/net/bluetooth/l2cap.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/net/bluetooth/l2cap.h') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 084dec001bf2..1c7d1cd5e679 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -44,6 +44,7 @@ #define L2CAP_DEFAULT_MAX_SDU_SIZE 0xFFFF #define L2CAP_DEFAULT_SDU_ITIME 0xFFFFFFFF #define L2CAP_DEFAULT_ACC_LAT 0xFFFFFFFF +#define L2CAP_BREDR_MAX_PAYLOAD 1019 /* 3-DH5 packet */ #define L2CAP_DISC_TIMEOUT msecs_to_jiffies(100) #define L2CAP_DISC_REJ_TIMEOUT msecs_to_jiffies(5000) -- cgit v1.2.3