1 /*
2 * session.c
3 */
4
5 /*-
6 * Copyright (c) 2006 Maksim Yevmenkin <m_evmenkin@yahoo.com>
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * $Id: session.c,v 1.3 2006/09/07 21:06:53 max Exp $
31 * $FreeBSD$
32 */
33
34 #include <sys/queue.h>
35 #include <assert.h>
36 #define L2CAP_SOCKET_CHECKED
37 #include <bluetooth.h>
38 #include <errno.h>
39 #include <fcntl.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <syslog.h>
44 #include <unistd.h>
45 #include <usbhid.h>
46 #include "bthid_config.h"
47 #include "bthidd.h"
48 #include "kbd.h"
49
50 /*
51 * Create new session
52 */
53
54 bthid_session_p
session_open(bthid_server_p srv,hid_device_p const d)55 session_open(bthid_server_p srv, hid_device_p const d)
56 {
57 bthid_session_p s;
58
59 assert(srv != NULL);
60 assert(d != NULL);
61
62 if ((s = (bthid_session_p) malloc(sizeof(*s))) == NULL)
63 return (NULL);
64
65 s->srv = srv;
66 memcpy(&s->bdaddr, &d->bdaddr, sizeof(s->bdaddr));
67 s->ctrl = -1;
68 s->intr = -1;
69
70 if (d->keyboard) {
71 /* Open /dev/vkbdctl */
72 s->vkbd = open("/dev/vkbdctl", O_RDWR);
73 if (s->vkbd < 0) {
74 syslog(LOG_ERR, "Could not open /dev/vkbdctl " \
75 "for %s. %s (%d)", bt_ntoa(&s->bdaddr, NULL),
76 strerror(errno), errno);
77 free(s);
78 return (NULL);
79 }
80 } else
81 s->vkbd = -1;
82
83 s->state = CLOSED;
84
85 s->keys1 = bit_alloc(kbd_maxkey());
86 if (s->keys1 == NULL) {
87 free(s);
88 return (NULL);
89 }
90
91 s->keys2 = bit_alloc(kbd_maxkey());
92 if (s->keys2 == NULL) {
93 free(s->keys1);
94 free(s);
95 return (NULL);
96 }
97
98 LIST_INSERT_HEAD(&srv->sessions, s, next);
99
100 return (s);
101 }
102
103 /*
104 * Lookup session by bdaddr
105 */
106
107 bthid_session_p
session_by_bdaddr(bthid_server_p srv,bdaddr_p bdaddr)108 session_by_bdaddr(bthid_server_p srv, bdaddr_p bdaddr)
109 {
110 bthid_session_p s;
111
112 assert(srv != NULL);
113 assert(bdaddr != NULL);
114
115 LIST_FOREACH(s, &srv->sessions, next)
116 if (memcmp(&s->bdaddr, bdaddr, sizeof(s->bdaddr)) == 0)
117 break;
118
119 return (s);
120 }
121
122 /*
123 * Lookup session by fd
124 */
125
126 bthid_session_p
session_by_fd(bthid_server_p srv,int32_t fd)127 session_by_fd(bthid_server_p srv, int32_t fd)
128 {
129 bthid_session_p s;
130
131 assert(srv != NULL);
132 assert(fd >= 0);
133
134 LIST_FOREACH(s, &srv->sessions, next)
135 if (s->ctrl == fd || s->intr == fd || s->vkbd == fd)
136 break;
137
138 return (s);
139 }
140
141 /*
142 * Close session
143 */
144
145 void
session_close(bthid_session_p s)146 session_close(bthid_session_p s)
147 {
148 assert(s != NULL);
149 assert(s->srv != NULL);
150
151 LIST_REMOVE(s, next);
152
153 if (s->intr != -1) {
154 FD_CLR(s->intr, &s->srv->rfdset);
155 FD_CLR(s->intr, &s->srv->wfdset);
156 close(s->intr);
157
158 if (s->srv->maxfd == s->intr)
159 s->srv->maxfd --;
160 }
161
162 if (s->ctrl != -1) {
163 FD_CLR(s->ctrl, &s->srv->rfdset);
164 FD_CLR(s->ctrl, &s->srv->wfdset);
165 close(s->ctrl);
166
167 if (s->srv->maxfd == s->ctrl)
168 s->srv->maxfd --;
169 }
170
171 if (s->vkbd != -1) {
172 FD_CLR(s->vkbd, &s->srv->rfdset);
173 close(s->vkbd);
174
175 if (s->srv->maxfd == s->vkbd)
176 s->srv->maxfd --;
177 }
178
179 free(s->keys1);
180 free(s->keys2);
181
182 memset(s, 0, sizeof(*s));
183 free(s);
184 }
185
186