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