[Bluetooth][OTP] Add base code for OTP server role
[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         int isFlightMode = 0;
100         int ret = -1;
101
102         if (TIZEN_FEATURE_FLIGHTMODE_ENABLED) {
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         }
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         if (TIZEN_FEATURE_BT_USB_DONGLE) {
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         }
182         if (ret < 0) {
183                 BT_ERR("running script failed");
184                 if (TIZEN_FEATURE_BT_USB_DONGLE) {
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                 }
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                 if (TIZEN_FEATURE_BT_USB_DONGLE) {
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                 }
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         if (TIZEN_FEATURE_BT_USB_DONGLE) {
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         }
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                 if (TIZEN_FEATURE_BT_USB_DONGLE) {
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                 }
319                 if (ret < 0) {
320                         BT_ERR("running script failed");
321                         if (TIZEN_FEATURE_BT_USB_DONGLE) {
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                         }
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 TIZEN_FEATURE_BT_HPS
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 TIZEN_FEATURE_BT_HPS
356         _bt_core_stop_httpproxy();
357 #endif
358
359 #ifdef TIZEN_FEATURE_BT_OTP
360         _bt_core_stop_otp();
361 #endif
362
363         status = _bt_core_get_status();
364         BT_DBG("status : %d", status);
365
366         if (status == BT_DEACTIVATED) {
367                 __bt_core_set_le_status(BT_LE_DEACTIVATING);
368                 int ret;
369                 if (TIZEN_FEATURE_BT_USB_DONGLE) {
370                         char *argv_down[] = {"/usr/bin/hciconfig", "/usr/bin/hciconfig", "hci0", "down", NULL};
371                         ret = __execute_command("/usr/bin/hciconfig", argv_down);
372                 } else {
373                         ret = __execute_command("/usr/etc/bluetooth/bt-stack-down.sh", NULL);
374                 }
375                 if (ret < 0) {
376                         BT_ERR("running script failed");
377                         __bt_core_set_le_status(BT_LE_ACTIVATED);
378                         return -1;
379                 }
380         } else {
381                         g_timeout_add(BT_CORE_IDLE_TERM_TIME, __bt_core_idle_terminate, NULL);
382         }
383
384         __bt_core_set_le_status(BT_LE_DEACTIVATED);
385
386         BT_DBG("-");
387         return 0;
388 }
389
390 int _bt_core_service_request_adapter(int service_function)
391 {
392         int ret = -1;
393
394         GArray *in_param1 = NULL;
395         GArray *in_param2 = NULL;
396         GArray *in_param3 = NULL;
397         GArray *in_param4 = NULL;
398         GArray *out_param = NULL;
399
400         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
401
402         ret = _bt_core_service_request(BT_CORE_SERVICE, service_function,
403                         in_param1, in_param2, in_param3, in_param4, &out_param);
404         if (ret < 0)
405                 BT_ERR("_bt_core_service_request_adapter() failed");
406
407         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
408
409         return ret;
410 }
411
412 static gboolean __bt_core_check_the_adapter_path(GDBusConnection *conn)
413 {
414         GError *err = NULL;
415         GDBusProxy *manager_proxy = NULL;
416         GVariant *result = NULL;
417         char *adapter_path = NULL;
418
419         if (conn == NULL)
420                 return FALSE;
421
422         manager_proxy =  g_dbus_proxy_new_sync(conn,
423                         G_DBUS_PROXY_FLAGS_NONE, NULL,
424                         "org.bluez",
425                         "/",
426                         "org.freedesktop.DBus.ObjectManager",
427                         NULL, &err);
428
429         if (!manager_proxy) {
430                 if (err != NULL) {
431                         BT_ERR("Unable to create proxy: %s", err->message);
432                         g_clear_error(&err);
433                 } else {
434                         BT_ERR("Fail to create proxy");
435                 }
436                 goto fail;
437         }
438
439         result = g_dbus_proxy_call_sync(manager_proxy, "DefaultAdapter", NULL,
440                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
441         if (!result) {
442                 if (err != NULL) {
443                         BT_ERR("Fail to get DefaultAdapter (Error: %s)", err->message);
444                         g_clear_error(&err);
445                 } else{
446                         BT_ERR("Fail to get DefaultAdapter");
447                 }
448                 goto fail;
449         }
450
451         if (g_strcmp0(g_variant_get_type_string(result), "(o)")) {
452                 BT_ERR("Incorrect result\n");
453                 goto fail;
454         }
455
456         g_variant_get(result, "(&o)", &adapter_path);
457
458         if (adapter_path == NULL ||
459                 strlen(adapter_path) >= BT_CORE_CHECK_ADAPTER_OBJECT_PATH_MAX) {
460                 BT_ERR("Adapter path is inproper\n");
461                 goto fail;
462         }
463
464         g_variant_unref(result);
465         g_object_unref(manager_proxy);
466
467         return TRUE;
468
469 fail:
470         if (result)
471                 g_variant_unref(result);
472
473         if (manager_proxy)
474                 g_object_unref(manager_proxy);
475
476         return FALSE;
477 }
478
479 void _bt_core_update_status(void)
480 {
481         int bt_status = VCONFKEY_BT_STATUS_OFF;
482         int bt_le_status = VCONFKEY_BT_LE_STATUS_OFF;
483         gboolean ret = FALSE;
484
485         ret = __bt_core_check_the_adapter_path(_bt_core_get_gdbus_connection());
486         BT_INFO("check the real status of bt_adapter");
487
488         if (ret != TRUE) {
489                 __bt_core_set_status(BT_DEACTIVATED);
490                 __bt_core_set_le_status(BT_DEACTIVATED);
491         } else {
492                 if (vconf_get_int(VCONFKEY_BT_STATUS, &bt_status) < 0)
493                         BT_ERR("no bluetooth device info, so BT was disabled at previous session");
494                 if (vconf_get_int(VCONFKEY_BT_LE_STATUS, &bt_le_status) < 0)
495                         BT_ERR("no bluetooth le info, so BT LE was disabled at previous session");
496
497                 BT_INFO("bt_status = %d, bt_le_status = %d", bt_status, bt_le_status);
498
499                 if (bt_status & VCONFKEY_BT_STATUS_ON)
500                         __bt_core_set_status(BT_ACTIVATED);
501                 if (bt_le_status & VCONFKEY_BT_LE_STATUS_ON)
502                         __bt_core_set_le_status(BT_ACTIVATED);
503         }
504 }
505
506 gboolean _bt_core_enable_adapter(void)
507 {
508         int ret;
509
510         _bt_set_flightmode_request(FALSE);
511         if (vconf_set_int(BT_OFF_DUE_TO_FLIGHT_MODE, 0) != 0)
512                 BT_ERR("Set vconf failed");
513
514         ret = _bt_enable_adapter();
515         if (ret < 0)
516                 return FALSE;
517         else
518                 return TRUE;
519 }
520
521 gboolean _bt_core_disable_adapter(void)
522 {
523         int ret;
524
525         _bt_set_flightmode_request(FALSE);
526         if (vconf_set_int(BT_OFF_DUE_TO_FLIGHT_MODE, 0) != 0)
527                 BT_ERR("Set vconf failed");
528
529         ret = _bt_disable_adapter();
530         if (ret < 0)
531                 return FALSE;
532         else
533                 return TRUE;
534 }
535
536 gboolean _bt_core_recover_adapter(void)
537 {
538         int ret;
539 #if 0
540         int ret_le;
541 #endif
542         BT_INFO_C("Recover bt adapter");
543
544         _bt_set_flightmode_request(FALSE);
545         if (vconf_set_int(BT_OFF_DUE_TO_FLIGHT_MODE, 0) != 0)
546                 BT_ERR("Set vconf failed");
547
548         is_recovery_mode = TRUE;
549
550         _bt_core_update_status();
551
552         if (_bt_core_get_status() == BT_ACTIVATED) {
553                 _bt_core_set_bt_status(BT_RECOVERY_MODE, 1);
554 #ifdef TIZEN_FEATURE_BUSACT
555                 _bt_core_service_request_adapter(BT_DISABLE_ADAPTER);
556 #endif
557         }
558         if (_bt_core_get_le_status() == BT_LE_ACTIVATED) {
559                 _bt_core_set_bt_le_status(BT_RECOVERY_MODE, 1);
560 #ifdef TIZEN_FEATURE_BUSACT
561                 _bt_core_service_request_adapter(BT_DISABLE_ADAPTER_LE);
562 #endif
563         }
564
565         ret = _bt_disable_adapter();
566         if (ret < 0)
567                 BT_ERR("_bt_disable_adapter() failed");
568
569 /* In platform, don't seperate BR/EDR and LE status */
570 #if 0
571         ret_le = _bt_disable_adapter_le();
572         if (ret_le < 0)
573                 BT_ERR("_bt_disable_adapter_le() failed");
574 #endif
575         return TRUE;
576 }
577
578 gboolean _bt_core_enable_adapter_le(void)
579 {
580         int ret;
581
582         ret = _bt_enable_adapter_le();
583         if (ret < 0)
584                 return FALSE;
585         else
586                 return TRUE;
587 }
588
589 gboolean _bt_core_disable_adapter_le(void)
590 {
591         BT_DBG("+");
592
593         int ret;
594
595         ret = _bt_disable_adapter_le();
596         if (ret < 0)
597                 return FALSE;
598         else
599                 return TRUE;
600 }
601
602 gboolean __bt_core_reset_adapter(void)
603 {
604         /* Forcely terminate */
605         if (__execute_command("/usr/etc/bluetooth/bt-reset-env.sh", NULL) < 0)
606                 BT_ERR("running script failed");
607
608         _bt_core_terminate();
609
610         return TRUE;
611 }
612
613 static gboolean __bt_core_enable_core_timeout_cb(gpointer data)
614 {
615         BT_DBG("+");
616
617         core_enable_timer_id = 0;
618
619         _bt_core_init_vconf_value();
620
621         return FALSE;
622 }
623
624 gboolean _bt_core_enable_core(void)
625 {
626         BT_DBG("+");
627
628         _bt_core_update_status();
629
630         if (core_enable_timer_id > 0)
631                 g_source_remove(core_enable_timer_id);
632
633         core_enable_timer_id = g_timeout_add(200, (GSourceFunc)__bt_core_enable_core_timeout_cb, NULL);
634
635         BT_DBG("-");
636         return TRUE;
637 }
638
639 gboolean _bt_core_set_transfer_value(gboolean value)
640 {
641         const char *event_val = NULL;
642         gboolean ret = TRUE;
643
644         BT_DBG("value: %d", value);
645
646         event_val = value ? EVT_VAL_BT_TRANSFERING : EVT_VAL_BT_NON_TRANSFERING;
647
648         if (__bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_TRANSFERING_STATE,
649                                                 event_val) != ES_R_OK) {
650                 BT_ERR("Fail to set BT state value");
651                 ret = FALSE;
652         }
653
654         if (ret == FALSE || value == FALSE) {
655                 BT_DBG("Terminate bt-core process");
656                 g_timeout_add(BT_CORE_IDLE_TERM_TIME, __bt_core_idle_terminate, NULL);
657         }
658
659         BT_DBG("-");
660         return ret;
661 }
662
663 gboolean _bt_core_factory_test_mode(const char *type, const char *arg)
664 {
665
666         char *cmd = NULL;
667         char *arg_list[3] = { NULL, NULL, NULL };
668
669         BT_DBG("Test item : %s", type);
670
671         if (g_strcmp0(type, "Enable_RF_Test") == 0) {
672                 cmd = "/usr/etc/bluetooth/bt-edutm-on.sh";
673                 arg_list[0] = "bt-edutm-on.sh";
674         } else if (g_strcmp0(type, "Disable_RF_Test") == 0) {
675                 cmd = "/usr/etc/bluetooth/bt-edutm-off.sh";
676                 arg_list[0] = "bt-edutm-off.sh";
677         } else if (g_strcmp0(type, "Slave_Mode") == 0) {
678                 cmd = "/usr/etc/bluetooth/bt-mode-slave.sh";
679                 arg_list[0] = "bt-mode-slave.sh";
680         } else if (g_strcmp0(type, "Master_Mode") == 0) {
681                 cmd = "/usr/etc/bluetooth/bt-mode-master.sh";
682                 arg_list[0] = "bt-mode-master.sh";
683         } else if (g_strcmp0(type, "SSP_Debug_Mode") == 0) {
684                 cmd = "/usr/etc/bluetooth/bt-set-ssp-debug-mode.sh";
685                 arg_list[0] = "bt-set-ssp-debug-mode.sh";
686                 arg_list[1] = (char *)arg;
687         } else if (g_strcmp0(type, "RF_Channel") == 0) {
688                 cmd = "/usr/etc/bluetooth/bt-enable-rf-channel.sh";
689                 arg_list[0] = "bt-enable-rf-channel.sh";
690                 arg_list[1] = (char *)arg;
691         } else {
692                 _bt_core_terminate();
693                 return FALSE;
694         }
695
696         BT_DBG("Run %s", cmd);
697         if (__execute_command(cmd, arg_list) < 0)
698                 BT_ERR("running script failed");
699
700         _bt_core_terminate();
701         return TRUE;
702 }
703
704 static gboolean __bt_core_recovery_cb(gpointer data)
705 {
706         int ret = 0;
707 #ifdef TIZEN_FEATURE_BUSACT
708         gboolean is_request_failed = FALSE;
709         static gboolean is_first_failure = TRUE;
710 #endif
711
712         BT_DBG("+");
713
714 #ifdef TIZEN_FEATURE_BUSACT
715         if (_bt_core_get_bt_status(BT_RECOVERY_MODE) == 1) {
716                 ret = _bt_core_service_request_adapter(BT_ENABLE_ADAPTER);
717                 if (ret < 0)
718                         is_request_failed = TRUE;
719         }
720
721         if (_bt_core_get_bt_le_status(BT_RECOVERY_MODE) == 1) {
722                 ret = _bt_core_service_request_adapter(BT_ENABLE_ADAPTER_LE);
723                 if (ret < 0)
724                         is_request_failed = TRUE;
725         }
726
727         if (is_request_failed == TRUE) {
728                 BT_ERR("Recovery is failed.");
729                 if (is_first_failure == TRUE) {
730                         g_timeout_add(2000, (GSourceFunc)__bt_core_recovery_cb, NULL);
731                         is_first_failure = FALSE;
732                         return FALSE;
733                 } else {
734                         is_first_failure = TRUE;
735                         return FALSE;
736                 }
737         } else
738                 is_first_failure = TRUE;
739 #endif
740
741         if (_bt_core_get_bt_status(BT_RECOVERY_MODE) == 1) {
742                 _bt_core_set_bt_status(BT_RECOVERY_MODE, 0);
743                 ret = _bt_enable_adapter();
744                 if (ret < 0)
745                         BT_ERR("_bt_enable_adapter() failed");
746         }
747
748 #if 0
749         if (_bt_core_get_bt_le_status(BT_RECOVERY_MODE) == 1) {
750                 _bt_core_set_bt_le_status(BT_RECOVERY_MODE, 0);
751                 ret = _bt_enable_adapter_le();
752                 if (ret < 0)
753                         BT_ERR("_bt_enable_adapter_le() failed");
754         }
755 #endif
756         is_recovery_mode = FALSE;
757
758         BT_DBG("-");
759
760         return FALSE;
761 }
762
763 static gboolean __bt_core_enable_timeout_cb(gpointer data)
764 {
765         bt_status_t adapter_status;
766         bt_le_status_t adapter_status_le;
767
768         BT_DBG("");
769
770         if (vconf_set_int(BT_OFF_DUE_TO_FLIGHT_MODE, 0) != 0)
771                 BT_ERR("Set vconf failed");
772
773         adapter_status = _bt_core_get_status();
774         adapter_status_le = _bt_core_get_le_status();
775
776         if (adapter_status == BT_DEACTIVATED &&
777                         _bt_core_get_bt_status(BT_FLIGHT_MODE) != 0) {
778                 _bt_core_set_bt_status(BT_FLIGHT_MODE, 0);
779                 _bt_core_service_request_adapter(BT_ENABLE_ADAPTER);
780                 _bt_enable_adapter();
781         }
782
783         if (adapter_status_le == BT_LE_DEACTIVATED &&
784                         _bt_core_get_bt_le_status(BT_FLIGHT_MODE) != 0) {
785                 _bt_core_set_bt_le_status(BT_FLIGHT_MODE, 0);
786                 _bt_core_service_request_adapter(BT_ENABLE_ADAPTER_LE);
787                 _bt_enable_adapter_le();
788         }
789
790         return FALSE;
791 }
792
793 static gboolean __bt_core_disable_timeout_cb(gpointer data)
794 {
795         bt_status_t adapter_status;
796         bt_le_status_t adapter_status_le;
797
798         BT_DBG("");
799
800         if (vconf_set_int(BT_OFF_DUE_TO_FLIGHT_MODE, 1) != 0)
801                 BT_ERR("Set vconf failed");
802
803         adapter_status = _bt_core_get_status();
804         adapter_status_le = _bt_core_get_le_status();
805
806         if (adapter_status == BT_ACTIVATED) {
807                 int bt_status_before_mode = 0;
808
809                 if (vconf_get_int(VCONFKEY_BT_STATUS, &bt_status_before_mode) == 0)
810                         _bt_core_set_bt_status(BT_FLIGHT_MODE, bt_status_before_mode);
811
812 #ifdef TIZEN_FEATURE_BUSACT
813                 _bt_core_service_request_adapter(BT_DISABLE_ADAPTER);
814 #endif
815                 _bt_disable_adapter();
816         }
817
818         if (adapter_status_le == BT_LE_ACTIVATED) {
819                 int bt_le_status_before_mode = 0;
820
821                 if (vconf_get_int(VCONFKEY_BT_LE_STATUS, &bt_le_status_before_mode) == 0)
822                         _bt_core_set_bt_le_status(BT_FLIGHT_MODE, bt_le_status_before_mode);
823
824 #ifdef TIZEN_FEATURE_BUSACT
825                 _bt_core_service_request_adapter(BT_DISABLE_ADAPTER_LE);
826 #endif
827                 _bt_disable_adapter_le();
828         }
829
830         return FALSE;
831 }
832
833 static int __bt_eventsystem_set_value(const char *event, const char *key, const char *value)
834 {
835         int ret;
836         bundle *b = NULL;
837
838         b = bundle_create();
839
840         bundle_add_str(b, key, value);
841
842         ret = eventsystem_send_system_event(event, b);
843
844         BT_DBG("eventsystem_send_system_event result: %d", ret);
845
846         bundle_free(b);
847
848         return ret;
849 }
850
851 void _bt_core_adapter_added_cb(void)
852 {
853         bt_status_t status;
854         bt_le_status_t le_status;
855         gboolean flight_mode_status;
856
857         BT_DBG("");
858
859         status = _bt_core_get_status();
860         BT_DBG("status : %d", status);
861         le_status = _bt_core_get_le_status();
862         BT_DBG("le_status : %d", le_status);
863
864         if (status == BT_ACTIVATING)
865                 __bt_core_set_status(BT_ACTIVATED);
866         if (le_status == BT_LE_ACTIVATING)
867                 __bt_core_set_le_status(BT_LE_ACTIVATED);
868
869         flight_mode_status = _bt_core_is_flight_mode_enabled();
870
871         if (flight_mode_status == TRUE && _bt_is_flightmode_request() == TRUE) {
872                 _bt_set_flightmode_request(FALSE);
873                 g_timeout_add(2000, (GSourceFunc)__bt_core_disable_timeout_cb, NULL);
874                 return;
875         }
876         _bt_set_flightmode_request(FALSE);
877
878         if (__bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
879                                                 EVT_VAL_BT_ON) != ES_R_OK)
880                 BT_ERR("Fail to set BT state value");
881
882         if (__bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
883                                                 EVT_VAL_BT_LE_ON) != ES_R_OK)
884                 BT_ERR("Fail to set BT LE state value");
885
886         _bt_core_terminate();
887 }
888
889 void _bt_core_adapter_removed_cb(void)
890 {
891         int flight_mode_value = 0;
892         int power_saving_mode = 0;
893         gboolean flight_mode_status;
894         static int timer_id = -1;
895
896         BT_DBG("is_recovery_mode: %d", is_recovery_mode);
897
898         __bt_core_set_status(BT_DEACTIVATED);
899         __bt_core_set_le_status(BT_LE_DEACTIVATED);
900         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
901                 BT_ERR("Set vconf failed");
902         if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
903                 BT_ERR("Set vconf failed");
904
905         if (__bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
906                                                 EVT_VAL_BT_OFF) != ES_R_OK)
907                 BT_ERR("Fail to set value");
908
909         if (__bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
910                                                 EVT_VAL_BT_LE_OFF) != ES_R_OK)
911                 BT_ERR("Fail to set value");
912
913         if (is_recovery_mode == TRUE) {
914                 if (timer_id < 0)
915                         timer_id = g_timeout_add(2000, (GSourceFunc)__bt_core_recovery_cb, NULL);
916                 return;
917         }
918
919         if (vconf_get_int(BT_OFF_DUE_TO_FLIGHT_MODE, &flight_mode_value) != 0)
920                 BT_ERR("Fail to get the flight_mode_deactivated value");
921
922         if (vconf_get_int(BT_OFF_DUE_TO_POWER_SAVING_MODE, &power_saving_mode) != 0)
923                 BT_ERR("Fail to get the ps_mode_deactivated value");
924
925         flight_mode_status = _bt_core_is_flight_mode_enabled();
926
927         if (flight_mode_status == FALSE && _bt_is_flightmode_request() == TRUE) {
928                 _bt_set_flightmode_request(FALSE);
929                 if (timer_id < 0)
930                         timer_id = g_timeout_add(2000, (GSourceFunc)__bt_core_enable_timeout_cb, NULL);
931                 return;
932         }
933         _bt_set_flightmode_request(FALSE);
934
935         if (flight_mode_value == 1 || power_saving_mode == 1) {
936                 BT_DBG("Bt Core not terminated");
937                 return;
938         }
939
940         _bt_core_terminate();
941 }