blob: 3e65c021df509193e3a3903a51026c39e3a09f20 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI connection handling. */
26
Gustavo Padovan8c520a52012-05-23 04:04:22 -030027#include <linux/export.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070028
29#include <net/bluetooth/bluetooth.h>
30#include <net/bluetooth/hci_core.h>
Andrei Emeltchenko9740e492012-05-29 13:59:02 +030031#include <net/bluetooth/a2mp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032
Vinicius Costa Gomes1aef8662012-07-27 19:32:55 -030033static void hci_le_create_connection(struct hci_conn *conn)
Ville Tervofcd89c02011-02-10 22:38:47 -030034{
35 struct hci_dev *hdev = conn->hdev;
36 struct hci_cp_le_create_conn cp;
37
38 conn->state = BT_CONNECT;
Johan Hedberga0c808b2012-01-16 09:49:58 +020039 conn->out = true;
Vinicius Costa Gomesb92a6222011-02-10 22:38:52 -030040 conn->link_mode |= HCI_LM_MASTER;
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -030041 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -030042
43 memset(&cp, 0, sizeof(cp));
Andrei Emeltchenko82781e62012-05-25 11:38:27 +030044 cp.scan_interval = __constant_cpu_to_le16(0x0060);
45 cp.scan_window = __constant_cpu_to_le16(0x0030);
Ville Tervofcd89c02011-02-10 22:38:47 -030046 bacpy(&cp.peer_addr, &conn->dst);
Andre Guedes6d3ce0e72011-05-31 14:20:57 -030047 cp.peer_addr_type = conn->dst_type;
Andrei Emeltchenko82781e62012-05-25 11:38:27 +030048 cp.conn_interval_min = __constant_cpu_to_le16(0x0028);
49 cp.conn_interval_max = __constant_cpu_to_le16(0x0038);
50 cp.supervision_timeout = __constant_cpu_to_le16(0x002a);
51 cp.min_ce_len = __constant_cpu_to_le16(0x0000);
52 cp.max_ce_len = __constant_cpu_to_le16(0x0000);
Ville Tervofcd89c02011-02-10 22:38:47 -030053
54 hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
55}
56
Vinicius Costa Gomes1aef8662012-07-27 19:32:55 -030057static void hci_le_create_connection_cancel(struct hci_conn *conn)
Ville Tervofcd89c02011-02-10 22:38:47 -030058{
59 hci_send_cmd(conn->hdev, HCI_OP_LE_CREATE_CONN_CANCEL, 0, NULL);
60}
61
Vinicius Costa Gomes1aef8662012-07-27 19:32:55 -030062static void hci_acl_create_connection(struct hci_conn *conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -070063{
64 struct hci_dev *hdev = conn->hdev;
65 struct inquiry_entry *ie;
66 struct hci_cp_create_conn cp;
67
Andrei Emeltchenko42d2d872012-02-17 11:40:57 +020068 BT_DBG("hcon %p", conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -070069
70 conn->state = BT_CONNECT;
Johan Hedberga0c808b2012-01-16 09:49:58 +020071 conn->out = true;
Marcel Holtmanna8746412008-07-14 20:13:46 +020072
Linus Torvalds1da177e2005-04-16 15:20:36 -070073 conn->link_mode = HCI_LM_MASTER;
74
Marcel Holtmann4c67bc72006-10-15 17:30:56 +020075 conn->attempt++;
76
Marcel Holtmanne4e8e372008-07-14 20:13:47 +020077 conn->link_policy = hdev->link_policy;
78
Linus Torvalds1da177e2005-04-16 15:20:36 -070079 memset(&cp, 0, sizeof(cp));
80 bacpy(&cp.bdaddr, &conn->dst);
81 cp.pscan_rep_mode = 0x02;
82
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020083 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
84 if (ie) {
Marcel Holtmann41a96212008-07-14 20:13:48 +020085 if (inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) {
86 cp.pscan_rep_mode = ie->data.pscan_rep_mode;
87 cp.pscan_mode = ie->data.pscan_mode;
88 cp.clock_offset = ie->data.clock_offset |
Andrei Emeltchenko82781e62012-05-25 11:38:27 +030089 __constant_cpu_to_le16(0x8000);
Marcel Holtmann41a96212008-07-14 20:13:48 +020090 }
91
Linus Torvalds1da177e2005-04-16 15:20:36 -070092 memcpy(conn->dev_class, ie->data.dev_class, 3);
Johan Hedberg58a681e2012-01-16 06:47:28 +020093 if (ie->data.ssp_mode > 0)
94 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 }
96
Marcel Holtmanna8746412008-07-14 20:13:46 +020097 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -070098 if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER))
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +020099 cp.role_switch = 0x01;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100 else
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200101 cp.role_switch = 0x00;
Marcel Holtmann4c67bc72006-10-15 17:30:56 +0200102
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200103 hci_send_cmd(hdev, HCI_OP_CREATE_CONN, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104}
105
Vinicius Costa Gomes1aef8662012-07-27 19:32:55 -0300106static void hci_acl_create_connection_cancel(struct hci_conn *conn)
Marcel Holtmann6ac59342006-09-26 09:43:48 +0200107{
108 struct hci_cp_create_conn_cancel cp;
109
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300110 BT_DBG("hcon %p", conn);
Marcel Holtmann6ac59342006-09-26 09:43:48 +0200111
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200112 if (conn->hdev->hci_ver < BLUETOOTH_VER_1_2)
Marcel Holtmann6ac59342006-09-26 09:43:48 +0200113 return;
114
115 bacpy(&cp.bdaddr, &conn->dst);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200116 hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp);
Marcel Holtmann6ac59342006-09-26 09:43:48 +0200117}
118
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
120{
121 struct hci_cp_disconnect cp;
122
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300123 BT_DBG("hcon %p", conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124
125 conn->state = BT_DISCONN;
126
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -0700127 cp.handle = cpu_to_le16(conn->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128 cp.reason = reason;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200129 hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130}
131
Vinicius Costa Gomes57f5d0d2012-07-27 19:32:54 -0300132static void hci_add_sco(struct hci_conn *conn, __u16 handle)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133{
134 struct hci_dev *hdev = conn->hdev;
135 struct hci_cp_add_sco cp;
136
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300137 BT_DBG("hcon %p", conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138
139 conn->state = BT_CONNECT;
Johan Hedberga0c808b2012-01-16 09:49:58 +0200140 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141
Marcel Holtmannefc76882009-02-06 09:13:37 +0100142 conn->attempt++;
143
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -0700144 cp.handle = cpu_to_le16(handle);
Marcel Holtmanna8746412008-07-14 20:13:46 +0200145 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200147 hci_send_cmd(hdev, HCI_OP_ADD_SCO, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148}
149
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200150void hci_setup_sync(struct hci_conn *conn, __u16 handle)
151{
152 struct hci_dev *hdev = conn->hdev;
153 struct hci_cp_setup_sync_conn cp;
154
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300155 BT_DBG("hcon %p", conn);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200156
157 conn->state = BT_CONNECT;
Johan Hedberga0c808b2012-01-16 09:49:58 +0200158 conn->out = true;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200159
Marcel Holtmannefc76882009-02-06 09:13:37 +0100160 conn->attempt++;
161
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200162 cp.handle = cpu_to_le16(handle);
Marcel Holtmanna8746412008-07-14 20:13:46 +0200163 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200164
Andrei Emeltchenko82781e62012-05-25 11:38:27 +0300165 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
166 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
167 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200168 cp.voice_setting = cpu_to_le16(hdev->voice_setting);
169 cp.retrans_effort = 0xff;
170
171 hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
172}
173
Claudio Takahasi2ce603e2011-02-16 20:44:53 -0200174void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
Gustavo Padovan5974e4c2012-05-17 00:36:25 -0300175 u16 latency, u16 to_multiplier)
Claudio Takahasi2ce603e2011-02-16 20:44:53 -0200176{
177 struct hci_cp_le_conn_update cp;
178 struct hci_dev *hdev = conn->hdev;
179
180 memset(&cp, 0, sizeof(cp));
181
182 cp.handle = cpu_to_le16(conn->handle);
183 cp.conn_interval_min = cpu_to_le16(min);
184 cp.conn_interval_max = cpu_to_le16(max);
185 cp.conn_latency = cpu_to_le16(latency);
186 cp.supervision_timeout = cpu_to_le16(to_multiplier);
Andrei Emeltchenko82781e62012-05-25 11:38:27 +0300187 cp.min_ce_len = __constant_cpu_to_le16(0x0001);
188 cp.max_ce_len = __constant_cpu_to_le16(0x0001);
Claudio Takahasi2ce603e2011-02-16 20:44:53 -0200189
190 hci_send_cmd(hdev, HCI_OP_LE_CONN_UPDATE, sizeof(cp), &cp);
191}
Claudio Takahasi2ce603e2011-02-16 20:44:53 -0200192
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -0300193void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8],
Gustavo Padovan5974e4c2012-05-17 00:36:25 -0300194 __u8 ltk[16])
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -0300195{
196 struct hci_dev *hdev = conn->hdev;
197 struct hci_cp_le_start_enc cp;
198
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300199 BT_DBG("hcon %p", conn);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -0300200
201 memset(&cp, 0, sizeof(cp));
202
203 cp.handle = cpu_to_le16(conn->handle);
204 memcpy(cp.ltk, ltk, sizeof(cp.ltk));
205 cp.ediv = ediv;
Anderson Briglia51beabd2011-09-19 14:41:09 -0400206 memcpy(cp.rand, rand, sizeof(cp.rand));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -0300207
208 hci_send_cmd(hdev, HCI_OP_LE_START_ENC, sizeof(cp), &cp);
209}
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -0300210
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400211/* Device _must_ be locked */
212void hci_sco_setup(struct hci_conn *conn, __u8 status)
213{
214 struct hci_conn *sco = conn->link;
215
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400216 if (!sco)
217 return;
218
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300219 BT_DBG("hcon %p", conn);
220
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400221 if (!status) {
222 if (lmp_esco_capable(conn->hdev))
223 hci_setup_sync(sco, conn->handle);
224 else
225 hci_add_sco(sco, conn->handle);
226 } else {
227 hci_proto_connect_cfm(sco, status);
228 hci_conn_del(sco);
229 }
230}
231
Gustavo F. Padovan19c40e32011-06-17 13:03:21 -0300232static void hci_conn_timeout(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233{
Gustavo F. Padovan19c40e32011-06-17 13:03:21 -0300234 struct hci_conn *conn = container_of(work, struct hci_conn,
Gustavo Padovan5974e4c2012-05-17 00:36:25 -0300235 disc_work.work);
Marcel Holtmann2950f212009-02-12 14:02:50 +0100236 __u8 reason;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300238 BT_DBG("hcon %p state %s", conn, state_to_string(conn->state));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239
240 if (atomic_read(&conn->refcnt))
241 return;
242
Marcel Holtmann6ac59342006-09-26 09:43:48 +0200243 switch (conn->state) {
244 case BT_CONNECT:
Marcel Holtmann769be972008-07-14 20:13:49 +0200245 case BT_CONNECT2:
Ville Tervofcd89c02011-02-10 22:38:47 -0300246 if (conn->out) {
247 if (conn->type == ACL_LINK)
Vinicius Costa Gomes1aef8662012-07-27 19:32:55 -0300248 hci_acl_create_connection_cancel(conn);
Ville Tervofcd89c02011-02-10 22:38:47 -0300249 else if (conn->type == LE_LINK)
Vinicius Costa Gomes1aef8662012-07-27 19:32:55 -0300250 hci_le_create_connection_cancel(conn);
Ville Tervofcd89c02011-02-10 22:38:47 -0300251 }
Marcel Holtmann6ac59342006-09-26 09:43:48 +0200252 break;
Marcel Holtmann769be972008-07-14 20:13:49 +0200253 case BT_CONFIG:
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900254 case BT_CONNECTED:
Marcel Holtmann2950f212009-02-12 14:02:50 +0100255 reason = hci_proto_disconn_ind(conn);
256 hci_acl_disconn(conn, reason);
Marcel Holtmann6ac59342006-09-26 09:43:48 +0200257 break;
258 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259 conn->state = BT_CLOSED;
Marcel Holtmann6ac59342006-09-26 09:43:48 +0200260 break;
261 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262}
263
Gustavo F. Padovan416dc942011-12-07 13:24:33 -0200264/* Enter sniff mode */
265static void hci_conn_enter_sniff_mode(struct hci_conn *conn)
266{
267 struct hci_dev *hdev = conn->hdev;
268
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300269 BT_DBG("hcon %p mode %d", conn, conn->mode);
Gustavo F. Padovan416dc942011-12-07 13:24:33 -0200270
271 if (test_bit(HCI_RAW, &hdev->flags))
272 return;
273
274 if (!lmp_sniff_capable(hdev) || !lmp_sniff_capable(conn))
275 return;
276
277 if (conn->mode != HCI_CM_ACTIVE || !(conn->link_policy & HCI_LP_SNIFF))
278 return;
279
280 if (lmp_sniffsubr_capable(hdev) && lmp_sniffsubr_capable(conn)) {
281 struct hci_cp_sniff_subrate cp;
282 cp.handle = cpu_to_le16(conn->handle);
Andrei Emeltchenko82781e62012-05-25 11:38:27 +0300283 cp.max_latency = __constant_cpu_to_le16(0);
284 cp.min_remote_timeout = __constant_cpu_to_le16(0);
285 cp.min_local_timeout = __constant_cpu_to_le16(0);
Gustavo F. Padovan416dc942011-12-07 13:24:33 -0200286 hci_send_cmd(hdev, HCI_OP_SNIFF_SUBRATE, sizeof(cp), &cp);
287 }
288
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200289 if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Gustavo F. Padovan416dc942011-12-07 13:24:33 -0200290 struct hci_cp_sniff_mode cp;
291 cp.handle = cpu_to_le16(conn->handle);
292 cp.max_interval = cpu_to_le16(hdev->sniff_max_interval);
293 cp.min_interval = cpu_to_le16(hdev->sniff_min_interval);
Andrei Emeltchenko82781e62012-05-25 11:38:27 +0300294 cp.attempt = __constant_cpu_to_le16(4);
295 cp.timeout = __constant_cpu_to_le16(1);
Gustavo F. Padovan416dc942011-12-07 13:24:33 -0200296 hci_send_cmd(hdev, HCI_OP_SNIFF_MODE, sizeof(cp), &cp);
297 }
298}
299
Marcel Holtmann04837f62006-07-03 10:02:33 +0200300static void hci_conn_idle(unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301{
Marcel Holtmann04837f62006-07-03 10:02:33 +0200302 struct hci_conn *conn = (void *) arg;
303
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300304 BT_DBG("hcon %p mode %d", conn, conn->mode);
Marcel Holtmann04837f62006-07-03 10:02:33 +0200305
306 hci_conn_enter_sniff_mode(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307}
308
Johan Hedberg9f616562011-04-28 11:28:54 -0700309static void hci_conn_auto_accept(unsigned long arg)
310{
311 struct hci_conn *conn = (void *) arg;
312 struct hci_dev *hdev = conn->hdev;
313
Johan Hedberg9f616562011-04-28 11:28:54 -0700314 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, sizeof(conn->dst),
Gustavo Padovan5974e4c2012-05-17 00:36:25 -0300315 &conn->dst);
Johan Hedberg9f616562011-04-28 11:28:54 -0700316}
317
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
319{
320 struct hci_conn *conn;
321
322 BT_DBG("%s dst %s", hdev->name, batostr(dst));
323
Andre Guedescb601d72012-01-30 09:22:09 -0300324 conn = kzalloc(sizeof(struct hci_conn), GFP_KERNEL);
Marcel Holtmann04837f62006-07-03 10:02:33 +0200325 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327
328 bacpy(&conn->dst, dst);
Marcel Holtmanna8746412008-07-14 20:13:46 +0200329 conn->hdev = hdev;
330 conn->type = type;
331 conn->mode = HCI_CM_ACTIVE;
332 conn->state = BT_OPEN;
Andrei Emeltchenko93f19c92009-09-03 12:34:19 +0300333 conn->auth_type = HCI_AT_GENERAL_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +0200334 conn->io_capability = hdev->io_capability;
Johan Hedberga9583552011-02-19 12:06:01 -0300335 conn->remote_auth = 0xff;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +0200336 conn->key_type = 0xff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337
Johan Hedberg58a681e2012-01-16 06:47:28 +0200338 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann052b30b2009-04-26 20:01:22 +0200339 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann04837f62006-07-03 10:02:33 +0200340
Marcel Holtmanna8746412008-07-14 20:13:46 +0200341 switch (type) {
342 case ACL_LINK:
343 conn->pkt_type = hdev->pkt_type & ACL_PTYPE_MASK;
344 break;
345 case SCO_LINK:
346 if (lmp_esco_capable(hdev))
Marcel Holtmannefc76882009-02-06 09:13:37 +0100347 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
348 (hdev->esco_type & EDR_ESCO_MASK);
Marcel Holtmanna8746412008-07-14 20:13:46 +0200349 else
350 conn->pkt_type = hdev->pkt_type & SCO_PTYPE_MASK;
351 break;
352 case ESCO_LINK:
Marcel Holtmannefc76882009-02-06 09:13:37 +0100353 conn->pkt_type = hdev->esco_type & ~EDR_ESCO_MASK;
Marcel Holtmanna8746412008-07-14 20:13:46 +0200354 break;
355 }
356
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357 skb_queue_head_init(&conn->data_q);
Marcel Holtmann04837f62006-07-03 10:02:33 +0200358
Marcel Holtmann70c1f202012-02-22 12:06:43 +0100359 INIT_LIST_HEAD(&conn->chan_list);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200360
Gustavo F. Padovan19c40e32011-06-17 13:03:21 -0300361 INIT_DELAYED_WORK(&conn->disc_work, hci_conn_timeout);
Pavel Emelyanovb24b8a22008-01-23 21:20:07 -0800362 setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn);
Johan Hedberg9f616562011-04-28 11:28:54 -0700363 setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept,
Gustavo Padovan5974e4c2012-05-17 00:36:25 -0300364 (unsigned long) conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365
366 atomic_set(&conn->refcnt, 0);
367
368 hci_dev_hold(hdev);
369
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 hci_conn_hash_add(hdev, conn);
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200371 if (hdev->notify)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
373
Marcel Holtmann9eba32b2009-08-22 14:19:26 -0700374 atomic_set(&conn->devref, 0);
375
Marcel Holtmanna67e8992009-05-02 18:24:06 -0700376 hci_conn_init_sysfs(conn);
377
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 return conn;
379}
380
381int hci_conn_del(struct hci_conn *conn)
382{
383 struct hci_dev *hdev = conn->hdev;
384
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300385 BT_DBG("%s hcon %p handle %d", hdev->name, conn, conn->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386
Marcel Holtmann04837f62006-07-03 10:02:33 +0200387 del_timer(&conn->idle_timer);
388
Gustavo F. Padovan19c40e32011-06-17 13:03:21 -0300389 cancel_delayed_work_sync(&conn->disc_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390
Johan Hedberg9f616562011-04-28 11:28:54 -0700391 del_timer(&conn->auto_accept_timer);
392
Marcel Holtmann5b7f9902007-07-11 09:51:55 +0200393 if (conn->type == ACL_LINK) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394 struct hci_conn *sco = conn->link;
395 if (sco)
396 sco->link = NULL;
397
398 /* Unacked frames */
399 hdev->acl_cnt += conn->sent;
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300400 } else if (conn->type == LE_LINK) {
401 if (hdev->le_pkts)
402 hdev->le_cnt += conn->sent;
403 else
404 hdev->acl_cnt += conn->sent;
Marcel Holtmann5b7f9902007-07-11 09:51:55 +0200405 } else {
406 struct hci_conn *acl = conn->link;
407 if (acl) {
408 acl->link = NULL;
409 hci_conn_put(acl);
410 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411 }
412
Gustavo F. Padovan2c33c062011-12-14 13:02:51 -0200413 hci_chan_list_flush(conn);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200414
Andrei Emeltchenko9740e492012-05-29 13:59:02 +0300415 if (conn->amp_mgr)
416 amp_mgr_put(conn->amp_mgr);
417
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 hci_conn_hash_del(hdev, conn);
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200419 if (hdev->notify)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +0200421
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 skb_queue_purge(&conn->data_q);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423
Marcel Holtmann9eba32b2009-08-22 14:19:26 -0700424 hci_conn_put_device(conn);
Dave Young2ae9a6b2009-02-21 16:13:34 +0800425
Marcel Holtmann384943e2009-05-08 18:20:43 -0700426 hci_dev_put(hdev);
427
Tomas Targownik163f4da2011-06-30 16:30:44 -0300428 if (conn->handle == 0)
429 kfree(conn);
430
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431 return 0;
432}
433
434struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
435{
436 int use_src = bacmp(src, BDADDR_ANY);
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200437 struct hci_dev *hdev = NULL, *d;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438
439 BT_DBG("%s -> %s", batostr(src), batostr(dst));
440
Gustavo F. Padovanf20d09d2011-12-22 16:30:27 -0200441 read_lock(&hci_dev_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200443 list_for_each_entry(d, &hci_dev_list, list) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300444 if (!test_bit(HCI_UP, &d->flags) ||
Andrei Emeltchenkod300fa92012-06-19 15:21:21 +0300445 test_bit(HCI_RAW, &d->flags) ||
446 d->dev_type != HCI_BREDR)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447 continue;
448
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900449 /* Simple routing:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450 * No source address - find interface with bdaddr != dst
451 * Source address - find interface with bdaddr == src
452 */
453
454 if (use_src) {
455 if (!bacmp(&d->bdaddr, src)) {
456 hdev = d; break;
457 }
458 } else {
459 if (bacmp(&d->bdaddr, dst)) {
460 hdev = d; break;
461 }
462 }
463 }
464
465 if (hdev)
466 hdev = hci_dev_hold(hdev);
467
Gustavo F. Padovanf20d09d2011-12-22 16:30:27 -0200468 read_unlock(&hci_dev_list_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469 return hdev;
470}
471EXPORT_SYMBOL(hci_get_route);
472
Vinicius Costa Gomesd04aef42012-07-27 19:32:56 -0300473static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
474 u8 dst_type, u8 sec_level, u8 auth_type)
475{
476 struct hci_conn *le;
477
478 le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
479 if (!le) {
480 le = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
481 if (le)
482 return ERR_PTR(-EBUSY);
483
484 le = hci_conn_add(hdev, LE_LINK, dst);
485 if (!le)
486 return ERR_PTR(-ENOMEM);
487
488 le->dst_type = bdaddr_to_le(dst_type);
489 hci_le_create_connection(le);
490 }
491
492 le->pending_sec_level = sec_level;
493 le->auth_type = auth_type;
494
495 hci_conn_hold(le);
496
497 return le;
498}
499
Vinicius Costa Gomesdb474272012-07-28 22:35:59 -0300500static struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
501 u8 sec_level, u8 auth_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502{
503 struct hci_conn *acl;
Ville Tervofcd89c02011-02-10 22:38:47 -0300504
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200505 acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
506 if (!acl) {
507 acl = hci_conn_add(hdev, ACL_LINK, dst);
508 if (!acl)
Johan Hedberg48c7aba2012-02-19 14:06:48 +0200509 return ERR_PTR(-ENOMEM);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510 }
511
512 hci_conn_hold(acl);
513
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200514 if (acl->state == BT_OPEN || acl->state == BT_CLOSED) {
Johan Hedberg765c2a92011-01-19 12:06:52 +0530515 acl->sec_level = BT_SECURITY_LOW;
516 acl->pending_sec_level = sec_level;
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200517 acl->auth_type = auth_type;
Vinicius Costa Gomes1aef8662012-07-27 19:32:55 -0300518 hci_acl_create_connection(acl);
Marcel Holtmann09ab6f42008-09-09 07:19:20 +0200519 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520
Vinicius Costa Gomesdb474272012-07-28 22:35:59 -0300521 return acl;
522}
523
Vinicius Costa Gomesf91c84682012-08-17 21:37:59 -0300524static struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type,
525 bdaddr_t *dst, u8 sec_level, u8 auth_type)
Vinicius Costa Gomesdb474272012-07-28 22:35:59 -0300526{
527 struct hci_conn *acl;
528 struct hci_conn *sco;
529
Vinicius Costa Gomesdb474272012-07-28 22:35:59 -0300530 acl = hci_connect_acl(hdev, dst, sec_level, auth_type);
531 if (IS_ERR(acl))
532 return acl;
533
Vinicius Costa Gomesf91c84682012-08-17 21:37:59 -0300534 sco = hci_conn_hash_lookup_ba(hdev, type, dst);
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200535 if (!sco) {
Vinicius Costa Gomesf91c84682012-08-17 21:37:59 -0300536 sco = hci_conn_add(hdev, type, dst);
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200537 if (!sco) {
Marcel Holtmann5b7f9902007-07-11 09:51:55 +0200538 hci_conn_put(acl);
Johan Hedberg48c7aba2012-02-19 14:06:48 +0200539 return ERR_PTR(-ENOMEM);
Marcel Holtmann5b7f9902007-07-11 09:51:55 +0200540 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 }
Marcel Holtmann5b7f9902007-07-11 09:51:55 +0200542
543 acl->link = sco;
544 sco->link = acl;
545
546 hci_conn_hold(sco);
547
548 if (acl->state == BT_CONNECTED &&
Gustavo Padovan5974e4c2012-05-17 00:36:25 -0300549 (sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
Johan Hedberg58a681e2012-01-16 06:47:28 +0200550 set_bit(HCI_CONN_POWER_SAVE, &acl->flags);
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700551 hci_conn_enter_active_mode(acl, BT_POWER_FORCE_ACTIVE_ON);
Nick Pellyc3902162009-11-13 14:16:32 -0800552
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200553 if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->flags)) {
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400554 /* defer SCO setup until mode change completed */
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200555 set_bit(HCI_CONN_SCO_SETUP_PEND, &acl->flags);
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400556 return sco;
557 }
558
559 hci_sco_setup(acl, 0x00);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200560 }
Marcel Holtmann5b7f9902007-07-11 09:51:55 +0200561
562 return sco;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564
Vinicius Costa Gomesb7d839b2012-07-27 19:32:58 -0300565/* Create SCO, ACL or LE connection. */
566struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst,
567 __u8 dst_type, __u8 sec_level, __u8 auth_type)
568{
Vinicius Costa Gomese6dd5482012-07-27 19:33:00 -0300569 BT_DBG("%s dst %s type 0x%x", hdev->name, batostr(dst), type);
Vinicius Costa Gomesb7d839b2012-07-27 19:32:58 -0300570
Vinicius Costa Gomes4cd2d982012-07-27 19:32:59 -0300571 switch (type) {
572 case LE_LINK:
Vinicius Costa Gomesb7d839b2012-07-27 19:32:58 -0300573 return hci_connect_le(hdev, dst, dst_type, sec_level, auth_type);
Vinicius Costa Gomes4cd2d982012-07-27 19:32:59 -0300574 case ACL_LINK:
Vinicius Costa Gomesb7d839b2012-07-27 19:32:58 -0300575 return hci_connect_acl(hdev, dst, sec_level, auth_type);
Vinicius Costa Gomes4cd2d982012-07-27 19:32:59 -0300576 case SCO_LINK:
Vinicius Costa Gomesf91c84682012-08-17 21:37:59 -0300577 case ESCO_LINK:
578 return hci_connect_sco(hdev, type, dst, sec_level, auth_type);
Vinicius Costa Gomes4cd2d982012-07-27 19:32:59 -0300579 }
Vinicius Costa Gomesb7d839b2012-07-27 19:32:58 -0300580
Vinicius Costa Gomes4cd2d982012-07-27 19:32:59 -0300581 return ERR_PTR(-EINVAL);
Vinicius Costa Gomesb7d839b2012-07-27 19:32:58 -0300582}
583
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +0200584/* Check link security requirement */
585int hci_conn_check_link_mode(struct hci_conn *conn)
586{
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300587 BT_DBG("hcon %p", conn);
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +0200588
Johan Hedbergaa64a8b2012-01-18 21:33:12 +0200589 if (hci_conn_ssp_enabled(conn) && !(conn->link_mode & HCI_LM_ENCRYPT))
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +0200590 return 0;
591
592 return 1;
593}
Marcel Holtmanne7c29cb2008-09-09 07:19:20 +0200594
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595/* Authenticate remote device */
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100596static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597{
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300598 BT_DBG("hcon %p", conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599
Johan Hedberg765c2a92011-01-19 12:06:52 +0530600 if (conn->pending_sec_level > sec_level)
601 sec_level = conn->pending_sec_level;
602
Marcel Holtmann96a31832009-02-12 16:23:03 +0100603 if (sec_level > conn->sec_level)
Johan Hedberg765c2a92011-01-19 12:06:52 +0530604 conn->pending_sec_level = sec_level;
Marcel Holtmann96a31832009-02-12 16:23:03 +0100605 else if (conn->link_mode & HCI_LM_AUTH)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606 return 1;
607
Johan Hedberg65cf6862011-01-19 12:06:49 +0530608 /* Make sure we preserve an existing MITM requirement*/
609 auth_type |= (conn->auth_type & 0x01);
610
Marcel Holtmann96a31832009-02-12 16:23:03 +0100611 conn->auth_type = auth_type;
612
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200613 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 struct hci_cp_auth_requested cp;
Peter Hurleyb7d05ba2012-01-13 15:11:30 +0100615
616 /* encrypt must be pending if auth is also pending */
617 set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
618
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -0700619 cp.handle = cpu_to_le16(conn->handle);
Marcel Holtmann40be4922008-07-14 20:13:50 +0200620 hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED,
Gustavo Padovan5974e4c2012-05-17 00:36:25 -0300621 sizeof(cp), &cp);
Waldemar Rymarkiewicz19f8def2011-05-31 15:49:25 +0200622 if (conn->key_type != 0xff)
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200623 set_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100625
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626 return 0;
627}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +0200629/* Encrypt the the link */
630static void hci_conn_encrypt(struct hci_conn *conn)
631{
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300632 BT_DBG("hcon %p", conn);
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +0200633
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200634 if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +0200635 struct hci_cp_set_conn_encrypt cp;
636 cp.handle = cpu_to_le16(conn->handle);
637 cp.encrypt = 0x01;
638 hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan5974e4c2012-05-17 00:36:25 -0300639 &cp);
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +0200640 }
641}
642
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100643/* Enable security */
Marcel Holtmann0684e5f2009-02-09 02:48:38 +0100644int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645{
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300646 BT_DBG("hcon %p", conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +0200648 /* For sdp we don't need the link key. */
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100649 if (sec_level == BT_SECURITY_SDP)
650 return 1;
651
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +0200652 /* For non 2.1 devices and low security level we don't need the link
653 key. */
Johan Hedbergaa64a8b2012-01-18 21:33:12 +0200654 if (sec_level == BT_SECURITY_LOW && !hci_conn_ssp_enabled(conn))
Marcel Holtmann3fdca1e2009-04-28 09:04:55 -0700655 return 1;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100656
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +0200657 /* For other security levels we need the link key. */
658 if (!(conn->link_mode & HCI_LM_AUTH))
659 goto auth;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +0200661 /* An authenticated combination key has sufficient security for any
662 security level. */
663 if (conn->key_type == HCI_LK_AUTH_COMBINATION)
664 goto encrypt;
665
666 /* An unauthenticated combination key has sufficient security for
667 security level 1 and 2. */
668 if (conn->key_type == HCI_LK_UNAUTH_COMBINATION &&
Gustavo Padovan5974e4c2012-05-17 00:36:25 -0300669 (sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW))
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +0200670 goto encrypt;
671
672 /* A combination key has always sufficient security for the security
673 levels 1 or 2. High security level requires the combination key
674 is generated using maximum PIN code length (16).
675 For pre 2.1 units. */
676 if (conn->key_type == HCI_LK_COMBINATION &&
Gustavo Padovan5974e4c2012-05-17 00:36:25 -0300677 (sec_level != BT_SECURITY_HIGH || conn->pin_length == 16))
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +0200678 goto encrypt;
679
680auth:
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200681 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 return 0;
683
Luiz Augusto von Dentz6fdf6582011-06-13 15:37:35 +0300684 if (!hci_conn_auth(conn, sec_level, auth_type))
685 return 0;
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100686
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +0200687encrypt:
688 if (conn->link_mode & HCI_LM_ENCRYPT)
689 return 1;
690
691 hci_conn_encrypt(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692 return 0;
693}
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100694EXPORT_SYMBOL(hci_conn_security);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695
Waldemar Rymarkiewiczb3b1b062011-05-06 09:42:31 +0200696/* Check secure link requirement */
697int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level)
698{
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300699 BT_DBG("hcon %p", conn);
Waldemar Rymarkiewiczb3b1b062011-05-06 09:42:31 +0200700
701 if (sec_level != BT_SECURITY_HIGH)
702 return 1; /* Accept if non-secure is required */
703
Waldemar Rymarkiewiczef4177e2011-06-02 14:24:52 +0200704 if (conn->sec_level == BT_SECURITY_HIGH)
Waldemar Rymarkiewiczb3b1b062011-05-06 09:42:31 +0200705 return 1;
706
707 return 0; /* Reject not secure link */
708}
709EXPORT_SYMBOL(hci_conn_check_secure);
710
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711/* Change link key */
712int hci_conn_change_link_key(struct hci_conn *conn)
713{
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300714 BT_DBG("hcon %p", conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200716 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 struct hci_cp_change_conn_link_key cp;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -0700718 cp.handle = cpu_to_le16(conn->handle);
Marcel Holtmann40be4922008-07-14 20:13:50 +0200719 hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY,
Gustavo Padovan5974e4c2012-05-17 00:36:25 -0300720 sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100722
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723 return 0;
724}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725
726/* Switch role */
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100727int hci_conn_switch_role(struct hci_conn *conn, __u8 role)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728{
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300729 BT_DBG("hcon %p", conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730
731 if (!role && conn->link_mode & HCI_LM_MASTER)
732 return 1;
733
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200734 if (!test_and_set_bit(HCI_CONN_RSWITCH_PEND, &conn->flags)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 struct hci_cp_switch_role cp;
736 bacpy(&cp.bdaddr, &conn->dst);
737 cp.role = role;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200738 hci_send_cmd(conn->hdev, HCI_OP_SWITCH_ROLE, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 }
Marcel Holtmann8c1b2352009-01-15 21:58:04 +0100740
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741 return 0;
742}
743EXPORT_SYMBOL(hci_conn_switch_role);
744
Marcel Holtmann04837f62006-07-03 10:02:33 +0200745/* Enter active mode */
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700746void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active)
Marcel Holtmann04837f62006-07-03 10:02:33 +0200747{
748 struct hci_dev *hdev = conn->hdev;
749
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300750 BT_DBG("hcon %p mode %d", conn, conn->mode);
Marcel Holtmann04837f62006-07-03 10:02:33 +0200751
752 if (test_bit(HCI_RAW, &hdev->flags))
753 return;
754
Jaikumar Ganesh14b12d02011-05-23 18:06:04 -0700755 if (conn->mode != HCI_CM_SNIFF)
756 goto timer;
757
Johan Hedberg58a681e2012-01-16 06:47:28 +0200758 if (!test_bit(HCI_CONN_POWER_SAVE, &conn->flags) && !force_active)
Marcel Holtmann04837f62006-07-03 10:02:33 +0200759 goto timer;
760
Johan Hedberg51a8efd2012-01-16 06:10:31 +0200761 if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +0200762 struct hci_cp_exit_sniff_mode cp;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -0700763 cp.handle = cpu_to_le16(conn->handle);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200764 hci_send_cmd(hdev, HCI_OP_EXIT_SNIFF_MODE, sizeof(cp), &cp);
Marcel Holtmann04837f62006-07-03 10:02:33 +0200765 }
766
767timer:
768 if (hdev->idle_timeout > 0)
769 mod_timer(&conn->idle_timer,
Gustavo Padovan5974e4c2012-05-17 00:36:25 -0300770 jiffies + msecs_to_jiffies(hdev->idle_timeout));
Marcel Holtmann04837f62006-07-03 10:02:33 +0200771}
772
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773/* Drop all connection on the device */
774void hci_conn_hash_flush(struct hci_dev *hdev)
775{
776 struct hci_conn_hash *h = &hdev->conn_hash;
Andrei Emeltchenko3c4e0df2012-02-02 10:32:17 +0200777 struct hci_conn *c, *n;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778
779 BT_DBG("hdev %s", hdev->name);
780
Andrei Emeltchenko3c4e0df2012-02-02 10:32:17 +0200781 list_for_each_entry_safe(c, n, &h->list, list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 c->state = BT_CLOSED;
783
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +0200784 hci_proto_disconn_cfm(c, HCI_ERROR_LOCAL_HOST_TERM);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785 hci_conn_del(c);
786 }
787}
788
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200789/* Check pending connect attempts */
790void hci_conn_check_pending(struct hci_dev *hdev)
791{
792 struct hci_conn *conn;
793
794 BT_DBG("hdev %s", hdev->name);
795
796 hci_dev_lock(hdev);
797
798 conn = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
799 if (conn)
Vinicius Costa Gomes1aef8662012-07-27 19:32:55 -0300800 hci_acl_create_connection(conn);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200801
802 hci_dev_unlock(hdev);
803}
804
Marcel Holtmann9eba32b2009-08-22 14:19:26 -0700805void hci_conn_hold_device(struct hci_conn *conn)
806{
807 atomic_inc(&conn->devref);
808}
809EXPORT_SYMBOL(hci_conn_hold_device);
810
811void hci_conn_put_device(struct hci_conn *conn)
812{
813 if (atomic_dec_and_test(&conn->devref))
814 hci_conn_del_sysfs(conn);
815}
816EXPORT_SYMBOL(hci_conn_put_device);
817
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818int hci_get_conn_list(void __user *arg)
819{
Gustavo Padovanfc5fef62012-05-23 04:04:19 -0300820 struct hci_conn *c;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821 struct hci_conn_list_req req, *cl;
822 struct hci_conn_info *ci;
823 struct hci_dev *hdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824 int n = 0, size, err;
825
826 if (copy_from_user(&req, arg, sizeof(req)))
827 return -EFAULT;
828
829 if (!req.conn_num || req.conn_num > (PAGE_SIZE * 2) / sizeof(*ci))
830 return -EINVAL;
831
832 size = sizeof(req) + req.conn_num * sizeof(*ci);
833
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200834 cl = kmalloc(size, GFP_KERNEL);
835 if (!cl)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836 return -ENOMEM;
837
Andrei Emeltchenko70f230202010-12-01 16:58:25 +0200838 hdev = hci_dev_get(req.dev_id);
839 if (!hdev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840 kfree(cl);
841 return -ENODEV;
842 }
843
844 ci = cl->conn_info;
845
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300846 hci_dev_lock(hdev);
Luiz Augusto von Dentz8035ded2011-11-01 10:58:56 +0200847 list_for_each_entry(c, &hdev->conn_hash.list, list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848 bacpy(&(ci + n)->bdaddr, &c->dst);
849 (ci + n)->handle = c->handle;
850 (ci + n)->type = c->type;
851 (ci + n)->out = c->out;
852 (ci + n)->state = c->state;
853 (ci + n)->link_mode = c->link_mode;
854 if (++n >= req.conn_num)
855 break;
856 }
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300857 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858
859 cl->dev_id = hdev->id;
860 cl->conn_num = n;
861 size = sizeof(req) + n * sizeof(*ci);
862
863 hci_dev_put(hdev);
864
865 err = copy_to_user(arg, cl, size);
866 kfree(cl);
867
868 return err ? -EFAULT : 0;
869}
870
871int hci_get_conn_info(struct hci_dev *hdev, void __user *arg)
872{
873 struct hci_conn_info_req req;
874 struct hci_conn_info ci;
875 struct hci_conn *conn;
876 char __user *ptr = arg + sizeof(req);
877
878 if (copy_from_user(&req, arg, sizeof(req)))
879 return -EFAULT;
880
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300881 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882 conn = hci_conn_hash_lookup_ba(hdev, req.type, &req.bdaddr);
883 if (conn) {
884 bacpy(&ci.bdaddr, &conn->dst);
885 ci.handle = conn->handle;
886 ci.type = conn->type;
887 ci.out = conn->out;
888 ci.state = conn->state;
889 ci.link_mode = conn->link_mode;
890 }
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300891 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892
893 if (!conn)
894 return -ENOENT;
895
896 return copy_to_user(ptr, &ci, sizeof(ci)) ? -EFAULT : 0;
897}
Marcel Holtmann40be4922008-07-14 20:13:50 +0200898
899int hci_get_auth_info(struct hci_dev *hdev, void __user *arg)
900{
901 struct hci_auth_info_req req;
902 struct hci_conn *conn;
903
904 if (copy_from_user(&req, arg, sizeof(req)))
905 return -EFAULT;
906
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300907 hci_dev_lock(hdev);
Marcel Holtmann40be4922008-07-14 20:13:50 +0200908 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &req.bdaddr);
909 if (conn)
910 req.type = conn->auth_type;
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300911 hci_dev_unlock(hdev);
Marcel Holtmann40be4922008-07-14 20:13:50 +0200912
913 if (!conn)
914 return -ENOENT;
915
916 return copy_to_user(arg, &req, sizeof(req)) ? -EFAULT : 0;
917}
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200918
919struct hci_chan *hci_chan_create(struct hci_conn *conn)
920{
921 struct hci_dev *hdev = conn->hdev;
922 struct hci_chan *chan;
923
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300924 BT_DBG("%s hcon %p", hdev->name, conn);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200925
Andre Guedes75d77352012-01-30 09:22:10 -0300926 chan = kzalloc(sizeof(struct hci_chan), GFP_KERNEL);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200927 if (!chan)
928 return NULL;
929
930 chan->conn = conn;
931 skb_queue_head_init(&chan->data_q);
932
Gustavo F. Padovan8192ede2011-12-14 15:08:48 -0200933 list_add_rcu(&chan->list, &conn->chan_list);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200934
935 return chan;
936}
937
938int hci_chan_del(struct hci_chan *chan)
939{
940 struct hci_conn *conn = chan->conn;
941 struct hci_dev *hdev = conn->hdev;
942
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300943 BT_DBG("%s hcon %p chan %p", hdev->name, conn, chan);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200944
Gustavo F. Padovan8192ede2011-12-14 15:08:48 -0200945 list_del_rcu(&chan->list);
946
947 synchronize_rcu();
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200948
949 skb_queue_purge(&chan->data_q);
950 kfree(chan);
951
952 return 0;
953}
954
Gustavo F. Padovan2c33c062011-12-14 13:02:51 -0200955void hci_chan_list_flush(struct hci_conn *conn)
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200956{
Andrei Emeltchenko2a5a5ec2012-02-02 10:32:18 +0200957 struct hci_chan *chan, *n;
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200958
Andrei Emeltchenko38b3fef2012-06-15 11:50:28 +0300959 BT_DBG("hcon %p", conn);
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200960
Andrei Emeltchenko2a5a5ec2012-02-02 10:32:18 +0200961 list_for_each_entry_safe(chan, n, &conn->chan_list, list)
Luiz Augusto von Dentz73d80de2011-11-02 15:52:01 +0200962 hci_chan_del(chan);
963}