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