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