Handle FM radio status with BT on / off senario
[platform/core/connectivity/bluetooth-frwk.git] / bt-core / bt-core-adapter.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <vconf.h>
19 #include <vconf-keys.h>
20 #include <vconf-internal-radio-keys.h>
21 #include <bundle.h>
22 #include <eventsystem.h>
23
24 #include "bt-core-main.h"
25 #include "bt-core-adapter.h"
26 #include "bt-core-common.h"
27 #include "bt-core-dbus-handler.h"
28 #include "bt-core-noti-handler.h"
29
30 #define BT_CORE_IDLE_TERM_TIME 200 /* 200ms */
31 #define BT_CORE_CHECK_ADAPTER_OBJECT_PATH_MAX 50
32
33
34 static bt_status_t adapter_status = BT_DEACTIVATED;
35 static bt_le_status_t adapter_le_status = BT_LE_DEACTIVATED;
36 static gboolean is_recovery_mode = FALSE;
37
38 static int bt_status_before[BT_MODE_MAX] = { VCONFKEY_BT_STATUS_OFF, };
39 static int bt_le_status_before[BT_MODE_MAX] = { VCONFKEY_BT_LE_STATUS_OFF, };
40
41 static void __bt_core_set_status(bt_status_t status)
42 {
43         adapter_status = status;
44 }
45
46 bt_status_t _bt_core_get_status(void)
47 {
48         return adapter_status;
49 }
50
51 static void __bt_core_set_le_status(bt_le_status_t status)
52 {
53         adapter_le_status = status;
54 }
55
56 bt_le_status_t _bt_core_get_le_status(void)
57 {
58         return adapter_le_status;
59 }
60
61 int _bt_core_get_bt_status(bt_mode_e mode)
62 {
63         return bt_status_before[mode];
64 }
65
66 int _bt_core_get_bt_le_status(bt_mode_e mode)
67 {
68         return bt_le_status_before[mode];
69 }
70
71 void _bt_core_set_bt_status(bt_mode_e mode, int status)
72 {
73         bt_status_before[mode] = status;
74 }
75
76 void _bt_core_set_bt_le_status(bt_mode_e mode, int status)
77 {
78         bt_le_status_before[mode] = status;
79 }
80
81 gboolean _bt_core_is_recovery_mode(void)
82 {
83         return is_recovery_mode;
84 }
85
86 static gboolean __bt_core_idle_terminate(gpointer data)
87 {
88         BT_DBG("+");
89         _bt_core_terminate();
90         return FALSE;
91 }
92
93 gboolean _bt_core_is_flight_mode_enabled(void)
94 {
95 #ifdef TIZEN_FEATURE_FLIGHTMODE_ENABLED
96         int isFlightMode = 0;
97         int ret = -1;
98
99         ret = vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &isFlightMode);
100         if (ret != 0) {
101                 BT_ERR("vconf_get_bool failed");
102         }
103         return isFlightMode;
104 #else
105         return FALSE;
106 #endif
107 }
108
109 static int __execute_command(const char *cmd, char *const arg_list[])
110 {
111         int pid;
112         int pid2;
113         int status = 0;
114         BT_DBG("+");
115
116         pid = fork();
117         switch (pid) {
118         case -1:
119                 BT_ERR("fork failed");
120                 return -1;
121
122         case 0:
123                 pid2 = fork();
124                 if (pid2 == -1) {
125                         BT_ERR("fork failed");
126                 } else if (pid2 == 0) {
127                         execv(cmd, arg_list);
128                         exit(256);
129                 }
130                 exit(0);
131                 break;
132
133         default:
134                 BT_DBG("parent : forked[%d]", pid);
135                 waitpid(pid, &status, 0);
136                 BT_DBG("child is terminated : %d", status);
137                 break;
138         }
139         BT_DBG("-");
140         return 0;
141 }
142
143 int _bt_enable_adapter(void)
144 {
145         int ret;
146         bt_status_t status;
147 #if 0
148         bt_le_status_t le_status;
149 #endif
150         BT_INFO("");
151
152         status = _bt_core_get_status();
153         if (status != BT_DEACTIVATED) {
154                 BT_ERR("Invalid state %d", status);
155                 g_timeout_add(BT_CORE_IDLE_TERM_TIME, __bt_core_idle_terminate, NULL);
156                 return -1;
157         }
158
159 #if 0 /* only the concept of private */
160         le_status = _bt_core_get_le_status();
161         if (le_status == BT_LE_ACTIVATED) {
162                 /* Turn on PSCAN, (ISCAN if needed) */
163                 /* Return with 0 for the Enabled response. */
164                 __bt_core_set_status(BT_ACTIVATED);
165                 BT_INFO("BR/EDR is enabled.");
166                 g_timeout_add(BT_CORE_IDLE_TERM_TIME, __bt_core_idle_terminate, NULL);
167                 return 0;
168         }
169 #endif
170
171         __bt_core_set_status(BT_ACTIVATING);
172 #ifdef USB_BLUETOOTH
173         char *argv_up[] = {"/usr/bin/hciconfig", "/usr/bin/hciconfig", "hci0", "up", NULL};
174         ret = __execute_command("/usr/bin/hciconfig", argv_up);
175 #else
176         ret = __execute_command("/usr/etc/bluetooth/bt-stack-up.sh", NULL);
177 #endif
178         if (ret < 0) {
179                 BT_ERR("running script failed");
180 #ifdef USB_BLUETOOTH
181                 char *argv_down[] = {"/usr/bin/hciconfig", "/usr/bin/hciconfig", "hci0", "down", NULL};
182                 ret = __execute_command("/usr/bin/hciconfig", argv_down);
183 #else
184                 ret = __execute_command("/usr/etc/bluetooth/bt-dev-end.sh", NULL);
185 #endif
186                 __bt_core_set_status(BT_DEACTIVATED);
187                 return -1;
188         }
189
190         return 0;
191 }
192
193 int _bt_disable_adapter(void)
194 {
195         bt_status_t status;
196 #if 0
197         bt_le_status_t le_status;
198 #endif
199
200         BT_INFO_C("Disable adapter");
201
202 #if 0 /* only the concept of private */
203         le_status = _bt_core_get_le_status();
204         BT_DBG("le_status : %d", le_status);
205         if (le_status == BT_LE_ACTIVATED) {
206                 /* Turn off PSCAN, (ISCAN if needed) */
207                 /* Return with 0 for the Disabled response. */
208                 __bt_core_set_status(BT_DEACTIVATED);
209                 BT_INFO("BR/EDR is disabled. now LE only mode");
210                 g_timeout_add(BT_CORE_IDLE_TERM_TIME, __bt_core_idle_terminate, NULL);
211                 return 0;
212         }
213 #endif
214
215         status = _bt_core_get_status();
216         if (status == BT_ACTIVATING) {
217                 /* Forcely terminate */
218 #ifdef USB_BLUETOOTH
219                 char *argv_down[] = {"/usr/bin/hciconfig", "/usr/bin/hciconfig", "hci0", "down", NULL};
220                 if (__execute_command("/usr/bin/hciconfig", argv_down) < 0)
221                         BT_ERR("running script failed");
222 #else
223
224 #ifdef TIZEN_FEATURE_RADIO
225                 int radio_status = VCONFKEY_RADIO_STATUS_OFF;
226
227                 /* Check if radio status on or off */
228                 if (vconf_get_int(VCONFKEY_RADIO_STATUS, &radio_status) < 0)
229                         BT_ERR("Fail to get radio status");
230
231                 BT_DBG("Radio status: %d", radio_status);
232
233                 if (radio_status == VCONFKEY_RADIO_STATUS_ON) {
234                         if (__execute_command("/usr/etc/bluetooth/bt-stack-down-with-radio.sh", NULL) < 0)
235                                 BT_ERR("running script failed");
236                 } else {
237                         if (__execute_command("/usr/etc/bluetooth/bt-stack-down.sh", NULL) < 0)
238                                 BT_ERR("running script failed");
239                 }
240 #else
241                 if (__execute_command("/usr/etc/bluetooth/bt-stack-down.sh", NULL) < 0)
242                         BT_ERR("running script failed");
243 #endif
244 #endif
245                 _bt_core_terminate();
246                 return 0;
247         } else if (status != BT_ACTIVATED) {
248                 BT_ERR("Invalid state %d", status);
249                 g_timeout_add(BT_CORE_IDLE_TERM_TIME, __bt_core_idle_terminate, NULL);
250         }
251
252         __bt_core_set_status(BT_DEACTIVATING);
253 #ifdef USB_BLUETOOTH
254         char *argv_down[] = {"/usr/bin/hciconfig", "/usr/bin/hciconfig", "hci0", "down", NULL};
255         if (__execute_command("/usr/bin/hciconfig", argv_down) < 0) {
256                 BT_ERR("running script failed");
257                 __bt_core_set_status(BT_ACTIVATED);
258                 return -1;
259         }
260 #else
261 #ifdef TIZEN_FEATURE_RADIO
262         int radio_status = VCONFKEY_RADIO_STATUS_OFF;
263
264         /* Check if radio status on or off */
265         if (vconf_get_int(VCONFKEY_RADIO_STATUS, &radio_status) < 0)
266                 BT_ERR("Fail to get radio status");
267
268         BT_DBG("Radio status: %d", radio_status);
269
270         if (radio_status == VCONFKEY_RADIO_STATUS_ON) {
271                 if (__execute_command("/usr/etc/bluetooth/bt-stack-down-with-radio.sh", NULL) < 0) {
272                         BT_ERR("running script failed");
273                         __bt_core_set_status(BT_ACTIVATED);
274                         return -1;
275                 }
276         } else {
277                 if (__execute_command("/usr/etc/bluetooth/bt-stack-down.sh", NULL) < 0) {
278                         BT_ERR("running script failed");
279                         __bt_core_set_status(BT_ACTIVATED);
280                         return -1;
281                 }
282         }
283 #else
284         if (__execute_command("/usr/etc/bluetooth/bt-stack-down.sh", NULL) < 0) {
285                         BT_ERR("running script failed");
286                         __bt_core_set_status(BT_ACTIVATED);
287                         return -1;
288         }
289 #endif
290 #endif
291
292         return 0;
293 }
294
295 int _bt_enable_adapter_le(void)
296 {
297         BT_DBG("");
298
299         int ret;
300         bt_status_t status;
301         bt_le_status_t le_status;
302         le_status = _bt_core_get_le_status();
303         retv_if(le_status != BT_LE_DEACTIVATED, -1);
304
305         status = _bt_core_get_status();
306         if (status == BT_DEACTIVATED) {
307                 __bt_core_set_le_status(BT_LE_ACTIVATING);
308                 BT_DBG("Activate BT");
309 #ifdef USB_BLUETOOTH
310                 char *argv_up[] = {"/usr/bin/hciconfig", "/usr/bin/hciconfig", "hci0", "up", NULL};
311                 ret = __execute_command("/usr/bin/hciconfig", argv_up);
312 #else
313                 ret = __execute_command("/usr/etc/bluetooth/bt-stack-up.sh", NULL);
314 #endif
315                 if (ret < 0) {
316                         BT_ERR("running script failed");
317 #ifdef USB_BLUETOOTH
318                         char *argv_down[] = {"/usr/bin/hciconfig", "/usr/bin/hciconfig", "hci0", "down", NULL};
319                         ret = __execute_command("/usr/bin/hciconfig", argv_down);
320 #else
321                         ret = __execute_command("/usr/etc/bluetooth/bt-dev-end.sh &", NULL);
322 #endif
323                         __bt_core_set_status(BT_DEACTIVATED);
324                         __bt_core_set_le_status(BT_LE_DEACTIVATED);
325                         return -1;
326                 }
327         } else {
328                 __bt_core_set_le_status(BT_LE_ACTIVATED);
329                 g_timeout_add(BT_CORE_IDLE_TERM_TIME, __bt_core_idle_terminate, NULL);
330         }
331 #ifdef HPS_FEATURE
332         ret = _bt_core_start_httpproxy();
333         if (ret < 0) {
334                 BT_ERR("_bt_core_start_httpproxy() failed");
335         }
336 #endif
337
338         return 0;
339 }
340
341 int _bt_disable_adapter_le(void)
342 {
343         BT_DBG("+");
344
345         bt_status_t status;
346         bt_le_status_t le_status;
347
348         le_status = _bt_core_get_le_status();
349         retv_if(le_status == BT_LE_DEACTIVATED, 0);
350         retv_if(le_status == BT_LE_DEACTIVATING, -1);
351
352 #ifdef HPS_FEATURE
353         _bt_core_stop_httpproxy();
354 #endif
355
356         status = _bt_core_get_status();
357         BT_DBG("status : %d", status);
358
359         if (status == BT_DEACTIVATED) {
360                 __bt_core_set_le_status(BT_LE_DEACTIVATING);
361 #ifdef USB_BLUETOOTH
362                 char *argv_down[] = {"/usr/bin/hciconfig", "/usr/bin/hciconfig", "hci0", "down", NULL};
363                 if (__execute_command("/usr/bin/hciconfig", argv_down) < 0) {
364 #else
365                 if (__execute_command("/usr/etc/bluetooth/bt-stack-down.sh", NULL) < 0) {
366 #endif
367                         BT_ERR("running script failed");
368                         __bt_core_set_le_status(BT_LE_ACTIVATED);
369                         return -1;
370                 }
371         } else {
372                         g_timeout_add(BT_CORE_IDLE_TERM_TIME, __bt_core_idle_terminate, NULL);
373         }
374
375         __bt_core_set_le_status(BT_LE_DEACTIVATED);
376
377         BT_DBG("-");
378         return 0;
379 }
380
381 int _bt_core_service_request_adapter(int service_function)
382 {
383         int ret = -1;
384
385         GArray *in_param1 = NULL;
386         GArray *in_param2 = NULL;
387         GArray *in_param3 = NULL;
388         GArray *in_param4 = NULL;
389         GArray *out_param = NULL;
390
391         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
392
393         ret = _bt_core_service_request(BT_CORE_SERVICE, service_function,
394                         in_param1, in_param2, in_param3, in_param4, &out_param);
395         if (ret < 0)
396                 BT_ERR("_bt_core_service_request_adapter() failed");
397
398         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
399
400         return ret;
401 }
402
403 static gboolean __bt_core_check_the_adapter_path(GDBusConnection *conn)
404 {
405         GError *err = NULL;
406         GDBusProxy *manager_proxy = NULL;
407         GVariant *result = NULL;
408         char *adapter_path = NULL;
409
410         if (conn == NULL)
411                 return FALSE;
412
413         manager_proxy =  g_dbus_proxy_new_sync(conn,
414                         G_DBUS_PROXY_FLAGS_NONE, NULL,
415                         "org.bluez",
416                         "/",
417                         "org.freedesktop.DBus.ObjectManager",
418                         NULL, &err);
419
420         if (!manager_proxy) {
421                 if (err != NULL) {
422                         BT_ERR("Unable to create proxy: %s", err->message);
423                         g_clear_error(&err);
424                 } else {
425                         BT_ERR("Fail to create proxy");
426                 }
427                 goto fail;
428         }
429
430         result = g_dbus_proxy_call_sync(manager_proxy, "DefaultAdapter", NULL,
431                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
432         if (!result) {
433                 if (err != NULL) {
434                         BT_ERR("Fail to get DefaultAdapter (Error: %s)", err->message);
435                         g_clear_error(&err);
436                 } else{
437                         BT_ERR("Fail to get DefaultAdapter");
438                 }
439                 goto fail;
440         }
441
442         if (g_strcmp0(g_variant_get_type_string(result), "(o)")) {
443                 BT_ERR("Incorrect result\n");
444                 goto fail;
445         }
446
447         g_variant_get(result, "(&o)", &adapter_path);
448
449         if (adapter_path == NULL ||
450                 strlen(adapter_path) >= BT_CORE_CHECK_ADAPTER_OBJECT_PATH_MAX) {
451                 BT_ERR("Adapter path is inproper\n");
452                 goto fail;
453         }
454
455         g_variant_unref(result);
456         g_object_unref(manager_proxy);
457
458         return TRUE;
459
460 fail:
461         if (result)
462                 g_variant_unref(result);
463
464         if (manager_proxy)
465                 g_object_unref(manager_proxy);
466
467         return FALSE;
468 }
469
470 void _bt_core_update_status(void)
471 {
472         int bt_status = VCONFKEY_BT_STATUS_OFF;
473         int bt_le_status = VCONFKEY_BT_LE_STATUS_OFF;
474         gboolean ret = FALSE;
475
476         ret = __bt_core_check_the_adapter_path(_bt_core_get_gdbus_connection());
477         BT_INFO("check the real status of bt_adapter");
478
479         if (ret != TRUE) {
480                 __bt_core_set_status(BT_DEACTIVATED);
481                 __bt_core_set_le_status(BT_DEACTIVATED);
482         } else {
483                 if (vconf_get_int(VCONFKEY_BT_STATUS, &bt_status) < 0)
484                         BT_ERR("no bluetooth device info, so BT was disabled at previous session");
485                 if (vconf_get_int(VCONFKEY_BT_LE_STATUS, &bt_le_status) < 0)
486                         BT_ERR("no bluetooth le info, so BT LE was disabled at previous session");
487
488                 BT_INFO("bt_status = %d, bt_le_status = %d", bt_status, bt_le_status);
489
490                 if (bt_status & VCONFKEY_BT_STATUS_ON)
491                         __bt_core_set_status(BT_ACTIVATED);
492                 if (bt_le_status & VCONFKEY_BT_LE_STATUS_ON)
493                         __bt_core_set_le_status(BT_ACTIVATED);
494         }
495 }
496
497 gboolean _bt_core_enable_adapter(void)
498 {
499         int ret;
500
501         _bt_set_flightmode_request(FALSE);
502         if (vconf_set_int(BT_OFF_DUE_TO_FLIGHT_MODE, 0) != 0)
503                 BT_ERR("Set vconf failed");
504
505         ret = _bt_enable_adapter();
506         if (ret < 0)
507                 return FALSE;
508         else
509                 return TRUE;
510 }
511
512 gboolean _bt_core_disable_adapter(void)
513 {
514         int ret;
515
516         _bt_set_flightmode_request(FALSE);
517         if (vconf_set_int(BT_OFF_DUE_TO_FLIGHT_MODE, 0) != 0)
518                 BT_ERR("Set vconf failed");
519
520         ret = _bt_disable_adapter();
521         if (ret < 0)
522                 return FALSE;
523         else
524                 return TRUE;
525 }
526
527 gboolean _bt_core_recover_adapter(void)
528 {
529         int ret;
530         int ret_le;
531
532         BT_INFO_C("Recover bt adapter");
533
534         _bt_set_flightmode_request(FALSE);
535         if (vconf_set_int(BT_OFF_DUE_TO_FLIGHT_MODE, 0) != 0)
536                 BT_ERR("Set vconf failed");
537
538         is_recovery_mode = TRUE;
539
540         _bt_core_update_status();
541
542         if (_bt_core_get_status() == BT_ACTIVATED) {
543                 _bt_core_set_bt_status(BT_RECOVERY_MODE, 1);
544                 _bt_core_service_request_adapter(BT_DISABLE_ADAPTER);
545         }
546         if (_bt_core_get_le_status() == BT_LE_ACTIVATED) {
547                 _bt_core_set_bt_le_status(BT_RECOVERY_MODE, 1);
548                 _bt_core_service_request_adapter(BT_DISABLE_ADAPTER_LE);
549         }
550
551         ret = _bt_disable_adapter();
552         if (ret < 0)
553                 BT_ERR("_bt_disable_adapter() failed");
554         ret_le = _bt_disable_adapter_le();
555         if (ret_le < 0)
556                 BT_ERR("_bt_disable_adapter_le() failed");
557
558         return TRUE;
559 }
560
561 gboolean _bt_core_enable_adapter_le(void)
562 {
563         int ret;
564
565         ret = _bt_enable_adapter_le();
566         if (ret < 0)
567                 return FALSE;
568         else
569                 return TRUE;
570 }
571
572 gboolean _bt_core_disable_adapter_le(void)
573 {
574         BT_DBG("+");
575
576         int ret;
577
578         ret = _bt_disable_adapter_le();
579         if (ret < 0)
580                 return FALSE;
581         else
582                 return TRUE;
583 }
584
585 gboolean __bt_core_reset_adapter(void)
586 {
587         /* Forcely terminate */
588         if (__execute_command("/usr/etc/bluetooth/bt-reset-env.sh", NULL) < 0) {
589                 BT_ERR("running script failed");
590         }
591         _bt_core_terminate();
592
593         return TRUE;
594 }
595
596 static gboolean __bt_core_enable_core_timeout_cb(gpointer data)
597 {
598         BT_DBG("+");
599
600         _bt_core_init_vconf_value();
601
602         return FALSE;
603 }
604
605 gboolean _bt_core_enable_core(void)
606 {
607         BT_DBG("+");
608
609         _bt_core_update_status();
610
611         g_timeout_add(200, (GSourceFunc)__bt_core_enable_core_timeout_cb, NULL);
612
613         BT_DBG("-");
614         return TRUE;
615 }
616
617 gboolean _bt_core_factory_test_mode(const char *type, const char *arg)
618 {
619
620         char *cmd = NULL;
621         char *arg_list[3] = { NULL, NULL, NULL };
622
623         BT_DBG("Test item : %s", type);
624
625         if (g_strcmp0(type, "Enable_RF_Test") == 0) {
626                 cmd = "/usr/etc/bluetooth/bt-edutm-on.sh";
627                 arg_list[0] = "bt-edutm-on.sh";
628         } else if (g_strcmp0(type, "Disable_RF_Test") == 0) {
629                 cmd = "/usr/etc/bluetooth/bt-edutm-off.sh";
630                 arg_list[0] = "bt-edutm-off.sh";
631         } else if (g_strcmp0(type, "Slave_Mode") == 0) {
632                 cmd = "/usr/etc/bluetooth/bt-mode-slave.sh";
633                 arg_list[0] = "bt-mode-slave.sh";
634         } else if (g_strcmp0(type, "Master_Mode") == 0) {
635                 cmd = "/usr/etc/bluetooth/bt-mode-master.sh";
636                 arg_list[0] = "bt-mode-master.sh";
637         } else if (g_strcmp0(type, "SSP_Debug_Mode") == 0) {
638                 cmd = "/usr/etc/bluetooth/bt-set-ssp-debug-mode.sh";
639                 arg_list[0] = "bt-set-ssp-debug-mode.sh";
640                 arg_list[1] = (char *)arg;
641         } else if (g_strcmp0(type, "RF_Channel") == 0) {
642                 cmd = "/usr/etc/bluetooth/bt-enable-rf-channel.sh";
643                 arg_list[0] = "bt-enable-rf-channel.sh";
644                 arg_list[1] = (char *)arg;
645         } else {
646                 _bt_core_terminate();
647                 return FALSE;
648         }
649
650         BT_DBG("Run %s", cmd);
651         if (__execute_command(cmd, arg_list) < 0) {
652                 BT_ERR("running script failed");
653         }
654
655         _bt_core_terminate();
656         return TRUE;
657 }
658
659 static gboolean __bt_core_recovery_cb(gpointer data)
660 {
661         int ret = 0;
662         gboolean is_request_failed = FALSE;
663         static gboolean is_first_failure = TRUE;
664
665         BT_DBG("+");
666
667         if (_bt_core_get_bt_status(BT_RECOVERY_MODE) == 1) {
668                 ret = _bt_core_service_request_adapter(BT_ENABLE_ADAPTER);
669                 if (ret < 0)
670                         is_request_failed = TRUE;
671         }
672
673         if (_bt_core_get_bt_le_status(BT_RECOVERY_MODE) == 1) {
674                 ret = _bt_core_service_request_adapter(BT_ENABLE_ADAPTER_LE);
675                 if (ret < 0)
676                         is_request_failed = TRUE;
677         }
678
679         if (is_request_failed == TRUE) {
680                 BT_ERR("Recovery is failed.");
681                 if (is_first_failure == TRUE) {
682                         g_timeout_add(2000, (GSourceFunc)__bt_core_recovery_cb, NULL);
683                         is_first_failure = FALSE;
684                         return FALSE;
685                 } else {
686                         is_first_failure = TRUE;
687                         return FALSE;
688                 }
689         } else
690                 is_first_failure = TRUE;
691
692         if (_bt_core_get_bt_status(BT_RECOVERY_MODE) == 1) {
693                 _bt_core_set_bt_status(BT_RECOVERY_MODE, 0);
694                 ret = _bt_enable_adapter();
695                 if (ret < 0)
696                         BT_ERR("_bt_enable_adapter() failed");
697         }
698         if (_bt_core_get_bt_le_status(BT_RECOVERY_MODE) == 1) {
699                 _bt_core_set_bt_le_status(BT_RECOVERY_MODE, 0);
700                 ret = _bt_enable_adapter_le();
701                 if (ret < 0)
702                         BT_ERR("_bt_enable_adapter_le() failed");
703         }
704
705         is_recovery_mode = FALSE;
706
707         BT_DBG("-");
708
709         return FALSE;
710 }
711
712 static gboolean __bt_core_enable_timeout_cb(gpointer data)
713 {
714         bt_status_t adapter_status;
715         bt_le_status_t adapter_status_le;
716
717         BT_DBG("");
718
719         if (vconf_set_int(BT_OFF_DUE_TO_FLIGHT_MODE, 0) != 0)
720                 BT_ERR("Set vconf failed");
721
722         adapter_status = _bt_core_get_status();
723         adapter_status_le = _bt_core_get_le_status();
724
725         if (adapter_status == BT_DEACTIVATED &&
726                         _bt_core_get_bt_status(BT_FLIGHT_MODE) != 0) {
727                 _bt_core_set_bt_status(BT_FLIGHT_MODE, 0);
728                 _bt_core_service_request_adapter(BT_ENABLE_ADAPTER);
729                 _bt_enable_adapter();
730         }
731
732         if (adapter_status_le == BT_LE_DEACTIVATED &&
733                         _bt_core_get_bt_le_status(BT_FLIGHT_MODE) != 0) {
734                 _bt_core_set_bt_le_status(BT_FLIGHT_MODE, 0);
735                 _bt_core_service_request_adapter(BT_ENABLE_ADAPTER_LE);
736                 _bt_enable_adapter_le();
737         }
738
739         return FALSE;
740 }
741
742 static gboolean __bt_core_disable_timeout_cb(gpointer data)
743 {
744         bt_status_t adapter_status;
745         bt_le_status_t adapter_status_le;
746
747         BT_DBG("");
748
749         if (vconf_set_int(BT_OFF_DUE_TO_FLIGHT_MODE, 1) != 0)
750                 BT_ERR("Set vconf failed");
751
752         adapter_status = _bt_core_get_status();
753         adapter_status_le = _bt_core_get_le_status();
754
755         if (adapter_status == BT_ACTIVATED) {
756                 int bt_status_before_mode = 0;
757
758                 if (vconf_get_int(VCONFKEY_BT_STATUS, &bt_status_before_mode) == 0)
759                         _bt_core_set_bt_status(BT_FLIGHT_MODE, bt_status_before_mode);
760
761                 _bt_core_service_request_adapter(BT_DISABLE_ADAPTER);
762                 _bt_disable_adapter();
763         }
764
765         if (adapter_status_le == BT_LE_ACTIVATED) {
766                 int bt_le_status_before_mode = 0;
767
768                 if (vconf_get_int(VCONFKEY_BT_LE_STATUS, &bt_le_status_before_mode) == 0)
769                         _bt_core_set_bt_le_status(BT_FLIGHT_MODE, bt_le_status_before_mode);
770
771                 _bt_core_service_request_adapter(BT_DISABLE_ADAPTER_LE);
772                 _bt_disable_adapter_le();
773         }
774
775         return FALSE;
776 }
777
778 static int __bt_eventsystem_set_value(const char *event, const char *key, const char *value)
779 {
780         int ret;
781         bundle *b = NULL;
782
783         b = bundle_create();
784
785         bundle_add_str(b, key, value);
786
787         ret = eventsystem_send_system_event(event, b);
788
789         BT_DBG("eventsystem_send_system_event result: %d", ret);
790
791         bundle_free(b);
792
793         return ret;
794 }
795
796 void _bt_core_adapter_added_cb(void)
797 {
798         bt_status_t status;
799         bt_le_status_t le_status;
800         gboolean flight_mode_status;
801
802         BT_DBG("");
803
804         status = _bt_core_get_status();
805         BT_DBG("status : %d", status);
806         le_status = _bt_core_get_le_status();
807         BT_DBG("le_status : %d", le_status);
808
809         if (status == BT_ACTIVATING)
810                 __bt_core_set_status(BT_ACTIVATED);
811         if (le_status == BT_LE_ACTIVATING)
812                 __bt_core_set_le_status(BT_LE_ACTIVATED);
813
814         flight_mode_status = _bt_core_is_flight_mode_enabled();
815
816         if (flight_mode_status == TRUE && _bt_is_flightmode_request() == TRUE) {
817                 _bt_set_flightmode_request(FALSE);
818                 g_timeout_add(2000, (GSourceFunc)__bt_core_disable_timeout_cb, NULL);
819                 return;
820         }
821         _bt_set_flightmode_request(FALSE);
822         _bt_core_terminate();
823 }
824
825 void _bt_core_adapter_removed_cb(void)
826 {
827         int flight_mode_value = 0;
828         int power_saving_mode = 0;
829         gboolean flight_mode_status;
830         static int timer_id = -1;
831
832         BT_DBG("");
833
834         __bt_core_set_status(BT_DEACTIVATED);
835         __bt_core_set_le_status(BT_LE_DEACTIVATED);
836         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
837                 BT_ERR("Set vconf failed");
838         if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
839                 BT_ERR("Set vconf failed");
840
841         if (__bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
842                                                 EVT_VAL_BT_OFF) != ES_R_OK)
843                 BT_ERR("Fail to set value");
844
845         if (__bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
846                                                 EVT_VAL_BT_LE_OFF) != ES_R_OK)
847                 BT_ERR("Fail to set value");
848
849         if (is_recovery_mode == TRUE) {
850                 if (timer_id < 0)
851                         timer_id = g_timeout_add(2000, (GSourceFunc)__bt_core_recovery_cb, NULL);
852                 return;
853         }
854
855         if (vconf_get_int(BT_OFF_DUE_TO_FLIGHT_MODE, &flight_mode_value) != 0)
856                 BT_ERR("Fail to get the flight_mode_deactivated value");
857
858         if (vconf_get_int(BT_OFF_DUE_TO_POWER_SAVING_MODE, &power_saving_mode) != 0)
859                 BT_ERR("Fail to get the ps_mode_deactivated value");
860
861         flight_mode_status = _bt_core_is_flight_mode_enabled();
862
863         if (flight_mode_status == FALSE && _bt_is_flightmode_request() == TRUE) {
864                 _bt_set_flightmode_request(FALSE);
865                 if (timer_id < 0)
866                         timer_id = g_timeout_add(2000, (GSourceFunc)__bt_core_enable_timeout_cb, NULL);
867                 return;
868         }
869         _bt_set_flightmode_request(FALSE);
870
871         if (flight_mode_value == 1 || power_saving_mode == 1) {
872                 BT_DBG("Bt Core not terminated");
873                 return;
874         }
875
876         _bt_core_terminate();
877 }