Merge the code from tizen_2.4
[platform/core/connectivity/bluetooth-frwk.git] / bt-api / bt-common.c
1 /*
2  * Bluetooth-frwk
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
7  *               Girishashok Joshi <girish.joshi@samsung.com>
8  *               Chanyeol Park <chanyeol.park@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *              http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */
23
24 #include <string.h>
25 #include <fcntl.h>
26 #include <unistd.h>
27 #include <sys/types.h>
28 #include <stdlib.h>
29 #include <sys/socket.h>
30
31
32 #include <gio/gunixfdlist.h>
33
34
35 #include "bluetooth-api.h"
36 #include "bluetooth-audio-api.h"
37 #include "bluetooth-hid-api.h"
38 #include "bluetooth-media-control.h"
39 #include "bt-internal-types.h"
40 #include "bluetooth-ipsp-api.h"
41
42 #include "bt-common.h"
43 #include "bt-request-sender.h"
44 #include "bt-event-handler.h"
45
46 static bt_user_info_t user_info[BT_MAX_USER_INFO];
47 static DBusConnection *system_conn = NULL;
48 static GDBusConnection *system_gdbus_conn = NULL;
49
50
51 static guint bus_id;
52
53 static GDBusConnection *system_gconn = NULL;
54
55 #define DBUS_TIMEOUT 20 * 1000 /* 20 Seconds */
56
57 GDBusConnection *g_bus_get_private_conn(void)
58 {
59         GError *error = NULL;
60         char *address;
61         GDBusConnection *private_gconn = NULL;
62
63         address = g_dbus_address_get_for_bus_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
64         if (address == NULL) {
65                 if (error) {
66                         BT_ERR ("Failed to get bus address: %s", error->message);
67                         g_clear_error(&error);
68                 }
69                 return NULL;
70         }
71
72         private_gconn = g_dbus_connection_new_for_address_sync (address,
73                                 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
74                                 G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
75                                 NULL, /* GDBusAuthObserver */
76                                 NULL,
77                                 &error);
78         if (!private_gconn) {
79                 if (error) {
80                         BT_ERR("Unable to connect to dbus: %s", error->message);
81                         g_clear_error(&error);
82                 }
83                 return NULL;
84         }
85
86         return private_gconn;
87 }
88
89 GDBusConnection *_bt_gdbus_init_system_gconn(void)
90 {
91         dbus_threads_init_default();
92
93         g_type_init();
94
95         if (system_gconn != NULL)
96                 return system_gconn;
97
98         system_gconn = g_bus_get_private_conn();
99
100         return system_gconn;
101 }
102
103 GDBusConnection *_bt_gdbus_get_system_gconn(void)
104 {
105         if (system_gconn == NULL) {
106                 system_gconn = _bt_gdbus_init_system_gconn();
107         } else if (g_dbus_connection_is_closed(system_gconn)){
108                 system_gconn = g_bus_get_private_conn();
109         }
110
111         return system_gconn;
112 }
113
114 void _bt_print_device_address_t(const bluetooth_device_address_t *addr)
115 {
116         BT_DBG("%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", addr->addr[0], addr->addr[1], addr->addr[2],
117                                 addr->addr[3], addr->addr[4], addr->addr[5]);
118 }
119
120 void _bt_set_user_data(int type, void *callback, void *user_data)
121 {
122         user_info[type].cb = callback;
123         user_info[type].user_data = user_data;
124 }
125
126 bt_user_info_t *_bt_get_user_data(int type)
127 {
128         return &user_info[type];
129 }
130
131 void _bt_common_event_cb(int event, int result, void *param,
132                                         void *callback, void *user_data)
133 {
134         bluetooth_event_param_t bt_event = { 0, };
135         bt_event.event = event;
136         bt_event.result = result;
137         bt_event.param_data = param;
138
139         if (callback)
140                 ((bluetooth_cb_func_ptr)callback)(bt_event.event, &bt_event,
141                                         user_data);
142 }
143
144 void _bt_input_event_cb(int event, int result, void *param,
145                                         void *callback, void *user_data)
146 {
147         hid_event_param_t bt_event = { 0, };
148         bt_event.event = event;
149         bt_event.result = result;
150         bt_event.param_data = param;
151
152         if (callback)
153                 ((hid_cb_func_ptr)callback)(bt_event.event, &bt_event,
154                                         user_data);
155 }
156
157 void _bt_headset_event_cb(int event, int result, void *param,
158                                         void *callback, void *user_data)
159 {
160         bt_audio_event_param_t bt_event = { 0, };
161         bt_event.event = event;
162         bt_event.result = result;
163         bt_event.param_data = param;
164
165         if (callback)
166                 ((bt_audio_func_ptr)callback)(bt_event.event, &bt_event,
167                                         user_data);
168 }
169
170 void _bt_a2dp_source_event_cb(int event, int result, void *param,
171                                         void *callback, void *user_data)
172 {
173         bt_audio_event_param_t bt_event = { 0, };
174         bt_event.event = event;
175         bt_event.result = result;
176         bt_event.param_data = param;
177         if (callback)
178                 ((bt_audio_func_ptr)callback)(bt_event.event, &bt_event,
179                                         user_data);
180 }
181
182 void _bt_hf_event_cb(int event, int result, void *param,
183                                         void *callback, void *user_data)
184 {
185         bt_hf_event_param_t bt_event = { 0, };
186         bt_event.event = event;
187         bt_event.result = result;
188         bt_event.param_data = param;
189
190         if (callback)
191                 ((bt_hf_func_ptr)callback)(bt_event.event, &bt_event,
192                                         user_data);
193 }
194
195
196 void _bt_avrcp_event_cb(int event, int result, void *param,
197                                         void *callback, void *user_data)
198 {
199         media_event_param_t bt_event = { 0, };
200         bt_event.event = event;
201         bt_event.result = result;
202         bt_event.param_data = param;
203
204         if (callback)
205                 ((media_cb_func_ptr)callback)(bt_event.event, &bt_event,
206                                         user_data);
207 }
208
209 void _bt_divide_device_class(bluetooth_device_class_t *device_class,
210                                 unsigned int cod)
211 {
212         ret_if(device_class == NULL);
213
214         device_class->major_class = (unsigned short)(cod & 0x00001F00) >> 8;
215         device_class->minor_class = (unsigned short)((cod & 0x000000FC));
216         device_class->service_class = (unsigned long)((cod & 0x00FF0000));
217
218         if (cod & 0x002000) {
219                 device_class->service_class |=
220                 BLUETOOTH_DEVICE_SERVICE_CLASS_LIMITED_DISCOVERABLE_MODE;
221         }
222 }
223
224 void _bt_convert_addr_string_to_type(unsigned char *addr,
225                                         const char *address)
226 {
227         int i;
228         char *ptr = NULL;
229
230         ret_if(address == NULL);
231         ret_if(addr == NULL);
232
233         for (i = 0; i < BT_ADDRESS_LENGTH_MAX; i++) {
234                 addr[i] = strtol(address, &ptr, 16);
235                 if (ptr[0] != '\0') {
236                         if (ptr[0] != ':')
237                                 return;
238
239                         address = ptr + 1;
240                 }
241         }
242 }
243
244 void _bt_convert_addr_type_to_string(char *address,
245                                 unsigned char *addr)
246 {
247         ret_if(address == NULL);
248         ret_if(addr == NULL);
249
250         g_snprintf(address, BT_ADDRESS_STRING_SIZE,
251                         "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
252                         addr[0], addr[1], addr[2],
253                         addr[3], addr[4], addr[5]);
254 }
255
256 int _bt_copy_utf8_string(char *dest, const char *src, unsigned int length)
257 {
258         int i;
259         const char *p = src;
260         char *next;
261         int count;
262
263         if (dest == NULL || src == NULL)
264                 return BLUETOOTH_ERROR_INVALID_PARAM;
265
266         i = 0;
267         while (*p != '\0' && i < length) {
268                 next = g_utf8_next_char(p);
269                 count = next - p;
270
271                 while (count > 0 && ((i + count) < length)) {
272                         dest[i++] = *p;
273                         p++;
274                         count --;
275                 }
276                 p = next;
277         }
278         return BLUETOOTH_ERROR_NONE;
279 }
280
281 gboolean _bt_utf8_validate(char *name)
282 {
283         BT_DBG("+");
284         gunichar2 *u16;
285         glong items_written = 0;
286
287         if (FALSE == g_utf8_validate(name, -1, NULL))
288                 return FALSE;
289
290         u16 = g_utf8_to_utf16(name, -1, NULL, &items_written, NULL);
291         if (u16 == NULL)
292                 return FALSE;
293
294         g_free(u16);
295
296         if (items_written != g_utf8_strlen(name, -1))
297                 return FALSE;
298
299         BT_DBG("-");
300         return TRUE;
301 }
302
303
304 static GDBusProxy *profile_gproxy;
305 static GDBusConnection *gconn;
306 static int latest_id = -1;
307 #define BT_RFCOMM_ID_MAX 245
308 static gboolean id_used[BT_RFCOMM_ID_MAX];
309 GDBusNodeInfo *new_conn_node;
310
311 static const gchar rfcomm_agent_xml[] =
312 "<node name='/'>"
313 " <interface name='org.bluez.Profile1'>"
314 "     <method name='NewConnection'>"
315 "          <arg type='o' name='object' direction='in'/>"
316 "          <arg type='h' name='fd' direction='in'/>"
317 "          <arg type='a{sv}' name='properties' direction='in'/>"
318 "     </method>"
319 "     <method name='RequestDisconnection'>"
320 "          <arg type='o' name='device' direction='in'/>"
321 "     </method>"
322 "  </interface>"
323 "</node>";
324
325 static void __new_connection_method(GDBusConnection *connection,
326                                             const gchar *sender,
327                                             const gchar *object_path,
328                                             const gchar *interface_name,
329                                             const gchar *method_name,
330                                             GVariant *parameters,
331                                             GDBusMethodInvocation *invocation,
332                                             gpointer user_data)
333 {
334         BT_DBG("method %s", method_name);
335         if (g_strcmp0(method_name, "NewConnection") == 0) {
336                 int index;
337                 GDBusMessage *msg;
338                 GUnixFDList *fd_list;
339                 GVariantBuilder *properties;
340                 char *obj_path;
341                 char addr[20];
342                 bluetooth_device_address_t  remote_addr1;
343                 bt_new_connection_cb cb = user_data;
344                 int fd;
345
346                 g_variant_get(parameters, "(oha{sv})", &obj_path, &index,
347                                                                 &properties);
348
349                 msg = g_dbus_method_invocation_get_message(invocation);
350                 fd_list = g_dbus_message_get_unix_fd_list(msg);
351                 if (fd_list == NULL) {
352                         GQuark quark = g_quark_from_string("rfcomm-app");
353                         GError *err = g_error_new(quark, 0, "No fd in message");
354                         g_dbus_method_invocation_return_gerror(invocation, err);
355                         g_error_free(err);
356                         return;
357                 }
358
359
360                 fd = g_unix_fd_list_get(fd_list, index, NULL);
361                 if (fd == -1) {
362                         BT_ERR("Invalid fd return");
363                         GQuark quark = g_quark_from_string("rfcomm-app");
364                         GError *err = g_error_new(quark, 0, "Invalid FD return");
365                         g_dbus_method_invocation_return_gerror(invocation, err);
366                         g_error_free(err);
367                         return;
368                 }
369                 BT_INFO("Object Path %s", obj_path);
370
371                 _bt_device_path_to_address(obj_path, addr);
372                 _bt_convert_addr_string_to_type(remote_addr1.addr, (const char *)addr);
373                 BT_INFO("fd: %d, address %s", fd, addr);
374
375                 g_dbus_method_invocation_return_value(invocation, NULL);
376
377                 if (cb)
378                         cb(object_path, fd, &remote_addr1);
379         } else if (g_strcmp0(method_name, "RequestDisconnection") == 0) {
380                 g_dbus_method_invocation_return_value(invocation, NULL);
381         }
382 }
383
384
385 static const GDBusInterfaceVTable method_table = {
386         __new_connection_method,
387         NULL,
388         NULL,
389 };
390
391 void _bt_swap_addr(unsigned char *dst, const unsigned char *src)
392 {
393         int i;
394
395         for (i = 0; i < 6; i++)
396                 dst[i] = src[5-i];
397 }
398
399 int __rfcomm_assign_id(void)
400 {
401         int index;
402
403         BT_DBG("latest_id: %d", latest_id);
404
405         index = latest_id + 1;
406
407         if (index >= BT_RFCOMM_ID_MAX)
408                 index = 0;
409
410         BT_DBG("index: %d", index);
411
412         while (id_used[index] == TRUE) {
413                 if (index == latest_id) {
414                         /* No available ID */
415                         BT_ERR("All request ID is used");
416                         return -1;
417                 }
418
419                 index++;
420
421                 if (index >= BT_RFCOMM_ID_MAX)
422                         index = 0;
423         }
424
425         latest_id = index;
426         id_used[index] = TRUE;
427
428         BT_DBG("Assigned Id: %d", latest_id);
429
430         return latest_id;
431 }
432
433 void __rfcomm_delete_id(int id)
434 {
435         ret_if(id >= BT_RFCOMM_ID_MAX);
436         ret_if(id < 0);
437
438         id_used[id] = FALSE;
439
440         /* Next server will use this ID */
441         latest_id = id - 1;
442 }
443
444 static GDBusConnection *__get_gdbus_connection()
445 {
446         if (gconn == NULL)
447                 gconn = g_bus_get_private_conn();
448
449         return gconn;
450 }
451
452 static GDBusProxy *__bt_gdbus_get_profile_proxy(void)
453 {
454         GDBusConnection *gconn;
455         GError *err = NULL;
456
457         if (profile_gproxy)
458                 return profile_gproxy;
459
460         gconn = __get_gdbus_connection();
461         if (gconn == NULL)
462                 return NULL;
463
464         profile_gproxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE,
465                                                 NULL, BT_BLUEZ_NAME,
466                                                 "/org/bluez",
467                                                 "org.bluez.ProfileManager1",
468                                                 NULL, &err);
469         if (err) {
470                 BT_ERR("Unable to create proxy: %s", err->message);
471                 g_clear_error(&err);
472                 return NULL;
473         }
474
475         return profile_gproxy;
476 }
477
478 static GDBusProxy *__bt_gdbus_get_device_proxy(char *object_path)
479 {
480         GDBusConnection *gconn;
481         GError *err = NULL;
482         GDBusProxy *device_gproxy;
483
484         gconn = __get_gdbus_connection();
485         if (gconn == NULL)
486                 return NULL;
487
488         device_gproxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE,
489                                                 NULL, BT_BLUEZ_NAME,
490                                                 object_path,
491                                                 BT_DEVICE_INTERFACE,
492                                                 NULL, &err);
493
494         if (err) {
495                 BT_ERR("Unable to create proxy: %s", err->message);
496                 g_clear_error(&err);
497                 return NULL;
498         }
499
500         return device_gproxy;
501 }
502
503 void _bt_unregister_gdbus(int object_id)
504 {
505         GDBusConnection *gconn;
506
507         gconn = __get_gdbus_connection();
508         if (gconn == NULL)
509                 return;
510
511         g_dbus_connection_unregister_object(gconn, object_id);
512 }
513
514 int _bt_register_new_conn(const char *path, bt_new_connection_cb cb)
515 {
516         GDBusConnection *gconn;
517         int id;
518         GError *error = NULL;
519
520         gconn = __get_gdbus_connection();
521         if (gconn == NULL)
522                 return -1;
523
524         if (new_conn_node == NULL)
525                 new_conn_node = _bt_get_gdbus_node(rfcomm_agent_xml);
526
527         if (new_conn_node == NULL)
528                 return -1;
529
530         id = g_dbus_connection_register_object(gconn, path,
531                                                 new_conn_node->interfaces[0],
532                                                 &method_table,
533                                                 cb, NULL, &error);
534         if (id == 0) {
535                 BT_ERR("Failed to register: %s", error->message);
536                 g_error_free(error);
537                 return -1;
538         }
539
540         BT_DBG("NEW CONNECTION ID %d", id);
541
542         return id;
543 }
544
545 static GDBusProxy * __bt_gdbus_get_adapter_proxy()
546 {
547         GError *err = NULL;
548         GDBusProxy *manager_proxy = NULL;
549         GDBusProxy *adapter_proxy = NULL;
550         GDBusConnection *conn;
551         GVariant *result = NULL;
552         char *adapter_path = NULL;
553
554         conn = __get_gdbus_connection();
555         retv_if(conn == NULL, NULL);
556
557         manager_proxy =  g_dbus_proxy_new_sync(conn,
558                         G_DBUS_PROXY_FLAGS_NONE, NULL,
559                         BT_BLUEZ_NAME,
560                         BT_MANAGER_PATH,
561                         BT_MANAGER_INTERFACE,
562                         NULL, &err);
563
564         if (!manager_proxy) {
565                 BT_ERR("Unable to create proxy: %s", err->message);
566                 goto fail;
567         }
568
569         result = g_dbus_proxy_call_sync(manager_proxy, "DefaultAdapter", NULL,
570                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
571         if (!result) {
572                 if (err != NULL)
573                         BT_ERR("Fail to get DefaultAdapter (Error: %s)", err->message);
574                 else
575                         BT_ERR("Fail to get DefaultAdapter");
576
577                 goto fail;
578         }
579
580         if (g_strcmp0(g_variant_get_type_string(result), "(o)")) {
581                 BT_ERR("Incorrect result\n");
582                 goto fail;
583         }
584
585         g_variant_get(result, "(&o)", &adapter_path);
586
587         if (adapter_path == NULL ||
588                 strlen(adapter_path) >= BT_ADAPTER_OBJECT_PATH_MAX) {
589                 BT_ERR("Adapter path is inproper\n");
590                 goto fail;
591         }
592
593         BT_INFO("Adapter Path %s", adapter_path);
594
595         adapter_proxy = g_dbus_proxy_new_sync(conn,
596                                         G_DBUS_PROXY_FLAGS_NONE, NULL,
597                                         BT_BLUEZ_NAME,
598                                         adapter_path,
599                                         BT_ADAPTER_INTERFACE,
600                                         NULL, &err);
601         if (err) {
602                 BT_ERR("DBus Error message: [%s]", err->message);
603                 g_clear_error(&err);
604         }
605
606 fail:
607         if (manager_proxy)
608                 g_object_unref(manager_proxy);
609         if (result)
610                 g_variant_unref(result);
611         return adapter_proxy;
612 }
613
614 int _bt_register_new_conn_ex(const char *path, const char *bus_name,bt_new_connection_cb cb)
615 {
616         GDBusConnection *gconn;
617         int id;
618         GError *error = NULL;
619
620         gconn = __get_gdbus_connection();
621         if (gconn == NULL)
622                 return -1;
623
624         if (new_conn_node == NULL)
625                 new_conn_node = _bt_get_gdbus_node_ex(rfcomm_agent_xml, bus_name);
626
627         if (new_conn_node == NULL)
628                 return -1;
629
630         id = g_dbus_connection_register_object(gconn, path,
631                                                 new_conn_node->interfaces[0],
632                                                 &method_table,
633                                                 cb, NULL, &error);
634         if (id == 0) {
635                 BT_ERR("Failed to register: %s", error->message);
636                 g_error_free(error);
637                 return -1;
638         }
639
640         BT_DBG("NEW CONNECTION ID %d", id);
641
642         return id;
643 }
644
645 int _bt_register_profile(bt_register_profile_info_t *info, gboolean use_default_rfcomm)
646 {
647         GVariantBuilder *option_builder;
648         GVariant *ret;
649         GDBusProxy *proxy;
650         GError *err = NULL;
651         int result = BLUETOOTH_ERROR_NONE;
652
653         proxy = __bt_gdbus_get_profile_proxy();
654         if (proxy == NULL) {
655                 BT_ERR("Getting profile proxy failed");
656                 return BLUETOOTH_ERROR_INTERNAL;
657         }
658
659         option_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
660         if (info->authentication)
661                 g_variant_builder_add(option_builder, "{sv}",
662                                                 "RequireAuthentication",
663                                                 g_variant_new_boolean(TRUE));
664         if (info->authorization)
665                 g_variant_builder_add(option_builder, "{sv}",
666                                                 "RequireAuthorization",
667                                                 g_variant_new_boolean(TRUE));
668         if (info->role)
669                 g_variant_builder_add(option_builder, "{sv}",
670                                                 "Role",
671                                                 g_variant_new_string(info->role));
672
673         /* Setting RFCOMM channel to default value 0; would allow bluez to assign
674          * RFCOMM channels based on the availability when two services want
675          * to use the RFCOMM along with SPP. Hence bluez makes sure that no
676          * two services use the same SPP RFCOMM channel. */
677         if (use_default_rfcomm)
678                 g_variant_builder_add(option_builder, "{sv}",
679                                                 "Channel",
680                                                 g_variant_new_uint16(RFCOMM_DEFAULT_PROFILE_CHANNEL));
681         if (info->service)
682                 g_variant_builder_add(option_builder, "{sv}",
683                                                 "Service",
684                                                 g_variant_new_string(info->service));
685
686         ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile",
687                                         g_variant_new("(osa{sv})", info->obj_path,
688                                                                 info->uuid,
689                                                                 option_builder),
690                                         G_DBUS_CALL_FLAGS_NONE, -1,
691                                         NULL, &err);
692         if (err) {
693                 g_dbus_error_strip_remote_error(err);
694                 BT_ERR("RegisterProfile failed: %s", err->message);
695
696                 if (g_strrstr(err->message, BT_ACCESS_DENIED_MSG))
697                         result = BLUETOOTH_ERROR_ACCESS_DENIED;
698                 else
699                         result = BLUETOOTH_ERROR_INTERNAL;
700
701                 g_clear_error(&err);
702         }
703
704         g_variant_builder_unref(option_builder);
705
706         if (ret)
707                 g_variant_unref(ret);
708
709         return result;
710 }
711
712 int _bt_register_profile_ex(bt_register_profile_info_t *info, gboolean use_default_rfcomm, const char *name, const char *path)
713 {
714         GVariantBuilder *option_builder;
715         GVariant *ret;
716         GDBusProxy *proxy;
717         GError *err = NULL;
718         int result = BLUETOOTH_ERROR_NONE;
719
720         proxy = __bt_gdbus_get_profile_proxy();
721         if (proxy == NULL) {
722                 BT_ERR("Getting profile proxy failed");
723                 return BLUETOOTH_ERROR_INTERNAL;
724         }
725
726         option_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
727         if (info->authentication)
728                 g_variant_builder_add(option_builder, "{sv}",
729                                                 "RequireAuthentication",
730                                                 g_variant_new_boolean(TRUE));
731         if (info->authorization)
732                 g_variant_builder_add(option_builder, "{sv}",
733                                                 "RequireAuthorization",
734                                                 g_variant_new_boolean(TRUE));
735         if (info->role)
736                 g_variant_builder_add(option_builder, "{sv}",
737                                                 "Role",
738                                                 g_variant_new_string(info->role));
739
740         /* Setting RFCOMM channel to default value 0; would allow bluez to assign
741          * RFCOMM channels based on the availability when two services want
742          * to use the RFCOMM along with SPP. Hence bluez makes sure that no
743          * two services use the same SPP RFCOMM channel. */
744         if (use_default_rfcomm)
745                 g_variant_builder_add(option_builder, "{sv}",
746                                                 "Channel",
747                                                 g_variant_new_uint16(RFCOMM_DEFAULT_PROFILE_CHANNEL));
748         if (info->service)
749                 g_variant_builder_add(option_builder, "{sv}",
750                                                 "Service",
751                                                 g_variant_new_string(info->service));
752
753         ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile2",
754                                         g_variant_new("(osssa{sv})", info->obj_path,
755                                                                 info->uuid,
756                                                                 name,
757                                                                 path,
758                                                                 option_builder),
759                                         G_DBUS_CALL_FLAGS_NONE, -1,
760                                         NULL, &err);
761         if (err) {
762                 g_dbus_error_strip_remote_error(err);
763                 BT_ERR("RegisterProfile failed: %s", err->message);
764
765                 if (g_strrstr(err->message, BT_ACCESS_DENIED_MSG))
766                         result = BLUETOOTH_ERROR_ACCESS_DENIED;
767                 else
768                         result = BLUETOOTH_ERROR_INTERNAL;
769
770                 g_clear_error(&err);
771         }
772
773         g_variant_builder_unref(option_builder);
774
775         if (ret)
776                 g_variant_unref(ret);
777
778         return result;
779 }
780
781 int _bt_register_profile_platform(bt_register_profile_info_t *info, gboolean use_default_rfcomm)
782 {
783         GVariantBuilder *option_builder;
784         GVariant *ret;
785         GDBusProxy *proxy;
786         GError *err = NULL;
787         int result = BLUETOOTH_ERROR_NONE;
788
789         proxy = __bt_gdbus_get_profile_proxy();
790         if (proxy == NULL) {
791                 BT_ERR("Getting profile proxy failed");
792                 return BLUETOOTH_ERROR_INTERNAL;
793         }
794
795         option_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
796         if (info->authentication)
797                 g_variant_builder_add(option_builder, "{sv}",
798                                                 "RequireAuthentication",
799                                                 g_variant_new_boolean(TRUE));
800         if (info->authorization)
801                 g_variant_builder_add(option_builder, "{sv}",
802                                                 "RequireAuthorization",
803                                                 g_variant_new_boolean(TRUE));
804         if (info->role)
805                 g_variant_builder_add(option_builder, "{sv}",
806                                                 "Role",
807                                                 g_variant_new_string(info->role));
808
809         /* Setting RFCOMM channel to default value 0; would allow bluez to assign
810          * RFCOMM channels based on the availability when two services want
811          * to use the RFCOMM along with SPP. Hence bluez makes sure that no
812          * two services use the same SPP RFCOMM channel. */
813         if (use_default_rfcomm)
814                 g_variant_builder_add(option_builder, "{sv}",
815                                                 "Channel",
816                                                 g_variant_new_uint16(RFCOMM_DEFAULT_PROFILE_CHANNEL));
817         if (info->service)
818                 g_variant_builder_add(option_builder, "{sv}",
819                                                 "Service",
820                                                 g_variant_new_string(info->service));
821
822         ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile1",
823                                         g_variant_new("(osa{sv})", info->obj_path,
824                                                                 info->uuid,
825                                                                 option_builder),
826                                         G_DBUS_CALL_FLAGS_NONE, -1,
827                                         NULL, &err);
828
829         if (err) {
830                 g_dbus_error_strip_remote_error(err);
831                 BT_ERR("RegisterProfile failed: %s", err->message);
832
833                 if (g_strrstr(err->message, BT_ACCESS_DENIED_MSG))
834                         result = BLUETOOTH_ERROR_ACCESS_DENIED;
835                 else
836                         result = BLUETOOTH_ERROR_INTERNAL;
837
838                 g_clear_error(&err);
839         }
840
841         g_variant_builder_unref(option_builder);
842
843         if (ret)
844                 g_variant_unref(ret);
845
846         return result;
847 }
848
849
850 void _bt_unregister_profile(char *path)
851 {
852         GVariant *ret;
853         GDBusProxy *proxy;
854         GError *err = NULL;
855
856         proxy = __bt_gdbus_get_profile_proxy();
857         if (proxy == NULL) {
858                 BT_ERR("Getting profile proxy failed");
859                 return;
860         }
861
862         ret = g_dbus_proxy_call_sync(proxy, "UnregisterProfile",
863                         g_variant_new("(o)", path),
864                         G_DBUS_CALL_FLAGS_NONE, -1,
865                         NULL, &err);
866         if (err) {
867                 BT_ERR("UnregisterProfile failed : %s", err->message);
868                 g_clear_error(&err);
869         }
870
871         if (ret)
872                 g_variant_unref(ret);
873
874         return;
875 }
876
877 GDBusNodeInfo * _bt_get_gdbus_node(const gchar *xml_data)
878 {
879         if (bus_id == 0) {
880                 char *name = g_strdup_printf("org.bt.frwk%d", getpid());
881
882                 bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
883                                                 name,
884                                                 G_BUS_NAME_OWNER_FLAGS_NONE,
885                                                 NULL,
886                                                 NULL,
887                                                 NULL,
888                                                 NULL,
889                                                 NULL);
890                 BT_DBG("Got bus id %d", bus_id);
891                 g_free(name);
892         }
893
894         return g_dbus_node_info_new_for_xml(xml_data, NULL);
895 }
896
897 GDBusNodeInfo * _bt_get_gdbus_node_ex(const gchar *xml_data, const char *bus_name)
898 {
899         if (bus_id == 0) {
900                 char *name = g_strdup(bus_name);
901                 bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
902                                                 name,
903                                                 G_BUS_NAME_OWNER_FLAGS_NONE,
904                                                 NULL,
905                                                 NULL,
906                                                 NULL,
907                                                 NULL,
908                                                 NULL);
909                 BT_DBG("Got bus id %d", bus_id);
910                 g_free(name);
911         }
912
913         return g_dbus_node_info_new_for_xml(xml_data, NULL);
914 }
915
916 int _bt_connect_profile(char *address, char *uuid, void *cb,
917                                                         gpointer func_data)
918 {
919         GDBusProxy *proxy;
920         GDBusProxy *adapter_proxy;
921         char *object_path;
922         GError *err = NULL;
923
924         object_path = _bt_get_device_object_path(address);
925
926         if (object_path == NULL) {
927                 GVariant *ret = NULL;
928                 BT_ERR("No searched device");
929                 adapter_proxy = __bt_gdbus_get_adapter_proxy();
930
931                 if (adapter_proxy == NULL) {
932                         BT_ERR("adapter proxy is NULL");
933                         return BLUETOOTH_ERROR_INTERNAL;
934                 }
935
936                 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
937                                 g_variant_new("(s)", address),
938                                 G_DBUS_CALL_FLAGS_NONE,
939                                 DBUS_TIMEOUT, NULL,
940                                 &err);
941
942                 if (err != NULL) {
943                         BT_ERR("CreateDevice Failed: %s", err->message);
944                         g_clear_error(&err);
945                 }
946                 if (ret)
947                         g_variant_unref(ret);
948                 g_object_unref(adapter_proxy);
949                 object_path = _bt_get_device_object_path(address);
950
951                 if (object_path == NULL)
952                         return BLUETOOTH_ERROR_INTERNAL;
953         }
954
955         proxy = __bt_gdbus_get_device_proxy(object_path);
956         g_free(object_path);
957
958         if (proxy == NULL) {
959                 BT_ERR("Error while getting proxy");
960                 return BLUETOOTH_ERROR_INTERNAL;
961         }
962
963         g_dbus_proxy_call(proxy, "ConnectProfile",
964                         g_variant_new("(s)", uuid),
965                         G_DBUS_CALL_FLAGS_NONE,
966                         DBUS_TIMEOUT, NULL,
967                         (GAsyncReadyCallback)cb,
968                         func_data);
969         BT_DBG("-");
970         return BLUETOOTH_ERROR_NONE;
971 }
972
973 int _bt_discover_services(char *address, char *uuid, void *cb,
974                 gpointer func_data)
975 {
976         char *object_path;
977         GDBusProxy *proxy;
978         GDBusProxy *adapter_proxy;
979         GError *err = NULL;
980         object_path = _bt_get_device_object_path(address);
981         if (object_path == NULL) {
982                 GVariant *ret = NULL;
983                 BT_ERR("No searched device");
984                 adapter_proxy = __bt_gdbus_get_adapter_proxy();
985                 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
986                 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
987                                 g_variant_new("(s)", address),
988                                 G_DBUS_CALL_FLAGS_NONE,
989                                 DBUS_TIMEOUT, NULL,
990                                 &err);
991                 if (err != NULL) {
992                         BT_ERR("CreateDevice Failed: %s", err->message);
993                         g_clear_error(&err);
994                 }
995                 if (ret)
996                         g_variant_unref(ret);
997
998                 g_object_unref(adapter_proxy);
999
1000                 object_path = _bt_get_device_object_path(address);
1001                 if (object_path == NULL)
1002                         return BLUETOOTH_ERROR_INTERNAL;
1003         }
1004         proxy = __bt_gdbus_get_device_proxy(object_path);
1005         g_free(object_path);
1006         if (proxy == NULL) {
1007                 BT_ERR("Error while getting proxy");
1008                 return BLUETOOTH_ERROR_INTERNAL;
1009         }
1010         g_dbus_proxy_call(proxy, "DiscoverServices",
1011                         g_variant_new("(s)", uuid),
1012                         G_DBUS_CALL_FLAGS_NONE,
1013                         DBUS_TIMEOUT, NULL,
1014                         (GAsyncReadyCallback)cb,
1015                         func_data);
1016         BT_DBG("-");
1017         return BLUETOOTH_ERROR_NONE;
1018 }
1019
1020 int _bt_cancel_discovers(char *address)
1021 {
1022         char *object_path;
1023         GDBusProxy *proxy;
1024         GDBusProxy *adapter_proxy;
1025         GError *err = NULL;
1026         object_path = _bt_get_device_object_path(address);
1027         if (object_path == NULL) {
1028                 GVariant *ret = NULL;
1029                 BT_ERR("No searched device");
1030                 adapter_proxy = __bt_gdbus_get_adapter_proxy();
1031                 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1032                 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1033                                 g_variant_new("(s)", address),
1034                                 G_DBUS_CALL_FLAGS_NONE,
1035                                 DBUS_TIMEOUT, NULL,
1036                                 &err);
1037                 if (err != NULL) {
1038                         BT_ERR("CreateDevice Failed: %s", err->message);
1039                         g_clear_error(&err);
1040                 }
1041                 if (ret)
1042                         g_variant_unref(ret);
1043
1044                 g_object_unref(adapter_proxy);
1045
1046                 object_path = _bt_get_device_object_path(address);
1047                 if (object_path == NULL)
1048                         return BLUETOOTH_ERROR_INTERNAL;
1049         }
1050         proxy = __bt_gdbus_get_device_proxy(object_path);
1051         g_free(object_path);
1052         g_dbus_proxy_call_sync(proxy, "CancelDiscovery",
1053                 NULL,
1054                 G_DBUS_CALL_FLAGS_NONE,
1055                 DBUS_TIMEOUT, NULL,
1056                 &err);
1057         if (err) {
1058                 BT_ERR("DBus Error message: [%s]", err->message);
1059                 g_clear_error(&err);
1060                 return BLUETOOTH_ERROR_INTERNAL;
1061         }
1062         if (proxy)
1063                 g_object_unref(proxy);
1064         return BLUETOOTH_ERROR_NONE;
1065 }
1066
1067 int _bt_discover_service_uuids(char *address, char *remote_uuid)
1068 {
1069         char *object_path;
1070         GDBusProxy *proxy;
1071         GDBusConnection *gconn;
1072         GError *err = NULL;
1073         char **uuid_value = NULL;
1074         gsize size = 0;
1075         int i =0;
1076         GVariant *value = NULL;
1077         GVariant *ret = NULL;
1078         int result = BLUETOOTH_ERROR_INTERNAL;
1079         BT_INFO("+");
1080         retv_if(remote_uuid == NULL, BLUETOOTH_ERROR_INTERNAL);
1081         gconn = __get_gdbus_connection();
1082         retv_if(gconn == NULL, BLUETOOTH_ERROR_INTERNAL);
1083         object_path = _bt_get_device_object_path(address);
1084         retv_if(object_path == NULL, BLUETOOTH_ERROR_INTERNAL);
1085
1086         proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE, NULL,
1087                                 BT_BLUEZ_NAME, object_path, BT_PROPERTIES_INTERFACE, NULL,
1088                                 &err);
1089         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1090         if (err) {
1091                 BT_ERR("DBus Error: [%s]", err->message);
1092                 g_clear_error(&err);
1093         }
1094         ret = g_dbus_proxy_call_sync(proxy, "GetAll",
1095                         g_variant_new("(s)", BT_DEVICE_INTERFACE),
1096                         G_DBUS_CALL_FLAGS_NONE,
1097                         DBUS_TIMEOUT, NULL,
1098                         &err);
1099         if (err) {
1100                 result = BLUETOOTH_ERROR_INTERNAL;
1101                 BT_ERR("DBus Error : %s", err->message);
1102                 g_clear_error(&err);
1103                 goto done;
1104         }
1105         if (ret == NULL) {
1106                 BT_ERR("g_dbus_proxy_call_sync function return NULL");
1107                 result = BLUETOOTH_ERROR_INTERNAL;
1108                 goto done;
1109         }
1110
1111         g_variant_get(ret, "(@a{sv})", &value);
1112         g_variant_unref(ret);
1113         if (value) {
1114                 GVariant *temp_value = g_variant_lookup_value(value, "UUIDs",
1115                         G_VARIANT_TYPE_STRING_ARRAY);
1116
1117                 if (temp_value) {
1118                         size = g_variant_get_size(temp_value);
1119                         if (size > 0) {
1120                                 uuid_value = (char **)g_variant_get_strv(temp_value, &size);
1121                                 BT_DBG("Size items %d", size);
1122
1123                                 if (uuid_value) {
1124                                         for (i = 0; uuid_value[i] != NULL; i++) {
1125                                                 BT_DBG("Remote uuids %s", uuid_value[i]);
1126                                                 if (strcasecmp(uuid_value[i], remote_uuid) == 0) {
1127                                                         result = BLUETOOTH_ERROR_NONE;
1128                                                         g_variant_unref(temp_value);
1129                                                         goto done;
1130                                                 }
1131                                         }
1132                                 }
1133                         }
1134                         g_variant_unref(temp_value);
1135                 }
1136         }
1137 done:
1138         if (proxy)
1139                 g_object_unref(proxy);
1140         if (value)
1141                 g_variant_unref(value);
1142         if (uuid_value)
1143                 g_free(uuid_value);
1144
1145         BT_DBG("-");
1146         return result;
1147 }
1148
1149 int _bt_get_cod_by_address(char *address, bluetooth_device_class_t *dev_class)
1150 {
1151         char *object_path;
1152         GDBusProxy *proxy;
1153         GDBusConnection *gconn;
1154         GError *err = NULL;
1155         GVariant *value = NULL;
1156         GVariant *result = NULL;
1157         unsigned int  class = 0x00;
1158         int ret = BLUETOOTH_ERROR_INTERNAL;
1159
1160         gconn = __get_gdbus_connection();
1161         retv_if(gconn == NULL, BLUETOOTH_ERROR_INTERNAL);
1162                 object_path = _bt_get_device_object_path(address);
1163
1164         retv_if(object_path == NULL, BLUETOOTH_ERROR_INTERNAL);
1165
1166         proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE, NULL,
1167                                 BT_BLUEZ_NAME, object_path, BT_PROPERTIES_INTERFACE, NULL,
1168                                 &err);
1169         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1170         if (err) {
1171                 BT_ERR("DBus Error: [%s]", err->message);
1172                 g_clear_error(&err);
1173         }
1174
1175         result = g_dbus_proxy_call_sync(proxy, "GetAll",
1176                         g_variant_new("(s)", BT_DEVICE_INTERFACE),
1177                         G_DBUS_CALL_FLAGS_NONE,
1178                         DBUS_TIMEOUT, NULL,
1179                         &err);
1180         if (err) {
1181                 ret = BLUETOOTH_ERROR_INTERNAL;
1182                 BT_ERR("DBus Error : %s", err->message);
1183                 g_clear_error(&err);
1184                 goto done;
1185         }
1186         if (result == NULL) {
1187                 BT_ERR("g_dbus_proxy_call_sync function return NULL");
1188                 ret = BLUETOOTH_ERROR_INTERNAL;
1189                 goto done;
1190         }
1191         g_variant_get(result, "(@a{sv})", &value);
1192         g_variant_unref(result);
1193         if (value) {
1194                 GVariant *temp_value = g_variant_lookup_value(value, "Class",
1195                         G_VARIANT_TYPE_UINT32);
1196                 class = g_variant_get_uint32(temp_value);
1197                 _bt_divide_device_class(dev_class, class);
1198                 if (temp_value)
1199                         g_variant_unref(temp_value);
1200         }
1201
1202 done:
1203         if (proxy)
1204                 g_object_unref(proxy);
1205         if (value)
1206                 g_variant_unref(value);
1207
1208         BT_DBG("-");
1209         return ret;
1210 }
1211
1212 int _bt_disconnect_profile(char *address, char *uuid, void *cb,
1213                                                         gpointer func_data)
1214 {
1215         GDBusProxy *proxy;
1216         char *object_path;
1217         GError *err = NULL;
1218         GDBusProxy *adapter_proxy;
1219         object_path = _bt_get_device_object_path(address);
1220         if (object_path == NULL) {
1221                 GVariant *ret = NULL;
1222                 BT_ERR("No searched device");
1223                 adapter_proxy = __bt_gdbus_get_adapter_proxy();
1224                 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1225                 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
1226                                 g_variant_new("(s)", address),
1227                                 G_DBUS_CALL_FLAGS_NONE,
1228                                 DBUS_TIMEOUT, NULL,
1229                                 &err);
1230                 if (err != NULL) {
1231                         BT_ERR("CreateDevice Failed: %s", err->message);
1232                         g_error_free(err);
1233                 }
1234                 if (ret)
1235                         g_variant_unref(ret);
1236                 g_object_unref(adapter_proxy);
1237                 object_path = _bt_get_device_object_path(address);
1238                 if (object_path == NULL)
1239                         return BLUETOOTH_ERROR_INTERNAL;
1240         }
1241         proxy = __bt_gdbus_get_device_proxy(object_path);
1242         g_free(object_path);
1243         if (proxy == NULL) {
1244                 BT_ERR("Error while getting proxy");
1245                 return BLUETOOTH_ERROR_INTERNAL;
1246         }
1247         g_dbus_proxy_call(proxy, "DisconnectProfile",
1248                         g_variant_new("(s)", uuid),
1249                         G_DBUS_CALL_FLAGS_NONE,
1250                         DBUS_TIMEOUT, NULL,
1251                         (GAsyncReadyCallback)cb,
1252                         func_data);
1253         BT_DBG("-");
1254         return BLUETOOTH_ERROR_NONE;
1255 }
1256
1257 int _bt_get_adapter_path(GDBusConnection *conn, char *path)
1258 {
1259         GError *err = NULL;
1260         GDBusProxy *manager_proxy = NULL;
1261         GVariant *result = NULL;
1262         char *adapter_path = NULL;
1263
1264         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1265
1266         manager_proxy =  g_dbus_proxy_new_sync(conn,
1267                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1268                         BT_BLUEZ_NAME,
1269                         BT_MANAGER_PATH,
1270                         BT_MANAGER_INTERFACE,
1271                         NULL, &err);
1272
1273         if (!manager_proxy) {
1274                 BT_ERR("Unable to create proxy: %s", err->message);
1275                 goto fail;
1276         }
1277
1278         result = g_dbus_proxy_call_sync(manager_proxy, "DefaultAdapter", NULL,
1279                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1280         if (!result) {
1281                 if (err != NULL)
1282                         BT_ERR("Fail to get DefaultAdapter (Error: %s)", err->message);
1283                 else
1284                         BT_ERR("Fail to get DefaultAdapter");
1285
1286                 goto fail;
1287         }
1288
1289         if (g_strcmp0(g_variant_get_type_string(result), "(o)")) {
1290                 BT_ERR("Incorrect result\n");
1291                 goto fail;
1292         }
1293
1294         g_variant_get(result, "(&o)", &adapter_path);
1295
1296         if (adapter_path == NULL ||
1297                 strlen(adapter_path) >= BT_ADAPTER_OBJECT_PATH_MAX) {
1298                 BT_ERR("Adapter path is inproper\n");
1299                 goto fail;
1300         }
1301
1302         if (path)
1303                 g_strlcpy(path, adapter_path, BT_ADAPTER_OBJECT_PATH_MAX);
1304
1305         g_variant_unref(result);
1306         g_object_unref(manager_proxy);
1307
1308         return BLUETOOTH_ERROR_NONE;
1309
1310 fail:
1311         g_clear_error(&err);
1312
1313         if (result)
1314                 g_variant_unref(result);
1315
1316         if (manager_proxy)
1317                 g_object_unref(manager_proxy);
1318
1319         return BLUETOOTH_ERROR_INTERNAL;
1320
1321 }
1322
1323 void _bt_convert_device_path_to_address(const char *device_path,
1324                                                 char *device_address)
1325 {
1326         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1327         char *dev_addr;
1328
1329         ret_if(device_path == NULL);
1330         ret_if(device_address == NULL);
1331
1332         dev_addr = strstr(device_path, "dev_");
1333         if (dev_addr != NULL) {
1334                 char *pos = NULL;
1335                 dev_addr += 4;
1336                 g_strlcpy(address, dev_addr, sizeof(address));
1337
1338                 while ((pos = strchr(address, '_')) != NULL) {
1339                         *pos = ':';
1340                 }
1341
1342                 g_strlcpy(device_address, address, BT_ADDRESS_STRING_SIZE);
1343         }
1344 }
1345
1346 static char *__bt_extract_device_path(GVariantIter *iter, char *address)
1347 {
1348         char *object_path = NULL;
1349         char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
1350         /* Parse the signature:  oa{sa{sv}}} */
1351         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
1352                         NULL)) {
1353                 retv_if(object_path == NULL, NULL);
1354                 _bt_convert_device_path_to_address(object_path, device_address);
1355
1356                 if (g_strcmp0(address, device_address) == 0) {
1357                         return g_strdup(object_path);
1358                 }
1359         }
1360         return NULL;
1361 }
1362
1363 char *_bt_get_device_object_path(char *address)
1364 {
1365         GError *err = NULL;
1366         GDBusProxy *proxy = NULL;
1367         GVariant *result = NULL;
1368         GVariantIter *iter = NULL;
1369         GDBusConnection *conn = NULL;
1370         char *object_path = NULL;
1371
1372         conn = _bt_gdbus_get_system_gconn();
1373         retv_if(conn == NULL, NULL);
1374
1375         proxy =  g_dbus_proxy_new_sync(conn,
1376                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1377                         BT_BLUEZ_NAME,
1378                         BT_MANAGER_PATH,
1379                         BT_MANAGER_INTERFACE,
1380                         NULL, &err);
1381
1382         if (!proxy) {
1383                 BT_ERR("Unable to create proxy: %s", err->message);
1384                 goto fail;
1385         }
1386
1387         result = g_dbus_proxy_call_sync(proxy, "GetManagedObjects", NULL,
1388                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1389         if (!result) {
1390                 if (err != NULL)
1391                         BT_ERR("Fail to get GetManagedObjects (Error: %s)", err->message);
1392                 else
1393                         BT_ERR("Fail to get GetManagedObjects");
1394
1395                 goto fail;
1396         }
1397
1398         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
1399         object_path = __bt_extract_device_path(iter, address);
1400
1401         g_variant_unref(result);
1402         g_object_unref(proxy);
1403         g_variant_iter_free(iter);
1404         return object_path;
1405
1406 fail:
1407         g_clear_error(&err);
1408
1409         if (proxy)
1410                 g_object_unref(proxy);
1411
1412         return object_path;
1413 }
1414
1415 void _bt_device_path_to_address(const char *device_path, char *device_address)
1416 {
1417         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1418         char *dev_addr = NULL;
1419
1420         if (!device_path || !device_address)
1421                 return;
1422
1423         dev_addr = strstr(device_path, "dev_");
1424         if (dev_addr != NULL) {
1425                 char *pos = NULL;
1426                 dev_addr += 4;
1427                 g_strlcpy(address, dev_addr, sizeof(address));
1428
1429                 while ((pos = strchr(address, '_')) != NULL) {
1430                         *pos = ':';
1431                 }
1432
1433                 g_strlcpy(device_address, address, BT_ADDRESS_STRING_SIZE);
1434         }
1435 }
1436
1437 /* TODO : replace the dbus-glib APIs to gdbus APIs */
1438 DBusConnection *__bt_init_system_conn(void)
1439 {
1440         if (system_conn == NULL)
1441                 system_conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, NULL);
1442
1443         if (system_conn) {
1444                 dbus_connection_setup_with_g_main(system_conn, NULL);
1445                 dbus_connection_set_exit_on_disconnect(system_conn, FALSE);
1446         }
1447
1448         return system_conn;
1449 }
1450
1451 DBusConnection *_bt_get_system_conn(void)
1452 {
1453         DBusConnection *conn = NULL;
1454
1455         if (system_conn == NULL) {
1456                 conn = __bt_init_system_conn();
1457         } else {
1458                 conn = system_conn;
1459         }
1460
1461         return conn;
1462 }
1463
1464
1465 int _bt_register_osp_server_in_agent(int type, char *uuid, char *path, int fd)
1466 {
1467         int ret;
1468         char uuid_str[BLUETOOTH_UUID_STRING_MAX] = { 0, };
1469         char path_str[BLUETOOTH_PATH_STRING] = { 0, };
1470
1471         BT_DBG("+");
1472         BT_INIT_PARAMS();
1473         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1474
1475         g_array_append_vals(in_param1, &type, sizeof(int));
1476         g_strlcpy(uuid_str, uuid, sizeof(uuid_str));
1477         g_array_append_vals(in_param2, &uuid_str, BLUETOOTH_UUID_STRING_MAX);
1478         g_strlcpy(path_str, path, sizeof(path_str));
1479         g_array_append_vals(in_param3, &path_str, BLUETOOTH_PATH_STRING);
1480         g_array_append_vals(in_param4, &fd, sizeof(int));
1481
1482         ret =  _bt_send_request(BT_AGENT_SERVICE, BT_SET_AUTHORIZATION,
1483                 in_param1, in_param2, in_param3, in_param4, &out_param);
1484
1485         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1486         BT_DBG("-");
1487         return ret;
1488 }
1489
1490 int _bt_unregister_osp_server_in_agent(int type, char *uuid)
1491 {
1492         int ret;
1493         char uuid_str[BLUETOOTH_UUID_STRING_MAX] = { 0, };
1494
1495         BT_DBG("+");
1496         BT_INIT_PARAMS();
1497         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1498
1499         g_array_append_vals(in_param1, &type, sizeof(int));
1500         g_strlcpy(uuid_str, uuid, sizeof(uuid_str));
1501         g_array_append_vals(in_param2, &uuid_str, BLUETOOTH_UUID_STRING_MAX);
1502
1503         ret =  _bt_send_request(BT_AGENT_SERVICE, BT_UNSET_AUTHORIZATION,
1504                 in_param1, in_param2, in_param3, in_param4, &out_param);
1505
1506         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1507         BT_DBG("-");
1508         return ret;
1509 }
1510
1511 int _bt_check_privilege(int service_type, int service_function)
1512 {
1513         int result;
1514
1515         BT_INIT_PARAMS();
1516         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1517
1518         result = _bt_send_request(service_type, service_function,
1519                 in_param1, in_param2, in_param3, in_param4, &out_param);
1520
1521         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1522
1523         return result;
1524 }
1525
1526 GVariant *_bt_get_managed_objects(void)
1527 {
1528         GDBusConnection *g_conn;
1529         GDBusProxy *manager_proxy = NULL;
1530         GVariant *result = NULL;
1531         GError *error = NULL;
1532
1533         BT_DBG("+");
1534
1535         g_conn = _bt_gdbus_get_system_gconn();
1536         retv_if(g_conn == NULL, NULL);
1537
1538         manager_proxy = g_dbus_proxy_new_sync(g_conn,
1539                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1540                         BT_BLUEZ_NAME,
1541                         BT_MANAGER_PATH,
1542                         BT_MANAGER_INTERFACE,
1543                         NULL, &error);
1544
1545         if (error) {
1546                 BT_ERR("Unable to create proxy: %s", error->message);
1547                 g_clear_error(&error);
1548                 return NULL;
1549         }
1550
1551         result = g_dbus_proxy_call_sync (manager_proxy,
1552                         "GetManagedObjects", NULL,
1553                         G_DBUS_CALL_FLAGS_NONE, -1,
1554                         NULL, &error);
1555
1556         if (error) {
1557                 BT_ERR("Fail to get ManagedObjects (Error: %s)", error->message);
1558                 g_clear_error(&error);
1559         }
1560
1561         g_object_unref(manager_proxy);
1562
1563         BT_DBG("-");
1564         return result;
1565 }
1566
1567 BT_EXPORT_API int bluetooth_is_supported(void)
1568 {
1569         int is_supported = 0;
1570         int len = 0;
1571         int fd = -1;
1572         rfkill_event event;
1573
1574         fd = open(RFKILL_NODE, O_RDONLY);
1575         if (fd < 0) {
1576                 BT_ERR("Fail to open RFKILL node");
1577                 return BLUETOOTH_ERROR_INTERNAL;
1578         }
1579
1580         if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
1581                 BT_ERR("Fail to set RFKILL node to non-blocking");
1582                 close(fd);
1583                 return BLUETOOTH_ERROR_INTERNAL;
1584         }
1585
1586         while (1) {
1587                 len = read(fd, &event, sizeof(event));
1588                 if (len < 0) {
1589                         BT_ERR("Fail to read events");
1590                         break;
1591                 }
1592
1593                 if (len != RFKILL_EVENT_SIZE) {
1594                         BT_ERR("The size is wrong\n");
1595                         continue;
1596                 }
1597
1598                 if (event.type == RFKILL_TYPE_BLUETOOTH) {
1599                         is_supported = 1;
1600                         break;
1601                 }
1602         }
1603
1604         close(fd);
1605
1606         BT_DBG("supported: %d", is_supported);
1607
1608         return is_supported;
1609 }
1610
1611 BT_EXPORT_API int bluetooth_register_callback(bluetooth_cb_func_ptr callback_ptr, void *user_data)
1612 {
1613         int ret;
1614
1615         _bt_gdbus_init_system_gconn();
1616         __bt_init_system_conn();
1617
1618         ret = _bt_init_event_handler();
1619         if (ret != BLUETOOTH_ERROR_NONE &&
1620              ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
1621                 BT_ERR("Fail to init the event handler");
1622                 return ret;
1623         }
1624
1625
1626         _bt_set_user_data(BT_COMMON, (void *)callback_ptr, user_data);
1627
1628         /* Register All events */
1629         ret = _bt_register_event(BT_ADAPTER_EVENT, (void *)callback_ptr, user_data);
1630         if (ret != BLUETOOTH_ERROR_NONE)
1631                 goto fail;
1632         ret = _bt_register_event(BT_DEVICE_EVENT, (void *)callback_ptr, user_data);
1633         if (ret != BLUETOOTH_ERROR_NONE)
1634                 goto fail;
1635         ret = _bt_register_event(BT_NETWORK_EVENT, (void *)callback_ptr, user_data);
1636         if (ret != BLUETOOTH_ERROR_NONE)
1637                 goto fail;
1638         ret = _bt_register_event(BT_RFCOMM_CLIENT_EVENT, (void *)callback_ptr, user_data);
1639         if (ret != BLUETOOTH_ERROR_NONE)
1640                 goto fail;
1641         ret = _bt_register_event(BT_RFCOMM_SERVER_EVENT, (void *)callback_ptr, user_data);
1642         if (ret != BLUETOOTH_ERROR_NONE)
1643                 goto fail;
1644 #ifdef GATT_NO_RELAY
1645         ret = _bt_register_event(BT_GATT_BLUEZ_EVENT, (void *)callback_ptr, user_data);
1646         if (ret != BLUETOOTH_ERROR_NONE)
1647                 goto fail;
1648 #endif
1649
1650         _bt_register_name_owner_changed();
1651
1652         return BLUETOOTH_ERROR_NONE;
1653 fail:
1654         BT_ERR("Fail to do _bt_register_event()");
1655         bluetooth_unregister_callback();
1656         return ret;
1657 }
1658
1659 BT_EXPORT_API int bluetooth_unregister_callback(void)
1660 {
1661         int ret;
1662
1663
1664         ret = _bt_deinit_event_handler();
1665         if (ret != BLUETOOTH_ERROR_NONE) {
1666                 BT_ERR("Fail to deinit the event handler");
1667         }
1668
1669         _bt_unregister_name_owner_changed();
1670
1671         _bt_set_user_data(BT_COMMON, NULL, NULL);
1672
1673         if (system_conn) {
1674                 dbus_connection_flush(system_conn);
1675                 dbus_connection_close(system_conn);
1676                 dbus_connection_unref(system_conn);
1677                 system_conn = NULL;
1678         }
1679         if (system_gconn) {
1680                 g_object_unref(system_gconn);
1681                 system_gconn = NULL;
1682         }
1683         _bt_gdbus_deinit_proxys();
1684         return BLUETOOTH_ERROR_NONE;
1685 }
1686