📄 ksock_multi.c
字号:
static int errno;#define __KERNEL_SYSCALLS__#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/signal.h>#include <linux/init.h>#include <linux/wait.h>#include <linux/smp_lock.h>#include <linux/net.h>#include <net/sock.h>#include <asm/unistd.h>#include <asm/uaccess.h>#include <net/bluetooth/bluetooth.h>#include <net/bluetooth/l2cap.h>#define VERSION "0.1"struct socket *ksock_sock_accept(struct socket *sock){ struct socket *nsock; int err; BT_DBG("%p", sock); nsock = sock_alloc(); if (!nsock) return NULL; nsock->type = sock->type; nsock->ops = sock->ops; err = sock->ops->accept(sock, nsock, 0); if (err < 0) { sock_release(nsock); return NULL; } return nsock;}static int ksock_session(void *arg){ struct socket *sock = arg; struct sock *sk = sock->sk; struct msghdr msg; DECLARE_WAITQUEUE(wait, current); BT_INFO(""); daemonize(); reparent_to_init(); set_fs(KERNEL_DS); sprintf(current->comm, "ksock(s)"); memset(&msg, 0, sizeof(msg)); msg.msg_iovlen = 1; add_wait_queue(sk->sleep, &wait); while (1) { struct sk_buff *skb; set_current_state(TASK_INTERRUPTIBLE); if (signal_pending(current)) break; while ((skb = skb_dequeue(&sk->receive_queue))) { struct iovec iv = { skb->data, skb->len }; BT_INFO("Received %d bytes", skb->len); msg.msg_iov = &iv; sock->ops->sendmsg(sock, &msg, skb->len, NULL); kfree_skb(skb); } if (sk->state != BT_CONNECTED) break; schedule(); } set_current_state(TASK_RUNNING); remove_wait_queue(sk->sleep, &wait); sock_release(sock); return 0;}static int ksock_listener(void *unused){ struct sockaddr_l2 addr; struct l2cap_options opts; struct socket *sock; int i, err, size; daemonize(); sigfillset(¤t->blocked); set_fs(KERNEL_DS); sprintf(current->comm, "ksock(l)"); BT_INFO(""); /* Create socket */ err = sock_create(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP, &sock); if (err < 0) { BT_ERR("Create socket failed %d", err); return err; } /* Bind socket */ bacpy(&addr.l2_bdaddr, BDADDR_ANY); addr.l2_family = AF_BLUETOOTH; addr.l2_psm = htobs(11); err = sock->ops->bind(sock, (struct sockaddr *) &addr, sizeof(addr)); if (err < 0) { BT_ERR("Bind failed %d", err); return err; } /* Set L2CAP options */ size = sizeof(opts); sock->ops->getsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, &size); opts.imtu = 1024; sock->ops->setsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, size); /* Start listening on the socket */ err = sock->ops->listen(sock, 10); if (err) { BT_ERR("Listen failed %d", err); sock_release(sock); return err; } for (i = 0; i < 2; i++) { struct socket *nsock; nsock = ksock_sock_accept(sock); if (!nsock) break; /* Start new thread for this session */ kernel_thread(ksock_session, nsock, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); } sock_release(sock); MOD_DEC_USE_COUNT; return 0;}int __init ksock_init(void){ MOD_INC_USE_COUNT; kernel_thread(ksock_listener, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); return 0;}void ksock_cleanup(void){ return;}module_init(ksock_init);module_exit(ksock_cleanup);MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");MODULE_DESCRIPTION("L2CAP kernel sockets example ver " VERSION);MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -