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