Update AG and HF agent codes from wearable product
[platform/core/connectivity/bluetooth-agent.git] / ag-agent / bluetooth-ag-agent.c
index e3b1242..066d2d3 100644 (file)
@@ -24,6 +24,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <signal.h>
+#include <stdbool.h>
 #include <sys/poll.h>
 #include <gio/gunixfdlist.h>
 #include <bundle_internal.h>
 #include "bluetooth-ag-handler.h"
 #include "bluetooth-agent-profile.h"
 
+#include <bluetooth.h>
+#include <bluetooth_internal.h>
+
 #include <TapiUtility.h>
 #include <ITapiSim.h>
 #include <ITapiModem.h>
+#include <ITapiCall.h>
 #include <TelNetwork.h>
+#include <TelCall.h>
 #include <app.h>
 #include <aul.h>
 #include <system_info.h>
 
 #include "contacts.h"
 #include "appsvc.h"
-
-static GMainLoop *gmain_loop = NULL;
-static GDBusProxy *service_gproxy;
-static guint interface_added_sig_id = 0;
-static guint interface_removed_sig_id = 0;
-static guint name_owner_sig_id = 0;
+#include <device-error.h>
+#include <device/battery.h>
+#include <device/callback.h>
+
+static GMainLoop *gmain_loop;
+static GDBusProxy *profile_gproxy;
+static guint interface_added_sig_id;
+static guint interface_removed_sig_id;
+static guint proterty_changed_sig_id;
+static guint name_owner_sig_id;
 GDBusConnection *ag_dbus_conn = NULL;
 gchar *remote_dev_path = NULL;
 gboolean wbs_en;
 uint16_t hfp_ver;
 uint16_t hsp_ver;
-static TapiHandle *tapi_handle;
+static TapiHandle *tapi_handle[3];
+int sim1;
+int sim2;
+static TapiHandle *tapi_handle_preferred_sim;
 extern wbs_options wbs_opts;
 GSList *active_devices = NULL;
-static gchar *local_addr = NULL;
-static GDBusProxy *app_gproxy;
+static gchar *local_addr;
 static gboolean call_launch_requested = FALSE;
-static gchar* sco_owner = NULL;
-static guint sco_open_timer_id = 0;
-static gboolean sco_open_request = FALSE;
+static gchar* sco_owner;
+static guint sco_open_timer_id;
+static gboolean sco_open_request;
 static guint hf_bluez_id;
 static guint hs_bluez_id;
 static guint app_id;
+static guint device_property_id;
 #ifdef TIZEN_FEATURE_BT_MEDIA_ENHANCE
-static guint media_sig_id = 0;
-static guint media_state_sig_id = 0;
+static guint media_sig_id;
+static guint media_state_sig_id;
 static bt_ag_media_transport_state_t transport_state;
 #endif
+static int last_speaker_gain = 9;
+
+#define GET_TAPI_HANDLE \
+       (tapi_handle_preferred_sim != NULL) ? tapi_handle_preferred_sim : \
+               ((sim1 == 1) ? tapi_handle[0] : tapi_handle[1])
 
 #define HSP_AG_UUID "00001112-0000-1000-8000-00805f9b34fb"
 #define HFP_AG_UUID "0000111f-0000-1000-8000-00805f9b34fb"
@@ -78,9 +96,7 @@ static bt_ag_media_transport_state_t transport_state;
 #define DEFAULT_ADAPTER_OBJECT_PATH "/org/bluez/hci0"
 #define VCONF_KEY_BT_LUNAR_ENABLED "db/wms/bt_loop_device_hfp_connected"
 
-#if defined(TIZEN_PROFILE_WEARABLE) && defined(TIZEN_FEATURE_BT_HFP_AG)
-#define CALL_APP_ID "org.tizen.call-ui"
-#endif
+#define CALL_ALIAS_APP_ID "tizen.call"
 
 #if defined(TIZEN_SUPPORT_DUAL_HF)
 #define VCONF_KEY_BT_HOST_BT_MAC_ADDR "db/wms/host_bt_mac"
@@ -105,6 +121,9 @@ static const gchar ag_agent_bluez_introspection_xml[] =
 "     <method name='RequestDisconnection'>"
 "          <arg type='o' name='device' direction='in'/>"
 "     </method>"
+"    <method name='ReplyAuthorize'>"
+"      <arg type='u' name='accept' direction='in'/>"
+"    </method>"
 " </interface>"
 "</node>";
 
@@ -191,11 +210,6 @@ typedef struct {
        uint16_t setting;
 } bt_voice;
 
-struct ag_codec {
-       bt_ag_info_t *bt_ag_info;
-       char *codec_status;
-};
-
 bt_ag_status_t ag = {
        .telephony_ready = FALSE,
        .features = 0,
@@ -217,6 +231,10 @@ static int __bt_ag_sco_connect(bt_ag_info_t *hs);
 void _bt_ag_set_headset_state(bt_ag_info_t *hs, hs_state_t state);
 static void __bt_ag_agent_reg_sim_event(TapiHandle *handle, void *user_data);
 static void __bt_ag_agent_dereg_sim_event(TapiHandle *handle);
+static uint32_t __bt_ag_agent_get_ag_features(void);
+static void  __bt_ag_agent_tel_cb(TapiHandle *handle, int result, void *data, void *user_data);
+static void __bt_ag_agent_subscribe_tapi_updates(TapiHandle *handle);
+static void __bt_ag_agent_unsubscribe_tapi_updates(TapiHandle *handle);
 static void __bt_ag_name_owner_changed_cb(GDBusConnection *connection,
                                        const gchar *sender_name,
                                        const gchar *object_path,
@@ -224,6 +242,7 @@ static void __bt_ag_name_owner_changed_cb(GDBusConnection *connection,
                                        const gchar *signal_name,
                                        GVariant *parameters,
                                        gpointer user_data);
+static GError *__bt_ag_agent_set_error(bt_hfp_agent_error_t error);
 
 static void __bt_convert_addr_type_to_rev_string(char *address,
                                unsigned char *addr)
@@ -236,8 +255,7 @@ static void __bt_convert_addr_type_to_rev_string(char *address,
                        addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
 }
 
-static GDBusProxy *__bt_ag_gdbus_init_service_proxy(const gchar *service,
-                               const gchar *path, const gchar *interface)
+static GDBusProxy *__bt_ag_gdbus_init_profile_proxy(void)
 {
        FN_START;
 
@@ -257,9 +275,8 @@ static GDBusProxy *__bt_ag_gdbus_init_service_proxy(const gchar *service,
 
        proxy =  g_dbus_proxy_new_sync(ag_dbus_conn,
                        G_DBUS_PROXY_FLAGS_NONE, NULL,
-                       service, path,
-                       interface, NULL, &err);
-
+                       BLUEZ_SERVICE_NAME, "/org/bluez",
+                       BLUEZ_PROFILE_MGMT_INTERFACE, NULL, &err);
        if (!proxy) {
                if (err) {
                        ERR("Unable to create proxy: %s", err->message);
@@ -268,6 +285,8 @@ static GDBusProxy *__bt_ag_gdbus_init_service_proxy(const gchar *service,
                return NULL;
        }
 
+       profile_gproxy = proxy;
+
        FN_END;
        return proxy;
 }
@@ -275,9 +294,39 @@ static GDBusProxy *__bt_ag_gdbus_init_service_proxy(const gchar *service,
 static GDBusProxy *__bt_ag_gdbus_get_app_proxy(const gchar *service,
                                const gchar *path, const gchar *interface)
 {
-       return (app_gproxy) ? app_gproxy :
-                       __bt_ag_gdbus_init_service_proxy(service,
-                                       path, interface);
+       FN_START;
+
+       GDBusProxy *proxy;
+       GError *err = NULL;
+
+       if (ag_dbus_conn == NULL)
+               ag_dbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+
+       if (!ag_dbus_conn) {
+               if (err) {
+                       ERR("Unable to connect to gdbus: %s", err->message);
+                       g_clear_error(&err);
+               }
+               return NULL;
+       }
+
+       DBG("%s %s %s", service, path, interface);
+
+       proxy =  g_dbus_proxy_new_sync(ag_dbus_conn,
+                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       service, path,
+                       interface, NULL, &err);
+
+       if (!proxy) {
+               if (err) {
+                       ERR("Unable to create proxy: %s", err->message);
+                       g_clear_error(&err);
+               }
+               return NULL;
+       }
+
+       FN_END;
+       return proxy;
 }
 
 static int __bt_ag_agent_gdbus_method_send(const char *service,
@@ -310,6 +359,7 @@ static int __bt_ag_agent_gdbus_method_send(const char *service,
 
                                g_clear_error(&error);
                        }
+                       g_object_unref(proxy);
                        return BT_HFP_AGENT_ERROR_INTERNAL;
                }
 
@@ -320,6 +370,8 @@ static int __bt_ag_agent_gdbus_method_send(const char *service,
                                        G_DBUS_CALL_FLAGS_NONE, 2000,
                                        NULL, NULL, NULL);
        }
+       g_object_unref(proxy);
+
        return BT_HFP_AGENT_ERROR_NONE;
 }
 
@@ -392,25 +444,24 @@ static void __bt_ag_agent_remove_watch(guint *watch_id)
 #if defined(TIZEN_SUPPORT_DUAL_HF)
 gboolean __bt_ag_agent_is_companion_device(const char *addr)
 {
-#if defined(TIZEN_PROFILE_WEARABLE)
-       char *host_device_address = NULL;
-       host_device_address = vconf_get_str(VCONF_KEY_BT_HOST_BT_MAC_ADDR);
+       if (TIZEN_PROFILE_WEARABLE) {
+               char *host_device_address = NULL;
+               host_device_address = vconf_get_str(VCONF_KEY_BT_HOST_BT_MAC_ADDR);
 
-       if (!host_device_address) {
-               INFO("Failed to get a companion device address");
-               return FALSE;
-       }
+               if (!host_device_address) {
+                       INFO("Failed to get a companion device address");
+                       return FALSE;
+               }
 
-       if (g_strcmp0(host_device_address, addr) == 0) {
-               INFO("addr[%s] is companion device", addr);
-               return TRUE;
+               if (g_strcmp0(host_device_address, addr) == 0) {
+                       INFO("addr[%s] is companion device", addr);
+                               free(host_device_address);
+                       return TRUE;
+               }
+               free(host_device_address);
+               return FALSE;
        }
-
-       return FALSE;
-#else
-       /* TODO : Need to add companion device check condition for Phone models */
        return FALSE;
-#endif
 }
 
 void __bt_convert_device_path_to_address(const gchar *device_path,
@@ -459,7 +510,7 @@ gboolean __bt_ag_agent_check_dual_hf_condition(const gchar *device_path)
        __bt_convert_device_path_to_address(device_path, device_address);
        is_companion_device = __bt_ag_agent_is_companion_device(device_address);
 
-       DBG(" device_address[%s]", device_address);
+       DBG_SECURE(" device_address[%s]", device_address);
        DBG(" is_companion_device[%d]", is_companion_device);
 
        if (__bt_ag_agent_is_companion_device_connected()) {
@@ -498,30 +549,9 @@ static gboolean __bt_get_outgoing_callapp_type(int *callapp_type)
        if (NULL == callapp_type)
                return FALSE;
 
-#if defined(TIZEN_PROFILE_WEARABLE) && defined(TIZEN_FEATURE_BT_HFP_AG)
-       *callapp_type = BT_VOICE_CALL;
-       FN_END;
-       return TRUE;
-#else
-#if 0
-       int ret;
-       ret = vconf_get_int(
-                       VCONFKEY_CISSAPPL_OUTGOING_CALL_TYPE_INT,
-                       callapp_type);
-       if (ret != 0) {
-               ERR("Failed to read  [%s]\n",
-                       VCONFKEY_CISSAPPL_OUTGOING_CALL_TYPE_INT);
-               return FALSE;
-       }
-
-       INFO(" [%s] = [%d]\n",
-               VCONFKEY_CISSAPPL_OUTGOING_CALL_TYPE_INT, *callapp_type);
-#endif
-       /* The vconf value does not include in platform. */
        *callapp_type = BT_VOICE_CALL;
        FN_END;
        return TRUE;
-#endif
 }
 
 static gboolean __bt_get_outgoing_call_condition(int *condition)
@@ -531,27 +561,9 @@ static gboolean __bt_get_outgoing_call_condition(int *condition)
        if (NULL == condition)
                return FALSE;
 
-#if defined(TIZEN_PROFILE_WEARABLE) && defined(TIZEN_FEATURE_BT_HFP_AG)
        *condition = BT_MO_ONLY_UNLOCKED;
        FN_END;
        return TRUE;
-#else
-#if 0
-       int ret;
-       ret = vconf_get_int(
-                       VCONFKEY_CISSAPPL_OUTGOING_CALL_CONDITIONS_INT,
-                       condition);
-       if (ret != 0) {
-               ERR("Failed to read  [%s]\n",
-                       VCONFKEY_CISSAPPL_OUTGOING_CALL_CONDITIONS_INT);
-               return FALSE;
-       }
-#endif
-       /* The vconf value does not include in platform. */
-       *condition = BT_MO_ONLY_UNLOCKED;
-       FN_END;
-       return TRUE;
-#endif
 }
 
 static gboolean  __bt_ag_agent_launch_call_app(const char *number)
@@ -573,23 +585,24 @@ static gboolean  __bt_ag_agent_launch_call_app(const char *number)
        if (strlen(number) != 0)
                bundle_add(b, "number", number);
 
-       aul_launch_app_async(CALL_APP_ID, b);
+       aul_launch_app_async(CALL_ALIAS_APP_ID, b);
        bundle_free(b);
 
        FN_END;
        return TRUE;
 }
 
-static void *__bt_ag_agent_launch_call_req(void *arg)
+static gboolean __bt_ag_agent_launch_call_req(void *arg)
 {
        FN_START;
        bundle *b = (bundle *)arg;
+
        if (appsvc_run_service(b, 0, NULL, NULL) < 0)
                ERR("Unable to run app svc");
        bundle_free(b);
        call_launch_requested = FALSE;
        FN_END;
-       return NULL;
+       return FALSE;
 }
 
 static gboolean __bt_ag_agent_make_call(const char *number)
@@ -598,7 +611,6 @@ static gboolean __bt_ag_agent_make_call(const char *number)
 
        char telnum[BT_MAX_TEL_NUM_STRING];
        bundle *b;
-       pthread_t thread_id;
 
        if (TIZEN_PROFILE_WEARABLE)
                return __bt_ag_agent_launch_call_app(number);
@@ -618,15 +630,7 @@ static gboolean __bt_ag_agent_make_call(const char *number)
        appsvc_add_data(b, "ctindex", "-1");
 
        call_launch_requested = TRUE;
-       if (pthread_create(&thread_id, NULL,
-                       (void *)&__bt_ag_agent_launch_call_req,
-                                       (void *)b) < 0) {
-               ERR("pthread_create() is failed");
-               call_launch_requested = FALSE;
-               return FALSE;
-       }
-       if (pthread_detach(thread_id) < 0)
-               ERR("pthread_detach() is failed");
+       g_idle_add(__bt_ag_agent_launch_call_req, b);
 
        FN_END;
        return TRUE;
@@ -729,7 +733,7 @@ bt_hfp_agent_error_t _bt_ag_agent_dial_num(const gchar *number, guint flags)
                goto fail;
        }
 
-       DBG("Number = %s", number);
+       DBG_SECURE("Number = %s", number);
        DBG("flags = %d", flags);
 
        if (!__bt_is_phone_locked(&phone_lock_state)) {
@@ -853,7 +857,7 @@ bt_hfp_agent_error_t _bt_ag_agent_dial_memory(unsigned int location)
                goto done;
        }
 
-       DBG("number %s", number);
+       DBG_SECURE("number %s", number);
 
        /*Make Voice call*/
        if (!__bt_ag_agent_make_call(number)) {
@@ -917,16 +921,17 @@ gboolean _bt_ag_agent_threeway_call(unsigned int chld_value,
        DBG("Value = %d", chld_value);
        DBG("Sender = %s", sender);
 
-#if defined(TIZEN_PROFILE_WEARABLE) && defined(TIZEN_FEATURE_BT_HFP_AG)
-       /* Check if AG supports (i.e. ag_chld_str = "0,1,2") the requested CHLD;
-       if not return FALSE */
-       if (chld_value != 0 && chld_value != 1 && chld_value != 2)
-               return FALSE;
-#else
+       if (TIZEN_PROFILE_WEARABLE) {
+               /* Check if AG supports (i.e. ag_chld_str = "0,1,2") the requested CHLD;
+               if not return FALSE */
+               if (chld_value != 0 && chld_value != 1 && chld_value != 2)
+                       return FALSE;
+       } else {
        if (chld_value != 0 && chld_value != 1 && chld_value != 2 &&
                                chld_value != 3)
                return FALSE;
-#endif
+       }
+
        _bt_ag_agent_emit_signal(ag_dbus_conn, path,
                                        BT_AG_SERVICE_NAME, "Threeway",
                                        g_variant_new("(u)", chld_value));
@@ -1154,12 +1159,14 @@ bt_hfp_agent_error_t _bt_ag_agent_vendor_cmd(const gchar *cmd,
 
 gboolean _bt_ag_agent_get_signal_quality(void *device)
 {
-       gint rssi;
+       int rssi;
+       int ret;
 
        FN_START;
-
-       if (vconf_get_int(VCONFKEY_TELEPHONY_RSSI, &rssi)) {
-               DBG("VCONFKEY_TELEPHONY_RSSI failed\n");
+       ret = tel_get_property_int(GET_TAPI_HANDLE,
+                               TAPI_PROP_NETWORK_SIGNALSTRENGTH_LEVEL, &rssi);
+       if (ret != TAPI_API_SUCCESS) {
+               ERR("Get signal status failed err = %d\n", ret);
                goto fail;
        }
 
@@ -1178,22 +1185,23 @@ fail:
 
 gboolean _bt_ag_agent_get_battery_status(void *device)
 {
-       gint battery_chrg_status;
-       gint battery_capacity;
+       bool battery_chrg_status;
+       int battery_capacity;
+       int ret;
 
        FN_START;
 
-       if (vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW,
-                                               &battery_chrg_status)) {
-               DBG("VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW failed\n");
+       ret = device_battery_is_charging(&battery_chrg_status);
+       if (ret != DEVICE_ERROR_NONE) {
+               ERR("Get battery charge status failed. Err = %d\n", ret);
                goto fail;
        }
 
        DBG("Status : %d\n", battery_chrg_status);
 
-       if (vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
-                                               &battery_capacity)) {
-               DBG("VCONFKEY_SYSMAN_BATTERY_CAPACITY failed\n");
+       ret = device_battery_get_percent(&battery_capacity);
+       if (ret != DEVICE_ERROR_NONE) {
+               ERR("Get battery capacity status failed. Err = %d\n", ret);
                goto fail;
        }
 
@@ -1212,12 +1220,14 @@ fail:
 
 gboolean _bt_ag_agent_get_operator_name(void *device)
 {
-       char *operator_name;
+       char *operator_name = NULL;
+       int ret;
        FN_START;
 
-       operator_name = vconf_get_str(VCONFKEY_TELEPHONY_NWNAME);
+       ret = tel_get_property_string(GET_TAPI_HANDLE,
+                                       TAPI_PROP_NETWORK_NETWORK_NAME, &operator_name);
        if (NULL == operator_name) {
-               DBG("vconf_get_str failed");
+               DBG("TAPI_PROP_NETWORK_NETWORK_NAME failed (%d)", ret);
                _bt_hfp_operator_reply(NULL, device);
                return FALSE;
        }
@@ -1246,7 +1256,7 @@ gboolean _bt_hfp_agent_nrec_status(gboolean status,
 
        _bt_ag_agent_emit_signal(ag_dbus_conn, hs->path,
                                        BT_AG_SERVICE_NAME, "NrecStatusChanged",
-                                       g_variant_new("(b)", status));
+                                       g_variant_new("(b)", hs->nrec_status));
        FN_END;
        return TRUE;
 }
@@ -1256,7 +1266,7 @@ gboolean _bt_ag_agent_get_imei_number(void *device)
        FN_START;
        char *imei_number;
 
-       imei_number = tel_get_misc_me_imei_sync(tapi_handle);
+       imei_number = tel_get_misc_me_imei_sync(GET_TAPI_HANDLE);
        if (NULL == imei_number) {
                ERR("tel_get_misc_me_imei_sync for imei_number failed");
                goto fail;
@@ -1311,7 +1321,7 @@ void _bt_ag_agent_get_imsi(void *device)
        FN_START;
        TelSimImsiInfo_t imsi;
        memset(&imsi, 0, sizeof(TelSimImsiInfo_t));
-       if (tel_get_sim_imsi(tapi_handle, &imsi) != TAPI_API_SUCCESS) {
+       if (tel_get_sim_imsi(GET_TAPI_HANDLE, &imsi) != TAPI_API_SUCCESS) {
                ERR("tel_get_sim_imsi failed");
                goto fail;
        }
@@ -1351,8 +1361,8 @@ void _bt_ag_agent_get_creg_status(void *device)
        int registration_status = 0;
        int roam_status = 0;
 
-       ret = tel_get_property_int(tapi_handle, TAPI_PROP_NETWORK_CIRCUIT_STATUS,
-                               &result);
+       ret = tel_get_property_int(GET_TAPI_HANDLE,
+                               TAPI_PROP_NETWORK_CIRCUIT_STATUS, &result);
        if (ret != TAPI_API_SUCCESS) {
                ERR("tel_get_property_int failed");
                return;
@@ -1364,8 +1374,9 @@ void _bt_ag_agent_get_creg_status(void *device)
        DBG_SECURE("Mapped Status %d", registration_status);
        if (registration_status ==
                        BT_AGENT_NETWORK_REG_STATUS_REGISTER_HOME_NETWORK) {
-               ret = vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &roam_status);
-               if (ret != 0) {
+               ret = tel_get_property_int(GET_TAPI_HANDLE,
+                               TAPI_PROP_NETWORK_ROAMING_STATUS, &roam_status);
+               if (ret != TAPI_API_SUCCESS) {
                        ERR("Get roaming status failed err = %d\n", ret);
                        return;
                }
@@ -1433,69 +1444,70 @@ void _bt_ag_agent_get_revision_information(void *device)
        FN_END;
 }
 
-#if defined(TIZEN_PROFILE_WEARABLE) && defined(TIZEN_FEATURE_BT_HFP_AG)
-static gboolean __bt_ag_agent_launch_voice_dial(gboolean activate)
+void _bt_ag_agent_set_last_speaker_gain(int gain)
 {
-       FN_START;
-       bundle *b;
-
-       b = bundle_create();
-       if (NULL == b) {
-               ERR("bundle_create() Failed");
-               return FALSE;
-       }
-
-       bundle_add(b, "domain", "bt_headset");
-       if (!activate)
-               bundle_add(b, "action_type", "deactivate");
-
-       aul_launch_app_async("org.tizen.svoice", b);
-       bundle_free(b);
-       FN_END;
-       return TRUE;
+       last_speaker_gain = gain;
 }
-#else
+
 static gboolean __bt_ag_agent_launch_voice_dial(gboolean activate)
 {
        FN_START;
-       app_control_h service = NULL;
+       if (TIZEN_PROFILE_WEARABLE) {
+               bundle *b;
 
-       app_control_create(&service);
+               b = bundle_create();
+               if (NULL == b) {
+                       ERR("bundle_create() Failed");
+                       return FALSE;
+               }
 
-       if (service == NULL) {
-               ERR("Service create failed");
-               return FALSE;
-       }
+               bundle_add(b, "domain", "bt_headset");
+               if (!activate)
+                       bundle_add(b, "action_type", "deactivate");
 
-       app_control_set_app_id(service, "org.tizen.svoice");
-       app_control_set_operation(service, APP_CONTROL_OPERATION_DEFAULT);
-       if (app_control_add_extra_data(service, "domain", "bt_headset")
-                                       != APP_CONTROL_ERROR_NONE) {
-               ERR("app_control_add_extra_data failed");
-               app_control_destroy(service);
-               return FALSE;
-       }
+               aul_launch_app_async("org.tizen.svoice", b);
+               bundle_free(b);
+               FN_END;
+               return TRUE;
+       } else {
+               app_control_h service = NULL;
+
+               app_control_create(&service);
+
+               if (service == NULL) {
+                       ERR("Service create failed");
+                       return FALSE;
+               }
 
-       if (!activate)
-               if (app_control_add_extra_data(service, "action_type", "deactivate")
+               app_control_set_app_id(service, "org.tizen.svoice");
+               app_control_set_operation(service, APP_CONTROL_OPERATION_DEFAULT);
+               if (app_control_add_extra_data(service, "domain", "bt_headset")
                                        != APP_CONTROL_ERROR_NONE) {
                        ERR("app_control_add_extra_data failed");
                        app_control_destroy(service);
                        return FALSE;
                }
 
-       if (app_control_send_launch_request(service, NULL, NULL) !=
+               if (!activate)
+                       if (app_control_add_extra_data(service, "action_type", "deactivate")
+                                       != APP_CONTROL_ERROR_NONE) {
+                               ERR("app_control_add_extra_data failed");
+                               app_control_destroy(service);
+                               return FALSE;
+                       }
+
+               if (app_control_send_launch_request(service, NULL, NULL) !=
                                                APP_CONTROL_ERROR_NONE) {
-               ERR("launch failed");
+                       ERR("launch failed");
+                       app_control_destroy(service);
+                       return FALSE;
+               }
+
                app_control_destroy(service);
-               return FALSE;
+               FN_END;
+               return TRUE;
        }
-
-       app_control_destroy(service);
-       FN_END;
-       return TRUE;
 }
-#endif
 
 gboolean _bt_ag_agent_voice_dial(gboolean activate)
 {
@@ -1510,6 +1522,9 @@ static void __bt_ag_codec_negotiation_info_reset(bt_ag_info_t *hs,
        hs->codec_info.is_negotiating = FALSE;
        hs->codec_info.requested_by_hf = FALSE;
        hs->codec_info.sending_codec = 0;
+       g_free(hs->codec_info.status);
+       hs->codec_info.status = NULL;
+
        if (reset) {
                hs->codec_info.remote_codecs = 0;
                hs->codec_info.final_codec = 0;
@@ -1525,27 +1540,26 @@ static void __bt_ag_codec_negotiation_info_reset(bt_ag_info_t *hs,
 
 static gboolean __bt_ag_codec_negotiation_finished(gpointer user_data)
 {
-       struct ag_codec *data = (struct ag_codec *)user_data;
+       bt_ag_info_t *hs = (bt_ag_info_t *)user_data;
 
-       if (g_strcmp0(data->codec_status, "finish") == 0) {
+       if (g_strcmp0(hs->codec_info.status, "finish") == 0) {
                DBG("Codec negotiation finished");
-               __bt_ag_sco_connect(data->bt_ag_info);
-               __bt_ag_codec_negotiation_info_reset(data->bt_ag_info, FALSE);
-               g_free(data->codec_status);
-               g_free(data);
+               __bt_ag_sco_connect(hs);
+               __bt_ag_codec_negotiation_info_reset(hs, FALSE);
                return TRUE;
-       } else if (g_strcmp0(data->codec_status, "timeout") == 0) {
-               DBG("Timeout is occured in codec negotiation");
+       } else if (g_strcmp0(hs->codec_info.status, "timeout") == 0) {
+               ERR("Timeout is occured in codec negotiation");
+               /* Codec negotiation is timedout fall back to default NB */
+               hs->codec = BT_CVSD_CODEC_ID;
+               hs->codec_info.final_codec = BT_CVSD_CODEC_ID;
        }
 
-       if (data->bt_ag_info->codec_info.requested_by_hf) {
-               __bt_ag_codec_negotiation_info_reset(data->bt_ag_info, FALSE);
+       if (hs->codec_info.requested_by_hf) {
+               __bt_ag_codec_negotiation_info_reset(hs, FALSE);
        } else {
-               __bt_ag_sco_connect(data->bt_ag_info);
-               __bt_ag_codec_negotiation_info_reset(data->bt_ag_info, FALSE);
+               __bt_ag_sco_connect(hs);
+               __bt_ag_codec_negotiation_info_reset(hs, FALSE);
        }
-       g_free(data->codec_status);
-       g_free(data);
 
        return FALSE;
 }
@@ -1584,9 +1598,11 @@ static bt_hfp_agent_error_t __bt_ag_set_codec(void *device, char *method)
 
                        g_clear_error(&err);
                }
+               g_object_unref(proxy);
                return BT_HFP_AGENT_ERROR_INTERNAL;
        }
        g_variant_unref(ret);
+       g_object_unref(proxy);
 
        return BT_HFP_AGENT_ERROR_NONE;
 }
@@ -1631,12 +1647,15 @@ static bt_hfp_agent_error_t __bt_hfp_send_bcs_command(bt_ag_info_t *hs,
                        gboolean init_by_hf)
 {
        uint32_t codec;
-       struct ag_codec *data = NULL;;
 
+#ifdef TIZEN_FEATURE_BT_SCO_WIDEBAND
        if (hs->codec_info.remote_codecs & BT_MSBC_CODEC_MASK)
                codec = BT_MSBC_CODEC_ID;
        else
                codec = BT_CVSD_CODEC_ID;
+#else
+       codec = BT_CVSD_CODEC_ID;
+#endif
 
        if (wbs_opts.wbs_enable == FALSE)
                codec = BT_CVSD_CODEC_ID;
@@ -1653,18 +1672,12 @@ static bt_hfp_agent_error_t __bt_hfp_send_bcs_command(bt_ag_info_t *hs,
        hs->codec_info.sending_codec = codec;
        hs->codec_info.requested_by_hf = init_by_hf;
        hs->codec_info.final_codec = codec;
-
-       data = g_new0(struct ag_codec, 1);
-       if (data == NULL)
-               return BT_HFP_AGENT_ERROR_NO_MEMORY;
-
-       data->bt_ag_info = hs;
-       data->codec_status = g_strdup("timeout");
+       hs->codec_info.status = g_strdup("timeout");
 
        hs->codec_info.nego_timer = g_timeout_add_seconds(
                        HFP_CODEC_NEGOTIATION_TIMEOUT,
                        (GSourceFunc)__bt_ag_codec_negotiation_finished,
-                       data);
+                       hs);
 
        return BT_HFP_AGENT_ERROR_NONE;
 }
@@ -1757,6 +1770,8 @@ static int __bt_hfp_available_codecs(bt_ag_info_t *hs, const char *buf)
                hs->codec_info.is_negotiating = FALSE;
                hs->codec_info.requested_by_hf = FALSE;
                hs->codec_info.sending_codec = 0;
+               g_free(hs->codec_info.status);
+               hs->codec_info.status = NULL;
                g_source_remove(hs->codec_info.nego_timer);
                __bt_hfp_codec_connection_setup(hs, FALSE);
        }
@@ -1787,12 +1802,13 @@ static int __bt_hfp_codec_selection(bt_ag_info_t *hs, const char *buf)
 {
        uint32_t codec = 0x00000000;
        hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
-       struct ag_codec *data = g_new0(struct ag_codec, 1);
 
        /* Timer reset */
        if (hs->codec_info.nego_timer) {
                g_source_remove(hs->codec_info.nego_timer);
                hs->codec_info.nego_timer = 0;
+               g_free(hs->codec_info.status);
+               hs->codec_info.status = NULL;
        }
 
        if (!(ag.features & BT_AG_FEATURE_CODEC_NEGOTIATION))
@@ -1803,10 +1819,9 @@ static int __bt_hfp_codec_selection(bt_ag_info_t *hs, const char *buf)
                                        BT_HFP_AGENT_ERROR_NONE)
                err = HFP_STATE_MNGR_ERR_AG_FAILURE;
 
-       data->bt_ag_info = hs;
-       data->codec_status = g_strdup("finish");
+       hs->codec_info.status = g_strdup("finish");
        _bt_ag_send_response(hs, err);
-       __bt_ag_codec_negotiation_finished(data);
+       __bt_ag_codec_negotiation_finished(hs);
 
        return 0;
 }
@@ -1836,7 +1851,7 @@ static const char *__bt_ag_state2str(hs_state_t state)
        return NULL;
 }
 
-void _bt_convert_addr_string_to_type_rev(unsigned char *addr,
+static void __bt_convert_addr_string_to_type_rev(unsigned char *addr,
                const char *address)
 {
        int i;
@@ -1900,8 +1915,16 @@ static int __bt_ag_sco_connect(bt_ag_info_t *hs)
        memset(&sco_addr, 0, sizeof(sco_addr));
        sco_addr.sco_family = AF_BLUETOOTH;
 
-       __bt_ag_str2ba(local_addr, &sco_addr.sco_bdaddr);
-       DBG("Local BD address: %s", local_addr);
+       if (local_addr) {
+               __bt_ag_str2ba(local_addr, &sco_addr.sco_bdaddr);
+               DBG_SECURE("Local BD address: %s", local_addr);
+       } else {
+               ERR("Local address is NULL");
+               ERR("Close SCO skt");
+               close(sco_skt);
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+       }
+
 
        err = bind(sco_skt, (struct sockaddr *) &sco_addr, sizeof(sco_addr));
        if (err < 0) {
@@ -1911,7 +1934,7 @@ static int __bt_ag_sco_connect(bt_ag_info_t *hs)
                return BT_HFP_AGENT_ERROR_INTERNAL;
        }
 
-       DBG("Socket FD : %d", sco_skt);
+       DBG_SECURE("Socket FD : %d", sco_skt);
 
        io = g_io_channel_unix_new(sco_skt);
        g_io_channel_set_close_on_unref(io, TRUE);
@@ -1944,11 +1967,12 @@ static int __bt_ag_sco_connect(bt_ag_info_t *hs)
        memset(&sco_addr, 0, sizeof(sco_addr));
        sco_addr.sco_family = AF_BLUETOOTH;
        __bt_ag_str2ba(hs->remote_addr, &sco_addr.sco_bdaddr);
-       DBG("remotel BD address: %s", hs->remote_addr);
+       DBG_SECURE("remotel BD address: %s", hs->remote_addr);
 
        err = connect(sco_skt, (struct sockaddr *) &sco_addr, sizeof(sco_addr));
        if (err < 0 && !(errno == EINPROGRESS || errno == EAGAIN)) {
-               ERR("ERROR: sco socket connect failed : %d", err);
+               err = -errno;
+               ERR("sco socket connect failed : %s (%d)", strerror(-err), -err);
                ERR("Close SCO skt");
                g_io_channel_unref(io);
                close(sco_skt);
@@ -2056,6 +2080,7 @@ static gboolean __bt_ag_sco_server_cb(GIOChannel *chan,
                                        BT_VOICE_NUM, &bt_vo, sizeof(bt_vo));
                if (err < 0) {
                        ERR("Sco socket set socket option failed");
+                       g_io_channel_unref(sco_io);
                        close(cli_sco_sock);
                        return FALSE;
                }
@@ -2099,8 +2124,8 @@ static int __bt_ag_start_sco_server(bt_ag_info_t *hs)
        memset(&addr, 0, sizeof(addr));
        addr.sco_family = AF_BLUETOOTH;
 
-       _bt_convert_addr_string_to_type_rev(bd_addr.b, hs->remote_addr);
-       DBG("Bind to address %s", hs->remote_addr);
+       __bt_convert_addr_string_to_type_rev(bd_addr.b, hs->remote_addr);
+       DBG_SECURE("Bind to address %s", hs->remote_addr);
        memcpy(&addr.sco_bdaddr, &bd_addr, sizeof(bdaddr_t));
 
        if (bind(sco_skt, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
@@ -2140,6 +2165,7 @@ void __bt_ag_stop_sco_server(bt_ag_info_t *hs)
                g_io_channel_unref(hs->sco_server);
                hs->sco_server = NULL;
        }
+       __bt_ag_agent_remove_watch(&hs->sco_watch_id);
        hs->sco_server_started = FALSE;
 }
 
@@ -2165,10 +2191,10 @@ static gboolean __bt_ag_sco_cb(GIOChannel *chan, GIOCondition cond,
        if (cond & G_IO_NVAL)
                return FALSE;
 
-       if (name_owner_sig_id != -1)
+       if (name_owner_sig_id)
                g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
                                        name_owner_sig_id);
-       name_owner_sig_id = -1;
+       name_owner_sig_id = 0;
        g_free(sco_owner);
        sco_owner = NULL;
 
@@ -2197,6 +2223,7 @@ void _bt_ag_set_headset_state(bt_ag_info_t *hs, hs_state_t state)
                                        BT_HEADSET_INTERFACE, "State",
                                        g_variant_new("s", hs_state));
                hs->state = state;
+               active_devices = g_slist_append(active_devices, hs);
                break;
 
        case HEADSET_STATE_CONNECTED:
@@ -2208,6 +2235,7 @@ void _bt_ag_set_headset_state(bt_ag_info_t *hs, hs_state_t state)
 
                if (hs->state < state) {
                        val = TRUE;
+                       if (!g_slist_find(active_devices, hs))
                        active_devices = g_slist_append(active_devices, hs);
                        _bt_ag_agent_emit_property_changed(ag_dbus_conn,
                                                hs->path,
@@ -2215,7 +2243,13 @@ void _bt_ag_set_headset_state(bt_ag_info_t *hs, hs_state_t state)
                                                "Connected",
                                                g_variant_new("b", val));
 
-                       DBG("Device %s connected\n", hs->remote_addr);
+                       DBG_SECURE("Device %s connected", hs->remote_addr);
+
+                       /* update remote dev path to last connected device. */
+                       if (remote_dev_path)
+                               g_free(remote_dev_path);
+                       remote_dev_path = g_strdup(hs->path);
+
 #if defined(TIZEN_SUPPORT_DUAL_HF)
                         if (!hs->is_companion_device)
                                __bt_ag_start_sco_server(hs);
@@ -2237,6 +2271,20 @@ void _bt_ag_set_headset_state(bt_ag_info_t *hs, hs_state_t state)
                break;
 
        case HEADSET_STATE_DISCONNECTED:
+               if (sco_open_timer_id > 0) {
+                       g_source_remove(sco_open_timer_id);
+                       sco_open_timer_id = 0;
+                       if (hs->invocation) {
+                               INFO("Disconnected before SCO Connection");
+                               /* Reply with error */
+                               GError *err = NULL;
+                               err = __bt_ag_agent_set_error(BT_HFP_AGENT_ERROR_NOT_CONNECTED);
+                               g_dbus_method_invocation_return_gerror(hs->invocation, err);
+                               hs->invocation = NULL;
+                               g_error_free(err);
+                       }
+               }
+
                __bt_ag_close_sco(hs);
                __bt_ag_headset_close_rfcomm(hs);
 
@@ -2272,6 +2320,7 @@ void _bt_ag_set_headset_state(bt_ag_info_t *hs, hs_state_t state)
                        __bt_ag_stop_sco_server(hs);
 
                g_free(hs->remote_addr);
+               g_free(hs->slc);
                g_free(hs);
                break;
 
@@ -2293,11 +2342,13 @@ void _bt_ag_set_headset_state(bt_ag_info_t *hs, hs_state_t state)
                                BT_HEADSET_INTERFACE, "Playing",
                                g_variant_new("b", val));
 
-               if (slconn->microphone_gain >= 0)
+               if (slconn->microphone_gain >= 0 &&
+                                       !slconn->is_voice_recognition_running)
                        _bt_ag_send_at(hs, "\r\n+VGM=%u\r\n",
                                slconn->microphone_gain);
 
-               if (slconn->speaker_gain >= 0)
+               if (slconn->speaker_gain >= 0 &&
+                                       !slconn->is_voice_recognition_running)
                        _bt_ag_send_at(hs, "\r\n+VGS=%u\r\n",
                                slconn->speaker_gain);
 
@@ -2478,10 +2529,16 @@ static int __bt_ag_send_at_valist(bt_ag_info_t *hdset, va_list list,
                }
 
                /* Synchronize the sending buffer */
+#if 0
+               /* Don't do sync call as it may block process untill all buffers are cleared
+               * On Z300F device this issue is reproduciable just connect with meacap
+               * select phonebook and call CPBR when we call CPBR multiple times it is
+               * blocking for 5 seconds.*/
                sync();
+#endif
                fsync(fd);
        } else {
-               ERR("FD is 0. remote_addr : %s", hdset->remote_addr);
+               ERR_SECURE("FD is 0. remote_addr : %s", hdset->remote_addr);
                return -1;
        }
 
@@ -2662,7 +2719,7 @@ static gboolean __bt_ag_agent_connection(gint32 fd, const gchar *device_path,
        __bt_ag_codec_negotiation_info_reset(bt_ag_info, TRUE);
 
        bt_ag_info->path = device_path;
-       DBG("device_path = [%s]", device_path);
+       DBG_SECURE("device_path = [%s]", device_path);
 
        address_len = sizeof(address);
        if (getpeername(fd, (struct sockaddr *) &address, &address_len) != 0)
@@ -2690,7 +2747,7 @@ static gboolean __bt_ag_agent_connection(gint32 fd, const gchar *device_path,
                        __bt_ag_agent_is_companion_device(bt_ag_info->remote_addr);
 #endif
 
-       DBG("remote Device Address = [%s]", bt_ag_info->remote_addr);
+       DBG_SECURE("remote Device Address = [%s]", bt_ag_info->remote_addr);
 
        if (g_strcmp0(object_path, BT_HS_AG_AGENT_OBJECT_PATH) == 0) {
                DBG("HSP connection completed");
@@ -2705,8 +2762,8 @@ static gboolean __bt_ag_agent_connection(gint32 fd, const gchar *device_path,
        __bt_ag_agent_start_watch(bt_ag_info);
 
        bt_ag_info->slc = g_new0(bt_ag_slconn_t, 1);
-       bt_ag_info->slc->speaker_gain = 15;
-       bt_ag_info->slc->microphone_gain = 15;
+       bt_ag_info->slc->speaker_gain = last_speaker_gain;
+       bt_ag_info->slc->microphone_gain = 9;
        bt_ag_info->slc->is_nrec = TRUE;
 
        return TRUE;
@@ -2801,6 +2858,9 @@ static gboolean __bt_sco_open_delay_timeout_cb(gpointer user_data)
                        }
                } else
                        __bt_ag_sco_connect(bt_ag_info);
+
+               DBG("Dbus Reply for SCO Connection request");
+               g_dbus_method_invocation_return_value(bt_ag_info->invocation, NULL);
        }
 
        return FALSE;
@@ -2946,6 +3006,7 @@ static void __bt_ag_agent_method(GDBusConnection *connection,
        int ret = BT_HFP_AGENT_ERROR_NONE;
        GError *err = NULL;
        const gchar *device_path = NULL;
+       GSList *l;
 
        if (g_strcmp0(method_name, "NewConnection") == 0) {
                gint32 fd;
@@ -2966,17 +3027,18 @@ static void __bt_ag_agent_method(GDBusConnection *connection,
 
                g_variant_get(parameters, "(oha{sv})",
                                                &device_path, &index, &options);
-
-#if defined(TIZEN_SUPPORT_DUAL_HF) && defined(TIZEN_PROFILE_WEARABLE)
-               /*
-                * Below code is not required for dual HF support for
-                * mobile devices
-                */
-               if (device_count &&
-                       __bt_ag_agent_check_dual_hf_condition(device_path) == FALSE) {
-                       INFO("not allow to connect 2nd HF connection");
-                       ret = BT_HFP_AGENT_ERROR_INTERNAL;
-                       goto fail;
+#if defined(TIZEN_SUPPORT_DUAL_HF)
+               if (TIZEN_PROFILE_WEARABLE) {
+                       /*
+                        * Below code is not required for dual HF support for
+                        * mobile devices
+                        */
+                       if (device_count &&
+                               __bt_ag_agent_check_dual_hf_condition(device_path) == FALSE) {
+                               INFO("not allow to connect 2nd HF connection");
+                               ret = BT_HFP_AGENT_ERROR_INTERNAL;
+                               goto fail;
+                       }
                }
 #endif
                msg = g_dbus_method_invocation_get_message(invocation);
@@ -2992,7 +3054,7 @@ static void __bt_ag_agent_method(GDBusConnection *connection,
                        goto fail;
                }
 
-               DBG("FD is = [%d], device_path = [%s]\n", fd, device_path);
+               DBG_SECURE("FD is = [%d], device_path = [%s]\n", fd, device_path);
 
                if (!__bt_ag_agent_connection(fd, device_path, object_path)) {
                        ret = BT_HFP_AGENT_ERROR_INTERNAL;
@@ -3001,15 +3063,14 @@ static void __bt_ag_agent_method(GDBusConnection *connection,
 
                g_dbus_method_invocation_return_value(invocation, NULL);
        } else if (g_strcmp0(method_name, "RequestDisconnection") == 0) {
-               GSList *l;
 
                g_variant_get(parameters, "(o)", &device_path);
-               INFO("device_path %s", device_path);
+               INFO_SECURE("device_path %s", device_path);
 
                for (l = active_devices; l; l = l->next) {
                        bt_ag_info_t *data = l->data;
 
-                       INFO("data->path %s", data->path);
+                       INFO_SECURE("data->path %s", data->path);
                        if (g_strcmp0(data->path, device_path) == 0) {
                                if (!__bt_ag_agent_connection_release(data)) {
                                        ret = BT_HFP_AGENT_ERROR_INTERNAL;
@@ -3019,6 +3080,30 @@ static void __bt_ag_agent_method(GDBusConnection *connection,
                                g_dbus_method_invocation_return_value(invocation, NULL);
                        }
                }
+       } else if (g_strcmp0(method_name, "ReplyAuthorize") == 0) {
+               const guint accept;
+               bt_ag_info_t *data;
+               g_variant_get(parameters, "(u)", &accept);
+               INFO("Accept: %d", accept);
+
+               l = active_devices;
+               data = l->data;
+               INFO_SECURE("data->path %s", data->path);
+               data->pbap_trusted = accept;
+
+               _bt_hfp_select_phonebook_memory_status_reply(data);
+
+               INFO("pbap_trusted %d", data->pbap_trusted);
+
+               if (data->pbap_trusted == BT_AG_FEATURE_PBAP_ALLOWED) {
+                       /* Allow Access update this to bluez */
+                       bt_device_set_profile_trusted(data->remote_addr,
+                               1, TRUE);
+               } else if (data->pbap_trusted == BT_AG_FEATURE_PBAP_BLOCKED) {
+                       /* Blocked Access update this to bluez */
+                       bt_device_set_profile_trusted(data->remote_addr,
+                               1, FALSE);
+               }
        } else if (g_strcmp0(method_name, "RegisterApplication") == 0) {
                gchar *path = NULL;
                gchar *address = NULL;
@@ -3033,7 +3118,7 @@ static void __bt_ag_agent_method(GDBusConnection *connection,
 
                g_free(local_addr);
                local_addr = g_strdup(address);
-               DBG("Address = %s\n", local_addr);
+               DBG_SECURE("Address = %s\n", local_addr);
                g_dbus_method_invocation_return_value(invocation, NULL);
        } else if (g_strcmp0(method_name, "UnregisterApplication") == 0) {
                gchar *path = NULL;
@@ -3142,7 +3227,6 @@ static void __bt_ag_agent_method(GDBusConnection *connection,
                }
        } else if (g_strcmp0(method_name, "Disconnect") == 0) {
                char hdset_address[18] = { 0, };
-               GSList *l;
 
                for (l = active_devices; l; l = l->next) {
                        bt_ag_info_t *data = l->data;
@@ -3150,7 +3234,7 @@ static void __bt_ag_agent_method(GDBusConnection *connection,
                        __bt_convert_addr_type_to_rev_string(hdset_address,
                                        (unsigned char *)data->remote_addr);
 
-                       DBG("Disconnect Headset %s, %s\n",
+                       DBG_SECURE("Disconnect Headset %s, %s\n",
                                                hdset_address, data->path);
                        _bt_ag_set_headset_state(data,
                                                HEADSET_STATE_DISCONNECTED);
@@ -3158,12 +3242,11 @@ static void __bt_ag_agent_method(GDBusConnection *connection,
                g_dbus_method_invocation_return_value(invocation, NULL);
        } else if (g_strcmp0(method_name, "IsConnected") == 0) {
                gboolean is_connected = FALSE;
-               GSList *l;
 
                for (l = active_devices; l; l = l->next) {
                        bt_ag_info_t *data = l->data;
 
-                       if (data->state == HEADSET_STATE_CONNECTED)
+                       if (data->state >= HEADSET_STATE_CONNECTED)
                                is_connected = TRUE;
                }
                DBG("is_connected : %s",
@@ -3172,7 +3255,6 @@ static void __bt_ag_agent_method(GDBusConnection *connection,
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(b)", is_connected));
        } else if (g_strcmp0(method_name, "IndicateCall") == 0) {
-               GSList *l;
 
                if (0 == g_slist_length(active_devices)) {
                        ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
@@ -3248,6 +3330,10 @@ static void __bt_ag_agent_method(GDBusConnection *connection,
                        ERR("Play In Progress");
                        ret = BT_HFP_AGENT_ERROR_BUSY;
                        break;
+               case HEADSET_STATE_ON_CALL:
+                       ERR("SCO is already established");
+                       ret = BT_HFP_AGENT_ERROR_ALREADY_CONNECTED;
+                       break;
                default:
                        break;
                }
@@ -3257,7 +3343,7 @@ static void __bt_ag_agent_method(GDBusConnection *connection,
                if (sco_open_timer_id > 0) {
                        INFO("SCO open delay");
                        sco_open_request = TRUE;
-                       g_dbus_method_invocation_return_value(invocation, NULL);
+                       bt_ag_info->invocation = invocation;
                        return;
                }
 
@@ -3288,11 +3374,11 @@ static void __bt_ag_agent_method(GDBusConnection *connection,
 
                g_dbus_method_invocation_return_value(invocation, NULL);
 
-               name_owner_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn,
+               if (name_owner_sig_id == 0)
+                       name_owner_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn,
                                        NULL, NULL, "NameOwnerChanged", NULL, NULL, 0,
                                        __bt_ag_name_owner_changed_cb, NULL, NULL);
        } else if (g_strcmp0(method_name, "Stop") == 0) {
-               GSList *l;
 
                for (l = active_devices; l; l = l->next) {
                        bt_ag_info_t *data = l->data;
@@ -3307,7 +3393,6 @@ static void __bt_ag_agent_method(GDBusConnection *connection,
                g_dbus_method_invocation_return_value(invocation, NULL);
        } else if (g_strcmp0(method_name, "IsPlaying") == 0) {
                gboolean is_playing = FALSE;
-               GSList *l;
 
                for (l = active_devices; l; l = l->next) {
                        bt_ag_info_t *data = l->data;
@@ -3324,12 +3409,8 @@ static void __bt_ag_agent_method(GDBusConnection *connection,
                guint16 gain_value = 0;
                bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path);
 
-               if (bt_ag_info == NULL) {
-                       ret = BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
-                       goto fail;
-               }
-
-               if (bt_ag_info->state < HEADSET_STATE_CONNECTED) {
+               if (bt_ag_info == NULL ||
+                       bt_ag_info->state < HEADSET_STATE_CONNECTED) {
                        ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
                        goto fail;
                }
@@ -3343,15 +3424,15 @@ static void __bt_ag_agent_method(GDBusConnection *connection,
        } else if (g_strcmp0(method_name, "SetSpeakerGain") == 0) {
                guint16 gain = 0;
                bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path);
+               if (bt_ag_info == NULL ||
+                       bt_ag_info->state < HEADSET_STATE_CONNECTED) {
+                       ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
+                       goto fail;
+               }
 
                g_variant_get(parameters, "(q)", &gain);
                DBG("Speaker gain = %d\n", gain);
 
-               if (bt_ag_info == NULL) {
-                       ret = BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
-                       goto fail;
-               }
-
                ret = _bt_hfp_set_speaker_gain(bt_ag_info, gain);
                if (ret)
                        goto fail;
@@ -3361,8 +3442,9 @@ static void __bt_ag_agent_method(GDBusConnection *connection,
                guint16 gain_value = 0;
                bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path);
 
-               if (bt_ag_info == NULL) {
-                       ret = BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
+               if (bt_ag_info == NULL ||
+                       bt_ag_info->state < HEADSET_STATE_CONNECTED) {
+                       ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
                        goto fail;
                }
 
@@ -3380,23 +3462,24 @@ static void __bt_ag_agent_method(GDBusConnection *connection,
        } else if (g_strcmp0(method_name, "SetMicrophoneGain") == 0) {
                guint16 gain = 0;
                bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path);
+               if (bt_ag_info == NULL ||
+                       bt_ag_info->state < HEADSET_STATE_CONNECTED) {
+                       ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
+                       goto fail;
+               }
 
                g_variant_get(parameters, "(q)", &gain);
                DBG("Microphone gain = %d\n", gain);
 
-               if (bt_ag_info == NULL) {
-                       ret = BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
-                       goto fail;
-               }
-
                ret = _bt_hfp_set_microphone_gain(bt_ag_info, gain);
                if (ret)
                        goto fail;
                g_dbus_method_invocation_return_value(invocation, NULL);
        } else if (g_strcmp0(method_name, "SetVoiceDial") == 0) {
                bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path);
-               if (bt_ag_info == NULL) {
-                       ret = BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
+               if (bt_ag_info == NULL ||
+                       bt_ag_info->state < HEADSET_STATE_CONNECTED) {
+                       ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
                        goto fail;
                }
 
@@ -3423,8 +3506,9 @@ static void __bt_ag_agent_method(GDBusConnection *connection,
        } else if (g_strcmp0(method_name, "SendVendorAtCmd") == 0) {
                gchar *cmd;
                bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path);
-               if (bt_ag_info == NULL) {
-                       ret = BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
+               if (bt_ag_info == NULL ||
+                       bt_ag_info->state < HEADSET_STATE_CONNECTED) {
+                       ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
                        goto fail;
                }
 
@@ -3643,12 +3727,10 @@ static void __bt_ag_unregister_profile_methods(void)
        }
 }
 
-static GDBusProxy *__bt_ag_gdbus_get_service_proxy(const gchar *service,
-                               const gchar *path, const gchar *interface)
+static GDBusProxy *__bt_ag_gdbus_get_profile_proxy(void)
 {
-       return (service_gproxy) ? service_gproxy :
-                       __bt_ag_gdbus_init_service_proxy(service,
-                                       path, interface);
+       return (profile_gproxy) ? profile_gproxy :
+                                 __bt_ag_gdbus_init_profile_proxy();
 }
 
 static void __bt_ag_agent_register(gchar *path, uint16_t profile_version,
@@ -3660,12 +3742,10 @@ static void __bt_ag_agent_register(gchar *path, uint16_t profile_version,
        GError *error = NULL;
        GVariantBuilder *builder;
 
-       proxy = __bt_ag_gdbus_get_service_proxy(BLUEZ_SERVICE_NAME,
-               "/org/bluez", BLUEZ_PROFILE_MGMT_INTERFACE);
+       proxy = __bt_ag_gdbus_get_profile_proxy();
        if (proxy == NULL)
                return;
 
-
        builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
 
        g_variant_builder_add(builder, "{sv}",
@@ -3715,15 +3795,13 @@ static void __bt_ag_agent_unregister(gchar *path)
        GVariant *ret;
        GError *error = NULL;
 
-       proxy = __bt_ag_gdbus_get_service_proxy(BLUEZ_SERVICE_NAME,
-               "/org/bluez", BLUEZ_PROFILE_MGMT_INTERFACE);
+       proxy = __bt_ag_gdbus_get_profile_proxy();
        if (proxy == NULL)
                return;
 
-
        ret = g_dbus_proxy_call_sync(proxy, "UnregisterProfile",
                                        g_variant_new("(o)", path),
-                                       G_DBUS_CALL_FLAGS_NONE, -1,
+                                       G_DBUS_CALL_FLAGS_NONE, 100,
                                        NULL, &error);
        g_free(path);
        /* set the name and role for the profile*/
@@ -3750,19 +3828,23 @@ static void __bt_ag_agent_unregister(gchar *path)
        return;
 }
 
-static void __bt_ag_agent_battery_status_cb(keynode_t *node)
+static void __bt_ag_agent_battery_status_cb(device_callback_e type,
+                                               void *value, void *user_data)
 {
-       int batt = vconf_keynode_get_int(node);
-
-       _bt_hfp_set_property_value("BatteryBarsChanged", batt);
+       int batt_cap;
+       if (type == DEVICE_CALLBACK_BATTERY_CAPACITY) {
+               device_battery_get_percent(&batt_cap);
+               _bt_hfp_set_property_value("BatteryBarsChanged", batt_cap);
+       }
 }
 
-static void __bt_ag_agent_network_signal_status_cb(keynode_t *node)
+static void __bt_ag_agent_network_signal_status_cb(TapiHandle *handle,
+               const char *noti_id, void *data, void *user_data)
 {
-       int signal_bar = vconf_keynode_get_int(node);
+       int *signal_bar = data;
 
-       BT_CHECK_SIGNAL_STRENGTH(signal_bar);
-       _bt_hfp_set_property_value("SignalBarsChanged", signal_bar);
+       BT_CHECK_SIGNAL_STRENGTH(*signal_bar);
+       _bt_hfp_set_property_value("SignalBarsChanged", *signal_bar);
 }
 
 static void __bt_ag_agent_lunar_connection_status_cb(keynode_t *node)
@@ -3779,19 +3861,73 @@ static void __bt_ag_agent_lunar_connection_status_cb(keynode_t *node)
        }
 }
 
-static void __bt_ag_agent_network_register_status_cb(keynode_t *node)
+static void __bt_ag_agent_call_preferred_voice_subscription_cb(TapiHandle *handle,
+               const char *noti_id, void *data, void *user_data)
+{
+       TelCallPreferredVoiceSubsNoti_t *noti_data = (TelCallPreferredVoiceSubsNoti_t *)data;
+       uint32_t ag_features;
+       int tapi_result;
+       if (!noti_data) {
+               ERR("Error happen during voice subscription data noti");
+               return;
+       }
+
+       INFO("TAPI_NOTI_CALL_PREFERRED_VOICE_SUBSCRIPTION = Value %d",
+                                               noti_data->preferred_subs);
+       ag_features = __bt_ag_agent_get_ag_features();
+       switch (noti_data->preferred_subs) {
+       case TAPI_CALL_PREFERRED_VOICE_SUBS_SIM1:
+       case TAPI_CALL_PREFERRED_VOICE_SUBS_ASK_ALWAYS:
+               if (tapi_handle_preferred_sim == tapi_handle[0]) {
+                       INFO("No handler change. Preferred sim is same as SIM1");
+                       break;
+               }
+               __bt_ag_agent_unsubscribe_tapi_updates(tapi_handle_preferred_sim);
+               tapi_handle_preferred_sim = tapi_handle[0];
+               _bt_hfp_initialize_telephony_manager(ag_features, tapi_handle_preferred_sim);
+               __bt_ag_agent_subscribe_tapi_updates(tapi_handle_preferred_sim);
+               tapi_result = tel_get_sim_msisdn(GET_TAPI_HANDLE, __bt_ag_agent_tel_cb, NULL);
+               if (tapi_result != TAPI_API_SUCCESS)
+                       ERR("Fail to get sim info: %d", tapi_result);
+               break;
+       case TAPI_CALL_PREFERRED_VOICE_SUBS_SIM2:
+               if (tapi_handle_preferred_sim == tapi_handle[1]) {
+                       INFO("No handler change. Preferred sim is same as SIM2");
+                       break;
+               }
+               __bt_ag_agent_unsubscribe_tapi_updates(tapi_handle_preferred_sim);
+               tapi_handle_preferred_sim = tapi_handle[1];
+               _bt_hfp_initialize_telephony_manager(ag_features, tapi_handle_preferred_sim);
+               __bt_ag_agent_subscribe_tapi_updates(tapi_handle_preferred_sim);
+               tapi_result = tel_get_sim_msisdn(GET_TAPI_HANDLE, __bt_ag_agent_tel_cb, NULL);
+               if (tapi_result != TAPI_API_SUCCESS)
+                       ERR("Fail to get sim info: %d", tapi_result);
+
+               break;
+
+       case TAPI_CALL_PREFERRED_VOICE_SUBS_CURRENT_NETWORK:
+       case TAPI_CALL_PREFERRED_VOICE_SUBS_UNKNOWN:
+       default:
+               break;
+       }
+}
+
+static void __bt_ag_agent_network_register_status_cb(TapiHandle *handle,
+               const char *noti_id, void *data, void *user_data)
 {
-       int service = vconf_keynode_get_int(node);
+       int service;
        bt_hfp_agent_network_registration_status_t network_service;
        int roam_status;
        int ret;
 
-       DBG("Current Signal Level = [%d] \n", service);
+       int *service_type = data;
 
-       switch (service) {
-       case VCONFKEY_TELEPHONY_SVCTYPE_NONE:
-       case VCONFKEY_TELEPHONY_SVCTYPE_NOSVC:
-       case VCONFKEY_TELEPHONY_SVCTYPE_SEARCH:
+       DBG("Network service type changed = [%d]", *service_type);
+
+       switch (*service_type) {
+       case TAPI_NETWORK_SERVICE_TYPE_UNKNOWN:
+       case TAPI_NETWORK_SERVICE_TYPE_NO_SERVICE:
+       case TAPI_NETWORK_SERVICE_TYPE_SEARCH:
                service = 0;
                break;
        default:
@@ -3799,8 +3935,9 @@ static void __bt_ag_agent_network_register_status_cb(keynode_t *node)
                break;
        }
 
-       ret = vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &roam_status);
-       if (ret != 0) {
+       ret = tel_get_property_int(GET_TAPI_HANDLE,
+                       TAPI_PROP_NETWORK_ROAMING_STATUS, &roam_status);
+       if (ret != TAPI_API_SUCCESS) {
                ERR("Get roaming status failed err = %d\n", ret);
                return;
        }
@@ -3820,21 +3957,11 @@ static void __bt_ag_agent_subscribe_vconf_updates(void)
        int ret;
 
        DBG("\n");
-
-       ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
-                               (void *)__bt_ag_agent_battery_status_cb, NULL);
-       if (0 != ret)
-               ERR("Subsrciption to battery status failed err =  [%d]\n", ret);
-
-       ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_RSSI,
-                       (void *)__bt_ag_agent_network_signal_status_cb, NULL);
-       if (0 != ret)
-               ERR("Subsrciption to netowrk signal failed err =  [%d]\n", ret);
-
-       ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_SVCTYPE,
-                       (void *)__bt_ag_agent_network_register_status_cb, NULL);
-       if (0 != ret)
-               ERR("Subsrciption to network failed err =  [%d]\n", ret);
+       ret = device_add_callback(DEVICE_CALLBACK_BATTERY_CAPACITY,
+                               __bt_ag_agent_battery_status_cb, NULL);
+       if (ret != DEVICE_ERROR_NONE) {
+               ERR("Subscription to battery status failed err =  [%d]\n", ret);
+       }
 
        if (TIZEN_PROFILE_WEARABLE) {
                ret = vconf_notify_key_changed(VCONF_KEY_BT_LUNAR_ENABLED,
@@ -3849,21 +3976,18 @@ static void __bt_ag_agent_release_vconf_updates(void)
        int ret;
 
        DBG("\n");
+       ret = device_remove_callback(DEVICE_CALLBACK_BATTERY_CAPACITY,
+                                       __bt_ag_agent_battery_status_cb);
+       if (ret != DEVICE_ERROR_NONE) {
+               ERR("Unsubscription to battery status failed err =  [%d]\n", ret);
+       }
 
-       ret = vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
-                       (vconf_callback_fn)__bt_ag_agent_battery_status_cb);
-       if (0 != ret)
-               ERR("vconf_ignore_key_changed failed\n");
-
-       ret = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_RSSI,
-               (vconf_callback_fn)__bt_ag_agent_network_signal_status_cb);
-       if (0 != ret)
-               ERR("vconf_ignore_key_changed failed\n");
-
-       ret = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_SVCTYPE,
-               (vconf_callback_fn)__bt_ag_agent_network_register_status_cb);
-       if (0 != ret)
-               ERR("vconf_ignore_key_changed failed\n");
+       if (TIZEN_PROFILE_WEARABLE) {
+               ret = vconf_ignore_key_changed(VCONF_KEY_BT_LUNAR_ENABLED,
+                               (void *)__bt_ag_agent_lunar_connection_status_cb);
+               if (0 != ret)
+                       ERR("Subsrciption to lunar connection failed err =  [%d]\n", ret);
+       }
 }
 
 static gboolean __bt_ag_agent_send_subscriber_number_changed(
@@ -3873,7 +3997,7 @@ static gboolean __bt_ag_agent_send_subscriber_number_changed(
 
        FN_START;
 
-       DBG("Number is %s", number);
+       DBG_SECURE("Number is %s", number);
 
        if (!_bt_hfp_set_property_name(property, number)) {
                DBG("Error- set property for subscriber no change  - ERROR\n");
@@ -3925,7 +4049,15 @@ static void  __bt_ag_agent_tel_cb(TapiHandle *handle,
        TelSimMsisdnList_t *number;
        gchar *subscriber_number;
 
-       ERR("*********** result = %d", result);
+       ERR("*********** Result =%d **********", result);
+
+       if (result == TAPI_ERROR_OPERATION_FAILED ||
+                       result == TAPI_ERROR_ACCESS_DENIED ||
+                               result == TAPI_ERROR_OPERATION_NOT_SUPPORTED) {
+               ERR("SIM has limited capabilities");
+               __bt_ag_agent_send_subscriber_number_changed("");
+               return;
+       }
 
        if (result == TAPI_API_SIM_LOCKED ||
                result == TAPI_API_SIM_NOT_INITIALIZED ||
@@ -4004,10 +4136,10 @@ static void __bt_ag_name_owner_changed_cb(GDBusConnection *connection,
                        return;
 
                if (strcasecmp(name_owner, sco_owner) == 0) {
-                       if (name_owner_sig_id != -1)
+                       if (name_owner_sig_id)
                                g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
                                                        name_owner_sig_id);
-                       name_owner_sig_id = -1;
+                       name_owner_sig_id = 0;
                        g_free(sco_owner);
                        sco_owner = NULL;
 
@@ -4024,7 +4156,7 @@ static void __bt_ag_name_owner_changed_cb(GDBusConnection *connection,
        }
 }
 
-static void __bt_ag_agent_filter_cb(GDBusConnection *connection,
+static void __bt_ag_agent_bluez_interface_signal_cb(GDBusConnection *connection,
                                        const gchar *sender_name,
                                        const gchar *object_path,
                                        const gchar *interface_name,
@@ -4047,7 +4179,7 @@ static void __bt_ag_agent_filter_cb(GDBusConnection *connection,
                        return;
                }
 
-               INFO("Adapter Path = [%s]", path);
+               INFO_SECURE("Adapter Path = [%s]", path);
                if (strcasecmp(path, DEFAULT_ADAPTER_OBJECT_PATH) == 0) {
                        gchar *path = g_strdup(BT_AG_AGENT_OBJECT_PATH);
                        __bt_ag_agent_register(path, hfp_ver,
@@ -4066,7 +4198,7 @@ static void __bt_ag_agent_filter_cb(GDBusConnection *connection,
                        return;
                }
 
-               INFO("Adapter Path = [%s]", path);
+               INFO_SECURE("Adapter Path = [%s]", path);
                if (strcasecmp(path, DEFAULT_ADAPTER_OBJECT_PATH) == 0) {
                        gchar *path = g_strdup(BT_AG_AGENT_OBJECT_PATH);
                        __bt_ag_agent_unregister(path);
@@ -4082,17 +4214,63 @@ static void __bt_ag_agent_filter_cb(GDBusConnection *connection,
        FN_END;
 }
 
-static void __bt_ag_agent_dbus_deinit(void)
+static void __bt_ag_agent_bluez_property_changed_cb(GDBusConnection *connection,
+                                       const gchar *sender_name,
+                                       const gchar *object_path,
+                                       const gchar *interface_name,
+                                       const gchar *signal_name,
+                                       GVariant *parameters,
+                                       gpointer user_data)
 {
+       GVariant *optional_param = NULL;
+       char *inter = NULL;
+       GVariant *dict_param = NULL;
 
-       if (service_gproxy) {
-               g_object_unref(service_gproxy);
-               service_gproxy = NULL;
+       if (strcasecmp(signal_name, BT_PROPERTY_CHANGED) == 0) {
+               if (g_strcmp0(g_variant_get_type_string(parameters),
+                       "(sa{sv}as)")) {
+                       ERR("Incorrect parameters\n");
+                       return;
+               }
+               g_variant_get(parameters, "(&s@a{sv}@as)",
+                               &inter, &dict_param, &optional_param);
+               if (strcasecmp(inter, BLUEZ_DEVICE_INTERFACE) == 0) {
+                       GVariantDict dict;
+                       int trusted = 0;
+                       g_variant_dict_init(&dict, dict_param);
+                       if (g_variant_dict_lookup(
+                               &dict, "TrustedProfiles", "u", &trusted)) {
+                               GSList *l;
+                               for (l = active_devices ; l; l = l->next) {
+                                       bt_ag_info_t *data = l->data;
+                                       if (g_strcmp0(data->path, object_path) != 0)
+                                               continue;
+                                       if (trusted == BT_PROFILE_SUPPORTED_TRUSTED) {
+                                               data->pbap_trusted =
+                                                       BT_AG_FEATURE_PBAP_ALLOWED;
+                                               DBG("[%s] PBAP is TRUSTED", object_path);
+                                       } else if (trusted == BT_PROFILE_SUPPORTED_BLOCKED) {
+                                               data->pbap_trusted =
+                                                       BT_AG_FEATURE_PBAP_BLOCKED;
+                                               DBG("[%s] PBAP is BLOCKED", object_path);
+                                       }
+                               }
+                       }
+                       g_variant_dict_end(&dict);
+               }
+               if (dict_param)
+                       g_variant_unref(dict_param);
        }
 
-       if (app_gproxy) {
-               g_object_unref(app_gproxy);
-               app_gproxy = NULL;
+       if (optional_param)
+               g_variant_unref(optional_param);
+}
+
+static void __bt_ag_agent_dbus_deinit(void)
+{
+       if (profile_gproxy) {
+               g_object_unref(profile_gproxy);
+               profile_gproxy = NULL;
        }
 
        if (ag_dbus_conn) {
@@ -4106,6 +4284,10 @@ static void __bt_ag_agent_dbus_deinit(void)
                        g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
                                                interface_removed_sig_id);
 
+               if (proterty_changed_sig_id)
+                       g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
+                                               proterty_changed_sig_id);
+
                if (name_owner_sig_id)
                        g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
                                                name_owner_sig_id);
@@ -4113,16 +4295,17 @@ static void __bt_ag_agent_dbus_deinit(void)
                if (media_sig_id)
                        g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
                                                media_sig_id);
-               media_sig_id = 0;
 
-               if (media_state_sig_id)
-                       g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
-                                               media_state_sig_id);
-               media_state_sig_id = 0;
+               media_sig_id = 0;
 #endif
+               if (device_property_id)
+                       g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
+                                               device_property_id);
 
+               device_property_id = 0;
                interface_added_sig_id = 0;
                interface_removed_sig_id = 0;
+               proterty_changed_sig_id = 0;
                name_owner_sig_id = 0;
                g_free(sco_owner);
                sco_owner = NULL;
@@ -4130,7 +4313,6 @@ static void __bt_ag_agent_dbus_deinit(void)
                g_object_unref(ag_dbus_conn);
                ag_dbus_conn = NULL;
        }
-       return;
 }
 
 static int __bt_ag_agent_get_adapter_path(GDBusConnection *conn, char *path)
@@ -4228,6 +4410,7 @@ void _bt_ag_agent_check_transport_state(void)
                                        G_DBUS_CALL_FLAGS_NONE, 2000,
                                        NULL, NULL, NULL);
                transport_state = MEDIA_TRANSPORT_STATE_IDLE;
+               g_object_unref(proxy);
        }
 
        FN_END;
@@ -4258,7 +4441,7 @@ static void __bt_ag_agent_media_filter_cb(GDBusConnection *connection,
        char *inter = NULL;
        GVariant *dict_param = NULL;
        GVariant *optional_param = NULL;
-
+       GSList *l;
        if (strcasecmp(signal_name, "PropertiesChanged") == 0) {
                if (g_strcmp0(g_variant_get_type_string(parameters),
                                                        "(sa{sv}as)")) {
@@ -4273,7 +4456,7 @@ static void __bt_ag_agent_media_filter_cb(GDBusConnection *connection,
                        GVariantIter *iter = NULL;
                        const gchar *key = NULL;
                        GVariant *value_var = NULL;
-                       gchar *value = NULL;
+                       const gchar *value = NULL;
                        g_variant_get(dict_param, "a{sv}", &iter);
                        while (g_variant_iter_loop(
                                        iter, "{sv}", &key, &value_var)) {
@@ -4337,12 +4520,17 @@ static void __bt_ag_agent_dbus_init(void)
        interface_added_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn,
                                NULL, BT_MANAGER_INTERFACE,
                                BT_INTERFACES_ADDED, NULL, NULL, 0,
-                               __bt_ag_agent_filter_cb, NULL, NULL);
+                               __bt_ag_agent_bluez_interface_signal_cb, NULL, NULL);
 
        interface_removed_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn,
                                NULL, BT_MANAGER_INTERFACE,
                                BT_INTERFACES_REMOVED, NULL, NULL, 0,
-                               __bt_ag_agent_filter_cb, NULL, NULL);
+                               __bt_ag_agent_bluez_interface_signal_cb, NULL, NULL);
+
+       proterty_changed_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn,
+                               NULL, BT_MANAGER_INTERFACE,
+                               BT_PROPERTY_CHANGED, NULL, NULL, 0,
+                               __bt_ag_agent_bluez_property_changed_cb, NULL, NULL);
 
 #ifdef TIZEN_FEATURE_BT_MEDIA_ENHANCE
        media_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn,
@@ -4357,10 +4545,62 @@ static void __bt_ag_agent_dbus_init(void)
 
        transport_state = MEDIA_TRANSPORT_STATE_DISCONNECTED;
 #endif
+       device_property_id = g_dbus_connection_signal_subscribe(ag_dbus_conn,
+                               NULL, BT_PROPERTIES_INTERFACE, BT_PROPERTY_CHANGED, NULL,
+                               NULL, 0, __bt_ag_agent_bluez_property_changed_cb,
+                               NULL, NULL);
        FN_END;
        return;
 }
 
+static void __bt_ag_agent_subscribe_tapi_updates(TapiHandle *handle)
+{
+       int ret;
+
+       DBG("\nSubscribe tapi update for handler %p", handle);
+
+       ret = tel_register_noti_event(handle, TAPI_PROP_NETWORK_SIGNALSTRENGTH_LEVEL,
+               __bt_ag_agent_network_signal_status_cb, NULL);
+       if (ret != TAPI_API_SUCCESS) {
+               ERR("Subsrciption to netowrk signal failed err =  [%d]\n", ret);
+       }
+
+       ret = tel_register_noti_event(handle, TAPI_PROP_NETWORK_SERVICE_TYPE,
+               __bt_ag_agent_network_register_status_cb, NULL);
+       if (ret != TAPI_API_SUCCESS) {
+               ERR("Subsrciption to network failed err =  [%d]\n", ret);
+       }
+
+       ret = tel_register_noti_event(handle, TAPI_NOTI_CALL_PREFERRED_VOICE_SUBSCRIPTION,
+               __bt_ag_agent_call_preferred_voice_subscription_cb, NULL);
+       if (ret != TAPI_API_SUCCESS) {
+               ERR("Subsrciption to preferred voice err =  [%d]\n", ret);
+       }
+
+}
+
+static void __bt_ag_agent_unsubscribe_tapi_updates(TapiHandle *handle)
+{
+       int ret;
+
+       DBG("\nUnsubscribe tapi update for handler %p", handle);
+
+       ret = tel_deregister_noti_event(handle, TAPI_PROP_NETWORK_SIGNALSTRENGTH_LEVEL);
+       if (ret != TAPI_API_SUCCESS) {
+               ERR("Subsrciption to netowrk signal failed err =  [%d]\n", ret);
+       }
+
+       ret = tel_deregister_noti_event(handle, TAPI_PROP_NETWORK_SERVICE_TYPE);
+       if (ret != TAPI_API_SUCCESS) {
+               ERR("Subsrciption to network failed err =  [%d]\n", ret);
+       }
+
+       ret = tel_deregister_noti_event(handle, TAPI_NOTI_CALL_PREFERRED_VOICE_SUBSCRIPTION);
+       if (ret != TAPI_API_SUCCESS) {
+               ERR("Subsrciption to preferred voice err =  [%d]\n", ret);
+       }
+}
+
 static uint32_t __bt_ag_agent_get_ag_features(void)
 {
 
@@ -4368,15 +4608,18 @@ static uint32_t __bt_ag_agent_get_ag_features(void)
                                BT_AG_FEATURE_REJECT_CALL |
                                BT_AG_FEATURE_ENHANCED_CALL_STATUS |
                                BT_AG_FEATURE_THREE_WAY_CALL |
+#if !defined(TIZEN_FEATURE_BT_VENDOR_SPRD)
                                BT_AG_FEATURE_VOICE_RECOGNITION |
+#endif
                                BT_AG_FEATURE_EXTENDED_ERROR_RESULT_CODES;
 
+#ifdef TIZEN_FEATURE_BT_SCO_WIDEBAND
        wbs_en = TRUE;
-#if defined(TIZEN_FEATURE_BT_HFP_AG)
-       hfp_ver = HFP_VERSION_1_7;
 #else
-       hfp_ver = HFP_VERSION_1_5;
+       wbs_en = FALSE;
 #endif
+
+       hfp_ver = HFP_VERSION_1_7;
        hsp_ver = HSP_VERSION_1_2;
 
        if (hfp_ver > HFP_VERSION_1_5)
@@ -4387,23 +4630,120 @@ static uint32_t __bt_ag_agent_get_ag_features(void)
        return ag_features;
 }
 
-void *__bt_ag_agent_telephony_init(void *arg)
+static void __bt_ag_agent_tel_get_preferred_sim(TapiHandle *handler)
 {
+       TelCallPreferredVoiceSubs_t preferredSubscription;
+       int err_code = tel_get_call_preferred_voice_subscription(handler, &preferredSubscription);
+       if (err_code == TAPI_API_SUCCESS) {
+               if (preferredSubscription == TAPI_CALL_PREFERRED_VOICE_SUBS_SIM1) {
+                       tapi_handle_preferred_sim = tapi_handle[0];
+                       INFO("Preferred SIM 1");
+               } else if (preferredSubscription == TAPI_CALL_PREFERRED_VOICE_SUBS_SIM2) {
+                       tapi_handle_preferred_sim = tapi_handle[1];
+                       INFO("Preferred SIM 2");
+               } else if (preferredSubscription == TAPI_CALL_PREFERRED_VOICE_SUBS_CURRENT_NETWORK) {
+                       INFO("Preferred SIM Current Network");
+               } else if (preferredSubscription == TAPI_CALL_PREFERRED_VOICE_SUBS_ASK_ALWAYS) {
+                       tapi_handle_preferred_sim = tapi_handle[0];
+                       INFO("Preferred SIM Always Ask");
+               } else {
+                       ERR("Unknown Preferred voice subscription");
+               }
+       }
+}
+
+static void __bt_ag_agent_tel_init_multisim(void)
+{
+       INFO_C("Initializing the telephony multi sim info");
+
+       char **cp_list = NULL;
+       unsigned int modem_num = 0;
+       int err_code;
+       TelSimCardStatus_t simStatus = 0;
+       int card_changed = 0;
+
+
+
+       /* Get CP name list ? cp_list */
+       cp_list = tel_get_cp_name_list();
+       if (cp_list == NULL) {
+               ERR("tel_get_cp_name_list() Failed");
+               return;
+       }
+
+       while (cp_list[modem_num]) {
+               /* Initialize TAPI handle */
+               tapi_handle[modem_num] = tel_init(cp_list[modem_num]);
+
+               if (tapi_handle[modem_num] == NULL) {
+                       /* TAPI initialization ? Failure */
+                       ERR_SECURE("tel_init failed for Modem SIM number = %d", modem_num);
+               } else {
+                       /* TAPI initialization ? Success */
+                       DBG_SECURE("Success for Modem SIM number = %d, handler = %p",
+                                       modem_num, tapi_handle[modem_num]);
+                        err_code = tel_get_sim_init_info(tapi_handle[modem_num],
+                                               &simStatus, &card_changed);
+                        INFO_SECURE("Sim number = %d SIM status = %d", modem_num, simStatus);
+                         if ((TAPI_API_SUCCESS == err_code) &&
+                                       (TAPI_SIM_STATUS_SIM_INIT_COMPLETED == simStatus)) {
+                               if (modem_num == 0)
+                                       sim1 = 1;
+                               else
+                                       sim2 = 1;
+                         }
+               }
+
+               /* Move to next CP Name in cp_list */
+               modem_num++;
+       }
+
+       tapi_handle[modem_num] = NULL;
+
+       g_strfreev(cp_list);
+}
+
+static void __bt_ag_agent_tel_deinit_multisim(void)
+{
+       INFO_C("DeInitializing the telephony multi sim info");
+
+       char **cp_list = NULL;
+       unsigned int modem_num = 0;
+       int result;
 
+       cp_list = tel_get_cp_name_list();
+       if (cp_list == NULL) {
+               ERR("tel_get_cp_name_list() Failed");
+               return;
+       }
+
+        while (cp_list[modem_num]) {
+               result = tel_deinit(tapi_handle[modem_num]);
+               if (result != TAPI_API_SUCCESS)
+                       ERR("Fail to tel_deinit");
+                /* Move to next CP Name in cp_list */
+                modem_num++;
+       }
+
+       g_strfreev(cp_list);
+}
+
+gboolean __bt_ag_agent_telephony_init(void *arg)
+{
        int tapi_result;
        uint32_t ag_features = *((uint32_t *)arg);
 
        INFO_C("Initializing the telephony info");
-
-       _bt_hfp_initialize_telephony_manager(ag_features);
+       __bt_ag_agent_tel_init_multisim();
+       __bt_ag_agent_tel_get_preferred_sim(GET_TAPI_HANDLE);
+       _bt_hfp_initialize_telephony_manager(ag_features, GET_TAPI_HANDLE);
+       __bt_ag_agent_subscribe_tapi_updates(GET_TAPI_HANDLE);
        __bt_ag_agent_subscribe_vconf_updates();
-
-       tapi_handle = tel_init(NULL);
-       tapi_result = tel_get_sim_msisdn(tapi_handle, __bt_ag_agent_tel_cb,
+       tapi_result = tel_get_sim_msisdn(GET_TAPI_HANDLE, __bt_ag_agent_tel_cb,
                                        NULL);
        if (tapi_result != TAPI_API_SUCCESS)
                ERR("Fail to get sim info: %d", tapi_result);
-       return NULL;
+       return FALSE;
 }
 
 int main(void)
@@ -4411,10 +4751,12 @@ int main(void)
        int i;
        uint32_t ag_features;
        struct sigaction sa;
-       pthread_t thread_id;
 
        INFO_C("### Starting Bluetooth AG agent");
 
+#if GLIB_VERSION_MIN_REQUIRED < GLIB_VERSION_2_36
+       g_type_init();
+#endif
        ag_features = __bt_ag_agent_get_ag_features();
 
        ag.sdp_features = (uint16_t) ag_features & 0x1F;
@@ -4422,6 +4764,10 @@ int main(void)
        if (hfp_ver >= HFP_VERSION_1_6 && wbs_en == TRUE)
                ag.sdp_features |= BT_AG_FEATURE_SDP_WIDEBAND_SPEECH;
 
+       __bt_ag_agent_dbus_init();
+
+       g_idle_add(__bt_ag_agent_telephony_init, &ag_features);
+
        memset(&sa, 0, sizeof(sa));
        sa.sa_flags = SA_NOCLDSTOP;
        sa.sa_handler = __bt_ag_agent_sigterm_handler;
@@ -4436,27 +4782,15 @@ int main(void)
                return EXIT_FAILURE;
        }
 
-       __bt_ag_agent_dbus_init();
-       if (pthread_create(&thread_id, NULL,
-                       (void *)&__bt_ag_agent_telephony_init,
-                                       &ag_features) < 0) {
-               ERR("pthread_create() is failed");
-               return EXIT_FAILURE;
-       }
-
-       if (pthread_detach(thread_id) < 0)
-               ERR("pthread_detach() is failed");
-
        g_main_loop_run(gmain_loop);
 
        DBG("Cleaning up");
 
-       tel_deinit(tapi_handle);
-
        __bt_ag_agent_dbus_deinit();
        _bt_hfp_deinitialize_telephony_manager();
        __bt_ag_agent_release_vconf_updates();
-
+       __bt_ag_agent_unsubscribe_tapi_updates(GET_TAPI_HANDLE);
+       __bt_ag_agent_tel_deinit_multisim();
        if (remote_dev_path)
                g_free(remote_dev_path);