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 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 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 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 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