linux/net/bluetooth/af_bluetooth.c
<<
>>
Prefs
   1/*
   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 address family and sockets. */
  26
  27#include <linux/module.h>
  28
  29#include <linux/types.h>
  30#include <linux/list.h>
  31#include <linux/errno.h>
  32#include <linux/kernel.h>
  33#include <linux/sched.h>
  34#include <linux/skbuff.h>
  35#include <linux/init.h>
  36#include <linux/poll.h>
  37#include <net/sock.h>
  38#include <asm/ioctls.h>
  39#include <linux/kmod.h>
  40
  41#include <net/bluetooth/bluetooth.h>
  42
  43#define VERSION "2.15"
  44
  45/* Bluetooth sockets */
  46#define BT_MAX_PROTO    8
  47static const struct net_proto_family *bt_proto[BT_MAX_PROTO];
  48static DEFINE_RWLOCK(bt_proto_lock);
  49
  50static struct lock_class_key bt_lock_key[BT_MAX_PROTO];
  51static const char *const bt_key_strings[BT_MAX_PROTO] = {
  52        "sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP",
  53        "sk_lock-AF_BLUETOOTH-BTPROTO_HCI",
  54        "sk_lock-AF_BLUETOOTH-BTPROTO_SCO",
  55        "sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM",
  56        "sk_lock-AF_BLUETOOTH-BTPROTO_BNEP",
  57        "sk_lock-AF_BLUETOOTH-BTPROTO_CMTP",
  58        "sk_lock-AF_BLUETOOTH-BTPROTO_HIDP",
  59        "sk_lock-AF_BLUETOOTH-BTPROTO_AVDTP",
  60};
  61
  62static struct lock_class_key bt_slock_key[BT_MAX_PROTO];
  63static const char *const bt_slock_key_strings[BT_MAX_PROTO] = {
  64        "slock-AF_BLUETOOTH-BTPROTO_L2CAP",
  65        "slock-AF_BLUETOOTH-BTPROTO_HCI",
  66        "slock-AF_BLUETOOTH-BTPROTO_SCO",
  67        "slock-AF_BLUETOOTH-BTPROTO_RFCOMM",
  68        "slock-AF_BLUETOOTH-BTPROTO_BNEP",
  69        "slock-AF_BLUETOOTH-BTPROTO_CMTP",
  70        "slock-AF_BLUETOOTH-BTPROTO_HIDP",
  71        "slock-AF_BLUETOOTH-BTPROTO_AVDTP",
  72};
  73
  74static inline void bt_sock_reclassify_lock(struct socket *sock, int proto)
  75{
  76        struct sock *sk = sock->sk;
  77
  78        if (!sk)
  79                return;
  80
  81        BUG_ON(sock_owned_by_user(sk));
  82
  83        sock_lock_init_class_and_name(sk,
  84                        bt_slock_key_strings[proto], &bt_slock_key[proto],
  85                                bt_key_strings[proto], &bt_lock_key[proto]);
  86}
  87
  88int bt_sock_register(int proto, const struct net_proto_family *ops)
  89{
  90        int err = 0;
  91
  92        if (proto < 0 || proto >= BT_MAX_PROTO)
  93                return -EINVAL;
  94
  95        write_lock(&bt_proto_lock);
  96
  97        if (bt_proto[proto])
  98                err = -EEXIST;
  99        else
 100                bt_proto[proto] = ops;
 101
 102        write_unlock(&bt_proto_lock);
 103
 104        return err;
 105}
 106EXPORT_SYMBOL(bt_sock_register);
 107
 108int bt_sock_unregister(int proto)
 109{
 110        int err = 0;
 111
 112        if (proto < 0 || proto >= BT_MAX_PROTO)
 113                return -EINVAL;
 114
 115        write_lock(&bt_proto_lock);
 116
 117        if (!bt_proto[proto])
 118                err = -ENOENT;
 119        else
 120                bt_proto[proto] = NULL;
 121
 122        write_unlock(&bt_proto_lock);
 123
 124        return err;
 125}
 126EXPORT_SYMBOL(bt_sock_unregister);
 127
 128static int bt_sock_create(struct net *net, struct socket *sock, int proto,
 129                          int kern)
 130{
 131        int err;
 132
 133        if (net != &init_net)
 134                return -EAFNOSUPPORT;
 135
 136        if (proto < 0 || proto >= BT_MAX_PROTO)
 137                return -EINVAL;
 138
 139        if (!bt_proto[proto])
 140                request_module("bt-proto-%d", proto);
 141
 142        err = -EPROTONOSUPPORT;
 143
 144        read_lock(&bt_proto_lock);
 145
 146        if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
 147                err = bt_proto[proto]->create(net, sock, proto, kern);
 148                bt_sock_reclassify_lock(sock, proto);
 149                module_put(bt_proto[proto]->owner);
 150        }
 151
 152        read_unlock(&bt_proto_lock);
 153
 154        return err;
 155}
 156
 157void bt_sock_link(struct bt_sock_list *l, struct sock *sk)
 158{
 159        write_lock_bh(&l->lock);
 160        sk_add_node(sk, &l->head);
 161        write_unlock_bh(&l->lock);
 162}
 163EXPORT_SYMBOL(bt_sock_link);
 164
 165void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
 166{
 167        write_lock_bh(&l->lock);
 168        sk_del_node_init(sk);
 169        write_unlock_bh(&l->lock);
 170}
 171EXPORT_SYMBOL(bt_sock_unlink);
 172
 173void bt_accept_enqueue(struct sock *parent, struct sock *sk)
 174{
 175        BT_DBG("parent %p, sk %p", parent, sk);
 176
 177        sock_hold(sk);
 178        list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q);
 179        bt_sk(sk)->parent = parent;
 180        parent->sk_ack_backlog++;
 181}
 182EXPORT_SYMBOL(bt_accept_enqueue);
 183
 184void bt_accept_unlink(struct sock *sk)
 185{
 186        BT_DBG("sk %p state %d", sk, sk->sk_state);
 187
 188        list_del_init(&bt_sk(sk)->accept_q);
 189        bt_sk(sk)->parent->sk_ack_backlog--;
 190        bt_sk(sk)->parent = NULL;
 191        sock_put(sk);
 192}
 193EXPORT_SYMBOL(bt_accept_unlink);
 194
 195struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
 196{
 197        struct list_head *p, *n;
 198        struct sock *sk;
 199
 200        BT_DBG("parent %p", parent);
 201
 202        list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
 203                sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
 204
 205                lock_sock(sk);
 206
 207                /* FIXME: Is this check still needed */
 208                if (sk->sk_state == BT_CLOSED) {
 209                        release_sock(sk);
 210                        bt_accept_unlink(sk);
 211                        continue;
 212                }
 213
 214                if (sk->sk_state == BT_CONNECTED || !newsock ||
 215                                                bt_sk(parent)->defer_setup) {
 216                        bt_accept_unlink(sk);
 217                        if (newsock)
 218                                sock_graft(sk, newsock);
 219                        release_sock(sk);
 220                        return sk;
 221                }
 222
 223                release_sock(sk);
 224        }
 225        return NULL;
 226}
 227EXPORT_SYMBOL(bt_accept_dequeue);
 228
 229int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 230                                struct msghdr *msg, size_t len, int flags)
 231{
 232        int noblock = flags & MSG_DONTWAIT;
 233        struct sock *sk = sock->sk;
 234        struct sk_buff *skb;
 235        size_t copied;
 236        int err;
 237
 238        BT_DBG("sock %p sk %p len %zu", sock, sk, len);
 239
 240        if (flags & (MSG_OOB))
 241                return -EOPNOTSUPP;
 242
 243        if (!(skb = skb_recv_datagram(sk, flags, noblock, &err))) {
 244                if (sk->sk_shutdown & RCV_SHUTDOWN)
 245                        return 0;
 246                return err;
 247        }
 248
 249        msg->msg_namelen = 0;
 250
 251        copied = skb->len;
 252        if (len < copied) {
 253                msg->msg_flags |= MSG_TRUNC;
 254                copied = len;
 255        }
 256
 257        skb_reset_transport_header(skb);
 258        err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
 259        if (err == 0)
 260                sock_recv_ts_and_drops(msg, sk, skb);
 261
 262        skb_free_datagram(sk, skb);
 263
 264        return err ? : copied;
 265}
 266EXPORT_SYMBOL(bt_sock_recvmsg);
 267
 268static inline unsigned int bt_accept_poll(struct sock *parent)
 269{
 270        struct list_head *p, *n;
 271        struct sock *sk;
 272
 273        list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
 274                sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
 275                if (sk->sk_state == BT_CONNECTED ||
 276                                        (bt_sk(parent)->defer_setup &&
 277                                                sk->sk_state == BT_CONNECT2))
 278                        return POLLIN | POLLRDNORM;
 279        }
 280
 281        return 0;
 282}
 283
 284unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
 285{
 286        struct sock *sk = sock->sk;
 287        unsigned int mask = 0;
 288
 289        BT_DBG("sock %p, sk %p", sock, sk);
 290
 291        poll_wait(file, sk_sleep(sk), wait);
 292
 293        if (sk->sk_state == BT_LISTEN)
 294                return bt_accept_poll(sk);
 295
 296        if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
 297                mask |= POLLERR;
 298
 299        if (sk->sk_shutdown & RCV_SHUTDOWN)
 300                mask |= POLLRDHUP;
 301
 302        if (sk->sk_shutdown == SHUTDOWN_MASK)
 303                mask |= POLLHUP;
 304
 305        if (!skb_queue_empty(&sk->sk_receive_queue) ||
 306                        (sk->sk_shutdown & RCV_SHUTDOWN))
 307                mask |= POLLIN | POLLRDNORM;
 308
 309        if (sk->sk_state == BT_CLOSED)
 310                mask |= POLLHUP;
 311
 312        if (sk->sk_state == BT_CONNECT ||
 313                        sk->sk_state == BT_CONNECT2 ||
 314                        sk->sk_state == BT_CONFIG)
 315                return mask;
 316
 317        if (sock_writeable(sk))
 318                mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
 319        else
 320                set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
 321
 322        return mask;
 323}
 324EXPORT_SYMBOL(bt_sock_poll);
 325
 326int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 327{
 328        struct sock *sk = sock->sk;
 329        struct sk_buff *skb;
 330        long amount;
 331        int err;
 332
 333        BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg);
 334
 335        switch (cmd) {
 336        case TIOCOUTQ:
 337                if (sk->sk_state == BT_LISTEN)
 338                        return -EINVAL;
 339
 340                amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
 341                if (amount < 0)
 342                        amount = 0;
 343                err = put_user(amount, (int __user *) arg);
 344                break;
 345
 346        case TIOCINQ:
 347                if (sk->sk_state == BT_LISTEN)
 348                        return -EINVAL;
 349
 350                lock_sock(sk);
 351                skb = skb_peek(&sk->sk_receive_queue);
 352                amount = skb ? skb->len : 0;
 353                release_sock(sk);
 354                err = put_user(amount, (int __user *) arg);
 355                break;
 356
 357        case SIOCGSTAMP:
 358                err = sock_get_timestamp(sk, (struct timeval __user *) arg);
 359                break;
 360
 361        case SIOCGSTAMPNS:
 362                err = sock_get_timestampns(sk, (struct timespec __user *) arg);
 363                break;
 364
 365        default:
 366                err = -ENOIOCTLCMD;
 367                break;
 368        }
 369
 370        return err;
 371}
 372EXPORT_SYMBOL(bt_sock_ioctl);
 373
 374int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
 375{
 376        DECLARE_WAITQUEUE(wait, current);
 377        int err = 0;
 378
 379        BT_DBG("sk %p", sk);
 380
 381        add_wait_queue(sk_sleep(sk), &wait);
 382        while (sk->sk_state != state) {
 383                set_current_state(TASK_INTERRUPTIBLE);
 384
 385                if (!timeo) {
 386                        err = -EINPROGRESS;
 387                        break;
 388                }
 389
 390                if (signal_pending(current)) {
 391                        err = sock_intr_errno(timeo);
 392                        break;
 393                }
 394
 395                release_sock(sk);
 396                timeo = schedule_timeout(timeo);
 397                lock_sock(sk);
 398
 399                err = sock_error(sk);
 400                if (err)
 401                        break;
 402        }
 403        set_current_state(TASK_RUNNING);
 404        remove_wait_queue(sk_sleep(sk), &wait);
 405        return err;
 406}
 407EXPORT_SYMBOL(bt_sock_wait_state);
 408
 409static struct net_proto_family bt_sock_family_ops = {
 410        .owner  = THIS_MODULE,
 411        .family = PF_BLUETOOTH,
 412        .create = bt_sock_create,
 413};
 414
 415static int __init bt_init(void)
 416{
 417        int err;
 418
 419        BT_INFO("Core ver %s", VERSION);
 420
 421        err = bt_sysfs_init();
 422        if (err < 0)
 423                return err;
 424
 425        err = sock_register(&bt_sock_family_ops);
 426        if (err < 0) {
 427                bt_sysfs_cleanup();
 428                return err;
 429        }
 430
 431        BT_INFO("HCI device and connection manager initialized");
 432
 433        hci_sock_init();
 434
 435        return 0;
 436}
 437
 438static void __exit bt_exit(void)
 439{
 440        hci_sock_cleanup();
 441
 442        sock_unregister(PF_BLUETOOTH);
 443
 444        bt_sysfs_cleanup();
 445}
 446
 447subsys_initcall(bt_init);
 448module_exit(bt_exit);
 449
 450MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 451MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
 452MODULE_VERSION(VERSION);
 453MODULE_LICENSE("GPL");
 454MODULE_ALIAS_NETPROTO(PF_BLUETOOTH);
 455
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.