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