| // SPDX-License-Identifier: MediaTekProprietary | 
 | /* 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> | 
 |  | 
 | static int dtmf_volume = 0; | 
 | void *dtmf_handle = NULL; | 
 |  | 
 | extern "C" { | 
 |     #include <dtmf.h> | 
 |     #include "mixer_ctrl.h" | 
 | } | 
 | #undef LOG_TAG | 
 | #define LOG_TAG "MULTI_USER_CC" | 
 |  | 
 | static speech_status speechStatus = SPEECH_OFF; | 
 | static 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_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"; | 
 |  | 
 | #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); | 
 |     if (ret) | 
 |         RLOGE("set_card_name err: %d", ret); | 
 |     return ret; | 
 | } | 
 | int mixer_set(int value ) | 
 | { | 
 |     int ret; | 
 |  | 
 |      //set mixer ctl to om:1 or off:0 | 
 |     ret = set_mixer_ctrl_value_int(g_mixer_name, value); | 
 |     if (ret) | 
 |         RLOGE("set_mixer_ctrl_value_int g_mixer_name err: %d", 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); | 
 |     if (ret) | 
 |         RLOGE("set_mixer_ctrl_value_int g_mixer_reset_name err: %d", 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); | 
 |         ret = -1; | 
 |     } | 
 |     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); | 
 |     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 | 
 | 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); | 
 |     dtmf_handle = dtmf_start(number, 500, 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); | 
 |  | 
 |     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); | 
 |  | 
 |     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"); | 
 |     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 -23 to 17 | 
 |     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) | 
 | { | 
 |     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 = SPEECH_OFF; | 
 |         mixer_set(0); | 
 |     } 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); | 
 |   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_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; | 
 | } | 
 |  | 
 | static 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; | 
 | } |