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