blob: 41351ba692e90174ec5dcfc4519cb4b393858762 [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
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4
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
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
30#include <linux/errno.h>
31#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/slab.h>
33#include <linux/poll.h>
34#include <linux/fcntl.h>
35#include <linux/init.h>
36#include <linux/skbuff.h>
37#include <linux/interrupt.h>
38#include <linux/notifier.h>
39#include <net/sock.h>
40
41#include <asm/system.h>
42#include <asm/uaccess.h>
43#include <asm/unaligned.h>
44
45#include <net/bluetooth/bluetooth.h>
46#include <net/bluetooth/hci_core.h>
47
48#ifndef CONFIG_BT_HCI_CORE_DEBUG
49#undef BT_DBG
50#define BT_DBG(D...)
51#endif
52
Marcel Holtmann4c67bc72006-10-15 17:30:56 +020053void hci_acl_connect(struct hci_conn *conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -070054{
55 struct hci_dev *hdev = conn->hdev;
56 struct inquiry_entry *ie;
57 struct hci_cp_create_conn cp;
58
59 BT_DBG("%p", conn);
60
61 conn->state = BT_CONNECT;
Marcel Holtmanna8746412008-07-14 20:13:46 +020062 conn->out = 1;
63
Linus Torvalds1da177e2005-04-16 15:20:36 -070064 conn->link_mode = HCI_LM_MASTER;
65
Marcel Holtmann4c67bc72006-10-15 17:30:56 +020066 conn->attempt++;
67
Marcel Holtmanne4e8e372008-07-14 20:13:47 +020068 conn->link_policy = hdev->link_policy;
69
Linus Torvalds1da177e2005-04-16 15:20:36 -070070 memset(&cp, 0, sizeof(cp));
71 bacpy(&cp.bdaddr, &conn->dst);
72 cp.pscan_rep_mode = 0x02;
73
Marcel Holtmann41a96212008-07-14 20:13:48 +020074 if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) {
75 if (inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) {
76 cp.pscan_rep_mode = ie->data.pscan_rep_mode;
77 cp.pscan_mode = ie->data.pscan_mode;
78 cp.clock_offset = ie->data.clock_offset |
79 cpu_to_le16(0x8000);
80 }
81
Linus Torvalds1da177e2005-04-16 15:20:36 -070082 memcpy(conn->dev_class, ie->data.dev_class, 3);
Marcel Holtmann41a96212008-07-14 20:13:48 +020083 conn->ssp_mode = ie->data.ssp_mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -070084 }
85
Marcel Holtmanna8746412008-07-14 20:13:46 +020086 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -070087 if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER))
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +020088 cp.role_switch = 0x01;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 else
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +020090 cp.role_switch = 0x00;
Marcel Holtmann4c67bc72006-10-15 17:30:56 +020091
Marcel Holtmanna9de9242007-10-20 13:33:56 +020092 hci_send_cmd(hdev, HCI_OP_CREATE_CONN, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -070093}
94
Marcel Holtmann6ac59342006-09-26 09:43:48 +020095static void hci_acl_connect_cancel(struct hci_conn *conn)
96{
97 struct hci_cp_create_conn_cancel cp;
98
99 BT_DBG("%p", conn);
100
101 if (conn->hdev->hci_ver < 2)
102 return;
103
104 bacpy(&cp.bdaddr, &conn->dst);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200105 hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp);
Marcel Holtmann6ac59342006-09-26 09:43:48 +0200106}
107
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
109{
110 struct hci_cp_disconnect cp;
111
112 BT_DBG("%p", conn);
113
114 conn->state = BT_DISCONN;
115
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -0700116 cp.handle = cpu_to_le16(conn->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117 cp.reason = reason;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200118 hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119}
120
121void hci_add_sco(struct hci_conn *conn, __u16 handle)
122{
123 struct hci_dev *hdev = conn->hdev;
124 struct hci_cp_add_sco cp;
125
126 BT_DBG("%p", conn);
127
128 conn->state = BT_CONNECT;
129 conn->out = 1;
130
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -0700131 cp.handle = cpu_to_le16(handle);
Marcel Holtmanna8746412008-07-14 20:13:46 +0200132 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200134 hci_send_cmd(hdev, HCI_OP_ADD_SCO, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135}
136
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200137void hci_setup_sync(struct hci_conn *conn, __u16 handle)
138{
139 struct hci_dev *hdev = conn->hdev;
140 struct hci_cp_setup_sync_conn cp;
141
142 BT_DBG("%p", conn);
143
144 conn->state = BT_CONNECT;
145 conn->out = 1;
146
147 cp.handle = cpu_to_le16(handle);
Marcel Holtmanna8746412008-07-14 20:13:46 +0200148 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200149
150 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
151 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
152 cp.max_latency = cpu_to_le16(0xffff);
153 cp.voice_setting = cpu_to_le16(hdev->voice_setting);
154 cp.retrans_effort = 0xff;
155
156 hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
157}
158
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159static void hci_conn_timeout(unsigned long arg)
160{
Marcel Holtmann04837f62006-07-03 10:02:33 +0200161 struct hci_conn *conn = (void *) arg;
162 struct hci_dev *hdev = conn->hdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163
164 BT_DBG("conn %p state %d", conn, conn->state);
165
166 if (atomic_read(&conn->refcnt))
167 return;
168
169 hci_dev_lock(hdev);
Marcel Holtmann6ac59342006-09-26 09:43:48 +0200170
171 switch (conn->state) {
172 case BT_CONNECT:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200173 if (conn->type == ACL_LINK)
174 hci_acl_connect_cancel(conn);
175 else
176 hci_acl_disconn(conn, 0x13);
Marcel Holtmann6ac59342006-09-26 09:43:48 +0200177 break;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900178 case BT_CONNECTED:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 hci_acl_disconn(conn, 0x13);
Marcel Holtmann6ac59342006-09-26 09:43:48 +0200180 break;
181 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 conn->state = BT_CLOSED;
Marcel Holtmann6ac59342006-09-26 09:43:48 +0200183 break;
184 }
185
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187}
188
Marcel Holtmann04837f62006-07-03 10:02:33 +0200189static void hci_conn_idle(unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190{
Marcel Holtmann04837f62006-07-03 10:02:33 +0200191 struct hci_conn *conn = (void *) arg;
192
193 BT_DBG("conn %p mode %d", conn, conn->mode);
194
195 hci_conn_enter_sniff_mode(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196}
197
198struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
199{
200 struct hci_conn *conn;
201
202 BT_DBG("%s dst %s", hdev->name, batostr(dst));
203
Marcel Holtmann04837f62006-07-03 10:02:33 +0200204 conn = kzalloc(sizeof(struct hci_conn), GFP_ATOMIC);
205 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207
208 bacpy(&conn->dst, dst);
Marcel Holtmanna8746412008-07-14 20:13:46 +0200209 conn->hdev = hdev;
210 conn->type = type;
211 conn->mode = HCI_CM_ACTIVE;
212 conn->state = BT_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213
Marcel Holtmann04837f62006-07-03 10:02:33 +0200214 conn->power_save = 1;
215
Marcel Holtmanna8746412008-07-14 20:13:46 +0200216 switch (type) {
217 case ACL_LINK:
218 conn->pkt_type = hdev->pkt_type & ACL_PTYPE_MASK;
219 break;
220 case SCO_LINK:
221 if (lmp_esco_capable(hdev))
222 conn->pkt_type = hdev->esco_type & SCO_ESCO_MASK;
223 else
224 conn->pkt_type = hdev->pkt_type & SCO_PTYPE_MASK;
225 break;
226 case ESCO_LINK:
227 conn->pkt_type = hdev->esco_type;
228 break;
229 }
230
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231 skb_queue_head_init(&conn->data_q);
Marcel Holtmann04837f62006-07-03 10:02:33 +0200232
Pavel Emelyanovb24b8a22008-01-23 21:20:07 -0800233 setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn);
234 setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235
236 atomic_set(&conn->refcnt, 0);
237
238 hci_dev_hold(hdev);
239
240 tasklet_disable(&hdev->tx_task);
241
242 hci_conn_hash_add(hdev, conn);
243 if (hdev->notify)
244 hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
245
Marcel Holtmannb219e3a2006-07-06 12:38:46 +0200246 hci_conn_add_sysfs(conn);
247
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248 tasklet_enable(&hdev->tx_task);
249
250 return conn;
251}
252
253int hci_conn_del(struct hci_conn *conn)
254{
255 struct hci_dev *hdev = conn->hdev;
256
257 BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
258
Marcel Holtmann04837f62006-07-03 10:02:33 +0200259 del_timer(&conn->idle_timer);
260
261 del_timer(&conn->disc_timer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262
Marcel Holtmann5b7f9902007-07-11 09:51:55 +0200263 if (conn->type == ACL_LINK) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264 struct hci_conn *sco = conn->link;
265 if (sco)
266 sco->link = NULL;
267
268 /* Unacked frames */
269 hdev->acl_cnt += conn->sent;
Marcel Holtmann5b7f9902007-07-11 09:51:55 +0200270 } else {
271 struct hci_conn *acl = conn->link;
272 if (acl) {
273 acl->link = NULL;
274 hci_conn_put(acl);
275 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276 }
277
278 tasklet_disable(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 hci_conn_hash_del(hdev, conn);
280 if (hdev->notify)
281 hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 tasklet_enable(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 skb_queue_purge(&conn->data_q);
Dave Young38b7da02007-12-29 19:17:47 -0800284 hci_conn_del_sysfs(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286 return 0;
287}
288
289struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
290{
291 int use_src = bacmp(src, BDADDR_ANY);
292 struct hci_dev *hdev = NULL;
293 struct list_head *p;
294
295 BT_DBG("%s -> %s", batostr(src), batostr(dst));
296
297 read_lock_bh(&hci_dev_list_lock);
298
299 list_for_each(p, &hci_dev_list) {
300 struct hci_dev *d = list_entry(p, struct hci_dev, list);
301
302 if (!test_bit(HCI_UP, &d->flags) || test_bit(HCI_RAW, &d->flags))
303 continue;
304
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900305 /* Simple routing:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306 * No source address - find interface with bdaddr != dst
307 * Source address - find interface with bdaddr == src
308 */
309
310 if (use_src) {
311 if (!bacmp(&d->bdaddr, src)) {
312 hdev = d; break;
313 }
314 } else {
315 if (bacmp(&d->bdaddr, dst)) {
316 hdev = d; break;
317 }
318 }
319 }
320
321 if (hdev)
322 hdev = hci_dev_hold(hdev);
323
324 read_unlock_bh(&hci_dev_list_lock);
325 return hdev;
326}
327EXPORT_SYMBOL(hci_get_route);
328
329/* Create SCO or ACL connection.
330 * Device _must_ be locked */
Marcel Holtmann5b7f9902007-07-11 09:51:55 +0200331struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332{
333 struct hci_conn *acl;
Marcel Holtmann5b7f9902007-07-11 09:51:55 +0200334 struct hci_conn *sco;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335
336 BT_DBG("%s dst %s", hdev->name, batostr(dst));
337
338 if (!(acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst))) {
339 if (!(acl = hci_conn_add(hdev, ACL_LINK, dst)))
340 return NULL;
341 }
342
343 hci_conn_hold(acl);
344
345 if (acl->state == BT_OPEN || acl->state == BT_CLOSED)
346 hci_acl_connect(acl);
347
Marcel Holtmann5b7f9902007-07-11 09:51:55 +0200348 if (type == ACL_LINK)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349 return acl;
Marcel Holtmann5b7f9902007-07-11 09:51:55 +0200350
351 if (!(sco = hci_conn_hash_lookup_ba(hdev, type, dst))) {
352 if (!(sco = hci_conn_add(hdev, type, dst))) {
353 hci_conn_put(acl);
354 return NULL;
355 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356 }
Marcel Holtmann5b7f9902007-07-11 09:51:55 +0200357
358 acl->link = sco;
359 sco->link = acl;
360
361 hci_conn_hold(sco);
362
363 if (acl->state == BT_CONNECTED &&
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200364 (sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
365 if (lmp_esco_capable(hdev))
366 hci_setup_sync(sco, acl->handle);
367 else
368 hci_add_sco(sco, acl->handle);
369 }
Marcel Holtmann5b7f9902007-07-11 09:51:55 +0200370
371 return sco;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372}
373EXPORT_SYMBOL(hci_connect);
374
375/* Authenticate remote device */
376int hci_conn_auth(struct hci_conn *conn)
377{
378 BT_DBG("conn %p", conn);
379
380 if (conn->link_mode & HCI_LM_AUTH)
381 return 1;
382
383 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
384 struct hci_cp_auth_requested cp;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -0700385 cp.handle = cpu_to_le16(conn->handle);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200386 hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387 }
388 return 0;
389}
390EXPORT_SYMBOL(hci_conn_auth);
391
392/* Enable encryption */
393int hci_conn_encrypt(struct hci_conn *conn)
394{
395 BT_DBG("conn %p", conn);
396
397 if (conn->link_mode & HCI_LM_ENCRYPT)
398 return 1;
399
400 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
401 return 0;
402
403 if (hci_conn_auth(conn)) {
404 struct hci_cp_set_conn_encrypt cp;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -0700405 cp.handle = cpu_to_le16(conn->handle);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900406 cp.encrypt = 1;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200407 hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408 }
409 return 0;
410}
411EXPORT_SYMBOL(hci_conn_encrypt);
412
413/* Change link key */
414int hci_conn_change_link_key(struct hci_conn *conn)
415{
416 BT_DBG("conn %p", conn);
417
418 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
419 struct hci_cp_change_conn_link_key cp;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -0700420 cp.handle = cpu_to_le16(conn->handle);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200421 hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 }
423 return 0;
424}
425EXPORT_SYMBOL(hci_conn_change_link_key);
426
427/* Switch role */
428int hci_conn_switch_role(struct hci_conn *conn, uint8_t role)
429{
430 BT_DBG("conn %p", conn);
431
432 if (!role && conn->link_mode & HCI_LM_MASTER)
433 return 1;
434
435 if (!test_and_set_bit(HCI_CONN_RSWITCH_PEND, &conn->pend)) {
436 struct hci_cp_switch_role cp;
437 bacpy(&cp.bdaddr, &conn->dst);
438 cp.role = role;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200439 hci_send_cmd(conn->hdev, HCI_OP_SWITCH_ROLE, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440 }
441 return 0;
442}
443EXPORT_SYMBOL(hci_conn_switch_role);
444
Marcel Holtmann04837f62006-07-03 10:02:33 +0200445/* Enter active mode */
446void hci_conn_enter_active_mode(struct hci_conn *conn)
447{
448 struct hci_dev *hdev = conn->hdev;
449
450 BT_DBG("conn %p mode %d", conn, conn->mode);
451
452 if (test_bit(HCI_RAW, &hdev->flags))
453 return;
454
455 if (conn->mode != HCI_CM_SNIFF || !conn->power_save)
456 goto timer;
457
458 if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
459 struct hci_cp_exit_sniff_mode cp;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -0700460 cp.handle = cpu_to_le16(conn->handle);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200461 hci_send_cmd(hdev, HCI_OP_EXIT_SNIFF_MODE, sizeof(cp), &cp);
Marcel Holtmann04837f62006-07-03 10:02:33 +0200462 }
463
464timer:
465 if (hdev->idle_timeout > 0)
466 mod_timer(&conn->idle_timer,
467 jiffies + msecs_to_jiffies(hdev->idle_timeout));
468}
469
470/* Enter sniff mode */
471void hci_conn_enter_sniff_mode(struct hci_conn *conn)
472{
473 struct hci_dev *hdev = conn->hdev;
474
475 BT_DBG("conn %p mode %d", conn, conn->mode);
476
477 if (test_bit(HCI_RAW, &hdev->flags))
478 return;
479
480 if (!lmp_sniff_capable(hdev) || !lmp_sniff_capable(conn))
481 return;
482
483 if (conn->mode != HCI_CM_ACTIVE || !(conn->link_policy & HCI_LP_SNIFF))
484 return;
485
486 if (lmp_sniffsubr_capable(hdev) && lmp_sniffsubr_capable(conn)) {
487 struct hci_cp_sniff_subrate cp;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -0700488 cp.handle = cpu_to_le16(conn->handle);
489 cp.max_latency = cpu_to_le16(0);
490 cp.min_remote_timeout = cpu_to_le16(0);
491 cp.min_local_timeout = cpu_to_le16(0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200492 hci_send_cmd(hdev, HCI_OP_SNIFF_SUBRATE, sizeof(cp), &cp);
Marcel Holtmann04837f62006-07-03 10:02:33 +0200493 }
494
495 if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
496 struct hci_cp_sniff_mode cp;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -0700497 cp.handle = cpu_to_le16(conn->handle);
498 cp.max_interval = cpu_to_le16(hdev->sniff_max_interval);
499 cp.min_interval = cpu_to_le16(hdev->sniff_min_interval);
500 cp.attempt = cpu_to_le16(4);
501 cp.timeout = cpu_to_le16(1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200502 hci_send_cmd(hdev, HCI_OP_SNIFF_MODE, sizeof(cp), &cp);
Marcel Holtmann04837f62006-07-03 10:02:33 +0200503 }
504}
505
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506/* Drop all connection on the device */
507void hci_conn_hash_flush(struct hci_dev *hdev)
508{
509 struct hci_conn_hash *h = &hdev->conn_hash;
510 struct list_head *p;
511
512 BT_DBG("hdev %s", hdev->name);
513
514 p = h->list.next;
515 while (p != &h->list) {
516 struct hci_conn *c;
517
518 c = list_entry(p, struct hci_conn, list);
519 p = p->next;
520
521 c->state = BT_CLOSED;
522
523 hci_proto_disconn_ind(c, 0x16);
524 hci_conn_del(c);
525 }
526}
527
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200528/* Check pending connect attempts */
529void hci_conn_check_pending(struct hci_dev *hdev)
530{
531 struct hci_conn *conn;
532
533 BT_DBG("hdev %s", hdev->name);
534
535 hci_dev_lock(hdev);
536
537 conn = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
538 if (conn)
539 hci_acl_connect(conn);
540
541 hci_dev_unlock(hdev);
542}
543
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544int hci_get_conn_list(void __user *arg)
545{
546 struct hci_conn_list_req req, *cl;
547 struct hci_conn_info *ci;
548 struct hci_dev *hdev;
549 struct list_head *p;
550 int n = 0, size, err;
551
552 if (copy_from_user(&req, arg, sizeof(req)))
553 return -EFAULT;
554
555 if (!req.conn_num || req.conn_num > (PAGE_SIZE * 2) / sizeof(*ci))
556 return -EINVAL;
557
558 size = sizeof(req) + req.conn_num * sizeof(*ci);
559
Jesper Juhl12fe2c52006-01-10 13:08:21 -0800560 if (!(cl = kmalloc(size, GFP_KERNEL)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561 return -ENOMEM;
562
563 if (!(hdev = hci_dev_get(req.dev_id))) {
564 kfree(cl);
565 return -ENODEV;
566 }
567
568 ci = cl->conn_info;
569
570 hci_dev_lock_bh(hdev);
571 list_for_each(p, &hdev->conn_hash.list) {
572 register struct hci_conn *c;
573 c = list_entry(p, struct hci_conn, list);
574
575 bacpy(&(ci + n)->bdaddr, &c->dst);
576 (ci + n)->handle = c->handle;
577 (ci + n)->type = c->type;
578 (ci + n)->out = c->out;
579 (ci + n)->state = c->state;
580 (ci + n)->link_mode = c->link_mode;
581 if (++n >= req.conn_num)
582 break;
583 }
584 hci_dev_unlock_bh(hdev);
585
586 cl->dev_id = hdev->id;
587 cl->conn_num = n;
588 size = sizeof(req) + n * sizeof(*ci);
589
590 hci_dev_put(hdev);
591
592 err = copy_to_user(arg, cl, size);
593 kfree(cl);
594
595 return err ? -EFAULT : 0;
596}
597
598int hci_get_conn_info(struct hci_dev *hdev, void __user *arg)
599{
600 struct hci_conn_info_req req;
601 struct hci_conn_info ci;
602 struct hci_conn *conn;
603 char __user *ptr = arg + sizeof(req);
604
605 if (copy_from_user(&req, arg, sizeof(req)))
606 return -EFAULT;
607
608 hci_dev_lock_bh(hdev);
609 conn = hci_conn_hash_lookup_ba(hdev, req.type, &req.bdaddr);
610 if (conn) {
611 bacpy(&ci.bdaddr, &conn->dst);
612 ci.handle = conn->handle;
613 ci.type = conn->type;
614 ci.out = conn->out;
615 ci.state = conn->state;
616 ci.link_mode = conn->link_mode;
617 }
618 hci_dev_unlock_bh(hdev);
619
620 if (!conn)
621 return -ENOENT;
622
623 return copy_to_user(ptr, &ci, sizeof(ci)) ? -EFAULT : 0;
624}