• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "cs_control.h"
17 
18 #include "securec.h"
19 
20 #include "standardize_utils.h"
21 #include "module_service_utils.h"
22 #include "cellular_call_register.h"
23 
24 namespace OHOS {
25 namespace Telephony {
~CSControl()26 CSControl::~CSControl()
27 {
28     ReleaseAllConnection();
29 }
30 
Dial(const CellularCallInfo & callInfo)31 int32_t CSControl::Dial(const CellularCallInfo &callInfo)
32 {
33     TELEPHONY_LOGI("Dial start");
34     int32_t ret = DialPreJudgment(callInfo);
35     if (ret != TELEPHONY_SUCCESS) {
36         return ret;
37     }
38 
39     ModuleServiceUtils moduleServiceUtils;
40     PhoneType netType = moduleServiceUtils.GetNetworkStatus(callInfo.slotId);
41     if (netType == PhoneType::PHONE_TYPE_IS_GSM) {
42         return DialGsm(callInfo);
43     }
44     if (netType == PhoneType::PHONE_TYPE_IS_CDMA) {
45         return DialCdma(callInfo);
46     }
47     TELEPHONY_LOGE("Dial return, net type error.");
48     return CALL_ERR_UNSUPPORTED_NETWORK_TYPE;
49 }
50 
DialCdma(const CellularCallInfo & callInfo)51 int32_t CSControl::DialCdma(const CellularCallInfo &callInfo)
52 {
53     if (!CanCall(connectionMap_)) {
54         TELEPHONY_LOGE("CSControl::DialCdma return, error type: call state error.");
55         return CALL_ERR_CALL_COUNTS_EXCEED_LIMIT;
56     }
57 
58     StandardizeUtils standardizeUtils;
59     // Remove the phone number separator
60     std::string newPhoneNum = standardizeUtils.RemoveSeparatorsPhoneNumber(callInfo.phoneNum);
61 
62     if (IsInState(connectionMap_, TelCallState::CALL_STATUS_ACTIVE)) {
63         TELEPHONY_LOGI("DialCdma, CDMA is have connection in active state.");
64         CellularCallConnectionCS csConnection;
65         return csConnection.SendCDMAThreeWayDialRequest(callInfo.slotId);
66     }
67     CLIRMode clirMode = CLIRMode::DEFAULT;
68     return EncapsulateDialCommon(callInfo.slotId, newPhoneNum, clirMode);
69 }
70 
DialGsm(const CellularCallInfo & callInfo)71 int32_t CSControl::DialGsm(const CellularCallInfo &callInfo)
72 {
73     TELEPHONY_LOGI("DialGsm entry.");
74     StandardizeUtils standardizeUtils;
75     // Remove the phone number separator
76     std::string newPhoneNum = standardizeUtils.RemoveSeparatorsPhoneNumber(callInfo.phoneNum);
77 
78     CLIRMode clirMode = CLIRMode::DEFAULT;
79     if (IsNeedExecuteMMI(callInfo.slotId, newPhoneNum, clirMode)) {
80         TELEPHONY_LOGI("DialGsm return, mmi code type.");
81         return RETURN_TYPE_MMI;
82     }
83 
84     if (!CanCall(connectionMap_)) {
85         TELEPHONY_LOGE("DialGsm return, error type: call state error.");
86         return CALL_ERR_CALL_COUNTS_EXCEED_LIMIT;
87     }
88 
89     // Calls can be put on hold, recovered, released, added to conversation,
90     // and transferred similarly as defined in 3GPP TS 22.030 [19].
91     if (IsInState(connectionMap_, TelCallState::CALL_STATUS_ACTIVE)) {
92         // New calls must be active, so other calls need to be hold
93         TELEPHONY_LOGI("DialGsm, GSM is have connection in active state.");
94         CellularCallConnectionCS pConnection;
95 
96         // Delay dialing to prevent failure to add a new call while making a multi-party call
97         // Will it block the main thread or other threads? Will the reception of messages be blocked during sleep?
98         // - a call can be temporarily disconnected from the ME but the connection is retained by the network
99         pConnection.SwitchCallRequest(callInfo.slotId);
100     }
101     return EncapsulateDialCommon(callInfo.slotId, newPhoneNum, clirMode);
102 }
103 
EncapsulateDialCommon(int32_t slotId,const std::string & phoneNum,CLIRMode & clirMode)104 int32_t CSControl::EncapsulateDialCommon(int32_t slotId, const std::string &phoneNum, CLIRMode &clirMode)
105 {
106     DialRequestStruct dialRequest;
107     /**
108      * <idx>: integer type;
109      * call identification number as described in 3GPP TS 22.030 [19] subclause 4.5.5.1
110      * this number can be used in +CHLD command operations
111      * <dir>:
112      */
113     dialRequest.phoneNum = phoneNum;
114 
115     /**
116      * <n> (parameter sets the adjustment for outgoing calls):
117      *  0	presentation indicator is used according to the subscription of the CLIR service
118      *  1	CLIR invocation
119      *  2	CLIR suppression
120      */
121     dialRequest.clirMode = clirMode;
122 
123     /**
124      * An example of voice group call service request usage:
125      * ATD*17*753#500; (originate voice group call with the priority level 3)
126      * OK (voice group call setup was successful)
127      */
128     CellularCallConnectionCS csConnection;
129     return csConnection.DialRequest(slotId, dialRequest);
130 }
131 
HangUp(const CellularCallInfo & callInfo,CallSupplementType type)132 int32_t CSControl::HangUp(const CellularCallInfo &callInfo, CallSupplementType type)
133 {
134     TELEPHONY_LOGI("HangUp start");
135     switch (type) {
136         case CallSupplementType::TYPE_DEFAULT: {
137             // Match the session connection according to the phone number string
138             auto pConnection =
139                 GetConnectionData<CsConnectionMap &, CellularCallConnectionCS *>(connectionMap_, callInfo.phoneNum);
140             if (pConnection == nullptr) {
141                 TELEPHONY_LOGI("HangUp: connection cannot be matched, use index directly");
142                 pConnection = FindConnectionByIndex<CsConnectionMap &, CellularCallConnectionCS *>(
143                     connectionMap_, callInfo.index);
144             }
145             if (pConnection == nullptr) {
146                 TELEPHONY_LOGE("CSControl::HangUp, error type: connection is null");
147                 return CALL_ERR_CALL_CONNECTION_NOT_EXIST;
148             }
149 
150             if (DelayedSingleton<CellularCallRegister>::GetInstance() != nullptr) {
151                 DelayedSingleton<CellularCallRegister>::GetInstance()->ReportSingleCallInfo(
152                     pConnection->GetCallReportInfo(), TelCallState::CALL_STATUS_DISCONNECTING);
153             }
154 
155             /**
156              * The "directory number" case shall be handled with dial command D,
157              * and the END case with hangup command H (or +CHUP).
158              * (e.g. +CHLD: (0,1,1x,2,2x,3)).
159              * NOTE: Call Hold, MultiParty and Explicit Call Transfer are only applicable to teleservice 11.
160              */
161             return pConnection->HangUpRequest(callInfo.slotId);
162         }
163         // 3GPP TS 27.007 V3.9.0 (2001-06) Call related supplementary services +CHLD
164         // 3GPP TS 27.007 V3.9.0 (2001-06) 7.22	Informative examples
165         case CallSupplementType::TYPE_HANG_UP_HOLD_WAIT:
166         // release the second (active) call and recover the first (held) call
167         case CallSupplementType::TYPE_HANG_UP_ACTIVE: {
168             CellularCallConnectionCS connection;
169             return connection.CallSupplementRequest(callInfo.slotId, type);
170         }
171         case CallSupplementType::TYPE_HANG_UP_ALL: {
172             TELEPHONY_LOGI("HangUp, hang up all call");
173             CellularCallConnectionCS connection;
174             // The AT command for hanging up all calls is the same as the AT command for rejecting calls,
175             // so the reject interface is reused.
176             return connection.RejectRequest(callInfo.slotId);
177         }
178         default: {
179             TELEPHONY_LOGE("HangUp warring, type is invalid");
180             return TELEPHONY_ERR_ARGUMENT_INVALID;
181         }
182     }
183 }
184 
Answer(const CellularCallInfo & callInfo)185 int32_t CSControl::Answer(const CellularCallInfo &callInfo)
186 {
187     auto pConnection =
188         GetConnectionData<CsConnectionMap &, CellularCallConnectionCS *>(connectionMap_, callInfo.phoneNum);
189     if (pConnection == nullptr) {
190         TELEPHONY_LOGI("Answer: connection cannot be matched, use index directly");
191         pConnection =
192             FindConnectionByIndex<CsConnectionMap &, CellularCallConnectionCS *>(connectionMap_, callInfo.index);
193     }
194     if (pConnection == nullptr) {
195         TELEPHONY_LOGE("Answer return, error type: connection is null");
196         return CALL_ERR_CALL_CONNECTION_NOT_EXIST;
197     }
198 
199     /**
200      * <stat> (state of the call):
201      * 0 active
202      * 1 held
203      * 2 dialing (MO call)
204      * 3 alerting (MO call)
205      * 4 incoming (MT call)
206      * 5 waiting (MT call)
207      */
208     // There is an active call when you call, or third party call waiting
209     if (IsInState(connectionMap_, TelCallState::CALL_STATUS_ACTIVE) ||
210         pConnection->GetStatus() == TelCallState::CALL_STATUS_WAITING) {
211         TELEPHONY_LOGI("Answer there is an active call when you call, or third party call waiting");
212         auto con = FindConnectionByState<CsConnectionMap &, CellularCallConnectionCS *>(
213             connectionMap_, TelCallState::CALL_STATUS_ACTIVE);
214         if (con != nullptr) {
215             /**
216              * shows commands to start the call, to switch from voice to data (In Call Modification) and to hang up
217              * the call. +CMOD and +FCLASS commands indicate the current settings before dialling or answering
218              * command, not that they shall be given just before D or A command.
219              */
220             TELEPHONY_LOGI("Answer: There is an active session currently, and it needs to hold");
221             con->SwitchCallRequest(callInfo.slotId);
222         } else {
223             TELEPHONY_LOGE("Answer return, error type: con is null, there are no active calls");
224         }
225     }
226 
227     if (pConnection->GetStatus() == TelCallState::CALL_STATUS_INCOMING ||
228         pConnection->GetStatus() == TelCallState::CALL_STATUS_ALERTING ||
229         pConnection->GetStatus() == TelCallState::CALL_STATUS_WAITING) {
230         return pConnection->AnswerRequest(callInfo.slotId);
231     }
232 
233     TELEPHONY_LOGE("CSControl::Answer return, error type: call state error, phone not ringing.");
234     return CALL_ERR_CALL_STATE;
235 }
236 
Reject(const CellularCallInfo & callInfo)237 int32_t CSControl::Reject(const CellularCallInfo &callInfo)
238 {
239     auto pConnection =
240         GetConnectionData<CsConnectionMap &, CellularCallConnectionCS *>(connectionMap_, callInfo.phoneNum);
241     if (pConnection == nullptr) {
242         TELEPHONY_LOGI("Reject: connection cannot be matched, use index directly");
243         pConnection =
244             FindConnectionByIndex<CsConnectionMap &, CellularCallConnectionCS *>(connectionMap_, callInfo.index);
245     }
246     if (pConnection == nullptr) {
247         TELEPHONY_LOGE("CSControl::Reject, error type: connection is null");
248         return CALL_ERR_CALL_CONNECTION_NOT_EXIST;
249     }
250 
251     /**
252      * shows commands to start the call, to switch from voice to data (In Call Modification) and to hang up the call.
253      * +CMOD and +FCLASS commands indicate the current settings before dialling or answering command,
254      * not that they shall be given just before D or A command.
255      */
256     if (!pConnection->IsRingingState()) {
257         TELEPHONY_LOGE("CSControl::Reject return, error type: call state error, phone not ringing.");
258         return CALL_ERR_CALL_STATE;
259     }
260     if (DelayedSingleton<CellularCallRegister>::GetInstance() != nullptr) {
261         DelayedSingleton<CellularCallRegister>::GetInstance()->ReportSingleCallInfo(
262             pConnection->GetCallReportInfo(), TelCallState::CALL_STATUS_DISCONNECTING);
263     }
264     return pConnection->RejectRequest(callInfo.slotId);
265 }
266 
HoldCall(int32_t slotId)267 int32_t CSControl::HoldCall(int32_t slotId)
268 {
269     /**
270      * When the call hold service is invoked, communication is interrupted on the traffic channel and the traffic
271      * channel is released from the existing call. The traffic channel is reserved for the served mobile subscriber
272      * invoking the call hold service. The served mobile subscriber can only have one call on hold at a time.
273      */
274     if (IsInState(connectionMap_, TelCallState::CALL_STATUS_INCOMING)) {
275         TELEPHONY_LOGE("HoldCall return, error type: call state error.");
276         return CALL_ERR_CALL_STATE;
277     }
278     CellularCallConnectionCS connection;
279     return connection.HoldRequest(slotId);
280 }
281 
UnHoldCall(int32_t slotId)282 int32_t CSControl::UnHoldCall(int32_t slotId)
283 {
284     // A notification shall be send towards the previously held party that the call has been retrieved.
285     if (IsInState(connectionMap_, TelCallState::CALL_STATUS_INCOMING)) {
286         TELEPHONY_LOGE("UnHoldCall return, error type: call state error.");
287         return CALL_ERR_CALL_STATE;
288     }
289     CellularCallConnectionCS connection;
290     return connection.UnHoldCallRequest(slotId);
291 }
292 
SwitchCall(int32_t slotId)293 int32_t CSControl::SwitchCall(int32_t slotId)
294 {
295     /**
296      * If the served mobile subscriber is connected to an active call and has another call on hold, she can:
297      * 1) Alternate from one call to the other.
298      * 2) Disconnect the active call.
299      * 3) Disconnect the held call.
300      * 4) Disconnect both calls.
301      */
302     if (IsInState(connectionMap_, TelCallState::CALL_STATUS_INCOMING)) {
303         TELEPHONY_LOGE("SwitchCall return, error type: call state error.");
304         return CALL_ERR_CALL_STATE;
305     }
306     CellularCallConnectionCS connection;
307     return connection.SwitchCallRequest(slotId);
308 }
309 
310 /**
311  * Explicitly choose one remote party to have a private communication with.
312  * This results in that remote party being removed from the multiParty call which is placed on hold,
313  * and the conversation between the served mobile subscriber and the designated remote party being a normal
314  * active call. The remaining remote parties may have communication with each other in this state.
315  */
SeparateConference(int32_t slotId,const std::string & splitString,int32_t index)316 int32_t CSControl::SeparateConference(int32_t slotId, const std::string &splitString, int32_t index)
317 {
318     if (splitString.empty()) {
319         TELEPHONY_LOGW("SeparateConference, splitString is empty.");
320     }
321 
322     auto pConnection = GetConnectionData<CsConnectionMap &, CellularCallConnectionCS *>(connectionMap_, splitString);
323     if (pConnection != nullptr) {
324         return pConnection->SeparateConferenceRequest(slotId, pConnection->GetIndex(), VOICE_CALL);
325     }
326 
327     TELEPHONY_LOGI("SeparateConference: connection cannot be matched, use index directly");
328     CellularCallConnectionCS connection;
329     return connection.SeparateConferenceRequest(slotId, index, VOICE_CALL);
330 }
331 
332 /**
333  * Add another remote party, to which a private communication has been established using
334  * the same procedures as in Section 1.3.8.1, if the number of remote parties does not then
335  * exceed the maximum number allowed, which results in an active multiParty call.
336  */
CombineConference(int32_t slotId)337 int32_t CSControl::CombineConference(int32_t slotId)
338 {
339     CellularCallConnectionCS connectionCs;
340     return connectionCs.CombineConferenceRequest(slotId, VOICE_CALL);
341 }
342 
HangUpAllConnection(int32_t slotId)343 int32_t CSControl::HangUpAllConnection(int32_t slotId)
344 {
345     TELEPHONY_LOGI("HangUpAllConnection entry");
346     CellularCallConnectionCS connection;
347     // The AT command for hanging up all calls is the same as the AT command for rejecting calls,
348     // so the reject interface is reused.
349     return connection.RejectRequest(slotId);
350 }
351 
CalculateInternationalRoaming(int32_t slotId) const352 bool CSControl::CalculateInternationalRoaming(int32_t slotId) const
353 {
354     bool ret = true;
355     ModuleServiceUtils moduleServiceUtils;
356     std::string operatorCountryIso = moduleServiceUtils.GetNetworkCountryCode(slotId);
357     std::string simCountryIso = moduleServiceUtils.GetIsoCountryCode(slotId);
358     ret = !operatorCountryIso.empty() && !simCountryIso.empty() && (operatorCountryIso != simCountryIso);
359     if (ret) {
360         if (simCountryIso == "us") {
361             ret = operatorCountryIso != "vi";
362         } else if (simCountryIso == "vi") {
363             ret = operatorCountryIso != "us";
364         }
365     }
366     return ret;
367 }
368 
ReportCallsData(int32_t slotId,const CallInfoList & callInfoList)369 int32_t CSControl::ReportCallsData(int32_t slotId, const CallInfoList &callInfoList)
370 {
371     if (callInfoList.callSize <= 0 && !connectionMap_.empty()) {
372         return ReportHungUpInfo(slotId);
373     } else if (callInfoList.callSize > 0 && connectionMap_.empty()) {
374         return ReportIncomingInfo(slotId, callInfoList);
375     } else if (callInfoList.callSize > 0 && !connectionMap_.empty()) {
376         return ReportUpdateInfo(slotId, callInfoList);
377     }
378     return TELEPHONY_ERROR;
379 }
380 
ReportUpdateInfo(int32_t slotId,const CallInfoList & callInfoList)381 int32_t CSControl::ReportUpdateInfo(int32_t slotId, const CallInfoList &callInfoList)
382 {
383     TELEPHONY_LOGI("ReportUpdateInfo entry");
384     CallsReportInfo callsReportInfo;
385     for (int32_t i = 0; i < callInfoList.callSize; ++i) {
386         CallReportInfo reportInfo = EncapsulationCallReportInfo(slotId, callInfoList.calls[i]);
387 
388         auto pConnection = GetConnectionData<CsConnectionMap &, CellularCallConnectionCS *>(
389             connectionMap_, callInfoList.calls[i].number);
390         if (pConnection == nullptr) {
391             CellularCallConnectionCS connection;
392             connection.SetOrUpdateCallReportInfo(reportInfo);
393             connection.SetFlag(true);
394             connection.SetIndex(callInfoList.calls[i].index);
395             SetConnectionData(connectionMap_, callInfoList.calls[i].number, connection);
396         } else {
397             pConnection->SetFlag(true);
398             pConnection->SetIndex(callInfoList.calls[i].index);
399             pConnection->SetOrUpdateCallReportInfo(reportInfo);
400         }
401         callsReportInfo.callVec.push_back(reportInfo);
402     }
403     callsReportInfo.slotId = slotId;
404     DeleteConnection(callsReportInfo, callInfoList);
405     if (DelayedSingleton<CellularCallRegister>::GetInstance() == nullptr) {
406         TELEPHONY_LOGE("ReportUpdateInfo return, GetInstance() is nullptr.");
407         return TELEPHONY_ERR_LOCAL_PTR_NULL;
408     }
409     DelayedSingleton<CellularCallRegister>::GetInstance()->ReportCallsInfo(callsReportInfo);
410     return TELEPHONY_SUCCESS;
411 }
412 
DeleteConnection(CallsReportInfo & callsReportInfo,const CallInfoList & callInfoList)413 void CSControl::DeleteConnection(CallsReportInfo &callsReportInfo, const CallInfoList &callInfoList)
414 {
415     auto it = connectionMap_.begin();
416     while (it != connectionMap_.end()) {
417         CallReportInfo callReportInfo = it->second.GetCallReportInfo();
418         if (!it->second.GetFlag()) {
419             callReportInfo.state = TelCallState::CALL_STATUS_DISCONNECTED;
420             callsReportInfo.callVec.push_back(callReportInfo);
421             connectionMap_.erase(it++);
422             GetCallFailReason(callsReportInfo.slotId, connectionMap_);
423         } else {
424             it->second.SetFlag(false);
425             ++it;
426         }
427     }
428 }
429 
EncapsulationCallReportInfo(int32_t slotId,const CallInfo & callInfo)430 CallReportInfo CSControl::EncapsulationCallReportInfo(int32_t slotId, const CallInfo &callInfo)
431 {
432     CallReportInfo callReportInfo;
433     if (memset_s(&callReportInfo, sizeof(callReportInfo), 0, sizeof(callReportInfo)) != EOK) {
434         TELEPHONY_LOGE("EncapsulationCallReportInfo return, memset_s fail.");
435         return callReportInfo;
436     }
437 
438     /**
439      * <idx>: integer type;
440      * call identification number as described in 3GPP TS 22.030 [19] subclause 4.5.5.1
441      * this number can be used in +CHLD command operations
442      * <dir>:
443      */
444     size_t cpyLen = strlen(callInfo.number.c_str()) + 1;
445     if (strcpy_s(callReportInfo.accountNum, cpyLen, callInfo.number.c_str()) != EOK) {
446         TELEPHONY_LOGE("EncapsulationCallReportInfo return, strcpy_s fail.");
447         return callReportInfo;
448     }
449 
450     /**
451      * <stat> (state of the call):
452      * 0 active
453      * 1 held
454      * 2 dialing (MO call)
455      * 3 alerting (MO call)
456      * 4 incoming (MT call)
457      * 5 waiting (MT call)
458      */
459     callReportInfo.index = callInfo.index;
460     callReportInfo.accountId = slotId;
461     callReportInfo.voiceDomain = callInfo.voiceDomain;
462     callReportInfo.state = static_cast<TelCallState>(callInfo.state);
463     callReportInfo.callType = CallType::TYPE_CS;
464     callReportInfo.callMode = VideoStateType::TYPE_VOICE;
465     return callReportInfo;
466 }
467 
ReportIncomingInfo(int32_t slotId,const CallInfoList & callInfoList)468 int32_t CSControl::ReportIncomingInfo(int32_t slotId, const CallInfoList &callInfoList)
469 {
470     TELEPHONY_LOGI("ReportIncomingInfo entry");
471     CallsReportInfo callsReportInfo;
472     for (int32_t i = 0; i < callInfoList.callSize; ++i) {
473         CallReportInfo cellularCallReportInfo = EncapsulationCallReportInfo(slotId, callInfoList.calls[i]);
474 
475         CellularCallConnectionCS connection;
476         connection.SetStatus(static_cast<TelCallState>(callInfoList.calls[i].state));
477         connection.SetIndex(callInfoList.calls[i].index);
478         connection.SetOrUpdateCallReportInfo(cellularCallReportInfo);
479         SetConnectionData(connectionMap_, callInfoList.calls[i].number, connection);
480 
481         callsReportInfo.callVec.push_back(cellularCallReportInfo);
482     }
483     if (DelayedSingleton<CellularCallRegister>::GetInstance() == nullptr) {
484         TELEPHONY_LOGE("ReportIncomingInfo return, GetInstance() is nullptr.");
485         return TELEPHONY_ERR_ARGUMENT_INVALID;
486     }
487     callsReportInfo.slotId = slotId;
488     DelayedSingleton<CellularCallRegister>::GetInstance()->ReportCallsInfo(callsReportInfo);
489     return TELEPHONY_SUCCESS;
490 }
491 
ReportHungUpInfo(int32_t slotId)492 int32_t CSControl::ReportHungUpInfo(int32_t slotId)
493 {
494     TELEPHONY_LOGI("ReportHungUpInfo entry");
495     CallsReportInfo callsReportInfo;
496     for (auto &it : connectionMap_) {
497         CallReportInfo callReportInfo = it.second.GetCallReportInfo();
498         callReportInfo.state = TelCallState::CALL_STATUS_DISCONNECTED;
499         callReportInfo.accountId = slotId;
500         callsReportInfo.callVec.push_back(callReportInfo);
501         GetCallFailReason(slotId, connectionMap_);
502     }
503     if (DelayedSingleton<CellularCallRegister>::GetInstance() == nullptr) {
504         TELEPHONY_LOGE("ReportHungUpInfo return, GetInstance() is nullptr.");
505         return TELEPHONY_ERR_LOCAL_PTR_NULL;
506     }
507     callsReportInfo.slotId = slotId;
508     DelayedSingleton<CellularCallRegister>::GetInstance()->ReportCallsInfo(callsReportInfo);
509     ReleaseAllConnection();
510     return TELEPHONY_SUCCESS;
511 }
512 
ReleaseAllConnection()513 void CSControl::ReleaseAllConnection()
514 {
515     connectionMap_.clear();
516 }
517 
GetConnectionMap()518 CsConnectionMap CSControl::GetConnectionMap()
519 {
520     return connectionMap_;
521 }
522 } // namespace Telephony
523 } // namespace OHOS