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 <stdio.h> 29 #include <unistd.h> 30 #include <stdlib.h> 31 #include <errno.h> 32 33 #include <bluetooth/bluetooth.h> 34 #include <bluetooth/bnep.h> 35 #include <bluetooth/sdp.h> 36 #include <bluetooth/sdp_lib.h> 37 #include <netinet/in.h> 38 39 #include <glib.h> 40 #include <gdbus.h> 41 42 #include "../src/dbus-common.h" 43 #include "../src/adapter.h" 44 45 #include "log.h" 46 #include "error.h" 47 #include "sdpd.h" 48 #include "btio.h" 49 #include "glib-helper.h" 50 51 #include "common.h" 52 #include "server.h" 53 54 #define NETWORK_SERVER_INTERFACE "org.bluez.NetworkServer" 55 #define SETUP_TIMEOUT 1 56 57 /* Pending Authorization */ 58 struct network_session { 59 bdaddr_t dst; /* Remote Bluetooth Address */ 60 GIOChannel *io; /* Pending connect channel */ 61 guint watch; /* BNEP socket watch */ 62 guint io_watch; 63 }; 64 65 struct network_adapter { 66 struct btd_adapter *adapter; /* Adapter pointer */ 67 GIOChannel *io; /* Bnep socket */ 68 struct network_session *setup; /* Setup in progress */ 69 GSList *servers; /* Server register to adapter */ 70 }; 71 72 /* Main server structure */ 73 struct network_server { 74 bdaddr_t src; /* Bluetooth Local Address */ 75 char *iface; /* DBus interface */ 76 char *name; /* Server service name */ 77 char *bridge; /* Bridge name */ 78 uint32_t record_id; /* Service record id */ 79 uint16_t id; /* Service class identifier */ 80 GSList *sessions; /* Active connections */ 81 struct network_adapter *na; /* Adapter reference */ 82 guint watch_id; /* Client service watch */ 83 }; 84 85 static DBusConnection *connection = NULL; 86 static GSList *adapters = NULL; 87 static gboolean security = TRUE; 88 89 static struct network_adapter *find_adapter(GSList *list, 90 struct btd_adapter *adapter) 91 { 92 for (; list; list = list->next) { 93 struct network_adapter *na = list->data; 94 95 if (na->adapter == adapter) 96 return na; 97 } 98 99 return NULL; 100 } 101 102 static struct network_server *find_server(GSList *list, uint16_t id) 103 { 104 for (; list; list = list->next) { 105 struct network_server *ns = list->data; 106 107 if (ns->id == id) 108 return ns; 109 } 110 111 return NULL; 112 } 113 114 static struct network_session *find_session(GSList *list, GIOChannel *chan) 115 { 116 GSList *l; 117 118 for (l = list; l; l = l->next) { 119 struct network_session *session = l->data; 120 121 if (session->io == chan) { 122 return session; 123 } 124 } 125 126 return NULL; 127 } 128 129 static struct network_session *find_session_by_addr(GSList *list, bdaddr_t dst_addr) 130 { 131 GSList *l; 132 133 for (l = list; l; l = l->next) { 134 struct network_session *session = l->data; 135 136 if (!bacmp(&session->dst, &dst_addr)) { 137 return session; 138 } 139 } 140 141 return NULL; 142 } 143 144 static void add_lang_attr(sdp_record_t *r) 145 { 146 sdp_lang_attr_t base_lang; 147 sdp_list_t *langs = 0; 148 149 /* UTF-8 MIBenum (http://www.iana.org/assignments/character-sets) */ 150 base_lang.code_ISO639 = (0x65 << 8) | 0x6e; 151 base_lang.encoding = 106; 152 base_lang.base_offset = SDP_PRIMARY_LANG_BASE; 153 langs = sdp_list_append(0, &base_lang); 154 sdp_set_lang_attr(r, langs); 155 sdp_list_free(langs, 0); 156 } 157 158 static sdp_record_t *server_record_new(const char *name, uint16_t id) 159 { 160 sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto; 161 uuid_t root_uuid, pan, l2cap, bnep; 162 sdp_profile_desc_t profile[1]; 163 sdp_list_t *proto[2]; 164 sdp_data_t *v, *p; 165 uint16_t psm = BNEP_PSM, version = 0x0100; 166 uint16_t security_desc = (security ? 0x0001 : 0x0000); 167 uint16_t net_access_type = 0xfffe; 168 uint32_t max_net_access_rate = 0; 169 const char *desc = "Network service"; 170 sdp_record_t *record; 171 172 record = sdp_record_alloc(); 173 if (!record) 174 return NULL; 175 176 record->attrlist = NULL; 177 record->pattern = NULL; 178 179 switch (id) { 180 case BNEP_SVC_NAP: 181 sdp_uuid16_create(&pan, NAP_SVCLASS_ID); 182 svclass = sdp_list_append(NULL, &pan); 183 sdp_set_service_classes(record, svclass); 184 185 sdp_uuid16_create(&profile[0].uuid, NAP_PROFILE_ID); 186 profile[0].version = 0x0100; 187 pfseq = sdp_list_append(NULL, &profile[0]); 188 sdp_set_profile_descs(record, pfseq); 189 190 sdp_set_info_attr(record, name, NULL, desc); 191 192 sdp_attr_add_new(record, SDP_ATTR_NET_ACCESS_TYPE, 193 SDP_UINT16, &net_access_type); 194 sdp_attr_add_new(record, SDP_ATTR_MAX_NET_ACCESSRATE, 195 SDP_UINT32, &max_net_access_rate); 196 break; 197 case BNEP_SVC_GN: 198 sdp_uuid16_create(&pan, GN_SVCLASS_ID); 199 svclass = sdp_list_append(NULL, &pan); 200 sdp_set_service_classes(record, svclass); 201 202 sdp_uuid16_create(&profile[0].uuid, GN_PROFILE_ID); 203 profile[0].version = 0x0100; 204 pfseq = sdp_list_append(NULL, &profile[0]); 205 sdp_set_profile_descs(record, pfseq); 206 207 sdp_set_info_attr(record, name, NULL, desc); 208 break; 209 case BNEP_SVC_PANU: 210 sdp_uuid16_create(&pan, PANU_SVCLASS_ID); 211 svclass = sdp_list_append(NULL, &pan); 212 sdp_set_service_classes(record, svclass); 213 214 sdp_uuid16_create(&profile[0].uuid, PANU_PROFILE_ID); 215 profile[0].version = 0x0100; 216 pfseq = sdp_list_append(NULL, &profile[0]); 217 sdp_set_profile_descs(record, pfseq); 218 219 sdp_set_info_attr(record, name, NULL, desc); 220 break; 221 default: 222 sdp_record_free(record); 223 return NULL; 224 } 225 226 sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); 227 root = sdp_list_append(NULL, &root_uuid); 228 sdp_set_browse_groups(record, root); 229 230 sdp_uuid16_create(&l2cap, L2CAP_UUID); 231 proto[0] = sdp_list_append(NULL, &l2cap); 232 p = sdp_data_alloc(SDP_UINT16, &psm); 233 proto[0] = sdp_list_append(proto[0], p); 234 apseq = sdp_list_append(NULL, proto[0]); 235 236 sdp_uuid16_create(&bnep, BNEP_UUID); 237 proto[1] = sdp_list_append(NULL, &bnep); 238 v = sdp_data_alloc(SDP_UINT16, &version); 239 proto[1] = sdp_list_append(proto[1], v); 240 241 /* Supported protocols */ 242 { 243 uint16_t ptype[] = { 244 0x0800, /* IPv4 */ 245 0x0806, /* ARP */ 246 }; 247 sdp_data_t *head, *pseq; 248 int p; 249 250 for (p = 0, head = NULL; p < 2; p++) { 251 sdp_data_t *data = sdp_data_alloc(SDP_UINT16, &ptype[p]); 252 if (head) 253 sdp_seq_append(head, data); 254 else 255 head = data; 256 } 257 pseq = sdp_data_alloc(SDP_SEQ16, head); 258 proto[1] = sdp_list_append(proto[1], pseq); 259 } 260 261 apseq = sdp_list_append(apseq, proto[1]); 262 263 aproto = sdp_list_append(NULL, apseq); 264 sdp_set_access_protos(record, aproto); 265 266 add_lang_attr(record); 267 268 sdp_attr_add_new(record, SDP_ATTR_SECURITY_DESC, 269 SDP_UINT16, &security_desc); 270 271 sdp_data_free(p); 272 sdp_data_free(v); 273 sdp_list_free(apseq, NULL); 274 sdp_list_free(root, NULL); 275 sdp_list_free(aproto, NULL); 276 sdp_list_free(proto[0], NULL); 277 sdp_list_free(proto[1], NULL); 278 sdp_list_free(svclass, NULL); 279 sdp_list_free(pfseq, NULL); 280 281 return record; 282 } 283 284 static ssize_t send_bnep_ctrl_rsp(int sk, uint16_t val) 285 { 286 struct bnep_control_rsp rsp; 287 288 rsp.type = BNEP_CONTROL; 289 rsp.ctrl = BNEP_SETUP_CONN_RSP; 290 rsp.resp = htons(val); 291 292 return send(sk, &rsp, sizeof(rsp), 0); 293 } 294 295 static void session_free(void *data) 296 { 297 struct network_session *session = data; 298 299 if (session->watch) 300 g_source_remove(session->watch); 301 302 if (session->io_watch) 303 g_source_remove(session->io_watch); 304 305 if (session->io) 306 g_io_channel_unref(session->io); 307 308 g_free(session); 309 } 310 311 static void bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond, 312 gpointer data) 313 { 314 struct network_server *ns = data; 315 struct network_session *session; 316 char address[18]; 317 const char *paddr = address; 318 319 session = find_session(ns->sessions, chan); 320 321 if (!connection || !session) return; 322 323 ba2str(&session->dst, address); 324 g_dbus_emit_signal(connection, adapter_get_path(ns->na->adapter), 325 ns->iface, "DeviceDisconnected", 326 DBUS_TYPE_STRING, &paddr, 327 DBUS_TYPE_INVALID); 328 g_io_channel_shutdown(chan, TRUE, NULL); 329 g_io_channel_unref(session->io); 330 session->io = NULL; 331 session_free(session); 332 } 333 334 335 static int server_connadd(struct network_server *ns, 336 struct network_session *session, 337 uint16_t dst_role) 338 { 339 char devname[16]; 340 char address[18]; 341 const char *paddr = address; 342 const char *pdevname = devname; 343 int err, nsk; 344 345 memset(devname, 0, sizeof(devname)); 346 strcpy(devname, "bnep%d"); 347 348 nsk = g_io_channel_unix_get_fd(session->io); 349 err = bnep_connadd(nsk, dst_role, devname); 350 if (err < 0) 351 return err; 352 353 info("Added new connection: %s", devname); 354 355 #ifndef ANDROID_NO_BRIDGE 356 if (bnep_add_to_bridge(devname, ns->bridge) < 0) { 357 error("Can't add %s to the bridge %s: %s(%d)", 358 devname, ns->bridge, strerror(errno), errno); 359 return -EPERM; 360 } 361 #endif 362 363 bnep_if_up(devname); 364 365 ns->sessions = g_slist_append(ns->sessions, session); 366 367 ba2str(&session->dst, address); 368 gboolean result = g_dbus_emit_signal(connection, adapter_get_path(ns->na->adapter), 369 ns->iface, "DeviceConnected", 370 DBUS_TYPE_STRING, &paddr, 371 DBUS_TYPE_STRING, &pdevname, 372 DBUS_TYPE_UINT16, &dst_role, 373 DBUS_TYPE_INVALID); 374 375 session->io_watch = g_io_add_watch(session->io, G_IO_ERR | G_IO_HUP, 376 (GIOFunc) bnep_watchdog_cb, ns); 377 378 return 0; 379 } 380 381 static uint16_t bnep_setup_chk(uint16_t dst_role, uint16_t src_role) 382 { 383 /* Allowed PAN Profile scenarios */ 384 switch (dst_role) { 385 case BNEP_SVC_NAP: 386 case BNEP_SVC_GN: 387 if (src_role == BNEP_SVC_PANU) 388 return 0; 389 return BNEP_CONN_INVALID_SRC; 390 case BNEP_SVC_PANU: 391 if (src_role == BNEP_SVC_PANU || 392 src_role == BNEP_SVC_GN || 393 src_role == BNEP_SVC_NAP) 394 return 0; 395 396 return BNEP_CONN_INVALID_SRC; 397 } 398 399 return BNEP_CONN_INVALID_DST; 400 } 401 402 static uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, 403 uint16_t *dst_role, uint16_t *src_role) 404 { 405 uint8_t *dest, *source; 406 407 dest = req->service; 408 source = req->service + req->uuid_size; 409 410 switch (req->uuid_size) { 411 case 2: /* UUID16 */ 412 *dst_role = ntohs(bt_get_unaligned((uint16_t *) dest)); 413 *src_role = ntohs(bt_get_unaligned((uint16_t *) source)); 414 break; 415 case 4: /* UUID32 */ 416 case 16: /* UUID128 */ 417 *dst_role = ntohl(bt_get_unaligned((uint32_t *) dest)); 418 *src_role = ntohl(bt_get_unaligned((uint32_t *) source)); 419 break; 420 default: 421 return BNEP_CONN_INVALID_SVC; 422 } 423 424 return 0; 425 } 426 427 static void setup_destroy(void *user_data) 428 { 429 struct network_adapter *na = user_data; 430 struct network_session *setup = na->setup; 431 432 if (!setup) 433 return; 434 435 na->setup = NULL; 436 437 session_free(setup); 438 } 439 440 static gboolean bnep_setup(GIOChannel *chan, 441 GIOCondition cond, gpointer user_data) 442 { 443 struct network_adapter *na = user_data; 444 struct network_server *ns; 445 uint8_t packet[BNEP_MTU]; 446 struct bnep_setup_conn_req *req = (void *) packet; 447 uint16_t src_role, dst_role, rsp = BNEP_CONN_NOT_ALLOWED; 448 int n, sk; 449 450 if (cond & G_IO_NVAL) 451 return FALSE; 452 453 if (cond & (G_IO_ERR | G_IO_HUP)) { 454 error("Hangup or error on BNEP socket"); 455 return FALSE; 456 } 457 458 sk = g_io_channel_unix_get_fd(chan); 459 460 /* Reading BNEP_SETUP_CONNECTION_REQUEST_MSG */ 461 n = read(sk, packet, sizeof(packet)); 462 if (n < 0) { 463 error("read(): %s(%d)", strerror(errno), errno); 464 return FALSE; 465 } 466 467 /* Highest known Control command ID 468 * is BNEP_FILTER_MULT_ADDR_RSP = 0x06 */ 469 if (req->type == BNEP_CONTROL && 470 req->ctrl > BNEP_FILTER_MULT_ADDR_RSP) { 471 uint8_t pkt[3]; 472 473 pkt[0] = BNEP_CONTROL; 474 pkt[1] = BNEP_CMD_NOT_UNDERSTOOD; 475 pkt[2] = req->ctrl; 476 477 send(sk, pkt, sizeof(pkt), 0); 478 479 return FALSE; 480 } 481 482 if (req->type != BNEP_CONTROL || req->ctrl != BNEP_SETUP_CONN_REQ) 483 return FALSE; 484 485 rsp = bnep_setup_decode(req, &dst_role, &src_role); 486 if (rsp) 487 goto reply; 488 489 rsp = bnep_setup_chk(dst_role, src_role); 490 if (rsp) 491 goto reply; 492 493 ns = find_server(na->servers, dst_role); 494 if (!ns) { 495 error("Server unavailable: (0x%x)", dst_role); 496 goto reply; 497 } 498 499 if (!ns->record_id) { 500 error("Service record not available"); 501 goto reply; 502 } 503 504 if (!ns->bridge) { 505 error("Bridge interface not configured"); 506 goto reply; 507 } 508 509 if (server_connadd(ns, na->setup, dst_role) < 0) 510 goto reply; 511 512 na->setup = NULL; 513 514 rsp = BNEP_SUCCESS; 515 516 reply: 517 send_bnep_ctrl_rsp(sk, rsp); 518 519 return FALSE; 520 } 521 522 static void connect_event(GIOChannel *chan, GError *err, gpointer user_data) 523 { 524 struct network_adapter *na = user_data; 525 526 if (err) { 527 error("%s", err->message); 528 setup_destroy(na); 529 return; 530 } 531 532 g_io_channel_set_close_on_unref(chan, TRUE); 533 534 na->setup->watch = g_io_add_watch_full(chan, G_PRIORITY_DEFAULT, 535 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, 536 bnep_setup, na, setup_destroy); 537 } 538 539 static void auth_cb(DBusError *derr, void *user_data) 540 { 541 struct network_adapter *na = user_data; 542 GError *err = NULL; 543 544 if (derr) { 545 error("Access denied: %s", derr->message); 546 goto reject; 547 } 548 549 if (!bt_io_accept(na->setup->io, connect_event, na, NULL, 550 &err)) { 551 error("bt_io_accept: %s", err->message); 552 g_error_free(err); 553 goto reject; 554 } 555 556 return; 557 558 reject: 559 g_io_channel_shutdown(na->setup->io, TRUE, NULL); 560 setup_destroy(na); 561 } 562 563 static void confirm_event(GIOChannel *chan, gpointer user_data) 564 { 565 struct network_adapter *na = user_data; 566 struct network_server *ns; 567 int perr; 568 bdaddr_t src, dst; 569 char address[18]; 570 GError *err = NULL; 571 572 bt_io_get(chan, BT_IO_L2CAP, &err, 573 BT_IO_OPT_SOURCE_BDADDR, &src, 574 BT_IO_OPT_DEST_BDADDR, &dst, 575 BT_IO_OPT_DEST, address, 576 BT_IO_OPT_INVALID); 577 if (err) { 578 error("%s", err->message); 579 g_error_free(err); 580 goto drop; 581 } 582 583 DBG("BNEP: incoming connect from %s", address); 584 585 if (na->setup) { 586 error("Refusing connect from %s: setup in progress", address); 587 goto drop; 588 } 589 590 ns = find_server(na->servers, BNEP_SVC_NAP); 591 if (!ns) 592 goto drop; 593 594 if (!ns->record_id) 595 goto drop; 596 597 if (!ns->bridge) 598 goto drop; 599 600 na->setup = g_new0(struct network_session, 1); 601 bacpy(&na->setup->dst, &dst); 602 na->setup->io = g_io_channel_ref(chan); 603 604 perr = btd_request_authorization(&src, &dst, BNEP_SVC_UUID, 605 auth_cb, na); 606 if (perr < 0) { 607 error("Refusing connect from %s: %s (%d)", address, 608 strerror(-perr), -perr); 609 setup_destroy(na); 610 goto drop; 611 } 612 613 return; 614 615 drop: 616 g_io_channel_shutdown(chan, TRUE, NULL); 617 } 618 619 int server_init(DBusConnection *conn, gboolean secure) 620 { 621 security = secure; 622 connection = dbus_connection_ref(conn); 623 624 return 0; 625 } 626 627 void server_exit(void) 628 { 629 dbus_connection_unref(connection); 630 connection = NULL; 631 } 632 633 static uint32_t register_server_record(struct network_server *ns) 634 { 635 sdp_record_t *record; 636 637 record = server_record_new(ns->name, ns->id); 638 if (!record) { 639 error("Unable to allocate new service record"); 640 return 0; 641 } 642 643 if (add_record_to_server(&ns->src, record) < 0) { 644 error("Failed to register service record"); 645 sdp_record_free(record); 646 return 0; 647 } 648 649 DBG("got record id 0x%x", record->handle); 650 651 return record->handle; 652 } 653 654 static void server_disconnect(DBusConnection *conn, void *user_data) 655 { 656 struct network_server *ns = user_data; 657 658 ns->watch_id = 0; 659 660 if (ns->record_id) { 661 remove_record_from_server(ns->record_id); 662 ns->record_id = 0; 663 } 664 665 g_free(ns->bridge); 666 ns->bridge = NULL; 667 } 668 669 static DBusMessage *register_server(DBusConnection *conn, 670 DBusMessage *msg, void *data) 671 { 672 struct network_server *ns = data; 673 DBusMessage *reply; 674 const char *uuid, *bridge; 675 676 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &uuid, 677 DBUS_TYPE_STRING, &bridge, DBUS_TYPE_INVALID)) 678 return NULL; 679 680 if (g_strcmp0(uuid, "nap")) 681 return btd_error_failed(msg, "Invalid UUID"); 682 683 if (ns->record_id) 684 return btd_error_already_exists(msg); 685 686 reply = dbus_message_new_method_return(msg); 687 if (!reply) 688 return NULL; 689 690 ns->record_id = register_server_record(ns); 691 if (!ns->record_id) 692 return btd_error_failed(msg, "SDP record registration failed"); 693 694 g_free(ns->bridge); 695 ns->bridge = g_strdup(bridge); 696 697 ns->watch_id = g_dbus_add_disconnect_watch(conn, 698 dbus_message_get_sender(msg), 699 server_disconnect, ns, NULL); 700 701 return reply; 702 } 703 704 static DBusMessage *unregister_server(DBusConnection *conn, 705 DBusMessage *msg, void *data) 706 { 707 struct network_server *ns = data; 708 DBusMessage *reply; 709 const char *uuid; 710 711 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &uuid, 712 DBUS_TYPE_INVALID)) 713 return NULL; 714 715 if (g_strcmp0(uuid, "nap")) 716 return btd_error_failed(msg, "Invalid UUID"); 717 718 reply = dbus_message_new_method_return(msg); 719 if (!reply) 720 return NULL; 721 722 g_dbus_remove_watch(conn, ns->watch_id); 723 724 server_disconnect(conn, ns); 725 726 return reply; 727 } 728 729 static DBusMessage *disconnect_device(DBusConnection *conn, 730 DBusMessage *msg, void *data) 731 { 732 DBusMessage *reply; 733 struct network_server *ns = data; 734 struct network_session *session; 735 const char *addr, *devname; 736 bdaddr_t dst_addr; 737 738 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr, 739 DBUS_TYPE_STRING, &devname, 740 DBUS_TYPE_INVALID)) 741 return NULL; 742 743 str2ba(addr, &dst_addr); 744 session = find_session_by_addr(ns->sessions, dst_addr); 745 746 if (!session) 747 return btd_error_failed(msg, "No active session"); 748 749 if (session->io) { 750 bnep_if_down(devname); 751 bnep_kill_connection(&dst_addr); 752 } else 753 return btd_error_not_connected(msg); 754 755 reply = dbus_message_new_method_return(msg); 756 if (!reply) 757 return NULL; 758 return reply; 759 } 760 761 762 static void adapter_free(struct network_adapter *na) 763 { 764 if (na->io != NULL) { 765 g_io_channel_shutdown(na->io, TRUE, NULL); 766 g_io_channel_unref(na->io); 767 } 768 769 setup_destroy(na); 770 btd_adapter_unref(na->adapter); 771 g_free(na); 772 } 773 774 static void server_free(struct network_server *ns) 775 { 776 if (!ns) 777 return; 778 779 /* FIXME: Missing release/free all bnepX interfaces */ 780 if (ns->record_id) 781 remove_record_from_server(ns->record_id); 782 783 g_free(ns->iface); 784 g_free(ns->name); 785 g_free(ns->bridge); 786 787 if (ns->sessions) { 788 g_slist_foreach(ns->sessions, (GFunc) session_free, NULL); 789 g_slist_free(ns->sessions); 790 } 791 792 g_free(ns); 793 } 794 795 static void path_unregister(void *data) 796 { 797 struct network_server *ns = data; 798 struct network_adapter *na = ns->na; 799 800 DBG("Unregistered interface %s on path %s", 801 ns->iface, adapter_get_path(na->adapter)); 802 803 na->servers = g_slist_remove(na->servers, ns); 804 server_free(ns); 805 806 if (na->servers) 807 return; 808 809 adapters = g_slist_remove(adapters, na); 810 adapter_free(na); 811 } 812 813 static GDBusMethodTable server_methods[] = { 814 { "Register", "ss", "", register_server }, 815 { "Unregister", "s", "", unregister_server }, 816 { "DisconnectDevice", "ss", "", disconnect_device }, 817 { } 818 }; 819 820 static GDBusSignalTable server_signals[] = { 821 { "DeviceConnected", "ssq" }, 822 { "DeviceDisconnected", "s" }, 823 { } 824 }; 825 826 static struct network_adapter *create_adapter(struct btd_adapter *adapter) 827 { 828 struct network_adapter *na; 829 GError *err = NULL; 830 bdaddr_t src; 831 832 na = g_new0(struct network_adapter, 1); 833 na->adapter = btd_adapter_ref(adapter); 834 835 adapter_get_address(adapter, &src); 836 837 na->io = bt_io_listen(BT_IO_L2CAP, NULL, confirm_event, na, 838 NULL, &err, 839 BT_IO_OPT_SOURCE_BDADDR, &src, 840 BT_IO_OPT_PSM, BNEP_PSM, 841 BT_IO_OPT_OMTU, BNEP_MTU, 842 BT_IO_OPT_IMTU, BNEP_MTU, 843 BT_IO_OPT_SEC_LEVEL, 844 security ? BT_IO_SEC_MEDIUM : BT_IO_SEC_LOW, 845 BT_IO_OPT_INVALID); 846 if (!na->io) { 847 error("%s", err->message); 848 g_error_free(err); 849 adapter_free(na); 850 return NULL; 851 } 852 853 return na; 854 } 855 856 int server_register(struct btd_adapter *adapter) 857 { 858 struct network_adapter *na; 859 struct network_server *ns; 860 const char *path; 861 862 na = find_adapter(adapters, adapter); 863 if (!na) { 864 na = create_adapter(adapter); 865 if (!na) 866 return -EINVAL; 867 adapters = g_slist_append(adapters, na); 868 } 869 870 ns = find_server(na->servers, BNEP_SVC_NAP); 871 if (ns) 872 return 0; 873 874 ns = g_new0(struct network_server, 1); 875 876 ns->iface = g_strdup(NETWORK_SERVER_INTERFACE); 877 ns->name = g_strdup("Network service"); 878 879 path = adapter_get_path(adapter); 880 881 if (!g_dbus_register_interface(connection, path, ns->iface, 882 server_methods, server_signals, NULL, 883 ns, path_unregister)) { 884 error("D-Bus failed to register %s interface", 885 ns->iface); 886 server_free(ns); 887 return -1; 888 } 889 890 adapter_get_address(adapter, &ns->src); 891 ns->id = BNEP_SVC_NAP; 892 ns->na = na; 893 ns->record_id = 0; 894 na->servers = g_slist_append(na->servers, ns); 895 896 DBG("Registered interface %s on path %s", ns->iface, path); 897 898 return 0; 899 } 900 901 int server_unregister(struct btd_adapter *adapter) 902 { 903 struct network_adapter *na; 904 struct network_server *ns; 905 uint16_t id = BNEP_SVC_NAP; 906 907 na = find_adapter(adapters, adapter); 908 if (!na) 909 return -EINVAL; 910 911 ns = find_server(na->servers, id); 912 if (!ns) 913 return -EINVAL; 914 915 g_dbus_unregister_interface(connection, adapter_get_path(adapter), 916 ns->iface); 917 918 return 0; 919 } 920