Add BT agent functionality on Tizen 3.0 49/43649/1 accepted/tizen/mobile/20150713.060931 accepted/tizen/tv/20150713.060937 accepted/tizen/wearable/20150713.060953 submit/tizen/20150713.033424
authorDoHyun Pyun <dh79.pyun@samsung.com>
Mon, 13 Jul 2015 03:33:07 +0000 (12:33 +0900)
committerDoHyun Pyun <dh79.pyun@samsung.com>
Mon, 13 Jul 2015 03:33:07 +0000 (12:33 +0900)
Change-Id: Ib768698e22fac81e9da3d160c940efad86427a1d
Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
33 files changed:
CMakeLists.txt
ag-agent/CMakeLists.txt [new file with mode: 0644]
ag-agent/bluetooth-ag-agent.c [new file with mode: 0644]
ag-agent/bluetooth-ag-agent.h [new file with mode: 0644]
ag-agent/bluetooth-ag-handler.c [new file with mode: 0644]
ag-agent/bluetooth-ag-handler.h [new file with mode: 0644]
ag-agent/bluetooth-ag-manager.c [new file with mode: 0644]
ag-agent/org.bluez.ag_agent.service [new file with mode: 0644]
ag-agent/voice-recognition-blacklist [new file with mode: 0644]
hf-agent/CMakeLists.txt [new file with mode: 0644]
hf-agent/bluetooth-hf-agent.c [new file with mode: 0644]
hf-agent/bluetooth-hf-agent.h [new file with mode: 0644]
hf-agent/org.bluez.hf_agent.service [new file with mode: 0644]
hfp-agent/CMakeLists.txt [deleted file]
hfp-agent/bluetooth-hfp-agent.c [deleted file]
hfp-agent/bluetooth-hfp-agent.h [deleted file]
hfp-agent/hfp_agent.xml [deleted file]
hfp-agent/org.bluez.hfp_agent.service [deleted file]
map-agent/CMakeLists.txt
map-agent/bluetooth_map_agent.c
map-agent/bluetooth_map_agent.h
map-agent/bluetooth_map_agent.xml
map-agent/map_bmessage.c
map-agent/map_bmessage.h
map-agent/org.bluez.map_agent.service
packaging/bluetooth-agent.spec
pb-agent/CMakeLists.txt
pb-agent/bluetooth_pb_agent.c
pb-agent/bluetooth_pb_agent.h
pb-agent/bluetooth_pb_agent.xml
pb-agent/bluetooth_pb_vcard.c
pb-agent/bluetooth_pb_vcard.h
pb-agent/org.bluez.pb_agent.service

index fe09c62..e6a08f4 100644 (file)
@@ -1,7 +1,11 @@
 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
 
+IF (TIZEN_WEARABLE)
+ADD_SUBDIRECTORY(hf-agent)
+ELSE (TIZEN_WEARABLE)
 ADD_SUBDIRECTORY(map-agent)
-
-#ADD_SUBDIRECTORY(pb-agent)
-
-#ADD_SUBDIRECTORY(hfp-agent)
+ADD_SUBDIRECTORY(pb-agent)
+IF (TIZEN_BT_HFP_AG_ENABLE)
+ADD_SUBDIRECTORY(ag-agent)
+ENDIF (TIZEN_BT_HFP_AG_ENABLE)
+ENDIF (TIZEN_WEARABLE)
diff --git a/ag-agent/CMakeLists.txt b/ag-agent/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a0f9781
--- /dev/null
@@ -0,0 +1,46 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(bluetooth-ag-agent C)
+
+SET(SRCS bluetooth-ag-agent.c
+                       bluetooth-ag-handler.c
+                       bluetooth-ag-manager.c)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+SET(PKG_MODULES
+       dlog
+       dbus-glib-1
+       vconf
+       appsvc
+       contacts-service2
+       tapi
+       capi-appfw-application
+       aul
+       capi-system-info
+       glib-2.0
+       gio-2.0
+       gio-unix-2.0
+)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs_ag_agent REQUIRED ${PKG_MODULES})
+
+FOREACH(flag ${pkgs_ag_agent_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+SET(APP_SYSCONFDIR /opt/var/lib/bluetooth)
+
+ADD_DEFINITIONS("-DAPP_SYSCONFDIR=\"${APP_SYSCONFDIR}\"")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_ag_agent_LDFLAGS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.bluez.ag_agent.service
+               DESTINATION share/dbus-1/system-services)
+
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/voice-recognition-blacklist
+               DESTINATION /opt/var/lib/bluetooth/)
diff --git a/ag-agent/bluetooth-ag-agent.c b/ag-agent/bluetooth-ag-agent.c
new file mode 100644 (file)
index 0000000..ff5b9c8
--- /dev/null
@@ -0,0 +1,4388 @@
+/*
+ * Bluetooth-ag-agent
+ *
+ * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:    Hocheol Seo <hocheol.seo@samsung.com>
+ *             Chethan T N <chethan.tn@samsung.com>
+ *             Chanyeol Park <chanyeol.park@samsung.com>
+ *             Rakesh MK <rakesh.mk@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 <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/poll.h>
+#include <gio/gunixfdlist.h>
+#include <bundle_internal.h>
+#include "bluetooth-ag-agent.h"
+#include "bluetooth-ag-handler.h"
+
+#include <TapiUtility.h>
+#include <ITapiSim.h>
+#include <ITapiModem.h>
+#include <TelNetwork.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 int owner_sig_id = -1;
+static int name_owner_sig_id = -1;
+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;
+extern wbs_options wbs_opts;
+GSList *active_devices = NULL;
+static gchar *local_addr = NULL;
+static GDBusProxy *app_gproxy;
+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 guint hf_bluez_id;
+static guint hs_bluez_id;
+static guint app_id;
+#ifdef TIZEN_MEDIA_ENHANCE
+static int media_sig_id = -1;
+static int media_state_sig_id = -1;
+static bt_ag_media_transport_state_t transport_state;
+#endif
+
+#define HSP_AG_UUID "00001112-0000-1000-8000-00805f9b34fb"
+#define HFP_AG_UUID "0000111f-0000-1000-8000-00805f9b34fb"
+#ifdef TIZEN_MEDIA_ENHANCE
+#define A2DP_SINK_UUID "0000110b-0000-1000-8000-00805f9b34fb"
+#endif
+#define DEFAULT_ADAPTER_OBJECT_PATH "/org/bluez/hci0"
+
+#ifdef TIZEN_SUPPORT_LUNAR_DEVICE
+#define VCONF_KEY_BT_LUNAR_ENABLED "db/wms/bt_loop_device_hfp_connected"
+#endif
+
+#if defined(TIZEN_WEARABLE) && defined(TIZEN_BT_HFP_AG_ENABLE)
+#define CALL_APP_ID "org.tizen.call-ui"
+#endif
+
+#if defined(TIZEN_SUPPORT_DUAL_HF)
+#define VCONF_KEY_BT_HOST_BT_MAC_ADDR "db/wms/host_bt_mac"
+#define MAX_CONNECTED_DEVICES 2
+#else
+#define MAX_CONNECTED_DEVICES 1
+#endif
+
+#define BT_AG_SIG_NUM 3
+static struct sigaction bt_ag_sigoldact[BT_AG_SIG_NUM];
+static int bt_ag_sig_to_handle[] = { SIGABRT, SIGSEGV, SIGTERM };
+
+/*Below Inrospection data is exposed to bluez from agent*/
+static const gchar ag_agent_bluez_introspection_xml[] =
+"<node name='/'>"
+" <interface name='org.bluez.Profile1'>"
+"     <method name='NewConnection'>"
+"          <arg type='o' name='device' direction='in'/>"
+"          <arg type='h' name='fd' direction='in'/>"
+"          <arg type='a{sv}' name='options' direction='in'/>"
+"     </method>"
+"     <method name='RequestDisconnection'>"
+"          <arg type='o' name='device' direction='in'/>"
+"     </method>"
+" </interface>"
+"</node>";
+
+/*Below Introspection data is exposed to application from agent*/
+static const gchar ag_agent_app_introspection_xml[] =
+"<node name='/'>"
+"  <interface name='Org.Hfp.App.Interface'>"
+"     <method name='RegisterApplication'>"
+"          <arg type='s' name='path' direction='in'/>"
+"          <arg type='s' name='address' direction='in'/>"
+"     </method>"
+"     <method name='UnregisterApplication'>"
+"          <arg type='s' name='path' direction='in'/>"
+"     </method>"
+"     <method name='IncomingCall'>"
+"          <arg type='s' name='path' direction='in'/>"
+"          <arg type='s' name='number' direction='in'/>"
+"          <arg type='i' name='id' direction='in'/>"
+"     </method>"
+"     <method name='OutgoingCall'>"
+"          <arg type='s' name='path' direction='in'/>"
+"          <arg type='s' name='number' direction='in'/>"
+"          <arg type='i' name='id' direction='in'/>"
+"     </method>"
+"     <method name='ChangeCallStatus'>"
+"          <arg type='s' name='path' direction='in'/>"
+"          <arg type='s' name='number' direction='in'/>"
+"          <arg type='i' name='status' direction='in'/>"
+"          <arg type='i' name='id' direction='in'/>"
+"     </method>"
+"     <method name='GetProperties'>"
+"              <arg type='a{sv}' name='properties' direction='out'/>"
+"     </method>"
+"      <method name='Disconnect'>"
+"      </method>"
+"      <method name='IsConnected'>"
+"              <arg type='b' name='connected' direction='out'/>"
+"      </method>"
+"      <method name='IndicateCall'>"
+"      </method>"
+"      <method name='CancelCall'>"
+"      </method>"
+"      <method name='Play'>"
+"      </method>"
+"      <method name='Stop'>"
+"      </method>"
+"      <method name='IsPlaying'>"
+"      <arg type='b' name='playing' direction='out'/>"
+"      </method>"
+"      <method name='GetSpeakerGain'>"
+"              <arg type='q' name='gain' direction='out'/>"
+"      </method>"
+"      <method name='GetMicrophoneGain'>"
+"              <arg type='q' name='gain' direction='out'/>"
+"      </method>"
+"      <method name='SetSpeakerGain'>"
+"              <arg type='q' name='gain' direction='in'/>"
+"      </method>"
+"      <method name='SetMicrophoneGain'>"
+"              <arg type='q' name='gain' direction='in'/>"
+"      </method>"
+"      <method name='SetVoiceDial'>"
+"              <arg type='b' name='enable' direction='in'/>"
+"      </method>"
+"      <method name='CheckPrivilege'>"
+"      </method>"
+"  </interface>"
+"</node>";
+
+struct event {
+       const char *cmd;
+       int (*callback)(bt_ag_info_t *hs, const char *buf);
+};
+
+struct sco_socket_addr {
+       sa_family_t     sco_family;
+       bt_addr         sco_bdaddr;
+};
+
+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,
+       .er_mode = 3,
+       .er_ind = 0,
+       .rh = BT_RSP_HOLD_NOT_SUPPORTED,
+       .number = NULL,
+       .number_type = 0,
+       .ring_timer = 0,
+       .sdp_features = 0,
+};
+static void __bt_ag_agent_sigterm_handler(int signo);
+static gboolean __bt_ag_agent_connection(gint32 fd, const gchar *device_path,
+                                               const gchar *object_path);
+static gboolean __bt_ag_agent_connection_release(bt_ag_info_t *hs);
+static gboolean __bt_ag_event_handler(GIOChannel *channel, GIOCondition cond,
+       void *user_data);
+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 void __bt_ag_name_owner_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);
+
+static void __bt_convert_addr_type_to_rev_string(char *address,
+                               unsigned char *addr)
+{
+       ret_if(address == NULL);
+       ret_if(addr == NULL);
+
+       g_snprintf(address, BT_ADDRESS_STRING_SIZE,
+                       "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
+                       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)
+{
+       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;
+       }
+
+       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 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);
+}
+
+static int __bt_ag_agent_gdbus_method_send(const char *service,
+                               const gchar *path, const char *interface,
+                               const char *method, gboolean response,
+                               GVariant *parameters)
+{
+       FN_START;
+
+       GVariant *ret;
+       GDBusProxy *proxy;
+       GError *error = NULL;
+
+       proxy = __bt_ag_gdbus_get_app_proxy(service, path, interface);
+       if (!proxy)
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+
+       if (response) {
+               ret = g_dbus_proxy_call_sync(proxy,
+                                       method, parameters,
+                                       G_DBUS_CALL_FLAGS_NONE, -1,
+                                       NULL, &error);
+               if (ret == NULL) {
+                       /* dBUS-RPC is failed */
+                       ERR("dBUS-RPC is failed");
+                       if (error != NULL) {
+                               /* dBUS gives error cause */
+                               ERR("D-Bus API failure: errCode[%x], message[%s]",
+                                       error->code, error->message);
+
+                               g_clear_error(&error);
+                       }
+                       return BT_HFP_AGENT_ERROR_INTERNAL;
+               }
+
+               g_variant_unref(ret);
+       } else {
+               g_dbus_proxy_call(proxy,
+                                       method, parameters,
+                                       G_DBUS_CALL_FLAGS_NONE, 2000,
+                                       NULL, NULL, NULL);
+       }
+       return BT_HFP_AGENT_ERROR_NONE;
+}
+
+gboolean _bt_ag_agent_emit_signal(
+                               GDBusConnection *connection,
+                               const char *path,
+                               const char *interface,
+                               const char *name,
+                               GVariant *property)
+{
+       FN_START;
+
+       GError *error = NULL;
+       gboolean ret;
+       ret =  g_dbus_connection_emit_signal(connection,
+                               NULL, path, interface,
+                               name, property,
+                               &error);
+       if (!ret) {
+               if (error != NULL) {
+                       /* dBUS gives error cause */
+                       ERR("D-Bus API failure: errCode[%x], message[%s]",
+                               error->code, error->message);
+                       g_clear_error(&error);
+               }
+       }
+       INFO_C("Emit Signal done = [%s]", name);
+
+       FN_END;
+       return ret;
+}
+
+gboolean _bt_ag_agent_emit_property_changed(
+                               GDBusConnection *connection,
+                               const char *path,
+                               const char *interface,
+                               const char *name,
+                               GVariant *property)
+{
+       FN_START;
+
+       gboolean ret;
+       GVariant *var_data;
+
+       var_data = g_variant_new("(sv)",        name, property);
+
+       ret =  _bt_ag_agent_emit_signal(connection,
+                               path, interface,
+                               "PropertyChanged", var_data);
+       FN_END;
+       return ret;
+}
+
+static void __bt_ag_agent_start_watch(bt_ag_info_t *bt_ag_info)
+{
+       bt_ag_info->watch_id = g_io_add_watch(bt_ag_info->io_chan,
+                       G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+                       (GIOFunc) __bt_ag_event_handler, bt_ag_info);
+}
+
+static void __bt_ag_agent_remove_watch(guint *watch_id)
+{
+       DBG("Remove IO watch ID %d", *watch_id);
+       if (*watch_id > 0) {
+               g_source_remove(*watch_id);
+               *watch_id = 0;
+       }
+}
+
+#if defined(TIZEN_SUPPORT_DUAL_HF)
+gboolean __bt_ag_agent_is_companion_device(const char *addr)
+{
+#if defined(TIZEN_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 (g_strcmp0(host_device_address, addr) == 0) {
+               INFO("addr[%s] is companion device", addr);
+               return TRUE;
+       }
+
+       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,
+                                               char *device_address)
+{
+       char address[BT_ADDRESS_STRING_SIZE] = { 0 };
+       char *dev_addr;
+
+       ret_if(device_path == NULL);
+       ret_if(device_address == NULL);
+
+       dev_addr = strstr(device_path, "dev_");
+       if (dev_addr != NULL) {
+               char *pos = NULL;
+               dev_addr += 4;
+               g_strlcpy(address, dev_addr, sizeof(address));
+
+               while ((pos = strchr(address, '_')) != NULL) {
+                       *pos = ':';
+               }
+
+               g_strlcpy(device_address, address, BT_ADDRESS_STRING_SIZE);
+       }
+}
+
+static gboolean  __bt_ag_agent_is_companion_device_connected(void)
+{
+       GSList *l;
+
+       for (l = active_devices ; l; l = l->next) {
+               bt_ag_info_t *data = l->data;
+
+               if (data->is_companion_device) {
+                       DBG("Companion device found");
+                       return TRUE;
+               }
+       }
+
+       return FALSE;
+}
+
+gboolean __bt_ag_agent_check_dual_hf_condition(const gchar *device_path)
+{
+       char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
+       gboolean is_companion_device;
+
+       __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(" is_companion_device[%d]", is_companion_device);
+
+       if (__bt_ag_agent_is_companion_device_connected()) {
+               if (is_companion_device)
+                       return FALSE;
+       } else {
+               if (!is_companion_device)
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+#endif /* TIZEN_SUPPORT_DUAL_HF */
+
+static gboolean __bt_is_phone_locked(int *phone_lock_state)
+{
+       FN_START;
+       int ret;
+
+       if (NULL == phone_lock_state)
+               return FALSE;
+
+       ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, phone_lock_state);
+       if (ret != 0) {
+               ERR("Failed to read  [%s]\n", VCONFKEY_IDLE_LOCK_STATE);
+               return FALSE;
+       }
+
+       FN_END;
+       return TRUE;
+}
+
+static gboolean __bt_get_outgoing_callapp_type(int *callapp_type)
+{
+       FN_START;
+
+       if (NULL == callapp_type)
+               return FALSE;
+
+#if defined(TIZEN_WEARABLE) && defined(TIZEN_BT_HFP_AG_ENABLE)
+       *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)
+{
+       FN_START;
+
+       if (NULL == condition)
+               return FALSE;
+
+#if defined(TIZEN_WEARABLE) && defined(TIZEN_BT_HFP_AG_ENABLE)
+       *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
+}
+
+#if defined(TIZEN_WEARABLE) && defined(TIZEN_TELEPHONY_ENABLED)
+static gboolean  __bt_ag_agent_launch_call_app(const char *number)
+{
+       FN_START;
+       bundle *b;
+
+       DBG_SECURE("number(%s)", number);
+
+       b = bundle_create();
+       if (NULL == b) {
+               ERR("bundle_create() Failed");
+               return FALSE;
+       }
+
+       bundle_add(b, "launch-type", "MO");
+       bundle_add(b, "dial-type", "HEADSET");
+
+       if (strlen(number) != 0)
+               bundle_add(b, "number", number);
+
+       aul_launch_app_async(CALL_APP_ID, b);
+       bundle_free(b);
+
+       FN_END;
+       return TRUE;
+}
+#endif
+
+static void *__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;
+}
+
+static gboolean __bt_ag_agent_make_call(const char *number)
+{
+       FN_START;
+
+#if defined(TIZEN_WEARABLE) && defined(TIZEN_BT_HFP_AG_ENABLE)
+       FN_END;
+       return __bt_ag_agent_launch_call_app(number);
+#else
+       char telnum[BT_MAX_TEL_NUM_STRING];
+       bundle *b;
+       pthread_t thread_id;
+
+       if (call_launch_requested == TRUE) {
+               DBG("Launch request is in progress");
+               return TRUE;
+       }
+
+       b = bundle_create();
+       if (NULL == b)
+               return FALSE;
+
+       appsvc_set_operation(b, APPSVC_OPERATION_CALL);
+       snprintf(telnum, sizeof(telnum), "tel:%s", number);
+       appsvc_set_uri(b, telnum);
+       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");
+
+       FN_END;
+       return TRUE;
+#endif
+}
+
+static gboolean __bt_ag_agent_make_video_call(const char *mo_number)
+{
+       FN_START;
+       bundle *kb;
+
+       kb = bundle_create();
+       if (NULL == kb)
+               return FALSE;
+
+       bundle_add(kb, "KEY_CALL_TYPE", "MO");
+       bundle_add(kb, "number", mo_number);
+       aul_launch_app("org.tizen.vtmain", kb);
+       bundle_free(kb);
+
+       FN_END;
+       return TRUE;
+}
+
+gboolean _bt_ag_agent_answer_call(unsigned int call_id,
+                               const gchar *path, const gchar *sender)
+{
+       FN_START;
+
+       if (path == NULL || sender == NULL) {
+               DBG("Invalid Arguments");
+               return FALSE;
+       }
+
+       DBG("Application path = %s", path);
+       DBG("Call Id = %d", call_id);
+       DBG("Sender = %s", sender);
+
+       _bt_ag_agent_emit_signal(ag_dbus_conn, path,
+                                       BT_AG_SERVICE_NAME, "Answer",
+                                       g_variant_new("(u)", call_id));
+       FN_END;
+       return TRUE;
+}
+
+gboolean _bt_ag_agent_reject_call(unsigned int call_id,
+                               const gchar *path, const gchar *sender)
+{
+       FN_START;
+
+       if (path == NULL || sender == NULL) {
+               DBG("Invalid Arguments");
+               return FALSE;
+       }
+
+       DBG("Application path = %s", path);
+       DBG("Call Id = %d", call_id);
+       DBG("Sender = %s", sender);
+
+       _bt_ag_agent_emit_signal(ag_dbus_conn, path,
+                                       BT_AG_SERVICE_NAME, "Reject",
+                                       g_variant_new("(u)", call_id));
+       FN_END;
+       return TRUE;
+}
+
+gboolean _bt_ag_agent_release_call(unsigned int call_id,
+                               const gchar *path, const gchar *sender)
+{
+       FN_START;
+
+       if (path == NULL || sender == NULL) {
+               DBG("Invalid Arguments");
+               return FALSE;
+       }
+
+       DBG("Application path = %s", path);
+       DBG("Call Id = %d", call_id);
+       DBG("Sender = %s", sender);
+
+       _bt_ag_agent_emit_signal(ag_dbus_conn, path,
+                                       BT_AG_SERVICE_NAME, "Release",
+                                       g_variant_new("(u)", call_id));
+
+       FN_END;
+       return TRUE;
+}
+
+bt_hfp_agent_error_t _bt_ag_agent_dial_num(const gchar *number, guint flags)
+{
+       bt_hfp_agent_error_t error_code = BT_HFP_AGENT_ERROR_NONE;
+       int callapp_type;
+       int phone_lock_state;
+       int condition;
+
+       FN_START;
+
+       if (number == NULL) {
+               ERR("Invalid Argument");
+               error_code = BT_HFP_AGENT_ERROR_INVALID_PARAM;
+               goto fail;
+       }
+
+       DBG("Number = %s", number);
+       DBG("flags = %d", flags);
+
+       if (!__bt_is_phone_locked(&phone_lock_state)) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto fail;
+       }
+
+       if (!__bt_get_outgoing_callapp_type(&callapp_type)) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto fail;
+       }
+
+       if (!__bt_get_outgoing_call_condition(&condition)) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto fail;
+       }
+
+       if (condition == BT_MO_ONLY_UNLOCKED && phone_lock_state ==
+               VCONFKEY_IDLE_LOCK) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto fail;
+       }
+
+       if (callapp_type == BT_VIDEO_CALL) {
+               if (!__bt_ag_agent_make_video_call(number)) {
+                       ERR("Problem launching application");
+                       error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                       goto fail;
+               }
+       } else {
+               if (!__bt_ag_agent_make_call(number)) {
+                       ERR("Problem launching application");
+                       error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                       goto fail;
+               }
+       }
+
+fail:
+       FN_END;
+       return error_code;
+}
+
+bt_hfp_agent_error_t _bt_ag_agent_dial_memory(unsigned int location)
+{
+       bt_hfp_agent_error_t error_code = BT_HFP_AGENT_ERROR_NONE;
+       char *number = NULL;
+       contacts_filter_h filter = NULL;
+       contacts_query_h query = NULL;
+       contacts_list_h list = NULL;
+       contacts_record_h record = NULL;
+       unsigned int projections[] = {
+               _contacts_speeddial.number,
+       };
+
+       FN_START;
+
+       DBG("location = %d", location);
+
+       /*Get number from contacts location*/
+       if (contacts_connect() != CONTACTS_ERROR_NONE) {
+               ERR(" contacts_connect failed");
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+       }
+
+       contacts_filter_create(_contacts_speeddial._uri, &filter);
+
+       if (filter == NULL)
+               goto done;
+
+       if (contacts_filter_add_int(filter,
+               _contacts_speeddial.speeddial_number,
+               CONTACTS_MATCH_EQUAL, location) !=
+               CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       contacts_query_create(_contacts_speeddial._uri, &query);
+
+       if (query == NULL)
+               goto done;
+
+       contacts_query_set_filter(query, filter);
+
+       if (contacts_query_set_projection(query, projections,
+                               sizeof(projections)/sizeof(unsigned int)) !=
+                               CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_db_get_records_with_query(query, 0, 1, &list) !=
+                               CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_list_first(list) != CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_list_get_current_record_p(list, &record) !=
+                               CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (record == NULL)
+               goto done;
+
+       if (contacts_record_get_str(record, _contacts_speeddial.number, &number)
+               != CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (number == NULL) {
+               ERR("No number at the location");
+               error_code = BT_HFP_AGENT_ERROR_INVALID_MEMORY_INDEX;
+               goto done;
+       }
+
+       DBG("number %s", number);
+
+       /*Make Voice call*/
+       if (!__bt_ag_agent_make_call(number)) {
+               ERR("Problem launching application");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+       }
+
+       g_free(number);
+done:
+       if (list != NULL)
+               contacts_list_destroy(list, TRUE);
+
+       if (filter != NULL)
+               contacts_filter_destroy(filter);
+
+       if (query != NULL)
+               contacts_query_destroy(query);
+
+       contacts_disconnect();
+
+       FN_END;
+
+       return error_code;
+}
+
+bt_hfp_agent_error_t _bt_ag_agent_send_dtmf(const gchar *dtmf,
+                               const gchar *path, const gchar *sender)
+{
+       bt_hfp_agent_error_t ret;
+
+       FN_START;
+
+       if (dtmf == NULL || path == NULL || sender == NULL) {
+               ERR("Invalid Argument");
+               return FALSE;
+       }
+
+       DBG("Dtmf = %s", dtmf);
+       DBG("Application path = %s", path);
+       DBG("Sender = %s", sender);
+
+       ret = __bt_ag_agent_gdbus_method_send(sender,
+                               path, TELEPHONY_APP_INTERFACE,
+                               "SendDtmf", FALSE,
+                               g_variant_new("(s)", dtmf));
+
+       return ret;
+}
+
+gboolean _bt_ag_agent_threeway_call(unsigned int chld_value,
+                               const gchar *path, const gchar *sender)
+{
+       FN_START;
+
+       if (path == NULL || sender == NULL) {
+               DBG("Invalid Arguments");
+               return FALSE;
+       }
+
+       DBG("Application path = %s", path);
+       DBG("Value = %d", chld_value);
+       DBG("Sender = %s", sender);
+
+#if defined(TIZEN_WEARABLE) && defined(TIZEN_BT_HFP_AG_ENABLE)
+       /* 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));
+       FN_END;
+       return TRUE;
+}
+
+bt_hfp_agent_error_t _bt_ag_agent_dial_last_num(void *device)
+{
+       bt_hfp_agent_error_t err_code = BT_HFP_AGENT_ERROR_NONE;
+       char *last_num = NULL;
+       int type;
+       int callapp_type;
+       int phone_lock_state;
+       int condition;
+       contacts_list_h list = NULL;
+       contacts_query_h query = NULL;
+       contacts_filter_h filter = NULL;
+       contacts_record_h record = NULL;
+       unsigned int projections[] = {
+               _contacts_phone_log.address,
+               _contacts_phone_log.log_type,
+       };
+
+       FN_START;
+
+       if (contacts_connect() != CONTACTS_ERROR_NONE) {
+               ERR(" contacts_connect failed");
+               err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               return err_code;
+       }
+
+       contacts_filter_create(_contacts_phone_log._uri, &filter);
+
+       if (filter == NULL)
+               goto done;
+
+       if (contacts_filter_add_int(filter, _contacts_phone_log.log_type,
+                               CONTACTS_MATCH_EQUAL,
+                               CONTACTS_PLOG_TYPE_VOICE_OUTGOING) !=
+                               CONTACTS_ERROR_NONE) {
+               ERR(" contacts_filter_add_int failed");
+               err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_OR) !=
+                               CONTACTS_ERROR_NONE) {
+               ERR(" contacts_filter_add_operator failed");
+               err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_filter_add_int(filter, _contacts_phone_log.log_type,
+                               CONTACTS_MATCH_EQUAL,
+                               CONTACTS_PLOG_TYPE_VIDEO_OUTGOING) !=
+                               CONTACTS_ERROR_NONE) {
+               ERR(" contacts_filter_add_int failed");
+               err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       contacts_query_create(_contacts_phone_log._uri, &query);
+
+       if (query == NULL)
+               goto done;
+
+       contacts_query_set_filter(query, filter);
+
+       if (contacts_query_set_projection(query, projections,
+                               sizeof(projections)/sizeof(unsigned int)) !=
+                               CONTACTS_ERROR_NONE) {
+               ERR(" contacts_query_set_projection failed");
+               err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_query_set_sort(query, _contacts_phone_log.log_time, false)
+               != CONTACTS_ERROR_NONE) {
+               ERR(" contacts_query_set_sort failed");
+               err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_db_get_records_with_query(query, 0, 1, &list)  !=
+                               CONTACTS_ERROR_NONE) {
+               ERR(" contacts_db_get_records_with_query failed");
+               err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_list_first(list)  != CONTACTS_ERROR_NONE) {
+               ERR(" contacts_list_first failed");
+               err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_list_get_current_record_p(list, &record)  !=
+                               CONTACTS_ERROR_NONE) {
+               err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (record == NULL)
+               goto done;
+
+       if (contacts_record_get_str(record, _contacts_phone_log.address,
+                               &last_num) != CONTACTS_ERROR_NONE) {
+               err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (last_num == NULL) {
+               ERR("No last number");
+               err_code = BT_HFP_AGENT_ERROR_NO_CALL_LOGS;
+               goto done;
+       }
+
+       if (!__bt_is_phone_locked(&phone_lock_state)) {
+               err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (!__bt_get_outgoing_callapp_type(&callapp_type)) {
+               err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (!__bt_get_outgoing_call_condition(&condition)) {
+               ERR(" Failed to get the call condition");
+               err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (condition == BT_MO_ONLY_UNLOCKED &&
+               phone_lock_state == VCONFKEY_IDLE_LOCK) {
+               ERR(" call condition and phone lock state check fail");
+               err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       switch (callapp_type) {
+       case BT_VOICE_CALL:
+               if (!__bt_ag_agent_make_call(last_num)) {
+                       ERR("Problem launching application");
+                       err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               }
+               break;
+       case BT_VIDEO_CALL:
+               if (!__bt_ag_agent_make_video_call(last_num)) {
+                       ERR("Problem launching application");
+                       err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               }
+               break;
+       case BT_FOLLOW_CALL_LOG:
+               if (contacts_record_get_int(record,
+                       _contacts_phone_log.log_type,
+                       &type) != CONTACTS_ERROR_NONE) {
+                       err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                       break;
+               }
+               if (type == CONTACTS_PLOG_TYPE_VOICE_OUTGOING) {
+                       if (!__bt_ag_agent_make_call(last_num)) {
+                               ERR("Problem launching application");
+                               err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                       }
+               } else if (type == CONTACTS_PLOG_TYPE_VIDEO_OUTGOING) {
+                       if (!__bt_ag_agent_make_video_call(last_num)) {
+                               ERR("Problem launching application");
+                               err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                       }
+               } else {
+                               err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               }
+               break;
+       default:
+               err_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               break;
+       }
+
+done:
+
+       if (list != NULL)
+               contacts_list_destroy(list, TRUE);
+
+       if (filter != NULL)
+               contacts_filter_destroy(filter);
+
+       if (query != NULL)
+               contacts_query_destroy(query);
+
+       contacts_disconnect();
+
+       if (last_num != NULL)
+               g_free(last_num);
+
+       FN_END;
+
+       return err_code;
+}
+
+bt_hfp_agent_error_t _bt_ag_agent_vendor_cmd(const gchar *cmd,
+               const gchar *path, const gchar *sender)
+{
+       bt_hfp_agent_error_t ret;
+
+       FN_START;
+
+       if (cmd == NULL || path == NULL || sender == NULL) {
+               ERR("Invalid Argument");
+               return BT_HFP_AGENT_ERROR_INVALID_PARAM;
+       }
+
+       DBG("cmd = %s", cmd);
+       DBG("Application path = %s", path);
+       DBG("Sender = %s", sender);
+
+       ret = __bt_ag_agent_gdbus_method_send(sender,
+                               path, TELEPHONY_APP_INTERFACE,
+                               "VendorCmd", FALSE,
+                               g_variant_new("(s)", cmd));
+       FN_END;
+       return ret;
+}
+
+gboolean _bt_ag_agent_get_signal_quality(void *device)
+{
+       gint rssi;
+
+       FN_START;
+
+       if (vconf_get_int(VCONFKEY_TELEPHONY_RSSI, &rssi)) {
+               DBG("VCONFKEY_TELEPHONY_RSSI failed\n");
+               goto fail;
+       }
+
+       DBG("RSSI : %d", rssi);
+
+       _bt_hfp_signal_quality_reply(rssi, BT_SIGNAL_QUALITY_BER,
+               device);
+
+       FN_END;
+       return TRUE;
+fail:
+       FN_END;
+       _bt_hfp_signal_quality_reply(-1, -1, device);
+       return FALSE;
+}
+
+gboolean _bt_ag_agent_get_battery_status(void *device)
+{
+       gint battery_chrg_status;
+       gint battery_capacity;
+
+       FN_START;
+
+       if (vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW,
+                                               &battery_chrg_status)) {
+               DBG("VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW failed\n");
+               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");
+               goto fail;
+       }
+
+       DBG("Capacity : %d\n", battery_capacity);
+
+       _bt_hfp_battery_property_reply(device,
+               battery_chrg_status, battery_capacity);
+       FN_END;
+       return TRUE;
+
+fail:
+       _bt_hfp_battery_property_reply(device, -1, -1);
+       FN_END;
+       return FALSE;
+}
+
+gboolean _bt_ag_agent_get_operator_name(void *device)
+{
+       char *operator_name;
+       FN_START;
+
+       operator_name = vconf_get_str(VCONFKEY_TELEPHONY_NWNAME);
+       if (NULL == operator_name) {
+               DBG("vconf_get_str failed");
+               _bt_hfp_operator_reply(NULL, device);
+               return FALSE;
+       }
+
+       DBG("operator_name  = [%s]", operator_name);
+
+       _bt_hfp_operator_reply(operator_name, device);
+
+       free(operator_name);
+
+       FN_END;
+       return TRUE;
+}
+
+gboolean _bt_hfp_agent_nrec_status(gboolean status,
+                       void *t_device)
+{
+       FN_START;
+       bt_ag_info_t *hs = (bt_ag_info_t *)t_device;
+
+       DBG("NREC status = %d", status);
+       if (status)
+               hs->nrec_status = FALSE;
+       else
+               hs->nrec_status = TRUE;
+
+       _bt_ag_agent_emit_signal(ag_dbus_conn, hs->path,
+                                       BT_AG_SERVICE_NAME, "NrecStatusChanged",
+                                       g_variant_new("(b)", status));
+       FN_END;
+       return TRUE;
+}
+
+gboolean _bt_ag_agent_get_imei_number(void *device)
+{
+       FN_START;
+       char *imei_number;
+
+       imei_number = tel_get_misc_me_imei_sync(tapi_handle);
+       if (NULL == imei_number) {
+               ERR("tel_get_misc_me_imei_sync for imei_number failed");
+               goto fail;
+       }
+
+       if (!g_utf8_validate(imei_number, -1, NULL)) {
+               free(imei_number);
+               ERR("get_imei_number : invalid UTF8");
+               goto fail;
+       }
+
+       DBG_SECURE("imei_number  = [%s]", imei_number);
+       _bt_hfp_get_imei_number_reply(imei_number, device);
+       free(imei_number);
+       FN_END;
+       return TRUE;
+
+fail:
+       _bt_hfp_get_imei_number_reply(NULL, device);
+       FN_END;
+       return FALSE;
+}
+
+void _bt_ag_agent_get_manufacturer_name(void *device)
+{
+       FN_START;
+       char *manufacturer_name;
+       int ret;
+
+       ret = system_info_get_platform_string("http://tizen.org/system/manufacturer",
+                                               &manufacturer_name);
+       if (SYSTEM_INFO_ERROR_NONE != ret) {
+               ERR("Get manufacturer_name failed : %d", ret);
+               if (NULL != manufacturer_name)
+                       free(manufacturer_name);
+
+               manufacturer_name = g_strdup("Unknown");
+       } else if (!g_utf8_validate(manufacturer_name, -1, NULL)) {
+               free(manufacturer_name);
+               manufacturer_name = g_strdup("Unknown");
+               ERR("get_manufacturer_name : invalid UTF8");
+       }
+
+       DBG_SECURE("manufacturer_name  = [%s]", manufacturer_name);
+       _bt_hfp_get_device_manufacturer_reply(manufacturer_name, device);
+       free(manufacturer_name);
+       FN_END;
+}
+
+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) {
+               ERR("tel_get_sim_imsi failed");
+               goto fail;
+       }
+       DBG_SECURE("tapi values %s %s %s", imsi.szMcc, imsi.szMnc, imsi.szMsin);
+
+       _bt_hfp_get_imsi_reply(imsi.szMcc, imsi.szMnc, imsi.szMsin, device);
+       FN_END;
+       return;
+fail:
+       _bt_hfp_get_imsi_reply(NULL, NULL, NULL, device);
+       FN_END;
+}
+
+int _bt_ag_agent_registration_status_convert(int result)
+{
+       switch (result) {
+       case TAPI_NETWORK_SERVICE_LEVEL_NO:
+               return BT_AGENT_NETWORK_REG_STATUS_NOT_REGISTER;
+       case TAPI_NETWORK_SERVICE_LEVEL_EMERGENCY:
+               return BT_AGENT_NETWORK_REG_STATUS_EMERGENCY;
+       case TAPI_NETWORK_SERVICE_LEVEL_FULL:
+               return BT_AGENT_NETWORK_REG_STATUS_REGISTER_HOME_NETWORK;
+       case TAPI_NETWORK_SERVICE_LEVEL_SEARCH:
+               return BT_AGENT_NETWORK_REG_STATUS_SEARCH;
+       default:
+               return BT_AGENT_NETWORK_REG_STATUS_UNKNOWN;
+       }
+       return result;
+}
+
+void _bt_ag_agent_get_creg_status(void *device)
+{
+       FN_START;
+       int result = 0;
+       int ret = 0;
+       int n = 1;
+       int registration_status = 0;
+       int roam_status = 0;
+
+       ret = tel_get_property_int(tapi_handle, TAPI_PROP_NETWORK_CIRCUIT_STATUS,
+                               &result);
+       if (ret != TAPI_API_SUCCESS) {
+               ERR("tel_get_property_int failed");
+               return;
+       }
+       registration_status =
+                       _bt_ag_agent_registration_status_convert(result);
+
+       DBG_SECURE("Registration status %d", result);
+       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) {
+                       ERR("Get roaming status failed err = %d\n", ret);
+                       return;
+               }
+               DBG_SECURE("Roam status %d", roam_status);
+               if (roam_status == 1) {
+                       registration_status =
+                                       BT_AGENT_NETWORK_REG_STATUS_REGISTERED_ROAMING;
+               }
+       }
+
+       _bt_hfp_get_creg_status_reply(n, registration_status, device);
+
+       FN_END;
+       return;
+}
+
+void _bt_ag_agent_get_model_name(void *device)
+{
+       FN_START;
+       char *model_name;
+       int ret;
+
+       ret = system_info_get_platform_string("http://tizen.org/system/model_name", &model_name);
+       if (SYSTEM_INFO_ERROR_NONE != ret) {
+               ERR("Get model_name failed: %d", ret);
+               if (NULL != model_name)
+                       free(model_name);
+
+               model_name = g_strdup("Unknown");
+       } else if (!g_utf8_validate(model_name, -1, NULL)) {
+               free(model_name);
+               model_name = g_strdup("Unknown");
+               ERR("get_model_name : invalid UTF8");
+       }
+
+       DBG_SECURE("model_name  = [%s]", model_name);
+       _bt_hfp_get_model_info_reply(model_name, device);
+       free(model_name);
+       FN_END;
+}
+
+void _bt_ag_agent_get_revision_information(void *device)
+{
+       FN_START;
+       char *revision_info;
+       int ret;
+
+       ret = system_info_get_platform_string("http://tizen.org/system/build.string",
+                               &revision_info);
+       if (SYSTEM_INFO_ERROR_NONE != ret) {
+               ERR("Get revision_info failed: %d", ret);
+               if (NULL != revision_info)
+                       free(revision_info);
+
+               revision_info = g_strdup("Unknown");
+       } else if (!g_utf8_validate(revision_info, -1, NULL)) {
+                       free(revision_info);
+                       revision_info = g_strdup("Unknown");
+                       ERR("get_revision_info: invalid UTF8");
+               }
+
+       DBG_SECURE("revision_info  = [%s]", revision_info);
+       _bt_hfp_get_revision_info_reply(revision_info, device);
+       free(revision_info);
+       FN_END;
+}
+
+#if defined(TIZEN_WEARABLE) && defined(TIZEN_BT_HFP_AG_ENABLE)
+static gboolean __bt_ag_agent_launch_voice_dial(gboolean activate)
+{
+       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;
+}
+#else
+static gboolean __bt_ag_agent_launch_voice_dial(gboolean activate)
+{
+       FN_START;
+       app_control_h service = NULL;
+
+       app_control_create(&service);
+
+       if (service == NULL) {
+               ERR("Service create failed");
+               return FALSE;
+       }
+
+       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 (!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");
+               app_control_destroy(service);
+               return FALSE;
+       }
+
+       app_control_destroy(service);
+       FN_END;
+       return TRUE;
+}
+#endif
+
+gboolean _bt_ag_agent_voice_dial(gboolean activate)
+{
+       DBG("Activate = %d", activate);
+
+       return __bt_ag_agent_launch_voice_dial(activate);
+}
+
+static void __bt_ag_codec_negotiation_info_reset(bt_ag_info_t *hs,
+                                       gboolean reset)
+{
+       hs->codec_info.is_negotiating = FALSE;
+       hs->codec_info.requested_by_hf = FALSE;
+       hs->codec_info.sending_codec = 0;
+       if (reset) {
+               hs->codec_info.remote_codecs = 0;
+               hs->codec_info.final_codec = 0;
+               hs->nrec_status = FALSE;
+       }
+
+       if (hs->codec_info.nego_timer) {
+               g_source_remove(hs->codec_info.nego_timer);
+               hs->codec_info.nego_timer = 0;
+       }
+       wbs_opts.wbs_enable = wbs_en;
+}
+
+static gboolean __bt_ag_codec_negotiation_finished(gpointer user_data)
+{
+       struct ag_codec *data = (struct ag_codec *)user_data;
+
+       if (g_strcmp0(data->codec_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);
+               return TRUE;
+       } else if (g_strcmp0(data->codec_status, "timeout") == 0) {
+               DBG("Timeout is occured in codec negotiation");
+       }
+
+       if (data->bt_ag_info->codec_info.requested_by_hf) {
+               __bt_ag_codec_negotiation_info_reset(data->bt_ag_info, FALSE);
+       } else {
+               __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);
+
+       return FALSE;
+}
+
+static bt_hfp_agent_error_t __bt_ag_set_codec(void *device, char *method)
+{
+       GDBusProxy *proxy;
+       GVariant *ret;
+       GError *err = NULL;
+       bt_ag_info_t *bt_ag_info = (bt_ag_info_t *)device;
+
+       proxy =  g_dbus_proxy_new_sync(ag_dbus_conn,
+                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       BLUEZ_SERVICE_NAME, DEFAULT_ADAPTER_OBJECT_PATH,
+                       BT_ADAPTER_INTERFACE, NULL, &err);
+
+       if (!proxy) {
+               if (err) {
+                       ERR("Unable to create proxy: %s", err->message);
+                       g_clear_error(&err);
+               }
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+       }
+
+       ret = g_dbus_proxy_call_sync(proxy, method,
+                       g_variant_new("(ss)", "Gateway", bt_ag_info->remote_addr),
+                       G_DBUS_CALL_FLAGS_NONE, -1,
+                       NULL, &err);
+       if (ret == NULL) {
+               /* dBUS-RPC is failed */
+               ERR("dBUS-RPC is failed");
+               if (err != NULL) {
+                       /* dBUS gives error cause */
+                       ERR("D-Bus API failure: errCode[%x], message[%s]",
+                              err->code, err->message);
+
+                       g_clear_error(&err);
+               }
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+       }
+       g_variant_unref(ret);
+
+       return BT_HFP_AGENT_ERROR_NONE;
+}
+
+static bt_hfp_agent_error_t __bt_ag_codec_selection_setup(bt_ag_info_t *hs,
+                       uint32_t codec)
+{
+       bt_hfp_agent_error_t err = BT_HFP_AGENT_ERROR_NONE;
+
+       DBG("Codec setup [%x]", codec);
+
+       /* 1. Compare sending codec & recieved code */
+       if (hs->codec_info.sending_codec != codec)
+               err = BT_HFP_AGENT_ERROR_INTERNAL;
+
+       /* 2. Send WB or NB command */
+       switch (codec) {
+       case BT_CVSD_CODEC_ID:
+               err = __bt_ag_set_codec(hs, "SetNbParameters");
+               break;
+       case BT_MSBC_CODEC_ID:
+               err = __bt_ag_set_codec(hs, "SetWbsParameters");
+               break;
+       default:
+               err = BT_HFP_AGENT_ERROR_INTERNAL;
+               break;
+       }
+
+       /* If the vendor specific calling returns error or codec is not correct,
+        * we send CVSD Codec parameter to MM module. and also returns
+        * normal value to HF
+       */
+       if (err != BT_HFP_AGENT_ERROR_NONE)
+               codec = BT_CVSD_CODEC_ID;
+
+       hs->codec_info.final_codec = codec;
+
+       return err;
+}
+
+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 = g_new0(struct ag_codec, 1);
+
+#ifdef TIZEN_KIRAN
+       codec = BT_CVSD_CODEC_ID;
+#else
+       if (hs->codec_info.remote_codecs & BT_MSBC_CODEC_MASK)
+               codec = BT_MSBC_CODEC_ID;
+       else
+               codec = BT_CVSD_CODEC_ID;
+#endif
+
+       if (wbs_opts.wbs_enable == FALSE)
+               codec = BT_CVSD_CODEC_ID;
+
+       hs->codec = codec;
+
+       if (_bt_ag_send_at(hs, "\r\n+BCS: %d\r\n", codec) < 0)
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+       else
+               DBG("Send +BCS:%d\n", codec);
+
+       /* Send +BCS command to HF, and wait some times */
+       hs->codec_info.is_negotiating = TRUE;
+       hs->codec_info.sending_codec = codec;
+       hs->codec_info.requested_by_hf = init_by_hf;
+       hs->codec_info.final_codec = codec;
+
+       data->bt_ag_info = hs;
+       data->codec_status = g_strdup ("timeout");
+
+       hs->codec_info.nego_timer = g_timeout_add_seconds(
+                       HFP_CODEC_NEGOTIATION_TIMEOUT,
+                       (GSourceFunc)__bt_ag_codec_negotiation_finished,
+                       data);
+
+       return BT_HFP_AGENT_ERROR_NONE;
+}
+
+
+static bt_hfp_agent_error_t __bt_hfp_codec_connection_setup(
+                               bt_ag_info_t *hs, gboolean init_by_hf)
+{
+       DBG("Request to codec connection by %s", init_by_hf ? "HF" : "AG");
+
+       if (hs->state < HEADSET_STATE_CONNECTED)
+               return BT_HFP_AGENT_ERROR_NOT_CONNECTED;
+
+       if (hs->codec_info.is_negotiating == TRUE) {
+               /* In codec negotiation, return and wait */
+               ERR("Codec nogotiation is in progress");
+               return BT_HFP_AGENT_ERROR_BUSY;
+       }
+
+       /* Not support Codec Negotiation or Not recieved BAC command */
+       if (!(ag.features & BT_AG_FEATURE_CODEC_NEGOTIATION) ||
+                               hs->codec_info.remote_codecs == 0) {
+               ERR("No support for Codec Negotiation or receive BAC command");
+               if (init_by_hf) {
+                       return BT_HFP_AGENT_ERROR_INTERNAL;
+               } else {
+                       __bt_ag_sco_connect(hs);
+                       return BT_HFP_AGENT_ERROR_INTERNAL;
+               }
+       }
+
+       /* If HF initiated codec connection setup, it should send OK command
+        * before +BCS command transmission.
+        */
+       if (init_by_hf)
+               return HFP_STATE_MNGR_ERR_NONE;
+       else
+               return __bt_hfp_send_bcs_command(hs, init_by_hf);
+}
+
+
+static int __hfp_parse_available_codecs(const char *cmd, uint32_t *codecs)
+{
+       char *str = NULL;
+       *codecs = 0x00000000;
+
+       str = strchr(cmd, '=');
+       if (str == NULL)
+               return -EINVAL;
+
+       while (str != NULL) {
+               str++;
+
+               if (atoi(str) == BT_CVSD_CODEC_ID)
+                       *codecs |= BT_CVSD_CODEC_MASK;
+               else if (atoi(str) == BT_MSBC_CODEC_ID)
+                       *codecs |= BT_MSBC_CODEC_MASK;
+
+               str = strchr(str, ',');
+       }
+
+       if (*codecs == 0x00000000)
+               return -EINVAL;
+
+       return 0;
+}
+
+/* AT+BAC (Bluetooth Available Codecs) */
+static int __bt_hfp_available_codecs(bt_ag_info_t *hs, const char *buf)
+{
+       uint32_t codecs = 0x00000000;
+       hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
+
+       if (!(ag.features & BT_AG_FEATURE_CODEC_NEGOTIATION)) {
+               err = HFP_STATE_MNGR_ERR_AG_FAILURE;
+       } else if (__hfp_parse_available_codecs(buf, &codecs) < 0) {
+               err = HFP_STATE_MNGR_ERR_AG_FAILURE;
+       } else {
+               DBG("Update remote available codecs [%x]", codecs);
+               hs->codec_info.remote_codecs = codecs;
+       }
+
+       _bt_ag_send_response(hs, err);
+
+       /* Reset codec information and
+        * restart codec connection setup by AG
+        */
+       hs->codec_info.final_codec = 0;
+       if (hs->codec_info.nego_timer) {
+               hs->codec_info.is_negotiating = FALSE;
+               hs->codec_info.requested_by_hf = FALSE;
+               hs->codec_info.sending_codec = 0;
+               g_source_remove(hs->codec_info.nego_timer);
+               __bt_hfp_codec_connection_setup(hs, FALSE);
+       }
+
+       return 0;
+}
+
+/* AT+BCC (Bluetooth Codec Connection) */
+static int __bt_hfp_codec_connection(bt_ag_info_t *hs, const char *buf)
+{
+       hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
+
+       err = __bt_hfp_codec_connection_setup(hs, TRUE);
+
+       _bt_ag_send_response(hs, err);
+
+       if (err == HFP_STATE_MNGR_ERR_NONE)
+               err = __bt_hfp_send_bcs_command(hs, TRUE);
+
+       if (err != HFP_STATE_MNGR_ERR_NONE)
+               ERR("Fail to request codec connection setup");
+
+       return 0;
+}
+
+/* AT+BCS (Bluetooth Codec Selection) */
+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;
+       }
+
+       if (!(ag.features & BT_AG_FEATURE_CODEC_NEGOTIATION))
+               err = HFP_STATE_MNGR_ERR_AG_FAILURE;
+       else if (__hfp_parse_available_codecs(buf, &codec) < 0)
+               err = HFP_STATE_MNGR_ERR_AG_FAILURE;
+       else if (__bt_ag_codec_selection_setup(hs, codec) !=
+                                       BT_HFP_AGENT_ERROR_NONE)
+               err = HFP_STATE_MNGR_ERR_AG_FAILURE;
+
+       data->bt_ag_info = hs;
+       data->codec_status = g_strdup ("finish");
+       _bt_ag_send_response(hs, err);
+       __bt_ag_codec_negotiation_finished(data);
+
+       return 0;
+}
+
+static void __bt_ag_str2ba(const char *str, bt_addr *ba)
+{
+       int i;
+       for (i = 5; i >= 0; i--, str += 3)
+               ba->b[i] = strtol(str, NULL, 16);
+}
+
+static const char *__bt_ag_state2str(hs_state_t state)
+{
+       switch (state) {
+       case HEADSET_STATE_DISCONNECTED:
+               return "disconnected";
+       case HEADSET_STATE_CONNECTING:
+               return "connecting";
+       case HEADSET_STATE_CONNECTED:
+               return "connected";
+       case HEADSET_STATE_PLAY_IN_PROGRESS:
+               return "Play In Progress";
+       case HEADSET_STATE_ON_CALL:
+               return "On Call";
+       }
+
+       return NULL;
+}
+
+void _bt_convert_addr_string_to_type_rev(unsigned char *addr,
+                                       const char *address)
+{
+        int i;
+        char *ptr = NULL;
+
+       ret_if(address == NULL);
+       ret_if(addr == NULL);
+
+        for (i = 0; i < 6; i++) {
+                addr[5 - i] = strtol(address, &ptr, 16);
+                if (ptr[0] != '\0') {
+                        if (ptr[0] != ':')
+                                return;
+
+                        address = ptr + 1;
+                }
+        }
+}
+
+static gboolean __bt_ag_check_nval(GIOChannel *chan)
+{
+       struct pollfd file_desc;
+
+       memset(&file_desc, 0, sizeof(file_desc));
+       file_desc.fd = g_io_channel_unix_get_fd(chan);
+       file_desc.events = POLLNVAL;
+
+       if (poll(&file_desc, 1, 0) > 0 && (POLLNVAL & file_desc.revents))
+               return TRUE;
+
+       return FALSE;
+}
+
+static int __bt_ag_sco_connect(bt_ag_info_t *hs)
+{
+       struct sco_socket_addr sco_addr;
+       int err;
+       GIOChannel *io;
+       int sco_skt;
+       bt_voice bt_vo;
+       bt_ag_slconn_t *slconn = hs->slc;
+       /*guint watch_id;*/
+
+       if (hs->state != HEADSET_STATE_CONNECTED)
+               return BT_HFP_AGENT_ERROR_NOT_CONNECTED;
+#ifdef TIZEN_MEDIA_ENHANCE
+       _bt_ag_agent_check_transport_state();
+#endif
+
+       /* Create Sco socket */
+       sco_skt = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BT_SCO_PRTCL);
+       if (sco_skt < 0) {
+               ERR("ERROR: Create socket failed.\n");
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+       }
+
+       /* Bind Sco Socket to Local BD addr */
+       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);
+
+       err = bind(sco_skt, (struct sockaddr *) &sco_addr, sizeof(sco_addr));
+       if (err < 0) {
+               ERR("ERROR: sco socket binding failed");
+               ERR("Close SCO skt");
+               close(sco_skt);
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+       }
+
+       DBG("Socket FD : %d", sco_skt);
+
+       io = g_io_channel_unix_new(sco_skt);
+       g_io_channel_set_close_on_unref(io, TRUE);
+       /*g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
+       g_io_channel_set_buffered(io, FALSE);
+       g_io_channel_set_encoding(io, NULL, NULL);*/
+
+       if ((ag.features & BT_AG_FEATURE_CODEC_NEGOTIATION) &&
+               (slconn && (slconn->hs_features &
+                       BT_HF_FEATURE_CODEC_NEGOTIATION)) &&
+                       wbs_opts.wbs_enable == TRUE) {
+               bt_vo.setting = (hs->codec == BT_MSBC_CODEC_ID) ?
+                               BT_HFP_MSBC_VOICE : BT_HFP_CVSD_VOICE;
+
+               DBG("set Bluetooth voice: %d", bt_vo.setting);
+               err = setsockopt(sco_skt, BT_SOCKET_LEVEL,
+                                       BT_VOICE_NUM, &bt_vo, sizeof(bt_vo));
+               if (err < 0) {
+                       ERR("ERROR: sco socket set socket option failed");
+                       ERR("Close SCO skt");
+                       close(sco_skt);
+                       return BT_HFP_AGENT_ERROR_INTERNAL;
+               }
+       } else {
+               DBG("Set NB codec parameter");
+               __bt_ag_set_codec(hs, "SetNbParameters");
+       }
+
+       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);
+
+       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("Close SCO skt");
+               close(sco_skt);
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+       }
+
+       /* Disabling the watch since SCO is connected */
+       /*watch_id = __bt_ag_set_watch(io,
+                       (GIOFunc) __bt_ag_sco_connect_cb, hs);
+       if (watch_id)
+               DBG("SCO watch set Success");*/
+
+       hs->sco = io;
+
+       _bt_ag_set_headset_state(hs, HEADSET_STATE_ON_CALL);
+       return BT_HFP_AGENT_ERROR_NONE;
+}
+
+static void __bt_ag_close_sco(bt_ag_info_t *hs)
+{
+       DBG("");
+       if (hs->sco) {
+               int sock = g_io_channel_unix_get_fd(hs->sco);
+               shutdown(sock, SHUT_RDWR);
+               g_io_channel_unref(hs->sco);
+               hs->sco = NULL;
+       }
+
+       if (hs->sco_id)
+               __bt_ag_agent_remove_watch(&hs->sco_id);
+}
+
+static gboolean __bt_ag_sco_server_conn_cb(GIOChannel *chan,
+                               GIOCondition cond, gpointer user_data)
+{
+       bt_ag_info_t *ag_info = user_data;
+
+       DBG("");
+       if (cond & G_IO_NVAL)
+               return FALSE;
+
+       if (cond & (G_IO_HUP | G_IO_ERR)) {
+               ag_info->sco = NULL;
+               if (ag_info->sco_id)
+                       __bt_ag_agent_remove_watch(&ag_info->sco_id);
+
+               if (ag_info->watch_id)
+                       _bt_ag_set_headset_state(ag_info, HEADSET_STATE_CONNECTED);
+               return FALSE;
+       }
+       return TRUE;
+}
+
+static gboolean __bt_ag_sco_server_cb(GIOChannel *chan,
+                               GIOCondition cond, gpointer user_data)
+{
+       bt_ag_info_t *ag_info = user_data;
+       int sco_skt;
+       int cli_sco_sock;
+       GIOChannel *sco_io;
+       bt_ag_slconn_t *slconn = ag_info->slc;
+       bt_voice bt_vo;
+       int err;
+
+       if ((cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) ||
+                               __bt_ag_check_nval(chan)) {
+               ERR("cond or chan is not valid");
+               return FALSE;
+       }
+
+       INFO_C("Incoming SCO....");
+
+       if (ag_info->state < HEADSET_STATE_CONNECTED)
+               return BT_HFP_AGENT_ERROR_NOT_CONNECTED;
+
+       sco_skt = g_io_channel_unix_get_fd(chan);
+
+       cli_sco_sock = accept(sco_skt, NULL, NULL);
+       if (cli_sco_sock < 0) {
+               ERR("accept is failed");
+               return TRUE;
+       }
+
+       sco_io = g_io_channel_unix_new(cli_sco_sock);
+       g_io_channel_set_close_on_unref(sco_io, TRUE);
+       g_io_channel_set_encoding(sco_io, NULL, NULL);
+       g_io_channel_set_flags(sco_io, G_IO_FLAG_NONBLOCK, NULL);
+       g_io_channel_set_buffered(sco_io, FALSE);
+
+       if ((ag.features & BT_AG_FEATURE_CODEC_NEGOTIATION) &&
+               (slconn && (slconn->hs_features &
+                       BT_HF_FEATURE_CODEC_NEGOTIATION)) &&
+                       wbs_opts.wbs_enable == TRUE) {
+               bt_vo.setting = (ag_info->codec == BT_MSBC_CODEC_ID) ?
+                               BT_HFP_MSBC_VOICE : BT_HFP_CVSD_VOICE;
+
+               DBG("set Bluetooth voice: %d", bt_vo.setting);
+               err = setsockopt(cli_sco_sock, BT_SOCKET_LEVEL,
+                                       BT_VOICE_NUM, &bt_vo, sizeof(bt_vo));
+               if (err < 0) {
+                       ERR("Sco socket set socket option failed");
+                       close(cli_sco_sock);
+                       return FALSE;
+               }
+       }
+
+       ag_info->sco = sco_io;
+       ag_info->sco_id = g_io_add_watch(sco_io, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+                                       __bt_ag_sco_server_conn_cb, ag_info);
+
+       if (remote_dev_path)
+               g_free(remote_dev_path);
+
+       remote_dev_path = g_strdup(ag_info->path);
+
+       _bt_ag_set_headset_state(ag_info, HEADSET_STATE_ON_CALL);
+
+       return TRUE;
+}
+
+static int __bt_ag_start_sco_server(bt_ag_info_t *hs)
+{
+       DBG("Start SCO server");
+       struct sco_socket_addr addr;
+       GIOChannel *sco_io;
+       int sco_skt;
+       bdaddr_t bd_addr = {{0},};
+
+       if (hs->sco_server_started) {
+               DBG("Already exsist");
+               return BT_HFP_AGENT_ERROR_ALREADY_EXSIST;
+       }
+
+       /* Create socket */
+       sco_skt = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BT_SCO_PRTCL);
+       if (sco_skt < 0) {
+               ERR("Can't create socket:\n");
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+       }
+
+       /* Bind to local address */
+       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);
+       memcpy(&addr.sco_bdaddr, &bd_addr, sizeof(bdaddr_t));
+
+       if (bind(sco_skt, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+               ERR("Can't bind socket:\n");
+               goto error;
+       }
+
+       if (listen(sco_skt, 1)) {
+               ERR("Can not listen on the socket:\n");
+               goto error;
+       }
+
+       sco_io = g_io_channel_unix_new(sco_skt);
+       g_io_channel_set_close_on_unref(sco_io, TRUE);
+       g_io_channel_set_encoding(sco_io, NULL, NULL);
+       g_io_channel_set_flags(sco_io, G_IO_FLAG_NONBLOCK, NULL);
+       g_io_channel_set_buffered(sco_io, FALSE);
+
+       hs->sco_server = sco_io;
+       hs->sco_watch_id = g_io_add_watch(sco_io,
+                       G_IO_IN | G_IO_HUP | G_IO_ERR |
+                       G_IO_NVAL, __bt_ag_sco_server_cb, hs);
+
+       hs->sco_server_started = TRUE;
+       return BT_HFP_AGENT_ERROR_NONE;
+
+error:
+       close(sco_skt);
+       return BT_HFP_AGENT_ERROR_INTERNAL;
+}
+
+void __bt_ag_stop_sco_server(bt_ag_info_t *hs)
+{
+       DBG("Stop SCO server");
+       if (hs->sco_server) {
+               g_io_channel_shutdown(hs->sco_server, TRUE, NULL);
+               g_io_channel_unref(hs->sco_server);
+               hs->sco_server = NULL;
+       }
+       hs->sco_server_started = FALSE;
+}
+
+static int __bt_ag_headset_close_rfcomm(bt_ag_info_t *hs)
+{
+       GIOChannel *rfcomm = hs->rfcomm;
+
+       if (rfcomm) {
+               g_io_channel_shutdown(rfcomm, TRUE, NULL);
+               g_io_channel_unref(rfcomm);
+               hs->rfcomm = NULL;
+       }
+
+       g_free(hs->slc);
+       hs->slc = NULL;
+
+       return 0;
+}
+
+static gboolean __bt_ag_sco_cb(GIOChannel *chan, GIOCondition cond,
+                       bt_ag_info_t *hs)
+{
+       if (cond & G_IO_NVAL)
+               return FALSE;
+
+       if (name_owner_sig_id != -1)
+               g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
+                                       name_owner_sig_id);
+       name_owner_sig_id = -1;
+       g_free(sco_owner);
+       sco_owner = NULL;
+
+       DBG("Audio connection disconnected");
+       _bt_ag_set_headset_state(hs, HEADSET_STATE_CONNECTED);
+
+       return FALSE;
+}
+
+void _bt_ag_set_headset_state(bt_ag_info_t *hs, hs_state_t state)
+{
+       bt_ag_slconn_t *slconn = hs->slc;
+       const char *hs_state;
+       hs_state_t org_state = hs->state;
+       gboolean val = FALSE;
+
+       if (org_state == state)
+               return;
+
+       hs_state = __bt_ag_state2str(state);
+
+       switch (state) {
+       case HEADSET_STATE_CONNECTING:
+               _bt_ag_agent_emit_property_changed(ag_dbus_conn,
+                                       hs->path,
+                                       BT_HEADSET_INTERFACE, "State",
+                                       g_variant_new("s", hs_state));
+               hs->state = state;
+               break;
+
+       case HEADSET_STATE_CONNECTED:
+               if (hs->state != HEADSET_STATE_PLAY_IN_PROGRESS)
+                       _bt_ag_agent_emit_property_changed(ag_dbus_conn,
+                                       hs->path,
+                                       BT_HEADSET_INTERFACE, "State",
+                                       g_variant_new("s", hs_state));
+
+               if (hs->state < state) {
+                       val = TRUE;
+                       active_devices = g_slist_append(active_devices, hs);
+                       _bt_ag_agent_emit_property_changed(ag_dbus_conn,
+                                               hs->path,
+                                               BT_HEADSET_INTERFACE,
+                                               "Connected",
+                                               g_variant_new("b", val));
+
+                       DBG("Device %s connected\n", hs->remote_addr);
+#if defined(TIZEN_SUPPORT_DUAL_HF)
+                        if (!hs->is_companion_device)
+                               __bt_ag_start_sco_server(hs);
+#else
+                       __bt_ag_start_sco_server(hs);
+#endif
+
+                       /* Set default code as Gateway NB */
+                       __bt_ag_set_codec(hs, "SetNbParameters");
+               } else if (hs->state == HEADSET_STATE_ON_CALL) {
+                       val = FALSE;
+                       _bt_ag_agent_emit_property_changed(ag_dbus_conn,
+                                               hs->path,
+                                               BT_HEADSET_INTERFACE,
+                                               "Playing",
+                                               g_variant_new("b", val));
+               }
+               hs->state = state;
+               break;
+
+       case HEADSET_STATE_DISCONNECTED:
+               __bt_ag_close_sco(hs);
+               __bt_ag_headset_close_rfcomm(hs);
+
+               if (hs->state == HEADSET_STATE_ON_CALL) {
+                       val = FALSE;
+                       _bt_ag_agent_emit_property_changed(ag_dbus_conn,
+                                               hs->path,
+                                               BT_HEADSET_INTERFACE,
+                                               "Playing",
+                                               g_variant_new("b", val));
+               }
+
+               val = FALSE;
+               _bt_ag_agent_emit_property_changed(ag_dbus_conn,
+                               hs->path,
+                               BT_HEADSET_INTERFACE,
+                               "Connected",
+                               g_variant_new("b", val));
+               if (hs->state > HEADSET_STATE_CONNECTING)
+                       _bt_hfp_device_disconnected(hs);
+
+               active_devices = g_slist_remove(active_devices, hs);
+
+               __bt_ag_codec_negotiation_info_reset(hs, TRUE);
+#if 0 /* SCO is crashed if below is called when SCO is opened by hf-agent */
+               __bt_ag_set_codec(hs, "SetNbParameters");
+#endif
+               hs->codec = 0;
+
+               /* Since SCO server is binded on remote address */
+               /* Need to stop SCO server once heasdet disconencted*/
+               if(hs->sco_server_started)
+                       __bt_ag_stop_sco_server(hs);
+
+               g_free(hs->remote_addr);
+               g_free(hs->slc);
+               g_free(hs);
+               break;
+
+       case HEADSET_STATE_PLAY_IN_PROGRESS:
+       case HEADSET_STATE_ON_CALL:
+               val = TRUE;
+               _bt_ag_agent_emit_property_changed(ag_dbus_conn,
+                                       hs->path,
+                                       BT_HEADSET_INTERFACE, "State",
+                                       g_variant_new("s", hs_state));
+
+               /*add watch for sco data */
+               hs->sco_id = g_io_add_watch(hs->sco,
+                                       G_IO_ERR | G_IO_NVAL,
+                                       (GIOFunc) __bt_ag_sco_cb, hs);
+
+               _bt_ag_agent_emit_property_changed(
+                               ag_dbus_conn, hs->path,
+                               BT_HEADSET_INTERFACE, "Playing",
+                               g_variant_new("b", val));
+
+               if (slconn->microphone_gain >= 0)
+                       _bt_ag_send_at(hs, "\r\n+VGM=%u\r\n",
+                               slconn->microphone_gain);
+
+               if (slconn->speaker_gain >= 0)
+                       _bt_ag_send_at(hs, "\r\n+VGS=%u\r\n",
+                               slconn->speaker_gain);
+
+               hs->state = state;
+               break;
+
+       default:
+               hs->state = state;
+               break;
+       }
+
+       INFO("STATE CHANGED from [%s(%d)] to [%s(%d)]",
+               __bt_ag_state2str(org_state), org_state, __bt_ag_state2str(state), state);
+}
+
+static struct event at_event_callbacks[] = {
+       { "AT+BRSF", _bt_hfp_supported_features },
+       { "AT+CIND", _bt_hfp_report_indicators },
+       { "AT+CMER", _bt_hfp_enable_indicators },
+       { "AT+CHLD", _bt_hfp_call_hold },
+       { "ATA", _bt_hfp_answer_call },
+       { "ATD", _bt_hfp_dial_number },
+       { "AT+VG", _bt_hfp_signal_gain_setting },
+       { "AT+CHUP", _bt_hfp_terminate_call },
+       { "AT+CKPD", _bt_hfp_key_press },
+       { "AT+CLIP", _bt_hfp_cli_notification },
+       { "AT+BTRH", _bt_hfp_response_and_hold },
+       { "AT+BLDN", _bt_hfp_last_dialed_number },
+       { "AT+VTS", _bt_hfp_dtmf_tone },
+       { "AT+CNUM", _bt_hfp_subscriber_number },
+       { "AT+CLCC", _bt_hfp_list_current_calls },
+       { "AT+CMEE", _bt_hfp_extended_errors },
+       { "AT+CCWA", _bt_hfp_call_waiting_notify },
+       { "AT+COPS", _bt_hfp_operator_selection },
+       { "AT+NREC", _bt_hfp_nr_and_ec },
+       { "AT+BVRA", _bt_hfp_voice_dial },
+       { "AT+XAPL", _bt_hfp_apl_command },
+       { "AT+IPHONEACCEV", _bt_hfp_apl_command },
+       { "AT+BIA", _bt_hfp_indicators_activation },
+       { "AT+CPBS", _bt_hfp_select_pb_memory },
+       { "AT+CPBR", _bt_hfp_read_pb_entries},
+       { "AT+CPBF", _bt_hfp_find_pb_entires },
+       { "AT+CSCS", _bt_hfp_select_character_set },
+       { "AT+CSQ", _bt_hfp_get_signal_quality },
+       { "AT+CBC", _bt_hfp_get_battery_charge_status },
+       { "AT+CPAS", _bt_hfp_get_activity_status },
+       { "AT+CGSN", _bt_hfp_get_equipment_identity },
+       { "AT+CGMM", _bt_hfp_get_model_information },
+       { "AT+CGMI", _bt_hfp_get_device_manufacturer },
+       { "AT+CGMR", _bt_hfp_get_revision_information },
+       { "AT+BAC", __bt_hfp_available_codecs },
+       { "AT+BCC", __bt_hfp_codec_connection },
+       { "AT+BCS", __bt_hfp_codec_selection },
+       { "AT+XSAT", _bt_hfp_vendor_cmd },
+       { "AT+CIMI", _bt_hfp_get_imsi },
+       { "AT+CREG", _bt_hfp_get_creg_status },
+       { 0 }
+};
+
+int num_of_secure_command = 4;
+static const char* secure_command[] = {"CLCC", "CLIP", "CPBR", "CCWA"};
+
+void __bt_ag_agent_print_at_buffer(char *message, const char *buf)
+{
+
+       int i = 0;
+       char s[MAX_BUFFER_SIZE] = {0, };
+       gboolean hide = FALSE;
+
+       gboolean is_security_command = FALSE;
+       char *xsat_ptr;
+
+       strncpy(s, buf, MAX_BUFFER_SIZE - 1);
+
+       for (i=0; i<num_of_secure_command; i++) {
+               if (strstr(buf, secure_command[i])) {
+                       is_security_command = TRUE;
+                       break;
+               }
+       }
+
+done:
+       /* +XSAT: 11,DISC */
+       xsat_ptr =  strstr(s, "11,DISC,");
+       if (xsat_ptr) {
+               xsat_ptr = xsat_ptr + 8;
+               int x = 0;
+               while (xsat_ptr[x] != '\0' && xsat_ptr[x] != '\r' && xsat_ptr[x] != '\n') {
+                       xsat_ptr[x] = 'X';
+                       x++;
+               }
+       }
+
+       /* AT+XSAT=11,Q_CT,X,XXXX */
+       xsat_ptr =  strstr(s, "11,Q_CT,");
+       if (xsat_ptr) {
+               xsat_ptr = xsat_ptr + 8;
+               int x = 0;
+               while (xsat_ptr[x] != '\0' && xsat_ptr[x] != '\r' && xsat_ptr[x] != '\n') {
+                       if (x > 1) /* ignore 0 and 1 position */
+                               xsat_ptr[x] = 'X';
+                       x++;
+               }
+       }
+
+       i = 0;
+       while (s[i] != '\0') {
+               if (s[i] == '\r' || s[i] == '\n') {
+                       s[i] = '.';
+               } else {
+                       if (s[i] == '\"')
+                               hide = hide ? FALSE : TRUE;
+                       else if (is_security_command && hide) {
+                               if (i % 2)
+                                       s[i] = 'X';
+                       }
+               }
+               i++;
+       }
+       if (message)
+               INFO("%s Buffer = [%s], Len(%d)", message, s, strlen(s));
+       else
+               INFO("[%s]", s);
+}
+
+static int __bt_ag_at_handler(bt_ag_info_t *hs, const char *buf)
+{
+       struct event *ev;
+
+       __bt_ag_agent_print_at_buffer("[AG AT CMD][RCVD] :", buf);
+
+       for (ev = at_event_callbacks; ev->cmd; ev++) {
+               if (!strncmp(buf, ev->cmd, strlen(ev->cmd)))
+                       return ev->callback(hs, buf);
+       }
+
+       return -EINVAL;
+}
+
+static int __bt_ag_send_at_valist(bt_ag_info_t *hdset, va_list list,
+                       char *list_format)
+{
+       ssize_t final_written, count;
+       char rsp_buffer[MAX_BUFFER_SIZE];
+       int fd;
+       int err;
+
+       count = vsnprintf(rsp_buffer, sizeof(rsp_buffer), list_format, list);
+       if (count < 0) {
+               ERR("count is %d", count);
+               return -EINVAL;
+       }
+
+       if (!hdset->io_chan) {
+               ERR("__bt_ag_send_at_valist: headset not connected");
+               return -EIO;
+       }
+
+       final_written = 0;
+
+       fd = g_io_channel_unix_get_fd(hdset->io_chan);
+
+       if (fd != 0) {
+               while (final_written < count) {
+                       ssize_t written;
+
+                       do {
+                               written = write(fd, rsp_buffer + final_written,
+                                               count - final_written);
+                       } while (written < 0 && errno == EINTR);
+
+                       if (written < 0) {
+                               err = -errno;
+                               ERR("write failed : %s (%d)", strerror(-err), -err);
+                               return -errno;
+                       }
+
+                       final_written += written;
+               }
+
+               /* Synchronize the sending buffer */
+               sync();
+               fsync(fd);
+       } else {
+               ERR("FD is 0. remote_addr : %s", hdset->remote_addr);
+               return -1;
+       }
+
+       __bt_ag_agent_print_at_buffer("[AG AT CMD][SENT]", rsp_buffer);
+
+       return 0;
+}
+
+int __attribute__((format(printf, 2, 3)))
+                       _bt_ag_send_at(bt_ag_info_t *hs, char *format, ...)
+{
+       va_list ap;
+       int ret;
+
+       va_start(ap, format);
+       ret = __bt_ag_send_at_valist(hs, ap, format);
+       va_end(ap);
+
+       return ret;
+}
+
+void __attribute__((format(printf, 3, 4)))
+               _bt_ag_send_foreach_headset(GSList *devices,
+                               int (*cmp) (bt_ag_info_t *hs),
+                               char *format, ...)
+{
+       GSList *l;
+       va_list ap;
+
+       for (l = devices; l != NULL; l = l->next) {
+               bt_ag_info_t *hs = l->data;
+               int ret;
+
+               if (cmp && cmp(hs) != 0)
+                       continue;
+
+               va_start(ap, format);
+               ret = __bt_ag_send_at_valist(hs, ap, format);
+               if (ret < 0)
+                       ERR("Failed to send to headset: %s (%d)",
+                                       strerror(-ret), -ret);
+               va_end(ap);
+       }
+}
+
+int _bt_ag_send_response(bt_ag_info_t *hs, hfp_state_manager_err_t err)
+{
+       if ((err != HFP_STATE_MNGR_ERR_NONE) && hs->slc->is_cme_enabled)
+               return _bt_ag_send_at(hs, "\r\n+CME ERROR: %d\r\n", err);
+
+       switch (err) {
+       case HFP_STATE_MNGR_ERR_NONE:
+               return _bt_ag_send_at(hs, "\r\nOK\r\n");
+       case HFP_STATE_MNGR_ERR_NO_NETWORK_SERVICE:
+               return _bt_ag_send_at(hs, "\r\nNO CARRIER\r\n");
+       default:
+               return _bt_ag_send_at(hs, "\r\nERROR\r\n");
+       }
+}
+
+static gboolean __bt_ag_event_handler(GIOChannel *channel,
+                               GIOCondition cond, void *user_data)
+{
+       bt_ag_slconn_t *slconn;
+       unsigned char event_buf[MAX_BUFFER_SIZE];
+       ssize_t len;
+       size_t available_buffer;
+       int fd;
+       bt_ag_info_t *bt_ag_info = (bt_ag_info_t *)user_data;
+
+
+       if (cond & G_IO_NVAL)
+               return FALSE;
+
+       slconn = bt_ag_info->slc;
+       if (cond & (G_IO_ERR | G_IO_HUP)) {
+               if (bt_ag_info->watch_id)
+                       __bt_ag_agent_remove_watch(&bt_ag_info->watch_id);
+
+               ERR("ERR or HUP on RFCOMM socket");
+               INFO_C("Disconnected [AG role] [Terminated by remote dev]");
+               goto failed;
+       }
+
+       fd = g_io_channel_unix_get_fd(channel);
+       len = read(fd, event_buf, sizeof(event_buf) - 1);
+
+       if (len < 0)
+               return FALSE;
+       available_buffer = sizeof(slconn->buffer) - (slconn->start) -
+                               (slconn->length) - 1;
+       if (available_buffer < (size_t) len) {
+               ERR("Buffer over flow");
+               goto failed;
+       }
+
+       memcpy(&slconn->buffer[slconn->start], event_buf, len);
+       slconn->length += len;
+
+       slconn->buffer[slconn->start + slconn->length] = '\0';
+
+       while (slconn->length > 0) {
+               char *get_cr;
+               int err;
+               off_t cmd_len;
+
+               get_cr = strchr(&slconn->buffer[slconn->start], '\r');
+               if (!get_cr)
+                       break;
+
+               cmd_len = 1 + (off_t) get_cr -
+                       (off_t) &slconn->buffer[slconn->start];
+               *get_cr = '\0';
+
+               if (cmd_len > 1) {
+                       DBG("Call AT handler");
+                       err = __bt_ag_at_handler(bt_ag_info,
+                                       &slconn->buffer[slconn->start]);
+               } else {
+                       ERR("Failed to call AT handler");
+                       err = 0;
+               }
+
+               if (err == -EINVAL) {
+                       ERR("Unrecognized command: %s",
+                               &slconn->buffer[slconn->start]);
+                       err = _bt_ag_send_response(bt_ag_info,
+                                       HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
+                       if (err < 0)
+                               goto failed;
+               } else if (err < 0)
+                       ERR("Error handling command %s: %s (%d)",
+                                               &slconn->buffer[slconn->start],
+                                               strerror(-err), -err);
+
+               slconn->start += cmd_len;
+               slconn->length -= cmd_len;
+
+               if (!slconn->length)
+                       slconn->start = 0;
+       }
+       return TRUE;
+failed:
+       ERR("Failed in event handler - SLC Disconnect");
+       _bt_ag_set_headset_state(bt_ag_info,
+                                       HEADSET_STATE_DISCONNECTED);
+       return FALSE;
+}
+
+static gboolean __bt_ag_agent_connection(gint32 fd, const gchar *device_path,
+                                               const gchar *object_path)
+{
+       GIOFlags flags;
+
+       bt_ag_info_t *bt_ag_info = g_new0(bt_ag_info_t, 1);
+       struct sockaddr_remote address;
+       socklen_t address_len;
+
+       INFO_C("Connected [AG role]");
+       bt_ag_info->rfcomm = NULL;
+       bt_ag_info->slc = NULL;
+       bt_ag_info->hfp_active = TRUE;
+       bt_ag_info->vr_blacklisted = FALSE;
+       bt_ag_info->state = HEADSET_STATE_DISCONNECTED;
+       bt_ag_info->sco_server_started = FALSE;
+       __bt_ag_codec_negotiation_info_reset(bt_ag_info, TRUE);
+
+       bt_ag_info->path = device_path;
+       DBG("device_path = [%s]", device_path);
+
+       address_len = sizeof(address);
+       if (getpeername(fd, (struct sockaddr *) &address, &address_len) != 0)
+               ERR("BD_ADDR is NULL");
+
+       DBG("RFCOMM connection for HFP/HSP is completed. Fd = [%d]", fd);
+       bt_ag_info->fd = fd;
+       bt_ag_info->io_chan = g_io_channel_unix_new(bt_ag_info->fd);
+       flags = g_io_channel_get_flags(bt_ag_info->io_chan);
+
+       flags &= ~G_IO_FLAG_NONBLOCK;
+       flags &= G_IO_FLAG_MASK;
+       g_io_channel_set_flags(bt_ag_info->io_chan, flags, NULL);
+       g_io_channel_set_encoding(bt_ag_info->io_chan, NULL, NULL);
+       g_io_channel_set_buffered(bt_ag_info->io_chan, FALSE);
+
+       bt_ag_info->rfcomm = g_io_channel_ref(bt_ag_info->io_chan);
+
+       bt_ag_info->remote_addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
+       __bt_convert_addr_type_to_rev_string(bt_ag_info->remote_addr,
+                                               address.remote_bdaddr.b);
+
+#if defined(TIZEN_SUPPORT_DUAL_HF)
+       bt_ag_info->is_companion_device =
+                       __bt_ag_agent_is_companion_device(bt_ag_info->remote_addr);
+#endif
+
+       DBG("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");
+               _bt_ag_set_headset_state(bt_ag_info,
+                                               HEADSET_STATE_CONNECTED);
+       }
+       else {
+               DBG("HFP connection connecting");
+               _bt_ag_set_headset_state(bt_ag_info,
+                                               HEADSET_STATE_CONNECTING);
+       }
+
+       __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->is_nrec = TRUE;
+
+       return TRUE;
+}
+
+static gboolean __bt_ag_agent_is_device_vr_blacklisted(const char *lap_addr)
+{
+       char *buffer;
+       FILE *fp;
+       long size;
+       size_t result;
+       char *token;
+       char *saveptr;
+
+       fp = fopen(AGENT_VR_BLACKLIST_FILE, "r");
+
+       if (fp == NULL) {
+               ERR("Unable to open VR blacklist file");
+               return FALSE;
+       }
+
+       fseek(fp, 0, SEEK_END);
+       size = ftell(fp);
+       if (size <= 0) {
+               ERR("size is not a positive number");
+               fclose(fp);
+               return FALSE;
+       }
+
+       rewind(fp);
+
+       buffer = g_malloc0(sizeof(char) * size);
+       if (buffer == NULL) {
+               ERR("g_malloc0 is failed");
+               fclose(fp);
+               return FALSE;
+       }
+       result = fread((char *)buffer, 1, size, fp);
+       fclose(fp);
+       if (result != size) {
+               ERR("Read Error");
+               g_free(buffer);
+               return FALSE;
+       }
+
+       token= strtok_r(buffer, "=", &saveptr);
+       if (token == NULL) {
+               g_free(buffer);
+               return FALSE;
+       }
+
+       while ((token = strtok_r(NULL, ",", &saveptr))) {
+               if (strlen(token) > 8)
+                       token[8] = '\0';
+               if (0 == g_strcmp0(token, lap_addr)) {
+                       INFO("Voice Recognition blacklisted");
+                       g_free(buffer);
+                       return TRUE;
+               }
+       }
+       g_free(buffer);
+       return FALSE;
+}
+
+static gboolean __bt_sco_open_delay_timeout_cb(gpointer user_data)
+{
+       bt_ag_info_t *bt_ag_info = (bt_ag_info_t *)user_data;
+       sco_open_timer_id = 0;
+       DBG("sco_open_request (%d)", sco_open_request);
+
+       if (sco_open_request && bt_ag_info->state == HEADSET_STATE_CONNECTED) {
+               bt_ag_slconn_t *slconn = bt_ag_info->slc;
+
+               INFO("try to open SCO");
+               sco_open_request = FALSE;
+
+               if ((ag.features & BT_AG_FEATURE_CODEC_NEGOTIATION) &&
+                               (slconn && (slconn->hs_features &
+                                       BT_HF_FEATURE_CODEC_NEGOTIATION))) {
+                       switch (bt_ag_info->codec_info.final_codec) {
+                       case BT_CVSD_CODEC_ID:
+                               __bt_ag_set_codec(bt_ag_info, "SetNbParameters");
+                               __bt_ag_sco_connect(bt_ag_info);
+                               break;
+                       case BT_MSBC_CODEC_ID:
+                               __bt_ag_set_codec(bt_ag_info, "SetWbsParameters");
+                               __bt_ag_sco_connect(bt_ag_info);
+                               break;
+                       default:
+                               __bt_hfp_codec_connection_setup(bt_ag_info, FALSE);
+                               break;
+                       }
+               } else
+                       __bt_ag_sco_connect(bt_ag_info);
+       }
+
+       return FALSE;
+}
+
+/*
+* Service level connection complete
+* indication and state management
+*/
+void _bt_ag_slconn_complete(bt_ag_info_t *hs)
+{
+       char lap_address[BT_LOWER_ADDRESS_LENGTH];
+
+       DBG("HFP Service Level Connection established\n");
+
+       /* Check device Voice Recognition blacklist status */
+       g_strlcpy(lap_address, hs->remote_addr, sizeof(lap_address));
+       hs->vr_blacklisted =
+               __bt_ag_agent_is_device_vr_blacklisted(lap_address);
+
+       if (sco_open_timer_id > 0) {
+               g_source_remove(sco_open_timer_id);
+               sco_open_timer_id = 0;
+       }
+
+       sco_open_request = FALSE;
+       sco_open_timer_id = g_timeout_add(BT_SCO_OPEN_DELAY_TIMER,
+                                               __bt_sco_open_delay_timeout_cb, hs);
+
+       _bt_ag_set_headset_state(hs, HEADSET_STATE_CONNECTED);
+}
+
+static gboolean __bt_ag_agent_connection_release(bt_ag_info_t *hs)
+{
+
+       g_io_channel_shutdown(hs->io_chan, TRUE, NULL);
+       g_io_channel_unref(hs->io_chan);
+       hs->io_chan = NULL;
+
+       if (hs->sco) {
+               __bt_ag_close_sco(hs);
+               _bt_ag_set_headset_state(hs, HEADSET_STATE_CONNECTED);
+               hs->sco = NULL;
+       }
+       __bt_ag_agent_remove_watch(&hs->watch_id);
+
+       _bt_ag_set_headset_state(hs, HEADSET_STATE_DISCONNECTED);
+       return TRUE;
+}
+
+static GQuark __bt_ag_agent_error_quark(void)
+{
+       FN_START;
+
+       static GQuark quark = 0;
+       if (!quark)
+               quark = g_quark_from_static_string("ag-agent");
+
+       FN_END;
+       return quark;
+}
+
+static GError *__bt_ag_agent_set_error(bt_hfp_agent_error_t error)
+{
+       FN_START;
+       ERR("error[%d]\n", error);
+
+       switch (error) {
+       case BT_HFP_AGENT_ERROR_NOT_AVAILABLE:
+               return g_error_new(BT_AG_AGENT_ERROR, error,
+                                       BT_ERROR_NOT_AVAILABLE);
+       case BT_HFP_AGENT_ERROR_NOT_CONNECTED:
+       return g_error_new(BT_AG_AGENT_ERROR, error,
+                                       BT_ERROR_NOT_CONNECTED);
+       case BT_HFP_AGENT_ERROR_BUSY:
+               return g_error_new(BT_AG_AGENT_ERROR, error,
+                                               BT_ERROR_BUSY);
+       case BT_HFP_AGENT_ERROR_INVALID_PARAM:
+               return g_error_new(BT_AG_AGENT_ERROR, error,
+                                               BT_ERROR_INVALID_PARAM);
+       case BT_HFP_AGENT_ERROR_ALREADY_EXSIST:
+               return g_error_new(BT_AG_AGENT_ERROR, error,
+                                               BT_ERROR_ALREADY_EXSIST);
+       case BT_HFP_AGENT_ERROR_ALREADY_CONNECTED:
+               return g_error_new(BT_AG_AGENT_ERROR, error,
+                                               BT_ERROR_ALREADY_CONNECTED);
+       case BT_HFP_AGENT_ERROR_NO_MEMORY:
+               return g_error_new(BT_AG_AGENT_ERROR, error,
+                                               BT_ERROR_NO_MEMORY);
+       case BT_HFP_AGENT_ERROR_I_O_ERROR:
+               return g_error_new(BT_AG_AGENT_ERROR, error,
+                                               BT_ERROR_I_O_ERROR);
+       case BT_HFP_AGENT_ERROR_OPERATION_NOT_AVAILABLE:
+               return g_error_new(BT_AG_AGENT_ERROR, error,
+                                       BT_ERROR_OPERATION_NOT_AVAILABLE);
+       case BT_HFP_AGENT_ERROR_BATTERY_STATUS:
+               return g_error_new(BT_AG_AGENT_ERROR, error,
+                                       BT_ERROR_BATTERY);
+       case BT_HFP_AGENT_ERROR_SIGNAL_STATUS:
+               return g_error_new(BT_AG_AGENT_ERROR, error,
+                                       BT_ERROR_SIGNAL);
+       case BT_HFP_AGENT_ERROR_NO_CALL_LOGS:
+               return g_error_new(BT_AG_AGENT_ERROR, error,
+                                       BT_ERROR_NO_CALL_LOG);
+       case BT_HFP_AGENT_ERROR_INTERNAL:
+       default:
+               return g_error_new(BT_AG_AGENT_ERROR, error,
+                                               BT_ERROR_INTERNAL);
+       }
+       FN_END;
+}
+
+static bt_ag_info_t *__bt_get_active_headset(const gchar *device_path)
+{
+       GSList *l;
+
+       for (l = active_devices ; l; l = l->next) {
+               bt_ag_info_t *data = l->data;
+               if (device_path == NULL) /*just to avoid crash incase of "play" when dailed from device[NEEDS TO BE CHANGED]*/
+                       return data;
+               if (g_strcmp0(data->path, device_path) == 0) {
+                       INFO("Active device found");
+                       return data;
+               }
+       }
+
+       INFO("Active device not found");
+       return NULL;
+}
+
+static void __bt_ag_agent_method(GDBusConnection *connection,
+                       const gchar *sender,
+                       const gchar *object_path,
+                       const gchar *interface_name,
+                       const gchar *method_name,
+                       GVariant *parameters,
+                       GDBusMethodInvocation *invocation,
+                       gpointer user_data)
+{
+       FN_START;
+
+       INFO("method %s", method_name);
+       INFO("object_path %s", object_path);
+       int ret = BT_HFP_AGENT_ERROR_NONE;
+       GError *err = NULL;
+       const gchar *device_path = NULL;
+
+       if (g_strcmp0(method_name, "NewConnection") == 0) {
+               gint32 fd;
+               int index;
+               GDBusMessage *msg;
+               GUnixFDList *fd_list;
+               GVariant *options;
+               int device_count = 0;
+               GSList *l;
+
+               device_count = g_slist_length(active_devices);
+
+               INFO("device_count %d", device_count);
+
+               if (device_count >= MAX_CONNECTED_DEVICES) {
+                       ret = BT_HFP_AGENT_ERROR_INTERNAL;
+                       goto fail;
+               }
+
+               g_variant_get(parameters, "(oha{sv})",
+                                               &device_path, &index, &options);
+#if defined(TIZEN_SUPPORT_DUAL_HF)
+               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);
+               fd_list = g_dbus_message_get_unix_fd_list(msg);
+               if (fd_list == NULL) {
+                       ret = BT_HFP_AGENT_ERROR_INTERNAL;
+                       goto fail;
+               }
+
+               fd = g_unix_fd_list_get(fd_list, index, NULL);
+               if (fd == -1) {
+                       ret = BT_HFP_AGENT_ERROR_INTERNAL;
+                       goto fail;
+               }
+
+               DBG("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;
+                       goto fail;
+               }
+
+               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);
+
+               for (l = active_devices; l; l = l->next) {
+                       bt_ag_info_t *data = l->data;
+
+                       INFO("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;
+                                       goto fail;
+                               }
+                               INFO_C("Disconnected [AG role] [Terminated by local host]");
+                               g_dbus_method_invocation_return_value(invocation, NULL);
+                       }
+               }
+       } else if (g_strcmp0(method_name, "RegisterApplication") == 0) {
+               gchar *path = NULL;
+               gchar *address = NULL;
+               g_variant_get(parameters, "(&s&s)", &path, &address);
+               /*local_addr = malloc(strlen(address));
+               memcpy(local_addr, address, strlen(address));*/
+
+               DBG("Sender = %s, Application path = %s\n", sender, path);
+               ret = _bt_hfp_register_telephony_agent(TRUE, path, sender);
+               if (ret)
+                       goto fail;
+
+               if (local_addr)
+                       g_free(local_addr);
+
+               local_addr = g_strdup(address);
+               DBG("Address = %s\n", local_addr);
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "UnregisterApplication") == 0) {
+               gchar *path = NULL;
+               g_variant_get(parameters, "(&s)", &path);
+
+               DBG("Application path = %s\n", path);
+               DBG("Sender = %s\n", sender);
+
+               ret = _bt_hfp_register_telephony_agent(FALSE, path, sender);
+               if (ret)
+                       goto fail;
+
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "IncomingCall") == 0) {
+               gchar *path;
+               gchar *number;
+               gint call_id;
+
+               g_variant_get(parameters, "(&s&si)", &path, &number, &call_id);
+
+               DBG("Application path = %s", path);
+               DBG_SECURE("Phone number = %s", number);
+               DBG("Call id = %d", call_id);
+
+               DBG("Sender = %s", sender);
+
+               ret = _bt_hfp_incoming_call(path, number, call_id, sender);
+               if (ret)
+                       goto fail;
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "OutgoingCall") == 0) {
+               gchar *path;
+               gchar *number;
+               gint call_id;
+
+               g_variant_get(parameters, "(&s&si)", &path, &number, &call_id);
+
+               DBG("Application path = %s", path);
+               DBG_SECURE("Phone number = %s", number);
+               DBG("Call id = %d", call_id);
+
+               DBG("Sender = %s", sender);
+
+               ret = _bt_hfp_outgoing_call(path, number, call_id, sender);
+               if (ret)
+                       goto fail;
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "ChangeCallStatus") == 0) {
+               gchar *path;
+               gchar *number;
+               gint status;
+               gint call_id;
+               GSList *l;
+
+               g_variant_get(parameters, "(&s&sii)",
+                                       &path, &number, &status, &call_id);
+               DBG("Application path = %s\n", path);
+               DBG_SECURE("Number = %s\n", number);
+               DBG("Status = %d\n", status);
+               DBG("Call id = %d\n", call_id);
+               DBG("Sender = %s\n", sender);
+
+               ret = _bt_hfp_change_call_status(path,
+                                       number, status, call_id, sender);
+
+               if (_bt_hfp_is_call_exist() == FALSE) {
+                       for (l = active_devices; l; l = l->next) {
+                               bt_ag_info_t *data = l->data;
+
+                               if(data->state == HEADSET_STATE_ON_CALL) {
+                                       __bt_ag_close_sco(data);
+                                       _bt_ag_set_headset_state(data,
+                                               HEADSET_STATE_CONNECTED);
+                               }
+                       }
+               }
+
+               if (ret)
+                       goto fail;
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "GetProperties") == 0) {
+               GVariantBuilder *builder;
+               GVariant *var_data;
+               bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path);
+
+               if (bt_ag_info) {
+                       gchar *codec = g_strdup("codec");
+                       gchar *nrec = g_strdup("nrec");
+
+                       builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+
+                       g_variant_builder_add(builder, "{sv}",
+                                       codec, g_variant_new("u", bt_ag_info->codec_info.final_codec));
+                       g_variant_builder_add(builder, "{sv}",
+                                       nrec, g_variant_new("b", bt_ag_info->nrec_status));
+
+                       var_data = g_variant_new("(a{sv})", builder);
+                       g_variant_builder_unref(builder);
+                       g_dbus_method_invocation_return_value(invocation, var_data);
+
+                       g_free(codec);
+                       g_free(nrec);
+               }
+       } 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;
+
+                       __bt_convert_addr_type_to_rev_string(hdset_address,
+                                       (unsigned char *)data->remote_addr);
+
+                       DBG("Disconnect Headset %s, %s\n",
+                                               hdset_address, data->path);
+                       _bt_ag_set_headset_state(data,
+                                               HEADSET_STATE_DISCONNECTED);
+               }
+               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)
+                               is_connected = TRUE;
+               }
+               DBG("is_connected : %s",
+                               is_connected ? "Connected":"Disconnected");
+
+               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;
+                       goto fail;
+               }
+
+               if (ag.ring_timer) {
+                       DBG("IndicateCall received when already indicating");
+                       g_dbus_method_invocation_return_value(invocation, NULL);
+               }
+
+               for (l = active_devices; l; l = l->next) {
+                       bt_ag_info_t *data = l->data;
+
+                       if(data->state >= HEADSET_STATE_CONNECTED)
+                               _bt_ag_send_at(data, "\r\nRING\r\n");
+               }
+
+               __bt_ring_timer_cb(NULL);
+               ag.ring_timer = g_timeout_add(AG_RING_INTERVAL,
+                               __bt_ring_timer_cb, NULL);
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "CancelCall") == 0) {
+               if (0 == g_slist_length(active_devices)) {
+                       ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
+                       goto fail;
+               }
+
+               if (ag.ring_timer) {
+                       g_source_remove(ag.ring_timer);
+                       ag.ring_timer = 0;
+               } else
+                       DBG("Got CancelCall method call but no call is active");
+
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "Play") == 0) {
+               bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path);
+               bt_ag_slconn_t *slconn = NULL;
+
+               if (bt_ag_info) {
+                       slconn = bt_ag_info->slc;
+               } else {
+                       ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
+                       goto fail;
+               }
+
+#ifndef __TIZEN_OPEN__
+#ifdef MDM_PHASE_2
+               int mode;
+               if ( slconn && FALSE == slconn->is_voice_recognition_running &&
+                               mdm_get_service() == MDM_RESULT_SUCCESS) {
+                       mode = mdm_get_allow_bluetooth_outgoing_call();
+                       mdm_release_service();
+
+                       if (mode == MDM_RESTRICTED) {
+                               ERR("[MDM] Not allow the outgoing call");
+                               ret = BT_HFP_AGENT_ERROR_OPERATION_NOT_AVAILABLE;
+                               goto fail;
+                       }
+               }
+#endif
+#endif
+
+               switch (bt_ag_info->state) {
+               case HEADSET_STATE_CONNECTING:
+               case HEADSET_STATE_DISCONNECTED:
+                       ERR("HEADSET_STATE  ERROR");
+                       ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
+                       break;
+               case HEADSET_STATE_CONNECTED:
+                       break;
+               case HEADSET_STATE_PLAY_IN_PROGRESS:
+                       ERR("Play In Progress");
+                       ret = BT_HFP_AGENT_ERROR_BUSY;
+                       break;
+               default:
+                       break;
+               }
+               if (ret)
+                       goto fail;
+
+               if (sco_open_timer_id > 0) {
+                       INFO("SCO open delay");
+                       sco_open_request = TRUE;
+                       g_dbus_method_invocation_return_value(invocation, NULL);
+                       return;
+               }
+
+               if ((ag.features & BT_AG_FEATURE_CODEC_NEGOTIATION) &&
+                               (slconn && (slconn->hs_features &
+                                       BT_HF_FEATURE_CODEC_NEGOTIATION))) {
+                       switch (bt_ag_info->codec_info.final_codec) {
+                       case BT_CVSD_CODEC_ID:
+                               __bt_ag_set_codec(bt_ag_info, "SetNbParameters");
+                               ret = __bt_ag_sco_connect(bt_ag_info);
+                               break;
+                       case BT_MSBC_CODEC_ID:
+                               __bt_ag_set_codec(bt_ag_info, "SetWbsParameters");
+                               ret = __bt_ag_sco_connect(bt_ag_info);
+                               break;
+                       default:
+                               ret = __bt_hfp_codec_connection_setup(bt_ag_info, FALSE);
+                               break;
+                       }
+               } else
+                       ret = __bt_ag_sco_connect(bt_ag_info);
+
+               if (ret)
+                       goto fail;
+
+               g_free(sco_owner);
+               sco_owner = g_strdup(sender);
+
+               g_dbus_method_invocation_return_value(invocation, NULL);
+
+               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;
+
+                       if(data->state > HEADSET_STATE_CONNECTED) {
+                               __bt_ag_close_sco(data);
+                               _bt_ag_set_headset_state(data,
+                                       HEADSET_STATE_CONNECTED);
+                       }
+               }
+
+               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;
+
+                       if(data->state == HEADSET_STATE_ON_CALL)
+                               is_playing = TRUE;
+               }
+               DBG("is_playing : %s", is_playing ? "Playing":"Not Playing");
+
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(b)", is_playing));
+       } else if (g_strcmp0(method_name, "GetSpeakerGain") == 0) {
+               bt_ag_slconn_t *slconn = NULL;
+               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) {
+                       ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
+                       goto fail;
+               }
+
+               slconn = bt_ag_info->slc;
+               if (slconn)
+                       gain_value = (guint16) slconn->speaker_gain;
+
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(q)", gain_value));
+       } else if (g_strcmp0(method_name, "SetSpeakerGain") == 0) {
+               guint16 gain;
+               bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path);
+
+               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;
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "GetMicrophoneGain") == 0) {
+               bt_ag_slconn_t *slconn = NULL;
+               guint16 gain_value;
+               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) {
+                       ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
+                       goto fail;
+               }
+
+               slconn = bt_ag_info->slc;
+               if (slconn)
+                       gain_value = (guint16) slconn->microphone_gain;
+
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(q)", gain_value));
+       } else if (g_strcmp0(method_name, "SetMicrophoneGain") == 0) {
+               guint16 gain;
+               bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path);
+
+               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;
+                       goto fail;
+               }
+
+               bt_ag_slconn_t *slconn = bt_ag_info->slc;
+               gboolean enable;
+
+               g_variant_get(parameters, "(b)", &enable);
+               DBG("VoiceDail enable = %d\n", enable);
+
+               if ((slconn && !(slconn->hs_features &
+                                       BT_HF_FEATURE_VOICE_RECOGNITION)))
+                       ret = BT_HFP_AGENT_ERROR_INTERNAL;
+               else if (bt_ag_info->vr_blacklisted)
+                       ret = BT_HFP_AGENT_ERROR_INTERNAL;
+               else
+                       ret = _bt_hfp_set_voice_dial(bt_ag_info, enable);
+
+               if (slconn)
+                       slconn->is_voice_recognition_running = enable;
+
+               if (ret)
+                       goto fail;
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } 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;
+                       goto fail;
+               }
+
+               g_variant_get(parameters, "(&s)", &cmd);
+               if (cmd == NULL){
+                       ret = BT_HFP_AGENT_ERROR_INVALID_PARAM;
+                       goto fail;
+               }
+
+               DBG("vendor cmd = %s", cmd);
+
+               ret = _bt_hfp_send_vendor_cmd(bt_ag_info, cmd);
+               if (ret)
+                       goto fail;
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "CheckPrivilege") == 0) {
+               DBG("Already pass dbus SMACK for bt-service::platform");
+               /* Return success */
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       }
+
+       INFO("-");
+       return;
+
+fail:
+       err = __bt_ag_agent_set_error(ret);
+       g_dbus_method_invocation_return_gerror(invocation, err);
+       g_error_free(err);
+       INFO("-");
+}
+
+static const GDBusInterfaceVTable method_table = {
+       __bt_ag_agent_method,
+       NULL,
+       NULL,
+};
+
+static GDBusNodeInfo *__bt_ag_create_method_node_info
+                                       (const gchar *introspection_data)
+{
+       GError *err = NULL;
+       GDBusNodeInfo *node_info = NULL;
+
+       if (introspection_data == NULL)
+               return NULL;
+
+       node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
+
+       if (err) {
+               ERR("Unable to create node: %s", err->message);
+               g_clear_error(&err);
+       }
+       return node_info;
+}
+
+static GDBusConnection *__bt_ag_get_gdbus_connection(void)
+{
+       FN_START;
+
+       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 dbus: %s", err->message);
+                       g_clear_error(&err);
+               }
+               return NULL;
+       }
+       FN_END;
+
+       return ag_dbus_conn;
+}
+
+static gboolean __bt_ag_register_profile_methods(void)
+{
+       FN_START;
+       GError *error = NULL;
+       guint owner_id;
+       GDBusNodeInfo *node_info;
+       gchar *path;
+
+       owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
+                               BT_AG_SERVICE_NAME,
+                               G_BUS_NAME_OWNER_FLAGS_NONE,
+                               NULL, NULL, NULL,
+                               NULL, NULL);
+
+       DBG("owner_id is [%d]", owner_id);
+
+       node_info = __bt_ag_create_method_node_info(
+                               ag_agent_bluez_introspection_xml);
+       if (node_info == NULL)
+               return FALSE;
+
+       path = g_strdup(BT_AG_AGENT_OBJECT_PATH);
+       DBG("path is [%s]", path);
+
+       hf_bluez_id = g_dbus_connection_register_object(ag_dbus_conn, path,
+                                       node_info->interfaces[0],
+                                       &method_table,
+                                       NULL, NULL, &error);
+       if (hf_bluez_id == 0) {
+               ERR("Failed to register: %s", error->message);
+               g_error_free(error);
+               g_free(path);
+               return FALSE;
+       }
+       g_free(path);
+
+       /* Ag register profile methods for HSP*/
+
+       path = g_strdup(BT_HS_AG_AGENT_OBJECT_PATH);
+       DBG("path is [%s]", path);
+
+       hs_bluez_id = g_dbus_connection_register_object(ag_dbus_conn, path,
+                                       node_info->interfaces[0],
+                                       &method_table,
+                                       NULL, NULL, &error);
+       if (hs_bluez_id == 0) {
+               ERR("Failed to register: %s", error->message);
+               g_error_free(error);
+               g_free(path);
+               return FALSE;
+       }
+       g_free(path);
+
+       node_info = __bt_ag_create_method_node_info
+                               (ag_agent_app_introspection_xml);
+       if (node_info == NULL)
+               return FALSE;
+
+       path = g_strdup(BT_AG_AGENT_OBJECT_PATH);
+       DBG("path is [%s]", path);
+
+       app_id = g_dbus_connection_register_object(ag_dbus_conn, path,
+                                               node_info->interfaces[0],
+                                               &method_table,
+                                               NULL, NULL, &error);
+       if (app_id == 0) {
+               ERR("Failed to register: %s", error->message);
+               g_error_free(error);
+               g_free(path);
+               return FALSE;
+       }
+       g_free(path);
+
+       FN_END;
+       return TRUE;
+}
+
+static void __bt_ag_unregister_profile_methods(void)
+{
+       DBG("");
+
+       if (hf_bluez_id > 0) {
+               g_dbus_connection_unregister_object(ag_dbus_conn,
+                                                       hf_bluez_id);
+               hf_bluez_id = 0;
+       }
+
+       if (hs_bluez_id > 0) {
+               g_dbus_connection_unregister_object(ag_dbus_conn,
+                                                       hs_bluez_id);
+               hs_bluez_id = 0;
+       }
+
+       if (app_id > 0) {
+               g_dbus_connection_unregister_object(ag_dbus_conn,
+                                                       app_id);
+               app_id = 0;
+       }
+}
+
+static GDBusProxy *__bt_ag_gdbus_get_service_proxy(const gchar *service,
+                               const gchar *path, const gchar *interface)
+{
+       return (service_gproxy) ? service_gproxy :
+                       __bt_ag_gdbus_init_service_proxy(service,
+                                       path, interface);
+}
+
+static void __bt_ag_agent_register(gchar *path, uint16_t profile_version,
+                               char *profile_uuid, const char* profile_name)
+{
+       FN_START;
+       GDBusProxy *proxy;
+       GVariant *ret;
+       GError *error = NULL;
+       GVariantBuilder *builder;
+
+       proxy = __bt_ag_gdbus_get_service_proxy(BLUEZ_SERVICE_NAME,
+               "/org/bluez", BLUEZ_PROFILE_MGMT_INTERFACE);
+       if (proxy == NULL)
+               return;
+
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+
+       g_variant_builder_add(builder, "{sv}",
+                       "Name", g_variant_new("s",
+                       profile_name));
+       g_variant_builder_add(builder, "{sv}",
+                       "Version", g_variant_new("q", profile_version));
+       /*g_variant_builder_add(builder, "{sv}",
+                       "Role", g_variant_new("s","client"));*/
+       if (g_strcmp0(path, BT_AG_AGENT_OBJECT_PATH) == 0) {
+               g_variant_builder_add(builder, "{sv}",
+                               "features", g_variant_new("q", ag.sdp_features));
+       }
+
+       ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile",
+                                       g_variant_new("(osa{sv})", path,
+                                                       profile_uuid, builder),
+                                       G_DBUS_CALL_FLAGS_NONE, -1,
+                                       NULL, &error);
+       g_variant_builder_unref(builder);
+       /* set the name and role for the profile*/
+       if (ret == NULL) {
+               /* dBUS-RPC is failed */
+               ERR("dBUS-RPC is failed");
+
+               if (error != NULL) {
+                       /* dBUS gives error cause */
+                       ERR("D-Bus API failure: errCode[%x], message[%s]",
+                                       error->code, error->message);
+
+                       g_clear_error(&error);
+               }
+               g_free(path);
+               return;
+       }
+       g_variant_unref(ret);
+       g_free(path);
+
+       FN_END;
+       return;
+}
+
+static void __bt_ag_agent_unregister(gchar *path)
+{
+       FN_START;
+       GDBusProxy *proxy;
+       GVariant *ret;
+       GError *error = NULL;
+
+       proxy = __bt_ag_gdbus_get_service_proxy(BLUEZ_SERVICE_NAME,
+               "/org/bluez", BLUEZ_PROFILE_MGMT_INTERFACE);
+       if (proxy == NULL)
+               return;
+
+
+       ret = g_dbus_proxy_call_sync(proxy, "UnregisterProfile",
+                                       g_variant_new("(o)", path),
+                                       G_DBUS_CALL_FLAGS_NONE, -1,
+                                       NULL, &error);
+       g_free(path);
+       /* set the name and role for the profile*/
+       if (ret == NULL) {
+               /* dBUS-RPC is failed */
+               ERR("dBUS-RPC is failed");
+
+               if (error != NULL) {
+                       /* dBUS gives error cause */
+                       ERR("D-Bus API failure: errCode[%x], message[%s]",
+                                       error->code, error->message);
+
+                       g_clear_error(&error);
+               }
+               return;
+       }
+       g_variant_unref(ret);
+
+       if (local_addr) {
+               g_free(local_addr);
+               local_addr = NULL;
+       }
+       FN_END;
+       return;
+}
+
+static void __bt_ag_agent_battery_status_cb(keynode_t *node)
+{
+       int batt = vconf_keynode_get_int(node);
+
+       _bt_hfp_set_property_value("BatteryBarsChanged", batt);
+}
+
+static void __bt_ag_agent_network_signal_status_cb(keynode_t *node)
+{
+       int signal_bar = vconf_keynode_get_int(node);
+
+       BT_CHECK_SIGNAL_STRENGTH(signal_bar);
+       _bt_hfp_set_property_value("SignalBarsChanged", signal_bar);
+}
+
+#ifdef TIZEN_SUPPORT_LUNAR_DEVICE
+static void __bt_ag_agent_lunar_connection_status_cb(keynode_t *node)
+{
+       gboolean status = vconf_keynode_get_bool(node);
+       GSList *l;
+       DBG("status = %d", status);
+
+       if (status == TRUE) {
+               for (l = active_devices; l; l = l->next) {
+                       bt_ag_info_t *data = l->data;
+                       _bt_ag_send_at(data, "\r\n+BSIR:1\r\n");
+               }
+       }
+}
+#endif
+
+static void __bt_ag_agent_network_register_status_cb(keynode_t *node)
+{
+       int service = vconf_keynode_get_int(node);
+       bt_hfp_agent_network_registration_status_t network_service;
+       int roam_status;
+       int ret;
+
+       DBG("Current Signal Level = [%d] \n", service);
+
+       switch (service) {
+       case VCONFKEY_TELEPHONY_SVCTYPE_NONE:
+       case VCONFKEY_TELEPHONY_SVCTYPE_NOSVC:
+       case VCONFKEY_TELEPHONY_SVCTYPE_SEARCH:
+               service = 0;
+               break;
+       default:
+               service = 1;
+               break;
+       }
+
+       ret = vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &roam_status);
+       if (ret != 0) {
+               ERR("Get roaming status failed err = %d\n", ret);
+               return;
+       }
+
+       if (roam_status == 0 && service == 1)
+               network_service = BT_AGENT_NETWORK_REG_STATUS_HOME;
+       else if (roam_status == 1 && service == 1)
+               network_service = BT_AGENT_NETWORK_REG_STATUS_ROAMING;
+       else
+               network_service = BT_AGENT_NETWORK_REG_STATUS_UNKOWN;
+
+       _bt_hfp_set_property_value("RegistrationChanged", network_service);
+}
+
+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);
+       }
+#ifdef TIZEN_SUPPORT_LUNAR_DEVICE
+       ret = vconf_notify_key_changed(VCONF_KEY_BT_LUNAR_ENABLED,
+                       (void *)__bt_ag_agent_lunar_connection_status_cb, NULL);
+       if (0 != ret) {
+               ERR("Subsrciption to lunar connection failed err =  [%d]\n", ret);
+       }
+#endif
+}
+
+static void __bt_ag_agent_release_vconf_updates(void)
+{
+       int ret;
+
+       DBG("\n");
+
+       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");
+       }
+}
+
+static gboolean __bt_ag_agent_send_subscriber_number_changed(
+                                                       const char *number)
+{
+       const char *property = g_strdup("SubscriberNumberChanged");
+
+       FN_START;
+
+       DBG("Number is %s", number);
+
+       if (!_bt_hfp_set_property_name(property, number)) {
+               DBG("Error- set property for subscriber no change  - ERROR\n");
+               g_free((void *)property);
+               return FALSE;
+       }
+       g_free((void *)property);
+       FN_END;
+       return TRUE;
+}
+static void __bt_ag_agent_sigterm_handler(int signo)
+{
+       int i;
+       GSList *l;
+
+       ERR_C("***** Signal handler came with signal %d *****", signo);
+
+       for (l = active_devices ; l; l = l->next) {
+               bt_ag_info_t *data = l->data;
+               if (!__bt_ag_agent_connection_release(data))
+                       ERR("__bt_ag_agent_connection_release failed");
+       }
+       if (ag_dbus_conn)
+               g_dbus_connection_flush(ag_dbus_conn, NULL, NULL, NULL);
+
+       if (gmain_loop) {
+               g_main_loop_quit(gmain_loop);
+               DBG("Exiting");
+               gmain_loop = NULL;
+       } else {
+               INFO("Terminating AG agent");
+               exit(0);
+       }
+
+       if (signo == SIGTERM)
+               return;
+
+       for (i = 0; i < BT_AG_SIG_NUM; i++)
+               sigaction(bt_ag_sig_to_handle[i], &(bt_ag_sigoldact[i]), NULL);
+
+       raise(signo);
+}
+
+static void  __bt_ag_agent_tel_cb(TapiHandle *handle,
+                               int result,
+                               void *data,
+                               void *user_data)
+{
+       TelSimMsisdnList_t *number;
+       gchar *subscriber_number;
+
+       ERR("*********** result = %d", result);
+
+       if (result == TAPI_API_SIM_LOCKED ||
+               result == TAPI_API_SIM_NOT_INITIALIZED ||
+               result == TAPI_API_SERVICE_NOT_READY) {
+               DBG("initializing the tapi event for SIM status");
+               __bt_ag_agent_reg_sim_event(handle, user_data);
+               return;
+       }
+
+       if (data == NULL)
+               return;
+
+       number = (TelSimMsisdnList_t *)data;
+       subscriber_number = g_strdup(number->list[0].num);
+       __bt_ag_agent_send_subscriber_number_changed(subscriber_number);
+       g_free(subscriber_number);
+}
+
+static void __bt_ag_agent_on_noti_sim_status (TapiHandle *handle,
+               const char *noti_id, void *data, void *user_data)
+{
+       TelSimCardStatus_t *status = data;
+       int tapi_result;
+
+       DBG("event TAPI_NOTI_SIM_STATUS received!! status[%d]", *status);
+
+       if (*status == TAPI_SIM_STATUS_SIM_INIT_COMPLETED) {
+               __bt_ag_agent_dereg_sim_event(handle);
+               tapi_result = tel_get_sim_msisdn(handle, __bt_ag_agent_tel_cb,
+                                       user_data);
+               if (tapi_result != TAPI_API_SUCCESS)
+                       ERR("Fail to get sim info: %d", tapi_result);
+       }
+}
+
+static void __bt_ag_agent_reg_sim_event (TapiHandle *handle, void *user_data)
+{
+       int ret;
+       ret = tel_register_noti_event(handle, TAPI_NOTI_SIM_STATUS,
+               __bt_ag_agent_on_noti_sim_status, user_data);
+
+       if (ret != TAPI_API_SUCCESS)
+               ERR("event register failed(%d)", ret);
+}
+
+static void __bt_ag_agent_dereg_sim_event (TapiHandle *handle)
+{
+       int ret;
+       ret = tel_deregister_noti_event(handle, TAPI_NOTI_SIM_STATUS);
+
+       if (ret != TAPI_API_SUCCESS)
+               ERR("event deregister failed(%d)", ret);
+}
+
+static void __bt_ag_name_owner_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)
+{
+       FN_START;
+       char *name_owner = NULL;
+       char *old_owner = NULL;
+       char *new_owner = NULL;
+
+       if (strcasecmp(signal_name, "NameOwnerChanged") == 0) {
+               GSList *l;
+
+               g_variant_get(parameters, "(sss)", &name_owner, &old_owner, &new_owner);
+
+               _bt_hfp_release_all_calls_by_sender(name_owner);
+
+               if (sco_owner == NULL)
+                       return;
+
+               if (strcasecmp(name_owner, sco_owner) == 0) {
+                       if (name_owner_sig_id != -1)
+                               g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
+                                                       name_owner_sig_id);
+                       name_owner_sig_id = -1;
+                       g_free(sco_owner);
+                       sco_owner = NULL;
+
+                       for (l = active_devices ; l; l = l->next) {
+                               bt_ag_info_t *data = l->data;
+
+                               if (data->sco) {
+                                       __bt_ag_close_sco(data);
+                                       _bt_ag_set_headset_state(data,
+                                               HEADSET_STATE_CONNECTED);
+                               }
+                       }
+               }
+       }
+}
+
+static void __bt_ag_agent_filter_cb(GDBusConnection *connection,
+                                       const gchar *sender_name,
+                                       const gchar *object_path,
+                                       const gchar *interface_name,
+                                       const gchar *signal_name,
+                                       GVariant *parameters,
+                                       gpointer user_data)
+{
+       FN_START;
+       char *path = NULL;
+       GVariant *optional_param;
+
+       if (strcasecmp(signal_name, "InterfacesAdded") == 0) {
+
+               g_variant_get(parameters, "(&o@a{sa{sv}})",
+                                                       &path, &optional_param);
+               if (!path) {
+                       ERR("Invalid adapter path");
+                       return;
+               }
+
+               INFO("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,
+                                HFP_AG_UUID, "Hands-Free Audio Gateway");
+
+                       path =  g_strdup(BT_HS_AG_AGENT_OBJECT_PATH);
+                       __bt_ag_agent_register(path, hsp_ver,
+                               HSP_AG_UUID, "Headset Audio Gateway");
+               }
+       } else if (strcasecmp(signal_name, "InterfacesRemoved") == 0) {
+               g_variant_get(parameters, "(&o@as)", &path, &optional_param);
+               if (!path) {
+                       ERR("Invalid adapter path");
+                       return;
+               }
+
+               INFO("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);
+
+                       path =  g_strdup(BT_HS_AG_AGENT_OBJECT_PATH);
+                       __bt_ag_agent_unregister(path);
+               }
+       }
+
+       FN_END;
+}
+
+static void __bt_ag_agent_dbus_deinit(void)
+{
+
+       if (service_gproxy) {
+               g_object_unref(service_gproxy);
+               service_gproxy = NULL;
+       }
+
+       if (app_gproxy) {
+               g_object_unref(app_gproxy);
+               app_gproxy = NULL;
+       }
+
+       if (ag_dbus_conn) {
+               __bt_ag_unregister_profile_methods();
+
+               if (owner_sig_id != -1)
+                       g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
+                                               owner_sig_id);
+
+               if (name_owner_sig_id != -1)
+                       g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
+                                               name_owner_sig_id);
+#ifdef TIZEN_MEDIA_ENHANCE
+               if (media_sig_id != -1)
+                       g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
+                                               media_sig_id);
+
+               if (media_state_sig_id != -1)
+                       g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
+                                               media_state_sig_id);
+#endif
+               name_owner_sig_id = -1;
+               g_free(sco_owner);
+               sco_owner = NULL;
+
+               g_object_unref(ag_dbus_conn);
+               ag_dbus_conn= NULL;
+       }
+       return;
+}
+
+static int __bt_ag_agent_get_adapter_path(GDBusConnection *conn, char *path)
+{
+       GError *err = NULL;
+       GDBusProxy *manager_proxy = NULL;
+       GVariant *result = NULL;
+       char *adapter_path = NULL;
+
+       if (conn == NULL)
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+
+       manager_proxy =  g_dbus_proxy_new_sync(conn,
+                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       BLUEZ_SERVICE_NAME,
+                       "/",
+                       BT_MANAGER_INTERFACE,
+                       NULL, &err);
+
+       if (!manager_proxy) {
+               ERR("Unable to create proxy: %s", err->message);
+               goto fail;
+       }
+
+       result = g_dbus_proxy_call_sync(manager_proxy, "DefaultAdapter", NULL,
+                       G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
+       if (!result) {
+               if (err != NULL)
+                       ERR("Fail to get DefaultAdapter (Error: %s)", err->message);
+               else
+                       ERR("Fail to get DefaultAdapter");
+
+               goto fail;
+       }
+
+       if (g_strcmp0(g_variant_get_type_string(result), "(o)")) {
+               ERR("Incorrect result\n");
+               goto fail;
+       }
+
+       g_variant_get(result, "(&o)", &adapter_path);
+
+       if (adapter_path == NULL ||
+               strlen(adapter_path) >= BT_ADAPTER_OBJECT_PATH_MAX) {
+               ERR("Adapter path is inproper\n");
+               goto fail;
+       }
+
+       if (path)
+               g_strlcpy(path, adapter_path, BT_ADAPTER_OBJECT_PATH_MAX);
+
+       g_variant_unref(result);
+       g_object_unref(manager_proxy);
+
+       return 0;
+
+fail:
+       g_clear_error(&err);
+
+       if (result)
+               g_variant_unref(result);
+
+       if (manager_proxy)
+               g_object_unref(manager_proxy);
+
+       return BT_HFP_AGENT_ERROR_INTERNAL;
+
+}
+
+#ifdef TIZEN_MEDIA_ENHANCE
+void _bt_ag_agent_check_transport_state(void)
+{
+       FN_START;
+
+       if (transport_state == MEDIA_TRANSPORT_STATE_PLAYING) {
+               GDBusProxy *proxy;
+               GVariant *ret;
+               GError *err = NULL;
+
+               proxy =  g_dbus_proxy_new_sync(ag_dbus_conn,
+                               G_DBUS_PROXY_FLAGS_NONE, NULL,
+                               "org.PulseAudio2", A2DP_SOURCE_ENDPOINT,
+                               BLUEZ_MEDIA_ENDPOINT_INTERFACE, NULL, &err);
+
+               if (!proxy) {
+                       if (err) {
+                               ERR("Unable to create proxy: %s", err->message);
+                               g_clear_error(&err);
+                       }
+                       return;
+               }
+               INFO_C("SuspendMedia initiated");
+
+               g_dbus_proxy_call(proxy,
+                                       "SuspendMedia", NULL,
+                                       G_DBUS_CALL_FLAGS_NONE, 2000,
+                                       NULL, NULL, NULL);
+               transport_state = MEDIA_TRANSPORT_STATE_IDLE;
+       }
+
+       FN_END;
+}
+
+static void __bt_ag_agent_transport_state_update(const char *value)
+{
+
+       if (!g_strcmp0(value, "idle"))
+               transport_state = MEDIA_TRANSPORT_STATE_IDLE;
+       else if (!g_strcmp0(value, "pending") || !g_strcmp0(value, "active"))
+               transport_state = MEDIA_TRANSPORT_STATE_PLAYING;
+       else
+               transport_state =  MEDIA_TRANSPORT_STATE_DISCONNECTED;
+
+       INFO_C("transport_state %d", transport_state);
+}
+
+static void __bt_ag_agent_media_filter_cb(GDBusConnection *connection,
+                                       const gchar *sender_name,
+                                       const gchar *object_path,
+                                       const gchar *interface_name,
+                                       const gchar *signal_name,
+                                       GVariant *parameters,
+                                       gpointer user_data)
+{
+       FN_START;
+       char *inter = NULL;
+       GVariant *dict_param = NULL;
+       GVariant *optional_param = NULL;
+
+       if (strcasecmp(signal_name, "PropertiesChanged") == 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 (dict_param && (!g_strcmp0(inter,
+                               BLUEZ_MEDIA_TRANSPORT_INTERFACE))){
+                       GVariantIter *iter = NULL;
+                       const gchar *key = NULL;
+                       GVariant *value_var = NULL;
+                       gchar *value = NULL;
+                       g_variant_get(dict_param, "a{sv}", &iter);
+                       while (g_variant_iter_loop(
+                                       iter, "{sv}", &key, &value_var)) {
+                               DBG("key %s", key);
+                               if (g_strcmp0(key, "State") == 0) {
+                                       value = g_variant_get_string(
+                                                               value_var,
+                                                               NULL);
+                                       DBG("value %s", value);
+                                       __bt_ag_agent_transport_state_update(value);
+                                       break;
+                               }
+                       }
+                       g_variant_iter_free(iter);
+                       g_variant_unref(dict_param);
+               }
+       } else if (strcasecmp(signal_name, "ProfileStateChanged") == 0) {
+               char *profile_uuid = NULL;
+               int state = 0;
+
+               g_variant_get(parameters, "(&si)", &profile_uuid, &state);
+               if ((g_strcmp0(profile_uuid, A2DP_SINK_UUID) == 0)  &&
+                       (state == BT_PROFILE_STATE_DISCONNECTED)) {
+                       DBG("Updating the transport state");
+                       __bt_ag_agent_transport_state_update("Disconnect");
+               }
+       }
+
+       FN_END;
+}
+#endif
+static void __bt_ag_agent_dbus_init(void)
+{
+       FN_START;
+
+       if (__bt_ag_get_gdbus_connection() == NULL) {
+               ERR("Error in creating the gdbus connection\n");
+               return;
+       }
+       if (!__bt_ag_register_profile_methods()) {
+               ERR("Error in HFP / HSP register_profile_methods\n");
+               return;
+       }
+
+       if(!__bt_ag_agent_get_adapter_path(ag_dbus_conn , NULL)) {
+
+               gchar *path = g_strdup(BT_AG_AGENT_OBJECT_PATH);
+               __bt_ag_agent_register(path, hfp_ver,
+                        HFP_AG_UUID, "Hands-Free Audio Gateway");
+
+               path = g_strdup(BT_HS_AG_AGENT_OBJECT_PATH);
+               __bt_ag_agent_register(path, hsp_ver,
+                       HSP_AG_UUID, "Headset Audio Gateway");
+       }
+
+       owner_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn,
+                               NULL, BT_MANAGER_INTERFACE, NULL, NULL, NULL, 0,
+                               __bt_ag_agent_filter_cb, NULL, NULL);
+#ifdef TIZEN_MEDIA_ENHANCE
+       media_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn,
+                               NULL, BT_PROPERTIES_INTERFACE, NULL, NULL,
+                               NULL, 0, __bt_ag_agent_media_filter_cb,
+                               NULL, NULL);
+
+       media_state_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn,
+                               NULL, BLUEZ_DEVICE_INTERFACE, NULL, NULL,
+                               NULL, 0, __bt_ag_agent_media_filter_cb,
+                               NULL, NULL);
+
+       transport_state = MEDIA_TRANSPORT_STATE_DISCONNECTED;
+#endif
+       FN_END;
+       return;
+}
+
+static uint32_t __bt_ag_agent_get_ag_features(void)
+{
+
+       uint32_t ag_features = BT_AG_FEATURE_EC_AND_NR |
+                               BT_AG_FEATURE_REJECT_CALL |
+                               BT_AG_FEATURE_ENHANCED_CALL_STATUS |
+                               BT_AG_FEATURE_THREE_WAY_CALL |
+#ifndef TIZEN_KIRAN
+                               BT_AG_FEATURE_VOICE_RECOGNITION |
+#endif
+                               BT_AG_FEATURE_EXTENDED_ERROR_RESULT_CODES;
+
+       wbs_en = TRUE;
+#if defined(TIZEN_BT_HFP_AG_ENABLE)
+       hfp_ver = HFP_VERSION_1_6;
+#else
+       hfp_ver = HFP_VERSION_1_5;
+#endif
+       hsp_ver = HSP_VERSION_1_2;
+
+       if (hfp_ver == HFP_VERSION_1_6)
+               ag_features |= BT_AG_FEATURE_CODEC_NEGOTIATION;
+       return ag_features;
+}
+
+void *__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_subscribe_vconf_updates();
+
+       tapi_handle = tel_init(NULL);
+       tapi_result = tel_get_sim_msisdn(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;
+}
+
+int main(void)
+{
+       int i;
+       uint32_t ag_features;
+       struct sigaction sa;
+       pthread_t thread_id;
+
+       INFO_C("Starting Bluetooth AG agent");
+
+       g_type_init();
+
+       ag_features = __bt_ag_agent_get_ag_features();
+
+       ag.sdp_features = (uint16_t) ag_features & 0x1F;
+
+       if (hfp_ver == HFP_VERSION_1_6 && wbs_en == TRUE)
+               ag.sdp_features |= BT_AG_FEATURE_SDP_WIDEBAND_SPEECH;
+
+       memset(&sa, 0, sizeof(sa));
+       sa.sa_flags = SA_NOCLDSTOP;
+       sa.sa_handler = __bt_ag_agent_sigterm_handler;
+
+       for (i = 0; i < BT_AG_SIG_NUM; i++)
+               sigaction(bt_ag_sig_to_handle[i], &sa, &(bt_ag_sigoldact[i]));
+
+       gmain_loop = g_main_loop_new(NULL, FALSE);
+
+       if (gmain_loop == NULL) {
+               ERR("GMainLoop create failed");
+               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();
+
+       if (remote_dev_path)
+               g_free(remote_dev_path);
+
+       if (gmain_loop)
+               g_main_loop_unref(gmain_loop);
+
+       INFO_C("Terminating Bluetooth AG agent");
+       return 0;
+}
diff --git a/ag-agent/bluetooth-ag-agent.h b/ag-agent/bluetooth-ag-agent.h
new file mode 100644 (file)
index 0000000..1836ef1
--- /dev/null
@@ -0,0 +1,625 @@
+/*
+ * Bluetooth-ag-agent.h
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:    Hocheol Seo <hocheol.seo@samsung.com>
+ *             Chethan TN <chethan.tn@samsung.com>
+ *             Chanyeol Park <chanyeol.park@samsung.com>
+ *             Rakesh MK <rakesh.mk@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.
+ *
+ */
+
+#ifndef __DEF_BT_AG_AGENT_H_
+#define __DEF_BT_AG_AGENT_H_
+
+#undef LOG_TAG
+#define LOG_TAG "BLUETOOTH_AG_AGENT"
+
+#define LOG_COLOR_RESET    "\033[0m"
+#define LOG_COLOR_RED      "\033[31m"
+#define LOG_COLOR_YELLOW   "\033[33m"
+#define LOG_COLOR_GREEN         "\033[32m"
+#define LOG_COLOR_BLUE          "\033[36m"
+#define LOG_COLOR_PURPLE   "\033[35m"
+
+#define DBG(fmt, args...) SLOGD(fmt, ##args)
+#define INFO(fmt, args...) SLOGI(fmt, ##args)
+#define ERR(fmt, args...) SLOGE(fmt, ##args)
+#define DBG_SECURE(fmt, args...) SECURE_SLOGD(fmt, ##args)
+#define INFO_SECURE(fmt, args...) SECURE_SLOGI(fmt, ##args)
+#define ERR_SECURE(fmt, args...) SECURE_SLOGE(fmt, ##args)
+#define DBG_SECURE(fmt, args...) SECURE_SLOGD(fmt, ##args)
+#define ERR_SECURE(fmt, args...) SECURE_SLOGE(fmt, ##args)
+#define INFO_C(fmt, arg...) \
+       SLOGI_IF(TRUE,  LOG_COLOR_BLUE" "fmt" "LOG_COLOR_RESET, ##arg)
+#define ERR_C(fmt, arg...) \
+       SLOGI_IF(TRUE,  LOG_COLOR_RED" "fmt" "LOG_COLOR_RESET, ##arg)
+
+#include <unistd.h>
+#include <dlog.h>
+#include <stdio.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <sys/socket.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <errno.h>
+
+#include "vconf.h"
+#include "vconf-keys.h"
+
+#define BT_AG_SERVICE_NAME "org.bluez.ag_agent"
+#define BT_AG_AGENT_OBJECT_PATH "/org/bluez/hfp_agent"
+#define BT_HS_AG_AGENT_OBJECT_PATH "/org/bluez/hsp_agent"
+#define BLUEZ_AG_INTERFACE_NAME "Hands-Free Audio Gateway"
+#define BLUEZ_SERVICE_NAME "org.bluez"
+#define BLUEZ_PROFILE_MGMT_INTERFACE "org.bluez.ProfileManager1"
+#define BT_MANAGER_INTERFACE "org.freedesktop.DBus.ObjectManager"
+#define HFP_APP_INTERFACE "Org.Hfp.App.Interface"
+#define TELEPHONY_APP_INTERFACE "org.tizen.csd.Call.Instance"
+#define BT_HEADSET_INTERFACE "org.bluez.Headset"
+#define BT_ADAPTER_INTERFACE   "org.bluez.Adapter1"
+#ifdef TIZEN_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
+
+#define BT_ADAPTER_OBJECT_PATH_MAX 50
+
+#define BT_ADDRESS_STRING_SIZE 18
+#define MAX_BUFFER_SIZE 1024
+
+/* Response and hold values */
+#define BT_RSP_HOLD_NOT_SUPPORTED      -2
+#define HANDSFREE_FEATURE_CALL_WAITING_AND_3WAY 0x0002
+
+/* HFP Agent Indicator event values */
+#define INDICATOR_EVENT_SERVICE_NONE                   0
+#define INDICATOR_EVENT_SERVICE_PRESENT                1
+
+#define INDICATOR_EVENT_CALL_INACTIVE                  0
+#define INDICATOR_EVENT_CALL_ACTIVE                    1
+
+#define INDICATOR_EVENT_CALLSETUP_INACTIVE              0
+#define INDICATOR_EVENT_CALLSETUP_INCOMING              1
+#define INDICATOR_EVENT_CALLSETUP_OUTGOING              2
+#define INDICATOR_EVENT_CALLSETUP_ALERTING              3
+
+#define INDICATOR_EVENT_CALLHELD_NONE                  0
+#define INDICATOR_EVENT_CALLHELD_MULTIPLE              1
+#define INDICATOR_EVENT_CALLHELD_ON_HOLD               2
+
+#define INDICATOR_EVENT_ROAM_INACTIVE                  0
+#define INDICATOR_EVENT_ROAM_ACTIVE                    1
+
+/* Telephony number types */
+#define AGENT_NUMBER_TYPE_TELEPHONY            129
+#define AGENT_NUMBER_TYPE_INTERNATIONAL        145
+
+/* Call direction parameters */
+#define AGENT_CALL_DIRECTION_OUTGOING  0
+#define AGENT_CALL_DIRECTION_INCOMING          1
+
+#define AGENT_CALL_STATUS_ACTIVE               0
+#define AGENT_CALL_STATUS_HELD         1
+#define AGENT_CALL_STATUS_DIALING              2
+#define AGENT_CALL_STATUS_ALERTING     3
+#define AGENT_CALL_STATUS_INCOMING     4
+#define AGENT_CALL_STATUS_WAITING              5
+
+#define AGENT_CALL_MODE_VOICE          0
+#define AGENT_CALL_MODE_DATA           1
+#define AGENT_CALL_MODE_FAX            2
+
+#define AGENT_CALL_MULTIPARTY_NO               0
+#define AGENT_CALL_MULTIPARTY_YES              1
+
+/* Subscriber number parameters*/
+#define AGENT_SUBSCRIBER_SERVICE_VOICE 4
+
+/* Operator selection mode values */
+#define AGENT_OPERATOR_MODE_AUTO                       0
+#define HSP_VERSION_1_2  0x0102
+
+/* Voice recognition blacklist file */
+#define AGENT_VR_BLACKLIST_FILE (APP_SYSCONFDIR"/voice-recognition-blacklist")
+
+#define BT_LOWER_ADDRESS_LENGTH 9
+
+enum hfp_version {
+       HFP_VERSION_1_5 = 0x0105,
+       HFP_VERSION_1_6 = 0x0106,
+       HFP_VERSION_LATEST = HFP_VERSION_1_6,
+};
+
+/* BD Address */
+typedef struct {
+       uint8_t b[6];
+} __attribute__((packed)) bt_addrs;
+
+/**
+ * @brief Outgoing call type status
+ *
+ * 0 : Follow last call log \n
+ * 1 : Voice call \n
+ * 2 : Video call \n
+ */
+#define BT_FOLLOW_CALL_LOG 0
+#define BT_VOICE_CALL 1
+#define BT_VIDEO_CALL 2
+
+/**
+ * @brief The status of making outgoing calls with BT headsets
+ *
+ * 0 : Even when device locked \n
+ * 1 : Only when device unlocked \n
+ */
+#define BT_MO_EVEN_LOCKED 0
+#define BT_MO_ONLY_UNLOCKED 1
+
+#define BT_CVSD_CODEC_ID 1
+#define BT_MSBC_CODEC_ID 2
+
+#define BT_CVSD_CODEC_MASK 0x0001
+#define BT_MSBC_CODEC_MASK 0x0002
+
+#define BT_HFP_MSBC_VOICE                      0x0063
+#define BT_HFP_CVSD_VOICE                      0x0060
+
+#define BT_SOCKET_LEVEL                        274
+#define BT_VOICE_NUM                   11
+
+#define BT_SCO_PRTCL   2
+
+#define HFP_CODEC_NEGOTIATION_TIMEOUT 3 /* 3 seconds */
+
+#define BT_SCO_OPEN_DELAY_TIMER 1000 /*1000 milliseconds*/
+
+/* AT+CSQ : Returns received signal strength indication.
+     Command response: +CSQ: <rssi>,<ber>
+    <ber> is not supported and has a constant value of 99, included for compatibility reasons.
+*/
+#define BT_SIGNAL_QUALITY_BER 99
+
+/*Length of the string used to send telephone number*/
+#define BT_MAX_TEL_NUM_STRING 30
+
+#define FUCNTION_CALLS
+#ifdef FUCNTION_CALLS
+#define FN_START       DBG("ENTER==>")
+#define FN_END         DBG("EXIT===>")
+#else
+#define FN_START
+#define FN_END
+#endif
+
+/* HS states */
+typedef enum {
+       HEADSET_STATE_DISCONNECTED,
+       HEADSET_STATE_CONNECTING,
+       HEADSET_STATE_CONNECTED,
+       HEADSET_STATE_PLAY_IN_PROGRESS,
+       HEADSET_STATE_ON_CALL
+} hs_state_t;
+
+typedef enum {
+       HFP_STATE_MNGR_ERR_AG_FAILURE = 0,
+       HFP_STATE_MNGR_NO_PHONE_CONNECTION = 1,
+       HFP_STATE_MNGR_ERR_NOT_ALLOWED  = 3,
+       HFP_STATE_MNGR_ERR_NOT_SUPPORTED        = 4,
+       HFP_STATE_MNGR_ERR_SIM_BUSY     = 14,
+       HFP_STATE_MNGR_ERR_INVALID_INDEX        = 21,
+       HFP_STATE_MNGR_ERR_INVALID_CHAR_IN_STRING       = 25,
+       HFP_STATE_MNGR_ERR_NO_NETWORK_SERVICE   = 30,
+       HFP_STATE_MNGR_ERR_NONE = 0x8000
+} hfp_state_manager_err_t;
+
+typedef enum {
+       BT_AG_FEATURE_THREE_WAY_CALL                    = 0x0001,
+       BT_AG_FEATURE_EC_AND_NR                         = 0x0002,
+       BT_AG_FEATURE_VOICE_RECOGNITION                 = 0x0004,
+       BT_AG_FEATURE_INBAND_RINGTONE                   = 0x0008,
+       BT_AG_FEATURE_ATTACH_NUMBER_TO_VOICETAG         = 0x0010,
+       BT_AG_FEATURE_REJECT_CALL                       = 0x0020,
+       BT_AG_FEATURE_ENHANCED_CALL_STATUS              = 0x0040,
+       BT_AG_FEATURE_ENHANCED_CALL_CONTROL             = 0x0080,
+       BT_AG_FEATURE_EXTENDED_ERROR_RESULT_CODES       = 0x0100,
+       BT_AG_FEATURE_CODEC_NEGOTIATION                 = 0x0200,
+} bt_ag_agent_feature_t;
+
+typedef enum {
+       BT_HF_FEATURE_EC_ANDOR_NR                       = 0x0001,
+       BT_HF_FEATURE_CALL_WAITING_AND_3WAY     = 0x0002,
+       BT_HF_FEATURE_CLI_PRESENTATION          = 0x0004,
+       BT_HF_FEATURE_VOICE_RECOGNITION         = 0x0008,
+       BT_HF_FEATURE_REMOTE_VOLUME_CONTROL     = 0x0010,
+       BT_HF_FEATURE_ENHANCED_CALL_STATUS              = 0x0020,
+       BT_HF_FEATURE_ENHANCED_CALL_CONTROL     = 0x0040,
+       BT_HF_FEATURE_CODEC_NEGOTIATION = 0x0080,
+} bt_hf_agent_feature_t;
+
+/* 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
+#define BT_AG_FEATURE_SDP_VOICE_RECOG          0x4
+#define BT_AG_FEATURE_SDP_IN_BAND_RING_TONE    0x8
+#define BT_AG_FEATURE_SDP_ATTACH_VOICE_TAG             0x10
+#define BT_AG_FEATURE_SDP_WIDEBAND_SPEECH              0x20
+
+#define BT_AG_AGENT_ERROR (__bt_ag_agent_error_quark())
+
+#define BT_ERROR_INTERNAL "InternalError"
+#define BT_ERROR_NOT_AVAILABLE "NotAvailable"
+#define BT_ERROR_NOT_CONNECTED "NotConnected"
+#define BT_ERROR_BUSY "InProgress"
+#define BT_ERROR_INVALID_PARAM "InvalidArguments"
+#define BT_ERROR_ALREADY_EXSIST "AlreadyExists"
+#define BT_ERROR_ALREADY_CONNECTED "Already Connected"
+#define BT_ERROR_NO_MEMORY "No memory"
+#define BT_ERROR_I_O_ERROR "I/O error"
+#define BT_ERROR_OPERATION_NOT_AVAILABLE "Operation currently not available"
+#define BT_ERROR_BATTERY "Battery error "
+#define BT_ERROR_SIGNAL "Signal error"
+#define BT_ERROR_NO_CALL_LOG "No Call log"
+#define BT_ERROR_INVLAID_DTMF "Invalid dtmf"
+
+#define BT_CHECK_SIGNAL_STRENGTH(rssi) \
+       if (rssi >= VCONFKEY_TELEPHONY_RSSI_4) \
+               rssi = VCONFKEY_TELEPHONY_RSSI_5
+
+typedef enum {
+       BT_HFP_AGENT_ERROR_NONE,
+       BT_HFP_AGENT_ERROR_INTERNAL,
+       BT_HFP_AGENT_ERROR_NOT_AVAILABLE,
+       BT_HFP_AGENT_ERROR_NOT_CONNECTED,
+       BT_HFP_AGENT_ERROR_BUSY,
+       BT_HFP_AGENT_ERROR_INVALID_PARAM,
+       BT_HFP_AGENT_ERROR_ALREADY_EXSIST,
+       BT_HFP_AGENT_ERROR_ALREADY_CONNECTED,
+       BT_HFP_AGENT_ERROR_NO_MEMORY,
+       BT_HFP_AGENT_ERROR_I_O_ERROR,
+       BT_HFP_AGENT_ERROR_OPERATION_NOT_AVAILABLE,
+       BT_HFP_AGENT_ERROR_NO_CALL_LOGS,
+       BT_HFP_AGENT_ERROR_INVALID_MEMORY_INDEX,
+       BT_HFP_AGENT_ERROR_INVALID_CHLD_INDEX,
+       BT_HFP_AGENT_ERROR_BATTERY_STATUS,
+       BT_HFP_AGENT_ERROR_SIGNAL_STATUS,
+       BT_HFP_AGENT_ERROR_NOT_SUPPORTED,
+       BT_HFP_AGENT_ERROR_INVALID_NUMBER,
+       BT_HFP_AGENT_ERROR_APPLICATION,
+       BT_HFP_AGENT_ERROR_INVALID_DTMF,
+} bt_hfp_agent_error_t;
+
+typedef enum {
+       BT_AGENT_NETWORK_REG_STATUS_HOME,
+       BT_AGENT_NETWORK_REG_STATUS_ROAMING,
+       BT_AGENT_NETWORK_REG_STATUS_OFFLINE,
+       BT_AGENT_NETWORK_REG_STATUS_SEARCHING,
+       BT_AGENT_NETWORK_REG_STATUS_NO_SIM,
+       BT_AGENT_NETWORK_REG_STATUS_POWEROFF,
+       BT_AGENT_NETWORK_REG_STATUS_POWERSAFE,
+       BT_AGENT_NETWORK_REG_STATUS_NO_COVERAGE,
+       BT_AGENT_NETWORK_REG_STATUS_REJECTED,
+       BT_AGENT_NETWORK_REG_STATUS_UNKOWN,
+} bt_hfp_agent_network_registration_status_t;
+
+typedef enum {
+       BT_AGENT_NETWORK_REG_STATUS_NOT_REGISTER,
+       BT_AGENT_NETWORK_REG_STATUS_REGISTER_HOME_NETWORK,
+       BT_AGENT_NETWORK_REG_STATUS_SEARCH,
+       BT_AGENT_NETWORK_REG_STATUS_REGISTRATION_DENIED,
+       BT_AGENT_NETWORK_REG_STATUS_UNKNOWN,
+       BT_AGENT_NETWORK_REG_STATUS_REGISTERED_ROAMING,
+       BT_AGENT_NETWORK_REG_STATUS_REGISTERED_SMS_HOME,
+       BT_AGENT_NETWORK_REG_STATUS_REGISTERED_SMS_ROAMING,
+       BT_AGENT_NETWORK_REG_STATUS_EMERGENCY,
+       BT_AGENT_NETWORK_REG_STATUS_REGISTERED_CSFB_HOME,
+       BT_AGENT_NETWORK_REG_STATUS_REGISTERED_CSFB_ROAMING,
+} bt_hfp_agent_reg_status_t;
+
+#ifdef TIZEN_MEDIA_ENHANCE
+typedef enum media_transport_state {
+    MEDIA_TRANSPORT_STATE_DISCONNECTED,
+    MEDIA_TRANSPORT_STATE_IDLE,
+    MEDIA_TRANSPORT_STATE_PLAYING
+} bt_ag_media_transport_state_t;
+
+/* Profile states matched to btd_service_state_t of bluez service.h */
+typedef enum {
+       BT_PROFILE_STATE_UNAVAILABLE,
+       BT_PROFILE_STATE_DISCONNECTED,
+       BT_PROFILE_STATE_CONNECTING,
+       BT_PROFILE_STATE_CONNECTED,
+       BT_PROFILE_STATE_DISCONNECTING,
+} bt_profile_state_t;
+#endif
+
+#define retv_if(expr, val) \
+       do { \
+               if (expr) { \
+                       ERR("(%s) return", #expr); \
+                       return (val); \
+               } \
+       } while (0)
+
+#define ret_if(expr) \
+       do { \
+               if (expr) { \
+                       ERR("(%s) return", #expr); \
+                       return; \
+               } \
+       } while (0)
+
+typedef struct {
+       unsigned char b[6];
+} __attribute__((packed)) bdaddr_t;
+
+/* Remote socket address */
+struct sockaddr_remote {
+       sa_family_t     family;
+       bdaddr_t        remote_bdaddr;
+       uint8_t         channel;
+};
+
+typedef struct {
+       const char *indicator_desc;
+       const char *indicator_range;
+       int hfp_value;
+       gboolean ignore;
+       gboolean is_activated;
+} bt_ag_indicators_t;
+
+typedef struct {
+       gboolean telephony_ready;       /* plugin initialized */
+       uint32_t features;            /* AG features */
+       const bt_ag_indicators_t *indicators;     /* Supported indicators */
+       int er_mode;               /* Event reporting mode */
+       int er_ind;                 /* Event reporting for indicators */
+       int rh;                 /* Response and Hold state */
+       char *number;             /* Incoming phone number */
+       int number_type;                /* Incoming number type */
+       guint ring_timer;               /* For incoming call indication */
+       const char *chld;               /* Response to AT+CHLD=? */
+       uint32_t sdp_features; /* SDP features */
+} bt_ag_status_t;
+
+typedef struct {
+       char buffer[MAX_BUFFER_SIZE];
+
+       int start;
+       int length;
+
+       gboolean is_nrec;
+       gboolean is_nrec_req;
+       gboolean is_pending_ring;
+       gboolean is_inband_ring;
+       gboolean is_cme_enabled;
+       gboolean is_cwa_enabled;
+       gboolean is_client_active;
+       gboolean is_voice_recognition_running;
+
+       int speaker_gain;
+       int microphone_gain;
+
+       unsigned int hs_features;
+} bt_ag_slconn_t;
+
+typedef struct {
+/*     DBusMessage *msg;
+       DBusPendingCall *call;*/
+       GIOChannel *io;
+       int err;
+       hs_state_t target_state;
+       GSList *callbacks;
+       uint16_t svclass;
+} hs_connecting_t;
+
+typedef struct {
+       char *object_path;
+       gboolean is_negotiating;
+       gboolean requested_by_hf;
+       guint nego_timer;
+       unsigned int remote_codecs;
+       unsigned int sending_codec;
+       unsigned int final_codec;
+} bt_negotiation_info_t;
+
+typedef struct {
+       const char *path;
+       guint32 fd;
+
+       gboolean auto_connect;
+       GIOChannel *io_chan;
+       char *remote_addr;
+       guint watch_id;
+       GIOChannel *sco_server;
+       guint sco_watch_id;
+
+       GIOChannel *rfcomm;
+       GIOChannel *sco;
+       guint sco_id;
+       guint codec;
+
+       gboolean auto_dc;
+
+       guint dc_timer;
+
+       gboolean hfp_active;
+       gboolean search_hfp;
+       gboolean rfcomm_initiator;
+       gboolean vr_blacklisted;
+
+       hs_state_t state;
+       bt_ag_slconn_t *slc;
+       hs_connecting_t *pending;
+       GSList *nrec_cbs;
+       gboolean sco_server_started;
+       gboolean nrec_status;
+       bt_negotiation_info_t codec_info;
+#if defined(TIZEN_SUPPORT_DUAL_HF)
+       gboolean is_companion_device;
+#endif
+} bt_ag_info_t;
+
+typedef void (*headset_nrec_cb) (bt_ag_info_t *hs,
+                                       gboolean nrec,
+                                       void *user_data);
+
+struct hs_nrec_callback {
+       unsigned int id;
+       headset_nrec_cb cb;
+       void *user_data;
+};
+
+typedef void (*hs_state_cb) (bt_ag_info_t *hs,
+               hs_state_t old_state,
+               hs_state_t new_state,
+               void *user_data);
+
+struct hs_state_callback {
+               hs_state_cb cb;
+               void *user_data;
+               unsigned int id;
+};
+
+int __attribute__((format(printf, 2, 3)))
+                       _bt_ag_send_at(bt_ag_info_t *hs, char *format, ...);
+void __attribute__((format(printf, 3, 4)))
+               _bt_ag_send_foreach_headset(GSList *devices,
+               int (*cmp) (bt_ag_info_t *hs),
+               char *format, ...);
+void _bt_ag_slconn_complete(bt_ag_info_t *hs);
+int _bt_ag_send_response(bt_ag_info_t *hs, hfp_state_manager_err_t err);
+void _bt_hfp_call_hold_request(const char *t_cmd, void *t_device);
+void _bt_hfp_key_press_request(const char *t_key_press, void *t_device);
+void _bt_hfp_terminate_call_request(void *t_device);
+void _bt_hfp_answer_call_request(void *t_device);
+void _bt_hfp_update_event_request(int indicator, void *t_device);
+void _bt_hfp_response_and_hold_request(void *t_device);
+void _bt_hfp_last_dialed_number_request(void *t_device);
+void _bt_hfp_dial_number_request(const char *dial_number, void *t_device);
+void _bt_hfp_channel_dtmf_request(char t_tone, void *t_device);
+void _bt_hfp_subscriber_number_request(void *t_device);
+void _bt_hfp_get_operator_selection_request(void *t_device);
+void _bt_hfp_noise_red_and_echo_cancel_request(gboolean t_enable,
+                       void *t_device);
+void _bt_hfp_voice_dial_request(gboolean t_enable, void *t_device);
+void _bt_hfp_set_indicators(const char *t_command, void *t_device);
+void _bt_hfp_select_phonebook_memory_status(void *t_device);
+void _bt_hfp_select_phonebook_memory_list(void *t_device);
+void _bt_hfp_select_phonebook_memory(void *t_device, const gchar *pb_path);
+void _bt_hfp_read_phonebook_entries_list(void *t_device);
+void _bt_hfp_read_phonebook_entries(void *t_device, const char *cmd);
+void _bt_hfp_find_phonebook_entries_status(void *t_device);
+void _bt_hfp_find_phonebook_entries(void *t_device, const char *cmd);
+void _bt_hfp_get_character_set(void *t_device);
+void _bt_hfp_list_supported_character(void *t_device);
+void _bt_hfp_set_character_set(void *t_device, const char *cmd);
+void _bt_hfp_get_battery_property(void *t_device);
+void _bt_hfp_signal_quality_reply(int32_t rssi, int32_t ber,
+       void *t_device);
+void _bt_hfp_battery_property_reply(void *data, int32_t bcs,
+                       int32_t bcl);
+void _bt_hfp_operator_reply(char *operator_name,  void *t_device);
+bt_hfp_agent_error_t _bt_ag_agent_dial_num(const gchar *number, guint flags);
+bt_hfp_agent_error_t _bt_ag_agent_dial_last_num(void *device);
+bt_hfp_agent_error_t _bt_ag_agent_send_dtmf(const gchar *dtmf,
+                               const gchar *path, const gchar *sender);
+bt_hfp_agent_error_t _bt_ag_agent_dial_memory(unsigned int location);
+gboolean _bt_ag_agent_get_signal_quality(void *device);
+gboolean _bt_ag_agent_get_battery_status(void *device);
+gboolean _bt_ag_agent_get_operator_name(void *device);
+gboolean _bt_hfp_agent_nrec_status(gboolean status,
+       void *t_device);
+gboolean _bt_ag_agent_voice_dial(gboolean activate);
+gboolean _bt_ag_agent_answer_call(unsigned int call_id,
+                               const gchar *path, const gchar *sender);
+gboolean _bt_ag_agent_reject_call(unsigned int call_id,
+                               const gchar *path, const gchar *sender);
+gboolean _bt_ag_agent_release_call(unsigned int call_id,
+                               const gchar *path, const gchar *sender);
+gboolean _bt_ag_agent_threeway_call(unsigned int chld_value,
+                               const gchar *path, const gchar *sender);
+void _bt_list_current_calls(void *t_device);
+void _bt_get_activity_status(void *t_device);
+int _bt_hfp_set_property_name(const char *property, const char *operator_name);
+void _bt_hfp_get_imei_number_reply(char *imei_number,  void *t_device);
+void _bt_hfp_get_model_info_reply(char *model,  void *t_device);
+void _bt_hfp_get_device_manufacturer_reply(char *manufacturer,  void *t_device);
+void _bt_hfp_get_revision_info_reply(char *revision,  void *t_device);
+void _bt_hfp_device_disconnected(void *t_device);
+int _bt_hfp_get_equipment_identity(bt_ag_info_t *device, const char *buf);
+int _bt_hfp_get_model_information(bt_ag_info_t *device, const char *buf);
+int _bt_hfp_get_device_manufacturer(bt_ag_info_t *device, const char *buf);
+int _bt_hfp_get_imsi(bt_ag_info_t *device, const char *buf);
+int _bt_hfp_get_creg_status(bt_ag_info_t *device, const char *buf);
+int _bt_hfp_get_revision_information(bt_ag_info_t *device, const char *buf);
+void _bt_hfp_get_equipment_identity_req(void *t_device);
+bt_hfp_agent_error_t _bt_hfp_register_telephony_agent(gboolean register_flag,
+               const char *path_to_register,
+               const char *sender);
+bt_hfp_agent_error_t _bt_hfp_incoming_call(const char *call_path,
+               const char *incoming_number,
+               uint32_t incoming_call_id,
+               const char *sender);
+bt_hfp_agent_error_t _bt_hfp_outgoing_call(const char *call_path,
+               const char *number,
+               uint32_t call_id, const char *sender);
+bt_hfp_agent_error_t _bt_hfp_change_call_status(const char *call_path,
+               const char *number,
+               uint32_t call_status,
+               uint32_t call_id,
+               const char *sender);
+void _bt_hfp_initialize_telephony_manager(uint32_t ag_features);
+void _bt_hfp_deinitialize_telephony_manager(void);
+gboolean _bt_ag_agent_emit_property_changed(
+                               GDBusConnection *connection,
+                               const char *path,
+                               const char *interface,
+                               const char *name,
+                               GVariant *property);
+void _bt_hfp_get_model_info_req(void *t_device);
+void _bt_hfp_get_device_manufacturer_req(void *t_device);
+void _bt_hfp_get_imsi_req(void *t_device);
+void _bt_hfp_get_creg_status_req(void *t_device);
+void _bt_hfp_get_revision_info_req(void *t_device);
+gboolean _bt_hfp_is_call_exist(void);
+void _bt_hfp_release_all_calls_by_sender(const char *sender);
+void _bt_hfp_get_imsi_reply(char *mcc, char *mnc, char *msin, void *t_device);
+void _bt_hfp_get_creg_status_reply(int n, int status, void *t_device);
+int _bt_hfp_set_property_value(const char *property, int value);
+void _bt_hfp_vendor_cmd_request(const char *cmd,
+                                               void *t_device);
+
+gboolean _bt_ag_agent_get_imei_number(void *device);
+void _bt_ag_agent_get_model_name(void *device);
+void _bt_ag_agent_get_manufacturer_name(void *device);
+void _bt_ag_agent_get_imsi(void *device);
+void _bt_ag_agent_get_creg_status(void *device);
+void _bt_ag_agent_get_revision_information(void *device);
+bt_hfp_agent_error_t _bt_ag_agent_vendor_cmd(const gchar *cmd,
+               const gchar *path, const gchar *sender);
+#ifdef TIZEN_MEDIA_ENHANCE
+void _bt_ag_agent_check_transport_state(void);
+#endif
+
+#endif /* __DEF_BT_AG_AGENT_H_ */
diff --git a/ag-agent/bluetooth-ag-handler.c b/ag-agent/bluetooth-ag-handler.c
new file mode 100644 (file)
index 0000000..06cc641
--- /dev/null
@@ -0,0 +1,1431 @@
+/*
+ * bluetooth-ag-handler.c
+ *
+ * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:    Hocheol Seo <hocheol.seo@samsung.com>
+ *             Chethan TN <chethan.tn@samsung.com>
+ *             Chanyeol Park <chanyeol.park@samsung.com>
+ *             Rakesh MK <rakesh.mk@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-agent.h"
+#include "bluetooth-ag-handler.h"
+#include "vconf.h"
+#include "vconf-keys.h"
+
+extern bt_ag_status_t ag;
+extern GSList *active_devices;
+extern GDBusConnection *ag_dbus_conn;
+extern gchar *remote_dev_path;
+
+ /* AT+CSQ : Returns received signal strength indication.
+     Command response: +CSQ: <rssi>,<ber>
+    <ber> is not supported and has a constant value of 99, included for compatibility reasons.
+*/
+#define BT_SIGNAL_QUALITY_BER 99
+
+wbs_options wbs_opts = {
+       .wbs_enable = FALSE,
+       .i2s_enable = 0x00,
+       .is_master = 0x00,
+       .clock_rate = 0x02,
+       .pcm_interface_rate = 0x00,
+};
+
+/* AT+BRSF response */
+int _bt_hfp_supported_features(bt_ag_info_t *hs, const char *buf)
+{
+       bt_ag_slconn_t *slconn = hs->slc;
+       int err;
+//     bt_hfp_agent_error_t ret = BT_HFP_AGENT_ERROR_NONE;
+
+       DBG("AT + BRSF");
+       if (strlen(buf) < 9)
+               return -EINVAL;
+
+       slconn->hs_features = strtoul(&buf[8], NULL, 10);
+#if 0 /* SCO is crashed if below is called when SCO is opened by hf-agent */
+       if (slconn->hs_features & BT_HF_FEATURE_CODEC_NEGOTIATION) {
+               ret = _bt_ag_set_codec(hs, "SetWbsParameters");
+               if (ret != BT_HFP_AGENT_ERROR_NONE)
+                       ERR("Unable to set the default WBC codec");
+       } else {
+               /* Default codec is NB */
+               ret = _bt_ag_set_codec(hs, "SetNbParameters");
+               if (ret != BT_HFP_AGENT_ERROR_NONE)
+                       ERR("Unable to set the default NBC codec");
+       }
+#endif
+       err = _bt_ag_send_at(hs, "\r\n+BRSF: %u\r\n", ag.features);
+       if (err < 0)
+               return err;
+
+       return _bt_ag_send_at(hs, "\r\nOK\r\n");
+}
+
+static char *__bt_get_indicator_ranges(const bt_ag_indicators_t *indicators)
+{
+       int i;
+       GString *gstr;
+
+       DBG("__bt_get_indicator_ranges");
+       gstr = g_string_new("\r\n+CIND: ");
+
+       for (i = 0; indicators[i].indicator_desc != NULL; i++) {
+               if (i == 0)
+                       g_string_append_printf(gstr, "(\"%s\",(%s))",
+                               indicators[i].indicator_desc,
+                               indicators[i].indicator_range);
+               else
+                       g_string_append_printf(gstr, ",(\"%s\",(%s))",
+                               indicators[i].indicator_desc,
+                               indicators[i].indicator_range);
+       }
+       g_string_append(gstr, "\r\n");
+       return g_string_free(gstr, FALSE);
+}
+
+static char *__bt_get_indicator_values(const bt_ag_indicators_t *indicators)
+{
+       int i;
+       GString *gstr;
+
+       gstr = g_string_new("\r\n+CIND: ");
+       DBG("__bt_get_indicator_values");
+       for (i = 0; indicators[i].indicator_range != NULL; i++) {
+               if (i == 0)
+                       g_string_append_printf(gstr, "%d",
+                               indicators[i].hfp_value);
+               else
+                       g_string_append_printf(gstr, ",%d",
+                               indicators[i].hfp_value);
+       }
+       g_string_append(gstr, "\r\n");
+
+       return g_string_free(gstr, FALSE);
+}
+
+static int __bt_check_hdset(bt_ag_info_t *hdset)
+{
+       bt_ag_slconn_t *slconn = hdset->slc;
+
+       if (!hdset->hfp_active)
+               return -1;
+
+       if (slconn->is_client_active)
+               return 0;
+       else
+               return -1;
+}
+
+static int __bt_hfp_cmp(bt_ag_info_t *hs)
+{
+       if (hs->hfp_active)
+               return 0;
+       else
+               return -1;
+}
+
+static int __bt_cwa_cmp(bt_ag_info_t *hs)
+{
+       if (!hs->hfp_active)
+               return -1;
+
+       if (hs->slc->is_cwa_enabled)
+               return 0;
+       else
+               return -1;
+}
+
+gboolean __bt_ring_timer_cb(gpointer data)
+{
+       _bt_ag_send_foreach_headset(active_devices, NULL, "\r\nRING\r\n");
+
+       if (ag.number)
+               _bt_ag_send_foreach_headset(active_devices, __bt_check_hdset,
+                                       "\r\n+CLIP: \"%s\",%d\r\n",
+                                       ag.number, ag.number_type);
+
+       return TRUE;
+}
+
+int _bt_incoming_call_indicator(const char *number, int type)
+{
+       bt_ag_info_t *hs;
+       bt_ag_slconn_t *slconn;
+
+       if (!active_devices)
+               return -ENODEV;
+
+       /* Get the updated list of connected devices */
+       hs = active_devices->data;
+       slconn = hs->slc;
+
+       if (ag.ring_timer) {
+               DBG("incoming_call_indicator: already calling....");
+               return -EBUSY;
+       }
+
+       /*If inband ring supported then no need to send RING alert to HF */
+       if (!hs->hfp_active && slconn->is_inband_ring) {
+               DBG("Inband ring tone supported");
+               return 0;
+       }
+
+       DBG("Inband ring tone not supported.. so send a RING to HF");
+       g_free(ag.number);
+       ag.number = g_strdup(number);
+       ag.number_type = type;
+
+       if (slconn->is_inband_ring &&
+                                       hs->state != HEADSET_STATE_ON_CALL) {
+               slconn->is_pending_ring = TRUE;
+               return 0;
+       }
+
+       __bt_ring_timer_cb(NULL);
+       ag.ring_timer = g_timeout_add(AG_RING_INTERVAL, __bt_ring_timer_cb, NULL);
+
+       return 0;
+}
+
+int _bt_calling_stopped_indicator(void)
+{
+       bt_ag_info_t *dev;
+
+       if (ag.ring_timer) {
+               g_source_remove(ag.ring_timer);
+               ag.ring_timer = 0;
+       }
+
+       if (!active_devices)
+               return 0;
+
+       /* In case SCO is in intermediate state to connect */
+       dev = active_devices->data;
+
+       if (!dev->slc->is_pending_ring && !ag.ring_timer)
+               return -EINVAL;
+
+       dev->slc->is_pending_ring = FALSE;
+
+       return 0;
+}
+
+void _bt_hfp_set_ag_indicator(uint32_t ag_features,
+                       const bt_ag_indicators_t *ag_indicators, int rh,
+                       const char *chld)
+{
+       DBG("Set Ag Features");
+       ag.telephony_ready = TRUE;
+       ag.features = ag_features;
+       ag.indicators = ag_indicators;
+       ag.rh = rh;
+       ag.chld = chld;
+}
+
+void _bt_hfp_deinitialize(void)
+{
+       g_free(ag.number);
+       memset(&ag, 0, sizeof(ag));
+       ag.rh = BT_RSP_HOLD_NOT_SUPPORTED;
+       ag.er_mode = 3;
+}
+
+/* Send event indication call from Statemanager module */
+bt_hfp_agent_error_t _bt_hfp_event_indicator(int index)
+{
+       if (!active_devices) {
+               DBG("No Active devices present");
+               return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
+       }
+
+       if (!ag.er_ind) {
+               DBG("Indicate event called but event reporting is disabled");
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+       }
+
+       DBG("Sending event notification to hf....");
+
+       _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
+                               "\r\n+CIEV: %d,%d\r\n", index + 1,
+                               ag.indicators[index].hfp_value);
+
+       return BT_HFP_AGENT_ERROR_NONE;
+}
+
+/* AT+CIND response */
+int _bt_hfp_report_indicators(bt_ag_info_t *hs, const char *buf)
+{
+       int err;
+       char *str;
+
+       if (strlen(buf) < 8)
+               return -EINVAL;
+
+       if (buf[7] == '=')
+               str = __bt_get_indicator_ranges(ag.indicators);
+       else
+               str = __bt_get_indicator_values(ag.indicators);
+
+       err = _bt_ag_send_at(hs, "%s", str);
+
+       g_free(str);
+
+       if (err < 0)
+               return err;
+
+       return _bt_ag_send_at(hs, "\r\nOK\r\n");
+}
+
+/* AT+CMER response */
+int _bt_event_reporting_response(void *t_device,
+                               bt_hfp_agent_error_t err)
+{
+       bt_ag_info_t *hdset = t_device;
+       bt_ag_slconn_t *slconn = hdset->slc;
+       int ret_val;
+
+       if (err != (bt_hfp_agent_error_t) HFP_STATE_MNGR_ERR_NONE)
+               return _bt_ag_send_response(t_device, err);
+
+       ret_val = _bt_ag_send_at(hdset, "\r\nOK\r\n");
+       if (ret_val < 0)
+               return ret_val;
+
+       if (hdset->state != HEADSET_STATE_CONNECTING)
+               return 0;
+
+       if (slconn->hs_features & HANDSFREE_FEATURE_CALL_WAITING_AND_3WAY &&
+                       ag.features & BT_AG_FEATURE_THREE_WAY_CALL)
+               return 0;
+
+       _bt_ag_slconn_complete(hdset);
+
+       return 0;
+}
+
+int _bt_hfp_enable_indicators(bt_ag_info_t *hdset, const char *buffer)
+{
+       if (strlen(buffer) < 13)
+               return -EINVAL;
+
+       /* tokenks can be <mode>,<keyp>,<disp>,<ind>,<bfr>*/
+       char **ind_tokens = g_strsplit(&buffer[8], ",", 5);
+
+       if (g_strv_length(ind_tokens) < 4) {
+               g_strfreev(ind_tokens);
+               return -EINVAL;
+       }
+
+       ag.er_mode = atoi(ind_tokens[0]);
+       ag.er_ind = atoi(ind_tokens[3]);
+
+       DBG("hfp_enable_indicators (CMER): indicator=%d, mode=%d",
+               ag.er_ind, ag.er_mode);
+
+       g_strfreev(ind_tokens);
+       ind_tokens = NULL;
+
+       switch (ag.er_ind) {
+       case 0:
+       case 1:
+               _bt_hfp_update_event_request(ag.er_ind, hdset);
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+       /* AT+CHLD response */
+int _bt_hfp_call_hold(bt_ag_info_t *hs, const char *buf)
+{
+       int err;
+
+       if (strlen(buf) < 9)
+               return -EINVAL;
+
+       if (buf[8] != '?') {
+               _bt_hfp_call_hold_request(&buf[8], hs);
+               return 0;
+       }
+
+       err = _bt_ag_send_at(hs, "\r\n+CHLD: (%s)\r\n", ag.chld);
+       if (err < 0)
+               return err;
+
+       err = _bt_ag_send_at(hs, "\r\nOK\r\n");
+       if (err < 0)
+               return err;
+
+       _bt_ag_slconn_complete(hs);
+
+       return 0;
+}
+
+int _bt_key_press_response(void *t_device, bt_hfp_agent_error_t err)
+{
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_hfp_key_press(bt_ag_info_t *hs, const char *buf)
+{
+       if (strlen(buf) < 9)
+               return -EINVAL;
+
+       if (ag.ring_timer) {
+               g_source_remove(ag.ring_timer);
+               ag.ring_timer = 0;
+       }
+
+       _bt_hfp_key_press_request(&buf[8], hs);
+
+       return 0;
+}
+
+int _bt_answer_call_response(void *hs, bt_hfp_agent_error_t err)
+{
+       return _bt_ag_send_response(hs, err);
+}
+
+int _bt_hfp_answer_call(bt_ag_info_t *hs, const char *buf)
+{
+       if (ag.ring_timer) {
+               g_source_remove(ag.ring_timer);
+               ag.ring_timer = 0;
+       }
+
+       if (ag.number) {
+               g_free(ag.number);
+               ag.number = NULL;
+       }
+
+       if (remote_dev_path)
+               g_free(remote_dev_path);
+
+       remote_dev_path = g_strdup(hs->path);
+
+       _bt_hfp_answer_call_request(hs);
+
+       return 0;
+}
+int _bt_terminate_call_response(void *t_device,
+                                       hfp_state_manager_err_t err)
+{
+       bt_ag_info_t *hs = t_device;
+
+       if (err != HFP_STATE_MNGR_ERR_NONE)
+               return _bt_ag_send_response(hs, err);
+
+       return _bt_ag_send_at(hs, "\r\nOK\r\n");
+}
+
+int _bt_hfp_terminate_call(bt_ag_info_t *hs, const char *buf)
+{
+       if (ag.number) {
+               g_free(ag.number);
+               ag.number = NULL;
+       }
+
+       if (ag.ring_timer) {
+               g_source_remove(ag.ring_timer);
+               ag.ring_timer = 0;
+       }
+
+       _bt_hfp_terminate_call_request(hs);
+
+       return 0;
+}
+
+int _bt_hfp_cli_notification(bt_ag_info_t *hs, const char *buf)
+{
+       bt_ag_slconn_t *slconn = hs->slc;
+
+       if (strlen(buf) < 9)
+               return -EINVAL;
+
+       slconn->is_client_active = buf[8] == '1' ? TRUE : FALSE;
+
+       return _bt_ag_send_at(hs, "\r\nOK\r\n");
+}
+
+int _bt_response_and_hold_response(void *t_device,
+                                       bt_hfp_agent_error_t err)
+{
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_hfp_response_and_hold(bt_ag_info_t *hs, const char *buf)
+{
+
+       if (strlen(buf) < 8)
+               return -EINVAL;
+
+       if (ag.rh == BT_RSP_HOLD_NOT_SUPPORTED)
+               return _bt_ag_send_response(hs,
+                       HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
+
+       if (buf[7] == '=') {
+               _bt_hfp_response_and_hold_request(hs);
+               return 0;
+       }
+
+       if (ag.rh >= 0)
+               _bt_ag_send_at(hs, "\r\n+BTRH: %d\r\n", ag.rh);
+
+       return _bt_ag_send_at(hs, "\r\nOK\r\n");
+}
+
+int _bt_hfp_last_dialed_number(bt_ag_info_t *hs, const char *buf)
+{
+       if (remote_dev_path)
+               g_free(remote_dev_path);
+
+       remote_dev_path = g_strdup(hs->path);
+       _bt_hfp_last_dialed_number_request(hs);
+
+       return 0;
+}
+
+int _bt_dial_number_response(void *t_device, bt_hfp_agent_error_t err)
+{
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_hfp_dial_number(bt_ag_info_t *hs, const char *buf)
+{
+       char number[MAX_BUFFER_SIZE];
+       size_t buf_len;
+
+       buf_len = strlen(buf);
+
+       if (buf[buf_len - 1] != ';') {
+               DBG("Reject the non-voice call dial number request");
+               return -EINVAL;
+       }
+
+       memset(number, 0, sizeof(number));
+       strncpy(number, &buf[3], buf_len - 4);
+
+       if (remote_dev_path)
+               g_free(remote_dev_path);
+
+       remote_dev_path = g_strdup(hs->path);
+
+       _bt_hfp_dial_number_request(number, hs);
+
+       return 0;
+}
+
+static int __bt_headset_set_gain(bt_ag_info_t *hs, uint16_t gain, char type)
+{
+       bt_ag_slconn_t *slconn = hs->slc;
+       const char *property;
+
+       if (gain > 15) {
+               DBG("Invalid gain value: %u", gain);
+               return -EINVAL;
+       }
+
+       switch (type) {
+       case BT_HFP_SPEAKER_GAIN:
+               if (slconn->speaker_gain == gain) {
+                       DBG("Ignoring no-change in speaker gain");
+                       return -EALREADY;
+               }
+               property = "SpeakerGain";
+               slconn->speaker_gain = gain;
+               break;
+       case BT_HFP_MICROPHONE_GAIN:
+               if (slconn->microphone_gain == gain) {
+                       DBG("Ignoring no-change in microphone gain");
+                       return -EALREADY;
+               }
+               property = "MicrophoneGain";
+               slconn->microphone_gain = gain;
+               break;
+       default:
+               DBG("Unknown gain setting\n");
+               return -EINVAL;
+       }
+
+       _bt_ag_agent_emit_property_changed(ag_dbus_conn, hs->path,
+                               BT_HEADSET_INTERFACE, property,
+                               g_variant_new("q", gain));
+       return 0;
+}
+
+int _bt_hfp_signal_gain_setting(bt_ag_info_t *hs, const char *buf)
+{
+       uint16_t gain;
+       int err;
+
+       if (strlen(buf) < 8) {
+               DBG("very short string to use for Gain setting\n");
+               return -EINVAL;
+       }
+
+       gain = (uint16_t) strtol(&buf[7], NULL, 10);
+
+       err = __bt_headset_set_gain(hs, gain, buf[5]);
+       if (err < 0 && err != -EALREADY)
+               return err;
+
+       return _bt_ag_send_at(hs, "\r\nOK\r\n");
+}
+
+int _bt_transmit_dtmf_response(void *t_device,
+                       bt_hfp_agent_error_t err)
+{
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_hfp_dtmf_tone(bt_ag_info_t *hs, const char *buf)
+{
+       char tone;
+
+       if (strlen(buf) < 8) {
+               printf("Too short string for DTMF tone");
+               return -EINVAL;
+       }
+
+       tone = buf[7];
+       if (tone >= '#' && tone <= 'D')
+               _bt_hfp_channel_dtmf_request(tone, hs);
+       else
+               return -EINVAL;
+
+       return 0;
+}
+
+int _bt_hfp_set_speaker_gain(bt_ag_info_t *hs,
+               uint16_t gain_value)
+{
+       int err;
+       char type = BT_HFP_SPEAKER_GAIN;
+
+       err = __bt_headset_set_gain(hs, gain_value, type);
+       if (err < 0)
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+
+       if (hs->state == HEADSET_STATE_ON_CALL) {
+               err = _bt_ag_send_at(hs, "\r\n+VG%c=%u\r\n", type,
+                               gain_value);
+               if (err < 0)
+                       return BT_HFP_AGENT_ERROR_INTERNAL;
+       }
+       return BT_HFP_AGENT_ERROR_NONE;
+}
+
+int _bt_hfp_set_microphone_gain(bt_ag_info_t *hs,
+               uint16_t gain_value)
+{
+       int err;
+       char type = BT_HFP_MICROPHONE_GAIN;
+
+       if (hs == NULL) {
+               DBG("hs is NULL");
+               return BT_HFP_AGENT_ERROR_INVALID_PARAM;
+       }
+
+       err = __bt_headset_set_gain(hs, gain_value, type);
+       if (err < 0)
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+
+       if (hs->state == HEADSET_STATE_ON_CALL) {
+               err = _bt_ag_send_at(hs, "\r\n+VG%c=%u\r\n", type,
+                               gain_value);
+               if (err < 0)
+                       return BT_HFP_AGENT_ERROR_INTERNAL;
+       }
+       return BT_HFP_AGENT_ERROR_NONE;
+}
+
+
+int _bt_hfp_set_voice_dial(bt_ag_info_t *hs,
+               gboolean enable)
+{
+       DBG("_bt_hfp_set_voice_dial = %d", enable);
+
+       if (_bt_ag_send_at(hs, "\r\n+BVRA: %d\r\n", enable) < 0)
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+
+       return BT_HFP_AGENT_ERROR_NONE;
+}
+
+int _bt_hfp_send_vendor_cmd(bt_ag_info_t *hs,
+               const char *cmd)
+{
+       DBG("_bt_hfp_send_vendor_cmd = %d", cmd);
+
+       if (_bt_ag_send_at(hs, "\r\n%s\r\n", cmd) < 0)
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+
+       return BT_HFP_AGENT_ERROR_NONE;
+}
+
+int _bt_vendor_cmd_response(void *t_device,
+                       bt_hfp_agent_error_t err)
+{
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_hfp_vendor_cmd(bt_ag_info_t *hs, const char *buf)
+{
+       DBG("XSAT vendor command");
+
+       _bt_hfp_vendor_cmd_request(buf, hs);
+
+       return 0;
+}
+
+int _bt_list_current_call_indicator(bt_ag_info_t *hs, int index, int direction,
+       int mode, int status, const char *call_num, int conference, int t_num)
+{
+       if (call_num && strlen(call_num) > 0) {
+               _bt_ag_send_at(hs,
+                       "\r\n+CLCC: %d,%d,%d,%d,%d,\"%s\",%d\r\n",
+                       index, direction, status, mode, conference,
+                               call_num, t_num);
+       } else {
+               _bt_ag_send_at(hs,
+                       "\r\n+CLCC: %d,%d,%d,%d,%d\r\n",
+                       index, direction, status, mode, conference);
+       }
+
+       return 0;
+}
+int _bt_subscriber_number_indicator(const char *call_num, int type, int service)
+{
+       if (!active_devices)
+               return -ENODEV;
+
+       _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
+                               "\r\n+CNUM: ,%s,%d,,%d\r\n",
+                               call_num, type, service);
+       return 0;
+}
+
+int _bt_subscriber_number_response(void *t_device,
+                                       bt_hfp_agent_error_t err)
+{
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_hfp_subscriber_number(bt_ag_info_t *hs, const char *buf)
+{
+       _bt_hfp_subscriber_number_request(hs);
+
+       return 0;
+}
+
+int _bt_call_waiting_indicator(const char *number, int type)
+{
+       if (!active_devices)
+               return -ENODEV;
+
+       DBG("Call waiting indicator to hf");
+       _bt_ag_send_foreach_headset(active_devices, __bt_cwa_cmp,
+                               "\r\n+CCWA: \"%s\",%d\r\n",
+                               number, type);
+       return 0;
+}
+
+int _bt_list_current_calls_response(void *t_device,
+                                       bt_hfp_agent_error_t err)
+{
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_hfp_list_current_calls(bt_ag_info_t *hs, const char *buf)
+{
+       _bt_list_current_calls(hs);
+
+       return 0;
+}
+
+int _bt_hfp_extended_errors(bt_ag_info_t *hs, const char *buf)
+{
+       bt_ag_slconn_t *slconn = hs->slc;
+
+       if (strlen(buf) < 9)
+               return -EINVAL;
+
+       if (buf[8] == '1') {
+               slconn->is_cme_enabled = TRUE;
+               DBG("CME errors enabled for headset %p", hs);
+       } else {
+               slconn->is_cme_enabled = FALSE;
+               DBG("CME errors disabled for headset %p", hs);
+       }
+
+       return _bt_ag_send_at(hs, "\r\nOK\r\n");
+}
+
+int _bt_hfp_call_waiting_notify(bt_ag_info_t *hs, const char *buf)
+{
+       bt_ag_slconn_t *slconn = hs->slc;
+
+       if (strlen(buf) < 9)
+               return -EINVAL;
+
+       if (buf[8] == '1') {
+               slconn->is_cwa_enabled = TRUE;
+               DBG("Call waiting notification enabled for headset %p", hs);
+       } else {
+               slconn->is_cwa_enabled = FALSE;
+               DBG("Call waiting notification disabled for headset %p", hs);
+       }
+
+       return _bt_ag_send_at(hs, "\r\nOK\r\n");
+}
+
+int _bt_operator_selection_response(void *t_device,
+                                       bt_hfp_agent_error_t err)
+{
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_call_hold_response(void *t_device, bt_hfp_agent_error_t err)
+{
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_nr_and_ec_response(void *t_device, bt_hfp_agent_error_t err)
+{
+       bt_ag_info_t *hs = t_device;
+       bt_ag_slconn_t *slconn = hs->slc;
+
+       if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
+               GSList *l;
+
+               for (l = hs->nrec_cbs; l; l = l->next) {
+                       struct hs_nrec_callback *nrec_cb = l->data;
+
+                       nrec_cb->cb(hs, slconn->is_nrec_req,
+                               nrec_cb->user_data);
+               }
+
+               slconn->is_nrec = hs->slc->is_nrec_req;
+       }
+
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_voice_dial_response(void *t_device, bt_hfp_agent_error_t err)
+{
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_operator_selection_indicator(int mode, const char *oper)
+{
+       if (!active_devices)
+               return -ENODEV;
+
+       _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
+                               "\r\n+COPS: %d,0,\"%s\"\r\n",
+                               mode, oper);
+       return 0;
+}
+
+int _bt_hfp_operator_selection(bt_ag_info_t *hs, const char *buf)
+{
+       if (strlen(buf) < 8)
+               return -EINVAL;
+
+       switch (buf[7]) {
+       case '?':
+               _bt_hfp_get_operator_selection_request(hs);
+               break;
+       case '=': {
+               if (buf[8] == '?')
+                       return _bt_ag_send_at(hs, "\r\n+CME ERROR: %d\r\n",
+                               HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
+               else
+                       return _bt_ag_send_at(hs, "\r\nOK\r\n");
+       }
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+int _bt_hfp_nr_and_ec(bt_ag_info_t *hs, const char *buf)
+{
+       bt_ag_slconn_t *slconn = hs->slc;
+
+       if (strlen(buf) < 9)
+               return -EINVAL;
+
+       if (buf[8] == '0')
+               slconn->is_nrec_req = FALSE;
+       else
+               slconn->is_nrec_req = TRUE;
+
+       _bt_hfp_noise_red_and_echo_cancel_request(slconn->is_nrec_req, hs);
+
+       return 0;
+}
+
+int _bt_hfp_voice_dial(bt_ag_info_t *hs, const char *buf)
+{
+       bt_ag_slconn_t *slconn = hs->slc;
+       gboolean enable;
+
+       if (strlen(buf) < 9)
+               return -EINVAL;
+
+       if (buf[8] == '0')
+               enable = FALSE;
+       else
+               enable = TRUE;
+
+       _bt_hfp_voice_dial_request(enable, hs);
+
+       slconn->is_voice_recognition_running = enable;
+
+       return 0;
+}
+
+int _bt_hfp_indicators_activation(bt_ag_info_t *hs, const char *buf)
+{
+       if (strlen(buf) < 7) {
+               printf("Invalid indicator activation request\n");
+               return -EINVAL;
+       }
+
+       _bt_hfp_set_indicators(&buf[6], hs);
+       return 0;
+}
+
+int _bt_indicators_activation_response(void *t_device,
+                                       bt_hfp_agent_error_t err)
+{
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_select_phonebook_memory_status_response(void *t_device,
+                                               const char *path,
+                                               uint32_t total, uint32_t used,
+                                               bt_hfp_agent_error_t err)
+{
+       bt_ag_info_t *hs = t_device;
+       bt_ag_slconn_t *slconn = hs->slc;
+
+       if (err != (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
+               if (slconn->is_cme_enabled)
+                       return _bt_ag_send_at(hs,
+                                       "\r\n+CME ERROR: %d\r\n", err);
+               else
+                       return _bt_ag_send_at(hs, "\r\nERROR\r\n");
+       }
+
+       if (!active_devices)
+               return -ENODEV;
+
+       _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
+                       "\r\n+CPBS: %s,%d,%d\r\n",
+                       path, used, total);
+
+       return _bt_ag_send_at(hs, "\r\nOK\r\n");
+}
+
+int _bt_select_phonebook_memory_list_response(void *t_device,
+                                               const char *buf,
+                                               bt_hfp_agent_error_t err)
+{
+       bt_ag_info_t *hs = t_device;
+       bt_ag_slconn_t *slconn = hs->slc;
+
+       if ((err != (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) ||
+                               (NULL == buf)) {
+               if (slconn->is_cme_enabled)
+                       return _bt_ag_send_at(hs,
+                                       "\r\n+CME ERROR: %d\r\n", err);
+               else
+                       return _bt_ag_send_at(hs, "\r\nERROR\r\n");
+       }
+
+       if (NULL != buf) {
+               if (!active_devices)
+                       return -ENODEV;
+
+               _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
+                                       "\r\n+CPBS: %s\r\n", buf);
+
+       }
+       return _bt_ag_send_at(hs, "\r\nOK\r\n");
+}
+
+int _bt_select_phonebook_memory_response(void *t_device,
+                                               bt_hfp_agent_error_t err)
+{
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_hfp_select_pb_memory(bt_ag_info_t *hs, const char *buf)
+{
+       if (strlen(buf) < 8)
+               return -EINVAL;
+
+       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;
+       }
+
+       return -EINVAL;
+}
+
+int _bt_read_phonebook_entries_list_response(void *t_device,
+                                               uint32_t used,
+                                               uint32_t number_length,
+                                               uint32_t name_length,
+                                               bt_hfp_agent_error_t err)
+{
+       bt_ag_info_t *hs = t_device;
+       bt_ag_slconn_t *slconn = hs->slc;
+
+       int send_err = 0;
+       int index = 1;
+
+       if (err != (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
+               if (slconn->is_cme_enabled)
+                       return _bt_ag_send_at(hs,
+                                       "\r\n+CME ERROR: %d\r\n", err);
+               else
+                       return _bt_ag_send_at(hs, "\r\nERROR\r\n");
+       }
+
+       if (used < 1)
+               index = 0;
+
+       send_err = _bt_ag_send_at(hs, "\r\n+CPBR: (%d-%d),%d,%d\r\n",
+                       index, used, number_length, name_length);
+       if (send_err < 0)
+               return send_err;
+
+       return _bt_ag_send_at(hs, "\r\nOK\r\n");
+}
+
+int _bt_read_phonebook_entries_response(void *t_device,
+                                       bt_hfp_agent_error_t err)
+{
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_read_phonebook_entries_indicator(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+CPBR: %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 (strlen(buf) < 8)
+               return -EINVAL;
+
+       if (buf[7] != '=')
+               return -EINVAL;
+
+       if (buf[8] == '?')
+               _bt_hfp_read_phonebook_entries_list(hs);
+       else
+               _bt_hfp_read_phonebook_entries(hs, &buf[8]);
+
+       return 0;
+}
+
+int _bt_find_phonebook_entries_status_response(void *t_device,
+                                               bt_hfp_agent_error_t err)
+{
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_find_phonebook_entries_response(void *t_device,
+                                       bt_hfp_agent_error_t err)
+{
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_find_phonebook_entries_status_indicator(uint32_t number_length,
+                                       uint32_t name_length)
+{
+       _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
+                       "\r\n+CPBF: %d,%d\r\n",
+                       number_length, name_length);
+
+       return 0;
+}
+
+int _bt_hfp_find_pb_entires(bt_ag_info_t *hs, const char *buf)
+{
+       if (strlen(buf) < 8)
+               return -EINVAL;
+
+       if (buf[7] != '=')
+               return -EINVAL;
+
+       if (buf[8] == '?')
+               _bt_hfp_find_phonebook_entries_status(hs);
+       else
+               _bt_hfp_find_phonebook_entries(hs, &buf[8]);
+
+       return 0;
+}
+
+int _bt_supported_character_generic_response(void *t_device,
+                                               char *character_set_list,
+                                               bt_hfp_agent_error_t err)
+{
+       bt_ag_info_t *hs = t_device;
+       bt_ag_slconn_t *slconn = hs->slc;
+
+       if (err != (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
+               if (slconn->is_cme_enabled)
+                       return _bt_ag_send_at(hs,
+                                       "\r\n+CME ERROR: %d\r\n", err);
+               else
+                       return _bt_ag_send_at(hs, "\r\nERROR\r\n");
+       }
+
+       if (NULL != character_set_list) {
+               if (!active_devices)
+                       return -ENODEV;
+
+               _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
+                       "\r\n+CSCS: %s\r\n", character_set_list);
+       }
+       return _bt_ag_send_at(hs, "\r\nOK\r\n");
+}
+
+int _bt_set_characterset_generic_response(void *t_device,
+                                       bt_hfp_agent_error_t err)
+{
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_hfp_select_character_set(bt_ag_info_t *hs, const char *buf)
+{
+       if (NULL != buf) {
+               if (strlen(buf) < 7)
+                       return -EINVAL;
+
+               if (buf[7] == '?') {
+                       _bt_hfp_get_character_set(hs);
+                       return 0;
+               }
+
+               if (buf[7] == '=') {
+                       if (buf[8] == '?')
+                               _bt_hfp_list_supported_character(hs);
+                       else
+                               _bt_hfp_set_character_set(hs, &buf[8]);
+               }
+       }
+       return 0;
+
+}
+
+int _bt_battery_charge_status_response(void *t_device,
+                                               int32_t bcs,
+                                               int32_t bcl,
+                                               bt_hfp_agent_error_t err)
+{
+       bt_ag_info_t *hs = t_device;
+
+       if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
+               _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
+                                       "\r\n+CBC: %d,%d\r\n", bcs, bcl);
+       }
+
+       return _bt_ag_send_response(hs, err);
+}
+
+int _bt_hfp_get_battery_charge_status(bt_ag_info_t *hs, const char *buf)
+{
+       if (strlen(buf) < 6)
+               return -EINVAL;
+
+       if (buf[6] == '=')
+               return _bt_ag_send_response(hs, HFP_STATE_MNGR_ERR_NONE);
+
+       _bt_hfp_get_battery_property(hs);
+       return 0;
+}
+
+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);
+}
+
+/* convert signal strength to a RSSI level */
+static int __bt_telephony_convert_signal_to_rssi(int signal)
+{
+       /* input  : BT signal strength (0~5) */
+       /* output : RSSI strength (0~31) */
+       switch (signal) {
+       case 0: return 0;
+       case 1: return 4;
+       case 2: return 8;
+       case 3: return 13;
+       case 4: return 19;
+       case 5: return 31;
+       }
+
+       if (signal > 5)
+               return 31;
+
+       return 0;
+}
+
+int _bt_signal_quality_response(void *t_device,
+                                               int32_t rssi,
+                                               int32_t ber,
+                                               bt_hfp_agent_error_t err)
+{
+       bt_ag_info_t *hs = t_device;
+
+       if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
+               _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
+                       "\r\n+CSQ: %d,%d\r\n",
+                       __bt_telephony_convert_signal_to_rssi(rssi), ber);
+       }
+       return _bt_ag_send_response(hs, err);
+}
+
+int _bt_telephony_signal_quality_list_supported_response(void *t_device,
+                                               bt_hfp_agent_error_t err)
+{
+       bt_ag_info_t *device = t_device;
+
+       if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
+               _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
+                                       "\r\n+CSQ: (0-31,99),(99)\r\n");
+       }
+       return _bt_ag_send_response(device, err);
+}
+
+int _bt_hfp_get_signal_quality(bt_ag_info_t *hs, const char *buf)
+{
+       if (strlen(buf) < 6)
+               return -EINVAL;
+
+       if (buf[6] == '=')
+               _bt_telephony_signal_quality_list_supported_response(hs,
+                                       HFP_STATE_MNGR_ERR_NONE);
+       else
+               _bt_ag_agent_get_signal_quality(hs);
+
+       return 0;
+}
+
+int _bt_hfp_get_activity_status_rsp(void *t_device,
+                                               int status,
+                                               bt_hfp_agent_error_t err)
+{
+       bt_ag_info_t *device = t_device;
+
+       if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
+               _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
+                                       "\r\n+CPAS: %d\r\n", status);
+       }
+
+       return _bt_ag_send_response(device, err);
+}
+
+int _bt_hfp_get_activity_status(bt_ag_info_t *device, const char *buf)
+{
+       if (strlen(buf) < 7)
+               return -EINVAL;
+
+       if (buf[7] == '?') {
+               return _bt_ag_send_response(device,
+                                       HFP_STATE_MNGR_ERR_AG_FAILURE);
+       } else if (buf[7] == '=') {
+               _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
+                                       "\r\n+CPAS: (0-4)\r\n");
+               return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
+       }
+
+       _bt_get_activity_status(device);
+       return 0;
+}
+
+int _bt_hfp_get_equipment_identity_rsp(void *t_device,
+                               char *identity, bt_hfp_agent_error_t err)
+{
+       if (identity)
+               _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
+               "\r\n+CGSN: %s\r\n", identity);
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_hfp_get_imsi_rsp(void *t_device,
+               char *mcc, char *mnc, char *msin, bt_hfp_agent_error_t err)
+{
+       if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE)
+               _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
+                               "\r\n%s%s%s\r\n", mcc,mnc,msin);
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_hfp_get_creg_status_rsp(void *t_device,
+               int n, int status, bt_hfp_agent_error_t err)
+{
+       if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE)
+               _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
+                               "\r\n+CREG: %d,%d\r\n", n, status);
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_hfp_get_equipment_identity(bt_ag_info_t *device, const char *buf)
+{
+       int len = strlen(buf);
+
+       if (len == 9 && buf[7] == '=' && buf[8] == '?')  /* AT+CGSN=? */
+               return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
+
+       else if (len > 7)
+               return -EINVAL;
+
+       _bt_hfp_get_equipment_identity_req(device); /* AT+CGSN */
+       return 0;
+}
+
+int _bt_hfp_get_model_info_rsp(void *t_device, char *model,
+                                               bt_hfp_agent_error_t err)
+{
+       if (model)
+               _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
+               "\r\n+CGMM: %s\r\n", model);
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_hfp_get_model_information(bt_ag_info_t *device, const char *buf)
+{
+       int len = strlen(buf);
+
+       if (len == 9 && buf[7] == '=' && buf[8] == '?')  /* AT+CGMM=? */
+               return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
+
+       else if (len > 7)
+               return -EINVAL;
+
+       _bt_hfp_get_model_info_req(device);/* AT+CGMM */
+       return 0;
+}
+
+int _bt_hfp_get_device_manufacturer_rsp(void *t_device,
+                               char *manufacturer, bt_hfp_agent_error_t err)
+{
+       if (manufacturer)
+               _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
+               "\r\n+CGMI: %s\r\n", manufacturer);
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_hfp_get_device_manufacturer(bt_ag_info_t *device, const char *buf)
+{
+       int len = strlen(buf);
+
+       if (len == 9 && buf[7] == '=' && buf[8] == '?')  /* AT+CGMI=? */
+               return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
+
+       else if (len > 7)
+               return -EINVAL;
+
+       _bt_hfp_get_device_manufacturer_req(device);
+       return 0;
+}
+
+int _bt_hfp_get_imsi(bt_ag_info_t *device, const char *buf)
+{
+       int len = strlen(buf);
+       DBG_SECURE("Buf %s", buf);
+
+       if (len == 7) {
+               _bt_hfp_get_imsi_req(device);
+       } else {
+               _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_INVALID_INDEX);
+       }
+
+       return 0;
+}
+
+int _bt_hfp_get_creg_status(bt_ag_info_t *device, const char *buf)
+{
+       int len = strlen(buf);
+       DBG_SECURE("buf %s", buf);
+       if (len < 7 || len > 9)
+               return -EINVAL;
+       else if (len == 7) {
+               _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_INVALID_INDEX);
+       } else if (buf[7] == '=') {
+               _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_INVALID_INDEX);
+       } else if (buf[7] == '?') {
+               _bt_hfp_get_creg_status_req(device);
+       }
+       return 0;
+}
+int _bt_hfp_get_revision_info_rsp(void *t_device, char *revision,
+                                               bt_hfp_agent_error_t err)
+{
+       if (revision)
+               _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
+               "\r\n+CGMR: %s\r\n", revision);
+       return _bt_ag_send_response(t_device, err);
+}
+
+int _bt_hfp_get_revision_information(bt_ag_info_t *device, const char *buf)
+{
+       int len = strlen(buf);
+
+       if (len == 9 && buf[7] == '=' && buf[8] == '?')  /* AT+CGMR=? */
+               return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
+
+       else if (len > 7)
+               return -EINVAL;
+
+       _bt_hfp_get_revision_info_req(device);
+       return 0;
+}
diff --git a/ag-agent/bluetooth-ag-handler.h b/ag-agent/bluetooth-ag-handler.h
new file mode 100644 (file)
index 0000000..e3f548c
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * bluetoth-ag-handler.h
+ *
+ * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:    Hocheol Seo <hocheol.seo@samsung.com>
+ *             Chethan TN <chethan.tn@samsung.com>
+ *             Chanyeol Park <chanyeol.park@samsung.com>
+ *             Rakesh MK <rakesh.mk@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 <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <glib.h>
+#include "bluetooth-ag-agent.h"
+
+#define BT_HFP_SPEAKER_GAIN 'S'
+#define BT_HFP_MICROPHONE_GAIN 'M'
+
+#define AG_RING_INTERVAL 1500
+
+typedef struct {
+       gboolean wbs_enable;
+       uint8_t i2s_enable;
+       uint8_t is_master;
+       uint8_t clock_rate;
+       uint8_t pcm_interface_rate;
+} wbs_options;
+
+/* BD Address */
+typedef struct {
+       uint8_t b[6];
+} __attribute__((packed)) bt_addr;
+
+int _bt_hfp_supported_features(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_report_indicators(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_enable_indicators(bt_ag_info_t *hdset, const char *buffer);
+int _bt_hfp_call_hold(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_answer_call(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_dial_number(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_signal_gain_setting(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_terminate_call(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_key_press(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_last_dialed_number(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_response_and_hold(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_cli_notification(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_dtmf_tone(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_subscriber_number(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_list_current_calls(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_extended_errors(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_call_waiting_notify(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_operator_selection(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_nr_and_ec(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_voice_dial(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_apl_command(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_apl_command(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_indicators_activation(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_select_pb_memory(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_read_pb_entries(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_select_character_set(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_find_pb_entires(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_get_signal_quality(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_get_battery_charge_status(bt_ag_info_t *hs, const char *buf);
+int _bt_calling_stopped_indicator(void);
+int _bt_incoming_call_indicator(const char *number, int type);
+int _bt_call_waiting_indicator(const char *number, int type);
+void _bt_hfp_deinitialize(void);
+gboolean __bt_ring_timer_cb(gpointer data);
+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_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);
+int _bt_event_reporting_response(void *t_device,
+                               bt_hfp_agent_error_t err);
+int _bt_terminate_call_response(void *t_device,
+                               hfp_state_manager_err_t err);
+int _bt_call_hold_response(void *t_device, bt_hfp_agent_error_t err);
+int _bt_key_press_response(void *t_device, bt_hfp_agent_error_t err);
+int _bt_subscriber_number_indicator(const char *call_num,
+                               int type, int service);
+int _bt_subscriber_number_response(void *t_device,
+                                       bt_hfp_agent_error_t err);
+int _bt_list_current_call_indicator(bt_ag_info_t *hs, int index, int direction,
+       int mode, int status, const char *call_num, int conference, int t_num);
+int _bt_list_current_calls_response(void *t_device,
+                                       bt_hfp_agent_error_t err);
+int _bt_nr_and_ec_response(void *t_device, bt_hfp_agent_error_t err);
+int _bt_voice_dial_response(void *t_device, bt_hfp_agent_error_t err);
+int _bt_indicators_activation_response(void *t_device,
+                                       bt_hfp_agent_error_t err);
+int _bt_select_phonebook_memory_status_response(void *t_device,
+                                               const char *path,
+                                               uint32_t total, uint32_t used,
+                                               bt_hfp_agent_error_t err);
+int _bt_select_phonebook_memory_list_response(void *t_device,
+                                               const char *buf,
+                                               bt_hfp_agent_error_t err);
+int _bt_select_phonebook_memory_response(void *t_device,
+                                               bt_hfp_agent_error_t err);
+int _bt_read_phonebook_entries_list_response(void *t_device,
+                                               uint32_t used,
+                                               uint32_t number_length,
+                                               uint32_t name_length,
+                                               bt_hfp_agent_error_t err);
+int _bt_read_phonebook_entries_response(void *t_device,
+                                       bt_hfp_agent_error_t err);
+int _bt_find_phonebook_entries_status_indicator(uint32_t number_length,
+                                       uint32_t name_length);
+int _bt_find_phonebook_entries_status_response(void *t_device,
+                                               bt_hfp_agent_error_t err);
+int _bt_supported_character_generic_response(void *t_device,
+                                               char *character_set_list,
+                                               bt_hfp_agent_error_t err);
+int _bt_set_characterset_generic_response(void *t_device,
+                                       bt_hfp_agent_error_t err);
+int _bt_signal_quality_response(void *t_device,
+                                               int32_t rssi,
+                                               int32_t ber,
+                                               bt_hfp_agent_error_t err);
+int _bt_battery_charge_status_response(void *t_device,
+                                               int32_t bcs,
+                                               int32_t bcl,
+                                               bt_hfp_agent_error_t err);
+int _bt_operator_selection_indicator(int mode, const char *oper);
+int _bt_operator_selection_response(void *t_device,
+                                       bt_hfp_agent_error_t err);
+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_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_hfp_get_activity_status_rsp(void *t_device,
+                                               int status,
+                                               bt_hfp_agent_error_t err);
+int _bt_hfp_get_activity_status(bt_ag_info_t *device, const char *buf);
+int _bt_hfp_set_speaker_gain(bt_ag_info_t *hs,
+               uint16_t gain_value);
+int _bt_hfp_set_microphone_gain(bt_ag_info_t *hs,
+               uint16_t gain_value);
+int _bt_hfp_set_voice_dial(bt_ag_info_t *hs,
+               gboolean enable);
+int _bt_hfp_get_equipment_identity_rsp(void *t_device,
+                               char *identity, bt_hfp_agent_error_t err);
+int _bt_hfp_get_imsi_rsp(void *t_device,
+               char *mcc, char *mnc, char *msin, bt_hfp_agent_error_t err);
+int _bt_hfp_get_creg_status_rsp(void *t_device,
+               int n, int status, bt_hfp_agent_error_t err);
+int _bt_hfp_get_model_info_rsp(void *t_device,
+                               char *model, bt_hfp_agent_error_t err);
+int _bt_hfp_get_device_manufacturer_rsp(void *t_device,
+                               char *manufacturer, bt_hfp_agent_error_t err);
+int _bt_hfp_get_revision_info_rsp(void *t_device,
+                               char *revision, bt_hfp_agent_error_t err);
+int _bt_hfp_vendor_cmd(bt_ag_info_t *hs, const char *buf);
+int _bt_hfp_send_vendor_cmd(bt_ag_info_t *hs,
+               const char *cmd);
+int _bt_vendor_cmd_response(void *t_device,
+                       bt_hfp_agent_error_t err);
diff --git a/ag-agent/bluetooth-ag-manager.c b/ag-agent/bluetooth-ag-manager.c
new file mode 100644 (file)
index 0000000..ef81942
--- /dev/null
@@ -0,0 +1,2171 @@
+/*
+ * bluetooth-ag-manager.c
+ *
+ * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:    Hocheol Seo <hocheol.seo@samsung.com>
+ *             Chethan TN <chethan.tn@samsung.com>
+ *             Chanyeol Park <chanyeol.park@samsung.com>
+ *             Rakesh MK <rakesh.mk@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 <string.h>
+#include "bluetooth-ag-agent.h"
+#include "bluetooth-ag-handler.h"
+#include <dbus/dbus.h>
+
+#define PHONEBOOK_AGENT_BUS_NAME "org.bluez.pb_agent"
+#define PHONEBOOK_AGENT_PATH    "/org/bluez/pb_agent"
+#define PHONEBOOK_AGENT_INTERFACE "org.bluez.PbAgent.At"
+
+struct telephony_call {
+       char *call_path;
+       int call_status;
+       gboolean call_originating;
+       gboolean call_emergency;
+       gboolean call_on_hold;
+       gboolean call_conference;
+       char *call_number;
+       gboolean call_setup;
+       uint32_t call_id;
+       char *call_sender;
+};
+
+#define HFP_AGENT_ACTIVITY_STATUS_READY 0
+#define HFP_AGENT_ACTIVITY_STATUS_UNAVAILABLE 1
+#define HFP_AGENT_ACTIVITY_STATUS_UNKNOWN 2
+#define HFP_AGENT_ACTIVITY_STATUS_RINGING 3
+#define HFP_AGENT_ACTIVITY_STATUS_CALL_IN_PROGRESS 4
+
+#define HFP_AGENT_BATTERY_INDICATOR "battchg"
+#define HFP_AGENT_CALL_INDICATOR               "call"
+#define HFP_AGENT_CALLHELD_INDICATOR   "callheld"
+#define HFP_AGENT_CALLSETUP_INDICATOR  "callsetup"
+#define HFP_AGENT_ROAMING_INDICATOR "roam"
+#define HFP_AGENT_SERVICE_INDICATOR  "service"
+#define HFP_AGENT_SIGNAL_INDICATOR     "signal"
+
+#define HFP_AGENT_CALL_IDLE  0
+#define HFP_AGENT_CALL_ACTIVE 1
+
+#define HFP_INCOMING_CALLSETUP 1
+#define HFP_OUTGOING_CALLSETUP 2
+#define RESTRAIN_CALL_FLAG 0x01
+#define ALLOW_CALL_FLAG  0x02
+
+#define HFP_CALL_STATUS_IDLE   0
+#define HFP_CALL_STATUS_CREATE         1
+#define HFP_CALL_STATUS_COMING         2
+#define HFP_CALL_STATUS_PROCEEDING     3
+#define HFP_CALL_STATUS_MO_ALERTING    4
+#define HFP_CALL_STATUS_MT_ALERTING            5
+#define HFP_CALL_STATUS_WAITING                6
+#define HFP_CALL_STATUS_ANSWERED       7
+#define HFP_CALL_STATUS_ACTIVE         8
+#define HFP_CALL_STATUS_MO_RELEASE     9
+#define HFP_CALL_STATUS_MT_RELEASE     10
+#define HFP_CALL_STATUS_HOLD_INITIATED         11
+#define HFP_CALL_STATUS_HOLD           12
+#define HFP_CALL_STATUS_RETRIEVE_INITIATED     13
+#define HFP_CALL_STATUS_RECONNECT_PENDING      14
+#define HFP_CALL_STATUS_TERMINATED             15
+#define HFP_CALL_STATUS_SWAP_INITIATED         16
+
+#define AGENT_MAX_PB_COUNT             1000
+#define AGENT_PB_NAME_MAX_LENGTH               20
+#define AGENT_PB_NUMBER_MAX_LENGTH     20
+#define AGENT_MAX_CALLLOG_COUNT                30
+#define ERR_NOT_FOUND -1
+#define AG_MAX_LENGTH 16
+
+static gboolean update_events = FALSE;
+static int caller_id = 0;
+
+static GSList *call_senders_paths = NULL;
+static GSList *existing_call_list = NULL;
+static GSList *agent_active_call_list = NULL;
+static char *ag_subscriber_num = NULL;
+
+static guint call_on_hold_timer = 0;
+
+typedef struct {
+       gchar *sender_path;
+       gchar *sender_name;
+} sender_info_t;
+
+static struct {
+       char *network_operator_name;
+       uint8_t network_status;
+       int32_t signal_strength;
+} network_info = {
+       .network_operator_name = NULL,
+       .network_status = BT_AGENT_NETWORK_REG_STATUS_UNKOWN,
+       .signal_strength = 0,
+};
+
+static const char *agent_pb_store_list[] =  {
+       "\"ME\"", "\"DC\"", "\"MC\"", "\"RC\""
+};
+
+static const char *agent_supported_character_set[] = {
+       "\"UTF-8\"", "\"IRA\""
+};
+
+#if defined(TIZEN_WEARABLE) && defined(TIZEN_BT_HFP_AG_ENABLE)
+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 ( \
+               sizeof(agent_supported_character_set)/sizeof(const char *))
+
+static bt_ag_indicators_t hfp_ag_ind[] = {
+       { "call", "0,1", 0, TRUE, TRUE },
+       { "callsetup", "0-3", 0 , TRUE, TRUE },
+       { "battchg", "0-5", 5 , TRUE, TRUE },
+       { "callheld", "0-2", 0 , FALSE, TRUE },
+       { "roam", "0,1", 0 , TRUE, TRUE },
+       { "signal", "0-5", 0 , TRUE, TRUE },
+       { "service",    "0,1", 0, TRUE, TRUE },
+       { NULL }
+};
+
+static struct {
+       int32_t path_id;
+       int32_t charset_id;
+} ag_pb_info = {
+       .path_id = 0,
+       .charset_id = 0
+};
+
+static gboolean __bt_hfp_check_for_callpath(const char *call_path,
+                                       const char *call_sender)
+{
+       GSList *sender_list = call_senders_paths;
+       sender_info_t *sender;
+
+       DBG("call path is  = %s\n", call_path);
+       DBG("sender is  = %s\n", call_sender);
+
+       if (call_path == NULL || call_sender == NULL) {
+
+               ERR("Invalid Parameters");
+               return FALSE;
+       }
+
+       /*check if the call is already registered*/
+       DBG("Checking if the call is already registered");
+       while (sender_list != NULL) {
+               sender = sender_list->data;
+
+               if (sender == NULL)
+                       break;
+
+               if (g_strcmp0(sender->sender_path, call_path) == 0) {
+                       DBG("sender path and call path match... so return true");
+                       return TRUE;
+               }
+
+               sender_list = sender_list->next;
+       }
+
+       ERR("Call path is not already registered");
+       return FALSE;
+}
+
+static void __bt_hfp_clear_sender_path(sender_info_t *s_path)
+{
+       if (s_path == NULL)
+               return;
+
+       g_free(s_path->sender_name);
+       g_free(s_path->sender_path);
+       g_free(s_path);
+
+       if (g_slist_length(call_senders_paths) == 0) {
+               g_slist_free(call_senders_paths);
+               call_senders_paths = NULL;
+       }
+}
+
+static void __bt_hfp_free_call(struct telephony_call *t_call)
+{
+       if (t_call == NULL)
+               return;
+
+       g_free(t_call->call_number);
+       g_free(t_call->call_path);
+       g_free(t_call->call_sender);
+       g_free(t_call);
+}
+
+static void __bt_hfp_reset_indicators(void)
+{
+       int i;
+
+       for (i = 0; hfp_ag_ind[i].indicator_desc != NULL; i++)
+               hfp_ag_ind[i].is_activated = TRUE;
+}
+
+void _bt_hfp_device_disconnected(void *t_device)
+{
+       DBG("hfp_agent: device %p disconnected", t_device);
+       update_events = FALSE;
+       __bt_hfp_reset_indicators();
+}
+
+void _bt_hfp_initialize_telephony_manager(uint32_t ag_features)
+{
+       int index;
+       int value;
+       int ret;
+
+       /* 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);
+                       } else {
+                               /* Send battery status ranging from 0-5 */
+                               if (value < 5)
+                                       hfp_ag_ind[index].hfp_value = 0;
+                               else if (value >= 100)
+                                       hfp_ag_ind[index].hfp_value = 5;
+                               else
+                                       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) {
+                               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)
+                               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) {
+                               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:
+                                       hfp_ag_ind[index].hfp_value =
+                                               INDICATOR_EVENT_SERVICE_NONE;
+                                       break;
+                               default:
+                                       hfp_ag_ind[index].hfp_value =
+                                               INDICATOR_EVENT_SERVICE_PRESENT;
+                                       break;
+                               }
+                       }
+               } else {
+                       hfp_ag_ind[index].hfp_value = 0;
+               }
+       }
+
+       /*Initializatoin of the indicators*/
+       _bt_hfp_set_ag_indicator(ag_features, hfp_ag_ind,
+                                       BT_RSP_HOLD_NOT_SUPPORTED,
+                                       ag_chld_str);
+}
+
+void _bt_hfp_deinitialize_telephony_manager(void)
+{
+       GSList *list = call_senders_paths;
+
+       g_free(ag_subscriber_num);
+       ag_subscriber_num = NULL;
+
+       g_free(network_info.network_operator_name);
+       network_info.network_operator_name = NULL;
+
+       network_info.network_status = BT_AGENT_NETWORK_REG_STATUS_UNKOWN;
+       network_info.signal_strength = 0;
+
+       g_slist_free(agent_active_call_list);
+       agent_active_call_list = NULL;
+
+       g_slist_foreach(existing_call_list, (GFunc) __bt_hfp_free_call, NULL);
+       g_slist_free(existing_call_list);
+       existing_call_list = NULL;
+
+       while (list != NULL) {
+               __bt_hfp_clear_sender_path(list->data);
+               list = list->next;
+       }
+
+       g_slist_free(call_senders_paths);
+       call_senders_paths = NULL;
+
+       _bt_hfp_deinitialize();
+}
+
+bt_hfp_agent_error_t _bt_hfp_register_telephony_agent(gboolean register_flag,
+               const char *path_to_register,
+               const char *sender)
+{
+       sender_info_t *sender_info;
+
+       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);
+
+       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",
+                                               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);
+
+               return BT_HFP_AGENT_ERROR_NONE;
+       } else {
+               /*remove the call from senders list */
+               GSList *s_list = call_senders_paths;
+
+               while (s_list != NULL) {
+                       sender_info = s_list->data;
+
+                       if (sender_info == NULL)
+                               return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
+
+                       if (g_strcmp0(sender_info->sender_path,
+                                       path_to_register) == 0) {
+                               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;
+               }
+
+               return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
+       }
+}
+
+static gboolean __bt_hfp_is_call_allowed(const char *call_path)
+{
+       GSList *call_list = existing_call_list;
+
+       /*if prior call list doesn't exisit, allow the call as it can be a new-call*/
+       if (!existing_call_list) {
+               DBG(" This must be a new call... Allow it!");
+               return TRUE;
+       }
+
+       while (call_list != NULL) {
+
+               struct telephony_call *t_call = call_list->data;
+
+               if (g_strcmp0(t_call->call_path, call_path) == 0)
+                       return TRUE;
+
+               call_list = call_list->next;
+       }
+
+       ERR("call is not allowed");
+       return FALSE;
+}
+
+static struct telephony_call *__bt_hfp_create_new_call(
+                                       const char *incoming_path,
+                                       uint32_t incoming_call_id,
+                                       const char *incoming_number,
+                                       const char *sender)
+{
+       struct telephony_call *t_call = NULL;
+       GSList *call_list = existing_call_list;
+
+       while (call_list != NULL) {
+               t_call = call_list->data;
+
+               if (t_call->call_id == incoming_call_id)
+                       break;
+               else
+                       t_call = NULL;
+
+               call_list = call_list->next;
+       }
+
+       DBG("Create a new call");
+
+       if (t_call == NULL) {
+               t_call = g_new0(struct telephony_call, 1);
+               t_call->call_id = incoming_call_id;
+               t_call->call_path = g_strdup(incoming_path);
+               t_call->call_sender = g_strdup(sender);
+               t_call->call_number = g_strdup(incoming_number);
+
+               existing_call_list = g_slist_append(existing_call_list,
+                                                       t_call);
+       }
+       return t_call;
+}
+
+gboolean _bt_hfp_is_call_exist(void)
+{
+       DBG("_bt_hfp_is_call_exist [%x]", existing_call_list);
+       if (existing_call_list)
+               return TRUE;
+       else
+               return FALSE;
+}
+
+static struct telephony_call *__bt_hfp_get_call_with_status(int call_status)
+{
+       DBG("Get Call with status %d", call_status);
+
+       GSList *temp_list = existing_call_list;
+
+       if (existing_call_list != NULL) {
+               while (temp_list != NULL) {
+                       struct telephony_call *t_call = temp_list->data;
+                       if (t_call->call_status == call_status)
+                               return t_call;
+                       temp_list = temp_list->next;
+               }
+       }
+
+       DBG("Existing call list is NULL. So return NULL");
+       return NULL;
+}
+
+static bt_hfp_agent_error_t __bt_hfp_modify_indicator(
+                       const char *indicator_name,
+                       int update_value)
+{
+       bt_ag_indicators_t *hf_ind = NULL;
+       int i;
+#ifdef TIZEN_MEDIA_ENHANCE
+       if(g_strcmp0(indicator_name,
+               HFP_AGENT_CALLSETUP_INDICATOR) == 0)
+               _bt_ag_agent_check_transport_state();
+#endif
+       for (i = 0; hfp_ag_ind[i].indicator_desc != NULL; i++) {
+               if (g_str_equal(hfp_ag_ind[i].indicator_desc,
+                                               indicator_name)) {
+                       hf_ind = &hfp_ag_ind[i];
+                       break;
+               }
+       }
+
+       if (hf_ind == NULL)
+               return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
+
+       if (hf_ind->hfp_value == update_value && hf_ind->ignore)
+               return BT_HFP_AGENT_ERROR_NONE;
+
+       if (hf_ind->is_activated ==  FALSE)
+               return BT_HFP_AGENT_ERROR_NONE;
+
+       hf_ind->hfp_value = update_value;
+
+       DBG("updating hfp event indicator [%s] with value [%d]",
+                               indicator_name, hf_ind->hfp_value);
+
+       return _bt_hfp_event_indicator(i);
+}
+
+static int __bt_hfp_get_indicator_value(
+                       const bt_ag_indicators_t *ag_indicators,
+                       const char *hf_desc)
+{
+       int x;
+       for (x = 0; ag_indicators[x].indicator_desc != NULL; x++) {
+               if (g_str_equal(ag_indicators[x].indicator_desc, hf_desc))
+                       return ag_indicators[x].hfp_value;
+       }
+
+       return ERR_NOT_FOUND;
+}
+
+static void __bt_hfp_handle_call_conference(void)
+{
+       GSList *t_call_list;
+       struct telephony_call *t_active_call = NULL;
+       int t_active_call_count = 0;
+
+       struct telephony_call *t_held_call = NULL;
+       int t_held_call_count = 0;
+
+       for (t_call_list = existing_call_list; t_call_list != NULL;
+               t_call_list = t_call_list->next) {
+
+               struct telephony_call *t_call = t_call_list->data;
+
+               if (t_call->call_status == HFP_CALL_STATUS_ACTIVE) {
+                       if (t_active_call == NULL)
+                               t_active_call = t_call;
+
+                       t_active_call_count++;
+
+                       if (t_active_call_count >= 2) {
+                               if (!t_active_call->call_conference)
+                                       t_active_call->call_conference = TRUE;
+                               t_call->call_conference = TRUE;
+                       }
+
+               } else if (t_call->call_status == HFP_CALL_STATUS_HOLD) {
+                       if (t_held_call == NULL)
+                               t_held_call = t_call;
+
+                       t_held_call_count++;
+
+                       if (t_held_call_count >= 2) {
+                               if (!t_held_call->call_conference)
+                                       t_held_call->call_conference = TRUE;
+                               t_call->call_conference = TRUE;
+                       }
+               }
+       }
+
+       if (t_held_call_count == 1) {
+                       if (t_held_call->call_conference)
+                               t_held_call->call_conference = FALSE;
+               }
+
+       if (t_active_call_count == 1) {
+               if (t_active_call->call_conference)
+                       t_active_call->call_conference = FALSE;
+       }
+}
+
+static gboolean __bt_hfp_on_call_hold_timeout(gpointer t_data)
+{
+       int status;
+
+       if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD)) {
+               if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE))
+                       status = INDICATOR_EVENT_CALLHELD_MULTIPLE;
+               else
+                       status = INDICATOR_EVENT_CALLHELD_ON_HOLD;
+       } else {
+               status = INDICATOR_EVENT_CALLHELD_NONE;
+       }
+
+       __bt_hfp_modify_indicator("callheld", status);
+
+       call_on_hold_timer = 0;
+       return FALSE;
+}
+
+static void __bt_hfp_handle_call_on_hold_request(void)
+{
+       DBG(" Starting the timer for call on hold");
+       if (call_on_hold_timer)
+               g_source_remove(call_on_hold_timer);
+
+       call_on_hold_timer = g_timeout_add(250, __bt_hfp_on_call_hold_timeout,
+                                                       NULL);
+       DBG(" returning from the timer call");
+}
+
+static void __bt_hfp_set_call_status(struct telephony_call *t_call,
+                               int call_status)
+{
+       int call_held = 0;
+       int org_status = t_call->call_status;
+
+       call_held = __bt_hfp_get_indicator_value(hfp_ag_ind, "callheld");
+
+       if (org_status == call_status) {
+               DBG("Ignore the CSD Call state change to existing state");
+               return;
+       }
+
+       t_call->call_status = call_status;
+
+       DBG(" call status is   %d", call_status);
+
+       switch (call_status) {
+       case HFP_CALL_STATUS_IDLE:
+               if (t_call->call_setup) {
+                       __bt_hfp_modify_indicator("callsetup",
+                               INDICATOR_EVENT_CALLSETUP_INACTIVE);
+                       if (!t_call->call_originating)
+                               _bt_calling_stopped_indicator();
+               }
+
+               g_free(t_call->call_number);
+               t_call->call_number = NULL;
+               t_call->call_originating = FALSE;
+               t_call->call_emergency = FALSE;
+               t_call->call_on_hold = FALSE;
+               t_call->call_conference = FALSE;
+               t_call->call_setup = FALSE;
+               break;
+
+       case HFP_CALL_STATUS_COMING:
+               t_call->call_originating = FALSE;
+               t_call->call_setup = TRUE;
+               __bt_hfp_modify_indicator("callsetup",
+                                       INDICATOR_EVENT_CALLSETUP_INCOMING);
+               break;
+
+       case HFP_CALL_STATUS_CREATE:
+               t_call->call_originating = TRUE;
+               t_call->call_setup = TRUE;
+               break;
+
+       case HFP_CALL_STATUS_MO_ALERTING:
+               __bt_hfp_modify_indicator("callsetup",
+                                       INDICATOR_EVENT_CALLSETUP_ALERTING);
+               break;
+
+       case HFP_CALL_STATUS_MT_ALERTING: {
+               int  t_number = AGENT_NUMBER_TYPE_TELEPHONY;
+
+               if (t_call->call_number == NULL) {
+                       t_number = AGENT_NUMBER_TYPE_TELEPHONY;
+               } else {
+                       if (t_call->call_number[0] == '+' ||
+                               strncmp(t_call->call_number, "00", 2) == 0)
+                               t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
+               }
+
+               if (org_status == HFP_CALL_STATUS_WAITING)
+                       _bt_incoming_call_indicator(t_call->call_number,
+                                               t_number);
+       }
+               break;
+
+       case HFP_CALL_STATUS_ACTIVE:
+               DBG(" This is an Active call");
+               if (t_call->call_on_hold) {
+                       t_call->call_on_hold = FALSE;
+                       __bt_hfp_handle_call_on_hold_request();
+               } else {
+                       if (!g_slist_find(agent_active_call_list, t_call)) {
+                               DBG(" This call is not in the active call list. So Add it to the list.\n");
+                               agent_active_call_list =
+                                       g_slist_prepend(agent_active_call_list,
+                                                       t_call);
+                       }
+                       if (g_slist_length(agent_active_call_list) == 1) {
+                               DBG(" Update indicator to show the call presence.\n");
+                               __bt_hfp_modify_indicator("call",
+                                               INDICATOR_EVENT_CALL_ACTIVE);
+                       }
+
+                       __bt_hfp_modify_indicator("callsetup",
+                                       INDICATOR_EVENT_CALLSETUP_INACTIVE);
+                       __bt_hfp_handle_call_on_hold_request();
+
+                       if (!t_call->call_originating)
+                               _bt_calling_stopped_indicator();
+
+                       t_call->call_setup = FALSE;
+               }
+               break;
+
+       case HFP_CALL_STATUS_MO_RELEASE:
+       case HFP_CALL_STATUS_MT_RELEASE:
+               agent_active_call_list = g_slist_remove(agent_active_call_list,
+                                                       t_call);
+               if (g_slist_length(agent_active_call_list) == 0)
+                       __bt_hfp_modify_indicator("call",
+                                       INDICATOR_EVENT_CALL_INACTIVE);
+
+               if (org_status == HFP_CALL_STATUS_HOLD) {
+                       __bt_hfp_modify_indicator("callheld", INDICATOR_EVENT_CALLHELD_NONE);
+               }
+
+               if ((org_status == HFP_CALL_STATUS_MO_ALERTING) ||
+                       (org_status == HFP_CALL_STATUS_COMING) ||
+                       (org_status == HFP_CALL_STATUS_CREATE) ||
+                       (org_status == HFP_CALL_STATUS_WAITING)) {
+                               __bt_hfp_modify_indicator("callsetup",
+                                       INDICATOR_EVENT_CALLSETUP_INACTIVE);
+               }
+
+               if (org_status == HFP_CALL_STATUS_COMING) {
+                       if (!t_call->call_originating)
+                               _bt_calling_stopped_indicator();
+               }
+               existing_call_list = g_slist_remove(existing_call_list, t_call);
+               __bt_hfp_free_call(t_call);
+               break;
+
+       case HFP_CALL_STATUS_HOLD:
+               t_call->call_on_hold = TRUE;
+               __bt_hfp_handle_call_on_hold_request();
+               break;
+
+       case HFP_CALL_STATUS_TERMINATED:
+               if (t_call->call_on_hold &&
+               !__bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD)) {
+                       __bt_hfp_modify_indicator("callheld",
+                                       INDICATOR_EVENT_CALLHELD_NONE);
+                       return;
+               }
+
+               if (call_held == INDICATOR_EVENT_CALLHELD_MULTIPLE &&
+               __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD) &&
+               !__bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE))
+                       __bt_hfp_modify_indicator("callheld",
+                               INDICATOR_EVENT_CALLHELD_ON_HOLD);
+               break;
+
+       case HFP_CALL_STATUS_PROCEEDING:
+       case HFP_CALL_STATUS_SWAP_INITIATED:
+       case HFP_CALL_STATUS_RETRIEVE_INITIATED:
+       case HFP_CALL_STATUS_RECONNECT_PENDING:
+       case HFP_CALL_STATUS_HOLD_INITIATED:
+       case HFP_CALL_STATUS_WAITING:
+       case HFP_CALL_STATUS_ANSWERED:
+               break;
+
+       default:
+               break;
+       }
+
+       /* Update the call conference status for each of the call */
+       __bt_hfp_handle_call_conference();
+}
+
+bt_hfp_agent_error_t _bt_hfp_incoming_call(const char *call_path,
+               const char *incoming_number,
+               uint32_t incoming_call_id,
+               const char *sender)
+{
+       struct telephony_call *t_call = NULL;
+       bt_hfp_agent_error_t hfp_err = BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
+       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))
+               return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
+
+       if (!__bt_hfp_is_call_allowed(call_path))
+               return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
+
+       /* Its a new call, so create a list for it*/
+       t_call = __bt_hfp_create_new_call(call_path, incoming_call_id,
+                                               incoming_number,
+                                               sender);
+
+       /*get the type of the incoming number*/
+       if (t_call->call_number == NULL) {
+               t_number = AGENT_NUMBER_TYPE_TELEPHONY;
+               ERR("call_number is NULL");
+       } else {
+               if (t_call->call_number[0] == '+' || strncmp(
+                                       t_call->call_number, "00", 2) == 0)
+                       t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
+
+               if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE) ||
+                               __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD)) {
+                       error = _bt_call_waiting_indicator(t_call->call_number,
+                                                               t_number);
+                       if (error != 0)
+                               ERR(" Fail to update CCWA information");
+
+                       if (update_events) {
+                               hfp_err = __bt_hfp_modify_indicator(
+                                       HFP_AGENT_CALLSETUP_INDICATOR,
+                                       HFP_INCOMING_CALLSETUP);
+                               if (hfp_err  != BT_HFP_AGENT_ERROR_NONE)
+                                       ERR("Failed to update the indicators");
+                       }
+                       __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_WAITING);
+               } else {
+                       DBG(" It is an incoming call");
+
+                       if (update_events) {
+                               hfp_err = __bt_hfp_modify_indicator(
+                                       HFP_AGENT_CALLSETUP_INDICATOR,
+                                       HFP_INCOMING_CALLSETUP);
+                               if (hfp_err  != BT_HFP_AGENT_ERROR_NONE)
+                                       ERR("Failed to update the indicators");
+                       }
+
+                       error = _bt_incoming_call_indicator(t_call->call_number,
+                                                               t_number);
+
+                       __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_COMING);
+
+                       if (error == -ENODEV)
+                               return BT_HFP_AGENT_ERROR_NOT_CONNECTED;
+                       else if (error == -EBUSY)
+                               return BT_HFP_AGENT_ERROR_BUSY;
+               }
+       }
+
+       return hfp_err;
+}
+
+bt_hfp_agent_error_t _bt_hfp_outgoing_call(const char *call_path,
+                               const char *number,
+                               uint32_t call_id, const char *sender)
+{
+       struct telephony_call *t_call = NULL;
+       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)
+               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*/
+
+       err = __bt_hfp_is_call_allowed(call_path);
+       if (!err)
+               return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
+
+       /* create a new call for the call_path */
+       t_call = __bt_hfp_create_new_call(call_path, call_id, number, sender);
+
+       __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_CREATE);
+
+       ret = __bt_hfp_modify_indicator(HFP_AGENT_CALLSETUP_INDICATOR,
+                                       HFP_OUTGOING_CALLSETUP);
+       if (ret != BT_HFP_AGENT_ERROR_NONE)
+               DBG("Error in updating indicator");
+
+       return ret;
+}
+
+bt_hfp_agent_error_t _bt_hfp_change_call_status(const char *call_path,
+               const char *number, uint32_t call_status,
+               uint32_t call_id, const char *sender)
+{
+       GSList *call_list = existing_call_list;
+       struct telephony_call *t_call = NULL;
+       gboolean ret = FALSE;
+
+       if (call_status > AG_MAX_LENGTH)
+               return BT_HFP_AGENT_ERROR_INVALID_PARAM;
+
+       ret = __bt_hfp_check_for_callpath(call_path, sender);
+
+       if (!ret)
+               return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
+
+       ret = __bt_hfp_is_call_allowed(call_path);
+       if (!ret)
+               return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
+
+       /* find call with the given call_id*/
+       DBG(" Find call with the given call Id from the list");
+       while (call_list != NULL) {
+               t_call = call_list->data;
+
+               if (t_call->call_id == call_id) {
+                       DBG("Call Id Match");
+                       break;
+               } else {
+                       t_call = NULL;
+               }
+
+               call_list = call_list->next;
+       }
+
+       if (t_call == NULL) {
+               DBG("t_call is NULL. So create new call");
+               t_call = __bt_hfp_create_new_call(call_path,
+                                       call_id, number, sender);
+       }
+
+       __bt_hfp_set_call_status(t_call, call_status);
+
+       return BT_HFP_AGENT_ERROR_NONE;
+}
+
+static int __bt_hfp_update_battery_strength(int32_t battery_strength)
+{
+       int bat_strength = 0;
+       int x, change_value;
+
+       DBG(" Battery strength is.... %d", battery_strength);
+
+       /* get the current battery level */
+       for (x = 0; hfp_ag_ind[x].indicator_desc != NULL; x++) {
+               if (g_str_equal(hfp_ag_ind[x].indicator_desc, "battchg"))
+                       bat_strength = hfp_ag_ind[x].hfp_value;
+       }
+
+       /* We need to send battery status ranging from 0-5 */
+       if (battery_strength < 5)
+                change_value = 0;
+       else if (battery_strength >= 100)
+               change_value = 5;
+       else
+               change_value = battery_strength / 20 + 1;
+
+       if (bat_strength == change_value) {
+               DBG("no change in battery strength");
+               return 0;
+       }
+
+       if (__bt_hfp_modify_indicator("battchg",
+                       change_value) == BT_HFP_AGENT_ERROR_NONE)
+               return 1;
+
+       return 0;
+}
+
+static int __bt_hfp_update_signal_strength(int32_t signal_strength_bars)
+{
+       if (signal_strength_bars < 0)
+               signal_strength_bars = 0;
+       else if (signal_strength_bars > 5)
+               signal_strength_bars = 5;
+
+       if (network_info.signal_strength == signal_strength_bars) {
+               DBG("no change in signal strength");
+               return 0;
+       }
+
+       network_info.signal_strength = signal_strength_bars;
+
+       if (__bt_hfp_modify_indicator("signal",
+                       signal_strength_bars) == BT_HFP_AGENT_ERROR_NONE)
+               return 1;
+
+       return 0;
+}
+
+static int __bt_hfp_update_registration_status(uint8_t register_status)
+{
+       bt_hfp_agent_error_t reg_ret = BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
+
+       DBG("Updating registration status to.... %d", register_status);
+
+       if (network_info.network_status == register_status) {
+               DBG("No change in registration status");
+               return 0;
+       }
+
+       if (register_status == BT_AGENT_NETWORK_REG_STATUS_ROAMING) {
+               reg_ret = __bt_hfp_modify_indicator("roam",
+                                       INDICATOR_EVENT_ROAM_ACTIVE);
+
+               if (network_info.network_status >
+                                       BT_AGENT_NETWORK_REG_STATUS_ROAMING)
+                       reg_ret = __bt_hfp_modify_indicator("service",
+                                       INDICATOR_EVENT_SERVICE_PRESENT);
+       } else if (register_status == BT_AGENT_NETWORK_REG_STATUS_HOME) {
+               reg_ret = __bt_hfp_modify_indicator("roam",
+                                       INDICATOR_EVENT_ROAM_INACTIVE);
+
+               if (network_info.network_status >
+                                       BT_AGENT_NETWORK_REG_STATUS_ROAMING)
+                       reg_ret = __bt_hfp_modify_indicator("service",
+                                       INDICATOR_EVENT_SERVICE_PRESENT);
+       } else if (register_status == BT_AGENT_NETWORK_REG_STATUS_OFFLINE ||
+               register_status == BT_AGENT_NETWORK_REG_STATUS_SEARCHING ||
+               register_status == BT_AGENT_NETWORK_REG_STATUS_NO_SIM ||
+               register_status == BT_AGENT_NETWORK_REG_STATUS_POWEROFF ||
+               register_status == BT_AGENT_NETWORK_REG_STATUS_POWERSAFE ||
+               register_status == BT_AGENT_NETWORK_REG_STATUS_NO_COVERAGE ||
+               register_status == BT_AGENT_NETWORK_REG_STATUS_REJECTED ||
+               register_status == BT_AGENT_NETWORK_REG_STATUS_UNKOWN) {
+               if (network_info.network_status <
+                                       BT_AGENT_NETWORK_REG_STATUS_OFFLINE)
+                       reg_ret = __bt_hfp_modify_indicator("service",
+                                               INDICATOR_EVENT_SERVICE_NONE);
+       }
+
+       network_info.network_status = register_status;
+       if (reg_ret == BT_HFP_AGENT_ERROR_NONE)
+               return 1;
+
+       return 0;
+}
+
+int _bt_hfp_set_property_value(const char *property, int value)
+{
+       int ret = 0;
+
+       DBG("Property is %s", property);
+
+       if (g_str_equal("RegistrationChanged", property))
+               ret = __bt_hfp_update_registration_status(value);
+
+       else if (g_str_equal("SignalBarsChanged", property))
+               ret = __bt_hfp_update_signal_strength(value);
+
+       else if (g_str_equal("BatteryBarsChanged", property))
+               ret = __bt_hfp_update_battery_strength(value);
+
+       return ret;
+}
+
+int _bt_hfp_set_property_name(const char *property, const char *operator_name)
+{
+       int ret = 0;
+
+       if (operator_name == NULL)
+               return 0;
+
+       if (g_str_equal("OperatorNameChanged", property)) {
+               g_free(network_info.network_operator_name);
+               network_info.network_operator_name =
+                               g_strndup(operator_name, 16);
+               ret = 1;
+       }
+
+       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);
+               ret = 1;
+       }
+       return ret;
+}
+
+static int __bt_hfp_answer_call(struct telephony_call *t_call)
+{
+       if (t_call->call_id != 0 && t_call->call_path != NULL &&
+               t_call->call_sender != NULL) {
+               _bt_ag_agent_answer_call(t_call->call_id,
+                                               t_call->call_path,
+                                               t_call->call_sender);
+               return 0;
+       }
+       return -1;
+}
+
+void _bt_hfp_answer_call_request(void *t_device)
+{
+       struct telephony_call *t_call;
+
+       t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_COMING);
+
+       if (t_call == NULL)
+               t_call = __bt_hfp_get_call_with_status(
+                               HFP_CALL_STATUS_MT_ALERTING);
+
+       if (t_call == NULL)
+               t_call = __bt_hfp_get_call_with_status(
+                       HFP_CALL_STATUS_PROCEEDING);
+
+       if (t_call == NULL)
+               t_call = __bt_hfp_get_call_with_status(
+                                       HFP_CALL_STATUS_WAITING);
+
+       if (t_call == NULL) {
+               _bt_answer_call_response(t_device,
+                                       HFP_STATE_MNGR_ERR_NOT_ALLOWED);
+               return;
+       }
+
+       if (__bt_hfp_answer_call(t_call) <  0)
+               _bt_answer_call_response(t_device,
+                               HFP_STATE_MNGR_ERR_AG_FAILURE);
+       else
+               _bt_answer_call_response(t_device, HFP_STATE_MNGR_ERR_NONE);
+}
+
+
+void _bt_hfp_dial_number_request(const char *dial_number, void *t_device)
+{
+       int call_flag = caller_id;
+       bt_hfp_agent_error_t error_code = 0;
+
+       if (strncmp(dial_number, "#31#", 4) == 0) {
+               dial_number = dial_number + 4;
+               call_flag = ALLOW_CALL_FLAG;
+       } else if (strncmp(dial_number, "*31#", 4) == 0) {
+               dial_number = dial_number + 4;
+               call_flag = RESTRAIN_CALL_FLAG;
+       } else if (dial_number[0] == '>') {
+               int dial_location = strtol(&dial_number[1], NULL, 0);
+
+               error_code = _bt_ag_agent_dial_memory(dial_location);
+
+               if (error_code ==  BT_HFP_AGENT_ERROR_NONE)
+                       _bt_dial_number_response(t_device,
+                                       HFP_STATE_MNGR_ERR_NONE);
+               else
+                       _bt_dial_number_response(t_device,
+                               HFP_STATE_MNGR_ERR_AG_FAILURE);
+               return;
+       }
+
+       error_code = _bt_ag_agent_dial_num(dial_number, call_flag);
+
+       if (error_code == BT_HFP_AGENT_ERROR_NONE) {
+               _bt_dial_number_response(t_device, HFP_STATE_MNGR_ERR_NONE);
+               return;
+       }
+
+       _bt_dial_number_response(t_device, HFP_STATE_MNGR_ERR_AG_FAILURE);
+
+}
+
+void _bt_hfp_update_event_request(int indicator, void *t_device)
+{
+       if (indicator == 1)
+               update_events = TRUE;
+       else
+               update_events = FALSE;
+
+       _bt_event_reporting_response(t_device,
+                                       HFP_STATE_MNGR_ERR_NONE);
+}
+
+static int __bt_bt_hfp_reject_call(struct telephony_call *t_call)
+{
+       gboolean ret;
+
+       if (t_call != NULL) {
+               DBG(" rejecting call from sender %s with call path %s and call id %d",
+                               t_call->call_sender,
+                               t_call->call_path,
+                               t_call->call_id);
+
+               ret = _bt_ag_agent_reject_call(t_call->call_id,
+                                               t_call->call_path,
+                                               t_call->call_sender);
+               if (ret)
+                       return 0;
+       }
+
+       return -1;
+}
+
+static int __bt_hfp_release_call(struct telephony_call *t_call)
+{
+       gboolean ret = _bt_ag_agent_release_call(t_call->call_id,
+                                       t_call->call_path,
+                                       t_call->call_sender);
+       if (!ret)
+               return -1;
+
+       return 0;
+}
+
+static int __bt_hfp_release_conference(void)
+{
+       GSList *temp_list = existing_call_list;
+
+       while (temp_list != NULL) {
+               struct telephony_call *t_call = temp_list->data;
+
+               if (t_call->call_conference)
+                       __bt_hfp_release_call(t_call);
+
+               temp_list = temp_list->next;
+       }
+       return 0;
+}
+
+void _bt_hfp_terminate_call_request(void *t_device)
+{
+       struct telephony_call *t_call;
+       struct telephony_call *t_alert = NULL;
+       int t_error = 0;
+
+       t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE);
+
+       if (t_call == NULL) {
+               DBG("Find non-idle call");
+               GSList *temp_call_list = existing_call_list;
+               while (temp_call_list != NULL) {
+                       t_call = temp_call_list->data;
+
+                       if (t_call->call_status == HFP_AGENT_CALL_IDLE)
+                               temp_call_list = temp_call_list->next;
+                       else
+                               break;
+               }
+       }
+
+       if (t_call == NULL) {
+               DBG("Seems like there are no active calls. So do not allow the call");
+               _bt_terminate_call_response(t_device,
+                                       HFP_STATE_MNGR_ERR_NOT_ALLOWED);
+               return;
+       }
+
+       if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_WAITING) != NULL) {
+               int value = 1;
+               t_error = _bt_ag_agent_threeway_call(value, t_call->call_path,
+                               t_call->call_sender);
+       } else if ((t_alert = __bt_hfp_get_call_with_status(
+                               HFP_CALL_STATUS_CREATE))
+               != NULL) {
+               t_error = __bt_bt_hfp_reject_call(t_alert);
+       } else if ((t_alert = __bt_hfp_get_call_with_status(
+                               HFP_CALL_STATUS_MO_ALERTING))
+               != NULL) {
+               t_error = __bt_bt_hfp_reject_call(t_alert);
+       } else if       ((t_alert =  __bt_hfp_get_call_with_status(
+                       HFP_CALL_STATUS_COMING)) != NULL) {
+               t_error = __bt_bt_hfp_reject_call(t_alert);
+       } else if (t_call->call_conference)
+               t_error = __bt_hfp_release_conference();
+       else
+               t_error = __bt_hfp_release_call(t_call);
+
+       if (t_error < 0)
+               _bt_terminate_call_response(t_device,
+                               HFP_STATE_MNGR_ERR_AG_FAILURE);
+       else
+               _bt_terminate_call_response(t_device, HFP_STATE_MNGR_ERR_NONE);
+}
+
+void _bt_hfp_call_hold_request(const char *t_cmd, void *t_device)
+{
+
+       struct telephony_call *t_call = NULL;
+       GSList *t_sender_list = call_senders_paths;
+       sender_info_t *sender_info = NULL;
+       uint32_t t_chld_value;
+
+       t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE);
+       if (t_call == NULL) {
+               if ((t_call =
+                       __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD))
+                       == NULL) {
+                       if ((t_call = __bt_hfp_get_call_with_status(
+                               HFP_CALL_STATUS_WAITING)) == NULL) {
+                               /* means there is no outgoing call*/
+                               _bt_call_hold_response(t_device,
+                                       HFP_STATE_MNGR_ERR_AG_FAILURE);
+                               return;
+                       }
+               }
+       }
+
+       while (t_sender_list != NULL) {
+               sender_info = t_sender_list->data;
+               if (sender_info == NULL) {
+                       _bt_call_hold_response(t_device,
+                               HFP_STATE_MNGR_ERR_AG_FAILURE);
+                       return;
+               }
+               if (g_strcmp0(t_call->call_path, sender_info->sender_path)
+                               == 0)
+                       break;
+
+               t_sender_list = t_sender_list->next;
+       }
+
+       t_chld_value = strtoul(&t_cmd[0], NULL, 0);
+       gboolean ret = _bt_ag_agent_threeway_call(t_chld_value,
+                       t_call->call_path,
+                       t_call->call_sender);
+
+       if (ret == TRUE)
+               _bt_call_hold_response(t_device, HFP_STATE_MNGR_ERR_NONE);
+       else {
+               _bt_call_hold_response(t_device, HFP_STATE_MNGR_ERR_AG_FAILURE);
+       }
+}
+
+void _bt_hfp_key_press_request(const char *t_key_press, void *t_device)
+{
+       struct telephony_call *t_active_call;
+       struct telephony_call *t_waiting_call;
+       int t_error = 0;
+
+       t_waiting_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_COMING);
+
+       if (t_waiting_call == NULL)
+               t_waiting_call = __bt_hfp_get_call_with_status(
+                               HFP_CALL_STATUS_MT_ALERTING);
+
+       if (t_waiting_call == NULL)
+               t_waiting_call = __bt_hfp_get_call_with_status(
+                               HFP_CALL_STATUS_PROCEEDING);
+
+       t_active_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE);
+
+
+       if (t_waiting_call != NULL)
+               t_error = __bt_hfp_answer_call(t_waiting_call);
+       else if (t_active_call != NULL)
+               t_error = __bt_hfp_release_call(t_active_call);
+       else {
+               if (_bt_ag_agent_dial_last_num(t_device) !=
+                               BT_HFP_AGENT_ERROR_NONE)
+                       _bt_dial_number_response(t_device,
+                                               HFP_STATE_MNGR_ERR_AG_FAILURE);
+               else
+                       _bt_dial_number_response(t_device,
+                                               HFP_STATE_MNGR_ERR_NONE);
+               return;
+       }
+
+       if (t_error < 0)
+               _bt_key_press_response(t_device,
+                                       HFP_STATE_MNGR_ERR_AG_FAILURE);
+       else
+               _bt_key_press_response(t_device,
+                                               HFP_STATE_MNGR_ERR_NONE);
+}
+
+void _bt_hfp_last_dialed_number_request(void *t_device)
+{
+       bt_hfp_agent_error_t error = _bt_ag_agent_dial_last_num(t_device);
+
+       if (error != BT_HFP_AGENT_ERROR_NONE)
+               _bt_dial_number_response(t_device,
+                                       HFP_STATE_MNGR_ERR_AG_FAILURE);
+       else
+               _bt_dial_number_response(t_device, HFP_STATE_MNGR_ERR_NONE);
+}
+
+void _bt_hfp_channel_dtmf_request(char t_tone, void *t_device)
+{
+       char buf[2] = { t_tone, '\0' };
+       char *tone_buffer = buf;
+
+       struct telephony_call *t_call = __bt_hfp_get_call_with_status(
+                                       HFP_CALL_STATUS_ACTIVE);
+       if (t_call == NULL) {
+               t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD);
+               if (t_call == NULL) {
+                       t_call = __bt_hfp_get_call_with_status(
+                                       HFP_CALL_STATUS_WAITING);
+                       if (t_call == NULL) {
+                               /* if this point is reached,
+                               it means there is no ongoing call */
+                               _bt_transmit_dtmf_response(t_device,
+                                               HFP_STATE_MNGR_ERR_AG_FAILURE);
+                               return;
+                       }
+               }
+       }
+
+       if (_bt_ag_agent_send_dtmf(tone_buffer, t_call->call_path,
+               t_call->call_sender) != BT_HFP_AGENT_ERROR_NONE) {
+               _bt_transmit_dtmf_response(t_device,
+                                       HFP_STATE_MNGR_ERR_AG_FAILURE);
+                       return;
+               }
+
+       _bt_transmit_dtmf_response(t_device, HFP_STATE_MNGR_ERR_NONE);
+}
+
+void _bt_hfp_vendor_cmd_request(const char *cmd,
+                                               void *t_device)
+{
+       GSList *t_sender_list = call_senders_paths;
+       sender_info_t *sender_info = NULL;
+       GSList *l;
+       bt_hfp_agent_error_t error = BT_HFP_AGENT_ERROR_NONE;
+
+       if (NULL != t_sender_list) {
+               for (l = t_sender_list; l != NULL; l = l->next) {
+                       sender_info = l->data;
+                       error = _bt_ag_agent_vendor_cmd(cmd,
+                               sender_info->sender_path,
+                               sender_info->sender_name);
+                       if (error != BT_HFP_AGENT_ERROR_NONE)
+                               break;
+               }
+       }
+
+       if (error != BT_HFP_AGENT_ERROR_NONE)
+               _bt_vendor_cmd_response(t_device,
+                                       HFP_STATE_MNGR_ERR_AG_FAILURE);
+       else
+               _bt_vendor_cmd_response(t_device, HFP_STATE_MNGR_ERR_NONE);
+}
+
+void _bt_hfp_subscriber_number_request(void *t_device)
+{
+       if (ag_subscriber_num != NULL) {
+
+               int  t_number =  AGENT_NUMBER_TYPE_TELEPHONY;
+
+               if (ag_subscriber_num[0] == '+' || strncmp(
+                                       ag_subscriber_num, "00", 2) == 0)
+                       t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
+
+               _bt_subscriber_number_indicator(ag_subscriber_num,
+                       t_number, AGENT_SUBSCRIBER_SERVICE_VOICE);
+       }
+
+       _bt_subscriber_number_response(t_device, HFP_STATE_MNGR_ERR_NONE);
+}
+
+static int __bt_hfp_get_call_status(struct telephony_call *t_call)
+{
+       switch (t_call->call_status) {
+       case HFP_CALL_STATUS_IDLE:
+       case HFP_CALL_STATUS_MO_RELEASE:
+       case HFP_CALL_STATUS_MT_RELEASE:
+       case HFP_CALL_STATUS_TERMINATED:
+               return -1;
+
+       case HFP_CALL_STATUS_ANSWERED:
+       case HFP_CALL_STATUS_ACTIVE:
+       case HFP_CALL_STATUS_RECONNECT_PENDING:
+       case HFP_CALL_STATUS_SWAP_INITIATED:
+       case HFP_CALL_STATUS_HOLD_INITIATED:
+               return AGENT_CALL_STATUS_ACTIVE;
+
+       case HFP_CALL_STATUS_RETRIEVE_INITIATED:
+       case HFP_CALL_STATUS_HOLD:
+               return AGENT_CALL_STATUS_HELD;
+
+       case  HFP_CALL_STATUS_WAITING:
+               return AGENT_CALL_STATUS_WAITING;
+
+       case HFP_CALL_STATUS_CREATE:
+               return AGENT_CALL_STATUS_DIALING;
+
+       case HFP_CALL_STATUS_PROCEEDING:
+               if (t_call->call_originating)
+                       return AGENT_CALL_STATUS_DIALING;
+               if (g_slist_length(agent_active_call_list) > 0)
+                       return AGENT_CALL_STATUS_WAITING;
+               else
+                       return AGENT_CALL_STATUS_INCOMING;
+
+       case HFP_CALL_STATUS_COMING:
+               if (g_slist_length(agent_active_call_list) > 0)
+                       return AGENT_CALL_STATUS_WAITING;
+               else
+                       return AGENT_CALL_STATUS_INCOMING;
+
+       case HFP_CALL_STATUS_MO_ALERTING:
+               return AGENT_CALL_STATUS_ALERTING;
+
+       case HFP_CALL_STATUS_MT_ALERTING:
+               return AGENT_CALL_STATUS_INCOMING;
+
+       default:
+               return -1;
+       }
+}
+
+void _bt_list_current_calls(void *t_device)
+{
+       GSList *t_call_list =  existing_call_list;
+       int t_status;
+       int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
+       int t_direction, t_call_conference;
+       int index;
+
+       while (t_call_list != NULL) {
+               struct telephony_call *t_call  = t_call_list->data;
+               t_status = __bt_hfp_get_call_status(t_call);
+               if (t_status >= 0) {
+                       if (t_call->call_originating != TRUE)
+                               t_direction = AGENT_CALL_DIRECTION_INCOMING;
+                       else
+                               t_direction = AGENT_CALL_DIRECTION_OUTGOING;
+
+                       if (t_call->call_conference != TRUE)
+                               t_call_conference = AGENT_CALL_MULTIPARTY_NO;
+                       else
+                               t_call_conference = AGENT_CALL_MULTIPARTY_YES;
+
+                       if (t_call->call_number == NULL) {
+                               t_number = AGENT_NUMBER_TYPE_TELEPHONY;
+                       } else {
+                               if (t_call->call_number[0] == '+' || strncmp(
+                                               t_call->call_number, "00", 2) == 0)
+                                       t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
+                       }
+
+                       index = t_call->call_id;
+                       _bt_list_current_call_indicator(t_device, index, t_direction,
+                                       AGENT_CALL_MODE_VOICE,
+                                       t_status,
+                                       t_call->call_number,
+                                       t_call_conference,
+                                       t_number);
+               }
+               t_call_list = t_call_list->next;
+       }
+       _bt_list_current_calls_response(t_device, HFP_STATE_MNGR_ERR_NONE);
+}
+
+void _bt_hfp_release_all_calls_by_sender(const char *sender)
+{
+       GSList *temp_list = existing_call_list;
+       GSList *next_list;
+
+       if(!sender)
+               return;
+
+       DBG("sender [%s]", sender);
+
+       while (temp_list != NULL) {
+               struct telephony_call *t_call = temp_list->data;
+
+               if (g_strcmp0(t_call->call_sender, sender) == 0) {
+                       INFO("terminate call[%d]", t_call->call_id);
+                       next_list = temp_list->next;
+                       __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_MT_RELEASE);
+                       temp_list = next_list;
+               } else
+                       temp_list = temp_list->next;
+       }
+}
+
+void _bt_hfp_noise_red_and_echo_cancel_request(gboolean t_enable,
+                       void *t_device)
+{
+       if (_bt_hfp_agent_nrec_status(t_enable, t_device) == TRUE)
+               _bt_nr_and_ec_response(t_device, HFP_STATE_MNGR_ERR_NONE);
+       else
+               _bt_nr_and_ec_response(t_device, HFP_STATE_MNGR_ERR_AG_FAILURE);
+
+       return;
+}
+
+void _bt_hfp_voice_dial_request(gboolean t_enable, void *t_device)
+{
+       gboolean ret = FALSE;
+       int call_state = 0;
+
+       if (vconf_get_int(VCONFKEY_CALL_STATE, &call_state) < 0)
+               ERR("vconf_get_int is failed");
+
+       if ((t_enable == TRUE && call_state == 0) || t_enable == FALSE)
+               ret = _bt_ag_agent_voice_dial(t_enable);
+
+       if (ret == TRUE)
+               _bt_voice_dial_response(t_device, HFP_STATE_MNGR_ERR_NONE);
+       else
+               _bt_voice_dial_response(t_device,
+                               HFP_STATE_MNGR_ERR_AG_FAILURE);
+
+       return;
+}
+
+void _bt_hfp_set_indicators(const char *t_command, void *t_device)
+{
+       const char delims = ',';
+       char *str = NULL;
+       int i = 0;
+       if (t_command == NULL)
+               goto fail;
+
+       str = strchr(t_command, '=');
+       while (hfp_ag_ind[i].indicator_desc != NULL && str != NULL) {
+               str++;
+
+               if ((g_strcmp0(hfp_ag_ind[i].indicator_desc, "call") != 0) &&
+               (g_strcmp0(hfp_ag_ind[i].indicator_desc, "callheld") != 0) &&
+               (g_strcmp0(hfp_ag_ind[i].indicator_desc, "callsetup") != 0)) {
+
+                       if (*str == '0') {
+                               hfp_ag_ind[i].is_activated = FALSE;
+                       } else if (*str == '1') {
+                               hfp_ag_ind[i].is_activated = TRUE;
+                       } else {
+                               DBG(" no change in is_activated for[%s]\n",
+                               hfp_ag_ind[i].indicator_desc);
+                       }
+               }
+               str = strchr(str, delims);
+               i++;
+       }
+
+       _bt_indicators_activation_response(t_device, HFP_STATE_MNGR_ERR_NONE);
+       return;
+
+fail:
+       _bt_indicators_activation_response(t_device,
+                       HFP_STATE_MNGR_ERR_INVALID_CHAR_IN_STRING);
+       return;
+}
+
+static int __bt_hfp_get_phonebook_count(const char *path, uint32_t *max_size,
+                               uint32_t *used)
+{
+#ifndef TIZEN_WEARABLE
+       GDBusConnection *g_conn;
+       GDBusProxy *g_proxy;
+       GError *err = NULL;
+       GVariant *ret = NULL;
+       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;
+       }
+
+       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;
+       }
+
+       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);
+       if ((g_strcmp0(path, "\"SM\"") == 0) ||
+                       (g_strcmp0(path, "\"ME\"") == 0)) {
+               max = AGENT_MAX_PB_COUNT;
+       } else if ((g_strcmp0(path, "\"DC\"") == 0) ||
+                       (g_strcmp0(path, "\"MC\"") == 0) ||
+                       (g_strcmp0(path, "\"RC\"") == 0)) {
+               max = AGENT_MAX_CALLLOG_COUNT;
+       }
+
+       if (max_size)
+               *max_size = max;
+       if (used) {
+               if (size > max)
+                       *used = max;
+               else
+                       *used = size;
+       }
+
+       if (g_conn)
+               g_object_unref(g_conn);
+       if (g_proxy)
+               g_object_unref(g_proxy);
+#endif
+       return 0;
+}
+
+void _bt_hfp_select_phonebook_memory_status(void *t_device)
+{
+       int32_t path_id = ag_pb_info.path_id;
+       uint32_t used = 0;
+       uint32_t max_size = 0;
+
+       hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
+
+       if (path_id < 0 || path_id >= AGENT_PB_STORE_LIST_SIZE)
+               path_id = 0;
+
+       if (__bt_hfp_get_phonebook_count(agent_pb_store_list[path_id],
+                       &max_size, &used))
+               err = HFP_STATE_MNGR_ERR_AG_FAILURE;
+
+       _bt_select_phonebook_memory_status_response(t_device,
+                       agent_pb_store_list[path_id],
+                       max_size, used,
+                       err);
+}
+
+static char *__bt_hfp_get_supported_list(const char *char_list[],
+                                       unsigned int size)
+{
+       GString *strng;
+
+       int index = 0;
+
+       if (char_list == NULL || size == 0)
+               return NULL;
+
+       strng = g_string_new("(");
+
+       while (index < size) {
+               if (index > 0)
+                       g_string_append(strng, ",");
+
+               g_string_append(strng, char_list[index]);
+               index++;
+       }
+
+       g_string_append(strng, ")");
+
+       return g_string_free(strng, FALSE);
+}
+
+void _bt_hfp_select_phonebook_memory_list(void *t_device)
+{
+       char *str;
+
+       str = __bt_hfp_get_supported_list(agent_pb_store_list,
+                       AGENT_PB_STORE_LIST_SIZE);
+
+       _bt_select_phonebook_memory_list_response(t_device,
+                       str, HFP_STATE_MNGR_ERR_NONE);
+
+       g_free(str);
+}
+
+void _bt_hfp_select_phonebook_memory(void *t_device, const gchar *pb_path)
+{
+       int i = 0;
+       hfp_state_manager_err_t err;
+
+       while (i < AGENT_PB_STORE_LIST_SIZE) {
+               if (strcmp(agent_pb_store_list[i], pb_path) == 0)
+                       break;
+               i++;
+       }
+
+       if      (i >= 0 && i < AGENT_PB_STORE_LIST_SIZE) {
+               err = HFP_STATE_MNGR_ERR_NONE;
+               ag_pb_info.path_id = i;
+       } else {
+               err = HFP_STATE_MNGR_ERR_INVALID_CHAR_IN_STRING;
+       }
+       _bt_select_phonebook_memory_response(t_device, err);
+}
+
+void _bt_hfp_read_phonebook_entries_list(void *t_device)
+{
+       hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
+
+       int32_t path_id = ag_pb_info.path_id;
+       uint32_t used = 0;
+
+       if (path_id < 0 || path_id >= AGENT_PB_STORE_LIST_SIZE)
+               err = HFP_STATE_MNGR_ERR_INVALID_INDEX;
+       else {
+               if (__bt_hfp_get_phonebook_count(agent_pb_store_list[path_id],
+                                       NULL, &used) != 0) {
+                       err = HFP_STATE_MNGR_ERR_NOT_ALLOWED;
+               }
+       }
+
+       _bt_read_phonebook_entries_list_response(t_device, used,
+               AGENT_PB_NUMBER_MAX_LENGTH, AGENT_PB_NAME_MAX_LENGTH,
+                       err);
+}
+
+static int __bt_hfp_get_phonebook_entries(int start_index, int end_index)
+{
+#ifdef TIZEN_WEARABLE
+       int count = 0;
+#else
+       GDBusConnection *g_conn;
+       GDBusProxy *g_proxy;
+       GError *err = NULL;
+       GVariant *ret = NULL;
+       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;
+
+       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;
+       }
+
+       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;
+       }
+
+       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 (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);
+               } 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(name);
+                               g_free(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
+       return count;
+}
+
+void _bt_hfp_read_phonebook_entries(void *t_device, const char *cmd)
+{
+       int start_index = 0;
+       int end_index = 0;
+
+       int count = 0;
+
+       char *str = NULL;
+       char *next = NULL;
+
+       hfp_state_manager_err_t err;
+
+       if (cmd == NULL)
+               return;
+
+       str = g_strdup(cmd);
+       next = strchr(str, ',');
+
+       if (next) {
+               *next = '\0';
+               next++;
+
+               end_index = strtol(next, NULL, 10);
+       }
+
+       start_index = strtol(str, NULL, 10);
+
+       g_free(str);
+
+       count = __bt_hfp_get_phonebook_entries(start_index, end_index);
+
+       if (count < 0)
+               err = HFP_STATE_MNGR_ERR_AG_FAILURE;
+       else if (count == 0)
+               err = HFP_STATE_MNGR_ERR_INVALID_INDEX;
+       else
+               err = HFP_STATE_MNGR_ERR_NONE;
+
+       _bt_read_phonebook_entries_response(t_device, err);
+}
+
+void _bt_hfp_find_phonebook_entries_status(void *t_device)
+{
+       _bt_find_phonebook_entries_status_indicator(
+                       AGENT_PB_NUMBER_MAX_LENGTH,
+                       AGENT_PB_NAME_MAX_LENGTH);
+
+       _bt_find_phonebook_entries_status_response(t_device,
+                                               HFP_STATE_MNGR_ERR_NONE);
+}
+
+static int __bt_hfp_find_pb_entries(const char *str)
+{
+       return 0;
+}
+
+void _bt_hfp_find_phonebook_entries(void *t_device, const char *cmd)
+{
+       gchar *st = NULL;
+       gchar *unquoted = NULL;
+
+       hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
+
+       /* remove quote and compress */
+       st = strchr(cmd, '"');
+       if (st == NULL)
+               unquoted = g_strdup(cmd);
+       else {
+               gchar *end = NULL;
+
+               end = strrchr(cmd, '"');
+               if (end == NULL)
+                       unquoted = g_strdup(cmd);
+               else
+                       unquoted = g_strndup(st + 1, end - st - 1);
+       }
+
+       if (__bt_hfp_find_pb_entries(unquoted))
+               err = HFP_STATE_MNGR_ERR_AG_FAILURE;
+
+       _bt_find_phonebook_entries_response(t_device, err);
+
+       g_free(unquoted);
+}
+
+void _bt_hfp_get_character_set(void *t_device)
+{
+       _bt_supported_character_generic_response(t_device,
+               (char *)agent_supported_character_set[ag_pb_info.charset_id],
+               HFP_STATE_MNGR_ERR_NONE);
+}
+
+void _bt_hfp_list_supported_character(void *t_device)
+{
+       char *str;
+
+       str = __bt_hfp_get_supported_list(agent_supported_character_set,
+                       AGENT_SUPPORTED_CHARACTER_SET_SIZE);
+
+       _bt_supported_character_generic_response(t_device,
+                       str, HFP_STATE_MNGR_ERR_NONE);
+
+       g_free(str);
+}
+
+void _bt_hfp_set_character_set(void *t_device, const char *cmd)
+{
+       int index = 0;
+
+       while (index < AGENT_SUPPORTED_CHARACTER_SET_SIZE) {
+               if (strcmp(agent_supported_character_set[index], cmd) == 0) {
+                       _bt_set_characterset_generic_response(t_device,
+                                       HFP_STATE_MNGR_ERR_NONE);
+
+                       ag_pb_info.charset_id = index;
+                       return;
+               }
+               index++;
+       }
+
+       _bt_set_characterset_generic_response(t_device,
+                       HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
+       return;
+}
+
+void _bt_hfp_signal_quality_reply(int32_t rssi, int32_t ber,
+       void *t_device)
+{
+       DBG("signal_quality_reply");
+
+       if (rssi == -1 && ber == -1) {
+               _bt_signal_quality_response(t_device, rssi, ber,
+               HFP_STATE_MNGR_ERR_AG_FAILURE);
+       } else {
+               _bt_signal_quality_response(t_device, rssi, ber,
+               HFP_STATE_MNGR_ERR_NONE);
+       }
+}
+
+void _bt_hfp_battery_property_reply(void *data, int32_t bcs,
+                       int32_t bcl)
+{
+       if (bcs == -1 || bcl == -1) {
+               _bt_battery_charge_status_response(data, bcs,
+                       bcl, HFP_STATE_MNGR_ERR_AG_FAILURE);
+       } else {
+               _bt_battery_charge_status_response(data, bcs,
+                       bcl, HFP_STATE_MNGR_ERR_NONE);
+       }
+
+       return;
+}
+
+void _bt_hfp_get_battery_property(void *t_device)
+{
+       _bt_ag_agent_get_battery_status(t_device);
+}
+
+void _bt_hfp_operator_reply(char *operator_name,  void *t_device)
+{
+       if (operator_name == NULL)
+               goto failed;
+
+       network_info.network_operator_name = g_strndup(operator_name, 16);
+
+       _bt_operator_selection_indicator(AGENT_OPERATOR_MODE_AUTO,
+                               operator_name);
+       _bt_operator_selection_response(t_device, HFP_STATE_MNGR_ERR_NONE);
+       return;
+
+failed:
+       _bt_operator_selection_indicator(AGENT_OPERATOR_MODE_AUTO, "UNKNOWN");
+       _bt_operator_selection_response(t_device,
+                               HFP_STATE_MNGR_ERR_AG_FAILURE);
+}
+
+void _bt_hfp_get_operator_selection_request(void *t_device)
+{
+       _bt_ag_agent_get_operator_name(t_device);
+}
+
+void _bt_hfp_response_and_hold_request(void *t_device)
+{
+       _bt_response_and_hold_response(t_device,
+                       HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
+}
+
+void _bt_get_activity_status(void *t_device)
+{
+       DBG("telephony-tizen: telephony_get_activity_status");
+
+       if (NULL != (__bt_hfp_get_call_with_status(
+                               HFP_CALL_STATUS_MT_ALERTING)) ||
+               NULL != (__bt_hfp_get_call_with_status(
+                               HFP_CALL_STATUS_MO_ALERTING)) ||
+               NULL != (__bt_hfp_get_call_with_status(
+                               HFP_CALL_STATUS_COMING)) ||
+               NULL != (__bt_hfp_get_call_with_status(
+                               HFP_CALL_STATUS_CREATE)))
+               _bt_hfp_get_activity_status_rsp(t_device,
+                               HFP_AGENT_ACTIVITY_STATUS_RINGING,
+                               HFP_STATE_MNGR_ERR_NONE);
+       else if (NULL != (__bt_hfp_get_call_with_status(
+                                       HFP_CALL_STATUS_WAITING)) ||
+               NULL != (__bt_hfp_get_call_with_status(
+                                               HFP_CALL_STATUS_ACTIVE)))
+               _bt_hfp_get_activity_status_rsp(t_device,
+                               HFP_AGENT_ACTIVITY_STATUS_CALL_IN_PROGRESS,
+                               HFP_STATE_MNGR_ERR_NONE);
+       else
+               _bt_hfp_get_activity_status_rsp(t_device,
+                               HFP_AGENT_ACTIVITY_STATUS_READY,
+                               HFP_STATE_MNGR_ERR_NONE);
+}
+
+void _bt_hfp_get_imei_number_reply(char *imei_number,  void *t_device)
+{
+       _bt_hfp_get_equipment_identity_rsp(t_device, imei_number,
+                                       HFP_STATE_MNGR_ERR_NONE);
+}
+
+void _bt_hfp_get_imsi_reply(char *mcc, char *mnc, char *msin, void *t_device)
+{
+       if (mcc != NULL && mnc != NULL && msin != NULL)
+               _bt_hfp_get_imsi_rsp(t_device, mcc, mnc, msin,
+                               HFP_STATE_MNGR_ERR_NONE);
+       else
+               _bt_hfp_get_imsi_rsp(t_device,NULL,NULL,NULL,
+                               HFP_STATE_MNGR_ERR_NOT_ALLOWED);
+}
+
+void _bt_hfp_get_creg_status_reply(int n, int status, void *t_device)
+{
+       _bt_hfp_get_creg_status_rsp(t_device, n, status,
+                               HFP_STATE_MNGR_ERR_NONE);
+}
+
+void _bt_hfp_get_equipment_identity_req(void *t_device)
+{
+       _bt_ag_agent_get_imei_number(t_device);
+}
+
+void _bt_hfp_get_model_info_reply(char *model,  void *t_device)
+{
+       _bt_hfp_get_model_info_rsp(t_device, model,
+                                       HFP_STATE_MNGR_ERR_NONE);
+}
+
+void _bt_hfp_get_model_info_req(void *t_device)
+{
+       _bt_ag_agent_get_model_name(t_device);
+}
+
+void _bt_hfp_get_device_manufacturer_reply(char *manufacturer,  void *t_device)
+{
+       _bt_hfp_get_device_manufacturer_rsp(t_device, manufacturer,
+                                       HFP_STATE_MNGR_ERR_NONE);
+}
+
+void _bt_hfp_get_device_manufacturer_req(void *t_device)
+{
+       _bt_ag_agent_get_manufacturer_name(t_device);
+}
+
+void _bt_hfp_get_imsi_req(void *t_device)
+{
+       _bt_ag_agent_get_imsi(t_device);
+}
+
+void _bt_hfp_get_creg_status_req(void *t_device)
+{
+       _bt_ag_agent_get_creg_status(t_device);
+}
+
+void _bt_hfp_get_revision_info_reply(char *revision,  void *t_device)
+{
+       _bt_hfp_get_revision_info_rsp(t_device, revision,
+                                       HFP_STATE_MNGR_ERR_NONE);
+}
+
+void _bt_hfp_get_revision_info_req(void *t_device)
+{
+       _bt_ag_agent_get_revision_information(t_device);
+}
+
diff --git a/ag-agent/org.bluez.ag_agent.service b/ag-agent/org.bluez.ag_agent.service
new file mode 100644 (file)
index 0000000..5cd68b3
--- /dev/null
@@ -0,0 +1,5 @@
+[D-BUS Service]
+Name=org.bluez.ag_agent
+Exec=/usr/bin/bluetooth-ag-agent
+User=system
+Group=system
diff --git a/ag-agent/voice-recognition-blacklist b/ag-agent/voice-recognition-blacklist
new file mode 100644 (file)
index 0000000..d00eb10
--- /dev/null
@@ -0,0 +1 @@
+AddressBlacklist=00:1B:52,0C:D9:C1,00:1E:AE,38:C0:96,BC:6A:29,64:D4:BD,30:14:4A,00:0E:9F,00:17:CA,00:26:7E,00:0B:24,00:24:0B,08:76:95,00:05:C9
diff --git a/hf-agent/CMakeLists.txt b/hf-agent/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5edad40
--- /dev/null
@@ -0,0 +1,25 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(bluetooth-hf-agent C)
+
+SET(SRCS bluetooth-hf-agent.c)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs_hf_agent
+               REQUIRED
+               dlog aul bluetooth-api alarm-service capi-appfw-app-manager
+               glib-2.0 gio-2.0 gio-unix-2.0 capi-system-device vconf)
+
+FOREACH(flag ${pkgs_hf_agent_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_hf_agent_LDFLAGS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.bluez.hf_agent.service
+               DESTINATION share/dbus-1/system-services)
diff --git a/hf-agent/bluetooth-hf-agent.c b/hf-agent/bluetooth-hf-agent.c
new file mode 100644 (file)
index 0000000..9ea77b9
--- /dev/null
@@ -0,0 +1,3370 @@
+/*
+ * Bluetooth-hf-agent
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:    Hocheol Seo <hocheol.seo@samsung.com>
+ *             Chethan T N <chethan.tn@samsung.com>
+ *             Chanyeol Park <chanyeol.park@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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <glib.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <sys/socket.h>
+#include <sys/poll.h>
+#include <aul.h>
+#include <gio/gio.h>
+#include <gio/gunixfdlist.h>
+#include <device/power.h>
+#include <app_manager.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+#include <bundle_internal.h>
+
+#include "bluetooth-hf-agent.h"
+
+#define BT_AGENT_SYSPOPUP_MAX_ATTEMPT 3
+#define CALL_APP_ID "org.tizen.call-ui"
+
+#define MAX_WAITING_DELAY 8
+#define READ_TX_POWER_MIN -30
+
+#define BT_ADDRESS_STRING_SIZE 18
+#define BT_AT_COMMAND_BUFFER_MAX 4000
+#define BT_HF_ERROR_RESP "\r\nERROR\r\n"
+#define BT_HF_COMMAND_TIMEOUT 3
+
+#define ret_if(expr) \
+       do { \
+               if (expr) { \
+                       ERR("(%s) return", #expr); \
+                       return; \
+               } \
+       } while (0)
+
+static GMainLoop *gmain_loop = NULL;
+static char *g_obj_path;
+
+static GDBusConnection *gdbus_conn;
+static GDBusProxy *service_gproxy;
+static int owner_sig_id = -1;
+int g_id = 0;
+uint16_t hf_ver;
+
+#define HFP_HF_UUID "0000111e-0000-1000-8000-00805f9b34fb"
+#define DEFAULT_ADAPTER_OBJECT_PATH "/org/bluez/hci0"
+
+/*Below Inrospection data is exposed to bluez from agent*/
+static const gchar hf_agent_bluez_introspection_xml[] =
+"<node name='/'>"
+"      <interface name='org.bluez.Profile1'>"
+"              <method name='NewConnection'>"
+"                      <arg type='o' name='device' direction='in'/>"
+"                      <arg type='h' name='fd' direction='in'/>"
+"                      <arg type='a{sv}' name='options' direction='in'/>"
+"              </method>"
+"              <method name='RequestDisconnection'>"
+"                      <arg type='o' name='device' direction='in'/>"
+"              </method>"
+"      </interface>"
+"</node>";
+
+/*Below Inrospection data is exposed to application from agent*/
+static const gchar hf_agent_introspection_xml[] =
+"<node name='/'>"
+" <interface name='org.tizen.HfApp'>"
+"              <method name='AnswerCall'>"
+"               </method>"
+"               <method name='TerminateCall'>"
+"               </method>"
+"               <method name='InitiateCall'>"
+"                       <arg type='s' name='phoneno' direction='in'/>"
+"               </method>"
+"               <method name='VoiceRecognition'>"
+"                       <arg type='i' name='status' direction='in'/>"
+"               </method>"
+"               <method name='ScoDisconnect'>"
+"               </method>"
+"               <method name='SpeakerGain'>"
+"                       <arg type='u' name='gain' direction='in'/>"
+"               </method>"
+"               <method name='SendDtmf'>"
+"                       <arg type='s' name='dtmf' direction='in'/>"
+"               </method>"
+"               <method name='SendAtCmd'>"
+"                       <arg type='s' name='atcmd' direction='in'/>"
+"               </method>"
+"               <method name='ReleaseAndAccept'>"
+"               </method>"
+"               <method name='CallSwap'>"
+"               </method>"
+"               <method name='ReleaseAllCall'>"
+"               </method>"
+"               <method name='JoinCall'>"
+"               </method>"
+"               <method name='GetCurrentCodec'>"
+"                      <arg type='i' name='codec' direction='out'/>"
+"               </method>"
+"               <method name='RequestCallList'>"
+"                      <arg type='i' name='count' direction='out'/>"
+"                      <arg type='a(siiii)' name='callList' direction='out'/>"
+"               </method>"
+"               <method name='GetAudioConnected'>"
+"                      <arg type='i' name='status' direction='out'/>"
+"               </method>"
+"               <method name='IsHfConnected'>"
+"                      <arg type='b' name='status' direction='out'/>"
+"               </method>"
+" </interface>"
+"</node>";
+
+static bt_hf_agent_info_t bt_hf_info;
+static gboolean is_hf_connected = FALSE;
+static int32_t current_codec_id = BT_HF_CODEC_ID_CVSD;
+static int32_t sco_audio_connected = BT_HF_AUDIO_DISCONNECTED;
+
+static char global_buff[BT_AT_COMMAND_BUFFER_MAX] = {0,};
+int send_flag;
+
+static char prev_cmd[BT_HF_CMD_BUF_SIZE];
+
+typedef struct {
+       int idx;
+       int dir;
+       int status;
+       int mode;
+       int multi_party;
+       int type;
+       char *number;
+} hf_call_list_info_t;
+
+static GError *__bt_hf_agent_set_error(bt_hf_agent_error_t error);
+
+static gboolean __bt_hf_agent_emit_property_changed(
+                               GDBusConnection *connection,
+                               const char *path,
+                               const char *interface,
+                               const char *name,
+                               GVariant *property);
+
+static gboolean __bt_hf_agent_data_cb(GIOChannel *chan, GIOCondition cond,
+                                       bt_hf_agent_info_t *bt_hf_info);
+static void __bt_hf_agent_stop_watch(bt_hf_agent_info_t *bt_hf_info);
+static void __bt_hf_agent_start_watch(bt_hf_agent_info_t *bt_hf_info);
+static gboolean __bt_hf_channel_write(GIOChannel *io, gchar *data,
+                                       gsize count);
+static gboolean __bt_hf_send_only_without_queue(bt_hf_agent_info_t *bt_hf_info,
+                                               gchar *data, gsize count);
+
+static gboolean __bt_hf_send_only(bt_hf_agent_info_t *bt_hf_info, gchar *data,
+                                       gsize count);
+static gboolean __bt_hf_send_and_read(bt_hf_agent_info_t *bt_hf_info,
+                               gchar *data, gchar *response, gsize count);
+static GSList *__bt_hf_parse_indicator_names(gchar *names, GSList *indies);
+static GSList *__bt_hf_parse_indicator_values(gchar *values, GSList *indies);
+static guint __bt_hf_get_hold_mpty_features(gchar *features);
+static gboolean __bt_establish_service_level_conn(bt_hf_agent_info_t *bt_hf_info);
+static void __bt_hf_agent_sigterm_handler(int signo);
+static gboolean __bt_hf_agent_release(void);
+
+static gboolean __bt_get_current_indicators(bt_hf_agent_info_t *bt_hf_info);
+static gboolean __bt_get_supported_indicators(bt_hf_agent_info_t *bt_hf_info);
+static gboolean __bt_hf_agent_connection(gint32 fd, const gchar * object_path);
+static gboolean __bt_hf_agent_connection_release(void);
+
+struct indicator {
+       gchar descr[BT_HF_INDICATOR_DESCR_SIZE];
+       gint value;
+};
+
+static int _hf_agent_answer_call(GDBusMethodInvocation *context);
+
+static int _hf_agent_terminate_call(GDBusMethodInvocation *context);
+
+static int _hf_agent_dial_no(GDBusMethodInvocation *context, char *no);
+
+static int _hf_agent_set_speaker_gain(GDBusMethodInvocation *context,
+                                                       unsigned int gain);
+
+static int _hf_agent_send_3way_cmd(GDBusMethodInvocation *context, char *cmd);
+
+static int _hf_agent_voice_recognition(GDBusMethodInvocation *context,
+                                                       unsigned int status);
+
+static gboolean bt_hf_agent_sco_disconnect(void);
+
+static int _hf_agent_send_dtmf(GDBusMethodInvocation *context, char *dtmf);
+
+static GVariant *bt_hf_agent_request_call_list(void);
+
+static int bt_hf_agent_send_at_cmd(GDBusMethodInvocation *context, char *atcmd);
+
+static int hf_handle_rx_at_cmd(bt_hf_agent_info_t *bt_hf_info, const char *buf);
+static GQuark __bt_hf_agent_error_quark(void)
+{
+       DBG("");
+
+       static GQuark quark = 0;
+       if (!quark)
+               quark = g_quark_from_static_string("hf-agent");
+
+       return quark;
+}
+
+static GError *__bt_hf_agent_set_error(bt_hf_agent_error_t error)
+{
+       ERR("error[%d]", error);
+
+       switch (error) {
+       case BT_HF_AGENT_ERROR_NOT_AVAILABLE:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_NOT_AVAILABLE);
+       case BT_HF_AGENT_ERROR_NOT_CONNECTED:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_NOT_CONNECTED);
+       case BT_HF_AGENT_ERROR_CONNECTION_FAILED:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_NOT_CONNECTION_FAILED);
+       case BT_HF_AGENT_ERROR_BUSY:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_BUSY);
+       case BT_HF_AGENT_ERROR_INVALID_PARAM:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_INVALID_PARAM);
+       case BT_HF_AGENT_ERROR_ALREADY_EXIST:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_ALREADY_EXIST);
+       case BT_HF_AGENT_ERROR_ALREADY_CONNECTED:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_ALREADY_CONNECTED);
+       case BT_HF_AGENT_ERROR_NO_MEMORY:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_NO_MEMORY);
+       case BT_HF_AGENT_ERROR_I_O_ERROR:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_I_O_ERROR);
+       case BT_HF_AGENT_ERROR_APPLICATION:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_OPERATION_NOT_AVAILABLE);
+       case BT_HF_AGENT_ERROR_NOT_ALLOWED:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_OPERATION_NOT_ALLOWED);
+       case BT_HF_AGENT_ERROR_NOT_SUPPORTED:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_OPERATION_NOT_SUPPORTED);
+       case BT_HF_AGENT_ERROR_INVALID_FILE_DESCRIPTOR:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_INVALID_FILE_DESCRIPTOR);
+       case BT_HF_AGENT_ERROR_INTERNAL:
+       default:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                               BT_ERROR_INTERNAL);
+       }
+}
+
+static void __bt_hf_lock_display(int timeout)
+{
+       int ret;
+
+       ret = device_power_request_lock(POWER_LOCK_DISPLAY, timeout);
+       if (ret >= 0)
+               DBG("Lock PM state as current state!");
+       else
+               ERR("deviced error!");
+}
+
+static void __bt_hf_unlock_display()
+{
+       int ret;
+
+       ret = device_power_release_lock(POWER_LOCK_DISPLAY);
+       if (ret >= 0)
+               DBG("UnLock PM state");
+       else
+               ERR("deviced error!");
+}
+
+static void __hf_agent_method(GDBusConnection *connection,
+                           const gchar *sender,
+                           const gchar *object_path,
+                           const gchar *interface_name,
+                           const gchar *method_name,
+                           GVariant *parameters,
+                           GDBusMethodInvocation *context,
+                           gpointer user_data)
+{
+       DBG("+");
+
+       INFO("method %s", method_name);
+       int ret = 0;
+       GError *err;
+
+       if (g_strcmp0(method_name, "NewConnection") == 0) {
+               gint32 fd;
+               int index;
+               GDBusMessage *msg;
+               GUnixFDList *fd_list;
+               const gchar *object_path;
+               GVariant *options;
+
+               g_variant_get(parameters, "(oha{sv})",
+                       &object_path, &index, &options);
+
+               msg = g_dbus_method_invocation_get_message(context);
+               fd_list = g_dbus_message_get_unix_fd_list(msg);
+               if (fd_list == NULL) {
+                       ret = BT_HF_AGENT_ERROR_INVALID_FILE_DESCRIPTOR;
+                       goto fail;
+               }
+
+               fd = g_unix_fd_list_get(fd_list, index, NULL);
+               if (fd == -1) {
+                       ret = BT_HF_AGENT_ERROR_INVALID_FILE_DESCRIPTOR;
+                       goto fail;
+               }
+
+               DBG("FD is = [%d], Object path = [%s]", fd, object_path);
+
+               if (!__bt_hf_agent_connection(fd, object_path)) {
+                       ret = BT_HF_AGENT_ERROR_INTERNAL;
+                       goto fail;
+               }
+
+               g_dbus_method_invocation_return_value(context, NULL);
+       } else if (g_strcmp0(method_name, "RequestDisconnection") == 0) {
+               if (!__bt_hf_agent_connection_release()) {
+                       ret = BT_HF_AGENT_ERROR_INTERNAL;
+                       goto fail;
+               }
+               INFO_C("Disconnected [HF role] [Terminated by local host]");
+               g_dbus_method_invocation_return_value(context, NULL);
+       } else if (g_strcmp0(method_name, "Release") == 0) {
+               if (!__bt_hf_agent_connection_release()) {
+                       ret = BT_HF_AGENT_ERROR_INTERNAL;
+                       goto fail;
+               }
+
+               g_dbus_method_invocation_return_value(context, NULL);
+       } else if (g_strcmp0(method_name, "AnswerCall") == 0) {
+               DBG("Going to call AnswerCall");
+               ret = _hf_agent_answer_call(context);
+               if (ret)
+                       goto fail;
+
+       } else if (g_strcmp0(method_name, "TerminateCall") == 0) {
+               DBG("Going to call TerminateCall");
+               ret = _hf_agent_terminate_call(context);
+               if (ret)
+                       goto fail;
+
+       } else if (g_strcmp0(method_name, "InitiateCall") == 0) {
+               char *phoneno = NULL;
+
+               g_variant_get(parameters, "(&s)", &phoneno);
+
+               DBG_SECURE("Going to call InitiateCall, Number is = [%s]\n", phoneno);
+               ret = _hf_agent_dial_no(NULL, phoneno);
+               if (ret)
+                       goto fail;
+
+               g_dbus_method_invocation_return_value(context, NULL);
+
+       } else if (g_strcmp0(method_name, "VoiceRecognition") == 0) {
+               int status = 0;
+
+               g_variant_get(parameters, "(i)", &status);
+
+               DBG("Going to call VoiceRecognition, Status [%d]", status);
+               ret = _hf_agent_voice_recognition(context, status);
+               if (ret)
+                       goto fail;
+
+       } else if (g_strcmp0(method_name, "ScoDisconnect") == 0) {
+               DBG("Going to call ScoDisconnect");
+               if (!bt_hf_agent_sco_disconnect()) {
+                       ret = BT_HF_AGENT_ERROR_INTERNAL;
+                       goto fail;
+               }
+
+               g_dbus_method_invocation_return_value(context, NULL);
+       } else if (g_strcmp0(method_name, "SpeakerGain") == 0) {
+               unsigned int gain = 0;
+
+               g_variant_get(parameters, "(u)", &gain);
+
+               DBG("Going to call SpeakerGain, gain is = [%d]\n", gain);
+               ret = _hf_agent_set_speaker_gain(context, gain);
+               if (ret)
+                       goto fail;
+
+       } else if (g_strcmp0(method_name, "SendDtmf") == 0) {
+               char *dtmf = NULL;
+
+               g_variant_get(parameters, "(&s)", &dtmf);
+
+               DBG("Going to call SendDtmf, dtmf is = [%s]\n", dtmf);
+               ret = _hf_agent_send_dtmf(NULL, dtmf);
+               if (ret)
+                       goto fail;
+               g_dbus_method_invocation_return_value(context, NULL);
+
+       } else if (g_strcmp0(method_name, "SendAtCmd") == 0) {
+               char *cmd = NULL;
+
+               g_variant_get(parameters, "(&s)", &cmd);
+
+               DBG("Going to call SendAtCmd, cmd is = [%s]\n", cmd);
+               ret = bt_hf_agent_send_at_cmd(context, cmd);
+               if (ret)
+                       goto fail;
+
+       } else if (g_strcmp0(method_name, "ReleaseAndAccept") == 0) {
+               DBG("Going to call ReleaseAndAccept");
+               ret = _hf_agent_send_3way_cmd(context,
+                                               BT_HF_RELEASE_AND_ACCEPT);
+               if (ret)
+                       goto fail;
+
+       } else if (g_strcmp0(method_name, "CallSwap") == 0) {
+               DBG("Going to call CallSwap");
+               ret = _hf_agent_send_3way_cmd(context,
+                                                       BT_HF_ACCEPT_AND_HOLD);
+               if (ret)
+                       goto fail;
+
+       } else if (g_strcmp0(method_name, "ReleaseAllCall") == 0) {
+               DBG("Going to call ReleaseAllCall");
+               ret = _hf_agent_send_3way_cmd(context, BT_HF_RELEASE_ALL);
+               if (ret)
+                       goto fail;
+
+       } else if (g_strcmp0(method_name, "JoinCall") == 0) {
+               DBG("Going to call JoinCall");
+               ret = _hf_agent_send_3way_cmd(context, BT_HF_JOIN_CALL);
+               if (ret)
+                       goto fail;
+
+       } else if (g_strcmp0(method_name, "GetCurrentCodec") == 0) {
+               DBG("Going to call GetCurrentCodec");
+               INFO("Current codec : %d", current_codec_id);
+               g_dbus_method_invocation_return_value(context,
+                               g_variant_new("(i)", current_codec_id));
+       } else if (g_strcmp0(method_name, "RequestCallList") == 0) {
+               GVariant *call_var;
+
+               DBG("Going to call RequestCallList");
+               call_var = bt_hf_agent_request_call_list();
+               if (!call_var) {
+                       ret = BT_HF_AGENT_ERROR_NOT_AVAILABLE;
+                       goto fail;
+               }
+               g_dbus_method_invocation_return_value(context, call_var);
+       } else if (g_strcmp0(method_name, "GetAudioConnected") == 0) {
+               DBG("Going to call GetAudioConnected");
+               g_dbus_method_invocation_return_value(context,
+                               g_variant_new("(i)", sco_audio_connected));
+       } else if (g_strcmp0(method_name, "IsHfConnected") == 0) {
+               DBG("Going to call IsHfConnected");
+               INFO("is_hf_connected : %s", is_hf_connected ? "Connected":"Disconnected");
+
+               g_dbus_method_invocation_return_value(context,
+                               g_variant_new("(b)", is_hf_connected));
+       }
+       INFO("-");
+       return;
+
+fail:
+       err = __bt_hf_agent_set_error(ret);
+       g_dbus_method_invocation_return_gerror(context, err);
+       g_error_free(err);
+       INFO("-");
+}
+
+static const GDBusInterfaceVTable method_table = {
+       __hf_agent_method,
+       NULL,
+       NULL,
+};
+
+static GDBusNodeInfo *__bt_hf_create_method_node_info
+                                       (const gchar *introspection_data)
+{
+       if (introspection_data == NULL)
+               return NULL;
+
+       return g_dbus_node_info_new_for_xml(introspection_data, NULL);
+}
+
+static GDBusConnection *__bt_hf_get_gdbus_connection(void)
+{
+       GDBusConnection *local_system_gconn = NULL;
+       GError *err = NULL;
+
+       if (gdbus_conn == NULL) {
+               gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+               if (!gdbus_conn) {
+                       if (err) {
+                               ERR("Unable to connect to dbus: %s", err->message);
+                               g_clear_error(&err);
+                       }
+                       gdbus_conn = NULL;
+               }
+       } else if (g_dbus_connection_is_closed(gdbus_conn)) {
+               local_system_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+
+               if (!local_system_gconn) {
+                       ERR("Unable to connect to dbus: %s", err->message);
+                       g_clear_error(&err);
+               }
+
+               gdbus_conn = local_system_gconn;
+       }
+
+       return gdbus_conn;
+}
+
+static gboolean __bt_hf_register_profile_methods(void)
+{
+       DBG("+");
+       GError *error = NULL;
+       guint object_id;
+       guint owner_id;
+       GDBusNodeInfo *node_info;
+       gchar *path;
+       GDBusConnection *conn;
+
+       owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
+                               BT_HF_SERVICE_NAME,
+                               G_BUS_NAME_OWNER_FLAGS_NONE,
+                               NULL, NULL, NULL,
+                               NULL, NULL);
+
+       DBG("owner_id is [%d]", owner_id);
+
+       node_info = __bt_hf_create_method_node_info(
+                               hf_agent_bluez_introspection_xml);
+       if (node_info == NULL)
+               return FALSE;
+
+       path = g_strdup(BT_HF_BLUEZ_OBJECT_PATH);
+       DBG("path is [%s]", path);
+
+       conn = __bt_hf_get_gdbus_connection();
+       if (!conn) {
+               ERR("Unable to get connection");
+               return FALSE;
+       }
+
+       object_id = g_dbus_connection_register_object(conn, path,
+                                       node_info->interfaces[0],
+                                       &method_table,
+                                       NULL, NULL, &error);
+       if (object_id == 0) {
+               ERR("Failed to register: %s", error->message);
+               g_error_free(error);
+               g_dbus_node_info_unref(node_info);
+               g_free(path);
+               return FALSE;
+       }
+       g_free(path);
+       g_dbus_node_info_unref(node_info);
+
+       node_info = __bt_hf_create_method_node_info(hf_agent_introspection_xml);
+       if (node_info == NULL)
+               return FALSE;
+
+       path = g_strdup(BT_HF_AGENT_OBJECT_PATH);
+       DBG("path is [%s]", path);
+
+       object_id = g_dbus_connection_register_object(conn, path,
+                                               node_info->interfaces[0],
+                                               &method_table,
+                                               NULL, NULL, &error);
+       if (object_id == 0) {
+               ERR("Failed to register: %s", error->message);
+               g_error_free(error);
+               g_dbus_node_info_unref(node_info);
+               g_free(path);
+               return FALSE;
+       }
+       g_free(path);
+       g_dbus_node_info_unref(node_info);
+
+       DBG("-");
+       return TRUE;
+}
+
+static GDBusProxy *__bt_hf_gdbus_init_service_proxy(const gchar *service,
+                               const gchar *path, const gchar *interface)
+{
+       DBG("+");
+
+       GDBusProxy *proxy;
+       GError *err = NULL;
+       GDBusConnection *conn;
+
+       conn = __bt_hf_get_gdbus_connection();
+       if (!conn) {
+               ERR("Unable to get connection");
+               return NULL;
+       }
+
+       proxy =  g_dbus_proxy_new_sync(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;
+       }
+
+       DBG("-");
+       return proxy;
+}
+
+static GDBusProxy *__bt_hf_gdbus_get_service_proxy(const gchar *service,
+                               const gchar *path, const gchar *interface)
+{
+       return (service_gproxy) ? service_gproxy :
+                       __bt_hf_gdbus_init_service_proxy(service,
+                                       path, interface);
+}
+
+static char __bt_hf_agent_get_tx_power(char *address)
+{
+       GVariant *ret;
+       GDBusProxy *proxy;
+       GError *error = NULL;
+       char result = READ_TX_POWER_MIN; /* default minimum */
+
+       proxy = __bt_hf_gdbus_get_service_proxy(BLUEZ_SERVICE_NAME, g_obj_path,
+                                               BLUEZ_HF_INTERFACE_NAME);
+       if (!proxy) {
+               ERR("Proxy is NULL");
+               return result;
+       }
+
+       ret = g_dbus_proxy_call_sync(proxy,
+                               "GetTxPowerLevel", g_variant_new("(s)", address),
+                               G_DBUS_CALL_FLAGS_NONE, -1,
+                               NULL, &error);
+       if (ret == NULL) {
+               ERR("DBus is failed");
+               if (error != NULL) {
+                       /* Dbus gives error cause */
+                       ERR("D-Bus API failure: errCode[%x], message[%s]",
+                                               error->code, error->message);
+                       g_clear_error(&error);
+               }
+               return result;
+       }
+       g_variant_get(ret, "(y)", &result);
+       DBG("TX power level = %d", result);
+       g_variant_unref(ret);
+       return result;
+}
+
+static int __bt_hf_agent_gdbus_method_send(const char *service,
+                               GVariant *path, const char *interface,
+                               const char *method)
+{
+       DBG("+");
+
+       GVariant *ret;
+       GDBusProxy *proxy;
+       GError *error = NULL;
+
+       proxy = __bt_hf_gdbus_get_service_proxy(service, g_obj_path, interface);
+       if (!proxy)
+               return BT_HF_AGENT_ERROR_INTERNAL;
+
+       ret = g_dbus_proxy_call_sync(proxy,
+                               method, path,
+                               G_DBUS_CALL_FLAGS_NONE, -1,
+                               NULL, &error);
+       if (ret == NULL) {
+               /* dBUS-RPC is failed */
+               ERR("dBUS-RPC is failed");
+               if (error != NULL) {
+                       /* dBUS gives error cause */
+                       ERR("D-Bus API failure: errCode[%x], message[%s]",
+                              error->code, error->message);
+
+                       g_clear_error(&error);
+               }
+               return BT_HF_AGENT_ERROR_INTERNAL;
+       }
+
+       g_variant_unref(ret);
+
+       return BT_HF_AGENT_ERROR_NONE;
+}
+
+static void  __bt_hf_agent_release_queue(void)
+{
+       int i, len;
+       bt_hf_agent_send_at_info *cmd;
+       GError *err;
+
+       len = g_slist_length(bt_hf_info.cmd_send_queue);
+       for (i = 0; i < len; ++i) {
+               cmd = g_slist_nth_data(bt_hf_info.cmd_send_queue, i);
+               if (cmd && cmd->context) {
+                       DBG("Pending context found for %.6s[%d]",
+                                                       cmd->at_cmd, cmd->id);
+                       err = __bt_hf_agent_set_error(BT_HF_AGENT_ERROR_INTERNAL);
+                       g_dbus_method_invocation_return_gerror(cmd->context, err);
+                       g_error_free(err);
+               }
+               if (cmd && cmd->timer_id)
+                       g_source_remove(cmd->timer_id);
+       }
+       g_slist_free(bt_hf_info.cmd_send_queue);
+       bt_hf_info.cmd_send_queue = NULL;
+       send_flag = 0;
+}
+
+static gboolean __bt_hf_monitor_timer_cb(gpointer data)
+{
+       DBG("+");
+       bt_hf_agent_send_at_info *cmd = data;
+       ERR_C("Monitor timer came becuase of timeout for sendflag %d, %s",
+                                               send_flag, cmd->at_cmd);
+       /* In the case of ATD, we have to inform the remote to end the call */
+       if (strstr(cmd->at_cmd, "ATD") || strstr(cmd->at_cmd, "BLDN")) {
+               INFO_C("Sending CHUP for remote call termination");
+               __bt_hf_send_only_without_queue(&bt_hf_info, BT_HF_END_CALL,
+                                                        strlen(BT_HF_END_CALL));
+               /* Here there is a high posisbility that we do not get response
+                * for CHUP. Hence we need to decrement send_flag to process further
+                * incomming packets because we already incremented it in the CHUP case. */
+                if (send_flag)
+                       send_flag--;
+
+               /* In the case of ATD, prev_cmd will be always ATD, because we will not
+                * allow further commands. For safer side again set prev_cmd as ATD */
+               strcpy(prev_cmd, "ATD");
+       }
+       hf_handle_rx_at_cmd(&bt_hf_info, BT_HF_ERROR_RESP);
+
+       DBG("-");
+
+       return FALSE;
+}
+
+
+gboolean __bt_hf_agent_add_queue(GDBusMethodInvocation *context, char *at,
+                                       int count, gboolean pending_flag)
+{
+       int i, len;
+       if (bt_hf_info.slc == FALSE)
+               return FALSE;
+
+       if (pending_flag)
+               DBG("*** Add Pending queue request for = %s **** ", at);
+       else
+                DBG("Add Pending queue respnse for = %s ", at);
+
+       bt_hf_agent_send_at_info *cmd = g_new0(bt_hf_agent_send_at_info, 1);
+       cmd->id = ++g_id;
+       memcpy(cmd->at_cmd, at, count);
+       cmd->count = count;
+       cmd->context =  context;
+       cmd->pending = pending_flag;
+       bt_hf_info.cmd_send_queue = g_slist_append(bt_hf_info.cmd_send_queue,
+                                                                       cmd);
+       len = g_slist_length(bt_hf_info.cmd_send_queue);
+       for (i = 0; i < len; ++i) {
+               cmd = g_slist_nth_data(bt_hf_info.cmd_send_queue, i);
+               DBG("Q> %.6s[%d]", cmd->at_cmd, cmd->id);
+       }
+
+       /* We need to have base timeout + tolerance value to process other request */
+       if (strstr(at, "ATD") || strstr(at, "BLDN")) {
+               /* Android 15 seconds timeout in case of ATD timeout in flight mode */
+               cmd->timer_id = g_timeout_add_seconds(BT_HF_COMMAND_TIMEOUT * 5 + len,
+                                        __bt_hf_monitor_timer_cb, cmd);
+       } else {
+               cmd->timer_id = g_timeout_add_seconds(BT_HF_COMMAND_TIMEOUT + len,
+                                        __bt_hf_monitor_timer_cb, cmd);
+       }
+       return TRUE;
+}
+
+/*
+Below methods exposed to Applicatoins
+*/
+static gboolean __bt_hf_agent_emit_signal(GDBusConnection *connection,
+                               const char *path, const char *interface,
+                               const char *signal_name, GVariant *param)
+{
+       GError *error = NULL;
+       gboolean ret;
+       ret =  g_dbus_connection_emit_signal(connection,
+                                NULL, path,
+                                interface, signal_name,
+                                param, &error);
+       if (!ret) {
+               if (error != NULL) {
+                       /* dBUS gives error cause */
+                       ERR("D-Bus API failure: errCode[%x], message[%s]",
+                              error->code, error->message);
+                       g_clear_error(&error);
+               }
+       }
+       INFO_C("Emit Signal [%s]", signal_name);
+
+       return ret;
+}
+
+static gboolean __bt_hf_agent_emit_property_changed(
+                               GDBusConnection *connection,
+                               const char *path,
+                               const char *interface,
+                               const char *name,
+                               GVariant *property)
+{
+       DBG("+");
+
+       GError *error = NULL;
+       gboolean ret;
+       ret =  g_dbus_connection_emit_signal(connection,
+                               NULL, path, interface,
+                               "PropertyChanged",
+                               g_variant_new("s(v)", name, property),
+                               &error);
+       if (!ret) {
+               if (error != NULL) {
+                       /* dBUS gives error cause */
+                       ERR("D-Bus API failure: errCode[%x], message[%s]",
+                              error->code, error->message);
+                       g_clear_error(&error);
+               }
+       }
+       DBG("-");
+       return ret;
+}
+
+/*
+Below methods exposed to Bluez
+*/
+
+static void __bt_hf_agent_handle_ind_change(bt_hf_agent_info_t *bt_hf_info,
+                                                       guint index, gint value)
+{
+       GDBusConnection *conn;
+       gchar *name;
+       struct indicator *ind = g_slist_nth_data(bt_hf_info->indies, index - 1);
+       if (ind == NULL) {
+               ERR("Indicator is NULL");
+               return;
+       }
+
+       name = ind->descr;
+       ind->value = value;
+
+       conn = __bt_hf_get_gdbus_connection();
+       if (!conn) {
+               ERR("Unable to get connection");
+               return;
+       }
+
+       INFO("Indicator name is %s, value = [%d]", name, value);
+       if (!strcmp(name, "\"call\"")) {
+               bt_hf_info->ciev_call_status = value;
+               if (value > 0) {
+                       __bt_hf_agent_emit_signal(conn,
+                                       BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE,
+                                       "CallStarted", NULL);
+                       bt_hf_info->is_dialing = FALSE;
+                       bt_hf_info->call_active = TRUE;
+               } else if (bt_hf_info->call_active) {
+                       __bt_hf_agent_emit_signal(conn,
+                                       BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE,
+                                       "CallEnded", NULL);
+                       bt_hf_info->call_active = FALSE;
+               }
+
+       } else if (!strcmp(name, "\"callsetup\"")) {
+               bt_hf_info->ciev_call_setup_status = value;
+               if (value == 0 && bt_hf_info->is_dialing) {
+                       __bt_hf_agent_emit_signal(conn,
+                                       BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE,
+                                       "CallTerminated",
+                                       NULL);
+                       bt_hf_info->is_dialing = FALSE;
+               } else if (!bt_hf_info->is_dialing && value > 0)
+                       bt_hf_info->is_dialing = TRUE;
+
+               if (bt_hf_info->ciev_call_status == 0 &&
+                                               bt_hf_info->ciev_call_setup_status == 0)
+                       __bt_hf_agent_emit_signal(gdbus_conn,
+                                       BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE,
+                                       "CallEnded", NULL);
+
+       } else if (!strcmp(name, "\"callheld\"")) {
+               if (value == 0) { /* No calls held*/
+                       __bt_hf_agent_emit_signal(conn,
+                                       BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE,
+                                       "NoCallsHeld",
+                                       NULL);
+               } else if (value == 1) {
+                       /*Call is placed on hold or active/held calls swapped */
+                       __bt_hf_agent_emit_signal(conn,
+                                       BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE,
+                                       "CallsSwapped", NULL);
+                       bt_hf_info->is_dialing = FALSE;
+               } else {
+                       /*Call on hold, no active call*/
+                       __bt_hf_agent_emit_signal(conn,
+                                       BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE,
+                                       "CallOnHold", NULL);
+                       bt_hf_info->is_dialing = FALSE;
+               }
+       } else if (!strcmp(name, "\"service\""))
+               __bt_hf_agent_emit_property_changed(conn,
+                               BT_HF_AGENT_OBJECT_PATH,
+                               BT_HF_SERVICE_INTERFACE,
+                               "RegistrationStatus",
+                               g_variant_new("(q)", value));
+       else if (!strcmp(name, "\"signal\""))
+               __bt_hf_agent_emit_property_changed(conn,
+                               BT_HF_AGENT_OBJECT_PATH,
+                               BT_HF_SERVICE_INTERFACE, "SignalStrength",
+                               g_variant_new("(q)", value));
+       else if (!strcmp(name, "\"roam\""))
+               __bt_hf_agent_emit_property_changed(conn,
+                               BT_HF_AGENT_OBJECT_PATH,
+                               BT_HF_SERVICE_INTERFACE, "RoamingStatus",
+                               g_variant_new("(q)", value));
+       else if (!strcmp(name, "\"battchg\""))
+               __bt_hf_agent_emit_property_changed(conn,
+                               BT_HF_AGENT_OBJECT_PATH,
+                               BT_HF_SERVICE_INTERFACE, "BatteryCharge",
+                               g_variant_new("(q)", value));
+}
+
+
+static gboolean  __bt_hf_agent_launch_call_app(const char *launch_type,
+                                                       const char *number)
+{
+       bundle *b;
+       bool is_running;
+
+       DBG("+");
+       app_manager_is_running(CALL_APP_ID, &is_running);
+       if (is_running)
+               return FALSE;
+
+       DBG_SECURE("Launch type = %s, number(%s)", launch_type, number);
+
+       b = bundle_create();
+       if (NULL == b) {
+               ERR("bundle_create() Failed");
+               return FALSE;
+       }
+
+       bundle_add(b, "launch-type", launch_type);
+
+       if (strlen(number) != 0)
+               bundle_add(b, "number", number);
+
+       bundle_add(b, "carrier-type", "BT");
+       DBG("For 3G, carrier-type: BT has been added");
+
+       aul_launch_app(CALL_APP_ID, b);
+       bundle_free(b);
+
+       DBG("-");
+
+       return TRUE;
+}
+
+static void __bt_hf_agent_handle_voice_activation(gint value)
+{
+       GDBusConnection *conn;
+
+       conn = __bt_hf_get_gdbus_connection();
+               if (!conn) {
+               ERR("Unable to get connection");
+               return;
+       }
+
+       __bt_hf_agent_emit_signal(conn, BT_HF_AGENT_OBJECT_PATH,
+               BT_HF_SERVICE_INTERFACE,
+               "VoiceRecognition",
+               g_variant_new("(i)", value));
+
+       return;
+}
+
+static void __bt_hf_agent_handle_speaker_gain(gint value)
+{
+       GDBusConnection *conn;
+
+       conn = __bt_hf_get_gdbus_connection();
+       if (!conn) {
+               ERR("Unable to get connection");
+               return;
+       }
+
+       __bt_hf_agent_emit_signal(conn, BT_HF_AGENT_OBJECT_PATH,
+                               BT_HF_SERVICE_INTERFACE, "VolumeSpeaker",
+                               g_variant_new("(i)", value));
+
+       return;
+}
+
+static int __bt_hf_agent_handle_ccwa(bt_hf_agent_info_t *bt_hf_info,
+                                                       const gchar *buf)
+{
+       GDBusConnection *conn;
+       gchar *ccwa;
+       gchar number[BT_HF_CALLER_NUM_SIZE];
+       gchar *sep;
+       char fmt_str[BT_HF_FMT_STR_SIZE];
+       int len = strlen(buf);
+
+       DBG("__bt_hf_agent_handle_ccwa +");
+       if (len > BT_HF_CALLER_NUM_SIZE + 10) {
+               ERR("buf len %d is too long", len);
+               return 1;
+       }
+
+       if ((ccwa = strstr(buf, "\r\n+CCWA"))) {
+               snprintf(fmt_str, sizeof(fmt_str), "\r\n+CCWA: \"%%%ds", sizeof(number) - 1);
+               if (sscanf(ccwa, fmt_str, number) == 1) {
+                       sep = strchr(number, '"');
+                       sep[0] = '\0';
+
+                       ccwa = number;
+
+                       conn = __bt_hf_get_gdbus_connection();
+                       if (!conn) {
+                               ERR("Unable to get connection");
+                               return 1;
+                       }
+
+                       __bt_hf_agent_emit_signal(conn,
+                                       BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE, "CallWaiting",
+                                       g_variant_new("(s)", ccwa));
+               } else {
+                       ERR_SECURE("CCWA '%s' is Call Wating", buf);
+                       return 1;
+               }
+       }
+       DBG("__bt_hf_agent_handle_ccwa -");
+       return 0;
+}
+
+static GSList *__bt_hf_prepare_call_list(const char *buf) {
+       GSList *call_list = NULL;
+       char *str = NULL;
+       char *ptr = NULL;
+       char *temp = NULL;
+       char *sp;
+       char delim_sep[] = "\r\n";
+       char temp_buf[BT_HF_DATA_BUF_SIZE] = {0,};
+
+       hf_call_list_info_t *call_info;
+
+       DBG("+");
+       strncpy(temp_buf, buf, BT_HF_DATA_BUF_SIZE - 1);
+
+       str = strtok_r(temp_buf, delim_sep, &sp);
+       while (str != NULL) {
+               if (!(strstr(str, "+CLCC:"))) {
+                       str = strtok_r(NULL, delim_sep, &sp);
+                       continue;
+               }
+
+               call_info = g_new0(hf_call_list_info_t, 1);
+
+               sscanf(str, "+CLCC: %1d,%1d, %1d, %1d, %1d",
+                               &call_info->idx, &call_info->dir,
+                               &call_info->status, &call_info->mode,
+                               &call_info->multi_party);
+               DBG("Index = [%d], Direction = [%d], Status = [%d], Mode = [%d], Multi_party = [%d]\n",
+                               call_info->idx, call_info->dir, call_info->status,
+                               call_info->mode, call_info->multi_party);
+
+               ptr = strstr(str, "\"");
+               if (ptr) {
+                       temp = strstr(ptr + 1, "\"");
+                       if (temp) {
+                               *temp = '\0';
+                               DBG_SECURE("\tPhone Number = [%s]\n", ptr + 1);
+                               call_info->number = g_strdup(ptr + 1);
+
+                               if (strstr(temp + 1, ",")) {
+                                       temp += 2;
+                                       DBG("\tType = [%s]\n", temp);
+                                       call_info->type = atoi(temp);
+                               }
+                       }
+               } else {
+                       /*In case of no phone no. in CLCC respnse, we should launch call application
+                        * with NULL string. By doing so "unknown" shall be displayed*/
+                       DBG("Phone number does not exist\n");
+                       call_info->number = g_strdup("");
+               }
+
+               call_list = g_slist_append(call_list, call_info);
+               str = strtok_r(NULL, delim_sep, &sp);
+       }
+       DBG("-");
+       return call_list;
+}
+
+static GSList *__bt_hf_get_call_list(bt_hf_agent_info_t *bt_hf_info)
+{
+       char buf[BT_HF_DATA_BUF_SIZE] = {0,};
+       GSList *call_list = NULL;
+
+       DBG("+");
+
+       /* Send CLCC when the callsetup */
+       __bt_hf_send_and_read(bt_hf_info, BT_HF_CALLLIST, buf,
+                       sizeof(BT_HF_CALLLIST) - 1);
+       DBG_SECURE("Receive CLCC response buffer = '%s'", buf);
+
+       call_list =  __bt_hf_prepare_call_list(buf);
+       DBG("-");
+       return call_list;
+}
+
+static void __bt_hf_call_info_free(void *data)
+{
+       DBG("+");
+
+       hf_call_list_info_t *call_info = data;
+       g_free(call_info->number);
+       g_free(call_info);
+
+       DBG("-");
+}
+
+static void __bt_hf_free_call_list(GSList *call_list)
+{
+       DBG("+");
+
+       g_slist_free_full(call_list, __bt_hf_call_info_free);
+
+       DBG("-");
+}
+
+static void __bt_hf_launch_call_using_call_list(GSList *call_list,
+                                       bt_hf_agent_info_t *bt_hf_info)
+{
+       guint len;
+       const char *launch_type_str;
+       hf_call_list_info_t *call_info;
+
+       DBG("+");
+       if (call_list == NULL)
+               return;
+
+       len = g_slist_length(call_list);
+
+       while (len--) {
+               call_info = g_slist_nth_data(call_list, len);
+
+               /* Launch based on below conditions
+                 * DC - Active call which is initiated from H
+                 * MR - Alerting call which is initiated from H
+                 * MT - Incoming call */
+               if (call_info->status == BT_HF_CALL_STAT_ACTIVE) {
+                       launch_type_str =  "DC";
+               } else {
+                       if (call_info->dir == BT_HF_CALL_DIR_INCOMING)
+                               launch_type_str =  "MT";
+                       else
+                               launch_type_str =  "MR";
+               }
+
+               if (__bt_hf_agent_launch_call_app(launch_type_str,
+                                       call_info->number)  == FALSE)
+                       DBG("call app launching failed");
+       }
+       DBG("-");
+}
+
+static GVariant *__bt_hf_agent_get_call_status_info(GSList *call_list)
+{
+       DBG("+");
+
+       int32_t call_count;
+       gchar *caller;
+       hf_call_list_info_t *call_info;
+
+       GVariantBuilder *builder;
+       GVariant *var_data;
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a(siiii)"));
+
+       call_count = g_slist_length(call_list);
+       DBG("Total call count = '%d'", call_count);
+
+       while (call_count--) {
+               call_info = g_slist_nth_data(call_list, call_count);
+               INFO("Idx=%d, Dir=%d, status=%d, mode=%d, mparty=%d",
+               call_info->idx, call_info->dir, call_info->status,
+               call_info->mode, call_info->multi_party);
+               caller = call_info->number;
+
+               g_variant_builder_add(builder, "(siiii)",
+                               caller, call_info->dir, call_info->status,
+                               call_info->multi_party, call_info->idx);
+       }
+       var_data = g_variant_new("(ia(siiii))",
+                               g_slist_length(call_list), builder);
+
+       g_variant_builder_unref(builder);
+       DBG("-");
+       return  var_data;
+}
+
+static void __bt_hf_clear_prev_sent_cmd(void)
+{
+       if (prev_cmd[0] != 0)
+               ERR("No sent command");
+
+       memset(prev_cmd, 0, BT_HF_CMD_BUF_SIZE);
+
+       return;
+}
+
+static void __bt_hf_agent_send_call_status_info(GSList *call_list)
+{
+       GDBusConnection *conn;
+       GVariant *var_data;
+
+       var_data = __bt_hf_agent_get_call_status_info(call_list);
+       conn = __bt_hf_get_gdbus_connection();
+       if (!conn) {
+               ERR("Unable to get connection");
+               return;
+       }
+
+       if (conn)
+               __bt_hf_agent_emit_signal(conn,
+                               BT_HF_AGENT_OBJECT_PATH,
+                               BT_HF_SERVICE_INTERFACE,
+                               "CallStatusUpdate",
+                               var_data);
+}
+
+static void __bt_hf_agent_handle_call_list(bt_hf_agent_info_t *bt_hf_info)
+{
+       int ret;
+
+       __bt_hf_lock_display(0);
+
+       bt_hf_info->context = NULL;
+
+       /* Send CLCC. The response will be handled in the handler */
+       ret = __bt_hf_send_only(bt_hf_info, BT_HF_CALLLIST,
+                                               sizeof(BT_HF_CALLLIST) - 1);
+       if (!ret)
+               ERR("Failed to send CLCC");
+
+       __bt_hf_unlock_display();
+}
+
+static void __bt_hf_agent_request_call_list_info(bt_hf_agent_info_t *bt_hf_info,
+                                                               guint index)
+{
+       char *name;
+       struct indicator *ind = g_slist_nth_data(bt_hf_info->indies, index - 1);
+       if (ind == NULL) {
+               ERR("Indicator is NULL");
+               return;
+       }
+       name = ind->descr;
+       DBG("name : %s", name);
+
+       if ((strcmp(name, "\"callsetup\"") != 0) &&
+                       (strcmp(name, "\"call\"") != 0) &&
+                               (strcmp(name, "\"callheld\"") != 0))
+               return;
+
+       __bt_hf_lock_display(0);
+
+       __bt_hf_agent_handle_call_list(bt_hf_info);
+
+       __bt_hf_unlock_display();
+
+}
+
+static gboolean __bt_hf_send_available_codec(bt_hf_agent_info_t *bt_hf_info, int send_only)
+{
+       gchar buf[BT_HF_DATA_BUF_SIZE];
+       gchar cmd_buf[BT_HF_CMD_BUF_SIZE] = {0};
+       gboolean ret;
+
+       snprintf(cmd_buf, sizeof(cmd_buf), BT_HF_AVAILABLE_CODEC,
+                       BT_HF_CODEC_ID_CVSD, BT_HF_CODEC_ID_MSBC);
+       if (send_only) {
+               bt_hf_info->context = NULL;
+
+               ret = __bt_hf_send_only(bt_hf_info, cmd_buf, strlen(cmd_buf));
+               return TRUE;
+       } else {
+               ret = __bt_hf_send_and_read(bt_hf_info, cmd_buf, buf,
+                               strlen(cmd_buf));
+       }
+       if (!ret || !strstr(buf, "OK"))
+               return FALSE;
+
+       return TRUE;
+}
+
+static  int _hf_agent_codec_setup(const char *addr, guint codec_id)
+{
+       int ret;
+
+       if (!g_obj_path) {
+               ERR("g_obj_path is NULL\n");
+               return BT_HF_AGENT_ERROR_INTERNAL;
+       }
+
+       switch (codec_id) {
+       case BT_HF_CODEC_ID_CVSD:
+               INFO("Set NB parameters");
+               ret = __bt_hf_agent_gdbus_method_send(BLUEZ_SERVICE_NAME,
+                                               g_variant_new("(ss)", "Handsfree", addr),
+                                               BT_ADAPTER_INTERFACE,
+                                               "SetNbParameters");
+               break;
+       case BT_HF_CODEC_ID_MSBC:
+               INFO("Set WBS parameters");
+               ret = __bt_hf_agent_gdbus_method_send(BLUEZ_SERVICE_NAME,
+                                               g_variant_new("(ss)", "Handsfree", addr),
+                                               BT_ADAPTER_INTERFACE,
+                                               "SetWbsParameters");
+               break;
+       default:
+               ret = BT_HF_AGENT_ERROR_INTERNAL;
+               ERR("Invalid Codec\n");
+               break;
+       }
+
+       if (ret)
+               ERR("Failed to setup the Codec\n");
+       else
+               current_codec_id = codec_id;
+
+       return ret;
+}
+
+static void __bt_hf_agent_handle_codec_select(bt_hf_agent_info_t *bt_hf_info,
+                                                       guint codec_id)
+{
+       gchar cmd_buf[BT_HF_CMD_BUF_SIZE] = {0};
+       gboolean ret;
+
+       if (codec_id != BT_HF_CODEC_ID_CVSD && codec_id != BT_HF_CODEC_ID_MSBC) {
+               INFO("Codec id doesn't match, so send available codec again");
+               ret = __bt_hf_send_available_codec(bt_hf_info, 1);
+               if (!ret)
+                       ERR("Failed to send avalable codec");
+               return;
+       }
+
+       /* HF should be ready accpet SCO connection before sending theresponse for
+       "\r\n+BCS=>Codec ID\r\n", Keep the BT chip ready to recevie encoded SCO data */
+       ret = _hf_agent_codec_setup(bt_hf_info->remote_addr, codec_id);
+
+       snprintf(cmd_buf, sizeof(cmd_buf), BT_HF_CODEC_SELECT, codec_id);
+
+       bt_hf_info->context = NULL;
+
+       ret = __bt_hf_send_only(bt_hf_info, cmd_buf, strlen(cmd_buf));
+       if (!ret)
+               ERR("Failed to select the Codec");
+}
+
+void __bt_hf_agent_print_at_buffer(char *message, const char *buf)
+{
+
+       int i = 0;
+       char s[BT_HF_DATA_BUF_SIZE] = {0, };
+       gboolean hide = FALSE;
+
+       gboolean has_clcc = FALSE;
+       gboolean has_clip = FALSE;
+       gboolean has_ccwa = FALSE;
+       char *xsat_ptr;
+
+       strncpy(s, buf, BT_HF_DATA_BUF_SIZE - 1);
+
+       has_clcc = strstr(buf, "CLCC:") ? TRUE : FALSE;
+       if (has_clcc == TRUE)
+               goto done;
+       has_clip = strstr(buf, "+CLIP:") ? TRUE : FALSE;
+       if (has_clip == TRUE)
+               goto done;
+       has_ccwa = strstr(buf, "+CCWA:") ? TRUE : FALSE;
+
+done:
+       /* +XSAT: 11,DISC */
+       xsat_ptr =  strstr(s, "11,DISC,");
+       if (xsat_ptr) {
+               xsat_ptr = xsat_ptr + 8;
+               int x = 0;
+               while (xsat_ptr[x] != '\0' && xsat_ptr[x] != '\r' && xsat_ptr[x] != '\n') {
+                       xsat_ptr[x] = 'X';
+                       x++;
+               }
+       }
+
+       /* AT+XSAT=11,Q_CT,X,XXXX */
+       xsat_ptr =  strstr(s, "11,Q_CT,");
+       if (xsat_ptr) {
+               xsat_ptr = xsat_ptr + 8;
+               int x = 0;
+               while (xsat_ptr[x] != '\0' && xsat_ptr[x] != '\r' && xsat_ptr[x] != '\n') {
+                       if (x > 1) /* ignore 0 and 1 position */
+                               xsat_ptr[x] = 'X';
+                       x++;
+               }
+       }
+
+       i = 0;
+       while (s[i] != '\0') {
+               if (s[i] == '\r' || s[i] == '\n') {
+                       s[i] = '.';
+               } else {
+                       if (s[i] == '\"')
+                               hide = hide ? FALSE : TRUE;
+                       else if ((has_clcc || has_clip || has_ccwa) && hide) {
+                               if (i % 2)
+                                       s[i] = 'X';
+                       }
+               }
+               i++;
+       }
+       if (message)
+               INFO("%s Buffer = %s, Length = %d ", message, s, strlen(s));
+       else
+               INFO("%s", s);
+}
+
+static int __bt_hf_agent_handler_ciev(bt_hf_agent_info_t *bt_hf_info, const char *buf)
+{
+       gchar indicator[BT_HF_INDICATOR_DESCR_SIZE + 4];
+       gchar *sep;
+       gint value;
+       guint index;
+       char fmt_str[BT_HF_FMT_STR_SIZE];
+
+       DBG("++++++++ __bt_hf_agent_handler_ciev +++++++++");
+
+       snprintf(fmt_str, sizeof(fmt_str), "\r\n+CIEV:%%%ds\r\n", sizeof(indicator) - 1);
+       if (sscanf(buf, fmt_str, indicator) == 1) {
+               sep = strchr(indicator, ',');
+               sep[0] = '\0';
+               sep += 1;
+               index = atoi(indicator);
+               value = atoi(sep);
+               __bt_hf_agent_handle_ind_change(bt_hf_info, index, value);
+
+               if (bt_hf_info->ciev_call_status == 0 &&
+                               bt_hf_info->ciev_call_setup_status == 0)
+                       INFO("No active call");
+               else
+                       /* Request CLCC based on indicator change for call/callsetup/callHeld */
+                       __bt_hf_agent_request_call_list_info(bt_hf_info, index);
+       }
+       DBG("--------- __bt_hf_agent_handler_ciev ------------");
+       return 0;
+}
+
+static void __bt_hf_agent_handle_ven_samsung(bt_hf_agent_info_t *bt_hf_info,
+                                               gint app_id, const char *msg)
+{
+       /* Whomesoever wants need to handle it */
+       char *sig_name = "SamsungXSAT";
+       GDBusConnection *conn;
+
+       conn = __bt_hf_get_gdbus_connection();
+       if (!conn) {
+               ERR("Unable to get connection");
+               return;
+       }
+
+       __bt_hf_agent_emit_signal(conn,
+                               BT_HF_AGENT_OBJECT_PATH,
+                               BT_HF_SERVICE_INTERFACE,
+                               sig_name,
+                               g_variant_new("(is)", app_id, msg));
+}
+
+static int __bt_hf_agent_handler_ring(bt_hf_agent_info_t *bt_hf_info, const char *buf)
+{
+       DBG("++++++++ __bt_hf_agent_handler_ring ++++++++");
+       DBG("---------__bt_hf_agent_handler_ring --------");
+
+       return 0;
+}
+
+static int __bt_hf_agent_handler_clip(bt_hf_agent_info_t *bt_hf_info, const char *buf)
+{
+       DBG("+++++++++ __bt_hf_agent_handler_clip ++++++++");
+       DBG("---------__bt_hf_agent_handler_clip --------");
+
+       return 0;
+}
+
+static int __bt_hf_agent_handler_bvra(bt_hf_agent_info_t *bt_hf_info, const char *buf)
+{
+       DBG("+++++++++ __bt_hf_agent_handler_bvra +++++++++");
+       gint value;
+        if (sscanf(buf, "\r\n+BVRA:%1d\r\n", &value) == 1)
+               __bt_hf_agent_handle_voice_activation(value);
+
+        DBG("---------__bt_hf_agent_handler_bvra --------");
+       return 0;
+}
+
+static int __bt_hf_agent_handler_bcs(bt_hf_agent_info_t *bt_hf_info, const char *buf)
+{
+       guint codec_id;
+       DBG("+++++++++ __bt_hf_agent_handler_bcs +++++++++-");
+       if (sscanf(buf, "\r\n+BCS:%3d\r\n", &codec_id))
+               __bt_hf_agent_handle_codec_select(bt_hf_info, codec_id);
+
+       DBG("---------__bt_hf_agent_handler_bcs --------");
+       return 0;
+}
+
+static int __bt_hf_agent_handler_vgs(bt_hf_agent_info_t *bt_hf_info, const char *buf)
+{
+       gint value;
+       DBG("+++++++++ __bt_hf_agent_handler_vgs +++++++++");
+       if (sscanf(buf, "\r\n+VGS:%2d\r\n", &value))
+               __bt_hf_agent_handle_speaker_gain(value);
+
+       DBG("---------__bt_hf_agent_handler_vgs --------");
+
+       return 0;
+}
+
+static int __bt_hf_agent_handler_ccwa(bt_hf_agent_info_t *bt_hf_info, const char *buf)
+{
+       DBG("+++++++++ __bt_hf_agent_handler_ccwa ++++++++");
+               __bt_hf_agent_handle_ccwa(bt_hf_info, buf);
+       DBG("---------__bt_hf_agent_handler_ccwa --------");
+
+       return 0;
+}
+
+
+static int __bt_hf_agent_handler_xsat(bt_hf_agent_info_t *bt_hf_info,
+                                                       const char *buf)
+{
+       gint app_id;
+       char msg[BT_HF_DATA_BUF_SIZE];
+       char fmt_str[BT_HF_CMD_BUF_SIZE];
+
+       DBG("+++++++++ __bt_hf_agent_handler_xsat +++++++++");
+       snprintf(fmt_str, sizeof(fmt_str), "\r\n+XSAT:%%d,%%%ds\r\n", sizeof(msg) - 1);
+       if (sscanf(buf, fmt_str, &app_id, msg)) {
+               if (app_id == 2 && strstr(msg, "READTXPOWER")) {
+                       char cmd_buf[BT_HF_CMD_BUF_SIZE * 2] = {0, };
+                       char power = __bt_hf_agent_get_tx_power(bt_hf_info->remote_addr);
+                       snprintf(cmd_buf, sizeof(cmd_buf), "AT+XSAT: 2,%d", power);
+                       bt_hf_agent_send_at_cmd(NULL, cmd_buf);
+               } else {
+                       __bt_hf_agent_handle_ven_samsung(bt_hf_info, app_id, msg);
+               }
+       }
+
+       DBG("---------__bt_hf_agent_handler_xsat --------");
+
+       return 0;
+}
+
+static int __bt_hf_agent_handler_cme_error(bt_hf_agent_info_t *bt_hf_info,
+                                                       const char *buf)
+{
+       DBG("+++++++++ __bt_hf_agent_handler_cme_error ++++++++");
+
+       GDBusConnection *conn;
+
+       if (strstr(prev_cmd, "ATD") || strstr(prev_cmd, BT_HF_REDIAL)) {
+               conn = __bt_hf_get_gdbus_connection();
+               if (!conn) {
+                       ERR("Unable to get connection");
+                       return 0;
+               }
+
+               __bt_hf_agent_emit_signal(conn,
+                                       BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE,
+                                       "CallTerminated",
+                                       NULL);
+       }
+
+       __bt_hf_clear_prev_sent_cmd();
+
+       return 0;
+}
+
+static int __bt_hf_agent_handler_response_ok(bt_hf_agent_info_t *bt_hf_info,
+                                                       const char *buf)
+{
+       DBG("+++++++++ __bt_hf_agent_handler_response_ok ++++++++");
+
+       __bt_hf_clear_prev_sent_cmd();
+
+       return 0;
+}
+
+static int __bt_hf_agent_handler_response_err(bt_hf_agent_info_t *bt_hf_info,
+                                                       const char *buf)
+{
+       DBG("+++++++++ __bt_hf_agent_handler_response_err ++++++++");
+       GDBusConnection *conn;
+
+       if (strstr(prev_cmd, "ATD") || strstr(prev_cmd, BT_HF_REDIAL)) {
+               conn = __bt_hf_get_gdbus_connection();
+               if (!conn) {
+                       ERR("Unable to get connection");
+                       return 0;
+               }
+
+               __bt_hf_agent_emit_signal(conn, BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE,
+                                       "CallTerminated",
+                                       NULL);
+       }
+       __bt_hf_clear_prev_sent_cmd();
+
+       return 0;
+}
+
+static int __bt_hf_agent_handler_response_serr(bt_hf_agent_info_t *bt_hf_info,
+                                                       const char *buf)
+{
+       DBG("+");
+       GDBusConnection *conn;
+
+       if (strstr(prev_cmd, "ATD") || strstr(prev_cmd, BT_HF_REDIAL)) {
+               conn = __bt_hf_get_gdbus_connection();
+               if (!conn) {
+                       ERR("Unable to get connection");
+                       return 0;
+               }
+
+               __bt_hf_agent_emit_signal(conn, BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE,
+                                       "CallTerminated",
+                                       NULL);
+       }
+
+       __bt_hf_clear_prev_sent_cmd();
+
+       DBG("-");
+       return 0;
+}
+
+static int __bt_hf_agent_handler_clcc(bt_hf_agent_info_t *bt_hf_info, const char *buffer)
+{
+
+       GSList *call_list = NULL;
+       DBG("+++++++++ __bt_hf_agent_handler_clcc ++++++++");
+       DBG_SECURE("Receive CLCC response buffer = '%s'", buffer);
+
+       __bt_hf_lock_display(0);
+
+       call_list = __bt_hf_prepare_call_list(buffer);
+
+       if (call_list == NULL)
+               goto done;
+
+       __bt_hf_launch_call_using_call_list(call_list, bt_hf_info);
+
+       __bt_hf_agent_send_call_status_info(call_list);
+
+       __bt_hf_free_call_list(call_list);
+
+done:
+       __bt_hf_unlock_display();
+       DBG("---------__bt_hf_agent_handler_clcc --------");
+       return 0;
+}
+
+static struct hf_event hf_event_callbacks[] = {
+       { "\r\n+CIEV:", __bt_hf_agent_handler_ciev },
+       { "\r\nRING", __bt_hf_agent_handler_ring },
+       { "\r\n+CLIP:", __bt_hf_agent_handler_clip },
+       { "\r\n+BVRA:", __bt_hf_agent_handler_bvra },
+       { "\r\n+BCS:", __bt_hf_agent_handler_bcs },
+       { "\r\n+VGS:", __bt_hf_agent_handler_vgs },
+       { "\r\n+CCWA:", __bt_hf_agent_handler_ccwa },
+       { "\r\n+XSAT:", __bt_hf_agent_handler_xsat },
+       {"\r\n+CLCC:", __bt_hf_agent_handler_clcc },
+       { 0 }
+};
+
+static struct hf_event hf_event_resp_callbacks[] = {
+       { "\r\n+CME ERROR:", __bt_hf_agent_handler_cme_error },
+       { "\r\nOK\r\n", __bt_hf_agent_handler_response_ok },
+       { "ERROR", __bt_hf_agent_handler_response_err },
+       { "SERR", __bt_hf_agent_handler_response_serr },
+       { 0 }
+};
+
+bt_hf_agent_send_at_info *__bt_hf_agent_find_next(bt_hf_agent_info_t *bt_hf_info)
+{
+       int len;
+       int i;
+       bt_hf_agent_send_at_info *cmd;
+       len = g_slist_length(bt_hf_info->cmd_send_queue);
+       for (i = 0; i < len; ++i) {
+               cmd = g_slist_nth_data(bt_hf_info->cmd_send_queue, i);
+               DBG("F> %.6s[%d]", cmd->at_cmd, cmd->id);
+       }
+       len = g_slist_length(bt_hf_info->cmd_send_queue);
+       DBG("Context queue length = %d", len);
+       if (len == 0)
+               return NULL;
+
+       cmd = g_slist_nth_data(bt_hf_info->cmd_send_queue, 0);
+       if (cmd) {
+               bt_hf_info->cmd_send_queue = g_slist_remove(bt_hf_info->cmd_send_queue, cmd);
+               DBG("NEXT[%d] Found %s, context = 0x%x, pending = %d", cmd->id,
+                               cmd->at_cmd, cmd->context, cmd->pending);
+                       return cmd;
+       }
+
+       DBG("**** Not found any pending command on list length %d ****", len);
+
+       return NULL;
+}
+
+static int hf_handle_rx_at_cmd(bt_hf_agent_info_t *bt_hf_info, const char *buf)
+{
+       struct hf_event *ev;
+       int ret = -EINVAL;
+       bt_hf_agent_send_at_info *cmd = NULL;
+
+       __bt_hf_agent_print_at_buffer("Processing [Rx cmd]:", buf);
+
+       for (ev = hf_event_resp_callbacks; ev->cmd; ev++) {
+               if (strstr(buf, ev->cmd)) {
+                       if (send_flag)
+                               send_flag--;
+                       DBG("Send flag value = %d(after)", send_flag);
+                       ret = ev->callback(bt_hf_info, buf);
+               }
+       }
+
+       if (ret != -EINVAL)
+               goto done;
+
+       for (ev = hf_event_callbacks; ev->cmd; ev++) {
+               if (!strncmp(buf, ev->cmd, strlen(ev->cmd))) {
+                       ret = ev->callback(bt_hf_info, buf);
+                       break;
+               }
+       }
+
+               return ret;
+done:
+
+       cmd = __bt_hf_agent_find_next(bt_hf_info);
+
+       if (cmd && cmd->context) {
+               DBG("Pending context found for %.6s[%d]", cmd->at_cmd, cmd->id);
+               g_dbus_method_invocation_return_value(cmd->context, NULL);
+               if (cmd->timer_id)
+                       g_source_remove(cmd->timer_id);
+               g_free(cmd);
+               cmd = NULL;
+       }
+
+       if (cmd == NULL)
+               cmd = __bt_hf_agent_find_next(bt_hf_info);
+
+       if (cmd && cmd->pending && send_flag == 0) {
+               DBG("Pending only found of %.6s[%d]", cmd->at_cmd, cmd->id);
+               __bt_hf_send_only_without_queue(bt_hf_info,
+                                       cmd->at_cmd, cmd->count);
+                cmd->pending = FALSE;
+               bt_hf_info->cmd_send_queue = g_slist_prepend(bt_hf_info->cmd_send_queue,
+                                                                       cmd);
+               DBG("Prepend %.6s[%d]", cmd->at_cmd, cmd->id);
+       } else {
+               if (cmd) {
+                       DBG("Pending free for %.6s[%d] - send_flag = %d",
+                                       cmd->at_cmd, cmd->id, send_flag);
+                       if (cmd->timer_id)
+                               g_source_remove(cmd->timer_id);
+                       g_free(cmd);
+               }
+
+
+
+               /* Need to process further pending */
+               cmd = __bt_hf_agent_find_next(bt_hf_info);
+               if (cmd) {
+                       if (cmd->pending && send_flag == 0) {
+                               DBG("2nd Pending only found of %.6s[%d]",
+                                                       cmd->at_cmd, cmd->id);
+                               __bt_hf_send_only_without_queue(bt_hf_info,
+                                               cmd->at_cmd, cmd->count);
+                                cmd->pending = FALSE;
+                       }
+                       bt_hf_info->cmd_send_queue = g_slist_prepend(bt_hf_info->cmd_send_queue,
+                                                                       cmd);
+                       DBG("2nd Prepend %.6s[%d]", cmd->at_cmd, cmd->id);
+               }
+       }
+       return ret;
+}
+
+static int hf_handle_append_clcc_buff(char *cmd_buf, const char *buf)
+{
+       int buf_length;
+       int cmd_length =  0;
+       int cmd_buf_len = 0;
+       char *pos_start, *pos_end;
+       const char *datap = buf;
+
+       cmd_buf_len = strlen(cmd_buf);
+       buf_length = strlen(buf);
+       DBG("buf_length = %d, cmd_buf_len = %d", buf_length, cmd_buf_len);
+
+       if (buf_length > 0 && strstr(datap, "+CLCC")) {
+               pos_start = strstr(datap, "\r\n");
+               if (pos_start == NULL) {
+                       ERR("Invalid AT command signature..\n");
+                       return 0;
+               }
+
+               pos_end = g_strrstr(datap, "+CLCC");
+               if (pos_end == NULL) {
+                       ERR("Invalid AT command signature..\n");
+                       return 0;
+               }
+               pos_end =  strstr(pos_end, "\r\n");
+               cmd_length =   (pos_end - pos_start) + 2;
+               INFO("CLCC balance Cmd Length = %d\n", cmd_length);
+               memcpy(cmd_buf + cmd_buf_len, pos_start, cmd_length);
+               cmd_buf[cmd_buf_len + cmd_length] = '\0';
+
+               if (strstr(cmd_buf, "\r\nOK\r\n")) {
+                       pos_end = strstr(datap, "\r\nOK\r\n");
+                       cmd_length =   (pos_end - pos_start);
+                       memcpy(cmd_buf + cmd_buf_len, pos_start, cmd_length);
+                       cmd_buf[cmd_buf_len + cmd_length] = '\0';
+                       INFO("New CLCC balance Cmd Length = %d", cmd_length);
+               }
+       }
+       return cmd_length;
+}
+
+
+static int hf_handle_rx_at_buff(bt_hf_agent_info_t *bt_hf_info, const char *buf)
+{
+       int buf_length;
+       int cmd_length;
+       char *pos_start, *pos_end;
+       int tmp;
+       gchar cmd_buf[BT_HF_DATA_BUF_SIZE] = {0,};
+       const char *datap = buf;
+
+       __bt_hf_agent_print_at_buffer("[HF AT CMD] Recv >>>>>:", buf);
+
+       buf_length = strlen(buf);
+
+       while (buf_length > 0) {
+               pos_start = strstr(datap, "\r\n");
+               if (pos_start == NULL) {
+                       ERR("Invalid AT command start signature..\n");
+                       break;
+               }
+
+               datap += 2;
+               pos_end = strstr(datap, "\r\n");
+               if (pos_end == NULL) {
+                       ERR("Invalid AT command end signature..\n");
+                       break;
+               }
+               cmd_length =   (pos_end - pos_start) + 2;
+               DBG("Cmd Length = %d\n", cmd_length);
+
+               memcpy(cmd_buf, pos_start, cmd_length);
+               cmd_buf[cmd_length] = '\0';
+
+               buf_length = buf_length - cmd_length;
+               datap = datap + cmd_length - 2;
+
+               /* We need to pass all the CLCC's together to its handler */
+               if (strstr(cmd_buf, "+CLCC")) {
+                       tmp = hf_handle_append_clcc_buff(cmd_buf, datap);
+                       datap += tmp;
+                       buf_length = buf_length - tmp;
+               }
+               hf_handle_rx_at_cmd(bt_hf_info, cmd_buf);
+               DBG("Pending buf_length = %d\n", buf_length);
+       }
+       return TRUE;
+
+}
+static gboolean __bt_hf_agent_data_cb(GIOChannel *chan, GIOCondition cond,
+                                       bt_hf_agent_info_t *bt_hf_info)
+{
+       gchar buf[BT_HF_DATA_BUF_SIZE] = {0,};
+       gsize read;
+       GError *gerr = NULL;
+       gboolean recvd_ok = FALSE;
+       gboolean recvd_error = FALSE;
+       gboolean recvd_sec_error = FALSE;
+
+       if (cond & (G_IO_ERR | G_IO_HUP)) {
+               ERR("ERR or HUP on RFCOMM socket");
+               INFO_C("Disconnected [HF role] [Terminated by remote dev]");
+               is_hf_connected = FALSE;
+               bt_hf_info->slc = FALSE;
+               __bt_hf_agent_release();
+               return FALSE;
+       }
+
+       if (g_io_channel_read_chars(chan, buf, sizeof(buf) - 1, &read, &gerr)
+                       != G_IO_STATUS_NORMAL) {
+               if (gerr) {
+                       ERR("Read failed, cond = [%d], Err msg = [%s]",
+                                                       cond, gerr->message);
+                       g_error_free(gerr);
+               }
+               return TRUE;
+       }
+       buf[read] = '\0';
+       recvd_ok = NULL != strstr(buf, BT_HF_OK_RESPONSE);
+       recvd_error = NULL != strstr(buf, BT_HF_ERROR_RESPONSE);
+       recvd_sec_error = NULL != strstr(buf, BT_HF_SEC_ERROR_RESPONSE);
+       DBG("<-------Received data --send flag status = %d ----->", send_flag);
+
+       /* Once service level connection is established we need to handle
+        * all the intermediate AT commands */
+       if (bt_hf_info->state != BT_HF_STATE_CONNECTED)
+               return TRUE;
+
+       if (send_flag) {
+               strncat(global_buff, buf,
+                       (BT_AT_COMMAND_BUFFER_MAX - 1) - strlen(global_buff));
+               if (!(recvd_ok || recvd_error || recvd_sec_error)) {
+                       __bt_hf_agent_print_at_buffer("Concat ()", global_buff);
+               } else {
+                       DBG("*** Received terminator.. process Rx buffer ***");
+                       hf_handle_rx_at_buff(bt_hf_info, global_buff);
+                       memset(global_buff, 0, sizeof(global_buff));
+               }
+       } else {
+               INFO("***  Received Direct AT buffer packet handling ****");
+               hf_handle_rx_at_buff(bt_hf_info, buf);
+       }
+       return TRUE;
+}
+
+static void __bt_hf_agent_start_watch(bt_hf_agent_info_t *bt_hf_info)
+{
+       bt_hf_info->watch_id = g_io_add_watch(bt_hf_info->io_chan,
+                       G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+                       (GIOFunc) __bt_hf_agent_data_cb, bt_hf_info);
+}
+
+static void __bt_hf_agent_stop_watch(bt_hf_agent_info_t *bt_hf_info)
+{
+       if (bt_hf_info->watch_id > 0) {
+               g_source_remove(bt_hf_info->watch_id);
+               bt_hf_info->watch_id = 0;
+       }
+}
+
+static gboolean __bt_hf_channel_write(GIOChannel *io, gchar *data,
+                                       gsize count)
+{
+       gsize written = 0;
+       GIOStatus status;
+
+       while (count > 0) {
+               status = g_io_channel_write_chars(io, data, count, &written,
+                                               NULL);
+               if (status != G_IO_STATUS_NORMAL)
+                       return FALSE;
+
+               data += written;
+               count -= written;
+       }
+       return TRUE;
+}
+
+static gboolean __bt_hf_send_only_without_queue(bt_hf_agent_info_t *bt_hf_info,
+                                               gchar *data, gsize count)
+{
+       GIOChannel *io_chan = bt_hf_info->io_chan;
+       if (!__bt_hf_channel_write(io_chan, data, count))
+               return FALSE;
+
+       g_io_channel_flush(io_chan, NULL);
+
+       if (count > 2 && data[2] == 'D') { /* ATDXXXXX */
+               INFO("Send only buffer size =[%d] No len = %d - Send <<<<<| %s",
+                                        count, count - 6, "ATDXXXXXXX");
+               snprintf(prev_cmd, BT_HF_CMD_BUF_SIZE, "%s", data);
+       } else {
+               INFO("No queue....Send only buffer size =[%d] - Send <<<<<| %s",
+                                                               count, data);
+       }
+
+       send_flag++;
+       /* DBG("Ref %d(after) on Send only buffer size =[%d] - Send <<<<<| %s",
+        * send_flag, count, data); */
+       return TRUE;
+
+}
+
+static gboolean __bt_hf_send_only(bt_hf_agent_info_t *bt_hf_info, gchar *data,
+                                                               gsize count)
+{
+       gboolean pending = FALSE;
+       GIOChannel *io_chan = bt_hf_info->io_chan;
+
+       if (send_flag) {
+               pending = TRUE;
+       }
+       __bt_hf_agent_add_queue(bt_hf_info->context, data, count, pending);
+
+       if (pending)
+               return TRUE;
+
+       if (!__bt_hf_channel_write(io_chan, data, count))
+               return FALSE;
+
+       g_io_channel_flush(io_chan, NULL);
+
+       if (count > 2 && data[2] == 'D') /* ATDXXXXX */
+               INFO("Send only buffer size =[%d] No len = %d - Send <<<<<| %s",
+                                        count, count - 6, "ATDXXXXXXX");
+       else
+               INFO("Send only buffer size =[%d] - Send <<<<<| %s", count, data);
+
+       send_flag++;
+       DBG("Ref %d(after) on Send only buffer size =[%d] - Send <<<<<| %s",
+                                               send_flag, count, data);
+       return TRUE;
+}
+
+static gboolean __bt_hf_send_and_read(bt_hf_agent_info_t *bt_hf_info,
+               gchar *data, gchar *response, gsize count)
+{
+       GIOChannel *io_chan = bt_hf_info->io_chan;
+       gsize rd_size = 0;
+       gboolean recvd_ok = FALSE;
+       gboolean recvd_error = FALSE;
+       gboolean recvd_sec_error = FALSE;
+       gchar *resp_buf = response;
+       gsize toread = BT_HF_DATA_BUF_SIZE - 1;
+       int i = 0;
+       int fd;
+       int err;
+       struct pollfd p;
+       GDBusConnection *conn;
+
+       /* Should not send cmds if DUT send a command and wait the response */
+       if (prev_cmd[0] != 0) {
+               INFO("DUT is waiting a respond for previous TX cmd. Skip sending.");
+               return FALSE;
+       }
+
+       memset(resp_buf, 0, BT_HF_DATA_BUF_SIZE);
+
+       if (!__bt_hf_channel_write(io_chan, data, count))
+               return FALSE;
+
+       g_io_channel_flush(io_chan, NULL);
+
+       __bt_hf_agent_print_at_buffer("[HF AT CMD] Send <<<<<:", data);
+
+       fd = g_io_channel_unix_get_fd(io_chan);
+       p.fd = fd;
+       p.events = POLLIN | POLLERR | POLLHUP | POLLNVAL;
+
+       /* Maximun 8 seconds of poll or 8 minus no of cmd received */
+       for (i = 1; i <= MAX_WAITING_DELAY; i++) {
+               DBG("Loop Counter = %d", i);
+               p.revents = 0;
+               err = poll(&p, 1, 1000);
+               if (err < 0) {
+                       ERR("Loop Counter = %d, >>>> Poll error happen", i);
+                       return FALSE;
+               } else if (err == 0) {
+                       INFO("Loop Counter = %d, >>>> Poll Timeout", i);
+               }
+
+               if (p.revents & (POLLERR | POLLHUP | POLLNVAL)) {
+                       ERR("Loop Counter = %d, >> Poll ERR/HUP/INV (%d)",
+                                                               i, p.revents);
+
+                       conn = __bt_hf_get_gdbus_connection();
+                       if (!conn) {
+                               ERR("Unable to get connection");
+                               return FALSE;
+                       }
+
+                       __bt_hf_agent_emit_signal(conn,
+                               BT_HF_AGENT_OBJECT_PATH,
+                               BT_HF_SERVICE_INTERFACE,
+                               "Disconnected",
+                               g_variant_new("(s)",
+                                               bt_hf_info->remote_addr));
+
+                       bt_hf_info->state = BT_HF_STATE_DISCONNECTED;
+                       return FALSE;
+               }
+
+               if (p.revents & POLLIN) {
+                       rd_size = read(fd, resp_buf, toread);
+                       resp_buf[rd_size] = '\0';
+                       DBG_SECURE("size = %d, Buffer=[%s]", rd_size, resp_buf);
+                       recvd_ok = NULL != strstr(resp_buf, BT_HF_OK_RESPONSE);
+                       recvd_error = NULL != strstr(resp_buf, BT_HF_ERROR_RESPONSE);
+                       recvd_sec_error = NULL != strstr(resp_buf, BT_HF_SEC_ERROR_RESPONSE);
+
+                       resp_buf += rd_size;
+                       toread -= rd_size;
+
+                       if (recvd_ok || recvd_error || recvd_sec_error) {
+                               DBG("Break Loop Counter = %d", i);
+                               break;
+                       }
+               }
+       }
+
+       /* Once service level connection is established we need to handle
+        * all the intermediate AT commands */
+       if (bt_hf_info->state == BT_HF_STATE_CONNECTED)
+               hf_handle_rx_at_buff(bt_hf_info, response);
+       return TRUE;
+}
+
+static GSList *__bt_hf_parse_indicator_names(gchar *names, GSList *indices)
+{
+       struct indicator *ind;
+       gchar *cur = names - 1;
+       GSList *list = indices;
+       gchar *next;
+
+       DBG("Indicator buffer = %s", names);
+       __bt_hf_agent_print_at_buffer("Indicator names :", names);
+       while (cur != NULL) {
+               cur += 2;
+               next = strstr(cur, ",(");
+               ind = g_new0(struct indicator, 1);
+               g_strlcpy(ind->descr, cur, BT_HF_INDICATOR_DESCR_SIZE);
+               ind->descr[(intptr_t) next - (intptr_t) cur] = '\0';
+               list = g_slist_append(list, (gpointer) ind);
+               cur = strstr(next + 1, ",(");
+       }
+       return list;
+}
+
+static GSList *__bt_hf_parse_indicator_values(gchar *values, GSList *indices)
+{
+       gint val;
+       struct indicator *ind;
+       GSList *runner = indices;
+
+       gchar *cur = values - 1;
+       DBG("Indicator string = %s", values);
+       __bt_hf_agent_print_at_buffer("Indicator values :", values);
+       while (cur != NULL) {
+               cur += 1;
+               sscanf(cur, "%1d", &val);
+               cur = strchr(cur, ',');
+               ind = g_slist_nth_data(runner, 0);
+               ind->value = val;
+               runner = g_slist_next(runner);
+       }
+       return indices;
+}
+
+static guint __bt_hf_get_hold_mpty_features(gchar *features)
+{
+       guint result = 0;
+
+       if (strstr(features, "0"))
+               result |= BT_HF_CHLD_0;
+
+       if (strstr(features, "1"))
+               result |= BT_HF_CHLD_1;
+
+       if (strstr(features, "1x"))
+               result |= BT_HF_CHLD_1x;
+
+       if (strstr(features, "2"))
+               result |= BT_HF_CHLD_2;
+
+       if (strstr(features, "2x"))
+               result |= BT_HF_CHLD_2x;
+
+       if (strstr(features, "3"))
+               result |= BT_HF_CHLD_3;
+
+       if (strstr(features, "4"))
+               result |= BT_HF_CHLD_4;
+
+       return result;
+}
+
+static gboolean __bt_hf_agent_sco_conn_cb(GIOChannel *chan, GIOCondition cond, gpointer user_data)
+{
+       bt_hf_agent_info_t *bt_hf_info = user_data;
+       GDBusConnection *conn;
+
+       DBG("");
+       if (cond & G_IO_NVAL)
+               return FALSE;
+
+       if (cond & (G_IO_HUP | G_IO_ERR)) {
+               g_io_channel_shutdown(chan, TRUE, NULL);
+               close(bt_hf_info->cli_sco_fd);
+               g_io_channel_unref(chan);
+               DBG("Emit AudioDisconnected Signal");
+
+               sco_audio_connected = BT_HF_AUDIO_DISCONNECTED;
+
+               conn = __bt_hf_get_gdbus_connection();
+               if (!conn) {
+                       ERR("Unable to get connection");
+                       return FALSE;
+               }
+               __bt_hf_agent_emit_signal(conn,
+                               BT_HF_AGENT_OBJECT_PATH,
+                               BT_HF_SERVICE_INTERFACE,
+                               "AudioDisconnected", NULL);
+
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean __bt_agent_query_and_update_call_list(gpointer data)
+{
+       DBG("+");
+       bt_hf_agent_info_t *bt_hf_info = data;
+
+       if (bt_hf_info->cli_sco_fd >= 0)
+               __bt_hf_agent_handle_call_list(bt_hf_info);
+       else
+               INFO("SCO Audio is already disconnected");
+
+       DBG("-");
+
+       return FALSE;
+}
+
+static gboolean __bt_hf_agent_sco_accept_cb(GIOChannel *chan, GIOCondition cond, gpointer user_data)
+{
+       bt_hf_agent_info_t *bt_hf_info = user_data;
+       int sco_skt;
+       int cli_sco_sock;
+       GIOChannel *sco_io;
+       GDBusConnection *conn;
+
+       INFO("Incoming SCO....");
+
+       if (cond & G_IO_NVAL)
+               return FALSE;
+
+       sco_skt = g_io_channel_unix_get_fd(chan);
+
+       if (cond & (G_IO_HUP | G_IO_ERR)) {
+               close(sco_skt);
+               return FALSE;
+       }
+
+       cli_sco_sock = accept(sco_skt, NULL, NULL);
+       if (cli_sco_sock < 0)
+               return FALSE;
+
+       bt_hf_info->cli_sco_fd = cli_sco_sock;
+
+       sco_io = g_io_channel_unix_new(cli_sco_sock);
+       g_io_channel_set_close_on_unref(sco_io, TRUE);
+       g_io_channel_set_encoding(sco_io, NULL, NULL);
+       g_io_channel_set_flags(sco_io, G_IO_FLAG_NONBLOCK, NULL);
+       g_io_channel_set_buffered(sco_io, FALSE);
+
+       g_io_add_watch(sco_io, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+                                       __bt_hf_agent_sco_conn_cb, bt_hf_info);
+
+       /* S-Voice app requires the AudioConnected signal earlier */
+       DBG("Emit AudioConnected Signal");
+
+       sco_audio_connected = BT_HF_AUDIO_CONNECTED;
+
+       conn = __bt_hf_get_gdbus_connection();
+       if (!conn) {
+               ERR("Unable to get connection");
+               return FALSE;
+       }
+
+       __bt_hf_agent_emit_signal(conn,
+                       BT_HF_AGENT_OBJECT_PATH,
+                       BT_HF_SERVICE_INTERFACE,
+                       "AudioConnected", NULL);
+
+       /* In the case of incoming call, the call app is already launched,
+        * hence AudioConnected signal is enough to update the call status.
+        * In the case of outgoing call we need to lauch the callapp.
+        */
+
+       g_idle_add(__bt_agent_query_and_update_call_list, bt_hf_info);
+
+       return TRUE;
+}
+
+void _bt_convert_addr_string_to_type_rev(unsigned char *addr,
+                                       const char *address)
+{
+        int i;
+        char *ptr = NULL;
+
+       ret_if(address == NULL);
+       ret_if(addr == NULL);
+
+        for (i = 0; i < 6; i++) {
+                addr[5 - i] = strtol(address, &ptr, 16);
+                if (ptr[0] != '\0') {
+                        if (ptr[0] != ':')
+                                return;
+
+                        address = ptr + 1;
+                }
+        }
+}
+
+static gboolean __bt_hf_agent_sco_accept(bt_hf_agent_info_t *bt_hf_info)
+{
+       struct sockaddr_sco addr;
+       GIOChannel *sco_io;
+       bdaddr_t bd_addr = {{0},};
+       int sco_skt;
+
+       if (bt_hf_info->state != BT_HF_STATE_CONNECTED)
+               return FALSE;
+
+       /* Create socket */
+       sco_skt = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
+       if (sco_skt < 0) {
+               ERR("Can't create socket:\n");
+               return FALSE;
+       }
+
+       /* Bind to local address */
+       memset(&addr, 0, sizeof(addr));
+       addr.sco_family = AF_BLUETOOTH;
+
+       DBG("Bind to address %s", bt_hf_info->remote_addr);
+
+       _bt_convert_addr_string_to_type_rev(bd_addr.b, bt_hf_info->remote_addr);
+       memcpy(&addr.sco_bdaddr, &bd_addr, sizeof(bdaddr_t));
+
+       if (bind(sco_skt, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+               ERR("Can't bind socket:\n");
+               goto error;
+       }
+
+       if (listen(sco_skt, 1)) {
+               ERR("Can not listen on the socket:\n");
+               goto error;
+       }
+
+       sco_io = g_io_channel_unix_new(sco_skt);
+       g_io_channel_set_close_on_unref(sco_io, TRUE);
+       g_io_channel_set_encoding(sco_io, NULL, NULL);
+       g_io_channel_set_flags(sco_io, G_IO_FLAG_NONBLOCK, NULL);
+       g_io_channel_set_buffered(sco_io, FALSE);
+
+       bt_hf_info->sco_fd = sco_skt;
+       bt_hf_info->sco_io_chan = sco_io;
+
+       bt_hf_info->sco_watch_id = g_io_add_watch(sco_io,
+                       G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, __bt_hf_agent_sco_accept_cb, bt_hf_info);
+
+       g_io_channel_unref(sco_io);
+
+       return TRUE;
+
+error:
+       close(sco_skt);
+       return FALSE;
+}
+
+static gboolean __bt_get_supported_indicators(bt_hf_agent_info_t *bt_hf_info)
+{
+       gchar buf[BT_HF_DATA_BUF_SIZE] = {0,};
+       gboolean ret;
+
+       ret = __bt_hf_send_and_read(bt_hf_info, BT_HF_INDICATORS_SUPP, buf,
+                               sizeof(BT_HF_INDICATORS_SUPP) - 1);
+       if (!ret || !strstr(buf, "+CIND:"))
+               return FALSE;
+
+       bt_hf_info->indies = __bt_hf_parse_indicator_names(strchr(buf, '('), NULL);
+
+       return TRUE;
+}
+
+static gboolean __bt_get_bia_cmd(bt_hf_agent_info_t *bt_hf_info, gchar *cmd, gsize cmd_size)
+{
+       GSList *l;
+       gsize ret;
+
+       if (bt_hf_info == NULL || cmd == NULL) {
+               ERR("Invalid parameter");
+               return FALSE;
+       }
+
+       ret = g_strlcpy(cmd, BT_HF_INDICATORS_ACTIVATION, cmd_size);
+
+       for (l = bt_hf_info->indies; l != NULL; l = g_slist_next(l)) {
+               ret = g_strlcat(cmd, "0,", cmd_size);
+               if (ret >= cmd_size) {
+                       ERR("Too many indices");
+                       return FALSE;
+               }
+
+       }
+
+       cmd[ret - 1] = '\0';
+       DBG("BIA Str : %s", cmd);
+
+       ret = g_strlcat(cmd, "\r", cmd_size);
+       if (ret >= cmd_size) {
+               ERR("Too many indices");
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean __bt_get_current_indicators(bt_hf_agent_info_t *bt_hf_info)
+{
+       gchar buf[BT_HF_DATA_BUF_SIZE] = {0,};
+       gboolean ret;
+       gchar *str;
+       GSList *l;
+       int index =  1;
+
+       ret = __bt_hf_send_and_read(bt_hf_info, BT_HF_INDICATORS_VAL, buf,
+               sizeof(BT_HF_INDICATORS_VAL) - 1);
+       if (!ret || !strstr(buf, "+CIND:"))
+               return FALSE;
+
+       /* if buf has other command prefix, skip it */
+       str = strstr(buf, "+CIND");
+       if (str == NULL)
+               return FALSE;
+
+       bt_hf_info->indies = __bt_hf_parse_indicator_values(str + 6, bt_hf_info->indies);
+
+       /* Parse the updated value */
+       for (l = bt_hf_info->indies; l != NULL; l = g_slist_next(l), ++index) {
+               struct indicator *ind = l->data;
+               if (!ind) {
+                       DBG("Index is NULL");
+                       break;
+               }
+
+               if (0 == g_strcmp0(ind->descr, "\"call\"")) {
+                       DBG("CIND Match found index = %d, %s, value = %d",
+                                               index, ind->descr, ind->value);
+                       bt_hf_info->ciev_call_status = ind->value;
+                       if (ind->value > 0) {
+                               bt_hf_info->is_dialing = FALSE;
+                               bt_hf_info->call_active = TRUE;
+                       }
+               } else if (0 == g_strcmp0(ind->descr, "\"callsetup\"")) {
+                       DBG("CIND Match found index = %d, %s, value = %d",
+                                               index, ind->descr, ind->value);
+                       bt_hf_info->ciev_call_setup_status = ind->value;
+                       if (!bt_hf_info->is_dialing && ind->value > 0)
+                               bt_hf_info->is_dialing = TRUE;
+               }
+       }
+
+       return TRUE;
+}
+
+static gboolean __bt_establish_service_level_conn(bt_hf_agent_info_t *bt_hf_info)
+{
+       gchar buf[BT_HF_DATA_BUF_SIZE];
+       gchar cmd_buf[BT_HF_CMD_BUF_SIZE] = {0};
+       gboolean ret;
+       char *buf_ptr;
+       guint feature = BT_HF_FEATURE_EC_ANDOR_NR |
+                       BT_HF_FEATURE_CALL_WAITING_AND_3WAY |
+                       BT_HF_FEATURE_CLI_PRESENTATION |
+                       BT_HF_FEATURE_VOICE_RECOGNITION |
+                       BT_HF_FEATURE_REMOTE_VOLUME_CONTROL |
+                       BT_HF_FEATURE_ENHANCED_CALL_STATUS |
+                       BT_HF_FEATURE_CODEC_NEGOTIATION;
+
+       snprintf(cmd_buf, sizeof(cmd_buf), BT_HF_FEATURES, feature);
+       ret = __bt_hf_send_and_read(bt_hf_info, cmd_buf, buf,
+                               strlen(cmd_buf));
+       if (!ret )
+               return FALSE;
+
+       buf_ptr = strstr(buf, "\r\n+BRSF:");
+       if (buf_ptr == NULL)
+               return FALSE;
+
+       if (!ret || sscanf(buf_ptr, "\r\n+BRSF:%5d", &bt_hf_info->ag_features) != 1)
+               return FALSE;
+       INFO("Gateway supported features are 0x%X", bt_hf_info->ag_features);
+
+       if (bt_hf_info->ag_features & BT_AG_FEATURE_CODEC_NEGOTIATION) {
+               ret = _hf_agent_codec_setup(bt_hf_info->remote_addr, BT_HF_CODEC_ID_MSBC);
+               if (ret != BT_HF_AGENT_ERROR_NONE)
+                       ERR("Unable to set the default WBC codec");
+
+               ret = __bt_hf_send_available_codec(bt_hf_info, 0);
+               if (!ret)
+                       return FALSE;
+       } else {
+               /* Default codec is NB */
+               ret = _hf_agent_codec_setup(bt_hf_info->remote_addr, BT_HF_CODEC_ID_CVSD);
+               if (ret != BT_HF_AGENT_ERROR_NONE)
+                       ERR("Unable to set the default NBC codec");
+       }
+
+       ret = __bt_get_supported_indicators(bt_hf_info);
+       if (!ret)
+               return FALSE;
+
+
+       ret = __bt_get_current_indicators(bt_hf_info);
+       if (!ret)
+               return FALSE;
+
+       ret = __bt_hf_send_and_read(bt_hf_info, BT_HF_INDICATORS_ENABLE, buf,
+                                       sizeof(BT_HF_INDICATORS_ENABLE) - 1);
+       if (!ret || !strstr(buf, "OK"))
+               return FALSE;
+
+       if ((bt_hf_info->ag_features & BT_AG_FEATURE_3WAY) != 0) {
+               ret = __bt_hf_send_and_read(bt_hf_info, BT_HF_HOLD_MPTY_SUPP,
+                                       buf, sizeof(BT_HF_HOLD_MPTY_SUPP) - 1);
+               if (!ret || !strstr(buf, "+CHLD:")) {
+                       ERR("Unable to get the CHLD Supported info");
+                       return FALSE;
+               }
+               bt_hf_info->hold_multiparty_features = __bt_hf_get_hold_mpty_features(
+                                                       strchr(buf, '('));
+       } else
+               bt_hf_info->hold_multiparty_features = 0;
+
+       INFO("Service layer connection successfully established...!");
+
+       __bt_hf_send_and_read(bt_hf_info, BT_HF_CALLER_IDENT_ENABLE, buf,
+                       sizeof(BT_HF_CALLER_IDENT_ENABLE) - 1);
+       __bt_hf_send_and_read(bt_hf_info, BT_HF_CARRIER_FORMAT, buf,
+                       sizeof(BT_HF_CARRIER_FORMAT) - 1);
+       __bt_hf_send_and_read(bt_hf_info, BT_HF_CALLWAIT_NOTI_ENABLE, buf,
+                       sizeof(BT_HF_CALLWAIT_NOTI_ENABLE) - 1);
+
+       if ((bt_hf_info->ag_features & BT_AG_FEATURE_NREC) != 0)
+               __bt_hf_send_and_read(bt_hf_info, BT_HF_NREC, buf,
+                                               sizeof(BT_HF_NREC) - 1);
+
+       if ((bt_hf_info->ag_features & BT_AG_FEATURE_EXTENDED_RES_CODE) != 0)
+               __bt_hf_send_and_read(bt_hf_info, BT_HF_EXTENDED_RESULT_CODE,
+                       buf, sizeof(BT_HF_EXTENDED_RESULT_CODE) - 1);
+
+       if (__bt_get_bia_cmd(bt_hf_info, cmd_buf, sizeof(cmd_buf)) == TRUE)
+               __bt_hf_send_and_read(bt_hf_info, cmd_buf, buf, strlen(cmd_buf));
+       else
+               ERR("__bt_get_bia_cmd is failed");
+
+       ret = __bt_hf_send_and_read(bt_hf_info, BT_HF_XSAT, buf,
+                                               sizeof(BT_HF_XSAT) - 1);
+       if (ret)
+               DBG("sent BT_HF_XSAT");
+       else
+               ERR("BT_HF_XSAT sending failed");
+
+       /* 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 (ret)
+               INFO("SLC completed with all commands");
+       else
+               ERR("BT_HF_BSSF sending failed");
+
+       bt_hf_info->slc = TRUE;
+       send_flag = FALSE;
+       g_id = 0;
+       memset(global_buff, 0, sizeof(global_buff));
+       return TRUE;
+}
+
+static void __bt_hf_agent_sigterm_handler(int signo)
+{
+       ERR_C("***** Signal handler came with signal %d *****", signo);
+       GDBusConnection *conn;
+
+       conn = __bt_hf_get_gdbus_connection();
+       if (!conn) {
+               ERR("Unable to get connection");
+               return;
+       }
+
+       __bt_hf_agent_emit_signal(conn,
+                       BT_HF_AGENT_OBJECT_PATH,
+                       BT_HF_SERVICE_INTERFACE,
+                       "CallEnded", NULL);
+       DBG("CallEnded Signal done");
+       if (gmain_loop) {
+               g_main_loop_quit(gmain_loop);
+               DBG("Exiting");
+               gmain_loop = NULL;
+       } else {
+               INFO_C("Terminating HF agent");
+               exit(0);
+       }
+}
+
+static void __bt_convert_addr_type_to_rev_string(char *address,
+                               unsigned char *addr)
+{
+       ret_if(address == NULL);
+       ret_if(addr == NULL);
+
+       g_snprintf(address, BT_ADDRESS_STRING_SIZE,
+                       "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
+                       addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
+}
+
+
+static gboolean __bt_hf_agent_release_after(gpointer user_data)
+{
+       if (__bt_hf_agent_release() == FALSE)
+               ERR("Unable to release hf connection");
+
+       return FALSE;
+}
+
+static gboolean __bt_agent_request_service_level_conn(gpointer data)
+{
+       char *remote_addr;
+       int bt_device_state = VCONFKEY_BT_DEVICE_NONE;
+       GDBusConnection *conn;
+
+       DBG("+");
+       memset(prev_cmd, 0, BT_HF_CMD_BUF_SIZE);
+
+       if (!__bt_establish_service_level_conn(&bt_hf_info)) {
+               ERR("Service Level Connection is fail");
+
+               conn = __bt_hf_get_gdbus_connection();
+               if (conn) {
+                       remote_addr = bt_hf_info.remote_addr;
+                       __bt_hf_agent_emit_signal(conn,
+                                       BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE,
+                                       "Connected",
+                                       g_variant_new("(s)", remote_addr));
+               }
+               bt_hf_info.state = BT_HF_STATE_CONNECTED;
+
+               if (vconf_get_int(VCONFKEY_BT_DEVICE, &bt_device_state) == 0) {
+                       DBG("BT device state is : 0x%X", bt_device_state);
+                       bt_device_state |= VCONFKEY_BT_DEVICE_AG_CONNECTED;
+                       if (vconf_set_int(VCONFKEY_BT_DEVICE, bt_device_state) != 0) {
+                               ERR("vconf_set_int failed");
+                       }
+               } else {
+                       ERR("vconf_get_int failed");
+               }
+
+               g_idle_add(__bt_hf_agent_release_after, NULL);
+
+               goto done;
+       }
+
+       bt_hf_info.state = BT_HF_STATE_CONNECTED;
+
+       __bt_hf_agent_sco_accept(&bt_hf_info);
+
+       __bt_hf_agent_start_watch(&bt_hf_info);
+
+       remote_addr = bt_hf_info.remote_addr;
+
+       INFO_SECURE("Address is : %s", remote_addr);
+       INFO_C("Connected [HF role]");
+
+       if (vconf_get_int(VCONFKEY_BT_DEVICE, &bt_device_state) == 0) {
+               DBG("BT device state is : 0x%X", bt_device_state);
+               bt_device_state |= VCONFKEY_BT_DEVICE_AG_CONNECTED;
+               if (vconf_set_int(VCONFKEY_BT_DEVICE, bt_device_state) != 0) {
+                       ERR("vconf_set_int failed");
+               }
+       } else {
+               ERR("vconf_get_int failed");
+       }
+
+       conn = __bt_hf_get_gdbus_connection();
+       if (!conn) {
+               ERR("Unable to get connection");
+               return FALSE;
+       }
+
+       __bt_hf_agent_emit_signal(conn,
+                       BT_HF_AGENT_OBJECT_PATH,
+                       BT_HF_SERVICE_INTERFACE,
+                       "Connected",
+                       g_variant_new("(s)", remote_addr));
+
+       /* Request the call list and launch call app if required */
+       __bt_hf_agent_handle_call_list(&bt_hf_info);
+
+done:
+       DBG("-");
+       return FALSE;
+}
+
+static gboolean __bt_hf_agent_connection(gint32 fd, const gchar *obj_path)
+{
+       GIOFlags flags;
+
+       struct sockaddr_remote address;
+       socklen_t address_len;
+       bt_hf_info.path = g_strdup(obj_path);
+
+       INFO_C("**** New HFP connection ****");
+
+       is_hf_connected = TRUE;
+
+       address_len = sizeof(address);
+       if (getpeername(fd, (struct sockaddr *) &address, &address_len) != 0)
+               ERR("BD_ADDR is NULL");
+
+       DBG("RFCOMM connection for HFP is completed. Fd = [%d]\n", fd);
+       bt_hf_info.fd = fd;
+       bt_hf_info.io_chan = g_io_channel_unix_new(bt_hf_info.fd);
+       flags = g_io_channel_get_flags(bt_hf_info.io_chan);
+
+       flags &= ~G_IO_FLAG_NONBLOCK;
+       flags &= G_IO_FLAG_MASK;
+       g_io_channel_set_flags(bt_hf_info.io_chan, flags, NULL);
+       g_io_channel_set_encoding(bt_hf_info.io_chan, NULL, NULL);
+       g_io_channel_set_buffered(bt_hf_info.io_chan, FALSE);
+
+       bt_hf_info.remote_addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
+       __bt_convert_addr_type_to_rev_string(bt_hf_info.remote_addr,
+                                               address.remote_bdaddr.b);
+
+       g_idle_add(__bt_agent_request_service_level_conn, NULL);
+
+       return TRUE;
+}
+
+static void __bt_hf_agent_indicator_free(gpointer mem)
+{
+       g_free(mem);
+}
+
+static gboolean __bt_hf_agent_release(void)
+{
+       int bt_device_state = VCONFKEY_BT_DEVICE_NONE;
+       GDBusConnection *conn;
+
+       if (bt_hf_info.state == BT_HF_STATE_DISCONNECTED) {
+               ERR("hf is already disconnected");
+               return FALSE;
+       }
+
+       if (bt_hf_info.indies) {
+               g_slist_free_full(bt_hf_info.indies, __bt_hf_agent_indicator_free);
+               bt_hf_info.indies = NULL;
+       }
+
+       if (bt_hf_info.io_chan) {
+               g_io_channel_shutdown(bt_hf_info.io_chan, TRUE, NULL);
+               g_io_channel_unref(bt_hf_info.io_chan);
+               bt_hf_info.io_chan = NULL;
+       }
+
+       if (bt_hf_info.sco_watch_id > 0) {
+               g_source_remove(bt_hf_info.sco_watch_id);
+               bt_hf_info.sco_watch_id = 0;
+       }
+
+       bt_hf_info.state = BT_HF_STATE_DISCONNECTED;
+
+       __bt_hf_agent_release_queue();
+
+       if (vconf_get_int(VCONFKEY_BT_DEVICE, &bt_device_state) == 0) {
+               DBG("BT device state is : 0x%X", bt_device_state);
+               bt_device_state ^= VCONFKEY_BT_DEVICE_AG_CONNECTED;
+               if (vconf_set_int(VCONFKEY_BT_DEVICE, bt_device_state) != 0) {
+                       ERR("vconf_set_int failed");
+               }
+       } else {
+               ERR("vconf_get_int failed");
+       }
+
+       __bt_hf_agent_stop_watch(&bt_hf_info);
+       conn = __bt_hf_get_gdbus_connection();
+       if (!conn) {
+               ERR("Unable to get connection");
+               return FALSE;
+       }
+
+       __bt_hf_agent_emit_signal(conn,
+                       BT_HF_AGENT_OBJECT_PATH,
+                       BT_HF_SERVICE_INTERFACE,
+                       "Disconnected",
+                       g_variant_new("(s)", bt_hf_info.remote_addr));
+
+       g_free(bt_hf_info.path);
+       bt_hf_info.path = NULL;
+
+       g_free(bt_hf_info.remote_addr);
+       bt_hf_info.remote_addr = NULL;
+
+       is_hf_connected = FALSE;
+
+       return TRUE;
+}
+
+static gboolean __bt_hf_agent_connection_release(void)
+{
+       return __bt_hf_agent_release();
+}
+
+static int __bt_hf_register_profile(const char *uuid, uint16_t version,
+                const char *name, const char *object, uint16_t features)
+{
+       DBG("+");
+       GDBusProxy *proxy;
+       GVariant *ret;
+       GError *error = NULL;
+       GVariantBuilder *builder;
+       gchar *path = NULL;
+
+       proxy = __bt_hf_gdbus_get_service_proxy(BLUEZ_SERVICE_NAME,
+                       "/org/bluez", BLUEZ_PROFILE_MGMT_INTERFACE);
+
+       if (proxy == NULL)
+               return BT_HF_AGENT_ERROR_INTERNAL;
+
+       path = g_strdup(BT_HF_BLUEZ_OBJECT_PATH);
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+
+       g_variant_builder_add(builder, "{sv}",
+                       "Name", g_variant_new("s",
+                       name));
+       g_variant_builder_add(builder, "{sv}",
+                       "Version", g_variant_new("q", version));
+
+       g_variant_builder_add(builder, "{sv}",
+                       "features", g_variant_new("q", features));
+
+       ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile",
+                               g_variant_new("(osa{sv})", path,
+                                       HFP_HF_UUID, builder),
+                               G_DBUS_CALL_FLAGS_NONE, -1,
+                               NULL, &error);
+
+       g_variant_builder_unref(builder);
+
+       if (ret == NULL) {
+               /* dBUS-RPC is failed */
+               ERR("dBUS-RPC is failed");
+               if (error != NULL) {
+                       /* dBUS gives error cause */
+                       ERR("D-Bus API failure: errCode[%x], message[%s]",
+                               error->code, error->message);
+                       g_clear_error(&error);
+               }
+               g_free(path);
+               return BT_HF_AGENT_ERROR_INTERNAL;
+       }
+       g_variant_unref(ret);
+       g_free(path);
+
+       DBG("-");
+       return BT_HF_AGENT_ERROR_NONE;
+}
+
+static void __bt_hf_agent_register(void)
+{
+       DBG("+");
+       int ret;
+       char *name;
+       uint16_t version = hf_ver;
+       uint16_t features = bt_hf_info.feature;
+
+       gchar *path = g_strdup(BT_HF_BLUEZ_OBJECT_PATH);
+       name = g_strdup("Hands-Free");
+
+       ret = __bt_hf_register_profile(HFP_HF_UUID, version, name, path,
+                                                               features);
+       if (ret)
+               ERR("Error in register");
+
+       g_free(path);
+       g_free(name);
+
+       DBG("-");
+       return;
+}
+
+static void __bt_hf_agent_unregister(void)
+{
+       DBG("+");
+
+       gchar *path = g_strdup(BT_HF_BLUEZ_OBJECT_PATH);
+
+       if (g_obj_path) {
+               __bt_hf_agent_gdbus_method_send(BLUEZ_SERVICE_NAME,
+                                               g_variant_new("(o)", path),
+                                               BLUEZ_HF_INTERFACE_NAME,
+                                               "UnregisterAgent");
+               g_free(g_obj_path);
+               g_obj_path = NULL;
+       }
+
+       g_free(path);
+
+       DBG("-");
+       return;
+}
+
+static void __bt_hf_agent_filter_cb(GDBusConnection *connection,
+                                                const gchar *sender_name,
+                                                const gchar *object_path,
+                                                const gchar *interface_name,
+                                                const gchar *signal_name,
+                                                GVariant *parameters,
+                                                gpointer user_data)
+{
+       DBG("+");
+       char *path = NULL;
+
+       GVariant *optional_param;
+
+       if (strcasecmp(signal_name, "InterfacesAdded") == 0) {
+
+               g_variant_get(parameters, "(&o@a{sa{sv}})",
+                               &path, &optional_param);
+               if (!path) {
+                       ERR("Invalid adapter path");
+                       return;
+               }
+
+               if (strcasecmp(path, DEFAULT_ADAPTER_OBJECT_PATH) == 0) {
+                       g_obj_path = g_strdup(path);
+                       INFO("Adapter Path = [%s]", path);
+                       __bt_hf_agent_register();
+               }
+       } else if (strcasecmp(signal_name, "InterfacesRemoved") == 0) {
+               g_variant_get(parameters, "(&o@as)", &path, &optional_param);
+               if (!path)
+                       __bt_hf_agent_unregister();
+       }
+       DBG("-");
+}
+
+static void __bt_hf_agent_dbus_init(void)
+{
+       GDBusConnection *conn;
+
+       DBG("+");
+
+       conn = __bt_hf_get_gdbus_connection();
+       if (conn == NULL) {
+               ERR("Error in creating the gdbus connection\n");
+               return;
+       }
+       if (!__bt_hf_register_profile_methods()) {
+               ERR("Error in register_profile_methods\n");
+               return;
+       }
+
+       owner_sig_id = g_dbus_connection_signal_subscribe(conn,
+                               NULL, BT_MANAGER_INTERFACE, NULL, NULL, NULL, 0,
+                               __bt_hf_agent_filter_cb, NULL, NULL);
+       DBG("-");
+       return;
+}
+
+static void __bt_hf_agent_dbus_deinit(void)
+{
+
+       if (service_gproxy) {
+               g_object_unref(service_gproxy);
+               service_gproxy = NULL;
+       }
+
+       if (gdbus_conn) {
+               if (owner_sig_id != -1)
+                       g_dbus_connection_signal_unsubscribe(gdbus_conn,
+                                               owner_sig_id);
+
+               g_object_unref(gdbus_conn);
+               gdbus_conn = NULL;
+       }
+       return;
+}
+
+static int _hf_agent_answer_call(GDBusMethodInvocation *context)
+{
+       int ret;
+
+       DBG("+\n");
+       if (bt_hf_info.state != BT_HF_STATE_CONNECTED) {
+               ERR("HF not Connected");
+               return BT_HF_AGENT_ERROR_NOT_CONNECTED;
+       }
+       bt_hf_info.context = context;
+
+       ret = __bt_hf_send_only(&bt_hf_info, BT_HF_ANSWER_CALL,
+                               sizeof(BT_HF_ANSWER_CALL) - 1);
+       if (!ret)
+               return BT_HF_AGENT_ERROR_INTERNAL;
+
+       DBG("-\n");
+       return BT_HF_AGENT_ERROR_NONE;
+
+}
+
+static int _hf_agent_terminate_call(GDBusMethodInvocation *context)
+{
+       int ret;
+
+       DBG("+\n");
+       if (bt_hf_info.state != BT_HF_STATE_CONNECTED) {
+               ERR("HF not Connected");
+               return BT_HF_AGENT_ERROR_NOT_CONNECTED;
+       }
+
+       bt_hf_info.context = context;
+
+       ret = __bt_hf_send_only(&bt_hf_info, BT_HF_END_CALL,
+                               sizeof(BT_HF_END_CALL) - 1);
+       if (!ret)
+               return BT_HF_AGENT_ERROR_INTERNAL;
+
+       DBG("-\n");
+       return BT_HF_AGENT_ERROR_NONE;
+}
+
+static int _hf_agent_dial_no(GDBusMethodInvocation *context, char *no)
+{
+       int ret;
+       char buf[BT_MAX_TEL_NUM_STR + 6] = {0};
+
+       if (bt_hf_info.state != BT_HF_STATE_CONNECTED) {
+               ERR("HF not Connected");
+               return BT_HF_AGENT_ERROR_NOT_CONNECTED;
+       }
+
+       bt_hf_info.context = context;
+
+       if (strlen(no) > 0) {
+               snprintf(buf, sizeof(buf),  BT_HF_DIAL_NO, no);
+
+               if (strstr(prev_cmd, "ATD") && bt_hf_info.ciev_call_status == 0
+                                               && bt_hf_info.ciev_call_setup_status == 0) {
+                       INFO("RAD POPUP CANCEL CASE. send ATD w/o response - KOR REQUEST");
+                       ret = __bt_hf_send_only_without_queue(&bt_hf_info, buf, strlen(buf));
+                       if (send_flag)
+                               send_flag--;
+               } else {
+                       ret = __bt_hf_send_only(&bt_hf_info, buf, strlen(buf));
+               }
+
+               /* prev_cmd is meant for only meant for ATD & AT+BLDN Error handling */
+               snprintf(prev_cmd, BT_HF_CMD_BUF_SIZE, "%s", buf);
+
+               if (!ret)
+                       return BT_HF_AGENT_ERROR_INTERNAL;
+
+               return BT_HF_AGENT_ERROR_NONE;
+       }
+
+       /* prev_cmd is meant for only meant for ATD & AT+BLDN Error handling */
+       snprintf(prev_cmd, BT_HF_CMD_BUF_SIZE, "%s", BT_HF_REDIAL);
+
+       ret = __bt_hf_send_only(&bt_hf_info, BT_HF_REDIAL,
+                                               sizeof(BT_HF_REDIAL) - 1);
+       if (!ret)
+               return BT_HF_AGENT_ERROR_INTERNAL;
+
+       return BT_HF_AGENT_ERROR_NONE;
+}
+
+static int _hf_agent_voice_recognition(GDBusMethodInvocation *context, unsigned int status)
+{
+       int ret;
+       char buf[20] = {0};
+
+       if (bt_hf_info.state != BT_HF_STATE_CONNECTED) {
+               ERR("HF not Connected");
+               return BT_HF_AGENT_ERROR_NOT_CONNECTED;
+       }
+
+       snprintf(buf, sizeof(buf),  BT_HF_VOICE_RECOGNITION, status);
+
+       bt_hf_info.context = context;
+
+       ret = __bt_hf_send_only(&bt_hf_info, buf, strlen(buf));
+       if (!ret)
+               return BT_HF_AGENT_ERROR_INTERNAL;
+
+
+       return BT_HF_AGENT_ERROR_NONE;
+}
+
+static int _hf_agent_set_speaker_gain(GDBusMethodInvocation *context, unsigned int gain)
+{
+       int ret;
+       char buf[20] = {0};
+
+       if (bt_hf_info.state != BT_HF_STATE_CONNECTED) {
+               ERR("HF not Connected");
+               return BT_HF_AGENT_ERROR_NOT_CONNECTED;
+       }
+
+       if (gain > BT_HF_MAX_SPEAKER_GAIN)
+               return BT_HF_AGENT_ERROR_INVALID_PARAM;
+
+       snprintf(buf, sizeof(buf),  BT_HF_SPEAKER_GAIN, gain);
+
+       bt_hf_info.context = context;
+
+       ret = __bt_hf_send_only(&bt_hf_info, buf,
+                               strlen(buf));
+       if (!ret)
+               return BT_HF_AGENT_ERROR_INTERNAL;
+
+       return BT_HF_AGENT_ERROR_NONE;
+
+}
+
+static int _hf_agent_send_dtmf(GDBusMethodInvocation *context, char *dtmf)
+{
+       int ret;
+       char buf[20] = {0};
+
+       if (strlen(dtmf) <= 0)
+               return BT_HF_AGENT_ERROR_INVALID_PARAM;
+
+       if (bt_hf_info.state != BT_HF_STATE_CONNECTED) {
+               ERR("HF not Connected");
+               return BT_HF_AGENT_ERROR_NOT_CONNECTED;
+       }
+
+       snprintf(buf, sizeof(buf),  BT_HF_DTMF, dtmf);
+
+       bt_hf_info.context = context;
+
+       ret = __bt_hf_send_only(&bt_hf_info, buf, strlen(buf));
+       if (!ret)
+               return BT_HF_AGENT_ERROR_INTERNAL;
+
+
+       return BT_HF_AGENT_ERROR_NONE;
+}
+
+
+static int _hf_agent_send_3way_cmd(GDBusMethodInvocation *context, char *cmd)
+{
+       int ret;
+
+       if (strlen(cmd) <= 0)
+               return BT_HF_AGENT_ERROR_INVALID_PARAM;
+
+       bt_hf_info.context = context;
+
+       ret = __bt_hf_send_only(&bt_hf_info, cmd,
+                               strlen(cmd));
+       if (!ret)
+               return BT_HF_AGENT_ERROR_INTERNAL;
+
+       return BT_HF_AGENT_ERROR_NONE;
+}
+
+static gboolean bt_hf_agent_sco_disconnect(void)
+{
+       DBG("+");
+       GDBusConnection *conn;
+
+       close(bt_hf_info.cli_sco_fd);
+       bt_hf_info.cli_sco_fd = -1;
+
+       DBG("Emit AudioDisconnected Signal");
+       conn = __bt_hf_get_gdbus_connection();
+       if (!conn) {
+               ERR("Unable to get connection");
+               return FALSE;
+       }
+
+       sco_audio_connected = BT_HF_AUDIO_DISCONNECTED;
+
+       __bt_hf_agent_emit_signal(conn,
+                       BT_HF_AGENT_OBJECT_PATH,
+                       BT_HF_SERVICE_INTERFACE,
+                       "AudioDisconnected", NULL);
+       DBG("-");
+       return TRUE;
+}
+
+static GVariant *bt_hf_agent_request_call_list(void)
+{
+       GSList *call_list = NULL;
+       GVariant *var_data;
+       DBG("+");
+
+       call_list = __bt_hf_get_call_list(&bt_hf_info);
+       if (!call_list) {
+               INFO("call list is NULL");
+               return NULL;
+       }
+
+       var_data = __bt_hf_agent_get_call_status_info(call_list);
+       __bt_hf_free_call_list(call_list);
+
+       DBG("-");
+       return var_data;
+}
+
+static int bt_hf_agent_send_at_cmd(GDBusMethodInvocation *context, char *atcmd)
+
+{
+       gboolean ret;
+       char cmd_buf[BT_MAX_TEL_NUM_STR + 20] = {0, };
+
+       DBG("+");
+
+       if (atcmd == NULL)
+               return  BT_HF_AGENT_ERROR_INVALID_PARAM;
+
+       if (bt_hf_info.state != BT_HF_STATE_CONNECTED)
+               return  BT_HF_AGENT_ERROR_NOT_CONNECTED;
+
+       /* Should not send cmds if DUT has sent a command and waiting for response */
+       if (prev_cmd[0] != 0) {
+               INFO("DUT is waiting a respond for previous TX cmd. Skip sending.");
+               return BT_HF_AGENT_ERROR_INTERNAL;
+       }
+
+       strncpy(cmd_buf, atcmd, sizeof(cmd_buf) - 2);
+       strncat(cmd_buf, "\r", (sizeof(cmd_buf) - 1) - strlen(cmd_buf));
+
+       bt_hf_info.context = context;
+
+       ret = __bt_hf_send_only(&bt_hf_info, cmd_buf, strlen(cmd_buf));
+       if (ret == FALSE)
+               return BT_HF_AGENT_ERROR_INTERNAL;
+
+       DBG("-");
+       return BT_HF_AGENT_ERROR_NONE;
+}
+
+static uint32_t __bt_hf_agent_get_hf_features(void)
+{
+
+       uint32_t hf_features = BT_HF_FEATURE_EC_ANDOR_NR |
+                       BT_HF_FEATURE_CALL_WAITING_AND_3WAY |
+                       BT_HF_FEATURE_CLI_PRESENTATION |
+                       BT_HF_FEATURE_VOICE_RECOGNITION |
+                       BT_HF_FEATURE_REMOTE_VOLUME_CONTROL |
+                       BT_HF_FEATURE_ENHANCED_CALL_STATUS |
+                       BT_HF_FEATURE_CODEC_NEGOTIATION;
+
+       hf_ver = HFP_VERSION_1_6;
+
+       return hf_features;
+}
+
+int main(void)
+{
+       struct sigaction sa;
+       const char *pkg_name = "org.tizen.hf_agent";
+       uint32_t hf_features;
+
+       INFO("Starting Bluetooth HF agent");
+
+       g_type_init();
+
+       hf_features = __bt_hf_agent_get_hf_features();
+       bt_hf_info.feature = (uint16_t) hf_features & 0x3F;
+
+       memset(&sa, 0, sizeof(sa));
+       sa.sa_flags = SA_NOCLDSTOP;
+       sa.sa_handler = __bt_hf_agent_sigterm_handler;
+       sigaction(SIGTERM, &sa, NULL);
+
+       /* Temporarily, block the below signal for debugging */
+//     sigaction(SIGSEGV, &sa, NULL);
+//     sigaction(SIGABRT, &sa, NULL);
+       gmain_loop = g_main_loop_new(NULL, FALSE);
+
+       if (gmain_loop == NULL) {
+               ERR("GMainLoop create failed\n");
+               return EXIT_FAILURE;
+       }
+
+       __bt_hf_agent_dbus_init();
+       g_main_loop_run(gmain_loop);
+
+       __bt_hf_agent_dbus_deinit();
+
+       if (gmain_loop)
+               g_main_loop_unref(gmain_loop);
+
+       INFO("Terminating Bluetooth HF agent");
+       return 0;
+}
diff --git a/hf-agent/bluetooth-hf-agent.h b/hf-agent/bluetooth-hf-agent.h
new file mode 100644 (file)
index 0000000..0a56557
--- /dev/null
@@ -0,0 +1,339 @@
+/*
+ * Bluetooth-hf-agent
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:    Hocheol Seo <hocheol.seo@samsung.com>
+ *             Girishashok Joshi <girish.joshi@samsung.com>
+ *             Chanyeol Park <chanyeol.park@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.
+ *
+ */
+
+#ifndef __DEF_BT_HF_AGENT_H_
+#define __DEF_BT_HF_AGENT_H_
+
+#undef LOG_TAG
+#define LOG_TAG "BLUETOOTH_HF_AGENT"
+
+#define LOG_COLOR_RESET    "\033[0m"
+#define LOG_COLOR_RED      "\033[31m"
+#define LOG_COLOR_YELLOW   "\033[33m"
+#define LOG_COLOR_GREEN         "\033[32m"
+#define LOG_COLOR_BLUE          "\033[36m"
+#define LOG_COLOR_PURPLE   "\033[35m"
+
+#define DBG(fmt, args...) SLOGD(fmt, ##args)
+#define INFO(fmt, args...) SLOGI(fmt, ##args)
+#define ERR(fmt, args...) SLOGE(fmt, ##args)
+#define DBG_SECURE(fmt, args...) SECURE_SLOGD(fmt, ##args)
+#define INFO_SECURE(fmt, args...) SECURE_SLOGI(fmt, ##args)
+#define ERR_SECURE(fmt, args...) SECURE_SLOGE(fmt, ##args)
+#define DBG_SECURE(fmt, args...) SECURE_SLOGD(fmt, ##args)
+#define INFO_C(fmt, arg...) \
+       SLOGI_IF(TRUE,  LOG_COLOR_BLUE" "fmt" "LOG_COLOR_RESET, ##arg)
+#define ERR_C(fmt, arg...) \
+       SLOGI_IF(TRUE,  LOG_COLOR_RED" "fmt" "LOG_COLOR_RESET, ##arg)
+
+
+#include <unistd.h>
+#include <dlog.h>
+#include <stdio.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <sys/socket.h>
+
+#define BTPROTO_SCO    2
+
+#define BT_HF_DATA_BUF_SIZE 1024
+#define BT_HF_CMD_BUF_SIZE 32
+#define BT_HF_INDICATOR_DESCR_SIZE 20
+#define BT_HF_CALLER_NUM_SIZE 64       /* size of number + type */
+#define BT_HF_FMT_STR_SIZE 32
+
+#define BT_HF_AGENT_ERROR (__bt_hf_agent_error_quark())
+
+#define BT_ERROR_INTERNAL "InternalError"
+#define BT_ERROR_NOT_AVAILABLE "NotAvailable"
+#define BT_ERROR_NOT_CONNECTED "NotConnected"
+#define BT_ERROR_NOT_CONNECTION_FAILED "ConnectionFailed"
+#define BT_ERROR_BUSY "InProgress"
+#define BT_ERROR_INVALID_PARAM "InvalidArguments"
+#define BT_ERROR_ALREADY_EXIST "AlreadyExists"
+#define BT_ERROR_ALREADY_CONNECTED "Already Connected"
+#define BT_ERROR_NO_MEMORY "No memory"
+#define BT_ERROR_I_O_ERROR "I/O error"
+#define BT_ERROR_OPERATION_NOT_AVAILABLE "Operation currently not available"
+#define BT_ERROR_OPERATION_NOT_ALLOWED "Operation not allowed"
+#define BT_ERROR_OPERATION_NOT_SUPPORTED "Operation not supported"
+#define BT_ERROR_INVALID_FILE_DESCRIPTOR "Invalid File Descriptor"
+
+typedef enum {
+       BT_HF_AGENT_ERROR_NONE,
+       BT_HF_AGENT_ERROR_INTERNAL,
+       BT_HF_AGENT_ERROR_NOT_AVAILABLE,
+       BT_HF_AGENT_ERROR_NOT_CONNECTED,
+       BT_HF_AGENT_ERROR_CONNECTION_FAILED,
+       BT_HF_AGENT_ERROR_BUSY,
+       BT_HF_AGENT_ERROR_INVALID_PARAM,
+       BT_HF_AGENT_ERROR_ALREADY_EXIST,
+       BT_HF_AGENT_ERROR_ALREADY_CONNECTED,
+       BT_HF_AGENT_ERROR_NO_MEMORY,
+       BT_HF_AGENT_ERROR_I_O_ERROR,
+       BT_HF_AGENT_ERROR_APPLICATION,
+       BT_HF_AGENT_ERROR_NOT_ALLOWED,
+       BT_HF_AGENT_ERROR_NOT_SUPPORTED,
+       BT_HF_AGENT_ERROR_INVALID_FILE_DESCRIPTOR,
+} bt_hf_agent_error_t;
+
+/* Extended Audio Gateway Error Result Codes */
+typedef enum {
+       BT_AG_CME_ERROR_NONE                    = -1,
+       BT_AG_CME_ERROR_AG_FAILURE              = 0,
+       BT_AG_CME_ERROR_NO_PHONE_CONNECTION     = 1,
+       BT_AG_CME_ERROR_NOT_ALLOWED             = 3,
+       BT_AG_CME_ERROR_NOT_SUPPORTED           = 4,
+       BT_AG_CME_ERROR_PH_SIM_PIN_REQUIRED     = 5,
+       BT_AG_CME_ERROR_SIM_NOT_INSERTED        = 10,
+       BT_AG_CME_ERROR_SIM_PIN_REQUIRED        = 11,
+       BT_AG_CME_ERROR_SIM_PUK_REQUIRED        = 12,
+       BT_AG_CME_ERROR_SIM_FAILURE             = 13,
+       BT_AG_CME_ERROR_SIM_BUSY                = 14,
+       BT_AG_CME_ERROR_INCORRECT_PASSWORD      = 16,
+       BT_AG_CME_ERROR_SIM_PIN2_REQUIRED       = 17,
+       BT_AG_CME_ERROR_SIM_PUK2_REQUIRED       = 18,
+       BT_AG_CME_ERROR_MEMORY_FULL             = 20,
+       BT_AG_CME_ERROR_INVALID_INDEX           = 21,
+       BT_AG_CME_ERROR_MEMORY_FAILURE          = 23,
+       BT_AG_CME_ERROR_TEXT_STRING_TOO_LONG    = 24,
+       BT_AG_CME_ERROR_INVALID_TEXT_STRING     = 25,
+       BT_AG_CME_ERROR_DIAL_STRING_TOO_LONG    = 26,
+       BT_AG_CME_ERROR_INVALID_DIAL_STRING     = 27,
+       BT_AG_CME_ERROR_NO_NETWORK_SERVICE      = 30,
+       BT_AG_CME_ERROR_NETWORK_TIMEOUT         = 31,
+       BT_AG_CME_ERROR_NETWORK_NOT_ALLOWED     = 32,
+} bt_ag_cme_error_t;
+
+typedef enum {
+       BT_HF_CALL_DIR_OUTGOING,
+       BT_HF_CALL_DIR_INCOMING,
+} bt_hf_call_direction_t;
+
+/* Call status as per spec */
+typedef enum {
+       BT_HF_CALL_STAT_ACTIVE,
+       BT_HF_CALL_STAT_HELD,
+       BT_HF_CALL_STAT_DIALING,
+       BT_HF_CALL_STAT_ALERTING,
+       BT_HF_CALL_STAT_INCOMING,
+       BT_HF_CALL_STAT_WAITING,
+} bt_hf_call_status_t;
+
+enum hfp_version {
+       HFP_VERSION_1_5 = 0x0105,
+       HFP_VERSION_1_6 = 0x0106,
+       HFP_VERSION_LATEST = HFP_VERSION_1_6,
+};
+
+/*Handsfree supported features*/
+#define BT_HF_FEATURE_EC_ANDOR_NR                      0x0001
+#define BT_HF_FEATURE_CALL_WAITING_AND_3WAY    0x0002
+#define BT_HF_FEATURE_CLI_PRESENTATION         0x0004
+#define BT_HF_FEATURE_VOICE_RECOGNITION                0x0008
+#define BT_HF_FEATURE_REMOTE_VOLUME_CONTROL    0x0010
+#define BT_HF_FEATURE_ENHANCED_CALL_STATUS     0x0020
+#define BT_HF_FEATURE_ENHANCED_CALL_CONTROL    0x0040
+#define BT_HF_FEATURE_CODEC_NEGOTIATION                0x0080
+
+/*AG suported feature*/
+#define BT_AG_FEATURE_3WAY 0x1
+#define BT_AG_FEATURE_NREC     0x0002
+#define BT_AG_FEATURE_EXTENDED_RES_CODE 0x100
+#define BT_AG_FEATURE_CODEC_NEGOTIATION        0x0200
+
+#define BT_HF_CODEC_ID_CVSD 1
+#define BT_HF_CODEC_ID_MSBC 2
+
+#define BT_HF_AUDIO_DISCONNECTED 0
+#define BT_HF_AUDIO_CONNECTED 1
+
+#define BT_MAX_TEL_NUM_STR 100
+
+#define BT_HF_FEATURES "AT+BRSF=%d\r"     /* = 0x7F = All features supported */
+#define BT_HF_INDICATORS_SUPP "AT+CIND=?\r"
+#define BT_HF_INDICATORS_VAL "AT+CIND?\r"
+#define BT_HF_INDICATORS_ENABLE "AT+CMER=3,0,0,1\r"
+#define BT_HF_HOLD_MPTY_SUPP "AT+CHLD=?\r"
+#define BT_HF_CALLER_IDENT_ENABLE "AT+CLIP=1\r"
+#define BT_HF_CARRIER_FORMAT "AT+COPS=3,0\r"
+#define BT_HF_EXTENDED_RESULT_CODE "AT+CMEE=1\r"
+#define BT_HF_INDICATORS_ACTIVATION "AT+BIA="
+#define BT_HF_ANSWER_CALL "ATA\r"
+#define BT_HF_END_CALL "AT+CHUP\r"
+#define BT_HF_REDIAL "AT+BLDN\r"
+#define BT_HF_DIAL_NO "ATD%.100s;\r"
+#define BT_HF_VOICE_RECOGNITION "AT+BVRA=%d\r"
+#define BT_HF_XSAT "AT+XSAT=00,TY,WA\r"
+#define BT_HF_BSSF "AT+BSSF=8\r"
+#define BT_HF_CALLLIST "AT+CLCC\r"
+#define BT_HF_AVAILABLE_CODEC "AT+BAC=%d,%d\r"
+#define BT_HF_CODEC_SELECT "AT+BCS=%d\r"
+#define BT_HF_SPEAKER_GAIN "AT+VGS=%d\r"
+#define BT_HF_DTMF "AT+VTS=%s\r"
+#define BT_HF_NREC "AT+NREC=0\r"
+#define BT_HF_CALLWAIT_NOTI_ENABLE "AT+CCWA=1\r"
+#define BT_HF_RELEASE_ALL "AT+CHLD=0\r"
+#define BT_HF_RELEASE_AND_ACCEPT "AT+CHLD=1\r"
+#define BT_HF_ACCEPT_AND_HOLD "AT+CHLD=2\r"
+#define BT_HF_JOIN_CALL "AT+CHLD=3\r"
+
+#define BT_MAX_EVENT_STR_LENGTH         50
+#define BT_AGENT_SYSPOPUP_TIMEOUT_FOR_MULTIPLE_POPUPS 200
+
+#define BT_HF_MAX_SPEAKER_GAIN 15
+#define BT_HF_MIN_SPEAKER_GAIN 0
+
+
+typedef enum {
+       BT_AGENT_EVENT_HANDSFREE_CONNECT = 0x1100,
+       BT_AGENT_EVENT_HANDSFREE_DISCONNECT = 0x1200,
+} bt_hfp_agent_event_type_t;
+
+/* Hold and multipary AG features.
+ * Comments below are copied from hands-free spec for reference */
+/* Releases all held calls or sets User Determined User Busy (UDUB)
+ * for a waiting call */
+#define BT_HF_CHLD_0 0x01
+/* Releases all active calls (if any exist) and accepts the other
+ * (held or waiting) call */
+#define BT_HF_CHLD_1 0x02
+/* Releases specified active call only <x> */
+#define BT_HF_CHLD_1x 0x04
+/* Places all active calls (if any exist) on hold and accepts the other
+ * (held or waiting) call */
+#define BT_HF_CHLD_2 0x08
+/* Request private consultation mode with specified call <x> (Place all
+ * calls on hold EXCEPT the call <x>) */
+#define BT_HF_CHLD_2x 0x10
+/* Adds a held call to the conversation */
+#define BT_HF_CHLD_3 0x20
+/* Connects the two calls and disconnects the subscriber from both calls
+ * (Explicit Call Transfer). Support for this value and its associated
+ * functionality is optional for the HF. */
+#define BT_HF_CHLD_4 0x40
+
+#define BT_HF_OK_RESPONSE "\r\nOK\r\n"
+#define BT_HF_ERROR_RESPONSE "ERROR"
+#define BT_HF_SEC_ERROR_RESPONSE "SERR"
+
+#define BT_HF_SERVICE_NAME "org.bluez.hf_agent"
+#define BT_HF_AGENT_OBJECT_PATH "/org/bluez/handsfree_agent"
+#define BT_HF_SERVICE_INTERFACE "org.tizen.HfApp"
+
+#define BT_HF_BLUEZ_OBJECT_PATH "/org/tizen/handsfree"
+#define BT_HF_BLUEZ_INTERFACE  "org.bluez.HandsfreeAgent"
+
+#define BLUEZ_SERVICE_NAME "org.bluez"
+#define BLUEZ_HF_INTERFACE_NAME "org.bluez.HandsfreeGateway"
+
+#define PM_SERVICE_NAME "org.tizen.system.deviced"
+#define PM_OBJECT_PATH "/Org/Tizen/System/DeviceD/Display"
+#define PM_INTERFACE_NAME "org.tizen.system.deviced.display"
+#define AT_CMD_BUFF_SIZE 500
+#define BLUEZ_PROFILE_MGMT_INTERFACE "org.bluez.ProfileManager1"
+#define BT_MANAGER_INTERFACE "org.freedesktop.DBus.ObjectManager"
+#define BT_ADAPTER_INTERFACE   "org.bluez.Adapter1"
+
+#define retv_if(expr, val) \
+       do { \
+               if (expr) { \
+                       ERR("(%s) return", #expr); \
+                       return (val); \
+               } \
+       } while (0)
+
+typedef enum {
+       BT_HF_STATE_DISCONNECTED,
+       BT_HF_STATE_CONNECTED
+} bt_hf_state_t;
+
+typedef struct {
+       guint32 fd;
+       gint sco_fd;
+       gint cli_sco_fd;
+
+       GIOChannel *io_chan;
+       GIOChannel *sco_io_chan;
+       bt_hf_state_t state;
+
+       guint watch_id;
+       guint sco_watch_id;
+       guint cli_sco_watch_id;
+
+       guint ag_features;
+       guint hold_multiparty_features;
+       GSList *indies;
+
+       gboolean is_dialing;
+       gboolean call_active;
+
+       guint ciev_call_status;
+       guint ciev_call_setup_status;
+
+       guint32 feature;
+
+       char *remote_addr;
+       int slc;
+       GSList *cmd_list;
+       GSList *cmd_send_queue;
+
+       GDBusMethodInvocation *context;
+       char *path;
+}bt_hf_agent_info_t;
+
+typedef struct {
+       int id;
+       char at_cmd[AT_CMD_BUFF_SIZE];
+       int count;
+       GDBusMethodInvocation *context;
+       int pending;
+       int timer_id;
+} bt_hf_agent_send_at_info;
+
+struct hf_event {
+       const char *cmd;
+       int (*callback) (bt_hf_agent_info_t *bt_hf_info, const char *buf);
+};
+
+typedef struct {
+       unsigned char b[6];
+} __attribute__((packed)) bdaddr_t;
+
+/* Remote socket address */
+struct sockaddr_remote {
+       sa_family_t     family;
+       bdaddr_t        remote_bdaddr;
+       uint8_t         channel;
+};
+
+/* SCO socket address */
+struct sockaddr_sco {
+       sa_family_t     sco_family;
+       bdaddr_t        sco_bdaddr;
+};
+
+#endif /* __DEF_BT_HF_AGENT_H_ */
diff --git a/hf-agent/org.bluez.hf_agent.service b/hf-agent/org.bluez.hf_agent.service
new file mode 100644 (file)
index 0000000..f63552c
--- /dev/null
@@ -0,0 +1,4 @@
+[D-BUS Service]
+Name=org.bluez.hf_agent
+Exec=/usr/bin/bluetooth-hf-agent
+User=root
diff --git a/hfp-agent/CMakeLists.txt b/hfp-agent/CMakeLists.txt
deleted file mode 100644 (file)
index f442ac2..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-PROJECT(bluetooth-hfp-agent C)
-
-SET(SRCS bluetooth-hfp-agent.c)
-
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
-
-INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs_hfp_agent
-               REQUIRED
-               dbus-glib-1 vconf appsvc contacts-service2 tapi)
-
-FOREACH(flag ${pkgs_hfp_agent_CFLAGS})
-       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-
-FIND_PROGRAM(DBUS_BINDING_TOOL NAMES dbus-binding-tool)
-EXEC_PROGRAM("${DBUS_BINDING_TOOL}"
-               ARGS "--prefix=bt_hfp_agent \\
-               ${CMAKE_CURRENT_SOURCE_DIR}/hfp_agent.xml \\
-               --mode=glib-server \\
-               --output=${CMAKE_CURRENT_SOURCE_DIR}/bluetooth_hfp_agent_glue.h")
-
-ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_hfp_agent_LDFLAGS})
-
-INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.bluez.hfp_agent.service
-               DESTINATION share/dbus-1/system-services)
diff --git a/hfp-agent/bluetooth-hfp-agent.c b/hfp-agent/bluetooth-hfp-agent.c
deleted file mode 100644 (file)
index 388eb89..0000000
+++ /dev/null
@@ -1,1859 +0,0 @@
-/*
- * bluetooth-agent
- *
- * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
- *
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <glib.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib-lowlevel.h>
-#include <signal.h>
-
-#include <TapiUtility.h>
-#include <ITapiSim.h>
-
-#include "vconf.h"
-#include "vconf-keys.h"
-#include "contacts.h"
-#include "appsvc.h"
-
-#include "bluetooth-hfp-agent.h"
-
-static GMainLoop *gmain_loop = NULL;
-static DBusGConnection *g_connection = NULL;
-static DBusConnection *gconn = NULL;
-static gboolean nrec_status = FALSE;
-
-#define BT_ERROR_INTERNAL "InternalError"
-#define BT_ERROR_NOT_AVAILABLE "NotAvailable"
-#define BT_ERROR_NOT_CONNECTED "NotConnected"
-#define BT_ERROR_BUSY "InProgress"
-#define BT_ERROR_INVALID_PARAM "InvalidArguments"
-#define BT_ERROR_ALREADY_EXSIST "AlreadyExists"
-#define BT_ERROR_ALREADY_CONNECTED "Already Connected"
-#define BT_ERROR_NO_MEMORY "No memory"
-#define BT_ERROR_I_O_ERROR "I/O error"
-#define BT_ERROR_OPERATION_NOT_AVAILABLE "Operation currently not available"
-#define BT_ERROR_BATTERY "Battery error "
-#define BT_ERROR_SIGNAL "Signal error"
-#define BT_ERROR_NO_CALL_LOG "No Call log"
-#define BT_ERROR_INVLAID_DTMF "Invalid dtmf"
-
-#define BLUEZ_SERVICE_NAME "org.bluez"
-#define TELEPHONY_CSD_INTERFACE "org.tizen.telephony.csd"
-#define TELEPHONY_CSD_OBJECT_PATH "/org/tizen/csd"
-#define TELEPHONY_APP_INTERFACE "org.tizen.csd.Call.Instance"
-
-#define BT_HFP_AGENT_SET_PROPERTY "SetProperty"
-
-#define BT_HFP_AGENT_OBJECT "/org/bluez/agent/hfp_agent"
-#define BT_HFP_AGENT_INTERFACE "org.bluez.hfp_agent"
-
-#define BT_SIGNAL_ARRAY_MAX 2
-
-/* AT+CSQ : Returns received signal strength indication.
-     Command response: +CSQ: <rssi>,<ber>
-    <ber> is not supported and has a constant value of 99, included for compatibility reasons.
-*/
-#define BT_SIGNAL_QUALITY_BER 99
-
-/*Length of the string used to send telephone number to app-svc
-   format: tel:<number>
-*/
-#define BT_MAX_TEL_NUM_STRING 20
-
-typedef struct {
-       GObject parent;
-} BtHfpAgent;
-
-typedef struct {
-       GObjectClass parent;
-} BtHfpAgentClass;
-
-GType bt_hfp_agent_get_type(void);
-
-#define BT_HFP_TYPE_AGENT (bt_hfp_agent_get_type())
-
-#define BT_HFP_AGENT(object)(G_TYPE_CHECK_INSTANCE_CAST((object), \
-                       BT_HFP_TYPE_AGENT , BtHfpAgent))
-
-#define BT_HFP_AGENT_CLASS(klass)(G_TYPE_CHECK_CLASS_CAST((klass), \
-                       BT_HFP_TYPE_AGENT , BtHfpAgentClass))
-
-#define BT_IS_HFP_AGENT(object)(G_TYPE_CHECK_INSTANCE_TYPE((object), \
-                       BT_HFP_TYPE_AGENT))
-
-#define BT_IS_HFP_AGENT_CLASS(klass)(G_TYPE_CHECK_CLASS_TYPE((klass), \
-                       BT_HFP_TYPE_AGENT))
-
-#define BT_HFP_AGENT_GET_CLASS(obj)(G_TYPE_INSTANCE_GET_CLASS((obj), \
-                       BT_HFP_TYPE_AGENT , BtHfpAgentClass))
-
-G_DEFINE_TYPE(BtHfpAgent, bt_hfp_agent, G_TYPE_OBJECT)
-
-static gboolean bt_hfp_agent_register_application(BtHfpAgent *agent,
-                               const gchar *path, DBusGMethodInvocation *context);
-
-static gboolean bt_hfp_agent_unregister_application(BtHfpAgent *agent,
-                               const gchar *path, DBusGMethodInvocation *context);
-
-static gboolean bt_hfp_agent_incoming_call(BtHfpAgent *agent, const gchar *path,
-                               const gchar *number, gint call_id,
-                               DBusGMethodInvocation *context);
-
-static gboolean bt_hfp_agent_outgoing_call(BtHfpAgent *agent, const gchar *path,
-                               const gchar *number, gint call_id,
-                               DBusGMethodInvocation *context);
-
-static gboolean bt_hfp_agent_change_call_status(BtHfpAgent *agent,
-                               const gchar *path, gint status, gint call_id,
-                               DBusGMethodInvocation *context);
-
-static gboolean bt_hfp_agent_answer_call(BtHfpAgent *agent, unsigned int call_id,
-                               const gchar *path, const gchar *sender,
-                               DBusGMethodInvocation *context);
-
-static gboolean bt_hfp_agent_release_call(BtHfpAgent *agent, unsigned int call_id,
-                               const gchar *path, const gchar *sender,
-                               DBusGMethodInvocation *context);
-
-static gboolean bt_hfp_agent_reject_call(BtHfpAgent *agent, unsigned int call_id,
-                               const gchar *path, const gchar *sender,
-                               DBusGMethodInvocation *context);
-
-static gboolean bt_hfp_agent_threeway_call(BtHfpAgent *agent, gint call_id,
-                               const gchar *path, const gchar *sender,
-                               DBusGMethodInvocation *context);
-
-static gboolean bt_hfp_agent_dial_last_num(BtHfpAgent *agent,
-                               DBusGMethodInvocation *context);
-
-static gboolean bt_hfp_agent_dial_num(BtHfpAgent *agent,
-                               const gchar *number, guint flags,
-                               DBusGMethodInvocation *context);
-
-static gboolean bt_hfp_agent_dial_memory(BtHfpAgent *agent, gint location,
-                               DBusGMethodInvocation *context);
-
-static gboolean bt_hfp_agent_send_dtmf(BtHfpAgent *agent, const gchar *dtmf,
-                               const gchar *path, const gchar *sender,
-                               DBusGMethodInvocation *context);
-
-static gboolean bt_hfp_agent_voice_dial(BtHfpAgent *agent, gboolean activate,
-                               DBusGMethodInvocation *context);
-
-static gboolean bt_hfp_agent_get_battery_status(BtHfpAgent *object,
-                               DBusGMethodInvocation *context);
-
-static gboolean bt_hfp_agent_get_signal_quality(BtHfpAgent *object,
-                               DBusGMethodInvocation *context);
-
-static gboolean bt_hfp_agent_get_properties(BtHfpAgent *agent,
-                               DBusGMethodInvocation *context);
-
-static gboolean bt_hfp_agent_get_operator_name(BtHfpAgent *object,
-                               DBusGMethodInvocation *context);
-
-static gboolean bt_hfp_agent_nrec_status(BtHfpAgent *agent, gboolean status,
-                               DBusGMethodInvocation *context);
-
-#include "bluetooth_hfp_agent_glue.h"
-
-static void bt_hfp_agent_init(BtHfpAgent *obj)
-{
-       DBG("+\n");
-
-       g_assert(obj != NULL);
-}
-
-static void bt_hfp_agent_finalize(GObject *obj)
-{
-       DBG("+\n");
-
-       G_OBJECT_CLASS(bt_hfp_agent_parent_class)->finalize(obj);
-}
-
-static void bt_hfp_agent_class_init(BtHfpAgentClass *klass)
-{
-       DBG("+\n");
-
-       GObjectClass *object_class = (GObjectClass *)klass;
-
-       g_assert(klass != NULL);
-
-       object_class->finalize = bt_hfp_agent_finalize;
-
-       dbus_g_object_type_install_info(BT_HFP_TYPE_AGENT,
-                                       &dbus_glib_bt_hfp_agent_object_info);
-}
-
-static GQuark __bt_hfp_agent_error_quark(void)
-{
-       DBG("+\n");
-
-       static GQuark quark = 0;
-       if (!quark)
-               quark = g_quark_from_static_string("agent");
-
-       return quark;
-}
-
-static GError *__bt_hfp_agent_set_error(bt_hfp_agent_error_t error)
-{
-       DBG("+\n");
-
-       switch (error) {
-       case BT_HFP_AGENT_ERROR_NOT_AVAILABLE:
-               return g_error_new(BT_HFP_AGENT_ERROR, error,
-                                               BT_ERROR_NOT_AVAILABLE);
-       case BT_HFP_AGENT_ERROR_NOT_CONNECTED:
-               return g_error_new(BT_HFP_AGENT_ERROR, error,
-                                               BT_ERROR_NOT_CONNECTED);
-       case BT_HFP_AGENT_ERROR_BUSY:
-               return g_error_new(BT_HFP_AGENT_ERROR, error,
-                                               BT_ERROR_BUSY);
-       case BT_HFP_AGENT_ERROR_INVALID_PARAM:
-               return g_error_new(BT_HFP_AGENT_ERROR, error,
-                                               BT_ERROR_INVALID_PARAM);
-       case BT_HFP_AGENT_ERROR_ALREADY_EXSIST:
-               return g_error_new(BT_HFP_AGENT_ERROR, error,
-                                               BT_ERROR_ALREADY_EXSIST);
-       case BT_HFP_AGENT_ERROR_ALREADY_CONNECTED:
-               return g_error_new(BT_HFP_AGENT_ERROR, error,
-                                               BT_ERROR_ALREADY_CONNECTED);
-       case BT_HFP_AGENT_ERROR_NO_MEMORY:
-               return g_error_new(BT_HFP_AGENT_ERROR, error,
-                                               BT_ERROR_NO_MEMORY);
-       case BT_HFP_AGENT_ERROR_I_O_ERROR:
-               return g_error_new(BT_HFP_AGENT_ERROR, error,
-                                               BT_ERROR_I_O_ERROR);
-       case BT_HFP_AGENT_ERROR_OPERATION_NOT_AVAILABLE:
-               return g_error_new(BT_HFP_AGENT_ERROR, error,
-                                       BT_ERROR_OPERATION_NOT_AVAILABLE);
-       case BT_HFP_AGENT_ERROR_BATTERY_STATUS:
-               return g_error_new(BT_HFP_AGENT_ERROR, error,
-                                       BT_ERROR_BATTERY);
-       case BT_HFP_AGENT_ERROR_SIGNAL_STATUS:
-               return g_error_new(BT_HFP_AGENT_ERROR, error,
-                                       BT_ERROR_SIGNAL);
-       case BT_HFP_AGENT_ERROR_NO_CALL_LOGS:
-               return g_error_new(BT_HFP_AGENT_ERROR, error,
-                                       BT_ERROR_NO_CALL_LOG);
-       case BT_HFP_AGENT_ERROR_INTERNAL:
-       default:
-               return g_error_new(BT_HFP_AGENT_ERROR, error,
-                                               BT_ERROR_INTERNAL);
-       }
-}
-
-static int __bt_hfp_agent_get_error(const char *error_message)
-{
-       if (error_message == NULL) {
-               DBG("Error message NULL\n");
-               return BT_HFP_AGENT_ERROR_INTERNAL;
-       }
-
-       DBG("Error message = %s \n", error_message);
-
-       if (g_strcmp0(error_message, BT_ERROR_NOT_AVAILABLE) == 0)
-               return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
-       else if (g_strcmp0(error_message, BT_ERROR_NOT_CONNECTED) == 0)
-               return BT_HFP_AGENT_ERROR_NOT_CONNECTED;
-       else if (g_strcmp0(error_message, BT_ERROR_BUSY) == 0)
-               return BT_HFP_AGENT_ERROR_BUSY;
-       else if (g_strcmp0(error_message, BT_ERROR_INVALID_PARAM) == 0)
-               return BT_HFP_AGENT_ERROR_INVALID_PARAM;
-       else if (g_strcmp0(error_message, BT_ERROR_ALREADY_EXSIST) == 0)
-               return BT_HFP_AGENT_ERROR_ALREADY_EXSIST;
-       else if (g_strcmp0(error_message, BT_ERROR_ALREADY_CONNECTED) == 0)
-               return BT_HFP_AGENT_ERROR_ALREADY_CONNECTED;
-       else if (g_strcmp0(error_message, BT_ERROR_NO_MEMORY) == 0)
-               return BT_HFP_AGENT_ERROR_NO_MEMORY;
-       else if (g_strcmp0(error_message, BT_ERROR_I_O_ERROR) == 0)
-               return BT_HFP_AGENT_ERROR_I_O_ERROR;
-       else if (g_strcmp0(error_message,
-                               BT_ERROR_OPERATION_NOT_AVAILABLE) == 0)
-               return BT_HFP_AGENT_ERROR_OPERATION_NOT_AVAILABLE;
-       else if (g_strcmp0(error_message, BT_ERROR_INVLAID_DTMF) == 0)
-               return BT_HFP_AGENT_ERROR_INVALID_DTMF;
-       else
-               return BT_HFP_AGENT_ERROR_INTERNAL;
-}
-
-static int __bt_hfp_agent_dbus_method_send(const char *service,
-                               const char *path, const char *interface,
-                               const char *method, gboolean response,
-                               int type, ...)
-{
-       DBusMessage *msg;
-       DBusMessage *reply;
-       DBusError err;
-       va_list args;
-       int error;
-
-       DBG("__bt_hfp_agent_dbus_method_send +\n");
-
-       msg = dbus_message_new_method_call(service, path, interface,
-                                                               method);
-       if (!msg) {
-               DBG("Unable to allocate new D-Bus %s message \n", method);
-               return BT_HFP_AGENT_ERROR_INTERNAL;
-       }
-
-       va_start(args, type);
-
-       if (!dbus_message_append_args_valist(msg, type, args)) {
-               dbus_message_unref(msg);
-               va_end(args);
-               return BT_HFP_AGENT_ERROR_INTERNAL;
-       }
-
-       va_end(args);
-
-       dbus_error_init(&err);
-
-       if (response) {
-               reply = dbus_connection_send_with_reply_and_block(gconn,
-                                                       msg, -1, &err);
-               dbus_message_unref(msg);
-
-               if (!reply) {
-                       DBG("Error returned in method call\n");
-                       if (dbus_error_is_set(&err)) {
-                               error = __bt_hfp_agent_get_error(err.message);
-                               dbus_error_free(&err);
-                               return error;
-                       } else {
-                               DBG("Error is not set\n");
-                               return BT_HFP_AGENT_ERROR_INTERNAL;
-                       }
-               }
-               dbus_message_unref(reply);
-       } else {
-               dbus_connection_send(gconn, msg, NULL);
-               dbus_message_unref(msg);
-       }
-
-       DBG("__bt_hfp_agent_dbus_method_send -\n");
-
-       return BT_HFP_AGENT_ERROR_NONE;
-}
-
-static gboolean bt_hfp_agent_register_application(BtHfpAgent *agent,
-                               const gchar *path, DBusGMethodInvocation *context)
-{
-       gboolean flag = TRUE;
-       char *sender;
-       GError *error;
-       int ret;
-
-       DBG("bt_hfp_agent_register_application + \n");
-
-       if (path == NULL) {
-               DBG("Invalid Argument path\n");
-               error = __bt_hfp_agent_set_error(
-                                       BT_HFP_AGENT_ERROR_INVALID_PARAM);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       DBG("Application path = %s\n", path);
-
-       sender = dbus_g_method_get_sender(context);
-
-       DBG("Sender = %s\n", sender);
-
-       ret = __bt_hfp_agent_dbus_method_send(BLUEZ_SERVICE_NAME,
-                               TELEPHONY_CSD_OBJECT_PATH,
-                               TELEPHONY_CSD_INTERFACE,
-                               "RegisterTelephonyAgent", TRUE,
-                               DBUS_TYPE_BOOLEAN, &flag,
-                               DBUS_TYPE_STRING, &path,
-                               DBUS_TYPE_STRING, &sender, DBUS_TYPE_INVALID);
-       g_free(sender);
-
-       if (ret != BT_HFP_AGENT_ERROR_NONE) {
-               error = __bt_hfp_agent_set_error(ret);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       dbus_g_method_return(context);
-
-       DBG("bt_hfp_agent_register_application - \n");
-       return TRUE;
-}
-
-static gboolean bt_hfp_agent_unregister_application(BtHfpAgent *agent,
-                               const gchar *path, DBusGMethodInvocation *context)
-{
-       gboolean flag = FALSE;
-       char *sender;
-       GError *error;
-       int ret;
-
-       DBG("bt_hfp_agent_unregister_application + \n");
-
-       if (path == NULL) {
-               DBG("Invalid Argument path\n");
-               error = __bt_hfp_agent_set_error(
-                                       BT_HFP_AGENT_ERROR_INVALID_PARAM);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       DBG("Application path = %s \n", path);
-
-       sender = dbus_g_method_get_sender(context);
-
-       DBG("Sender = %s\n", sender);
-
-       ret = __bt_hfp_agent_dbus_method_send(BLUEZ_SERVICE_NAME,
-                               TELEPHONY_CSD_OBJECT_PATH,
-                               TELEPHONY_CSD_INTERFACE,
-                               "RegisterTelephonyAgent", TRUE,
-                               DBUS_TYPE_BOOLEAN, &flag,
-                               DBUS_TYPE_STRING, &path,
-                               DBUS_TYPE_STRING, &sender, DBUS_TYPE_INVALID);
-       g_free(sender);
-
-       if (ret != BT_HFP_AGENT_ERROR_NONE) {
-               error = __bt_hfp_agent_set_error(ret);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       dbus_g_method_return(context);
-
-       DBG("bt_hfp_agent_unregister_application - \n");
-       return TRUE;
-}
-
-static gboolean bt_hfp_agent_incoming_call(BtHfpAgent *agent, const gchar *path,
-                               const gchar *number, gint call_id,
-                               DBusGMethodInvocation *context)
-{
-       GError *error;
-       char *sender;
-       int ret;
-
-       DBG("bt_hfp_agent_incoming_call + \n");
-
-       if (path == NULL || number == NULL) {
-               DBG("Invalid Arguments\n");
-               error = __bt_hfp_agent_set_error(
-                                       BT_HFP_AGENT_ERROR_INVALID_PARAM);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       DBG("Application path = %s\n", path);
-       DBG("Phone number = %s\n", number);
-       DBG("Call id = %d\n", call_id);
-
-       sender = dbus_g_method_get_sender(context);
-
-       DBG("Sender = %s\n", sender);
-
-       ret = __bt_hfp_agent_dbus_method_send(BLUEZ_SERVICE_NAME,
-                               TELEPHONY_CSD_OBJECT_PATH,
-                               TELEPHONY_CSD_INTERFACE,
-                               "Incoming", TRUE,
-                               DBUS_TYPE_STRING, &path,
-                               DBUS_TYPE_STRING, &number,
-                               DBUS_TYPE_UINT32, &call_id,
-                               DBUS_TYPE_STRING, &sender,
-                               DBUS_TYPE_INVALID);
-       g_free(sender);
-
-       if (ret != BT_HFP_AGENT_ERROR_NONE) {
-               error = __bt_hfp_agent_set_error(ret);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       dbus_g_method_return(context);
-
-       DBG("bt_hfp_agent_incoming_call - \n");
-       return TRUE;
-}
-
-static gboolean bt_hfp_agent_outgoing_call(BtHfpAgent *agent, const gchar *path,
-                               const gchar *number, gint call_id,
-                               DBusGMethodInvocation *context)
-{
-       GError *error;
-       char *sender;
-       int ret;
-
-       DBG("bt_hfp_agent_outgoing_call + \n");
-
-       if (path == NULL || number == NULL) {
-               DBG("Invalid Arguments\n");
-               error = __bt_hfp_agent_set_error(
-                                       BT_HFP_AGENT_ERROR_INVALID_PARAM);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       DBG("Application path = %s\n", path);
-       DBG("Phone number = %s\n", number);
-       DBG("Call id = %d\n", call_id);
-
-       sender = dbus_g_method_get_sender(context);
-
-       DBG("Sender = %s\n", sender);
-
-       ret = __bt_hfp_agent_dbus_method_send(BLUEZ_SERVICE_NAME,
-                               TELEPHONY_CSD_OBJECT_PATH,
-                               TELEPHONY_CSD_INTERFACE,
-                               "Outgoing", TRUE,
-                               DBUS_TYPE_STRING, &path,
-                               DBUS_TYPE_STRING, &number,
-                               DBUS_TYPE_UINT32, &call_id,
-                               DBUS_TYPE_STRING, &sender,
-                               DBUS_TYPE_INVALID);
-       g_free(sender);
-
-       if (ret != BT_HFP_AGENT_ERROR_NONE) {
-               error = __bt_hfp_agent_set_error(ret);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       dbus_g_method_return(context);
-
-       DBG("bt_hfp_agent_outgoing_call - \n");
-       return TRUE;
-}
-
-static gboolean bt_hfp_agent_change_call_status(BtHfpAgent *agent,
-                               const gchar *path, gint status, gint call_id,
-                               DBusGMethodInvocation *context)
-{
-       GError *error;
-       char *sender;
-       int ret;
-
-       DBG("bt_hfp_agent_change_call_status + \n");
-
-       if (path == NULL) {
-               DBG("Invalid Argument path\n");
-               error = __bt_hfp_agent_set_error(
-                                       BT_HFP_AGENT_ERROR_INVALID_PARAM);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       DBG("Application path = %s\n", path);
-       DBG("Status = %d\n", status);
-       DBG("Call id = %d\n", call_id);
-
-       sender = dbus_g_method_get_sender(context);
-
-       DBG("Sender = %s\n", sender);
-
-       ret = __bt_hfp_agent_dbus_method_send(BLUEZ_SERVICE_NAME,
-                               TELEPHONY_CSD_OBJECT_PATH,
-                               TELEPHONY_CSD_INTERFACE,
-                               "SetCallStatus", TRUE,
-                               DBUS_TYPE_STRING, &path,
-                               DBUS_TYPE_UINT32, &status,
-                               DBUS_TYPE_UINT32, &call_id,
-                               DBUS_TYPE_STRING, &sender,
-                               DBUS_TYPE_INVALID);
-       g_free(sender);
-
-       if (ret != BT_HFP_AGENT_ERROR_NONE) {
-               error = __bt_hfp_agent_set_error(ret);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       dbus_g_method_return(context);
-
-       DBG("bt_hfp_agent_change_call_status - \n");
-       return TRUE;
-}
-
-static gboolean bt_hfp_agent_answer_call(BtHfpAgent *agent, unsigned int call_id,
-                               const gchar *path, const gchar *sender,
-                               DBusGMethodInvocation *context)
-{
-       int ret;
-       GError *error;
-       DBG("+\n");
-
-       if (path == NULL || sender == NULL) {
-               DBG("Invalid Arguments\n");
-               error = __bt_hfp_agent_set_error(
-                                       BT_HFP_AGENT_ERROR_INVALID_PARAM);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       DBG("Application path = %s \n", path);
-       DBG("Call Id = %d", call_id);
-       DBG("Sender = %s\n", sender);
-
-       ret = __bt_hfp_agent_dbus_method_send(sender,
-                               path, TELEPHONY_APP_INTERFACE,
-                               "Answer", FALSE,
-                               DBUS_TYPE_UINT32, &call_id,
-                               DBUS_TYPE_INVALID);
-
-       if (ret != BT_HFP_AGENT_ERROR_NONE) {
-               error = __bt_hfp_agent_set_error(ret);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       dbus_g_method_return(context);
-
-       DBG("-\n");
-       return TRUE;
-}
-
-static gboolean bt_hfp_agent_release_call(BtHfpAgent *agent, unsigned int call_id,
-                               const gchar *path, const gchar *sender,
-                               DBusGMethodInvocation *context)
-{
-       int ret;
-       GError *error;
-       DBG("+\n");
-
-       if (path == NULL || sender == NULL) {
-               DBG("Invalid Arguments\n");
-               error = __bt_hfp_agent_set_error(
-                                       BT_HFP_AGENT_ERROR_INVALID_PARAM);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       DBG("Application path = %s \n", path);
-       DBG("Call Id = %d", call_id);
-       DBG("Sender = %s\n", sender);
-
-       ret = __bt_hfp_agent_dbus_method_send(sender,
-                               path, TELEPHONY_APP_INTERFACE,
-                               "Release", FALSE,
-                               DBUS_TYPE_UINT32, &call_id,
-                               DBUS_TYPE_INVALID);
-
-       if (ret != BT_HFP_AGENT_ERROR_NONE) {
-               error = __bt_hfp_agent_set_error(ret);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       dbus_g_method_return(context);
-       DBG("-\n");
-       return TRUE;
-}
-
-static gboolean bt_hfp_agent_reject_call(BtHfpAgent *agent, unsigned int call_id,
-                               const gchar *path, const gchar *sender,
-                               DBusGMethodInvocation *context)
-{
-       int ret;
-       GError *error;
-       DBG("+\n");
-
-       if (path == NULL || sender == NULL) {
-               DBG("Invalid Arguments\n");
-               error = __bt_hfp_agent_set_error(
-                                       BT_HFP_AGENT_ERROR_INVALID_PARAM);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       DBG("Application path = %s \n", path);
-       DBG("Call Id = %d", call_id);
-       DBG("Sender = %s\n", sender);
-
-       ret = __bt_hfp_agent_dbus_method_send(sender,
-                               path, TELEPHONY_APP_INTERFACE,
-                               "Reject", FALSE,
-                               DBUS_TYPE_UINT32, &call_id,
-                               DBUS_TYPE_INVALID);
-
-       if (ret != BT_HFP_AGENT_ERROR_NONE) {
-               error = __bt_hfp_agent_set_error(ret);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       dbus_g_method_return(context);
-       DBG("-\n");
-       return TRUE;
-}
-
-static gboolean bt_hfp_agent_threeway_call(BtHfpAgent *agent, gint value,
-                               const gchar *path, const gchar *sender,
-                               DBusGMethodInvocation *context)
-{
-       int ret;
-       GError *error;
-       DBG("+\n");
-
-       if (path == NULL || sender == NULL) {
-               DBG("Invalid Arguments\n");
-               error = __bt_hfp_agent_set_error(
-                                       BT_HFP_AGENT_ERROR_INVALID_PARAM);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       DBG("Application path = %s \n", path);
-       DBG("Value = %d", value);
-       DBG("Sender = %s\n", sender);
-
-       ret = __bt_hfp_agent_dbus_method_send(sender,
-                               path, TELEPHONY_APP_INTERFACE,
-                               "Threeway", TRUE,
-                               DBUS_TYPE_UINT32, &value,
-                               DBUS_TYPE_INVALID);
-
-       if (ret != BT_HFP_AGENT_ERROR_NONE) {
-               error = __bt_hfp_agent_set_error(ret);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       dbus_g_method_return(context);
-       DBG("-\n");
-       return TRUE;
-}
-
-void __bt_append_entry(DBusMessageIter *iter,
-                       const char *key, int type, void *val)
-{
-       DBusMessageIter entry;
-       DBusMessageIter value;
-       const char *str;
-       char signal[BT_SIGNAL_ARRAY_MAX] = { type, '\0' };
-
-       if (type == DBUS_TYPE_STRING) {
-               str = *((const char **) val);
-               if (str == NULL) {
-                       return;
-               }
-       }
-
-       dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY,
-                                                       NULL, &entry);
-       dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
-
-       dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
-                                               signal, &value);
-
-       dbus_message_iter_append_basic(&value, type, val);
-
-       dbus_message_iter_close_container(&entry, &value);
-
-       dbus_message_iter_close_container(iter, &entry);
-}
-
-static gboolean bt_hfp_agent_get_properties(BtHfpAgent *agent,
-                               DBusGMethodInvocation *context)
-{
-       DBusMessage *reply;
-       DBusMessageIter iter;
-       DBusMessageIter dict;
-       GError *error;
-
-       DBG("bt_hfp_agent_get_properties + \n");
-
-       reply = dbus_g_method_get_reply(context);
-       if (!reply) {
-               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INTERNAL);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       dbus_message_iter_init_append(reply, &iter);
-
-       dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
-                       DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
-                       DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
-                       DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
-
-       __bt_append_entry(&dict, "nrec", DBUS_TYPE_BOOLEAN, &nrec_status);
-       dbus_message_iter_close_container(&iter, &dict);
-       dbus_g_method_send_reply(context, reply);
-       DBG("bt_hfp_agent_get_properties - \n");
-       return TRUE;
-}
-
-static gboolean __bt_hfp_agent_make_call(const char *number)
-{
-       bundle *b;
-       char telnum[BT_MAX_TEL_NUM_STRING];
-
-       b = bundle_create();
-       if (NULL == b)
-               return FALSE;
-
-       appsvc_set_operation(b, APPSVC_OPERATION_CALL);
-       snprintf(telnum, sizeof(telnum), "tel:%s", number);
-       appsvc_set_uri(b, telnum);
-       appsvc_add_data(b, "ctindex", "-1");
-       appsvc_run_service(b, 0, NULL, NULL);
-       bundle_free(b);
-
-       return TRUE;
-}
-
-static gboolean bt_hfp_agent_dial_last_num(BtHfpAgent *agent,
-                               DBusGMethodInvocation *context)
-{
-       GError *error;
-       int error_code = BT_HFP_AGENT_ERROR_NONE;
-       char *last_number = NULL;
-       contacts_list_h list = NULL;
-       contacts_query_h query = NULL;
-       contacts_filter_h filter = NULL;
-       contacts_record_h record = NULL;
-       unsigned int projections[] = {
-               _contacts_phone_log.address,
-       };
-
-       DBG("+ \n");
-
-       if (contacts_connect2() != CONTACTS_ERROR_NONE) {
-               ERR(" contacts_connect2 failed \n");
-               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INTERNAL);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       contacts_filter_create(_contacts_phone_log._uri, &filter);
-
-       if (filter == NULL)
-               goto done;
-
-       if (contacts_filter_add_int(filter, _contacts_phone_log.log_type,
-                               CONTACTS_MATCH_EQUAL,
-                               CONTACTS_PLOG_TYPE_VOICE_OUTGOING) !=
-                               CONTACTS_ERROR_NONE) {
-               ERR(" contacts_filter_add_int failed \n");
-               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
-               goto done;
-       }
-
-       if (contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_OR) !=
-                               CONTACTS_ERROR_NONE) {
-               ERR(" contacts_filter_add_operator failed \n");
-               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
-               goto done;
-       }
-
-       if (contacts_filter_add_int(filter, _contacts_phone_log.log_type,
-                               CONTACTS_MATCH_EQUAL,
-                               CONTACTS_PLOG_TYPE_VIDEO_OUTGOING) !=
-                               CONTACTS_ERROR_NONE) {
-               ERR(" contacts_filter_add_int failed \n");
-               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
-               goto done;
-       }
-
-       contacts_query_create(_contacts_phone_log._uri, &query);
-
-       if (query == NULL)
-               goto done;
-
-       contacts_query_set_filter(query, filter);
-
-       if (contacts_query_set_projection(query, projections,
-                               sizeof(projections)/sizeof(unsigned int)) !=
-                               CONTACTS_ERROR_NONE) {
-               ERR(" contacts_query_set_projection failed \n");
-               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
-               goto done;
-       }
-
-       if (contacts_query_set_sort(query, _contacts_phone_log.log_time, false) !=
-                               CONTACTS_ERROR_NONE) {
-               ERR(" contacts_query_set_sort failed \n");
-               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
-               goto done;
-       }
-
-       if (contacts_db_get_records_with_query(query, 0, 1, &list)  !=
-                               CONTACTS_ERROR_NONE) {
-               ERR(" contacts_db_get_records_with_query failed \n");
-               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
-               goto done;
-       }
-
-       if (contacts_list_first(list)  != CONTACTS_ERROR_NONE) {
-               ERR(" contacts_list_first failed \n");
-               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
-               goto done;
-       }
-
-       if (contacts_list_get_current_record_p(list, &record)  !=
-                               CONTACTS_ERROR_NONE) {
-               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
-               goto done;
-       }
-
-       if (record == NULL)
-               goto done;
-
-       contacts_record_get_str(record, _contacts_phone_log.address,
-                                                       &last_number);
-
-       if (last_number == NULL) {
-               ERR("No last number \n");
-               error_code = BT_HFP_AGENT_ERROR_NO_CALL_LOGS;
-               goto done;
-       }
-
-       /*Make Voice call*/
-       if (!__bt_hfp_agent_make_call(last_number)) {
-               ERR("Problem launching application \n");
-               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
-       }
-
-       g_free(last_number);
-
-done:
-       if (list != NULL)
-               contacts_list_destroy(list, TRUE);
-
-       if (filter != NULL)
-               contacts_filter_destroy(filter);
-
-       if (query != NULL)
-               contacts_query_destroy(query);
-
-       contacts_disconnect2();
-
-       DBG("-\n");
-
-       if (error_code == BT_HFP_AGENT_ERROR_NONE) {
-               dbus_g_method_return(context);
-               return TRUE;
-       } else {
-               error = __bt_hfp_agent_set_error(error_code);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-}
-
-static gboolean bt_hfp_agent_dial_num(BtHfpAgent *agent,
-                               const gchar *number, guint flags,
-                               DBusGMethodInvocation *context)
-{
-       GError *error;
-       int error_code;
-
-       DBG("+\n");
-
-       if (number == NULL) {
-               ERR("Invalid Argument\n");
-               error_code = BT_HFP_AGENT_ERROR_INVALID_PARAM;
-               goto fail;
-       }
-
-       DBG("Number = %s \n", number);
-       DBG("flags = %d", flags);
-
-       /*TODO: Make use of flags*/
-
-       /*Make Voice call*/
-       if (!__bt_hfp_agent_make_call(number)) {
-               ERR("Problem launching application \n");
-               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
-               goto fail;
-       }
-
-       dbus_g_method_return(context);
-
-       DBG("-\n");
-       return TRUE;
-fail:
-       error = __bt_hfp_agent_set_error(error_code);
-       dbus_g_method_return_error(context, error);
-       g_error_free(error);
-       DBG("-\n");
-       return FALSE;
-}
-
-static gboolean bt_hfp_agent_dial_memory(BtHfpAgent *agent, gint location,
-                               DBusGMethodInvocation *context)
-{
-       GError *error;
-       int error_code = BT_HFP_AGENT_ERROR_NONE;
-       char *number = NULL;
-       contacts_filter_h filter = NULL;
-       contacts_query_h query = NULL;
-       contacts_list_h list = NULL;
-       contacts_record_h record = NULL;
-       unsigned int projections[] = {
-               _contacts_speeddial.number,
-       };
-
-       DBG("+\n");
-
-       DBG("location = %d \n", location);
-
-       /*Get number from contacts location*/
-       if (contacts_connect2() != CONTACTS_ERROR_NONE) {
-               ERR(" contacts_connect2 failed \n");
-               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INTERNAL);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       contacts_filter_create(_contacts_speeddial._uri, &filter);
-
-       if (filter == NULL)
-               goto done;
-
-       if (contacts_filter_add_int(filter, _contacts_speeddial.speeddial_number,
-                               CONTACTS_MATCH_EQUAL, location) !=
-                               CONTACTS_ERROR_NONE) {
-               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
-               goto done;
-       }
-
-       contacts_query_create(_contacts_speeddial._uri, &query);
-
-       if (query == NULL)
-               goto done;
-
-       contacts_query_set_filter(query, filter);
-
-       if (contacts_query_set_projection(query, projections,
-                               sizeof(projections)/sizeof(unsigned int)) !=
-                               CONTACTS_ERROR_NONE) {
-               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
-               goto done;
-       }
-
-       if (contacts_db_get_records_with_query(query, 0, 1, &list) !=
-                               CONTACTS_ERROR_NONE) {
-               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
-               goto done;
-       }
-
-       if (contacts_list_first(list) != CONTACTS_ERROR_NONE) {
-               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
-               goto done;
-       }
-
-       if (contacts_list_get_current_record_p(list, &record) !=
-                               CONTACTS_ERROR_NONE) {
-               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
-               goto done;
-       }
-
-       if (record == NULL)
-               goto done;
-
-       contacts_record_get_str(record, _contacts_speeddial.number,
-                                                       &number);
-
-       if (number == NULL) {
-               ERR("No number at the location \n");
-               error_code = BT_HFP_AGENT_ERROR_INVALID_MEMORY_INDEX;
-               goto done;
-       }
-
-       DBG("number %s\n", number);
-
-       /*Make Voice call*/
-       if (!__bt_hfp_agent_make_call(number)) {
-               ERR("Problem launching application \n");
-               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
-       }
-
-       g_free(number);
-done:
-       if (list != NULL)
-               contacts_list_destroy(list, TRUE);
-
-       if (filter != NULL)
-               contacts_filter_destroy(filter);
-
-       if (query != NULL)
-               contacts_query_destroy(query);
-
-       contacts_disconnect2();
-
-       DBG("-\n");
-
-       if (error_code == BT_HFP_AGENT_ERROR_NONE) {
-               dbus_g_method_return(context);
-               return TRUE;
-       } else {
-               error = __bt_hfp_agent_set_error(error_code);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-}
-
-static gboolean bt_hfp_agent_send_dtmf(BtHfpAgent *agent, const gchar *dtmf,
-                               const gchar *path, const gchar *sender,
-                               DBusGMethodInvocation *context)
-{
-       GError *error;
-       int ret;
-
-       DBG("+\n");
-
-       if (dtmf == NULL || path == NULL || sender == NULL) {
-               ERR("Invalid Argument\n");
-               error = __bt_hfp_agent_set_error(
-                                       BT_HFP_AGENT_ERROR_INVALID_PARAM);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       DBG("Dtmf = %s \n", dtmf);
-       DBG("Application path = %s \n", path);
-       DBG("Sender = %s\n", sender);
-
-       ret = __bt_hfp_agent_dbus_method_send(sender,
-                               path, TELEPHONY_APP_INTERFACE,
-                               "SendDtmf", FALSE,
-                               DBUS_TYPE_STRING, &dtmf,
-                               DBUS_TYPE_INVALID);
-
-       if (ret != BT_HFP_AGENT_ERROR_NONE) {
-               error = __bt_hfp_agent_set_error(ret);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       /*App Selector code here needed*/
-       dbus_g_method_return(context);
-
-       DBG("-\n");
-       return TRUE;
-}
-
-static gboolean bt_hfp_agent_voice_dial(BtHfpAgent *agent, gboolean activate,
-                               DBusGMethodInvocation *context)
-{
-       DBG("+\n");
-
-       DBG("Activate = %d \n", activate);
-
-       /*App Selector code here needed*/
-       dbus_g_method_return(context);
-
-       DBG("-\n");
-       return TRUE;
-}
-
-static gboolean bt_hfp_agent_get_battery_status(BtHfpAgent *object,
-                               DBusGMethodInvocation *context)
-{
-       gint battery_chrg_status;
-       gint battery_capacity;
-       GError *error;
-
-       DBG("+\n");
-
-       if (vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW,
-                                               &battery_chrg_status)) {
-               DBG("VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW failed\n");
-               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");
-               goto fail;
-       }
-
-       DBG("Capacity : %d\n", battery_capacity);
-
-       dbus_g_method_return(context, battery_chrg_status, battery_capacity);
-       DBG("-\n");
-       return TRUE;
-
-fail:
-       error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_BATTERY_STATUS);
-       dbus_g_method_return_error(context, error);
-       g_error_free(error);
-       DBG("-\n");
-       return FALSE;
-}
-
-static gboolean bt_hfp_agent_get_signal_quality(BtHfpAgent *object,
-                                       DBusGMethodInvocation *context)
-{
-       gint rssi;
-       GError *error;
-
-       DBG("+\n");
-
-       if (vconf_get_int(VCONFKEY_TELEPHONY_RSSI, &rssi)) {
-               DBG("VCONFKEY_TELEPHONY_RSSI failed\n");
-               goto fail;
-       }
-
-       DBG("RSSI : %d \n", rssi);
-
-       dbus_g_method_return(context, rssi, BT_SIGNAL_QUALITY_BER);
-       DBG("-\n");
-       return TRUE;
-fail:
-       error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_SIGNAL_STATUS);
-       dbus_g_method_return_error(context, error);
-       g_error_free(error);
-       DBG("-\n");
-       return FALSE;
-}
-
-static gboolean bt_hfp_agent_get_operator_name(BtHfpAgent *object,
-                               DBusGMethodInvocation *context)
-{
-       char *operator_name;
-       GError *error;
-
-       DBG(" +\n");
-
-       operator_name = vconf_get_str(VCONFKEY_TELEPHONY_NWNAME);
-       if (NULL == operator_name) {
-               DBG("vconf_get_str failed \n");
-               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INTERNAL);
-               dbus_g_method_return_error(context, error);
-               g_error_free(error);
-               return FALSE;
-       }
-
-       DBG("operator_name  = [%s] \n", operator_name);
-
-       dbus_g_method_return(context, operator_name);
-       free(operator_name);
-
-       DBG(" -\n");
-       return TRUE;
-}
-
-static gboolean bt_hfp_agent_nrec_status(BtHfpAgent *agent, gboolean status,
-                               DBusGMethodInvocation *context)
-{
-       DBusMessage *signal;
-
-       DBG("+\n");
-
-       DBG("NREC status = %d \n", status);
-       nrec_status = status;
-       dbus_g_method_return(context);
-
-       /*Emit NREC Status change signal with value*/
-       signal = dbus_message_new_signal(BT_HFP_AGENT_OBJECT,
-                                       BT_HFP_AGENT_INTERFACE,
-                                       "NrecStatusChanged");
-       if (!signal)
-               return FALSE;
-
-       if (!dbus_message_append_args(signal,
-                               DBUS_TYPE_BOOLEAN, &status,
-                               DBUS_TYPE_INVALID)) {
-               DBG("Signal appending failed\n");
-               dbus_message_unref(signal);
-               return FALSE;
-       }
-
-       dbus_connection_send(gconn, signal, NULL);
-       dbus_message_unref(signal);
-       DBG("-\n");
-       return TRUE;
-}
-
-static void __bt_hfp_agent_append_variant(DBusMessageIter *iter,
-                       int type, void *val)
-{
-       DBusMessageIter value_iter;
-       const char *variant;
-
-       switch (type) {
-       case DBUS_TYPE_BOOLEAN:
-               variant = DBUS_TYPE_BOOLEAN_AS_STRING;
-               break;
-       case DBUS_TYPE_STRING:
-               variant = DBUS_TYPE_STRING_AS_STRING;
-               break;
-       case DBUS_TYPE_BYTE:
-               variant = DBUS_TYPE_BYTE_AS_STRING;
-               break;
-       case DBUS_TYPE_UINT16:
-               variant = DBUS_TYPE_UINT16_AS_STRING;
-               break;
-       case DBUS_TYPE_UINT32:
-               variant = DBUS_TYPE_UINT32_AS_STRING;
-               break;
-       case DBUS_TYPE_INT16:
-               variant = DBUS_TYPE_INT16_AS_STRING;
-               break;
-       case DBUS_TYPE_INT32:
-               variant = DBUS_TYPE_INT32_AS_STRING;
-               break;
-       case DBUS_TYPE_OBJECT_PATH:
-               variant = DBUS_TYPE_OBJECT_PATH_AS_STRING;
-               break;
-       default:
-               variant = DBUS_TYPE_VARIANT_AS_STRING;
-               break;
-       }
-
-       dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, variant,
-                                                       &value_iter);
-       dbus_message_iter_append_basic(&value_iter, type, val);
-       dbus_message_iter_close_container(iter, &value_iter);
-}
-
-static gboolean __bt_hfp_agent_dbus_method_variant_send(const char *path,
-               const char *interface, const char *method, const char *name,
-               int type, void *value)
-{
-       DBusMessage *msg;
-       DBusMessage *reply;
-       DBusError err;
-       DBusMessageIter iter;
-
-       DBG(" +\n");
-
-       msg = dbus_message_new_method_call(BLUEZ_SERVICE_NAME,
-                       path, interface, method);
-
-       if (!msg) {
-               DBG("Unable to allocate new D-Bus %s message", method);
-               return FALSE;
-       }
-
-       dbus_message_iter_init_append(msg, &iter);
-
-       dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
-
-       __bt_hfp_agent_append_variant(&iter, type, value);
-
-       dbus_error_init(&err);
-
-       reply = dbus_connection_send_with_reply_and_block(gconn,
-                               msg, -1, &err);
-
-       dbus_message_unref(msg);
-
-       if (!reply) {
-               DBG("Error returned in method call\n");
-               if (dbus_error_is_set(&err)) {
-                       if (err.message != NULL) {
-                               DBG("Error message = %s\n", err.message);
-                       }
-                       dbus_error_free(&err);
-               }
-               return FALSE;
-       }
-
-       dbus_message_unref(reply);
-
-       DBG(" -\n");
-       return TRUE;
-}
-
-static gboolean __bt_hfp_agent_send_registration_status_changed(
-               bt_hfp_agent_network_registration_status_t status)
-{
-       const char *property = g_strdup("RegistrationChanged");
-
-       DBG(" +\n");
-
-       if (!__bt_hfp_agent_dbus_method_variant_send(TELEPHONY_CSD_OBJECT_PATH,
-                       TELEPHONY_CSD_INTERFACE,
-                       BT_HFP_AGENT_SET_PROPERTY,
-                       property, DBUS_TYPE_BYTE, &status)) {
-               DBG("__bt_hfp_agent_dbus_method_variant_send - ERROR\n");
-               g_free((void *)property);
-               return FALSE;
-       }
-       DBG(" -\n");
-
-       g_free((void *)property);
-       return TRUE;
-}
-
-static gboolean __bt_hfp_agent_send_subscriber_number_changed(
-                                                       const char *number)
-{
-       const char *property = g_strdup("SubscriberNumberChanged");
-
-       DBG(" +\n");
-
-       if (!__bt_hfp_agent_dbus_method_variant_send(TELEPHONY_CSD_OBJECT_PATH,
-                       TELEPHONY_CSD_INTERFACE,
-                       BT_HFP_AGENT_SET_PROPERTY,
-                       property,
-                       DBUS_TYPE_STRING, &number)) {
-               DBG("__bt_hfp_agent_dbus_method_variant_send - ERROR\n");
-               g_free((void *)property);
-               return FALSE;
-       }
-
-       DBG(" -\n");
-       g_free((void *)property);
-       return TRUE;
-}
-
-static gboolean __bt_hfp_agent_send_signal_bar_changed(int signal_bar)
-{
-       const char *property = g_strdup("SignalBarsChanged");
-
-       DBG(" +\n");
-
-       if (!__bt_hfp_agent_dbus_method_variant_send(TELEPHONY_CSD_OBJECT_PATH,
-                       TELEPHONY_CSD_INTERFACE,
-                       BT_HFP_AGENT_SET_PROPERTY,
-                       property, DBUS_TYPE_INT32, &signal_bar)) {
-               DBG("__bt_hfp_agent_dbus_method_variant_send - ERROR\n");
-               g_free((void *)property);
-               return FALSE;
-       }
-
-       g_free((void *)property);
-       DBG(" -\n");
-       return TRUE;
-}
-
-static gboolean __bt_hfp_agent_send_battery_level_changed(int battery_level)
-{
-       const char *property = g_strdup("BatteryBarsChanged");
-       int battery_status;
-
-       DBG(" +\n");
-
-       /* We need to send battery status ranging from 0-5 */
-       if (battery_level < 5)
-                battery_status = 0;
-       else if (battery_level >= 100)
-               battery_status = 5;
-       else
-               battery_status = battery_level / 20 + 1;
-
-       if (!__bt_hfp_agent_dbus_method_variant_send(TELEPHONY_CSD_OBJECT_PATH,
-                       TELEPHONY_CSD_INTERFACE,
-                       BT_HFP_AGENT_SET_PROPERTY,
-                       property,
-                       DBUS_TYPE_INT32, &battery_status)) {
-               DBG("__bt_hfp_agent_dbus_method_variant_send - ERROR\n");
-               g_free((void *)property);
-               return FALSE;
-       }
-
-       DBG(" -\n");
-       g_free((void *)property);
-       return TRUE;
-}
-
-static void __bt_hfp_agent_send_battery_level(void)
-{
-       int ret;
-       int batt;
-
-       DBG(" +\n");
-
-       ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY, &batt);
-       if (ret != 0) {
-               DBG("vconf_get_int failed err = %d \n", ret);
-               return;
-       }
-
-       DBG("Current battery Level = [%d] \n", batt);
-
-       __bt_hfp_agent_send_battery_level_changed(batt);
-
-       DBG(" -\n");
-}
-
-static void __bt_hfp_agent_send_signal_status(void)
-{
-       int ret;
-       int signal_level;
-
-       DBG(" +\n");
-
-       ret = vconf_get_int(VCONFKEY_TELEPHONY_RSSI, &signal_level);
-       if (ret != 0) {
-               DBG("vconf_get_int failed err = %d \n", ret);
-               return;
-       }
-
-       DBG("Current Signal Level = [%d] \n", signal_level);
-
-       __bt_hfp_agent_send_signal_bar_changed(signal_level);
-
-       DBG(" -\n");
-}
-
-static void __bt_hfp_agent_network_send( int service, int roam_status)
-{
-       int ret;
-       bt_hfp_agent_network_registration_status_t network_service;
-
-       DBG(" +\n");
-
-       switch (service) {
-       case VCONFKEY_TELEPHONY_SVCTYPE_NONE:
-       case VCONFKEY_TELEPHONY_SVCTYPE_NOSVC:
-       case VCONFKEY_TELEPHONY_SVCTYPE_SEARCH:
-               service = 0;
-               break;
-       default:
-               service = 1;
-               break;
-       }
-
-       ret = vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &roam_status);
-       if (ret != 0) {
-               DBG("Get roaming status failed err = %d\n", ret);
-               return;
-       }
-
-       if (roam_status == 0 && service == 1)
-               network_service = BT_HFP_AGENT_NETWORK_REG_STATUS_HOME;
-       else if (roam_status == 1 && service == 1)
-               network_service = BT_HFP_AGENT_NETWORK_REG_STATUS_ROAMING;
-       else
-               network_service = BT_HFP_AGENT_NETWORK_REG_STATUS_UNKOWN;
-
-       DBG("Network service = %d\n", network_service);
-
-       __bt_hfp_agent_send_registration_status_changed(network_service);
-
-       DBG(" -\n");
-}
-
-static void __bt_hfp_agent_send_network_status(void)
-{
-       int ret;
-       int roam_status;
-       int service;
-
-
-       DBG(" +\n");
-
-       ret = vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &roam_status);
-       if (ret != 0) {
-               DBG("vconf_get_int failed for \n");
-               return;
-       }
-
-       DBG("roam_status  = [%d] \n", roam_status);
-
-       ret = vconf_get_int(VCONFKEY_TELEPHONY_SVCTYPE, &service);
-       if (ret != 0) {
-               DBG("vconf_get_int failed\n");
-               return;
-       }
-
-       DBG("service  = [%d] \n", service);
-
-       __bt_hfp_agent_network_send(service, roam_status);
-
-       DBG(" -\n");
-}
-
-static void __bt_hfp_agent_send_vconf_values(void)
-{
-       __bt_hfp_agent_send_battery_level();
-       __bt_hfp_agent_send_signal_status();
-       __bt_hfp_agent_send_network_status();
-}
-
-static void __bt_hfp_agent_battery_status_cb(keynode_t *node)
-{
-       int batt = vconf_keynode_get_int(node);
-
-       DBG(" +\n");
-
-       DBG("Current Battery Level = [%d] \n", batt);
-
-       __bt_hfp_agent_send_battery_level_changed(batt);
-
-       DBG(" -\n");
-}
-
-static void __bt_hfp_agent_network_signal_status_cb(keynode_t *node)
-{
-       int signal_bar = vconf_keynode_get_int(node);
-
-       DBG(" +\n");
-
-       DBG("Current Signal Level = [%d] \n", signal_bar);
-
-       __bt_hfp_agent_send_signal_bar_changed(signal_bar);
-
-       DBG(" -\n");
-}
-
-static void __bt_hfp_agent_network_register_status_cb(keynode_t *node)
-{
-       int service = vconf_keynode_get_int(node);
-       int roam_status;
-       int ret;
-
-       DBG(" +\n");
-
-       DBG("Current Signal Level = [%d] \n", service);
-
-       ret = vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &roam_status);
-       if (ret != 0) {
-               DBG("Get roaming status failed err = %d\n", ret);
-               return;
-       }
-
-       __bt_hfp_agent_network_send(service, roam_status);
-
-       DBG(" -\n");
-}
-
-static void __bt_hfp_agent_subscribe_vconf_updates(void)
-{
-       int ret;
-
-       DBG(" +\n");
-
-       ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
-                               (void *)__bt_hfp_agent_battery_status_cb, NULL);
-       if (0 != ret) {
-               DBG("Subsrciption to battery status failed err =  [%d]\n", ret);
-       }
-
-       ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_RSSI,
-                       (void *)__bt_hfp_agent_network_signal_status_cb, NULL);
-       if (0 != ret) {
-               DBG("Subsrciption to netowrk signal failed err =  [%d]\n", ret);
-       }
-
-       ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_SVCTYPE,
-                       (void *)__bt_hfp_agent_network_register_status_cb, NULL);
-       if (0 != ret) {
-               DBG("Subsrciption to network failed err =  [%d]\n", ret);
-       }
-
-       DBG(" -\n");
-}
-
-static void __bt_hfp_agent_release_vconf_updates(void)
-{
-       int ret;
-
-       DBG(" +\n");
-
-       ret = vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
-                       (vconf_callback_fn)__bt_hfp_agent_battery_status_cb);
-       if (0 != ret) {
-               DBG("vconf_ignore_key_changed failed\n");
-       }
-
-       ret = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_RSSI,
-               (vconf_callback_fn)__bt_hfp_agent_network_signal_status_cb);
-       if (0 != ret) {
-               DBG("vconf_ignore_key_changed failed\n");
-       }
-
-       ret = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_SVCTYPE,
-               (vconf_callback_fn)__bt_hfp_agent_network_register_status_cb);
-       if (0 != ret) {
-               DBG("vconf_ignore_key_changed failed\n");
-       }
-
-       DBG(" -\n");
-}
-
-static void __bt_hfp_agent_dbus_init(BtHfpAgent *agent)
-{
-       GError *error = NULL;
-       DBusGProxy *bus_proxy = NULL;
-       guint result;
-
-       g_connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
-       if (error != NULL) {
-               ERR("Failed connection to system bus[%s] \n", error->message);
-               g_error_free(error);
-               return;
-       }
-
-       bus_proxy = dbus_g_proxy_new_for_name(g_connection,
-                                       DBUS_SERVICE_DBUS,
-                                       DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
-       if (bus_proxy == NULL) {
-               ERR("Failed to get a proxy for D-Bus\n");
-               return;
-       }
-
-       if (!dbus_g_proxy_call(bus_proxy, "RequestName", &error, G_TYPE_STRING,
-                       BT_HFP_SERVICE, G_TYPE_UINT, 0, G_TYPE_INVALID,
-                       G_TYPE_UINT, &result, G_TYPE_INVALID)) {
-               if (error != NULL) {
-                       ERR("RequestName RPC failed[%s]\n", error->message);
-                       g_error_free(error);
-               }
-
-               g_object_unref(bus_proxy);
-               return;
-       }
-
-       DBG("result : %d %d\n", result, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
-       if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
-               ERR("Failed to get the primary well-known name.\n");
-               g_object_unref(bus_proxy);
-               return;
-       }
-
-       g_object_unref(bus_proxy);
-
-       dbus_g_connection_register_g_object(g_connection,
-               BT_HFP_SERVICE_OBJECT_PATH, G_OBJECT(agent));
-
-       gconn = dbus_g_connection_get_connection(g_connection);
-       if (gconn == NULL) {
-               ERR("Failed to get connection \n");
-               return;
-       }
-
-       __bt_hfp_agent_send_vconf_values();
-       __bt_hfp_agent_subscribe_vconf_updates();
-}
-
-static void  __bt_hfp_agent_tel_cb(TapiHandle *handle,
-                               int result,
-                               void *data,
-                               void *user_data)
-{
-       TelSimMsisdnList_t *number;
-       gchar *subscriber_number;
-
-       if (data == NULL)
-               return;
-
-       number = (TelSimMsisdnList_t *)data;
-       subscriber_number = g_strdup(number->list[0].num);
-       __bt_hfp_agent_send_subscriber_number_changed(subscriber_number);
-       g_free(subscriber_number);
-}
-
-static void __bt_hfp_agent_sigterm_handler(int signo)
-{
-       DBG("+\n");
-
-       if (gmain_loop)
-               g_main_loop_quit(gmain_loop);
-       else
-               exit(0);
-
-       DBG("-\n");
-}
-
-int main(void)
-{
-       TapiHandle *handle;
-       BtHfpAgent *bt_hfp_obj = NULL;
-       struct sigaction sa;
-       int tapi_result;
-
-       g_type_init();
-
-       memset(&sa, 0, sizeof(sa));
-       sa.sa_flags = SA_NOCLDSTOP;
-       sa.sa_handler = __bt_hfp_agent_sigterm_handler;
-       sigaction(SIGTERM, &sa, NULL);
-       sigaction(SIGINT, &sa, NULL);
-
-       gmain_loop = g_main_loop_new(NULL, FALSE);
-
-       if (gmain_loop == NULL) {
-               ERR("GMainLoop create failed \n");
-               return EXIT_FAILURE;
-       }
-
-       bt_hfp_obj = g_object_new(BT_HFP_TYPE_AGENT, NULL);
-       if (bt_hfp_obj == NULL) {
-               ERR("Failed to create BtHfpAgent instance \n");
-               if (gmain_loop)
-                       g_main_loop_unref(gmain_loop);
-
-               return EXIT_FAILURE;
-       }
-
-       handle = tel_init(NULL);
-       tapi_result = tel_get_sim_msisdn(handle, __bt_hfp_agent_tel_cb,
-                                       bt_hfp_obj);
-
-       if(tapi_result != TAPI_API_SUCCESS)
-               ERR("Fail to get sim info: %d", tapi_result);
-
-       __bt_hfp_agent_dbus_init(bt_hfp_obj);
-
-       g_main_loop_run(gmain_loop);
-
-       tel_deinit(handle);
-
-       __bt_hfp_agent_release_vconf_updates();
-
-       if (bt_hfp_obj) {
-               dbus_g_connection_unregister_g_object(g_connection,
-                                               G_OBJECT(bt_hfp_obj));
-               g_object_unref(bt_hfp_obj);
-       }
-
-       if (g_connection)
-               dbus_g_connection_unref(g_connection);
-
-       if (gmain_loop)
-               g_main_loop_unref(gmain_loop);
-
-       return 0;
-}
diff --git a/hfp-agent/bluetooth-hfp-agent.h b/hfp-agent/bluetooth-hfp-agent.h
deleted file mode 100644 (file)
index ddf8a61..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * bluetooth-agent
- *
- * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
- *
- * 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.
- *
- */
-
-#ifndef __DEF_BT_HFP_AGENT_H_
-#define __DEF_BT_HFP_AGENT_H_
-
-#include <unistd.h>
-#include <dlog.h>
-#include <stdio.h>
-
-#define BT_HFP_AGENT_ERROR (__bt_hfp_agent_error_quark())
-
-typedef enum {
-       BT_HFP_AGENT_NETWORK_REG_STATUS_HOME,
-       BT_HFP_AGENT_NETWORK_REG_STATUS_ROAMING,
-       BT_HFP_AGENT_NETWORK_REG_STATUS_OFFLINE,
-       BT_HFP_AGENT_NETWORK_REG_STATUS_SEARCHING,
-       BT_HFP_AGENT_NETWORK_REG_STATUS_NO_SIM,
-       BT_HFP_AGENT_NETWORK_REG_STATUS_POWEROFF,
-       BT_HFP_AGENT_NETWORK_REG_STATUS_POWERSAFE,
-       BT_HFP_AGENT_NETWORK_REG_STATUS_NO_COVERAGE,
-       BT_HFP_AGENT_NETWORK_REG_STATUS_REJECTED,
-       BT_HFP_AGENT_NETWORK_REG_STATUS_UNKOWN,
-} bt_hfp_agent_network_registration_status_t;
-
-typedef enum {
-       BT_HFP_AGENT_ERROR_INTERNAL,
-       BT_HFP_AGENT_ERROR_NOT_AVAILABLE,
-       BT_HFP_AGENT_ERROR_NOT_CONNECTED,
-       BT_HFP_AGENT_ERROR_BUSY,
-       BT_HFP_AGENT_ERROR_INVALID_PARAM,
-       BT_HFP_AGENT_ERROR_ALREADY_EXSIST,
-       BT_HFP_AGENT_ERROR_ALREADY_CONNECTED,
-       BT_HFP_AGENT_ERROR_NO_MEMORY,
-       BT_HFP_AGENT_ERROR_I_O_ERROR,
-       BT_HFP_AGENT_ERROR_OPERATION_NOT_AVAILABLE,
-       BT_HFP_AGENT_ERROR_NO_CALL_LOGS,
-       BT_HFP_AGENT_ERROR_INVALID_MEMORY_INDEX,
-       BT_HFP_AGENT_ERROR_INVALID_CHLD_INDEX,
-       BT_HFP_AGENT_ERROR_BATTERY_STATUS,
-       BT_HFP_AGENT_ERROR_SIGNAL_STATUS,
-       BT_HFP_AGENT_ERROR_NOT_SUPPORTED,
-       BT_HFP_AGENT_ERROR_INVALID_NUMBER,
-       BT_HFP_AGENT_ERROR_APPLICATION,
-       BT_HFP_AGENT_ERROR_INVALID_DTMF,
-       BT_HFP_AGENT_ERROR_NONE,
-} bt_hfp_agent_error_t;
-
-#define BT_HFP_SERVICE_OBJECT_PATH "/org/bluez/hfp_agent"
-#define BT_HFP_SERVICE "org.bluez.hfp_agent"
-
-#undef LOG_TAG
-#define LOG_TAG "BLUETOOTH_AGENT_HFP"
-
-#define DBG(fmt, args...) SLOGD(fmt, ##args)
-#define ERR(fmt, args...) SLOGE(fmt, ##args)
-#endif /* __DEF_BT_HFP_AGENT_H_ */
diff --git a/hfp-agent/hfp_agent.xml b/hfp-agent/hfp_agent.xml
deleted file mode 100644 (file)
index a9942dd..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-
-<node name="/">
-  <interface name="Org.Hfp.App.Interface">
-
-    <method name="RegisterApplication">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-      <arg type="s" name="path"/>
-    </method>
-
-    <method name="UnregisterApplication">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-      <arg type="s" name="path"/>
-    </method>
-
-    <method name="IncomingCall">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-      <arg type="s" name="path"/>
-      <arg type="s" name="number"/>
-      <arg type="i" name="id"/>
-    </method>
-
-    <method name="OutgoingCall">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-      <arg type="s" name="path"/>
-      <arg type="s" name="number"/>
-      <arg type="i" name="id"/>
-    </method>
-
-    <method name="ChangeCallStatus">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-      <arg type="s" name="path"/>
-      <arg type="i" name="status"/>
-      <arg type="i" name="id"/>
-    </method>
-
-    <method name="GetProperties">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-    </method>
-
- </interface>
-
- <interface name="Org.Hfp.Bluez.Interface">
-
-    <method name="AnswerCall">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-       <arg type="u" name="callid"/>
-       <arg type="s" name="path"/>
-       <arg type="s" name="sender"/>
-    </method>
-
-    <method name="ReleaseCall">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-      <arg type="u" name="callid"/>
-      <arg type="s" name="path"/>
-      <arg type="s" name="sender"/>
-    </method>
-
-    <method name="RejectCall">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-      <arg type="u" name="callid"/>
-      <arg type="s" name="path"/>
-      <arg type="s" name="sender"/>
-    </method>
-
-    <method name="ThreewayCall">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-      <arg type="u" name="value"/>
-      <arg type="s" name="path"/>
-      <arg type="s" name="sender"/>
-    </method>
-
-    <method name="DialLastNum">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-    </method>
-
-    <method name="DialNum">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-      <arg type="s" name="Number"/>
-      <arg type="u" name="flags"/>
-    </method>
-
-    <method name="DialMemory">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-      <arg type="i" name="location"/>
-    </method>
-
-    <method name="SendDtmf">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-      <arg type="s" name="dtmf"/>
-      <arg type="s" name="path"/>
-      <arg type="s" name="sender"/>
-    </method>
-
-    <method name="VoiceDial">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-      <arg type="b" name="activate"/>
-    </method>
-
-    <method name="GetBatteryStatus">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-      <arg type="i" name="bcl" direction="out"/>
-      <arg type="i" name="bcs" direction="out"/>
-    </method>
-
-    <method name="GetSignalQuality">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-      <arg type="i" name="rssi" direction="out"/>
-      <arg type="i" name="ber" direction="out"/>
-    </method>
-
-    <method name="GetOperatorName">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-      <arg type="s" name="operator" direction="out"/>
-    </method>
-
-    <method name="NrecStatus">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-      <arg type="b" name="status"/>
-    </method>
-
-  </interface>
-</node>
diff --git a/hfp-agent/org.bluez.hfp_agent.service b/hfp-agent/org.bluez.hfp_agent.service
deleted file mode 100644 (file)
index 28e2aa2..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-[D-BUS Service]
-Name=org.bluez.hfp_agent
-Exec=/usr/bin/bluetooth-hfp-agent
-User=root
index 2a9695d..ae99f3c 100644 (file)
@@ -8,7 +8,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
 INCLUDE(FindPkgConfig)
 pkg_check_modules(pkgs_map_agent
                REQUIRED
-               dlog vconf)
+               dbus-glib-1 dlog msg-service tapi vconf)
 
 FOREACH(flag ${pkgs_map_agent_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
@@ -16,16 +16,16 @@ ENDFOREACH(flag)
 
 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
 
-#FIND_PROGRAM(DBUS_BINDING_TOOL NAMES dbus-binding-tool)
-#EXEC_PROGRAM("${DBUS_BINDING_TOOL}"
-#              ARGS "--prefix=bluetooth_map \\
-#              ${CMAKE_CURRENT_SOURCE_DIR}/bluetooth_map_agent.xml \\
-#              --mode=glib-server \\
-#              --output=${CMAKE_CURRENT_SOURCE_DIR}/bluetooth_map_agent_glue.h")
+FIND_PROGRAM(DBUS_BINDING_TOOL NAMES dbus-binding-tool)
+EXEC_PROGRAM("${DBUS_BINDING_TOOL}"
+               ARGS "--prefix=bluetooth_map \\
+               ${CMAKE_CURRENT_SOURCE_DIR}/bluetooth_map_agent.xml \\
+               --mode=glib-server \\
+               --output=${CMAKE_CURRENT_SOURCE_DIR}/bluetooth_map_agent_glue.h")
 
 ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
 TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_map_agent_LDFLAGS})
 
 INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.bluez.map_agent.service
-               DESTINATION share/dbus-1/services)
+               DESTINATION share/dbus-1/system-services)
index 32baac5..1a90256 100644 (file)
@@ -1,13 +1,17 @@
 /*
- * bluetooth-agent
+ * Bluetooth-agent
  *
- * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
+ *              Girishashok Joshi <girish.joshi@samsung.com>
+ *              Chanyeol Park <chanyeol.park@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
+ *             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,
@@ -17,8 +21,6 @@
  *
  */
 
-#if 0
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "msg_transport_types.h"
 #include "msg_types.h"
 
-#ifdef SUPPORT_EMAIL
-/*Email Header Files*/
-#include "email-types.h"
-#include "email-api-init.h"
-#include "email-api-account.h"
-#include "email-api-mailbox.h"
-#include "email-api-mail.h"
-#include "email-api-network.h"
-#endif
-
+#include <TelSms.h>
+#include <TapiUtility.h>
+#include <ITapiNetText.h>
 #include <bluetooth_map_agent.h>
-
 #include <map_bmessage.h>
 
-#define OBEX_CLIENT_SERVICE "org.openobex.client"
-#define OBEX_CLIENT_INTERFACE "org.openobex.Client"
-#define OBEX_CLIENT_PATH "/"
+#define OBEX_CLIENT_SERVICE "org.bluez.obex"
+#define OBEX_CLIENT_INTERFACE "org.bluez.obex.Client1"
+#define OBEX_CLIENT_PATH "/org/bluez/obex"
+
 #define MNS_CLIENT_INTERFACE "org.openobex.MessageNotification"
 
 #define DBUS_STRUCT_STRING_STRING_UINT (dbus_g_type_get_struct("GValueArray", \
                G_TYPE_INVALID))
 
 static msg_handle_t g_msg_handle = NULL;
+static TapiHandle *g_tapi_handle = NULL;
+static TelSmsAddressInfo_t *g_sca_info = NULL;
+static DBusGProxy *g_mns_proxy;
 
 #define BT_MAP_NEW_MESSAGE "NewMessage"
 #define BT_MAP_STATUS_CB "sent status callback"
 #define BT_MAP_MSG_CB "sms message callback"
-#define BT_MAP_EMAIL_DEFAULTACCOUNT "db/email/defaultaccount"
 #define BT_MNS_OBJECT_PATH "/org/bluez/mns"
 #define BT_MNS_INTERFACE "org.bluez.mns"
-#define BT_MAIL_TEMP_BODY "/tmp/bt_mail.txt"
 #define BT_MAP_SENT_FOLDER_NAME "SENT"
+#define BT_MAP_MSG_TEMPLATE "TEMPLATE"
+#define BT_MAP_DELETED_FOLDER_NAME "DELETED"
 #define BT_MAP_MSG_INFO_MAX 256
 #define BT_MAP_MSG_HANDLE_MAX 21
 #define BT_MAP_TIMESTAMP_MAX_LEN 16
-#define BT_MAP_SUBJECT_MAX_LEN 20
+#define BT_MAP_SUBJECT_MAX_LEN 50
 #define BT_MAP_MSG_BODY_MAX 1024
 #define BT_MSG_UPDATE  0
 #define BT_MSG_DELETE  1
 #define BT_SMS 0
-#define BT_EMAIL 1
-#define BT_EMAIL_HANDLE_BASE (G_MAXUINT64 / 2)
-#define BT_MAIL_ID_MAX_LENGTH 50
 
 #define BEGIN_BMSEG "BEGIN:BMSG\r\n"
 #define END_BMSEG "END:BMSG\r\n"
@@ -109,20 +104,23 @@ static msg_handle_t g_msg_handle = NULL;
 #define LANGUAGE "LANGUAGE:%s\r\n"
 #define LENGTH "LENGTH:%d\r\n"
 #define MSG_BODY "BEGIN:MSG\r\n%s\r\nEND:MSG\r\n"
+#define MSG_BODY_BEGIN "BEGIN:MSG\r\n"
+#define MSG_BODY_END "\r\nEND:MSG\r\n"
 
-/* This has been added for testing purpose, will be removed when SMS APIs
-    are available. */
-#define TEST_PDU "06810000000000040681567777000021017101750261A05"\
-                "376BA0D8297E5F3B73BCC4ED3F3A030FB1ECECF41613A"\
-                "5D1E1ED3E7A0B2BD2CCF8362AEA4195407C941ECF77C9"\
-                "E769F41753968FC769BD3E4B27B5C0691EB6510FD0D7AD"\
-                "BCBF27B397D46D343A163990E42BFDB6590BCDC4E93D3"\
-                "E539889E86CF41F437485E26D7C765D0DB5E96DFCBE933"\
-                "9A1E9A36A72063900AA2BF41B5DBED760385E920E9DC357B35A9"
-
-GSList* id_list = NULL;
+GSList *id_list = NULL;
 guint64 current_push_map_id;
 
+typedef enum {
+       SMS_TON_UNKNOWN = 0,            /* unknown */
+       SMS_TON_INTERNATIONAL = 1,      /* international number */
+       SMS_TON_NATIONAL = 2,           /* national number */
+       SMS_TON_NETWORK_SPECIFIC = 3, /* network specific number */
+       SMS_TON_DEDICATED_ACCESS = 4, /* subscriber number */
+       SMS_TON_ALPHA_NUMERIC = 5,      /* alphanumeric, GSM 7-bit default */
+       SMS_TON_ABBREVIATED_NUMBER = 6, /* abbreviated number */
+       SMS_TON_RESERVED_FOR_EXT = 7 /* reserved for extension */
+} bt_sim_type_of_num_t;
+
 struct id_info {
        guint64 map_id;
        int uid;
@@ -220,26 +218,28 @@ static gboolean bluetooth_map_noti_registration(BluetoothMapAgent *agent,
                                        gchar *remote_addr,
                                        gboolean status,
                                        DBusGMethodInvocation *context);
-
+static gboolean bluetooth_map_destroy_agent(BluetoothMapAgent *agent,
+                                       DBusGMethodInvocation *context);
 
 #include "bluetooth_map_agent_glue.h"
 
 static void bluetooth_map_agent_init(BluetoothMapAgent *obj)
 {
-       DBG("+\n");
-
+       FN_START;
        g_assert(obj != NULL);
+       FN_END;
 }
 
 static void bluetooth_map_agent_finalize(GObject *obj)
 {
-       DBG("+\n");
-
+       FN_START;
        G_OBJECT_CLASS(bluetooth_map_agent_parent_class)->finalize(obj);
+       FN_END;
 }
 
 static void bluetooth_map_agent_class_init(BluetoothMapAgentClass *klass)
 {
+       FN_START;
        GObjectClass *object_class = (GObjectClass *) klass;
 
        g_assert(klass != NULL);
@@ -248,91 +248,132 @@ static void bluetooth_map_agent_class_init(BluetoothMapAgentClass *klass)
 
        dbus_g_object_type_install_info(BLUETOOTH_MAP_TYPE_AGENT,
                                        &dbus_glib_bluetooth_map_object_info);
+       FN_END;
 }
 
 static GQuark __bt_map_agent_error_quark(void)
 {
+       FN_START;
        static GQuark quark = 0;
        if (!quark)
                quark = g_quark_from_static_string("agent");
 
+       FN_END;
        return quark;
 }
 
 static GError *__bt_map_agent_error(bt_map_agent_error_t error,
                                     const char *err_msg)
 {
+       FN_START;
        return g_error_new(BT_MAP_AGENT_ERROR, error, err_msg, NULL);
 }
 
-static guint64 _bt_validate_uid(int uid)
+static void __bt_mns_client_event_notify(gchar *event, guint64 handle,
+                                       gchar *folder, gchar *old_folder,
+                                       gchar *msg_type);
+
+static char *__bt_get_truncated_utf8_string(char *src)
+{
+       FN_START;
+       char *p = src;
+       char *next;
+       char dest[BT_MAP_SUBJECT_MAX_LEN] = {0,};
+       int count;
+       int i = 0;
+
+       if (src == NULL)
+               return FALSE;
+
+       while (*p != '\0' && i < sizeof(dest)) {
+               next = g_utf8_next_char(p);
+               count = next - p;
+
+               while (count > 0 && ((i + count) < sizeof(dest))) {
+                       dest[i++] = *p;
+                       p++;
+                       count --;
+               }
+               p = next;
+       }
+
+       FN_END;
+       return g_strdup(dest);
+}
+
+static guint64 __bt_validate_uid(int uid)
 {
-        DBG("Validate uid");
-        struct id_info *info;
-        int count;
-        int i;
-
-        count = g_slist_length(id_list);
-        for (i = 0; i < count; i++) {
-                info = (struct id_info *)g_slist_nth_data(id_list, i);
+       FN_START;
+       struct id_info *info;
+       int count;
+       int i;
+
+       count = g_slist_length(id_list);
+       for (i = 0; i < count; i++) {
+               info = (struct id_info *)g_slist_nth_data(id_list, i);
                if (!info)
                        break;
 
-                if (info->uid == uid) {
-                        printf("uid = %d\n", uid);
-                        return info->map_id;
-                }
-        }
+               if (info->uid == uid) {
+                       DBG("uid = %d\n", uid);
+                       return info->map_id;
+               }
+       }
 
-        return 0;
+       FN_END;
+       return 0;
 }
 
 static guint64 __bt_add_id(int uid)
 {
-        DBG("Add id: %d\n", uid);
-        static guint64 map_id;
-        struct id_info *info;
-        guint64 test;
+       FN_START;
+       static guint64 map_id;
+       struct id_info *info;
+       guint64 test;
 
-        test = _bt_validate_uid(uid);
-        DBG("test: %llx\n", test);
-        if (test)
-                return test;
+       DBG("Add id: %d\n", uid);
+       test = __bt_validate_uid(uid);
+       DBG("test: %llx\n", test);
+       if (test)
+               return test;
 
-        info = g_new0(struct id_info, 1);
+       info = g_new0(struct id_info, 1);
 
-        map_id++;
+       map_id++;
 
-        info->map_id = map_id;
-        info->uid = uid;
-        DBG("map_id = %llx, uid = %d \n", info->map_id, info->uid);
+       info->map_id = map_id;
+       info->uid = uid;
+       DBG("map_id = %llx, uid = %d \n", info->map_id, info->uid);
 
-        id_list = g_slist_append(id_list, info);
+       id_list = g_slist_append(id_list, info);
 
-        return map_id;
+       FN_END;
+       return map_id;
 }
 
 static int __bt_get_id(guint64 map_id)
 {
-        DBG("get id\n");
-        struct id_info *info;
-        int count;
+       FN_START;
+       struct id_info *info;
+       int count;
        int i;
 
-        count = g_slist_length(id_list);
+       count = g_slist_length(id_list);
 
-        for (i = 0; i < count; i++) {
-                info = (struct id_info *)g_slist_nth_data(id_list, i);
+       for (i = 0; i < count; i++) {
+               info = (struct id_info *)g_slist_nth_data(id_list, i);
 
-                if (info->map_id == map_id)
-                        return info->uid;
-        }
+               if (info->map_id == map_id)
+                       return info->uid;
+       }
 
-        return -1;
+       FN_END;
+       return -1;
 }
 
 static int __bt_get_uid(gchar *handle)
 {
+       FN_START;
        guint64 map_id;
        int uid;
 
@@ -345,12 +386,13 @@ static int __bt_get_uid(gchar *handle)
 
        uid = __bt_get_id(map_id);
 
+       FN_END;
        return uid;
 }
 
 static int __bt_update_id(guint64 map_id, int new_uid)
 {
-       DBG("update id\n");
+       FN_START;
        struct id_info *info;
        int i;
        int count;
@@ -366,46 +408,163 @@ static int __bt_update_id(guint64 map_id, int new_uid)
                }
        }
 
-        return -1;
+       FN_END;
+       return -1;
 }
 
 static void __bt_remove_list(GSList *id_list)
 {
+       FN_START;
        if (!id_list)
                return;
 
-        DBG("Removing id list\n");
-        g_slist_free_full(id_list, g_free);
+       DBG("Removing id list\n");
+       g_slist_free_full(id_list, g_free);
+       FN_END;
+}
+
+static int __bt_get_folder_id(char *folder_path)
+{
+       FN_START;
+       int folder_id = -1;
+       int i;
+       char *folder;
+       msg_struct_list_s folder_list = {0,};
+       msg_error_t err;
+       msg_struct_t p_folder;
+       DBG_SECURE("folder_path %s\n", folder_path);
+
+       folder = strrchr(folder_path, '/');
+       if (NULL == folder)
+               folder = folder_path;
+       else
+               folder++;
+
+       err = msg_get_folder_list(g_msg_handle, &folder_list);
+       if (err != MSG_SUCCESS)
+               goto done;
+
+       for (i = 0; i < folder_list.nCount; i++) {
+               char folder_name[BT_MAP_MSG_INFO_MAX] = {0, };
+
+               p_folder = folder_list.msg_struct_info[i];
+
+               err = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
+                                       folder_name, BT_MAP_MSG_INFO_MAX);
+               if (err != MSG_SUCCESS)
+                       continue;
+
+               DBG_SECURE("folder_name %s\n", folder_name);
+               if (!g_ascii_strncasecmp(folder_name, folder, strlen(folder))) {
+                       err = msg_get_int_value(p_folder,
+                                       MSG_FOLDER_INFO_ID_INT,
+                                       &folder_id);
+                       if (err != MSG_SUCCESS)
+                               goto done;
+
+                       DBG("folder_id %d", folder_id);
+                       break;
+               }
+       }
+
+done:
+       if (folder_list.msg_struct_info)
+               msg_release_list_struct(&folder_list);
+
+       FN_END;
+       return folder_id;
+
 }
 
+static void __bt_add_deleted_folder(void)
+{
+       FN_START;
+       msg_error_t err;
+       msg_struct_t folder_info = msg_create_struct(MSG_STRUCT_FOLDER_INFO);
+
+       err = msg_set_int_value(folder_info, MSG_FOLDER_INFO_TYPE_INT,
+                                               MSG_FOLDER_TYPE_USER_DEF);
+       if (err != MSG_SUCCESS) {
+               ERR("Failed adding type %d", err);
+               msg_release_struct(&folder_info);
+               return;
+       }
+
+       err = msg_set_str_value(folder_info, MSG_FOLDER_INFO_NAME_STR,
+                                       "DELETED", MAX_FOLDER_NAME_SIZE);
+       if (err != MSG_SUCCESS) {
+               ERR("Failed adding str %d", err);
+               msg_release_struct(&folder_info);
+               return;
+       }
+
+       err = msg_add_folder(g_msg_handle, folder_info);
+       if (err != MSG_SUCCESS) {
+               ERR("Failed adding folder %d", err);
+               msg_release_struct(&folder_info);
+               return;
+       }
+
+       msg_release_struct(&folder_info);
+       FN_END;
+}
 
 static gchar *__bt_get_folder_name(int id)
 {
+       FN_START;
        int ret;
+       int i;
+       int folder_id;
+       gboolean path_found = FALSE;
        char folder_name[BT_MAP_MSG_INFO_MAX] = {0,};
 
-       msg_struct_list_s g_folderList;
+       msg_struct_list_s folder_list = {0,};
        msg_struct_t p_folder;
 
-       ret = msg_get_folder_list(g_msg_handle, &g_folderList);
+       ret = msg_get_folder_list(g_msg_handle, &folder_list);
        if (ret != MSG_SUCCESS)
-               goto done;
+               return g_strdup("TELECOM/MSG");
+
+       if (folder_list.msg_struct_info == NULL)
+               return g_strdup("TELECOM/MSG");
 
-       p_folder = g_folderList.msg_struct_info[id];
+       for (i = 0; i < folder_list.nCount; i++) {
+               p_folder = folder_list.msg_struct_info[i];
 
-       ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
+               ret = msg_get_int_value(p_folder,
+                                       MSG_FOLDER_INFO_ID_INT,
+                                       &folder_id);
+               if (ret != MSG_SUCCESS)
+                       break;
+               DBG("folder_id %d, id = %d", folder_id, id);
+               if (folder_id == id) {
+                       ret = msg_get_str_value(p_folder,
+                                       MSG_FOLDER_INFO_NAME_STR,
                                        folder_name, BT_MAP_MSG_INFO_MAX);
-       if (ret != MSG_SUCCESS)
-               goto done;
+                       if (ret != MSG_SUCCESS)
+                               break;
 
-       return g_strdup_printf("TELECOM/MSG/%s", folder_name);
+                       path_found = TRUE;
+                       DBG_SECURE("folder_name %s", folder_name);
+                       break;
+               }
+       }
 
-done:
-       return g_strdup("TELECOM/MSG");
+       if (folder_list.msg_struct_info) {
+               ret = msg_release_list_struct(&folder_list);
+               ERR("Err %d", ret);
+       }
+
+       FN_END;
+       if (path_found != TRUE)
+               return g_strdup("TELECOM/MSG");
+       else
+               return g_strdup_printf("TELECOM/MSG/%s", folder_name);
 }
 
 static void __get_msg_timestamp(time_t *ltime, char *timestamp)
 {
+       FN_START;
        struct tm local_time;
        int year;
        int month;
@@ -419,31 +578,267 @@ static void __get_msg_timestamp(time_t *ltime, char *timestamp)
                                        local_time.tm_mday, local_time.tm_hour,
                                        local_time.tm_min, local_time.tm_sec);
 
+       FN_END;
        return;
 }
 
+#define SET_TON_NPI(dest, ton, npi) {  \
+       dest = 0x80;                    \
+       dest |= (ton & 0x07) << 4;      \
+       dest |= npi & 0x0F;             \
+}
+
+static int __bt_ascii_to_upper(int ch)
+{
+       return (('a' <= (ch) && (ch) <= 'z') ? ((ch) - ('a'-'A')) : (ch));
+}
+
+static int __bt_sms_pack_gsm_code(gchar *p_out, const char *data, int in_len)
+{
+       FN_START;
+       int i;
+       int pos;
+       int shift = 0;
+
+       for (pos = 0, i = 0; i < in_len; pos++, i++) {
+               /* pack the low bits */
+               p_out[pos] = data[i] >> shift;
+
+               if (i + 1 < in_len) {
+                       /* pack the high bits using the low bits
+                          of the next character */
+                       p_out[pos] |= data[i+1] << (7 - shift);
+
+                       shift++;
+
+                       if (shift == 7) {
+                               shift = 0;
+                               i++;
+                       }
+               }
+       }
+
+       FN_END;
+       return pos;
+}
+
+static void __bt_sms_conv_digit_to_bcd(gchar *p_bcd, char *p_digits, int digit_len)
+{
+       FN_START;
+       int i;
+       int j;
+       int digit;
+       unsigned char higher;
+       unsigned char lower;
+
+       if (p_bcd == NULL || p_digits == NULL)
+               return;
+
+       /* 0123456789 -> 1032547698 */
+       for (i = 0, j = 0; i < digit_len; i = i + 2, j++) {
+               if (p_digits[i] == '*')
+                       digit = 0x0A;
+               else if (p_digits[i] == '#')
+                       digit = 0x0B;
+               else if (__bt_ascii_to_upper(p_digits[i]) == 'P')
+                       digit = 0x0C;
+               else
+                       digit = (int) (p_digits[i] - '0');
+
+               lower = digit & 0x0F;
+
+               if (digit_len != i + 1) {
+                       if (p_digits[i+1] == '*')
+                               digit = 0x0A;
+                       else if (p_digits[i+1] == '#')
+                               digit = 0x0B;
+                       else if (__bt_ascii_to_upper(p_digits[i+1]) == 'P')
+                               digit = 0x0C;
+                       else
+                               digit = (int) (p_digits[i+1] - '0');
+
+                       higher = digit & 0x0F;
+               } else {
+                       higher = 0xFF;
+               }
+
+               p_bcd[j] = (higher << 4) | lower;
+       }
+       FN_END;
+}
+
+static int  __bt_sms_encode_addr(gchar *addr_field, char *dial_num,
+                               int dial_num_len, int ton, int npi)
+{
+       FN_START;
+       int index = 0;
+
+       if (dial_num == NULL || addr_field == NULL)
+               return -1;
+
+       if (dial_num[0] == '+') {
+               dial_num++;
+               dial_num_len--;
+               ton = SMS_TON_INTERNATIONAL;
+       }
+
+       if (ton != SMS_TON_ALPHA_NUMERIC) {
+               /* Origination address length address length */
+               addr_field[index++] = (unsigned char)dial_num_len;
+       } else {
+               addr_field[index] = (unsigned char)
+                                       (((dial_num_len * 7 + 7) / 8) * 2);
+
+               if (((dial_num_len * 7) % 8) <= 4)
+                       addr_field[index]--;
+
+               index++;
+       }
+
+       SET_TON_NPI(addr_field[index], ton, npi);
+       index++; /* SET_TON_NPI */
+
+       if (ton != SMS_TON_ALPHA_NUMERIC) {
+               __bt_sms_conv_digit_to_bcd(&addr_field[index],
+                                       (char *)dial_num, dial_num_len);
+
+               if (dial_num_len % 2)
+                       index += (dial_num_len / 2) + 1;
+               else
+                       index += dial_num_len / 2;
+       } else {
+               index += __bt_sms_pack_gsm_code(&addr_field[index],
+                                               dial_num, (int)dial_num_len);
+       }
+
+       FN_END;
+       return index;
+}
+
+static int __bt_sms_encode_time(gchar *addr_field, time_t *tm)
+{
+       FN_START;
+       int index = 0;
+       struct tm ltime;
+       int year;
+       int month;
+
+       if (!localtime_r(tm, &ltime))
+               return index;
+
+       year = ltime.tm_year + 1900; /* years since 1900 */
+       year = year % 100;
+       month = ltime.tm_mon + 1; /* months since January */
+
+       addr_field[index++] = ((year % 10)  << 4) + (year / 10);
+       addr_field[index++] = ((month % 10) << 4) + (month / 10);
+       addr_field[index++] = ((ltime.tm_mday % 10) << 4) +
+                                                       (ltime.tm_mday / 10);
+       addr_field[index++] = ((ltime.tm_hour % 10) << 4) +
+                                                       (ltime.tm_hour / 10);
+       addr_field[index++] = ((ltime.tm_min % 10) << 4) + (ltime.tm_min / 10);
+       addr_field[index++] = ((ltime.tm_sec % 10) << 4) + (ltime.tm_sec / 10);
+       addr_field[index] = 0x00;
+
+       FN_END;
+       return index;
+}
+
+static gchar *__bt_get_sms_pdu_from_msg_data(gchar *number,
+                                               char *msg, time_t tm,
+                                               int *msg_pdu_len)
+{
+       FN_START;
+       gchar packet[TAPI_NETTEXT_MSG_SIZE_MAX] = {0,};
+       int index = 0;
+
+       packet[index] = 0x00; /* Since SCA is unknown for stored messages */
+       index++;
+
+       /* TP-MTI : Type of message */
+       packet[index] = 0x00;   /* SMS-DELIVER PDU */
+
+       /* TP-MMS bit is set to 1 as we support only SMS */
+       packet[index] |= 0x04;
+       index++;
+
+       /* TP-OA : Mobile originating address */
+       index += __bt_sms_encode_addr(packet+index,
+                                       number, strlen(number),
+                                       g_sca_info->Ton, g_sca_info->Npi);
+
+       /* TP-PID : Since we use only SMS so set to 0 */
+       packet[index++] = 0x00;
+
+       /* TP-DCS : Data Coding Scheme, default value set */
+       packet[index++] = 0x00;
+
+       /* TP-SCTS : Message timestamp */
+       index += __bt_sms_encode_time(packet+index, &tm);
+       index++;
+       /* TP-UDL : Message body length */
+       packet[index++] = strlen(msg);
+
+       /* TP-UD : Message body */
+       index += __bt_sms_pack_gsm_code(packet + index, msg, strlen(msg));
+
+       *msg_pdu_len = index;
+
+       FN_END;
+       return g_memdup(packet, index);
+}
+
+static void __bt_get_sms_sca(TapiHandle *handle, int result, void *data,
+                                                       void *user_data)
+{
+       FN_START;
+       TelSmsAddressInfo_t *scaInfo = data;
+
+       DBG("__bt_get_sms_sca 0x%x", result);
+
+       if (data == NULL) {
+               g_sca_info = g_malloc0(sizeof(TelSmsAddressInfo_t));
+               g_sca_info->Ton = 0;
+               g_sca_info->Npi = 0;
+               g_sca_info->DialNumLen = 0;
+               return;
+       }
+
+       g_sca_info = g_malloc0(sizeof(TelSmsAddressInfo_t));
+       g_sca_info->Ton = scaInfo->Ton;
+       g_sca_info->Npi = scaInfo->Npi;
+       g_sca_info->DialNumLen = scaInfo->DialNumLen;
+       FN_END;
+}
+
 static char *__bt_prepare_msg_bmseg(msg_struct_t msg_info, gboolean attach,
                                                        gboolean transcode)
 {
+       FN_START;
        int ret;
        int m_type = MSG_TYPE_SMS;
        int folder_id;
        int count;
+       int dptime = 0;
+       int j;
        bool read_status = false;
        char msg_body[BT_MAP_MSG_BODY_MAX] = {0,};
        char addr_value[MAX_ADDRESS_VAL_LEN] = {0,};
-       char name_value[MAX_ADDRESS_VAL_LEN] = {0,};
-       gchar *folder_path;
+       char name_value[MAX_DISPLAY_NAME_LEN] = {0,};
+
+       msg_list_handle_t addr_list = NULL;
+       msg_struct_t addr_info = NULL;
 
-       msg_struct_list_s *addr_list = NULL;
        GString *msg;
+       gchar *folder_path = NULL;
+       gchar *msg_pdu;
 
        msg = g_string_new(BEGIN_BMSEG);
        g_string_append(msg, BMSEG_VERSION);
 
        ret = msg_get_bool_value(msg_info, MSG_MESSAGE_READ_BOOL, &read_status);
        if (ret == MSG_SUCCESS) {
-               DBG("read_status %d\n", read_status);
+               INFO("read_status %d\n", read_status);
        }
 
        if (read_status)
@@ -453,55 +848,43 @@ static char *__bt_prepare_msg_bmseg(msg_struct_t msg_info, gboolean attach,
 
        ret = msg_get_int_value(msg_info, MSG_MESSAGE_TYPE_INT, &m_type);
        if (ret == MSG_SUCCESS) {
-               DBG("m_type %d\n", m_type);
-       }
-
-       switch (m_type) {
-       case MSG_TYPE_MMS:
-       case MSG_TYPE_MMS_JAVA:
-       case MSG_TYPE_MMS_NOTI:
-               g_string_append_printf(msg, MSEG_TYPE, "MMS");
-               break;
-
-       default:
+               INFO("m_type %d\n", m_type);
                 g_string_append_printf(msg, MSEG_TYPE, "SMS_GSM");
-               break;
        }
 
        ret = msg_get_int_value(msg_info, MSG_MESSAGE_FOLDER_ID_INT,
                                                        &folder_id);
        if (ret == MSG_SUCCESS) {
                DBG("folder_id %d\n", folder_id);
-       }
-
-       folder_path = __bt_get_folder_name(folder_id);
-       g_string_append_printf(msg, FOLDER_PATH, folder_path);
 
+               folder_path = __bt_get_folder_name(folder_id);
+               g_string_append_printf(msg, FOLDER_PATH, folder_path);
+       }
 
-       ret = msg_get_list_handle(msg_info, MSG_MESSAGE_ADDR_LIST_STRUCT,
-                                                       (void **)&addr_list);
+       ret = msg_get_list_handle(msg_info, MSG_MESSAGE_ADDR_LIST_HND,
+                                               (void **)&addr_list);
        if (ret == MSG_SUCCESS) {
-               count = addr_list->nCount;
+               count = msg_list_length(addr_list);
                DBG("count %d \n", count);
-               while (count > 0) {
-                       msg_struct_t addr_info = NULL;
-                       addr_info = addr_list->msg_struct_info[count - 1];
+
+               if (count > 0) {
+                       addr_info = (msg_struct_t)msg_list_nth_data(addr_list,
+                                                                       0);
 
                        msg_get_str_value(addr_info,
                                        MSG_ADDRESS_INFO_ADDRESS_VALUE_STR,
                                        addr_value, MAX_ADDRESS_VAL_LEN);
-                       DBG("addr_value %s\n", addr_value);
+                       DBG_SECURE("addr_value %s\n", addr_value);
                        msg_get_str_value(addr_info,
                                        MSG_ADDRESS_INFO_DISPLAYNAME_STR,
-                                       name_value, MAX_ADDRESS_VAL_LEN);
+                                       name_value, MAX_DISPLAY_NAME_LEN);
                        if (!strlen(name_value))
                                g_stpcpy(name_value, addr_value);
 
-                       DBG("name_value %s\n", name_value);
+                       DBG_SECURE("name_value %s\n", name_value);
 
                        g_string_append_printf(msg, VCARD, name_value,
                                                                addr_value);
-                       count--;
                }
        }
 
@@ -511,40 +894,55 @@ static char *__bt_prepare_msg_bmseg(msg_struct_t msg_info, gboolean attach,
        if (transcode) {
                g_string_append_printf(msg, CHARSET, "UTF-8");
 
-               if (m_type == MSG_TYPE_MMS)
-                       ret = msg_get_str_value(msg_info,
-                                               MSG_MESSAGE_MMS_TEXT_STR,
-                                               msg_body, BT_MAP_SUBJECT_MAX_LEN);
-               else
-                       ret = msg_get_str_value(msg_info,
-                                               MSG_MESSAGE_SMS_DATA_STR,
-                                               msg_body, BT_MAP_MSG_BODY_MAX);
 
+               ret = msg_get_str_value(msg_info,
+                                       MSG_MESSAGE_SMS_DATA_STR,
+                                       msg_body, BT_MAP_MSG_BODY_MAX);
                if (ret == MSG_SUCCESS) {
                        g_string_append_printf(msg, LENGTH, strlen(msg_body));
                        g_string_append_printf(msg, MSG_BODY, msg_body);
                }
        } else {
-               gchar *msg_pdu;
                g_string_append_printf(msg, ENCODING, "G-7BIT");
                g_string_append_printf(msg, CHARSET, "native");
-               /* The below line has been added for testing purpose,
-                   will be removed when SMS APIs are available. */
-               msg_pdu = g_strdup(TEST_PDU);
-               g_string_append_printf(msg, LENGTH, strlen(msg_pdu));
-               g_string_append_printf(msg, MSG_BODY, msg_pdu);
-               g_free(msg_pdu);
+
+               msg_get_int_value(msg_info,
+                               MSG_MESSAGE_DISPLAY_TIME_INT, &dptime);
+
+               ret = msg_get_str_value(msg_info, MSG_MESSAGE_SMS_DATA_STR,
+                                       msg_body, BT_MAP_MSG_BODY_MAX);
+               if (ret == MSG_SUCCESS) {
+                       int msg_pdu_len = 0;
+                       msg_pdu = __bt_get_sms_pdu_from_msg_data(addr_value,
+                                                       msg_body, dptime,
+                                                       &msg_pdu_len);
+                       if (msg_pdu) {
+                               DBG("msg_pdu_len = %d", msg_pdu_len);
+
+                               g_string_append_printf(msg, LENGTH, msg_pdu_len);
+                               g_string_append(msg, MSG_BODY_BEGIN);
+                               for (j = 0; j < msg_pdu_len; j++)
+                                       g_string_append_printf(msg, "%02x",
+                                                                       msg_pdu[j]);
+
+                               g_string_append(msg, MSG_BODY_END);
+                               g_free(msg_pdu);
+                       }
+               }
        }
 
        g_string_append(msg, END_BBODY);
        g_string_append(msg, END_BENV);
        g_string_append(msg, END_BMSEG);
+       g_free(folder_path);
 
+       FN_END;
        return g_string_free(msg, FALSE);
 }
 
 static void __bt_message_info_free(struct message_info msg_info)
 {
+       FN_START;
        g_free(msg_info.handle);
        g_free(msg_info.subject);
        g_free(msg_info.datetime);
@@ -557,10 +955,12 @@ static void __bt_message_info_free(struct message_info msg_info)
        g_free(msg_info.reception_status);
        g_free(msg_info.size);
        g_free(msg_info.attachment_size);
+       FN_END;
 }
 
 static struct message_info __bt_message_info_get(msg_struct_t msg_struct_handle)
 {
+       FN_START;
        struct message_info msg_info = {0,};
        int ret;
        int msg_id;
@@ -570,16 +970,16 @@ static struct message_info __bt_message_info_get(msg_struct_t msg_struct_handle)
        int data_size;
        int priority;
        int direction_type;
+       int count;
        bool protect_status = 0;
        bool read_status = 0;
 
        char msg_handle[BT_MAP_MSG_HANDLE_MAX] = {0,};
-       char msg_subject[BT_MAP_SUBJECT_MAX_LEN] = {0,};
        char msg_datetime[BT_MAP_TIMESTAMP_MAX_LEN] = {0,};
        char msg_size[5] = {0,};
        char msg_body[BT_MAP_MSG_BODY_MAX] = {0,};
        char addr_value[MAX_ADDRESS_VAL_LEN] = {0,};
-       char name_value[MAX_ADDRESS_VAL_LEN] = {0,};
+       char name_value[MAX_DISPLAY_NAME_LEN] = {0,};
 
        msg_info.text = FALSE;
        msg_info.protect = FALSE;
@@ -588,7 +988,7 @@ static struct message_info __bt_message_info_get(msg_struct_t msg_struct_handle)
 
        msg_struct_t msg = NULL;
        msg_struct_t send_opt = NULL;
-       msg_struct_list_s *addr_list = NULL;
+       msg_list_handle_t addr_list = NULL;
        msg_struct_t addr_info = NULL;
 
        ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_ID_INT, &msg_id);
@@ -599,7 +999,12 @@ static struct message_info __bt_message_info_get(msg_struct_t msg_struct_handle)
        msg_info.handle = g_strdup(msg_handle);
 
        msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
+       if (msg == NULL)
+               goto next;
+
        send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
+       if (send_opt == NULL)
+               goto next;
 
        ret = msg_get_message(g_msg_handle,
                                                (msg_message_id_t)msg_id,
@@ -609,31 +1014,39 @@ static struct message_info __bt_message_info_get(msg_struct_t msg_struct_handle)
                goto next;
        }
 
-       ret = msg_get_list_handle(msg, MSG_MESSAGE_ADDR_LIST_STRUCT,
+       ret = msg_get_list_handle(msg, MSG_MESSAGE_ADDR_LIST_HND,
                                                        (void **)&addr_list);
        if (ret != MSG_SUCCESS) {
                DBG("ret = %d\n", ret);
                goto next;
        }
 
-       addr_info = addr_list->msg_struct_info[0];
+       count = msg_list_length(addr_list);
 
-       ret = msg_get_str_value(addr_info, MSG_ADDRESS_INFO_ADDRESS_VALUE_STR,
-                               addr_value, MAX_ADDRESS_VAL_LEN);
-       if (ret == MSG_SUCCESS)
-               DBG("addr_value %s\n", addr_value);
+       if (count != 0) {
+               addr_info = (msg_struct_t)msg_list_nth_data(addr_list, 0);
 
-       ret = msg_get_str_value(addr_info, MSG_ADDRESS_INFO_DISPLAYNAME_STR,
-                       name_value, MAX_ADDRESS_VAL_LEN);
-       if (ret == MSG_SUCCESS)
-               DBG("name_value %s\n", name_value);
+               ret = msg_get_str_value(addr_info,
+                                       MSG_ADDRESS_INFO_ADDRESS_VALUE_STR,
+                                       addr_value, MAX_ADDRESS_VAL_LEN);
+               if (ret == MSG_SUCCESS)
+                       DBG_SECURE("addr_value %s\n", addr_value);
 
-       if (!strlen(name_value))
-               g_stpcpy(name_value, addr_value);
+               ret = msg_get_str_value(addr_info,
+                                       MSG_ADDRESS_INFO_DISPLAYNAME_STR,
+                                       name_value, MAX_DISPLAY_NAME_LEN);
+
+               if (ret == MSG_SUCCESS)
+                       DBG_SECURE("name_value %s\n", name_value);
 
-       DBG("name_value %s\n", name_value);
+               if (!strlen(name_value))
+                       g_stpcpy(name_value, addr_value);
+
+               DBG_SECURE("name_value %s\n", name_value);
+       }
 
-       ret = msg_get_int_value(msg, MSG_MESSAGE_DIRECTION_INT, &direction_type);
+       ret = msg_get_int_value(msg, MSG_MESSAGE_DIRECTION_INT,
+                                               &direction_type);
        if (ret != MSG_SUCCESS)
                goto next;
 
@@ -653,7 +1066,10 @@ next:
        msg_release_struct(&msg);
        msg_release_struct(&send_opt);
 
-       ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_DISPLAY_TIME_INT, &dptime);
+       g_free(msg_info.handle);
+
+       ret = msg_get_int_value(msg_struct_handle,
+                               MSG_MESSAGE_DISPLAY_TIME_INT, &dptime);
        if (ret == MSG_SUCCESS) {
                __get_msg_timestamp((time_t *)&dptime, msg_datetime);
        }
@@ -665,48 +1081,16 @@ next:
                DBG("m_type %d\n", m_type);
        }
 
-       switch (m_type) {
-       case MSG_TYPE_MMS:
-       case MSG_TYPE_MMS_JAVA:
-       case MSG_TYPE_MMS_NOTI:
-               msg_info.type = g_strdup("MMS");
-               break;
-
-       default:
-               msg_info.type = g_strdup("SMS_GSM");
-               break;
-       }
-
-       if (m_type == MSG_TYPE_MMS) {
-               ret = msg_get_str_value(msg_struct_handle,
-                                       MSG_MESSAGE_SUBJECT_STR, msg_subject,
-                                       BT_MAP_SUBJECT_MAX_LEN);
-               if (ret == MSG_SUCCESS) {
-                       DBG("MMS subject %s", msg_subject);
-               }
-
-               msg_info.subject = g_strdup(msg_subject);
+       msg_info.type = g_strdup("SMS_GSM");
 
-               ret = msg_get_str_value(msg_struct_handle,
-                                       MSG_MESSAGE_MMS_TEXT_STR, msg_body,
-                                       BT_MAP_MSG_BODY_MAX);
-               if (ret == MSG_SUCCESS) {
-                       DBG("msg_body %s", msg_body);
-                       if (strlen(msg_body))
-                               msg_info.text = TRUE ;
-               }
-
-       } else if (m_type == MSG_TYPE_SMS) {
-               ret = msg_get_str_value(msg_struct_handle,
-                                       MSG_MESSAGE_SMS_DATA_STR, msg_body,
-                                       BT_MAP_MSG_BODY_MAX);
-               if (ret == MSG_SUCCESS) {
-                       DBG("SMS subject %s", msg_body);
-                       if (strlen(msg_body)) {
-                               msg_info.text = TRUE ;
-                               msg_info.subject = g_strndup(msg_body,
-                                                       BT_MAP_SUBJECT_MAX_LEN);
-                       }
+       ret = msg_get_str_value(msg_struct_handle,
+                               MSG_MESSAGE_SMS_DATA_STR, msg_body,
+                               BT_MAP_MSG_BODY_MAX);
+       if (ret == MSG_SUCCESS) {
+               DBG_SECURE("SMS subject %s", msg_body);
+               if (strlen(msg_body)) {
+                       msg_info.text = TRUE ;
+                       msg_info.subject = __bt_get_truncated_utf8_string(msg_body);
                }
        }
 
@@ -741,6 +1125,7 @@ next:
                        msg_info.priority = TRUE;
        }
 
+       FN_END;
        return msg_info;
 }
 
@@ -748,316 +1133,209 @@ static void __bluetooth_map_msg_incoming_status_cb(msg_handle_t handle,
                                                        msg_struct_t msg,
                                                        void *user_param)
 {
-       DBusGProxy *mns_proxy;
-       GError *error = NULL;
-
+       FN_START;
        int msg_id = 0;
        int msg_type = 0;
-       int ret = MSG_SUCCESS;
-
-       char *message_type = NULL;
+       int ret;
 
        guint64 uid;
 
-       DBG("+\n");
-
-       ret = msg_get_int_value(msg, MSG_MESSAGE_ID_INT, &msg_id);
-       if (ret != MSG_SUCCESS)
-               return;;
-
-       uid = __bt_add_id(msg_id);
+       if (!g_mns_proxy) {
+               INFO("MNS Client not connected");
+               return;
+       }
 
        ret = msg_get_int_value(msg, MSG_MESSAGE_TYPE_INT, &msg_type);
        if (ret != MSG_SUCCESS)
                return;
 
-       switch (msg_type) {
-       case MSG_TYPE_SMS:
-               message_type = g_strdup("SMS_GSM");
-               break;
-       case MSG_TYPE_MMS:
-               message_type = g_strdup("MMS");
-               break;
-       default:
-               return;
-       }
-
-       mns_proxy = dbus_g_proxy_new_for_name(g_connection, OBEX_CLIENT_SERVICE,
-                                                       g_mns_path,
-                                                       MNS_CLIENT_INTERFACE);
-       if (mns_proxy == NULL) {
-               ERR("Failed to get a proxy for D-Bus\n");
-               g_free(message_type);
+       if (msg_type != MSG_TYPE_SMS) {
+               INFO("Not a SMS");
                return;
        }
 
-       dbus_g_proxy_call(mns_proxy, "SendEvent", &error,
-               G_TYPE_STRING, "NewMessage",
-               G_TYPE_UINT64, uid,
-               G_TYPE_STRING, "TELECOM/MSG/INBOX",
-               G_TYPE_STRING, "",
-               G_TYPE_STRING, message_type,
-               G_TYPE_INVALID, G_TYPE_INVALID);
-       if (error) {
-               DBG("Error [%s]", error->message);
-               g_error_free(error);
+       ret = msg_get_int_value(msg, MSG_MESSAGE_ID_INT, &msg_id);
+       if (ret != MSG_SUCCESS)
+               return;;
+
+       uid = __bt_add_id(msg_id);
+
+       __bt_mns_client_event_notify("NewMessage", uid,
+                                               "TELECOM/MSG/INBOX", "",
+                                               "SMS_GSM");
+
+       FN_END;
+       return;
+}
+
+static void __bluetooth_map_msg_sent_status_cb(msg_handle_t handle,
+                                                       msg_struct_t msg,
+                                                       void *user_param)
+{
+       FN_START;
+       int ret;
+       int status;
+
+       if (!g_mns_proxy) {
+               INFO("MNS Client not connected");
+               return;
        }
 
-       DBG("-\n");
-       g_free(message_type);
-       g_object_unref(mns_proxy);
+       ret = msg_get_int_value(msg, MSG_SENT_STATUS_NETWORK_STATUS_INT,
+                                                               &status);
+       if (ret != MSG_SUCCESS)
+               return;
+
+       if (status == MSG_NETWORK_SEND_SUCCESS) {
+               INFO("MSG SENT SUCCESS !!! ");
+               __bt_mns_client_event_notify("MessageShift",
+                                       current_push_map_id,
+                                       "TELECOM/MSG/SENT",
+                                       "TELECOM/MSG/OUTBOX",
+                                       "SMS_GSM");
+
+               __bt_mns_client_event_notify("SendingSuccess",
+                                       current_push_map_id,
+                                       "TELECOM/MSG/SENT", "",
+                                       "SMS_GSM");
+       } else {
+               ERR("MSG SENT FAIL !!! [%d]", status);
+               __bt_mns_client_event_notify("SendingFailure",
+                                       current_push_map_id,
+                                       "TELECOM/MSG/OUTBOX", "",
+                                       "SMS_GSM");
+       }
+
+       FN_END;
        return;
 }
 
 static gboolean __bluetooth_map_start_service()
 {
-       msg_error_t err = MSG_SUCCESS;
-       gboolean msg_ret = TRUE;
-#ifdef SUPPORT_EMAIL
-       int email_err = EMAIL_ERROR_NONE;
-       gboolean email_ret = TRUE;
-#endif
+       FN_START;
+       msg_error_t err;
 
        err = msg_open_msg_handle(&g_msg_handle);
        if (err != MSG_SUCCESS) {
                ERR("msg_open_msg_handle error = %d\n", err);
-               msg_ret = FALSE;
-               goto done;
+               return FALSE;
        }
 
+       if (-1 == __bt_get_folder_id(BT_MAP_DELETED_FOLDER_NAME))
+               __bt_add_deleted_folder();
+
        err = msg_reg_sms_message_callback(g_msg_handle,
                                        __bluetooth_map_msg_incoming_status_cb,
                                        0, (void *)BT_MAP_MSG_CB);
        if (err != MSG_SUCCESS) {
                ERR("msg_reg_sms_message_callback error  = %d\n", err);
-               msg_ret = FALSE;
-       }
-
-done:
-
-#ifdef SUPPORT_EMAIL
-
-       email_err = email_service_begin();
-       if (email_err != EMAIL_ERROR_NONE) {
-               ERR("email_service_begin fail  error = %d\n", email_err);
-               email_ret = FALSE;
+               return FALSE;
        }
 
-       if (msg_ret || email_ret)
-               return TRUE;
-       else
+       err = msg_reg_sent_status_callback(g_msg_handle,
+                                       __bluetooth_map_msg_sent_status_cb,
+                                       NULL);
+       if (err != MSG_SUCCESS) {
+               ERR("msg_reg_sent_status_callback error  = %d\n", err);
                return FALSE;
+       }
 
-#else
-
-       return msg_ret;
-
-#endif
+       FN_END;
+       return TRUE;
 }
 
 static void __bluetooth_map_stop_service()
 {
+       FN_START;
+       msg_error_t err =  MSG_SUCCESS;
+       int folder_id;
+
+       folder_id = __bt_get_folder_id(BT_MAP_DELETED_FOLDER_NAME);
+       if (-1 != folder_id) {
+               err = msg_delete_folder(g_msg_handle, folder_id);
+               if (err != MSG_SUCCESS)
+                       ERR("Delete folder failed");
+       }
+
        if (NULL != g_msg_handle)
                msg_close_msg_handle(&g_msg_handle);
 
        g_msg_handle = NULL;
 
-#ifdef SUPPORT_EMAIL
-       if (EMAIL_ERROR_NONE != email_service_end())
-               ERR("email_service_end fail \n");
-#endif
+       FN_END;
        return;
 }
 
-#ifdef SUPPORT_EMAIL
-static int __bt_store_mail(email_mailbox_type_e type, char *subject,
-                                               char *body, char *recepients)
+static gboolean __bt_validate_utf8(char **text)
 {
-       int account_id;
-       int mail_id;
-       int err;
-       char from_address[BT_MAIL_ID_MAX_LENGTH] = { 0, };
-       FILE *body_file;
-       struct stat st_buf;
-
-       email_account_t *account_data = NULL;
-       email_mailbox_t *mailbox_data = NULL;
-       email_mail_data_t *mail_data = NULL;
-
-       err = email_load_default_account_id(&account_id);
-       if (EMAIL_ERROR_NONE != err)
-               goto fail;
-
-       err = email_get_account(account_id, GET_FULL_DATA_WITHOUT_PASSWORD,
-                                                               &account_data);
-       if (EMAIL_ERROR_NONE != err)
-               goto fail;
-
-       err = email_get_mailbox_by_mailbox_type(account_id, type,
-                                                               &mailbox_data);
-       if (EMAIL_ERROR_NONE != err)
-               goto fail;
-
-       snprintf(from_address, BT_MAIL_ID_MAX_LENGTH, "<%s>",
-                                       account_data->user_email_address);
-       email_free_account(&account_data, 1);
-
-       mail_data = calloc(1, sizeof(email_mail_data_t));
-       if (NULL == mail_data) {
-               email_free_mailbox(&mailbox_data, 1);
-               goto fail;
-       }
-
-       DBG("\n account_id %d\n", account_id);
-       mail_data->account_id = account_id;
-       mail_data->save_status = 1;
-       mail_data->body_download_status = 1;
-       /* mail_data->flags_draft_field = 1; */
-       mail_data->flags_seen_field = 1;
-       mail_data->file_path_plain = g_strdup(BT_MAIL_TEMP_BODY);
-
-       mail_data->mailbox_id = mailbox_data->mailbox_id;
-       mail_data->mailbox_type = mailbox_data->mailbox_type;
-       email_free_mailbox(&mailbox_data, 1);
-
-       mail_data->full_address_from = g_strdup(from_address);
-       mail_data->full_address_to = g_strdup(recepients);
-       mail_data->subject = g_strdup(subject);
-       mail_data->report_status = EMAIL_MAIL_REQUEST_DSN |
-                                                       EMAIL_MAIL_REQUEST_MDN;
-
-       body_file = fopen(BT_MAIL_TEMP_BODY, "w");
-       if (body_file == NULL) {
-               DBG("\n fopen [%s]failed\n", BT_MAIL_TEMP_BODY);
-               email_free_mail_data(&mail_data, 1);
-               goto fail;
-       }
-
-       fprintf(body_file, body);
-       fflush(body_file);
-       fclose(body_file);
-
-       err = email_add_mail(mail_data, NULL, 0, NULL, 0);
-       if (err != EMAIL_ERROR_NONE) {
-               DBG("email_add_mail failed. [%d]\n", err);
-               if (!stat(mail_data->file_path_plain, &st_buf))
-                       remove(mail_data->file_path_plain);
-
-               email_free_mail_data(&mail_data, 1);
-               goto fail;
-       }
-
-       DBG("saved mail id = [%d]\n", mail_data->mail_id);
-
-       mail_id = mail_data->mail_id;
-
-       email_free_mail_data(&mail_data, 1);
-
-       return mail_id;
+       FN_START;
+       if (g_utf8_validate(*text, -1, NULL))
+               return TRUE;
 
-fail:
-       return 0;
+       FN_END;
+       return FALSE;
 }
 
-static int __bt_email_send(char *subject, char *body, char* recepients)
+static gboolean __bt_validate_msg_data(struct message_info *msg_info)
 {
-       int err;
-       int mail_id;
-       int handle;
-
-       mail_id = __bt_store_mail(EMAIL_MAILBOX_TYPE_OUTBOX, subject,
-                                                       body, recepients);
-       if (mail_id) {
-               DBG("mail_id = %d\n", mail_id);
-               err = email_send_mail(mail_id, &handle);
-               if (err != EMAIL_ERROR_NONE)
-                       DBG("Sending failed[%d]\n", err);
-       }
+       FN_START;
+       if (msg_info == NULL)
+               return FALSE;
 
-       return mail_id;
-}
-#endif
+       if (msg_info->subject)
+               return __bt_validate_utf8(&msg_info->subject);
 
-static int __bt_get_folder_id(char *folder_path)
-{
-       int folder_id = -1;
-       int i;
-       char *folder;
-       msg_struct_list_s folder_list;
-       msg_error_t err;
-       msg_struct_t p_folder;
-       DBG("__bt_get_folder_id\n");
+       if (msg_info->sender_name)
+               return __bt_validate_utf8(&msg_info->sender_name);
 
-       folder = strrchr(folder_path, '/');
-       if (NULL == folder)
-               return -1;
-
-       folder++;
+       if (msg_info->sender_addressing)
+               return __bt_validate_utf8(&msg_info->sender_addressing);
 
-       DBG("folderName %s\n", folder);
+       if (msg_info->replyto_addressing)
+               return __bt_validate_utf8(&msg_info->replyto_addressing);
 
-       err = msg_get_folder_list(g_msg_handle, &folder_list);
-       if (err != MSG_SUCCESS)
-               return -1;
+       if (msg_info->recipient_name)
+               return __bt_validate_utf8(&msg_info->recipient_name);
 
-       for (i = 0; i < folder_list.nCount; i++) {
-               p_folder = folder_list.msg_struct_info[i];
-               char folder_name[BT_MAP_MSG_INFO_MAX] = {0, };
-
-               err = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
-                                       folder_name, BT_MAP_MSG_INFO_MAX);
-               if (err != MSG_SUCCESS)
-                       continue;
-
-               DBG("folderName %s\n", folder_name);
-               if (!g_ascii_strncasecmp(folder_name, folder, strlen(folder))) {
-                       err = msg_get_int_value(p_folder, MSG_FOLDER_INFO_ID_INT,
-                                                               &folder_id);
-                       if (err != MSG_SUCCESS)
-                               return -1;
-
-                       break;
-               }
-       }
-
-       return folder_id;
+       if (msg_info->recipient_addressing)
+               return __bt_validate_utf8(&msg_info->recipient_addressing);
 
+       FN_END;
+       return TRUE;
 }
 
-msg_error_t __bt_send_sms(int msg_id, msg_struct_t pMsg, msg_struct_t pSendOpt)
+msg_error_t __bt_send_sms(int msg_id, msg_struct_t p_msg, msg_struct_t p_send_opt)
 {
+       FN_START;
        msg_error_t err;
-       msg_struct_t pReq;
+       msg_struct_t p_req;
 
-       pReq = msg_create_struct(MSG_STRUCT_REQUEST_INFO);
+       p_req = msg_create_struct(MSG_STRUCT_REQUEST_INFO);
 
-       msg_set_int_value(pMsg, MSG_MESSAGE_ID_INT, msg_id);
-       msg_set_struct_handle(pReq, MSG_REQUEST_MESSAGE_HND, pMsg);
-       msg_set_struct_handle(pReq, MSG_REQUEST_SENDOPT_HND, pSendOpt);
+       msg_set_int_value(p_msg, MSG_MESSAGE_ID_INT, msg_id);
+       msg_set_struct_handle(p_req, MSG_REQUEST_MESSAGE_HND, p_msg);
+       msg_set_struct_handle(p_req, MSG_REQUEST_SENDOPT_HND, p_send_opt);
 
-       err = msg_sms_send_message(g_msg_handle, pReq);
-       if (err == MSG_SUCCESS)
-               DBG("Sending Message is successful!!!");
-       else
-               DBG("Sending Message is failed!!! %d", err);
+       err = msg_sms_send_message(g_msg_handle, p_req);
+       if (err != MSG_SUCCESS)
+               ERR("Failed msg_sms_send_message %d", err);
 
-       msg_release_struct(&pReq);
+       msg_release_struct(&p_req);
+       FN_END;
        return err;
 }
 
 static int __bt_push_sms(gboolean send, int folder_id, char *body,
                                                        GSList *recepients)
 {
-       DBG("+ \n");
+       FN_START;
        msg_struct_t msg_info = NULL;
        msg_struct_t send_opt = NULL;
-       msg_struct_list_s *addr_list;
        msg_error_t err;
 
        int count = 0;
        int i = 0;
-       int msg_id;
-       guint64 uid = -1;
+       int msg_id = -1;
 
        msg_info = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
        if (msg_info == NULL)
@@ -1068,8 +1346,9 @@ static int __bt_push_sms(gboolean send, int folder_id, char *body,
                goto fail;
 
        if (body) {
-               err = msg_set_str_value(msg_info, MSG_MESSAGE_SMS_DATA_STR, body,
-                                                                       strlen(body));
+               err = msg_set_str_value(msg_info,
+                                       MSG_MESSAGE_SMS_DATA_STR,
+                                       body, strlen(body));
                if (err != MSG_SUCCESS)
                        goto fail;
        } else {
@@ -1088,27 +1367,24 @@ static int __bt_push_sms(gboolean send, int folder_id, char *body,
        if (recepients) {
                count = g_slist_length(recepients);
                DBG("Count = %d\n", count);
-               msg_get_list_handle(msg_info, MSG_MESSAGE_ADDR_LIST_STRUCT,
-                                                       (void**)&addr_list);
 
-               addr_list->nCount = count;
                for (i = 0; i < count; i++) {
+                       msg_struct_t tmp_addr;
                        char *address = (char *)g_slist_nth_data(recepients, i);
                        if (address == NULL) {
-                               DBG("[ERROR] address is value NULL, skip");
+                               ERR("[ERROR] address is value NULL, skip");
                                continue;
                        }
-                       msg_set_int_value(addr_list->msg_struct_info[i],
-                                       MSG_ADDRESS_INFO_ADDRESS_TYPE_INT,
-                                       MSG_ADDRESS_TYPE_PLMN);
+                       msg_list_add_item(msg_info,
+                               MSG_MESSAGE_ADDR_LIST_HND, &tmp_addr);
 
-                       msg_set_int_value(addr_list->msg_struct_info[i],
-                                       MSG_ADDRESS_INFO_RECIPIENT_TYPE_INT,
-                                       MSG_RECIPIENTS_TYPE_TO);
+                       msg_set_int_value(tmp_addr,
+                               MSG_ADDRESS_INFO_RECIPIENT_TYPE_INT,
+                               MSG_RECIPIENTS_TYPE_TO);
 
-                       msg_set_str_value(addr_list->msg_struct_info[i],
-                                       MSG_ADDRESS_INFO_ADDRESS_VALUE_STR,
-                                       address, strlen(address));
+                       msg_set_str_value(tmp_addr,
+                               MSG_ADDRESS_INFO_ADDRESS_VALUE_STR,
+                               address, strlen(address));
                }
        }
 
@@ -1126,55 +1402,36 @@ static int __bt_push_sms(gboolean send, int folder_id, char *body,
 
        msg_id = msg_add_message(g_msg_handle, msg_info, send_opt);
        DBG("msg_id = %d\n", msg_id);
-       uid = __bt_add_id(msg_id);
 
-       if (send == TRUE) {
-               err = __bt_send_sms(msg_id, msg_info, send_opt);
-               if (err != MSG_SUCCESS) {
-                       uid = -1;
-                       goto fail;
-               }
-       }
+       if (send == TRUE)
+               __bt_send_sms(msg_id, msg_info, send_opt);
+
 
 fail:
        msg_release_struct(&msg_info);
        msg_release_struct(&send_opt);
-       DBG("-\n");
-       return uid;
-}
-
-static gboolean __bt_msg_is_mms(int msg_type)
-{
-       gboolean result = FALSE;
-
-       switch (msg_type) {
-       case MSG_TYPE_MMS_NOTI:
-       case MSG_TYPE_MMS_JAVA:
-       case MSG_TYPE_MMS:
-               result = TRUE;
-               break;
-       default:
-               break;
-       }
-
-       return result;
+       FN_END;
+       return msg_id;
 }
 
 static void __bt_mns_client_connect(char *address)
 {
-       DBusGProxy *mns_proxy;
+       FN_START;
        GHashTable *hash;
-       GValue *addr_value;
        GValue *tgt_value;
        GError *error = NULL;
        const char *session_path = NULL;
 
-       DBG("+ address %s\n", address);
+       if (g_mns_proxy) {
+               DBG_SECURE("MNS Client already connected to %s", address);
+               return;
+       }
 
-       mns_proxy = dbus_g_proxy_new_for_name(g_connection, OBEX_CLIENT_SERVICE,
+       g_mns_proxy = dbus_g_proxy_new_for_name(g_connection,
+                                               OBEX_CLIENT_SERVICE,
                                                OBEX_CLIENT_PATH,
                                                OBEX_CLIENT_INTERFACE);
-       if (mns_proxy == NULL) {
+       if (!g_mns_proxy) {
                ERR("Failed to get a proxy for D-Bus\n");
                return;
        }
@@ -1182,26 +1439,23 @@ static void __bt_mns_client_connect(char *address)
        hash = g_hash_table_new_full(g_str_hash, g_str_equal,
                                     NULL, (GDestroyNotify)g_free);
 
-       addr_value = g_new0(GValue, 1);
-       g_value_init(addr_value, G_TYPE_STRING);
-       g_value_set_string(addr_value, address);
-       g_hash_table_insert(hash, "Destination", addr_value);
-
        tgt_value = g_new0(GValue, 1);
        g_value_init(tgt_value, G_TYPE_STRING);
        g_value_set_string(tgt_value, "MNS");
        g_hash_table_insert(hash, "Target", tgt_value);
 
-       dbus_g_proxy_call(mns_proxy, "CreateSession", &error,
+       dbus_g_proxy_call(g_mns_proxy, "CreateSession", &error,
+               G_TYPE_STRING,address,
                dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
                hash, G_TYPE_INVALID,
                DBUS_TYPE_G_OBJECT_PATH, &session_path,
                G_TYPE_INVALID);
        if (error) {
-               DBG("Error [%s]", error->message);
+               ERR("Error [%s]", error->message);
                g_error_free(error);
                g_hash_table_destroy(hash);
-               g_object_unref(mns_proxy);
+               g_object_unref(g_mns_proxy);
+               g_mns_proxy = NULL;
                return;
        }
 
@@ -1209,50 +1463,81 @@ static void __bt_mns_client_connect(char *address)
        DBG("g_mns_path = %s\n", g_mns_path);
 
        g_hash_table_destroy(hash);
-       g_object_unref(mns_proxy);
 
-       DBG("-\n");
+       FN_END;
        return;
 }
 
 static void __bt_mns_client_disconnect()
 {
-       DBusGProxy *mns_proxy;
+       FN_START;
        GError *error = NULL;
 
-       if (!g_mns_path)
-               return;
-
-       mns_proxy = dbus_g_proxy_new_for_name(g_connection, OBEX_CLIENT_SERVICE,
-                                               OBEX_CLIENT_PATH,
-                                               OBEX_CLIENT_INTERFACE);
-       if (mns_proxy == NULL) {
-               DBG("Failed to get a proxy for D-Bus\n");
+       if (!g_mns_proxy) {
+               ERR("No proxy to disconnect");
                return;
        }
 
-       dbus_g_proxy_call(mns_proxy, "RemoveSession", &error,
+       dbus_g_proxy_call(g_mns_proxy, "RemoveSession", &error,
                DBUS_TYPE_G_OBJECT_PATH, g_mns_path,
                G_TYPE_INVALID, G_TYPE_INVALID);
        if (error) {
-               DBG("Error [%s]", error->message);
+               ERR("Error [%s]", error->message);
                g_error_free(error);
-               g_object_unref(mns_proxy);
-               return;
        }
 
        g_free(g_mns_path);
        g_mns_path = NULL;
 
-       g_object_unref(mns_proxy);
+       g_object_unref(g_mns_proxy);
+       g_mns_proxy = NULL;
 
-       DBG("-\n");
+       FN_END;
        return;
 }
 
+static void __bt_mns_client_event_notify(gchar *event, guint64 handle,
+                                       gchar *folder, gchar *old_folder,
+                                       gchar *msg_type)
+{
+       FN_START;
+       GError *error = NULL;
+       DBusGProxy *mns_proxy;
+
+       if (!g_mns_proxy) {
+               ERR("No client proxy");
+               return;
+       }
+
+       mns_proxy = dbus_g_proxy_new_for_name(g_connection,
+                                               OBEX_CLIENT_SERVICE,
+                                               g_mns_path,
+                                               MNS_CLIENT_INTERFACE);
+       if (mns_proxy == NULL) {
+               ERR("Failed to get a proxy for D-Bus\n");
+               return;
+       }
+
+       dbus_g_proxy_call(mns_proxy, "SendEvent", &error,
+               G_TYPE_STRING, event,
+               G_TYPE_UINT64, handle,
+               G_TYPE_STRING, folder,
+               G_TYPE_STRING, old_folder,
+               G_TYPE_STRING, msg_type,
+               G_TYPE_INVALID, G_TYPE_INVALID);
+       if (error) {
+               ERR("Error [%s]", error->message);
+               g_error_free(error);
+       }
+
+       g_object_unref(mns_proxy);
+       FN_END;
+}
+
 static gboolean bluetooth_map_get_folder_tree(BluetoothMapAgent *agent,
                                                DBusGMethodInvocation *context)
 {
+       FN_START;
        GPtrArray *array = g_ptr_array_new();
        GValue value;
        GError *error = NULL;
@@ -1263,29 +1548,21 @@ static gboolean bluetooth_map_get_folder_tree(BluetoothMapAgent *agent,
        int ret;
        gboolean msg_ret = TRUE;
 
-       msg_struct_list_s g_folderList;
+       msg_struct_list_s folder_list = {0,};
        msg_struct_t p_folder;
 
-#ifdef SUPPORT_EMAIL
-       int j;
-       int account_id = 0;
-       int mailbox_count = 0;
-       gboolean flag = FALSE;
-       email_mailbox_t *mailbox_list = NULL;
-#endif
-
        if (g_msg_handle == NULL) {
                msg_ret = FALSE;
                goto done;
        }
 
-       if (msg_get_folder_list(g_msg_handle, &g_folderList) != MSG_SUCCESS) {
+       if (msg_get_folder_list(g_msg_handle, &folder_list) != MSG_SUCCESS) {
                msg_ret = FALSE;
                goto done;
        }
 
-       for (i = 0; i < g_folderList.nCount; i++) {
-               p_folder = g_folderList.msg_struct_info[i];
+       for (i = 0; i < folder_list.nCount; i++) {
+               p_folder = folder_list.msg_struct_info[i];
                memset(folder_name, 0x00, BT_MAP_MSG_INFO_MAX);
 
                ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
@@ -1293,6 +1570,9 @@ static gboolean bluetooth_map_get_folder_tree(BluetoothMapAgent *agent,
                if (ret != MSG_SUCCESS)
                        continue;
 
+               if (g_strstr_len(folder_name, -1, BT_MAP_MSG_TEMPLATE))
+                       continue;
+
                if (!g_ascii_strncasecmp(folder_name, BT_MAP_SENT_FOLDER_NAME,
                                        strlen(BT_MAP_SENT_FOLDER_NAME))) {
                        memset(folder_name, 0, sizeof(folder_name));
@@ -1309,64 +1589,11 @@ static gboolean bluetooth_map_get_folder_tree(BluetoothMapAgent *agent,
                g_ptr_array_add(array, g_value_get_boxed(&value));
        }
 
-#ifdef SUPPORT_EMAIL
-email:
-       if (EMAIL_ERROR_NONE != email_load_default_account_id(&account_id))
-               goto done;
-
-       if (EMAIL_ERROR_NONE != email_get_mailbox_list(account_id,
-                                                       EMAIL_MAILBOX_ALL,
-                                                       &mailbox_list,
-                                                       &mailbox_count)) {
-               goto done;
-       }
-
-       msg_ret = TRUE;
-
-       for (i = 0; i < mailbox_count; i++) {
-               flag = FALSE;
-               for (j = 0; j < g_folderList.nCount; j++) {
-
-                       p_folder = g_folderList.msg_struct_info[j];
-                       memset(folder_name, 0x00, BT_MAP_MSG_INFO_MAX);
-
-                       ret = msg_get_str_value(p_folder,
-                                               MSG_FOLDER_INFO_NAME_STR,
-                                               folder_name,
-                                               BT_MAP_MSG_INFO_MAX);
-                       if (ret != MSG_SUCCESS)
-                               continue;
-
-                       if (!g_ascii_strncasecmp(mailbox_list[i].alias,
-                               folder_name, strlen(mailbox_list[i].alias))) {
-                               flag = TRUE;
-                               break;
-                       }
-               }
-
-               if (!flag) {
-                       g_strlcpy(name, mailbox_list[i].alias, sizeof(name));
-
-                       if (!g_ascii_strncasecmp(name, BT_MAP_SENT_FOLDER_NAME,
-                                       strlen(BT_MAP_SENT_FOLDER_NAME)))
-                               continue;
-
-                       memset(&value, 0, sizeof(GValue));
-                       g_value_init(&value, DBUS_STRUCT_STRING_STRING_UINT);
-                       g_value_take_boxed(&value,
-                               dbus_g_type_specialized_construct(
-                               DBUS_STRUCT_STRING_STRING_UINT));
-                       dbus_g_type_struct_set(&value, 0, name, G_MAXUINT);
-                       g_ptr_array_add(array, g_value_get_boxed(&value));
-               }
-       }
-
-       if (mailbox_list != NULL)
-                email_free_mailbox(&mailbox_list, mailbox_count);
-#endif
-
 done:
 
+       if (folder_list.msg_struct_info)
+               msg_release_list_struct(&folder_list);
+
        if (msg_ret == FALSE) {
                g_ptr_array_free(array, TRUE);
 
@@ -1378,6 +1605,7 @@ done:
        } else {
                dbus_g_method_return(context, array);
                g_ptr_array_free(array, TRUE);
+               FN_END;
                return TRUE;
        }
 }
@@ -1386,6 +1614,7 @@ static gboolean bluetooth_map_get_message_list(BluetoothMapAgent *agent,
                                                gchar *folder_name, guint16 max,
                                                DBusGMethodInvocation *context)
 {
+       FN_START;
        GPtrArray *array = g_ptr_array_new();
        GValue value;
        GError *error = NULL;
@@ -1393,91 +1622,95 @@ static gboolean bluetooth_map_get_message_list(BluetoothMapAgent *agent,
        char *folder = NULL;
        int i = 0;
        int ret = 0;
-       int folder_id = 0;
-       int unread_cnt;
-       guint64 count;
-       gboolean newmsg;
-
-       msg_struct_list_s g_folderList;
-       msg_struct_list_s msg_list;
-       msg_struct_t count_info;
-
-#ifdef SUPPORT_EMAIL
-       int total = 0;
-       int account_id = 0;
-       int mailbox_count = 0;
-       int mail_count = 0;
-       char *type = NULL;
-       char msg_datetime[BT_MAP_TIMESTAMP_MAX_LEN] = {0,};
-       email_mailbox_t *mailbox_list = NULL;
-       email_mail_list_item_t *mail_list = NULL;
-       email_list_filter_t *filter_list = NULL;
-       email_list_sorting_rule_t *sorting_rule_list = NULL;
-#endif
+       int folder_id = -1;
+       int folder_len;
+       bool read;
+       guint64 count = 0;
+       gboolean newmsg = FALSE;
+
+       msg_struct_list_s folder_list = {0,};
+       msg_struct_list_s msg_list = {0,};
+       msg_struct_t list_cond;
 
        if (g_msg_handle == NULL)
                goto fail;
 
+       if (!folder_name)
+               goto fail;
+
+       folder_len = strlen(folder_name);
+       /* In case of parent folders send empty message listing */
+       if (!g_ascii_strncasecmp(folder_name, "/", folder_len) ||
+               !g_ascii_strncasecmp(folder_name, "/telecom", folder_len) ||
+               !g_ascii_strncasecmp(folder_name, "/telecom/msg", folder_len))
+               goto done;
+
        folder = strrchr(folder_name, '/');
        if (NULL == folder)
                folder = folder_name;
        else
                folder++;
 
-       ret = msg_get_folder_list(g_msg_handle, &g_folderList);
+       ret = msg_get_folder_list(g_msg_handle, &folder_list);
        if (ret != MSG_SUCCESS)
                goto fail;
 
-       for (i = 0; i < g_folderList.nCount; i++) {
-               msg_struct_t pFolder = g_folderList.msg_struct_info[i];
-               char folderName[BT_MAP_MSG_INFO_MAX] = {0, };
+       for (i = 0; i < folder_list.nCount; i++) {
+               char f_name[BT_MAP_MSG_INFO_MAX] = {0, };
+               msg_struct_t p_folder = folder_list.msg_struct_info[i];
 
-               ret = msg_get_str_value(pFolder, MSG_FOLDER_INFO_NAME_STR,
-                                       folderName, BT_MAP_MSG_INFO_MAX);
+               ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
+                                       f_name, BT_MAP_MSG_INFO_MAX);
                if (ret  != MSG_SUCCESS)
                        continue;
 
-               if (!g_ascii_strncasecmp(folderName, folder, strlen(folder))) {
-                       ret = msg_get_int_value(pFolder, MSG_FOLDER_INFO_ID_INT,
+               if (!g_ascii_strncasecmp(f_name, folder, strlen(folder))) {
+                       ret = msg_get_int_value(p_folder, MSG_FOLDER_INFO_ID_INT,
                                                                &folder_id);
                        if (ret != MSG_SUCCESS)
                                goto fail;
-                       else
-                               DBG("folder_id %d \n", folder_id);
+
+                       DBG("folder_id %d \n", folder_id);
 
                        break;
                }
        }
 
-       ret = msg_get_folder_view_list(g_msg_handle, folder_id,
-                                                       NULL, &msg_list);
-       if (ret  != MSG_SUCCESS)
+       if (folder_id == -1)
                goto fail;
 
-       count = msg_list.nCount;
+       list_cond = msg_create_struct(MSG_STRUCT_MSG_LIST_CONDITION);
+       ret = msg_set_int_value(list_cond,
+                               MSG_LIST_CONDITION_FOLDER_ID_INT,
+                               folder_id);
+       if (ret != MSG_SUCCESS)
+               goto fail;
 
-       count_info = msg_create_struct(MSG_STRUCT_COUNT_INFO);
-       ret = msg_count_message(g_msg_handle, folder_id, count_info);
-       if (ret != MSG_SUCCESS) {
-               msg_release_struct(&count_info);
+       ret = msg_set_int_value(list_cond,
+                               MSG_LIST_CONDITION_MSGTYPE_INT, MSG_TYPE_SMS);
+       if (ret != MSG_SUCCESS)
                goto fail;
-       }
 
-       ret = msg_get_int_value(count_info, MSG_COUNT_INFO_UNREAD_INT,
-                                                               &unread_cnt);
-       if (ret != MSG_SUCCESS) {
-               msg_release_struct(&count_info);
+       ret = msg_get_message_list2(g_msg_handle, list_cond, &msg_list);
+
+       msg_release_struct(&list_cond);
+
+       if (ret != MSG_SUCCESS)
                goto fail;
-       }
 
-       if (unread_cnt != 0)
-               newmsg = TRUE;
-       else
-               newmsg = FALSE;
+       count = msg_list.nCount;
 
-       msg_release_struct(&count_info);
+       for (i = 0; i < count; i++) {
+               msg_get_bool_value(msg_list.msg_struct_info[i],
+                                       MSG_MESSAGE_READ_BOOL, &read);
+               if (read == false) {
+                       newmsg = TRUE;
+                       break;
+               }
+       }
+
+       DBG("count = %llx, newmsg = %d, max = %d", count, newmsg, max);
 
-       DBG("MaxlistCount %d \n", max);
        if (max == 0)
                goto done;
 
@@ -1492,28 +1725,11 @@ static gboolean bluetooth_map_get_message_list(BluetoothMapAgent *agent,
 
                msg_info = __bt_message_info_get(msg_list.msg_struct_info[i]);
 
-/* Keeping the bleow debug till stabilization is done. */
-
-/*
-       DBG("msg_info.handle = %s\n", msg_info.handle);
-       DBG("msg_info.subject = %s\n", msg_info.subject);
-       DBG("msg_info.datetime = %s\n", msg_info.datetime);
-       DBG("msg_info.sender_name = %s\n", msg_info.sender_name);
-       DBG("msg_info.sender_addressing = %s\n", msg_info.sender_addressing);
-       DBG("msg_info.replyto_addressing = %s\n", msg_info.replyto_addressing);
-       DBG("msg_info.recipient_name = %s\n", msg_info.recipient_name);
-       DBG("msg_info.recipient_addressing = %s\n",
-                                       msg_info.recipient_addressing);
-       DBG("msg_info.type = %s\n", msg_info.type);
-       DBG("msg_info.reception_status = %s\n", msg_info.reception_status);
-       DBG("msg_info.size = %s\n", msg_info.size);
-       DBG("msg_info.attachment_size = %s\n", msg_info.attachment_size);
-       DBG("msg_info.text = %d\n", msg_info.text);
-       DBG("msg_info.read = %d\n", msg_info.read);
-       DBG("msg_info.sent = %d\n", msg_info.sent);
-       DBG("msg_info.protect = %d\n", msg_info.protect);
-       DBG("msg_info.priority = %d\n", msg_info.priority);
-*/
+               if (!__bt_validate_msg_data(&msg_info)) {
+                       __bt_message_info_free(msg_info);
+                       count--;
+                       continue;
+               }
 
                dbus_g_type_struct_set(&value, 0, msg_info.handle,
                                        1, msg_info.subject,
@@ -1531,135 +1747,38 @@ static gboolean bluetooth_map_get_message_list(BluetoothMapAgent *agent,
                                        13, msg_info.read,
                                        14, msg_info.sent,
                                        15, msg_info.protect,
-                                       16, msg_info.replyto_addressing, G_MAXUINT);
+                                       16, msg_info.replyto_addressing,
+                                       G_MAXUINT);
                g_ptr_array_add(array, g_value_get_boxed(&value));
 
                __bt_message_info_free(msg_info);
        }
 
-#ifdef SUPPORT_EMAIL
-email:
-       if (EMAIL_ERROR_NONE != email_load_default_account_id(&account_id)) {
-               if (!msg_ret)
-                       goto fail;
-       }
-
-       if (EMAIL_ERROR_NONE != email_get_mailbox_list(account_id,
-                                                       EMAIL_MAILBOX_ALL,
-                                                       &mailbox_list,
-                                                       &mailbox_count)) {
-               if (!msg_ret)
-                       goto fail;
-       }
-
-       if (mailbox_list == NULL)
-               goto fail;
-
-       for (i = 0; i < mailbox_count; i++) {
-               DBG("mailbox alias = %s \n", mailbox_list[i].alias);
-               if (!g_ascii_strncasecmp(mailbox_list[i].alias, folder,
-                       strlen(folder))) {
-                       total = mailbox_list[i].total_mail_count_on_server;
-                       DBG("Total mail on sever:%d\n", total);
-                       DBG("mailbox name:%s\n", mailbox_list[i].mailbox_name);
-
-                       break;
-               }
-
-               if (!msg_ret)
-                       goto fail;
-               else
-                       goto done;
-       }
-
-       /* Need to modify the filter code, have to make it dynamic
-          based on remote device request Also to check whether it needs
-          to be done in agent or in obexd */
-
-       filter_list = g_new0(email_list_filter_t, 3);
-       filter_list[0].list_filter_item_type = EMAIL_LIST_FILTER_ITEM_RULE;
-       filter_list[0].list_filter_item.rule.target_attribute =
-                                               EMAIL_MAIL_ATTRIBUTE_ACCOUNT_ID;
-       filter_list[0].list_filter_item.rule.rule_type =
-                                               EMAIL_LIST_FILTER_RULE_EQUAL;
-       filter_list[0].list_filter_item.rule.key_value.integer_type_value =
-                                                               account_id;
-
-       filter_list[1].list_filter_item_type = EMAIL_LIST_FILTER_ITEM_OPERATOR;
-       filter_list[1].list_filter_item.operator_type =
-                                               EMAIL_LIST_FILTER_OPERATOR_AND;
-
-       filter_list[2].list_filter_item_type = EMAIL_LIST_FILTER_ITEM_RULE;
-       filter_list[2].list_filter_item.rule.target_attribute =
-                                       EMAIL_MAIL_ATTRIBUTE_MAILBOX_NAME;
-       filter_list[2].list_filter_item.rule.rule_type =
-                                               EMAIL_LIST_FILTER_RULE_EQUAL;
-       type = g_strdup(mailbox_list[i].mailbox_name);
-       filter_list[2].list_filter_item.rule.key_value.string_type_value = type;
-       filter_list[2].list_filter_item.rule.case_sensitivity = true;
-
-       sorting_rule_list = g_new0(email_list_sorting_rule_t, 1);
-       sorting_rule_list->target_attribute = EMAIL_MAIL_ATTRIBUTE_DATE_TIME;
-       sorting_rule_list->sort_order = EMAIL_SORT_ORDER_ASCEND;
-
-       ret = email_get_mail_list_ex(filter_list, 3,
-                                       sorting_rule_list, 1, 0, total - 1,
-                                       &mail_list, &mail_count);
-
-       DBG("email API ret %d  \n", ret);
-       if (ret != EMAIL_ERROR_NONE) {
-               if (!msg_ret) {
-                       g_free(type);
-                       g_free(filter_list);
-                       g_free(sorting_rule_list);
-                       goto fail;
-               } else
-                       goto done;
-       }
-
-       for (i = 0; i < mail_count; ++i) {
-               time_t time = {0,};
-               memset(&value, 0, sizeof(GValue));
-               g_value_init(&value, DBUS_STRUCT_MESSAGE_LIST);
-               g_value_take_boxed(&value, dbus_g_type_specialized_construct(
-                                       DBUS_STRUCT_MESSAGE_LIST));
-
-               uid = __bt_add_id(mail_list[i].mail_id);
-               snprintf(msg_handle, sizeof(msg_handle), "%llx", uid);
-
-               g_strlcpy(msg_type,  "EMAIL", sizeof(msg_type));
-
-               time = mail_list[i].date_time;
-               __get_msg_timestamp(&time, msg_datetime);
-
-               dbus_g_type_struct_set(&value, 0, msg_handle, 1, msg_type,
-                                       2, msg_datetime, G_MAXUINT);
-               g_ptr_array_add(array, g_value_get_boxed(&value));
-       }
-
-       if (mailbox_list != NULL)
-                email_free_mailbox(&mailbox_list, mailbox_count);
-       if (mail_list != NULL)
-               g_free(mail_list);
+done:
+       if (folder_list.msg_struct_info)
+               ret = msg_release_list_struct(&folder_list);
 
-       g_free(filter_list);
-       g_free(sorting_rule_list);
-       g_free(type);
-#endif
+       if (msg_list.msg_struct_info)
+               ret = msg_release_list_struct(&msg_list);
 
-done:
-       DBG("Request completed \n");
        dbus_g_method_return(context, newmsg, count, array);
        g_ptr_array_free(array, TRUE);
-       DBG("Request completed successfully \n");
+       FN_END;
        return TRUE;
 
 fail:
+       if (folder_list.msg_struct_info)
+               ret = msg_release_list_struct(&folder_list);
+
+       if (msg_list.msg_struct_info)
+               ret = msg_release_list_struct(&msg_list);
+
        g_ptr_array_free(array, TRUE);
        error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
                                                          "InternalError");
        dbus_g_method_return_error(context, error);
        g_error_free(error);
+       ERR("fail -");
        return FALSE;
 }
 
@@ -1670,98 +1789,53 @@ static gboolean bluetooth_map_get_message(BluetoothMapAgent *agent,
                                                gboolean first_request,
                                                DBusGMethodInvocation *context)
 {
-       DBG("+ \n");
+       FN_START;
        char *buf = NULL;
        int message_id = 0;
-       int msg_type = BT_SMS;
 
        GError *error = NULL;
 
+       msg_error_t msg_err;
        msg_struct_t msg = NULL;
        msg_struct_t send_opt = NULL;
-#ifdef SUPPORT_EMAIL
-       email_mail_data_t *mail_data = NULL;
-#endif
+
        message_id = __bt_get_uid(message_name);
        if (message_id == -1)
                goto fail;
 
        DBG("message_id %d \n", message_id);
-       DBG("msg_type %d \n", msg_type);
        DBG("attach %d \n", attach);
        DBG("transcode %d \n", transcode);
        DBG("first_request %d \n", first_request);
 
-       if (msg_type == BT_SMS) {
-               if (g_msg_handle == NULL)
-                       goto fail;
-
-               msg_error_t msg_err;
-
-               msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
-               send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
-
-               msg_err = msg_get_message(g_msg_handle,
-                                               (msg_message_id_t)message_id,
-                                               msg, send_opt);
-               if (msg_err != MSG_SUCCESS)
-                       goto fail;
-
-               buf = __bt_prepare_msg_bmseg(msg, attach, transcode);
-
-               msg_release_struct(&msg);
-               msg_release_struct(&send_opt);
-#ifdef SUPPORT_EMAIL
-       } else if (msg_type == BT_EMAIL) {
-
-               FILE *body_file;
-               int account_id;
-               long read_size;
-               long email_size;
-
-               if (EMAIL_ERROR_NONE !=
-                               email_load_default_account_id(&account_id))
-                       goto fail;
-
-               if (EMAIL_ERROR_NONE !=
-                               email_get_mail_data(message_id, &mail_data))
-                       goto fail;
-
-               body_file = fopen(mail_data->file_path_plain, "r");
-               if (body_file == NULL)
-                       body_file = fopen(mail_data->file_path_html, "rb");
-
-               if (body_file != NULL) {
-                       fseek(body_file , 0, SEEK_END);
-                       email_size = ftell(body_file);
-                       rewind(body_file);
-
-                       buf = (char *)g_malloc0(sizeof(char) * email_size);
-
-                       read_size = fread(buf, 1, email_size, body_file);
+       if (g_msg_handle == NULL)
+               goto fail;
 
-                       fclose(body_file);
+       msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
+       if (!msg)
+               goto fail;
 
-                       if (read_size != email_size)
-                               goto fail;
-               } else
-                       buf = (char *)g_strdup("");
+       send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
+       if (!send_opt)
+               goto fail;
 
-               email_free_mail_data(&mail_data, 1);
-#endif
-       } else {
-               DBG("msg_type not supported %d \n", msg_type);
+       msg_err = msg_get_message(g_msg_handle,
+                                       (msg_message_id_t)message_id,
+                                       msg, send_opt);
+       if (msg_err != MSG_SUCCESS)
                goto fail;
-       }
+
+       buf = __bt_prepare_msg_bmseg(msg, attach, transcode);
 
        dbus_g_method_return(context, FALSE, buf);
+       msg_release_struct(&msg);
+       msg_release_struct(&send_opt);
        g_free(buf);
 
-       DBG("- \n");
+       FN_END;
        return TRUE;
 
 fail:
-       g_free(buf);
 
        if (msg)
                msg_release_struct(&msg);
@@ -1769,15 +1843,11 @@ fail:
        if (send_opt)
                msg_release_struct(&send_opt);
 
-#ifdef SUPPORT_EMAIL
-       if (mail_data)
-               email_free_mail_data(&mail_data, 1);
-#endif
-
        error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
                                                        "InternalError");
        dbus_g_method_return_error(context, error);
        g_error_free(error);
+       ERR("fail - \n");
        return FALSE;
 }
 
@@ -1788,16 +1858,10 @@ static gboolean bluetooth_map_push_message(BluetoothMapAgent *agent,
                                        gchar *folder_name,
                                        DBusGMethodInvocation *context)
 {
-       DBG("+\n");
-       GError *error = NULL;
+       FN_START;
        guint64 handle = 0;
-       int folder_id;
-
-       DBG("folder_name = %s\n", folder_name);
 
-       folder_id = __bt_get_folder_id(folder_name);
-       if (folder_id == -1)
-               goto fail;
+       DBG_SECURE("folder_name = %s\n", folder_name);
 
        handle = __bt_add_id(-1);
        current_push_map_id = handle;
@@ -1818,32 +1882,24 @@ static gboolean bluetooth_map_push_message(BluetoothMapAgent *agent,
        DBG("opt.native = %d\n", opt.native);
 
        dbus_g_method_return(context, handle);
-       DBG("-\n");
+       FN_END;
        return TRUE;
-fail:
-       error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
-                                               "InternalError");
-       dbus_g_method_return_error(context, error);
-       g_error_free(error);
-
-       return FALSE;
 }
 
 static gboolean bluetooth_map_push_message_data(BluetoothMapAgent *agent,
                                        gchar *bmsg,
                                        DBusGMethodInvocation *context)
 {
-       DBG("+\n");
+       FN_START;
        int id = -1;
        int folder_id;
-       char *folder = NULL;
        char *body = NULL;
        GSList *recepients = NULL;
        gboolean send = FALSE;
 
        GError *error = NULL;
 
-       DBG("BMSG is \n %s", bmsg);
+       INFO("BMSG is \n %s", bmsg);
 
        struct bmsg_data *bmsg_info = NULL;
 
@@ -1851,10 +1907,6 @@ static gboolean bluetooth_map_push_message_data(BluetoothMapAgent *agent,
        if (!bmsg_info)
                goto done;
 
-       folder = bmsg_get_msg_folder(bmsg_info);
-       if (folder == NULL)
-               goto done;
-
        folder_id = __bt_get_folder_id(bmsg_info->folder);
        if (folder_id == -1)
                goto done;
@@ -1862,7 +1914,7 @@ static gboolean bluetooth_map_push_message_data(BluetoothMapAgent *agent,
        if (MSG_OUTBOX_ID == folder_id)
                send = TRUE;
 
-       body = bmsg_get_msg_body(bmsg_info);
+       body = bmsg_get_msg_body(bmsg_info, opt.native);
        if (body == NULL)
                goto done;
 
@@ -1875,22 +1927,21 @@ static gboolean bluetooth_map_push_message_data(BluetoothMapAgent *agent,
        __bt_update_id(current_push_map_id, id);
 
 done:
-       g_free(folder);
        g_free(body);
        g_slist_free(recepients);
-       g_free(bmsg_info);
+       bmsg_free_bmsg(bmsg_info);
 
        if (id == -1) {
                error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
                                                        "InternalError");
                dbus_g_method_return_error(context, error);
                g_error_free(error);
-               DBG("-\n");
+               FN_END;
                return FALSE;
        }
 
        dbus_g_method_return(context);
-       DBG("-\n");
+       FN_END;
        return TRUE;
 }
 
@@ -1898,22 +1949,9 @@ static gboolean bluetooth_map_update_message(BluetoothMapAgent *agent,
                                                DBusGMethodInvocation *context)
 {
        int err = TRUE;
-#ifdef SUPPORT_EMAIL
-       int handle;
-       err = email_sync_header_for_all_account(&handle);
 
-       if (err == EMAIL_ERROR_NONE) {
-               DBG("Handle to stop download = %d \n", handle);
-       } else {
-               ERR("Message Update failed \n");
-       }
-
-       dbus_g_method_return(context, err);
-       return (err == EMAIL_ERROR_NONE) ? TRUE : FALSE;
-#else
        dbus_g_method_return(context, err);
        return TRUE;
-#endif
 }
 
 static gboolean bluetooth_map_set_read_status(BluetoothMapAgent *agent,
@@ -1921,91 +1959,24 @@ static gboolean bluetooth_map_set_read_status(BluetoothMapAgent *agent,
                                                gboolean read_status,
                                                DBusGMethodInvocation *context)
 {
-       int message_id = 0;
-       int msg_type = BT_SMS;
-#ifdef SUPPORT_EMAIL
-       email_mail_data_t *mail_data = NULL;
-#endif
+       FN_START;
+       int msg_id;
        GError *error = NULL;
+       msg_error_t msg_err;
 
-       DBG("+\n");
-
-       message_id = __bt_get_uid(handle);
-       if (message_id == -1)
+       msg_id = __bt_get_uid(handle);
+       if (msg_id == -1)
                goto fail;
 
-       DBG("message_id = %d,  read_status = %d\n", message_id, read_status);
+       DBG("msg_id = %d,  read_status = %d\n", msg_id, read_status);
 
-       if (msg_type == BT_SMS) {
-               msg_error_t msg_err;
-               msg_struct_t msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
-               msg_struct_t send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
-               int msg_type = 0;
-
-               msg_err = msg_get_message(g_msg_handle,
-                                               (msg_message_id_t)message_id,
-                                               msg, send_opt);
-               if (msg_err != MSG_SUCCESS) {
-                       msg_release_struct(&msg);
-                       msg_release_struct(&send_opt);
-                       goto fail;
-               }
-
-               msg_err = msg_get_int_value(msg, MSG_MESSAGE_TYPE_INT,
-                                                               &msg_type);
-               if (msg_err != MSG_SUCCESS) {
-                       msg_release_struct(&msg);
-                       msg_release_struct(&send_opt);
-                       goto fail;
-               }
-
-               msg_err = msg_update_read_status(g_msg_handle, message_id,
-                                                               read_status);
-               if (msg_err != MSG_SUCCESS) {
-                       msg_release_struct(&msg);
-                       msg_release_struct(&send_opt);
-                       goto fail;
-               }
-
-               if (__bt_msg_is_mms(msg_type)) {
-                       if (read_status == TRUE)
-                               msg_err = msg_mms_send_read_report(g_msg_handle,
-                                               message_id,
-                                               MSG_READ_REPORT_IS_READ);
-                       else
-                               msg_err = msg_mms_send_read_report(g_msg_handle,
-                                               message_id,
-                                               MSG_READ_REPORT_NONE);
-               }
-
-               msg_release_struct(&msg);
-               msg_release_struct(&send_opt);
-
-               if (msg_err != MSG_SUCCESS)
-                       goto fail;
-#ifdef SUPPORT_EMAIL
-       } else if (msg_type == BT_EMAIL) {
-
-               if (email_get_mail_data(message_id, &mail_data) !=
-                                                       EMAIL_ERROR_NONE) {
-                       ERR("email_get_mail_data failed\n");
-                       goto fail;
-               }
-
-               if (email_set_flags_field(mail_data->account_id, &message_id, 1,
-                       EMAIL_FLAGS_SEEN_FIELD, read_status, 0) !=
-                                                       EMAIL_ERROR_NONE) {
-                       email_free_mail_data(&mail_data, 1);
-                       goto fail;
-               }
-
-               email_free_mail_data(&mail_data, 1);
-#endif
-       } else
+       msg_err = msg_update_read_status(g_msg_handle, msg_id,
+                                                       read_status);
+       if (msg_err != MSG_SUCCESS)
                goto fail;
 
        dbus_g_method_return(context);
-       DBG("-\n");
+       FN_END;
        return TRUE;
 
 fail:
@@ -2014,6 +1985,7 @@ fail:
        dbus_g_method_return_error(context, error);
        g_error_free(error);
 
+       ERR("fail -\n");
        return FALSE;
 }
 
@@ -2022,53 +1994,102 @@ static gboolean bluetooth_map_set_delete_status(BluetoothMapAgent *agent,
                                                gboolean delete_status,
                                                DBusGMethodInvocation *context)
 {
-       int message_id = 0;
-       int msg_type = BT_SMS;
-#ifdef SUPPORT_EMAIL
-       email_mail_data_t *mail_data = NULL;
-#endif
+       FN_START;
+       int msg_id = 0;
+       int folder_id;
+       int del_folder_id;
+       gchar *folder_name = NULL;
+       guint64 map_id;
        GError *error = NULL;
+       msg_error_t err;
+       msg_struct_t msg = NULL;
+       msg_struct_t send_opt = NULL;
 
-       DBG("+\n");
+       msg_id = __bt_get_uid(handle);
+       if (msg_id == -1)
+               goto fail;
 
-       message_id = __bt_get_uid(handle);
-       if (message_id == -1)
+       if (g_msg_handle == NULL)
                goto fail;
 
-       DBG("message_id = %d, delete_status = %d\n", message_id, delete_status);
+       msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
+       if (msg == NULL)
+               goto fail;
 
-       if (msg_type == BT_SMS) {
-               if (msg_delete_message(g_msg_handle, message_id) !=
-                                                               MSG_SUCCESS) {
-                       goto fail;
-               }
-#ifdef SUPPORT_EMAIL
-       } else if (msg_type == BT_EMAIL) {
+       send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
+       if (send_opt == NULL)
+               goto fail;
 
-               if (email_get_mail_data(message_id, &mail_data) !=
-                                                       EMAIL_ERROR_NONE)
-                       goto fail;
+       err = msg_get_message(g_msg_handle,
+                                       (msg_message_id_t)msg_id,
+                                       msg, send_opt);
+       if (err != MSG_SUCCESS)
+               goto fail;
 
-               if (email_delete_mail(mail_data->mailbox_id, &message_id,
-                                               1, 1) != EMAIL_ERROR_NONE) {
-                       email_free_mail_data(&mail_data, 1);
-                       goto fail;
+       err = msg_get_int_value(msg, MSG_MESSAGE_FOLDER_ID_INT,
+                                                       &folder_id);
+       if (err != MSG_SUCCESS)
+               goto fail;
+
+       folder_name = __bt_get_folder_name(folder_id);
+       del_folder_id = __bt_get_folder_id(BT_MAP_DELETED_FOLDER_NAME);
+       map_id = __bt_validate_uid(msg_id);
+
+       DBG("msg_id = %d, delete_status = %d\n", msg_id, delete_status);
+
+       if (-1 == del_folder_id) {
+               ERR("Delete folder not present");
+               if (delete_status == TRUE) {
+                       err = msg_delete_message(g_msg_handle, msg_id);
+                       if (err != MSG_SUCCESS)
+                               goto fail;
                }
 
-               email_free_mail_data(&mail_data, 1);
-#endif
-       } else
-               goto fail;
+       } else {
+               if (delete_status == TRUE) {
+                       err = msg_move_msg_to_folder(g_msg_handle, msg_id, del_folder_id);
+                       if (err == MSG_SUCCESS) {
+                               __bt_mns_client_event_notify("MessageShift",
+                                               map_id,
+                                               "TELECOM/MSG/DELETED",
+                                               folder_name,
+                                               "SMS_GSM");
+                       }
+               } else {
+                       if (folder_id != del_folder_id) {
+                               DBG("Message not in delete folder");
+                               goto fail;
+                       }
+
+                       err = msg_move_msg_to_folder(g_msg_handle, msg_id, MSG_INBOX_ID);
+                       if (err == MSG_SUCCESS) {
+                               __bt_mns_client_event_notify("MessageShift",
+                                               map_id,
+                                               "TELECOM/MSG/INBOX",
+                                               "TELECOM/MSG/DELETED",
+                                               "SMS_GSM");
+                       }
+               }
+       }
 
+       g_free(folder_name);
+       msg_release_struct(&msg);
+       msg_release_struct(&send_opt);
        dbus_g_method_return(context);
-       DBG("-\n");
+       FN_END;
        return TRUE;
 
 fail:
+       g_free(folder_name);
+
+       msg_release_struct(&msg);
+       msg_release_struct(&send_opt);
+
        error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
                                                        "InternalError");
        dbus_g_method_return_error(context, error);
        g_error_free(error);
+       ERR("fail -\n");
        return FALSE;
 }
 
@@ -2077,7 +2098,8 @@ static gboolean bluetooth_map_noti_registration(BluetoothMapAgent *agent,
                                                gboolean status,
                                                DBusGMethodInvocation *context)
 {
-       DBG("remote_addr = %s \n", remote_addr);
+       FN_START;
+       DBG_SECURE("remote_addr = %s \n", remote_addr);
 
        if (status == TRUE)
                __bt_mns_client_connect(remote_addr);
@@ -2087,16 +2109,23 @@ static gboolean bluetooth_map_noti_registration(BluetoothMapAgent *agent,
        return TRUE;
 }
 
-#endif
-
+static gboolean bluetooth_map_destroy_agent(BluetoothMapAgent *agent,
+                                       DBusGMethodInvocation *context)
+{
+       FN_START;
+       g_main_loop_quit(g_mainloop);
+       return TRUE;
+}
 
-int main(int argc, char **argv)
+int main(void)
 {
-#if 0
+       FN_START;
        BluetoothMapAgent *bluetooth_map_obj = NULL;
        DBusGProxy *bus_proxy = NULL;
        guint result = 0;
+       int ret;
        GError *error = NULL;
+       DBG("Starting Bluetooth MAP agent");
 
        g_type_init();
 
@@ -2133,7 +2162,7 @@ int main(int argc, char **argv)
                }
                goto failure;
        }
-       DBG("result : %d %d\n", result, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
+
        if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
                ERR("Failed to get the primary well-known name.\n");
                goto failure;
@@ -2143,10 +2172,6 @@ int main(int argc, char **argv)
        bus_proxy = NULL;
 
        bluetooth_map_obj = g_object_new(BLUETOOTH_MAP_TYPE_AGENT, NULL);
-       if (bluetooth_map_obj == NULL) {
-               ERR("Failed to create one BluetoothMapAgent instance.\n");
-               goto failure;
-       }
 
        /* Registering it on the D-Bus */
        dbus_g_connection_register_g_object(g_connection,
@@ -2156,15 +2181,27 @@ int main(int argc, char **argv)
        if (__bluetooth_map_start_service() == FALSE)
                goto failure;
 
+       g_tapi_handle = tel_init(NULL);
+       if (!g_tapi_handle)
+               goto failure;
+
+       ret = tel_get_sms_sca(g_tapi_handle, 0, __bt_get_sms_sca, NULL);
+       if (ret != TAPI_API_SUCCESS) {
+               ERR("TAPI err = %d", ret);
+               goto failure;
+       }
+
        g_main_loop_run(g_mainloop);
 
  failure:
-       DBG("Terminate the bluetooth-map-agent\n");
 
        __bt_remove_list(id_list);
 
-       if (g_mns_path)
-               __bt_mns_client_disconnect();
+       tel_deinit(g_tapi_handle);
+       g_free(g_sca_info);
+
+       __bt_mns_client_disconnect();
+
        if (bus_proxy)
                g_object_unref(bus_proxy);
        if (bluetooth_map_obj)
@@ -2172,10 +2209,8 @@ int main(int argc, char **argv)
        if (g_connection)
                dbus_g_connection_unref(g_connection);
 
-
        __bluetooth_map_stop_service();
+       DBG("Bluetooth MAP agent Terminated successfully\n");
+       FN_END;
        return EXIT_FAILURE;
-#endif
-       return 0;
 }
-
index 5989903..14597f9 100644 (file)
@@ -1,13 +1,17 @@
 /*
- * bluetooth-agent
+ * Bluetooth-agent
  *
- * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
+ *              Girishashok Joshi <girish.joshi@samsung.com>
+ *              Chanyeol Park <chanyeol.park@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
+ *             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,
@@ -39,9 +43,29 @@ typedef enum {
 #define BT_MAP_SERVICE_INTERFACE "org.bluez.MapAgent"
 
 #undef LOG_TAG
-#define LOG_TAG "BLUETOOTH_AGENT_MESSAGE"
-
+#define LOG_TAG "BLUETOOTH_AGENT_MAP"
+#define INFO(fmt, args...) SLOGI(fmt, ##args)
 #define DBG(fmt, args...) SLOGD(fmt, ##args)
 #define ERR(fmt, args...) SLOGE(fmt, ##args)
 
+#define DBG_SECURE(fmt, args...) SECURE_SLOGD(fmt, ##args)
+#define ERR_SECURE(fmt, args...) SECURE_SLOGE(fmt, ##args)
+
+#define FUCNTION_CALLS
+#ifdef FUCNTION_CALLS
+#define FN_START       DBG("ENTER==>")
+#define FN_END         DBG("EXIT===>")
+#else
+#define FN_START
+#define FN_END
+#endif
+
+#define retv_if(expr, val) \
+       do { \
+               if (expr) { \
+                       ERR("(%s) return", #expr); \
+                       return (val); \
+               } \
+       } while (0)
+
 #endif /* __DEF_BT_AGENT_H_ */
index fea0177..977418b 100644 (file)
@@ -56,5 +56,8 @@
                        <arg type="b" name="status"/>
                        <arg type="u" name="update_err" direction="out"/>
                </method>
+               <method name="DestroyAgent">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+               </method>
        </interface>
 </node>
index 31e729c..b4bf5d9 100644 (file)
@@ -1,13 +1,17 @@
 /*
- * bluetooth-agent
+ * Bluetooth-agent
  *
- * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
+ *              Girishashok Joshi <girish.joshi@samsung.com>
+ *              Chanyeol Park <chanyeol.park@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
+ *             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,
  *
  */
 
-#if 0
-
 #include <stdio.h>
 #include <string.h>
 #include <glib.h>
 
-#include <map_bmessage.h>
+#include <ITapiNetText.h>
 
+#include <map_bmessage.h>
 #include <bluetooth_map_agent.h>
 
 #define CRLF_LEN 2
+#define BT_SMS_DATA_MAX_LEN 165
 
 #define BMSG_TAG "BEGIN:BMSG\r\n"
 #define VER_TAG "VERSION:"
 #define LANGUAGE_TAG "LANGUAGE:"
 #define LENGTH_TAG "LENGTH:"
 
+static guint8 g_enc_lvl = 1;
 
 void print_bmsg(struct bmsg_data *bmsg)
 {
+       FN_START;
        if (bmsg == NULL)
                return;
 
@@ -60,11 +66,14 @@ void print_bmsg(struct bmsg_data *bmsg)
        DBG("bmsg->version = %s", bmsg->version);
        DBG("bmsg->status = %s", bmsg->status);
        DBG("bmsg->type = %s", bmsg->type);
-       DBG("bmsg->folder = %s", bmsg->folder);
-       DBG("bmsg->originator_vcard_data->version = %s",
-                                       bmsg->originator_vcard_data->version);
-       DBG("bmsg->originator_vcard_data->n = %s",
-                                       bmsg->originator_vcard_data->n);
+       DBG_SECURE("bmsg->folder = %s", bmsg->folder);
+
+       if (bmsg->originator_vcard_data) {
+               DBG_SECURE("bmsg->originator_vcard_data->version = %s",
+                                               bmsg->originator_vcard_data->version);
+               DBG_SECURE("bmsg->originator_vcard_data->n = %s",
+                                               bmsg->originator_vcard_data->n);
+       }
 
        int i = 0;
        env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
@@ -82,22 +91,22 @@ void print_bmsg(struct bmsg_data *bmsg)
                        if (rvcard->version != NULL)
                                DBG("vcard->version = %s\n", rvcard->version);
                        if (rvcard->n != NULL)
-                               DBG("vcard->n = %s\n", rvcard->n);
+                               DBG_SECURE("vcard->n = %s\n", rvcard->n);
                        if (rvcard->fn != NULL)
-                               DBG("vcard->fn = %s\n", rvcard->fn);
+                               DBG_SECURE("vcard->fn = %s\n", rvcard->fn);
                        if (rvcard->tel != NULL)
-                               DBG("vcard->tel = %s\n", rvcard->tel);
+                               DBG_SECURE("vcard->tel = %s\n", rvcard->tel);
                        if (rvcard->email != NULL)
-                               DBG("vcard->email = %s\n", rvcard->email);
+                               DBG_SECURE("vcard->email = %s\n", rvcard->email);
 
                        rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
                }
 
                if (env_data->body_content != NULL) {
-                       DBG("env_data->body_content->length = %"
+                       DBG_SECURE("env_data->body_content->length = %"
                                                G_GUINT64_FORMAT "\n",
                                                env_data->body_content->length);
-                       DBG("env_data->body_content->msg = %s\n",
+                       DBG_SECURE("env_data->body_content->msg = %s\n",
                                                env_data->body_content->msg);
                }
 
@@ -108,15 +117,162 @@ void print_bmsg(struct bmsg_data *bmsg)
 
                env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
        }
+       FN_END;
+}
+
+static gchar *__bt_unpack_gsm7bit_msg(const char* pdu, int in_len)
+{
+       FN_START;
+       int i;
+       int pos = 0;
+       int shift = 0;
+       gchar data[BT_SMS_DATA_MAX_LEN + 1] = {0,};
+
+       for (i = 0; i < in_len; i++) {
+               if (shift == 0) {
+                       data[i] = pdu[pos] & 0x7F;
+
+                       shift = 7;
+                       pos++;
+               } else {
+                       data[i] = (pdu[pos - 1] >> shift) |
+                                               (pdu[pos] << (8 - shift));
+                       data[i] &= 0x7F;
+
+                       shift--;
+                       if (shift > 0)
+                               pos++;
+               }
+       }
+
+       DBG_SECURE("msg = %s\n", data);
+       FN_END;
+       return g_strdup(data);
+}
+
+static gchar *__bt_get_msg_body_from_pdu(gchar *pdu, guint64 pdu_len)
+{
+       FN_START;
+       int index = 0;
+       int i;
+       int j = 0;
+       int dcs;
+       int udh = 0;
+       int coding_scheme;
+       int phone_num_len = 0;
+       char temp[3];
+       char msg_data[BT_SMS_DATA_MAX_LEN + 1] = {0,};
+       unsigned char pdu_data[TAPI_NETTEXT_MSG_SIZE_MAX] = {0,};
+
+       for (i = 0; i < (pdu_len - 1);) {
+               snprintf(temp, sizeof(temp), "%c%c", pdu[i], pdu[i+1]);
+
+               pdu_data[j] = g_ascii_strtoull(temp, NULL, 16);
+               DBG("pdu_data = %02x\n", pdu_data[j]);
+               j++;
+               i = i + 2;
+       }
+
+       DBG("pdu[%d] = %x\n", index, pdu_data[index]);
+       if (pdu[index] == 0x00)
+               index++;
+       else
+               index = index + pdu_data[index];
+
+       /* TP-MTI */
+       index = index + 1;
+
+       if (pdu_data[index] & 0x40)
+               udh = 1;
+
+       DBG("udh = %d", udh);
+
+       /* TP-MR */
+       index = index + 1;
+
+       /* phone number length */
+       index = index + 1;
+       DBG("pdu[%d] = %x\n", index, pdu_data[index]);
+
+       if ((pdu_data[index] % 2) == 0)
+               phone_num_len = pdu_data[index] / 2;
+       else
+               phone_num_len = pdu_data[index] / 2 + 1;
+
+       DBG("phone_num_len [%d]\n", phone_num_len);
+
+       /* phone number type */
+       index = index + 1;
+
+       /* phone_num_len/2 encoded phone num length */
+       index = index + phone_num_len;
+
+       /* TP-PID */
+       index = index + 1;
+
+       /* TP-DCS */
+       index = index + 1;
+
+       dcs = pdu_data[index];
+       coding_scheme = (dcs & 0x0C) >> 2;
+       DBG("coding_scheme = %d\n", coding_scheme);
+
+       /* TP-VP */
+       index = index + 1;
+
+       /* TP-UDL */
+       index = index + 1;
+       int udl = pdu_data[index];
+       DBG("udl = %x\n", udl);
+
+       /* message body */
+       index = index + 1;
+
+       memcpy(msg_data, (void*)&pdu_data[index], udl);
+
+       FN_END;
+       return __bt_unpack_gsm7bit_msg(msg_data, udl);
+}
+
+static gchar *__bt_get_valid_number(gchar* num)
+{
+       FN_START;
+       int len;
+       int i = 0;
+       int j = 0;
+       gchar *valid_num;
+
+       if (!num)
+               return NULL;
+
+       len = strlen(num);
+
+       valid_num = g_malloc0(len + 1);
+       retv_if(valid_num == NULL, NULL);
+
+       for (i = 0, j = 0; i < len; i++) {
+
+               if (num[i] != '-') {
+                       valid_num[j] = num[i];
+                       j++;
+               }
+       }
+
+       valid_num[j] = '\0';
+
+       FN_END;
+       return valid_num;
 }
 
 char *bmsg_get_msg_folder(struct bmsg_data *bmsg)
 {
+       FN_START;
        return g_strdup(bmsg->folder);
 }
 
-char *bmsg_get_msg_body(struct bmsg_data *bmsg)
+char *bmsg_get_msg_body(struct bmsg_data *bmsg, gboolean utf)
 {
+       FN_START;
        struct benv_data *env_data;
        int i = 0;
 
@@ -124,13 +280,21 @@ char *bmsg_get_msg_body(struct bmsg_data *bmsg)
 
        while (env_data != NULL) {
                if (env_data->body_content != NULL) {
-                       DBG("env_data->body_content->msg = %s\n",
+                       DBG_SECURE("env_data->body_content->msg = %s\n",
                                                env_data->body_content->msg);
-                       DBG("env_data->body_content->length = %"
+                       DBG_SECURE("env_data->body_content->length = %"
                                                G_GUINT64_FORMAT "\n",
                                                env_data->body_content->length);
-                       return g_strndup(env_data->body_content->msg,
-                                                               env_data->body_content->length);
+
+                       if (utf == FALSE) {
+                               return __bt_get_msg_body_from_pdu(
+                                               env_data->body_content->msg,
+                                               env_data->body_content->length);
+                       } else {
+                               return g_strndup(
+                                               env_data->body_content->msg,
+                                               env_data->body_content->length);
+                       }
                }
 
                i++;
@@ -140,11 +304,13 @@ char *bmsg_get_msg_body(struct bmsg_data *bmsg)
                env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
        }
 
+       FN_END;
        return NULL;
 }
 
 GSList *bmsg_get_msg_recepients(struct bmsg_data *bmsg)
 {
+       FN_START;
        struct benv_data *env_data;
        GSList *receiver = NULL;
        int i = 0;
@@ -162,8 +328,9 @@ GSList *bmsg_get_msg_recepients(struct bmsg_data *bmsg)
                        k++;
 
                        if (rvcard->tel != NULL) {
-                               DBG("vcard->tel = %s\n", rvcard->tel);
-                               receiver = g_slist_append(receiver, rvcard->tel);
+                               DBG_SECURE("vcard->tel = %s\n", rvcard->tel);
+                               receiver = g_slist_append(receiver,
+                                                               rvcard->tel);
                        }
 
                        rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
@@ -175,12 +342,13 @@ GSList *bmsg_get_msg_recepients(struct bmsg_data *bmsg)
 
                env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
        }
-
+       FN_END;
        return receiver;
 }
 
 void bmsg_free_vcard_data(struct bmsg_vcard *vcard_data)
 {
+       FN_START;
        if (vcard_data == NULL)
                return;
 
@@ -190,12 +358,13 @@ void bmsg_free_vcard_data(struct bmsg_vcard *vcard_data)
        g_free(vcard_data->tel);
        g_free(vcard_data->email);
        g_free(vcard_data);
-
+       FN_END;
        return;
 }
 
 void bmsg_free_bmsg(struct bmsg_data *bmsg)
 {
+       FN_START;
        struct benv_data *env_data;
        int i = 0;
 
@@ -243,12 +412,14 @@ void bmsg_free_bmsg(struct bmsg_data *bmsg)
                env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
        }
 
+       FN_END;
 done:
        g_free(bmsg);
 }
 
 gchar *bmsg_get_parse_sub_block(char **sub_block_data, char *element)
 {
+       FN_START;
        gchar *start;
        gchar *end;
        gchar *block_start;
@@ -257,8 +428,6 @@ gchar *bmsg_get_parse_sub_block(char **sub_block_data, char *element)
        size_t offset;
        size_t len;
 
-       DBG("");
-
        start = g_strdup_printf("BEGIN:%s\r\n", element);
        end = g_strdup_printf("END:%s\r\n", element);
        offset = strlen(start);
@@ -282,11 +451,13 @@ gchar *bmsg_get_parse_sub_block(char **sub_block_data, char *element)
 done:
        g_free(start);
        g_free(end);
+       FN_END;
        return sub_block;
 }
 
 gchar *bmsg_get_tag_data(char **block_data, char *element)
 {
+       FN_START;
        gchar *end = "\r\n";
        gchar *block_start;
        gchar *block_end;
@@ -294,8 +465,6 @@ gchar *bmsg_get_tag_data(char **block_data, char *element)
        size_t offset;
        size_t len;
 
-       DBG("");
-
        if (*block_data == NULL || element == NULL)
                return NULL;
 
@@ -312,18 +481,16 @@ gchar *bmsg_get_tag_data(char **block_data, char *element)
        len = block_end - block_start - offset;
        sub_block = g_strndup(block_start + offset, len);
        *block_data = *block_data + offset + len + CRLF_LEN;
-
+       FN_END;
        return sub_block;
 }
 
 struct bmsg_bbody *bmsg_get_bbody_data(gchar *block_data)
 {
-       gchar *bbody_block_data_start;
-       gchar *temp;
+       FN_START;
        struct bmsg_bbody *bbody;
-       DBG("");
-
-       bbody_block_data_start = block_data;
+       gchar *temp;
+       gchar *bbody_block_data_start = block_data;
 
        bbody = g_new0(struct bmsg_bbody, 1);
 
@@ -347,49 +514,50 @@ struct bmsg_bbody *bmsg_get_bbody_data(gchar *block_data)
        bbody->msg = bmsg_get_parse_sub_block(&block_data, "MSG");
 
        g_free(bbody_block_data_start);
-
+       FN_END;
        return bbody;
 }
 
 struct bmsg_vcard *bmsg_get_vcard_data(gchar *sub_block_data)
 {
-       gchar *vcard_block_data_start;
+       FN_START;
        struct bmsg_vcard *vcard;
-       DBG("");
-
-       vcard_block_data_start = sub_block_data;
+       gchar *num;
+       gchar *vcard_block_data_start = sub_block_data;
 
        vcard = g_new0(struct bmsg_vcard, 1);
 
        vcard->version = bmsg_get_tag_data(&sub_block_data, VER_TAG);
        vcard->n = bmsg_get_tag_data(&sub_block_data, VCARD_N_TAG);
        vcard->fn = bmsg_get_tag_data(&sub_block_data, VCARD_FN_TAG);
-       vcard->tel = bmsg_get_tag_data(&sub_block_data, VCARD_TEL_TAG);
+       num = bmsg_get_tag_data(&sub_block_data, VCARD_TEL_TAG);
+       vcard->tel = __bt_get_valid_number(num);
        vcard->email = bmsg_get_tag_data(&sub_block_data, VCARD_EMAIL_TAG);
 
        g_free(vcard_block_data_start);
-
+       g_free(num);
+       FN_END;
        return vcard;
 }
 
 struct benv_data *bmsg_get_env_encapsulation_data(gchar **sub_block_data)
 {
+       FN_START;
        gchar *is_valid;
        gchar *bbody_data = NULL;
-       static guint8 lvl = 1;
 
        is_valid = g_strstr_len(*sub_block_data, strlen(VCARD_BEGIN_TAG),
                                                        VCARD_BEGIN_TAG);
        if (is_valid == NULL)
                return NULL;
 
-       if (lvl > 3)
+       if (g_enc_lvl > 3)
                return NULL;
 
        struct benv_data *rec_data = g_new0(struct benv_data, 1);
 
-       rec_data->encapsulation_level = lvl;
-       lvl++;
+       rec_data->encapsulation_level = g_enc_lvl;
+       g_enc_lvl++;
 
        while (is_valid != NULL) {
                gchar *vcard_data = NULL;
@@ -397,7 +565,7 @@ struct benv_data *bmsg_get_env_encapsulation_data(gchar **sub_block_data)
 
                vcard_data = bmsg_get_parse_sub_block(sub_block_data, "VCARD");
                if (vcard_data == NULL) {
-                       DBG("parse error\n");
+                       ERR("parse error\n");
                        g_free(rec_data);
                        return NULL;
                }
@@ -419,24 +587,22 @@ struct benv_data *bmsg_get_env_encapsulation_data(gchar **sub_block_data)
 
        bbody_data = bmsg_get_parse_sub_block(sub_block_data, "BBODY");
        if (bbody_data == NULL) {
-               DBG("parse error\n");
+               ERR("parse error\n");
                return rec_data;
        }
 
        rec_data->body_content = bmsg_get_bbody_data(bbody_data);
-
+       FN_END;
        return rec_data;
 }
 
 struct bmsg_envelope *bmsg_get_envelope_data(gchar **block_data)
 {
-       gchar *env_block_data_start;
+       FN_START;
        gchar *sub_block_data;
        struct bmsg_envelope *envelope_data;
        struct benv_data *rec_data;
 
-       env_block_data_start = *block_data;
-
        envelope_data = g_new0(struct bmsg_envelope, 1);
 
        sub_block_data = bmsg_get_parse_sub_block(block_data, "BENV");
@@ -453,22 +619,24 @@ struct bmsg_envelope *bmsg_get_envelope_data(gchar **block_data)
                        rec_data = bmsg_get_env_encapsulation_data(
                                                        &sub_block_data);
                }
+               g_free(sub_block_data);
                sub_block_data = bmsg_get_parse_sub_block(&sub_block_data,
                                                                        "BENV");
        }
        g_free(sub_block_data);
-
+       FN_END;
        return envelope_data;
 }
 
-struct bmsg_data * bmsg_parse(gchar *buf)
+struct bmsg_data *bmsg_parse(gchar *buf)
 {
+       FN_START;
        gchar *block_data;
        gchar *sub_block_data;
        gchar *block_data_start;
        struct bmsg_data *bmsg;
 
-       DBG("");
+       g_enc_lvl = 1;
 
        block_data = bmsg_get_parse_sub_block(&buf, "BMSG");
        if (block_data == NULL)
@@ -495,12 +663,11 @@ struct bmsg_data * bmsg_parse(gchar *buf)
                goto parse_fail;
 
        sub_block_data = bmsg_get_parse_sub_block(&block_data, "VCARD");
-       if (sub_block_data == NULL)
-               goto parse_fail;
-
-       bmsg->originator_vcard_data = bmsg_get_vcard_data(sub_block_data);
-       if (bmsg->originator_vcard_data == NULL)
-               goto parse_fail;
+       if (sub_block_data != NULL) {
+               bmsg->originator_vcard_data = bmsg_get_vcard_data(sub_block_data);
+               if (bmsg->originator_vcard_data == NULL)
+                       goto parse_fail;
+       }
 
        bmsg->envelope_data = bmsg_get_envelope_data(&block_data);
        if (bmsg->envelope_data == NULL)
@@ -510,14 +677,15 @@ struct bmsg_data * bmsg_parse(gchar *buf)
 
        DBG("Parse done");
        print_bmsg(bmsg);
-
+       FN_END;
        return bmsg;
 
 parse_fail:
-       DBG("Parse fail");
-       bmsg_free_bmsg(bmsg);
+       g_free(block_data_start);
 
+       ERR("Parse fail");
+       bmsg_free_bmsg(bmsg);
+       FN_END;
        return NULL;
 }
 
-#endif
index 4cdadf7..860f86f 100644 (file)
@@ -1,13 +1,17 @@
 /*
- * bluetooth-agent
+ * Bluetooth-agent
  *
- * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
+ *              Girishashok Joshi <girish.joshi@samsung.com>
+ *              Chanyeol Park <chanyeol.park@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
+ *             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,
@@ -62,8 +66,9 @@ struct bmsg_data {
 
 struct bmsg_data * bmsg_parse(gchar *buf);
 char *bmsg_get_msg_folder(struct bmsg_data *bmsg);
-char *bmsg_get_msg_body(struct bmsg_data *bmsg);
+char *bmsg_get_msg_body(struct bmsg_data *bmsg, gboolean utf);
 GSList *bmsg_get_msg_recepients(struct bmsg_data *bmsg);
+void bmsg_free_bmsg(struct bmsg_data *bmsg);
 
 #ifdef __cplusplus
 }
index b299104..3a5a867 100644 (file)
@@ -1,4 +1,3 @@
 [D-BUS Service]
 Name=org.bluez.map_agent
 Exec=/usr/bin/bluetooth-map-agent
-User=root
index c12a3c4..4a18d65 100644 (file)
@@ -1,20 +1,32 @@
 Name:       bluetooth-agent
 Summary:    Bluetooth agent packages that support various external profiles
-Version:    0.0.9
-Release:    2
+Version:    0.1.0
+Release:    1
 Group:      Network & Connectivity/Bluetooth
 License:    Apache-2.0
 Source0:    %{name}-%{version}.tar.gz
 Source1001:    bluetooth-agent.manifest
 
+Requires(post): sys-assert
+BuildRequires:  pkgconfig(aul)
+BuildRequires:  pkgconfig(bluetooth-api)
+%if "%{?profile}" == "wearable"
+BuildRequires:  pkgconfig(alarm-service)
+BuildRequires:  pkgconfig(capi-appfw-app-manager)
+BuildRequires:  pkgconfig(capi-system-device)
+%else
 BuildRequires:  pkgconfig(contacts-service2)
-BuildRequires:  pkgconfig(dbus-glib-1)
 BuildRequires:  pkgconfig(msg-service)
-BuildRequires:  pkgconfig(email-service)
+%endif
+BuildRequires:  pkgconfig(capi-system-info)
+BuildRequires:  pkgconfig(dbus-glib-1)
 BuildRequires:  pkgconfig(tapi)
 BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(vconf)
 BuildRequires:  pkgconfig(appsvc)
+BuildRequires:  pkgconfig(capi-appfw-application)
+BuildRequires:  pkgconfig(capi-media-image-util)
+BuildRequires:  pkgconfig(libexif)
 BuildRequires:  cmake
 
 %description
@@ -25,7 +37,33 @@ Bluetooth agent packages that support various external profiles
 cp %{SOURCE1001} .
 
 %build
-cmake . -DCMAKE_INSTALL_PREFIX=/usr
+export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
+export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
+export CFLAGS="$CFLAGS -DTIZEN_MEDIA_ENHANCE"
+export CFLAGS="$CFLAGS -DTIZEN_BT_HFP_AG_ENABLE"
+
+%if "%{?profile}" == "wearable"
+export CFLAGS="$CFLAGS -DTIZEN_WEARABLE"
+export CFLAGS="$CFLAGS -DTIZEN_SUPPORT_LUNAR_DEVICE"
+%else
+%if "%{?tizen_target_name}" == "Z130H"
+export CFLAGS="$CFLAGS -DTIZEN_KIRAN"
+%endif
+%endif
+
+export CFLAGS+=" -fpie -DPBAP_SIM_ENABLE"
+
+export CFLAGS+=" -fpie -fvisibility=hidden"
+export LDFLAGS+=" -Wl,--rpath=/usr/lib -Wl,--as-needed -Wl,--unresolved-symbols=ignore-in-shared-libs -pie"
+
+cmake . -DCMAKE_INSTALL_PREFIX=/usr \
+%if "%{?profile}" == "wearable"
+        -DTIZEN_WEARABLE=1 \
+%else
+        -DTIZEN_WEARABLE=0 \
+%endif
+        -DTIZEN_BT_HFP_AG_ENABLE=1
 
 make VERBOSE=1
 
@@ -33,12 +71,21 @@ make VERBOSE=1
 rm -rf %{buildroot}
 %make_install
 
+install -D -m 0644 LICENSE %{buildroot}%{_datadir}/license/bluetooth-agent
+
 %files
 %manifest %{name}.manifest
 %defattr(-, root, root)
+%if "%{?profile}" == "wearable"
+%{_bindir}/bluetooth-hf-agent
+%{_datadir}/dbus-1/system-services/org.bluez.hf_agent.service
+%else
 %{_bindir}/bluetooth-map-agent
-#%{_bindir}/bluetooth-pb-agent
-#%{_bindir}/bluetooth-hfp-agent
-#%{_datadir}/dbus-1/system-services/org.bluez.pb_agent.service
-%{_datadir}/dbus-1/services/org.bluez.map_agent.service
-#%{_datadir}/dbus-1/system-services/org.bluez.hfp_agent.service
+%{_bindir}/bluetooth-pb-agent
+%{_datadir}/dbus-1/system-services/org.bluez.pb_agent.service
+%{_datadir}/dbus-1/system-services/org.bluez.map_agent.service
+%{_datadir}/dbus-1/system-services/org.bluez.ag_agent.service
+%{_bindir}/bluetooth-ag-agent
+%attr(0666,-,-) /opt/var/lib/bluetooth/voice-recognition-blacklist
+%endif
+%{_datadir}/license/bluetooth-agent
index fa65204..ff7e129 100644 (file)
@@ -8,7 +8,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
 INCLUDE(FindPkgConfig)
 pkg_check_modules(pkgs_pb_agent
                REQUIRED
-               dbus-glib-1 dlog contacts-service2 tapi vconf)
+               dbus-glib-1 dlog contacts-service2 tapi vconf capi-media-image-util libexif)
 
 FOREACH(flag ${pkgs_pb_agent_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
index c3df5da..08694c2 100644 (file)
@@ -1,13 +1,18 @@
 /*
- * bluetooth-agent
+ * Bluetooth-agent
  *
- * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
+ *              Girishashok Joshi <girish.joshi@samsung.com>
+ *              Chanyeol Park <chanyeol.park@samsung.com>
+ *              Jaekyun Lee <jkyun.leek@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
+ *             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,
 
 #define BLUETOOTH_PB_AGENT_TIMEOUT 600
 
-static gchar *bluetooth_pb_agent_folder_list[] = {
-       "/telecom/pb",
-       "/telecom/ich",
-       "/telecom/och",
-       "/telecom/mch",
-       "/telecom/cch",
-       NULL
-};
-
-typedef enum {
-       TELECOM_PB = 0,
-       TELECOM_ICH,
-       TELECOM_OCH,
-       TELECOM_MCH,
-       TELECOM_CCH,
-       TELECOM_NONE
-} PhoneBookType;
-
 typedef struct {
        GObject parent;
 
@@ -66,9 +53,6 @@ typedef struct {
 
        TapiHandle *tapi_handle;
        gchar *tel_number;
-
-       GHashTable *contact_list;
-
        guint timeout_id;
 
        PhoneBookType pb_type;
@@ -111,6 +95,8 @@ G_DEFINE_TYPE(BluetoothPbAgent, bluetooth_pb_agent, G_TYPE_OBJECT)
                                                        G_TYPE_STRING, G_TYPE_UINT, G_TYPE_INVALID))
 
 static guint signals[LAST_SIGNAL] = { 0 };
+static guint total_missed_call_count = 0;
+static guint unnotified_missed_call_count = 0;
 
 static GMainLoop *mainloop = NULL;
 
@@ -169,6 +155,9 @@ static gboolean bluetooth_pb_add_contact (BluetoothPbAgent *agent,
                                        const char *filename,
                                        GError **error);
 
+static gboolean bluetooth_pb_destroy_agent(BluetoothPbAgent *agent,
+                                       DBusGMethodInvocation *context);
+
 static void __bluetooth_pb_dbus_return_error(DBusGMethodInvocation *context,
                                        gint code,
                                        const gchar *message);
@@ -184,7 +173,7 @@ static gint __bluetooth_pb_phone_log_filter_append(contacts_filter_h filter,
 static contacts_query_h __bluetooth_pb_query_phone_log(gint *match,
                                                gint size);
 
-static contacts_query_h __bluetooth_pb_query_person(void);
+static contacts_query_h __bluetooth_pb_query_person(int addressbook);
 
 static contacts_query_h __bluetooth_pb_query_person_number(void);
 
@@ -256,15 +245,6 @@ static void __bluetooth_pb_get_list_name(BluetoothPbAgent *agent,
                                        const gchar *find_text,
                                        GPtrArray *ptr_array);
 
-static void __bluetooth_pb_list_hash_reset(BluetoothPbAgent *agent);
-
-static gboolean __bluetooth_pb_list_hash_insert(BluetoothPbAgent *agent,
-                                               gint handle,
-                                               gint id);
-
-static gint __bluetooth_pb_list_hash_lookup_id(BluetoothPbAgent *agent,
-                                       gint handle);
-
 static void __bluetooth_pb_list_ptr_array_add(GPtrArray *ptr_array,
                                                const gchar *name,
                                                const gchar *number,
@@ -292,20 +272,19 @@ static void __bluetooth_pb_agent_dbus_init(BluetoothPbAgent *agent);
 
 static void bluetooth_pb_agent_init(BluetoothPbAgent *agent)
 {
+       FN_START;
        agent->bus = NULL;
        agent->proxy = NULL;
-
        agent->tapi_handle = NULL;
        agent->tel_number = NULL;
-
-       agent->contact_list = NULL;
        agent->timeout_id = 0;
-
        agent->pb_type = TELECOM_NONE;
+       FN_END;
 }
 
 static void bluetooth_pb_agent_class_init(BluetoothPbAgentClass *klass)
 {
+       FN_START;
        GObjectClass *object_class = (GObjectClass *) klass;
 
        klass->clear = bluetooth_pb_agent_clear;
@@ -322,14 +301,14 @@ static void bluetooth_pb_agent_class_init(BluetoothPbAgentClass *klass)
 
        dbus_g_object_type_install_info(BLUETOOTH_PB_TYPE_AGENT,
                                        &dbus_glib_bluetooth_pb_object_info);
+       FN_END;
 }
 
 static void bluetooth_pb_agent_finalize(GObject *obj)
 {
+       FN_START;
        BluetoothPbAgent *agent  = BLUETOOTH_PB_AGENT(obj);
 
-       DBG("+\n");
-
        if (agent->tapi_handle) {
                tel_deinit(agent->tapi_handle);
                agent->tapi_handle = NULL;
@@ -345,11 +324,6 @@ static void bluetooth_pb_agent_finalize(GObject *obj)
                agent->timeout_id = 0;
        }
 
-       if (agent->contact_list) {
-               g_hash_table_destroy(agent->contact_list);
-               agent->contact_list = NULL;
-       }
-
        if (agent->proxy) {
                g_object_unref(agent->proxy);
                agent->proxy = NULL;
@@ -362,24 +336,21 @@ static void bluetooth_pb_agent_finalize(GObject *obj)
 
 
        G_OBJECT_CLASS(bluetooth_pb_agent_parent_class)->finalize(obj);
+       FN_END;
 }
 
 static void bluetooth_pb_agent_clear(BluetoothPbAgent *agent)
 {
-       DBG("+\n");
-
-       if (agent->contact_list) {
-               g_hash_table_destroy(agent->contact_list);
-               agent->contact_list = NULL;
-       }
-
+       FN_START;
        agent->pb_type = TELECOM_NONE;
+       FN_END;
 }
 
 static gboolean bluetooth_pb_get_phonebook_folder_list(BluetoothPbAgent *agent,
                                                const gchar ***folder_list,
                                                GError **error)
 {
+       FN_START;
        gint size;
        gint i;
        gchar **folder;
@@ -392,6 +363,7 @@ static gboolean bluetooth_pb_get_phonebook_folder_list(BluetoothPbAgent *agent,
 
        *folder_list = (const gchar **)folder;
 
+       FN_END;
        return TRUE;
 }
 
@@ -403,13 +375,12 @@ static gboolean bluetooth_pb_get_phonebook(BluetoothPbAgent *agent,
                                        guint16 list_start_offset,
                                        DBusGMethodInvocation *context)
 {
+       FN_START;
        PhoneBookType pb_type = TELECOM_NONE;
        GPtrArray *vcards = NULL;
        gchar **vcards_str = NULL;
 
-       guint new_missed_call = 0;
-
-       DBG("name: %s filter: %lld format: %d max_list_count: %d list_start_offset: %d\n",
+       INFO("name: %s filter: %lld format: %d max_list_count: %d list_start_offset: %d\n",
                        name, filter, format, max_list_count, list_start_offset);
 
        __bluetooth_pb_agent_timeout_add_seconds(agent);
@@ -437,10 +408,17 @@ static gboolean bluetooth_pb_get_phonebook(BluetoothPbAgent *agent,
 
        vcards_str = (gchar **) g_ptr_array_free(vcards, FALSE);
 
-       dbus_g_method_return(context, vcards_str, new_missed_call);
+       if (pb_type == TELECOM_MCH) {
+               dbus_g_method_return(context, vcards_str, unnotified_missed_call_count);
+               INFO("Notified [%d] missed call count", unnotified_missed_call_count);
+               unnotified_missed_call_count = 0;
+       } else {
+               dbus_g_method_return(context, vcards_str, 0);
+       }
 
        g_strfreev(vcards_str);
 
+       FN_END;
        return TRUE;
 }
 
@@ -448,12 +426,11 @@ static gboolean bluetooth_pb_get_phonebook_size(BluetoothPbAgent *agent,
                                                const char *name,
                                                DBusGMethodInvocation *context)
 {
+       FN_START;
        PhoneBookType pb_type = TELECOM_NONE;
-
-       guint new_missed_call = 0;
        guint count = 0;
 
-       DBG("name: %s\n", name);
+       DBG_SECURE("name: %s\n", name);
 
        __bluetooth_pb_agent_timeout_add_seconds(agent);
 
@@ -467,13 +444,22 @@ static gboolean bluetooth_pb_get_phonebook_size(BluetoothPbAgent *agent,
        }
 
        /* for owner */
+#ifdef PBAP_SIM_ENABLE
+       if (pb_type == TELECOM_PB || pb_type == SIM_PB)
+               count++;
+#else
        if (pb_type == TELECOM_PB)
                count++;
+#endif
+       if (pb_type == TELECOM_MCH) {
+               dbus_g_method_return(context, count, unnotified_missed_call_count);
+               INFO("Notified [%d] missed call count", unnotified_missed_call_count);
+               unnotified_missed_call_count = 0;
+       } else {
+               dbus_g_method_return(context, count, 0);
+       }
 
-       __bluetooth_pb_get_count_new_missed_call(&new_missed_call);
-
-       dbus_g_method_return(context, count, new_missed_call);
-
+       FN_END;
        return TRUE;
 }
 
@@ -482,11 +468,12 @@ static gboolean bluetooth_pb_get_phonebook_list(BluetoothPbAgent *agent,
                                                const char *name,
                                                DBusGMethodInvocation *context)
 {
+       FN_START;
        PhoneBookType pb_type = TELECOM_NONE;
 
        GPtrArray *ptr_array;
 
-       DBG("name: %s\n", name);
+       DBG_SECURE("name: %s\n", name);
 
        __bluetooth_pb_agent_timeout_add_seconds(agent);
 
@@ -503,11 +490,21 @@ static gboolean bluetooth_pb_get_phonebook_list(BluetoothPbAgent *agent,
 
        __bluetooth_pb_get_list(agent, pb_type, ptr_array);
 
-       dbus_g_method_return(context, ptr_array);
+//     __bluetooth_pb_get_count_new_missed_call(&new_missed_call);
+       INFO("pb_type[%d] / number of missed_call[%d]", pb_type, unnotified_missed_call_count);
+
+       if (pb_type == TELECOM_MCH) {
+               dbus_g_method_return(context, ptr_array, unnotified_missed_call_count);
+               INFO("Notified [%d] missed call count", unnotified_missed_call_count);
+               unnotified_missed_call_count = 0;
+       } else {
+               dbus_g_method_return(context, ptr_array, 0);
+       }
 
        if (ptr_array)
                g_ptr_array_free(ptr_array, TRUE);
 
+       FN_END;
        return TRUE;
 }
 
@@ -519,15 +516,15 @@ static gboolean bluetooth_pb_get_phonebook_entry(BluetoothPbAgent *agent,
                                                guint8 format,
                                                DBusGMethodInvocation *context)
 {
+       FN_START;
        PhoneBookType pb_type = TELECOM_NONE;
 
        gint handle = 0;
-       gint cid = -1;
        gchar *str = NULL;
 
        const gchar *attr = NULL;
 
-       DBG("folder: %s id: %s filter: %ld format: %d\n",
+       DBG_SECURE("folder: %s id: %s filter: %ld format: %d\n",
                        folder, id, filter, format);
 
        __bluetooth_pb_agent_timeout_add_seconds(agent);
@@ -553,25 +550,25 @@ static gboolean bluetooth_pb_get_phonebook_entry(BluetoothPbAgent *agent,
        /* create index cache */
        __bluetooth_pb_get_list(agent, pb_type, NULL);
 
-       cid = __bluetooth_pb_list_hash_lookup_id(agent, handle);
-
        switch(pb_type) {
        case TELECOM_PB:
                if (handle == 0) {
                        str = _bluetooth_pb_vcard_contact_owner(agent->tel_number,
                                                                filter, format);
                } else {
-                       str = _bluetooth_pb_vcard_contact(cid, filter, format);
+                       if (_bluetooth_get_contact_addressbook(handle) == PBAP_ADDRESSBOOK_PHONE)
+                               str = _bluetooth_pb_vcard_contact(handle, filter, format);
                }
                break;
+
        case TELECOM_ICH:
-               str = _bluetooth_pb_vcard_call(cid, filter, format, "RECEIVED");
+               str = _bluetooth_pb_vcard_call(handle, filter, format, "RECEIVED");
                break;
        case TELECOM_OCH:
-               str = _bluetooth_pb_vcard_call(cid, filter, format, "DIALED");
+               str = _bluetooth_pb_vcard_call(handle, filter, format, "DIALED");
                break;
        case TELECOM_MCH:
-               str = _bluetooth_pb_vcard_call(cid, filter, format, "MISSED");
+               str = _bluetooth_pb_vcard_call(handle, filter, format, "MISSED");
                break;
        case TELECOM_CCH: {
                contacts_record_h record = NULL;
@@ -579,17 +576,28 @@ static gboolean bluetooth_pb_get_phonebook_entry(BluetoothPbAgent *agent,
                gint status;
 
                status = contacts_db_get_record(_contacts_phone_log._uri,
-                               cid, &record);
+                               handle, &record);
 
                if (status != CONTACTS_ERROR_NONE)
                        break;
 
                attr = __bluetooth_pb_phone_log_get_log_type(record);
-               str = _bluetooth_pb_vcard_call(cid, filter, format, attr);
+               str = _bluetooth_pb_vcard_call(handle, filter, format, attr);
 
                contacts_record_destroy(record, TRUE);
                break;
        }
+#ifdef PBAP_SIM_ENABLE
+       case SIM_PB:
+               if (handle == 0) {
+                       str = _bluetooth_pb_vcard_contact_owner(agent->tel_number,
+                                                               filter, format);
+               } else {
+                       if (_bluetooth_get_contact_addressbook(handle) == PBAP_ADDRESSBOOK_SIM)
+                               str = _bluetooth_pb_vcard_contact(handle, filter, format);
+               }
+               break;
+#endif
        default:
                __bluetooth_pb_dbus_return_error(context,
                                        G_FILE_ERROR_INVAL,
@@ -600,6 +608,7 @@ static gboolean bluetooth_pb_get_phonebook_entry(BluetoothPbAgent *agent,
        dbus_g_method_return(context, str);
        g_free(str);
 
+       FN_END;
        return TRUE;
 }
 
@@ -607,6 +616,7 @@ static gboolean bluetooth_pb_get_phonebook_size_at(BluetoothPbAgent *agent,
                                        const gchar *command,
                                        DBusGMethodInvocation *context)
 {
+       FN_START;
        PhoneBookType pb_type = TELECOM_NONE;
        guint count = 0;
 
@@ -625,6 +635,7 @@ static gboolean bluetooth_pb_get_phonebook_size_at(BluetoothPbAgent *agent,
 
        dbus_g_method_return(context, count);
 
+       FN_END;
        return TRUE;
 }
 
@@ -634,6 +645,7 @@ static gboolean bluetooth_pb_get_phonebook_entries_at(BluetoothPbAgent *agent,
                                        gint end_index,
                                        DBusGMethodInvocation *context)
 {
+       FN_START;
        PhoneBookType pb_type = TELECOM_NONE;
 
        GPtrArray *ptr_array = NULL;
@@ -663,6 +675,7 @@ static gboolean bluetooth_pb_get_phonebook_entries_at(BluetoothPbAgent *agent,
        if (ptr_array)
                g_ptr_array_free(ptr_array, TRUE);
 
+       FN_END;
        return TRUE;
 }
 
@@ -671,6 +684,7 @@ static gboolean bluetooth_pb_get_phonebook_entries_find_at(BluetoothPbAgent *age
                                                        const gchar *find_text,
                                                        DBusGMethodInvocation *context)
 {
+       FN_START;
        PhoneBookType pb_type = TELECOM_NONE;
 
        GPtrArray *ptr_array = NULL;
@@ -698,12 +712,14 @@ static gboolean bluetooth_pb_get_phonebook_entries_find_at(BluetoothPbAgent *age
        if (ptr_array)
                g_ptr_array_free(ptr_array, TRUE);
 
+       FN_END;
        return TRUE;
 }
 
 static gboolean bluetooth_pb_get_total_object_count(BluetoothPbAgent *agent,
                                        gchar *path, DBusGMethodInvocation *context)
 {
+       FN_START;
        guint count = 0;
        PhoneBookType pb_type = TELECOM_NONE;
 
@@ -724,6 +740,7 @@ static gboolean bluetooth_pb_get_total_object_count(BluetoothPbAgent *agent,
 
        DBG("%s() %d\n", __FUNCTION__, __LINE__);
 
+       FN_END;
        return TRUE;
 }
 
@@ -731,20 +748,21 @@ static gboolean bluetooth_pb_get_total_object_count(BluetoothPbAgent *agent,
 #if 0
 static int __bluetooth_pb_agent_read_file(const char *file_path, char **stream)
 {
+       FN_START;
        FILE *fp = NULL;
        int read_len = -1;
        int received_file_size = 0;
        struct stat file_attr;
 
        if (file_path == NULL || stream == NULL) {
-               DBG("Invalid data \n");
+               ERR("Invalid data \n");
                return -1;
        }
 
-       DBG("file_path = %s\n", file_path);
+       DBG_SECURE("file_path = %s\n", file_path);
 
        if ((fp = fopen(file_path, "r+")) == NULL) {
-               DBG("Cannot open %s\n", file_path);
+               ERR_SECURE("Cannot open %s\n", file_path);
                return -1;
        }
 
@@ -753,7 +771,7 @@ static int __bluetooth_pb_agent_read_file(const char *file_path, char **stream)
                DBG("file_attr.st_size = %d, size = %d\n", file_attr.st_size, received_file_size);
 
                if (received_file_size <= 0) {
-                       DBG("Some problem in the file size [%s]  \n", file_path);
+                       ERR_SECURE("Some problem in the file size [%s]  \n", file_path);
                        fclose(fp);
                        fp = NULL;
                        return -1;
@@ -766,7 +784,7 @@ static int __bluetooth_pb_agent_read_file(const char *file_path, char **stream)
                        return -1;
                }
        } else {
-               DBG("Some problem in the file [%s]  \n", file_path);
+               ERR_SECURE("Some problem in the file [%s]  \n", file_path);
                fclose(fp);
                fp = NULL;
                return -1;
@@ -779,7 +797,7 @@ static int __bluetooth_pb_agent_read_file(const char *file_path, char **stream)
                        fclose(fp);
                        fp = NULL;
                }
-               DBG("Cannot open %s\n", file_path);
+               DBG_SECURE("Cannot open %s\n", file_path);
                return -1;
        }
 
@@ -787,6 +805,7 @@ static int __bluetooth_pb_agent_read_file(const char *file_path, char **stream)
                fclose(fp);
                fp = NULL;
        }
+       FN_END;
        return 0;
 }
 #endif
@@ -794,6 +813,7 @@ static int __bluetooth_pb_agent_read_file(const char *file_path, char **stream)
 static gboolean bluetooth_pb_add_contact(BluetoothPbAgent *agent, const char *filename,
                                         GError **error)
 {
+       FN_START;
        /* Contact API is changed, Temporary blocked */
 #if 0
        CTSstruct *contact_record = NULL;
@@ -803,16 +823,16 @@ static gboolean bluetooth_pb_add_contact(BluetoothPbAgent *agent, const char *fi
        int err = 0;
        char *stream = NULL;
 
-       DBG("file_path = %s\n", filename);
+       DBG_SECURE("file_path = %s\n", filename);
 
        err = contacts_svc_connect();
-       DBG("contact_db_service_connect fucntion call [error] = %d \n", err);
+       ERR("contact_db_service_connect fucntion call [error] = %d \n", err);
 
        err = __bluetooth_pb_agent_read_file(filename, &stream);
 
        if (err != 0) {
                contacts_svc_disconnect();
-               DBG("contacts_svc_disconnect fucntion call [error] = %d \n", err);
+               ERR("contacts_svc_disconnect fucntion call [error] = %d \n", err);
 
                if (NULL != stream) {
                        free(stream);
@@ -842,18 +862,18 @@ static gboolean bluetooth_pb_add_contact(BluetoothPbAgent *agent, const char *fi
                        contacts_svc_insert_contact(0, contact_record);
                }
        } else {
-               DBG("Fail \n");
+               ERR("Fail \n");
        }
 
        err = contacts_svc_disconnect();
-       DBG("contacts_svc_disconnect fucntion call [error] = %d \n", err);
+       ERR("contacts_svc_disconnect fucntion call [error] = %d \n", err);
 
        if (NULL != stream) {
                free(stream);
                stream = NULL;
        }
 #endif
-
+       FN_END;
        return TRUE;
 }
 
@@ -861,6 +881,7 @@ static void __bluetooth_pb_dbus_return_error(DBusGMethodInvocation *context,
                                        gint code,
                                        const gchar *message)
 {
+       FN_START;
        GQuark quark;
        GError *error = NULL;
 
@@ -871,10 +892,12 @@ static void __bluetooth_pb_dbus_return_error(DBusGMethodInvocation *context,
 
        dbus_g_method_return_error(context, error);
        g_error_free(error);
+       FN_END;
 }
 
 static PhoneBookType __bluetooth_pb_get_pb_type(const char *name)
 {
+       FN_START;
        gchar *suffix = ".vcf";
        gint len;
        gint size;
@@ -894,11 +917,13 @@ static PhoneBookType __bluetooth_pb_get_pb_type(const char *name)
                        return i;
        }
 
+       FN_END;
        return TELECOM_NONE;
 }
 
 static PhoneBookType __bluetooth_pb_get_storage_pb_type(const char *name)
 {
+       FN_START;
        if (name == NULL)
                return TELECOM_NONE;
 
@@ -914,6 +939,7 @@ static PhoneBookType __bluetooth_pb_get_storage_pb_type(const char *name)
        if (g_strcmp0(name, "\"MC\"") == 0)
                return TELECOM_MCH;
 
+       FN_END;
        return TELECOM_NONE;
 }
 
@@ -921,6 +947,7 @@ static gint __bluetooth_pb_phone_log_filter_append(contacts_filter_h filter,
                                                gint *match,
                                                gint size)
 {
+       FN_START;
        gint i;
        gint status;
 
@@ -943,12 +970,14 @@ static gint __bluetooth_pb_phone_log_filter_append(contacts_filter_h filter,
                        return status;
        }
 
+       FN_END;
        return CONTACTS_ERROR_NONE;
 }
 
 static contacts_query_h __bluetooth_pb_query_phone_log(gint *match,
                                                gint size)
 {
+       FN_START;
        contacts_query_h query = NULL;
        contacts_filter_h filter = NULL;
 
@@ -995,26 +1024,106 @@ static contacts_query_h __bluetooth_pb_query_phone_log(gint *match,
 
        contacts_filter_destroy(filter);
 
+       FN_END;
        return query;
 }
 
-static contacts_query_h __bluetooth_pb_query_person(void)
+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);
+
+       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;
+       }
 
-       status = contacts_query_create(_contacts_person._uri,
-                       &query);
+       contacts_list_destroy(recordList, true);
 
+       status = contacts_query_set_filter(query, filter);
        if (status != CONTACTS_ERROR_NONE)
-               return NULL;
+               ERR("Could not Apply Filter");
 
+       contacts_filter_destroy(filter);
+       FN_END;
        return query;
 }
 
 static contacts_query_h __bluetooth_pb_query_person_number(void)
 {
+       FN_START;
        contacts_query_h query = NULL;
 
        gint status;
@@ -1025,34 +1134,41 @@ static contacts_query_h __bluetooth_pb_query_person_number(void)
        if (status != CONTACTS_ERROR_NONE)
                return NULL;
 
+       FN_END;
        return query;
 }
 
 static contacts_query_h __bluetooth_pb_query_phone_log_incoming(void)
 {
-       gint size = 2;
+       FN_START;
+       gint size = 4;
        gint match[] = {
                CONTACTS_PLOG_TYPE_VOICE_INCOMMING,
-               CONTACTS_PLOG_TYPE_VIDEO_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,
@@ -1061,12 +1177,14 @@ static contacts_query_h __bluetooth_pb_query_phone_log_missed(void)
                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)
 {
-       gint size = 8;
+       FN_START;
+       gint size = 10;
        gint match[] = {
                CONTACTS_PLOG_TYPE_VOICE_INCOMMING,
                CONTACTS_PLOG_TYPE_VIDEO_INCOMMING,
@@ -1075,15 +1193,19 @@ static contacts_query_h __bluetooth_pb_query_phone_log_combined(void)
                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_VIDEO_INCOMMING_SEEN,
+               CONTACTS_PLOG_TYPE_VOICE_REJECT,
+               CONTACTS_PLOG_TYPE_VIDEO_REJECT
        };
 
+       FN_END;
        return __bluetooth_pb_query_phone_log(match, size);
 }
 
 static gboolean __bluetooth_pb_get_count(PhoneBookType pb_type,
                                guint *count)
 {
+       FN_START;
        contacts_query_h query = NULL;
 
        gint status;
@@ -1091,7 +1213,7 @@ static gboolean __bluetooth_pb_get_count(PhoneBookType pb_type,
 
        switch (pb_type) {
        case TELECOM_PB:
-               query = __bluetooth_pb_query_person();
+               query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_PHONE);
                break;
        case TELECOM_ICH:
                query = __bluetooth_pb_query_phone_log_incoming();
@@ -1105,6 +1227,11 @@ static gboolean __bluetooth_pb_get_count(PhoneBookType pb_type,
        case TELECOM_CCH:
                query = __bluetooth_pb_query_phone_log_combined();
                break;
+#ifdef PBAP_SIM_ENABLE
+       case SIM_PB:
+               query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_SIM);
+               break;
+#endif
        default:
                return FALSE;
        }
@@ -1126,11 +1253,13 @@ static gboolean __bluetooth_pb_get_count(PhoneBookType pb_type,
 
        *count = (gint) signed_count;
 
+       FN_END;
        return TRUE;
 }
 
 static gboolean __bluetooth_pb_get_count_new_missed_call(guint *count)
 {
+       FN_START;
        contacts_query_h query = NULL;
 
        gint status;
@@ -1161,11 +1290,13 @@ static gboolean __bluetooth_pb_get_count_new_missed_call(guint *count)
 
        *count = (guint)signed_count;
 
+       FN_END;
        return TRUE;
 }
 
 static const char *__bluetooth_pb_phone_log_get_log_type(contacts_record_h record)
 {
+       FN_START;
        gint status;
        gint log_type;
 
@@ -1179,6 +1310,8 @@ static const char *__bluetooth_pb_phone_log_get_log_type(contacts_record_h recor
        switch (log_type) {
        case CONTACTS_PLOG_TYPE_VOICE_INCOMMING:
        case CONTACTS_PLOG_TYPE_VIDEO_INCOMMING:
+       case CONTACTS_PLOG_TYPE_VOICE_REJECT:
+       case CONTACTS_PLOG_TYPE_VIDEO_REJECT:
                return "RECEIVED";
        case CONTACTS_PLOG_TYPE_VOICE_OUTGOING:
        case CONTACTS_PLOG_TYPE_VIDEO_OUTGOING:
@@ -1191,6 +1324,7 @@ static const char *__bluetooth_pb_phone_log_get_log_type(contacts_record_h recor
        default:
                return NULL;
        }
+       FN_END;
 }
 
 static void __bluetooth_pb_get_vcards(BluetoothPbAgent *agent,
@@ -1201,6 +1335,7 @@ static void __bluetooth_pb_get_vcards(BluetoothPbAgent *agent,
                                guint16 list_start_offset,
                                GPtrArray *vcards)
 {
+       FN_START;
        contacts_list_h record_list = NULL;
        contacts_query_h query = NULL;
 
@@ -1225,6 +1360,9 @@ static void __bluetooth_pb_get_vcards(BluetoothPbAgent *agent,
 
        switch (pb_type) {
        case TELECOM_PB:
+#ifdef PBAP_SIM_ENABLE
+       case SIM_PB:
+#endif
                /* for owner */
                if (list_start_offset == 0) {
                        char *vcard;
@@ -1236,11 +1374,19 @@ static void __bluetooth_pb_get_vcards(BluetoothPbAgent *agent,
 
                        offset = 0;
 
-                       if (limit > 0)
+                       if (limit == 1)
+                               return;
+                       else if (limit > 1)
                                limit--;
                }
 
-               query = __bluetooth_pb_query_person();
+               if (pb_type == TELECOM_PB)
+                       query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_PHONE);
+#ifdef PBAP_SIM_ENABLE
+               else if(pb_type == SIM_PB)
+                       query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_SIM);
+#endif
+
                property_id = _contacts_person.id;
                break;
        case TELECOM_ICH:
@@ -1266,66 +1412,79 @@ static void __bluetooth_pb_get_vcards(BluetoothPbAgent *agent,
        default:
                return;
        }
+       INFO("Limit is = %d and offset is =%d\n", limit, offset);
+
+       /* When limit is passed as ZERO to contacts_db_get_records_with_query API
+        * then this API will provide all available contacts in its database (unrestricted).
+        * Now consider a case when client requests for maxlistcount of 1 and start offset as 0
+        * then we have already read the owner card in above switch case and when it reads owner
+        * card it decrements the limit by 1.
+        */
+       if(limit != 0)
+       {
+               status = contacts_db_get_records_with_query(query, offset, limit, &record_list);
+
+               if (status != CONTACTS_ERROR_NONE) {
+                       contacts_list_destroy(record_list, TRUE);
+                       contacts_query_destroy(query);
+                       return;
+               }
 
-       status = contacts_db_get_records_with_query(query, offset, limit, &record_list);
-
-       if (status != CONTACTS_ERROR_NONE) {
-               contacts_query_destroy(query);
-               return;
-       }
-
-       status = contacts_list_first(record_list);
+               status = contacts_list_first(record_list);
 
-       if (status != CONTACTS_ERROR_NONE) {
-               contacts_list_destroy(record_list, TRUE);
-               contacts_query_destroy(query);
-               return;
-       }
+               if (status != CONTACTS_ERROR_NONE) {
+                       contacts_list_destroy(record_list, TRUE);
+                       contacts_query_destroy(query);
+                       return;
+               }
 
-       do {
-               contacts_record_h record;
+               do {
+                       contacts_record_h record;
 
-               gint id;
+                       gint id;
 
-               gchar *vcard = NULL;
+                       gchar *vcard = NULL;
 
-               record = NULL;
-               status = contacts_list_get_current_record_p(record_list, &record);
+                       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, property_id, &id);
+                       if (status != CONTACTS_ERROR_NONE)
+                               continue;
+                       id = 0;
+                       status = contacts_record_get_int(record, property_id, &id);
 
-               if (status != CONTACTS_ERROR_NONE)
-                       continue;
+                       if (status != CONTACTS_ERROR_NONE)
+                               continue;
 
-               if (property_id == _contacts_person.id)
-                       vcard = _bluetooth_pb_vcard_contact(id, filter, format);
-               else {
-                       if (get_log)
-                               attr = __bluetooth_pb_phone_log_get_log_type(record);
+                       if (property_id == _contacts_person.id)
+                               vcard = _bluetooth_pb_vcard_contact(id, filter, format);
+                       else {
+                               if (get_log)
+                                       attr = __bluetooth_pb_phone_log_get_log_type(record);
 
-                       vcard = _bluetooth_pb_vcard_call(id, filter, format, attr);
-               }
+                               vcard = _bluetooth_pb_vcard_call(id, filter, format, attr);
+                       }
 
-               if (vcard)
-                       g_ptr_array_add(vcards, vcard);
+                       if (vcard)
+                               g_ptr_array_add(vcards, vcard);
 
-       } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+               } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+               contacts_list_destroy(record_list, TRUE);
+       }
 
-       contacts_list_destroy(record_list, TRUE);
        contacts_query_destroy(query);
+
+       FN_END;
 }
 
 static void __bluetooth_pb_get_contact_list(BluetoothPbAgent *agent,
                                        contacts_query_h query,
                                        GPtrArray *ptr_array)
 {
+       FN_START;
        contacts_list_h record_list = NULL;
 
        gint status;
-       int i = 1;
 
        /* Add owner */
        if (ptr_array) {
@@ -1345,8 +1504,10 @@ static void __bluetooth_pb_get_contact_list(BluetoothPbAgent *agent,
        status = contacts_db_get_records_with_query(query,
                        -1, -1, &record_list);
 
-       if (status != CONTACTS_ERROR_NONE)
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
                return;
+       }
 
        status = contacts_list_first(record_list);
 
@@ -1355,8 +1516,6 @@ static void __bluetooth_pb_get_contact_list(BluetoothPbAgent *agent,
                return;
        }
 
-       __bluetooth_pb_list_hash_reset(agent);
-
        do {
                contacts_record_h record;
 
@@ -1371,14 +1530,12 @@ static void __bluetooth_pb_get_contact_list(BluetoothPbAgent *agent,
 
                id = 0;
                status = contacts_record_get_int(record,
-                               _contacts_person.id,
+                               _contacts_person_contact.person_id,
                                &id);
 
                if (status != CONTACTS_ERROR_NONE)
                        continue;
 
-               __bluetooth_pb_list_hash_insert(agent, i, id);
-
                /* create list */
                if (ptr_array) {
                        gchar *name;
@@ -1388,27 +1545,26 @@ static void __bluetooth_pb_get_contact_list(BluetoothPbAgent *agent,
                        number = _bluetooth_pb_number_from_person_id(id);
 
                        __bluetooth_pb_list_ptr_array_add(ptr_array,
-                                       name, number, i);
+                                       name, number, id);
 
                        g_free(name);
                        g_free(number);
                }
 
-               i++;
-
        } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
 
        contacts_list_destroy(record_list, TRUE);
+       FN_END;
 }
 
 static void __bluetooth_pb_get_phone_log_list(BluetoothPbAgent *agent,
                                        contacts_query_h query,
                                        GPtrArray *ptr_array)
 {
+       FN_START;
        contacts_list_h record_list = NULL;
 
        gint status;
-       int i = 1;
 
        status = contacts_db_get_records_with_query(query,
                        -1, -1, &record_list);
@@ -1423,8 +1579,6 @@ static void __bluetooth_pb_get_phone_log_list(BluetoothPbAgent *agent,
                return;
        }
 
-       __bluetooth_pb_list_hash_reset(agent);
-
        do {
                contacts_record_h record;
 
@@ -1445,8 +1599,6 @@ static void __bluetooth_pb_get_phone_log_list(BluetoothPbAgent *agent,
                if (status != CONTACTS_ERROR_NONE)
                        continue;
 
-               __bluetooth_pb_list_hash_insert(agent, i, id);
-
                /* create list */
                if (ptr_array) {
                        gchar *name;
@@ -1460,16 +1612,15 @@ static void __bluetooth_pb_get_phone_log_list(BluetoothPbAgent *agent,
                                        &number);
 
                        __bluetooth_pb_list_ptr_array_add(ptr_array,
-                                       name, number, i);
+                                       name, number, id);
 
                        g_free(name);
                }
 
-               i++;
-
        } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
 
        contacts_list_destroy(record_list, TRUE);
+       FN_END;
 }
 
 
@@ -1477,6 +1628,7 @@ static void __bluetooth_pb_get_list(BluetoothPbAgent *agent,
                                PhoneBookType pb_type,
                                GPtrArray *ptr_array)
 {
+       FN_START;
        contacts_query_h query;
 
        /* no requires refresh cache */
@@ -1485,7 +1637,7 @@ static void __bluetooth_pb_get_list(BluetoothPbAgent *agent,
 
        switch (pb_type) {
        case TELECOM_PB:
-               query = __bluetooth_pb_query_person();
+               query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_PHONE);
                __bluetooth_pb_get_contact_list(agent, query, ptr_array);
                break;
        case TELECOM_ICH:
@@ -1504,6 +1656,12 @@ static void __bluetooth_pb_get_list(BluetoothPbAgent *agent,
                query = __bluetooth_pb_query_phone_log_combined();
                __bluetooth_pb_get_phone_log_list(agent, query, ptr_array);
                break;
+#ifdef PBAP_SIM_ENABLE
+       case SIM_PB:
+               query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_SIM);
+               __bluetooth_pb_get_contact_list(agent, query, ptr_array);
+               break;
+#endif
        default:
                return;
        }
@@ -1512,6 +1670,7 @@ static void __bluetooth_pb_get_list(BluetoothPbAgent *agent,
 
        if (query)
                contacts_query_destroy(query);
+       FN_END;
 }
 
 static void __bluetooth_pb_get_contact_list_number(BluetoothPbAgent *agent,
@@ -1520,12 +1679,10 @@ static void __bluetooth_pb_get_contact_list_number(BluetoothPbAgent *agent,
                                                gint end_index,
                                                GPtrArray *ptr_array)
 {
+       FN_START;
        contacts_list_h record_list = NULL;
-
        gint status;
-
        gint i;
-
        gint from;
        gint to;
        gint offset;
@@ -1549,8 +1706,10 @@ static void __bluetooth_pb_get_contact_list_number(BluetoothPbAgent *agent,
                        from - 1 , offset,
                        &record_list);
 
-       if (status != CONTACTS_ERROR_NONE)
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
                return;
+       }
 
        status = contacts_list_first(record_list);
 
@@ -1589,6 +1748,7 @@ static void __bluetooth_pb_get_contact_list_number(BluetoothPbAgent *agent,
        } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
 
        contacts_list_destroy(record_list, TRUE);
+       FN_END;
 }
 
 static void __bluetooth_pb_get_phone_log_list_number(BluetoothPbAgent *agent,
@@ -1597,6 +1757,7 @@ static void __bluetooth_pb_get_phone_log_list_number(BluetoothPbAgent *agent,
                                                gint end_index,
                                                GPtrArray *ptr_array)
 {
+       FN_START;
        contacts_list_h record_list = NULL;
 
        gint status;
@@ -1626,8 +1787,10 @@ static void __bluetooth_pb_get_phone_log_list_number(BluetoothPbAgent *agent,
                        from - 1 , offset,
                        &record_list);
 
-       if (status != CONTACTS_ERROR_NONE)
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
                return;
+       }
 
        status = contacts_list_first(record_list);
        if (status != CONTACTS_ERROR_NONE) {
@@ -1654,6 +1817,10 @@ static void __bluetooth_pb_get_phone_log_list_number(BluetoothPbAgent *agent,
                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);
 
@@ -1673,6 +1840,7 @@ static void __bluetooth_pb_get_phone_log_list_number(BluetoothPbAgent *agent,
        } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
 
        contacts_list_destroy(record_list, TRUE);
+       FN_END;
 }
 
 static void __bluetooth_pb_get_list_number(BluetoothPbAgent *agent,
@@ -1681,6 +1849,7 @@ static void __bluetooth_pb_get_list_number(BluetoothPbAgent *agent,
                                                gint end_index,
                                                GPtrArray *ptr_array)
 {
+       FN_START;
        contacts_query_h query;
 
        switch (pb_type) {
@@ -1715,6 +1884,7 @@ static void __bluetooth_pb_get_list_number(BluetoothPbAgent *agent,
 
        if (query)
                contacts_query_destroy(query);
+       FN_END;
 }
 
 static void __bluetooth_pb_get_contact_list_name(BluetoothPbAgent *agent,
@@ -1722,6 +1892,7 @@ static void __bluetooth_pb_get_contact_list_name(BluetoothPbAgent *agent,
                                                const gchar *find_text,
                                                GPtrArray *ptr_array)
 {
+       FN_START;
        contacts_list_h record_list = NULL;
 
        gint status;
@@ -1730,8 +1901,10 @@ static void __bluetooth_pb_get_contact_list_name(BluetoothPbAgent *agent,
        status = contacts_db_get_records_with_query(query,
                        -1, -1, &record_list);
 
-       if (status != CONTACTS_ERROR_NONE)
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
                return;
+       }
 
        status = contacts_list_first(record_list);
 
@@ -1771,6 +1944,8 @@ static void __bluetooth_pb_get_contact_list_name(BluetoothPbAgent *agent,
 
                i++;
        } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+       contacts_list_destroy(record_list, TRUE);
+       FN_END;
 }
 
 static void __bluetooth_pb_get_phone_log_list_name(BluetoothPbAgent *agent,
@@ -1778,6 +1953,7 @@ static void __bluetooth_pb_get_phone_log_list_name(BluetoothPbAgent *agent,
                                                const gchar *find_text,
                                                GPtrArray *ptr_array)
 {
+       FN_START;
        contacts_list_h record_list = NULL;
 
        gint status;
@@ -1788,8 +1964,10 @@ static void __bluetooth_pb_get_phone_log_list_name(BluetoothPbAgent *agent,
                        -1, -1,
                        &record_list);
 
-       if (status != CONTACTS_ERROR_NONE)
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
                return;
+       }
 
        status = contacts_list_first(record_list);
 
@@ -1816,6 +1994,10 @@ static void __bluetooth_pb_get_phone_log_list_name(BluetoothPbAgent *agent,
                status = contacts_record_get_int(record,
                                _contacts_phone_log.id,
                                &id);
+               if (status != CONTACTS_ERROR_NONE) {
+                       ERR("contacts_record_get_int failed %d", status);
+                       continue;
+               }
 
                display_name = _bluetooth_pb_fn_from_phonelog_id(id);
 
@@ -1838,6 +2020,7 @@ static void __bluetooth_pb_get_phone_log_list_name(BluetoothPbAgent *agent,
        } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
 
        contacts_list_destroy(record_list, TRUE);
+       FN_END;
 }
 
 static void __bluetooth_pb_get_list_name(BluetoothPbAgent *agent,
@@ -1845,6 +2028,7 @@ static void __bluetooth_pb_get_list_name(BluetoothPbAgent *agent,
                                        const gchar *find_text,
                                        GPtrArray *ptr_array)
 {
+       FN_START;
        contacts_query_h query;
 
        switch (pb_type) {
@@ -1879,41 +2063,7 @@ static void __bluetooth_pb_get_list_name(BluetoothPbAgent *agent,
 
        if (query)
                contacts_query_destroy(query);
-}
-
-static void __bluetooth_pb_list_hash_reset(BluetoothPbAgent *agent)
-{
-       if(agent->contact_list)
-               g_hash_table_destroy(agent->contact_list);
-
-       agent->contact_list = g_hash_table_new(g_direct_hash, g_direct_equal);
-}
-
-static gboolean __bluetooth_pb_list_hash_insert(BluetoothPbAgent *agent,
-                                               gint handle,
-                                               gint id)
-{
-       if (agent->contact_list == NULL)
-               return FALSE;
-
-       g_hash_table_insert(agent->contact_list,
-                       GINT_TO_POINTER(handle), GINT_TO_POINTER(id));
-
-       return TRUE;
-}
-
-static gint __bluetooth_pb_list_hash_lookup_id(BluetoothPbAgent *agent,
-                                       gint handle)
-{
-       gint id;
-
-       if (agent->contact_list == NULL)
-               return 0;
-
-       id = GPOINTER_TO_INT(g_hash_table_lookup(agent->contact_list,
-                               GINT_TO_POINTER(handle)));
-
-       return id;
+       FN_END;
 }
 
 static void __bluetooth_pb_list_ptr_array_add(GPtrArray *ptr_array,
@@ -1921,23 +2071,30 @@ static void __bluetooth_pb_list_ptr_array_add(GPtrArray *ptr_array,
                                                const gchar *number,
                                                gint handle)
 {
+       FN_START;
        GValue value = { 0, };
+       gchar *temp_name = g_strdup(name);
+       gchar *temp_number = g_strdup(number);
 
        g_value_init(&value, DBUS_STRUCT_STRING_STRING_UINT);
        g_value_take_boxed(&value,
                        dbus_g_type_specialized_construct(DBUS_STRUCT_STRING_STRING_UINT));
 
        dbus_g_type_struct_set(&value,
-                               0, g_strdup(name),
-                               1, g_strdup(number),
+                               0, temp_name,
+                               1, temp_number,
                                2, handle,
                                G_MAXUINT);
 
        g_ptr_array_add(ptr_array, g_value_get_boxed(&value));
+       g_free(temp_name);
+       g_free(temp_number)
+       FN_END;
 }
 
 static void __bluetooth_pb_list_ptr_array_free(gpointer data)
 {
+       FN_START;
        GValue value = { 0, };
 
        gchar *name = NULL;
@@ -1956,31 +2113,51 @@ static void __bluetooth_pb_list_ptr_array_free(gpointer data)
 
        g_free(name);
        g_free(number);
+       FN_END;
 }
 
 static void __bluetooth_pb_agent_signal_handler(int signum)
 {
-       if (mainloop)
+       FN_START;
+       if (mainloop) {
                g_main_loop_quit(mainloop);
-       else
+       } else {
+               DBG("Terminate Bluetooth PBAP agent");
                exit(0);
+       }
 }
 
 
 static void __bluetooth_pb_contact_changed(const gchar *view_uri,
                                        void *user_data)
 {
+       FN_START;
        BluetoothPbAgent *agent;
+       guint new_missed_call;
 
+       DBG("Received contact changed cb");
        g_return_if_fail(BLUETOOTH_IS_PB_AGENT(user_data));
        agent = BLUETOOTH_PB_AGENT(user_data);
 
+       g_object_ref(agent);
        g_signal_emit(agent, signals[CLEAR], 0);
        g_object_unref(agent);
+
+       __bluetooth_pb_get_count_new_missed_call(&new_missed_call);
+
+       if (new_missed_call > total_missed_call_count)
+               unnotified_missed_call_count += new_missed_call - total_missed_call_count;
+
+       INFO("Missed call count : #prev[%d], #current[%d], #unnotified[%d]",
+               total_missed_call_count, new_missed_call, unnotified_missed_call_count);
+
+       total_missed_call_count = new_missed_call;
+       FN_END;
 }
 
 static void __bluetooth_pb_agent_timeout_add_seconds(BluetoothPbAgent *agent)
 {
+       FN_START;
        g_return_if_fail(BLUETOOTH_IS_PB_AGENT(agent));
 
        if(agent->timeout_id)
@@ -1989,10 +2166,12 @@ static void __bluetooth_pb_agent_timeout_add_seconds(BluetoothPbAgent *agent)
        agent->timeout_id = g_timeout_add_seconds(BLUETOOTH_PB_AGENT_TIMEOUT,
                                __bluetooth_pb_agent_timeout_calback,
                                agent);
+       FN_END;
 }
 
 static gboolean __bluetooth_pb_agent_timeout_calback(gpointer user_data)
 {
+       FN_START;
        BluetoothPbAgent *agent;
 
        g_return_val_if_fail(BLUETOOTH_IS_PB_AGENT(user_data), FALSE);
@@ -2003,6 +2182,7 @@ static gboolean __bluetooth_pb_agent_timeout_calback(gpointer user_data)
        if (mainloop)
                g_main_loop_quit(mainloop);
 
+       FN_END;
        return FALSE;
 }
 
@@ -2011,6 +2191,7 @@ static void __bluetooth_pb_tel_callback(TapiHandle *handle,
                                        void *data,
                                        void *user_data)
 {
+       FN_START;
        BluetoothPbAgent *agent;
        TelSimMsisdnList_t *number;
 
@@ -2020,22 +2201,26 @@ static void __bluetooth_pb_tel_callback(TapiHandle *handle,
 
        __bluetooth_pb_agent_dbus_init(agent);
 
-       number = (TelSimMsisdnList_t *)data;
-       agent->tel_number = g_strdup(number->list[0].num);
+       if (data != NULL) {
+               number = (TelSimMsisdnList_t *)data;
+               agent->tel_number = g_strdup(number->list[0].num);
+       }
 
        tel_deinit(agent->tapi_handle);
        agent->tapi_handle = NULL;
+       FN_END;
 }
 
 static void __bluetooth_pb_agent_dbus_init(BluetoothPbAgent *agent)
 {
+       FN_START;
        guint result = 0;
        GError *error = NULL;
 
        agent->bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
 
        if (error != NULL) {
-               DBG("Couldn't connect to system bus[%s]\n", error->message);
+               ERR("Couldn't connect to system bus[%s]\n", error->message);
                g_error_free(error);
                return;
        }
@@ -2046,7 +2231,7 @@ static void __bluetooth_pb_agent_dbus_init(BluetoothPbAgent *agent)
                        DBUS_INTERFACE_DBUS);
 
        if (agent->proxy == NULL) {
-               DBG("Failed to get a proxy for D-Bus\n");
+               ERR("Failed to get a proxy for D-Bus\n");
                return;
        }
 
@@ -2058,7 +2243,7 @@ static void __bluetooth_pb_agent_dbus_init(BluetoothPbAgent *agent)
                                G_TYPE_UINT, &result,
                                G_TYPE_INVALID)) {
                if (error != NULL) {
-                       DBG("RequestName RPC failed[%s]\n", error->message);
+                       ERR("RequestName RPC failed[%s]\n", error->message);
                        g_error_free(error);
                }
 
@@ -2069,7 +2254,7 @@ static void __bluetooth_pb_agent_dbus_init(BluetoothPbAgent *agent)
        }
        DBG("result : %d %d\n", result, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
        if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
-               DBG("Failed to get the primary well-known name.\n");
+               ERR("Failed to get the primary well-known name.\n");
 
                g_object_unref(agent->proxy);
                agent->proxy = NULL;
@@ -2083,38 +2268,58 @@ static void __bluetooth_pb_agent_dbus_init(BluetoothPbAgent *agent)
        dbus_g_connection_register_g_object(agent->bus,
                        BT_PB_SERVICE_OBJECT_PATH,
                        G_OBJECT(agent));
+       FN_END;
+}
+
+static gboolean bluetooth_pb_destroy_agent(BluetoothPbAgent *agent,
+                                       DBusGMethodInvocation *context)
+{
+       FN_START;
+       g_main_loop_quit(mainloop);
+       FN_END;
+       return TRUE;
 }
 
-int main(int argc, char **argv)
+int main(void)
 {
+       FN_START;
        BluetoothPbAgent *agent;
 
        gint ret = EXIT_SUCCESS;
        gint tapi_result;
 
        struct sigaction sa;
+       DBG("Starting Bluetooth PBAP agent");
 
        g_type_init();
 
        mainloop = g_main_loop_new(NULL, FALSE);
        if (mainloop == NULL) {
-               DBG("Couldn't create GMainLoop\n");
+               ERR("Couldn't create GMainLoop\n");
                return EXIT_FAILURE;
        }
 
        agent = g_object_new(BLUETOOTH_PB_TYPE_AGENT, NULL);
 
        /* connect contact */
-       if (contacts_connect2() != CONTACTS_ERROR_NONE) {
-               DBG("Can not connect contacts server\n");
+       if (contacts_connect() != CONTACTS_ERROR_NONE) {
+               ERR("Can not connect contacts server\n");
                g_object_unref(agent);
                return EXIT_FAILURE;
        }
 
-       if (contacts_db_add_changed_cb(_contacts_event._uri,
+       __bluetooth_pb_get_count_new_missed_call(&total_missed_call_count);
+
+       if (contacts_db_add_changed_cb(_contacts_contact._uri,
+                       __bluetooth_pb_contact_changed,
+                       (void *)agent) != CONTACTS_ERROR_NONE) {
+               ERR("Can not add changed callback");
+       }
+
+       if (contacts_db_add_changed_cb(_contacts_phone_log._uri,
                        __bluetooth_pb_contact_changed,
-                       g_object_ref(agent)) != CONTACTS_ERROR_NONE) {
-               DBG("Can not add changed callback");
+                       (void *)agent) != CONTACTS_ERROR_NONE) {
+               ERR("Can not add changed callback");
        }
 
        /* set signal */
@@ -2137,23 +2342,26 @@ int main(int argc, char **argv)
 
        g_main_loop_run(mainloop);
 
-       DBG("Terminate the bluetooth-pb-agent\n");
-
-       if (agent) {
-               contacts_db_remove_changed_cb(_contacts_event._uri,
-                               __bluetooth_pb_contact_changed,
-                               g_object_ref(agent));
-
-               g_object_unref(agent);
+       if (contacts_db_remove_changed_cb(_contacts_phone_log._uri,
+                       __bluetooth_pb_contact_changed,
+                       (void *)agent) != CONTACTS_ERROR_NONE) {
+               ERR("Cannot remove changed callback");
        }
 
+       if (contacts_db_remove_changed_cb(_contacts_contact._uri,
+                       __bluetooth_pb_contact_changed,
+                       (void *)agent) != CONTACTS_ERROR_NONE) {
+               ERR("Cannot remove changed callback");
+       }
 
-       contacts_disconnect2();
+       if (contacts_disconnect() != CONTACTS_ERROR_NONE)
+               ERR("contacts_disconnect failed \n");
 
        g_signal_emit(agent, signals[CLEAR], 0);
 
-       if (agent)
-               g_object_unref(agent);
+       g_object_unref(agent);
 
+       DBG("Terminate Bluetooth PBAP agent");
+       FN_END;
        return ret;
 }
index 515170b..cbe4d62 100644 (file)
@@ -1,13 +1,17 @@
 /*
- * bluetooth-agent
+ * Bluetooth-agent
  *
- * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
+ *              Girishashok Joshi <girish.joshi@samsung.com>
+ *              Chanyeol Park <chanyeol.park@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
+ *             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,
 #define BT_PB_SERVICE_INTERFACE                "org.bluez.PbAgent"
 
 #undef LOG_TAG
-#define LOG_TAG "BLUETOOTH_AGENT_PHONEBOOK"
-
+#define LOG_TAG "BLUETOOTH_AGENT_PB"
+#define INFO(fmt, args...) SLOGI(fmt, ##args)
 #define DBG(fmt, args...) SLOGD(fmt, ##args)
 #define ERR(fmt, args...) SLOGE(fmt, ##args)
 
+#define DBG_SECURE(fmt, args...) SECURE_SLOGD(fmt, ##args)
+#define ERR_SECURE(fmt, args...) SECURE_SLOGE(fmt, ##args)
+
+#ifdef FUCNTION_CALLS
+#define FN_START       DBG("ENTER==>")
+#define FN_END         DBG("EXIT===>")
+#else
+#define FN_START
+#define FN_END
+#endif
+
+static gchar *bluetooth_pb_agent_folder_list[] = {
+       "/telecom/pb",
+       "/telecom/ich",
+       "/telecom/och",
+       "/telecom/mch",
+       "/telecom/cch",
+#ifdef PBAP_SIM_ENABLE
+       "/SIM1/telecom/pb",
+#endif
+       NULL
+};
+
+typedef enum {
+       TELECOM_PB = 0,
+       TELECOM_ICH,
+       TELECOM_OCH,
+       TELECOM_MCH,
+       TELECOM_CCH,
+#ifdef PBAP_SIM_ENABLE
+       SIM_PB,
+#endif
+       TELECOM_NONE
+} PhoneBookType;
+
 #endif                         /* __DEF_BT_AGENT_H_ */
index f41836c..27bc433 100644 (file)
@@ -28,6 +28,7 @@
                        <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
                        <arg type="s" name="name"/>
                        <arg type="a(ssu)" name="phonebook_list" direction="out"/>
+                       <arg type="u" name="new_missed_call" direction="out"/>
                </method>
 
                <method name="GetPhonebookEntry">
                        <arg type="s" name="filename"/>
                </method>
 
+               <method name="DestroyAgent">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+               </method>
+
                <signal name="clear"/>
 
        </interface>
index c17dc44..ba74060 100644 (file)
@@ -1,13 +1,18 @@
 /*
- * bluetooth-agent
+ * Bluetooth-agent
  *
- * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
+ *              Girishashok Joshi <girish.joshi@samsung.com>
+ *              Chanyeol Park <chanyeol.park@samsung.com>
+ *              Jaekyun Lee <jkyun.lee@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
+ *             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,
  * limitations under the License.
  *
  */
-
 #include <time.h>
 #include <string.h>
 #include <stdarg.h>
-
-
+#include <stdlib.h>
+#include <stdio.h>
 #include <glib.h>
 #include <dbus/dbus-glib.h>
-
 #include <vconf.h>
 #include <dlog.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
 #include <contacts.h>
+#include <image_util.h>
+//#include <image_util_product.h>
+#include <libexif/exif-data.h>
+#include <unistd.h>
 
 #include "bluetooth_pb_vcard.h"
-
-#define BT_PB_AGENT    "BT_PB_AGENT"
-#define DBG(fmt, args...) SLOG(LOG_DEBUG, BT_PB_AGENT, "%s():%d "fmt, __func__, __LINE__, ##args)
-#define ERR(fmt, args...) SLOG(LOG_ERROR, BT_PB_AGENT, "%s():%d "fmt, __func__, __LINE__, ##args)
+#include "bluetooth_pb_agent.h"
 
 #define VCARD_FORMAT_2_1 0x0
 #define VCARD_FORMAT_3_0 0x1
 #define VCARD_PROID    (0x1 << 25)     /* not supported */
 #define VCARD_CLASS    (0x1 << 26)     /* not supported */
 #define VCARD_SORT_STRING      (0x1 << 27)     /* not supported */
-
 #define VCARD_X_IRMC_CALL_DATETIME     (0x1 << 28)
 
 #define QP_ENC_LEN     3
 #define LINEBREAK_LEN  75
 
+typedef struct {
+       const char *src;
+       const char *dest;
+       int ret;
+       contacts_record_h person;
+       GString *string;
+} bt_image_info_t;
+
+gchar dest_thumb_path[255];
+#define PBAP_IMAGE_THUMB_SIZE 48
+#define PBAP_THMB_PATH "_thumb"
+#define PBAP_THUMB_FILE_SIZE 4096
+#define PBAP_IMAGE_ENCODE_QUALITY      90
+#define PBAP_SECURITY_FILE_GROUP 6005
+#define PBAP_SECURITY_DEFAULT_PERMISSION 0660
+#define PBAP_SECURITY_DIR_DEFAULT_PERMISSION 0770
+#define PBAP_SECURITY_IMAGE_PERMISSION 0440
+
 static gchar *__bluetooth_pb_vcard_escape(const gchar *str);
 
 static gchar *__bluetooth_pb_vcard_strv_concat(gchar **strv,
@@ -116,6 +140,9 @@ static void __bluetooth_pb_vcard_append_base64_encode_v21(GString *string,
 static void __bluetooth_pb_vcard_append_n_v21(GString *string,
                                        contacts_record_h contact);
 
+static void __bluetooth_pb_vcard_append_phonetic_first_v21(GString *string,
+                                       contacts_record_h contact);
+
 static void __bluetooth_pb_vcard_append_tel_v21(GString *string,
                                                contacts_record_h conatct);
 
@@ -179,11 +206,11 @@ static gchar *__bluetooth_pb_vcard_real_contact_valist_v30(gint person_id,
                                                        va_list args);
 
 static gchar *__bluetooth_pb_vcard_real_contact_with_properties(gint person_id,
-                                                               gint phonelog_id,
-                                                               guint64 filter,
-                                                               guint8 format,
-                                                               const gchar *first_name,
-                                                               ...);
+                                                       gint phonelog_id,
+                                                       guint64 filter,
+                                                       guint8 format,
+                                                       const gchar *first_name,
+                                                       ...);
 
 static gchar *__bluetooth_pb_vcard_real_call_v21(gint phonelog_id,
                                                guint filter,
@@ -214,6 +241,8 @@ static gchar *__bluetooth_pb_phonelog_datetime(gint phonelog_id);
 
 static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact);
 
+static gchar *__bluetooth_pb_phonetic_name_from_contact(contacts_record_h contact);
+
 static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact);
 
 static gint __bluetooth_pb_person_id_from_phonelog_id(gint phonelog_id);
@@ -221,6 +250,7 @@ static gint __bluetooth_pb_person_id_from_phonelog_id(gint phonelog_id);
 
 static gchar *__bluetooth_pb_vcard_escape(const gchar *str)
 {
+       FN_START;
        GString *escaped;
 
        gchar *st = NULL;
@@ -241,19 +271,20 @@ static gchar *__bluetooth_pb_vcard_escape(const gchar *str)
 
                        pos++;
                        st = pos;
-               }
-               else {
+               } else {
                        pos++;
                }
        }
 
        g_string_append_len(escaped, st, (pos - st));
+       FN_END;
        return g_string_free(escaped, FALSE);
 }
 
 static gchar *__bluetooth_pb_vcard_strv_concat(gchar **strv,
                                        const gchar *separator)
 {
+       FN_START;
        GString *string = g_string_new(NULL);
        gint i;
 
@@ -264,11 +295,13 @@ static gchar *__bluetooth_pb_vcard_strv_concat(gchar **strv,
                g_string_append(string, strv[i]);
        }
 
+       FN_END;
        return g_string_free(string, FALSE);
 }
 
 static gboolean __bluetooth_pb_vcard_qp_encode_check(const gchar *str)
 {
+       FN_START;
        gchar *pos = NULL;
 
        if (str == NULL)
@@ -282,6 +315,7 @@ static gboolean __bluetooth_pb_vcard_qp_encode_check(const gchar *str)
 
                pos++;
        }
+       FN_END;
        return FALSE;
 }
 
@@ -289,6 +323,7 @@ static gboolean __bluetooth_pb_vcard_qp_encode_check(const gchar *str)
 static gint __bluetooth_pb_vcard_qp_encode_strlen(const gchar *str,
                                                gint len)
 {
+       FN_START;
        gchar *pos;
 
        gint count = 0;
@@ -297,7 +332,7 @@ static gint __bluetooth_pb_vcard_qp_encode_strlen(const gchar *str,
        if (str == NULL)
                return 0;
 
-       if (strlen(str) < len )
+       if (strlen(str) < len)
                length = -1;
 
        pos = (gchar *)str;
@@ -331,6 +366,7 @@ static gint __bluetooth_pb_vcard_qp_encode_strlen(const gchar *str,
                count++;
        }
 
+       FN_END;
        return count;
 }
 
@@ -340,6 +376,7 @@ static void __bluetooth_pb_vcard_qp_encode_append_to_hex(GString *string,
                                                        gint len,
                                                        gint *line_pos)
 {
+       FN_START;
        int i;
 
        if (str == NULL || len == 0)
@@ -355,6 +392,7 @@ static void __bluetooth_pb_vcard_qp_encode_append_to_hex(GString *string,
                g_string_append_printf(string, "=%02X", (guchar)*(str+i));
                *line_pos += QP_ENC_LEN;
        }
+       FN_END;
 }
 
 /* append plain visiable ascii character */
@@ -362,6 +400,7 @@ static void __bluetooth_pb_vcard_qp_encode_append_printable_c(GString *string,
                                                        gchar ch,
                                                        gint *line_pos)
 {
+       FN_START;
        /* add soft linebreak when it exceed */
        if (*line_pos + 1 > LINEBREAK_LEN) {
                g_string_append(string, "=\r\n");
@@ -369,6 +408,7 @@ static void __bluetooth_pb_vcard_qp_encode_append_printable_c(GString *string,
        }
        g_string_append_c(string, ch);
        (*line_pos)++;
+       FN_END;
 }
 
 static void __bluetooth_pb_vcard_qp_encode_append(GString *string,
@@ -376,7 +416,7 @@ static void __bluetooth_pb_vcard_qp_encode_append(GString *string,
                                                gint len,
                                                gint *line_pos)
 {
-       gint length;
+       FN_START;
        gint encode_len;
 
        gint i = 0;
@@ -392,20 +432,17 @@ static void __bluetooth_pb_vcard_qp_encode_append(GString *string,
                *line_pos = 0;
        }
 
-       length = strlen(str);
-       if (length > len)
-               length = len;
-
        while (i < len) {
                gchar *pos;
 
                pos = ((gchar *)str) + i;
 
-               /* converts invisiable character and escape character '=' to quoted-printable */
+               /* converts invisiable character and escape character '='
+                       to quoted-printable */
                if ((guchar)*pos != '\t' &&
                                ((guchar)*pos < ' ' || (guchar)*pos == '=')) {
-                       __bluetooth_pb_vcard_qp_encode_append_to_hex(string, pos,
-                                       1, line_pos);
+                       __bluetooth_pb_vcard_qp_encode_append_to_hex(string,
+                                                       pos, 1, line_pos);
                        i++;
 
                        continue;
@@ -419,20 +456,23 @@ static void __bluetooth_pb_vcard_qp_encode_append(GString *string,
                        next = g_utf8_next_char(pos);
 
                        ch_len = next - pos;
-                       __bluetooth_pb_vcard_qp_encode_append_to_hex(string, pos,
-                                       ch_len, line_pos);
+                       __bluetooth_pb_vcard_qp_encode_append_to_hex(string,
+                                                       pos, ch_len, line_pos);
                        i += ch_len;
 
                        continue;
                }
 
-               __bluetooth_pb_vcard_qp_encode_append_printable_c(string, *pos, line_pos);
+               __bluetooth_pb_vcard_qp_encode_append_printable_c(string, *pos,
+                                                               line_pos);
                i++;
        }
+       FN_END;
 }
 
-static gchar__bluetooth_pb_vcard_qp_encode(const gchar *str)
+static gchar *__bluetooth_pb_vcard_qp_encode(const gchar *str)
 {
+       FN_START;
        GString *enc;
 
        gchar *st_pos;
@@ -460,15 +500,16 @@ static gchar* __bluetooth_pb_vcard_qp_encode(const gchar *str)
                        continue;
                }
 
-               /* split string with given delimeter '\r', '\n' or '\r\n' - newline */
-               if (*pos == '\r' || *pos == '\n' ) {
+               /* split string with given delimeter '\r', '\n' or
+                       '\r\n' - newline */
+               if (*pos == '\r' || *pos == '\n') {
                        __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
                                        (pos - st_pos), &line_pos);
 
                        /* converts newline to qp_encode with soft linebreak
                         for example, converts \r\n to =0D=0A=\r\n */
-                       __bluetooth_pb_vcard_qp_encode_append_to_hex(enc, "\r\n",
-                                       2, &line_pos);
+                       __bluetooth_pb_vcard_qp_encode_append_to_hex(enc,
+                                                       "\r\n", 2, &line_pos);
                        g_string_append(enc, "=\r\n ");
 
                        line_pos = 1;
@@ -489,12 +530,14 @@ static gchar* __bluetooth_pb_vcard_qp_encode(const gchar *str)
        __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
                        (pos - st_pos), &line_pos);
 
+       FN_END;
        return g_string_free(enc, FALSE);
 }
 
 static void __bluetooth_pb_vcard_append_param_v21(GString *string,
                                                 const gchar *param)
 {
+       FN_START;
        gchar *pos = NULL;
 
        if (param == NULL)
@@ -512,6 +555,7 @@ static void __bluetooth_pb_vcard_append_param_v21(GString *string,
 
        if (*pos != '\0')
                g_string_append_printf(string, ";%s", pos);
+       FN_END;
 }
 
 static void __bluetooth_pb_vcard_append_qp_encode_v21(GString *string,
@@ -519,6 +563,7 @@ static void __bluetooth_pb_vcard_append_qp_encode_v21(GString *string,
                                                const gchar *param,
                                                const gchar *value)
 {
+       FN_START;
        GString *property = NULL;
 
        if (name == NULL)
@@ -551,6 +596,7 @@ static void __bluetooth_pb_vcard_append_qp_encode_v21(GString *string,
        g_string_append_printf(string, "%s\r\n", property->str);
 
        g_string_free(property, TRUE);
+       FN_END;
 }
 
 
@@ -561,10 +607,12 @@ static void __bluetooth_pb_vcard_append_base64_encode_v21(GString *string,
                                                        gsize len,
                                                        gboolean folding)
 {
+       FN_START;
        gchar *enc = NULL;
 
        if (name == NULL)
                return;
+       DBG("base 64 encoding\n");
 
        g_string_append(string, name);
 
@@ -578,7 +626,6 @@ static void __bluetooth_pb_vcard_append_base64_encode_v21(GString *string,
 
        enc = g_base64_encode((const guchar *)value, len);
 
-
        if (folding == FALSE) {
                g_string_append(string, enc);
        } else {
@@ -586,38 +633,59 @@ static void __bluetooth_pb_vcard_append_base64_encode_v21(GString *string,
                gint i = 0;
 
                /* count ' ' size for folding */
-               gint fline_len = LINEBREAK_LEN -1;
+               gint fline_len = LINEBREAK_LEN - 1;
 
                for (i = 0; (i * fline_len) < enc_len; i++) {
                        g_string_append(string, "\r\n ");
                        if ((i * fline_len) + fline_len > enc_len)
                                g_string_append(string, enc + (i * fline_len));
                        else
-                               g_string_append_len(string, enc + (i * fline_len), fline_len);
+                               g_string_append_len(string, enc +
+                                               (i * fline_len), fline_len);
                }
 
                /* some application requires more \r\n */
                g_string_append(string, "\r\n");
        }
        g_string_append(string, "\r\n");
+       DBG("base 64 encoding\n");
 
        g_free(enc);
+       FN_END;
 }
 
 static void __bluetooth_pb_vcard_append_n_v21(GString *string,
                                        contacts_record_h contact)
 {
+       FN_START;
        gchar *str;
 
        str = __bluetooth_pb_name_from_contact(contact);
        __bluetooth_pb_vcard_append_qp_encode_v21(string, "N", NULL, str);
 
        g_free(str);
+       FN_END;
+}
+
+static void __bluetooth_pb_vcard_append_phonetic_first_v21(GString *string,
+                                       contacts_record_h contact)
+{
+       FN_START;
+       gchar *str;
+
+       str = __bluetooth_pb_phonetic_name_from_contact(contact);
+
+       if (str != NULL) {
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "SOUND", "X-IRMC-N", str);
+               g_free(str);
+       }
+       FN_END;
 }
 
 static void __bluetooth_pb_vcard_append_tel_v21(GString *string,
                                                contacts_record_h contact)
 {
+       FN_START;
        guint count = 0;
 
        gint i;
@@ -655,20 +723,23 @@ static void __bluetooth_pb_vcard_append_tel_v21(GString *string,
                escaped = __bluetooth_pb_vcard_escape(tel);
 
                paramv = __bluetooth_pb_contact_tel_param(number);
-               param = __bluetooth_pb_vcard_strv_concat(paramv, ";");
-
-               g_strfreev(paramv);
-
-               __bluetooth_pb_vcard_append_qp_encode_v21(string, "TEL", param, escaped);
+               if (paramv) {
+                       param = __bluetooth_pb_vcard_strv_concat(paramv, ";");
+                       g_strfreev(paramv);
+                       __bluetooth_pb_vcard_append_qp_encode_v21(string, "TEL", param,
+                                                               escaped);
+                       g_free(param);
+               }
 
                g_free(escaped);
-               g_free(param);
        }
+       FN_END;
 }
 
 static void __bluetooth_pb_vcard_append_fn_v21(GString *string,
                                        contacts_record_h person)
 {
+       FN_START;
        gint status;
 
        gchar *fn = NULL;
@@ -688,49 +759,298 @@ static void __bluetooth_pb_vcard_append_fn_v21(GString *string,
        g_free(fn);
 }
 
-static void __bluetooth_pb_vcard_append_photo_v21(GString *string,
-                                               contacts_record_h person)
+static image_util_rotation_e __bt_pbap_get_rotation_info(const char *path)
 {
-       gint status;
+       FN_START;
+       ExifData *ed = NULL;
+       ExifEntry *entry;
+       image_util_rotation_e rotation = IMAGE_UTIL_ROTATION_NONE;
+       int orientation = 0;
 
-       gsize len = 0;
+       ed = exif_data_new_from_file(path);
+       if (ed == NULL) {
+               ERR("exif_data_new_from_file : ExifData is NULL");
+               return IMAGE_UTIL_ROTATION_NONE;
+       }
 
-       gchar *filename = NULL;
+       entry = exif_data_get_entry(ed, EXIF_TAG_ORIENTATION);
+       if (entry) {
+               ExifByteOrder mByteOrder = exif_data_get_byte_order(ed);
+               orientation = (int)exif_get_short(entry->data, mByteOrder);
+               if (orientation < 0 || orientation > 8)
+                       orientation = 0;
+       }
+
+       exif_data_unref(ed);
 
+       switch (orientation) {
+       case 1: /* Top-left */
+               rotation = IMAGE_UTIL_ROTATION_NONE;
+               break;
+       case 2: /* Top-right */
+               rotation = IMAGE_UTIL_ROTATION_FLIP_HORZ;
+               break;
+       case 3: /* Bottom-right */
+               rotation = IMAGE_UTIL_ROTATION_180;
+               break;
+       case 4: /* Bottom-left */
+               rotation = IMAGE_UTIL_ROTATION_FLIP_VERT;
+               break;
+       case 6: /* Right-top */
+               rotation = IMAGE_UTIL_ROTATION_90;
+               break;
+       case 8: /* Left-bottom */
+               rotation = IMAGE_UTIL_ROTATION_270;
+               break;
+       case 5: /* Left-top */
+       case 7: /* Right-bottom */
+       case 0:
+       default:
+               break;
+       };
+
+       FN_END;
+       return rotation;
+}
+
+
+static bool __bt_pbap_image_util_supported_jpeg_colorspace_cb(
+                       image_util_colorspace_e colorspace, void *user_data)
+{
+       FN_START;
+       unsigned char *img_target = 0;
+       unsigned char *img_source = 0;
        gchar *type = NULL;
        gchar *param = NULL;
        gchar *contents = NULL;
+       int width = 0;
+       int height = 0;
+       int resized_width = 0;
+       int resized_height = 0;
+       int dest_fd = 0;
+       unsigned int size_decode = 0;
+       image_util_rotation_e rotation;
+       image_util_error_e ret = 0;
+       gsize len = 0;
 
+       bt_image_info_t *info = (bt_image_info_t *)user_data;
+       rotation = __bt_pbap_get_rotation_info(info->src);
+       ret = image_util_decode_jpeg(info->src, colorspace, &img_source, &width,
+                                                       &height, &size_decode);
+       if (ret != IMAGE_UTIL_ERROR_NONE) {
+               ERR("Can not decode");
+               memset(info, 0x00, sizeof(bt_image_info_t));
+               return true;
+       }
+
+       DBG("decoding completed width = %d, height = %d, size = %d\n", width,
+                                                       height, size_decode);
+       if (width > PBAP_IMAGE_THUMB_SIZE  || height > PBAP_IMAGE_THUMB_SIZE) {
+               if (width <= 0 || height <= 0) {
+                       free(img_source);
+                       ERR("image size error(%d)", PBAP_IMAGE_THUMB_SIZE);
+                       memset(info, 0x00, sizeof(bt_image_info_t));
+                       return false;
+               }
 
-       status = contacts_record_get_str_p(person,
-                       _contacts_person.image_thumbnail_path,
-                       &filename);
-
-       if (status != CONTACTS_ERROR_NONE)
-               return;
+               if (width > height) {
+                       resized_width = PBAP_IMAGE_THUMB_SIZE ;
+                       resized_height = height * PBAP_IMAGE_THUMB_SIZE / width;
+               } else {
+                       resized_height = PBAP_IMAGE_THUMB_SIZE;
+                       resized_width = width * PBAP_IMAGE_THUMB_SIZE / height;
+               }
 
-       type = __bluetooth_pb_contact_photo_type(filename);
+               if (resized_height % 8)
+                       resized_height += 8 - (resized_height % 8);
+               if (resized_width % 8)
+                       resized_width += 8 - (resized_width % 8);
+
+               DBG("original size[%d, %d] changed to resize[%d,%d]", width,
+                                       height, resized_width, resized_height);
+
+               ret = image_util_calculate_buffer_size(resized_width,
+                                                       resized_height,
+                                                       colorspace ,
+                                                       &size_decode);
+
+               img_target = g_malloc0(size_decode);
+
+               /* do resize */
+               ret = image_util_resize(img_target, &resized_width,
+                                       &resized_height, img_source, width,
+                                       height, colorspace);
+               if (ret != IMAGE_UTIL_ERROR_NONE) {
+                       ERR("image_util_resize failed(%d)", ret);
+                       g_free(img_target);
+                       free(img_source);
+                       memset(info, 0x00, sizeof(bt_image_info_t));
+                       return false;
+               }
+               free(img_source);
+       } else {
+               resized_width = width;
+               resized_height = height;
+               img_target = img_source;
+       }
+       DBG("Resized w = %d, ht = %d, size = %d\n", width, height, size_decode);
+
+       if (IMAGE_UTIL_ROTATION_NONE != rotation) {
+               int rotated_width, rotated_height;
+               unsigned char *img_rotate = 0;
+               img_rotate = g_malloc0(size_decode);
+               image_util_rotate(img_rotate, &rotated_width, &rotated_height,
+                                       rotation, img_target, resized_width,
+                                       resized_height, colorspace);
+               resized_width = rotated_width;
+               resized_height = rotated_height;
+               g_free(img_target);
+               img_target = img_rotate;
+       }
+
+       /* image encode */
+       ret = image_util_encode_jpeg(img_target, resized_width, resized_height,
+                                       colorspace, PBAP_IMAGE_ENCODE_QUALITY,
+                                       info->dest);
+       g_free(img_target);
+       if (ret != IMAGE_UTIL_ERROR_NONE) {
+               ERR("image_util_encode_jpeg failed(%d)", ret);
+               info->ret = CONTACTS_ERROR_INTERNAL;
+               goto done;
+       }
+       DBG("Encoding done\n");
+
+       dest_fd = open(info->dest, O_RDONLY);
+       if (dest_fd < 0) {
+               ERR("System : Open Failed(%d)", errno);
+               ERR_SECURE("Open : dest path(%s)", info->dest);
+               goto done;
+       }
+
+       ret = fchown(dest_fd, getuid(), PBAP_SECURITY_FILE_GROUP);
+       if (0 != ret) {
+               ERR("fchown Failed(%d)", errno);
+               DBG_SECURE("fchown : dest path(%s)", info->dest);
+               close(dest_fd);
+               goto done;
+       }
+
+       ret = fchmod(dest_fd, PBAP_SECURITY_IMAGE_PERMISSION);
+       if (0 != ret) {
+               ERR("fchmod Failed(%d)", errno);
+               ERR_SECURE("fchmod : dest path(%s)", info->dest);
+               close(dest_fd);
+               goto done;
+       }
+       close(dest_fd);
+
+       info->ret = CONTACTS_ERROR_NONE;
+       type = __bluetooth_pb_contact_photo_type(info->dest);
+       DBG("Cintact image thumb type is = %s\n", type);
 
        if (type) {
                param = g_strdup_printf("TYPE=%s", type);
                g_free(type);
        }
 
-       if (g_file_get_contents(filename, &contents, &len, NULL) == FALSE) {
-               ERR("can not read file contents:%s\n", filename);
-               return;
+       if (g_file_get_contents(info->dest, &contents, &len, NULL) == FALSE) {
+               ERR("can not read file contents:%s\n", info->dest);
+               goto done;
        }
 
-       __bluetooth_pb_vcard_append_base64_encode_v21(string,
+       __bluetooth_pb_vcard_append_base64_encode_v21(info->string,
                        "PHOTO", param, contents, len, TRUE);
 
+done:
        g_free(param);
        g_free(contents);
+       remove(info->dest);
+       memset(info, 0x00, sizeof(bt_image_info_t));
+       DBG("Cintact image thumb created successfuly\n");
+       FN_END;
+       return false;
+}
+
+static void __bluetooth_pb_vcard_append_photo_v21(GString *string,
+                                               contacts_record_h person)
+{
+       FN_START;
+       gint status;
+       gchar *filename = NULL;
+       int res = 0;
+       bt_image_info_t img_info;
+       struct stat stat_info;
+       gchar *type = NULL;
+       gchar *param = NULL;
+       gchar *contents = NULL;
+       gsize len = 0;
+       char *ptr = NULL;
+
+       status = contacts_record_get_str_p(person,
+                       _contacts_person.image_thumbnail_path,
+                       &filename);
+
+       if (status != CONTACTS_ERROR_NONE || NULL == filename)
+               return;
+
+       stat_info.st_size = 0;
+
+       if (0 > stat(filename, &stat_info)) {
+               ERR("fstat failed, file does not exist %s", filename);
+       }
+
+       if (PBAP_THUMB_FILE_SIZE > stat_info.st_size) {
+               DBG_SECURE("File size small, so use thubnail %s\n", filename);
+
+               type = __bluetooth_pb_contact_photo_type(filename);
+               if (type) {
+                       param = g_strdup_printf("TYPE=%s", type);
+                       g_free(type);
+               }
+
+               if (g_file_get_contents(filename, &contents, &len, NULL) ==
+                                                                       FALSE) {
+                       ERR("can not read file contents:%s\n", filename);
+                       g_free(param);
+                       return;
+               }
+               DBG("Retrieved the contents of the file \n");
+               __bluetooth_pb_vcard_append_base64_encode_v21(string,
+                               "PHOTO", param, contents, len, TRUE);
+
+               g_free(param);
+               g_free(contents);
+               return;
+       }
+
+       ptr = strrchr(filename, '.');
+       if (NULL != ptr) {
+               memset(dest_thumb_path, 0x00, sizeof(dest_thumb_path));
+               g_strlcpy(dest_thumb_path, filename, ptr - filename);
+               g_strlcat(dest_thumb_path, PBAP_THMB_PATH,
+                                               sizeof(dest_thumb_path));
+               g_strlcat(dest_thumb_path, ptr, sizeof(dest_thumb_path));
+               DBG("Thumbnail path is = %s", dest_thumb_path);
+       }
+       DBG_SECURE("filename = %s Thumbnail path is = %s", filename, dest_thumb_path);
+       img_info.src = filename;
+       img_info.dest = dest_thumb_path;
+       img_info.ret = CONTACTS_ERROR_INTERNAL;
+       img_info.person = person;
+       img_info.string = string;
+
+       res = image_util_foreach_supported_jpeg_colorspace(
+               __bt_pbap_image_util_supported_jpeg_colorspace_cb, &img_info);
+       if (res != IMAGE_UTIL_ERROR_NONE) {
+               ERR("Image resizing is failed");
+       }
+       FN_END;
 }
 
 static void __bluetooth_pb_vcard_append_bday_v21(GString *string,
                                                contacts_record_h contact)
 {
+       FN_START;
        guint count = 0;
 
        gint status;
@@ -783,11 +1103,13 @@ static void __bluetooth_pb_vcard_append_bday_v21(GString *string,
                                NULL, bday);
                g_free(bday);
        }
+       FN_END;
 }
 
 static void __bluetooth_pb_vcard_append_adr_v21(GString *string,
                                                contacts_record_h contact)
 {
+       FN_START;
        guint count = 0;
 
        gint status;
@@ -824,20 +1146,24 @@ static void __bluetooth_pb_vcard_append_adr_v21(GString *string,
                g_strfreev(addrv);
 
                paramv = __bluetooth_pb_contact_addr_param(address);
-               param = __bluetooth_pb_vcard_strv_concat(paramv, ";");
-               g_strfreev(paramv);
+               if (paramv) {
+                       param = __bluetooth_pb_vcard_strv_concat(paramv, ";");
+                       g_strfreev(paramv);
 
-               __bluetooth_pb_vcard_append_qp_encode_v21(string, "ADR",
-                               param, addr);
+                       __bluetooth_pb_vcard_append_qp_encode_v21(string, "ADR",
+                                       param, addr);
+                       g_free(param);
+               }
 
-               g_free(param);
                g_free(addr);
        }
+       FN_END;
 }
 
 static void __bluetooth_pb_vcard_append_email_v21(GString *string,
                                                contacts_record_h contact)
 {
+       FN_START;
        guint count = 0;
 
        gint status;
@@ -870,15 +1196,18 @@ static void __bluetooth_pb_vcard_append_email_v21(GString *string,
                        continue;
 
                escaped = __bluetooth_pb_vcard_escape(tmp);
-               __bluetooth_pb_vcard_append_qp_encode_v21(string, "EMAIL", NULL, escaped);
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "EMAIL", NULL,
+                                                               escaped);
 
                g_free(escaped);
        }
+       FN_END;
 }
 
 static void __bluetooth_pb_vcard_append_title_v21(GString *string,
                                                contacts_record_h contact)
 {
+       FN_START;
        guint count = 0;
 
        gint status;
@@ -898,7 +1227,7 @@ static void __bluetooth_pb_vcard_append_title_v21(GString *string,
                gchar *escaped;
 
                status = contacts_record_get_child_record_at_p(contact,
-                               _contacts_contact.company,i, &company);
+                                       _contacts_contact.company, i, &company);
 
                if (status != CONTACTS_ERROR_NONE)
                        continue;
@@ -911,15 +1240,18 @@ static void __bluetooth_pb_vcard_append_title_v21(GString *string,
                        continue;
 
                escaped = __bluetooth_pb_vcard_escape(title);
-               __bluetooth_pb_vcard_append_qp_encode_v21(string, "TITLE", NULL, escaped);
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "TITLE", NULL,
+                                                               escaped);
 
                g_free(escaped);
        }
+       FN_END;
 }
 
 static void __bluetooth_pb_vcard_append_role_v21(GString *string,
                                                contacts_record_h contact)
 {
+       FN_START;
        guint count = 0;
 
        gint status;
@@ -952,15 +1284,18 @@ static void __bluetooth_pb_vcard_append_role_v21(GString *string,
                        continue;
 
                escaped = __bluetooth_pb_vcard_escape(role);
-               __bluetooth_pb_vcard_append_qp_encode_v21(string, "ROLE", NULL, escaped);
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "ROLE", NULL,
+                                                               escaped);
 
                g_free(escaped);
        }
+       FN_END;
 }
 
 static void __bluetooth_pb_vcard_append_org_v21(GString *string,
                                                contacts_record_h contact)
 {
+       FN_START;
        guint count = 0;
 
        gint status;
@@ -1023,16 +1358,19 @@ static void __bluetooth_pb_vcard_append_org_v21(GString *string,
                        g_free(escaped);
                }
 
-               __bluetooth_pb_vcard_append_qp_encode_v21(string, "ORG", NULL, str->str);
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "ORG", NULL,
+                                                               str->str);
 
                g_string_free(str, TRUE);
 
        }
+       FN_END;
 }
 
 static void __bluetooth_pb_vcard_append_note_v21(GString *string,
                                                contacts_record_h contact)
 {
+       FN_START;
        guint count = 0;
 
        gint status;
@@ -1065,15 +1403,18 @@ static void __bluetooth_pb_vcard_append_note_v21(GString *string,
                        continue;
 
                escaped = __bluetooth_pb_vcard_escape(tmp);
-               __bluetooth_pb_vcard_append_qp_encode_v21(string, "NOTE", NULL, escaped);
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "NOTE", NULL,
+                                                               escaped);
 
                g_free(escaped);
        }
+       FN_END;
 }
 
 static void __bluetooth_pb_vcard_append_rev_v21(GString *string,
                                                contacts_record_h contact)
 {
+       FN_START;
        gint time = 0;
        gint status;
 
@@ -1090,20 +1431,23 @@ static void __bluetooth_pb_vcard_append_rev_v21(GString *string,
        if (time <= 0)
                return;
 
-       gmtime_r((const time_t*)(&time), &result);
+       gmtime_r((const time_t *)(&time), &result);
 
        rev = g_strdup_printf("%04d-%02d-%02dT%02d:%02d:%02dZ",
-                       (1900 + result.tm_year), (1 + result.tm_mon), result.tm_mday,
-                       result.tm_hour, result.tm_min, result.tm_sec);
+                       (1900 + result.tm_year), (1 + result.tm_mon),
+                       result.tm_mday, result.tm_hour, result.tm_min,
+                       result.tm_sec);
 
        __bluetooth_pb_vcard_append_qp_encode_v21(string, "REV", NULL, rev);
 
        g_free(rev);
+       FN_END;
 }
 
 static void __bluetooth_pb_vcard_append_url_v21(GString *string,
                                                contacts_record_h contact)
 {
+       FN_START;
        guint count = 0;
 
        gint i;
@@ -1139,15 +1483,18 @@ static void __bluetooth_pb_vcard_append_url_v21(GString *string,
                        continue;
 
                escaped = __bluetooth_pb_vcard_escape(tmp);
-               __bluetooth_pb_vcard_append_qp_encode_v21(string, "URL", NULL, escaped);
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "URL", NULL,
+                                                               escaped);
 
                g_free(escaped);
        }
+       FN_END;
 }
 
 static void __bluetooth_pb_vcard_append_uid_v21(GString *string,
                                                contacts_record_h contact)
 {
+       FN_START;
        int status;
 
        gchar *uid = NULL;
@@ -1164,6 +1511,7 @@ static void __bluetooth_pb_vcard_append_uid_v21(GString *string,
        __bluetooth_pb_vcard_append_qp_encode_v21(string, "UID", NULL, escaped);
 
        g_free(escaped);
+       FN_END;
 }
 
 static void __bluetooth_pb_vcard_append_v30(GString *string,
@@ -1171,6 +1519,7 @@ static void __bluetooth_pb_vcard_append_v30(GString *string,
                                        const gchar *param,
                                        const gchar *value)
 {
+       FN_START;
        if (string == NULL)
                return;
        if (name == NULL)
@@ -1187,22 +1536,24 @@ static void __bluetooth_pb_vcard_append_v30(GString *string,
                g_string_append(string, value);
 
        g_string_append(string, "\r\n");
+       FN_END;
 }
 
 static void __bluetooth_pb_vcard_remove_v30(GString *string,
                                        const gchar *property_name)
 {
+       FN_START;
        gchar *pos = NULL;
        gchar *st_pos = NULL;
 
        gboolean matched = FALSE;
 
-       if(string == NULL || property_name == NULL)
+       if (string == NULL || property_name == NULL)
                return;
 
        pos = string->str;
 
-       while(*pos != '\0') {
+       while (*pos != '\0') {
                if (matched == FALSE) {
                        if (g_ascii_strncasecmp(pos, "\r\n", 2) == 0) {
                                gint attrlen = 0;
@@ -1211,7 +1562,8 @@ static void __bluetooth_pb_vcard_remove_v30(GString *string,
                                pos += 2;
 
                                attrlen = strlen(property_name);
-                               if (g_ascii_strncasecmp(pos, property_name, attrlen) == 0) {
+                               if (g_ascii_strncasecmp(pos, property_name,
+                                                               attrlen) == 0) {
                                        pos += attrlen;
 
                                        if (*pos == ':' || *pos == ';') {
@@ -1221,14 +1573,16 @@ static void __bluetooth_pb_vcard_remove_v30(GString *string,
                                }
                                continue;
                        }
-               }
-               else {
+               } else {
                        if (g_ascii_strncasecmp(pos, "\r\n", 2) == 0) {
                                pos += 2;
 
                                if (*pos != ' ' && *pos != '\t') {
                                        /* +2 means move over \r\n */
-                                       g_string_erase(string, (st_pos+2)-(string->str), pos-(st_pos +2));
+                                       g_string_erase(string,
+                                               (st_pos+2)-(string->str),
+                                               pos-(st_pos+2));
+
                                        pos = st_pos;
                                        matched = FALSE;
                                }
@@ -1238,11 +1592,13 @@ static void __bluetooth_pb_vcard_remove_v30(GString *string,
 
                pos++;
        }
+       FN_END;
 }
 
 static gchar *__bluetooth_pb_vcard_filter_v30(const gchar *vcard,
                                        guint64 filter)
 {
+       FN_START;
        GString *string = NULL;
 
        if (vcard == NULL)
@@ -1256,36 +1612,37 @@ static gchar *__bluetooth_pb_vcard_filter_v30(const gchar *vcard,
        if ((filter & VCARD_BDAY) == 0)
                __bluetooth_pb_vcard_remove_v30(string, "BDAY");
 
-       if ((filter & VCARD_ADR) == 0 )
+       if ((filter & VCARD_ADR) == 0)
                __bluetooth_pb_vcard_remove_v30(string, "ADR");
 
-       if ((filter & VCARD_EMAIL) == 0 )
+       if ((filter & VCARD_EMAIL) == 0)
                __bluetooth_pb_vcard_remove_v30(string, "EMAIL");
 
-       if ((filter & VCARD_TITLE) == 0 )
+       if ((filter & VCARD_TITLE) == 0)
                __bluetooth_pb_vcard_remove_v30(string, "TITLE");
 
-       if ((filter & VCARD_ROLE) == 0 )
+       if ((filter & VCARD_ROLE) == 0)
                __bluetooth_pb_vcard_remove_v30(string, "ROLE");
 
-       if ((filter & VCARD_ORG) == 0 )
+       if ((filter & VCARD_ORG) == 0)
                __bluetooth_pb_vcard_remove_v30(string, "ORG");
 
-       if ((filter & VCARD_NOTE) == 0 )
+       if ((filter & VCARD_NOTE) == 0)
                __bluetooth_pb_vcard_remove_v30(string, "NOTE");
 
-       if ((filter & VCARD_REV) == 0 )
+       if ((filter & VCARD_REV) == 0)
                __bluetooth_pb_vcard_remove_v30(string, "REV");
 
-       if ((filter & VCARD_URL) == 0 )
+       if ((filter & VCARD_URL) == 0)
                __bluetooth_pb_vcard_remove_v30(string, "URL");
 
-       if ((filter & VCARD_UID) == 0 )
+       if ((filter & VCARD_UID) == 0)
                __bluetooth_pb_vcard_remove_v30(string, "UID");
 
-       if ((filter & VCARD_NICKNAME) == 0 )
+       if ((filter & VCARD_NICKNAME) == 0)
                __bluetooth_pb_vcard_remove_v30(string, "NICKNAME");
 
+       FN_END;
        return g_string_free(string, FALSE);
 }
 
@@ -1295,6 +1652,7 @@ static gchar *__bluetooth_pb_vcard_real_contact_valist_v21(gint person_id,
                                                        const gchar *first_name,
                                                        va_list args)
 {
+       FN_START;
        contacts_record_h person = NULL;
        contacts_record_h contact = NULL;
 
@@ -1333,6 +1691,8 @@ static gchar *__bluetooth_pb_vcard_real_contact_valist_v21(gint person_id,
        if (f == 0)
                f = ~f;
 
+       DBG("filter[%x]\n", filter);
+
        str = g_string_new("BEGIN:VCARD\r\nVERSION:2.1\r\n");
 
        /* N, TEL is default */
@@ -1342,7 +1702,8 @@ static gchar *__bluetooth_pb_vcard_real_contact_valist_v21(gint person_id,
                gchar *number;
 
                number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
-               __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "X-0", number);
+               __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "X-0",
+                                                                       number);
                g_free(number);
 
 
@@ -1352,6 +1713,9 @@ static gchar *__bluetooth_pb_vcard_real_contact_valist_v21(gint person_id,
 
        if (f & VCARD_FN)
                __bluetooth_pb_vcard_append_fn_v21(str, person);
+/*     Need to check filter
+       if (f & VCARD_SOUND)*/
+               __bluetooth_pb_vcard_append_phonetic_first_v21(str, contact);
        if (f & VCARD_PHOTO)
                __bluetooth_pb_vcard_append_photo_v21(str, person);
        if (f & VCARD_BDAY)
@@ -1383,7 +1747,8 @@ static gchar *__bluetooth_pb_vcard_real_contact_valist_v21(gint person_id,
                        gchar *escaped = NULL;
 
                        escaped = __bluetooth_pb_vcard_escape(value);
-                       __bluetooth_pb_vcard_append_qp_encode_v21(str, name, param, escaped);
+                       __bluetooth_pb_vcard_append_qp_encode_v21(str, name,
+                                                               param, escaped);
 
                        g_free(escaped);
                }
@@ -1396,6 +1761,7 @@ static gchar *__bluetooth_pb_vcard_real_contact_valist_v21(gint person_id,
        contacts_record_destroy(contact, TRUE);
        contacts_record_destroy(person, TRUE);
 
+       FN_END;
        return g_string_free(str, FALSE);
 }
 
@@ -1406,6 +1772,7 @@ static gchar *__bluetooth_pb_vcard_real_contact_valist_v30(gint person_id,
                                                        const gchar *first_name,
                                                        va_list args)
 {
+       FN_START;
        contacts_record_h person = NULL;
 
        GString *str = NULL;
@@ -1432,7 +1799,8 @@ static gchar *__bluetooth_pb_vcard_real_contact_valist_v30(gint person_id,
        if (status != CONTACTS_ERROR_NONE)
                return NULL;
 
-       str = g_string_new(vcard);
+       /* removing the END:VCARD\r\n" to append extra data */
+       str = g_string_new_len(vcard, (strlen(vcard)-11));
        g_free(vcard);
 
        /* append contents on vcard */
@@ -1445,8 +1813,8 @@ static gchar *__bluetooth_pb_vcard_real_contact_valist_v30(gint person_id,
                name = va_arg(args, const gchar *);
        }
 
-       /* if phonelog_id exist,
-          we shall show only the phone number, which was used for that phone log */
+       /* if phonelog_id exist, we shall show only the phone number, which was
+          used for that phone log */
        if (phonelog_id > 0) {
                gchar *number;
 
@@ -1457,6 +1825,8 @@ static gchar *__bluetooth_pb_vcard_real_contact_valist_v30(gint person_id,
                g_free(number);
        }
 
+       g_string_append(str, "END:VCARD\r\n");
+
        vcard = g_string_free(str, FALSE);
 
        /* temporary fixed for some application crash */
@@ -1474,24 +1844,26 @@ static gchar *__bluetooth_pb_vcard_real_contact_valist_v30(gint person_id,
                }
        }
 
+       FN_END;
        return vcard;
 }
 
 
 static gchar *__bluetooth_pb_vcard_real_contact_with_properties(gint person_id,
-                                                               gint phonelog_id,
-                                                               guint64 filter,
-                                                               guint8 format,
-                                                               const gchar *first_name,
-                                                               ...)
+                                                       gint phonelog_id,
+                                                       guint64 filter,
+                                                       guint8 format,
+                                                       const gchar *first_name,
+                                                       ...)
 {
-       DBG("\n");
+       FN_START;
+       DBG(" format [%d]\n", format);
        gchar *vcard = NULL;
        va_list args;
 
        va_start(args, first_name);
 
-       switch(format) {
+       switch (format) {
        case VCARD_FORMAT_3_0:
                vcard = __bluetooth_pb_vcard_real_contact_valist_v30(person_id,
                                phonelog_id, filter,
@@ -1507,6 +1879,7 @@ static gchar *__bluetooth_pb_vcard_real_contact_with_properties(gint person_id,
 
        va_end(args);
 
+       FN_END;
        return vcard;
 }
 
@@ -1514,6 +1887,7 @@ static gchar *__bluetooth_pb_vcard_real_call_v21(gint phonelog_id,
                                                guint filter,
                                                const char *attr)
 {
+       FN_START;
        GString *str;
        gchar *number;
 
@@ -1530,13 +1904,15 @@ static gchar *__bluetooth_pb_vcard_real_call_v21(gint phonelog_id,
                gchar *datetime = NULL;
 
                datetime = __bluetooth_pb_phonelog_datetime(phonelog_id);
-               __bluetooth_pb_vcard_append_qp_encode_v21(str, "X-IRMC-CALL-DATETIME",
-                               attr, datetime);
+               __bluetooth_pb_vcard_append_qp_encode_v21(str,
+                                                       "X-IRMC-CALL-DATETIME",
+                                                       attr, datetime);
                g_free(datetime);
        }
 
        g_string_append(str, "END:VCARD\r\n");
 
+       FN_END;
        return g_string_free(str, FALSE);
 }
 
@@ -1544,6 +1920,7 @@ static gchar *__bluetooth_pb_vcard_real_call_v30(gint phonelog_id,
                                                guint filter,
                                                const gchar *attr)
 {
+       FN_START;
        GString *str;
        gchar *number;
 
@@ -1568,6 +1945,7 @@ static gchar *__bluetooth_pb_vcard_real_call_v30(gint phonelog_id,
 
        g_string_append(str, "END:VCARD\r\n");
 
+       FN_END;
        return g_string_free(str, FALSE);
 }
 
@@ -1576,10 +1954,10 @@ static gchar *__bluetooth_pb_vcard_real_call(gint phonelog_id,
                                        guint8 format,
                                        const gchar *attr)
 {
-       DBG("\n");
+       FN_START;
        gchar *vcard = NULL;
 
-       switch(format) {
+       switch (format) {
        case VCARD_FORMAT_3_0:
                vcard = __bluetooth_pb_vcard_real_call_v30(phonelog_id,
                                filter, attr);
@@ -1591,6 +1969,7 @@ static gchar *__bluetooth_pb_vcard_real_call(gint phonelog_id,
                break;
        }
 
+       FN_END;
        return vcard;
 }
 
@@ -1598,6 +1977,7 @@ static gchar **__bluetooth_pb_contact_add_field_str(contacts_record_h record,
                                                int *field,
                                                gint field_size)
 {
+       FN_START;
        gchar **strv;
 
        gint status;
@@ -1639,11 +2019,13 @@ static gchar **__bluetooth_pb_contact_add_field_str(contacts_record_h record,
                        strv[i] = __bluetooth_pb_vcard_escape(tmp);
        }
 
+       FN_END;
        return strv;
 }
 
 static gchar **__bluetooth_pb_contact_tel_param(contacts_record_h number)
 {
+       FN_START;
        gchar **strv = NULL;
 
        const gint TEL_PARAM_LEN = 13;
@@ -1655,14 +2037,14 @@ static gchar **__bluetooth_pb_contact_tel_param(contacts_record_h number)
 
        bool is_default = false;
 
-       strv = g_new0(char *, TEL_PARAM_LEN + 1);       /* tel param max size is 13 */
-
        status = contacts_record_get_bool(number, _contacts_number.is_default,
                        &is_default);
 
        if (status != CONTACTS_ERROR_NONE)
                return NULL;
 
+       strv = g_new0(char *, TEL_PARAM_LEN + 1);/* tel param max size is 13 */
+
        if (is_default) {
                strv[i] = g_strdup("PREF");
                i++;
@@ -1736,17 +2118,19 @@ static gchar **__bluetooth_pb_contact_tel_param(contacts_record_h number)
        }
 
        /* CTS_NUM_TYPE_PCS is not part of vcard2.1 */
+       FN_END;
        return strv;
 }
 
 
 static gchar *__bluetooth_pb_contact_photo_type(const gchar *filename)
 {
+       FN_START;
        gchar *filetype = NULL;
        gchar *ext = NULL;
 
        if (g_file_test(filename, G_FILE_TEST_IS_REGULAR) == FALSE) {
-               ERR("file does not regular:%s\n", filename);
+               ERR_SECURE("file does not regular:%s\n", filename);
                return NULL;
        }
 
@@ -1770,19 +2154,23 @@ static gchar *__bluetooth_pb_contact_photo_type(const gchar *filename)
                filetype = "MET";
        else if (g_ascii_strcasecmp(ext, "dib") == 0)
                filetype = "DIB";
-       else if (g_ascii_strcasecmp(ext, "pict") == 0 || g_ascii_strcasecmp(ext, "pct") == 0 ||
+       else if (g_ascii_strcasecmp(ext, "pict") == 0 ||
+                       g_ascii_strcasecmp(ext, "pct") == 0 ||
                        g_ascii_strcasecmp(ext, "pic") == 0)
                filetype = "PICT";
-       else if (g_ascii_strcasecmp(ext, "tiff") == 0 || g_ascii_strcasecmp(ext, "tif") == 0)
+       else if (g_ascii_strcasecmp(ext, "tiff") == 0 ||
+                       g_ascii_strcasecmp(ext, "tif") == 0)
                filetype = "TIFF";
        else if (g_ascii_strcasecmp(ext, "ps") == 0)
                filetype = "PS";
        else if (g_ascii_strcasecmp(ext, "pdf") == 0)
                filetype = "PDF";
-       else if (g_ascii_strcasecmp(ext, "jpeg") == 0 || g_ascii_strcasecmp(ext, "jpg") == 0 ||
+       else if (g_ascii_strcasecmp(ext, "jpeg") == 0 ||
+                       g_ascii_strcasecmp(ext, "jpg") == 0 ||
                        g_ascii_strcasecmp(ext, "jpe") == 0)
                filetype = "JPEG";
-       else if (g_ascii_strcasecmp(ext, "mpeg") == 0 || g_ascii_strcasecmp(ext, "mpg") == 0)
+       else if (g_ascii_strcasecmp(ext, "mpeg") == 0 ||
+                       g_ascii_strcasecmp(ext, "mpg") == 0)
                filetype = "MPEG";
        else if (g_ascii_strcasecmp(ext, "m2v") == 0)
                filetype = "MPEG2";
@@ -1793,11 +2181,13 @@ static gchar *__bluetooth_pb_contact_photo_type(const gchar *filename)
        else if (g_ascii_strcasecmp(ext, "png") == 0)
                filetype = "PNG";
 
+       FN_END;
        return g_strdup(filetype);
 }
 
 static gchar **__bluetooth_pb_contact_addr(contacts_record_h address)
 {
+       FN_START;
        const gint ADDR_LEN = 7;
 
        gchar **strv = NULL;
@@ -1812,12 +2202,13 @@ static gchar **__bluetooth_pb_contact_addr(contacts_record_h address)
 
        strv = __bluetooth_pb_contact_add_field_str(address,
                        addr, ADDR_LEN);
+       FN_END;
        return strv;
 }
 
 static gchar **__bluetooth_pb_contact_addr_param(contacts_record_h address)
 {
-
+       FN_START;
        contacts_address_type_e type;
 
        gint status;
@@ -1825,8 +2216,6 @@ static gchar **__bluetooth_pb_contact_addr_param(contacts_record_h address)
 
        gchar **strv = NULL;
 
-       strv = g_new0(gchar *, 7);      /* ADDR param max size is 6 */
-
        status = contacts_record_get_int(address,
                        _contacts_address.type,
                        (gint *)&type);
@@ -1834,6 +2223,8 @@ static gchar **__bluetooth_pb_contact_addr_param(contacts_record_h address)
        if (status != CONTACTS_ERROR_NONE)
                return NULL;
 
+       strv = g_new0(gchar *, 7);      /* ADDR param max size is 6 */
+
        if (type & CONTACTS_ADDRESS_TYPE_HOME) {
                strv[i] = g_strdup("HOME");
                i++;
@@ -1858,11 +2249,13 @@ static gchar **__bluetooth_pb_contact_addr_param(contacts_record_h address)
                strv[i] = g_strdup("PARCEL");
                i++;
        }
+       FN_END;
        return strv;
 }
 
 static gchar *__bluetooth_pb_phonelog_datetime(gint phonelog_id)
 {
+       FN_START;
        contacts_record_h phone_log;
 
        char time_str[32] = {0,};
@@ -1896,11 +2289,13 @@ static gchar *__bluetooth_pb_phonelog_datetime(gint phonelog_id)
 
        contacts_record_destroy(phone_log, TRUE);
 
+       FN_END;
        return g_strdup(time_str);
 }
 
 static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact)
 {
+       FN_START;
        contacts_record_h name = NULL;
 
        GString *str = g_string_new(NULL);
@@ -1940,11 +2335,63 @@ static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact)
                g_free(escape);
        }
 
+       FN_END;
+       return g_string_free(str, FALSE);
+}
+
+static gchar *__bluetooth_pb_phonetic_name_from_contact(contacts_record_h contact)
+{
+       FN_START;
+       contacts_record_h name = NULL;
+
+       GString *str = g_string_new(NULL);
+
+       gint status;
+
+       gchar *phonetic_first = NULL;
+       gchar *phonetic_last = NULL;
+       gchar *escape = NULL;
+
+       status = contacts_record_get_child_record_at_p(contact,
+                       _contacts_contact.name, 0, &name);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_record_get_str_p(name, _contacts_name.phonetic_first, &phonetic_first);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       if (phonetic_first == NULL)
+               return NULL;
+
+       status = contacts_record_get_str_p(name, _contacts_name.phonetic_last, &phonetic_last);
+
+       if ((status == CONTACTS_ERROR_NONE) && (phonetic_last != NULL)) {
+               escape = __bluetooth_pb_vcard_escape(phonetic_last);
+               g_string_append(str, escape);
+               g_free(escape);
+               g_string_append_c(str, ' ');
+       }
+
+       escape = __bluetooth_pb_vcard_escape(phonetic_first);
+       g_string_append(str, escape);
+
+       g_free(escape);
+       g_string_append_c(str, ';');
+       g_string_append_c(str, ';');
+       g_string_append_c(str, ';');
+       g_string_append_c(str, ';');
+
+       FN_END;
        return g_string_free(str, FALSE);
 }
 
+
 static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact)
 {
+       FN_START;
        guint count = 0;
 
        gint status;
@@ -2017,11 +2464,13 @@ static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact)
                str = g_strdup(tmp);
        }
 
+       FN_END;
        return str;
 }
 
 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;
@@ -2065,79 +2514,118 @@ static gint __bluetooth_pb_person_id_from_phonelog_id(gint phonelog_id)
                        CONTACTS_MATCH_EQUAL,
                        phonelog_id);
 
-       if (status != CONTACTS_ERROR_NONE) {
-               contacts_filter_destroy(filter);
-               return 0;
-       }
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
 
        status = contacts_query_create(_contacts_person_phone_log._uri, &query);
 
-       if (status != CONTACTS_ERROR_NONE) {
-               contacts_filter_destroy(filter);
-               return 0;
-       }
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
 
        status = contacts_query_set_filter(query, filter);
 
-       if (status != CONTACTS_ERROR_NONE) {
-               contacts_filter_destroy(filter);
-               contacts_query_destroy(query);
-               return 0;
-       }
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
 
-       status = contacts_db_get_records_with_query(query, -1, -1, &record_list);
+       status = contacts_db_get_records_with_query(query, -1, -1,
+                                                               &record_list);
 
-       if (status != CONTACTS_ERROR_NONE) {
-               contacts_filter_destroy(filter);
-               contacts_query_destroy(query);
-
-               return 0;
-       }
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
 
        status = contacts_list_first(record_list);
 
-       if (status != CONTACTS_ERROR_NONE) {
-               contacts_list_destroy(record_list, TRUE);
-               contacts_filter_destroy(filter);
-               contacts_query_destroy(query);
-
-               return 0;
-       }
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
 
        status = contacts_list_get_current_record_p(record_list, &record);
 
-       if (status != CONTACTS_ERROR_NONE) {
-               contacts_list_destroy(record_list, TRUE);
-               contacts_filter_destroy(filter);
-               contacts_query_destroy(query);
-
-               return 0;
-       }
+       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) {
-               contacts_list_destroy(record_list, TRUE);
-               contacts_filter_destroy(filter);
-               contacts_query_destroy(query);
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
 
-               return 0;
-       }
+done:
+       if (record_list != NULL)
+               contacts_list_destroy(record_list, TRUE);
 
-       contacts_list_destroy(record_list, TRUE);
        contacts_filter_destroy(filter);
-       contacts_query_destroy(query);
 
+       if (query != NULL)
+               contacts_query_destroy(query);
+
+       FN_END;
        return person_id;
 }
 
+int _bluetooth_get_contact_addressbook(gint person_id)
+{
+       contacts_record_h person = NULL;
+       contacts_record_h contact = NULL;
+       contacts_record_h addressbook = NULL;
+
+       char* addressbook_name = NULL;
+       gint contact_id = 0;
+       gint address_book_id = 0;
+       gint status;
+
+       status = contacts_db_get_record(_contacts_person._uri,
+                       person_id,
+                       &person);
+       if (status != CONTACTS_ERROR_NONE)
+               return PBAP_ADDRESSBOOK_PHONE; /* Default*/
+
+       status = contacts_record_get_int(person,
+                       _contacts_person.display_contact_id,
+                       &contact_id);
+       contacts_record_destroy(person, TRUE);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return PBAP_ADDRESSBOOK_PHONE; /* Default*/
+
+       status = contacts_db_get_record(_contacts_contact._uri,
+                       contact_id,
+                       &contact);
+       if (status != CONTACTS_ERROR_NONE)
+               return PBAP_ADDRESSBOOK_PHONE; /* Default*/
+
+       status = contacts_record_get_int(contact,
+                       _contacts_contact.address_book_id,
+                       &address_book_id);
+       contacts_record_destroy(contact, TRUE);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return PBAP_ADDRESSBOOK_PHONE; /* Default*/
+
+       status = contacts_db_get_record(_contacts_address_book._uri,
+                       address_book_id,
+                       &addressbook);
+       if (status != CONTACTS_ERROR_NONE)
+               return PBAP_ADDRESSBOOK_PHONE; /* Default*/
+
+       status = contacts_record_get_str_p(addressbook, _contacts_address_book.name,
+                                               &addressbook_name);
+       contacts_record_destroy(addressbook, TRUE);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return PBAP_ADDRESSBOOK_PHONE; /* Default*/
+
+       if (address_book_id == 0 || _bt_is_sim_addressbook(addressbook_name) == false)
+               return PBAP_ADDRESSBOOK_PHONE;
+
+       return PBAP_ADDRESSBOOK_SIM;
+}
 /* API for vcard */
 gchar *_bluetooth_pb_vcard_contact(gint person_id,
                                guint64 filter,
                                guint8 format)
 {
+       FN_START;
        gchar *str = NULL;
 
        if (person_id <= 0)
@@ -2146,6 +2634,7 @@ gchar *_bluetooth_pb_vcard_contact(gint person_id,
        str = __bluetooth_pb_vcard_real_contact_with_properties(person_id, 0,
                        filter, format,
                        NULL);
+       FN_END;
        return str;
 }
 
@@ -2153,6 +2642,7 @@ gchar *_bluetooth_pb_vcard_contact_owner(const gchar *number,
                                        guint64 filter,
                                        guint8 format)
 {
+       FN_START;
        GString *str = g_string_new("BEGIN:VCARD\r\n");
        gchar *fn;
        gchar *name;
@@ -2166,18 +2656,21 @@ gchar *_bluetooth_pb_vcard_contact_owner(const gchar *number,
 
                __bluetooth_pb_vcard_append_v30(str, "N", NULL, name);
                __bluetooth_pb_vcard_append_v30(str, "FN", NULL, fn);
-               __bluetooth_pb_vcard_append_v30(str, "TEL", "TYPE=CELL", number);
+               __bluetooth_pb_vcard_append_v30(str, "TEL", "TYPE=CELL",
+                                                                       number);
                break;
        case VCARD_FORMAT_2_1:
-       default :
+       default:
                g_string_append(str, "VERSION:2.1\r\n");
 
                __bluetooth_pb_vcard_append_qp_encode_v21(str, "N", NULL, name);
 
                if (filter == 0 || (filter & VCARD_FN))
-                       __bluetooth_pb_vcard_append_qp_encode_v21(str, "FN", NULL, fn);
+                       __bluetooth_pb_vcard_append_qp_encode_v21(str, "FN",
+                                                               NULL, fn);
 
-               __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "CELL", number);
+               __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "CELL",
+                                                                       number);
                break;
 
        }
@@ -2187,6 +2680,7 @@ gchar *_bluetooth_pb_vcard_contact_owner(const gchar *number,
        g_free(fn);
        g_free(name);
 
+       FN_END;
        return g_string_free(str, FALSE);
 }
 
@@ -2195,12 +2689,13 @@ gchar *_bluetooth_pb_vcard_call(gint phonelog_id,
                                guint8 format,
                                const gchar *attr)
 {
+       FN_START;
        gint person_id = 0;
 
        gchar *str = NULL;
 
        if (attr == NULL) {
-               DBG("Unknown attribute type ignored\n");
+               ERR("Unknown attribute type ignored\n");
                return NULL;
        }
 
@@ -2212,32 +2707,36 @@ gchar *_bluetooth_pb_vcard_call(gint phonelog_id,
                if (filter == 0 || (filter & VCARD_X_IRMC_CALL_DATETIME)) {
                        gchar *datetime = NULL;
 
-                       datetime = __bluetooth_pb_phonelog_datetime(phonelog_id);
+                       datetime = __bluetooth_pb_phonelog_datetime(
+                                                               phonelog_id);
 
-                       str = __bluetooth_pb_vcard_real_contact_with_properties(person_id,
+                       str = __bluetooth_pb_vcard_real_contact_with_properties(
+                                       person_id,
                                        phonelog_id,
                                        filter, format,
                                        "X-IRMC-CALL-DATETIME", attr, datetime,
                                        NULL);
 
-                       if(datetime)
+                       if (datetime)
                                g_free(datetime);
-               }
-               else {
-                       str = __bluetooth_pb_vcard_real_contact_with_properties(person_id,
+               } else {
+                       str = __bluetooth_pb_vcard_real_contact_with_properties(
+                                       person_id,
                                        phonelog_id,
                                        filter, format,
                                        NULL);
                }
-       }
-       else
-               str = __bluetooth_pb_vcard_real_call(phonelog_id, filter, format, attr);
+       } else
+               str = __bluetooth_pb_vcard_real_call(phonelog_id, filter,
+                                                               format, attr);
 
+       FN_END;
        return str;
 }
 
 gchar *_bluetooth_pb_fn_from_person_id(gint person_id)
 {
+       FN_START;
        contacts_record_h person = NULL;
 
        gint status;
@@ -2260,11 +2759,13 @@ gchar *_bluetooth_pb_fn_from_person_id(gint person_id)
 
        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;
 
@@ -2289,7 +2790,7 @@ gchar *_bluetooth_pb_name_from_person_id(gint person_id)
                return NULL;
        }
 
-       contacts_db_get_record(_contacts_contact._uri,
+       status = contacts_db_get_record(_contacts_contact._uri,
                        contact_id,
                        &contact);
 
@@ -2303,11 +2804,13 @@ gchar *_bluetooth_pb_name_from_person_id(gint person_id)
        contacts_record_destroy(contact, TRUE);
        contacts_record_destroy(person, TRUE);
 
+       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;
 
@@ -2347,11 +2850,13 @@ gchar *_bluetooth_pb_number_from_person_id(gint person_id)
        contacts_record_destroy(contact, TRUE);
        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;
 
@@ -2360,13 +2865,15 @@ gchar *_bluetooth_pb_fn_from_phonelog_id(gint phonelog_id)
        if (person_id > 0)
                str = _bluetooth_pb_fn_from_person_id(person_id);
        else
-               str = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
+               str = g_strdup("");
 
+       FN_END;
        return str;
 }
 
 gchar *_bluetooth_pb_name_from_phonelog_id(gint phonelog_id)
 {
+       FN_START;
        gint person_id = 0;
        gchar *str = NULL;
 
@@ -2383,11 +2890,13 @@ gchar *_bluetooth_pb_name_from_phonelog_id(gint phonelog_id)
                g_free(tmp);
        }
 
+       FN_END;
        return str;
 }
 
 gchar *_bluetooth_pb_number_from_phonelog_id(gint phonelog_id)
 {
+       FN_START;
        contacts_record_h phone_log;
 
        gint status;
@@ -2401,7 +2910,7 @@ gchar *_bluetooth_pb_number_from_phonelog_id(gint phonelog_id)
        if (status != CONTACTS_ERROR_NONE)
                return NULL;
 
-       contacts_record_get_str_p(phone_log,
+       status = contacts_record_get_str_p(phone_log,
                        _contacts_phone_log.address,
                        &tmp);
 
@@ -2414,11 +2923,13 @@ gchar *_bluetooth_pb_number_from_phonelog_id(gint phonelog_id)
 
        contacts_record_destroy(phone_log, TRUE);
 
+       FN_END;
        return str;
 }
 
 gchar *_bluetooth_pb_owner_name(void)
 {
+       FN_START;
        gchar *name;
 
        name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
@@ -2426,5 +2937,11 @@ gchar *_bluetooth_pb_owner_name(void)
        if (name == NULL)
                name = g_strdup("My Name");
 
+       FN_END;
        return name;
 }
+
+bool _bt_is_sim_addressbook(const char *addressbook)
+{
+       return g_str_has_prefix(addressbook, SIM_ADDRESSBOOK_PREFIX);
+}
index 24d9675..38edd84 100644 (file)
@@ -1,13 +1,17 @@
 /*
- * bluetooth-agent
+ * Bluetooth-agent
  *
- * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
+ *              Girishashok Joshi <girish.joshi@samsung.com>
+ *              Chanyeol Park <chanyeol.park@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
+ *             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,
 
 #include <glib.h>
 
+#define SIM_ADDRESSBOOK_PREFIX "http://tizen.samsung.com/addressbook/sim"
+
+typedef enum {
+       PBAP_ADDRESSBOOK_PHONE,
+       PBAP_ADDRESSBOOK_SIM,
+} bt_pbap_addressbook_e;
+
 /* vcard */
 gchar *_bluetooth_pb_vcard_contact(gint person_id,
                                guint64 filter,
@@ -50,4 +61,6 @@ gchar *_bluetooth_pb_number_from_phonelog_id(gint phonelog_id);
 
 gchar *_bluetooth_pb_owner_name(void);
 
+bool _bt_is_sim_addressbook(const char *addressbook);
+
 #endif
index c4426a3..e890341 100644 (file)
@@ -1,4 +1,3 @@
 [D-BUS Service]
 Name=org.bluez.pb_agent
 Exec=/usr/bin/bluetooth-pb-agent
-User=root