Merge "A2DP profile multiple source support" into tizen
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-dbus-common-utils.c
1 /*
2  * BLUETOOTH HAL
3  *
4  * Copyright (c) 2015 -2016 Samsung Electronics Co., Ltd All Rights Reserved.
5  *
6  * Contact: Anupam Roy <anupam.r@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *              http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdio.h>
23 #include <stdint.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <fcntl.h>
27 #include <errno.h>
28 #include <termios.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31 #include <arpa/inet.h>
32
33 #include <dlog.h>
34 #include <glib.h>
35 #include <sys/prctl.h>
36 #include <gio/gio.h>
37 #include <gio/gunixfdlist.h>
38
39 #include "bt-hal-dbus-common-utils.h"
40
41 #include "bt-hal.h"
42 #include "bt-hal-log.h"
43 #include "bt-hal-msg.h"
44 #include "bt-hal-utils.h"
45 #include "bt-hal-internal.h"
46
47 #define CASE_RETURN_STR(const) case const: return #const;
48
49 /**
50  * This is RFCOMM default Channel Value
51  */
52 #define RFCOMM_DEFAULT_PROFILE_CHANNEL 0
53 #define BT_AUDIO_SOURCE_MAX 2
54
55 static char *avrcp_control_path = NULL;
56 static char *avrcp_transport_path = NULL;
57
58 static GDBusConnection *system_conn;
59 static GDBusConnection *session_conn;
60 static GDBusProxy *manager_gproxy = NULL;
61 static GDBusProxy *adapter_gproxy = NULL;
62 static GDBusProxy *profile_gproxy = NULL;
63
64 static GDBusProxy *adapter_properties_proxy;
65 static GDBusProxy *avrcp_ctrl_proxy;
66
67 struct avrcp_proxy {
68         GDBusProxy *avrcp_ctrl_proxy;
69         char *avrcp_control_path;
70         bt_bdaddr_t bd_addr;
71 };
72
73 struct avrcp_proxy proxy_array[BT_AUDIO_SOURCE_MAX];
74
75 static 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                         char *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 void _bt_hal_logging_connection(gboolean connect, int addr_type)
1208 {
1209         static int le_conn = 0;
1210         static int le_disc = 0;
1211         static int edr_conn = 0;
1212         static int edr_disc = 0;
1213
1214         if (connect) {
1215                 if (addr_type)
1216                         le_conn++;
1217                 else
1218                         edr_conn++;
1219         } else {
1220                 if (addr_type)
1221                         le_disc++;
1222                 else
1223                         edr_disc++;
1224         }
1225
1226         INFO("[PM] Number of LE conn: %d disc: %d, Number of BR/EDR conn: %d disc: %d",
1227                         le_conn, le_disc, edr_conn, edr_disc);
1228 }
1229
1230 void _bt_hal_swap_byte_ordering(char *data, int data_len)
1231 {
1232         char temp;
1233         int i, j;
1234
1235         if (data == NULL)
1236                 return;
1237         /* Swap to opposite endian */
1238         for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
1239                 temp = data[i];
1240                 data[i] = data[j];
1241                 data[j] = temp;
1242         }
1243 }
1244
1245 int _bt_hal_byte_arr_cmp(const char *data1, const char *data2, int data_len)
1246 {
1247         int i;
1248
1249         if (data1 == NULL || data2 == NULL)
1250                 return -1;
1251         for (i = 0; i < data_len; i++) {
1252                 if (data1[i] != data2[i])
1253                         return data1[i] - data2[i];
1254         }
1255         return 0;
1256 }
1257 int _bt_hal_byte_arr_cmp_with_mask(const char *data1, const char *data2,
1258                 const char *mask, int data_len)
1259 {
1260         int i;
1261         char a, b;
1262
1263         if (data1 == NULL || data2 == NULL || mask == NULL)
1264         return -1;
1265
1266         for (i = 0; i < data_len; i++) {
1267                 a = data1[i] & mask[i];
1268                 b = data2[i] & mask[i];
1269                 if (a != b)
1270                         return (int)(a - b);
1271         }
1272         return 0;
1273 }
1274
1275 int _bt_hal_connect_profile(char *address, char *uuid,
1276                 void *cb, gpointer func_data)
1277 {
1278         char *object_path;
1279         GDBusProxy *proxy;
1280         GDBusConnection *conn;
1281         GDBusProxy *adapter_proxy;
1282         GError *error = NULL;
1283
1284         conn = _bt_hal_get_system_gconn();
1285         if (conn == NULL)
1286                 return  BT_HAL_ERROR_INTERNAL;
1287
1288         object_path = _bt_hal_get_device_object_path(address);
1289         if (object_path == NULL) {
1290                 ERR("No searched device");
1291
1292                 adapter_proxy = _bt_hal_get_adapter_proxy();
1293                 if (adapter_proxy == NULL)
1294                         return  BT_HAL_ERROR_INTERNAL;
1295
1296                 g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1297                                 g_variant_new("(s)", address),
1298                                 G_DBUS_CALL_FLAGS_NONE,
1299                                 -1,
1300                                 NULL,
1301                                 &error);
1302
1303                 if (error != NULL) {
1304                         ERR("CreateDevice Fail: %s", error->message);
1305                         g_error_free(error);
1306                 }
1307
1308                 object_path = _bt_hal_get_device_object_path(address);
1309         }
1310         if (object_path == NULL)
1311                 return  BT_HAL_ERROR_INTERNAL;
1312
1313         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1314                         NULL, BT_HAL_BLUEZ_NAME,
1315                         object_path, BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
1316         g_free(object_path);
1317         if (proxy == NULL)
1318                 return  BT_HAL_ERROR_INTERNAL;
1319
1320
1321         g_dbus_proxy_call(proxy, "ConnectProfile",
1322                         g_variant_new("(s)", uuid),
1323                         G_DBUS_CALL_FLAGS_NONE,
1324                         BT_HAL_MAX_DBUS_TIMEOUT,
1325                         NULL,
1326                         (GAsyncReadyCallback)cb,
1327                         func_data);
1328
1329         return BT_HAL_ERROR_NONE;
1330 }
1331
1332 int _bt_hal_disconnect_profile(char *address, char *uuid,
1333                 void *cb, gpointer func_data)
1334 {
1335         char *object_path;
1336         GDBusProxy *proxy;
1337         GDBusConnection *conn;
1338
1339         conn = _bt_hal_get_system_gconn();
1340         if (conn == NULL)
1341                 return  BT_HAL_ERROR_INTERNAL;
1342
1343         object_path = _bt_hal_get_device_object_path(address);
1344         if (object_path == NULL)
1345                 return  BT_HAL_ERROR_INTERNAL;
1346
1347         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1348                         NULL, BT_HAL_BLUEZ_NAME,
1349                         object_path, BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
1350         g_free(object_path);
1351         if (proxy == NULL)
1352                 return  BT_HAL_ERROR_INTERNAL;
1353
1354         g_dbus_proxy_call(proxy, "DisconnectProfile",
1355                         g_variant_new("(s)", uuid),
1356                         G_DBUS_CALL_FLAGS_NONE,
1357                         BT_HAL_MAX_DBUS_TIMEOUT,
1358                         NULL,
1359                         (GAsyncReadyCallback)cb,
1360                         func_data);
1361
1362         return BT_HAL_ERROR_NONE;
1363 }
1364
1365 int _bt_hal_register_profile(bt_hal_register_profile_info_t *info, gboolean use_default_rfcomm)
1366 {
1367         GVariantBuilder *option_builder;
1368         GVariant *ret;
1369         GDBusProxy *proxy;
1370         GError *err = NULL;
1371         int result = BT_STATUS_SUCCESS;
1372
1373         proxy = _bt_hal_get_profile_proxy();
1374         if (proxy == NULL) {
1375                 ERR("Getting profile proxy failed");
1376                 return BT_STATUS_FAIL;
1377         }
1378
1379         option_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1380         if (info->authentication)
1381                 g_variant_builder_add(option_builder, "{sv}",
1382                                 "RequireAuthentication",
1383                                 g_variant_new_boolean(TRUE));
1384         if (info->authorization)
1385                 g_variant_builder_add(option_builder, "{sv}",
1386                                 "RequireAuthorization",
1387                                 g_variant_new_boolean(TRUE));
1388         if (info->role)
1389                 g_variant_builder_add(option_builder, "{sv}",
1390                                 "Role",
1391                                 g_variant_new_string(info->role));
1392
1393         /*
1394          * Setting RFCOMM channel to default value 0; would allow bluez to assign
1395          * RFCOMM channels based on the availability when two services want to use
1396          * the RFCOMM along with SPP. Hence bluez makes sure that no two services
1397          * use the same SPP RFCOMM channel.
1398          */
1399         if (use_default_rfcomm)
1400                 g_variant_builder_add(option_builder, "{sv}",
1401                                 "Channel",
1402                                 g_variant_new_uint16(RFCOMM_DEFAULT_PROFILE_CHANNEL));
1403         if (info->service)
1404                 g_variant_builder_add(option_builder, "{sv}",
1405                                 "Service",
1406                                 g_variant_new_string(info->service));
1407
1408         ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile",
1409                         g_variant_new("(osa{sv})", info->obj_path,
1410                                 info->uuid,
1411                                 option_builder),
1412                         G_DBUS_CALL_FLAGS_NONE, -1,
1413                         NULL, &err);
1414         if (err) {
1415                 ERR("RegisterProfile failed: %s", err->message);
1416
1417                 if (g_strrstr(err->message, BT_HAL_ACCESS_DENIED_MSG))
1418                         result = BT_STATUS_AUTH_REJECTED;
1419                 else
1420                         result = BT_STATUS_FAIL;
1421
1422                 g_clear_error(&err);
1423         }
1424
1425         g_variant_builder_unref(option_builder);
1426
1427         if (ret)
1428                 g_variant_unref(ret);
1429
1430         return result;
1431 }
1432
1433 void _bt_hal_unregister_profile(char *path)
1434 {
1435         GVariant *ret;
1436         GDBusProxy *proxy;
1437         GError *err = NULL;
1438
1439         proxy = _bt_hal_get_profile_proxy();
1440         if (proxy == NULL) {
1441                 ERR("Getting profile proxy failed");
1442                 return;
1443         }
1444
1445         ret = g_dbus_proxy_call_sync(proxy, "UnregisterProfile",
1446                         g_variant_new("(o)", path),
1447                         G_DBUS_CALL_FLAGS_NONE, -1,
1448                         NULL, &err);
1449         if (err) {
1450                 ERR("UnregisterProfile failed : %s", err->message);
1451                 g_clear_error(&err);
1452         }
1453
1454         if (ret)
1455                 g_variant_unref(ret);
1456
1457         return;
1458 }
1459
1460 static void __hal_new_connection_method(GDBusConnection *connection,
1461                 const gchar *sender,
1462                 const gchar *object_path,
1463                 const gchar *interface_name,
1464                 const gchar *method_name,
1465                 GVariant *parameters,
1466                 GDBusMethodInvocation *invocation,
1467                 gpointer user_data)
1468 {
1469         DBG("method %s", method_name);
1470         if (g_strcmp0(method_name, "NewConnection") == 0) {
1471                 int index;
1472                 int fd;
1473                 GUnixFDList *fd_list;
1474                 GDBusMessage *msg;
1475                 GVariantBuilder *properties;
1476                 char *obj_path;
1477                 bt_bdaddr_t remote_addr1;
1478                 char addr[BT_HAL_ADDRESS_STRING_SIZE];
1479                 bt_hal_new_connection_cb cb = user_data;
1480
1481                 g_variant_get(parameters, "(oha{sv})", &obj_path, &index,
1482                                 &properties);
1483
1484                 msg = g_dbus_method_invocation_get_message(invocation);
1485                 fd_list = g_dbus_message_get_unix_fd_list(msg);
1486                 if (fd_list == NULL) {
1487                         GQuark quark = g_quark_from_string("rfcomm-app");
1488                         GError *err = g_error_new(quark, 0, "No fd in message");
1489                         g_dbus_method_invocation_return_gerror(invocation, err);
1490                         g_error_free(err);
1491                         return;
1492                 }
1493
1494
1495                 fd = g_unix_fd_list_get(fd_list, index, NULL);
1496                 if (fd == -1) {
1497                         ERR("Invalid fd return");
1498                         GQuark quark = g_quark_from_string("rfcomm-app");
1499                         GError *err = g_error_new(quark, 0, "Invalid FD return");
1500                         g_dbus_method_invocation_return_gerror(invocation, err);
1501                         g_error_free(err);
1502                         return;
1503                 }
1504                 INFO("Object Path %s", obj_path);
1505
1506                 _bt_hal_convert_device_path_to_address(obj_path, addr);
1507                 _bt_hal_convert_addr_string_to_type(remote_addr1.address, (const char *)addr);
1508                 INFO("fd: %d, address %s", fd, addr);
1509
1510                 g_dbus_method_invocation_return_value(invocation, NULL);
1511
1512                 if (cb)
1513                         cb(object_path, fd, &remote_addr1);
1514                 else
1515                         close(fd);
1516         } else if (g_strcmp0(method_name, "RequestDisconnection") == 0) {
1517                 g_dbus_method_invocation_return_value(invocation, NULL);
1518         }
1519 }
1520
1521 static GDBusNodeInfo *_bt_hal_get_gdbus_node(const gchar *xml_data)
1522 {
1523         if (bus_id == 0) {
1524                 char *name = g_strdup_printf("org.bt.frwk.p%d", getpid());
1525
1526                 bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1527                                 name,
1528                                 G_BUS_NAME_OWNER_FLAGS_NONE,
1529                                 NULL,
1530                                 NULL,
1531                                 NULL,
1532                                 NULL,
1533                                 NULL);
1534                 DBG("Got bus id %d", bus_id);
1535                 g_free(name);
1536         }
1537
1538         return g_dbus_node_info_new_for_xml(xml_data, NULL);
1539 }
1540
1541 static const GDBusInterfaceVTable method_table = {
1542         __hal_new_connection_method,
1543         NULL,
1544         NULL,
1545 };
1546
1547 int _bt_hal_register_new_gdbus_object(const char *path, bt_hal_new_connection_cb cb)
1548 {
1549         GDBusConnection *gconn;
1550         int id;
1551         GError *error = NULL;
1552
1553         gconn = _bt_hal_get_system_gconn();
1554         if (gconn == NULL)
1555                 return -1;
1556
1557         if (new_conn_node == NULL)
1558                 new_conn_node = _bt_hal_get_gdbus_node(rfcomm_agent_xml);
1559
1560         if (new_conn_node == NULL)
1561                 return -1;
1562
1563         id = g_dbus_connection_register_object(gconn, path,
1564                         new_conn_node->interfaces[0],
1565                         &method_table,
1566                         cb, NULL, &error);
1567         if (id == 0) {
1568                 ERR("Failed to register: %s", error->message);
1569                 g_error_free(error);
1570                 return -1;
1571         }
1572
1573         DBG("NEW CONNECTION ID %d", id);
1574
1575         return id;
1576 }
1577
1578 void _bt_hal_unregister_gdbus_object(int object_id)
1579 {
1580         GDBusConnection *gconn;
1581
1582         gconn = _bt_hal_get_system_gconn();
1583         if (gconn == NULL)
1584                 return;
1585
1586         g_dbus_connection_unregister_object(gconn, object_id);
1587 }
1588
1589 int _bt_hal_discover_services(char *address, char *uuid, void *cb, gpointer func_data)
1590 {
1591         char *object_path;
1592         GDBusProxy *proxy;
1593         GDBusProxy *adapter_proxy;
1594         GError *err = NULL;
1595         GDBusConnection *conn;
1596
1597         conn = _bt_hal_get_system_gconn();
1598         if (conn == NULL) {
1599                 ERR("conn == NULL, return");
1600                 return  BT_STATUS_FAIL;
1601         }
1602
1603         object_path = _bt_hal_get_device_object_path(address);
1604         if (object_path == NULL) {
1605                 GVariant *ret = NULL;
1606
1607                 INFO("No searched device");
1608                 adapter_proxy = _bt_hal_get_adapter_proxy();
1609                 if (adapter_proxy == NULL) {
1610                         ERR("adapter_proxy == NULL, return");
1611                         return BT_STATUS_FAIL;
1612                 }
1613
1614                 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1615                                 g_variant_new("(s)", address),
1616                                 G_DBUS_CALL_FLAGS_NONE,
1617                                 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1618                                 &err);
1619                 if (err != NULL) {
1620                         ERR("CreateDevice Failed: %s", err->message);
1621                         g_clear_error(&err);
1622                 }
1623
1624                 if (ret)
1625                         g_variant_unref(ret);
1626
1627                 g_object_unref(adapter_proxy);
1628                 object_path = _bt_hal_get_device_object_path(address);
1629                 if (object_path == NULL) {
1630                         ERR("object_path == NULL, return");
1631                         return BT_STATUS_FAIL;
1632                 }
1633         }
1634
1635         proxy = g_dbus_proxy_new_sync(conn,
1636                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1637                         BT_HAL_BLUEZ_NAME, object_path,
1638                         BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
1639         g_free(object_path);
1640         if (proxy == NULL) {
1641                 ERR("Error while getting proxy");
1642                 return BT_STATUS_FAIL;
1643         }
1644
1645         g_dbus_proxy_call(proxy, "DiscoverServices",
1646                         g_variant_new("(s)", uuid),
1647                         G_DBUS_CALL_FLAGS_NONE,
1648                         BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1649                         (GAsyncReadyCallback)cb,
1650                         func_data);
1651         DBG("-");
1652         return BT_STATUS_SUCCESS;
1653 }
1654
1655 int _bt_hal_cancel_discovers(char *address)
1656 {
1657         char *object_path;
1658         GDBusProxy *proxy;
1659         GDBusProxy *adapter_proxy;
1660         GError *err = NULL;
1661         GDBusConnection *conn;
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                 GVariant *ret = NULL;
1670                 INFO("No searched device");
1671                 adapter_proxy = _bt_hal_get_adapter_proxy();
1672                 if (adapter_proxy == NULL) {
1673                         ERR("adapter_proxy == NULL, return");
1674                         return BT_STATUS_FAIL;
1675                 }
1676
1677                 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1678                                 g_variant_new("(s)", address),
1679                                 G_DBUS_CALL_FLAGS_NONE,
1680                                 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1681                                 &err);
1682                 if (err != NULL) {
1683                         ERR("CreateDevice Failed: %s", err->message);
1684                         g_clear_error(&err);
1685                 }
1686
1687                 if (ret)
1688                         g_variant_unref(ret);
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         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 (err) {
1708                 ERR("DBus Error message: [%s]", err->message);
1709                 g_clear_error(&err);
1710                 return BT_STATUS_FAIL;
1711         }
1712
1713         if (proxy)
1714                 g_object_unref(proxy);
1715
1716         return BT_STATUS_SUCCESS;
1717 }
1718
1719 int _bt_hal_discover_service_uuids(char *address, char *remote_uuid)
1720 {
1721         char *object_path;
1722         GDBusProxy *proxy;
1723         GDBusConnection *gconn;
1724         GError *err = NULL;
1725         char **uuid_value = NULL;
1726         gsize size = 0;
1727         int i = 0;
1728         GVariant *value = NULL;
1729         GVariant *ret = NULL;
1730         int result = BT_STATUS_FAIL;
1731
1732         DBG("+");
1733
1734         if (remote_uuid == NULL) {
1735                 ERR("remote_uuid == NULL, return");
1736                 return BT_STATUS_FAIL;
1737         }
1738
1739         gconn = _bt_hal_get_system_gconn();
1740         if (gconn == NULL) {
1741                 ERR("gconn == NULL, return");
1742                 return BT_STATUS_FAIL;
1743         }
1744
1745         object_path = _bt_hal_get_device_object_path(address);
1746         if (object_path == NULL) {
1747                 ERR("object_path == NULL, return");
1748                 return BT_STATUS_FAIL;
1749         }
1750
1751         proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE, NULL,
1752                         BT_HAL_BLUEZ_NAME, object_path, BT_HAL_PROPERTIES_INTERFACE, NULL,
1753                         &err);
1754         if (proxy == NULL) {
1755                 g_free(object_path);
1756                 ERR("proxy == NULL, return");
1757                 return BT_STATUS_FAIL;
1758         }
1759
1760         if (err) {
1761                 ERR("DBus Error: [%s]", err->message);
1762                 g_clear_error(&err);
1763         }
1764
1765         ret = g_dbus_proxy_call_sync(proxy, "GetAll",
1766                         g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
1767                         G_DBUS_CALL_FLAGS_NONE,
1768                         BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1769                         &err);
1770         if (err) {
1771                 result = BT_STATUS_FAIL;
1772                 ERR("DBus Error : %s", err->message);
1773                 g_clear_error(&err);
1774                 goto done;
1775         }
1776
1777         if (ret == NULL) {
1778                 ERR("g_dbus_proxy_call_sync function return NULL");
1779                 result = BT_STATUS_FAIL;
1780                 goto done;
1781         }
1782
1783         g_variant_get(ret, "(@a{sv})", &value);
1784         g_variant_unref(ret);
1785         if (value) {
1786                 GVariant *temp_value = g_variant_lookup_value(value, "UUIDs",
1787                                 G_VARIANT_TYPE_STRING_ARRAY);
1788
1789                 if (temp_value)
1790                         size = g_variant_get_size(temp_value);
1791
1792                 if (size > 0) {
1793                         uuid_value = (char **)g_variant_get_strv(temp_value, &size);
1794                         DBG("Size items %zu", size);
1795                 }
1796
1797                 if (temp_value)
1798                         g_variant_unref(temp_value);
1799
1800                 if (uuid_value) {
1801                         for (i = 0; uuid_value[i] != NULL; i++) {
1802                                 DBG("Remote uuids %s, searched uuid: %s",
1803                                                 uuid_value[i], remote_uuid);
1804                                 if (strcasecmp(uuid_value[i], remote_uuid) == 0) {
1805                                         result = BT_STATUS_SUCCESS;
1806                                         goto done;
1807                                 }
1808                         }
1809                 }
1810         }
1811
1812 done:
1813         if (proxy)
1814                 g_object_unref(proxy);
1815         if (value)
1816                 g_variant_unref(value);
1817         if (uuid_value)
1818                 g_free(uuid_value);
1819
1820         DBG("-");
1821         return result;
1822 }
1823
1824 int bt_hal_gatt_convert_prop2string(
1825                 bt_hal_gatt_characteristic_property_t properties,
1826                 char *char_properties[])
1827 {
1828         int flag_count = 0;
1829
1830         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_BROADCAST) {
1831                 char_properties[flag_count] = g_strdup("broadcast");
1832                 flag_count++;
1833         }
1834         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_READ) {
1835                 char_properties[flag_count] = g_strdup("read");
1836                 flag_count++;
1837         }
1838         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE) {
1839                 char_properties[flag_count] = g_strdup("write-without-response");
1840                 flag_count++;
1841         }
1842         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE) {
1843                 char_properties[flag_count] = g_strdup("write");
1844                 flag_count++;
1845         }
1846         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY) {
1847                 char_properties[flag_count] = g_strdup("notify");
1848                 flag_count++;
1849         }
1850         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE) {
1851                 char_properties[flag_count] = g_strdup("indicate");
1852                 flag_count++;
1853         }
1854         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE) {
1855                 char_properties[flag_count] = g_strdup("authenticated-signed-writes");
1856                 flag_count++;
1857         }
1858         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE) {
1859                 char_properties[flag_count] = g_strdup("reliable-write");
1860                 flag_count++;
1861         }
1862         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES) {
1863                 char_properties[flag_count] = g_strdup("writable-auxiliaries");
1864                 flag_count++;
1865         }
1866         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ) {
1867                 char_properties[flag_count] = g_strdup("encrypt-read");
1868                 flag_count++;
1869         }
1870         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE) {
1871                 char_properties[flag_count] = g_strdup("encrypt-write");
1872                 flag_count++;
1873         }
1874         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ) {
1875                 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
1876                 flag_count++;
1877         }
1878         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE) {
1879                 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
1880                 flag_count++;
1881         }
1882
1883         if (flag_count == 0) {
1884                 char_properties[flag_count] = g_strdup("read");
1885                 flag_count++;
1886         }
1887
1888         return flag_count;
1889 }
1890
1891 int bt_hal_gatt_convert_perm2string(
1892                 bt_hal_gatt_permission_t properties,
1893                 char *char_properties[])
1894 {
1895         int flag_count = 0;
1896
1897         if (properties & BT_HAL_GATT_PERMISSION_READ) {
1898                 char_properties[flag_count] = g_strdup("read");
1899                 flag_count++;
1900         }
1901         if (properties & BT_HAL_GATT_PERMISSION_WRITE) {
1902                 char_properties[flag_count] = g_strdup("write");
1903                 flag_count++;
1904         }
1905         if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_READ) {
1906                 char_properties[flag_count] = g_strdup("encrypt-read");
1907                 flag_count++;
1908         }
1909         if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_WRITE) {
1910                 char_properties[flag_count] = g_strdup("encrypt-write");
1911                 flag_count++;
1912         }
1913         if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_READ) {
1914                 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
1915                 flag_count++;
1916         }
1917         if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_WRITE) {
1918                 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
1919                 flag_count++;
1920         }
1921
1922         if (flag_count == 0) {
1923                 char_properties[flag_count] = g_strdup("read");
1924                 flag_count++;
1925         }
1926
1927         return flag_count;
1928 }
1929
1930 gboolean _bt_hal_is_service_enabled(const char *uuid)
1931 {
1932         GDBusProxy *proxy;
1933         GError *error = NULL;
1934         GVariant *result;
1935         GVariant *temp;
1936         GVariantIter *iter = NULL;
1937         gchar *uuid_str;
1938         gboolean ret = FALSE;
1939
1940         DBG("+");
1941
1942         proxy = _bt_hal_get_adapter_properties_proxy();
1943         if (!proxy) {
1944                 DBG("_bt_hal_dbus_get_local_name: Adapter Properties proxy get failed!!!");
1945                 return FALSE;
1946         }
1947
1948         result = g_dbus_proxy_call_sync(proxy,
1949                         "Get", g_variant_new("(ss)",
1950                                 BT_HAL_ADAPTER_INTERFACE, "UUIDs"),
1951                         G_DBUS_CALL_FLAGS_NONE, -1,
1952                         NULL, &error);
1953         if (!result) {
1954                 if (error != NULL) {
1955                         ERR("Failed to get UUIDs (Error: %s)", error->message);
1956                         g_clear_error(&error);
1957                 } else
1958                         ERR("Failed to get UUIDs");
1959                 return FALSE;
1960         }
1961
1962         g_variant_get(result, "(v)", &temp);
1963         g_variant_get(temp, "as", &iter);
1964         if (!iter) {
1965                 ERR("Failed to get UUIDs");
1966                 g_variant_unref(result);
1967                 return FALSE;
1968         }
1969
1970         while (g_variant_iter_loop(iter, "s", &uuid_str)) {
1971                 DBG("UUID string [%s]\n", uuid_str);
1972                 if (!strncasecmp(uuid, uuid_str, strlen(uuid))) {
1973                         ret = TRUE;
1974                         break;
1975                 }
1976         }
1977
1978         g_variant_iter_free(iter);
1979         g_variant_unref(result);
1980         g_variant_unref(temp);
1981         DBG("-");
1982         return ret;
1983 }