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