6 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
8 * Copyright (c) 2006 Maksim Yevmenkin <m_evmenkin@yahoo.com>
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * $Id: session.c,v 1.3 2006/09/07 21:06:53 max Exp $
36 #include <sys/queue.h>
38 #define L2CAP_SOCKET_CHECKED
39 #include <bluetooth.h>
48 #include "bthid_config.h"
58 session_open(bthid_server_p srv, hid_device_p const d)
65 if ((s = (bthid_session_p) malloc(sizeof(*s))) == NULL)
69 memcpy(&s->bdaddr, &d->bdaddr, sizeof(s->bdaddr));
79 s->keys1 = bit_alloc(kbd_maxkey());
80 if (s->keys1 == NULL) {
85 s->keys2 = bit_alloc(kbd_maxkey());
86 if (s->keys2 == NULL) {
92 LIST_INSERT_HEAD(&srv->sessions, s, next);
98 * Initialize virtual keyboard and mouse after both channels are established
102 session_run(bthid_session_p s)
104 hid_device_p d = get_hid_device(&s->bdaddr);
105 struct sockaddr_l2cap local;
109 /* Open /dev/vkbdctl */
110 s->vkbd = open("/dev/vkbdctl", O_RDWR);
112 syslog(LOG_ERR, "Could not open /dev/vkbdctl " \
113 "for %s. %s (%d)", bt_ntoa(&s->bdaddr, NULL),
114 strerror(errno), errno);
117 /* Register session's vkbd descriptor (if needed) for read */
118 FD_SET(s->vkbd, &s->srv->rfdset);
119 if (s->vkbd > s->srv->maxfd)
120 s->srv->maxfd = s->vkbd;
123 /* Pass device for probing */
126 /* Take local bdaddr */
128 getsockname(s->ctrl, (struct sockaddr *) &local, &len);
130 if (d->mouse && s->srv->uinput) {
131 s->umouse = uinput_open_mouse(d, &local.l2cap_bdaddr);
133 syslog(LOG_ERR, "Could not open /dev/uinput " \
134 "for %s. %s (%d)", bt_ntoa(&s->bdaddr,
135 NULL), strerror(errno), errno);
139 if (d->keyboard && s->srv->uinput) {
140 s->ukbd = uinput_open_keyboard(d, &local.l2cap_bdaddr);
142 syslog(LOG_ERR, "Could not open /dev/uinput " \
143 "for %s. %s (%d)", bt_ntoa(&s->bdaddr,
144 NULL), strerror(errno), errno);
147 /* Register session's ukbd descriptor (if needed) for read */
148 FD_SET(s->ukbd, &s->srv->rfdset);
149 if (s->ukbd > s->srv->maxfd)
150 s->srv->maxfd = s->ukbd;
156 * Lookup session by bdaddr
160 session_by_bdaddr(bthid_server_p srv, bdaddr_p bdaddr)
165 assert(bdaddr != NULL);
167 LIST_FOREACH(s, &srv->sessions, next)
168 if (memcmp(&s->bdaddr, bdaddr, sizeof(s->bdaddr)) == 0)
175 * Lookup session by fd
179 session_by_fd(bthid_server_p srv, int32_t fd)
186 LIST_FOREACH(s, &srv->sessions, next)
187 if (s->ctrl == fd || s->intr == fd ||
188 s->vkbd == fd || s->ukbd == fd)
199 session_close(bthid_session_p s)
202 assert(s->srv != NULL);
204 LIST_REMOVE(s, next);
207 FD_CLR(s->intr, &s->srv->rfdset);
208 FD_CLR(s->intr, &s->srv->wfdset);
211 if (s->srv->maxfd == s->intr)
216 FD_CLR(s->ctrl, &s->srv->rfdset);
217 FD_CLR(s->ctrl, &s->srv->wfdset);
220 if (s->srv->maxfd == s->ctrl)
225 FD_CLR(s->vkbd, &s->srv->rfdset);
228 if (s->srv->maxfd == s->vkbd)
236 FD_CLR(s->ukbd, &s->srv->rfdset);
239 if (s->srv->maxfd == s->ukbd)
247 memset(s, 0, sizeof(*s));