1d95e75fdSopenharmony_ci/* 2d95e75fdSopenharmony_ci * Copyright (C) 2021-2022 Huawei Device Co., Ltd. 3d95e75fdSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4d95e75fdSopenharmony_ci * you may not use this file except in compliance with the License. 5d95e75fdSopenharmony_ci * You may obtain a copy of the License at 6d95e75fdSopenharmony_ci * 7d95e75fdSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8d95e75fdSopenharmony_ci * 9d95e75fdSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10d95e75fdSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11d95e75fdSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d95e75fdSopenharmony_ci * See the License for the specific language governing permissions and 13d95e75fdSopenharmony_ci * limitations under the License. 14d95e75fdSopenharmony_ci */ 15d95e75fdSopenharmony_ci 16d95e75fdSopenharmony_ci#include "ims_control.h" 17d95e75fdSopenharmony_ci 18d95e75fdSopenharmony_ci#include "cellular_call_hisysevent.h" 19d95e75fdSopenharmony_ci#include "cellular_call_register.h" 20d95e75fdSopenharmony_ci#include "emergency_utils.h" 21d95e75fdSopenharmony_ci#include "module_service_utils.h" 22d95e75fdSopenharmony_ci#include "securec.h" 23d95e75fdSopenharmony_ci#include "standardize_utils.h" 24d95e75fdSopenharmony_ci 25d95e75fdSopenharmony_cinamespace OHOS { 26d95e75fdSopenharmony_cinamespace Telephony { 27d95e75fdSopenharmony_ciIMSControl::~IMSControl() 28d95e75fdSopenharmony_ci{ 29d95e75fdSopenharmony_ci TELEPHONY_LOGI("~IMSControl start"); 30d95e75fdSopenharmony_ci ReleaseAllConnection(); 31d95e75fdSopenharmony_ci} 32d95e75fdSopenharmony_ci 33d95e75fdSopenharmony_ciint32_t IMSControl::Dial(const CellularCallInfo &callInfo, bool isEcc) 34d95e75fdSopenharmony_ci{ 35d95e75fdSopenharmony_ci TELEPHONY_LOGI("Dial start"); 36d95e75fdSopenharmony_ci DelayedSingleton<CellularCallHiSysEvent>::GetInstance()->SetCallParameterInfo( 37d95e75fdSopenharmony_ci callInfo.slotId, static_cast<int32_t>(callInfo.callType), callInfo.videoState); 38d95e75fdSopenharmony_ci int32_t ret = DialPreJudgment(callInfo, isEcc); 39d95e75fdSopenharmony_ci if (ret != TELEPHONY_SUCCESS) { 40d95e75fdSopenharmony_ci return ret; 41d95e75fdSopenharmony_ci } 42d95e75fdSopenharmony_ci ModuleServiceUtils moduleServiceUtils; 43d95e75fdSopenharmony_ci RegServiceState regState = moduleServiceUtils.GetPsRegState(callInfo.slotId); 44d95e75fdSopenharmony_ci if (!(regState == RegServiceState::REG_STATE_IN_SERVICE || isEcc)) { 45d95e75fdSopenharmony_ci TELEPHONY_LOGE("can not dial."); 46d95e75fdSopenharmony_ci return TELEPHONY_ERR_NETWORK_NOT_IN_SERVICE; 47d95e75fdSopenharmony_ci } 48d95e75fdSopenharmony_ci // sip uri needs to remove separator 49d95e75fdSopenharmony_ci std::string newPhoneNum(callInfo.phoneNum); 50d95e75fdSopenharmony_ci StandardizeUtils standardizeUtils; 51d95e75fdSopenharmony_ci if (newPhoneNum.find('@') != std::string::npos || newPhoneNum.find("%40") != std::string::npos) { 52d95e75fdSopenharmony_ci newPhoneNum = standardizeUtils.RemoveSeparatorsPhoneNumber(newPhoneNum); 53d95e75fdSopenharmony_ci } 54d95e75fdSopenharmony_ci 55d95e75fdSopenharmony_ci CLIRMode clirMode = CLIRMode::DEFAULT; 56d95e75fdSopenharmony_ci if (IsNeedExecuteMMI(callInfo.slotId, newPhoneNum, clirMode, true)) { 57d95e75fdSopenharmony_ci TELEPHONY_LOGI("Dial return, mmi code type."); 58d95e75fdSopenharmony_ci return RETURN_TYPE_MMI; 59d95e75fdSopenharmony_ci } 60d95e75fdSopenharmony_ci return DialJudgment(callInfo.slotId, newPhoneNum, clirMode, callInfo.videoState); 61d95e75fdSopenharmony_ci} 62d95e75fdSopenharmony_ci 63d95e75fdSopenharmony_ciint32_t IMSControl::DialJudgment(int32_t slotId, const std::string &phoneNum, CLIRMode &clirMode, int32_t videoState) 64d95e75fdSopenharmony_ci{ 65d95e75fdSopenharmony_ci TELEPHONY_LOGI("DialJudgment entry."); 66d95e75fdSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(connectionMapMutex_); 67d95e75fdSopenharmony_ci if (!CanCall(connectionMap_)) { 68d95e75fdSopenharmony_ci TELEPHONY_LOGE("DialJudgment return, error type: call state error."); 69d95e75fdSopenharmony_ci CellularCallHiSysEvent::WriteDialCallFaultEvent( 70d95e75fdSopenharmony_ci slotId, INVALID_PARAMETER, videoState, CALL_ERR_CALL_COUNTS_EXCEED_LIMIT, "ims dial call state error"); 71d95e75fdSopenharmony_ci return CALL_ERR_CALL_COUNTS_EXCEED_LIMIT; 72d95e75fdSopenharmony_ci } 73d95e75fdSopenharmony_ci pendingPhoneNumber_ = phoneNum; 74d95e75fdSopenharmony_ci // Calls can be put on hold, recovered, released, added to conversation, 75d95e75fdSopenharmony_ci // and transferred similarly as defined in 3GPP TS 22.030 [19]. 76d95e75fdSopenharmony_ci for (auto &connection : connectionMap_) { 77d95e75fdSopenharmony_ci if (connection.second.GetStatus() == TelCallState::CALL_STATUS_ACTIVE && 78d95e75fdSopenharmony_ci !connection.second.IsPendingHangup()) { 79d95e75fdSopenharmony_ci TELEPHONY_LOGI("DialJudgment, have connection in active state."); 80d95e75fdSopenharmony_ci EmergencyUtils emergencyUtils; 81d95e75fdSopenharmony_ci bool isEmergency = false; 82d95e75fdSopenharmony_ci emergencyUtils.IsEmergencyCall(slotId, phoneNum, isEmergency); 83d95e75fdSopenharmony_ci connection.second.SetHoldToDialInfo(phoneNum, clirMode, videoState, isEmergency); 84d95e75fdSopenharmony_ci connection.second.SetDialFlag(true); 85d95e75fdSopenharmony_ci // - a call can be temporarily disconnected from the ME but the connection is retained by the network 86d95e75fdSopenharmony_ci return connection.second.SwitchCallRequest(slotId); 87d95e75fdSopenharmony_ci } 88d95e75fdSopenharmony_ci } 89d95e75fdSopenharmony_ci return EncapsulateDial(slotId, phoneNum, clirMode, videoState); 90d95e75fdSopenharmony_ci} 91d95e75fdSopenharmony_ci 92d95e75fdSopenharmony_ciint32_t IMSControl::EncapsulateDial( 93d95e75fdSopenharmony_ci int32_t slotId, const std::string &phoneNum, CLIRMode &clirMode, int32_t videoState) const 94d95e75fdSopenharmony_ci{ 95d95e75fdSopenharmony_ci TELEPHONY_LOGI("EncapsulateDial start"); 96d95e75fdSopenharmony_ci 97d95e75fdSopenharmony_ci ImsDialInfoStruct dialInfo; 98d95e75fdSopenharmony_ci dialInfo.videoState = videoState; 99d95e75fdSopenharmony_ci dialInfo.bEmergencyCall = false; 100d95e75fdSopenharmony_ci EmergencyUtils emergencyUtils; 101d95e75fdSopenharmony_ci emergencyUtils.IsEmergencyCall(slotId, phoneNum, dialInfo.bEmergencyCall); 102d95e75fdSopenharmony_ci 103d95e75fdSopenharmony_ci /** 104d95e75fdSopenharmony_ci * <idx>: integer type; 105d95e75fdSopenharmony_ci * call identification number as described in 3GPP TS 22.030 [19] subclause 4.5.5.1 106d95e75fdSopenharmony_ci * this number can be used in +CHLD command operations 107d95e75fdSopenharmony_ci * <dir>: 108d95e75fdSopenharmony_ci */ 109d95e75fdSopenharmony_ci dialInfo.phoneNum = phoneNum; 110d95e75fdSopenharmony_ci /** 111d95e75fdSopenharmony_ci * <n> (parameter sets the adjustment for outgoing calls): 112d95e75fdSopenharmony_ci * 0 presentation indicator is used according to the subscription of the CLIR service 113d95e75fdSopenharmony_ci * 1 CLIR invocation 114d95e75fdSopenharmony_ci * 2 CLIR suppression 115d95e75fdSopenharmony_ci */ 116d95e75fdSopenharmony_ci dialInfo.clirMode = clirMode; 117d95e75fdSopenharmony_ci /** 118d95e75fdSopenharmony_ci * An example of voice group call service request usage: 119d95e75fdSopenharmony_ci * ATD*17*753#500; (originate voice group call with the priority level 3) 120d95e75fdSopenharmony_ci * OK (voice group call setup was successful) 121d95e75fdSopenharmony_ci */ 122d95e75fdSopenharmony_ci 123d95e75fdSopenharmony_ci CellularCallConnectionIMS cellularCallConnectionIms; 124d95e75fdSopenharmony_ci return cellularCallConnectionIms.DialRequest(slotId, dialInfo); 125d95e75fdSopenharmony_ci} 126d95e75fdSopenharmony_ci 127d95e75fdSopenharmony_ciint32_t IMSControl::HangUp(const CellularCallInfo &callInfo, CallSupplementType type) 128d95e75fdSopenharmony_ci{ 129d95e75fdSopenharmony_ci TELEPHONY_LOGI("HangUp start"); 130d95e75fdSopenharmony_ci switch (type) { 131d95e75fdSopenharmony_ci case CallSupplementType::TYPE_DEFAULT: { 132d95e75fdSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(connectionMapMutex_); 133d95e75fdSopenharmony_ci auto pConnection = FindConnectionByIndex<ImsConnectionMap &, CellularCallConnectionIMS *>( 134d95e75fdSopenharmony_ci connectionMap_, callInfo.index); 135d95e75fdSopenharmony_ci if (pConnection == nullptr) { 136d95e75fdSopenharmony_ci TELEPHONY_LOGE("HangUp return, error type: connection is null"); 137d95e75fdSopenharmony_ci return CALL_ERR_CALL_CONNECTION_NOT_EXIST; 138d95e75fdSopenharmony_ci } 139d95e75fdSopenharmony_ci pConnection->SetHangupFlag(true); 140d95e75fdSopenharmony_ci if (DelayedSingleton<CellularCallRegister>::GetInstance() != nullptr) { 141d95e75fdSopenharmony_ci DelayedSingleton<CellularCallRegister>::GetInstance()->ReportSingleCallInfo( 142d95e75fdSopenharmony_ci pConnection->GetCallReportInfo(), TelCallState::CALL_STATUS_DISCONNECTING); 143d95e75fdSopenharmony_ci } 144d95e75fdSopenharmony_ci return pConnection->HangUpRequest(callInfo.slotId, callInfo.phoneNum, callInfo.index); 145d95e75fdSopenharmony_ci } 146d95e75fdSopenharmony_ci case CallSupplementType::TYPE_HANG_UP_HOLD_WAIT: 147d95e75fdSopenharmony_ci // release the second (active) call and recover the first (held) call 148d95e75fdSopenharmony_ci case CallSupplementType::TYPE_HANG_UP_ACTIVE: { 149d95e75fdSopenharmony_ci CellularCallConnectionIMS connection; 150d95e75fdSopenharmony_ci return connection.CallSupplementRequest(callInfo.slotId, type); 151d95e75fdSopenharmony_ci } 152d95e75fdSopenharmony_ci case CallSupplementType::TYPE_HANG_UP_ALL: { 153d95e75fdSopenharmony_ci TELEPHONY_LOGI("HangUp, hang up all call"); 154d95e75fdSopenharmony_ci CellularCallConnectionIMS connection; 155d95e75fdSopenharmony_ci // The AT command for hanging up all calls is the same as the AT command for rejecting calls, 156d95e75fdSopenharmony_ci // so the reject interface is reused. 157d95e75fdSopenharmony_ci return connection.RejectRequest(callInfo.slotId, callInfo.phoneNum, callInfo.index); 158d95e75fdSopenharmony_ci } 159d95e75fdSopenharmony_ci default: { 160d95e75fdSopenharmony_ci TELEPHONY_LOGE("HangUp warring, type is invalid"); 161d95e75fdSopenharmony_ci return TELEPHONY_ERR_ARGUMENT_INVALID; 162d95e75fdSopenharmony_ci } 163d95e75fdSopenharmony_ci } 164d95e75fdSopenharmony_ci} 165d95e75fdSopenharmony_ci 166d95e75fdSopenharmony_ciint32_t IMSControl::Answer(const CellularCallInfo &callInfo) 167d95e75fdSopenharmony_ci{ 168d95e75fdSopenharmony_ci TELEPHONY_LOGI("IMSControl::Answer start"); 169d95e75fdSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(connectionMapMutex_); 170d95e75fdSopenharmony_ci auto pConnection = FindConnectionByIndex<ImsConnectionMap &, CellularCallConnectionIMS *>( 171d95e75fdSopenharmony_ci connectionMap_, callInfo.index); 172d95e75fdSopenharmony_ci if (pConnection == nullptr) { 173d95e75fdSopenharmony_ci TELEPHONY_LOGE("HangUp return, error type: connection is null"); 174d95e75fdSopenharmony_ci return CALL_ERR_CALL_CONNECTION_NOT_EXIST; 175d95e75fdSopenharmony_ci } 176d95e75fdSopenharmony_ci if (IsInState(connectionMap_, TelCallState::CALL_STATUS_HOLDING) && 177d95e75fdSopenharmony_ci IsInState(connectionMap_, TelCallState::CALL_STATUS_ACTIVE)) { 178d95e75fdSopenharmony_ci TELEPHONY_LOGD("already threeway mode. hangup holding call and pickup new call"); 179d95e75fdSopenharmony_ci int32_t ret = CheckAndHangupHoldingCall(); 180d95e75fdSopenharmony_ci if (ret != TELEPHONY_SUCCESS) { 181d95e75fdSopenharmony_ci TELEPHONY_LOGE("hangup holding call failed"); 182d95e75fdSopenharmony_ci return ret; 183d95e75fdSopenharmony_ci } 184d95e75fdSopenharmony_ci } 185d95e75fdSopenharmony_ci auto con = FindConnectionByState<ImsConnectionMap &, CellularCallConnectionIMS *>( 186d95e75fdSopenharmony_ci connectionMap_, TelCallState::CALL_STATUS_ACTIVE); 187d95e75fdSopenharmony_ci if (con != nullptr && !con->IsPendingHold() && 188d95e75fdSopenharmony_ci pConnection->GetStatus() == TelCallState::CALL_STATUS_WAITING) { 189d95e75fdSopenharmony_ci TELEPHONY_LOGI("Answer there is an active call when you call, or third party call waiting"); 190d95e75fdSopenharmony_ci return con->SwitchCallRequest(callInfo.slotId); 191d95e75fdSopenharmony_ci } 192d95e75fdSopenharmony_ci if (pConnection->GetStatus() == TelCallState::CALL_STATUS_ALERTING || 193d95e75fdSopenharmony_ci pConnection->GetStatus() == TelCallState::CALL_STATUS_INCOMING || 194d95e75fdSopenharmony_ci pConnection->GetStatus() == TelCallState::CALL_STATUS_WAITING) { 195d95e75fdSopenharmony_ci return pConnection->AnswerRequest(callInfo.slotId, callInfo.phoneNum, callInfo.videoState, callInfo.index); 196d95e75fdSopenharmony_ci } 197d95e75fdSopenharmony_ci TELEPHONY_LOGE("IMSControl::Answer return, error type: call state error, phone not ringing."); 198d95e75fdSopenharmony_ci return CALL_ERR_CALL_STATE; 199d95e75fdSopenharmony_ci} 200d95e75fdSopenharmony_ci 201d95e75fdSopenharmony_ciint32_t IMSControl::CheckAndHangupHoldingCall() 202d95e75fdSopenharmony_ci{ 203d95e75fdSopenharmony_ci for (auto &it : connectionMap_) { 204d95e75fdSopenharmony_ci CellularCallConnectionIMS holdConn = it.second; 205d95e75fdSopenharmony_ci if (holdConn.GetStatus() == TelCallState::CALL_STATUS_HOLDING) { 206d95e75fdSopenharmony_ci auto callReportInfo = holdConn.GetCallReportInfo(); 207d95e75fdSopenharmony_ci int32_t result = holdConn.HangUpRequest(callReportInfo.accountId, 208d95e75fdSopenharmony_ci callReportInfo.accountNum, callReportInfo.index); 209d95e75fdSopenharmony_ci if (result != TELEPHONY_SUCCESS) { 210d95e75fdSopenharmony_ci return result; 211d95e75fdSopenharmony_ci } 212d95e75fdSopenharmony_ci } 213d95e75fdSopenharmony_ci } 214d95e75fdSopenharmony_ci return TELEPHONY_SUCCESS; 215d95e75fdSopenharmony_ci} 216d95e75fdSopenharmony_ci 217d95e75fdSopenharmony_ciint32_t IMSControl::Reject(const CellularCallInfo &callInfo) 218d95e75fdSopenharmony_ci{ 219d95e75fdSopenharmony_ci TELEPHONY_LOGI("IMSControl::Reject start"); 220d95e75fdSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(connectionMapMutex_); 221d95e75fdSopenharmony_ci auto pConnection = 222d95e75fdSopenharmony_ci FindConnectionByIndex<ImsConnectionMap &, CellularCallConnectionIMS *>(connectionMap_, callInfo.index); 223d95e75fdSopenharmony_ci if (pConnection == nullptr) { 224d95e75fdSopenharmony_ci TELEPHONY_LOGE("IMSControl::Reject, error type: connection is null"); 225d95e75fdSopenharmony_ci return CALL_ERR_CALL_CONNECTION_NOT_EXIST; 226d95e75fdSopenharmony_ci } 227d95e75fdSopenharmony_ci if (!pConnection->IsRingingState()) { 228d95e75fdSopenharmony_ci TELEPHONY_LOGE("IMSControl::Reject return, error type: call state error, phone not ringing."); 229d95e75fdSopenharmony_ci return CALL_ERR_CALL_STATE; 230d95e75fdSopenharmony_ci } 231d95e75fdSopenharmony_ci if (DelayedSingleton<CellularCallRegister>::GetInstance() != nullptr) { 232d95e75fdSopenharmony_ci DelayedSingleton<CellularCallRegister>::GetInstance()->ReportSingleCallInfo( 233d95e75fdSopenharmony_ci pConnection->GetCallReportInfo(), TelCallState::CALL_STATUS_DISCONNECTING); 234d95e75fdSopenharmony_ci } 235d95e75fdSopenharmony_ci return pConnection->RejectRequest(callInfo.slotId, callInfo.phoneNum, callInfo.index); 236d95e75fdSopenharmony_ci} 237d95e75fdSopenharmony_ci 238d95e75fdSopenharmony_ciint32_t IMSControl::HoldCall(int32_t slotId) 239d95e75fdSopenharmony_ci{ 240d95e75fdSopenharmony_ci TELEPHONY_LOGI("HoldCall start"); 241d95e75fdSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(connectionMapMutex_); 242d95e75fdSopenharmony_ci if (IsInState(connectionMap_, TelCallState::CALL_STATUS_INCOMING)) { 243d95e75fdSopenharmony_ci TELEPHONY_LOGE("HoldCall return, error type: call state error."); 244d95e75fdSopenharmony_ci return CALL_ERR_CALL_STATE; 245d95e75fdSopenharmony_ci } 246d95e75fdSopenharmony_ci CellularCallConnectionIMS cellularCallConnectionIms; 247d95e75fdSopenharmony_ci return cellularCallConnectionIms.HoldCallRequest(slotId); 248d95e75fdSopenharmony_ci} 249d95e75fdSopenharmony_ci 250d95e75fdSopenharmony_ciint32_t IMSControl::UnHoldCall(int32_t slotId) 251d95e75fdSopenharmony_ci{ 252d95e75fdSopenharmony_ci TELEPHONY_LOGI("UnHoldCall start"); 253d95e75fdSopenharmony_ci CellularCallConnectionIMS cellularCallConnectionIms; 254d95e75fdSopenharmony_ci return cellularCallConnectionIms.UnHoldCallRequest(slotId); 255d95e75fdSopenharmony_ci} 256d95e75fdSopenharmony_ci 257d95e75fdSopenharmony_ciint32_t IMSControl::SwitchCall(int32_t slotId) 258d95e75fdSopenharmony_ci{ 259d95e75fdSopenharmony_ci TELEPHONY_LOGI("SwitchCall start"); 260d95e75fdSopenharmony_ci CellularCallConnectionIMS cellularCallConnectionIms; 261d95e75fdSopenharmony_ci return cellularCallConnectionIms.SwitchCallRequest(slotId); 262d95e75fdSopenharmony_ci} 263d95e75fdSopenharmony_ci 264d95e75fdSopenharmony_ci/** 265d95e75fdSopenharmony_ci * Add another remote party, to which a private communication has been established using 266d95e75fdSopenharmony_ci * the same procedures as in Section 1.3.8.1, if the number of remote parties does not then 267d95e75fdSopenharmony_ci * exceed the maximum number allowed, which results in an active multiParty call. 268d95e75fdSopenharmony_ci */ 269d95e75fdSopenharmony_ciint32_t IMSControl::CombineConference(int32_t slotId) 270d95e75fdSopenharmony_ci{ 271d95e75fdSopenharmony_ci TELEPHONY_LOGI("CombineConference entry"); 272d95e75fdSopenharmony_ci CellularCallConnectionIMS connection; 273d95e75fdSopenharmony_ci int32_t voiceCall = 0; 274d95e75fdSopenharmony_ci return connection.CombineConferenceRequest(slotId, voiceCall); 275d95e75fdSopenharmony_ci} 276d95e75fdSopenharmony_ci 277d95e75fdSopenharmony_ciint32_t IMSControl::HangUpAllConnection(int32_t slotId) 278d95e75fdSopenharmony_ci{ 279d95e75fdSopenharmony_ci TELEPHONY_LOGI("HangUpAllConnection entry"); 280d95e75fdSopenharmony_ci CellularCallConnectionIMS connection; 281d95e75fdSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(connectionMapMutex_); 282d95e75fdSopenharmony_ci if (connectionMap_.empty()) { 283d95e75fdSopenharmony_ci TELEPHONY_LOGI("connectionMap_ is empty."); 284d95e75fdSopenharmony_ci return TELEPHONY_ERROR; 285d95e75fdSopenharmony_ci } 286d95e75fdSopenharmony_ci for (auto &it : connectionMap_) { 287d95e75fdSopenharmony_ci int32_t index = it.second.GetIndex(); 288d95e75fdSopenharmony_ci std::string number = it.second.GetNumber(); 289d95e75fdSopenharmony_ci connection.RejectRequest(slotId, number, index); 290d95e75fdSopenharmony_ci } 291d95e75fdSopenharmony_ci // The AT command for hanging up all calls is the same as the AT command for rejecting calls, 292d95e75fdSopenharmony_ci // so the reject interface is reused. 293d95e75fdSopenharmony_ci return TELEPHONY_SUCCESS; 294d95e75fdSopenharmony_ci} 295d95e75fdSopenharmony_ci 296d95e75fdSopenharmony_ciint32_t IMSControl::InviteToConference(int32_t slotId, const std::vector<std::string> &numberList) 297d95e75fdSopenharmony_ci{ 298d95e75fdSopenharmony_ci TELEPHONY_LOGI("InviteToConference entry"); 299d95e75fdSopenharmony_ci CellularCallConnectionIMS connection; 300d95e75fdSopenharmony_ci return connection.InviteToConferenceRequest(slotId, numberList); 301d95e75fdSopenharmony_ci} 302d95e75fdSopenharmony_ci 303d95e75fdSopenharmony_ciint32_t IMSControl::KickOutFromConference(int32_t slotId, const std::string &KickOutString, int32_t index) 304d95e75fdSopenharmony_ci{ 305d95e75fdSopenharmony_ci TELEPHONY_LOGI("KickOutFromConference entry"); 306d95e75fdSopenharmony_ci if (KickOutString.empty()) { 307d95e75fdSopenharmony_ci TELEPHONY_LOGW("KickOutFromConference, splitString is empty."); 308d95e75fdSopenharmony_ci } 309d95e75fdSopenharmony_ci 310d95e75fdSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(connectionMapMutex_); 311d95e75fdSopenharmony_ci auto pConnection = FindConnectionByIndex<ImsConnectionMap &, CellularCallConnectionIMS *>(connectionMap_, index); 312d95e75fdSopenharmony_ci if (pConnection != nullptr) { 313d95e75fdSopenharmony_ci return pConnection->KickOutFromConferenceRequest(slotId, pConnection->GetIndex()); 314d95e75fdSopenharmony_ci } 315d95e75fdSopenharmony_ci 316d95e75fdSopenharmony_ci TELEPHONY_LOGI("KickOutFromConference: connection cannot be matched, use index directly"); 317d95e75fdSopenharmony_ci CellularCallConnectionIMS connection; 318d95e75fdSopenharmony_ci return connection.KickOutFromConferenceRequest(slotId, index); 319d95e75fdSopenharmony_ci} 320d95e75fdSopenharmony_ci 321d95e75fdSopenharmony_ciint32_t IMSControl::StartRtt(int32_t slotId, const std::string &msg) 322d95e75fdSopenharmony_ci{ 323d95e75fdSopenharmony_ci TELEPHONY_LOGI("StartRtt entry"); 324d95e75fdSopenharmony_ci CellularCallConnectionIMS connection; 325d95e75fdSopenharmony_ci return connection.StartRttRequest(slotId, msg); 326d95e75fdSopenharmony_ci} 327d95e75fdSopenharmony_ci 328d95e75fdSopenharmony_ciint32_t IMSControl::StopRtt(int32_t slotId) 329d95e75fdSopenharmony_ci{ 330d95e75fdSopenharmony_ci TELEPHONY_LOGI("StopRtt entry"); 331d95e75fdSopenharmony_ci CellularCallConnectionIMS connection; 332d95e75fdSopenharmony_ci return connection.StopRttRequest(slotId); 333d95e75fdSopenharmony_ci} 334d95e75fdSopenharmony_ci 335d95e75fdSopenharmony_civoid IMSControl::ReleaseAllConnection() 336d95e75fdSopenharmony_ci{ 337d95e75fdSopenharmony_ci TELEPHONY_LOGI("ReleaseAllConnection entry"); 338d95e75fdSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(connectionMapMutex_); 339d95e75fdSopenharmony_ci connectionMap_.clear(); 340d95e75fdSopenharmony_ci} 341d95e75fdSopenharmony_ci 342d95e75fdSopenharmony_ciImsConnectionMap IMSControl::GetConnectionMap() 343d95e75fdSopenharmony_ci{ 344d95e75fdSopenharmony_ci TELEPHONY_LOGI("GetConnectionMap entry"); 345d95e75fdSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(connectionMapMutex_); 346d95e75fdSopenharmony_ci return connectionMap_; 347d95e75fdSopenharmony_ci} 348d95e75fdSopenharmony_ci 349d95e75fdSopenharmony_ciint32_t IMSControl::ReportImsCallsData(int32_t slotId, const ImsCurrentCallList &callInfoList) 350d95e75fdSopenharmony_ci{ 351d95e75fdSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(connectionMapMutex_); 352d95e75fdSopenharmony_ci if (callInfoList.callSize <= 0) { 353d95e75fdSopenharmony_ci return ReportHangUpInfo(slotId); 354d95e75fdSopenharmony_ci } else if (callInfoList.callSize > 0 && connectionMap_.empty()) { 355d95e75fdSopenharmony_ci return ReportIncomingInfo(slotId, callInfoList); 356d95e75fdSopenharmony_ci } else if (callInfoList.callSize > 0 && !connectionMap_.empty()) { 357d95e75fdSopenharmony_ci return ReportUpdateInfo(slotId, callInfoList); 358d95e75fdSopenharmony_ci } 359d95e75fdSopenharmony_ci return TELEPHONY_ERROR; 360d95e75fdSopenharmony_ci} 361d95e75fdSopenharmony_ci 362d95e75fdSopenharmony_ciint32_t IMSControl::ReportCallsData(int32_t slotId, const CallInfoList &callInfoList) 363d95e75fdSopenharmony_ci{ 364d95e75fdSopenharmony_ci return TELEPHONY_ERROR; 365d95e75fdSopenharmony_ci} 366d95e75fdSopenharmony_ci 367d95e75fdSopenharmony_ciint32_t IMSControl::ReportHangUpInfo(int32_t slotId) 368d95e75fdSopenharmony_ci{ 369d95e75fdSopenharmony_ci TELEPHONY_LOGI("ReportHangUpInfo entry"); 370d95e75fdSopenharmony_ci CallsReportInfo callsReportInfo; 371d95e75fdSopenharmony_ci for (auto &it : connectionMap_) { 372d95e75fdSopenharmony_ci CallReportInfo reportInfo = it.second.GetCallReportInfo(); 373d95e75fdSopenharmony_ci reportInfo.state = TelCallState::CALL_STATUS_DISCONNECTED; 374d95e75fdSopenharmony_ci reportInfo.accountId = slotId; 375d95e75fdSopenharmony_ci callsReportInfo.callVec.push_back(reportInfo); 376d95e75fdSopenharmony_ci GetCallFailReason(slotId, connectionMap_); 377d95e75fdSopenharmony_ci } 378d95e75fdSopenharmony_ci if (connectionMap_.empty()) { 379d95e75fdSopenharmony_ci TELEPHONY_LOGI("connectionMap_ is empty"); 380d95e75fdSopenharmony_ci CallReportInfo reportInfo; 381d95e75fdSopenharmony_ci reportInfo.state = TelCallState::CALL_STATUS_DISCONNECTED; 382d95e75fdSopenharmony_ci reportInfo.accountId = slotId; 383d95e75fdSopenharmony_ci callsReportInfo.callVec.push_back(reportInfo); 384d95e75fdSopenharmony_ci } 385d95e75fdSopenharmony_ci if (DelayedSingleton<CellularCallRegister>::GetInstance() == nullptr) { 386d95e75fdSopenharmony_ci TELEPHONY_LOGE("ReportHangUpInfo return, GetInstance() is nullptr."); 387d95e75fdSopenharmony_ci return TELEPHONY_ERR_LOCAL_PTR_NULL; 388d95e75fdSopenharmony_ci } 389d95e75fdSopenharmony_ci callsReportInfo.slotId = slotId; 390d95e75fdSopenharmony_ci if (isIgnoredIncomingCall_) { 391d95e75fdSopenharmony_ci isIgnoredIncomingCall_ = false; 392d95e75fdSopenharmony_ci } else { 393d95e75fdSopenharmony_ci DelayedSingleton<CellularCallRegister>::GetInstance()->ReportCallsInfo(callsReportInfo); 394d95e75fdSopenharmony_ci } 395d95e75fdSopenharmony_ci ReleaseAllConnection(); 396d95e75fdSopenharmony_ci return TELEPHONY_SUCCESS; 397d95e75fdSopenharmony_ci} 398d95e75fdSopenharmony_ci 399d95e75fdSopenharmony_ciint32_t IMSControl::ReportIncomingInfo(int32_t slotId, const ImsCurrentCallList &imsCurrentCallInfoList) 400d95e75fdSopenharmony_ci{ 401d95e75fdSopenharmony_ci TELEPHONY_LOGI("ReportIncomingInfo entry"); 402d95e75fdSopenharmony_ci CallsReportInfo callsReportInfo; 403d95e75fdSopenharmony_ci for (int32_t i = 0; i < imsCurrentCallInfoList.callSize; ++i) { 404d95e75fdSopenharmony_ci CallReportInfo reportInfo = EncapsulationCallReportInfo(slotId, imsCurrentCallInfoList.calls[i]); 405d95e75fdSopenharmony_ci 406d95e75fdSopenharmony_ci CellularCallConnectionIMS connection; 407d95e75fdSopenharmony_ci connection.SetStatus(static_cast<TelCallState>(imsCurrentCallInfoList.calls[i].state)); 408d95e75fdSopenharmony_ci connection.SetIndex(imsCurrentCallInfoList.calls[i].index); 409d95e75fdSopenharmony_ci connection.SetNumber(imsCurrentCallInfoList.calls[i].number); 410d95e75fdSopenharmony_ci connection.SetOrUpdateCallReportInfo(reportInfo); 411d95e75fdSopenharmony_ci SetConnectionData(connectionMap_, imsCurrentCallInfoList.calls[i].index, connection); 412d95e75fdSopenharmony_ci 413d95e75fdSopenharmony_ci callsReportInfo.callVec.push_back(reportInfo); 414d95e75fdSopenharmony_ci } 415d95e75fdSopenharmony_ci if (DelayedSingleton<CellularCallRegister>::GetInstance() == nullptr) { 416d95e75fdSopenharmony_ci TELEPHONY_LOGE("ReportIncomingInfo return, GetInstance() is nullptr."); 417d95e75fdSopenharmony_ci return TELEPHONY_ERR_ARGUMENT_INVALID; 418d95e75fdSopenharmony_ci } 419d95e75fdSopenharmony_ci callsReportInfo.slotId = slotId; 420d95e75fdSopenharmony_ci if (!DelayedSingleton<CellularCallRegister>::GetInstance()->IsCallManagerCallBackRegistered() && 421d95e75fdSopenharmony_ci callsReportInfo.callVec.size() != 0 && callsReportInfo.callVec[0].state == TelCallState::CALL_STATUS_INCOMING) { 422d95e75fdSopenharmony_ci isIgnoredIncomingCall_ = true; 423d95e75fdSopenharmony_ci } else { 424d95e75fdSopenharmony_ci DelayedSingleton<CellularCallRegister>::GetInstance()->ReportCallsInfo(callsReportInfo); 425d95e75fdSopenharmony_ci } 426d95e75fdSopenharmony_ci return TELEPHONY_SUCCESS; 427d95e75fdSopenharmony_ci} 428d95e75fdSopenharmony_ci 429d95e75fdSopenharmony_ciint32_t IMSControl::ReportUpdateInfo(int32_t slotId, const ImsCurrentCallList &callInfoList) 430d95e75fdSopenharmony_ci{ 431d95e75fdSopenharmony_ci TELEPHONY_LOGD("ReportUpdateInfo entry"); 432d95e75fdSopenharmony_ci CallsReportInfo callsReportInfo; 433d95e75fdSopenharmony_ci for (int32_t i = 0; i < callInfoList.callSize; ++i) { 434d95e75fdSopenharmony_ci CallReportInfo reportInfo = EncapsulationCallReportInfo(slotId, callInfoList.calls[i]); 435d95e75fdSopenharmony_ci if (callInfoList.callSize == 1 && reportInfo.state == TelCallState::CALL_STATUS_WAITING) { 436d95e75fdSopenharmony_ci TELEPHONY_LOGI("only one call, report incoming state instead of waiting state"); 437d95e75fdSopenharmony_ci reportInfo.state = TelCallState::CALL_STATUS_INCOMING; 438d95e75fdSopenharmony_ci } 439d95e75fdSopenharmony_ci auto pConnection = FindConnectionByIndex<ImsConnectionMap &, CellularCallConnectionIMS *>( 440d95e75fdSopenharmony_ci connectionMap_, callInfoList.calls[i].index); 441d95e75fdSopenharmony_ci if (pConnection == nullptr) { 442d95e75fdSopenharmony_ci CellularCallConnectionIMS connection; 443d95e75fdSopenharmony_ci connection.SetOrUpdateCallReportInfo(reportInfo); 444d95e75fdSopenharmony_ci connection.SetFlag(true); 445d95e75fdSopenharmony_ci connection.SetIndex(callInfoList.calls[i].index); 446d95e75fdSopenharmony_ci connection.SetNumber(callInfoList.calls[i].number); 447d95e75fdSopenharmony_ci SetConnectionData(connectionMap_, callInfoList.calls[i].index, connection); 448d95e75fdSopenharmony_ci } else { 449d95e75fdSopenharmony_ci TelCallState preCallState = pConnection->GetStatus(); 450d95e75fdSopenharmony_ci pConnection->SetFlag(true); 451d95e75fdSopenharmony_ci pConnection->SetIndex(callInfoList.calls[i].index); 452d95e75fdSopenharmony_ci pConnection->SetNumber(callInfoList.calls[i].number); 453d95e75fdSopenharmony_ci pConnection->SetOrUpdateCallReportInfo(reportInfo); 454d95e75fdSopenharmony_ci TelCallState curCallState = pConnection->GetStatus(); 455d95e75fdSopenharmony_ci if (IsConnectedOut(preCallState, curCallState)) { 456d95e75fdSopenharmony_ci pConnection->UpdateCallNumber(pendingPhoneNumber_); 457d95e75fdSopenharmony_ci pendingPhoneNumber_.clear(); 458d95e75fdSopenharmony_ci ExecutePostDial(slotId, pConnection->GetIndex()); 459d95e75fdSopenharmony_ci } 460d95e75fdSopenharmony_ci } 461d95e75fdSopenharmony_ci callsReportInfo.callVec.push_back(reportInfo); 462d95e75fdSopenharmony_ci } 463d95e75fdSopenharmony_ci callsReportInfo.slotId = slotId; 464d95e75fdSopenharmony_ci DeleteConnection(callsReportInfo, callInfoList); 465d95e75fdSopenharmony_ci if (DelayedSingleton<CellularCallRegister>::GetInstance() == nullptr) { 466d95e75fdSopenharmony_ci TELEPHONY_LOGE("ReportUpdateInfo return, GetInstance() is nullptr."); 467d95e75fdSopenharmony_ci return TELEPHONY_ERR_LOCAL_PTR_NULL; 468d95e75fdSopenharmony_ci } 469d95e75fdSopenharmony_ci if (isIgnoredIncomingCall_) { 470d95e75fdSopenharmony_ci isIgnoredIncomingCall_ = false; 471d95e75fdSopenharmony_ci } else { 472d95e75fdSopenharmony_ci DelayedSingleton<CellularCallRegister>::GetInstance()->ReportCallsInfo(callsReportInfo); 473d95e75fdSopenharmony_ci } 474d95e75fdSopenharmony_ci return TELEPHONY_SUCCESS; 475d95e75fdSopenharmony_ci} 476d95e75fdSopenharmony_ci 477d95e75fdSopenharmony_ciCallReportInfo IMSControl::EncapsulationCallReportInfo(int32_t slotId, const ImsCurrentCall &callInfo) 478d95e75fdSopenharmony_ci{ 479d95e75fdSopenharmony_ci TELEPHONY_LOGD("EncapsulationCallReportInfo entry"); 480d95e75fdSopenharmony_ci CallReportInfo callReportInfo; 481d95e75fdSopenharmony_ci if (memset_s(&callReportInfo, sizeof(callReportInfo), 0, sizeof(callReportInfo)) != EOK) { 482d95e75fdSopenharmony_ci TELEPHONY_LOGE("EncapsulationCallReportInfo return, memset_s fail."); 483d95e75fdSopenharmony_ci return callReportInfo; 484d95e75fdSopenharmony_ci } 485d95e75fdSopenharmony_ci 486d95e75fdSopenharmony_ci StandardizeUtils standardizeUtils; 487d95e75fdSopenharmony_ci std::string phoneNumber = callInfo.number.empty() ? callInfo.name : callInfo.number; 488d95e75fdSopenharmony_ci std::string newString = standardizeUtils.FormatNumberAndToa(phoneNumber, callInfo.toa); 489d95e75fdSopenharmony_ci size_t cpyLen = strlen(newString.c_str()) + 1; 490d95e75fdSopenharmony_ci if (cpyLen > static_cast<size_t>(kMaxNumberLen + 1)) { 491d95e75fdSopenharmony_ci TELEPHONY_LOGE("EncapsulationCallReportInfo return, strcpy_s fail."); 492d95e75fdSopenharmony_ci return callReportInfo; 493d95e75fdSopenharmony_ci } 494d95e75fdSopenharmony_ci if (strcpy_s(callReportInfo.accountNum, cpyLen, newString.c_str()) != EOK) { 495d95e75fdSopenharmony_ci TELEPHONY_LOGE("EncapsulationCallReportInfo return, strcpy_s fail."); 496d95e75fdSopenharmony_ci return callReportInfo; 497d95e75fdSopenharmony_ci } 498d95e75fdSopenharmony_ci callReportInfo.index = callInfo.index; 499d95e75fdSopenharmony_ci callReportInfo.accountId = slotId; 500d95e75fdSopenharmony_ci callReportInfo.state = static_cast<TelCallState>(callInfo.state); 501d95e75fdSopenharmony_ci callReportInfo.voiceDomain = callInfo.voiceDomain; 502d95e75fdSopenharmony_ci callReportInfo.callType = CallType::TYPE_IMS; 503d95e75fdSopenharmony_ci switch (callInfo.callType) { 504d95e75fdSopenharmony_ci case ImsCallType::TEL_IMS_CALL_TYPE_VOICE: 505d95e75fdSopenharmony_ci callReportInfo.callMode = VideoStateType::TYPE_VOICE; 506d95e75fdSopenharmony_ci break; 507d95e75fdSopenharmony_ci case ImsCallType::TEL_IMS_CALL_TYPE_VT_TX: 508d95e75fdSopenharmony_ci callReportInfo.callMode = VideoStateType::TYPE_SEND_ONLY; 509d95e75fdSopenharmony_ci break; 510d95e75fdSopenharmony_ci case ImsCallType::TEL_IMS_CALL_TYPE_VT_RX: 511d95e75fdSopenharmony_ci callReportInfo.callMode = VideoStateType::TYPE_RECEIVE_ONLY; 512d95e75fdSopenharmony_ci break; 513d95e75fdSopenharmony_ci case ImsCallType::TEL_IMS_CALL_TYPE_VT: 514d95e75fdSopenharmony_ci callReportInfo.callMode = VideoStateType::TYPE_VIDEO; 515d95e75fdSopenharmony_ci break; 516d95e75fdSopenharmony_ci default: 517d95e75fdSopenharmony_ci callReportInfo.callMode = VideoStateType::TYPE_VOICE; 518d95e75fdSopenharmony_ci break; 519d95e75fdSopenharmony_ci } 520d95e75fdSopenharmony_ci callReportInfo.mpty = callInfo.mpty; 521d95e75fdSopenharmony_ci callReportInfo.crsType = callInfo.toneType; 522d95e75fdSopenharmony_ci callReportInfo.originalCallType = callInfo.callInitialType; 523d95e75fdSopenharmony_ci return callReportInfo; 524d95e75fdSopenharmony_ci} 525d95e75fdSopenharmony_ci 526d95e75fdSopenharmony_civoid IMSControl::DeleteConnection(CallsReportInfo &callsReportInfo, const ImsCurrentCallList &callInfoList) 527d95e75fdSopenharmony_ci{ 528d95e75fdSopenharmony_ci TELEPHONY_LOGI("DeleteConnection entry"); 529d95e75fdSopenharmony_ci auto it = connectionMap_.begin(); 530d95e75fdSopenharmony_ci while (it != connectionMap_.end()) { 531d95e75fdSopenharmony_ci if (!it->second.GetFlag()) { 532d95e75fdSopenharmony_ci CallReportInfo callReportInfo = it->second.GetCallReportInfo(); 533d95e75fdSopenharmony_ci callReportInfo.state = TelCallState::CALL_STATUS_DISCONNECTED; 534d95e75fdSopenharmony_ci callsReportInfo.callVec.push_back(callReportInfo); 535d95e75fdSopenharmony_ci it = connectionMap_.erase(it); 536d95e75fdSopenharmony_ci GetCallFailReason(callsReportInfo.slotId, connectionMap_); 537d95e75fdSopenharmony_ci } else { 538d95e75fdSopenharmony_ci it->second.SetFlag(false); 539d95e75fdSopenharmony_ci ++it; 540d95e75fdSopenharmony_ci } 541d95e75fdSopenharmony_ci } 542d95e75fdSopenharmony_ci} 543d95e75fdSopenharmony_ci 544d95e75fdSopenharmony_ciint32_t IMSControl::ExecutePostDial(int32_t slotId, int64_t callId) 545d95e75fdSopenharmony_ci{ 546d95e75fdSopenharmony_ci TELEPHONY_LOGI("ExecutePostDial entry"); 547d95e75fdSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(connectionMapMutex_); 548d95e75fdSopenharmony_ci if (connectionMap_.empty()) { 549d95e75fdSopenharmony_ci TELEPHONY_LOGE("connectionMap_ is empty."); 550d95e75fdSopenharmony_ci return TELEPHONY_ERROR; 551d95e75fdSopenharmony_ci } 552d95e75fdSopenharmony_ci auto pConnection = FindConnectionByIndex<ImsConnectionMap &, CellularCallConnectionIMS *>(connectionMap_, callId); 553d95e75fdSopenharmony_ci if (pConnection == nullptr) { 554d95e75fdSopenharmony_ci return TELEPHONY_ERR_LOCAL_PTR_NULL; 555d95e75fdSopenharmony_ci } 556d95e75fdSopenharmony_ci char currentChar; 557d95e75fdSopenharmony_ci PostDialCallState state = pConnection->ProcessNextChar(slotId, currentChar); 558d95e75fdSopenharmony_ci switch (state) { 559d95e75fdSopenharmony_ci case PostDialCallState::POST_DIAL_CALL_STARTED: 560d95e75fdSopenharmony_ci DelayedSingleton<CellularCallRegister>::GetInstance()->ReportPostDialChar(currentChar); 561d95e75fdSopenharmony_ci break; 562d95e75fdSopenharmony_ci case PostDialCallState::POST_DIAL_CALL_DELAY: 563d95e75fdSopenharmony_ci DelayedSingleton<CellularCallRegister>::GetInstance()->ReportPostDialDelay( 564d95e75fdSopenharmony_ci pConnection->GetLeftPostDialCallString()); 565d95e75fdSopenharmony_ci break; 566d95e75fdSopenharmony_ci default: 567d95e75fdSopenharmony_ci break; 568d95e75fdSopenharmony_ci } 569d95e75fdSopenharmony_ci return TELEPHONY_SUCCESS; 570d95e75fdSopenharmony_ci} 571d95e75fdSopenharmony_ci 572d95e75fdSopenharmony_ciint32_t IMSControl::PostDialProceed(const CellularCallInfo &callInfo, const bool proceed) 573d95e75fdSopenharmony_ci{ 574d95e75fdSopenharmony_ci TELEPHONY_LOGI("PostDialProceed entry"); 575d95e75fdSopenharmony_ci std::string networkAddress; 576d95e75fdSopenharmony_ci std::string postDialString; 577d95e75fdSopenharmony_ci StandardizeUtils standardizeUtils; 578d95e75fdSopenharmony_ci standardizeUtils.ExtractAddressAndPostDial(callInfo.phoneNum, networkAddress, postDialString); 579d95e75fdSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(connectionMapMutex_); 580d95e75fdSopenharmony_ci auto pConnection = FindConnectionByIndex<ImsConnectionMap &, CellularCallConnectionIMS *>(connectionMap_, 581d95e75fdSopenharmony_ci callInfo.index); 582d95e75fdSopenharmony_ci if (pConnection == nullptr) { 583d95e75fdSopenharmony_ci TELEPHONY_LOGE("ims pConnection is nullptr!"); 584d95e75fdSopenharmony_ci return TELEPHONY_ERR_LOCAL_PTR_NULL; 585d95e75fdSopenharmony_ci } 586d95e75fdSopenharmony_ci if (proceed) { 587d95e75fdSopenharmony_ci ExecutePostDial(callInfo.slotId, pConnection->GetIndex()); 588d95e75fdSopenharmony_ci } else { 589d95e75fdSopenharmony_ci pConnection->SetPostDialCallState(PostDialCallState::POST_DIAL_CALL_CANCELED); 590d95e75fdSopenharmony_ci } 591d95e75fdSopenharmony_ci return TELEPHONY_SUCCESS; 592d95e75fdSopenharmony_ci} 593d95e75fdSopenharmony_ci 594d95e75fdSopenharmony_ciint32_t IMSControl::RestoreConnection(const std::vector<CellularCallInfo> &infos, int32_t slotId) 595d95e75fdSopenharmony_ci{ 596d95e75fdSopenharmony_ci TELEPHONY_LOGI("RestoreConnection entry"); 597d95e75fdSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(connectionMapMutex_); 598d95e75fdSopenharmony_ci for (auto &info : infos) { 599d95e75fdSopenharmony_ci if (info.callType == CallType::TYPE_IMS && info.slotId == slotId) { 600d95e75fdSopenharmony_ci CellularCallConnectionIMS connectionIMS; 601d95e75fdSopenharmony_ci connectionIMS.SetIndex(info.index); 602d95e75fdSopenharmony_ci connectionIMS.SetNumber(info.phoneNum); 603d95e75fdSopenharmony_ci SetConnectionData(connectionMap_, info.index, connectionIMS); 604d95e75fdSopenharmony_ci } 605d95e75fdSopenharmony_ci } 606d95e75fdSopenharmony_ci return TELEPHONY_SUCCESS; 607d95e75fdSopenharmony_ci} 608d95e75fdSopenharmony_ci 609d95e75fdSopenharmony_ciint32_t IMSControl::ReportHangUp(const std::vector<CellularCallInfo> &infos, int32_t slotId) 610d95e75fdSopenharmony_ci{ 611d95e75fdSopenharmony_ci CallsReportInfo callsReportInfo; 612d95e75fdSopenharmony_ci callsReportInfo.slotId = slotId; 613d95e75fdSopenharmony_ci for (const auto &info : infos) { 614d95e75fdSopenharmony_ci if (info.callType == CallType::TYPE_IMS && info.slotId == slotId) { 615d95e75fdSopenharmony_ci CallReportInfo imsCallReportInfo; 616d95e75fdSopenharmony_ci if (memset_s(imsCallReportInfo.accountNum, kMaxNumberLen + 1, 0, kMaxNumberLen + 1) != EOK) { 617d95e75fdSopenharmony_ci TELEPHONY_LOGE("memset_s fail"); 618d95e75fdSopenharmony_ci return TELEPHONY_ERR_MEMSET_FAIL; 619d95e75fdSopenharmony_ci } 620d95e75fdSopenharmony_ci if (memcpy_s(imsCallReportInfo.accountNum, kMaxNumberLen, info.phoneNum, kMaxNumberLen) != EOK) { 621d95e75fdSopenharmony_ci TELEPHONY_LOGE("memcpy_s fail"); 622d95e75fdSopenharmony_ci return TELEPHONY_ERR_MEMCPY_FAIL; 623d95e75fdSopenharmony_ci } 624d95e75fdSopenharmony_ci imsCallReportInfo.index = info.index; 625d95e75fdSopenharmony_ci imsCallReportInfo.accountId = info.slotId; 626d95e75fdSopenharmony_ci imsCallReportInfo.callType = CallType::TYPE_IMS; 627d95e75fdSopenharmony_ci imsCallReportInfo.callMode = 628d95e75fdSopenharmony_ci static_cast<bool>(info.callType) ? VideoStateType::TYPE_VIDEO : VideoStateType::TYPE_VOICE; 629d95e75fdSopenharmony_ci imsCallReportInfo.state = TelCallState::CALL_STATUS_DISCONNECTED; 630d95e75fdSopenharmony_ci callsReportInfo.callVec.push_back(imsCallReportInfo); 631d95e75fdSopenharmony_ci } 632d95e75fdSopenharmony_ci } 633d95e75fdSopenharmony_ci if (DelayedSingleton<CellularCallRegister>::GetInstance() == nullptr) { 634d95e75fdSopenharmony_ci TELEPHONY_LOGE("CellularCallRegister instance is nullptr"); 635d95e75fdSopenharmony_ci return TELEPHONY_ERR_LOCAL_PTR_NULL; 636d95e75fdSopenharmony_ci } 637d95e75fdSopenharmony_ci DelayedSingleton<CellularCallRegister>::GetInstance()->ReportCallsInfo(callsReportInfo); 638d95e75fdSopenharmony_ci return TELEPHONY_SUCCESS; 639d95e75fdSopenharmony_ci} 640d95e75fdSopenharmony_ci 641d95e75fdSopenharmony_civoid IMSControl::DialAfterHold(int32_t slotId) 642d95e75fdSopenharmony_ci{ 643d95e75fdSopenharmony_ci TELEPHONY_LOGI("DialAfterHold entry"); 644d95e75fdSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(connectionMapMutex_); 645d95e75fdSopenharmony_ci for (auto &connection : connectionMap_) { 646d95e75fdSopenharmony_ci if (connection.second.IsNeedToDial()) { 647d95e75fdSopenharmony_ci ImsDialInfoStruct holdToDialInfo = connection.second.GetHoldToDialInfo(); 648d95e75fdSopenharmony_ci CellularCallConnectionIMS cellularCallConnectionIms; 649d95e75fdSopenharmony_ci cellularCallConnectionIms.DialRequest(slotId, holdToDialInfo); 650d95e75fdSopenharmony_ci connection.second.SetDialFlag(false); 651d95e75fdSopenharmony_ci break; 652d95e75fdSopenharmony_ci } 653d95e75fdSopenharmony_ci } 654d95e75fdSopenharmony_ci} 655d95e75fdSopenharmony_ci 656d95e75fdSopenharmony_civoid IMSControl::RecoverPendingHold() 657d95e75fdSopenharmony_ci{ 658d95e75fdSopenharmony_ci TELEPHONY_LOGI("RecoverPendingHold entry"); 659d95e75fdSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(connectionMapMutex_); 660d95e75fdSopenharmony_ci for (auto &connection : connectionMap_) { 661d95e75fdSopenharmony_ci if (connection.second.IsPendingHold()) { 662d95e75fdSopenharmony_ci connection.second.UpdatePendingHoldFlag(false); 663d95e75fdSopenharmony_ci break; 664d95e75fdSopenharmony_ci } 665d95e75fdSopenharmony_ci } 666d95e75fdSopenharmony_ci} 667d95e75fdSopenharmony_ci} // namespace Telephony 668d95e75fdSopenharmony_ci} // namespace OHOS 669