1 /*
2 * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "ims_control.h"
17
18 #include "cellular_call_hisysevent.h"
19 #include "cellular_call_register.h"
20 #include "emergency_utils.h"
21 #include "module_service_utils.h"
22 #include "securec.h"
23 #include "standardize_utils.h"
24
25 namespace OHOS {
26 namespace Telephony {
~IMSControl()27 IMSControl::~IMSControl()
28 {
29 TELEPHONY_LOGI("~IMSControl start");
30 ReleaseAllConnection();
31 }
32
Dial(const CellularCallInfo & callInfo)33 int32_t IMSControl::Dial(const CellularCallInfo &callInfo)
34 {
35 TELEPHONY_LOGI("Dial start");
36 DelayedSingleton<CellularCallHiSysEvent>::GetInstance()->SetCallParameterInfo(
37 callInfo.slotId, static_cast<int32_t>(callInfo.callType), callInfo.videoState);
38 int32_t ret = DialPreJudgment(callInfo);
39 if (ret != TELEPHONY_SUCCESS) {
40 return ret;
41 }
42
43 // sip uri needs to remove separator
44 std::string newPhoneNum(callInfo.phoneNum);
45 StandardizeUtils standardizeUtils;
46 if (newPhoneNum.find('@') != std::string::npos || newPhoneNum.find("%40") != std::string::npos) {
47 newPhoneNum = standardizeUtils.RemoveSeparatorsPhoneNumber(newPhoneNum);
48 }
49
50 CLIRMode clirMode = CLIRMode::DEFAULT;
51 if (IsNeedExecuteMMI(callInfo.slotId, newPhoneNum, clirMode)) {
52 TELEPHONY_LOGI("Dial return, mmi code type.");
53 return RETURN_TYPE_MMI;
54 }
55 return DialJudgment(callInfo.slotId, newPhoneNum, clirMode, callInfo.videoState);
56 }
57
DialJudgment(int32_t slotId,const std::string & phoneNum,CLIRMode & clirMode,int32_t videoState)58 int32_t IMSControl::DialJudgment(int32_t slotId, const std::string &phoneNum, CLIRMode &clirMode, int32_t videoState)
59 {
60 TELEPHONY_LOGI("DialJudgment entry.");
61 if (!CanCall(connectionMap_)) {
62 TELEPHONY_LOGE("DialJudgment return, error type: call state error.");
63 CellularCallHiSysEvent::WriteDialCallFaultEvent(
64 slotId, INVALID_PARAMETER, videoState, CALL_ERR_CALL_COUNTS_EXCEED_LIMIT, "ims dial call state error");
65 return CALL_ERR_CALL_COUNTS_EXCEED_LIMIT;
66 }
67
68 // Calls can be put on hold, recovered, released, added to conversation,
69 // and transferred similarly as defined in 3GPP TS 22.030 [19].
70 if (IsInState(connectionMap_, TelCallState::CALL_STATUS_ACTIVE)) {
71 // New calls must be active, so other calls need to be hold
72 TELEPHONY_LOGI("DialJudgment, have connection in active state.");
73 CellularCallConnectionIMS connection;
74 // - a call can be temporarily disconnected from the ME but the connection is retained by the network
75 connection.HoldCallRequest(slotId);
76 }
77 return EncapsulateDial(slotId, phoneNum, clirMode, videoState);
78 }
79
EncapsulateDial(int32_t slotId,const std::string & phoneNum,CLIRMode & clirMode,int32_t videoState) const80 int32_t IMSControl::EncapsulateDial(
81 int32_t slotId, const std::string &phoneNum, CLIRMode &clirMode, int32_t videoState) const
82 {
83 TELEPHONY_LOGI("EncapsulateDial start");
84
85 ImsDialInfoStruct dialInfo;
86 dialInfo.videoState = videoState;
87 dialInfo.bEmergencyCall = false;
88 EmergencyUtils emergencyUtils;
89 emergencyUtils.IsEmergencyCall(slotId, phoneNum, dialInfo.bEmergencyCall);
90
91 /**
92 * <idx>: integer type;
93 * call identification number as described in 3GPP TS 22.030 [19] subclause 4.5.5.1
94 * this number can be used in +CHLD command operations
95 * <dir>:
96 */
97 dialInfo.phoneNum = phoneNum;
98 /**
99 * <n> (parameter sets the adjustment for outgoing calls):
100 * 0 presentation indicator is used according to the subscription of the CLIR service
101 * 1 CLIR invocation
102 * 2 CLIR suppression
103 */
104 dialInfo.clirMode = clirMode;
105 /**
106 * An example of voice group call service request usage:
107 * ATD*17*753#500; (originate voice group call with the priority level 3)
108 * OK (voice group call setup was successful)
109 */
110
111 CellularCallConnectionIMS cellularCallConnectionIms;
112 return cellularCallConnectionIms.DialRequest(slotId, dialInfo);
113 }
114
HangUp(const CellularCallInfo & callInfo,CallSupplementType type)115 int32_t IMSControl::HangUp(const CellularCallInfo &callInfo, CallSupplementType type)
116 {
117 TELEPHONY_LOGI("HangUp start");
118 switch (type) {
119 case CallSupplementType::TYPE_DEFAULT: {
120 auto pConnection =
121 GetConnectionData<ImsConnectionMap &, CellularCallConnectionIMS *>(connectionMap_, callInfo.phoneNum);
122 if (pConnection == nullptr) {
123 TELEPHONY_LOGI("HangUp: connection cannot be matched, use index directly");
124 pConnection = FindConnectionByIndex<ImsConnectionMap &, CellularCallConnectionIMS *>(
125 connectionMap_, callInfo.index);
126 }
127 if (pConnection == nullptr) {
128 TELEPHONY_LOGE("HangUp return, error type: connection is null");
129 return CALL_ERR_CALL_CONNECTION_NOT_EXIST;
130 }
131
132 if (DelayedSingleton<CellularCallRegister>::GetInstance() != nullptr) {
133 DelayedSingleton<CellularCallRegister>::GetInstance()->ReportSingleCallInfo(
134 pConnection->GetCallReportInfo(), TelCallState::CALL_STATUS_DISCONNECTING);
135 }
136 return pConnection->HangUpRequest(callInfo.slotId, callInfo.phoneNum, callInfo.index);
137 }
138 case CallSupplementType::TYPE_HANG_UP_HOLD_WAIT:
139 // release the second (active) call and recover the first (held) call
140 case CallSupplementType::TYPE_HANG_UP_ACTIVE: {
141 CellularCallConnectionIMS connection;
142 return connection.CallSupplementRequest(callInfo.slotId, type);
143 }
144 case CallSupplementType::TYPE_HANG_UP_ALL: {
145 TELEPHONY_LOGI("HangUp, hang up all call");
146 CellularCallConnectionIMS connection;
147 // The AT command for hanging up all calls is the same as the AT command for rejecting calls,
148 // so the reject interface is reused.
149 return connection.RejectRequest(callInfo.slotId, callInfo.phoneNum, callInfo.index);
150 }
151 default: {
152 TELEPHONY_LOGE("HangUp warring, type is invalid");
153 return TELEPHONY_ERR_ARGUMENT_INVALID;
154 }
155 }
156 }
157
Answer(const CellularCallInfo & callInfo)158 int32_t IMSControl::Answer(const CellularCallInfo &callInfo)
159 {
160 TELEPHONY_LOGI("IMSControl::Answer start");
161 auto pConnection =
162 GetConnectionData<ImsConnectionMap &, CellularCallConnectionIMS *>(connectionMap_, callInfo.phoneNum);
163 if (pConnection == nullptr) {
164 TELEPHONY_LOGE("IMSControl::Answer, error type: connection is null");
165 return CALL_ERR_CALL_CONNECTION_NOT_EXIST;
166 }
167 if (IsInState(connectionMap_, TelCallState::CALL_STATUS_ACTIVE) &&
168 pConnection->GetStatus() == TelCallState::CALL_STATUS_WAITING) {
169 TELEPHONY_LOGI("Answer there is an active call when you call, or third party call waiting");
170 auto con = FindConnectionByState<ImsConnectionMap &, CellularCallConnectionIMS *>(
171 connectionMap_, TelCallState::CALL_STATUS_ACTIVE);
172 if (con == nullptr) {
173 TELEPHONY_LOGE("Answer return, error type: con is null, there are no active calls");
174 return CALL_ERR_CALL_CONNECTION_NOT_EXIST;
175 }
176 return con->SwitchCallRequest(callInfo.slotId);
177 }
178 if (pConnection->GetStatus() == TelCallState::CALL_STATUS_ALERTING ||
179 pConnection->GetStatus() == TelCallState::CALL_STATUS_INCOMING ||
180 pConnection->GetStatus() == TelCallState::CALL_STATUS_WAITING) {
181 return pConnection->AnswerRequest(callInfo.slotId, callInfo.phoneNum, callInfo.videoState, callInfo.index);
182 }
183 TELEPHONY_LOGE("IMSControl::Answer return, error type: call state error, phone not ringing.");
184 return CALL_ERR_CALL_STATE;
185 }
186
Reject(const CellularCallInfo & callInfo)187 int32_t IMSControl::Reject(const CellularCallInfo &callInfo)
188 {
189 TELEPHONY_LOGI("IMSControl::Reject start");
190 auto pConnection =
191 GetConnectionData<ImsConnectionMap &, CellularCallConnectionIMS *>(connectionMap_, callInfo.phoneNum);
192 if (pConnection == nullptr) {
193 TELEPHONY_LOGI("Reject: connection cannot be matched, use index directly");
194 pConnection =
195 FindConnectionByIndex<ImsConnectionMap &, CellularCallConnectionIMS *>(connectionMap_, callInfo.index);
196 }
197 if (pConnection == nullptr) {
198 TELEPHONY_LOGE("IMSControl::Reject, error type: connection is null");
199 return CALL_ERR_CALL_CONNECTION_NOT_EXIST;
200 }
201 if (!pConnection->IsRingingState()) {
202 TELEPHONY_LOGE("IMSControl::Reject return, error type: call state error, phone not ringing.");
203 return CALL_ERR_CALL_STATE;
204 }
205 if (DelayedSingleton<CellularCallRegister>::GetInstance() != nullptr) {
206 DelayedSingleton<CellularCallRegister>::GetInstance()->ReportSingleCallInfo(
207 pConnection->GetCallReportInfo(), TelCallState::CALL_STATUS_DISCONNECTING);
208 }
209 return pConnection->RejectRequest(callInfo.slotId, callInfo.phoneNum, callInfo.index);
210 }
211
HoldCall(int32_t slotId)212 int32_t IMSControl::HoldCall(int32_t slotId)
213 {
214 TELEPHONY_LOGI("HoldCall start");
215 if (IsInState(connectionMap_, TelCallState::CALL_STATUS_INCOMING)) {
216 TELEPHONY_LOGE("HoldCall return, error type: call state error.");
217 return CALL_ERR_CALL_STATE;
218 }
219 CellularCallConnectionIMS cellularCallConnectionIms;
220 return cellularCallConnectionIms.HoldCallRequest(slotId);
221 }
222
UnHoldCall(int32_t slotId)223 int32_t IMSControl::UnHoldCall(int32_t slotId)
224 {
225 TELEPHONY_LOGI("UnHoldCall start");
226 CellularCallConnectionIMS cellularCallConnectionIms;
227 return cellularCallConnectionIms.UnHoldCallRequest(slotId);
228 }
229
SwitchCall(int32_t slotId)230 int32_t IMSControl::SwitchCall(int32_t slotId)
231 {
232 TELEPHONY_LOGI("SwitchCall start");
233 CellularCallConnectionIMS cellularCallConnectionIms;
234 return cellularCallConnectionIms.SwitchCallRequest(slotId);
235 }
236
237 /**
238 * Add another remote party, to which a private communication has been established using
239 * the same procedures as in Section 1.3.8.1, if the number of remote parties does not then
240 * exceed the maximum number allowed, which results in an active multiParty call.
241 */
CombineConference(int32_t slotId)242 int32_t IMSControl::CombineConference(int32_t slotId)
243 {
244 TELEPHONY_LOGI("CombineConference entry");
245 CellularCallConnectionIMS connection;
246 int32_t voiceCall = 0;
247 return connection.CombineConferenceRequest(slotId, voiceCall);
248 }
249
HangUpAllConnection(int32_t slotId)250 int32_t IMSControl::HangUpAllConnection(int32_t slotId)
251 {
252 TELEPHONY_LOGI("HangUpAllConnection entry");
253 CellularCallConnectionIMS connection;
254 int32_t index = connectionMap_.begin()->second.GetIndex();
255 // The AT command for hanging up all calls is the same as the AT command for rejecting calls,
256 // so the reject interface is reused.
257 return connection.RejectRequest(slotId, connectionMap_.begin()->first, index);
258 }
259
InviteToConference(int32_t slotId,const std::vector<std::string> & numberList)260 int32_t IMSControl::InviteToConference(int32_t slotId, const std::vector<std::string> &numberList)
261 {
262 TELEPHONY_LOGI("InviteToConference entry");
263 CellularCallConnectionIMS connection;
264 return connection.InviteToConferenceRequest(slotId, numberList);
265 }
266
KickOutFromConference(int32_t slotId,const std::vector<std::string> & numberList)267 int32_t IMSControl::KickOutFromConference(int32_t slotId, const std::vector<std::string> &numberList)
268 {
269 TELEPHONY_LOGI("KickOutFromConference entry");
270 CellularCallConnectionIMS connection;
271 return connection.KickOutFromConferenceRequest(slotId, numberList);
272 }
273
UpdateImsCallMode(const CellularCallInfo & callInfo,ImsCallMode mode)274 int32_t IMSControl::UpdateImsCallMode(const CellularCallInfo &callInfo, ImsCallMode mode)
275 {
276 TELEPHONY_LOGI("UpdateImsCallMode entry");
277 auto pConnection =
278 GetConnectionData<ImsConnectionMap &, CellularCallConnectionIMS *>(connectionMap_, callInfo.phoneNum);
279 if (pConnection == nullptr) {
280 TELEPHONY_LOGI("UpdateImsCallMode: connection cannot be matched, use index directly");
281 pConnection =
282 FindConnectionByIndex<ImsConnectionMap &, CellularCallConnectionIMS *>(connectionMap_, callInfo.index);
283 }
284 if (pConnection == nullptr) {
285 TELEPHONY_LOGE("IMSControl::UpdateImsCallMode, error type: connection is null");
286 return CALL_ERR_CALL_CONNECTION_NOT_EXIST;
287 }
288 bool bContinue = pConnection->GetStatus() == TelCallState::CALL_STATUS_ALERTING ||
289 pConnection->GetStatus() == TelCallState::CALL_STATUS_ACTIVE;
290 if (!bContinue) {
291 TELEPHONY_LOGE("IMSControl::UpdateImsCallMode return, error type: call state error.");
292 return CALL_ERR_CALL_STATE;
293 }
294 return pConnection->UpdateCallMediaModeRequest(callInfo, mode);
295 }
296
StartRtt(int32_t slotId,const std::string & msg)297 int32_t IMSControl::StartRtt(int32_t slotId, const std::string &msg)
298 {
299 TELEPHONY_LOGI("StartRtt entry");
300 CellularCallConnectionIMS connection;
301 return connection.StartRttRequest(slotId, msg);
302 }
303
StopRtt(int32_t slotId)304 int32_t IMSControl::StopRtt(int32_t slotId)
305 {
306 TELEPHONY_LOGI("StopRtt entry");
307 CellularCallConnectionIMS connection;
308 return connection.StopRttRequest(slotId);
309 }
310
ReleaseAllConnection()311 void IMSControl::ReleaseAllConnection()
312 {
313 connectionMap_.clear();
314 }
315
GetConnectionMap()316 ImsConnectionMap IMSControl::GetConnectionMap()
317 {
318 return connectionMap_;
319 }
320
ReportImsCallsData(int32_t slotId,const ImsCurrentCallList & callInfoList)321 int32_t IMSControl::ReportImsCallsData(int32_t slotId, const ImsCurrentCallList &callInfoList)
322 {
323 if (callInfoList.callSize <= 0 && !connectionMap_.empty()) {
324 return ReportHungUpInfo(slotId);
325 } else if (callInfoList.callSize > 0 && connectionMap_.empty()) {
326 return ReportIncomingInfo(slotId, callInfoList);
327 } else if (callInfoList.callSize > 0 && !connectionMap_.empty()) {
328 return ReportUpdateInfo(slotId, callInfoList);
329 }
330 return TELEPHONY_ERROR;
331 }
332
ReportCallsData(int32_t slotId,const CallInfoList & callInfoList)333 int32_t IMSControl::ReportCallsData(int32_t slotId, const CallInfoList &callInfoList)
334 {
335 return TELEPHONY_ERROR;
336 }
337
ReportHungUpInfo(int32_t slotId)338 int32_t IMSControl::ReportHungUpInfo(int32_t slotId)
339 {
340 TELEPHONY_LOGI("ReportHungUpInfo entry");
341 CallsReportInfo callsReportInfo;
342 for (auto &it : connectionMap_) {
343 CallReportInfo reportInfo = it.second.GetCallReportInfo();
344 reportInfo.state = TelCallState::CALL_STATUS_DISCONNECTED;
345 reportInfo.accountId = slotId;
346 callsReportInfo.callVec.push_back(reportInfo);
347 GetCallFailReason(slotId, connectionMap_);
348 }
349 if (DelayedSingleton<CellularCallRegister>::GetInstance() == nullptr) {
350 TELEPHONY_LOGE("ReportHungUpInfo return, GetInstance() is nullptr.");
351 return TELEPHONY_ERR_LOCAL_PTR_NULL;
352 }
353 callsReportInfo.slotId = slotId;
354 if (isIgnoredHangupReport_) {
355 SetHangupReportIgnoredFlag(false);
356 } else if (isIgnoredIncomingCall_) {
357 isIgnoredIncomingCall_ = false;
358 } else {
359 DelayedSingleton<CellularCallRegister>::GetInstance()->ReportCallsInfo(callsReportInfo);
360 }
361 ReleaseAllConnection();
362 return TELEPHONY_SUCCESS;
363 }
364
ReportIncomingInfo(int32_t slotId,const ImsCurrentCallList & imsCurrentCallInfoList)365 int32_t IMSControl::ReportIncomingInfo(int32_t slotId, const ImsCurrentCallList &imsCurrentCallInfoList)
366 {
367 TELEPHONY_LOGI("ReportIncomingInfo entry");
368 CallsReportInfo callsReportInfo;
369 for (int32_t i = 0; i < imsCurrentCallInfoList.callSize; ++i) {
370 CallReportInfo reportInfo = EncapsulationCallReportInfo(slotId, imsCurrentCallInfoList.calls[i]);
371
372 CellularCallConnectionIMS connection;
373 connection.SetStatus(static_cast<TelCallState>(imsCurrentCallInfoList.calls[i].state));
374 connection.SetIndex(imsCurrentCallInfoList.calls[i].index);
375 connection.SetOrUpdateCallReportInfo(reportInfo);
376 SetConnectionData(connectionMap_, imsCurrentCallInfoList.calls[i].number, connection);
377
378 callsReportInfo.callVec.push_back(reportInfo);
379 }
380 if (DelayedSingleton<CellularCallRegister>::GetInstance() == nullptr) {
381 TELEPHONY_LOGE("ReportIncomingInfo return, GetInstance() is nullptr.");
382 return TELEPHONY_ERR_ARGUMENT_INVALID;
383 }
384 callsReportInfo.slotId = slotId;
385 if (!DelayedSingleton<CellularCallRegister>::GetInstance()->IsCallManagerCallBackRegistered() &&
386 callsReportInfo.callVec.size() != 0 && callsReportInfo.callVec[0].state == TelCallState::CALL_STATUS_INCOMING) {
387 isIgnoredIncomingCall_ = true;
388 } else {
389 DelayedSingleton<CellularCallRegister>::GetInstance()->ReportCallsInfo(callsReportInfo);
390 }
391 return TELEPHONY_SUCCESS;
392 }
393
ReportUpdateInfo(int32_t slotId,const ImsCurrentCallList & callInfoList)394 int32_t IMSControl::ReportUpdateInfo(int32_t slotId, const ImsCurrentCallList &callInfoList)
395 {
396 TELEPHONY_LOGI("ReportUpdateInfo entry");
397 CallsReportInfo callsReportInfo;
398 for (int32_t i = 0; i < callInfoList.callSize; ++i) {
399 CallReportInfo reportInfo = EncapsulationCallReportInfo(slotId, callInfoList.calls[i]);
400
401 auto pConnection = GetConnectionData<ImsConnectionMap &, CellularCallConnectionIMS *>(
402 connectionMap_, callInfoList.calls[i].number);
403 if (pConnection == nullptr) {
404 CellularCallConnectionIMS connection;
405 connection.SetOrUpdateCallReportInfo(reportInfo);
406 connection.SetFlag(true);
407 connection.SetIndex(callInfoList.calls[i].index);
408 SetConnectionData(connectionMap_, callInfoList.calls[i].number, connection);
409 } else {
410 pConnection->SetFlag(true);
411 pConnection->SetIndex(callInfoList.calls[i].index);
412 pConnection->SetOrUpdateCallReportInfo(reportInfo);
413 }
414 callsReportInfo.callVec.push_back(reportInfo);
415 }
416 callsReportInfo.slotId = slotId;
417 DeleteConnection(callsReportInfo, callInfoList);
418 if (DelayedSingleton<CellularCallRegister>::GetInstance() == nullptr) {
419 TELEPHONY_LOGE("ReportUpdateInfo return, GetInstance() is nullptr.");
420 return TELEPHONY_ERR_LOCAL_PTR_NULL;
421 }
422 if (isIgnoredIncomingCall_) {
423 isIgnoredIncomingCall_ = false;
424 } else {
425 DelayedSingleton<CellularCallRegister>::GetInstance()->ReportCallsInfo(callsReportInfo);
426 }
427 return TELEPHONY_SUCCESS;
428 }
429
EncapsulationCallReportInfo(int32_t slotId,const ImsCurrentCall & callInfo)430 CallReportInfo IMSControl::EncapsulationCallReportInfo(int32_t slotId, const ImsCurrentCall &callInfo)
431 {
432 TELEPHONY_LOGI("EncapsulationCallReportInfo entry");
433 CallReportInfo callReportInfo;
434 if (memset_s(&callReportInfo, sizeof(callReportInfo), 0, sizeof(callReportInfo)) != EOK) {
435 TELEPHONY_LOGE("EncapsulationCallReportInfo return, memset_s fail.");
436 return callReportInfo;
437 }
438
439 size_t cpyLen = strlen(callInfo.number.c_str()) + 1;
440 if (cpyLen > static_cast<size_t>(kMaxNumberLen + 1)) {
441 TELEPHONY_LOGE("EncapsulationCallReportInfo return, strcpy_s fail.");
442 return callReportInfo;
443 }
444 if (strcpy_s(callReportInfo.accountNum, cpyLen, callInfo.number.c_str()) != EOK) {
445 TELEPHONY_LOGE("EncapsulationCallReportInfo return, strcpy_s fail.");
446 return callReportInfo;
447 }
448 callReportInfo.index = callInfo.index;
449 callReportInfo.accountId = slotId;
450 callReportInfo.state = static_cast<TelCallState>(callInfo.state);
451 callReportInfo.voiceDomain = callInfo.voiceDomain;
452 callReportInfo.callType = CallType::TYPE_IMS;
453 callReportInfo.callMode = callInfo.callType ? VideoStateType::TYPE_VIDEO : VideoStateType::TYPE_VOICE;
454 return callReportInfo;
455 }
456
DeleteConnection(CallsReportInfo & callsReportInfo,const ImsCurrentCallList & callInfoList)457 void IMSControl::DeleteConnection(CallsReportInfo &callsReportInfo, const ImsCurrentCallList &callInfoList)
458 {
459 TELEPHONY_LOGI("DeleteConnection entry");
460 auto it = connectionMap_.begin();
461 while (it != connectionMap_.end()) {
462 if (!it->second.GetFlag()) {
463 CallReportInfo callReportInfo = it->second.GetCallReportInfo();
464 callReportInfo.state = TelCallState::CALL_STATUS_DISCONNECTED;
465 callsReportInfo.callVec.push_back(callReportInfo);
466 connectionMap_.erase(it++);
467 GetCallFailReason(callsReportInfo.slotId, connectionMap_);
468 } else {
469 it->second.SetFlag(false);
470 ++it;
471 }
472 }
473 }
474 } // namespace Telephony
475 } // namespace OHOS
476