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