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