summaryrefslogtreecommitdiff
path: root/plugins/service.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/service.c')
-rw-r--r--plugins/service.c832
1 files changed, 0 insertions, 832 deletions
diff --git a/plugins/service.c b/plugins/service.c
deleted file mode 100644
index 288f8496..00000000
--- a/plugins/service.c
+++ /dev/null
@@ -1,832 +0,0 @@
-/*
- *
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2006-2010 Nokia Corporation
- * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
-
-#include <gdbus.h>
-
-#include "sdpd.h"
-#include "sdp-xml.h"
-#include "plugin.h"
-#include "adapter.h"
-#include "error.h"
-#include "log.h"
-
-#define SERVICE_INTERFACE "org.bluez.Service"
-
-static DBusConnection *connection;
-
-struct record_data {
- uint32_t handle;
- char *sender;
- guint listener_id;
- struct service_adapter *serv_adapter;
-};
-
-struct context_data {
- sdp_record_t *record;
- sdp_data_t attr_data;
- struct sdp_xml_data *stack_head;
- uint16_t attr_id;
-};
-
-struct pending_auth {
- DBusConnection *conn;
- DBusMessage *msg;
- char *sender;
- bdaddr_t dst;
- char uuid[MAX_LEN_UUID_STR];
-};
-
-struct service_adapter {
- struct btd_adapter *adapter;
- GSList *pending_list;
- GSList *records;
-};
-
-static struct service_adapter *serv_adapter_any = NULL;
-
-static int compute_seq_size(sdp_data_t *data)
-{
- int unit_size = data->unitSize;
- sdp_data_t *seq = data->val.dataseq;
-
- for (; seq; seq = seq->next)
- unit_size += seq->unitSize;
-
- return unit_size;
-}
-
-static void element_start(GMarkupParseContext *context,
- const gchar *element_name, const gchar **attribute_names,
- const gchar **attribute_values, gpointer user_data, GError **err)
-{
- struct context_data *ctx_data = user_data;
-
- if (!strcmp(element_name, "record"))
- return;
-
- if (!strcmp(element_name, "attribute")) {
- int i;
- for (i = 0; attribute_names[i]; i++) {
- if (!strcmp(attribute_names[i], "id")) {
- ctx_data->attr_id = strtol(attribute_values[i], 0, 0);
- break;
- }
- }
- DBG("New attribute 0x%04x", ctx_data->attr_id);
- return;
- }
-
- if (ctx_data->stack_head) {
- struct sdp_xml_data *newelem = sdp_xml_data_alloc();
- newelem->next = ctx_data->stack_head;
- ctx_data->stack_head = newelem;
- } else {
- ctx_data->stack_head = sdp_xml_data_alloc();
- ctx_data->stack_head->next = NULL;
- }
-
- if (!strcmp(element_name, "sequence"))
- ctx_data->stack_head->data = sdp_data_alloc(SDP_SEQ8, NULL);
- else if (!strcmp(element_name, "alternate"))
- ctx_data->stack_head->data = sdp_data_alloc(SDP_ALT8, NULL);
- else {
- int i;
- /* Parse value, name, encoding */
- for (i = 0; attribute_names[i]; i++) {
- if (!strcmp(attribute_names[i], "value")) {
- int curlen = strlen(ctx_data->stack_head->text);
- int attrlen = strlen(attribute_values[i]);
-
- /* Ensure we're big enough */
- while ((curlen + 1 + attrlen) > ctx_data->stack_head->size) {
- sdp_xml_data_expand(ctx_data->stack_head);
- }
-
- memcpy(ctx_data->stack_head->text + curlen,
- attribute_values[i], attrlen);
- ctx_data->stack_head->text[curlen + attrlen] = '\0';
- }
-
- if (!strcmp(attribute_names[i], "encoding")) {
- if (!strcmp(attribute_values[i], "hex"))
- ctx_data->stack_head->type = 1;
- }
-
- if (!strcmp(attribute_names[i], "name")) {
- ctx_data->stack_head->name = strdup(attribute_values[i]);
- }
- }
-
- ctx_data->stack_head->data = sdp_xml_parse_datatype(element_name,
- ctx_data->stack_head, ctx_data->record);
-
- if (ctx_data->stack_head->data == NULL)
- error("Can't parse element %s", element_name);
- }
-}
-
-static void element_end(GMarkupParseContext *context,
- const gchar *element_name, gpointer user_data, GError **err)
-{
- struct context_data *ctx_data = user_data;
- struct sdp_xml_data *elem;
-
- if (!strcmp(element_name, "record"))
- return;
-
- if (!strcmp(element_name, "attribute")) {
- if (ctx_data->stack_head && ctx_data->stack_head->data) {
- int ret = sdp_attr_add(ctx_data->record, ctx_data->attr_id,
- ctx_data->stack_head->data);
- if (ret == -1)
- DBG("Could not add attribute 0x%04x",
- ctx_data->attr_id);
-
- ctx_data->stack_head->data = NULL;
- sdp_xml_data_free(ctx_data->stack_head);
- ctx_data->stack_head = NULL;
- } else {
- DBG("No data for attribute 0x%04x", ctx_data->attr_id);
- }
- return;
- }
-
- if (!strcmp(element_name, "sequence")) {
- ctx_data->stack_head->data->unitSize = compute_seq_size(ctx_data->stack_head->data);
-
- if (ctx_data->stack_head->data->unitSize > USHRT_MAX) {
- ctx_data->stack_head->data->unitSize += sizeof(uint32_t);
- ctx_data->stack_head->data->dtd = SDP_SEQ32;
- } else if (ctx_data->stack_head->data->unitSize > UCHAR_MAX) {
- ctx_data->stack_head->data->unitSize += sizeof(uint16_t);
- ctx_data->stack_head->data->dtd = SDP_SEQ16;
- } else {
- ctx_data->stack_head->data->unitSize += sizeof(uint8_t);
- }
- } else if (!strcmp(element_name, "alternate")) {
- ctx_data->stack_head->data->unitSize = compute_seq_size(ctx_data->stack_head->data);
-
- if (ctx_data->stack_head->data->unitSize > USHRT_MAX) {
- ctx_data->stack_head->data->unitSize += sizeof(uint32_t);
- ctx_data->stack_head->data->dtd = SDP_ALT32;
- } else if (ctx_data->stack_head->data->unitSize > UCHAR_MAX) {
- ctx_data->stack_head->data->unitSize += sizeof(uint16_t);
- ctx_data->stack_head->data->dtd = SDP_ALT16;
- } else {
- ctx_data->stack_head->data->unitSize += sizeof(uint8_t);
- }
- }
-
- if (ctx_data->stack_head->next && ctx_data->stack_head->data &&
- ctx_data->stack_head->next->data) {
- switch (ctx_data->stack_head->next->data->dtd) {
- case SDP_SEQ8:
- case SDP_SEQ16:
- case SDP_SEQ32:
- case SDP_ALT8:
- case SDP_ALT16:
- case SDP_ALT32:
- ctx_data->stack_head->next->data->val.dataseq =
- sdp_seq_append(ctx_data->stack_head->next->data->val.dataseq,
- ctx_data->stack_head->data);
- ctx_data->stack_head->data = NULL;
- break;
- }
-
- elem = ctx_data->stack_head;
- ctx_data->stack_head = ctx_data->stack_head->next;
-
- sdp_xml_data_free(elem);
- }
-}
-
-static GMarkupParser parser = {
- element_start, element_end, NULL, NULL, NULL
-};
-
-static sdp_record_t *sdp_xml_parse_record(const char *data, int size)
-{
- GMarkupParseContext *ctx;
- struct context_data *ctx_data;
- sdp_record_t *record;
-
- ctx_data = malloc(sizeof(*ctx_data));
- if (!ctx_data)
- return NULL;
-
- record = sdp_record_alloc();
- if (!record) {
- free(ctx_data);
- return NULL;
- }
-
- memset(ctx_data, 0, sizeof(*ctx_data));
- ctx_data->record = record;
-
- ctx = g_markup_parse_context_new(&parser, 0, ctx_data, NULL);
-
- if (g_markup_parse_context_parse(ctx, data, size, NULL) == FALSE) {
- error("XML parsing error");
- g_markup_parse_context_free(ctx);
- sdp_record_free(record);
- free(ctx_data);
- return NULL;
- }
-
- g_markup_parse_context_free(ctx);
-
- free(ctx_data);
-
- return record;
-}
-
-static struct record_data *find_record(struct service_adapter *serv_adapter,
- uint32_t handle, const char *sender)
-{
- GSList *list;
-
- for (list = serv_adapter->records; list; list = list->next) {
- struct record_data *data = list->data;
- if (handle == data->handle && !strcmp(sender, data->sender))
- return data;
- }
-
- return NULL;
-}
-
-static struct pending_auth *next_pending(struct service_adapter *serv_adapter)
-{
- GSList *l = serv_adapter->pending_list;
-
- if (l) {
- struct pending_auth *auth = l->data;
- return auth;
- }
-
- return NULL;
-}
-
-static struct pending_auth *find_pending_by_sender(
- struct service_adapter *serv_adapter,
- const char *sender)
-{
- GSList *l = serv_adapter->pending_list;
-
- for (; l; l = l->next) {
- struct pending_auth *auth = l->data;
- if (g_str_equal(auth->sender, sender))
- return auth;
- }
-
- return NULL;
-}
-
-static void exit_callback(DBusConnection *conn, void *user_data)
-{
- struct record_data *user_record = user_data;
- struct service_adapter *serv_adapter = user_record->serv_adapter;
- struct pending_auth *auth;
-
- DBG("remove record");
-
- serv_adapter->records = g_slist_remove(serv_adapter->records,
- user_record);
-
- auth = find_pending_by_sender(serv_adapter, user_record->sender);
- if (auth) {
- serv_adapter->pending_list = g_slist_remove(serv_adapter->pending_list,
- auth);
- g_free(auth);
- }
-
- remove_record_from_server(user_record->handle);
-
- g_free(user_record->sender);
- g_free(user_record);
-}
-
-static int add_xml_record(DBusConnection *conn, const char *sender,
- struct service_adapter *serv_adapter,
- const char *record, dbus_uint32_t *handle)
-{
- struct record_data *user_record;
- sdp_record_t *sdp_record;
- bdaddr_t src;
-
- sdp_record = sdp_xml_parse_record(record, strlen(record));
- if (!sdp_record) {
- error("Parsing of XML service record failed");
- return -EIO;
- }
-
- if (serv_adapter->adapter)
- adapter_get_address(serv_adapter->adapter, &src);
- else
- bacpy(&src, BDADDR_ANY);
-
- if (add_record_to_server(&src, sdp_record) < 0) {
- error("Failed to register service record");
- sdp_record_free(sdp_record);
- return -EIO;
- }
-
- user_record = g_new0(struct record_data, 1);
- user_record->handle = sdp_record->handle;
- user_record->sender = g_strdup(sender);
- user_record->serv_adapter = serv_adapter;
- user_record->listener_id = g_dbus_add_disconnect_watch(conn, sender,
- exit_callback, user_record, NULL);
-
- serv_adapter->records = g_slist_append(serv_adapter->records,
- user_record);
-
- DBG("listener_id %d", user_record->listener_id);
-
- *handle = user_record->handle;
-
- return 0;
-}
-
-static DBusMessage *update_record(DBusConnection *conn, DBusMessage *msg,
- struct service_adapter *serv_adapter,
- dbus_uint32_t handle, sdp_record_t *sdp_record)
-{
- bdaddr_t src;
- int err;
-
- if (remove_record_from_server(handle) < 0) {
- sdp_record_free(sdp_record);
- return btd_error_not_available(msg);
- }
-
- if (serv_adapter->adapter)
- adapter_get_address(serv_adapter->adapter, &src);
- else
- bacpy(&src, BDADDR_ANY);
-
- sdp_record->handle = handle;
- err = add_record_to_server(&src, sdp_record);
- if (err < 0) {
- sdp_record_free(sdp_record);
- error("Failed to update the service record");
- return btd_error_failed(msg, strerror(-err));
- }
-
- return dbus_message_new_method_return(msg);
-}
-
-static DBusMessage *update_xml_record(DBusConnection *conn,
- DBusMessage *msg,
- struct service_adapter *serv_adapter)
-{
- struct record_data *user_record;
- sdp_record_t *sdp_record;
- const char *record;
- dbus_uint32_t handle;
- int len;
-
- if (dbus_message_get_args(msg, NULL,
- DBUS_TYPE_UINT32, &handle,
- DBUS_TYPE_STRING, &record,
- DBUS_TYPE_INVALID) == FALSE)
- return NULL;
-
- len = (record ? strlen(record) : 0);
- if (len == 0)
- return btd_error_invalid_args(msg);
-
- user_record = find_record(serv_adapter, handle,
- dbus_message_get_sender(msg));
- if (!user_record)
- return btd_error_not_available(msg);
-
- sdp_record = sdp_xml_parse_record(record, len);
- if (!sdp_record) {
- error("Parsing of XML service record failed");
- return btd_error_failed(msg,
- "Parsing of XML service record failed");
- }
-
- return update_record(conn, msg, serv_adapter, handle, sdp_record);
-}
-
-static int remove_record(DBusConnection *conn, const char *sender,
- struct service_adapter *serv_adapter,
- dbus_uint32_t handle)
-{
- struct record_data *user_record;
-
- DBG("remove record 0x%x", handle);
-
- user_record = find_record(serv_adapter, handle, sender);
- if (!user_record)
- return -1;
-
- DBG("listner_id %d", user_record->listener_id);
-
- g_dbus_remove_watch(conn, user_record->listener_id);
-
- exit_callback(conn, user_record);
-
- return 0;
-}
-
-static DBusMessage *add_service_record(DBusConnection *conn,
- DBusMessage *msg, void *data)
-{
- struct service_adapter *serv_adapter = data;
- DBusMessage *reply;
- const char *sender, *record;
- dbus_uint32_t handle;
- int err;
-
- if (dbus_message_get_args(msg, NULL,
- DBUS_TYPE_STRING, &record, DBUS_TYPE_INVALID) == FALSE)
- return NULL;
-
- sender = dbus_message_get_sender(msg);
- err = add_xml_record(conn, sender, serv_adapter, record, &handle);
- if (err < 0)
- return btd_error_failed(msg, strerror(-err));
-
- reply = dbus_message_new_method_return(msg);
- if (!reply)
- return NULL;
-
- dbus_message_append_args(reply, DBUS_TYPE_UINT32, &handle,
- DBUS_TYPE_INVALID);
-
- return reply;
-}
-
-static DBusMessage *update_service_record(DBusConnection *conn,
- DBusMessage *msg, void *data)
-{
- struct service_adapter *serv_adapter = data;
-
- return update_xml_record(conn, msg, serv_adapter);
-}
-
-static DBusMessage *remove_service_record(DBusConnection *conn,
- DBusMessage *msg, void *data)
-{
- struct service_adapter *serv_adapter = data;
- dbus_uint32_t handle;
- const char *sender;
-
- if (dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle,
- DBUS_TYPE_INVALID) == FALSE)
- return NULL;
-
- sender = dbus_message_get_sender(msg);
-
- if (remove_record(conn, sender, serv_adapter, handle) < 0)
- return btd_error_not_available(msg);
-
- return dbus_message_new_method_return(msg);
-}
-
-static void auth_cb(DBusError *derr, void *user_data)
-{
- struct service_adapter *serv_adapter = user_data;
- DBusMessage *reply;
- struct pending_auth *auth;
- bdaddr_t src;
-
- auth = next_pending(serv_adapter);
- if (auth == NULL) {
- info("Authorization cancelled: Client exited");
- return;
- }
-
- if (derr) {
- error("Access denied: %s", derr->message);
-
- reply = btd_error_not_authorized(auth->msg);
- dbus_message_unref(auth->msg);
- g_dbus_send_message(auth->conn, reply);
- goto done;
- }
-
- g_dbus_send_reply(auth->conn, auth->msg,
- DBUS_TYPE_INVALID);
-
-done:
- dbus_connection_unref(auth->conn);
-
- serv_adapter->pending_list = g_slist_remove(serv_adapter->pending_list,
- auth);
- g_free(auth);
-
- auth = next_pending(serv_adapter);
- if (auth == NULL)
- return;
-
- if (serv_adapter->adapter)
- adapter_get_address(serv_adapter->adapter, &src);
- else
- bacpy(&src, BDADDR_ANY);
-
- btd_request_authorization(&src, &auth->dst,
- auth->uuid, auth_cb, serv_adapter);
-}
-
-static DBusMessage *request_authorization(DBusConnection *conn,
- DBusMessage *msg, void *data)
-{
- struct record_data *user_record;
- struct service_adapter *serv_adapter = data;
- sdp_record_t *record;
- sdp_list_t *services;
- const char *sender;
- dbus_uint32_t handle;
- const char *address;
- struct pending_auth *auth;
- char uuid_str[MAX_LEN_UUID_STR];
- uuid_t *uuid, *uuid128;
- bdaddr_t src;
-
- if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
- DBUS_TYPE_UINT32, &handle,
- DBUS_TYPE_INVALID) == FALSE)
- return NULL;
-
- sender = dbus_message_get_sender(msg);
- if (find_pending_by_sender(serv_adapter, sender))
- return btd_error_does_not_exist(msg);
-
- user_record = find_record(serv_adapter, handle, sender);
- if (!user_record) {
- user_record = find_record(serv_adapter_any, handle, sender);
- if (!user_record)
- return btd_error_not_authorized(msg);
- }
-
- record = sdp_record_find(user_record->handle);
- if (record == NULL)
- return btd_error_not_authorized(msg);
-
- if (sdp_get_service_classes(record, &services) < 0) {
- sdp_record_free(record);
- return btd_error_not_authorized(msg);
- }
-
- if (services == NULL)
- return btd_error_not_authorized(msg);
-
- uuid = services->data;
- uuid128 = sdp_uuid_to_uuid128(uuid);
-
- sdp_list_free(services, bt_free);
-
- if (sdp_uuid2strn(uuid128, uuid_str, MAX_LEN_UUID_STR) < 0) {
- bt_free(uuid128);
- return btd_error_not_authorized(msg);
- }
- bt_free(uuid128);
-
- auth = g_new0(struct pending_auth, 1);
- auth->msg = dbus_message_ref(msg);
- auth->conn = dbus_connection_ref(connection);
- auth->sender = user_record->sender;
- memcpy(auth->uuid, uuid_str, MAX_LEN_UUID_STR);
- str2ba(address, &auth->dst);
-
- serv_adapter->pending_list = g_slist_append(serv_adapter->pending_list,
- auth);
-
- auth = next_pending(serv_adapter);
- if (auth == NULL)
- return btd_error_does_not_exist(msg);
-
- if (serv_adapter->adapter)
- adapter_get_address(serv_adapter->adapter, &src);
- else
- bacpy(&src, BDADDR_ANY);
-
- if (btd_request_authorization(&src, &auth->dst, auth->uuid, auth_cb,
- serv_adapter) < 0) {
- serv_adapter->pending_list = g_slist_remove(serv_adapter->pending_list,
- auth);
- g_free(auth);
- return btd_error_not_authorized(msg);
- }
-
- return NULL;
-}
-
-static DBusMessage *cancel_authorization(DBusConnection *conn,
- DBusMessage *msg, void *data)
-{
- DBusMessage *reply;
- struct service_adapter *serv_adapter = data;
- struct pending_auth *auth;
- const gchar *sender;
- bdaddr_t src;
-
- sender = dbus_message_get_sender(msg);
-
- auth = find_pending_by_sender(serv_adapter, sender);
- if (auth == NULL)
- return btd_error_does_not_exist(msg);
-
- if (serv_adapter->adapter)
- adapter_get_address(serv_adapter->adapter, &src);
- else
- bacpy(&src, BDADDR_ANY);
-
- btd_cancel_authorization(&src, &auth->dst);
-
- reply = btd_error_not_authorized(auth->msg);
- dbus_message_unref(auth->msg);
- g_dbus_send_message(auth->conn, reply);
-
- dbus_connection_unref(auth->conn);
-
- serv_adapter->pending_list = g_slist_remove(serv_adapter->pending_list,
- auth);
- g_free(auth);
-
- auth = next_pending(serv_adapter);
- if (auth == NULL)
- goto done;
-
- if (serv_adapter->adapter)
- adapter_get_address(serv_adapter->adapter, &src);
- else
- bacpy(&src, BDADDR_ANY);
-
- btd_request_authorization(&src, &auth->dst,
- auth->uuid, auth_cb, serv_adapter);
-
-done:
- return dbus_message_new_method_return(msg);
-}
-
-static const GDBusMethodTable service_methods[] = {
- { GDBUS_METHOD("AddRecord",
- GDBUS_ARGS({ "record", "s" }),
- GDBUS_ARGS({ "handle", "u" }),
- add_service_record) },
- { GDBUS_METHOD("UpdateRecord",
- GDBUS_ARGS({ "handle", "u" }, { "record", "s" }), NULL,
- update_service_record) },
- { GDBUS_METHOD("RemoveRecord",
- GDBUS_ARGS({ "handle", "u" }), NULL,
- remove_service_record) },
- { GDBUS_ASYNC_METHOD("RequestAuthorization",
- GDBUS_ARGS({ "address", "s" }, { "handle", "u"}), NULL,
- request_authorization) },
- { GDBUS_METHOD("CancelAuthorization",
- NULL, NULL, cancel_authorization) },
- { }
-};
-
-static void path_unregister(void *data)
-{
- struct service_adapter *serv_adapter = data;
- GSList *l, *next = NULL;
-
- for (l = serv_adapter->records; l != NULL; l = next) {
- struct record_data *user_record = l->data;
-
- next = l->next;
-
- g_dbus_remove_watch(connection, user_record->listener_id);
- exit_callback(connection, user_record);
- }
-
- g_free(serv_adapter);
-}
-
-static int register_interface(const char *path, struct btd_adapter *adapter)
-{
- struct service_adapter *serv_adapter;
-
- DBG("path %s", path);
-
- serv_adapter = g_try_new0(struct service_adapter, 1);
- if (serv_adapter == NULL)
- return -ENOMEM;
-
- serv_adapter->adapter = adapter;
- serv_adapter->pending_list = NULL;
-
- if (g_dbus_register_interface(connection, path, SERVICE_INTERFACE,
- service_methods, NULL, NULL, serv_adapter,
- path_unregister) == FALSE) {
- error("D-Bus failed to register %s interface",
- SERVICE_INTERFACE);
- g_free(serv_adapter);
- return -EIO;
- }
-
- DBG("Registered interface %s on path %s", SERVICE_INTERFACE, path);
-
- if (serv_adapter->adapter == NULL)
- serv_adapter_any = serv_adapter;
-
- return 0;
-}
-
-static void unregister_interface(const char *path)
-{
- DBG("path %s", path);
-
- g_dbus_unregister_interface(connection, path, SERVICE_INTERFACE);
-}
-
-static int service_probe(struct btd_adapter *adapter)
-{
- register_interface(adapter_get_path(adapter), adapter);
-
- return 0;
-}
-
-static void service_remove(struct btd_adapter *adapter)
-{
- unregister_interface(adapter_get_path(adapter));
-}
-
-static struct btd_adapter_driver service_driver = {
- .name = "service",
- .probe = service_probe,
- .remove = service_remove,
-};
-
-static const char *any_path;
-
-static int service_init(void)
-{
- int err;
-
- connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
- if (connection == NULL)
- return -EIO;
-
- any_path = btd_adapter_any_request_path();
- if (any_path != NULL) {
- if (register_interface(any_path, NULL) < 0) {
- btd_adapter_any_release_path();
- any_path = NULL;
- }
- }
-
- err = btd_register_adapter_driver(&service_driver);
- if (err < 0) {
- dbus_connection_unref(connection);
- return err;
- }
-
- return 0;
-}
-
-static void service_exit(void)
-{
- btd_unregister_adapter_driver(&service_driver);
-
- if (any_path != NULL) {
- unregister_interface(any_path);
-
- btd_adapter_any_release_path();
- any_path = NULL;
- }
-
- dbus_connection_unref(connection);
-}
-
-BLUETOOTH_PLUGIN_DEFINE(service, VERSION,
- BLUETOOTH_PLUGIN_PRIORITY_HIGH, service_init, service_exit)