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