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
54 static char *avrcp_control_path = NULL;
55 static char *avrcp_transport_path = NULL;
57 static GDBusConnection *system_conn;
58 static GDBusConnection *session_conn;
59 static GDBusProxy *manager_gproxy = NULL;
60 static GDBusProxy *adapter_gproxy = NULL;
61 static GDBusProxy *profile_gproxy = NULL;
63 static GDBusProxy *adapter_properties_proxy;
64 static GDBusProxy *avrcp_ctrl_proxy;
66 static GDBusConnection *system_gconn = NULL;
69 GDBusNodeInfo *new_conn_node;
70 static const gchar rfcomm_agent_xml[] =
72 " <interface name='org.bluez.Profile1'>"
73 " <method name='NewConnection'>"
74 " <arg type='o' name='object' direction='in'/>"
75 " <arg type='h' name='fd' direction='in'/>"
76 " <arg type='a{sv}' name='properties' direction='in'/>"
78 " <method name='RequestDisconnection'>"
79 " <arg type='o' name='device' direction='in'/>"
84 GDBusConnection *_bt_hal_gdbus_init_system_gconn(void)
88 if (system_gconn != NULL)
91 system_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
94 ERR("Unable to connect to dbus: %s", error->message);
95 g_clear_error(&error);
101 GDBusConnection *_bt_hal_gdbus_get_system_gconn(void)
103 GDBusConnection *local_system_gconn = NULL;
104 GError *error = NULL;
106 if (system_gconn == NULL) {
107 system_gconn = _bt_hal_gdbus_init_system_gconn();
108 } else if (g_dbus_connection_is_closed(system_gconn)) {
110 local_system_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
112 if (!local_system_gconn) {
113 ERR("Unable to connect to dbus: %s", error->message);
114 g_clear_error(&error);
117 system_gconn = local_system_gconn;
123 static GDBusProxy *__bt_hal_init_manager_proxy(void)
129 if (system_conn == NULL) {
130 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
131 if (system_conn == NULL)
135 proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
136 NULL, BT_HAL_BLUEZ_NAME,
137 BT_HAL_MANAGER_PATH, BT_HAL_MANAGER_INTERFACE, NULL, NULL);
142 manager_gproxy = proxy;
148 static GDBusProxy *__bt_hal_init_adapter_proxy(void)
150 GDBusProxy *manager_proxy;
152 char *adapter_path = NULL;
154 if (system_conn == NULL) {
155 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
156 if (system_conn == NULL)
160 manager_proxy = _bt_hal_get_manager_proxy();
161 if (manager_proxy == NULL)
164 adapter_path = _bt_hal_get_adapter_path();
165 if (adapter_path == NULL)
168 proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
169 NULL, BT_HAL_BLUEZ_NAME,
170 adapter_path, BT_HAL_ADAPTER_INTERFACE, NULL, NULL);
172 g_free(adapter_path);
177 adapter_gproxy = proxy;
182 static GDBusProxy *__bt_hal_init_adapter_properties_proxy(void)
184 GDBusProxy *manager_proxy;
186 char *adapter_path = NULL;
188 if (system_conn == NULL) {
189 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
190 if (system_conn == NULL)
194 manager_proxy = _bt_hal_get_manager_proxy();
195 if (manager_proxy == NULL)
198 adapter_path = _bt_hal_get_adapter_path();
199 if (adapter_path == NULL)
202 proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
203 NULL, BT_HAL_BLUEZ_NAME,
204 adapter_path, BT_HAL_PROPERTIES_INTERFACE, NULL, NULL);
206 g_free(adapter_path);
211 adapter_properties_proxy = proxy;
216 void _bt_hal_set_control_device_path(const char *path)
222 g_free(avrcp_control_path);
223 DBG("control_path = %s", path);
224 avrcp_control_path = g_strdup(path);
227 void _bt_hal_remove_control_device_path(const char *path)
232 if (avrcp_control_path &&
233 !g_strcmp0(avrcp_control_path, path)) {
234 DBG("control_path = %s", path);
235 g_free(avrcp_control_path);
236 avrcp_control_path = NULL;
240 static char *__bt_hal_extract_control_device_path(GVariantIter *iter, char *address)
242 char *object_path = NULL;
243 char *interface_str = NULL;
244 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
246 /* Parse the signature: oa{sa{sv}}} */
247 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_str)) {
248 if (object_path == NULL)
251 if (g_strcmp0(interface_str, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
252 _bt_hal_convert_device_path_to_address(object_path, device_address);
253 if (g_strcmp0(address, device_address) == 0)
254 return g_strdup(object_path);
260 static char *__bt_hal_extract_transport_device_path(GVariantIter *iter, char *address)
262 char *object_path = NULL;
263 char *interface_str = NULL;
264 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
266 /* Parse the signature: oa{sa{sv}}} */
267 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_str)) {
268 if (object_path == NULL)
271 if (g_strcmp0(interface_str, BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
272 _bt_hal_convert_device_path_to_address(object_path, device_address);
273 if (g_strcmp0(address, device_address) == 0)
274 return g_strdup(object_path);
280 static char *__bt_hal_get_control_device_object_path(char *address)
282 char *object_path = NULL;
283 GDBusConnection *conn;
284 GDBusProxy *manager_proxy;
285 GVariant *result = NULL;
286 GVariantIter *iter = NULL;
288 conn = _bt_hal_get_system_gconn();
292 manager_proxy = _bt_hal_get_manager_proxy();
293 if (manager_proxy == NULL)
296 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
298 G_DBUS_CALL_FLAGS_NONE,
303 ERR("Can't get managed objects");
307 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
308 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
309 object_path = __bt_hal_extract_control_device_path(iter, address);
310 g_variant_iter_free(iter);
311 g_variant_unref(result);
315 static char *__bt_hal_get_transport_device_object_path(char *address)
317 char *object_path = NULL;
318 GDBusConnection *conn;
319 GDBusProxy *manager_proxy;
320 GVariant *result = NULL;
321 GVariantIter *iter = NULL;
323 conn = _bt_hal_get_system_gconn();
327 manager_proxy = _bt_hal_get_manager_proxy();
328 if (manager_proxy == NULL)
331 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
333 G_DBUS_CALL_FLAGS_NONE,
338 ERR("Can't get managed objects");
342 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
343 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
344 object_path = __bt_hal_extract_transport_device_path(iter, address);
345 g_variant_iter_free(iter);
346 g_variant_unref(result);
350 char *_bt_hal_get_control_device_path(bt_bdaddr_t *bd_addr)
353 char connected_address[BT_HAL_ADDRESS_STRING_SIZE];
357 if (avrcp_control_path != NULL)
358 return avrcp_control_path;
360 _bt_hal_convert_addr_type_to_string(connected_address, bd_addr->address);
362 DBG("device address = %s", connected_address);
364 control_path = __bt_hal_get_control_device_object_path(connected_address);
365 if (control_path == NULL)
368 avrcp_control_path = control_path;
369 DBG("control_path = %s", control_path);
373 char *_bt_hal_get_transport_device_path(bt_bdaddr_t *bd_addr)
375 char *transport_path;
376 char connected_address[BT_HAL_ADDRESS_STRING_SIZE];
380 if (avrcp_transport_path != NULL)
381 return avrcp_transport_path;
383 _bt_hal_convert_addr_type_to_string(connected_address, bd_addr->address);
385 DBG("device address = %s", connected_address);
387 transport_path = __bt_hal_get_transport_device_object_path(connected_address);
388 if (transport_path == NULL)
391 avrcp_transport_path = transport_path;
392 DBG("transport_path = %s", transport_path);
393 return transport_path;
396 static GDBusConnection *__bt_hal_init_system_gconn(void)
398 if (system_conn == NULL)
399 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
404 static GDBusProxy *__bt_hal_init_avrcp_ctrl_proxy(bt_bdaddr_t *bd_addr)
406 GDBusProxy *manager_proxy;
408 char *control_path = NULL;
410 if (system_conn == NULL) {
411 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
412 if (system_conn == NULL)
416 manager_proxy = _bt_hal_get_manager_proxy();
417 if (manager_proxy == NULL)
420 control_path = _bt_hal_get_control_device_path(bd_addr);
421 if (control_path == NULL)
424 proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
425 NULL, BT_HAL_BLUEZ_NAME,
426 control_path, BT_HAL_PLAYER_CONTROL_INTERFACE, NULL, NULL);
431 avrcp_ctrl_proxy = proxy;
435 static GDBusConnection *__bt_hal_init_session_conn(void)
437 if (session_conn == NULL)
438 session_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
443 GDBusConnection *_bt_hal_get_session_gconn(void)
445 return (session_conn) ? session_conn : __bt_hal_init_session_conn();
448 GDBusConnection *_bt_hal_get_system_gconn(void)
450 return (system_conn) ? system_conn : __bt_hal_init_system_gconn();
453 GDBusProxy *_bt_hal_get_manager_proxy(void)
456 if (manager_gproxy) {
457 const gchar *path = g_dbus_proxy_get_object_path(manager_gproxy);
459 ERR("Already proxy released hence creating new proxy");
460 return __bt_hal_init_manager_proxy();
462 return manager_gproxy;
465 return __bt_hal_init_manager_proxy();
468 GDBusProxy *_bt_hal_get_adapter_proxy(void)
470 if (adapter_gproxy) {
471 const char *path = g_dbus_proxy_get_object_path(adapter_gproxy);
473 ERR("Already proxy released hence creating new proxy");
474 return __bt_hal_init_adapter_proxy();
477 return adapter_gproxy;
479 return __bt_hal_init_adapter_proxy();
483 GDBusProxy *_bt_hal_get_avrcp_ctrl_proxy(bt_bdaddr_t *bd_addr)
485 if (avrcp_ctrl_proxy) {
486 const char *path = g_dbus_proxy_get_object_path(avrcp_ctrl_proxy);
488 ERR("Already proxy released hence creating new proxy");
489 return __bt_hal_init_avrcp_ctrl_proxy(bd_addr);
492 return avrcp_ctrl_proxy;
494 return __bt_hal_init_avrcp_ctrl_proxy(bd_addr);
498 GDBusProxy *_bt_hal_get_avrcp_ctrl_properties_proxy(bt_bdaddr_t *bd_addr)
501 GError *error = NULL;
502 char *control_path = NULL;
503 GDBusConnection *conn = NULL;
506 control_path = _bt_hal_get_control_device_path(bd_addr);
507 if (control_path == NULL)
510 DBG("control_path = %s", control_path);
512 conn = _bt_hal_get_system_gconn();
514 ERR("FAIL to get system connection");
517 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
518 NULL, BT_HAL_BLUEZ_NAME,
519 control_path, BT_HAL_PROPERTIES_INTERFACE, NULL, &error);
522 ERR("Unable to allocate new proxy");
524 ERR("%s", error->message);
525 g_clear_error(&error);
534 GDBusProxy *_bt_hal_get_avrcp_transport_properties_proxy(bt_bdaddr_t *bd_addr)
537 GError *error = NULL;
538 char *transport_path = NULL;
539 GDBusConnection *conn = NULL;
542 transport_path = _bt_hal_get_transport_device_path(bd_addr);
543 if (transport_path == NULL)
546 DBG("transport_path = %s", transport_path);
548 conn = _bt_hal_get_system_gconn();
550 ERR("FAIL to get system connection");
553 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
554 NULL, BT_HAL_BLUEZ_NAME,
555 transport_path, BT_HAL_PROPERTIES_INTERFACE, NULL, &error);
558 ERR("Unable to allocate new proxy");
560 ERR("%s", error->message);
561 g_clear_error(&error);
570 GDBusProxy *_bt_hal_get_adapter_properties_proxy(void)
572 return (adapter_properties_proxy) ? adapter_properties_proxy :
573 __bt_hal_init_adapter_properties_proxy();
576 GDBusProxy *_bt_hal_get_profile_proxy(void)
578 GDBusConnection *gconn;
582 return profile_gproxy;
584 gconn = _bt_hal_get_system_gconn();
586 ERR("_bt_hal_get_system_gconn failed");
590 profile_gproxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE,
591 NULL, BT_HAL_BLUEZ_NAME,
593 "org.bluez.ProfileManager1",
596 ERR("Unable to create proxy: %s", err->message);
601 return profile_gproxy;
604 static char *__bt_hal_extract_adapter_path(GVariantIter *iter)
606 char *object_path = NULL;
607 GVariantIter *interface_iter;
608 GVariantIter *svc_iter;
609 char *interface_str = NULL;
611 /* Parse the signature: oa{sa{sv}}} */
612 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
615 if (object_path == NULL)
618 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
619 &interface_str, &svc_iter)) {
620 if (g_strcmp0(interface_str, "org.bluez.Adapter1") != 0)
623 DBG("Object Path: %s", object_path);
624 g_free(interface_str);
625 g_variant_iter_free(svc_iter);
626 g_variant_iter_free(interface_iter);
627 return g_strdup(object_path);
633 char *_bt_hal_get_adapter_path(void)
635 GDBusConnection *conn;
636 GDBusProxy *manager_proxy;
637 GVariant *result = NULL;
638 GVariantIter *iter = NULL;
639 char *adapter_path = NULL;
642 conn = _bt_hal_get_system_gconn();
646 manager_proxy = _bt_hal_get_manager_proxy();
647 if (manager_proxy == NULL)
650 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
652 G_DBUS_CALL_FLAGS_NONE,
657 ERR("Can't get managed objects");
661 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
662 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
664 adapter_path = __bt_hal_extract_adapter_path(iter);
665 g_variant_iter_free(iter);
666 g_variant_unref(result);
671 int _bt_hal_is_adapter_powered(gboolean *powered)
674 GError *error = NULL;
679 proxy = _bt_hal_get_adapter_properties_proxy();
681 return BT_STATUS_FAIL;
683 result = g_dbus_proxy_call_sync(proxy,
685 g_variant_new("(ss)", BT_HAL_ADAPTER_INTERFACE,
687 G_DBUS_CALL_FLAGS_NONE,
693 ERR("Failed to get powered status");
695 ERR("Failed to get powered status (Error: %s)", error->message);
696 g_clear_error(&error);
698 return BT_STATUS_FAIL;
701 g_variant_get(result, "(v)", &temp);
702 *powered = g_variant_get_boolean(temp);
703 INFO("powered: %d", *powered);
705 g_variant_unref(result);
706 g_variant_unref(temp);
707 return BT_STATUS_SUCCESS;
710 void _bt_hal_deinit_bluez_proxy(void)
712 if (manager_gproxy) {
713 g_object_unref(manager_gproxy);
714 manager_gproxy = NULL;
717 if (adapter_gproxy) {
718 g_object_unref(adapter_gproxy);
719 adapter_gproxy = NULL;
721 if (adapter_properties_proxy) {
722 g_object_unref(adapter_properties_proxy);
723 adapter_properties_proxy = NULL;
727 void _bt_hal_deinit_proxys(void)
729 _bt_hal_deinit_bluez_proxy();
732 g_object_unref(system_conn);
737 g_object_unref(session_conn);
742 void _bt_hal_convert_device_path_to_address(const char *device_path,
743 char *device_address)
745 char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
748 if (device_path == NULL || device_address == NULL)
751 dev_addr = strstr(device_path, "dev_");
752 if (dev_addr != NULL) {
755 g_strlcpy(address, dev_addr, sizeof(address));
757 while ((pos = strchr(address, '_')) != NULL)
760 g_strlcpy(device_address, address, BT_HAL_ADDRESS_STRING_SIZE);
764 gboolean _bt_hal_uuid_is_standard(bt_uuid_t *p_uuid)
766 uint32_t uuid0, uuid4;
767 uint16_t uuid1, uuid2, uuid3, uuid5;
768 const char *uuid_name;
769 const char *uuid_name1;
771 memcpy(&uuid0, &(p_uuid->uu[0]), 4);
772 memcpy(&uuid1, &(p_uuid->uu[4]), 2);
773 memcpy(&uuid2, &(p_uuid->uu[6]), 2);
774 memcpy(&uuid3, &(p_uuid->uu[8]), 2);
775 memcpy(&uuid4, &(p_uuid->uu[10]), 4);
776 memcpy(&uuid5, &(p_uuid->uu[14]), 2);
778 uuid_name = _bt_hal_dump_uuid_name(ntohl(uuid0));
779 uuid_name1 = _bt_hal_dump_uuid_name((ntohl(uuid4) >> 16));
781 DBG("UUID Name [%s]", uuid_name);
782 DBG("UUID Name Shifted [%s]", uuid_name1);
784 if (!g_strcmp0(uuid_name, "--"))
791 void _bt_hal_convert_uuid_string_to_type(unsigned char *uuid,
792 const char *device_uuid)
794 uint32_t uuid0, uuid4;
795 uint16_t uuid1, uuid2, uuid3, uuid5;
797 sscanf(device_uuid, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
798 &uuid0, &uuid1, &uuid2, &uuid3, &uuid4, &uuid5);
800 uuid0 = htonl(uuid0);
801 uuid1 = htons(uuid1);
802 uuid2 = htons(uuid2);
803 uuid3 = htons(uuid3);
804 uuid4 = htonl(uuid4);
805 uuid5 = htons(uuid5);
807 memcpy(&(uuid[0]), &uuid0, 4);
808 memcpy(&(uuid[4]), &uuid1, 2);
809 memcpy(&(uuid[6]), &uuid2, 2);
810 memcpy(&(uuid[8]), &uuid3, 2);
811 memcpy(&(uuid[10]), &uuid4, 4);
812 memcpy(&(uuid[14]), &uuid5, 2);
815 void _bt_hal_convert_uuid_type_to_string(char *str, const unsigned char *uuid)
827 snprintf(str, BT_HAL_UUID_STRING_LEN,
828 "%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",
829 uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
830 uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
833 void _bt_hal_convert_addr_string_to_type(unsigned char *addr,
839 if (address == NULL || addr == NULL)
842 for (i = 0; i < BT_HAL_ADDRESS_LENGTH_MAX; i++) {
843 addr[i] = strtol(address, &ptr, 16);
845 if (ptr[0] != '\0') {
854 void _bt_hal_convert_addr_type_to_string(char *address,
855 const unsigned char *addr)
857 if (address == NULL || addr == NULL)
860 snprintf(address, BT_HAL_ADDRESS_STRING_SIZE,
861 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
862 addr[0], addr[1], addr[2],
863 addr[3], addr[4], addr[5]);
866 void _bt_hal_print_device_address_t(const bt_hal_device_address_t *addr)
868 DBG("%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", addr->addr[0], addr->addr[1], addr->addr[2],
869 addr->addr[3], addr->addr[4], addr->addr[5]);
872 void _bt_hal_divide_device_class(bt_hal_device_class_t *device_class,
875 if (device_class == NULL)
878 device_class->major_class = (unsigned short)(cod & 0x00001F00) >> 8;
879 device_class->minor_class = (unsigned short)((cod & 0x000000FC));
880 device_class->service_class = (unsigned long)((cod & 0x00FF0000));
882 if (cod & 0x002000) {
883 device_class->service_class |=
884 BT_HAL_DEVICE_SERVICE_CLASS_LIMITED_DISCOVERABLE_MODE;
888 int _bt_hal_copy_utf8_string(char *dest, const char *src, unsigned int length)
895 if (dest == NULL || src == NULL)
896 return BT_HAL_ERROR_INVALID_PARAM;
898 DBG("+src : %s", src);
899 DBG("+dest : %s", dest);
902 while (*p != '\0' && i < length) {
903 next = g_utf8_next_char(p);
906 while (count > 0 && ((i + count) < length)) {
913 return BT_HAL_ERROR_NONE;
916 gboolean _bt_hal_utf8_validate(char *name)
920 glong items_written = 0;
922 if (FALSE == g_utf8_validate(name, -1, NULL))
925 u16 = g_utf8_to_utf16(name, -1, NULL, &items_written, NULL);
931 if (items_written != g_utf8_strlen(name, -1))
938 int _bt_hal_set_socket_non_blocking(int socket_fd)
940 /* Set Nonblocking */
943 arg = fcntl(socket_fd, F_GETFL);
948 if (arg & O_NONBLOCK)
949 ERR("Already Non-blocking \n");
953 if (fcntl(socket_fd, F_SETFL, arg) < 0)
956 return BT_HAL_ERROR_NONE;
959 int _bt_hal_set_non_blocking_tty(int sk)
961 struct termios ti = {0,};
964 err = _bt_hal_set_socket_non_blocking(sk);
967 ERR("Error in set non blocking!\n");
971 tcflush(sk, TCIOFLUSH);
973 /* Switch tty to RAW mode */
975 tcsetattr(sk, TCSANOW, &ti);
977 return BT_HAL_ERROR_NONE;
980 static char *__bt_hal_extract_device_path(GVariantIter *iter, char *address)
982 char *object_path = NULL;
983 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
985 /* Parse the signature: oa{sa{sv}}} */
986 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, NULL)) {
987 if (object_path == NULL)
989 _bt_hal_convert_device_path_to_address(object_path, device_address);
990 if (g_strcmp0(address, device_address) == 0)
991 return g_strdup(object_path);
996 char *_bt_hal_get_device_object_path(char *address)
998 char *object_path = NULL;
999 GDBusConnection *conn;
1000 GDBusProxy *manager_proxy;
1001 GVariant *result = NULL;
1002 GVariantIter *iter = NULL;
1004 conn = _bt_hal_get_system_gconn();
1008 manager_proxy = _bt_hal_get_manager_proxy();
1009 if (manager_proxy == NULL)
1012 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
1014 G_DBUS_CALL_FLAGS_NONE,
1019 ERR("Can't get managed objects");
1023 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
1024 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
1025 object_path = __bt_hal_extract_device_path(iter, address);
1026 g_variant_iter_free(iter);
1027 g_variant_unref(result);
1031 GVariant *_bt_hal_get_managed_objects(void)
1033 GDBusConnection *conn;
1034 GDBusProxy *manager_proxy;
1035 GVariant *result = NULL;
1036 GError *error = NULL;
1039 conn = _bt_hal_get_system_gconn();
1043 manager_proxy = _bt_hal_get_manager_proxy();
1044 if (manager_proxy == NULL)
1047 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
1049 G_DBUS_CALL_FLAGS_NONE,
1054 ERR("Can't get managed objects");
1059 ERR("Fail to get ManagedObjects (Error: %s)", error->message);
1060 g_clear_error(&error);
1067 char *_bt_hal_convert_error_to_string(int error)
1070 case BT_HAL_ERROR_CANCEL:
1072 case BT_HAL_ERROR_INVALID_PARAM:
1073 return "INVALID_PARAMETER";
1074 case BT_HAL_ERROR_INVALID_DATA:
1075 return "INVALID DATA";
1076 case BT_HAL_ERROR_MEMORY_ALLOCATION:
1077 case BT_HAL_ERROR_OUT_OF_MEMORY:
1078 return "OUT_OF_MEMORY";
1079 case BT_HAL_ERROR_TIMEOUT:
1081 case BT_HAL_ERROR_NO_RESOURCES:
1082 return "NO_RESOURCES";
1083 case BT_HAL_ERROR_INTERNAL:
1085 case BT_HAL_ERROR_NOT_SUPPORT:
1086 return "NOT_SUPPORT";
1087 case BT_HAL_ERROR_DEVICE_NOT_ENABLED:
1088 return "NOT_ENABLED";
1089 case BT_HAL_ERROR_DEVICE_ALREADY_ENABLED:
1090 return "ALREADY_ENABLED";
1091 case BT_HAL_ERROR_DEVICE_BUSY:
1092 return "DEVICE_BUSY";
1093 case BT_HAL_ERROR_ACCESS_DENIED:
1094 return "ACCESS_DENIED";
1095 case BT_HAL_ERROR_MAX_CLIENT:
1096 return "MAX_CLIENT";
1097 case BT_HAL_ERROR_NOT_FOUND:
1099 case BT_HAL_ERROR_SERVICE_SEARCH_ERROR:
1100 return "SERVICE_SEARCH_ERROR";
1101 case BT_HAL_ERROR_PARING_FAILED:
1102 return "PARING_FAILED";
1103 case BT_HAL_ERROR_NOT_PAIRED:
1104 return "NOT_PAIRED";
1105 case BT_HAL_ERROR_SERVICE_NOT_FOUND:
1106 return "SERVICE_NOT_FOUND";
1107 case BT_HAL_ERROR_NOT_CONNECTED:
1108 return "NOT_CONNECTED";
1109 case BT_HAL_ERROR_ALREADY_CONNECT:
1110 return "ALREADY_CONNECT";
1111 case BT_HAL_ERROR_CONNECTION_BUSY:
1112 return "CONNECTION_BUSY";
1113 case BT_HAL_ERROR_CONNECTION_ERROR:
1114 return "CONNECTION_ERROR";
1115 case BT_HAL_ERROR_MAX_CONNECTION:
1116 return "MAX_CONNECTION";
1117 case BT_HAL_ERROR_NOT_IN_OPERATION:
1118 return "NOT_IN_OPERATION";
1119 case BT_HAL_ERROR_CANCEL_BY_USER:
1120 return "CANCEL_BY_USER";
1121 case BT_HAL_ERROR_REGISTRATION_FAILED:
1122 return "REGISTRATION_FAILED";
1123 case BT_HAL_ERROR_IN_PROGRESS:
1124 return "IN_PROGRESS";
1125 case BT_HAL_ERROR_AUTHENTICATION_FAILED:
1126 return "AUTHENTICATION_FAILED";
1127 case BT_HAL_ERROR_HOST_DOWN:
1129 case BT_HAL_ERROR_END_OF_DEVICE_LIST:
1130 return "END_OF_DEVICE_LIST";
1131 case BT_HAL_ERROR_AGENT_ALREADY_EXIST:
1132 return "AGENT_ALREADY_EXIST";
1133 case BT_HAL_ERROR_AGENT_DOES_NOT_EXIST:
1134 return "AGENT_DOES_NOT_EXIST";
1135 case BT_HAL_ERROR_ALREADY_INITIALIZED:
1136 return "ALREADY_INITIALIZED";
1137 case BT_HAL_ERROR_PERMISSION_DEINED:
1138 return "PERMISSION_DEINED";
1139 case BT_HAL_ERROR_ALREADY_DEACTIVATED:
1140 return "ALREADY_DEACTIVATED";
1141 case BT_HAL_ERROR_NOT_INITIALIZED:
1142 return "NOT_INITIALIZED";
1148 char * _bt_hal_convert_disc_reason_to_string(int reason)
1154 return "Connection terminated by local host";
1156 return "Remote user terminated connection";
1163 int _bt_hal_convert_disc_reason_to_status(int reason)
1167 return BT_STATUS_CONN_TOUT; //"Link loss"
1169 return BT_STATUS_CONN_TERM_LOCAL_HOST; //"Connection terminated by local host";
1171 return BT_STATUS_CONN_TERM_RMT_HOST; //"Connection terminated by local host";
1174 return BT_STATUS_FAIL;
1178 void _bt_hal_logging_connection(gboolean connect, int addr_type)
1180 static int le_conn = 0;
1181 static int le_disc = 0;
1182 static int edr_conn = 0;
1183 static int edr_disc = 0;
1197 INFO("[PM] Number of LE conn: %d disc: %d, Number of BR/EDR conn: %d disc: %d",
1198 le_conn, le_disc, edr_conn, edr_disc);
1201 void _bt_hal_swap_byte_ordering(char *data, int data_len)
1208 /* Swap to opposite endian */
1209 for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
1216 int _bt_hal_byte_arr_cmp(const char *data1, const char *data2, int data_len)
1220 if (data1 == NULL || data2 == NULL)
1222 for (i = 0; i < data_len; i++) {
1223 if (data1[i] != data2[i])
1224 return data1[i] - data2[i];
1228 int _bt_hal_byte_arr_cmp_with_mask(const char *data1, const char *data2,
1229 const char *mask, int data_len)
1234 if (data1 == NULL || data2 == NULL || mask == NULL)
1237 for (i = 0; i < data_len; i++) {
1238 a = data1[i] & mask[i];
1239 b = data2[i] & mask[i];
1241 return (int)(a - b);
1246 int _bt_hal_connect_profile(char *address, char *uuid,
1247 void *cb, gpointer func_data)
1251 GDBusConnection *conn;
1252 GDBusProxy *adapter_proxy;
1253 GError *error = NULL;
1255 conn = _bt_hal_get_system_gconn();
1257 return BT_HAL_ERROR_INTERNAL;
1259 object_path = _bt_hal_get_device_object_path(address);
1260 if (object_path == NULL) {
1261 ERR("No searched device");
1263 adapter_proxy = _bt_hal_get_adapter_proxy();
1264 if (adapter_proxy == NULL)
1265 return BT_HAL_ERROR_INTERNAL;
1267 g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1268 g_variant_new("(s)", address),
1269 G_DBUS_CALL_FLAGS_NONE,
1274 if (error != NULL) {
1275 ERR("CreateDevice Fail: %s", error->message);
1276 g_error_free(error);
1279 object_path = _bt_hal_get_device_object_path(address);
1281 if (object_path == NULL)
1282 return BT_HAL_ERROR_INTERNAL;
1284 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1285 NULL, BT_HAL_BLUEZ_NAME,
1286 object_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1287 g_free(object_path);
1289 return BT_HAL_ERROR_INTERNAL;
1292 g_dbus_proxy_call(proxy, "ConnectProfile",
1293 g_variant_new("(s)", uuid),
1294 G_DBUS_CALL_FLAGS_NONE,
1295 BT_HAL_MAX_DBUS_TIMEOUT,
1297 (GAsyncReadyCallback)cb,
1300 return BT_HAL_ERROR_NONE;
1303 int _bt_hal_disconnect_profile(char *address, char *uuid,
1304 void *cb, gpointer func_data)
1308 GDBusConnection *conn;
1310 conn = _bt_hal_get_system_gconn();
1312 return BT_HAL_ERROR_INTERNAL;
1314 object_path = _bt_hal_get_device_object_path(address);
1315 if (object_path == NULL)
1316 return BT_HAL_ERROR_INTERNAL;
1318 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1319 NULL, BT_HAL_BLUEZ_NAME,
1320 object_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1321 g_free(object_path);
1323 return BT_HAL_ERROR_INTERNAL;
1325 g_dbus_proxy_call(proxy, "DisconnectProfile",
1326 g_variant_new("(s)", uuid),
1327 G_DBUS_CALL_FLAGS_NONE,
1328 BT_HAL_MAX_DBUS_TIMEOUT,
1330 (GAsyncReadyCallback)cb,
1333 return BT_HAL_ERROR_NONE;
1336 int _bt_hal_register_profile(bt_hal_register_profile_info_t *info, gboolean use_default_rfcomm)
1338 GVariantBuilder *option_builder;
1342 int result = BT_STATUS_SUCCESS;
1344 proxy = _bt_hal_get_profile_proxy();
1345 if (proxy == NULL) {
1346 ERR("Getting profile proxy failed");
1347 return BT_STATUS_FAIL;
1350 option_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1351 if (info->authentication)
1352 g_variant_builder_add(option_builder, "{sv}",
1353 "RequireAuthentication",
1354 g_variant_new_boolean(TRUE));
1355 if (info->authorization)
1356 g_variant_builder_add(option_builder, "{sv}",
1357 "RequireAuthorization",
1358 g_variant_new_boolean(TRUE));
1360 g_variant_builder_add(option_builder, "{sv}",
1362 g_variant_new_string(info->role));
1365 * Setting RFCOMM channel to default value 0; would allow bluez to assign
1366 * RFCOMM channels based on the availability when two services want to use
1367 * the RFCOMM along with SPP. Hence bluez makes sure that no two services
1368 * use the same SPP RFCOMM channel.
1370 if (use_default_rfcomm)
1371 g_variant_builder_add(option_builder, "{sv}",
1373 g_variant_new_uint16(RFCOMM_DEFAULT_PROFILE_CHANNEL));
1375 g_variant_builder_add(option_builder, "{sv}",
1377 g_variant_new_string(info->service));
1379 ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile",
1380 g_variant_new("(osa{sv})", info->obj_path,
1383 G_DBUS_CALL_FLAGS_NONE, -1,
1386 ERR("RegisterProfile failed: %s", err->message);
1388 if (g_strrstr(err->message, BT_HAL_ACCESS_DENIED_MSG))
1389 result = BT_STATUS_AUTH_REJECTED;
1391 result = BT_STATUS_FAIL;
1393 g_clear_error(&err);
1396 g_variant_builder_unref(option_builder);
1399 g_variant_unref(ret);
1404 void _bt_hal_unregister_profile(char *path)
1410 proxy = _bt_hal_get_profile_proxy();
1411 if (proxy == NULL) {
1412 ERR("Getting profile proxy failed");
1416 ret = g_dbus_proxy_call_sync(proxy, "UnregisterProfile",
1417 g_variant_new("(o)", path),
1418 G_DBUS_CALL_FLAGS_NONE, -1,
1421 ERR("UnregisterProfile failed : %s", err->message);
1422 g_clear_error(&err);
1426 g_variant_unref(ret);
1431 static void __hal_new_connection_method(GDBusConnection *connection,
1432 const gchar *sender,
1433 const gchar *object_path,
1434 const gchar *interface_name,
1435 const gchar *method_name,
1436 GVariant *parameters,
1437 GDBusMethodInvocation *invocation,
1440 DBG("method %s", method_name);
1441 if (g_strcmp0(method_name, "NewConnection") == 0) {
1444 GUnixFDList *fd_list;
1446 GVariantBuilder *properties;
1448 bt_bdaddr_t remote_addr1;
1449 char addr[BT_HAL_ADDRESS_STRING_SIZE];
1450 bt_hal_new_connection_cb cb = user_data;
1452 g_variant_get(parameters, "(oha{sv})", &obj_path, &index,
1455 msg = g_dbus_method_invocation_get_message(invocation);
1456 fd_list = g_dbus_message_get_unix_fd_list(msg);
1457 if (fd_list == NULL) {
1458 GQuark quark = g_quark_from_string("rfcomm-app");
1459 GError *err = g_error_new(quark, 0, "No fd in message");
1460 g_dbus_method_invocation_return_gerror(invocation, err);
1466 fd = g_unix_fd_list_get(fd_list, index, NULL);
1468 ERR("Invalid fd return");
1469 GQuark quark = g_quark_from_string("rfcomm-app");
1470 GError *err = g_error_new(quark, 0, "Invalid FD return");
1471 g_dbus_method_invocation_return_gerror(invocation, err);
1475 INFO("Object Path %s", obj_path);
1477 _bt_hal_convert_device_path_to_address(obj_path, addr);
1478 _bt_hal_convert_addr_string_to_type(remote_addr1.address, (const char *)addr);
1479 INFO("fd: %d, address %s", fd, addr);
1481 g_dbus_method_invocation_return_value(invocation, NULL);
1484 cb(object_path, fd, &remote_addr1);
1487 } else if (g_strcmp0(method_name, "RequestDisconnection") == 0) {
1488 g_dbus_method_invocation_return_value(invocation, NULL);
1492 static GDBusNodeInfo *_bt_hal_get_gdbus_node(const gchar *xml_data)
1495 char *name = g_strdup_printf("org.bt.frwk.p%d", getpid());
1497 bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1499 G_BUS_NAME_OWNER_FLAGS_NONE,
1505 DBG("Got bus id %d", bus_id);
1509 return g_dbus_node_info_new_for_xml(xml_data, NULL);
1512 static const GDBusInterfaceVTable method_table = {
1513 __hal_new_connection_method,
1518 int _bt_hal_register_new_gdbus_object(const char *path, bt_hal_new_connection_cb cb)
1520 GDBusConnection *gconn;
1522 GError *error = NULL;
1524 gconn = _bt_hal_get_system_gconn();
1528 if (new_conn_node == NULL)
1529 new_conn_node = _bt_hal_get_gdbus_node(rfcomm_agent_xml);
1531 if (new_conn_node == NULL)
1534 id = g_dbus_connection_register_object(gconn, path,
1535 new_conn_node->interfaces[0],
1539 ERR("Failed to register: %s", error->message);
1540 g_error_free(error);
1544 DBG("NEW CONNECTION ID %d", id);
1549 void _bt_hal_unregister_gdbus_object(int object_id)
1551 GDBusConnection *gconn;
1553 gconn = _bt_hal_get_system_gconn();
1557 g_dbus_connection_unregister_object(gconn, object_id);
1560 int _bt_hal_discover_services(char *address, char *uuid, void *cb, gpointer func_data)
1564 GDBusProxy *adapter_proxy;
1566 GDBusConnection *conn;
1568 conn = _bt_hal_get_system_gconn();
1570 ERR("conn == NULL, return");
1571 return BT_STATUS_FAIL;
1574 object_path = _bt_hal_get_device_object_path(address);
1575 if (object_path == NULL) {
1576 GVariant *ret = NULL;
1578 INFO("No searched device");
1579 adapter_proxy = _bt_hal_get_adapter_proxy();
1580 if (adapter_proxy == NULL) {
1581 ERR("adapter_proxy == NULL, return");
1582 return BT_STATUS_FAIL;
1585 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1586 g_variant_new("(s)", address),
1587 G_DBUS_CALL_FLAGS_NONE,
1588 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1591 ERR("CreateDevice Failed: %s", err->message);
1592 g_clear_error(&err);
1596 g_variant_unref(ret);
1598 g_object_unref(adapter_proxy);
1599 object_path = _bt_hal_get_device_object_path(address);
1600 if (object_path == NULL) {
1601 ERR("object_path == NULL, return");
1602 return BT_STATUS_FAIL;
1606 proxy = g_dbus_proxy_new_sync(conn,
1607 G_DBUS_PROXY_FLAGS_NONE, NULL,
1608 BT_HAL_BLUEZ_NAME, object_path,
1609 BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1610 g_free(object_path);
1611 if (proxy == NULL) {
1612 ERR("Error while getting proxy");
1613 return BT_STATUS_FAIL;
1616 g_dbus_proxy_call(proxy, "DiscoverServices",
1617 g_variant_new("(s)", uuid),
1618 G_DBUS_CALL_FLAGS_NONE,
1619 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1620 (GAsyncReadyCallback)cb,
1623 return BT_STATUS_SUCCESS;
1626 int _bt_hal_cancel_discovers(char *address)
1630 GDBusProxy *adapter_proxy;
1632 GDBusConnection *conn;
1634 conn = _bt_hal_get_system_gconn();
1636 return BT_STATUS_FAIL;
1638 object_path = _bt_hal_get_device_object_path(address);
1639 if (object_path == NULL) {
1640 GVariant *ret = NULL;
1641 INFO("No searched device");
1642 adapter_proxy = _bt_hal_get_adapter_proxy();
1643 if (adapter_proxy == NULL) {
1644 ERR("adapter_proxy == NULL, return");
1645 return BT_STATUS_FAIL;
1648 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1649 g_variant_new("(s)", address),
1650 G_DBUS_CALL_FLAGS_NONE,
1651 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1654 ERR("CreateDevice Failed: %s", err->message);
1655 g_clear_error(&err);
1659 g_variant_unref(ret);
1661 g_object_unref(adapter_proxy);
1663 object_path = _bt_hal_get_device_object_path(address);
1664 if (object_path == NULL)
1665 return BT_STATUS_FAIL;
1668 proxy = g_dbus_proxy_new_sync(conn,
1669 G_DBUS_PROXY_FLAGS_NONE, NULL,
1670 BT_HAL_BLUEZ_NAME, object_path,
1671 BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1672 g_free(object_path);
1673 g_dbus_proxy_call_sync(proxy, "CancelDiscovery",
1675 G_DBUS_CALL_FLAGS_NONE,
1676 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1679 ERR("DBus Error message: [%s]", err->message);
1680 g_clear_error(&err);
1681 return BT_STATUS_FAIL;
1685 g_object_unref(proxy);
1687 return BT_STATUS_SUCCESS;
1690 int _bt_hal_discover_service_uuids(char *address, char *remote_uuid)
1694 GDBusConnection *gconn;
1696 char **uuid_value = NULL;
1699 GVariant *value = NULL;
1700 GVariant *ret = NULL;
1701 int result = BT_STATUS_FAIL;
1705 if (remote_uuid == NULL) {
1706 ERR("remote_uuid == NULL, return");
1707 return BT_STATUS_FAIL;
1710 gconn = _bt_hal_get_system_gconn();
1711 if (gconn == NULL) {
1712 ERR("gconn == NULL, return");
1713 return BT_STATUS_FAIL;
1716 object_path = _bt_hal_get_device_object_path(address);
1717 if (object_path == NULL) {
1718 ERR("object_path == NULL, return");
1719 return BT_STATUS_FAIL;
1722 proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE, NULL,
1723 BT_HAL_BLUEZ_NAME, object_path, BT_HAL_PROPERTIES_INTERFACE, NULL,
1725 if (proxy == NULL) {
1726 g_free(object_path);
1727 ERR("proxy == NULL, return");
1728 return BT_STATUS_FAIL;
1732 ERR("DBus Error: [%s]", err->message);
1733 g_clear_error(&err);
1736 ret = g_dbus_proxy_call_sync(proxy, "GetAll",
1737 g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
1738 G_DBUS_CALL_FLAGS_NONE,
1739 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1742 result = BT_STATUS_FAIL;
1743 ERR("DBus Error : %s", err->message);
1744 g_clear_error(&err);
1749 ERR("g_dbus_proxy_call_sync function return NULL");
1750 result = BT_STATUS_FAIL;
1754 g_variant_get(ret, "(@a{sv})", &value);
1755 g_variant_unref(ret);
1757 GVariant *temp_value = g_variant_lookup_value(value, "UUIDs",
1758 G_VARIANT_TYPE_STRING_ARRAY);
1761 size = g_variant_get_size(temp_value);
1764 uuid_value = (char **)g_variant_get_strv(temp_value, &size);
1765 DBG("Size items %zu", size);
1769 g_variant_unref(temp_value);
1772 for (i = 0; uuid_value[i] != NULL; i++) {
1773 DBG("Remote uuids %s, searched uuid: %s",
1774 uuid_value[i], remote_uuid);
1775 if (strcasecmp(uuid_value[i], remote_uuid) == 0) {
1776 result = BT_STATUS_SUCCESS;
1785 g_object_unref(proxy);
1787 g_variant_unref(value);
1795 int bt_hal_gatt_convert_prop2string(
1796 bt_hal_gatt_characteristic_property_t properties,
1797 char *char_properties[])
1801 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_BROADCAST) {
1802 char_properties[flag_count] = g_strdup("broadcast");
1805 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_READ) {
1806 char_properties[flag_count] = g_strdup("read");
1809 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE) {
1810 char_properties[flag_count] = g_strdup("write-without-response");
1813 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE) {
1814 char_properties[flag_count] = g_strdup("write");
1817 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY) {
1818 char_properties[flag_count] = g_strdup("notify");
1821 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE) {
1822 char_properties[flag_count] = g_strdup("indicate");
1825 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE) {
1826 char_properties[flag_count] = g_strdup("authenticated-signed-writes");
1829 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE) {
1830 char_properties[flag_count] = g_strdup("reliable-write");
1833 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES) {
1834 char_properties[flag_count] = g_strdup("writable-auxiliaries");
1837 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ) {
1838 char_properties[flag_count] = g_strdup("encrypt-read");
1841 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE) {
1842 char_properties[flag_count] = g_strdup("encrypt-write");
1845 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ) {
1846 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
1849 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE) {
1850 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
1854 if (flag_count == 0) {
1855 char_properties[flag_count] = g_strdup("read");
1862 int bt_hal_gatt_convert_perm2string(
1863 bt_hal_gatt_permission_t properties,
1864 char *char_properties[])
1868 if (properties & BT_HAL_GATT_PERMISSION_READ) {
1869 char_properties[flag_count] = g_strdup("read");
1872 if (properties & BT_HAL_GATT_PERMISSION_WRITE) {
1873 char_properties[flag_count] = g_strdup("write");
1876 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_READ) {
1877 char_properties[flag_count] = g_strdup("encrypt-read");
1880 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_WRITE) {
1881 char_properties[flag_count] = g_strdup("encrypt-write");
1884 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_READ) {
1885 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
1888 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_WRITE) {
1889 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
1893 if (flag_count == 0) {
1894 char_properties[flag_count] = g_strdup("read");
1901 gboolean _bt_hal_is_service_enabled(const char *uuid)
1904 GError *error = NULL;
1907 GVariantIter *iter = NULL;
1909 gboolean ret = FALSE;
1913 proxy = _bt_hal_get_adapter_properties_proxy();
1915 DBG("_bt_hal_dbus_get_local_name: Adapter Properties proxy get failed!!!");
1919 result = g_dbus_proxy_call_sync(proxy,
1920 "Get", g_variant_new("(ss)",
1921 BT_HAL_ADAPTER_INTERFACE, "UUIDs"),
1922 G_DBUS_CALL_FLAGS_NONE, -1,
1925 if (error != NULL) {
1926 ERR("Failed to get UUIDs (Error: %s)", error->message);
1927 g_clear_error(&error);
1929 ERR("Failed to get UUIDs");
1933 g_variant_get(result, "(v)", &temp);
1934 g_variant_get(temp, "as", &iter);
1936 ERR("Failed to get UUIDs");
1937 g_variant_unref(result);
1941 while (g_variant_iter_loop(iter, "s", &uuid_str)) {
1942 DBG("UUID string [%s]\n", uuid_str);
1943 if (!strncasecmp(uuid, uuid_str, strlen(uuid))) {
1949 g_variant_iter_free(iter);
1950 g_variant_unref(result);
1951 g_variant_unref(temp);