Last active
December 18, 2015 18:29
-
-
Save kmanna/5825747 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 9b55aebfea81ca8ac9f0731736fffee826537de8 Mon Sep 17 00:00:00 2001 | |
From: Kyle Manna <kmanna@fanhattan.com> | |
Date: Wed, 19 Jun 2013 18:10:03 -0700 | |
Subject: [PATCH 1/3] bluetooth: Add ability to pass connection params | |
* Useful for adding Bluetooth Low Energy Connection Parameters which | |
are currently hardcoded. | |
--- | |
include/net/bluetooth/hci_core.h | 5 ++-- | |
include/net/bluetooth/l2cap.h | 4 ++++ | |
net/bluetooth/hci_conn.c | 47 +++++++++++++++++++++++--------------- | |
net/bluetooth/l2cap_core.c | 7 ++++-- | |
net/bluetooth/mgmt.c | 4 ++-- | |
net/bluetooth/sco.c | 2 +- | |
6 files changed, 43 insertions(+), 26 deletions(-) | |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h | |
index 014a2ea..d1ccc02 100644 | |
--- a/include/net/bluetooth/hci_core.h | |
+++ b/include/net/bluetooth/hci_core.h | |
@@ -584,8 +584,9 @@ void hci_chan_del(struct hci_chan *chan); | |
void hci_chan_list_flush(struct hci_conn *conn); | |
struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle); | |
-struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, | |
- __u8 dst_type, __u8 sec_level, __u8 auth_type); | |
+struct hci_conn *hci_connect(struct hci_dev *hdev, int type, void *cp, | |
+ bdaddr_t *dst, __u8 dst_type, | |
+ __u8 sec_level, __u8 auth_type); | |
int hci_conn_check_link_mode(struct hci_conn *conn); | |
int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level); | |
int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type); | |
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h | |
index 7588ef4..6abfa91 100644 | |
--- a/include/net/bluetooth/l2cap.h | |
+++ b/include/net/bluetooth/l2cap.h | |
@@ -438,6 +438,10 @@ struct l2cap_chan { | |
struct l2cap_conn *conn; | |
struct hci_conn *hs_hcon; | |
struct hci_chan *hs_hchan; | |
+ | |
+ /* Optionally set by setsockopt */ | |
+ struct hci_cp_le_create_conn *cp_le; | |
+ | |
struct kref kref; | |
__u8 state; | |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c | |
index 4925a02..1ecbbac 100644 | |
--- a/net/bluetooth/hci_conn.c | |
+++ b/net/bluetooth/hci_conn.c | |
@@ -31,28 +31,34 @@ | |
#include <net/bluetooth/a2mp.h> | |
#include <net/bluetooth/smp.h> | |
-static void hci_le_create_connection(struct hci_conn *conn) | |
+static void hci_le_create_connection(struct hci_conn *conn, | |
+ struct hci_cp_le_create_conn *cp) | |
{ | |
struct hci_dev *hdev = conn->hdev; | |
- struct hci_cp_le_create_conn cp; | |
+ struct hci_cp_le_create_conn cp_stack; | |
conn->state = BT_CONNECT; | |
conn->out = true; | |
conn->link_mode |= HCI_LM_MASTER; | |
conn->sec_level = BT_SECURITY_LOW; | |
- memset(&cp, 0, sizeof(cp)); | |
- cp.scan_interval = __constant_cpu_to_le16(0x0060); | |
- cp.scan_window = __constant_cpu_to_le16(0x0030); | |
- bacpy(&cp.peer_addr, &conn->dst); | |
- cp.peer_addr_type = conn->dst_type; | |
- cp.conn_interval_min = __constant_cpu_to_le16(0x0028); | |
- cp.conn_interval_max = __constant_cpu_to_le16(0x0038); | |
- cp.supervision_timeout = __constant_cpu_to_le16(0x002a); | |
- cp.min_ce_len = __constant_cpu_to_le16(0x0000); | |
- cp.max_ce_len = __constant_cpu_to_le16(0x0000); | |
- | |
- hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp); | |
+ if (!cp) { | |
+ cp = &cp_stack; | |
+ | |
+ memset(cp, 0, sizeof(*cp)); | |
+ cp->scan_interval = __constant_cpu_to_le16(0x0060); | |
+ cp->scan_window = __constant_cpu_to_le16(0x0030); | |
+ cp->conn_interval_min = __constant_cpu_to_le16(0x0028); | |
+ cp->conn_interval_max = __constant_cpu_to_le16(0x0038); | |
+ cp->supervision_timeout = __constant_cpu_to_le16(0x002a); | |
+ cp->min_ce_len = __constant_cpu_to_le16(0x0000); | |
+ cp->max_ce_len = __constant_cpu_to_le16(0x0000); | |
+ } | |
+ | |
+ bacpy(&cp->peer_addr, &conn->dst); | |
+ cp->peer_addr_type = conn->dst_type; | |
+ | |
+ hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(*cp), cp); | |
} | |
static void hci_le_create_connection_cancel(struct hci_conn *conn) | |
@@ -498,7 +504,8 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src) | |
EXPORT_SYMBOL(hci_get_route); | |
static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, | |
- u8 dst_type, u8 sec_level, u8 auth_type) | |
+ u8 dst_type, u8 sec_level, u8 auth_type, | |
+ struct hci_cp_le_create_conn *cp) | |
{ | |
struct hci_conn *le; | |
@@ -516,7 +523,7 @@ static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, | |
return ERR_PTR(-ENOMEM); | |
le->dst_type = bdaddr_to_le(dst_type); | |
- hci_le_create_connection(le); | |
+ hci_le_create_connection(le, cp); | |
} | |
le->pending_sec_level = sec_level; | |
@@ -593,14 +600,16 @@ static struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, | |
} | |
/* Create SCO, ACL or LE connection. */ | |
-struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, | |
- __u8 dst_type, __u8 sec_level, __u8 auth_type) | |
+struct hci_conn *hci_connect(struct hci_dev *hdev, int type, void *cp, | |
+ bdaddr_t *dst, __u8 dst_type, | |
+ __u8 sec_level, __u8 auth_type) | |
{ | |
BT_DBG("%s dst %pMR type 0x%x", hdev->name, dst, type); | |
switch (type) { | |
case LE_LINK: | |
- return hci_connect_le(hdev, dst, dst_type, sec_level, auth_type); | |
+ return hci_connect_le(hdev, dst, dst_type, sec_level, | |
+ auth_type, cp); | |
case ACL_LINK: | |
return hci_connect_acl(hdev, dst, sec_level, auth_type); | |
case SCO_LINK: | |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c | |
index 22e6583..de086e5 100644 | |
--- a/net/bluetooth/l2cap_core.c | |
+++ b/net/bluetooth/l2cap_core.c | |
@@ -461,6 +461,9 @@ static void l2cap_chan_destroy(struct kref *kref) | |
list_del(&chan->global_l); | |
write_unlock(&chan_list_lock); | |
+ if (chan->cp_le) | |
+ kfree(chan->cp_le); | |
+ | |
kfree(chan); | |
} | |
@@ -1689,10 +1692,10 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, | |
auth_type = l2cap_get_auth_type(chan); | |
if (chan->dcid == L2CAP_CID_LE_DATA) | |
- hcon = hci_connect(hdev, LE_LINK, dst, dst_type, | |
+ hcon = hci_connect(hdev, LE_LINK, chan->cp_le, dst, dst_type, | |
chan->sec_level, auth_type); | |
else | |
- hcon = hci_connect(hdev, ACL_LINK, dst, dst_type, | |
+ hcon = hci_connect(hdev, ACL_LINK, NULL, dst, dst_type, | |
chan->sec_level, auth_type); | |
if (IS_ERR(hcon)) { | |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c | |
index f559b96..1ff28e0 100644 | |
--- a/net/bluetooth/mgmt.c | |
+++ b/net/bluetooth/mgmt.c | |
@@ -1918,10 +1918,10 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, | |
auth_type = HCI_AT_DEDICATED_BONDING_MITM; | |
if (cp->addr.type == BDADDR_BREDR) | |
- conn = hci_connect(hdev, ACL_LINK, &cp->addr.bdaddr, | |
+ conn = hci_connect(hdev, ACL_LINK, NULL, &cp->addr.bdaddr, | |
cp->addr.type, sec_level, auth_type); | |
else | |
- conn = hci_connect(hdev, LE_LINK, &cp->addr.bdaddr, | |
+ conn = hci_connect(hdev, LE_LINK, NULL, &cp->addr.bdaddr, | |
cp->addr.type, sec_level, auth_type); | |
memset(&rp, 0, sizeof(rp)); | |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c | |
index 299ef14..e2baf77 100644 | |
--- a/net/bluetooth/sco.c | |
+++ b/net/bluetooth/sco.c | |
@@ -176,7 +176,7 @@ static int sco_connect(struct sock *sk) | |
else | |
type = SCO_LINK; | |
- hcon = hci_connect(hdev, type, dst, BDADDR_BREDR, BT_SECURITY_LOW, | |
+ hcon = hci_connect(hdev, type, NULL, dst, BDADDR_BREDR, BT_SECURITY_LOW, | |
HCI_AT_NO_BONDING); | |
if (IS_ERR(hcon)) { | |
err = PTR_ERR(hcon); | |
-- | |
1.7.9.5 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 906472affdd070d240d078884610b13681d5939c Mon Sep 17 00:00:00 2001 | |
From: Kyle Manna <kmanna@fanhattan.com> | |
Date: Thu, 20 Jun 2013 11:53:40 -0700 | |
Subject: [PATCH 2/3] bluetooth: Add l2cap setsockopt for LE conn params | |
* Userspace can now specify connection parameters prior to connecting to the | |
device. | |
--- | |
include/net/bluetooth/bluetooth.h | 2 ++ | |
net/bluetooth/l2cap_sock.c | 20 ++++++++++++++++++++ | |
2 files changed, 22 insertions(+) | |
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h | |
index 2554b3f..f2474fc 100644 | |
--- a/include/net/bluetooth/bluetooth.h | |
+++ b/include/net/bluetooth/bluetooth.h | |
@@ -82,6 +82,8 @@ struct bt_power { | |
#define BT_CHANNEL_POLICY 10 | |
+#define BT_LE_CONN_PARAM 11 | |
+ | |
/* BR/EDR only (default policy) | |
* AMP controllers cannot be used. | |
* Channel move requests from the remote device are denied. | |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c | |
index 97d47b9..3cc8fbe 100644 | |
--- a/net/bluetooth/l2cap_sock.c | |
+++ b/net/bluetooth/l2cap_sock.c | |
@@ -748,6 +748,26 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, | |
break; | |
+ case BT_LE_CONN_PARAM: | |
+ | |
+ if (sizeof(struct hci_cp_le_create_conn) != optlen) { | |
+ err = -EINVAL; | |
+ break; | |
+ } | |
+ | |
+ chan->cp_le = kmalloc(optlen, GFP_KERNEL); | |
+ if (!chan->cp_le) { | |
+ err = -ENOMEM; | |
+ break; | |
+ } | |
+ | |
+ if (copy_from_user((char *)chan->cp_le, optval, optlen)) { | |
+ err = -EFAULT; | |
+ break; | |
+ } | |
+ | |
+ break; | |
+ | |
default: | |
err = -ENOPROTOOPT; | |
break; | |
-- | |
1.7.9.5 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 1e25dd4b891eb90fbc3c7116726066f6b9ec2c3d Mon Sep 17 00:00:00 2001 | |
From: Kyle Manna <kmanna@fanhattan.com> | |
Date: Thu, 20 Jun 2013 12:13:23 -0700 | |
Subject: [PATCH 3/3] WIP: bluetooth: Add debugging output | |
* Don't commit. | |
--- | |
net/bluetooth/hci_conn.c | 3 +++ | |
net/bluetooth/l2cap_sock.c | 6 ++++++ | |
2 files changed, 9 insertions(+) | |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c | |
index 1ecbbac..0d5f9a1 100644 | |
--- a/net/bluetooth/hci_conn.c | |
+++ b/net/bluetooth/hci_conn.c | |
@@ -42,7 +42,10 @@ static void hci_le_create_connection(struct hci_conn *conn, | |
conn->link_mode |= HCI_LM_MASTER; | |
conn->sec_level = BT_SECURITY_LOW; | |
+ pr_info("%s() cp = %p\n", __func__, cp); | |
+ | |
if (!cp) { | |
+ pr_info("%s() using default cp!!\n", __func__); | |
cp = &cp_stack; | |
memset(cp, 0, sizeof(*cp)); | |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c | |
index 3cc8fbe..9536557 100644 | |
--- a/net/bluetooth/l2cap_sock.c | |
+++ b/net/bluetooth/l2cap_sock.c | |
@@ -591,6 +591,8 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, | |
BT_DBG("sk %p", sk); | |
+ pr_info("%s(%p) optname = %d\n", __func__, sk, optname); | |
+ | |
if (level == SOL_L2CAP) | |
return l2cap_sock_setsockopt_old(sock, optname, optval, optlen); | |
@@ -750,6 +752,8 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, | |
case BT_LE_CONN_PARAM: | |
+ pr_info("%s(): attempting to copy connection parameters\n", __func__); | |
+ | |
if (sizeof(struct hci_cp_le_create_conn) != optlen) { | |
err = -EINVAL; | |
break; | |
@@ -765,6 +769,8 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, | |
err = -EFAULT; | |
break; | |
} | |
+ | |
+ pr_info("%s(): connection parameters copied\n", __func__); | |
break; | |
-- | |
1.7.9.5 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment