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 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 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> CanCall(T && 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> FindConnectionByState(const T1 && t1,TelCallState state)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> FindConnectionByIndex(const T1 && t1,int32_t index)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> SetConnectionData(T1 && t1,const int32_t & key,const T2 & con)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> IsInState(T1 && t,TelCallState state)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> StartDtmf(T && t,char cDtmfCode,const CellularCallInfo & callInfo)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 if (pConnection == nullptr) { 314 TELEPHONY_LOGE("StartDtmf, error type: connection is null"); 315 return CALL_ERR_CALL_CONNECTION_NOT_EXIST; 316 } 317 if (!IsDtmfKey(cDtmfCode)) { 318 TELEPHONY_LOGE("StartDtmf return, error type: cDtmfCode invalid."); 319 return CALL_ERR_PARAMETER_OUT_OF_RANGE; 320 } 321 return pConnection->StartDtmfRequest(callInfo.slotId, cDtmfCode, pConnection->GetIndex()); 322 } 323 324 /** 325 * StopDtmf 326 * 327 * 23014-400_2001 6 Support of DTMF across the air interface 328 * 3GPP TS 22.030 329 * 330 * STOP DTMF : No further info 331 * @param std::map<std::string, BaseConnection> 332 * @param CellularCallInfo 333 * @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 334 */ 335 template<typename T> StopDtmf(T && t,const CellularCallInfo & callInfo)336 int32_t StopDtmf(T &&t, const CellularCallInfo &callInfo) const 337 { 338 /** 339 * The messages when sent across the air interface should contain the following information: 340 * a) START DTMF : Containing the digit value (0-9,A,B,C,D,*,#); 341 * b) START DTMF ACKNOWLEDGE: Containing the digit value (0-9,A,B,C,D,*,#) corresponding to the DTMF tone that 342 * the network applies towards the remote user; 343 * c) STOP DTMF : No further info; 344 * d) STOP DTMF ACKNOWLEDGE: No further info. 345 * Only a single digit will be passed in each START DTMF and START DTMF ACKNOWLEDGE message 346 */ 347 TELEPHONY_LOGD("ControlBase::StopDtmf start"); 348 auto pConnection = FindConnectionByIndex<T &, decltype(&t.begin()->second)>(t, callInfo.index); 349 if (pConnection == nullptr) { 350 TELEPHONY_LOGE("StopDtmf, error type: connection is null"); 351 return CALL_ERR_CALL_CONNECTION_NOT_EXIST; 352 } 353 return pConnection->StopDtmfRequest(callInfo.slotId, pConnection->GetIndex()); 354 } 355 356 /** 357 * SendDtmf 358 * 359 * 23014-400_2001 6 Support of DTMF across the air interface 360 * 3GPP TS 22.030 361 * 362 * @param std::map<std::string, BaseConnection> 363 * @param Dtmf Code 364 * @param CellularCallInfo 365 * @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 366 */ 367 template<typename T> SendDtmf(T && t,char cDtmfCode,const CellularCallInfo & callInfo)368 int32_t SendDtmf(T &&t, char cDtmfCode, const CellularCallInfo &callInfo) const 369 { 370 /** 371 * 3gpp 27007-430_2001 372 * 373 * C.2.11 DTMF and tone generation +VTS 374 * 375 * This command allows the transmission of DTMF tones and arbitrary tones (see note). 376 * These tones may be used (for example) when announcing the start of a recording period. 377 * The command is write only. 378 * In this profile of commands, this command does not operate in data or fax modes of operation (+FCLASS=0,1,2 379 7). NOTE 1: D is used only for dialling. 380 381 The string parameter of the command consists of combinations of the following separated by commas: 382 1. <DTMF>. A single ASCII character in the set 0 9, #,*,A D. 383 This is interpreted as a single ACSII character whose duration is set by the +VTD command. 384 NOTE 2: In GSM this operates only in voice mode. 385 2. [<tone1>,<tone2>,<duration>]. 386 This is interpreted as a dual tone of frequencies <tone1> and <tone2>, lasting for a time <duration> (in 10 387 ms multiples). NOTE 3: This does not operate in GSM. 388 3. {<DTMF>,<duration>}. This is interpreted as a DTMF tone of different duration from that mandated by the 389 +VTD command. NOTE 4: In GSM this operates only in voice mode. 390 */ 391 TELEPHONY_LOGD("ControlBase::SendDtmf start"); 392 auto pConnection = FindConnectionByIndex<T &, decltype(&t.begin()->second)>(t, callInfo.index); 393 if (pConnection == nullptr) { 394 TELEPHONY_LOGE("SendDtmf, error type: connection is null"); 395 return CALL_ERR_CALL_CONNECTION_NOT_EXIST; 396 } 397 if (!IsDtmfKey(cDtmfCode)) { 398 TELEPHONY_LOGE("SendDtmf return, error type: cDtmfCode invalid."); 399 return CALL_ERR_PARAMETER_OUT_OF_RANGE; 400 } 401 return pConnection->SendDtmfRequest(callInfo.slotId, cDtmfCode, pConnection->GetIndex()); 402 } 403 404 /** 405 * GetCallFailReason 406 * 407 * 3GPP TS 24.008 V17.4.0 (2021-09) 10.5.4.11 Cause 408 * 409 * @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure. 410 */ 411 template<typename T> GetCallFailReason(int32_t slotId,T && t)412 int32_t GetCallFailReason(int32_t slotId, T &&t) const 413 { 414 decltype(t.begin()->second) connection; 415 return connection.GetCallFailReasonRequest(slotId); 416 } 417 418 protected: 419 bool isIgnoredIncomingCall_ = false; 420 421 private: 422 /** 423 * Check call with airplane mode on 424 */ 425 bool CheckAirplaneModeScene(const CellularCallInfo &callInfo); 426 427 /** 428 * check call with activate sim 429 */ 430 bool CheckActivateSimScene(int32_t slotId); 431 432 /** 433 * Handle call with airplane mode on 434 */ 435 int32_t HandleEcc(const CellularCallInfo &callInfo, bool isEcc, bool isAirplaneModeOn, bool isActivateSim); 436 437 private: 438 std::shared_ptr<AppExecFwk::EventRunner> eventLoop_; 439 std::condition_variable cv_; 440 std::mutex mutex_; 441 }; 442 } // namespace Telephony 443 } // namespace OHOS 444 445 #endif // CELLULAR_CALL_CONTROL_BASE_H 446