tizen 2.3 release
[framework/connectivity/mobileap-agent.git] / src / mobileap_bluetooth.c
old mode 100644 (file)
new mode 100755 (executable)
index 077f18a..43cd1c2
@@ -22,7 +22,7 @@
 #include <dbus/dbus-glib-lowlevel.h>
 #include <bluetooth.h>
 
-#include "mobileap_agent.h"
+#include "mobileap_softap.h"
 #include "mobileap_common.h"
 #include "mobileap_bluetooth.h"
 #include "mobileap_handler.h"
@@ -38,10 +38,16 @@ static __bt_remote_device_s __bt_remote_devices[MOBILE_AP_MAX_BT_STA] = {
        {NULL, NULL, IP_ADDRESS_BT_1},
        {NULL, NULL, IP_ADDRESS_BT_2},
        {NULL, NULL, IP_ADDRESS_BT_3},
-       {NULL, NULL, IP_ADDRESS_BT_4},
-       {NULL, NULL, IP_ADDRESS_BT_5},
-       {NULL, NULL, IP_ADDRESS_BT_6},
-       {NULL, NULL, IP_ADDRESS_BT_7}};
+       {NULL, NULL, IP_ADDRESS_BT_4}};
+
+static DBusGMethodInvocation *g_context = NULL;
+
+static void __bt_nap_connection_changed(bool connected, const char *remote_address,
+                               const char *interface_name, void *user_data);
+static void __bt_adapter_state_changed(int result, bt_adapter_state_e adapter_state, void *user_data);
+static void __handle_bt_adapter_visibility();
+
+int __recheck_bt_adapter_timer = 0;
 
 static __bt_remote_device_s *__find_bt_remote(const char *mac)
 {
@@ -56,7 +62,7 @@ static __bt_remote_device_s *__find_bt_remote(const char *mac)
        }
 
        if (i == MOBILE_AP_MAX_BT_STA) {
-               ERR("Not found : %s\n", mac);
+               SERR("Not found : %s\n", mac);
                return NULL;
        }
 
@@ -83,6 +89,9 @@ static __bt_remote_device_s *__add_bt_remote(bt_device_info_s *info, const char
                return NULL;
        }
 
+       _add_interface_routing(__bt_remote_devices[i].intf_name,
+                       __bt_remote_devices[i].intf_ip);
+       _add_routing_rule(__bt_remote_devices[i].intf_name);
        __bt_remote_devices[i].info = info;
 
        return &__bt_remote_devices[i];
@@ -101,10 +110,13 @@ static gboolean __del_bt_remote(const char *mac)
        }
 
        if (i == MOBILE_AP_MAX_BT_STA) {
-               ERR("Not found : %s\n", mac);
+               SERR("Not found : %s\n", mac);
                return FALSE;
        }
 
+       _del_routing_rule(__bt_remote_devices[i].intf_name);
+       _del_interface_routing(__bt_remote_devices[i].intf_name,
+                       __bt_remote_devices[i].intf_ip);
         bt_adapter_free_device_info(__bt_remote_devices[i].info);
         g_free(__bt_remote_devices[i].intf_name);
 
@@ -125,6 +137,9 @@ static void __del_bt_remote_all(void)
                }
 
                if (__bt_remote_devices[i].intf_name) {
+                       _del_routing_rule(__bt_remote_devices[i].intf_name);
+                       _del_interface_routing(__bt_remote_devices[i].intf_name,
+                               __bt_remote_devices[i].intf_ip);
                        g_free(__bt_remote_devices[i].intf_name);
                        __bt_remote_devices[i].intf_name = NULL;
                }
@@ -133,6 +148,213 @@ static void __del_bt_remote_all(void)
        return;
 }
 
+static mobile_ap_error_code_e __init_bt(TetheringObject *obj)
+{
+       int ret;
+
+       ret = bt_initialize();
+       if (ret != BT_ERROR_NONE) {
+               ERR("bt_initialize is failed : %d\n", ret);
+               return MOBILE_AP_ERROR_RESOURCE;
+       }
+
+       ret = bt_adapter_set_state_changed_cb(__bt_adapter_state_changed, (void *)obj);
+       if (ret != BT_ERROR_NONE) {
+               ERR("bt_adapter_set_state_changed_cb is failed : %d\n", ret);
+               bt_deinitialize();
+               return MOBILE_AP_ERROR_RESOURCE;
+       }
+
+       return MOBILE_AP_ERROR_NONE;
+}
+
+static void __deinit_bt(void)
+{
+       int ret;
+
+       ret = bt_adapter_unset_state_changed_cb();
+       if (ret != BT_ERROR_NONE)
+               ERR("bt_adapter_unset_state_changed_cb is failed : %d\n", ret);
+
+       ret = bt_deinitialize();
+       if (ret != BT_ERROR_NONE)
+               ERR("bt_deinitialize is failed : %d\n", ret);
+
+       return;
+}
+
+static gboolean __is_bt_adapter_on(void)
+{
+       int ret;
+       bt_adapter_state_e adapter_state = BT_ADAPTER_DISABLED;
+
+       ret = bt_adapter_get_state(&adapter_state);
+       if (ret != BT_ERROR_NONE) {
+               ERR("bt_adapter_get_state is failed : %d\n", ret);
+               return FALSE;
+       }
+
+       if (adapter_state == BT_ADAPTER_ENABLED)
+               return TRUE;
+       else
+               return FALSE;
+}
+
+gboolean __bt_adapter_timeout_cb(gpointer data)
+{
+       DBG("+\n");
+
+       static int retry_count = 0;
+       if (__is_bt_adapter_on() == TRUE) {
+               DBG("BT Adapter is enabled by other process \n");
+               retry_count = 0;
+               DBG("-\n");
+               return FALSE;
+       } else {
+               if (++retry_count >= PS_RECHECK_COUNT_MAX) {
+                       retry_count = 0;
+                       ERR("_enable_bt_tethering() is failed because of bt_adapter_eanbled() failed:n");
+                       _mobileap_clear_state(MOBILE_AP_STATE_BT);
+                       __deinit_bt();
+                       dbus_g_method_return(g_context,
+                                       MOBILE_AP_ENABLE_BT_TETHERING_CFM, MOBILE_AP_ERROR_INTERNAL);
+                       g_context = NULL;
+                       _unblock_device_sleep();
+                       DBG("-\n");
+                       return FALSE;
+               } else {
+                       DBG("-\n");
+                       return TRUE;
+               }
+       }
+}
+
+static mobile_ap_error_code_e __turn_on_bt_adapter(TetheringObject *obj)
+{
+       int ret;
+
+       ret = bt_adapter_enable();
+       if (ret == BT_ERROR_NOW_IN_PROGRESS) {
+               if (__recheck_bt_adapter_timer) {
+                       g_source_remove(__recheck_bt_adapter_timer);
+               }
+               __recheck_bt_adapter_timer = g_timeout_add(PS_RECHECK_INTERVAL,
+                               __bt_adapter_timeout_cb, NULL);
+               return MOBILE_AP_ERROR_NONE;
+       }
+
+       if (ret != BT_ERROR_NONE && ret != BT_ERROR_ALREADY_DONE) {
+               ERR("bt_adapter_enable is failed : %d\n", ret);
+               if (ret == BT_ERROR_PERMISSION_DENIED)
+                       return MOBILE_AP_ERROR_PERMISSION_DENIED;
+               else
+                       return MOBILE_AP_ERROR_RESOURCE;
+       }
+
+       return MOBILE_AP_ERROR_NONE;
+}
+
+static mobile_ap_error_code_e __turn_on_bt_nap(TetheringObject *obj)
+{
+       int bt_ret = BT_ERROR_NONE;
+
+       bt_ret = bt_nap_set_connection_state_changed_cb(__bt_nap_connection_changed, (void *)obj);
+       if (bt_ret != BT_ERROR_NONE) {
+               ERR("bt_nap_set_connection_state_changed_cb is failed : %d\n", bt_ret);
+               return MOBILE_AP_ERROR_RESOURCE;
+       }
+
+       bt_ret = bt_nap_activate();
+       if (bt_ret != BT_ERROR_NONE && bt_ret != BT_ERROR_ALREADY_DONE) {
+               bt_nap_unset_connection_state_changed_cb();
+               ERR("bt_nap_activate is failed : %d\n", bt_ret);
+               if (bt_ret == BT_ERROR_PERMISSION_DENIED)
+                       return MOBILE_AP_ERROR_PERMISSION_DENIED;
+               else
+                       return MOBILE_AP_ERROR_RESOURCE;
+       }
+
+       return MOBILE_AP_ERROR_NONE;
+}
+
+static void __turn_off_bt_nap(void)
+{
+       int bt_ret;
+
+       bt_ret = bt_nap_disconnect_all();
+       if (bt_ret != BT_ERROR_NONE)
+               ERR("bt_nap_disconnect_all is failed : %d\n", bt_ret);
+       else
+               DBG("bt_nap_disconnect_all is called\n");
+
+       bt_ret = bt_nap_unset_connection_state_changed_cb();
+       if (bt_ret != BT_ERROR_NONE)
+               ERR("bt_nap_unset_connection_state_changed_cb is failed : %d\n", bt_ret);
+
+       return;
+}
+
+mobile_ap_error_code_e _enable_bt_tethering(TetheringObject *obj)
+{
+       mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
+
+       DBG("+\n");
+       if (__recheck_bt_adapter_timer) {
+               g_source_remove(__recheck_bt_adapter_timer);
+               __recheck_bt_adapter_timer = 0;
+       }
+
+       if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP)) {
+               ERR("Wi-Fi AP is enabled\n");
+               return MOBILE_AP_ERROR_RESOURCE;
+       }
+
+       ret = _init_tethering(obj);
+       if (ret != MOBILE_AP_ERROR_NONE) {
+               return ret;
+       }
+
+       ret = __turn_on_bt_nap(obj);
+       if (ret != MOBILE_AP_ERROR_NONE) {
+               _deinit_tethering(obj);
+               return ret;
+       }
+       _delete_timeout_noti();
+       _init_timeout_cb(MOBILE_AP_TYPE_BT, (void *)obj);
+       _start_timeout_cb(MOBILE_AP_TYPE_BT, time(NULL) + TETHERING_CONN_TIMEOUT);
+
+       return ret;
+}
+
+mobile_ap_error_code_e _disable_bt_tethering(TetheringObject *obj)
+{
+       int ret = BT_ERROR_NONE;
+       if (!_mobileap_is_enabled(MOBILE_AP_STATE_BT)) {
+               ERR("BT tethering has not been enabled\n");
+               return MOBILE_AP_ERROR_NOT_ENABLED;
+       }
+       ret = bt_adapter_unset_visibility_mode_changed_cb();
+       if (ret != BT_ERROR_NONE)
+               ERR("bt_adapter_unset_visibility_mode_changed_cb is failed : %d\n", ret);
+
+       _block_device_sleep();
+       if (__is_bt_adapter_on()) {
+               __turn_off_bt_nap();
+               __deinit_bt();
+       }
+
+       _remove_station_info_all(MOBILE_AP_TYPE_BT);
+       __del_bt_remote_all();
+       _deinit_timeout_cb(MOBILE_AP_TYPE_BT);
+
+       _deinit_tethering(obj);
+       _mobileap_clear_state(MOBILE_AP_STATE_BT);
+       _unblock_device_sleep();
+
+       return MOBILE_AP_ERROR_NONE;
+}
+
+
 static void __bt_nap_connection_changed(bool connected, const char *remote_address, const char *interface_name, void *user_data)
 {
        if (remote_address == NULL || interface_name == NULL || user_data == NULL) {
@@ -145,11 +367,10 @@ static void __bt_nap_connection_changed(bool connected, const char *remote_addre
        int ret;
        int n_station = 0;
 
-       DBG("Remote address : %s, Interface : %s, %s\n",
+       SDBG("Remote address : %s, Interface : %s, %s\n",
                        remote_address, interface_name,
                        connected ? "Connected" : "Disconnected");
 
-
        if (connected) {
                ret = bt_adapter_get_bonded_device_info(remote_address, &info);
                if (ret != BT_ERROR_NONE) {
@@ -177,47 +398,12 @@ static void __bt_nap_connection_changed(bool connected, const char *remote_addre
                _get_station_count((gconstpointer)MOBILE_AP_TYPE_BT,
                                _slist_find_station_by_interface, &n_station);
                if (n_station == 0)
-                       _start_timeout_cb(MOBILE_AP_TYPE_BT);
+                       _start_timeout_cb(MOBILE_AP_TYPE_BT, time(NULL) + TETHERING_CONN_TIMEOUT);
        }
 
        return;
 }
 
-static mobile_ap_error_code_e __activate_bt_nap(TetheringObject *obj)
-{
-       int bt_ret = BT_ERROR_NONE;
-
-       bt_ret = bt_nap_set_connection_state_changed_cb(__bt_nap_connection_changed, (void *)obj);
-       if (bt_ret != BT_ERROR_NONE) {
-               ERR("bt_nap_set_connection_state_changed_cb is failed : %d\n", bt_ret);
-               return MOBILE_AP_ERROR_RESOURCE;
-       }
-
-       bt_ret = bt_nap_activate();
-       if (bt_ret != BT_ERROR_NONE && bt_ret != BT_ERROR_ALREADY_DONE) {
-               bt_nap_unset_connection_state_changed_cb();
-               ERR("bt_nap_activate is failed : %d\n", bt_ret);
-               return MOBILE_AP_ERROR_RESOURCE;
-       }
-
-       return MOBILE_AP_ERROR_NONE;
-}
-
-static void __deactivate_bt_nap(void)
-{
-       int bt_ret;
-
-       bt_ret = bt_nap_deactivate();
-       if (bt_ret != BT_ERROR_NONE)
-               ERR("bt_nap_deactivate is failed : %d\n", bt_ret);
-
-       bt_ret = bt_nap_unset_connection_state_changed_cb();
-       if (bt_ret != BT_ERROR_NONE)
-               ERR("bt_nap_unset_connection_state_changed_cb is failed : %d\n", bt_ret);
-
-       return;
-}
-
 static void __bt_adapter_state_changed(int result, bt_adapter_state_e adapter_state, void *user_data)
 {
        if (user_data == NULL) {
@@ -225,28 +411,20 @@ static void __bt_adapter_state_changed(int result, bt_adapter_state_e adapter_st
                return;
        }
 
+       DBG("+\n");
+
        if (!_mobileap_is_enabled(MOBILE_AP_STATE_BT))
                return;
 
-       int ret;
-       int duration;
-       bt_adapter_visibility_mode_e mode;
+       int ret = MOBILE_AP_ERROR_RESOURCE;
        TetheringObject *obj = (TetheringObject *)user_data;
-       DBusGMethodInvocation *context = obj->bt_context;
 
-       obj->bt_context = NULL;
        if (result != BT_ERROR_NONE) {
                ERR("BT Adapter operation is failed : %d\n", result);
-               if (context) {
-                       ret = MOBILE_AP_ERROR_RESOURCE;
-                       dbus_g_method_return(context,
-                                       MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
-                       _mobileap_clear_state(MOBILE_AP_STATE_BT);
-               }
-               return;
+               goto FAIL;
        }
 
-       DBG("BT Adapter is %s\n", adapter_state == BT_ADAPTER_ENABLED ?
+       SDBG("BT Adapter is %s\n", adapter_state == BT_ADAPTER_ENABLED ?
                        "enabled" : "disabled");
        if (adapter_state == BT_ADAPTER_DISABLED) {
                _disable_bt_tethering(obj);
@@ -254,26 +432,30 @@ static void __bt_adapter_state_changed(int result, bt_adapter_state_e adapter_st
                                SIGNAL_MSG_NOT_AVAIL_INTERFACE);
                return;
        } else {
-               ret = bt_adapter_get_visibility(&mode, &duration);
-               if (ret == BT_ERROR_NONE && mode == BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE)
-                       _create_status_noti(MH_NOTI_BT_VISIBILITY_STR);
-       }
+               ret = _enable_bt_tethering(obj);
+               if (ret != MOBILE_AP_ERROR_NONE) {
+                       ERR("_enable_bt_tethering() is failed : %d\n", ret);
+                       __deinit_bt();
+                       goto FAIL;
+               }
 
-       ret = __activate_bt_nap(obj);
-       if (ret != MOBILE_AP_ERROR_NONE) {
-               bt_adapter_unset_state_changed_cb();
-               bt_deinitialize();
-               _deinit_tethering(obj);
-               dbus_g_method_return(context,
+               _emit_mobileap_dbus_signal(obj, E_SIGNAL_BT_TETHER_ON, NULL);
+               dbus_g_method_return(g_context,
                                MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
-               _mobileap_clear_state(MOBILE_AP_STATE_BT);
+               __handle_bt_adapter_visibility();
+               g_context = NULL;
+               _unblock_device_sleep();
+
                return;
        }
 
-       _emit_mobileap_dbus_signal(obj, E_SIGNAL_BT_TETHER_ON, NULL);
-       if (context)
-               dbus_g_method_return(context,
-                               MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
+FAIL:
+       dbus_g_method_return(g_context,
+                       MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
+       g_context = NULL;
+       _mobileap_clear_state(MOBILE_AP_STATE_BT);
+       _unblock_device_sleep();
+
        return;
 }
 
@@ -299,159 +481,115 @@ void _bt_get_remote_device_name(TetheringObject *obj, const char *mac, char **na
        return;
 }
 
-mobile_ap_error_code_e _enable_bt_tethering(TetheringObject *obj,
-               DBusGMethodInvocation *context)
+static void __bt_adapter_visibility_changed_cb(int result,
+                               bt_adapter_visibility_mode_e visibility_mode, void *user_data)
 {
-       mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
-       int bt_ret;
-       int duration;
-       bt_adapter_visibility_mode_e mode;
-       bt_adapter_state_e adapter_state = BT_ADAPTER_DISABLED;
+       DBG("+\n");
 
-       if (_mobileap_is_enabled(MOBILE_AP_STATE_BT)) {
-               ERR("Bluetooth tethering is already enabled\n");
-               ret = MOBILE_AP_ERROR_ALREADY_ENABLED;
-               return ret;
-       }
+       int ret;
+       int duration;
+       bt_adapter_visibility_mode_e mode = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE;
 
-       if (obj->bt_context != NULL) {
-               ERR("Bluetooth tethering request is progressing\n");
-               ret = MOBILE_AP_ERROR_IN_PROGRESS;
-               return ret;
+       ret = bt_adapter_get_visibility(&mode, &duration);
+       if (ret != BT_ERROR_NONE) {
+               ERR("bt_adapter_get_visibility is failed 0x[%X]\n", ret);
        }
 
-       if (!_mobileap_set_state(MOBILE_AP_STATE_BT)) {
-               ret = MOBILE_AP_ERROR_RESOURCE;
-               goto FAIL;
+       if (mode == BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE) {
+                       ERR("_launch_toast_popup() is failed\n");
        }
 
-       if (!_init_tethering(obj)) {
-               ret = MOBILE_AP_ERROR_RESOURCE;
-               goto FAIL;
-       }
+       DBG("-\n");
+}
 
-       bt_ret = bt_initialize();
-       if (bt_ret != BT_ERROR_NONE) {
-               ERR("bt_initialize is failed : %d\n", bt_ret);
-               _deinit_tethering(obj);
-               ret = MOBILE_AP_ERROR_RESOURCE;
-               goto FAIL;
-       }
+static void __handle_bt_adapter_visibility()
+{
+       DBG("+\n");
 
-       bt_ret = bt_adapter_set_state_changed_cb(__bt_adapter_state_changed, (void *)obj);
-       if (bt_ret != BT_ERROR_NONE) {
-               ERR("bt_adapter_set_state_changed_cb is failed : %d\n", bt_ret);
-               bt_deinitialize();
-               _deinit_tethering(obj);
-               ret = MOBILE_AP_ERROR_RESOURCE;
-               goto FAIL;
-       }
+       int ret;
+       int duration;
+       bt_adapter_visibility_mode_e mode = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE;
 
-       bt_ret = bt_adapter_get_state(&adapter_state);
-       if (bt_ret != BT_ERROR_NONE) {
-               ERR("bt_adapter_get_state is failed : %d\n", bt_ret);
-               bt_adapter_unset_state_changed_cb();
-               bt_deinitialize();
-               _deinit_tethering(obj);
-               ret = MOBILE_AP_ERROR_RESOURCE;
-               goto FAIL;
+       ret = bt_adapter_get_visibility(&mode, &duration);
+       if (ret != BT_ERROR_NONE) {
+               ERR("bt_adapter_get_visibility is failed 0x[%X]\n", ret);
        }
 
-       if (adapter_state == BT_ADAPTER_DISABLED) {
-               bt_ret = bt_adapter_enable();
-               if (bt_ret != BT_ERROR_NONE) {
-                       ERR("bt_adapter_enable is failed : %d\n", bt_ret);
-                       bt_adapter_unset_state_changed_cb();
-                       bt_deinitialize();
-                       _deinit_tethering(obj);
-                       ret = MOBILE_AP_ERROR_RESOURCE;
-                       goto FAIL;
+       if (mode == BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE) {
+               ret = bt_adapter_set_visibility(BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE, 120);
+               if (ret != BT_ERROR_NONE) {
+                       ERR("bt_adapter_set_visibility is failed 0x[%X]\n", ret);
                }
-               obj->bt_context = context;
-               return ret;
-       } else {
-               bt_ret = bt_adapter_get_visibility(&mode, &duration);
-               if (bt_ret == BT_ERROR_NONE && mode == BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE)
-                       _create_status_noti(MH_NOTI_BT_VISIBILITY_STR);
-
-       }
-
-       ret = __activate_bt_nap(obj);
-       if (ret != MOBILE_AP_ERROR_NONE) {
-               bt_adapter_unset_state_changed_cb();
-               bt_deinitialize();
-               _deinit_tethering(obj);
-               ret = MOBILE_AP_ERROR_RESOURCE;
-               goto FAIL;
        }
-
-       _delete_timeout_noti();
-       _init_timeout_cb(MOBILE_AP_TYPE_BT, (void *)obj);
-       _start_timeout_cb(MOBILE_AP_TYPE_BT);
-
-       return ret;
-
-FAIL:
-       _mobileap_clear_state(MOBILE_AP_STATE_BT);
-
-       return ret;
-}
-
-mobile_ap_error_code_e _disable_bt_tethering(TetheringObject *obj)
-{
-       int bt_ret;
-
-       if (!_mobileap_is_enabled(MOBILE_AP_STATE_BT)) {
-               ERR("BT tethering has not been enabled\n");
-               return MOBILE_AP_ERROR_NOT_ENABLED;
-       }
-
-       __deactivate_bt_nap();
-
-       bt_ret = bt_adapter_unset_state_changed_cb();
-       if (bt_ret != BT_ERROR_NONE)
-               ERR("bt_adapter_unset_state_changed_cb is failed : %d\n", bt_ret);
-
-       bt_ret = bt_deinitialize();
-       if (bt_ret != BT_ERROR_NONE)
-               ERR("bt_deinitialize is failed : %d\n", bt_ret);
-
-       _remove_station_info_all(MOBILE_AP_TYPE_BT);
-       __del_bt_remote_all();
-       _deinit_timeout_cb(MOBILE_AP_TYPE_BT);
-
-       _deinit_tethering(obj);
-       _mobileap_clear_state(MOBILE_AP_STATE_BT);
-
-       return MOBILE_AP_ERROR_NONE;
+       bt_adapter_set_visibility_mode_changed_cb(__bt_adapter_visibility_changed_cb, NULL);
+       DBG("-\n");
 }
-
 gboolean tethering_enable_bt_tethering(TetheringObject *obj,
                DBusGMethodInvocation *context)
 {
        mobile_ap_error_code_e ret;
+       gboolean ret_val = FALSE;
 
        DBG("+\n");
 
        g_assert(obj != NULL);
        g_assert(context != NULL);
 
+       if (g_context) {
+               DBG("It is turnning on\n");
+               dbus_g_method_return(context,
+                               MOBILE_AP_ENABLE_BT_TETHERING_CFM,
+                               MOBILE_AP_ERROR_IN_PROGRESS);
+               return FALSE;
+       }
+
+       g_context = context;
+
+       _block_device_sleep();
 
-       ret = _enable_bt_tethering(obj, context);
+       ret = __init_bt(obj);
+       if (ret != MOBILE_AP_ERROR_NONE)
+               goto DONE;
+
+       if (!_mobileap_set_state(MOBILE_AP_STATE_BT)) {
+               ret = MOBILE_AP_ERROR_RESOURCE;
+               __deinit_bt();
+               goto DONE;
+       }
+
+       if (__is_bt_adapter_on() == FALSE) {
+               DBG("Bluetooth is deactivated\n");
+               if (__turn_on_bt_adapter(obj) != MOBILE_AP_ERROR_NONE) {
+                       ERR("__turn_on_bt_adapter is failed\n");
+                       ret = MOBILE_AP_ERROR_INTERNAL;
+                       _mobileap_clear_state(MOBILE_AP_STATE_BT);
+                       __deinit_bt();
+                       goto DONE;
+               }
+
+               return TRUE;
+       }
+
+       ret = _enable_bt_tethering(obj);
        if (ret != MOBILE_AP_ERROR_NONE) {
                ERR("_enable_bt_tethering() is failed : %d\n", ret);
-               dbus_g_method_return(context,
-                               MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
-               return FALSE;
-       } else if (obj->bt_context == NULL) {
+               _mobileap_clear_state(MOBILE_AP_STATE_BT);
+               __deinit_bt();
+       } else {
                _emit_mobileap_dbus_signal(obj, E_SIGNAL_BT_TETHER_ON, NULL);
-               dbus_g_method_return(context,
-                               MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
+               __handle_bt_adapter_visibility();
+               ret_val = TRUE;
        }
 
-       return TRUE;
-}
+DONE:
+       dbus_g_method_return(g_context,
+                       MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
+       g_context = NULL;
 
+       _unblock_device_sleep();
+
+       return ret_val;
+}
 
 gboolean tethering_disable_bt_tethering(TetheringObject *obj,
                DBusGMethodInvocation *context)
@@ -473,3 +611,8 @@ gboolean tethering_disable_bt_tethering(TetheringObject *obj,
        dbus_g_method_return(context, MOBILE_AP_DISABLE_BT_TETHERING_CFM, ret);
        return TRUE;
 }
+
+gboolean _is_trying_bt_operation(void)
+{
+       return (g_context ? TRUE : FALSE);
+}