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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [bluetooth/] [sco.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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
/*
26
 * BlueZ SCO sockets.
27
 *
28
 * $Id: sco.c,v 1.1.1.1 2004-04-15 01:17:01 phoenix Exp $
29
 */
30
#define VERSION "0.3"
31
 
32
#include <linux/config.h>
33
#include <linux/module.h>
34
 
35
#include <linux/types.h>
36
#include <linux/errno.h>
37
#include <linux/kernel.h>
38
#include <linux/major.h>
39
#include <linux/sched.h>
40
#include <linux/slab.h>
41
#include <linux/poll.h>
42
#include <linux/fcntl.h>
43
#include <linux/init.h>
44
#include <linux/skbuff.h>
45
#include <linux/interrupt.h>
46
#include <linux/socket.h>
47
#include <linux/skbuff.h>
48
#include <linux/proc_fs.h>
49
#include <linux/list.h>
50
#include <net/sock.h>
51
 
52
#include <asm/system.h>
53
#include <asm/uaccess.h>
54
 
55
#include <net/bluetooth/bluetooth.h>
56
#include <net/bluetooth/hci_core.h>
57
#include <net/bluetooth/sco.h>
58
 
59
#ifndef SCO_DEBUG
60
#undef  BT_DBG
61
#define BT_DBG( A... )
62
#endif
63
 
64
static struct proto_ops sco_sock_ops;
65
 
66
static struct bluez_sock_list sco_sk_list = {
67
        lock: RW_LOCK_UNLOCKED
68
};
69
 
70
static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent);
71
static void sco_chan_del(struct sock *sk, int err);
72
static inline struct sock * sco_chan_get(struct sco_conn *conn);
73
 
74
static int  sco_conn_del(struct hci_conn *conn, int err);
75
 
76
static void sco_sock_close(struct sock *sk);
77
static void sco_sock_kill(struct sock *sk);
78
 
79
/* ----- SCO timers ------ */
80
static void sco_sock_timeout(unsigned long arg)
81
{
82
        struct sock *sk = (struct sock *) arg;
83
 
84
        BT_DBG("sock %p state %d", sk, sk->state);
85
 
86
        bh_lock_sock(sk);
87
        sk->err = ETIMEDOUT;
88
        sk->state_change(sk);
89
        bh_unlock_sock(sk);
90
 
91
        sco_sock_kill(sk);
92
        sock_put(sk);
93
}
94
 
95
static void sco_sock_set_timer(struct sock *sk, long timeout)
96
{
97
        BT_DBG("sock %p state %d timeout %ld", sk, sk->state, timeout);
98
 
99
        if (!mod_timer(&sk->timer, jiffies + timeout))
100
                sock_hold(sk);
101
}
102
 
103
static void sco_sock_clear_timer(struct sock *sk)
104
{
105
        BT_DBG("sock %p state %d", sk, sk->state);
106
 
107
        if (timer_pending(&sk->timer) && del_timer(&sk->timer))
108
                __sock_put(sk);
109
}
110
 
111
static void sco_sock_init_timer(struct sock *sk)
112
{
113
        init_timer(&sk->timer);
114
        sk->timer.function = sco_sock_timeout;
115
        sk->timer.data = (unsigned long)sk;
116
}
117
 
118
/* -------- SCO connections --------- */
119
static struct sco_conn *sco_conn_add(struct hci_conn *hcon, __u8 status)
120
{
121
        struct hci_dev *hdev = hcon->hdev;
122
        struct sco_conn *conn;
123
 
124
        if ((conn = hcon->sco_data))
125
                return conn;
126
 
127
        if (status)
128
                return conn;
129
 
130
        if (!(conn = kmalloc(sizeof(struct sco_conn), GFP_ATOMIC)))
131
                return NULL;
132
        memset(conn, 0, sizeof(struct sco_conn));
133
 
134
        spin_lock_init(&conn->lock);
135
 
136
        hcon->sco_data = conn;
137
        conn->hcon = hcon;
138
 
139
        conn->src = &hdev->bdaddr;
140
        conn->dst = &hcon->dst;
141
 
142
        if (hdev->sco_mtu > 0)
143
                conn->mtu = hdev->sco_mtu;
144
        else
145
                conn->mtu = 60;
146
 
147
        BT_DBG("hcon %p conn %p", hcon, conn);
148
 
149
        MOD_INC_USE_COUNT;
150
        return conn;
151
}
152
 
153
static int sco_conn_del(struct hci_conn *hcon, int err)
154
{
155
        struct sco_conn *conn;
156
        struct sock *sk;
157
 
158
        if (!(conn = hcon->sco_data))
159
                return 0;
160
 
161
        BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
162
 
163
        /* Kill socket */
164
        if ((sk = sco_chan_get(conn))) {
165
                bh_lock_sock(sk);
166
                sco_sock_clear_timer(sk);
167
                sco_chan_del(sk, err);
168
                bh_unlock_sock(sk);
169
                sco_sock_kill(sk);
170
        }
171
 
172
        hcon->sco_data = NULL;
173
        kfree(conn);
174
 
175
        MOD_DEC_USE_COUNT;
176
        return 0;
177
}
178
 
179
int sco_connect(struct sock *sk)
180
{
181
        bdaddr_t *src = &bluez_pi(sk)->src;
182
        bdaddr_t *dst = &bluez_pi(sk)->dst;
183
        struct sco_conn *conn;
184
        struct hci_conn *hcon;
185
        struct hci_dev  *hdev;
186
        int err = 0;
187
 
188
        BT_DBG("%s -> %s", batostr(src), batostr(dst));
189
 
190
        if (!(hdev = hci_get_route(dst, src)))
191
                return -EHOSTUNREACH;
192
 
193
        hci_dev_lock_bh(hdev);
194
 
195
        err = -ENOMEM;
196
 
197
        hcon = hci_connect(hdev, SCO_LINK, dst);
198
        if (!hcon)
199
                goto done;
200
 
201
        conn = sco_conn_add(hcon, 0);
202
        if (!conn) {
203
                hci_conn_put(hcon);
204
                goto done;
205
        }
206
 
207
        /* Update source addr of the socket */
208
        bacpy(src, conn->src);
209
 
210
        err = sco_chan_add(conn, sk, NULL);
211
        if (err)
212
                goto done;
213
 
214
        if (hcon->state == BT_CONNECTED) {
215
                sco_sock_clear_timer(sk);
216
                sk->state = BT_CONNECTED;
217
        } else {
218
                sk->state = BT_CONNECT;
219
                sco_sock_set_timer(sk, sk->sndtimeo);
220
        }
221
done:
222
        hci_dev_unlock_bh(hdev);
223
        hci_dev_put(hdev);
224
        return err;
225
}
226
 
227
static inline int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
228
{
229
        struct sco_conn *conn = sco_pi(sk)->conn;
230
        struct sk_buff *skb;
231
        int err, count;
232
 
233
        /* Check outgoing MTU */
234
        if (len > conn->mtu)
235
                return -EINVAL;
236
 
237
        BT_DBG("sk %p len %d", sk, len);
238
 
239
        count = MIN(conn->mtu, len);
240
        if (!(skb = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err)))
241
                return err;
242
 
243
        if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
244
                err = -EFAULT;
245
                goto fail;
246
        }
247
 
248
        if ((err = hci_send_sco(conn->hcon, skb)) < 0)
249
                goto fail;
250
 
251
        return count;
252
 
253
fail:
254
        kfree_skb(skb);
255
        return err;
256
}
257
 
258
static inline void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
259
{
260
        struct sock *sk = sco_chan_get(conn);
261
 
262
        if (!sk)
263
                goto drop;
264
 
265
        BT_DBG("sk %p len %d", sk, skb->len);
266
 
267
        if (sk->state != BT_CONNECTED)
268
                goto drop;
269
 
270
        if (!sock_queue_rcv_skb(sk, skb))
271
                return;
272
 
273
drop:
274
        kfree_skb(skb);
275
        return;
276
}
277
 
278
/* -------- Socket interface ---------- */
279
static struct sock *__sco_get_sock_by_addr(bdaddr_t *ba)
280
{
281
        struct sock *sk;
282
 
283
        for (sk = sco_sk_list.head; sk; sk = sk->next) {
284
                if (!bacmp(&bluez_pi(sk)->src, ba))
285
                        break;
286
        }
287
 
288
        return sk;
289
}
290
 
291
/* Find socket listening on source bdaddr.
292
 * Returns closest match.
293
 */
294
static struct sock *sco_get_sock_listen(bdaddr_t *src)
295
{
296
        struct sock *sk, *sk1 = NULL;
297
 
298
        read_lock(&sco_sk_list.lock);
299
 
300
        for (sk = sco_sk_list.head; sk; sk = sk->next) {
301
                if (sk->state != BT_LISTEN)
302
                        continue;
303
 
304
                /* Exact match. */
305
                if (!bacmp(&bluez_pi(sk)->src, src))
306
                        break;
307
 
308
                /* Closest match */
309
                if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
310
                        sk1 = sk;
311
        }
312
 
313
        read_unlock(&sco_sk_list.lock);
314
 
315
        return sk ? sk : sk1;
316
}
317
 
318
static void sco_sock_destruct(struct sock *sk)
319
{
320
        BT_DBG("sk %p", sk);
321
 
322
        skb_queue_purge(&sk->receive_queue);
323
        skb_queue_purge(&sk->write_queue);
324
 
325
        MOD_DEC_USE_COUNT;
326
}
327
 
328
static void sco_sock_cleanup_listen(struct sock *parent)
329
{
330
        struct sock *sk;
331
 
332
        BT_DBG("parent %p", parent);
333
 
334
        /* Close not yet accepted channels */
335
        while ((sk = bluez_accept_dequeue(parent, NULL))) {
336
                sco_sock_close(sk);
337
                sco_sock_kill(sk);
338
        }
339
 
340
        parent->state  = BT_CLOSED;
341
        parent->zapped = 1;
342
}
343
 
344
/* Kill socket (only if zapped and orphan)
345
 * Must be called on unlocked socket.
346
 */
347
static void sco_sock_kill(struct sock *sk)
348
{
349
        if (!sk->zapped || sk->socket)
350
                return;
351
 
352
        BT_DBG("sk %p state %d", sk, sk->state);
353
 
354
        /* Kill poor orphan */
355
        bluez_sock_unlink(&sco_sk_list, sk);
356
        sk->dead = 1;
357
        sock_put(sk);
358
}
359
 
360
/* Close socket.
361
 * Must be called on unlocked socket.
362
 */
363
static void sco_sock_close(struct sock *sk)
364
{
365
        struct sco_conn *conn;
366
 
367
        sco_sock_clear_timer(sk);
368
 
369
        lock_sock(sk);
370
 
371
        conn = sco_pi(sk)->conn;
372
 
373
        BT_DBG("sk %p state %d conn %p socket %p", sk, sk->state, conn, sk->socket);
374
 
375
        switch (sk->state) {
376
        case BT_LISTEN:
377
                sco_sock_cleanup_listen(sk);
378
                break;
379
 
380
        case BT_CONNECTED:
381
        case BT_CONFIG:
382
        case BT_CONNECT:
383
        case BT_DISCONN:
384
                sco_chan_del(sk, ECONNRESET);
385
                break;
386
 
387
        default:
388
                sk->zapped = 1;
389
                break;
390
        };
391
 
392
        release_sock(sk);
393
}
394
 
395
static void sco_sock_init(struct sock *sk, struct sock *parent)
396
{
397
        BT_DBG("sk %p", sk);
398
 
399
        if (parent)
400
                sk->type = parent->type;
401
}
402
 
403
static struct sock *sco_sock_alloc(struct socket *sock, int proto, int prio)
404
{
405
        struct sock *sk;
406
 
407
        if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
408
                return NULL;
409
 
410
        bluez_sock_init(sock, sk);
411
 
412
        sk->zapped   = 0;
413
 
414
        sk->destruct = sco_sock_destruct;
415
        sk->sndtimeo = SCO_CONN_TIMEOUT;
416
 
417
        sk->protocol = proto;
418
        sk->state    = BT_OPEN;
419
 
420
        sco_sock_init_timer(sk);
421
 
422
        bluez_sock_link(&sco_sk_list, sk);
423
 
424
        MOD_INC_USE_COUNT;
425
        return sk;
426
}
427
 
428
static int sco_sock_create(struct socket *sock, int protocol)
429
{
430
        struct sock *sk;
431
 
432
        BT_DBG("sock %p", sock);
433
 
434
        sock->state = SS_UNCONNECTED;
435
 
436
        if (sock->type != SOCK_SEQPACKET)
437
                return -ESOCKTNOSUPPORT;
438
 
439
        sock->ops = &sco_sock_ops;
440
 
441
        if (!(sk = sco_sock_alloc(sock, protocol, GFP_KERNEL)))
442
                return -ENOMEM;
443
 
444
        sco_sock_init(sk, NULL);
445
        return 0;
446
}
447
 
448
static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
449
{
450
        struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
451
        struct sock *sk = sock->sk;
452
        bdaddr_t *src = &sa->sco_bdaddr;
453
        int err = 0;
454
 
455
        BT_DBG("sk %p %s", sk, batostr(&sa->sco_bdaddr));
456
 
457
        if (!addr || addr->sa_family != AF_BLUETOOTH)
458
                return -EINVAL;
459
 
460
        lock_sock(sk);
461
 
462
        if (sk->state != BT_OPEN) {
463
                err = -EBADFD;
464
                goto done;
465
        }
466
 
467
        write_lock_bh(&sco_sk_list.lock);
468
 
469
        if (bacmp(src, BDADDR_ANY) && __sco_get_sock_by_addr(src)) {
470
                err = -EADDRINUSE;
471
        } else {
472
                /* Save source address */
473
                bacpy(&bluez_pi(sk)->src, &sa->sco_bdaddr);
474
                sk->state = BT_BOUND;
475
        }
476
 
477
        write_unlock_bh(&sco_sk_list.lock);
478
 
479
done:
480
        release_sock(sk);
481
 
482
        return err;
483
}
484
 
485
static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
486
{
487
        struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
488
        struct sock *sk = sock->sk;
489
        int err = 0;
490
 
491
 
492
        BT_DBG("sk %p", sk);
493
 
494
        if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_sco))
495
                return -EINVAL;
496
 
497
        if (sk->state != BT_OPEN && sk->state != BT_BOUND)
498
                return -EBADFD;
499
 
500
        if (sk->type != SOCK_SEQPACKET)
501
                return -EINVAL;
502
 
503
        lock_sock(sk);
504
 
505
        /* Set destination address and psm */
506
        bacpy(&bluez_pi(sk)->dst, &sa->sco_bdaddr);
507
 
508
        if ((err = sco_connect(sk)))
509
                goto done;
510
 
511
        err = bluez_sock_wait_state(sk, BT_CONNECTED,
512
                        sock_sndtimeo(sk, flags & O_NONBLOCK));
513
 
514
done:
515
        release_sock(sk);
516
        return err;
517
}
518
 
519
int sco_sock_listen(struct socket *sock, int backlog)
520
{
521
        struct sock *sk = sock->sk;
522
        int err = 0;
523
 
524
        BT_DBG("sk %p backlog %d", sk, backlog);
525
 
526
        lock_sock(sk);
527
 
528
        if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
529
                err = -EBADFD;
530
                goto done;
531
        }
532
 
533
        sk->max_ack_backlog = backlog;
534
        sk->ack_backlog = 0;
535
        sk->state = BT_LISTEN;
536
 
537
done:
538
        release_sock(sk);
539
        return err;
540
}
541
 
542
int sco_sock_accept(struct socket *sock, struct socket *newsock, int flags)
543
{
544
        DECLARE_WAITQUEUE(wait, current);
545
        struct sock *sk = sock->sk, *ch;
546
        long timeo;
547
        int err = 0;
548
 
549
        lock_sock(sk);
550
 
551
        if (sk->state != BT_LISTEN) {
552
                err = -EBADFD;
553
                goto done;
554
        }
555
 
556
        timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
557
 
558
        BT_DBG("sk %p timeo %ld", sk, timeo);
559
 
560
        /* Wait for an incoming connection. (wake-one). */
561
        add_wait_queue_exclusive(sk->sleep, &wait);
562
        while (!(ch = bluez_accept_dequeue(sk, newsock))) {
563
                set_current_state(TASK_INTERRUPTIBLE);
564
                if (!timeo) {
565
                        err = -EAGAIN;
566
                        break;
567
                }
568
 
569
                release_sock(sk);
570
                timeo = schedule_timeout(timeo);
571
                lock_sock(sk);
572
 
573
                if (sk->state != BT_LISTEN) {
574
                        err = -EBADFD;
575
                        break;
576
                }
577
 
578
                if (signal_pending(current)) {
579
                        err = sock_intr_errno(timeo);
580
                        break;
581
                }
582
        }
583
        set_current_state(TASK_RUNNING);
584
        remove_wait_queue(sk->sleep, &wait);
585
 
586
        if (err)
587
                goto done;
588
 
589
        newsock->state = SS_CONNECTED;
590
 
591
        BT_DBG("new socket %p", ch);
592
 
593
done:
594
        release_sock(sk);
595
        return err;
596
}
597
 
598
static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
599
{
600
        struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
601
        struct sock *sk = sock->sk;
602
 
603
        BT_DBG("sock %p, sk %p", sock, sk);
604
 
605
        addr->sa_family = AF_BLUETOOTH;
606
        *len = sizeof(struct sockaddr_sco);
607
 
608
        if (peer)
609
                bacpy(&sa->sco_bdaddr, &bluez_pi(sk)->dst);
610
        else
611
                bacpy(&sa->sco_bdaddr, &bluez_pi(sk)->src);
612
 
613
        return 0;
614
}
615
 
616
static int sco_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
617
{
618
        struct sock *sk = sock->sk;
619
        int err = 0;
620
 
621
        BT_DBG("sock %p, sk %p", sock, sk);
622
 
623
        if (sk->err)
624
                return sock_error(sk);
625
 
626
        if (msg->msg_flags & MSG_OOB)
627
                return -EOPNOTSUPP;
628
 
629
        lock_sock(sk);
630
 
631
        if (sk->state == BT_CONNECTED)
632
                err = sco_send_frame(sk, msg, len);
633
        else
634
                err = -ENOTCONN;
635
 
636
        release_sock(sk);
637
        return err;
638
}
639
 
640
int sco_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
641
{
642
        struct sock *sk = sock->sk;
643
        int err = 0;
644
 
645
        BT_DBG("sk %p", sk);
646
 
647
        lock_sock(sk);
648
 
649
        switch (optname) {
650
        default:
651
                err = -ENOPROTOOPT;
652
                break;
653
        };
654
 
655
        release_sock(sk);
656
        return err;
657
}
658
 
659
int sco_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
660
{
661
        struct sock *sk = sock->sk;
662
        struct sco_options opts;
663
        struct sco_conninfo cinfo;
664
        int len, err = 0;
665
 
666
        BT_DBG("sk %p", sk);
667
 
668
        if (get_user(len, optlen))
669
                return -EFAULT;
670
 
671
        lock_sock(sk);
672
 
673
        switch (optname) {
674
        case SCO_OPTIONS:
675
                if (sk->state != BT_CONNECTED) {
676
                        err = -ENOTCONN;
677
                        break;
678
                }
679
 
680
                opts.mtu = sco_pi(sk)->conn->mtu;
681
 
682
                BT_DBG("mtu %d", opts.mtu);
683
 
684
                len = MIN(len, sizeof(opts));
685
                if (copy_to_user(optval, (char *)&opts, len))
686
                        err = -EFAULT;
687
 
688
                break;
689
 
690
        case SCO_CONNINFO:
691
                if (sk->state != BT_CONNECTED) {
692
                        err = -ENOTCONN;
693
                        break;
694
                }
695
 
696
                cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;
697
 
698
                len = MIN(len, sizeof(cinfo));
699
                if (copy_to_user(optval, (char *)&cinfo, len))
700
                        err = -EFAULT;
701
 
702
                break;
703
 
704
        default:
705
                err = -ENOPROTOOPT;
706
                break;
707
        };
708
 
709
        release_sock(sk);
710
        return err;
711
}
712
 
713
static int sco_sock_release(struct socket *sock)
714
{
715
        struct sock *sk = sock->sk;
716
        int err = 0;
717
 
718
        BT_DBG("sock %p, sk %p", sock, sk);
719
 
720
        if (!sk)
721
                return 0;
722
 
723
        sco_sock_close(sk);
724
        if (sk->linger) {
725
                lock_sock(sk);
726
                err = bluez_sock_wait_state(sk, BT_CLOSED, sk->lingertime);
727
                release_sock(sk);
728
        }
729
 
730
        sock_orphan(sk);
731
        sco_sock_kill(sk);
732
        return err;
733
}
734
 
735
static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
736
{
737
        BT_DBG("conn %p", conn);
738
 
739
        sco_pi(sk)->conn = conn;
740
        conn->sk = sk;
741
 
742
        if (parent)
743
                bluez_accept_enqueue(parent, sk);
744
}
745
 
746
static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
747
{
748
        int err = 0;
749
 
750
        sco_conn_lock(conn);
751
        if (conn->sk) {
752
                err = -EBUSY;
753
        } else {
754
                __sco_chan_add(conn, sk, parent);
755
        }
756
        sco_conn_unlock(conn);
757
        return err;
758
}
759
 
760
static inline struct sock * sco_chan_get(struct sco_conn *conn)
761
{
762
        struct sock *sk = NULL;
763
        sco_conn_lock(conn);
764
        sk = conn->sk;
765
        sco_conn_unlock(conn);
766
        return sk;
767
}
768
 
769
/* Delete channel.
770
 * Must be called on the locked socket. */
771
static void sco_chan_del(struct sock *sk, int err)
772
{
773
        struct sco_conn *conn;
774
 
775
        conn = sco_pi(sk)->conn;
776
 
777
        BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
778
 
779
        if (conn) {
780
                sco_conn_lock(conn);
781
                conn->sk = NULL;
782
                sco_pi(sk)->conn = NULL;
783
                sco_conn_unlock(conn);
784
                hci_conn_put(conn->hcon);
785
        }
786
 
787
        sk->state = BT_CLOSED;
788
        sk->err   = err;
789
        sk->state_change(sk);
790
 
791
        sk->zapped = 1;
792
}
793
 
794
static void sco_conn_ready(struct sco_conn *conn)
795
{
796
        struct sock *parent, *sk;
797
 
798
        BT_DBG("conn %p", conn);
799
 
800
        sco_conn_lock(conn);
801
 
802
        if ((sk = conn->sk)) {
803
                sco_sock_clear_timer(sk);
804
                bh_lock_sock(sk);
805
                sk->state = BT_CONNECTED;
806
                sk->state_change(sk);
807
                bh_unlock_sock(sk);
808
        } else {
809
                parent = sco_get_sock_listen(conn->src);
810
                if (!parent)
811
                        goto done;
812
 
813
                bh_lock_sock(parent);
814
 
815
                sk = sco_sock_alloc(NULL, BTPROTO_SCO, GFP_ATOMIC);
816
                if (!sk) {
817
                        bh_unlock_sock(parent);
818
                        goto done;
819
                }
820
 
821
                sco_sock_init(sk, parent);
822
 
823
                bacpy(&bluez_pi(sk)->src, conn->src);
824
                bacpy(&bluez_pi(sk)->dst, conn->dst);
825
 
826
                hci_conn_hold(conn->hcon);
827
                __sco_chan_add(conn, sk, parent);
828
 
829
                sk->state = BT_CONNECTED;
830
 
831
                /* Wake up parent */
832
                parent->data_ready(parent, 1);
833
 
834
                bh_unlock_sock(parent);
835
        }
836
 
837
done:
838
        sco_conn_unlock(conn);
839
}
840
 
841
/* ----- SCO interface with lower layer (HCI) ----- */
842
int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
843
{
844
        BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
845
 
846
        /* Always accept connection */
847
        return HCI_LM_ACCEPT;
848
}
849
 
850
int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
851
{
852
        BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
853
 
854
        if (hcon->type != SCO_LINK)
855
                return 0;
856
 
857
        if (!status) {
858
                struct sco_conn *conn;
859
 
860
                conn = sco_conn_add(hcon, status);
861
                if (conn)
862
                        sco_conn_ready(conn);
863
        } else
864
                sco_conn_del(hcon, bterr(status));
865
 
866
        return 0;
867
}
868
 
869
int sco_disconn_ind(struct hci_conn *hcon, __u8 reason)
870
{
871
        BT_DBG("hcon %p reason %d", hcon, reason);
872
 
873
        if (hcon->type != SCO_LINK)
874
                return 0;
875
 
876
        sco_conn_del(hcon, bterr(reason));
877
        return 0;
878
}
879
 
880
int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
881
{
882
        struct sco_conn *conn = hcon->sco_data;
883
 
884
        if (!conn)
885
                goto drop;
886
 
887
        BT_DBG("conn %p len %d", conn, skb->len);
888
 
889
        if (skb->len) {
890
                sco_recv_frame(conn, skb);
891
                return 0;
892
        }
893
 
894
drop:
895
        kfree_skb(skb);
896
        return 0;
897
}
898
 
899
/* ----- Proc fs support ------ */
900
static int sco_sock_dump(char *buf, struct bluez_sock_list *list)
901
{
902
        struct sco_pinfo *pi;
903
        struct sock *sk;
904
        char *ptr = buf;
905
 
906
        write_lock_bh(&list->lock);
907
 
908
        for (sk = list->head; sk; sk = sk->next) {
909
                pi = sco_pi(sk);
910
                ptr += sprintf(ptr, "%s %s %d\n",
911
                                batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
912
                                sk->state);
913
        }
914
 
915
        write_unlock_bh(&list->lock);
916
 
917
        ptr += sprintf(ptr, "\n");
918
 
919
        return ptr - buf;
920
}
921
 
922
static int sco_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
923
{
924
        char *ptr = buf;
925
        int len;
926
 
927
        BT_DBG("count %d, offset %ld", count, offset);
928
 
929
        ptr += sco_sock_dump(ptr, &sco_sk_list);
930
        len  = ptr - buf;
931
 
932
        if (len <= count + offset)
933
                *eof = 1;
934
 
935
        *start = buf + offset;
936
        len -= offset;
937
 
938
        if (len > count)
939
                len = count;
940
        if (len < 0)
941
                len = 0;
942
 
943
        return len;
944
}
945
 
946
static struct proto_ops sco_sock_ops = {
947
        family:         PF_BLUETOOTH,
948
        release:        sco_sock_release,
949
        bind:           sco_sock_bind,
950
        connect:        sco_sock_connect,
951
        listen:         sco_sock_listen,
952
        accept:         sco_sock_accept,
953
        getname:        sco_sock_getname,
954
        sendmsg:        sco_sock_sendmsg,
955
        recvmsg:        bluez_sock_recvmsg,
956
        poll:           bluez_sock_poll,
957
        socketpair:     sock_no_socketpair,
958
        ioctl:          sock_no_ioctl,
959
        shutdown:       sock_no_shutdown,
960
        setsockopt:     sco_sock_setsockopt,
961
        getsockopt:     sco_sock_getsockopt,
962
        mmap:           sock_no_mmap
963
};
964
 
965
static struct net_proto_family sco_sock_family_ops = {
966
        family:         PF_BLUETOOTH,
967
        create:         sco_sock_create
968
};
969
 
970
static struct hci_proto sco_hci_proto = {
971
        name:           "SCO",
972
        id:             HCI_PROTO_SCO,
973
        connect_ind:    sco_connect_ind,
974
        connect_cfm:    sco_connect_cfm,
975
        disconn_ind:    sco_disconn_ind,
976
        recv_scodata:   sco_recv_scodata,
977
};
978
 
979
int __init sco_init(void)
980
{
981
        int err;
982
 
983
        if ((err = bluez_sock_register(BTPROTO_SCO, &sco_sock_family_ops))) {
984
                BT_ERR("Can't register SCO socket layer");
985
                return err;
986
        }
987
 
988
        if ((err = hci_register_proto(&sco_hci_proto))) {
989
                BT_ERR("Can't register SCO protocol");
990
                return err;
991
        }
992
 
993
        create_proc_read_entry("bluetooth/sco", 0, 0, sco_read_proc, NULL);
994
 
995
        BT_INFO("BlueZ SCO ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
996
        BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
997
        return 0;
998
}
999
 
1000
void sco_cleanup(void)
1001
{
1002
        int err;
1003
 
1004
        remove_proc_entry("bluetooth/sco", NULL);
1005
 
1006
        /* Unregister socket, protocol and notifier */
1007
        if ((err = bluez_sock_unregister(BTPROTO_SCO)))
1008
                BT_ERR("Can't unregister SCO socket layer %d", err);
1009
 
1010
        if ((err = hci_unregister_proto(&sco_hci_proto)))
1011
                BT_ERR("Can't unregister SCO protocol %d", err);
1012
}
1013
 
1014
module_init(sco_init);
1015
module_exit(sco_cleanup);
1016
 
1017
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
1018
MODULE_DESCRIPTION("BlueZ SCO ver " VERSION);
1019
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

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