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