OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [net/] [bluetooth/] [hci_conn.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
   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
15
   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
18
   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
 
20
   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21
   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
22
   SOFTWARE IS DISCLAIMED.
23
*/
24
 
25
/* Bluetooth HCI connection handling. */
26
 
27
#include <linux/module.h>
28
 
29
#include <linux/types.h>
30
#include <linux/errno.h>
31
#include <linux/kernel.h>
32
#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
 
53
void hci_acl_connect(struct hci_conn *conn)
54
{
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;
62
        conn->out   = 1;
63
        conn->link_mode = HCI_LM_MASTER;
64
 
65
        conn->attempt++;
66
 
67
        memset(&cp, 0, sizeof(cp));
68
        bacpy(&cp.bdaddr, &conn->dst);
69
        cp.pscan_rep_mode = 0x02;
70
 
71
        if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst)) &&
72
                        inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) {
73
                cp.pscan_rep_mode = ie->data.pscan_rep_mode;
74
                cp.pscan_mode     = ie->data.pscan_mode;
75
                cp.clock_offset   = ie->data.clock_offset | cpu_to_le16(0x8000);
76
                memcpy(conn->dev_class, ie->data.dev_class, 3);
77
        }
78
 
79
        cp.pkt_type = cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK);
80
        if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER))
81
                cp.role_switch = 0x01;
82
        else
83
                cp.role_switch = 0x00;
84
 
85
        hci_send_cmd(hdev, HCI_OP_CREATE_CONN, sizeof(cp), &cp);
86
}
87
 
88
static void hci_acl_connect_cancel(struct hci_conn *conn)
89
{
90
        struct hci_cp_create_conn_cancel cp;
91
 
92
        BT_DBG("%p", conn);
93
 
94
        if (conn->hdev->hci_ver < 2)
95
                return;
96
 
97
        bacpy(&cp.bdaddr, &conn->dst);
98
        hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp);
99
}
100
 
101
void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
102
{
103
        struct hci_cp_disconnect cp;
104
 
105
        BT_DBG("%p", conn);
106
 
107
        conn->state = BT_DISCONN;
108
 
109
        cp.handle = cpu_to_le16(conn->handle);
110
        cp.reason = reason;
111
        hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp);
112
}
113
 
114
void hci_add_sco(struct hci_conn *conn, __u16 handle)
115
{
116
        struct hci_dev *hdev = conn->hdev;
117
        struct hci_cp_add_sco cp;
118
 
119
        BT_DBG("%p", conn);
120
 
121
        conn->state = BT_CONNECT;
122
        conn->out = 1;
123
 
124
        cp.handle   = cpu_to_le16(handle);
125
        cp.pkt_type = cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
126
 
127
        hci_send_cmd(hdev, HCI_OP_ADD_SCO, sizeof(cp), &cp);
128
}
129
 
130
void hci_setup_sync(struct hci_conn *conn, __u16 handle)
131
{
132
        struct hci_dev *hdev = conn->hdev;
133
        struct hci_cp_setup_sync_conn cp;
134
 
135
        BT_DBG("%p", conn);
136
 
137
        conn->state = BT_CONNECT;
138
        conn->out = 1;
139
 
140
        cp.handle   = cpu_to_le16(handle);
141
        cp.pkt_type = cpu_to_le16(hdev->esco_type);
142
 
143
        cp.tx_bandwidth   = cpu_to_le32(0x00001f40);
144
        cp.rx_bandwidth   = cpu_to_le32(0x00001f40);
145
        cp.max_latency    = cpu_to_le16(0xffff);
146
        cp.voice_setting  = cpu_to_le16(hdev->voice_setting);
147
        cp.retrans_effort = 0xff;
148
 
149
        hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
150
}
151
 
152
static void hci_conn_timeout(unsigned long arg)
153
{
154
        struct hci_conn *conn = (void *) arg;
155
        struct hci_dev *hdev = conn->hdev;
156
 
157
        BT_DBG("conn %p state %d", conn, conn->state);
158
 
159
        if (atomic_read(&conn->refcnt))
160
                return;
161
 
162
        hci_dev_lock(hdev);
163
 
164
        switch (conn->state) {
165
        case BT_CONNECT:
166
                if (conn->type == ACL_LINK)
167
                        hci_acl_connect_cancel(conn);
168
                else
169
                        hci_acl_disconn(conn, 0x13);
170
                break;
171
        case BT_CONNECTED:
172
                hci_acl_disconn(conn, 0x13);
173
                break;
174
        default:
175
                conn->state = BT_CLOSED;
176
                break;
177
        }
178
 
179
        hci_dev_unlock(hdev);
180
}
181
 
182
static void hci_conn_idle(unsigned long arg)
183
{
184
        struct hci_conn *conn = (void *) arg;
185
 
186
        BT_DBG("conn %p mode %d", conn, conn->mode);
187
 
188
        hci_conn_enter_sniff_mode(conn);
189
}
190
 
191
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
192
{
193
        struct hci_conn *conn;
194
 
195
        BT_DBG("%s dst %s", hdev->name, batostr(dst));
196
 
197
        conn = kzalloc(sizeof(struct hci_conn), GFP_ATOMIC);
198
        if (!conn)
199
                return NULL;
200
 
201
        bacpy(&conn->dst, dst);
202
        conn->hdev   = hdev;
203
        conn->type   = type;
204
        conn->mode   = HCI_CM_ACTIVE;
205
        conn->state  = BT_OPEN;
206
 
207
        conn->power_save = 1;
208
 
209
        skb_queue_head_init(&conn->data_q);
210
 
211
        init_timer(&conn->disc_timer);
212
        conn->disc_timer.function = hci_conn_timeout;
213
        conn->disc_timer.data = (unsigned long) conn;
214
 
215
        init_timer(&conn->idle_timer);
216
        conn->idle_timer.function = hci_conn_idle;
217
        conn->idle_timer.data = (unsigned long) conn;
218
 
219
        atomic_set(&conn->refcnt, 0);
220
 
221
        hci_dev_hold(hdev);
222
 
223
        tasklet_disable(&hdev->tx_task);
224
 
225
        hci_conn_hash_add(hdev, conn);
226
        if (hdev->notify)
227
                hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
228
 
229
        hci_conn_add_sysfs(conn);
230
 
231
        tasklet_enable(&hdev->tx_task);
232
 
233
        return conn;
234
}
235
 
236
int hci_conn_del(struct hci_conn *conn)
237
{
238
        struct hci_dev *hdev = conn->hdev;
239
 
240
        BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
241
 
242
        del_timer(&conn->idle_timer);
243
 
244
        del_timer(&conn->disc_timer);
245
 
246
        if (conn->type == ACL_LINK) {
247
                struct hci_conn *sco = conn->link;
248
                if (sco)
249
                        sco->link = NULL;
250
 
251
                /* Unacked frames */
252
                hdev->acl_cnt += conn->sent;
253
        } else {
254
                struct hci_conn *acl = conn->link;
255
                if (acl) {
256
                        acl->link = NULL;
257
                        hci_conn_put(acl);
258
                }
259
        }
260
 
261
        tasklet_disable(&hdev->tx_task);
262
        hci_conn_hash_del(hdev, conn);
263
        if (hdev->notify)
264
                hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
265
        tasklet_enable(&hdev->tx_task);
266
        skb_queue_purge(&conn->data_q);
267
        hci_conn_del_sysfs(conn);
268
        hci_dev_put(hdev);
269
 
270
        return 0;
271
}
272
 
273
struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
274
{
275
        int use_src = bacmp(src, BDADDR_ANY);
276
        struct hci_dev *hdev = NULL;
277
        struct list_head *p;
278
 
279
        BT_DBG("%s -> %s", batostr(src), batostr(dst));
280
 
281
        read_lock_bh(&hci_dev_list_lock);
282
 
283
        list_for_each(p, &hci_dev_list) {
284
                struct hci_dev *d = list_entry(p, struct hci_dev, list);
285
 
286
                if (!test_bit(HCI_UP, &d->flags) || test_bit(HCI_RAW, &d->flags))
287
                        continue;
288
 
289
                /* Simple routing:
290
                 *   No source address - find interface with bdaddr != dst
291
                 *   Source address    - find interface with bdaddr == src
292
                 */
293
 
294
                if (use_src) {
295
                        if (!bacmp(&d->bdaddr, src)) {
296
                                hdev = d; break;
297
                        }
298
                } else {
299
                        if (bacmp(&d->bdaddr, dst)) {
300
                                hdev = d; break;
301
                        }
302
                }
303
        }
304
 
305
        if (hdev)
306
                hdev = hci_dev_hold(hdev);
307
 
308
        read_unlock_bh(&hci_dev_list_lock);
309
        return hdev;
310
}
311
EXPORT_SYMBOL(hci_get_route);
312
 
313
/* Create SCO or ACL connection.
314
 * Device _must_ be locked */
315
struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
316
{
317
        struct hci_conn *acl;
318
        struct hci_conn *sco;
319
 
320
        BT_DBG("%s dst %s", hdev->name, batostr(dst));
321
 
322
        if (!(acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst))) {
323
                if (!(acl = hci_conn_add(hdev, ACL_LINK, dst)))
324
                        return NULL;
325
        }
326
 
327
        hci_conn_hold(acl);
328
 
329
        if (acl->state == BT_OPEN || acl->state == BT_CLOSED)
330
                hci_acl_connect(acl);
331
 
332
        if (type == ACL_LINK)
333
                return acl;
334
 
335
        if (!(sco = hci_conn_hash_lookup_ba(hdev, type, dst))) {
336
                if (!(sco = hci_conn_add(hdev, type, dst))) {
337
                        hci_conn_put(acl);
338
                        return NULL;
339
                }
340
        }
341
 
342
        acl->link = sco;
343
        sco->link = acl;
344
 
345
        hci_conn_hold(sco);
346
 
347
        if (acl->state == BT_CONNECTED &&
348
                        (sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
349
                if (lmp_esco_capable(hdev))
350
                        hci_setup_sync(sco, acl->handle);
351
                else
352
                        hci_add_sco(sco, acl->handle);
353
        }
354
 
355
        return sco;
356
}
357
EXPORT_SYMBOL(hci_connect);
358
 
359
/* Authenticate remote device */
360
int hci_conn_auth(struct hci_conn *conn)
361
{
362
        BT_DBG("conn %p", conn);
363
 
364
        if (conn->link_mode & HCI_LM_AUTH)
365
                return 1;
366
 
367
        if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
368
                struct hci_cp_auth_requested cp;
369
                cp.handle = cpu_to_le16(conn->handle);
370
                hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
371
        }
372
        return 0;
373
}
374
EXPORT_SYMBOL(hci_conn_auth);
375
 
376
/* Enable encryption */
377
int hci_conn_encrypt(struct hci_conn *conn)
378
{
379
        BT_DBG("conn %p", conn);
380
 
381
        if (conn->link_mode & HCI_LM_ENCRYPT)
382
                return 1;
383
 
384
        if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
385
                return 0;
386
 
387
        if (hci_conn_auth(conn)) {
388
                struct hci_cp_set_conn_encrypt cp;
389
                cp.handle  = cpu_to_le16(conn->handle);
390
                cp.encrypt = 1;
391
                hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp);
392
        }
393
        return 0;
394
}
395
EXPORT_SYMBOL(hci_conn_encrypt);
396
 
397
/* Change link key */
398
int hci_conn_change_link_key(struct hci_conn *conn)
399
{
400
        BT_DBG("conn %p", conn);
401
 
402
        if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
403
                struct hci_cp_change_conn_link_key cp;
404
                cp.handle = cpu_to_le16(conn->handle);
405
                hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, sizeof(cp), &cp);
406
        }
407
        return 0;
408
}
409
EXPORT_SYMBOL(hci_conn_change_link_key);
410
 
411
/* Switch role */
412
int hci_conn_switch_role(struct hci_conn *conn, uint8_t role)
413
{
414
        BT_DBG("conn %p", conn);
415
 
416
        if (!role && conn->link_mode & HCI_LM_MASTER)
417
                return 1;
418
 
419
        if (!test_and_set_bit(HCI_CONN_RSWITCH_PEND, &conn->pend)) {
420
                struct hci_cp_switch_role cp;
421
                bacpy(&cp.bdaddr, &conn->dst);
422
                cp.role = role;
423
                hci_send_cmd(conn->hdev, HCI_OP_SWITCH_ROLE, sizeof(cp), &cp);
424
        }
425
        return 0;
426
}
427
EXPORT_SYMBOL(hci_conn_switch_role);
428
 
429
/* Enter active mode */
430
void hci_conn_enter_active_mode(struct hci_conn *conn)
431
{
432
        struct hci_dev *hdev = conn->hdev;
433
 
434
        BT_DBG("conn %p mode %d", conn, conn->mode);
435
 
436
        if (test_bit(HCI_RAW, &hdev->flags))
437
                return;
438
 
439
        if (conn->mode != HCI_CM_SNIFF || !conn->power_save)
440
                goto timer;
441
 
442
        if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
443
                struct hci_cp_exit_sniff_mode cp;
444
                cp.handle = cpu_to_le16(conn->handle);
445
                hci_send_cmd(hdev, HCI_OP_EXIT_SNIFF_MODE, sizeof(cp), &cp);
446
        }
447
 
448
timer:
449
        if (hdev->idle_timeout > 0)
450
                mod_timer(&conn->idle_timer,
451
                        jiffies + msecs_to_jiffies(hdev->idle_timeout));
452
}
453
 
454
/* Enter sniff mode */
455
void hci_conn_enter_sniff_mode(struct hci_conn *conn)
456
{
457
        struct hci_dev *hdev = conn->hdev;
458
 
459
        BT_DBG("conn %p mode %d", conn, conn->mode);
460
 
461
        if (test_bit(HCI_RAW, &hdev->flags))
462
                return;
463
 
464
        if (!lmp_sniff_capable(hdev) || !lmp_sniff_capable(conn))
465
                return;
466
 
467
        if (conn->mode != HCI_CM_ACTIVE || !(conn->link_policy & HCI_LP_SNIFF))
468
                return;
469
 
470
        if (lmp_sniffsubr_capable(hdev) && lmp_sniffsubr_capable(conn)) {
471
                struct hci_cp_sniff_subrate cp;
472
                cp.handle             = cpu_to_le16(conn->handle);
473
                cp.max_latency        = cpu_to_le16(0);
474
                cp.min_remote_timeout = cpu_to_le16(0);
475
                cp.min_local_timeout  = cpu_to_le16(0);
476
                hci_send_cmd(hdev, HCI_OP_SNIFF_SUBRATE, sizeof(cp), &cp);
477
        }
478
 
479
        if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
480
                struct hci_cp_sniff_mode cp;
481
                cp.handle       = cpu_to_le16(conn->handle);
482
                cp.max_interval = cpu_to_le16(hdev->sniff_max_interval);
483
                cp.min_interval = cpu_to_le16(hdev->sniff_min_interval);
484
                cp.attempt      = cpu_to_le16(4);
485
                cp.timeout      = cpu_to_le16(1);
486
                hci_send_cmd(hdev, HCI_OP_SNIFF_MODE, sizeof(cp), &cp);
487
        }
488
}
489
 
490
/* Drop all connection on the device */
491
void hci_conn_hash_flush(struct hci_dev *hdev)
492
{
493
        struct hci_conn_hash *h = &hdev->conn_hash;
494
        struct list_head *p;
495
 
496
        BT_DBG("hdev %s", hdev->name);
497
 
498
        p = h->list.next;
499
        while (p != &h->list) {
500
                struct hci_conn *c;
501
 
502
                c = list_entry(p, struct hci_conn, list);
503
                p = p->next;
504
 
505
                c->state = BT_CLOSED;
506
 
507
                hci_proto_disconn_ind(c, 0x16);
508
                hci_conn_del(c);
509
        }
510
}
511
 
512
/* Check pending connect attempts */
513
void hci_conn_check_pending(struct hci_dev *hdev)
514
{
515
        struct hci_conn *conn;
516
 
517
        BT_DBG("hdev %s", hdev->name);
518
 
519
        hci_dev_lock(hdev);
520
 
521
        conn = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
522
        if (conn)
523
                hci_acl_connect(conn);
524
 
525
        hci_dev_unlock(hdev);
526
}
527
 
528
int hci_get_conn_list(void __user *arg)
529
{
530
        struct hci_conn_list_req req, *cl;
531
        struct hci_conn_info *ci;
532
        struct hci_dev *hdev;
533
        struct list_head *p;
534
        int n = 0, size, err;
535
 
536
        if (copy_from_user(&req, arg, sizeof(req)))
537
                return -EFAULT;
538
 
539
        if (!req.conn_num || req.conn_num > (PAGE_SIZE * 2) / sizeof(*ci))
540
                return -EINVAL;
541
 
542
        size = sizeof(req) + req.conn_num * sizeof(*ci);
543
 
544
        if (!(cl = kmalloc(size, GFP_KERNEL)))
545
                return -ENOMEM;
546
 
547
        if (!(hdev = hci_dev_get(req.dev_id))) {
548
                kfree(cl);
549
                return -ENODEV;
550
        }
551
 
552
        ci = cl->conn_info;
553
 
554
        hci_dev_lock_bh(hdev);
555
        list_for_each(p, &hdev->conn_hash.list) {
556
                register struct hci_conn *c;
557
                c = list_entry(p, struct hci_conn, list);
558
 
559
                bacpy(&(ci + n)->bdaddr, &c->dst);
560
                (ci + n)->handle = c->handle;
561
                (ci + n)->type  = c->type;
562
                (ci + n)->out   = c->out;
563
                (ci + n)->state = c->state;
564
                (ci + n)->link_mode = c->link_mode;
565
                if (++n >= req.conn_num)
566
                        break;
567
        }
568
        hci_dev_unlock_bh(hdev);
569
 
570
        cl->dev_id = hdev->id;
571
        cl->conn_num = n;
572
        size = sizeof(req) + n * sizeof(*ci);
573
 
574
        hci_dev_put(hdev);
575
 
576
        err = copy_to_user(arg, cl, size);
577
        kfree(cl);
578
 
579
        return err ? -EFAULT : 0;
580
}
581
 
582
int hci_get_conn_info(struct hci_dev *hdev, void __user *arg)
583
{
584
        struct hci_conn_info_req req;
585
        struct hci_conn_info ci;
586
        struct hci_conn *conn;
587
        char __user *ptr = arg + sizeof(req);
588
 
589
        if (copy_from_user(&req, arg, sizeof(req)))
590
                return -EFAULT;
591
 
592
        hci_dev_lock_bh(hdev);
593
        conn = hci_conn_hash_lookup_ba(hdev, req.type, &req.bdaddr);
594
        if (conn) {
595
                bacpy(&ci.bdaddr, &conn->dst);
596
                ci.handle = conn->handle;
597
                ci.type  = conn->type;
598
                ci.out   = conn->out;
599
                ci.state = conn->state;
600
                ci.link_mode = conn->link_mode;
601
        }
602
        hci_dev_unlock_bh(hdev);
603
 
604
        if (!conn)
605
                return -ENOENT;
606
 
607
        return copy_to_user(ptr, &ci, sizeof(ci)) ? -EFAULT : 0;
608
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.