4 * Copyright (c) 2015 -2016 Samsung Electronics Co., Ltd All Rights Reserved.
6 * Contact: Anupam Roy <anupam.r@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
31 #include <arpa/inet.h>
35 #include <sys/prctl.h>
37 #include <gio/gunixfdlist.h>
39 #include "bt-hal-dbus-common-utils.h"
42 #include "bt-hal-log.h"
43 #include "bt-hal-msg.h"
44 #include "bt-hal-utils.h"
45 #include "bt-hal-internal.h"
47 #define CASE_RETURN_STR(const) case const: return #const;
50 * This is RFCOMM default Channel Value
52 #define RFCOMM_DEFAULT_PROFILE_CHANNEL 0
53 #define BT_AUDIO_SOURCE_MAX 2
55 static char *avrcp_control_path = NULL;
56 static char *avrcp_transport_path = NULL;
58 static GDBusConnection *system_conn;
59 static GDBusConnection *session_conn;
60 static GDBusProxy *manager_gproxy = NULL;
61 static GDBusProxy *adapter_gproxy = NULL;
62 static GDBusProxy *profile_gproxy = NULL;
64 static GDBusProxy *adapter_properties_proxy;
65 static GDBusProxy *avrcp_ctrl_proxy;
68 GDBusProxy *avrcp_ctrl_proxy;
69 char *avrcp_control_path;
73 struct avrcp_proxy proxy_array[BT_AUDIO_SOURCE_MAX];
76 GDBusNodeInfo *new_conn_node;
77 static const gchar rfcomm_agent_xml[] =
79 " <interface name='org.bluez.Profile1'>"
80 " <method name='NewConnection'>"
81 " <arg type='o' name='object' direction='in'/>"
82 " <arg type='h' name='fd' direction='in'/>"
83 " <arg type='a{sv}' name='properties' direction='in'/>"
85 " <method name='RequestDisconnection'>"
86 " <arg type='o' name='device' direction='in'/>"
91 static GDBusConnection *__bt_hal_init_session_conn(void)
93 if (session_conn == NULL)
94 session_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
99 GDBusConnection *_bt_hal_get_session_gconn(void)
101 return (session_conn) ? session_conn : __bt_hal_init_session_conn();
104 static GDBusConnection *__bt_hal_init_system_gconn(void)
106 GError *error = NULL;
108 if (system_conn != NULL)
111 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
114 ERR("Unable to connect to dbus: %s", error->message);
115 g_clear_error(&error);
121 GDBusConnection *_bt_hal_get_system_gconn(void)
123 GDBusConnection *local_system_gconn = NULL;
124 GError *error = NULL;
126 if (system_conn == NULL) {
127 system_conn = __bt_hal_init_system_gconn();
128 } else if (g_dbus_connection_is_closed(system_conn)) {
130 local_system_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
132 if (!local_system_gconn) {
133 ERR("Unable to connect to dbus: %s", error->message);
134 g_clear_error(&error);
137 system_conn = local_system_gconn;
143 static GDBusProxy *__bt_hal_init_manager_proxy(void)
149 if (system_conn == NULL) {
150 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
151 if (system_conn == NULL)
155 proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
156 NULL, BT_HAL_BLUEZ_NAME,
157 BT_HAL_MANAGER_PATH, BT_HAL_MANAGER_INTERFACE, NULL, NULL);
162 manager_gproxy = proxy;
168 static GDBusProxy *__bt_hal_init_adapter_proxy(void)
170 GDBusProxy *manager_proxy;
172 char *adapter_path = NULL;
174 if (system_conn == NULL) {
175 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
176 if (system_conn == NULL)
180 manager_proxy = _bt_hal_get_manager_proxy();
181 if (manager_proxy == NULL)
184 adapter_path = _bt_hal_get_adapter_path();
185 if (adapter_path == NULL)
188 proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
189 NULL, BT_HAL_BLUEZ_NAME,
190 adapter_path, BT_HAL_ADAPTER_INTERFACE, NULL, NULL);
192 g_free(adapter_path);
197 adapter_gproxy = proxy;
202 static GDBusProxy *__bt_hal_init_adapter_properties_proxy(void)
204 GDBusProxy *manager_proxy;
206 char *adapter_path = NULL;
208 if (system_conn == NULL) {
209 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
210 if (system_conn == NULL)
214 manager_proxy = _bt_hal_get_manager_proxy();
215 if (manager_proxy == NULL)
218 adapter_path = _bt_hal_get_adapter_path();
219 if (adapter_path == NULL)
222 proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
223 NULL, BT_HAL_BLUEZ_NAME,
224 adapter_path, BT_HAL_PROPERTIES_INTERFACE, NULL, NULL);
226 g_free(adapter_path);
231 adapter_properties_proxy = proxy;
236 void _bt_hal_set_control_device_path(const char *path)
243 DBG("control_path = %s", path);
245 for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
246 if (proxy_array[i].avrcp_control_path == NULL) {
247 proxy_array[i].avrcp_control_path = g_strdup(path);
248 DBG("PATH %s formed index %d", proxy_array[i].avrcp_control_path, i);
254 void _bt_hal_remove_control_device_path(const char *path)
261 for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
262 if (g_strcmp0(proxy_array[i].avrcp_control_path, path) == 0) {
263 DBG("Clear AVRCP proxy[%d]", i);
264 g_free(proxy_array[i].avrcp_control_path);
265 g_object_unref(proxy_array[i].avrcp_ctrl_proxy);
267 proxy_array[i].avrcp_control_path = NULL;
268 proxy_array[i].avrcp_ctrl_proxy = NULL;
269 memset(proxy_array[i].bd_addr.address, 0, 6);
275 static char *__bt_hal_extract_control_device_path(GVariantIter *iter, char *address)
277 char *object_path = NULL;
278 char *interface_str = NULL;
279 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
281 /* Parse the signature: oa{sa{sv}}} */
282 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_str)) {
283 if (object_path == NULL)
286 if (g_strcmp0(interface_str, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
287 _bt_hal_convert_device_path_to_address(object_path, device_address);
288 if (g_strcmp0(address, device_address) == 0)
289 return g_strdup(object_path);
295 static char *__bt_hal_extract_transport_device_path(GVariantIter *iter, char *address)
297 char *object_path = NULL;
298 char *interface_str = NULL;
299 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
301 /* Parse the signature: oa{sa{sv}}} */
302 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_str)) {
303 if (object_path == NULL)
306 if (g_strcmp0(interface_str, BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
307 _bt_hal_convert_device_path_to_address(object_path, device_address);
308 if (g_strcmp0(address, device_address) == 0)
309 return g_strdup(object_path);
315 static char *__bt_hal_get_control_device_object_path(char *address)
317 char *object_path = NULL;
318 GDBusConnection *conn;
319 GDBusProxy *manager_proxy;
320 GVariant *result = NULL;
321 GVariantIter *iter = NULL;
323 conn = _bt_hal_get_system_gconn();
327 manager_proxy = _bt_hal_get_manager_proxy();
328 if (manager_proxy == NULL)
331 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
333 G_DBUS_CALL_FLAGS_NONE,
338 ERR("Can't get managed objects");
342 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
343 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
344 object_path = __bt_hal_extract_control_device_path(iter, address);
345 g_variant_iter_free(iter);
346 g_variant_unref(result);
350 static char *__bt_hal_get_transport_device_object_path(char *address)
352 char *object_path = NULL;
353 GDBusConnection *conn;
354 GDBusProxy *manager_proxy;
355 GVariant *result = NULL;
356 GVariantIter *iter = NULL;
358 conn = _bt_hal_get_system_gconn();
362 manager_proxy = _bt_hal_get_manager_proxy();
363 if (manager_proxy == NULL)
366 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
368 G_DBUS_CALL_FLAGS_NONE,
373 ERR("Can't get managed objects");
377 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
378 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
379 object_path = __bt_hal_extract_transport_device_path(iter, address);
380 g_variant_iter_free(iter);
381 g_variant_unref(result);
385 char *_bt_hal_get_control_device_path(bt_bdaddr_t *bd_addr)
388 char connected_address[BT_HAL_ADDRESS_STRING_SIZE];
392 if (avrcp_control_path != NULL)
393 return avrcp_control_path;
395 _bt_hal_convert_addr_type_to_string(connected_address, bd_addr->address);
397 DBG("device address = %s", connected_address);
399 control_path = __bt_hal_get_control_device_object_path(connected_address);
400 if (control_path == NULL)
403 avrcp_control_path = control_path;
404 DBG("control_path = %s", control_path);
408 char *_bt_hal_get_transport_device_path(bt_bdaddr_t *bd_addr)
410 char *transport_path;
411 char connected_address[BT_HAL_ADDRESS_STRING_SIZE];
415 if (avrcp_transport_path != NULL)
416 return avrcp_transport_path;
418 _bt_hal_convert_addr_type_to_string(connected_address, bd_addr->address);
420 DBG("device address = %s", connected_address);
422 transport_path = __bt_hal_get_transport_device_object_path(connected_address);
423 if (transport_path == NULL)
426 avrcp_transport_path = transport_path;
427 DBG("transport_path = %s", transport_path);
428 return transport_path;
431 static GDBusProxy *__bt_hal_init_avrcp_ctrl_proxy(bt_bdaddr_t *bd_addr)
433 GDBusProxy *manager_proxy;
435 GDBusConnection *gconn = NULL;
438 gconn = _bt_hal_get_system_gconn();
442 manager_proxy = _bt_hal_get_manager_proxy();
443 if (manager_proxy == NULL)
446 for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
447 if (proxy_array[i].avrcp_ctrl_proxy == NULL) {
448 memcpy(proxy_array[i].bd_addr.address, bd_addr->address, 6);
449 DBG("PATH %s formed index %d ", proxy_array[i].avrcp_control_path, i);
454 if (i == BT_AUDIO_SOURCE_MAX) {
455 ERR("NO free arr proxy space found");
459 proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE,
460 NULL, BT_HAL_BLUEZ_NAME,
461 proxy_array[i].avrcp_control_path, BT_HAL_PLAYER_CONTROL_INTERFACE, NULL, NULL);
466 avrcp_ctrl_proxy = proxy;
467 proxy_array[i].avrcp_ctrl_proxy = proxy;
472 GDBusProxy *_bt_hal_get_manager_proxy(void)
475 if (manager_gproxy) {
476 const gchar *path = g_dbus_proxy_get_object_path(manager_gproxy);
478 ERR("Already proxy released hence creating new proxy");
479 return __bt_hal_init_manager_proxy();
481 return manager_gproxy;
484 return __bt_hal_init_manager_proxy();
487 GDBusProxy *_bt_hal_get_adapter_proxy(void)
489 if (adapter_gproxy) {
490 const char *path = g_dbus_proxy_get_object_path(adapter_gproxy);
492 ERR("Already proxy released hence creating new proxy");
493 return __bt_hal_init_adapter_proxy();
496 return adapter_gproxy;
498 return __bt_hal_init_adapter_proxy();
502 GDBusProxy *_bt_hal_get_avrcp_ctrl_proxy(bt_bdaddr_t *bd_addr)
506 for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
507 if (proxy_array[i].avrcp_ctrl_proxy
508 && (!memcmp(proxy_array[i].bd_addr.address, bd_addr->address, 6))) {
509 const gchar *path = g_dbus_proxy_get_object_path(proxy_array[i].avrcp_ctrl_proxy);
512 proxy_array[i].avrcp_ctrl_proxy = NULL;
513 ERR("Already proxy released hence creating new proxy");
514 return __bt_hal_init_avrcp_ctrl_proxy(bd_addr);
517 DBG("address found path PATH %s", path);
518 return proxy_array[i].avrcp_ctrl_proxy;
522 DBG("address NOT found");
524 return __bt_hal_init_avrcp_ctrl_proxy(bd_addr);
527 GDBusProxy *_bt_hal_get_avrcp_ctrl_properties_proxy(bt_bdaddr_t *bd_addr)
530 GError *error = NULL;
531 char *control_path = NULL;
532 GDBusConnection *conn = NULL;
535 control_path = _bt_hal_get_control_device_path(bd_addr);
536 if (control_path == NULL)
539 DBG("control_path = %s", control_path);
541 conn = _bt_hal_get_system_gconn();
543 ERR("FAIL to get system connection");
546 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
547 NULL, BT_HAL_BLUEZ_NAME,
548 control_path, BT_HAL_PROPERTIES_INTERFACE, NULL, &error);
551 ERR("Unable to allocate new proxy");
553 ERR("%s", error->message);
554 g_clear_error(&error);
563 GDBusProxy *_bt_hal_get_avrcp_transport_properties_proxy(bt_bdaddr_t *bd_addr)
566 GError *error = NULL;
567 char *transport_path = NULL;
568 GDBusConnection *conn = NULL;
571 transport_path = _bt_hal_get_transport_device_path(bd_addr);
572 if (transport_path == NULL)
575 DBG("transport_path = %s", transport_path);
577 conn = _bt_hal_get_system_gconn();
579 ERR("FAIL to get system connection");
582 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
583 NULL, BT_HAL_BLUEZ_NAME,
584 transport_path, BT_HAL_PROPERTIES_INTERFACE, NULL, &error);
587 ERR("Unable to allocate new proxy");
589 ERR("%s", error->message);
590 g_clear_error(&error);
599 GDBusProxy *_bt_hal_get_adapter_properties_proxy(void)
601 return (adapter_properties_proxy) ? adapter_properties_proxy :
602 __bt_hal_init_adapter_properties_proxy();
605 GDBusProxy *_bt_hal_get_profile_proxy(void)
607 GDBusConnection *gconn;
611 return profile_gproxy;
613 gconn = _bt_hal_get_system_gconn();
615 ERR("_bt_hal_get_system_gconn failed");
619 profile_gproxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE,
620 NULL, BT_HAL_BLUEZ_NAME,
622 "org.bluez.ProfileManager1",
625 ERR("Unable to create proxy: %s", err->message);
630 return profile_gproxy;
633 static char *__bt_hal_extract_adapter_path(GVariantIter *iter)
635 char *object_path = NULL;
636 GVariantIter *interface_iter;
637 GVariantIter *svc_iter;
638 char *interface_str = NULL;
640 /* Parse the signature: oa{sa{sv}}} */
641 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
644 if (object_path == NULL)
647 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
648 &interface_str, &svc_iter)) {
649 if (g_strcmp0(interface_str, "org.bluez.Adapter1") != 0)
652 DBG("Object Path: %s", object_path);
653 g_free(interface_str);
654 g_variant_iter_free(svc_iter);
655 g_variant_iter_free(interface_iter);
656 return g_strdup(object_path);
662 char *_bt_hal_get_adapter_path(void)
664 GDBusConnection *conn;
665 GDBusProxy *manager_proxy;
666 GVariant *result = NULL;
667 GVariantIter *iter = NULL;
668 char *adapter_path = NULL;
671 conn = _bt_hal_get_system_gconn();
675 manager_proxy = _bt_hal_get_manager_proxy();
676 if (manager_proxy == NULL)
679 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
681 G_DBUS_CALL_FLAGS_NONE,
686 ERR("Can't get managed objects");
690 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
691 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
693 adapter_path = __bt_hal_extract_adapter_path(iter);
694 g_variant_iter_free(iter);
695 g_variant_unref(result);
700 int _bt_hal_is_adapter_powered(gboolean *powered)
703 GError *error = NULL;
708 proxy = _bt_hal_get_adapter_properties_proxy();
710 return BT_STATUS_FAIL;
712 result = g_dbus_proxy_call_sync(proxy,
714 g_variant_new("(ss)", BT_HAL_ADAPTER_INTERFACE,
716 G_DBUS_CALL_FLAGS_NONE,
722 ERR("Failed to get powered status");
724 ERR("Failed to get powered status (Error: %s)", error->message);
725 g_clear_error(&error);
727 return BT_STATUS_FAIL;
730 g_variant_get(result, "(v)", &temp);
731 *powered = g_variant_get_boolean(temp);
732 INFO("powered: %d", *powered);
734 g_variant_unref(result);
735 g_variant_unref(temp);
736 return BT_STATUS_SUCCESS;
739 void _bt_hal_deinit_bluez_proxy(void)
741 if (manager_gproxy) {
742 g_object_unref(manager_gproxy);
743 manager_gproxy = NULL;
746 if (adapter_gproxy) {
747 g_object_unref(adapter_gproxy);
748 adapter_gproxy = NULL;
750 if (adapter_properties_proxy) {
751 g_object_unref(adapter_properties_proxy);
752 adapter_properties_proxy = NULL;
756 void _bt_hal_deinit_proxys(void)
758 _bt_hal_deinit_bluez_proxy();
761 g_object_unref(system_conn);
766 g_object_unref(session_conn);
771 GDBusProxy *_bt_hal_get_hid_agent_proxy(void)
773 GDBusConnection *conn;
777 conn = _bt_hal_get_system_gconn();
779 ERR("_bt_hal_get_system_gconn failed");
783 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
784 BT_HAL_HID_SERVICE_NAME, BT_HAL_HID_AGENT_OBJECT_PATH,
785 BT_HAL_HID_SERVICE_INTERFACE, NULL, &err);
788 ERR("Unable to create proxy: %s", err->message);
797 void _bt_hal_convert_device_path_to_address(const char *device_path,
798 char *device_address)
800 char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
803 if (device_path == NULL || device_address == NULL)
806 dev_addr = strstr(device_path, "dev_");
807 if (dev_addr != NULL) {
810 g_strlcpy(address, dev_addr, sizeof(address));
812 while ((pos = strchr(address, '_')) != NULL)
815 g_strlcpy(device_address, address, BT_HAL_ADDRESS_STRING_SIZE);
819 gboolean _bt_hal_uuid_is_standard(bt_uuid_t *p_uuid)
821 uint32_t uuid0, uuid4;
822 uint16_t uuid1, uuid2, uuid3, uuid5;
823 const char *uuid_name;
824 const char *uuid_name1;
826 memcpy(&uuid0, &(p_uuid->uu[0]), 4);
827 memcpy(&uuid1, &(p_uuid->uu[4]), 2);
828 memcpy(&uuid2, &(p_uuid->uu[6]), 2);
829 memcpy(&uuid3, &(p_uuid->uu[8]), 2);
830 memcpy(&uuid4, &(p_uuid->uu[10]), 4);
831 memcpy(&uuid5, &(p_uuid->uu[14]), 2);
833 uuid_name = _bt_hal_dump_uuid_name(ntohl(uuid0));
834 uuid_name1 = _bt_hal_dump_uuid_name((ntohl(uuid4) >> 16));
836 DBG("UUID Name [%s]", uuid_name);
837 DBG("UUID Name Shifted [%s]", uuid_name1);
839 if (!g_strcmp0(uuid_name, "--"))
846 void _bt_hal_convert_uuid_string_to_type(unsigned char *uuid,
847 const char *device_uuid)
849 uint32_t uuid0, uuid4;
850 uint16_t uuid1, uuid2, uuid3, uuid5;
852 sscanf(device_uuid, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
853 &uuid0, &uuid1, &uuid2, &uuid3, &uuid4, &uuid5);
855 uuid0 = htonl(uuid0);
856 uuid1 = htons(uuid1);
857 uuid2 = htons(uuid2);
858 uuid3 = htons(uuid3);
859 uuid4 = htonl(uuid4);
860 uuid5 = htons(uuid5);
862 memcpy(&(uuid[0]), &uuid0, 4);
863 memcpy(&(uuid[4]), &uuid1, 2);
864 memcpy(&(uuid[6]), &uuid2, 2);
865 memcpy(&(uuid[8]), &uuid3, 2);
866 memcpy(&(uuid[10]), &uuid4, 4);
867 memcpy(&(uuid[14]), &uuid5, 2);
870 void _bt_hal_convert_uuid_type_to_string(char *str, const unsigned char *uuid)
882 snprintf(str, BT_HAL_UUID_STRING_LEN,
883 "%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X",
884 uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
885 uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
888 void _bt_hal_convert_addr_string_to_type(unsigned char *addr,
894 if (address == NULL || addr == NULL)
897 for (i = 0; i < BT_HAL_ADDRESS_LENGTH_MAX; i++) {
898 addr[i] = strtol(address, &ptr, 16);
900 if (ptr[0] != '\0') {
909 void _bt_hal_convert_addr_type_to_string(char *address,
910 const unsigned char *addr)
912 if (address == NULL || addr == NULL)
915 snprintf(address, BT_HAL_ADDRESS_STRING_SIZE,
916 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
917 addr[0], addr[1], addr[2],
918 addr[3], addr[4], addr[5]);
921 void _bt_hal_print_device_address_t(const bt_hal_device_address_t *addr)
923 DBG("%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", addr->addr[0], addr->addr[1], addr->addr[2],
924 addr->addr[3], addr->addr[4], addr->addr[5]);
927 void _bt_hal_divide_device_class(bt_hal_device_class_t *device_class,
930 if (device_class == NULL)
933 device_class->major_class = (unsigned short)(cod & 0x00001F00) >> 8;
934 device_class->minor_class = (unsigned short)((cod & 0x000000FC));
935 device_class->service_class = (unsigned long)((cod & 0x00FF0000));
937 if (cod & 0x002000) {
938 device_class->service_class |=
939 BT_HAL_DEVICE_SERVICE_CLASS_LIMITED_DISCOVERABLE_MODE;
943 int _bt_hal_copy_utf8_string(char *dest, const char *src, unsigned int length)
950 if (dest == NULL || src == NULL)
951 return BT_HAL_ERROR_INVALID_PARAM;
953 DBG("+src : %s", src);
954 DBG("+dest : %s", dest);
957 while (*p != '\0' && i < length) {
958 next = g_utf8_next_char(p);
961 while (count > 0 && ((i + count) < length)) {
968 return BT_HAL_ERROR_NONE;
971 gboolean _bt_hal_utf8_validate(char *name)
975 glong items_written = 0;
977 if (FALSE == g_utf8_validate(name, -1, NULL))
980 u16 = g_utf8_to_utf16(name, -1, NULL, &items_written, NULL);
986 if (items_written != g_utf8_strlen(name, -1))
993 int _bt_hal_set_socket_non_blocking(int socket_fd)
995 /* Set Nonblocking */
998 arg = fcntl(socket_fd, F_GETFL);
1003 if (arg & O_NONBLOCK)
1004 ERR("Already Non-blocking \n");
1008 if (fcntl(socket_fd, F_SETFL, arg) < 0)
1011 return BT_HAL_ERROR_NONE;
1014 int _bt_hal_set_non_blocking_tty(int sk)
1016 struct termios ti = {0,};
1019 err = _bt_hal_set_socket_non_blocking(sk);
1022 ERR("Error in set non blocking!\n");
1026 tcflush(sk, TCIOFLUSH);
1028 /* Switch tty to RAW mode */
1030 tcsetattr(sk, TCSANOW, &ti);
1032 return BT_HAL_ERROR_NONE;
1035 static char *__bt_hal_extract_device_path(GVariantIter *iter, char *address)
1037 char *object_path = NULL;
1038 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
1040 /* Parse the signature: oa{sa{sv}}} */
1041 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, NULL)) {
1042 if (object_path == NULL)
1044 _bt_hal_convert_device_path_to_address(object_path, device_address);
1045 if (g_strcmp0(address, device_address) == 0)
1046 return g_strdup(object_path);
1051 char *_bt_hal_get_device_object_path(char *address)
1053 char *object_path = NULL;
1054 GDBusConnection *conn;
1055 GDBusProxy *manager_proxy;
1056 GVariant *result = NULL;
1057 GVariantIter *iter = NULL;
1059 conn = _bt_hal_get_system_gconn();
1063 manager_proxy = _bt_hal_get_manager_proxy();
1064 if (manager_proxy == NULL)
1067 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
1069 G_DBUS_CALL_FLAGS_NONE,
1074 ERR("Can't get managed objects");
1078 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
1079 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
1080 object_path = __bt_hal_extract_device_path(iter, address);
1081 g_variant_iter_free(iter);
1082 g_variant_unref(result);
1086 GVariant *_bt_hal_get_managed_objects(void)
1088 GDBusConnection *conn;
1089 GDBusProxy *manager_proxy;
1090 GVariant *result = NULL;
1091 GError *error = NULL;
1094 conn = _bt_hal_get_system_gconn();
1098 manager_proxy = _bt_hal_get_manager_proxy();
1099 if (manager_proxy == NULL)
1102 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
1104 G_DBUS_CALL_FLAGS_NONE,
1109 ERR("Can't get managed objects");
1114 ERR("Fail to get ManagedObjects (Error: %s)", error->message);
1115 g_clear_error(&error);
1122 char *_bt_hal_convert_error_to_string(int error)
1125 case BT_HAL_ERROR_CANCEL:
1127 case BT_HAL_ERROR_INVALID_PARAM:
1128 return "INVALID_PARAMETER";
1129 case BT_HAL_ERROR_INVALID_DATA:
1130 return "INVALID DATA";
1131 case BT_HAL_ERROR_MEMORY_ALLOCATION:
1132 case BT_HAL_ERROR_OUT_OF_MEMORY:
1133 return "OUT_OF_MEMORY";
1134 case BT_HAL_ERROR_TIMEOUT:
1136 case BT_HAL_ERROR_NO_RESOURCES:
1137 return "NO_RESOURCES";
1138 case BT_HAL_ERROR_INTERNAL:
1140 case BT_HAL_ERROR_NOT_SUPPORT:
1141 return "NOT_SUPPORT";
1142 case BT_HAL_ERROR_DEVICE_NOT_ENABLED:
1143 return "NOT_ENABLED";
1144 case BT_HAL_ERROR_DEVICE_ALREADY_ENABLED:
1145 return "ALREADY_ENABLED";
1146 case BT_HAL_ERROR_DEVICE_BUSY:
1147 return "DEVICE_BUSY";
1148 case BT_HAL_ERROR_ACCESS_DENIED:
1149 return "ACCESS_DENIED";
1150 case BT_HAL_ERROR_MAX_CLIENT:
1151 return "MAX_CLIENT";
1152 case BT_HAL_ERROR_NOT_FOUND:
1154 case BT_HAL_ERROR_SERVICE_SEARCH_ERROR:
1155 return "SERVICE_SEARCH_ERROR";
1156 case BT_HAL_ERROR_PARING_FAILED:
1157 return "PARING_FAILED";
1158 case BT_HAL_ERROR_NOT_PAIRED:
1159 return "NOT_PAIRED";
1160 case BT_HAL_ERROR_SERVICE_NOT_FOUND:
1161 return "SERVICE_NOT_FOUND";
1162 case BT_HAL_ERROR_NOT_CONNECTED:
1163 return "NOT_CONNECTED";
1164 case BT_HAL_ERROR_ALREADY_CONNECT:
1165 return "ALREADY_CONNECT";
1166 case BT_HAL_ERROR_CONNECTION_BUSY:
1167 return "CONNECTION_BUSY";
1168 case BT_HAL_ERROR_CONNECTION_ERROR:
1169 return "CONNECTION_ERROR";
1170 case BT_HAL_ERROR_MAX_CONNECTION:
1171 return "MAX_CONNECTION";
1172 case BT_HAL_ERROR_NOT_IN_OPERATION:
1173 return "NOT_IN_OPERATION";
1174 case BT_HAL_ERROR_CANCEL_BY_USER:
1175 return "CANCEL_BY_USER";
1176 case BT_HAL_ERROR_REGISTRATION_FAILED:
1177 return "REGISTRATION_FAILED";
1178 case BT_HAL_ERROR_IN_PROGRESS:
1179 return "IN_PROGRESS";
1180 case BT_HAL_ERROR_AUTHENTICATION_FAILED:
1181 return "AUTHENTICATION_FAILED";
1182 case BT_HAL_ERROR_HOST_DOWN:
1184 case BT_HAL_ERROR_END_OF_DEVICE_LIST:
1185 return "END_OF_DEVICE_LIST";
1186 case BT_HAL_ERROR_AGENT_ALREADY_EXIST:
1187 return "AGENT_ALREADY_EXIST";
1188 case BT_HAL_ERROR_AGENT_DOES_NOT_EXIST:
1189 return "AGENT_DOES_NOT_EXIST";
1190 case BT_HAL_ERROR_ALREADY_INITIALIZED:
1191 return "ALREADY_INITIALIZED";
1192 case BT_HAL_ERROR_PERMISSION_DEINED:
1193 return "PERMISSION_DEINED";
1194 case BT_HAL_ERROR_ALREADY_DEACTIVATED:
1195 return "ALREADY_DEACTIVATED";
1196 case BT_HAL_ERROR_NOT_INITIALIZED:
1197 return "NOT_INITIALIZED";
1203 char * _bt_hal_convert_disc_reason_to_string(int reason)
1209 return "Connection terminated by local host";
1211 return "Remote user terminated connection";
1218 int _bt_hal_convert_disc_reason_to_status(int reason)
1222 return BT_STATUS_CONN_TOUT; //"Link loss"
1224 return BT_STATUS_CONN_TERM_LOCAL_HOST; //"Connection terminated by local host";
1226 return BT_STATUS_CONN_TERM_RMT_HOST; //"Connection terminated by local host";
1229 return BT_STATUS_FAIL;
1233 void _bt_hal_logging_connection(gboolean connect, int addr_type)
1235 static int le_conn = 0;
1236 static int le_disc = 0;
1237 static int edr_conn = 0;
1238 static int edr_disc = 0;
1252 INFO("[PM] Number of LE conn: %d disc: %d, Number of BR/EDR conn: %d disc: %d",
1253 le_conn, le_disc, edr_conn, edr_disc);
1256 void _bt_hal_swap_byte_ordering(char *data, int data_len)
1263 /* Swap to opposite endian */
1264 for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
1271 int _bt_hal_byte_arr_cmp(const char *data1, const char *data2, int data_len)
1275 if (data1 == NULL || data2 == NULL)
1277 for (i = 0; i < data_len; i++) {
1278 if (data1[i] != data2[i])
1279 return data1[i] - data2[i];
1283 int _bt_hal_byte_arr_cmp_with_mask(const char *data1, const char *data2,
1284 const char *mask, int data_len)
1289 if (data1 == NULL || data2 == NULL || mask == NULL)
1292 for (i = 0; i < data_len; i++) {
1293 a = data1[i] & mask[i];
1294 b = data2[i] & mask[i];
1296 return (int)(a - b);
1301 int _bt_hal_connect_profile(char *address, char *uuid,
1302 void *cb, gpointer func_data)
1306 GDBusConnection *conn;
1307 GDBusProxy *adapter_proxy;
1308 GError *error = NULL;
1310 conn = _bt_hal_get_system_gconn();
1312 return BT_HAL_ERROR_INTERNAL;
1314 object_path = _bt_hal_get_device_object_path(address);
1315 if (object_path == NULL) {
1316 ERR("No searched device");
1318 adapter_proxy = _bt_hal_get_adapter_proxy();
1319 if (adapter_proxy == NULL)
1320 return BT_HAL_ERROR_INTERNAL;
1322 g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1323 g_variant_new("(s)", address),
1324 G_DBUS_CALL_FLAGS_NONE,
1329 if (error != NULL) {
1330 ERR("CreateDevice Fail: %s", error->message);
1331 g_error_free(error);
1334 object_path = _bt_hal_get_device_object_path(address);
1336 if (object_path == NULL)
1337 return BT_HAL_ERROR_INTERNAL;
1339 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1340 NULL, BT_HAL_BLUEZ_NAME,
1341 object_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1342 g_free(object_path);
1344 return BT_HAL_ERROR_INTERNAL;
1347 g_dbus_proxy_call(proxy, "ConnectProfile",
1348 g_variant_new("(s)", uuid),
1349 G_DBUS_CALL_FLAGS_NONE,
1350 BT_HAL_MAX_DBUS_TIMEOUT,
1352 (GAsyncReadyCallback)cb,
1355 return BT_HAL_ERROR_NONE;
1358 int _bt_hal_disconnect_profile(char *address, char *uuid,
1359 void *cb, gpointer func_data)
1363 GDBusConnection *conn;
1365 conn = _bt_hal_get_system_gconn();
1367 return BT_HAL_ERROR_INTERNAL;
1369 object_path = _bt_hal_get_device_object_path(address);
1370 if (object_path == NULL)
1371 return BT_HAL_ERROR_INTERNAL;
1373 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1374 NULL, BT_HAL_BLUEZ_NAME,
1375 object_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1376 g_free(object_path);
1378 return BT_HAL_ERROR_INTERNAL;
1380 g_dbus_proxy_call(proxy, "DisconnectProfile",
1381 g_variant_new("(s)", uuid),
1382 G_DBUS_CALL_FLAGS_NONE,
1383 BT_HAL_MAX_DBUS_TIMEOUT,
1385 (GAsyncReadyCallback)cb,
1388 return BT_HAL_ERROR_NONE;
1391 int _bt_hal_register_profile(bt_hal_register_profile_info_t *info, gboolean use_default_rfcomm)
1393 GVariantBuilder *option_builder;
1397 int result = BT_STATUS_SUCCESS;
1399 proxy = _bt_hal_get_profile_proxy();
1400 if (proxy == NULL) {
1401 ERR("Getting profile proxy failed");
1402 return BT_STATUS_FAIL;
1405 option_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1406 if (info->authentication)
1407 g_variant_builder_add(option_builder, "{sv}",
1408 "RequireAuthentication",
1409 g_variant_new_boolean(TRUE));
1410 if (info->authorization)
1411 g_variant_builder_add(option_builder, "{sv}",
1412 "RequireAuthorization",
1413 g_variant_new_boolean(TRUE));
1415 g_variant_builder_add(option_builder, "{sv}",
1417 g_variant_new_string(info->role));
1420 * Setting RFCOMM channel to default value 0; would allow bluez to assign
1421 * RFCOMM channels based on the availability when two services want to use
1422 * the RFCOMM along with SPP. Hence bluez makes sure that no two services
1423 * use the same SPP RFCOMM channel.
1425 if (use_default_rfcomm)
1426 g_variant_builder_add(option_builder, "{sv}",
1428 g_variant_new_uint16(RFCOMM_DEFAULT_PROFILE_CHANNEL));
1430 g_variant_builder_add(option_builder, "{sv}",
1432 g_variant_new_string(info->service));
1434 ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile",
1435 g_variant_new("(osa{sv})", info->obj_path,
1438 G_DBUS_CALL_FLAGS_NONE, -1,
1441 ERR("RegisterProfile failed: %s", err->message);
1443 if (g_strrstr(err->message, BT_HAL_ACCESS_DENIED_MSG))
1444 result = BT_STATUS_AUTH_REJECTED;
1446 result = BT_STATUS_FAIL;
1448 g_clear_error(&err);
1451 g_variant_builder_unref(option_builder);
1454 g_variant_unref(ret);
1459 void _bt_hal_unregister_profile(char *path)
1465 proxy = _bt_hal_get_profile_proxy();
1466 if (proxy == NULL) {
1467 ERR("Getting profile proxy failed");
1471 ret = g_dbus_proxy_call_sync(proxy, "UnregisterProfile",
1472 g_variant_new("(o)", path),
1473 G_DBUS_CALL_FLAGS_NONE, -1,
1476 ERR("UnregisterProfile failed : %s", err->message);
1477 g_clear_error(&err);
1481 g_variant_unref(ret);
1486 static void __hal_new_connection_method(GDBusConnection *connection,
1487 const gchar *sender,
1488 const gchar *object_path,
1489 const gchar *interface_name,
1490 const gchar *method_name,
1491 GVariant *parameters,
1492 GDBusMethodInvocation *invocation,
1495 DBG("method %s", method_name);
1496 if (g_strcmp0(method_name, "NewConnection") == 0) {
1499 GUnixFDList *fd_list;
1501 GVariantBuilder *properties;
1503 bt_bdaddr_t remote_addr1;
1504 char addr[BT_HAL_ADDRESS_STRING_SIZE];
1505 bt_hal_new_connection_cb cb = user_data;
1507 g_variant_get(parameters, "(oha{sv})", &obj_path, &index,
1510 msg = g_dbus_method_invocation_get_message(invocation);
1511 fd_list = g_dbus_message_get_unix_fd_list(msg);
1512 if (fd_list == NULL) {
1513 GQuark quark = g_quark_from_string("rfcomm-app");
1514 GError *err = g_error_new(quark, 0, "No fd in message");
1515 g_dbus_method_invocation_return_gerror(invocation, err);
1521 fd = g_unix_fd_list_get(fd_list, index, NULL);
1523 ERR("Invalid fd return");
1524 GQuark quark = g_quark_from_string("rfcomm-app");
1525 GError *err = g_error_new(quark, 0, "Invalid FD return");
1526 g_dbus_method_invocation_return_gerror(invocation, err);
1530 INFO("Object Path %s", obj_path);
1532 _bt_hal_convert_device_path_to_address(obj_path, addr);
1533 _bt_hal_convert_addr_string_to_type(remote_addr1.address, (const char *)addr);
1534 INFO("fd: %d, address %s", fd, addr);
1536 g_dbus_method_invocation_return_value(invocation, NULL);
1539 cb(object_path, fd, &remote_addr1);
1542 } else if (g_strcmp0(method_name, "RequestDisconnection") == 0) {
1543 g_dbus_method_invocation_return_value(invocation, NULL);
1547 static GDBusNodeInfo *_bt_hal_get_gdbus_node(const gchar *xml_data)
1550 char *name = g_strdup_printf("org.bt.frwk.p%d", getpid());
1552 bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1554 G_BUS_NAME_OWNER_FLAGS_NONE,
1560 DBG("Got bus id %d", bus_id);
1564 return g_dbus_node_info_new_for_xml(xml_data, NULL);
1567 static const GDBusInterfaceVTable method_table = {
1568 __hal_new_connection_method,
1573 int _bt_hal_register_new_gdbus_object(const char *path, bt_hal_new_connection_cb cb)
1575 GDBusConnection *gconn;
1577 GError *error = NULL;
1579 gconn = _bt_hal_get_system_gconn();
1583 if (new_conn_node == NULL)
1584 new_conn_node = _bt_hal_get_gdbus_node(rfcomm_agent_xml);
1586 if (new_conn_node == NULL)
1589 id = g_dbus_connection_register_object(gconn, path,
1590 new_conn_node->interfaces[0],
1594 ERR("Failed to register: %s", error->message);
1595 g_error_free(error);
1599 DBG("NEW CONNECTION ID %d", id);
1604 void _bt_hal_unregister_gdbus_object(int object_id)
1606 GDBusConnection *gconn;
1608 gconn = _bt_hal_get_system_gconn();
1612 g_dbus_connection_unregister_object(gconn, object_id);
1615 int _bt_hal_discover_services(char *address, char *uuid, void *cb, gpointer func_data)
1619 GDBusProxy *adapter_proxy;
1621 GDBusConnection *conn;
1623 conn = _bt_hal_get_system_gconn();
1625 ERR("conn == NULL, return");
1626 return BT_STATUS_FAIL;
1629 object_path = _bt_hal_get_device_object_path(address);
1630 if (object_path == NULL) {
1631 GVariant *ret = NULL;
1633 INFO("No searched device");
1634 adapter_proxy = _bt_hal_get_adapter_proxy();
1635 if (adapter_proxy == NULL) {
1636 ERR("adapter_proxy == NULL, return");
1637 return BT_STATUS_FAIL;
1640 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1641 g_variant_new("(s)", address),
1642 G_DBUS_CALL_FLAGS_NONE,
1643 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1646 ERR("CreateDevice Failed: %s", err->message);
1647 g_clear_error(&err);
1651 g_variant_unref(ret);
1653 g_object_unref(adapter_proxy);
1654 object_path = _bt_hal_get_device_object_path(address);
1655 if (object_path == NULL) {
1656 ERR("object_path == NULL, return");
1657 return BT_STATUS_FAIL;
1661 proxy = g_dbus_proxy_new_sync(conn,
1662 G_DBUS_PROXY_FLAGS_NONE, NULL,
1663 BT_HAL_BLUEZ_NAME, object_path,
1664 BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1665 g_free(object_path);
1666 if (proxy == NULL) {
1667 ERR("Error while getting proxy");
1668 return BT_STATUS_FAIL;
1671 g_dbus_proxy_call(proxy, "DiscoverServices",
1672 g_variant_new("(s)", uuid),
1673 G_DBUS_CALL_FLAGS_NONE,
1674 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1675 (GAsyncReadyCallback)cb,
1678 return BT_STATUS_SUCCESS;
1681 int _bt_hal_cancel_discovers(char *address)
1685 GDBusProxy *adapter_proxy;
1687 GDBusConnection *conn;
1689 conn = _bt_hal_get_system_gconn();
1691 return BT_STATUS_FAIL;
1693 object_path = _bt_hal_get_device_object_path(address);
1694 if (object_path == NULL) {
1695 GVariant *ret = NULL;
1696 INFO("No searched device");
1697 adapter_proxy = _bt_hal_get_adapter_proxy();
1698 if (adapter_proxy == NULL) {
1699 ERR("adapter_proxy == NULL, return");
1700 return BT_STATUS_FAIL;
1703 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1704 g_variant_new("(s)", address),
1705 G_DBUS_CALL_FLAGS_NONE,
1706 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1709 ERR("CreateDevice Failed: %s", err->message);
1710 g_clear_error(&err);
1714 g_variant_unref(ret);
1716 g_object_unref(adapter_proxy);
1718 object_path = _bt_hal_get_device_object_path(address);
1719 if (object_path == NULL)
1720 return BT_STATUS_FAIL;
1723 proxy = g_dbus_proxy_new_sync(conn,
1724 G_DBUS_PROXY_FLAGS_NONE, NULL,
1725 BT_HAL_BLUEZ_NAME, object_path,
1726 BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1727 g_free(object_path);
1728 g_dbus_proxy_call_sync(proxy, "CancelDiscovery",
1730 G_DBUS_CALL_FLAGS_NONE,
1731 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1734 ERR("DBus Error message: [%s]", err->message);
1735 g_clear_error(&err);
1736 return BT_STATUS_FAIL;
1740 g_object_unref(proxy);
1742 return BT_STATUS_SUCCESS;
1745 int _bt_hal_discover_service_uuids(char *address, char *remote_uuid)
1749 GDBusConnection *gconn;
1751 char **uuid_value = NULL;
1754 GVariant *value = NULL;
1755 GVariant *ret = NULL;
1756 int result = BT_STATUS_FAIL;
1760 if (remote_uuid == NULL) {
1761 ERR("remote_uuid == NULL, return");
1762 return BT_STATUS_FAIL;
1765 gconn = _bt_hal_get_system_gconn();
1766 if (gconn == NULL) {
1767 ERR("gconn == NULL, return");
1768 return BT_STATUS_FAIL;
1771 object_path = _bt_hal_get_device_object_path(address);
1772 if (object_path == NULL) {
1773 ERR("object_path == NULL, return");
1774 return BT_STATUS_FAIL;
1777 proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE, NULL,
1778 BT_HAL_BLUEZ_NAME, object_path, BT_HAL_PROPERTIES_INTERFACE, NULL,
1780 if (proxy == NULL) {
1781 g_free(object_path);
1782 ERR("proxy == NULL, return");
1783 return BT_STATUS_FAIL;
1787 ERR("DBus Error: [%s]", err->message);
1788 g_clear_error(&err);
1791 ret = g_dbus_proxy_call_sync(proxy, "GetAll",
1792 g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
1793 G_DBUS_CALL_FLAGS_NONE,
1794 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1797 result = BT_STATUS_FAIL;
1798 ERR("DBus Error : %s", err->message);
1799 g_clear_error(&err);
1804 ERR("g_dbus_proxy_call_sync function return NULL");
1805 result = BT_STATUS_FAIL;
1809 g_variant_get(ret, "(@a{sv})", &value);
1810 g_variant_unref(ret);
1812 GVariant *temp_value = g_variant_lookup_value(value, "UUIDs",
1813 G_VARIANT_TYPE_STRING_ARRAY);
1816 size = g_variant_get_size(temp_value);
1819 uuid_value = (char **)g_variant_get_strv(temp_value, &size);
1820 DBG("Size items %zu", size);
1824 g_variant_unref(temp_value);
1827 for (i = 0; uuid_value[i] != NULL; i++) {
1828 DBG("Remote uuids %s, searched uuid: %s",
1829 uuid_value[i], remote_uuid);
1830 if (strcasecmp(uuid_value[i], remote_uuid) == 0) {
1831 result = BT_STATUS_SUCCESS;
1840 g_object_unref(proxy);
1842 g_variant_unref(value);
1850 int bt_hal_gatt_convert_prop2string(
1851 bt_hal_gatt_characteristic_property_t properties,
1852 char *char_properties[])
1856 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_BROADCAST) {
1857 char_properties[flag_count] = g_strdup("broadcast");
1860 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_READ) {
1861 char_properties[flag_count] = g_strdup("read");
1864 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE) {
1865 char_properties[flag_count] = g_strdup("write-without-response");
1868 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE) {
1869 char_properties[flag_count] = g_strdup("write");
1872 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY) {
1873 char_properties[flag_count] = g_strdup("notify");
1876 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE) {
1877 char_properties[flag_count] = g_strdup("indicate");
1880 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE) {
1881 char_properties[flag_count] = g_strdup("authenticated-signed-writes");
1884 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE) {
1885 char_properties[flag_count] = g_strdup("reliable-write");
1888 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES) {
1889 char_properties[flag_count] = g_strdup("writable-auxiliaries");
1892 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ) {
1893 char_properties[flag_count] = g_strdup("encrypt-read");
1896 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE) {
1897 char_properties[flag_count] = g_strdup("encrypt-write");
1900 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ) {
1901 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
1904 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE) {
1905 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
1909 if (flag_count == 0) {
1910 char_properties[flag_count] = g_strdup("read");
1917 int bt_hal_gatt_convert_perm2string(
1918 bt_hal_gatt_permission_t properties,
1919 char *char_properties[])
1923 if (properties & BT_HAL_GATT_PERMISSION_READ) {
1924 char_properties[flag_count] = g_strdup("read");
1927 if (properties & BT_HAL_GATT_PERMISSION_WRITE) {
1928 char_properties[flag_count] = g_strdup("write");
1931 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_READ) {
1932 char_properties[flag_count] = g_strdup("encrypt-read");
1935 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_WRITE) {
1936 char_properties[flag_count] = g_strdup("encrypt-write");
1939 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_READ) {
1940 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
1943 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_WRITE) {
1944 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
1948 if (flag_count == 0) {
1949 char_properties[flag_count] = g_strdup("read");
1956 gboolean _bt_hal_is_service_enabled(const char *uuid)
1959 GError *error = NULL;
1962 GVariantIter *iter = NULL;
1964 gboolean ret = FALSE;
1968 proxy = _bt_hal_get_adapter_properties_proxy();
1970 DBG("_bt_hal_dbus_get_local_name: Adapter Properties proxy get failed!!!");
1974 result = g_dbus_proxy_call_sync(proxy,
1975 "Get", g_variant_new("(ss)",
1976 BT_HAL_ADAPTER_INTERFACE, "UUIDs"),
1977 G_DBUS_CALL_FLAGS_NONE, -1,
1980 if (error != NULL) {
1981 ERR("Failed to get UUIDs (Error: %s)", error->message);
1982 g_clear_error(&error);
1984 ERR("Failed to get UUIDs");
1988 g_variant_get(result, "(v)", &temp);
1989 g_variant_get(temp, "as", &iter);
1991 ERR("Failed to get UUIDs");
1992 g_variant_unref(result);
1996 while (g_variant_iter_loop(iter, "s", &uuid_str)) {
1997 DBG("UUID string [%s]\n", uuid_str);
1998 if (!strncasecmp(uuid, uuid_str, strlen(uuid))) {
2004 g_variant_iter_free(iter);
2005 g_variant_unref(result);
2006 g_variant_unref(temp);