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