• 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 "call_request_process.h"
17 
18 #include "call_ability_report_proxy.h"
19 #include "call_control_manager.h"
20 #include "call_manager_errors.h"
21 #include "call_manager_hisysevent.h"
22 #include "call_number_utils.h"
23 #include "cellular_call_connection.h"
24 #include "common_type.h"
25 #include "core_service_connection.h"
26 #include "cs_call.h"
27 #include "ims_call.h"
28 #include "ott_call.h"
29 #include "report_call_info_handler.h"
30 #include "telephony_log_wrapper.h"
31 
32 namespace OHOS {
33 namespace Telephony {
CallRequestProcess()34 CallRequestProcess::CallRequestProcess() {}
35 
~CallRequestProcess()36 CallRequestProcess::~CallRequestProcess() {}
37 
DialRequest()38 int32_t CallRequestProcess::DialRequest()
39 {
40     DialParaInfo info;
41     DelayedSingleton<CallControlManager>::GetInstance()->GetDialParaInfo(info);
42     if (!info.isDialing) {
43         TELEPHONY_LOGE("the device is not dialing!");
44         CallManagerHisysevent::WriteDialCallFaultEvent(info.accountId, static_cast<int32_t>(info.callType),
45             static_cast<int32_t>(info.videoState), static_cast<int32_t>(CallErrorCode::CALL_ERROR_DEVICE_NOT_DIALING),
46             "the device is not dialing");
47         return CALL_ERR_ILLEGAL_CALL_OPERATION;
48     }
49     if (info.number.length() > static_cast<size_t>(kMaxNumberLen)) {
50         TELEPHONY_LOGE("Number out of limit!");
51         return CALL_ERR_NUMBER_OUT_OF_RANGE;
52     }
53     if (info.dialType == DialType::DIAL_CARRIER_TYPE &&
54         DelayedSingleton<CoreServiceConnection>::GetInstance()->IsFdnEnabled(info.accountId)) {
55         std::vector<std::u16string> fdnNumberList =
56             DelayedSingleton<CoreServiceConnection>::GetInstance()->GetFdnNumberList(info.accountId);
57         if (!fdnNumberList.empty() && !IsFdnNumber(fdnNumberList, info.number)) {
58             CallEventInfo eventInfo;
59             (void)memset_s(eventInfo.phoneNum, kMaxNumberLen, 0, kMaxNumberLen);
60             eventInfo.eventId = CallAbilityEventId::EVENT_INVALID_FDN_NUMBER;
61             (void)memcpy_s(eventInfo.phoneNum, kMaxNumberLen, info.number.c_str(), info.number.length());
62             DelayedSingleton<CallControlManager>::GetInstance()->NotifyCallEventUpdated(eventInfo);
63             TELEPHONY_LOGW("invalid fdn number!");
64             CallManagerHisysevent::WriteDialCallFaultEvent(info.accountId, static_cast<int32_t>(info.callType),
65                 static_cast<int32_t>(info.videoState),
66                 static_cast<int32_t>(CallErrorCode::CALL_ERROR_INVALID_FDN_NUMBER), "invalid fdn number!");
67             return CALL_ERR_DIAL_FAILED;
68         }
69     }
70     TELEPHONY_LOGI("dialType:%{public}d", info.dialType);
71     int32_t ret = CALL_ERR_UNKNOW_DIAL_TYPE;
72     switch (info.dialType) {
73         case DialType::DIAL_CARRIER_TYPE:
74             ret = CarrierDialProcess(info);
75             break;
76         case DialType::DIAL_VOICE_MAIL_TYPE:
77             ret = VoiceMailDialProcess(info);
78             break;
79         case DialType::DIAL_OTT_TYPE:
80             ret = OttDialProcess(info);
81             break;
82         default:
83             TELEPHONY_LOGE("invalid dialType:%{public}d", info.dialType);
84             break;
85     }
86     return ret;
87 }
88 
AnswerRequest(int32_t callId,int32_t videoState)89 void CallRequestProcess::AnswerRequest(int32_t callId, int32_t videoState)
90 {
91     sptr<CallBase> call = GetOneCallObject(callId);
92     if (call == nullptr) {
93         TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
94         return;
95     }
96     int32_t ret = call->AnswerCall(videoState);
97     if (ret != TELEPHONY_SUCCESS) {
98         TELEPHONY_LOGE("AnswerCall failed!");
99         return;
100     }
101     DelayedSingleton<CallControlManager>::GetInstance()->NotifyIncomingCallAnswered(call);
102 }
103 
RejectRequest(int32_t callId,bool isSendSms,std::string & content)104 void CallRequestProcess::RejectRequest(int32_t callId, bool isSendSms, std::string &content)
105 {
106     sptr<CallBase> call = GetOneCallObject(callId);
107     if (call == nullptr) {
108         TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
109         return;
110     }
111 
112     int32_t ret = call->RejectCall();
113     if (ret != TELEPHONY_SUCCESS) {
114         TELEPHONY_LOGE("RejectCall failed!");
115         return;
116     }
117     TELEPHONY_LOGI("start to send reject message...");
118     DelayedSingleton<CallControlManager>::GetInstance()->NotifyIncomingCallRejected(call, isSendSms, content);
119 }
120 
HangUpRequest(int32_t callId)121 void CallRequestProcess::HangUpRequest(int32_t callId)
122 {
123     sptr<CallBase> call = GetOneCallObject(callId);
124     if (call == nullptr) {
125         TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
126         return;
127     }
128     TelCallState state = call->GetTelCallState();
129     TelConferenceState confState = call->GetTelConferenceState();
130     if (((state == TelCallState::CALL_STATUS_ACTIVE) &&
131         (CallObjectManager::IsCallExist(call->GetCallType(), TelCallState::CALL_STATUS_HOLDING))) ||
132         (confState == TelConferenceState::TEL_CONFERENCE_ACTIVE)) {
133         TELEPHONY_LOGI("release the active call and recover the held call");
134         call->SetPolicyFlag(PolicyFlag::POLICY_FLAG_HANG_UP_ACTIVE);
135     } else if (confState == TelConferenceState::TEL_CONFERENCE_HOLDING) {
136         TELEPHONY_LOGI("release the held call and the wait call");
137         call->SetPolicyFlag(PolicyFlag::POLICY_FLAG_HANG_UP_HOLD_WAIT);
138     }
139     call->HangUpCall();
140     if (state == TelCallState::CALL_STATUS_DIALING || state == TelCallState::CALL_STATUS_ALERTING) {
141         sptr<CallBase> holdCall = CallObjectManager::GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_HOLD);
142         if (holdCall) {
143             TELEPHONY_LOGI("release the dialing/alerting call and recover the held call");
144             holdCall->UnHoldCall();
145         }
146     }
147 }
148 
HoldRequest(int32_t callId)149 void CallRequestProcess::HoldRequest(int32_t callId)
150 {
151     sptr<CallBase> call = GetOneCallObject(callId);
152     if (call == nullptr) {
153         TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
154         return;
155     }
156     call->HoldCall();
157 }
158 
UnHoldRequest(int32_t callId)159 void CallRequestProcess::UnHoldRequest(int32_t callId)
160 {
161     sptr<CallBase> call = GetOneCallObject(callId);
162     if (call == nullptr) {
163         TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
164         return;
165     }
166     call->UnHoldCall();
167 }
168 
SwitchRequest(int32_t callId)169 void CallRequestProcess::SwitchRequest(int32_t callId)
170 {
171     sptr<CallBase> call = GetOneCallObject(callId);
172     if (call == nullptr) {
173         TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
174         return;
175     }
176     call->SwitchCall();
177 }
178 
CombineConferenceRequest(int32_t mainCallId)179 void CallRequestProcess::CombineConferenceRequest(int32_t mainCallId)
180 {
181     sptr<CallBase> call = GetOneCallObject(mainCallId);
182     if (call == nullptr) {
183         TELEPHONY_LOGE("the call object is nullptr, mainCallId:%{public}d", mainCallId);
184         return;
185     }
186     int32_t ret = call->CombineConference();
187     if (ret != TELEPHONY_SUCCESS) {
188         TELEPHONY_LOGE("CombineConference failed");
189     }
190 }
191 
SeparateConferenceRequest(int32_t callId)192 void CallRequestProcess::SeparateConferenceRequest(int32_t callId)
193 {
194     sptr<CallBase> call = GetOneCallObject(callId);
195     if (call == nullptr) {
196         TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
197         return;
198     }
199     int32_t ret = call->SeparateConference();
200     if (ret != TELEPHONY_SUCCESS) {
201         TELEPHONY_LOGE("SeparateConference failed");
202     }
203 }
204 
KickOutFromConferenceRequest(int32_t callId)205 void CallRequestProcess::KickOutFromConferenceRequest(int32_t callId)
206 {
207     sptr<CallBase> call = GetOneCallObject(callId);
208     if (call == nullptr) {
209         TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
210         return;
211     }
212     int32_t ret = call->KickOutFromConference();
213     if (ret != TELEPHONY_SUCCESS) {
214         TELEPHONY_LOGE("KickOutFormConference failed");
215     }
216 }
217 
UpdateImsCallMode(int32_t callId,ImsCallMode mode)218 int32_t CallRequestProcess::UpdateImsCallMode(int32_t callId, ImsCallMode mode)
219 {
220     int32_t ret = TELEPHONY_ERR_FAIL;
221     sptr<CallBase> call = GetOneCallObject(callId);
222     if (call == nullptr) {
223         TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
224         return ret;
225     }
226     // only netcall type support update call media mode
227     if (call->GetCallType() == CallType::TYPE_IMS) {
228         sptr<IMSCall> netCall = reinterpret_cast<IMSCall *>(call.GetRefPtr());
229         TELEPHONY_LOGI("ims call update media request");
230         ret = netCall->SendUpdateCallMediaModeRequest(mode);
231         if (ret != TELEPHONY_SUCCESS) {
232             TELEPHONY_LOGE("SendUpdateCallMediaModeRequest failed. %{public}d", ret);
233         }
234     } else {
235         TELEPHONY_LOGE("the call object not support upgrade/downgrad media, callId:%{public}d", callId);
236     }
237     return ret;
238 }
239 
UpdateCallMediaModeRequest(int32_t callId,ImsCallMode mode)240 void CallRequestProcess::UpdateCallMediaModeRequest(int32_t callId, ImsCallMode mode)
241 {
242     int32_t ret = TELEPHONY_ERR_FAIL;
243     AppExecFwk::PacMap resultInfo;
244     ret = UpdateImsCallMode(callId, mode);
245     if (ret != TELEPHONY_SUCCESS) {
246         resultInfo.PutIntValue("result", ret);
247         DelayedSingleton<CallAbilityReportProxy>::GetInstance()->ReportAsyncResults(
248             CallResultReportId::UPDATE_MEDIA_MODE_REPORT_ID, resultInfo);
249     }
250 }
251 
StartRttRequest(int32_t callId,std::u16string & msg)252 void CallRequestProcess::StartRttRequest(int32_t callId, std::u16string &msg)
253 {
254     sptr<CallBase> call = GetOneCallObject(callId);
255     if (call == nullptr) {
256         TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
257         return;
258     }
259     if (call->GetCallType() != CallType::TYPE_IMS) {
260         TELEPHONY_LOGE("Unsupported Network type, callId:%{public}d", callId);
261         return;
262     } else {
263         sptr<IMSCall> imsCall = reinterpret_cast<IMSCall *>(call.GetRefPtr());
264         imsCall->StartRtt(msg);
265     }
266 }
267 
StopRttRequest(int32_t callId)268 void CallRequestProcess::StopRttRequest(int32_t callId)
269 {
270     sptr<CallBase> call = GetOneCallObject(callId);
271     if (call == nullptr) {
272         TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
273         return;
274     }
275     if (call->GetCallType() != CallType::TYPE_IMS) {
276         TELEPHONY_LOGE("Unsupported Network type, callId:%{public}d", callId);
277         return;
278     } else {
279         sptr<IMSCall> imsCall = reinterpret_cast<IMSCall *>(call.GetRefPtr());
280         imsCall->StopRtt();
281     }
282 }
283 
JoinConference(int32_t callId,std::vector<std::string> & numberList)284 void CallRequestProcess::JoinConference(int32_t callId, std::vector<std::string> &numberList)
285 {
286     sptr<CallBase> call = GetOneCallObject(callId);
287     if (call == nullptr) {
288         TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
289         return;
290     }
291     int32_t ret =
292         DelayedSingleton<CellularCallConnection>::GetInstance()->InviteToConference(numberList, call->GetSlotId());
293     if (ret != TELEPHONY_SUCCESS) {
294         TELEPHONY_LOGE("Invite to conference failed!");
295         return;
296     }
297 }
298 
UpdateCallReportInfo(const DialParaInfo & info,TelCallState state)299 int32_t CallRequestProcess::UpdateCallReportInfo(const DialParaInfo &info, TelCallState state)
300 {
301     CallDetailInfo callDetatilInfo;
302     if (memset_s(&callDetatilInfo, sizeof(CallDetailInfo), 0, sizeof(CallDetailInfo)) != EOK) {
303         TELEPHONY_LOGE("memset_s callDetatilInfo fail");
304         return TELEPHONY_ERR_MEMSET_FAIL;
305     }
306     callDetatilInfo.callType = info.callType;
307     callDetatilInfo.accountId = info.accountId;
308     callDetatilInfo.index = info.index;
309     callDetatilInfo.state = state;
310     callDetatilInfo.callMode = info.videoState;
311     callDetatilInfo.voiceDomain = static_cast<int32_t>(info.callType);
312     if (info.number.length() > kMaxNumberLen) {
313         TELEPHONY_LOGE("numbser length out of range");
314         return CALL_ERR_NUMBER_OUT_OF_RANGE;
315     }
316     if (memcpy_s(&callDetatilInfo.phoneNum, kMaxNumberLen, info.number.c_str(), info.number.length()) != EOK) {
317         TELEPHONY_LOGE("memcpy_s number failed!");
318         return TELEPHONY_ERR_MEMCPY_FAIL;
319     }
320     return DelayedSingleton<ReportCallInfoHandler>::GetInstance()->UpdateCallReportInfo(callDetatilInfo);
321 }
322 
HandleDialFail()323 int32_t CallRequestProcess::HandleDialFail()
324 {
325     std::unique_lock<std::mutex> lock(mutex_);
326     while (!isFirstDialCallAdded_) {
327         if (cv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_ONE_SECOND)) == std::cv_status::timeout) {
328             TELEPHONY_LOGE("CarrierDialProcess call is not added");
329             return CALL_ERR_DIAL_FAILED;
330         }
331     }
332     sptr<CallBase> call = nullptr;
333     call = GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_CREATE);
334     if (call != nullptr) {
335         return DealFailDial(call);
336     }
337     call = GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_CONNECTING);
338     if (call != nullptr) {
339         return DealFailDial(call);
340     }
341     call = GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_DIALING);
342     if (call != nullptr) {
343         return DealFailDial(call);
344     }
345     TELEPHONY_LOGE("can not find connect call or dialing call");
346     return CALL_ERR_CALL_STATE;
347 }
348 
CarrierDialProcess(DialParaInfo & info)349 int32_t CallRequestProcess::CarrierDialProcess(DialParaInfo &info)
350 {
351     std::string newPhoneNumer =
352         DelayedSingleton<CallNumberUtils>::GetInstance()->RemoveSeparatorsPhoneNumber(info.number);
353     bool isMMiCode = DelayedSingleton<CallNumberUtils>::GetInstance()->IsMMICode(newPhoneNumer);
354     int32_t ret = TELEPHONY_ERROR;
355     if (!isMMiCode) {
356         isFirstDialCallAdded_ = false;
357         info.number = newPhoneNumer;
358         ret = UpdateCallReportInfo(info, TelCallState::CALL_STATUS_DIALING);
359         if (ret != TELEPHONY_SUCCESS) {
360             TELEPHONY_LOGE("UpdateCallReportInfo failed!");
361             return ret;
362         }
363     }
364     CellularCallInfo callInfo;
365     ret = PackCellularCallInfo(info, callInfo);
366     if (ret != TELEPHONY_SUCCESS) {
367         TELEPHONY_LOGW("PackCellularCallInfo failed!");
368         CallManagerHisysevent::WriteDialCallFaultEvent(info.accountId, static_cast<int32_t>(info.callType),
369             static_cast<int32_t>(info.videoState), ret, "Carrier type PackCellularCallInfo failed");
370         return ret;
371     }
372     // Obtain gateway information
373     ret = DelayedSingleton<CellularCallConnection>::GetInstance()->Dial(callInfo);
374     if (ret != TELEPHONY_SUCCESS) {
375         TELEPHONY_LOGE("Dial failed!");
376         if (isMMiCode) {
377             return ret;
378         }
379         int32_t handleRet = HandleDialFail();
380         if (handleRet != TELEPHONY_SUCCESS) {
381             TELEPHONY_LOGE("HandleDialFail failed!");
382             return handleRet;
383         }
384         return ret;
385     }
386     return TELEPHONY_SUCCESS;
387 }
388 
VoiceMailDialProcess(DialParaInfo & info)389 int32_t CallRequestProcess::VoiceMailDialProcess(DialParaInfo &info)
390 {
391     CellularCallInfo callInfo;
392     int32_t ret = PackCellularCallInfo(info, callInfo);
393     if (ret != TELEPHONY_SUCCESS) {
394         TELEPHONY_LOGW("PackCellularCallInfo failed!");
395         CallManagerHisysevent::WriteDialCallFaultEvent(info.accountId, static_cast<int32_t>(info.callType),
396             static_cast<int32_t>(info.videoState), ret, "Voice mail type PackCellularCallInfo failed");
397         return ret;
398     }
399     ret = DelayedSingleton<CellularCallConnection>::GetInstance()->Dial(callInfo);
400     if (ret != TELEPHONY_SUCCESS) {
401         TELEPHONY_LOGE("Dial VoiceMail failed!");
402         return ret;
403     }
404     return TELEPHONY_SUCCESS;
405 }
406 
OttDialProcess(DialParaInfo & info)407 int32_t CallRequestProcess::OttDialProcess(DialParaInfo &info)
408 {
409     AppExecFwk::PacMap callInfo;
410     callInfo.PutStringValue("phoneNumber", info.number);
411     callInfo.PutStringValue("bundleName", info.bundleName);
412     callInfo.PutIntValue("videoState", static_cast<int32_t>(info.videoState));
413     int32_t ret = DelayedSingleton<CallAbilityReportProxy>::GetInstance()->OttCallRequest(
414         OttCallRequestId::OTT_REQUEST_DIAL, callInfo);
415     if (ret != TELEPHONY_SUCCESS) {
416         TELEPHONY_LOGE("OTT call Dial failed!");
417         return ret;
418     }
419     return TELEPHONY_SUCCESS;
420 }
421 
PackCellularCallInfo(DialParaInfo & info,CellularCallInfo & callInfo)422 int32_t CallRequestProcess::PackCellularCallInfo(DialParaInfo &info, CellularCallInfo &callInfo)
423 {
424     callInfo.callId = info.callId;
425     callInfo.accountId = info.accountId;
426     callInfo.callType = info.callType;
427     callInfo.videoState = static_cast<int32_t>(info.videoState);
428     callInfo.index = info.index;
429     callInfo.slotId = info.accountId;
430     if (memset_s(callInfo.phoneNum, kMaxNumberLen, 0, kMaxNumberLen) != EOK) {
431         TELEPHONY_LOGW("memset_s failed!");
432         return TELEPHONY_ERR_MEMSET_FAIL;
433     }
434     if (info.number.length() > static_cast<size_t>(kMaxNumberLen)) {
435         TELEPHONY_LOGE("Number out of limit!");
436         return CALL_ERR_NUMBER_OUT_OF_RANGE;
437     }
438     if (memcpy_s(callInfo.phoneNum, kMaxNumberLen, info.number.c_str(), info.number.length()) != EOK) {
439         TELEPHONY_LOGE("memcpy_s failed!");
440         return TELEPHONY_ERR_MEMCPY_FAIL;
441     }
442     return TELEPHONY_SUCCESS;
443 }
444 
IsFdnNumber(std::vector<std::u16string> fdnNumberList,std::string phoneNumber)445 bool CallRequestProcess::IsFdnNumber(std::vector<std::u16string> fdnNumberList, std::string phoneNumber)
446 {
447     char number[kMaxNumberLen + 1] = { 0 };
448     int32_t j = 0;
449     for (int32_t i = 0; i < static_cast<int32_t>(phoneNumber.length()); i++) {
450         if (i >= kMaxNumberLen) {
451             break;
452         }
453         if (*(phoneNumber.c_str() + i) != ' ') {
454             number[j++] = *(phoneNumber.c_str() + i);
455         }
456     }
457     for (std::vector<std::u16string>::iterator it = fdnNumberList.begin(); it != fdnNumberList.end(); ++it) {
458         if (strstr(number, Str16ToStr8(*it).c_str()) != nullptr) {
459             TELEPHONY_LOGI("you are allowed to dial!");
460             return true;
461         }
462     }
463     TELEPHONY_LOGW("There is no fixed number.");
464     return false;
465 }
466 } // namespace Telephony
467 } // namespace OHOS
468