[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/cc.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/cc.cpp
new file mode 100644
index 0000000..8fea821
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/cc.cpp
@@ -0,0 +1,1408 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#include "cc.h"
+#include <alloca.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cutils/jstring.h>
+#include <stdbool.h>
+#include <glib.h>
+#include <string.h>
+#include <string>
+#include <thread>
+#include "eCall.h"
+
+static int dtmf_volume = 0;
+void *dtmf_handle = NULL;
+
+extern "C" {
+    #include <dtmf.h>
+    #include "mixer_ctrl.h"
+}
+#undef LOG_TAG
+#define LOG_TAG "DEMO_CC"
+
+static speech_status speechStatus = SPEECH_OFF;
+int autoAnswerMode = 0;
+static int inCallRecordMode = 0;
+static call_status inCallstatus = CALL_OFF;
+//int callIndex = 0;
+const char g_card_name[] = "mtk_phonecall";
+/*for speech on*/
+const char g_mixer_name[] = "Speech_on";
+const char g_mixer_name_ecall[] = "Speech_on_ecall";
+const char g_mixer_reset_name[] = "Modem_reset_notify";
+const char g_mixer_name_bt[] = "Speech_on_bt";
+const char g_bt_has_ecnr_name[] = "BT_HAS_ECNR";
+const char g_bt_wbs_name[] = "BT_WBS";
+int g_audio_path = 0; // 0: normal, 1: bt
+int g_bt_has_ecnr_value = 0; // 0: ecnr, 1, no ecnr
+int g_bt_wbs_value = 0; // 0: 8000, 1, 16000
+/*for DL call volume*/
+const char g_mixer_name_volume[] = "DL Call";
+const char g_mixer_name_volume_bt[] = "DL BT";
+
+const char g_DL_mute_name[] = "Speech_DL_mute";
+const char g_UL_mute_name[] = "Speech_UL_mute";
+
+const char *RING_PATH = "/system/etc/tele/ring/ring.wav";
+static bool isRingStart = false;
+
+#if defined(TARGET_PLATFORM_MT2731)||defined(TARGET_PLATFORM_MT2735)
+#define MAX_VOLUME (6)
+#define MIN_VOLUME (0)
+#endif
+
+#ifdef TARGET_PLATFORM_MT2635
+#define MAX_VOLUME (17)
+#define MIN_VOLUME (-23)
+#endif
+
+#define BT_MAX_VOLUME (15)
+#define BT_MIN_VOLUME (0)
+#define DTMF_MAX_VOLUME (36)
+#define DTMF_MIN_VOLUME (0)
+
+int get_call_status(void)
+{
+    return inCallstatus;
+}
+
+void set_audio_path(int path)
+{
+    if ((path != 0) && (path != 1)) {
+        RLOGE("set_audio_path() illegal value %d, we support 0: normal, 1: bt", path);
+        return;
+    }
+
+    g_audio_path = path;
+}
+
+int get_audio_path(void)
+{
+    return g_audio_path;
+}
+
+void set_bt_has_ecnr(int ecnr)
+{
+    if ((ecnr != 0) && (ecnr != 1)) {
+        RLOGE("set_bt_has_ecnr() illegal value %d, we support 0: do ecnr, 1: no ecnr", ecnr);
+        return;
+    }
+
+    g_bt_has_ecnr_value = ecnr;
+}
+
+int get_bt_has_ecnr(void)
+{
+    return g_bt_has_ecnr_value;
+}
+
+void set_bt_wbs(int wbs)
+{
+    if ((wbs < 0) || (wbs > 15)) {
+        RLOGE("set_bt_wbs() illegal value %d, we support 0~15", wbs);
+        return;
+    }
+
+    g_bt_wbs_value = wbs;
+}
+
+int get_bt_wbs(void)
+{
+    return g_bt_wbs_value;
+}
+
+int mixer_init()
+{
+    int ret;
+
+    // only need to set card name once
+    ret = set_card_name(g_card_name);
+    RLOGD("mixer_init(%s) = %d", g_card_name, ret);
+    return ret;
+}
+int mixer_set(int value )
+{
+    int ret;
+
+     //set mixer ctl to om:1 or off:0
+    if(value){
+        ret = set_mixer_ctrl_value_int(isEcallAudioPath() ? g_mixer_name_ecall: g_mixer_name, value);
+        RLOGD("mixer_set(%s) = %d, ret: %d", (isEcallAudioPath() ? g_mixer_name_ecall: g_mixer_name), value, ret);
+    } else {
+        //setEcallAudioPathOn(false);
+        ret = get_mixer_ctrl_value_int(g_mixer_name);
+        RLOGD("mixer_set(get_mixer_ctrl_value_int: %s) = %d", g_mixer_name, ret);
+        if(ret  == 0) {
+            ret = set_mixer_ctrl_value_int(g_mixer_name, value);
+            RLOGD("mixer_set(%s) = %d", g_mixer_name, ret);
+        } else {
+            ret = set_mixer_ctrl_value_int(g_mixer_name_ecall, value);
+            RLOGD("mixer_set(%s) = %d", g_mixer_name_ecall, ret);
+        }
+    }
+
+
+    return ret;
+}
+int mixer_reset_set(int value )
+{
+    int ret;
+
+    // set mixer  to reset:1
+    ret = set_mixer_ctrl_value_int(g_mixer_reset_name, value);
+    RLOGD("mixer_reset_set(%s) = %d", g_mixer_reset_name, ret);
+    return ret;
+}
+int bt_mixer_set(int value)
+{
+    int ret;
+
+    //set mixer ctrl to on:1 or off:0
+    // bt speech
+    int bt_has_ecnr = get_bt_has_ecnr();
+    int bt_wbs = get_bt_wbs();
+    ret = set_mixer_ctrl_value_int(g_bt_has_ecnr_name, bt_has_ecnr);
+    ret = set_mixer_ctrl_value_int(g_bt_wbs_name, bt_wbs);
+    ret = set_mixer_ctrl_value_int(g_mixer_name_bt, value);
+
+    if (ret)
+        RLOGE("set_mixer_ctrl_value_int err: %d", ret);
+    return ret;
+}
+
+int mixer_check(int mix)
+{
+    int ret;
+
+    if (mix == 0) {
+        ret = get_mixer_ctrl_value_int(g_mixer_name);
+    } else if (mix == 1){
+        ret = get_mixer_ctrl_value_int(g_mixer_name_bt);
+    } else {
+        RLOGE("mixer_check wrong mix %d", mix);
+    }
+    RLOGD("The ctrl \"%s\" is set to %d ", g_mixer_name, ret);
+    return ret;
+}
+int mixer_set_volume(int value)
+{
+    int ret;
+    if (get_audio_path() == 0) {
+        ret = set_mixer_ctrl_volume_value(g_mixer_name_volume, value);
+    } else {
+        ret = set_mixer_ctrl_volume_value(g_mixer_name_volume_bt, value);
+    }
+    if (ret)
+        RLOGE("set_mixer_ctrl_volume_value_int err: %d", ret);
+    return ret;
+}
+long int mixer_get_volume()
+{
+    long int vol_value;
+    if (get_audio_path() == 0) {
+        vol_value = get_mixer_ctrl_volume_value(g_mixer_name_volume);
+    } else {
+        vol_value = get_mixer_ctrl_volume_value(g_mixer_name_volume_bt);
+    }
+    RLOGD("The ctrl \"%s\" is set to %d", g_mixer_name_volume, vol_value);
+    return vol_value;
+}
+
+GstElement *pipeline_element;
+GstState gst_cur_state = GST_STATE_NULL;
+static int gst_status = 0;
+
+int GSM_Init(char* filepath)
+{
+    GstElement *pipeline, *source, *mux, *encoder, *sink;
+    RLOGD("[GSM]GSM Init Start!");
+    /* Initialisation */
+    gst_init (NULL, NULL);
+
+    pipeline = gst_pipeline_new ("3gppmux-test");
+    source   = gst_element_factory_make ("pulsesrc",       "file-source");
+    encoder  = gst_element_factory_make ("faac",           "encoder");
+    mux      = gst_element_factory_make ("3gppmux",        "muxer");
+    sink     = gst_element_factory_make ("filesink",       "output");
+
+    g_object_set(mux, "fragment-duration", 100, NULL);
+    g_object_set(sink, "location", filepath, NULL);
+
+    if (!pipeline || !source || !encoder || !mux || !sink) {
+        if(pipeline) {
+            gst_object_unref (GST_OBJECT (pipeline));
+            pipeline = NULL;
+        }
+        if(source) {
+            gst_object_unref (GST_OBJECT (source));
+            source = NULL;
+        }
+        if(encoder) {
+            gst_object_unref (GST_OBJECT (encoder));
+            encoder = NULL;
+        }
+        if(mux) {
+            gst_object_unref (GST_OBJECT (mux));
+            mux = NULL;
+        }
+        if(sink) {
+            gst_object_unref (GST_OBJECT (sink));
+            sink = NULL;
+        }
+        RLOGE ("[GSM]One element could not be created. Exiting");
+        return -1;
+    }
+
+    gst_bin_add_many (GST_BIN (pipeline), source, encoder, mux, sink, NULL);
+    gst_element_link_many (source, encoder, mux, sink, NULL);
+
+    pipeline_element = pipeline;
+    gst_status = 1; //initial done
+    RLOGD("[GSM]GSM Init Done!");
+    return 0;
+}
+
+int GSM_Start(void)
+{
+    RLOGD("[GSM]GSM Start start!");
+    if(gst_status == 2)
+        return 0;
+
+    if(gst_status == 1 || gst_status ==3) {
+        GstStateChangeReturn ret = gst_element_set_state (pipeline_element, GST_STATE_PLAYING);
+
+        RLOGD("[GSM]Running... return: %d", ret);
+        //g_main_loop_run (gst_loop);
+        gst_status = 2; //start done
+    } else {
+        return -1;
+    }
+    RLOGD("[GSM]GSM Start End!");
+    return 0;
+}
+
+int GSM_Stop()
+{
+    RLOGD("[GSM]GSM Stop Start!");
+    if (gst_status == 4)
+        return 0;
+
+    if(gst_status == 2 || gst_status == 3) {
+    /* Out of the main loop, clean up nicely */
+        gboolean isSend = gst_element_send_event (pipeline_element, gst_event_new_eos ());
+        GstStateChangeReturn ret = gst_element_set_state (pipeline_element, GST_STATE_NULL);
+        RLOGD("[GSM]Returned, stopping playback. ret: %d, isSend: %d", ret, isSend);
+        gst_status = 4;
+    } else {
+        return -1;
+    }
+    RLOGD("[GSM]GSM Stop End!");
+    return 0;
+}
+
+int GSM_Close()
+{
+    RLOGD("[GSM]Deleting pipeline");
+    gst_object_unref (GST_OBJECT (pipeline_element));
+    gst_deinit ();
+    gst_status = 0;
+    RLOGD("[GSM]GSM Close Done!");
+    return 0;
+}
+/*cmd:1, address,
+*2, clirMode,
+*3, if present, uusinfo.type
+*4, as above, uusinfo.Dcs
+*5, as above, uusinfo.userdatalength
+*6, as above, uusinfo.UserData
+*/
+//RIL_REQUEST_DIAL
+int dial(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos =  p.dataPosition();
+
+    if (argc < 3 || argv[1]==NULL) {
+        //add log msg
+        free(pRI);
+        return -1;
+    }
+    //address;
+    writeStringToParcel(p, (const char *)argv[1]);
+    //clirMode
+    if (argc >=2) {
+    p.writeInt32(atoi(argv[2]));
+
+    if (argc == 7 && argv[3] != NULL
+        && argv[4] != NULL && argv[5] != NULL
+        && argv[6] != NULL ) {
+        p.writeInt32(1); // UUS information is present
+        p.writeInt32(atoi(argv[3]));
+        p.writeInt32(atoi(argv[4]));
+        p.writeByteArray((size_t)atoi(argv[5]),(uint8_t*)argv[6]);
+    } else {
+        p.writeInt32(0); // UUS information is absent
+    }
+    }
+    p.setDataPosition(pos);
+    setEcallAudioPathOn(false);
+    pRI->pCI->dispatchFunction(p, pRI);
+    inCallstatus = CALL_ON;
+    return 0;
+}
+#if 0 //not need user setup
+//RIL_REQUEST_OEM_HOOK_STRINGS
+int invokeOemRilRequestStrings(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    RLOGD("OEM_HOOK_STRINGS: p1->\"%s\",p2->\"%s\"",argv[1],argv[2]);
+    p.writeInt32(2);
+    writeStringToParcel(p, (const char *)argv[1]);
+    writeStringToParcel(p, "\"\"");//(const char *)argv[2]);
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+#endif
+
+extern void ARspRequest (int request,RIL_SOCKET_ID socket_id);
+//RIL_REQUEST_SET_AUDIO_PATH
+/*cmd:1, speech mode,
+*2, bt_has_ecnr
+*3, bt_wbs
+*/
+int setAudioPath(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if (argc < 1) {
+        free(pRI);
+        RLOGE("set bt mode need bt_has_encr and bt_wbs");
+        return -1;
+    }
+
+    int temp_audio_path = atoi(argv[1]);
+    int bt_has_ecnr;
+    int bt_wbs;
+    int current_audio_path = get_audio_path();
+    RLOGD("setAudioPath enter");
+    if ((temp_audio_path != 0) && (temp_audio_path != 1)) {
+        RLOGE("audio path illegal %d, only support 0 and 1", temp_audio_path);
+        return -1;
+    }
+    set_audio_path(temp_audio_path);
+    RLOGD("set audio path to %d, current audio path is %d", temp_audio_path, current_audio_path);
+    if (temp_audio_path == 1) {
+        /* bt speech need BT_HAS_ECNR and BT_WBS */
+        bt_has_ecnr = atoi(argv[2]);
+        bt_wbs = atoi(argv[3]);
+        set_bt_has_ecnr(bt_has_ecnr);
+        set_bt_wbs(bt_wbs);
+        RLOGD("set bt_has_ecnr %d, bt_wbs %d", bt_has_ecnr, bt_wbs);
+    }
+    if ((current_audio_path != temp_audio_path)
+        && (get_call_status() == CALL_ON)) {
+        if (current_audio_path == 0) {
+            if (getSpeechStatus() == NORMAL_SPEECH_ON) {
+                RLOGD("normal speech off then bt speech on");
+                mixer_set(0);
+                setSpeechAndStatus(2);
+            }
+        } else {
+            if (getSpeechStatus() == BT_SPEECH_ON) {
+                RLOGD("bt speech off then normal speech on");
+                bt_mixer_set(0);
+                setSpeechAndStatus(1);
+            }
+        }
+    }
+    if (pRI != NULL) {
+        free(pRI);
+    }
+
+    RLOGD("setAudioPath done");
+    return 0;
+}
+
+
+//RIL_REQUEST_HANGUP
+int hangupConnection(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]));
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_FORCE_RELEASE_CALL
+int forceReleaseCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]));
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_SEPARATE_CONNECTION
+int separateConnection(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]));
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_DTMF
+//RIL_REQUEST_DTMF_START
+int sendDtmf(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    int number;
+    size_t pos = p.dataPosition();
+    char * c_num = NULL;
+
+    c_num = argv[1];
+    if (c_num == NULL) {
+        free(pRI);
+        return -1;
+    }
+    number = int(c_num[0] - '0');
+    if(number == -6)
+       number = 10;
+    if(number == -13)
+       number = 11;
+    RLOGD("DTMF input number is %s-->%d",c_num,number);
+    if ( number < 0 || number > 15 ) {
+        RLOGE("DTMF input number error");
+        free(pRI);
+        return -1;
+    }
+
+    writeStringToParcel(p, (const char *)argv[1]);
+    p.setDataPosition(pos);
+
+    dtmf_stop(dtmf_handle);
+    gint time_ms = 500;
+    if (pRI->pCI->requestNumber == RIL_REQUEST_DTMF_START) {
+        time_ms = 0;
+    }
+    RLOGD("request: %d, time_ms = %d", pRI->pCI->requestNumber, time_ms);
+    dtmf_handle = dtmf_start(number, time_ms, dtmf_volume, NULL);
+    pRI->pCI->dispatchFunction(p, pRI);
+    if (dtmf_handle == NULL)
+        RLOGE("[DTMF] dtmf_start return NULL!");
+    return 0;
+}
+
+//RIL_REQUEST_UDUB
+int rejectCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_ANSWER
+int acceptCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    inCallstatus = CALL_ON;
+    return 0;
+}
+
+//RIL_REQUEST_HANGUP_ALL
+int hangupAll(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_CONFERENCE
+int conference(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND
+int hangupWaitingOrBackground(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE
+int switchWaitingOrHoldingAndActive(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND
+int hangupForegroundResumeBackground(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_EXPLICIT_CALL_TRANSFER
+int explicitCallTransfer(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_ADD_IMS_CONFERENCE_CALL_MEMBER
+int addImsConferenceCallMember(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.writeInt32(3);
+    writeStringToParcel(p, (const char *)argv[1]);//confCallId
+    writeStringToParcel(p, (const char *)argv[2]);//address
+    writeStringToParcel(p, (const char *)argv[3]);//CallIdToAdd
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_REMOVE_IMS_CONFERENCE_CALL_MEMBER
+int removeImsConferenceCallMember(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    p.writeInt32(3);
+    writeStringToParcel(p, (const char *)argv[1]);//confCallId
+    writeStringToParcel(p, (const char *)argv[2]);//address
+    writeStringToParcel(p, (const char *)argv[3]);//CallIdToRemove
+
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_CONFERENCE_DIAL
+//argv[1]:DialMethod
+//argv[2]:ParticipantsNumber
+//argv[2+ParticipantsNumber]:addresss
+//argv[2+ParticipantsNumber+1]:clir
+int conferenceDial(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+    int ParticipantsNumber,i;
+
+    if( argc < 3 ) {
+        free(pRI);
+        RLOGE("Error: conference Dial parameter is error!");
+        return -1;
+    }
+
+    ParticipantsNumber = atoi(argv[2]);
+
+    if( argc < (ParticipantsNumber+3) ) {
+        free(pRI);
+        RLOGE("Error: Dial With SIP URI parameter is error! \
+            argc is %d, and need parameter %d",argc,(ParticipantsNumber+3));
+        return -1;
+    }
+
+    p.writeInt32((ParticipantsNumber+3));
+    writeStringToParcel(p, (const char *)argv[1]); //DialMethod
+    writeStringToParcel(p, (const char *)argv[2]); //ParticipantsNumber
+    for( i=0; i<ParticipantsNumber; i++ ){ //address
+        writeStringToParcel(p, (const char *)argv[3+i]);
+    }
+    writeStringToParcel(p, (const char *)argv[3+ParticipantsNumber]);//clir
+
+    p.setDataPosition(pos);
+    setEcallAudioPathOn(false);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_DIAL_WITH_SIP_URI
+int dialWithSipUri(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    if (argc < 3 || argv[1]==NULL) {
+        free(pRI);
+        return -1;
+    }
+
+    writeStringToParcel(p, (const char *)argv[1]);//address
+    /* for compatibility of test script, still receive clirMode and UUS,
+       but don't send them to libvendor-ril */
+#if 0
+    p.writeInt32(atoi(argv[2]));//clirMode
+    p.writeInt32(0); // UUS information is absent
+#endif
+
+    p.setDataPosition(pos);
+    setEcallAudioPathOn(false);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_HOLD_CALL
+int holdCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    if (argc < 2 || argv[1]==NULL) {
+        free(pRI);
+        return -1;
+    }
+
+    //callIDToHold
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]));
+
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+//RIL_REQUEST_RESUME_CALL
+int resumeCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos = p.dataPosition();
+
+    if (argc < 2 || argv[1]==NULL) {
+        free(pRI);
+        return -1;
+    }
+
+    //callIDToResume
+    p.writeInt32(1);
+    p.writeInt32(atoi(argv[1]));
+
+    p.setDataPosition(pos);
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+int getCurrentCalls(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+int autoAnswerCall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(argc < 2) {
+        RLOGW("[error],set auto answer call parameter error!");
+        free(pRI);
+        return 0;
+    }
+    //need add lock to pretect.
+    autoAnswerMode = atoi(argv[1]) ? 1 : 0;
+    RLOGD("SetAutoAnserMode is %s",autoAnswerMode ? "On" :"Off");
+    if(pRI) {
+        free(pRI);
+    }
+    return 0;
+}
+
+int inCallRecord(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    int recordEnable = 0;
+    char* filepath = NULL;
+    if(inCallstatus == CALL_OFF || speechStatus == SPEECH_OFF) {
+        RLOGW("[warning],not in calling status. Can't do record!");
+        return 0;
+    }
+
+    if(argc < 3) {
+        free(pRI);
+        RLOGW("[error],inCallRecord parameter error!");
+        return 0;
+    }
+
+    recordEnable = atoi(argv[1]) ? 1 : 0;
+    RLOGD("InCall record %s!",recordEnable ? "enable" : "disable");
+    filepath = argv[2];
+    RLOGD("InCall record file path as \'%s\'",filepath);
+
+   if (recordEnable == 1) {//enable record
+       RLOGD("start GSM!");
+       if(-1 != GSM_Init(filepath) && -1 != GSM_Start()) {
+            inCallRecordMode = 1;
+            RLOGW("inCallRecord Start OK!");
+       }else{
+            inCallRecordMode = 0;
+            RLOGW("[error],inCallRecord Start fail!");
+      }
+    } else { //disable record
+        if (inCallRecordMode == 1) {
+            if(!(-1 != GSM_Stop() && -1 != GSM_Close()))
+                RLOGW("[error],inCallRecord fail!");
+
+            inCallRecordMode = 0;
+        }
+    }
+
+   if(pRI != NULL) {
+       free(pRI);
+   }
+    return 0;
+}
+
+int StopRecord()
+{
+    RLOGD("After Handup, stop record! Before Record is %s",inCallRecordMode ? "Enable" : "Disable");
+    if (inCallRecordMode == 1) {
+         if(!(-1 != GSM_Stop() && -1 != GSM_Close()))
+            RLOGW("[error],inCallRecord fail!");
+
+         inCallRecordMode = 0;
+        /*From GSM report stop_record to PulseAudio send record_off  need 15ms. so after stop record delay 30ms*/
+         usleep(30*1000);
+    }
+    return 0;
+}
+
+int setSpeechVolume(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    int setValue = 0;
+    RLOGD("setSpeechVolume start!");
+
+    if(argc < 2) {
+        free(pRI);
+        RLOGW("Warning: no set volume value!");
+        return -1;
+    }
+
+    setValue = atoi(argv[1]);
+    RLOGD("set Speech Volume value is %d!",setValue);
+    if (get_audio_path() == 0) {
+        if(setValue < MIN_VOLUME || setValue > MAX_VOLUME) {
+            RLOGW("Warning: set volume value is over-range!");
+            return -1;
+        }
+    } else {
+        if(setValue < BT_MIN_VOLUME || setValue > BT_MAX_VOLUME) {
+            RLOGW("Warning: set bt volume value is over-range!");
+            return -1;
+        }
+    }
+    //paramter is from 1 to 7
+    mixer_set_volume(setValue);
+    free(pRI);
+    return 0;
+}
+int setDtmfVolume(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    int setValue = 0;
+    RLOGD("setDtmfVolume start!");
+
+    if(argc < 2) {
+        RLOGW("Warning: no set volume value!");
+        free(pRI);
+        return -1;
+    }
+
+    setValue = atoi(argv[1]);
+    RLOGD("set dtmf Volume value is %d!",setValue);
+    if(setValue < DTMF_MIN_VOLUME || setValue > DTMF_MAX_VOLUME) {
+        RLOGW("Warning: set volume value is over-range!");
+        free(pRI);
+        return -1;
+    }
+    //paramter is from 0 to 36
+    dtmf_volume = setValue;
+
+    free(pRI);
+    return 0;
+}
+
+speech_status getSpeechStatus()
+{
+    return speechStatus;
+}
+
+void setSpeechAndStatus(int value)
+{
+    RLOGD("setSpeechAndStatus value: %d, speechStatus: %d", value, speechStatus);
+    if (value == 1) {
+        speechStatus = NORMAL_SPEECH_ON;
+        mixer_set(1);
+    } else if (value == 2) {
+        speechStatus = BT_SPEECH_ON;
+        bt_mixer_set(1);
+    } else if (value == 0) {
+        speechStatus == BT_SPEECH_ON ? bt_mixer_set(0) : mixer_set(0);
+        speechStatus = SPEECH_OFF;
+    } else {
+        RLOGE("set speech value is invaild!\n");
+    }
+}
+//RIL_REQUEST_EMERGENCY_DIAL
+/*cmd:1, address,
+*2, clirMode,
+*3, if present, uusinfo.type
+*4, as above, uusinfo.Dcs
+*5, as above, uusinfo.userdatalength
+*6, as above, uusinfo.UserData
+*/
+int emergencyDial(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+  android::Parcel p;
+  size_t pos = p.dataPosition();
+
+  if (argc < 3 || argv[1] == NULL)
+  {
+    //add log msg
+    free(pRI);
+    return -1;
+  }
+  //address;
+  writeStringToParcel(p, (const char *) argv[1]);
+  //clirMode
+  if (argc >= 2)
+  {
+    p.writeInt32(atoi(argv[2]));
+
+    if (argc == 7&& argv[3] != NULL
+    && argv[4] != NULL && argv[5] != NULL
+    && argv[6] != NULL)
+    {
+      p.writeInt32(1); // UUS information is present
+      p.writeInt32(atoi(argv[3]));
+      p.writeInt32(atoi(argv[4]));
+      p.writeByteArray((size_t) atoi(argv[5]), (uint8_t*) argv[6]);
+    } else
+    {
+      p.writeInt32(0); // UUS information is absent
+    }
+  }
+  p.setDataPosition(pos);
+  setEcallAudioPathOn(false);
+  pRI->pCI->dispatchFunction(p, pRI);
+  return 0;
+}
+//RIL_REQUEST_SET_ECC_SERVICE_CATEGORY
+int setEccServiceCategory(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+  android::Parcel p;
+  size_t pos =  p.dataPosition();
+
+  //if ( getSpeechStatus() != 1)
+  //    setSpeechAndStatus(1);
+
+  p.writeInt32(1);
+  p.writeInt32(atoi(argv[1]));
+  p.setDataPosition(pos);
+  pRI->pCI->dispatchFunction(p, pRI);
+  return 0;
+}
+//RIL_REQUEST_SET_ECC_LIST
+/* argv[1]: list number
+   argv[2+i]: ECC string
+   argv[3+i]: Categroy
+   argv[4+i]: Conditon
+*/
+int setEccList(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos =  p.dataPosition();
+    int num = 0;
+    //if ( getSpeechStatus() != 1)
+    //    setSpeechAndStatus(1);
+    if(argc < 3) {
+        RLOGE("%s parameter error!",__func__);
+        free(pRI);
+        return -1;
+    }
+    num = atoi(argv[1]);
+    RLOGD("list number is %d, argc is %d",num, argc);
+    if((num == 0) || ((argc-2) < num*3)) {
+        RLOGE("%s parameter error!",__func__);
+        free(pRI);
+        return -1;
+    }
+
+    p.writeInt32(num*3);
+    for(int i = 0; i < num; i++){
+        writeStringToParcel(p, (const char *)argv[2+i*3+0]); //ECC
+        writeStringToParcel(p, (const char *)argv[2+i*3+1]); //Category
+        writeStringToParcel(p, (const char *)argv[2+i*3+2]); //Condition
+        RLOGD("list[%d],ECC is %s, Category is %s, Condition is %s!",i+1,argv[2+i*3+0],argv[2+i*3+1],argv[2+i*3+2]);
+    }
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_SET_ECC_NUM
+int setEccNum(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    size_t pos =  p.dataPosition();
+    int num = 0;
+
+    if(argc < 2 || argc > 3) {
+        RLOGE("%s parameter error!",__func__);
+        free(pRI);
+        return -1;
+    }
+
+    num = (argc > 2)?2:1;
+
+    p.writeInt32(num);
+    writeStringToParcel(p, (const char *)argv[1]); //ECC number with card
+    RLOGD("Set ECC number with card: %s",argv[1]);
+    if (num>1){
+        writeStringToParcel(p, (const char *)argv[2]); //ECC number without card
+        RLOGD("Set ECC number without card: %s",argv[2]);
+    }
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+//RIL_REQUEST_GET_ECC_NUM
+int getEccNum(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+int handleECCNumResponse(const void *data, int datalen, RIL_SOCKET_ID socket_id){
+    if (data == NULL || datalen <= 0){
+        RLOGE("%s parameter error!",__func__);
+        return -1;
+    }
+
+    printf("[ECC NUM][Slot%d] %s\n", socket_id, (const char*)data);
+    RLOGD("[ECC NUM][Slot%d] %s\n", socket_id, (const char*)data);
+    return 0;
+}
+
+
+//RIL_REQUEST_LAST_CALL_FAIL_CAUSE
+int getLastCallFailCause(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+    if(argc != 1)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        free(pRI);
+        return -1;
+    }
+    RLOGD("getLastCallFailCause %d: " , pRI->pCI->requestNumber);
+    android::Parcel p;
+
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+
+#ifdef C2K_SUPPORT
+static bool is12Key(char c) {
+  return (c >= '0' && c <= '9') || c == '*' || c == '#';
+}
+
+//RIL_REQUEST_CDMA_BURST_DTMF
+int sendBurstDtmf(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+  if(argc < 4) {
+      RLOGE("%s parameter error!",__func__);
+      free(pRI);
+      return -1;
+  }
+  int number;
+  char * c_num = NULL;
+
+  c_num = argv[1];
+  if (c_num == NULL) {
+      free(pRI);
+      return -1;
+  }
+  number = int(c_num[0] - '0');
+  if(number == -6)
+     number = 10;
+  if(number == -13)
+     number = 11;
+  RLOGD("DTMF input number is %s-->%d",c_num,number);
+  if ( number < 0 || number > 15 ) {
+      RLOGE("DTMF input number error");
+      free(pRI);
+      return -1;
+  }
+  dtmf_stop(dtmf_handle);
+  dtmf_handle = dtmf_start(number, 500, dtmf_volume, NULL);
+  android::Parcel p;
+  size_t pos =  p.dataPosition();
+  p.writeInt32(3);
+  writeStringToParcel(p, c_num);
+  writeStringToParcel(p, argv[2]);
+  writeStringToParcel(p, argv[3]);
+  p.setDataPosition(pos);
+  pRI->pCI->dispatchFunction(p, pRI);
+  if (dtmf_handle == NULL)
+      RLOGE("[DTMF] dtmf_start return NULL!");
+  return 0;
+}
+
+//RIL_REQUEST_CDMA_FLASH
+int sendCDMAFeatureCode(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI){
+    if(argc > 2)
+    {
+        RLOGD("the peremeters numbers isn't right , so return");
+        free(pRI);
+        return -1;
+    }
+    android::Parcel p;
+    size_t pos =  p.dataPosition();
+    writeStringToParcel(p, ((argc == 1) ? "" : argv[1]));
+    p.setDataPosition(pos);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}
+#endif /*C2K_SUPPORT*/
+
+static int mixer_set_mute(int path, int value)
+{
+    RLOGD("mixer_set_mute path: %d , value: %d", path, value);
+    int ret;
+    /* DL:0 UL:1 */
+    if (path == 0) {
+        ret = set_mixer_ctrl_value_int(g_DL_mute_name, value);
+    } else {
+        ret = set_mixer_ctrl_value_int(g_UL_mute_name, value);
+    }
+    if (ret) {
+        RLOGE("set_mixer_ctrl_volume_value_int err: %d", ret);
+    }
+    return ret;
+}
+
+static long int mixer_get_mute(int path)
+{
+    long int is_mute;
+
+    /* DL:0 UL:1 */
+    if (path == 0) {
+        is_mute = get_mixer_ctrl_value_int(g_DL_mute_name);
+        RLOGD("The ctrl \"%s\" is set to %d", g_DL_mute_name, is_mute);
+    } else {
+        is_mute = get_mixer_ctrl_value_int(g_UL_mute_name);
+        RLOGD("The ctrl \"%s\" is set to %d", g_UL_mute_name, is_mute);
+    }
+
+    return is_mute;
+}
+
+int setCallMute(bool mute) {
+    RLOGD("setCallMute: %d", mute);
+    return mixer_set_mute(1, (mute ? 1: 0));
+}
+
+int getCallMute() {
+    long int cc_mute = mixer_get_mute(1);
+    RLOGD("getCallMute: %d", cc_mute);
+    return cc_mute;
+}
+
+void resetMute() {
+    if (getCallMute() > 0) {
+        setCallMute(false);
+    }
+}
+
+void callRing(RIL_SOCKET_ID soc_id)
+{
+    resetMute();
+    if (autoAnswerMode) {
+        RLOGD("Auto Answer MT Call!");
+        android::requestAnswer(soc_id);
+    }
+    return;
+}
+
+void autoAnswerForCdma(RIL_SOCKET_ID socket_id)
+{
+    resetMute();
+    if (autoAnswerMode) {
+        RLOGD("Auto Answer MT Call for cdma");
+        ARspRequest(RIL_REQUEST_CDMA_FLASH, socket_id);
+    }
+    return;
+}
+
+//void callStateChange(void)
+void speechonoff(int callnum)
+{
+    static int callIndex = 0;
+    RLOGD("callnum = %d, Call State Change then judge speech on/off!", callnum);
+    callIndex = callnum;
+    if( callIndex == 1 && speechStatus == SPEECH_OFF) {  //speech on
+        //RLOGD("DemoAPP Call shell command (pactl set-card-profile 0 phonecall)");
+        //system("pactl set-card-profile 0 phonecall");
+        //RLOGD("DemoAPP Call shell command end");
+        if (get_audio_path() == 0) {
+            mixer_set(1);
+            speechStatus = NORMAL_SPEECH_ON;
+        } else {
+            bt_mixer_set(1);
+            speechStatus = BT_SPEECH_ON;
+        }
+        inCallstatus = CALL_ON;
+        RLOGD("[speech]: set on");
+        sendCallMsg(true); //for Power Manager test
+    } else if (callIndex == 0
+               && (speechStatus == NORMAL_SPEECH_ON
+                   || speechStatus == BT_SPEECH_ON)) { //speech off
+        StopRecord();
+        sendCallMsg(false); // for Power Manager test.
+        dtmf_stop(dtmf_handle);
+        if (speechStatus == NORMAL_SPEECH_ON) {
+            mixer_set(0);
+        } else {
+            bt_mixer_set(0);
+        }
+        //RLOGD("DemoAPP Call shell command (pactl set-card-profile 0 HiFi)");
+        //system("pactl set-card-profile 0 HiFi");
+        //RLOGD("DemoAPP Call(pactl set-card-profile 0 HiFi) command end");
+        speechStatus = SPEECH_OFF;
+        inCallstatus = CALL_OFF;
+        resetMute();
+        RLOGD("[speech]: set off");
+    } else {
+        RLOGD("callIndex is %d, speechStatus is %d.",callIndex, speechStatus);
+    }
+
+    return;
+}
+
+//RIL_REQUEST_SET_MUTE
+int setMute(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(pRI) {
+        free(pRI);
+    }
+    bool mute = (atoi(argv[1]) > 0) ? true: false;
+    RLOGD("set mute %s", ((atoi(argv[1]) > 0) ? "on": "off"));
+    int ret = setCallMute(mute);
+    std::string str;
+    if(ret) {
+        str.append("set mute fail, please try agian\n");
+    } else {
+        str.append("set mute ");
+        str.append((atoi(argv[1]) > 0) ? "on ": "off ");
+        str.append("success\n");
+    }
+    android::emResultNotify(str.c_str());
+    return 0;
+}
+
+//RIL_REQUEST_GET_MUTE
+int getMute(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    if(pRI) {
+        free(pRI);
+    }
+    std::string str;
+    int mute = getCallMute();
+    //TBC -200 fail status
+    if(mute == -200) {
+        str.append("get mute state fail, please check whether does call exsit. \n");
+    } else {
+        str.append("current mute state is ");
+        str.append((mute == 1) ? "on\n" : "off\n");
+    }
+    android::emResultNotify(str.c_str());
+    return 0;
+}
+
+//RIL_UNSOL_SIP_CALL_PROGRESS_INDICATOR
+int handleUnsolSipCallProgressInd(const void *response, size_t responselen) {
+    if (response == NULL && responselen != 0) {
+        RLOGE("handleUnsolSipCallProgressInd: invalid response: NULL");
+        return -1;
+    }
+    if (responselen % sizeof(char *) != 0) {
+        RLOGE("handleUnsolSipCallProgressInd: invalid response length %d expected multiple of %d\n",
+            (int)responselen, (int)sizeof(char *));
+        return -1;
+    }
+
+    int numStrings = responselen / sizeof(char *);
+    RLOGD("handleUnsolSipCallProgressInd: numStrings: %d", numStrings);
+    if(numStrings < 6) {
+        RLOGE("handleUnsolSipCallProgressInd: invalid response numbers: NULL");
+        return -1;
+    }
+    char **p_cur = (char **) response;
+    //<call_id>,<dir>,<SIP_msg_type>,<method>,<response_code>,"<reason_text>"
+    //if response == <id>, 1, 0, 4, 0, "call completed elsewhere" ,printf "SIP CANCEL:Call completed elsewhere"
+    //if response == <id>, 1, 0, 4, 0, " declined" ,printf "SIP CANCEL:declined"
+    std::string call_id(p_cur[0]);
+    std::string dir(p_cur[1]);
+    std::string sip_msg_type(p_cur[2]);
+    std::string method(p_cur[3]);
+    std::string resp_code(p_cur[4]);
+    std::string reason_text(p_cur[5]);
+    RLOGD("%s, call_id=%s, dir=%s, sip_msg_type=%s, method=%s, resp_code=%s, reason_text=%s",
+            __FUNCTION__, call_id.c_str(),dir.c_str(),sip_msg_type.c_str(),method.c_str(),resp_code.c_str(), reason_text.c_str());
+    printf("call_id=%s, dir=%s, sip_msg_type=%s, method=%s, resp_code=%s, reason_text=%s\n",
+            call_id.c_str(),dir.c_str(),sip_msg_type.c_str(),method.c_str(),resp_code.c_str(), reason_text.c_str());
+
+    if ((std::stoi(dir) == 1) && (std::stoi(sip_msg_type) == 0)
+            && (std::stoi(method) == 4) && (std::stoi(resp_code) == 0)) {
+        std::string msg("SIP CANCEL:");
+        msg.append(reason_text);
+        printf("%s", msg.c_str());
+    }
+    return 0;
+}
+
+//RIL_UNSOL_CALL_INFO_INDICATION
+int handleUnsolCallInfoInd(const void *response, size_t responselen, RIL_SOCKET_ID socket_id) {
+    int numStrings = 0;
+
+    if (response == NULL && responselen != 0) {
+        RLOGE("[slot%d]handleUnsolCallInfoInd, invalid response: NULL", socket_id);
+        return -1;
+    }
+    if (responselen % sizeof(char *) != 0) {
+        RLOGE("[slot%d]handleUnsolCallInfoInd: invalid response length %d expected multiple of %d\n",socket_id,
+            (int)responselen, (int)sizeof(char *));
+        return -1;
+    }
+
+    if (response == NULL) {
+        RLOGE("[slot%d]handleUnsolCallInfoInd, length and invalid response : NULL", socket_id);
+    } else {
+        char **p_cur = (char **) response;
+
+        numStrings = responselen / sizeof(char *);
+        RLOGD("[slot%d]handleUnsolCallInfoInd: numStrings: %d",socket_id, numStrings);
+        if(numStrings < 9) {
+            RLOGE("[slot%d]handleUnsolCallInfoInd, invalid numStrings(%d) < 9, no pau value : numStrings", socket_id);
+            return -1;
+        } else {
+            RLOGD("[slot%d]handleUnsolCallInfoInd(): pau: %s", socket_id, p_cur[8]);
+            printf("[slot%d]handleUnsolCallInfoInd(): pau: %s\n", socket_id, p_cur[8]);
+        }
+    }
+    return 0;
+}
+
+static void playtone(int start) {
+    RLOGD("playtone(): start: %d, isRingStart %d", start, isRingStart);
+    char cmd[256];
+    sprintf(cmd, "aplay %s", RING_PATH);
+    system(cmd);
+    isRingStart = false;
+}
+
+//RIL_UNSOL_RINGBACK_TONE
+int handleRingbackTone(const void *response, size_t responselen, RIL_SOCKET_ID socket_id) {
+
+    int numInts = 0;
+
+    if (response == NULL && responselen != 0) {
+        RLOGE("[slot%d]handleRingbackTone, invalid response: NULL", socket_id);
+        return -1;
+    }
+    if (responselen % sizeof(int) != 0) {
+        RLOGE("[slot%d]handleRingbackTone: invalid response length %d expected multiple of %d\n",socket_id,
+            (int)responselen, (int)sizeof(char *));
+        return -1;
+    }
+
+    int *p_int = (int *) response;
+
+    numInts = responselen / sizeof(int);
+    RLOGD("[slot%d]handleRingbackTone: numInts: %d",socket_id, numInts);
+    if(numInts < 1) {
+        RLOGE("[slot%d]handleRingbackTone, invalid numStrings(%d) < 1", socket_id);
+        return -1;
+    } else {
+        int start = p_int[0];
+        RLOGD("[slot%d]handleRingbackTone(): start: %d, isRingStart %d", socket_id, start, isRingStart);
+        printf("[slot%d]handleRingbackTone(): start: %d, isRingStart %d\n", socket_id, start, isRingStart);
+#if defined(TARGET_PLATFORM_MT2731)
+        if(start && (!isRingStart)) {
+            isRingStart = true;
+            std::thread t(playtone, start);
+            t.detach();
+        } else if((!start) && isRingStart) {
+            isRingStart = false;
+            system("kill $(ps aux | grep '[a]play' | awk '{print $2}')");
+        }
+#endif
+    }
+    return 0;
+}
+
+//RIL_REQUEST_DTMF_STOP
+int stopDtmf(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+    android::Parcel p;
+
+    dtmf_stop(dtmf_handle);
+    pRI->pCI->dispatchFunction(p, pRI);
+    return 0;
+}