aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/hci.h2
-rw-r--r--include/net/bluetooth/hci_core.h25
-rw-r--r--net/bluetooth/hci_conn.c51
-rw-r--r--net/bluetooth/hci_event.c93
4 files changed, 164 insertions, 7 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 802d2505f138..e756f82a29e5 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -168,6 +168,8 @@ enum {
168#define SCO_LINK 0x00 168#define SCO_LINK 0x00
169#define ACL_LINK 0x01 169#define ACL_LINK 0x01
170#define ESCO_LINK 0x02 170#define ESCO_LINK 0x02
171/* Low Energy links do not have defined link type. Use invented one */
172#define LE_LINK 0x80
171 173
172/* LMP features */ 174/* LMP features */
173#define LMP_3SLOT 0x01 175#define LMP_3SLOT 0x01
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 6163bff6fa91..f434e96ce020 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -60,6 +60,7 @@ struct hci_conn_hash {
60 spinlock_t lock; 60 spinlock_t lock;
61 unsigned int acl_num; 61 unsigned int acl_num;
62 unsigned int sco_num; 62 unsigned int sco_num;
63 unsigned int le_num;
63}; 64};
64 65
65struct bdaddr_list { 66struct bdaddr_list {
@@ -309,20 +310,36 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
309{ 310{
310 struct hci_conn_hash *h = &hdev->conn_hash; 311 struct hci_conn_hash *h = &hdev->conn_hash;
311 list_add(&c->list, &h->list); 312 list_add(&c->list, &h->list);
312 if (c->type == ACL_LINK) 313 switch (c->type) {
314 case ACL_LINK:
313 h->acl_num++; 315 h->acl_num++;
314 else 316 break;
317 case LE_LINK:
318 h->le_num++;
319 break;
320 case SCO_LINK:
321 case ESCO_LINK:
315 h->sco_num++; 322 h->sco_num++;
323 break;
324 }
316} 325}
317 326
318static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c) 327static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
319{ 328{
320 struct hci_conn_hash *h = &hdev->conn_hash; 329 struct hci_conn_hash *h = &hdev->conn_hash;
321 list_del(&c->list); 330 list_del(&c->list);
322 if (c->type == ACL_LINK) 331 switch (c->type) {
332 case ACL_LINK:
323 h->acl_num--; 333 h->acl_num--;
324 else 334 break;
335 case LE_LINK:
336 h->le_num--;
337 break;
338 case SCO_LINK:
339 case ESCO_LINK:
325 h->sco_num--; 340 h->sco_num--;
341 break;
342 }
326} 343}
327 344
328static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev, 345static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 42dc39f25b72..d0c470c18f9d 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -45,6 +45,32 @@
45#include <net/bluetooth/bluetooth.h> 45#include <net/bluetooth/bluetooth.h>
46#include <net/bluetooth/hci_core.h> 46#include <net/bluetooth/hci_core.h>
47 47
48static void hci_le_connect(struct hci_conn *conn)
49{
50 struct hci_dev *hdev = conn->hdev;
51 struct hci_cp_le_create_conn cp;
52
53 conn->state = BT_CONNECT;
54 conn->out = 1;
55
56 memset(&cp, 0, sizeof(cp));
57 cp.scan_interval = cpu_to_le16(0x0004);
58 cp.scan_window = cpu_to_le16(0x0004);
59 bacpy(&cp.peer_addr, &conn->dst);
60 cp.conn_interval_min = cpu_to_le16(0x0008);
61 cp.conn_interval_max = cpu_to_le16(0x0100);
62 cp.supervision_timeout = cpu_to_le16(0x0064);
63 cp.min_ce_len = cpu_to_le16(0x0001);
64 cp.max_ce_len = cpu_to_le16(0x0001);
65
66 hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
67}
68
69static void hci_le_connect_cancel(struct hci_conn *conn)
70{
71 hci_send_cmd(conn->hdev, HCI_OP_LE_CREATE_CONN_CANCEL, 0, NULL);
72}
73
48void hci_acl_connect(struct hci_conn *conn) 74void hci_acl_connect(struct hci_conn *conn)
49{ 75{
50 struct hci_dev *hdev = conn->hdev; 76 struct hci_dev *hdev = conn->hdev;
@@ -193,8 +219,12 @@ static void hci_conn_timeout(unsigned long arg)
193 switch (conn->state) { 219 switch (conn->state) {
194 case BT_CONNECT: 220 case BT_CONNECT:
195 case BT_CONNECT2: 221 case BT_CONNECT2:
196 if (conn->type == ACL_LINK && conn->out) 222 if (conn->out) {
197 hci_acl_connect_cancel(conn); 223 if (conn->type == ACL_LINK)
224 hci_acl_connect_cancel(conn);
225 else if (conn->type == LE_LINK)
226 hci_le_connect_cancel(conn);
227 }
198 break; 228 break;
199 case BT_CONFIG: 229 case BT_CONFIG:
200 case BT_CONNECTED: 230 case BT_CONNECTED:
@@ -361,15 +391,30 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
361} 391}
362EXPORT_SYMBOL(hci_get_route); 392EXPORT_SYMBOL(hci_get_route);
363 393
364/* Create SCO or ACL connection. 394/* Create SCO, ACL or LE connection.
365 * Device _must_ be locked */ 395 * Device _must_ be locked */
366struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type) 396struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type)
367{ 397{
368 struct hci_conn *acl; 398 struct hci_conn *acl;
369 struct hci_conn *sco; 399 struct hci_conn *sco;
400 struct hci_conn *le;
370 401
371 BT_DBG("%s dst %s", hdev->name, batostr(dst)); 402 BT_DBG("%s dst %s", hdev->name, batostr(dst));
372 403
404 if (type == LE_LINK) {
405 le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
406 if (!le)
407 le = hci_conn_add(hdev, LE_LINK, dst);
408 if (!le)
409 return NULL;
410 if (le->state == BT_OPEN)
411 hci_le_connect(le);
412
413 hci_conn_hold(le);
414
415 return le;
416 }
417
373 acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); 418 acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
374 if (!acl) { 419 if (!acl) {
375 acl = hci_conn_add(hdev, ACL_LINK, dst); 420 acl = hci_conn_add(hdev, ACL_LINK, dst);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index cee46cbe7aeb..47c6e9316ce8 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1107,6 +1107,43 @@ static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1107 hci_dev_unlock(hdev); 1107 hci_dev_unlock(hdev);
1108} 1108}
1109 1109
1110static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1111{
1112 struct hci_cp_le_create_conn *cp;
1113 struct hci_conn *conn;
1114
1115 BT_DBG("%s status 0x%x", hdev->name, status);
1116
1117 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1118 if (!cp)
1119 return;
1120
1121 hci_dev_lock(hdev);
1122
1123 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1124
1125 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1126 conn);
1127
1128 if (status) {
1129 if (conn && conn->state == BT_CONNECT) {
1130 conn->state = BT_CLOSED;
1131 hci_proto_connect_cfm(conn, status);
1132 hci_conn_del(conn);
1133 }
1134 } else {
1135 if (!conn) {
1136 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
1137 if (conn)
1138 conn->out = 1;
1139 else
1140 BT_ERR("No memory for new connection");
1141 }
1142 }
1143
1144 hci_dev_unlock(hdev);
1145}
1146
1110static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 1147static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1111{ 1148{
1112 __u8 status = *((__u8 *) skb->data); 1149 __u8 status = *((__u8 *) skb->data);
@@ -1738,6 +1775,10 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
1738 mgmt_disconnect_failed(hdev->id); 1775 mgmt_disconnect_failed(hdev->id);
1739 break; 1776 break;
1740 1777
1778 case HCI_OP_LE_CREATE_CONN:
1779 hci_cs_le_create_conn(hdev, ev->status);
1780 break;
1781
1741 default: 1782 default:
1742 BT_DBG("%s opcode 0x%x", hdev->name, opcode); 1783 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1743 break; 1784 break;
@@ -2321,6 +2362,54 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_
2321 hci_dev_unlock(hdev); 2362 hci_dev_unlock(hdev);
2322} 2363}
2323 2364
2365static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2366{
2367 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
2368 struct hci_conn *conn;
2369
2370 BT_DBG("%s status %d", hdev->name, ev->status);
2371
2372 hci_dev_lock(hdev);
2373
2374 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
2375 if (!conn)
2376 goto unlock;
2377
2378 if (ev->status) {
2379 hci_proto_connect_cfm(conn, ev->status);
2380 conn->state = BT_CLOSED;
2381 hci_conn_del(conn);
2382 goto unlock;
2383 }
2384
2385 conn->handle = __le16_to_cpu(ev->handle);
2386 conn->state = BT_CONNECTED;
2387
2388 hci_conn_hold_device(conn);
2389 hci_conn_add_sysfs(conn);
2390
2391 hci_proto_connect_cfm(conn, ev->status);
2392
2393unlock:
2394 hci_dev_unlock(hdev);
2395}
2396
2397static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
2398{
2399 struct hci_ev_le_meta *le_ev = (void *) skb->data;
2400
2401 skb_pull(skb, sizeof(*le_ev));
2402
2403 switch (le_ev->subevent) {
2404 case HCI_EV_LE_CONN_COMPLETE:
2405 hci_le_conn_complete_evt(hdev, skb);
2406 break;
2407
2408 default:
2409 break;
2410 }
2411}
2412
2324void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) 2413void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
2325{ 2414{
2326 struct hci_event_hdr *hdr = (void *) skb->data; 2415 struct hci_event_hdr *hdr = (void *) skb->data;
@@ -2461,6 +2550,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
2461 hci_remote_host_features_evt(hdev, skb); 2550 hci_remote_host_features_evt(hdev, skb);
2462 break; 2551 break;
2463 2552
2553 case HCI_EV_LE_META:
2554 hci_le_meta_evt(hdev, skb);
2555 break;
2556
2464 default: 2557 default:
2465 BT_DBG("%s event 0x%x", hdev->name, event); 2558 BT_DBG("%s event 0x%x", hdev->name, event);
2466 break; 2559 break;