896a2281727ba2906963d3d390f8af61d14a3a29
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-device.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <glib.h>
19 #include <gio/gio.h>
20 #include <dlog.h>
21 #include <string.h>
22 #include <vconf.h>
23 #include <bundle_internal.h>
24
25
26 #include "bluetooth-api.h"
27 #include "bt-internal-types.h"
28
29 #include "bt-service-common.h"
30 #include "bt-service-adapter-le.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 #include "bt-service-network.h"
37 #include "bt-service-adapter.h"
38 #include "bt-service-gap-agent.h"
39 #include "bt-service-pbap.h"
40
41 #define BT_SYSPOPUP_IPC_RESPONSE_OBJECT "/org/projectx/bt_syspopup_res"
42 #define BT_SYSPOPUP_INTERFACE "User.Bluetooth.syspopup"
43 #define BT_SYSPOPUP_METHOD_RESPONSE "Response"
44
45 #define BT_LE_CONN_INTERVAL_MIN 7.5 /* msec */
46 #define BT_LE_CONN_INTERVAL_MAX 4000 /* msec */
47 #define BT_LE_CONN_SUPER_TO_MIN 100 /* msec */
48 #define BT_LE_CONN_SUPER_TO_MAX 32000 /* msec */
49 #define BT_LE_CONN_SLAVE_LATENCY_MAX 499
50 #define BT_LE_CONN_INTERVAL_SPLIT 1.25 /* msec */
51 #define BT_LE_CONN_TO_SPLIT 10 /* msec */
52 #define BT_DEVICE_PIN_CODE_SLOT_MAX 10
53
54 #define BT_LE_CONN_PARAM_DEFAULT_SUPERVISION_TIMEOUT    6000    /* msec */
55
56 #define BT_LE_CONN_PARAM_BALANCED_MIN_INTERVAL  30      /* msec */
57 #define BT_LE_CONN_PARAM_BALANCED_MAX_INTERVAL  50      /* msec */
58 #define BT_LE_CONN_PARAM_BALANCED_SLAVE_LATENCY 0       /* event */
59
60 #define BT_LE_CONN_PARAM_LOW_LATENCY_MIN_INTERVAL       10      /* msec */
61 #define BT_LE_CONN_PARAM_LOW_LATENCY_MAX_INTERVAL       30      /* msec */
62 #define BT_LE_CONN_PARAM_LOW_LATENCY_SLAVE_LATENCY      0       /* event */
63
64 #define BT_LE_CONN_PARAM_LOW_POWER_MIN_INTERVAL         80      /* msec */
65 #define BT_LE_CONN_PARAM_LOW_POWER_MAX_INTERVAL         100     /* msec */
66 #define BT_LE_CONN_PARAM_LOW_POWER_SLAVE_LATENCY        2       /* event */
67
68 #define PROFILE_SUPPORTED 0x3 /* This corresponds to binary 0b11*/
69
70 typedef struct {
71         int req_id;
72         int result;
73         char *addr;
74         gboolean is_autopair;
75         GDBusProxy *device_proxy;
76         GDBusProxy *adapter_proxy;
77         void *agent;
78         unsigned short conn_type;
79         gboolean bonding_wo_discovery;
80 } bt_funcion_data_t;
81
82 typedef struct {
83         char *address;
84         char *pin_code;
85 } bt_pin_code_info_t;
86
87 typedef struct {
88         int req_id;
89         bluetooth_device_address_t bd_addr;
90         gboolean auto_connect;
91 } bt_pending_le_conn_info_s;
92
93 gboolean is_device_creating;
94 bt_funcion_data_t *bonding_info;
95 bt_funcion_data_t *searching_info;
96 bt_funcion_data_t *att_mtu_req_info;
97
98 static GSList *pin_info_list = NULL;
99 static bt_pending_le_conn_info_s *pending_le_conn_info = NULL;
100 static guint pending_le_conn_timer_id = 0;
101
102 /* This HID Mouse does not support pairing precedure. need to skip it. */
103 #define SMB_MOUSE_LAP_ADDR "00:12:A1"
104
105 static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res,
106                                         gpointer user_data);
107
108 static int __bt_retry_bond(void);
109
110
111 /*static void __bt_decline_pair_request()
112 {
113         GVariant *out_param1;
114         GVariant *out_param2;
115         request_info_t *req_info;
116         bluetooth_device_info_t dev_info;
117         bt_remote_dev_info_t *remote_dev_info;
118         GVariant *uuid_list, *manufacture_data;
119         GVariant *param;
120
121         BT_DBG("+");
122         if (bonding_info) {
123                 req_info = _bt_get_request_info(bonding_info->req_id);
124                 if (req_info == NULL) {
125                         BT_ERR("req_info == NULL");
126                         goto done;
127                 }
128                 remote_dev_info = _bt_get_remote_device_info(bonding_info->addr);
129         } else {
130                 BT_DBG("bonding_info is NULL");
131                 BT_DBG("-");
132                 return;
133         }
134
135         uuid_list =  g_variant_new_from_data((const GVariantType *)"as",
136                                                 remote_dev_info->uuids, remote_dev_info->uuid_count,
137                                                 TRUE, NULL, NULL);
138
139         manufacture_data = g_variant_new_from_data((const GVariantType *)"ay",
140                                                 remote_dev_info->manufacturer_data, remote_dev_info->manufacturer_data_len,
141                                                 TRUE, NULL, NULL);
142
143         param = g_variant_new("isunsbuba{s}na{y})",
144                         bonding_info->result,
145                         bonding_info->addr,
146                         remote_dev_info->class,
147                         remote_dev_info->rssi,
148                         remote_dev_info->name,
149                         remote_dev_info->paired,
150                         remote_dev_info->connected,
151                         remote_dev_info->trust,
152                         uuid_list,
153                         remote_dev_info->manufacturer_data_len,
154                         manufacture_data);
155
156
157         //Send the event to application
158         if (remote_dev_info != NULL) {
159                 _bt_send_event(BT_ADAPTER_EVENT,
160                         BLUETOOTH_EVENT_BONDING_FINISHED,
161                         param);
162
163                 _bt_free_device_info(remote_dev_info);
164         }
165
166         if (req_info->context == NULL)
167                 goto done;
168
169         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
170         _bt_convert_addr_string_to_type(dev_info.device_address.addr,
171                                         bonding_info->addr);
172
173         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
174                 &dev_info, sizeof(bluetooth_device_info_t), TRUE, NULL, NULL);
175
176         out_param2 = g_variant_new_from_data((const GVariantType *)"i",
177                 &bonding_info->result, sizeof(int), TRUE, NULL, NULL);
178
179
180         g_dbus_method_invocation_return_value(req_info->context,
181                         g_variant_new("@ayi", out_param1, out_param2));
182
183
184         _bt_delete_request_list(req_info->req_id);
185 done:
186
187         g_free(bonding_info->addr);
188         g_free(bonding_info);
189         bonding_info = NULL;
190
191         BT_DBG("-");
192 } */
193
194 gboolean _bt_is_device_creating(void)
195 {
196         return is_device_creating;
197 }
198
199 gboolean _bt_is_bonding_device_address(const char *address)
200 {
201         if (bonding_info == NULL || bonding_info->addr == NULL)
202                 return FALSE;
203
204         if (g_strcmp0(bonding_info->addr, address) == 0) {
205                 BT_DBG("[%s]  is bonding device", address);
206                 return TRUE;
207         }
208
209         BT_DBG("[%s]  is NOT bonding device", address);
210         return FALSE;
211 }
212
213 void _bt_set_autopair_status_in_bonding_info(gboolean is_autopair)
214 {
215         ret_if(bonding_info == NULL);
216         bonding_info->is_autopair = is_autopair;
217 }
218
219 void __bt_cancel_search_service_done(void)
220 {
221         int result = BLUETOOTH_ERROR_CANCEL_BY_USER;
222         request_info_t *req_info;
223         bluetooth_device_info_t dev_info;
224         GVariant *out_param1;
225
226         ret_if(searching_info == NULL);
227
228         req_info = _bt_get_request_info(searching_info->req_id);
229         if (req_info == NULL) {
230                 BT_ERR("req_info == NULL");
231                 goto done;
232         }
233
234         if (req_info->context == NULL)
235                 goto done;
236
237         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
238         _bt_convert_addr_string_to_type(dev_info.device_address.addr,
239                                         searching_info->addr);
240
241         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
242                 &dev_info, sizeof(bluetooth_device_info_t), TRUE, NULL, NULL);
243
244
245         g_dbus_method_invocation_return_value(req_info->context,
246                         g_variant_new("(iv)", result, out_param1));
247
248         _bt_delete_request_list(req_info->req_id);
249
250 done:
251
252         g_free(searching_info->addr);
253         g_free(searching_info);
254         searching_info = NULL;
255 }
256
257 static void __bt_get_uuids(GVariant *value, bt_remote_dev_info_t *info)
258 {
259         ret_if(value == NULL);
260         ret_if(info == NULL);
261
262         gsize uuid_count = 0;
263
264         info->uuids = g_variant_dup_strv(value, &uuid_count);
265         info->uuid_count = (unsigned int)uuid_count;
266
267         BT_DBG("uuid count : %d", uuid_count);
268 }
269
270 bt_remote_dev_info_t *_bt_get_remote_device_info(char *address)
271 {
272         char *object_path = NULL;
273         bt_remote_dev_info_t *dev_info;
274
275         retv_if(address == NULL, NULL);
276
277         object_path = _bt_get_device_object_path(address);
278         retv_if(object_path == NULL, NULL);
279
280         dev_info = _bt_get_remote_device_info_by_object_path(object_path);
281
282         g_free(object_path);
283         return dev_info;
284 }
285
286 bt_remote_dev_info_t *_bt_get_remote_device_info_by_object_path(
287                                                         const char *object_path)
288 {
289         bt_remote_dev_info_t *dev_info;
290         GDBusProxy *adapter_proxy;
291         GDBusProxy *device_proxy;
292         GVariant *value;
293         GVariant *tmp_value;
294         gchar *name;
295         gchar * address;
296         GDBusConnection *conn;
297         GError *error = NULL;
298         GVariant *result = NULL;
299         GVariantIter *value_iter;
300         guint8 m_value;
301         int i = 0;
302
303         adapter_proxy = _bt_get_adapter_proxy();
304         retv_if(adapter_proxy == NULL, NULL);
305
306         retv_if(object_path == NULL, NULL);
307
308         conn = _bt_gdbus_get_system_gconn();
309         if (conn == NULL) {
310                 BT_ERR("conn == NULL");
311                 return NULL;
312         }
313
314         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
315                                         NULL, BT_BLUEZ_NAME, object_path,
316                                         BT_PROPERTIES_INTERFACE,  NULL, NULL);
317
318         retv_if(device_proxy == NULL, NULL);
319
320         result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
321                                 g_variant_new("(s)", BT_DEVICE_INTERFACE),
322                                 G_DBUS_CALL_FLAGS_NONE,
323                                 -1,
324                                 NULL,
325                                 &error);
326
327         g_object_unref(device_proxy);
328
329         dev_info = g_malloc0(sizeof(bt_remote_dev_info_t));
330
331         if (result != NULL) {
332                 g_variant_get(result , "(@a{sv})", &value);
333                 g_variant_unref(result);
334
335                 tmp_value = g_variant_lookup_value(value, "Alias", G_VARIANT_TYPE_STRING);
336
337                 g_variant_get(tmp_value, "s", &name);
338                 g_variant_unref(tmp_value);
339                 if (name != NULL)
340                         DBG_SECURE("Alias Name [%s]", name);
341                 else {
342                         tmp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
343                         g_variant_get(tmp_value, "s", &name);
344                         g_variant_unref(tmp_value);
345                 }
346
347                 tmp_value = g_variant_lookup_value(value, "IsAliasSet", G_VARIANT_TYPE_BOOLEAN);
348                 if (tmp_value) {
349                         dev_info->is_alias_set = g_variant_get_boolean(tmp_value);
350                         g_variant_unref(tmp_value);
351                 } else {
352                         dev_info->is_alias_set = FALSE;
353                 }
354                 BT_DBG("IsAliasSet: [%s]", dev_info->is_alias_set ? "TRUE" : "FALSE");
355
356                 tmp_value = g_variant_lookup_value(value, "Class", G_VARIANT_TYPE_UINT32);
357                 if (tmp_value) {
358                         dev_info->class = g_variant_get_uint32(tmp_value);
359                         g_variant_unref(tmp_value);
360                 } else
361                         dev_info->class = 0;
362
363                 tmp_value = g_variant_lookup_value(value, "Connected",  G_VARIANT_TYPE_BYTE);
364                 if (tmp_value) {
365                         dev_info->connected = g_variant_get_byte(tmp_value);
366                         g_variant_unref(tmp_value);
367                 } else
368                         dev_info->connected = BLUETOOTH_CONNECTED_LINK_NONE;
369                 BT_DBG("connected link : %d", dev_info->connected);
370
371                 tmp_value = g_variant_lookup_value(value, "Trusted",  G_VARIANT_TYPE_BOOLEAN);
372                 if (tmp_value) {
373                         dev_info->trust = g_variant_get_boolean(tmp_value);
374                         g_variant_unref(tmp_value);
375                 } else
376                         dev_info->trust = FALSE;
377
378                 tmp_value = g_variant_lookup_value(value, "Paired",  G_VARIANT_TYPE_BOOLEAN);
379                 if (tmp_value) {
380                         dev_info->paired = g_variant_get_boolean(tmp_value);
381                         g_variant_unref(tmp_value);
382                 } else
383                         dev_info->paired = FALSE;
384
385                 tmp_value = g_variant_lookup_value(value, "RSSI", G_VARIANT_TYPE_INT16);
386                 if (tmp_value) {
387                         dev_info->rssi = g_variant_get_int16(tmp_value);
388                         g_variant_unref(tmp_value);
389                 } else
390                         dev_info->rssi = 0;
391
392                 tmp_value = g_variant_lookup_value(value, "LastAddrType", G_VARIANT_TYPE_BYTE);
393                 if (tmp_value) {
394                         dev_info->addr_type = g_variant_get_byte(tmp_value);
395                         g_variant_unref(tmp_value);
396                 } else
397                         dev_info->addr_type = 0;
398
399                 tmp_value = g_variant_lookup_value(value, "UUIDs", G_VARIANT_TYPE_STRING_ARRAY);
400                 if (tmp_value) {
401                         __bt_get_uuids(tmp_value, dev_info);
402                         g_variant_unref(tmp_value);
403                 }
404
405                 tmp_value = g_variant_lookup_value(value, "ManufacturerDataLen", G_VARIANT_TYPE_UINT16);
406                 if (tmp_value) {
407                         dev_info->manufacturer_data_len = g_variant_get_uint16(tmp_value);
408                         if (dev_info->manufacturer_data_len > BLUETOOTH_MANUFACTURER_DATA_LENGTH_MAX) {
409                                 BT_ERR("manufacturer_data_len is too long(len = %d)", dev_info->manufacturer_data_len);
410                                 dev_info->manufacturer_data_len = BLUETOOTH_MANUFACTURER_DATA_LENGTH_MAX;
411                         }
412                         g_variant_unref(tmp_value);
413                 } else
414                         dev_info->manufacturer_data_len = 0;
415
416                 tmp_value = g_variant_lookup_value(value, "ManufacturerData", G_VARIANT_TYPE_ARRAY);
417                 if (tmp_value) {
418                         if ((dev_info->manufacturer_data_len == 0) ||
419                                         dev_info->manufacturer_data_len != g_variant_get_size(tmp_value)) {
420                                 BT_ERR("manufacturer data length doesn't match");
421                                 dev_info->manufacturer_data_len = 0;
422                                 dev_info->manufacturer_data = NULL;
423                         } else {
424                                 dev_info->manufacturer_data = g_malloc0(dev_info->manufacturer_data_len);
425                                 g_variant_get(tmp_value, "ay", &value_iter);
426                                 while (g_variant_iter_loop(value_iter, "y", &m_value))
427                                         dev_info->manufacturer_data[i++] = m_value;
428                         }
429                         g_variant_unref(tmp_value);
430                 } else {
431                         BT_INFO("manufacture data is not a G_VARIANT_TYPE_ARRAY ");
432                         dev_info->manufacturer_data_len = 0;
433                         dev_info->manufacturer_data = NULL;
434                 }
435
436                 tmp_value = g_variant_lookup_value(value, "Address", G_VARIANT_TYPE_STRING);
437                 g_variant_get(tmp_value, "s", &address);
438                 g_variant_unref(tmp_value);
439
440                 dev_info->address = g_strdup(address);
441                 dev_info->name = g_strdup(name);
442                 g_free(name);
443                 g_variant_unref(value);
444         } else {
445                 BT_ERR("result  is NULL\n");
446                 g_free(dev_info);
447                 dev_info = NULL;
448         }
449
450         return dev_info;
451 }
452
453 char *_bt_get_bonded_device_name(char *address)
454 {
455         bluetooth_device_address_t device_address = { {0} };
456         bluetooth_device_info_t dev_info;
457
458         retv_if(address == NULL, strdup(""));
459
460         _bt_convert_addr_string_to_type(device_address.addr, address);
461
462         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
463
464         _bt_get_bonded_device_info(&device_address, &dev_info);
465
466         return g_strdup(dev_info.device_name.name);
467 }
468
469 static gboolean __ignore_auto_pairing_request(const char *address)
470 {
471         gchar *buffer;
472         char **lines;
473         int i;
474         char lap_address[BT_LOWER_ADDRESS_LENGTH + 1] = {0,};
475         char *temp_buffer;
476         FILE *fp;
477         long size;
478         size_t result;
479
480         BT_DBG("+\n");
481
482         if (address == NULL)
483                 return FALSE;
484
485         /* Get the LAP(Lower Address part) */
486         /* User BT_LOWER_ADDRESS_LENGTH+1 for lap_address to accomodate
487              a "," */
488         snprintf(lap_address, sizeof(lap_address), ",%s", address);
489
490         fp = fopen(BT_AGENT_AUTO_PAIR_BLACKLIST_FILE, "r");
491
492         if (fp == NULL) {
493                 BT_ERR("fopen failed \n");
494                 return FALSE;
495         }
496
497         fseek(fp, 0, SEEK_END);
498         size = ftell(fp);
499         rewind(fp);
500
501         if (size < 0) {
502                 BT_ERR("Get file size failed \n");
503                 fclose(fp);
504                 return FALSE;
505         }
506
507         buffer = g_malloc0(sizeof(char) * size);
508         result = fread((char *)buffer, 1, size, fp);
509         fclose(fp);
510         if (result != size) {
511                 BT_ERR("Read Error\n");
512                 g_free(buffer);
513                 return FALSE;
514         }
515
516         BT_DBG("Buffer = %s\n", buffer);
517
518         lines = g_strsplit_set(buffer, BT_AGENT_NEW_LINE, 0);
519         g_free(buffer);
520
521         if (lines == NULL)
522                 return FALSE;
523
524         /* Write the data and insert new device data */
525         for (i = 0; lines[i] != NULL; i++) {
526                 if (g_str_has_prefix(lines[i], "AddressBlacklist")) {
527                         temp_buffer = g_strconcat(lines[i], lap_address, NULL);
528                         g_free(lines[i]);
529                         lines[i] = temp_buffer;
530                 }
531         }
532         buffer = g_strjoinv(BT_AGENT_NEW_LINE, lines);
533         g_strfreev(lines);
534         /* Fix : NULL_RETURNS */
535         retv_if(buffer == NULL, FALSE);
536
537         fp = fopen(BT_AGENT_AUTO_PAIR_BLACKLIST_FILE, "w");
538
539         if (fp == NULL) {
540                 BT_ERR("fopen failed \n");
541                 g_free(buffer);
542                 return FALSE;
543         }
544
545         BT_DBG("Buffer = %s\n", buffer);
546         fwrite(buffer, 1, strlen(buffer), fp);
547         fclose(fp);
548
549         g_free(buffer);
550
551         BT_DBG("-\n");
552
553         return FALSE;
554 }
555
556 static int __bt_cancel_bonding(void)
557 {
558         BT_CHECK_PARAMETER(bonding_info, return);
559         BT_CHECK_PARAMETER(bonding_info->addr, return);
560         /* First Cancel the ongoing pairing in bluez otherwise if we send
561          * pair request bluez will send inprogress and we again retry bond so
562          * this cycle continues */
563          GError *err = NULL;
564         g_dbus_proxy_call_sync(bonding_info->device_proxy, "CancelPairing",
565                         NULL, G_DBUS_CALL_FLAGS_NONE,
566                         10000, NULL, &err);
567         if (err) {
568                 BT_ERR("Cancelling bonding request error msg (%s)", err->message);
569                 g_clear_error(&err);
570                 return BLUETOOTH_ERROR_PARING_FAILED;
571         }
572         return BLUETOOTH_ERROR_NONE;
573 }
574
575 static int __bt_retry_bond(void)
576 {
577         BT_CHECK_PARAMETER(bonding_info, return);
578         BT_CHECK_PARAMETER(bonding_info->addr, return);
579
580         g_dbus_proxy_call(bonding_info->device_proxy, "Pair",
581                                 g_variant_new("(y)", bonding_info->conn_type),
582                                 G_DBUS_CALL_FLAGS_NONE,
583                                 BT_MAX_DBUS_TIMEOUT,
584                                 NULL,
585                                 (GAsyncReadyCallback)__bt_bond_device_cb,
586                                 NULL);
587
588         return BLUETOOTH_ERROR_NONE;
589 }
590
591
592 static int __bt_remove_and_bond(void)
593 {
594         GDBusProxy *adapter_proxy;
595         GVariant *result = NULL;
596         GError *err = NULL;
597         char *device_path = NULL;
598
599         BT_CHECK_PARAMETER(bonding_info, return);
600         BT_CHECK_PARAMETER(bonding_info->addr, return);
601
602         adapter_proxy = _bt_get_adapter_proxy();
603         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
604
605         result = g_dbus_proxy_call_sync(adapter_proxy, "FindDevice",
606                                 g_variant_new("(s)", bonding_info->addr),
607                                 G_DBUS_CALL_FLAGS_NONE,
608                                 -1,
609                                 NULL,
610                                 NULL);
611         if (result == NULL)
612                 return BLUETOOTH_ERROR_INTERNAL;
613
614         g_variant_get(result , "(o)", &device_path);
615         g_variant_unref(result);
616
617         retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL);
618
619         result = g_dbus_proxy_call_sync(adapter_proxy, "UnpairDevice",
620                                 g_variant_new("(o)", device_path),
621                                 G_DBUS_CALL_FLAGS_NONE,
622                                 -1,
623                                 NULL,
624                                 &err);
625         g_free(device_path);
626         if (err != NULL) {
627                 BT_ERR("UnpairDevice Fail: %s", err->message);
628                 g_error_free(err);
629                 return BLUETOOTH_ERROR_INTERNAL;
630         }
631
632         return __bt_retry_bond();
633 }
634
635 static int __bt_cancel_and_bond(void)
636 {
637         int ret = BLUETOOTH_ERROR_NONE;
638
639         ret = _bt_agent_reply_cancellation();
640         if (ret != BLUETOOTH_ERROR_NONE) {
641                 BT_ERR("Fail to call reply cancellation");
642                 return ret;
643         }
644         return __bt_retry_bond();
645 }
646
647
648 static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res,
649                                         gpointer user_data)
650 {
651         int result = BLUETOOTH_ERROR_NONE;
652         GError *err = NULL;
653         GVariant *reply;
654         GVariant *out_param1;
655         request_info_t *req_info;
656         bluetooth_device_info_t dev_info;
657         bt_remote_dev_info_t *remote_dev_info;
658         GVariant *manufacture_data;
659         GVariant *param;
660
661         /* Terminate ALL system popup */
662         if (headed_plugin_info->plugin_headed_enabled)
663                 headed_plugin_info->headed_plugin->bt_destroy_popup_all();
664
665         reply = g_dbus_proxy_call_finish(proxy, res, &err);
666         if (reply)
667                 g_variant_unref(reply);
668
669         is_device_creating = FALSE;
670
671         if (bonding_info == NULL) {
672                 /* Send reply */
673                 BT_ERR("bonding_info == NULL");
674                 if (err)
675                         g_error_free(err);
676                 return;
677         }
678
679         req_info = _bt_get_request_info(bonding_info->req_id);
680         if (req_info == NULL) {
681                 BT_ERR("req_info == NULL");
682                 goto done;
683         }
684
685         if (err != NULL) {
686                 g_dbus_error_strip_remote_error(err);
687                 BT_ERR("Error occured in CreateBonding [%s]", err->message);
688
689                 if (g_strrstr(err->message, "Already Exists")) {
690                         BT_INFO("Existing Bond, remove and retry");
691                         ret_if(__bt_remove_and_bond() == BLUETOOTH_ERROR_NONE);
692
693                         result = BLUETOOTH_ERROR_PARING_FAILED;
694                 } else if (_bt_agent_is_canceled() ||
695                         g_strrstr(err->message, "Authentication Canceled")) {
696                         BT_INFO("Cancelled by USER");
697                         result = BLUETOOTH_ERROR_CANCEL_BY_USER;
698                 } else if (g_strrstr(err->message, "Authentication Rejected")) {
699                         BT_INFO("REJECTED");
700                         result = BLUETOOTH_ERROR_ACCESS_DENIED;
701                 } else if (g_strrstr(err->message, "In Progress")) {
702                         BT_INFO("Bond in progress, cancel and retry");
703                         ret_if(__bt_cancel_and_bond() == BLUETOOTH_ERROR_NONE);
704
705                         result = BLUETOOTH_ERROR_PARING_FAILED;
706                 } else if (g_strrstr(err->message, "Authentication Failed")) {
707                         BT_INFO("Authentication Failed");
708                         if (bonding_info->is_autopair == TRUE) {
709                                 _bt_set_autopair_status_in_bonding_info(FALSE);
710                                 __ignore_auto_pairing_request(bonding_info->addr);
711                         }
712                         result = BLUETOOTH_ERROR_AUTHENTICATION_FAILED;
713                 } else if (g_strrstr(err->message, "Page Timeout")) {
714                         BT_INFO("Page Timeout");
715                         /* This is the special case
716                              As soon as call bluetooth_bond_device, try to cancel bonding.
717                              In this case, before completing to call 'CreatePairedDevice' method
718                              the procedure is stopped. So 'Cancle' error is not return.
719                         */
720                         result = BLUETOOTH_ERROR_HOST_DOWN;
721                 } else if (g_strrstr(err->message, BT_DBUS_TIMEOUT_MESSAGE)) {
722                         BT_INFO("Cancel already running bonding");
723                         if (__bt_cancel_bonding() != BLUETOOTH_ERROR_NONE) {
724                                 BT_INFO("Error while Cancelling bonding");
725                                 /* we need to unref proxy so continue */
726                         }
727                         result = BLUETOOTH_ERROR_INTERNAL;
728                 } else if (g_strrstr(err->message, "Connection Timeout")) {
729                         /* Pairing request timeout */
730                         result = BLUETOOTH_ERROR_TIMEOUT;
731                 } else if (g_strrstr(err->message, "Authentication Timeout")) {
732                         /* Pairing request timeout */
733                         result = BLUETOOTH_ERROR_TIMEOUT;
734                 } else {
735                         BT_DBG("Default case");
736                         result = BLUETOOTH_ERROR_PARING_FAILED;
737                 }
738         }
739
740         if (result == BLUETOOTH_ERROR_PARING_FAILED ||
741                         result == BLUETOOTH_ERROR_AUTHENTICATION_FAILED ||
742                         result == BLUETOOTH_ERROR_TIMEOUT ||
743                         result == BLUETOOTH_ERROR_HOST_DOWN) {
744                 if (TIZEN_PROFILE_WEARABLE) {
745                         int is_sw_running = 0;
746
747                         if (vconf_get_int(VCONFKEY_SETUP_WIZARD_STATE, &is_sw_running))
748                                 BT_ERR("vconf_get_int for setup wizard state failed");
749
750                         if (!is_sw_running) {
751                                 if (headed_plugin_info->plugin_headed_enabled)
752                                         headed_plugin_info->headed_plugin->bt_launch_unable_to_pairing_syspopup(result);
753                         } else {
754                                 BT_ERR("Unable to pair");
755                         }
756                 }
757                 bonding_info->result = result;
758         }
759
760         g_object_unref(proxy);
761         bonding_info->device_proxy = NULL;
762
763         if (result != BLUETOOTH_ERROR_NONE) {
764                 if (bonding_info->bonding_wo_discovery) {
765                         GDBusProxy *adapter_proxy;
766                         GVariant *ret = NULL;
767                         GError *error = NULL;
768                         char *device_path;
769
770                         BT_ERR("Bond was tried without discovery. Remove it");
771
772                         adapter_proxy = _bt_get_adapter_proxy();
773                         if (adapter_proxy == NULL) {
774                                 BT_ERR("Cannot get adapter_proxy");
775                                 goto dbus_return;
776                         }
777
778                         device_path = _bt_get_device_object_path(bonding_info->addr);
779                         if (device_path == NULL) {
780                                 BT_ERR("Cannot get device path");
781                                 goto dbus_return;
782                         }
783
784                         ret = g_dbus_proxy_call_sync(adapter_proxy,
785                                         "RemoveDevice",
786                                         g_variant_new("(o)", device_path),
787                                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
788                                         &error);
789                         if (error != NULL) {
790                                 BT_ERR("RemoveDevice Fail: %s", error->message);
791                                 g_clear_error(&error);
792                         }
793
794                         if (ret)
795                                 g_variant_unref(ret);
796
797                         g_free(device_path);
798                 }
799
800                 goto dbus_return;
801         }
802
803         remote_dev_info = _bt_get_remote_device_info(bonding_info->addr);
804         if (!remote_dev_info)
805                 goto dbus_return;
806
807         GVariant *uuids = NULL;
808         GVariantBuilder *builder = NULL;
809         int i = 0;
810         builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
811         for (i = 0; i < remote_dev_info->uuid_count; i++) {
812                 g_variant_builder_add(builder, "s",
813                         remote_dev_info->uuids[i]);
814         }
815         uuids = g_variant_new("as", builder);
816         g_variant_builder_unref(builder);
817         manufacture_data = g_variant_new_from_data((const GVariantType *)"ay",
818                                                 remote_dev_info->manufacturer_data, remote_dev_info->manufacturer_data_len,
819                                                 TRUE, NULL, NULL);
820
821         param = g_variant_new("(isunsbub@asn@ay)",
822                         result,
823                         bonding_info->addr,
824                         remote_dev_info->class,
825                         remote_dev_info->rssi,
826                         remote_dev_info->name,
827                         remote_dev_info->paired,
828                         remote_dev_info->connected,
829                         remote_dev_info->trust,
830                         uuids,
831                         remote_dev_info->manufacturer_data_len,
832                         manufacture_data);
833
834
835         /* Send the event to application */
836         _bt_send_event(BT_ADAPTER_EVENT,
837                 BLUETOOTH_EVENT_BONDING_FINISHED,
838                 param);
839
840         _bt_free_device_info(remote_dev_info);
841
842 dbus_return:
843         if (req_info->context == NULL)
844                 goto done;
845
846         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
847         _bt_convert_addr_string_to_type(dev_info.device_address.addr,
848                                         bonding_info->addr);
849
850         if (_bt_adapter_get_status() != BT_ACTIVATED)
851                 result = BLUETOOTH_ERROR_NOT_IN_OPERATION;
852
853         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
854                 &dev_info, sizeof(bluetooth_device_info_t), TRUE, NULL, NULL);
855
856         g_dbus_method_invocation_return_value(req_info->context,
857                         g_variant_new("(iv)", result, out_param1));
858
859         g_variant_unref(out_param1);
860
861         _bt_delete_request_list(req_info->req_id);
862 done:
863         if (err)
864                 g_error_free(err);
865
866         _bt_agent_set_canceled(FALSE);
867
868
869         g_free(bonding_info->addr);
870         g_free(bonding_info);
871         bonding_info = NULL;
872 }
873
874 int _bt_bond_device(int request_id,
875                 bluetooth_device_address_t *device_address,
876                 unsigned short conn_type, GArray **out_param1)
877 {
878         GDBusProxy *proxy;
879         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
880         bluetooth_device_info_t dev_info;
881
882         GDBusConnection *conn;
883         char *device_path = NULL;
884         GDBusProxy *adapter_proxy;
885         GError *error = NULL;
886         gboolean bonding_wo_discovery = FALSE;
887
888         BT_CHECK_PARAMETER(device_address, return);
889
890         if (bonding_info) {
891                 BT_ERR("Bonding in progress");
892
893                 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
894                 memcpy(dev_info.device_address.addr, device_address->addr,
895                                 BLUETOOTH_ADDRESS_LENGTH);
896
897                 g_array_append_vals(*out_param1, &dev_info,
898                                 sizeof(bluetooth_device_info_t));
899
900                 return BLUETOOTH_ERROR_DEVICE_BUSY;
901         }
902
903         conn = _bt_gdbus_get_system_gconn();
904         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
905
906         _bt_convert_addr_type_to_string(address, device_address->addr);
907
908         device_path = _bt_get_device_object_path(address);
909
910         if (device_path == NULL) {
911                 BT_ERR("No searched device");
912                 GVariant *ret = NULL;
913                 adapter_proxy = _bt_get_adapter_proxy();
914                 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
915
916                 ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
917                                         g_variant_new("(s)", address),
918                                         G_DBUS_CALL_FLAGS_NONE,
919                                         -1,
920                                         NULL,
921                                         &error);
922
923                 if (error != NULL) {
924                         BT_ERR("CreateDevice Fail: %s", error->message);
925                         g_clear_error(&error);
926                 }
927                 if (ret)
928                         g_variant_unref(ret);
929                 device_path = _bt_get_device_object_path(address);
930                 if (device_path == NULL) {
931                         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
932                         memcpy(dev_info.device_address.addr, device_address->addr,
933                                         BLUETOOTH_ADDRESS_LENGTH);
934
935                         g_array_append_vals(*out_param1, &dev_info,
936                                         sizeof(bluetooth_device_info_t));
937
938                         return BLUETOOTH_ERROR_NOT_PAIRED;
939                 } else {
940                         BT_INFO("device_path is created[%s]", device_path);
941                 }
942                 bonding_wo_discovery = TRUE;
943         }
944
945         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
946                                                                 NULL, BT_BLUEZ_NAME,
947                                                                 device_path, BT_DEVICE_INTERFACE,  NULL, NULL);
948
949         g_free(device_path);
950         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
951
952         bonding_info = g_malloc0(sizeof(bt_funcion_data_t));
953         bonding_info->addr = g_strdup(address);
954         bonding_info->req_id = request_id;
955
956         bonding_info->device_proxy = proxy;
957         bonding_info->conn_type = conn_type;
958         bonding_info->bonding_wo_discovery = bonding_wo_discovery;
959
960         is_device_creating = TRUE;
961
962         g_dbus_proxy_call(proxy, "Pair",
963                                 g_variant_new("(y)", conn_type),
964                                 G_DBUS_CALL_FLAGS_NONE,
965                                 BT_MAX_DBUS_TIMEOUT,
966                                 NULL,
967                                 (GAsyncReadyCallback)__bt_bond_device_cb,
968                                 NULL);
969
970 /* TODO: We need to check if we can pair the specific device using 'pair' API of bluez 5.x */
971
972         return BLUETOOTH_ERROR_NONE;
973 /*fail:
974         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
975         _bt_convert_addr_string_to_type(dev_info.device_address.addr,
976                                         bonding_info->addr);
977
978         g_array_append_vals(*out_param1, &dev_info,
979                                 sizeof(bluetooth_device_info_t));
980
981         is_device_creating = FALSE;
982
983         g_free(bonding_info->addr);
984         g_free(bonding_info);
985         bonding_info = NULL;
986
987         return BLUETOOTH_ERROR_INTERNAL;*/
988 }
989
990 int _bt_cancel_bonding(void)
991 {
992         int ret = BLUETOOTH_ERROR_NONE;
993
994         retv_if(bonding_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
995
996         ret = _bt_agent_reply_cancellation();
997         if (ret != BLUETOOTH_ERROR_NONE) {
998                 BT_ERR("Fail to call reply cancellation");
999                 return ret;
1000         }
1001
1002         _bt_agent_set_canceled(TRUE);
1003
1004         return BLUETOOTH_ERROR_NONE;
1005 }
1006
1007 static void __bt_unbond_cb(GDBusProxy *proxy, GAsyncResult *res,
1008                                         gpointer user_data)
1009 {
1010         GError *err = NULL;
1011         GVariant *reply;
1012         GVariant *out_param1;
1013         int result = BLUETOOTH_ERROR_NONE;
1014         bt_funcion_data_t *unbonding_info;
1015         bluetooth_device_info_t dev_info;
1016         request_info_t *req_info;
1017
1018         reply = g_dbus_proxy_call_finish(proxy, res, &err);
1019         if (reply)
1020                 g_variant_unref(reply);
1021
1022         unbonding_info = user_data;
1023
1024         if (unbonding_info == NULL) {
1025                 /* Send reply */
1026                 BT_ERR("unbonding_info == NULL");
1027                 goto done;
1028         }
1029
1030         req_info = _bt_get_request_info(unbonding_info->req_id);
1031         if (req_info == NULL) {
1032                 BT_ERR("req_info == NULL");
1033                 goto done;
1034         }
1035
1036         if (err != NULL) {
1037                 BT_ERR("Error occured in RemoveBonding [%s]\n", err->message);
1038                 result = BLUETOOTH_ERROR_INTERNAL;
1039         }
1040
1041         if (req_info->context == NULL)
1042                 goto done;
1043
1044         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
1045         _bt_convert_addr_string_to_type(dev_info.device_address.addr,
1046                                         unbonding_info->addr);
1047
1048         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
1049                 &dev_info, sizeof(bluetooth_device_info_t), TRUE, NULL, NULL);
1050
1051         g_dbus_method_invocation_return_value(req_info->context,
1052                         g_variant_new("(iv)", result, out_param1));
1053
1054
1055         _bt_delete_request_list(req_info->req_id);
1056
1057 done:
1058         if (err)
1059                 g_error_free(err);
1060
1061         if (unbonding_info) {
1062                 g_free(unbonding_info->addr);
1063                 g_free(unbonding_info);
1064         }
1065 }
1066
1067 int _bt_unbond_device(int request_id,
1068                         bluetooth_device_address_t *device_address,
1069                         GArray **out_param1)
1070 {
1071         char *device_path = NULL;
1072         bt_funcion_data_t *unbonding_info;
1073         GDBusProxy *adapter_proxy = NULL;
1074         GDBusProxy *device_proxy = NULL;
1075         GDBusConnection *conn;
1076         int result = BLUETOOTH_ERROR_INTERNAL;
1077         bluetooth_device_info_t dev_info;
1078         GError *error = NULL;
1079         GVariant *ret = NULL;
1080
1081         BT_CHECK_PARAMETER(device_address, return);
1082
1083         adapter_proxy = _bt_get_adapter_proxy();
1084         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1085
1086         /* allocate user data so that it can be retrieved in callback */
1087         unbonding_info = g_malloc0(sizeof(bt_funcion_data_t));
1088         unbonding_info->addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
1089         unbonding_info->req_id = request_id;
1090
1091         _bt_convert_addr_type_to_string(unbonding_info->addr,
1092                                         device_address->addr);
1093
1094         device_path = _bt_get_device_object_path(unbonding_info->addr);
1095
1096         if (device_path == NULL) {
1097                 BT_ERR("No paired device");
1098                 result = BLUETOOTH_ERROR_NOT_PAIRED;
1099                 goto fail;
1100         }
1101
1102         conn = _bt_gdbus_get_system_gconn();
1103         if (conn == NULL) {
1104                 BT_ERR("conn is NULL");
1105                 result = BLUETOOTH_ERROR_INTERNAL;
1106                 goto fail;
1107         }
1108
1109         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1110                                                                 NULL, BT_BLUEZ_NAME,
1111                                                                 device_path, BT_PROPERTIES_INTERFACE,  NULL, NULL);
1112
1113         if (device_proxy != NULL) {
1114
1115                 ret = g_dbus_proxy_call_sync(device_proxy, "Get",
1116                                         g_variant_new("(ss)", BT_DEVICE_INTERFACE, "Paired"),
1117                                         G_DBUS_CALL_FLAGS_NONE,
1118                                         -1,
1119                                         NULL,
1120                                         &error);
1121                 if (error) {
1122                         BT_ERR("Getting property failed: [%s]\n", error->message);
1123                         g_error_free(error);
1124                         result = BLUETOOTH_ERROR_NOT_PAIRED;
1125                         goto fail;
1126                 } else {
1127                         if (!ret) {
1128                                 BT_ERR("No paired device");
1129                                 g_object_unref(device_proxy);
1130                                 result = BLUETOOTH_ERROR_NOT_PAIRED;
1131                                 goto fail;
1132                         }
1133                         g_variant_unref(ret);
1134                 }
1135                 g_object_unref(device_proxy);
1136         }
1137
1138         g_dbus_proxy_call(adapter_proxy, "UnpairDevice",
1139                                 g_variant_new("(o)", device_path),
1140                                 G_DBUS_CALL_FLAGS_NONE,
1141                                 BT_MAX_DBUS_TIMEOUT,
1142                                 NULL,
1143                                 (GAsyncReadyCallback)__bt_unbond_cb,
1144                                 unbonding_info);
1145
1146         g_free(device_path);
1147         return BLUETOOTH_ERROR_NONE;
1148
1149 fail:
1150         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
1151         _bt_convert_addr_string_to_type(dev_info.device_address.addr,
1152                                         unbonding_info->addr);
1153
1154         g_array_append_vals(*out_param1, &dev_info,
1155                                 sizeof(bluetooth_device_info_t));
1156         g_free(device_path);
1157         g_free(unbonding_info->addr);
1158         g_free(unbonding_info);
1159         return result;
1160 }
1161
1162 static void __bt_discover_cb(GDBusProxy *proxy, GAsyncResult *res,
1163                                         gpointer user_data)
1164 {
1165         GError *err = NULL;
1166         GVariant *reply;
1167         GVariant *out_param1;
1168         int result = BLUETOOTH_ERROR_NONE;
1169         bluetooth_device_info_t dev_info;
1170         bt_remote_dev_info_t *remote_dev_info;
1171         request_info_t *req_info;
1172         GVariant *uuid_list, *manufacture_data;
1173         GVariant *param;
1174         GVariantBuilder *builder = NULL;
1175         int i = 0;
1176
1177         reply = g_dbus_proxy_call_finish(proxy, res, &err);
1178         if (reply)
1179                 g_variant_unref(reply);
1180
1181         g_object_unref(proxy);
1182
1183         if (searching_info == NULL) {
1184                 /* Send reply */
1185                 BT_ERR("unbonding_info == NULL");
1186                 goto done;
1187         }
1188
1189         req_info = _bt_get_request_info(searching_info->req_id);
1190         if (req_info == NULL) {
1191                 BT_ERR("req_info == NULL");
1192                 goto done;
1193         }
1194
1195         if (err != NULL) {
1196                 g_dbus_error_strip_remote_error(err);
1197                 BT_ERR("Error occured in Proxy call [%s]\n", err->message);
1198
1199                 if (g_strrstr("Operation canceled", err->message))
1200                         result = BLUETOOTH_ERROR_CANCEL_BY_USER;
1201                 else if (g_strrstr("In Progress", err->message))
1202                         result = BLUETOOTH_ERROR_IN_PROGRESS;
1203                 else if (g_strrstr("Host is down", err->message))
1204                         result = BLUETOOTH_ERROR_HOST_DOWN;
1205                 else
1206                         result = BLUETOOTH_ERROR_CONNECTION_ERROR;
1207
1208                 if (result == BLUETOOTH_ERROR_HOST_DOWN ||
1209                      result == BLUETOOTH_ERROR_CONNECTION_ERROR) {
1210                         remote_dev_info = _bt_get_remote_device_info(searching_info->addr);
1211                         if (remote_dev_info && remote_dev_info->uuids != NULL &&
1212                              remote_dev_info->uuid_count > 0) {
1213                                 result = BLUETOOTH_ERROR_NONE;
1214                                 goto event;
1215                         }
1216                         _bt_free_device_info(remote_dev_info);
1217                 }
1218                 goto dbus_return;
1219         }
1220
1221         remote_dev_info = _bt_get_remote_device_info(searching_info->addr);
1222         if (!remote_dev_info)
1223                 goto dbus_return;
1224
1225 event:
1226         builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
1227         for (i = 0; i < remote_dev_info->uuid_count; i++) {
1228                 g_variant_builder_add(builder, "s",
1229                         remote_dev_info->uuids[i]);
1230         }
1231         uuid_list = g_variant_new("as", builder);
1232         g_variant_builder_unref(builder);
1233         manufacture_data = g_variant_new_from_data((const GVariantType *)"ay",
1234                                                 remote_dev_info->manufacturer_data, remote_dev_info->manufacturer_data_len,
1235                                                 TRUE, NULL, NULL);
1236
1237         param = g_variant_new("(isunsbub@asn@ay)",
1238                         result,
1239                         searching_info->addr,
1240                         remote_dev_info->class,
1241                         remote_dev_info->rssi,
1242                         remote_dev_info->name,
1243                         remote_dev_info->paired,
1244                         remote_dev_info->connected,
1245                         remote_dev_info->trust,
1246                         uuid_list,
1247                         remote_dev_info->manufacturer_data_len,
1248                         manufacture_data);
1249
1250         /* Send the event to application */
1251         _bt_send_event(BT_ADAPTER_EVENT,
1252                 BLUETOOTH_EVENT_SERVICE_SEARCHED,
1253                 param);
1254
1255         _bt_free_device_info(remote_dev_info);
1256
1257 dbus_return:
1258         if (req_info->context == NULL)
1259                 goto done;
1260
1261         memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
1262         _bt_convert_addr_string_to_type(dev_info.device_address.addr,
1263                                         searching_info->addr);
1264
1265         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
1266                 &dev_info, sizeof(bluetooth_device_info_t), TRUE, NULL, NULL);
1267
1268         g_dbus_method_invocation_return_value(req_info->context,
1269                         g_variant_new("(iv)", result, out_param1));
1270
1271
1272         _bt_delete_request_list(req_info->req_id);
1273 done:
1274         if (err)
1275                 g_error_free(err);
1276
1277         if (searching_info) {
1278                 g_free(searching_info->addr);
1279                 g_free(searching_info);
1280                 searching_info = NULL;
1281         }
1282 }
1283
1284 int _bt_search_device(int request_id,
1285                         bluetooth_device_address_t *device_address)
1286 {
1287         char *device_path = NULL;
1288         GDBusProxy *device_proxy = NULL;
1289         GDBusConnection *conn;
1290
1291         GDBusProxy *adapter_proxy;
1292         int result = BLUETOOTH_ERROR_INTERNAL;
1293
1294         BT_CHECK_PARAMETER(device_address, return);
1295
1296         if (bonding_info) {
1297                 BT_ERR("Bonding in progress");
1298                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1299         }
1300
1301         if (searching_info) {
1302                 BT_ERR("Service searching in progress");
1303                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1304         }
1305
1306         adapter_proxy = _bt_get_adapter_proxy();
1307         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1308
1309         /* allocate user data so that it can be retrieved in callback */
1310         searching_info = g_malloc0(sizeof(bt_funcion_data_t));
1311         searching_info->addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
1312         searching_info->req_id = request_id;
1313
1314         _bt_convert_addr_type_to_string(searching_info->addr,
1315                                         device_address->addr);
1316
1317         conn = _bt_gdbus_get_system_gconn();
1318         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1319
1320
1321         device_path = _bt_get_device_object_path(searching_info->addr);
1322
1323         if (device_path == NULL) {
1324                 BT_ERR("No paired device");
1325                 result = BLUETOOTH_ERROR_NOT_PAIRED;
1326                 goto fail;
1327         }
1328
1329         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1330                                                                 NULL, BT_BLUEZ_NAME,
1331                                                                 device_path, BT_DEVICE_INTERFACE,  NULL, NULL);
1332         g_free(device_path);
1333         if (device_proxy == NULL) {
1334                 result = BLUETOOTH_ERROR_INTERNAL;
1335                 goto fail;
1336         }
1337
1338         g_dbus_proxy_call(device_proxy, "DiscoverServices",
1339                         g_variant_new("(s)", ""),
1340                         G_DBUS_CALL_FLAGS_NONE,
1341                         BT_MAX_DBUS_TIMEOUT,
1342                         NULL,
1343                         (GAsyncReadyCallback)__bt_discover_cb,
1344                         searching_info);
1345
1346         searching_info->device_proxy = device_proxy;
1347
1348         return BLUETOOTH_ERROR_NONE;
1349 fail:
1350
1351         g_free(searching_info->addr);
1352         g_free(searching_info);
1353         searching_info = NULL;
1354         return result;
1355 }
1356
1357 int _bt_cancel_search_device(void)
1358 {
1359         GVariant *ret = NULL;
1360         GError *err = NULL;
1361
1362         retv_if(searching_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
1363
1364         if (searching_info->device_proxy) {
1365                 ret = g_dbus_proxy_call_sync(searching_info->device_proxy, "CancelDiscovery",
1366                                 NULL,
1367                                 G_DBUS_CALL_FLAGS_NONE,
1368                                 -1,
1369                                 NULL,
1370                                 &err);
1371                 if (ret)
1372                         g_variant_unref(ret);
1373         }
1374         __bt_cancel_search_service_done();
1375
1376         return BLUETOOTH_ERROR_NONE;
1377 }
1378
1379 int _bt_set_alias(bluetooth_device_address_t *device_address,
1380                                       const char *alias)
1381 {
1382         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1383         gchar *device_path = NULL;
1384         GDBusProxy *adapter_proxy;
1385         GDBusProxy *device_proxy;
1386         GVariant *ret = NULL;
1387         GError *error = NULL;
1388         GDBusConnection *conn;
1389
1390         BT_CHECK_PARAMETER(device_address, return);
1391         BT_CHECK_PARAMETER(alias, return);
1392
1393         adapter_proxy = _bt_get_adapter_proxy();
1394         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1395
1396         conn = _bt_gdbus_get_system_gconn();
1397         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1398
1399         _bt_convert_addr_type_to_string(address, device_address->addr);
1400
1401         device_path = _bt_get_device_object_path(address);
1402
1403         if (device_path == NULL) {
1404                 BT_ERR("No paired device");
1405                 return BLUETOOTH_ERROR_NOT_PAIRED;
1406         }
1407
1408         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1409                                                                 NULL, BT_BLUEZ_NAME,
1410                                                                 device_path, BT_PROPERTIES_INTERFACE,  NULL, NULL);
1411
1412         g_free(device_path);
1413         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1414
1415         ret = g_dbus_proxy_call_sync(device_proxy, "Set",
1416                                 g_variant_new("(ssv)", BT_DEVICE_INTERFACE,  "Alias", g_variant_new("s", alias)),
1417                                 G_DBUS_CALL_FLAGS_NONE,
1418                                 -1,
1419                                 NULL,
1420                                 &error);
1421         if (ret)
1422                 g_variant_unref(ret);
1423
1424         g_object_unref(device_proxy);
1425
1426         if (error) {
1427                  BT_ERR("SetProperty error: [%s]", error->message);
1428                  g_error_free(error);
1429                  return BLUETOOTH_ERROR_INTERNAL;
1430         }
1431
1432         return BLUETOOTH_ERROR_NONE;
1433 }
1434
1435 int _bt_set_authorization(bluetooth_device_address_t *device_address,
1436                                       gboolean authorize)
1437 {
1438         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1439         gchar *device_path = NULL;
1440         GDBusProxy *device_proxy;
1441         gboolean previous_value;
1442         GError *error = NULL;
1443         GDBusConnection *conn;
1444         GVariant *result = NULL;
1445         GVariant *temp = NULL;
1446         int ret = BLUETOOTH_ERROR_NONE;
1447
1448         BT_CHECK_PARAMETER(device_address, return);
1449
1450         conn = _bt_gdbus_get_system_gconn();
1451         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1452
1453         _bt_convert_addr_type_to_string(address, device_address->addr);
1454
1455         device_path = _bt_get_device_object_path(address);
1456
1457         if (device_path == NULL) {
1458                 BT_ERR("No paired device");
1459                 return BLUETOOTH_ERROR_NOT_PAIRED;
1460         }
1461
1462         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1463                                                                 NULL, BT_BLUEZ_NAME,
1464                                                                 device_path, BT_PROPERTIES_INTERFACE,  NULL, NULL);
1465
1466         g_free(device_path);
1467         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1468
1469         result = g_dbus_proxy_call_sync(device_proxy, "Get",
1470                                 g_variant_new("(ss)", BT_DEVICE_INTERFACE, "Trusted"),
1471                                 G_DBUS_CALL_FLAGS_NONE,
1472                                 -1,
1473                                 NULL,
1474                                 &error);
1475         if (error != NULL) {
1476                 BT_ERR("Getting property failed: [%s]\n", error->message);
1477                 g_error_free(error);
1478                 g_object_unref(device_proxy);
1479                 return BLUETOOTH_ERROR_INTERNAL;
1480         }
1481
1482         g_variant_get(result, "(v)", &temp);
1483         previous_value = g_variant_get_boolean(temp);
1484         g_variant_unref(temp);
1485         g_variant_unref(result);
1486         /* If the input is same with previous value, return error. */
1487         if (previous_value == authorize) {
1488                 BT_ERR("Same value: %d", previous_value);
1489                 g_object_unref(device_proxy);
1490                 ret = BLUETOOTH_ERROR_INVALID_PARAM;
1491                 goto done;
1492         }
1493
1494         result = g_dbus_proxy_call_sync(device_proxy, "Set",
1495                                  g_variant_new("(ssv)", BT_DEVICE_INTERFACE, "Trusted", g_variant_new("b", authorize)),
1496                                  G_DBUS_CALL_FLAGS_NONE,
1497                                  -1,
1498                                  NULL,
1499                                  &error);
1500
1501         g_object_unref(device_proxy);
1502         if (error) {
1503                  BT_ERR("SetProperty error: [%s]", error->message);
1504                  g_error_free(error);
1505                  ret = BLUETOOTH_ERROR_INTERNAL;
1506         }
1507 done:
1508         if (result)
1509                 g_variant_unref(result);
1510
1511         return ret;
1512 }
1513
1514 int _bt_is_gatt_connected(bluetooth_device_address_t *device_address,
1515                         gboolean *is_connected)
1516 {
1517         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1518         char *object_path = NULL;
1519
1520         GDBusProxy *device_proxy;
1521         GError *error = NULL;
1522         GVariant *value;
1523         GVariant *tmp_value;
1524         GDBusConnection *conn;
1525         GVariant *result = NULL;
1526         int ret = BLUETOOTH_ERROR_NONE;
1527
1528         BT_CHECK_PARAMETER(device_address, return);
1529
1530         conn = _bt_gdbus_get_system_gconn();
1531         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1532
1533         _bt_convert_addr_type_to_string(address, device_address->addr);
1534
1535         object_path = _bt_get_device_object_path(address);
1536         retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
1537
1538         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1539                         NULL, BT_BLUEZ_NAME, object_path,
1540                         BT_PROPERTIES_INTERFACE,  NULL, NULL);
1541         g_free(object_path);
1542         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1543
1544         result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
1545                         g_variant_new("(s)", BT_DEVICE_INTERFACE),
1546                         G_DBUS_CALL_FLAGS_NONE,
1547                         -1,
1548                         NULL,
1549                         &error);
1550         if (result == NULL) {
1551                 if (error != NULL) {
1552                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
1553                         g_error_free(error);
1554                 }
1555                 g_object_unref(device_proxy);
1556                 return BLUETOOTH_ERROR_INTERNAL;
1557         }
1558
1559         g_variant_get(result , "(@a{sv})", &value);
1560         g_variant_unref(result);
1561
1562         tmp_value = g_variant_lookup_value(value, "GattConnected", G_VARIANT_TYPE_BOOLEAN);
1563         if (tmp_value == NULL) {
1564                 g_object_unref(device_proxy);
1565                 g_variant_unref(value);
1566                 return BLUETOOTH_ERROR_INTERNAL;
1567         }
1568
1569         *is_connected = g_variant_get_boolean(tmp_value);
1570
1571         BT_DBG("gatt is connected : %d", *is_connected);
1572
1573         g_variant_unref(tmp_value);
1574         g_variant_unref(value);
1575         g_object_unref(device_proxy);
1576
1577         return ret;
1578 }
1579
1580 int _bt_is_device_connected(bluetooth_device_address_t *device_address,
1581                         int connection_type, gboolean *is_connected)
1582 {
1583         char *object_path = NULL;
1584         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1585         char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
1586         GDBusProxy *device_proxy = NULL;
1587         GDBusProxy *adapter_proxy = NULL;
1588         GDBusConnection *conn;
1589         GError *error = NULL;
1590         GVariant *tmp_value = NULL;
1591         GVariant *value = NULL;
1592         GVariant *result = NULL;
1593         char *uuid = NULL;
1594
1595         retv_if(device_address == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1596         retv_if(is_connected == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1597
1598         _bt_convert_addr_type_to_string(address, device_address->addr);
1599         _bt_convert_addr_string_to_secure_string(secure_address, address);
1600
1601         *is_connected = FALSE;
1602         BT_DBG("%s connection_type: 0x%02x", secure_address, connection_type);
1603
1604         if (connection_type == BLUETOOTH_RFCOMM_SERVICE)
1605                 return _bt_rfcomm_is_device_connected(device_address,
1606                                                 is_connected);
1607         else if (connection_type == BLUETOOTH_GATT_SERVICE)
1608                 return _bt_is_gatt_connected(device_address, is_connected);
1609         else if (connection_type == BLUETOOTH_PBAP_SERVICE)
1610                 return _bt_pbap_is_connected(device_address, is_connected);
1611
1612         adapter_proxy = _bt_get_adapter_proxy();
1613         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1614
1615         conn = _bt_gdbus_get_system_gconn();
1616         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1617
1618         _bt_convert_addr_type_to_string(address, device_address->addr);
1619
1620         if (connection_type == BLUETOOTH_NAP_SERVER_SERVICE) {
1621                 object_path = _bt_get_adapter_path();
1622                 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1623                                                                         NULL, BT_BLUEZ_NAME,
1624                                                                         object_path, BT_NETWORK_SERVER_INTERFACE,  NULL, NULL);
1625                 g_free(object_path);
1626                 if (device_proxy == NULL) {
1627                         BT_DBG("Device don't have this service");
1628                         return BLUETOOTH_ERROR_INTERNAL;
1629                 }
1630
1631                 result = g_dbus_proxy_call_sync(device_proxy, "GetProperties",
1632                                         g_variant_new("(s)", address),
1633                                         G_DBUS_CALL_FLAGS_NONE,
1634                                         -1,
1635                                         NULL,
1636                                         &error);
1637
1638                 if (result == NULL) {
1639                         BT_ERR("[GetProperties] Error occured in Proxy call");
1640                         if (error) {
1641                                 BT_ERR("%s", error->message);
1642                                 g_error_free(error);
1643                         }
1644                         *is_connected = FALSE;
1645                         g_object_unref(device_proxy);
1646                         return BLUETOOTH_ERROR_NONE;
1647                 }
1648                 g_variant_get(result , "(@a{sv})", &value);
1649                 g_variant_unref(result);
1650
1651                 if (value) {
1652                         tmp_value = g_variant_lookup_value(value,
1653                                                         "Connected",
1654                                                         G_VARIANT_TYPE_BOOLEAN);
1655                         if (tmp_value) {
1656                                 *is_connected = g_variant_get_boolean(tmp_value);
1657                                 g_variant_unref(tmp_value);
1658                         }
1659                         g_variant_unref(value);
1660                 }
1661         } else if (connection_type == BLUETOOTH_NAP_SERVICE) {
1662                 return _bt_is_network_connected(_bt_get_net_conn(),
1663                                                 device_address->addr, is_connected);
1664         } else {
1665                 uuid = _bt_get_profile_uuid128(connection_type);
1666                 if (uuid == NULL) {
1667                         BT_ERR("connection_type: %d, uuid is NULL", connection_type);
1668                         return BLUETOOTH_ERROR_INTERNAL;
1669                 }
1670                 BT_DBG("uuid %s [%s]", uuid, _bt_convert_uuid_to_string(uuid));
1671
1672                 object_path = _bt_get_device_object_path(address);
1673                 if (!object_path) {
1674                         BT_ERR("object_path is NULL");
1675                         g_free(uuid);
1676                         return BLUETOOTH_ERROR_NOT_PAIRED;
1677                 }
1678
1679                 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1680                                                                         NULL, BT_BLUEZ_NAME,
1681                                                                         object_path, BT_DEVICE_INTERFACE,  NULL, NULL);
1682                 g_free(object_path);
1683                 if (device_proxy == NULL) {
1684                         BT_DBG("Device don't have this service");
1685                         g_free(uuid);
1686                         return BLUETOOTH_ERROR_INTERNAL;
1687                 }
1688
1689                 result = g_dbus_proxy_call_sync(device_proxy, "IsConnectedProfile",
1690                                         g_variant_new("(s)", uuid),
1691                                         G_DBUS_CALL_FLAGS_NONE,
1692                                         -1,
1693                                         NULL,
1694                                         &error);
1695
1696                 if (result == NULL) {
1697                         BT_ERR("[IsConnectedProfile] Error occured in Proxy call");
1698                         if (error) {
1699                                 BT_ERR("%s", error->message);
1700                                 if (g_strrstr(error->message, "Not Connected"))
1701                                         BT_DBG("Not connected");
1702                                 g_error_free(error);
1703                         }
1704                         *is_connected = FALSE;
1705                         g_object_unref(device_proxy);
1706                         g_free(uuid);
1707                         return BLUETOOTH_ERROR_NONE;
1708                 }
1709                 g_variant_get(result, "(b)", is_connected);
1710                 g_free(uuid);
1711                 g_variant_unref(result);
1712         }
1713
1714         g_object_unref(device_proxy);
1715         return BLUETOOTH_ERROR_NONE;
1716 }
1717
1718 int _bt_get_connected_link(bluetooth_device_address_t *device_address,
1719                         bluetooth_connected_link_t *connected)
1720 {
1721         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1722         char *object_path = NULL;
1723
1724         GDBusProxy *device_proxy;
1725         GError *error = NULL;
1726         GDBusConnection *conn;
1727         GVariant *tmp_value = NULL;
1728         GVariant *value = NULL;
1729         GVariant *result = NULL;
1730
1731         BT_CHECK_PARAMETER(device_address, return);
1732
1733         conn = _bt_gdbus_get_system_gconn();
1734         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1735
1736         _bt_convert_addr_type_to_string(address, device_address->addr);
1737
1738         object_path = _bt_get_device_object_path(address);
1739         retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
1740
1741         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1742                                                                 NULL, BT_BLUEZ_NAME,
1743                                                                 object_path, BT_PROPERTIES_INTERFACE,  NULL, NULL);
1744         g_free(object_path);
1745         if (device_proxy == NULL) {
1746                 *connected = BLUETOOTH_CONNECTED_LINK_NONE;
1747                 return BLUETOOTH_ERROR_NONE;
1748         }
1749
1750         result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
1751                                         g_variant_new("(s)", BT_DEVICE_INTERFACE),
1752                                         G_DBUS_CALL_FLAGS_NONE,
1753                                         -1,
1754                                         NULL,
1755                                         &error);
1756
1757         if (error != NULL) {
1758                 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
1759                 g_error_free(error);
1760                 g_object_unref(device_proxy);
1761                 return BLUETOOTH_ERROR_INTERNAL;
1762         }
1763
1764         g_variant_get(result , "(@a{sv})", &value);
1765         g_variant_unref(result);
1766
1767         tmp_value = g_variant_lookup_value(value, "Connected", G_VARIANT_TYPE_BYTE);
1768         if (tmp_value != NULL) {
1769                 *connected = g_variant_get_byte(tmp_value);
1770                 g_variant_unref(tmp_value);
1771                 g_object_unref(device_proxy);
1772                 return BLUETOOTH_ERROR_NONE;
1773         } else  {
1774                 BT_ERR("g_variant value is NULL");
1775                 return BLUETOOTH_ERROR_INTERNAL;
1776         }
1777 }
1778
1779 static void __le_connection_req_cb(GDBusProxy *proxy, GAsyncResult *res,
1780                 gpointer user_data)
1781 {
1782         GError *err = NULL;
1783         GVariant *out_param1;
1784         GVariant *reply;
1785         int result = BLUETOOTH_ERROR_NONE;
1786         bt_function_data_t *func_data = user_data;
1787         request_info_t *req_info = NULL;
1788         bluetooth_device_address_t device_addr = { {0} };
1789
1790         reply = g_dbus_proxy_call_finish(proxy, res, &err);
1791         g_object_unref(proxy);
1792
1793         if (reply == NULL) {
1794                 BT_ERR("ConnectLE / DisconnectLE DBus call error");
1795                 if (err) {
1796                         BT_ERR("Error: %s", err->message);
1797                         g_clear_error(&err);
1798                 }
1799                 result = BLUETOOTH_ERROR_INTERNAL;
1800         } else {
1801                 g_variant_unref(reply);
1802         }
1803
1804         if (func_data == NULL) {
1805                 BT_ERR("func_data is NULL");
1806                 goto done;
1807         }
1808
1809         req_info = _bt_get_request_info(func_data->req_id);
1810         if (req_info == NULL) {
1811                 BT_ERR("req_info is NULL");
1812                 goto done;
1813         }
1814
1815         if (req_info->context == NULL) {
1816                 BT_ERR("req_info->context is NULL");
1817                 goto done;
1818         }
1819
1820         _bt_convert_addr_string_to_type(device_addr.addr,
1821                         (const char *)func_data->address);
1822
1823         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
1824                         &device_addr, sizeof(bluetooth_device_address_t), TRUE,
1825                         NULL, NULL);
1826
1827         g_dbus_method_invocation_return_value(req_info->context,
1828                         g_variant_new("(iv)", result, out_param1));
1829
1830 done:
1831         if (req_info)
1832                 _bt_delete_request_list(req_info->req_id);
1833
1834         if (func_data) {
1835                 g_free(func_data->address);
1836                 g_free(func_data);
1837         }
1838 }
1839
1840 static int __bt_connect_le_device_internal(int req_id, const bluetooth_device_address_t *bd_addr,
1841         gboolean auto_connect)
1842 {
1843         char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
1844         char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
1845         gchar *device_path = NULL;
1846         GDBusProxy *device_proxy = NULL;
1847         GDBusConnection *conn;
1848         int ret = BLUETOOTH_ERROR_NONE;
1849         bt_function_data_t *func_data;
1850
1851         BT_CHECK_PARAMETER(bd_addr, return);
1852
1853         conn = _bt_gdbus_get_system_gconn();
1854         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1855
1856         _bt_convert_addr_type_to_string(device_address,
1857                         (unsigned char *)bd_addr->addr);
1858         device_path = _bt_get_device_object_path(device_address);
1859         if (device_path == NULL) {
1860                 BT_ERR_C("device_path NULL : [%s]", device_address);
1861                 ret = BLUETOOTH_ERROR_INTERNAL;
1862                 return ret;
1863         }
1864
1865         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1866                         NULL, BT_BLUEZ_NAME,
1867                         device_path, BT_DEVICE_INTERFACE,  NULL, NULL);
1868         g_free(device_path);
1869         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1870
1871         func_data = g_malloc0(sizeof(bt_function_data_t));
1872         func_data->address = g_strdup(device_address);
1873         if (func_data->address == NULL) {
1874                 BT_ERR("Unable to allocate memory for address");
1875                 ret = BLUETOOTH_ERROR_MEMORY_ALLOCATION;
1876                 goto fail;
1877         }
1878
1879         _bt_convert_addr_string_to_secure_string(secure_address, device_address);
1880         BT_INFO("Connect LE [%s]", secure_address);
1881
1882         func_data->req_id = req_id;
1883
1884         g_dbus_proxy_call(device_proxy, "ConnectLE",
1885                         g_variant_new("(b)", auto_connect),
1886                         G_DBUS_CALL_FLAGS_NONE,
1887                         BT_MAX_DBUS_TIMEOUT,
1888                         NULL,
1889                         (GAsyncReadyCallback)__le_connection_req_cb, func_data);
1890
1891         return ret;
1892
1893 fail:
1894         if (device_proxy)
1895                 g_object_unref(device_proxy);
1896
1897         g_free(func_data->address);
1898         g_free(func_data);
1899
1900         return ret;
1901 }
1902
1903 static gboolean __bt_connect_le_timer_cb(gpointer user_data)
1904 {
1905         BT_INFO("Try to initiate pending LE connection");
1906
1907         pending_le_conn_timer_id = 0;
1908
1909         __bt_connect_le_device_internal(pending_le_conn_info->req_id,
1910                 &pending_le_conn_info->bd_addr,
1911                 pending_le_conn_info->auto_connect);
1912
1913         g_free(pending_le_conn_info);
1914         pending_le_conn_info = NULL;
1915
1916         return FALSE;
1917 }
1918
1919 void _bt_pending_connect_le_device(void)
1920 {
1921         if (pending_le_conn_timer_id > 0) {
1922                 g_source_remove(pending_le_conn_timer_id);
1923                 __bt_connect_le_timer_cb(NULL);
1924         }
1925 }
1926
1927 int _bt_connect_le_device(int req_id, const bluetooth_device_address_t *bd_addr,
1928                 gboolean auto_connect)
1929 {
1930         int ret = BLUETOOTH_ERROR_NONE;
1931
1932         BT_CHECK_PARAMETER(bd_addr, return);
1933
1934         ret = _bt_hold_current_advertising();
1935         if (ret == BLUETOOTH_ERROR_NONE) {
1936                 BT_INFO("Current advertising is held");
1937                 pending_le_conn_info = g_malloc0(sizeof(bt_pending_le_conn_info_s));
1938                 pending_le_conn_info->req_id = req_id;
1939                 memcpy(pending_le_conn_info->bd_addr.addr, bd_addr->addr,
1940                                 BLUETOOTH_ADDRESS_LENGTH);
1941                 pending_le_conn_info->auto_connect = auto_connect;
1942
1943                 pending_le_conn_timer_id =
1944                         g_timeout_add(1000, __bt_connect_le_timer_cb, NULL);
1945
1946                 return BLUETOOTH_ERROR_NONE;
1947         }
1948
1949         BT_ERR("Unable to hold advertising");
1950
1951         return __bt_connect_le_device_internal(req_id, bd_addr, auto_connect);
1952 }
1953
1954 int _bt_disconnect_le_device(int req_id,
1955                 const bluetooth_device_address_t *bd_addr)
1956 {
1957         char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
1958         char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
1959         gchar *device_path;
1960         GDBusProxy *device_proxy;
1961         GDBusConnection *conn;
1962         int ret = BLUETOOTH_ERROR_NONE;
1963         bt_function_data_t *func_data;
1964
1965         BT_CHECK_PARAMETER(bd_addr, return);
1966
1967         conn = _bt_gdbus_get_system_gconn();
1968         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1969
1970         _bt_convert_addr_type_to_string(device_address,
1971                         (unsigned char *)bd_addr->addr);
1972         device_path = _bt_get_device_object_path(device_address);
1973         if (device_path == NULL) {
1974                 BT_DBG("device_path NULL");
1975                 ret = BLUETOOTH_ERROR_INTERNAL;
1976                 return ret;
1977         }
1978
1979         retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL);
1980
1981         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1982                         NULL, BT_BLUEZ_NAME,
1983                         device_path, BT_DEVICE_INTERFACE,  NULL, NULL);
1984         g_free(device_path);
1985         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1986
1987         func_data = g_malloc0(sizeof(bt_function_data_t));
1988         func_data->address = g_strdup(device_address);
1989         if (func_data->address == NULL) {
1990                 BT_ERR("Unable to allocate memory for address");
1991                 ret = BLUETOOTH_ERROR_MEMORY_ALLOCATION;
1992                 goto fail;
1993         }
1994
1995         _bt_convert_addr_string_to_secure_string(secure_address, device_address);
1996         BT_INFO("Disconnect LE [%s]", secure_address);
1997
1998         func_data->req_id = req_id;
1999
2000         g_dbus_proxy_call(device_proxy, "DisconnectLE",
2001                         NULL,
2002                         G_DBUS_CALL_FLAGS_NONE,
2003                         BT_MAX_DBUS_TIMEOUT,
2004                         NULL,
2005                         (GAsyncReadyCallback)__le_connection_req_cb, func_data);
2006         return ret;
2007
2008 fail:
2009         if (device_proxy)
2010                 g_object_unref(device_proxy);
2011
2012         g_free(func_data->address);
2013         g_free(func_data);
2014
2015         return ret;
2016 }
2017
2018 int _bt_connect_le_ipsp_device(const bluetooth_device_address_t *bd_addr)
2019 {
2020         char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
2021         gchar *device_path = NULL;
2022         GError *error = NULL;
2023         GDBusProxy *device_proxy = NULL;
2024         GDBusProxy *adapter_proxy;
2025         GDBusConnection *conn;
2026         int ret = BLUETOOTH_ERROR_NONE;
2027
2028         BT_CHECK_PARAMETER(bd_addr, return);
2029
2030         _bt_convert_addr_type_to_string(device_address,
2031                         (unsigned char *)bd_addr->addr);
2032
2033         conn = _bt_gdbus_get_system_gconn();
2034         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2035
2036         adapter_proxy = _bt_get_adapter_proxy();
2037         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2038
2039         device_path = _bt_get_device_object_path(device_address);
2040         if (device_path == NULL) {
2041                 BT_DBG("device_path NULL");
2042                 ret = BLUETOOTH_ERROR_INTERNAL;
2043                 return ret;
2044         }
2045
2046         retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL);
2047
2048         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2049                                                         NULL, BT_BLUEZ_NAME,
2050                                                         device_path, BT_DEVICE_INTERFACE,  NULL, NULL);
2051         g_free(device_path);
2052         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2053
2054         g_dbus_proxy_call_sync(device_proxy, "ConnectIpsp",
2055                                 NULL,
2056                                 G_DBUS_CALL_FLAGS_NONE,
2057                                 -1,
2058                                 NULL,
2059                                 &error);
2060         if (error) {
2061                 BT_ERR("ConnectIpsp Call Error %s[%s]", error->message, device_address);
2062                 g_error_free(error);
2063                 g_object_unref(device_proxy);
2064                 return BLUETOOTH_ERROR_INTERNAL;
2065         }
2066         g_object_unref(device_proxy);
2067
2068         /* IPSP daemon launch */
2069         GDBusProxy *ipsp_proxy;
2070
2071         ipsp_proxy = _bt_get_ipsp_proxy();
2072         retv_if(ipsp_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2073
2074         g_dbus_proxy_call(ipsp_proxy, "EnableIpsp",
2075                         NULL, G_DBUS_CALL_FLAGS_NONE,
2076                         -1, NULL, NULL, NULL);
2077
2078         return ret;
2079 }
2080
2081 int _bt_disconnect_le_ipsp_device(const bluetooth_device_address_t *bd_addr)
2082 {
2083         char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
2084         gchar *device_path = NULL;
2085         GError *error = NULL;
2086         GDBusProxy *device_proxy = NULL;
2087         GDBusProxy *adapter_proxy;
2088         GDBusConnection *conn;
2089         int ret = BLUETOOTH_ERROR_NONE;
2090
2091         BT_CHECK_PARAMETER(bd_addr, return);
2092
2093         _bt_convert_addr_type_to_string(device_address,
2094                         (unsigned char *)bd_addr->addr);
2095
2096         conn = _bt_gdbus_get_system_gconn();
2097         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2098
2099         adapter_proxy = _bt_get_adapter_proxy();
2100         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2101
2102         device_path = _bt_get_device_object_path(device_address);
2103         if (device_path == NULL) {
2104                 BT_DBG("device_path NULL");
2105                 ret = BLUETOOTH_ERROR_INTERNAL;
2106                 return ret;
2107         }
2108
2109         retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL);
2110
2111         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2112                                                         NULL, BT_BLUEZ_NAME,
2113                                                         device_path, BT_DEVICE_INTERFACE,  NULL, NULL);
2114         g_free(device_path);
2115         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2116
2117         g_dbus_proxy_call_sync(device_proxy, "DisconnectIpsp",
2118                                 NULL,
2119                                 G_DBUS_CALL_FLAGS_NONE,
2120                                 -1,
2121                                 NULL,
2122                                 &error);
2123         if (error) {
2124                 BT_ERR("DisconnectIpsp Call Error %s[%s]", error->message, device_address);
2125                 g_error_free(error);
2126                 g_object_unref(device_proxy);
2127                 return BLUETOOTH_ERROR_INTERNAL;
2128         }
2129
2130         g_object_unref(device_proxy);
2131
2132         return ret;
2133 }
2134
2135 int _bt_connect_profile(char *address, char *uuid,
2136                                                 void *cb, gpointer func_data)
2137 {
2138         char *object_path;
2139         GDBusProxy *proxy;
2140         GDBusConnection *conn;
2141         GDBusProxy *adapter_proxy;
2142         GVariant *result = NULL;
2143         GError *error = NULL;
2144
2145         conn = _bt_gdbus_get_system_gconn();
2146         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2147
2148         object_path = _bt_get_device_object_path(address);
2149         if (object_path == NULL) {
2150                 BT_ERR("No searched device");
2151
2152                 adapter_proxy = _bt_get_adapter_proxy();
2153                 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2154
2155                 result = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
2156                                          g_variant_new("(s)", address),
2157                                          G_DBUS_CALL_FLAGS_NONE,
2158                                          -1,
2159                                          NULL,
2160                                          &error);
2161
2162                 if (error != NULL) {
2163                         BT_ERR("CreateDevice Fail: %s", error->message);
2164                         g_error_free(error);
2165                 }
2166                 if (result)
2167                         g_variant_unref(result);
2168
2169                 object_path = _bt_get_device_object_path(address);
2170         }
2171         retv_if(object_path == NULL, BLUETOOTH_ERROR_INTERNAL);
2172
2173         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2174                                                                 NULL, BT_BLUEZ_NAME,
2175                                                                 object_path, BT_DEVICE_INTERFACE,  NULL, NULL);
2176         g_free(object_path);
2177         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2178
2179         g_dbus_proxy_call(proxy, "ConnectProfile",
2180                                 g_variant_new("(s)", uuid),
2181                                 G_DBUS_CALL_FLAGS_NONE,
2182                                 BT_MAX_DBUS_TIMEOUT,
2183                                 NULL,
2184                                 (GAsyncReadyCallback)cb,
2185                                 func_data);
2186
2187         return BLUETOOTH_ERROR_NONE;
2188 }
2189
2190 int _bt_disconnect_all(char *address)
2191 {
2192         int ret = BLUETOOTH_ERROR_NONE;
2193         char *object_path;
2194         GDBusProxy *proxy;
2195         GDBusConnection *conn;
2196         GVariant *result = NULL;
2197         GError *err = NULL;
2198
2199         BT_DBG("");
2200         conn = _bt_gdbus_get_system_gconn();
2201         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2202
2203         object_path = _bt_get_device_object_path(address);
2204         retv_if(object_path == NULL, BLUETOOTH_ERROR_INTERNAL);
2205
2206         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2207                                         NULL, BT_BLUEZ_NAME,
2208                                         object_path, BT_DEVICE_INTERFACE,  NULL, NULL);
2209         g_free(object_path);
2210         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2211
2212         result = g_dbus_proxy_call_sync(proxy, "Disconnect",
2213                 NULL,
2214                 G_DBUS_CALL_FLAGS_NONE,
2215                 -1, NULL,
2216                 &err);
2217
2218         if (err != NULL) {
2219                 BT_ERR("Dbus Call Error:[%s]", err->message);
2220                 g_error_free(err);
2221                 ret = BLUETOOTH_ERROR_INTERNAL;
2222         }
2223
2224         g_object_unref(proxy);
2225         if (result)
2226                 g_variant_unref(result);
2227
2228         return ret;
2229 }
2230
2231 int _bt_disconnect_profile(char *address, char *uuid,
2232                                                 void *cb, gpointer func_data)
2233 {
2234         char *object_path;
2235         GDBusProxy *proxy;
2236         GDBusConnection *conn;
2237
2238         conn = _bt_gdbus_get_system_gconn();
2239         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2240
2241         object_path = _bt_get_device_object_path(address);
2242         retv_if(object_path == NULL, BLUETOOTH_ERROR_INTERNAL);
2243
2244         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2245                                                                 NULL, BT_BLUEZ_NAME,
2246                                                                 object_path, BT_DEVICE_INTERFACE,  NULL, NULL);
2247         g_free(object_path);
2248         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2249
2250         g_dbus_proxy_call(proxy, "DisconnectProfile",
2251                                         g_variant_new("(s)", uuid),
2252                                         G_DBUS_CALL_FLAGS_NONE,
2253                                         BT_MAX_DBUS_TIMEOUT,
2254                                         NULL,
2255                                         (GAsyncReadyCallback)cb,
2256                                         func_data);
2257
2258         return BLUETOOTH_ERROR_NONE;
2259 }
2260
2261 int _bt_enable_rssi(bluetooth_device_address_t *bd_addr, int link_type,
2262                 int low_threshold, int in_range_threshold, int high_threshold)
2263 {
2264         int ret = BLUETOOTH_ERROR_NONE;
2265         GDBusProxy *proxy;
2266         GVariant *result = NULL;
2267         GError *error = NULL;
2268         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2269
2270         BT_CHECK_PARAMETER(bd_addr, return);
2271         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X] Link Type[%d]",
2272                         bd_addr->addr[0], bd_addr->addr[1],
2273                         bd_addr->addr[2], bd_addr->addr[3],
2274                         bd_addr->addr[4], bd_addr->addr[5],
2275                         link_type);
2276         BT_DBG("Enable RSSI: [Threshold %d %d %d]", low_threshold,
2277                         in_range_threshold, high_threshold);
2278
2279         _bt_convert_addr_type_to_string(address, bd_addr->addr);
2280
2281         proxy = _bt_get_adapter_proxy();
2282         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2283
2284         result = g_dbus_proxy_call_sync(proxy, "EnableRssi",
2285                                 g_variant_new("(siiii)", address, link_type, low_threshold, in_range_threshold, high_threshold),
2286                                 G_DBUS_CALL_FLAGS_NONE,
2287                                 -1,
2288                                 NULL,
2289                                 &error);
2290         if (error != NULL) {
2291                         BT_ERR("Dbus Call Error:[%s]", error->message);
2292                         g_error_free(error);
2293                         ret = BLUETOOTH_ERROR_INTERNAL;
2294         }
2295
2296         if (result)
2297                 g_variant_unref(result);
2298
2299         return ret;
2300 }
2301
2302 int _bt_get_rssi_strength(bluetooth_device_address_t *bd_addr,
2303                                         int link_type)
2304 {
2305         int ret = BLUETOOTH_ERROR_NONE;
2306         GDBusProxy *proxy;
2307         GVariant *result = NULL;
2308         GError *error = NULL;
2309         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2310
2311         BT_CHECK_PARAMETER(bd_addr, return);
2312         BT_DBG("BD Address [%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X] Link Type[%d]",
2313                         bd_addr->addr[0], bd_addr->addr[1],
2314                         bd_addr->addr[2], bd_addr->addr[3],
2315                         bd_addr->addr[4], bd_addr->addr[5],
2316                         link_type);
2317
2318         _bt_convert_addr_type_to_string(address, bd_addr->addr);
2319
2320         proxy = _bt_get_adapter_proxy();
2321         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2322
2323         result = g_dbus_proxy_call_sync(proxy, "GetRssiStrength",
2324                                 g_variant_new("(si)", address, link_type),
2325                                 G_DBUS_CALL_FLAGS_NONE,
2326                                 -1,
2327                                 NULL,
2328                                 &error);
2329
2330         if (error != NULL) {
2331                         BT_ERR("Dbus Call Error:[%s]", error->message);
2332                         g_error_free(error);
2333                         ret = BLUETOOTH_ERROR_INTERNAL;
2334         }
2335
2336         if (result)
2337                 g_variant_unref(result);
2338
2339         return ret;
2340 }
2341
2342 int _bt_le_conn_update(unsigned char *device_address,
2343                                 float interval_min, float interval_max,
2344                                 guint16 latency, guint16 time_out)
2345 {
2346         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2347         gchar *device_path = NULL;
2348         GError *error = NULL;
2349         GDBusProxy *device_proxy = NULL;
2350         GDBusConnection *conn;
2351         GVariant *reply;
2352         guint32 min, max, to;
2353         guint32 min_supervision_to;
2354         int ret = BLUETOOTH_ERROR_NONE;
2355
2356         BT_CHECK_PARAMETER(device_address, return);
2357
2358         BT_INFO("Min interval: %f, Max interval: %f, Latency: %u, Supervision timeout: %u",
2359                         interval_min, interval_max, latency, time_out);
2360
2361         if (interval_min > interval_max ||
2362                         interval_min < BT_LE_CONN_INTERVAL_MIN ||
2363                         interval_max > BT_LE_CONN_INTERVAL_MAX) {
2364                 ret = BLUETOOTH_ERROR_INVALID_PARAM;
2365                 goto fail;
2366         }
2367
2368         if (time_out < BT_LE_CONN_SUPER_TO_MIN ||
2369                         time_out > BT_LE_CONN_SUPER_TO_MAX) {
2370                 ret = BLUETOOTH_ERROR_INVALID_PARAM;
2371                 goto fail;
2372         }
2373
2374         if (latency > BT_LE_CONN_SLAVE_LATENCY_MAX) {
2375                 ret = BLUETOOTH_ERROR_INVALID_PARAM;
2376                 goto fail;
2377         }
2378
2379         /*
2380          * The Supervision_Timeout in milliseconds shall be larger than
2381          * (1 + Conn_Latency) * Conn_Interval_Max * 2,
2382          * where Conn_Interval_Max is given in milliseconds.
2383          */
2384         min_supervision_to = (1 + latency) * interval_max * 2;
2385         if (time_out <= min_supervision_to) {
2386                 ret = BLUETOOTH_ERROR_INVALID_PARAM;
2387                 goto fail;
2388         }
2389
2390         _bt_convert_addr_type_to_string(address, device_address);
2391
2392         BT_DBG("Remote device address: %s", address);
2393
2394         device_path = _bt_get_device_object_path(address);
2395
2396         if (device_path == NULL) {
2397                 BT_ERR("device_path NULL");
2398                 ret = BLUETOOTH_ERROR_INTERNAL;
2399                 goto fail;
2400         }
2401
2402         conn = _bt_gdbus_get_system_gconn();
2403         if (conn == NULL) {
2404                 BT_ERR("conn NULL");
2405                 ret = BLUETOOTH_ERROR_INTERNAL;
2406                 goto fail;
2407         }
2408
2409         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2410                                                                 NULL, BT_BLUEZ_NAME,
2411                                                                 device_path, BT_DEVICE_INTERFACE,  NULL, NULL);
2412
2413         g_free(device_path);
2414         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2415
2416         min = interval_min / BT_LE_CONN_INTERVAL_SPLIT;
2417         max = interval_max / BT_LE_CONN_INTERVAL_SPLIT;
2418         to = time_out / BT_LE_CONN_TO_SPLIT;
2419
2420         reply = g_dbus_proxy_call_sync(device_proxy, "LeConnUpdate",
2421                                 g_variant_new("(uuuu)", min, max, latency, to),
2422                                 G_DBUS_CALL_FLAGS_NONE,
2423                                 -1,
2424                                 NULL,
2425                                 &error);
2426
2427         g_object_unref(device_proxy);
2428         if (reply == NULL) {
2429                 if (error) {
2430                         BT_ERR("Error %s[%s]", error->message, address);
2431                         if (g_strrstr(error->message, "In Progress"))
2432                                 ret = BLUETOOTH_ERROR_IN_PROGRESS;
2433                         else
2434                                 ret = BLUETOOTH_ERROR_INTERNAL;
2435                         g_error_free(error);
2436                         return ret;
2437                 }
2438         }
2439         g_variant_unref(reply);
2440
2441 fail:
2442         return ret;
2443 }
2444
2445 int _bt_set_pin_code(bluetooth_device_address_t *device_address,
2446                                 bluetooth_device_pin_code_t *pin_code)
2447 {
2448         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2449         GSList *l = NULL;
2450         bt_pin_code_info_t *pin_info = NULL;
2451
2452         BT_CHECK_PARAMETER(device_address, return);
2453         BT_CHECK_PARAMETER(pin_code, return);
2454         retv_if(g_slist_length(pin_info_list) >= BT_DEVICE_PIN_CODE_SLOT_MAX,
2455                         BLUETOOTH_ERROR_NO_RESOURCES);
2456
2457         _bt_convert_addr_type_to_string(address, device_address->addr);
2458
2459         for (l = pin_info_list; l != NULL; l = l->next) {
2460                 pin_info = l->data;
2461
2462                 if (g_strcmp0(pin_info->address, address) == 0) {
2463                         g_free(pin_info->pin_code);
2464                         pin_info->pin_code = g_strdup(pin_code->pin_code);
2465                         return BLUETOOTH_ERROR_NONE;
2466                 }
2467         }
2468
2469         pin_info = g_malloc0(sizeof(bt_pin_code_info_t));
2470         pin_info->address = g_strdup(address);
2471         pin_info->pin_code = g_strdup(pin_code->pin_code);
2472         pin_info_list = g_slist_append(pin_info_list, pin_info);
2473
2474         return BLUETOOTH_ERROR_NONE;
2475 }
2476
2477 gint __bt_compare_address(gpointer *a, gpointer *b)
2478 {
2479         bt_pin_code_info_t *pin_info = (bt_pin_code_info_t *)a;
2480         char *address = (char *)b;
2481         return g_strcmp0(pin_info->address, address);
2482 }
2483
2484 int _bt_unset_pin_code(bluetooth_device_address_t *device_address)
2485 {
2486         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2487         GSList *l = NULL;
2488         bt_pin_code_info_t *pin_info = NULL;
2489
2490         BT_CHECK_PARAMETER(device_address, return);
2491
2492         _bt_convert_addr_type_to_string(address, device_address->addr);
2493
2494         l = g_slist_find_custom(pin_info_list, address,
2495                 (GCompareFunc)__bt_compare_address);
2496         if (l)
2497                 pin_info = l->data;
2498         if (pin_info) {
2499                 pin_info_list = g_slist_remove(pin_info_list, pin_info);
2500                 g_free(pin_info->address);
2501                 g_free(pin_info->pin_code);
2502                 g_free(pin_info);
2503         }
2504
2505         return BLUETOOTH_ERROR_NONE;
2506 }
2507
2508 int _bt_get_device_pin_code(const char *address, char *pin_code)
2509 {
2510         GSList *l = NULL;
2511
2512         BT_CHECK_PARAMETER(address, return);
2513         BT_CHECK_PARAMETER(pin_code, return);
2514
2515         for (l = pin_info_list; l != NULL; l = l->next) {
2516                 bt_pin_code_info_t *pin_info = l->data;
2517
2518                 if (g_strcmp0(pin_info->address, address) == 0) {
2519                         g_strlcpy(pin_code, pin_info->pin_code,
2520                                         BLUETOOTH_PIN_CODE_MAX_LENGTH + 1);
2521
2522                         return BLUETOOTH_ERROR_NONE;
2523                 }
2524         }
2525
2526         return BLUETOOTH_ERROR_NOT_FOUND;
2527 }
2528
2529 int _bt_get_le_connection_parameter(bluetooth_le_connection_mode_t mode,
2530                 bluetooth_le_connection_param_t *param)
2531 {
2532         if (param == NULL)
2533                 return BLUETOOTH_ERROR_INVALID_PARAM;
2534
2535         if (mode < BLUETOOTH_LE_CONNECTION_MODE_BALANCED ||
2536             mode > BLUETOOTH_LE_CONNECTION_MODE_LOW_POWER)
2537                 return BLUETOOTH_ERROR_INVALID_PARAM;
2538
2539         memset(param, 0x00, sizeof(bluetooth_le_connection_param_t));
2540
2541         switch (mode) {
2542         case BLUETOOTH_LE_CONNECTION_MODE_BALANCED:
2543                 param->interval_min = BT_LE_CONN_PARAM_BALANCED_MIN_INTERVAL;
2544                 param->interval_max = BT_LE_CONN_PARAM_BALANCED_MAX_INTERVAL;
2545                 param->latency = BT_LE_CONN_PARAM_BALANCED_SLAVE_LATENCY;
2546                 param->timeout = BT_LE_CONN_PARAM_DEFAULT_SUPERVISION_TIMEOUT;
2547                 break;
2548
2549         case BLUETOOTH_LE_CONNECTION_MODE_LOW_LATENCY:
2550                 param->interval_min = BT_LE_CONN_PARAM_LOW_LATENCY_MIN_INTERVAL;
2551                 param->interval_max = BT_LE_CONN_PARAM_LOW_LATENCY_MAX_INTERVAL;
2552                 param->latency = BT_LE_CONN_PARAM_LOW_LATENCY_SLAVE_LATENCY;
2553                 param->timeout = BT_LE_CONN_PARAM_DEFAULT_SUPERVISION_TIMEOUT;
2554                 break;
2555
2556         case BLUETOOTH_LE_CONNECTION_MODE_LOW_POWER:
2557                 param->interval_min = BT_LE_CONN_PARAM_LOW_POWER_MIN_INTERVAL;
2558                 param->interval_max = BT_LE_CONN_PARAM_LOW_POWER_MAX_INTERVAL;
2559                 param->latency = BT_LE_CONN_PARAM_LOW_POWER_SLAVE_LATENCY;
2560                 param->timeout = BT_LE_CONN_PARAM_DEFAULT_SUPERVISION_TIMEOUT;
2561                 break;
2562
2563         default:
2564                 BT_ERR("Unhandled mode : %d", mode);
2565                 break;
2566         }
2567
2568         return BLUETOOTH_ERROR_NONE;
2569 }
2570
2571 int _bt_get_trusted_profile_from_flag(bluetooth_trusted_profile_t profile,
2572                 guint trusted_profile_flag, guint *trusted)
2573 {
2574         int trust_profile;
2575         *trusted = FALSE;
2576
2577         switch (profile) {
2578         case TRUSTED_PROFILE_PBAP:
2579                 if (trusted_profile_flag & (PROFILE_SUPPORTED << 0))
2580                         trust_profile = trusted_profile_flag & (1 << 1);
2581                 else
2582                         return BLUETOOTH_ERROR_NOT_SUPPORT;
2583                 break;
2584         case TRUSTED_PROFILE_MAP:
2585                 if (trusted_profile_flag & (PROFILE_SUPPORTED << 2))
2586                         trust_profile = trusted_profile_flag & (1 << 3);
2587                 else
2588                         return BLUETOOTH_ERROR_NOT_SUPPORT;
2589                 break;
2590         case TRUSTED_PROFILE_SAP:
2591                 if (trusted_profile_flag & (PROFILE_SUPPORTED << 4))
2592                         trust_profile = trusted_profile_flag & (1 << 5);
2593                 else
2594                         return BLUETOOTH_ERROR_NOT_SUPPORT;
2595                 break;
2596         case TRUSTED_PROFILE_ALL: /* Return Flag for All profiles*/
2597                 *trusted = trusted_profile_flag;
2598                 return BLUETOOTH_ERROR_NONE;
2599         default:
2600                 return BLUETOOTH_ERROR_NOT_SUPPORT;
2601         }
2602
2603         if (trust_profile)
2604                 *trusted = TRUE;
2605
2606         return BLUETOOTH_ERROR_NONE;
2607 }
2608
2609 int _bt_get_restricted_profile_from_flag(bluetooth_restricted_profile_t profile,
2610                 guint restricted_profile_flag, guint *restricted)
2611 {
2612         int restrict_profile;
2613         *restricted = FALSE;
2614
2615         switch (profile) {
2616         case RESTRICTED_PROFILE_HFP_HS:
2617                         restrict_profile = restricted_profile_flag & (1 << 0);
2618                 break;
2619         case RESTRICTED_PROFILE_A2DP:
2620                         restrict_profile = restricted_profile_flag & (1 << 2);
2621                 break;
2622         default:
2623                 return BLUETOOTH_ERROR_NOT_SUPPORT;
2624         }
2625
2626         if (restrict_profile)
2627                 *restricted = TRUE;
2628
2629         return BLUETOOTH_ERROR_NONE;
2630 }
2631
2632 char *_bt_get_trusted_profile_uuid(bluetooth_trusted_profile_t profile)
2633 {
2634         switch (profile) {
2635         case TRUSTED_PROFILE_PBAP:
2636                 return g_strdup("00001130-0000-1000-8000-00805f9b34fb");
2637         case TRUSTED_PROFILE_MAP:
2638                 return g_strdup("00001134-0000-1000-8000-00805f9b34fb");
2639         case TRUSTED_PROFILE_SAP:
2640                 return g_strdup("0000112D-0000-1000-8000-00805f9b34fb");
2641         case TRUSTED_PROFILE_ALL:
2642                 return NULL;
2643         }
2644
2645         return NULL;
2646 }
2647
2648 char *_bt_get_restricted_profile_uuid(bluetooth_restricted_profile_t profile)
2649 {
2650         switch (profile) {
2651         case RESTRICTED_PROFILE_HFP_HS:
2652                 return g_strdup("0000111e-0000-1000-8000-00805f9b34fb");
2653         case RESTRICTED_PROFILE_A2DP:
2654                 return g_strdup("0000110b-0000-1000-8000-00805f9b34fb");
2655         }
2656
2657         return NULL;
2658 }
2659
2660 bluetooth_trusted_profile_t _bt_get_trusted_profile_enum(const char *uuid)
2661 {
2662         if (g_strcmp0("0000112f-0000-1000-8000-00805f9b34fb", uuid) == 0)
2663                 return TRUSTED_PROFILE_PBAP;
2664         else if (g_strcmp0("00001132-0000-1000-8000-00805f9b34fb", uuid) == 0)
2665                 return TRUSTED_PROFILE_MAP;
2666         else if (g_strcmp0("0000112D-0000-1000-8000-00805f9b34fb", uuid) == 0)
2667                 return TRUSTED_PROFILE_SAP;
2668
2669         return 0; /* 0 - Unknown Profile */
2670 }
2671
2672 int _bt_set_trust_profile(bluetooth_device_address_t *bd_addr,
2673                 bluetooth_trusted_profile_t profile, gboolean trust)
2674 {
2675         int ret = BLUETOOTH_ERROR_NONE;
2676         GDBusConnection *conn;
2677         GDBusProxy *proxy;
2678         GError *error = NULL;
2679         char *device_path = NULL;
2680         char *uuid = NULL;
2681         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2682         GVariant *reply;
2683
2684         BT_CHECK_PARAMETER(bd_addr, return);
2685         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X] profile[%d] trust[%d]",
2686                         bd_addr->addr[0], bd_addr->addr[1],
2687                         bd_addr->addr[2], bd_addr->addr[3],
2688                         bd_addr->addr[4], bd_addr->addr[5],
2689                         profile, trust);
2690
2691         conn = _bt_gdbus_get_system_gconn();
2692         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2693
2694         _bt_convert_addr_type_to_string(address, bd_addr->addr);
2695
2696         device_path = _bt_get_device_object_path(address);
2697         retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL);
2698
2699         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2700                         NULL, BT_BLUEZ_NAME, device_path,
2701                         BT_DEVICE_INTERFACE, NULL, NULL);
2702
2703         g_free(device_path);
2704         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2705
2706         uuid = _bt_get_trusted_profile_uuid(profile);
2707         if (uuid == NULL) {
2708                 g_object_unref(proxy);
2709                 return BLUETOOTH_ERROR_NOT_SUPPORT;
2710         }
2711
2712         reply = g_dbus_proxy_call_sync(proxy, "SetTrustedProfile",
2713                         g_variant_new("(sb)", uuid, trust),
2714                         G_DBUS_CALL_FLAGS_NONE, -1,
2715                         NULL, &error);
2716         g_object_unref(proxy);
2717
2718         if (reply == NULL) {
2719                 BT_ERR("Failed to Set Profile Trusted");
2720                 ret = BLUETOOTH_ERROR_INTERNAL;
2721                 if (error) {
2722                         BT_ERR("Error %s[%s]", error->message, address);
2723                         g_error_free(error);
2724                 }
2725                 goto finish;
2726         }
2727         g_variant_unref(reply);
2728
2729 finish:
2730         g_free(uuid);
2731         return ret;
2732 }
2733
2734 int _bt_get_trust_profile(bluetooth_device_address_t *bd_addr,
2735                 bluetooth_trusted_profile_t profile, guint *trust)
2736 {
2737         int ret = BLUETOOTH_ERROR_NONE;
2738         GDBusConnection *conn;
2739         GDBusProxy *proxy;
2740         GError *error = NULL;
2741         char *device_path = NULL;
2742         guint trusted_profile_flag;
2743         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2744         GVariant *reply;
2745
2746         BT_CHECK_PARAMETER(bd_addr, return);
2747         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X] profile[%d] trust[%d]",
2748                         bd_addr->addr[0], bd_addr->addr[1],
2749                         bd_addr->addr[2], bd_addr->addr[3],
2750                         bd_addr->addr[4], bd_addr->addr[5],
2751                         profile, *trust);
2752
2753         conn = _bt_gdbus_get_system_gconn();
2754         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2755
2756         _bt_convert_addr_type_to_string(address, bd_addr->addr);
2757
2758         device_path = _bt_get_device_object_path(address);
2759         retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL);
2760
2761         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2762                         NULL, BT_BLUEZ_NAME, device_path,
2763                         BT_PROPERTIES_INTERFACE, NULL, NULL);
2764
2765         g_free(device_path);
2766         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2767
2768         reply = g_dbus_proxy_call_sync(proxy, "Get",
2769                         g_variant_new("(ss)", BT_DEVICE_INTERFACE, "TrustedProfiles"),
2770                         G_DBUS_CALL_FLAGS_NONE, -1,
2771                         NULL, &error);
2772         g_object_unref(proxy);
2773
2774         if (reply == NULL) {
2775                 BT_ERR("Failed to Get Profile Trusted");
2776                 ret = BLUETOOTH_ERROR_INTERNAL;
2777                 if (error) {
2778                         BT_ERR("Error %s[%s]", error->message, address);
2779                         g_error_free(error);
2780                 }
2781                 *trust = 0;
2782         } else {
2783                 GVariant *temp;
2784                 g_variant_get(reply, "(v)", &temp);
2785                 trusted_profile_flag = g_variant_get_uint32(temp);
2786                 BT_DBG("TRUST_FLAG %d", trusted_profile_flag);
2787
2788                 ret = _bt_get_trusted_profile_from_flag(profile,
2789                                 trusted_profile_flag, trust);
2790                 g_variant_unref(temp);
2791                 g_variant_unref(reply);
2792         }
2793
2794         BT_DBG("TRUST %d", *trust);
2795         return ret;
2796 }
2797
2798 int _bt_set_restrict_profile(bluetooth_device_address_t *bd_addr,
2799                 bluetooth_restricted_profile_t profile, gboolean restricted)
2800 {
2801         int ret = BLUETOOTH_ERROR_NONE;
2802         GDBusConnection *conn;
2803         GDBusProxy *proxy;
2804         GError *error = NULL;
2805         char *device_path = NULL;
2806         char *uuid = NULL;
2807         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2808         GVariant *reply;
2809
2810         BT_CHECK_PARAMETER(bd_addr, return);
2811         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X] profile[%d] restricted[%d]",
2812                         bd_addr->addr[0], bd_addr->addr[1],
2813                         bd_addr->addr[2], bd_addr->addr[3],
2814                         bd_addr->addr[4], bd_addr->addr[5],
2815                         profile, restricted);
2816
2817         conn = _bt_gdbus_get_system_gconn();
2818         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2819
2820         _bt_convert_addr_type_to_string(address, bd_addr->addr);
2821
2822         device_path = _bt_get_device_object_path(address);
2823         retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL);
2824
2825         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2826                         NULL, BT_BLUEZ_NAME, device_path,
2827                         BT_DEVICE_INTERFACE, NULL, NULL);
2828
2829         g_free(device_path);
2830         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2831
2832         uuid = _bt_get_restricted_profile_uuid(profile);
2833         if (uuid == NULL) {
2834                 g_object_unref(proxy);
2835                 return BLUETOOTH_ERROR_NOT_SUPPORT;
2836         }
2837
2838         reply = g_dbus_proxy_call_sync(proxy, "SetRestrictedProfile",
2839                         g_variant_new("(sb)", uuid, restricted),
2840                         G_DBUS_CALL_FLAGS_NONE, -1,
2841                         NULL, &error);
2842         g_object_unref(proxy);
2843
2844         if (reply == NULL) {
2845                 BT_ERR("Failed to Set Profile Restricted");
2846                 ret = BLUETOOTH_ERROR_INTERNAL;
2847                 if (error) {
2848                         BT_ERR("Error %s[%s]", error->message, address);
2849                         g_error_free(error);
2850                 }
2851                 goto finish;
2852         }
2853         g_variant_unref(reply);
2854
2855 finish:
2856         g_free(uuid);
2857         return ret;
2858 }
2859
2860 int _bt_get_restrict_profile(bluetooth_device_address_t *bd_addr,
2861                 bluetooth_restricted_profile_t profile, guint *restricted)
2862 {
2863         int ret = BLUETOOTH_ERROR_NONE;
2864         GDBusConnection *conn;
2865         GDBusProxy *proxy;
2866         GError *error = NULL;
2867         char *device_path = NULL;
2868         guint restricted_profile_flag;
2869         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2870         GVariant *reply;
2871
2872         BT_CHECK_PARAMETER(bd_addr, return);
2873         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X] profile[%d] restricted[%d]",
2874                         bd_addr->addr[0], bd_addr->addr[1],
2875                         bd_addr->addr[2], bd_addr->addr[3],
2876                         bd_addr->addr[4], bd_addr->addr[5],
2877                         profile, *restricted);
2878
2879         conn = _bt_gdbus_get_system_gconn();
2880         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2881
2882         _bt_convert_addr_type_to_string(address, bd_addr->addr);
2883
2884         device_path = _bt_get_device_object_path(address);
2885         retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL);
2886
2887         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2888                         NULL, BT_BLUEZ_NAME, device_path,
2889                         BT_PROPERTIES_INTERFACE, NULL, NULL);
2890
2891         g_free(device_path);
2892         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2893
2894         reply = g_dbus_proxy_call_sync(proxy, "Get",
2895                         g_variant_new("(ss)", BT_DEVICE_INTERFACE, "RestrictedProfiles"),
2896                         G_DBUS_CALL_FLAGS_NONE, -1,
2897                         NULL, &error);
2898         g_object_unref(proxy);
2899
2900         if (reply == NULL) {
2901                 BT_ERR("Failed to Get Profile Restricted");
2902                 ret = BLUETOOTH_ERROR_INTERNAL;
2903                 if (error) {
2904                         BT_ERR("Error %s[%s]", error->message, address);
2905                         g_error_free(error);
2906                 }
2907                 *restricted = 0;
2908         } else {
2909                 GVariant *temp;
2910                 g_variant_get(reply, "(v)", &temp);
2911                 restricted_profile_flag = g_variant_get_uint32(temp);
2912                 BT_DBG("Restricted_FLAG %d", restricted_profile_flag);
2913
2914                 ret = _bt_get_restricted_profile_from_flag(profile,
2915                                 restricted_profile_flag, restricted);
2916                 g_variant_unref(temp);
2917                 g_variant_unref(reply);
2918         }
2919
2920         BT_DBG("TRUST %d", *restricted);
2921         return ret;
2922 }
2923
2924 static void __bt_request_att_mtu_device_cb(GDBusProxy *proxy, GAsyncResult *res,
2925                                         gpointer user_data)
2926 {
2927         GError *err = NULL;
2928         GVariant *out_param1;
2929         request_info_t *req_info;
2930         GVariant *val = NULL;
2931         GVariant *param = NULL;
2932         guint8 status = 0;
2933         guint16 mtu = 0;
2934         bluetooth_device_address_t device_addr = { {0} };
2935         int result = BLUETOOTH_ERROR_NONE;
2936
2937         BT_DBG("+");
2938         val = g_dbus_proxy_call_finish(proxy, res, &err);
2939
2940         req_info = _bt_get_request_info(att_mtu_req_info->req_id);
2941         if (req_info == NULL) {
2942                 BT_ERR("req_info == NULL");
2943                 g_object_unref(proxy);
2944                 att_mtu_req_info->device_proxy = NULL;
2945                 goto done;
2946         }
2947
2948         if (err != NULL) {
2949                 BT_ERR("Error occured in RequestAttMtu [%s]", err->message);
2950
2951                 if (g_strrstr(err->message, "NotSupported")) {
2952                         BT_INFO("Connection Not Supported");
2953                         result = BLUETOOTH_ERROR_NOT_SUPPORT;
2954                 } else if (g_strrstr(err->message, "NotConnected")) {
2955                         BT_INFO("Not connected");
2956                         result = BLUETOOTH_ERROR_NOT_CONNECTED;
2957                 } else if (g_strrstr(err->message, "InvalidArguments")) {
2958                         BT_INFO("Not connected");
2959                         result = BLUETOOTH_ERROR_INVALID_PARAM;
2960                 } else {
2961                         BT_DBG("Default case");
2962                         result = BLUETOOTH_ERROR_INTERNAL;
2963                 }
2964         }
2965
2966         g_object_unref(proxy);
2967         att_mtu_req_info->device_proxy = NULL;
2968
2969         if (result != BLUETOOTH_ERROR_NONE)
2970                 goto dbus_return;
2971
2972         if (val) {
2973                  g_variant_get(val, "(qy)", &mtu, &status);
2974                  g_variant_unref(val);
2975         }
2976
2977         BT_DBG("MTU %d, Status %d, %s", mtu, status, att_mtu_req_info->addr);
2978
2979         param = g_variant_new("(isqy)",
2980                         result,
2981                         att_mtu_req_info->addr,
2982                         mtu,
2983                         status);
2984
2985         /* Send the event to application */
2986         _bt_send_event(BT_DEVICE_EVENT,
2987                 BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED,
2988                 param);
2989
2990 dbus_return:
2991         if (req_info->context == NULL)
2992                 goto done;
2993
2994         _bt_convert_addr_string_to_type(device_addr.addr,
2995                                         (const char *)att_mtu_req_info->addr);
2996
2997         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
2998                         &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
2999         g_dbus_method_invocation_return_value(req_info->context,
3000                         g_variant_new("(iv)", result, out_param1));
3001
3002         _bt_delete_request_list(req_info->req_id);
3003 done:
3004         if (err)
3005                 g_error_free(err);
3006
3007         g_free(att_mtu_req_info->addr);
3008         g_free(att_mtu_req_info);
3009         att_mtu_req_info = NULL;
3010
3011         BT_DBG("-");
3012 }
3013
3014 int _bt_request_att_mtu(int request_id, bluetooth_device_address_t *device_address,
3015                                                                 unsigned int mtu)
3016 {
3017         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
3018         gchar *device_path = NULL;
3019         GDBusProxy *adapter_proxy;
3020         GDBusProxy *device_proxy;
3021         GDBusConnection *conn;
3022         int ret = BLUETOOTH_ERROR_NONE;
3023
3024         BT_CHECK_PARAMETER(device_address, return);
3025
3026         if (att_mtu_req_info) {
3027                 BT_ERR("ATT MTU request in progress");
3028                 return BLUETOOTH_ERROR_DEVICE_BUSY;
3029         }
3030
3031         conn = _bt_gdbus_get_system_gconn();
3032         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
3033
3034         adapter_proxy = _bt_get_adapter_proxy();
3035         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
3036
3037         _bt_convert_addr_type_to_string(address, device_address->addr);
3038
3039         BT_DBG("Remote device address: %s", address);
3040
3041         device_path = _bt_get_device_object_path(address);
3042
3043         retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL);
3044
3045         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
3046                                                                 NULL, BT_BLUEZ_NAME,
3047                                                                 device_path, BT_DEVICE_INTERFACE,  NULL, NULL);
3048         g_free(device_path);
3049         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
3050
3051         att_mtu_req_info = g_malloc0(sizeof(bt_funcion_data_t));
3052         att_mtu_req_info->addr = (char *)g_strdup(address);
3053         att_mtu_req_info->req_id = request_id;
3054         att_mtu_req_info->device_proxy = device_proxy;
3055
3056         g_dbus_proxy_call(device_proxy, "RequestAttMtu",
3057                                 g_variant_new("(q)", mtu),
3058                                 G_DBUS_CALL_FLAGS_NONE,
3059                                 BT_MAX_DBUS_TIMEOUT,
3060                                 NULL,
3061                                 (GAsyncReadyCallback)__bt_request_att_mtu_device_cb,
3062                                 NULL);
3063
3064         return ret;
3065 }
3066
3067 int _bt_get_att_mtu(bluetooth_device_address_t *device_address,
3068                         unsigned int *mtu)
3069 {
3070         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
3071         char *object_path = NULL;
3072
3073         GDBusProxy *device_proxy;
3074         GError *error = NULL;
3075         GVariant *value;
3076         GVariant *tmp_value;
3077         GDBusConnection *conn;
3078         GVariant *result = NULL;
3079         int ret = BLUETOOTH_ERROR_NONE;
3080
3081         BT_CHECK_PARAMETER(device_address, return);
3082
3083         conn = _bt_gdbus_get_system_gconn();
3084         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
3085
3086         _bt_convert_addr_type_to_string(address, device_address->addr);
3087
3088         object_path = _bt_get_device_object_path(address);
3089         retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
3090
3091         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
3092                         NULL, BT_BLUEZ_NAME, object_path,
3093                         BT_PROPERTIES_INTERFACE,  NULL, NULL);
3094         g_free(object_path);
3095         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
3096
3097         result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
3098                         g_variant_new("(s)", BT_DEVICE_INTERFACE),
3099                         G_DBUS_CALL_FLAGS_NONE,
3100                         -1,
3101                         NULL,
3102                         &error);
3103         if (result == NULL) {
3104                 if (error != NULL) {
3105                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
3106                         g_error_free(error);
3107                 }
3108                 g_object_unref(device_proxy);
3109                 return BLUETOOTH_ERROR_INTERNAL;
3110         }
3111
3112         g_variant_get(result , "(@a{sv})", &value);
3113         g_variant_unref(result);
3114
3115         tmp_value = g_variant_lookup_value(value, "AttMtu", G_VARIANT_TYPE_UINT16);
3116         if (tmp_value == NULL) {
3117                 g_object_unref(device_proxy);
3118                 g_variant_unref(value);
3119                 return BLUETOOTH_ERROR_INTERNAL;
3120         }
3121
3122         *mtu = g_variant_get_uint16(tmp_value);
3123
3124         BT_DBG("ATT MTU : %d", *mtu);
3125
3126         g_variant_unref(tmp_value);
3127         g_variant_unref(value);
3128         g_object_unref(device_proxy);
3129
3130         return ret;
3131 }
3132
3133 int _bt_get_device_ida(bluetooth_device_address_t *device_address,
3134                         bluetooth_device_address_t *id_address)
3135 {
3136         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
3137         gchar *device_path = NULL;
3138         const gchar *idaddress = NULL;
3139         GDBusProxy *device_proxy;
3140         GError *error = NULL;
3141         GVariant *result = NULL;
3142         GDBusConnection *conn;
3143         int ret = BLUETOOTH_ERROR_NONE;
3144
3145         BT_CHECK_PARAMETER(device_address, return);
3146
3147         conn = _bt_gdbus_get_system_gconn();
3148         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
3149
3150         _bt_convert_addr_type_to_string(address, device_address->addr);
3151
3152         device_path = _bt_get_device_object_path(address);
3153         retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
3154
3155         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
3156                                                                 NULL, BT_BLUEZ_NAME,
3157                                                                 device_path, BT_DEVICE_INTERFACE,  NULL, NULL);
3158         g_free(device_path);
3159         if (!device_proxy) {
3160                 BT_ERR("Unable to get proxy");
3161                 return BLUETOOTH_ERROR_INTERNAL;
3162         }
3163
3164         result = g_dbus_proxy_call_sync(device_proxy, "GetIDAddress",
3165                                  NULL,
3166                                  G_DBUS_CALL_FLAGS_NONE,
3167                                  -1,
3168                                  NULL,
3169                                  &error);
3170
3171         if (result == NULL) {
3172                 BT_ERR("Failed to get device ID address");
3173                 if (error != NULL) {
3174                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
3175                         g_error_free(error);
3176                 }
3177                 g_object_unref(device_proxy);
3178                 return BLUETOOTH_ERROR_INTERNAL;
3179         }
3180
3181         g_variant_get(result , "(s)", &idaddress);
3182         g_variant_unref(result);
3183
3184         if (idaddress == NULL) {
3185                 BT_ERR("No paired device");
3186                 g_object_unref(device_proxy);
3187                 return BLUETOOTH_ERROR_NOT_PAIRED;
3188         }
3189
3190         BT_DBG("ID Address:%s", idaddress);
3191
3192         if (idaddress)
3193                 _bt_convert_addr_string_to_type(id_address->addr, idaddress);
3194         else
3195                 ret = BLUETOOTH_ERROR_INTERNAL;
3196
3197         g_object_unref(device_proxy);
3198
3199         return ret;
3200 }
3201
3202 int _bt_passkey_reply(const char *passkey, gboolean authentication_reply)
3203 {
3204         GapAgentPrivate *agent = _bt_get_adapter_agent();
3205         retv_if(!agent, BLUETOOTH_ERROR_INTERNAL);
3206
3207         if (authentication_reply)
3208                 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, passkey, NULL);
3209         else
3210                 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, passkey, NULL);
3211
3212         BT_DBG("BT_PASSKEY_REPLY");
3213         return BLUETOOTH_ERROR_NONE;
3214 }
3215
3216 int _bt_passkey_confirmation_reply(gboolean confirmation_reply)
3217 {
3218         GapAgentPrivate *agent = _bt_get_adapter_agent();
3219         retv_if(!agent, BLUETOOTH_ERROR_INTERNAL);
3220
3221         if (confirmation_reply)
3222                 gap_agent_reply_confirmation(agent, GAP_AGENT_ACCEPT, NULL);
3223         else
3224                 gap_agent_reply_confirmation(agent, GAP_AGENT_REJECT, NULL);
3225
3226         BT_DBG("BT_PASSKEY_CONFIRMATION_REPLY");
3227         return BLUETOOTH_ERROR_NONE;
3228 }