⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 core.c

📁 Linux嵌入式平台蓝牙协议栈软件
💻 C
📖 第 1 页 / 共 2 页
字号:
	struct sock *intr_sk = session->intr_sock->sk;	struct sk_buff *skb;	int vendor = 0x0000, product = 0x0000;	wait_queue_t ctrl_wait, intr_wait;	unsigned long timeo = HZ;	BT_DBG("session %p", session);	if (session->input) {		vendor  = session->input->id.vendor;		product = session->input->id.product;	}	daemonize("khidpd_%04x%04x", vendor, product);	set_user_nice(current, -15);	current->flags |= PF_NOFREEZE;	init_waitqueue_entry(&ctrl_wait, current);	init_waitqueue_entry(&intr_wait, current);	add_wait_queue(ctrl_sk->sk_sleep, &ctrl_wait);	add_wait_queue(intr_sk->sk_sleep, &intr_wait);	while (!atomic_read(&session->terminate)) {		set_current_state(TASK_INTERRUPTIBLE);		if (ctrl_sk->sk_state != BT_CONNECTED || intr_sk->sk_state != BT_CONNECTED)			break;		while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) {			skb_orphan(skb);			hidp_recv_frame(session, skb);		}		while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) {			skb_orphan(skb);			hidp_recv_frame(session, skb);		}		hidp_process_transmit(session);		schedule();	}	set_current_state(TASK_RUNNING);	remove_wait_queue(intr_sk->sk_sleep, &intr_wait);	remove_wait_queue(ctrl_sk->sk_sleep, &ctrl_wait);	down_write(&hidp_session_sem);	hidp_del_timer(session);	if (intr_sk->sk_state != BT_CONNECTED) {		init_waitqueue_entry(&ctrl_wait, current);		add_wait_queue(ctrl_sk->sk_sleep, &ctrl_wait);		while (timeo && ctrl_sk->sk_state != BT_CLOSED) {			set_current_state(TASK_INTERRUPTIBLE);			timeo = schedule_timeout(timeo);		}		set_current_state(TASK_RUNNING);		remove_wait_queue(ctrl_sk->sk_sleep, &ctrl_wait);		timeo = HZ;	}	fput(session->ctrl_sock->file);	init_waitqueue_entry(&intr_wait, current);	add_wait_queue(intr_sk->sk_sleep, &intr_wait);	while (timeo && intr_sk->sk_state != BT_CLOSED) {		set_current_state(TASK_INTERRUPTIBLE);		timeo = schedule_timeout(timeo);	}	set_current_state(TASK_RUNNING);	remove_wait_queue(intr_sk->sk_sleep, &intr_wait);	fput(session->intr_sock->file);	__hidp_unlink_session(session);	if (session->input) {		input_unregister_device(session->input);		kfree(session->input);	}	up_write(&hidp_session_sem);	kfree(session);	return 0;}static inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req){	struct input_dev *input = session->input;	int i;	input->private = session;	input->id.bustype = BUS_BLUETOOTH;	input->id.vendor  = req->vendor;	input->id.product = req->product;	input->id.version = req->version;	if (req->subclass & 0x40) {		set_bit(EV_KEY, input->evbit);		set_bit(EV_LED, input->evbit);		set_bit(EV_REP, input->evbit);		set_bit(LED_NUML,    input->ledbit);		set_bit(LED_CAPSL,   input->ledbit);		set_bit(LED_SCROLLL, input->ledbit);		set_bit(LED_COMPOSE, input->ledbit);		set_bit(LED_KANA,    input->ledbit);		for (i = 0; i < sizeof(hidp_keycode); i++)			set_bit(hidp_keycode[i], input->keybit);		clear_bit(0, input->keybit);	}	if (req->subclass & 0x80) {		input->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);		input->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);		input->relbit[0] = BIT(REL_X) | BIT(REL_Y);		input->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);		input->relbit[0] |= BIT(REL_WHEEL);	}	input->event = hidp_input_event;	input_register_device(input);}int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock){	struct hidp_session *session, *s;	int err;	BT_DBG("");	if (bacmp(&bt_sk(ctrl_sock->sk)->src, &bt_sk(intr_sock->sk)->src) ||			bacmp(&bt_sk(ctrl_sock->sk)->dst, &bt_sk(intr_sock->sk)->dst))		return -ENOTUNIQ;	session = kmalloc(sizeof(struct hidp_session), GFP_KERNEL);	if (!session) 		return -ENOMEM;	memset(session, 0, sizeof(struct hidp_session));	session->input = kmalloc(sizeof(struct input_dev), GFP_KERNEL);	if (!session->input) {		kfree(session);		return -ENOMEM;	}	memset(session->input, 0, sizeof(struct input_dev));	down_write(&hidp_session_sem);	s = __hidp_get_session(&bt_sk(ctrl_sock->sk)->dst);	if (s && s->state == BT_CONNECTED) {		err = -EEXIST;		goto failed;	}	bacpy(&session->bdaddr, &bt_sk(ctrl_sock->sk)->dst);	session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl_sock->sk)->omtu, l2cap_pi(ctrl_sock->sk)->imtu);	session->intr_mtu = min_t(uint, l2cap_pi(intr_sock->sk)->omtu, l2cap_pi(intr_sock->sk)->imtu);	BT_DBG("ctrl mtu %d intr mtu %d", session->ctrl_mtu, session->intr_mtu);	session->ctrl_sock = ctrl_sock;	session->intr_sock = intr_sock;	session->state     = BT_CONNECTED;	init_timer(&session->timer);	session->timer.function = hidp_idle_timeout;	session->timer.data     = (unsigned long) session;	skb_queue_head_init(&session->ctrl_transmit);	skb_queue_head_init(&session->intr_transmit);	session->flags   = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID);	session->idle_to = req->idle_to;	if (session->input)		hidp_setup_input(session, req);	__hidp_link_session(session);	hidp_set_timer(session);	err = kernel_thread(hidp_session, session, CLONE_KERNEL);	if (err < 0)		goto unlink;	if (session->input) {		hidp_send_message(session, 0x70);		session->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE);		session->leds = 0xff;		hidp_input_event(session->input, EV_LED, 0, 0);	}	up_write(&hidp_session_sem);	return 0;unlink:	hidp_del_timer(session);	__hidp_unlink_session(session);	if (session->input)		input_unregister_device(session->input);failed:	up_write(&hidp_session_sem);	if (session->input)		kfree(session->input);	kfree(session);	return err;}int hidp_del_connection(struct hidp_conndel_req *req){	struct hidp_session *session;	int err = 0;	BT_DBG("");	down_read(&hidp_session_sem);	session = __hidp_get_session(&req->bdaddr);	if (session) {		if (req->flags & (1 << HIDP_VIRTUAL_CABLE_UNPLUG)) {			hidp_send_message(session, 0x15);		} else {			/* Flush the transmit queues */			skb_queue_purge(&session->ctrl_transmit);			skb_queue_purge(&session->intr_transmit);			/* Kill session thread */			atomic_inc(&session->terminate);			hidp_schedule(session);		}	} else		err = -ENOENT;	up_read(&hidp_session_sem);	return err;}int hidp_get_connlist(struct hidp_connlist_req *req){	struct list_head *p;	int err = 0, n = 0;	BT_DBG("");	down_read(&hidp_session_sem);	list_for_each(p, &hidp_session_list) {		struct hidp_session *session;		struct hidp_conninfo ci;		session = list_entry(p, struct hidp_session, list);		__hidp_copy_session(session, &ci);		if (copy_to_user(req->ci, &ci, sizeof(ci))) {			err = -EFAULT;			break;		}		if (++n >= req->cnum)			break;		req->ci++;	}	req->cnum = n;	up_read(&hidp_session_sem);	return err;}int hidp_get_conninfo(struct hidp_conninfo *ci){	struct hidp_session *session;	int err = 0;	down_read(&hidp_session_sem);	session = __hidp_get_session(&ci->bdaddr);	if (session)		__hidp_copy_session(session, ci);	else		err = -ENOENT;	up_read(&hidp_session_sem);	return err;}static int __init hidp_init(void){	l2cap_load();	BT_INFO("HIDP (Human Interface Emulation) ver %s", VERSION);	return hidp_init_sockets();}static void __exit hidp_exit(void){	hidp_cleanup_sockets();}module_init(hidp_init);module_exit(hidp_exit);MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");MODULE_DESCRIPTION("Bluetooth HIDP ver " VERSION);MODULE_VERSION(VERSION);MODULE_LICENSE("GPL");MODULE_ALIAS("bt-proto-6");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -