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 <ctype.h>
29 #include <dirent.h>
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <termios.h>
36 #include <unistd.h>
37 #include <arpa/inet.h>
38 #include <sys/param.h>
39 #include <sys/ioctl.h>
40 #include <sys/stat.h>
41 #include <sys/types.h>
42 #include <sys/un.h>
43
44 #include <bluetooth/bluetooth.h>
45 #include <bluetooth/hci.h>
46 #include <bluetooth/hci_lib.h>
47 #include <bluetooth/sdp.h>
48 #include <bluetooth/sdp_lib.h>
49 #include <bluetooth/rfcomm.h>
50
51 #include <glib.h>
52 #include <gdbus.h>
53
54 #include "../src/dbus-common.h"
55 #include "../src/adapter.h"
56
57 #include "log.h"
58 #include "textfile.h"
59
60 #include "error.h"
61 #include "sdpd.h"
62 #include "glib-helper.h"
63 #include "btio.h"
64 #include "proxy.h"
65
66 #define SERIAL_PROXY_INTERFACE "org.bluez.SerialProxy"
67 #define SERIAL_MANAGER_INTERFACE "org.bluez.SerialProxyManager"
68 #define BUF_SIZE 1024
69
70 typedef enum {
71 TTY_PROXY,
72 UNIX_SOCKET_PROXY,
73 TCP_SOCKET_PROXY,
74 UNKNOWN_PROXY_TYPE = 0xFF
75 } proxy_type_t;
76
77 struct serial_adapter {
78 struct btd_adapter *btd_adapter; /* Adapter pointer */
79 DBusConnection *conn; /* Adapter connection */
80 GSList *proxies; /* Proxies list */
81 };
82
83 struct serial_proxy {
84 bdaddr_t src; /* Local address */
85 bdaddr_t dst; /* Remote address */
86 char *path; /* Proxy path */
87 char *uuid128; /* UUID 128 */
88 char *address; /* TTY or Unix socket name */
89 char *owner; /* Application bus name */
90 guint watch; /* Application watch */
91 short int port; /* TCP port */
92 proxy_type_t type; /* TTY or Unix socket */
93 struct termios sys_ti; /* Default TTY setting */
94 struct termios proxy_ti; /* Proxy TTY settings */
95 uint8_t channel; /* RFCOMM channel */
96 uint32_t record_id; /* Service record id */
97 GIOChannel *io; /* Server listen */
98 GIOChannel *rfcomm; /* Remote RFCOMM channel*/
99 GIOChannel *local; /* Local channel: TTY or Unix socket */
100 struct serial_adapter *adapter; /* Adapter pointer */
101 };
102
103 static GSList *adapters = NULL;
104 static int sk_counter = 0;
105
disable_proxy(struct serial_proxy * prx)106 static void disable_proxy(struct serial_proxy *prx)
107 {
108 if (prx->rfcomm) {
109 g_io_channel_shutdown(prx->rfcomm, TRUE, NULL);
110 g_io_channel_unref(prx->rfcomm);
111 prx->rfcomm = NULL;
112 }
113
114 if (prx->local) {
115 g_io_channel_shutdown(prx->local, TRUE, NULL);
116 g_io_channel_unref(prx->local);
117 prx->local = NULL;
118 }
119
120 remove_record_from_server(prx->record_id);
121 prx->record_id = 0;
122
123 g_io_channel_unref(prx->io);
124 prx->io = NULL;
125 }
126
proxy_free(struct serial_proxy * prx)127 static void proxy_free(struct serial_proxy *prx)
128 {
129 g_free(prx->owner);
130 g_free(prx->path);
131 g_free(prx->address);
132 g_free(prx->uuid128);
133 g_free(prx);
134 }
135
does_not_exist(DBusMessage * msg,const char * description)136 static inline DBusMessage *does_not_exist(DBusMessage *msg,
137 const char *description)
138 {
139 return g_dbus_create_error(msg, ERROR_INTERFACE ".DoesNotExist",
140 description);
141 }
142
invalid_arguments(DBusMessage * msg,const char * description)143 static inline DBusMessage *invalid_arguments(DBusMessage *msg,
144 const char *description)
145 {
146 return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
147 description);
148 }
149
failed(DBusMessage * msg,const char * description)150 static inline DBusMessage *failed(DBusMessage *msg, const char *description)
151 {
152 return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
153 description);
154 }
155
add_lang_attr(sdp_record_t * r)156 static void add_lang_attr(sdp_record_t *r)
157 {
158 sdp_lang_attr_t base_lang;
159 sdp_list_t *langs = 0;
160
161 /* UTF-8 MIBenum (http://www.iana.org/assignments/character-sets) */
162 base_lang.code_ISO639 = (0x65 << 8) | 0x6e;
163 base_lang.encoding = 106;
164 base_lang.base_offset = SDP_PRIMARY_LANG_BASE;
165 langs = sdp_list_append(0, &base_lang);
166 sdp_set_lang_attr(r, langs);
167 sdp_list_free(langs, 0);
168 }
169
proxy_record_new(const char * uuid128,uint8_t channel)170 static sdp_record_t *proxy_record_new(const char *uuid128, uint8_t channel)
171 {
172 sdp_list_t *apseq, *aproto, *profiles, *proto[2], *root, *svclass_id;
173 uuid_t uuid, root_uuid, l2cap, rfcomm;
174 sdp_profile_desc_t profile;
175 sdp_record_t *record;
176 sdp_data_t *ch;
177
178 record = sdp_record_alloc();
179 if (!record)
180 return NULL;
181
182 sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
183 root = sdp_list_append(NULL, &root_uuid);
184 sdp_set_browse_groups(record, root);
185 sdp_list_free(root, NULL);
186
187 bt_string2uuid(&uuid, uuid128);
188 sdp_uuid128_to_uuid(&uuid);
189 svclass_id = sdp_list_append(NULL, &uuid);
190 sdp_set_service_classes(record, svclass_id);
191 sdp_list_free(svclass_id, NULL);
192
193 sdp_uuid16_create(&profile.uuid, SERIAL_PORT_PROFILE_ID);
194 profile.version = 0x0100;
195 profiles = sdp_list_append(NULL, &profile);
196 sdp_set_profile_descs(record, profiles);
197 sdp_list_free(profiles, NULL);
198
199 sdp_uuid16_create(&l2cap, L2CAP_UUID);
200 proto[0] = sdp_list_append(NULL, &l2cap);
201 apseq = sdp_list_append(NULL, proto[0]);
202
203 sdp_uuid16_create(&rfcomm, RFCOMM_UUID);
204 proto[1] = sdp_list_append(NULL, &rfcomm);
205 ch = sdp_data_alloc(SDP_UINT8, &channel);
206 proto[1] = sdp_list_append(proto[1], ch);
207 apseq = sdp_list_append(apseq, proto[1]);
208
209 aproto = sdp_list_append(NULL, apseq);
210 sdp_set_access_protos(record, aproto);
211
212 add_lang_attr(record);
213
214 sdp_set_info_attr(record, "Serial Proxy", NULL, "Serial Proxy");
215
216 sdp_data_free(ch);
217 sdp_list_free(proto[0], NULL);
218 sdp_list_free(proto[1], NULL);
219 sdp_list_free(apseq, NULL);
220 sdp_list_free(aproto, NULL);
221
222 return record;
223 }
224
channel_write(GIOChannel * chan,char * buf,size_t size)225 static GIOError channel_write(GIOChannel *chan, char *buf, size_t size)
226 {
227 GIOError err = G_IO_ERROR_NONE;
228 gsize wbytes, written;
229
230 wbytes = written = 0;
231 while (wbytes < size) {
232 err = g_io_channel_write(chan,
233 buf + wbytes,
234 size - wbytes,
235 &written);
236
237 if (err != G_IO_ERROR_NONE)
238 return err;
239
240 wbytes += written;
241 }
242
243 return err;
244 }
245
forward_data(GIOChannel * chan,GIOCondition cond,gpointer data)246 static gboolean forward_data(GIOChannel *chan, GIOCondition cond, gpointer data)
247 {
248 char buf[BUF_SIZE];
249 struct serial_proxy *prx = data;
250 GIOChannel *dest;
251 GIOError err;
252 size_t rbytes;
253
254 if (cond & G_IO_NVAL)
255 return FALSE;
256
257 dest = (chan == prx->rfcomm) ? prx->local : prx->rfcomm;
258
259 if (cond & (G_IO_HUP | G_IO_ERR)) {
260 /* Try forward remaining data */
261 do {
262 rbytes = 0;
263 err = g_io_channel_read(chan, buf, sizeof(buf), &rbytes);
264 if (err != G_IO_ERROR_NONE || rbytes == 0)
265 break;
266
267 err = channel_write(dest, buf, rbytes);
268 } while (err == G_IO_ERROR_NONE);
269
270 g_io_channel_shutdown(prx->local, TRUE, NULL);
271 g_io_channel_unref(prx->local);
272 prx->local = NULL;
273
274 g_io_channel_shutdown(prx->rfcomm, TRUE, NULL);
275 g_io_channel_unref(prx->rfcomm);
276 prx->rfcomm = NULL;
277
278 return FALSE;
279 }
280
281 rbytes = 0;
282 err = g_io_channel_read(chan, buf, sizeof(buf), &rbytes);
283 if (err != G_IO_ERROR_NONE)
284 return FALSE;
285
286 err = channel_write(dest, buf, rbytes);
287 if (err != G_IO_ERROR_NONE)
288 return FALSE;
289
290 return TRUE;
291 }
292
unix_socket_connect(const char * address)293 static inline int unix_socket_connect(const char *address)
294 {
295 struct sockaddr_un addr;
296 int err, sk;
297
298 memset(&addr, 0, sizeof(addr));
299 addr.sun_family = PF_UNIX;
300
301 if (strncmp("x00", address, 3) == 0) {
302 /*
303 * Abstract namespace: first byte NULL, x00
304 * must be removed from the original address.
305 */
306 strncpy(addr.sun_path + 1, address + 3,
307 sizeof(addr.sun_path) - 2);
308 } else {
309 /* Filesystem address */
310 strncpy(addr.sun_path, address, sizeof(addr.sun_path) - 1);
311 }
312
313 /* Unix socket */
314 sk = socket(AF_UNIX, SOCK_STREAM, 0);
315 if (sk < 0) {
316 err = errno;
317 error("Unix socket(%s) create failed: %s(%d)",
318 address, strerror(err), err);
319 return -err;
320 }
321
322 if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
323 err = errno;
324 error("Unix socket(%s) connect failed: %s(%d)",
325 address, strerror(err), err);
326 close(sk);
327 errno = err;
328 return -err;
329 }
330
331 return sk;
332 }
333
tcp_socket_connect(const char * address)334 static int tcp_socket_connect(const char *address)
335 {
336 struct sockaddr_in addr;
337 int err, sk;
338 unsigned short int port;
339
340 memset(&addr, 0, sizeof(addr));
341
342 if (strncmp(address, "localhost", 9) != 0) {
343 error("Address should have the form localhost:port.");
344 return -1;
345 }
346 port = atoi(strchr(address, ':') + 1);
347 if (port <= 0) {
348 error("Invalid port '%d'.", port);
349 return -1;
350 }
351 addr.sin_family = AF_INET;
352 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
353 addr.sin_port = htons(port);
354
355 sk = socket(PF_INET, SOCK_STREAM, 0);
356 if (sk < 0) {
357 err = errno;
358 error("TCP socket(%s) create failed %s(%d)", address,
359 strerror(err), err);
360 return -err;
361 }
362 if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
363 err = errno;
364 error("TCP socket(%s) connect failed: %s(%d)",
365 address, strerror(err), err);
366 close(sk);
367 errno = err;
368 return -err;
369 }
370 return sk;
371 }
372
tty_open(const char * tty,struct termios * ti)373 static inline int tty_open(const char *tty, struct termios *ti)
374 {
375 int err, sk;
376
377 sk = open(tty, O_RDWR | O_NOCTTY);
378 if (sk < 0) {
379 err = errno;
380 error("Can't open TTY %s: %s(%d)", tty, strerror(err), err);
381 return -err;
382 }
383
384 if (ti && tcsetattr(sk, TCSANOW, ti) < 0) {
385 err = errno;
386 error("Can't change serial settings: %s(%d)",
387 strerror(err), err);
388 close(sk);
389 errno = err;
390 return -err;
391 }
392
393 return sk;
394 }
395
connect_event_cb(GIOChannel * chan,GError * conn_err,gpointer data)396 static void connect_event_cb(GIOChannel *chan, GError *conn_err, gpointer data)
397 {
398 struct serial_proxy *prx = data;
399 int sk;
400
401 if (conn_err) {
402 error("%s", conn_err->message);
403 goto drop;
404 }
405
406 /* Connect local */
407 switch (prx->type) {
408 case UNIX_SOCKET_PROXY:
409 sk = unix_socket_connect(prx->address);
410 break;
411 case TTY_PROXY:
412 sk = tty_open(prx->address, &prx->proxy_ti);
413 break;
414 case TCP_SOCKET_PROXY:
415 sk = tcp_socket_connect(prx->address);
416 break;
417 default:
418 sk = -1;
419 }
420
421 if (sk < 0)
422 goto drop;
423
424 prx->local = g_io_channel_unix_new(sk);
425
426 g_io_add_watch(prx->rfcomm,
427 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
428 forward_data, prx);
429
430 g_io_add_watch(prx->local,
431 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
432 forward_data, prx);
433
434 return;
435
436 drop:
437 g_io_channel_shutdown(prx->rfcomm, TRUE, NULL);
438 g_io_channel_unref(prx->rfcomm);
439 prx->rfcomm = NULL;
440 }
441
auth_cb(DBusError * derr,void * user_data)442 static void auth_cb(DBusError *derr, void *user_data)
443 {
444 struct serial_proxy *prx = user_data;
445 GError *err = NULL;
446
447 if (derr) {
448 error("Access denied: %s", derr->message);
449 goto reject;
450 }
451
452 if (!bt_io_accept(prx->rfcomm, connect_event_cb, prx, NULL,
453 &err)) {
454 error("bt_io_accept: %s", err->message);
455 g_error_free(err);
456 goto reject;
457 }
458
459 return;
460
461 reject:
462 g_io_channel_shutdown(prx->rfcomm, TRUE, NULL);
463 g_io_channel_unref(prx->rfcomm);
464 prx->rfcomm = NULL;
465 }
466
confirm_event_cb(GIOChannel * chan,gpointer user_data)467 static void confirm_event_cb(GIOChannel *chan, gpointer user_data)
468 {
469 struct serial_proxy *prx = user_data;
470 int perr;
471 char address[18];
472 GError *err = NULL;
473
474 bt_io_get(chan, BT_IO_RFCOMM, &err,
475 BT_IO_OPT_DEST_BDADDR, &prx->dst,
476 BT_IO_OPT_DEST, address,
477 BT_IO_OPT_INVALID);
478 if (err) {
479 error("%s", err->message);
480 g_error_free(err);
481 goto drop;
482 }
483
484 if (prx->rfcomm) {
485 error("Refusing connect from %s: Proxy already in use",
486 address);
487 goto drop;
488 }
489
490 DBG("Serial Proxy: incoming connect from %s", address);
491
492 prx->rfcomm = g_io_channel_ref(chan);
493
494 perr = btd_request_authorization(&prx->src, &prx->dst,
495 prx->uuid128, auth_cb, prx);
496 if (perr < 0) {
497 error("Refusing connect from %s: %s (%d)", address,
498 strerror(-perr), -perr);
499 g_io_channel_unref(prx->rfcomm);
500 prx->rfcomm = NULL;
501 goto drop;
502 }
503
504 return;
505
506 drop:
507 g_io_channel_shutdown(chan, TRUE, NULL);
508 }
509
enable_proxy(struct serial_proxy * prx)510 static int enable_proxy(struct serial_proxy *prx)
511 {
512 sdp_record_t *record;
513 GError *gerr = NULL;
514 int err;
515
516 if (prx->io)
517 return -EALREADY;
518
519 /* Listen */
520 prx->io = bt_io_listen(BT_IO_RFCOMM, NULL, confirm_event_cb, prx,
521 NULL, &gerr,
522 BT_IO_OPT_SOURCE_BDADDR, &prx->src,
523 BT_IO_OPT_INVALID);
524 if (!prx->io)
525 goto failed;
526
527 bt_io_get(prx->io, BT_IO_RFCOMM, &gerr,
528 BT_IO_OPT_CHANNEL, &prx->channel,
529 BT_IO_OPT_INVALID);
530 if (gerr) {
531 g_io_channel_unref(prx->io);
532 prx->io = NULL;
533 goto failed;
534 }
535
536 DBG("Allocated channel %d", prx->channel);
537
538 g_io_channel_set_close_on_unref(prx->io, TRUE);
539
540 record = proxy_record_new(prx->uuid128, prx->channel);
541 if (!record) {
542 g_io_channel_unref(prx->io);
543 return -ENOMEM;
544 }
545
546 err = add_record_to_server(&prx->src, record);
547 if (err < 0) {
548 sdp_record_free(record);
549 g_io_channel_unref(prx->io);
550 return err;
551 }
552
553 prx->record_id = record->handle;
554
555 return 0;
556
557 failed:
558 error("%s", gerr->message);
559 g_error_free(gerr);
560 return -EIO;
561
562 }
proxy_enable(DBusConnection * conn,DBusMessage * msg,void * data)563 static DBusMessage *proxy_enable(DBusConnection *conn,
564 DBusMessage *msg, void *data)
565 {
566 struct serial_proxy *prx = data;
567 int err;
568
569 err = enable_proxy(prx);
570 if (err == -EALREADY)
571 return failed(msg, "Already enabled");
572 else if (err == -ENOMEM)
573 return failed(msg, "Unable to allocate new service record");
574 else if (err < 0)
575 return g_dbus_create_error(msg, ERROR_INTERFACE "Failed",
576 "Proxy enable failed (%s)", strerror(-err));
577
578 return dbus_message_new_method_return(msg);
579 }
580
proxy_disable(DBusConnection * conn,DBusMessage * msg,void * data)581 static DBusMessage *proxy_disable(DBusConnection *conn,
582 DBusMessage *msg, void *data)
583 {
584 struct serial_proxy *prx = data;
585
586 if (!prx->io)
587 return failed(msg, "Not enabled");
588
589 /* Remove the watches and unregister the record */
590 disable_proxy(prx);
591
592 return dbus_message_new_method_return(msg);
593 }
594
proxy_get_info(DBusConnection * conn,DBusMessage * msg,void * data)595 static DBusMessage *proxy_get_info(DBusConnection *conn,
596 DBusMessage *msg, void *data)
597 {
598 struct serial_proxy *prx = data;
599 DBusMessage *reply;
600 DBusMessageIter iter, dict;
601 dbus_bool_t boolean;
602
603 reply = dbus_message_new_method_return(msg);
604 if (!reply)
605 return NULL;
606
607 dbus_message_iter_init_append(reply, &iter);
608
609 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
610 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
611 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
612 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
613
614 dict_append_entry(&dict, "uuid", DBUS_TYPE_STRING, &prx->uuid128);
615
616 dict_append_entry(&dict, "address", DBUS_TYPE_STRING, &prx->address);
617
618 if (prx->channel)
619 dict_append_entry(&dict, "channel",
620 DBUS_TYPE_BYTE, &prx->channel);
621
622 boolean = (prx->io ? TRUE : FALSE);
623 dict_append_entry(&dict, "enabled", DBUS_TYPE_BOOLEAN, &boolean);
624
625 boolean = (prx->rfcomm ? TRUE : FALSE);
626 dict_append_entry(&dict, "connected", DBUS_TYPE_BOOLEAN, &boolean);
627
628 /* If connected: append the remote address */
629 if (boolean) {
630 char bda[18];
631 const char *pstr = bda;
632
633 ba2str(&prx->dst, bda);
634 dict_append_entry(&dict, "address", DBUS_TYPE_STRING, &pstr);
635 }
636
637 dbus_message_iter_close_container(&iter, &dict);
638
639 return reply;
640 }
641
642 static struct {
643 const char *str;
644 speed_t speed;
645 } supported_speed[] = {
646 {"50", B50 },
647 {"300", B300 },
648 {"600", B600 },
649 {"1200", B1200 },
650 {"1800", B1800 },
651 {"2400", B2400 },
652 {"4800", B4800 },
653 {"9600", B9600 },
654 {"19200", B19200 },
655 {"38400", B38400 },
656 {"57600", B57600 },
657 {"115200", B115200 },
658 { NULL, B0 }
659 };
660
str2speed(const char * str,speed_t * speed)661 static speed_t str2speed(const char *str, speed_t *speed)
662 {
663 int i;
664
665 for (i = 0; supported_speed[i].str; i++) {
666 if (strcmp(supported_speed[i].str, str) != 0)
667 continue;
668
669 if (speed)
670 *speed = supported_speed[i].speed;
671
672 return supported_speed[i].speed;
673 }
674
675 return B0;
676 }
677
set_parity(const char * str,tcflag_t * ctrl)678 static int set_parity(const char *str, tcflag_t *ctrl)
679 {
680 if (strcasecmp("even", str) == 0) {
681 *ctrl |= PARENB;
682 *ctrl &= ~PARODD;
683 } else if (strcasecmp("odd", str) == 0) {
684 *ctrl |= PARENB;
685 *ctrl |= PARODD;
686 } else if (strcasecmp("mark", str) == 0)
687 *ctrl |= PARENB;
688 else if ((strcasecmp("none", str) == 0) ||
689 (strcasecmp("space", str) == 0))
690 *ctrl &= ~PARENB;
691 else
692 return -1;
693
694 return 0;
695 }
696
set_databits(uint8_t databits,tcflag_t * ctrl)697 static int set_databits(uint8_t databits, tcflag_t *ctrl)
698 {
699 if (databits < 5 || databits > 8)
700 return -EINVAL;
701
702 *ctrl &= ~CSIZE;
703 switch (databits) {
704 case 5:
705 *ctrl |= CS5;
706 break;
707 case 6:
708 *ctrl |= CS6;
709 break;
710 case 7:
711 *ctrl |= CS7;
712 break;
713 case 8:
714 *ctrl |= CS8;
715 break;
716 }
717
718 return 0;
719 }
720
set_stopbits(uint8_t stopbits,tcflag_t * ctrl)721 static int set_stopbits(uint8_t stopbits, tcflag_t *ctrl)
722 {
723 /* 1.5 will not be allowed */
724 switch (stopbits) {
725 case 1:
726 *ctrl &= ~CSTOPB;
727 return 0;
728 case 2:
729 *ctrl |= CSTOPB;
730 return 0;
731 }
732
733 return -EINVAL;
734 }
735
proxy_set_serial_params(DBusConnection * conn,DBusMessage * msg,void * data)736 static DBusMessage *proxy_set_serial_params(DBusConnection *conn,
737 DBusMessage *msg, void *data)
738 {
739 struct serial_proxy *prx = data;
740 const char *ratestr, *paritystr;
741 uint8_t databits, stopbits;
742 tcflag_t ctrl; /* Control mode flags */
743 speed_t speed = B0; /* In/Out speed */
744
745 /* Don't allow change TTY settings if it is open */
746 if (prx->local)
747 return failed(msg, "Not allowed");
748
749 if (!dbus_message_get_args(msg, NULL,
750 DBUS_TYPE_STRING, &ratestr,
751 DBUS_TYPE_BYTE, &databits,
752 DBUS_TYPE_BYTE, &stopbits,
753 DBUS_TYPE_STRING, &paritystr,
754 DBUS_TYPE_INVALID))
755 return NULL;
756
757 if (str2speed(ratestr, &speed) == B0)
758 return invalid_arguments(msg, "Invalid baud rate");
759
760 ctrl = prx->proxy_ti.c_cflag;
761 if (set_databits(databits, &ctrl) < 0)
762 return invalid_arguments(msg, "Invalid data bits");
763
764 if (set_stopbits(stopbits, &ctrl) < 0)
765 return invalid_arguments(msg, "Invalid stop bits");
766
767 if (set_parity(paritystr, &ctrl) < 0)
768 return invalid_arguments(msg, "Invalid parity");
769
770 prx->proxy_ti.c_cflag = ctrl;
771 prx->proxy_ti.c_cflag |= (CLOCAL | CREAD);
772 cfsetispeed(&prx->proxy_ti, speed);
773 cfsetospeed(&prx->proxy_ti, speed);
774
775 return dbus_message_new_method_return(msg);
776 }
777
778 static GDBusMethodTable proxy_methods[] = {
779 { "Enable", "", "", proxy_enable },
780 { "Disable", "", "", proxy_disable },
781 { "GetInfo", "", "a{sv}",proxy_get_info },
782 { "SetSerialParameters", "syys", "", proxy_set_serial_params },
783 { },
784 };
785
proxy_path_unregister(gpointer data)786 static void proxy_path_unregister(gpointer data)
787 {
788 struct serial_proxy *prx = data;
789 int sk;
790
791 DBG("Unregistered proxy: %s", prx->address);
792
793 if (prx->type != TTY_PROXY)
794 goto done;
795
796 /* Restore the initial TTY configuration */
797 sk = open(prx->address, O_RDWR | O_NOCTTY);
798 if (sk >= 0) {
799 tcsetattr(sk, TCSAFLUSH, &prx->sys_ti);
800 close(sk);
801 }
802 done:
803
804 proxy_free(prx);
805 }
806
register_proxy_object(struct serial_proxy * prx)807 static int register_proxy_object(struct serial_proxy *prx)
808 {
809 struct serial_adapter *adapter = prx->adapter;
810 char path[MAX_PATH_LENGTH + 1];
811
812 snprintf(path, MAX_PATH_LENGTH, "%s/proxy%d",
813 adapter_get_path(adapter->btd_adapter), sk_counter++);
814
815 if (!g_dbus_register_interface(adapter->conn, path,
816 SERIAL_PROXY_INTERFACE,
817 proxy_methods, NULL, NULL,
818 prx, proxy_path_unregister)) {
819 error("D-Bus failed to register %s path", path);
820 return -1;
821 }
822
823 prx->path = g_strdup(path);
824 adapter->proxies = g_slist_append(adapter->proxies, prx);
825
826 DBG("Registered proxy: %s", path);
827
828 return 0;
829 }
830
proxy_tty_register(struct serial_adapter * adapter,const char * uuid128,const char * address,struct termios * ti,struct serial_proxy ** proxy)831 static int proxy_tty_register(struct serial_adapter *adapter,
832 const char *uuid128, const char *address,
833 struct termios *ti,
834 struct serial_proxy **proxy)
835 {
836 struct termios sys_ti;
837 struct serial_proxy *prx;
838 int sk, ret;
839
840 sk = open(address, O_RDONLY | O_NOCTTY);
841 if (sk < 0) {
842 error("Cant open TTY: %s(%d)", strerror(errno), errno);
843 return -EINVAL;
844 }
845
846 prx = g_new0(struct serial_proxy, 1);
847 prx->address = g_strdup(address);
848 prx->uuid128 = g_strdup(uuid128);
849 prx->type = TTY_PROXY;
850 adapter_get_address(adapter->btd_adapter, &prx->src);
851 prx->adapter = adapter;
852
853 /* Current TTY settings */
854 memset(&sys_ti, 0, sizeof(sys_ti));
855 tcgetattr(sk, &sys_ti);
856 memcpy(&prx->sys_ti, &sys_ti, sizeof(sys_ti));
857 close(sk);
858
859 if (!ti) {
860 /* Use current settings */
861 memcpy(&prx->proxy_ti, &sys_ti, sizeof(sys_ti));
862 } else {
863 /* New TTY settings: user provided */
864 memcpy(&prx->proxy_ti, ti, sizeof(*ti));
865 }
866
867 ret = register_proxy_object(prx);
868 if (ret < 0) {
869 proxy_free(prx);
870 return ret;
871 }
872
873 *proxy = prx;
874
875 return ret;
876 }
877
proxy_socket_register(struct serial_adapter * adapter,const char * uuid128,const char * address,struct serial_proxy ** proxy)878 static int proxy_socket_register(struct serial_adapter *adapter,
879 const char *uuid128, const char *address,
880 struct serial_proxy **proxy)
881 {
882 struct serial_proxy *prx;
883 int ret;
884
885 prx = g_new0(struct serial_proxy, 1);
886 prx->address = g_strdup(address);
887 prx->uuid128 = g_strdup(uuid128);
888 prx->type = UNIX_SOCKET_PROXY;
889 adapter_get_address(adapter->btd_adapter, &prx->src);
890 prx->adapter = adapter;
891
892 ret = register_proxy_object(prx);
893 if (ret < 0) {
894 proxy_free(prx);
895 return ret;
896 }
897
898 *proxy = prx;
899
900 return ret;
901 }
902
proxy_tcp_register(struct serial_adapter * adapter,const char * uuid128,const char * address,struct serial_proxy ** proxy)903 static int proxy_tcp_register(struct serial_adapter *adapter,
904 const char *uuid128, const char *address,
905 struct serial_proxy **proxy)
906 {
907 struct serial_proxy *prx;
908 int ret;
909
910 prx = g_new0(struct serial_proxy, 1);
911 prx->address = g_strdup(address);
912 prx->uuid128 = g_strdup(uuid128);
913 prx->type = TCP_SOCKET_PROXY;
914 adapter_get_address(adapter->btd_adapter, &prx->src);
915 prx->adapter = adapter;
916
917 ret = register_proxy_object(prx);
918 if (ret < 0) {
919 proxy_free(prx);
920 return ret;
921 }
922
923 *proxy = prx;
924
925 return ret;
926 }
927
addr2type(const char * address)928 static proxy_type_t addr2type(const char *address)
929 {
930 struct stat st;
931
932 if (stat(address, &st) < 0) {
933 /*
934 * Unix socket: if the sun_path starts with null byte
935 * it refers to abstract namespace. 'x00' will be used
936 * to represent the null byte.
937 */
938 if (strncmp("localhost:", address, 10) == 0)
939 return TCP_SOCKET_PROXY;
940 if (strncmp("x00", address, 3) != 0)
941 return UNKNOWN_PROXY_TYPE;
942 else
943 return UNIX_SOCKET_PROXY;
944 } else {
945 /* Filesystem: char device or unix socket */
946 if (S_ISCHR(st.st_mode) && strncmp("/dev/", address, 4) == 0)
947 return TTY_PROXY;
948 else if (S_ISSOCK(st.st_mode))
949 return UNIX_SOCKET_PROXY;
950 else
951 return UNKNOWN_PROXY_TYPE;
952 }
953 }
954
proxy_addrcmp(gconstpointer proxy,gconstpointer addr)955 static int proxy_addrcmp(gconstpointer proxy, gconstpointer addr)
956 {
957 const struct serial_proxy *prx = proxy;
958 const char *address = addr;
959
960 return strcmp(prx->address, address);
961 }
962
proxy_pathcmp(gconstpointer proxy,gconstpointer p)963 static int proxy_pathcmp(gconstpointer proxy, gconstpointer p)
964 {
965 const struct serial_proxy *prx = proxy;
966 const char *path = p;
967
968 return strcmp(prx->path, path);
969 }
970
register_proxy(struct serial_adapter * adapter,const char * uuid_str,const char * address,struct serial_proxy ** proxy)971 static int register_proxy(struct serial_adapter *adapter,
972 const char *uuid_str, const char *address,
973 struct serial_proxy **proxy)
974 {
975 proxy_type_t type;
976 int err;
977
978 type = addr2type(address);
979 if (type == UNKNOWN_PROXY_TYPE)
980 return -EINVAL;
981
982 /* Only one proxy per address(TTY or unix socket) is allowed */
983 if (g_slist_find_custom(adapter->proxies, address, proxy_addrcmp))
984 return -EALREADY;
985
986 switch (type) {
987 case UNIX_SOCKET_PROXY:
988 err = proxy_socket_register(adapter, uuid_str, address, proxy);
989 break;
990 case TTY_PROXY:
991 err = proxy_tty_register(adapter, uuid_str, address, NULL,
992 proxy);
993 break;
994 case TCP_SOCKET_PROXY:
995 err = proxy_tcp_register(adapter, uuid_str, address, proxy);
996 break;
997 default:
998 err = -EINVAL;
999 }
1000
1001 if (err < 0)
1002 return err;
1003
1004 g_dbus_emit_signal(adapter->conn,
1005 adapter_get_path(adapter->btd_adapter),
1006 SERIAL_MANAGER_INTERFACE, "ProxyCreated",
1007 DBUS_TYPE_STRING, &(*proxy)->path,
1008 DBUS_TYPE_INVALID);
1009
1010 return 0;
1011 }
1012
unregister_proxy(struct serial_proxy * proxy)1013 static void unregister_proxy(struct serial_proxy *proxy)
1014 {
1015 struct serial_adapter *adapter = proxy->adapter;
1016 char *path = g_strdup(proxy->path);
1017
1018 if (proxy->watch > 0)
1019 g_dbus_remove_watch(adapter->conn, proxy->watch);
1020
1021 g_dbus_emit_signal(adapter->conn,
1022 adapter_get_path(adapter->btd_adapter),
1023 SERIAL_MANAGER_INTERFACE, "ProxyRemoved",
1024 DBUS_TYPE_STRING, &path,
1025 DBUS_TYPE_INVALID);
1026
1027 adapter->proxies = g_slist_remove(adapter->proxies, proxy);
1028
1029 g_dbus_unregister_interface(adapter->conn, path,
1030 SERIAL_PROXY_INTERFACE);
1031
1032 g_free(path);
1033 }
1034
watch_proxy(DBusConnection * connection,void * user_data)1035 static void watch_proxy(DBusConnection *connection, void *user_data)
1036 {
1037 struct serial_proxy *proxy = user_data;
1038
1039 proxy->watch = 0;
1040 unregister_proxy(proxy);
1041 }
1042
create_proxy(DBusConnection * conn,DBusMessage * msg,void * data)1043 static DBusMessage *create_proxy(DBusConnection *conn,
1044 DBusMessage *msg, void *data)
1045 {
1046 struct serial_adapter *adapter = data;
1047 struct serial_proxy *proxy;
1048 const char *pattern, *address;
1049 char *uuid_str;
1050 int err;
1051
1052 if (!dbus_message_get_args(msg, NULL,
1053 DBUS_TYPE_STRING, &pattern,
1054 DBUS_TYPE_STRING, &address,
1055 DBUS_TYPE_INVALID))
1056 return NULL;
1057
1058 uuid_str = bt_name2string(pattern);
1059 if (!uuid_str)
1060 return invalid_arguments(msg, "Invalid UUID");
1061
1062 err = register_proxy(adapter, uuid_str, address, &proxy);
1063 g_free(uuid_str);
1064
1065 if (err == -EINVAL)
1066 return invalid_arguments(msg, "Invalid address");
1067 else if (err == -EALREADY)
1068 return g_dbus_create_error(msg, ERROR_INTERFACE ".AlreadyExist",
1069 "Proxy already exists");
1070 else if (err < 0)
1071 return g_dbus_create_error(msg, ERROR_INTERFACE "Failed",
1072 "Proxy creation failed (%s)", strerror(-err));
1073
1074 proxy->owner = g_strdup(dbus_message_get_sender(msg));
1075 proxy->watch = g_dbus_add_disconnect_watch(conn, proxy->owner,
1076 watch_proxy,
1077 proxy, NULL);
1078
1079 return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &proxy->path,
1080 DBUS_TYPE_INVALID);
1081 }
1082
list_proxies(DBusConnection * conn,DBusMessage * msg,void * data)1083 static DBusMessage *list_proxies(DBusConnection *conn,
1084 DBusMessage *msg, void *data)
1085 {
1086 struct serial_adapter *adapter = data;
1087 const GSList *l;
1088 DBusMessage *reply;
1089 DBusMessageIter iter, iter_array;
1090
1091 reply = dbus_message_new_method_return(msg);
1092 if (!reply)
1093 return NULL;
1094
1095 dbus_message_iter_init_append(reply, &iter);
1096 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1097 DBUS_TYPE_STRING_AS_STRING, &iter_array);
1098
1099 for (l = adapter->proxies; l; l = l->next) {
1100 struct serial_proxy *prx = l->data;
1101
1102 dbus_message_iter_append_basic(&iter_array,
1103 DBUS_TYPE_STRING, &prx->path);
1104 }
1105
1106 dbus_message_iter_close_container(&iter, &iter_array);
1107
1108 return reply;
1109 }
1110
remove_proxy(DBusConnection * conn,DBusMessage * msg,void * data)1111 static DBusMessage *remove_proxy(DBusConnection *conn,
1112 DBusMessage *msg, void *data)
1113 {
1114 struct serial_adapter *adapter = data;
1115 struct serial_proxy *prx;
1116 const char *path, *sender;
1117 GSList *l;
1118
1119 if (!dbus_message_get_args(msg, NULL,
1120 DBUS_TYPE_STRING, &path,
1121 DBUS_TYPE_INVALID))
1122 return NULL;
1123
1124 l = g_slist_find_custom(adapter->proxies, path, proxy_pathcmp);
1125 if (!l)
1126 return does_not_exist(msg, "Invalid proxy path");
1127
1128 prx = l->data;
1129
1130 sender = dbus_message_get_sender(msg);
1131 if (g_strcmp0(prx->owner, sender) != 0)
1132 return failed(msg, "Permission denied");
1133
1134 unregister_proxy(prx);
1135
1136 return dbus_message_new_method_return(msg);
1137 }
1138
manager_path_unregister(void * data)1139 static void manager_path_unregister(void *data)
1140 {
1141 struct serial_adapter *adapter = data;
1142 GSList *l;
1143
1144 /* Remove proxy objects */
1145 for (l = adapter->proxies; l; l = l->next) {
1146 struct serial_proxy *prx = l->data;
1147 char *path = g_strdup(prx->path);
1148
1149 g_dbus_unregister_interface(adapter->conn, path,
1150 SERIAL_PROXY_INTERFACE);
1151 g_free(path);
1152 }
1153
1154 if (adapter->conn)
1155 dbus_connection_unref(adapter->conn);
1156
1157 adapters = g_slist_remove(adapters, adapter);
1158 g_slist_free(adapter->proxies);
1159 btd_adapter_unref(adapter->btd_adapter);
1160 g_free(adapter);
1161 }
1162
1163 static GDBusMethodTable manager_methods[] = {
1164 { "CreateProxy", "ss", "s", create_proxy },
1165 { "ListProxies", "", "as", list_proxies },
1166 { "RemoveProxy", "s", "", remove_proxy },
1167 { },
1168 };
1169
1170 static GDBusSignalTable manager_signals[] = {
1171 { "ProxyCreated", "s" },
1172 { "ProxyRemoved", "s" },
1173 { }
1174 };
1175
find_adapter(GSList * list,struct btd_adapter * btd_adapter)1176 static struct serial_adapter *find_adapter(GSList *list,
1177 struct btd_adapter *btd_adapter)
1178 {
1179 GSList *l;
1180
1181 for (l = list; l; l = l->next) {
1182 struct serial_adapter *adapter = l->data;
1183
1184 if (adapter->btd_adapter == btd_adapter)
1185 return adapter;
1186 }
1187
1188 return NULL;
1189 }
1190
serial_proxy_init(struct serial_adapter * adapter)1191 static void serial_proxy_init(struct serial_adapter *adapter)
1192 {
1193 GKeyFile *config;
1194 GError *gerr = NULL;
1195 const char *file = CONFIGDIR "/serial.conf";
1196 char **group_list;
1197 int i;
1198
1199 config = g_key_file_new();
1200
1201 if (!g_key_file_load_from_file(config, file, 0, &gerr)) {
1202 error("Parsing %s failed: %s", file, gerr->message);
1203 g_error_free(gerr);
1204 g_key_file_free(config);
1205 return;
1206 }
1207
1208 group_list = g_key_file_get_groups(config, NULL);
1209
1210 for (i = 0; group_list[i] != NULL; i++) {
1211 char *group_str = group_list[i], *uuid_str, *address;
1212 int err;
1213 struct serial_proxy *prx;
1214
1215 /* string length of "Proxy" is 5 */
1216 if (strlen(group_str) < 5 || strncmp(group_str, "Proxy", 5))
1217 continue;
1218
1219 uuid_str = g_key_file_get_string(config, group_str, "UUID",
1220 &gerr);
1221 if (gerr) {
1222 DBG("%s: %s", file, gerr->message);
1223 g_error_free(gerr);
1224 g_key_file_free(config);
1225 g_strfreev(group_list);
1226 return;
1227 }
1228
1229 address = g_key_file_get_string(config, group_str, "Address",
1230 &gerr);
1231 if (gerr) {
1232 DBG("%s: %s", file, gerr->message);
1233 g_error_free(gerr);
1234 g_key_file_free(config);
1235 g_free(uuid_str);
1236 g_strfreev(group_list);
1237 return;
1238 }
1239
1240 err = register_proxy(adapter, uuid_str, address, &prx);
1241 if (err == -EINVAL)
1242 error("Invalid address.");
1243 else if (err == -EALREADY)
1244 DBG("Proxy already exists.");
1245 else if (err < 0)
1246 error("Proxy creation failed (%s)", strerror(-err));
1247 else {
1248 err = enable_proxy(prx);
1249 if (err < 0)
1250 error("Proxy enable failed (%s)",
1251 strerror(-err));
1252 }
1253
1254 g_free(uuid_str);
1255 g_free(address);
1256 }
1257
1258 g_strfreev(group_list);
1259 g_key_file_free(config);
1260 }
1261
proxy_register(DBusConnection * conn,struct btd_adapter * btd_adapter)1262 int proxy_register(DBusConnection *conn, struct btd_adapter *btd_adapter)
1263 {
1264 struct serial_adapter *adapter;
1265 const char *path;
1266
1267 adapter = find_adapter(adapters, btd_adapter);
1268 if (adapter)
1269 return -EINVAL;
1270
1271 adapter = g_new0(struct serial_adapter, 1);
1272 adapter->conn = dbus_connection_ref(conn);
1273 adapter->btd_adapter = btd_adapter_ref(btd_adapter);
1274
1275 path = adapter_get_path(btd_adapter);
1276
1277 if (!g_dbus_register_interface(conn, path,
1278 SERIAL_MANAGER_INTERFACE,
1279 manager_methods, manager_signals, NULL,
1280 adapter, manager_path_unregister)) {
1281 error("Failed to register %s interface to %s",
1282 SERIAL_MANAGER_INTERFACE, path);
1283 return -1;
1284 }
1285
1286 adapters = g_slist_append(adapters, adapter);
1287
1288 DBG("Registered interface %s on path %s",
1289 SERIAL_MANAGER_INTERFACE, path);
1290
1291 serial_proxy_init(adapter);
1292
1293 return 0;
1294 }
1295
proxy_unregister(struct btd_adapter * btd_adapter)1296 void proxy_unregister(struct btd_adapter *btd_adapter)
1297 {
1298 struct serial_adapter *adapter;
1299
1300 adapter = find_adapter(adapters, btd_adapter);
1301 if (!adapter)
1302 return;
1303
1304 g_dbus_unregister_interface(adapter->conn,
1305 adapter_get_path(btd_adapter),
1306 SERIAL_MANAGER_INTERFACE);
1307 }
1308