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