3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2006-2010 Nokia Corporation
6 * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
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.
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.
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
33 #include <bluetooth/bluetooth.h>
34 #include <bluetooth/sdp.h>
35 #include <bluetooth/sdp_lib.h>
46 #define SERVICE_INTERFACE "org.bluez.Service"
48 static DBusConnection *connection;
54 struct service_adapter *serv_adapter;
60 struct sdp_xml_data *stack_head;
69 char uuid[MAX_LEN_UUID_STR];
72 struct service_adapter {
73 struct btd_adapter *adapter;
78 static struct service_adapter *serv_adapter_any = NULL;
80 static int compute_seq_size(sdp_data_t *data)
82 int unit_size = data->unitSize;
83 sdp_data_t *seq = data->val.dataseq;
85 for (; seq; seq = seq->next)
86 unit_size += seq->unitSize;
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)
95 struct context_data *ctx_data = user_data;
97 if (!strcmp(element_name, "record"))
100 if (!strcmp(element_name, "attribute")) {
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);
108 DBG("New attribute 0x%04x", ctx_data->attr_id);
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;
117 ctx_data->stack_head = sdp_xml_data_alloc();
118 ctx_data->stack_head->next = NULL;
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);
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]);
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);
138 memcpy(ctx_data->stack_head->text + curlen,
139 attribute_values[i], attrlen);
140 ctx_data->stack_head->text[curlen + attrlen] = '\0';
143 if (!strcmp(attribute_names[i], "encoding")) {
144 if (!strcmp(attribute_values[i], "hex"))
145 ctx_data->stack_head->type = 1;
148 if (!strcmp(attribute_names[i], "name")) {
149 ctx_data->stack_head->name = strdup(attribute_values[i]);
153 ctx_data->stack_head->data = sdp_xml_parse_datatype(element_name,
154 ctx_data->stack_head, ctx_data->record);
156 if (ctx_data->stack_head->data == NULL)
157 error("Can't parse element %s", element_name);
161 static void element_end(GMarkupParseContext *context,
162 const gchar *element_name, gpointer user_data, GError **err)
164 struct context_data *ctx_data = user_data;
165 struct sdp_xml_data *elem;
167 if (!strcmp(element_name, "record"))
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);
175 DBG("Could not add attribute 0x%04x",
178 ctx_data->stack_head->data = NULL;
179 sdp_xml_data_free(ctx_data->stack_head);
180 ctx_data->stack_head = NULL;
182 DBG("No data for attribute 0x%04x", ctx_data->attr_id);
187 if (!strcmp(element_name, "sequence")) {
188 ctx_data->stack_head->data->unitSize = compute_seq_size(ctx_data->stack_head->data);
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;
197 ctx_data->stack_head->data->unitSize += sizeof(uint8_t);
199 } else if (!strcmp(element_name, "alternate")) {
200 ctx_data->stack_head->data->unitSize = compute_seq_size(ctx_data->stack_head->data);
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;
209 ctx_data->stack_head->data->unitSize += sizeof(uint8_t);
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) {
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;
229 elem = ctx_data->stack_head;
230 ctx_data->stack_head = ctx_data->stack_head->next;
232 sdp_xml_data_free(elem);
236 static GMarkupParser parser = {
237 element_start, element_end, NULL, NULL, NULL
240 static sdp_record_t *sdp_xml_parse_record(const char *data, int size)
242 GMarkupParseContext *ctx;
243 struct context_data *ctx_data;
244 sdp_record_t *record;
246 ctx_data = malloc(sizeof(*ctx_data));
250 record = sdp_record_alloc();
256 memset(ctx_data, 0, sizeof(*ctx_data));
257 ctx_data->record = record;
259 ctx = g_markup_parse_context_new(&parser, 0, ctx_data, NULL);
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);
269 g_markup_parse_context_free(ctx);
276 static struct record_data *find_record(struct service_adapter *serv_adapter,
277 uint32_t handle, const char *sender)
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))
290 static struct pending_auth *next_pending(struct service_adapter *serv_adapter)
292 GSList *l = serv_adapter->pending_list;
295 struct pending_auth *auth = l->data;
302 static struct pending_auth *find_pending_by_sender(
303 struct service_adapter *serv_adapter,
306 GSList *l = serv_adapter->pending_list;
308 for (; l; l = l->next) {
309 struct pending_auth *auth = l->data;
310 if (g_str_equal(auth->sender, sender))
317 static void exit_callback(DBusConnection *conn, void *user_data)
319 struct record_data *user_record = user_data;
320 struct service_adapter *serv_adapter = user_record->serv_adapter;
321 struct pending_auth *auth;
323 DBG("remove record");
325 serv_adapter->records = g_slist_remove(serv_adapter->records,
328 auth = find_pending_by_sender(serv_adapter, user_record->sender);
330 serv_adapter->pending_list = g_slist_remove(serv_adapter->pending_list,
335 remove_record_from_server(user_record->handle);
337 g_free(user_record->sender);
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)
345 struct record_data *user_record;
346 sdp_record_t *sdp_record;
349 sdp_record = sdp_xml_parse_record(record, strlen(record));
351 error("Parsing of XML service record failed");
355 if (serv_adapter->adapter)
356 adapter_get_address(serv_adapter->adapter, &src);
358 bacpy(&src, BDADDR_ANY);
360 if (add_record_to_server(&src, sdp_record) < 0) {
361 error("Failed to register service record");
362 sdp_record_free(sdp_record);
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);
373 serv_adapter->records = g_slist_append(serv_adapter->records,
376 DBG("listener_id %d", user_record->listener_id);
378 *handle = user_record->handle;
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)
390 if (remove_record_from_server(handle) < 0) {
391 sdp_record_free(sdp_record);
392 return btd_error_not_available(msg);
395 if (serv_adapter->adapter)
396 adapter_get_address(serv_adapter->adapter, &src);
398 bacpy(&src, BDADDR_ANY);
400 sdp_record->handle = handle;
401 err = add_record_to_server(&src, sdp_record);
403 sdp_record_free(sdp_record);
404 error("Failed to update the service record");
405 return btd_error_failed(msg, strerror(-err));
408 return dbus_message_new_method_return(msg);
411 static DBusMessage *update_xml_record(DBusConnection *conn,
413 struct service_adapter *serv_adapter)
415 struct record_data *user_record;
416 sdp_record_t *sdp_record;
418 dbus_uint32_t handle;
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 btd_error_invalid_args(msg);
427 len = (record ? strlen(record) : 0);
429 return btd_error_invalid_args(msg);
431 user_record = find_record(serv_adapter, handle,
432 dbus_message_get_sender(msg));
434 return btd_error_not_available(msg);
436 sdp_record = sdp_xml_parse_record(record, len);
438 error("Parsing of XML service record failed");
439 return btd_error_failed(msg,
440 "Parsing of XML service record failed");
443 return update_record(conn, msg, serv_adapter, handle, sdp_record);
446 static int remove_record(DBusConnection *conn, const char *sender,
447 struct service_adapter *serv_adapter,
448 dbus_uint32_t handle)
450 struct record_data *user_record;
452 DBG("remove record 0x%x", handle);
454 user_record = find_record(serv_adapter, handle, sender);
458 DBG("listner_id %d", user_record->listener_id);
460 g_dbus_remove_watch(conn, user_record->listener_id);
462 exit_callback(conn, user_record);
467 static DBusMessage *add_service_record(DBusConnection *conn,
468 DBusMessage *msg, void *data)
470 struct service_adapter *serv_adapter = data;
472 const char *sender, *record;
473 dbus_uint32_t handle;
476 if (dbus_message_get_args(msg, NULL,
477 DBUS_TYPE_STRING, &record, DBUS_TYPE_INVALID) == FALSE)
478 return btd_error_invalid_args(msg);
480 sender = dbus_message_get_sender(msg);
481 err = add_xml_record(conn, sender, serv_adapter, record, &handle);
483 return btd_error_failed(msg, strerror(-err));
485 reply = dbus_message_new_method_return(msg);
489 dbus_message_append_args(reply, DBUS_TYPE_UINT32, &handle,
495 static DBusMessage *update_service_record(DBusConnection *conn,
496 DBusMessage *msg, void *data)
498 struct service_adapter *serv_adapter = data;
500 return update_xml_record(conn, msg, serv_adapter);
503 static DBusMessage *remove_service_record(DBusConnection *conn,
504 DBusMessage *msg, void *data)
506 struct service_adapter *serv_adapter = data;
507 dbus_uint32_t handle;
510 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle,
511 DBUS_TYPE_INVALID) == FALSE)
512 return btd_error_invalid_args(msg);
514 sender = dbus_message_get_sender(msg);
516 if (remove_record(conn, sender, serv_adapter, handle) < 0)
517 return btd_error_not_available(msg);
519 return dbus_message_new_method_return(msg);
522 static void auth_cb(DBusError *derr, void *user_data)
524 struct service_adapter *serv_adapter = user_data;
526 struct pending_auth *auth;
529 auth = next_pending(serv_adapter);
531 info("Authorization cancelled: Client exited");
536 error("Access denied: %s", derr->message);
538 reply = btd_error_not_authorized(auth->msg);
539 dbus_message_unref(auth->msg);
540 g_dbus_send_message(auth->conn, reply);
544 g_dbus_send_reply(auth->conn, auth->msg,
548 dbus_connection_unref(auth->conn);
550 serv_adapter->pending_list = g_slist_remove(serv_adapter->pending_list,
554 auth = next_pending(serv_adapter);
558 if (serv_adapter->adapter)
559 adapter_get_address(serv_adapter->adapter, &src);
561 bacpy(&src, BDADDR_ANY);
563 btd_request_authorization(&src, &auth->dst,
564 auth->uuid, auth_cb, serv_adapter);
567 static DBusMessage *request_authorization(DBusConnection *conn,
568 DBusMessage *msg, void *data)
570 struct record_data *user_record;
571 struct service_adapter *serv_adapter = data;
572 sdp_record_t *record;
573 sdp_list_t *services;
575 dbus_uint32_t handle;
577 struct pending_auth *auth;
578 char uuid_str[MAX_LEN_UUID_STR];
579 uuid_t *uuid, *uuid128;
582 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
583 DBUS_TYPE_UINT32, &handle,
584 DBUS_TYPE_INVALID) == FALSE)
585 return btd_error_invalid_args(msg);
587 sender = dbus_message_get_sender(msg);
588 if (find_pending_by_sender(serv_adapter, sender))
589 return btd_error_does_not_exist(msg);
591 user_record = find_record(serv_adapter, handle, sender);
593 user_record = find_record(serv_adapter_any, handle, sender);
595 return btd_error_not_authorized(msg);
598 record = sdp_record_find(user_record->handle);
600 return btd_error_not_authorized(msg);
602 if (sdp_get_service_classes(record, &services) < 0) {
603 sdp_record_free(record);
604 return btd_error_not_authorized(msg);
607 if (services == NULL)
608 return btd_error_not_authorized(msg);
610 uuid = services->data;
611 uuid128 = sdp_uuid_to_uuid128(uuid);
613 sdp_list_free(services, bt_free);
615 if (sdp_uuid2strn(uuid128, uuid_str, MAX_LEN_UUID_STR) < 0) {
617 return btd_error_not_authorized(msg);
621 auth = g_new0(struct pending_auth, 1);
622 auth->msg = dbus_message_ref(msg);
623 auth->conn = dbus_connection_ref(connection);
624 auth->sender = user_record->sender;
625 memcpy(auth->uuid, uuid_str, MAX_LEN_UUID_STR);
626 str2ba(address, &auth->dst);
628 serv_adapter->pending_list = g_slist_append(serv_adapter->pending_list,
631 auth = next_pending(serv_adapter);
633 return btd_error_does_not_exist(msg);
635 if (serv_adapter->adapter)
636 adapter_get_address(serv_adapter->adapter, &src);
638 bacpy(&src, BDADDR_ANY);
640 if (btd_request_authorization(&src, &auth->dst, auth->uuid, auth_cb,
642 serv_adapter->pending_list = g_slist_remove(serv_adapter->pending_list,
645 return btd_error_not_authorized(msg);
651 static DBusMessage *cancel_authorization(DBusConnection *conn,
652 DBusMessage *msg, void *data)
655 struct service_adapter *serv_adapter = data;
656 struct pending_auth *auth;
660 sender = dbus_message_get_sender(msg);
662 auth = find_pending_by_sender(serv_adapter, sender);
664 return btd_error_does_not_exist(msg);
666 if (serv_adapter->adapter)
667 adapter_get_address(serv_adapter->adapter, &src);
669 bacpy(&src, BDADDR_ANY);
671 btd_cancel_authorization(&src, &auth->dst);
673 reply = btd_error_not_authorized(auth->msg);
674 dbus_message_unref(auth->msg);
675 g_dbus_send_message(auth->conn, reply);
677 dbus_connection_unref(auth->conn);
679 serv_adapter->pending_list = g_slist_remove(serv_adapter->pending_list,
683 auth = next_pending(serv_adapter);
687 if (serv_adapter->adapter)
688 adapter_get_address(serv_adapter->adapter, &src);
690 bacpy(&src, BDADDR_ANY);
692 btd_request_authorization(&src, &auth->dst,
693 auth->uuid, auth_cb, serv_adapter);
696 return dbus_message_new_method_return(msg);
699 static const GDBusMethodTable service_methods[] = {
700 { GDBUS_METHOD("AddRecord",
701 GDBUS_ARGS({ "record", "s" }),
702 GDBUS_ARGS({ "handle", "u" }),
703 add_service_record) },
704 { GDBUS_METHOD("UpdateRecord",
705 GDBUS_ARGS({ "handle", "u" }, { "record", "s" }), NULL,
706 update_service_record) },
707 { GDBUS_METHOD("RemoveRecord",
708 GDBUS_ARGS({ "handle", "u" }), NULL,
709 remove_service_record) },
710 { GDBUS_ASYNC_METHOD("RequestAuthorization",
711 GDBUS_ARGS({ "address", "s" }, { "handle", "u"}), NULL,
712 request_authorization) },
713 { GDBUS_METHOD("CancelAuthorization",
714 NULL, NULL, cancel_authorization) },
718 static void path_unregister(void *data)
720 struct service_adapter *serv_adapter = data;
721 GSList *l, *next = NULL;
723 for (l = serv_adapter->records; l != NULL; l = next) {
724 struct record_data *user_record = l->data;
728 g_dbus_remove_watch(connection, user_record->listener_id);
729 exit_callback(connection, user_record);
732 g_free(serv_adapter);
735 static int register_interface(const char *path, struct btd_adapter *adapter)
737 struct service_adapter *serv_adapter;
739 DBG("path %s", path);
741 serv_adapter = g_try_new0(struct service_adapter, 1);
742 if (serv_adapter == NULL)
745 serv_adapter->adapter = adapter;
746 serv_adapter->pending_list = NULL;
748 if (g_dbus_register_interface(connection, path, SERVICE_INTERFACE,
749 service_methods, NULL, NULL, serv_adapter,
750 path_unregister) == FALSE) {
751 error("D-Bus failed to register %s interface",
753 g_free(serv_adapter);
757 DBG("Registered interface %s on path %s", SERVICE_INTERFACE, path);
759 if (serv_adapter->adapter == NULL)
760 serv_adapter_any = serv_adapter;
765 static void unregister_interface(const char *path)
767 DBG("path %s", path);
769 g_dbus_unregister_interface(connection, path, SERVICE_INTERFACE);
772 static int service_probe(struct btd_adapter *adapter)
774 register_interface(adapter_get_path(adapter), adapter);
779 static void service_remove(struct btd_adapter *adapter)
781 unregister_interface(adapter_get_path(adapter));
784 static struct btd_adapter_driver service_driver = {
786 .probe = service_probe,
787 .remove = service_remove,
790 static const char *any_path;
792 static int service_init(void)
796 connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
797 if (connection == NULL)
800 any_path = btd_adapter_any_request_path();
801 if (any_path != NULL) {
802 if (register_interface(any_path, NULL) < 0) {
803 btd_adapter_any_release_path();
808 err = btd_register_adapter_driver(&service_driver);
810 dbus_connection_unref(connection);
817 static void service_exit(void)
819 btd_unregister_adapter_driver(&service_driver);
821 if (any_path != NULL) {
822 unregister_interface(any_path);
824 btd_adapter_any_release_path();
828 dbus_connection_unref(connection);
831 BLUETOOTH_PLUGIN_DEFINE(service, VERSION,
832 BLUETOOTH_PLUGIN_PRIORITY_HIGH, service_init, service_exit)