8a31963bd7a29604d48056387efcc5ae5750341a
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-adapter.c
1 /*
2  * Bluetooth-frwk
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
7  *               Girishashok Joshi <girish.joshi@samsung.com>
8  *               Chanyeol Park <chanyeol.park@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *              http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */
23
24 #include <stdio.h>
25 #include <dbus/dbus-glib.h>
26 #include <dbus/dbus.h>
27 #include <glib.h>
28 #include <dlog.h>
29 #include <string.h>
30 #include <vconf.h>
31 #include <status.h>
32 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
33 #include <syspopup_caller.h>
34 #endif
35 #if __TIZEN_MOBILE__
36 #include <aul.h>
37 #endif
38 #include <notification.h>
39 #ifdef ENABLE_TIZEN_2_4
40 #include <journal/device.h>
41 #endif
42
43 #include "alarm.h"
44
45 #include "bluetooth-api.h"
46 #include "bt-internal-types.h"
47
48 #include "bt-service-common.h"
49 #include "bt-service-event.h"
50 #include "bt-service-adapter.h"
51 #include "bt-service-util.h"
52 #include "bt-service-network.h"
53 #include "bt-service-obex-server.h"
54 #include "bt-service-agent.h"
55 #include "bt-service-main.h"
56 #include "bt-service-avrcp.h"
57
58 typedef struct {
59         guint event_id;
60         int timeout;
61         time_t start_time;
62         gboolean alarm_init;
63         int alarm_id;
64 } bt_adapter_timer_t;
65
66 bt_adapter_timer_t visible_timer = {0, };
67
68 static gboolean is_discovering;
69 static gboolean is_le_discovering;
70 static bt_le_discovery_type_t le_discovery_type = BT_LE_PASSIVE_SCAN;
71 static gboolean cancel_by_user;
72 static bt_status_t adapter_status = BT_DEACTIVATED;
73 static bt_le_status_t adapter_le_status = BT_LE_DEACTIVATED;
74 static void *adapter_agent = NULL;
75 static DBusGProxy *core_proxy = NULL;
76 static guint timer_id = 0;
77 static guint le_timer_id = 0;
78
79 #define BT_CORE_NAME "org.projectx.bt_core"
80 #define BT_CORE_PATH "/org/projectx/bt_core"
81 #define BT_CORE_INTERFACE "org.projectx.btcore"
82
83 #define BT_DISABLE_TIME 500 /* 500 ms */
84
85 DBusGProxy *_bt_init_core_proxy(void)
86 {
87        DBusGProxy *proxy;
88         DBusGConnection *conn;
89
90         conn = _bt_get_system_gconn();
91         if (!conn)
92                 return NULL;
93
94        proxy = dbus_g_proxy_new_for_name(conn, BT_CORE_NAME,
95                        BT_CORE_PATH, BT_CORE_INTERFACE);
96         if (!proxy)
97                 return NULL;
98
99        core_proxy = proxy;
100
101        return proxy;
102 }
103
104 static DBusGProxy *__bt_get_core_proxy(void)
105 {
106        return (core_proxy) ? core_proxy : _bt_init_core_proxy();
107 }
108
109 static gboolean __bt_is_factory_test_mode(void)
110 {
111         int mode = 0;
112
113 #ifdef ENABLE_TIZEN_2_4
114         if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
115                 BT_ERR("Get the DUT Mode fail");
116                 return TRUE;
117         }
118 #endif
119
120         if (mode != FALSE) {
121                 BT_INFO("DUT Test Mode !!");
122                 return TRUE;
123         }
124
125         return FALSE;
126 }
127
128 static gboolean __bt_timeout_handler(gpointer user_data)
129 {
130         int result = BLUETOOTH_ERROR_NONE;
131         time_t current_time;
132         int time_diff;
133
134         /* Take current time */
135         time(&current_time);
136         time_diff = difftime(current_time, visible_timer.start_time);
137
138         /* Send event to application */
139         _bt_send_event(BT_ADAPTER_EVENT,
140                         BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
141                         DBUS_TYPE_INT32, &result,
142                         DBUS_TYPE_INT16, &time_diff,
143                         DBUS_TYPE_INVALID);
144
145         if (visible_timer.timeout <= time_diff) {
146                 g_source_remove(visible_timer.event_id);
147                 visible_timer.event_id = 0;
148                 visible_timer.timeout = 0;
149
150 #ifndef TIZEN_WEARABLE
151                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
152                         BT_ERR("Set vconf failed\n");
153 #endif
154                 return FALSE;
155         }
156
157         return TRUE;
158 }
159
160 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
161 {
162         BT_DBG("__bt_visibility_alarm_cb - alram id = [%d] \n", alarm_id);
163
164         int result = BLUETOOTH_ERROR_NONE;
165         int timeout = 0;
166
167         if (alarm_id != visible_timer.alarm_id)
168                 return 0;
169
170         if (visible_timer.event_id) {
171                 _bt_send_event(BT_ADAPTER_EVENT,
172                                 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
173                                 DBUS_TYPE_INT32, &result,
174                                 DBUS_TYPE_INT16, &timeout,
175                                 DBUS_TYPE_INVALID);
176                 g_source_remove(visible_timer.event_id);
177                 visible_timer.event_id = 0;
178                 visible_timer.timeout = 0;
179
180 #ifndef TIZEN_WEARABLE
181                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
182                         BT_ERR("Set vconf failed\n");
183 #endif
184         }
185         /* Switch Off visibility in Bluez */
186         _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
187         visible_timer.alarm_id = 0;
188         return 0;
189 }
190
191 static void __bt_visibility_alarm_create()
192 {
193         alarm_id_t alarm_id;
194         int result;
195
196         result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, visible_timer.timeout,
197                                                 0, NULL, &alarm_id);
198         if(result < 0) {
199                 BT_ERR("Failed to create alarm error = %d\n", result);
200         } else {
201                 BT_DBG("Alarm created = %d\n", alarm_id);
202                 visible_timer.alarm_id = alarm_id;
203         }
204 }
205
206 static void __bt_visibility_alarm_remove()
207 {
208         if (visible_timer.event_id > 0) {
209                 g_source_remove(visible_timer.event_id);
210                 visible_timer.event_id = 0;
211         }
212
213         if (visible_timer.alarm_id > 0) {
214                 alarmmgr_remove_alarm(visible_timer.alarm_id);
215                 visible_timer.alarm_id = 0;
216         }
217 }
218
219 int __bt_set_visible_time(int timeout)
220 {
221         int result;
222
223         __bt_visibility_alarm_remove();
224
225         visible_timer.timeout = timeout;
226
227 #ifndef TIZEN_WEARABLE
228         if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
229                 BT_ERR("Set vconf failed");
230 #endif
231         if (timeout <= 0)
232                 return BLUETOOTH_ERROR_NONE;
233
234         if (!visible_timer.alarm_init) {
235                 /* Set Alarm timer to switch off BT */
236                 result = alarmmgr_init("bt-service");
237                 if (result != 0)
238                         return BLUETOOTH_ERROR_INTERNAL;
239
240                 visible_timer.alarm_init = TRUE;
241         }
242
243         result = alarmmgr_set_cb(__bt_visibility_alarm_cb, NULL);
244         if (result != 0)
245                 return BLUETOOTH_ERROR_INTERNAL;
246
247         /* Take start time */
248         time(&(visible_timer.start_time));
249         visible_timer.event_id = g_timeout_add_seconds(1,
250                                 __bt_timeout_handler, NULL);
251
252         __bt_visibility_alarm_create();
253
254         return BLUETOOTH_ERROR_NONE;
255 }
256
257 static void __bt_get_service_list(GValue *value, bluetooth_device_info_t *dev)
258 {
259         int i;
260         char **uuids;
261         char **parts;
262
263         ret_if(value == NULL);
264         ret_if(dev == NULL);
265
266         uuids = g_value_get_boxed(value);
267         ret_if(uuids == NULL);
268
269         dev->service_index = 0;
270
271         for (i = 0; uuids[i] != NULL; i++) {
272                 g_strlcpy(dev->uuids[i], uuids[i], BLUETOOTH_UUID_STRING_MAX);
273
274                 parts = g_strsplit(uuids[i], "-", -1);
275
276                 if (parts == NULL || parts[0] == NULL)
277                         break;
278
279                 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
280                 g_strfreev(parts);
281
282                 dev->service_index++;
283         }
284 }
285
286 static bt_remote_dev_info_t *__bt_parse_remote_device_info(
287                                         DBusMessageIter *item_iter)
288 {
289         DBusMessageIter value_iter;
290         bt_remote_dev_info_t *dev_info;
291
292         dbus_message_iter_recurse(item_iter, &value_iter);
293
294         if (dbus_message_iter_get_arg_type(&value_iter) !=
295                                         DBUS_TYPE_DICT_ENTRY) {
296                 BT_DBG("No entry");
297                 return NULL;
298         }
299
300         dev_info = g_malloc0(sizeof(bt_remote_dev_info_t));
301
302         while (dbus_message_iter_get_arg_type(&value_iter) ==
303                                                 DBUS_TYPE_DICT_ENTRY) {
304                 char *value = NULL;
305                 char *key;
306                 DBusMessageIter dict_entry;
307                 DBusMessageIter iter_dict_val;
308
309                 dbus_message_iter_recurse(&value_iter, &dict_entry);
310
311                 dbus_message_iter_get_basic(&dict_entry, &key);
312
313                 if (key == NULL) {
314                         dbus_message_iter_next(&value_iter);
315                         continue;
316                 }
317
318                 if (!dbus_message_iter_next(&dict_entry)) {
319                         dbus_message_iter_next(&value_iter);
320                         continue;
321                 }
322                 dbus_message_iter_recurse(&dict_entry, &iter_dict_val);
323
324                 if (strcasecmp(key, "Address") == 0) {
325                         const char *address = NULL;
326                         dbus_message_iter_get_basic(&iter_dict_val,
327                                                         &address);
328                         dev_info->address = g_strdup(address);
329                 } else if (strcasecmp(key, "Class") == 0) {
330                         dbus_message_iter_get_basic(&iter_dict_val,
331                                                 &dev_info->class);
332                 } else if (strcasecmp(key, "Name") == 0) {
333                         dbus_message_iter_get_basic(&iter_dict_val,
334                                                         &value);
335                         if (dev_info->name == NULL)
336                                 dev_info->name = g_strdup(value);
337                 } else if (strcasecmp(key, "Connected") == 0) {
338                         dbus_message_iter_get_basic(&iter_dict_val,
339                                                 &dev_info->connected);
340                 } else if (strcasecmp(key, "Paired") == 0) {
341                         dbus_message_iter_get_basic(&iter_dict_val,
342                                                 &dev_info->paired);
343                 } else if (strcasecmp(key, "Trusted") == 0) {
344                         dbus_message_iter_get_basic(&iter_dict_val,
345                                                 &dev_info->trust);
346                 } else if (strcasecmp(key, "RSSI") == 0) {
347                         dbus_message_iter_get_basic(&iter_dict_val,
348                                                 &dev_info->rssi);
349                 } else if (strcasecmp(key, "UUIDs") == 0) {
350                         DBusMessageIter uuid_iter;
351                         DBusMessageIter tmp_iter;
352                         int i = 0;
353
354                         dbus_message_iter_recurse(&iter_dict_val,
355                                                         &uuid_iter);
356                         tmp_iter = uuid_iter;
357
358                         /* Store the uuid count */
359                         while (dbus_message_iter_get_arg_type(&tmp_iter) !=
360                                                         DBUS_TYPE_INVALID) {
361
362                                 dbus_message_iter_get_basic(&tmp_iter,
363                                                                 &value);
364
365                                 dev_info->uuid_count++;
366                                 if (!dbus_message_iter_next(&tmp_iter))
367                                         break;
368                         }
369
370                         /* Store the uuids */
371                         if (dev_info->uuid_count > 0) {
372                                 dev_info->uuids = g_new0(char *,
373                                                 dev_info->uuid_count + 1);
374                         } else {
375                                 dbus_message_iter_next(&value_iter);
376                                 continue;
377                         }
378
379                         while (dbus_message_iter_get_arg_type(&uuid_iter) !=
380                                                         DBUS_TYPE_INVALID) {
381                                 dbus_message_iter_get_basic(&uuid_iter,
382                                                                 &value);
383                                 dev_info->uuids[i] = g_strdup(value);
384                                 i++;
385                                 if (!dbus_message_iter_next(&uuid_iter)) {
386                                         break;
387                                 }
388                         }
389                 }
390
391                 dbus_message_iter_next(&value_iter);
392         }
393
394         return dev_info;
395 }
396
397 static void __bt_extract_remote_devinfo(DBusMessageIter *msg_iter,
398                                                 GArray **dev_list)
399 {
400         bt_remote_dev_info_t *dev_info = NULL;
401         char *object_path = NULL;
402         DBusMessageIter value_iter;
403
404         /* Parse the signature:  oa{sa{sv}}} */
405         ret_if(dbus_message_iter_get_arg_type(msg_iter) !=
406                                         DBUS_TYPE_OBJECT_PATH);
407
408         dbus_message_iter_get_basic(msg_iter, &object_path);
409         ret_if(object_path == NULL);
410
411         /* object array (oa) */
412         ret_if(dbus_message_iter_next(msg_iter) == FALSE);
413         ret_if(dbus_message_iter_get_arg_type(msg_iter) != DBUS_TYPE_ARRAY);
414
415         dbus_message_iter_recurse(msg_iter, &value_iter);
416
417         /* string array (sa) */
418         while (dbus_message_iter_get_arg_type(&value_iter) ==
419                                         DBUS_TYPE_DICT_ENTRY) {
420                 char *interface_name = NULL;
421                 DBusMessageIter interface_iter;
422
423                 dbus_message_iter_recurse(&value_iter, &interface_iter);
424
425                 ret_if(dbus_message_iter_get_arg_type(&interface_iter) !=
426                                                         DBUS_TYPE_STRING);
427
428                 dbus_message_iter_get_basic(&interface_iter, &interface_name);
429
430                 ret_if(dbus_message_iter_next(&interface_iter) == FALSE);
431
432                 ret_if(dbus_message_iter_get_arg_type(&interface_iter) !=
433                                                         DBUS_TYPE_ARRAY);
434
435                 if (g_strcmp0(interface_name, "org.bluez.Device1") == 0) {
436                         BT_DBG("Found a device: %s", object_path);
437                         dev_info = __bt_parse_remote_device_info(
438                                                         &interface_iter);
439
440                         if (dev_info) {
441                                 g_array_append_vals(*dev_list, dev_info,
442                                         sizeof(bt_remote_dev_info_t));
443                         }
444                 }
445
446                 dbus_message_iter_next(&value_iter);
447         }
448 }
449
450 int _bt_get_remote_found_devices(GArray **dev_list)
451 {
452         DBusMessage *msg;
453         DBusMessage *reply;
454         DBusMessageIter reply_iter;
455         DBusMessageIter value_iter;
456         DBusError err;
457         DBusConnection *conn;
458
459         conn = _bt_get_system_conn();
460         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
461
462         msg = dbus_message_new_method_call(BT_BLUEZ_NAME, BT_MANAGER_PATH,
463                                                 BT_MANAGER_INTERFACE,
464                                                 "GetManagedObjects");
465
466         retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
467
468         /* Synchronous call */
469         dbus_error_init(&err);
470         reply = dbus_connection_send_with_reply_and_block(
471                                         conn, msg,
472                                         -1, &err);
473         dbus_message_unref(msg);
474
475         if (!reply) {
476                 BT_ERR("Can't get managed objects");
477
478                 if (dbus_error_is_set(&err)) {
479                         BT_ERR("%s", err.message);
480                         dbus_error_free(&err);
481                 }
482                 return BLUETOOTH_ERROR_INTERNAL;
483         }
484
485         if (dbus_message_iter_init(reply, &reply_iter) == FALSE) {
486                 BT_ERR("Fail to iterate the reply");
487                 return BLUETOOTH_ERROR_INTERNAL;
488         }
489
490         dbus_message_iter_recurse(&reply_iter, &value_iter);
491
492         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
493         while (dbus_message_iter_get_arg_type(&value_iter) ==
494                                                 DBUS_TYPE_DICT_ENTRY) {
495                 DBusMessageIter msg_iter;
496
497                 dbus_message_iter_recurse(&value_iter, &msg_iter);
498
499                 __bt_extract_remote_devinfo(&msg_iter, dev_list);
500
501                 dbus_message_iter_next(&value_iter);
502         }
503
504         return BLUETOOTH_ERROR_NONE;
505 }
506
507 static int __bt_get_bonded_device_info(gchar *device_path,
508                 bluetooth_device_info_t *dev_info)
509 {
510         GValue *value = { 0 };
511         GError *err = NULL;
512         DBusGProxy *device_proxy;
513         const gchar *address;
514         const gchar *name;
515         unsigned int cod;
516         gint rssi;
517         gboolean trust;
518         gboolean paired;
519         gboolean connected;
520         GByteArray *manufacturer_data = NULL;
521         GHashTable *hash = NULL;
522         int ret;
523         DBusGConnection *conn;
524
525         BT_CHECK_PARAMETER(device_path, return);
526         BT_CHECK_PARAMETER(dev_info, return);
527
528         conn = _bt_get_system_gconn();
529         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
530
531         device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
532                                 device_path, BT_PROPERTIES_INTERFACE);
533
534         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
535
536         dbus_g_proxy_call(device_proxy, "GetAll", &err,
537                                 G_TYPE_STRING, BT_DEVICE_INTERFACE,
538                                 G_TYPE_INVALID,
539                                 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
540                                 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
541
542         g_object_unref(device_proxy);
543
544         if (err != NULL) {
545                 BT_ERR("Error occured in Proxy call [%s]\n", err->message);
546                 g_error_free(err);
547                 return BLUETOOTH_ERROR_INTERNAL;
548         }
549
550         if (hash != NULL) {
551                 value = g_hash_table_lookup(hash, "Paired");
552                 paired = g_value_get_boolean(value);
553
554                 value = g_hash_table_lookup(hash, "Address");
555                 address = value ? g_value_get_string(value) : NULL;
556
557                 value = g_hash_table_lookup(hash, "Alias");
558                 name = value ? g_value_get_string(value) : NULL;
559
560                 if (name != NULL)
561                         BT_DBG("Alias Name [%s]", name);
562                 else {
563                         value = g_hash_table_lookup(hash, "Name");
564                         name = value ? g_value_get_string(value) : NULL;
565                 }
566
567                 value = g_hash_table_lookup(hash, "Class");
568                 cod = value ? g_value_get_uint(value) : 0;
569
570                 value = g_hash_table_lookup(hash, "Connected");
571                 connected = value ? g_value_get_boolean(value) : FALSE;
572
573                 value = g_hash_table_lookup(hash, "Trusted");
574                 trust = value ? g_value_get_boolean(value) : FALSE;
575
576                 BT_DBG("paired: %d", paired);
577                 BT_DBG("trust: %d", trust);
578
579                 if ((paired == FALSE) && (trust == FALSE)) {
580                         return BLUETOOTH_ERROR_NOT_PAIRED;
581                 }
582
583                 value = g_hash_table_lookup(hash, "RSSI");
584                 rssi = value ? g_value_get_int(value) : 0;
585
586                 value = g_hash_table_lookup(hash, "UUIDs");
587                 __bt_get_service_list(value, dev_info);
588
589                 value = g_hash_table_lookup(hash, "ManufacturerDataLen");
590                 dev_info->manufacturer_data.data_len = value ? g_value_get_uint(value) : 0;
591
592                 value = g_hash_table_lookup(hash, "ManufacturerData");
593                 manufacturer_data = value ? g_value_get_boxed(value) : NULL;
594                 if (manufacturer_data) {
595                         if (manufacturer_data->len > 0) {
596                                 BT_DBG("manufacturer_data->len  = %d", manufacturer_data->len);
597                                 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
598                         }
599                 }
600
601                 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
602                                                 address);
603
604                 _bt_divide_device_class(&dev_info->device_class, cod);
605
606                 g_strlcpy(dev_info->device_name.name, name,
607                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
608
609                 dev_info->rssi = rssi;
610                 dev_info->trust = trust;
611                 dev_info->paired = paired;
612                 dev_info->connected = connected;
613                 g_hash_table_destroy(hash);
614                 ret = BLUETOOTH_ERROR_NONE;
615         } else {
616                 BT_ERR("Hash is NULL\n");
617                 ret = BLUETOOTH_ERROR_INTERNAL;
618         }
619
620         return ret;
621 }
622
623 void _bt_set_discovery_status(gboolean mode)
624 {
625         is_discovering = mode;
626 }
627
628 void _bt_set_le_discovery_status(gboolean mode)
629 {
630         is_le_discovering = mode;
631 }
632
633 void _bt_set_le_discovery_type(bt_le_discovery_type_t type)
634 {
635         le_discovery_type = type;
636 }
637
638 bt_le_discovery_type_t _bt_get_le_discovery_type(void)
639 {
640         return le_discovery_type;
641 }
642
643 void _bt_set_cancel_by_user(gboolean value)
644 {
645         cancel_by_user = value;
646 }
647
648 gboolean _bt_get_cancel_by_user(void)
649 {
650         return cancel_by_user;
651 }
652
653 void _bt_adapter_set_status(bt_status_t status)
654 {
655         BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status);
656         adapter_status = status;
657 }
658
659 #ifdef __TIZEN_MOBILE__
660 static void __launch_bt_service(int status, int run_type)
661 {
662         bundle *kb;
663         char status_val[5] = { 0, };
664         char run_type_val[5] = { 0, };
665
666         snprintf(status_val, sizeof(status_val), "%d", status);
667         snprintf(run_type_val, sizeof(run_type_val), "%d", run_type);
668
669         BT_DBG("status: %s, run_type: %s", status_val, run_type_val);
670
671         kb = bundle_create();
672
673         bundle_add(kb, "launch-type", "setstate");
674         bundle_add(kb, "status", status_val);
675         bundle_add(kb, "run-type", run_type_val);
676
677         aul_launch_app("org.tizen.bluetooth", kb);
678
679         bundle_free(kb);
680 }
681 #endif
682
683 bt_status_t _bt_adapter_get_status(void)
684 {
685         return adapter_status;
686 }
687
688 void _bt_adapter_set_le_status(bt_le_status_t status)
689 {
690         BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status);
691         adapter_le_status = status;
692 }
693
694 bt_le_status_t _bt_adapter_get_le_status(void)
695 {
696         return adapter_le_status;
697 }
698
699 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
700 {
701         char *phone_name = NULL;
702         char *ptr = NULL;
703
704         if (node == NULL)
705                 return;
706
707         if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
708                 phone_name = vconf_keynode_get_str(node);
709
710                 if (phone_name && strlen(phone_name) != 0) {
711                         if (!g_utf8_validate(phone_name, -1,
712                                                         (const char **)&ptr))
713                                 *ptr = '\0';
714
715                         _bt_set_local_name(phone_name);
716                 }
717         }
718 }
719
720 #ifdef TIZEN_WEARABLE
721 static char * __bt_change_dev_name(const char *default_name)
722 {
723         FILE *fp = NULL;
724         char *buf = NULL;
725         char *name = NULL;
726         int result;
727
728         if ((fp = fopen("/csa/bluetooth/.bd_addr", "r")) == NULL) {
729                 BT_ERR("Unable to open bd_addr");
730                 return NULL;
731         }
732
733         result = fseek(fp, -4, SEEK_END);
734         if (result < 0) {
735                 BT_ERR("fseek is failed");
736                 fclose(fp);
737                 return NULL;
738         }
739
740         buf = (char *)malloc(sizeof(char) * 5);
741         if (buf == NULL) {
742                 BT_ERR("malloc is failed");
743                 fclose(fp);
744                 return NULL;
745         }
746         memset(buf, 0, 5);
747
748         result = fread(buf, 1, 4, fp);
749         if (result)
750                 BT_DBG("Size Read: [%d]", result);
751         else
752                 BT_ERR("Error reading file: code[%d]", result);
753
754         name = g_strdup_printf("%s (%s)", default_name, buf);
755
756         BT_INFO("%s", name);
757
758         free(buf);
759         fclose(fp);
760
761         return name ;
762 }
763 #else
764 static void __bt_set_visible_mode(void)
765 {
766         int timeout = 0;
767
768         if (vconf_get_int(BT_FILE_VISIBLE_TIME, &timeout) != 0)
769                 BT_ERR("Fail to get the timeout value");
770
771         /* -1: Always on */
772 }
773 #endif
774
775 static void __bt_set_local_name(void)
776 {
777         char *phone_name = NULL;
778         char *ptr = NULL;
779
780         phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
781
782         if (!phone_name)
783                 return;
784
785         if (strlen(phone_name) != 0) {
786                 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
787                         *ptr = '\0';
788
789 #ifdef TIZEN_WEARABLE
790                 if (strstr(phone_name, "(") == NULL) {
791                         char *tmp = __bt_change_dev_name(phone_name);
792                         if (tmp != NULL) {
793                                 free(phone_name);
794                                 phone_name = tmp;
795                         }
796                 }
797 #endif
798                 _bt_set_local_name(phone_name);
799         }
800         free(phone_name);
801 }
802
803 int __bt_set_enabled(void)
804 {
805         int adapter_status = BT_ADAPTER_DISABLED;
806         int result = BLUETOOTH_ERROR_NONE;
807
808         _bt_check_adapter(&adapter_status);
809         adapter_status = BT_ADAPTER_ENABLED;
810
811         if (adapter_status == BT_ADAPTER_DISABLED) {
812                 BT_ERR("Bluetoothd is not running");
813                 return BLUETOOTH_ERROR_INTERNAL;
814         }
815
816 #ifndef TIZEN_WEARABLE
817         __bt_set_visible_mode();
818 #endif
819
820         __bt_set_local_name();
821
822         /* Update Bluetooth Status to notify other modules */
823         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
824                 BT_ERR("Set vconf failed\n");
825
826         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
827                 BT_ERR("Set vconf failed\n");
828
829         /* Send enabled event to API */
830         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
831                                 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
832
833         return BLUETOOTH_ERROR_NONE;
834 }
835
836 void _bt_set_disabled(int result)
837 {
838         int power_off_status = 0;
839         int ret;
840         int ret_pm_ignore;
841         int pm_ignore_mode = 0;
842
843         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
844         BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
845
846         ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
847
848         /* Update the vconf BT status in normal Deactivation case only */
849         if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
850                 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
851
852                 BT_DBG("Update vconf for BT normal Deactivation");
853
854                 if (result == BLUETOOTH_ERROR_TIMEOUT)
855                         if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0 )
856                                 BT_ERR("Set vconf failed");
857
858                 /* Update Bluetooth Status to notify other modules */
859                 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
860                         BT_ERR("Set vconf failed");
861         }
862
863         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
864                 BT_ERR("Set vconf failed\n");
865
866         _bt_adapter_set_status(BT_DEACTIVATED);
867
868                 /* Send disabled event */
869         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
870                         DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
871
872 #if 0
873         if (_bt_adapter_get_le_status() != BT_LE_DEACTIVATED) {
874                 /* Send disabled event */
875                 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
876                                 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
877         }
878 #endif
879 }
880
881 static int __bt_set_le_enabled(void)
882 {
883         BT_DBG("+");
884         int result = BLUETOOTH_ERROR_NONE;
885         bt_status_t status;
886
887         __bt_set_local_name();
888
889 #ifdef ENABLE_TIZEN_2_4
890         /* Update Bluetooth Status to notify other modules */
891         if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
892                 BT_ERR("Set vconf failed\n");
893 #endif
894         /* Send enabled event to API */
895         /*
896         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
897                                 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
898         */
899         status = _bt_adapter_get_status();
900         if (status == BT_DEACTIVATED) {
901                 BT_INFO("BREDR is off, turn off PSCAN");
902                 _bt_set_connectable(FALSE);
903         }
904         if (le_timer_id > 0) {
905                 g_source_remove(le_timer_id);
906                 le_timer_id = 0;
907         }
908
909         /* Send enabled event to API */
910         _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED,
911                                 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
912
913         BT_DBG("-");
914         return BLUETOOTH_ERROR_NONE;
915 }
916
917 void _bt_set_le_disabled(int result)
918 {
919         int power_off_status;
920         int ret;
921
922         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
923         BT_DBG("ret : %d", ret);
924         BT_DBG("power_off_status : %d", power_off_status);
925
926         /* Update Bluetooth Status to notify other modules */
927         BT_DBG("Update vconf for BT LE normal Deactivation");
928 #ifdef ENABLE_TIZEN_2_4
929         if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
930                 BT_ERR("Set vconf failed\n");
931         _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
932 #endif
933
934         if (_bt_adapter_get_status() != BT_DEACTIVATED) {
935                 /* Send disabled event */
936                 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
937                                 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
938         }
939 }
940
941 void *_bt_get_adapter_agent(void)
942 {
943         return adapter_agent;
944 }
945
946 int _bt_enable_core(void)
947 {
948         DBusGProxy *proxy;
949
950         proxy = __bt_get_core_proxy();
951         retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
952
953         if (dbus_g_proxy_call(proxy, "EnableCore", NULL,
954                         G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
955                 BT_ERR("Bt core call failed");
956         }
957
958         return BLUETOOTH_ERROR_NONE;
959 }
960
961 static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data)
962 {
963         gboolean flight_mode = FALSE;
964         int power_saving_mode = 0;
965         int type;
966
967         DBG_SECURE("key=%s", vconf_keynode_get_name(node));
968         type = vconf_keynode_get_type(node);
969         if (type == VCONF_TYPE_BOOL) {
970                 flight_mode = vconf_keynode_get_bool(node);
971                 if (flight_mode != TRUE) {
972                         BT_ERR("Ignore the event");
973                         return;
974                 }
975         } else if (type == VCONF_TYPE_INT) {
976                 power_saving_mode = vconf_keynode_get_int(node);
977                 if (power_saving_mode != 2) {
978                         BT_ERR("Ignore the event");
979                         return;
980                 }
981         } else {
982                 BT_ERR("Invaild vconf key type : %d", type);
983                 return;
984         }
985
986         _bt_enable_core();
987 }
988
989 void _bt_service_register_vconf_handler(void)
990 {
991         int ret;
992         BT_DBG("+");
993
994 #ifdef TIZEN_TELEPHONY_ENABLED
995         ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
996                 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL);
997         if (ret < 0)
998                 BT_ERR("Unable to register key handler");
999 #else
1000         BT_DBG("Telephony is disabled");
1001 #endif
1002
1003 #ifndef TIZEN_WEARABLE
1004 #ifdef ENABLE_TIZEN_2_4
1005         ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
1006                         (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL);
1007         if (ret < 0)
1008                 BT_ERR("Unable to register key handler");
1009 #endif
1010 #endif
1011 }
1012
1013 void _bt_service_unregister_vconf_handler(void)
1014 {
1015         BT_DBG("+");
1016
1017 #ifdef TIZEN_TELEPHONY_ENABLED
1018         vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
1019                 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
1020 #endif
1021
1022 #ifndef TIZEN_WEARABLE
1023 #ifdef ENABLE_TIZEN_2_4
1024         vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
1025                         (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
1026 #endif
1027 #endif
1028 }
1029
1030 static int _bt_set_powered(gboolean is_powered)
1031 {
1032         DBusGProxy *proxy;
1033         GValue powered = { 0 };
1034         GError *error = NULL;
1035
1036         if (__bt_is_factory_test_mode()) {
1037                 BT_ERR("Unable to set power in factory binary !!");
1038                 return BLUETOOTH_ERROR_NOT_SUPPORT;
1039         }
1040
1041         proxy = _bt_get_adapter_properties_proxy();
1042
1043         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1044
1045         g_value_init(&powered, G_TYPE_BOOLEAN);
1046         g_value_set_boolean(&powered, is_powered);
1047
1048         dbus_g_proxy_call(proxy, "Set", &error,
1049                                                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1050                                                         G_TYPE_STRING, "Powered",
1051                                                         G_TYPE_VALUE, &powered,
1052                                                         G_TYPE_INVALID, G_TYPE_INVALID);
1053
1054         g_value_unset(&powered);
1055         if (error != NULL) {
1056                 BT_ERR("Powered set err:\n [%s]", error->message);
1057                 g_error_free(error);
1058                 return BLUETOOTH_ERROR_INTERNAL;
1059         }
1060
1061         BT_INFO("Set powered [%d]", is_powered);
1062         return BLUETOOTH_ERROR_NONE;
1063 }
1064
1065 void _bt_handle_adapter_added(void)
1066 {
1067         BT_DBG("+");
1068         bt_status_t status;
1069         bt_le_status_t le_status;
1070         int ret;
1071
1072         if (timer_id > 0) {
1073                 BT_DBG("g_source is removed");
1074                 g_source_remove(timer_id);
1075                 timer_id = 0;
1076         }
1077
1078         status = _bt_adapter_get_status();
1079         le_status = _bt_adapter_get_le_status();
1080         BT_DBG("status : %d", status);
1081         BT_DBG("le_status : %d", le_status);
1082
1083         adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
1084         if (!adapter_agent) {
1085                 BT_ERR("Fail to register agent");
1086                 //return;
1087         }
1088
1089 #ifdef __TIZEN_MOBILE__
1090         if (!aul_app_is_running("org.tizen.bluetooth"))
1091                         __launch_bt_service(0, 0);
1092
1093         if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
1094                 BT_ERR("Fail to register media player");
1095
1096 #endif
1097
1098         if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
1099                 BT_ERR("Fail to init obex server");
1100
1101 #ifndef TIZEN_WEARABLE
1102 /*
1103         if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
1104                 BT_ERR("Fail to activate network");
1105 */
1106 #endif
1107
1108         /* add the vconf noti handler */
1109         ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
1110                                         __bt_phone_name_changed_cb, NULL);
1111         if (ret < 0)
1112                 BT_ERR("Unable to register key handler");
1113
1114         if (le_status == BT_LE_ACTIVATING) {
1115                 __bt_set_le_enabled();
1116                 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1117         }
1118
1119         BT_ERR("Activating BT ......");
1120
1121         if (status == BT_ACTIVATING) {
1122                 __bt_set_enabled();
1123                 _bt_adapter_set_status(BT_ACTIVATED);
1124         }
1125 #ifdef ENABLE_TIZEN_2_4
1126         journal_bt_on();
1127 #endif
1128
1129         _bt_service_register_vconf_handler();
1130 }
1131
1132 void _bt_handle_adapter_removed(void)
1133 {
1134         int ret;
1135
1136         _bt_adapter_set_status(BT_DEACTIVATED);
1137 #ifdef ENABLE_TIZEN_2_4
1138         journal_bt_off();
1139 #endif
1140
1141         __bt_visibility_alarm_remove();
1142
1143         if (visible_timer.alarm_init) {
1144                 alarmmgr_fini();
1145                 visible_timer.alarm_init = FALSE;
1146         }
1147
1148         ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
1149                                 (vconf_callback_fn)__bt_phone_name_changed_cb);
1150         if (0 != ret) {
1151                 ERR("vconf_ignore_key_changed failed\n");
1152         }
1153
1154         _bt_destroy_agent(adapter_agent);
1155         adapter_agent = NULL;
1156
1157         _bt_reliable_terminate_service(NULL);
1158 }
1159
1160 static gboolean __bt_enable_timeout_cb(gpointer user_data)
1161 {
1162         DBusGProxy *proxy;
1163
1164         timer_id = 0;
1165
1166         retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE);
1167
1168         BT_ERR("EnableAdapter is failed");
1169
1170         proxy = __bt_get_core_proxy();
1171         if (!proxy)
1172                 return FALSE;
1173
1174         /* Clean up the process */
1175         if (dbus_g_proxy_call(proxy, "DisableAdapter", NULL,
1176                                 G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
1177                 BT_ERR("Bt core call failed");
1178         }
1179
1180         _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
1181
1182         /* Display notification */
1183         notification_status_message_post(BT_STR_NOT_SUPPORT);
1184
1185         _bt_terminate_service(NULL);
1186
1187         return FALSE;
1188 }
1189
1190 static gboolean __bt_enable_le_timeout_cb(gpointer user_data)
1191 {
1192         DBusGProxy *proxy;
1193
1194         le_timer_id = 0;
1195
1196         retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE);
1197
1198         BT_ERR("EnableAdapterLE is failed");
1199
1200         proxy = __bt_get_core_proxy();
1201         if (!proxy)
1202                 return FALSE;
1203
1204         /* Clean up the process */
1205         if (dbus_g_proxy_call(proxy, "DisableAdapterLe", NULL,
1206                                 G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
1207                 BT_ERR("Bt core call failed");
1208         }
1209
1210         _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
1211
1212         _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
1213
1214         /* Display notification */
1215         notification_status_message_post(BT_STR_NOT_SUPPORT);
1216
1217         if (_bt_adapter_get_status() == BT_DEACTIVATED)
1218                 _bt_terminate_service(NULL);
1219
1220         return FALSE;
1221 }
1222
1223 void _bt_adapter_start_le_enable_timer(void)
1224 {
1225         if (le_timer_id > 0) {
1226                 g_source_remove(le_timer_id);
1227                 le_timer_id = 0;
1228         }
1229
1230         le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
1231                         __bt_enable_le_timeout_cb, NULL);
1232
1233         return;
1234 }
1235
1236 void _bt_adapter_start_enable_timer(void)
1237 {
1238         if (timer_id > 0) {
1239                 g_source_remove(timer_id);
1240                 timer_id = 0;
1241         }
1242
1243         timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
1244                         __bt_enable_timeout_cb, NULL);
1245
1246         return;
1247 }
1248
1249 int _bt_enable_adapter(void)
1250 {
1251         DBusGProxy *proxy;
1252         GError *err = NULL;
1253         int ret;
1254         bt_status_t status = _bt_adapter_get_status();
1255         bt_le_status_t le_status = _bt_adapter_get_le_status();
1256         BT_DBG("");
1257
1258         if (status == BT_ACTIVATING) {
1259                 BT_ERR("Enabling in progress");
1260                 return BLUETOOTH_ERROR_IN_PROGRESS;
1261         }
1262
1263         if (status == BT_ACTIVATED) {
1264                 BT_ERR("Already enabled");
1265                 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1266         }
1267
1268         if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1269                 BT_ERR("Disabling in progress");
1270                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1271         }
1272
1273         _bt_adapter_set_status(BT_ACTIVATING);
1274
1275         proxy = __bt_get_core_proxy();
1276         if (!proxy)
1277                 return BLUETOOTH_ERROR_INTERNAL;
1278
1279         if (le_status == BT_LE_ACTIVATED) {
1280                 BT_INFO("LE Already enabled. Just turn on PSCAN");
1281                 ret = _bt_set_connectable(TRUE);
1282                 if (ret == BLUETOOTH_ERROR_NONE) {
1283                         _bt_adapter_set_status(BT_ACTIVATED);
1284                 } else {
1285                         return BLUETOOTH_ERROR_INTERNAL;
1286                 }
1287         }
1288          if (dbus_g_proxy_call_with_timeout(proxy, "EnableAdapter",
1289                                         BT_ENABLE_TIMEOUT, &err,
1290                                         G_TYPE_INVALID,
1291                                         G_TYPE_INVALID) == FALSE) {
1292
1293                 _bt_adapter_set_status(BT_DEACTIVATED);
1294
1295                 if (err != NULL) {
1296                         BT_ERR("Bt core call failed: [%s]", err->message);
1297                         g_error_free(err);
1298                 }
1299
1300                 /* Clean up the process */
1301                 if (dbus_g_proxy_call(proxy, "DisableAdapter", NULL,
1302                                 G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
1303                                 BT_ERR("Bt core call failed");
1304                 }
1305
1306                 /* Display notification */
1307                 notification_status_message_post(BT_STR_NOT_SUPPORT);
1308
1309                 /* Terminate myself */
1310                 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1311                 return BLUETOOTH_ERROR_INTERNAL;
1312         }
1313
1314         if (le_status == BT_LE_ACTIVATED) {
1315                 __bt_set_enabled();
1316         } else {
1317                 _bt_adapter_start_enable_timer();
1318         }
1319
1320         return BLUETOOTH_ERROR_NONE;
1321 }
1322
1323 static gboolean __bt_disconnect_all(void)
1324 {
1325         int i;
1326         DBusGConnection *conn;
1327         DBusGProxy *dev_proxy;
1328         gboolean ret = FALSE;
1329
1330         GArray *device_list;
1331         bluetooth_device_info_t info;
1332         guint size;
1333         char *device_path = NULL;
1334         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1335
1336
1337         BT_DBG("");
1338
1339         conn = _bt_get_system_gconn();
1340
1341         device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
1342
1343         if (_bt_get_bonded_devices(&device_list)
1344                                         != BLUETOOTH_ERROR_NONE) {
1345                 g_array_free(device_list, TRUE);
1346                 return FALSE;
1347         }
1348
1349         size = (device_list->len) / sizeof(bluetooth_device_info_t);
1350
1351         for (i = 0; i < size; i++) {
1352
1353                 info = g_array_index(device_list,
1354                                 bluetooth_device_info_t, i);
1355
1356                 if (info.connected == TRUE) {
1357                         BT_DBG("Found Connected device");
1358                         _bt_convert_addr_type_to_string(address, info.device_address.addr);
1359                         device_path = _bt_get_device_object_path(address);
1360                         if (device_path == NULL)
1361                                 continue;
1362
1363                         BT_DBG("Disconnecting : %s", device_path);
1364
1365                         dev_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1366                                         device_path, BT_DEVICE_INTERFACE);
1367                         if (dev_proxy == NULL)
1368                                 continue;
1369
1370                         if(!dbus_g_proxy_call(dev_proxy, "Disconnect",
1371                                                 NULL, G_TYPE_INVALID, G_TYPE_INVALID)) {
1372                                 BT_ERR("Disconnect fail error.");
1373                                 g_object_unref(dev_proxy);
1374                                 return FALSE;
1375                         }
1376                 }
1377         }
1378         ret = TRUE;
1379         g_array_free(device_list, TRUE);
1380
1381         return ret;
1382 }
1383
1384 static gboolean __bt_set_disabled_timeout_cb(gpointer user_data)
1385 {
1386         BT_DBG("");
1387         _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1388
1389         return FALSE;
1390 }
1391
1392 int __bt_disable_cb(void)
1393 {
1394         FN_START;
1395         DBusGProxy *proxy;
1396         bt_le_status_t le_status;
1397         int ret;
1398
1399         _bt_adapter_set_status(BT_DEACTIVATING);
1400         le_status = _bt_adapter_get_le_status();
1401         BT_DBG("le_status : %d", le_status);
1402         if (le_status == BT_LE_ACTIVATED) {
1403                 BT_INFO("LE is enabled. Just turn off PSCAN");
1404
1405                 if (_bt_is_discovering())
1406                         _bt_cancel_discovery();
1407
1408                 if (_bt_is_connectable() == FALSE) {
1409                         g_timeout_add(100, (GSourceFunc)__bt_set_disabled_timeout_cb, NULL);
1410                 } else {
1411                         ret = _bt_set_connectable(FALSE);
1412                         if (ret != BLUETOOTH_ERROR_NONE) {
1413                                 BT_ERR("_bt_set_connectable fail!");
1414                                 _bt_adapter_set_status(BT_ACTIVATED);
1415                                 return BLUETOOTH_ERROR_INTERNAL;
1416                         }
1417                 }
1418         }
1419
1420         proxy = __bt_get_core_proxy();
1421         retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1422
1423         if (dbus_g_proxy_call(proxy, "DisableAdapter", NULL,
1424                         G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
1425                 BT_ERR("Bt core call failed");
1426                 _bt_adapter_set_status(BT_ACTIVATED);
1427                 return BLUETOOTH_ERROR_INTERNAL;
1428         }
1429
1430         return BLUETOOTH_ERROR_NONE;
1431 }
1432
1433 int _bt_disable_adapter(void)
1434 {
1435         int ret;
1436
1437         if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1438                 BT_DBG("Disabling in progress");
1439                 return BLUETOOTH_ERROR_IN_PROGRESS;
1440         }
1441
1442         if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1443                 BT_DBG("Already disabled");
1444                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1445         }
1446
1447         if (timer_id > 0) {
1448                 g_source_remove(timer_id);
1449                 timer_id = 0;
1450         }
1451
1452         __bt_disconnect_all();
1453
1454         ret = __bt_disable_cb();
1455
1456         BT_DBG("-");
1457         return ret;
1458 }
1459
1460 int _bt_recover_adapter(void)
1461 {
1462         BT_DBG("+");
1463         DBusGProxy *proxy;
1464
1465         if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1466                 BT_DBG("Disabling in progress");
1467                 return BLUETOOTH_ERROR_IN_PROGRESS;
1468         }
1469
1470         if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1471                 BT_DBG("Already disabled");
1472                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1473         }
1474
1475         _bt_adapter_set_status(BT_DEACTIVATING);
1476
1477         proxy = __bt_get_core_proxy();
1478         retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1479
1480         if (dbus_g_proxy_call(proxy, "RecoverAdapter", NULL,
1481                                        G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
1482                 BT_ERR("Bt core call failed");
1483                 return BLUETOOTH_ERROR_INTERNAL;
1484         }
1485
1486         __bt_disconnect_all();
1487
1488         BT_ERR("-");
1489         return BLUETOOTH_ERROR_NONE;
1490 }
1491
1492 int _bt_reset_adapter(void)
1493 {
1494         DBusGProxy *proxy;
1495
1496         BT_DBG("");
1497
1498         proxy = __bt_get_core_proxy();
1499         if (!proxy)
1500                 return BLUETOOTH_ERROR_INTERNAL;
1501
1502         if (dbus_g_proxy_call(proxy, "ResetAdapter", NULL,
1503                                        G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
1504                 BT_ERR("Bt core call failed");
1505                 return BLUETOOTH_ERROR_INTERNAL;
1506         }
1507
1508         /* Terminate myself */
1509         if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1510                 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1511         }
1512
1513         return BLUETOOTH_ERROR_NONE;
1514 }
1515
1516 int _bt_check_adapter(int *status)
1517 {
1518         char *adapter_path = NULL;
1519
1520         BT_CHECK_PARAMETER(status, return);
1521
1522         *status = BT_ADAPTER_DISABLED;
1523
1524         adapter_path = _bt_get_adapter_path();
1525
1526
1527         if (adapter_path != NULL)
1528                 *status = BT_ADAPTER_ENABLED;
1529
1530         g_free(adapter_path);
1531
1532         return BLUETOOTH_ERROR_NONE;
1533 }
1534
1535 int _bt_enable_adapter_le(void)
1536 {
1537         BT_DBG("+");
1538         DBusGProxy *proxy;
1539         GError *err = NULL;
1540         bt_status_t status = _bt_adapter_get_status();
1541         bt_le_status_t le_status = _bt_adapter_get_le_status();
1542
1543         if (le_status == BT_LE_ACTIVATING) {
1544                 BT_ERR("Enabling in progress");
1545                 return BLUETOOTH_ERROR_IN_PROGRESS;
1546         }
1547
1548         if (le_status == BT_LE_ACTIVATED) {
1549                 BT_ERR("Already enabled");
1550                 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1551         }
1552
1553         if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1554                 BT_ERR("Disabling in progress");
1555                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1556         }
1557
1558         _bt_adapter_set_le_status(BT_LE_ACTIVATING);
1559
1560         proxy = __bt_get_core_proxy();
1561         retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1562
1563 #if 0 // vconf key not found so commenting to resolve build issues.
1564         if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
1565                 BT_ERR("Set vconf failed");
1566 #endif
1567
1568         if (dbus_g_proxy_call_with_timeout(proxy, "EnableAdapterLe",
1569                                 BT_ENABLE_TIMEOUT, &err,
1570                                 G_TYPE_INVALID,
1571                                 G_TYPE_INVALID) == FALSE) {
1572
1573                 _bt_adapter_set_le_status(BT_DEACTIVATED);
1574
1575                 if (err != NULL) {
1576                         BT_ERR("Bt core call failed: [%s]", err->message);
1577                         g_error_free(err);
1578                 }
1579
1580                 /* Clean up the process */
1581                 if (dbus_g_proxy_call(proxy, "DisableAdapterLe", NULL,
1582                                         G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
1583                         BT_ERR("Bt core call failed");
1584                 }
1585
1586                 /* Display notification */
1587                 notification_status_message_post(BT_STR_NOT_SUPPORT);
1588
1589                 /* Terminate myself */
1590                 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1591                         g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1592                 return BLUETOOTH_ERROR_INTERNAL;
1593         }
1594
1595         _bt_adapter_start_le_enable_timer();
1596
1597         if (status == BT_ACTIVATED) {
1598                 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1599                 __bt_set_le_enabled();
1600         }
1601         BT_DBG("le status : %d", _bt_adapter_get_le_status());
1602         BT_DBG("-");
1603         return BLUETOOTH_ERROR_NONE;
1604 }
1605
1606 int _bt_disable_adapter_le(void)
1607 {
1608         BT_DBG("+");
1609         DBusGProxy *proxy;
1610         bt_le_status_t bt_le_state;
1611
1612         bt_le_state = _bt_adapter_get_le_status();
1613         if (bt_le_state == BT_LE_DEACTIVATING) {
1614                 BT_DBG("Disabling in progress");
1615                 return BLUETOOTH_ERROR_IN_PROGRESS;
1616         }
1617
1618         if (bt_le_state == BT_LE_DEACTIVATED) {
1619                 BT_DBG("Already disabled");
1620                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1621         }
1622
1623         _bt_adapter_set_le_status(BT_LE_DEACTIVATING);
1624
1625         proxy = __bt_get_core_proxy();
1626         if (!proxy)
1627                 return BLUETOOTH_ERROR_INTERNAL;
1628 #if 0 // vconf key not found so commenting to resolve build issues.
1629         if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
1630                 BT_ERR("Set vconf failed");
1631 #endif
1632
1633         if (dbus_g_proxy_call(proxy, "DisableAdapterLe", NULL,
1634                                        G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
1635                 BT_ERR("Bt core call failed");
1636                 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1637                 return BLUETOOTH_ERROR_INTERNAL;
1638        }
1639
1640         _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1641         BT_DBG("le status : %d", _bt_adapter_get_le_status());
1642         BT_DBG("-");
1643         return BLUETOOTH_ERROR_NONE;
1644 }
1645
1646 int _bt_get_local_address(bluetooth_device_address_t *local_address)
1647 {
1648
1649         DBusGProxy *proxy;
1650         GError *err = NULL;
1651         char *address;
1652         GValue address_v = { 0 };
1653
1654         BT_CHECK_PARAMETER(local_address, return);
1655
1656         proxy = _bt_get_adapter_properties_proxy();
1657         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1658
1659         if (!dbus_g_proxy_call(proxy, "Get", &err,
1660                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1661                         G_TYPE_STRING, "Address",
1662                         G_TYPE_INVALID,
1663                         G_TYPE_VALUE, &address_v,
1664                         G_TYPE_INVALID)) {
1665                 if (err != NULL) {
1666                         BT_ERR("Getting property failed: [%s]\n", err->message);
1667                         g_error_free(err);
1668                 }
1669                 return BLUETOOTH_ERROR_INTERNAL;
1670         }
1671
1672         address = (char *)g_value_get_string(&address_v);
1673
1674         if (address) {
1675                 _bt_convert_addr_string_to_type(local_address->addr, address);
1676         } else {
1677                 return BLUETOOTH_ERROR_INTERNAL;
1678         }
1679
1680         return BLUETOOTH_ERROR_NONE;
1681 }
1682
1683 int _bt_get_local_version(bluetooth_version_t *local_version)
1684 {
1685         DBusGProxy *proxy;
1686         GHashTable *hash = NULL;
1687         char *ver = NULL;
1688         char *ptr = NULL;
1689         int ret = BLUETOOTH_ERROR_NONE;
1690
1691         BT_CHECK_PARAMETER(local_version, return);
1692
1693         GError *err = NULL;
1694         GValue version_v = { 0 };
1695
1696         proxy = _bt_get_adapter_properties_proxy();
1697         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1698
1699         if (!dbus_g_proxy_call(proxy, "Get", &err,
1700                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1701                         G_TYPE_STRING, "Version",
1702                         G_TYPE_INVALID,
1703                         G_TYPE_VALUE, &version_v,
1704                         G_TYPE_INVALID)) {
1705                 if (err != NULL) {
1706                         BT_ERR("Getting property failed: [%s]\n", err->message);
1707                         g_error_free(err);
1708                 }
1709                 return BLUETOOTH_ERROR_INTERNAL;
1710         }
1711
1712         ver = (char *)g_value_get_string(&version_v);
1713
1714
1715         if (ver && (strlen(ver) > 0)) {
1716                 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1717                 if (!g_utf8_validate(ver, -1, (const char **)&ptr))
1718                         *ptr = '\0';
1719
1720                 g_strlcpy(local_version->version, ver,
1721                                 BLUETOOTH_VERSION_LENGTH_MAX + 1);
1722
1723         } else {
1724                 ret = BLUETOOTH_ERROR_INTERNAL;
1725         }
1726
1727         g_hash_table_destroy(hash);
1728         return ret;
1729 }
1730
1731 int _bt_get_local_name(bluetooth_device_name_t *local_name)
1732 {
1733         DBusGProxy *proxy;
1734         GHashTable *hash = NULL;
1735         char *name = NULL;
1736         char *ptr = NULL;
1737         int ret = BLUETOOTH_ERROR_NONE;
1738
1739         GError *err = NULL;
1740         GValue name_v = { 0 };
1741
1742         BT_CHECK_PARAMETER(local_name, return);
1743
1744         proxy = _bt_get_adapter_properties_proxy();
1745         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1746
1747         if (!dbus_g_proxy_call(proxy, "Get", &err,
1748                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1749                         G_TYPE_STRING, "Alias",
1750                         G_TYPE_INVALID,
1751                         G_TYPE_VALUE, &name_v,
1752                         G_TYPE_INVALID)) {
1753                 if (err != NULL) {
1754                         BT_ERR("Getting property failed: [%s]\n", err->message);
1755                         g_error_free(err);
1756                 }
1757                 return BLUETOOTH_ERROR_INTERNAL;
1758         }
1759
1760         name = (char *)g_value_get_string(&name_v);
1761
1762         if (name && (strlen(name) > 0)) {
1763                 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1764                 if (!g_utf8_validate(name, -1, (const char **)&ptr))
1765                         *ptr = '\0';
1766
1767                 g_strlcpy(local_name->name, name,
1768                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
1769         } else {
1770                 ret = BLUETOOTH_ERROR_INTERNAL;
1771         }
1772
1773         g_hash_table_destroy(hash);
1774         return ret;
1775 }
1776
1777 int _bt_set_local_name(char *local_name)
1778 {
1779         GValue name = { 0 };
1780         DBusGProxy *proxy;
1781         GError *error = NULL;
1782         char *ptr = NULL;
1783
1784         BT_CHECK_PARAMETER(local_name, return);
1785
1786         proxy = _bt_get_adapter_properties_proxy();
1787
1788         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1789
1790         if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
1791                 *ptr = '\0';
1792
1793         g_value_init(&name, G_TYPE_STRING);
1794         g_value_set_string(&name, local_name);
1795
1796         dbus_g_proxy_call(proxy, "Set", &error,
1797                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1798                         G_TYPE_STRING, "Alias",
1799                         G_TYPE_VALUE, &name,
1800                         G_TYPE_INVALID, G_TYPE_INVALID);
1801
1802         g_value_unset(&name);
1803
1804         if (error) {
1805                 BT_ERR("SetProperty Fail: %s", error->message);
1806                 g_error_free(error);
1807                 return BLUETOOTH_ERROR_INTERNAL;
1808         }
1809
1810         return BLUETOOTH_ERROR_NONE;
1811 }
1812
1813 int _bt_is_service_used(char *service_uuid, gboolean *used)
1814 {
1815         char **uuids;
1816         int i;
1817         DBusGProxy *proxy;
1818         GError *err = NULL;
1819         GValue uuids_v = { 0 };
1820         int ret = BLUETOOTH_ERROR_NONE;
1821
1822         BT_DBG("+");
1823         BT_CHECK_PARAMETER(service_uuid, return);
1824         BT_CHECK_PARAMETER(used, return);
1825
1826         proxy = _bt_get_adapter_properties_proxy();
1827         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1828
1829         if (!dbus_g_proxy_call(proxy, "Get", &err,
1830                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1831                         G_TYPE_STRING, "UUIDs",
1832                         G_TYPE_INVALID,
1833                         G_TYPE_VALUE, &uuids_v,
1834                         G_TYPE_INVALID)) {
1835                 if (err != NULL) {
1836                         BT_ERR("Getting property failed: [%s]\n", err->message);
1837                         g_error_free(err);
1838                 }
1839                 return BLUETOOTH_ERROR_INTERNAL;
1840         }
1841
1842         uuids = g_value_get_boxed(&uuids_v);
1843
1844         if (uuids == NULL) {
1845                 /* Normal case */
1846                 *used = FALSE;
1847                 goto done;
1848         }
1849
1850         for (i = 0; uuids[i] != NULL; i++) {
1851                 if (strcasecmp(uuids[i], service_uuid) == 0) {
1852                         *used = TRUE;
1853                         goto done;
1854                 }
1855         }
1856
1857         *used = FALSE;
1858 done:
1859         BT_DBG("Service Used? %d", *used);
1860         return ret;
1861 }
1862
1863
1864 static gboolean __bt_get_discoverable_property(void)
1865 {
1866         DBusGProxy *proxy;
1867         GValue discoverable_v = { 0 };
1868         GError *err = NULL;
1869
1870         proxy = _bt_get_adapter_properties_proxy();
1871         retv_if(proxy == NULL, FALSE);
1872
1873         if (!dbus_g_proxy_call(proxy, "Get", &err,
1874                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1875                         G_TYPE_STRING, "Discoverable",
1876                         G_TYPE_INVALID,
1877                         G_TYPE_VALUE, &discoverable_v,
1878                         G_TYPE_INVALID)) {
1879                 if (err != NULL) {
1880                         BT_ERR("Getting property failed: [%s]\n", err->message);
1881                         g_error_free(err);
1882                 }
1883                 return FALSE;
1884         }
1885
1886         return g_value_get_boolean(&discoverable_v);
1887 }
1888
1889 int _bt_get_discoverable_mode(int *mode)
1890 {
1891         gboolean discoverable;
1892         unsigned int timeout;
1893
1894         BT_CHECK_PARAMETER(mode, return);
1895
1896         discoverable = __bt_get_discoverable_property();
1897         timeout = _bt_get_discoverable_timeout_property();
1898
1899         if (discoverable == TRUE) {
1900                 if (timeout == 0)
1901                         *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1902                 else
1903                         *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
1904         } else {
1905                 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1906         }
1907         return BLUETOOTH_ERROR_NONE;
1908 }
1909
1910
1911 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
1912 {
1913         int ret = BLUETOOTH_ERROR_NONE;
1914         gboolean inq_scan;
1915         gboolean pg_scan;
1916         GError *error = NULL;
1917         GValue connectable = { 0 };
1918         GValue discoverable = { 0 };
1919         GValue val_timeout = { 0 };
1920         DBusGProxy *proxy;
1921
1922         proxy = _bt_get_adapter_properties_proxy();
1923
1924         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1925
1926         g_value_init(&connectable, G_TYPE_BOOLEAN);
1927         g_value_init(&discoverable, G_TYPE_BOOLEAN);
1928         g_value_init(&val_timeout, G_TYPE_UINT);
1929
1930         switch (discoverable_mode) {
1931         case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
1932                 pg_scan = TRUE;
1933                 inq_scan = FALSE;
1934                 timeout = 0;
1935                 break;
1936         case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
1937                 pg_scan = TRUE;
1938                 inq_scan = TRUE;
1939                 timeout = 0;
1940                 break;
1941         case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
1942                 inq_scan = TRUE;
1943                 pg_scan = TRUE;
1944                 break;
1945         default:
1946                 return BLUETOOTH_ERROR_INVALID_PARAM;
1947         }
1948
1949         BT_INFO("Req. discoverable_mode : %d, timeout : %d",
1950                         discoverable_mode, timeout);
1951
1952         g_value_set_boolean(&connectable, pg_scan);
1953         g_value_set_boolean(&discoverable, inq_scan);
1954         g_value_set_uint(&val_timeout, timeout);
1955
1956         dbus_g_proxy_call(proxy, "Set", &error,
1957                                 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1958                                 G_TYPE_STRING, "Connectable",
1959                                 G_TYPE_VALUE, &connectable,
1960                                 G_TYPE_INVALID, G_TYPE_INVALID);
1961
1962         if (error != NULL) {
1963                 BT_ERR("Connectable set err:[%s]", error->message);
1964                 g_error_free(error);
1965                 ret = BLUETOOTH_ERROR_INTERNAL;
1966                 goto done;
1967         }
1968
1969         dbus_g_proxy_call(proxy, "Set", &error,
1970                                 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1971                                 G_TYPE_STRING, "Discoverable",
1972                                 G_TYPE_VALUE, &discoverable,
1973                                 G_TYPE_INVALID, G_TYPE_INVALID);
1974
1975
1976         if (error != NULL) {
1977                 BT_ERR("Discoverable set err:[%s]", error->message);
1978                 g_error_free(error);
1979                 ret = BLUETOOTH_ERROR_INTERNAL;
1980                 goto done;
1981         }
1982
1983         dbus_g_proxy_call(proxy, "Set", &error,
1984                                 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1985                                 G_TYPE_STRING, "DiscoverableTimeout",
1986                                 G_TYPE_VALUE, &val_timeout,
1987                                 G_TYPE_INVALID, G_TYPE_INVALID);
1988
1989         if (error != NULL) {
1990                 BT_ERR("Timeout set err:[%s]", error->message);
1991                 g_error_free(error);
1992                 ret = BLUETOOTH_ERROR_INTERNAL;
1993                 goto done;
1994         }
1995
1996         if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
1997                 timeout = -1;
1998
1999         ret = __bt_set_visible_time(timeout);
2000
2001 done:
2002         g_value_unset(&val_timeout);
2003         g_value_unset(&connectable);
2004         g_value_unset(&discoverable);
2005
2006         return ret;
2007 }
2008
2009 int _bt_start_discovery(void)
2010 {
2011         DBusGProxy *proxy;
2012         GError *err = NULL;
2013
2014         if (_bt_is_discovering() == TRUE) {
2015                 BT_ERR("BT is already in discovering");
2016                 return BLUETOOTH_ERROR_IN_PROGRESS;
2017         } else if (_bt_is_device_creating() == TRUE) {
2018                 BT_ERR("Bonding device is going on");
2019                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2020         }
2021
2022         proxy = _bt_get_adapter_proxy();
2023         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2024
2025         if (!dbus_g_proxy_call(proxy, "StartDiscovery", &err,
2026                                G_TYPE_INVALID, G_TYPE_INVALID)) {
2027                 if (err != NULL) {
2028                         BT_ERR("StartDiscovery failed: [%s]\n", err->message);
2029                         g_error_free(err);
2030                 }
2031                 BT_ERR("Discover start failed");
2032                 return BLUETOOTH_ERROR_INTERNAL;
2033         }
2034
2035         is_discovering = TRUE;
2036         cancel_by_user = FALSE;
2037         /* discovery status will be change in event */
2038                 BT_ERR("_bt_start_discovery 3");
2039
2040         return BLUETOOTH_ERROR_NONE;
2041 }
2042
2043 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
2044 {
2045         DBusGProxy *proxy;
2046
2047         const gchar *disc_type;
2048
2049         if (_bt_is_discovering() == TRUE) {
2050                 BT_ERR("BT is already in discovering");
2051                 return BLUETOOTH_ERROR_IN_PROGRESS;
2052         }
2053
2054         proxy = _bt_get_adapter_proxy();
2055         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2056
2057         if (role == DISCOVERY_ROLE_BREDR)
2058                 disc_type = "BREDR";
2059         else if (role == DISCOVERY_ROLE_LE)
2060                 disc_type = "LE";
2061         else if (role == DISCOVERY_ROLE_LE_BREDR)
2062                 disc_type = "LE_BREDR";
2063         else
2064                 return BLUETOOTH_ERROR_INVALID_PARAM;
2065
2066         if (!dbus_g_proxy_call(proxy, "StartCustomDiscovery", NULL,
2067                          G_TYPE_STRING, disc_type,
2068                                G_TYPE_INVALID, G_TYPE_INVALID)) {
2069                 BT_ERR("StartCustomDiscovery failed");
2070                 return BLUETOOTH_ERROR_INTERNAL;
2071         }
2072
2073         is_discovering = TRUE;
2074         cancel_by_user = FALSE;
2075         /* discovery status will be change in event */
2076
2077         return BLUETOOTH_ERROR_NONE;
2078 }
2079
2080 int _bt_cancel_discovery(void)
2081 {
2082         DBusGProxy *proxy;
2083         GError *err = NULL;
2084
2085         if (_bt_is_discovering() == FALSE) {
2086                 BT_ERR("BT is not in discovering");
2087                 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2088         }
2089
2090         proxy = _bt_get_adapter_proxy();
2091         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2092
2093         if (!dbus_g_proxy_call(proxy, "StopDiscovery", &err,
2094                                G_TYPE_INVALID, G_TYPE_INVALID)) {
2095                 if (err != NULL) {
2096                         BT_ERR("StopDiscovery failed: [%s]\n", err->message);
2097                         g_error_free(err);
2098                 }
2099                 return BLUETOOTH_ERROR_INTERNAL;
2100         }
2101
2102         cancel_by_user = TRUE;
2103         /* discovery status will be change in event */
2104
2105         return BLUETOOTH_ERROR_NONE;
2106 }
2107
2108 int _bt_start_le_discovery(void)
2109 {
2110    DBusGProxy *proxy;
2111
2112    if (_bt_is_le_discovering() == TRUE) {
2113        BT_ERR("BT is already in LE discovering");
2114        return BLUETOOTH_ERROR_IN_PROGRESS;
2115    }
2116
2117    proxy = _bt_get_adapter_proxy();
2118    retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2119
2120    if (!dbus_g_proxy_call(proxy, "StartLEDiscovery", NULL,
2121                   G_TYPE_INVALID, G_TYPE_INVALID)) {
2122        BT_ERR("LE Discover start failed");
2123        return BLUETOOTH_ERROR_INTERNAL;
2124    }
2125
2126    is_le_discovering = TRUE;
2127
2128    return BLUETOOTH_ERROR_NONE;
2129 }
2130
2131 int _bt_stop_le_discovery(void)
2132 {
2133    DBusGProxy *proxy;
2134
2135    if (_bt_is_le_discovering() == FALSE) {
2136        BT_ERR("BT is not in LE discovering");
2137        return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2138    }
2139
2140    proxy = _bt_get_adapter_proxy();
2141    retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2142
2143    if (!dbus_g_proxy_call(proxy, "StopLEDiscovery", NULL,
2144                   G_TYPE_INVALID, G_TYPE_INVALID)) {
2145        BT_ERR("LE Discover stop failed");
2146        return BLUETOOTH_ERROR_INTERNAL;
2147    }
2148
2149    return BLUETOOTH_ERROR_NONE;
2150 }
2151
2152 gboolean _bt_is_discovering(void)
2153 {
2154         return is_discovering;
2155 }
2156
2157 gboolean _bt_is_le_discovering(void)
2158 {
2159    return is_le_discovering;
2160 }
2161
2162 gboolean _bt_is_connectable(void)
2163 {
2164         DBusGProxy *proxy;
2165         GValue connectable_v = { 0 };
2166         GError *err = NULL;
2167         gboolean is_connectable = FALSE;
2168
2169         proxy = _bt_get_adapter_properties_proxy();
2170         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2171
2172         if (!dbus_g_proxy_call(proxy, "Get", &err,
2173                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
2174                         G_TYPE_STRING, "Connectable",
2175                         G_TYPE_INVALID,
2176                         G_TYPE_VALUE, &connectable_v,
2177                         G_TYPE_INVALID)) {
2178                 if (err != NULL) {
2179                         BT_ERR("Getting property failed: [%s]\n", err->message);
2180                         g_error_free(err);
2181                 }
2182                 return BLUETOOTH_ERROR_INTERNAL;
2183         }
2184
2185         is_connectable = g_value_get_boolean(&connectable_v);
2186         BT_INFO("Get connectable [%d]", is_connectable);
2187
2188         return is_connectable;
2189 }
2190
2191 int _bt_set_connectable(gboolean is_connectable)
2192 {
2193         DBusGProxy *proxy;
2194         GValue connectable = { 0 };
2195         GError *error = NULL;
2196
2197         if (__bt_is_factory_test_mode()) {
2198                 BT_ERR("Unable to set connectable in factory binary !!");
2199                 return BLUETOOTH_ERROR_NOT_SUPPORT;
2200         }
2201
2202         proxy = _bt_get_adapter_properties_proxy();
2203
2204         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2205
2206         g_value_init(&connectable, G_TYPE_BOOLEAN);
2207         g_value_set_boolean(&connectable, is_connectable);
2208
2209         dbus_g_proxy_call(proxy, "Set", &error,
2210                                 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
2211                                 G_TYPE_STRING, "Connectable",
2212                                 G_TYPE_VALUE, &connectable,
2213                                 G_TYPE_INVALID, G_TYPE_INVALID);
2214
2215         g_value_unset(&connectable);
2216         if (error != NULL) {
2217                 BT_ERR("Connectable set err:[%s]", error->message);
2218                 g_error_free(error);
2219                 return BLUETOOTH_ERROR_INTERNAL;
2220         }
2221
2222         BT_INFO("Set connectable [%d]", is_connectable);
2223         return BLUETOOTH_ERROR_NONE;
2224 }
2225
2226 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
2227 {
2228         DBusGProxy *proxy;
2229         GValue discovering_v = { 0 };
2230         GError *err = NULL;
2231         char *discovering_type =  NULL;
2232
2233         proxy = _bt_get_adapter_properties_proxy();
2234         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2235
2236         if (discovery_type == DISCOVERY_ROLE_BREDR)
2237                 discovering_type = "Discovering";
2238         else if (discovery_type == DISCOVERY_ROLE_LE)
2239                 discovering_type = "LEDiscovering";
2240
2241         if (!dbus_g_proxy_call(proxy, "Get", &err,
2242                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
2243                         G_TYPE_STRING, discovering_type,
2244                         G_TYPE_INVALID,
2245                         G_TYPE_VALUE, &discovering_v,
2246                         G_TYPE_INVALID)) {
2247                 if (err != NULL) {
2248                         BT_ERR("Getting property failed: [%s]\n", err->message);
2249                         g_error_free(err);
2250                 }
2251                 return BLUETOOTH_ERROR_INTERNAL;
2252         }
2253
2254         return g_value_get_boolean(&discovering_v);
2255 }
2256
2257 unsigned int _bt_get_discoverable_timeout_property(void)
2258 {
2259         DBusGProxy *proxy;
2260         GValue timeout_v = { 0 };
2261         GError *err = NULL;
2262
2263         proxy = _bt_get_adapter_properties_proxy();
2264         retv_if(proxy == NULL, 0);
2265
2266         if (!dbus_g_proxy_call(proxy, "Get", &err,
2267                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
2268                         G_TYPE_STRING, "DiscoverableTimeout",
2269                         G_TYPE_INVALID,
2270                         G_TYPE_VALUE, &timeout_v,
2271                         G_TYPE_INVALID)) {
2272                 if (err != NULL) {
2273                         BT_ERR("Getting property failed: [%s]\n", err->message);
2274                         g_error_free(err);
2275                 }
2276                 return 0;
2277         }
2278
2279         return g_value_get_uint(&timeout_v);
2280 }
2281
2282 static bluetooth_device_info_t *__bt_parse_device_info(DBusMessageIter *item_iter)
2283 {
2284         DBusMessageIter value_iter;
2285         bluetooth_device_info_t *dev_info;
2286
2287         dbus_message_iter_recurse(item_iter, &value_iter);
2288
2289         if (dbus_message_iter_get_arg_type(&value_iter) != DBUS_TYPE_DICT_ENTRY) {
2290                 BT_DBG("No entry");
2291                 return NULL;
2292         }
2293
2294         dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
2295
2296         while (dbus_message_iter_get_arg_type(&value_iter) ==
2297                                                 DBUS_TYPE_DICT_ENTRY) {
2298                 char *value = NULL;
2299                 char *key;
2300                 DBusMessageIter dict_entry;
2301                 DBusMessageIter iter_dict_val;
2302
2303                 dbus_message_iter_recurse(&value_iter, &dict_entry);
2304
2305                 dbus_message_iter_get_basic(&dict_entry, &key);
2306
2307                 if (key == NULL) {
2308                         dbus_message_iter_next(&value_iter);
2309                         continue;
2310                 }
2311
2312                 if (!dbus_message_iter_next(&dict_entry)) {
2313                         dbus_message_iter_next(&value_iter);
2314                         continue;
2315                 }
2316                 dbus_message_iter_recurse(&dict_entry, &iter_dict_val);
2317
2318                 if (strcasecmp(key, "Address") == 0) {
2319                         const char *address = NULL;
2320                         dbus_message_iter_get_basic(&iter_dict_val, &address);
2321                         _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2322                                                         address);
2323
2324                 } else if (strcasecmp(key, "Class") == 0) {
2325                         unsigned int cod;
2326                         dbus_message_iter_get_basic(&iter_dict_val, &cod);
2327                         _bt_divide_device_class(&dev_info->device_class, cod);
2328                 } else if (strcasecmp(key, "Name") == 0) {
2329                         dbus_message_iter_get_basic(&iter_dict_val, &value);
2330
2331                         /* If there is no Alias */
2332                         if (strlen(dev_info->device_name.name) == 0) {
2333                                 g_strlcpy(dev_info->device_name.name, value,
2334                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2335                         }
2336                 } else if (strcasecmp(key, "Alias") == 0) {
2337                         dbus_message_iter_get_basic(&iter_dict_val, &value);
2338
2339                         /* Overwrite the name */
2340                         if (value) {
2341                                 memset(dev_info->device_name.name, 0x00,
2342                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2343                                 g_strlcpy(dev_info->device_name.name, value,
2344                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2345                         }
2346                 } else if (strcasecmp(key, "Connected") == 0) {
2347                         dbus_message_iter_get_basic(&iter_dict_val,
2348                                                 &dev_info->connected);
2349                 } else if (strcasecmp(key, "Paired") == 0) {
2350                         dbus_message_iter_get_basic(&iter_dict_val,
2351                                                 &dev_info->paired);
2352                 } else if (strcasecmp(key, "Trusted") == 0) {
2353                         dbus_message_iter_get_basic(&iter_dict_val,
2354                                                 &dev_info->trust);
2355                 } else if (strcasecmp(key, "RSSI") == 0) {
2356                         dbus_message_iter_get_basic(&iter_dict_val,
2357                                                 &dev_info->rssi);
2358                 } else if (strcasecmp(key, "UUIDs") == 0) {
2359                         DBusMessageIter uuid_iter;
2360                         char **parts;
2361                         int i = 0;
2362
2363                         dbus_message_iter_recurse(&iter_dict_val, &uuid_iter);
2364
2365                         while (dbus_message_iter_get_arg_type(&uuid_iter) != DBUS_TYPE_INVALID) {
2366                                 dbus_message_iter_get_basic(&uuid_iter,
2367                                                         &value);
2368
2369                                 g_strlcpy(dev_info->uuids[i], value,
2370                                                 BLUETOOTH_UUID_STRING_MAX);
2371
2372                                 parts = g_strsplit(value, "-", -1);
2373
2374                                 if (parts == NULL || parts[0] == NULL)
2375                                         break;
2376
2377                                 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2378                                 g_strfreev(parts);
2379
2380                                 i++;
2381                                 if (!dbus_message_iter_next(&uuid_iter)) {
2382                                         break;
2383                                 }
2384                         }
2385
2386                         dev_info->service_index = i;
2387                 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
2388                         dbus_message_iter_get_basic(&iter_dict_val,
2389                                                                 &dev_info->manufacturer_data.data_len);
2390                 } else if (strcasecmp(key, "ManufacturerData") == 0) {
2391                         DBusMessageIter manufacturer_iter;
2392                         int i = 0;
2393                         char byte = 0;
2394
2395                         dbus_message_iter_recurse(&iter_dict_val, &manufacturer_iter);
2396
2397                         while (dbus_message_iter_get_arg_type(&manufacturer_iter) == DBUS_TYPE_BYTE) {
2398                                 dbus_message_iter_get_basic(&manufacturer_iter, &byte);
2399                                 dev_info->manufacturer_data.data[i] = byte;
2400                                 i++;
2401                                 dbus_message_iter_next(&manufacturer_iter);
2402                         }
2403                 }
2404
2405                 dbus_message_iter_next(&value_iter);
2406         }
2407
2408         return dev_info;
2409 }
2410
2411 static void __bt_extract_device_info(DBusMessageIter *msg_iter,
2412                                                         GArray **dev_list)
2413 {
2414         bluetooth_device_info_t *dev_info = NULL;
2415         char *object_path = NULL;
2416         DBusMessageIter value_iter;
2417
2418         /* Parse the signature:  oa{sa{sv}}} */
2419         ret_if(dbus_message_iter_get_arg_type(msg_iter) !=
2420                                 DBUS_TYPE_OBJECT_PATH);
2421
2422         dbus_message_iter_get_basic(msg_iter, &object_path);
2423         ret_if(object_path == NULL);
2424
2425         /* object array (oa) */
2426         ret_if(dbus_message_iter_next(msg_iter) == FALSE);
2427         ret_if(dbus_message_iter_get_arg_type(msg_iter) != DBUS_TYPE_ARRAY);
2428
2429         dbus_message_iter_recurse(msg_iter, &value_iter);
2430
2431         /* string array (sa) */
2432         while (dbus_message_iter_get_arg_type(&value_iter) ==
2433                                         DBUS_TYPE_DICT_ENTRY) {
2434                 char *interface_name = NULL;
2435                 DBusMessageIter interface_iter;
2436
2437                 dbus_message_iter_recurse(&value_iter, &interface_iter);
2438
2439                 ret_if(dbus_message_iter_get_arg_type(&interface_iter) !=
2440                                                         DBUS_TYPE_STRING);
2441
2442                 dbus_message_iter_get_basic(&interface_iter, &interface_name);
2443
2444                 ret_if(dbus_message_iter_next(&interface_iter) == FALSE);
2445
2446                 ret_if(dbus_message_iter_get_arg_type(&interface_iter) !=
2447                                                         DBUS_TYPE_ARRAY);
2448
2449                 if (g_strcmp0(interface_name, "org.bluez.Device1") == 0) {
2450                         BT_DBG("Found a device: %s", object_path);
2451                         dev_info = __bt_parse_device_info(&interface_iter);
2452
2453                         if (dev_info) {
2454                                 if (dev_info->paired == FALSE)
2455                                         goto not_paired;
2456
2457                                 g_array_append_vals(*dev_list, dev_info,
2458                                                 sizeof(bluetooth_device_info_t));
2459
2460                                 g_free(dev_info);
2461                         }
2462
2463                         return;
2464                 }
2465
2466                 dbus_message_iter_next(&value_iter);
2467         }
2468
2469         BT_DBG("There is no device interface");
2470
2471 not_paired:
2472         BT_DBG("Not paired");
2473         g_free(dev_info);
2474 }
2475
2476 int _bt_get_bonded_devices(GArray **dev_list)
2477 {
2478         BT_DBG("+");
2479         DBusMessage *msg;
2480         DBusMessage *reply;
2481         DBusMessageIter reply_iter;
2482         DBusMessageIter value_iter;
2483         DBusError err;
2484         DBusConnection *conn;
2485
2486         conn = _bt_get_system_conn();
2487         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2488
2489         msg = dbus_message_new_method_call(BT_BLUEZ_NAME, BT_MANAGER_PATH,
2490                                                 BT_MANAGER_INTERFACE,
2491                                                 "GetManagedObjects");
2492
2493         retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
2494
2495         /* Synchronous call */
2496         dbus_error_init(&err);
2497         reply = dbus_connection_send_with_reply_and_block(
2498                                         conn, msg,
2499                                         -1, &err);
2500         dbus_message_unref(msg);
2501
2502         if (!reply) {
2503                 BT_ERR("Can't get managed objects");
2504
2505                 if (dbus_error_is_set(&err)) {
2506                         BT_ERR("%s", err.message);
2507                         dbus_error_free(&err);
2508                 }
2509                 return BLUETOOTH_ERROR_INTERNAL;
2510         }
2511
2512         if (dbus_message_iter_init(reply, &reply_iter) == FALSE) {
2513                 BT_ERR("Fail to iterate the reply");
2514                 dbus_message_unref(reply);
2515                 return BLUETOOTH_ERROR_INTERNAL;
2516         }
2517
2518         dbus_message_iter_recurse(&reply_iter, &value_iter);
2519
2520         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
2521         while (dbus_message_iter_get_arg_type(&value_iter) ==
2522                                                 DBUS_TYPE_DICT_ENTRY) {
2523                 DBusMessageIter msg_iter;
2524
2525                 dbus_message_iter_recurse(&value_iter, &msg_iter);
2526
2527                 __bt_extract_device_info(&msg_iter, dev_list);
2528
2529                 dbus_message_iter_next(&value_iter);
2530         }
2531         dbus_message_unref(reply);
2532         BT_DBG("-");
2533         return BLUETOOTH_ERROR_NONE;
2534 }
2535
2536 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2537                                 bluetooth_device_info_t *dev_info)
2538 {
2539         char *object_path = NULL;
2540         DBusGProxy *adapter_proxy;
2541         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2542         int ret = BLUETOOTH_ERROR_NONE;
2543
2544         BT_CHECK_PARAMETER(device_address, return);
2545         BT_CHECK_PARAMETER(dev_info, return);
2546
2547         adapter_proxy = _bt_get_adapter_proxy();
2548         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2549
2550         _bt_convert_addr_type_to_string(address, device_address->addr);
2551
2552         object_path = _bt_get_device_object_path(address);
2553
2554         retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2555
2556         ret = __bt_get_bonded_device_info(object_path, dev_info);
2557         g_free(object_path);
2558
2559         return ret;
2560 }
2561
2562 int _bt_get_timeout_value(int *timeout)
2563 {
2564         time_t current_time;
2565         int time_diff;
2566
2567         /* Take current time */
2568         time(&current_time);
2569         time_diff = difftime(current_time, visible_timer.start_time);
2570
2571         BT_DBG("Time diff = %d\n", time_diff);
2572
2573         *timeout = visible_timer.timeout - time_diff;
2574
2575         return BLUETOOTH_ERROR_NONE;
2576 }
2577
2578 int _bt_set_le_privacy(gboolean set_privacy)
2579 {
2580         DBusGProxy *proxy;
2581         GError *error = NULL;
2582         int ret = BLUETOOTH_ERROR_NONE;
2583
2584         if (__bt_is_factory_test_mode()) {
2585                 BT_ERR("Unable to set le privacy in factory binary !!");
2586                 return BLUETOOTH_ERROR_NOT_SUPPORT;
2587         }
2588
2589         if (_bt_adapter_get_status() != BT_ACTIVATED &&
2590                 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2591                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2592         }
2593
2594         proxy = _bt_get_adapter_proxy();
2595         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2596
2597         dbus_g_proxy_call(proxy, "SetLePrivacy", &error,
2598                                    G_TYPE_BOOLEAN, set_privacy,
2599                                    G_TYPE_INVALID, G_TYPE_INVALID);
2600
2601         if (error) {
2602                 BT_ERR("SetLePrivacy Failed :[%s]", error->message);
2603                 if (g_strrstr(error->message, BT_SERVICE_ERR_MSG_NOT_SUPPORTED))
2604                         ret = BLUETOOTH_ERROR_NOT_SUPPORT;
2605                 else
2606                         ret = BLUETOOTH_ERROR_INTERNAL;
2607                 g_error_free(error);
2608                 return ret;
2609         }
2610
2611         BT_INFO("SetLePrivacy as %d", set_privacy);
2612
2613         return BLUETOOTH_ERROR_NONE;
2614 }
2615
2616 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2617 {
2618         DBusGProxy *proxy;
2619         GError *error = NULL;
2620         GArray *arr;
2621         int i;
2622
2623         BT_CHECK_PARAMETER(m_data, return);
2624
2625         if (_bt_adapter_get_status() != BT_ACTIVATED &&
2626                 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2627                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2628         }
2629
2630         proxy = _bt_get_adapter_proxy();
2631         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2632
2633         arr = g_array_new(TRUE, TRUE, sizeof(guint8));
2634
2635         for (i = 0; i < (m_data->data_len) + 2; i++)
2636                 g_array_append_vals(arr, &(m_data->data[i]), sizeof(guint8));
2637
2638         dbus_g_proxy_call(proxy, "SetManufacturerData", &error,
2639                         DBUS_TYPE_G_UCHAR_ARRAY, arr,
2640                         G_TYPE_INVALID, G_TYPE_INVALID);
2641
2642         g_array_free(arr, TRUE);
2643
2644         if (error) {
2645                 BT_ERR("SetManufacturerData Fail: %s", error->message);
2646                 g_error_free(error);
2647                 return BLUETOOTH_ERROR_INTERNAL;
2648         }
2649
2650         _bt_send_event(BT_ADAPTER_EVENT,
2651                         BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2652                         DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
2653                         &m_data, m_data->data_len,
2654                         DBUS_TYPE_INVALID);
2655
2656         BT_INFO("Set manufacturer data");
2657
2658         return BLUETOOTH_ERROR_NONE;
2659 }