aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrei Emeltchenko <andrei.emeltchenko@nokia.com>2011-01-03 04:14:36 -0500
committerGustavo F. Padovan <padovan@profusion.mobi>2011-02-07 22:40:04 -0500
commite702112ff68a554bcac16bb03ddc2b8e5425bcbf (patch)
tree872f93640d646326167d41b7797d5a7eea75b751
parentb2c60d42db0fea1e6c4345739601024863566a13 (diff)
Bluetooth: Use non-flushable by default L2CAP data packets
Modification of Nick Pelly <npelly@google.com> patch. With Bluetooth 2.1 ACL packets can be flushable or non-flushable. This commit makes ACL data packets non-flushable by default on compatible chipsets, and adds the BT_FLUSHABLE socket option to explicitly request flushable ACL data packets for a given L2CAP socket. This is useful for A2DP data which can be safely discarded if it can not be delivered within a short time (while other ACL data should not be discarded). Note that making ACL data flushable has no effect unless the automatic flush timeout for that ACL link is changed from its default of 0 (infinite). Default packet types (for compatible chipsets): Frame 34: 13 bytes on wire (104 bits), 13 bytes captured (104 bits) Bluetooth HCI H4 Bluetooth HCI ACL Packet .... 0000 0000 0010 = Connection Handle: 0x0002 ..00 .... .... .... = PB Flag: First Non-automatically Flushable Packet (0) 00.. .... .... .... = BC Flag: Point-To-Point (0) Data Total Length: 8 Bluetooth L2CAP Packet After setting BT_FLUSHABLE (sock.setsockopt(274 /*SOL_BLUETOOTH*/, 8 /* BT_FLUSHABLE */, 1 /* flush */)) Frame 34: 13 bytes on wire (104 bits), 13 bytes captured (104 bits) Bluetooth HCI H4 Bluetooth HCI ACL Packet .... 0000 0000 0010 = Connection Handle: 0x0002 ..10 .... .... .... = PB Flag: First Automatically Flushable Packet (2) 00.. .... .... .... = BC Flag: Point-To-Point (0) Data Total Length: 8 Bluetooth L2CAP Packet Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@nokia.com> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
-rw-r--r--include/net/bluetooth/bluetooth.h5
-rw-r--r--include/net/bluetooth/hci.h2
-rw-r--r--include/net/bluetooth/hci_core.h1
-rw-r--r--include/net/bluetooth/l2cap.h1
-rw-r--r--net/bluetooth/hci_core.c7
-rw-r--r--net/bluetooth/l2cap.c59
6 files changed, 69 insertions, 6 deletions
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 0c5e72503b77..ed7d775337e0 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -64,6 +64,11 @@ struct bt_security {
64 64
65#define BT_DEFER_SETUP 7 65#define BT_DEFER_SETUP 7
66 66
67#define BT_FLUSHABLE 8
68
69#define BT_FLUSHABLE_OFF 0
70#define BT_FLUSHABLE_ON 1
71
67#define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg) 72#define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg)
68#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg) 73#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg)
69#define BT_DBG(fmt, arg...) pr_debug("%s: " fmt "\n" , __func__ , ## arg) 74#define BT_DBG(fmt, arg...) pr_debug("%s: " fmt "\n" , __func__ , ## arg)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 29a7a8ca0438..5d033dc9d43b 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -150,6 +150,7 @@ enum {
150#define EDR_ESCO_MASK (ESCO_2EV3 | ESCO_3EV3 | ESCO_2EV5 | ESCO_3EV5) 150#define EDR_ESCO_MASK (ESCO_2EV3 | ESCO_3EV3 | ESCO_2EV5 | ESCO_3EV5)
151 151
152/* ACL flags */ 152/* ACL flags */
153#define ACL_START_NO_FLUSH 0x00
153#define ACL_CONT 0x01 154#define ACL_CONT 0x01
154#define ACL_START 0x02 155#define ACL_START 0x02
155#define ACL_ACTIVE_BCAST 0x04 156#define ACL_ACTIVE_BCAST 0x04
@@ -194,6 +195,7 @@ enum {
194#define LMP_EDR_3S_ESCO 0x80 195#define LMP_EDR_3S_ESCO 0x80
195 196
196#define LMP_SIMPLE_PAIR 0x08 197#define LMP_SIMPLE_PAIR 0x08
198#define LMP_NO_FLUSH 0x40
197 199
198/* Connection modes */ 200/* Connection modes */
199#define HCI_CM_ACTIVE 0x0000 201#define HCI_CM_ACTIVE 0x0000
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index d2cf88407690..4e14610baece 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -458,6 +458,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
458#define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR) 458#define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
459#define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO) 459#define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO)
460#define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR) 460#define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR)
461#define lmp_no_flush_capable(dev) ((dev)->features[6] & LMP_NO_FLUSH)
461 462
462/* ----- HCI protocols ----- */ 463/* ----- HCI protocols ----- */
463struct hci_proto { 464struct hci_proto {
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 7ad25ca60ec0..7f88a87d7a46 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -327,6 +327,7 @@ struct l2cap_pinfo {
327 __u8 sec_level; 327 __u8 sec_level;
328 __u8 role_switch; 328 __u8 role_switch;
329 __u8 force_reliable; 329 __u8 force_reliable;
330 __u8 flushable;
330 331
331 __u8 conf_req[64]; 332 __u8 conf_req[64];
332 __u8 conf_len; 333 __u8 conf_len;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 9c4541bc488a..9ba92adaa9ad 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1395,7 +1395,7 @@ void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
1395 1395
1396 skb->dev = (void *) hdev; 1396 skb->dev = (void *) hdev;
1397 bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 1397 bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
1398 hci_add_acl_hdr(skb, conn->handle, flags | ACL_START); 1398 hci_add_acl_hdr(skb, conn->handle, flags);
1399 1399
1400 list = skb_shinfo(skb)->frag_list; 1400 list = skb_shinfo(skb)->frag_list;
1401 if (!list) { 1401 if (!list) {
@@ -1413,12 +1413,15 @@ void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
1413 spin_lock_bh(&conn->data_q.lock); 1413 spin_lock_bh(&conn->data_q.lock);
1414 1414
1415 __skb_queue_tail(&conn->data_q, skb); 1415 __skb_queue_tail(&conn->data_q, skb);
1416
1417 flags &= ~ACL_START;
1418 flags |= ACL_CONT;
1416 do { 1419 do {
1417 skb = list; list = list->next; 1420 skb = list; list = list->next;
1418 1421
1419 skb->dev = (void *) hdev; 1422 skb->dev = (void *) hdev;
1420 bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; 1423 bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
1421 hci_add_acl_hdr(skb, conn->handle, flags | ACL_CONT); 1424 hci_add_acl_hdr(skb, conn->handle, flags);
1422 1425
1423 BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); 1426 BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
1424 1427
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 675614e38e14..4bf98dfd24bc 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -373,13 +373,19 @@ static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
373static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data) 373static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
374{ 374{
375 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data); 375 struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
376 u8 flags;
376 377
377 BT_DBG("code 0x%2.2x", code); 378 BT_DBG("code 0x%2.2x", code);
378 379
379 if (!skb) 380 if (!skb)
380 return; 381 return;
381 382
382 hci_send_acl(conn->hcon, skb, 0); 383 if (lmp_no_flush_capable(conn->hcon->hdev))
384 flags = ACL_START_NO_FLUSH;
385 else
386 flags = ACL_START;
387
388 hci_send_acl(conn->hcon, skb, flags);
383} 389}
384 390
385static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control) 391static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
@@ -389,6 +395,7 @@ static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
389 struct l2cap_conn *conn = pi->conn; 395 struct l2cap_conn *conn = pi->conn;
390 struct sock *sk = (struct sock *)pi; 396 struct sock *sk = (struct sock *)pi;
391 int count, hlen = L2CAP_HDR_SIZE + 2; 397 int count, hlen = L2CAP_HDR_SIZE + 2;
398 u8 flags;
392 399
393 if (sk->sk_state != BT_CONNECTED) 400 if (sk->sk_state != BT_CONNECTED)
394 return; 401 return;
@@ -425,7 +432,12 @@ static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
425 put_unaligned_le16(fcs, skb_put(skb, 2)); 432 put_unaligned_le16(fcs, skb_put(skb, 2));
426 } 433 }
427 434
428 hci_send_acl(pi->conn->hcon, skb, 0); 435 if (lmp_no_flush_capable(conn->hcon->hdev))
436 flags = ACL_START_NO_FLUSH;
437 else
438 flags = ACL_START;
439
440 hci_send_acl(pi->conn->hcon, skb, flags);
429} 441}
430 442
431static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control) 443static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
@@ -912,6 +924,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
912 pi->sec_level = l2cap_pi(parent)->sec_level; 924 pi->sec_level = l2cap_pi(parent)->sec_level;
913 pi->role_switch = l2cap_pi(parent)->role_switch; 925 pi->role_switch = l2cap_pi(parent)->role_switch;
914 pi->force_reliable = l2cap_pi(parent)->force_reliable; 926 pi->force_reliable = l2cap_pi(parent)->force_reliable;
927 pi->flushable = l2cap_pi(parent)->flushable;
915 } else { 928 } else {
916 pi->imtu = L2CAP_DEFAULT_MTU; 929 pi->imtu = L2CAP_DEFAULT_MTU;
917 pi->omtu = 0; 930 pi->omtu = 0;
@@ -927,6 +940,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
927 pi->sec_level = BT_SECURITY_LOW; 940 pi->sec_level = BT_SECURITY_LOW;
928 pi->role_switch = 0; 941 pi->role_switch = 0;
929 pi->force_reliable = 0; 942 pi->force_reliable = 0;
943 pi->flushable = BT_FLUSHABLE_OFF;
930 } 944 }
931 945
932 /* Default config options */ 946 /* Default config options */
@@ -1431,10 +1445,17 @@ static void l2cap_drop_acked_frames(struct sock *sk)
1431static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb) 1445static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
1432{ 1446{
1433 struct l2cap_pinfo *pi = l2cap_pi(sk); 1447 struct l2cap_pinfo *pi = l2cap_pi(sk);
1448 struct hci_conn *hcon = pi->conn->hcon;
1449 u16 flags;
1434 1450
1435 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len); 1451 BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
1436 1452
1437 hci_send_acl(pi->conn->hcon, skb, 0); 1453 if (!pi->flushable && lmp_no_flush_capable(hcon->hdev))
1454 flags = ACL_START_NO_FLUSH;
1455 else
1456 flags = ACL_START;
1457
1458 hci_send_acl(hcon, skb, flags);
1438} 1459}
1439 1460
1440static void l2cap_streaming_send(struct sock *sk) 1461static void l2cap_streaming_send(struct sock *sk)
@@ -2079,6 +2100,30 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
2079 bt_sk(sk)->defer_setup = opt; 2100 bt_sk(sk)->defer_setup = opt;
2080 break; 2101 break;
2081 2102
2103 case BT_FLUSHABLE:
2104 if (get_user(opt, (u32 __user *) optval)) {
2105 err = -EFAULT;
2106 break;
2107 }
2108
2109 if (opt > BT_FLUSHABLE_ON) {
2110 err = -EINVAL;
2111 break;
2112 }
2113
2114 if (opt == BT_FLUSHABLE_OFF) {
2115 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
2116 /* proceed futher only when we have l2cap_conn and
2117 No Flush support in the LM */
2118 if (!conn || !lmp_no_flush_capable(conn->hcon->hdev)) {
2119 err = -EINVAL;
2120 break;
2121 }
2122 }
2123
2124 l2cap_pi(sk)->flushable = opt;
2125 break;
2126
2082 default: 2127 default:
2083 err = -ENOPROTOOPT; 2128 err = -ENOPROTOOPT;
2084 break; 2129 break;
@@ -2218,6 +2263,12 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
2218 2263
2219 break; 2264 break;
2220 2265
2266 case BT_FLUSHABLE:
2267 if (put_user(l2cap_pi(sk)->flushable, (u32 __user *) optval))
2268 err = -EFAULT;
2269
2270 break;
2271
2221 default: 2272 default:
2222 err = -ENOPROTOOPT; 2273 err = -ENOPROTOOPT;
2223 break; 2274 break;
@@ -4678,7 +4729,7 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
4678 4729
4679 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags); 4730 BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
4680 4731
4681 if (flags & ACL_START) { 4732 if (!(flags & ACL_CONT)) {
4682 struct l2cap_hdr *hdr; 4733 struct l2cap_hdr *hdr;
4683 struct sock *sk; 4734 struct sock *sk;
4684 u16 cid; 4735 u16 cid;