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