1 /* 2 * 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2004-2010 Marcel Holtmann <marcel (at) holtmann.org> 6 * 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 * 22 */ 23 24 #ifdef HAVE_CONFIG_H 25 #include <config.h> 26 #endif 27 28 #include <ctype.h> 29 #include <dirent.h> 30 #include <errno.h> 31 #include <fcntl.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <string.h> 35 #include <termios.h> 36 #include <unistd.h> 37 #include <arpa/inet.h> 38 #include <sys/param.h> 39 #include <sys/ioctl.h> 40 #include <sys/stat.h> 41 #include <sys/types.h> 42 #include <sys/un.h> 43 44 #include <bluetooth/bluetooth.h> 45 #include <bluetooth/hci.h> 46 #include <bluetooth/hci_lib.h> 47 #include <bluetooth/sdp.h> 48 #include <bluetooth/sdp_lib.h> 49 #include <bluetooth/rfcomm.h> 50 51 #include <glib.h> 52 #include <gdbus.h> 53 54 #include "../src/dbus-common.h" 55 #include "adapter.h" 56 #include "device.h" 57 58 #include "log.h" 59 #include "textfile.h" 60 61 #include "error.h" 62 #include "port.h" 63 #include "proxy.h" 64 #include "storage.h" 65 #include "manager.h" 66 #include "sdpd.h" 67 #include "glib-helper.h" 68 69 #define RFCOMM_UUID_STR "00000003-0000-1000-8000-00805F9B34FB" 70 71 static DBusConnection *connection = NULL; 72 73 static int serial_probe(struct btd_device *device, const char *uuid) 74 { 75 struct btd_adapter *adapter = device_get_adapter(device); 76 const gchar *path = device_get_path(device); 77 sdp_list_t *protos; 78 int ch; 79 bdaddr_t src, dst; 80 const sdp_record_t *rec; 81 82 DBG("path %s: %s", path, uuid); 83 84 rec = btd_device_get_record(device, uuid); 85 if (!rec) 86 return -EINVAL; 87 88 if (sdp_get_access_protos(rec, &protos) < 0) 89 return -EINVAL; 90 91 ch = sdp_get_proto_port(protos, RFCOMM_UUID); 92 sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL); 93 sdp_list_free(protos, NULL); 94 95 if (ch < 1 || ch > 30) { 96 error("Channel out of range: %d", ch); 97 return -EINVAL; 98 } 99 100 adapter_get_address(adapter, &src); 101 device_get_address(device, &dst); 102 103 return port_register(connection, path, &src, &dst, uuid, ch); 104 } 105 106 static void serial_remove(struct btd_device *device) 107 { 108 const gchar *path = device_get_path(device); 109 110 DBG("path %s", path); 111 112 port_unregister(path); 113 } 114 115 116 static int port_probe(struct btd_device *device, GSList *uuids) 117 { 118 while (uuids) { 119 serial_probe(device, uuids->data); 120 uuids = uuids->next; 121 } 122 123 return 0; 124 } 125 126 static void port_remove(struct btd_device *device) 127 { 128 return serial_remove(device); 129 } 130 131 static struct btd_device_driver serial_port_driver = { 132 .name = "serial-port", 133 .uuids = BTD_UUIDS(RFCOMM_UUID_STR), 134 .probe = port_probe, 135 .remove = port_remove, 136 }; 137 138 static int proxy_probe(struct btd_adapter *adapter) 139 { 140 const char *path = adapter_get_path(adapter); 141 142 DBG("path %s", path); 143 144 return proxy_register(connection, adapter); 145 } 146 147 static void proxy_remove(struct btd_adapter *adapter) 148 { 149 const char *path = adapter_get_path(adapter); 150 151 DBG("path %s", path); 152 153 proxy_unregister(adapter); 154 } 155 156 static struct btd_adapter_driver serial_proxy_driver = { 157 .name = "serial-proxy", 158 .probe = proxy_probe, 159 .remove = proxy_remove, 160 }; 161 162 int serial_manager_init(DBusConnection *conn) 163 { 164 connection = dbus_connection_ref(conn); 165 166 btd_register_adapter_driver(&serial_proxy_driver); 167 btd_register_device_driver(&serial_port_driver); 168 169 return 0; 170 } 171 172 void serial_manager_exit(void) 173 { 174 btd_unregister_device_driver(&serial_port_driver); 175 176 dbus_connection_unref(connection); 177 connection = NULL; 178 } 179