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/sdp.h> 46 #include <bluetooth/sdp_lib.h> 47 #include <bluetooth/rfcomm.h> 48 49 #include <glib.h> 50 #include <gdbus.h> 51 52 #include "../src/dbus-common.h" 53 #include "adapter.h" 54 #include "device.h" 55 56 #include "log.h" 57 #include "textfile.h" 58 59 #include "error.h" 60 #include "port.h" 61 #include "proxy.h" 62 #include "storage.h" 63 #include "manager.h" 64 #include "sdpd.h" 65 #include "glib-helper.h" 66 67 #define RFCOMM_UUID_STR "00000003-0000-1000-8000-00805F9B34FB" 68 69 static DBusConnection *connection = NULL; 70 71 static int serial_probe(struct btd_device *device, const char *uuid) 72 { 73 struct btd_adapter *adapter = device_get_adapter(device); 74 const gchar *path = device_get_path(device); 75 sdp_list_t *protos; 76 int ch; 77 bdaddr_t src, dst; 78 const sdp_record_t *rec; 79 80 DBG("path %s: %s", path, uuid); 81 82 rec = btd_device_get_record(device, uuid); 83 if (!rec) 84 return -EINVAL; 85 86 if (sdp_get_access_protos(rec, &protos) < 0) 87 return -EINVAL; 88 89 ch = sdp_get_proto_port(protos, RFCOMM_UUID); 90 sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL); 91 sdp_list_free(protos, NULL); 92 93 if (ch < 1 || ch > 30) { 94 error("Channel out of range: %d", ch); 95 return -EINVAL; 96 } 97 98 adapter_get_address(adapter, &src); 99 device_get_address(device, &dst); 100 101 return port_register(connection, path, &src, &dst, uuid, ch); 102 } 103 104 static void serial_remove(struct btd_device *device) 105 { 106 const gchar *path = device_get_path(device); 107 108 DBG("path %s", path); 109 110 port_unregister(path); 111 } 112 113 114 static int port_probe(struct btd_device *device, GSList *uuids) 115 { 116 while (uuids) { 117 serial_probe(device, uuids->data); 118 uuids = uuids->next; 119 } 120 121 return 0; 122 } 123 124 static void port_remove(struct btd_device *device) 125 { 126 return serial_remove(device); 127 } 128 129 static struct btd_device_driver serial_port_driver = { 130 .name = "serial-port", 131 .uuids = BTD_UUIDS(RFCOMM_UUID_STR), 132 .probe = port_probe, 133 .remove = port_remove, 134 }; 135 136 static int proxy_probe(struct btd_adapter *adapter) 137 { 138 const char *path = adapter_get_path(adapter); 139 140 DBG("path %s", path); 141 142 return proxy_register(connection, adapter); 143 } 144 145 static void proxy_remove(struct btd_adapter *adapter) 146 { 147 const char *path = adapter_get_path(adapter); 148 149 DBG("path %s", path); 150 151 proxy_unregister(adapter); 152 } 153 154 static struct btd_adapter_driver serial_proxy_driver = { 155 .name = "serial-proxy", 156 .probe = proxy_probe, 157 .remove = proxy_remove, 158 }; 159 160 int serial_manager_init(DBusConnection *conn) 161 { 162 connection = dbus_connection_ref(conn); 163 164 btd_register_adapter_driver(&serial_proxy_driver); 165 btd_register_device_driver(&serial_port_driver); 166 167 return 0; 168 } 169 170 void serial_manager_exit(void) 171 { 172 btd_unregister_device_driver(&serial_port_driver); 173 174 dbus_connection_unref(connection); 175 connection = NULL; 176 } 177