1 /* 2 * 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2006-2010 Nokia Corporation 6 * Copyright (C) 2004-2010 Marcel Holtmann <marcel (at) holtmann.org> 7 * 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 * 23 */ 24 25 #ifdef HAVE_CONFIG_H 26 #include <config.h> 27 #endif 28 29 #include <errno.h> 30 #include <stdlib.h> 31 #include <string.h> 32 33 #include <bluetooth/bluetooth.h> 34 #include <bluetooth/sdp.h> 35 #include <bluetooth/sdp_lib.h> 36 37 #include <gdbus.h> 38 39 #include "sdpd.h" 40 #include "sdp-xml.h" 41 #include "plugin.h" 42 #include "adapter.h" 43 #include "error.h" 44 #include "log.h" 45 46 #define SERVICE_INTERFACE "org.bluez.Service" 47 48 static DBusConnection *connection; 49 50 struct record_data { 51 uint32_t handle; 52 char *sender; 53 guint listener_id; 54 struct service_adapter *serv_adapter; 55 }; 56 57 struct context_data { 58 sdp_record_t *record; 59 sdp_data_t attr_data; 60 struct sdp_xml_data *stack_head; 61 uint16_t attr_id; 62 }; 63 64 struct pending_auth { 65 DBusConnection *conn; 66 DBusMessage *msg; 67 char *sender; 68 bdaddr_t dst; 69 char uuid[MAX_LEN_UUID_STR]; 70 }; 71 72 struct service_adapter { 73 struct btd_adapter *adapter; 74 GSList *pending_list; 75 GSList *records; 76 }; 77 78 static struct service_adapter *serv_adapter_any = NULL; 79 80 static int compute_seq_size(sdp_data_t *data) 81 { 82 int unit_size = data->unitSize; 83 sdp_data_t *seq = data->val.dataseq; 84 85 for (; seq; seq = seq->next) 86 unit_size += seq->unitSize; 87 88 return unit_size; 89 } 90 91 static void element_start(GMarkupParseContext *context, 92 const gchar *element_name, const gchar **attribute_names, 93 const gchar **attribute_values, gpointer user_data, GError **err) 94 { 95 struct context_data *ctx_data = user_data; 96 97 if (!strcmp(element_name, "record")) 98 return; 99 100 if (!strcmp(element_name, "attribute")) { 101 int i; 102 for (i = 0; attribute_names[i]; i++) { 103 if (!strcmp(attribute_names[i], "id")) { 104 ctx_data->attr_id = strtol(attribute_values[i], 0, 0); 105 break; 106 } 107 } 108 DBG("New attribute 0x%04x", ctx_data->attr_id); 109 return; 110 } 111 112 if (ctx_data->stack_head) { 113 struct sdp_xml_data *newelem = sdp_xml_data_alloc(); 114 newelem->next = ctx_data->stack_head; 115 ctx_data->stack_head = newelem; 116 } else { 117 ctx_data->stack_head = sdp_xml_data_alloc(); 118 ctx_data->stack_head->next = NULL; 119 } 120 121 if (!strcmp(element_name, "sequence")) 122 ctx_data->stack_head->data = sdp_data_alloc(SDP_SEQ8, NULL); 123 else if (!strcmp(element_name, "alternate")) 124 ctx_data->stack_head->data = sdp_data_alloc(SDP_ALT8, NULL); 125 else { 126 int i; 127 /* Parse value, name, encoding */ 128 for (i = 0; attribute_names[i]; i++) { 129 if (!strcmp(attribute_names[i], "value")) { 130 int curlen = strlen(ctx_data->stack_head->text); 131 int attrlen = strlen(attribute_values[i]); 132 133 /* Ensure we're big enough */ 134 while ((curlen + 1 + attrlen) > ctx_data->stack_head->size) { 135 sdp_xml_data_expand(ctx_data->stack_head); 136 } 137 138 memcpy(ctx_data->stack_head->text + curlen, 139 attribute_values[i], attrlen); 140 ctx_data->stack_head->text[curlen + attrlen] = '\0'; 141 } 142 143 if (!strcmp(attribute_names[i], "encoding")) { 144 if (!strcmp(attribute_values[i], "hex")) 145 ctx_data->stack_head->type = 1; 146 } 147 148 if (!strcmp(attribute_names[i], "name")) { 149 ctx_data->stack_head->name = strdup(attribute_values[i]); 150 } 151 } 152 153 ctx_data->stack_head->data = sdp_xml_parse_datatype(element_name, 154 ctx_data->stack_head, ctx_data->record); 155 156 if (ctx_data->stack_head->data == NULL) 157 error("Can't parse element %s", element_name); 158 } 159 } 160 161 static void element_end(GMarkupParseContext *context, 162 const gchar *element_name, gpointer user_data, GError **err) 163 { 164 struct context_data *ctx_data = user_data; 165 struct sdp_xml_data *elem; 166 167 if (!strcmp(element_name, "record")) 168 return; 169 170 if (!strcmp(element_name, "attribute")) { 171 if (ctx_data->stack_head && ctx_data->stack_head->data) { 172 int ret = sdp_attr_add(ctx_data->record, ctx_data->attr_id, 173 ctx_data->stack_head->data); 174 if (ret == -1) 175 DBG("Could not add attribute 0x%04x", 176 ctx_data->attr_id); 177 178 ctx_data->stack_head->data = NULL; 179 sdp_xml_data_free(ctx_data->stack_head); 180 ctx_data->stack_head = NULL; 181 } else { 182 DBG("No data for attribute 0x%04x", ctx_data->attr_id); 183 } 184 return; 185 } 186 187 if (!strcmp(element_name, "sequence")) { 188 ctx_data->stack_head->data->unitSize = compute_seq_size(ctx_data->stack_head->data); 189 190 if (ctx_data->stack_head->data->unitSize > USHRT_MAX) { 191 ctx_data->stack_head->data->unitSize += sizeof(uint32_t); 192 ctx_data->stack_head->data->dtd = SDP_SEQ32; 193 } else if (ctx_data->stack_head->data->unitSize > UCHAR_MAX) { 194 ctx_data->stack_head->data->unitSize += sizeof(uint16_t); 195 ctx_data->stack_head->data->dtd = SDP_SEQ16; 196 } else { 197 ctx_data->stack_head->data->unitSize += sizeof(uint8_t); 198 } 199 } else if (!strcmp(element_name, "alternate")) { 200 ctx_data->stack_head->data->unitSize = compute_seq_size(ctx_data->stack_head->data); 201 202 if (ctx_data->stack_head->data->unitSize > USHRT_MAX) { 203 ctx_data->stack_head->data->unitSize += sizeof(uint32_t); 204 ctx_data->stack_head->data->dtd = SDP_ALT32; 205 } else if (ctx_data->stack_head->data->unitSize > UCHAR_MAX) { 206 ctx_data->stack_head->data->unitSize += sizeof(uint16_t); 207 ctx_data->stack_head->data->dtd = SDP_ALT16; 208 } else { 209 ctx_data->stack_head->data->unitSize += sizeof(uint8_t); 210 } 211 } 212 213 if (ctx_data->stack_head->next && ctx_data->stack_head->data && 214 ctx_data->stack_head->next->data) { 215 switch (ctx_data->stack_head->next->data->dtd) { 216 case SDP_SEQ8: 217 case SDP_SEQ16: 218 case SDP_SEQ32: 219 case SDP_ALT8: 220 case SDP_ALT16: 221 case SDP_ALT32: 222 ctx_data->stack_head->next->data->val.dataseq = 223 sdp_seq_append(ctx_data->stack_head->next->data->val.dataseq, 224 ctx_data->stack_head->data); 225 ctx_data->stack_head->data = NULL; 226 break; 227 } 228 229 elem = ctx_data->stack_head; 230 ctx_data->stack_head = ctx_data->stack_head->next; 231 232 sdp_xml_data_free(elem); 233 } 234 } 235 236 static GMarkupParser parser = { 237 element_start, element_end, NULL, NULL, NULL 238 }; 239 240 static sdp_record_t *sdp_xml_parse_record(const char *data, int size) 241 { 242 GMarkupParseContext *ctx; 243 struct context_data *ctx_data; 244 sdp_record_t *record; 245 246 ctx_data = malloc(sizeof(*ctx_data)); 247 if (!ctx_data) 248 return NULL; 249 250 record = sdp_record_alloc(); 251 if (!record) { 252 free(ctx_data); 253 return NULL; 254 } 255 256 memset(ctx_data, 0, sizeof(*ctx_data)); 257 ctx_data->record = record; 258 259 ctx = g_markup_parse_context_new(&parser, 0, ctx_data, NULL); 260 261 if (g_markup_parse_context_parse(ctx, data, size, NULL) == FALSE) { 262 error("XML parsing error"); 263 g_markup_parse_context_free(ctx); 264 sdp_record_free(record); 265 free(ctx_data); 266 return NULL; 267 } 268 269 g_markup_parse_context_free(ctx); 270 271 free(ctx_data); 272 273 return record; 274 } 275 276 static struct record_data *find_record(struct service_adapter *serv_adapter, 277 uint32_t handle, const char *sender) 278 { 279 GSList *list; 280 281 for (list = serv_adapter->records; list; list = list->next) { 282 struct record_data *data = list->data; 283 if (handle == data->handle && !strcmp(sender, data->sender)) 284 return data; 285 } 286 287 return NULL; 288 } 289 290 static struct pending_auth *next_pending(struct service_adapter *serv_adapter) 291 { 292 GSList *l = serv_adapter->pending_list; 293 294 if (l) { 295 struct pending_auth *auth = l->data; 296 return auth; 297 } 298 299 return NULL; 300 } 301 302 static struct pending_auth *find_pending_by_sender( 303 struct service_adapter *serv_adapter, 304 const char *sender) 305 { 306 GSList *l = serv_adapter->pending_list; 307 308 for (; l; l = l->next) { 309 struct pending_auth *auth = l->data; 310 if (g_str_equal(auth->sender, sender)) 311 return auth; 312 } 313 314 return NULL; 315 } 316 317 static void exit_callback(DBusConnection *conn, void *user_data) 318 { 319 struct record_data *user_record = user_data; 320 struct service_adapter *serv_adapter = user_record->serv_adapter; 321 struct pending_auth *auth; 322 323 DBG("remove record"); 324 325 serv_adapter->records = g_slist_remove(serv_adapter->records, 326 user_record); 327 328 auth = find_pending_by_sender(serv_adapter, user_record->sender); 329 if (auth) { 330 serv_adapter->pending_list = g_slist_remove(serv_adapter->pending_list, 331 auth); 332 g_free(auth); 333 } 334 335 remove_record_from_server(user_record->handle); 336 337 g_free(user_record->sender); 338 g_free(user_record); 339 } 340 341 static int add_xml_record(DBusConnection *conn, const char *sender, 342 struct service_adapter *serv_adapter, 343 const char *record, dbus_uint32_t *handle) 344 { 345 struct record_data *user_record; 346 sdp_record_t *sdp_record; 347 bdaddr_t src; 348 349 sdp_record = sdp_xml_parse_record(record, strlen(record)); 350 if (!sdp_record) { 351 error("Parsing of XML service record failed"); 352 return -EIO; 353 } 354 355 if (serv_adapter->adapter) 356 adapter_get_address(serv_adapter->adapter, &src); 357 else 358 bacpy(&src, BDADDR_ANY); 359 360 if (add_record_to_server(&src, sdp_record) < 0) { 361 error("Failed to register service record"); 362 sdp_record_free(sdp_record); 363 return -EIO; 364 } 365 366 user_record = g_new0(struct record_data, 1); 367 user_record->handle = sdp_record->handle; 368 user_record->sender = g_strdup(sender); 369 user_record->serv_adapter = serv_adapter; 370 user_record->listener_id = g_dbus_add_disconnect_watch(conn, sender, 371 exit_callback, user_record, NULL); 372 373 serv_adapter->records = g_slist_append(serv_adapter->records, 374 user_record); 375 376 DBG("listener_id %d", user_record->listener_id); 377 378 *handle = user_record->handle; 379 380 return 0; 381 } 382 383 static DBusMessage *update_record(DBusConnection *conn, DBusMessage *msg, 384 struct service_adapter *serv_adapter, 385 dbus_uint32_t handle, sdp_record_t *sdp_record) 386 { 387 bdaddr_t src; 388 int err; 389 390 if (remove_record_from_server(handle) < 0) { 391 sdp_record_free(sdp_record); 392 return btd_error_not_available(msg); 393 } 394 395 if (serv_adapter->adapter) 396 adapter_get_address(serv_adapter->adapter, &src); 397 else 398 bacpy(&src, BDADDR_ANY); 399 400 sdp_record->handle = handle; 401 err = add_record_to_server(&src, sdp_record); 402 if (err < 0) { 403 sdp_record_free(sdp_record); 404 error("Failed to update the service record"); 405 return btd_error_failed(msg, strerror(-err)); 406 } 407 408 return dbus_message_new_method_return(msg); 409 } 410 411 static DBusMessage *update_xml_record(DBusConnection *conn, 412 DBusMessage *msg, 413 struct service_adapter *serv_adapter) 414 { 415 struct record_data *user_record; 416 sdp_record_t *sdp_record; 417 const char *record; 418 dbus_uint32_t handle; 419 int len; 420 421 if (dbus_message_get_args(msg, NULL, 422 DBUS_TYPE_UINT32, &handle, 423 DBUS_TYPE_STRING, &record, 424 DBUS_TYPE_INVALID) == FALSE) 425 return NULL; 426 427 len = (record ? strlen(record) : 0); 428 if (len == 0) 429 return btd_error_invalid_args(msg); 430 431 user_record = find_record(serv_adapter, handle, 432 dbus_message_get_sender(msg)); 433 if (!user_record) 434 return btd_error_not_available(msg); 435 436 sdp_record = sdp_xml_parse_record(record, len); 437 if (!sdp_record) { 438 error("Parsing of XML service record failed"); 439 sdp_record_free(sdp_record); 440 return btd_error_failed(msg, 441 "Parsing of XML service record failed"); 442 } 443 444 return update_record(conn, msg, serv_adapter, handle, sdp_record); 445 } 446 447 static int remove_record(DBusConnection *conn, const char *sender, 448 struct service_adapter *serv_adapter, 449 dbus_uint32_t handle) 450 { 451 struct record_data *user_record; 452 453 DBG("remove record 0x%x", handle); 454 455 user_record = find_record(serv_adapter, handle, sender); 456 if (!user_record) 457 return -1; 458 459 DBG("listner_id %d", user_record->listener_id); 460 461 g_dbus_remove_watch(conn, user_record->listener_id); 462 463 exit_callback(conn, user_record); 464 465 return 0; 466 } 467 468 static DBusMessage *add_service_record(DBusConnection *conn, 469 DBusMessage *msg, void *data) 470 { 471 struct service_adapter *serv_adapter = data; 472 DBusMessage *reply; 473 const char *sender, *record; 474 dbus_uint32_t handle; 475 int err; 476 477 if (dbus_message_get_args(msg, NULL, 478 DBUS_TYPE_STRING, &record, DBUS_TYPE_INVALID) == FALSE) 479 return NULL; 480 481 sender = dbus_message_get_sender(msg); 482 err = add_xml_record(conn, sender, serv_adapter, record, &handle); 483 if (err < 0) 484 return btd_error_failed(msg, strerror(-err)); 485 486 reply = dbus_message_new_method_return(msg); 487 if (!reply) 488 return NULL; 489 490 dbus_message_append_args(reply, DBUS_TYPE_UINT32, &handle, 491 DBUS_TYPE_INVALID); 492 493 return reply; 494 } 495 496 static DBusMessage *update_service_record(DBusConnection *conn, 497 DBusMessage *msg, void *data) 498 { 499 struct service_adapter *serv_adapter = data; 500 501 return update_xml_record(conn, msg, serv_adapter); 502 } 503 504 static DBusMessage *remove_service_record(DBusConnection *conn, 505 DBusMessage *msg, void *data) 506 { 507 struct service_adapter *serv_adapter = data; 508 dbus_uint32_t handle; 509 const char *sender; 510 511 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle, 512 DBUS_TYPE_INVALID) == FALSE) 513 return NULL; 514 515 sender = dbus_message_get_sender(msg); 516 517 if (remove_record(conn, sender, serv_adapter, handle) < 0) 518 return btd_error_not_available(msg); 519 520 return dbus_message_new_method_return(msg); 521 } 522 523 static void auth_cb(DBusError *derr, void *user_data) 524 { 525 struct service_adapter *serv_adapter = user_data; 526 DBusMessage *reply; 527 struct pending_auth *auth; 528 bdaddr_t src; 529 530 auth = next_pending(serv_adapter); 531 if (auth == NULL) { 532 info("Authorization cancelled: Client exited"); 533 return; 534 } 535 536 if (derr) { 537 error("Access denied: %s", derr->message); 538 539 reply = btd_error_not_authorized(auth->msg); 540 dbus_message_unref(auth->msg); 541 g_dbus_send_message(auth->conn, reply); 542 goto done; 543 } 544 545 g_dbus_send_reply(auth->conn, auth->msg, 546 DBUS_TYPE_INVALID); 547 548 done: 549 dbus_connection_unref(auth->conn); 550 551 serv_adapter->pending_list = g_slist_remove(serv_adapter->pending_list, 552 auth); 553 g_free(auth); 554 555 auth = next_pending(serv_adapter); 556 if (auth == NULL) 557 return; 558 559 if (serv_adapter->adapter) 560 adapter_get_address(serv_adapter->adapter, &src); 561 else 562 bacpy(&src, BDADDR_ANY); 563 564 btd_request_authorization(&src, &auth->dst, 565 auth->uuid, auth_cb, serv_adapter); 566 } 567 568 static DBusMessage *request_authorization(DBusConnection *conn, 569 DBusMessage *msg, void *data) 570 { 571 struct record_data *user_record; 572 struct service_adapter *serv_adapter = data; 573 sdp_record_t *record; 574 sdp_list_t *services; 575 const char *sender; 576 dbus_uint32_t handle; 577 const char *address; 578 struct pending_auth *auth; 579 char uuid_str[MAX_LEN_UUID_STR]; 580 uuid_t *uuid, *uuid128; 581 bdaddr_t src; 582 583 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address, 584 DBUS_TYPE_UINT32, &handle, 585 DBUS_TYPE_INVALID) == FALSE) 586 return NULL; 587 588 sender = dbus_message_get_sender(msg); 589 if (find_pending_by_sender(serv_adapter, sender)) 590 return btd_error_does_not_exist(msg); 591 592 user_record = find_record(serv_adapter, handle, sender); 593 if (!user_record) { 594 user_record = find_record(serv_adapter_any, handle, sender); 595 if (!user_record) 596 return btd_error_not_authorized(msg); 597 } 598 599 record = sdp_record_find(user_record->handle); 600 if (record == NULL) 601 return btd_error_not_authorized(msg); 602 603 if (sdp_get_service_classes(record, &services) < 0) { 604 sdp_record_free(record); 605 return btd_error_not_authorized(msg); 606 } 607 608 if (services == NULL) 609 return btd_error_not_authorized(msg); 610 611 uuid = services->data; 612 uuid128 = sdp_uuid_to_uuid128(uuid); 613 614 sdp_list_free(services, bt_free); 615 616 if (sdp_uuid2strn(uuid128, uuid_str, MAX_LEN_UUID_STR) < 0) { 617 bt_free(uuid128); 618 return btd_error_not_authorized(msg); 619 } 620 bt_free(uuid128); 621 622 auth = g_new0(struct pending_auth, 1); 623 auth->msg = dbus_message_ref(msg); 624 auth->conn = dbus_connection_ref(connection); 625 auth->sender = user_record->sender; 626 memcpy(auth->uuid, uuid_str, MAX_LEN_UUID_STR); 627 str2ba(address, &auth->dst); 628 629 serv_adapter->pending_list = g_slist_append(serv_adapter->pending_list, 630 auth); 631 632 auth = next_pending(serv_adapter); 633 if (auth == NULL) 634 return btd_error_does_not_exist(msg); 635 636 if (serv_adapter->adapter) 637 adapter_get_address(serv_adapter->adapter, &src); 638 else 639 bacpy(&src, BDADDR_ANY); 640 641 if (btd_request_authorization(&src, &auth->dst, auth->uuid, auth_cb, 642 serv_adapter) < 0) { 643 serv_adapter->pending_list = g_slist_remove(serv_adapter->pending_list, 644 auth); 645 g_free(auth); 646 return btd_error_not_authorized(msg); 647 } 648 649 return NULL; 650 } 651 652 static DBusMessage *cancel_authorization(DBusConnection *conn, 653 DBusMessage *msg, void *data) 654 { 655 DBusMessage *reply; 656 struct service_adapter *serv_adapter = data; 657 struct pending_auth *auth; 658 const gchar *sender; 659 bdaddr_t src; 660 661 sender = dbus_message_get_sender(msg); 662 663 auth = find_pending_by_sender(serv_adapter, sender); 664 if (auth == NULL) 665 return btd_error_does_not_exist(msg); 666 667 if (serv_adapter->adapter) 668 adapter_get_address(serv_adapter->adapter, &src); 669 else 670 bacpy(&src, BDADDR_ANY); 671 672 btd_cancel_authorization(&src, &auth->dst); 673 674 reply = btd_error_not_authorized(auth->msg); 675 dbus_message_unref(auth->msg); 676 g_dbus_send_message(auth->conn, reply); 677 678 dbus_connection_unref(auth->conn); 679 680 serv_adapter->pending_list = g_slist_remove(serv_adapter->pending_list, 681 auth); 682 g_free(auth); 683 684 auth = next_pending(serv_adapter); 685 if (auth == NULL) 686 goto done; 687 688 if (serv_adapter->adapter) 689 adapter_get_address(serv_adapter->adapter, &src); 690 else 691 bacpy(&src, BDADDR_ANY); 692 693 btd_request_authorization(&src, &auth->dst, 694 auth->uuid, auth_cb, serv_adapter); 695 696 done: 697 return dbus_message_new_method_return(msg); 698 } 699 700 static GDBusMethodTable service_methods[] = { 701 { "AddRecord", "s", "u", add_service_record }, 702 { "UpdateRecord", "us", "", update_service_record }, 703 { "RemoveRecord", "u", "", remove_service_record }, 704 { "RequestAuthorization","su", "", request_authorization, 705 G_DBUS_METHOD_FLAG_ASYNC}, 706 { "CancelAuthorization", "", "", cancel_authorization }, 707 { } 708 }; 709 710 static void path_unregister(void *data) 711 { 712 struct service_adapter *serv_adapter = data; 713 GSList *l, *next = NULL; 714 715 for (l = serv_adapter->records; l != NULL; l = next) { 716 struct record_data *user_record = l->data; 717 718 next = l->next; 719 720 g_dbus_remove_watch(connection, user_record->listener_id); 721 exit_callback(connection, user_record); 722 } 723 724 g_free(serv_adapter); 725 } 726 727 static int register_interface(const char *path, struct btd_adapter *adapter) 728 { 729 struct service_adapter *serv_adapter; 730 731 DBG("path %s", path); 732 733 serv_adapter = g_try_new0(struct service_adapter, 1); 734 if (serv_adapter == NULL) 735 return -ENOMEM; 736 737 serv_adapter->adapter = adapter; 738 serv_adapter->pending_list = NULL; 739 740 if (g_dbus_register_interface(connection, path, SERVICE_INTERFACE, 741 service_methods, NULL, NULL, serv_adapter, 742 path_unregister) == FALSE) { 743 error("D-Bus failed to register %s interface", 744 SERVICE_INTERFACE); 745 g_free(serv_adapter); 746 return -EIO; 747 } 748 749 DBG("Registered interface %s on path %s", SERVICE_INTERFACE, path); 750 751 if (serv_adapter->adapter == NULL) 752 serv_adapter_any = serv_adapter; 753 754 return 0; 755 } 756 757 static void unregister_interface(const char *path) 758 { 759 DBG("path %s", path); 760 761 g_dbus_unregister_interface(connection, path, SERVICE_INTERFACE); 762 } 763 764 static int service_probe(struct btd_adapter *adapter) 765 { 766 register_interface(adapter_get_path(adapter), adapter); 767 768 return 0; 769 } 770 771 static void service_remove(struct btd_adapter *adapter) 772 { 773 unregister_interface(adapter_get_path(adapter)); 774 } 775 776 static struct btd_adapter_driver service_driver = { 777 .name = "service", 778 .probe = service_probe, 779 .remove = service_remove, 780 }; 781 782 static const char *any_path; 783 784 static int service_init(void) 785 { 786 int err; 787 788 connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); 789 if (connection == NULL) 790 return -EIO; 791 792 any_path = btd_adapter_any_request_path(); 793 if (any_path != NULL) { 794 if (register_interface(any_path, NULL) < 0) { 795 btd_adapter_any_release_path(); 796 any_path = NULL; 797 } 798 } 799 800 err = btd_register_adapter_driver(&service_driver); 801 if (err < 0) { 802 dbus_connection_unref(connection); 803 return err; 804 } 805 806 return 0; 807 } 808 809 static void service_exit(void) 810 { 811 btd_unregister_adapter_driver(&service_driver); 812 813 if (any_path != NULL) { 814 unregister_interface(any_path); 815 816 btd_adapter_any_release_path(); 817 any_path = NULL; 818 } 819 820 dbus_connection_unref(connection); 821 } 822 823 BLUETOOTH_PLUGIN_DEFINE(service, VERSION, 824 BLUETOOTH_PLUGIN_PRIORITY_HIGH, service_init, service_exit) 825