hci_conn.c 20.3 KB
Newer Older
1
/*
Linus Torvalds's avatar
Linus Torvalds committed
2
   BlueZ - Bluetooth protocol stack for Linux
3
   Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds's avatar
Linus Torvalds committed
4
5
6
7
8
9
10
11
12
13
14

   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2 as
   published by the Free Software Foundation;

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
15
16
17
   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds's avatar
Linus Torvalds committed
18
19
   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

20
21
   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds's avatar
Linus Torvalds committed
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
   SOFTWARE IS DISCLAIMED.
*/

/* Bluetooth HCI connection handling. */

#include <linux/module.h>

#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/fcntl.h>
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/interrupt.h>
#include <linux/notifier.h>
#include <net/sock.h>

#include <asm/system.h>
42
#include <linux/uaccess.h>
Linus Torvalds's avatar
Linus Torvalds committed
43
44
45
46
47
#include <asm/unaligned.h>

#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>

48
49
50
51
52
53
54
static void hci_le_connect(struct hci_conn *conn)
{
	struct hci_dev *hdev = conn->hdev;
	struct hci_cp_le_create_conn cp;

	conn->state = BT_CONNECT;
	conn->out = 1;
55
	conn->link_mode |= HCI_LM_MASTER;
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

	memset(&cp, 0, sizeof(cp));
	cp.scan_interval = cpu_to_le16(0x0004);
	cp.scan_window = cpu_to_le16(0x0004);
	bacpy(&cp.peer_addr, &conn->dst);
	cp.conn_interval_min = cpu_to_le16(0x0008);
	cp.conn_interval_max = cpu_to_le16(0x0100);
	cp.supervision_timeout = cpu_to_le16(0x0064);
	cp.min_ce_len = cpu_to_le16(0x0001);
	cp.max_ce_len = cpu_to_le16(0x0001);

	hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
}

static void hci_le_connect_cancel(struct hci_conn *conn)
{
	hci_send_cmd(conn->hdev, HCI_OP_LE_CREATE_CONN_CANCEL, 0, NULL);
}

75
void hci_acl_connect(struct hci_conn *conn)
Linus Torvalds's avatar
Linus Torvalds committed
76
77
78
79
80
81
82
83
{
	struct hci_dev *hdev = conn->hdev;
	struct inquiry_entry *ie;
	struct hci_cp_create_conn cp;

	BT_DBG("%p", conn);

	conn->state = BT_CONNECT;
84
85
	conn->out = 1;

Linus Torvalds's avatar
Linus Torvalds committed
86
87
	conn->link_mode = HCI_LM_MASTER;

88
89
	conn->attempt++;

90
91
	conn->link_policy = hdev->link_policy;

Linus Torvalds's avatar
Linus Torvalds committed
92
93
94
95
	memset(&cp, 0, sizeof(cp));
	bacpy(&cp.bdaddr, &conn->dst);
	cp.pscan_rep_mode = 0x02;

96
97
	ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
	if (ie) {
98
99
100
101
102
103
104
		if (inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) {
			cp.pscan_rep_mode = ie->data.pscan_rep_mode;
			cp.pscan_mode     = ie->data.pscan_mode;
			cp.clock_offset   = ie->data.clock_offset |
							cpu_to_le16(0x8000);
		}

Linus Torvalds's avatar
Linus Torvalds committed
105
		memcpy(conn->dev_class, ie->data.dev_class, 3);
106
		conn->ssp_mode = ie->data.ssp_mode;
Linus Torvalds's avatar
Linus Torvalds committed
107
108
	}

109
	cp.pkt_type = cpu_to_le16(conn->pkt_type);
Linus Torvalds's avatar
Linus Torvalds committed
110
	if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER))
111
		cp.role_switch = 0x01;
Linus Torvalds's avatar
Linus Torvalds committed
112
	else
113
		cp.role_switch = 0x00;
114

115
	hci_send_cmd(hdev, HCI_OP_CREATE_CONN, sizeof(cp), &cp);
Linus Torvalds's avatar
Linus Torvalds committed
116
117
}

118
119
120
121
122
123
124
125
126
127
static void hci_acl_connect_cancel(struct hci_conn *conn)
{
	struct hci_cp_create_conn_cancel cp;

	BT_DBG("%p", conn);

	if (conn->hdev->hci_ver < 2)
		return;

	bacpy(&cp.bdaddr, &conn->dst);
128
	hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp);
129
130
}

Linus Torvalds's avatar
Linus Torvalds committed
131
132
133
134
135
136
137
138
void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
{
	struct hci_cp_disconnect cp;

	BT_DBG("%p", conn);

	conn->state = BT_DISCONN;

139
	cp.handle = cpu_to_le16(conn->handle);
Linus Torvalds's avatar
Linus Torvalds committed
140
	cp.reason = reason;
141
	hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp);
Linus Torvalds's avatar
Linus Torvalds committed
142
143
144
145
146
147
148
149
150
151
152
153
}

void hci_add_sco(struct hci_conn *conn, __u16 handle)
{
	struct hci_dev *hdev = conn->hdev;
	struct hci_cp_add_sco cp;

	BT_DBG("%p", conn);

	conn->state = BT_CONNECT;
	conn->out = 1;

154
155
	conn->attempt++;

156
	cp.handle   = cpu_to_le16(handle);
157
	cp.pkt_type = cpu_to_le16(conn->pkt_type);
Linus Torvalds's avatar
Linus Torvalds committed
158

159
	hci_send_cmd(hdev, HCI_OP_ADD_SCO, sizeof(cp), &cp);
Linus Torvalds's avatar
Linus Torvalds committed
160
161
}

162
163
164
165
166
167
168
169
170
171
void hci_setup_sync(struct hci_conn *conn, __u16 handle)
{
	struct hci_dev *hdev = conn->hdev;
	struct hci_cp_setup_sync_conn cp;

	BT_DBG("%p", conn);

	conn->state = BT_CONNECT;
	conn->out = 1;

172
173
	conn->attempt++;

174
	cp.handle   = cpu_to_le16(handle);
175
	cp.pkt_type = cpu_to_le16(conn->pkt_type);
176
177
178
179
180
181
182
183
184
185

	cp.tx_bandwidth   = cpu_to_le32(0x00001f40);
	cp.rx_bandwidth   = cpu_to_le32(0x00001f40);
	cp.max_latency    = cpu_to_le16(0xffff);
	cp.voice_setting  = cpu_to_le16(hdev->voice_setting);
	cp.retrans_effort = 0xff;

	hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
}

186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
					u16 latency, u16 to_multiplier)
{
	struct hci_cp_le_conn_update cp;
	struct hci_dev *hdev = conn->hdev;

	memset(&cp, 0, sizeof(cp));

	cp.handle		= cpu_to_le16(conn->handle);
	cp.conn_interval_min	= cpu_to_le16(min);
	cp.conn_interval_max	= cpu_to_le16(max);
	cp.conn_latency		= cpu_to_le16(latency);
	cp.supervision_timeout	= cpu_to_le16(to_multiplier);
	cp.min_ce_len		= cpu_to_le16(0x0001);
	cp.max_ce_len		= cpu_to_le16(0x0001);

	hci_send_cmd(hdev, HCI_OP_LE_CONN_UPDATE, sizeof(cp), &cp);
}
EXPORT_SYMBOL(hci_le_conn_update);

206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
/* Device _must_ be locked */
void hci_sco_setup(struct hci_conn *conn, __u8 status)
{
	struct hci_conn *sco = conn->link;

	BT_DBG("%p", conn);

	if (!sco)
		return;

	if (!status) {
		if (lmp_esco_capable(conn->hdev))
			hci_setup_sync(sco, conn->handle);
		else
			hci_add_sco(sco, conn->handle);
	} else {
		hci_proto_connect_cfm(sco, status);
		hci_conn_del(sco);
	}
}

Linus Torvalds's avatar
Linus Torvalds committed
227
228
static void hci_conn_timeout(unsigned long arg)
{
229
230
	struct hci_conn *conn = (void *) arg;
	struct hci_dev *hdev = conn->hdev;
231
	__u8 reason;
Linus Torvalds's avatar
Linus Torvalds committed
232
233
234
235
236
237
238

	BT_DBG("conn %p state %d", conn, conn->state);

	if (atomic_read(&conn->refcnt))
		return;

	hci_dev_lock(hdev);
239
240
241

	switch (conn->state) {
	case BT_CONNECT:
242
	case BT_CONNECT2:
243
244
245
246
247
248
		if (conn->out) {
			if (conn->type == ACL_LINK)
				hci_acl_connect_cancel(conn);
			else if (conn->type == LE_LINK)
				hci_le_connect_cancel(conn);
		}
249
		break;
250
	case BT_CONFIG:
251
	case BT_CONNECTED:
252
253
		reason = hci_proto_disconn_ind(conn);
		hci_acl_disconn(conn, reason);
254
255
		break;
	default:
Linus Torvalds's avatar
Linus Torvalds committed
256
		conn->state = BT_CLOSED;
257
258
259
		break;
	}

Linus Torvalds's avatar
Linus Torvalds committed
260
261
262
	hci_dev_unlock(hdev);
}

263
static void hci_conn_idle(unsigned long arg)
Linus Torvalds's avatar
Linus Torvalds committed
264
{
265
266
267
268
269
	struct hci_conn *conn = (void *) arg;

	BT_DBG("conn %p mode %d", conn, conn->mode);

	hci_conn_enter_sniff_mode(conn);
Linus Torvalds's avatar
Linus Torvalds committed
270
271
}

272
273
274
275
276
277
278
279
280
281
282
283
284
static void hci_conn_auto_accept(unsigned long arg)
{
	struct hci_conn *conn = (void *) arg;
	struct hci_dev *hdev = conn->hdev;

	hci_dev_lock(hdev);

	hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, sizeof(conn->dst),
								&conn->dst);

	hci_dev_unlock(hdev);
}

Linus Torvalds's avatar
Linus Torvalds committed
285
286
287
288
289
290
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
{
	struct hci_conn *conn;

	BT_DBG("%s dst %s", hdev->name, batostr(dst));

291
292
	conn = kzalloc(sizeof(struct hci_conn), GFP_ATOMIC);
	if (!conn)
Linus Torvalds's avatar
Linus Torvalds committed
293
294
295
		return NULL;

	bacpy(&conn->dst, dst);
296
297
298
299
	conn->hdev  = hdev;
	conn->type  = type;
	conn->mode  = HCI_CM_ACTIVE;
	conn->state = BT_OPEN;
300
	conn->auth_type = HCI_AT_GENERAL_BONDING;
301
	conn->io_capability = hdev->io_capability;
302
	conn->remote_auth = 0xff;
303
	conn->key_type = 0xff;
Linus Torvalds's avatar
Linus Torvalds committed
304

305
	conn->power_save = 1;
306
	conn->disc_timeout = HCI_DISCONN_TIMEOUT;
307

308
309
310
311
312
313
	switch (type) {
	case ACL_LINK:
		conn->pkt_type = hdev->pkt_type & ACL_PTYPE_MASK;
		break;
	case SCO_LINK:
		if (lmp_esco_capable(hdev))
314
315
			conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
					(hdev->esco_type & EDR_ESCO_MASK);
316
317
318
319
		else
			conn->pkt_type = hdev->pkt_type & SCO_PTYPE_MASK;
		break;
	case ESCO_LINK:
320
		conn->pkt_type = hdev->esco_type & ~EDR_ESCO_MASK;
321
322
323
		break;
	}

Linus Torvalds's avatar
Linus Torvalds committed
324
	skb_queue_head_init(&conn->data_q);
325

326
327
	setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn);
	setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn);
328
329
	setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept,
							(unsigned long) conn);
Linus Torvalds's avatar
Linus Torvalds committed
330
331
332
333
334
335
336
337
338
339
340

	atomic_set(&conn->refcnt, 0);

	hci_dev_hold(hdev);

	tasklet_disable(&hdev->tx_task);

	hci_conn_hash_add(hdev, conn);
	if (hdev->notify)
		hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);

341
342
	atomic_set(&conn->devref, 0);

343
344
	hci_conn_init_sysfs(conn);

Linus Torvalds's avatar
Linus Torvalds committed
345
346
347
348
349
350
351
352
353
354
355
	tasklet_enable(&hdev->tx_task);

	return conn;
}

int hci_conn_del(struct hci_conn *conn)
{
	struct hci_dev *hdev = conn->hdev;

	BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);

356
357
358
	del_timer(&conn->idle_timer);

	del_timer(&conn->disc_timer);
Linus Torvalds's avatar
Linus Torvalds committed
359

360
361
	del_timer(&conn->auto_accept_timer);

362
	if (conn->type == ACL_LINK) {
Linus Torvalds's avatar
Linus Torvalds committed
363
364
365
366
367
368
		struct hci_conn *sco = conn->link;
		if (sco)
			sco->link = NULL;

		/* Unacked frames */
		hdev->acl_cnt += conn->sent;
369
370
371
372
373
	} else if (conn->type == LE_LINK) {
		if (hdev->le_pkts)
			hdev->le_cnt += conn->sent;
		else
			hdev->acl_cnt += conn->sent;
374
375
376
377
378
379
	} else {
		struct hci_conn *acl = conn->link;
		if (acl) {
			acl->link = NULL;
			hci_conn_put(acl);
		}
Linus Torvalds's avatar
Linus Torvalds committed
380
381
382
	}

	tasklet_disable(&hdev->tx_task);
383

Linus Torvalds's avatar
Linus Torvalds committed
384
385
386
	hci_conn_hash_del(hdev, conn);
	if (hdev->notify)
		hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
387

Linus Torvalds's avatar
Linus Torvalds committed
388
	tasklet_enable(&hdev->tx_task);
389

Linus Torvalds's avatar
Linus Torvalds committed
390
391
	skb_queue_purge(&conn->data_q);

392
	hci_conn_put_device(conn);
393

394
395
	hci_dev_put(hdev);

Linus Torvalds's avatar
Linus Torvalds committed
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
	return 0;
}

struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
{
	int use_src = bacmp(src, BDADDR_ANY);
	struct hci_dev *hdev = NULL;
	struct list_head *p;

	BT_DBG("%s -> %s", batostr(src), batostr(dst));

	read_lock_bh(&hci_dev_list_lock);

	list_for_each(p, &hci_dev_list) {
		struct hci_dev *d = list_entry(p, struct hci_dev, list);

		if (!test_bit(HCI_UP, &d->flags) || test_bit(HCI_RAW, &d->flags))
			continue;

415
		/* Simple routing:
Linus Torvalds's avatar
Linus Torvalds committed
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
		 *   No source address - find interface with bdaddr != dst
		 *   Source address    - find interface with bdaddr == src
		 */

		if (use_src) {
			if (!bacmp(&d->bdaddr, src)) {
				hdev = d; break;
			}
		} else {
			if (bacmp(&d->bdaddr, dst)) {
				hdev = d; break;
			}
		}
	}

	if (hdev)
		hdev = hci_dev_hold(hdev);

	read_unlock_bh(&hci_dev_list_lock);
	return hdev;
}
EXPORT_SYMBOL(hci_get_route);

439
/* Create SCO, ACL or LE connection.
Linus Torvalds's avatar
Linus Torvalds committed
440
 * Device _must_ be locked */
441
struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type)
Linus Torvalds's avatar
Linus Torvalds committed
442
443
{
	struct hci_conn *acl;
444
	struct hci_conn *sco;
445
	struct hci_conn *le;
Linus Torvalds's avatar
Linus Torvalds committed
446
447
448

	BT_DBG("%s dst %s", hdev->name, batostr(dst));

449
450
	if (type == LE_LINK) {
		le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
451
		if (le)
452
			return ERR_PTR(-EBUSY);
453
		le = hci_conn_add(hdev, LE_LINK, dst);
454
		if (!le)
455
			return ERR_PTR(-ENOMEM);
456
457
458
459
460
461
462
463
		if (le->state == BT_OPEN)
			hci_le_connect(le);

		hci_conn_hold(le);

		return le;
	}

464
465
466
467
	acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
	if (!acl) {
		acl = hci_conn_add(hdev, ACL_LINK, dst);
		if (!acl)
Linus Torvalds's avatar
Linus Torvalds committed
468
469
470
471
472
			return NULL;
	}

	hci_conn_hold(acl);

473
	if (acl->state == BT_OPEN || acl->state == BT_CLOSED) {
474
475
		acl->sec_level = BT_SECURITY_LOW;
		acl->pending_sec_level = sec_level;
476
		acl->auth_type = auth_type;
Linus Torvalds's avatar
Linus Torvalds committed
477
		hci_acl_connect(acl);
478
	}
Linus Torvalds's avatar
Linus Torvalds committed
479

480
481
	if (type == ACL_LINK)
		return acl;
Linus Torvalds's avatar
Linus Torvalds committed
482

483
484
485
486
	sco = hci_conn_hash_lookup_ba(hdev, type, dst);
	if (!sco) {
		sco = hci_conn_add(hdev, type, dst);
		if (!sco) {
487
488
			hci_conn_put(acl);
			return NULL;
Linus Torvalds's avatar
Linus Torvalds committed
489
		}
490
	}
Linus Torvalds's avatar
Linus Torvalds committed
491

492
493
	acl->link = sco;
	sco->link = acl;
Linus Torvalds's avatar
Linus Torvalds committed
494

495
	hci_conn_hold(sco);
Linus Torvalds's avatar
Linus Torvalds committed
496

497
	if (acl->state == BT_CONNECTED &&
498
			(sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
499
500
501
		acl->power_save = 1;
		hci_conn_enter_active_mode(acl);

502
503
504
505
506
507
508
		if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->pend)) {
			/* defer SCO setup until mode change completed */
			set_bit(HCI_CONN_SCO_SETUP_PEND, &acl->pend);
			return sco;
		}

		hci_sco_setup(acl, 0x00);
509
	}
510
511

	return sco;
Linus Torvalds's avatar
Linus Torvalds committed
512
513
514
}
EXPORT_SYMBOL(hci_connect);

515
516
517
518
519
520
521
522
523
524
525
526
527
/* Check link security requirement */
int hci_conn_check_link_mode(struct hci_conn *conn)
{
	BT_DBG("conn %p", conn);

	if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0 &&
					!(conn->link_mode & HCI_LM_ENCRYPT))
		return 0;

	return 1;
}
EXPORT_SYMBOL(hci_conn_check_link_mode);

Linus Torvalds's avatar
Linus Torvalds committed
528
/* Authenticate remote device */
529
static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
Linus Torvalds's avatar
Linus Torvalds committed
530
531
532
{
	BT_DBG("conn %p", conn);

533
534
535
	if (conn->pending_sec_level > sec_level)
		sec_level = conn->pending_sec_level;

536
	if (sec_level > conn->sec_level)
537
		conn->pending_sec_level = sec_level;
538
	else if (conn->link_mode & HCI_LM_AUTH)
Linus Torvalds's avatar
Linus Torvalds committed
539
540
		return 1;

541
542
543
	/* Make sure we preserve an existing MITM requirement*/
	auth_type |= (conn->auth_type & 0x01);

544
545
	conn->auth_type = auth_type;

Linus Torvalds's avatar
Linus Torvalds committed
546
547
	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
		struct hci_cp_auth_requested cp;
548
		cp.handle = cpu_to_le16(conn->handle);
549
550
		hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED,
							sizeof(cp), &cp);
Linus Torvalds's avatar
Linus Torvalds committed
551
	}
552

Linus Torvalds's avatar
Linus Torvalds committed
553
554
555
	return 0;
}

556
557
558
559
560
561
562
563
564
565
566
567
568
569
/* Encrypt the the link */
static void hci_conn_encrypt(struct hci_conn *conn)
{
	BT_DBG("conn %p", conn);

	if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
		struct hci_cp_set_conn_encrypt cp;
		cp.handle  = cpu_to_le16(conn->handle);
		cp.encrypt = 0x01;
		hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
									&cp);
	}
}

570
/* Enable security */
571
int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
Linus Torvalds's avatar
Linus Torvalds committed
572
573
574
{
	BT_DBG("conn %p", conn);

575
	/* For sdp we don't need the link key. */
576
577
578
	if (sec_level == BT_SECURITY_SDP)
		return 1;

579
580
	/* For non 2.1 devices and low security level we don't need the link
	   key. */
581
582
583
	if (sec_level == BT_SECURITY_LOW &&
				(!conn->ssp_mode || !conn->hdev->ssp_mode))
		return 1;
584

585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
	/* For other security levels we need the link key. */
	if (!(conn->link_mode & HCI_LM_AUTH))
		goto auth;

	/* An authenticated combination key has sufficient security for any
	   security level. */
	if (conn->key_type == HCI_LK_AUTH_COMBINATION)
		goto encrypt;

	/* An unauthenticated combination key has sufficient security for
	   security level 1 and 2. */
	if (conn->key_type == HCI_LK_UNAUTH_COMBINATION &&
			(sec_level == BT_SECURITY_MEDIUM ||
			sec_level == BT_SECURITY_LOW))
		goto encrypt;

	/* A combination key has always sufficient security for the security
	   levels 1 or 2. High security level requires the combination key
	   is generated using maximum PIN code length (16).
	   For pre 2.1 units. */
	if (conn->key_type == HCI_LK_COMBINATION &&
			(sec_level != BT_SECURITY_HIGH ||
			conn->pin_length == 16))
		goto encrypt;

auth:
611
	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
Linus Torvalds's avatar
Linus Torvalds committed
612
613
		return 0;

614
615
	if (!hci_conn_auth(conn, sec_level, auth_type))
		return 0;
616
617
618
619

encrypt:
	if (conn->link_mode & HCI_LM_ENCRYPT)
		return 1;
620

621
	hci_conn_encrypt(conn);
Linus Torvalds's avatar
Linus Torvalds committed
622
623
	return 0;
}
624
EXPORT_SYMBOL(hci_conn_security);
Linus Torvalds's avatar
Linus Torvalds committed
625

626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
/* Check secure link requirement */
int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level)
{
	BT_DBG("conn %p", conn);

	if (sec_level != BT_SECURITY_HIGH)
		return 1; /* Accept if non-secure is required */

	if (conn->key_type == HCI_LK_AUTH_COMBINATION ||
			(conn->key_type == HCI_LK_COMBINATION &&
			conn->pin_length == 16))
		return 1;

	return 0; /* Reject not secure link */
}
EXPORT_SYMBOL(hci_conn_check_secure);

Linus Torvalds's avatar
Linus Torvalds committed
643
644
645
646
647
648
649
/* Change link key */
int hci_conn_change_link_key(struct hci_conn *conn)
{
	BT_DBG("conn %p", conn);

	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
		struct hci_cp_change_conn_link_key cp;
650
		cp.handle = cpu_to_le16(conn->handle);
651
652
		hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY,
							sizeof(cp), &cp);
Linus Torvalds's avatar
Linus Torvalds committed
653
	}
654

Linus Torvalds's avatar
Linus Torvalds committed
655
656
657
658
659
	return 0;
}
EXPORT_SYMBOL(hci_conn_change_link_key);

/* Switch role */
660
int hci_conn_switch_role(struct hci_conn *conn, __u8 role)
Linus Torvalds's avatar
Linus Torvalds committed
661
662
663
664
665
666
667
668
669
670
{
	BT_DBG("conn %p", conn);

	if (!role && conn->link_mode & HCI_LM_MASTER)
		return 1;

	if (!test_and_set_bit(HCI_CONN_RSWITCH_PEND, &conn->pend)) {
		struct hci_cp_switch_role cp;
		bacpy(&cp.bdaddr, &conn->dst);
		cp.role = role;
671
		hci_send_cmd(conn->hdev, HCI_OP_SWITCH_ROLE, sizeof(cp), &cp);
Linus Torvalds's avatar
Linus Torvalds committed
672
	}
673

Linus Torvalds's avatar
Linus Torvalds committed
674
675
676
677
	return 0;
}
EXPORT_SYMBOL(hci_conn_switch_role);

678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
/* Enter active mode */
void hci_conn_enter_active_mode(struct hci_conn *conn)
{
	struct hci_dev *hdev = conn->hdev;

	BT_DBG("conn %p mode %d", conn, conn->mode);

	if (test_bit(HCI_RAW, &hdev->flags))
		return;

	if (conn->mode != HCI_CM_SNIFF || !conn->power_save)
		goto timer;

	if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
		struct hci_cp_exit_sniff_mode cp;
693
		cp.handle = cpu_to_le16(conn->handle);
694
		hci_send_cmd(hdev, HCI_OP_EXIT_SNIFF_MODE, sizeof(cp), &cp);
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
	}

timer:
	if (hdev->idle_timeout > 0)
		mod_timer(&conn->idle_timer,
			jiffies + msecs_to_jiffies(hdev->idle_timeout));
}

/* Enter sniff mode */
void hci_conn_enter_sniff_mode(struct hci_conn *conn)
{
	struct hci_dev *hdev = conn->hdev;

	BT_DBG("conn %p mode %d", conn, conn->mode);

	if (test_bit(HCI_RAW, &hdev->flags))
		return;

	if (!lmp_sniff_capable(hdev) || !lmp_sniff_capable(conn))
		return;

	if (conn->mode != HCI_CM_ACTIVE || !(conn->link_policy & HCI_LP_SNIFF))
		return;

	if (lmp_sniffsubr_capable(hdev) && lmp_sniffsubr_capable(conn)) {
		struct hci_cp_sniff_subrate cp;
721
722
723
724
		cp.handle             = cpu_to_le16(conn->handle);
		cp.max_latency        = cpu_to_le16(0);
		cp.min_remote_timeout = cpu_to_le16(0);
		cp.min_local_timeout  = cpu_to_le16(0);
725
		hci_send_cmd(hdev, HCI_OP_SNIFF_SUBRATE, sizeof(cp), &cp);
726
727
728
729
	}

	if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
		struct hci_cp_sniff_mode cp;
730
731
732
733
734
		cp.handle       = cpu_to_le16(conn->handle);
		cp.max_interval = cpu_to_le16(hdev->sniff_max_interval);
		cp.min_interval = cpu_to_le16(hdev->sniff_min_interval);
		cp.attempt      = cpu_to_le16(4);
		cp.timeout      = cpu_to_le16(1);
735
		hci_send_cmd(hdev, HCI_OP_SNIFF_MODE, sizeof(cp), &cp);
736
737
738
	}
}

Linus Torvalds's avatar
Linus Torvalds committed
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
/* Drop all connection on the device */
void hci_conn_hash_flush(struct hci_dev *hdev)
{
	struct hci_conn_hash *h = &hdev->conn_hash;
	struct list_head *p;

	BT_DBG("hdev %s", hdev->name);

	p = h->list.next;
	while (p != &h->list) {
		struct hci_conn *c;

		c = list_entry(p, struct hci_conn, list);
		p = p->next;

		c->state = BT_CLOSED;

756
		hci_proto_disconn_cfm(c, 0x16);
Linus Torvalds's avatar
Linus Torvalds committed
757
758
759
760
		hci_conn_del(c);
	}
}

761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
/* Check pending connect attempts */
void hci_conn_check_pending(struct hci_dev *hdev)
{
	struct hci_conn *conn;

	BT_DBG("hdev %s", hdev->name);

	hci_dev_lock(hdev);

	conn = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
	if (conn)
		hci_acl_connect(conn);

	hci_dev_unlock(hdev);
}

777
778
779
780
781
782
783
784
785
786
787
788
789
void hci_conn_hold_device(struct hci_conn *conn)
{
	atomic_inc(&conn->devref);
}
EXPORT_SYMBOL(hci_conn_hold_device);

void hci_conn_put_device(struct hci_conn *conn)
{
	if (atomic_dec_and_test(&conn->devref))
		hci_conn_del_sysfs(conn);
}
EXPORT_SYMBOL(hci_conn_put_device);

Linus Torvalds's avatar
Linus Torvalds committed
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
int hci_get_conn_list(void __user *arg)
{
	struct hci_conn_list_req req, *cl;
	struct hci_conn_info *ci;
	struct hci_dev *hdev;
	struct list_head *p;
	int n = 0, size, err;

	if (copy_from_user(&req, arg, sizeof(req)))
		return -EFAULT;

	if (!req.conn_num || req.conn_num > (PAGE_SIZE * 2) / sizeof(*ci))
		return -EINVAL;

	size = sizeof(req) + req.conn_num * sizeof(*ci);

806
807
	cl = kmalloc(size, GFP_KERNEL);
	if (!cl)
Linus Torvalds's avatar
Linus Torvalds committed
808
809
		return -ENOMEM;

810
811
	hdev = hci_dev_get(req.dev_id);
	if (!hdev) {
Linus Torvalds's avatar
Linus Torvalds committed
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
		kfree(cl);
		return -ENODEV;
	}

	ci = cl->conn_info;

	hci_dev_lock_bh(hdev);
	list_for_each(p, &hdev->conn_hash.list) {
		register struct hci_conn *c;
		c = list_entry(p, struct hci_conn, list);

		bacpy(&(ci + n)->bdaddr, &c->dst);
		(ci + n)->handle = c->handle;
		(ci + n)->type  = c->type;
		(ci + n)->out   = c->out;
		(ci + n)->state = c->state;
		(ci + n)->link_mode = c->link_mode;
		if (++n >= req.conn_num)
			break;
	}
	hci_dev_unlock_bh(hdev);

	cl->dev_id = hdev->id;
	cl->conn_num = n;
	size = sizeof(req) + n * sizeof(*ci);

	hci_dev_put(hdev);

	err = copy_to_user(arg, cl, size);
	kfree(cl);

	return err ? -EFAULT : 0;
}

int hci_get_conn_info(struct hci_dev *hdev, void __user *arg)
{
	struct hci_conn_info_req req;
	struct hci_conn_info ci;
	struct hci_conn *conn;
	char __user *ptr = arg + sizeof(req);

	if (copy_from_user(&req, arg, sizeof(req)))
		return -EFAULT;

	hci_dev_lock_bh(hdev);
	conn = hci_conn_hash_lookup_ba(hdev, req.type, &req.bdaddr);
	if (conn) {
		bacpy(&ci.bdaddr, &conn->dst);
		ci.handle = conn->handle;
		ci.type  = conn->type;
		ci.out   = conn->out;
		ci.state = conn->state;
		ci.link_mode = conn->link_mode;
	}
	hci_dev_unlock_bh(hdev);

	if (!conn)
		return -ENOENT;

	return copy_to_user(ptr, &ci, sizeof(ci)) ? -EFAULT : 0;
}
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892

int hci_get_auth_info(struct hci_dev *hdev, void __user *arg)
{
	struct hci_auth_info_req req;
	struct hci_conn *conn;

	if (copy_from_user(&req, arg, sizeof(req)))
		return -EFAULT;

	hci_dev_lock_bh(hdev);
	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &req.bdaddr);
	if (conn)
		req.type = conn->auth_type;
	hci_dev_unlock_bh(hdev);

	if (!conn)
		return -ENOENT;

	return copy_to_user(arg, &req, sizeof(req)) ? -EFAULT : 0;
}