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