• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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