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_handler.h"
17
18#include "cellular_call_config.h"
19#include "cellular_call_hisysevent.h"
20#include "cellular_call_service.h"
21#include "hitrace_meter.h"
22#include "tel_ril_call_parcel.h"
23#include "tel_ril_types.h"
24#include "ims_call_client.h"
25#include "operator_config_types.h"
26#include "radio_event.h"
27#include "resource_utils.h"
28#include "satellite_call_client.h"
29#include "satellite_radio_event.h"
30#include "securec.h"
31
32namespace OHOS {
33namespace Telephony {
34const uint32_t GET_CS_CALL_DATA_ID = 10001;
35const uint32_t GET_IMS_CALL_DATA_ID = 10002;
36const uint32_t OPERATOR_CONFIG_CHANGED_ID = 10004;
37const uint32_t GET_SATELLITE_CALL_DATA_ID = 10005;
38const uint32_t NETWORK_STATE_CHANGED = 10006;
39const int64_t DELAY_TIME = 100;
40const int32_t MAX_REQUEST_COUNT = 50;
41// message was null, mean report the default message to user which have been define at CellularCallSupplement
42const std::string DEFAULT_NULL_MESSAGE = "";
43
44CellularCallHandler::CellularCallHandler(const EventFwk::CommonEventSubscribeInfo &subscriberInfo)
45    : TelEventHandler("CellularCallHandler"), CommonEventSubscriber(subscriberInfo)
46{
47    InitBasicFuncMap();
48    InitConfigFuncMap();
49    InitSupplementFuncMap();
50    InitActiveReportFuncMap();
51    InitSatelliteCallFuncMap();
52    InitAdditionalFuncMap();
53}
54
55void CellularCallHandler::InitBasicFuncMap()
56{
57    requestFuncMap_[RadioEvent::RADIO_DIAL] =
58        [this](const AppExecFwk::InnerEvent::Pointer &event) { DialResponse(event); };
59    requestFuncMap_[RadioEvent::RADIO_HANGUP_CONNECT] =
60        [this](const AppExecFwk::InnerEvent::Pointer &event) { CommonResultResponse(event); };
61    requestFuncMap_[RadioEvent::RADIO_REJECT_CALL] =
62        [this](const AppExecFwk::InnerEvent::Pointer &event) { CommonResultResponse(event); };
63    requestFuncMap_[RadioEvent::RADIO_ACCEPT_CALL] =
64        [this](const AppExecFwk::InnerEvent::Pointer &event) { CommonResultResponse(event); };
65    requestFuncMap_[RadioEvent::RADIO_HOLD_CALL] =
66        [this](const AppExecFwk::InnerEvent::Pointer &event) { CommonResultResponse(event); };
67    requestFuncMap_[RadioEvent::RADIO_ACTIVE_CALL] =
68        [this](const AppExecFwk::InnerEvent::Pointer &event) { CommonResultResponse(event); };
69    requestFuncMap_[RadioEvent::RADIO_SWAP_CALL] =
70        [this](const AppExecFwk::InnerEvent::Pointer &event) { SwapCallResponse(event); };
71    requestFuncMap_[RadioEvent::RADIO_COMBINE_CALL] =
72        [this](const AppExecFwk::InnerEvent::Pointer &event) { CommonResultResponse(event); };
73    requestFuncMap_[RadioEvent::RADIO_JOIN_CALL] =
74        [this](const AppExecFwk::InnerEvent::Pointer &event) { CommonResultResponse(event); };
75    requestFuncMap_[RadioEvent::RADIO_SPLIT_CALL] =
76        [this](const AppExecFwk::InnerEvent::Pointer &event) { CommonResultResponse(event); };
77    requestFuncMap_[RadioEvent::RADIO_CALL_SUPPLEMENT] =
78        [this](const AppExecFwk::InnerEvent::Pointer &event) { CommonResultResponse(event); };
79    requestFuncMap_[RadioEvent::RADIO_SEND_DTMF] =
80        [this](const AppExecFwk::InnerEvent::Pointer &event) { SendDtmfResponse(event); };
81    requestFuncMap_[RadioEvent::RADIO_START_DTMF] =
82        [this](const AppExecFwk::InnerEvent::Pointer &event) { StartDtmfResponse(event); };
83    requestFuncMap_[RadioEvent::RADIO_STOP_DTMF] =
84        [this](const AppExecFwk::InnerEvent::Pointer &event) { StopDtmfResponse(event); };
85    requestFuncMap_[RadioEvent::RADIO_CURRENT_CALLS] =
86        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetCsCallsDataResponse(event); };
87    requestFuncMap_[RadioEvent::RADIO_GET_CALL_FAIL_REASON] =
88        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetCallFailReasonResponse(event); };
89    requestFuncMap_[RadioEvent::RADIO_RECV_CALL_MEDIA_MODE_REQUEST] =
90        [this](const AppExecFwk::InnerEvent::Pointer &event) { ReceiveUpdateCallMediaModeRequest(event); };
91    requestFuncMap_[RadioEvent::RADIO_RECV_CALL_MEDIA_MODE_RESPONSE] =
92        [this](const AppExecFwk::InnerEvent::Pointer &event) { ReceiveUpdateCallMediaModeResponse(event); };
93    requestFuncMap_[RadioEvent::RADIO_CALL_SESSION_EVENT_CHANGED] =
94        [this](const AppExecFwk::InnerEvent::Pointer &event) { HandleCallSessionEventChanged(event); };
95    requestFuncMap_[RadioEvent::RADIO_CALL_PEER_DIMENSIONS_CHANGED] =
96        [this](const AppExecFwk::InnerEvent::Pointer &event) { HandlePeerDimensionsChanged(event); };
97    requestFuncMap_[RadioEvent::RADIO_CALL_DATA_USAGE_CHANGED] =
98        [this](const AppExecFwk::InnerEvent::Pointer &event) { HandleCallDataUsageChanged(event); };
99    requestFuncMap_[RadioEvent::RADIO_CAMERA_CAPABILITIES_CHANGED] =
100        [this](const AppExecFwk::InnerEvent::Pointer &event) { HandleCameraCapabilitiesChanged(event); };
101    requestFuncMap_[RadioEvent::RADIO_IMS_GET_CALL_DATA] =
102        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetImsCallsDataResponse(event); };
103}
104
105void CellularCallHandler::InitConfigFuncMap()
106{
107    requestFuncMap_[RadioEvent::RADIO_SET_CMUT] =
108        [this](const AppExecFwk::InnerEvent::Pointer &event) { SetMuteResponse(event); };
109    requestFuncMap_[RadioEvent::RADIO_GET_CMUT] =
110        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetMuteResponse(event); };
111    requestFuncMap_[RadioEvent::RADIO_SET_CALL_PREFERENCE_MODE] =
112        [this](const AppExecFwk::InnerEvent::Pointer &event) { SetDomainPreferenceModeResponse(event); };
113    requestFuncMap_[RadioEvent::RADIO_GET_CALL_PREFERENCE_MODE] =
114        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetDomainPreferenceModeResponse(event); };
115    requestFuncMap_[RadioEvent::RADIO_SET_IMS_SWITCH_STATUS] =
116        [this](const AppExecFwk::InnerEvent::Pointer &event) { SetImsSwitchStatusResponse(event); };
117    requestFuncMap_[RadioEvent::RADIO_GET_IMS_SWITCH_STATUS] =
118        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetImsSwitchStatusResponse(event); };
119    requestFuncMap_[RadioEvent::RADIO_SET_VONR_SWITCH_STATUS] =
120        [this](const AppExecFwk::InnerEvent::Pointer &event) { SetVoNRSwitchStatusResponse(event); };
121    requestFuncMap_[RadioEvent::RADIO_SET_EMERGENCY_CALL_LIST] =
122        [this](const AppExecFwk::InnerEvent::Pointer &event) { SetEmergencyCallListResponse(event); };
123    requestFuncMap_[RadioEvent::RADIO_GET_EMERGENCY_CALL_LIST] =
124        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetEmergencyCallListResponse(event); };
125    requestFuncMap_[OPERATOR_CONFIG_CHANGED_ID] =
126        [this](const AppExecFwk::InnerEvent::Pointer &event) { HandleOperatorConfigChanged(event); };
127}
128
129void CellularCallHandler::InitSupplementFuncMap()
130{
131    requestFuncMap_[RadioEvent::RADIO_GET_CALL_WAIT] =
132        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetCallWaitingResponse(event); };
133    requestFuncMap_[RadioEvent::RADIO_SET_CALL_WAIT] =
134        [this](const AppExecFwk::InnerEvent::Pointer &event) { SetCallWaitingResponse(event); };
135    requestFuncMap_[RadioEvent::RADIO_GET_CALL_FORWARD] =
136        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetCallTransferResponse(event); };
137    requestFuncMap_[RadioEvent::RADIO_SET_CALL_FORWARD] =
138        [this](const AppExecFwk::InnerEvent::Pointer &event) { SetCallTransferInfoResponse(event); };
139    requestFuncMap_[RadioEvent::RADIO_GET_CALL_CLIP] =
140        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetClipResponse(event); };
141    requestFuncMap_[RadioEvent::RADIO_SET_CALL_CLIP] =
142        [this](const AppExecFwk::InnerEvent::Pointer &event) { SetClipResponse(event); };
143    requestFuncMap_[RadioEvent::RADIO_GET_CALL_CLIR] =
144        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetClirResponse(event); };
145    requestFuncMap_[RadioEvent::RADIO_SET_CALL_CLIR] =
146        [this](const AppExecFwk::InnerEvent::Pointer &event) { SetClirResponse(event); };
147    requestFuncMap_[RadioEvent::RADIO_IMS_GET_COLR] =
148        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetColrResponse(event); };
149    requestFuncMap_[RadioEvent::RADIO_IMS_SET_COLR] =
150        [this](const AppExecFwk::InnerEvent::Pointer &event) { SetColrResponse(event); };
151    requestFuncMap_[RadioEvent::RADIO_IMS_GET_COLP] =
152        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetColpResponse(event); };
153    requestFuncMap_[RadioEvent::RADIO_IMS_SET_COLP] =
154        [this](const AppExecFwk::InnerEvent::Pointer &event) { SetColpResponse(event); };
155    requestFuncMap_[RadioEvent::RADIO_GET_CALL_RESTRICTION] =
156        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetCallRestrictionResponse(event); };
157    requestFuncMap_[RadioEvent::RADIO_SET_CALL_RESTRICTION] =
158        [this](const AppExecFwk::InnerEvent::Pointer &event) { SetCallRestrictionResponse(event); };
159    requestFuncMap_[RadioEvent::RADIO_SET_CALL_RESTRICTION_PWD] =
160        [this](const AppExecFwk::InnerEvent::Pointer &event) { SetBarringPasswordResponse(event); };
161    requestFuncMap_[RadioEvent::RADIO_SET_USSD] =
162        [this](const AppExecFwk::InnerEvent::Pointer &event) { SendUssdResponse(event); };
163    requestFuncMap_[MMIHandlerId::EVENT_SET_UNLOCK_PIN_PUK_ID] =
164        [this](const AppExecFwk::InnerEvent::Pointer &event) { SendUnlockPinPukResponse(event); };
165    requestFuncMap_[RadioEvent::RADIO_CLOSE_UNFINISHED_USSD] =
166        [this](const AppExecFwk::InnerEvent::Pointer &event) { CloseUnFinishedUssdResponse(event); };
167}
168
169void CellularCallHandler::InitActiveReportFuncMap()
170{
171    requestFuncMap_[RadioEvent::RADIO_CALL_STATUS_INFO] =
172        [this](const AppExecFwk::InnerEvent::Pointer &event) { CsCallStatusInfoReport(event); };
173    requestFuncMap_[RadioEvent::RADIO_IMS_CALL_STATUS_INFO] =
174        [this](const AppExecFwk::InnerEvent::Pointer &event) { ImsCallStatusInfoReport(event); };
175    requestFuncMap_[RadioEvent::RADIO_AVAIL] =
176        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetCsCallData(event); };
177    requestFuncMap_[RadioEvent::RADIO_NOT_AVAIL] =
178        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetCsCallData(event); };
179    requestFuncMap_[RadioEvent::RADIO_CALL_USSD_NOTICE] =
180        [this](const AppExecFwk::InnerEvent::Pointer &event) { UssdNotifyResponse(event); };
181    requestFuncMap_[RadioEvent::RADIO_CALL_RINGBACK_VOICE] =
182        [this](const AppExecFwk::InnerEvent::Pointer &event) { CallRingBackVoiceResponse(event); };
183    requestFuncMap_[RadioEvent::RADIO_CALL_SRVCC_STATUS] =
184        [this](const AppExecFwk::InnerEvent::Pointer &event) { UpdateSrvccStateReport(event); };
185    requestFuncMap_[RadioEvent::RADIO_CALL_SS_NOTICE] =
186        [this](const AppExecFwk::InnerEvent::Pointer &event) { SsNotifyResponse(event); };
187    requestFuncMap_[RadioEvent::RADIO_CALL_EMERGENCY_NUMBER_REPORT] =
188        [this](const AppExecFwk::InnerEvent::Pointer &event) { ReportEccChanged(event); };
189    requestFuncMap_[RadioEvent::RADIO_SIM_STATE_CHANGE] =
190        [this](const AppExecFwk::InnerEvent::Pointer &event) { SimStateChangeReport(event); };
191    requestFuncMap_[RadioEvent::RADIO_SIM_RECORDS_LOADED] =
192        [this](const AppExecFwk::InnerEvent::Pointer &event) { SimRecordsLoadedReport(event); };
193    requestFuncMap_[RadioEvent::RADIO_SIM_ACCOUNT_LOADED] =
194        [this](const AppExecFwk::InnerEvent::Pointer &event) { SimAccountLoadedReport(event); };
195    requestFuncMap_[RadioEvent::RADIO_CALL_RSRVCC_STATUS] =
196        [this](const AppExecFwk::InnerEvent::Pointer &event) { UpdateRsrvccStateReport(event); };
197    requestFuncMap_[RadioEvent::RADIO_RESIDENT_NETWORK_CHANGE] =
198        [this](const AppExecFwk::InnerEvent::Pointer &event) { ResidentNetworkChangeReport(event); };
199    requestFuncMap_[NETWORK_STATE_CHANGED] =
200        [this](const AppExecFwk::InnerEvent::Pointer &event) { NetworkStateChangeReport(event); };
201    requestFuncMap_[RadioEvent::RADIO_RIL_ADAPTER_HOST_DIED] =
202        [this](const AppExecFwk::InnerEvent::Pointer &event) { OnRilAdapterHostDied(event); };
203    requestFuncMap_[RadioEvent::RADIO_FACTORY_RESET] =
204        [this](const AppExecFwk::InnerEvent::Pointer &event) { FactoryReset(event); };
205    requestFuncMap_[RadioEvent::RADIO_NV_REFRESH_FINISHED] =
206        [this](const AppExecFwk::InnerEvent::Pointer &event) { NvCfgFinishedIndication(event); };
207#ifdef CALL_MANAGER_AUTO_START_OPTIMIZE
208    requestFuncMap_[RadioEvent::RADIO_GET_STATUS] =
209        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetRadioStateProcess(event); };
210    requestFuncMap_[RadioEvent::RADIO_STATE_CHANGED] =
211        [this](const AppExecFwk::InnerEvent::Pointer &event) { RadioStateChangeProcess(event); };
212#endif
213}
214
215void CellularCallHandler::InitSatelliteCallFuncMap()
216{
217    requestFuncMap_[SatelliteRadioEvent::SATELLITE_RADIO_CALL_STATE_CHANGED] =
218        [this](const AppExecFwk::InnerEvent::Pointer &event) { SatelliteCallStatusInfoReport(event); };
219    requestFuncMap_[SatelliteRadioEvent::SATELLITE_RADIO_DIAL] =
220        [this](const AppExecFwk::InnerEvent::Pointer &event) { DialSatelliteResponse(event); };
221    requestFuncMap_[SatelliteRadioEvent::SATELLITE_RADIO_HANGUP] =
222        [this](const AppExecFwk::InnerEvent::Pointer &event) { CommonResultResponse(event); };
223    requestFuncMap_[SatelliteRadioEvent::SATELLITE_RADIO_ANSWER] =
224        [this](const AppExecFwk::InnerEvent::Pointer &event) { CommonResultResponse(event); };
225    requestFuncMap_[SatelliteRadioEvent::SATELLITE_RADIO_REJECT] =
226        [this](const AppExecFwk::InnerEvent::Pointer &event) { CommonResultResponse(event); };
227    requestFuncMap_[SatelliteRadioEvent::SATELLITE_RADIO_GET_CALL_DATA] =
228        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetSatelliteCallsDataResponse(event); };
229    requestFuncMap_[GET_SATELLITE_CALL_DATA_ID] =
230        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetSatelliteCallsDataRequest(event); };
231}
232
233void CellularCallHandler::InitAdditionalFuncMap()
234{
235    requestFuncMap_[GET_CS_CALL_DATA_ID] =
236        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetCsCallsDataRequest(event); };
237    requestFuncMap_[GET_IMS_CALL_DATA_ID] =
238        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetImsCallsDataRequest(event); };
239    requestFuncMap_[REGISTER_HANDLER_ID] =
240        [this](const AppExecFwk::InnerEvent::Pointer &event) { RegisterHandler(event); };
241    requestFuncMap_[MMIHandlerId::EVENT_MMI_Id] =
242        [this](const AppExecFwk::InnerEvent::Pointer &event) { GetMMIResponse(event); };
243    requestFuncMap_[DtmfHandlerId::EVENT_EXECUTE_POST_DIAL] =
244        [this](const AppExecFwk::InnerEvent::Pointer &event) { ExecutePostDial(event); };
245}
246
247void CellularCallHandler::RegisterImsCallCallbackHandler()
248{
249    // Register IMS
250    std::shared_ptr<ImsCallClient> imsCallClient = DelayedSingleton<ImsCallClient>::GetInstance();
251    if (imsCallClient != nullptr) {
252        imsCallClient->RegisterImsCallCallbackHandler(slotId_, shared_from_this());
253    }
254}
255
256void CellularCallHandler::RegisterSatelliteCallCallbackHandler()
257{
258    // Register Satellite
259    std::shared_ptr<SatelliteCallClient> satelliteCallClient = DelayedSingleton<SatelliteCallClient>::GetInstance();
260    if (satelliteCallClient != nullptr) {
261        satelliteCallClient->RegisterSatelliteCallCallbackHandler(slotId_, shared_from_this());
262    }
263}
264
265void CellularCallHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
266{
267    if (event == nullptr) {
268        TELEPHONY_LOGE("[slot%{public}d] event is null", slotId_);
269        return;
270    }
271
272    uint32_t eventId = event->GetInnerEventId();
273    TELEPHONY_LOGD("[slot%{public}d] eventId = %{public}d", slotId_, eventId);
274
275    auto itFunc = requestFuncMap_.find(event->GetInnerEventId());
276    if (itFunc != requestFuncMap_.end()) {
277        auto requestFunc = itFunc->second;
278        if (requestFunc != nullptr) {
279            return requestFunc(event);
280        }
281    }
282    TELEPHONY_LOGI("[slot%{public}d] Function not found, need check.", slotId_);
283}
284
285void CellularCallHandler::OnReceiveEvent(const EventFwk::CommonEventData &data)
286{
287    EventFwk::Want want = data.GetWant();
288    std::string action = want.GetAction();
289    TELEPHONY_LOGI("[slot%{public}d] action=%{public}s code=%{public}d", slotId_, action.c_str(), data.GetCode());
290    if (action == EventFwk::CommonEventSupport::COMMON_EVENT_OPERATOR_CONFIG_CHANGED) {
291        int32_t slotId = want.GetIntParam(BROADCAST_ARG_SLOT_ID, DEFAULT_SIM_SLOT_ID);
292        if (slotId_ != slotId) {
293            return;
294        }
295        this->SendEvent(OPERATOR_CONFIG_CHANGED_ID, DELAY_TIME, Priority::HIGH);
296    }
297    if (action == EventFwk::CommonEventSupport::COMMON_EVENT_NETWORK_STATE_CHANGED) {
298        int32_t slotId = want.GetIntParam(BROADCAST_ARG_SLOT_ID, DEFAULT_SIM_SLOT_ID);
299        if (slotId_ != slotId) {
300            return;
301        }
302        this->SendEvent(NETWORK_STATE_CHANGED, 0, Priority::HIGH);
303    }
304}
305
306void CellularCallHandler::GetCsCallData(const AppExecFwk::InnerEvent::Pointer &event)
307{
308    this->SendEvent(GET_CS_CALL_DATA_ID, 0, Priority::HIGH);
309}
310
311void CellularCallHandler::GetImsCallData(const AppExecFwk::InnerEvent::Pointer &event)
312{
313    this->SendEvent(GET_IMS_CALL_DATA_ID, 0, Priority::HIGH);
314}
315
316void CellularCallHandler::GetSatelliteCallData(const AppExecFwk::InnerEvent::Pointer &event)
317{
318    this->SendEvent(GET_SATELLITE_CALL_DATA_ID, 0, Priority::HIGH);
319}
320
321void CellularCallHandler::CellularCallIncomingStartTrace(const int32_t state)
322{
323    if (state == static_cast<int32_t>(TelCallState::CALL_STATUS_INCOMING)) {
324        StartAsyncTrace(HITRACE_TAG_OHOS, "CellularCallIncoming", getpid());
325    }
326}
327
328void CellularCallHandler::CellularCallIncomingFinishTrace(const int32_t state)
329{
330    if (state == static_cast<int32_t>(TelCallState::CALL_STATUS_INCOMING)) {
331        FinishAsyncTrace(HITRACE_TAG_OHOS, "CellularCallIncoming", getpid());
332    }
333}
334
335void CellularCallHandler::ReportCsCallsData(const CallInfoList &callInfoList)
336{
337    auto serviceInstance = DelayedSingleton<CellularCallService>::GetInstance();
338    if (serviceInstance == nullptr) {
339        TELEPHONY_LOGE("[slot%{public}d] serviceInstance is null", slotId_);
340        return;
341    }
342    CallInfo callInfo;
343    std::vector<CallInfo>::const_iterator it = callInfoList.calls.begin();
344    for (; it != callInfoList.calls.end(); ++it) {
345        callInfo.state = (*it).state;
346    }
347    TELEPHONY_LOGI("[slot%{public}d] callInfoList.callSize:%{public}d", slotId_, callInfoList.callSize);
348    CellularCallIncomingStartTrace(callInfo.state);
349    auto csControl = serviceInstance->GetCsControl(slotId_);
350    if (callInfoList.callSize == 0) {
351        if (isInCsRedial_) {
352            TELEPHONY_LOGI("[slot%{public}d] Ignore hangup during cs redial", slotId_);
353            isInCsRedial_ = false;
354            return;
355        }
356        if (csControl == nullptr) {
357            TELEPHONY_LOGE("[slot%{public}d] cs_control is null", slotId_);
358            CellularCallIncomingFinishTrace(callInfo.state);
359            return;
360        }
361        if (csControl->ReportCallsData(slotId_, callInfoList) != TELEPHONY_SUCCESS) {
362            CellularCallIncomingFinishTrace(callInfo.state);
363        }
364        serviceInstance->SetCsControl(slotId_, nullptr);
365        return;
366    }
367    if (isInCsRedial_) {
368        TELEPHONY_LOGI("[slot%{public}d] Ignore cs call state change during cs redial", slotId_);
369        return;
370    }
371    if (callInfoList.callSize == 1) {
372        if (csControl == nullptr) {
373            csControl = std::make_shared<CSControl>();
374            serviceInstance->SetCsControl(slotId_, csControl);
375        }
376    }
377    if (csControl == nullptr) {
378        TELEPHONY_LOGE("[slot%{public}d] cs_control is null", slotId_);
379        CellularCallIncomingFinishTrace(callInfo.state);
380        return;
381    }
382    if (csControl->ReportCallsData(slotId_, callInfoList) != TELEPHONY_SUCCESS) {
383        CellularCallIncomingFinishTrace(callInfo.state);
384    }
385}
386
387void CellularCallHandler::ReportImsCallsData(const ImsCurrentCallList &imsCallInfoList)
388{
389    auto serviceInstance = DelayedSingleton<CellularCallService>::GetInstance();
390    if (serviceInstance == nullptr) {
391        TELEPHONY_LOGE("[slot%{public}d] serviceInstance is null", slotId_);
392        return;
393    }
394    ImsCurrentCall imsCallInfo;
395    std::vector<ImsCurrentCall>::const_iterator it = imsCallInfoList.calls.begin();
396    for (; it != imsCallInfoList.calls.end(); ++it) {
397        imsCallInfo.state = (*it).state;
398    }
399    TELEPHONY_LOGI("[slot%{public}d] imsCallInfoList.callSize:%{public}d", slotId_, imsCallInfoList.callSize);
400    CellularCallIncomingStartTrace(imsCallInfo.state);
401    auto imsControl = serviceInstance->GetImsControl(slotId_);
402    if (imsCallInfoList.callSize == 0) {
403        if (imsControl == nullptr) {
404            TELEPHONY_LOGE("[slot%{public}d] ims_control is null", slotId_);
405            return;
406        }
407        if (imsControl->ReportImsCallsData(slotId_, imsCallInfoList) != TELEPHONY_SUCCESS) {
408            CellularCallIncomingFinishTrace(imsCallInfo.state);
409        }
410        serviceInstance->SetImsControl(slotId_, nullptr);
411        return;
412    }
413    if (srvccState_ == SrvccState::STARTED) {
414        TELEPHONY_LOGI("[slot%{public}d] Ignore to report ims call state change during srvcc", slotId_);
415        return;
416    }
417    if (imsCallInfoList.callSize == 1) {
418        if (imsControl == nullptr) {
419            imsControl = std::make_shared<IMSControl>();
420            serviceInstance->SetImsControl(slotId_, imsControl);
421        }
422    }
423    if (imsControl == nullptr) {
424        TELEPHONY_LOGE("[slot%{public}d] ims_control is null", slotId_);
425        CellularCallIncomingFinishTrace(imsCallInfo.state);
426        return;
427    }
428    if (imsControl->ReportImsCallsData(slotId_, imsCallInfoList) != TELEPHONY_SUCCESS) {
429        CellularCallIncomingFinishTrace(imsCallInfo.state);
430    }
431}
432
433void CellularCallHandler::GetCsCallsDataResponse(const AppExecFwk::InnerEvent::Pointer &event)
434{
435    // Returns list of current calls of ME. If command succeeds but no calls are available,
436    // no information response is sent to TE. Refer subclause 9.2 for possible <err> values.
437    TELEPHONY_LOGI("[slot%{public}d] GetCsCallsDataResponse entry", slotId_);
438    auto callInfoList = event->GetSharedObject<CallInfoList>();
439    if (callInfoList == nullptr) {
440        TELEPHONY_LOGE("[slot%{public}d] Cannot get the callInfoList, need to get rilResponseInfo", slotId_);
441        auto rilResponseInfo = event->GetSharedObject<RadioResponseInfo>();
442        if (rilResponseInfo == nullptr) {
443            TELEPHONY_LOGE("[slot%{public}d] callInfoList and rilResponseInfo are null", slotId_);
444            return;
445        }
446        if (rilResponseInfo->error == ErrType::NONE) {
447            TELEPHONY_LOGE("[slot%{public}d] Failed to query the call list but no reason!", slotId_);
448            return;
449        }
450        CellularCallEventInfo eventInfo;
451        eventInfo.eventType = CellularCallEventType::EVENT_REQUEST_RESULT_TYPE;
452        eventInfo.eventId = RequestResultEventId::RESULT_GET_CURRENT_CALLS_FAILED;
453        if (registerInstance_ == nullptr) {
454            TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
455            return;
456        }
457        registerInstance_->ReportEventResultInfo(eventInfo);
458        return;
459    }
460    ProcessCsPhoneNumber(*callInfoList);
461    ProcessRedundantCode(*callInfoList);
462    ReportCsCallsData(*callInfoList);
463}
464
465void CellularCallHandler::GetImsCallsDataResponse(const AppExecFwk::InnerEvent::Pointer &event)
466{
467    // Returns list of current calls of ME. If command succeeds but no calls are available,
468    // no information response is sent to TE. Refer subclause 9.2 for possible <err> values.
469    auto imsCallInfoList = event->GetSharedObject<ImsCurrentCallList>();
470    if (imsCallInfoList == nullptr) {
471        TELEPHONY_LOGE("[slot%{public}d] Cannot get the imsCallInfoList, need to get rilResponseInfo", slotId_);
472        auto rilResponseInfo = event->GetSharedObject<RadioResponseInfo>();
473        if (rilResponseInfo == nullptr) {
474            TELEPHONY_LOGE("[slot%{public}d] callInfoList and rilResponseInfo are null", slotId_);
475            return;
476        }
477        if (rilResponseInfo->error == ErrType::NONE) {
478            TELEPHONY_LOGE("[slot%{public}d] Failed to query the call list but no reason!", slotId_);
479            return;
480        }
481        if (registerInstance_ == nullptr) {
482            TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
483            return;
484        }
485        registerInstance_->ReportGetCallDataResult(static_cast<int32_t>(rilResponseInfo->error));
486        return;
487    }
488    ProcessImsPhoneNumber(*imsCallInfoList);
489    ReportImsCallsData(*imsCallInfoList);
490}
491
492void CellularCallHandler::DialResponse(const AppExecFwk::InnerEvent::Pointer &event)
493{
494    auto result = event->GetSharedObject<RadioResponseInfo>();
495    if (result == nullptr) {
496        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
497        return;
498    }
499    struct CallBehaviorParameterInfo info = { 0 };
500    auto callHiSysEvent = DelayedSingleton<CellularCallHiSysEvent>::GetInstance();
501    if (callHiSysEvent == nullptr) {
502        TELEPHONY_LOGE("CellularCallHiSysEvent is null.");
503        return;
504    }
505    callHiSysEvent->GetCallParameterInfo(info);
506    if (result->error != ErrType::NONE) {
507        TELEPHONY_LOGE("[slot%{public}d] dial error:%{public}d", slotId_, result->error);
508        CellularCallEventInfo eventInfo;
509        eventInfo.eventType = CellularCallEventType::EVENT_REQUEST_RESULT_TYPE;
510
511        /*
512         * 3GPP TS 27.007 V3.9.0 (2001-06)
513         * If ME has succeeded in establishing a logical link between application protocols and external interface,
514         * it will send CONNECT message to the TE. Otherwise, the NO CARRIER response will be returned.
515         */
516        if (result->error == ErrType::ERR_CMD_NO_CARRIER) {
517            eventInfo.eventId = RequestResultEventId::RESULT_DIAL_NO_CARRIER;
518        } else {
519            eventInfo.eventId = RequestResultEventId::RESULT_DIAL_SEND_FAILED;
520        }
521        if (registerInstance_ == nullptr) {
522            TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
523            return;
524        }
525        registerInstance_->ReportEventResultInfo(eventInfo);
526        CellularCallHiSysEvent::WriteDialCallBehaviorEvent(info, CallResponseResult::COMMAND_FAILURE);
527    } else {
528        CellularCallHiSysEvent::WriteDialCallBehaviorEvent(info, CallResponseResult::COMMAND_SUCCESS);
529    }
530}
531
532void CellularCallHandler::DialSatelliteResponse(const AppExecFwk::InnerEvent::Pointer &event)
533{
534    auto result = event->GetSharedObject<RadioResponseInfo>();
535    if (result == nullptr) {
536        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
537        return;
538    }
539    struct CallBehaviorParameterInfo satelliteCallInfo = { 0 };
540    auto callHiSysEvent = DelayedSingleton<CellularCallHiSysEvent>::GetInstance();
541    if (callHiSysEvent == nullptr) {
542        TELEPHONY_LOGE("CellularCallHiSysEvent is null.");
543        return;
544    }
545    callHiSysEvent->GetCallParameterInfo(satelliteCallInfo);
546    if (result->error != ErrType::NONE) {
547        TELEPHONY_LOGE("[slot%{public}d] dial error:%{public}d", slotId_, result->error);
548        CellularCallEventInfo eventInfo;
549        eventInfo.eventType = CellularCallEventType::EVENT_REQUEST_RESULT_TYPE;
550
551        if (result->error == ErrType::ERR_CMD_NO_CARRIER) {
552            eventInfo.eventId = RequestResultEventId::RESULT_DIAL_NO_CARRIER;
553        } else {
554            eventInfo.eventId = RequestResultEventId::RESULT_DIAL_SEND_FAILED;
555        }
556        if (registerInstance_ == nullptr) {
557            TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
558            return;
559        }
560        registerInstance_->ReportEventResultInfo(eventInfo);
561        CellularCallHiSysEvent::WriteDialCallBehaviorEvent(satelliteCallInfo, CallResponseResult::COMMAND_FAILURE);
562    } else {
563        CellularCallHiSysEvent::WriteDialCallBehaviorEvent(satelliteCallInfo, CallResponseResult::COMMAND_SUCCESS);
564    }
565}
566
567void CellularCallHandler::GetSatelliteCallsDataResponse(const AppExecFwk::InnerEvent::Pointer &event)
568{
569    auto satelliteCallInfoList = event->GetSharedObject<SatelliteCurrentCallList>();
570    if (satelliteCallInfoList == nullptr) {
571        TELEPHONY_LOGE(
572            "[slot%{public}d] Cannot get the SatelliteCurrentCallList, need to create satelliteCallInfoList", slotId_);
573        satelliteCallInfoList = std::make_shared<SatelliteCurrentCallList>();
574    }
575    ReportSatelliteCallsData(*satelliteCallInfoList);
576}
577
578void CellularCallHandler::ReportSatelliteCallsData(const SatelliteCurrentCallList &callInfoList)
579{
580    auto serviceInstance = DelayedSingleton<CellularCallService>::GetInstance();
581    if (serviceInstance == nullptr) {
582        TELEPHONY_LOGE("[slot%{public}d] serviceInstance is null", slotId_);
583        return;
584    }
585    auto satelliteControl = serviceInstance->GetSatelliteControl(slotId_);
586    SatelliteCurrentCall callInfo;
587    std::vector<SatelliteCurrentCall>::const_iterator it = callInfoList.calls.begin();
588    for (; it != callInfoList.calls.end(); ++it) {
589        callInfo.state = (*it).state;
590    }
591    TELEPHONY_LOGI("[slot%{public}d] callInfoList.callSize:%{public}d", slotId_, callInfoList.callSize);
592    CellularCallIncomingStartTrace(callInfo.state);
593    if (callInfoList.callSize == 0) {
594        if (satelliteControl == nullptr) {
595            TELEPHONY_LOGE("[slot%{public}d] satelliteControl is null", slotId_);
596            CellularCallIncomingFinishTrace(callInfo.state);
597            return;
598        }
599        if (satelliteControl->ReportSatelliteCallsData(slotId_, callInfoList) != TELEPHONY_SUCCESS) {
600            CellularCallIncomingFinishTrace(callInfo.state);
601        }
602        serviceInstance->SetSatelliteControl(slotId_, nullptr);
603        return;
604    }
605    if (callInfoList.callSize == 1) {
606        if (satelliteControl == nullptr) {
607            satelliteControl = std::make_shared<SatelliteControl>();
608            serviceInstance->SetSatelliteControl(slotId_, satelliteControl);
609        }
610    }
611    if (satelliteControl == nullptr) {
612        TELEPHONY_LOGE("[slot%{public}d] satelliteControl is null", slotId_);
613        CellularCallIncomingFinishTrace(callInfo.state);
614        return;
615    }
616    if (satelliteControl->ReportSatelliteCallsData(slotId_, callInfoList) != TELEPHONY_SUCCESS) {
617        CellularCallIncomingFinishTrace(callInfo.state);
618    }
619}
620
621void CellularCallHandler::CommonResultEventHandling(
622    const AppExecFwk::InnerEvent::Pointer &event, CellularCallEventInfo &eventInfo)
623{
624    eventInfo.eventType = CellularCallEventType::EVENT_REQUEST_RESULT_TYPE;
625    switch (event->GetInnerEventId()) {
626        case RadioEvent::RADIO_HANGUP_CONNECT:
627            eventInfo.eventId = RequestResultEventId::RESULT_END_SEND_FAILED;
628            break;
629        case RadioEvent::RADIO_REJECT_CALL:
630            eventInfo.eventId = RequestResultEventId::RESULT_REJECT_SEND_FAILED;
631            break;
632        case RadioEvent::RADIO_ACCEPT_CALL:
633            eventInfo.eventId = RequestResultEventId::RESULT_ACCEPT_SEND_FAILED;
634            break;
635        case RadioEvent::RADIO_HOLD_CALL:
636            eventInfo.eventId = RequestResultEventId::RESULT_HOLD_SEND_FAILED;
637            break;
638        case RadioEvent::RADIO_ACTIVE_CALL:
639            eventInfo.eventId = RequestResultEventId::RESULT_ACTIVE_SEND_FAILED;
640            break;
641        case RadioEvent::RADIO_SWAP_CALL:
642            eventInfo.eventId = RequestResultEventId::RESULT_SWAP_SEND_FAILED;
643            break;
644        case RadioEvent::RADIO_COMBINE_CALL:
645        case RadioEvent::RADIO_JOIN_CALL:
646            eventInfo.eventId = RequestResultEventId::RESULT_COMBINE_SEND_FAILED;
647            break;
648        case RadioEvent::RADIO_SPLIT_CALL:
649            eventInfo.eventId = RequestResultEventId::RESULT_SPLIT_SEND_FAILED;
650            break;
651        case RadioEvent::RADIO_CALL_SUPPLEMENT:
652            eventInfo.eventId = RequestResultEventId::RESULT_SUPPLEMENT_SEND_FAILED;
653            break;
654        default:
655            break;
656    }
657}
658
659void CellularCallHandler::CommonResultResponse(const AppExecFwk::InnerEvent::Pointer &event)
660{
661    auto result = event->GetSharedObject<RadioResponseInfo>();
662    if (result == nullptr) {
663        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
664        return;
665    }
666    struct CallBehaviorParameterInfo info = { 0 };
667    auto callHiSysEvent = DelayedSingleton<CellularCallHiSysEvent>::GetInstance();
668    if (callHiSysEvent == nullptr) {
669        TELEPHONY_LOGE("CellularCallHiSysEvent is null.");
670        return;
671    }
672    callHiSysEvent->GetCallParameterInfo(info);
673    if (result->error != ErrType::NONE) {
674        CellularCallEventInfo eventInfo;
675        eventInfo.eventId = RequestResultEventId::INVALID_REQUEST_RESULT_EVENT_ID;
676        CommonResultEventHandling(event, eventInfo);
677        if (eventInfo.eventId == RequestResultEventId::RESULT_END_SEND_FAILED ||
678            eventInfo.eventId == RequestResultEventId::RESULT_REJECT_SEND_FAILED) {
679            CellularCallHiSysEvent::WriteHangUpCallBehaviorEvent(info, CallResponseResult::COMMAND_FAILURE);
680        } else if (eventInfo.eventId == RequestResultEventId::RESULT_ACCEPT_SEND_FAILED) {
681            CellularCallHiSysEvent::WriteAnswerCallBehaviorEvent(info, CallResponseResult::COMMAND_FAILURE);
682        } else {
683            TELEPHONY_LOGW("[slot%{public}d] eventId is:%{public}d, not within the scope of processing", slotId_,
684                eventInfo.eventId);
685        }
686        if (registerInstance_ == nullptr) {
687            TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
688            return;
689        }
690        registerInstance_->ReportEventResultInfo(eventInfo);
691        return;
692    }
693    uint32_t id = event->GetInnerEventId();
694    if (id == RadioEvent::RADIO_HANGUP_CONNECT || id == RadioEvent::RADIO_REJECT_CALL) {
695        CellularCallHiSysEvent::WriteHangUpCallBehaviorEvent(info, CallResponseResult::COMMAND_SUCCESS);
696    } else if (id == RadioEvent::RADIO_ACCEPT_CALL) {
697        CellularCallHiSysEvent::WriteAnswerCallBehaviorEvent(info, CallResponseResult::COMMAND_SUCCESS);
698    } else {
699        TELEPHONY_LOGW("[slot%{public}d] id is:%{public}d, not within the scope of processing", slotId_, id);
700    }
701}
702
703void CellularCallHandler::ExecutePostDial(const AppExecFwk::InnerEvent::Pointer &event)
704{
705    auto postDialData = event->GetSharedObject<PostDialData>();
706    if (postDialData == nullptr) {
707        TELEPHONY_LOGE("[slot%{public}d] postDialData is null", slotId_);
708        return;
709    }
710    auto serviceInstance = DelayedSingleton<CellularCallService>::GetInstance();
711    if (serviceInstance == nullptr) {
712        TELEPHONY_LOGE("[slot%{public}d] serviceInstance is null", slotId_);
713        return;
714    }
715    int64_t callId = postDialData->callId;
716    if (postDialData->isIms) {
717        auto imsControl = serviceInstance->GetImsControl(slotId_);
718        if (imsControl == nullptr) {
719            TELEPHONY_LOGE("[slot%{public}d] imsControl is null", slotId_);
720            return;
721        }
722        imsControl->ExecutePostDial(slotId_, callId);
723    } else {
724        auto csControl = serviceInstance->GetCsControl(slotId_);
725        if (csControl == nullptr) {
726            TELEPHONY_LOGE("[slot%{public}d] csControl is null", slotId_);
727            return;
728        }
729        csControl->ExecutePostDial(slotId_, callId);
730    }
731}
732
733void CellularCallHandler::SwapCallResponse(const AppExecFwk::InnerEvent::Pointer &event)
734{
735    auto serviceInstence = DelayedSingleton<CellularCallService>::GetInstance();
736    if (serviceInstence == nullptr) {
737        TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
738        return;
739    }
740    auto callType = event->GetParam();
741    std::shared_ptr<IMSControl> imsControl = nullptr;
742    if (callType == static_cast<int32_t>(CallType::TYPE_IMS)) {
743        imsControl = serviceInstence->GetImsControl(slotId_);
744        if (imsControl == nullptr) {
745            TELEPHONY_LOGE("[slot%{public}d] imsControl is null", slotId_);
746            return;
747        }
748        imsControl->RecoverPendingHold();
749    }
750    auto result = event->GetSharedObject<RadioResponseInfo>();
751    if (result == nullptr) {
752        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
753        return;
754    }
755    if (result->error != ErrType::NONE) {
756        CellularCallEventInfo eventInfo;
757        eventInfo.eventId = RequestResultEventId::INVALID_REQUEST_RESULT_EVENT_ID;
758        CommonResultEventHandling(event, eventInfo);
759        if (registerInstance_ == nullptr) {
760            TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
761            return;
762        }
763        registerInstance_->ReportEventResultInfo(eventInfo);
764        return;
765    }
766    if (imsControl != nullptr) {
767        imsControl->DialAfterHold(slotId_);
768    }
769}
770
771void CellularCallHandler::SendDtmfResponse(const AppExecFwk::InnerEvent::Pointer &event)
772{
773    auto result = event->GetSharedObject<RadioResponseInfo>();
774    if (result == nullptr) {
775        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
776        return;
777    }
778
779    std::shared_ptr<PostDialData> postDial = std::make_shared<PostDialData>();
780    postDial->callId = result->flag;
781    postDial->isIms = event->GetParam() == static_cast<int32_t>(CallType::TYPE_IMS);
782    this->SendEvent(EVENT_EXECUTE_POST_DIAL, postDial, DELAY_TIME);
783
784    CellularCallEventInfo eventInfo;
785    eventInfo.eventType = CellularCallEventType::EVENT_REQUEST_RESULT_TYPE;
786    if (result->error != ErrType::NONE) {
787        eventInfo.eventId = RequestResultEventId::RESULT_SEND_DTMF_FAILED;
788    } else {
789        eventInfo.eventId = RequestResultEventId::RESULT_SEND_DTMF_SUCCESS;
790    }
791    if (registerInstance_ == nullptr) {
792        TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
793        return;
794    }
795    registerInstance_->ReportEventResultInfo(eventInfo);
796}
797
798void CellularCallHandler::StartDtmfResponse(const AppExecFwk::InnerEvent::Pointer &event)
799{
800    auto result = event->GetSharedObject<RadioResponseInfo>();
801    if (result == nullptr) {
802        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
803        return;
804    }
805    if (registerInstance_ == nullptr) {
806        TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
807        return;
808    }
809    registerInstance_->ReportStartDtmfResult(static_cast<int32_t>(result->error));
810}
811
812void CellularCallHandler::SimStateChangeReport(const AppExecFwk::InnerEvent::Pointer &event)
813{
814    CellularCallConfig config;
815    config.HandleSimStateChanged(slotId_);
816}
817
818void CellularCallHandler::FactoryReset(const AppExecFwk::InnerEvent::Pointer &event)
819{
820    CellularCallConfig config;
821    config.HandleFactoryReset(slotId_);
822}
823
824void CellularCallHandler::SimRecordsLoadedReport(const AppExecFwk::InnerEvent::Pointer &event)
825{
826    CellularCallConfig config;
827    config.HandleSimRecordsLoaded(slotId_);
828}
829
830void CellularCallHandler::SimAccountLoadedReport(const AppExecFwk::InnerEvent::Pointer &event)
831{
832    CellularCallConfig config;
833    config.HandleSimAccountLoaded(slotId_);
834}
835
836void CellularCallHandler::ResidentNetworkChangeReport(const AppExecFwk::InnerEvent::Pointer &event)
837{
838    if (event == nullptr) {
839        TELEPHONY_LOGE("ResidentNetworkChangeReport event is nullptr slotId:%{public}d!", slotId_);
840        return;
841    }
842    auto result = event->GetSharedObject<std::string>();
843    if (result == nullptr) {
844        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
845        return;
846    }
847    CellularCallConfig config;
848    config.HandleResidentNetworkChange(slotId_, *result);
849}
850
851void CellularCallHandler::NetworkStateChangeReport(const AppExecFwk::InnerEvent::Pointer &event)
852{
853    if (event == nullptr) {
854        TELEPHONY_LOGE("NetworkStateChangeReport event is nullptr slotId:%{public}d!", slotId_);
855        return;
856    }
857    CellularCallConfig config;
858    config.HandleNetworkStateChange(slotId_);
859}
860
861void CellularCallHandler::StopDtmfResponse(const AppExecFwk::InnerEvent::Pointer &event)
862{
863    auto result = event->GetSharedObject<RadioResponseInfo>();
864    if (result == nullptr) {
865        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
866        return;
867    }
868    if (registerInstance_ == nullptr) {
869        TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
870        return;
871    }
872    registerInstance_->ReportStopDtmfResult(static_cast<int32_t>(result->error));
873}
874
875void CellularCallHandler::ReceiveUpdateCallMediaModeRequest(const AppExecFwk::InnerEvent::Pointer &event)
876{
877    struct CallBehaviorParameterInfo info = { 0 };
878    auto callHiSysEvent = DelayedSingleton<CellularCallHiSysEvent>::GetInstance();
879    if (callHiSysEvent == nullptr) {
880        TELEPHONY_LOGE("CellularCallHiSysEvent is null.");
881        return;
882    }
883    callHiSysEvent->GetCallParameterInfo(info);
884    auto result = event->GetSharedObject<ImsCallModeReceiveInfo>();
885    if (result == nullptr) {
886        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
887        return;
888    }
889    if (registerInstance_ == nullptr) {
890        TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
891        return;
892    }
893    registerInstance_->ReceiveUpdateCallMediaModeRequest(slotId_, *result);
894    int32_t requestResult = static_cast<ImsCallModeRequestResult>(result->result);
895    CellularCallHiSysEvent::WriteImsCallModeBehaviorEvent(
896        CallModeBehaviorType::RECEIVE_REQUEST_EVENT, info, requestResult);
897}
898
899void CellularCallHandler::ReceiveUpdateCallMediaModeResponse(const AppExecFwk::InnerEvent::Pointer &event)
900{
901    struct CallBehaviorParameterInfo info = { 0 };
902    auto callHiSysEvent = DelayedSingleton<CellularCallHiSysEvent>::GetInstance();
903    if (callHiSysEvent == nullptr) {
904        TELEPHONY_LOGE("CellularCallHiSysEvent is null.");
905        return;
906    }
907    callHiSysEvent->GetCallParameterInfo(info);
908    auto result = event->GetSharedObject<ImsCallModeReceiveInfo>();
909    if (result == nullptr) {
910        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
911        return;
912    }
913    if (registerInstance_ == nullptr) {
914        TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
915        return;
916    }
917    registerInstance_->ReceiveUpdateCallMediaModeResponse(slotId_, *result);
918    info.videoState = static_cast<ImsCallType>(result->callType);
919    int32_t requestResult = static_cast<ImsCallModeRequestResult>(result->result);
920    CellularCallHiSysEvent::WriteImsCallModeBehaviorEvent(
921        CallModeBehaviorType::RECEIVE_RESPONSE_EVENT, info, requestResult);
922}
923
924void CellularCallHandler::HandleCallSessionEventChanged(const AppExecFwk::InnerEvent::Pointer &event)
925{
926    auto result = event->GetSharedObject<ImsCallSessionEventInfo>();
927    if (result == nullptr) {
928        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
929        return;
930    }
931    if (registerInstance_ == nullptr) {
932        TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
933        return;
934    }
935    registerInstance_->HandleCallSessionEventChanged(*result);
936}
937
938void CellularCallHandler::HandlePeerDimensionsChanged(const AppExecFwk::InnerEvent::Pointer &event)
939{
940    auto result = event->GetSharedObject<ImsCallPeerDimensionsInfo>();
941    if (result == nullptr) {
942        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
943        return;
944    }
945    if (registerInstance_ == nullptr) {
946        TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
947        return;
948    }
949    registerInstance_->HandlePeerDimensionsChanged(*result);
950}
951
952void CellularCallHandler::HandleCallDataUsageChanged(const AppExecFwk::InnerEvent::Pointer &event)
953{
954    auto result = event->GetSharedObject<ImsCallDataUsageInfo>();
955    if (result == nullptr) {
956        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
957        return;
958    }
959    if (registerInstance_ == nullptr) {
960        TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
961        return;
962    }
963    registerInstance_->HandleCallDataUsageChanged(*result);
964}
965
966void CellularCallHandler::HandleCameraCapabilitiesChanged(const AppExecFwk::InnerEvent::Pointer &event)
967{
968    auto result = event->GetSharedObject<CameraCapabilitiesInfo>();
969    if (result == nullptr) {
970        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
971        return;
972    }
973    if (registerInstance_ == nullptr) {
974        TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
975        return;
976    }
977    registerInstance_->HandleCameraCapabilitiesChanged(*result);
978}
979
980void CellularCallHandler::SetSlotId(int32_t id)
981{
982    slotId_ = id;
983}
984
985int32_t CellularCallHandler::GetSlotId()
986{
987    return slotId_;
988}
989
990int64_t CellularCallHandler::CurrentTimeMillis()
991{
992    int64_t timems =
993        std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
994            .count();
995    return timems;
996}
997
998void CellularCallHandler::GetCsCallsDataRequest(const AppExecFwk::InnerEvent::Pointer &event)
999{
1000    lastCallsDataFlag_ = CurrentTimeMillis();
1001    CellularCallConnectionCS connectionCs;
1002    connectionCs.GetCsCallsDataRequest(slotId_, lastCallsDataFlag_);
1003}
1004
1005void CellularCallHandler::GetImsCallsDataRequest(const AppExecFwk::InnerEvent::Pointer &event)
1006{
1007    lastCallsDataFlag_ = CurrentTimeMillis();
1008    CellularCallConnectionIMS connectionIms;
1009    connectionIms.GetImsCallsDataRequest(slotId_, lastCallsDataFlag_);
1010}
1011
1012void CellularCallHandler::GetSatelliteCallsDataRequest(const AppExecFwk::InnerEvent::Pointer &event)
1013{
1014    lastCallsDataFlag_ = CurrentTimeMillis();
1015    CellularCallConnectionSatellite connectionSatellite;
1016    connectionSatellite.GetSatelliteCallsDataRequest(slotId_, lastCallsDataFlag_);
1017}
1018
1019void CellularCallHandler::RegisterHandler(const AppExecFwk::InnerEvent::Pointer &event)
1020{
1021    CellularCallConnectionCS connectionCs;
1022    connectionCs.RegisterHandler();
1023}
1024
1025void CellularCallHandler::SetDomainPreferenceModeResponse(const AppExecFwk::InnerEvent::Pointer &event)
1026{
1027    auto info = event->GetSharedObject<RadioResponseInfo>();
1028    if (info == nullptr) {
1029        TELEPHONY_LOGE("[slot%{public}d] info is null", slotId_);
1030        return;
1031    }
1032    CellularCallEventInfo eventInfo;
1033    eventInfo.eventType = CellularCallEventType::EVENT_REQUEST_RESULT_TYPE;
1034    if (info->error != ErrType::NONE) {
1035        eventInfo.eventId = RequestResultEventId::RESULT_SET_CALL_PREFERENCE_MODE_FAILED;
1036    } else {
1037        eventInfo.eventId = RequestResultEventId::RESULT_SET_CALL_PREFERENCE_MODE_SUCCESS;
1038
1039        CellularCallConfig config;
1040        config.SetTempMode(slotId_);
1041    }
1042    if (registerInstance_ == nullptr) {
1043        TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
1044        return;
1045    }
1046    registerInstance_->ReportEventResultInfo(eventInfo);
1047}
1048
1049void CellularCallHandler::GetDomainPreferenceModeResponse(const AppExecFwk::InnerEvent::Pointer &event)
1050{
1051    auto mode = event->GetSharedObject<int32_t>();
1052    if (mode == nullptr) {
1053        TELEPHONY_LOGI("[slot%{public}d] mode is null", slotId_);
1054        return;
1055    }
1056    CellularCallConfig config;
1057    config.GetDomainPreferenceModeResponse(slotId_, *mode);
1058}
1059
1060void CellularCallHandler::SetImsSwitchStatusResponse(const AppExecFwk::InnerEvent::Pointer &event)
1061{
1062    auto info = event->GetSharedObject<RadioResponseInfo>();
1063    if (info == nullptr) {
1064        TELEPHONY_LOGE("[slot%{public}d] info is null", slotId_);
1065        return;
1066    }
1067    if (registerInstance_ == nullptr) {
1068        TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
1069        return;
1070    }
1071    CellularCallConfig config;
1072    config.HandleSetLteImsSwitchResult(slotId_, info->error);
1073}
1074
1075void CellularCallHandler::GetImsSwitchStatusResponse(const AppExecFwk::InnerEvent::Pointer &event) {}
1076
1077void CellularCallHandler::SetVoNRSwitchStatusResponse(const AppExecFwk::InnerEvent::Pointer &event)
1078{
1079    auto info = event->GetSharedObject<RadioResponseInfo>();
1080    if (info == nullptr) {
1081        TELEPHONY_LOGE("[slot%{public}d] info is null", slotId_);
1082        return;
1083    }
1084    CellularCallConfig config;
1085    config.HandleSetVoNRSwitchResult(slotId_, info->error);
1086}
1087
1088void CellularCallHandler::CsCallStatusInfoReport(const AppExecFwk::InnerEvent::Pointer &event)
1089{
1090    TELEPHONY_LOGI("[slot%{public}d] CsCallStatusInfoReport entry", slotId_);
1091    if (srvccState_ == SrvccState::STARTED) {
1092        TELEPHONY_LOGI("[slot%{public}d] Ignore to report cs call state change cause by srvcc started", slotId_);
1093        return;
1094    }
1095    GetCsCallData(event);
1096}
1097
1098void CellularCallHandler::ImsCallStatusInfoReport(const AppExecFwk::InnerEvent::Pointer &event)
1099{
1100    GetImsCallData(event);
1101}
1102
1103void CellularCallHandler::SatelliteCallStatusInfoReport(const AppExecFwk::InnerEvent::Pointer &event)
1104{
1105    if (srvccState_ == SrvccState::STARTED) {
1106        TELEPHONY_LOGI("[slot%{public}d] Ignore to report satellite call state change cause by srvcc started", slotId_);
1107        return;
1108    }
1109    GetSatelliteCallData(event);
1110}
1111
1112void CellularCallHandler::UssdNotifyResponse(const AppExecFwk::InnerEvent::Pointer &event)
1113{
1114    auto result = event->GetSharedObject<UssdNoticeInfo>();
1115    if (result == nullptr) {
1116        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
1117        return;
1118    }
1119    CellularCallSupplement supplement;
1120    supplement.EventUssdNotify(*result);
1121}
1122
1123void CellularCallHandler::SetMuteResponse(const AppExecFwk::InnerEvent::Pointer &event)
1124{
1125    auto info = event->GetSharedObject<RadioResponseInfo>();
1126    if (info == nullptr) {
1127        TELEPHONY_LOGE("[slot%{public}d] info is null", slotId_);
1128        return;
1129    }
1130    MuteControlResponse response;
1131    if (registerInstance_ == nullptr) {
1132        TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
1133        return;
1134    }
1135    response.result = static_cast<int32_t>(info->error);
1136    registerInstance_->ReportSetMuteResult(response);
1137}
1138
1139void CellularCallHandler::GetMuteResponse(const AppExecFwk::InnerEvent::Pointer &event)
1140{
1141    MuteControlResponse response;
1142    auto mute = event->GetSharedObject<int32_t>();
1143    if (mute == nullptr) {
1144        TELEPHONY_LOGI("[slot%{public}d] mute is null", slotId_);
1145        auto info = event->GetSharedObject<RadioResponseInfo>();
1146        if (info == nullptr) {
1147            TELEPHONY_LOGE("[slot%{public}d] info is null", slotId_);
1148            return;
1149        }
1150        response.result = static_cast<int32_t>(info->error);
1151    } else {
1152        response.result = static_cast<int32_t>(ErrType::NONE);
1153        response.value = *mute;
1154    }
1155    if (registerInstance_ == nullptr) {
1156        TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
1157        return;
1158    }
1159    registerInstance_->ReportGetMuteResult(response);
1160}
1161
1162void CellularCallHandler::GetEmergencyCallListResponse(const AppExecFwk::InnerEvent::Pointer &event)
1163{
1164    auto eccList = event->GetSharedObject<EmergencyInfoList>();
1165    if (eccList == nullptr) {
1166        TELEPHONY_LOGE("[slot%{public}d] eccList is null", slotId_);
1167        return;
1168    }
1169    CellularCallConfig config;
1170    config.UpdateEmergencyCallFromRadio(slotId_, *eccList);
1171}
1172
1173void CellularCallHandler::SetEmergencyCallListResponse(const AppExecFwk::InnerEvent::Pointer &event)
1174{
1175    auto info = event->GetSharedObject<RadioResponseInfo>();
1176    if (info == nullptr) {
1177        TELEPHONY_LOGE("[slot%{public}d] info is null", slotId_);
1178        return;
1179    }
1180    if (registerInstance_ == nullptr) {
1181        TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
1182        return;
1183    }
1184    SetEccListResponse response;
1185    response.result = static_cast<int32_t>(info->error);
1186    registerInstance_->ReportSetEmergencyCallListResponse(response);
1187}
1188
1189void CellularCallHandler::CallRingBackVoiceResponse(const AppExecFwk::InnerEvent::Pointer &event)
1190{
1191    auto ringBackVoice = event->GetSharedObject<RingbackVoice>();
1192    if (ringBackVoice == nullptr) {
1193        TELEPHONY_LOGE("[slot%{public}d] ringBackVoice is null", slotId_);
1194        return;
1195    }
1196    if (registerInstance_ == nullptr) {
1197        TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
1198        return;
1199    }
1200    registerInstance_->ReportCallRingBackResult(ringBackVoice->status);
1201}
1202
1203void CellularCallHandler::GetCallFailReasonResponse(const AppExecFwk::InnerEvent::Pointer &event)
1204{
1205    if (registerInstance_ == nullptr) {
1206        TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
1207        return;
1208    }
1209    auto reason = event->GetSharedObject<int32_t>();
1210    DisconnectedDetails details;
1211    if (reason == nullptr) {
1212        auto info = event->GetSharedObject<DisconnectedDetails>();
1213        if (info == nullptr) {
1214            TELEPHONY_LOGE("[slot%{public}d] info is null", slotId_);
1215            return;
1216        }
1217        details.reason = static_cast<DisconnectedReason>(info->reason);
1218        details.message = (info->message.c_str() == nullptr) ? "" : info->message;
1219    } else {
1220        details.reason = static_cast<DisconnectedReason>(*reason);
1221        details.message = "";
1222    }
1223
1224    if (details.message.empty()) {
1225        std::string callFailedMessageName = "";
1226        bool ret =
1227            ResourceUtils::Get().GetCallFailedMessageName(static_cast<int32_t>(details.reason), callFailedMessageName);
1228        if (!ret) {
1229            TELEPHONY_LOGE("[slot%{public}d] Get call failed message failed!", slotId_);
1230            return;
1231        }
1232        ResourceUtils::Get().GetStringValueByName(callFailedMessageName, details.message);
1233    }
1234    CellularCallHiSysEvent::WriteCallEndBehaviorEvent(slotId_, static_cast<int32_t>(details.reason));
1235    registerInstance_->ReportCallFailReason(details);
1236}
1237
1238void CellularCallHandler::UpdateSrvccStateReport(const AppExecFwk::InnerEvent::Pointer &event)
1239{
1240    auto srvccStatus = event->GetSharedObject<SrvccStatus>();
1241    if (srvccStatus == nullptr) {
1242        TELEPHONY_LOGE("[slot%{public}d] srvccStatus is null", slotId_);
1243        return;
1244    }
1245    TELEPHONY_LOGI("[slot%{public}d] srvccStatus is %{public}d", slotId_, srvccStatus->status);
1246    srvccState_ = srvccStatus->status;
1247    auto serviceInstance_ = DelayedSingleton<CellularCallService>::GetInstance();
1248    if (registerInstance_ == nullptr) {
1249        TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
1250        return;
1251    }
1252    serviceInstance_->SetSrvccState(srvccState_);
1253    if (srvccState_ != SrvccState::COMPLETED) {
1254        TELEPHONY_LOGE("[slot%{public}d] srvccState_ != SrvccState::COMPLETED", slotId_);
1255        return;
1256    }
1257    SrvccStateCompleted();
1258}
1259
1260void CellularCallHandler::ReportEccChanged(const AppExecFwk::InnerEvent::Pointer &event)
1261{
1262    auto emergencyInfoList = event->GetSharedObject<EmergencyInfoList>();
1263    if (emergencyInfoList == nullptr) {
1264        TELEPHONY_LOGE("[slot%{public}d] emergencyInfoList is null", slotId_);
1265        return;
1266    }
1267    CellularCallConfig config;
1268    auto calls = emergencyInfoList->calls;
1269    if (calls.size() > 0 && static_cast<uint32_t>(calls.back().total) != calls.size()) {
1270        TELEPHONY_LOGE("[slot%{public}d] data error", slotId_);
1271        auto endCall = calls.back();
1272        if (endCall.index < endCall.total) {
1273            return;
1274        }
1275        TELEPHONY_LOGI("[slot%{public}d] try query", slotId_);
1276        config.GetEmergencyCallList(slotId_);
1277        return;
1278    }
1279    config.UpdateEmergencyCallFromRadio(slotId_, *emergencyInfoList);
1280}
1281
1282void CellularCallHandler::SrvccStateCompleted()
1283{
1284    if (srvccState_ != SrvccState::COMPLETED) {
1285        TELEPHONY_LOGE("[slot%{public}d] srvccState_ != SrvccState::COMPLETED", slotId_);
1286        return;
1287    }
1288    auto serviceInstance_ = DelayedSingleton<CellularCallService>::GetInstance();
1289    if (serviceInstance_ == nullptr) {
1290        TELEPHONY_LOGE("[slot%{public}d] registerInstance_ is null", slotId_);
1291        return;
1292    }
1293    auto csControl = serviceInstance_->GetCsControl(slotId_);
1294    if (csControl != nullptr) {
1295        TELEPHONY_LOGI("[slot%{public}d] CsControl ReleaseAllConnection", slotId_);
1296        csControl->ReleaseAllConnection();
1297        serviceInstance_->SetCsControl(slotId_, nullptr);
1298    } else {
1299        TELEPHONY_LOGI("[slot%{public}d] CsControl is null", slotId_);
1300        csControl = std::make_shared<CSControl>();
1301        serviceInstance_->SetCsControl(slotId_, csControl);
1302    }
1303    auto imsControl = serviceInstance_->GetImsControl(slotId_);
1304    if (imsControl != nullptr) {
1305        TELEPHONY_LOGI("[slot%{public}d] ImsControl ReleaseAllConnection", slotId_);
1306        imsControl->ReleaseAllConnection();
1307        serviceInstance_->SetImsControl(slotId_, nullptr);
1308    } else {
1309        TELEPHONY_LOGI("[slot%{public}d] imsControl is null", slotId_);
1310    }
1311    srvccState_ = SrvccState::SRVCC_NONE;
1312}
1313
1314void CellularCallHandler::GetMMIResponse(const AppExecFwk::InnerEvent::Pointer &event)
1315{
1316    std::unique_ptr<MMICodeUtils> mmiCodeUtils = event->GetUniqueObject<MMICodeUtils>();
1317    if (mmiCodeUtils == nullptr) {
1318        TELEPHONY_LOGE("[slot%{public}d] mmiCodeUtils is null", slotId_);
1319        return;
1320    }
1321    mmiCodeUtils->ExecuteMmiCode(slotId_);
1322}
1323
1324void CellularCallHandler::GetCallWaitingResponse(const AppExecFwk::InnerEvent::Pointer &event)
1325{
1326    auto result = event->GetSharedObject<CallWaitResult>();
1327    if (result == nullptr) {
1328        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
1329        return;
1330    }
1331    int32_t flag = SS_FROM_MMI_CODE;
1332    int32_t ret = ConfirmAndRemoveSsRequestCommand(result->result.index, flag);
1333    if (ret != TELEPHONY_SUCCESS) {
1334        return;
1335    }
1336    CellularCallSupplement supplement;
1337    supplement.EventGetCallWaiting(*result, result->result.message, flag);
1338}
1339
1340void CellularCallHandler::ProcessRedundantCode(CallInfoList &callInfoList)
1341{
1342    if (callInfoList.callSize == 0 || callInfoList.calls.empty()) {
1343        return;
1344    }
1345
1346    for (uint64_t i = 0; i < callInfoList.calls.size(); i++) {
1347        CallInfo callInfo = callInfoList.calls[i];
1348        std::regex phoneContextPattern(DOUBLE_PHONE_CONTEXT_STRING);
1349        if (callInfo.type == INTERNATION_CODE && std::regex_match(callInfo.number, phoneContextPattern)) {
1350            callInfoList.calls[i].number = callInfo.number.substr(0, 1) +
1351                callInfo.number.substr(PHONE_CONTEXT_EXPECTED.length());
1352        }
1353    }
1354}
1355
1356void CellularCallHandler::ProcessCsPhoneNumber(CallInfoList &list)
1357{
1358    if (list.callSize == 0 || list.calls.empty()) {
1359        return;
1360    }
1361    for (uint64_t i = 0; i < list.calls.size(); i++) {
1362        CallInfo callInfo = list.calls[i];
1363        if (callInfo.number.length() <= PHONE_CONTEXT_UNEXPECTED.length()) {
1364            continue;
1365        }
1366        if (callInfo.number.compare(0, PHONE_CONTEXT_UNEXPECTED.length(), PHONE_CONTEXT_UNEXPECTED) == 0) {
1367            list.calls[i].number = callInfo.number.replace(0, PHONE_CONTEXT_UNEXPECTED.length(),
1368                PHONE_CONTEXT_EXPECTED);
1369        }
1370    }
1371}
1372
1373void CellularCallHandler::ProcessImsPhoneNumber(ImsCurrentCallList &list)
1374{
1375    if (list.callSize == 0 || list.calls.empty()) {
1376        return;
1377    }
1378    for (uint64_t i = 0; i < list.calls.size(); i++) {
1379        ImsCurrentCall currentCall = list.calls[i];
1380        if (currentCall.number.length() <= PHONE_CONTEXT_UNEXPECTED.length()) {
1381            continue;
1382        }
1383        if (currentCall.number.compare(0, PHONE_CONTEXT_UNEXPECTED.length(), PHONE_CONTEXT_UNEXPECTED) == 0) {
1384            list.calls[i].number = currentCall.number.replace(0, PHONE_CONTEXT_UNEXPECTED.length(),
1385                PHONE_CONTEXT_EXPECTED);
1386        }
1387    }
1388}
1389
1390void CellularCallHandler::SetCallWaitingResponse(const AppExecFwk::InnerEvent::Pointer &event)
1391{
1392    auto result = event->GetSharedObject<SsBaseResult>();
1393    if (result == nullptr) {
1394        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
1395        return;
1396    }
1397    int32_t flag = SS_FROM_MMI_CODE;
1398    int32_t ret = ConfirmAndRemoveSsRequestCommand(result->index, flag);
1399    if (ret != TELEPHONY_SUCCESS) {
1400        return;
1401    }
1402    CellularCallSupplement supplement;
1403    if (result->result != TELEPHONY_SUCCESS) {
1404        result->result = TELEPHONY_ERR_RIL_CMD_FAIL;
1405    }
1406    supplement.EventSetCallWaiting(result->result, result->message, flag);
1407}
1408
1409void CellularCallHandler::GetClirResponse(const AppExecFwk::InnerEvent::Pointer &event)
1410{
1411    auto getClirResult = event->GetSharedObject<GetClirResult>();
1412    if (getClirResult == nullptr) {
1413        TELEPHONY_LOGE("[slot%{public}d] getClirResult is null", slotId_);
1414        return;
1415    }
1416    int32_t flag = SS_FROM_MMI_CODE;
1417    int32_t ret = ConfirmAndRemoveSsRequestCommand(getClirResult->result.index, flag);
1418    if (ret != TELEPHONY_SUCCESS) {
1419        return;
1420    }
1421    CellularCallSupplement supplement;
1422    supplement.EventGetClir(*getClirResult, getClirResult->result.message, flag);
1423}
1424
1425void CellularCallHandler::SetClirResponse(const AppExecFwk::InnerEvent::Pointer &event)
1426{
1427    auto result = event->GetSharedObject<SsBaseResult>();
1428    if (result == nullptr) {
1429        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
1430        return;
1431    }
1432    int32_t flag = SS_FROM_MMI_CODE;
1433    int32_t ret = ConfirmAndRemoveSsRequestCommand(result->index, flag);
1434    if (ret != TELEPHONY_SUCCESS) {
1435        return;
1436    }
1437    CellularCallSupplement supplement;
1438    supplement.EventSetClir(result->result, result->message, flag);
1439}
1440
1441void CellularCallHandler::GetClipResponse(const AppExecFwk::InnerEvent::Pointer &event)
1442{
1443    auto getClipResult = event->GetSharedObject<GetClipResult>();
1444    if (getClipResult == nullptr) {
1445        TELEPHONY_LOGE("[slot%{public}d] getClipResult is null", slotId_);
1446        return;
1447    }
1448    int32_t flag = SS_FROM_MMI_CODE;
1449    int32_t ret = ConfirmAndRemoveSsRequestCommand(getClipResult->result.index, flag);
1450    if (ret != TELEPHONY_SUCCESS) {
1451        return;
1452    }
1453    CellularCallSupplement supplement;
1454    supplement.EventGetClip(*getClipResult, getClipResult->result.message, flag);
1455}
1456
1457void CellularCallHandler::SetClipResponse(const AppExecFwk::InnerEvent::Pointer &event)
1458{
1459    auto result = event->GetSharedObject<SsBaseResult>();
1460    if (result == nullptr) {
1461        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
1462        return;
1463    }
1464    int32_t flag = SS_FROM_MMI_CODE;
1465    int32_t ret = ConfirmAndRemoveSsRequestCommand(result->index, flag);
1466    if (ret != TELEPHONY_SUCCESS) {
1467        return;
1468    }
1469    CellularCallSupplement supplement;
1470    supplement.EventSetClip(result->result, result->message, flag);
1471}
1472
1473void CellularCallHandler::GetColrResponse(const AppExecFwk::InnerEvent::Pointer &event)
1474{
1475    auto colrResult = event->GetSharedObject<GetColrResult>();
1476    if (colrResult == nullptr) {
1477        TELEPHONY_LOGE("[slot%{public}d] colrResult is null", slotId_);
1478        return;
1479    }
1480    int32_t flag = SS_FROM_MMI_CODE;
1481    int32_t ret = ConfirmAndRemoveSsRequestCommand(colrResult->result.index, flag);
1482    if (ret != TELEPHONY_SUCCESS) {
1483        return;
1484    }
1485    CellularCallSupplement supplement;
1486    supplement.EventGetColr(*colrResult, colrResult->result.message, flag);
1487}
1488
1489void CellularCallHandler::SetColrResponse(const AppExecFwk::InnerEvent::Pointer &event)
1490{
1491    auto result = event->GetSharedObject<SsBaseResult>();
1492    if (result == nullptr) {
1493        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
1494        return;
1495    }
1496    int32_t flag = SS_FROM_MMI_CODE;
1497    int32_t ret = ConfirmAndRemoveSsRequestCommand(result->index, flag);
1498    if (ret != TELEPHONY_SUCCESS) {
1499        return;
1500    }
1501    CellularCallSupplement supplement;
1502    supplement.EventSetColr(result->result, result->message, flag);
1503}
1504
1505void CellularCallHandler::GetColpResponse(const AppExecFwk::InnerEvent::Pointer &event)
1506{
1507    auto colpResult = event->GetSharedObject<GetColpResult>();
1508    if (colpResult == nullptr) {
1509        TELEPHONY_LOGE("[slot%{public}d] colpResult is null", slotId_);
1510        return;
1511    }
1512    int32_t flag = SS_FROM_MMI_CODE;
1513    int32_t ret = ConfirmAndRemoveSsRequestCommand(colpResult->result.index, flag);
1514    if (ret != TELEPHONY_SUCCESS) {
1515        return;
1516    }
1517    CellularCallSupplement supplement;
1518    supplement.EventGetColp(*colpResult, colpResult->result.message, flag);
1519}
1520
1521void CellularCallHandler::SetColpResponse(const AppExecFwk::InnerEvent::Pointer &event)
1522{
1523    auto result = event->GetSharedObject<SsBaseResult>();
1524    if (result == nullptr) {
1525        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
1526        return;
1527    }
1528    int32_t flag = SS_FROM_MMI_CODE;
1529    int32_t ret = ConfirmAndRemoveSsRequestCommand(result->index, flag);
1530    if (ret != TELEPHONY_SUCCESS) {
1531        return;
1532    }
1533    CellularCallSupplement supplement;
1534    supplement.EventSetColp(result->result, result->message, flag);
1535}
1536
1537void CellularCallHandler::GetCallTransferResponse(const AppExecFwk::InnerEvent::Pointer &event)
1538{
1539    auto cFQueryList = event->GetSharedObject<CallForwardQueryInfoList>();
1540    if (cFQueryList == nullptr) {
1541        TELEPHONY_LOGE("[slot%{public}d] cFQueryList is null", slotId_);
1542        return;
1543    }
1544    SsRequestCommand ss;
1545    int32_t ret = GetSsRequestCommand(cFQueryList->result.index, ss);
1546    if (ret == TELEPHONY_SUCCESS) {
1547        cFQueryList->result.reason = ss.cfReason;
1548    }
1549    int32_t flag = SS_FROM_MMI_CODE;
1550    ret = ConfirmAndRemoveSsRequestCommand(cFQueryList->result.index, flag);
1551    if (ret != TELEPHONY_SUCCESS) {
1552        return;
1553    }
1554    CellularCallSupplement supplement;
1555    supplement.EventGetCallTransferInfo(*cFQueryList, cFQueryList->result.message, flag);
1556}
1557
1558void CellularCallHandler::SetCallTransferInfoResponse(const AppExecFwk::InnerEvent::Pointer &event)
1559{
1560    auto result = event->GetSharedObject<SsBaseResult>();
1561    if (result == nullptr) {
1562        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
1563        return;
1564    }
1565    int32_t flag = SS_FROM_MMI_CODE;
1566    int32_t ret = ConfirmAndRemoveSsRequestCommand(result->index, flag);
1567    if (ret != TELEPHONY_SUCCESS) {
1568        return;
1569    }
1570    CellularCallSupplement supplement;
1571    CallForwardingInfo info;
1572    auto callHiSysEvent = DelayedSingleton<CellularCallHiSysEvent>::GetInstance();
1573    if (callHiSysEvent == nullptr) {
1574        TELEPHONY_LOGE("CellularCallHiSysEvent is null.");
1575        return;
1576    }
1577    callHiSysEvent->GetCallForwardingInfo(info);
1578    if (result->result == TELEPHONY_SUCCESS) {
1579        CoreManagerInner::GetInstance().SetVoiceCallForwarding(info.slotId, info.enable, info.number);
1580    } else {
1581        result->result = TELEPHONY_ERR_RIL_CMD_FAIL;
1582    }
1583    supplement.EventSetCallTransferInfo(result->result, result->message, flag);
1584}
1585
1586void CellularCallHandler::GetCallRestrictionResponse(const AppExecFwk::InnerEvent::Pointer &event)
1587{
1588    auto result = event->GetSharedObject<CallRestrictionResult>();
1589    if (result == nullptr) {
1590        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
1591        return;
1592    }
1593    int32_t flag = SS_FROM_MMI_CODE;
1594    int32_t ret = ConfirmAndRemoveSsRequestCommand(result->result.index, flag);
1595    if (ret != TELEPHONY_SUCCESS) {
1596        return;
1597    }
1598    CellularCallSupplement supplement;
1599    supplement.EventGetCallRestriction(*result, result->result.message, flag);
1600}
1601
1602void CellularCallHandler::SetCallRestrictionResponse(const AppExecFwk::InnerEvent::Pointer &event)
1603{
1604    auto result = event->GetSharedObject<SsBaseResult>();
1605    if (result == nullptr) {
1606        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
1607        return;
1608    }
1609    int32_t flag = SS_FROM_MMI_CODE;
1610    int32_t ret = ConfirmAndRemoveSsRequestCommand(result->index, flag);
1611    if (ret != TELEPHONY_SUCCESS) {
1612        return;
1613    }
1614    CellularCallSupplement supplement;
1615    if (result->result != TELEPHONY_SUCCESS) {
1616        result->result = TELEPHONY_ERR_RIL_CMD_FAIL;
1617    }
1618    supplement.EventSetCallRestriction(result->result, result->message, flag);
1619}
1620
1621void CellularCallHandler::SetBarringPasswordResponse(const AppExecFwk::InnerEvent::Pointer &event)
1622{
1623    auto result = event->GetSharedObject<SsBaseResult>();
1624    if (result == nullptr) {
1625        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
1626        return;
1627    }
1628    int32_t flag = SS_FROM_MMI_CODE;
1629    int32_t ret = ConfirmAndRemoveSsRequestCommand(result->index, flag);
1630    if (ret != TELEPHONY_SUCCESS) {
1631        return;
1632    }
1633    CellularCallSupplement supplement;
1634    if (result->result != TELEPHONY_SUCCESS) {
1635        result->result = TELEPHONY_ERR_RIL_CMD_FAIL;
1636    }
1637    supplement.EventSetBarringPassword(result->result, result->message, flag);
1638}
1639
1640void CellularCallHandler::SendUssdResponse(const AppExecFwk::InnerEvent::Pointer &event)
1641{
1642    auto result = event->GetSharedObject<RadioResponseInfo>();
1643    if (result == nullptr) {
1644        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
1645        return;
1646    }
1647    CellularCallSupplement supplement;
1648    supplement.EventSendUssd(*result);
1649}
1650
1651void CellularCallHandler::SsNotifyResponse(const AppExecFwk::InnerEvent::Pointer &event)
1652{
1653    auto result = event->GetSharedObject<SsNoticeInfo>();
1654    if (result == nullptr) {
1655        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
1656        return;
1657    }
1658    CellularCallSupplement supplement;
1659    supplement.EventSsNotify(*result);
1660}
1661
1662void CellularCallHandler::SendUnlockPinPukResponse(const AppExecFwk::InnerEvent::Pointer &event)
1663{
1664    auto result = event->GetSharedObject<PinPukResponse>();
1665    if (result == nullptr) {
1666        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
1667        return;
1668    }
1669    CellularCallSupplement supplement;
1670    supplement.EventSetPinPuk(*result);
1671}
1672
1673void CellularCallHandler::HandleOperatorConfigChanged(const AppExecFwk::InnerEvent::Pointer &event)
1674{
1675    CellularCallConfig config;
1676    config.HandleOperatorConfigChanged(slotId_);
1677}
1678
1679void CellularCallHandler::UpdateRsrvccStateReport(const AppExecFwk::InnerEvent::Pointer &event)
1680{
1681    isInCsRedial_ = true;
1682    auto serviceInstance = DelayedSingleton<CellularCallService>::GetInstance();
1683    if (serviceInstance == nullptr) {
1684        TELEPHONY_LOGE("[slot%{public}d] serviceInstance is null", slotId_);
1685        return;
1686    }
1687    serviceInstance->SetCsControl(slotId_, nullptr);
1688}
1689
1690void CellularCallHandler::RequestSsRequestCommandIndex(int32_t &index)
1691{
1692    if (indexCommand_ >= MAX_REQUEST_COUNT) {
1693        indexCommand_ = 0;
1694    } else {
1695        indexCommand_++;
1696    }
1697    index = indexCommand_;
1698}
1699
1700void CellularCallHandler::SaveSsRequestCommand(const std::shared_ptr<SsRequestCommand> &utCommand, int32_t index)
1701{
1702    if (utCommand == nullptr) {
1703        TELEPHONY_LOGE("[slot%{public}d] utCommand is null", slotId_);
1704        return;
1705    }
1706    int32_t indexCommand = indexCommand_;
1707    std::lock_guard<std::mutex> lock(mutex_);
1708    utCommandMap_.insert(std::make_pair(indexCommand, utCommand));
1709}
1710
1711int32_t CellularCallHandler::ConfirmAndRemoveSsRequestCommand(int32_t index, int32_t &flag)
1712{
1713    if (index == INVALID_INDEX) {
1714        // -1 mean this command index wasn't come from app, so don't need report result
1715        TELEPHONY_LOGI("[slot%{public}d] index is invalid, nothing need to do", slotId_);
1716        return TELEPHONY_ERROR;
1717    }
1718    std::lock_guard<std::mutex> lock(mutex_);
1719    auto itor = utCommandMap_.find(index);
1720    if (itor == utCommandMap_.end()) {
1721        TELEPHONY_LOGE("[slot%{public}d] the index(%{public}d) in utCommandMap_ haven't been found", slotId_, index);
1722        return TELEPHONY_ERROR;
1723    }
1724    flag = itor->second->flag;
1725    utCommandMap_.erase(index);
1726    return TELEPHONY_SUCCESS;
1727}
1728
1729int32_t CellularCallHandler::GetSsRequestCommand(int32_t index, SsRequestCommand &ss)
1730{
1731    std::lock_guard<std::mutex> lock(mutex_);
1732    auto itor = utCommandMap_.find(index);
1733    if (itor == utCommandMap_.end()) {
1734        TELEPHONY_LOGE("[slot%{public}d] the index in utCommandMap_ haven't been found", slotId_);
1735        return TELEPHONY_ERROR;
1736    }
1737
1738    ss.cfAction = itor->second->cfAction;
1739    ss.cfReason = itor->second->cfReason;
1740    ss.number = itor->second->number;
1741    ss.enable = itor->second->enable;
1742    ss.clirAction = itor->second->clirAction;
1743    ss.facility = itor->second->facility;
1744    if (strcpy_s(ss.password, sizeof(ss.password), itor->second->password) != EOK) {
1745        TELEPHONY_LOGE("password strcpy_s fail.");
1746        return TELEPHONY_ERR_STRCPY_FAIL;
1747    }
1748    ss.classType = itor->second->classType;
1749    ss.action = itor->second->action;
1750    ss.flag = itor->second->flag;
1751    return TELEPHONY_SUCCESS;
1752}
1753
1754void CellularCallHandler::CloseUnFinishedUssdResponse(const AppExecFwk::InnerEvent::Pointer &event)
1755{
1756    auto result = event->GetSharedObject<RadioResponseInfo>();
1757    if (result == nullptr) {
1758        TELEPHONY_LOGE("[slot%{public}d] result is null", slotId_);
1759        return;
1760    }
1761    CellularCallSupplement supplement;
1762    supplement.EventCloseUnFinishedUssd(*result);
1763}
1764
1765void CellularCallHandler::OnRilAdapterHostDied(const AppExecFwk::InnerEvent::Pointer &event)
1766{
1767    auto serviceInstance = DelayedSingleton<CellularCallService>::GetInstance();
1768    if (serviceInstance == nullptr) {
1769        TELEPHONY_LOGE("[slot%{public}d] serviceInstance is null", slotId_);
1770        return;
1771    }
1772    auto csControl = serviceInstance->GetCsControl(slotId_);
1773    if (csControl == nullptr) {
1774        TELEPHONY_LOGE("[slot%{public}d] cs_control is null", slotId_);
1775    } else if (csControl->ReportHangUpInfo(slotId_) != TELEPHONY_SUCCESS) {
1776        TELEPHONY_LOGE("[slot%{public}d] fail to disconnect cs calls", slotId_);
1777    } else {
1778        serviceInstance->SetCsControl(slotId_, nullptr);
1779    }
1780    auto imsControl = serviceInstance->GetImsControl(slotId_);
1781    if (imsControl == nullptr) {
1782        TELEPHONY_LOGE("[slot%{public}d] ims_control is null", slotId_);
1783    } else if (imsControl->ReportHangUpInfo(slotId_) != TELEPHONY_SUCCESS) {
1784        TELEPHONY_LOGE("[slot%{public}d] fail to disconnect ims calls", slotId_);
1785    } else {
1786        serviceInstance->SetImsControl(slotId_, nullptr);
1787    }
1788    auto satelliteControl = serviceInstance->GetSatelliteControl(slotId_);
1789    if (satelliteControl == nullptr) {
1790        TELEPHONY_LOGE("[slot%{public}d] satelliteControl is null", slotId_);
1791    } else if (satelliteControl->ReportHangUpInfo(slotId_) != TELEPHONY_SUCCESS) {
1792        TELEPHONY_LOGE("[slot%{public}d] fail to disconnect satellite calls", slotId_);
1793    } else {
1794        serviceInstance->SetSatelliteControl(slotId_, nullptr);
1795    }
1796}
1797
1798#ifdef CALL_MANAGER_AUTO_START_OPTIMIZE
1799void CellularCallHandler::StartCallManagerService()
1800{
1801    auto serviceInstance = DelayedSingleton<CellularCallService>::GetInstance();
1802    if (serviceInstance == nullptr) {
1803        TELEPHONY_LOGE("[slot%{public}d] serviceInstance is null", slotId_);
1804        return;
1805    }
1806    serviceInstance->StartCallManagerService();
1807}
1808
1809void CellularCallHandler::RadioStateChangeProcess(const AppExecFwk::InnerEvent::Pointer &event)
1810{
1811    std::shared_ptr<Int32Parcel> object = event->GetSharedObject<Int32Parcel>();
1812    if (object == nullptr) {
1813        TELEPHONY_LOGE("[slot%{public}d] object is null", slotId_);
1814        return;
1815    }
1816    TELEPHONY_LOGI("[slot%{public}d] Radio changed with state: %{public}d", slotId_, object->data);
1817    if (object->data == CORE_SERVICE_POWER_ON) {
1818        StartCallManagerService();
1819    }
1820}
1821
1822void CellularCallHandler::GetRadioStateProcess(const AppExecFwk::InnerEvent::Pointer &event)
1823{
1824    auto object = event->GetUniqueObject<RadioStateInfo>();
1825    if (object == nullptr) {
1826        TELEPHONY_LOGE("object is null");
1827        return;
1828    }
1829    TELEPHONY_LOGI("GetRadioStateProcess [slot%{public}d], state=%{public}d", slotId_, object->state);
1830    if (object->state == CORE_SERVICE_POWER_ON) {
1831        StartCallManagerService();
1832    }
1833}
1834#endif
1835
1836void CellularCallHandler::NvCfgFinishedIndication(const AppExecFwk::InnerEvent::Pointer &event)
1837{
1838    CellularCallConfig config;
1839    ModuleServiceUtils obtain;
1840    std::vector<int32_t> slotVector = obtain.GetSlotInfo();
1841    for (const auto &it : slotVector) {
1842        config.UpdateImsCapabilities(it, true);
1843    }
1844}
1845} // namespace Telephony
1846} // namespace OHOS
1847