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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
   RFCOMM implementation for Linux Bluetooth stack (BlueZ).
3
   Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
4
   Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
5
 
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License version 2 as
8
   published by the Free Software Foundation;
9
 
10
   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
11
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
13
   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
14
   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
15
   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 
19
   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
20
   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
21
   SOFTWARE IS DISCLAIMED.
22
*/
23
 
24
/*
25
 * RFCOMM sockets.
26
 *
27
 * $Id: sock.c,v 1.1.1.1 2004-04-15 01:17:13 phoenix Exp $
28
 */
29
 
30
#include <linux/config.h>
31
#include <linux/module.h>
32
 
33
#include <linux/types.h>
34
#include <linux/errno.h>
35
#include <linux/kernel.h>
36
#include <linux/major.h>
37
#include <linux/sched.h>
38
#include <linux/slab.h>
39
#include <linux/poll.h>
40
#include <linux/fcntl.h>
41
#include <linux/init.h>
42
#include <linux/skbuff.h>
43
#include <linux/interrupt.h>
44
#include <linux/socket.h>
45
#include <linux/skbuff.h>
46
#include <linux/list.h>
47
#include <net/sock.h>
48
 
49
#include <asm/system.h>
50
#include <asm/uaccess.h>
51
 
52
#include <net/bluetooth/bluetooth.h>
53
#include <net/bluetooth/rfcomm.h>
54
 
55
#ifndef CONFIG_BLUEZ_RFCOMM_DEBUG
56
#undef  BT_DBG
57
#define BT_DBG(D...)
58
#endif
59
 
60
static struct proto_ops rfcomm_sock_ops;
61
 
62
static struct bluez_sock_list rfcomm_sk_list = {
63
        lock: RW_LOCK_UNLOCKED
64
};
65
 
66
static void rfcomm_sock_close(struct sock *sk);
67
static void rfcomm_sock_kill(struct sock *sk);
68
 
69
/* ---- DLC callbacks ----
70
 *
71
 * called under rfcomm_dlc_lock()
72
 */
73
static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb)
74
{
75
        struct sock *sk = d->owner;
76
        if (!sk)
77
                return;
78
 
79
        atomic_add(skb->len, &sk->rmem_alloc);
80
        skb_queue_tail(&sk->receive_queue, skb);
81
        sk->data_ready(sk, skb->len);
82
 
83
        if (atomic_read(&sk->rmem_alloc) >= sk->rcvbuf)
84
                rfcomm_dlc_throttle(d);
85
}
86
 
87
static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
88
{
89
        struct sock *sk = d->owner, *parent;
90
        if (!sk)
91
                return;
92
 
93
        BT_DBG("dlc %p state %ld err %d", d, d->state, err);
94
 
95
        bh_lock_sock(sk);
96
 
97
        if (err)
98
                sk->err = err;
99
        sk->state = d->state;
100
 
101
        parent = bluez_pi(sk)->parent;
102
        if (!parent) {
103
                if (d->state == BT_CONNECTED)
104
                        rfcomm_session_getaddr(d->session, &bluez_pi(sk)->src, NULL);
105
                sk->state_change(sk);
106
        } else
107
                parent->data_ready(parent, 0);
108
 
109
        bh_unlock_sock(sk);
110
}
111
 
112
/* ---- Socket functions ---- */
113
static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src)
114
{
115
        struct sock *sk;
116
 
117
        for (sk = rfcomm_sk_list.head; sk; sk = sk->next) {
118
                if (rfcomm_pi(sk)->channel == channel &&
119
                                !bacmp(&bluez_pi(sk)->src, src))
120
                        break;
121
        }
122
 
123
        return sk;
124
}
125
 
126
/* Find socket with channel and source bdaddr.
127
 * Returns closest match.
128
 */
129
static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
130
{
131
        struct sock *sk, *sk1 = NULL;
132
 
133
        for (sk = rfcomm_sk_list.head; sk; sk = sk->next) {
134
                if (state && sk->state != state)
135
                        continue;
136
 
137
                if (rfcomm_pi(sk)->channel == channel) {
138
                        /* Exact match. */
139
                        if (!bacmp(&bluez_pi(sk)->src, src))
140
                                break;
141
 
142
                        /* Closest match */
143
                        if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
144
                                sk1 = sk;
145
                }
146
        }
147
        return sk ? sk : sk1;
148
}
149
 
150
/* Find socket with given address (channel, src).
151
 * Returns locked socket */
152
static inline struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
153
{
154
        struct sock *s;
155
        read_lock(&rfcomm_sk_list.lock);
156
        s = __rfcomm_get_sock_by_channel(state, channel, src);
157
        if (s) bh_lock_sock(s);
158
        read_unlock(&rfcomm_sk_list.lock);
159
        return s;
160
}
161
 
162
static void rfcomm_sock_destruct(struct sock *sk)
163
{
164
        struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
165
 
166
        BT_DBG("sk %p dlc %p", sk, d);
167
 
168
        skb_queue_purge(&sk->receive_queue);
169
        skb_queue_purge(&sk->write_queue);
170
 
171
        rfcomm_dlc_lock(d);
172
        rfcomm_pi(sk)->dlc = NULL;
173
 
174
        /* Detach DLC if it's owned by this socket */
175
        if (d->owner == sk)
176
                d->owner = NULL;
177
        rfcomm_dlc_unlock(d);
178
 
179
        rfcomm_dlc_put(d);
180
 
181
        MOD_DEC_USE_COUNT;
182
}
183
 
184
static void rfcomm_sock_cleanup_listen(struct sock *parent)
185
{
186
        struct sock *sk;
187
 
188
        BT_DBG("parent %p", parent);
189
 
190
        /* Close not yet accepted dlcs */
191
        while ((sk = bluez_accept_dequeue(parent, NULL))) {
192
                rfcomm_sock_close(sk);
193
                rfcomm_sock_kill(sk);
194
        }
195
 
196
        parent->state  = BT_CLOSED;
197
        parent->zapped = 1;
198
}
199
 
200
/* Kill socket (only if zapped and orphan)
201
 * Must be called on unlocked socket.
202
 */
203
static void rfcomm_sock_kill(struct sock *sk)
204
{
205
        if (!sk->zapped || sk->socket)
206
                return;
207
 
208
        BT_DBG("sk %p state %d refcnt %d", sk, sk->state, atomic_read(&sk->refcnt));
209
 
210
        /* Kill poor orphan */
211
        bluez_sock_unlink(&rfcomm_sk_list, sk);
212
        sk->dead = 1;
213
        sock_put(sk);
214
}
215
 
216
static void __rfcomm_sock_close(struct sock *sk)
217
{
218
        struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
219
 
220
        BT_DBG("sk %p state %d socket %p", sk, sk->state, sk->socket);
221
 
222
        switch (sk->state) {
223
        case BT_LISTEN:
224
                rfcomm_sock_cleanup_listen(sk);
225
                break;
226
 
227
        case BT_CONNECT:
228
        case BT_CONNECT2:
229
        case BT_CONFIG:
230
        case BT_CONNECTED:
231
                rfcomm_dlc_close(d, 0);
232
 
233
        default:
234
                sk->zapped = 1;
235
                break;
236
        }
237
}
238
 
239
/* Close socket.
240
 * Must be called on unlocked socket.
241
 */
242
static void rfcomm_sock_close(struct sock *sk)
243
{
244
        lock_sock(sk);
245
        __rfcomm_sock_close(sk);
246
        release_sock(sk);
247
}
248
 
249
static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
250
{
251
        BT_DBG("sk %p", sk);
252
 
253
        if (parent)
254
                sk->type = parent->type;
255
}
256
 
257
static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, int prio)
258
{
259
        struct rfcomm_dlc *d;
260
        struct sock *sk;
261
 
262
        sk = sk_alloc(PF_BLUETOOTH, prio, 1);
263
        if (!sk)
264
                return NULL;
265
 
266
        d = rfcomm_dlc_alloc(prio);
267
        if (!d) {
268
                sk_free(sk);
269
                return NULL;
270
        }
271
        d->data_ready   = rfcomm_sk_data_ready;
272
        d->state_change = rfcomm_sk_state_change;
273
 
274
        rfcomm_pi(sk)->dlc = d;
275
        d->owner = sk;
276
 
277
        bluez_sock_init(sock, sk);
278
 
279
        sk->zapped   = 0;
280
 
281
        sk->destruct = rfcomm_sock_destruct;
282
        sk->sndtimeo = RFCOMM_CONN_TIMEOUT;
283
 
284
        sk->sndbuf   = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
285
        sk->rcvbuf   = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
286
 
287
        sk->protocol = proto;
288
        sk->state    = BT_OPEN;
289
 
290
        bluez_sock_link(&rfcomm_sk_list, sk);
291
 
292
        BT_DBG("sk %p", sk);
293
 
294
        MOD_INC_USE_COUNT;
295
        return sk;
296
}
297
 
298
static int rfcomm_sock_create(struct socket *sock, int protocol)
299
{
300
        struct sock *sk;
301
 
302
        BT_DBG("sock %p", sock);
303
 
304
        sock->state = SS_UNCONNECTED;
305
 
306
        if (sock->type != SOCK_STREAM && sock->type != SOCK_RAW)
307
                return -ESOCKTNOSUPPORT;
308
 
309
        sock->ops = &rfcomm_sock_ops;
310
 
311
        if (!(sk = rfcomm_sock_alloc(sock, protocol, GFP_KERNEL)))
312
                return -ENOMEM;
313
 
314
        rfcomm_sock_init(sk, NULL);
315
        return 0;
316
}
317
 
318
static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
319
{
320
        struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
321
        struct sock *sk = sock->sk;
322
        int err = 0;
323
 
324
        BT_DBG("sk %p %s", sk, batostr(&sa->rc_bdaddr));
325
 
326
        if (!addr || addr->sa_family != AF_BLUETOOTH)
327
                return -EINVAL;
328
 
329
        lock_sock(sk);
330
 
331
        if (sk->state != BT_OPEN) {
332
                err = -EBADFD;
333
                goto done;
334
        }
335
 
336
        write_lock_bh(&rfcomm_sk_list.lock);
337
 
338
        if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) {
339
                err = -EADDRINUSE;
340
        } else {
341
                /* Save source address */
342
                bacpy(&bluez_pi(sk)->src, &sa->rc_bdaddr);
343
                rfcomm_pi(sk)->channel = sa->rc_channel;
344
                sk->state = BT_BOUND;
345
        }
346
 
347
        write_unlock_bh(&rfcomm_sk_list.lock);
348
 
349
done:
350
        release_sock(sk);
351
        return err;
352
}
353
 
354
static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
355
{
356
        struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
357
        struct sock *sk = sock->sk;
358
        struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
359
        int err = 0;
360
 
361
        BT_DBG("sk %p", sk);
362
 
363
        if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_rc))
364
                return -EINVAL;
365
 
366
        if (sk->state != BT_OPEN && sk->state != BT_BOUND)
367
                return -EBADFD;
368
 
369
        if (sk->type != SOCK_STREAM)
370
                return -EINVAL;
371
 
372
        lock_sock(sk);
373
 
374
        sk->state = BT_CONNECT;
375
        bacpy(&bluez_pi(sk)->dst, &sa->rc_bdaddr);
376
        rfcomm_pi(sk)->channel = sa->rc_channel;
377
 
378
        err = rfcomm_dlc_open(d, &bluez_pi(sk)->src, &sa->rc_bdaddr, sa->rc_channel);
379
        if (!err)
380
                err = bluez_sock_wait_state(sk, BT_CONNECTED,
381
                                sock_sndtimeo(sk, flags & O_NONBLOCK));
382
 
383
        release_sock(sk);
384
        return err;
385
}
386
 
387
int rfcomm_sock_listen(struct socket *sock, int backlog)
388
{
389
        struct sock *sk = sock->sk;
390
        int err = 0;
391
 
392
        BT_DBG("sk %p backlog %d", sk, backlog);
393
 
394
        lock_sock(sk);
395
 
396
        if (sk->state != BT_BOUND) {
397
                err = -EBADFD;
398
                goto done;
399
        }
400
 
401
        sk->max_ack_backlog = backlog;
402
        sk->ack_backlog = 0;
403
        sk->state = BT_LISTEN;
404
 
405
done:
406
        release_sock(sk);
407
        return err;
408
}
409
 
410
int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags)
411
{
412
        DECLARE_WAITQUEUE(wait, current);
413
        struct sock *sk = sock->sk, *nsk;
414
        long timeo;
415
        int err = 0;
416
 
417
        lock_sock(sk);
418
 
419
        if (sk->state != BT_LISTEN) {
420
                err = -EBADFD;
421
                goto done;
422
        }
423
 
424
        timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
425
 
426
        BT_DBG("sk %p timeo %ld", sk, timeo);
427
 
428
        /* Wait for an incoming connection. (wake-one). */
429
        add_wait_queue_exclusive(sk->sleep, &wait);
430
        while (!(nsk = bluez_accept_dequeue(sk, newsock))) {
431
                set_current_state(TASK_INTERRUPTIBLE);
432
                if (!timeo) {
433
                        err = -EAGAIN;
434
                        break;
435
                }
436
 
437
                release_sock(sk);
438
                timeo = schedule_timeout(timeo);
439
                lock_sock(sk);
440
 
441
                if (sk->state != BT_LISTEN) {
442
                        err = -EBADFD;
443
                        break;
444
                }
445
 
446
                if (signal_pending(current)) {
447
                        err = sock_intr_errno(timeo);
448
                        break;
449
                }
450
        }
451
        set_current_state(TASK_RUNNING);
452
        remove_wait_queue(sk->sleep, &wait);
453
 
454
        if (err)
455
                goto done;
456
 
457
        newsock->state = SS_CONNECTED;
458
 
459
        BT_DBG("new socket %p", nsk);
460
 
461
done:
462
        release_sock(sk);
463
        return err;
464
}
465
 
466
static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
467
{
468
        struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
469
        struct sock *sk = sock->sk;
470
 
471
        BT_DBG("sock %p, sk %p", sock, sk);
472
 
473
        sa->rc_family  = AF_BLUETOOTH;
474
        sa->rc_channel = rfcomm_pi(sk)->channel;
475
        if (peer)
476
                bacpy(&sa->rc_bdaddr, &bluez_pi(sk)->dst);
477
        else
478
                bacpy(&sa->rc_bdaddr, &bluez_pi(sk)->src);
479
 
480
        *len = sizeof(struct sockaddr_rc);
481
        return 0;
482
}
483
 
484
static int rfcomm_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
485
                               struct scm_cookie *scm)
486
{
487
        struct sock *sk = sock->sk;
488
        struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
489
        struct sk_buff *skb;
490
        int err, size;
491
        int sent = 0;
492
 
493
        if (msg->msg_flags & MSG_OOB)
494
                return -EOPNOTSUPP;
495
 
496
        if (sk->shutdown & SEND_SHUTDOWN)
497
                return -EPIPE;
498
 
499
        BT_DBG("sock %p, sk %p", sock, sk);
500
 
501
        lock_sock(sk);
502
 
503
        while (len) {
504
                size = min_t(uint, len, d->mtu);
505
 
506
                skb = sock_alloc_send_skb(sk, size + RFCOMM_SKB_RESERVE,
507
                                msg->msg_flags & MSG_DONTWAIT, &err);
508
                if (!skb)
509
                        break;
510
                skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
511
 
512
                err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
513
                if (err) {
514
                        kfree_skb(skb);
515
                        sent = err;
516
                        break;
517
                }
518
 
519
                err = rfcomm_dlc_send(d, skb);
520
                if (err < 0) {
521
                        kfree_skb(skb);
522
                        break;
523
                }
524
 
525
                sent += size;
526
                len  -= size;
527
        }
528
 
529
        release_sock(sk);
530
 
531
        return sent ? sent : err;
532
}
533
 
534
static long rfcomm_sock_data_wait(struct sock *sk, long timeo)
535
{
536
        DECLARE_WAITQUEUE(wait, current);
537
 
538
        add_wait_queue(sk->sleep, &wait);
539
        for (;;) {
540
                set_current_state(TASK_INTERRUPTIBLE);
541
 
542
                if (skb_queue_len(&sk->receive_queue) || sk->err || (sk->shutdown & RCV_SHUTDOWN) ||
543
                                signal_pending(current) || !timeo)
544
                        break;
545
 
546
                set_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
547
                release_sock(sk);
548
                timeo = schedule_timeout(timeo);
549
                lock_sock(sk);
550
                clear_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
551
        }
552
 
553
        __set_current_state(TASK_RUNNING);
554
        remove_wait_queue(sk->sleep, &wait);
555
        return timeo;
556
}
557
 
558
static int rfcomm_sock_recvmsg(struct socket *sock, struct msghdr *msg, int size,
559
                               int flags, struct scm_cookie *scm)
560
{
561
        struct sock *sk = sock->sk;
562
        int target, err = 0, copied = 0;
563
        long timeo;
564
 
565
        if (flags & MSG_OOB)
566
                return -EOPNOTSUPP;
567
 
568
        msg->msg_namelen = 0;
569
 
570
        BT_DBG("sk %p size %d", sk, size);
571
 
572
        lock_sock(sk);
573
 
574
        target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
575
        timeo  = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
576
 
577
        do {
578
                struct sk_buff *skb;
579
                int chunk;
580
 
581
                skb = skb_dequeue(&sk->receive_queue);
582
                if (!skb) {
583
                        if (copied >= target)
584
                                break;
585
 
586
                        if ((err = sock_error(sk)) != 0)
587
                                break;
588
                        if (sk->shutdown & RCV_SHUTDOWN)
589
                                break;
590
 
591
                        err = -EAGAIN;
592
                        if (!timeo)
593
                                break;
594
 
595
                        timeo = rfcomm_sock_data_wait(sk, timeo);
596
 
597
                        if (signal_pending(current)) {
598
                                err = sock_intr_errno(timeo);
599
                                goto out;
600
                        }
601
                        continue;
602
                }
603
 
604
                chunk = min_t(unsigned int, skb->len, size);
605
                if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
606
                        skb_queue_head(&sk->receive_queue, skb);
607
                        if (!copied)
608
                                copied = -EFAULT;
609
                        break;
610
                }
611
                copied += chunk;
612
                size   -= chunk;
613
 
614
                if (!(flags & MSG_PEEK)) {
615
                        atomic_sub(chunk, &sk->rmem_alloc);
616
 
617
                        skb_pull(skb, chunk);
618
                        if (skb->len) {
619
                                skb_queue_head(&sk->receive_queue, skb);
620
                                break;
621
                        }
622
                        kfree_skb(skb);
623
 
624
                } else {
625
                        /* put message back and return */
626
                        skb_queue_head(&sk->receive_queue, skb);
627
                        break;
628
                }
629
        } while (size);
630
 
631
out:
632
        if (atomic_read(&sk->rmem_alloc) <= (sk->rcvbuf >> 2))
633
                rfcomm_dlc_unthrottle(rfcomm_pi(sk)->dlc);
634
 
635
        release_sock(sk);
636
        return copied ? : err;
637
}
638
 
639
static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
640
{
641
        struct sock *sk = sock->sk;
642
        int err = 0;
643
 
644
        BT_DBG("sk %p", sk);
645
 
646
        lock_sock(sk);
647
 
648
        switch (optname) {
649
        default:
650
                err = -ENOPROTOOPT;
651
                break;
652
        };
653
 
654
        release_sock(sk);
655
        return err;
656
}
657
 
658
static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
659
{
660
        struct sock *sk = sock->sk;
661
        int len, err = 0;
662
 
663
        BT_DBG("sk %p", sk);
664
 
665
        if (get_user(len, optlen))
666
                return -EFAULT;
667
 
668
        lock_sock(sk);
669
 
670
        switch (optname) {
671
        default:
672
                err = -ENOPROTOOPT;
673
                break;
674
        };
675
 
676
        release_sock(sk);
677
        return err;
678
}
679
 
680
static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
681
{
682
        struct sock *sk = sock->sk;
683
        int err;
684
 
685
        lock_sock(sk);
686
 
687
#ifdef CONFIG_BLUEZ_RFCOMM_TTY
688
        err = rfcomm_dev_ioctl(sk, cmd, arg);
689
#else
690
        err = -EOPNOTSUPP;
691
#endif
692
 
693
        release_sock(sk);
694
 
695
        return err;
696
}
697
 
698
static int rfcomm_sock_shutdown(struct socket *sock, int how)
699
{
700
        struct sock *sk = sock->sk;
701
        int err = 0;
702
 
703
        BT_DBG("sock %p, sk %p", sock, sk);
704
 
705
        if (!sk) return 0;
706
 
707
        lock_sock(sk);
708
        if (!sk->shutdown) {
709
                sk->shutdown = SHUTDOWN_MASK;
710
                __rfcomm_sock_close(sk);
711
 
712
                if (sk->linger)
713
                        err = bluez_sock_wait_state(sk, BT_CLOSED, sk->lingertime);
714
        }
715
        release_sock(sk);
716
        return err;
717
}
718
 
719
static int rfcomm_sock_release(struct socket *sock)
720
{
721
        struct sock *sk = sock->sk;
722
        int err = 0;
723
 
724
        BT_DBG("sock %p, sk %p", sock, sk);
725
 
726
        if (!sk)
727
                return 0;
728
 
729
        err = rfcomm_sock_shutdown(sock, 2);
730
 
731
        sock_orphan(sk);
732
        rfcomm_sock_kill(sk);
733
        return err;
734
}
735
 
736
/* ---- RFCOMM core layer callbacks ----
737
 *
738
 * called under rfcomm_lock()
739
 */
740
int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d)
741
{
742
        struct sock *sk, *parent;
743
        bdaddr_t src, dst;
744
        int result = 0;
745
 
746
        BT_DBG("session %p channel %d", s, channel);
747
 
748
        rfcomm_session_getaddr(s, &src, &dst);
749
 
750
        /* Check if we have socket listening on this channel */
751
        parent = rfcomm_get_sock_by_channel(BT_LISTEN, channel, &src);
752
        if (!parent)
753
                return 0;
754
 
755
        /* Check for backlog size */
756
        if (parent->ack_backlog > parent->max_ack_backlog) {
757
                BT_DBG("backlog full %d", parent->ack_backlog);
758
                goto done;
759
        }
760
 
761
        sk = rfcomm_sock_alloc(NULL, BTPROTO_RFCOMM, GFP_ATOMIC);
762
        if (!sk)
763
                goto done;
764
 
765
        rfcomm_sock_init(sk, parent);
766
        bacpy(&bluez_pi(sk)->src, &src);
767
        bacpy(&bluez_pi(sk)->dst, &dst);
768
        rfcomm_pi(sk)->channel = channel;
769
 
770
        sk->state = BT_CONFIG;
771
        bluez_accept_enqueue(parent, sk);
772
 
773
        /* Accept connection and return socket DLC */
774
        *d = rfcomm_pi(sk)->dlc;
775
        result = 1;
776
 
777
done:
778
        bh_unlock_sock(parent);
779
        return result;
780
}
781
 
782
/* ---- Proc fs support ---- */
783
int rfcomm_sock_dump(char *buf)
784
{
785
        struct bluez_sock_list *list = &rfcomm_sk_list;
786
        struct rfcomm_pinfo *pi;
787
        struct sock *sk;
788
        char *ptr = buf;
789
 
790
        write_lock_bh(&list->lock);
791
 
792
        for (sk = list->head; sk; sk = sk->next) {
793
                pi = rfcomm_pi(sk);
794
                ptr += sprintf(ptr, "sk  %s %s %d %d\n",
795
                                batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
796
                                sk->state, rfcomm_pi(sk)->channel);
797
        }
798
 
799
        write_unlock_bh(&list->lock);
800
 
801
        return ptr - buf;
802
}
803
 
804
static struct proto_ops rfcomm_sock_ops = {
805
        family:         PF_BLUETOOTH,
806
        release:        rfcomm_sock_release,
807
        bind:           rfcomm_sock_bind,
808
        connect:        rfcomm_sock_connect,
809
        listen:         rfcomm_sock_listen,
810
        accept:         rfcomm_sock_accept,
811
        getname:        rfcomm_sock_getname,
812
        sendmsg:        rfcomm_sock_sendmsg,
813
        recvmsg:        rfcomm_sock_recvmsg,
814
        shutdown:       rfcomm_sock_shutdown,
815
        setsockopt:     rfcomm_sock_setsockopt,
816
        getsockopt:     rfcomm_sock_getsockopt,
817
        ioctl:          rfcomm_sock_ioctl,
818
        poll:           bluez_sock_poll,
819
        socketpair:     sock_no_socketpair,
820
        mmap:           sock_no_mmap
821
};
822
 
823
static struct net_proto_family rfcomm_sock_family_ops = {
824
        family:         PF_BLUETOOTH,
825
        create:         rfcomm_sock_create
826
};
827
 
828
int rfcomm_init_sockets(void)
829
{
830
        int err;
831
 
832
        if ((err = bluez_sock_register(BTPROTO_RFCOMM, &rfcomm_sock_family_ops))) {
833
                BT_ERR("Can't register RFCOMM socket layer");
834
                return err;
835
        }
836
 
837
        return 0;
838
}
839
 
840
void rfcomm_cleanup_sockets(void)
841
{
842
        int err;
843
 
844
        /* Unregister socket, protocol and notifier */
845
        if ((err = bluez_sock_unregister(BTPROTO_RFCOMM)))
846
                BT_ERR("Can't unregister RFCOMM socket layer %d", err);
847
}

powered by: WebSVN 2.1.0

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