diff options
author | Gustavo F. Padovan <gustavo@las.ic.unicamp.br> | 2009-08-26 03:04:03 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2009-08-26 03:12:20 -0400 |
commit | 7e7430908c3ccaf71f0851050c8ccaf9ecfb3b56 (patch) | |
tree | 7a435dbbb39a1d6179e0b683cb510978bec0adb5 /net/bluetooth | |
parent | 2246b2f1b43f3fbd128e72b129dcbbd3202cc592 (diff) |
Bluetooth: Add support for L2CAP 'Send RRorRNR' action
When called, 'Send RRorRNR' should send a RNR frame if local device is
busy or a RR frame otherwise.
Signed-off-by: Gustavo F. Padovan <gustavo@las.ic.unicamp.br>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/l2cap.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 40fbf5cb1f7e..b03012564647 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -366,6 +366,16 @@ static inline int l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control) | |||
366 | return hci_send_acl(pi->conn->hcon, skb, 0); | 366 | return hci_send_acl(pi->conn->hcon, skb, 0); |
367 | } | 367 | } |
368 | 368 | ||
369 | static inline int l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control) | ||
370 | { | ||
371 | if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) | ||
372 | control |= L2CAP_SUPER_RCV_NOT_READY; | ||
373 | else | ||
374 | control |= L2CAP_SUPER_RCV_READY; | ||
375 | |||
376 | return l2cap_send_sframe(pi, control); | ||
377 | } | ||
378 | |||
369 | static void l2cap_do_start(struct sock *sk) | 379 | static void l2cap_do_start(struct sock *sk) |
370 | { | 380 | { |
371 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 381 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; |
@@ -1202,8 +1212,7 @@ static void l2cap_monitor_timeout(unsigned long arg) | |||
1202 | __mod_monitor_timer(); | 1212 | __mod_monitor_timer(); |
1203 | 1213 | ||
1204 | control = L2CAP_CTRL_POLL; | 1214 | control = L2CAP_CTRL_POLL; |
1205 | control |= L2CAP_SUPER_RCV_READY; | 1215 | l2cap_send_rr_or_rnr(l2cap_pi(sk), control); |
1206 | l2cap_send_sframe(l2cap_pi(sk), control); | ||
1207 | bh_unlock_sock(sk); | 1216 | bh_unlock_sock(sk); |
1208 | } | 1217 | } |
1209 | 1218 | ||
@@ -1219,8 +1228,7 @@ static void l2cap_retrans_timeout(unsigned long arg) | |||
1219 | l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F; | 1228 | l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F; |
1220 | 1229 | ||
1221 | control = L2CAP_CTRL_POLL; | 1230 | control = L2CAP_CTRL_POLL; |
1222 | control |= L2CAP_SUPER_RCV_READY; | 1231 | l2cap_send_rr_or_rnr(l2cap_pi(sk), control); |
1223 | l2cap_send_sframe(l2cap_pi(sk), control); | ||
1224 | bh_unlock_sock(sk); | 1232 | bh_unlock_sock(sk); |
1225 | } | 1233 | } |
1226 | 1234 | ||
@@ -3428,8 +3436,8 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str | |||
3428 | 3436 | ||
3429 | del_timer(&l2cap_pi(sk)->retrans_timer); | 3437 | del_timer(&l2cap_pi(sk)->retrans_timer); |
3430 | if (rx_control & L2CAP_CTRL_POLL) { | 3438 | if (rx_control & L2CAP_CTRL_POLL) { |
3431 | u16 control = L2CAP_CTRL_FINAL | L2CAP_SUPER_RCV_READY; | 3439 | u16 control = L2CAP_CTRL_FINAL; |
3432 | l2cap_send_sframe(l2cap_pi(sk), control); | 3440 | l2cap_send_rr_or_rnr(l2cap_pi(sk), control); |
3433 | } | 3441 | } |
3434 | break; | 3442 | break; |
3435 | } | 3443 | } |