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)
147 if (system_conn == NULL) {
148 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
149 if (system_conn == NULL)
153 proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
154 NULL, BT_HAL_BLUEZ_NAME,
155 BT_HAL_MANAGER_PATH, BT_HAL_MANAGER_INTERFACE, NULL, NULL);
160 manager_gproxy = proxy;
165 static GDBusProxy *__bt_hal_init_adapter_proxy(void)
167 GDBusProxy *manager_proxy;
169 char *adapter_path = NULL;
171 if (system_conn == NULL) {
172 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
173 if (system_conn == NULL)
177 manager_proxy = _bt_hal_get_manager_proxy();
178 if (manager_proxy == NULL)
181 adapter_path = _bt_hal_get_adapter_path();
182 if (adapter_path == NULL)
185 proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
186 NULL, BT_HAL_BLUEZ_NAME,
187 adapter_path, BT_HAL_ADAPTER_INTERFACE, NULL, NULL);
189 g_free(adapter_path);
194 adapter_gproxy = proxy;
199 static GDBusProxy *__bt_hal_init_adapter_properties_proxy(void)
201 GDBusProxy *manager_proxy;
203 char *adapter_path = NULL;
205 if (system_conn == NULL) {
206 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
207 if (system_conn == NULL)
211 manager_proxy = _bt_hal_get_manager_proxy();
212 if (manager_proxy == NULL)
215 adapter_path = _bt_hal_get_adapter_path();
216 if (adapter_path == NULL)
219 proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
220 NULL, BT_HAL_BLUEZ_NAME,
221 adapter_path, BT_HAL_PROPERTIES_INTERFACE, NULL, NULL);
223 g_free(adapter_path);
228 adapter_properties_proxy = proxy;
233 void _bt_hal_set_control_device_path(const char *path)
240 DBG("control_path = %s", path);
242 for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
243 if (proxy_array[i].avrcp_control_path == NULL) {
244 proxy_array[i].avrcp_control_path = g_strdup(path);
245 DBG("PATH %s formed index %d", proxy_array[i].avrcp_control_path, i);
251 void _bt_hal_remove_control_device_path(const char *path)
258 for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
259 if (g_strcmp0(proxy_array[i].avrcp_control_path, path) == 0) {
260 DBG("Clear AVRCP proxy[%d]", i);
261 g_free(proxy_array[i].avrcp_control_path);
262 g_object_unref(proxy_array[i].avrcp_ctrl_proxy);
264 proxy_array[i].avrcp_control_path = NULL;
265 proxy_array[i].avrcp_ctrl_proxy = NULL;
266 memset(proxy_array[i].bd_addr.address, 0, 6);
272 static char *__bt_hal_extract_control_device_path(GVariantIter *iter, char *address)
274 char *object_path = NULL;
275 char *interface_str = NULL;
276 GVariantIter *interface_iter;
277 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
279 /* Parse the signature: oa{sa{sv}}} */
280 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
281 if (object_path == NULL)
284 while(g_variant_iter_loop(interface_iter, "{&sa{sv}}", &interface_str, NULL)) {
285 if (g_strcmp0(interface_str, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
286 _bt_hal_convert_device_path_to_address(object_path, device_address);
287 if (g_strcmp0(address, device_address) == 0) {
288 DBG("Object Path: %s", object_path);
289 g_variant_iter_free(interface_iter);
290 return g_strdup(object_path);
298 static char *__bt_hal_extract_transport_device_path(GVariantIter *iter, char *address)
300 char *object_path = NULL;
301 char *interface_str = NULL;
302 GVariantIter *interface_iter;
303 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
305 /* Parse the signature: oa{sa{sv}}} */
306 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
307 if (object_path == NULL)
310 while(g_variant_iter_loop(interface_iter, "{&sa{sv}}", &interface_str, NULL)) {
311 if (g_strcmp0(interface_str, BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
312 _bt_hal_convert_device_path_to_address(object_path, device_address);
313 if (g_strcmp0(address, device_address) == 0) {
314 DBG("Object Path: %s", object_path);
315 g_variant_iter_free(interface_iter);
316 return g_strdup(object_path);
324 static char *__bt_hal_get_control_device_object_path(char *address)
326 char *object_path = NULL;
327 GDBusConnection *conn;
328 GDBusProxy *manager_proxy;
329 GVariant *result = NULL;
330 GVariantIter *iter = NULL;
332 conn = _bt_hal_get_system_gconn();
336 manager_proxy = _bt_hal_get_manager_proxy();
337 if (manager_proxy == NULL)
340 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
342 G_DBUS_CALL_FLAGS_NONE,
347 ERR("Can't get managed objects");
351 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
352 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
353 object_path = __bt_hal_extract_control_device_path(iter, address);
354 g_variant_iter_free(iter);
355 g_variant_unref(result);
359 static char *__bt_hal_get_transport_device_object_path(char *address)
361 char *object_path = NULL;
362 GDBusConnection *conn;
363 GDBusProxy *manager_proxy;
364 GVariant *result = NULL;
365 GVariantIter *iter = NULL;
367 conn = _bt_hal_get_system_gconn();
371 manager_proxy = _bt_hal_get_manager_proxy();
372 if (manager_proxy == NULL)
375 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
377 G_DBUS_CALL_FLAGS_NONE,
382 ERR("Can't get managed objects");
386 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
387 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
388 object_path = __bt_hal_extract_transport_device_path(iter, address);
389 g_variant_iter_free(iter);
390 g_variant_unref(result);
394 char *_bt_hal_get_control_device_path(bt_bdaddr_t *bd_addr)
397 char connected_address[BT_HAL_ADDRESS_STRING_SIZE];
399 if (avrcp_control_path != NULL)
400 return avrcp_control_path;
402 _bt_hal_convert_addr_type_to_string(connected_address, bd_addr->address);
404 control_path = __bt_hal_get_control_device_object_path(connected_address);
405 if (control_path == NULL)
408 avrcp_control_path = control_path;
409 DBG("control_path = %s", control_path);
413 char *_bt_hal_get_transport_device_path(bt_bdaddr_t *bd_addr)
415 char *transport_path;
416 char connected_address[BT_HAL_ADDRESS_STRING_SIZE];
418 if (avrcp_transport_path != NULL)
419 return avrcp_transport_path;
421 _bt_hal_convert_addr_type_to_string(connected_address, bd_addr->address);
423 transport_path = __bt_hal_get_transport_device_object_path(connected_address);
424 if (transport_path == NULL)
427 avrcp_transport_path = transport_path;
428 DBG("transport_path = %s", transport_path);
429 return transport_path;
432 static GDBusProxy *__bt_hal_init_avrcp_ctrl_proxy(bt_bdaddr_t *bd_addr)
434 GDBusProxy *manager_proxy;
436 GDBusConnection *gconn = NULL;
439 gconn = _bt_hal_get_system_gconn();
443 manager_proxy = _bt_hal_get_manager_proxy();
444 if (manager_proxy == NULL)
447 for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
448 if (proxy_array[i].avrcp_ctrl_proxy == NULL) {
449 memcpy(proxy_array[i].bd_addr.address, bd_addr->address, 6);
450 DBG("PATH %s formed index %d ", proxy_array[i].avrcp_control_path, i);
455 if (i == BT_AUDIO_SOURCE_MAX) {
456 ERR("NO free arr proxy space found");
460 proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE,
461 NULL, BT_HAL_BLUEZ_NAME,
462 proxy_array[i].avrcp_control_path, BT_HAL_PLAYER_CONTROL_INTERFACE, NULL, NULL);
467 avrcp_ctrl_proxy = proxy;
468 proxy_array[i].avrcp_ctrl_proxy = proxy;
473 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;
483 return __bt_hal_init_manager_proxy();
486 GDBusProxy *_bt_hal_get_adapter_proxy(void)
488 if (adapter_gproxy) {
489 const char *path = g_dbus_proxy_get_object_path(adapter_gproxy);
491 ERR("Already proxy released hence creating new proxy");
492 return __bt_hal_init_adapter_proxy();
495 return adapter_gproxy;
497 return __bt_hal_init_adapter_proxy();
501 GDBusProxy *_bt_hal_get_avrcp_ctrl_proxy(bt_bdaddr_t *bd_addr)
505 for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
506 if (proxy_array[i].avrcp_ctrl_proxy
507 && (!memcmp(proxy_array[i].bd_addr.address, bd_addr->address, 6))) {
508 const gchar *path = g_dbus_proxy_get_object_path(proxy_array[i].avrcp_ctrl_proxy);
511 proxy_array[i].avrcp_ctrl_proxy = NULL;
512 ERR("Already proxy released hence creating new proxy");
513 return __bt_hal_init_avrcp_ctrl_proxy(bd_addr);
516 DBG("address found path PATH %s", path);
517 return proxy_array[i].avrcp_ctrl_proxy;
521 DBG("address NOT found");
523 return __bt_hal_init_avrcp_ctrl_proxy(bd_addr);
526 GDBusProxy *_bt_hal_get_avrcp_ctrl_properties_proxy(bt_bdaddr_t *bd_addr)
529 GError *error = NULL;
530 char *control_path = NULL;
531 GDBusConnection *conn = NULL;
533 control_path = _bt_hal_get_control_device_path(bd_addr);
534 if (control_path == NULL)
537 DBG("control_path = %s", control_path);
539 conn = _bt_hal_get_system_gconn();
541 ERR("FAIL to get system connection");
544 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
545 NULL, BT_HAL_BLUEZ_NAME,
546 control_path, BT_HAL_PROPERTIES_INTERFACE, NULL, &error);
549 ERR("Unable to allocate new proxy");
551 ERR("%s", error->message);
552 g_clear_error(&error);
560 GDBusProxy *_bt_hal_get_avrcp_transport_properties_proxy(bt_bdaddr_t *bd_addr)
563 GError *error = NULL;
564 char *transport_path = NULL;
565 GDBusConnection *conn = NULL;
567 transport_path = _bt_hal_get_transport_device_path(bd_addr);
568 if (transport_path == NULL)
571 DBG("transport_path = %s", transport_path);
573 conn = _bt_hal_get_system_gconn();
575 ERR("FAIL to get system connection");
578 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
579 NULL, BT_HAL_BLUEZ_NAME,
580 transport_path, BT_HAL_PROPERTIES_INTERFACE, NULL, &error);
583 ERR("Unable to allocate new proxy");
585 ERR("%s", error->message);
586 g_clear_error(&error);
594 GDBusProxy *_bt_hal_get_adapter_properties_proxy(void)
596 return (adapter_properties_proxy) ? adapter_properties_proxy :
597 __bt_hal_init_adapter_properties_proxy();
600 GDBusProxy *_bt_hal_get_profile_proxy(void)
602 GDBusConnection *gconn;
606 return profile_gproxy;
608 gconn = _bt_hal_get_system_gconn();
610 ERR("_bt_hal_get_system_gconn failed");
614 profile_gproxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE,
615 NULL, BT_HAL_BLUEZ_NAME,
617 "org.bluez.ProfileManager1",
620 ERR("Unable to create proxy: %s", err->message);
625 return profile_gproxy;
628 static char *__bt_hal_extract_adapter_path(GVariantIter *iter)
630 char *object_path = NULL;
631 GVariantIter *interface_iter;
632 GVariantIter *svc_iter;
633 char *interface_str = NULL;
635 /* Parse the signature: oa{sa{sv}}} */
636 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
639 if (object_path == NULL)
642 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
643 &interface_str, &svc_iter)) {
644 if (g_strcmp0(interface_str, "org.bluez.Adapter1") != 0)
647 DBG("Object Path: %s", object_path);
648 g_free(interface_str);
649 g_variant_iter_free(svc_iter);
650 g_variant_iter_free(interface_iter);
651 return g_strdup(object_path);
657 char *_bt_hal_get_adapter_path(void)
659 GDBusConnection *conn;
660 GDBusProxy *manager_proxy;
661 GVariant *result = NULL;
662 GVariantIter *iter = NULL;
663 char *adapter_path = NULL;
665 conn = _bt_hal_get_system_gconn();
669 manager_proxy = _bt_hal_get_manager_proxy();
670 if (manager_proxy == NULL)
673 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
675 G_DBUS_CALL_FLAGS_NONE,
680 ERR("Can't get managed objects");
684 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
685 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
687 adapter_path = __bt_hal_extract_adapter_path(iter);
688 g_variant_iter_free(iter);
689 g_variant_unref(result);
694 int _bt_hal_is_adapter_powered(gboolean *powered)
697 GError *error = NULL;
702 proxy = _bt_hal_get_adapter_properties_proxy();
704 return BT_STATUS_FAIL;
706 result = g_dbus_proxy_call_sync(proxy,
708 g_variant_new("(ss)", BT_HAL_ADAPTER_INTERFACE,
710 G_DBUS_CALL_FLAGS_NONE,
716 ERR("Failed to get powered status");
718 ERR("Failed to get powered status (Error: %s)", error->message);
719 g_clear_error(&error);
721 return BT_STATUS_FAIL;
724 g_variant_get(result, "(v)", &temp);
725 *powered = g_variant_get_boolean(temp);
726 INFO("powered: %d", *powered);
728 g_variant_unref(result);
729 g_variant_unref(temp);
730 return BT_STATUS_SUCCESS;
733 void _bt_hal_deinit_bluez_proxy(void)
735 if (manager_gproxy) {
736 g_object_unref(manager_gproxy);
737 manager_gproxy = NULL;
740 if (adapter_gproxy) {
741 g_object_unref(adapter_gproxy);
742 adapter_gproxy = NULL;
744 if (adapter_properties_proxy) {
745 g_object_unref(adapter_properties_proxy);
746 adapter_properties_proxy = NULL;
750 void _bt_hal_deinit_proxys(void)
752 _bt_hal_deinit_bluez_proxy();
755 g_object_unref(system_conn);
760 g_object_unref(session_conn);
765 GDBusProxy *_bt_hal_get_hid_agent_proxy(void)
767 GDBusConnection *conn;
771 conn = _bt_hal_get_system_gconn();
773 ERR("_bt_hal_get_system_gconn failed");
777 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
778 BT_HAL_HID_SERVICE_NAME, BT_HAL_HID_AGENT_OBJECT_PATH,
779 BT_HAL_HID_SERVICE_INTERFACE, NULL, &err);
782 ERR("Unable to create proxy: %s", err->message);
791 void _bt_hal_convert_device_path_to_address(const char *device_path,
792 char *device_address)
794 char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
797 if (device_path == NULL || device_address == NULL)
800 dev_addr = strstr(device_path, "dev_");
801 if (dev_addr != NULL) {
804 g_strlcpy(address, dev_addr, sizeof(address));
806 while ((pos = strchr(address, '_')) != NULL)
809 g_strlcpy(device_address, address, BT_HAL_ADDRESS_STRING_SIZE);
813 gboolean _bt_hal_uuid_is_standard(bt_uuid_t *p_uuid)
815 uint32_t uuid0, uuid4;
816 uint16_t uuid1, uuid2, uuid3, uuid5;
817 const char *uuid_name;
818 const char *uuid_name1;
820 memcpy(&uuid0, &(p_uuid->uu[0]), 4);
821 memcpy(&uuid1, &(p_uuid->uu[4]), 2);
822 memcpy(&uuid2, &(p_uuid->uu[6]), 2);
823 memcpy(&uuid3, &(p_uuid->uu[8]), 2);
824 memcpy(&uuid4, &(p_uuid->uu[10]), 4);
825 memcpy(&uuid5, &(p_uuid->uu[14]), 2);
827 uuid_name = _bt_hal_dump_uuid_name(ntohl(uuid0));
828 uuid_name1 = _bt_hal_dump_uuid_name((ntohl(uuid4) >> 16));
830 DBG("UUID Name [%s]", uuid_name);
831 DBG("UUID Name Shifted [%s]", uuid_name1);
833 if (!g_strcmp0(uuid_name, "--"))
840 void _bt_hal_convert_uuid_string_to_type(unsigned char *uuid,
841 const char *device_uuid)
843 uint32_t uuid0, uuid4;
844 uint16_t uuid1, uuid2, uuid3, uuid5;
846 sscanf(device_uuid, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
847 &uuid0, &uuid1, &uuid2, &uuid3, &uuid4, &uuid5);
849 uuid0 = htonl(uuid0);
850 uuid1 = htons(uuid1);
851 uuid2 = htons(uuid2);
852 uuid3 = htons(uuid3);
853 uuid4 = htonl(uuid4);
854 uuid5 = htons(uuid5);
856 memcpy(&(uuid[0]), &uuid0, 4);
857 memcpy(&(uuid[4]), &uuid1, 2);
858 memcpy(&(uuid[6]), &uuid2, 2);
859 memcpy(&(uuid[8]), &uuid3, 2);
860 memcpy(&(uuid[10]), &uuid4, 4);
861 memcpy(&(uuid[14]), &uuid5, 2);
864 void _bt_hal_convert_uuid_type_to_string(char *str, const unsigned char *uuid)
876 snprintf(str, BT_HAL_UUID_STRING_LEN,
877 "%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",
878 uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
879 uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
882 void _bt_hal_convert_addr_string_to_type(unsigned char *addr,
888 if (address == NULL || addr == NULL)
891 for (i = 0; i < BT_HAL_ADDRESS_LENGTH_MAX; i++) {
892 addr[i] = strtol(address, &ptr, 16);
894 if (ptr[0] != '\0') {
903 void _bt_hal_convert_addr_type_to_string(char *address,
904 const unsigned char *addr)
906 if (address == NULL || addr == NULL)
909 snprintf(address, BT_HAL_ADDRESS_STRING_SIZE,
910 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
911 addr[0], addr[1], addr[2],
912 addr[3], addr[4], addr[5]);
915 void _bt_hal_print_device_address_t(const bt_hal_device_address_t *addr)
917 DBG("%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", addr->addr[0], addr->addr[1], addr->addr[2],
918 addr->addr[3], addr->addr[4], addr->addr[5]);
921 void _bt_hal_divide_device_class(bt_hal_device_class_t *device_class,
924 if (device_class == NULL)
927 device_class->major_class = (unsigned short)(cod & 0x00001F00) >> 8;
928 device_class->minor_class = (unsigned short)((cod & 0x000000FC));
929 device_class->service_class = (unsigned long)((cod & 0x00FF0000));
931 if (cod & 0x002000) {
932 device_class->service_class |=
933 BT_HAL_DEVICE_SERVICE_CLASS_LIMITED_DISCOVERABLE_MODE;
937 int _bt_hal_copy_utf8_string(char *dest, const char *src, unsigned int length)
944 if (dest == NULL || src == NULL)
945 return BT_HAL_ERROR_INVALID_PARAM;
947 DBG("+src : %s", src);
948 DBG("+dest : %s", dest);
951 while (*p != '\0' && i < length) {
952 next = g_utf8_next_char(p);
955 while (count > 0 && ((i + count) < length)) {
962 return BT_HAL_ERROR_NONE;
965 gboolean _bt_hal_utf8_validate(char *name)
968 glong items_written = 0;
970 if (FALSE == g_utf8_validate(name, -1, NULL))
973 u16 = g_utf8_to_utf16(name, -1, NULL, &items_written, NULL);
979 if (items_written != g_utf8_strlen(name, -1))
985 int _bt_hal_set_socket_non_blocking(int socket_fd)
987 /* Set Nonblocking */
990 arg = fcntl(socket_fd, F_GETFL);
995 if (arg & O_NONBLOCK)
996 ERR("Already Non-blocking \n");
1000 if (fcntl(socket_fd, F_SETFL, arg) < 0)
1003 return BT_HAL_ERROR_NONE;
1006 int _bt_hal_set_non_blocking_tty(int sk)
1008 struct termios ti = {0,};
1011 err = _bt_hal_set_socket_non_blocking(sk);
1014 ERR("Error in set non blocking!\n");
1018 tcflush(sk, TCIOFLUSH);
1020 /* Switch tty to RAW mode */
1022 tcsetattr(sk, TCSANOW, &ti);
1024 return BT_HAL_ERROR_NONE;
1027 static char *__bt_hal_extract_device_path(GVariantIter *iter, char *address)
1029 char *object_path = NULL;
1030 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
1032 /* Parse the signature: oa{sa{sv}}} */
1033 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, NULL)) {
1034 if (object_path == NULL)
1036 _bt_hal_convert_device_path_to_address(object_path, device_address);
1037 if (g_strcmp0(address, device_address) == 0)
1038 return g_strdup(object_path);
1043 char *_bt_hal_get_device_object_path(char *address)
1045 char *object_path = NULL;
1046 GDBusConnection *conn;
1047 GDBusProxy *manager_proxy;
1048 GVariant *result = NULL;
1049 GVariantIter *iter = NULL;
1051 conn = _bt_hal_get_system_gconn();
1055 manager_proxy = _bt_hal_get_manager_proxy();
1056 if (manager_proxy == NULL)
1059 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
1061 G_DBUS_CALL_FLAGS_NONE,
1066 ERR("Can't get managed objects");
1070 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
1071 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
1072 object_path = __bt_hal_extract_device_path(iter, address);
1073 g_variant_iter_free(iter);
1074 g_variant_unref(result);
1078 GVariant *_bt_hal_get_managed_objects(void)
1080 GDBusConnection *conn;
1081 GDBusProxy *manager_proxy;
1082 GVariant *result = NULL;
1083 GError *error = NULL;
1085 conn = _bt_hal_get_system_gconn();
1089 manager_proxy = _bt_hal_get_manager_proxy();
1090 if (manager_proxy == NULL)
1093 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
1095 G_DBUS_CALL_FLAGS_NONE,
1100 ERR("Can't get managed objects");
1105 ERR("Fail to get ManagedObjects (Error: %s)", error->message);
1106 g_clear_error(&error);
1113 char *_bt_hal_convert_error_to_string(int error)
1116 case BT_HAL_ERROR_CANCEL:
1118 case BT_HAL_ERROR_INVALID_PARAM:
1119 return "INVALID_PARAMETER";
1120 case BT_HAL_ERROR_INVALID_DATA:
1121 return "INVALID DATA";
1122 case BT_HAL_ERROR_MEMORY_ALLOCATION:
1123 case BT_HAL_ERROR_OUT_OF_MEMORY:
1124 return "OUT_OF_MEMORY";
1125 case BT_HAL_ERROR_TIMEOUT:
1127 case BT_HAL_ERROR_NO_RESOURCES:
1128 return "NO_RESOURCES";
1129 case BT_HAL_ERROR_INTERNAL:
1131 case BT_HAL_ERROR_NOT_SUPPORT:
1132 return "NOT_SUPPORT";
1133 case BT_HAL_ERROR_DEVICE_NOT_ENABLED:
1134 return "NOT_ENABLED";
1135 case BT_HAL_ERROR_DEVICE_ALREADY_ENABLED:
1136 return "ALREADY_ENABLED";
1137 case BT_HAL_ERROR_DEVICE_BUSY:
1138 return "DEVICE_BUSY";
1139 case BT_HAL_ERROR_ACCESS_DENIED:
1140 return "ACCESS_DENIED";
1141 case BT_HAL_ERROR_MAX_CLIENT:
1142 return "MAX_CLIENT";
1143 case BT_HAL_ERROR_NOT_FOUND:
1145 case BT_HAL_ERROR_SERVICE_SEARCH_ERROR:
1146 return "SERVICE_SEARCH_ERROR";
1147 case BT_HAL_ERROR_PARING_FAILED:
1148 return "PARING_FAILED";
1149 case BT_HAL_ERROR_NOT_PAIRED:
1150 return "NOT_PAIRED";
1151 case BT_HAL_ERROR_SERVICE_NOT_FOUND:
1152 return "SERVICE_NOT_FOUND";
1153 case BT_HAL_ERROR_NOT_CONNECTED:
1154 return "NOT_CONNECTED";
1155 case BT_HAL_ERROR_ALREADY_CONNECT:
1156 return "ALREADY_CONNECT";
1157 case BT_HAL_ERROR_CONNECTION_BUSY:
1158 return "CONNECTION_BUSY";
1159 case BT_HAL_ERROR_CONNECTION_ERROR:
1160 return "CONNECTION_ERROR";
1161 case BT_HAL_ERROR_MAX_CONNECTION:
1162 return "MAX_CONNECTION";
1163 case BT_HAL_ERROR_NOT_IN_OPERATION:
1164 return "NOT_IN_OPERATION";
1165 case BT_HAL_ERROR_CANCEL_BY_USER:
1166 return "CANCEL_BY_USER";
1167 case BT_HAL_ERROR_REGISTRATION_FAILED:
1168 return "REGISTRATION_FAILED";
1169 case BT_HAL_ERROR_IN_PROGRESS:
1170 return "IN_PROGRESS";
1171 case BT_HAL_ERROR_AUTHENTICATION_FAILED:
1172 return "AUTHENTICATION_FAILED";
1173 case BT_HAL_ERROR_HOST_DOWN:
1175 case BT_HAL_ERROR_END_OF_DEVICE_LIST:
1176 return "END_OF_DEVICE_LIST";
1177 case BT_HAL_ERROR_AGENT_ALREADY_EXIST:
1178 return "AGENT_ALREADY_EXIST";
1179 case BT_HAL_ERROR_AGENT_DOES_NOT_EXIST:
1180 return "AGENT_DOES_NOT_EXIST";
1181 case BT_HAL_ERROR_ALREADY_INITIALIZED:
1182 return "ALREADY_INITIALIZED";
1183 case BT_HAL_ERROR_PERMISSION_DEINED:
1184 return "PERMISSION_DEINED";
1185 case BT_HAL_ERROR_ALREADY_DEACTIVATED:
1186 return "ALREADY_DEACTIVATED";
1187 case BT_HAL_ERROR_NOT_INITIALIZED:
1188 return "NOT_INITIALIZED";
1194 char * _bt_hal_convert_disc_reason_to_string(int reason)
1200 return "Connection terminated by local host";
1202 return "Remote user terminated connection";
1209 int _bt_hal_convert_disc_reason_to_status(int reason)
1213 return BT_STATUS_CONN_TOUT; //"Link loss"
1215 return BT_STATUS_CONN_TERM_LOCAL_HOST; //"Connection terminated by local host";
1217 return BT_STATUS_CONN_TERM_RMT_HOST; //"Connection terminated by local host";
1220 return BT_STATUS_FAIL;
1224 void _bt_hal_logging_connection(gboolean connect, int addr_type)
1226 static int le_conn = 0;
1227 static int le_disc = 0;
1228 static int edr_conn = 0;
1229 static int edr_disc = 0;
1243 INFO("[PM] Number of LE conn: %d disc: %d, Number of BR/EDR conn: %d disc: %d",
1244 le_conn, le_disc, edr_conn, edr_disc);
1247 void _bt_hal_swap_byte_ordering(char *data, int data_len)
1254 /* Swap to opposite endian */
1255 for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
1262 int _bt_hal_byte_arr_cmp(const char *data1, const char *data2, int data_len)
1266 if (data1 == NULL || data2 == NULL)
1268 for (i = 0; i < data_len; i++) {
1269 if (data1[i] != data2[i])
1270 return data1[i] - data2[i];
1274 int _bt_hal_byte_arr_cmp_with_mask(const char *data1, const char *data2,
1275 const char *mask, int data_len)
1280 if (data1 == NULL || data2 == NULL || mask == NULL)
1283 for (i = 0; i < data_len; i++) {
1284 a = data1[i] & mask[i];
1285 b = data2[i] & mask[i];
1287 return (int)(a - b);
1292 int _bt_hal_connect_profile(char *address, char *uuid,
1293 void *cb, gpointer func_data)
1297 GDBusConnection *conn;
1298 GDBusProxy *adapter_proxy;
1299 GError *error = NULL;
1301 conn = _bt_hal_get_system_gconn();
1303 return BT_HAL_ERROR_INTERNAL;
1305 object_path = _bt_hal_get_device_object_path(address);
1306 if (object_path == NULL) {
1307 ERR("No searched device");
1309 adapter_proxy = _bt_hal_get_adapter_proxy();
1310 if (adapter_proxy == NULL)
1311 return BT_HAL_ERROR_INTERNAL;
1313 g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1314 g_variant_new("(s)", address),
1315 G_DBUS_CALL_FLAGS_NONE,
1320 if (error != NULL) {
1321 ERR("CreateDevice Fail: %s", error->message);
1322 g_error_free(error);
1325 object_path = _bt_hal_get_device_object_path(address);
1327 if (object_path == NULL)
1328 return BT_HAL_ERROR_INTERNAL;
1330 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1331 NULL, BT_HAL_BLUEZ_NAME,
1332 object_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1333 g_free(object_path);
1335 return BT_HAL_ERROR_INTERNAL;
1338 g_dbus_proxy_call(proxy, "ConnectProfile",
1339 g_variant_new("(s)", uuid),
1340 G_DBUS_CALL_FLAGS_NONE,
1341 BT_HAL_MAX_DBUS_TIMEOUT,
1343 (GAsyncReadyCallback)cb,
1346 return BT_HAL_ERROR_NONE;
1349 int _bt_hal_disconnect_profile(char *address, char *uuid,
1350 void *cb, gpointer func_data)
1354 GDBusConnection *conn;
1356 conn = _bt_hal_get_system_gconn();
1358 return BT_HAL_ERROR_INTERNAL;
1360 object_path = _bt_hal_get_device_object_path(address);
1361 if (object_path == NULL)
1362 return BT_HAL_ERROR_INTERNAL;
1364 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1365 NULL, BT_HAL_BLUEZ_NAME,
1366 object_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1367 g_free(object_path);
1369 return BT_HAL_ERROR_INTERNAL;
1371 g_dbus_proxy_call(proxy, "DisconnectProfile",
1372 g_variant_new("(s)", uuid),
1373 G_DBUS_CALL_FLAGS_NONE,
1374 BT_HAL_MAX_DBUS_TIMEOUT,
1376 (GAsyncReadyCallback)cb,
1379 return BT_HAL_ERROR_NONE;
1382 int _bt_hal_register_profile(bt_hal_register_profile_info_t *info, gboolean use_default_rfcomm)
1384 GVariantBuilder *option_builder;
1388 int result = BT_STATUS_SUCCESS;
1390 proxy = _bt_hal_get_profile_proxy();
1391 if (proxy == NULL) {
1392 ERR("Getting profile proxy failed");
1393 return BT_STATUS_FAIL;
1396 option_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1397 if (info->authentication)
1398 g_variant_builder_add(option_builder, "{sv}",
1399 "RequireAuthentication",
1400 g_variant_new_boolean(TRUE));
1401 if (info->authorization)
1402 g_variant_builder_add(option_builder, "{sv}",
1403 "RequireAuthorization",
1404 g_variant_new_boolean(TRUE));
1406 g_variant_builder_add(option_builder, "{sv}",
1408 g_variant_new_string(info->role));
1411 * Setting RFCOMM channel to default value 0; would allow bluez to assign
1412 * RFCOMM channels based on the availability when two services want to use
1413 * the RFCOMM along with SPP. Hence bluez makes sure that no two services
1414 * use the same SPP RFCOMM channel.
1416 if (use_default_rfcomm)
1417 g_variant_builder_add(option_builder, "{sv}",
1419 g_variant_new_uint16(RFCOMM_DEFAULT_PROFILE_CHANNEL));
1421 g_variant_builder_add(option_builder, "{sv}",
1423 g_variant_new_string(info->service));
1425 ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile",
1426 g_variant_new("(osa{sv})", info->obj_path,
1429 G_DBUS_CALL_FLAGS_NONE, -1,
1432 ERR("RegisterProfile failed: %s", err->message);
1434 if (g_strrstr(err->message, BT_HAL_ACCESS_DENIED_MSG))
1435 result = BT_STATUS_AUTH_REJECTED;
1437 result = BT_STATUS_FAIL;
1439 g_clear_error(&err);
1442 g_variant_builder_unref(option_builder);
1445 g_variant_unref(ret);
1450 void _bt_hal_unregister_profile(char *path)
1456 proxy = _bt_hal_get_profile_proxy();
1457 if (proxy == NULL) {
1458 ERR("Getting profile proxy failed");
1462 ret = g_dbus_proxy_call_sync(proxy, "UnregisterProfile",
1463 g_variant_new("(o)", path),
1464 G_DBUS_CALL_FLAGS_NONE, -1,
1467 ERR("UnregisterProfile failed : %s", err->message);
1468 g_clear_error(&err);
1472 g_variant_unref(ret);
1477 static void __hal_new_connection_method(GDBusConnection *connection,
1478 const gchar *sender,
1479 const gchar *object_path,
1480 const gchar *interface_name,
1481 const gchar *method_name,
1482 GVariant *parameters,
1483 GDBusMethodInvocation *invocation,
1486 DBG("method %s", method_name);
1487 if (g_strcmp0(method_name, "NewConnection") == 0) {
1490 GUnixFDList *fd_list;
1492 GVariantBuilder *properties;
1494 bt_bdaddr_t remote_addr1;
1495 char addr[BT_HAL_ADDRESS_STRING_SIZE];
1496 bt_hal_new_connection_cb cb = user_data;
1498 g_variant_get(parameters, "(oha{sv})", &obj_path, &index,
1501 msg = g_dbus_method_invocation_get_message(invocation);
1502 fd_list = g_dbus_message_get_unix_fd_list(msg);
1503 if (fd_list == NULL) {
1504 GQuark quark = g_quark_from_string("rfcomm-app");
1505 GError *err = g_error_new(quark, 0, "No fd in message");
1506 g_dbus_method_invocation_return_gerror(invocation, err);
1512 fd = g_unix_fd_list_get(fd_list, index, NULL);
1514 ERR("Invalid fd return");
1515 GQuark quark = g_quark_from_string("rfcomm-app");
1516 GError *err = g_error_new(quark, 0, "Invalid FD return");
1517 g_dbus_method_invocation_return_gerror(invocation, err);
1521 INFO("Object Path %s", obj_path);
1523 _bt_hal_convert_device_path_to_address(obj_path, addr);
1524 _bt_hal_convert_addr_string_to_type(remote_addr1.address, (const char *)addr);
1525 INFO("fd: %d, address %s", fd, addr);
1527 g_dbus_method_invocation_return_value(invocation, NULL);
1530 cb(object_path, fd, &remote_addr1);
1533 } else if (g_strcmp0(method_name, "RequestDisconnection") == 0) {
1534 g_dbus_method_invocation_return_value(invocation, NULL);
1538 static GDBusNodeInfo *_bt_hal_get_gdbus_node(const gchar *xml_data)
1541 char *name = g_strdup_printf("org.bt.frwk.p%d", getpid());
1543 bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1545 G_BUS_NAME_OWNER_FLAGS_NONE,
1551 DBG("Got bus id %d", bus_id);
1555 return g_dbus_node_info_new_for_xml(xml_data, NULL);
1558 static const GDBusInterfaceVTable method_table = {
1559 __hal_new_connection_method,
1564 int _bt_hal_register_new_gdbus_object(const char *path, bt_hal_new_connection_cb cb)
1566 GDBusConnection *gconn;
1568 GError *error = NULL;
1570 gconn = _bt_hal_get_system_gconn();
1574 if (new_conn_node == NULL)
1575 new_conn_node = _bt_hal_get_gdbus_node(rfcomm_agent_xml);
1577 if (new_conn_node == NULL)
1580 id = g_dbus_connection_register_object(gconn, path,
1581 new_conn_node->interfaces[0],
1585 ERR("Failed to register: %s", error->message);
1586 g_error_free(error);
1590 DBG("NEW CONNECTION ID %d", id);
1595 void _bt_hal_unregister_gdbus_object(int object_id)
1597 GDBusConnection *gconn;
1599 gconn = _bt_hal_get_system_gconn();
1603 g_dbus_connection_unregister_object(gconn, object_id);
1606 int _bt_hal_discover_services(char *address, char *uuid, void *cb, gpointer func_data)
1610 GDBusProxy *adapter_proxy;
1612 GDBusConnection *conn;
1614 conn = _bt_hal_get_system_gconn();
1616 ERR("conn == NULL, return");
1617 return BT_STATUS_FAIL;
1620 object_path = _bt_hal_get_device_object_path(address);
1621 if (object_path == NULL) {
1622 GVariant *ret = NULL;
1624 INFO("No searched device");
1625 adapter_proxy = _bt_hal_get_adapter_proxy();
1626 if (adapter_proxy == NULL) {
1627 ERR("adapter_proxy == NULL, return");
1628 return BT_STATUS_FAIL;
1631 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1632 g_variant_new("(s)", address),
1633 G_DBUS_CALL_FLAGS_NONE,
1634 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1637 ERR("CreateDevice Failed: %s", err->message);
1638 g_clear_error(&err);
1642 g_variant_unref(ret);
1644 g_object_unref(adapter_proxy);
1645 object_path = _bt_hal_get_device_object_path(address);
1646 if (object_path == NULL) {
1647 ERR("object_path == NULL, return");
1648 return BT_STATUS_FAIL;
1652 proxy = g_dbus_proxy_new_sync(conn,
1653 G_DBUS_PROXY_FLAGS_NONE, NULL,
1654 BT_HAL_BLUEZ_NAME, object_path,
1655 BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1656 g_free(object_path);
1657 if (proxy == NULL) {
1658 ERR("Error while getting proxy");
1659 return BT_STATUS_FAIL;
1662 g_dbus_proxy_call(proxy, "DiscoverServices",
1663 g_variant_new("(s)", uuid),
1664 G_DBUS_CALL_FLAGS_NONE,
1665 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1666 (GAsyncReadyCallback)cb,
1669 return BT_STATUS_SUCCESS;
1672 int _bt_hal_cancel_discovers(char *address)
1676 GDBusProxy *adapter_proxy;
1678 GDBusConnection *conn;
1680 conn = _bt_hal_get_system_gconn();
1682 return BT_STATUS_FAIL;
1684 object_path = _bt_hal_get_device_object_path(address);
1685 if (object_path == NULL) {
1686 GVariant *ret = NULL;
1687 INFO("No searched device");
1688 adapter_proxy = _bt_hal_get_adapter_proxy();
1689 if (adapter_proxy == NULL) {
1690 ERR("adapter_proxy == NULL, return");
1691 return BT_STATUS_FAIL;
1694 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1695 g_variant_new("(s)", address),
1696 G_DBUS_CALL_FLAGS_NONE,
1697 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1700 ERR("CreateDevice Failed: %s", err->message);
1701 g_clear_error(&err);
1705 g_variant_unref(ret);
1707 g_object_unref(adapter_proxy);
1709 object_path = _bt_hal_get_device_object_path(address);
1710 if (object_path == NULL)
1711 return BT_STATUS_FAIL;
1714 proxy = g_dbus_proxy_new_sync(conn,
1715 G_DBUS_PROXY_FLAGS_NONE, NULL,
1716 BT_HAL_BLUEZ_NAME, object_path,
1717 BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1718 g_free(object_path);
1719 g_dbus_proxy_call_sync(proxy, "CancelDiscovery",
1721 G_DBUS_CALL_FLAGS_NONE,
1722 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1725 ERR("DBus Error message: [%s]", err->message);
1726 g_clear_error(&err);
1727 return BT_STATUS_FAIL;
1731 g_object_unref(proxy);
1733 return BT_STATUS_SUCCESS;
1736 int _bt_hal_discover_service_uuids(char *address, char *remote_uuid)
1740 GDBusConnection *gconn;
1742 char **uuid_value = NULL;
1745 GVariant *value = NULL;
1746 GVariant *ret = NULL;
1747 int result = BT_STATUS_FAIL;
1749 if (remote_uuid == NULL) {
1750 ERR("remote_uuid == NULL, return");
1751 return BT_STATUS_FAIL;
1754 gconn = _bt_hal_get_system_gconn();
1755 if (gconn == NULL) {
1756 ERR("gconn == NULL, return");
1757 return BT_STATUS_FAIL;
1760 object_path = _bt_hal_get_device_object_path(address);
1761 if (object_path == NULL) {
1762 ERR("object_path == NULL, return");
1763 return BT_STATUS_FAIL;
1766 proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE, NULL,
1767 BT_HAL_BLUEZ_NAME, object_path, BT_HAL_PROPERTIES_INTERFACE, NULL,
1769 if (proxy == NULL) {
1770 g_free(object_path);
1771 ERR("proxy == NULL, return");
1772 return BT_STATUS_FAIL;
1776 ERR("DBus Error: [%s]", err->message);
1777 g_clear_error(&err);
1780 ret = g_dbus_proxy_call_sync(proxy, "GetAll",
1781 g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
1782 G_DBUS_CALL_FLAGS_NONE,
1783 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1786 result = BT_STATUS_FAIL;
1787 ERR("DBus Error : %s", err->message);
1788 g_clear_error(&err);
1793 ERR("g_dbus_proxy_call_sync function return NULL");
1794 result = BT_STATUS_FAIL;
1798 g_variant_get(ret, "(@a{sv})", &value);
1799 g_variant_unref(ret);
1801 GVariant *temp_value = g_variant_lookup_value(value, "UUIDs",
1802 G_VARIANT_TYPE_STRING_ARRAY);
1805 size = g_variant_get_size(temp_value);
1808 uuid_value = (char **)g_variant_get_strv(temp_value, &size);
1809 DBG("Size items %zu", size);
1813 g_variant_unref(temp_value);
1816 for (i = 0; uuid_value[i] != NULL; i++) {
1817 DBG("Remote uuids %s, searched uuid: %s",
1818 uuid_value[i], remote_uuid);
1819 if (strcasecmp(uuid_value[i], remote_uuid) == 0) {
1820 result = BT_STATUS_SUCCESS;
1829 g_object_unref(proxy);
1831 g_variant_unref(value);
1838 int bt_hal_gatt_convert_prop2string(
1839 bt_hal_gatt_characteristic_property_t properties,
1840 char *char_properties[])
1844 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_BROADCAST) {
1845 char_properties[flag_count] = g_strdup("broadcast");
1848 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_READ) {
1849 char_properties[flag_count] = g_strdup("read");
1852 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE) {
1853 char_properties[flag_count] = g_strdup("write-without-response");
1856 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE) {
1857 char_properties[flag_count] = g_strdup("write");
1860 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY) {
1861 char_properties[flag_count] = g_strdup("notify");
1864 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE) {
1865 char_properties[flag_count] = g_strdup("indicate");
1868 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE) {
1869 char_properties[flag_count] = g_strdup("authenticated-signed-writes");
1872 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE) {
1873 char_properties[flag_count] = g_strdup("reliable-write");
1876 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES) {
1877 char_properties[flag_count] = g_strdup("writable-auxiliaries");
1880 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ) {
1881 char_properties[flag_count] = g_strdup("encrypt-read");
1884 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE) {
1885 char_properties[flag_count] = g_strdup("encrypt-write");
1888 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ) {
1889 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
1892 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE) {
1893 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
1897 if (flag_count == 0) {
1898 char_properties[flag_count] = g_strdup("read");
1905 int bt_hal_gatt_convert_perm2string(
1906 bt_hal_gatt_permission_t properties,
1907 char *char_properties[])
1911 if (properties & BT_HAL_GATT_PERMISSION_READ) {
1912 char_properties[flag_count] = g_strdup("read");
1915 if (properties & BT_HAL_GATT_PERMISSION_WRITE) {
1916 char_properties[flag_count] = g_strdup("write");
1919 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_READ) {
1920 char_properties[flag_count] = g_strdup("encrypt-read");
1923 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_WRITE) {
1924 char_properties[flag_count] = g_strdup("encrypt-write");
1927 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_READ) {
1928 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
1931 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_WRITE) {
1932 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
1936 if (flag_count == 0) {
1937 char_properties[flag_count] = g_strdup("read");
1944 gboolean _bt_hal_is_service_enabled(const char *uuid)
1947 GError *error = NULL;
1950 GVariantIter *iter = NULL;
1952 gboolean ret = FALSE;
1954 proxy = _bt_hal_get_adapter_properties_proxy();
1956 DBG("_bt_hal_dbus_get_local_name: Adapter Properties proxy get failed!!!");
1960 result = g_dbus_proxy_call_sync(proxy,
1961 "Get", g_variant_new("(ss)",
1962 BT_HAL_ADAPTER_INTERFACE, "UUIDs"),
1963 G_DBUS_CALL_FLAGS_NONE, -1,
1966 if (error != NULL) {
1967 ERR("Failed to get UUIDs (Error: %s)", error->message);
1968 g_clear_error(&error);
1970 ERR("Failed to get UUIDs");
1974 g_variant_get(result, "(v)", &temp);
1975 g_variant_get(temp, "as", &iter);
1977 ERR("Failed to get UUIDs");
1978 g_variant_unref(result);
1982 while (g_variant_iter_loop(iter, "&s", &uuid_str)) {
1983 DBG("UUID string [%s]\n", uuid_str);
1984 if (!strncasecmp(uuid, uuid_str, strlen(uuid))) {
1990 g_variant_iter_free(iter);
1991 g_variant_unref(result);
1992 g_variant_unref(temp);