88183bf99d416d2302fb07c1b6ad6ce4ac540b51
[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);
340         BT_CHECK_PARAMETER(bonding_info->addr);
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);
370         BT_CHECK_PARAMETER(bonding_info->addr);
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);
402         BT_CHECK_PARAMETER(bonding_info->addr);
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                 goto done;
445         }
446
447         req_info = _bt_get_request_info(bonding_info->req_id);
448         if (req_info == NULL) {
449                 BT_ERR("req_info == NULL");
450                 goto done;
451         }
452
453         if (err != NULL) {
454                 BT_ERR("Error occured in CreateBonding [%s]", err->message);
455
456                 if (!strcmp(err->message, "Already Exists")) {
457                         BT_DBG("Existing Bond, remove and retry");
458                         ret_if(__bt_remove_and_bond() == BLUETOOTH_ERROR_NONE);
459
460                         result = BLUETOOTH_ERROR_PARING_FAILED;
461                 } else if (!strcmp(err->message, "Authentication Rejected")) {
462                         result = BLUETOOTH_ERROR_ACCESS_DENIED;
463                 } else if (_bt_agent_is_canceled(bonding_info->agent) ||
464                         !strcmp(err->message, "Authentication Canceled")) {
465                         result = BLUETOOTH_ERROR_CANCEL_BY_USER;
466                 } else if (!strcmp(err->message, "In Progress")) {
467                         BT_DBG("Bond in progress, cancel and retry");
468                         ret_if(__bt_cancel_and_bond() == BLUETOOTH_ERROR_NONE);
469
470                         result = BLUETOOTH_ERROR_PARING_FAILED;
471                 } else if (!strcmp(err->message, "Authentication Failed")) {
472                         if (bonding_info->is_autopair == TRUE) {
473                                 _bt_set_autopair_status_in_bonding_info(FALSE);
474                                 __ignore_auto_pairing_request(bonding_info->addr);
475                         }
476                         result = BLUETOOTH_ERROR_AUTHENTICATION_FAILED;
477                 } else if (!strcmp(err->message, "Page Timeout")) {
478                         /* This is the special case
479                              As soon as call bluetooth_bond_device, try to cancel bonding.
480                              In this case, before completing to call 'CreatePairedDevice' method
481                              the procedure is stopped. So 'Cancle' error is not return.
482                         */
483                         result = BLUETOOTH_ERROR_HOST_DOWN;
484                 } else if (!strcmp(err->message, BT_TIMEOUT_MESSAGE)) {
485                         dbus_g_proxy_call(proxy, "CancelDeviceCreation", NULL,
486                                            G_TYPE_STRING, bonding_info->addr,
487                                            G_TYPE_INVALID, G_TYPE_INVALID);
488
489                         result = BLUETOOTH_ERROR_TIMEOUT;
490                 } else {
491                         result = BLUETOOTH_ERROR_PARING_FAILED;
492                 }
493         }
494
495         if (result != BLUETOOTH_ERROR_NONE)
496                 goto dbus_return;
497
498         remote_dev_info = _bt_get_remote_device_info(bonding_info->addr);
499
500         /* Send the event to application */
501         if (remote_dev_info != NULL) {
502                 _bt_send_event(BT_ADAPTER_EVENT,
503                         BLUETOOTH_EVENT_BONDING_FINISHED,
504                         DBUS_TYPE_INT32, &result,
505                         DBUS_TYPE_STRING, &bonding_info->addr,
506                         DBUS_TYPE_UINT32, &remote_dev_info->class,
507                         DBUS_TYPE_INT16, &remote_dev_info->rssi,
508                         DBUS_TYPE_STRING, &remote_dev_info->name,
509                         DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
510                         DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
511                         DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
512                         DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
513                         &remote_dev_info->uuids, remote_dev_info->uuid_count,
514                         DBUS_TYPE_INVALID);
515
516                 _bt_free_device_info(remote_dev_info);
517         }
518
519 dbus_return:
520         if (req_info->context == NULL)
521                 goto done;
522
523         out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
524         out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
525
526         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
527         _bt_convert_addr_string_to_type(dev_info.device_address.addr,
528                                         bonding_info->addr);
529
530         g_array_append_vals(out_param1, &dev_info,
531                                 sizeof(bluetooth_device_info_t));
532         g_array_append_vals(out_param2, &result, sizeof(int));
533
534         dbus_g_method_return(req_info->context, out_param1, out_param2);
535
536         g_array_free(out_param1, TRUE);
537         g_array_free(out_param2, TRUE);
538
539         _bt_delete_request_list(req_info->req_id);
540 done:
541         if (err)
542                 g_error_free(err);
543
544         _bt_destroy_agent(bonding_info->agent);
545
546         g_free(bonding_info->addr);
547         g_free(bonding_info);
548         bonding_info = NULL;
549
550 }
551
552 int _bt_bond_device(int request_id,
553                 bluetooth_device_address_t *device_address,
554                 GArray **out_param1)
555 {
556         DBusGProxy *proxy;
557         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
558         void *agent;
559         bluetooth_device_info_t dev_info;
560
561         BT_CHECK_PARAMETER(device_address);
562
563         if (bonding_info) {
564                 BT_ERR("Bonding in progress");
565                 return BLUETOOTH_ERROR_DEVICE_BUSY;
566         }
567
568         proxy = _bt_get_adapter_proxy();
569         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
570
571         _bt_convert_addr_type_to_string(address, device_address->addr);
572
573         agent = _bt_create_agent(BT_DEVICE_AGENT_PATH, FALSE);
574         retv_if(agent == NULL, BLUETOOTH_ERROR_INTERNAL);
575
576         bonding_info = g_malloc0(sizeof(bt_funcion_data_t));
577         bonding_info->addr = g_strdup(address);
578         bonding_info->req_id = request_id;
579         bonding_info->agent = agent;
580
581         is_deivce_creating = TRUE;
582
583         if (!strncmp(address, SMB_MOUSE_LAP_ADDR, strlen(SMB_MOUSE_LAP_ADDR))) {
584                 bluetooth_device_address_t device_addr = { {0} };
585                 BT_ERR("This device don't support pairing. So skip pairing.");
586                 if (!dbus_g_proxy_begin_call(proxy, "CreateDevice",
587                                 (DBusGProxyCallNotify)__bt_bond_device_cb,
588                                 NULL, NULL,
589                                 G_TYPE_STRING, device_addr,
590                                 G_TYPE_INVALID)) {
591                         BT_ERR("CreateDevice failed");
592                         goto fail;
593                 }
594
595                 _bt_convert_addr_string_to_type(device_addr.addr, address);
596                 if (_bt_set_authorization(&device_addr, TRUE))
597                         BT_ERR("_bt_set_authorization failed [%s]", address);
598
599         } else {
600                 if (!dbus_g_proxy_begin_call_with_timeout(proxy, "CreatePairedDevice",
601                                         (DBusGProxyCallNotify) __bt_bond_device_cb,
602                                         NULL, NULL, BT_MAX_DBUS_TIMEOUT,
603                                         G_TYPE_STRING, address,
604                                         DBUS_TYPE_G_OBJECT_PATH, BT_DEVICE_AGENT_PATH,
605                                         G_TYPE_STRING, "DisplayYesNo",
606                                         G_TYPE_INVALID)) {
607                         BT_ERR("CreatePairedDevice call fail");
608                         goto fail;
609                 }
610         }
611
612         return BLUETOOTH_ERROR_NONE;
613 fail:
614         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
615         _bt_convert_addr_string_to_type(dev_info.device_address.addr,
616                                         bonding_info->addr);
617
618         g_array_append_vals(*out_param1, &dev_info,
619                                 sizeof(bluetooth_device_info_t));
620
621         is_deivce_creating = FALSE;
622
623         _bt_destroy_agent(agent);
624
625         g_free(bonding_info->addr);
626         g_free(bonding_info);
627         bonding_info = NULL;
628
629         return BLUETOOTH_ERROR_INTERNAL;
630 }
631
632 int _bt_cancel_bonding(void)
633 {
634         DBusGProxy *adapter_proxy;
635
636         retv_if(bonding_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
637
638         adapter_proxy = _bt_get_adapter_proxy();
639         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
640
641         dbus_g_proxy_call_no_reply(adapter_proxy, "CancelDeviceCreation",
642                                    G_TYPE_STRING, bonding_info->addr,
643                                    G_TYPE_INVALID, G_TYPE_INVALID);
644
645         return BLUETOOTH_ERROR_NONE;
646 }
647
648 static void __bt_unbond_cb(DBusGProxy *proxy, DBusGProxyCall *call,
649                                 gpointer user_data)
650 {
651         GError *err = NULL;
652         GArray *out_param1;
653         GArray *out_param2;
654         int result = BLUETOOTH_ERROR_NONE;
655         bt_funcion_data_t *unbonding_info;
656         bluetooth_device_info_t dev_info;
657         request_info_t *req_info;
658
659         dbus_g_proxy_end_call(proxy, call, &err, G_TYPE_INVALID);
660
661         unbonding_info = user_data;
662
663         if (unbonding_info == NULL) {
664                 /* Send reply */
665                 BT_ERR("unbonding_info == NULL");
666                 goto done;
667         }
668
669         req_info = _bt_get_request_info(unbonding_info->req_id);
670         if (req_info == NULL) {
671                 BT_ERR("req_info == NULL");
672                 goto done;
673         }
674
675         if (err != NULL) {
676                 BT_ERR("Error occured in RemoveBonding [%s]\n", err->message);
677                 result = BLUETOOTH_ERROR_INTERNAL;
678                 goto dbus_return;
679         }
680
681 dbus_return:
682         if (req_info->context == NULL)
683                 goto done;
684
685         out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
686         out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
687
688         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
689         _bt_convert_addr_string_to_type(dev_info.device_address.addr,
690                                         unbonding_info->addr);
691
692         g_array_append_vals(out_param1, &dev_info,
693                                 sizeof(bluetooth_device_info_t));
694         g_array_append_vals(out_param2, &result, sizeof(int));
695
696         dbus_g_method_return(req_info->context, out_param1, out_param2);
697
698         _bt_delete_request_list(req_info->req_id);
699
700         g_array_free(out_param1, TRUE);
701         g_array_free(out_param2, TRUE);
702
703 done:
704         if (err)
705                 g_error_free(err);
706
707         if (unbonding_info) {
708                 g_free(unbonding_info->addr);
709                 g_free(unbonding_info);
710         }
711 }
712
713 int _bt_unbond_device(int request_id,
714                         bluetooth_device_address_t *device_address,
715                         GArray **out_param1)
716 {
717         char *device_path = NULL;
718         bt_funcion_data_t *unbonding_info;
719         DBusGProxy *adapter_proxy;
720         int result = BLUETOOTH_ERROR_INTERNAL;
721         bluetooth_device_info_t dev_info;
722
723         BT_CHECK_PARAMETER(device_address);
724
725         adapter_proxy = _bt_get_adapter_proxy();
726         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
727
728         /* allocate user data so that it can be retrieved in callback */
729         unbonding_info = g_malloc0(sizeof(bt_funcion_data_t));
730         unbonding_info->addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
731         unbonding_info->req_id = request_id;
732
733         _bt_convert_addr_type_to_string(unbonding_info->addr,
734                                         device_address->addr);
735
736         dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
737                                   G_TYPE_STRING, unbonding_info->addr,
738                                   G_TYPE_INVALID,
739                                   DBUS_TYPE_G_OBJECT_PATH, &device_path,
740                                   G_TYPE_INVALID);
741
742         if (device_path == NULL) {
743                 BT_ERR("No paired device");
744                 result = BLUETOOTH_ERROR_NOT_PAIRED;
745                 goto fail;
746         }
747
748         if (!dbus_g_proxy_begin_call(adapter_proxy, "RemoveDevice",
749                                 (DBusGProxyCallNotify) __bt_unbond_cb,
750                                 (gpointer)unbonding_info, NULL,
751                                 DBUS_TYPE_G_OBJECT_PATH, device_path,
752                                 G_TYPE_INVALID)) {
753                 BT_ERR("RemoveBonding begin failed\n");
754                 goto fail;
755         }
756         g_free(device_path);
757         return BLUETOOTH_ERROR_NONE;
758
759 fail:
760         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
761         _bt_convert_addr_string_to_type(dev_info.device_address.addr,
762                                         unbonding_info->addr);
763
764         g_array_append_vals(*out_param1, &dev_info,
765                                 sizeof(bluetooth_device_info_t));
766         g_free(device_path);
767         g_free(unbonding_info->addr);
768         g_free(unbonding_info);
769         return result;
770 }
771
772 static void __bt_discover_cb(DBusGProxy *proxy, DBusGProxyCall *call,
773                                 gpointer user_data)
774 {
775         GError *err = NULL;
776         GHashTable *hash = NULL;
777         GArray *out_param1;
778         GArray *out_param2;
779         int result = BLUETOOTH_ERROR_NONE;
780         bluetooth_device_info_t dev_info;
781         bt_remote_dev_info_t *remote_dev_info;
782         request_info_t *req_info;
783
784         dbus_g_proxy_end_call(proxy, call, &err,
785                               dbus_g_type_get_map("GHashTable", G_TYPE_UINT, G_TYPE_STRING), &hash,
786                               G_TYPE_INVALID);
787
788         g_object_unref(proxy);
789
790         if (searching_info == NULL) {
791                 /* Send reply */
792                 BT_ERR("unbonding_info == NULL");
793                 goto done;
794         }
795
796         req_info = _bt_get_request_info(searching_info->req_id);
797         if (req_info == NULL) {
798                 BT_ERR("req_info == NULL");
799                 goto done;
800         }
801
802         if (err != NULL) {
803                 BT_ERR("Error occured in Proxy call [%s]\n", err->message);
804
805                 if (!strcmp("Operation canceled", err->message)) {
806                         result = BLUETOOTH_ERROR_CANCEL_BY_USER;
807                 } else if (!strcmp("In Progress", err->message)) {
808                         result = BLUETOOTH_ERROR_IN_PROGRESS;
809                 } else if (!strcmp("Host is down", err->message)) {
810                         result = BLUETOOTH_ERROR_HOST_DOWN;
811                 } else {
812                         result = BLUETOOTH_ERROR_CONNECTION_ERROR;
813                 }
814
815                 if (result == BLUETOOTH_ERROR_HOST_DOWN ||
816                      result == BLUETOOTH_ERROR_CONNECTION_ERROR) {
817                         remote_dev_info = _bt_get_remote_device_info(searching_info->addr);
818                         if (remote_dev_info && remote_dev_info->uuids != NULL &&
819                              remote_dev_info->uuid_count > 0) {
820                                 result = BLUETOOTH_ERROR_NONE;
821                                 goto event;
822                         }
823                         _bt_free_device_info(remote_dev_info);
824                 }
825                 goto dbus_return;
826         }
827
828         remote_dev_info = _bt_get_remote_device_info(searching_info->addr);
829
830 event:
831         /* Send the event to application */
832         if (remote_dev_info != NULL) {
833                 _bt_send_event(BT_ADAPTER_EVENT,
834                         BLUETOOTH_EVENT_SERVICE_SEARCHED,
835                         DBUS_TYPE_INT32, &result,
836                         DBUS_TYPE_STRING, &searching_info->addr,
837                         DBUS_TYPE_UINT32, &remote_dev_info->class,
838                         DBUS_TYPE_INT16, &remote_dev_info->rssi,
839                         DBUS_TYPE_STRING, &remote_dev_info->name,
840                         DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
841                         DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
842                         DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
843                         DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
844                         &remote_dev_info->uuids, remote_dev_info->uuid_count,
845                         DBUS_TYPE_INVALID);
846
847                 _bt_free_device_info(remote_dev_info);
848         }
849
850 dbus_return:
851         if (req_info->context == NULL)
852                 goto done;
853
854         out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
855         out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
856
857         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
858         _bt_convert_addr_string_to_type(dev_info.device_address.addr,
859                                         searching_info->addr);
860
861         g_array_append_vals(out_param1, &dev_info,
862                                 sizeof(bluetooth_device_info_t));
863         g_array_append_vals(out_param2, &result, sizeof(int));
864
865         dbus_g_method_return(req_info->context, out_param1, out_param2);
866
867         g_array_free(out_param1, TRUE);
868         g_array_free(out_param2, TRUE);
869
870         _bt_delete_request_list(req_info->req_id);
871 done:
872         if (err)
873                 g_error_free(err);
874
875         g_hash_table_destroy(hash);
876
877         if (searching_info) {
878                 g_free(searching_info->addr);
879                 g_free(searching_info);
880                 searching_info = NULL;
881         }
882 }
883
884 static void __bt_create_device_cb(DBusGProxy *proxy, DBusGProxyCall *call,
885                                 gpointer user_data)
886 {
887         GError *err = NULL;
888         char *device_path = NULL;
889         GArray *out_param1;
890         GArray *out_param2;
891         int result = BLUETOOTH_ERROR_NONE;
892         bluetooth_device_info_t dev_info;
893         bt_remote_dev_info_t *remote_dev_info;
894         request_info_t *req_info;
895
896         is_deivce_creating = FALSE;
897
898         dbus_g_proxy_end_call(proxy, call, &err,
899                         DBUS_TYPE_G_OBJECT_PATH, &device_path,
900                         G_TYPE_INVALID);
901         g_free(device_path);
902         if (searching_info == NULL) {
903                 /* Send reply */
904                 BT_ERR("searching_info == NULL");
905                 goto done;
906         }
907
908         req_info = _bt_get_request_info(searching_info->req_id);
909         if (req_info == NULL) {
910                 BT_ERR("req_info == NULL");
911                 goto done;
912         }
913
914         if (err != NULL) {
915                 BT_ERR("Error occured in Proxy call [%s]\n", err->message);
916                 result = BLUETOOTH_ERROR_CONNECTION_ERROR;
917                 goto dbus_return;
918         }
919
920         remote_dev_info = _bt_get_remote_device_info(searching_info->addr);
921
922         /* Send the event to application */
923         if (remote_dev_info != NULL) {
924                 _bt_send_event(BT_ADAPTER_EVENT,
925                         BLUETOOTH_EVENT_SERVICE_SEARCHED,
926                         DBUS_TYPE_INT32, &result,
927                         DBUS_TYPE_STRING, &searching_info->addr,
928                         DBUS_TYPE_UINT32, &remote_dev_info->class,
929                         DBUS_TYPE_INT16, &remote_dev_info->rssi,
930                         DBUS_TYPE_STRING, &remote_dev_info->name,
931                         DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
932                         DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
933                         DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
934                         DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
935                         &remote_dev_info->uuids, remote_dev_info->uuid_count,
936                         DBUS_TYPE_INVALID);
937
938                 _bt_free_device_info(remote_dev_info);
939         }
940
941 dbus_return:
942         if (req_info->context == NULL)
943                 goto done;
944
945         out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
946         out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
947
948         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
949         _bt_convert_addr_string_to_type(dev_info.device_address.addr,
950                                         searching_info->addr);
951
952         g_array_append_vals(out_param1, &dev_info,
953                                 sizeof(bluetooth_device_info_t));
954         g_array_append_vals(out_param2, &result, sizeof(int));
955
956         dbus_g_method_return(req_info->context, out_param1, out_param2);
957
958         g_array_free(out_param1, TRUE);
959         g_array_free(out_param2, TRUE);
960
961         _bt_delete_request_list(req_info->req_id);
962 done:
963         if (err)
964                 g_error_free(err);
965
966         if (searching_info) {
967                 g_free(searching_info->addr);
968                 g_free(searching_info);
969                 searching_info = NULL;
970         }
971 }
972
973 int _bt_search_device(int request_id,
974                         bluetooth_device_address_t *device_address)
975 {
976         char *device_path = NULL;
977         DBusGProxy *adapter_proxy;
978         DBusGProxy *device_proxy = NULL;
979         DBusGConnection *conn;
980         int result = BLUETOOTH_ERROR_INTERNAL;
981
982         BT_CHECK_PARAMETER(device_address);
983
984         if (searching_info) {
985                 BT_ERR("Service searching in progress");
986                 return BLUETOOTH_ERROR_DEVICE_BUSY;
987         }
988
989         adapter_proxy = _bt_get_adapter_proxy();
990         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
991
992         conn = _bt_get_system_gconn();
993         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
994
995         /* allocate user data so that it can be retrieved in callback */
996         searching_info = g_malloc0(sizeof(bt_funcion_data_t));
997         searching_info->addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
998         searching_info->req_id = request_id;
999
1000         _bt_convert_addr_type_to_string(searching_info->addr,
1001                                         device_address->addr);
1002
1003         dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
1004                                   G_TYPE_STRING, searching_info->addr,
1005                                   G_TYPE_INVALID,
1006                                   DBUS_TYPE_G_OBJECT_PATH, &device_path,
1007                                   G_TYPE_INVALID);
1008
1009         if (device_path == NULL) {
1010                 BT_ERR("No paired device");
1011
1012                 is_deivce_creating = TRUE;
1013
1014                 if (!dbus_g_proxy_begin_call(adapter_proxy,
1015                                 "CreateDevice",
1016                                 (DBusGProxyCallNotify)__bt_create_device_cb,
1017                                 (gpointer)searching_info, NULL,
1018                                 G_TYPE_STRING, searching_info->addr,
1019                                 G_TYPE_INVALID)) {
1020                         BT_ERR("CreateDevice failed");
1021                         result = BLUETOOTH_ERROR_INTERNAL;
1022                         is_deivce_creating = FALSE;
1023                         goto fail;
1024                 }
1025
1026                 searching_info->adapter_proxy = device_proxy;
1027
1028                 return BLUETOOTH_ERROR_NONE;
1029         }
1030
1031         device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1032                                       device_path, BT_DEVICE_INTERFACE);
1033         g_free(device_path);
1034         if (device_proxy == NULL) {
1035                 result = BLUETOOTH_ERROR_INTERNAL;
1036                 goto fail;
1037         }
1038         if (!dbus_g_proxy_begin_call(device_proxy, "DiscoverServices",
1039                                 (DBusGProxyCallNotify)__bt_discover_cb,
1040                                 (gpointer)searching_info, NULL,
1041                                 G_TYPE_STRING, "",
1042                                 G_TYPE_INVALID)) {
1043                 BT_ERR("DiscoverServices failed");
1044                 goto fail;
1045         }
1046
1047         searching_info->device_proxy = device_proxy;
1048
1049         return BLUETOOTH_ERROR_NONE;
1050 fail:
1051         if (device_proxy)
1052                 g_object_unref(device_proxy);
1053
1054         g_free(searching_info->addr);
1055         g_free(searching_info);
1056         searching_info = NULL;
1057         return result;
1058 }
1059
1060 int _bt_cancel_search_device(void)
1061 {
1062         GError *err = NULL;
1063
1064         retv_if(searching_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
1065
1066         if (searching_info->device_proxy) {
1067                 dbus_g_proxy_call(searching_info->device_proxy,
1068                                 "CancelDiscovery",
1069                                 &err,
1070                                 G_TYPE_INVALID, G_TYPE_INVALID);
1071         } else if (searching_info->adapter_proxy) {
1072                 dbus_g_proxy_call(searching_info->adapter_proxy,
1073                                 "CancelDeviceCreation",
1074                                 &err,
1075                                 G_TYPE_STRING, searching_info->addr,
1076                                 G_TYPE_INVALID);
1077         } else {
1078                 BT_ERR("No proxy info");
1079                 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1080         }
1081
1082         if (err != NULL) {
1083                 BT_ERR("Error occured [%s]\n", err->message);
1084                 g_error_free(err);
1085                 return BLUETOOTH_ERROR_INTERNAL;
1086         }
1087
1088         __bt_cancel_search_service_done();
1089
1090         return BLUETOOTH_ERROR_NONE;
1091 }
1092
1093 int _bt_set_alias(bluetooth_device_address_t *device_address,
1094                                       const char *alias)
1095 {
1096         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1097         gchar *device_path = NULL;
1098         DBusGProxy *adapter_proxy;
1099         DBusGProxy *device_proxy;
1100         GError *error = NULL;
1101         GValue name = { 0 };
1102         DBusGConnection *conn;
1103
1104         BT_CHECK_PARAMETER(device_address);
1105         BT_CHECK_PARAMETER(alias);
1106
1107         adapter_proxy = _bt_get_adapter_proxy();
1108         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1109
1110         conn = _bt_get_system_gconn();
1111         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1112
1113         _bt_convert_addr_type_to_string(address, device_address->addr);
1114
1115         dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
1116                           G_TYPE_STRING, address, G_TYPE_INVALID,
1117                           DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID);
1118
1119         if (device_path == NULL) {
1120                 BT_ERR("No paired device");
1121                 return BLUETOOTH_ERROR_NOT_PAIRED;
1122         }
1123
1124         device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1125                                 device_path, BT_DEVICE_INTERFACE);
1126
1127         g_free(device_path);
1128         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1129         g_value_init(&name, G_TYPE_STRING);
1130         g_value_set_string(&name, alias);
1131
1132         dbus_g_proxy_call(device_proxy, "SetProperty", &error,
1133                            G_TYPE_STRING, "Alias", G_TYPE_VALUE,
1134                            &name, G_TYPE_INVALID);
1135
1136         g_object_unref(device_proxy);
1137
1138         g_value_unset(&name);
1139
1140         if (error) {
1141                  BT_ERR("SetProperty error: [%s]", error->message);
1142                  g_error_free(error);
1143                  return BLUETOOTH_ERROR_INTERNAL;
1144         }
1145
1146         return BLUETOOTH_ERROR_NONE;
1147 }
1148
1149 int _bt_set_authorization(bluetooth_device_address_t *device_address,
1150                                       gboolean authorize)
1151 {
1152         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1153         gchar *device_path = NULL;
1154         DBusGProxy *adapter_proxy;
1155         DBusGProxy *device_proxy;
1156         gboolean previous_value;
1157         GError *error = NULL;
1158         GValue trusted = { 0 };
1159         GValue *value;
1160         GHashTable *hash = NULL;
1161         DBusGConnection *conn;
1162         int ret = BLUETOOTH_ERROR_NONE;
1163
1164         BT_CHECK_PARAMETER(device_address);
1165
1166         adapter_proxy = _bt_get_adapter_proxy();
1167         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1168
1169         conn = _bt_get_system_gconn();
1170         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1171
1172         _bt_convert_addr_type_to_string(address, device_address->addr);
1173
1174         dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
1175                           G_TYPE_STRING, address, G_TYPE_INVALID,
1176                           DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID);
1177
1178         if (device_path == NULL) {
1179                 BT_ERR("No paired device");
1180                 return BLUETOOTH_ERROR_NOT_PAIRED;
1181         }
1182
1183         device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1184                                 device_path, BT_DEVICE_INTERFACE);
1185         g_free(device_path);
1186         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1187
1188         dbus_g_proxy_call(device_proxy, "GetProperties", &error,
1189                                 G_TYPE_INVALID,
1190                                 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
1191                                 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
1192
1193         if (error != NULL) {
1194                 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
1195                 g_error_free(error);
1196                 g_object_unref(device_proxy);
1197                 return BLUETOOTH_ERROR_INTERNAL;
1198         }
1199
1200         if (hash == NULL) {
1201                 g_object_unref(device_proxy);
1202                 return BLUETOOTH_ERROR_INTERNAL;
1203         }
1204
1205         value = g_hash_table_lookup(hash, "Trusted");
1206         previous_value = value ? g_value_get_boolean(value) : FALSE;
1207
1208         /* If the input is same with previous value, return error. */
1209         if (previous_value == authorize) {
1210                 BT_ERR("Same value: %d", previous_value);
1211                 g_object_unref(device_proxy);
1212                 ret = BLUETOOTH_ERROR_INVALID_PARAM;
1213                 goto done;
1214         }
1215
1216         g_value_init(&trusted, G_TYPE_BOOLEAN);
1217         g_value_set_boolean(&trusted, authorize);
1218
1219         dbus_g_proxy_call(device_proxy, "SetProperty", &error,
1220                            G_TYPE_STRING, "Trusted", G_TYPE_VALUE,
1221                            &trusted, G_TYPE_INVALID);
1222
1223         g_object_unref(device_proxy);
1224
1225         g_value_unset(&trusted);
1226
1227         if (error) {
1228                  BT_ERR("SetProperty error: [%s]", error->message);
1229                  g_error_free(error);
1230                  ret = BLUETOOTH_ERROR_INTERNAL;
1231         }
1232 done:
1233         g_hash_table_destroy(hash);
1234
1235         return ret;
1236 }
1237
1238 int _bt_is_device_connected(bluetooth_device_address_t *device_address,
1239                         int connection_type, gboolean *is_connected)
1240 {
1241         char *object_path = NULL;
1242         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1243         DBusGProxy *device_proxy = NULL;
1244         DBusGProxy *adapter_proxy = NULL;
1245         DBusGConnection *conn;
1246         GError *error = NULL;
1247         GHashTable *hash = NULL;
1248         GValue *value = NULL;
1249         char *interface = NULL;
1250
1251         retv_if(device_address == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1252         retv_if(is_connected == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1253
1254         if (connection_type == BLUETOOTH_RFCOMM_SERVICE)
1255                 return _bt_rfcomm_is_device_connected(device_address,
1256                                                 is_connected);
1257
1258         adapter_proxy = _bt_get_adapter_proxy();
1259         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1260
1261         conn = _bt_get_system_gconn();
1262         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1263
1264         _bt_convert_addr_type_to_string(address, device_address->addr);
1265
1266         dbus_g_proxy_call(adapter_proxy, "FindDevice",
1267                           &error, G_TYPE_STRING, address,
1268                           G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH,
1269                           &object_path, G_TYPE_INVALID);
1270
1271         if (error != NULL) {
1272                 BT_ERR("Failed to Find device: %s", error->message);
1273                 g_error_free(error);
1274                 return BLUETOOTH_ERROR_NOT_PAIRED;
1275         }
1276
1277         retv_if(object_path == NULL, BLUETOOTH_ERROR_INTERNAL);
1278
1279         switch (connection_type) {
1280         case BLUETOOTH_HSP_SERVICE:
1281                 interface = BT_HEADSET_INTERFACE;
1282                 break;
1283         case BLUETOOTH_A2DP_SERVICE:
1284                 interface = BT_SINK_INTERFACE;
1285                 break;
1286         case BLUETOOTH_HID_SERVICE:
1287                 interface = BT_INPUT_INTERFACE;
1288                 break;
1289         default:
1290                 BT_DBG("Unknown type!");
1291                 g_free(object_path);
1292                 return BLUETOOTH_ERROR_INVALID_PARAM;
1293         }
1294
1295         BT_DBG("Interface name: %s", interface);
1296
1297         device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME, object_path, interface);
1298         g_free(object_path);
1299         if (device_proxy == NULL) {
1300                 BT_DBG("Device don't have this service");
1301                 is_connected = FALSE;
1302                 return BLUETOOTH_ERROR_NONE;
1303         }
1304         dbus_g_proxy_call(device_proxy, "GetProperties", &error,
1305                                 G_TYPE_INVALID,
1306                                 dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
1307                                 &hash, G_TYPE_INVALID);
1308
1309         if (error != NULL) {
1310                 BT_DBG("Failed to get properties: %s\n", error->message);
1311                 g_error_free(error);
1312                 g_object_unref(device_proxy);
1313                 is_connected = FALSE;
1314                 return BLUETOOTH_ERROR_NONE;
1315         }
1316
1317         if (hash != NULL) {
1318                 value = g_hash_table_lookup(hash, "Connected");
1319                 *is_connected = value ? g_value_get_boolean(value) : FALSE;
1320                 g_hash_table_destroy(hash);
1321         } else {
1322                 *is_connected = FALSE;
1323         }
1324
1325         g_object_unref(device_proxy);
1326         return BLUETOOTH_ERROR_NONE;
1327 }
1328