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