Rollback changes to submit TIZEN:COMMON project
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-device.c
1 /*
2  * bluetooth-frwk
3  *
4  * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *              http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <dbus/dbus-glib.h>
21 #include <dbus/dbus.h>
22 #include <glib.h>
23 #include <dlog.h>
24 #include <string.h>
25 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
26 #include <syspopup_caller.h>
27 #endif
28
29 #include "bluetooth-api.h"
30 #include "bt-internal-types.h"
31
32 #include "bt-service-common.h"
33 #include "bt-service-event.h"
34 #include "bt-service-device.h"
35 #include "bt-service-rfcomm-client.h"
36 #include "bt-service-util.h"
37 #include "bt-service-agent.h"
38
39 typedef struct {
40         int req_id;
41         char *addr;
42         gboolean is_autopair;
43         DBusGProxy *device_proxy;
44         DBusGProxy *adapter_proxy;
45 } bt_funcion_data_t;
46
47 gboolean is_deivce_creating;
48 bt_funcion_data_t *bonding_info;
49 bt_funcion_data_t *searching_info;
50
51 /* This HID Mouse does not support pairing precedure. need to skip it. */
52 #define SMB_MOUSE_LAP_ADDR "00:12:A1"
53
54 static void __bt_bond_device_cb(DBusGProxy *proxy, DBusGProxyCall *call,
55                                                      gpointer user_data);
56
57
58 gboolean _bt_is_device_creating(void)
59 {
60         return is_deivce_creating;
61 }
62
63 void _bt_set_autopair_status_in_bonding_info(gboolean is_autopair)
64 {
65         ret_if(bonding_info == NULL);
66         bonding_info->is_autopair = is_autopair;
67 }
68
69 void _bt_device_path_to_address(const char *device_path,
70                                         char *device_address)
71 {
72         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
73         char *dev_addr;
74         char *pos;
75
76         ret_if(device_path == NULL);
77         ret_if(device_address == NULL);
78
79         dev_addr = strstr(device_path, "dev_");
80         ret_if(dev_addr == NULL);
81
82         dev_addr += 4;
83         g_strlcpy(address, dev_addr, sizeof(address));
84
85         while ((pos = strchr(address, '_')) != NULL) {
86                 *pos = ':';
87         }
88
89         g_strlcpy(device_address, address, BT_ADDRESS_STRING_SIZE);
90 }
91
92 void __bt_cancel_search_service_done(void)
93 {
94         int result = BLUETOOTH_ERROR_CANCEL_BY_USER;
95         request_info_t *req_info;
96         bluetooth_device_info_t dev_info;
97         GArray *out_param1;
98         GArray *out_param2;
99
100         ret_if(searching_info == NULL);
101
102         req_info = _bt_get_request_info(searching_info->req_id);
103         if (req_info == NULL) {
104                 BT_ERR("req_info == NULL");
105                 goto done;
106         }
107
108         if (req_info->context == NULL)
109                 goto done;
110
111         out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
112         out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
113
114         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
115         _bt_convert_addr_string_to_type(dev_info.device_address.addr,
116                                         searching_info->addr);
117
118         g_array_append_vals(out_param1, &dev_info,
119                                 sizeof(bluetooth_device_info_t));
120         g_array_append_vals(out_param2, &result, sizeof(int));
121
122         dbus_g_method_return(req_info->context, out_param1, out_param2);
123
124         g_array_free(out_param1, TRUE);
125         g_array_free(out_param2, TRUE);
126
127         _bt_delete_request_list(req_info->req_id);
128
129 done:
130         if (searching_info->device_proxy)
131                 g_object_unref(searching_info->device_proxy);
132
133         if (searching_info->adapter_proxy)
134                 g_object_unref(searching_info->adapter_proxy);
135
136         g_free(searching_info->addr);
137         g_free(searching_info);
138         searching_info = NULL;
139 }
140
141 static void __bt_get_uuids(GValue *value, bt_remote_dev_info_t *info)
142 {
143         int i = 0;
144         char **uuid_value;
145
146         ret_if(value == NULL);
147         ret_if(info == NULL);
148
149         info->uuid_count = 0;
150
151         uuid_value = g_value_get_boxed(value);
152         ret_if(uuid_value == NULL);
153
154         while (uuid_value[i]) {
155                 i++;
156         }
157         ret_if(i == 0);
158
159         info->uuid_count = i;
160
161         info->uuids = g_new0(char *, info->uuid_count + 1);
162
163         for (i = 0; uuid_value[i] != NULL; i++) {
164                 info->uuids[i] = g_strdup(uuid_value[i]);
165         }
166 }
167
168 bt_remote_dev_info_t *_bt_get_remote_device_info(char *address)
169 {
170         bt_remote_dev_info_t *dev_info;
171         char *object_path = NULL;
172         DBusGProxy *adapter_proxy;
173         DBusGProxy *device_proxy;
174         GHashTable *hash = NULL;
175         GValue *value;
176         const gchar *name;
177         DBusGConnection *conn;
178
179         retv_if(address == NULL, NULL);
180
181         adapter_proxy = _bt_get_adapter_proxy();
182         retv_if(adapter_proxy == NULL, NULL);
183
184         object_path = _bt_get_device_object_path(address);
185
186         retv_if(object_path == NULL, NULL);
187
188         conn = _bt_get_system_gconn();
189         if (conn == NULL) {
190                 BT_ERR("conn == NULL");
191                 g_free(object_path);
192                 return NULL;
193         }
194
195         device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
196                                 object_path, BT_PROPERTIES_INTERFACE);
197         g_free(object_path);
198         retv_if(device_proxy == NULL, NULL);
199
200         dbus_g_proxy_call(device_proxy, "GetAll", NULL,
201                                 G_TYPE_STRING, BT_DEVICE_INTERFACE,
202                                 G_TYPE_INVALID,
203                                 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
204                                 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
205
206         g_object_unref(device_proxy);
207
208         dev_info = g_malloc0(sizeof(bt_remote_dev_info_t));
209
210         if (hash != NULL) {
211                 value = g_hash_table_lookup(hash, "Alias");
212                 name = value ? g_value_get_string(value) : NULL;
213
214                 if (name != NULL)
215                         BT_DBG("Alias Name [%s]", name);
216                 else {
217                         value = g_hash_table_lookup(hash, "Name");
218                         name = value ? g_value_get_string(value) : NULL;
219                 }
220
221                 value = g_hash_table_lookup(hash, "Class");
222                 dev_info->class = value ? g_value_get_uint(value) : 0;
223
224                 value = g_hash_table_lookup(hash, "Connected");
225                 dev_info->connected = value ? g_value_get_boolean(value) : FALSE;
226
227                 value = g_hash_table_lookup(hash, "Trusted");
228                 dev_info->trust = value ? g_value_get_boolean(value) : FALSE;
229
230                 value = g_hash_table_lookup(hash, "RSSI");
231                 dev_info->rssi = value ? g_value_get_int(value) : 0;
232
233                 value = g_hash_table_lookup(hash, "UUIDs");
234                 __bt_get_uuids(value, dev_info);
235
236                 dev_info->address = g_strdup(address);
237                 dev_info->name = g_strdup(name);
238
239                 value = g_hash_table_lookup(hash, "Paired");
240                 dev_info->paired = value ? g_value_get_boolean(value) : FALSE;
241
242                 g_hash_table_destroy(hash);
243         } else {
244                 BT_ERR("Hash is NULL\n");
245                 g_free(dev_info);
246                 dev_info = NULL;
247         }
248
249         return dev_info;
250 }
251
252 static gboolean __ignore_auto_pairing_request(const char *address)
253 {
254         gchar *buffer;
255         char **lines;
256         int i;
257         char lap_address[BT_LOWER_ADDRESS_LENGTH + 1] = {0,};
258         char *temp_buffer;
259         FILE *fp;
260         long size;
261         size_t result;
262
263         BT_DBG("+\n");
264
265         if (address == NULL)
266                 return FALSE;
267
268         /* Get the LAP(Lower Address part) */
269         /* User BT_LOWER_ADDRESS_LENGTH+1 for lap_address to accomodate
270              a "," */
271         snprintf(lap_address, sizeof(lap_address), ",%s", address);
272
273         fp = fopen(BT_AGENT_AUTO_PAIR_BLACKLIST_FILE, "r");
274
275         if (fp == NULL) {
276                 BT_DBG("fopen failed \n");
277                 return FALSE;
278         }
279
280         fseek(fp, 0, SEEK_END);
281         size = ftell(fp);
282         rewind(fp);
283
284         if (size < 0) {
285                 BT_DBG("Get file size failed \n");
286                 fclose(fp);
287                 return FALSE;
288         }
289
290         buffer = g_malloc0(sizeof(char) * size);
291         result = fread((char *)buffer, 1, size, fp);
292         fclose(fp);
293         if (result != size) {
294                 BT_DBG("Read Error\n");
295                 g_free(buffer);
296                 return FALSE;
297         }
298
299         BT_DBG("Buffer = %s\n", buffer);
300
301         lines = g_strsplit_set(buffer, BT_AGENT_NEW_LINE, 0);
302         g_free(buffer);
303
304         if (lines == NULL)
305                 return FALSE;
306
307         /* Write the data and insert new device data */
308         for (i = 0; lines[i] != NULL; i++) {
309                 if (g_str_has_prefix(lines[i], "AddressBlacklist")) {
310                         temp_buffer = g_strconcat(lines[i], lap_address, NULL);
311                         g_free(lines[i]);
312                         lines[i] = temp_buffer;
313                 }
314         }
315         buffer = g_strjoinv(BT_AGENT_NEW_LINE, lines);
316         g_strfreev(lines);
317
318         fp = fopen(BT_AGENT_AUTO_PAIR_BLACKLIST_FILE, "w");
319
320         if (fp == NULL) {
321                 BT_DBG("fopen failed \n");
322                 g_free(buffer);
323                 return FALSE;
324         }
325
326         BT_DBG("Buffer = %s\n", buffer);
327         fwrite(buffer, 1, strlen(buffer), fp);
328         fclose(fp);
329
330         g_free(buffer);
331
332         BT_DBG("-\n");
333
334         return FALSE;
335 }
336
337 static int __bt_retry_bond(void)
338 {
339         DBusGProxy *device_proxy;
340         char *device_path;
341         DBusGConnection *conn;
342
343         BT_CHECK_PARAMETER(bonding_info, return);
344         BT_CHECK_PARAMETER(bonding_info->addr, return);
345
346         conn = _bt_get_system_gconn();
347         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
348
349         device_path = _bt_get_device_object_path(bonding_info->addr);
350
351         if (device_path == NULL) {
352                 BT_ERR("No searched device");
353                 return BLUETOOTH_ERROR_NOT_PAIRED;
354         }
355
356         if (bonding_info->device_proxy) {
357                 device_proxy = bonding_info->device_proxy;
358         } else  {
359                 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
360                                 device_path, BT_DEVICE_INTERFACE);
361         }
362
363         g_free(device_path);
364         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
365
366         is_deivce_creating = TRUE;
367         bonding_info->device_proxy = device_proxy;
368
369         if (!dbus_g_proxy_begin_call_with_timeout(device_proxy, "Pair",
370                                 (DBusGProxyCallNotify) __bt_bond_device_cb,
371                                 NULL, NULL, BT_MAX_DBUS_TIMEOUT,
372                                 G_TYPE_INVALID,
373                                 G_TYPE_INVALID)) {
374                 BT_ERR("Pair call fail");
375                 is_deivce_creating = FALSE;
376                 g_object_unref(device_proxy);
377                 return BLUETOOTH_ERROR_INTERNAL;
378         }
379
380         return BLUETOOTH_ERROR_NONE;
381 }
382
383
384 static int __bt_remove_and_bond(void)
385 {
386         DBusGProxy *adapter_proxy;
387         GError *err = NULL;
388         char *device_path = NULL;
389
390         BT_CHECK_PARAMETER(bonding_info, return);
391         BT_CHECK_PARAMETER(bonding_info->addr, return);
392
393         adapter_proxy = _bt_get_adapter_proxy();
394         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
395
396         device_path = _bt_get_device_object_path(bonding_info->addr);
397
398         retv_if (device_path == NULL, BLUETOOTH_ERROR_INTERNAL);
399
400         dbus_g_proxy_call(adapter_proxy, "RemoveDevice",
401                           &err, DBUS_TYPE_G_OBJECT_PATH, device_path,
402                           G_TYPE_INVALID, G_TYPE_INVALID);
403         g_free(device_path);
404         if (err != NULL) {
405                 BT_ERR("RemoveDevice Fail: %s", err->message);
406                 g_error_free(err);
407                 return BLUETOOTH_ERROR_INTERNAL;
408         }
409
410         return __bt_retry_bond();
411 }
412
413 static int __bt_cancel_and_bond(void)
414 {
415         BT_CHECK_PARAMETER(bonding_info, return);
416         BT_CHECK_PARAMETER(bonding_info->device_proxy, return);
417
418         dbus_g_proxy_call_no_reply(bonding_info->device_proxy,
419                                 "CancelPairing",
420                                 G_TYPE_INVALID, G_TYPE_INVALID);
421
422         return __bt_retry_bond();
423 }
424
425
426 static void __bt_bond_device_cb(DBusGProxy *proxy, DBusGProxyCall *call,
427                                                      gpointer user_data)
428 {
429         int result = BLUETOOTH_ERROR_NONE;
430         GError *err = NULL;
431         GArray *out_param1;
432         GArray *out_param2;
433         request_info_t *req_info;
434         bluetooth_device_info_t dev_info;
435         bt_remote_dev_info_t *remote_dev_info;
436
437         /* Terminate ALL system popup */
438 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
439         syspopup_destroy_all();
440 #endif
441
442         dbus_g_proxy_end_call(proxy, call, &err, G_TYPE_INVALID);
443
444         g_object_unref(proxy);
445
446         is_deivce_creating = FALSE;
447
448         if (bonding_info == NULL) {
449                 /* Send reply */
450                 BT_ERR("bonding_info == NULL");
451                 if (err)
452                         g_error_free(err);
453                 return;
454         }
455
456         bonding_info->device_proxy = NULL;
457
458         req_info = _bt_get_request_info(bonding_info->req_id);
459         if (req_info == NULL) {
460                 BT_ERR("req_info == NULL");
461                 goto done;
462         }
463
464         if (err != NULL) {
465                 BT_ERR("Error occured in Pair [%s]", err->message);
466
467                 if (!strcmp(err->message, "Already Exists")) {
468                         BT_DBG("Existing Bond, remove and retry");
469                         ret_if(__bt_remove_and_bond() == BLUETOOTH_ERROR_NONE);
470
471                         result = BLUETOOTH_ERROR_PARING_FAILED;
472                 } else if (!strcmp(err->message, "Authentication Rejected")) {
473                         result = BLUETOOTH_ERROR_ACCESS_DENIED;
474 //              } else if (_bt_agent_is_canceled(bonding_info->agent) ||
475 //                      !strcmp(err->message, "Authentication Canceled")) {
476 //                      result = BLUETOOTH_ERROR_CANCEL_BY_USER;
477                 } else if (!strcmp(err->message, "In Progress")) {
478                         BT_DBG("Bond in progress, cancel and retry");
479                         ret_if(__bt_cancel_and_bond() == BLUETOOTH_ERROR_NONE);
480
481                         result = BLUETOOTH_ERROR_PARING_FAILED;
482                 } else if (!strcmp(err->message, "Authentication Failed")) {
483                         if (bonding_info->is_autopair == TRUE) {
484                                 _bt_set_autopair_status_in_bonding_info(FALSE);
485                                 __ignore_auto_pairing_request(bonding_info->addr);
486                         }
487                         result = BLUETOOTH_ERROR_AUTHENTICATION_FAILED;
488                 } else if (!strcmp(err->message, "Page Timeout")) {
489                         /* This is the special case
490                              As soon as call bluetooth_bond_device, try to cancel bonding.
491                              In this case, before completing to call 'CreatePairedDevice' method
492                              the procedure is stopped. So 'Cancle' error is not return.
493                         */
494                         result = BLUETOOTH_ERROR_HOST_DOWN;
495                 } else if (!strcmp(err->message, BT_TIMEOUT_MESSAGE)) {
496                         dbus_g_proxy_call(proxy, "CancelDeviceCreation", NULL,
497                                            G_TYPE_STRING, bonding_info->addr,
498                                            G_TYPE_INVALID, G_TYPE_INVALID);
499
500                         result = BLUETOOTH_ERROR_TIMEOUT;
501                 } else {
502                         result = BLUETOOTH_ERROR_PARING_FAILED;
503                 }
504         }
505
506         if (result != BLUETOOTH_ERROR_NONE)
507                 goto dbus_return;
508
509         remote_dev_info = _bt_get_remote_device_info(bonding_info->addr);
510
511         /* Send the event to application */
512         if (remote_dev_info != NULL) {
513                 _bt_send_event(BT_ADAPTER_EVENT,
514                         BLUETOOTH_EVENT_BONDING_FINISHED,
515                         DBUS_TYPE_INT32, &result,
516                         DBUS_TYPE_STRING, &bonding_info->addr,
517                         DBUS_TYPE_UINT32, &remote_dev_info->class,
518                         DBUS_TYPE_INT16, &remote_dev_info->rssi,
519                         DBUS_TYPE_STRING, &remote_dev_info->name,
520                         DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
521                         DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
522                         DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
523                         DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
524                         &remote_dev_info->uuids, remote_dev_info->uuid_count,
525                         DBUS_TYPE_INVALID);
526
527                 _bt_free_device_info(remote_dev_info);
528         }
529
530 dbus_return:
531         if (req_info->context == NULL)
532                 goto done;
533
534         out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
535         out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
536
537         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
538         _bt_convert_addr_string_to_type(dev_info.device_address.addr,
539                                         bonding_info->addr);
540
541         g_array_append_vals(out_param1, &dev_info,
542                                 sizeof(bluetooth_device_info_t));
543         g_array_append_vals(out_param2, &result, sizeof(int));
544
545         dbus_g_method_return(req_info->context, out_param1, out_param2);
546
547         g_array_free(out_param1, TRUE);
548         g_array_free(out_param2, TRUE);
549
550         _bt_delete_request_list(req_info->req_id);
551 done:
552         if (err)
553                 g_error_free(err);
554
555         g_free(bonding_info->addr);
556         g_free(bonding_info);
557         bonding_info = NULL;
558
559 }
560
561 int _bt_bond_device(int request_id,
562                 bluetooth_device_address_t *device_address,
563                 GArray **out_param1)
564 {
565         DBusGProxy *proxy;
566         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
567         bluetooth_device_info_t dev_info;
568         DBusGConnection *conn;
569         char *device_path = NULL;
570
571         BT_CHECK_PARAMETER(device_address, return);
572
573         if (bonding_info) {
574                 BT_ERR("Bonding in progress");
575                 return BLUETOOTH_ERROR_DEVICE_BUSY;
576         }
577
578         conn = _bt_get_system_gconn();
579         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
580
581         _bt_convert_addr_type_to_string(address, device_address->addr);
582
583         device_path = _bt_get_device_object_path(address);
584
585         if (device_path == NULL) {
586                 BT_ERR("No searched device");
587                 return BLUETOOTH_ERROR_NOT_PAIRED;
588         }
589
590         proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
591                                 device_path, BT_DEVICE_INTERFACE);
592
593         g_free(device_path);
594         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
595
596         bonding_info = g_malloc0(sizeof(bt_funcion_data_t));
597         bonding_info->addr = g_strdup(address);
598         bonding_info->req_id = request_id;
599         bonding_info->device_proxy = proxy;
600
601         is_deivce_creating = TRUE;
602
603         if (!dbus_g_proxy_begin_call_with_timeout(proxy, "Pair",
604                                 (DBusGProxyCallNotify) __bt_bond_device_cb,
605                                 NULL, NULL, BT_MAX_DBUS_TIMEOUT,
606                                 G_TYPE_INVALID,
607                                 G_TYPE_INVALID)) {
608                 BT_ERR("Pair call fail");
609                 g_object_unref(proxy);
610                 goto fail;
611         }
612
613
614 /* To Do: We need to check if we can pair the specific device using 'pair' API of bluez 5.x */
615 #if 0
616         if (!strncmp(address, SMB_MOUSE_LAP_ADDR, strlen(SMB_MOUSE_LAP_ADDR))) {
617                 bluetooth_device_address_t device_addr = { {0} };
618                 BT_ERR("This device don't support pairing. So skip pairing.");
619                 if (!dbus_g_proxy_begin_call(proxy, "CreateDevice",
620                                 (DBusGProxyCallNotify)__bt_bond_device_cb,
621                                 NULL, NULL,
622                                 G_TYPE_STRING, device_addr,
623                                 G_TYPE_INVALID)) {
624                         BT_ERR("CreateDevice failed");
625                         goto fail;
626                 }
627
628                 _bt_convert_addr_string_to_type(device_addr.addr, address);
629                 if (_bt_set_authorization(&device_addr, TRUE))
630                         BT_ERR("_bt_set_authorization failed [%s]", address);
631
632         } else {
633                 if (!dbus_g_proxy_begin_call_with_timeout(proxy, "CreatePairedDevice",
634                                         (DBusGProxyCallNotify) __bt_bond_device_cb,
635                                         NULL, NULL, BT_MAX_DBUS_TIMEOUT,
636                                         G_TYPE_STRING, address,
637                                         DBUS_TYPE_G_OBJECT_PATH, BT_DEVICE_AGENT_PATH,
638                                         G_TYPE_STRING, "DisplayYesNo",
639                                         G_TYPE_INVALID)) {
640                         BT_ERR("CreatePairedDevice call fail");
641                         goto fail;
642                 }
643         }
644 #endif
645
646         return BLUETOOTH_ERROR_NONE;
647 fail:
648         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
649         _bt_convert_addr_string_to_type(dev_info.device_address.addr,
650                                         bonding_info->addr);
651
652         g_array_append_vals(*out_param1, &dev_info,
653                                 sizeof(bluetooth_device_info_t));
654
655         is_deivce_creating = FALSE;
656
657         g_free(bonding_info->addr);
658         g_free(bonding_info);
659         bonding_info = NULL;
660
661         return BLUETOOTH_ERROR_INTERNAL;
662 }
663
664 int _bt_cancel_bonding(void)
665 {
666         retv_if(bonding_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
667         retv_if(bonding_info->device_proxy == NULL,
668                                 BLUETOOTH_ERROR_NOT_IN_OPERATION);
669
670         dbus_g_proxy_call_no_reply(bonding_info->device_proxy,
671                                 "CancelPairing",
672                                 G_TYPE_INVALID, G_TYPE_INVALID);
673
674         return BLUETOOTH_ERROR_NONE;
675 }
676
677 static void __bt_unbond_cb(DBusGProxy *proxy, DBusGProxyCall *call,
678                                 gpointer user_data)
679 {
680         GError *err = NULL;
681         GArray *out_param1;
682         GArray *out_param2;
683         int result = BLUETOOTH_ERROR_NONE;
684         bt_funcion_data_t *unbonding_info;
685         bluetooth_device_info_t dev_info;
686         request_info_t *req_info;
687
688         dbus_g_proxy_end_call(proxy, call, &err, G_TYPE_INVALID);
689
690         unbonding_info = user_data;
691
692         if (unbonding_info == NULL) {
693                 /* Send reply */
694                 BT_ERR("unbonding_info == NULL");
695                 goto done;
696         }
697
698         req_info = _bt_get_request_info(unbonding_info->req_id);
699         if (req_info == NULL) {
700                 BT_ERR("req_info == NULL");
701                 goto done;
702         }
703
704         if (err != NULL) {
705                 BT_ERR("Error occured in RemoveBonding [%s]\n", err->message);
706                 result = BLUETOOTH_ERROR_INTERNAL;
707                 goto dbus_return;
708         }
709
710 dbus_return:
711         if (req_info->context == NULL)
712                 goto done;
713
714         out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
715         out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
716
717         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
718         _bt_convert_addr_string_to_type(dev_info.device_address.addr,
719                                         unbonding_info->addr);
720
721         g_array_append_vals(out_param1, &dev_info,
722                                 sizeof(bluetooth_device_info_t));
723         g_array_append_vals(out_param2, &result, sizeof(int));
724
725         dbus_g_method_return(req_info->context, out_param1, out_param2);
726
727         _bt_delete_request_list(req_info->req_id);
728
729         g_array_free(out_param1, TRUE);
730         g_array_free(out_param2, TRUE);
731
732 done:
733         if (err)
734                 g_error_free(err);
735
736         if (unbonding_info) {
737                 g_free(unbonding_info->addr);
738                 g_free(unbonding_info);
739         }
740 }
741
742 int _bt_unbond_device(int request_id,
743                         bluetooth_device_address_t *device_address,
744                         GArray **out_param1)
745 {
746         char *device_path = NULL;
747         bt_funcion_data_t *unbonding_info;
748         DBusGProxy *adapter_proxy;
749         int result = BLUETOOTH_ERROR_INTERNAL;
750         bluetooth_device_info_t dev_info;
751
752         BT_CHECK_PARAMETER(device_address, return);
753
754         adapter_proxy = _bt_get_adapter_proxy();
755         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
756
757         /* allocate user data so that it can be retrieved in callback */
758         unbonding_info = g_malloc0(sizeof(bt_funcion_data_t));
759         unbonding_info->addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
760         unbonding_info->req_id = request_id;
761
762         _bt_convert_addr_type_to_string(unbonding_info->addr,
763                                         device_address->addr);
764
765         device_path = _bt_get_device_object_path(unbonding_info->addr);
766
767         if (device_path == NULL) {
768                 BT_ERR("No paired device");
769                 result = BLUETOOTH_ERROR_NOT_PAIRED;
770                 goto fail;
771         }
772
773         if (!dbus_g_proxy_begin_call(adapter_proxy, "RemoveDevice",
774                                 (DBusGProxyCallNotify) __bt_unbond_cb,
775                                 (gpointer)unbonding_info, NULL,
776                                 DBUS_TYPE_G_OBJECT_PATH, device_path,
777                                 G_TYPE_INVALID)) {
778                 BT_ERR("RemoveBonding begin failed\n");
779                 goto fail;
780         }
781         g_free(device_path);
782         return BLUETOOTH_ERROR_NONE;
783
784 fail:
785         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
786         _bt_convert_addr_string_to_type(dev_info.device_address.addr,
787                                         unbonding_info->addr);
788
789         g_array_append_vals(*out_param1, &dev_info,
790                                 sizeof(bluetooth_device_info_t));
791         g_free(device_path);
792         g_free(unbonding_info->addr);
793         g_free(unbonding_info);
794         return result;
795 }
796
797 static void __bt_discover_cb(DBusGProxy *proxy, DBusGProxyCall *call,
798                                 gpointer user_data)
799 {
800         GError *err = NULL;
801         GHashTable *hash = NULL;
802         GArray *out_param1;
803         GArray *out_param2;
804         GValue uuid_v = { 0 };
805         int result = BLUETOOTH_ERROR_NONE;
806         bluetooth_device_info_t dev_info;
807         bt_remote_dev_info_t *remote_dev_info;
808         request_info_t *req_info;
809
810         dbus_g_proxy_end_call(proxy, call, &err,
811                               G_TYPE_VALUE, &uuid_v,
812                               G_TYPE_INVALID);
813
814         g_object_unref(proxy);
815
816         if (searching_info == NULL) {
817                 /* Send reply */
818                 BT_ERR("searching_info == NULL");
819                 goto done;
820         }
821
822         req_info = _bt_get_request_info(searching_info->req_id);
823         if (req_info == NULL) {
824                 BT_ERR("req_info == NULL");
825                 goto done;
826         }
827
828         if (err != NULL) {
829                 BT_ERR("Error occured in Proxy call [%s]\n", err->message);
830
831                 if (!strcmp("Operation canceled", err->message)) {
832                         result = BLUETOOTH_ERROR_CANCEL_BY_USER;
833                 } else if (!strcmp("In Progress", err->message)) {
834                         result = BLUETOOTH_ERROR_IN_PROGRESS;
835                 } else if (!strcmp("Host is down", err->message)) {
836                         result = BLUETOOTH_ERROR_HOST_DOWN;
837                 } else {
838                         result = BLUETOOTH_ERROR_CONNECTION_ERROR;
839                 }
840
841                 if (result == BLUETOOTH_ERROR_HOST_DOWN ||
842                      result == BLUETOOTH_ERROR_CONNECTION_ERROR) {
843                         remote_dev_info = _bt_get_remote_device_info(searching_info->addr);
844                         if (remote_dev_info && remote_dev_info->uuids != NULL &&
845                              remote_dev_info->uuid_count > 0) {
846                                 result = BLUETOOTH_ERROR_NONE;
847                                 goto event;
848                         }
849                         _bt_free_device_info(remote_dev_info);
850                 }
851                 goto dbus_return;
852         }
853
854         remote_dev_info = _bt_get_remote_device_info(searching_info->addr);
855
856 event:
857         /* Send the event to application */
858         if (remote_dev_info != NULL) {
859                 _bt_send_event(BT_ADAPTER_EVENT,
860                         BLUETOOTH_EVENT_SERVICE_SEARCHED,
861                         DBUS_TYPE_INT32, &result,
862                         DBUS_TYPE_STRING, &searching_info->addr,
863                         DBUS_TYPE_UINT32, &remote_dev_info->class,
864                         DBUS_TYPE_INT16, &remote_dev_info->rssi,
865                         DBUS_TYPE_STRING, &remote_dev_info->name,
866                         DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
867                         DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
868                         DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
869                         DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
870                         &remote_dev_info->uuids, remote_dev_info->uuid_count,
871                         DBUS_TYPE_INVALID);
872
873                 _bt_free_device_info(remote_dev_info);
874         }
875
876 dbus_return:
877         if (req_info->context == NULL)
878                 goto done;
879
880         out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
881         out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
882
883         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
884         _bt_convert_addr_string_to_type(dev_info.device_address.addr,
885                                         searching_info->addr);
886
887         g_array_append_vals(out_param1, &dev_info,
888                                 sizeof(bluetooth_device_info_t));
889         g_array_append_vals(out_param2, &result, sizeof(int));
890
891         dbus_g_method_return(req_info->context, out_param1, out_param2);
892
893         g_array_free(out_param1, TRUE);
894         g_array_free(out_param2, TRUE);
895
896         _bt_delete_request_list(req_info->req_id);
897 done:
898         if (err)
899                 g_error_free(err);
900
901         g_hash_table_destroy(hash);
902
903         if (searching_info) {
904                 g_free(searching_info->addr);
905                 g_free(searching_info);
906                 searching_info = NULL;
907         }
908 }
909
910 static void __bt_create_device_cb(DBusGProxy *proxy, DBusGProxyCall *call,
911                                 gpointer user_data)
912 {
913         GError *err = NULL;
914         char *device_path = NULL;
915         GArray *out_param1;
916         GArray *out_param2;
917         int result = BLUETOOTH_ERROR_NONE;
918         bluetooth_device_info_t dev_info;
919         bt_remote_dev_info_t *remote_dev_info;
920         request_info_t *req_info;
921
922         is_deivce_creating = FALSE;
923
924         dbus_g_proxy_end_call(proxy, call, &err,
925                         DBUS_TYPE_G_OBJECT_PATH, &device_path,
926                         G_TYPE_INVALID);
927         g_free(device_path);
928         if (searching_info == NULL) {
929                 /* Send reply */
930                 BT_ERR("searching_info == NULL");
931                 goto done;
932         }
933
934         req_info = _bt_get_request_info(searching_info->req_id);
935         if (req_info == NULL) {
936                 BT_ERR("req_info == NULL");
937                 goto done;
938         }
939
940         if (err != NULL) {
941                 BT_ERR("Error occured in Proxy call [%s]\n", err->message);
942                 result = BLUETOOTH_ERROR_CONNECTION_ERROR;
943                 goto dbus_return;
944         }
945
946         remote_dev_info = _bt_get_remote_device_info(searching_info->addr);
947
948         /* Send the event to application */
949         if (remote_dev_info != NULL) {
950                 _bt_send_event(BT_ADAPTER_EVENT,
951                         BLUETOOTH_EVENT_SERVICE_SEARCHED,
952                         DBUS_TYPE_INT32, &result,
953                         DBUS_TYPE_STRING, &searching_info->addr,
954                         DBUS_TYPE_UINT32, &remote_dev_info->class,
955                         DBUS_TYPE_INT16, &remote_dev_info->rssi,
956                         DBUS_TYPE_STRING, &remote_dev_info->name,
957                         DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
958                         DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
959                         DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
960                         DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
961                         &remote_dev_info->uuids, remote_dev_info->uuid_count,
962                         DBUS_TYPE_INVALID);
963
964                 _bt_free_device_info(remote_dev_info);
965         }
966
967 dbus_return:
968         if (req_info->context == NULL)
969                 goto done;
970
971         out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
972         out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
973
974         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
975         _bt_convert_addr_string_to_type(dev_info.device_address.addr,
976                                         searching_info->addr);
977
978         g_array_append_vals(out_param1, &dev_info,
979                                 sizeof(bluetooth_device_info_t));
980         g_array_append_vals(out_param2, &result, sizeof(int));
981
982         dbus_g_method_return(req_info->context, out_param1, out_param2);
983
984         g_array_free(out_param1, TRUE);
985         g_array_free(out_param2, TRUE);
986
987         _bt_delete_request_list(req_info->req_id);
988 done:
989         if (err)
990                 g_error_free(err);
991
992         if (searching_info) {
993                 g_free(searching_info->addr);
994                 g_free(searching_info);
995                 searching_info = NULL;
996         }
997 }
998
999 int _bt_search_device(int request_id,
1000                         bluetooth_device_address_t *device_address)
1001 {
1002         char *device_path = NULL;
1003         DBusGProxy *adapter_proxy;
1004         DBusGProxy *device_proxy = NULL;
1005         DBusGConnection *conn;
1006         int result = BLUETOOTH_ERROR_INTERNAL;
1007
1008         BT_CHECK_PARAMETER(device_address, return);
1009
1010         if (searching_info) {
1011                 BT_ERR("Service searching in progress");
1012                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1013         }
1014
1015         adapter_proxy = _bt_get_adapter_proxy();
1016         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1017
1018         conn = _bt_get_system_gconn();
1019         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1020
1021         /* allocate user data so that it can be retrieved in callback */
1022         searching_info = g_malloc0(sizeof(bt_funcion_data_t));
1023         searching_info->addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
1024         searching_info->req_id = request_id;
1025
1026         _bt_convert_addr_type_to_string(searching_info->addr,
1027                                         device_address->addr);
1028
1029         device_path = _bt_get_device_object_path(searching_info->addr);
1030
1031         if (device_path == NULL) {
1032                 /* Not support this function in bluez 5.2 */
1033                 BT_ERR("No paired device");
1034                 goto fail;
1035
1036                 is_deivce_creating = TRUE;
1037
1038                 if (!dbus_g_proxy_begin_call(adapter_proxy,
1039                                 "CreateDevice",
1040                                 (DBusGProxyCallNotify)__bt_create_device_cb,
1041                                 (gpointer)searching_info, NULL,
1042                                 G_TYPE_STRING, searching_info->addr,
1043                                 G_TYPE_INVALID)) {
1044                         BT_ERR("CreateDevice failed");
1045                         result = BLUETOOTH_ERROR_INTERNAL;
1046                         is_deivce_creating = FALSE;
1047                         goto fail;
1048                 }
1049
1050                 searching_info->adapter_proxy = device_proxy;
1051
1052                 return BLUETOOTH_ERROR_NONE;
1053         }
1054
1055         device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1056                                       device_path, BT_PROPERTIES_INTERFACE);
1057         g_free(device_path);
1058         if (device_proxy == NULL) {
1059                 result = BLUETOOTH_ERROR_INTERNAL;
1060                 goto fail;
1061         }
1062
1063         if (!dbus_g_proxy_begin_call(device_proxy, "Get",
1064                         (DBusGProxyCallNotify)__bt_discover_cb,
1065                         (gpointer)searching_info, NULL,
1066                         G_TYPE_STRING, BT_DEVICE_INTERFACE,
1067                         G_TYPE_STRING, "UUIDs",
1068                         G_TYPE_INVALID)) {
1069                 BT_ERR("DiscoverServices failed");
1070                 goto fail;
1071         }
1072
1073         searching_info->device_proxy = device_proxy;
1074
1075         return BLUETOOTH_ERROR_NONE;
1076 fail:
1077         if (device_proxy)
1078                 g_object_unref(device_proxy);
1079
1080         g_free(searching_info->addr);
1081         g_free(searching_info);
1082         searching_info = NULL;
1083         return result;
1084 }
1085
1086 int _bt_cancel_search_device(void)
1087 {
1088         GError *err = NULL;
1089
1090         retv_if(searching_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
1091
1092         if (searching_info->device_proxy) {
1093                 dbus_g_proxy_call(searching_info->device_proxy,
1094                                 "CancelDiscovery",
1095                                 &err,
1096                                 G_TYPE_INVALID, G_TYPE_INVALID);
1097         } else if (searching_info->adapter_proxy) {
1098                 dbus_g_proxy_call(searching_info->adapter_proxy,
1099                                 "CancelDeviceCreation",
1100                                 &err,
1101                                 G_TYPE_STRING, searching_info->addr,
1102                                 G_TYPE_INVALID);
1103         } else {
1104                 BT_ERR("No proxy info");
1105                 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1106         }
1107
1108         if (err != NULL) {
1109                 BT_ERR("Error occured [%s]\n", err->message);
1110                 g_error_free(err);
1111                 return BLUETOOTH_ERROR_INTERNAL;
1112         }
1113
1114         __bt_cancel_search_service_done();
1115
1116         return BLUETOOTH_ERROR_NONE;
1117 }
1118
1119 int _bt_set_alias(bluetooth_device_address_t *device_address,
1120                                       const char *alias)
1121 {
1122         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1123         gchar *device_path = NULL;
1124         DBusGProxy *adapter_proxy;
1125         DBusGProxy *device_proxy;
1126         GError *error = NULL;
1127         GValue name = { 0 };
1128         DBusGConnection *conn;
1129
1130         BT_CHECK_PARAMETER(device_address, return);
1131         BT_CHECK_PARAMETER(alias, return);
1132
1133         adapter_proxy = _bt_get_adapter_proxy();
1134         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1135
1136         conn = _bt_get_system_gconn();
1137         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1138
1139         _bt_convert_addr_type_to_string(address, device_address->addr);
1140
1141         device_path = _bt_get_device_object_path(address);
1142
1143         if (device_path == NULL) {
1144                 BT_ERR("No paired device");
1145                 return BLUETOOTH_ERROR_NOT_PAIRED;
1146         }
1147
1148         device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1149                                 device_path, BT_PROPERTIES_INTERFACE);
1150
1151         g_free(device_path);
1152         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1153         g_value_init(&name, G_TYPE_STRING);
1154         g_value_set_string(&name, alias);
1155
1156         dbus_g_proxy_call(device_proxy, "Set", &error,
1157                         G_TYPE_STRING, BT_DEVICE_INTERFACE,
1158                         G_TYPE_STRING, "Alias",
1159                         G_TYPE_VALUE, &name,
1160                         G_TYPE_INVALID, G_TYPE_INVALID);
1161
1162         g_object_unref(device_proxy);
1163
1164         g_value_unset(&name);
1165
1166         if (error) {
1167                  BT_ERR("SetProperty error: [%s]", error->message);
1168                  g_error_free(error);
1169                  return BLUETOOTH_ERROR_INTERNAL;
1170         }
1171
1172         return BLUETOOTH_ERROR_NONE;
1173 }
1174
1175 int _bt_set_authorization(bluetooth_device_address_t *device_address,
1176                                       gboolean authorize)
1177 {
1178         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1179         gchar *device_path = NULL;
1180         DBusGProxy *device_proxy;
1181         gboolean previous_value;
1182         GError *error = NULL;
1183         GValue trusted = { 0 };
1184         GValue trusted_v = { 0 };
1185         DBusGConnection *conn;
1186         int ret = BLUETOOTH_ERROR_NONE;
1187
1188         BT_CHECK_PARAMETER(device_address, return);
1189
1190         conn = _bt_get_system_gconn();
1191         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1192
1193         _bt_convert_addr_type_to_string(address, device_address->addr);
1194
1195         device_path = _bt_get_device_object_path(address);
1196
1197         if (device_path == NULL) {
1198                 BT_ERR("No paired device");
1199                 return BLUETOOTH_ERROR_NOT_PAIRED;
1200         }
1201
1202         device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1203                                 device_path, BT_PROPERTIES_INTERFACE);
1204         g_free(device_path);
1205         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1206
1207         if (!dbus_g_proxy_call(device_proxy, "Get", &error,
1208                         G_TYPE_STRING, BT_DEVICE_INTERFACE,
1209                         G_TYPE_STRING, "Trusted",
1210                         G_TYPE_INVALID,
1211                         G_TYPE_VALUE, &trusted_v,
1212                         G_TYPE_INVALID)) {
1213                 if (error != NULL) {
1214                         BT_ERR("Getting property failed: [%s]\n", error->message);
1215                         g_error_free(error);
1216                 }
1217                 g_object_unref(device_proxy);
1218                 return BLUETOOTH_ERROR_INTERNAL;
1219         }
1220
1221         previous_value = g_value_get_boolean(&trusted_v);
1222
1223         /* If the input is same with previous value, return error. */
1224         if (previous_value == authorize) {
1225                 BT_ERR("Same value: %d", previous_value);
1226                 g_object_unref(device_proxy);
1227                 ret = BLUETOOTH_ERROR_INVALID_PARAM;
1228                 goto done;
1229         }
1230
1231         g_value_init(&trusted, G_TYPE_BOOLEAN);
1232         g_value_set_boolean(&trusted, authorize);
1233
1234         dbus_g_proxy_call(device_proxy, "Set", &error,
1235                         G_TYPE_STRING, BT_DEVICE_INTERFACE,
1236                         G_TYPE_STRING, "Trusted",
1237                         G_TYPE_VALUE, &trusted,
1238                         G_TYPE_INVALID, G_TYPE_INVALID);
1239
1240         g_object_unref(device_proxy);
1241         g_value_unset(&trusted);
1242
1243         if (error) {
1244                  BT_ERR("SetProperty error: [%s]", error->message);
1245                  g_error_free(error);
1246                  ret = BLUETOOTH_ERROR_INTERNAL;
1247         }
1248 done:
1249         return ret;
1250 }
1251
1252 int _bt_is_device_connected(bluetooth_device_address_t *device_address,
1253                         int connection_type, gboolean *is_connected)
1254 {
1255         char *object_path = NULL;
1256         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1257         DBusGProxy *device_proxy = NULL;
1258         DBusGProxy *adapter_proxy = NULL;
1259         DBusGConnection *conn;
1260         GError *error = NULL;
1261         GHashTable *hash = NULL;
1262         GValue *value = NULL;
1263         char *interface = NULL;
1264
1265         retv_if(device_address == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1266         retv_if(is_connected == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1267
1268         if (connection_type == BLUETOOTH_RFCOMM_SERVICE)
1269                 return _bt_rfcomm_is_device_connected(device_address,
1270                                                 is_connected);
1271
1272         adapter_proxy = _bt_get_adapter_proxy();
1273         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1274
1275         conn = _bt_get_system_gconn();
1276         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1277
1278         _bt_convert_addr_type_to_string(address, device_address->addr);
1279
1280         dbus_g_proxy_call(adapter_proxy, "FindDevice",
1281                           &error, G_TYPE_STRING, address,
1282                           G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH,
1283                           &object_path, G_TYPE_INVALID);
1284
1285         if (error != NULL) {
1286                 BT_ERR("Failed to Find device: %s", error->message);
1287                 g_error_free(error);
1288                 return BLUETOOTH_ERROR_NOT_PAIRED;
1289         }
1290
1291         retv_if(object_path == NULL, BLUETOOTH_ERROR_INTERNAL);
1292
1293         switch (connection_type) {
1294         case BLUETOOTH_HSP_SERVICE:
1295                 interface = BT_HFP_AGENT_INTERFACE;
1296                 break;
1297         case BLUETOOTH_A2DP_SERVICE:
1298                 interface = BT_SINK_INTERFACE;
1299                 break;
1300         case BLUETOOTH_HID_SERVICE:
1301                 interface = BT_INPUT_INTERFACE;
1302                 break;
1303         default:
1304                 BT_DBG("Unknown type!");
1305                 g_free(object_path);
1306                 return BLUETOOTH_ERROR_INVALID_PARAM;
1307         }
1308
1309         BT_DBG("Interface name: %s", interface);
1310
1311         device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME, object_path, interface);
1312         g_free(object_path);
1313         if (device_proxy == NULL) {
1314                 BT_DBG("Device don't have this service");
1315                 is_connected = FALSE;
1316                 return BLUETOOTH_ERROR_NONE;
1317         }
1318         dbus_g_proxy_call(device_proxy, "GetProperties", &error,
1319                                 G_TYPE_INVALID,
1320                                 dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
1321                                 &hash, G_TYPE_INVALID);
1322
1323         if (error != NULL) {
1324                 BT_DBG("Failed to get properties: %s\n", error->message);
1325                 g_error_free(error);
1326                 g_object_unref(device_proxy);
1327                 is_connected = FALSE;
1328                 return BLUETOOTH_ERROR_NONE;
1329         }
1330
1331         if (hash != NULL) {
1332                 value = g_hash_table_lookup(hash, "Connected");
1333                 *is_connected = value ? g_value_get_boolean(value) : FALSE;
1334                 g_hash_table_destroy(hash);
1335         } else {
1336                 *is_connected = FALSE;
1337         }
1338
1339         g_object_unref(device_proxy);
1340         return BLUETOOTH_ERROR_NONE;
1341 }
1342