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