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$ 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 56 bthid_session_p 57 session_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 s->ctx = NULL; 72 73 if (d->keyboard) { 74 /* Open /dev/vkbdctl */ 75 s->vkbd = open("/dev/vkbdctl", O_RDWR); 76 if (s->vkbd < 0) { 77 syslog(LOG_ERR, "Could not open /dev/vkbdctl " \ 78 "for %s. %s (%d)", bt_ntoa(&s->bdaddr, NULL), 79 strerror(errno), errno); 80 free(s); 81 return (NULL); 82 } 83 } else 84 s->vkbd = -1; 85 86 s->state = CLOSED; 87 88 s->keys1 = bit_alloc(kbd_maxkey()); 89 if (s->keys1 == NULL) { 90 free(s); 91 return (NULL); 92 } 93 94 s->keys2 = bit_alloc(kbd_maxkey()); 95 if (s->keys2 == NULL) { 96 free(s->keys1); 97 free(s); 98 return (NULL); 99 } 100 101 LIST_INSERT_HEAD(&srv->sessions, s, next); 102 103 return (s); 104 } 105 106 /* 107 * Lookup session by bdaddr 108 */ 109 110 bthid_session_p 111 session_by_bdaddr(bthid_server_p srv, bdaddr_p bdaddr) 112 { 113 bthid_session_p s; 114 115 assert(srv != NULL); 116 assert(bdaddr != NULL); 117 118 LIST_FOREACH(s, &srv->sessions, next) 119 if (memcmp(&s->bdaddr, bdaddr, sizeof(s->bdaddr)) == 0) 120 break; 121 122 return (s); 123 } 124 125 /* 126 * Lookup session by fd 127 */ 128 129 bthid_session_p 130 session_by_fd(bthid_server_p srv, int32_t fd) 131 { 132 bthid_session_p s; 133 134 assert(srv != NULL); 135 assert(fd >= 0); 136 137 LIST_FOREACH(s, &srv->sessions, next) 138 if (s->ctrl == fd || s->intr == fd || s->vkbd == fd) 139 break; 140 141 return (s); 142 } 143 144 /* 145 * Close session 146 */ 147 148 void 149 session_close(bthid_session_p s) 150 { 151 assert(s != NULL); 152 assert(s->srv != NULL); 153 154 LIST_REMOVE(s, next); 155 156 if (s->intr != -1) { 157 FD_CLR(s->intr, &s->srv->rfdset); 158 FD_CLR(s->intr, &s->srv->wfdset); 159 close(s->intr); 160 161 if (s->srv->maxfd == s->intr) 162 s->srv->maxfd --; 163 } 164 165 if (s->ctrl != -1) { 166 FD_CLR(s->ctrl, &s->srv->rfdset); 167 FD_CLR(s->ctrl, &s->srv->wfdset); 168 close(s->ctrl); 169 170 if (s->srv->maxfd == s->ctrl) 171 s->srv->maxfd --; 172 } 173 174 if (s->vkbd != -1) { 175 FD_CLR(s->vkbd, &s->srv->rfdset); 176 close(s->vkbd); 177 178 if (s->srv->maxfd == s->vkbd) 179 s->srv->maxfd --; 180 } 181 182 free(s->ctx); 183 free(s->keys1); 184 free(s->keys2); 185 186 memset(s, 0, sizeof(*s)); 187 free(s); 188 } 189 190