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];
75 static GDBusConnection *system_gconn = NULL;
78 GDBusNodeInfo *new_conn_node;
79 static const gchar rfcomm_agent_xml[] =
81 " <interface name='org.bluez.Profile1'>"
82 " <method name='NewConnection'>"
83 " <arg type='o' name='object' direction='in'/>"
84 " <arg type='h' name='fd' direction='in'/>"
85 " <arg type='a{sv}' name='properties' direction='in'/>"
87 " <method name='RequestDisconnection'>"
88 " <arg type='o' name='device' direction='in'/>"
93 GDBusConnection *_bt_hal_gdbus_init_system_gconn(void)
97 if (system_gconn != NULL)
100 system_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
103 ERR("Unable to connect to dbus: %s", error->message);
104 g_clear_error(&error);
110 GDBusConnection *_bt_hal_gdbus_get_system_gconn(void)
112 GDBusConnection *local_system_gconn = NULL;
113 GError *error = NULL;
115 if (system_gconn == NULL) {
116 system_gconn = _bt_hal_gdbus_init_system_gconn();
117 } else if (g_dbus_connection_is_closed(system_gconn)) {
119 local_system_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
121 if (!local_system_gconn) {
122 ERR("Unable to connect to dbus: %s", error->message);
123 g_clear_error(&error);
126 system_gconn = local_system_gconn;
132 static GDBusProxy *__bt_hal_init_manager_proxy(void)
138 if (system_conn == NULL) {
139 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
140 if (system_conn == NULL)
144 proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
145 NULL, BT_HAL_BLUEZ_NAME,
146 BT_HAL_MANAGER_PATH, BT_HAL_MANAGER_INTERFACE, NULL, NULL);
151 manager_gproxy = proxy;
157 static GDBusProxy *__bt_hal_init_adapter_proxy(void)
159 GDBusProxy *manager_proxy;
161 char *adapter_path = NULL;
163 if (system_conn == NULL) {
164 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
165 if (system_conn == NULL)
169 manager_proxy = _bt_hal_get_manager_proxy();
170 if (manager_proxy == NULL)
173 adapter_path = _bt_hal_get_adapter_path();
174 if (adapter_path == NULL)
177 proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
178 NULL, BT_HAL_BLUEZ_NAME,
179 adapter_path, BT_HAL_ADAPTER_INTERFACE, NULL, NULL);
181 g_free(adapter_path);
186 adapter_gproxy = proxy;
191 static GDBusProxy *__bt_hal_init_adapter_properties_proxy(void)
193 GDBusProxy *manager_proxy;
195 char *adapter_path = NULL;
197 if (system_conn == NULL) {
198 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
199 if (system_conn == NULL)
203 manager_proxy = _bt_hal_get_manager_proxy();
204 if (manager_proxy == NULL)
207 adapter_path = _bt_hal_get_adapter_path();
208 if (adapter_path == NULL)
211 proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
212 NULL, BT_HAL_BLUEZ_NAME,
213 adapter_path, BT_HAL_PROPERTIES_INTERFACE, NULL, NULL);
215 g_free(adapter_path);
220 adapter_properties_proxy = proxy;
225 void _bt_hal_set_control_device_path(const char *path)
232 DBG("control_path = %s", path);
234 for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
235 if (proxy_array[i].avrcp_control_path == NULL) {
236 proxy_array[i].avrcp_control_path = g_strdup(path);
237 DBG("PATH %s formed index %d", proxy_array[i].avrcp_control_path, i);
243 void _bt_hal_remove_control_device_path(const char *path)
250 for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
251 if (g_strcmp0(proxy_array[i].avrcp_control_path, path) == 0) {
252 DBG("Clear AVRCP proxy[%d]", i);
253 g_free(proxy_array[i].avrcp_control_path);
254 g_object_unref(proxy_array[i].avrcp_ctrl_proxy);
256 proxy_array[i].avrcp_control_path = NULL;
257 proxy_array[i].avrcp_ctrl_proxy = NULL;
258 memset(proxy_array[i].bd_addr.address, 0, 6);
264 static char *__bt_hal_extract_control_device_path(GVariantIter *iter, char *address)
266 char *object_path = NULL;
267 char *interface_str = NULL;
268 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
270 /* Parse the signature: oa{sa{sv}}} */
271 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_str)) {
272 if (object_path == NULL)
275 if (g_strcmp0(interface_str, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
276 _bt_hal_convert_device_path_to_address(object_path, device_address);
277 if (g_strcmp0(address, device_address) == 0)
278 return g_strdup(object_path);
284 static char *__bt_hal_extract_transport_device_path(GVariantIter *iter, char *address)
286 char *object_path = NULL;
287 char *interface_str = NULL;
288 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
290 /* Parse the signature: oa{sa{sv}}} */
291 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_str)) {
292 if (object_path == NULL)
295 if (g_strcmp0(interface_str, BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
296 _bt_hal_convert_device_path_to_address(object_path, device_address);
297 if (g_strcmp0(address, device_address) == 0)
298 return g_strdup(object_path);
304 static char *__bt_hal_get_control_device_object_path(char *address)
306 char *object_path = NULL;
307 GDBusConnection *conn;
308 GDBusProxy *manager_proxy;
309 GVariant *result = NULL;
310 GVariantIter *iter = NULL;
312 conn = _bt_hal_get_system_gconn();
316 manager_proxy = _bt_hal_get_manager_proxy();
317 if (manager_proxy == NULL)
320 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
322 G_DBUS_CALL_FLAGS_NONE,
327 ERR("Can't get managed objects");
331 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
332 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
333 object_path = __bt_hal_extract_control_device_path(iter, address);
334 g_variant_iter_free(iter);
335 g_variant_unref(result);
339 static char *__bt_hal_get_transport_device_object_path(char *address)
341 char *object_path = NULL;
342 GDBusConnection *conn;
343 GDBusProxy *manager_proxy;
344 GVariant *result = NULL;
345 GVariantIter *iter = NULL;
347 conn = _bt_hal_get_system_gconn();
351 manager_proxy = _bt_hal_get_manager_proxy();
352 if (manager_proxy == NULL)
355 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
357 G_DBUS_CALL_FLAGS_NONE,
362 ERR("Can't get managed objects");
366 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
367 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
368 object_path = __bt_hal_extract_transport_device_path(iter, address);
369 g_variant_iter_free(iter);
370 g_variant_unref(result);
374 char *_bt_hal_get_control_device_path(bt_bdaddr_t *bd_addr)
377 char connected_address[BT_HAL_ADDRESS_STRING_SIZE];
381 if (avrcp_control_path != NULL)
382 return avrcp_control_path;
384 _bt_hal_convert_addr_type_to_string(connected_address, bd_addr->address);
386 DBG("device address = %s", connected_address);
388 control_path = __bt_hal_get_control_device_object_path(connected_address);
389 if (control_path == NULL)
392 avrcp_control_path = control_path;
393 DBG("control_path = %s", control_path);
397 char *_bt_hal_get_transport_device_path(bt_bdaddr_t *bd_addr)
399 char *transport_path;
400 char connected_address[BT_HAL_ADDRESS_STRING_SIZE];
404 if (avrcp_transport_path != NULL)
405 return avrcp_transport_path;
407 _bt_hal_convert_addr_type_to_string(connected_address, bd_addr->address);
409 DBG("device address = %s", connected_address);
411 transport_path = __bt_hal_get_transport_device_object_path(connected_address);
412 if (transport_path == NULL)
415 avrcp_transport_path = transport_path;
416 DBG("transport_path = %s", transport_path);
417 return transport_path;
420 static GDBusConnection *__bt_hal_init_system_gconn(void)
422 if (system_conn == NULL)
423 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
428 static GDBusProxy *__bt_hal_init_avrcp_ctrl_proxy(bt_bdaddr_t *bd_addr)
430 GDBusProxy *manager_proxy;
432 GDBusConnection *gconn = NULL;
435 gconn = _bt_hal_gdbus_get_system_gconn();
439 manager_proxy = _bt_hal_get_manager_proxy();
440 if (manager_proxy == NULL)
443 for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
444 if (proxy_array[i].avrcp_ctrl_proxy == NULL) {
445 memcpy(proxy_array[i].bd_addr.address, bd_addr->address, 6);
446 DBG("PATH %s formed index %d ", proxy_array[i].avrcp_control_path, i);
451 if (i == BT_AUDIO_SOURCE_MAX) {
452 ERR("NO free arr proxy space found");
456 proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE,
457 NULL, BT_HAL_BLUEZ_NAME,
458 proxy_array[i].avrcp_control_path, BT_HAL_PLAYER_CONTROL_INTERFACE, NULL, NULL);
463 avrcp_ctrl_proxy = proxy;
464 proxy_array[i].avrcp_ctrl_proxy = proxy;
469 static GDBusConnection *__bt_hal_init_session_conn(void)
471 if (session_conn == NULL)
472 session_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
477 GDBusConnection *_bt_hal_get_session_gconn(void)
479 return (session_conn) ? session_conn : __bt_hal_init_session_conn();
482 GDBusConnection *_bt_hal_get_system_gconn(void)
484 return (system_conn) ? system_conn : __bt_hal_init_system_gconn();
487 GDBusProxy *_bt_hal_get_manager_proxy(void)
490 if (manager_gproxy) {
491 const gchar *path = g_dbus_proxy_get_object_path(manager_gproxy);
493 ERR("Already proxy released hence creating new proxy");
494 return __bt_hal_init_manager_proxy();
496 return manager_gproxy;
499 return __bt_hal_init_manager_proxy();
502 GDBusProxy *_bt_hal_get_adapter_proxy(void)
504 if (adapter_gproxy) {
505 const char *path = g_dbus_proxy_get_object_path(adapter_gproxy);
507 ERR("Already proxy released hence creating new proxy");
508 return __bt_hal_init_adapter_proxy();
511 return adapter_gproxy;
513 return __bt_hal_init_adapter_proxy();
517 GDBusProxy *_bt_hal_get_avrcp_ctrl_proxy(bt_bdaddr_t *bd_addr)
521 for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
522 if (proxy_array[i].avrcp_ctrl_proxy
523 && (!memcmp(proxy_array[i].bd_addr.address, bd_addr->address, 6))) {
524 char *path = g_dbus_proxy_get_object_path(proxy_array[i].avrcp_ctrl_proxy);
527 proxy_array[i].avrcp_ctrl_proxy = NULL;
528 ERR("Already proxy released hence creating new proxy");
529 return __bt_hal_init_avrcp_ctrl_proxy(bd_addr);
532 DBG("address found path PATH %s", path);
533 return proxy_array[i].avrcp_ctrl_proxy;
537 DBG("address NOT found");
539 return __bt_hal_init_avrcp_ctrl_proxy(bd_addr);
542 GDBusProxy *_bt_hal_get_avrcp_ctrl_properties_proxy(bt_bdaddr_t *bd_addr)
545 GError *error = NULL;
546 char *control_path = NULL;
547 GDBusConnection *conn = NULL;
550 control_path = _bt_hal_get_control_device_path(bd_addr);
551 if (control_path == NULL)
554 DBG("control_path = %s", control_path);
556 conn = _bt_hal_get_system_gconn();
558 ERR("FAIL to get system connection");
561 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
562 NULL, BT_HAL_BLUEZ_NAME,
563 control_path, BT_HAL_PROPERTIES_INTERFACE, NULL, &error);
566 ERR("Unable to allocate new proxy");
568 ERR("%s", error->message);
569 g_clear_error(&error);
578 GDBusProxy *_bt_hal_get_avrcp_transport_properties_proxy(bt_bdaddr_t *bd_addr)
581 GError *error = NULL;
582 char *transport_path = NULL;
583 GDBusConnection *conn = NULL;
586 transport_path = _bt_hal_get_transport_device_path(bd_addr);
587 if (transport_path == NULL)
590 DBG("transport_path = %s", transport_path);
592 conn = _bt_hal_get_system_gconn();
594 ERR("FAIL to get system connection");
597 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
598 NULL, BT_HAL_BLUEZ_NAME,
599 transport_path, BT_HAL_PROPERTIES_INTERFACE, NULL, &error);
602 ERR("Unable to allocate new proxy");
604 ERR("%s", error->message);
605 g_clear_error(&error);
614 GDBusProxy *_bt_hal_get_adapter_properties_proxy(void)
616 return (adapter_properties_proxy) ? adapter_properties_proxy :
617 __bt_hal_init_adapter_properties_proxy();
620 GDBusProxy *_bt_hal_get_profile_proxy(void)
622 GDBusConnection *gconn;
626 return profile_gproxy;
628 gconn = _bt_hal_get_system_gconn();
630 ERR("_bt_hal_get_system_gconn failed");
634 profile_gproxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE,
635 NULL, BT_HAL_BLUEZ_NAME,
637 "org.bluez.ProfileManager1",
640 ERR("Unable to create proxy: %s", err->message);
645 return profile_gproxy;
648 static char *__bt_hal_extract_adapter_path(GVariantIter *iter)
650 char *object_path = NULL;
651 GVariantIter *interface_iter;
652 GVariantIter *svc_iter;
653 char *interface_str = NULL;
655 /* Parse the signature: oa{sa{sv}}} */
656 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
659 if (object_path == NULL)
662 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
663 &interface_str, &svc_iter)) {
664 if (g_strcmp0(interface_str, "org.bluez.Adapter1") != 0)
667 DBG("Object Path: %s", object_path);
668 g_free(interface_str);
669 g_variant_iter_free(svc_iter);
670 g_variant_iter_free(interface_iter);
671 return g_strdup(object_path);
677 char *_bt_hal_get_adapter_path(void)
679 GDBusConnection *conn;
680 GDBusProxy *manager_proxy;
681 GVariant *result = NULL;
682 GVariantIter *iter = NULL;
683 char *adapter_path = NULL;
686 conn = _bt_hal_get_system_gconn();
690 manager_proxy = _bt_hal_get_manager_proxy();
691 if (manager_proxy == NULL)
694 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
696 G_DBUS_CALL_FLAGS_NONE,
701 ERR("Can't get managed objects");
705 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
706 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
708 adapter_path = __bt_hal_extract_adapter_path(iter);
709 g_variant_iter_free(iter);
710 g_variant_unref(result);
715 int _bt_hal_is_adapter_powered(gboolean *powered)
718 GError *error = NULL;
723 proxy = _bt_hal_get_adapter_properties_proxy();
725 return BT_STATUS_FAIL;
727 result = g_dbus_proxy_call_sync(proxy,
729 g_variant_new("(ss)", BT_HAL_ADAPTER_INTERFACE,
731 G_DBUS_CALL_FLAGS_NONE,
737 ERR("Failed to get powered status");
739 ERR("Failed to get powered status (Error: %s)", error->message);
740 g_clear_error(&error);
742 return BT_STATUS_FAIL;
745 g_variant_get(result, "(v)", &temp);
746 *powered = g_variant_get_boolean(temp);
747 INFO("powered: %d", *powered);
749 g_variant_unref(result);
750 g_variant_unref(temp);
751 return BT_STATUS_SUCCESS;
754 void _bt_hal_deinit_bluez_proxy(void)
756 if (manager_gproxy) {
757 g_object_unref(manager_gproxy);
758 manager_gproxy = NULL;
761 if (adapter_gproxy) {
762 g_object_unref(adapter_gproxy);
763 adapter_gproxy = NULL;
765 if (adapter_properties_proxy) {
766 g_object_unref(adapter_properties_proxy);
767 adapter_properties_proxy = NULL;
771 void _bt_hal_deinit_proxys(void)
773 _bt_hal_deinit_bluez_proxy();
776 g_object_unref(system_conn);
781 g_object_unref(session_conn);
786 void _bt_hal_convert_device_path_to_address(const char *device_path,
787 char *device_address)
789 char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
792 if (device_path == NULL || device_address == NULL)
795 dev_addr = strstr(device_path, "dev_");
796 if (dev_addr != NULL) {
799 g_strlcpy(address, dev_addr, sizeof(address));
801 while ((pos = strchr(address, '_')) != NULL)
804 g_strlcpy(device_address, address, BT_HAL_ADDRESS_STRING_SIZE);
808 gboolean _bt_hal_uuid_is_standard(bt_uuid_t *p_uuid)
810 uint32_t uuid0, uuid4;
811 uint16_t uuid1, uuid2, uuid3, uuid5;
812 const char *uuid_name;
813 const char *uuid_name1;
815 memcpy(&uuid0, &(p_uuid->uu[0]), 4);
816 memcpy(&uuid1, &(p_uuid->uu[4]), 2);
817 memcpy(&uuid2, &(p_uuid->uu[6]), 2);
818 memcpy(&uuid3, &(p_uuid->uu[8]), 2);
819 memcpy(&uuid4, &(p_uuid->uu[10]), 4);
820 memcpy(&uuid5, &(p_uuid->uu[14]), 2);
822 uuid_name = _bt_hal_dump_uuid_name(ntohl(uuid0));
823 uuid_name1 = _bt_hal_dump_uuid_name((ntohl(uuid4) >> 16));
825 DBG("UUID Name [%s]", uuid_name);
826 DBG("UUID Name Shifted [%s]", uuid_name1);
828 if (!g_strcmp0(uuid_name, "--"))
835 void _bt_hal_convert_uuid_string_to_type(unsigned char *uuid,
836 const char *device_uuid)
838 uint32_t uuid0, uuid4;
839 uint16_t uuid1, uuid2, uuid3, uuid5;
841 sscanf(device_uuid, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
842 &uuid0, &uuid1, &uuid2, &uuid3, &uuid4, &uuid5);
844 uuid0 = htonl(uuid0);
845 uuid1 = htons(uuid1);
846 uuid2 = htons(uuid2);
847 uuid3 = htons(uuid3);
848 uuid4 = htonl(uuid4);
849 uuid5 = htons(uuid5);
851 memcpy(&(uuid[0]), &uuid0, 4);
852 memcpy(&(uuid[4]), &uuid1, 2);
853 memcpy(&(uuid[6]), &uuid2, 2);
854 memcpy(&(uuid[8]), &uuid3, 2);
855 memcpy(&(uuid[10]), &uuid4, 4);
856 memcpy(&(uuid[14]), &uuid5, 2);
859 void _bt_hal_convert_uuid_type_to_string(char *str, const unsigned char *uuid)
871 snprintf(str, BT_HAL_UUID_STRING_LEN,
872 "%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",
873 uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
874 uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
877 void _bt_hal_convert_addr_string_to_type(unsigned char *addr,
883 if (address == NULL || addr == NULL)
886 for (i = 0; i < BT_HAL_ADDRESS_LENGTH_MAX; i++) {
887 addr[i] = strtol(address, &ptr, 16);
889 if (ptr[0] != '\0') {
898 void _bt_hal_convert_addr_type_to_string(char *address,
899 const unsigned char *addr)
901 if (address == NULL || addr == NULL)
904 snprintf(address, BT_HAL_ADDRESS_STRING_SIZE,
905 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
906 addr[0], addr[1], addr[2],
907 addr[3], addr[4], addr[5]);
910 void _bt_hal_print_device_address_t(const bt_hal_device_address_t *addr)
912 DBG("%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", addr->addr[0], addr->addr[1], addr->addr[2],
913 addr->addr[3], addr->addr[4], addr->addr[5]);
916 void _bt_hal_divide_device_class(bt_hal_device_class_t *device_class,
919 if (device_class == NULL)
922 device_class->major_class = (unsigned short)(cod & 0x00001F00) >> 8;
923 device_class->minor_class = (unsigned short)((cod & 0x000000FC));
924 device_class->service_class = (unsigned long)((cod & 0x00FF0000));
926 if (cod & 0x002000) {
927 device_class->service_class |=
928 BT_HAL_DEVICE_SERVICE_CLASS_LIMITED_DISCOVERABLE_MODE;
932 int _bt_hal_copy_utf8_string(char *dest, const char *src, unsigned int length)
939 if (dest == NULL || src == NULL)
940 return BT_HAL_ERROR_INVALID_PARAM;
942 DBG("+src : %s", src);
943 DBG("+dest : %s", dest);
946 while (*p != '\0' && i < length) {
947 next = g_utf8_next_char(p);
950 while (count > 0 && ((i + count) < length)) {
957 return BT_HAL_ERROR_NONE;
960 gboolean _bt_hal_utf8_validate(char *name)
964 glong items_written = 0;
966 if (FALSE == g_utf8_validate(name, -1, NULL))
969 u16 = g_utf8_to_utf16(name, -1, NULL, &items_written, NULL);
975 if (items_written != g_utf8_strlen(name, -1))
982 int _bt_hal_set_socket_non_blocking(int socket_fd)
984 /* Set Nonblocking */
987 arg = fcntl(socket_fd, F_GETFL);
992 if (arg & O_NONBLOCK)
993 ERR("Already Non-blocking \n");
997 if (fcntl(socket_fd, F_SETFL, arg) < 0)
1000 return BT_HAL_ERROR_NONE;
1003 int _bt_hal_set_non_blocking_tty(int sk)
1005 struct termios ti = {0,};
1008 err = _bt_hal_set_socket_non_blocking(sk);
1011 ERR("Error in set non blocking!\n");
1015 tcflush(sk, TCIOFLUSH);
1017 /* Switch tty to RAW mode */
1019 tcsetattr(sk, TCSANOW, &ti);
1021 return BT_HAL_ERROR_NONE;
1024 static char *__bt_hal_extract_device_path(GVariantIter *iter, char *address)
1026 char *object_path = NULL;
1027 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
1029 /* Parse the signature: oa{sa{sv}}} */
1030 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, NULL)) {
1031 if (object_path == NULL)
1033 _bt_hal_convert_device_path_to_address(object_path, device_address);
1034 if (g_strcmp0(address, device_address) == 0)
1035 return g_strdup(object_path);
1040 char *_bt_hal_get_device_object_path(char *address)
1042 char *object_path = NULL;
1043 GDBusConnection *conn;
1044 GDBusProxy *manager_proxy;
1045 GVariant *result = NULL;
1046 GVariantIter *iter = NULL;
1048 conn = _bt_hal_get_system_gconn();
1052 manager_proxy = _bt_hal_get_manager_proxy();
1053 if (manager_proxy == NULL)
1056 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
1058 G_DBUS_CALL_FLAGS_NONE,
1063 ERR("Can't get managed objects");
1067 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
1068 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
1069 object_path = __bt_hal_extract_device_path(iter, address);
1070 g_variant_iter_free(iter);
1071 g_variant_unref(result);
1075 GVariant *_bt_hal_get_managed_objects(void)
1077 GDBusConnection *conn;
1078 GDBusProxy *manager_proxy;
1079 GVariant *result = NULL;
1080 GError *error = NULL;
1083 conn = _bt_hal_get_system_gconn();
1087 manager_proxy = _bt_hal_get_manager_proxy();
1088 if (manager_proxy == NULL)
1091 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
1093 G_DBUS_CALL_FLAGS_NONE,
1098 ERR("Can't get managed objects");
1103 ERR("Fail to get ManagedObjects (Error: %s)", error->message);
1104 g_clear_error(&error);
1111 char *_bt_hal_convert_error_to_string(int error)
1114 case BT_HAL_ERROR_CANCEL:
1116 case BT_HAL_ERROR_INVALID_PARAM:
1117 return "INVALID_PARAMETER";
1118 case BT_HAL_ERROR_INVALID_DATA:
1119 return "INVALID DATA";
1120 case BT_HAL_ERROR_MEMORY_ALLOCATION:
1121 case BT_HAL_ERROR_OUT_OF_MEMORY:
1122 return "OUT_OF_MEMORY";
1123 case BT_HAL_ERROR_TIMEOUT:
1125 case BT_HAL_ERROR_NO_RESOURCES:
1126 return "NO_RESOURCES";
1127 case BT_HAL_ERROR_INTERNAL:
1129 case BT_HAL_ERROR_NOT_SUPPORT:
1130 return "NOT_SUPPORT";
1131 case BT_HAL_ERROR_DEVICE_NOT_ENABLED:
1132 return "NOT_ENABLED";
1133 case BT_HAL_ERROR_DEVICE_ALREADY_ENABLED:
1134 return "ALREADY_ENABLED";
1135 case BT_HAL_ERROR_DEVICE_BUSY:
1136 return "DEVICE_BUSY";
1137 case BT_HAL_ERROR_ACCESS_DENIED:
1138 return "ACCESS_DENIED";
1139 case BT_HAL_ERROR_MAX_CLIENT:
1140 return "MAX_CLIENT";
1141 case BT_HAL_ERROR_NOT_FOUND:
1143 case BT_HAL_ERROR_SERVICE_SEARCH_ERROR:
1144 return "SERVICE_SEARCH_ERROR";
1145 case BT_HAL_ERROR_PARING_FAILED:
1146 return "PARING_FAILED";
1147 case BT_HAL_ERROR_NOT_PAIRED:
1148 return "NOT_PAIRED";
1149 case BT_HAL_ERROR_SERVICE_NOT_FOUND:
1150 return "SERVICE_NOT_FOUND";
1151 case BT_HAL_ERROR_NOT_CONNECTED:
1152 return "NOT_CONNECTED";
1153 case BT_HAL_ERROR_ALREADY_CONNECT:
1154 return "ALREADY_CONNECT";
1155 case BT_HAL_ERROR_CONNECTION_BUSY:
1156 return "CONNECTION_BUSY";
1157 case BT_HAL_ERROR_CONNECTION_ERROR:
1158 return "CONNECTION_ERROR";
1159 case BT_HAL_ERROR_MAX_CONNECTION:
1160 return "MAX_CONNECTION";
1161 case BT_HAL_ERROR_NOT_IN_OPERATION:
1162 return "NOT_IN_OPERATION";
1163 case BT_HAL_ERROR_CANCEL_BY_USER:
1164 return "CANCEL_BY_USER";
1165 case BT_HAL_ERROR_REGISTRATION_FAILED:
1166 return "REGISTRATION_FAILED";
1167 case BT_HAL_ERROR_IN_PROGRESS:
1168 return "IN_PROGRESS";
1169 case BT_HAL_ERROR_AUTHENTICATION_FAILED:
1170 return "AUTHENTICATION_FAILED";
1171 case BT_HAL_ERROR_HOST_DOWN:
1173 case BT_HAL_ERROR_END_OF_DEVICE_LIST:
1174 return "END_OF_DEVICE_LIST";
1175 case BT_HAL_ERROR_AGENT_ALREADY_EXIST:
1176 return "AGENT_ALREADY_EXIST";
1177 case BT_HAL_ERROR_AGENT_DOES_NOT_EXIST:
1178 return "AGENT_DOES_NOT_EXIST";
1179 case BT_HAL_ERROR_ALREADY_INITIALIZED:
1180 return "ALREADY_INITIALIZED";
1181 case BT_HAL_ERROR_PERMISSION_DEINED:
1182 return "PERMISSION_DEINED";
1183 case BT_HAL_ERROR_ALREADY_DEACTIVATED:
1184 return "ALREADY_DEACTIVATED";
1185 case BT_HAL_ERROR_NOT_INITIALIZED:
1186 return "NOT_INITIALIZED";
1192 char * _bt_hal_convert_disc_reason_to_string(int reason)
1198 return "Connection terminated by local host";
1200 return "Remote user terminated connection";
1207 void _bt_hal_logging_connection(gboolean connect, int addr_type)
1209 static int le_conn = 0;
1210 static int le_disc = 0;
1211 static int edr_conn = 0;
1212 static int edr_disc = 0;
1226 INFO("[PM] Number of LE conn: %d disc: %d, Number of BR/EDR conn: %d disc: %d",
1227 le_conn, le_disc, edr_conn, edr_disc);
1230 void _bt_hal_swap_byte_ordering(char *data, int data_len)
1237 /* Swap to opposite endian */
1238 for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
1245 int _bt_hal_byte_arr_cmp(const char *data1, const char *data2, int data_len)
1249 if (data1 == NULL || data2 == NULL)
1251 for (i = 0; i < data_len; i++) {
1252 if (data1[i] != data2[i])
1253 return data1[i] - data2[i];
1257 int _bt_hal_byte_arr_cmp_with_mask(const char *data1, const char *data2,
1258 const char *mask, int data_len)
1263 if (data1 == NULL || data2 == NULL || mask == NULL)
1266 for (i = 0; i < data_len; i++) {
1267 a = data1[i] & mask[i];
1268 b = data2[i] & mask[i];
1270 return (int)(a - b);
1275 int _bt_hal_connect_profile(char *address, char *uuid,
1276 void *cb, gpointer func_data)
1280 GDBusConnection *conn;
1281 GDBusProxy *adapter_proxy;
1282 GError *error = NULL;
1284 conn = _bt_hal_get_system_gconn();
1286 return BT_HAL_ERROR_INTERNAL;
1288 object_path = _bt_hal_get_device_object_path(address);
1289 if (object_path == NULL) {
1290 ERR("No searched device");
1292 adapter_proxy = _bt_hal_get_adapter_proxy();
1293 if (adapter_proxy == NULL)
1294 return BT_HAL_ERROR_INTERNAL;
1296 g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1297 g_variant_new("(s)", address),
1298 G_DBUS_CALL_FLAGS_NONE,
1303 if (error != NULL) {
1304 ERR("CreateDevice Fail: %s", error->message);
1305 g_error_free(error);
1308 object_path = _bt_hal_get_device_object_path(address);
1310 if (object_path == NULL)
1311 return BT_HAL_ERROR_INTERNAL;
1313 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1314 NULL, BT_HAL_BLUEZ_NAME,
1315 object_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1316 g_free(object_path);
1318 return BT_HAL_ERROR_INTERNAL;
1321 g_dbus_proxy_call(proxy, "ConnectProfile",
1322 g_variant_new("(s)", uuid),
1323 G_DBUS_CALL_FLAGS_NONE,
1324 BT_HAL_MAX_DBUS_TIMEOUT,
1326 (GAsyncReadyCallback)cb,
1329 return BT_HAL_ERROR_NONE;
1332 int _bt_hal_disconnect_profile(char *address, char *uuid,
1333 void *cb, gpointer func_data)
1337 GDBusConnection *conn;
1339 conn = _bt_hal_get_system_gconn();
1341 return BT_HAL_ERROR_INTERNAL;
1343 object_path = _bt_hal_get_device_object_path(address);
1344 if (object_path == NULL)
1345 return BT_HAL_ERROR_INTERNAL;
1347 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1348 NULL, BT_HAL_BLUEZ_NAME,
1349 object_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1350 g_free(object_path);
1352 return BT_HAL_ERROR_INTERNAL;
1354 g_dbus_proxy_call(proxy, "DisconnectProfile",
1355 g_variant_new("(s)", uuid),
1356 G_DBUS_CALL_FLAGS_NONE,
1357 BT_HAL_MAX_DBUS_TIMEOUT,
1359 (GAsyncReadyCallback)cb,
1362 return BT_HAL_ERROR_NONE;
1365 int _bt_hal_register_profile(bt_hal_register_profile_info_t *info, gboolean use_default_rfcomm)
1367 GVariantBuilder *option_builder;
1371 int result = BT_STATUS_SUCCESS;
1373 proxy = _bt_hal_get_profile_proxy();
1374 if (proxy == NULL) {
1375 ERR("Getting profile proxy failed");
1376 return BT_STATUS_FAIL;
1379 option_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1380 if (info->authentication)
1381 g_variant_builder_add(option_builder, "{sv}",
1382 "RequireAuthentication",
1383 g_variant_new_boolean(TRUE));
1384 if (info->authorization)
1385 g_variant_builder_add(option_builder, "{sv}",
1386 "RequireAuthorization",
1387 g_variant_new_boolean(TRUE));
1389 g_variant_builder_add(option_builder, "{sv}",
1391 g_variant_new_string(info->role));
1394 * Setting RFCOMM channel to default value 0; would allow bluez to assign
1395 * RFCOMM channels based on the availability when two services want to use
1396 * the RFCOMM along with SPP. Hence bluez makes sure that no two services
1397 * use the same SPP RFCOMM channel.
1399 if (use_default_rfcomm)
1400 g_variant_builder_add(option_builder, "{sv}",
1402 g_variant_new_uint16(RFCOMM_DEFAULT_PROFILE_CHANNEL));
1404 g_variant_builder_add(option_builder, "{sv}",
1406 g_variant_new_string(info->service));
1408 ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile",
1409 g_variant_new("(osa{sv})", info->obj_path,
1412 G_DBUS_CALL_FLAGS_NONE, -1,
1415 ERR("RegisterProfile failed: %s", err->message);
1417 if (g_strrstr(err->message, BT_HAL_ACCESS_DENIED_MSG))
1418 result = BT_STATUS_AUTH_REJECTED;
1420 result = BT_STATUS_FAIL;
1422 g_clear_error(&err);
1425 g_variant_builder_unref(option_builder);
1428 g_variant_unref(ret);
1433 void _bt_hal_unregister_profile(char *path)
1439 proxy = _bt_hal_get_profile_proxy();
1440 if (proxy == NULL) {
1441 ERR("Getting profile proxy failed");
1445 ret = g_dbus_proxy_call_sync(proxy, "UnregisterProfile",
1446 g_variant_new("(o)", path),
1447 G_DBUS_CALL_FLAGS_NONE, -1,
1450 ERR("UnregisterProfile failed : %s", err->message);
1451 g_clear_error(&err);
1455 g_variant_unref(ret);
1460 static void __hal_new_connection_method(GDBusConnection *connection,
1461 const gchar *sender,
1462 const gchar *object_path,
1463 const gchar *interface_name,
1464 const gchar *method_name,
1465 GVariant *parameters,
1466 GDBusMethodInvocation *invocation,
1469 DBG("method %s", method_name);
1470 if (g_strcmp0(method_name, "NewConnection") == 0) {
1473 GUnixFDList *fd_list;
1475 GVariantBuilder *properties;
1477 bt_bdaddr_t remote_addr1;
1478 char addr[BT_HAL_ADDRESS_STRING_SIZE];
1479 bt_hal_new_connection_cb cb = user_data;
1481 g_variant_get(parameters, "(oha{sv})", &obj_path, &index,
1484 msg = g_dbus_method_invocation_get_message(invocation);
1485 fd_list = g_dbus_message_get_unix_fd_list(msg);
1486 if (fd_list == NULL) {
1487 GQuark quark = g_quark_from_string("rfcomm-app");
1488 GError *err = g_error_new(quark, 0, "No fd in message");
1489 g_dbus_method_invocation_return_gerror(invocation, err);
1495 fd = g_unix_fd_list_get(fd_list, index, NULL);
1497 ERR("Invalid fd return");
1498 GQuark quark = g_quark_from_string("rfcomm-app");
1499 GError *err = g_error_new(quark, 0, "Invalid FD return");
1500 g_dbus_method_invocation_return_gerror(invocation, err);
1504 INFO("Object Path %s", obj_path);
1506 _bt_hal_convert_device_path_to_address(obj_path, addr);
1507 _bt_hal_convert_addr_string_to_type(remote_addr1.address, (const char *)addr);
1508 INFO("fd: %d, address %s", fd, addr);
1510 g_dbus_method_invocation_return_value(invocation, NULL);
1513 cb(object_path, fd, &remote_addr1);
1516 } else if (g_strcmp0(method_name, "RequestDisconnection") == 0) {
1517 g_dbus_method_invocation_return_value(invocation, NULL);
1521 static GDBusNodeInfo *_bt_hal_get_gdbus_node(const gchar *xml_data)
1524 char *name = g_strdup_printf("org.bt.frwk.p%d", getpid());
1526 bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1528 G_BUS_NAME_OWNER_FLAGS_NONE,
1534 DBG("Got bus id %d", bus_id);
1538 return g_dbus_node_info_new_for_xml(xml_data, NULL);
1541 static const GDBusInterfaceVTable method_table = {
1542 __hal_new_connection_method,
1547 int _bt_hal_register_new_gdbus_object(const char *path, bt_hal_new_connection_cb cb)
1549 GDBusConnection *gconn;
1551 GError *error = NULL;
1553 gconn = _bt_hal_get_system_gconn();
1557 if (new_conn_node == NULL)
1558 new_conn_node = _bt_hal_get_gdbus_node(rfcomm_agent_xml);
1560 if (new_conn_node == NULL)
1563 id = g_dbus_connection_register_object(gconn, path,
1564 new_conn_node->interfaces[0],
1568 ERR("Failed to register: %s", error->message);
1569 g_error_free(error);
1573 DBG("NEW CONNECTION ID %d", id);
1578 void _bt_hal_unregister_gdbus_object(int object_id)
1580 GDBusConnection *gconn;
1582 gconn = _bt_hal_get_system_gconn();
1586 g_dbus_connection_unregister_object(gconn, object_id);
1589 int _bt_hal_discover_services(char *address, char *uuid, void *cb, gpointer func_data)
1593 GDBusProxy *adapter_proxy;
1595 GDBusConnection *conn;
1597 conn = _bt_hal_get_system_gconn();
1599 ERR("conn == NULL, return");
1600 return BT_STATUS_FAIL;
1603 object_path = _bt_hal_get_device_object_path(address);
1604 if (object_path == NULL) {
1605 GVariant *ret = NULL;
1607 INFO("No searched device");
1608 adapter_proxy = _bt_hal_get_adapter_proxy();
1609 if (adapter_proxy == NULL) {
1610 ERR("adapter_proxy == NULL, return");
1611 return BT_STATUS_FAIL;
1614 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1615 g_variant_new("(s)", address),
1616 G_DBUS_CALL_FLAGS_NONE,
1617 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1620 ERR("CreateDevice Failed: %s", err->message);
1621 g_clear_error(&err);
1625 g_variant_unref(ret);
1627 g_object_unref(adapter_proxy);
1628 object_path = _bt_hal_get_device_object_path(address);
1629 if (object_path == NULL) {
1630 ERR("object_path == NULL, return");
1631 return BT_STATUS_FAIL;
1635 proxy = g_dbus_proxy_new_sync(conn,
1636 G_DBUS_PROXY_FLAGS_NONE, NULL,
1637 BT_HAL_BLUEZ_NAME, object_path,
1638 BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1639 g_free(object_path);
1640 if (proxy == NULL) {
1641 ERR("Error while getting proxy");
1642 return BT_STATUS_FAIL;
1645 g_dbus_proxy_call(proxy, "DiscoverServices",
1646 g_variant_new("(s)", uuid),
1647 G_DBUS_CALL_FLAGS_NONE,
1648 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1649 (GAsyncReadyCallback)cb,
1652 return BT_STATUS_SUCCESS;
1655 int _bt_hal_cancel_discovers(char *address)
1659 GDBusProxy *adapter_proxy;
1661 GDBusConnection *conn;
1663 conn = _bt_hal_get_system_gconn();
1665 return BT_STATUS_FAIL;
1667 object_path = _bt_hal_get_device_object_path(address);
1668 if (object_path == NULL) {
1669 GVariant *ret = NULL;
1670 INFO("No searched device");
1671 adapter_proxy = _bt_hal_get_adapter_proxy();
1672 if (adapter_proxy == NULL) {
1673 ERR("adapter_proxy == NULL, return");
1674 return BT_STATUS_FAIL;
1677 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1678 g_variant_new("(s)", address),
1679 G_DBUS_CALL_FLAGS_NONE,
1680 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1683 ERR("CreateDevice Failed: %s", err->message);
1684 g_clear_error(&err);
1688 g_variant_unref(ret);
1690 g_object_unref(adapter_proxy);
1692 object_path = _bt_hal_get_device_object_path(address);
1693 if (object_path == NULL)
1694 return BT_STATUS_FAIL;
1697 proxy = g_dbus_proxy_new_sync(conn,
1698 G_DBUS_PROXY_FLAGS_NONE, NULL,
1699 BT_HAL_BLUEZ_NAME, object_path,
1700 BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1701 g_free(object_path);
1702 g_dbus_proxy_call_sync(proxy, "CancelDiscovery",
1704 G_DBUS_CALL_FLAGS_NONE,
1705 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1708 ERR("DBus Error message: [%s]", err->message);
1709 g_clear_error(&err);
1710 return BT_STATUS_FAIL;
1714 g_object_unref(proxy);
1716 return BT_STATUS_SUCCESS;
1719 int _bt_hal_discover_service_uuids(char *address, char *remote_uuid)
1723 GDBusConnection *gconn;
1725 char **uuid_value = NULL;
1728 GVariant *value = NULL;
1729 GVariant *ret = NULL;
1730 int result = BT_STATUS_FAIL;
1734 if (remote_uuid == NULL) {
1735 ERR("remote_uuid == NULL, return");
1736 return BT_STATUS_FAIL;
1739 gconn = _bt_hal_get_system_gconn();
1740 if (gconn == NULL) {
1741 ERR("gconn == NULL, return");
1742 return BT_STATUS_FAIL;
1745 object_path = _bt_hal_get_device_object_path(address);
1746 if (object_path == NULL) {
1747 ERR("object_path == NULL, return");
1748 return BT_STATUS_FAIL;
1751 proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE, NULL,
1752 BT_HAL_BLUEZ_NAME, object_path, BT_HAL_PROPERTIES_INTERFACE, NULL,
1754 if (proxy == NULL) {
1755 g_free(object_path);
1756 ERR("proxy == NULL, return");
1757 return BT_STATUS_FAIL;
1761 ERR("DBus Error: [%s]", err->message);
1762 g_clear_error(&err);
1765 ret = g_dbus_proxy_call_sync(proxy, "GetAll",
1766 g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
1767 G_DBUS_CALL_FLAGS_NONE,
1768 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1771 result = BT_STATUS_FAIL;
1772 ERR("DBus Error : %s", err->message);
1773 g_clear_error(&err);
1778 ERR("g_dbus_proxy_call_sync function return NULL");
1779 result = BT_STATUS_FAIL;
1783 g_variant_get(ret, "(@a{sv})", &value);
1784 g_variant_unref(ret);
1786 GVariant *temp_value = g_variant_lookup_value(value, "UUIDs",
1787 G_VARIANT_TYPE_STRING_ARRAY);
1790 size = g_variant_get_size(temp_value);
1793 uuid_value = (char **)g_variant_get_strv(temp_value, &size);
1794 DBG("Size items %zu", size);
1798 g_variant_unref(temp_value);
1801 for (i = 0; uuid_value[i] != NULL; i++) {
1802 DBG("Remote uuids %s, searched uuid: %s",
1803 uuid_value[i], remote_uuid);
1804 if (strcasecmp(uuid_value[i], remote_uuid) == 0) {
1805 result = BT_STATUS_SUCCESS;
1814 g_object_unref(proxy);
1816 g_variant_unref(value);
1824 int bt_hal_gatt_convert_prop2string(
1825 bt_hal_gatt_characteristic_property_t properties,
1826 char *char_properties[])
1830 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_BROADCAST) {
1831 char_properties[flag_count] = g_strdup("broadcast");
1834 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_READ) {
1835 char_properties[flag_count] = g_strdup("read");
1838 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE) {
1839 char_properties[flag_count] = g_strdup("write-without-response");
1842 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE) {
1843 char_properties[flag_count] = g_strdup("write");
1846 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY) {
1847 char_properties[flag_count] = g_strdup("notify");
1850 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE) {
1851 char_properties[flag_count] = g_strdup("indicate");
1854 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE) {
1855 char_properties[flag_count] = g_strdup("authenticated-signed-writes");
1858 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE) {
1859 char_properties[flag_count] = g_strdup("reliable-write");
1862 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES) {
1863 char_properties[flag_count] = g_strdup("writable-auxiliaries");
1866 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ) {
1867 char_properties[flag_count] = g_strdup("encrypt-read");
1870 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE) {
1871 char_properties[flag_count] = g_strdup("encrypt-write");
1874 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ) {
1875 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
1878 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE) {
1879 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
1883 if (flag_count == 0) {
1884 char_properties[flag_count] = g_strdup("read");
1891 int bt_hal_gatt_convert_perm2string(
1892 bt_hal_gatt_permission_t properties,
1893 char *char_properties[])
1897 if (properties & BT_HAL_GATT_PERMISSION_READ) {
1898 char_properties[flag_count] = g_strdup("read");
1901 if (properties & BT_HAL_GATT_PERMISSION_WRITE) {
1902 char_properties[flag_count] = g_strdup("write");
1905 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_READ) {
1906 char_properties[flag_count] = g_strdup("encrypt-read");
1909 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_WRITE) {
1910 char_properties[flag_count] = g_strdup("encrypt-write");
1913 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_READ) {
1914 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
1917 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_WRITE) {
1918 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
1922 if (flag_count == 0) {
1923 char_properties[flag_count] = g_strdup("read");
1930 gboolean _bt_hal_is_service_enabled(const char *uuid)
1933 GError *error = NULL;
1936 GVariantIter *iter = NULL;
1938 gboolean ret = FALSE;
1942 proxy = _bt_hal_get_adapter_properties_proxy();
1944 DBG("_bt_hal_dbus_get_local_name: Adapter Properties proxy get failed!!!");
1948 result = g_dbus_proxy_call_sync(proxy,
1949 "Get", g_variant_new("(ss)",
1950 BT_HAL_ADAPTER_INTERFACE, "UUIDs"),
1951 G_DBUS_CALL_FLAGS_NONE, -1,
1954 if (error != NULL) {
1955 ERR("Failed to get UUIDs (Error: %s)", error->message);
1956 g_clear_error(&error);
1958 ERR("Failed to get UUIDs");
1962 g_variant_get(result, "(v)", &temp);
1963 g_variant_get(temp, "as", &iter);
1965 ERR("Failed to get UUIDs");
1966 g_variant_unref(result);
1970 while (g_variant_iter_loop(iter, "s", &uuid_str)) {
1971 DBG("UUID string [%s]\n", uuid_str);
1972 if (!strncasecmp(uuid, uuid_str, strlen(uuid))) {
1978 g_variant_iter_free(iter);
1979 g_variant_unref(result);
1980 g_variant_unref(temp);