• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "control_base.h"
17 
18 #include "cellular_call_config.h"
19 #include "cellular_call_hisysevent.h"
20 #include "cellular_call_service.h"
21 #include "module_service_utils.h"
22 #include "standardize_utils.h"
23 
24 namespace OHOS {
25 namespace Telephony {
26 const uint32_t WAIT_TIME_SECOND = 5;
27 
DialPreJudgment(const CellularCallInfo & callInfo,bool isEcc)28 int32_t ControlBase::DialPreJudgment(const CellularCallInfo &callInfo, bool isEcc)
29 {
30     int32_t ret = CheckAirplaneModeScene(callInfo, isEcc);
31     if (ret != TELEPHONY_SUCCESS) {
32         TELEPHONY_LOGE("CheckAirplaneModeScene fail");
33         return ret;
34     }
35     std::string dialString(callInfo.phoneNum);
36     if (dialString.empty()) {
37         TELEPHONY_LOGE("DialPreJudgment return, dialString is empty.");
38         CellularCallHiSysEvent::WriteDialCallFaultEvent(callInfo.accountId, static_cast<int32_t>(callInfo.callType),
39             callInfo.videoState, CALL_ERR_PHONE_NUMBER_EMPTY, "dialString is empty");
40         return CALL_ERR_PHONE_NUMBER_EMPTY;
41     }
42 
43     ModuleServiceUtils moduleServiceUtils;
44     if (!moduleServiceUtils.GetRadioState(callInfo.slotId)) {
45         TELEPHONY_LOGE("DialPreJudgment return, radio state error.");
46         CellularCallHiSysEvent::WriteDialCallFaultEvent(callInfo.accountId, static_cast<int32_t>(callInfo.callType),
47             callInfo.videoState, CALL_ERR_GET_RADIO_STATE_FAILED, "radio state error");
48         return CALL_ERR_GET_RADIO_STATE_FAILED;
49     }
50     return TELEPHONY_SUCCESS;
51 }
52 
IsNeedExecuteMMI(int32_t slotId,std::string & phoneString,CLIRMode & clirMode,bool isNeedUseIms)53 bool ControlBase::IsNeedExecuteMMI(int32_t slotId, std::string &phoneString, CLIRMode &clirMode, bool isNeedUseIms)
54 {
55     TELEPHONY_LOGI("IsNeedExecuteMMI start");
56     // Also supplementary services may be controlled using dial command according to 3GPP TS 22.030 [19].
57     // An example of call forwarding on no reply for telephony with the adjustment of the
58     // no reply condition timer on 25 seconds:
59     // Parse the MMI code from the string
60     std::unique_ptr<MMICodeUtils> mmiCodeUtils = std::make_unique<MMICodeUtils>();
61     // Parse the MMI code from the string
62     if (mmiCodeUtils == nullptr) {
63         TELEPHONY_LOGE("IsNeedExecuteMMI return, mmiCodeUtils is nullptr");
64         return false;
65     }
66     if (!mmiCodeUtils->IsNeedExecuteMmi(phoneString, isNeedUseIms)) {
67         TELEPHONY_LOGI("IsNeedExecuteMMI return, isn't need to execute mmi");
68         return false;
69     }
70     if (mmiCodeUtils->GetMMIData().serviceCode == "30" && !mmiCodeUtils->GetMMIData().dialString.empty()) {
71         TELEPHONY_LOGI("IsNeedExecuteMMI, handle additional CLIR mode");
72         if (mmiCodeUtils->GetMMIData().actionString == "*") {
73             phoneString = mmiCodeUtils->GetMMIData().dialString;
74             clirMode = CLIRMode::TRANSFER;
75             return false;
76         } else if (mmiCodeUtils->GetMMIData().actionString == "#") {
77             phoneString = mmiCodeUtils->GetMMIData().dialString;
78             clirMode = CLIRMode::INHIBITION;
79             return false;
80         }
81     }
82     if (DelayedSingleton<CellularCallService>::GetInstance() == nullptr) {
83         TELEPHONY_LOGI("IsNeedExecuteMMI return, GetInstance is nullptr");
84         return false;
85     }
86     if (DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId) == nullptr) {
87         TELEPHONY_LOGI("IsNeedExecuteMMI return, GetHandler is nullptr");
88         return false;
89     }
90     return DelayedSingleton<CellularCallService>::GetInstance()->GetHandler(slotId)->SendEvent(
91         MMIHandlerId::EVENT_MMI_Id, mmiCodeUtils);
92 }
93 
IsDtmfKey(char c) const94 bool ControlBase::IsDtmfKey(char c) const
95 {
96     /**
97      * 1. <DTMF>. A single ASCII character in the set 0 9, #,*,A D. This is interpreted as a single ASCII character
98      * whose duration is set by the +VTD command. NOTE 2:	In GSM this operates only in voice mode.
99      */
100     return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'D') || c == '*' || c == '#';
101 }
102 
IsConnectedOut(TelCallState preState,TelCallState curState)103 bool ControlBase::IsConnectedOut(TelCallState preState, TelCallState curState)
104 {
105     if ((preState == TelCallState::CALL_STATUS_DIALING || preState == TelCallState::CALL_STATUS_ALERTING) &&
106         !(curState == TelCallState::CALL_STATUS_DIALING || curState == TelCallState::CALL_STATUS_ALERTING)) {
107         return true;
108     }
109     return false;
110 }
111 
SetHangupReportIgnoredFlag(bool ignored)112 void ControlBase::SetHangupReportIgnoredFlag(bool ignored)
113 {
114     TELEPHONY_LOGI("SetHangupReportIgnoredFlag ignored:%{public}d", ignored);
115     isIgnoredHangupReport_ = ignored;
116 }
117 
CheckAirplaneModeScene(const CellularCallInfo & callInfo,bool isEcc)118 int32_t ControlBase::CheckAirplaneModeScene(const CellularCallInfo &callInfo, bool isEcc)
119 {
120     bool isAirplaneModeOn = false;
121     ModuleServiceUtils moduleServiceUtils;
122     if (moduleServiceUtils.GetAirplaneMode(isAirplaneModeOn) == TELEPHONY_SUCCESS && isAirplaneModeOn) {
123         int32_t ret = HandleEcc(callInfo, isEcc);
124         if (ret != TELEPHONY_SUCCESS) {
125             TELEPHONY_LOGE("HandleEcc fail");
126             return ret;
127         }
128     }
129     return TELEPHONY_SUCCESS;
130 }
131 
HandleEcc(const CellularCallInfo & callInfo,bool isEcc)132 int32_t ControlBase::HandleEcc(const CellularCallInfo &callInfo, bool isEcc)
133 {
134     if (!isEcc) {
135         TELEPHONY_LOGE("HandleEcc airplane mode is not ecc");
136         return TELEPHONY_ERR_AIRPLANE_MODE_ON;
137     }
138 
139     ModuleServiceUtils moduleServiceUtils;
140     int32_t ret = moduleServiceUtils.UpdateRadioOn(callInfo.slotId);
141     if (ret != TELEPHONY_SUCCESS) {
142         TELEPHONY_LOGE("UpdateRadioOn fail");
143         return ret;
144     }
145     std::unique_lock<std::mutex> lock(mutex_);
146     CellularCallConfig cellularCallConfig;
147     while (!cellularCallConfig.IsReadyToCall(callInfo.slotId)) {
148         if (cv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
149             TELEPHONY_LOGE("HandleEcc network in service timeout");
150             return CALL_ERR_DIAL_FAILED;
151         }
152     }
153 
154     return TELEPHONY_SUCCESS;
155 }
156 
SetReadyToCall(int32_t slotId,bool isReadyToCall)157 int32_t ControlBase::SetReadyToCall(int32_t slotId, bool isReadyToCall)
158 {
159     CellularCallConfig cellularCallConfig;
160     if (!cellularCallConfig.IsReadyToCall(slotId) && isReadyToCall) {
161         cellularCallConfig.SetReadyToCall(slotId, isReadyToCall);
162         cv_.notify_all();
163     }
164     return TELEPHONY_SUCCESS;
165 }
166 } // namespace Telephony
167 } // namespace OHOS
168