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