|  | /* | 
|  | * Copyright (C) 2006 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  | #include <string.h> | 
|  | #include <stddef.h> | 
|  | #include <stdlib.h> | 
|  | #include <stdio.h> | 
|  | #include <stdbool.h> | 
|  | #include<fcntl.h> | 
|  | #include<sys/stat.h> | 
|  | #include<sys/types.h> | 
|  | #include<unistd.h> | 
|  | #include <assert.h> | 
|  | #include <log/log.h> | 
|  | #include <vendor-ril/telephony/ril.h> | 
|  | #include <string> | 
|  | #include <mutex> | 
|  | #include <vector> | 
|  | #include <cutils/properties.h> | 
|  |  | 
|  | #include "Radio_capability_switch_util.h" | 
|  | #include "common.h" | 
|  | #include "Phone_utils.h" | 
|  | #include "utils.h" | 
|  | #include "data.h" | 
|  | #include "cc.h" | 
|  |  | 
|  | #undef LOG_TAG | 
|  | #define LOG_TAG "MULTI_USER_COMMON" | 
|  |  | 
|  | typedef enum { | 
|  | STATE_IN_SERVICE        =0, | 
|  | STATE_OUT_OF_SERVICE    =1, | 
|  | STATE_EMERGENCY_ONLY    =2, | 
|  | STATE_POWER_OFF         =3 | 
|  | } Service_State; | 
|  |  | 
|  | RfDesenseTxTest* m_RfDesense; | 
|  | static RIL_CardStatus_v6* cur_CardS_Status[2] = {NULL, NULL}; | 
|  | static RIL_RadioCapability radio_capability[2]; | 
|  |  | 
|  | static int cur_voice_radio_tech[2] = {RADIO_TECH_UNKNOWN, RADIO_TECH_UNKNOWN}; | 
|  |  | 
|  | static int reg_voice_service_state[2] = {0, 0}; | 
|  | static int reg_data_service_state[2] = {0, 0}; | 
|  | static int reg_data_radio_tech[2] = {RADIO_TECH_UNKNOWN, RADIO_TECH_UNKNOWN}; | 
|  | static int reg_voice_radio_tech[2] = {RADIO_TECH_UNKNOWN, RADIO_TECH_UNKNOWN}; | 
|  | static int preferred_network_type[2]  = {Phone_utils::PREFERRED_NETWORK_MODE, Phone_utils::PREFERRED_NETWORK_MODE}; | 
|  | static int radio_status[2] = {RADIO_STATE_UNAVAILABLE, RADIO_STATE_UNAVAILABLE}; | 
|  | static std::vector<int> call_state[2]; | 
|  |  | 
|  | static int default_sim_all = RIL_SOCKET_1; | 
|  | static int default_sim_all_except_data =  RIL_SOCKET_1; | 
|  | static int default_sim_voice = RIL_SOCKET_1; | 
|  | static int default_sim_data = RIL_SOCKET_1; | 
|  | static int default_sim_sms = RIL_SOCKET_1; | 
|  | static bool isNeedReconnect = false; | 
|  |  | 
|  | static std::int32_t token = 0; | 
|  | static std::mutex g_mutex; | 
|  |  | 
|  | static int regCodeToRadioTechnology(int request, int code, int slot); | 
|  |  | 
|  | void update_call_state(void *response, size_t responselen, int slot) { | 
|  | int num = responselen / sizeof(RIL_Call *); | 
|  | if(num == 0) { | 
|  | call_state[slot].clear(); | 
|  | RLOGD("[SIM%d]clear call state", slot); | 
|  | } else { | 
|  | call_state[slot].clear(); | 
|  | for (int i = 0 ; i < num ; i++) { | 
|  | RIL_Call *p_cur = ((RIL_Call **) response)[i]; | 
|  | /* each call info */ | 
|  | call_state[slot].push_back(p_cur->state); | 
|  | RLOGD("[SIM%d][id:%d]update_call_state: %d", slot,p_cur->index, p_cur->state); | 
|  | if(p_cur->isMT) { | 
|  | resetMute(); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | int is_call_state_idle(int slot) { | 
|  | bool is_idle = true; | 
|  | if(!call_state[slot].empty()) { | 
|  | is_idle = false; | 
|  | } | 
|  | RLOGD("[SIM%d]is_call_state_idle: %d", slot, is_idle); | 
|  | return is_idle; | 
|  | } | 
|  |  | 
|  | void update_preferred_network_type(int type, int slot) { | 
|  | RLOGD("[SIM%d]update_preferred_network_type: %d", slot, type); | 
|  | preferred_network_type[slot] = type; | 
|  | } | 
|  |  | 
|  | int get_preferred_network_type(int slot) { | 
|  | return preferred_network_type[slot]; | 
|  | } | 
|  |  | 
|  | static int needBlockReq(int request) | 
|  | { | 
|  | #ifdef ENABLE_BLOCK_FEATURE | 
|  | return 1; | 
|  | #endif | 
|  |  | 
|  | switch (request){ | 
|  | case RIL_REQUEST_RADIO_POWER: return 1; | 
|  | case RIL_REQUEST_SET_IMS_ENABLE: return 1; | 
|  | //case RIL_REQUEST_DATA_REGISTRATION_STATE: return 1; | 
|  | default: return 0; | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int setupToken(int token, int mode, int block) | 
|  | { | 
|  | switch (mode){ | 
|  | case INIT: | 
|  | token |= INIT_TOKEN_MARK; | 
|  | break; | 
|  | case UDP: | 
|  | token |= RIL_TOKEN_MARK; | 
|  | break; | 
|  | case ATCI: | 
|  | token |= ATCI_TOKEN_MARK; | 
|  | break; | 
|  | case RSPD: | 
|  | token |= RSP_DISP_TOKEN_MARK; | 
|  | break; | 
|  | case OTHER: | 
|  | token |= OTHER_TOKEN_MARK; | 
|  | break; | 
|  | default: | 
|  | break; | 
|  | } | 
|  |  | 
|  | if(block) | 
|  | token |= BLOCK_MARK; | 
|  |  | 
|  | return token; | 
|  | } | 
|  |  | 
|  | bool isDataConnectEnable(int slot) { | 
|  | char value[PROPERTY_VALUE_MAX] = {0}; | 
|  | utils::getMSimProperty(slot,PROP_DEFAULT_DATA_SIM_STATUS, value); | 
|  | if(atoi(value) == 1)  { | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | void updataDataConnectState(int slot, bool state) { | 
|  | utils::setMSimProperty(slot,PROP_DEFAULT_DATA_SIM_STATUS, const_cast<char*>(state ? "1":"0")); | 
|  | } | 
|  |  | 
|  | std::int32_t GenerateToken(int mode, int request) { | 
|  | g_mutex.lock(); | 
|  | if (token +1 == TOKEN_MODE) { | 
|  | token = 1; | 
|  | } else { | 
|  | token++; | 
|  | } | 
|  | std::int32_t t= 0; | 
|  | t = setupToken(token,mode,needBlockReq(request)); | 
|  | g_mutex.unlock(); | 
|  | return t; | 
|  | } | 
|  |  | 
|  | RequestInfo* creatRILInfoAndInit(int request, int mode, RIL_SOCKET_ID soc_id) | 
|  | { | 
|  | RequestInfo *pRI  = (RequestInfo *)calloc(1, sizeof(RequestInfo)); | 
|  | if(pRI ==NULL){ | 
|  | RLOGE("%s,memory alloc error!",__func__); | 
|  | return NULL; | 
|  | } | 
|  | android::initRequestInfo(pRI,request,mode, soc_id); | 
|  | return pRI; | 
|  | } | 
|  |  | 
|  | void set_default_sim_all_except_data(int slot_id) { | 
|  | RLOGD("set_default_sim_all excpet data: %d", slot_id); | 
|  | default_sim_all_except_data =  slot_id; | 
|  | set_default_sim_voice(slot_id); | 
|  | set_default_sim_sms(slot_id); | 
|  | } | 
|  |  | 
|  | int get_default_sim_all_except_data() { | 
|  | return default_sim_all_except_data; | 
|  | } | 
|  |  | 
|  | void set_default_sim_all(int slot_id){ | 
|  | RLOGD("set_default_sim_all: %d", slot_id); | 
|  | default_sim_all =  slot_id; | 
|  | set_default_sim_all_except_data(slot_id); | 
|  | set_default_sim_data(slot_id); | 
|  | } | 
|  |  | 
|  | int get_default_sim_all(){ | 
|  | return default_sim_all; | 
|  | } | 
|  |  | 
|  | void set_default_sim_voice(int slot_id){ | 
|  | RLOGD("set_default_sim_voice: %d", slot_id); | 
|  | default_sim_voice = slot_id; | 
|  | } | 
|  |  | 
|  | int get_default_sim_voice(){ | 
|  | return default_sim_voice; | 
|  | } | 
|  |  | 
|  | void set_default_sim_data(int slot) { | 
|  | if(get_default_sim_data() != slot) { | 
|  | if(isDataConnectEnable(get_default_sim_data())) { | 
|  | isNeedReconnect = true; | 
|  | deactivateDataCall(0,NULL,(RIL_SOCKET_ID)0,NULL); | 
|  | } | 
|  | default_sim_data = slot; | 
|  | utils::mtk_property_set(PROP_DEFAULT_DATA_SIM, std::to_string(default_sim_data + 1).c_str()); | 
|  | while(!isRadioAvailable(RIL_SOCKET_ID(slot))) { | 
|  | sleep(1); | 
|  | RLOGD("[SIM%d]set_default_sim_data(RIL_REQUEST_SET_RADIO_CAPABILITY): wait radio available", slot); | 
|  | } | 
|  | syncDataSettings(RIL_SOCKET_ID(slot)); | 
|  | if(utils::is_support_dsds()) { | 
|  | Radio_capability_switch_util::sendRadioCapabilityRequest(slot); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | bool isNeedConnect() { | 
|  | return isNeedReconnect; | 
|  | } | 
|  |  | 
|  | void resetConnect() { | 
|  | isNeedReconnect = false; | 
|  | } | 
|  | int get_default_sim_data_for_switch() { | 
|  | return default_sim_data; | 
|  | } | 
|  |  | 
|  | int get_default_sim_data(){ | 
|  | default_sim_data = utils::mtk_property_get_int32(PROP_DEFAULT_DATA_SIM, 1) -1; | 
|  | return default_sim_data; | 
|  | } | 
|  |  | 
|  | void set_default_sim_sms(int slot_id){ | 
|  | RLOGD("set_default_sim_sms: %d", slot_id); | 
|  | default_sim_sms = slot_id; | 
|  | } | 
|  |  | 
|  | int get_default_sim_sms() { | 
|  | return default_sim_sms; | 
|  | } | 
|  |  | 
|  | static int regCodeToServiceState(int request,int code, int slot); | 
|  |  | 
|  | const char * radioStateToString(RIL_RadioState s) { | 
|  | switch (s) { | 
|  | case RADIO_STATE_OFF: | 
|  | return "RADIO_OFF"; | 
|  | case RADIO_STATE_UNAVAILABLE: | 
|  | return "RADIO_UNAVAILABLE"; | 
|  | case RADIO_STATE_SIM_NOT_READY: | 
|  | return "RADIO_SIM_NOT_READY"; | 
|  | case RADIO_STATE_SIM_LOCKED_OR_ABSENT: | 
|  | return "RADIO_SIM_LOCKED_OR_ABSENT"; | 
|  | case RADIO_STATE_SIM_READY: | 
|  | return "RADIO_SIM_READY"; | 
|  | case RADIO_STATE_RUIM_NOT_READY: | 
|  | return "RADIO_RUIM_NOT_READY"; | 
|  | case RADIO_STATE_RUIM_READY: | 
|  | return "RADIO_RUIM_READY"; | 
|  | case RADIO_STATE_RUIM_LOCKED_OR_ABSENT: | 
|  | return "RADIO_RUIM_LOCKED_OR_ABSENT"; | 
|  | case RADIO_STATE_NV_NOT_READY: | 
|  | return "RADIO_NV_NOT_READY"; | 
|  | case RADIO_STATE_NV_READY: | 
|  | return "RADIO_NV_READY"; | 
|  | case RADIO_STATE_ON: | 
|  | return "RADIO_ON"; | 
|  | default: | 
|  | return "<unknown state>"; | 
|  | } | 
|  | } | 
|  |  | 
|  | const char *rilSocketIdToString(RIL_SOCKET_ID socket_id) { | 
|  | switch (socket_id) { | 
|  | case RIL_SOCKET_1: | 
|  | return "RIL_SOCKET_1"; | 
|  | #if (SIM_COUNT >= 2) | 
|  | case RIL_SOCKET_2: | 
|  | return "RIL_SOCKET_2"; | 
|  | #endif | 
|  | #if (SIM_COUNT >= 3) | 
|  | case RIL_SOCKET_3: | 
|  | return "RIL_SOCKET_3"; | 
|  | #endif | 
|  | #if (SIM_COUNT >= 4) | 
|  | case RIL_SOCKET_4: | 
|  | return "RIL_SOCKET_4"; | 
|  | #endif | 
|  | default: | 
|  | return "not a valid RIL"; | 
|  | } | 
|  | } | 
|  |  | 
|  | void update_radio_capa(RIL_RadioCapability* cap, int slot) { | 
|  | memset(&radio_capability[slot], 0, sizeof(RIL_RadioCapability)); | 
|  | if(cap != NULL) { | 
|  | strcpy(radio_capability[slot].logicalModemUuid,cap->logicalModemUuid); | 
|  | radio_capability[slot].phase = cap->phase; | 
|  | radio_capability[slot].rat = cap->rat; | 
|  | radio_capability[slot].session = cap->session; | 
|  | radio_capability[slot].status = cap->status; | 
|  | radio_capability[slot].version = cap->version; | 
|  | } | 
|  | } | 
|  |  | 
|  | RIL_RadioCapability get_radio_capa(int slot) { | 
|  | return radio_capability[slot]; | 
|  | } | 
|  |  | 
|  | void update_voice_radio_tech(int code, int slot) { | 
|  | cur_voice_radio_tech[slot] = code; | 
|  | } | 
|  |  | 
|  | int get_voice_radio_tech(int slot){ | 
|  | return cur_voice_radio_tech[slot]; | 
|  | } | 
|  |  | 
|  | void updateCardStatusV6(RIL_CardStatus_v6 *card_status,int slot) | 
|  | { | 
|  | if(cur_CardS_Status[slot] != NULL) { | 
|  | RLOGD("[slot%d]updateCardStatusV6", slot); | 
|  | for(int i = 0; i < cur_CardS_Status[slot]->num_applications; i++) { | 
|  | free(cur_CardS_Status[slot]->applications[i].aid_ptr); | 
|  | cur_CardS_Status[slot]->applications[i].aid_ptr = NULL; | 
|  | free(cur_CardS_Status[slot]->applications[i].app_label_ptr); | 
|  | cur_CardS_Status[slot]->applications[i].app_label_ptr = NULL; | 
|  | } | 
|  | free(cur_CardS_Status[slot]); | 
|  | cur_CardS_Status[slot] = NULL; | 
|  | } | 
|  | cur_CardS_Status[slot] = (RIL_CardStatus_v6 *)calloc(1, sizeof(RIL_CardStatus_v6)); | 
|  | memset(cur_CardS_Status[slot], 0, sizeof(RIL_CardStatus_v6)); | 
|  | cur_CardS_Status[slot]->card_state = card_status->card_state; | 
|  | cur_CardS_Status[slot]->cdma_subscription_app_index = card_status->cdma_subscription_app_index; | 
|  | cur_CardS_Status[slot]->gsm_umts_subscription_app_index = card_status->gsm_umts_subscription_app_index; | 
|  | cur_CardS_Status[slot]->ims_subscription_app_index = card_status->ims_subscription_app_index; | 
|  | cur_CardS_Status[slot]->num_applications = card_status->num_applications; | 
|  | cur_CardS_Status[slot]->universal_pin_state = card_status->universal_pin_state; | 
|  | RLOGD("[slot%d]updateCardStatusV6 card_state: %d, cdma_index: %d, gsm_index: %d, " | 
|  | "ims_index: %d, num_applications: %d, universal_pin_state: %d", | 
|  | slot, | 
|  | cur_CardS_Status[slot]->card_state, | 
|  | cur_CardS_Status[slot]->cdma_subscription_app_index, | 
|  | cur_CardS_Status[slot]->gsm_umts_subscription_app_index, | 
|  | cur_CardS_Status[slot]->ims_subscription_app_index, | 
|  | cur_CardS_Status[slot]->num_applications, | 
|  | cur_CardS_Status[slot]->universal_pin_state); | 
|  | if(card_status) | 
|  | { | 
|  | for(int i = 0; i < card_status->num_applications; i++) { | 
|  | cur_CardS_Status[slot]->applications[i].app_state       = card_status->applications[i].app_state; | 
|  | cur_CardS_Status[slot]->applications[i].app_type        = card_status->applications[i].app_type; | 
|  | cur_CardS_Status[slot]->applications[i].perso_substate  = card_status->applications[i].perso_substate; | 
|  | cur_CardS_Status[slot]->applications[i].pin1            = card_status->applications[i].pin1; | 
|  | cur_CardS_Status[slot]->applications[i].pin1_replaced   = card_status->applications[i].pin1_replaced; | 
|  | cur_CardS_Status[slot]->applications[i].pin2            = card_status->applications[i].pin2; | 
|  | cur_CardS_Status[slot]->applications[i].aid_ptr = strdup(card_status->applications[i].aid_ptr); | 
|  | cur_CardS_Status[slot]->applications[i].app_label_ptr = strdup(card_status->applications[i].app_label_ptr); | 
|  | } | 
|  | } else { | 
|  | RLOGD("[slot%d]updateCardStatusV6: sim card message is null", slot); | 
|  | } | 
|  | } | 
|  |  | 
|  | char* getAid(int slot) | 
|  | { | 
|  | char* aid = ""; | 
|  | int index = -1; | 
|  | if(cur_CardS_Status[slot] != NULL){ | 
|  | if(Phone_utils::get_phone_type(slot) == Phone_utils::PHONE_TYPE_CDMA) { | 
|  | index = cur_CardS_Status[slot]->cdma_subscription_app_index; | 
|  | } else { | 
|  | index = cur_CardS_Status[slot]->gsm_umts_subscription_app_index; | 
|  | } | 
|  | if(index >= 0 && index < cur_CardS_Status[slot]->num_applications) { | 
|  | aid =  cur_CardS_Status[slot]->applications[index].aid_ptr; | 
|  | } | 
|  | } | 
|  | RLOGD("[slot%d] index: %d, getAid: %s", slot, index, aid); | 
|  | return aid; | 
|  | } | 
|  |  | 
|  | void update_reg_voice_service_state(int request, char *code, int slot, int32_t token) | 
|  | { | 
|  | if((reg_voice_service_state[slot] != atoi(code)) || ((token&RIL_TOKEN_MARK) == RIL_TOKEN_MARK)) { | 
|  | reg_voice_service_state[slot] = atoi(code); | 
|  | regCodeToServiceState(request, atoi(code), slot); | 
|  | } | 
|  | } | 
|  |  | 
|  | void update_reg_voice_radio_tech(int request, int code, int slot, int32_t token) { | 
|  | if((reg_voice_radio_tech[slot] != code) || ((token&RIL_TOKEN_MARK) == RIL_TOKEN_MARK)){ | 
|  | reg_voice_radio_tech[slot] = code; | 
|  | regCodeToRadioTechnology(request, code, slot); | 
|  | } | 
|  | } | 
|  |  | 
|  | void update_reg_data_service_state(int request, char *code,int slot, int32_t token) | 
|  | { | 
|  | if((reg_data_service_state[slot] != atoi(code)) || ((token&RIL_TOKEN_MARK) == RIL_TOKEN_MARK)) { | 
|  | reg_data_service_state[slot] = atoi(code); | 
|  | regCodeToServiceState(request, atoi(code), slot); | 
|  | } | 
|  | } | 
|  |  | 
|  | void update_reg_data_radio_tech(int request, int code, int slot, int32_t token){ | 
|  | if((reg_data_radio_tech[slot] != code) || ((token&RIL_TOKEN_MARK) == RIL_TOKEN_MARK)) { | 
|  | reg_data_radio_tech[slot] = code; | 
|  | regCodeToRadioTechnology(request, code, slot); | 
|  | } | 
|  | } | 
|  |  | 
|  | void registerRadioOn(RfDesenseTxTest* rf){ | 
|  | if(!m_RfDesense) { | 
|  | m_RfDesense = rf; | 
|  | } | 
|  | } | 
|  |  | 
|  | void unregisterRadioOn() { | 
|  | if(m_RfDesense) { | 
|  | m_RfDesense == NULL; | 
|  | } | 
|  | } | 
|  |  | 
|  | void registerRadioOffOrNotAvailable(RfDesenseTxTest* rf){ | 
|  | if(!m_RfDesense) { | 
|  | m_RfDesense = rf; | 
|  | } | 
|  | } | 
|  |  | 
|  | void unregisterRadioOffOrNotAvailable() { | 
|  | if(m_RfDesense) { | 
|  | m_RfDesense == NULL; | 
|  | } | 
|  | } | 
|  |  | 
|  | void registerOnUnsolOemHookRaw(RfDesenseTxTest* rf){ | 
|  | if(!m_RfDesense) { | 
|  | m_RfDesense = rf; | 
|  | } | 
|  | } | 
|  |  | 
|  | void unregisterOnUnsolOemHookRaw(){ | 
|  | if(m_RfDesense) { | 
|  | m_RfDesense == NULL; | 
|  | } | 
|  | } | 
|  |  | 
|  | void register_response_oem_hook_raw(RfDesenseTxTest* rf){ | 
|  | if(!m_RfDesense) { | 
|  | m_RfDesense = rf; | 
|  | } | 
|  | } | 
|  |  | 
|  | void unregister_response_oem_hook_raw(){ | 
|  | if(m_RfDesense) { | 
|  | m_RfDesense == NULL; | 
|  | } | 
|  | } | 
|  |  | 
|  | void updateRadioStatus(int newValue ,RIL_SOCKET_ID soc_id) | 
|  | { | 
|  | RLOGD("updateRadioStatus oldState: %d, newState: %d", radio_status[soc_id], newValue); | 
|  | bool newOn = (newValue == RADIO_STATE_ON); | 
|  | bool oldOn = (radio_status[soc_id] == RADIO_STATE_ON); | 
|  | bool newAvaiable = (newValue != RADIO_STATE_UNAVAILABLE); | 
|  | bool oldAvaiable = (radio_status[soc_id] != RADIO_STATE_UNAVAILABLE); | 
|  | if (newOn && !oldOn) { | 
|  | RLOGD("RadioStateOn"); | 
|  | //printf("[SIM%d] radio on\n",soc_id +1); | 
|  | if(m_RfDesense){ | 
|  | m_RfDesense->emRadioStateOn(); | 
|  | } | 
|  | } | 
|  |  | 
|  | if ((!newOn || !newAvaiable) && !((!oldOn || !oldAvaiable))) { | 
|  | RLOGD("RadioStateOfforNotAvailable"); | 
|  | //printf("[SIM%d] radio off or not available\n",soc_id +1); | 
|  | if(m_RfDesense){ | 
|  | m_RfDesense->emRadioStateOfforNotAvailable(); | 
|  | } | 
|  | } | 
|  | if(newValue != radio_status[soc_id]) { | 
|  | radio_status[soc_id] = newValue; | 
|  | } | 
|  | } | 
|  |  | 
|  | bool isRadioOn(RIL_SOCKET_ID soc_id) | 
|  | { | 
|  | return radio_status[soc_id] == RADIO_STATE_ON; | 
|  | } | 
|  |  | 
|  | bool isRadioAvailable(RIL_SOCKET_ID soc_id) | 
|  | { | 
|  | return radio_status[soc_id] != RADIO_STATE_UNAVAILABLE; | 
|  | } | 
|  |  | 
|  | static int regCodeToServiceState(int request,int code, int slot) | 
|  | { | 
|  | RLOGD("[slot%d]regCodeToServiceState %d, request: %s",slot, code, android::requestToString(request)); | 
|  | switch (code) | 
|  | { | 
|  | case 0: | 
|  | case 2: // 2 is "searching" | 
|  | case 3: // 3 is "registration denied" | 
|  | case 4: // 4 is "unknown" no vaild in current baseband | 
|  | case 10:// same as 0, but indicates that emergency call is possible. | 
|  | case 12:// same as 2, but indicates that emergency call is possible. | 
|  | case 13:// same as 3, but indicates that emergency call is possible. | 
|  | case 14:// same as 4, but indicates that emergency call is possible. | 
|  | { | 
|  | if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) { | 
|  | printf("[Muser:%d][VOICE REG_STATUS][SIM%d] The current service state is OUT OF SERVICE\n", getpid(), slot); | 
|  | } else { | 
|  | printf("[Muser:%d][DATA  REG_STATUS][SIM%d] The current service state is OUT OF SERVICE\n", getpid(), slot); | 
|  | } | 
|  | return STATE_OUT_OF_SERVICE; | 
|  | } | 
|  |  | 
|  | case 1: | 
|  | case 5: | 
|  | { | 
|  | if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) { | 
|  | printf("[Muser:%d][VOICE REG_STATUS][SIM%d] The current service state is IN SERVICE\n",getpid(), slot); | 
|  | } else { | 
|  | printf("[Muser:%d][DATA  REG_STATUS][SIM%d] The current service state is IN SERVICE\n", getpid(),slot); | 
|  | } | 
|  | return STATE_IN_SERVICE; | 
|  | } | 
|  |  | 
|  | default: | 
|  | { | 
|  | if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) { | 
|  | printf("[Muser:%d][VOICE REG_STATUS][SIM%d] Unexpected service state %d\n", getpid(), slot, code); | 
|  | } else { | 
|  | printf("[Muser:%d][DATA  REG_STATUS][SIM%d] Unexpected service state %d\n", getpid(), slot, code); | 
|  | } | 
|  | RLOGW("[SIM%d]regCodeToServiceState: unexpected service state %d", slot, code); | 
|  | return STATE_OUT_OF_SERVICE; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | static int regCodeToRadioTechnology(int request, int code, int slot) { | 
|  | RLOGD("[slot%d]regCodeToRadioTechnology %d, request: %s",slot, code, android::requestToString(request)); | 
|  | switch(code) { | 
|  | case RADIO_TECH_LTE: | 
|  | { | 
|  | if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) { | 
|  | printf("[Muser:%d][VOICE REG_STATUS][SIM%d] The registered radio technology is 4G\n", getpid(), slot); | 
|  | } else { | 
|  | printf("[Muser:%d][DATA  REG_STATUS][SIM%d] The registered radio technology is 4G\n", getpid(), slot); | 
|  | } | 
|  | break; | 
|  | } | 
|  | case RADIO_TECH_GSM: | 
|  | case RADIO_TECH_GPRS: | 
|  | case RADIO_TECH_EDGE: | 
|  | case RADIO_TECH_IS95A: | 
|  | case RADIO_TECH_IS95B: | 
|  | case RADIO_TECH_1xRTT: | 
|  | { | 
|  | if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) { | 
|  | printf("[Muser:%d][VOICE REG_STATUS][SIM%d] The registered radio technology is 2G\n", getpid(), slot); | 
|  | } else { | 
|  | printf("[Muser:%d][DATA  REG_STATUS][SIM%d] The registered radio technology is 2G\n", getpid(), slot); | 
|  | } | 
|  | break; | 
|  | } | 
|  | case RADIO_TECH_UMTS: | 
|  | case RADIO_TECH_HSDPA: | 
|  | case RADIO_TECH_HSUPA: | 
|  | case RADIO_TECH_HSPA: | 
|  | case RADIO_TECH_EHRPD: | 
|  | case RADIO_TECH_HSPAP: | 
|  | case RADIO_TECH_TD_SCDMA: | 
|  | case RADIO_TECH_EVDO_0: | 
|  | case RADIO_TECH_EVDO_A: | 
|  | case RADIO_TECH_EVDO_B: | 
|  | { | 
|  | if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) { | 
|  | printf("[Muser:%d][VOICE REG_STATUS][SIM%d] The registered radio technology is 3G\n", getpid(), slot); | 
|  | } else { | 
|  | printf("[Muser:%d][DATA  REG_STATUS][SIM%d] The registered radio technology is 3G\n", getpid(), slot); | 
|  | } | 
|  | break; | 
|  | } | 
|  | case RADIO_TECH_UNKNOWN: | 
|  | { | 
|  | if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) { | 
|  | printf("[Muser:%d][VOICE REG_STATUS][SIM%d] The registered radio technology is unknown\n", getpid(), slot); | 
|  | } else { | 
|  | printf("[Muser:%d][DATA  REG_STATUS][SIM%d] The registered radio technology is unknown\n", getpid(), slot); | 
|  | } | 
|  | break; | 
|  | } | 
|  | default: | 
|  | { | 
|  | if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) { | 
|  | printf("[Muser:%d][VOICE REG_STATUS][SIM%d] %d is unexpected value\n",getpid(), slot, code); | 
|  | } else { | 
|  | printf("[Muser:%d][DATA  REG_STATUS][SIM%d] %d is unexpected value\n",getpid(), slot, code); | 
|  | } | 
|  | } | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | int get_reg_data_radio_tech(int slot) { | 
|  | return reg_data_radio_tech[slot]; | 
|  | } | 
|  |  | 
|  | int get_reg_voice_radio_tech(int slot) { | 
|  | return reg_voice_radio_tech[slot]; | 
|  | } | 
|  |  | 
|  | #ifdef ECALL_SUPPORT | 
|  | void ConvertMsd(const char *msdChar, unsigned char *msd) { | 
|  | unsigned int n, x; | 
|  |  | 
|  | for (n = 0; n < MSD_MAX_LENGTH; n++) { | 
|  | if (sscanf(&msdChar[n<<1], "%2x", &x) == 1) { | 
|  | msd[n] = x; | 
|  | } else { | 
|  | RLOGE("invalid MSD characters"); | 
|  | break; | 
|  | } | 
|  | } | 
|  | } | 
|  | #endif /*ECALL_SUPPORT*/ | 
|  |  | 
|  | bool isFinalResponseErrorEx(char* str) { | 
|  | AtLine atline(str, NULL); | 
|  | return (atline.isFinalResponseErrorEx(0) == 1 ? true : false); | 
|  | } | 
|  |  | 
|  | int get_atci_sim(){ | 
|  | return utils::mtk_property_get_int32(ATCI_SIM, 0); | 
|  | } | 
|  |  | 
|  | static char *findNextChar(char *p, char c, int length) | 
|  | { | 
|  | char *ptr = p; | 
|  | int i = 0; | 
|  | while (i++ < length) | 
|  | { | 
|  | if (*ptr++ == c) | 
|  | return ptr; | 
|  | } | 
|  | return NULL; | 
|  | } | 
|  |  | 
|  | static int getGMTval(char *pdata) | 
|  | { | 
|  | char *ptr; | 
|  | ptr = findNextChar(pdata, '+', strlen(pdata)); | 
|  | if (ptr == NULL) | 
|  | { | 
|  | ptr = findNextChar(pdata, '-', strlen(pdata)); | 
|  | if (ptr == NULL) | 
|  | { | 
|  | return 0; | 
|  | } | 
|  | } | 
|  | return atoi(ptr); | 
|  | } | 
|  |  | 
|  | static void adjustGMT2LocalTime(struct tm *src, int dGMTval) | 
|  | { | 
|  | time_t t1, t2; | 
|  | struct tm * ptm; | 
|  | char buf[255]; | 
|  | int dShiftSec; | 
|  |  | 
|  | dShiftSec = dGMTval * 15 * 60; | 
|  | t1 = mktime(src); | 
|  | t2 = (time_t)(t1 + dShiftSec); | 
|  | ptm = gmtime(&t2); | 
|  |  | 
|  | memcpy(src, ptm, sizeof(struct tm)); | 
|  | } | 
|  |  | 
|  | void updateSystemTime(const void *data, int datalen) | 
|  | { | 
|  | char strTime[32]; | 
|  | struct tm tm; | 
|  | time_t t; | 
|  | int dGMTval; | 
|  |  | 
|  | if (data == NULL || datalen <= 0) | 
|  | return; | 
|  |  | 
|  | memset(strTime, 0, sizeof(strTime)); | 
|  | strcat(strTime, "20"); | 
|  | strcat(strTime, (const char *)data); | 
|  |  | 
|  | dGMTval = getGMTval(strTime); | 
|  | memset(&tm, 0, sizeof(struct tm)); | 
|  | strptime(strTime, "%Y/%m/%d,%H:%M:%S", &tm); | 
|  |  | 
|  | adjustGMT2LocalTime(&tm, dGMTval); | 
|  |  | 
|  | t = mktime(&tm); | 
|  | stime(&t); | 
|  |  | 
|  | return; | 
|  | } |