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