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