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