Get local IRK value
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-dbus-common-utils.c
1 /*
2  * BLUETOOTH HAL
3  *
4  * Copyright (c) 2015 -2016 Samsung Electronics Co., Ltd All Rights Reserved.
5  *
6  * Contact: Anupam Roy <anupam.r@samsung.com>
7  *
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
11  *
12  *              http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21
22 #include <stdio.h>
23 #include <stdint.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <fcntl.h>
27 #include <errno.h>
28 #include <termios.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31 #include <arpa/inet.h>
32
33 #include <dlog.h>
34 #include <glib.h>
35 #include <sys/prctl.h>
36 #include <gio/gio.h>
37 #include <gio/gunixfdlist.h>
38
39 #include "bt-hal-dbus-common-utils.h"
40
41 #include "bt-hal.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"
46
47 #define CASE_RETURN_STR(const) case const: return #const;
48
49 /**
50  * This is RFCOMM default Channel Value
51  */
52 #define RFCOMM_DEFAULT_PROFILE_CHANNEL 0
53 #define BT_AUDIO_SOURCE_MAX 2
54
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;
60
61 static GDBusProxy *adapter_properties_proxy;
62 static GDBusProxy *avrcp_ctrl_proxy;
63
64 struct avrcp_proxy {
65         GDBusProxy *avrcp_ctrl_proxy;
66         char *avrcp_control_path;
67         bt_bdaddr_t bd_addr;
68 };
69
70 static struct avrcp_proxy proxy_array[BT_AUDIO_SOURCE_MAX];
71
72 static guint bus_id;
73 static GDBusNodeInfo *new_conn_node;
74 static const gchar rfcomm_agent_xml[] =
75 "<node name='/'>"
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'/>"
81 "     </method>"
82 "     <method name='RequestDisconnection'>"
83 "          <arg type='o' name='device' direction='in'/>"
84 "     </method>"
85 "  </interface>"
86 "</node>";
87
88 static GDBusNodeInfo *new_l2cap_le_conn_node;
89 static const gchar l2cap_le_agent_xml[] =
90 "<node name='/'>"
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'/>"
95 "     </method>"
96 "  </interface>"
97 "</node>";
98
99 static GDBusConnection *__bt_hal_init_session_conn(void)
100 {
101         if (session_conn == NULL)
102                 session_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
103
104         return session_conn;
105 }
106
107 GDBusConnection *_bt_hal_get_session_gconn(void)
108 {
109         return (session_conn) ? session_conn : __bt_hal_init_session_conn();
110 }
111
112 static GDBusConnection *__bt_hal_init_system_gconn(void)
113 {
114         GError *error = NULL;
115
116         if (system_conn != NULL)
117                 return system_conn;
118
119         system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
120
121         if (!system_conn) {
122                 ERR("Unable to connect to dbus: %s", error->message);
123                 g_clear_error(&error);
124         }
125
126         return system_conn;
127 }
128
129 GDBusConnection *_bt_hal_get_system_gconn(void)
130 {
131         GDBusConnection *local_system_gconn = NULL;
132         GError *error = NULL;
133
134         if (system_conn == NULL) {
135                 system_conn = __bt_hal_init_system_gconn();
136         } else if (g_dbus_connection_is_closed(system_conn)) {
137
138                 local_system_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
139
140                 if (!local_system_gconn) {
141                         ERR("Unable to connect to dbus: %s", error->message);
142                         g_clear_error(&error);
143                 }
144
145                 system_conn = local_system_gconn;
146         }
147
148         return system_conn;
149 }
150
151 static GDBusProxy *__bt_hal_init_manager_proxy(void)
152 {
153         GDBusProxy *proxy;
154
155         if (system_conn == NULL) {
156                 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
157                 if (system_conn == NULL)
158                         return  NULL;
159         }
160
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);
164
165         if (proxy == NULL)
166                 return NULL;
167
168         manager_gproxy = proxy;
169
170         return proxy;
171 }
172
173 static GDBusProxy *__bt_hal_init_adapter_proxy(void)
174 {
175         GDBusProxy *manager_proxy;
176         GDBusProxy *proxy;
177         char *adapter_path = NULL;
178
179         if (system_conn == NULL) {
180                 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
181                 if (system_conn == NULL)
182                         return  NULL;
183         }
184
185         manager_proxy = _bt_hal_get_manager_proxy();
186         if (manager_proxy == NULL)
187                 return  NULL;
188
189         adapter_path = _bt_hal_get_adapter_path();
190         if (adapter_path == NULL)
191                 return  NULL;
192
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);
196
197         g_free(adapter_path);
198
199         if (proxy == NULL)
200                 return NULL;
201
202         adapter_gproxy = proxy;
203
204         return proxy;
205 }
206
207 static GDBusProxy *__bt_hal_init_adapter_properties_proxy(void)
208 {
209         GDBusProxy *manager_proxy;
210         GDBusProxy *proxy;
211         char *adapter_path = NULL;
212
213         if (system_conn == NULL) {
214                 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
215                 if (system_conn == NULL)
216                         return  NULL;
217         }
218
219         manager_proxy = _bt_hal_get_manager_proxy();
220         if (manager_proxy == NULL)
221                 return  NULL;
222
223         adapter_path = _bt_hal_get_adapter_path();
224         if (adapter_path == NULL)
225                 return   NULL;
226
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);
230
231         g_free(adapter_path);
232
233         if (proxy == NULL)
234                 return  NULL;
235
236         adapter_properties_proxy = proxy;
237
238         return proxy;
239 }
240
241 void _bt_hal_set_control_device_path(const char *path)
242 {
243         int i;
244
245         if (path == NULL)
246                 return;
247
248         DBG("control_path = %s", path);
249
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);
254                         return;
255                 }
256         }
257 }
258
259 void _bt_hal_remove_control_device_path(const char *path)
260 {
261         int i;
262
263         if (path == NULL)
264                 return;
265
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);
271
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);
275                         return;
276                 }
277         }
278 }
279
280 static char *__bt_hal_extract_control_device_path(GVariantIter *iter, char *address)
281 {
282         char *object_path = NULL;
283         char *interface_str = NULL;
284         GVariantIter *interface_iter;
285         char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
286
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)
290                         continue;
291
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);
299                                 }
300                         }
301                 }
302         }
303         return NULL;
304 }
305
306 static char *__bt_hal_extract_transport_device_path(GVariantIter *iter, char *address)
307 {
308         char *object_path = NULL;
309         char *interface_str = NULL;
310         GVariantIter *interface_iter;
311         char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
312
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)
316                         continue;
317
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);
325                                 }
326                         }
327                 }
328         }
329         return NULL;
330 }
331
332 static char *__bt_hal_get_control_device_object_path(char *address)
333 {
334         char *object_path = NULL;
335         GDBusConnection *conn;
336         GDBusProxy *manager_proxy;
337         GVariant *result = NULL;
338         GVariantIter *iter = NULL;
339
340         conn = _bt_hal_get_system_gconn();
341         if (conn == NULL)
342                 return NULL;
343
344         manager_proxy = _bt_hal_get_manager_proxy();
345         if (manager_proxy == NULL)
346                 return  NULL;
347
348         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
349                         NULL,
350                         G_DBUS_CALL_FLAGS_NONE,
351                         -1,
352                         NULL,
353                         NULL);
354         if (!result) {
355                 ERR("Can't get managed objects");
356                 return NULL;
357         }
358
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);
364         return object_path;
365 }
366
367 static char *__bt_hal_get_transport_device_object_path(char *address)
368 {
369         char *object_path = NULL;
370         GDBusConnection *conn;
371         GDBusProxy *manager_proxy;
372         GVariant *result = NULL;
373         GVariantIter *iter = NULL;
374
375         conn = _bt_hal_get_system_gconn();
376         if (conn == NULL)
377                 return NULL;
378
379         manager_proxy = _bt_hal_get_manager_proxy();
380         if (manager_proxy == NULL)
381                 return  NULL;
382
383         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
384                         NULL,
385                         G_DBUS_CALL_FLAGS_NONE,
386                         -1,
387                         NULL,
388                         NULL);
389         if (!result) {
390                 ERR("Can't get managed objects");
391                 return NULL;
392         }
393
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);
399         return object_path;
400 }
401
402 char *_bt_hal_get_control_device_path(bt_bdaddr_t *bd_addr)
403 {
404         char *control_path;
405         char connected_address[BT_HAL_ADDRESS_STRING_SIZE];
406
407         /* We can add the cache to get transport path for each device */
408
409         _bt_hal_convert_addr_type_to_string(connected_address, bd_addr->address);
410
411         control_path = __bt_hal_get_control_device_object_path(connected_address);
412         if (control_path == NULL)
413                 return NULL;
414
415         DBG("control_path = %s", control_path);
416         return control_path;
417 }
418
419 char *_bt_hal_get_transport_device_path(bt_bdaddr_t *bd_addr)
420 {
421         char *transport_path;
422         char connected_address[BT_HAL_ADDRESS_STRING_SIZE];
423
424         /* We can add the cache to get transport path for each device */
425
426         _bt_hal_convert_addr_type_to_string(connected_address, bd_addr->address);
427
428         transport_path = __bt_hal_get_transport_device_object_path(connected_address);
429         if (transport_path == NULL)
430                 return NULL;
431
432         DBG("transport_path = %s", transport_path);
433         return transport_path;
434 }
435
436 static GDBusProxy *__bt_hal_init_avrcp_ctrl_proxy(bt_bdaddr_t *bd_addr)
437 {
438         GDBusProxy *manager_proxy;
439         GDBusProxy *proxy;
440         GDBusConnection *gconn = NULL;
441         int i;
442
443         gconn = _bt_hal_get_system_gconn();
444         if (gconn == NULL)
445                 return  NULL;
446
447         manager_proxy = _bt_hal_get_manager_proxy();
448         if (manager_proxy == NULL)
449                 return  NULL;
450
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);
455                         break;
456                 }
457         }
458
459         if (i == BT_AUDIO_SOURCE_MAX) {
460                 ERR("NO free arr proxy space found");
461                 return NULL;
462         }
463
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);
467
468         if (proxy == NULL)
469                 return NULL;
470
471         avrcp_ctrl_proxy = proxy;
472         proxy_array[i].avrcp_ctrl_proxy = proxy;
473
474         return proxy;
475 }
476
477 GDBusProxy *_bt_hal_get_manager_proxy(void)
478 {
479         if (manager_gproxy) {
480                 const gchar *path =  g_dbus_proxy_get_object_path(manager_gproxy);
481                 if (path == NULL) {
482                         ERR("Already proxy released hence creating new proxy");
483                         return  __bt_hal_init_manager_proxy();
484                 }
485                 return manager_gproxy;
486         }
487         return  __bt_hal_init_manager_proxy();
488 }
489
490 GDBusProxy *_bt_hal_get_adapter_proxy(void)
491 {
492         if (adapter_gproxy) {
493                 const char *path =  g_dbus_proxy_get_object_path(adapter_gproxy);
494                 if (path == NULL) {
495                         ERR("Already proxy released hence creating new proxy");
496                         return  __bt_hal_init_adapter_proxy();
497                 }
498
499                 return adapter_gproxy;
500         }
501         return  __bt_hal_init_adapter_proxy();
502
503 }
504
505 GDBusProxy *_bt_hal_get_avrcp_ctrl_proxy(bt_bdaddr_t *bd_addr)
506 {
507         int i;
508
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);
513
514                         if (!path) {
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);
518                         }
519
520                         DBG("address found      path PATH %s", path);
521                         return proxy_array[i].avrcp_ctrl_proxy;
522                 }
523         }
524
525         DBG("address NOT found");
526
527         return  __bt_hal_init_avrcp_ctrl_proxy(bd_addr);
528 }
529
530 GDBusProxy *_bt_hal_get_avrcp_ctrl_properties_proxy(bt_bdaddr_t *bd_addr)
531 {
532         GDBusProxy *proxy;
533         GError *error = NULL;
534         char *control_path = NULL;
535         GDBusConnection *conn = NULL;
536
537         control_path = _bt_hal_get_control_device_path(bd_addr);
538         if (control_path == NULL)
539                 return  NULL;
540
541         DBG("control_path = %s", control_path);
542
543         conn = _bt_hal_get_system_gconn();
544         if (conn == NULL) {
545                 ERR("FAIL to get system connection");
546                 return NULL;
547         }
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);
551
552         if (proxy == NULL) {
553                 ERR("Unable to allocate new proxy");
554                 if (error) {
555                         ERR("%s", error->message);
556                         g_clear_error(&error);
557                 }
558                 return NULL;
559         }
560
561         return proxy;
562 }
563
564 GDBusProxy *_bt_hal_get_avrcp_transport_properties_proxy(bt_bdaddr_t *bd_addr)
565 {
566         GDBusProxy *proxy;
567         GError *error = NULL;
568         char *transport_path = NULL;
569         GDBusConnection *conn = NULL;
570
571         transport_path = _bt_hal_get_transport_device_path(bd_addr);
572         if (transport_path == NULL)
573                 return  NULL;
574
575         DBG("transport_path = %s", transport_path);
576
577         conn = _bt_hal_get_system_gconn();
578         if (conn == NULL) {
579                 ERR("FAIL to get system connection");
580                 return NULL;
581         }
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);
585
586         if (proxy == NULL) {
587                 ERR("Unable to allocate new proxy");
588                 if (error) {
589                         ERR("%s", error->message);
590                         g_clear_error(&error);
591                 }
592                 return NULL;
593         }
594
595         return proxy;
596 }
597
598 GDBusProxy *_bt_hal_get_adapter_properties_proxy(void)
599 {
600         return (adapter_properties_proxy) ? adapter_properties_proxy :
601                 __bt_hal_init_adapter_properties_proxy();
602 }
603
604 GDBusProxy *_bt_hal_get_profile_proxy(void)
605 {
606         GDBusConnection *gconn;
607         GError *err = NULL;
608
609         if (profile_gproxy)
610                 return profile_gproxy;
611
612         gconn = _bt_hal_get_system_gconn();
613         if (gconn == NULL) {
614                 ERR("_bt_hal_get_system_gconn failed");
615                 return NULL;
616         }
617
618         profile_gproxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE,
619                         NULL, BT_HAL_BLUEZ_NAME,
620                         "/org/bluez",
621                         "org.bluez.ProfileManager1",
622                         NULL, &err);
623         if (err) {
624                 ERR("Unable to create proxy: %s", err->message);
625                 g_clear_error(&err);
626                 return NULL;
627         }
628
629         return profile_gproxy;
630 }
631
632 static char *__bt_hal_extract_adapter_path(GVariantIter *iter)
633 {
634         char *object_path = NULL;
635         GVariantIter *interface_iter;
636         GVariantIter *svc_iter;
637         char *interface_str = NULL;
638
639         /* Parse the signature: oa{sa{sv}}} */
640         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
641                                 &interface_iter)) {
642
643                 if (object_path == NULL)
644                         continue;
645
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)
649                                 continue;
650
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);
656                 }
657         }
658         return NULL;
659 }
660
661 char *_bt_hal_get_adapter_path(void)
662 {
663         GDBusConnection *conn;
664         GDBusProxy *manager_proxy;
665         GVariant *result = NULL;
666         GVariantIter *iter = NULL;
667         char *adapter_path = NULL;
668
669         conn = _bt_hal_get_system_gconn();
670         if (conn == NULL)
671                 return  NULL;
672
673         manager_proxy = _bt_hal_get_manager_proxy();
674         if (manager_proxy == NULL)
675                 return NULL;
676
677         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
678                         NULL,
679                         G_DBUS_CALL_FLAGS_NONE,
680                         -1,
681                         NULL,
682                         NULL);
683         if (!result) {
684                 ERR("Can't get managed objects");
685                 return NULL;
686         }
687
688         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
689         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
690
691         adapter_path = __bt_hal_extract_adapter_path(iter);
692         g_variant_iter_free(iter);
693         g_variant_unref(result);
694
695         return adapter_path;
696 }
697
698 int _bt_hal_is_adapter_powered(gboolean *powered)
699 {
700         GDBusProxy *proxy;
701         GError *error = NULL;
702         GVariant *result;
703         GVariant *temp;
704         *powered = FALSE;
705
706         proxy = _bt_hal_get_adapter_properties_proxy();
707         if (proxy == NULL)
708                 return  BT_STATUS_FAIL;
709
710         result = g_dbus_proxy_call_sync(proxy,
711                         "Get",
712                         g_variant_new("(ss)", BT_HAL_ADAPTER_INTERFACE,
713                                 "Powered"),
714                         G_DBUS_CALL_FLAGS_NONE,
715                         -1,
716                         NULL,
717                         &error);
718
719         if (!result) {
720                 ERR("Failed to get powered status");
721                 if (error != NULL) {
722                         ERR("Failed to get powered status (Error: %s)", error->message);
723                         g_clear_error(&error);
724                 }
725                 return  BT_STATUS_FAIL;
726         }
727
728         g_variant_get(result, "(v)", &temp);
729         *powered = g_variant_get_boolean(temp);
730         INFO("powered: %d", *powered);
731
732         g_variant_unref(result);
733         g_variant_unref(temp);
734         return BT_STATUS_SUCCESS;
735 }
736
737 void _bt_hal_deinit_bluez_proxy(void)
738 {
739         if (manager_gproxy) {
740                 g_object_unref(manager_gproxy);
741                 manager_gproxy = NULL;
742         }
743
744         if (adapter_gproxy) {
745                 g_object_unref(adapter_gproxy);
746                 adapter_gproxy = NULL;
747         }
748         if (adapter_properties_proxy) {
749                 g_object_unref(adapter_properties_proxy);
750                 adapter_properties_proxy = NULL;
751         }
752 }
753
754 void _bt_hal_deinit_proxys(void)
755 {
756         _bt_hal_deinit_bluez_proxy();
757
758         if (system_conn) {
759                 g_object_unref(system_conn);
760                 system_conn = NULL;
761         }
762
763         if (session_conn) {
764                 g_object_unref(session_conn);
765                 session_conn = NULL;
766         }
767 }
768
769 GDBusProxy *_bt_hal_get_hid_agent_proxy(void)
770 {
771         GDBusConnection *conn;
772         GDBusProxy *proxy;
773         GError *err = NULL;
774
775         conn = _bt_hal_get_system_gconn();
776         if (conn == NULL) {
777                 ERR("_bt_hal_get_system_gconn failed");
778                 return NULL;
779         }
780
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);
784         if (proxy == NULL) {
785                 if (err != NULL) {
786                         ERR("Unable to create proxy: %s", err->message);
787                         g_clear_error(&err);
788                 }
789                 return NULL;
790         }
791
792         return proxy;
793 }
794
795 void _bt_hal_convert_device_path_to_address(const char *device_path,
796                 char *device_address)
797 {
798         char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
799         char *dev_addr;
800
801         if (device_path == NULL || device_address == NULL)
802                 return;
803
804         dev_addr = strstr(device_path, "dev_");
805         if (dev_addr != NULL) {
806                 char *pos = NULL;
807                 dev_addr += 4;
808                 g_strlcpy(address, dev_addr, sizeof(address));
809
810                 while ((pos = strchr(address, '_')) != NULL)
811                         *pos = ':';
812
813                 g_strlcpy(device_address, address, BT_HAL_ADDRESS_STRING_SIZE);
814         }
815 }
816
817 gboolean _bt_hal_uuid_is_standard(bt_uuid_t *p_uuid)
818 {
819         uint32_t uuid0, uuid4;
820         uint16_t uuid1, uuid2, uuid3, uuid5;
821         const char *uuid_name;
822         const char *uuid_name1;
823
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);
830
831         uuid_name = _bt_hal_dump_uuid_name(ntohl(uuid0));
832         uuid_name1 = _bt_hal_dump_uuid_name((ntohl(uuid4) >> 16));
833
834         DBG("UUID Name [%s]", uuid_name);
835         DBG("UUID Name Shifted [%s]", uuid_name1);
836
837         if (!g_strcmp0(uuid_name, "--"))
838                 return FALSE;
839         else
840                 return TRUE;
841
842 }
843
844 void _bt_hal_convert_uuid_string_to_type(unsigned char *uuid,
845                 const char *device_uuid)
846 {
847         uint32_t uuid0, uuid4;
848         uint16_t uuid1, uuid2, uuid3, uuid5;
849
850         sscanf(device_uuid, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
851                         &uuid0, &uuid1, &uuid2, &uuid3, &uuid4, &uuid5);
852
853         uuid0 = htonl(uuid0);
854         uuid1 = htons(uuid1);
855         uuid2 = htons(uuid2);
856         uuid3 = htons(uuid3);
857         uuid4 = htonl(uuid4);
858         uuid5 = htons(uuid5);
859
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);
866 }
867
868 void _bt_hal_convert_uuid_type_to_string(char *str, const unsigned char *uuid)
869 {
870         if (!str) {
871                 ERR("str == NULL");
872                 return;
873         }
874
875         if (!uuid) {
876                 ERR("uuid == NULL");
877                 return;
878         }
879
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]);
884 }
885
886 void _bt_hal_convert_addr_string_to_type(unsigned char *addr,
887                 const char *address)
888 {
889         int i;
890         char *ptr = NULL;
891
892         if (address == NULL || addr == NULL)
893                 return;
894
895         for (i = 0; i < BT_HAL_ADDRESS_LENGTH_MAX; i++) {
896                 addr[i] = strtol(address, &ptr, 16);
897
898                 if (ptr[0] != '\0') {
899                         if (ptr[0] != ':')
900                                 return;
901
902                         address = ptr + 1;
903                 }
904         }
905 }
906
907 void _bt_hal_convert_addr_type_to_string(char *address,
908                 const unsigned char *addr)
909 {
910         if (address == NULL || addr == NULL)
911                 return;
912
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]);
917 }
918
919 void _bt_hal_print_device_address_t(const bt_hal_device_address_t *addr)
920 {
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]);
923 }
924
925 void _bt_hal_divide_device_class(bt_hal_device_class_t *device_class,
926                 unsigned int cod)
927 {
928         if (device_class == NULL)
929                 return;
930
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));
934
935         if (cod & 0x002000) {
936                 device_class->service_class |=
937                         BT_HAL_DEVICE_SERVICE_CLASS_LIMITED_DISCOVERABLE_MODE;
938         }
939 }
940
941 int _bt_hal_copy_utf8_string(char *dest, const char *src, unsigned int length)
942 {
943         int i;
944         const char *p = src;
945         char *next;
946         int count;
947
948         if (dest == NULL || src == NULL)
949                 return BT_HAL_ERROR_INVALID_PARAM;
950
951         DBG("+src : %s", src);
952         DBG("+dest : %s", dest);
953
954         i = 0;
955         while (*p != '\0' && i < length) {
956                 next = g_utf8_next_char(p);
957                 count = next - p;
958
959                 while (count > 0 && ((i + count) < length)) {
960                         dest[i++] = *p;
961                         p++;
962                         count--;
963                 }
964                 p = next;
965         }
966         return BT_HAL_ERROR_NONE;
967 }
968
969 gboolean _bt_hal_utf8_validate(char *name)
970 {
971         gunichar2 *u16;
972         glong items_written = 0;
973
974         if (FALSE == g_utf8_validate(name, -1, NULL))
975                 return FALSE;
976
977         u16 = g_utf8_to_utf16(name, -1, NULL, &items_written, NULL);
978         if (u16 == NULL)
979                 return FALSE;
980
981         g_free(u16);
982
983         if (items_written != g_utf8_strlen(name, -1))
984                 return FALSE;
985
986         return TRUE;
987 }
988
989 int _bt_hal_set_socket_non_blocking(int socket_fd)
990 {
991         /* Set Nonblocking */
992         long arg;
993
994         arg = fcntl(socket_fd, F_GETFL);
995
996         if (arg < 0)
997                 return -errno;
998
999         if (arg & O_NONBLOCK)
1000                 ERR("Already Non-blocking \n");
1001
1002         arg |= O_NONBLOCK;
1003
1004         if (fcntl(socket_fd, F_SETFL, arg) < 0)
1005                 return -errno;
1006
1007         return BT_HAL_ERROR_NONE;
1008 }
1009
1010 int _bt_hal_set_non_blocking_tty(int sk)
1011 {
1012         struct termios ti = {0,};
1013         int err;
1014
1015         err = _bt_hal_set_socket_non_blocking(sk);
1016
1017         if (err < 0) {
1018                 ERR("Error in set non blocking!\n");
1019                 return err;
1020         }
1021
1022         tcflush(sk, TCIOFLUSH);
1023
1024         /* Switch tty to RAW mode */
1025         cfmakeraw(&ti);
1026         tcsetattr(sk, TCSANOW, &ti);
1027
1028         return BT_HAL_ERROR_NONE;
1029 }
1030
1031 static char *__bt_hal_extract_device_path(GVariantIter *iter, char *address)
1032 {
1033         char *object_path = NULL;
1034         char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
1035
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)
1039                         return  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);
1043         }
1044         return NULL;
1045 }
1046
1047 char *_bt_hal_get_device_object_path(char *address)
1048 {
1049         char *object_path = NULL;
1050         GDBusConnection *conn;
1051         GDBusProxy *manager_proxy;
1052         GVariant *result = NULL;
1053         GVariantIter *iter = NULL;
1054
1055         conn = _bt_hal_get_system_gconn();
1056         if (conn == NULL)
1057                 return NULL;
1058
1059         manager_proxy = _bt_hal_get_manager_proxy();
1060         if (manager_proxy == NULL)
1061                 return  NULL;
1062
1063         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
1064                         NULL,
1065                         G_DBUS_CALL_FLAGS_NONE,
1066                         -1,
1067                         NULL,
1068                         NULL);
1069         if (!result) {
1070                 ERR("Can't get managed objects");
1071                 return NULL;
1072         }
1073
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);
1079         return object_path;
1080 }
1081
1082 GVariant *_bt_hal_get_managed_objects(void)
1083 {
1084         GDBusConnection *conn;
1085         GDBusProxy *manager_proxy;
1086         GVariant *result = NULL;
1087         GError *error = NULL;
1088
1089         conn = _bt_hal_get_system_gconn();
1090         if (conn == NULL)
1091                 return NULL;
1092
1093         manager_proxy = _bt_hal_get_manager_proxy();
1094         if (manager_proxy == NULL)
1095                 return  NULL;
1096
1097         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
1098                         NULL,
1099                         G_DBUS_CALL_FLAGS_NONE,
1100                         -1,
1101                         NULL,
1102                         NULL);
1103         if (!result) {
1104                 ERR("Can't get managed objects");
1105                 return NULL;
1106         }
1107
1108         if (error) {
1109                 ERR("Fail to get ManagedObjects (Error: %s)", error->message);
1110                 g_clear_error(&error);
1111         }
1112
1113         return result;
1114 }
1115
1116
1117 char *_bt_hal_convert_error_to_string(int error)
1118 {
1119         switch (error) {
1120         case BT_HAL_ERROR_CANCEL:
1121                 return "CANCELLED";
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:
1130                 return "TIMEOUT";
1131         case BT_HAL_ERROR_NO_RESOURCES:
1132                 return "NO_RESOURCES";
1133         case BT_HAL_ERROR_INTERNAL:
1134                 return "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:
1148                 return "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:
1178                 return "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";
1193         default:
1194                 return "UNKNOWN";
1195         }
1196 }
1197
1198 char * _bt_hal_convert_disc_reason_to_string(int reason)
1199 {
1200         switch (reason) {
1201         case 1:
1202                 return "Link loss";
1203         case 2:
1204                 return "Connection terminated by local host";
1205         case 3:
1206                 return "Remote user terminated connection";
1207         case 0:
1208         default:
1209                 return "Unknown";
1210         }
1211 }
1212
1213 void _bt_hal_logging_connection(gboolean connect, int addr_type)
1214 {
1215         static int le_conn = 0;
1216         static int le_disc = 0;
1217         static int edr_conn = 0;
1218         static int edr_disc = 0;
1219
1220         if (connect) {
1221                 if (addr_type)
1222                         le_conn++;
1223                 else
1224                         edr_conn++;
1225         } else {
1226                 if (addr_type)
1227                         le_disc++;
1228                 else
1229                         edr_disc++;
1230         }
1231
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);
1234 }
1235
1236 void _bt_hal_swap_byte_ordering(char *data, int data_len)
1237 {
1238         char temp;
1239         int i, j;
1240
1241         if (data == NULL)
1242                 return;
1243         /* Swap to opposite endian */
1244         for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
1245                 temp = data[i];
1246                 data[i] = data[j];
1247                 data[j] = temp;
1248         }
1249 }
1250
1251 int _bt_hal_byte_arr_cmp(const char *data1, const char *data2, int data_len)
1252 {
1253         int i;
1254
1255         if (data1 == NULL || data2 == NULL)
1256                 return -1;
1257         for (i = 0; i < data_len; i++) {
1258                 if (data1[i] != data2[i])
1259                         return data1[i] - data2[i];
1260         }
1261         return 0;
1262 }
1263 int _bt_hal_byte_arr_cmp_with_mask(const char *data1, const char *data2,
1264                 const char *mask, int data_len)
1265 {
1266         int i;
1267         char a, b;
1268
1269         if (data1 == NULL || data2 == NULL || mask == NULL)
1270         return -1;
1271
1272         for (i = 0; i < data_len; i++) {
1273                 a = data1[i] & mask[i];
1274                 b = data2[i] & mask[i];
1275                 if (a != b)
1276                         return (int)(a - b);
1277         }
1278         return 0;
1279 }
1280
1281 int _bt_hal_connect_profile(char *address, char *uuid,
1282                 void *cb, gpointer func_data)
1283 {
1284         char *object_path;
1285         GDBusProxy *proxy;
1286         GDBusConnection *conn;
1287         GDBusProxy *adapter_proxy;
1288         GError *error = NULL;
1289         GVariant *result;
1290
1291         conn = _bt_hal_get_system_gconn();
1292         if (conn == NULL)
1293                 return  BT_HAL_ERROR_INTERNAL;
1294
1295         object_path = _bt_hal_get_device_object_path(address);
1296         if (object_path == NULL) {
1297                 ERR("No searched device");
1298
1299                 adapter_proxy = _bt_hal_get_adapter_proxy();
1300                 if (adapter_proxy == NULL)
1301                         return  BT_HAL_ERROR_INTERNAL;
1302
1303                 result = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1304                                 g_variant_new("(s)", address),
1305                                 G_DBUS_CALL_FLAGS_NONE,
1306                                 -1,
1307                                 NULL,
1308                                 &error);
1309                 if (!result) {
1310                         if (error) {
1311                                 ERR("CreateDevice Fail: %s", error->message);
1312                                 g_error_free(error);
1313                         }
1314                 } else {
1315                         g_variant_unref(result);
1316                 }
1317
1318                 object_path = _bt_hal_get_device_object_path(address);
1319         }
1320         if (object_path == NULL)
1321                 return  BT_HAL_ERROR_INTERNAL;
1322
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);
1327         if (proxy == NULL)
1328                 return  BT_HAL_ERROR_INTERNAL;
1329
1330
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,
1335                         NULL,
1336                         (GAsyncReadyCallback)cb,
1337                         func_data);
1338
1339         return BT_HAL_ERROR_NONE;
1340 }
1341
1342 int _bt_hal_disconnect_profile(char *address, char *uuid,
1343                 void *cb, gpointer func_data)
1344 {
1345         char *object_path;
1346         GDBusProxy *proxy;
1347         GDBusConnection *conn;
1348
1349         conn = _bt_hal_get_system_gconn();
1350         if (conn == NULL)
1351                 return  BT_HAL_ERROR_INTERNAL;
1352
1353         object_path = _bt_hal_get_device_object_path(address);
1354         if (object_path == NULL)
1355                 return  BT_HAL_ERROR_INTERNAL;
1356
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);
1361         if (proxy == NULL)
1362                 return  BT_HAL_ERROR_INTERNAL;
1363
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,
1368                         NULL,
1369                         (GAsyncReadyCallback)cb,
1370                         func_data);
1371
1372         return BT_HAL_ERROR_NONE;
1373 }
1374
1375 int _bt_hal_register_profile(bt_hal_register_profile_info_t *info, gboolean use_default_rfcomm)
1376 {
1377         GVariantBuilder *option_builder;
1378         GVariant *ret;
1379         GDBusProxy *proxy;
1380         GError *err = NULL;
1381         int result = BT_STATUS_SUCCESS;
1382
1383         proxy = _bt_hal_get_profile_proxy();
1384         if (proxy == NULL) {
1385                 ERR("Getting profile proxy failed");
1386                 return BT_STATUS_FAIL;
1387         }
1388
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));
1398         if (info->role)
1399                 g_variant_builder_add(option_builder, "{sv}",
1400                                 "Role",
1401                                 g_variant_new_string(info->role));
1402
1403         /*
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.
1408          */
1409         if (use_default_rfcomm)
1410                 g_variant_builder_add(option_builder, "{sv}",
1411                                 "Channel",
1412                                 g_variant_new_uint16(RFCOMM_DEFAULT_PROFILE_CHANNEL));
1413         if (info->service)
1414                 g_variant_builder_add(option_builder, "{sv}",
1415                                 "Service",
1416                                 g_variant_new_string(info->service));
1417
1418         ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile",
1419                         g_variant_new("(osa{sv})", info->obj_path,
1420                                 info->uuid,
1421                                 option_builder),
1422                         G_DBUS_CALL_FLAGS_NONE, -1,
1423                         NULL, &err);
1424         if (err) {
1425                 ERR("RegisterProfile failed: %s", err->message);
1426
1427                 if (g_strrstr(err->message, BT_HAL_ACCESS_DENIED_MSG))
1428                         result = BT_STATUS_AUTH_REJECTED;
1429                 else
1430                         result = BT_STATUS_FAIL;
1431
1432                 g_clear_error(&err);
1433         }
1434
1435         g_variant_builder_unref(option_builder);
1436
1437         if (ret)
1438                 g_variant_unref(ret);
1439
1440         return result;
1441 }
1442
1443 void _bt_hal_unregister_profile(char *path)
1444 {
1445         GVariant *ret;
1446         GDBusProxy *proxy;
1447         GError *err = NULL;
1448
1449         proxy = _bt_hal_get_profile_proxy();
1450         if (proxy == NULL) {
1451                 ERR("Getting profile proxy failed");
1452                 return;
1453         }
1454
1455         ret = g_dbus_proxy_call_sync(proxy, "UnregisterProfile",
1456                         g_variant_new("(o)", path),
1457                         G_DBUS_CALL_FLAGS_NONE, -1,
1458                         NULL, &err);
1459         if (err) {
1460                 ERR("UnregisterProfile failed : %s", err->message);
1461                 g_clear_error(&err);
1462         }
1463
1464         if (ret)
1465                 g_variant_unref(ret);
1466
1467         return;
1468 }
1469
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,
1477                 gpointer user_data)
1478 {
1479         DBG("method %s", method_name);
1480         if (g_strcmp0(method_name, "NewConnection") == 0) {
1481                 int index;
1482                 int fd;
1483                 GUnixFDList *fd_list;
1484                 GDBusMessage *msg;
1485                 GVariantBuilder *properties;
1486                 char *obj_path;
1487                 bt_bdaddr_t remote_addr1;
1488                 char addr[BT_HAL_ADDRESS_STRING_SIZE];
1489                 bt_hal_new_connection_cb cb = user_data;
1490
1491                 g_variant_get(parameters, "(oha{sv})", &obj_path, &index,
1492                                 &properties);
1493
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);
1500                         g_error_free(err);
1501                         return;
1502                 }
1503
1504
1505                 fd = g_unix_fd_list_get(fd_list, index, NULL);
1506                 if (fd == -1) {
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);
1511                         g_error_free(err);
1512                         return;
1513                 }
1514                 INFO("Object Path %s", obj_path);
1515
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);
1519
1520                 g_dbus_method_invocation_return_value(invocation, NULL);
1521
1522                 if (cb)
1523                         cb(object_path, fd, &remote_addr1);
1524                 else
1525                         close(fd);
1526         } else if (g_strcmp0(method_name, "RequestDisconnection") == 0) {
1527                 g_dbus_method_invocation_return_value(invocation, NULL);
1528         }
1529 }
1530
1531 int _bt_hal_connect_l2cap_le(char *address,
1532                         bt_hal_l2cap_le_profile_info_t *info, void *cb, gpointer func_data)
1533 {
1534         GVariantBuilder *option_builder;
1535         char *object_path;
1536         GDBusProxy *proxy;
1537         GDBusConnection *conn;
1538         GDBusProxy *adapter_proxy;
1539         GError *error = NULL;
1540         GVariant *result;
1541
1542         DBG("+");
1543         conn = _bt_hal_get_system_gconn();
1544         if (conn == NULL)
1545                 return  BT_HAL_ERROR_INTERNAL;
1546
1547         object_path = _bt_hal_get_device_object_path(address);
1548         if (object_path == NULL) {
1549                 ERR("No searched device");
1550
1551                 adapter_proxy = _bt_hal_get_adapter_proxy();
1552                 if (adapter_proxy == NULL)
1553                         return  BT_HAL_ERROR_INTERNAL;
1554
1555                 result = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1556                                 g_variant_new("(s)", address), G_DBUS_CALL_FLAGS_NONE,
1557                                 -1, NULL, &error);
1558
1559                 if (!result) {
1560                         if (error) {
1561                                 ERR("CreateDevice Fail: %s", error->message);
1562                                 g_error_free(error);
1563                         }
1564                 } else
1565                         g_variant_unref(result);
1566
1567                 object_path = _bt_hal_get_device_object_path(address);
1568         }
1569
1570         if (object_path == NULL) {
1571                 INFO("Not able to find device object");
1572                 return BT_HAL_ERROR_INTERNAL;
1573         }
1574
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);
1579
1580         if (proxy == NULL) {
1581                 INFO("proxy is null");
1582                 return BT_HAL_ERROR_INTERNAL;
1583         }
1584
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));
1590
1591         if (info->authorization)
1592                 g_variant_builder_add(option_builder, "{sv}",
1593                                 "RequireAuthorization",
1594                                 g_variant_new_boolean(TRUE));
1595
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);
1601
1602         g_variant_builder_unref(option_builder);
1603
1604         DBG("-");
1605         return BT_HAL_ERROR_NONE;
1606 }
1607
1608 int _bt_hal_listen_l2cap_le(bt_hal_l2cap_le_profile_info_t *info)
1609 {
1610         GVariantBuilder *option_builder;
1611         GVariant *ret;
1612         GDBusProxy *proxy;
1613         GError *err = NULL;
1614         int result = BT_STATUS_SUCCESS;
1615
1616         DBG("+");
1617         proxy = _bt_hal_get_adapter_proxy();
1618         if (proxy == NULL) {
1619                 ERR("Getting adapter profile proxy failed");
1620                 return BT_STATUS_FAIL;
1621         }
1622
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));
1628
1629         if (info->authorization)
1630                 g_variant_builder_add(option_builder, "{sv}",
1631                                 "RequireAuthorization",
1632                                 g_variant_new_boolean(TRUE));
1633
1634         ret = g_dbus_proxy_call_sync(proxy, "ListenL2capLESocket",
1635                         g_variant_new("(oia{sv})", info->obj_path, info->psm,
1636                                 option_builder),
1637                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1638
1639         if (err) {
1640                 ERR("Listen L2cap_LE failed: %s", err->message);
1641
1642                 if (g_strrstr(err->message, BT_HAL_ACCESS_DENIED_MSG))
1643                         result = BT_STATUS_AUTH_REJECTED;
1644                 else
1645                         result = BT_STATUS_FAIL;
1646
1647                 g_clear_error(&err);
1648         }
1649
1650         g_variant_builder_unref(option_builder);
1651
1652         if (ret)
1653                 g_variant_unref(ret);
1654
1655         DBG("-");
1656         return result;
1657 }
1658
1659 void _bt_hal_remove_l2cap_le_socket(char *path)
1660 {
1661         GVariant *ret;
1662         GDBusProxy *proxy;
1663         GError *err = NULL;
1664
1665         proxy = _bt_hal_get_adapter_proxy();
1666         if (proxy == NULL) {
1667                 ERR("Getting adapter profile proxy failed");
1668                 return;
1669         }
1670
1671         ret = g_dbus_proxy_call_sync(proxy, "RemoveL2capLESocket",
1672                         g_variant_new("(o)", path),
1673                         G_DBUS_CALL_FLAGS_NONE, -1,
1674                         NULL, &err);
1675         if (err) {
1676                 ERR("Remove socket l2cap le failed : %s", err->message);
1677                 g_clear_error(&err);
1678         }
1679
1680         if (ret)
1681                 g_variant_unref(ret);
1682
1683         return;
1684 }
1685
1686 int _bt_hal_get_psm_l2cap_le(bt_hal_l2cap_le_profile_info_t *info, uint32_t *psm)
1687 {
1688         GVariant *ret;
1689         GDBusProxy *proxy;
1690         GError *err = NULL;
1691         int result = BT_STATUS_SUCCESS;
1692
1693         proxy = _bt_hal_get_adapter_proxy();
1694         if (proxy == NULL) {
1695                 ERR("Getting adapter profile proxy failed");
1696                 return BT_STATUS_FAIL;
1697         }
1698
1699         ret = g_dbus_proxy_call_sync(proxy, "GetPSML2capLE",
1700                         g_variant_new("(o)", info->obj_path),
1701                         G_DBUS_CALL_FLAGS_NONE, -1,
1702                         NULL, &err);
1703         if (err) {
1704                 ERR("Get PSM L2cap_LE failed: %s", err->message);
1705                 result = BT_STATUS_FAIL;
1706                 g_clear_error(&err);
1707                 return result;
1708         }
1709
1710         g_variant_get(ret, "(u)", psm);
1711         INFO("PSM: %d", *psm);
1712
1713         if (ret)
1714                 g_variant_unref(ret);
1715
1716         return result;
1717 }
1718
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,
1726                 gpointer user_data)
1727 {
1728         INFO("method %s", method_name);
1729         if (g_strcmp0(method_name, "NewConnection") == 0) {
1730                 INFO("L2cap_LE New connection method");
1731                 int index;
1732                 int fd;
1733                 GUnixFDList *fd_list;
1734                 GDBusMessage *msg;
1735                 char *obj_path;
1736                 bt_bdaddr_t remote_addr1;
1737                 char addr[BT_HAL_ADDRESS_STRING_SIZE];
1738                 bt_hal_new_connection_cb cb = user_data;
1739
1740                 g_variant_get(parameters, "(oh)", &obj_path, &index);
1741
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);
1749                         g_error_free(err);
1750                         return;
1751                 }
1752
1753                 fd = g_unix_fd_list_get(fd_list, index, NULL);
1754                 if (fd == -1) {
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);
1759                         g_error_free(err);
1760                         return;
1761                 }
1762
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);
1766
1767                 g_dbus_method_invocation_return_value(invocation, NULL);
1768
1769                 if (cb)
1770                         cb(object_path, fd, &remote_addr1);
1771                 else
1772                         close(fd);
1773         }
1774 }
1775
1776 static GDBusNodeInfo *_bt_hal_get_gdbus_node(const gchar *xml_data)
1777 {
1778         if (bus_id == 0) {
1779                 char *name = g_strdup_printf("org.bt.frwk.p%d", getpid());
1780
1781                 bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1782                                 name,
1783                                 G_BUS_NAME_OWNER_FLAGS_NONE,
1784                                 NULL,
1785                                 NULL,
1786                                 NULL,
1787                                 NULL,
1788                                 NULL);
1789                 DBG("Got bus id %d", bus_id);
1790                 g_free(name);
1791         }
1792
1793         return g_dbus_node_info_new_for_xml(xml_data, NULL);
1794 }
1795
1796 static const GDBusInterfaceVTable method_table = {
1797         __hal_new_connection_method,
1798         NULL,
1799         NULL,
1800 };
1801
1802 static const GDBusInterfaceVTable l2cap_le_method_table = {
1803         __hal_l2cap_le_new_connection_method,
1804         NULL,
1805         NULL,
1806 };
1807
1808 int _bt_hal_register_new_gdbus_object(const char *path, bt_hal_new_connection_cb cb)
1809 {
1810         GDBusConnection *gconn;
1811         int id;
1812         GError *error = NULL;
1813
1814         gconn = _bt_hal_get_system_gconn();
1815         if (gconn == NULL)
1816                 return -1;
1817
1818         if (new_conn_node == NULL)
1819                 new_conn_node = _bt_hal_get_gdbus_node(rfcomm_agent_xml);
1820
1821         if (new_conn_node == NULL)
1822                 return -1;
1823
1824         id = g_dbus_connection_register_object(gconn, path,
1825                         new_conn_node->interfaces[0],
1826                         &method_table,
1827                         cb, NULL, &error);
1828         if (id == 0) {
1829                 ERR("Failed to register: %s", error->message);
1830                 g_error_free(error);
1831                 return -1;
1832         }
1833
1834         DBG("NEW CONNECTION ID %d", id);
1835
1836         return id;
1837 }
1838
1839 void _bt_hal_unregister_gdbus_object(int object_id)
1840 {
1841         GDBusConnection *gconn;
1842
1843         gconn = _bt_hal_get_system_gconn();
1844         if (gconn == NULL)
1845                 return;
1846
1847         g_dbus_connection_unregister_object(gconn, object_id);
1848 }
1849
1850 int _bt_hal_register_new_l2cap_le_gdbus_object(const char *path,
1851                                                 bt_hal_new_connection_cb cb)
1852 {
1853         GDBusConnection *gconn;
1854         int id;
1855         GError *error = NULL;
1856
1857         gconn = _bt_hal_get_system_gconn();
1858         if (gconn == NULL)
1859                 return -1;
1860
1861         if (new_l2cap_le_conn_node == NULL)
1862                 new_l2cap_le_conn_node = _bt_hal_get_gdbus_node(l2cap_le_agent_xml);
1863
1864         if (new_l2cap_le_conn_node == NULL)
1865                 return -1;
1866
1867         id = g_dbus_connection_register_object(gconn, path,
1868                         new_l2cap_le_conn_node->interfaces[0],
1869                         &l2cap_le_method_table,
1870                         cb, NULL, &error);
1871         if (id == 0) {
1872                 ERR("Failed to register: %s", error->message);
1873                 g_error_free(error);
1874                 return -1;
1875         }
1876
1877         INFO("L2CAP_LE NEW CONNECTION ID %d", id);
1878
1879         return id;
1880 }
1881
1882 void _bt_hal_unregister_l2cap_le_gdbus_object(int object_id)
1883 {
1884         GDBusConnection *gconn;
1885
1886         gconn = _bt_hal_get_system_gconn();
1887         if (gconn == NULL)
1888                 return;
1889
1890         g_dbus_connection_unregister_object(gconn, object_id);
1891 }
1892
1893 int _bt_hal_discover_services(char *address, char *uuid, void *cb, gpointer func_data)
1894 {
1895         char *object_path;
1896         GDBusProxy *proxy;
1897         GDBusProxy *adapter_proxy;
1898         GError *err = NULL;
1899         GDBusConnection *conn;
1900
1901         conn = _bt_hal_get_system_gconn();
1902         if (conn == NULL) {
1903                 ERR("conn == NULL, return");
1904                 return  BT_STATUS_FAIL;
1905         }
1906
1907         object_path = _bt_hal_get_device_object_path(address);
1908         if (object_path == NULL) {
1909                 GVariant *ret = NULL;
1910
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;
1916                 }
1917
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,
1922                                 &err);
1923                 if (err != NULL) {
1924                         ERR("CreateDevice Failed: %s", err->message);
1925                         g_clear_error(&err);
1926                 }
1927
1928                 if (ret)
1929                         g_variant_unref(ret);
1930
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;
1936                 }
1937         }
1938
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;
1947         }
1948
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,
1954                         func_data);
1955         DBG("-");
1956         return BT_STATUS_SUCCESS;
1957 }
1958
1959 int _bt_hal_cancel_discovers(char *address)
1960 {
1961         char *object_path;
1962         GDBusProxy *proxy;
1963         GDBusProxy *adapter_proxy;
1964         GError *err = NULL;
1965         GDBusConnection *conn;
1966         GVariant *ret = NULL;
1967
1968         conn = _bt_hal_get_system_gconn();
1969         if (conn == NULL)
1970                 return  BT_STATUS_FAIL;
1971
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;
1979                 }
1980
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,
1985                                 &err);
1986                 if (!ret) {
1987                         if (err) {
1988                                 ERR("CreateDevice Failed: %s", err->message);
1989                                 g_clear_error(&err);
1990                         }
1991                 } else {
1992                         g_variant_unref(ret);
1993                 }
1994
1995                 g_object_unref(adapter_proxy);
1996
1997                 object_path = _bt_hal_get_device_object_path(address);
1998                 if (object_path == NULL)
1999                         return BT_STATUS_FAIL;
2000         }
2001
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",
2008                         NULL,
2009                         G_DBUS_CALL_FLAGS_NONE,
2010                         BT_HAL_MAX_DBUS_TIMEOUT, NULL,
2011                         &err);
2012         if (!ret) {
2013                 if (err) {
2014                         ERR("DBus Error message: [%s]", err->message);
2015                         g_clear_error(&err);
2016                         return BT_STATUS_FAIL;
2017                 }
2018         } else {
2019                 g_variant_unref(ret);
2020         }
2021
2022         if (proxy)
2023                 g_object_unref(proxy);
2024
2025         return BT_STATUS_SUCCESS;
2026 }
2027
2028 int _bt_hal_discover_service_uuids(char *address, char *remote_uuid)
2029 {
2030         char *object_path;
2031         GDBusProxy *proxy;
2032         GDBusConnection *gconn;
2033         GError *err = NULL;
2034         char **uuid_value = NULL;
2035         gsize size = 0;
2036         int i = 0;
2037         GVariant *value = NULL;
2038         GVariant *ret = NULL;
2039         int result = BT_STATUS_FAIL;
2040
2041         if (remote_uuid == NULL) {
2042                 ERR("remote_uuid == NULL, return");
2043                 return BT_STATUS_FAIL;
2044         }
2045
2046         gconn = _bt_hal_get_system_gconn();
2047         if (gconn == NULL) {
2048                 ERR("gconn == NULL, return");
2049                 return BT_STATUS_FAIL;
2050         }
2051
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;
2056         }
2057
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,
2060                         &err);
2061         if (proxy == NULL) {
2062                 g_free(object_path);
2063                 ERR("proxy == NULL, return");
2064                 return BT_STATUS_FAIL;
2065         }
2066
2067         if (err) {
2068                 ERR("DBus Error: [%s]", err->message);
2069                 g_clear_error(&err);
2070         }
2071
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,
2076                         &err);
2077         if (err) {
2078                 result = BT_STATUS_FAIL;
2079                 ERR("DBus Error : %s", err->message);
2080                 g_clear_error(&err);
2081                 goto done;
2082         }
2083
2084         if (ret == NULL) {
2085                 ERR("g_dbus_proxy_call_sync function return NULL");
2086                 result = BT_STATUS_FAIL;
2087                 goto done;
2088         }
2089
2090         g_variant_get(ret, "(@a{sv})", &value);
2091         g_variant_unref(ret);
2092         if (value) {
2093                 GVariant *temp_value = g_variant_lookup_value(value, "UUIDs",
2094                                 G_VARIANT_TYPE_STRING_ARRAY);
2095
2096                 if (temp_value)
2097                         size = g_variant_get_size(temp_value);
2098
2099                 if (size > 0) {
2100                         uuid_value = (char **)g_variant_get_strv(temp_value, &size);
2101                         DBG("Size items %zu", size);
2102                 }
2103
2104                 if (temp_value)
2105                         g_variant_unref(temp_value);
2106
2107                 if (uuid_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;
2113                                         goto done;
2114                                 }
2115                         }
2116                 }
2117         }
2118
2119 done:
2120         if (proxy)
2121                 g_object_unref(proxy);
2122         if (value)
2123                 g_variant_unref(value);
2124         if (uuid_value)
2125                 g_free(uuid_value);
2126
2127         return result;
2128 }
2129
2130 int bt_hal_gatt_convert_prop2string(
2131                 bt_hal_gatt_characteristic_property_t properties,
2132                 char *char_properties[])
2133 {
2134         int flag_count = 0;
2135
2136         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_BROADCAST) {
2137                 char_properties[flag_count] = g_strdup("broadcast");
2138                 flag_count++;
2139         }
2140         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_READ) {
2141                 char_properties[flag_count] = g_strdup("read");
2142                 flag_count++;
2143         }
2144         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE) {
2145                 char_properties[flag_count] = g_strdup("write-without-response");
2146                 flag_count++;
2147         }
2148         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE) {
2149                 char_properties[flag_count] = g_strdup("write");
2150                 flag_count++;
2151         }
2152         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY) {
2153                 char_properties[flag_count] = g_strdup("notify");
2154                 flag_count++;
2155         }
2156         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE) {
2157                 char_properties[flag_count] = g_strdup("indicate");
2158                 flag_count++;
2159         }
2160         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE) {
2161                 char_properties[flag_count] = g_strdup("authenticated-signed-writes");
2162                 flag_count++;
2163         }
2164         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE) {
2165                 char_properties[flag_count] = g_strdup("reliable-write");
2166                 flag_count++;
2167         }
2168         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES) {
2169                 char_properties[flag_count] = g_strdup("writable-auxiliaries");
2170                 flag_count++;
2171         }
2172         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ) {
2173                 char_properties[flag_count] = g_strdup("encrypt-read");
2174                 flag_count++;
2175         }
2176         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE) {
2177                 char_properties[flag_count] = g_strdup("encrypt-write");
2178                 flag_count++;
2179         }
2180         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ) {
2181                 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
2182                 flag_count++;
2183         }
2184         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE) {
2185                 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
2186                 flag_count++;
2187         }
2188
2189         if (flag_count == 0) {
2190                 char_properties[flag_count] = g_strdup("read");
2191                 flag_count++;
2192         }
2193
2194         return flag_count;
2195 }
2196
2197 int bt_hal_gatt_convert_perm2string(
2198                 bt_hal_gatt_permission_t properties,
2199                 char *char_properties[])
2200 {
2201         int flag_count = 0;
2202
2203         if (properties & BT_HAL_GATT_PERMISSION_READ) {
2204                 char_properties[flag_count] = g_strdup("read");
2205                 flag_count++;
2206         }
2207         if (properties & BT_HAL_GATT_PERMISSION_WRITE) {
2208                 char_properties[flag_count] = g_strdup("write");
2209                 flag_count++;
2210         }
2211         if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_READ) {
2212                 char_properties[flag_count] = g_strdup("encrypt-read");
2213                 flag_count++;
2214         }
2215         if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_WRITE) {
2216                 char_properties[flag_count] = g_strdup("encrypt-write");
2217                 flag_count++;
2218         }
2219         if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_READ) {
2220                 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
2221                 flag_count++;
2222         }
2223         if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_WRITE) {
2224                 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
2225                 flag_count++;
2226         }
2227
2228         if (flag_count == 0) {
2229                 char_properties[flag_count] = g_strdup("read");
2230                 flag_count++;
2231         }
2232
2233         return flag_count;
2234 }
2235
2236 gboolean _bt_hal_is_service_enabled(const char *uuid)
2237 {
2238         GDBusProxy *proxy;
2239         GError *error = NULL;
2240         GVariant *result;
2241         GVariant *temp;
2242         GVariantIter *iter = NULL;
2243         gchar *uuid_str;
2244         gboolean ret = FALSE;
2245
2246         proxy = _bt_hal_get_adapter_properties_proxy();
2247         if (!proxy) {
2248                 DBG("_bt_hal_dbus_get_local_name: Adapter Properties proxy get failed!!!");
2249                 return FALSE;
2250         }
2251
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,
2256                         NULL, &error);
2257         if (!result) {
2258                 if (error != NULL) {
2259                         ERR("Failed to get UUIDs (Error: %s)", error->message);
2260                         g_clear_error(&error);
2261                 } else
2262                         ERR("Failed to get UUIDs");
2263                 return FALSE;
2264         }
2265
2266         g_variant_get(result, "(v)", &temp);
2267         g_variant_get(temp, "as", &iter);
2268         if (!iter) {
2269                 ERR("Failed to get UUIDs");
2270                 g_variant_unref(result);
2271                 return FALSE;
2272         }
2273
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))) {
2277                         ret = TRUE;
2278                         break;
2279                 }
2280         }
2281
2282         g_variant_iter_free(iter);
2283         g_variant_unref(result);
2284         g_variant_unref(temp);
2285
2286         return ret;
2287 }