4 * Copyright (c) 2015 -2016 Samsung Electronics Co., Ltd All Rights Reserved.
6 * Contact: Anupam Roy <anupam.r@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
31 #include <arpa/inet.h>
35 #include <sys/prctl.h>
37 #include <gio/gunixfdlist.h>
39 #include "bt-hal-dbus-common-utils.h"
42 #include "bt-hal-log.h"
43 #include "bt-hal-msg.h"
44 #include "bt-hal-utils.h"
45 #include "bt-hal-internal.h"
47 #define CASE_RETURN_STR(const) case const: return #const;
50 * This is RFCOMM default Channel Value
52 #define RFCOMM_DEFAULT_PROFILE_CHANNEL 0
53 #define BT_AUDIO_SOURCE_MAX 2
55 static GDBusConnection *system_conn;
56 static GDBusConnection *session_conn;
57 static GDBusProxy *manager_gproxy = NULL;
58 static GDBusProxy *adapter_gproxy = NULL;
59 static GDBusProxy *profile_gproxy = NULL;
61 static GDBusProxy *adapter_properties_proxy;
62 static GDBusProxy *avrcp_ctrl_proxy;
65 GDBusProxy *avrcp_ctrl_proxy;
66 char *avrcp_control_path;
70 static struct avrcp_proxy proxy_array[BT_AUDIO_SOURCE_MAX];
73 static GDBusNodeInfo *new_conn_node;
74 static const gchar rfcomm_agent_xml[] =
76 " <interface name='org.bluez.Profile1'>"
77 " <method name='NewConnection'>"
78 " <arg type='o' name='object' direction='in'/>"
79 " <arg type='h' name='fd' direction='in'/>"
80 " <arg type='a{sv}' name='properties' direction='in'/>"
82 " <method name='RequestDisconnection'>"
83 " <arg type='o' name='device' direction='in'/>"
88 static GDBusNodeInfo *new_l2cap_le_conn_node;
89 static const gchar l2cap_le_agent_xml[] =
91 " <interface name='org.bluez.l2cap_le'>"
92 " <method name='NewConnection'>"
93 " <arg type='o' name='object' direction='in'/>"
94 " <arg type='h' name='fd' direction='in'/>"
99 static GDBusConnection *__bt_hal_init_session_conn(void)
101 if (session_conn == NULL)
102 session_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
107 GDBusConnection *_bt_hal_get_session_gconn(void)
109 return (session_conn) ? session_conn : __bt_hal_init_session_conn();
112 static GDBusConnection *__bt_hal_init_system_gconn(void)
114 GError *error = NULL;
116 if (system_conn != NULL)
119 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
122 ERR("Unable to connect to dbus: %s", error->message);
123 g_clear_error(&error);
129 GDBusConnection *_bt_hal_get_system_gconn(void)
131 GDBusConnection *local_system_gconn = NULL;
132 GError *error = NULL;
134 if (system_conn == NULL) {
135 system_conn = __bt_hal_init_system_gconn();
136 } else if (g_dbus_connection_is_closed(system_conn)) {
138 local_system_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
140 if (!local_system_gconn) {
141 ERR("Unable to connect to dbus: %s", error->message);
142 g_clear_error(&error);
145 system_conn = local_system_gconn;
151 static GDBusProxy *__bt_hal_init_manager_proxy(void)
155 if (system_conn == NULL) {
156 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
157 if (system_conn == NULL)
161 proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
162 NULL, BT_HAL_BLUEZ_NAME,
163 BT_HAL_MANAGER_PATH, BT_HAL_MANAGER_INTERFACE, NULL, NULL);
168 manager_gproxy = proxy;
173 static GDBusProxy *__bt_hal_init_adapter_proxy(void)
175 GDBusProxy *manager_proxy;
177 char *adapter_path = NULL;
179 if (system_conn == NULL) {
180 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
181 if (system_conn == NULL)
185 manager_proxy = _bt_hal_get_manager_proxy();
186 if (manager_proxy == NULL)
189 adapter_path = _bt_hal_get_adapter_path();
190 if (adapter_path == NULL)
193 proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
194 NULL, BT_HAL_BLUEZ_NAME,
195 adapter_path, BT_HAL_ADAPTER_INTERFACE, NULL, NULL);
197 g_free(adapter_path);
202 adapter_gproxy = proxy;
207 static GDBusProxy *__bt_hal_init_adapter_properties_proxy(void)
209 GDBusProxy *manager_proxy;
211 char *adapter_path = NULL;
213 if (system_conn == NULL) {
214 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
215 if (system_conn == NULL)
219 manager_proxy = _bt_hal_get_manager_proxy();
220 if (manager_proxy == NULL)
223 adapter_path = _bt_hal_get_adapter_path();
224 if (adapter_path == NULL)
227 proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
228 NULL, BT_HAL_BLUEZ_NAME,
229 adapter_path, BT_HAL_PROPERTIES_INTERFACE, NULL, NULL);
231 g_free(adapter_path);
236 adapter_properties_proxy = proxy;
241 void _bt_hal_set_control_device_path(const char *path)
248 DBG("control_path = %s", path);
250 for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
251 if (proxy_array[i].avrcp_control_path == NULL) {
252 proxy_array[i].avrcp_control_path = g_strdup(path);
253 DBG("PATH %s formed index %d", proxy_array[i].avrcp_control_path, i);
259 void _bt_hal_remove_control_device_path(const char *path)
266 for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
267 if (g_strcmp0(proxy_array[i].avrcp_control_path, path) == 0) {
268 DBG("Clear AVRCP proxy[%d]", i);
269 g_free(proxy_array[i].avrcp_control_path);
270 g_object_unref(proxy_array[i].avrcp_ctrl_proxy);
272 proxy_array[i].avrcp_control_path = NULL;
273 proxy_array[i].avrcp_ctrl_proxy = NULL;
274 memset(proxy_array[i].bd_addr.address, 0, 6);
280 static char *__bt_hal_extract_control_device_path(GVariantIter *iter, char *address)
282 char *object_path = NULL;
283 char *interface_str = NULL;
284 GVariantIter *interface_iter;
285 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
287 /* Parse the signature: oa{sa{sv}}} */
288 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
289 if (object_path == NULL)
292 while(g_variant_iter_loop(interface_iter, "{&sa{sv}}", &interface_str, NULL)) {
293 if (g_strcmp0(interface_str, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
294 _bt_hal_convert_device_path_to_address(object_path, device_address);
295 if (g_strcmp0(address, device_address) == 0) {
296 DBG("Object Path: %s", object_path);
297 g_variant_iter_free(interface_iter);
298 return g_strdup(object_path);
306 static char *__bt_hal_extract_transport_device_path(GVariantIter *iter, char *address)
308 char *object_path = NULL;
309 char *interface_str = NULL;
310 GVariantIter *interface_iter;
311 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
313 /* Parse the signature: oa{sa{sv}}} */
314 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
315 if (object_path == NULL)
318 while(g_variant_iter_loop(interface_iter, "{&sa{sv}}", &interface_str, NULL)) {
319 if (g_strcmp0(interface_str, BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
320 _bt_hal_convert_device_path_to_address(object_path, device_address);
321 if (g_strcmp0(address, device_address) == 0) {
322 DBG("Object Path: %s", object_path);
323 g_variant_iter_free(interface_iter);
324 return g_strdup(object_path);
332 static char *__bt_hal_get_control_device_object_path(char *address)
334 char *object_path = NULL;
335 GDBusConnection *conn;
336 GDBusProxy *manager_proxy;
337 GVariant *result = NULL;
338 GVariantIter *iter = NULL;
340 conn = _bt_hal_get_system_gconn();
344 manager_proxy = _bt_hal_get_manager_proxy();
345 if (manager_proxy == NULL)
348 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
350 G_DBUS_CALL_FLAGS_NONE,
355 ERR("Can't get managed objects");
359 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
360 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
361 object_path = __bt_hal_extract_control_device_path(iter, address);
362 g_variant_iter_free(iter);
363 g_variant_unref(result);
367 static char *__bt_hal_get_transport_device_object_path(char *address)
369 char *object_path = NULL;
370 GDBusConnection *conn;
371 GDBusProxy *manager_proxy;
372 GVariant *result = NULL;
373 GVariantIter *iter = NULL;
375 conn = _bt_hal_get_system_gconn();
379 manager_proxy = _bt_hal_get_manager_proxy();
380 if (manager_proxy == NULL)
383 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
385 G_DBUS_CALL_FLAGS_NONE,
390 ERR("Can't get managed objects");
394 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
395 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
396 object_path = __bt_hal_extract_transport_device_path(iter, address);
397 g_variant_iter_free(iter);
398 g_variant_unref(result);
402 char *_bt_hal_get_control_device_path(bt_bdaddr_t *bd_addr)
405 char connected_address[BT_HAL_ADDRESS_STRING_SIZE];
407 /* We can add the cache to get transport path for each device */
409 _bt_hal_convert_addr_type_to_string(connected_address, bd_addr->address);
411 control_path = __bt_hal_get_control_device_object_path(connected_address);
412 if (control_path == NULL)
415 DBG("control_path = %s", control_path);
419 char *_bt_hal_get_transport_device_path(bt_bdaddr_t *bd_addr)
421 char *transport_path;
422 char connected_address[BT_HAL_ADDRESS_STRING_SIZE];
424 /* We can add the cache to get transport path for each device */
426 _bt_hal_convert_addr_type_to_string(connected_address, bd_addr->address);
428 transport_path = __bt_hal_get_transport_device_object_path(connected_address);
429 if (transport_path == NULL)
432 DBG("transport_path = %s", transport_path);
433 return transport_path;
436 static GDBusProxy *__bt_hal_init_avrcp_ctrl_proxy(bt_bdaddr_t *bd_addr)
438 GDBusProxy *manager_proxy;
440 GDBusConnection *gconn = NULL;
443 gconn = _bt_hal_get_system_gconn();
447 manager_proxy = _bt_hal_get_manager_proxy();
448 if (manager_proxy == NULL)
451 for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
452 if (proxy_array[i].avrcp_ctrl_proxy == NULL) {
453 memcpy(proxy_array[i].bd_addr.address, bd_addr->address, 6);
454 DBG("PATH %s formed index %d ", proxy_array[i].avrcp_control_path, i);
459 if (i == BT_AUDIO_SOURCE_MAX) {
460 ERR("NO free arr proxy space found");
464 proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE,
465 NULL, BT_HAL_BLUEZ_NAME,
466 proxy_array[i].avrcp_control_path, BT_HAL_PLAYER_CONTROL_INTERFACE, NULL, NULL);
471 avrcp_ctrl_proxy = proxy;
472 proxy_array[i].avrcp_ctrl_proxy = proxy;
477 GDBusProxy *_bt_hal_get_manager_proxy(void)
479 if (manager_gproxy) {
480 const gchar *path = g_dbus_proxy_get_object_path(manager_gproxy);
482 ERR("Already proxy released hence creating new proxy");
483 return __bt_hal_init_manager_proxy();
485 return manager_gproxy;
487 return __bt_hal_init_manager_proxy();
490 GDBusProxy *_bt_hal_get_adapter_proxy(void)
492 if (adapter_gproxy) {
493 const char *path = g_dbus_proxy_get_object_path(adapter_gproxy);
495 ERR("Already proxy released hence creating new proxy");
496 return __bt_hal_init_adapter_proxy();
499 return adapter_gproxy;
501 return __bt_hal_init_adapter_proxy();
505 GDBusProxy *_bt_hal_get_avrcp_ctrl_proxy(bt_bdaddr_t *bd_addr)
509 for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
510 if (proxy_array[i].avrcp_ctrl_proxy
511 && (!memcmp(proxy_array[i].bd_addr.address, bd_addr->address, 6))) {
512 const gchar *path = g_dbus_proxy_get_object_path(proxy_array[i].avrcp_ctrl_proxy);
515 proxy_array[i].avrcp_ctrl_proxy = NULL;
516 ERR("Already proxy released hence creating new proxy");
517 return __bt_hal_init_avrcp_ctrl_proxy(bd_addr);
520 DBG("address found path PATH %s", path);
521 return proxy_array[i].avrcp_ctrl_proxy;
525 DBG("address NOT found");
527 return __bt_hal_init_avrcp_ctrl_proxy(bd_addr);
530 GDBusProxy *_bt_hal_get_avrcp_ctrl_properties_proxy(bt_bdaddr_t *bd_addr)
533 GError *error = NULL;
534 char *control_path = NULL;
535 GDBusConnection *conn = NULL;
537 control_path = _bt_hal_get_control_device_path(bd_addr);
538 if (control_path == NULL)
541 DBG("control_path = %s", control_path);
543 conn = _bt_hal_get_system_gconn();
545 ERR("FAIL to get system connection");
548 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
549 NULL, BT_HAL_BLUEZ_NAME,
550 control_path, BT_HAL_PROPERTIES_INTERFACE, NULL, &error);
553 ERR("Unable to allocate new proxy");
555 ERR("%s", error->message);
556 g_clear_error(&error);
564 GDBusProxy *_bt_hal_get_avrcp_transport_properties_proxy(bt_bdaddr_t *bd_addr)
567 GError *error = NULL;
568 char *transport_path = NULL;
569 GDBusConnection *conn = NULL;
571 transport_path = _bt_hal_get_transport_device_path(bd_addr);
572 if (transport_path == NULL)
575 DBG("transport_path = %s", transport_path);
577 conn = _bt_hal_get_system_gconn();
579 ERR("FAIL to get system connection");
582 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
583 NULL, BT_HAL_BLUEZ_NAME,
584 transport_path, BT_HAL_PROPERTIES_INTERFACE, NULL, &error);
587 ERR("Unable to allocate new proxy");
589 ERR("%s", error->message);
590 g_clear_error(&error);
598 GDBusProxy *_bt_hal_get_adapter_properties_proxy(void)
600 return (adapter_properties_proxy) ? adapter_properties_proxy :
601 __bt_hal_init_adapter_properties_proxy();
604 GDBusProxy *_bt_hal_get_profile_proxy(void)
606 GDBusConnection *gconn;
610 return profile_gproxy;
612 gconn = _bt_hal_get_system_gconn();
614 ERR("_bt_hal_get_system_gconn failed");
618 profile_gproxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE,
619 NULL, BT_HAL_BLUEZ_NAME,
621 "org.bluez.ProfileManager1",
624 ERR("Unable to create proxy: %s", err->message);
629 return profile_gproxy;
632 static char *__bt_hal_extract_adapter_path(GVariantIter *iter)
634 char *object_path = NULL;
635 GVariantIter *interface_iter;
636 GVariantIter *svc_iter;
637 char *interface_str = NULL;
639 /* Parse the signature: oa{sa{sv}}} */
640 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
643 if (object_path == NULL)
646 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
647 &interface_str, &svc_iter)) {
648 if (g_strcmp0(interface_str, "org.bluez.Adapter1") != 0)
651 DBG("Object Path: %s", object_path);
652 g_free(interface_str);
653 g_variant_iter_free(svc_iter);
654 g_variant_iter_free(interface_iter);
655 return g_strdup(object_path);
661 char *_bt_hal_get_adapter_path(void)
663 GDBusConnection *conn;
664 GDBusProxy *manager_proxy;
665 GVariant *result = NULL;
666 GVariantIter *iter = NULL;
667 char *adapter_path = NULL;
669 conn = _bt_hal_get_system_gconn();
673 manager_proxy = _bt_hal_get_manager_proxy();
674 if (manager_proxy == NULL)
677 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
679 G_DBUS_CALL_FLAGS_NONE,
684 ERR("Can't get managed objects");
688 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
689 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
691 adapter_path = __bt_hal_extract_adapter_path(iter);
692 g_variant_iter_free(iter);
693 g_variant_unref(result);
698 int _bt_hal_is_adapter_powered(gboolean *powered)
701 GError *error = NULL;
706 proxy = _bt_hal_get_adapter_properties_proxy();
708 return BT_STATUS_FAIL;
710 result = g_dbus_proxy_call_sync(proxy,
712 g_variant_new("(ss)", BT_HAL_ADAPTER_INTERFACE,
714 G_DBUS_CALL_FLAGS_NONE,
720 ERR("Failed to get powered status");
722 ERR("Failed to get powered status (Error: %s)", error->message);
723 g_clear_error(&error);
725 return BT_STATUS_FAIL;
728 g_variant_get(result, "(v)", &temp);
729 *powered = g_variant_get_boolean(temp);
730 INFO("powered: %d", *powered);
732 g_variant_unref(result);
733 g_variant_unref(temp);
734 return BT_STATUS_SUCCESS;
737 void _bt_hal_deinit_bluez_proxy(void)
739 if (manager_gproxy) {
740 g_object_unref(manager_gproxy);
741 manager_gproxy = NULL;
744 if (adapter_gproxy) {
745 g_object_unref(adapter_gproxy);
746 adapter_gproxy = NULL;
748 if (adapter_properties_proxy) {
749 g_object_unref(adapter_properties_proxy);
750 adapter_properties_proxy = NULL;
754 void _bt_hal_deinit_proxys(void)
756 _bt_hal_deinit_bluez_proxy();
759 g_object_unref(system_conn);
764 g_object_unref(session_conn);
769 GDBusProxy *_bt_hal_get_hid_agent_proxy(void)
771 GDBusConnection *conn;
775 conn = _bt_hal_get_system_gconn();
777 ERR("_bt_hal_get_system_gconn failed");
781 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
782 BT_HAL_HID_SERVICE_NAME, BT_HAL_HID_AGENT_OBJECT_PATH,
783 BT_HAL_HID_SERVICE_INTERFACE, NULL, &err);
786 ERR("Unable to create proxy: %s", err->message);
795 void _bt_hal_convert_device_path_to_address(const char *device_path,
796 char *device_address)
798 char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
801 if (device_path == NULL || device_address == NULL)
804 dev_addr = strstr(device_path, "dev_");
805 if (dev_addr != NULL) {
808 g_strlcpy(address, dev_addr, sizeof(address));
810 while ((pos = strchr(address, '_')) != NULL)
813 g_strlcpy(device_address, address, BT_HAL_ADDRESS_STRING_SIZE);
817 gboolean _bt_hal_uuid_is_standard(bt_uuid_t *p_uuid)
819 uint32_t uuid0, uuid4;
820 uint16_t uuid1, uuid2, uuid3, uuid5;
821 const char *uuid_name;
822 const char *uuid_name1;
824 memcpy(&uuid0, &(p_uuid->uu[0]), 4);
825 memcpy(&uuid1, &(p_uuid->uu[4]), 2);
826 memcpy(&uuid2, &(p_uuid->uu[6]), 2);
827 memcpy(&uuid3, &(p_uuid->uu[8]), 2);
828 memcpy(&uuid4, &(p_uuid->uu[10]), 4);
829 memcpy(&uuid5, &(p_uuid->uu[14]), 2);
831 uuid_name = _bt_hal_dump_uuid_name(ntohl(uuid0));
832 uuid_name1 = _bt_hal_dump_uuid_name((ntohl(uuid4) >> 16));
834 DBG("UUID Name [%s]", uuid_name);
835 DBG("UUID Name Shifted [%s]", uuid_name1);
837 if (!g_strcmp0(uuid_name, "--"))
844 void _bt_hal_convert_uuid_string_to_type(unsigned char *uuid,
845 const char *device_uuid)
847 uint32_t uuid0, uuid4;
848 uint16_t uuid1, uuid2, uuid3, uuid5;
850 sscanf(device_uuid, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
851 &uuid0, &uuid1, &uuid2, &uuid3, &uuid4, &uuid5);
853 uuid0 = htonl(uuid0);
854 uuid1 = htons(uuid1);
855 uuid2 = htons(uuid2);
856 uuid3 = htons(uuid3);
857 uuid4 = htonl(uuid4);
858 uuid5 = htons(uuid5);
860 memcpy(&(uuid[0]), &uuid0, 4);
861 memcpy(&(uuid[4]), &uuid1, 2);
862 memcpy(&(uuid[6]), &uuid2, 2);
863 memcpy(&(uuid[8]), &uuid3, 2);
864 memcpy(&(uuid[10]), &uuid4, 4);
865 memcpy(&(uuid[14]), &uuid5, 2);
868 void _bt_hal_convert_uuid_type_to_string(char *str, const unsigned char *uuid)
880 snprintf(str, BT_HAL_UUID_STRING_LEN,
881 "%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",
882 uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
883 uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
886 void _bt_hal_convert_addr_string_to_type(unsigned char *addr,
892 if (address == NULL || addr == NULL)
895 for (i = 0; i < BT_HAL_ADDRESS_LENGTH_MAX; i++) {
896 addr[i] = strtol(address, &ptr, 16);
898 if (ptr[0] != '\0') {
907 void _bt_hal_convert_addr_type_to_string(char *address,
908 const unsigned char *addr)
910 if (address == NULL || addr == NULL)
913 snprintf(address, BT_HAL_ADDRESS_STRING_SIZE,
914 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
915 addr[0], addr[1], addr[2],
916 addr[3], addr[4], addr[5]);
919 void _bt_hal_print_device_address_t(const bt_hal_device_address_t *addr)
921 DBG("%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", addr->addr[0], addr->addr[1], addr->addr[2],
922 addr->addr[3], addr->addr[4], addr->addr[5]);
925 void _bt_hal_divide_device_class(bt_hal_device_class_t *device_class,
928 if (device_class == NULL)
931 device_class->major_class = (unsigned short)(cod & 0x00001F00) >> 8;
932 device_class->minor_class = (unsigned short)((cod & 0x000000FC));
933 device_class->service_class = (unsigned long)((cod & 0x00FF0000));
935 if (cod & 0x002000) {
936 device_class->service_class |=
937 BT_HAL_DEVICE_SERVICE_CLASS_LIMITED_DISCOVERABLE_MODE;
941 int _bt_hal_copy_utf8_string(char *dest, const char *src, unsigned int length)
948 if (dest == NULL || src == NULL)
949 return BT_HAL_ERROR_INVALID_PARAM;
951 DBG("+src : %s", src);
952 DBG("+dest : %s", dest);
955 while (*p != '\0' && i < length) {
956 next = g_utf8_next_char(p);
959 while (count > 0 && ((i + count) < length)) {
966 return BT_HAL_ERROR_NONE;
969 gboolean _bt_hal_utf8_validate(char *name)
972 glong items_written = 0;
974 if (FALSE == g_utf8_validate(name, -1, NULL))
977 u16 = g_utf8_to_utf16(name, -1, NULL, &items_written, NULL);
983 if (items_written != g_utf8_strlen(name, -1))
989 int _bt_hal_set_socket_non_blocking(int socket_fd)
991 /* Set Nonblocking */
994 arg = fcntl(socket_fd, F_GETFL);
999 if (arg & O_NONBLOCK)
1000 ERR("Already Non-blocking \n");
1004 if (fcntl(socket_fd, F_SETFL, arg) < 0)
1007 return BT_HAL_ERROR_NONE;
1010 int _bt_hal_set_non_blocking_tty(int sk)
1012 struct termios ti = {0,};
1015 err = _bt_hal_set_socket_non_blocking(sk);
1018 ERR("Error in set non blocking!\n");
1022 tcflush(sk, TCIOFLUSH);
1024 /* Switch tty to RAW mode */
1026 tcsetattr(sk, TCSANOW, &ti);
1028 return BT_HAL_ERROR_NONE;
1031 static char *__bt_hal_extract_device_path(GVariantIter *iter, char *address)
1033 char *object_path = NULL;
1034 char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
1036 /* Parse the signature: oa{sa{sv}}} */
1037 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, NULL)) {
1038 if (object_path == NULL)
1040 _bt_hal_convert_device_path_to_address(object_path, device_address);
1041 if (g_strcmp0(address, device_address) == 0)
1042 return g_strdup(object_path);
1047 char *_bt_hal_get_device_object_path(char *address)
1049 char *object_path = NULL;
1050 GDBusConnection *conn;
1051 GDBusProxy *manager_proxy;
1052 GVariant *result = NULL;
1053 GVariantIter *iter = NULL;
1055 conn = _bt_hal_get_system_gconn();
1059 manager_proxy = _bt_hal_get_manager_proxy();
1060 if (manager_proxy == NULL)
1063 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
1065 G_DBUS_CALL_FLAGS_NONE,
1070 ERR("Can't get managed objects");
1074 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
1075 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
1076 object_path = __bt_hal_extract_device_path(iter, address);
1077 g_variant_iter_free(iter);
1078 g_variant_unref(result);
1082 GVariant *_bt_hal_get_managed_objects(void)
1084 GDBusConnection *conn;
1085 GDBusProxy *manager_proxy;
1086 GVariant *result = NULL;
1087 GError *error = NULL;
1089 conn = _bt_hal_get_system_gconn();
1093 manager_proxy = _bt_hal_get_manager_proxy();
1094 if (manager_proxy == NULL)
1097 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
1099 G_DBUS_CALL_FLAGS_NONE,
1104 ERR("Can't get managed objects");
1109 ERR("Fail to get ManagedObjects (Error: %s)", error->message);
1110 g_clear_error(&error);
1117 char *_bt_hal_convert_error_to_string(int error)
1120 case BT_HAL_ERROR_CANCEL:
1122 case BT_HAL_ERROR_INVALID_PARAM:
1123 return "INVALID_PARAMETER";
1124 case BT_HAL_ERROR_INVALID_DATA:
1125 return "INVALID DATA";
1126 case BT_HAL_ERROR_MEMORY_ALLOCATION:
1127 case BT_HAL_ERROR_OUT_OF_MEMORY:
1128 return "OUT_OF_MEMORY";
1129 case BT_HAL_ERROR_TIMEOUT:
1131 case BT_HAL_ERROR_NO_RESOURCES:
1132 return "NO_RESOURCES";
1133 case BT_HAL_ERROR_INTERNAL:
1135 case BT_HAL_ERROR_NOT_SUPPORT:
1136 return "NOT_SUPPORT";
1137 case BT_HAL_ERROR_DEVICE_NOT_ENABLED:
1138 return "NOT_ENABLED";
1139 case BT_HAL_ERROR_DEVICE_ALREADY_ENABLED:
1140 return "ALREADY_ENABLED";
1141 case BT_HAL_ERROR_DEVICE_BUSY:
1142 return "DEVICE_BUSY";
1143 case BT_HAL_ERROR_ACCESS_DENIED:
1144 return "ACCESS_DENIED";
1145 case BT_HAL_ERROR_MAX_CLIENT:
1146 return "MAX_CLIENT";
1147 case BT_HAL_ERROR_NOT_FOUND:
1149 case BT_HAL_ERROR_SERVICE_SEARCH_ERROR:
1150 return "SERVICE_SEARCH_ERROR";
1151 case BT_HAL_ERROR_PARING_FAILED:
1152 return "PARING_FAILED";
1153 case BT_HAL_ERROR_NOT_PAIRED:
1154 return "NOT_PAIRED";
1155 case BT_HAL_ERROR_SERVICE_NOT_FOUND:
1156 return "SERVICE_NOT_FOUND";
1157 case BT_HAL_ERROR_NOT_CONNECTED:
1158 return "NOT_CONNECTED";
1159 case BT_HAL_ERROR_ALREADY_CONNECT:
1160 return "ALREADY_CONNECT";
1161 case BT_HAL_ERROR_CONNECTION_BUSY:
1162 return "CONNECTION_BUSY";
1163 case BT_HAL_ERROR_CONNECTION_ERROR:
1164 return "CONNECTION_ERROR";
1165 case BT_HAL_ERROR_MAX_CONNECTION:
1166 return "MAX_CONNECTION";
1167 case BT_HAL_ERROR_NOT_IN_OPERATION:
1168 return "NOT_IN_OPERATION";
1169 case BT_HAL_ERROR_CANCEL_BY_USER:
1170 return "CANCEL_BY_USER";
1171 case BT_HAL_ERROR_REGISTRATION_FAILED:
1172 return "REGISTRATION_FAILED";
1173 case BT_HAL_ERROR_IN_PROGRESS:
1174 return "IN_PROGRESS";
1175 case BT_HAL_ERROR_AUTHENTICATION_FAILED:
1176 return "AUTHENTICATION_FAILED";
1177 case BT_HAL_ERROR_HOST_DOWN:
1179 case BT_HAL_ERROR_END_OF_DEVICE_LIST:
1180 return "END_OF_DEVICE_LIST";
1181 case BT_HAL_ERROR_AGENT_ALREADY_EXIST:
1182 return "AGENT_ALREADY_EXIST";
1183 case BT_HAL_ERROR_AGENT_DOES_NOT_EXIST:
1184 return "AGENT_DOES_NOT_EXIST";
1185 case BT_HAL_ERROR_ALREADY_INITIALIZED:
1186 return "ALREADY_INITIALIZED";
1187 case BT_HAL_ERROR_PERMISSION_DEINED:
1188 return "PERMISSION_DEINED";
1189 case BT_HAL_ERROR_ALREADY_DEACTIVATED:
1190 return "ALREADY_DEACTIVATED";
1191 case BT_HAL_ERROR_NOT_INITIALIZED:
1192 return "NOT_INITIALIZED";
1198 char * _bt_hal_convert_disc_reason_to_string(int reason)
1204 return "Connection terminated by local host";
1206 return "Remote user terminated connection";
1213 void _bt_hal_logging_connection(gboolean connect, int addr_type)
1215 static int le_conn = 0;
1216 static int le_disc = 0;
1217 static int edr_conn = 0;
1218 static int edr_disc = 0;
1232 INFO("[PM] Number of LE conn: %d disc: %d, Number of BR/EDR conn: %d disc: %d",
1233 le_conn, le_disc, edr_conn, edr_disc);
1236 void _bt_hal_swap_byte_ordering(char *data, int data_len)
1243 /* Swap to opposite endian */
1244 for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
1251 int _bt_hal_byte_arr_cmp(const char *data1, const char *data2, int data_len)
1255 if (data1 == NULL || data2 == NULL)
1257 for (i = 0; i < data_len; i++) {
1258 if (data1[i] != data2[i])
1259 return data1[i] - data2[i];
1263 int _bt_hal_byte_arr_cmp_with_mask(const char *data1, const char *data2,
1264 const char *mask, int data_len)
1269 if (data1 == NULL || data2 == NULL || mask == NULL)
1272 for (i = 0; i < data_len; i++) {
1273 a = data1[i] & mask[i];
1274 b = data2[i] & mask[i];
1276 return (int)(a - b);
1281 int _bt_hal_connect_profile(char *address, char *uuid,
1282 void *cb, gpointer func_data)
1286 GDBusConnection *conn;
1287 GDBusProxy *adapter_proxy;
1288 GError *error = NULL;
1291 conn = _bt_hal_get_system_gconn();
1293 return BT_HAL_ERROR_INTERNAL;
1295 object_path = _bt_hal_get_device_object_path(address);
1296 if (object_path == NULL) {
1297 ERR("No searched device");
1299 adapter_proxy = _bt_hal_get_adapter_proxy();
1300 if (adapter_proxy == NULL)
1301 return BT_HAL_ERROR_INTERNAL;
1303 result = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1304 g_variant_new("(s)", address),
1305 G_DBUS_CALL_FLAGS_NONE,
1311 ERR("CreateDevice Fail: %s", error->message);
1312 g_error_free(error);
1315 g_variant_unref(result);
1318 object_path = _bt_hal_get_device_object_path(address);
1320 if (object_path == NULL)
1321 return BT_HAL_ERROR_INTERNAL;
1323 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1324 NULL, BT_HAL_BLUEZ_NAME,
1325 object_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1326 g_free(object_path);
1328 return BT_HAL_ERROR_INTERNAL;
1331 g_dbus_proxy_call(proxy, "ConnectProfile",
1332 g_variant_new("(s)", uuid),
1333 G_DBUS_CALL_FLAGS_NONE,
1334 BT_HAL_MAX_DBUS_TIMEOUT,
1336 (GAsyncReadyCallback)cb,
1339 return BT_HAL_ERROR_NONE;
1342 int _bt_hal_disconnect_profile(char *address, char *uuid,
1343 void *cb, gpointer func_data)
1347 GDBusConnection *conn;
1349 conn = _bt_hal_get_system_gconn();
1351 return BT_HAL_ERROR_INTERNAL;
1353 object_path = _bt_hal_get_device_object_path(address);
1354 if (object_path == NULL)
1355 return BT_HAL_ERROR_INTERNAL;
1357 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1358 NULL, BT_HAL_BLUEZ_NAME,
1359 object_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1360 g_free(object_path);
1362 return BT_HAL_ERROR_INTERNAL;
1364 g_dbus_proxy_call(proxy, "DisconnectProfile",
1365 g_variant_new("(s)", uuid),
1366 G_DBUS_CALL_FLAGS_NONE,
1367 BT_HAL_MAX_DBUS_TIMEOUT,
1369 (GAsyncReadyCallback)cb,
1372 return BT_HAL_ERROR_NONE;
1375 int _bt_hal_register_profile(bt_hal_register_profile_info_t *info, gboolean use_default_rfcomm)
1377 GVariantBuilder *option_builder;
1381 int result = BT_STATUS_SUCCESS;
1383 proxy = _bt_hal_get_profile_proxy();
1384 if (proxy == NULL) {
1385 ERR("Getting profile proxy failed");
1386 return BT_STATUS_FAIL;
1389 option_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1390 if (info->authentication)
1391 g_variant_builder_add(option_builder, "{sv}",
1392 "RequireAuthentication",
1393 g_variant_new_boolean(TRUE));
1394 if (info->authorization)
1395 g_variant_builder_add(option_builder, "{sv}",
1396 "RequireAuthorization",
1397 g_variant_new_boolean(TRUE));
1399 g_variant_builder_add(option_builder, "{sv}",
1401 g_variant_new_string(info->role));
1404 * Setting RFCOMM channel to default value 0; would allow bluez to assign
1405 * RFCOMM channels based on the availability when two services want to use
1406 * the RFCOMM along with SPP. Hence bluez makes sure that no two services
1407 * use the same SPP RFCOMM channel.
1409 if (use_default_rfcomm)
1410 g_variant_builder_add(option_builder, "{sv}",
1412 g_variant_new_uint16(RFCOMM_DEFAULT_PROFILE_CHANNEL));
1414 g_variant_builder_add(option_builder, "{sv}",
1416 g_variant_new_string(info->service));
1418 ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile",
1419 g_variant_new("(osa{sv})", info->obj_path,
1422 G_DBUS_CALL_FLAGS_NONE, -1,
1425 ERR("RegisterProfile failed: %s", err->message);
1427 if (g_strrstr(err->message, BT_HAL_ACCESS_DENIED_MSG))
1428 result = BT_STATUS_AUTH_REJECTED;
1430 result = BT_STATUS_FAIL;
1432 g_clear_error(&err);
1435 g_variant_builder_unref(option_builder);
1438 g_variant_unref(ret);
1443 void _bt_hal_unregister_profile(char *path)
1449 proxy = _bt_hal_get_profile_proxy();
1450 if (proxy == NULL) {
1451 ERR("Getting profile proxy failed");
1455 ret = g_dbus_proxy_call_sync(proxy, "UnregisterProfile",
1456 g_variant_new("(o)", path),
1457 G_DBUS_CALL_FLAGS_NONE, -1,
1460 ERR("UnregisterProfile failed : %s", err->message);
1461 g_clear_error(&err);
1465 g_variant_unref(ret);
1470 static void __hal_new_connection_method(GDBusConnection *connection,
1471 const gchar *sender,
1472 const gchar *object_path,
1473 const gchar *interface_name,
1474 const gchar *method_name,
1475 GVariant *parameters,
1476 GDBusMethodInvocation *invocation,
1479 DBG("method %s", method_name);
1480 if (g_strcmp0(method_name, "NewConnection") == 0) {
1483 GUnixFDList *fd_list;
1485 GVariantBuilder *properties;
1487 bt_bdaddr_t remote_addr1;
1488 char addr[BT_HAL_ADDRESS_STRING_SIZE];
1489 bt_hal_new_connection_cb cb = user_data;
1491 g_variant_get(parameters, "(oha{sv})", &obj_path, &index,
1494 msg = g_dbus_method_invocation_get_message(invocation);
1495 fd_list = g_dbus_message_get_unix_fd_list(msg);
1496 if (fd_list == NULL) {
1497 GQuark quark = g_quark_from_string("rfcomm-app");
1498 GError *err = g_error_new(quark, 0, "No fd in message");
1499 g_dbus_method_invocation_return_gerror(invocation, err);
1505 fd = g_unix_fd_list_get(fd_list, index, NULL);
1507 ERR("Invalid fd return");
1508 GQuark quark = g_quark_from_string("rfcomm-app");
1509 GError *err = g_error_new(quark, 0, "Invalid FD return");
1510 g_dbus_method_invocation_return_gerror(invocation, err);
1514 INFO("Object Path %s", obj_path);
1516 _bt_hal_convert_device_path_to_address(obj_path, addr);
1517 _bt_hal_convert_addr_string_to_type(remote_addr1.address, (const char *)addr);
1518 INFO("fd: %d, address %s", fd, addr);
1520 g_dbus_method_invocation_return_value(invocation, NULL);
1523 cb(object_path, fd, &remote_addr1);
1526 } else if (g_strcmp0(method_name, "RequestDisconnection") == 0) {
1527 g_dbus_method_invocation_return_value(invocation, NULL);
1531 int _bt_hal_connect_l2cap_le(char *address,
1532 bt_hal_l2cap_le_profile_info_t *info, void *cb, gpointer func_data)
1534 GVariantBuilder *option_builder;
1537 GDBusConnection *conn;
1538 GDBusProxy *adapter_proxy;
1539 GError *error = NULL;
1543 conn = _bt_hal_get_system_gconn();
1545 return BT_HAL_ERROR_INTERNAL;
1547 object_path = _bt_hal_get_device_object_path(address);
1548 if (object_path == NULL) {
1549 ERR("No searched device");
1551 adapter_proxy = _bt_hal_get_adapter_proxy();
1552 if (adapter_proxy == NULL)
1553 return BT_HAL_ERROR_INTERNAL;
1555 result = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1556 g_variant_new("(s)", address), G_DBUS_CALL_FLAGS_NONE,
1561 ERR("CreateDevice Fail: %s", error->message);
1562 g_error_free(error);
1565 g_variant_unref(result);
1567 object_path = _bt_hal_get_device_object_path(address);
1570 if (object_path == NULL) {
1571 INFO("Not able to find device object");
1572 return BT_HAL_ERROR_INTERNAL;
1575 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1576 NULL, BT_HAL_BLUEZ_NAME,
1577 object_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1578 g_free(object_path);
1580 if (proxy == NULL) {
1581 INFO("proxy is null");
1582 return BT_HAL_ERROR_INTERNAL;
1585 option_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1586 if (info->authentication)
1587 g_variant_builder_add(option_builder, "{sv}",
1588 "RequireAuthentication",
1589 g_variant_new_boolean(TRUE));
1591 if (info->authorization)
1592 g_variant_builder_add(option_builder, "{sv}",
1593 "RequireAuthorization",
1594 g_variant_new_boolean(TRUE));
1596 g_dbus_proxy_call(proxy, "ConnectL2capLESocket",
1597 g_variant_new("(oia{sv})", info->obj_path,
1598 info->psm, option_builder),
1599 G_DBUS_CALL_FLAGS_NONE, BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1600 (GAsyncReadyCallback)cb, func_data);
1602 g_variant_builder_unref(option_builder);
1605 return BT_HAL_ERROR_NONE;
1608 int _bt_hal_listen_l2cap_le(bt_hal_l2cap_le_profile_info_t *info)
1610 GVariantBuilder *option_builder;
1614 int result = BT_STATUS_SUCCESS;
1617 proxy = _bt_hal_get_adapter_proxy();
1618 if (proxy == NULL) {
1619 ERR("Getting adapter profile proxy failed");
1620 return BT_STATUS_FAIL;
1623 option_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1624 if (info->authentication)
1625 g_variant_builder_add(option_builder, "{sv}",
1626 "RequireAuthentication",
1627 g_variant_new_boolean(TRUE));
1629 if (info->authorization)
1630 g_variant_builder_add(option_builder, "{sv}",
1631 "RequireAuthorization",
1632 g_variant_new_boolean(TRUE));
1634 ret = g_dbus_proxy_call_sync(proxy, "ListenL2capLESocket",
1635 g_variant_new("(oia{sv})", info->obj_path, info->psm,
1637 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1640 ERR("Listen L2cap_LE failed: %s", err->message);
1642 if (g_strrstr(err->message, BT_HAL_ACCESS_DENIED_MSG))
1643 result = BT_STATUS_AUTH_REJECTED;
1645 result = BT_STATUS_FAIL;
1647 g_clear_error(&err);
1650 g_variant_builder_unref(option_builder);
1653 g_variant_unref(ret);
1659 void _bt_hal_remove_l2cap_le_socket(char *path)
1665 proxy = _bt_hal_get_adapter_proxy();
1666 if (proxy == NULL) {
1667 ERR("Getting adapter profile proxy failed");
1671 ret = g_dbus_proxy_call_sync(proxy, "RemoveL2capLESocket",
1672 g_variant_new("(o)", path),
1673 G_DBUS_CALL_FLAGS_NONE, -1,
1676 ERR("Remove socket l2cap le failed : %s", err->message);
1677 g_clear_error(&err);
1681 g_variant_unref(ret);
1686 int _bt_hal_get_psm_l2cap_le(bt_hal_l2cap_le_profile_info_t *info, uint32_t *psm)
1691 int result = BT_STATUS_SUCCESS;
1693 proxy = _bt_hal_get_adapter_proxy();
1694 if (proxy == NULL) {
1695 ERR("Getting adapter profile proxy failed");
1696 return BT_STATUS_FAIL;
1699 ret = g_dbus_proxy_call_sync(proxy, "GetPSML2capLE",
1700 g_variant_new("(o)", info->obj_path),
1701 G_DBUS_CALL_FLAGS_NONE, -1,
1704 ERR("Get PSM L2cap_LE failed: %s", err->message);
1705 result = BT_STATUS_FAIL;
1706 g_clear_error(&err);
1710 g_variant_get(ret, "(u)", psm);
1711 INFO("PSM: %d", *psm);
1714 g_variant_unref(ret);
1719 static void __hal_l2cap_le_new_connection_method(GDBusConnection *connection,
1720 const gchar *sender,
1721 const gchar *object_path,
1722 const gchar *interface_name,
1723 const gchar *method_name,
1724 GVariant *parameters,
1725 GDBusMethodInvocation *invocation,
1728 INFO("method %s", method_name);
1729 if (g_strcmp0(method_name, "NewConnection") == 0) {
1730 INFO("L2cap_LE New connection method");
1733 GUnixFDList *fd_list;
1736 bt_bdaddr_t remote_addr1;
1737 char addr[BT_HAL_ADDRESS_STRING_SIZE];
1738 bt_hal_new_connection_cb cb = user_data;
1740 g_variant_get(parameters, "(oh)", &obj_path, &index);
1742 msg = g_dbus_method_invocation_get_message(invocation);
1743 fd_list = g_dbus_message_get_unix_fd_list(msg);
1744 if (fd_list == NULL) {
1745 ERR("No fd in message");
1746 GQuark quark = g_quark_from_string("l2cap_le-app");
1747 GError *err = g_error_new(quark, 0, "No fd in message");
1748 g_dbus_method_invocation_return_gerror(invocation, err);
1753 fd = g_unix_fd_list_get(fd_list, index, NULL);
1755 ERR("Invalid fd return");
1756 GQuark quark = g_quark_from_string("l2cap_le-app");
1757 GError *err = g_error_new(quark, 0, "Invalid FD return");
1758 g_dbus_method_invocation_return_gerror(invocation, err);
1763 _bt_hal_convert_device_path_to_address(obj_path, addr);
1764 _bt_hal_convert_addr_string_to_type(remote_addr1.address, (const char *)addr);
1765 INFO("Object path %s, fd: %d, address %s", obj_path, fd, addr);
1767 g_dbus_method_invocation_return_value(invocation, NULL);
1770 cb(object_path, fd, &remote_addr1);
1776 static GDBusNodeInfo *_bt_hal_get_gdbus_node(const gchar *xml_data)
1779 char *name = g_strdup_printf("org.bt.frwk.p%d", getpid());
1781 bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1783 G_BUS_NAME_OWNER_FLAGS_NONE,
1789 DBG("Got bus id %d", bus_id);
1793 return g_dbus_node_info_new_for_xml(xml_data, NULL);
1796 static const GDBusInterfaceVTable method_table = {
1797 __hal_new_connection_method,
1802 static const GDBusInterfaceVTable l2cap_le_method_table = {
1803 __hal_l2cap_le_new_connection_method,
1808 int _bt_hal_register_new_gdbus_object(const char *path, bt_hal_new_connection_cb cb)
1810 GDBusConnection *gconn;
1812 GError *error = NULL;
1814 gconn = _bt_hal_get_system_gconn();
1818 if (new_conn_node == NULL)
1819 new_conn_node = _bt_hal_get_gdbus_node(rfcomm_agent_xml);
1821 if (new_conn_node == NULL)
1824 id = g_dbus_connection_register_object(gconn, path,
1825 new_conn_node->interfaces[0],
1829 ERR("Failed to register: %s", error->message);
1830 g_error_free(error);
1834 DBG("NEW CONNECTION ID %d", id);
1839 void _bt_hal_unregister_gdbus_object(int object_id)
1841 GDBusConnection *gconn;
1843 gconn = _bt_hal_get_system_gconn();
1847 g_dbus_connection_unregister_object(gconn, object_id);
1850 int _bt_hal_register_new_l2cap_le_gdbus_object(const char *path,
1851 bt_hal_new_connection_cb cb)
1853 GDBusConnection *gconn;
1855 GError *error = NULL;
1857 gconn = _bt_hal_get_system_gconn();
1861 if (new_l2cap_le_conn_node == NULL)
1862 new_l2cap_le_conn_node = _bt_hal_get_gdbus_node(l2cap_le_agent_xml);
1864 if (new_l2cap_le_conn_node == NULL)
1867 id = g_dbus_connection_register_object(gconn, path,
1868 new_l2cap_le_conn_node->interfaces[0],
1869 &l2cap_le_method_table,
1872 ERR("Failed to register: %s", error->message);
1873 g_error_free(error);
1877 INFO("L2CAP_LE NEW CONNECTION ID %d", id);
1882 void _bt_hal_unregister_l2cap_le_gdbus_object(int object_id)
1884 GDBusConnection *gconn;
1886 gconn = _bt_hal_get_system_gconn();
1890 g_dbus_connection_unregister_object(gconn, object_id);
1893 int _bt_hal_discover_services(char *address, char *uuid, void *cb, gpointer func_data)
1897 GDBusProxy *adapter_proxy;
1899 GDBusConnection *conn;
1901 conn = _bt_hal_get_system_gconn();
1903 ERR("conn == NULL, return");
1904 return BT_STATUS_FAIL;
1907 object_path = _bt_hal_get_device_object_path(address);
1908 if (object_path == NULL) {
1909 GVariant *ret = NULL;
1911 INFO("No searched device");
1912 adapter_proxy = _bt_hal_get_adapter_proxy();
1913 if (adapter_proxy == NULL) {
1914 ERR("adapter_proxy == NULL, return");
1915 return BT_STATUS_FAIL;
1918 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1919 g_variant_new("(s)", address),
1920 G_DBUS_CALL_FLAGS_NONE,
1921 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1924 ERR("CreateDevice Failed: %s", err->message);
1925 g_clear_error(&err);
1929 g_variant_unref(ret);
1931 g_object_unref(adapter_proxy);
1932 object_path = _bt_hal_get_device_object_path(address);
1933 if (object_path == NULL) {
1934 ERR("object_path == NULL, return");
1935 return BT_STATUS_FAIL;
1939 proxy = g_dbus_proxy_new_sync(conn,
1940 G_DBUS_PROXY_FLAGS_NONE, NULL,
1941 BT_HAL_BLUEZ_NAME, object_path,
1942 BT_HAL_DEVICE_INTERFACE, NULL, NULL);
1943 g_free(object_path);
1944 if (proxy == NULL) {
1945 ERR("Error while getting proxy");
1946 return BT_STATUS_FAIL;
1949 g_dbus_proxy_call(proxy, "DiscoverServices",
1950 g_variant_new("(s)", uuid),
1951 G_DBUS_CALL_FLAGS_NONE,
1952 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1953 (GAsyncReadyCallback)cb,
1956 return BT_STATUS_SUCCESS;
1959 int _bt_hal_cancel_discovers(char *address)
1963 GDBusProxy *adapter_proxy;
1965 GDBusConnection *conn;
1966 GVariant *ret = NULL;
1968 conn = _bt_hal_get_system_gconn();
1970 return BT_STATUS_FAIL;
1972 object_path = _bt_hal_get_device_object_path(address);
1973 if (object_path == NULL) {
1974 INFO("No searched device");
1975 adapter_proxy = _bt_hal_get_adapter_proxy();
1976 if (adapter_proxy == NULL) {
1977 ERR("adapter_proxy == NULL, return");
1978 return BT_STATUS_FAIL;
1981 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1982 g_variant_new("(s)", address),
1983 G_DBUS_CALL_FLAGS_NONE,
1984 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1988 ERR("CreateDevice Failed: %s", err->message);
1989 g_clear_error(&err);
1992 g_variant_unref(ret);
1995 g_object_unref(adapter_proxy);
1997 object_path = _bt_hal_get_device_object_path(address);
1998 if (object_path == NULL)
1999 return BT_STATUS_FAIL;
2002 proxy = g_dbus_proxy_new_sync(conn,
2003 G_DBUS_PROXY_FLAGS_NONE, NULL,
2004 BT_HAL_BLUEZ_NAME, object_path,
2005 BT_HAL_DEVICE_INTERFACE, NULL, NULL);
2006 g_free(object_path);
2007 ret = g_dbus_proxy_call_sync(proxy, "CancelDiscovery",
2009 G_DBUS_CALL_FLAGS_NONE,
2010 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
2014 ERR("DBus Error message: [%s]", err->message);
2015 g_clear_error(&err);
2016 return BT_STATUS_FAIL;
2019 g_variant_unref(ret);
2023 g_object_unref(proxy);
2025 return BT_STATUS_SUCCESS;
2028 int _bt_hal_discover_service_uuids(char *address, char *remote_uuid)
2032 GDBusConnection *gconn;
2034 char **uuid_value = NULL;
2037 GVariant *value = NULL;
2038 GVariant *ret = NULL;
2039 int result = BT_STATUS_FAIL;
2041 if (remote_uuid == NULL) {
2042 ERR("remote_uuid == NULL, return");
2043 return BT_STATUS_FAIL;
2046 gconn = _bt_hal_get_system_gconn();
2047 if (gconn == NULL) {
2048 ERR("gconn == NULL, return");
2049 return BT_STATUS_FAIL;
2052 object_path = _bt_hal_get_device_object_path(address);
2053 if (object_path == NULL) {
2054 ERR("object_path == NULL, return");
2055 return BT_STATUS_FAIL;
2058 proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE, NULL,
2059 BT_HAL_BLUEZ_NAME, object_path, BT_HAL_PROPERTIES_INTERFACE, NULL,
2061 if (proxy == NULL) {
2062 g_free(object_path);
2063 ERR("proxy == NULL, return");
2064 return BT_STATUS_FAIL;
2068 ERR("DBus Error: [%s]", err->message);
2069 g_clear_error(&err);
2072 ret = g_dbus_proxy_call_sync(proxy, "GetAll",
2073 g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
2074 G_DBUS_CALL_FLAGS_NONE,
2075 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
2078 result = BT_STATUS_FAIL;
2079 ERR("DBus Error : %s", err->message);
2080 g_clear_error(&err);
2085 ERR("g_dbus_proxy_call_sync function return NULL");
2086 result = BT_STATUS_FAIL;
2090 g_variant_get(ret, "(@a{sv})", &value);
2091 g_variant_unref(ret);
2093 GVariant *temp_value = g_variant_lookup_value(value, "UUIDs",
2094 G_VARIANT_TYPE_STRING_ARRAY);
2097 size = g_variant_get_size(temp_value);
2100 uuid_value = (char **)g_variant_get_strv(temp_value, &size);
2101 DBG("Size items %zu", size);
2105 g_variant_unref(temp_value);
2108 for (i = 0; uuid_value[i] != NULL; i++) {
2109 DBG("Remote uuids %s, searched uuid: %s",
2110 uuid_value[i], remote_uuid);
2111 if (strcasecmp(uuid_value[i], remote_uuid) == 0) {
2112 result = BT_STATUS_SUCCESS;
2121 g_object_unref(proxy);
2123 g_variant_unref(value);
2130 int bt_hal_gatt_convert_prop2string(
2131 bt_hal_gatt_characteristic_property_t properties,
2132 char *char_properties[])
2136 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_BROADCAST) {
2137 char_properties[flag_count] = g_strdup("broadcast");
2140 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_READ) {
2141 char_properties[flag_count] = g_strdup("read");
2144 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE) {
2145 char_properties[flag_count] = g_strdup("write-without-response");
2148 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE) {
2149 char_properties[flag_count] = g_strdup("write");
2152 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY) {
2153 char_properties[flag_count] = g_strdup("notify");
2156 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE) {
2157 char_properties[flag_count] = g_strdup("indicate");
2160 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE) {
2161 char_properties[flag_count] = g_strdup("authenticated-signed-writes");
2164 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE) {
2165 char_properties[flag_count] = g_strdup("reliable-write");
2168 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES) {
2169 char_properties[flag_count] = g_strdup("writable-auxiliaries");
2172 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ) {
2173 char_properties[flag_count] = g_strdup("encrypt-read");
2176 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE) {
2177 char_properties[flag_count] = g_strdup("encrypt-write");
2180 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ) {
2181 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
2184 if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE) {
2185 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
2189 if (flag_count == 0) {
2190 char_properties[flag_count] = g_strdup("read");
2197 int bt_hal_gatt_convert_perm2string(
2198 bt_hal_gatt_permission_t properties,
2199 char *char_properties[])
2203 if (properties & BT_HAL_GATT_PERMISSION_READ) {
2204 char_properties[flag_count] = g_strdup("read");
2207 if (properties & BT_HAL_GATT_PERMISSION_WRITE) {
2208 char_properties[flag_count] = g_strdup("write");
2211 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_READ) {
2212 char_properties[flag_count] = g_strdup("encrypt-read");
2215 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_WRITE) {
2216 char_properties[flag_count] = g_strdup("encrypt-write");
2219 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_READ) {
2220 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
2223 if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_WRITE) {
2224 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
2228 if (flag_count == 0) {
2229 char_properties[flag_count] = g_strdup("read");
2236 gboolean _bt_hal_is_service_enabled(const char *uuid)
2239 GError *error = NULL;
2242 GVariantIter *iter = NULL;
2244 gboolean ret = FALSE;
2246 proxy = _bt_hal_get_adapter_properties_proxy();
2248 DBG("_bt_hal_dbus_get_local_name: Adapter Properties proxy get failed!!!");
2252 result = g_dbus_proxy_call_sync(proxy,
2253 "Get", g_variant_new("(ss)",
2254 BT_HAL_ADAPTER_INTERFACE, "UUIDs"),
2255 G_DBUS_CALL_FLAGS_NONE, -1,
2258 if (error != NULL) {
2259 ERR("Failed to get UUIDs (Error: %s)", error->message);
2260 g_clear_error(&error);
2262 ERR("Failed to get UUIDs");
2266 g_variant_get(result, "(v)", &temp);
2267 g_variant_get(temp, "as", &iter);
2269 ERR("Failed to get UUIDs");
2270 g_variant_unref(result);
2274 while (g_variant_iter_loop(iter, "&s", &uuid_str)) {
2275 DBG("UUID string [%s]\n", uuid_str);
2276 if (!strncasecmp(uuid, uuid_str, strlen(uuid))) {
2282 g_variant_iter_free(iter);
2283 g_variant_unref(result);
2284 g_variant_unref(temp);