revise installing a license file
[platform/core/telephony/tel-plugin-imc.git] / src / imc_call.c
index 2777b8d..3b4b909 100644 (file)
@@ -1,7 +1,9 @@
 /*
  * tel-plugin-imc
  *
- * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: sharanayya mathapati <sharan.m@samsung.com>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * limitations under the License.
  */
 
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-
 #include <glib.h>
 
 #include <tcore.h>
-#include <server.h>
-#include <plugin.h>
-#include <core_object.h>
 #include <hal.h>
+#include <core_object.h>
+#include <plugin.h>
 #include <queue.h>
 #include <storage.h>
+#include <co_call.h>
+#include <user_request.h>
+#include <server.h>
 #include <at.h>
 #include <vconf.h>
-#include <co_call.h>
 
-#include "imc_call.h"
 #include "imc_common.h"
+#include "imc_call.h"
+
 
-#define COMMA  0X2c
 #define STATUS_INCOMING    4
 #define STATUS_WAITING     5
 #define STATUS_CONNECTED   7
-
-#define find_call_object(co, call_id, call_obj) \
-       do { \
-               call_obj = tcore_call_object_find_by_id(co, call_id); \
-               if (!call_obj) { \
-                       err("unable to find call object"); \
-                       return; \
-               } \
-       } while (0)
-
-struct imc_set_volume_info {
-       guint next_index;
-       guint volume;
+#define COMMA              0X2c
+#define MAX_CALL_DTMF_DIGITS_LEN 32
+
+static gboolean setsoundpath = FALSE;
+static gboolean soundvolume = FALSE;
+
+/* End Cause field  - Call state end cause */
+
+typedef enum {
+       CALL_END_NO_CAUSE,
+
+       /* These definitions are taken from GSM 04.08 Table 10.86 */
+
+       CC_CAUSE_UNASSIGNED_NUMBER,
+       CC_CAUSE_NO_ROUTE_TO_DEST,
+       CC_CAUSE_CHANNEL_UNACCEPTABLE,
+       CC_CAUSE_OPERATOR_DETERMINED_BARRING,
+       CC_CAUSE_NORMAL_CALL_CLEARING,
+       CC_CAUSE_USER_BUSY,
+       CC_CAUSE_NO_USER_RESPONDING,
+       CC_CAUSE_USER_ALERTING_NO_ANSWER,
+       CC_CAUSE_CALL_REJECTED,
+       CC_CAUSE_NUMBER_CHANGED,
+       CC_CAUSE_NON_SELECTED_USER_CLEARING,
+       CC_CAUSE_DESTINATION_OUT_OF_ORDER,
+       CC_CAUSE_INVALID_NUMBER_FORMAT,
+       CC_CAUSE_FACILITY_REJECTED,
+       CC_CAUSE_RESPONSE_TO_STATUS_ENQUIRY,
+       CC_CAUSE_NORMAL_UNSPECIFIED,
+       CC_CAUSE_NO_CIRCUIT_CHANNEL_AVAILABLE,
+       CC_CAUSE_NETWORK_OUT_OF_ORDER,
+       CC_CAUSE_TEMPORARY_FAILURE,
+       CC_CAUSE_SWITCHING_EQUIPMENT_CONGESTION,
+       CC_CAUSE_ACCESS_INFORMATION_DISCARDED,
+       CC_CAUSE_REQUESTED_CIRCUIT_CHANNEL_NOT_AVAILABLE,
+       CC_CAUSE_RESOURCES_UNAVAILABLE_UNSPECIFIED,
+       CC_CAUSE_QUALITY_OF_SERVICE_UNAVAILABLE,
+       CC_CAUSE_REQUESTED_FACILITY_NOT_SUBSCRIBED,
+       CC_CAUSE_INCOMING_CALL_BARRED_WITHIN_CUG,
+       CC_CAUSE_BEARER_CAPABILITY_NOT_AUTHORISED,
+       CC_CAUSE_BEARER_CAPABILITY_NOT_PRESENTLY_AVAILABLE,
+       CC_CAUSE_SERVICE_OR_OPTION_NOT_AVAILABLE,
+       CC_CAUSE_BEARER_SERVICE_NOT_IMPLEMENTED,
+       CC_CAUSE_ACM_GEQ_ACMMAX,
+       CC_CAUSE_REQUESTED_FACILITY_NOT_IMPLEMENTED,
+       CC_CAUSE_ONLY_RESTRICTED_DIGITAL_INFO_BC_AVAILABLE,
+       CC_CAUSE_SERVICE_OR_OPTION_NOT_IMPLEMENTED,
+       CC_CAUSE_INVALID_TRANSACTION_ID_VALUE,
+       CC_CAUSE_USER_NOT_MEMBER_OF_CUG,
+       CC_CAUSE_INCOMPATIBLE_DESTINATION,
+       CC_CAUSE_INVALID_TRANSIT_NETWORK_SELECTION,
+       CC_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE,
+       CC_CAUSE_INVALID_MANDATORY_INFORMATION,
+       CC_CAUSE_MESSAGE_TYPE_NON_EXISTENT,
+       CC_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROT_STATE,
+       CC_CAUSE_IE_NON_EXISTENT_OR_NOT_IMPLEMENTED,
+       CC_CAUSE_CONDITIONAL_IE_ERROR,
+       CC_CAUSE_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE,
+       CC_CAUSE_RECOVERY_ON_TIMER_EXPIRY,
+       CC_CAUSE_PROTOCOL_ERROR_UNSPECIFIED,
+       CC_CAUSE_INTERWORKING_UNSPECIFIED,
+       CC_CAUSE_END = 128,
+
+       /* Reject causes */
+       REJECT_CAUSE_IMSI_UNKNOWN_IN_HLR,
+       REJECT_CAUSE_ILLEGAL_MS,
+       REJECT_CAUSE_IMSI_UNKNOWN_IN_VLR,
+       REJECT_CAUSE_IMEI_NOT_ACCEPTED,
+       REJECT_CAUSE_ILLEGAL_ME,
+       REJECT_CAUSE_GPRS_SERVICES_NOT_ALLOWED,
+       REJECT_CAUSE_GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED,
+       REJECT_CAUSE_MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK,
+       REJECT_CAUSE_IMPLICITLY_DETACHED,
+       REJECT_CAUSE_PLMN_NOT_ALLOWED,
+       REJECT_CAUSE_LA_NOT_ALLOWED,
+       REJECT_CAUSE_NATIONAL_ROAMING_NOT_ALLOWED,
+       REJECT_CAUSE_GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN,
+       REJECT_CAUSE_NO_SUITABLE_CELLS_IN_LA,
+       REJECT_CAUSE_MSC_TEMPORARILY_NOT_REACHABLE,
+       REJECT_CAUSE_NETWORK_FAILURE,
+       REJECT_CAUSE_MAC_FAILURE,
+       REJECT_CAUSE_SYNCH_FAILURE,
+       REJECT_CAUSE_CONGESTTION,
+       REJECT_CAUSE_GSM_AUTH_UNACCEPTED,
+       REJECT_CAUSE_SERVICE_OPTION_NOT_SUPPORTED,
+       REJECT_CAUSE_REQ_SERV_OPT_NOT_SUBSCRIBED,
+       REJECT_CAUSE_SERVICE_OPT__OUT_OF_ORDER,
+       REJECT_CAUSE_CALL_CANNOT_BE_IDENTIFIED,
+       REJECT_CAUSE_NO_PDP_CONTEXT_ACTIVATED,
+       REJECT_CAUSE_RETRY_UPON_ENTRY_INTO_A_NEW_CELL_MIN_VALUE,
+       REJECT_CAUSE_RETRY_UPON_ENTRY_INTO_A_NEW_CELL_MAX_VALUE,
+       REJECT_CAUSE_SEMANTICALLY_INCORRECT_MSG,
+       REJECT_CAUSE_INVALID_MANDATORY_INFO,
+       REJECT_CAUSE_MESSAGE_TYPE_NON_EXISTANT,
+       REJECT_CAUSE_MESSAGE_TYPE_NOT_COMP_PRT_ST,
+       REJECT_CAUSE_IE_NON_EXISTANT,
+       REJECT_CAUSE_MSG_NOT_COMPATIBLE_PROTOCOL_STATE,
+
+
+       /* Connection Management establishment rejection cause */
+       REJECT_CAUSE_REJ_UNSPECIFIED,
+
+       /* AS reject causes */
+       REJECT_CAUSE_AS_REJ_RR_REL_IND,
+       REJECT_CAUSE_AS_REJ_RR_RANDOM_ACCESS_FAILURE,
+       REJECT_CAUSE_AS_REJ_RRC_REL_IND,
+       REJECT_CAUSE_AS_REJ_RRC_CLOSE_SESSION_IND,
+       REJECT_CAUSE_AS_REJ_RRC_OPEN_SESSION_FAILURE,
+       REJECT_CAUSE_AS_REJ_LOW_LEVEL_FAIL,
+       REJECT_CAUSE_AS_REJ_LOW_LEVEL_FAIL_REDIAL_NOT_ALLOWED,
+       REJECT_CAUSE_AS_REJ_LOW_LEVEL_IMMED_RETRY,
+
+       /* MM reject causes */
+       REJECT_CAUSE_MM_REJ_INVALID_SIM,
+       REJECT_CAUSE_MM_REJ_NO_SERVICE,
+       REJECT_CAUSE_MM_REJ_TIMER_T3230_EXP,
+       REJECT_CAUSE_MM_REJ_NO_CELL_AVAILABLE,
+       REJECT_CAUSE_MM_REJ_WRONG_STATE,
+       REJECT_CAUSE_MM_REJ_ACCESS_CLASS_BLOCKED,
+       /* Definitions for release ind causes between MM  and CNM */
+       REJECT_CAUSE_ABORT_MSG_RECEIVED,
+       REJECT_CAUSE_OTHER_CAUSE,
+
+       /* CNM reject causes */
+       REJECT_CAUSE_CNM_REJ_TIMER_T303_EXP,
+       REJECT_CAUSE_CNM_REJ_NO_RESOURCES,
+       REJECT_CAUSE_CNM_MM_REL_PENDING,
+       REJECT_CAUSE_CNM_INVALID_USER_DATA,
+       CALL_END_CAUSE_MAX = 255
+} call_end_cause_e_type;
+
+
+struct clcc_call_t {
+       struct call_CLCC_info {
+               int id;
+               enum tcore_call_direction direction;
+               enum tcore_call_status status;
+               enum tcore_call_type type;
+               int mpty;
+               int num_len;
+               int num_type;
+       }
+       info;
+       char number[90];
 };
 
-static gchar *xdrv_set_volume[] = {
-       "AT+XDRV=40,7,3,88",
-       "AT+XDRV=40,7,0,88",
-       "AT+XDRV=40,8,0,88",
-       "AT+XDRV=40,8,2,",
-       NULL
+typedef struct {
+       int network_cause;
+       int tapi_cause;
+} call_end_cause_info;
+
+/**************************************************************************
+  *                                                    Local Function Prototypes
+  **************************************************************************/
+/*************************             REQUESTS                ***************************/
+static void _call_status_idle(TcorePlugin *p, CallObject *co);
+static void _call_status_active(TcorePlugin *p, CallObject *co);
+static void _call_status_dialing(TcorePlugin *p, CallObject *co);
+static void _call_status_alert(TcorePlugin *p, CallObject *co);
+static void _call_status_incoming(TcorePlugin *p, CallObject *co);
+static void _call_status_waiting(TcorePlugin *p, CallObject *co);
+static TReturn _call_list_get(CoreObject *o, gboolean *event_flag);
+/* Todo Need to check whether this api is required */
+
+/*************************             CONFIRMATION            ***************************/
+static void on_confirmation_call_message_send(TcorePending *p, gboolean result, void *user_data);     /* from Kernel */
+static void on_confirmation_call_hold(TcorePending *p, int data_len, const void *data, void *user_data);
+static void on_confirmation_call_swap(TcorePending *p, int data_len, const void *data, void *user_data);
+static void on_confirmation_call_split(TcorePending *p, int data_len, const void *data, void *user_data);
+static void on_confirmation_call_hold_and_accept(TcorePending *p, int data_len, const void *data, void *user_data);
+
+static void _on_confirmation_call_release(TcorePending *p, int data_len, const void *data, void *user_data, int type);
+static void _on_confirmation_call(TcorePending *p, int data_len, const void *data, void *user_data, int type);
+static void _on_confirmation_call_end_cause(TcorePending *p, int data_len, const void *data, void *user_data);
+
+/*************************             RESPONSES               ***************************/
+static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data);
+
+/*************************             NOTIIFICATIONS          ***************************/
+static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data);
+static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data);
+static void on_notification_call_status(CoreObject *o, const void *data, void *user_data);
+static gboolean on_notification_call_info(CoreObject *o, const void *data, void *user_data);
+static gboolean on_notification_call_clip_info(CoreObject *o, const void *data, void *user_data);
+
+
+/**************************************************************************
+  *                                                    Local Utility Function Prototypes
+  **************************************************************************/
+static gboolean _call_request_message(TcorePending *pending, CoreObject *o, UserRequest *ur, void *on_resp, void *user_data);
+static void _call_branch_by_status(TcorePlugin *p, CallObject *co, unsigned int status);
+static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call);
+
+/**************************************************************************
+  *                                                    Local Function Definitions
+  **************************************************************************/
+
+const call_end_cause_info call_end_cause_table[] =   /* call end cause table to convert Netwotk cause to TAPI cause */
+{
+       { 1, CC_CAUSE_UNASSIGNED_NUMBER}, { 3, CC_CAUSE_NO_ROUTE_TO_DEST},
+       { 6, CC_CAUSE_CHANNEL_UNACCEPTABLE}, { 8, CC_CAUSE_OPERATOR_DETERMINED_BARRING},
+       { 16, CC_CAUSE_NORMAL_CALL_CLEARING}, { 17, CC_CAUSE_USER_BUSY},
+       { 18, CC_CAUSE_NO_USER_RESPONDING}, { 19, CC_CAUSE_USER_ALERTING_NO_ANSWER},
+       { 21, CC_CAUSE_CALL_REJECTED}, { 22, CC_CAUSE_NUMBER_CHANGED},
+       { 26, CC_CAUSE_NON_SELECTED_USER_CLEARING}, { 27, CC_CAUSE_DESTINATION_OUT_OF_ORDER},
+       { 28, CC_CAUSE_INVALID_NUMBER_FORMAT}, { 29, CC_CAUSE_FACILITY_REJECTED},
+       { 30, CC_CAUSE_RESPONSE_TO_STATUS_ENQUIRY}, { 31, CC_CAUSE_NORMAL_UNSPECIFIED},
+       { 34, CC_CAUSE_NO_CIRCUIT_CHANNEL_AVAILABLE}, { 38, CC_CAUSE_NETWORK_OUT_OF_ORDER},
+       { 41, CC_CAUSE_TEMPORARY_FAILURE}, { 42, CC_CAUSE_SWITCHING_EQUIPMENT_CONGESTION},
+       { 43, CC_CAUSE_ACCESS_INFORMATION_DISCARDED}, { 44, CC_CAUSE_REQUESTED_CIRCUIT_CHANNEL_NOT_AVAILABLE},
+       { 47, CC_CAUSE_RESOURCES_UNAVAILABLE_UNSPECIFIED}, { 49, CC_CAUSE_QUALITY_OF_SERVICE_UNAVAILABLE},
+       { 50, CC_CAUSE_REQUESTED_FACILITY_NOT_SUBSCRIBED}, { 55, CC_CAUSE_INCOMING_CALL_BARRED_WITHIN_CUG},
+       { 57, CC_CAUSE_BEARER_CAPABILITY_NOT_AUTHORISED}, { 58, CC_CAUSE_BEARER_CAPABILITY_NOT_PRESENTLY_AVAILABLE},
+       { 63, CC_CAUSE_SERVICE_OR_OPTION_NOT_AVAILABLE}, { 65, CC_CAUSE_BEARER_SERVICE_NOT_IMPLEMENTED},
+       { 68, CC_CAUSE_ACM_GEQ_ACMMAX}, { 69, CC_CAUSE_REQUESTED_FACILITY_NOT_IMPLEMENTED},
+       { 70, CC_CAUSE_ONLY_RESTRICTED_DIGITAL_INFO_BC_AVAILABLE}, { 79, CC_CAUSE_SERVICE_OR_OPTION_NOT_IMPLEMENTED},
+       { 81, CC_CAUSE_INVALID_TRANSACTION_ID_VALUE}, { 87, CC_CAUSE_USER_NOT_MEMBER_OF_CUG},
+       { 88, CC_CAUSE_INCOMPATIBLE_DESTINATION}, { 91, CC_CAUSE_INVALID_TRANSIT_NETWORK_SELECTION},
+       { 95, CC_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE}, { 96, CC_CAUSE_INVALID_MANDATORY_INFORMATION},
+       { 97, CC_CAUSE_MESSAGE_TYPE_NON_EXISTENT}, { 98, CC_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROT_STATE},
+       { 99, CC_CAUSE_IE_NON_EXISTENT_OR_NOT_IMPLEMENTED}, { 100, CC_CAUSE_CONDITIONAL_IE_ERROR},
+       { 101, CC_CAUSE_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE}, { 102, CC_CAUSE_RECOVERY_ON_TIMER_EXPIRY},
+       { 111, CC_CAUSE_PROTOCOL_ERROR_UNSPECIFIED}, {127, CC_CAUSE_INTERWORKING_UNSPECIFIED},
 };
 
-/*Forward Declarations*/
-static void on_response_imc_call_default(TcorePending *p,
-       guint data_len, const void *data, void *user_data);
-
-static TelReturn __call_list_get(CoreObject *co, gboolean flag);
-
-
-static TelCallType __call_type(int type)
+static enum tcore_call_status _call_status(unsigned int status)
 {
        dbg("Entry");
 
-       switch (type) {
+       switch (status) {
        case 0:
-               return TEL_CALL_TYPE_VOICE;
+               return TCORE_CALL_STATUS_ACTIVE;
 
        case 1:
-               return TEL_CALL_TYPE_VIDEO;
+               return TCORE_CALL_STATUS_HELD;
+
+       case 2:
+               return TCORE_CALL_STATUS_DIALING;
 
+       case 3:
+               return TCORE_CALL_STATUS_ALERT;
+
+       case 4:
+               return TCORE_CALL_STATUS_INCOMING;
+
+       case 5:
+               return TCORE_CALL_STATUS_WAITING;
+
+       case 6:         /* DISCONNECTED state  - FALL THROUGH */
        default:
-               err("invalid call type, returing default call type as voice");
-               return TEL_CALL_TYPE_VOICE;
+               return TCORE_CALL_STATUS_IDLE;
        }
 }
 
-static TelCallState __call_state(int state)
+static gboolean _call_is_in_mpty(int mpty)
 {
        dbg("Entry");
 
-       switch (state) {
+       switch (mpty) {
        case 0:
-               return TEL_CALL_STATE_ACTIVE;
+               return FALSE;
 
        case 1:
-               return TEL_CALL_STATE_HELD;
+               return TRUE;
 
-       case 2:
-               return TEL_CALL_STATE_DIALING;
+       default:
+               break;
+       }
 
-       case 3:
-               return TEL_CALL_STATE_ALERT;
+       return FALSE;
+}
 
-       case 4:
-       case 5:
-               return TEL_CALL_STATE_INCOMING;
+static enum tcore_call_type call_type(int type)
+{
+       dbg("Entry");
+
+       switch (type) {
+       case 0:
+               return TCORE_CALL_TYPE_VOICE;
+
+       case 1:
+               return TCORE_CALL_TYPE_VIDEO;
 
        default:
-               return TEL_CALL_STATE_IDLE;
+               break;
        }
+
+       return TCORE_CALL_TYPE_VOICE;
 }
 
-static void __call_branch_by_status(CoreObject *co, CallObject *call_obj, TelCallState call_state)
+static int _compare_call_end_cause(int networkcause)
 {
-       unsigned int call_id;
-       TelCallType call_type;
-       TelCallState state;
-       TcoreNotification command = TCORE_NOTIFICATION_UNKNOWN;
-       dbg("Call State[%d]", call_state);
-
-       if (tcore_call_object_get_state(call_obj, &state) == FALSE) {
-               err("unable to get call status");
-               return;
-       }
+       unsigned int count;
 
-       if (call_state == state) {
-               dbg("current call state and existing call state are same");
-               return;
+       for (count = 0; count < sizeof(call_end_cause_table) / sizeof(call_end_cause_info); count++) {
+               if (call_end_cause_table[count].network_cause == networkcause)
+                       return (call_end_cause_table[count].tapi_cause);
        }
+       return CC_CAUSE_NORMAL_CALL_CLEARING;
+       dbg("Exit");
+}
 
-       if (tcore_call_object_get_call_type(call_obj, &call_type) == FALSE) {
-               err("unable to get call type");
-               return;
-       }
+static gboolean on_notification_call_clip_info(CoreObject *o, const void *data, void *user_data)
+{
+       dbg("Entry");
 
-       if (tcore_call_object_get_id(call_obj, &call_id) == FALSE) {
-               err("unable to get call id");
-               return;
-       }
+       /* TODO */
 
-       /* Set Status */
-       tcore_call_object_set_state(call_obj, call_state);
+       return TRUE;
+}
 
-       if (call_type == TEL_CALL_TYPE_VOICE) {
-               /* voice call notification */
-               switch (call_state) {
-               case TEL_CALL_STATE_ACTIVE:
-                       command = TCORE_NOTIFICATION_CALL_STATUS_ACTIVE;
-               break;
+static gboolean on_notification_call_info(CoreObject *o, const void *data, void *user_data)
+{
+       GSList *tokens = NULL;
+       GSList *lines = NULL;
+       const char *line = NULL;
+       char *stat;
+       int status;
 
-               case TEL_CALL_STATE_HELD:
-                       command = TCORE_NOTIFICATION_CALL_STATUS_HELD;
-               break;
+       dbg("Entry");
 
-               case TEL_CALL_STATE_DIALING:
-                       command = TCORE_NOTIFICATION_CALL_STATUS_DIALING;
-               break;
+       lines = (GSList *) data;
+       if (1 != g_slist_length(lines)) {
+               err("Unsolicited message, BUT multiple lines present");
+               goto OUT;
+       }
 
-               case TEL_CALL_STATE_ALERT:
-                       command = TCORE_NOTIFICATION_CALL_STATUS_ALERT;
-               break;
+       line = (char *) (lines->data);
+       tokens = tcore_at_tok_new(line);
 
-               case TEL_CALL_STATE_INCOMING:
-               case TEL_CALL_STATE_WAITING: {
-                       TelCallIncomingInfo incoming = {0,};
-                       command = TCORE_NOTIFICATION_CALL_STATUS_INCOMING;
-                       incoming.call_id = call_id;
-                       tcore_call_object_get_cli_validity(call_obj, &incoming.cli_validity);
-                       tcore_call_object_get_number(call_obj, incoming.number);
-                       tcore_call_object_get_cni_validity(call_obj, &incoming.cni_validity);
-                       tcore_call_object_get_name(call_obj, incoming.name);
-                       tcore_call_object_get_mt_forward(call_obj, &incoming.forward);
-                       tcore_call_object_get_active_line(call_obj, &incoming.active_line);
-
-                       /* Send notification */
-                       tcore_object_send_notification(co, command, sizeof(TelCallIncomingInfo), &incoming);
-                       return;
-               }
+       stat = g_slist_nth_data(tokens, 1);
+       if (!stat) {
+               dbg("Stat is missing from %XCALLSTAT indiaction");
+       } else {
+               status = atoi(stat);
 
-               case TEL_CALL_STATE_IDLE: {
-                       TelCallStatusIdleNoti idle;
-                       command = TCORE_NOTIFICATION_CALL_STATUS_IDLE;
-                       idle.call_id = call_id;
+               switch (status) {
+               case STATUS_INCOMING:
+                       dbg("calling on_notification_call_incoming");
+                       on_notification_call_incoming(o, line, user_data);
+                       break;
 
-                       /* TODO - get proper call end cause. */
-                       idle.cause = TEL_CALL_END_CAUSE_NONE;
+               case STATUS_WAITING:
+                       dbg("calling on_notification_call_waiting");
+                       on_notification_call_waiting(o, line, user_data);
+                       break;
 
-                       /* Send notification */
-                       tcore_object_send_notification(co, command,
-                               sizeof(TelCallStatusIdleNoti), &idle);
+               case STATUS_CONNECTED:     /*igonre Connected state. */
+                       dbg("Connected state");
+                       break;
 
-                       /* Free Call object */
-                       tcore_call_object_free(co, call_obj);
-                       return;
-               }
+               default:
+                       dbg("calling on_notification_call_status");
+                       on_notification_call_status(o, line, user_data);
+                       break;
                }
-
        }
-       else if (call_type == TEL_CALL_TYPE_VIDEO) {
-               /* video call notification */
-               switch (call_state) {
-               case TEL_CALL_STATE_ACTIVE:
-                       command = TCORE_NOTIFICATION_VIDEO_CALL_STATUS_ACTIVE;
-               break;
 
-               case TEL_CALL_STATE_HELD:
-                       err("invalid state");
-               break;
+       /* Free tokens */
+       tcore_at_tok_free(tokens);
 
-               case TEL_CALL_STATE_DIALING:
-                       command = TCORE_NOTIFICATION_VIDEO_CALL_STATUS_DIALING;
-               break;
+OUT:
+       dbg("Exit");
+       return TRUE;
+}
 
-               case TEL_CALL_STATE_ALERT:
-                       command = TCORE_NOTIFICATION_VIDEO_CALL_STATUS_ALERT;
-               break;
+static gboolean _call_request_message(TcorePending *pending,
+                                                                         CoreObject *o,
+                                                                         UserRequest *ur,
+                                                                         void *on_resp,
+                                                                         void *user_data)
+{
+       TcoreHal *hal = NULL;
+       TReturn ret;
 
-               case TEL_CALL_STATE_INCOMING:
-               case TEL_CALL_STATE_WAITING:
-                       command = TCORE_NOTIFICATION_VIDEO_CALL_STATUS_INCOMING;
-               break;
+       dbg("Entry");
 
-               case TEL_CALL_STATE_IDLE: {
-                       TelCallStatusIdleNoti idle;
-                       command = TCORE_NOTIFICATION_VIDEO_CALL_STATUS_IDLE;
-                       idle.call_id = call_id;
+       tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
 
-                       /* TODO - get proper call end cause. */
-                       idle.cause = TEL_CALL_END_CAUSE_NONE;
+       if (on_resp)
+               tcore_pending_set_response_callback(pending, on_resp, user_data);
 
-                       /* Send notification */
-                       tcore_object_send_notification(co, command,
-                               sizeof(TelCallStatusIdleNoti), &idle);
+       tcore_pending_set_send_callback(pending, on_confirmation_call_message_send, NULL);
 
-                       /* Free Call object */
-                       tcore_call_object_free(co, call_obj);
-                       return;
-               }
-               }
-       }
-       else {
-               err("Unknown Call type: [%d]", call_type);
+       if (ur)
+               tcore_pending_link_user_request(pending, ur);
+       else
+               err("User Request is NULL, is this internal request??");
+
+       /* HAL */
+       hal = tcore_object_get_hal(o);
+       /* Send request to HAL */
+       ret = tcore_hal_send_request(hal, pending);
+       if (TCORE_RETURN_SUCCESS != ret) {
+               err("Request send failed");
+               return FALSE;
        }
 
-       if (command != TCORE_NOTIFICATION_UNKNOWN)
-               tcore_object_send_notification(co, command, sizeof(call_id), &call_id);
+       dbg("Exit");
+       return TRUE;
 }
 
-static void __handle_call_list_get(CoreObject *co, gboolean flag, void *data)
+static void _call_status_idle(TcorePlugin *p, CallObject *co)
 {
-       int call_id;
-       int direction;
-       int call_type;
-       int state;
-       int mpty;
-       int ton;
-       GSList *tokens = NULL;
-       char *resp = NULL;
-       char *line;
-       char *num = NULL;
-       int num_type;
-       char number[TEL_CALL_CALLING_NUMBER_LEN_MAX +1] = {0,};
-       GSList *lines = data;
-       CallObject *call_obj = NULL;
-
-        while (lines != NULL) {
-               line = (char *)lines->data;
-               /* point to next node */
-               lines = lines->next;
-               /* free previous tokens*/
-               tcore_at_tok_free(tokens);
-
-               tokens = tcore_at_tok_new(line);
-
-               /* <id1> */
-               resp = g_slist_nth_data(tokens, 0);
-               if (NULL == resp) {
-                       err("Invalid call_id");
-                       continue;
-               }
-               call_id = atoi(resp);
-
-               /* <dir> */
-               resp = g_slist_nth_data(tokens, 1);
-               if (NULL == resp) {
-                       err("Invalid direction");
-                       continue;
-               }
-               direction = (atoi(resp) == 0) ? 1 : 0;
-
-               /* <stat> */
-               resp = g_slist_nth_data(tokens, 2);
-               if (NULL == resp) {
-                       err("Invalid state");
-                       continue;
-               }
-               state = __call_state(atoi(resp));
+       CoreObject *core_obj = NULL;
+       char *cmd_str = NULL;
+       TcorePending *pending = NULL;
+       TcoreATRequest *req = NULL;
+       gboolean ret = FALSE;
+       UserRequest *ur;
 
-               /* <mode> */
-               resp = g_slist_nth_data(tokens, 3);
-               if (NULL == resp) {
-                       err("Invalid call_type");
-                       continue;
+       dbg("Entry");
+       core_obj = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL);
+       dbg("Call Handle [%d], Call Status [%d]", tcore_call_object_get_handle(co), tcore_call_object_get_status(co));
+
+       if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_IDLE) {
+               /* get call end cause. */
+               cmd_str = g_strdup_printf("%s", "AT+XCEER");
+               dbg("Request command string: %s", cmd_str);
+
+               /* Create new Pending request */
+               pending = tcore_pending_new(core_obj, 0);
+
+               /* Create new AT-Command request */
+               req = tcore_at_request_new(cmd_str, "+XCEER", TCORE_AT_SINGLELINE);
+               if (req == NULL) {
+                       tcore_pending_free(pending);
+                       g_free(cmd_str);
+                       return;
                }
-               call_type = __call_type(atoi(resp));
 
-               /* <mpty> */
-               resp = g_slist_nth_data(tokens, 4);
-               if (NULL == resp) {
-                       err("Invalid mpty");
-                       continue;
-               }
-               mpty = atoi(resp);
+               dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
+               /* Free command string */
+               g_free(cmd_str);
 
-               /* <number> */
-               resp = g_slist_nth_data(tokens, 5);
-               if (NULL == resp) {
-                       err("Number is NULL");
-               } else {
-                       // Strike off double quotes
-                       num = tcore_at_tok_extract(resp);
-                       dbg("Number: [%s]", num);
-
-                       /* <type> */
-                       resp = g_slist_nth_data(tokens, 6);
-                       if (!resp) {
-                               err("Invalid num type");
-                       } else {
-                               num_type = atoi(resp);
-                               /* check number is international or national. */
-                               ton = ((num_type) >> 4) & 0x07;
-                               if (ton == 1 && num[0] != '+') {
-                                       /* international number */
-                                       number[0] = '+';
-                                       memcpy(&number[1], num, strlen(num));
-                               } else {
-                                       memcpy(number, num, strlen(num));
-                               }
-                       }
-                       g_free(num);
-               }
+               /* Set request data (AT command) to Pending request */
+               tcore_pending_set_request_data(pending, 0, req);
 
-               dbg("Call ID: [%d] Direction: [%s] Call Type: [%d] Multi-party: [%s] "
-                       "Number: [%s] TON: [%d] State: [%d]",
-                       call_id, (direction ? "Outgoing" : "Incoming"), call_type,
-                       (mpty ? "YES" : "NO"), number, ton, state);
+               ur = tcore_user_request_new(NULL, NULL);
+               /* Send request */
+               ret = _call_request_message(pending, core_obj, ur, _on_confirmation_call_end_cause, co);
 
-               call_obj = tcore_call_object_find_by_id(co, call_id);
-               if (NULL == call_obj) {
-                       call_obj = tcore_call_object_new(co, call_id);
-                       if (NULL == call_obj) {
-                               err("unable to create call object");
-                               continue;
+               if (!ret) {
+                       err("Failed to send AT-Command request");
+                       /* free only UserRequest. */
+                       if (ur) {
+                               tcore_user_request_free(ur);
+                               ur = NULL;
                        }
+                       return;
                }
-
-               /* Set Call parameters */
-               tcore_call_object_set_type(call_obj, call_type);
-               tcore_call_object_set_direction(call_obj, direction);
-               tcore_call_object_set_multiparty_state(call_obj, mpty);
-               tcore_call_object_set_cli_info(call_obj, TEL_CALL_CLI_VALIDITY_VALID, number);
-               tcore_call_object_set_active_line(call_obj, TEL_CALL_ACTIVE_LINE1);
-               if (flag == TRUE)
-                       __call_branch_by_status(co, call_obj, state);
-               else
-                       tcore_call_object_set_state(call_obj, state);
+       } else {
+               err("Call object was not free");
+               tcore_call_object_free(core_obj, co);
        }
+       dbg("Exit");
+       return;
 }
 
-/* internal notification operation */
-static void __on_notification_imc_call_incoming(CoreObject *co, unsigned int call_id,
-       void *user_data)
+static void _call_status_dialing(TcorePlugin *p, CallObject *co)
 {
-       GSList *list = NULL;
-       CallObject *call_obj = NULL;
-       dbg("entry");
+       struct tnoti_call_status_dialing data;
 
-       /* check call with incoming status already exist */
-       list = tcore_call_object_find_by_status(co, TEL_CALL_STATE_INCOMING);
-       if (list != NULL) {
-               err("Incoming call already exist! Skip...");
-               g_slist_free(list);
-               return;
-       }
-       g_slist_free(list);
+       dbg("Entry");
 
-       call_obj = tcore_call_object_find_by_id(co, call_id);
-       if (call_obj != NULL) {
-               err("Call object for Call ID [%d] already exist! Skip...", call_id);
-               return;
-       }
+       if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_DIALING) {
+               data.type = tcore_call_object_get_type(co);
+               dbg("data.type : [%d]", data.type);
 
-       /* Create new Call object */
-       call_obj = tcore_call_object_new(co, (unsigned int)call_id);
-       if (NULL == call_obj) {
-               err("Failed to create Call object");
-               return;
+               data.handle = tcore_call_object_get_handle(co);
+               dbg("data.handle = %d", data.handle);
+
+               /* Set Status */
+               tcore_call_object_set_status(co, TCORE_CALL_STATUS_DIALING);
+
+               /* Send notification to TAPI */
+               tcore_server_send_notification(tcore_plugin_ref_server(p),
+                                                                          tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
+                                                                          TNOTI_CALL_STATUS_DIALING,
+                                                                          sizeof(struct tnoti_call_status_dialing),
+                                                                          (void *) &data);
        }
 
-       /* Make request to get current Call list */
-       __call_list_get(co, TRUE);
+       dbg("Exit");
+       return;
 }
 
-static void __on_notification_imc_call_status(CoreObject *co, unsigned int call_id,
-       unsigned int call_state, void *user_data)
+static void _call_status_alert(TcorePlugin *p, CallObject *co)
 {
-       CallObject *call_obj = NULL;
-       TelCallState state;
+       struct tnoti_call_status_alert data;
 
-       state = __call_state(call_state);
-       dbg("state [%d]", state);
-
-       switch (state) {
-       case TEL_CALL_STATE_ACTIVE: {
-               find_call_object(co, call_id, call_obj);
-               /* Send notification to application */
-               __call_branch_by_status(co, call_obj, state);
-       }
-       break;
+       dbg("Entry");
 
-       case TEL_CALL_STATE_HELD: {
-               find_call_object(co, call_id, call_obj);
-               /* Send notification to application */
-               __call_branch_by_status(co, call_obj, state);
-       }
-       break;
+       /* Alerting has just 1 data 'CALL ID' */
+       if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_ALERT) {
+               data.type = tcore_call_object_get_type(co);
+               dbg("data.type : [%d]", data.type);
 
-       case TEL_CALL_STATE_DIALING: {
-               call_obj = tcore_call_object_find_by_id(co, call_id);
-               if (!call_obj) {
-                       call_obj = tcore_call_object_new(co, call_id);
-                       if (!call_obj) {
-                               err("unable to create call object");
-                               return;
-                       }
-               }
-               /* Make request to get current call list.Update CallObject with <number>
-                * and send notification to application */
-               __call_list_get(co, TRUE);
-       }
-       break;
+               data.handle = tcore_call_object_get_handle(co);
+               dbg("data.handle = %d", data.handle);
 
-       case TEL_CALL_STATE_ALERT: {
-               find_call_object(co, call_id, call_obj);
-               /* Send notification to application */
-               __call_branch_by_status(co, call_obj, TEL_CALL_STATE_ALERT);
-       }
-       break;
+               /* Set Status */
+               tcore_call_object_set_status(co, TCORE_CALL_STATUS_ALERT);
 
-       case TEL_CALL_STATE_IDLE: {
-               find_call_object(co, call_id, call_obj);
-               /* Send notification to application */
-               __call_branch_by_status(co, call_obj, state);
+               /* Send notification to TAPI */
+               tcore_server_send_notification(tcore_plugin_ref_server(p),
+                                                                          tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
+                                                                          TNOTI_CALL_STATUS_ALERT,
+                                                                          sizeof(struct tnoti_call_status_alert),
+                                                                          (void *) &data);
        }
-       break;
 
-       default:
-               err("invalid call status");
-               break;
-       }
+       dbg("Exit");
+       return;
 }
 
-/*internal response operation */
-static void __on_response_imc_call_list_get(TcorePending *p, guint data_len, const void *data,
-       void *user_data)
+static void _call_status_active(TcorePlugin *p, CallObject *co)
 {
-       const TcoreAtResponse *at_resp = data;
-       CoreObject *co = tcore_pending_ref_core_object(p);
-       ImcRespCbData *resp_cb_data = user_data;
-       GSList *lines = NULL;
-       TelCallResult result = TEL_CALL_RESULT_FAILURE; //TODO - CME error mapping required
-       gboolean *flag = IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
-       int count;
-       dbg("entry");
-
-       tcore_check_return_assert(co != NULL);
-       tcore_check_return_assert(resp_cb_data != NULL);
-
-       if (at_resp && at_resp->success) {
-               result = TEL_CALL_RESULT_SUCCESS;
-               if (NULL == at_resp->lines) {
-                       err("invalid response received");
-                       return;
-               }
+       struct tnoti_call_status_active data;
 
-               lines = (GSList *) at_resp->lines;
-               count = g_slist_length(lines);
-               dbg("Total records : %d", g_slist_length(lines));
-               if (0 == count) {
-                       err("Call count is zero");
-                       return;
-               }
+       dbg("Entry");
 
-               dbg("RESPONSE OK");
+       if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_ACTIVE) {
+               data.type = tcore_call_object_get_type(co);
+               dbg("data.type : [%d]", data.type);
 
-               /* parse +CLCC notification parameter */
-               __handle_call_list_get(co, *flag, lines);
+               data.handle = tcore_call_object_get_handle(co);
+               dbg("data.handle = %d", data.handle);
 
-       } else {
-               err("RESPONSE NOK");
+               /* Set Status */
+               tcore_call_object_set_status(co, TCORE_CALL_STATUS_ACTIVE);
+
+               /* Send notification to TAPI */
+               tcore_server_send_notification(tcore_plugin_ref_server(p),
+                                                                          tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
+                                                                          TNOTI_CALL_STATUS_ACTIVE,
+                                                                          sizeof(struct tnoti_call_status_active),
+                                                                          (void *) &data);
        }
+
+       dbg("Exit");
+       return;
 }
 
-/*internal request operation */
-static TelReturn __send_call_request(CoreObject *co, TcoreObjectResponseCallback cb,
-       void *cb_data, gchar *at_cmd, gchar *func_name)
+static void _call_status_held(TcorePlugin *p, CallObject *co)
 {
-       ImcRespCbData *resp_cb_data;
-       TelReturn ret;
+       struct tnoti_call_status_held data;
+
+       dbg("Entry");
 
-       /* Response callback data */
-       resp_cb_data = imc_create_resp_cb_data(cb, cb_data, func_name, strlen(func_name) + 1);
+       if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_HELD) {
+               data.type = tcore_call_object_get_type(co);
+               dbg("data.type : [%d]", data.type);
 
-       /* Send Request to modem */
-       ret = tcore_at_prepare_and_send_request(co,
-               at_cmd, NULL,
-               TCORE_AT_COMMAND_TYPE_NO_RESULT,
-               NULL,
-               on_response_imc_call_default, resp_cb_data,
-               on_send_imc_request, NULL);
-       IMC_CHECK_REQUEST_RET(ret, resp_cb_data, func_name);
+               data.handle = tcore_call_object_get_handle(co);
+               dbg("data.handle = %d", data.handle);
 
-       /* Free resources */
-       g_free(at_cmd);
-       return ret;
+               /* Set Status */
+               tcore_call_object_set_status(co, TCORE_CALL_STATUS_HELD);
+
+               /* Send notification to TAPI */
+               tcore_server_send_notification(tcore_plugin_ref_server(p),
+                                                                          tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
+                                                                          TNOTI_CALL_STATUS_HELD,
+                                                                          sizeof(struct tnoti_call_status_held),
+                                                                          (void *) &data);
+       }
+
+       dbg("Exit");
+       return;
 }
 
- /*
- * Operation -  Get current call list.
- *
- * Request -
- * AT-Command: AT+CLCC
- *
- * Response -
- * Success:
- *[+CLCC: <id1>, <dir>, <stat>, <mode>,<mpty>[,<number>,<type>[,<alpha>[,<priority>]]]
- *[<CR><LF> +CLCC: <id2>,<dir>,<stat>,<mode>,<mpty>[,<number>,<type>[,<alpha>[,<priority>]]][\85]]]
- * OK
- * Failure:
- * +CME ERROR: <error>
- */
-static TelReturn __call_list_get(CoreObject *co, gboolean flag)
+static void _call_status_incoming(TcorePlugin *p, CallObject *co)
 {
-       ImcRespCbData *resp_cb_data;
-       TelReturn ret =TEL_RETURN_FAILURE;
+       struct tnoti_call_status_incoming data;
+
        dbg("Entry");
 
-       if (NULL == co) {
-               err("Core Object is NULL");
-               return ret;
-       }
+       if (tcore_call_object_get_status(co) != TCORE_CALL_STATUS_INCOMING) {
+               tcore_call_object_set_status(co, TCORE_CALL_STATUS_INCOMING);
 
-       /* Response callback data */
-       resp_cb_data = imc_create_resp_cb_data(NULL, NULL, &flag, sizeof(gboolean));
+               data.type = tcore_call_object_get_type(co);
+               dbg("data.type : [%d]", data.type);
 
-       /* Send Request to modem */
-       ret = tcore_at_prepare_and_send_request(co,
-               "AT+CLCC","+CLCC",
-               TCORE_AT_COMMAND_TYPE_MULTILINE,
-               NULL,
-               __on_response_imc_call_list_get, resp_cb_data,
-               on_send_imc_request, NULL);
-       IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get current call list");
+               data.handle = tcore_call_object_get_handle(co);
+               dbg("data.handle = %d", data.handle);
 
-       return ret;
-}
+               data.cli.mode = tcore_call_object_get_cli_mode(co);
+               dbg("data.cli.mode : [%d]", data.cli.mode);
 
-/* Notification */
+               tcore_call_object_get_number(co, data.cli.number);
+               dbg("data.cli.number : [%s]", data.cli.number);
 
-/*
-* Operation -  call status notification from network.
-* notification message format:
-* +XCALLSTAT: <call_id><stat>
-* where
-* <call_id>
-* indicates the call identification (GSM02.30 4.5.5.1)
-* <stat>
-* 0 active
-* 1 hold
-* 2 dialling (MO call)
-* 3 alerting (MO call; ringing for the remote party)
-* 4 ringing (MT call)
-* 5 waiting (MT call)
-* 6 disconnected
-* 7 connected (indicates the completion of a call setup first time for MT and MO calls \96 this is reported in
-addition to state active)
-*/
-static gboolean on_notification_imc_call_status(CoreObject *co, const void *data,
-       void *user_data)
-{
-       GSList *tokens = NULL;
-       GSList *lines = NULL;
-       const char *line = NULL;
-       char *state = NULL, *call_handle = NULL;
-       unsigned int status, call_id;
+               data.cna.mode = tcore_call_object_get_cna_mode(co);
+               dbg("data.cna.mode : [%d]", data.cna.mode);
 
-       dbg("Entry");
+               tcore_call_object_get_name(co, data.cna.name);
+               dbg("data.cna.name : [%s]", data.cna.name);
 
-       lines = (GSList *) data;
-       if (lines == NULL) {
-               err("Invalid response received");
-               return TRUE;
-       }
-       line = (char *) (lines->data);
-       tokens = tcore_at_tok_new(line);
+               data.forward = FALSE; /* this is tmp code */
 
-       call_handle = g_slist_nth_data(tokens, 0);
-       if (NULL == call_handle) {
-               err("call_id missing from %XCALLSTAT indiaction");
-               goto OUT;
-       }
-       call_id = atoi(call_handle);
-       state = g_slist_nth_data(tokens, 1);
-       if (NULL == state) {
-               err("State is missing from %XCALLSTAT indication");
-               goto OUT;
+               data.active_line = tcore_call_object_get_active_line(co);
+               dbg("data.active_line : [%d]", data.active_line);
+
+               /* Send notification to TAPI */
+               tcore_server_send_notification(tcore_plugin_ref_server(p),
+                                                                          tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
+                                                                          TNOTI_CALL_STATUS_INCOMING,
+                                                                          sizeof(struct tnoti_call_status_incoming),
+                                                                          (void *) &data);
        }
-       status = atoi(state);
-       dbg("call_id[%d], status[%d]", call_id, status);
 
+       dbg("Exit");
+       return;
+}
+
+static void _call_status_waiting(TcorePlugin *p, CallObject *co)
+{
+       dbg("Entry");
+       _call_status_incoming(p, co);
+
+       dbg("Exit");
+       return;
+}
+
+static void _call_branch_by_status(TcorePlugin *p, CallObject *co, unsigned int status)
+{
+       dbg("Entry");
+
+       dbg("Call Status is %d", status);
        switch (status) {
-       case STATUS_INCOMING:
-       case STATUS_WAITING:
-               __on_notification_imc_call_incoming(co, call_id, user_data);
+       case TCORE_CALL_STATUS_IDLE:
+               _call_status_idle(p, co);
                break;
 
-       case STATUS_CONNECTED:     /* ignore Connected state. */
-               dbg("ignore connected state");
+       case TCORE_CALL_STATUS_ACTIVE:
+               _call_status_active(p, co);
                break;
 
-       default:
-               __on_notification_imc_call_status(co, call_id, status, user_data);
+       case TCORE_CALL_STATUS_HELD:
+               _call_status_held(p, co);
+               break;
+
+       case TCORE_CALL_STATUS_DIALING:
+               _call_status_dialing(p, co);
+               break;
+
+       case TCORE_CALL_STATUS_ALERT:
+               _call_status_alert(p, co);
+               break;
+
+       case TCORE_CALL_STATUS_INCOMING:
+               _call_status_incoming(p, co);
+               break;
+
+       case TCORE_CALL_STATUS_WAITING:
+               _call_status_waiting(p, co);
                break;
        }
-OUT:
-       // Free tokens
-       tcore_at_tok_free(tokens);
-       return TRUE;
+
+       dbg("Exit");
+       return;
 }
 
-/*
- * Operation -  SS network initiated notification.
- *
- * notification message format:
- * +CSSU: <code2>[<index> [,<number>,<type>]]
- * <code2>
- * (it is manufacturer specific, which of these codes are supported):
- * 0 this is a forwarded call (MT call setup)
- * 1 this is a CUG call (<index> present) (MT call setup)
- * 2 call has been put on hold (during a voice call)
- * 3 call has been retrieved (during a voice call)
- * 4 multiparty call entered (during a voice call)
- * 5 Call has been released - not a SS notification (during a voice call)
- * 6 forward check SS message received (can be received whenever)
- * 7 call is being connected (alerting) with the remote party in alerting state
- *   in explicit call transfer operation
- *   (during a voice call)
- * 8 call has been connected with the other remote party in explicit call transfer
- *   operation (during a voice call or MT call setup)
- * 9 this is a deflected call (MT call setup)
- * 10 additional incoming call forwarded
- * <index>
- * refer Closed user group +CCUG
- * <number>
- *  string type phone of format specified by <type>
- * <type>
- * type of address octet in integer format.
- */
-static gboolean on_notification_imc_call_ss_cssu_info(CoreObject *co, const void *event_data,
-       void *user_data)
+static TReturn _call_list_get(CoreObject *o, gboolean *event_flag)
 {
-       GSList *tokens = NULL;
-       TcoreNotification command = TCORE_NOTIFICATION_UNKNOWN;
-       char *resp = NULL;
-       char *cmd = 0;
-       int index = 0;
-       int code2 = -1;
-       char number[TEL_CALL_CALLING_NUMBER_LEN_MAX + 1] = {'\0',};
+       UserRequest *ur = NULL;
+       TcorePending *pending = NULL;
+       char *cmd_str = NULL;
+       TcoreATRequest *req = NULL;
+       gboolean ret = FALSE;
 
-       dbg("entry");
+       dbg("Entry");
+       if (!o) {
+               err("Core Object is NULL");
+               return TCORE_RETURN_FAILURE;
+       }
 
-       if (1 != g_slist_length((GSList *) event_data)) {
-               err("unsolicited msg but multiple line");
-               return TRUE;
+       /* Create new User Request */
+       ur = tcore_user_request_new(NULL, NULL);
+
+       /* Command string */
+       cmd_str = g_strdup("AT+CLCC");
+
+       /* Create new Pending Request */
+       pending = tcore_pending_new(o, 0);
+       req = tcore_at_request_new(cmd_str, "+CLCC", TCORE_AT_MULTILINE);
+       if (req == NULL) {
+               tcore_pending_free(pending);
+               g_free(cmd_str);
+               if (ur) {
+                       tcore_user_request_free(ur);
+                       ur = NULL;
+               }
+               return TCORE_RETURN_FAILURE;
        }
+       g_free(cmd_str);
 
-       cmd = (char *) ((GSList *) event_data)->data;
-       dbg("ss notification message[%s]", cmd);
+       dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
 
-       tokens = tcore_at_tok_new(cmd);
+       tcore_pending_set_request_data(pending, 0, req);
 
-       /* parse <code2> */
-       resp = g_slist_nth_data(tokens, 0);
-       if (NULL == resp) {
-               err("Code2 is missing from %CSSU indiaction");
-               tcore_at_tok_free(tokens);
-               return TRUE;
+       ret = _call_request_message(pending, o, ur, on_response_call_list_get, event_flag);
+       if (!ret) {
+               err("AT request (%s) sending failed", req->cmd);
+               /* free only UserRequest. */
+               if (ur) {
+                       tcore_user_request_free(ur);
+                       ur = NULL;
+               }
+               return TCORE_RETURN_FAILURE;
        }
 
-       code2 = atoi(resp);
+       dbg("AT request sent success");
+       return TCORE_RETURN_SUCCESS;
+}
 
-       /* parse [ <index>, <number> <type>] */
-       if ((resp = g_slist_nth_data(tokens, 1)))
-               index = atoi(resp);
+/* CONFIRMATION */
+static void on_confirmation_call_message_send(TcorePending *p, gboolean result, void *user_data)
+{
+       dbg("Entry");
 
-       if ((resp = g_slist_nth_data(tokens, 2))) {
-               /* Strike off double quotes */
-               int len = strlen(resp) - 2;
-               memcpy(number, resp + 1, len);
-               number[len] = '\0';;
+       if (result == FALSE) {  /* Fail */
+               dbg("SEND FAIL");
+       } else {
+               dbg("SEND OK");
        }
 
-       dbg("+CSSU: <code2> = %d <index> = %d <number> = %s ", code2, index, number);
+       dbg("Exit");
+       return;
+}
+
+static void call_prepare_and_send_pending_request(CoreObject *co, const char *at_cmd, const char *prefix, enum tcore_at_command_type at_cmd_type, TcorePendingResponseCallback callback)
+{
+       TcoreATRequest *req = NULL;
+       TcoreHal *hal = NULL;
+       TcorePending *pending = NULL;
+       TReturn ret;
+
+       hal = tcore_object_get_hal(co);
+       dbg("hal: %p", hal);
+
+       pending = tcore_pending_new(co, 0);
+       if (!pending)
+               return;
+       req = tcore_at_request_new(at_cmd, prefix, at_cmd_type);
+       if (req == NULL) {
+               tcore_pending_free(pending);
+               return;
+       }
+       dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+       tcore_pending_set_request_data(pending, 0, req);
+       tcore_pending_set_response_callback(pending, callback, NULL);
+       tcore_pending_set_send_callback(pending, on_confirmation_call_message_send, NULL);
+       ret = tcore_hal_send_request(hal, pending);
+       if (ret != TCORE_RETURN_SUCCESS)
+               err("Failed to process request");
+}
+
+static void on_confirmation_call_outgoing(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       UserRequest *ur = NULL;
+       GSList *tokens = NULL;
+       const char *line = NULL;
+       const TcoreATResponse *response = data;
+       struct tresp_call_dial resp;
+       enum telephony_call_error error;
+       dbg("Entry");
+
+       ur = tcore_pending_ref_user_request(p);
+       if (ur) {
+               if (response->success > 0) {
+                       dbg("RESPONSE OK");
+                       resp.err = CALL_ERROR_NONE;
+               } else {
+                       dbg("RESPONSE NOT OK");
+
+                       line = (const char *) response->final_response;
+                       tokens = tcore_at_tok_new(line);
+
+                       if (g_slist_length(tokens) < 1) {
+                               err("Unspecified error cause OR string corrupted");
+                               resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+                       } else {
+                               error = atoi(g_slist_nth_data(tokens, 0));
+                               err("Error: [%d]", error);
+                               /* TODO: CMEE error mapping is required. */
+                               resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+                       }
+
+                       /* Free tokens */
+                       tcore_at_tok_free(tokens);
+               }
+
+               /* Send Response to TAPI */
+               tcore_user_request_send_response(ur, TRESP_CALL_DIAL, sizeof(struct tresp_call_dial), &resp);
+       } else {
+               err("User Request is NULL");
+       }
+
+       dbg("Exit");
+       return;
+}
+
+static void on_confirmation_call_accept(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       UserRequest *ur = NULL;
+       GSList *tokens = NULL;
+       const char *line = NULL;
+       const TcoreATResponse *response = data;
+       struct tresp_call_answer resp;
+       enum telephony_call_error error;
+       dbg("Entry");
+
+       ur = tcore_pending_ref_user_request(p);
+       if (ur) {
+               if (response->success > 0) {
+                       dbg("RESPONSE OK");
+                       resp.err = CALL_ERROR_NONE;
+               } else {
+                       dbg("RESPONSE NOT OK");
+
+                       line = (const char *) response->final_response;
+                       tokens = tcore_at_tok_new(line);
+
+                       if (g_slist_length(tokens) < 1) {
+                               err("Unspecified error cause OR string corrupted");
+                               resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+                       } else {
+                               error = atoi(g_slist_nth_data(tokens, 0));
+                               err("Error: [%d]", error);
+                               /* TODO: CMEE error mapping is required. */
+                               resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+                       }
+
+                       /* Free tokens */
+                       tcore_at_tok_free(tokens);
+               }
+
+               resp.handle = tcore_call_object_get_handle((CallObject *) user_data);
+
+               /* Send Response to TAPI */
+               tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
+       } else {
+               err("User Request is NULL");
+       }
+
+       dbg("Exit");
+       return;
+}
+
+
+static void on_confirmation_call_reject(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       UserRequest *ur = NULL;
+       GSList *tokens = NULL;
+       const char *line = NULL;
+       const TcoreATResponse *response = data;
+       struct tresp_call_answer resp;
+       enum telephony_call_error error;
+
+       dbg("Entry");
+
+       ur = tcore_pending_ref_user_request(p);
+       if (ur) {
+               if (response->success > 0) {
+                       dbg("RESPONSE OK");
+                       resp.err = CALL_ERROR_NONE;
+               } else {
+                       dbg("RESPONSE NOT OK");
+                       line = (const char *) response->final_response;
+                       tokens = tcore_at_tok_new(line);
+
+                       if (g_slist_length(tokens) < 1) {
+                               err("Unspecified error cause OR string corrupted");
+                               resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+                       } else {
+                               error = atoi(g_slist_nth_data(tokens, 0));
+                               err("Error: [%d]", error);
+                               /* TODO: CMEE error mapping is required. */
+                               resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+                       }
+
+                       /* Free tokens */
+                       tcore_at_tok_free(tokens);
+               }
+
+               resp.handle = tcore_call_object_get_handle((CallObject *) user_data);
+
+               /* Send Response to TAPI */
+               tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
+       } else {
+               err("User Request is NULL");
+       }
+
+       dbg("Exit");
+       return;
+}
+
+static void on_confirmation_call_replace(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       UserRequest *ur = NULL;
+       GSList *tokens = NULL;
+       const char *line = NULL;
+       const TcoreATResponse *response = data;
+       struct tresp_call_answer resp;
+       enum telephony_call_error error;
+
+       dbg("Entry");
+       ur = tcore_pending_ref_user_request(p);
+       if (ur) {
+               if (response->success > 0) {
+                       dbg("RESPONSE OK");
+                       resp.err = CALL_ERROR_NONE;
+               } else {
+                       dbg("RESPONSE NOT OK");
+                       line = (const char *) response->final_response;
+                       tokens = tcore_at_tok_new(line);
+
+                       if (g_slist_length(tokens) < 1) {
+                               err("Unspecified error cause OR string corrupted");
+                               resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+                       } else {
+                               error = atoi(g_slist_nth_data(tokens, 0));
+                               err("Error: [%d]", error);
+                               /* TODO: CMEE error mapping is required. */
+                               resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+                       }
+
+                       /* Free tokens */
+                       tcore_at_tok_free(tokens);
+               }
+               resp.handle = tcore_call_object_get_handle((CallObject *) user_data);
+
+               /* Send Response to TAPI */
+               tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
+       } else {
+               dbg("User Request is NULL");
+       }
+
+       dbg("Exit");
+       return;
+}
+
+static void on_confirmation_call_hold_and_accept(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       CoreObject *o = NULL;
+       UserRequest *ur = NULL;
+       GSList *tokens = NULL;
+       const char *line = NULL;
+       const TcoreATResponse *response = data;
+       struct tresp_call_answer resp;
+       enum telephony_call_error error;
+
+       dbg("Entry");
+
+       o = tcore_pending_ref_core_object(p);
+       ur = tcore_pending_ref_user_request(p);
+       resp.handle = tcore_call_object_get_handle((CallObject *) user_data);
+
+       if (ur) {
+               if (response->success > 0) {
+                       dbg("RESPONSE OK");
+                       resp.err = CALL_ERROR_NONE;
+               } else {
+                       err("RESPONSE NOT OK");
+                       line = (const char *) response->final_response;
+                       tokens = tcore_at_tok_new(line);
+
+                       if (g_slist_length(tokens) < 1) {
+                               err("Unspecified error cause OR string corrupted");
+                               resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+                       } else {
+                               error = atoi(g_slist_nth_data(tokens, 0));
+                               err("Error: [%d]", error);
+                               /* TODO: CMEE error mapping is required. */
+                               resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+                       }
+
+                       /* Free tokens */
+                       tcore_at_tok_free(tokens);
+               }
+
+               /* Send response to TAPI */
+               tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
+               if (!resp.err) {
+                       GSList *list = 0;
+                       CallObject *co = NULL;
+
+                       /* Active Call */
+                       list = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_ACTIVE);
+                       if (!list) {
+                               err("Can't find active Call");
+                               return;
+                       }
+
+                       co = (CallObject *) list->data;
+                       if (!co) {
+                               err("Can't get active Call object");
+                               return;
+                       }
+
+                       /* Set Call Status */
+                       tcore_call_object_set_status(co, TCORE_CALL_STATUS_HELD);
+                       dbg("Call status is set to HELD");
+               }
+       } else {
+               err("User Request is NULL");
+       }
+
+       dbg("Exit");
+       return;
+}
+
+static void _on_confirmation_call_release(TcorePending *p, int data_len, const void *data, void *user_data, int type)
+{
+       UserRequest *ur = NULL;
+       struct tresp_call_end resp;
+       GSList *tokens = NULL;
+       const char *line = NULL;
+       enum telephony_call_error error;
+       const TcoreATResponse *response = data;
+
+       dbg("Entry");
+       ur = tcore_pending_ref_user_request(p);
+       if (ur) {
+               if (response->success > 0) {
+                       dbg("RESPONSE OK");
+                       resp.err = CALL_ERROR_NONE;
+               } else {
+                       err("RESPONSE NOT OK");
+
+                       line = (const char *) response->final_response;
+                       tokens = tcore_at_tok_new(line);
+
+                       if (g_slist_length(tokens) < 1) {
+                               err("Unspecified error cause OR string corrupted");
+                               resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+                       } else {
+                               error = atoi(g_slist_nth_data(tokens, 0));
+                               err("Error: [%d]", error);
+                               /* TODO: CMEE error mapping is required. */
+                               resp.err = CALL_ERROR_SERVICE_UNAVAIL;
+                       }
+                       tcore_at_tok_free(tokens);
+               }
+
+               resp.type = type;
+               resp.handle = tcore_call_object_get_handle((CallObject *) user_data);
+               dbg("resp.type = %d  resp.handle= %d", resp.type, resp.handle);
+
+               /* Send reponse to TAPI */
+               tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
+       } else {
+               err("User Request is NULL");
+       }
+
+       dbg("Exit");
+       return;
+}
+
+/* RESPONSE */
+static void on_confirmation_call_endall(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       /* skip response handling - actual result will be handled in on_confirmation_call_release_all */
+       const TcoreATResponse *response = data;
+
+       dbg("Entry");
+
+       if (response->success > 0)
+               dbg("RESPONSE OK");
+       else
+               err("RESPONSE NOT OK");
+
+       dbg("Exit");
+       return;
+}
+
+
+static void on_confirmation_call_release_all(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       dbg("Entry");
+       _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_ALL);
+
+       return;
+}
+
+
+static void on_confirmation_call_release_specific(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       dbg("Entry");
+       _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_DEFAULT);
+
+       return;
+}
+
+static void on_confirmation_call_release_all_active(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       dbg("Entry");
+       _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_ACTIVE_ALL);
+
+       return;
+}
+
+static void on_confirmation_call_release_all_held(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       dbg("Entry");
+       _on_confirmation_call_release(p, data_len, data, user_data, CALL_END_TYPE_HOLD_ALL);
+
+       return;
+}
+
+static void _on_confirmation_call(TcorePending *p, int data_len, const void *data, void *user_data, int type)
+{
+       UserRequest *ur = NULL;
+       GSList *tokens = NULL;
+       const char *line = NULL;
+       const TcoreATResponse *response = NULL;
+       enum telephony_call_error error;
+
+       dbg("Entry");
+       ur = tcore_pending_ref_user_request(p);
+       response = (TcoreATResponse *) data;
+       if (response->success > 0) {
+               dbg("RESPONSE OK");
+               error = CALL_ERROR_NONE;
+       } else {
+               err("RESPONSE NOT OK");
+
+               line = (const char *) response->final_response;
+               tokens = tcore_at_tok_new(line);
+
+               if (g_slist_length(tokens) < 1) {
+                       err("Unspecified error cause OR string corrupted");
+                       error = CALL_ERROR_SERVICE_UNAVAIL;
+               } else {
+                       error = atoi(g_slist_nth_data(tokens, 0));
+
+                       /* TODO: CMEE error mapping is required. */
+                       error = CALL_ERROR_SERVICE_UNAVAIL;
+               }
+
+               /* Free tokens */
+               tcore_at_tok_free(tokens);
+       }
+
+       dbg("Response Call type -%d", type);
+       switch (type) {
+       case TRESP_CALL_HOLD:
+       {
+               struct tresp_call_hold resp;
+
+               resp.err = error;
+               resp.handle = tcore_call_object_get_handle((CallObject *) user_data);
+               dbg("call hold response");
+               /* Send reponse to TAPI */
+               tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
+       }
+       break;
+
+       case TRESP_CALL_ACTIVE:
+       {
+               struct tresp_call_active resp;
+
+               resp.err = error;
+               resp.handle = tcore_call_object_get_handle((CallObject *) user_data);
+               dbg("call active response");
+               /* Send reponse to TAPI */
+               tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
+       }
+       break;
+
+       case TRESP_CALL_JOIN:
+       {
+               struct tresp_call_join resp;
+
+               resp.err = error;
+               resp.handle = tcore_call_object_get_handle((CallObject *) user_data);
+               dbg("call join response");
+
+               /* Send reponse to TAPI */
+               tcore_user_request_send_response(ur, TRESP_CALL_JOIN, sizeof(struct tresp_call_join), &resp);
+       }
+       break;
+
+       case TRESP_CALL_SPLIT:
+       {
+               struct tresp_call_split resp;
+
+               resp.err = error;
+               resp.handle = tcore_call_object_get_handle((CallObject *) user_data);
+               dbg("call split response");
+               /* Send reponse to TAPI */
+               tcore_user_request_send_response(ur, TRESP_CALL_SPLIT, sizeof(struct tresp_call_split), &resp);
+       }
+       break;
+
+       case TRESP_CALL_SWAP:
+       {
+               struct tresp_call_swap resp;
+
+               resp.err = error;
+               resp.handle = tcore_call_object_get_handle((CallObject *) user_data);
+               dbg("call swap response");
+               /* Send reponse to TAPI */
+               tcore_user_request_send_response(ur, TRESP_CALL_SWAP, sizeof(struct tresp_call_swap), &resp);
+       }
+       break;
+
+       case TRESP_CALL_DEFLECT:
+       {
+               struct tresp_call_deflect resp;
+
+               resp.err = error;
+               resp.handle = tcore_call_object_get_handle((CallObject *) user_data);
+               dbg("call deflect response");
+               /* Send reponse to TAPI */
+               tcore_user_request_send_response(ur, TRESP_CALL_DEFLECT, sizeof(struct tresp_call_deflect), &resp);
+       }
+
+       break;
+
+       case TRESP_CALL_TRANSFER:
+       {
+               struct tresp_call_transfer resp;
+
+               resp.err = error;
+               resp.handle = tcore_call_object_get_handle((CallObject *) user_data);
+               dbg("call transfer response");
+               /* Send reponse to TAPI */
+               tcore_user_request_send_response(ur, TRESP_CALL_TRANSFER, sizeof(struct tresp_call_transfer), &resp);
+       }
+       break;
+
+       case TRESP_CALL_START_CONT_DTMF:
+       {
+               struct tresp_call_dtmf resp;
+
+               resp.err = error;
+               dbg("call start cont dtmf response");
+               /* Send reponse to TAPI */
+               tcore_user_request_send_response(ur, TRESP_CALL_START_CONT_DTMF, sizeof(struct tresp_call_dtmf), &resp);
+       }
+       break;
+
+       case TRESP_CALL_STOP_CONT_DTMF:
+       {
+               struct tresp_call_dtmf resp;
+
+               resp.err = error;
+               dbg("call stop cont dtmf response");
+               /* Send reponse to TAPI */
+               tcore_user_request_send_response(ur, TRESP_CALL_START_CONT_DTMF, sizeof(struct tresp_call_dtmf), &resp);
+       }
+       break;
+
+       default:
+       {
+               dbg("type not supported");
+               return;
+       }
+       }
+
+       if ((type == TRESP_CALL_HOLD) || (type == TRESP_CALL_ACTIVE) || (type == TRESP_CALL_JOIN)
+               || (type == TRESP_CALL_SPLIT) || (type == TRESP_CALL_SWAP)) {
+               if (!error) {
+                       CoreObject *core_obj = NULL;
+                       gboolean *eflag = g_new0(gboolean, 1);
+
+                       core_obj = tcore_pending_ref_core_object(p);
+                       *eflag = TRUE;
+
+                       dbg("Calling _call_list_get");
+                       _call_list_get(core_obj, eflag);
+               }
+       }
+
+       dbg("Exit");
+       return;
+}
+
+static void on_confirmation_call_hold(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       dbg("Entry");
+       _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_HOLD);
+
+       return;
+}
+
+static void on_confirmation_call_active(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       dbg("Entry");
+       _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_ACTIVE);
+
+       return;
+}
+
+static void on_confirmation_call_join(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       dbg("Entry");
+       _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_JOIN);
+
+       return;
+}
+
+static void on_confirmation_call_split(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       dbg("Entry");
+       _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_SPLIT);
+
+       return;
+}
+
+static void on_confirmation_call_deflect(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       dbg("Entry");
+       _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_DEFLECT);
+
+       return;
+}
+
+static void on_confirmation_call_transfer(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       dbg("Entry");
+       _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_TRANSFER);
+
+       return;
+}
+
+static void on_confirmation_call_start_cont_dtmf(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       dbg("Entry");
+       _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_START_CONT_DTMF);
+
+       return;
+}
+
+static void on_confirmation_call_stop_cont_dtmf(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       dbg("Entry");
+       _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_STOP_CONT_DTMF);
+
+       return;
+}
+
+#if 0
+static void _on_confirmation_dtmf_tone_duration(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       GSList *tokens = NULL;
+       const char *line = NULL;
+       const TcoreATResponse *response = data;
+       enum telephony_call_error error;
+
+       dbg("Entry");
+
+       if (response->success > 0) {
+               dbg("RESPONSE OK");
+               error = CALL_ERROR_NONE;
+       } else {
+               err("RESPONSE NOT OK");
+               line = (const char *) response->final_response;
+               tokens = tcore_at_tok_new(line);
+               if (g_slist_length(tokens) < 1) {
+                       err("err cause not specified or string corrupted");
+                       error = CALL_ERROR_SERVICE_UNAVAIL;
+               } else {
+                       error = atoi(g_slist_nth_data(tokens, 0));
+                       /* TODO: CMEE error mapping is required. */
+               }
+
+               /* Free tokens */
+               tcore_at_tok_free(tokens);
+       }
+
+       dbg("Set dtmf tone duration response - %d", error);
+       return;
+}
+#endif
+
+static void on_confirmation_call_swap(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       dbg("Entry");
+       _on_confirmation_call(p, data_len, data, user_data, TRESP_CALL_SWAP);
+
+       return;
+}
+
+static void on_confirmation_set_sound_path(TcorePending *p, int data_len,
+                                               const void *data,
+                                               void *user_data)
+{
+       const TcoreATResponse *resp = data;
+       struct tnoti_call_sound_path *snd_path = user_data;
+       struct tresp_call_set_sound_path resp_set_sound_path;
+       UserRequest *ur = tcore_pending_ref_user_request(p);
+       TcorePlugin *plugin = tcore_pending_ref_plugin(p);
+       CoreObject *co_call;
+
+       if (ur == NULL) {
+               err("User Request is NULL");
+               g_free(user_data);
+               return;
+       }
+
+       if (resp->success <= 0) {
+
+               dbg("RESPONSE NOT OK");
+               resp_set_sound_path.err = TRUE;
+
+               goto out;
+       }
+
+       dbg("RESPONSE OK");
+       resp_set_sound_path.err = FALSE;
+
+       co_call = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_CALL);
+
+       /* Notify control plugin about sound path */
+       tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+                                       co_call, TNOTI_CALL_SOUND_PATH,
+                                       sizeof(struct tnoti_call_sound_path),
+                                       snd_path);
+
+out:
+       /* Answer TAPI request */
+       tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH,
+                               sizeof(resp_set_sound_path),
+                               &resp_set_sound_path);
+
+       g_free(user_data);
+}
+
+static void on_confirmation_call_set_source_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       UserRequest *ur = NULL;
+       GSList *tokens = NULL;
+       const char *line = NULL;
+       const TcoreATResponse *response = data;
+       char *resp_str = NULL;
+       struct tresp_call_set_sound_path resp;
+       gboolean error;
+
+       dbg("Entry");
+       ur = tcore_pending_ref_user_request(p);
+
+       /* +XDRV: <group_id>, <function_id>, <xdrv_result>[, <response_n>]\ 3 */
+       if (!response) {
+               err("Input data is NULL");
+               return;
+       }
+
+       if (response->success > 0) {
+               dbg("RESPONSE OK");
+
+               line = (const char *) (((GSList *) response->lines)->data);
+               tokens = tcore_at_tok_new(line);
+
+               resp_str = g_slist_nth_data(tokens, 0);
+               if (!g_slist_nth_data(tokens, 0)) {
+                       err("group_id is missing");
+                       resp.err = TRUE;
+                       goto OUT;
+               }
+
+               if (!g_slist_nth_data(tokens, 1)) {
+                       err(" function_id is missing");
+                       resp.err = TRUE;
+                       goto OUT;
+               }
+
+               resp_str = g_slist_nth_data(tokens, 2);
+
+               if (resp_str) {
+                       error = atoi(resp_str);
+                       if (0 == error) {
+                               dbg("Response is Success");
+                               resp.err = FALSE;
+                       } else {
+                               resp.err = TRUE;
+                       }
+               }
+OUT:
+               /* Free tokens */
+               tcore_at_tok_free(tokens);
+       } else {
+               dbg("RESPONSE NOT OK");
+
+               line = (const char *) response->final_response;
+               tokens = tcore_at_tok_new(line);
+
+               if (g_slist_length(tokens) < 1) {
+                       err("err cause not specified or string corrupted");
+                       resp.err = TRUE;
+               } else {
+                       error = atoi(g_slist_nth_data(tokens, 0));
+
+                       /* TODO: CMEE error mapping is required. */
+                       resp.err = TRUE;
+               }
+
+               /* Free tokens */
+               tcore_at_tok_free(tokens);
+       }
+
+       if (ur) {
+               if (resp.err) {  /* Send only failed notification . success notification send when destination device is set. */
+                       /* Send notification to TAPI */
+                       tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_set_sound_path), &resp);
+                       setsoundpath = TRUE;
+               }
+       } else {
+               err("User Request is NULL");
+       }
+
+       dbg("Exit");
+       return;
+}
+
+static void on_confirmation_call_set_destination_sound_path(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       UserRequest *ur = NULL;
+       GSList *tokens = NULL;
+       const char *line = NULL;
+       char *resp_str = NULL;
+       struct tresp_call_set_sound_path resp;
+       const TcoreATResponse *response = data;
+       gboolean error;
+
+       dbg("Entry");
+
+       ur = tcore_pending_ref_user_request(p);
+       /* +XDRV: <group_id>, <function_id>, <xdrv_result>[, <response_n>] */
+
+       if (!response) {
+               err("Input data is NULL");
+               return;
+       }
+
+       if (ur) {
+               if (response->success > 0) {
+                       dbg("RESPONSE OK");
+
+                       line = (const char *) (((GSList *) response->lines)->data);
+                       tokens = tcore_at_tok_new(line);
+
+                       resp_str = g_slist_nth_data(tokens, 0);
+                       if (!g_slist_nth_data(tokens, 0)) {
+                               dbg("group_id is missing");
+                               resp.err = TRUE;
+                               goto OUT;
+                       }
+
+                       if (!g_slist_nth_data(tokens, 1)) {
+                               dbg("function_id is missing");
+                               resp.err = TRUE;
+                               goto OUT;
+                       }
+
+                       resp_str = g_slist_nth_data(tokens, 2);
+                       if (resp_str) {
+                               error = atoi(resp_str);
+                               if (0 == error) {
+                                       dbg("Response is Success");
+                                       resp.err = FALSE;
+                               } else {
+                                       resp.err = TRUE;
+                               }
+                       }
+
+OUT:
+                       /* Free tokens */
+                       tcore_at_tok_free(tokens);
+               } else {
+                       dbg("RESPONSE NOT OK");
+
+                       line = (const char *) response->final_response;
+                       tokens = tcore_at_tok_new(line);
+
+                       if (g_slist_length(tokens) < 1) {
+                               err("err cause not specified or string corrupted");
+                               resp.err = TRUE;
+                       } else {
+                               error = atoi(g_slist_nth_data(tokens, 0));
+                               /* TODO: CMEE error mapping is required. */
+                               resp.err = TRUE;
+                       }
+
+                       /* Free tokens */
+                       tcore_at_tok_free(tokens);
+               }
+
+               if (setsoundpath == TRUE) {
+                       setsoundpath = FALSE;
+               } else {
+                       /* Send response to TAPI */
+                       tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_PATH, sizeof(struct tresp_call_set_sound_path), &resp);
+               }
+       } else {
+               dbg("User Request is NULL");
+       }
+
+       dbg("Exit");
+       return;
+}
+
+static void on_confirmation_call_set_source_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       UserRequest *ur = NULL;
+       GSList *tokens = NULL;
+       const char *line = NULL;
+       const TcoreATResponse *response = data;
+       char *resp_str = NULL;
+       struct tresp_call_set_sound_volume_level resp;
+       gboolean error;
+
+       ur = tcore_pending_ref_user_request(p);
+       dbg("Entry");
+       /* +XDRV: <group_id>, <function_id>, <xdrv_result>[, <response_n>]\ 3 */
+       if (!response) {
+               err("Input data is NULL");
+               return;
+       }
+
+       if (response->success > 0) {
+               dbg("RESPONSE OK");
+
+               line = (const char *) (((GSList *) response->lines)->data);
+               tokens = tcore_at_tok_new(line);
+
+               resp_str = g_slist_nth_data(tokens, 0);
+               if (!g_slist_nth_data(tokens, 0)) {
+                       err("group_id is missing");
+                       resp.err = TRUE;
+                       goto OUT;
+               }
+
+               if (!g_slist_nth_data(tokens, 1)) {
+                       err("function_id is missing");
+                       resp.err = TRUE;
+                       goto OUT;
+               }
+
+               resp_str = g_slist_nth_data(tokens, 2);
+               if (resp_str) {
+                       error = atoi(resp_str);
+
+                       if (0 == error) {
+                               dbg("Response is Success ");
+                               resp.err = FALSE;
+                       } else {
+                               resp.err = TRUE;
+                       }
+               }
+
+OUT:
+               /* Free tokens */
+               tcore_at_tok_free(tokens);
+       } else {
+               dbg("RESPONSE NOT OK");
+
+               line = (const char *) response->final_response;
+               tokens = tcore_at_tok_new(line);
+
+               if (g_slist_length(tokens) < 1) {
+                       err("err cause not specified or string corrupted");
+                       resp.err = TRUE;
+               } else {
+                       error = atoi(g_slist_nth_data(tokens, 0));
+
+                       /* TODO: CMEE error mapping is required. */
+                       resp.err = TRUE;
+               }
+
+               /* Free tokens */
+               tcore_at_tok_free(tokens);
+       }
+
+       if (ur) {
+               if (resp.err && soundvolume == FALSE) {  /* Send only failed notification . success notification send when destination device is set. */
+                       /* Send reposne to TAPI */
+                       tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_set_sound_volume_level), &resp);
+                       soundvolume = TRUE;
+               }
+       } else {
+               err("User Request is NULL");
+       }
+
+       dbg("Exit");
+       return;
+}
+
+
+static void on_confirmation_call_set_destination_sound_volume_level(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       UserRequest *ur = NULL;
+       GSList *tokens = NULL;
+       const char *line = NULL;
+       char *resp_str = NULL;
+       const TcoreATResponse *response = data;
+       struct tresp_call_set_sound_volume_level resp;
+       gboolean error;
+
+       dbg("Entry");
+
+       ur = tcore_pending_ref_user_request(p);
+
+       /* +XDRV: <group_id>, <function_id>, <xdrv_result>[, <response_n>]\ 3 */
+       if (!response) {
+               err("Input data is NULL");
+               return;
+       }
+
+       if (ur) {
+               if (response->success > 0) {
+                       dbg("RESPONSE OK");
+                       line = (const char *) (((GSList *) response->lines)->data);
+                       tokens = tcore_at_tok_new(line);
+                       resp_str = g_slist_nth_data(tokens, 0);
+
+                       if (!g_slist_nth_data(tokens, 0)) {
+                               err("group_id is missing");
+                               resp.err = TRUE;
+                               goto OUT;
+                       }
+
+                       if (!g_slist_nth_data(tokens, 1)) {
+                               err("function_id is missing");
+                               resp.err = TRUE;
+                               goto OUT;
+                       }
+
+                       resp_str = g_slist_nth_data(tokens, 2);
+
+                       if (resp_str) {
+                               error = atoi(resp_str);
+
+                               if (0 == error) {
+                                       dbg("Response is Success");
+                                       resp.err = FALSE;
+                               } else {
+                                       resp.err = TRUE;
+                               }
+                       }
+
+OUT:
+                       /* Free tokens */
+                       tcore_at_tok_free(tokens);
+               } else {
+                       dbg("RESPONSE NOT OK");
+
+                       line = (const char *) response->final_response;
+                       tokens = tcore_at_tok_new(line);
+
+                       if (g_slist_length(tokens) < 1) {
+                               err("err cause not specified or string corrupted");
+                               resp.err = TRUE;
+                       } else {
+                               error = atoi(g_slist_nth_data(tokens, 0));
+
+                               /* TODO: CMEE error mapping is required. */
+                               resp.err = TRUE;
+                       }
+
+                       tcore_at_tok_free(tokens);
+               }
+
+               if (soundvolume == TRUE) {
+                       soundvolume = FALSE;
+               } else {
+                       /* Send reposne to TAPI */
+                       tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_VOLUME_LEVEL, sizeof(struct tresp_call_set_sound_volume_level), &resp);
+               }
+       } else {
+               err("User Request is NULL");
+       }
+
+       dbg("Exit");
+       return;
+}
+
+
+static void on_confirmation_call_set_sound_mute_status(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       UserRequest *ur = NULL;
+       GSList *tokens = NULL;
+       const char *line = NULL;
+       char *resp_str = NULL;
+       struct tresp_call_set_sound_mute_status resp;
+       const TcoreATResponse *response = data;
+       gboolean error;
+
+       dbg("Entry");
+
+       ur = tcore_pending_ref_user_request(p);
+
+       if (!response) {
+               err("Input data is NULL");
+               return;
+       }
+
+       if (response->success > 0) {
+               dbg("RESPONSE OK");
+
+               line = (const char *) (((GSList *) response->lines)->data);
+               tokens = tcore_at_tok_new(line);
+               resp_str = g_slist_nth_data(tokens, 0);
+
+               if (!g_slist_nth_data(tokens, 0)) {
+                       err("group_id is missing");
+                       resp.err = TRUE;
+                       goto OUT;
+               }
+
+               if (!g_slist_nth_data(tokens, 1)) {
+                       err(" function_id is missing");
+                       resp.err = TRUE;
+                       goto OUT;
+               }
+
+               resp_str = g_slist_nth_data(tokens, 2);
+
+               if (resp_str) {
+                       error = atoi(resp_str);
+                       if (0 == error) {
+                               dbg("Response is Success");
+                               resp.err = FALSE;
+                       } else {
+                               resp.err = TRUE;
+                       }
+               }
+OUT:
+               /* Free tokens */
+               tcore_at_tok_free(tokens);
+       } else {
+               dbg("RESPONSE NOT OK");
+
+               line = (const char *) response->final_response;
+               tokens = tcore_at_tok_new(line);
+
+               if (g_slist_length(tokens) < 1) {
+                       err("err cause not specified or string corrupted");
+                       resp.err = TRUE;
+               } else {
+                       error = atoi(g_slist_nth_data(tokens, 0));
+
+                       /* TODO: CMEE error mapping is required. */
+                       resp.err = TRUE;
+               }
+
+               /* Free tokens */
+               tcore_at_tok_free(tokens);
+       }
+
+       if (ur)
+               tcore_user_request_send_response(ur, TRESP_CALL_SET_SOUND_MUTE_STATUS, sizeof(struct tresp_call_set_sound_mute_status), &resp);
+       else
+               err("User Request is NULL");
+
+       dbg("Exit");
+       return;
+}
+
+/* RESPONSE */
+static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       TcorePlugin *plugin = NULL;
+       CoreObject *core_obj = NULL;
+       CallObject *co = NULL;
+       struct clcc_call_t *call_list = NULL;
+       gboolean *event_flag = (gboolean *) user_data;
+       const TcoreATResponse *response = data;
+       GSList *resp_data = NULL;
+       char *line = NULL;
+
+       int cllc_info = 0, countCalls = 0, countValidCalls = 0;
+       int error = 0;
+
+       dbg("Entry");
+
+       plugin = tcore_pending_ref_plugin(p);
+       core_obj = tcore_pending_ref_core_object(p);
+
+       if (response->success > 0) {
+               dbg("RESPONCE OK");
+               if (response->lines) {
+                       resp_data = (GSList *) response->lines;
+                       countCalls = g_slist_length(resp_data);
+                       dbg("Total records : %d", countCalls);
+               }
+
+               if (0 == countCalls) {
+                       err("Call count is zero");
+                       if (event_flag) {
+                               g_free(event_flag);
+                               event_flag = NULL;
+                       }
+                       return;
+               }
+
+               call_list = g_new0(struct clcc_call_t, countCalls);
+
+               for (countValidCalls = 0; resp_data != NULL; resp_data = resp_data->next, countValidCalls++, cllc_info++) {
+                       line = (char *) (resp_data->data);
+
+                       error = _callFromCLCCLine(line, call_list + countValidCalls);
+                       if (0 != error)
+                               continue;
+
+                       co = tcore_call_object_find_by_id(core_obj, call_list[cllc_info].info.id);
+                       if (!co) {
+                               co = tcore_call_object_new(core_obj);
+                               if (!co) {
+                                       err("[ error ] co is NULL");
+                                       continue;
+                               }
+                       }
+
+                       /* Call set parameters */
+                       tcore_call_object_set_type(co, call_type(call_list[cllc_info].info.type));
+                       tcore_call_object_set_direction(co, call_list[cllc_info].info.direction);
+                       tcore_call_object_set_multiparty_state(co, _call_is_in_mpty(call_list[cllc_info].info.mpty));
+                       tcore_call_object_set_cli_info(co, CALL_CLI_MODE_DEFAULT, 0, call_list[cllc_info].number, strlen(call_list[cllc_info].number));
+                       tcore_call_object_set_active_line(co, 0);
+
+                       if (*event_flag) {
+                               dbg("Call status before calling _call_branch_by_status() : (%d)", call_list[cllc_info].info.status);
+                               _call_branch_by_status(plugin, co, call_list[cllc_info].info.status);
+                       } else {
+                               /* Set Status */
+                               tcore_call_object_set_status(co, call_list[cllc_info].info.status);
+
+                               dbg("Call id : (%d)", call_list[cllc_info].info.id);
+                               dbg("Call direction : (%d)", call_list[cllc_info].info.direction);
+                               dbg("Call type : (%d)", call_list[cllc_info].info.type);
+                               dbg("Call mpty : (%d)", call_list[cllc_info].info.mpty);
+                               dbg("Call number : (%s)", call_list[cllc_info].number);
+                               dbg("Call status : (%d)", call_list[cllc_info].info.status);
+                       }
+               }
+
+               /* Free Call list */
+               g_free(call_list);
+       }
+
+       /* Free User data */
+       if (event_flag) {
+       g_free(event_flag);
+               event_flag = NULL;
+       }
+
+       dbg("Exit");
+       return;
+}
+
+static void _on_confirmation_call_end_cause(TcorePending *p, int data_len, const void *data, void *user_data)
+{
+       TcorePlugin *plugin = NULL;
+       CoreObject *core_obj = NULL;
+       CallObject *co = (CallObject *) user_data;
+       const TcoreATResponse *response = data;
+       const char *line = NULL;
+       struct tnoti_call_status_idle call_status;
+       GSList *tokens = NULL;
+       char *resp_str;
+       int error;
+
+       dbg("Entry");
+       plugin = tcore_pending_ref_plugin(p);
+       core_obj = tcore_pending_ref_core_object(p);
+
+       if (response->success > 0) {
+               dbg("RESPONSE OK");
+               line = (const char *) (((GSList *) response->lines)->data);
+               tokens = tcore_at_tok_new(line);
+               resp_str = g_slist_nth_data(tokens, 0);
+               if (!resp_str) {
+                       err("call end cause - report value missing");
+               } else {
+                       resp_str = g_slist_nth_data(tokens, 1);
+                       if (!resp_str)
+                               err("call end cause value missing");
+
+                       error = atoi(resp_str);
+                       dbg("call end cause - %d", error);
+                       call_status.cause = _compare_call_end_cause(error);
+                       dbg("TAPI call end cause - %d", call_status.cause);
+               }
+
+               /* Free tokens */
+               tcore_at_tok_free(tokens);
+       } else {
+               err("RESPONSE NOT OK");
+               line = (char *) response->final_response;
+               tokens = tcore_at_tok_new(line);
+               if (g_slist_length(tokens) < 1)
+                       err("err cause not specified or string corrupted");
+               else
+                       err(" err cause  value: %d", atoi(g_slist_nth_data(tokens, 0)));
+
+               call_status.cause = CC_CAUSE_NORMAL_CALL_CLEARING;
+               /* Free tokens */
+               tcore_at_tok_free(tokens);
+       }
+
+       call_status.type = tcore_call_object_get_type(co);
+       dbg("data.type : [%d]", call_status.type);
+
+       call_status.handle = tcore_call_object_get_handle(co);
+       dbg("data.handle : [%d]", call_status.handle);
+
+       /* Set Status */
+       tcore_call_object_set_status(co, TCORE_CALL_STATUS_IDLE);
+
+       /* Send Notification to TAPI */
+       tcore_server_send_notification(tcore_plugin_ref_server(plugin),
+                                                                  core_obj,
+                                                                  TNOTI_CALL_STATUS_IDLE,
+                                                                  sizeof(struct tnoti_call_status_idle),
+                                                                  (void *) &call_status);
+
+       /* Free Call object */
+       tcore_call_object_free(core_obj, co);
+}
+
+static int _callFromCLCCLine(char *line, struct clcc_call_t *p_call)
+{
+       /* +CLCC: 1, 0, 2, 0, 0, "18005551212", 145 */
+       /* [+CLCC: <id1>, <dir>, <stat>, <mode>, <mpty>[, <number>, <type>[, <alpha>[, <priority>]]] */
+       int state;
+       int mode;
+       int isMT;
+       char *num = NULL;
+       unsigned int num_type;
+       GSList *tokens = NULL;
+       char *resp = NULL;
+
+       dbg("Entry");
+
+       tokens = tcore_at_tok_new(line);
+       /* parse <id> */
+       resp = g_slist_nth_data(tokens, 0);
+       if (!resp) {
+               err("InValid ID");
+               goto ERROR;
+       }
+       p_call->info.id = atoi(resp);
+       dbg("id : [%d]\n", p_call->info.id);
+
+       /* parse <dir> */
+       resp = g_slist_nth_data(tokens, 1);
+       if (!resp) {
+               err("InValid Dir");
+               goto ERROR;
+       }
+       isMT = atoi(resp);
+       if (0 == isMT)
+               p_call->info.direction = TCORE_CALL_DIRECTION_OUTGOING;
+       else
+               p_call->info.direction = TCORE_CALL_DIRECTION_INCOMING;
+
+       dbg("Direction : [ %d ]\n", p_call->info.direction);
+
+       /* parse <stat> */
+       resp = g_slist_nth_data(tokens, 2);
+       if (!resp) {
+               err("InValid Stat");
+               goto ERROR;
+       }
+       state = atoi(resp);
+       dbg("Call state : %d", state);
+       switch (state) {
+       case 0:     /* active */
+               p_call->info.status = TCORE_CALL_STATUS_ACTIVE;
+       break;
+
+       case 1:
+               p_call->info.status = TCORE_CALL_STATUS_HELD;
+       break;
 
-       /* <code2> - other values will be ignored */
-       switch (code2) {
-       case 0:
-               command = TCORE_NOTIFICATION_CALL_INFO_MT_FORWARDED;
-               break;
        case 2:
-               command = TCORE_NOTIFICATION_CALL_INFO_HELD;
-               break;
+               p_call->info.status = TCORE_CALL_STATUS_DIALING;
+       break;
+
        case 3:
-               command = TCORE_NOTIFICATION_CALL_INFO_ACTIVE;
-               break;
+               p_call->info.status = TCORE_CALL_STATUS_ALERT;
+       break;
+
        case 4:
-               command = TCORE_NOTIFICATION_CALL_INFO_JOINED;
-               break;
-       case 7:
-       case 8:
-               command = TCORE_NOTIFICATION_CALL_INFO_TRANSFERED;
-               break;
-       case 9:
-               command = TCORE_NOTIFICATION_CALL_INFO_MT_DEFLECTED;
-               break;
-       default:
-               dbg("Unsupported +CSSU notification : %d", code2);
-               break;
+               p_call->info.status = TCORE_CALL_STATUS_INCOMING;
+       break;
+
+       case 5:
+               p_call->info.status = TCORE_CALL_STATUS_WAITING;
+       break;
+       }
+       dbg("Status : [%d]\n", p_call->info.status);
+
+       /* parse <mode> */
+       resp = g_slist_nth_data(tokens, 3);
+       if (!resp) {
+               err("InValid Mode");
+               goto ERROR;
+       }
+       mode = atoi(resp);
+       switch (mode) {
+       case 0:
+               p_call->info.type = TCORE_CALL_TYPE_VOICE;
+       break;
+
+       case 1:
+               p_call->info.type = TCORE_CALL_TYPE_VIDEO;
+       break;
+
+       default: /* only Voice/VT call is supported in CS. treat other unknown calls as error */
+               dbg("invalid type : [%d]\n", mode);
+               goto ERROR;
+       }
+       dbg("Call type : [%d]\n", p_call->info.type);
+
+       /* parse <mpty> */
+       resp = g_slist_nth_data(tokens, 4);
+       if (!resp) {
+               err("InValid Mpty");
+               goto ERROR;
+       }
+
+       p_call->info.mpty = atoi(resp);
+       dbg("Mpty : [ %d ]\n", p_call->info.mpty);
+
+       /* parse <num> */
+       resp = g_slist_nth_data(tokens, 5);
+       dbg("Incoming number - %s and its len  - %d", resp, strlen(resp));
+
+       /* tolerate null here */
+       if (!resp) {
+               err("Number is NULL");
+               goto ERROR;
        }
+       /* Strike off double quotes */
+       num = tcore_at_tok_extract(resp);
+       if (num == NULL)
+               err("number after removing quotes is NULL");
+       else
+               dbg("num  after removing quotes - %s", num);
 
-       if (command != TCORE_NOTIFICATION_UNKNOWN)
-               tcore_object_send_notification(co, command, 0, NULL);
+       p_call->info.num_len = strlen(resp);
+       dbg("num_len : [0x%x]\n", p_call->info.num_len);
+
+       /* parse <num type> */
+       resp = g_slist_nth_data(tokens, 6);
+       if (!resp) {
+               dbg("InValid Num type");
+               goto ERROR;
+       }
+       p_call->info.num_type = atoi(resp);
+       dbg("BCD num type: [0x%x]\n", p_call->info.num_type);
+
+       /* check number is international or national. */
+       num_type = ((p_call->info.num_type) >> 4) & 0x07;
+       dbg("called party's type of number : [0x%x]\n", num_type);
+
+       if (num != NULL) {
+               if (num_type == 1 && num[0] != '+') {
+                       /* international number */
+                       p_call->number[0] = '+';
+                       memcpy(&(p_call->number[1]), num, strlen(num));
+               } else {
+                       memcpy(&(p_call->number), num, strlen(num));
+               }
+               dbg("incoming number - %s", p_call->number);
+       }
+       g_free(num);
+       num = NULL;
+       /* Free tokens */
        tcore_at_tok_free(tokens);
 
-       return TRUE;
+       dbg("Exit");
+       return 0;
+
+ERROR:
+       err("Invalid CLCC line");
+
+       g_free(num);
+
+       /* Free tokens */
+       tcore_at_tok_free(tokens);
+       err("Exit");
+       return -1;
 }
 
-/*
-* Operation -  SS network initiated notification.
-* notification message format:
-* +CSSI : <code1>[,<index>]
-* where
-* <code1>
-* 0 unconditional call forwarding is active
-* 1 some of the conditional call forwarding are active
-* 2 call has been forwarded
-* 3 call is waiting
-* 4 this is a CUG call (also <index> present)
-* 5 outgoing calls are barred
-* 6 incoming calls are barred
-* 7 CLIR suppression rejected
-* 8 call has been deflected
-
-* <index>
-* refer Closed user group +CCUG.
-*/
-static gboolean on_notification_imc_call_ss_cssi_info(CoreObject *co, const void *event_data,
-       void *user_data)
+/* NOTIFICATION */
+static void on_notification_call_waiting(CoreObject *o, const void *data, void *user_data)
 {
        GSList *tokens = NULL;
-       TcoreNotification command = TCORE_NOTIFICATION_UNKNOWN;
-       char *resp = NULL;
-       char *cmd = 0;
-       int index = 0;
-       int code1 = -1;
+       const char *line = NULL;
+       char *pId;
+       int call_id;
+       gboolean *eflag;
+       GSList *pList = NULL;
+       CallObject *co = NULL, *dupco = NULL;
 
-       dbg("entry");
+       dbg("function entrance");
+       /* check call with waiting status already exist */
+       pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_WAITING);
 
-       if (1 != g_slist_length((GSList *) event_data)) {
-               err("unsolicited msg but multiple line");
-               return TRUE;
+       if (pList != NULL) {
+               dbg("[error]Waiting call already exist. skip");
+               return;
+       }
+       /* check call with incoming status already exist */
+       pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
+
+       if (pList != NULL) {
+               dbg("[error]incoming call already exist. skip");
+               return;
        }
-       cmd = (char *) ((GSList *) event_data)->data;
-       dbg("ss notification message[%s]", cmd);
+       line = (char *) data;
+       tokens = tcore_at_tok_new(line);
 
-       tokens = tcore_at_tok_new(cmd);
-       /* parse <code1> */
-       resp = g_slist_nth_data(tokens, 0);
-       if (NULL == resp) {
-               err("<code1> is missing from %CSSI indiaction");
+       pId = g_slist_nth_data(tokens, 0);
+       if (!pId) {
+               dbg("[error]:Call id is missing from +XCALLSTAT indication");
                tcore_at_tok_free(tokens);
-               return TRUE;
+               return;
        }
 
-       code1 = atoi(resp);
+       call_id = atoi(pId);
+       dupco = tcore_call_object_find_by_id(o, call_id);
+       if (dupco != NULL) {
+               dbg("co with same id already exist. skip");
+               tcore_at_tok_free(tokens);
+               return;
+       }
+       co = tcore_call_object_new(o);
+       if (!co) {
+               err("[ error ] co is NULL");
+               tcore_at_tok_free(tokens);
+               return;
+       }
+       tcore_call_object_set_id(co, call_id);
 
-       /* parse [ <index>] */
-       if ((resp = g_slist_nth_data(tokens, 1)))
-               index = atoi(resp);
+       tcore_at_tok_free(tokens);
 
-       dbg("+CSSI: <code1> = %d <index> = %d ", code1, index);
+       eflag = g_new0(gboolean, 1);
+       *eflag = TRUE;
+       dbg("calling _call_list_get");
+       _call_list_get(o, eflag);
+}
 
-       /* <code1> - other values will be ignored */
-       switch (code1) {
-       case 0:
-               command = TCORE_NOTIFICATION_CALL_INFO_MO_FORWARD_UNCONDITIONAL;
-               break;
-       case 1:
-               command = TCORE_NOTIFICATION_CALL_INFO_MO_FORWARD_CONDITIONAL;
-               break;
-       case 2:
-               command = TCORE_NOTIFICATION_CALL_INFO_MO_FORWARDED;
-               break;
-       case 3:
-               command = TCORE_NOTIFICATION_CALL_INFO_MO_WAITING;
-               break;
-       case 5:
-               command = TCORE_NOTIFICATION_CALL_INFO_MO_BARRED_OUTGOING;
-               break;
-       case 6:
-               command = TCORE_NOTIFICATION_CALL_INFO_MO_BARRED_INCOMING;
-               break;
-       case 8:
-               command  = TCORE_NOTIFICATION_CALL_INFO_MO_DEFLECTED;
-               break;
-       default:
-               dbg("Unsupported +CSSI notification : %d", code1);
-               break;
+static void on_notification_call_incoming(CoreObject *o, const void *data, void *user_data)
+{
+       GSList *tokens = NULL;
+       const char *line = NULL;
+       char *pId;
+       int call_id;
+       gboolean *eflag;
+       GSList *pList = NULL;
+       CallObject *co = NULL, *dupco = NULL;
+
+       dbg("function entrance");
+       /* check call with incoming status already exist */
+       pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
+
+       if (pList != NULL) {
+               dbg("incoming call already exist. skip");
+               return;
+       }
+
+       line = (char *) data;
+       tokens = tcore_at_tok_new(line);
+
+       pId = g_slist_nth_data(tokens, 0);
+       if (!pId) {
+               dbg("Error:Call id is missing from %XCALLSTAT indication");
+               tcore_at_tok_free(tokens);
+               return;
+       }
+
+       call_id = atoi(pId);
+
+       dupco = tcore_call_object_find_by_id(o, call_id);
+       if (dupco != NULL) {
+               dbg("co with same id already exist. skip");
+               tcore_at_tok_free(tokens);
+               return;
+       }
+
+       co = tcore_call_object_new(o);
+       if (!co) {
+               dbg("[ error ] co is NULL");
+               tcore_at_tok_free(tokens);
+               return;
        }
+       tcore_call_object_set_id(co, call_id);
 
-       if (command != TCORE_NOTIFICATION_UNKNOWN)
-               tcore_object_send_notification(co, command, 0, NULL);
+       dbg("freeing  at token");
        tcore_at_tok_free(tokens);
 
-       return TRUE;
+       eflag = g_new0(gboolean, 1);
+       *eflag = TRUE;
+
+       dbg("calling  _call_list_get");
+       _call_list_get(o, eflag);
 }
 
-static gboolean on_notification_imc_call_clip_info(CoreObject *co, const void *data,
-       void *user_data)
+static void on_notification_call_status(CoreObject *o, const void *data, void *user_data)
 {
-       dbg("entry");
-       /* TODO - handle +CLIP notification*/
-       return TRUE;
+       char *cmd = NULL;
+       TcorePlugin *plugin = NULL;
+       CallObject *co = NULL;
+       int id = -1;
+       int status = 0;
+       int type = 0;
+       char *stat = NULL;
+       char *pCallId = NULL;
+       GSList *tokens = NULL;
+       gboolean *eflag = NULL;
+       enum tcore_call_status co_status;
+
+       dbg("function entrance");
+       plugin = tcore_object_ref_plugin(o);
+       cmd = (char *) data;
+       tokens = tcore_at_tok_new(cmd);
+
+       /* parse <Call Id> */
+       pCallId = g_slist_nth_data(tokens, 0);
+       if (!pCallId) {
+               dbg("CallId is missing from %XCALLSTAT indication");
+               tcore_at_tok_free(tokens);
+               return;
+       } else {
+               id = atoi(pCallId);
+               dbg("call id = %d", id);
+               /* parse <Stat> */
+               if ((stat = g_slist_nth_data(tokens, 1)))
+                       status = atoi(stat);
+               dbg("call status = %d", status);
+       }
+
+       tcore_at_tok_free(tokens);
+       co_status = _call_status(status);
+
+       dbg("co_status = %d", co_status);
+       switch (co_status) {
+       case CALL_STATUS_ACTIVE:
+       {
+               int prev_status;
+               dbg("call(%d) status : [ ACTIVE ]", id);
+
+               co = tcore_call_object_find_by_id(o, id);
+               if (!co) {
+                       dbg("co is NULL");
+                       return;
+               }
+               /*
+               * Activie / Held status notification will be handled in call_list_get().
+               * Because of timing issue, we should not notifity this event before updating call info.
+               * One exception is that we will send this event when active status is receviced during dialing or incoming.
+               */
+               prev_status = tcore_call_object_get_status(co);
+               if ((prev_status == TCORE_CALL_STATUS_DIALING)
+                       || (prev_status == TCORE_CALL_STATUS_ALERT)
+                       || (prev_status == TCORE_CALL_STATUS_INCOMING)
+                       || (prev_status == TCORE_CALL_STATUS_WAITING)) {
+                       _call_status_active(plugin, co);
+               }
+       }
+       break;
+
+       case CALL_STATUS_HELD:
+       {
+               dbg("call(%d) status : [ held ]", id);
+               /*
+               * Activie / Held status notification will be handled in call_list_get().
+               * Because of timing issue, we should not notifity this event before updating call info.
+               */
+               /*
+               co = tcore_call_object_find_by_id(o, id);
+               if (!co) {
+                       dbg("co is NULL");
+                       return;
+               }
+               _call_status_held(plugin, co);
+               */
+       }
+       break;
+
+       case CALL_STATUS_DIALING:
+       {
+               dbg("call(%d) status : [ dialing ]", id);
+               co = tcore_call_object_find_by_id(o, id);
+               if (!co) {
+                       co = tcore_call_object_new(o);
+                       if (!co) {
+                               dbg("error : tcore_call_object_new [ id : %d ]", id);
+                               return;
+                       }
+                       tcore_call_object_set_id(co, id);
+               }
+
+               tcore_call_object_set_type(co, call_type(type));
+               tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_OUTGOING);
+               _call_status_dialing(plugin, co);
+       }
+       break;
+
+       case CALL_STATUS_ALERT:
+       {
+               dbg("call(%d) status : [ alert ]", id);
+               co = tcore_call_object_find_by_id(o, id);
+               if (!co) {
+                       dbg("co is NULL");
+                       return;
+               }
+               /* Store dialed number information into Call object. */
+               eflag = g_new0(gboolean, 1);
+               *eflag = TRUE;
+               dbg("calling _call_list_get");
+               _call_list_get(o, eflag);
+       }
+       break;
+
+       case CALL_STATUS_INCOMING:
+       case CALL_STATUS_WAITING:
+               dbg("call(%d) status : [ incoming ]", id);
+               break;
+
+       case CALL_STATUS_IDLE:
+       {
+               dbg("call(%d) status : [ release ]", id);
+
+               co = tcore_call_object_find_by_id(o, id);
+               if (!co) {
+                       dbg("co is NULL");
+                       return;
+               }
+
+               plugin = tcore_object_ref_plugin(o);
+               if (!plugin) {
+                       dbg("plugin is NULL");
+                       return;
+               }
+               _call_status_idle(plugin, co);
+       }
+       break;
+
+       default:
+               dbg("invalid call status", id);
+               break;
+       }
 }
 
-/* Response */
-static void on_response_imc_call_default(TcorePending *p,
-       guint data_len, const void *data, void *user_data)
+static TReturn imc_call_outgoing(CoreObject *o, UserRequest *ur)
 {
-       const TcoreAtResponse *at_resp = data;
-       CoreObject *co = tcore_pending_ref_core_object(p);
-       ImcRespCbData *resp_cb_data = user_data;
+       struct treq_call_dial *data = 0;
+       char *cmd_str;
+       const char *clir, *num;
+       TcorePending *pending;
+       TcoreATRequest *req;
+       gboolean ret;
 
-       TelCallResult result;
-       dbg("entry");
+       dbg("Entry");
 
-       tcore_check_return_assert(co != NULL);
-       tcore_check_return_assert(resp_cb_data != NULL);
+       data = (struct treq_call_dial *) tcore_user_request_ref_data(ur, 0);
+       if (data->type == CALL_TYPE_VIDEO) {
+               dbg("invalid call type");
+               return TCORE_RETURN_FAILURE;
+       }
 
-       if (at_resp && at_resp->success) {
-               result = TEL_CALL_RESULT_SUCCESS;
+       if (!strncmp(data->number, "*31#", 4)) {
+               dbg("clir suppression");
+               clir = "i";
+               num = data->number + 4;
+       } else if (!strncmp(data->number, "#31#", 4)) {
+               dbg("clir invocation");
+               clir = "I";
+               num = data->number + 4;
        } else {
-               err("ERROR[%s]",at_resp->final_response);
-               result = TEL_CALL_RESULT_FAILURE;
-               /*TODO - need to map CME error and final response error to TelCallResult */
+               int cli = 0;
+
+               dbg("no clir string in number");
+
+               vconf_get_int("db/ciss/show_my_number", &cli);
+
+               if (cli == 2) {
+                       dbg("clir invocation from setting application");
+                       clir = "I";
+               } else {
+                       dbg("set clir state to default");
+                       clir = "";
+               }
+               num = data->number;
+       }
+
+       dbg("data->number = %s", num);
+
+       cmd_str = g_strdup_printf("ATD%s%s;", num, clir);
+
+       dbg("request command : %s", cmd_str);
+
+       pending = tcore_pending_new(o, 0);
+       req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+       if (req == NULL) {
+               tcore_pending_free(pending);
+               g_free(cmd_str);
+               return TCORE_RETURN_FAILURE;
+       }
+       dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+       tcore_pending_set_request_data(pending, 0, req);
+       ret = _call_request_message(pending, o, ur, on_confirmation_call_outgoing, NULL);
+
+       g_free(cmd_str);
+
+       if (ret == FALSE) {
+               dbg("AT request(%s) sent failed", req->cmd);
+               return TCORE_RETURN_FAILURE;
        }
 
-       dbg("%s: [%s]", IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data),
-                (result == TEL_CALL_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+       dbg("AT request(%s) sent success", req->cmd);
 
-       /* Invoke callback */
-       if (resp_cb_data->cb)
-               resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+       dbg("Exit");
 
-       /* Free callback data */
-       imc_destroy_resp_cb_data(resp_cb_data);
+       return TCORE_RETURN_SUCCESS;
 }
 
-static void on_response_imc_call_set_volume_info(TcorePending *p,
-       guint data_len, const void *data, void *user_data)
+static TReturn imc_call_answer(CoreObject *o, UserRequest *ur)
 {
-       const TcoreAtResponse *at_resp = data;
-       CoreObject *co = tcore_pending_ref_core_object(p);
-       ImcRespCbData *resp_cb_data = user_data;
-       GSList *tokens = NULL;
-       GSList *line = NULL;
-       char *resp_str = NULL;
-       gboolean error;
+       char *cmd_str = NULL;
+       CallObject *co = NULL;
+       struct treq_call_answer *data = 0;
+       TcorePending *pending = NULL;
+       TcoreATRequest *req;
+       gboolean ret = FALSE;
+
+       dbg("function entrance");
+
+       if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+               dbg("cp not ready/n");
+               return TCORE_RETURN_ENOSYS;
+       }
 
-       TelCallResult result = TEL_CALL_RESULT_FAILURE;  // TODO: XDRV error mapping is required
-       dbg("Enter");
+       data = (struct treq_call_answer *) tcore_user_request_ref_data(ur, 0);
+       co = tcore_call_object_find_by_handle(o, data->handle);
+       if (data->type == CALL_ANSWER_TYPE_ACCEPT) {
+               dbg(" request type CALL_ANSWER_TYPE_ACCEPT");
+
+               cmd_str = g_strdup_printf("%s", "ATA");
+               pending = tcore_pending_new(o, 0);
+               req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+               if (req == NULL) {
+                       tcore_pending_free(pending);
+                       g_free(cmd_str);
+                       return TCORE_RETURN_FAILURE;
+               }
+               dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
 
-       tcore_check_return_assert(co != NULL);
-       tcore_check_return_assert(resp_cb_data != NULL);
+               tcore_pending_set_request_data(pending, 0, req);
+               ret = _call_request_message(pending, o, ur, on_confirmation_call_accept, co);
+               g_free(cmd_str);
 
-       if (at_resp && at_resp->success) {
-               line = at_resp->lines;
-               tokens = tcore_at_tok_new(line->data);
+               if (!ret) {
+                       dbg("AT request(%s) sent failed", req->cmd);
+                       return TCORE_RETURN_FAILURE;
+               }
+       } else {
+               switch (data->type) {
+               case CALL_ANSWER_TYPE_REJECT:
+               {
+                       dbg("call answer reject");
+                       tcore_call_control_answer_reject(o, ur, on_confirmation_call_reject, co);
+               }
+               break;
 
-               if (!g_slist_nth_data(tokens, 0)) {
-                       err("group_id is missing");
-                       goto OUT;
+               case CALL_ANSWER_TYPE_REPLACE:
+               {
+                       dbg("call answer replace");
+                       tcore_call_control_answer_replace(o, ur, on_confirmation_call_replace, co);
                }
+               break;
 
-               if (!g_slist_nth_data(tokens, 1)) {
-                       err(" function_id is missing");
-                       goto OUT;
+               case CALL_ANSWER_TYPE_HOLD_ACCEPT:
+               {
+                       dbg("call answer hold and accept");
+                       tcore_call_control_answer_hold_and_accept(o, ur, on_confirmation_call_hold_and_accept, co);
                }
+               break;
 
-               resp_str = g_slist_nth_data(tokens, 2);
-               if (!resp_str) {
-                       err("xdrv result missing");
-                       goto OUT;
-               } else {
-                       struct imc_set_volume_info *volume_info;
-                       gchar *vol = "";
-                       gchar *at_cmd;
-                       TelReturn ret;
+               default:
+                       dbg("[ error ] wrong answer type [ %d ]", data->type);
+                       return TCORE_RETURN_FAILURE;
+               }
+       }
 
-                       error = atoi(resp_str);
-                       if (error) {
-                               err("RESPONSE NOK");
-                               goto OUT;
+       return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn imc_call_release(CoreObject *o, UserRequest *ur)
+{
+       CallObject *co = NULL;
+       struct treq_call_end *data = 0;
+       UserRequest *ur_dup = NULL;
+       char *chld0_cmd = NULL;
+       char *chld1_cmd = NULL;
+       TcorePending *pending = NULL, *pending1 = NULL;
+       TcoreATRequest *req, *req1;
+       gboolean ret = FALSE;
+
+       dbg("function entrance");
+       if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+               dbg("cp not ready/n");
+               return TCORE_RETURN_ENOSYS;
+       }
+       data = (struct treq_call_end *) tcore_user_request_ref_data(ur, 0);
+       co = tcore_call_object_find_by_handle(o, data->handle);
+
+       dbg("type of release call = %d", data->type);
+
+       if (data->type == CALL_END_TYPE_ALL) {
+               /* releaseAll do not exist on legacy request. send CHLD=0, CHLD=1 in sequence */
+               chld0_cmd = g_strdup("AT+CHLD=0");
+               chld1_cmd = g_strdup("AT+CHLD=1");
+
+               pending = tcore_pending_new(o, 0);
+               req = tcore_at_request_new(chld0_cmd, NULL, TCORE_AT_NO_RESULT);
+               if (req == NULL) {
+                       tcore_pending_free(pending);
+                       g_free(chld0_cmd);
+                       g_free(chld1_cmd);
+                       return TCORE_RETURN_FAILURE;
+               }
+               dbg("input command is %s", chld0_cmd);
+               dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+               tcore_pending_set_request_data(pending, 0, req);
+               ur_dup = tcore_user_request_new(NULL, NULL);
+               ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_endall, NULL);
+               g_free(chld0_cmd);
+
+               if (!ret) {
+                       dbg("AT request %s has failed ", req->cmd);
+                       if (ur_dup) {
+                               tcore_user_request_free(ur_dup);
+                               ur_dup = NULL;
                        }
+                       g_free(chld1_cmd);
+                       return TCORE_RETURN_FAILURE;
+               }
+
+               pending1 = tcore_pending_new(o, 0);
+               req1 = tcore_at_request_new(chld1_cmd, NULL, TCORE_AT_NO_RESULT);
+               if (req1 == NULL) {
+                       tcore_pending_free(pending1);
+                       g_free(chld1_cmd);
+                       return TCORE_RETURN_FAILURE;
+               }
+               dbg("input command is %s", chld1_cmd);
+               dbg("req-cmd : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
+
+               tcore_pending_set_request_data(pending1, 0, req1);
+               ret = _call_request_message(pending1, o, ur, on_confirmation_call_release_all, co);
+               g_free(chld1_cmd);
+
+               if (!ret) {
+                       dbg("AT request %s has failed ", req->cmd);
+                       return TCORE_RETURN_FAILURE;
+               }
+       } else {
+               switch (data->type) {
+               case CALL_END_TYPE_DEFAULT:
+               {
+                       int id = 0;
+                       id = tcore_call_object_get_id(co);
+
+                       dbg("call end call id [%d]", id);
+                       tcore_call_control_end_specific(o, ur, id, on_confirmation_call_release_specific, co);
+               }
+               break;
+
+               case CALL_END_TYPE_ACTIVE_ALL:
+               {
+                       dbg("call end all active");
+                       tcore_call_control_end_all_active(o, ur, on_confirmation_call_release_all_active, co);
+               }
+               break;
+
+               case CALL_END_TYPE_HOLD_ALL:
+               {
+                       dbg("call end all held");
+                       tcore_call_control_end_all_held(o, ur, on_confirmation_call_release_all_held, co);
+               }
+               break;
+
+               default:
+                       dbg("[ error ] wrong end type [ %d ]", data->type);
+                       return TCORE_RETURN_FAILURE;
+               }
+       }
+
+       return TCORE_RETURN_SUCCESS;
+}
+
+static TReturn imc_call_hold(CoreObject *o, UserRequest *ur)
+{
+       struct treq_call_hold *hold = 0;
+       CallObject *co = NULL;
 
-                       /* Fetch from resp_cb_data */
-                       volume_info = (struct imc_set_volume_info *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
-                       dbg("volume info index[%d]", volume_info->next_index);
+       dbg("function entrance");
 
-                       if (xdrv_set_volume[volume_info->next_index] == NULL) {
-                               /*Processing of xdrv commands  completed */
-                               dbg("RESPONSE OK");
-                               result = TEL_CALL_RESULT_SUCCESS;
-                               goto OUT;
-                       } else if (volume_info->next_index == 3) {
-                               switch ((volume_info->volume) / 10) {
-                               case 0 :
-                                       vol = "0";
-                               break;
-                               case 1 :
-                                       vol = "40";
-                               break;
-                               case 2 :
-                                       vol = "46";
-                               break;
-                               case 3 :
-                                       vol = "52";
-                               break;
-                               case 4 :
-                                       vol = "58";
-                               break;
-                               case 5 :
-                                       vol = "64";
-                               break;
-                               case 6 :
-                                       vol = "70";
-                               break;
-                               case 7 :
-                                       vol = "76";
-                               break;
-                               case 8 :
-                                       vol = "82";
-                               break;
-                               case 9 :
-                               default :
-                                       vol = "88";
-                               }
-                       }
+       if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+               dbg("cp not ready/n");
+               return TCORE_RETURN_ENOSYS;
+       }
 
-                       at_cmd = g_strdup_printf("%s%s",
-                                       xdrv_set_volume[volume_info->next_index], vol);
+       hold = (struct treq_call_hold *) tcore_user_request_ref_data(ur, 0);
+       dbg("call handle : [ %d ]", hold->handle);
 
-                       /* Increament index to point to next command */
-                       volume_info->next_index += 1;
+       co = tcore_call_object_find_by_handle(o, hold->handle);
+       tcore_call_control_hold(o, ur, on_confirmation_call_hold, co);
 
-                       /* Send Request to modem */
-                       ret = tcore_at_prepare_and_send_request(co,
-                                       at_cmd, "+XDRV",
-                                       TCORE_AT_COMMAND_TYPE_SINGLELINE,
-                                       NULL,
-                                       on_response_imc_call_set_volume_info, resp_cb_data,
-                                       on_send_imc_request, NULL);
-                       IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "imc_call_set_volume_info");
-                       g_free(at_cmd);
+       return TCORE_RETURN_SUCCESS;
+}
 
-                       return;
-               }
+static TReturn imc_call_active(CoreObject *o, UserRequest *ur)
+{
+       struct treq_call_active *active = 0;
+       CallObject *co = NULL;
+
+       if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+               dbg("cp not ready/n");
+               return TCORE_RETURN_ENOSYS;
        }
 
-OUT :
-       dbg("Set Volume Info: [%s]",
-                       (result == TEL_CALL_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+       active = (struct treq_call_active *) tcore_user_request_ref_data(ur, 0);
+       dbg("call handle : [ %d ]", active->handle);
 
-       /* Invoke callback */
-       if (resp_cb_data->cb)
-               resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+       co = tcore_call_object_find_by_handle(o, active->handle);
+       tcore_call_control_active(o, ur, on_confirmation_call_active, co);
 
-       imc_destroy_resp_cb_data(resp_cb_data);
-       tcore_at_tok_free(tokens);
+       return TCORE_RETURN_SUCCESS;
 }
 
-static void on_response_imc_call_set_sound_path(TcorePending *p,
-       guint data_len, const void *data, void *user_data)
+static TReturn imc_call_swap(CoreObject *o, UserRequest *ur)
 {
-       const TcoreAtResponse *at_resp = data;
-       CoreObject *co = tcore_pending_ref_core_object(p);
-       ImcRespCbData *resp_cb_data = user_data;
-       GSList *tokens = NULL;
-       GSList *line = NULL;
-       char *resp_str = NULL;
-       gboolean error;
-       gint xdrv_func_id = -1;
+       struct treq_call_swap *swap = NULL;
+       CallObject *co = NULL;
 
-       TelCallResult result = TEL_CALL_RESULT_FAILURE;  // TODO: XDRV error mapping is required
-       dbg("Enter");
+       if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+               dbg("cp not ready/n");
+               return TCORE_RETURN_ENOSYS;
+       }
 
-       tcore_check_return_assert(co != NULL);
-       tcore_check_return_assert(resp_cb_data != NULL);
+       swap = (struct treq_call_swap *) tcore_user_request_ref_data(ur, 0);
+       dbg("call handle : [ %d ]", swap->handle);
 
-       if (at_resp && at_resp->success) {
-               line = at_resp->lines;
-               tokens = tcore_at_tok_new(line->data);
-               if (!g_slist_nth_data(tokens, 0)) {
-                       err("group_id is missing");
-                       goto OUT;
-               }
+       co = tcore_call_object_find_by_handle(o, swap->handle);
+       tcore_call_control_swap(o, ur, on_confirmation_call_swap, co);
 
-               if (!(resp_str = g_slist_nth_data(tokens, 1))) {
-                       err(" function_id is missing");
-                       goto OUT;
-               }
+       return TCORE_RETURN_SUCCESS;
+}
 
-               xdrv_func_id = atoi(resp_str);
+static TReturn imc_call_join(CoreObject *o, UserRequest *ur)
+{
+       struct treq_call_join *join = 0;
+       CallObject *co = NULL;
 
-               resp_str = g_slist_nth_data(tokens, 2);
-               if (resp_str) {
-                       error = atoi(resp_str);
-                       if (error) {
-                               err("RESPONSE NOK");
-                               goto OUT;
-                       } else {
-                               if (xdrv_func_id == 4) {
-                                       /* Send next command to configure destination device type */
-                                       gchar *at_cmd;
-                                       TelReturn ret;
-                                       gint *device_type = IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
-
-                                       at_cmd = g_strdup_printf("AT+XDRV=40,5,2,0,0,0,0,0,1,0,1,0,%d",
-                                                               *device_type);
-
-                                       ret = tcore_at_prepare_and_send_request(co,
-                                                       at_cmd, "+XDRV",
-                                                       TCORE_AT_COMMAND_TYPE_SINGLELINE,
-                                                       NULL,
-                                                       on_response_imc_call_set_sound_path, resp_cb_data,
-                                                       on_send_imc_request, NULL);
-                                       IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "imc_call_set_sound_path");
-                                       g_free(at_cmd);
-
-                                       return;
-                               }
-                               dbg("RESPONSE OK");
-                               result = TEL_CALL_RESULT_SUCCESS;
-                       }
-               }
+       if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+               dbg("cp not ready/n");
+               return TCORE_RETURN_ENOSYS;
        }
 
-OUT :
-       dbg("Set Sound Path: [%s]",
-                       (result == TEL_CALL_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
+       join = (struct treq_call_join *) tcore_user_request_ref_data(ur, 0);
+       dbg("call handle : [ %d ]", join->handle);
 
-       tcore_at_tok_free(tokens);
-
-       /* Invoke callback */
-       if (resp_cb_data->cb)
-               resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+       co = tcore_call_object_find_by_handle(o, join->handle);
+       tcore_call_control_join(o, ur, on_confirmation_call_join, co);
 
-       imc_destroy_resp_cb_data(resp_cb_data);
+       return TCORE_RETURN_SUCCESS;
 }
 
-static void on_response_set_sound_path(TcorePending *p, guint data_len,
-                                       const void *data, void *user_data)
+static TReturn imc_call_split(CoreObject *o, UserRequest *ur)
 {
-       const TcoreAtResponse *at_resp = data;
-       ImcRespCbData *resp_cb_data = user_data;
-       TelCallResult result = TEL_CALL_RESULT_FAILURE;
-       CoreObject *co_call = tcore_pending_ref_core_object(p);
+       struct treq_call_split *split = 0;
+       CallObject *co = NULL;
+       int id = 0;
+
+       if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+               dbg("cp not ready/n");
+               return TCORE_RETURN_ENOSYS;
+       }
 
-       if (at_resp && at_resp->success)
-                       result = TEL_CALL_RESULT_SUCCESS;
+       split = (struct treq_call_split *) tcore_user_request_ref_data(ur, 0);
+       co = tcore_call_object_find_by_handle(o, split->handle);
 
-       if(resp_cb_data->cb)
-               resp_cb_data->cb(co_call, (gint)result, NULL, resp_cb_data->cb_data);
+       id = tcore_call_object_get_id(co);
+       dbg("call ID : [ %d ]", id);
 
-       imc_destroy_resp_cb_data(resp_cb_data);
+       tcore_call_control_split(o, ur, id, on_confirmation_call_split, co);
+
+       return TCORE_RETURN_SUCCESS;
 }
 
-static void on_response_imc_call_set_mute(TcorePending *p, guint data_len,
-       const void *data, void *user_data)
+static TReturn imc_call_deflect(CoreObject *o, UserRequest *ur)
 {
-       const TcoreAtResponse *at_resp = data;
-       CoreObject *co = tcore_pending_ref_core_object(p);
-       ImcRespCbData *resp_cb_data = user_data;
-       GSList *tokens = NULL;
-       const char *line = NULL;
-       char *resp_str = NULL;
-       gboolean error;
+       struct treq_call_deflect *deflect = 0;
+       CallObject *co = NULL;
 
-       TelCallResult result = TEL_CALL_RESULT_FAILURE;  // TODO: XDRV error mapping is required
-       dbg("Enter");
+       if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+               dbg("cp not ready/n");
+               return TCORE_RETURN_ENOSYS;
+       }
 
-       tcore_check_return_assert(co != NULL);
-       tcore_check_return_assert(resp_cb_data != NULL);
+       deflect = (struct treq_call_deflect *) tcore_user_request_ref_data(ur, 0);
+       co = tcore_call_object_find_by_number(o, deflect->number);
+       dbg("deflect number: [ %s ]", deflect->number);
 
-       if (at_resp && at_resp->success) {
-               result = TEL_CALL_RESULT_SUCCESS;
-               line = (((GSList *)at_resp->lines)->data);
-               tokens = tcore_at_tok_new(line);
+       tcore_call_control_deflect(o, ur, deflect->number, on_confirmation_call_deflect, co);
 
-               resp_str = g_slist_nth_data(tokens, 0);
-               if (!g_slist_nth_data(tokens, 0)) {
-                       err("group_id is missing");
-                       result = TEL_CALL_RESULT_FAILURE;
-                       goto OUT;
-               }
+       return TCORE_RETURN_SUCCESS;
+}
 
-               if (!g_slist_nth_data(tokens, 1)) {
-                       err(" function_id is missing");
-                       result = TEL_CALL_RESULT_FAILURE;
-                       goto OUT;
-               }
+static TReturn imc_call_transfer(CoreObject *o, UserRequest *ur)
+{
+       struct treq_call_transfer *transfer = 0;
+       CallObject *co = NULL;
 
-               resp_str = g_slist_nth_data(tokens, 2);
-               if (resp_str) {
-                       error = atoi(resp_str);
-                       if (error) {
-                               result = TEL_CALL_RESULT_FAILURE;
-                               goto OUT;
-                       } else {
-                               result = TEL_CALL_RESULT_SUCCESS;
-                       }
-               }
+       if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+               dbg("cp not ready/n");
+               return TCORE_RETURN_ENOSYS;
        }
 
-OUT :
-       dbg("Set Mute: [%s]",
-                       (result == TEL_CALL_RESULT_SUCCESS ? "SUCCESS" : "FAIL"));
-       tcore_at_tok_free(tokens);
+       transfer = (struct treq_call_transfer *) tcore_user_request_ref_data(ur, 0);
+       dbg("call handle : [ %d ]", transfer->handle);
 
-       /* Invoke callback */
-       if (resp_cb_data->cb)
-               resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
+       co = tcore_call_object_find_by_handle(o, transfer->handle);
+       tcore_call_control_transfer(o, ur, on_confirmation_call_transfer, co);
 
-       imc_destroy_resp_cb_data(resp_cb_data);
+       return TCORE_RETURN_SUCCESS;
 }
 
-
- /* Request */
- /*
- * Operation - dial
- *
- * Request -
- * AT-Command: ATD <num> [I] [G] [;]
- * <num> - dialed number
- * [I][i] - CLI presentation(supression or invocation)
- * [G] - control the CUG supplementary service information for this call.
- *
- * Response -
- * Success:
- * OK or CONNECT
- * Failure:
- * "ERROR"
- * "NO ANSWER"
- * "NO CARRIER"
- * "BUSY"
- * "NO DIALTONE"
- * +CME ERROR: <error>
- */
-static TelReturn imc_call_dial(CoreObject *co, const TelCallDial *dial_info,
-               TcoreObjectResponseCallback cb, void *cb_data)
+static TReturn imc_call_start_cont_dtmf(CoreObject *o, UserRequest *ur)
 {
-       gchar *at_cmd;
-       const gchar *clir;
-       gchar *num;
+       char *cmd_str = NULL;
+       gboolean ret = FALSE;
+       TcoreATRequest *req;
+       struct treq_call_start_cont_dtmf *dtmf = 0;
+       TcorePending *pending = NULL;
 
-       dbg("entry");
+       dbg("Function enter");
 
-       if (dial_info->call_type == TEL_CALL_TYPE_VIDEO) {
-               err("Video call is not supported in imc modem");
-                return TEL_RETURN_OPERATION_NOT_SUPPORTED;
+       if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+               dbg("cp not ready/n");
+               return TCORE_RETURN_ENOSYS;
        }
+       dtmf = (struct treq_call_start_cont_dtmf *) tcore_user_request_ref_data(ur, 0);
 
-       if (!strncmp(dial_info->number, "*31#", 4)) {
-               dbg("clir suppression");
-               clir = "i";
-               num = (gchar *)&(dial_info->number[4]);
-       } else if (!strncmp(dial_info->number, "#31#", 4)) {
-               dbg("clir invocation");
-               clir = "I";
-               num = (gchar *)&(dial_info->number[4]);
-       } else {
-               int cli = 0;
-
-               dbg("no clir string in number");
+       /* Start Command Syntax: AT+XVTS=<DTMF> */
+       cmd_str = g_strdup_printf("AT+XVTS=%c", dtmf->dtmf_digit);
 
-               /* it will be removed when setting application use tapi_ss_set_cli()
-                * instead of his own vconfkey. (0 : By network, 1 : Show, 2 : Hide)
-                */
-               vconf_get_int("db/ciss/show_my_number", &cli);
-               if(cli == 2){
-                       dbg("clir invocation from setting application");
-                       clir = "I";
-               } else {
-                       dbg("set clir state to default");
-                       clir = "";
-               }
-               num = (gchar *)dial_info->number;
+       pending = tcore_pending_new(o, 0);
+       req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+       if (req == NULL) {
+               tcore_pending_free(pending);
+               g_free(cmd_str);
+               return TCORE_RETURN_FAILURE;
        }
 
-       /* AT-Command */
-       at_cmd = g_strdup_printf("ATD%s%s;", num, clir);
-       dbg(" at command : %s", at_cmd);
+       dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+       tcore_pending_set_request_data(pending, 0, req);
+       ret = _call_request_message(pending, o, ur, on_confirmation_call_start_cont_dtmf, NULL);
+       g_free(cmd_str);
+
+       if (!ret) {
+               dbg("AT request sent failed");
+               return TCORE_RETURN_FAILURE;
+       }
 
-       return __send_call_request(co, cb, cb_data, at_cmd, "imc_call_dial");
+       return TCORE_RETURN_SUCCESS;
 }
 
-/*
- * Operation - Answer/Reject/Replace/hold(current call) & accept incoming call.
- *
- * Request -
- *
- * 1. AT-Command: ATA
- * Response -
- * Success:
- * OK
- * Failure:
- * +CME ERROR: <error>
- *
- * 2. AT-Command: AT+CHLD=[<n>]
- * <n>
- * 0 - (deafult)release all held calls or set User Determined User Busy for a waiting/incoming
- * call; if both exists then only the waiting call will be rejected.
- * 1 -  release all active calls and accepts the other (held or waiting)
- * Note: In the scenario: An active call, a waiting call and held call, when the active call is
- * terminated, we will make the Waiting call as active.
- * 2 -         place all active calls (if exist) on hold and accepts the other call (held or waiting/in-coming).
- * If only one call exists which is active, place it on hold and if only held call exists make it active call.
- * Response -
- * Success:
- * OK
- * Failure:
- * +CME ERROR: <error>
- * For more informatiion refer 3GPP TS 27.007.
- */
-static TelReturn imc_call_answer(CoreObject *co, TelCallAnswerType ans_type,
-       TcoreObjectResponseCallback cb, void *cb_data)
+static TReturn imc_call_stop_cont_dtmf(CoreObject *o, UserRequest *ur)
 {
-       gchar *at_cmd;
-       dbg("entry");
+       char *cmd_str = NULL;
+       gboolean ret = FALSE;
+       TcoreATRequest *req;
+       TcorePending *pending = NULL;
+
+       dbg("Function enter");
+
+       if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+               dbg("cp not ready/n");
+               return TCORE_RETURN_ENOSYS;
+       }
 
-       if (ans_type == TEL_CALL_ANSWER_ACCEPT) {
-               /* AT-Command */
-               at_cmd = g_strdup_printf("%s", "ATA");
-       }else if (ans_type == TEL_CALL_ANSWER_REJECT) {
-               /* AT-Command */
-               at_cmd = g_strdup_printf("%s", "AT+CHLD=0");
-       } else if (ans_type == TEL_CALL_ANSWER_REPLACE) {
-               /* AT-Command */
-               at_cmd = g_strdup_printf("%s", "AT+CHLD=1");
-       } else if (ans_type == TEL_CALL_ANSWER_HOLD_AND_ACCEPT) {
-               /* AT-Command */
-               at_cmd = g_strdup_printf("%s", "AT+CHLD=2");
-       }else {
-               err("Unsupported call answer type");
-               return TEL_RETURN_FAILURE;
+       /* Stop Command Syntax: AT+XVTS= */
+       cmd_str = g_strdup_printf("AT+XVTS=");
+
+       pending = tcore_pending_new(o, 0);
+       req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+       if (req == NULL) {
+               tcore_pending_free(pending);
+               g_free(cmd_str);
+               return TCORE_RETURN_FAILURE;
        }
 
-       dbg("at command : %s", at_cmd);
+       dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+
+       tcore_pending_set_request_data(pending, 0, req);
+       ret = _call_request_message(pending, o, ur, on_confirmation_call_stop_cont_dtmf, NULL);
+       g_free(cmd_str);
+
+       if (!ret) {
+               dbg("AT request sent failed");
+               return TCORE_RETURN_FAILURE;
+       }
 
-       return __send_call_request(co, cb, cb_data, at_cmd, "imc_call_answer");
+       return TCORE_RETURN_SUCCESS;
 }
 
-/*
- * Operation - release all calls/release specific call/release all active call/release all held calls.
- *
- * Request -
- * 1. AT-Command: AT+CHLD=[<n>]
- * <n>
- * 0  - (defualt)release all held calls or set User Determined User Busy for a waiting/incoming.
- * call; if both exists then only the waiting call will be rejected.
- * 1  - release all active calls and accepts the other (held or waiting).
- * 1x - release a specific call (x specific call number as indicated by call id).
- * 8  -        release all calls.
- * Response -
- * Success:
- * OK
- * Failure:
- * +CME ERROR: <error>
- */
-static TelReturn imc_call_end(CoreObject *co, const TelCallEnd *end_info,
-       TcoreObjectResponseCallback cb, void *cb_data)
+static TReturn imc_call_set_sound_path(CoreObject *o, UserRequest *ur)
 {
-       gchar *at_cmd;
-       dbg("entry");
+       UserRequest *ur_dup = NULL;
+       TcorePending *pending = NULL, *pending1 = NULL;
+       TcoreATRequest *req, *req1;
+       char *cmd_str = NULL, *cmd_str1 = NULL;
+       int device_type = -1;
+       struct treq_call_set_sound_path *sound_path = 0;
+       gboolean ret = FALSE;
+       TcorePlugin *plugin = tcore_object_ref_plugin(o);
+       const char *cp_name = tcore_server_get_cp_name_by_plugin(plugin);
 
-       if (end_info->end_type == TEL_CALL_END_ALL) {
-               /* AT-Command */
-               at_cmd = g_strdup_printf("%s", "AT+CHLD=8");
-       }else if (end_info->end_type == TEL_CALL_END) {
-               /* AT-Command */
-               at_cmd = g_strdup_printf("%s%d", "AT+CHLD=1",end_info->call_id);
-       } else if (end_info->end_type == TEL_CALL_END_ACTIVE_ALL) {
-               /* AT-Command */
-               at_cmd = g_strdup_printf("%s", "AT+CHLD=1");
-       } else if (end_info->end_type == TEL_CALL_END_HOLD_ALL) {
-               /* AT-Command */
-               at_cmd = g_strdup_printf("%s", "AT+CHLD=0");
-       }else {
-               err("Unsupported call end type");
-               return TEL_RETURN_FAILURE;
+       dbg("function entrance");
+
+       if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+               dbg("cp not ready/n");
+               return TCORE_RETURN_ENOSYS;
+       }
+       sound_path = (struct treq_call_set_sound_path *) tcore_user_request_ref_data(ur, 0);
+       if (sound_path == NULL) {
+               dbg("invaling user request");
+               return TCORE_RETURN_FAILURE;
        }
+       dbg("audio device type - 0x%x", sound_path->path);
+       switch (sound_path->path) {
+       case CALL_SOUND_PATH_HANDSET:
+               device_type = 1;
+               break;
 
-       dbg("at command : %s", at_cmd);
+       case CALL_SOUND_PATH_HEADSET:
+               device_type = 2;
+               break;
 
-       return __send_call_request(co, cb, cb_data, at_cmd, "imc_call_end");
-}
+       case CALL_SOUND_PATH_HEADSET_3_5PI:
+               device_type = 3;
+               break;
 
-/*
- * Operation - send dtmf.
- *
- * Request -
- * 1. AT-Command: AT+VTS=<DTMF>,{<DTMF>,<duration>}.
- * where
- * <DTMF>:
- * is a single ASCII character in the set 0-9, #, *, A-D. Even it will support string DTMF.
- * <duration>:
- * integer in range 0-255, meaning 1/10(10 millisec) seconds multiples. The string parameter
- * of the command consists of combinations of the following separated by commas:
- * NOTE : There is a limit of 50 dtmf tones can be requested through a single VTS command.
- * Response -
- * Success:
- * OK
- * Failure:
- * +CME ERROR: <error>
- */
-static TelReturn imc_call_send_dtmf(CoreObject *co, const char *dtmf_str,
-       TcoreObjectResponseCallback cb,  void *cb_data)
-{
-       gchar *at_cmd;
-       char *tmp_dtmf = NULL, *dtmf;
-       unsigned int count;
+       case CALL_SOUND_PATH_SPEAKER:
+               device_type = 4;
+               break;
 
-       dbg("entry");
+       case CALL_SOUND_PATH_HANDFREE:
+               device_type = 5;
+               break;
 
-       //(void) _set_dtmf_tone_duration(o, dup);
-       tmp_dtmf = tcore_malloc0((strlen(dtmf_str) * 2) + 1); // DTMF digits + comma for each dtmf digit.
-       tcore_check_return_value_assert(tmp_dtmf != NULL, TEL_RETURN_FAILURE);
-       /* Save initial pointer */
-       dtmf = tmp_dtmf;
+       case CALL_SOUND_PATH_HEADSET_HAC:
+               device_type = 6;
+               break;
 
-       for (count = 0; count < strlen(dtmf_str); count++) {
-               *tmp_dtmf = dtmf_str[count];
-               tmp_dtmf++;
+       case CALL_SOUND_PATH_BLUETOOTH:
+       case CALL_SOUND_PATH_STEREO_BLUETOOTH:
+               device_type = 7;
+               break;
 
-               *tmp_dtmf = COMMA;
-               tmp_dtmf++;
+       case CALL_SOUND_PATH_BT_NSEC_OFF:
+       case CALL_SOUND_PATH_MIC1:
+       case CALL_SOUND_PATH_MIC2:
+       default:
+               dbg("unsupported device type");
+               return TCORE_RETURN_FAILURE;
        }
 
-       // last digit is having COMMA , overwrite it with '\0' .
-       *(--tmp_dtmf) = '\0';
+       if (g_str_has_prefix(cp_name, "mfld_blackbay") == TRUE) {
+               struct tnoti_call_sound_path *tnoti_snd_path;
 
-       // AT+VTS = <d1>,<d2>,<d3>,<d4>,<d5>,<d6>, ..... <d32>
-       at_cmd = g_strdup_printf("AT+VTS=%s", dtmf);
-       dbg("at command : %s", at_cmd);
+               tnoti_snd_path = g_try_new0(struct tnoti_call_sound_path, 1);
+               if (!tnoti_snd_path)
+                       return TCORE_RETURN_ENOMEM;
 
-       tcore_free(dtmf);
+               tnoti_snd_path->path = sound_path->path;
 
-       return __send_call_request(co, cb, cb_data, at_cmd, "imc_call_send_dtmf");
-}
+               /* Configure modem I2S1 to 8khz, mono, PCM if routing to bluetooth */
+               if (sound_path->path == CALL_SOUND_PATH_BLUETOOTH || sound_path->path == CALL_SOUND_PATH_STEREO_BLUETOOTH) {
+                       call_prepare_and_send_pending_request(o, "AT+XDRV=40, 4, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 21", NULL, TCORE_AT_NO_RESULT, NULL);
+                       call_prepare_and_send_pending_request(o, "AT+XDRV=40, 5, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 22", NULL, TCORE_AT_NO_RESULT, NULL);
+               } else {
+                       call_prepare_and_send_pending_request(o, "AT+XDRV=40, 4, 3, 0, 1, 0, 8, 0, 1, 0, 2, 0, 21", NULL, TCORE_AT_NO_RESULT, NULL);
+                       call_prepare_and_send_pending_request(o, "AT+XDRV=40, 5, 2, 0, 1, 0, 8, 0, 1, 0, 2, 0, 22", NULL, TCORE_AT_NO_RESULT, NULL);
+               }
 
-/*
- * Operation - call hold.
- *
- * Request -
- * 1. AT-Command: AT+CHLD=[<n>]
- * Where
- * <n>
- * 2 - place all active calls (if exist) on hold and accepts the other call (held or waiting/incoming).
- * If only one call exists which is active, place it on hold and if only held call exists
- * make it active call
- * Response -
- * Success:
- * OK
- * Failure:
- * +CME ERROR: <error>
- */
-static TelReturn imc_call_hold(CoreObject *co, TcoreObjectResponseCallback cb,
-       void *cb_data)
+               /* Configure modem I2S2 and do the modem routing */
+               call_prepare_and_send_pending_request(o, "AT+XDRV=40, 4, 4, 0, 0, 0, 8, 0, 1, 0, 2, 0, 21", NULL, TCORE_AT_NO_RESULT, NULL);
+               call_prepare_and_send_pending_request(o, "AT+XDRV=40, 5, 3, 0, 0, 0, 8, 0, 1, 0, 2, 0, 22", NULL, TCORE_AT_NO_RESULT, NULL);
+               call_prepare_and_send_pending_request(o, "AT+XDRV=40, 6, 0, 4", NULL, TCORE_AT_NO_RESULT, NULL);
+               call_prepare_and_send_pending_request(o, "AT+XDRV=40, 6, 3, 0", NULL, TCORE_AT_NO_RESULT, NULL);
+               call_prepare_and_send_pending_request(o, "AT+XDRV=40, 6, 4, 2", NULL, TCORE_AT_NO_RESULT, NULL);
+               call_prepare_and_send_pending_request(o, "AT+XDRV=40, 6, 5, 2", NULL, TCORE_AT_NO_RESULT, NULL);
 
-{
-       gchar *at_cmd;
-       dbg("entry");
+               /* amc enable */
+               call_prepare_and_send_pending_request(o, "AT+XDRV=40, 2, 4", NULL, TCORE_AT_NO_RESULT, NULL); /* AMC_I2S2_RX */
+               call_prepare_and_send_pending_request(o, "AT+XDRV=40, 2, 3", NULL, TCORE_AT_NO_RESULT, NULL); /* AMC_I2S1_RX */
+               /* amc route: AMC_RADIO_RX => AMC_I2S1_TX */
 
-       at_cmd = g_strdup_printf("%s", "AT+CHLD=2");
-       dbg("at command : %s", at_cmd);
+               pending = tcore_pending_new(o, 0);
+               req = tcore_at_request_new("AT+XDRV=40, 6, 0, 2", "+XDRV", TCORE_AT_SINGLELINE);
+               if (req == NULL) {
+                       tcore_pending_free(pending);
+                       return TCORE_RETURN_FAILURE;
+               }
+               dbg("XDRV req-cmd for source type  : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+               tcore_pending_set_request_data(pending, 0, req);
+               ur_dup = tcore_user_request_ref(ur);
+               ret = _call_request_message(pending, o, ur_dup, on_confirmation_set_sound_path, tnoti_snd_path);
 
-       return __send_call_request(co, cb, cb_data, at_cmd, "imc_call_hold");
-}
+       } else {
 
-/*
- * Operation - call active.
- *
- * Request -
- * 1. AT-Command: AT+CHLD=[<n>]
- * Where
- * <n>
- * 2 - place all active calls (if exist) on hold and accepts the other call (held or waiting/incoming).
- * If only one call exists which is active, place it on hold and if only held call exists
- * make it active call
- * Response -
- * Success:
- * OK
- * Failure:
- * +CME ERROR: <error>
- */
-static TelReturn imc_call_active(CoreObject *co, TcoreObjectResponseCallback cb,
-       void *cb_data)
-{
-       gchar *at_cmd;
-       dbg("entry");
+               cmd_str = g_strdup_printf("AT+XDRV=40, 4, 3, 0, 0, 0, 0, 0, 1, 0, 1, 0, %d", device_type); /* source type. */
+               pending = tcore_pending_new(o, 0);
+               req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+               if (req == NULL) {
+                       tcore_pending_free(pending);
+                       g_free(cmd_str);
+                       return TCORE_RETURN_FAILURE;
+               }
+               dbg("XDRV req-cmd for source type  : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
+               tcore_pending_set_request_data(pending, 0, req);
+               ur_dup = tcore_user_request_ref(ur);
+               ret = _call_request_message(pending, o, ur_dup, on_confirmation_call_set_source_sound_path, NULL);
+               g_free(cmd_str);
+
+               if (!ret) {
+                       dbg("At request(%s) sent failed", req->cmd);
+                       return TCORE_RETURN_FAILURE;
+               }
 
-       at_cmd = g_strdup_printf("%s", "AT+CHLD=2");
-       dbg("at command : %s", at_cmd);
+               cmd_str1 = g_strdup_printf("AT+XDRV=40, 5, 2, 0, 0, 0, 0, 0, 1, 0, 1, 0, %d", device_type); /* destination type */
+               pending1 = tcore_pending_new(o, 0);
+               req1 = tcore_at_request_new(cmd_str1, "+XDRV", TCORE_AT_SINGLELINE);
+               if (req1 == NULL) {
+                       tcore_pending_free(pending1);
+                       g_free(cmd_str1);
+                       return TCORE_RETURN_FAILURE;
+               }
+               dbg("XDRV req-cmd for destination type : %s, prefix(if any) :%s, cmd_len : %d", req1->cmd, req1->prefix, strlen(req1->cmd));
+               tcore_pending_set_request_data(pending1, 0, req1);
+               ret = _call_request_message(pending1, o, ur, on_confirmation_call_set_destination_sound_path, NULL);
+               g_free(cmd_str1);
+
+               if (!ret) {
+                       dbg("AT request %s has failed ", req1->cmd);
+                       return TCORE_RETURN_FAILURE;
+               }
+       }
 
-       return __send_call_request(co, cb, cb_data, at_cmd, "imc_call_active");
+       return TCORE_RETURN_SUCCESS;
 }
 
-/*
- * Operation - call swap.
- *
- * Request -
- * 1. AT-Command: AT+CHLD=[<n>]
- * Where
- * <n>
- * 2 - place all active calls (if exist) on hold and accepts the other call (held or waiting/incoming).
- * If only one call exists which is active, place it on hold and if only held call exists
- * make it active call
- * Response -
- * Success:
- * OK
- * Failure:
- * +CME ERROR: <error>
- */
-static TelReturn imc_call_swap(CoreObject *co, TcoreObjectResponseCallback cb,
-       void *cb_data)
+static TReturn imc_call_set_sound_volume_level(CoreObject *o, UserRequest *ur)
 {
-       gchar *at_cmd;
-       dbg("entry");
+       UserRequest *src_ur = NULL;
+       UserRequest *dest_ur = NULL;
+       TcorePending *src_pending = NULL;
+       TcorePending *dest_pending = NULL;
+       TcoreATRequest *src_req = NULL;
+       TcoreATRequest *dest_req = NULL;
+       char *cmd_str = NULL, *volume_level = NULL;
+       gboolean ret = FALSE;
+       struct treq_call_set_sound_volume_level *data = NULL;
 
-       at_cmd = g_strdup_printf("%s", "AT+CHLD=2");
-       dbg("at command : %s", at_cmd);
+       dbg("Entry");
 
-       return __send_call_request(co, cb, cb_data, at_cmd, "imc_call_swap");
-}
+       if (FALSE == tcore_hal_get_power_state(tcore_object_get_hal(o))) {
+               dbg("cp not ready/n");
+               return TCORE_RETURN_ENOSYS;
+       }
 
-/*
- * Operation - call join.
- *
- * Request -
- * 1. AT-Command: AT+CHLD=[<n>]
- * Where
- * <n>
- * 3 - adds a held call to the conversation
- * Response -
- * Success:
- * OK
- * Failure:
- * +CME ERROR: <error>
- */
-static TelReturn imc_call_join(CoreObject *co, TcoreObjectResponseCallback cb,
-       void *cb_data)
-{
-       gchar *at_cmd;
-       dbg("entry");
+       data = (struct treq_call_set_sound_volume_level *) tcore_user_request_ref_data(ur, 0);
 
-       at_cmd = g_strdup_printf("%s", "AT+CHLD=3");
-       dbg("at command : %s", at_cmd);
+       /* Hard-coded values for MIC & Speakers */
+       /* Source volume */
+       dbg("Set Source volume");
 
-       return __send_call_request(co, cb, cb_data, at_cmd, "imc_call_join");
-}
+       cmd_str = g_strdup_printf("%s", "AT+XDRV=40, 7, 3, 88");   /* Source type */
+       dbg("Request command string: %s", cmd_str);
 
-/*
- * Operation - call split.
- *
- * Request -
- * 1. AT-Command: AT+CHLD=[<n>]
- * Where
- * <n>
- * 2x - place all active calls on hold except call x with which communication is supported
- * Response -
- * Success:
- * OK
- * Failure:
- * +CME ERROR: <error>
- */
-static TelReturn imc_call_split(CoreObject *co, unsigned int call_id,
-       TcoreObjectResponseCallback cb, void *cb_data)
-{
-       gchar *at_cmd;
-       dbg("entry");
+       /* Create new Pending request */
+       src_pending = tcore_pending_new(o, 0);
 
-       at_cmd = g_strdup_printf("%s%d", "AT+CHLD=2", call_id);
-       dbg("at command : %s", at_cmd);
+       /* Create new AT-Command request */
+       src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+       if (src_req == NULL) {
+               tcore_pending_free(src_pending);
+               g_free(cmd_str);
+               return TCORE_RETURN_FAILURE;
+       }
+       dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
 
-       return __send_call_request(co, cb, cb_data, at_cmd, "imc_call_split");
-}
+       /* Free Command string */
+       g_free(cmd_str);
 
-/*
- * Operation - call transfer.
- *
- * Request -
- * 1. AT-Command: AT+CHLD=[<n>]
- * Where
- * <n>
- * 4 connects the two calls and disconnects the subscriber from both calls (Explicit Call Transfer)
- * Response -
- * Success:
- * OK
- * Failure:
- * +CME ERROR: <error>
- */
-static TelReturn imc_call_transfer(CoreObject *co, TcoreObjectResponseCallback cb,
-       void *cb_data)
-{
-       gchar *at_cmd;
-       dbg("entry");
+       tcore_pending_set_request_data(src_pending, 0, src_req);
+       src_ur = tcore_user_request_ref(ur);
 
-       at_cmd = g_strdup_printf("%s", "AT+CHLD=4");
-       dbg("at command : %s", at_cmd);
+       /* Send request */
+       ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
+       if (!ret) {
+               err("Failed to send AT-Command request");
+               return TCORE_RETURN_FAILURE;
+       }
 
-       return __send_call_request(co, cb, cb_data, at_cmd, "imc_call_transfer");
-}
+       cmd_str = g_strdup_printf("%s", "AT+XDRV=40, 7, 0, 88");   /* Destination type */
+       dbg("Request command string: %s", cmd_str);
 
-/*
- * Operation - call transfer.
- *
- * Request -
- * 1. AT-Command: AT+CTFR= <number>[,<type>]
- * Where
- * number>
- * string type phone number
- * <type>
- * type of address octet in integer format. It is optional parameter.
- *
- * Response -
- * Success:
- * OK
- * Failure:
- * +CME ERROR: <error>
- */
-static TelReturn imc_call_deflect(CoreObject *co, const char *deflect_to,
-       TcoreObjectResponseCallback cb, void *cb_data)
-{
-       gchar *at_cmd;
-       dbg("entry");
+       /* Create new Pending request */
+       src_pending = tcore_pending_new(o, 0);
 
-       at_cmd = g_strdup_printf("AT+CTFR=%s", deflect_to);
-       dbg("at command : %s", at_cmd);
+       /* Create new AT-Command request */
+       src_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+       if (src_req == NULL) {
+               tcore_pending_free(src_pending);
+               g_free(cmd_str);
+               return TCORE_RETURN_FAILURE;
+       }
+       dbg("Command: %s, prefix(if any): %s, Command length: %d", src_req->cmd, src_req->prefix, strlen(src_req->cmd));
 
-       return __send_call_request(co, cb, cb_data, at_cmd, "imc_call_deflect");
-}
+       /* Free Command string */
+       g_free(cmd_str);
 
-static TelReturn imc_call_set_active_line(CoreObject *co, TelCallActiveLine active_line,
-       TcoreObjectResponseCallback cb, void *cb_data)
-{
-       dbg("entry");
+       tcore_pending_set_request_data(src_pending, 0, src_req);
 
-       dbg("exit");
-       return TEL_RETURN_OPERATION_NOT_SUPPORTED;
-}
+       src_ur = tcore_user_request_ref(ur);
 
-static TelReturn imc_call_get_active_line(CoreObject *co, TcoreObjectResponseCallback cb,
-       void *cb_data)
-{
-       dbg("entry");
+       /* Send request */
+       ret = _call_request_message(src_pending, o, src_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
+       if (!ret) {
+               err("Failed to send AT-Command request");
+               return TCORE_RETURN_FAILURE;
+       }
 
-       dbg("exit");
-       return TEL_RETURN_OPERATION_NOT_SUPPORTED;
-}
+       /* Destination volume */
+       dbg("Set Source volume");
 
-/*
- * Operation - Set voule info.
- *
- * Request -
- * AT-Command: AT+XDRV=<group_id>,<function_id>[,<param_n>]
- * The first command parameter defines the involved driver group.
- * The second command parameter defines a certain function in the selected driver group.
- * Other parameters are dependent on the first two parameters.
- * Nearly all parameters are integer values, also if they are represented by literals.
- * Only very few are strings or
- * hex data strings.
- *
- * Response -
- * +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
- * The first response parameter defines the involved driver group.
- * The second response parameter defines the current function in the selected driver group.
- * The third response parameter defines the xdrv_result of the operation.
- * Additional response parameters dependent on the first two parameters.
- */
-static TelReturn imc_call_set_volume_info(CoreObject *co, const TelCallVolumeInfo *volume_info,
-       TcoreObjectResponseCallback cb, void *cb_data)
-{
-       ImcRespCbData *resp_cb_data = NULL;
-       gchar *at_cmd;
-       TelReturn ret;
-       struct imc_set_volume_info cb_volume_info;
+       cmd_str = g_strdup_printf("%s", "AT+XDRV=40, 8, 0, 88");   /* Source type */
+       dbg("Request command string: %s", cmd_str);
 
-       dbg("entry");
+       /* Create new Pending request */
+       dest_pending = tcore_pending_new(o, 0);
 
-       cb_volume_info.next_index = 1;
-       cb_volume_info.volume = volume_info->volume;
+       /* Create new AT-Command request */
+       dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+       if (dest_req == NULL) {
+               tcore_pending_free(dest_pending);
+               g_free(cmd_str);
+               return TCORE_RETURN_FAILURE;
+       }
+       dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
 
-       /* Response callback data */
-       resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
-                               &cb_volume_info, sizeof(struct imc_set_volume_info));
+       /* Free Command string */
+       g_free(cmd_str);
 
-       at_cmd = g_strdup_printf("%s", xdrv_set_volume[0]);
+       tcore_pending_set_request_data(dest_pending, 0, dest_req);
+       dest_ur = tcore_user_request_ref(ur);
 
-       /* Send Request to modem */
-       ret = tcore_at_prepare_and_send_request(co,
-                       at_cmd, "+XDRV",
-                       TCORE_AT_COMMAND_TYPE_SINGLELINE,
-                       NULL,
-                       on_response_imc_call_set_volume_info, resp_cb_data,
-                       on_send_imc_request, NULL);
-       IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "imc_call_set_volume_info");
+       /* Send request */
+       ret = _call_request_message(dest_pending, o, dest_ur, on_confirmation_call_set_source_sound_volume_level, NULL);
+       if (!ret) {
+               err("Failed to send AT-Command request");
+               return TCORE_RETURN_FAILURE;
+       }
 
-       g_free(at_cmd);
-       return ret;
-}
+       dbg("Input volume level - %d", data->volume);
+       switch (data->volume) {
+       case CALL_SOUND_MUTE:
+               volume_level = "0";
+               break;
 
+       case CALL_SOUND_VOLUME_LEVEL_1:
+               volume_level = "40";
+               break;
 
-static TelReturn imc_call_get_volume_info(CoreObject *co, TelCallSoundDevice sound_device,
-       TcoreObjectResponseCallback cb, void *cb_data)
-{
-       dbg("Entry");
+       case CALL_SOUND_VOLUME_LEVEL_2:
+               volume_level = "46";
+               break;
 
-       dbg("Exit");
-       return TEL_RETURN_OPERATION_NOT_SUPPORTED;
-}
+       case CALL_SOUND_VOLUME_LEVEL_3:
+               volume_level = "52";
+               break;
 
-/*
- * Operation - Set sound path.
- *
- * Request -
- * AT-Command: AT+XDRV=<group_id>,<function_id>[,<param_n>]
- * The first command parameter defines the involved driver group.
- * The second command parameter defines a certain function in the selected driver group.
- * Other parameters are dependent on the first two parameters.
- * Nearly all parameters are integer values, also if they are represented by literals.
- * Only very few are strings or
- * hex data strings.
- *
- * Response -
- * +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
- * The first response parameter defines the involved driver group.
- * The second response parameter defines the current function in the selected driver group.
- * The third response parameter defines the xdrv_result of the operation.
- * Additional response parameters dependent on the first two parameters.
- */
+       case CALL_SOUND_VOLUME_LEVEL_4:
+               volume_level = "58";
+               break;
 
-static TelReturn imc_call_set_sound_path(CoreObject *co, const TelCallSoundPathInfo *sound_path_info,
-       TcoreObjectResponseCallback cb, void *cb_data)
-{
-       ImcRespCbData *resp_cb_data = NULL;
-       TelReturn ret;
-       gchar *at_cmd;
-       gint device_type = -1;
-       TcorePlugin *plugin = tcore_object_ref_plugin(co);
-       const char *cp_name = tcore_server_get_cp_name_by_plugin(plugin);
+       case CALL_SOUND_VOLUME_LEVEL_5:
+               volume_level = "64";
+               break;
 
-       dbg("audio device type - 0x%x", sound_path_info->path);
+       case CALL_SOUND_VOLUME_LEVEL_6:
+               volume_level = "70";
+               break;
 
-       switch (sound_path_info->path) {
-               case TEL_SOUND_PATH_HANDSET:
-                       device_type = 1;
-                       break;
-               case TEL_SOUND_PATH_HEADSET:
-                       device_type = 2;
-                       break;
-               case TEL_SOUND_PATH_HEADSET_3_5PI:
-                       device_type = 3;
-                       break;
-               case TEL_SOUND_PATH_SPK_PHONE:
-                       device_type = 4;
-                       break;
-               case TEL_SOUND_PATH_HANDSFREE:
-                       device_type = 5;
-                       break;
-               case TEL_SOUND_PATH_HEADSET_HAC:
-                       device_type = 6;
-                       break;
-               case TEL_SOUND_PATH_BLUETOOTH:
-               case TEL_SOUND_PATH_STEREO_BLUETOOTH:
-                       device_type = 7;
-                       break;
-               case TEL_SOUND_PATH_BT_NSEC_OFF:
-               case TEL_SOUND_PATH_MIC1:
-               case TEL_SOUND_PATH_MIC2:
-               default:
-                       dbg("unsupported device type");
-                       return TEL_RETURN_INVALID_PARAMETER;
-       }
+       case CALL_SOUND_VOLUME_LEVEL_7:
+               volume_level = "76";
+               break;
 
-       if (g_str_has_prefix(cp_name, "imcmodem")) {
-               /* Response callback data */
-               resp_cb_data = imc_create_resp_cb_data(cb, cb_data, &device_type, sizeof(gint));
+       case CALL_SOUND_VOLUME_LEVEL_8:
+               volume_level = "82";
+               break;
 
-               at_cmd = g_strdup_printf("AT+XDRV=40,4,3,0,0,0,0,0,1,0,1,0,%d", device_type);
+       case CALL_SOUND_VOLUME_LEVEL_9:
+       default:
+               volume_level = "88";
+               break;
+       }
+       cmd_str = g_strdup_printf("%s%s", "AT+XDRV=40, 8, 2, ", volume_level);   /* Destination type */
+       dbg("Request command string: %s", cmd_str);
+
+       /* Create new Pending request */
+       dest_pending = tcore_pending_new(o, 0);
+
+       /* Create new AT-Command request */
+       dest_req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+       if (dest_req == NULL) {
+               tcore_pending_free(dest_pending);
+               g_free(cmd_str);
+               return TCORE_RETURN_FAILURE;
+       }
+       dbg("Command: %s, prefix(if any): %s, Command length: %d", dest_req->cmd, dest_req->prefix, strlen(dest_req->cmd));
 
-               ret = tcore_at_prepare_and_send_request(co,
-                       at_cmd, "+XDRV",
-                       TCORE_AT_COMMAND_TYPE_SINGLELINE,
-                       NULL,
-                       on_response_imc_call_set_sound_path, resp_cb_data,
-                       on_send_imc_request, NULL);
-               IMC_CHECK_REQUEST_RET(ret, NULL, "imc_call_set_sound_path");
-               g_free(at_cmd);
-       } else {
-               /* Response callback data */
-               resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+       /* Free Command string */
+       g_free(cmd_str);
 
-               /* Configure modem I2S1 to 8khz, mono, PCM if routing to bluetooth */
-               if (sound_path_info->path == TEL_SOUND_PATH_BLUETOOTH ||
-                               sound_path_info->path == TEL_SOUND_PATH_STEREO_BLUETOOTH) {
-                       tcore_at_prepare_and_send_request(co,
-                                       "AT+XDRV=40,4,3,0,1,0,0,0,0,0,0,0,21",
-                                       NULL, TCORE_AT_COMMAND_TYPE_NO_RESULT,
-                                       NULL, NULL, NULL, NULL, NULL);
-
-                       tcore_at_prepare_and_send_request(co,
-                                       "AT+XDRV=40,5,2,0,1,0,0,0,0,0,0,0,22",
-                                       NULL, TCORE_AT_COMMAND_TYPE_NO_RESULT,
-                                       NULL, NULL, NULL, NULL, NULL);
-               } else {
-                       tcore_at_prepare_and_send_request(co,
-                                       "AT+XDRV=40,4,3,0,1,0,8,0,1,0,2,0,21",
-                                       NULL, TCORE_AT_COMMAND_TYPE_NO_RESULT,
-                                       NULL, NULL, NULL, NULL, NULL);
+       tcore_pending_set_request_data(dest_pending, 0, dest_req);
 
-                       tcore_at_prepare_and_send_request(co,
-                                       "AT+XDRV=40,5,2,0,1,0,8,0,1,0,2,0,22",
-                                       NULL, TCORE_AT_COMMAND_TYPE_NO_RESULT,
-                                       NULL, NULL, NULL, NULL, NULL);
-               }
+       /* Send request */
+       ret = _call_request_message(dest_pending, o, ur, on_confirmation_call_set_destination_sound_volume_level, NULL);
+       if (!ret) {
+               err("Failed to send AT-Command request");
+               return TCORE_RETURN_FAILURE;
+       }
 
-               /* Configure modem I2S2 and do the modem routing */
-               tcore_at_prepare_and_send_request(co,
-                               "AT+XDRV=40,4,4,0,0,0,8,0,1,0,2,0,21",
-                               NULL, TCORE_AT_COMMAND_TYPE_NO_RESULT,
-                               NULL, NULL, NULL, NULL, NULL);
+       return TCORE_RETURN_SUCCESS;
+}
 
-               tcore_at_prepare_and_send_request(co,
-                               "AT+XDRV=40,5,3,0,0,0,8,0,1,0,2,0,22",
-                               NULL, TCORE_AT_COMMAND_TYPE_NO_RESULT,
-                               NULL, NULL, NULL, NULL, NULL);
+static TReturn imc_call_set_sound_mute_status(CoreObject *o, UserRequest *ur)
+{
+       struct treq_call_set_sound_mute_status *data = NULL;
+       char *cmd_str = NULL;
+       TReturn ret;
+       TcorePending *pending = NULL;
+       TcoreATRequest *req = NULL;
 
-               tcore_at_prepare_and_send_request(co, "AT+XDRV=40,6,0,4",
-                               NULL, TCORE_AT_COMMAND_TYPE_NO_RESULT,
-                               NULL, NULL, NULL, NULL, NULL);
+       dbg("function entrance");
 
-               tcore_at_prepare_and_send_request(co, "AT+XDRV=40,6,3,0",
-                               NULL, TCORE_AT_COMMAND_TYPE_NO_RESULT,
-                               NULL, NULL, NULL, NULL, NULL);
+       data = (struct treq_call_set_sound_mute_status *) tcore_user_request_ref_data(ur, 0);
 
-               tcore_at_prepare_and_send_request(co, "AT+XDRV=40,6,4,2",
-                               NULL, TCORE_AT_COMMAND_TYPE_NO_RESULT,
-                               NULL, NULL, NULL, NULL, NULL);
+       if (data->status == CALL_SOUND_MUTE_STATUS_ON)
+               cmd_str = g_strdup_printf("%s", "AT+XDRV=40, 8, 0, 0, 0");
+       else if (data->status == CALL_SOUND_MUTE_STATUS_OFF)
+               cmd_str = g_strdup_printf("%s", "AT+XDRV=40, 8, 0, 0, 88");
 
-               tcore_at_prepare_and_send_request(co, "AT+XDRV=40,6,5,2",
-                               NULL, TCORE_AT_COMMAND_TYPE_NO_RESULT,
-                               NULL, NULL, NULL, NULL, NULL);
+       dbg("Request command : [%s]", cmd_str);
 
-               /* amc enable */
-               tcore_at_prepare_and_send_request(co, "AT+XDRV=40,2,4",
-                               NULL, TCORE_AT_COMMAND_TYPE_NO_RESULT,
-                               NULL, NULL, NULL, NULL, NULL);
+       pending = tcore_pending_new(o, 0);
 
-               tcore_at_prepare_and_send_request(co, "AT+XDRV=40,2,3",
-                               NULL, TCORE_AT_COMMAND_TYPE_NO_RESULT,
-                               NULL, NULL, NULL, NULL, NULL);
+       req = tcore_at_request_new(cmd_str, "+XDRV", TCORE_AT_SINGLELINE);
+       if (req == NULL) {
+               tcore_pending_free(pending);
+               g_free(cmd_str);
+               return TCORE_RETURN_FAILURE;
+       }
+       dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
 
-               /* amc route: AMC_RADIO_RX => AMC_I2S1_TX */
-               ret = tcore_at_prepare_and_send_request(co, "AT+XDRV=40,6,0,2",
-                               "+XDRV", TCORE_AT_COMMAND_TYPE_SINGLELINE, NULL,
-                               on_response_set_sound_path, resp_cb_data, NULL, NULL);
+       g_free(cmd_str);
 
-               IMC_CHECK_REQUEST_RET(ret, NULL, "imc_call_set_sound_path");
+       /* Set request data (AT command) to Pending request */
+       tcore_pending_set_request_data(pending, 0, req);
+
+       /* Send request */
+       ret = _call_request_message(pending, o, ur, on_confirmation_call_set_sound_mute_status, NULL);
+       if (!ret) {
+               err("Failed to send AT-Command request");
+               return TCORE_RETURN_FAILURE;
        }
 
-       return ret;
+       dbg("Exit");
+       return TCORE_RETURN_SUCCESS;
 }
 
-/*
- * Operation - Set/Unset mute status.
- *
- * Request -
- * AT-Command: AT+XDRV=<group_id>,<function_id>[,<param_n>]
- * The first command parameter defines the involved driver group.
- * The second command parameter defines a certain function in the selected driver group.
- * Other parameters are dependent on the first two parameters.
- * Nearly all parameters are integer values, also if they are represented by literals.
- * Only very few are strings or
- * hex data strings.
- *
- * Response -
- * +XDRV: <group_id>,<function_id>,<xdrv_result>[,<response_n>]
- * The first response parameter defines the involved driver group.
- * The second response parameter defines the current function in the selected driver group.
- * The third response parameter defines the xdrv_result of the operation.
- * Additional response parameters dependent on the first two parameters.
- */
-static TelReturn imc_call_set_mute(CoreObject *co, gboolean mute, TcoreObjectResponseCallback cb,
-       void *cb_data)
+static TReturn imc_call_set_preferred_voice_subscription(CoreObject *o, UserRequest *ur)
 {
-       ImcRespCbData *resp_cb_data = NULL;
-       gchar *at_cmd;
-       TelReturn ret;
+       struct treq_call_set_preferred_voice_subscription *req_data = NULL;
+       Server *server;
+       Storage *strg = NULL;
+       TReturn ret = TCORE_RETURN_FAILURE;
 
-       dbg("entry");
+       dbg("Entry");
 
-       /* Response callback data */
-       resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
+       server = tcore_plugin_ref_server(tcore_object_ref_plugin(o));
+       strg = tcore_server_find_storage(server, "vconf");
 
-       /* AT - Command */
-       if (mute)
-               at_cmd = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,0");  /*MUTE*/
-       else
-               at_cmd = g_strdup_printf("%s", "AT+XDRV=40,8,0,0,88"); /*UNMUTE*/
+       req_data = (struct treq_call_set_preferred_voice_subscription *) tcore_user_request_ref_data(ur, NULL);
+       dbg("Preferred Subscription: [%d]", req_data->preferred_subs);
 
-       /* Send Request to modem */
-       ret = tcore_at_prepare_and_send_request(co,
-                       at_cmd, "+XDRV",
-                       TCORE_AT_COMMAND_TYPE_SINGLELINE,
-                       NULL,
-                       on_response_imc_call_set_mute, resp_cb_data,
-                       on_send_imc_request, NULL);
-       IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "imc_call_set_mute");
+       /* Update VCONF through Storage - req_data->preferred_subs is aligned to VCONFKEY values */
+       if (tcore_storage_set_int(strg, STORAGE_KEY_TELEPHONY_PREFERRED_VOICE_SUBSCRIPTION, req_data->preferred_subs)) {
+               struct tresp_call_set_preferred_voice_subscription resp_data = {0, };
 
-       g_free(at_cmd);
+               /* Send Response */
+               resp_data.err = CALL_ERROR_NONE;
+               ret = tcore_user_request_send_response(ur,
+                       TRESP_CALL_SET_PREFERRED_VOICE_SUBSCRIPTION,
+                       sizeof(struct tresp_call_set_preferred_voice_subscription), &resp_data);
+               }
 
+       dbg("ret: [0x%x]", ret);
        return ret;
 }
 
-static TelReturn imc_call_get_mute_status(CoreObject *co, TcoreObjectResponseCallback cb,
-       void *cb_data)
+static TReturn imc_call_get_preferred_voice_subscription(CoreObject *o, UserRequest *ur)
 {
-       dbg("entry");
+       struct tresp_call_get_preferred_voice_subscription resp_data = {0, };
+       TReturn ret = TCORE_RETURN_FAILURE;
+       Server *server;
+       Storage *strg = NULL;
 
-       dbg("exit");
-       return TEL_RETURN_OPERATION_NOT_SUPPORTED;
-}
+       dbg("Entry");
 
+       server = tcore_plugin_ref_server(tcore_object_ref_plugin(o));
+       strg = tcore_server_find_storage(server, "vconf");
 
-static TelReturn imc_call_set_sound_recording(CoreObject *co, TelCallSoundRecording sound_rec,
-       TcoreObjectResponseCallback cb, void *cb_data)
-{
-       dbg("entry");
+       /* VCONFKEY is aligned to resp_data->preferred_subs type */
+       resp_data.preferred_subs = tcore_storage_get_int(strg, STORAGE_KEY_TELEPHONY_PREFERRED_VOICE_SUBSCRIPTION);
+       dbg("Preferred Subscription: [%d]", resp_data.preferred_subs);
+
+       resp_data.err = CALL_ERROR_NONE;
+       /* Send Response */
+       ret = tcore_user_request_send_response(ur,
+               TRESP_CALL_GET_PREFERRED_VOICE_SUBSCRIPTION,
+               sizeof(struct tresp_call_get_preferred_voice_subscription), &resp_data);
 
-       dbg("exit");
-       return TEL_RETURN_OPERATION_NOT_SUPPORTED;
+       dbg("ret: [0x%x]", ret);
+       return ret;
 }
 
-static TelReturn imc_call_set_sound_equalization(CoreObject *co, const TelCallSoundEqualization *sound_eq,
-       TcoreObjectResponseCallback cb, void *cb_data)
+#if 0
+static TReturn _set_dtmf_tone_duration(CoreObject *o, UserRequest *ur)
 {
-       dbg("entry");
+       char *cmd_str = NULL;
+       TcorePending *pending = NULL;
+       TcoreATRequest *req = NULL;
+       gboolean ret = FALSE;
+
+       dbg("Entry");
+
+       cmd_str = g_strdup_printf("%s", "AT+VTD=3"); /* ~300 mili secs. +VTD= n, where  n = (0 - 255) * 1/10 secs. */
+       dbg("Request command string: %s", cmd_str);
+
+       /* Create new Pending request */
+       pending = tcore_pending_new(o, 0);
+
+       /* Create new AT-Command request */
+       req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
+       dbg("Command: %s, prefix(if any): %s, Command length: %d", req->cmd, req->prefix, strlen(req->cmd));
+
+       /* Free command string */
+       g_free(cmd_str);
+
+       /* Set request data (AT command) to Pending request */
+       tcore_pending_set_request_data(pending, 0, req);
 
-       dbg("exit");
-       return TEL_RETURN_OPERATION_NOT_SUPPORTED;
+       /* Send request */
+       ret = _call_request_message(pending, o, ur, _on_confirmation_dtmf_tone_duration, NULL);
+       if (!ret) {
+               err("Failed to send AT-Command request");
+               if (ur) {
+                       tcore_user_request_free(ur);
+                       ur = NULL;
+               }
+               return TCORE_RETURN_FAILURE;
+       }
+
+       dbg("Exit");
+       return TCORE_RETURN_SUCCESS;
 }
+#endif
 
 /* Call Operations */
-static TcoreCallOps imc_call_ops = {
-       .dial = imc_call_dial,
+static struct tcore_call_operations call_ops = {
+       .dial = imc_call_outgoing,
        .answer = imc_call_answer,
-       .end = imc_call_end,
-       .send_dtmf = imc_call_send_dtmf,
+       .end = imc_call_release,
        .hold = imc_call_hold,
        .active = imc_call_active,
        .swap = imc_call_swap,
        .join = imc_call_join,
        .split = imc_call_split,
-       .transfer = imc_call_transfer,
        .deflect = imc_call_deflect,
-       .set_active_line = imc_call_set_active_line,
-       .get_active_line = imc_call_get_active_line,
-       .set_volume_info = imc_call_set_volume_info,
-       .get_volume_info = imc_call_get_volume_info,
+       .transfer = imc_call_transfer,
+       .start_cont_dtmf = imc_call_start_cont_dtmf,
+       .stop_cont_dtmf = imc_call_stop_cont_dtmf,
+       .send_burst_dtmf = NULL,
        .set_sound_path = imc_call_set_sound_path,
-       .set_mute = imc_call_set_mute,
-       .get_mute_status = imc_call_get_mute_status,
-       .set_sound_recording = imc_call_set_sound_recording,
-       .set_sound_equalization = imc_call_set_sound_equalization,
+       .set_sound_volume_level = imc_call_set_sound_volume_level,
+       .get_sound_volume_level = NULL,
+       .set_sound_mute_status = imc_call_set_sound_mute_status,
+       .get_sound_mute_status = NULL,
+       .set_sound_equalization = NULL,
+       .set_sound_noise_reduction = NULL,
+       .set_preferred_voice_subscription = imc_call_set_preferred_voice_subscription,
+       .get_preferred_voice_subscription = imc_call_get_preferred_voice_subscription,
 };
 
-gboolean imc_call_init(TcorePlugin *p, CoreObject *co)
+gboolean imc_call_init(TcorePlugin *cp, CoreObject *co_call)
 {
        dbg("Entry");
 
        /* Set operations */
-       tcore_call_set_ops(co, &imc_call_ops);
+       tcore_call_set_ops(co_call, &call_ops, TCORE_OPS_TYPE_CP);
 
        /* Add Callbacks */
-       tcore_object_add_callback(co, "+XCALLSTAT", on_notification_imc_call_status, NULL);
-       tcore_object_add_callback(co, "+CLIP", on_notification_imc_call_clip_info, NULL);
-       tcore_object_add_callback(co, "+CSSU", on_notification_imc_call_ss_cssu_info, NULL);
-       tcore_object_add_callback(co, "+CSSI", on_notification_imc_call_ss_cssi_info, NULL);
+       tcore_object_add_callback(co_call, "+XCALLSTAT", on_notification_call_info, NULL);
+       tcore_object_add_callback(co_call, "+CLIP", on_notification_call_clip_info, NULL);
+
+       dbg("Exit");
 
        return TRUE;
 }
 
-void imc_call_exit(TcorePlugin *p, CoreObject *co)
+void imc_call_exit(TcorePlugin *cp, CoreObject *co_call)
 {
        dbg("Exit");
 }