3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
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.
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.
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
35 #include <sys/ioctl.h>
36 #include <sys/types.h>
40 #include <bluetooth/bluetooth.h>
41 #include <bluetooth/rfcomm.h>
42 #include <bluetooth/sdp.h>
43 #include <bluetooth/sdp_lib.h>
48 #include "../src/dbus-common.h"
51 #include "glib-helper.h"
52 #include "sdp-client.h"
62 #define SERIAL_PORT_INTERFACE "org.bluez.Serial"
64 #define MAX_OPEN_TRIES 5
65 #define OPEN_WAIT 300 /* ms. udev node creation retry wait */
67 struct serial_device {
68 DBusConnection *conn; /* for name listener handling */
69 bdaddr_t src; /* Source (local) address */
70 bdaddr_t dst; /* Destination address */
71 char *path; /* Device path */
72 GSList *ports; /* Available ports */
76 DBusMessage *msg; /* for name listener handling */
77 int16_t id; /* RFCOMM device id */
78 uint8_t channel; /* RFCOMM channel */
79 char *uuid; /* service identification */
80 char *dev; /* RFCOMM device name */
81 int fd; /* Opened file descriptor */
82 GIOChannel *io; /* BtIO channel */
84 struct serial_device *device;
87 static GSList *devices = NULL;
89 static struct serial_device *find_device(GSList *devices, const char *path)
93 for (l = devices; l != NULL; l = l->next) {
94 struct serial_device *device = l->data;
96 if (!strcmp(device->path, path))
103 static struct serial_port *find_port(GSList *ports, const char *pattern)
109 channel = strtol(pattern, &endptr, 10);
111 for (l = ports; l != NULL; l = l->next) {
112 struct serial_port *port = l->data;
116 if (port->uuid && !strcasecmp(port->uuid, pattern))
119 if (endptr && *endptr == '\0' && port->channel == channel)
122 if (port->dev && !strcmp(port->dev, pattern))
128 uuid_str = bt_name2string(pattern);
132 ret = strcasecmp(port->uuid, uuid_str);
141 static int port_release(struct serial_port *port)
143 struct rfcomm_dev_req req;
149 g_io_channel_shutdown(port->io, TRUE, NULL);
150 g_io_channel_unref(port->io);
153 bt_cancel_discovery(&port->device->src,
159 DBG("Serial port %s released", port->dev);
161 rfcomm_ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM);
170 memset(&req, 0, sizeof(req));
171 req.dev_id = port->id;
174 * We are hitting a kernel bug inside RFCOMM code when
175 * RFCOMM_HANGUP_NOW bit is set on request's flags passed to
176 * ioctl(RFCOMMRELEASEDEV)!
178 req.flags = (1 << RFCOMM_HANGUP_NOW);
180 if (ioctl(rfcomm_ctl, RFCOMMRELEASEDEV, &req) < 0) {
182 error("Can't release device %s: %s (%d)",
183 port->dev, strerror(-err), -err);
193 static void serial_port_free(void *data)
195 struct serial_port *port = data;
196 struct serial_device *device = port->device;
198 if (device && port->listener_id > 0)
199 g_dbus_remove_watch(device->conn, port->listener_id);
207 static void serial_device_free(void *data)
209 struct serial_device *device = data;
211 g_free(device->path);
213 dbus_connection_unref(device->conn);
217 static void port_owner_exited(DBusConnection *conn, void *user_data)
219 struct serial_port *port = user_data;
223 port->listener_id = 0;
226 static void path_unregister(void *data)
228 struct serial_device *device = data;
230 DBG("Unregistered interface %s on path %s", SERIAL_PORT_INTERFACE,
233 devices = g_slist_remove(devices, device);
234 serial_device_free(device);
237 void port_release_all(void)
239 g_slist_free_full(devices, serial_device_free);
242 static void open_notify(int fd, int err, struct serial_port *port)
244 struct serial_device *device = port->device;
248 /* Max tries exceeded */
250 reply = btd_error_failed(port->msg, strerror(-err));
253 reply = g_dbus_create_reply(port->msg,
254 DBUS_TYPE_STRING, &port->dev,
258 /* Reply to the requestor */
259 g_dbus_send_message(device->conn, reply);
262 static gboolean open_continue(gpointer user_data)
264 struct serial_port *port = user_data;
266 static int ntries = MAX_OPEN_TRIES;
268 if (!port->listener_id)
269 return FALSE; /* Owner exited */
271 fd = open(port->dev, O_RDONLY | O_NOCTTY);
274 error("Could not open %s: %s (%d)",
275 port->dev, strerror(-err), -err);
277 /* Reporting error */
278 open_notify(fd, err, port);
279 ntries = MAX_OPEN_TRIES;
285 /* Connection succeeded */
286 open_notify(fd, 0, port);
290 static int port_open(struct serial_port *port)
294 fd = open(port->dev, O_RDONLY | O_NOCTTY);
296 g_timeout_add(OPEN_WAIT, open_continue, port);
303 static void rfcomm_connect_cb(GIOChannel *chan, GError *conn_err,
306 struct serial_port *port = user_data;
307 struct serial_device *device = port->device;
308 struct rfcomm_dev_req req;
313 if (!port->listener_id)
317 error("%s", conn_err->message);
318 reply = btd_error_failed(port->msg, conn_err->message);
322 sk = g_io_channel_unix_get_fd(chan);
324 if (dbus_message_has_member(port->msg, "ConnectFD")) {
325 reply = g_dbus_create_reply(port->msg, DBUS_TYPE_UNIX_FD, &sk,
327 g_dbus_send_message(device->conn, reply);
331 g_dbus_remove_watch(device->conn, port->listener_id);
332 port->listener_id = 0;
337 memset(&req, 0, sizeof(req));
339 req.flags = (1 << RFCOMM_REUSE_DLC);
340 bacpy(&req.src, &device->src);
341 bacpy(&req.dst, &device->dst);
342 req.channel = port->channel;
344 g_io_channel_unref(port->io);
347 port->id = ioctl(sk, RFCOMMCREATEDEV, &req);
350 error("ioctl(RFCOMMCREATEDEV): %s (%d)", strerror(-err), -err);
351 reply = btd_error_failed(port->msg, strerror(-err));
352 g_io_channel_shutdown(chan, TRUE, NULL);
356 port->dev = g_strdup_printf("/dev/rfcomm%d", port->id);
358 DBG("Serial port %s created", port->dev);
360 g_io_channel_shutdown(chan, TRUE, NULL);
362 /* Addressing connect port */
363 fd = port_open(port);
365 /* Open in progress: Wait the callback */
368 open_notify(fd, 0, port);
372 g_dbus_send_message(device->conn, reply);
373 g_dbus_remove_watch(device->conn, port->listener_id);
374 port->listener_id = 0;
377 static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
379 struct serial_port *port = user_data;
380 struct serial_device *device = port->device;
381 sdp_record_t *record = NULL;
386 if (!port->listener_id)
390 error("Unable to get service record: %s (%d)", strerror(-err),
392 reply = btd_error_failed(port->msg, strerror(-err));
396 if (!recs || !recs->data) {
397 error("No record found");
398 reply = btd_error_failed(port->msg, "No record found");
404 if (sdp_get_access_protos(record, &protos) < 0) {
405 error("Unable to get access protos from port record");
406 reply = btd_error_failed(port->msg, "Invalid channel");
410 port->channel = sdp_get_proto_port(protos, RFCOMM_UUID);
412 sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL);
413 sdp_list_free(protos, NULL);
415 port->io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, port,
417 BT_IO_OPT_SOURCE_BDADDR, &device->src,
418 BT_IO_OPT_DEST_BDADDR, &device->dst,
419 BT_IO_OPT_CHANNEL, port->channel,
420 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
423 error("%s", gerr->message);
424 reply = btd_error_failed(port->msg, gerr->message);
432 g_dbus_remove_watch(device->conn, port->listener_id);
433 port->listener_id = 0;
434 g_dbus_send_message(device->conn, reply);
437 static int connect_port(struct serial_port *port)
439 struct serial_device *device = port->device;
446 err = bt_string2uuid(&uuid, port->uuid);
450 sdp_uuid128_to_uuid(&uuid);
452 return bt_search_service(&device->src, &device->dst, &uuid,
453 get_record_cb, port, NULL);
456 port->io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, port,
458 BT_IO_OPT_SOURCE_BDADDR, &device->src,
459 BT_IO_OPT_DEST_BDADDR, &device->dst,
460 BT_IO_OPT_CHANNEL, port->channel,
461 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
463 if (port->io == NULL)
469 static struct serial_port *create_port(struct serial_device *device,
470 const char *uuid, uint8_t channel)
472 struct serial_port *port;
474 port = g_new0(struct serial_port, 1);
475 port->uuid = g_strdup(uuid);
476 port->channel = channel;
477 port->device = device;
481 device->ports = g_slist_append(device->ports, port);
486 static DBusMessage *port_connect(DBusConnection *conn,
487 DBusMessage *msg, void *user_data)
489 struct serial_device *device = user_data;
490 struct serial_port *port;
494 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
495 DBUS_TYPE_INVALID) == FALSE)
498 port = find_port(device->ports, pattern);
503 channel = strtol(pattern, &endptr, 10);
504 if ((endptr && *endptr != '\0') || channel < 1 || channel > 30)
505 return btd_error_does_not_exist(msg);
507 port = create_port(device, NULL, channel);
510 if (port->listener_id)
511 return btd_error_failed(msg, "Port already in use");
513 port->listener_id = g_dbus_add_disconnect_watch(conn,
514 dbus_message_get_sender(msg),
515 port_owner_exited, port,
518 port->msg = dbus_message_ref(msg);
520 err = connect_port(port);
522 error("%s", strerror(-err));
523 g_dbus_remove_watch(conn, port->listener_id);
524 port->listener_id = 0;
526 return btd_error_failed(msg, strerror(-err));
532 static DBusMessage *port_disconnect(DBusConnection *conn,
533 DBusMessage *msg, void *user_data)
535 struct serial_device *device = user_data;
536 struct serial_port *port;
537 const char *dev, *owner, *caller;
539 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &dev,
540 DBUS_TYPE_INVALID) == FALSE)
543 port = find_port(device->ports, dev);
545 return btd_error_does_not_exist(msg);
547 if (!port->listener_id)
548 return btd_error_not_connected(msg);
550 owner = dbus_message_get_sender(port->msg);
551 caller = dbus_message_get_sender(msg);
552 if (!g_str_equal(owner, caller))
553 return btd_error_not_authorized(msg);
557 g_dbus_remove_watch(conn, port->listener_id);
558 port->listener_id = 0;
560 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
563 static const GDBusMethodTable port_methods[] = {
564 { GDBUS_ASYNC_METHOD("Connect",
565 GDBUS_ARGS({ "pattern", "s" }), GDBUS_ARGS({ "tty", "s" }),
567 { GDBUS_ASYNC_METHOD("ConnectFD",
568 GDBUS_ARGS({ "pattern", "s" }), GDBUS_ARGS({ "fd", "s" }),
570 { GDBUS_METHOD("Disconnect",
571 GDBUS_ARGS({ "device", "s" }), NULL,
576 static struct serial_device *create_serial_device(DBusConnection *conn,
577 const char *path, bdaddr_t *src,
580 struct serial_device *device;
582 device = g_new0(struct serial_device, 1);
583 device->conn = dbus_connection_ref(conn);
584 bacpy(&device->dst, dst);
585 bacpy(&device->src, src);
586 device->path = g_strdup(path);
588 if (!g_dbus_register_interface(conn, path,
589 SERIAL_PORT_INTERFACE,
590 port_methods, NULL, NULL,
591 device, path_unregister)) {
592 error("D-Bus failed to register %s interface",
593 SERIAL_PORT_INTERFACE);
594 serial_device_free(device);
598 DBG("Registered interface %s on path %s",
599 SERIAL_PORT_INTERFACE, path);
604 int port_register(DBusConnection *conn, const char *path, bdaddr_t *src,
605 bdaddr_t *dst, const char *uuid, uint8_t channel)
607 struct serial_device *device;
608 struct serial_port *port;
610 device = find_device(devices, path);
612 device = create_serial_device(conn, path, src, dst);
615 devices = g_slist_append(devices, device);
618 if (find_port(device->ports, uuid))
621 port = g_new0(struct serial_port, 1);
622 port->uuid = g_strdup(uuid);
623 port->channel = channel;
624 port->device = device;
628 device->ports = g_slist_append(device->ports, port);
633 int port_unregister(const char *path)
635 struct serial_device *device;
637 device = find_device(devices, path);
641 g_slist_free_full(device->ports, serial_port_free);
643 g_dbus_unregister_interface(device->conn, path, SERIAL_PORT_INTERFACE);