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 #include <bluetooth.h> 37 #include <errno.h> 38 #include <fcntl.h> 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <syslog.h> 43 #include <unistd.h> 44 #include <usbhid.h> 45 #include "bthid_config.h" 46 #include "bthidd.h" 47 #include "kbd.h" 48 49 /* 50 * Create new session 51 */ 52 53 bthid_session_p 54 session_open(bthid_server_p srv, hid_device_p const d) 55 { 56 bthid_session_p s; 57 58 assert(srv != NULL); 59 assert(d != NULL); 60 61 if ((s = (bthid_session_p) malloc(sizeof(*s))) == NULL) 62 return (NULL); 63 64 s->srv = srv; 65 memcpy(&s->bdaddr, &d->bdaddr, sizeof(s->bdaddr)); 66 s->ctrl = -1; 67 s->intr = -1; 68 69 if (d->keyboard) { 70 /* Open /dev/vkbdctl */ 71 s->vkbd = open("/dev/vkbdctl", O_RDWR); 72 if (s->vkbd < 0) { 73 syslog(LOG_ERR, "Could not open /dev/vkbdctl " \ 74 "for %s. %s (%d)", bt_ntoa(&s->bdaddr, NULL), 75 strerror(errno), errno); 76 free(s); 77 return (NULL); 78 } 79 } else 80 s->vkbd = -1; 81 82 s->state = CLOSED; 83 84 s->keys1 = bit_alloc(kbd_maxkey()); 85 if (s->keys1 == NULL) { 86 free(s); 87 return (NULL); 88 } 89 90 s->keys2 = bit_alloc(kbd_maxkey()); 91 if (s->keys2 == NULL) { 92 free(s->keys1); 93 free(s); 94 return (NULL); 95 } 96 97 LIST_INSERT_HEAD(&srv->sessions, s, next); 98 99 return (s); 100 } 101 102 /* 103 * Lookup session by bdaddr 104 */ 105 106 bthid_session_p 107 session_by_bdaddr(bthid_server_p srv, bdaddr_p bdaddr) 108 { 109 bthid_session_p s; 110 111 assert(srv != NULL); 112 assert(bdaddr != NULL); 113 114 LIST_FOREACH(s, &srv->sessions, next) 115 if (memcmp(&s->bdaddr, bdaddr, sizeof(s->bdaddr)) == 0) 116 break; 117 118 return (s); 119 } 120 121 /* 122 * Lookup session by fd 123 */ 124 125 bthid_session_p 126 session_by_fd(bthid_server_p srv, int32_t fd) 127 { 128 bthid_session_p s; 129 130 assert(srv != NULL); 131 assert(fd >= 0); 132 133 LIST_FOREACH(s, &srv->sessions, next) 134 if (s->ctrl == fd || s->intr == fd || s->vkbd == fd) 135 break; 136 137 return (s); 138 } 139 140 /* 141 * Close session 142 */ 143 144 void 145 session_close(bthid_session_p s) 146 { 147 assert(s != NULL); 148 assert(s->srv != NULL); 149 150 LIST_REMOVE(s, next); 151 152 if (s->intr != -1) { 153 FD_CLR(s->intr, &s->srv->rfdset); 154 FD_CLR(s->intr, &s->srv->wfdset); 155 close(s->intr); 156 157 if (s->srv->maxfd == s->intr) 158 s->srv->maxfd --; 159 } 160 161 if (s->ctrl != -1) { 162 FD_CLR(s->ctrl, &s->srv->rfdset); 163 FD_CLR(s->ctrl, &s->srv->wfdset); 164 close(s->ctrl); 165 166 if (s->srv->maxfd == s->ctrl) 167 s->srv->maxfd --; 168 } 169 170 if (s->vkbd != -1) { 171 FD_CLR(s->vkbd, &s->srv->rfdset); 172 close(s->vkbd); 173 174 if (s->srv->maxfd == s->vkbd) 175 s->srv->maxfd --; 176 } 177 178 free(s->keys1); 179 free(s->keys2); 180 181 memset(s, 0, sizeof(*s)); 182 free(s); 183 } 184 185