Home | History | Annotate | Download | only in serial
      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 <errno.h>
     29 #include <stdio.h>
     30 #include <stdint.h>
     31 #include <stdlib.h>
     32 #include <string.h>
     33 #include <termios.h>
     34 #include <unistd.h>
     35 #include <sys/ioctl.h>
     36 #include <sys/types.h>
     37 #include <sys/stat.h>
     38 #include <fcntl.h>
     39 
     40 #include <bluetooth/bluetooth.h>
     41 #include <bluetooth/rfcomm.h>
     42 #include <bluetooth/sdp.h>
     43 #include <bluetooth/sdp_lib.h>
     44 
     45 #include <glib.h>
     46 #include <gdbus.h>
     47 
     48 #include "../src/dbus-common.h"
     49 
     50 #include "log.h"
     51 #include "glib-helper.h"
     52 #include "btio.h"
     53 
     54 #include "error.h"
     55 #include "manager.h"
     56 #include "adapter.h"
     57 #include "device.h"
     58 #include "storage.h"
     59 #include "port.h"
     60 
     61 #define SERIAL_PORT_INTERFACE	"org.bluez.Serial"
     62 
     63 #define MAX_OPEN_TRIES		5
     64 #define OPEN_WAIT		300	/* ms. udev node creation retry wait */
     65 
     66 struct serial_device {
     67 	DBusConnection	*conn;		/* for name listener handling */
     68 	bdaddr_t	src;		/* Source (local) address */
     69 	bdaddr_t	dst;		/* Destination address */
     70 	char		*path;		/* Device path */
     71 	GSList		*ports;		/* Available ports */
     72 };
     73 
     74 struct serial_port {
     75 	DBusMessage	*msg;		/* for name listener handling */
     76 	int16_t		id;		/* RFCOMM device id */
     77 	uint8_t		channel;	/* RFCOMM channel */
     78 	char		*uuid;		/* service identification */
     79 	char		*dev;		/* RFCOMM device name */
     80 	int		fd;		/* Opened file descriptor */
     81 	GIOChannel	*io;		/* BtIO channel */
     82 	guint		listener_id;
     83 	struct serial_device *device;
     84 };
     85 
     86 static GSList *devices = NULL;
     87 
     88 static struct serial_device *find_device(GSList *devices, const char *path)
     89 {
     90 	GSList *l;
     91 
     92 	for (l = devices; l != NULL; l = l->next) {
     93 		struct serial_device *device = l->data;
     94 
     95 		if (!strcmp(device->path, path))
     96 			return device;
     97 	}
     98 
     99 	return NULL;
    100 }
    101 
    102 static struct serial_port *find_port(GSList *ports, const char *pattern)
    103 {
    104 	GSList *l;
    105 	int channel;
    106 	char *endptr = NULL;
    107 
    108 	channel = strtol(pattern, &endptr, 10);
    109 
    110 	for (l = ports; l != NULL; l = l->next) {
    111 		struct serial_port *port = l->data;
    112 		char *uuid_str;
    113 		int ret;
    114 
    115 		if (port->uuid && !strcasecmp(port->uuid, pattern))
    116 			return port;
    117 
    118 		if (endptr && *endptr == '\0' && port->channel == channel)
    119 			return port;
    120 
    121 		if (port->dev && !strcmp(port->dev, pattern))
    122 			return port;
    123 
    124 		if (!port->uuid)
    125 			continue;
    126 
    127 		uuid_str = bt_name2string(pattern);
    128 		if (!uuid_str)
    129 			continue;
    130 
    131 		ret = strcasecmp(port->uuid, uuid_str);
    132 		g_free(uuid_str);
    133 		if (ret == 0)
    134 			return port;
    135 	}
    136 
    137 	return NULL;
    138 }
    139 
    140 static int port_release(struct serial_port *port)
    141 {
    142 	struct rfcomm_dev_req req;
    143 	int rfcomm_ctl;
    144 	int err = 0;
    145 
    146 	if (port->id < 0) {
    147 		if (port->io) {
    148 			g_io_channel_shutdown(port->io, TRUE, NULL);
    149 			g_io_channel_unref(port->io);
    150 			port->io = NULL;
    151 		} else
    152 			bt_cancel_discovery(&port->device->src,
    153 						&port->device->dst);
    154 
    155 		return 0;
    156 	}
    157 
    158 	DBG("Serial port %s released", port->dev);
    159 
    160 	rfcomm_ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM);
    161 	if (rfcomm_ctl < 0)
    162 		return -errno;
    163 
    164 	if (port->fd >= 0) {
    165 		close(port->fd);
    166 		port->fd = -1;
    167 	}
    168 
    169 	memset(&req, 0, sizeof(req));
    170 	req.dev_id = port->id;
    171 
    172 	/*
    173 	 * We are hitting a kernel bug inside RFCOMM code when
    174 	 * RFCOMM_HANGUP_NOW bit is set on request's flags passed to
    175 	 * ioctl(RFCOMMRELEASEDEV)!
    176 	 */
    177 	req.flags = (1 << RFCOMM_HANGUP_NOW);
    178 
    179 	if (ioctl(rfcomm_ctl, RFCOMMRELEASEDEV, &req) < 0) {
    180 		err = errno;
    181 		error("Can't release device %s: %s (%d)",
    182 				port->dev, strerror(err), err);
    183 	}
    184 
    185 	g_free(port->dev);
    186 	port->dev = NULL;
    187 	port->id = -1;
    188 	close(rfcomm_ctl);
    189 	return -err;
    190 }
    191 
    192 static void serial_port_free(struct serial_port *port)
    193 {
    194 	struct serial_device *device = port->device;
    195 
    196 	if (device && port->listener_id > 0)
    197 		g_dbus_remove_watch(device->conn, port->listener_id);
    198 
    199 	port_release(port);
    200 
    201 	g_free(port->uuid);
    202 	g_free(port);
    203 }
    204 
    205 static void serial_device_free(struct serial_device *device)
    206 {
    207 	g_free(device->path);
    208 	if (device->conn)
    209 		dbus_connection_unref(device->conn);
    210 	g_free(device);
    211 }
    212 
    213 static void port_owner_exited(DBusConnection *conn, void *user_data)
    214 {
    215 	struct serial_port *port = user_data;
    216 
    217 	port_release(port);
    218 
    219 	port->listener_id = 0;
    220 }
    221 
    222 static void path_unregister(void *data)
    223 {
    224 	struct serial_device *device = data;
    225 
    226 	DBG("Unregistered interface %s on path %s", SERIAL_PORT_INTERFACE,
    227 		device->path);
    228 
    229 	devices = g_slist_remove(devices, device);
    230 	serial_device_free(device);
    231 }
    232 
    233 void port_release_all(void)
    234 {
    235 	g_slist_foreach(devices, (GFunc) serial_device_free, NULL);
    236 	g_slist_free(devices);
    237 }
    238 
    239 static void open_notify(int fd, int err, struct serial_port *port)
    240 {
    241 	struct serial_device *device = port->device;
    242 	DBusMessage *reply;
    243 
    244 	if (err < 0) {
    245 		/* Max tries exceeded */
    246 		port_release(port);
    247 		reply = btd_error_failed(port->msg, strerror(-err));
    248 	} else {
    249 		port->fd = fd;
    250 		reply = g_dbus_create_reply(port->msg,
    251 				DBUS_TYPE_STRING, &port->dev,
    252 				DBUS_TYPE_INVALID);
    253 	}
    254 
    255 	/* Reply to the requestor */
    256 	g_dbus_send_message(device->conn, reply);
    257 }
    258 
    259 static gboolean open_continue(gpointer user_data)
    260 {
    261 	struct serial_port *port = user_data;
    262 	int fd;
    263 	static int ntries = MAX_OPEN_TRIES;
    264 
    265 	if (!port->listener_id)
    266 		return FALSE; /* Owner exited */
    267 
    268 	fd = open(port->dev, O_RDONLY | O_NOCTTY);
    269 	if (fd < 0) {
    270 		int err = -errno;
    271 		error("Could not open %s: %s (%d)",
    272 				port->dev, strerror(-err), -err);
    273 		if (!--ntries) {
    274 			/* Reporting error */
    275 			open_notify(fd, err, port);
    276 			ntries = MAX_OPEN_TRIES;
    277 			return FALSE;
    278 		}
    279 		return TRUE;
    280 	}
    281 
    282 	/* Connection succeeded */
    283 	open_notify(fd, 0, port);
    284 	return FALSE;
    285 }
    286 
    287 static int port_open(struct serial_port *port)
    288 {
    289 	int fd;
    290 
    291 	fd = open(port->dev, O_RDONLY | O_NOCTTY);
    292 	if (fd < 0) {
    293 		g_timeout_add(OPEN_WAIT, open_continue, port);
    294 		return -EINPROGRESS;
    295 	}
    296 
    297 	return fd;
    298 }
    299 
    300 static void rfcomm_connect_cb(GIOChannel *chan, GError *conn_err,
    301 							gpointer user_data)
    302 {
    303 	struct serial_port *port = user_data;
    304 	struct serial_device *device = port->device;
    305 	struct rfcomm_dev_req req;
    306 	int sk, fd;
    307 	DBusMessage *reply;
    308 
    309 	/* Owner exited? */
    310 	if (!port->listener_id)
    311 		return;
    312 
    313 	if (conn_err) {
    314 		error("%s", conn_err->message);
    315 		reply = btd_error_failed(port->msg, conn_err->message);
    316 		goto fail;
    317 	}
    318 
    319 	memset(&req, 0, sizeof(req));
    320 	req.dev_id = -1;
    321 	req.flags = (1 << RFCOMM_REUSE_DLC);
    322 	bacpy(&req.src, &device->src);
    323 	bacpy(&req.dst, &device->dst);
    324 	req.channel = port->channel;
    325 
    326 	g_io_channel_unref(port->io);
    327 	port->io = NULL;
    328 
    329 	sk = g_io_channel_unix_get_fd(chan);
    330 	port->id = ioctl(sk, RFCOMMCREATEDEV, &req);
    331 	if (port->id < 0) {
    332 		int err = -errno;
    333 		error("ioctl(RFCOMMCREATEDEV): %s (%d)", strerror(-err), -err);
    334 		reply = btd_error_failed(port->msg, strerror(-err));
    335 		g_io_channel_shutdown(chan, TRUE, NULL);
    336 		goto fail;
    337 	}
    338 
    339 	port->dev = g_strdup_printf("/dev/rfcomm%d", port->id);
    340 
    341 	DBG("Serial port %s created", port->dev);
    342 
    343 	g_io_channel_shutdown(chan, TRUE, NULL);
    344 
    345 	/* Addressing connect port */
    346 	fd = port_open(port);
    347 	if (fd < 0)
    348 		/* Open in progress: Wait the callback */
    349 		return;
    350 
    351 	open_notify(fd, 0, port);
    352 	return;
    353 
    354 fail:
    355 	g_dbus_send_message(device->conn, reply);
    356 	g_dbus_remove_watch(device->conn, port->listener_id);
    357 	port->listener_id = 0;
    358 }
    359 
    360 static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
    361 {
    362 	struct serial_port *port = user_data;
    363 	struct serial_device *device = port->device;
    364 	sdp_record_t *record = NULL;
    365 	sdp_list_t *protos;
    366 	DBusMessage *reply;
    367 	GError *gerr = NULL;
    368 
    369 	if (!port->listener_id) {
    370 		reply = NULL;
    371 		goto failed;
    372 	}
    373 
    374 	if (err < 0) {
    375 		error("Unable to get service record: %s (%d)", strerror(-err),
    376 			-err);
    377 		reply = btd_error_failed(port->msg, strerror(-err));
    378 		goto failed;
    379 	}
    380 
    381 	if (!recs || !recs->data) {
    382 		error("No record found");
    383 		reply = btd_error_failed(port->msg, "No record found");
    384 		goto failed;
    385 	}
    386 
    387 	record = recs->data;
    388 
    389 	if (sdp_get_access_protos(record, &protos) < 0) {
    390 		error("Unable to get access protos from port record");
    391 		reply = btd_error_failed(port->msg, "Invalid channel");
    392 		goto failed;
    393 	}
    394 
    395 	port->channel = sdp_get_proto_port(protos, RFCOMM_UUID);
    396 
    397 	sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL);
    398 	sdp_list_free(protos, NULL);
    399 
    400 	port->io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, port,
    401 				NULL, &gerr,
    402 				BT_IO_OPT_SOURCE_BDADDR, &device->src,
    403 				BT_IO_OPT_DEST_BDADDR, &device->dst,
    404 				BT_IO_OPT_CHANNEL, port->channel,
    405 				BT_IO_OPT_INVALID);
    406 	if (!port->io) {
    407 		error("%s", gerr->message);
    408 		reply = btd_error_failed(port->msg, gerr->message);
    409 		g_error_free(gerr);
    410 		goto failed;
    411 	}
    412 
    413 	return;
    414 
    415 failed:
    416 	g_dbus_remove_watch(device->conn, port->listener_id);
    417 	port->listener_id = 0;
    418 	g_dbus_send_message(device->conn, reply);
    419 }
    420 
    421 static int connect_port(struct serial_port *port)
    422 {
    423 	struct serial_device *device = port->device;
    424 	uuid_t uuid;
    425 	int err;
    426 
    427 	if (!port->uuid)
    428 		goto connect;
    429 
    430 	err = bt_string2uuid(&uuid, port->uuid);
    431 	if (err < 0)
    432 		return err;
    433 
    434 	sdp_uuid128_to_uuid(&uuid);
    435 
    436 	return bt_search_service(&device->src, &device->dst, &uuid,
    437 				get_record_cb, port, NULL);
    438 
    439 connect:
    440 	port->io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, port,
    441 				NULL, NULL,
    442 				BT_IO_OPT_SOURCE_BDADDR, &device->src,
    443 				BT_IO_OPT_DEST_BDADDR, &device->dst,
    444 				BT_IO_OPT_CHANNEL, port->channel,
    445 				BT_IO_OPT_INVALID);
    446 	if (port->io)
    447 		return 0;
    448 
    449 	return -errno;
    450 }
    451 
    452 static struct serial_port *create_port(struct serial_device *device,
    453 					const char *uuid, uint8_t channel)
    454 {
    455 	struct serial_port *port;
    456 
    457 	port = g_new0(struct serial_port, 1);
    458 	port->uuid = g_strdup(uuid);
    459 	port->channel = channel;
    460 	port->device = device;
    461 	port->id = -1;
    462 	port->fd = -1;
    463 
    464 	device->ports = g_slist_append(device->ports, port);
    465 
    466 	return port;
    467 }
    468 
    469 static DBusMessage *port_connect(DBusConnection *conn,
    470 					DBusMessage *msg, void *user_data)
    471 {
    472 	struct serial_device *device = user_data;
    473 	struct serial_port *port;
    474 	const char *pattern;
    475 	int err;
    476 
    477 	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
    478 						DBUS_TYPE_INVALID) == FALSE)
    479 		return NULL;
    480 
    481 	port = find_port(device->ports, pattern);
    482 	if (!port) {
    483 		char *endptr = NULL;
    484 		int channel;
    485 
    486 		channel = strtol(pattern, &endptr, 10);
    487 		if ((endptr && *endptr != '\0') || channel < 1 || channel > 30)
    488 			return btd_error_does_not_exist(msg);
    489 
    490 		port = create_port(device, NULL, channel);
    491 	}
    492 
    493 	if (port->listener_id)
    494 		return btd_error_failed(msg, "Port already in use");
    495 
    496 	port->listener_id = g_dbus_add_disconnect_watch(conn,
    497 						dbus_message_get_sender(msg),
    498 						port_owner_exited, port,
    499 						NULL);
    500 	port->msg = dbus_message_ref(msg);
    501 
    502 	err = connect_port(port);
    503 	if (err < 0) {
    504 		error("%s", strerror(-err));
    505 		g_dbus_remove_watch(conn, port->listener_id);
    506 		port->listener_id = 0;
    507 
    508 		return btd_error_failed(msg, strerror(-err));
    509 	}
    510 
    511 	return NULL;
    512 }
    513 
    514 static DBusMessage *port_disconnect(DBusConnection *conn,
    515 					DBusMessage *msg, void *user_data)
    516 {
    517 	struct serial_device *device = user_data;
    518 	struct serial_port *port;
    519 	const char *dev, *owner, *caller;
    520 
    521 	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &dev,
    522 						DBUS_TYPE_INVALID) == FALSE)
    523 		return NULL;
    524 
    525 	port = find_port(device->ports, dev);
    526 	if (!port)
    527 		return btd_error_does_not_exist(msg);
    528 
    529 	if (!port->listener_id)
    530 		return btd_error_not_connected(msg);
    531 
    532 	owner = dbus_message_get_sender(port->msg);
    533 	caller = dbus_message_get_sender(msg);
    534 	if (!g_str_equal(owner, caller))
    535 		return btd_error_not_authorized(msg);
    536 
    537 	port_release(port);
    538 
    539 	g_dbus_remove_watch(conn, port->listener_id);
    540 	port->listener_id = 0;
    541 
    542 	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
    543 }
    544 
    545 static GDBusMethodTable port_methods[] = {
    546 	{ "Connect",    "s", "s", port_connect, G_DBUS_METHOD_FLAG_ASYNC },
    547 	{ "Disconnect", "s", "",  port_disconnect },
    548 	{ }
    549 };
    550 
    551 static struct serial_device *create_serial_device(DBusConnection *conn,
    552 					const char *path, bdaddr_t *src,
    553 					bdaddr_t *dst)
    554 {
    555 	struct serial_device *device;
    556 
    557 	device = g_new0(struct serial_device, 1);
    558 	device->conn = dbus_connection_ref(conn);
    559 	bacpy(&device->dst, dst);
    560 	bacpy(&device->src, src);
    561 	device->path = g_strdup(path);
    562 
    563 	if (!g_dbus_register_interface(conn, path,
    564 				SERIAL_PORT_INTERFACE,
    565 				port_methods, NULL, NULL,
    566 				device, path_unregister)) {
    567 		error("D-Bus failed to register %s interface",
    568 				SERIAL_PORT_INTERFACE);
    569 		serial_device_free(device);
    570 		return NULL;
    571 	}
    572 
    573 	DBG("Registered interface %s on path %s",
    574 		SERIAL_PORT_INTERFACE, path);
    575 
    576 	return device;
    577 }
    578 
    579 int port_register(DBusConnection *conn, const char *path, bdaddr_t *src,
    580 			bdaddr_t *dst, const char *uuid, uint8_t channel)
    581 {
    582 	struct serial_device *device;
    583 	struct serial_port *port;
    584 
    585 	device = find_device(devices, path);
    586 	if (!device) {
    587 		device = create_serial_device(conn, path, src, dst);
    588 		if (!device)
    589 			return -1;
    590 		devices = g_slist_append(devices, device);
    591 	}
    592 
    593 	if (find_port(device->ports, uuid))
    594 		return 0;
    595 
    596 	port = g_new0(struct serial_port, 1);
    597 	port->uuid = g_strdup(uuid);
    598 	port->channel = channel;
    599 	port->device = device;
    600 	port->id = -1;
    601 	port->fd = -1;
    602 
    603 	device->ports = g_slist_append(device->ports, port);
    604 
    605 	return 0;
    606 }
    607 
    608 int port_unregister(const char *path)
    609 {
    610 	struct serial_device *device;
    611 
    612 	device = find_device(devices, path);
    613 	if (!device)
    614 		return -ENOENT;
    615 
    616 	g_slist_foreach(device->ports, (GFunc) serial_port_free, NULL);
    617 	g_slist_free(device->ports);
    618 
    619 	g_dbus_unregister_interface(device->conn, path, SERIAL_PORT_INTERFACE);
    620 
    621 	return 0;
    622 }
    623