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