xref: /openbmc/linux/net/bluetooth/hci_conn.c (revision 893d67514aebcfd3ebf17bd212ceea1e2741a443)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    BlueZ - Bluetooth protocol stack for Linux
32d0a0346SRon Shaffer    Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
41da177e4SLinus Torvalds 
51da177e4SLinus Torvalds    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
61da177e4SLinus Torvalds 
71da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
81da177e4SLinus Torvalds    it under the terms of the GNU General Public License version 2 as
91da177e4SLinus Torvalds    published by the Free Software Foundation;
101da177e4SLinus Torvalds 
111da177e4SLinus Torvalds    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
121da177e4SLinus Torvalds    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
131da177e4SLinus Torvalds    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
141da177e4SLinus Torvalds    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
151da177e4SLinus Torvalds    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
161da177e4SLinus Torvalds    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
171da177e4SLinus Torvalds    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
181da177e4SLinus Torvalds    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
191da177e4SLinus Torvalds 
201da177e4SLinus Torvalds    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
211da177e4SLinus Torvalds    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
221da177e4SLinus Torvalds    SOFTWARE IS DISCLAIMED.
231da177e4SLinus Torvalds */
241da177e4SLinus Torvalds 
251da177e4SLinus Torvalds /* Bluetooth HCI connection handling. */
261da177e4SLinus Torvalds 
271da177e4SLinus Torvalds #include <linux/module.h>
281da177e4SLinus Torvalds 
291da177e4SLinus Torvalds #include <linux/types.h>
301da177e4SLinus Torvalds #include <linux/errno.h>
311da177e4SLinus Torvalds #include <linux/kernel.h>
321da177e4SLinus Torvalds #include <linux/slab.h>
331da177e4SLinus Torvalds #include <linux/poll.h>
341da177e4SLinus Torvalds #include <linux/fcntl.h>
351da177e4SLinus Torvalds #include <linux/init.h>
361da177e4SLinus Torvalds #include <linux/skbuff.h>
371da177e4SLinus Torvalds #include <linux/interrupt.h>
381da177e4SLinus Torvalds #include <linux/notifier.h>
391da177e4SLinus Torvalds #include <net/sock.h>
401da177e4SLinus Torvalds 
411da177e4SLinus Torvalds #include <asm/system.h>
4270f23020SAndrei Emeltchenko #include <linux/uaccess.h>
431da177e4SLinus Torvalds #include <asm/unaligned.h>
441da177e4SLinus Torvalds 
451da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
461da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
471da177e4SLinus Torvalds 
48fcd89c09SVille Tervo static void hci_le_connect(struct hci_conn *conn)
49fcd89c09SVille Tervo {
50fcd89c09SVille Tervo 	struct hci_dev *hdev = conn->hdev;
51fcd89c09SVille Tervo 	struct hci_cp_le_create_conn cp;
52fcd89c09SVille Tervo 
53fcd89c09SVille Tervo 	conn->state = BT_CONNECT;
54fcd89c09SVille Tervo 	conn->out = 1;
55b92a6223SVinicius Costa Gomes 	conn->link_mode |= HCI_LM_MASTER;
56fcd89c09SVille Tervo 
57fcd89c09SVille Tervo 	memset(&cp, 0, sizeof(cp));
58fcd89c09SVille Tervo 	cp.scan_interval = cpu_to_le16(0x0004);
59fcd89c09SVille Tervo 	cp.scan_window = cpu_to_le16(0x0004);
60fcd89c09SVille Tervo 	bacpy(&cp.peer_addr, &conn->dst);
61fcd89c09SVille Tervo 	cp.conn_interval_min = cpu_to_le16(0x0008);
62fcd89c09SVille Tervo 	cp.conn_interval_max = cpu_to_le16(0x0100);
63fcd89c09SVille Tervo 	cp.supervision_timeout = cpu_to_le16(0x0064);
64fcd89c09SVille Tervo 	cp.min_ce_len = cpu_to_le16(0x0001);
65fcd89c09SVille Tervo 	cp.max_ce_len = cpu_to_le16(0x0001);
66fcd89c09SVille Tervo 
67fcd89c09SVille Tervo 	hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
68fcd89c09SVille Tervo }
69fcd89c09SVille Tervo 
70fcd89c09SVille Tervo static void hci_le_connect_cancel(struct hci_conn *conn)
71fcd89c09SVille Tervo {
72fcd89c09SVille Tervo 	hci_send_cmd(conn->hdev, HCI_OP_LE_CREATE_CONN_CANCEL, 0, NULL);
73fcd89c09SVille Tervo }
74fcd89c09SVille Tervo 
754c67bc74SMarcel Holtmann void hci_acl_connect(struct hci_conn *conn)
761da177e4SLinus Torvalds {
771da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
781da177e4SLinus Torvalds 	struct inquiry_entry *ie;
791da177e4SLinus Torvalds 	struct hci_cp_create_conn cp;
801da177e4SLinus Torvalds 
811da177e4SLinus Torvalds 	BT_DBG("%p", conn);
821da177e4SLinus Torvalds 
831da177e4SLinus Torvalds 	conn->state = BT_CONNECT;
841da177e4SLinus Torvalds 	conn->out = 1;
85a8746417SMarcel Holtmann 
861da177e4SLinus Torvalds 	conn->link_mode = HCI_LM_MASTER;
871da177e4SLinus Torvalds 
884c67bc74SMarcel Holtmann 	conn->attempt++;
894c67bc74SMarcel Holtmann 
90e4e8e37cSMarcel Holtmann 	conn->link_policy = hdev->link_policy;
91e4e8e37cSMarcel Holtmann 
921da177e4SLinus Torvalds 	memset(&cp, 0, sizeof(cp));
931da177e4SLinus Torvalds 	bacpy(&cp.bdaddr, &conn->dst);
941da177e4SLinus Torvalds 	cp.pscan_rep_mode = 0x02;
951da177e4SLinus Torvalds 
9670f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
9770f23020SAndrei Emeltchenko 	if (ie) {
9841a96212SMarcel Holtmann 		if (inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) {
991da177e4SLinus Torvalds 			cp.pscan_rep_mode = ie->data.pscan_rep_mode;
1001da177e4SLinus Torvalds 			cp.pscan_mode     = ie->data.pscan_mode;
10141a96212SMarcel Holtmann 			cp.clock_offset   = ie->data.clock_offset |
10241a96212SMarcel Holtmann 							cpu_to_le16(0x8000);
10341a96212SMarcel Holtmann 		}
10441a96212SMarcel Holtmann 
1051da177e4SLinus Torvalds 		memcpy(conn->dev_class, ie->data.dev_class, 3);
10641a96212SMarcel Holtmann 		conn->ssp_mode = ie->data.ssp_mode;
1071da177e4SLinus Torvalds 	}
1081da177e4SLinus Torvalds 
109a8746417SMarcel Holtmann 	cp.pkt_type = cpu_to_le16(conn->pkt_type);
1101da177e4SLinus Torvalds 	if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER))
1111da177e4SLinus Torvalds 		cp.role_switch = 0x01;
1121da177e4SLinus Torvalds 	else
1131da177e4SLinus Torvalds 		cp.role_switch = 0x00;
1141da177e4SLinus Torvalds 
115a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_CREATE_CONN, sizeof(cp), &cp);
1161da177e4SLinus Torvalds }
1171da177e4SLinus Torvalds 
1186ac59344SMarcel Holtmann static void hci_acl_connect_cancel(struct hci_conn *conn)
1196ac59344SMarcel Holtmann {
1206ac59344SMarcel Holtmann 	struct hci_cp_create_conn_cancel cp;
1216ac59344SMarcel Holtmann 
1226ac59344SMarcel Holtmann 	BT_DBG("%p", conn);
1236ac59344SMarcel Holtmann 
1246ac59344SMarcel Holtmann 	if (conn->hdev->hci_ver < 2)
1256ac59344SMarcel Holtmann 		return;
1266ac59344SMarcel Holtmann 
1276ac59344SMarcel Holtmann 	bacpy(&cp.bdaddr, &conn->dst);
128a9de9248SMarcel Holtmann 	hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp);
1296ac59344SMarcel Holtmann }
1306ac59344SMarcel Holtmann 
1311da177e4SLinus Torvalds void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
1321da177e4SLinus Torvalds {
1331da177e4SLinus Torvalds 	struct hci_cp_disconnect cp;
1341da177e4SLinus Torvalds 
1351da177e4SLinus Torvalds 	BT_DBG("%p", conn);
1361da177e4SLinus Torvalds 
1371da177e4SLinus Torvalds 	conn->state = BT_DISCONN;
1381da177e4SLinus Torvalds 
139aca3192cSYOSHIFUJI Hideaki 	cp.handle = cpu_to_le16(conn->handle);
1401da177e4SLinus Torvalds 	cp.reason = reason;
141a9de9248SMarcel Holtmann 	hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp);
1421da177e4SLinus Torvalds }
1431da177e4SLinus Torvalds 
1441da177e4SLinus Torvalds void hci_add_sco(struct hci_conn *conn, __u16 handle)
1451da177e4SLinus Torvalds {
1461da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
1471da177e4SLinus Torvalds 	struct hci_cp_add_sco cp;
1481da177e4SLinus Torvalds 
1491da177e4SLinus Torvalds 	BT_DBG("%p", conn);
1501da177e4SLinus Torvalds 
1511da177e4SLinus Torvalds 	conn->state = BT_CONNECT;
1521da177e4SLinus Torvalds 	conn->out = 1;
1531da177e4SLinus Torvalds 
154efc7688bSMarcel Holtmann 	conn->attempt++;
155efc7688bSMarcel Holtmann 
156aca3192cSYOSHIFUJI Hideaki 	cp.handle   = cpu_to_le16(handle);
157a8746417SMarcel Holtmann 	cp.pkt_type = cpu_to_le16(conn->pkt_type);
1581da177e4SLinus Torvalds 
159a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_ADD_SCO, sizeof(cp), &cp);
1601da177e4SLinus Torvalds }
1611da177e4SLinus Torvalds 
162b6a0dc82SMarcel Holtmann void hci_setup_sync(struct hci_conn *conn, __u16 handle)
163b6a0dc82SMarcel Holtmann {
164b6a0dc82SMarcel Holtmann 	struct hci_dev *hdev = conn->hdev;
165b6a0dc82SMarcel Holtmann 	struct hci_cp_setup_sync_conn cp;
166b6a0dc82SMarcel Holtmann 
167b6a0dc82SMarcel Holtmann 	BT_DBG("%p", conn);
168b6a0dc82SMarcel Holtmann 
169b6a0dc82SMarcel Holtmann 	conn->state = BT_CONNECT;
170b6a0dc82SMarcel Holtmann 	conn->out = 1;
171b6a0dc82SMarcel Holtmann 
172efc7688bSMarcel Holtmann 	conn->attempt++;
173efc7688bSMarcel Holtmann 
174b6a0dc82SMarcel Holtmann 	cp.handle   = cpu_to_le16(handle);
175a8746417SMarcel Holtmann 	cp.pkt_type = cpu_to_le16(conn->pkt_type);
176b6a0dc82SMarcel Holtmann 
177b6a0dc82SMarcel Holtmann 	cp.tx_bandwidth   = cpu_to_le32(0x00001f40);
178b6a0dc82SMarcel Holtmann 	cp.rx_bandwidth   = cpu_to_le32(0x00001f40);
179b6a0dc82SMarcel Holtmann 	cp.max_latency    = cpu_to_le16(0xffff);
180b6a0dc82SMarcel Holtmann 	cp.voice_setting  = cpu_to_le16(hdev->voice_setting);
181b6a0dc82SMarcel Holtmann 	cp.retrans_effort = 0xff;
182b6a0dc82SMarcel Holtmann 
183b6a0dc82SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
184b6a0dc82SMarcel Holtmann }
185b6a0dc82SMarcel Holtmann 
1862ce603ebSClaudio Takahasi void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
1872ce603ebSClaudio Takahasi 					u16 latency, u16 to_multiplier)
1882ce603ebSClaudio Takahasi {
1892ce603ebSClaudio Takahasi 	struct hci_cp_le_conn_update cp;
1902ce603ebSClaudio Takahasi 	struct hci_dev *hdev = conn->hdev;
1912ce603ebSClaudio Takahasi 
1922ce603ebSClaudio Takahasi 	memset(&cp, 0, sizeof(cp));
1932ce603ebSClaudio Takahasi 
1942ce603ebSClaudio Takahasi 	cp.handle		= cpu_to_le16(conn->handle);
1952ce603ebSClaudio Takahasi 	cp.conn_interval_min	= cpu_to_le16(min);
1962ce603ebSClaudio Takahasi 	cp.conn_interval_max	= cpu_to_le16(max);
1972ce603ebSClaudio Takahasi 	cp.conn_latency		= cpu_to_le16(latency);
1982ce603ebSClaudio Takahasi 	cp.supervision_timeout	= cpu_to_le16(to_multiplier);
1992ce603ebSClaudio Takahasi 	cp.min_ce_len		= cpu_to_le16(0x0001);
2002ce603ebSClaudio Takahasi 	cp.max_ce_len		= cpu_to_le16(0x0001);
2012ce603ebSClaudio Takahasi 
2022ce603ebSClaudio Takahasi 	hci_send_cmd(hdev, HCI_OP_LE_CONN_UPDATE, sizeof(cp), &cp);
2032ce603ebSClaudio Takahasi }
2042ce603ebSClaudio Takahasi EXPORT_SYMBOL(hci_le_conn_update);
2052ce603ebSClaudio Takahasi 
206e73439d8SMarcel Holtmann /* Device _must_ be locked */
207e73439d8SMarcel Holtmann void hci_sco_setup(struct hci_conn *conn, __u8 status)
208e73439d8SMarcel Holtmann {
209e73439d8SMarcel Holtmann 	struct hci_conn *sco = conn->link;
210e73439d8SMarcel Holtmann 
211e73439d8SMarcel Holtmann 	BT_DBG("%p", conn);
212e73439d8SMarcel Holtmann 
213e73439d8SMarcel Holtmann 	if (!sco)
214e73439d8SMarcel Holtmann 		return;
215e73439d8SMarcel Holtmann 
216e73439d8SMarcel Holtmann 	if (!status) {
217e73439d8SMarcel Holtmann 		if (lmp_esco_capable(conn->hdev))
218e73439d8SMarcel Holtmann 			hci_setup_sync(sco, conn->handle);
219e73439d8SMarcel Holtmann 		else
220e73439d8SMarcel Holtmann 			hci_add_sco(sco, conn->handle);
221e73439d8SMarcel Holtmann 	} else {
222e73439d8SMarcel Holtmann 		hci_proto_connect_cfm(sco, status);
223e73439d8SMarcel Holtmann 		hci_conn_del(sco);
224e73439d8SMarcel Holtmann 	}
225e73439d8SMarcel Holtmann }
226e73439d8SMarcel Holtmann 
2271da177e4SLinus Torvalds static void hci_conn_timeout(unsigned long arg)
2281da177e4SLinus Torvalds {
2291da177e4SLinus Torvalds 	struct hci_conn *conn = (void *) arg;
2301da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
2312950f21aSMarcel Holtmann 	__u8 reason;
2321da177e4SLinus Torvalds 
2331da177e4SLinus Torvalds 	BT_DBG("conn %p state %d", conn, conn->state);
2341da177e4SLinus Torvalds 
2351da177e4SLinus Torvalds 	if (atomic_read(&conn->refcnt))
2361da177e4SLinus Torvalds 		return;
2371da177e4SLinus Torvalds 
2381da177e4SLinus Torvalds 	hci_dev_lock(hdev);
2396ac59344SMarcel Holtmann 
2406ac59344SMarcel Holtmann 	switch (conn->state) {
2416ac59344SMarcel Holtmann 	case BT_CONNECT:
242769be974SMarcel Holtmann 	case BT_CONNECT2:
243fcd89c09SVille Tervo 		if (conn->out) {
244fcd89c09SVille Tervo 			if (conn->type == ACL_LINK)
2456ac59344SMarcel Holtmann 				hci_acl_connect_cancel(conn);
246fcd89c09SVille Tervo 			else if (conn->type == LE_LINK)
247fcd89c09SVille Tervo 				hci_le_connect_cancel(conn);
248fcd89c09SVille Tervo 		}
2496ac59344SMarcel Holtmann 		break;
250769be974SMarcel Holtmann 	case BT_CONFIG:
2516ac59344SMarcel Holtmann 	case BT_CONNECTED:
2522950f21aSMarcel Holtmann 		reason = hci_proto_disconn_ind(conn);
2532950f21aSMarcel Holtmann 		hci_acl_disconn(conn, reason);
2546ac59344SMarcel Holtmann 		break;
2556ac59344SMarcel Holtmann 	default:
2561da177e4SLinus Torvalds 		conn->state = BT_CLOSED;
2576ac59344SMarcel Holtmann 		break;
2586ac59344SMarcel Holtmann 	}
2596ac59344SMarcel Holtmann 
2601da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
2611da177e4SLinus Torvalds }
2621da177e4SLinus Torvalds 
26304837f64SMarcel Holtmann static void hci_conn_idle(unsigned long arg)
2641da177e4SLinus Torvalds {
26504837f64SMarcel Holtmann 	struct hci_conn *conn = (void *) arg;
26604837f64SMarcel Holtmann 
26704837f64SMarcel Holtmann 	BT_DBG("conn %p mode %d", conn, conn->mode);
26804837f64SMarcel Holtmann 
26904837f64SMarcel Holtmann 	hci_conn_enter_sniff_mode(conn);
2701da177e4SLinus Torvalds }
2711da177e4SLinus Torvalds 
2729f61656aSJohan Hedberg static void hci_conn_auto_accept(unsigned long arg)
2739f61656aSJohan Hedberg {
2749f61656aSJohan Hedberg 	struct hci_conn *conn = (void *) arg;
2759f61656aSJohan Hedberg 	struct hci_dev *hdev = conn->hdev;
2769f61656aSJohan Hedberg 
2779f61656aSJohan Hedberg 	hci_dev_lock(hdev);
2789f61656aSJohan Hedberg 
2799f61656aSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, sizeof(conn->dst),
2809f61656aSJohan Hedberg 								&conn->dst);
2819f61656aSJohan Hedberg 
2829f61656aSJohan Hedberg 	hci_dev_unlock(hdev);
2839f61656aSJohan Hedberg }
2849f61656aSJohan Hedberg 
2851da177e4SLinus Torvalds struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
2861da177e4SLinus Torvalds {
2871da177e4SLinus Torvalds 	struct hci_conn *conn;
2881da177e4SLinus Torvalds 
2891da177e4SLinus Torvalds 	BT_DBG("%s dst %s", hdev->name, batostr(dst));
2901da177e4SLinus Torvalds 
29104837f64SMarcel Holtmann 	conn = kzalloc(sizeof(struct hci_conn), GFP_ATOMIC);
29204837f64SMarcel Holtmann 	if (!conn)
2931da177e4SLinus Torvalds 		return NULL;
2941da177e4SLinus Torvalds 
2951da177e4SLinus Torvalds 	bacpy(&conn->dst, dst);
2961da177e4SLinus Torvalds 	conn->hdev  = hdev;
29704837f64SMarcel Holtmann 	conn->type  = type;
29804837f64SMarcel Holtmann 	conn->mode  = HCI_CM_ACTIVE;
2991da177e4SLinus Torvalds 	conn->state = BT_OPEN;
30093f19c9fSAndrei Emeltchenko 	conn->auth_type = HCI_AT_GENERAL_BONDING;
30117fa4b9dSJohan Hedberg 	conn->io_capability = hdev->io_capability;
302a9583556SJohan Hedberg 	conn->remote_auth = 0xff;
30313d39315SWaldemar Rymarkiewicz 	conn->key_type = 0xff;
3041da177e4SLinus Torvalds 
30504837f64SMarcel Holtmann 	conn->power_save = 1;
306052b30b0SMarcel Holtmann 	conn->disc_timeout = HCI_DISCONN_TIMEOUT;
30704837f64SMarcel Holtmann 
308a8746417SMarcel Holtmann 	switch (type) {
309a8746417SMarcel Holtmann 	case ACL_LINK:
310a8746417SMarcel Holtmann 		conn->pkt_type = hdev->pkt_type & ACL_PTYPE_MASK;
311a8746417SMarcel Holtmann 		break;
312a8746417SMarcel Holtmann 	case SCO_LINK:
313a8746417SMarcel Holtmann 		if (lmp_esco_capable(hdev))
314efc7688bSMarcel Holtmann 			conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
315efc7688bSMarcel Holtmann 					(hdev->esco_type & EDR_ESCO_MASK);
316a8746417SMarcel Holtmann 		else
317a8746417SMarcel Holtmann 			conn->pkt_type = hdev->pkt_type & SCO_PTYPE_MASK;
318a8746417SMarcel Holtmann 		break;
319a8746417SMarcel Holtmann 	case ESCO_LINK:
320efc7688bSMarcel Holtmann 		conn->pkt_type = hdev->esco_type & ~EDR_ESCO_MASK;
321a8746417SMarcel Holtmann 		break;
322a8746417SMarcel Holtmann 	}
323a8746417SMarcel Holtmann 
3241da177e4SLinus Torvalds 	skb_queue_head_init(&conn->data_q);
32504837f64SMarcel Holtmann 
326b24b8a24SPavel Emelyanov 	setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn);
327b24b8a24SPavel Emelyanov 	setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn);
3289f61656aSJohan Hedberg 	setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept,
3299f61656aSJohan Hedberg 							(unsigned long) conn);
3301da177e4SLinus Torvalds 
3311da177e4SLinus Torvalds 	atomic_set(&conn->refcnt, 0);
3321da177e4SLinus Torvalds 
3331da177e4SLinus Torvalds 	hci_dev_hold(hdev);
3341da177e4SLinus Torvalds 
3351da177e4SLinus Torvalds 	tasklet_disable(&hdev->tx_task);
3361da177e4SLinus Torvalds 
3371da177e4SLinus Torvalds 	hci_conn_hash_add(hdev, conn);
3381da177e4SLinus Torvalds 	if (hdev->notify)
3391da177e4SLinus Torvalds 		hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
3401da177e4SLinus Torvalds 
3419eba32b8SMarcel Holtmann 	atomic_set(&conn->devref, 0);
3429eba32b8SMarcel Holtmann 
343a67e899cSMarcel Holtmann 	hci_conn_init_sysfs(conn);
344a67e899cSMarcel Holtmann 
3451da177e4SLinus Torvalds 	tasklet_enable(&hdev->tx_task);
3461da177e4SLinus Torvalds 
3471da177e4SLinus Torvalds 	return conn;
3481da177e4SLinus Torvalds }
3491da177e4SLinus Torvalds 
3501da177e4SLinus Torvalds int hci_conn_del(struct hci_conn *conn)
3511da177e4SLinus Torvalds {
3521da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
3531da177e4SLinus Torvalds 
3541da177e4SLinus Torvalds 	BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
3551da177e4SLinus Torvalds 
35604837f64SMarcel Holtmann 	del_timer(&conn->idle_timer);
35704837f64SMarcel Holtmann 
35804837f64SMarcel Holtmann 	del_timer(&conn->disc_timer);
3591da177e4SLinus Torvalds 
3609f61656aSJohan Hedberg 	del_timer(&conn->auto_accept_timer);
3619f61656aSJohan Hedberg 
3625b7f9909SMarcel Holtmann 	if (conn->type == ACL_LINK) {
3631da177e4SLinus Torvalds 		struct hci_conn *sco = conn->link;
3641da177e4SLinus Torvalds 		if (sco)
3651da177e4SLinus Torvalds 			sco->link = NULL;
3661da177e4SLinus Torvalds 
3671da177e4SLinus Torvalds 		/* Unacked frames */
3681da177e4SLinus Torvalds 		hdev->acl_cnt += conn->sent;
3696ed58ec5SVille Tervo 	} else if (conn->type == LE_LINK) {
3706ed58ec5SVille Tervo 		if (hdev->le_pkts)
3716ed58ec5SVille Tervo 			hdev->le_cnt += conn->sent;
3726ed58ec5SVille Tervo 		else
3736ed58ec5SVille Tervo 			hdev->acl_cnt += conn->sent;
3745b7f9909SMarcel Holtmann 	} else {
3755b7f9909SMarcel Holtmann 		struct hci_conn *acl = conn->link;
3765b7f9909SMarcel Holtmann 		if (acl) {
3775b7f9909SMarcel Holtmann 			acl->link = NULL;
3785b7f9909SMarcel Holtmann 			hci_conn_put(acl);
3795b7f9909SMarcel Holtmann 		}
3801da177e4SLinus Torvalds 	}
3811da177e4SLinus Torvalds 
3821da177e4SLinus Torvalds 	tasklet_disable(&hdev->tx_task);
3837d0db0a3SMarcel Holtmann 
3841da177e4SLinus Torvalds 	hci_conn_hash_del(hdev, conn);
3851da177e4SLinus Torvalds 	if (hdev->notify)
3861da177e4SLinus Torvalds 		hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
3877d0db0a3SMarcel Holtmann 
3881da177e4SLinus Torvalds 	tasklet_enable(&hdev->tx_task);
3897d0db0a3SMarcel Holtmann 
3901da177e4SLinus Torvalds 	skb_queue_purge(&conn->data_q);
3911da177e4SLinus Torvalds 
3929eba32b8SMarcel Holtmann 	hci_conn_put_device(conn);
3932ae9a6beSDave Young 
394384943ecSMarcel Holtmann 	hci_dev_put(hdev);
395384943ecSMarcel Holtmann 
3961da177e4SLinus Torvalds 	return 0;
3971da177e4SLinus Torvalds }
3981da177e4SLinus Torvalds 
3991da177e4SLinus Torvalds struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
4001da177e4SLinus Torvalds {
4011da177e4SLinus Torvalds 	int use_src = bacmp(src, BDADDR_ANY);
4021da177e4SLinus Torvalds 	struct hci_dev *hdev = NULL;
4031da177e4SLinus Torvalds 	struct list_head *p;
4041da177e4SLinus Torvalds 
4051da177e4SLinus Torvalds 	BT_DBG("%s -> %s", batostr(src), batostr(dst));
4061da177e4SLinus Torvalds 
4071da177e4SLinus Torvalds 	read_lock_bh(&hci_dev_list_lock);
4081da177e4SLinus Torvalds 
4091da177e4SLinus Torvalds 	list_for_each(p, &hci_dev_list) {
4101da177e4SLinus Torvalds 		struct hci_dev *d = list_entry(p, struct hci_dev, list);
4111da177e4SLinus Torvalds 
4121da177e4SLinus Torvalds 		if (!test_bit(HCI_UP, &d->flags) || test_bit(HCI_RAW, &d->flags))
4131da177e4SLinus Torvalds 			continue;
4141da177e4SLinus Torvalds 
4151da177e4SLinus Torvalds 		/* Simple routing:
4161da177e4SLinus Torvalds 		 *   No source address - find interface with bdaddr != dst
4171da177e4SLinus Torvalds 		 *   Source address    - find interface with bdaddr == src
4181da177e4SLinus Torvalds 		 */
4191da177e4SLinus Torvalds 
4201da177e4SLinus Torvalds 		if (use_src) {
4211da177e4SLinus Torvalds 			if (!bacmp(&d->bdaddr, src)) {
4221da177e4SLinus Torvalds 				hdev = d; break;
4231da177e4SLinus Torvalds 			}
4241da177e4SLinus Torvalds 		} else {
4251da177e4SLinus Torvalds 			if (bacmp(&d->bdaddr, dst)) {
4261da177e4SLinus Torvalds 				hdev = d; break;
4271da177e4SLinus Torvalds 			}
4281da177e4SLinus Torvalds 		}
4291da177e4SLinus Torvalds 	}
4301da177e4SLinus Torvalds 
4311da177e4SLinus Torvalds 	if (hdev)
4321da177e4SLinus Torvalds 		hdev = hci_dev_hold(hdev);
4331da177e4SLinus Torvalds 
4341da177e4SLinus Torvalds 	read_unlock_bh(&hci_dev_list_lock);
4351da177e4SLinus Torvalds 	return hdev;
4361da177e4SLinus Torvalds }
4371da177e4SLinus Torvalds EXPORT_SYMBOL(hci_get_route);
4381da177e4SLinus Torvalds 
439fcd89c09SVille Tervo /* Create SCO, ACL or LE connection.
4401da177e4SLinus Torvalds  * Device _must_ be locked */
4418c1b2355SMarcel Holtmann struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type)
4421da177e4SLinus Torvalds {
4431da177e4SLinus Torvalds 	struct hci_conn *acl;
4445b7f9909SMarcel Holtmann 	struct hci_conn *sco;
445fcd89c09SVille Tervo 	struct hci_conn *le;
4461da177e4SLinus Torvalds 
4471da177e4SLinus Torvalds 	BT_DBG("%s dst %s", hdev->name, batostr(dst));
4481da177e4SLinus Torvalds 
449fcd89c09SVille Tervo 	if (type == LE_LINK) {
450fcd89c09SVille Tervo 		le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
45115c4794fSAnderson Briglia 		if (le)
45230e76272SVille Tervo 			return ERR_PTR(-EBUSY);
453fcd89c09SVille Tervo 		le = hci_conn_add(hdev, LE_LINK, dst);
454fcd89c09SVille Tervo 		if (!le)
45530e76272SVille Tervo 			return ERR_PTR(-ENOMEM);
456*893d6751SAndre Guedes 
457fcd89c09SVille Tervo 		hci_le_connect(le);
458fcd89c09SVille Tervo 
459fcd89c09SVille Tervo 		hci_conn_hold(le);
460fcd89c09SVille Tervo 
461fcd89c09SVille Tervo 		return le;
462fcd89c09SVille Tervo 	}
463fcd89c09SVille Tervo 
46470f23020SAndrei Emeltchenko 	acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
46570f23020SAndrei Emeltchenko 	if (!acl) {
46670f23020SAndrei Emeltchenko 		acl = hci_conn_add(hdev, ACL_LINK, dst);
46770f23020SAndrei Emeltchenko 		if (!acl)
4681da177e4SLinus Torvalds 			return NULL;
4691da177e4SLinus Torvalds 	}
4701da177e4SLinus Torvalds 
4711da177e4SLinus Torvalds 	hci_conn_hold(acl);
4721da177e4SLinus Torvalds 
47309ab6f4cSMarcel Holtmann 	if (acl->state == BT_OPEN || acl->state == BT_CLOSED) {
474765c2a96SJohan Hedberg 		acl->sec_level = BT_SECURITY_LOW;
475765c2a96SJohan Hedberg 		acl->pending_sec_level = sec_level;
47609ab6f4cSMarcel Holtmann 		acl->auth_type = auth_type;
4771da177e4SLinus Torvalds 		hci_acl_connect(acl);
47809ab6f4cSMarcel Holtmann 	}
4791da177e4SLinus Torvalds 
4805b7f9909SMarcel Holtmann 	if (type == ACL_LINK)
4815b7f9909SMarcel Holtmann 		return acl;
4821da177e4SLinus Torvalds 
48370f23020SAndrei Emeltchenko 	sco = hci_conn_hash_lookup_ba(hdev, type, dst);
48470f23020SAndrei Emeltchenko 	if (!sco) {
48570f23020SAndrei Emeltchenko 		sco = hci_conn_add(hdev, type, dst);
48670f23020SAndrei Emeltchenko 		if (!sco) {
4871da177e4SLinus Torvalds 			hci_conn_put(acl);
4881da177e4SLinus Torvalds 			return NULL;
4891da177e4SLinus Torvalds 		}
4901da177e4SLinus Torvalds 	}
4915b7f9909SMarcel Holtmann 
4921da177e4SLinus Torvalds 	acl->link = sco;
4931da177e4SLinus Torvalds 	sco->link = acl;
4941da177e4SLinus Torvalds 
4951da177e4SLinus Torvalds 	hci_conn_hold(sco);
4961da177e4SLinus Torvalds 
4971da177e4SLinus Torvalds 	if (acl->state == BT_CONNECTED &&
498b6a0dc82SMarcel Holtmann 			(sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
499c390216bSNick Pelly 		acl->power_save = 1;
500c390216bSNick Pelly 		hci_conn_enter_active_mode(acl);
501c390216bSNick Pelly 
502e73439d8SMarcel Holtmann 		if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->pend)) {
503e73439d8SMarcel Holtmann 			/* defer SCO setup until mode change completed */
504e73439d8SMarcel Holtmann 			set_bit(HCI_CONN_SCO_SETUP_PEND, &acl->pend);
505e73439d8SMarcel Holtmann 			return sco;
506e73439d8SMarcel Holtmann 		}
507e73439d8SMarcel Holtmann 
508e73439d8SMarcel Holtmann 		hci_sco_setup(acl, 0x00);
509b6a0dc82SMarcel Holtmann 	}
5101da177e4SLinus Torvalds 
5111da177e4SLinus Torvalds 	return sco;
5121da177e4SLinus Torvalds }
5131da177e4SLinus Torvalds EXPORT_SYMBOL(hci_connect);
5141da177e4SLinus Torvalds 
515e7c29cb1SMarcel Holtmann /* Check link security requirement */
516e7c29cb1SMarcel Holtmann int hci_conn_check_link_mode(struct hci_conn *conn)
517e7c29cb1SMarcel Holtmann {
518e7c29cb1SMarcel Holtmann 	BT_DBG("conn %p", conn);
519e7c29cb1SMarcel Holtmann 
520e7c29cb1SMarcel Holtmann 	if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0 &&
521e7c29cb1SMarcel Holtmann 					!(conn->link_mode & HCI_LM_ENCRYPT))
522e7c29cb1SMarcel Holtmann 		return 0;
523e7c29cb1SMarcel Holtmann 
524e7c29cb1SMarcel Holtmann 	return 1;
525e7c29cb1SMarcel Holtmann }
526e7c29cb1SMarcel Holtmann EXPORT_SYMBOL(hci_conn_check_link_mode);
527e7c29cb1SMarcel Holtmann 
5281da177e4SLinus Torvalds /* Authenticate remote device */
5290684e5f9SMarcel Holtmann static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
5301da177e4SLinus Torvalds {
5311da177e4SLinus Torvalds 	BT_DBG("conn %p", conn);
5321da177e4SLinus Torvalds 
533765c2a96SJohan Hedberg 	if (conn->pending_sec_level > sec_level)
534765c2a96SJohan Hedberg 		sec_level = conn->pending_sec_level;
535765c2a96SJohan Hedberg 
53696a31833SMarcel Holtmann 	if (sec_level > conn->sec_level)
537765c2a96SJohan Hedberg 		conn->pending_sec_level = sec_level;
53896a31833SMarcel Holtmann 	else if (conn->link_mode & HCI_LM_AUTH)
5391da177e4SLinus Torvalds 		return 1;
5401da177e4SLinus Torvalds 
54165cf686eSJohan Hedberg 	/* Make sure we preserve an existing MITM requirement*/
54265cf686eSJohan Hedberg 	auth_type |= (conn->auth_type & 0x01);
54365cf686eSJohan Hedberg 
54496a31833SMarcel Holtmann 	conn->auth_type = auth_type;
54596a31833SMarcel Holtmann 
5461da177e4SLinus Torvalds 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
5471da177e4SLinus Torvalds 		struct hci_cp_auth_requested cp;
548aca3192cSYOSHIFUJI Hideaki 		cp.handle = cpu_to_le16(conn->handle);
54940be492fSMarcel Holtmann 		hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED,
55040be492fSMarcel Holtmann 							sizeof(cp), &cp);
55119f8def0SWaldemar Rymarkiewicz 		if (conn->key_type != 0xff)
55219f8def0SWaldemar Rymarkiewicz 			set_bit(HCI_CONN_REAUTH_PEND, &conn->pend);
5531da177e4SLinus Torvalds 	}
5548c1b2355SMarcel Holtmann 
5551da177e4SLinus Torvalds 	return 0;
5561da177e4SLinus Torvalds }
5571da177e4SLinus Torvalds 
55813d39315SWaldemar Rymarkiewicz /* Encrypt the the link */
55913d39315SWaldemar Rymarkiewicz static void hci_conn_encrypt(struct hci_conn *conn)
56013d39315SWaldemar Rymarkiewicz {
56113d39315SWaldemar Rymarkiewicz 	BT_DBG("conn %p", conn);
56213d39315SWaldemar Rymarkiewicz 
56313d39315SWaldemar Rymarkiewicz 	if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
56413d39315SWaldemar Rymarkiewicz 		struct hci_cp_set_conn_encrypt cp;
56513d39315SWaldemar Rymarkiewicz 		cp.handle  = cpu_to_le16(conn->handle);
56613d39315SWaldemar Rymarkiewicz 		cp.encrypt = 0x01;
56713d39315SWaldemar Rymarkiewicz 		hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
56813d39315SWaldemar Rymarkiewicz 									&cp);
56913d39315SWaldemar Rymarkiewicz 	}
57013d39315SWaldemar Rymarkiewicz }
57113d39315SWaldemar Rymarkiewicz 
5728c1b2355SMarcel Holtmann /* Enable security */
5730684e5f9SMarcel Holtmann int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
5741da177e4SLinus Torvalds {
5751da177e4SLinus Torvalds 	BT_DBG("conn %p", conn);
5761da177e4SLinus Torvalds 
57713d39315SWaldemar Rymarkiewicz 	/* For sdp we don't need the link key. */
5788c1b2355SMarcel Holtmann 	if (sec_level == BT_SECURITY_SDP)
5798c1b2355SMarcel Holtmann 		return 1;
5808c1b2355SMarcel Holtmann 
58113d39315SWaldemar Rymarkiewicz 	/* For non 2.1 devices and low security level we don't need the link
58213d39315SWaldemar Rymarkiewicz 	   key. */
5833fdca1e1SMarcel Holtmann 	if (sec_level == BT_SECURITY_LOW &&
5843fdca1e1SMarcel Holtmann 				(!conn->ssp_mode || !conn->hdev->ssp_mode))
5858c1b2355SMarcel Holtmann 		return 1;
5868c1b2355SMarcel Holtmann 
58713d39315SWaldemar Rymarkiewicz 	/* For other security levels we need the link key. */
58813d39315SWaldemar Rymarkiewicz 	if (!(conn->link_mode & HCI_LM_AUTH))
58913d39315SWaldemar Rymarkiewicz 		goto auth;
5901da177e4SLinus Torvalds 
59113d39315SWaldemar Rymarkiewicz 	/* An authenticated combination key has sufficient security for any
59213d39315SWaldemar Rymarkiewicz 	   security level. */
59313d39315SWaldemar Rymarkiewicz 	if (conn->key_type == HCI_LK_AUTH_COMBINATION)
59413d39315SWaldemar Rymarkiewicz 		goto encrypt;
59513d39315SWaldemar Rymarkiewicz 
59613d39315SWaldemar Rymarkiewicz 	/* An unauthenticated combination key has sufficient security for
59713d39315SWaldemar Rymarkiewicz 	   security level 1 and 2. */
59813d39315SWaldemar Rymarkiewicz 	if (conn->key_type == HCI_LK_UNAUTH_COMBINATION &&
59913d39315SWaldemar Rymarkiewicz 			(sec_level == BT_SECURITY_MEDIUM ||
60013d39315SWaldemar Rymarkiewicz 			sec_level == BT_SECURITY_LOW))
60113d39315SWaldemar Rymarkiewicz 		goto encrypt;
60213d39315SWaldemar Rymarkiewicz 
60313d39315SWaldemar Rymarkiewicz 	/* A combination key has always sufficient security for the security
60413d39315SWaldemar Rymarkiewicz 	   levels 1 or 2. High security level requires the combination key
60513d39315SWaldemar Rymarkiewicz 	   is generated using maximum PIN code length (16).
60613d39315SWaldemar Rymarkiewicz 	   For pre 2.1 units. */
60713d39315SWaldemar Rymarkiewicz 	if (conn->key_type == HCI_LK_COMBINATION &&
60813d39315SWaldemar Rymarkiewicz 			(sec_level != BT_SECURITY_HIGH ||
60913d39315SWaldemar Rymarkiewicz 			conn->pin_length == 16))
61013d39315SWaldemar Rymarkiewicz 		goto encrypt;
61113d39315SWaldemar Rymarkiewicz 
61213d39315SWaldemar Rymarkiewicz auth:
6131da177e4SLinus Torvalds 	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
6141da177e4SLinus Torvalds 		return 0;
6151da177e4SLinus Torvalds 
61613d39315SWaldemar Rymarkiewicz 	hci_conn_auth(conn, sec_level, auth_type);
61713d39315SWaldemar Rymarkiewicz 	return 0;
6188c1b2355SMarcel Holtmann 
61913d39315SWaldemar Rymarkiewicz encrypt:
62013d39315SWaldemar Rymarkiewicz 	if (conn->link_mode & HCI_LM_ENCRYPT)
62113d39315SWaldemar Rymarkiewicz 		return 1;
62213d39315SWaldemar Rymarkiewicz 
62313d39315SWaldemar Rymarkiewicz 	hci_conn_encrypt(conn);
6241da177e4SLinus Torvalds 	return 0;
6251da177e4SLinus Torvalds }
6268c1b2355SMarcel Holtmann EXPORT_SYMBOL(hci_conn_security);
6271da177e4SLinus Torvalds 
628b3b1b061SWaldemar Rymarkiewicz /* Check secure link requirement */
629b3b1b061SWaldemar Rymarkiewicz int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level)
630b3b1b061SWaldemar Rymarkiewicz {
631b3b1b061SWaldemar Rymarkiewicz 	BT_DBG("conn %p", conn);
632b3b1b061SWaldemar Rymarkiewicz 
633b3b1b061SWaldemar Rymarkiewicz 	if (sec_level != BT_SECURITY_HIGH)
634b3b1b061SWaldemar Rymarkiewicz 		return 1; /* Accept if non-secure is required */
635b3b1b061SWaldemar Rymarkiewicz 
636b3b1b061SWaldemar Rymarkiewicz 	if (conn->key_type == HCI_LK_AUTH_COMBINATION ||
637b3b1b061SWaldemar Rymarkiewicz 			(conn->key_type == HCI_LK_COMBINATION &&
638b3b1b061SWaldemar Rymarkiewicz 			conn->pin_length == 16))
639b3b1b061SWaldemar Rymarkiewicz 		return 1;
640b3b1b061SWaldemar Rymarkiewicz 
641b3b1b061SWaldemar Rymarkiewicz 	return 0; /* Reject not secure link */
642b3b1b061SWaldemar Rymarkiewicz }
643b3b1b061SWaldemar Rymarkiewicz EXPORT_SYMBOL(hci_conn_check_secure);
644b3b1b061SWaldemar Rymarkiewicz 
6451da177e4SLinus Torvalds /* Change link key */
6461da177e4SLinus Torvalds int hci_conn_change_link_key(struct hci_conn *conn)
6471da177e4SLinus Torvalds {
6481da177e4SLinus Torvalds 	BT_DBG("conn %p", conn);
6491da177e4SLinus Torvalds 
6501da177e4SLinus Torvalds 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
6511da177e4SLinus Torvalds 		struct hci_cp_change_conn_link_key cp;
652aca3192cSYOSHIFUJI Hideaki 		cp.handle = cpu_to_le16(conn->handle);
65340be492fSMarcel Holtmann 		hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY,
65440be492fSMarcel Holtmann 							sizeof(cp), &cp);
6551da177e4SLinus Torvalds 	}
6568c1b2355SMarcel Holtmann 
6571da177e4SLinus Torvalds 	return 0;
6581da177e4SLinus Torvalds }
6591da177e4SLinus Torvalds EXPORT_SYMBOL(hci_conn_change_link_key);
6601da177e4SLinus Torvalds 
6611da177e4SLinus Torvalds /* Switch role */
6628c1b2355SMarcel Holtmann int hci_conn_switch_role(struct hci_conn *conn, __u8 role)
6631da177e4SLinus Torvalds {
6641da177e4SLinus Torvalds 	BT_DBG("conn %p", conn);
6651da177e4SLinus Torvalds 
6661da177e4SLinus Torvalds 	if (!role && conn->link_mode & HCI_LM_MASTER)
6671da177e4SLinus Torvalds 		return 1;
6681da177e4SLinus Torvalds 
6691da177e4SLinus Torvalds 	if (!test_and_set_bit(HCI_CONN_RSWITCH_PEND, &conn->pend)) {
6701da177e4SLinus Torvalds 		struct hci_cp_switch_role cp;
6711da177e4SLinus Torvalds 		bacpy(&cp.bdaddr, &conn->dst);
6721da177e4SLinus Torvalds 		cp.role = role;
673a9de9248SMarcel Holtmann 		hci_send_cmd(conn->hdev, HCI_OP_SWITCH_ROLE, sizeof(cp), &cp);
6741da177e4SLinus Torvalds 	}
6758c1b2355SMarcel Holtmann 
6761da177e4SLinus Torvalds 	return 0;
6771da177e4SLinus Torvalds }
6781da177e4SLinus Torvalds EXPORT_SYMBOL(hci_conn_switch_role);
6791da177e4SLinus Torvalds 
68004837f64SMarcel Holtmann /* Enter active mode */
68104837f64SMarcel Holtmann void hci_conn_enter_active_mode(struct hci_conn *conn)
68204837f64SMarcel Holtmann {
68304837f64SMarcel Holtmann 	struct hci_dev *hdev = conn->hdev;
68404837f64SMarcel Holtmann 
68504837f64SMarcel Holtmann 	BT_DBG("conn %p mode %d", conn, conn->mode);
68604837f64SMarcel Holtmann 
68704837f64SMarcel Holtmann 	if (test_bit(HCI_RAW, &hdev->flags))
68804837f64SMarcel Holtmann 		return;
68904837f64SMarcel Holtmann 
69004837f64SMarcel Holtmann 	if (conn->mode != HCI_CM_SNIFF || !conn->power_save)
69104837f64SMarcel Holtmann 		goto timer;
69204837f64SMarcel Holtmann 
69304837f64SMarcel Holtmann 	if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
69404837f64SMarcel Holtmann 		struct hci_cp_exit_sniff_mode cp;
695aca3192cSYOSHIFUJI Hideaki 		cp.handle = cpu_to_le16(conn->handle);
696a9de9248SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_EXIT_SNIFF_MODE, sizeof(cp), &cp);
69704837f64SMarcel Holtmann 	}
69804837f64SMarcel Holtmann 
69904837f64SMarcel Holtmann timer:
70004837f64SMarcel Holtmann 	if (hdev->idle_timeout > 0)
70104837f64SMarcel Holtmann 		mod_timer(&conn->idle_timer,
70204837f64SMarcel Holtmann 			jiffies + msecs_to_jiffies(hdev->idle_timeout));
70304837f64SMarcel Holtmann }
70404837f64SMarcel Holtmann 
70504837f64SMarcel Holtmann /* Enter sniff mode */
70604837f64SMarcel Holtmann void hci_conn_enter_sniff_mode(struct hci_conn *conn)
70704837f64SMarcel Holtmann {
70804837f64SMarcel Holtmann 	struct hci_dev *hdev = conn->hdev;
70904837f64SMarcel Holtmann 
71004837f64SMarcel Holtmann 	BT_DBG("conn %p mode %d", conn, conn->mode);
71104837f64SMarcel Holtmann 
71204837f64SMarcel Holtmann 	if (test_bit(HCI_RAW, &hdev->flags))
71304837f64SMarcel Holtmann 		return;
71404837f64SMarcel Holtmann 
71504837f64SMarcel Holtmann 	if (!lmp_sniff_capable(hdev) || !lmp_sniff_capable(conn))
71604837f64SMarcel Holtmann 		return;
71704837f64SMarcel Holtmann 
71804837f64SMarcel Holtmann 	if (conn->mode != HCI_CM_ACTIVE || !(conn->link_policy & HCI_LP_SNIFF))
71904837f64SMarcel Holtmann 		return;
72004837f64SMarcel Holtmann 
72104837f64SMarcel Holtmann 	if (lmp_sniffsubr_capable(hdev) && lmp_sniffsubr_capable(conn)) {
72204837f64SMarcel Holtmann 		struct hci_cp_sniff_subrate cp;
723aca3192cSYOSHIFUJI Hideaki 		cp.handle             = cpu_to_le16(conn->handle);
724aca3192cSYOSHIFUJI Hideaki 		cp.max_latency        = cpu_to_le16(0);
725aca3192cSYOSHIFUJI Hideaki 		cp.min_remote_timeout = cpu_to_le16(0);
726aca3192cSYOSHIFUJI Hideaki 		cp.min_local_timeout  = cpu_to_le16(0);
727a9de9248SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_SNIFF_SUBRATE, sizeof(cp), &cp);
72804837f64SMarcel Holtmann 	}
72904837f64SMarcel Holtmann 
73004837f64SMarcel Holtmann 	if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
73104837f64SMarcel Holtmann 		struct hci_cp_sniff_mode cp;
732aca3192cSYOSHIFUJI Hideaki 		cp.handle       = cpu_to_le16(conn->handle);
733aca3192cSYOSHIFUJI Hideaki 		cp.max_interval = cpu_to_le16(hdev->sniff_max_interval);
734aca3192cSYOSHIFUJI Hideaki 		cp.min_interval = cpu_to_le16(hdev->sniff_min_interval);
735aca3192cSYOSHIFUJI Hideaki 		cp.attempt      = cpu_to_le16(4);
736aca3192cSYOSHIFUJI Hideaki 		cp.timeout      = cpu_to_le16(1);
737a9de9248SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_SNIFF_MODE, sizeof(cp), &cp);
73804837f64SMarcel Holtmann 	}
73904837f64SMarcel Holtmann }
74004837f64SMarcel Holtmann 
7411da177e4SLinus Torvalds /* Drop all connection on the device */
7421da177e4SLinus Torvalds void hci_conn_hash_flush(struct hci_dev *hdev)
7431da177e4SLinus Torvalds {
7441da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
7451da177e4SLinus Torvalds 	struct list_head *p;
7461da177e4SLinus Torvalds 
7471da177e4SLinus Torvalds 	BT_DBG("hdev %s", hdev->name);
7481da177e4SLinus Torvalds 
7491da177e4SLinus Torvalds 	p = h->list.next;
7501da177e4SLinus Torvalds 	while (p != &h->list) {
7511da177e4SLinus Torvalds 		struct hci_conn *c;
7521da177e4SLinus Torvalds 
7531da177e4SLinus Torvalds 		c = list_entry(p, struct hci_conn, list);
7541da177e4SLinus Torvalds 		p = p->next;
7551da177e4SLinus Torvalds 
7561da177e4SLinus Torvalds 		c->state = BT_CLOSED;
7571da177e4SLinus Torvalds 
7582950f21aSMarcel Holtmann 		hci_proto_disconn_cfm(c, 0x16);
7591da177e4SLinus Torvalds 		hci_conn_del(c);
7601da177e4SLinus Torvalds 	}
7611da177e4SLinus Torvalds }
7621da177e4SLinus Torvalds 
763a9de9248SMarcel Holtmann /* Check pending connect attempts */
764a9de9248SMarcel Holtmann void hci_conn_check_pending(struct hci_dev *hdev)
765a9de9248SMarcel Holtmann {
766a9de9248SMarcel Holtmann 	struct hci_conn *conn;
767a9de9248SMarcel Holtmann 
768a9de9248SMarcel Holtmann 	BT_DBG("hdev %s", hdev->name);
769a9de9248SMarcel Holtmann 
770a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
771a9de9248SMarcel Holtmann 
772a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
773a9de9248SMarcel Holtmann 	if (conn)
774a9de9248SMarcel Holtmann 		hci_acl_connect(conn);
775a9de9248SMarcel Holtmann 
776a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
777a9de9248SMarcel Holtmann }
778a9de9248SMarcel Holtmann 
7799eba32b8SMarcel Holtmann void hci_conn_hold_device(struct hci_conn *conn)
7809eba32b8SMarcel Holtmann {
7819eba32b8SMarcel Holtmann 	atomic_inc(&conn->devref);
7829eba32b8SMarcel Holtmann }
7839eba32b8SMarcel Holtmann EXPORT_SYMBOL(hci_conn_hold_device);
7849eba32b8SMarcel Holtmann 
7859eba32b8SMarcel Holtmann void hci_conn_put_device(struct hci_conn *conn)
7869eba32b8SMarcel Holtmann {
7879eba32b8SMarcel Holtmann 	if (atomic_dec_and_test(&conn->devref))
7889eba32b8SMarcel Holtmann 		hci_conn_del_sysfs(conn);
7899eba32b8SMarcel Holtmann }
7909eba32b8SMarcel Holtmann EXPORT_SYMBOL(hci_conn_put_device);
7919eba32b8SMarcel Holtmann 
7921da177e4SLinus Torvalds int hci_get_conn_list(void __user *arg)
7931da177e4SLinus Torvalds {
7941da177e4SLinus Torvalds 	struct hci_conn_list_req req, *cl;
7951da177e4SLinus Torvalds 	struct hci_conn_info *ci;
7961da177e4SLinus Torvalds 	struct hci_dev *hdev;
7971da177e4SLinus Torvalds 	struct list_head *p;
7981da177e4SLinus Torvalds 	int n = 0, size, err;
7991da177e4SLinus Torvalds 
8001da177e4SLinus Torvalds 	if (copy_from_user(&req, arg, sizeof(req)))
8011da177e4SLinus Torvalds 		return -EFAULT;
8021da177e4SLinus Torvalds 
8031da177e4SLinus Torvalds 	if (!req.conn_num || req.conn_num > (PAGE_SIZE * 2) / sizeof(*ci))
8041da177e4SLinus Torvalds 		return -EINVAL;
8051da177e4SLinus Torvalds 
8061da177e4SLinus Torvalds 	size = sizeof(req) + req.conn_num * sizeof(*ci);
8071da177e4SLinus Torvalds 
80870f23020SAndrei Emeltchenko 	cl = kmalloc(size, GFP_KERNEL);
80970f23020SAndrei Emeltchenko 	if (!cl)
8101da177e4SLinus Torvalds 		return -ENOMEM;
8111da177e4SLinus Torvalds 
81270f23020SAndrei Emeltchenko 	hdev = hci_dev_get(req.dev_id);
81370f23020SAndrei Emeltchenko 	if (!hdev) {
8141da177e4SLinus Torvalds 		kfree(cl);
8151da177e4SLinus Torvalds 		return -ENODEV;
8161da177e4SLinus Torvalds 	}
8171da177e4SLinus Torvalds 
8181da177e4SLinus Torvalds 	ci = cl->conn_info;
8191da177e4SLinus Torvalds 
8201da177e4SLinus Torvalds 	hci_dev_lock_bh(hdev);
8211da177e4SLinus Torvalds 	list_for_each(p, &hdev->conn_hash.list) {
8221da177e4SLinus Torvalds 		register struct hci_conn *c;
8231da177e4SLinus Torvalds 		c = list_entry(p, struct hci_conn, list);
8241da177e4SLinus Torvalds 
8251da177e4SLinus Torvalds 		bacpy(&(ci + n)->bdaddr, &c->dst);
8261da177e4SLinus Torvalds 		(ci + n)->handle = c->handle;
8271da177e4SLinus Torvalds 		(ci + n)->type  = c->type;
8281da177e4SLinus Torvalds 		(ci + n)->out   = c->out;
8291da177e4SLinus Torvalds 		(ci + n)->state = c->state;
8301da177e4SLinus Torvalds 		(ci + n)->link_mode = c->link_mode;
8311da177e4SLinus Torvalds 		if (++n >= req.conn_num)
8321da177e4SLinus Torvalds 			break;
8331da177e4SLinus Torvalds 	}
8341da177e4SLinus Torvalds 	hci_dev_unlock_bh(hdev);
8351da177e4SLinus Torvalds 
8361da177e4SLinus Torvalds 	cl->dev_id = hdev->id;
8371da177e4SLinus Torvalds 	cl->conn_num = n;
8381da177e4SLinus Torvalds 	size = sizeof(req) + n * sizeof(*ci);
8391da177e4SLinus Torvalds 
8401da177e4SLinus Torvalds 	hci_dev_put(hdev);
8411da177e4SLinus Torvalds 
8421da177e4SLinus Torvalds 	err = copy_to_user(arg, cl, size);
8431da177e4SLinus Torvalds 	kfree(cl);
8441da177e4SLinus Torvalds 
8451da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
8461da177e4SLinus Torvalds }
8471da177e4SLinus Torvalds 
8481da177e4SLinus Torvalds int hci_get_conn_info(struct hci_dev *hdev, void __user *arg)
8491da177e4SLinus Torvalds {
8501da177e4SLinus Torvalds 	struct hci_conn_info_req req;
8511da177e4SLinus Torvalds 	struct hci_conn_info ci;
8521da177e4SLinus Torvalds 	struct hci_conn *conn;
8531da177e4SLinus Torvalds 	char __user *ptr = arg + sizeof(req);
8541da177e4SLinus Torvalds 
8551da177e4SLinus Torvalds 	if (copy_from_user(&req, arg, sizeof(req)))
8561da177e4SLinus Torvalds 		return -EFAULT;
8571da177e4SLinus Torvalds 
8581da177e4SLinus Torvalds 	hci_dev_lock_bh(hdev);
8591da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_ba(hdev, req.type, &req.bdaddr);
8601da177e4SLinus Torvalds 	if (conn) {
8611da177e4SLinus Torvalds 		bacpy(&ci.bdaddr, &conn->dst);
8621da177e4SLinus Torvalds 		ci.handle = conn->handle;
8631da177e4SLinus Torvalds 		ci.type  = conn->type;
8641da177e4SLinus Torvalds 		ci.out   = conn->out;
8651da177e4SLinus Torvalds 		ci.state = conn->state;
8661da177e4SLinus Torvalds 		ci.link_mode = conn->link_mode;
8671da177e4SLinus Torvalds 	}
8681da177e4SLinus Torvalds 	hci_dev_unlock_bh(hdev);
8691da177e4SLinus Torvalds 
8701da177e4SLinus Torvalds 	if (!conn)
8711da177e4SLinus Torvalds 		return -ENOENT;
8721da177e4SLinus Torvalds 
8731da177e4SLinus Torvalds 	return copy_to_user(ptr, &ci, sizeof(ci)) ? -EFAULT : 0;
8741da177e4SLinus Torvalds }
87540be492fSMarcel Holtmann 
87640be492fSMarcel Holtmann int hci_get_auth_info(struct hci_dev *hdev, void __user *arg)
87740be492fSMarcel Holtmann {
87840be492fSMarcel Holtmann 	struct hci_auth_info_req req;
87940be492fSMarcel Holtmann 	struct hci_conn *conn;
88040be492fSMarcel Holtmann 
88140be492fSMarcel Holtmann 	if (copy_from_user(&req, arg, sizeof(req)))
88240be492fSMarcel Holtmann 		return -EFAULT;
88340be492fSMarcel Holtmann 
88440be492fSMarcel Holtmann 	hci_dev_lock_bh(hdev);
88540be492fSMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &req.bdaddr);
88640be492fSMarcel Holtmann 	if (conn)
88740be492fSMarcel Holtmann 		req.type = conn->auth_type;
88840be492fSMarcel Holtmann 	hci_dev_unlock_bh(hdev);
88940be492fSMarcel Holtmann 
89040be492fSMarcel Holtmann 	if (!conn)
89140be492fSMarcel Holtmann 		return -ENOENT;
89240be492fSMarcel Holtmann 
89340be492fSMarcel Holtmann 	return copy_to_user(arg, &req, sizeof(req)) ? -EFAULT : 0;
89440be492fSMarcel Holtmann }
895