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 "cellular_call_connection_ims.h"
17 
18 #include "cellular_call_hisysevent.h"
19 #include "cellular_call_service.h"
20 #include "ims_call_client.h"
21 #include "radio_event.h"
22 #include "securec.h"
23 #include "standardize_utils.h"
24 
25 namespace OHOS {
26 namespace Telephony {
DialRequest(int32_t slotId,const ImsDialInfoStruct & dialRequest)27 int32_t CellularCallConnectionIMS::DialRequest(int32_t slotId, const ImsDialInfoStruct &dialRequest)
28 {
29     TELEPHONY_LOGI("call ims service");
30     ImsCallInfo callInfo;
31     if (memset_s(&callInfo, sizeof(callInfo), 0, sizeof(callInfo)) != EOK) {
32         TELEPHONY_LOGE("return, memset_s error.");
33         CellularCallHiSysEvent::WriteDialCallFaultEvent(
34             slotId, INVALID_PARAMETER, dialRequest.videoState, TELEPHONY_ERR_MEMSET_FAIL, "memset_s error");
35         return TELEPHONY_ERR_MEMSET_FAIL;
36     }
37     UpdateCallNumber(dialRequest.phoneNum);
38     size_t cpyLen = strlen(phoneNumber_.c_str()) + 1;
39     if (cpyLen > static_cast<size_t>(kMaxNumberLength)) {
40         phoneNumber_.clear();
41         return TELEPHONY_ERR_STRCPY_FAIL;
42     }
43     if (strcpy_s(callInfo.phoneNum, cpyLen, phoneNumber_.c_str()) != EOK) {
44         TELEPHONY_LOGE("return, strcpy_s fail.");
45         phoneNumber_.clear();
46         CellularCallHiSysEvent::WriteDialCallFaultEvent(
47             slotId, INVALID_PARAMETER, dialRequest.videoState, TELEPHONY_ERR_STRCPY_FAIL, "strcpy_s fail");
48         return TELEPHONY_ERR_STRCPY_FAIL;
49     }
50     phoneNumber_.clear();
51     callInfo.videoState = dialRequest.videoState;
52     callInfo.slotId = slotId;
53     if (DelayedSingleton<ImsCallClient>::GetInstance() == nullptr) {
54         TELEPHONY_LOGE("return, ImsCallClient is nullptr.");
55         CellularCallHiSysEvent::WriteDialCallFaultEvent(slotId, INVALID_PARAMETER, dialRequest.videoState,
56             CALL_ERR_RESOURCE_UNAVAILABLE, "ims vendor service does not exist");
57         return CALL_ERR_RESOURCE_UNAVAILABLE;
58     }
59     return DelayedSingleton<ImsCallClient>::GetInstance()->Dial(callInfo, dialRequest.clirMode);
60 }
61 
HangUpRequest(int32_t slotId,const std::string & phoneNum,int32_t index)62 int32_t CellularCallConnectionIMS::HangUpRequest(int32_t slotId, const std::string &phoneNum, int32_t index)
63 {
64     if (moduleUtils_.NeedCallImsService()) {
65         TELEPHONY_LOGI("call ims service");
66         ImsCallInfo hangUpCallInfo;
67         if (memset_s(&hangUpCallInfo, sizeof(hangUpCallInfo), 0, sizeof(hangUpCallInfo)) != EOK) {
68             TELEPHONY_LOGE("return, memset_s error.");
69             return TELEPHONY_ERR_MEMSET_FAIL;
70         }
71         if (static_cast<int32_t>(phoneNum.length() + 1) > kMaxNumberLength) {
72             return TELEPHONY_ERR_STRCPY_FAIL;
73         }
74         if (strcpy_s(hangUpCallInfo.phoneNum, strlen(phoneNum.c_str()) + 1, phoneNum.c_str()) != EOK) {
75             TELEPHONY_LOGE("return, strcpy_s fail.");
76             return TELEPHONY_ERR_STRCPY_FAIL;
77         }
78         hangUpCallInfo.slotId = slotId;
79         hangUpCallInfo.index = index;
80         if (DelayedSingleton<ImsCallClient>::GetInstance() == nullptr) {
81             TELEPHONY_LOGE("return, ImsCallClient is nullptr.");
82             return CALL_ERR_RESOURCE_UNAVAILABLE;
83         }
84         return DelayedSingleton<ImsCallClient>::GetInstance()->HangUp(hangUpCallInfo);
85     }
86     TELEPHONY_LOGE("ims vendor service does not exist.");
87     CellularCallHiSysEvent::WriteHangUpFaultEvent(slotId, INVALID_PARAMETER,
88         static_cast<int32_t>(CallErrorCode::CALL_ERROR_IMS_SERVICE_NOT_EXIST),
89         "HangUpRequest ims vendor service does not exist");
90     return TELEPHONY_ERROR;
91 }
92 
AnswerRequest(int32_t slotId,const std::string & phoneNum,int32_t videoState,int32_t index)93 int32_t CellularCallConnectionIMS::AnswerRequest(
94     int32_t slotId, const std::string &phoneNum, int32_t videoState, int32_t index)
95 {
96     if (moduleUtils_.NeedCallImsService()) {
97         TELEPHONY_LOGI("call ims service");
98         ImsCallInfo answerCallInfo;
99         if (memset_s(&answerCallInfo, sizeof(answerCallInfo), 0, sizeof(answerCallInfo)) != EOK) {
100             TELEPHONY_LOGE("return, memset_s error.");
101             return TELEPHONY_ERR_MEMSET_FAIL;
102         }
103         if (static_cast<int32_t>(phoneNum.length() + 1) > kMaxNumberLength) {
104             return TELEPHONY_ERR_STRCPY_FAIL;
105         }
106         if (strcpy_s(answerCallInfo.phoneNum, strlen(phoneNum.c_str()) + 1, phoneNum.c_str()) != EOK) {
107             TELEPHONY_LOGE("return, strcpy_s fail.");
108             return TELEPHONY_ERR_STRCPY_FAIL;
109         }
110         answerCallInfo.videoState = videoState;
111         answerCallInfo.slotId = slotId;
112         answerCallInfo.index = index;
113         if (DelayedSingleton<ImsCallClient>::GetInstance() == nullptr) {
114             TELEPHONY_LOGE("return, ImsCallClient is nullptr.");
115             return CALL_ERR_RESOURCE_UNAVAILABLE;
116         }
117         return DelayedSingleton<ImsCallClient>::GetInstance()->Answer(answerCallInfo);
118     }
119     TELEPHONY_LOGE("ims vendor service does not exist.");
120     CellularCallHiSysEvent::WriteAnswerCallFaultEvent(slotId, INVALID_PARAMETER, INVALID_PARAMETER,
121         static_cast<int32_t>(CallErrorCode::CALL_ERROR_IMS_SERVICE_NOT_EXIST), "ims vendor service does not exist");
122     return TELEPHONY_ERROR;
123 }
124 
RejectRequest(int32_t slotId,const std::string & phoneNum,int32_t index)125 int32_t CellularCallConnectionIMS::RejectRequest(int32_t slotId, const std::string &phoneNum, int32_t index)
126 {
127     if (moduleUtils_.NeedCallImsService()) {
128         TELEPHONY_LOGI("call ims service");
129         ImsCallInfo rejectCallInfo;
130         if (memset_s(&rejectCallInfo, sizeof(rejectCallInfo), 0, sizeof(rejectCallInfo)) != EOK) {
131             TELEPHONY_LOGE("return, memset_s error.");
132             return TELEPHONY_ERR_MEMSET_FAIL;
133         }
134         if (static_cast<int32_t>(phoneNum.length() + 1) > kMaxNumberLength) {
135             return TELEPHONY_ERR_STRCPY_FAIL;
136         }
137         if (strcpy_s(rejectCallInfo.phoneNum, strlen(phoneNum.c_str()) + 1, phoneNum.c_str()) != EOK) {
138             TELEPHONY_LOGE("return, strcpy_s fail.");
139             return TELEPHONY_ERR_STRCPY_FAIL;
140         }
141         rejectCallInfo.slotId = slotId;
142         rejectCallInfo.index = index;
143         if (DelayedSingleton<ImsCallClient>::GetInstance() == nullptr) {
144             TELEPHONY_LOGE("return, ImsCallClient is nullptr.");
145             return CALL_ERR_RESOURCE_UNAVAILABLE;
146         }
147         return DelayedSingleton<ImsCallClient>::GetInstance()->Reject(rejectCallInfo);
148     }
149     TELEPHONY_LOGE("ims vendor service does not exist.");
150     CellularCallHiSysEvent::WriteHangUpFaultEvent(slotId, INVALID_PARAMETER,
151         static_cast<int32_t>(CallErrorCode::CALL_ERROR_IMS_SERVICE_NOT_EXIST),
152         "RejectRequest ims vendor service does not exist");
153     return TELEPHONY_ERROR;
154 }
155 
HoldCallRequest(int32_t slotId)156 int32_t CellularCallConnectionIMS::HoldCallRequest(int32_t slotId)
157 {
158     if (moduleUtils_.NeedCallImsService()) {
159         TELEPHONY_LOGI("call ims service");
160         if (DelayedSingleton<ImsCallClient>::GetInstance() == nullptr) {
161             TELEPHONY_LOGE("return, ImsCallClient is nullptr.");
162             return CALL_ERR_RESOURCE_UNAVAILABLE;
163         }
164         int32_t callType = static_cast<int32_t>(GetCallReportInfo().callMode);
165         return DelayedSingleton<ImsCallClient>::GetInstance()->HoldCall(slotId, callType);
166     }
167     TELEPHONY_LOGE("ims vendor service does not exist.");
168     return TELEPHONY_ERROR;
169 }
170 
UnHoldCallRequest(int32_t slotId)171 int32_t CellularCallConnectionIMS::UnHoldCallRequest(int32_t slotId)
172 {
173     if (moduleUtils_.NeedCallImsService()) {
174         TELEPHONY_LOGI("call ims service");
175         if (DelayedSingleton<ImsCallClient>::GetInstance() == nullptr) {
176             TELEPHONY_LOGE("return, ImsCallClient is nullptr.");
177             return CALL_ERR_RESOURCE_UNAVAILABLE;
178         }
179         int32_t callType = static_cast<int32_t>(GetCallReportInfo().callMode);
180         return DelayedSingleton<ImsCallClient>::GetInstance()->UnHoldCall(slotId, callType);
181     }
182     TELEPHONY_LOGE("ims vendor service does not exist.");
183     return TELEPHONY_ERROR;
184 }
185 
SwitchCallRequest(int32_t slotId)186 int32_t CellularCallConnectionIMS::SwitchCallRequest(int32_t slotId)
187 {
188     if (moduleUtils_.NeedCallImsService()) {
189         TELEPHONY_LOGI("call ims service");
190         if (DelayedSingleton<ImsCallClient>::GetInstance() == nullptr) {
191             TELEPHONY_LOGE("return, ImsCallClient is nullptr.");
192             return CALL_ERR_RESOURCE_UNAVAILABLE;
193         }
194         int32_t callType = static_cast<int32_t>(GetCallReportInfo().callMode);
195         int32_t ret = DelayedSingleton<ImsCallClient>::GetInstance()->SwitchCall(slotId, callType);
196         if (ret == TELEPHONY_SUCCESS) {
197             UpdatePendingHoldFlag(true);
198         }
199         return ret;
200     }
201     TELEPHONY_LOGE("ims vendor service does not exist.");
202     return TELEPHONY_ERROR;
203 }
204 
CombineConferenceRequest(int32_t slotId,int32_t voiceCall)205 int32_t CellularCallConnectionIMS::CombineConferenceRequest(int32_t slotId, int32_t voiceCall)
206 {
207     if (moduleUtils_.NeedCallImsService()) {
208         TELEPHONY_LOGI("call ims service");
209         if (DelayedSingleton<ImsCallClient>::GetInstance() == nullptr) {
210             TELEPHONY_LOGE("return, ImsCallClient is nullptr.");
211             return CALL_ERR_RESOURCE_UNAVAILABLE;
212         }
213         return DelayedSingleton<ImsCallClient>::GetInstance()->CombineConference(slotId);
214     }
215     TELEPHONY_LOGE("ims vendor service does not exist.");
216     return TELEPHONY_ERROR;
217 }
218 
InviteToConferenceRequest(int32_t slotId,const std::vector<std::string> & numberList)219 int32_t CellularCallConnectionIMS::InviteToConferenceRequest(
220     int32_t slotId, const std::vector<std::string> &numberList)
221 {
222     if (moduleUtils_.NeedCallImsService()) {
223         TELEPHONY_LOGI("call ims service");
224         if (DelayedSingleton<ImsCallClient>::GetInstance() == nullptr) {
225             TELEPHONY_LOGE("return, ImsCallClient is nullptr.");
226             return CALL_ERR_RESOURCE_UNAVAILABLE;
227         }
228         return DelayedSingleton<ImsCallClient>::GetInstance()->InviteToConference(slotId, numberList);
229     }
230     TELEPHONY_LOGE("ims vendor service does not exist.");
231     return TELEPHONY_ERROR;
232 }
233 
KickOutFromConferenceRequest(int32_t slotId,int32_t index)234 int32_t CellularCallConnectionIMS::KickOutFromConferenceRequest(int32_t slotId, int32_t index)
235 {
236     if (moduleUtils_.NeedCallImsService()) {
237         TELEPHONY_LOGI("call ims service");
238         if (DelayedSingleton<ImsCallClient>::GetInstance() == nullptr) {
239             TELEPHONY_LOGE("return, ImsCallClient is nullptr.");
240             return CALL_ERR_RESOURCE_UNAVAILABLE;
241         }
242         return DelayedSingleton<ImsCallClient>::GetInstance()->KickOutFromConference(slotId, index);
243     }
244     TELEPHONY_LOGE("ims vendor service does not exist.");
245     return TELEPHONY_ERROR;
246 }
247 
CallSupplementRequest(int32_t slotId,CallSupplementType type)248 int32_t CellularCallConnectionIMS::CallSupplementRequest(int32_t slotId, CallSupplementType type)
249 {
250     TELEPHONY_LOGD("start");
251     if (DelayedSingleton<CellularCallService>::GetInstance() == nullptr) {
252         TELEPHONY_LOGE("return, error type: GetInstance() is nullptr.");
253         return CALL_ERR_RESOURCE_UNAVAILABLE;
254     }
255     auto handle = DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId);
256     if (handle == nullptr) {
257         TELEPHONY_LOGE("return, error type: handle is nullptr.");
258         return CALL_ERR_RESOURCE_UNAVAILABLE;
259     }
260     CoreManagerInner::GetInstance().CallSupplement(slotId, RadioEvent::RADIO_CALL_SUPPLEMENT, type, handle);
261     return TELEPHONY_SUCCESS;
262 }
263 
GetImsCallsDataRequest(int32_t slotId,int64_t lastCallsDataFlag)264 int32_t CellularCallConnectionIMS::GetImsCallsDataRequest(int32_t slotId, int64_t lastCallsDataFlag)
265 {
266     if (moduleUtils_.NeedCallImsService()) {
267         TELEPHONY_LOGI("call ims service");
268         if (DelayedSingleton<ImsCallClient>::GetInstance() == nullptr) {
269             TELEPHONY_LOGE("return, ImsCallClient is nullptr.");
270             return CALL_ERR_RESOURCE_UNAVAILABLE;
271         }
272         return DelayedSingleton<ImsCallClient>::GetInstance()->GetImsCallsDataRequest(slotId, lastCallsDataFlag);
273     }
274     TELEPHONY_LOGE("ims vendor service does not exist.");
275     return TELEPHONY_ERROR;
276 }
277 
SendDtmfRequest(int32_t slotId,char cDtmfCode,int32_t index) const278 int32_t CellularCallConnectionIMS::SendDtmfRequest(int32_t slotId, char cDtmfCode, int32_t index) const
279 {
280     if (moduleUtils_.NeedCallImsService()) {
281         TELEPHONY_LOGD("call ims service");
282         if (DelayedSingleton<ImsCallClient>::GetInstance() == nullptr) {
283             TELEPHONY_LOGE("return, ImsCallClient is nullptr.");
284             return CALL_ERR_RESOURCE_UNAVAILABLE;
285         }
286         return DelayedSingleton<ImsCallClient>::GetInstance()->SendDtmf(slotId, cDtmfCode, index);
287     }
288     TELEPHONY_LOGE("ims vendor service does not exist.");
289     return TELEPHONY_ERROR;
290 }
291 
StartDtmfRequest(int32_t slotId,char cDtmfCode,int32_t index) const292 int32_t CellularCallConnectionIMS::StartDtmfRequest(int32_t slotId, char cDtmfCode, int32_t index) const
293 {
294     if (moduleUtils_.NeedCallImsService()) {
295         TELEPHONY_LOGI("call ims service");
296         if (DelayedSingleton<ImsCallClient>::GetInstance() == nullptr) {
297             TELEPHONY_LOGE("return, ImsCallClient is nullptr.");
298             return CALL_ERR_RESOURCE_UNAVAILABLE;
299         }
300         return DelayedSingleton<ImsCallClient>::GetInstance()->StartDtmf(slotId, cDtmfCode, index);
301     }
302     TELEPHONY_LOGE("ims vendor service does not exist.");
303     return TELEPHONY_ERROR;
304 }
305 
StopDtmfRequest(int32_t slotId,int32_t index) const306 int32_t CellularCallConnectionIMS::StopDtmfRequest(int32_t slotId, int32_t index) const
307 {
308     if (moduleUtils_.NeedCallImsService()) {
309         TELEPHONY_LOGI("call ims service");
310         if (DelayedSingleton<ImsCallClient>::GetInstance() == nullptr) {
311             TELEPHONY_LOGE("return, ImsCallClient is nullptr.");
312             return CALL_ERR_RESOURCE_UNAVAILABLE;
313         }
314         return DelayedSingleton<ImsCallClient>::GetInstance()->StopDtmf(slotId, index);
315     }
316     TELEPHONY_LOGE("ims vendor service does not exist.");
317     return TELEPHONY_ERROR;
318 }
319 
StartRttRequest(int32_t slotId,const std::string & msg)320 int32_t CellularCallConnectionIMS::StartRttRequest(int32_t slotId, const std::string &msg)
321 {
322     if (moduleUtils_.NeedCallImsService()) {
323         TELEPHONY_LOGI("call ims service");
324         if (DelayedSingleton<ImsCallClient>::GetInstance() == nullptr) {
325             TELEPHONY_LOGE("return, ImsCallClient is nullptr.");
326             return CALL_ERR_RESOURCE_UNAVAILABLE;
327         }
328         return DelayedSingleton<ImsCallClient>::GetInstance()->StartRtt(slotId, msg);
329     }
330     TELEPHONY_LOGE("ims vendor service does not exist.");
331     return TELEPHONY_ERROR;
332 }
333 
StopRttRequest(int32_t slotId)334 int32_t CellularCallConnectionIMS::StopRttRequest(int32_t slotId)
335 {
336     if (moduleUtils_.NeedCallImsService()) {
337         TELEPHONY_LOGI("call ims service");
338         if (DelayedSingleton<ImsCallClient>::GetInstance() == nullptr) {
339             TELEPHONY_LOGE("return, ImsCallClient is nullptr.");
340             return CALL_ERR_RESOURCE_UNAVAILABLE;
341         }
342         return DelayedSingleton<ImsCallClient>::GetInstance()->StopRtt(slotId);
343     }
344     TELEPHONY_LOGE("ims vendor service does not exist.");
345     return TELEPHONY_ERROR;
346 }
347 
GetCallFailReasonRequest(int32_t slotId) const348 int32_t CellularCallConnectionIMS::GetCallFailReasonRequest(int32_t slotId) const
349 {
350     if (moduleUtils_.NeedCallImsService()) {
351         TELEPHONY_LOGD("call ims service");
352         if (DelayedSingleton<ImsCallClient>::GetInstance() == nullptr) {
353             TELEPHONY_LOGE("return, ImsCallClient is nullptr.");
354             return CALL_ERR_RESOURCE_UNAVAILABLE;
355         }
356         return DelayedSingleton<ImsCallClient>::GetInstance()->GetLastCallFailReason(slotId);
357     }
358     TELEPHONY_LOGE("ims vendor service does not exist.");
359     return TELEPHONY_ERROR;
360 }
361 
ProcessPostDialCallChar(int32_t slotId,char c)362 int32_t CellularCallConnectionIMS::ProcessPostDialCallChar(int32_t slotId, char c)
363 {
364     if (StandardizeUtils::IsDtmfKey(c)) {
365         SendDtmfRequest(slotId, c, GetIndex());
366     } else if (StandardizeUtils::IsPauseKey(c)) {
367         SetPostDialCallState(PostDialCallState::POST_DIAL_CALL_PAUSE);
368         auto handle = DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId);
369         if (handle == nullptr) {
370             TELEPHONY_LOGE("SendDtmfRequest return, error type: handle is nullptr.");
371             return CALL_ERR_RESOURCE_UNAVAILABLE;
372         }
373         std::shared_ptr<PostDialData> postDial = std::make_shared<PostDialData>();
374         postDial->callId = GetIndex();
375         postDial->isIms = true;
376         handle->SendEvent(EVENT_EXECUTE_POST_DIAL, postDial, PAUSE_DELAY_TIME);
377     } else if (StandardizeUtils::IsWaitKey(c)) {
378         SetPostDialCallState(PostDialCallState::POST_DIAL_CALL_DELAY);
379     }
380     return TELEPHONY_SUCCESS;
381 }
382 
SetHoldToDialInfo(std::string holdToDialNum,CLIRMode holdToDialClirMode,int32_t holdToDialVideoState,bool isEmergency)383 void CellularCallConnectionIMS::SetHoldToDialInfo(std::string holdToDialNum, CLIRMode holdToDialClirMode,
384     int32_t holdToDialVideoState, bool isEmergency)
385 {
386     holdToDialInfo_.phoneNum = holdToDialNum;
387     holdToDialInfo_.clirMode = holdToDialClirMode;
388     holdToDialInfo_.videoState = holdToDialVideoState;
389     holdToDialInfo_.bEmergencyCall = isEmergency;
390 }
391 
IsNeedToDial()392 bool CellularCallConnectionIMS::IsNeedToDial()
393 {
394     return isNeedToDial_;
395 }
396 
SetDialFlag(bool isNeedToDial)397 void CellularCallConnectionIMS::SetDialFlag(bool isNeedToDial)
398 {
399     isNeedToDial_ = isNeedToDial;
400 }
401 
GetHoldToDialInfo()402 ImsDialInfoStruct CellularCallConnectionIMS::GetHoldToDialInfo()
403 {
404     return holdToDialInfo_;
405 }
406 
IsPendingHold()407 bool CellularCallConnectionIMS::IsPendingHold()
408 {
409     return GetCallReportInfo().isPendingHold;
410 }
411 } // namespace Telephony
412 } // namespace OHOS
413