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#ifndef CELLULAR_CALL_CONTROL_BASE_H 17#define CELLULAR_CALL_CONTROL_BASE_H 18 19#include "call_manager_errors.h" 20#include "event_handler.h" 21#include "cellular_call_data_struct.h" 22#include "telephony_log_wrapper.h" 23#include "base_connection.h" 24#include "tel_ril_call_parcel.h" 25#include "mmi_code_utils.h" 26 27namespace OHOS { 28namespace Telephony { 29class ControlBase { 30public: 31 /** 32 * constructor 33 */ 34 ControlBase() = default; 35 36 /** 37 * destructor 38 */ 39 virtual ~ControlBase() = default; 40 41 /** 42 * Dial 43 * 44 * 27007-430_2001 6.27 Informative examples 45 * 3GPP TS 22.030 [19] 46 * 47 * originate a voice call 48 * 49 * @param CellularCallInfo 50 * @param bool 51 * @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 52 */ 53 virtual int32_t Dial(const CellularCallInfo &callInfo, bool isEcc) = 0; 54 55 /** 56 * HangUp 57 * 58 * 3GPP TS 27.007 V3.9.0 (2001-06) Call related supplementary services +CHLD 59 * 3GPP TS 27.007 V3.9.0 (2001-06) 7.22 Informative examples 60 * 3GPP TS 22.030 [19] 61 * 62 * release call 63 * 64 * @param CellularCallInfo 65 * @param CallSupplementType 66 * @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 67 */ 68 virtual int32_t HangUp(const CellularCallInfo &callInfo, CallSupplementType type) = 0; 69 70 /** 71 * Answer 72 * 73 * 27007-430_2001 6.6 Alternating mode call control method 74 * 3GPP TS 22.030 [19] 75 * 76 * Answer an incoming voice call. 77 * 78 * @param CellularCallInfo 79 * @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 80 */ 81 virtual int32_t Answer(const CellularCallInfo &callInfo) = 0; 82 83 /** 84 * Reject 85 * 86 * 27007-430_2001 6.6 Alternating mode call control method 87 * 3GPP TS 22.030 [19] 88 * 89 * Reject an incoming voice call 90 * 91 * @param CellularCallInfo 92 * @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 93 */ 94 virtual int32_t Reject(const CellularCallInfo &callInfo) = 0; 95 96 /** 97 * HoldCall 98 * 99 * 22083-400_2001 2 Call hold 100 * 3GPP TS 22.030 [3] 101 * 3GPP TS 23.083 V4.2.0 (2001-04) 2 Call hold (HOLD) 102 * 103 * The call hold service allows a served mobile subscriber 104 * 105 * @param slotId 106 * @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 107 */ 108 virtual int32_t HoldCall(int32_t slotId) = 0; 109 110 /** 111 * UnHoldCall 112 * 113 * 22083-400_2001 2 Call hold 114 * 3GPP TS 22.030 [3] 115 * 116 * Retrieve the held call. 117 * 118 * @param slotId 119 * @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 120 */ 121 virtual int32_t UnHoldCall(int32_t slotId) = 0; 122 123 /** 124 * SwitchCall 125 * 126 * 22083-400_2001 2 Call hold 127 * 3GPP TS 22.030 [3] 128 * 129 * Alternate from one call to the other 130 * 131 * @param slotId 132 * @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 133 */ 134 virtual int32_t SwitchCall(int32_t slotId) = 0; 135 136 /** 137 * CombineConference 138 * 139 * 22084-400_2001 1.3.8.2 Managing an active multiParty call 140 * 3GPP TS 22.030 141 * 142 * Add another remote party 143 * @param slotId 144 * @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 145 */ 146 virtual int32_t CombineConference(int32_t slotId) = 0; 147 148 /** 149 * HangUpAllConnection 150 * 151 * @param slotId 152 * @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 153 */ 154 virtual int32_t HangUpAllConnection(int32_t slotId) = 0; 155 156 /** 157 * ReportCallsData 158 * 159 * @param slotId 160 * @param CallInfoList 161 * @returns Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 162 */ 163 virtual int32_t ReportCallsData(int32_t slotId, const CallInfoList &callInfoList) = 0; 164 165 /** 166 * Dial PreJudgment 167 * 168 * @param CellularCallInfo 169 * @returns Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 170 */ 171 int32_t DialPreJudgment(const CellularCallInfo &callInfo, bool isEcc); 172 173 /** 174 * Is Need Execute MMI 175 * 176 * @param slotId 177 * @param std::string phoneString 178 * @param CLIRMode 179 * @param isNeedUseIms 180 * @returns bool 181 */ 182 bool IsNeedExecuteMMI(int32_t slotId, std::string &phoneString, CLIRMode &clirMode, bool isNeedUseIms); 183 184 /** 185 * Is Dtmf Key 186 * 187 * 23014-400_2001 6 Support of DTMF across the air interface 188 * 3GPP TS 22.030 189 * 190 * @param char 191 * @returns bool 192 */ 193 bool IsDtmfKey(char c) const; 194 195 bool IsConnectedOut(TelCallState preState, TelCallState curState); 196 197 int32_t SetReadyToCall(int32_t slotId, bool isReadyToCall); 198 199 /** 200 * Determine whether the call can be initiated currently 201 * 202 * @param std::map<std::string, BaseConnection> 203 * @return Returns true can to call 204 */ 205 template<typename T> 206 bool CanCall(T &&t) 207 { 208 unsigned int maximumCalls = 6; 209 return t.size() <= maximumCalls; 210 } 211 212 /** 213 * FindConnectionByState 214 * 215 * @param std::map<std::string, BaseConnection> 216 * @param TelCallState 217 * @return pointer 218 */ 219 template<typename T1, typename T2> 220 T2 FindConnectionByState(const T1 &&t1, TelCallState state) const 221 { 222 for (auto &it : t1) { 223 T2 pConnection = &it.second; 224 if (pConnection != nullptr && pConnection->GetStatus() == state) { 225 return pConnection; 226 } 227 } 228 return nullptr; 229 } 230 231 /** 232 * FindConnectionByIndex 233 * 234 * @param std::map<std::string, BaseConnection> 235 * @param index 236 * @return pointer 237 */ 238 template<typename T1, typename T2> 239 T2 FindConnectionByIndex(const T1 &&t1, int32_t index) const 240 { 241 for (auto &it : t1) { 242 T2 pConnection = &it.second; 243 if (pConnection != nullptr && pConnection->GetIndex() == index) { 244 return pConnection; 245 } 246 } 247 return nullptr; 248 } 249 250 /** 251 * SetConnectionData 252 * 253 * @param std::map<std::string, BaseConnection> 254 * @param string phoneNum 255 * @param BaseConnection 256 * @return bool 257 */ 258 template<typename T1, typename T2> 259 bool SetConnectionData(T1 &&t1, const int32_t &key, const T2 &con) 260 { 261 if (!t1.insert(std::make_pair(key, con)).second) { 262 TELEPHONY_LOGE("SetConnectionData, key already exists."); 263 return false; 264 } 265 return true; 266 } 267 268 /** 269 * Determines if a connection is currently in this state 270 * 271 * @param std::map<std::string, BaseConnection> 272 * @param TelCallState 273 * @return Returns true or false 274 */ 275 template<typename T1> 276 bool IsInState(T1 &&t, TelCallState state) 277 { 278 for (const auto &it : t) { 279 auto pConnection = &it.second; 280 if (pConnection != nullptr && pConnection->GetStatus() == state) { 281 return true; 282 } 283 } 284 return false; 285 } 286 287 /** 288 * StartDtmf 289 * 290 * 23014-400_2001 6 Support of DTMF across the air interface 291 * 3GPP TS 22.030 292 * 293 * START DTMF : Containing the digit value (0-9,A,B,C,D,*,#) 294 * @param std::map<std::string, BaseConnection> 295 * @param Dtmf Code 296 * @param CellularCallInfo 297 * @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 298 */ 299 template<typename T> 300 int32_t StartDtmf(T &&t, char cDtmfCode, const CellularCallInfo &callInfo) const 301 { 302 /** 303 * The messages when sent across the air interface should contain the following information: 304 * a) START DTMF : Containing the digit value (0-9,A,B,C,D,*,#); 305 * b) START DTMF ACKNOWLEDGE: Containing the digit value (0-9,A,B,C,D,*,#) corresponding to the DTMF tone that 306 * the network applies towards the remote user; 307 * c) STOP DTMF : No further info; 308 * d) STOP DTMF ACKNOWLEDGE: No further info. 309 * Only a single digit will be passed in each START DTMF and START DTMF ACKNOWLEDGE message 310 */ 311 TELEPHONY_LOGD("ControlBase::StartDtmf start"); 312 auto pConnection = FindConnectionByIndex<T &, decltype(&t.begin()->second)>(t, callInfo.index); 313 314 if (pConnection == nullptr) { 315 TELEPHONY_LOGE("StartDtmf, error type: connection is null"); 316 return CALL_ERR_CALL_CONNECTION_NOT_EXIST; 317 } 318 if (!IsDtmfKey(cDtmfCode)) { 319 TELEPHONY_LOGE("StartDtmf return, error type: cDtmfCode invalid."); 320 return CALL_ERR_PARAMETER_OUT_OF_RANGE; 321 } 322 return pConnection->StartDtmfRequest(callInfo.slotId, cDtmfCode, pConnection->GetIndex()); 323 } 324 325 /** 326 * StopDtmf 327 * 328 * 23014-400_2001 6 Support of DTMF across the air interface 329 * 3GPP TS 22.030 330 * 331 * STOP DTMF : No further info 332 * @param std::map<std::string, BaseConnection> 333 * @param CellularCallInfo 334 * @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 335 */ 336 template<typename T> 337 int32_t StopDtmf(T &&t, const CellularCallInfo &callInfo) const 338 { 339 /** 340 * The messages when sent across the air interface should contain the following information: 341 * a) START DTMF : Containing the digit value (0-9,A,B,C,D,*,#); 342 * b) START DTMF ACKNOWLEDGE: Containing the digit value (0-9,A,B,C,D,*,#) corresponding to the DTMF tone that 343 * the network applies towards the remote user; 344 * c) STOP DTMF : No further info; 345 * d) STOP DTMF ACKNOWLEDGE: No further info. 346 * Only a single digit will be passed in each START DTMF and START DTMF ACKNOWLEDGE message 347 */ 348 TELEPHONY_LOGD("ControlBase::StopDtmf start"); 349 auto pConnection = FindConnectionByIndex<T &, decltype(&t.begin()->second)>(t, callInfo.index); 350 if (pConnection == nullptr) { 351 TELEPHONY_LOGE("StopDtmf, error type: connection is null"); 352 return CALL_ERR_CALL_CONNECTION_NOT_EXIST; 353 } 354 return pConnection->StopDtmfRequest(callInfo.slotId, pConnection->GetIndex()); 355 } 356 357 /** 358 * SendDtmf 359 * 360 * 23014-400_2001 6 Support of DTMF across the air interface 361 * 3GPP TS 22.030 362 * 363 * @param std::map<std::string, BaseConnection> 364 * @param Dtmf Code 365 * @param CellularCallInfo 366 * @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 367 */ 368 template<typename T> 369 int32_t SendDtmf(T &&t, char cDtmfCode, const CellularCallInfo &callInfo) const 370 { 371 /** 372 * 3gpp 27007-430_2001 373 * 374 * C.2.11 DTMF and tone generation +VTS 375 * 376 * This command allows the transmission of DTMF tones and arbitrary tones (see note). 377 * These tones may be used (for example) when announcing the start of a recording period. 378 * The command is write only. 379 * In this profile of commands, this command does not operate in data or fax modes of operation (+FCLASS=0,1,2 380 7). NOTE 1: D is used only for dialling. 381 382 The string parameter of the command consists of combinations of the following separated by commas: 383 1. <DTMF>. A single ASCII character in the set 0 9, #,*,A D. 384 This is interpreted as a single ACSII character whose duration is set by the +VTD command. 385 NOTE 2: In GSM this operates only in voice mode. 386 2. [<tone1>,<tone2>,<duration>]. 387 This is interpreted as a dual tone of frequencies <tone1> and <tone2>, lasting for a time <duration> (in 10 388 ms multiples). NOTE 3: This does not operate in GSM. 389 3. {<DTMF>,<duration>}. This is interpreted as a DTMF tone of different duration from that mandated by the 390 +VTD command. NOTE 4: In GSM this operates only in voice mode. 391 */ 392 TELEPHONY_LOGD("ControlBase::SendDtmf start"); 393 auto pConnection = FindConnectionByIndex<T &, decltype(&t.begin()->second)>(t, callInfo.index); 394 if (pConnection == nullptr) { 395 TELEPHONY_LOGE("SendDtmf, error type: connection is null"); 396 return CALL_ERR_CALL_CONNECTION_NOT_EXIST; 397 } 398 if (!IsDtmfKey(cDtmfCode)) { 399 TELEPHONY_LOGE("SendDtmf return, error type: cDtmfCode invalid."); 400 return CALL_ERR_PARAMETER_OUT_OF_RANGE; 401 } 402 return pConnection->SendDtmfRequest(callInfo.slotId, cDtmfCode, pConnection->GetIndex()); 403 } 404 405 /** 406 * GetCallFailReason 407 * 408 * 3GPP TS 24.008 V17.4.0 (2021-09) 10.5.4.11 Cause 409 * 410 * @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 411 */ 412 template<typename T> 413 int32_t GetCallFailReason(int32_t slotId, T &&t) const 414 { 415 decltype(t.begin()->second) connection; 416 return connection.GetCallFailReasonRequest(slotId); 417 } 418 419protected: 420 bool isIgnoredIncomingCall_ = false; 421 422private: 423 /** 424 * Check call with airplane mode on 425 */ 426 bool CheckAirplaneModeScene(const CellularCallInfo &callInfo); 427 428 /** 429 * check call with activate sim 430 */ 431 bool CheckActivateSimScene(int32_t slotId); 432 433 /** 434 * Handle call with airplane mode on 435 */ 436 int32_t HandleEcc(const CellularCallInfo &callInfo, bool isEcc, bool isAirplaneModeOn, bool isActivateSim); 437 438private: 439 std::shared_ptr<AppExecFwk::EventRunner> eventLoop_; 440 std::condition_variable cv_; 441 std::mutex mutex_; 442}; 443} // namespace Telephony 444} // namespace OHOS 445 446#endif // CELLULAR_CALL_CONTROL_BASE_H 447