[Feature]add MT2731_MP2_MR2_SVN388 baseline version
Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/eCall.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/eCall.cpp
new file mode 100644
index 0000000..48db868
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/ecall/eCall.cpp
@@ -0,0 +1,1306 @@
+//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 "ecall/eCall.h"
+
+#include <vendor-ril/telephony/ril.h>
+#include <string>
+#include <vector>
+#include <glib.h>
+#include <cutils/jstring.h>
+#include <time.h>
+#include <signal.h>
+#include <pthread.h>
+#include <string.h>
+#include <memory>
+
+#include "util/utils.h"
+#include "cc.h"
+#include "common.h"
+#include "sms/sms.h"
+#include "sms/gsm/sms_pdu.h"
+#include "./gost/utils/GostEcallUtils.h"
+#include "./gost/sslp/SslpManager.h"
+#include "./gost/sslp/ecall/EcallUtils.h"
+#include "network.h"
+
+#undef LOG_TAG
+#define LOG_TAG "DEMO_ECALL"
+#define PROP_ECALL_TEST_CASE "vendor.gost.ecall.ecall_case_test"
+#define PROP_ECALL_DEREGIST_TIME "vendor.gost.ecall.nad_deregistration_time_minute"
+#define PROP_ECALL_REDIAL_TIMER "vendor.ecall.redial.timer" //default 120s
+
+int fast_argc = 0;
+std::vector<std::string> fast_argv;
+int fast_ecall_socket_id = -1;
+static ECALL_TYPE ecall_type = ECALL_TYPE::EN16454_ECALL;
+static bool inNeedRegister = false;
+static bool gostFastEcallFlg = false;
+static bool is_ecall_audio_path = false;
+
+int gost_sms_argc = 0;
+std::vector<std::string> gost_sms_argv;
+int gost_sms_socket_id = -1;
+
+typedef enum {
+ REDIAL_DOING = 1,
+ REDIAL_SUCCESS = 2,
+ REDIAL_EXPIRES = 3,
+ REDIAL_UNKNOWN = 4,
+}ecall_redial_status;
+
+int act_fecall_socid = -1;
+int act_feCall_Id = -1;
+static ecall_redial_status redial_tag = REDIAL_UNKNOWN;
+static bool normal_ecall_tag = false;
+
+#ifdef ECALL_SUPPORT
+extern speech_status getSpeechStatus();
+extern void setSpeechAndStatus(int value);
+int resetIVS(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int dialFastEcall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+void start_ecll_timer(timer_t timer, int signal_value, int milliseconds);
+//RIL_REQUEST_ECALL_SET_MSD
+int setMSD(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int T7GostEcallSmsMsd(sigval_t sig);
+int setNadRegState(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI);
+int gostStartDeregisterTimer();
+
+static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
+//#define PROP_ECALL_MSD_DATA "vendor.ecall.msd.data"
+static char* msd_data = NULL;
+
+//LOCAL_SET_MSD_DATA_FOR_TEST
+int setMsdDateForTest(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+ if (argc < 1 || argv[1] == NULL) {
+ RLOGD("setMsdDateForTest invalid parameters");
+ free(pRI);
+ return -1;
+ }
+ char *msd_data_src = (char*) argv[1];
+ int len = strlen(msd_data_src);
+
+ if (len % 2 == 1) {
+ RLOGD("setMsdDateForTest invalid parameters, length is't right");
+ free(pRI);
+ return -1;
+ }
+ if(msd_data) {
+ free(msd_data);
+ msd_data = NULL;
+ }
+ msd_data = strdup(msd_data_src);
+ RLOGD("setMsdDateForTest() data: %s", (msd_data == NULL ? "": msd_data));
+ return 0;
+}
+
+static timer_t sT2;
+static timer_t sT5;
+static timer_t sT6;
+static timer_t sT7;
+static timer_t sRedialTimer;
+static timer_t sAutoAnsTimer;
+static timer_t gostResendMsdTimer;
+static timer_t gostDeregistrationTimer;
+
+#define T2_TIMEOUT 60*60*1000
+#define T5_TIMEOUT 5*1000
+#define T6_TIMEOUT 5*1000
+#define T7_TIMEOUT 20*1000
+//#define REDIAL_TIMEOUT 2*60*1000
+#define AUTOANS_TIMEOUT 60*60*1000
+
+static int sT2_sig_value = 2;
+static int sT5_sig_value = 5;
+static int sT6_sig_value = 6;
+static int sT7_sig_value = 7;
+static int redial_sig_value = 8;
+static int autoAns_sig_value = 9;
+static int gost_resend_msd_value = 11;
+static int gost_deregistration_value = 12;
+
+bool isEcallAudioPath() {
+ RLOGD("%s , is_ecall_audio_path: %d", __FUNCTION__, is_ecall_audio_path);
+ return is_ecall_audio_path;
+}
+
+bool isEcallAutoanswerTimerFinish() {
+ struct itimerspec timespec;
+ if(timer_gettime(sAutoAnsTimer, ×pec) == -1) {
+ RLOGD("%s(), get time fail(%s)", __FUNCTION__, strerror(errno));
+ return true;
+ }
+ RLOGD("%s(), tv_sec=%ld, tv_nsec=%ld", __FUNCTION__,timespec.it_value.tv_sec, timespec.it_value.tv_nsec);
+ if((timespec.it_value.tv_sec == 0) && (timespec.it_value.tv_nsec == 0) ) {
+ RLOGD("%s(), timer_id(%ld) had stopped", __FUNCTION__, (long)sAutoAnsTimer);
+ return true;
+ }
+ return false;
+}
+
+void setEcallAudioPathOn(bool on) {
+ RLOGD("%s() , is_ecall_audio_path: %d, on: %d", __FUNCTION__, is_ecall_audio_path, on);
+
+ if((is_ecall_audio_path != on) && (isEcallAutoanswerTimerFinish())) {
+ is_ecall_audio_path = on;
+ }
+ RLOGD("%s() , is_ecall_audio_path: %d", __FUNCTION__, is_ecall_audio_path);
+}
+
+void autoAnswerEcall(bool on) {
+ RLOGD("%s() , is_ecall_audio_path: %d, on: %d", __FUNCTION__, is_ecall_audio_path, on);
+ if(is_ecall_audio_path != on) {
+ is_ecall_audio_path = on;
+ }
+ if(on) {
+ char* argv[2] = {"", "1"};
+ autoAnswerCall(2, argv, RIL_SOCKET_ID(0), NULL); //unused socket id;
+ } else {
+ char* argv[2] = {"", "0"};
+ autoAnswerCall(2, argv, RIL_SOCKET_ID(0), NULL); //unused socket id;
+ }
+}
+
+void saveFastEcallData(int argc, char** argv ,RIL_SOCKET_ID id) {
+ fast_ecall_socket_id = id;
+ fast_argc = argc;
+ fast_argv.clear();
+ for(int i = 0; i < argc; i++) {
+ RLOGD("fast_argv[%d] = %s", i, (argv[i]==NULL)? "NULL":argv[i]);
+ fast_argv.push_back(argv[i]);
+ }
+}
+
+void resetEcallIVSandAudio(int mode, RIL_SOCKET_ID id) {
+ RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_RESET_IVS, mode, id);
+ resetIVS(0, NULL, id, pRI);
+// char* argv[2] = { "RIL_REQUEST_SET_MUTE", "0" };
+// setMute(2, argv, id, NULL);
+}
+
+void ecall_timer_handler(sigval_t sig) {
+ RLOGD("ecall_timer_handler, sig_value: %d", sig.sival_int);
+ int s;
+ s = pthread_mutex_lock(&mtx);
+ if(s != 0) {
+ RLOGE("ecall_timer_handler, pthead_mutex_lock fail");
+ }
+ if(sig.sival_int == sT2_sig_value) {
+ RLOGD("T2 timeout, call_Id=%d, socket_id=%d", act_feCall_Id, act_fecall_socid);
+ if(act_feCall_Id == -1 || act_fecall_socid == -1) {
+ goto done;
+ }
+ RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_HANGUP, UDP, RIL_SOCKET_ID(act_fecall_socid));
+ char* id = const_cast<char*>(std::to_string(act_feCall_Id).c_str());
+ char* argv[2] = { "RIL_REQUEST_HANGUP", "" };
+ argv[1] = id;
+ hangupConnection(2, argv, RIL_SOCKET_ID(act_fecall_socid), pRI);
+ act_fecall_socid = -1;
+ act_feCall_Id = -1;
+ } else if(sig.sival_int == sT5_sig_value
+ || sig.sival_int == sT6_sig_value
+ || sig.sival_int == sT7_sig_value) {
+ normal_ecall_tag = false;
+ resetEcallIVSandAudio(UDP, RIL_SOCKET_ID(fast_ecall_socket_id));
+ if(0 != T7GostEcallSmsMsd(sig))
+ {
+ if(sig.sival_int == sT5_sig_value || sig.sival_int == sT7_sig_value) {
+ fast_argc = 0;
+ fast_argv.clear();
+ }
+ }
+ } else if(sig.sival_int == redial_sig_value) {
+ redial_tag = REDIAL_EXPIRES;
+ RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_RESET_IVS, UDP,RIL_SOCKET_ID(fast_ecall_socket_id));
+ resetIVS(0, NULL, RIL_SOCKET_ID(fast_ecall_socket_id), pRI);
+ fast_argc = 0;
+ fast_argv.clear();
+ start_ecll_timer(sAutoAnsTimer, autoAns_sig_value, AUTOANS_TIMEOUT);
+ autoAnswerEcall(true);
+ } else if(sig.sival_int == autoAns_sig_value) {
+ autoAnswerEcall(false);
+ } else if(sig.sival_int == gost_resend_msd_value) {
+ //send msd
+ char** argv = new char*[gost_sms_argv.size()];
+ argv[gost_sms_argv.size()] = nullptr;
+ for(int i=0; i < gost_sms_argv.size(); i++) {
+ char* temp = new char[gost_sms_argv[i].size()];
+ strcpy(temp, gost_sms_argv[i].c_str());
+ argv[i] = temp;
+ }
+
+ RequestInfo *pRI = creatRILInfoAndInit(RIL_REQUEST_SEND_SMS, UDP, (RIL_SOCKET_ID)gost_sms_socket_id);
+ sendSMS(gost_sms_argc, argv, pRI->socket_id, pRI);
+
+ for(int i=0; i < gost_sms_argv.size(); i++) {
+ delete argv[i];
+ }
+ delete argv;
+ } else if(sig.sival_int == gost_deregistration_value) {
+ RIL_SOCKET_ID id = (RIL_SOCKET_ID)fast_ecall_socket_id;
+ if(id == -1) {
+ id = (RIL_SOCKET_ID)get_default_sim_all_except_data();
+ }
+ RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_SET_REGISTRATION_STATE, UDP, id);
+ char* argv[2] = { "RIL_REQUEST_ECALL_SET_REGISTRATION_STATE", "0" };
+ setNadRegState(2, argv, id, pRI);
+ }
+ else {
+ RLOGE("ecall_timer_handler, sig_value is invalid!");
+ }
+done:
+ s = pthread_mutex_unlock(&mtx);
+ if(s != 0) {
+ RLOGE("ecall_timer_handler, pthread_mutex_unlock fail");
+ }
+
+}
+
+void init_ecall_timer(timer_t* timer, int signal_value) {
+
+ struct sigevent sevp;
+ memset(&sevp, 0, sizeof(sevp));
+ sevp.sigev_value.sival_int = signal_value;
+ sevp.sigev_notify = SIGEV_THREAD;
+ sevp.sigev_notify_function = ecall_timer_handler;
+
+ if(timer_create(CLOCK_MONOTONIC, &sevp, timer) == -1) {
+ RLOGE("init_ecall_timer() failed reason=[%s]", strerror(errno));
+ }
+ RLOGD("init_ecall_timer(), timer_Id = %ld, signal_value=%d", (long)(*timer), signal_value);
+}
+
+void init_ecall_timer_all() {
+ init_ecall_timer(&sT2,sT2_sig_value);
+ init_ecall_timer(&sT5,sT5_sig_value);
+ init_ecall_timer(&sT6,sT6_sig_value);
+ init_ecall_timer(&sT7,sT7_sig_value);
+ init_ecall_timer(&sRedialTimer,redial_sig_value);
+ init_ecall_timer(&sAutoAnsTimer,autoAns_sig_value);
+ init_ecall_timer(&gostResendMsdTimer,gost_resend_msd_value);
+ init_ecall_timer(&gostDeregistrationTimer, gost_deregistration_value);
+}
+
+void start_ecll_timer(timer_t timer, int signal_value, int milliseconds) {
+ RLOGD("start_ecll_timer(), timer_id=%ld, signal_value=%d, time=%d",(long)timer, signal_value, milliseconds);
+
+ struct itimerspec expire;
+ expire.it_interval.tv_sec = 0;
+ expire.it_interval.tv_nsec = 0;
+ expire.it_value.tv_sec = milliseconds/1000;
+ expire.it_value.tv_nsec = (milliseconds%1000)*1000000;
+ if (timer_settime(timer, 0, &expire, NULL) == -1) {
+ RLOGE("timer_settime failed reason=[%s]", strerror(errno));
+ }
+}
+
+void stop_ecall_timer(timer_t timer, int signal_value) {
+ RLOGD("stop_ecall_timer(), timer_id=%ld, signal_value=%d", (long)timer, signal_value);
+ struct itimerspec timespec;
+ if(timer_gettime(timer, ×pec) == -1) {
+ RLOGD("stop_ecall_timer(), get time fail(%s)", strerror(errno));
+ return;
+ }
+ RLOGD("stop_ecall_timer(), tv_sec=%ld, tv_nsec=%ld",timespec.it_value.tv_sec, timespec.it_value.tv_nsec);
+ if((timespec.it_value.tv_sec == 0) && (timespec.it_value.tv_nsec == 0) ) {
+ RLOGD("stop_ecall_timer(), timer_id(%ld) had stopped, just return", (long)timer);
+ return;
+ } else {
+ start_ecll_timer(timer, signal_value, 0);
+ }
+}
+
+void saveEcallRecord(RIL_ECall_Indication ind) {
+ std::string str;
+ if(ind == RIL_UNSOL_ECALL_ALACK_POSITIVE_RECEIVED) {
+ str = "ECALL_ALACK_POSITIVE_RECEIVED";
+ } else if(ind == RIL_UNSOL_ECALL_ALACK_CLEARDOWN_RECEIVED) {
+ str = "ECALL_ALACK_CLEARDOWN_RECEIVED";
+ } else {
+ str = "";
+ }
+ struct timespec real;
+ clock_gettime(CLOCK_REALTIME, &real);
+ RLOGD("saveEcallRecord(%s) tv_s:%ld, tv_ns:%ld",str.c_str(), real.tv_sec, real.tv_nsec);
+ char utc_time[100]={0};
+ strftime(utc_time, sizeof(utc_time), "%D %T", gmtime(&real.tv_sec));
+ printf("saveEcallRecord, %s,UTC: data_time=%ld\n", str.c_str(),utc_time);
+ RLOGD("saveEcallRecord, %s,UTC: data_time=%ld", str.c_str(),utc_time);
+ char local_time[100]={0};
+ struct tm t;
+ strftime(local_time, sizeof(local_time), "%D %T", localtime_r(&real.tv_sec, &t));
+ printf("saveEcallRecord, %s,local: data_time=%ld\n", str.c_str(),local_time);
+ RLOGD("saveEcallRecord, %s,UTC: data_time=%ld", str.c_str(),utc_time);
+}
+
+void redialFastEcall(RIL_SOCKET_ID socket_id) {
+ if(isGostEcall())
+ {
+ RLOGD("gost ecall redialFastEcall return for test");
+ return;
+ }
+ RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_FAST_MAKE_ECALL, UDP, socket_id);
+ char** argv = new char*[fast_argv.size()];
+ for(int i=0; i < fast_argv.size(); i++) {
+ argv[i] = new char[fast_argv[i].size() +1];
+ memset(argv[i], 0 , fast_argv[i].size() +1);
+ strncpy(argv[i], fast_argv[i].c_str(),fast_argv[i].size());
+ argv[i][fast_argv[i].size()] = '\0';
+ }
+
+ dialFastEcall(fast_argc, argv, socket_id, pRI);
+
+ for(int i=0; i < fast_argv.size(); i++) {
+ delete [] argv[i];
+ }
+ delete []argv;
+}
+
+void handleEcallIndication(const void* data, int datalen, RIL_SOCKET_ID soc_id) {
+ if (data == NULL || datalen != sizeof(RIL_Ecall_Unsol_Indications)) {
+ if (data == NULL) {
+ RLOGE("handleEcallIndication invalid response: NULL");
+ } else {
+ RLOGE("handleEcallIndication: invalid response length %d expecting len: %d",
+ sizeof(RIL_Ecall_Unsol_Indications), data);
+ }
+ return ;
+ }
+
+ RIL_Ecall_Unsol_Indications *p_cur = (RIL_Ecall_Unsol_Indications *)data;
+ RLOGD("handleEcallIndication, call_id: %d, ind: %d",p_cur->call_id, p_cur->ind);
+ switch(p_cur->ind){
+ case RIL_UNSOL_ECALL_SENDING_START: // = 1,
+ {
+ RLOGD("handleEcallIndication: normal_ecall_tag=%d", normal_ecall_tag);
+ if(!normal_ecall_tag){
+ //char msd_data[MSD_MAX_LENGTH]= {0};
+ //utils::mtk_property_get(PROP_ECALL_MSD_DATA, msd_data, NULL);
+ RLOGD("msd_data: %s", msd_data==NULL ? "":msd_data);
+ if(msd_data != NULL) {
+// char* arg[2] = { "RIL_REQUEST_SET_MUTE", "1" };
+// setMute(2, arg, soc_id, NULL);
+ RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_SET_MSD, RSPD, soc_id);
+ char* argv[3] = {"RIL_REQUEST_ECALL_SET_MSD", "", "" };
+ argv[1] = const_cast<char*>(std::to_string(p_cur->call_id).c_str());
+ argv[2] = msd_data;
+ setMSD(3, argv, soc_id, pRI);
+ }
+ } else {
+ stop_ecall_timer(sT5, sT5_sig_value);
+ }
+ break;
+ }
+ case RIL_UNSOL_ECALL_SENDING_MSD: // = 2,
+ {
+ start_ecll_timer(sT7,sT7_sig_value, T7_TIMEOUT);
+ act_fecall_socid = soc_id;
+ act_feCall_Id = p_cur->call_id;
+ break;
+ }
+ case RIL_UNSOL_ECALL_LLACK_RECEIVED: // = 3,
+ {
+ fast_argc = 0;
+ fast_argv.clear();
+ stop_ecall_timer(sT7, sT7_sig_value);
+ start_ecll_timer(sT6, sT6_sig_value, T6_TIMEOUT);
+ act_fecall_socid = soc_id;
+ act_feCall_Id = p_cur->call_id;
+ normal_ecall_tag = false;
+ break;
+ }
+ case RIL_UNSOL_ECALL_ALACK_POSITIVE_RECEIVED: // = 4,
+ {
+ stop_ecall_timer(sT6, sT6_sig_value);
+ resetEcallIVSandAudio(RSPD, soc_id);
+ saveEcallRecord(p_cur->ind);
+ break;
+ }
+ case RIL_UNSOL_ECALL_ALACK_CLEARDOWN_RECEIVED: // = 5,
+ {
+ stop_ecall_timer(sT6, sT6_sig_value);
+ stop_ecall_timer(sT2, sT2_sig_value);
+ resetEcallIVSandAudio(RSPD, soc_id);
+ saveEcallRecord(p_cur->ind);
+ RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_HANGUP, RSPD, soc_id);
+ char* id = const_cast<char*>(std::to_string(p_cur->call_id).c_str());
+ char* argv[2] = { "RIL_REQUEST_HANGUP", "" };
+ argv[1] = id;
+ hangupConnection(2, argv, soc_id, pRI);
+ break;
+ }
+ case RIL_UNSOL_ECALL_ACTIVE: // =11,
+ {
+ if(redial_tag == REDIAL_DOING) {
+ redial_tag = REDIAL_SUCCESS;
+ stop_ecall_timer(sRedialTimer, redial_sig_value);
+ }
+ stop_ecall_timer(sAutoAnsTimer, autoAns_sig_value);
+ autoAnswerEcall(false);
+ start_ecll_timer(sT2, sT2_sig_value,T2_TIMEOUT);
+ start_ecll_timer(sT5,sT5_sig_value, T5_TIMEOUT);
+ break;
+ }
+ case RIL_UNSOL_ECALL_DISCONNECTED: //=12,
+ {
+ start_ecll_timer(sAutoAnsTimer,autoAns_sig_value, AUTOANS_TIMEOUT);
+ autoAnswerEcall(true);
+ stop_ecall_timer(sT2, sT2_sig_value);
+ if(isGostEcall())
+ {
+ //start deregistration time
+ start_ecll_timer(gostDeregistrationTimer, gost_deregistration_value, gostStartDeregisterTimer());
+ }
+
+ break;
+ }
+ case RIL_UNSOL_ECALL_ABNORMAL_HANGUP: //=15,
+ {
+ RLOGD(" make fast ecall redial start, redial_tag: %d", redial_tag);
+ if(redial_tag != REDIAL_DOING) {
+ stop_ecall_timer(sT2, sT2_sig_value);
+ stop_ecall_timer(sT5,sT5_sig_value);
+ stop_ecall_timer(sT6,sT6_sig_value);
+ stop_ecall_timer(sT7,sT7_sig_value);
+ int32_t timer = utils::mtk_property_get_int32(PROP_ECALL_REDIAL_TIMER, 120);
+ RLOGD(" make fast ecall redial start, vendor.ecall.redial.timer: %d", timer);
+ start_ecll_timer(sRedialTimer, redial_sig_value, timer*1000);
+ }
+ if(redial_tag != REDIAL_SUCCESS || redial_tag != REDIAL_EXPIRES){
+ redial_tag = REDIAL_DOING;
+ RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_RESET_IVS, UDP, soc_id);
+ resetIVS(0, NULL, soc_id, pRI);
+ redialFastEcall(soc_id);
+ }
+ break;
+ }
+ //case RIL_UNSOL_ECALL_IMS_MSD_ACK: // = 20,
+ //case RIL_UNSOL_ECALL_IMS_UPDATE_MSD: // = 21,
+ //case RIL_UNSOL_ECALL_UNSPECIFIED: // = 0xffff,
+ default:
+ RLOGD("handleEcallIndication don't handlt the value(%d)", p_cur->ind);
+ }
+}
+
+//RIL_REQUEST_ECALL_SET_IVS
+int setIVS(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+ android::Parcel p;
+ size_t pos = p.dataPosition();
+
+ if (getSpeechStatus() == SPEECH_OFF) {
+ if (get_audio_path() == 0) {
+ setSpeechAndStatus(1);
+ } else {
+ setSpeechAndStatus(2);
+ }
+ }
+
+ //paramter int. 0 disable, 1 enable
+ p.writeInt32(1);
+ p.writeInt32(atoi(argv[1]) ? 1 : 0);
+ p.setDataPosition(pos);
+ pRI->pCI->dispatchFunction(p, pRI);
+ return 0;
+}
+
+//RIL_REQUEST_ECALL_SET_MSD
+int setMSD(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+ android::Parcel p;
+ size_t pos = p.dataPosition();
+ int digitCount;
+ uint8_t uct;
+ int digitLimit;
+ char *msd_data_src = (char *) argv[2];
+ unsigned char msd_data_dst[MSD_MAX_LENGTH];
+ int len = strlen(msd_data_src);
+
+ if (argc < 2 || argv[2] == NULL || len % 2 == 1) {
+ //add log msg
+ free(pRI);
+ return -1;
+ }
+
+ if (getSpeechStatus() == SPEECH_OFF) {
+ if (get_audio_path() == 0) {
+ setSpeechAndStatus(1);
+ } else {
+ setSpeechAndStatus(2);
+ }
+ }
+ //call_id
+ p.writeInt32(atoi(argv[1]));
+ //msd_data Convert MSD to byte representation
+ RLOGD("msd_data_src: msd_data_src length = %d %s\n", strlen(msd_data_src),
+ msd_data_src);
+ ConvertMsd((const char *) argv[2], msd_data_dst);
+
+ digitLimit = MIN(len / 2, MSD_MAX_LENGTH);
+ p.writeInt32(digitLimit);
+
+ for (digitCount = 0; digitCount < digitLimit; digitCount++) {
+ p.write(&(msd_data_dst[digitCount]), sizeof(uint8_t));
+ }
+
+ p.setDataPosition(pos);
+ pRI->pCI->dispatchFunction(p, pRI);
+ return 0;
+}
+//RIL_REQUEST_ECALL_SET_PSAP
+int setPASP(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+ android::Parcel p;
+ size_t pos = p.dataPosition();
+
+ if (getSpeechStatus() == SPEECH_OFF) {
+ if (get_audio_path() == 0) {
+ setSpeechAndStatus(1);
+ } else {
+ setSpeechAndStatus(2);
+ }
+ }
+
+ //paramter int. 0 disable, 1 enable
+ p.writeInt32(1);
+ p.writeInt32(atoi(argv[1]) ? 1 : 0);
+ p.setDataPosition(pos);
+ pRI->pCI->dispatchFunction(p, pRI);
+ return 0;
+}
+
+//RIL_REQUEST_ECALL_IVS_PUSH_MSD
+int IVSPushMSD(int argc, char **argv, RIL_SOCKET_ID socket_id,
+ RequestInfo *pRI) {
+ android::Parcel p;
+
+ if (getSpeechStatus() == SPEECH_OFF) {
+ if (get_audio_path() == 0) {
+ setSpeechAndStatus(1);
+ } else {
+ setSpeechAndStatus(2);
+ }
+ }
+
+ //paramter none
+ pRI->pCI->dispatchFunction(p, pRI);
+ return 0;
+}
+//RIL_REQUEST_ECALL_PSAP_PULL_MSD
+int PSAPPushMSD(int argc, char **argv, RIL_SOCKET_ID socket_id,
+ RequestInfo *pRI) {
+ android::Parcel p;
+
+ if (getSpeechStatus() == SPEECH_OFF) {
+ if (get_audio_path() == 0) {
+ setSpeechAndStatus(1);
+ } else {
+ setSpeechAndStatus(2);
+ }
+ }
+
+ //paramter none
+ pRI->pCI->dispatchFunction(p, pRI);
+ return 0;
+}
+int setCTRLSequence(int argc, char **argv, RIL_SOCKET_ID socket_id,
+ RequestInfo *pRI) {
+ android::Parcel p;
+ size_t pos = p.dataPosition();
+
+ if (argc < 1 || argc > 4) {
+ //add log msg
+ free(pRI);
+ return -1;
+ }
+ //CTRL Sequence
+ p.writeInt32(3);
+ writeStringToParcel(p, (const char *) argv[1]);
+ writeStringToParcel(p, (const char *) argv[2]);
+ writeStringToParcel(p, (const char *) argv[3]);
+
+ p.setDataPosition(pos);
+ pRI->pCI->dispatchFunction(p, pRI);
+
+ return 0;
+}
+//RIL_REQUEST_ECALL_RESET_IVS
+int resetIVS(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+ android::Parcel p;
+
+ if (getSpeechStatus() == SPEECH_OFF) {
+ if (get_audio_path() == 0) {
+ setSpeechAndStatus(1);
+ } else {
+ setSpeechAndStatus(2);
+ }
+ }
+
+ //paramter none
+ pRI->pCI->dispatchFunction(p, pRI);
+ return 0;
+}
+//RIL_REQUEST_ECALL_SET_TEST_NUM
+int setTestNum(int argc, char **argv, RIL_SOCKET_ID socket_id,
+ RequestInfo *pRI) {
+ android::Parcel p;
+ size_t pos = p.dataPosition();
+
+ if(argc -1 == 0) {
+ p.writeInt32(0);
+ p.writeInt32(0);
+ writeStringToParcel(p, "");
+ } else if (argc -1 == 1) {
+ p.writeInt32(1);
+ p.writeInt32(atoi(argv[1]) ? 1 : 0);
+ writeStringToParcel(p, "");
+ } else if (argc - 1 == 2) {
+ p.writeInt32(2);
+ p.writeInt32(atoi(argv[1]) ? 1 : 0);
+ writeStringToParcel(p, (const char *) argv[2]);
+ } else {
+ RLOGD("parameters is invalid");
+ free(pRI);
+ return -1;
+ }
+ p.setDataPosition(pos);
+ pRI->pCI->dispatchFunction(p, pRI);
+ return 0;
+}
+
+//RIL_REQUEST_ECALL_SET_RECONF_NUM
+int setReconfNum(int argc, char **argv, RIL_SOCKET_ID socket_id,
+ RequestInfo *pRI) {
+ android::Parcel p;
+ size_t pos = p.dataPosition();
+ if(argc -1 == 0) {
+ p.writeInt32(0);
+ p.writeInt32(0);
+ writeStringToParcel(p, "");
+ } else if (argc -1 == 1) {
+ p.writeInt32(1);
+ p.writeInt32(atoi(argv[1]) ? 1 : 0);
+ writeStringToParcel(p, "");
+ } else if (argc - 1 == 2) {
+ p.writeInt32(2);
+ p.writeInt32(atoi(argv[1]) ? 1 : 0);
+ writeStringToParcel(p, (const char *) argv[2]);
+ } else {
+ RLOGD("parameters is invalid");
+ free(pRI);
+ return -1;
+ }
+ p.setDataPosition(pos);
+ pRI->pCI->dispatchFunction(p, pRI);
+ return 0;
+}
+
+//RIL_REQUEST_ECALL_MAKE_ECALL
+int makeECall(int argc, char **argv, RIL_SOCKET_ID socket_id,
+ RequestInfo *pRI) {
+ android::Parcel p;
+ size_t pos = p.dataPosition();
+ //paramter int, type
+ int type;
+ type = atoi(argv[1]);
+ if (type < 0 || type > 3) {
+ RLOGW("makeECall type is invaild. set default 0!");
+ type = 0;
+ }
+
+ p.writeInt32(1);
+ p.writeInt32(type);
+ p.setDataPosition(pos);
+ setEcallAudioPathOn(true);
+ pRI->pCI->dispatchFunction(p, pRI);
+ return 0;
+}
+
+//RIL_REQUEST_ECALL_FAST_MAKE_ECALL
+/*cmd:1, ecall_cat,
+*2, ecall_variant,
+*3, address
+*4, msd_data
+*/
+int dialFastEcall(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+ if(isGostEcall())
+ {
+ if(inNeedRegister)
+ {
+ RLOGD("%s:%d", __FUNCTION__, __LINE__);
+ gostFastEcallFlg = true;
+ gostNetworkSelectionSet(socket_id);
+ while(inNeedRegister)
+ {
+ sleep(1);
+ RLOGD("%s:%d", __FUNCTION__, __LINE__);
+ }
+ stop_ecall_timer(gostDeregistrationTimer,gost_deregistration_value);
+ }
+ }
+ saveFastEcallData(argc, argv, socket_id);
+ if (argc < 5 || argv[3] == NULL || argv[4] == NULL) {
+ //add log msg
+ free(pRI);
+ return -1;
+ }
+ android::Parcel p;
+ size_t pos = p.dataPosition();
+ int digitCount;
+ uint8_t uct;
+ int digitLimit;
+ char *msd_data_src = (char *)argv[4];
+ unsigned char msd_data_dst[MSD_MAX_LENGTH];
+ int len = strlen(msd_data_src);
+
+ if (len%2 == 1) {
+ //add log msg
+ free(pRI);
+ return -1;
+ }
+ //ecall_cat
+ p.writeInt32(atoi(argv[1]));
+ //ecall_variant
+ p.writeInt32(atoi(argv[2]));
+ //address;
+ if(strcasecmp(argv[3], "null") == 0)
+ {
+ writeStringToParcel(p, "");
+ } else {
+ writeStringToParcel(p, (const char *)argv[3]);
+ }
+
+ //msd_data Convert MSD to byte representation
+ RLOGD("msd_data_src: %s , length = %d", msd_data_src, strlen(msd_data_src));
+ ConvertMsd((const char *)argv[4], msd_data_dst);
+
+ digitLimit= MIN(len/2, MSD_MAX_LENGTH);
+ p.writeInt32(digitLimit);
+
+ for (digitCount = 0 ; digitCount < digitLimit; digitCount ++) {
+ p.write(&(msd_data_dst[digitCount]), sizeof(uint8_t));
+ }
+
+ p.setDataPosition(pos);
+ normal_ecall_tag = true;
+ setEcallAudioPathOn(true);
+ pRI->pCI->dispatchFunction(p, pRI);
+
+ return 0;
+}
+
+
+//RIL_REQUEST_ECALL_SET_PRI
+int setEmsdpri(int argc, char **argv, RIL_SOCKET_ID socket_id,
+ RequestInfo *pRI) {
+ if (argc != 5) {
+ RLOGW("parameter is invalid");
+ free(pRI);
+ return 0;
+ }
+ int data1 = atoi(argv[1]);
+ int data2 = atoi(argv[2]);
+ int data3 = atoi(argv[3]);
+ int data4 = atoi(argv[4]);
+
+ if (data1 + data2 + data3 + data4 != 10) {
+ RLOGW("parameter is invalid , %d,%d,%d,%d", data1, data2, data3, data4);
+ free(pRI);
+ return 0;
+ }
+ android::Parcel p;
+ size_t pos = p.dataPosition();
+ p.writeInt32(4);
+ p.writeInt32(data1);
+ p.writeInt32(data2);
+ p.writeInt32(data3);
+ p.writeInt32(data4);
+ p.setDataPosition(pos);
+ pRI->pCI->dispatchFunction(p, pRI);
+ return 0;
+}
+
+//RIL_REQUEST_ECALL_SET_NAD_DEREGISTRATION_TIME
+/*
+ * "data" is const ints*
+ * ((const int *)data)[0] is purpose, 0-for eCall(currently only support 0, can be extended in future)
+ * ((const int *)data)[1] is mode, 1-set timer; 0-reset timer
+ * ((const int *)data)[2] is timer1, timer value (minute) set for emergency call
+ * ((const int *)data)[3] is timer2, timer value (minute) set for rest/reconfiguration call,
+ *
+ * in current, timer1 and timer2 prefer to be the same value.
+ */
+int setNadDeregTime(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+ if (argc != 5) {
+ RLOGW("parameter is invalid");
+ free(pRI);
+ return 0;
+ }
+
+ int purpose = atoi(argv[1]);
+ int mode = (atoi(argv[2]) != 0) ? 1 : 0;
+ int timer1 = atoi(argv[3]);
+ int timer2 = atoi(argv[4]);
+ if (timer1 != timer2) {
+ RLOGW("setNadDeregTime, parameter is invalid:data3 != data4");
+ free(pRI);
+ return 0;
+ }
+
+ android::Parcel p;
+ size_t pos = p.dataPosition();
+ p.writeInt32(4);
+ p.writeInt32(purpose);
+ p.writeInt32(mode);
+ p.writeInt32(timer1);
+ p.writeInt32(timer2);
+ p.setDataPosition(pos);
+ pRI->pCI->dispatchFunction(p, pRI);
+ return 0;
+}
+
+/**
+* RIL_REQUEST_ECALL_SET_REGISTRATION_STATE
+*
+* REQUEST to set nad registration state of ecall only sim
+*
+* "data" is const ints*
+* ((const int *)data)[0] is state, 0-deregister from NW, enter the eCall inactivity procedure;
+* 1-register to NW, leave the eCall inactivity procedure(not support, reserved for future use)
+* "response" is NULL
+*
+* Valid errors:
+* SUCCESS
+* GENERIC_FAILURE
+*/
+int setNadRegState(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+ if(argc != 2) {
+ RLOGW("parameter is invalid");
+ free(pRI);
+ return 0;
+ }
+
+ int state = (atoi(argv[1])!= 0) ? 1 : 0;
+
+ android::Parcel p;
+ size_t pos = p.dataPosition();
+ p.writeInt32(1);
+ p.writeInt32(state);
+ p.setDataPosition(pos);
+ pRI->pCI->dispatchFunction(p, pRI);
+ return 0;
+}
+
+int setEcallType(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+ if(argc < 2) {
+ RLOGW("[error],setEcallType parameter error!");
+ free(pRI);
+ return 0;
+ }
+ RLOGD("setEcallType is %s",argv[1]);
+ int value = atoi(argv[1]);
+ switch(value) {
+ case 1:
+ {
+ ecall_type = ECALL_TYPE::EN16454_ECALL;
+ break;
+ }
+ case 2:
+ {
+ ecall_type = ECALL_TYPE::GOST_ECALL;
+ break;
+ }
+ case 3:
+ {
+ ecall_type = ECALL_TYPE::NG_ECALL;
+ break;
+ }
+ default:
+ RLOGD("setEcallType error %s",argv[1]);
+ }
+
+ if(pRI) {
+ free(pRI);
+ }
+ return 0;
+}
+
+int getEcallType(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI) {
+ RLOGD("%s, %d", __FUNCTION__, ecall_type);
+
+ if(ecall_type == ECALL_TYPE::EN16454_ECALL) {
+ printf("the current test type is: EN16454 ECALL\n");
+ } else if(ecall_type == ECALL_TYPE::GOST_ECALL) {
+ printf("the current test type is: GOST ECALL\n");
+ } else if (ecall_type == ECALL_TYPE::NG_ECALL) {
+ printf("the current test type is: NG ECALL (IMS)\n");
+ } else {
+ printf("the current test type is: unknown\n");
+ }
+
+ if(pRI) {
+ free(pRI);
+ }
+ return 0;
+}
+
+bool isEn16454Ecall() {
+ bool value = (ecall_type == ECALL_TYPE::EN16454_ECALL);
+ RLOGD("%s=%d, type = %d", __FUNCTION__, value, ecall_type);
+ return value;
+}
+
+bool isGostEcall() {
+ bool value = (ecall_type == ECALL_TYPE::GOST_ECALL);
+ RLOGD("%s=%d, type = %d", __FUNCTION__, value, ecall_type);
+ return value;
+}
+
+bool isNgEcall() {
+ bool value = (ecall_type == ECALL_TYPE::NG_ECALL);
+ RLOGD("%s=%d, type = %d", __FUNCTION__, value, ecall_type);
+ return value;
+}
+
+void gostSaveSmsData(int argc, char** argv ,RIL_SOCKET_ID id) {
+ gost_sms_socket_id = id;
+ gost_sms_argc = argc;
+ gost_sms_argv.clear();
+ for(int i = 0; i < argc; i++) {
+ gost_sms_argv.push_back(argv[i]);
+ }
+}
+
+void gostDelSaveSmsData() {
+ if(fast_argc != 0)
+ {
+ fast_argc = 0;
+ fast_argv.clear();
+ }
+}
+
+#define INT_MEM_TRANSMIT_ATTEMPTS 10
+#define INT_MEM_TRANSMIT_INTERVAL (60*60*1000)
+static int gost_attempts = INT_MEM_TRANSMIT_ATTEMPTS;
+static int gost_interval = INT_MEM_TRANSMIT_INTERVAL;
+
+void gostSetInNeedRegister(bool flags)
+{
+ RLOGD("%s:flags(%d) change!", __FUNCTION__, flags);
+ inNeedRegister = flags;
+}
+void gostFastEcallFlgSet(bool flags)
+{
+ RLOGD("%s:flags(%d) change!", __FUNCTION__, flags);
+ gostFastEcallFlg = flags;
+}
+
+int gostTransmitAttemptsSet(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+ if(argc < 2) {
+ RLOGW("[error],gostTransmitAttemptsSet parameter error!");
+ free(pRI);
+ return 0;
+ }
+
+ int attempts = atoi(argv[1]);;
+ gost_attempts = attempts;
+ RLOGD("%s:gost_attempts(%d)", __FUNCTION__, gost_attempts);
+
+ if(pRI) {
+ free(pRI);
+ }
+ return 0;
+}
+
+int gostStartDeregisterTimer()
+{
+ char configNum[16]= {0};
+ int timerValue;
+ utils::mtk_property_get(PROP_ECALL_DEREGIST_TIME, configNum, "60");
+ timerValue = atoi(configNum) * 60 * 1000;
+ RLOGD("%s:configNum(%d)", __FUNCTION__, timerValue);
+ return timerValue;
+}
+
+int gostTransmitIntervalSet(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+ if(argc < 2) {
+ RLOGW("[error],gostTransmitIntervalSet parameter error!");
+ free(pRI);
+ return 0;
+ }
+
+ int interval = atoi(argv[1]);;
+ gost_interval = interval;
+ RLOGD("%s:gost_interval(%d)", __FUNCTION__, gost_interval);
+
+ if(pRI) {
+ free(pRI);
+ }
+ return 0;
+}
+
+int gostTransmitDefaultSet(int argc, char **argv, RIL_SOCKET_ID socket_id, RequestInfo *pRI)
+{
+ gost_attempts = INT_MEM_TRANSMIT_ATTEMPTS;
+ gost_interval = INT_MEM_TRANSMIT_INTERVAL;
+ RLOGD("%s:gost_attempts(%d), gost_interval(%d)", __FUNCTION__, gost_attempts, gost_interval);
+
+ if(pRI) {
+ free(pRI);
+ }
+ return 0;
+}
+
+int gostNetworkSelectionSet(int soc_id)
+{
+ RLOGD("%s:soc_id(%d)", __FUNCTION__, soc_id);
+ if(isGostEcall() && gostFastEcallFlg)
+ {
+ RequestInfo *pRI = creatRILInfoAndInit(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, UDP, (RIL_SOCKET_ID)(soc_id));
+ if(pRI == NULL)
+ {
+ RLOGE("error PRI is NULL");
+ return 0;
+ }
+ char* argv[1] = {"RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC"};
+ setNetworkSelectionModeAutomatic(1, argv, (RIL_SOCKET_ID)(soc_id), pRI);
+ }
+ return 0;
+}
+
+int gostEcallResendMsd(bool flg)
+{
+ static int resendnum = 0;
+
+ //no resend
+ if(!flg)
+ {
+ if(resendnum != 0)
+ {
+ stop_ecall_timer(gostResendMsdTimer,gost_resend_msd_value);
+ }
+ resendnum = 0;
+ return 0;
+ }
+
+ //abandon
+ if(resendnum > gost_attempts)
+ {
+ resendnum = 0;
+ stop_ecall_timer(gostResendMsdTimer,gost_resend_msd_value);
+ return 0;
+ }
+
+ //resend
+ resendnum++;
+ start_ecll_timer(gostResendMsdTimer, gost_resend_msd_value, gost_interval);
+}
+
+int T7GostEcallSmsMsd(sigval_t sig) {
+ char** argv = new char*[fast_argv.size()];
+ char msd[512];
+ char saveEcallData[512];
+ char sdata[512];
+
+ if((sig.sival_int != sT7_sig_value) && (sig.sival_int != sT5_sig_value))
+ {
+ return -1;
+ }
+
+ if(isGostEcall())
+ {
+ //for test
+ char testCase[140]= {0};
+ utils::mtk_property_get(PROP_ECALL_TEST_CASE, testCase, "test");
+ if(strcmp(testCase, "33470") == 0)
+ {
+ RLOGD("%s:testCase(%s) not need send sms", __FUNCTION__, testCase);
+ return -1;
+ }
+
+ if(fast_argv.size() < 5) {
+ RLOGD("%s:testCase(%s) fast_argv size(%d) is not right", __FUNCTION__, testCase,fast_argv.size());
+ return -1;
+ }
+ for(int i=0; i < fast_argv.size(); i++) {
+ argv[i] = new char[fast_argv[i].size() +1];
+ memset(argv[i], 0 , fast_argv[i].size() +1);
+ strncpy(argv[i], fast_argv[i].c_str(),fast_argv[i].size());
+ argv[i][fast_argv[i].size()] = '\0';
+ }
+
+ RLOGD("num:%s, data:%s\n", argv[3], argv[4]);
+ char *msd_data_src = (char *)argv[4];
+ int len = strlen(msd_data_src);
+ std::shared_ptr<SslpManager> manager = std::make_shared<SslpManager>();
+ std::string data = manager->encodeAllRecords(service_support_layer_protocol::EGTS_ECALL_SERVICE,
+ service_support_layer_protocol::EGTS_ECALL_SERVICE,
+ EcallUtils::EGTS_SR_RAW_MSD_DATA,
+ msd_data_src);
+ //encode
+ RLOGD("T7:data.c_str():%s\n", data.c_str());
+ int pt = GOST_EGTS_PT_APPDATA;
+ gostTransferLayerEncode(msd, 0, const_cast<char*> (data.c_str()), pt, sizeof(msd));
+ RLOGD("T7:msd:%s\n", msd);
+ gostSendSmsForMsd(fast_ecall_socket_id, argv[3], msd);
+ for(int i=0; i < fast_argv.size(); i++) {
+ delete [] argv[i];
+ }
+ delete []argv;
+
+ return 0;
+ }
+
+ return -1;
+}
+
+#define GOST_OK 0
+#define GOST_ERROR -1
+int gostInitEcallViaSms(int soc_id, char *num, int ecalltype, char *msd)
+{
+ //init ecall
+ RequestInfo *pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_FAST_MAKE_ECALL, UDP, (RIL_SOCKET_ID)(soc_id));
+ if(pRI == NULL)
+ {
+ RLOGE("error PRI is NULL");
+ return 0;
+ }
+
+ int argc = 5;
+ char *argv[5];
+ argv[0] = "RIL_REQUEST_ECALL_FAST_MAKE_ECALL";
+ if(ecalltype)
+ {
+ argv[1] = "2";//1:Manual 2:auto
+ }
+ else
+ {
+ argv[1] = "1";//1:Manual 2:auto
+ }
+ argv[2] = "2"; //1:test ecall 2:Emergency eCall 3:Reconfiguration eCall
+// argv[3] = "1"; //1:Pull mode 2:push mode
+ argv[3] = num;
+ argv[4] = msd;
+ dialFastEcall(argc, argv, (RIL_SOCKET_ID)(soc_id), pRI);
+ return 0;
+}
+
+int gostParseSmsHandle(int soc_id, char *num, char *msg)
+{
+ char msd[512] = {0};
+ char sdata[512] = {0};
+ char server_data[512] = {0};
+ int server_len;
+ int parseStatus;
+ gost_transfer_head_t stransferHead;
+
+ memset(&stransferHead, 0, sizeof(stransferHead));
+ parseStatus = gostTransferLayerDecode(msg, server_data, &server_len, &stransferHead);
+ const char* SFRD = server_data;
+ uint16_t FDL = server_len;
+ std::shared_ptr<SslpManager> sMg = std::make_shared<SslpManager>();
+ parseStatus += sMg->decodeAllRecords(SFRD, FDL);
+ std::uint16_t cmd = UINT16_MAX;
+ if(sMg->isIncludedCmdCode(EcallUtils::EGTS_ECALL_REQ)) {
+ cmd = EcallUtils::EGTS_ECALL_REQ;
+ } else if(sMg->isIncludedCmdCode(EcallUtils::EGTS_ECALL_MSD_REQ)) {
+ cmd = EcallUtils::EGTS_ECALL_MSD_REQ;
+ } else if(sMg->isIncludedCmdCode(EcallUtils::EGTS_ECALL_DEREGISTRATION)) {
+ cmd = EcallUtils::EGTS_ECALL_DEREGISTRATION;
+ }
+ if(cmd == UINT16_MAX) {
+ MTK_RLOGW("don't support this ack,just return");
+ return -1;
+ }
+ MTK_RLOGD("the cmd = 0X%04X, parseStatus = %d", cmd, parseStatus);
+ std::string sslp_ack = sMg->encodeAck(service_support_layer_protocol::EGTS_COMMANDS_SERVICE,
+ service_support_layer_protocol::EGTS_COMMANDS_SERVICE,
+ CmdUtils::EGTS_SR_COMMAND_DATA,
+ cmd,
+ (parseStatus == GOST_OK));
+ strncpy(sdata, sslp_ack.c_str(), 512);
+ int pt = GOST_EGTS_PT_RESPONSE;
+ gostResponseTypeSfrdEncode(sdata, stransferHead, parseStatus);
+ gostTransferLayerEncode(msd, 0, sdata, pt, sizeof(msd));
+ //send SMS ACK
+ gostSendSmsForMsd(soc_id, num, msd);
+
+ if (parseStatus == GOST_OK) {
+ if(cmd == EcallUtils::EGTS_ECALL_REQ) {
+ int ecalltype = sMg->getEcallReqPara(); // 0 manual , 1: auto
+ //make fast ECALL;
+ if(msd_data == NULL) {
+ RLOGW("msd_data is empty, please input");
+ return -1;
+ }
+
+ char ecallNum[64] = {0};
+ if(fast_argv.size() > 4)
+ {
+ strcpy(ecallNum, fast_argv[3].c_str());
+ }
+ gostInitEcallViaSms(soc_id, ecallNum, ecalltype, msd_data);
+ } else if(cmd == EcallUtils::EGTS_ECALL_MSD_REQ) {
+ //check whether need send SMS by decoding transport value in command.
+ if(sMg->isNeedNewSms()) {
+ //TBD: send new SMS;
+ if(msd_data == NULL) {
+ RLOGW("msd_data is empty, please input");
+ return -1;
+ }
+ std::string msdData(msd_data);
+ std::shared_ptr<SslpManager> sMg = std::make_shared<SslpManager>();
+ std::string records = sMg->encodeAllRecords(service_support_layer_protocol::EGTS_ECALL_SERVICE,
+ service_support_layer_protocol::EGTS_ECALL_SERVICE, EcallUtils::EGTS_SR_RAW_MSD_DATA, msdData);
+ //transport encode and sms send
+ int pt = GOST_EGTS_PT_APPDATA;
+ memset(msd, 0, sizeof(msd));
+ gostTransferLayerEncode(msd, 0, const_cast<char*> (records.c_str()), pt, sizeof(msd));
+ gostSendSmsForMsd(soc_id, num, msd);
+ }
+ } else if(cmd == EcallUtils::EGTS_ECALL_DEREGISTRATION) {
+ MTK_RLOGD("send RIL_REQUEST_ECALL_SET_REGISTRATION_STATE 0");
+ RIL_SOCKET_ID id = (RIL_SOCKET_ID)fast_ecall_socket_id;
+ if(id == -1) {
+ id = (RIL_SOCKET_ID)get_default_sim_all_except_data();
+ }
+ RequestInfo* pRI = creatRILInfoAndInit(RIL_REQUEST_ECALL_SET_REGISTRATION_STATE, UDP, id);
+ char* argv[2] = { "RIL_REQUEST_ECALL_SET_REGISTRATION_STATE", "0" };
+ setNadRegState(2, argv, id, pRI);
+ }
+ }
+ return 0;
+}
+#endif /*ECALL_SUPPORT*/