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