fdf21132d599764b019d628d301faf74033ba345
[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 char *_bt_hal_convert_error_to_string(int error)
1032 {
1033         switch (error) {
1034         case BT_HAL_ERROR_CANCEL:
1035                 return "CANCELLED";
1036         case BT_HAL_ERROR_INVALID_PARAM:
1037                 return "INVALID_PARAMETER";
1038         case BT_HAL_ERROR_INVALID_DATA:
1039                 return "INVALID DATA";
1040         case BT_HAL_ERROR_MEMORY_ALLOCATION:
1041         case BT_HAL_ERROR_OUT_OF_MEMORY:
1042                 return "OUT_OF_MEMORY";
1043         case BT_HAL_ERROR_TIMEOUT:
1044                 return "TIMEOUT";
1045         case BT_HAL_ERROR_NO_RESOURCES:
1046                 return "NO_RESOURCES";
1047         case BT_HAL_ERROR_INTERNAL:
1048                 return "INTERNAL";
1049         case BT_HAL_ERROR_NOT_SUPPORT:
1050                 return "NOT_SUPPORT";
1051         case BT_HAL_ERROR_DEVICE_NOT_ENABLED:
1052                 return "NOT_ENABLED";
1053         case BT_HAL_ERROR_DEVICE_ALREADY_ENABLED:
1054                 return "ALREADY_ENABLED";
1055         case BT_HAL_ERROR_DEVICE_BUSY:
1056                 return "DEVICE_BUSY";
1057         case BT_HAL_ERROR_ACCESS_DENIED:
1058                 return "ACCESS_DENIED";
1059         case BT_HAL_ERROR_MAX_CLIENT:
1060                 return "MAX_CLIENT";
1061         case BT_HAL_ERROR_NOT_FOUND:
1062                 return "NOT_FOUND";
1063         case BT_HAL_ERROR_SERVICE_SEARCH_ERROR:
1064                 return "SERVICE_SEARCH_ERROR";
1065         case BT_HAL_ERROR_PARING_FAILED:
1066                 return "PARING_FAILED";
1067         case BT_HAL_ERROR_NOT_PAIRED:
1068                 return "NOT_PAIRED";
1069         case BT_HAL_ERROR_SERVICE_NOT_FOUND:
1070                 return "SERVICE_NOT_FOUND";
1071         case BT_HAL_ERROR_NOT_CONNECTED:
1072                 return "NOT_CONNECTED";
1073         case BT_HAL_ERROR_ALREADY_CONNECT:
1074                 return "ALREADY_CONNECT";
1075         case BT_HAL_ERROR_CONNECTION_BUSY:
1076                 return "CONNECTION_BUSY";
1077         case BT_HAL_ERROR_CONNECTION_ERROR:
1078                 return "CONNECTION_ERROR";
1079         case BT_HAL_ERROR_MAX_CONNECTION:
1080                 return "MAX_CONNECTION";
1081         case BT_HAL_ERROR_NOT_IN_OPERATION:
1082                 return "NOT_IN_OPERATION";
1083         case BT_HAL_ERROR_CANCEL_BY_USER:
1084                 return "CANCEL_BY_USER";
1085         case BT_HAL_ERROR_REGISTRATION_FAILED:
1086                 return "REGISTRATION_FAILED";
1087         case BT_HAL_ERROR_IN_PROGRESS:
1088                 return "IN_PROGRESS";
1089         case BT_HAL_ERROR_AUTHENTICATION_FAILED:
1090                 return "AUTHENTICATION_FAILED";
1091         case BT_HAL_ERROR_HOST_DOWN:
1092                 return "HOST_DOWN";
1093         case BT_HAL_ERROR_END_OF_DEVICE_LIST:
1094                 return "END_OF_DEVICE_LIST";
1095         case BT_HAL_ERROR_AGENT_ALREADY_EXIST:
1096                 return "AGENT_ALREADY_EXIST";
1097         case BT_HAL_ERROR_AGENT_DOES_NOT_EXIST:
1098                 return "AGENT_DOES_NOT_EXIST";
1099         case BT_HAL_ERROR_ALREADY_INITIALIZED:
1100                 return "ALREADY_INITIALIZED";
1101         case BT_HAL_ERROR_PERMISSION_DEINED:
1102                 return "PERMISSION_DEINED";
1103         case BT_HAL_ERROR_ALREADY_DEACTIVATED:
1104                 return "ALREADY_DEACTIVATED";
1105         case BT_HAL_ERROR_NOT_INITIALIZED:
1106                 return "NOT_INITIALIZED";
1107         default:
1108                 return "UNKNOWN";
1109         }
1110 }
1111
1112 char * _bt_hal_convert_disc_reason_to_string(int reason)
1113 {
1114         switch (reason) {
1115         case 1:
1116                 return "Link loss";
1117         case 2:
1118                 return "Connection terminated by local host";
1119         case 3:
1120                 return "Remote user terminated connection";
1121         case 0:
1122         default:
1123                 return "Unknown";
1124         }
1125 }
1126
1127 void _bt_hal_logging_connection(gboolean connect, int addr_type)
1128 {
1129         static int le_conn = 0;
1130         static int le_disc = 0;
1131         static int edr_conn = 0;
1132         static int edr_disc = 0;
1133
1134         if (connect) {
1135                 if (addr_type)
1136                         le_conn++;
1137                 else
1138                         edr_conn++;
1139         } else {
1140                 if (addr_type)
1141                         le_disc++;
1142                 else
1143                         edr_disc++;
1144         }
1145
1146         INFO("[PM] Number of LE conn: %d disc: %d, Number of BR/EDR conn: %d disc: %d",
1147                         le_conn, le_disc, edr_conn, edr_disc);
1148 }
1149
1150 void _bt_hal_swap_byte_ordering(char *data, int data_len)
1151 {
1152         char temp;
1153         int i, j;
1154
1155         if (data == NULL)
1156                 return;
1157         /* Swap to opposite endian */
1158         for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
1159                 temp = data[i];
1160                 data[i] = data[j];
1161                 data[j] = temp;
1162         }
1163 }
1164
1165 int _bt_hal_byte_arr_cmp(const char *data1, const char *data2, int data_len)
1166 {
1167         int i;
1168
1169         if (data1 == NULL || data2 == NULL)
1170                 return -1;
1171         for (i = 0; i < data_len; i++) {
1172                 if (data1[i] != data2[i])
1173                         return data1[i] - data2[i];
1174         }
1175         return 0;
1176 }
1177 int _bt_hal_byte_arr_cmp_with_mask(const char *data1, const char *data2,
1178                 const char *mask, int data_len)
1179 {
1180         int i;
1181         char a, b;
1182
1183         if (data1 == NULL || data2 == NULL || mask == NULL)
1184         return -1;
1185
1186         for (i = 0; i < data_len; i++) {
1187                 a = data1[i] & mask[i];
1188                 b = data2[i] & mask[i];
1189                 if (a != b)
1190                         return (int)(a - b);
1191         }
1192         return 0;
1193 }
1194
1195 int _bt_hal_connect_profile(char *address, char *uuid,
1196                 void *cb, gpointer func_data)
1197 {
1198         char *object_path;
1199         GDBusProxy *proxy;
1200         GDBusConnection *conn;
1201         GDBusProxy *adapter_proxy;
1202         GError *error = NULL;
1203
1204         conn = _bt_hal_get_system_gconn();
1205         if (conn == NULL)
1206                 return  BT_HAL_ERROR_INTERNAL;
1207
1208         object_path = _bt_hal_get_device_object_path(address);
1209         if (object_path == NULL) {
1210                 ERR("No searched device");
1211
1212                 adapter_proxy = _bt_hal_get_adapter_proxy();
1213                 if (adapter_proxy == NULL)
1214                         return  BT_HAL_ERROR_INTERNAL;
1215
1216                 g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1217                                 g_variant_new("(s)", address),
1218                                 G_DBUS_CALL_FLAGS_NONE,
1219                                 -1,
1220                                 NULL,
1221                                 &error);
1222
1223                 if (error != NULL) {
1224                         ERR("CreateDevice Fail: %s", error->message);
1225                         g_error_free(error);
1226                 }
1227
1228                 object_path = _bt_hal_get_device_object_path(address);
1229         }
1230         if (object_path == NULL)
1231                 return  BT_HAL_ERROR_INTERNAL;
1232
1233         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1234                         NULL, BT_HAL_BLUEZ_NAME,
1235                         object_path, BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
1236         g_free(object_path);
1237         if (proxy == NULL)
1238                 return  BT_HAL_ERROR_INTERNAL;
1239
1240
1241         g_dbus_proxy_call(proxy, "ConnectProfile",
1242                         g_variant_new("(s)", uuid),
1243                         G_DBUS_CALL_FLAGS_NONE,
1244                         BT_HAL_MAX_DBUS_TIMEOUT,
1245                         NULL,
1246                         (GAsyncReadyCallback)cb,
1247                         func_data);
1248
1249         return BT_HAL_ERROR_NONE;
1250 }
1251
1252 int _bt_hal_disconnect_profile(char *address, char *uuid,
1253                 void *cb, gpointer func_data)
1254 {
1255         char *object_path;
1256         GDBusProxy *proxy;
1257         GDBusConnection *conn;
1258
1259         conn = _bt_hal_get_system_gconn();
1260         if (conn == NULL)
1261                 return  BT_HAL_ERROR_INTERNAL;
1262
1263         object_path = _bt_hal_get_device_object_path(address);
1264         if (object_path == NULL)
1265                 return  BT_HAL_ERROR_INTERNAL;
1266
1267         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1268                         NULL, BT_HAL_BLUEZ_NAME,
1269                         object_path, BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
1270         g_free(object_path);
1271         if (proxy == NULL)
1272                 return  BT_HAL_ERROR_INTERNAL;
1273
1274         g_dbus_proxy_call(proxy, "DisconnectProfile",
1275                         g_variant_new("(s)", uuid),
1276                         G_DBUS_CALL_FLAGS_NONE,
1277                         BT_HAL_MAX_DBUS_TIMEOUT,
1278                         NULL,
1279                         (GAsyncReadyCallback)cb,
1280                         func_data);
1281
1282         return BT_HAL_ERROR_NONE;
1283 }
1284
1285 int _bt_hal_register_profile(bt_hal_register_profile_info_t *info, gboolean use_default_rfcomm)
1286 {
1287         GVariantBuilder *option_builder;
1288         GVariant *ret;
1289         GDBusProxy *proxy;
1290         GError *err = NULL;
1291         int result = BT_STATUS_SUCCESS;
1292
1293         proxy = _bt_hal_get_profile_proxy();
1294         if (proxy == NULL) {
1295                 ERR("Getting profile proxy failed");
1296                 return BT_STATUS_FAIL;
1297         }
1298
1299         option_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1300         if (info->authentication)
1301                 g_variant_builder_add(option_builder, "{sv}",
1302                                 "RequireAuthentication",
1303                                 g_variant_new_boolean(TRUE));
1304         if (info->authorization)
1305                 g_variant_builder_add(option_builder, "{sv}",
1306                                 "RequireAuthorization",
1307                                 g_variant_new_boolean(TRUE));
1308         if (info->role)
1309                 g_variant_builder_add(option_builder, "{sv}",
1310                                 "Role",
1311                                 g_variant_new_string(info->role));
1312
1313         /*
1314          * Setting RFCOMM channel to default value 0; would allow bluez to assign
1315          * RFCOMM channels based on the availability when two services want to use
1316          * the RFCOMM along with SPP. Hence bluez makes sure that no two services
1317          * use the same SPP RFCOMM channel.
1318          */
1319         if (use_default_rfcomm)
1320                 g_variant_builder_add(option_builder, "{sv}",
1321                                 "Channel",
1322                                 g_variant_new_uint16(RFCOMM_DEFAULT_PROFILE_CHANNEL));
1323         if (info->service)
1324                 g_variant_builder_add(option_builder, "{sv}",
1325                                 "Service",
1326                                 g_variant_new_string(info->service));
1327
1328         ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile",
1329                         g_variant_new("(osa{sv})", info->obj_path,
1330                                 info->uuid,
1331                                 option_builder),
1332                         G_DBUS_CALL_FLAGS_NONE, -1,
1333                         NULL, &err);
1334         if (err) {
1335                 ERR("RegisterProfile failed: %s", err->message);
1336
1337                 if (g_strrstr(err->message, BT_HAL_ACCESS_DENIED_MSG))
1338                         result = BT_STATUS_AUTH_REJECTED;
1339                 else
1340                         result = BT_STATUS_FAIL;
1341
1342                 g_clear_error(&err);
1343         }
1344
1345         g_variant_builder_unref(option_builder);
1346
1347         if (ret)
1348                 g_variant_unref(ret);
1349
1350         return result;
1351 }
1352
1353 void _bt_hal_unregister_profile(char *path)
1354 {
1355         GVariant *ret;
1356         GDBusProxy *proxy;
1357         GError *err = NULL;
1358
1359         proxy = _bt_hal_get_profile_proxy();
1360         if (proxy == NULL) {
1361                 ERR("Getting profile proxy failed");
1362                 return;
1363         }
1364
1365         ret = g_dbus_proxy_call_sync(proxy, "UnregisterProfile",
1366                         g_variant_new("(o)", path),
1367                         G_DBUS_CALL_FLAGS_NONE, -1,
1368                         NULL, &err);
1369         if (err) {
1370                 ERR("UnregisterProfile failed : %s", err->message);
1371                 g_clear_error(&err);
1372         }
1373
1374         if (ret)
1375                 g_variant_unref(ret);
1376
1377         return;
1378 }
1379
1380 static void __hal_new_connection_method(GDBusConnection *connection,
1381                 const gchar *sender,
1382                 const gchar *object_path,
1383                 const gchar *interface_name,
1384                 const gchar *method_name,
1385                 GVariant *parameters,
1386                 GDBusMethodInvocation *invocation,
1387                 gpointer user_data)
1388 {
1389         DBG("method %s", method_name);
1390         if (g_strcmp0(method_name, "NewConnection") == 0) {
1391                 int index;
1392                 int fd;
1393                 GUnixFDList *fd_list;
1394                 GDBusMessage *msg;
1395                 GVariantBuilder *properties;
1396                 char *obj_path;
1397                 bt_bdaddr_t remote_addr1;
1398                 char addr[BT_HAL_ADDRESS_STRING_SIZE];
1399                 bt_hal_new_connection_cb cb = user_data;
1400
1401                 g_variant_get(parameters, "(oha{sv})", &obj_path, &index,
1402                                 &properties);
1403
1404                 msg = g_dbus_method_invocation_get_message(invocation);
1405                 fd_list = g_dbus_message_get_unix_fd_list(msg);
1406                 if (fd_list == NULL) {
1407                         GQuark quark = g_quark_from_string("rfcomm-app");
1408                         GError *err = g_error_new(quark, 0, "No fd in message");
1409                         g_dbus_method_invocation_return_gerror(invocation, err);
1410                         g_error_free(err);
1411                         return;
1412                 }
1413
1414
1415                 fd = g_unix_fd_list_get(fd_list, index, NULL);
1416                 if (fd == -1) {
1417                         ERR("Invalid fd return");
1418                         GQuark quark = g_quark_from_string("rfcomm-app");
1419                         GError *err = g_error_new(quark, 0, "Invalid FD return");
1420                         g_dbus_method_invocation_return_gerror(invocation, err);
1421                         g_error_free(err);
1422                         return;
1423                 }
1424                 INFO("Object Path %s", obj_path);
1425
1426                 _bt_hal_convert_device_path_to_address(obj_path, addr);
1427                 _bt_hal_convert_addr_string_to_type(remote_addr1.address, (const char *)addr);
1428                 INFO("fd: %d, address %s", fd, addr);
1429
1430                 g_dbus_method_invocation_return_value(invocation, NULL);
1431
1432                 if (cb)
1433                         cb(object_path, fd, &remote_addr1);
1434         } else if (g_strcmp0(method_name, "RequestDisconnection") == 0) {
1435                 g_dbus_method_invocation_return_value(invocation, NULL);
1436         }
1437 }
1438
1439 static GDBusNodeInfo *_bt_hal_get_gdbus_node(const gchar *xml_data)
1440 {
1441         if (bus_id == 0) {
1442                 char *name = g_strdup_printf("org.bt.frwk%d", getpid());
1443
1444                 bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1445                                 name,
1446                                 G_BUS_NAME_OWNER_FLAGS_NONE,
1447                                 NULL,
1448                                 NULL,
1449                                 NULL,
1450                                 NULL,
1451                                 NULL);
1452                 DBG("Got bus id %d", bus_id);
1453                 g_free(name);
1454         }
1455
1456         return g_dbus_node_info_new_for_xml(xml_data, NULL);
1457 }
1458
1459 static const GDBusInterfaceVTable method_table = {
1460         __hal_new_connection_method,
1461         NULL,
1462         NULL,
1463 };
1464
1465 int _bt_hal_register_new_gdbus_object(const char *path, bt_hal_new_connection_cb cb)
1466 {
1467         GDBusConnection *gconn;
1468         int id;
1469         GError *error = NULL;
1470
1471         gconn = _bt_hal_get_system_gconn();
1472         if (gconn == NULL)
1473                 return -1;
1474
1475         if (new_conn_node == NULL)
1476                 new_conn_node = _bt_hal_get_gdbus_node(rfcomm_agent_xml);
1477
1478         if (new_conn_node == NULL)
1479                 return -1;
1480
1481         id = g_dbus_connection_register_object(gconn, path,
1482                         new_conn_node->interfaces[0],
1483                         &method_table,
1484                         cb, NULL, &error);
1485         if (id == 0) {
1486                 ERR("Failed to register: %s", error->message);
1487                 g_error_free(error);
1488                 return -1;
1489         }
1490
1491         DBG("NEW CONNECTION ID %d", id);
1492
1493         return id;
1494 }
1495
1496 void _bt_hal_unregister_gdbus_object(int object_id)
1497 {
1498         GDBusConnection *gconn;
1499
1500         gconn = _bt_hal_get_system_gconn();
1501         if (gconn == NULL)
1502                 return;
1503
1504         g_dbus_connection_unregister_object(gconn, object_id);
1505 }
1506
1507 int _bt_hal_discover_services(char *address, char *uuid, void *cb, gpointer func_data)
1508 {
1509         char *object_path;
1510         GDBusProxy *proxy;
1511         GDBusProxy *adapter_proxy;
1512         GError *err = NULL;
1513         GDBusConnection *conn;
1514
1515         conn = _bt_hal_get_system_gconn();
1516         if (conn == NULL) {
1517                 ERR("conn == NULL, return");
1518                 return  BT_STATUS_FAIL;
1519         }
1520
1521         object_path = _bt_hal_get_device_object_path(address);
1522         if (object_path == NULL) {
1523                 GVariant *ret = NULL;
1524
1525                 INFO("No searched device");
1526                 adapter_proxy = _bt_hal_get_adapter_proxy();
1527                 if (adapter_proxy == NULL) {
1528                         ERR("adapter_proxy == NULL, return");
1529                         return BT_STATUS_FAIL;
1530                 }
1531
1532                 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1533                                 g_variant_new("(s)", address),
1534                                 G_DBUS_CALL_FLAGS_NONE,
1535                                 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1536                                 &err);
1537                 if (err != NULL) {
1538                         ERR("CreateDevice Failed: %s", err->message);
1539                         g_clear_error(&err);
1540                 }
1541
1542                 if (ret)
1543                         g_variant_unref(ret);
1544
1545                 g_object_unref(adapter_proxy);
1546                 object_path = _bt_hal_get_device_object_path(address);
1547                 if (object_path == NULL) {
1548                         ERR("object_path == NULL, return");
1549                         return BT_STATUS_FAIL;
1550                 }
1551         }
1552
1553         proxy = g_dbus_proxy_new_sync(conn,
1554                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1555                         BT_HAL_BLUEZ_NAME, object_path,
1556                         BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
1557         g_free(object_path);
1558         if (proxy == NULL) {
1559                 ERR("Error while getting proxy");
1560                 return BT_STATUS_FAIL;
1561         }
1562
1563         g_dbus_proxy_call(proxy, "DiscoverServices",
1564                         g_variant_new("(s)", uuid),
1565                         G_DBUS_CALL_FLAGS_NONE,
1566                         BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1567                         (GAsyncReadyCallback)cb,
1568                         func_data);
1569         DBG("-");
1570         return BT_STATUS_SUCCESS;
1571 }
1572
1573 int _bt_hal_cancel_discovers(char *address)
1574 {
1575         char *object_path;
1576         GDBusProxy *proxy;
1577         GDBusProxy *adapter_proxy;
1578         GError *err = NULL;
1579         GDBusConnection *conn;
1580
1581         conn = _bt_hal_get_system_gconn();
1582         if (conn == NULL)
1583                 return  BT_STATUS_FAIL;
1584
1585         object_path = _bt_hal_get_device_object_path(address);
1586         if (object_path == NULL) {
1587                 GVariant *ret = NULL;
1588                 INFO("No searched device");
1589                 adapter_proxy = _bt_hal_get_adapter_proxy();
1590                 if (adapter_proxy == NULL) {
1591                         ERR("adapter_proxy == NULL, return");
1592                         return BT_STATUS_FAIL;
1593                 }
1594
1595                 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1596                                 g_variant_new("(s)", address),
1597                                 G_DBUS_CALL_FLAGS_NONE,
1598                                 BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1599                                 &err);
1600                 if (err != NULL) {
1601                         ERR("CreateDevice Failed: %s", err->message);
1602                         g_clear_error(&err);
1603                 }
1604
1605                 if (ret)
1606                         g_variant_unref(ret);
1607
1608                 g_object_unref(adapter_proxy);
1609
1610                 object_path = _bt_hal_get_device_object_path(address);
1611                 if (object_path == NULL)
1612                         return BT_STATUS_FAIL;
1613         }
1614
1615         proxy = g_dbus_proxy_new_sync(conn,
1616                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1617                         BT_HAL_BLUEZ_NAME, object_path,
1618                         BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
1619         g_free(object_path);
1620         g_dbus_proxy_call_sync(proxy, "CancelDiscovery",
1621                         NULL,
1622                         G_DBUS_CALL_FLAGS_NONE,
1623                         BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1624                         &err);
1625         if (err) {
1626                 ERR("DBus Error message: [%s]", err->message);
1627                 g_clear_error(&err);
1628                 return BT_STATUS_FAIL;
1629         }
1630
1631         if (proxy)
1632                 g_object_unref(proxy);
1633
1634         return BT_STATUS_SUCCESS;
1635 }
1636
1637 int _bt_hal_discover_service_uuids(char *address, char *remote_uuid)
1638 {
1639         char *object_path;
1640         GDBusProxy *proxy;
1641         GDBusConnection *gconn;
1642         GError *err = NULL;
1643         char **uuid_value = NULL;
1644         gsize size;
1645         int i = 0;
1646         GVariant *value = NULL;
1647         GVariant *ret = NULL;
1648         int result = BT_STATUS_FAIL;
1649
1650         DBG("+");
1651
1652         if (remote_uuid == NULL) {
1653                 ERR("remote_uuid == NULL, return");
1654                 return BT_STATUS_FAIL;
1655         }
1656
1657         gconn = _bt_hal_get_system_gconn();
1658         if (gconn == NULL) {
1659                 ERR("gconn == NULL, return");
1660                 return BT_STATUS_FAIL;
1661         }
1662
1663         object_path = _bt_hal_get_device_object_path(address);
1664         if (object_path == NULL) {
1665                 ERR("object_path == NULL, return");
1666                 return BT_STATUS_FAIL;
1667         }
1668
1669         proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE, NULL,
1670                         BT_HAL_BLUEZ_NAME, object_path, BT_HAL_PROPERTIES_INTERFACE, NULL,
1671                         &err);
1672         if (proxy == NULL) {
1673                 g_free(object_path);
1674                 ERR("proxy == NULL, return");
1675                 return BT_STATUS_FAIL;
1676         }
1677
1678         if (err) {
1679                 ERR("DBus Error: [%s]", err->message);
1680                 g_clear_error(&err);
1681         }
1682
1683         ret = g_dbus_proxy_call_sync(proxy, "GetAll",
1684                         g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
1685                         G_DBUS_CALL_FLAGS_NONE,
1686                         BT_HAL_MAX_DBUS_TIMEOUT, NULL,
1687                         &err);
1688         if (err) {
1689                 result = BT_STATUS_FAIL;
1690                 ERR("DBus Error : %s", err->message);
1691                 g_clear_error(&err);
1692                 goto done;
1693         }
1694
1695         if (ret == NULL) {
1696                 ERR("g_dbus_proxy_call_sync function return NULL");
1697                 result = BT_STATUS_FAIL;
1698                 goto done;
1699         }
1700
1701         g_variant_get(ret, "(@a{sv})", &value);
1702         g_variant_unref(ret);
1703         if (value) {
1704                 GVariant *temp_value = g_variant_lookup_value(value, "UUIDs",
1705                                 G_VARIANT_TYPE_STRING_ARRAY);
1706
1707                 if (temp_value)
1708                         size = g_variant_get_size(temp_value);
1709
1710                 if (size > 0) {
1711                         uuid_value = (char **)g_variant_get_strv(temp_value, &size);
1712                         DBG("Size items %d", size);
1713                 }
1714
1715                 if (temp_value)
1716                         g_variant_unref(temp_value);
1717
1718                 if (uuid_value) {
1719                         for (i = 0; uuid_value[i] != NULL; i++) {
1720                                 DBG("Remote uuids %s, searched uuid: %s",
1721                                                 uuid_value[i], remote_uuid);
1722                                 if (strcasecmp(uuid_value[i], remote_uuid) == 0) {
1723                                         result = BT_STATUS_SUCCESS;
1724                                         goto done;
1725                                 }
1726                         }
1727                 }
1728         }
1729
1730 done:
1731         if (proxy)
1732                 g_object_unref(proxy);
1733         if (value)
1734                 g_variant_unref(value);
1735         if (uuid_value)
1736                 g_free(uuid_value);
1737
1738         DBG("-");
1739         return result;
1740 }
1741
1742 int bt_hal_gatt_convert_prop2string(
1743                 bt_hal_gatt_characteristic_property_t properties,
1744                 char *char_properties[])
1745 {
1746         int flag_count = 0;
1747
1748         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_BROADCAST) {
1749                 char_properties[flag_count] = g_strdup("broadcast");
1750                 flag_count++;
1751         }
1752         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_READ) {
1753                 char_properties[flag_count] = g_strdup("read");
1754                 flag_count++;
1755         }
1756         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE) {
1757                 char_properties[flag_count] = g_strdup("write-without-response");
1758                 flag_count++;
1759         }
1760         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE) {
1761                 char_properties[flag_count] = g_strdup("write");
1762                 flag_count++;
1763         }
1764         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY) {
1765                 char_properties[flag_count] = g_strdup("notify");
1766                 flag_count++;
1767         }
1768         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_INDICATE) {
1769                 char_properties[flag_count] = g_strdup("indicate");
1770                 flag_count++;
1771         }
1772         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE) {
1773                 char_properties[flag_count] = g_strdup("authenticated-signed-writes");
1774                 flag_count++;
1775         }
1776         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE) {
1777                 char_properties[flag_count] = g_strdup("reliable-write");
1778                 flag_count++;
1779         }
1780         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES) {
1781                 char_properties[flag_count] = g_strdup("writable-auxiliaries");
1782                 flag_count++;
1783         }
1784         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ) {
1785                 char_properties[flag_count] = g_strdup("encrypt-read");
1786                 flag_count++;
1787         }
1788         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE) {
1789                 char_properties[flag_count] = g_strdup("encrypt-write");
1790                 flag_count++;
1791         }
1792         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ) {
1793                 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
1794                 flag_count++;
1795         }
1796         if (properties & BT_HAL_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE) {
1797                 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
1798                 flag_count++;
1799         }
1800
1801         if (flag_count == 0) {
1802                 char_properties[flag_count] = g_strdup("read");
1803                 flag_count++;
1804         }
1805
1806         return flag_count;
1807 }
1808
1809 int bt_hal_gatt_convert_perm2string(
1810                 bt_hal_gatt_permission_t properties,
1811                 char *char_properties[])
1812 {
1813         int flag_count = 0;
1814
1815         if (properties & BT_HAL_GATT_PERMISSION_READ) {
1816                 char_properties[flag_count] = g_strdup("read");
1817                 flag_count++;
1818         }
1819         if (properties & BT_HAL_GATT_PERMISSION_WRITE) {
1820                 char_properties[flag_count] = g_strdup("write");
1821                 flag_count++;
1822         }
1823         if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_READ) {
1824                 char_properties[flag_count] = g_strdup("encrypt-read");
1825                 flag_count++;
1826         }
1827         if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_WRITE) {
1828                 char_properties[flag_count] = g_strdup("encrypt-write");
1829                 flag_count++;
1830         }
1831         if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_READ) {
1832                 char_properties[flag_count] = g_strdup("encrypt-authenticated-read");
1833                 flag_count++;
1834         }
1835         if (properties & BT_HAL_GATT_PERMISSION_ENCRYPT_AUTHENTICATED_WRITE) {
1836                 char_properties[flag_count] = g_strdup("encrypt-authenticated-write");
1837                 flag_count++;
1838         }
1839
1840         if (flag_count == 0) {
1841                 char_properties[flag_count] = g_strdup("read");
1842                 flag_count++;
1843         }
1844
1845         return flag_count;
1846 }
1847
1848 gboolean _bt_hal_is_service_enabled(const char *uuid)
1849 {
1850         GDBusProxy *proxy;
1851         GError *error = NULL;
1852         GVariant *result;
1853         GVariant *temp;
1854         GVariantIter *iter = NULL;
1855         gchar *uuid_str;
1856         gboolean ret = FALSE;
1857
1858         DBG("+");
1859
1860         proxy = _bt_hal_get_adapter_properties_proxy();
1861         if (!proxy) {
1862                 DBG("_bt_hal_dbus_get_local_name: Adapter Properties proxy get failed!!!");
1863                 return FALSE;
1864         }
1865
1866         result = g_dbus_proxy_call_sync(proxy,
1867                         "Get", g_variant_new("(ss)",
1868                                 BT_HAL_ADAPTER_INTERFACE, "UUIDs"),
1869                         G_DBUS_CALL_FLAGS_NONE, -1,
1870                         NULL, &error);
1871         if (!result) {
1872                 if (error != NULL) {
1873                         ERR("Failed to get UUIDs (Error: %s)", error->message);
1874                         g_clear_error(&error);
1875                 } else
1876                         ERR("Failed to get UUIDs");
1877                 return FALSE;
1878         }
1879
1880         g_variant_get(result, "(v)", &temp);
1881         g_variant_get(temp, "as", &iter);
1882         if (!iter) {
1883                 ERR("Failed to get UUIDs");
1884                 g_variant_unref(result);
1885                 return FALSE;
1886         }
1887
1888         while (g_variant_iter_loop(iter, "s", &uuid_str)) {
1889                 DBG("UUID string [%s]\n", uuid_str);
1890                 if (!strncasecmp(uuid, uuid_str, strlen(uuid))) {
1891                         ret = TRUE;
1892                         break;
1893                 }
1894         }
1895
1896         g_variant_iter_free(iter);
1897         g_variant_unref(result);
1898         g_variant_unref(temp);
1899         DBG("-");
1900         return ret;
1901 }