[FRWK] Implement 'Reset Adapter' API
[platform/core/connectivity/bluetooth-frwk.git] / bt-service-adaptation / services / adapter / bt-service-core-adapter.c
index 8b39942..3958cd9 100644 (file)
 #include <string.h>
 #include <vconf.h>
 #include <vconf-internal-keys.h>
-#include <syspopup_caller.h>
-#include <aul.h>
-#include <eventsystem.h>
+#include <bundle.h>
 #include <bundle_internal.h>
+#include <eventsystem.h>
 
 #include "alarm.h"
 
@@ -45,7 +44,7 @@
 #include "bt-service-core-adapter-le.h"
 #include "bt-service-gatt.h"
 
-#ifdef TIZEN_DPM_ENABLE
+#ifdef TIZEN_FEATURE_BT_DPM
 #include "bt-service-dpm.h"
 #endif
 #include "bt-service-hidhost.h"
 #include <oal-manager.h>
 #include <oal-adapter-mgr.h>
 
+#ifdef TIZEN_FEATURE_BT_PAN_NAP
+#include "bt-service-network.h"
+#endif
 /*This file will contain state machines related to adapter and remote device */
 
+#include "bt-internal-types.h"
+
 /* Global variables */
 typedef struct {
        guint event_id;
@@ -72,6 +76,9 @@ static bt_adapter_timer_t visible_timer;
 
 static guint timer_id = 0;
 
+static gboolean a2dp_init_pending = FALSE;
+
+
 /* Adapter default states */
 static bt_status_t adapter_state = BT_DEACTIVATED;
 static bt_adapter_discovery_state_t adapter_discovery_state = ADAPTER_DISCOVERY_STOPPED;
@@ -89,12 +96,13 @@ static void __bt_adapter_state_set_status(bt_status_t status);
 static void __bt_adapter_update_discovery_status(bt_adapter_discovery_state_t status);
 static void __bt_adapter_state_change_callback(int bt_status);
 static int __bt_adapter_state_handle_request(gboolean enable);
-static int __bt_adapter_state_discovery_request(gboolean enable);
+static int __bt_adapter_state_discovery_request(gboolean enable,
+               unsigned short max_response, unsigned short duration, unsigned int mask,
+               gboolean is_custom, bt_discovery_role_type_t role);
 static void __bt_adapter_discovery_state_change_callback(int bt_discovery_status);
 static gboolean __bt_is_service_request_present(int service_function);
-#ifdef TIZEN_MOBILE
+
 static void __bt_set_visible_mode(void);
-#endif
 static void __bt_set_local_name(void);
 
 /* Initialize BT stack (Initialize OAL layer) */
@@ -125,20 +133,55 @@ int _bt_enable_adapter(void)
        return __bt_adapter_state_handle_request(TRUE);
 }
 
+int _bt_enable_core(void)
+{
+       /* TODO_40 : 4.0 merge  */
+       BT_INFO("Not Supported");
+       return BLUETOOTH_ERROR_NOT_SUPPORT;
+}
+
+int _bt_recover_adapter(void)
+{
+       /* TODO_40 : 4.0 merge  */
+       BT_INFO("Not Supported");
+       return BLUETOOTH_ERROR_NOT_SUPPORT;
+}
+
+int _bt_reset_adapter(void)
+{
+       BT_INFO("+");
+       if (OAL_STATUS_SUCCESS != adapter_reset())
+               return BLUETOOTH_ERROR_INTERNAL;
+
+       /* TODO_40 : 4.0 merge  */
+       /* TODO Currently bt-service is not terminated in tizen next.
+           It should be handled in future patch */
+       if (_bt_adapter_get_status() == BT_DEACTIVATED)
+               g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
 int _bt_disable_adapter(void)
 {
        return __bt_adapter_state_handle_request(FALSE);
 }
 
+int _bt_start_discovery(unsigned short max_response,
+               unsigned short duration, unsigned int cod_mask)
+{
+       return __bt_adapter_state_discovery_request(TRUE, max_response, duration,
+                               cod_mask, FALSE, 0x00);
+}
 
-int _bt_start_discovery(void)
+int _bt_start_custom_discovery(bt_discovery_role_type_t role)
 {
-       return __bt_adapter_state_discovery_request(TRUE);
+       return __bt_adapter_state_discovery_request(TRUE, 0, 0, 0, TRUE, role);
 }
 
 int _bt_cancel_discovery(void)
 {
-       return __bt_adapter_state_discovery_request(FALSE);
+       return __bt_adapter_state_discovery_request(FALSE, 0, 0, 0, FALSE, 0x00);
 }
 
 gboolean _bt_is_discovering(void)
@@ -298,10 +341,10 @@ static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
                visible_timer.event_id = 0;
                visible_timer.timeout = 0;
 
-#ifndef TIZEN_PROFILE_WEARABLE
-               if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
-                       BT_ERR("Set vconf failed\n");
-#endif
+               if (!TIZEN_PROFILE_WEARABLE) {
+                       if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
+                               BT_ERR("Set vconf failed\n");
+               }
        }
        /* Switch Off visibility in Bluez */
        _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
@@ -329,10 +372,11 @@ static gboolean __bt_timeout_handler(gpointer user_data)
                visible_timer.event_id = 0;
                visible_timer.timeout = 0;
 
-#ifndef TIZEN_PROFILE_WEARABLE
-               if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
-                       BT_ERR("Set vconf failed\n");
-#endif
+               if (!TIZEN_PROFILE_WEARABLE) {
+                       if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
+                               BT_ERR("Set vconf failed\n");
+               }
+
                return FALSE;
        }
 
@@ -357,21 +401,23 @@ static void __bt_visibility_alarm_create()
 static int __bt_set_visible_time(int timeout)
 {
        int result;
+#ifdef TIZEN_FEATURE_BT_DPM
+       int discoverable_state = DPM_BT_ERROR;
+#endif
 
        __bt_visibility_alarm_remove();
 
        visible_timer.timeout = timeout;
 
-#ifndef TIZEN_PROFILE_WEARABLE
-#ifdef TIZEN_DPM_ENABLE
-       if (_bt_dpm_get_bluetooth_limited_discoverable_state() != DPM_RESTRICTED) {
+#ifdef TIZEN_FEATURE_BT_DPM
+       _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
+       if (discoverable_state != DPM_RESTRICTED) {
 #endif
                if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
                        BT_ERR("Set vconf failed");
-#ifdef TIZEN_DPM_ENABLE
+#ifdef TIZEN_FEATURE_BT_DPM
        }
 #endif
-#endif
 
        if (timeout <= 0)
                return BLUETOOTH_ERROR_NONE;
@@ -402,20 +448,26 @@ static int __bt_set_visible_time(int timeout)
 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
 {
        int result;
+#ifdef TIZEN_FEATURE_BT_DPM
+       int discoverable_state = DPM_BT_ERROR;
+#endif
 
        BT_DBG("+");
 
        BT_INFO("discoverable_mode: %d, timeout: %d", discoverable_mode, timeout);
 
-#ifdef TIZEN_DPM_ENABLE
+#ifdef TIZEN_FEATURE_BT_DPM
+       _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
        if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE &&
-                       _bt_dpm_get_bluetooth_limited_discoverable_state() == DPM_RESTRICTED) {
-               _bt_launch_dpm_popup("DPM_POLICY_DISABLE_BT_HANDSFREE");
+                discoverable_state == DPM_RESTRICTED) {
+               if (headed_plugin_info->plugin_headed_enabled)
+                       headed_plugin_info->headed_plugin->bt_launch_dpmpopup("DPM_POLICY_DISABLE_BT_HANDSFREE");
                return BLUETOOTH_ERROR_ACCESS_DENIED;
        }
        if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE &&
-                       _bt_dpm_get_bluetooth_limited_discoverable_state() == DPM_RESTRICTED) {
-               _bt_launch_dpm_popup("DPM_POLICY_DISABLE_BT");
+               discoverable_state == DPM_RESTRICTED) {
+               if (headed_plugin_info->plugin_headed_enabled)
+                       headed_plugin_info->headed_plugin->bt_launch_dpmpopup("DPM_POLICY_DISABLE_BT");
                return BLUETOOTH_ERROR_ACCESS_DENIED;
        }
 #endif
@@ -524,6 +576,162 @@ int _bt_adapter_get_bonded_devices(void)
        return result;
 }
 
+int _bt_get_profile_connected_devices(char *profile_uuid, GArray **addr_list)
+{
+       BT_DBG("+");
+       GDBusConnection *conn;
+       GDBusProxy *manager_proxy;
+       GVariant *result = NULL;
+       GVariant *result1 = NULL;
+       GVariantIter *iter = NULL;
+       GError *error = NULL;
+       char *object_path = NULL;
+       GVariantIter *interface_iter;
+       char *interface_str = NULL;
+       GDBusProxy *device_proxy = NULL;
+       gboolean is_connected = FALSE;
+
+       conn = _bt_gdbus_get_system_gconn();
+       retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+       manager_proxy = _bt_get_manager_proxy();
+       retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+       result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
+                       NULL,
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       NULL);
+
+       if (!result) {
+               if (error != NULL) {
+                       BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
+                       g_clear_error(&error);
+                       error = NULL;
+               } else
+                       BT_ERR("Failed to Failed to GetManagedObjects");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
+       g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
+
+       /* Parse the signature:  oa{sa{sv}}} */
+        while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
+                if (object_path == NULL)
+                        continue;
+
+                while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
+                                &interface_str, NULL)) {
+                       if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
+                               BT_DBG("Found a device: %s", object_path);
+                               g_free(interface_str);
+
+                               device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+                                               NULL, BT_BLUEZ_NAME,
+                                               object_path, BT_DEVICE_INTERFACE,  NULL, NULL);
+
+                               if (device_proxy == NULL) {
+                                       BT_DBG("Device don't have this service");
+                                       break;
+                               }
+
+                               result1 = g_dbus_proxy_call_sync(device_proxy, "IsConnectedProfile",
+                                               g_variant_new("(s)", profile_uuid),
+                                               G_DBUS_CALL_FLAGS_NONE,
+                                               -1,
+                                               NULL,
+                                               &error);
+
+                               if (result1 == NULL) {
+                                       BT_ERR("Error occured in Proxy call");
+                                       if (error) {
+                                               BT_ERR("Error occured in Proxy call [%s]\n", error->message);
+                                               g_error_free(error);
+                                               error = NULL;
+                                       }
+                                       g_object_unref(device_proxy);
+                                       break;
+                               }
+                               g_variant_get(result1, "(b)", &is_connected);
+
+                               if (is_connected == TRUE) {
+                                       char address[BT_ADDRESS_STRING_SIZE];
+                                       bluetooth_device_address_t *addr = NULL;
+
+                                       _bt_convert_device_path_to_address(object_path, address);
+
+                                       addr = g_malloc0(sizeof(bluetooth_device_address_t));
+                                       _bt_convert_addr_string_to_type(addr->addr, address);
+
+                                       g_array_append_vals(*addr_list, addr,
+                                                       sizeof(bluetooth_device_address_t));
+                               }
+
+                               g_variant_unref(result1);
+                               g_object_unref(device_proxy);
+
+                               break;
+                       }
+                }
+        }
+
+        g_variant_unref(result);
+        g_variant_iter_free(iter);
+
+        BT_DBG("-");
+        return BLUETOOTH_ERROR_NONE;
+}
+
+static void __bt_handle_pending_a2dp_init(service_uuid_t *service_list, unsigned int count)
+{
+       int ret;
+       unsigned int i;
+       unsigned char *uuid;
+       char uuid_str[BT_UUID_STRING_SIZE];
+
+       if (!a2dp_init_pending)
+               return;
+
+       BT_DBG("+");
+       a2dp_init_pending = FALSE;
+       for (i = 0; i < count; i++) {
+               uuid = service_list[i].uuid;
+               _bt_service_convert_uuid_type_to_string(uuid_str, uuid);
+               BT_INFO("Adapter Service: [%s]", uuid_str);
+               if (!strcasecmp(uuid_str, A2DP_SINK_UUID)) {
+                       BT_INFO("Enable A2DP Sink role");
+                       /* Initialize A2DP Sink */
+                       ret = _bt_audio_initialize(BT_A2DP_SINK_MODULE);
+                       if (ret != BLUETOOTH_ERROR_NONE)
+                               BT_ERR("_bt_audio_initialize(BT_A2DP_SINK_MODULE) Failed");
+
+                       /* Initialize AVRCP Controller */
+                       ret = _bt_audio_initialize(BT_AVRCP_CTRL_MODULE);
+                       if (ret != BLUETOOTH_ERROR_NONE)
+                               BT_ERR("_bt_audio_initialize(BT_AVRCP_CTRL_MODULE) Failed");
+
+                       _bt_audio_set_current_role(BLUETOOTH_A2DP_SINK);
+                       return;
+               }
+       }
+
+       BT_INFO("Enable A2DP Source role by default");
+       /* Initialize A2DP Source */
+       ret = _bt_audio_initialize(BT_A2DP_SOURCE_MODULE);
+       if (ret != BLUETOOTH_ERROR_NONE)
+               BT_ERR("_bt_audio_initialize(BT_A2DP_SOURCE_MODULE) Failed");
+
+       /* Initialize AVRCP Target */
+       ret = _bt_audio_initialize(BT_AVRCP_MODULE);
+       if (ret != BLUETOOTH_ERROR_NONE)
+               BT_ERR("_bt_audio_initialize(BT_AVRCP_MODULE) Failed");
+
+       _bt_audio_set_current_role(BLUETOOTH_A2DP_SOURCE);
+       BT_DBG("-");
+}
+
 static void __bt_adapter_event_handler(int event_type, gpointer event_data)
 {
        int result = BLUETOOTH_ERROR_NONE;
@@ -659,6 +867,7 @@ static void __bt_adapter_event_handler(int event_type, gpointer event_data)
 
                count = list->num;
                service_list = list->service_list;
+               __bt_handle_pending_a2dp_init(service_list, count);
                __bt_adapter_handle_pending_requests(BT_IS_SERVICE_USED, service_list, count);
                break;
        }
@@ -690,7 +899,7 @@ static void __bt_adapter_event_handler(int event_type, gpointer event_data)
        BT_DBG("-");
 }
 
-static int __bt_init_profiles()
+int _bt_init_profiles()
 {
        int ret;
 
@@ -700,43 +909,31 @@ static int __bt_init_profiles()
                BT_ERR("_bt_hidhost_initialize Failed");
                return ret;
        }
+
        ret = _bt_socket_init();
        if (ret != BLUETOOTH_ERROR_NONE) {
                BT_ERR("_bt_socket_init Failed");
                return ret;
        }
-       /* Initialize A2DP Source */
-       ret = _bt_audio_initialize(BT_A2DP_SOURCE_MODULE);
-       if (ret != BLUETOOTH_ERROR_NONE) {
-               BT_ERR("_bt_audio_initialize(BT_A2DP_SOURCE_MODULE) Failed");
-               return ret;
-       }
 
-       /* Initialize AVRCP Target */
-       ret = _bt_audio_initialize(BT_AVRCP_MODULE);
-       if (ret != BLUETOOTH_ERROR_NONE) {
-               BT_ERR("_bt_audio_initialize(BT_AVRCP_MODULE) Failed");
-               return ret;
+       /*
+        * Query local adapter services and based on a2dp service uuids initialized
+        * in bluetooth stack, enable A2DP sourec or A2DP sink role.
+        */
+       ret =  adapter_get_service_uuids();
+       if (ret != OAL_STATUS_SUCCESS) {
+               BT_ERR("adapter_get_service_uuids failed: %d", ret);
+               return BLUETOOTH_ERROR_INTERNAL;
+       } else {
+               a2dp_init_pending = TRUE;
        }
 
-       /* Initialize A2DP Sink */
-       ret = _bt_audio_initialize(BT_A2DP_SINK_MODULE);
-       if (ret != BLUETOOTH_ERROR_NONE) {
-               BT_ERR("_bt_audio_initialize(BT_A2DP_SINK_MODULE) Failed");
-               return ret;
-       }
        /* Initialize HFP Audio Gateway */
        ret = _bt_audio_initialize(BT_AG_MODULE);
        if (ret != BLUETOOTH_ERROR_NONE) {
                BT_ERR("_bt_audio_initialize(BT_AG_MODULE) Failed");
                return ret;
        }
-       /* Initialize AVRCP Controller */
-       ret = _bt_audio_initialize(BT_AVRCP_CTRL_MODULE);
-       if (ret != BLUETOOTH_ERROR_NONE) {
-               BT_ERR("_bt_audio_initialize(BT_AVRCP_CTRL_MODULE) Failed");
-               return ret;
-       }
        /* Registering callback for receiving audio services searched */
        ret = _bt_audio_initialize(BT_AUDIO_ALL_MODULE);
        if (ret != BLUETOOTH_ERROR_NONE) {
@@ -765,32 +962,48 @@ static int __bt_init_profiles()
        return BLUETOOTH_ERROR_NONE;
 }
 
+int _bt_cleanup_profiles(void)
+{
+       /* TODO: Cleanup bluetooth profiles */
+       _bt_hidhost_deinitialize();
+       _bt_socket_deinit();
+#if 0
+       /* TODO: Cleanup bluetooth audio profiles */
+       //_bt_audio_deinitialize(BT_A2DP_SOURCE_MODULE);
+       //_bt_audio_deinitialize(BT_AVRCP_MODULE);
+       //_bt_audio_deinitialize(BT_A2DP_SINK_MODULE);
+       //_bt_audio_deinitialize(BT_AG_MODULE);
+       //_bt_audio_deinitialize(BT_AVRCP_CTRL_MODULE);
+       //_bt_audio_deinitialize(BT_AUDIO_ALL_MODULE);
+#endif
+       _bt_hdp_deinit();
+       _bt_gatt_deinit();
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
 /* OAL post initialization handler */
 static void __bt_post_oal_init(void)
 {
        int ret;
        int status = VCONFKEY_BT_STATUS_OFF;
 
-       BT_DBG("OAL initialized, Init profiles..");
-       ret = __bt_init_profiles();
-       if (ret != BLUETOOTH_ERROR_NONE)
-               BT_ERR("Bluetooth profile init error: %d", ret);
-
+       BT_DBG("OAL initialized");
        if (vconf_get_int(VCONFKEY_BT_STATUS, &status) != 0) {
                BT_ERR("Fail to get the enabled value");
        }
 
+#if 0
        /* Update Bluetooth Status to OFF */
        if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
                BT_ERR("Set vconf failed\n");
+#endif
 
        if (status & VCONFKEY_BT_STATUS_ON) {
                ret = _bt_enable_adapter();
                if (ret != BLUETOOTH_ERROR_NONE)
                        BT_ERR("_bt_enable_adapter failed with error: %d", ret);
        }
-
-       return;
 }
 
 /* OAL initialization handler */
@@ -860,7 +1073,7 @@ static void __bt_adapter_handle_pending_requests(int service_function, void *use
                        g_array_append_vals(out_param, user_data, size);
                        break;
                case BT_IS_SERVICE_USED: {
-                       int i;
+                       unsigned int i;
                        gboolean used = FALSE;
                        unsigned char *uuid;
                        char uuid_str[BT_UUID_STRING_SIZE];
@@ -896,7 +1109,7 @@ static void __bt_adapter_handle_pending_requests(int service_function, void *use
                        if (NULL != req_info->user_data)
                                continue;
 
-                       BT_DBG("Total num of bonded devices = [%d]", count);
+                       BT_DBG("BT_GET_BONDED_DEVICES: count = [%d]", count);
                        /* No bonded devices, return method invocation */
                        if (0 == count || !addr_list)
                                break;
@@ -945,21 +1158,46 @@ static void __bt_adapter_handle_pending_requests(int service_function, void *use
        }
 }
 
+static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
+{
+       char *phone_name = NULL;
+       char *ptr = NULL;
+
+       if (node == NULL)
+               return;
+
+       if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
+               phone_name = vconf_keynode_get_str(node);
+
+               if (phone_name && strlen(phone_name) != 0) {
+                       if (!g_utf8_validate(phone_name, -1,
+                                       (const char **)&ptr))
+                               *ptr = '\0';
+
+                       _bt_set_local_name(phone_name);
+               }
+       }
+}
+
 /* Request return handlings */
 static gboolean __bt_adapter_post_set_enabled(gpointer user_data)
 {
        BT_INFO("__bt_adapter_post_set_enabled>>");
 
-#ifdef TIZEN_MOBILE
-       __bt_set_visible_mode();
-#else
-#ifdef TIZEN_TV
-       if (BLUETOOTH_ERROR_NONE != _bt_set_discoverable_mode(
-                       BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0))
-               BT_ERR("Fail to set discoverable mode");
-#endif
-#endif
-       __bt_set_local_name();
+       if (!TIZEN_PROFILE_TV) {
+               __bt_set_visible_mode();
+
+               /* add the vconf noti handler */
+               if (0 != vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
+                               (vconf_callback_fn)__bt_phone_name_changed_cb, NULL))
+                       BT_ERR("DEVICE_NAME key changed notification registration failed");
+
+               __bt_set_local_name();
+       } else {
+               if (BLUETOOTH_ERROR_NONE != _bt_set_discoverable_mode(
+                               BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0))
+                       BT_ERR("Fail to set discoverable mode");
+       }
 
        /* Get All properties */
        if (OAL_STATUS_SUCCESS != adapter_get_properties())
@@ -972,14 +1210,24 @@ static gboolean __bt_adapter_post_set_enabled(gpointer user_data)
 static gboolean __bt_adapter_post_set_disabled(gpointer user_data)
 {
        BT_INFO("_bt_adapter_post_set_disabled>>");
-       /* Add Adapter disabled post processing codes */
+
+       if (!TIZEN_PROFILE_TV) {
+               /* Add Adapter disabled post processing codes */
+               if (vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
+                               (vconf_callback_fn)__bt_phone_name_changed_cb) != 0)
+                       BT_ERR("vconf_ignore_key_changed failed");
+       }
+
        return FALSE;
 }
 
 static void __bt_adapter_update_bt_enabled(void)
 {
        int result = BLUETOOTH_ERROR_NONE;
-       BT_INFO("_bt_adapter_update_bt_enabled>>");
+       BT_INFO("_bt_adapter_update_bt_enabled >> Init profiles...");
+       if (BLUETOOTH_ERROR_NONE != _bt_init_profiles())
+               BT_ERR("Bluetooth profile init failed");
+
        /* Update Bluetooth Status to notify other modules */
        if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
                BT_ERR("Set vconf failed\n");
@@ -997,7 +1245,8 @@ static void __bt_adapter_update_bt_enabled(void)
 static void __bt_adapter_update_bt_disabled(void)
 {
        int result = BLUETOOTH_ERROR_NONE;
-       BT_INFO("_bt_adapter_update_bt_disabled>>");
+       BT_INFO("_bt_adapter_update_bt_disabled >> Cleanup profiles...");
+       _bt_cleanup_profiles();
 
        int power_off_status = 0;
        int ret;
@@ -1008,7 +1257,7 @@ static void __bt_adapter_update_bt_disabled(void)
 
        /* Update Bluetooth Status to notify other modules */
        if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
-               BT_ERR("Set vconf failed\n");
+               BT_ERR("Set vconf failed");
 
        /* TODO:Add timer function to handle any further post processing */
        g_idle_add((GSourceFunc)__bt_adapter_post_set_disabled, NULL);
@@ -1021,7 +1270,6 @@ static void __bt_adapter_update_bt_disabled(void)
                        g_variant_new("(i)", result));
 }
 
-
 static void __bt_adapter_state_set_status(bt_status_t status)
 {
         BT_INFO("adapter_status changed [%d] -> [%d]", adapter_state, status);
@@ -1071,8 +1319,7 @@ static int __bt_adapter_state_handle_request(gboolean enable)
        BT_DBG("");
 
        switch (adapter_state) {
-       case BT_ACTIVATING:
-       {
+       case BT_ACTIVATING: {
                BT_INFO("Adapter is currently in activating state, state [%d]",
                                adapter_state);
                if (enable) {
@@ -1098,8 +1345,7 @@ static int __bt_adapter_state_handle_request(gboolean enable)
                }
                break;
        }
-       case BT_ACTIVATED:
-       {
+       case BT_ACTIVATED: {
                BT_INFO("Adapter is currently in activated state, state [%d]",
                                adapter_state);
                if (enable) {
@@ -1125,8 +1371,7 @@ static int __bt_adapter_state_handle_request(gboolean enable)
                }
                break;
        }
-       case BT_DEACTIVATING:
-       {
+       case BT_DEACTIVATING: {
                BT_INFO("Adapter is currently in deactivating state, state [%d]",
                                adapter_state);
                if (!enable) {
@@ -1134,7 +1379,7 @@ static int __bt_adapter_state_handle_request(gboolean enable)
 
                } else {
                        result = adapter_enable();
-                       if (result != OAL_STATUS_SUCCESS) {
+                       if (result != OAL_STATUS_SUCCESS && result != OAL_STATUS_PENDING) {
                                BT_ERR("adapter_enable failed: [%d]", result);
                                adapter_disable();
                                result = BLUETOOTH_ERROR_INTERNAL;
@@ -1147,15 +1392,14 @@ static int __bt_adapter_state_handle_request(gboolean enable)
                }
                break;
        }
-       case BT_DEACTIVATED:
-       {
+       case BT_DEACTIVATED: {
                BT_INFO("Adapter is currently in deactivated state, state [%d]",
                                adapter_state);
                if (!enable) {
                        return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
                } else {
                        result = adapter_enable();
-                       if (result != OAL_STATUS_SUCCESS) {
+                       if (result != OAL_STATUS_SUCCESS && result != OAL_STATUS_PENDING) {
                                BT_ERR("adapter_enable failed: [%d]", result);
                                adapter_disable();
                                result = BLUETOOTH_ERROR_INTERNAL;
@@ -1168,7 +1412,11 @@ static int __bt_adapter_state_handle_request(gboolean enable)
                }
                break;
        }
+       default:
+               BT_ERR("Unknown state: %d", adapter_state);
+               break;
        }
+
        if (enable && result == BLUETOOTH_ERROR_NONE) {
                /* Adapter enable request is successful, setup event handlers */
                _bt_service_register_event_handler_callback(
@@ -1178,7 +1426,10 @@ static int __bt_adapter_state_handle_request(gboolean enable)
        return result;
 }
 
-static int __bt_adapter_state_discovery_request(gboolean enable)
+static int __bt_adapter_state_discovery_request(gboolean enable,
+               unsigned short max_response, unsigned short duration,
+               unsigned int mask, gboolean is_custom,
+               bt_discovery_role_type_t role)
 {
        int result = BLUETOOTH_ERROR_NONE;
 
@@ -1226,13 +1477,19 @@ static int __bt_adapter_state_discovery_request(gboolean enable)
                if (!enable)
                        return BLUETOOTH_ERROR_NOT_IN_OPERATION;
                else {
-                       result = adapter_start_inquiry();
-               if (result != OAL_STATUS_SUCCESS) {
+                       BT_DBG("max_resp: %u, duration: %u, cod: 0x%X", max_response, duration, mask);
+
+                       if (!is_custom)
+                               result = adapter_start_inquiry(duration);
+                       else
+                               result = adapter_start_custom_inquiry(role);
+
+                       if (result != OAL_STATUS_SUCCESS) {
                                BT_ERR("Start Discovery failed: %d", result);
                                result = BLUETOOTH_ERROR_INTERNAL;
                        } else {
                                BT_ERR("Start Discovery Triggered successfully");
-                       __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STARTING);
+                               __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STARTING);
                                result = BLUETOOTH_ERROR_NONE;
                        }
                }
@@ -1244,7 +1501,11 @@ static int __bt_adapter_state_discovery_request(gboolean enable)
                if (!enable)
                        return BLUETOOTH_ERROR_NOT_IN_OPERATION;
                else {
-                       result = adapter_start_inquiry();
+                       BT_DBG("max_resp: %u, duration: %u, cod: 0x%X", max_response, duration, mask);
+                       if (!is_custom)
+                               result = adapter_start_inquiry(duration);
+                       else
+                               result = adapter_start_custom_inquiry(role);
                        if (result != OAL_STATUS_SUCCESS) {
                                BT_ERR("Start Discovery failed: %d", result);
                                result = BLUETOOTH_ERROR_INTERNAL;
@@ -1256,6 +1517,9 @@ static int __bt_adapter_state_discovery_request(gboolean enable)
                }
                break;
        }
+       default:
+               BT_ERR("Unknown state: %d", adapter_discovery_state);
+               break;
        }
 
        BT_DBG("-");
@@ -1292,17 +1556,19 @@ static void __bt_adapter_discovery_state_change_callback(int bt_discovery_status
        }
 }
 
-#ifdef TIZEN_MOBILE
 static void __bt_set_visible_mode(void)
 {
        int timeout = 0;
+#ifdef TIZEN_FEATURE_BT_DPM
+       int discoverable_state = DPM_BT_ERROR;
+#endif
 
        if (vconf_get_int(BT_FILE_VISIBLE_TIME, &timeout) != 0)
                BT_ERR("Fail to get the timeout value");
 
-#ifdef TIZEN_DPM_ENABLE
-       if (timeout == -1 ||
-                       _bt_dpm_get_bluetooth_limited_discoverable_state() == DPM_RESTRICTED) {
+#ifdef TIZEN_FEATURE_BT_DPM
+       _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
+       if (timeout == -1 || discoverable_state == DPM_RESTRICTED) {
                if (_bt_set_discoverable_mode(
                                        BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE,
                                        timeout) != BLUETOOTH_ERROR_NONE) {
@@ -1333,7 +1599,6 @@ static void __bt_set_visible_mode(void)
        }
 #endif
 }
-#endif
 
 static void __bt_set_local_name(void)
 {
@@ -1353,3 +1618,56 @@ static void __bt_set_local_name(void)
        }
        free(phone_name);
 }
+
+void _bt_adapter_set_status(bt_status_t status)
+{
+       BT_INFO("adapter_status changed [%d] -> [%d]", adapter_state, status);
+       adapter_state = status;
+}
+
+bt_status_t _bt_adapter_get_status(void)
+{
+       return adapter_state;
+}
+
+void _bt_set_disabled(int result)
+{
+       int power_off_status = 0;
+       int ret;
+       int ret_pm_ignore;
+       int pm_ignore_mode = 0;
+
+       ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
+       BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
+
+       ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
+
+       /* Update the vconf BT status in normal Deactivation case only */
+       if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
+               ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
+
+               BT_DBG("Update vconf for BT normal Deactivation");
+
+               if (result == BLUETOOTH_ERROR_TIMEOUT)
+                       if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0)
+                               BT_ERR("Set vconf failed");
+
+               /* Update Bluetooth Status to notify other modules */
+               if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
+                       BT_ERR("Set vconf failed");
+
+               if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
+                                                       EVT_VAL_BT_OFF) != ES_R_OK)
+                       BT_ERR("Fail to set value");
+       }
+
+       if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
+               BT_ERR("Set vconf failed\n");
+
+       _bt_cancel_queued_transfers();
+       _bt_adapter_set_status(BT_DEACTIVATED);
+       __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STOPPED);
+
+       BT_INFO("Adapter disabled");
+}
+