session.c revision 330449
1/*
2 * session.c
3 */
4
5/*-
6 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
7 *
8 * Copyright (c) 2006 Maksim Yevmenkin <m_evmenkin@yahoo.com>
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
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.
19 *
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
30 * SUCH DAMAGE.
31 *
32 * $Id: session.c,v 1.3 2006/09/07 21:06:53 max Exp $
33 * $FreeBSD: stable/11/usr.sbin/bluetooth/bthidd/session.c 330449 2018-03-05 07:26:05Z eadler $
34 */
35
36#include <sys/queue.h>
37#include <assert.h>
38#define L2CAP_SOCKET_CHECKED
39#include <bluetooth.h>
40#include <errno.h>
41#include <fcntl.h>
42#include <stdio.h>
43#include <stdlib.h>
44#include <string.h>
45#include <syslog.h>
46#include <unistd.h>
47#include <usbhid.h>
48#include "bthid_config.h"
49#include "bthidd.h"
50#include "kbd.h"
51
52/*
53 * Create new session
54 */
55
56bthid_session_p
57session_open(bthid_server_p srv, hid_device_p const d)
58{
59	bthid_session_p	s;
60
61	assert(srv != NULL);
62	assert(d != NULL);
63
64	if ((s = (bthid_session_p) malloc(sizeof(*s))) == NULL)
65		return (NULL);
66
67	s->srv = srv;
68	memcpy(&s->bdaddr, &d->bdaddr, sizeof(s->bdaddr));
69	s->ctrl = -1;
70	s->intr = -1;
71
72	if (d->keyboard) {
73		/* Open /dev/vkbdctl */
74		s->vkbd = open("/dev/vkbdctl", O_RDWR);
75		if (s->vkbd < 0) {
76			syslog(LOG_ERR, "Could not open /dev/vkbdctl " \
77				"for %s. %s (%d)", bt_ntoa(&s->bdaddr, NULL),
78				strerror(errno), errno);
79			free(s);
80			return (NULL);
81		}
82	} else
83		s->vkbd = -1;
84
85	s->state = CLOSED;
86
87	s->keys1 = bit_alloc(kbd_maxkey());
88	if (s->keys1 == NULL) {
89		free(s);
90		return (NULL);
91	}
92
93	s->keys2 = bit_alloc(kbd_maxkey());
94	if (s->keys2 == NULL) {
95		free(s->keys1);
96		free(s);
97		return (NULL);
98	}
99
100	LIST_INSERT_HEAD(&srv->sessions, s, next);
101
102	return (s);
103}
104
105/*
106 * Lookup session by bdaddr
107 */
108
109bthid_session_p
110session_by_bdaddr(bthid_server_p srv, bdaddr_p bdaddr)
111{
112	bthid_session_p	s;
113
114	assert(srv != NULL);
115	assert(bdaddr != NULL);
116
117	LIST_FOREACH(s, &srv->sessions, next)
118		if (memcmp(&s->bdaddr, bdaddr, sizeof(s->bdaddr)) == 0)
119			break;
120
121	return (s);
122}
123
124/*
125 * Lookup session by fd
126 */
127
128bthid_session_p
129session_by_fd(bthid_server_p srv, int32_t fd)
130{
131	bthid_session_p	s;
132
133	assert(srv != NULL);
134	assert(fd >= 0);
135
136	LIST_FOREACH(s, &srv->sessions, next)
137		if (s->ctrl == fd || s->intr == fd || s->vkbd == fd)
138			break;
139
140	return (s);
141}
142
143/*
144 * Close session
145 */
146
147void
148session_close(bthid_session_p s)
149{
150	assert(s != NULL);
151	assert(s->srv != NULL);
152
153	LIST_REMOVE(s, next);
154
155	if (s->intr != -1) {
156		FD_CLR(s->intr, &s->srv->rfdset);
157		FD_CLR(s->intr, &s->srv->wfdset);
158		close(s->intr);
159
160		if (s->srv->maxfd == s->intr)
161			s->srv->maxfd --;
162	}
163
164	if (s->ctrl != -1) {
165		FD_CLR(s->ctrl, &s->srv->rfdset);
166		FD_CLR(s->ctrl, &s->srv->wfdset);
167		close(s->ctrl);
168
169		if (s->srv->maxfd == s->ctrl)
170			s->srv->maxfd --;
171	}
172
173	if (s->vkbd != -1) {
174		FD_CLR(s->vkbd, &s->srv->rfdset);
175		close(s->vkbd);
176
177		if (s->srv->maxfd == s->vkbd)
178			s->srv->maxfd --;
179	}
180
181	free(s->keys1);
182	free(s->keys2);
183
184	memset(s, 0, sizeof(*s));
185	free(s);
186}
187
188