Update AG and HF agent codes from wearable product 79/165979/3 submit/tizen_4.0/20180108.000053
authorSangki Park <sangki79.park@samsung.com>
Fri, 5 Jan 2018 05:02:49 +0000 (14:02 +0900)
committerSangki Park <sangki79.park@samsung.com>
Fri, 5 Jan 2018 05:55:57 +0000 (14:55 +0900)
Change-Id: I4ebc2965fca1aaab0c6d4e2c77493cd0cb3dc9e2
Signed-off-by: Sangki Park <sangki79.park@samsung.com>
ag-agent/CMakeLists.txt
ag-agent/bluetooth-ag-agent.c
ag-agent/bluetooth-ag-agent.h [changed mode: 0755->0644]
ag-agent/bluetooth-ag-handler.c
ag-agent/bluetooth-ag-handler.h [changed mode: 0755->0644]
ag-agent/bluetooth-ag-manager.c
ag-agent/bluetooth-ag-phonebook.c [new file with mode: 0644]
ag-agent/bluetooth-ag-phonebook.h [new file with mode: 0644]
hf-agent/bluetooth-hf-agent.c
hf-agent/bluetooth-hf-agent.h
packaging/bluetooth-agent.spec

index 99fe7b4..ba4b676 100644 (file)
@@ -4,6 +4,7 @@ PROJECT(bluetooth-ag-agent C)
 SET(SRCS bluetooth-ag-agent.c
                        bluetooth-ag-handler.c
                        bluetooth-ag-manager.c
+                       bluetooth-ag-phonebook.c
                        ../include/bluetooth-agent-profile.c)
 
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
@@ -12,9 +13,12 @@ SET(PKG_MODULES
        dlog
        dbus-glib-1
        vconf
+       syspopup-caller
+       capi-network-bluetooth
        appsvc
        contacts-service2
        tapi
+       capi-system-device
        capi-appfw-application
        aul
        capi-system-info
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);
 
old mode 100755 (executable)
new mode 100644 (file)
index 3198660..ea7c9cf
 #include <glib.h>
 #include <gio/gio.h>
 #include <errno.h>
+#include <TapiUtility.h>
+#include <ITapiSim.h>
+#include <ITapiModem.h>
+#include <TelNetwork.h>
 
 #include "vconf.h"
 #include "vconf-keys.h"
 #define TELEPHONY_APP_INTERFACE "org.tizen.csd.Call.Instance"
 #define BT_HEADSET_INTERFACE "org.bluez.Headset"
 #define BT_ADAPTER_INTERFACE   "org.bluez.Adapter1"
+#define BT_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
+#define BLUEZ_DEVICE_INTERFACE "org.bluez.Device1"
 #define BT_INTERFACES_ADDED "InterfacesAdded"
 #define BT_INTERFACES_REMOVED "InterfacesRemoved"
+#define BT_PROPERTY_CHANGED "PropertiesChanged"
+
 #ifdef TIZEN_FEATURE_BT_MEDIA_ENHANCE
-#define BT_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
 #define BLUEZ_MEDIA_TRANSPORT_INTERFACE "org.bluez.MediaTransport1"
 #define BLUEZ_MEDIA_ENDPOINT_INTERFACE "org.bluez.MediaEndpoint1"
-#define BLUEZ_DEVICE_INTERFACE "org.bluez.Device1"
 #define A2DP_SOURCE_ENDPOINT "/MediaEndpoint/A2DPSource"
 #endif
 
@@ -262,6 +268,19 @@ typedef enum {
        BT_HF_FEATURE_CODEC_NEGOTIATION = 0x0080,
 } bt_hf_agent_feature_t;
 
+typedef enum {
+       BT_AG_FEATURE_PBAP_SHOW_AUTHORIZATION = 0x0000,
+       BT_AG_FEATURE_PBAP_BLOCKED = 0x0001,
+       BT_AG_FEATURE_PBAP_CANCEL = 0x0002,
+       BT_AG_FEATURE_PBAP_ALLOWED= 0x0004
+} bt_pbap_trusted_feature_t;
+
+typedef enum {
+       BT_PROFILE_SHOW_AUTHORIZATION = 0x0, /* 0b00 */
+       BT_PROFILE_SUPPORTED_BLOCKED = 0x1, /* 0b01 */
+       BT_PROFILE_SUPPORTED_TRUSTED= 0x2, /* 0b10 */
+} bt_profile_trusted_states;
+
 /* HFP AG service record bitmap. Bluetooth HFP 1.6 spec page 95 */
 #define BT_AG_FEATURE_SDP_3WAY                 0x1
 #define BT_AG_FEATURE_SDP_ECNR                 0x2
@@ -446,6 +465,7 @@ typedef struct {
        unsigned int remote_codecs;
        unsigned int sending_codec;
        unsigned int final_codec;
+       char *status;
 } bt_negotiation_info_t;
 
 typedef struct {
@@ -484,6 +504,9 @@ typedef struct {
 #if defined(TIZEN_SUPPORT_DUAL_HF)
        gboolean is_companion_device;
 #endif
+       int pbap_trusted;
+       char at_pbap_buf[30];
+       GDBusMethodInvocation *invocation;
 } bt_ag_info_t;
 
 typedef void (*headset_nrec_cb) (bt_ag_info_t *hs,
@@ -595,7 +618,7 @@ bt_hfp_agent_error_t _bt_hfp_change_call_status(const char *call_path,
                uint32_t call_status,
                uint32_t call_id,
                const char *sender);
-void _bt_hfp_initialize_telephony_manager(uint32_t ag_features);
+void _bt_hfp_initialize_telephony_manager(uint32_t ag_features, TapiHandle *handler);
 void _bt_hfp_deinitialize_telephony_manager(void);
 gboolean _bt_ag_agent_emit_property_changed(
                                GDBusConnection *connection,
@@ -627,5 +650,6 @@ bt_hfp_agent_error_t _bt_ag_agent_vendor_cmd(const gchar *cmd,
 #ifdef TIZEN_FEATURE_BT_MEDIA_ENHANCE
 void _bt_ag_agent_check_transport_state(void);
 #endif
+void _bt_ag_agent_set_last_speaker_gain(int gain);
 
 #endif /* __DEF_BT_AG_AGENT_H_ */
index 2a761d3..82270a8 100644 (file)
  * limitations under the License.
  *
  */
+#include <stdbool.h>
+#include <bundle_internal.h>
+#include <bluetooth.h>
+#include <bluetooth_internal.h>
 #include "bluetooth-ag-agent.h"
 #include "bluetooth-ag-handler.h"
 #include "vconf.h"
 #include "vconf-keys.h"
+#include <syspopup_caller.h>
 
 extern bt_ag_status_t ag;
 extern GSList *active_devices;
@@ -549,6 +554,7 @@ static int __bt_headset_set_gain(bt_ag_info_t *hs, uint16_t gain, char type)
                }
                property = "SpeakerGain";
                slconn->speaker_gain = gain;
+               _bt_ag_agent_set_last_speaker_gain(gain);
                break;
        case BT_HFP_MICROPHONE_GAIN:
                if (slconn->microphone_gain == gain) {
@@ -895,6 +901,11 @@ int _bt_hfp_voice_dial(bt_ag_info_t *hs, const char *buf)
        else
                enable = TRUE;
 
+       if (remote_dev_path)
+               g_free(remote_dev_path);
+
+       remote_dev_path = g_strdup(hs->path);
+
        _bt_hfp_voice_dial_request(enable, hs);
 
        slconn->is_voice_recognition_running = enable;
@@ -905,7 +916,7 @@ int _bt_hfp_voice_dial(bt_ag_info_t *hs, const char *buf)
 int _bt_hfp_indicators_activation(bt_ag_info_t *hs, const char *buf)
 {
        if (strlen(buf) < 7) {
-               printf("Invalid indicator activation request\n");
+               ERR("Invalid indicator activation request\n");
                return -EINVAL;
        }
 
@@ -978,10 +989,106 @@ int _bt_select_phonebook_memory_response(void *t_device,
        return _bt_ag_send_response(t_device, err);
 }
 
-int _bt_hfp_select_pb_memory(bt_ag_info_t *hs, const char *buf)
+static char *__bt_get_remote_device_name(const char *device_path)
+{
+       char *name = NULL;
+       GVariant *value;
+       GVariant *result = NULL;
+       GError *err = NULL;
+       GDBusProxy *device_proxy;
+       GDBusConnection *conn;
+
+       if (device_path == NULL)
+               return NULL;
+
+       conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
+
+       INFO_SECURE("Device_path %s", device_path);
+       device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+                                               NULL, "org.bluez",
+                                               device_path,
+                                               BT_PROPERTIES_INTERFACE,
+                                               NULL, &err);
+
+       result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
+                       g_variant_new("(s)", "org.bluez.Device1"),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       20, NULL,
+                       &err);
+       if (err) {
+               ERR("DBus Error : %s", err->message);
+               g_clear_error(&err);
+               return NULL;
+       }
+       if (result == NULL) {
+               ERR("g_dbus_proxy_call_sync function return NULL");
+               return NULL;
+       }
+       g_variant_get(result, "(@a{sv})", &value);
+
+       if (value) {
+               GVariant *temp_value = g_variant_lookup_value(value, "Alias",
+                       G_VARIANT_TYPE_STRING);
+               g_variant_get(temp_value, "(s)", &name);
+               if (temp_value)
+                       g_variant_unref(temp_value);
+
+               if (name != NULL)
+                       INFO_SECURE("Alias Name [%s]", name);
+               else {
+                       temp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
+                       g_variant_get(temp_value, "s", &name);
+                       if (temp_value)
+                               g_variant_unref(temp_value);
+                       INFO_SECURE("Name = %s", name);
+               }
+       }
+       g_variant_unref(result);
+       g_object_unref(device_proxy);
+       return name;
+}
+
+int _bt_launch_pbap_popup(const char *device_name,
+                                                       const char *agent_path)
 {
-       if (strlen(buf) < 8)
-               return -EINVAL;
+       int ret;
+       bundle *b;
+       char event_str[50 + 1];
+
+       b = bundle_create();
+       if (!b) {
+               ERR("Launching system popup failed");
+               return -1;
+       }
+
+       bundle_add(b, "device-name", device_name);
+       bundle_add(b, "agent-path", agent_path);
+
+       g_strlcpy(event_str, "phonebook-request", sizeof(event_str));
+
+       bundle_add(b, "event-type", event_str);
+
+       ret = syspopup_launch("bt-syspopup", b);
+       if (0 > ret) {
+               ERR("Popup launch failed... %d", ret);
+       }
+
+       bundle_free(b);
+
+       INFO("_bt_agent_launch_system_popup");
+       return 0;
+}
+
+int _bt_hfp_select_phonebook_memory_status_reply(bt_ag_info_t *hs)
+{
+       const char *buf = hs->at_pbap_buf;
+       if (hs->pbap_trusted == BT_AG_FEATURE_PBAP_BLOCKED
+               || hs->pbap_trusted == BT_AG_FEATURE_PBAP_CANCEL) {
+               INFO("Doesnot have Access reply with error");
+               _bt_select_phonebook_memory_response(hs,
+                       HFP_STATE_MNGR_ERR_NOT_ALLOWED);
+               return 0;
+       }
 
        if (buf[7] == '?') {
                _bt_hfp_select_phonebook_memory_status(hs);
@@ -994,10 +1101,60 @@ int _bt_hfp_select_pb_memory(bt_ag_info_t *hs, const char *buf)
                        return 0;
                }
                _bt_hfp_select_phonebook_memory(hs, &buf[8]);
-               return 0;
        }
 
-       return -EINVAL;
+       return 0;
+}
+
+int _bt_hfp_select_pb_memory(bt_ag_info_t *hs, const char *buf)
+{
+       if (strlen(buf) < 8)
+               return -EINVAL;
+       INFO("Pbap_trusted %d", hs->pbap_trusted);
+       if (hs->pbap_trusted == BT_AG_FEATURE_PBAP_SHOW_AUTHORIZATION
+               || hs->pbap_trusted == BT_AG_FEATURE_PBAP_CANCEL) {
+               strncpy(hs->at_pbap_buf, buf, sizeof(hs->at_pbap_buf) - 1);
+               /* Adding Popup here */
+               int trust = 0;
+               bt_initialize();
+               int err = bt_device_get_profile_trusted(hs->remote_addr, 1, &trust);
+               if (err != TIZEN_ERROR_NONE) {
+                       INFO("Show authorization popup %d Error %d", trust, err);
+                       char *name = __bt_get_remote_device_name(hs->path);
+                       INFO_SECURE("remote device name %s", name);
+                       _bt_launch_pbap_popup(name,
+                               BT_AG_AGENT_OBJECT_PATH);
+                       return 0;
+               }
+               if (trust == 0) {
+                       INFO("This device has been marked as blocked");
+                       hs->pbap_trusted = BT_AG_FEATURE_PBAP_BLOCKED;
+                       return -EACCES;
+               } else
+                       hs->pbap_trusted = BT_AG_FEATURE_PBAP_ALLOWED;
+       }
+       if (hs->pbap_trusted == BT_AG_FEATURE_PBAP_ALLOWED) {
+               INFO("Authorized from PBAP");
+               if (buf[7] == '?') {
+                       _bt_hfp_select_phonebook_memory_status(hs);
+                       return 0;
+               }
+
+               if (buf[7] == '=') {
+                       if (buf[8] == '?') {
+                               _bt_hfp_select_phonebook_memory_list(hs);
+                               return 0;
+                       }
+                       _bt_hfp_select_phonebook_memory(hs, &buf[8]);
+                       return 0;
+               }
+       } else if (hs->pbap_trusted == BT_AG_FEATURE_PBAP_BLOCKED) {
+               INFO("Device is blocked");
+               /* Reply with Error */
+               return -EACCES;
+       }
+
+       return 0;
 }
 
 int _bt_read_phonebook_entries_list_response(void *t_device,
@@ -1021,7 +1178,7 @@ int _bt_read_phonebook_entries_list_response(void *t_device,
        }
 
        if (used < 1)
-               index = 0;
+               used = 1;
 
        send_err = _bt_ag_send_at(hs, "\r\n+CPBR: (%d-%d),%d,%d\r\n",
                        index, used, number_length, name_length);
@@ -1057,8 +1214,31 @@ int _bt_read_phonebook_entries_indicator(const char *name, const char *number,
        return 0;
 }
 
+int _bt_read_phonebook_entries_indicator_by_name(const char *name,
+                                       const char *number, uint32_t handle)
+{
+       int type = 129;
+       const char *pos = NULL;
+
+       pos = number;
+       while (*pos == ' ' || *pos == '\t')
+               pos++;
+
+       /* 145 means international access code, otherwise 129 is used */
+       if (*pos == '+')
+               type = 145;
+
+       _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
+               "\r\n+CPBF: %d,\"%s\",%d,\"%s\"\r\n",
+               handle, number, type, name);
+       return 0;
+}
+
 int _bt_hfp_read_pb_entries(bt_ag_info_t *hs, const char *buf)
 {
+       if (hs->pbap_trusted != BT_AG_FEATURE_PBAP_ALLOWED)
+               return -EACCES;
+
        if (strlen(buf) < 8)
                return -EINVAL;
 
@@ -1097,6 +1277,10 @@ int _bt_find_phonebook_entries_status_indicator(uint32_t number_length,
 
 int _bt_hfp_find_pb_entires(bt_ag_info_t *hs, const char *buf)
 {
+       /* Check if Contact access is permitted or not */
+       if (hs->pbap_trusted != BT_AG_FEATURE_PBAP_ALLOWED)
+               return -EACCES;
+
        if (strlen(buf) < 8)
                return -EINVAL;
 
@@ -1195,7 +1379,8 @@ int _bt_hfp_apl_command(bt_ag_info_t *hs, const char *buf)
 {
        DBG("Got Apple command: %s", buf);
 
-       return _bt_ag_send_response(hs, HFP_STATE_MNGR_ERR_NONE);
+       /*we don't support XAPL commands*/
+       return _bt_ag_send_response(hs, HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
 }
 
 /* convert signal strength to a RSSI level */
old mode 100755 (executable)
new mode 100644 (file)
index 96bd7f3..d3060c6
@@ -84,6 +84,7 @@ bt_hfp_agent_error_t _bt_hfp_event_indicator(int index);
 void _bt_hfp_set_ag_indicator(uint32_t ag_features,
                                const bt_ag_indicators_t *ag_indicators,
                                int rh, const char *chld);
+int _bt_hfp_select_phonebook_memory_status_reply(bt_ag_info_t *hs);
 int _bt_calling_stopped_indicator(void);
 int _bt_incoming_call_indicator(const char *number, int type);
 int _bt_dial_number_response(void *t_device, bt_hfp_agent_error_t err);
@@ -145,12 +146,17 @@ int _bt_transmit_dtmf_response(void *t_device,
                        bt_hfp_agent_error_t err);
 int _bt_find_phonebook_entries_response(void *t_device,
                                        bt_hfp_agent_error_t err);
+int _bt_read_phonebook_entries_indicator(const char *name, const char *number,
+                                       uint32_t handle);
 int _bt_response_and_hold_response(void *t_device,
                                        bt_hfp_agent_error_t err);
 int _bt_answer_call_response(void *hs, bt_hfp_agent_error_t err);
 int _bt_read_phonebook_entries_indicator(const char *name,
                                        const char *number,
                                        uint32_t handle);
+int _bt_read_phonebook_entries_indicator_by_name(const char *name,
+                                       const char *number,
+                                       uint32_t handle);
 int _bt_hfp_get_activity_status_rsp(void *t_device,
                                                int status,
                                                bt_hfp_agent_error_t err);
index 5ba4477..f58a500 100644 (file)
 #include <string.h>
 #include "bluetooth-ag-agent.h"
 #include "bluetooth-ag-handler.h"
-#include <dbus/dbus.h>
+#include "bluetooth-agent-profile.h"
+#include <glib.h>
+
+#include "bluetooth-ag-phonebook.h"
+
+#include <TapiUtility.h>
+#include <ITapiSim.h>
+
+#include <device/battery.h>
+#include <device-error.h>
 
 #define PHONEBOOK_AGENT_BUS_NAME "org.bluez.pb_agent"
 #define PHONEBOOK_AGENT_PATH    "/org/bluez/pb_agent"
@@ -116,20 +125,20 @@ static struct {
        .signal_strength = 0,
 };
 
+#ifdef TIZEN_FEATURE_BT_PBAP_SIM
+static const char *agent_pb_store_list[] =  {
+       "\"ME\"", "\"DC\"", "\"MC\"", "\"SM\"", "\"RC\""
+};
+#else
 static const char *agent_pb_store_list[] =  {
        "\"ME\"", "\"DC\"", "\"MC\"", "\"RC\""
 };
+#endif
 
 static const char *agent_supported_character_set[] = {
        "\"UTF-8\"", "\"IRA\""
 };
 
-#if defined(TIZEN_PROFILE_WEARABLE) && defined(TIZEN_FEATURE_BT_HFP_AG)
-static const char *ag_chld_str = "0,1,2";
-#else
-static const char *ag_chld_str = "0,1,2,3";
-#endif
-
 #define AGENT_PB_STORE_LIST_SIZE (sizeof(agent_pb_store_list) \
                                /sizeof(const char *))
 #define AGENT_SUPPORTED_CHARACTER_SET_SIZE ( \
@@ -154,6 +163,33 @@ static struct {
        .charset_id = 0
 };
 
+void __bt_hfp_print_callpath(const char *call_path, const char *call_sender)
+{
+       GSList *sender_list = call_senders_paths;
+       sender_info_t *sender;
+
+       INFO("=============================");
+       INFO("call path is  = %s\n", call_path);
+       INFO("sender is  = %s\n", call_sender);
+
+       if (call_path == NULL || call_sender == NULL) {
+               ERR("Invalid Parameters");
+               return;
+       }
+
+       while (sender_list != NULL) {
+               sender = sender_list->data;
+
+               if (sender == NULL)
+                       break;
+
+               INFO("sender->sender_path [%s] ", sender->sender_path);
+               sender_list = sender_list->next;
+       }
+       INFO("=============================");
+       return;
+}
+
 static gboolean __bt_hfp_check_for_callpath(const char *call_path,
                                        const char *call_sender)
 {
@@ -185,7 +221,7 @@ static gboolean __bt_hfp_check_for_callpath(const char *call_path,
                sender_list = sender_list->next;
        }
 
-       ERR("Call path is not already registered");
+       ERR("Call path [%s] is not registered", call_path);
        return FALSE;
 }
 
@@ -230,19 +266,24 @@ void _bt_hfp_device_disconnected(void *t_device)
        __bt_hfp_reset_indicators();
 }
 
-void _bt_hfp_initialize_telephony_manager(uint32_t ag_features)
+void _bt_hfp_initialize_telephony_manager(uint32_t ag_features, TapiHandle *handler)
 {
        int index;
        int value;
        int ret;
+       char *ag_chld_str;
+
+       if (TIZEN_PROFILE_WEARABLE)
+               ag_chld_str = "0,1,2";
+       else
+               ag_chld_str = "0,1,2,3";
 
        /* Reset the indicator values */
        for (index = 0; hfp_ag_ind[index].indicator_desc != NULL; index++) {
                if (g_str_equal(hfp_ag_ind[index].indicator_desc, "battchg")) {
-                       ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
-                                                                       &value);
-                       if (ret != 0) {
-                               ERR("Get battery status failed : %d\n", ret);
+                       ret = device_battery_get_percent(&value);
+                       if (ret != DEVICE_ERROR_NONE) {
+                               ERR("Get battery status failed. Err = %d\n", ret);
                        } else {
                                /* Send battery status ranging from 0-5 */
                                if (value < 5)
@@ -253,28 +294,28 @@ void _bt_hfp_initialize_telephony_manager(uint32_t ag_features)
                                        hfp_ag_ind[index].hfp_value = value / 20 + 1;
                        }
                } else if (g_str_equal(hfp_ag_ind[index].indicator_desc, "signal")) {
-                       ret = vconf_get_int(VCONFKEY_TELEPHONY_RSSI, &value);
-                       if (ret != 0) {
+                       ret = tel_get_property_int(handler, TAPI_PROP_NETWORK_SIGNALSTRENGTH_LEVEL, &value);
+                       if (ret != TAPI_API_SUCCESS) {
                                ERR("Get signal status failed err = %d\n", ret);
                        } else {
                                BT_CHECK_SIGNAL_STRENGTH(value);
                                hfp_ag_ind[index].hfp_value = value;
                        }
                } else if (g_str_equal(hfp_ag_ind[index].indicator_desc, "roam")) {
-                       ret = vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &value);
-                       if (ret != 0)
+                       ret = tel_get_property_int(handler, TAPI_PROP_NETWORK_ROAMING_STATUS, &value);
+                       if (ret != TAPI_API_SUCCESS)
                                ERR("Get roaming status failed err = %d\n", ret);
                        else
                                hfp_ag_ind[index].hfp_value = value;
                } else if (g_str_equal(hfp_ag_ind[index].indicator_desc, "service")) {
-                       ret = vconf_get_int(VCONFKEY_TELEPHONY_SVCTYPE, &value);
-                       if (ret != 0) {
+                       ret = tel_get_property_int(handler, TAPI_PROP_NETWORK_SERVICE_TYPE, &value);
+                       if (ret != TAPI_API_SUCCESS) {
                                ERR("Get Service status failed : %d\n", ret);
                        } else {
                                switch (value) {
-                               case VCONFKEY_TELEPHONY_SVCTYPE_NONE:
-                               case VCONFKEY_TELEPHONY_SVCTYPE_NOSVC:
-                               case VCONFKEY_TELEPHONY_SVCTYPE_SEARCH:
+                               case TAPI_NETWORK_SERVICE_TYPE_UNKNOWN:
+                               case TAPI_NETWORK_SERVICE_TYPE_NO_SERVICE:
+                               case TAPI_NETWORK_SERVICE_TYPE_SEARCH:
                                        hfp_ag_ind[index].hfp_value =
                                                INDICATOR_EVENT_SERVICE_NONE;
                                        break;
@@ -335,22 +376,21 @@ bt_hfp_agent_error_t _bt_hfp_register_telephony_agent(gboolean register_flag,
        if (sender == NULL || path_to_register == NULL)
                return BT_HFP_AGENT_ERROR_INVALID_PARAM;
 
-       DBG(" register_flag = %d", register_flag);
-       DBG(" path_to_register = %s", path_to_register);
-       DBG(" sender = %s", sender);
+       INFO(" register_flag = %d", register_flag);
+       INFO(" path_to_register = %s", path_to_register);
+       INFO(" sender = %s", sender);
 
        if (register_flag) {
                if (__bt_hfp_check_for_callpath(path_to_register, sender))
                        return BT_HFP_AGENT_ERROR_ALREADY_EXSIST;
 
                /* add call path to the senders list*/
-               DBG("Call path doesn't exist. Add path %s to global path",
+               INFO("Call path doesn't exist. Add path %s to global path",
                                                path_to_register);
                sender_info = g_new0(sender_info_t, 1);
                sender_info->sender_path = g_strdup(path_to_register);
                sender_info->sender_name = g_strdup(sender);
-               call_senders_paths = g_slist_append(call_senders_paths,
-                                                               sender_info);
+               call_senders_paths = g_slist_append(call_senders_paths, sender_info);
 
                return BT_HFP_AGENT_ERROR_NONE;
        } else {
@@ -365,10 +405,12 @@ bt_hfp_agent_error_t _bt_hfp_register_telephony_agent(gboolean register_flag,
 
                        if (g_strcmp0(sender_info->sender_path,
                                        path_to_register) == 0) {
+                               INFO("Remove path [%s]", path_to_register);
                                call_senders_paths = g_slist_remove(
                                                        call_senders_paths,
                                                        sender_info);
                                __bt_hfp_clear_sender_path(sender_info);
+
                                return BT_HFP_AGENT_ERROR_NONE;
                        }
                        s_list = s_list->next;
@@ -764,15 +806,17 @@ bt_hfp_agent_error_t _bt_hfp_incoming_call(const char *call_path,
                const char *sender)
 {
        struct telephony_call *t_call = NULL;
-       bt_hfp_agent_error_t hfp_err = BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
+       bt_hfp_agent_error_t hfp_err = BT_HFP_AGENT_ERROR_NONE;
        int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
        int error;
 
        if (sender == NULL || call_path == NULL)
                return BT_HFP_AGENT_ERROR_INVALID_PARAM;
 
-       if (!__bt_hfp_check_for_callpath(call_path, sender))
+       if (!__bt_hfp_check_for_callpath(call_path, sender)) {
+               __bt_hfp_print_callpath(call_path, sender);
                return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
+       }
 
        if (!__bt_hfp_is_call_allowed(call_path))
                return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
@@ -840,11 +884,11 @@ bt_hfp_agent_error_t _bt_hfp_outgoing_call(const char *call_path,
        bt_hfp_agent_error_t ret =  BT_HFP_AGENT_ERROR_NONE;
        gboolean err = FALSE;
 
-
        err = __bt_hfp_check_for_callpath(call_path, sender);
-       if (!err)
+       if (!err) {
+               __bt_hfp_print_callpath(call_path, sender);
                return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
-
+       }
        /*check if the call_path exisits in the active call list, if not
        don't allow as the call may be initated by some other application*/
 
@@ -878,8 +922,10 @@ bt_hfp_agent_error_t _bt_hfp_change_call_status(const char *call_path,
 
        ret = __bt_hfp_check_for_callpath(call_path, sender);
 
-       if (!ret)
+       if (!ret) {
+               __bt_hfp_print_callpath(call_path, sender);
                return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
+       }
 
        ret = __bt_hfp_is_call_allowed(call_path);
        if (!ret)
@@ -1048,7 +1094,7 @@ int _bt_hfp_set_property_name(const char *property, const char *operator_name)
        if (g_str_equal("SubscriberNumberChanged", property)) {
                g_free(ag_subscriber_num);
                ag_subscriber_num = g_strdup(operator_name);
-               DBG("HFP: subscriber_number updated: %s", ag_subscriber_num);
+               DBG_SECURE("HFP: subscriber_number updated: %s", ag_subscriber_num);
                ret = 1;
        }
        return ret;
@@ -1179,12 +1225,16 @@ static int __bt_hfp_release_call(struct telephony_call *t_call)
 static int __bt_hfp_release_conference(void)
 {
        GSList *temp_list = existing_call_list;
+       int ret = 0;
 
        while (temp_list != NULL) {
                struct telephony_call *t_call = temp_list->data;
 
-               if (t_call->call_conference)
-                       __bt_hfp_release_call(t_call);
+               if (t_call->call_conference) {
+                       ret = __bt_hfp_release_call(t_call);
+                       if (ret < 0)
+                               ERR("Seems like there are no active calls.");
+               }
 
                temp_list = temp_list->next;
        }
@@ -1524,8 +1574,6 @@ void _bt_hfp_release_all_calls_by_sender(const char *sender)
        if (!sender)
                return;
 
-       DBG("sender [%s]", sender);
-
        while (temp_list != NULL) {
                struct telephony_call *t_call = temp_list->data;
 
@@ -1611,57 +1659,27 @@ fail:
 static int __bt_hfp_get_phonebook_count(const char *path, uint32_t *max_size,
                                uint32_t *used)
 {
-#ifndef TIZEN_PROFILE_WEARABLE
-       GDBusConnection *g_conn;
-       GDBusProxy *g_proxy;
-       GError *err = NULL;
-       GVariant *ret = NULL;
+       FN_START;
+       PhoneBookType pb_type = TELECOM_NONE;
+       guint count = 0;
        uint32_t max = 0;
-       uint32_t size = 0;
-
-       g_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
 
-       if (!g_conn) {
-               if (err) {
-                       ERR("Unable to connect to gdbus: %s", err->message);
-                       g_clear_error(&err);
-               }
-               return -1;
+       INFO("name: %s\n", path);
+       if (contacts_connect() != CONTACTS_ERROR_NONE) {
+               ERR("Can not connect contacts server\n");
+               return 0;
        }
 
-       g_proxy =  g_dbus_proxy_new_sync(g_conn,
-                       G_DBUS_PROXY_FLAGS_NONE, NULL,
-                       PHONEBOOK_AGENT_BUS_NAME, PHONEBOOK_AGENT_PATH,
-                       PHONEBOOK_AGENT_INTERFACE, NULL, &err);
+       pb_type = __bluetooth_pb_get_storage_pb_type(path);
 
-       if (!g_proxy) {
-               if (err) {
-                       ERR("Unable to connect to gdbus: %s", err->message);
-                       g_clear_error(&err);
-               }
-               return -1;
+       if (__bluetooth_pb_get_count(pb_type, &count) == FALSE) {
+               ERR("unable to get count");
+               if (contacts_disconnect() != CONTACTS_ERROR_NONE)
+                       ERR("contacts_disconnect failed");
+               return 0;
        }
 
-       ret = g_dbus_proxy_call_sync(g_proxy, "GetPhonebookSizeAt",
-                       g_variant_new("(s)",
-                       path),
-                       G_DBUS_CALL_FLAGS_NONE, -1,
-                       NULL, &err);
-
-       if (ret == NULL) {
-               ERR("dbus call failed");
-               if (err != NULL) {
-                       ERR("D-Bus API failure: errCode[%x], message[%s]",
-                              err->code, err->message);
-
-                       g_clear_error(&err);
-               }
-       }
-       if (ret != NULL) {
-               g_variant_get(ret, "(u)", &size);
-               g_variant_unref(ret);
-       }
-       DBG("Size returned %d", size);
+       DBG("Size returned %d", count);
        if ((g_strcmp0(path, "\"SM\"") == 0) ||
                        (g_strcmp0(path, "\"ME\"") == 0)) {
                max = AGENT_MAX_PB_COUNT;
@@ -1674,17 +1692,14 @@ static int __bt_hfp_get_phonebook_count(const char *path, uint32_t *max_size,
        if (max_size)
                *max_size = max;
        if (used) {
-               if (size > max)
+               if (count > max)
                        *used = max;
                else
-                       *used = size;
+                       *used = count;
        }
-
-       if (g_conn)
-               g_object_unref(g_conn);
-       if (g_proxy)
-               g_object_unref(g_proxy);
-#endif
+       if (contacts_disconnect() != CONTACTS_ERROR_NONE)
+               ERR("contacts_disconnect failed");
+       FN_END;
        return 0;
 }
 
@@ -1790,96 +1805,33 @@ void _bt_hfp_read_phonebook_entries_list(void *t_device)
 
 static int __bt_hfp_get_phonebook_entries(int start_index, int end_index)
 {
-#ifdef TIZEN_PROFILE_WEARABLE
-       int count = 0;
-#else
-       GDBusConnection *g_conn;
-       GDBusProxy *g_proxy;
-       GError *err = NULL;
-       GVariant *ret = NULL;
+       FN_START;
        int count = 0;
-       GVariant *value = NULL;
-       GVariant *tuple = NULL;
-       const char *name = NULL;
-       const char *number = NULL;
-
-       char *uni_name;
-       char *uni_number;
-
-       uint32_t handle = 0;
+       PhoneBookType pb_type = TELECOM_NONE;
 
-       g_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+       DBG("command: %s, start_index: %d, end_index: %d\n",
+               agent_pb_store_list[ag_pb_info.path_id], start_index, end_index);
 
-       if (!g_conn) {
-               if (err) {
-                       ERR("Unable to connect to gdbus: %s", err->message);
-                       g_clear_error(&err);
-               }
-               return -1;
+       if (contacts_connect() != CONTACTS_ERROR_NONE) {
+               ERR("Can not connect contacts server");
+               return 0;
        }
 
-       g_proxy =  g_dbus_proxy_new_sync(g_conn,
-                       G_DBUS_PROXY_FLAGS_NONE, NULL,
-                       PHONEBOOK_AGENT_BUS_NAME, PHONEBOOK_AGENT_PATH,
-                       PHONEBOOK_AGENT_INTERFACE, NULL, &err);
-       if (!g_proxy) {
-               if (err) {
-                       ERR("Unable to connect to gdbus: %s", err->message);
-                       g_clear_error(&err);
-               }
-               return -1;
-       }
+       pb_type = __bluetooth_pb_get_storage_pb_type(
+                               agent_pb_store_list[ag_pb_info.path_id]);
 
-       ret = g_dbus_proxy_call_sync(g_proxy, "GetPhonebookEntriesAt",
-                       g_variant_new("(sii)",
-                       agent_pb_store_list[ag_pb_info.path_id],
-                       start_index, end_index),
-                       G_DBUS_CALL_FLAGS_NONE, -1,
-                       NULL, &err);
+       if (pb_type == TELECOM_NONE || pb_type == TELECOM_CCH) {
+               if (contacts_disconnect() != CONTACTS_ERROR_NONE)
+                       ERR("contacts_disconnect failed");
+               return 0;
+       }
 
-       if (ret == NULL) {
-               ERR("Dbus call failed");
-               if (err != NULL) {
-                       ERR("D-Bus API failure: errCode[%x], message[%s]",
-                                  err->code, err->message);
+       __bluetooth_pb_get_list_number(pb_type,
+                       start_index, end_index, &count);
 
-                       g_clear_error(&err);
-               } else {
-                       ERR("error returned was NULL");
-               }
-               return -1;
-       } else {
-               tuple = g_variant_get_child_value(ret, 0);
-               if (tuple != NULL) {
-                       int number_contacts = g_variant_n_children(tuple);
-                       DBG("number of contacts %d", number_contacts);
-                       while (count < number_contacts) {
-                               value = NULL;
-
-                               value = g_variant_get_child_value(tuple, count);
-
-                               g_variant_get(value, "(ssu)", &name, &number, &handle);
-                               count++;
-                               uni_name = g_strndup(name, AGENT_PB_NAME_MAX_LENGTH);
-                               uni_number = g_strndup(number, AGENT_PB_NAME_MAX_LENGTH);
-
-                               _bt_read_phonebook_entries_indicator(uni_name,
-                                               uni_number, handle);
-                               g_variant_unref(value);
-                               g_free(uni_name);
-                               g_free(uni_number);
-                               g_free((gpointer)name);
-                               g_free((gpointer)number);
-                       }
-                       g_variant_unref(tuple);
-               }
-       }
-       g_variant_unref(ret);
-       if (g_conn)
-               g_object_unref(g_conn);
-       if (g_proxy)
-               g_object_unref(g_proxy);
-#endif
+       if (contacts_disconnect() != CONTACTS_ERROR_NONE)
+               ERR("contacts_disconnect failed");
+       FN_END;
        return count;
 }
 
@@ -1934,8 +1886,47 @@ void _bt_hfp_find_phonebook_entries_status(void *t_device)
                                                HFP_STATE_MNGR_ERR_NONE);
 }
 
+static int __bt_hfp_get_phonebook_entries_by_name(int start_index,
+                                       int end_index,
+                                       const char *str)
+{
+       FN_START;
+       int count = 0;
+       PhoneBookType pb_type = TELECOM_NONE;
+
+       DBG("command: %s, start_index: %d, end_index: %d\n",
+               agent_pb_store_list[ag_pb_info.path_id], start_index, end_index);
+
+       if (contacts_connect() != CONTACTS_ERROR_NONE) {
+               ERR("Can not connect contacts server");
+               return 0;
+       }
+
+       pb_type = __bluetooth_pb_get_storage_pb_type(
+                               agent_pb_store_list[ag_pb_info.path_id]);
+
+       if (pb_type == TELECOM_NONE || pb_type == TELECOM_CCH) {
+               if (contacts_disconnect() != CONTACTS_ERROR_NONE)
+                       ERR("contacts_disconnect failed");
+               return 0;
+       }
+
+       __bluetooth_pb_get_list_entries_by_name(pb_type,
+                       start_index, end_index, str, &count);
+
+       if (contacts_disconnect() != CONTACTS_ERROR_NONE)
+               ERR("contacts_disconnect failed");
+       FN_END;
+       return count;
+}
+
 static int __bt_hfp_find_pb_entries(const char *str)
 {
+       char *search = g_ascii_strup(str, strlen(str));
+
+       /* No limit on number of searched item and need to search complete list*/
+       __bt_hfp_get_phonebook_entries_by_name(0, 0, search);
+       g_free(search);
        return 0;
 }
 
diff --git a/ag-agent/bluetooth-ag-phonebook.c b/ag-agent/bluetooth-ag-phonebook.c
new file mode 100644 (file)
index 0000000..e6528e3
--- /dev/null
@@ -0,0 +1,1236 @@
+/*
+ * bluetooth-ag-phonebook.c
+ *
+ * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:    Hocheol Seo <hocheol.seo@samsung.com>
+ *             Sangki Park <sangki79.park@samsung.com>
+ *             Chanyeol Park <chanyeol.park@samsung.com>
+ *             Rakesh MK <rakesh.mk@samsung.com>
+ *             Anurag B <biradar.a@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "bluetooth-ag-phonebook.h"
+#include "bluetooth-ag-agent.h"
+#include "bluetooth-ag-handler.h"
+
+
+static contacts_query_h __bluetooth_pb_query_phone_log_incoming(void);
+
+static contacts_query_h __bluetooth_pb_query_phone_log_outgoing(void);
+
+static contacts_query_h __bluetooth_pb_query_phone_log_missed(void);
+
+static contacts_query_h __bluetooth_pb_query_phone_log_combined(void);
+
+#ifdef TIZEN_FEATURE_BT_PBAP_SIM
+static gchar *_bluetooth_pb_number_from_person_id(gint person_id);
+
+static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact);
+
+static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact);
+#endif
+
+PhoneBookType __bluetooth_pb_get_storage_pb_type(const char *name)
+{
+       FN_START;
+       if (name == NULL)
+               return TELECOM_NONE;
+
+       if (g_strcmp0(name, "\"ME\"") == 0)
+               return TELECOM_PB;
+
+       if (g_strcmp0(name, "\"RC\"") == 0)
+               return TELECOM_ICH;
+
+       if (g_strcmp0(name, "\"DC\"") == 0)
+               return TELECOM_OCH;
+
+       if (g_strcmp0(name, "\"MC\"") == 0)
+               return TELECOM_MCH;
+#ifdef TIZEN_FEATURE_BT_PBAP_SIM
+       if (g_strcmp0(name, "\"SM\"") == 0)
+               return SIM_PB;
+#endif
+
+       FN_END;
+       return TELECOM_NONE;
+}
+
+static bool _bt_is_sim_addressbook(const char *addressbook)
+{
+       return g_str_has_prefix(addressbook, SIM_ADDRESSBOOK_PREFIX);
+}
+
+static bool __bt_is_matching_addressbook(const char *addressbook_name,
+                       int addressbook)
+{
+       bool is_sim_addressbook = _bt_is_sim_addressbook(addressbook_name);
+
+       if ((is_sim_addressbook == false
+                       && addressbook == PBAP_ADDRESSBOOK_PHONE) ||
+               (is_sim_addressbook == true
+                       && addressbook == PBAP_ADDRESSBOOK_SIM))
+               return true;
+
+       return false;
+}
+
+static contacts_query_h __bluetooth_pb_query_person(int addressbook)
+{
+       FN_START;
+       contacts_query_h query = NULL;
+       contacts_filter_h filter = NULL;
+       contacts_list_h recordList = NULL;
+       contacts_record_h record = NULL;
+
+       char *addressbook_name = NULL;
+       int address_book_id = 0;
+       int count = 0;
+       unsigned int i = 0;
+       gint status;
+       bool is_first_condition = true;
+       DBG("Addressbook [%d]", addressbook);
+       /* Create query*/
+       status = contacts_query_create(_contacts_person_contact._uri, &query);
+       if (status != 0) {
+               ERR("Could not create query");
+               return NULL;
+       }
+
+       /* Create addressbook Filter*/
+       contacts_db_get_all_records(_contacts_address_book._uri, 0, 0,
+               &recordList);
+       contacts_filter_create(_contacts_person_contact._uri, &filter);
+       contacts_list_get_count(recordList, &count);
+       INFO("COUNT %d", count);
+       for (i = 0; i < count; i++) {
+               status = contacts_list_get_current_record_p(recordList, &record);
+               if (status != CONTACTS_ERROR_NONE) {
+                       ERR("Contact list get api failed %d", status);
+                       goto next;
+               }
+               status = contacts_record_get_str_p(record, _contacts_address_book.name,
+                                       &addressbook_name);
+               if (status != CONTACTS_ERROR_NONE) {
+                       ERR("Contact record get api failed %d", status);
+                       goto next;
+               }
+               status = contacts_record_get_int(record, _contacts_address_book.id,
+                                       &address_book_id);
+               if (status != CONTACTS_ERROR_NONE) {
+                       ERR("contacts record get int api failed %d", status);
+                       goto next;
+               }
+
+               DBG("Addressbook ID: [%d] Addressbook Name: [%s]",
+                               address_book_id, addressbook_name);
+
+               if (__bt_is_matching_addressbook(addressbook_name,
+                               addressbook)) {
+                       if (is_first_condition)
+                               is_first_condition = false;
+                       else
+                               contacts_filter_add_operator(filter,
+                                               CONTACTS_FILTER_OPERATOR_OR);
+                       DBG("SELECTED Addressbook ID: [%d] Addressbook Name: [%s]",
+                                       address_book_id, addressbook_name);
+                       status = contacts_filter_add_int(filter,
+                                       _contacts_person_contact.address_book_id,
+                                       CONTACTS_MATCH_EQUAL, address_book_id);
+                       if (status != CONTACTS_ERROR_NONE)
+                               ERR("Contact filter add failed %d", status);
+               }
+next:
+               if (contacts_list_next(recordList) != CONTACTS_ERROR_NONE)
+                       break;
+       }
+
+       contacts_list_destroy(recordList, true);
+
+       status = contacts_query_set_filter(query, filter);
+       if (status != CONTACTS_ERROR_NONE)
+               ERR("Could not Apply Filter");
+
+       contacts_filter_destroy(filter);
+       FN_END;
+       return query;
+}
+
+gboolean __bluetooth_pb_get_count(PhoneBookType pb_type,
+                               guint *count)
+{
+       FN_START;
+       contacts_query_h query = NULL;
+
+       gint status;
+       gint signed_count;
+       INFO("Pb type %d", pb_type);
+       switch (pb_type) {
+       case TELECOM_PB:
+               query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_PHONE);
+               break;
+       case TELECOM_ICH:
+               query = __bluetooth_pb_query_phone_log_incoming();
+               break;
+       case TELECOM_OCH:
+               query = __bluetooth_pb_query_phone_log_outgoing();
+               break;
+       case TELECOM_MCH:
+               query = __bluetooth_pb_query_phone_log_missed();
+               break;
+       case TELECOM_CCH:
+               query = __bluetooth_pb_query_phone_log_combined();
+               break;
+#ifdef TIZEN_FEATURE_BT_PBAP_SIM
+       case SIM_PB:
+               query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_SIM);
+               break;
+#endif
+       default:
+               return FALSE;
+       }
+
+       if (query == NULL)
+               return FALSE;
+
+       status = contacts_db_get_count_with_query(query, &signed_count);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_query_destroy(query);
+               return FALSE;
+       }
+
+       contacts_query_destroy(query);
+
+       if (signed_count < 0)
+               signed_count = 0;
+
+       *count = (gint) signed_count;
+
+       FN_END;
+       return TRUE;
+}
+
+void __bluetooth_pb_list_ptr_array_add(const gchar *name,
+                                               const gchar *number,
+                                               gint handle)
+{
+       FN_START;
+       gchar *temp_name = g_strdup(name);
+       gchar *temp_number = NULL;
+       if (number == NULL)
+               temp_number = g_strdup("");
+       else
+               temp_number = g_strdup(number);
+
+       _bt_read_phonebook_entries_indicator(temp_name,
+                                               temp_number, handle);
+
+       g_free(temp_name);
+       g_free(temp_number);
+       FN_END;
+}
+
+void __bluetooth_pb_list_ptr_array_add_by_name(const gchar *name,
+                                               const gchar *number,
+                                               gint handle)
+{
+       FN_START;
+       gchar *temp_name = g_strdup(name);
+       gchar *temp_number = NULL;
+       if (number == NULL)
+               temp_number = g_strdup("");
+       else
+               temp_number = g_strdup(number);
+
+       _bt_read_phonebook_entries_indicator_by_name(temp_name,
+                                               temp_number, handle);
+
+       g_free(temp_name);
+       g_free(temp_number);
+       FN_END;
+}
+
+contacts_query_h __bluetooth_pb_query_person_number(void)
+{
+       FN_START;
+       contacts_query_h query = NULL;
+
+       gint status;
+
+       status = contacts_query_create(_contacts_person_number._uri,
+                               &query);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       FN_END;
+       return query;
+}
+
+void __bluetooth_pb_get_contact_list_number(
+                                               contacts_query_h query,
+                                               gint start_index,
+                                               gint end_index,
+                                               gint *count)
+{
+       FN_START;
+       contacts_list_h record_list = NULL;
+       gint status;
+       gint i;
+       gint from;
+       gint to;
+       gint offset;
+
+       from = start_index;
+       to = end_index;
+
+       if (from < 1)
+               from = 1;
+
+       if (to < 1)
+               to = 1;
+
+       offset = to - from + 1;
+       if (offset <= 0)
+               return;
+
+       i = from;
+
+       status = contacts_db_get_records_with_query(query,
+                       from - 1 , offset,
+                       &record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       status = contacts_list_first(record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       do {
+               contacts_record_h record;
+
+               gchar *display_name;
+               gchar *number;
+
+               record = NULL;
+               status = contacts_list_get_current_record_p(record_list,
+                               &record);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               display_name = NULL;
+               number = NULL;
+
+               contacts_record_get_str_p(record,
+                               _contacts_person_number.display_name,
+                               &display_name);
+               contacts_record_get_str_p(record,
+                               _contacts_person_number.number,
+                               &number);
+
+               __bluetooth_pb_list_ptr_array_add(display_name, number, i);
+
+               i++;
+       } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+       *count = i;
+
+       contacts_list_destroy(record_list, TRUE);
+       FN_END;
+}
+
+#ifdef TIZEN_FEATURE_BT_PBAP_SIM
+static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact)
+{
+       FN_START;
+       gint count = 0;
+
+       gint status;
+       gint i;
+
+       gchar *str = NULL;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.number,
+                       &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h number = NULL;
+
+               gchar *tmp = NULL;
+
+               bool is_default = false;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.number, i, &number);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               status = contacts_record_get_bool(number,
+                               _contacts_number.is_default,
+                               &is_default);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               if (is_default == FALSE)
+                       continue;
+
+               status = contacts_record_get_str_p(number,
+                               _contacts_number.number,
+                               &tmp);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               if (tmp) {
+                       str = g_strdup(tmp);
+                       break;
+               }
+       }
+
+       /* get first number */
+       if (str == NULL) {
+               gchar *tmp = NULL;
+
+               contacts_record_h number = NULL;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.number, 0, &number);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       return NULL;
+
+               status = contacts_record_get_str_p(number,
+                               _contacts_number.number,
+                               &tmp);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       return NULL;
+
+               str = g_strdup(tmp);
+       }
+
+       FN_END;
+       return str;
+}
+
+gchar *_bluetooth_pb_number_from_person_id(gint person_id)
+{
+       FN_START;
+       contacts_record_h person = NULL;
+       contacts_record_h contact = NULL;
+
+       gint status;
+       gint contact_id = 0;
+
+       gchar *str;
+
+       status = contacts_db_get_record(_contacts_person._uri,
+                       person_id,
+                       &person);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+
+       status = contacts_record_get_int(person,
+                       _contacts_person.display_contact_id,
+                       &contact_id);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_record_destroy(person, TRUE);
+               return NULL;
+       }
+
+       status = contacts_db_get_record(_contacts_contact._uri,
+                       contact_id,
+                       &contact);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_record_destroy(person, TRUE);
+               return NULL;
+       }
+
+       str = __bluetooth_pb_number_from_contact(contact);
+
+       contacts_record_destroy(contact, TRUE);
+       contacts_record_destroy(person, TRUE);
+
+       FN_END;
+       return str;
+}
+
+gchar *_bluetooth_pb_name_from_person_id(gint person_id)
+{
+       FN_START;
+       contacts_record_h person = NULL;
+       contacts_record_h contact = NULL;
+
+       gint status;
+       gint contact_id = 0;
+
+       gchar *str;
+
+       status = contacts_db_get_record(_contacts_person._uri,
+                       person_id,
+                       &person);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_record_get_int(person,
+                       _contacts_person.display_contact_id,
+                       &contact_id);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_record_destroy(person, TRUE);
+               return NULL;
+       }
+
+       status = contacts_db_get_record(_contacts_contact._uri,
+                       contact_id,
+                       &contact);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_record_destroy(person, TRUE);
+               return NULL;
+       }
+
+       str = __bluetooth_pb_name_from_contact(contact);
+
+       contacts_record_destroy(contact, TRUE);
+       contacts_record_destroy(person, TRUE);
+
+       FN_END;
+       return str;
+}
+
+static gchar *__bluetooth_pb_vcard_escape(const gchar *str)
+{
+       FN_START;
+       GString *escaped;
+
+       gchar *st = NULL;
+       gchar *pos = NULL;
+
+       if (str == NULL)
+               return NULL;
+
+       escaped = g_string_new(NULL);
+
+       st = (gchar *)str;
+       pos = st;
+
+       while (*pos != '\0') {
+               if (*pos == ';') {
+                       g_string_append_len(escaped, st, (pos - st));
+                       g_string_append(escaped, "\\;");
+
+                       pos++;
+                       st = pos;
+               } else {
+                       pos++;
+               }
+       }
+
+       g_string_append_len(escaped, st, (pos - st));
+       FN_END;
+       return g_string_free(escaped, FALSE);
+}
+
+static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact)
+{
+       FN_START;
+       contacts_record_h name = NULL;
+
+       GString *str;
+
+       gint status;
+       gint i;
+
+       gint name_size = 5;
+       gint name_val[] = { _contacts_name.last,
+                       _contacts_name.first,
+                       _contacts_name.addition,
+                       _contacts_name.prefix,
+                       _contacts_name.suffix };
+
+
+       status = contacts_record_get_child_record_at_p(contact,
+                       _contacts_contact.name, 0, &name);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       str = g_string_new(NULL);
+
+       for (i = 0; i < name_size; i++) {
+               gchar *tmp = NULL;
+               gchar *escape = NULL;
+
+               status = contacts_record_get_str_p(name, name_val[i], &tmp);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               escape = __bluetooth_pb_vcard_escape(tmp);
+
+               g_string_append(str, escape);
+
+               g_free(escape);
+       }
+
+       FN_END;
+       return g_string_free(str, FALSE);
+}
+
+static void __bluetooth_pb_get_contact_list(
+                                       contacts_query_h query,
+                                       gint start_index,
+                                       gint end_index,
+                                       gint *count)
+{
+       FN_START;
+       contacts_list_h record_list = NULL;
+       gint i = 0;
+
+       gint status;
+
+       status = contacts_db_get_records_with_query(query,
+                       start_index, end_index, &record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       status = contacts_list_first(record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       do {
+               contacts_record_h record;
+
+               gint id;
+
+               record = NULL;
+               status = contacts_list_get_current_record_p(record_list,
+                               &record);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               id = 0;
+               status = contacts_record_get_int(record,
+                               _contacts_person_contact.person_id,
+                               &id);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               gchar *name;
+               gchar *number;
+
+               name = _bluetooth_pb_name_from_person_id(id);
+               number = _bluetooth_pb_number_from_person_id(id);
+
+               __bluetooth_pb_list_ptr_array_add(name, number, id);
+               i++;
+
+               g_free(name);
+               g_free(number);
+
+       } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+
+       *count = i;
+       contacts_list_destroy(record_list, TRUE);
+       FN_END;
+}
+
+static void __bluetooth_pb_get_contact_list_by_name(
+                                       contacts_query_h query,
+                                       gint start_index,
+                                       gint end_index,
+                                       const char *str,
+                                       gint *count)
+{
+       FN_START;
+       contacts_list_h record_list = NULL;
+       gint i = 0;
+       contacts_record_h record;
+       gint id;
+       gint status;
+       gchar *name;
+       gchar *number;
+       char *pb_name_up;
+
+       status = contacts_db_get_records_with_query(query,
+                       start_index, end_index, &record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       status = contacts_list_first(record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       do {
+               record = NULL;
+               status = contacts_list_get_current_record_p(record_list,
+                               &record);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               id = 0;
+               status = contacts_record_get_int(record,
+                               _contacts_person_contact.person_id,
+                               &id);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               name = _bluetooth_pb_name_from_person_id(id);
+               number = _bluetooth_pb_number_from_person_id(id);
+               pb_name_up = g_ascii_strup(name, strlen(name));
+
+               if (g_strstr_len(pb_name_up, -1, str) != NULL)
+                       __bluetooth_pb_list_ptr_array_add_by_name(name, number, id);
+
+               g_free(pb_name_up);
+               i++;
+
+               g_free(name);
+               g_free(number);
+
+       } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+
+       *count = i;
+       contacts_list_destroy(record_list, TRUE);
+       FN_END;
+}
+#endif
+
+static contacts_query_h __bluetooth_pb_query_phone_log_incoming(void)
+{
+       FN_START;
+       gint size = 4;
+       gint match[] = {
+               CONTACTS_PLOG_TYPE_VOICE_INCOMMING,
+               CONTACTS_PLOG_TYPE_VIDEO_INCOMMING,
+               CONTACTS_PLOG_TYPE_VOICE_REJECT,
+               CONTACTS_PLOG_TYPE_VIDEO_REJECT
+       };
+
+       FN_END;
+       return __bluetooth_pb_query_phone_log(match, size);
+}
+
+static contacts_query_h __bluetooth_pb_query_phone_log_outgoing(void)
+{
+       FN_START;
+       gint size = 2;
+       gint match[] = {
+               CONTACTS_PLOG_TYPE_VOICE_OUTGOING,
+               CONTACTS_PLOG_TYPE_VIDEO_OUTGOING
+       };
+
+       FN_END;
+       return __bluetooth_pb_query_phone_log(match, size);
+}
+
+static contacts_query_h __bluetooth_pb_query_phone_log_missed(void)
+{
+       FN_START;
+       gint size = 4;
+       gint match[] = {
+               CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN,
+               CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN,
+               CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN,
+               CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN
+       };
+
+       FN_END;
+       return __bluetooth_pb_query_phone_log(match, size);
+}
+
+static contacts_query_h __bluetooth_pb_query_phone_log_combined(void)
+{
+       FN_START;
+       gint size = 10;
+       gint match[] = {
+               CONTACTS_PLOG_TYPE_VOICE_INCOMMING,
+               CONTACTS_PLOG_TYPE_VIDEO_INCOMMING,
+               CONTACTS_PLOG_TYPE_VOICE_OUTGOING,
+               CONTACTS_PLOG_TYPE_VIDEO_OUTGOING,
+               CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN,
+               CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN,
+               CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN,
+               CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN,
+               CONTACTS_PLOG_TYPE_VOICE_REJECT,
+               CONTACTS_PLOG_TYPE_VIDEO_REJECT
+       };
+
+       FN_END;
+       return __bluetooth_pb_query_phone_log(match, size);
+}
+
+
+gint __bluetooth_pb_phone_log_filter_append(contacts_filter_h filter,
+                                               gint *match,
+                                               gint size)
+{
+       FN_START;
+       gint i;
+       gint status;
+
+       for (i = 0; i < size; i++) {
+
+               if (i > 0) {
+                       status = contacts_filter_add_operator(filter,
+                                       CONTACTS_FILTER_OPERATOR_OR);
+
+                       if (status != CONTACTS_ERROR_NONE)
+                               return status;
+               }
+
+               status = contacts_filter_add_int(filter,
+                               _contacts_phone_log.log_type,
+                               CONTACTS_MATCH_EQUAL,
+                               match[i]);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       return status;
+       }
+
+       FN_END;
+       return CONTACTS_ERROR_NONE;
+}
+
+contacts_query_h __bluetooth_pb_query_phone_log(gint *match,
+                                               gint size)
+{
+       FN_START;
+       contacts_query_h query = NULL;
+       contacts_filter_h filter = NULL;
+
+       gint status;
+
+       status = contacts_query_create(_contacts_phone_log._uri,
+                               &query);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_filter_create(_contacts_phone_log._uri, &filter);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_query_destroy(query);
+               return NULL;
+       }
+
+       status = __bluetooth_pb_phone_log_filter_append(filter, match, size);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_filter_destroy(filter);
+               contacts_query_destroy(query);
+               return NULL;
+       }
+
+       status = contacts_query_set_filter(query, filter);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_filter_destroy(filter);
+               contacts_query_destroy(query);
+               return NULL;
+       }
+
+       status = contacts_query_set_sort(query,
+                       _contacts_phone_log.log_time,
+                       false);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_filter_destroy(filter);
+               contacts_query_destroy(query);
+               return NULL;
+       }
+
+       contacts_filter_destroy(filter);
+
+       FN_END;
+       return query;
+}
+
+static gint __bluetooth_pb_person_id_from_phonelog_id(gint phonelog_id)
+{
+       FN_START;
+       contacts_query_h query = NULL;
+       contacts_filter_h filter = NULL;
+       contacts_list_h record_list = NULL;
+
+       contacts_record_h phone_log = NULL;
+       contacts_record_h record = NULL;
+
+       gint status;
+       gint person_id = 0;
+
+       status = contacts_db_get_record(_contacts_phone_log._uri,
+                       phonelog_id,
+                       &phone_log);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return 0;
+
+       status = contacts_record_get_int(phone_log,
+                       _contacts_phone_log.person_id,
+                       &person_id);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_record_destroy(phone_log, TRUE);
+               return 0;
+       }
+
+       contacts_record_destroy(phone_log, TRUE);
+
+       if (person_id)
+               return person_id;
+
+       status = contacts_filter_create(_contacts_person_phone_log._uri,
+                       &filter);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return 0;
+
+
+       status = contacts_filter_add_int(filter,
+                       _contacts_person_phone_log.log_id,
+                       CONTACTS_MATCH_EQUAL,
+                       phonelog_id);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+       status = contacts_query_create(_contacts_person_phone_log._uri, &query);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+       status = contacts_query_set_filter(query, filter);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+       status = contacts_db_get_records_with_query(query, -1, -1,
+                                                               &record_list);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+       status = contacts_list_first(record_list);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+       status = contacts_list_get_current_record_p(record_list, &record);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+       status = contacts_record_get_int(record,
+                       _contacts_person_phone_log.person_id,
+                       &person_id);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+done:
+       if (record_list != NULL)
+               contacts_list_destroy(record_list, TRUE);
+
+       contacts_filter_destroy(filter);
+
+       if (query != NULL)
+               contacts_query_destroy(query);
+
+       FN_END;
+       return person_id;
+}
+
+gchar *_bluetooth_pb_fn_from_person_id(gint person_id)
+{
+       FN_START;
+       contacts_record_h person = NULL;
+
+       gint status;
+
+       gchar *str = NULL;
+
+       status = contacts_db_get_record(_contacts_person._uri,
+                       person_id,
+                       &person);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_record_get_str(person,
+                       _contacts_person.display_name,
+                       &str);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       contacts_record_destroy(person, TRUE);
+
+       FN_END;
+       return str;
+}
+
+gchar *_bluetooth_pb_fn_from_phonelog_id(gint phonelog_id)
+{
+       FN_START;
+       gint person_id = 0;
+       gchar *str = NULL;
+
+       person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
+
+       if (person_id > 0)
+               str = _bluetooth_pb_fn_from_person_id(person_id);
+       else
+               str = g_strdup("");
+
+       FN_END;
+       return str;
+}
+
+
+static void __bluetooth_pb_get_phone_log_list_number(contacts_query_h query,
+                                               gint start_index,
+                                               gint end_index,
+                                               int *count)
+{
+       FN_START;
+       contacts_list_h record_list = NULL;
+
+       gint status;
+
+       gint i;
+
+       gint from;
+       gint to;
+       gint offset;
+
+       from = start_index;
+       to = end_index;
+
+       if (from < 1)
+               from = 1;
+
+       if (to < 1)
+               to = 1;
+
+       offset = to - from + 1;
+       if (offset <= 0)
+               return;
+
+       i = from;
+
+       status = contacts_db_get_records_with_query(query,
+                       from - 1 , offset,
+                       &record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       status = contacts_list_first(record_list);
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       do {
+               contacts_record_h record = NULL;
+
+               gint id;
+
+               gchar *display_name;
+               gchar *number;
+
+               record = NULL;
+               status = contacts_list_get_current_record_p(record_list,
+                               &record);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               id = 0;
+               status = contacts_record_get_int(record,
+                               _contacts_phone_log.id,
+                               &id);
+               if (status != CONTACTS_ERROR_NONE) {
+                       ERR("contact_record_get_int api failed %d", status);
+                       continue;
+               }
+
+               display_name = _bluetooth_pb_fn_from_phonelog_id(id);
+
+               number = NULL;
+               contacts_record_get_str_p(record,
+                               _contacts_phone_log.address,
+                               &number);
+
+
+               __bluetooth_pb_list_ptr_array_add(display_name, number, i);
+
+               i++;
+
+               g_free(display_name);
+
+       } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+       *count = i;
+
+       contacts_list_destroy(record_list, TRUE);
+       FN_END;
+}
+
+void __bluetooth_pb_get_list_entries_by_name(
+                                               PhoneBookType pb_type,
+                                               gint start_index,
+                                               gint end_index,
+                                               const char *str,
+                                               gint *count)
+{
+       FN_START;
+       contacts_query_h query;
+
+       switch (pb_type) {
+       case TELECOM_PB:
+               query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_PHONE);
+               __bluetooth_pb_get_contact_list_by_name(query,
+                               start_index, end_index, str, count);
+               break;
+
+       case TELECOM_ICH:
+               query = __bluetooth_pb_query_phone_log_incoming();
+               __bluetooth_pb_get_contact_list_by_name(query,
+                               start_index, end_index, str, count);
+               break;
+       case TELECOM_OCH:
+               query = __bluetooth_pb_query_phone_log_outgoing();
+               __bluetooth_pb_get_contact_list_by_name(query,
+                               start_index, end_index, str, count);
+               break;
+       case TELECOM_MCH:
+               query = __bluetooth_pb_query_phone_log_missed();
+               __bluetooth_pb_get_contact_list_by_name(query,
+                               start_index, end_index, str, count);
+               break;
+       case TELECOM_CCH:
+               query = __bluetooth_pb_query_phone_log_combined();
+               __bluetooth_pb_get_contact_list_by_name(query,
+                               start_index, end_index, str, count);
+               break;
+#ifdef TIZEN_FEATURE_BT_PBAP_SIM
+       case SIM_PB:
+               query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_SIM);
+               __bluetooth_pb_get_contact_list_by_name(query,
+                       start_index, end_index, str, count);
+               break;
+#endif
+       default:
+               return;
+       }
+
+       if (query)
+               contacts_query_destroy(query);
+       FN_END;
+}
+
+void __bluetooth_pb_get_list_number(
+                                               PhoneBookType pb_type,
+                                               gint start_index,
+                                               gint end_index,
+                                               gint *count)
+{
+       FN_START;
+       contacts_query_h query;
+
+       switch (pb_type) {
+       case TELECOM_PB:
+               query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_PHONE);
+               __bluetooth_pb_get_contact_list(query,
+                               start_index, end_index, count);
+               break;
+
+       case TELECOM_ICH:
+               query = __bluetooth_pb_query_phone_log_incoming();
+               __bluetooth_pb_get_phone_log_list_number(query,
+                               start_index, end_index, count);
+               break;
+       case TELECOM_OCH:
+               query = __bluetooth_pb_query_phone_log_outgoing();
+               __bluetooth_pb_get_phone_log_list_number(query,
+                               start_index, end_index, count);
+               break;
+       case TELECOM_MCH:
+               query = __bluetooth_pb_query_phone_log_missed();
+               __bluetooth_pb_get_phone_log_list_number(query,
+                               start_index, end_index, count);
+               break;
+       case TELECOM_CCH:
+               query = __bluetooth_pb_query_phone_log_combined();
+               __bluetooth_pb_get_phone_log_list_number(query,
+                               start_index, end_index, count);
+               break;
+#ifdef TIZEN_FEATURE_BT_PBAP_SIM
+       case SIM_PB:
+               query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_SIM);
+               __bluetooth_pb_get_contact_list(query,
+                       start_index, end_index, count);
+               break;
+#endif
+       default:
+               return;
+       }
+
+       if (query)
+               contacts_query_destroy(query);
+       FN_END;
+}
+
+
diff --git a/ag-agent/bluetooth-ag-phonebook.h b/ag-agent/bluetooth-ag-phonebook.h
new file mode 100644 (file)
index 0000000..bf02f6e
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * bluetooth-ag-phonebook.h
+ *
+ * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:    Hocheol Seo <hocheol.seo@samsung.com>
+ *             Sangki Park<sangki79.park@samsung.com>
+ *             Chanyeol Park <chanyeol.park@samsung.com>
+ *             Rakesh MK <rakesh.mk@samsung.com>
+ *             Anurag B <biradar.a@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <contacts.h>
+#include <contacts_record.h>
+#include <TapiUtility.h>
+#include <ITapiSim.h>
+
+typedef enum {
+       TELECOM_PB = 0,
+       TELECOM_ICH,
+       TELECOM_OCH,
+       TELECOM_MCH,
+       TELECOM_CCH,
+#ifdef TIZEN_FEATURE_BT_PBAP_SIM
+       SIM_PB,
+#endif
+       TELECOM_NONE
+} PhoneBookType;
+
+typedef enum {
+       PBAP_ADDRESSBOOK_PHONE,
+       PBAP_ADDRESSBOOK_SIM,
+} bt_pbap_addressbook_e;
+
+#define SIM_ADDRESSBOOK_PREFIX "http://tizen.org/addressbook/sim"
+
+
+PhoneBookType __bluetooth_pb_get_storage_pb_type(const char *name);
+
+contacts_query_h __bluetooth_pb_query_phone_log(gint *match,
+                                               gint size);
+
+gboolean __bluetooth_pb_get_count(PhoneBookType pb_type,
+                               guint *count);
+
+void __bluetooth_pb_get_list_number(
+                                               PhoneBookType pb_type,
+                                               gint start_index,
+                                               gint end_index,
+                                               gint *count);
+
+void __bluetooth_pb_get_list_entries_by_name(
+                                               PhoneBookType pb_type,
+                                               gint start_index,
+                                               gint end_index,
+                                               const char *str,
+                                               gint *count);
+
index 1bf622f..90435e4 100644 (file)
@@ -2895,6 +2895,24 @@ static void __bt_establish_initialization(bt_hf_agent_info_t *bt_hf_info)
        else
                ERR("BT_HF_XSAT sending failed");
 
+       if (TIZEN_PROFILE_WEARABLE) {
+               /* send Bluetooth Samsung Support Feature cmd */
+               ret = __bt_hf_send_and_read(bt_hf_info, BT_HF_BSSF, buf,
+                                                       sizeof(BT_HF_BSSF) - 1);
+
+               /* If we got a 'OK' reply, peer AG is samsung device.
+                * Otherwise, non-samsung device */
+               if (ret && strstr(buf, "OK"))
+                       bt_hf_info->is_companion_dev = TRUE;
+               else
+                       bt_hf_info->is_companion_dev = FALSE;
+
+               if (ret)
+                       INFO("SLC completed with [%s] device",
+                               bt_hf_info->is_companion_dev ? "SS Companion" : "Other");
+               else
+                       ERR("BT_HF_BSSF sending failed");
+       }
 }
 
 static void __bt_hf_agent_sigterm_handler(int signo)
index b5b51d6..1252960 100644 (file)
@@ -276,6 +276,8 @@ typedef struct {
        gboolean is_dialing;
        gboolean call_active;
        gboolean inband_ringtone_support;
+       gboolean is_companion_dev;
+
        guint ciev_call_status;
        guint ciev_call_setup_status;
 
index a6c56a6..937288c 100644 (file)
@@ -24,7 +24,7 @@ BuildRequires:  pkgconfig(capi-appfw-app-manager)
 BuildRequires:  pkgconfig(capi-system-device)
 %endif
 # This usage of profile macro does NOT conflict 4.0 configurability.
-%if "%{?profile}" != "wearable" && "%{?profile}" != "ivi"
+%if "%{?profile}" != "ivi"
 # Original: common, mobile, tv. Added: "undefined"
 BuildRequires:  pkgconfig(contacts-service2)
 BuildRequires:  pkgconfig(msg-service)
@@ -33,8 +33,11 @@ BuildRequires:  pkgconfig(email-service)
 BuildRequires:  pkgconfig(capi-system-info)
 BuildRequires:  pkgconfig(dbus-glib-1)
 BuildRequires:  pkgconfig(tapi)
+BuildRequires:  pkgconfig(capi-system-device)
 BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(vconf)
+BuildRequires:  pkgconfig(syspopup-caller)
+BuildRequires:  pkgconfig(capi-network-bluetooth)
 BuildRequires:  pkgconfig(appsvc)
 BuildRequires:  pkgconfig(capi-appfw-application)
 BuildRequires:  pkgconfig(capi-network-connection)
@@ -93,9 +96,9 @@ cp %{SOURCE1001} .
 export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
 export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
 export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
+
 #export CFLAGS="$CFLAGS -DTIZEN_FEATURE_BT_MEDIA_ENHANCE"
-export CFLAGS="$CFLAGS -DTIZEN_FEATURE_BT_HFP_AG"
-export CFLAGS="$CFLAGS -DTIZEN_SUPPORT_DUAL_HF"
+#export CFLAGS="$CFLAGS -DTIZEN_SUPPORT_DUAL_HF"
 
 %ifarch aarch64
 echo arch64
@@ -111,15 +114,15 @@ export CXXFLAGS+=" -DARCH64"
 export FFLAGS+=" -DARCH64"
 %endif
 
-export CFLAGS+=" -fpie -DTIZEN_FEATURE_BP_PBAP_SIM -fvisibility=hidden "
-export CXXFLAGS+=" -fpie -DTIZEN_FEATURE_BP_PBAP_SIM -fvisibility=hidden "
+export CFLAGS+=" -fpie -DTIZEN_FEATURE_BT_PBAP_SIM -fvisibility=hidden "
+export CXXFLAGS+=" -fpie -DTIZEN_FEATURE_BT_PBAP_SIM -fvisibility=hidden "
 
 export LDFLAGS+=" -Wl,--rpath=/usr/lib -Wl,--as-needed -Wl,--unresolved-symbols=ignore-in-shared-libs -pie"
 
 export CFLAGS_DEFAULT="$CFLAGS"
 
 # Build All (wearalbe/ivi/common/tv/mobile)
-cmake . -DCMAKE_INSTALL_PREFIX=/usr -DTIZEN_FEATURE_BT_HFP_AG=1
+cmake . -DCMAKE_INSTALL_PREFIX=/usr
 make VERBOSE=1
 
 %install