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