90f74fcb08a4a0ed8eba17d9c0f7f8bbe423fd3d
[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 struct avrcp_proxy proxy_array[BT_AUDIO_SOURCE_MAX];
71
72 static guint bus_id;
73 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 GDBusConnection *__bt_hal_init_session_conn(void)
89 {
90         if (session_conn == NULL)
91                 session_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
92
93         return session_conn;
94 }
95
96 GDBusConnection *_bt_hal_get_session_gconn(void)
97 {
98         return (session_conn) ? session_conn : __bt_hal_init_session_conn();
99 }
100
101 static GDBusConnection *__bt_hal_init_system_gconn(void)
102 {
103         GError *error = NULL;
104
105         if (system_conn != NULL)
106                 return system_conn;
107
108         system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
109
110         if (!system_conn) {
111                 ERR("Unable to connect to dbus: %s", error->message);
112                 g_clear_error(&error);
113         }
114
115         return system_conn;
116 }
117
118 GDBusConnection *_bt_hal_get_system_gconn(void)
119 {
120         GDBusConnection *local_system_gconn = NULL;
121         GError *error = NULL;
122
123         if (system_conn == NULL) {
124                 system_conn = __bt_hal_init_system_gconn();
125         } else if (g_dbus_connection_is_closed(system_conn)) {
126
127                 local_system_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
128
129                 if (!local_system_gconn) {
130                         ERR("Unable to connect to dbus: %s", error->message);
131                         g_clear_error(&error);
132                 }
133
134                 system_conn = local_system_gconn;
135         }
136
137         return system_conn;
138 }
139
140 static GDBusProxy *__bt_hal_init_manager_proxy(void)
141 {
142         GDBusProxy *proxy;
143
144         if (system_conn == NULL) {
145                 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
146                 if (system_conn == NULL)
147                         return  NULL;
148         }
149
150         proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
151                         NULL, BT_HAL_BLUEZ_NAME,
152                         BT_HAL_MANAGER_PATH, BT_HAL_MANAGER_INTERFACE,  NULL, NULL);
153
154         if (proxy == NULL)
155                 return NULL;
156
157         manager_gproxy = proxy;
158
159         return proxy;
160 }
161
162 static GDBusProxy *__bt_hal_init_adapter_proxy(void)
163 {
164         GDBusProxy *manager_proxy;
165         GDBusProxy *proxy;
166         char *adapter_path = NULL;
167
168         if (system_conn == NULL) {
169                 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
170                 if (system_conn == NULL)
171                         return  NULL;
172         }
173
174         manager_proxy = _bt_hal_get_manager_proxy();
175         if (manager_proxy == NULL)
176                 return  NULL;
177
178         adapter_path = _bt_hal_get_adapter_path();
179         if (adapter_path == NULL)
180                 return  NULL;
181
182         proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
183                         NULL, BT_HAL_BLUEZ_NAME,
184                         adapter_path, BT_HAL_ADAPTER_INTERFACE,  NULL, NULL);
185
186         g_free(adapter_path);
187
188         if (proxy == NULL)
189                 return NULL;
190
191         adapter_gproxy = proxy;
192
193         return proxy;
194 }
195
196 static GDBusProxy *__bt_hal_init_adapter_properties_proxy(void)
197 {
198         GDBusProxy *manager_proxy;
199         GDBusProxy *proxy;
200         char *adapter_path = NULL;
201
202         if (system_conn == NULL) {
203                 system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
204                 if (system_conn == NULL)
205                         return  NULL;
206         }
207
208         manager_proxy = _bt_hal_get_manager_proxy();
209         if (manager_proxy == NULL)
210                 return  NULL;
211
212         adapter_path = _bt_hal_get_adapter_path();
213         if (adapter_path == NULL)
214                 return   NULL;
215
216         proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
217                         NULL, BT_HAL_BLUEZ_NAME,
218                         adapter_path, BT_HAL_PROPERTIES_INTERFACE,  NULL, NULL);
219
220         g_free(adapter_path);
221
222         if (proxy == NULL)
223                 return  NULL;
224
225         adapter_properties_proxy = proxy;
226
227         return proxy;
228 }
229
230 void _bt_hal_set_control_device_path(const char *path)
231 {
232         int i;
233
234         if (path == NULL)
235                 return;
236
237         DBG("control_path = %s", path);
238
239         for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
240                 if (proxy_array[i].avrcp_control_path == NULL) {
241                         proxy_array[i].avrcp_control_path = g_strdup(path);
242                         DBG("PATH %s formed index %d", proxy_array[i].avrcp_control_path, i);
243                         return;
244                 }
245         }
246 }
247
248 void _bt_hal_remove_control_device_path(const char *path)
249 {
250         int i;
251
252         if (path == NULL)
253                 return;
254
255         for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
256                 if (g_strcmp0(proxy_array[i].avrcp_control_path, path) == 0) {
257                         DBG("Clear AVRCP proxy[%d]", i);
258                         g_free(proxy_array[i].avrcp_control_path);
259                         g_object_unref(proxy_array[i].avrcp_ctrl_proxy);
260
261                         proxy_array[i].avrcp_control_path = NULL;
262                         proxy_array[i].avrcp_ctrl_proxy = NULL;
263                         memset(proxy_array[i].bd_addr.address, 0, 6);
264                         return;
265                 }
266         }
267 }
268
269 static char *__bt_hal_extract_control_device_path(GVariantIter *iter, char *address)
270 {
271         char *object_path = NULL;
272         char *interface_str = NULL;
273         GVariantIter *interface_iter;
274         char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
275
276         /* Parse the signature: oa{sa{sv}}} */
277         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
278                 if (object_path == NULL)
279                         continue;
280
281                 while(g_variant_iter_loop(interface_iter, "{&sa{sv}}", &interface_str, NULL)) {
282                         if (g_strcmp0(interface_str, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
283                                 _bt_hal_convert_device_path_to_address(object_path, device_address);
284                                 if (g_strcmp0(address, device_address) == 0) {
285                                         DBG("Object Path: %s", object_path);
286                                         g_variant_iter_free(interface_iter);
287                                         return g_strdup(object_path);
288                                 }
289                         }
290                 }
291         }
292         return NULL;
293 }
294
295 static char *__bt_hal_extract_transport_device_path(GVariantIter *iter, char *address)
296 {
297         char *object_path = NULL;
298         char *interface_str = NULL;
299         GVariantIter *interface_iter;
300         char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
301
302         /* Parse the signature: oa{sa{sv}}} */
303         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
304                 if (object_path == NULL)
305                         continue;
306
307                 while(g_variant_iter_loop(interface_iter, "{&sa{sv}}", &interface_str, NULL)) {
308                         if (g_strcmp0(interface_str, BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
309                                 _bt_hal_convert_device_path_to_address(object_path, device_address);
310                                 if (g_strcmp0(address, device_address) == 0) {
311                                         DBG("Object Path: %s", object_path);
312                                         g_variant_iter_free(interface_iter);
313                                         return g_strdup(object_path);
314                                 }
315                         }
316                 }
317         }
318         return NULL;
319 }
320
321 static char *__bt_hal_get_control_device_object_path(char *address)
322 {
323         char *object_path = NULL;
324         GDBusConnection *conn;
325         GDBusProxy *manager_proxy;
326         GVariant *result = NULL;
327         GVariantIter *iter = NULL;
328
329         conn = _bt_hal_get_system_gconn();
330         if (conn == NULL)
331                 return NULL;
332
333         manager_proxy = _bt_hal_get_manager_proxy();
334         if (manager_proxy == NULL)
335                 return  NULL;
336
337         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
338                         NULL,
339                         G_DBUS_CALL_FLAGS_NONE,
340                         -1,
341                         NULL,
342                         NULL);
343         if (!result) {
344                 ERR("Can't get managed objects");
345                 return NULL;
346         }
347
348         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
349         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
350         object_path = __bt_hal_extract_control_device_path(iter, address);
351         g_variant_iter_free(iter);
352         g_variant_unref(result);
353         return object_path;
354 }
355
356 static char *__bt_hal_get_transport_device_object_path(char *address)
357 {
358         char *object_path = NULL;
359         GDBusConnection *conn;
360         GDBusProxy *manager_proxy;
361         GVariant *result = NULL;
362         GVariantIter *iter = NULL;
363
364         conn = _bt_hal_get_system_gconn();
365         if (conn == NULL)
366                 return NULL;
367
368         manager_proxy = _bt_hal_get_manager_proxy();
369         if (manager_proxy == NULL)
370                 return  NULL;
371
372         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
373                         NULL,
374                         G_DBUS_CALL_FLAGS_NONE,
375                         -1,
376                         NULL,
377                         NULL);
378         if (!result) {
379                 ERR("Can't get managed objects");
380                 return NULL;
381         }
382
383         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
384         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
385         object_path = __bt_hal_extract_transport_device_path(iter, address);
386         g_variant_iter_free(iter);
387         g_variant_unref(result);
388         return object_path;
389 }
390
391 char *_bt_hal_get_control_device_path(bt_bdaddr_t *bd_addr)
392 {
393         char *control_path;
394         char connected_address[BT_HAL_ADDRESS_STRING_SIZE];
395
396         /* We can add the cache to get transport path for each device */
397
398         _bt_hal_convert_addr_type_to_string(connected_address, bd_addr->address);
399
400         control_path = __bt_hal_get_control_device_object_path(connected_address);
401         if (control_path == NULL)
402                 return NULL;
403
404         DBG("control_path = %s", control_path);
405         return control_path;
406 }
407
408 char *_bt_hal_get_transport_device_path(bt_bdaddr_t *bd_addr)
409 {
410         char *transport_path;
411         char connected_address[BT_HAL_ADDRESS_STRING_SIZE];
412
413         /* We can add the cache to get transport path for each device */
414
415         _bt_hal_convert_addr_type_to_string(connected_address, bd_addr->address);
416
417         transport_path = __bt_hal_get_transport_device_object_path(connected_address);
418         if (transport_path == NULL)
419                 return NULL;
420
421         DBG("transport_path = %s", transport_path);
422         return transport_path;
423 }
424
425 static GDBusProxy *__bt_hal_init_avrcp_ctrl_proxy(bt_bdaddr_t *bd_addr)
426 {
427         GDBusProxy *manager_proxy;
428         GDBusProxy *proxy;
429         GDBusConnection *gconn = NULL;
430         int i;
431
432         gconn = _bt_hal_get_system_gconn();
433         if (gconn == NULL)
434                 return  NULL;
435
436         manager_proxy = _bt_hal_get_manager_proxy();
437         if (manager_proxy == NULL)
438                 return  NULL;
439
440         for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
441                 if (proxy_array[i].avrcp_ctrl_proxy == NULL) {
442                         memcpy(proxy_array[i].bd_addr.address, bd_addr->address, 6);
443                         DBG("PATH %s formed index %d ", proxy_array[i].avrcp_control_path, i);
444                         break;
445                 }
446         }
447
448         if (i == BT_AUDIO_SOURCE_MAX) {
449                 ERR("NO free arr proxy space found");
450                 return NULL;
451         }
452
453         proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE,
454                         NULL, BT_HAL_BLUEZ_NAME,
455                         proxy_array[i].avrcp_control_path, BT_HAL_PLAYER_CONTROL_INTERFACE,  NULL, NULL);
456
457         if (proxy == NULL)
458                 return NULL;
459
460         avrcp_ctrl_proxy = proxy;
461         proxy_array[i].avrcp_ctrl_proxy = proxy;
462
463         return proxy;
464 }
465
466 GDBusProxy *_bt_hal_get_manager_proxy(void)
467 {
468         if (manager_gproxy) {
469                 const gchar *path =  g_dbus_proxy_get_object_path(manager_gproxy);
470                 if (path == NULL) {
471                         ERR("Already proxy released hence creating new proxy");
472                         return  __bt_hal_init_manager_proxy();
473                 }
474                 return manager_gproxy;
475         }
476         return  __bt_hal_init_manager_proxy();
477 }
478
479 GDBusProxy *_bt_hal_get_adapter_proxy(void)
480 {
481         if (adapter_gproxy) {
482                 const char *path =  g_dbus_proxy_get_object_path(adapter_gproxy);
483                 if (path == NULL) {
484                         ERR("Already proxy released hence creating new proxy");
485                         return  __bt_hal_init_adapter_proxy();
486                 }
487
488                 return adapter_gproxy;
489         }
490         return  __bt_hal_init_adapter_proxy();
491
492 }
493
494 GDBusProxy *_bt_hal_get_avrcp_ctrl_proxy(bt_bdaddr_t *bd_addr)
495 {
496         int i;
497
498         for (i = 0; i < BT_AUDIO_SOURCE_MAX; i++) {
499                 if (proxy_array[i].avrcp_ctrl_proxy
500                      && (!memcmp(proxy_array[i].bd_addr.address, bd_addr->address, 6))) {
501                         const gchar *path = g_dbus_proxy_get_object_path(proxy_array[i].avrcp_ctrl_proxy);
502
503                         if (!path) {
504                                 proxy_array[i].avrcp_ctrl_proxy = NULL;
505                                 ERR("Already proxy released hence creating new proxy");
506                                 return  __bt_hal_init_avrcp_ctrl_proxy(bd_addr);
507                         }
508
509                         DBG("address found      path PATH %s", path);
510                         return proxy_array[i].avrcp_ctrl_proxy;
511                 }
512         }
513
514         DBG("address NOT found");
515
516         return  __bt_hal_init_avrcp_ctrl_proxy(bd_addr);
517 }
518
519 GDBusProxy *_bt_hal_get_avrcp_ctrl_properties_proxy(bt_bdaddr_t *bd_addr)
520 {
521         GDBusProxy *proxy;
522         GError *error = NULL;
523         char *control_path = NULL;
524         GDBusConnection *conn = NULL;
525
526         control_path = _bt_hal_get_control_device_path(bd_addr);
527         if (control_path == NULL)
528                 return  NULL;
529
530         DBG("control_path = %s", control_path);
531
532         conn = _bt_hal_get_system_gconn();
533         if (conn == NULL) {
534                 ERR("FAIL to get system connection");
535                 return NULL;
536         }
537         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
538                         NULL, BT_HAL_BLUEZ_NAME,
539                         control_path, BT_HAL_PROPERTIES_INTERFACE,  NULL, &error);
540
541         if (proxy == NULL) {
542                 ERR("Unable to allocate new proxy");
543                 if (error) {
544                         ERR("%s", error->message);
545                         g_clear_error(&error);
546                 }
547                 return NULL;
548         }
549
550         return proxy;
551 }
552
553 GDBusProxy *_bt_hal_get_avrcp_transport_properties_proxy(bt_bdaddr_t *bd_addr)
554 {
555         GDBusProxy *proxy;
556         GError *error = NULL;
557         char *transport_path = NULL;
558         GDBusConnection *conn = NULL;
559
560         transport_path = _bt_hal_get_transport_device_path(bd_addr);
561         if (transport_path == NULL)
562                 return  NULL;
563
564         DBG("transport_path = %s", transport_path);
565
566         conn = _bt_hal_get_system_gconn();
567         if (conn == NULL) {
568                 ERR("FAIL to get system connection");
569                 return NULL;
570         }
571         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
572                         NULL, BT_HAL_BLUEZ_NAME,
573                         transport_path, BT_HAL_PROPERTIES_INTERFACE,  NULL, &error);
574
575         if (proxy == NULL) {
576                 ERR("Unable to allocate new proxy");
577                 if (error) {
578                         ERR("%s", error->message);
579                         g_clear_error(&error);
580                 }
581                 return NULL;
582         }
583
584         return proxy;
585 }
586
587 GDBusProxy *_bt_hal_get_adapter_properties_proxy(void)
588 {
589         return (adapter_properties_proxy) ? adapter_properties_proxy :
590                 __bt_hal_init_adapter_properties_proxy();
591 }
592
593 GDBusProxy *_bt_hal_get_profile_proxy(void)
594 {
595         GDBusConnection *gconn;
596         GError *err = NULL;
597
598         if (profile_gproxy)
599                 return profile_gproxy;
600
601         gconn = _bt_hal_get_system_gconn();
602         if (gconn == NULL) {
603                 ERR("_bt_hal_get_system_gconn failed");
604                 return NULL;
605         }
606
607         profile_gproxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE,
608                         NULL, BT_HAL_BLUEZ_NAME,
609                         "/org/bluez",
610                         "org.bluez.ProfileManager1",
611                         NULL, &err);
612         if (err) {
613                 ERR("Unable to create proxy: %s", err->message);
614                 g_clear_error(&err);
615                 return NULL;
616         }
617
618         return profile_gproxy;
619 }
620
621 static char *__bt_hal_extract_adapter_path(GVariantIter *iter)
622 {
623         char *object_path = NULL;
624         GVariantIter *interface_iter;
625         GVariantIter *svc_iter;
626         char *interface_str = NULL;
627
628         /* Parse the signature: oa{sa{sv}}} */
629         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
630                                 &interface_iter)) {
631
632                 if (object_path == NULL)
633                         continue;
634
635                 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
636                                         &interface_str, &svc_iter)) {
637                         if (g_strcmp0(interface_str, "org.bluez.Adapter1") != 0)
638                                 continue;
639
640                         DBG("Object Path: %s", object_path);
641                         g_free(interface_str);
642                         g_variant_iter_free(svc_iter);
643                         g_variant_iter_free(interface_iter);
644                         return g_strdup(object_path);
645                 }
646         }
647         return NULL;
648 }
649
650 char *_bt_hal_get_adapter_path(void)
651 {
652         GDBusConnection *conn;
653         GDBusProxy *manager_proxy;
654         GVariant *result = NULL;
655         GVariantIter *iter = NULL;
656         char *adapter_path = NULL;
657
658         conn = _bt_hal_get_system_gconn();
659         if (conn == NULL)
660                 return  NULL;
661
662         manager_proxy = _bt_hal_get_manager_proxy();
663         if (manager_proxy == NULL)
664                 return NULL;
665
666         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
667                         NULL,
668                         G_DBUS_CALL_FLAGS_NONE,
669                         -1,
670                         NULL,
671                         NULL);
672         if (!result) {
673                 ERR("Can't get managed objects");
674                 return NULL;
675         }
676
677         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
678         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
679
680         adapter_path = __bt_hal_extract_adapter_path(iter);
681         g_variant_iter_free(iter);
682         g_variant_unref(result);
683
684         return adapter_path;
685 }
686
687 int _bt_hal_is_adapter_powered(gboolean *powered)
688 {
689         GDBusProxy *proxy;
690         GError *error = NULL;
691         GVariant *result;
692         GVariant *temp;
693         *powered = FALSE;
694
695         proxy = _bt_hal_get_adapter_properties_proxy();
696         if (proxy == NULL)
697                 return  BT_STATUS_FAIL;
698
699         result = g_dbus_proxy_call_sync(proxy,
700                         "Get",
701                         g_variant_new("(ss)", BT_HAL_ADAPTER_INTERFACE,
702                                 "Powered"),
703                         G_DBUS_CALL_FLAGS_NONE,
704                         -1,
705                         NULL,
706                         &error);
707
708         if (!result) {
709                 ERR("Failed to get powered status");
710                 if (error != NULL) {
711                         ERR("Failed to get powered status (Error: %s)", error->message);
712                         g_clear_error(&error);
713                 }
714                 return  BT_STATUS_FAIL;
715         }
716
717         g_variant_get(result, "(v)", &temp);
718         *powered = g_variant_get_boolean(temp);
719         INFO("powered: %d", *powered);
720
721         g_variant_unref(result);
722         g_variant_unref(temp);
723         return BT_STATUS_SUCCESS;
724 }
725
726 void _bt_hal_deinit_bluez_proxy(void)
727 {
728         if (manager_gproxy) {
729                 g_object_unref(manager_gproxy);
730                 manager_gproxy = NULL;
731         }
732
733         if (adapter_gproxy) {
734                 g_object_unref(adapter_gproxy);
735                 adapter_gproxy = NULL;
736         }
737         if (adapter_properties_proxy) {
738                 g_object_unref(adapter_properties_proxy);
739                 adapter_properties_proxy = NULL;
740         }
741 }
742
743 void _bt_hal_deinit_proxys(void)
744 {
745         _bt_hal_deinit_bluez_proxy();
746
747         if (system_conn) {
748                 g_object_unref(system_conn);
749                 system_conn = NULL;
750         }
751
752         if (session_conn) {
753                 g_object_unref(session_conn);
754                 session_conn = NULL;
755         }
756 }
757
758 GDBusProxy *_bt_hal_get_hid_agent_proxy(void)
759 {
760         GDBusConnection *conn;
761         GDBusProxy *proxy;
762         GError *err = NULL;
763
764         conn = _bt_hal_get_system_gconn();
765         if (conn == NULL) {
766                 ERR("_bt_hal_get_system_gconn failed");
767                 return NULL;
768         }
769
770         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
771                                         BT_HAL_HID_SERVICE_NAME, BT_HAL_HID_AGENT_OBJECT_PATH,
772                                         BT_HAL_HID_SERVICE_INTERFACE, NULL, &err);
773         if (proxy == NULL) {
774                 if (err != NULL) {
775                         ERR("Unable to create proxy: %s", err->message);
776                         g_clear_error(&err);
777                 }
778                 return NULL;
779         }
780
781         return proxy;
782 }
783
784 void _bt_hal_convert_device_path_to_address(const char *device_path,
785                 char *device_address)
786 {
787         char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
788         char *dev_addr;
789
790         if (device_path == NULL || device_address == NULL)
791                 return;
792
793         dev_addr = strstr(device_path, "dev_");
794         if (dev_addr != NULL) {
795                 char *pos = NULL;
796                 dev_addr += 4;
797                 g_strlcpy(address, dev_addr, sizeof(address));
798
799                 while ((pos = strchr(address, '_')) != NULL)
800                         *pos = ':';
801
802                 g_strlcpy(device_address, address, BT_HAL_ADDRESS_STRING_SIZE);
803         }
804 }
805
806 gboolean _bt_hal_uuid_is_standard(bt_uuid_t *p_uuid)
807 {
808         uint32_t uuid0, uuid4;
809         uint16_t uuid1, uuid2, uuid3, uuid5;
810         const char *uuid_name;
811         const char *uuid_name1;
812
813         memcpy(&uuid0, &(p_uuid->uu[0]), 4);
814         memcpy(&uuid1, &(p_uuid->uu[4]), 2);
815         memcpy(&uuid2, &(p_uuid->uu[6]), 2);
816         memcpy(&uuid3, &(p_uuid->uu[8]), 2);
817         memcpy(&uuid4, &(p_uuid->uu[10]), 4);
818         memcpy(&uuid5, &(p_uuid->uu[14]), 2);
819
820         uuid_name = _bt_hal_dump_uuid_name(ntohl(uuid0));
821         uuid_name1 = _bt_hal_dump_uuid_name((ntohl(uuid4) >> 16));
822
823         DBG("UUID Name [%s]", uuid_name);
824         DBG("UUID Name Shifted [%s]", uuid_name1);
825
826         if (!g_strcmp0(uuid_name, "--"))
827                 return FALSE;
828         else
829                 return TRUE;
830
831 }
832
833 void _bt_hal_convert_uuid_string_to_type(unsigned char *uuid,
834                 const char *device_uuid)
835 {
836         uint32_t uuid0, uuid4;
837         uint16_t uuid1, uuid2, uuid3, uuid5;
838
839         sscanf(device_uuid, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
840                         &uuid0, &uuid1, &uuid2, &uuid3, &uuid4, &uuid5);
841
842         uuid0 = htonl(uuid0);
843         uuid1 = htons(uuid1);
844         uuid2 = htons(uuid2);
845         uuid3 = htons(uuid3);
846         uuid4 = htonl(uuid4);
847         uuid5 = htons(uuid5);
848
849         memcpy(&(uuid[0]), &uuid0, 4);
850         memcpy(&(uuid[4]), &uuid1, 2);
851         memcpy(&(uuid[6]), &uuid2, 2);
852         memcpy(&(uuid[8]), &uuid3, 2);
853         memcpy(&(uuid[10]), &uuid4, 4);
854         memcpy(&(uuid[14]), &uuid5, 2);
855 }
856
857 void _bt_hal_convert_uuid_type_to_string(char *str, const unsigned char *uuid)
858 {
859         if (!str) {
860                 ERR("str == NULL");
861                 return;
862         }
863
864         if (!uuid) {
865                 ERR("uuid == NULL");
866                 return;
867         }
868
869         snprintf(str, BT_HAL_UUID_STRING_LEN,
870                         "%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",
871                         uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
872                         uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
873 }
874
875 void _bt_hal_convert_addr_string_to_type(unsigned char *addr,
876                 const char *address)
877 {
878         int i;
879         char *ptr = NULL;
880
881         if (address == NULL || addr == NULL)
882                 return;
883
884         for (i = 0; i < BT_HAL_ADDRESS_LENGTH_MAX; i++) {
885                 addr[i] = strtol(address, &ptr, 16);
886
887                 if (ptr[0] != '\0') {
888                         if (ptr[0] != ':')
889                                 return;
890
891                         address = ptr + 1;
892                 }
893         }
894 }
895
896 void _bt_hal_convert_addr_type_to_string(char *address,
897                 const unsigned char *addr)
898 {
899         if (address == NULL || addr == NULL)
900                 return;
901
902         snprintf(address, BT_HAL_ADDRESS_STRING_SIZE,
903                         "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
904                         addr[0], addr[1], addr[2],
905                         addr[3], addr[4], addr[5]);
906 }
907
908 void _bt_hal_print_device_address_t(const bt_hal_device_address_t *addr)
909 {
910         DBG("%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", addr->addr[0], addr->addr[1], addr->addr[2],
911                         addr->addr[3], addr->addr[4], addr->addr[5]);
912 }
913
914 void _bt_hal_divide_device_class(bt_hal_device_class_t *device_class,
915                 unsigned int cod)
916 {
917         if (device_class == NULL)
918                 return;
919
920         device_class->major_class = (unsigned short)(cod & 0x00001F00) >> 8;
921         device_class->minor_class = (unsigned short)((cod & 0x000000FC));
922         device_class->service_class = (unsigned long)((cod & 0x00FF0000));
923
924         if (cod & 0x002000) {
925                 device_class->service_class |=
926                         BT_HAL_DEVICE_SERVICE_CLASS_LIMITED_DISCOVERABLE_MODE;
927         }
928 }
929
930 int _bt_hal_copy_utf8_string(char *dest, const char *src, unsigned int length)
931 {
932         int i;
933         const char *p = src;
934         char *next;
935         int count;
936
937         if (dest == NULL || src == NULL)
938                 return BT_HAL_ERROR_INVALID_PARAM;
939
940         DBG("+src : %s", src);
941         DBG("+dest : %s", dest);
942
943         i = 0;
944         while (*p != '\0' && i < length) {
945                 next = g_utf8_next_char(p);
946                 count = next - p;
947
948                 while (count > 0 && ((i + count) < length)) {
949                         dest[i++] = *p;
950                         p++;
951                         count--;
952                 }
953                 p = next;
954         }
955         return BT_HAL_ERROR_NONE;
956 }
957
958 gboolean _bt_hal_utf8_validate(char *name)
959 {
960         gunichar2 *u16;
961         glong items_written = 0;
962
963         if (FALSE == g_utf8_validate(name, -1, NULL))
964                 return FALSE;
965
966         u16 = g_utf8_to_utf16(name, -1, NULL, &items_written, NULL);
967         if (u16 == NULL)
968                 return FALSE;
969
970         g_free(u16);
971
972         if (items_written != g_utf8_strlen(name, -1))
973                 return FALSE;
974
975         return TRUE;
976 }
977
978 int _bt_hal_set_socket_non_blocking(int socket_fd)
979 {
980         /* Set Nonblocking */
981         long arg;
982
983         arg = fcntl(socket_fd, F_GETFL);
984
985         if (arg < 0)
986                 return -errno;
987
988         if (arg & O_NONBLOCK)
989                 ERR("Already Non-blocking \n");
990
991         arg |= O_NONBLOCK;
992
993         if (fcntl(socket_fd, F_SETFL, arg) < 0)
994                 return -errno;
995
996         return BT_HAL_ERROR_NONE;
997 }
998
999 int _bt_hal_set_non_blocking_tty(int sk)
1000 {
1001         struct termios ti = {0,};
1002         int err;
1003
1004         err = _bt_hal_set_socket_non_blocking(sk);
1005
1006         if (err < 0) {
1007                 ERR("Error in set non blocking!\n");
1008                 return err;
1009         }
1010
1011         tcflush(sk, TCIOFLUSH);
1012
1013         /* Switch tty to RAW mode */
1014         cfmakeraw(&ti);
1015         tcsetattr(sk, TCSANOW, &ti);
1016
1017         return BT_HAL_ERROR_NONE;
1018 }
1019
1020 static char *__bt_hal_extract_device_path(GVariantIter *iter, char *address)
1021 {
1022         char *object_path = NULL;
1023         char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
1024
1025         /* Parse the signature: oa{sa{sv}}} */
1026         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, NULL)) {
1027                 if (object_path == NULL)
1028                         return  NULL;
1029                 _bt_hal_convert_device_path_to_address(object_path, device_address);
1030                 if (g_strcmp0(address, device_address) == 0)
1031                         return g_strdup(object_path);
1032         }
1033         return NULL;
1034 }
1035
1036 char *_bt_hal_get_device_object_path(char *address)
1037 {
1038         char *object_path = NULL;
1039         GDBusConnection *conn;
1040         GDBusProxy *manager_proxy;
1041         GVariant *result = NULL;
1042         GVariantIter *iter = NULL;
1043
1044         conn = _bt_hal_get_system_gconn();
1045         if (conn == NULL)
1046                 return NULL;
1047
1048         manager_proxy = _bt_hal_get_manager_proxy();
1049         if (manager_proxy == NULL)
1050                 return  NULL;
1051
1052         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
1053                         NULL,
1054                         G_DBUS_CALL_FLAGS_NONE,
1055                         -1,
1056                         NULL,
1057                         NULL);
1058         if (!result) {
1059                 ERR("Can't get managed objects");
1060                 return NULL;
1061         }
1062
1063         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
1064         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
1065         object_path = __bt_hal_extract_device_path(iter, address);
1066         g_variant_iter_free(iter);
1067         g_variant_unref(result);
1068         return object_path;
1069 }
1070
1071 GVariant *_bt_hal_get_managed_objects(void)
1072 {
1073         GDBusConnection *conn;
1074         GDBusProxy *manager_proxy;
1075         GVariant *result = NULL;
1076         GError *error = NULL;
1077
1078         conn = _bt_hal_get_system_gconn();
1079         if (conn == NULL)
1080                 return NULL;
1081
1082         manager_proxy = _bt_hal_get_manager_proxy();
1083         if (manager_proxy == NULL)
1084                 return  NULL;
1085
1086         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
1087                         NULL,
1088                         G_DBUS_CALL_FLAGS_NONE,
1089                         -1,
1090                         NULL,
1091                         NULL);
1092         if (!result) {
1093                 ERR("Can't get managed objects");
1094                 return NULL;
1095         }
1096
1097         if (error) {
1098                 ERR("Fail to get ManagedObjects (Error: %s)", error->message);
1099                 g_clear_error(&error);
1100         }
1101
1102         return result;
1103 }
1104
1105
1106 char *_bt_hal_convert_error_to_string(int error)
1107 {
1108         switch (error) {
1109         case BT_HAL_ERROR_CANCEL:
1110                 return "CANCELLED";
1111         case BT_HAL_ERROR_INVALID_PARAM:
1112                 return "INVALID_PARAMETER";
1113         case BT_HAL_ERROR_INVALID_DATA:
1114                 return "INVALID DATA";
1115         case BT_HAL_ERROR_MEMORY_ALLOCATION:
1116         case BT_HAL_ERROR_OUT_OF_MEMORY:
1117                 return "OUT_OF_MEMORY";
1118         case BT_HAL_ERROR_TIMEOUT:
1119                 return "TIMEOUT";
1120         case BT_HAL_ERROR_NO_RESOURCES:
1121                 return "NO_RESOURCES";
1122         case BT_HAL_ERROR_INTERNAL:
1123                 return "INTERNAL";
1124         case BT_HAL_ERROR_NOT_SUPPORT:
1125                 return "NOT_SUPPORT";
1126         case BT_HAL_ERROR_DEVICE_NOT_ENABLED:
1127                 return "NOT_ENABLED";
1128         case BT_HAL_ERROR_DEVICE_ALREADY_ENABLED:
1129                 return "ALREADY_ENABLED";
1130         case BT_HAL_ERROR_DEVICE_BUSY:
1131                 return "DEVICE_BUSY";
1132         case BT_HAL_ERROR_ACCESS_DENIED:
1133                 return "ACCESS_DENIED";
1134         case BT_HAL_ERROR_MAX_CLIENT:
1135                 return "MAX_CLIENT";
1136         case BT_HAL_ERROR_NOT_FOUND:
1137                 return "NOT_FOUND";
1138         case BT_HAL_ERROR_SERVICE_SEARCH_ERROR:
1139                 return "SERVICE_SEARCH_ERROR";
1140         case BT_HAL_ERROR_PARING_FAILED:
1141                 return "PARING_FAILED";
1142         case BT_HAL_ERROR_NOT_PAIRED:
1143                 return "NOT_PAIRED";
1144         case BT_HAL_ERROR_SERVICE_NOT_FOUND:
1145                 return "SERVICE_NOT_FOUND";
1146         case BT_HAL_ERROR_NOT_CONNECTED:
1147                 return "NOT_CONNECTED";
1148         case BT_HAL_ERROR_ALREADY_CONNECT:
1149                 return "ALREADY_CONNECT";
1150         case BT_HAL_ERROR_CONNECTION_BUSY:
1151                 return "CONNECTION_BUSY";
1152         case BT_HAL_ERROR_CONNECTION_ERROR:
1153                 return "CONNECTION_ERROR";
1154         case BT_HAL_ERROR_MAX_CONNECTION:
1155                 return "MAX_CONNECTION";
1156         case BT_HAL_ERROR_NOT_IN_OPERATION:
1157                 return "NOT_IN_OPERATION";
1158         case BT_HAL_ERROR_CANCEL_BY_USER:
1159                 return "CANCEL_BY_USER";
1160         case BT_HAL_ERROR_REGISTRATION_FAILED:
1161                 return "REGISTRATION_FAILED";
1162         case BT_HAL_ERROR_IN_PROGRESS:
1163                 return "IN_PROGRESS";
1164         case BT_HAL_ERROR_AUTHENTICATION_FAILED:
1165                 return "AUTHENTICATION_FAILED";
1166         case BT_HAL_ERROR_HOST_DOWN:
1167                 return "HOST_DOWN";
1168         case BT_HAL_ERROR_END_OF_DEVICE_LIST:
1169                 return "END_OF_DEVICE_LIST";
1170         case BT_HAL_ERROR_AGENT_ALREADY_EXIST:
1171                 return "AGENT_ALREADY_EXIST";
1172         case BT_HAL_ERROR_AGENT_DOES_NOT_EXIST:
1173                 return "AGENT_DOES_NOT_EXIST";
1174         case BT_HAL_ERROR_ALREADY_INITIALIZED:
1175                 return "ALREADY_INITIALIZED";
1176         case BT_HAL_ERROR_PERMISSION_DEINED:
1177                 return "PERMISSION_DEINED";
1178         case BT_HAL_ERROR_ALREADY_DEACTIVATED:
1179                 return "ALREADY_DEACTIVATED";
1180         case BT_HAL_ERROR_NOT_INITIALIZED:
1181                 return "NOT_INITIALIZED";
1182         default:
1183                 return "UNKNOWN";
1184         }
1185 }
1186
1187 char * _bt_hal_convert_disc_reason_to_string(int reason)
1188 {
1189         switch (reason) {
1190         case 1:
1191                 return "Link loss";
1192         case 2:
1193                 return "Connection terminated by local host";
1194         case 3:
1195                 return "Remote user terminated connection";
1196         case 0:
1197         default:
1198                 return "Unknown";
1199         }
1200 }
1201
1202 int _bt_hal_convert_disc_reason_to_status(int reason)
1203 {
1204         switch (reason) {
1205         case 1:
1206                 return BT_STATUS_CONN_TOUT; //"Link loss"
1207         case 2:
1208                 return BT_STATUS_CONN_TERM_LOCAL_HOST; //"Connection terminated by local host";
1209         case 3:
1210                 return BT_STATUS_CONN_TERM_RMT_HOST; //"Connection terminated by local host";
1211         case 0:
1212         default:
1213                 return BT_STATUS_FAIL;
1214         }
1215 }
1216
1217 void _bt_hal_logging_connection(gboolean connect, int addr_type)
1218 {
1219         static int le_conn = 0;
1220         static int le_disc = 0;
1221         static int edr_conn = 0;
1222         static int edr_disc = 0;
1223
1224         if (connect) {
1225                 if (addr_type)
1226                         le_conn++;
1227                 else
1228                         edr_conn++;
1229         } else {
1230                 if (addr_type)
1231                         le_disc++;
1232                 else
1233                         edr_disc++;
1234         }
1235
1236         INFO("[PM] Number of LE conn: %d disc: %d, Number of BR/EDR conn: %d disc: %d",
1237                         le_conn, le_disc, edr_conn, edr_disc);
1238 }
1239
1240 void _bt_hal_swap_byte_ordering(char *data, int data_len)
1241 {
1242         char temp;
1243         int i, j;
1244
1245         if (data == NULL)
1246                 return;
1247         /* Swap to opposite endian */
1248         for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
1249                 temp = data[i];
1250                 data[i] = data[j];
1251                 data[j] = temp;
1252         }
1253 }
1254
1255 int _bt_hal_byte_arr_cmp(const char *data1, const char *data2, int data_len)
1256 {
1257         int i;
1258
1259         if (data1 == NULL || data2 == NULL)
1260                 return -1;
1261         for (i = 0; i < data_len; i++) {
1262                 if (data1[i] != data2[i])
1263                         return data1[i] - data2[i];
1264         }
1265         return 0;
1266 }
1267 int _bt_hal_byte_arr_cmp_with_mask(const char *data1, const char *data2,
1268                 const char *mask, int data_len)
1269 {
1270         int i;
1271         char a, b;
1272
1273         if (data1 == NULL || data2 == NULL || mask == NULL)
1274         return -1;
1275
1276         for (i = 0; i < data_len; i++) {
1277                 a = data1[i] & mask[i];
1278                 b = data2[i] & mask[i];
1279                 if (a != b)
1280                         return (int)(a - b);
1281         }
1282         return 0;
1283 }
1284
1285 int _bt_hal_connect_profile(char *address, char *uuid,
1286                 void *cb, gpointer func_data)
1287 {
1288         char *object_path;
1289         GDBusProxy *proxy;
1290         GDBusConnection *conn;
1291         GDBusProxy *adapter_proxy;
1292         GError *error = NULL;
1293
1294         conn = _bt_hal_get_system_gconn();
1295         if (conn == NULL)
1296                 return  BT_HAL_ERROR_INTERNAL;
1297
1298         object_path = _bt_hal_get_device_object_path(address);
1299         if (object_path == NULL) {
1300                 ERR("No searched device");
1301
1302                 adapter_proxy = _bt_hal_get_adapter_proxy();
1303                 if (adapter_proxy == NULL)
1304                         return  BT_HAL_ERROR_INTERNAL;
1305
1306                 g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1307                                 g_variant_new("(s)", address),
1308                                 G_DBUS_CALL_FLAGS_NONE,
1309                                 -1,
1310                                 NULL,
1311                                 &error);
1312
1313                 if (error != NULL) {
1314                         ERR("CreateDevice Fail: %s", error->message);
1315                         g_error_free(error);
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 static GDBusNodeInfo *_bt_hal_get_gdbus_node(const gchar *xml_data)
1532 {
1533         if (bus_id == 0) {
1534                 char *name = g_strdup_printf("org.bt.frwk.p%d", getpid());
1535
1536                 bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1537                                 name,
1538                                 G_BUS_NAME_OWNER_FLAGS_NONE,
1539                                 NULL,
1540                                 NULL,
1541                                 NULL,
1542                                 NULL,
1543                                 NULL);
1544                 DBG("Got bus id %d", bus_id);
1545                 g_free(name);
1546         }
1547
1548         return g_dbus_node_info_new_for_xml(xml_data, NULL);
1549 }
1550
1551 static const GDBusInterfaceVTable method_table = {
1552         __hal_new_connection_method,
1553         NULL,
1554         NULL,
1555 };
1556
1557 int _bt_hal_register_new_gdbus_object(const char *path, bt_hal_new_connection_cb cb)
1558 {
1559         GDBusConnection *gconn;
1560         int id;
1561         GError *error = NULL;
1562
1563         gconn = _bt_hal_get_system_gconn();
1564         if (gconn == NULL)
1565                 return -1;
1566
1567         if (new_conn_node == NULL)
1568                 new_conn_node = _bt_hal_get_gdbus_node(rfcomm_agent_xml);
1569
1570         if (new_conn_node == NULL)
1571                 return -1;
1572
1573         id = g_dbus_connection_register_object(gconn, path,
1574                         new_conn_node->interfaces[0],
1575                         &method_table,
1576                         cb, NULL, &error);
1577         if (id == 0) {
1578                 ERR("Failed to register: %s", error->message);
1579                 g_error_free(error);
1580                 return -1;
1581         }
1582
1583         DBG("NEW CONNECTION ID %d", id);
1584
1585         return id;
1586 }
1587
1588 void _bt_hal_unregister_gdbus_object(int object_id)
1589 {
1590         GDBusConnection *gconn;
1591
1592         gconn = _bt_hal_get_system_gconn();
1593         if (gconn == NULL)
1594                 return;
1595
1596         g_dbus_connection_unregister_object(gconn, object_id);
1597 }
1598
1599 int _bt_hal_discover_services(char *address, char *uuid, void *cb, gpointer func_data)
1600 {
1601         char *object_path;
1602         GDBusProxy *proxy;
1603         GDBusProxy *adapter_proxy;
1604         GError *err = NULL;
1605         GDBusConnection *conn;
1606
1607         conn = _bt_hal_get_system_gconn();
1608         if (conn == NULL) {
1609                 ERR("conn == NULL, return");
1610                 return  BT_STATUS_FAIL;
1611         }
1612
1613         object_path = _bt_hal_get_device_object_path(address);
1614         if (object_path == NULL) {
1615                 GVariant *ret = NULL;
1616
1617                 INFO("No searched device");
1618                 adapter_proxy = _bt_hal_get_adapter_proxy();
1619                 if (adapter_proxy == NULL) {
1620                         ERR("adapter_proxy == NULL, return");
1621                         return BT_STATUS_FAIL;
1622                 }
1623
1624                 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1625                                 g_variant_new("(s)", address),
1626                                 G_DBUS_CALL_FLAGS_NONE,
1627                                 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1628                                 &err);
1629                 if (err != NULL) {
1630                         ERR("CreateDevice Failed: %s", err->message);
1631                         g_clear_error(&err);
1632                 }
1633
1634                 if (ret)
1635                         g_variant_unref(ret);
1636
1637                 g_object_unref(adapter_proxy);
1638                 object_path = _bt_hal_get_device_object_path(address);
1639                 if (object_path == NULL) {
1640                         ERR("object_path == NULL, return");
1641                         return BT_STATUS_FAIL;
1642                 }
1643         }
1644
1645         proxy = g_dbus_proxy_new_sync(conn,
1646                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1647                         BT_HAL_BLUEZ_NAME, object_path,
1648                         BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
1649         g_free(object_path);
1650         if (proxy == NULL) {
1651                 ERR("Error while getting proxy");
1652                 return BT_STATUS_FAIL;
1653         }
1654
1655         g_dbus_proxy_call(proxy, "DiscoverServices",
1656                         g_variant_new("(s)", uuid),
1657                         G_DBUS_CALL_FLAGS_NONE,
1658                         BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1659                         (GAsyncReadyCallback)cb,
1660                         func_data);
1661         DBG("-");
1662         return BT_STATUS_SUCCESS;
1663 }
1664
1665 int _bt_hal_cancel_discovers(char *address)
1666 {
1667         char *object_path;
1668         GDBusProxy *proxy;
1669         GDBusProxy *adapter_proxy;
1670         GError *err = NULL;
1671         GDBusConnection *conn;
1672
1673         conn = _bt_hal_get_system_gconn();
1674         if (conn == NULL)
1675                 return  BT_STATUS_FAIL;
1676
1677         object_path = _bt_hal_get_device_object_path(address);
1678         if (object_path == NULL) {
1679                 GVariant *ret = NULL;
1680                 INFO("No searched device");
1681                 adapter_proxy = _bt_hal_get_adapter_proxy();
1682                 if (adapter_proxy == NULL) {
1683                         ERR("adapter_proxy == NULL, return");
1684                         return BT_STATUS_FAIL;
1685                 }
1686
1687                 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1688                                 g_variant_new("(s)", address),
1689                                 G_DBUS_CALL_FLAGS_NONE,
1690                                 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1691                                 &err);
1692                 if (err != NULL) {
1693                         ERR("CreateDevice Failed: %s", err->message);
1694                         g_clear_error(&err);
1695                 }
1696
1697                 if (ret)
1698                         g_variant_unref(ret);
1699
1700                 g_object_unref(adapter_proxy);
1701
1702                 object_path = _bt_hal_get_device_object_path(address);
1703                 if (object_path == NULL)
1704                         return BT_STATUS_FAIL;
1705         }
1706
1707         proxy = g_dbus_proxy_new_sync(conn,
1708                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1709                         BT_HAL_BLUEZ_NAME, object_path,
1710                         BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
1711         g_free(object_path);
1712         g_dbus_proxy_call_sync(proxy, "CancelDiscovery",
1713                         NULL,
1714                         G_DBUS_CALL_FLAGS_NONE,
1715                         BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1716                         &err);
1717         if (err) {
1718                 ERR("DBus Error message: [%s]", err->message);
1719                 g_clear_error(&err);
1720                 return BT_STATUS_FAIL;
1721         }
1722
1723         if (proxy)
1724                 g_object_unref(proxy);
1725
1726         return BT_STATUS_SUCCESS;
1727 }
1728
1729 int _bt_hal_discover_service_uuids(char *address, char *remote_uuid)
1730 {
1731         char *object_path;
1732         GDBusProxy *proxy;
1733         GDBusConnection *gconn;
1734         GError *err = NULL;
1735         char **uuid_value = NULL;
1736         gsize size = 0;
1737         int i = 0;
1738         GVariant *value = NULL;
1739         GVariant *ret = NULL;
1740         int result = BT_STATUS_FAIL;
1741
1742         if (remote_uuid == NULL) {
1743                 ERR("remote_uuid == NULL, return");
1744                 return BT_STATUS_FAIL;
1745         }
1746
1747         gconn = _bt_hal_get_system_gconn();
1748         if (gconn == NULL) {
1749                 ERR("gconn == NULL, return");
1750                 return BT_STATUS_FAIL;
1751         }
1752
1753         object_path = _bt_hal_get_device_object_path(address);
1754         if (object_path == NULL) {
1755                 ERR("object_path == NULL, return");
1756                 return BT_STATUS_FAIL;
1757         }
1758
1759         proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE, NULL,
1760                         BT_HAL_BLUEZ_NAME, object_path, BT_HAL_PROPERTIES_INTERFACE, NULL,
1761                         &err);
1762         if (proxy == NULL) {
1763                 g_free(object_path);
1764                 ERR("proxy == NULL, return");
1765                 return BT_STATUS_FAIL;
1766         }
1767
1768         if (err) {
1769                 ERR("DBus Error: [%s]", err->message);
1770                 g_clear_error(&err);
1771         }
1772
1773         ret = g_dbus_proxy_call_sync(proxy, "GetAll",
1774                         g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
1775                         G_DBUS_CALL_FLAGS_NONE,
1776                         BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1777                         &err);
1778         if (err) {
1779                 result = BT_STATUS_FAIL;
1780                 ERR("DBus Error : %s", err->message);
1781                 g_clear_error(&err);
1782                 goto done;
1783         }
1784
1785         if (ret == NULL) {
1786                 ERR("g_dbus_proxy_call_sync function return NULL");
1787                 result = BT_STATUS_FAIL;
1788                 goto done;
1789         }
1790
1791         g_variant_get(ret, "(@a{sv})", &value);
1792         g_variant_unref(ret);
1793         if (value) {
1794                 GVariant *temp_value = g_variant_lookup_value(value, "UUIDs",
1795                                 G_VARIANT_TYPE_STRING_ARRAY);
1796
1797                 if (temp_value)
1798                         size = g_variant_get_size(temp_value);
1799
1800                 if (size > 0) {
1801                         uuid_value = (char **)g_variant_get_strv(temp_value, &size);
1802                         DBG("Size items %zu", size);
1803                 }
1804
1805                 if (temp_value)
1806                         g_variant_unref(temp_value);
1807
1808                 if (uuid_value) {
1809                         for (i = 0; uuid_value[i] != NULL; i++) {
1810                                 DBG("Remote uuids %s, searched uuid: %s",
1811                                                 uuid_value[i], remote_uuid);
1812                                 if (strcasecmp(uuid_value[i], remote_uuid) == 0) {
1813                                         result = BT_STATUS_SUCCESS;
1814                                         goto done;
1815                                 }
1816                         }
1817                 }
1818         }
1819
1820 done:
1821         if (proxy)
1822                 g_object_unref(proxy);
1823         if (value)
1824                 g_variant_unref(value);
1825         if (uuid_value)
1826                 g_free(uuid_value);
1827
1828         return result;
1829 }
1830
1831 int bt_hal_gatt_convert_prop2string(
1832                 bt_hal_gatt_characteristic_property_t properties,
1833                 char *char_properties[])
1834 {
1835         int flag_count = 0;
1836
1837         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_BROADCAST) {
1838                 char_properties[flag_count] = g_strdup("broadcast");
1839                 flag_count++;
1840         }
1841         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_READ) {
1842                 char_properties[flag_count] = g_strdup("read");
1843                 flag_count++;
1844         }
1845         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE) {
1846                 char_properties[flag_count] = g_strdup("write-without-response");
1847                 flag_count++;
1848         }
1849         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE) {
1850                 char_properties[flag_count] = g_strdup("write");
1851                 flag_count++;
1852         }
1853         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY) {
1854                 char_properties[flag_count] = g_strdup("notify");
1855                 flag_count++;
1856         }
1857         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE) {
1858                 char_properties[flag_count] = g_strdup("indicate");
1859                 flag_count++;
1860         }
1861         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE) {
1862                 char_properties[flag_count] = g_strdup("authenticated-signed-writes");
1863                 flag_count++;
1864         }
1865         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE) {
1866                 char_properties[flag_count] = g_strdup("reliable-write");
1867                 flag_count++;
1868         }
1869         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES) {
1870                 char_properties[flag_count] = g_strdup("writable-auxiliaries");
1871                 flag_count++;
1872         }
1873         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ) {
1874                 char_properties[flag_count] = g_strdup("encrypt-read");
1875                 flag_count++;
1876         }
1877         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE) {
1878                 char_properties[flag_count] = g_strdup("encrypt-write");
1879                 flag_count++;
1880         }
1881         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ) {
1882                 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
1883                 flag_count++;
1884         }
1885         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE) {
1886                 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
1887                 flag_count++;
1888         }
1889
1890         if (flag_count == 0) {
1891                 char_properties[flag_count] = g_strdup("read");
1892                 flag_count++;
1893         }
1894
1895         return flag_count;
1896 }
1897
1898 int bt_hal_gatt_convert_perm2string(
1899                 bt_hal_gatt_permission_t properties,
1900                 char *char_properties[])
1901 {
1902         int flag_count = 0;
1903
1904         if (properties & BT_HAL_GATT_PERMISSION_READ) {
1905                 char_properties[flag_count] = g_strdup("read");
1906                 flag_count++;
1907         }
1908         if (properties & BT_HAL_GATT_PERMISSION_WRITE) {
1909                 char_properties[flag_count] = g_strdup("write");
1910                 flag_count++;
1911         }
1912         if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_READ) {
1913                 char_properties[flag_count] = g_strdup("encrypt-read");
1914                 flag_count++;
1915         }
1916         if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_WRITE) {
1917                 char_properties[flag_count] = g_strdup("encrypt-write");
1918                 flag_count++;
1919         }
1920         if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_READ) {
1921                 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
1922                 flag_count++;
1923         }
1924         if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_WRITE) {
1925                 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
1926                 flag_count++;
1927         }
1928
1929         if (flag_count == 0) {
1930                 char_properties[flag_count] = g_strdup("read");
1931                 flag_count++;
1932         }
1933
1934         return flag_count;
1935 }
1936
1937 gboolean _bt_hal_is_service_enabled(const char *uuid)
1938 {
1939         GDBusProxy *proxy;
1940         GError *error = NULL;
1941         GVariant *result;
1942         GVariant *temp;
1943         GVariantIter *iter = NULL;
1944         gchar *uuid_str;
1945         gboolean ret = FALSE;
1946
1947         proxy = _bt_hal_get_adapter_properties_proxy();
1948         if (!proxy) {
1949                 DBG("_bt_hal_dbus_get_local_name: Adapter Properties proxy get failed!!!");
1950                 return FALSE;
1951         }
1952
1953         result = g_dbus_proxy_call_sync(proxy,
1954                         "Get", g_variant_new("(ss)",
1955                                 BT_HAL_ADAPTER_INTERFACE, "UUIDs"),
1956                         G_DBUS_CALL_FLAGS_NONE, -1,
1957                         NULL, &error);
1958         if (!result) {
1959                 if (error != NULL) {
1960                         ERR("Failed to get UUIDs (Error: %s)", error->message);
1961                         g_clear_error(&error);
1962                 } else
1963                         ERR("Failed to get UUIDs");
1964                 return FALSE;
1965         }
1966
1967         g_variant_get(result, "(v)", &temp);
1968         g_variant_get(temp, "as", &iter);
1969         if (!iter) {
1970                 ERR("Failed to get UUIDs");
1971                 g_variant_unref(result);
1972                 return FALSE;
1973         }
1974
1975         while (g_variant_iter_loop(iter, "&s", &uuid_str)) {
1976                 DBG("UUID string [%s]\n", uuid_str);
1977                 if (!strncasecmp(uuid, uuid_str, strlen(uuid))) {
1978                         ret = TRUE;
1979                         break;
1980                 }
1981         }
1982
1983         g_variant_iter_free(iter);
1984         g_variant_unref(result);
1985         g_variant_unref(temp);
1986
1987         return ret;
1988 }