• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@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 
find_device(GSList * devices,const char * path)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 
find_port(GSList * ports,const char * pattern)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 
port_release(struct serial_port * port)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 
serial_port_free(struct serial_port * port)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 
serial_device_free(struct serial_device * device)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 
port_owner_exited(DBusConnection * conn,void * user_data)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 
path_unregister(void * data)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 
port_release_all(void)233 void port_release_all(void)
234 {
235 	g_slist_foreach(devices, (GFunc) serial_device_free, NULL);
236 	g_slist_free(devices);
237 }
238 
open_notify(int fd,int err,struct serial_port * port)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 
open_continue(gpointer user_data)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 
port_open(struct serial_port * port)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 
rfcomm_connect_cb(GIOChannel * chan,GError * conn_err,gpointer user_data)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 
get_record_cb(sdp_list_t * recs,int err,gpointer user_data)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 
connect_port(struct serial_port * port)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 
create_port(struct serial_device * device,const char * uuid,uint8_t channel)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 
port_connect(DBusConnection * conn,DBusMessage * msg,void * user_data)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 
port_disconnect(DBusConnection * conn,DBusMessage * msg,void * user_data)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 
create_serial_device(DBusConnection * conn,const char * path,bdaddr_t * src,bdaddr_t * dst)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 
port_register(DBusConnection * conn,const char * path,bdaddr_t * src,bdaddr_t * dst,const char * uuid,uint8_t channel)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 
port_unregister(const char * path)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