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