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 GDBusConnection *system_conn;
56 static GDBusConnection *session_conn;
57 static GDBusProxy *manager_gproxy = NULL;
58 static GDBusProxy *adapter_gproxy = NULL;
59 static GDBusProxy *profile_gproxy = NULL;
61 static GDBusProxy *adapter_properties_proxy;
62 static GDBusProxy *avrcp_ctrl_proxy;
65 GDBusProxy *avrcp_ctrl_proxy;
66 char *avrcp_control_path;
70 struct avrcp_proxy proxy_array[BT_AUDIO_SOURCE_MAX];
73 GDBusNodeInfo *new_conn_node;
74 static const gchar rfcomm_agent_xml[] =
76 " <interface name='org.bluez.Profile1'>"
77 " <method name='NewConnection'>"
78 " <arg type='o' name='object' direction='in'/>"
79 " <arg type='h' name='fd' direction='in'/>"
80 " <arg type='a{sv}' name='properties' direction='in'/>"
82 " <method name='RequestDisconnection'>"
83 " <arg type='o' name='device' direction='in'/>"
88 static GDBusConnection *__bt_hal_init_session_conn(void)
90 if (session_conn == NULL)
91 session_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
96 GDBusConnection *_bt_hal_get_session_gconn(void)
98 return (session_conn) ? session_conn : __bt_hal_init_session_conn();
101 static GDBusConnection *__bt_hal_init_system_gconn(void)
103 GError *error = NULL;
105 if (system_conn != NULL)
108 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
111 ERR("Unable to connect to dbus: %s", error->message);
112 g_clear_error(&error);
118 GDBusConnection *_bt_hal_get_system_gconn(void)
120 GDBusConnection *local_system_gconn = NULL;
121 GError *error = NULL;
123 if (system_conn == NULL) {
124 system_conn = __bt_hal_init_system_gconn();
125 } else if (g_dbus_connection_is_closed(system_conn)) {
127 local_system_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
129 if (!local_system_gconn) {
130 ERR("Unable to connect to dbus: %s", error->message);
131 g_clear_error(&error);
134 system_conn = local_system_gconn;
140 static GDBusProxy *__bt_hal_init_manager_proxy(void)
144 if (system_conn == NULL) {
145 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
146 if (system_conn == NULL)
150 proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
151 NULL, BT_HAL_BLUEZ_NAME,
152 BT_HAL_MANAGER_PATH, BT_HAL_MANAGER_INTERFACE, NULL, NULL);
157 manager_gproxy = proxy;
162 static GDBusProxy *__bt_hal_init_adapter_proxy(void)
164 GDBusProxy *manager_proxy;
166 char *adapter_path = NULL;
168 if (system_conn == NULL) {
169 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
170 if (system_conn == NULL)
174 manager_proxy = _bt_hal_get_manager_proxy();
175 if (manager_proxy == NULL)
178 adapter_path = _bt_hal_get_adapter_path();
179 if (adapter_path == NULL)
182 proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
183 NULL, BT_HAL_BLUEZ_NAME,
184 adapter_path, BT_HAL_ADAPTER_INTERFACE, NULL, NULL);
186 g_free(adapter_path);
191 adapter_gproxy = proxy;
196 static GDBusProxy *__bt_hal_init_adapter_properties_proxy(void)
198 GDBusProxy *manager_proxy;
200 char *adapter_path = NULL;
202 if (system_conn == NULL) {
203 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
204 if (system_conn == NULL)
208 manager_proxy = _bt_hal_get_manager_proxy();
209 if (manager_proxy == NULL)
212 adapter_path = _bt_hal_get_adapter_path();
213 if (adapter_path == NULL)
216 proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
217 NULL, BT_HAL_BLUEZ_NAME,
218 adapter_path, BT_HAL_PROPERTIES_INTERFACE, NULL, NULL);
220 g_free(adapter_path);
225 adapter_properties_proxy = proxy;
230 void _bt_hal_set_control_device_path(const char *path)
237 DBG("control_path = %s", path);
239 for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
240 if (proxy_array[i].avrcp_control_path == NULL) {
241 proxy_array[i].avrcp_control_path = g_strdup(path);
242 DBG("PATH %s formed index %d", proxy_array[i].avrcp_control_path, i);
248 void _bt_hal_remove_control_device_path(const char *path)
255 for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
256 if (g_strcmp0(proxy_array[i].avrcp_control_path, path) == 0) {
257 DBG("Clear AVRCP proxy[%d]", i);
258 g_free(proxy_array[i].avrcp_control_path);
259 g_object_unref(proxy_array[i].avrcp_ctrl_proxy);
261 proxy_array[i].avrcp_control_path = NULL;
262 proxy_array[i].avrcp_ctrl_proxy = NULL;
263 memset(proxy_array[i].bd_addr.address, 0, 6);
269 static char *__bt_hal_extract_control_device_path(GVariantIter *iter, char *address)
271 char *object_path = NULL;
272 char *interface_str = NULL;
273 GVariantIter *interface_iter;
274 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
276 /* Parse the signature: oa{sa{sv}}} */
277 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
278 if (object_path == NULL)
281 while(g_variant_iter_loop(interface_iter, "{&sa{sv}}", &interface_str, NULL)) {
282 if (g_strcmp0(interface_str, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
283 _bt_hal_convert_device_path_to_address(object_path, device_address);
284 if (g_strcmp0(address, device_address) == 0) {
285 DBG("Object Path: %s", object_path);
286 g_variant_iter_free(interface_iter);
287 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 GVariantIter *interface_iter;
300 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
302 /* Parse the signature: oa{sa{sv}}} */
303 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
304 if (object_path == NULL)
307 while(g_variant_iter_loop(interface_iter, "{&sa{sv}}", &interface_str, NULL)) {
308 if (g_strcmp0(interface_str, BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
309 _bt_hal_convert_device_path_to_address(object_path, device_address);
310 if (g_strcmp0(address, device_address) == 0) {
311 DBG("Object Path: %s", object_path);
312 g_variant_iter_free(interface_iter);
313 return g_strdup(object_path);
321 static char *__bt_hal_get_control_device_object_path(char *address)
323 char *object_path = NULL;
324 GDBusConnection *conn;
325 GDBusProxy *manager_proxy;
326 GVariant *result = NULL;
327 GVariantIter *iter = NULL;
329 conn = _bt_hal_get_system_gconn();
333 manager_proxy = _bt_hal_get_manager_proxy();
334 if (manager_proxy == NULL)
337 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
339 G_DBUS_CALL_FLAGS_NONE,
344 ERR("Can't get managed objects");
348 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
349 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
350 object_path = __bt_hal_extract_control_device_path(iter, address);
351 g_variant_iter_free(iter);
352 g_variant_unref(result);
356 static char *__bt_hal_get_transport_device_object_path(char *address)
358 char *object_path = NULL;
359 GDBusConnection *conn;
360 GDBusProxy *manager_proxy;
361 GVariant *result = NULL;
362 GVariantIter *iter = NULL;
364 conn = _bt_hal_get_system_gconn();
368 manager_proxy = _bt_hal_get_manager_proxy();
369 if (manager_proxy == NULL)
372 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
374 G_DBUS_CALL_FLAGS_NONE,
379 ERR("Can't get managed objects");
383 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
384 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
385 object_path = __bt_hal_extract_transport_device_path(iter, address);
386 g_variant_iter_free(iter);
387 g_variant_unref(result);
391 char *_bt_hal_get_control_device_path(bt_bdaddr_t *bd_addr)
394 char connected_address[BT_HAL_ADDRESS_STRING_SIZE];
396 /* We can add the cache to get transport path for each device */
398 _bt_hal_convert_addr_type_to_string(connected_address, bd_addr->address);
400 control_path = __bt_hal_get_control_device_object_path(connected_address);
401 if (control_path == NULL)
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];
413 /* We can add the cache to get transport path for each device */
415 _bt_hal_convert_addr_type_to_string(connected_address, bd_addr->address);
417 transport_path = __bt_hal_get_transport_device_object_path(connected_address);
418 if (transport_path == NULL)
421 DBG("transport_path = %s", transport_path);
422 return transport_path;
425 static GDBusProxy *__bt_hal_init_avrcp_ctrl_proxy(bt_bdaddr_t *bd_addr)
427 GDBusProxy *manager_proxy;
429 GDBusConnection *gconn = NULL;
432 gconn = _bt_hal_get_system_gconn();
436 manager_proxy = _bt_hal_get_manager_proxy();
437 if (manager_proxy == NULL)
440 for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
441 if (proxy_array[i].avrcp_ctrl_proxy == NULL) {
442 memcpy(proxy_array[i].bd_addr.address, bd_addr->address, 6);
443 DBG("PATH %s formed index %d ", proxy_array[i].avrcp_control_path, i);
448 if (i == BT_AUDIO_SOURCE_MAX) {
449 ERR("NO free arr proxy space found");
453 proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE,
454 NULL, BT_HAL_BLUEZ_NAME,
455 proxy_array[i].avrcp_control_path, BT_HAL_PLAYER_CONTROL_INTERFACE, NULL, NULL);
460 avrcp_ctrl_proxy = proxy;
461 proxy_array[i].avrcp_ctrl_proxy = proxy;
466 GDBusProxy *_bt_hal_get_manager_proxy(void)
468 if (manager_gproxy) {
469 const gchar *path = g_dbus_proxy_get_object_path(manager_gproxy);
471 ERR("Already proxy released hence creating new proxy");
472 return __bt_hal_init_manager_proxy();
474 return manager_gproxy;
476 return __bt_hal_init_manager_proxy();
479 GDBusProxy *_bt_hal_get_adapter_proxy(void)
481 if (adapter_gproxy) {
482 const char *path = g_dbus_proxy_get_object_path(adapter_gproxy);
484 ERR("Already proxy released hence creating new proxy");
485 return __bt_hal_init_adapter_proxy();
488 return adapter_gproxy;
490 return __bt_hal_init_adapter_proxy();
494 GDBusProxy *_bt_hal_get_avrcp_ctrl_proxy(bt_bdaddr_t *bd_addr)
498 for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
499 if (proxy_array[i].avrcp_ctrl_proxy
500 && (!memcmp(proxy_array[i].bd_addr.address, bd_addr->address, 6))) {
501 const gchar *path = g_dbus_proxy_get_object_path(proxy_array[i].avrcp_ctrl_proxy);
504 proxy_array[i].avrcp_ctrl_proxy = NULL;
505 ERR("Already proxy released hence creating new proxy");
506 return __bt_hal_init_avrcp_ctrl_proxy(bd_addr);
509 DBG("address found path PATH %s", path);
510 return proxy_array[i].avrcp_ctrl_proxy;
514 DBG("address NOT found");
516 return __bt_hal_init_avrcp_ctrl_proxy(bd_addr);
519 GDBusProxy *_bt_hal_get_avrcp_ctrl_properties_proxy(bt_bdaddr_t *bd_addr)
522 GError *error = NULL;
523 char *control_path = NULL;
524 GDBusConnection *conn = NULL;
526 control_path = _bt_hal_get_control_device_path(bd_addr);
527 if (control_path == NULL)
530 DBG("control_path = %s", control_path);
532 conn = _bt_hal_get_system_gconn();
534 ERR("FAIL to get system connection");
537 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
538 NULL, BT_HAL_BLUEZ_NAME,
539 control_path, BT_HAL_PROPERTIES_INTERFACE, NULL, &error);
542 ERR("Unable to allocate new proxy");
544 ERR("%s", error->message);
545 g_clear_error(&error);
553 GDBusProxy *_bt_hal_get_avrcp_transport_properties_proxy(bt_bdaddr_t *bd_addr)
556 GError *error = NULL;
557 char *transport_path = NULL;
558 GDBusConnection *conn = NULL;
560 transport_path = _bt_hal_get_transport_device_path(bd_addr);
561 if (transport_path == NULL)
564 DBG("transport_path = %s", transport_path);
566 conn = _bt_hal_get_system_gconn();
568 ERR("FAIL to get system connection");
571 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
572 NULL, BT_HAL_BLUEZ_NAME,
573 transport_path, BT_HAL_PROPERTIES_INTERFACE, NULL, &error);
576 ERR("Unable to allocate new proxy");
578 ERR("%s", error->message);
579 g_clear_error(&error);
587 GDBusProxy *_bt_hal_get_adapter_properties_proxy(void)
589 return (adapter_properties_proxy) ? adapter_properties_proxy :
590 __bt_hal_init_adapter_properties_proxy();
593 GDBusProxy *_bt_hal_get_profile_proxy(void)
595 GDBusConnection *gconn;
599 return profile_gproxy;
601 gconn = _bt_hal_get_system_gconn();
603 ERR("_bt_hal_get_system_gconn failed");
607 profile_gproxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE,
608 NULL, BT_HAL_BLUEZ_NAME,
610 "org.bluez.ProfileManager1",
613 ERR("Unable to create proxy: %s", err->message);
618 return profile_gproxy;
621 static char *__bt_hal_extract_adapter_path(GVariantIter *iter)
623 char *object_path = NULL;
624 GVariantIter *interface_iter;
625 GVariantIter *svc_iter;
626 char *interface_str = NULL;
628 /* Parse the signature: oa{sa{sv}}} */
629 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
632 if (object_path == NULL)
635 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
636 &interface_str, &svc_iter)) {
637 if (g_strcmp0(interface_str, "org.bluez.Adapter1") != 0)
640 DBG("Object Path: %s", object_path);
641 g_free(interface_str);
642 g_variant_iter_free(svc_iter);
643 g_variant_iter_free(interface_iter);
644 return g_strdup(object_path);
650 char *_bt_hal_get_adapter_path(void)
652 GDBusConnection *conn;
653 GDBusProxy *manager_proxy;
654 GVariant *result = NULL;
655 GVariantIter *iter = NULL;
656 char *adapter_path = NULL;
658 conn = _bt_hal_get_system_gconn();
662 manager_proxy = _bt_hal_get_manager_proxy();
663 if (manager_proxy == NULL)
666 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
668 G_DBUS_CALL_FLAGS_NONE,
673 ERR("Can't get managed objects");
677 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
678 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
680 adapter_path = __bt_hal_extract_adapter_path(iter);
681 g_variant_iter_free(iter);
682 g_variant_unref(result);
687 int _bt_hal_is_adapter_powered(gboolean *powered)
690 GError *error = NULL;
695 proxy = _bt_hal_get_adapter_properties_proxy();
697 return BT_STATUS_FAIL;
699 result = g_dbus_proxy_call_sync(proxy,
701 g_variant_new("(ss)", BT_HAL_ADAPTER_INTERFACE,
703 G_DBUS_CALL_FLAGS_NONE,
709 ERR("Failed to get powered status");
711 ERR("Failed to get powered status (Error: %s)", error->message);
712 g_clear_error(&error);
714 return BT_STATUS_FAIL;
717 g_variant_get(result, "(v)", &temp);
718 *powered = g_variant_get_boolean(temp);
719 INFO("powered: %d", *powered);
721 g_variant_unref(result);
722 g_variant_unref(temp);
723 return BT_STATUS_SUCCESS;
726 void _bt_hal_deinit_bluez_proxy(void)
728 if (manager_gproxy) {
729 g_object_unref(manager_gproxy);
730 manager_gproxy = NULL;
733 if (adapter_gproxy) {
734 g_object_unref(adapter_gproxy);
735 adapter_gproxy = NULL;
737 if (adapter_properties_proxy) {
738 g_object_unref(adapter_properties_proxy);
739 adapter_properties_proxy = NULL;
743 void _bt_hal_deinit_proxys(void)
745 _bt_hal_deinit_bluez_proxy();
748 g_object_unref(system_conn);
753 g_object_unref(session_conn);
758 GDBusProxy *_bt_hal_get_hid_agent_proxy(void)
760 GDBusConnection *conn;
764 conn = _bt_hal_get_system_gconn();
766 ERR("_bt_hal_get_system_gconn failed");
770 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
771 BT_HAL_HID_SERVICE_NAME, BT_HAL_HID_AGENT_OBJECT_PATH,
772 BT_HAL_HID_SERVICE_INTERFACE, NULL, &err);
775 ERR("Unable to create proxy: %s", err->message);
784 void _bt_hal_convert_device_path_to_address(const char *device_path,
785 char *device_address)
787 char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
790 if (device_path == NULL || device_address == NULL)
793 dev_addr = strstr(device_path, "dev_");
794 if (dev_addr != NULL) {
797 g_strlcpy(address, dev_addr, sizeof(address));
799 while ((pos = strchr(address, '_')) != NULL)
802 g_strlcpy(device_address, address, BT_HAL_ADDRESS_STRING_SIZE);
806 gboolean _bt_hal_uuid_is_standard(bt_uuid_t *p_uuid)
808 uint32_t uuid0, uuid4;
809 uint16_t uuid1, uuid2, uuid3, uuid5;
810 const char *uuid_name;
811 const char *uuid_name1;
813 memcpy(&uuid0, &(p_uuid->uu[0]), 4);
814 memcpy(&uuid1, &(p_uuid->uu[4]), 2);
815 memcpy(&uuid2, &(p_uuid->uu[6]), 2);
816 memcpy(&uuid3, &(p_uuid->uu[8]), 2);
817 memcpy(&uuid4, &(p_uuid->uu[10]), 4);
818 memcpy(&uuid5, &(p_uuid->uu[14]), 2);
820 uuid_name = _bt_hal_dump_uuid_name(ntohl(uuid0));
821 uuid_name1 = _bt_hal_dump_uuid_name((ntohl(uuid4) >> 16));
823 DBG("UUID Name [%s]", uuid_name);
824 DBG("UUID Name Shifted [%s]", uuid_name1);
826 if (!g_strcmp0(uuid_name, "--"))
833 void _bt_hal_convert_uuid_string_to_type(unsigned char *uuid,
834 const char *device_uuid)
836 uint32_t uuid0, uuid4;
837 uint16_t uuid1, uuid2, uuid3, uuid5;
839 sscanf(device_uuid, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
840 &uuid0, &uuid1, &uuid2, &uuid3, &uuid4, &uuid5);
842 uuid0 = htonl(uuid0);
843 uuid1 = htons(uuid1);
844 uuid2 = htons(uuid2);
845 uuid3 = htons(uuid3);
846 uuid4 = htonl(uuid4);
847 uuid5 = htons(uuid5);
849 memcpy(&(uuid[0]), &uuid0, 4);
850 memcpy(&(uuid[4]), &uuid1, 2);
851 memcpy(&(uuid[6]), &uuid2, 2);
852 memcpy(&(uuid[8]), &uuid3, 2);
853 memcpy(&(uuid[10]), &uuid4, 4);
854 memcpy(&(uuid[14]), &uuid5, 2);
857 void _bt_hal_convert_uuid_type_to_string(char *str, const unsigned char *uuid)
869 snprintf(str, BT_HAL_UUID_STRING_LEN,
870 "%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",
871 uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
872 uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
875 void _bt_hal_convert_addr_string_to_type(unsigned char *addr,
881 if (address == NULL || addr == NULL)
884 for (i = 0; i < BT_HAL_ADDRESS_LENGTH_MAX; i++) {
885 addr[i] = strtol(address, &ptr, 16);
887 if (ptr[0] != '\0') {
896 void _bt_hal_convert_addr_type_to_string(char *address,
897 const unsigned char *addr)
899 if (address == NULL || addr == NULL)
902 snprintf(address, BT_HAL_ADDRESS_STRING_SIZE,
903 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
904 addr[0], addr[1], addr[2],
905 addr[3], addr[4], addr[5]);
908 void _bt_hal_print_device_address_t(const bt_hal_device_address_t *addr)
910 DBG("%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", addr->addr[0], addr->addr[1], addr->addr[2],
911 addr->addr[3], addr->addr[4], addr->addr[5]);
914 void _bt_hal_divide_device_class(bt_hal_device_class_t *device_class,
917 if (device_class == NULL)
920 device_class->major_class = (unsigned short)(cod & 0x00001F00) >> 8;
921 device_class->minor_class = (unsigned short)((cod & 0x000000FC));
922 device_class->service_class = (unsigned long)((cod & 0x00FF0000));
924 if (cod & 0x002000) {
925 device_class->service_class |=
926 BT_HAL_DEVICE_SERVICE_CLASS_LIMITED_DISCOVERABLE_MODE;
930 int _bt_hal_copy_utf8_string(char *dest, const char *src, unsigned int length)
937 if (dest == NULL || src == NULL)
938 return BT_HAL_ERROR_INVALID_PARAM;
940 DBG("+src : %s", src);
941 DBG("+dest : %s", dest);
944 while (*p != '\0' && i < length) {
945 next = g_utf8_next_char(p);
948 while (count > 0 && ((i + count) < length)) {
955 return BT_HAL_ERROR_NONE;
958 gboolean _bt_hal_utf8_validate(char *name)
961 glong items_written = 0;
963 if (FALSE == g_utf8_validate(name, -1, NULL))
966 u16 = g_utf8_to_utf16(name, -1, NULL, &items_written, NULL);
972 if (items_written != g_utf8_strlen(name, -1))
978 int _bt_hal_set_socket_non_blocking(int socket_fd)
980 /* Set Nonblocking */
983 arg = fcntl(socket_fd, F_GETFL);
988 if (arg & O_NONBLOCK)
989 ERR("Already Non-blocking \n");
993 if (fcntl(socket_fd, F_SETFL, arg) < 0)
996 return BT_HAL_ERROR_NONE;
999 int _bt_hal_set_non_blocking_tty(int sk)
1001 struct termios ti = {0,};
1004 err = _bt_hal_set_socket_non_blocking(sk);
1007 ERR("Error in set non blocking!\n");
1011 tcflush(sk, TCIOFLUSH);
1013 /* Switch tty to RAW mode */
1015 tcsetattr(sk, TCSANOW, &ti);
1017 return BT_HAL_ERROR_NONE;
1020 static char *__bt_hal_extract_device_path(GVariantIter *iter, char *address)
1022 char *object_path = NULL;
1023 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
1025 /* Parse the signature: oa{sa{sv}}} */
1026 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, NULL)) {
1027 if (object_path == NULL)
1029 _bt_hal_convert_device_path_to_address(object_path, device_address);
1030 if (g_strcmp0(address, device_address) == 0)
1031 return g_strdup(object_path);
1036 char *_bt_hal_get_device_object_path(char *address)
1038 char *object_path = NULL;
1039 GDBusConnection *conn;
1040 GDBusProxy *manager_proxy;
1041 GVariant *result = NULL;
1042 GVariantIter *iter = NULL;
1044 conn = _bt_hal_get_system_gconn();
1048 manager_proxy = _bt_hal_get_manager_proxy();
1049 if (manager_proxy == NULL)
1052 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
1054 G_DBUS_CALL_FLAGS_NONE,
1059 ERR("Can't get managed objects");
1063 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
1064 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
1065 object_path = __bt_hal_extract_device_path(iter, address);
1066 g_variant_iter_free(iter);
1067 g_variant_unref(result);
1071 GVariant *_bt_hal_get_managed_objects(void)
1073 GDBusConnection *conn;
1074 GDBusProxy *manager_proxy;
1075 GVariant *result = NULL;
1076 GError *error = NULL;
1078 conn = _bt_hal_get_system_gconn();
1082 manager_proxy = _bt_hal_get_manager_proxy();
1083 if (manager_proxy == NULL)
1086 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
1088 G_DBUS_CALL_FLAGS_NONE,
1093 ERR("Can't get managed objects");
1098 ERR("Fail to get ManagedObjects (Error: %s)", error->message);
1099 g_clear_error(&error);
1106 char *_bt_hal_convert_error_to_string(int error)
1109 case BT_HAL_ERROR_CANCEL:
1111 case BT_HAL_ERROR_INVALID_PARAM:
1112 return "INVALID_PARAMETER";
1113 case BT_HAL_ERROR_INVALID_DATA:
1114 return "INVALID DATA";
1115 case BT_HAL_ERROR_MEMORY_ALLOCATION:
1116 case BT_HAL_ERROR_OUT_OF_MEMORY:
1117 return "OUT_OF_MEMORY";
1118 case BT_HAL_ERROR_TIMEOUT:
1120 case BT_HAL_ERROR_NO_RESOURCES:
1121 return "NO_RESOURCES";
1122 case BT_HAL_ERROR_INTERNAL:
1124 case BT_HAL_ERROR_NOT_SUPPORT:
1125 return "NOT_SUPPORT";
1126 case BT_HAL_ERROR_DEVICE_NOT_ENABLED:
1127 return "NOT_ENABLED";
1128 case BT_HAL_ERROR_DEVICE_ALREADY_ENABLED:
1129 return "ALREADY_ENABLED";
1130 case BT_HAL_ERROR_DEVICE_BUSY:
1131 return "DEVICE_BUSY";
1132 case BT_HAL_ERROR_ACCESS_DENIED:
1133 return "ACCESS_DENIED";
1134 case BT_HAL_ERROR_MAX_CLIENT:
1135 return "MAX_CLIENT";
1136 case BT_HAL_ERROR_NOT_FOUND:
1138 case BT_HAL_ERROR_SERVICE_SEARCH_ERROR:
1139 return "SERVICE_SEARCH_ERROR";
1140 case BT_HAL_ERROR_PARING_FAILED:
1141 return "PARING_FAILED";
1142 case BT_HAL_ERROR_NOT_PAIRED:
1143 return "NOT_PAIRED";
1144 case BT_HAL_ERROR_SERVICE_NOT_FOUND:
1145 return "SERVICE_NOT_FOUND";
1146 case BT_HAL_ERROR_NOT_CONNECTED:
1147 return "NOT_CONNECTED";
1148 case BT_HAL_ERROR_ALREADY_CONNECT:
1149 return "ALREADY_CONNECT";
1150 case BT_HAL_ERROR_CONNECTION_BUSY:
1151 return "CONNECTION_BUSY";
1152 case BT_HAL_ERROR_CONNECTION_ERROR:
1153 return "CONNECTION_ERROR";
1154 case BT_HAL_ERROR_MAX_CONNECTION:
1155 return "MAX_CONNECTION";
1156 case BT_HAL_ERROR_NOT_IN_OPERATION:
1157 return "NOT_IN_OPERATION";
1158 case BT_HAL_ERROR_CANCEL_BY_USER:
1159 return "CANCEL_BY_USER";
1160 case BT_HAL_ERROR_REGISTRATION_FAILED:
1161 return "REGISTRATION_FAILED";
1162 case BT_HAL_ERROR_IN_PROGRESS:
1163 return "IN_PROGRESS";
1164 case BT_HAL_ERROR_AUTHENTICATION_FAILED:
1165 return "AUTHENTICATION_FAILED";
1166 case BT_HAL_ERROR_HOST_DOWN:
1168 case BT_HAL_ERROR_END_OF_DEVICE_LIST:
1169 return "END_OF_DEVICE_LIST";
1170 case BT_HAL_ERROR_AGENT_ALREADY_EXIST:
1171 return "AGENT_ALREADY_EXIST";
1172 case BT_HAL_ERROR_AGENT_DOES_NOT_EXIST:
1173 return "AGENT_DOES_NOT_EXIST";
1174 case BT_HAL_ERROR_ALREADY_INITIALIZED:
1175 return "ALREADY_INITIALIZED";
1176 case BT_HAL_ERROR_PERMISSION_DEINED:
1177 return "PERMISSION_DEINED";
1178 case BT_HAL_ERROR_ALREADY_DEACTIVATED:
1179 return "ALREADY_DEACTIVATED";
1180 case BT_HAL_ERROR_NOT_INITIALIZED:
1181 return "NOT_INITIALIZED";
1187 char * _bt_hal_convert_disc_reason_to_string(int reason)
1193 return "Connection terminated by local host";
1195 return "Remote user terminated connection";
1202 int _bt_hal_convert_disc_reason_to_status(int reason)
1206 return BT_STATUS_CONN_TOUT; //"Link loss"
1208 return BT_STATUS_CONN_TERM_LOCAL_HOST; //"Connection terminated by local host";
1210 return BT_STATUS_CONN_TERM_RMT_HOST; //"Connection terminated by local host";
1213 return BT_STATUS_FAIL;
1217 void _bt_hal_logging_connection(gboolean connect, int addr_type)
1219 static int le_conn = 0;
1220 static int le_disc = 0;
1221 static int edr_conn = 0;
1222 static int edr_disc = 0;
1236 INFO("[PM] Number of LE conn: %d disc: %d, Number of BR/EDR conn: %d disc: %d",
1237 le_conn, le_disc, edr_conn, edr_disc);
1240 void _bt_hal_swap_byte_ordering(char *data, int data_len)
1247 /* Swap to opposite endian */
1248 for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
1255 int _bt_hal_byte_arr_cmp(const char *data1, const char *data2, int data_len)
1259 if (data1 == NULL || data2 == NULL)
1261 for (i = 0; i < data_len; i++) {
1262 if (data1[i] != data2[i])
1263 return data1[i] - data2[i];
1267 int _bt_hal_byte_arr_cmp_with_mask(const char *data1, const char *data2,
1268 const char *mask, int data_len)
1273 if (data1 == NULL || data2 == NULL || mask == NULL)
1276 for (i = 0; i < data_len; i++) {
1277 a = data1[i] & mask[i];
1278 b = data2[i] & mask[i];
1280 return (int)(a - b);
1285 int _bt_hal_connect_profile(char *address, char *uuid,
1286 void *cb, gpointer func_data)
1290 GDBusConnection *conn;
1291 GDBusProxy *adapter_proxy;
1292 GError *error = NULL;
1294 conn = _bt_hal_get_system_gconn();
1296 return BT_HAL_ERROR_INTERNAL;
1298 object_path = _bt_hal_get_device_object_path(address);
1299 if (object_path == NULL) {
1300 ERR("No searched device");
1302 adapter_proxy = _bt_hal_get_adapter_proxy();
1303 if (adapter_proxy == NULL)
1304 return BT_HAL_ERROR_INTERNAL;
1306 g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1307 g_variant_new("(s)", address),
1308 G_DBUS_CALL_FLAGS_NONE,
1313 if (error != NULL) {
1314 ERR("CreateDevice Fail: %s", error->message);
1315 g_error_free(error);
1318 object_path = _bt_hal_get_device_object_path(address);
1320 if (object_path == NULL)
1321 return BT_HAL_ERROR_INTERNAL;
1323 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1324 NULL, BT_HAL_BLUEZ_NAME,
1325 object_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1326 g_free(object_path);
1328 return BT_HAL_ERROR_INTERNAL;
1331 g_dbus_proxy_call(proxy, "ConnectProfile",
1332 g_variant_new("(s)", uuid),
1333 G_DBUS_CALL_FLAGS_NONE,
1334 BT_HAL_MAX_DBUS_TIMEOUT,
1336 (GAsyncReadyCallback)cb,
1339 return BT_HAL_ERROR_NONE;
1342 int _bt_hal_disconnect_profile(char *address, char *uuid,
1343 void *cb, gpointer func_data)
1347 GDBusConnection *conn;
1349 conn = _bt_hal_get_system_gconn();
1351 return BT_HAL_ERROR_INTERNAL;
1353 object_path = _bt_hal_get_device_object_path(address);
1354 if (object_path == NULL)
1355 return BT_HAL_ERROR_INTERNAL;
1357 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1358 NULL, BT_HAL_BLUEZ_NAME,
1359 object_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1360 g_free(object_path);
1362 return BT_HAL_ERROR_INTERNAL;
1364 g_dbus_proxy_call(proxy, "DisconnectProfile",
1365 g_variant_new("(s)", uuid),
1366 G_DBUS_CALL_FLAGS_NONE,
1367 BT_HAL_MAX_DBUS_TIMEOUT,
1369 (GAsyncReadyCallback)cb,
1372 return BT_HAL_ERROR_NONE;
1375 int _bt_hal_register_profile(bt_hal_register_profile_info_t *info, gboolean use_default_rfcomm)
1377 GVariantBuilder *option_builder;
1381 int result = BT_STATUS_SUCCESS;
1383 proxy = _bt_hal_get_profile_proxy();
1384 if (proxy == NULL) {
1385 ERR("Getting profile proxy failed");
1386 return BT_STATUS_FAIL;
1389 option_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1390 if (info->authentication)
1391 g_variant_builder_add(option_builder, "{sv}",
1392 "RequireAuthentication",
1393 g_variant_new_boolean(TRUE));
1394 if (info->authorization)
1395 g_variant_builder_add(option_builder, "{sv}",
1396 "RequireAuthorization",
1397 g_variant_new_boolean(TRUE));
1399 g_variant_builder_add(option_builder, "{sv}",
1401 g_variant_new_string(info->role));
1404 * Setting RFCOMM channel to default value 0; would allow bluez to assign
1405 * RFCOMM channels based on the availability when two services want to use
1406 * the RFCOMM along with SPP. Hence bluez makes sure that no two services
1407 * use the same SPP RFCOMM channel.
1409 if (use_default_rfcomm)
1410 g_variant_builder_add(option_builder, "{sv}",
1412 g_variant_new_uint16(RFCOMM_DEFAULT_PROFILE_CHANNEL));
1414 g_variant_builder_add(option_builder, "{sv}",
1416 g_variant_new_string(info->service));
1418 ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile",
1419 g_variant_new("(osa{sv})", info->obj_path,
1422 G_DBUS_CALL_FLAGS_NONE, -1,
1425 ERR("RegisterProfile failed: %s", err->message);
1427 if (g_strrstr(err->message, BT_HAL_ACCESS_DENIED_MSG))
1428 result = BT_STATUS_AUTH_REJECTED;
1430 result = BT_STATUS_FAIL;
1432 g_clear_error(&err);
1435 g_variant_builder_unref(option_builder);
1438 g_variant_unref(ret);
1443 void _bt_hal_unregister_profile(char *path)
1449 proxy = _bt_hal_get_profile_proxy();
1450 if (proxy == NULL) {
1451 ERR("Getting profile proxy failed");
1455 ret = g_dbus_proxy_call_sync(proxy, "UnregisterProfile",
1456 g_variant_new("(o)", path),
1457 G_DBUS_CALL_FLAGS_NONE, -1,
1460 ERR("UnregisterProfile failed : %s", err->message);
1461 g_clear_error(&err);
1465 g_variant_unref(ret);
1470 static void __hal_new_connection_method(GDBusConnection *connection,
1471 const gchar *sender,
1472 const gchar *object_path,
1473 const gchar *interface_name,
1474 const gchar *method_name,
1475 GVariant *parameters,
1476 GDBusMethodInvocation *invocation,
1479 DBG("method %s", method_name);
1480 if (g_strcmp0(method_name, "NewConnection") == 0) {
1483 GUnixFDList *fd_list;
1485 GVariantBuilder *properties;
1487 bt_bdaddr_t remote_addr1;
1488 char addr[BT_HAL_ADDRESS_STRING_SIZE];
1489 bt_hal_new_connection_cb cb = user_data;
1491 g_variant_get(parameters, "(oha{sv})", &obj_path, &index,
1494 msg = g_dbus_method_invocation_get_message(invocation);
1495 fd_list = g_dbus_message_get_unix_fd_list(msg);
1496 if (fd_list == NULL) {
1497 GQuark quark = g_quark_from_string("rfcomm-app");
1498 GError *err = g_error_new(quark, 0, "No fd in message");
1499 g_dbus_method_invocation_return_gerror(invocation, err);
1505 fd = g_unix_fd_list_get(fd_list, index, NULL);
1507 ERR("Invalid fd return");
1508 GQuark quark = g_quark_from_string("rfcomm-app");
1509 GError *err = g_error_new(quark, 0, "Invalid FD return");
1510 g_dbus_method_invocation_return_gerror(invocation, err);
1514 INFO("Object Path %s", obj_path);
1516 _bt_hal_convert_device_path_to_address(obj_path, addr);
1517 _bt_hal_convert_addr_string_to_type(remote_addr1.address, (const char *)addr);
1518 INFO("fd: %d, address %s", fd, addr);
1520 g_dbus_method_invocation_return_value(invocation, NULL);
1523 cb(object_path, fd, &remote_addr1);
1526 } else if (g_strcmp0(method_name, "RequestDisconnection") == 0) {
1527 g_dbus_method_invocation_return_value(invocation, NULL);
1531 static GDBusNodeInfo *_bt_hal_get_gdbus_node(const gchar *xml_data)
1534 char *name = g_strdup_printf("org.bt.frwk.p%d", getpid());
1536 bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1538 G_BUS_NAME_OWNER_FLAGS_NONE,
1544 DBG("Got bus id %d", bus_id);
1548 return g_dbus_node_info_new_for_xml(xml_data, NULL);
1551 static const GDBusInterfaceVTable method_table = {
1552 __hal_new_connection_method,
1557 int _bt_hal_register_new_gdbus_object(const char *path, bt_hal_new_connection_cb cb)
1559 GDBusConnection *gconn;
1561 GError *error = NULL;
1563 gconn = _bt_hal_get_system_gconn();
1567 if (new_conn_node == NULL)
1568 new_conn_node = _bt_hal_get_gdbus_node(rfcomm_agent_xml);
1570 if (new_conn_node == NULL)
1573 id = g_dbus_connection_register_object(gconn, path,
1574 new_conn_node->interfaces[0],
1578 ERR("Failed to register: %s", error->message);
1579 g_error_free(error);
1583 DBG("NEW CONNECTION ID %d", id);
1588 void _bt_hal_unregister_gdbus_object(int object_id)
1590 GDBusConnection *gconn;
1592 gconn = _bt_hal_get_system_gconn();
1596 g_dbus_connection_unregister_object(gconn, object_id);
1599 int _bt_hal_discover_services(char *address, char *uuid, void *cb, gpointer func_data)
1603 GDBusProxy *adapter_proxy;
1605 GDBusConnection *conn;
1607 conn = _bt_hal_get_system_gconn();
1609 ERR("conn == NULL, return");
1610 return BT_STATUS_FAIL;
1613 object_path = _bt_hal_get_device_object_path(address);
1614 if (object_path == NULL) {
1615 GVariant *ret = NULL;
1617 INFO("No searched device");
1618 adapter_proxy = _bt_hal_get_adapter_proxy();
1619 if (adapter_proxy == NULL) {
1620 ERR("adapter_proxy == NULL, return");
1621 return BT_STATUS_FAIL;
1624 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1625 g_variant_new("(s)", address),
1626 G_DBUS_CALL_FLAGS_NONE,
1627 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1630 ERR("CreateDevice Failed: %s", err->message);
1631 g_clear_error(&err);
1635 g_variant_unref(ret);
1637 g_object_unref(adapter_proxy);
1638 object_path = _bt_hal_get_device_object_path(address);
1639 if (object_path == NULL) {
1640 ERR("object_path == NULL, return");
1641 return BT_STATUS_FAIL;
1645 proxy = g_dbus_proxy_new_sync(conn,
1646 G_DBUS_PROXY_FLAGS_NONE, NULL,
1647 BT_HAL_BLUEZ_NAME, object_path,
1648 BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1649 g_free(object_path);
1650 if (proxy == NULL) {
1651 ERR("Error while getting proxy");
1652 return BT_STATUS_FAIL;
1655 g_dbus_proxy_call(proxy, "DiscoverServices",
1656 g_variant_new("(s)", uuid),
1657 G_DBUS_CALL_FLAGS_NONE,
1658 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1659 (GAsyncReadyCallback)cb,
1662 return BT_STATUS_SUCCESS;
1665 int _bt_hal_cancel_discovers(char *address)
1669 GDBusProxy *adapter_proxy;
1671 GDBusConnection *conn;
1673 conn = _bt_hal_get_system_gconn();
1675 return BT_STATUS_FAIL;
1677 object_path = _bt_hal_get_device_object_path(address);
1678 if (object_path == NULL) {
1679 GVariant *ret = NULL;
1680 INFO("No searched device");
1681 adapter_proxy = _bt_hal_get_adapter_proxy();
1682 if (adapter_proxy == NULL) {
1683 ERR("adapter_proxy == NULL, return");
1684 return BT_STATUS_FAIL;
1687 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1688 g_variant_new("(s)", address),
1689 G_DBUS_CALL_FLAGS_NONE,
1690 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1693 ERR("CreateDevice Failed: %s", err->message);
1694 g_clear_error(&err);
1698 g_variant_unref(ret);
1700 g_object_unref(adapter_proxy);
1702 object_path = _bt_hal_get_device_object_path(address);
1703 if (object_path == NULL)
1704 return BT_STATUS_FAIL;
1707 proxy = g_dbus_proxy_new_sync(conn,
1708 G_DBUS_PROXY_FLAGS_NONE, NULL,
1709 BT_HAL_BLUEZ_NAME, object_path,
1710 BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1711 g_free(object_path);
1712 g_dbus_proxy_call_sync(proxy, "CancelDiscovery",
1714 G_DBUS_CALL_FLAGS_NONE,
1715 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1718 ERR("DBus Error message: [%s]", err->message);
1719 g_clear_error(&err);
1720 return BT_STATUS_FAIL;
1724 g_object_unref(proxy);
1726 return BT_STATUS_SUCCESS;
1729 int _bt_hal_discover_service_uuids(char *address, char *remote_uuid)
1733 GDBusConnection *gconn;
1735 char **uuid_value = NULL;
1738 GVariant *value = NULL;
1739 GVariant *ret = NULL;
1740 int result = BT_STATUS_FAIL;
1742 if (remote_uuid == NULL) {
1743 ERR("remote_uuid == NULL, return");
1744 return BT_STATUS_FAIL;
1747 gconn = _bt_hal_get_system_gconn();
1748 if (gconn == NULL) {
1749 ERR("gconn == NULL, return");
1750 return BT_STATUS_FAIL;
1753 object_path = _bt_hal_get_device_object_path(address);
1754 if (object_path == NULL) {
1755 ERR("object_path == NULL, return");
1756 return BT_STATUS_FAIL;
1759 proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE, NULL,
1760 BT_HAL_BLUEZ_NAME, object_path, BT_HAL_PROPERTIES_INTERFACE, NULL,
1762 if (proxy == NULL) {
1763 g_free(object_path);
1764 ERR("proxy == NULL, return");
1765 return BT_STATUS_FAIL;
1769 ERR("DBus Error: [%s]", err->message);
1770 g_clear_error(&err);
1773 ret = g_dbus_proxy_call_sync(proxy, "GetAll",
1774 g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
1775 G_DBUS_CALL_FLAGS_NONE,
1776 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1779 result = BT_STATUS_FAIL;
1780 ERR("DBus Error : %s", err->message);
1781 g_clear_error(&err);
1786 ERR("g_dbus_proxy_call_sync function return NULL");
1787 result = BT_STATUS_FAIL;
1791 g_variant_get(ret, "(@a{sv})", &value);
1792 g_variant_unref(ret);
1794 GVariant *temp_value = g_variant_lookup_value(value, "UUIDs",
1795 G_VARIANT_TYPE_STRING_ARRAY);
1798 size = g_variant_get_size(temp_value);
1801 uuid_value = (char **)g_variant_get_strv(temp_value, &size);
1802 DBG("Size items %zu", size);
1806 g_variant_unref(temp_value);
1809 for (i = 0; uuid_value[i] != NULL; i++) {
1810 DBG("Remote uuids %s, searched uuid: %s",
1811 uuid_value[i], remote_uuid);
1812 if (strcasecmp(uuid_value[i], remote_uuid) == 0) {
1813 result = BT_STATUS_SUCCESS;
1822 g_object_unref(proxy);
1824 g_variant_unref(value);
1831 int bt_hal_gatt_convert_prop2string(
1832 bt_hal_gatt_characteristic_property_t properties,
1833 char *char_properties[])
1837 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_BROADCAST) {
1838 char_properties[flag_count] = g_strdup("broadcast");
1841 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_READ) {
1842 char_properties[flag_count] = g_strdup("read");
1845 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE) {
1846 char_properties[flag_count] = g_strdup("write-without-response");
1849 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE) {
1850 char_properties[flag_count] = g_strdup("write");
1853 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY) {
1854 char_properties[flag_count] = g_strdup("notify");
1857 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE) {
1858 char_properties[flag_count] = g_strdup("indicate");
1861 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE) {
1862 char_properties[flag_count] = g_strdup("authenticated-signed-writes");
1865 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE) {
1866 char_properties[flag_count] = g_strdup("reliable-write");
1869 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES) {
1870 char_properties[flag_count] = g_strdup("writable-auxiliaries");
1873 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ) {
1874 char_properties[flag_count] = g_strdup("encrypt-read");
1877 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE) {
1878 char_properties[flag_count] = g_strdup("encrypt-write");
1881 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ) {
1882 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
1885 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE) {
1886 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
1890 if (flag_count == 0) {
1891 char_properties[flag_count] = g_strdup("read");
1898 int bt_hal_gatt_convert_perm2string(
1899 bt_hal_gatt_permission_t properties,
1900 char *char_properties[])
1904 if (properties & BT_HAL_GATT_PERMISSION_READ) {
1905 char_properties[flag_count] = g_strdup("read");
1908 if (properties & BT_HAL_GATT_PERMISSION_WRITE) {
1909 char_properties[flag_count] = g_strdup("write");
1912 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_READ) {
1913 char_properties[flag_count] = g_strdup("encrypt-read");
1916 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_WRITE) {
1917 char_properties[flag_count] = g_strdup("encrypt-write");
1920 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_READ) {
1921 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
1924 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_WRITE) {
1925 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
1929 if (flag_count == 0) {
1930 char_properties[flag_count] = g_strdup("read");
1937 gboolean _bt_hal_is_service_enabled(const char *uuid)
1940 GError *error = NULL;
1943 GVariantIter *iter = NULL;
1945 gboolean ret = FALSE;
1947 proxy = _bt_hal_get_adapter_properties_proxy();
1949 DBG("_bt_hal_dbus_get_local_name: Adapter Properties proxy get failed!!!");
1953 result = g_dbus_proxy_call_sync(proxy,
1954 "Get", g_variant_new("(ss)",
1955 BT_HAL_ADAPTER_INTERFACE, "UUIDs"),
1956 G_DBUS_CALL_FLAGS_NONE, -1,
1959 if (error != NULL) {
1960 ERR("Failed to get UUIDs (Error: %s)", error->message);
1961 g_clear_error(&error);
1963 ERR("Failed to get UUIDs");
1967 g_variant_get(result, "(v)", &temp);
1968 g_variant_get(temp, "as", &iter);
1970 ERR("Failed to get UUIDs");
1971 g_variant_unref(result);
1975 while (g_variant_iter_loop(iter, "&s", &uuid_str)) {
1976 DBG("UUID string [%s]\n", uuid_str);
1977 if (!strncasecmp(uuid, uuid_str, strlen(uuid))) {
1983 g_variant_iter_free(iter);
1984 g_variant_unref(result);
1985 g_variant_unref(temp);