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