^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) CMTP implementation for Linux Bluetooth stack (BlueZ).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) it under the terms of the GNU General Public License version 2 as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) published by the Free Software Foundation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) SOFTWARE IS DISCLAIMED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/socket.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/isdn/capilli.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include "cmtp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static struct bt_sock_list cmtp_sk_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .lock = __RW_LOCK_UNLOCKED(cmtp_sk_list.lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static int cmtp_sock_release(struct socket *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) BT_DBG("sock %p sk %p", sock, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (!sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) bt_sock_unlink(&cmtp_sk_list, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) sock_orphan(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) sock_put(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static int do_cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, void __user *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct cmtp_connadd_req ca;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct cmtp_conndel_req cd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct cmtp_connlist_req cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct cmtp_conninfo ci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct socket *nsock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) BT_DBG("cmd %x arg %p", cmd, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) case CMTPCONNADD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (!capable(CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (copy_from_user(&ca, argp, sizeof(ca)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) nsock = sockfd_lookup(ca.sock, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (!nsock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (nsock->sk->sk_state != BT_CONNECTED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) sockfd_put(nsock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return -EBADFD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) err = cmtp_add_connection(&ca, nsock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (copy_to_user(argp, &ca, sizeof(ca)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) sockfd_put(nsock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) case CMTPCONNDEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (!capable(CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (copy_from_user(&cd, argp, sizeof(cd)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return cmtp_del_connection(&cd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) case CMTPGETCONNLIST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (copy_from_user(&cl, argp, sizeof(cl)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (cl.cnum <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) err = cmtp_get_connlist(&cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (!err && copy_to_user(argp, &cl, sizeof(cl)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) case CMTPGETCONNINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (copy_from_user(&ci, argp, sizeof(ci)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) err = cmtp_get_conninfo(&ci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (!err && copy_to_user(argp, &ci, sizeof(ci)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return do_cmtp_sock_ioctl(sock, cmd, (void __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) void __user *argp = compat_ptr(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (cmd == CMTPGETCONNLIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct cmtp_connlist_req cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) u32 __user *p = argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) u32 uci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (get_user(cl.cnum, p) || get_user(uci, p + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) cl.ci = compat_ptr(uci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (cl.cnum <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) err = cmtp_get_connlist(&cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (!err && put_user(cl.cnum, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return do_cmtp_sock_ioctl(sock, cmd, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static const struct proto_ops cmtp_sock_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .family = PF_BLUETOOTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .release = cmtp_sock_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .ioctl = cmtp_sock_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) .compat_ioctl = cmtp_sock_compat_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) .bind = sock_no_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) .getname = sock_no_getname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) .sendmsg = sock_no_sendmsg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) .recvmsg = sock_no_recvmsg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .listen = sock_no_listen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) .shutdown = sock_no_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) .connect = sock_no_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .socketpair = sock_no_socketpair,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .accept = sock_no_accept,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) .mmap = sock_no_mmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static struct proto cmtp_proto = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) .name = "CMTP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) .obj_size = sizeof(struct bt_sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static int cmtp_sock_create(struct net *net, struct socket *sock, int protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) int kern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) BT_DBG("sock %p", sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (sock->type != SOCK_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return -ESOCKTNOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto, kern);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (!sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) sock_init_data(sock, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) sock->ops = &cmtp_sock_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) sock->state = SS_UNCONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) sock_reset_flag(sk, SOCK_ZAPPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) sk->sk_protocol = protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) sk->sk_state = BT_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) bt_sock_link(&cmtp_sk_list, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static const struct net_proto_family cmtp_sock_family_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) .family = PF_BLUETOOTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) .create = cmtp_sock_create
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) int cmtp_init_sockets(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) err = proto_register(&cmtp_proto, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) err = bt_sock_register(BTPROTO_CMTP, &cmtp_sock_family_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) BT_ERR("Can't register CMTP socket");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) err = bt_procfs_init(&init_net, "cmtp", &cmtp_sk_list, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) BT_ERR("Failed to create CMTP proc file");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) bt_sock_unregister(BTPROTO_HIDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) BT_INFO("CMTP socket layer initialized");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) proto_unregister(&cmtp_proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) void cmtp_cleanup_sockets(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) bt_procfs_cleanup(&init_net, "cmtp");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) bt_sock_unregister(BTPROTO_CMTP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) proto_unregister(&cmtp_proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }