| //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*/ |