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 "hril_call_parcel.h" 25 #include "mmi_code_utils.h" 26 27 namespace OHOS { 28 namespace Telephony { 29 class ControlBase { 30 public: 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 /** 198 * Ignore the hangup report when the hangup is caused by CallManager crash. 199 * 200 * @param ignored which decides whether to ignore the hangup report 201 */ 202 void SetHangupReportIgnoredFlag(bool ignored); 203 204 int32_t SetReadyToCall(int32_t slotId, bool isReadyToCall); 205 206 /** 207 * Determine whether the call can be initiated currently 208 * 209 * @param std::map<std::string, BaseConnection> 210 * @return Returns true can to call 211 */ 212 template<typename T> CanCall(T && t)213 bool CanCall(T &&t) 214 { 215 unsigned int maximumCalls = 6; 216 return t.size() <= maximumCalls; 217 } 218 219 /** 220 * FindConnectionByState 221 * 222 * @param std::map<std::string, BaseConnection> 223 * @param TelCallState 224 * @return pointer 225 */ 226 template<typename T1, typename T2> FindConnectionByState(const T1 && t1,TelCallState state)227 T2 FindConnectionByState(const T1 &&t1, TelCallState state) const 228 { 229 for (auto &it : t1) { 230 T2 pConnection = &it.second; 231 if (pConnection != nullptr && pConnection->GetStatus() == state) { 232 return pConnection; 233 } 234 } 235 return nullptr; 236 } 237 238 /** 239 * FindConnectionByIndex 240 * 241 * @param std::map<std::string, BaseConnection> 242 * @param index 243 * @return pointer 244 */ 245 template<typename T1, typename T2> FindConnectionByIndex(const T1 && t1,int32_t index)246 T2 FindConnectionByIndex(const T1 &&t1, int32_t index) const 247 { 248 for (auto &it : t1) { 249 T2 pConnection = &it.second; 250 if (pConnection != nullptr && pConnection->GetIndex() == index) { 251 return pConnection; 252 } 253 } 254 return nullptr; 255 } 256 257 /** 258 * SetConnectionData 259 * 260 * @param std::map<std::string, BaseConnection> 261 * @param string phoneNum 262 * @param BaseConnection 263 * @return bool 264 */ 265 template<typename T1, typename T2> SetConnectionData(T1 && t1,const int32_t & key,const T2 & con)266 bool SetConnectionData(T1 &&t1, const int32_t &key, const T2 &con) 267 { 268 if (!t1.insert(std::make_pair(key, con)).second) { 269 TELEPHONY_LOGE("SetConnectionData, key already exists."); 270 return false; 271 } 272 return true; 273 } 274 275 /** 276 * Determines if a connection is currently in this state 277 * 278 * @param std::map<std::string, BaseConnection> 279 * @param TelCallState 280 * @return Returns true or false 281 */ 282 template<typename T1> IsInState(T1 && t,TelCallState state)283 bool IsInState(T1 &&t, TelCallState state) 284 { 285 for (const auto &it : t) { 286 auto pConnection = &it.second; 287 if (pConnection != nullptr && pConnection->GetStatus() == state) { 288 return true; 289 } 290 } 291 return false; 292 } 293 294 /** 295 * StartDtmf 296 * 297 * 23014-400_2001 6 Support of DTMF across the air interface 298 * 3GPP TS 22.030 299 * 300 * START DTMF : Containing the digit value (0-9,A,B,C,D,*,#) 301 * @param std::map<std::string, BaseConnection> 302 * @param Dtmf Code 303 * @param CellularCallInfo 304 * @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 305 */ 306 template<typename T> StartDtmf(T && t,char cDtmfCode,const CellularCallInfo & callInfo)307 int32_t StartDtmf(T &&t, char cDtmfCode, const CellularCallInfo &callInfo) const 308 { 309 /** 310 * The messages when sent across the air interface should contain the following information: 311 * a) START DTMF : Containing the digit value (0-9,A,B,C,D,*,#); 312 * b) START DTMF ACKNOWLEDGE: Containing the digit value (0-9,A,B,C,D,*,#) corresponding to the DTMF tone that 313 * the network applies towards the remote user; 314 * c) STOP DTMF : No further info; 315 * d) STOP DTMF ACKNOWLEDGE: No further info. 316 * Only a single digit will be passed in each START DTMF and START DTMF ACKNOWLEDGE message 317 */ 318 TELEPHONY_LOGD("ControlBase::StartDtmf start"); 319 auto pConnection = FindConnectionByIndex<T &, decltype(&t.begin()->second)>(t, callInfo.index); 320 321 if (pConnection == nullptr) { 322 TELEPHONY_LOGE("StartDtmf, error type: connection is null"); 323 return CALL_ERR_CALL_CONNECTION_NOT_EXIST; 324 } 325 if (!IsDtmfKey(cDtmfCode)) { 326 TELEPHONY_LOGE("StartDtmf return, error type: cDtmfCode invalid."); 327 return CALL_ERR_PARAMETER_OUT_OF_RANGE; 328 } 329 return pConnection->StartDtmfRequest(callInfo.slotId, cDtmfCode, pConnection->GetIndex()); 330 } 331 332 /** 333 * StopDtmf 334 * 335 * 23014-400_2001 6 Support of DTMF across the air interface 336 * 3GPP TS 22.030 337 * 338 * STOP DTMF : No further info 339 * @param std::map<std::string, BaseConnection> 340 * @param CellularCallInfo 341 * @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 342 */ 343 template<typename T> StopDtmf(T && t,const CellularCallInfo & callInfo)344 int32_t StopDtmf(T &&t, const CellularCallInfo &callInfo) const 345 { 346 /** 347 * The messages when sent across the air interface should contain the following information: 348 * a) START DTMF : Containing the digit value (0-9,A,B,C,D,*,#); 349 * b) START DTMF ACKNOWLEDGE: Containing the digit value (0-9,A,B,C,D,*,#) corresponding to the DTMF tone that 350 * the network applies towards the remote user; 351 * c) STOP DTMF : No further info; 352 * d) STOP DTMF ACKNOWLEDGE: No further info. 353 * Only a single digit will be passed in each START DTMF and START DTMF ACKNOWLEDGE message 354 */ 355 TELEPHONY_LOGD("ControlBase::StopDtmf start"); 356 auto pConnection = FindConnectionByIndex<T &, decltype(&t.begin()->second)>(t, callInfo.index); 357 if (pConnection == nullptr) { 358 TELEPHONY_LOGE("StopDtmf, error type: connection is null"); 359 return CALL_ERR_CALL_CONNECTION_NOT_EXIST; 360 } 361 return pConnection->StopDtmfRequest(callInfo.slotId, pConnection->GetIndex()); 362 } 363 364 /** 365 * SendDtmf 366 * 367 * 23014-400_2001 6 Support of DTMF across the air interface 368 * 3GPP TS 22.030 369 * 370 * @param std::map<std::string, BaseConnection> 371 * @param Dtmf Code 372 * @param CellularCallInfo 373 * @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 374 */ 375 template<typename T> SendDtmf(T && t,char cDtmfCode,const CellularCallInfo & callInfo)376 int32_t SendDtmf(T &&t, char cDtmfCode, const CellularCallInfo &callInfo) const 377 { 378 /** 379 * 3gpp 27007-430_2001 380 * 381 * C.2.11 DTMF and tone generation +VTS 382 * 383 * This command allows the transmission of DTMF tones and arbitrary tones (see note). 384 * These tones may be used (for example) when announcing the start of a recording period. 385 * The command is write only. 386 * In this profile of commands, this command does not operate in data or fax modes of operation (+FCLASS=0,1,2 387 7). NOTE 1: D is used only for dialling. 388 389 The string parameter of the command consists of combinations of the following separated by commas: 390 1. <DTMF>. A single ASCII character in the set 0 9, #,*,A D. 391 This is interpreted as a single ACSII character whose duration is set by the +VTD command. 392 NOTE 2: In GSM this operates only in voice mode. 393 2. [<tone1>,<tone2>,<duration>]. 394 This is interpreted as a dual tone of frequencies <tone1> and <tone2>, lasting for a time <duration> (in 10 395 ms multiples). NOTE 3: This does not operate in GSM. 396 3. {<DTMF>,<duration>}. This is interpreted as a DTMF tone of different duration from that mandated by the 397 +VTD command. NOTE 4: In GSM this operates only in voice mode. 398 */ 399 TELEPHONY_LOGD("ControlBase::SendDtmf start"); 400 auto pConnection = FindConnectionByIndex<T &, decltype(&t.begin()->second)>(t, callInfo.index); 401 if (pConnection == nullptr) { 402 TELEPHONY_LOGE("SendDtmf, error type: connection is null"); 403 return CALL_ERR_CALL_CONNECTION_NOT_EXIST; 404 } 405 if (!IsDtmfKey(cDtmfCode)) { 406 TELEPHONY_LOGE("SendDtmf return, error type: cDtmfCode invalid."); 407 return CALL_ERR_PARAMETER_OUT_OF_RANGE; 408 } 409 return pConnection->SendDtmfRequest(callInfo.slotId, cDtmfCode, pConnection->GetIndex()); 410 } 411 412 /** 413 * GetCallFailReason 414 * 415 * 3GPP TS 24.008 V17.4.0 (2021-09) 10.5.4.11 Cause 416 * 417 * @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 418 */ 419 template<typename T> GetCallFailReason(int32_t slotId,T && t)420 int32_t GetCallFailReason(int32_t slotId, T &&t) const 421 { 422 decltype(t.begin()->second) connection; 423 return connection.GetCallFailReasonRequest(slotId); 424 } 425 426 protected: 427 bool isIgnoredHangupReport_ = false; 428 bool isIgnoredIncomingCall_ = false; 429 430 private: 431 /** 432 * Check call with airplane mode on 433 */ 434 int32_t CheckAirplaneModeScene(const CellularCallInfo &callInfo, bool isEcc); 435 436 /** 437 * Handle call with airplane mode on 438 */ 439 int32_t HandleEcc(const CellularCallInfo &callInfo, bool isEcc); 440 441 private: 442 std::shared_ptr<AppExecFwk::EventRunner> eventLoop_; 443 std::condition_variable cv_; 444 std::mutex mutex_; 445 }; 446 } // namespace Telephony 447 } // namespace OHOS 448 449 #endif // CELLULAR_CALL_CONTROL_BASE_H 450