2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 #include <sys/types.h>
23 #include <sys/socket.h>
26 #include <gio/gunixfdlist.h>
29 #include "bluetooth-api.h"
30 #include "bluetooth-audio-api.h"
31 #include "bluetooth-hid-api.h"
32 #include "bluetooth-media-control.h"
33 #include "bt-internal-types.h"
34 #include "bluetooth-ipsp-api.h"
36 #include "bt-common.h"
37 #include "bt-request-sender.h"
38 #include "bt-event-handler.h"
40 static bt_user_info_t user_info[BT_MAX_USER_INFO];
41 static DBusConnection *system_conn = NULL;
42 static GDBusConnection *system_gdbus_conn = NULL;
47 static GDBusConnection *system_gconn = NULL;
49 #define DBUS_TIMEOUT 20 * 1000 /* 20 Seconds */
51 GDBusConnection *g_bus_get_private_conn(void)
55 GDBusConnection *private_gconn = NULL;
57 address = g_dbus_address_get_for_bus_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
58 if (address == NULL) {
60 BT_ERR ("Failed to get bus address: %s", error->message);
61 g_clear_error(&error);
66 private_gconn = g_dbus_connection_new_for_address_sync (address,
67 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
68 G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
69 NULL, /* GDBusAuthObserver */
74 BT_ERR("Unable to connect to dbus: %s", error->message);
75 g_clear_error(&error);
83 GDBusConnection *_bt_gdbus_init_system_gconn(void)
85 dbus_threads_init_default();
89 if (system_gconn != NULL)
92 system_gconn = g_bus_get_private_conn();
97 GDBusConnection *_bt_gdbus_get_system_gconn(void)
99 if (system_gconn == NULL) {
100 system_gconn = _bt_gdbus_init_system_gconn();
101 } else if (g_dbus_connection_is_closed(system_gconn)){
102 system_gconn = g_bus_get_private_conn();
108 void _bt_print_device_address_t(const bluetooth_device_address_t *addr)
110 BT_DBG("%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", addr->addr[0], addr->addr[1], addr->addr[2],
111 addr->addr[3], addr->addr[4], addr->addr[5]);
114 void _bt_set_user_data(int type, void *callback, void *user_data)
116 user_info[type].cb = callback;
117 user_info[type].user_data = user_data;
120 bt_user_info_t *_bt_get_user_data(int type)
122 return &user_info[type];
125 void _bt_common_event_cb(int event, int result, void *param,
126 void *callback, void *user_data)
128 bluetooth_event_param_t bt_event = { 0, };
129 bt_event.event = event;
130 bt_event.result = result;
131 bt_event.param_data = param;
134 ((bluetooth_cb_func_ptr)callback)(bt_event.event, &bt_event,
138 void _bt_input_event_cb(int event, int result, void *param,
139 void *callback, void *user_data)
141 hid_event_param_t bt_event = { 0, };
142 bt_event.event = event;
143 bt_event.result = result;
144 bt_event.param_data = param;
147 ((hid_cb_func_ptr)callback)(bt_event.event, &bt_event,
151 void _bt_headset_event_cb(int event, int result, void *param,
152 void *callback, void *user_data)
154 bt_audio_event_param_t bt_event = { 0, };
155 bt_event.event = event;
156 bt_event.result = result;
157 bt_event.param_data = param;
160 ((bt_audio_func_ptr)callback)(bt_event.event, &bt_event,
164 void _bt_a2dp_source_event_cb(int event, int result, void *param,
165 void *callback, void *user_data)
167 bt_audio_event_param_t bt_event = { 0, };
168 bt_event.event = event;
169 bt_event.result = result;
170 bt_event.param_data = param;
172 ((bt_audio_func_ptr)callback)(bt_event.event, &bt_event,
176 void _bt_hf_event_cb(int event, int result, void *param,
177 void *callback, void *user_data)
179 bt_hf_event_param_t bt_event = { 0, };
180 bt_event.event = event;
181 bt_event.result = result;
182 bt_event.param_data = param;
185 ((bt_hf_func_ptr)callback)(bt_event.event, &bt_event,
190 void _bt_avrcp_event_cb(int event, int result, void *param,
191 void *callback, void *user_data)
193 media_event_param_t bt_event = { 0, };
194 bt_event.event = event;
195 bt_event.result = result;
196 bt_event.param_data = param;
199 ((media_cb_func_ptr)callback)(bt_event.event, &bt_event,
203 void _bt_divide_device_class(bluetooth_device_class_t *device_class,
206 ret_if(device_class == NULL);
208 device_class->major_class = (unsigned short)(cod & 0x00001F00) >> 8;
209 device_class->minor_class = (unsigned short)((cod & 0x000000FC));
210 device_class->service_class = (unsigned long)((cod & 0x00FF0000));
212 if (cod & 0x002000) {
213 device_class->service_class |=
214 BLUETOOTH_DEVICE_SERVICE_CLASS_LIMITED_DISCOVERABLE_MODE;
218 void _bt_convert_addr_string_to_type(unsigned char *addr,
224 ret_if(address == NULL);
225 ret_if(addr == NULL);
227 for (i = 0; i < BT_ADDRESS_LENGTH_MAX; i++) {
228 addr[i] = strtol(address, &ptr, 16);
229 if (ptr[0] != '\0') {
238 void _bt_convert_addr_type_to_string(char *address,
241 ret_if(address == NULL);
242 ret_if(addr == NULL);
244 g_snprintf(address, BT_ADDRESS_STRING_SIZE,
245 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
246 addr[0], addr[1], addr[2],
247 addr[3], addr[4], addr[5]);
250 int _bt_copy_utf8_string(char *dest, const char *src, unsigned int length)
257 if (dest == NULL || src == NULL)
258 return BLUETOOTH_ERROR_INVALID_PARAM;
261 while (*p != '\0' && i < length) {
262 next = g_utf8_next_char(p);
265 while (count > 0 && ((i + count) < length)) {
272 return BLUETOOTH_ERROR_NONE;
275 gboolean _bt_utf8_validate(char *name)
279 glong items_written = 0;
281 if (FALSE == g_utf8_validate(name, -1, NULL))
284 u16 = g_utf8_to_utf16(name, -1, NULL, &items_written, NULL);
290 if (items_written != g_utf8_strlen(name, -1))
298 static GDBusProxy *profile_gproxy;
299 static GDBusConnection *gconn;
300 static int latest_id = -1;
301 #define BT_RFCOMM_ID_MAX 245
302 static gboolean id_used[BT_RFCOMM_ID_MAX];
303 GDBusNodeInfo *new_conn_node;
305 static const gchar rfcomm_agent_xml[] =
307 " <interface name='org.bluez.Profile1'>"
308 " <method name='NewConnection'>"
309 " <arg type='o' name='object' direction='in'/>"
310 " <arg type='h' name='fd' direction='in'/>"
311 " <arg type='a{sv}' name='properties' direction='in'/>"
313 " <method name='RequestDisconnection'>"
314 " <arg type='o' name='device' direction='in'/>"
319 static void __new_connection_method(GDBusConnection *connection,
321 const gchar *object_path,
322 const gchar *interface_name,
323 const gchar *method_name,
324 GVariant *parameters,
325 GDBusMethodInvocation *invocation,
328 BT_DBG("method %s", method_name);
329 if (g_strcmp0(method_name, "NewConnection") == 0) {
332 GUnixFDList *fd_list;
333 GVariantBuilder *properties;
336 bluetooth_device_address_t remote_addr1;
337 bt_new_connection_cb cb = user_data;
340 g_variant_get(parameters, "(oha{sv})", &obj_path, &index,
343 msg = g_dbus_method_invocation_get_message(invocation);
344 fd_list = g_dbus_message_get_unix_fd_list(msg);
345 if (fd_list == NULL) {
346 GQuark quark = g_quark_from_string("rfcomm-app");
347 GError *err = g_error_new(quark, 0, "No fd in message");
348 g_dbus_method_invocation_return_gerror(invocation, err);
354 fd = g_unix_fd_list_get(fd_list, index, NULL);
356 BT_ERR("Invalid fd return");
357 GQuark quark = g_quark_from_string("rfcomm-app");
358 GError *err = g_error_new(quark, 0, "Invalid FD return");
359 g_dbus_method_invocation_return_gerror(invocation, err);
363 BT_INFO("Object Path %s", obj_path);
365 _bt_device_path_to_address(obj_path, addr);
366 _bt_convert_addr_string_to_type(remote_addr1.addr, (const char *)addr);
367 BT_INFO("fd: %d, address %s", fd, addr);
369 g_dbus_method_invocation_return_value(invocation, NULL);
372 cb(object_path, fd, &remote_addr1);
373 } else if (g_strcmp0(method_name, "RequestDisconnection") == 0) {
374 g_dbus_method_invocation_return_value(invocation, NULL);
379 static const GDBusInterfaceVTable method_table = {
380 __new_connection_method,
385 void _bt_swap_addr(unsigned char *dst, const unsigned char *src)
389 for (i = 0; i < 6; i++)
393 int __rfcomm_assign_id(void)
397 BT_DBG("latest_id: %d", latest_id);
399 index = latest_id + 1;
401 if (index >= BT_RFCOMM_ID_MAX)
404 BT_DBG("index: %d", index);
406 while (id_used[index] == TRUE) {
407 if (index == latest_id) {
408 /* No available ID */
409 BT_ERR("All request ID is used");
415 if (index >= BT_RFCOMM_ID_MAX)
420 id_used[index] = TRUE;
422 BT_DBG("Assigned Id: %d", latest_id);
427 void __rfcomm_delete_id(int id)
429 ret_if(id >= BT_RFCOMM_ID_MAX);
434 /* Next server will use this ID */
438 static GDBusConnection *__get_gdbus_connection()
441 gconn = g_bus_get_private_conn();
446 static GDBusProxy *__bt_gdbus_get_profile_proxy(void)
448 GDBusConnection *gconn;
452 return profile_gproxy;
454 gconn = __get_gdbus_connection();
458 profile_gproxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE,
461 "org.bluez.ProfileManager1",
464 BT_ERR("Unable to create proxy: %s", err->message);
469 return profile_gproxy;
472 static GDBusProxy *__bt_gdbus_get_device_proxy(char *object_path)
474 GDBusConnection *gconn;
476 GDBusProxy *device_gproxy;
478 gconn = __get_gdbus_connection();
482 device_gproxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE,
489 BT_ERR("Unable to create proxy: %s", err->message);
494 return device_gproxy;
497 void _bt_unregister_gdbus(int object_id)
499 GDBusConnection *gconn;
501 gconn = __get_gdbus_connection();
505 g_dbus_connection_unregister_object(gconn, object_id);
508 int _bt_register_new_conn(const char *path, bt_new_connection_cb cb)
510 GDBusConnection *gconn;
512 GError *error = NULL;
514 gconn = __get_gdbus_connection();
518 if (new_conn_node == NULL)
519 new_conn_node = _bt_get_gdbus_node(rfcomm_agent_xml);
521 if (new_conn_node == NULL)
524 id = g_dbus_connection_register_object(gconn, path,
525 new_conn_node->interfaces[0],
529 BT_ERR("Failed to register: %s", error->message);
534 BT_DBG("NEW CONNECTION ID %d", id);
539 static GDBusProxy * __bt_gdbus_get_adapter_proxy()
542 GDBusProxy *manager_proxy = NULL;
543 GDBusProxy *adapter_proxy = NULL;
544 GDBusConnection *conn;
545 GVariant *result = NULL;
546 char *adapter_path = NULL;
548 conn = __get_gdbus_connection();
549 retv_if(conn == NULL, NULL);
551 manager_proxy = g_dbus_proxy_new_sync(conn,
552 G_DBUS_PROXY_FLAGS_NONE, NULL,
555 BT_MANAGER_INTERFACE,
558 if (!manager_proxy) {
559 BT_ERR("Unable to create proxy: %s", err->message);
563 result = g_dbus_proxy_call_sync(manager_proxy, "DefaultAdapter", NULL,
564 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
567 BT_ERR("Fail to get DefaultAdapter (Error: %s)", err->message);
569 BT_ERR("Fail to get DefaultAdapter");
574 if (g_strcmp0(g_variant_get_type_string(result), "(o)")) {
575 BT_ERR("Incorrect result\n");
579 g_variant_get(result, "(&o)", &adapter_path);
581 if (adapter_path == NULL ||
582 strlen(adapter_path) >= BT_ADAPTER_OBJECT_PATH_MAX) {
583 BT_ERR("Adapter path is inproper\n");
587 BT_INFO("Adapter Path %s", adapter_path);
589 adapter_proxy = g_dbus_proxy_new_sync(conn,
590 G_DBUS_PROXY_FLAGS_NONE, NULL,
593 BT_ADAPTER_INTERFACE,
596 BT_ERR("DBus Error message: [%s]", err->message);
602 g_object_unref(manager_proxy);
604 g_variant_unref(result);
605 return adapter_proxy;
608 int _bt_register_new_conn_ex(const char *path, const char *bus_name,bt_new_connection_cb cb)
610 GDBusConnection *gconn;
612 GError *error = NULL;
614 gconn = __get_gdbus_connection();
618 if (new_conn_node == NULL)
619 new_conn_node = _bt_get_gdbus_node_ex(rfcomm_agent_xml, bus_name);
621 if (new_conn_node == NULL)
624 id = g_dbus_connection_register_object(gconn, path,
625 new_conn_node->interfaces[0],
629 BT_ERR("Failed to register: %s", error->message);
634 BT_DBG("NEW CONNECTION ID %d", id);
639 int _bt_register_profile(bt_register_profile_info_t *info, gboolean use_default_rfcomm)
641 GVariantBuilder *option_builder;
645 int result = BLUETOOTH_ERROR_NONE;
647 proxy = __bt_gdbus_get_profile_proxy();
649 BT_ERR("Getting profile proxy failed");
650 return BLUETOOTH_ERROR_INTERNAL;
653 option_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
654 if (info->authentication)
655 g_variant_builder_add(option_builder, "{sv}",
656 "RequireAuthentication",
657 g_variant_new_boolean(TRUE));
658 if (info->authorization)
659 g_variant_builder_add(option_builder, "{sv}",
660 "RequireAuthorization",
661 g_variant_new_boolean(TRUE));
663 g_variant_builder_add(option_builder, "{sv}",
665 g_variant_new_string(info->role));
667 /* Setting RFCOMM channel to default value 0; would allow bluez to assign
668 * RFCOMM channels based on the availability when two services want
669 * to use the RFCOMM along with SPP. Hence bluez makes sure that no
670 * two services use the same SPP RFCOMM channel. */
671 if (use_default_rfcomm)
672 g_variant_builder_add(option_builder, "{sv}",
674 g_variant_new_uint16(RFCOMM_DEFAULT_PROFILE_CHANNEL));
676 g_variant_builder_add(option_builder, "{sv}",
678 g_variant_new_string(info->service));
680 ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile",
681 g_variant_new("(osa{sv})", info->obj_path,
684 G_DBUS_CALL_FLAGS_NONE, -1,
687 g_dbus_error_strip_remote_error(err);
688 BT_ERR("RegisterProfile failed: %s", err->message);
690 if (g_strrstr(err->message, BT_ACCESS_DENIED_MSG))
691 result = BLUETOOTH_ERROR_ACCESS_DENIED;
693 result = BLUETOOTH_ERROR_INTERNAL;
698 g_variant_builder_unref(option_builder);
701 g_variant_unref(ret);
706 int _bt_register_profile_ex(bt_register_profile_info_t *info, gboolean use_default_rfcomm, const char *name, const char *path)
708 GVariantBuilder *option_builder;
712 int result = BLUETOOTH_ERROR_NONE;
714 proxy = __bt_gdbus_get_profile_proxy();
716 BT_ERR("Getting profile proxy failed");
717 return BLUETOOTH_ERROR_INTERNAL;
720 option_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
721 if (info->authentication)
722 g_variant_builder_add(option_builder, "{sv}",
723 "RequireAuthentication",
724 g_variant_new_boolean(TRUE));
725 if (info->authorization)
726 g_variant_builder_add(option_builder, "{sv}",
727 "RequireAuthorization",
728 g_variant_new_boolean(TRUE));
730 g_variant_builder_add(option_builder, "{sv}",
732 g_variant_new_string(info->role));
734 /* Setting RFCOMM channel to default value 0; would allow bluez to assign
735 * RFCOMM channels based on the availability when two services want
736 * to use the RFCOMM along with SPP. Hence bluez makes sure that no
737 * two services use the same SPP RFCOMM channel. */
738 if (use_default_rfcomm)
739 g_variant_builder_add(option_builder, "{sv}",
741 g_variant_new_uint16(RFCOMM_DEFAULT_PROFILE_CHANNEL));
743 g_variant_builder_add(option_builder, "{sv}",
745 g_variant_new_string(info->service));
747 ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile2",
748 g_variant_new("(osssa{sv})", info->obj_path,
753 G_DBUS_CALL_FLAGS_NONE, -1,
756 g_dbus_error_strip_remote_error(err);
757 BT_ERR("RegisterProfile failed: %s", err->message);
759 if (g_strrstr(err->message, BT_ACCESS_DENIED_MSG))
760 result = BLUETOOTH_ERROR_ACCESS_DENIED;
762 result = BLUETOOTH_ERROR_INTERNAL;
767 g_variant_builder_unref(option_builder);
770 g_variant_unref(ret);
775 int _bt_register_profile_platform(bt_register_profile_info_t *info, gboolean use_default_rfcomm)
777 GVariantBuilder *option_builder;
781 int result = BLUETOOTH_ERROR_NONE;
783 proxy = __bt_gdbus_get_profile_proxy();
785 BT_ERR("Getting profile proxy failed");
786 return BLUETOOTH_ERROR_INTERNAL;
789 option_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
790 if (info->authentication)
791 g_variant_builder_add(option_builder, "{sv}",
792 "RequireAuthentication",
793 g_variant_new_boolean(TRUE));
794 if (info->authorization)
795 g_variant_builder_add(option_builder, "{sv}",
796 "RequireAuthorization",
797 g_variant_new_boolean(TRUE));
799 g_variant_builder_add(option_builder, "{sv}",
801 g_variant_new_string(info->role));
803 /* Setting RFCOMM channel to default value 0; would allow bluez to assign
804 * RFCOMM channels based on the availability when two services want
805 * to use the RFCOMM along with SPP. Hence bluez makes sure that no
806 * two services use the same SPP RFCOMM channel. */
807 if (use_default_rfcomm)
808 g_variant_builder_add(option_builder, "{sv}",
810 g_variant_new_uint16(RFCOMM_DEFAULT_PROFILE_CHANNEL));
812 g_variant_builder_add(option_builder, "{sv}",
814 g_variant_new_string(info->service));
816 ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile1",
817 g_variant_new("(osa{sv})", info->obj_path,
820 G_DBUS_CALL_FLAGS_NONE, -1,
824 g_dbus_error_strip_remote_error(err);
825 BT_ERR("RegisterProfile failed: %s", err->message);
827 if (g_strrstr(err->message, BT_ACCESS_DENIED_MSG))
828 result = BLUETOOTH_ERROR_ACCESS_DENIED;
830 result = BLUETOOTH_ERROR_INTERNAL;
835 g_variant_builder_unref(option_builder);
838 g_variant_unref(ret);
844 void _bt_unregister_profile(char *path)
850 proxy = __bt_gdbus_get_profile_proxy();
852 BT_ERR("Getting profile proxy failed");
856 ret = g_dbus_proxy_call_sync(proxy, "UnregisterProfile",
857 g_variant_new("(o)", path),
858 G_DBUS_CALL_FLAGS_NONE, -1,
861 BT_ERR("UnregisterProfile failed : %s", err->message);
866 g_variant_unref(ret);
871 GDBusNodeInfo * _bt_get_gdbus_node(const gchar *xml_data)
874 char *name = g_strdup_printf("org.bt.frwk%d", getpid());
876 bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
878 G_BUS_NAME_OWNER_FLAGS_NONE,
884 BT_DBG("Got bus id %d", bus_id);
888 return g_dbus_node_info_new_for_xml(xml_data, NULL);
891 GDBusNodeInfo * _bt_get_gdbus_node_ex(const gchar *xml_data, const char *bus_name)
894 char *name = g_strdup(bus_name);
895 bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
897 G_BUS_NAME_OWNER_FLAGS_NONE,
903 BT_DBG("Got bus id %d", bus_id);
907 return g_dbus_node_info_new_for_xml(xml_data, NULL);
910 int _bt_connect_profile(char *address, char *uuid, void *cb,
914 GDBusProxy *adapter_proxy;
918 object_path = _bt_get_device_object_path(address);
920 if (object_path == NULL) {
921 GVariant *ret = NULL;
922 BT_ERR("No searched device");
923 adapter_proxy = __bt_gdbus_get_adapter_proxy();
925 if (adapter_proxy == NULL) {
926 BT_ERR("adapter proxy is NULL");
927 return BLUETOOTH_ERROR_INTERNAL;
930 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
931 g_variant_new("(s)", address),
932 G_DBUS_CALL_FLAGS_NONE,
937 BT_ERR("CreateDevice Failed: %s", err->message);
941 g_variant_unref(ret);
942 g_object_unref(adapter_proxy);
943 object_path = _bt_get_device_object_path(address);
945 if (object_path == NULL)
946 return BLUETOOTH_ERROR_INTERNAL;
949 proxy = __bt_gdbus_get_device_proxy(object_path);
953 BT_ERR("Error while getting proxy");
954 return BLUETOOTH_ERROR_INTERNAL;
957 g_dbus_proxy_call(proxy, "ConnectProfile",
958 g_variant_new("(s)", uuid),
959 G_DBUS_CALL_FLAGS_NONE,
961 (GAsyncReadyCallback)cb,
964 return BLUETOOTH_ERROR_NONE;
967 int _bt_discover_services(char *address, char *uuid, void *cb,
972 GDBusProxy *adapter_proxy;
974 object_path = _bt_get_device_object_path(address);
975 if (object_path == NULL) {
976 GVariant *ret = NULL;
977 BT_ERR("No searched device");
978 adapter_proxy = __bt_gdbus_get_adapter_proxy();
979 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
980 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
981 g_variant_new("(s)", address),
982 G_DBUS_CALL_FLAGS_NONE,
986 BT_ERR("CreateDevice Failed: %s", err->message);
990 g_variant_unref(ret);
992 g_object_unref(adapter_proxy);
994 object_path = _bt_get_device_object_path(address);
995 if (object_path == NULL)
996 return BLUETOOTH_ERROR_INTERNAL;
998 proxy = __bt_gdbus_get_device_proxy(object_path);
1000 if (proxy == NULL) {
1001 BT_ERR("Error while getting proxy");
1002 return BLUETOOTH_ERROR_INTERNAL;
1004 g_dbus_proxy_call(proxy, "DiscoverServices",
1005 g_variant_new("(s)", uuid),
1006 G_DBUS_CALL_FLAGS_NONE,
1008 (GAsyncReadyCallback)cb,
1011 return BLUETOOTH_ERROR_NONE;
1014 int _bt_cancel_discovers(char *address)
1018 GDBusProxy *adapter_proxy;
1020 object_path = _bt_get_device_object_path(address);
1021 if (object_path == NULL) {
1022 GVariant *ret = NULL;
1023 BT_ERR("No searched device");
1024 adapter_proxy = __bt_gdbus_get_adapter_proxy();
1025 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1026 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1027 g_variant_new("(s)", address),
1028 G_DBUS_CALL_FLAGS_NONE,
1032 BT_ERR("CreateDevice Failed: %s", err->message);
1033 g_clear_error(&err);
1036 g_variant_unref(ret);
1038 g_object_unref(adapter_proxy);
1040 object_path = _bt_get_device_object_path(address);
1041 if (object_path == NULL)
1042 return BLUETOOTH_ERROR_INTERNAL;
1044 proxy = __bt_gdbus_get_device_proxy(object_path);
1045 g_free(object_path);
1046 g_dbus_proxy_call_sync(proxy, "CancelDiscovery",
1048 G_DBUS_CALL_FLAGS_NONE,
1052 BT_ERR("DBus Error message: [%s]", err->message);
1053 g_clear_error(&err);
1054 return BLUETOOTH_ERROR_INTERNAL;
1057 g_object_unref(proxy);
1058 return BLUETOOTH_ERROR_NONE;
1061 int _bt_discover_service_uuids(char *address, char *remote_uuid)
1065 GDBusConnection *gconn;
1067 char **uuid_value = NULL;
1070 GVariant *value = NULL;
1071 GVariant *ret = NULL;
1072 int result = BLUETOOTH_ERROR_INTERNAL;
1074 retv_if(remote_uuid == NULL, BLUETOOTH_ERROR_INTERNAL);
1075 gconn = __get_gdbus_connection();
1076 retv_if(gconn == NULL, BLUETOOTH_ERROR_INTERNAL);
1077 object_path = _bt_get_device_object_path(address);
1078 retv_if(object_path == NULL, BLUETOOTH_ERROR_INTERNAL);
1080 proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE, NULL,
1081 BT_BLUEZ_NAME, object_path, BT_PROPERTIES_INTERFACE, NULL,
1083 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1085 BT_ERR("DBus Error: [%s]", err->message);
1086 g_clear_error(&err);
1088 ret = g_dbus_proxy_call_sync(proxy, "GetAll",
1089 g_variant_new("(s)", BT_DEVICE_INTERFACE),
1090 G_DBUS_CALL_FLAGS_NONE,
1094 result = BLUETOOTH_ERROR_INTERNAL;
1095 BT_ERR("DBus Error : %s", err->message);
1096 g_clear_error(&err);
1100 BT_ERR("g_dbus_proxy_call_sync function return NULL");
1101 result = BLUETOOTH_ERROR_INTERNAL;
1105 g_variant_get(ret, "(@a{sv})", &value);
1106 g_variant_unref(ret);
1108 GVariant *temp_value = g_variant_lookup_value(value, "UUIDs",
1109 G_VARIANT_TYPE_STRING_ARRAY);
1112 size = g_variant_get_size(temp_value);
1114 uuid_value = (char **)g_variant_get_strv(temp_value, &size);
1115 BT_DBG("Size items %d", size);
1118 for (i = 0; uuid_value[i] != NULL; i++) {
1119 BT_DBG("Remote uuids %s", uuid_value[i]);
1120 if (strcasecmp(uuid_value[i], remote_uuid) == 0) {
1121 result = BLUETOOTH_ERROR_NONE;
1122 g_variant_unref(temp_value);
1128 g_variant_unref(temp_value);
1133 g_object_unref(proxy);
1135 g_variant_unref(value);
1143 int _bt_get_cod_by_address(char *address, bluetooth_device_class_t *dev_class)
1147 GDBusConnection *gconn;
1149 GVariant *value = NULL;
1150 GVariant *result = NULL;
1151 unsigned int class = 0x00;
1152 int ret = BLUETOOTH_ERROR_INTERNAL;
1154 gconn = __get_gdbus_connection();
1155 retv_if(gconn == NULL, BLUETOOTH_ERROR_INTERNAL);
1156 object_path = _bt_get_device_object_path(address);
1158 retv_if(object_path == NULL, BLUETOOTH_ERROR_INTERNAL);
1160 proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE, NULL,
1161 BT_BLUEZ_NAME, object_path, BT_PROPERTIES_INTERFACE, NULL,
1163 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1165 BT_ERR("DBus Error: [%s]", err->message);
1166 g_clear_error(&err);
1169 result = g_dbus_proxy_call_sync(proxy, "GetAll",
1170 g_variant_new("(s)", BT_DEVICE_INTERFACE),
1171 G_DBUS_CALL_FLAGS_NONE,
1175 ret = BLUETOOTH_ERROR_INTERNAL;
1176 BT_ERR("DBus Error : %s", err->message);
1177 g_clear_error(&err);
1180 if (result == NULL) {
1181 BT_ERR("g_dbus_proxy_call_sync function return NULL");
1182 ret = BLUETOOTH_ERROR_INTERNAL;
1185 g_variant_get(result, "(@a{sv})", &value);
1186 g_variant_unref(result);
1188 GVariant *temp_value = g_variant_lookup_value(value, "Class",
1189 G_VARIANT_TYPE_UINT32);
1190 class = g_variant_get_uint32(temp_value);
1191 _bt_divide_device_class(dev_class, class);
1193 g_variant_unref(temp_value);
1198 g_object_unref(proxy);
1200 g_variant_unref(value);
1206 int _bt_disconnect_profile(char *address, char *uuid, void *cb,
1212 GDBusProxy *adapter_proxy;
1213 object_path = _bt_get_device_object_path(address);
1214 if (object_path == NULL) {
1215 GVariant *ret = NULL;
1216 BT_ERR("No searched device");
1217 adapter_proxy = __bt_gdbus_get_adapter_proxy();
1218 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1219 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1220 g_variant_new("(s)", address),
1221 G_DBUS_CALL_FLAGS_NONE,
1225 BT_ERR("CreateDevice Failed: %s", err->message);
1229 g_variant_unref(ret);
1230 g_object_unref(adapter_proxy);
1231 object_path = _bt_get_device_object_path(address);
1232 if (object_path == NULL)
1233 return BLUETOOTH_ERROR_INTERNAL;
1235 proxy = __bt_gdbus_get_device_proxy(object_path);
1236 g_free(object_path);
1237 if (proxy == NULL) {
1238 BT_ERR("Error while getting proxy");
1239 return BLUETOOTH_ERROR_INTERNAL;
1241 g_dbus_proxy_call(proxy, "DisconnectProfile",
1242 g_variant_new("(s)", uuid),
1243 G_DBUS_CALL_FLAGS_NONE,
1245 (GAsyncReadyCallback)cb,
1248 return BLUETOOTH_ERROR_NONE;
1251 int _bt_get_adapter_path(GDBusConnection *conn, char *path)
1254 GDBusProxy *manager_proxy = NULL;
1255 GVariant *result = NULL;
1256 char *adapter_path = NULL;
1258 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1260 manager_proxy = g_dbus_proxy_new_sync(conn,
1261 G_DBUS_PROXY_FLAGS_NONE, NULL,
1264 BT_MANAGER_INTERFACE,
1267 if (!manager_proxy) {
1268 BT_ERR("Unable to create proxy: %s", err->message);
1272 result = g_dbus_proxy_call_sync(manager_proxy, "DefaultAdapter", NULL,
1273 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1276 BT_ERR("Fail to get DefaultAdapter (Error: %s)", err->message);
1278 BT_ERR("Fail to get DefaultAdapter");
1283 if (g_strcmp0(g_variant_get_type_string(result), "(o)")) {
1284 BT_ERR("Incorrect result\n");
1288 g_variant_get(result, "(&o)", &adapter_path);
1290 if (adapter_path == NULL ||
1291 strlen(adapter_path) >= BT_ADAPTER_OBJECT_PATH_MAX) {
1292 BT_ERR("Adapter path is inproper\n");
1297 g_strlcpy(path, adapter_path, BT_ADAPTER_OBJECT_PATH_MAX);
1299 g_variant_unref(result);
1300 g_object_unref(manager_proxy);
1302 return BLUETOOTH_ERROR_NONE;
1305 g_clear_error(&err);
1308 g_variant_unref(result);
1311 g_object_unref(manager_proxy);
1313 return BLUETOOTH_ERROR_INTERNAL;
1317 void _bt_convert_device_path_to_address(const char *device_path,
1318 char *device_address)
1320 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1323 ret_if(device_path == NULL);
1324 ret_if(device_address == NULL);
1326 dev_addr = strstr(device_path, "dev_");
1327 if (dev_addr != NULL) {
1330 g_strlcpy(address, dev_addr, sizeof(address));
1332 while ((pos = strchr(address, '_')) != NULL) {
1336 g_strlcpy(device_address, address, BT_ADDRESS_STRING_SIZE);
1340 static char *__bt_extract_device_path(GVariantIter *iter, char *address)
1342 char *object_path = NULL;
1343 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
1344 /* Parse the signature: oa{sa{sv}}} */
1345 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
1347 retv_if(object_path == NULL, NULL);
1348 _bt_convert_device_path_to_address(object_path, device_address);
1350 if (g_strcmp0(address, device_address) == 0) {
1351 return g_strdup(object_path);
1357 char *_bt_get_device_object_path(char *address)
1360 GDBusProxy *proxy = NULL;
1361 GVariant *result = NULL;
1362 GVariantIter *iter = NULL;
1363 GDBusConnection *conn = NULL;
1364 char *object_path = NULL;
1366 conn = _bt_gdbus_get_system_gconn();
1367 retv_if(conn == NULL, NULL);
1369 proxy = g_dbus_proxy_new_sync(conn,
1370 G_DBUS_PROXY_FLAGS_NONE, NULL,
1373 BT_MANAGER_INTERFACE,
1377 BT_ERR("Unable to create proxy: %s", err->message);
1381 result = g_dbus_proxy_call_sync(proxy, "GetManagedObjects", NULL,
1382 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1385 BT_ERR("Fail to get GetManagedObjects (Error: %s)", err->message);
1387 BT_ERR("Fail to get GetManagedObjects");
1392 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
1393 object_path = __bt_extract_device_path(iter, address);
1395 g_variant_unref(result);
1396 g_object_unref(proxy);
1397 g_variant_iter_free(iter);
1401 g_clear_error(&err);
1404 g_object_unref(proxy);
1409 void _bt_device_path_to_address(const char *device_path, char *device_address)
1411 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1412 char *dev_addr = NULL;
1414 if (!device_path || !device_address)
1417 dev_addr = strstr(device_path, "dev_");
1418 if (dev_addr != NULL) {
1421 g_strlcpy(address, dev_addr, sizeof(address));
1423 while ((pos = strchr(address, '_')) != NULL) {
1427 g_strlcpy(device_address, address, BT_ADDRESS_STRING_SIZE);
1431 /* TODO : replace the dbus-glib APIs to gdbus APIs */
1432 DBusConnection *__bt_init_system_conn(void)
1434 if (system_conn == NULL)
1435 system_conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, NULL);
1438 dbus_connection_setup_with_g_main(system_conn, NULL);
1439 dbus_connection_set_exit_on_disconnect(system_conn, FALSE);
1445 DBusConnection *_bt_get_system_conn(void)
1447 DBusConnection *conn = NULL;
1449 if (system_conn == NULL) {
1450 conn = __bt_init_system_conn();
1459 int _bt_register_osp_server_in_agent(int type, char *uuid, char *path, int fd)
1462 char uuid_str[BLUETOOTH_UUID_STRING_MAX] = { 0, };
1463 char path_str[BLUETOOTH_PATH_STRING] = { 0, };
1467 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1469 g_array_append_vals(in_param1, &type, sizeof(int));
1470 g_strlcpy(uuid_str, uuid, sizeof(uuid_str));
1471 g_array_append_vals(in_param2, &uuid_str, BLUETOOTH_UUID_STRING_MAX);
1472 g_strlcpy(path_str, path, sizeof(path_str));
1473 g_array_append_vals(in_param3, &path_str, BLUETOOTH_PATH_STRING);
1474 g_array_append_vals(in_param4, &fd, sizeof(int));
1476 ret = _bt_send_request(BT_AGENT_SERVICE, BT_SET_AUTHORIZATION,
1477 in_param1, in_param2, in_param3, in_param4, &out_param);
1479 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1484 int _bt_unregister_osp_server_in_agent(int type, char *uuid)
1487 char uuid_str[BLUETOOTH_UUID_STRING_MAX] = { 0, };
1491 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1493 g_array_append_vals(in_param1, &type, sizeof(int));
1494 g_strlcpy(uuid_str, uuid, sizeof(uuid_str));
1495 g_array_append_vals(in_param2, &uuid_str, BLUETOOTH_UUID_STRING_MAX);
1497 ret = _bt_send_request(BT_AGENT_SERVICE, BT_UNSET_AUTHORIZATION,
1498 in_param1, in_param2, in_param3, in_param4, &out_param);
1500 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1505 int _bt_check_privilege(int service_type, int service_function)
1510 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1512 result = _bt_send_request(service_type, service_function,
1513 in_param1, in_param2, in_param3, in_param4, &out_param);
1515 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1520 GVariant *_bt_get_managed_objects(void)
1522 GDBusConnection *g_conn;
1523 GDBusProxy *manager_proxy = NULL;
1524 GVariant *result = NULL;
1525 GError *error = NULL;
1529 g_conn = _bt_gdbus_get_system_gconn();
1530 retv_if(g_conn == NULL, NULL);
1532 manager_proxy = g_dbus_proxy_new_sync(g_conn,
1533 G_DBUS_PROXY_FLAGS_NONE, NULL,
1536 BT_MANAGER_INTERFACE,
1540 BT_ERR("Unable to create proxy: %s", error->message);
1541 g_clear_error(&error);
1545 result = g_dbus_proxy_call_sync (manager_proxy,
1546 "GetManagedObjects", NULL,
1547 G_DBUS_CALL_FLAGS_NONE, -1,
1551 BT_ERR("Fail to get ManagedObjects (Error: %s)", error->message);
1552 g_clear_error(&error);
1555 g_object_unref(manager_proxy);
1561 BT_EXPORT_API int bluetooth_is_supported(void)
1563 int is_supported = 0;
1568 fd = open(RFKILL_NODE, O_RDONLY);
1570 BT_ERR("Fail to open RFKILL node");
1571 return BLUETOOTH_ERROR_INTERNAL;
1574 if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
1575 BT_ERR("Fail to set RFKILL node to non-blocking");
1577 return BLUETOOTH_ERROR_INTERNAL;
1581 len = read(fd, &event, sizeof(event));
1583 BT_ERR("Fail to read events");
1587 if (len != RFKILL_EVENT_SIZE) {
1588 BT_ERR("The size is wrong\n");
1592 if (event.type == RFKILL_TYPE_BLUETOOTH) {
1600 BT_DBG("supported: %d", is_supported);
1602 return is_supported;
1605 BT_EXPORT_API int bluetooth_register_callback(bluetooth_cb_func_ptr callback_ptr, void *user_data)
1609 _bt_gdbus_init_system_gconn();
1610 __bt_init_system_conn();
1612 ret = _bt_init_event_handler();
1613 if (ret != BLUETOOTH_ERROR_NONE &&
1614 ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
1615 BT_ERR("Fail to init the event handler");
1620 _bt_set_user_data(BT_COMMON, (void *)callback_ptr, user_data);
1622 /* Register All events */
1623 ret = _bt_register_event(BT_ADAPTER_EVENT, (void *)callback_ptr, user_data);
1624 if (ret != BLUETOOTH_ERROR_NONE)
1626 ret = _bt_register_event(BT_DEVICE_EVENT, (void *)callback_ptr, user_data);
1627 if (ret != BLUETOOTH_ERROR_NONE)
1629 ret = _bt_register_event(BT_NETWORK_EVENT, (void *)callback_ptr, user_data);
1630 if (ret != BLUETOOTH_ERROR_NONE)
1632 ret = _bt_register_event(BT_RFCOMM_CLIENT_EVENT, (void *)callback_ptr, user_data);
1633 if (ret != BLUETOOTH_ERROR_NONE)
1635 ret = _bt_register_event(BT_RFCOMM_SERVER_EVENT, (void *)callback_ptr, user_data);
1636 if (ret != BLUETOOTH_ERROR_NONE)
1638 #ifdef GATT_NO_RELAY
1639 ret = _bt_register_event(BT_GATT_BLUEZ_EVENT, (void *)callback_ptr, user_data);
1640 if (ret != BLUETOOTH_ERROR_NONE)
1644 _bt_register_name_owner_changed();
1646 return BLUETOOTH_ERROR_NONE;
1648 BT_ERR("Fail to do _bt_register_event()");
1649 bluetooth_unregister_callback();
1653 BT_EXPORT_API int bluetooth_unregister_callback(void)
1658 ret = _bt_deinit_event_handler();
1659 if (ret != BLUETOOTH_ERROR_NONE) {
1660 BT_ERR("Fail to deinit the event handler");
1663 _bt_unregister_name_owner_changed();
1665 _bt_set_user_data(BT_COMMON, NULL, NULL);
1668 dbus_connection_flush(system_conn);
1669 dbus_connection_close(system_conn);
1670 dbus_connection_unref(system_conn);
1674 g_object_unref(system_gconn);
1675 system_gconn = NULL;
1677 _bt_gdbus_deinit_proxys();
1678 return BLUETOOTH_ERROR_NONE;