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