* Copyright (C) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CELLULAR_CALL_CONTROL_BASE_H
#define CELLULAR_CALL_CONTROL_BASE_H
#include "call_manager_errors.h"
#include "event_handler.h"
#include "cellular_call_data_struct.h"
#include "telephony_log_wrapper.h"
#include "base_connection.h"
#include "tel_ril_call_parcel.h"
#include "mmi_code_utils.h"
namespace OHOS {
namespace Telephony {
class ControlBase {
public:
* constructor
*/
ControlBase() = default;
* destructor
*/
virtual ~ControlBase() = default;
* Dial
*
* 27007-430_2001 6.27 Informative examples
* 3GPP TS 22.030 [19]
*
* originate a voice call
*
* @param CellularCallInfo
* @param bool
* @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure.
*/
virtual int32_t Dial(const CellularCallInfo &callInfo, bool isEcc) = 0;
* HangUp
*
* 3GPP TS 27.007 V3.9.0 (2001-06) Call related supplementary services +CHLD
* 3GPP TS 27.007 V3.9.0 (2001-06) 7.22 Informative examples
* 3GPP TS 22.030 [19]
*
* release call
*
* @param CellularCallInfo
* @param CallSupplementType
* @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure.
*/
virtual int32_t HangUp(const CellularCallInfo &callInfo, CallSupplementType type) = 0;
* Answer
*
* 27007-430_2001 6.6 Alternating mode call control method
* 3GPP TS 22.030 [19]
*
* Answer an incoming voice call.
*
* @param CellularCallInfo
* @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure.
*/
virtual int32_t Answer(const CellularCallInfo &callInfo) = 0;
* Reject
*
* 27007-430_2001 6.6 Alternating mode call control method
* 3GPP TS 22.030 [19]
*
* Reject an incoming voice call
*
* @param CellularCallInfo
* @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure.
*/
virtual int32_t Reject(const CellularCallInfo &callInfo) = 0;
* HoldCall
*
* 22083-400_2001 2 Call hold
* 3GPP TS 22.030 [3]
* 3GPP TS 23.083 V4.2.0 (2001-04) 2 Call hold (HOLD)
*
* The call hold service allows a served mobile subscriber
*
* @param slotId
* @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure.
*/
virtual int32_t HoldCall(int32_t slotId, bool isRTT = false) = 0;
* UnHoldCall
*
* 22083-400_2001 2 Call hold
* 3GPP TS 22.030 [3]
*
* Retrieve the held call.
*
* @param slotId
* @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure.
*/
virtual int32_t UnHoldCall(int32_t slotId, bool isRTT = false) = 0;
* SwitchCall
*
* 22083-400_2001 2 Call hold
* 3GPP TS 22.030 [3]
*
* Alternate from one call to the other
*
* @param slotId
* @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure.
*/
virtual int32_t SwitchCall(int32_t slotId, bool isRTT = false) = 0;
* CombineConference
*
* 22084-400_2001 1.3.8.2 Managing an active multiParty call
* 3GPP TS 22.030
*
* Add another remote party
* @param slotId
* @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure.
*/
virtual int32_t CombineConference(int32_t slotId) = 0;
* HangUpAllConnection
*
* @param slotId
* @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure.
*/
virtual int32_t HangUpAllConnection(int32_t slotId) = 0;
* ReportCallsData
*
* @param slotId
* @param CallInfoList
* @returns Error Code: Returns TELEPHONY_SUCCESS on success, others on failure.
*/
virtual int32_t ReportCallsData(int32_t slotId, const CallInfoList &callInfoList) = 0;
* Dial PreJudgment
*
* @param CellularCallInfo
* @returns Error Code: Returns TELEPHONY_SUCCESS on success, others on failure.
*/
int32_t DialPreJudgment(const CellularCallInfo &callInfo, bool isEcc);
* Is Need Execute MMI
*
* @param slotId
* @param std::string phoneString
* @param CLIRMode
* @param isNeedUseIms
* @returns bool
*/
bool IsNeedExecuteMMI(int32_t slotId, std::string &phoneString, CLIRMode &clirMode, bool isNeedUseIms);
* Is Dtmf Key
*
* 23014-400_2001 6 Support of DTMF across the air interface
* 3GPP TS 22.030
*
* @param char
* @returns bool
*/
bool IsDtmfKey(char c) const;
bool IsConnectedOut(TelCallState preState, TelCallState curState);
int32_t SetReadyToCall(int32_t slotId, bool isReadyToCall);
* Determine whether the call can be initiated currently
*
* @param std::map<std::string, BaseConnection>
* @return Returns true can to call
*/
template<typename T>
bool CanCall(T &&t)
{
unsigned int maximumCalls = 6;
return t.size() <= maximumCalls;
}
* FindConnectionByState
*
* @param std::map<std::string, BaseConnection>
* @param TelCallState
* @return pointer
*/
template<typename T1, typename T2>
T2 FindConnectionByState(const T1 &&t1, TelCallState state) const
{
for (auto &it : t1) {
T2 pConnection = &it.second;
if (pConnection != nullptr && pConnection->GetStatus() == state) {
return pConnection;
}
}
return nullptr;
}
* FindConnectionByIndex
*
* @param std::map<std::string, BaseConnection>
* @param index
* @return pointer
*/
template<typename T1, typename T2>
T2 FindConnectionByIndex(const T1 &&t1, int32_t index) const
{
for (auto &it : t1) {
T2 pConnection = &it.second;
if (pConnection != nullptr && pConnection->GetIndex() == index) {
return pConnection;
}
}
return nullptr;
}
* SetConnectionData
*
* @param std::map<std::string, BaseConnection>
* @param string phoneNum
* @param BaseConnection
* @return bool
*/
template<typename T1, typename T2>
bool SetConnectionData(T1 &&t1, const int32_t &key, const T2 &con)
{
if (!t1.insert(std::make_pair(key, con)).second) {
TELEPHONY_LOGE("SetConnectionData, key already exists.");
return false;
}
return true;
}
* Determines if a connection is currently in this state
*
* @param std::map<std::string, BaseConnection>
* @param TelCallState
* @return Returns true or false
*/
template<typename T1>
bool IsInState(T1 &&t, TelCallState state)
{
for (const auto &it : t) {
auto pConnection = &it.second;
if (pConnection != nullptr && pConnection->GetStatus() == state) {
return true;
}
}
return false;
}
* StartDtmf
*
* 23014-400_2001 6 Support of DTMF across the air interface
* 3GPP TS 22.030
*
* START DTMF : Containing the digit value (0-9,A,B,C,D,*,#)
* @param std::map<std::string, BaseConnection>
* @param Dtmf Code
* @param CellularCallInfo
* @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure.
*/
template<typename T>
int32_t StartDtmf(T &&t, char cDtmfCode, const CellularCallInfo &callInfo) const
{
* The messages when sent across the air interface should contain the following information:
* a) START DTMF : Containing the digit value (0-9,A,B,C,D,*,#);
* b) START DTMF ACKNOWLEDGE: Containing the digit value (0-9,A,B,C,D,*,#) corresponding to the DTMF tone that
* the network applies towards the remote user;
* c) STOP DTMF : No further info;
* d) STOP DTMF ACKNOWLEDGE: No further info.
* Only a single digit will be passed in each START DTMF and START DTMF ACKNOWLEDGE message
*/
TELEPHONY_LOGD("ControlBase::StartDtmf start");
auto pConnection = FindConnectionByIndex<T &, decltype(&t.begin()->second)>(t, callInfo.index);
if (pConnection == nullptr) {
TELEPHONY_LOGE("StartDtmf, error type: connection is null");
return CALL_ERR_CALL_CONNECTION_NOT_EXIST;
}
if (!IsDtmfKey(cDtmfCode)) {
TELEPHONY_LOGE("StartDtmf return, error type: cDtmfCode invalid.");
return CALL_ERR_PARAMETER_OUT_OF_RANGE;
}
return pConnection->StartDtmfRequest(callInfo.slotId, cDtmfCode, pConnection->GetIndex());
}
* StopDtmf
*
* 23014-400_2001 6 Support of DTMF across the air interface
* 3GPP TS 22.030
*
* STOP DTMF : No further info
* @param std::map<std::string, BaseConnection>
* @param CellularCallInfo
* @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure.
*/
template<typename T>
int32_t StopDtmf(T &&t, const CellularCallInfo &callInfo) const
{
* The messages when sent across the air interface should contain the following information:
* a) START DTMF : Containing the digit value (0-9,A,B,C,D,*,#);
* b) START DTMF ACKNOWLEDGE: Containing the digit value (0-9,A,B,C,D,*,#) corresponding to the DTMF tone that
* the network applies towards the remote user;
* c) STOP DTMF : No further info;
* d) STOP DTMF ACKNOWLEDGE: No further info.
* Only a single digit will be passed in each START DTMF and START DTMF ACKNOWLEDGE message
*/
TELEPHONY_LOGD("ControlBase::StopDtmf start");
auto pConnection = FindConnectionByIndex<T &, decltype(&t.begin()->second)>(t, callInfo.index);
if (pConnection == nullptr) {
TELEPHONY_LOGE("StopDtmf, error type: connection is null");
return CALL_ERR_CALL_CONNECTION_NOT_EXIST;
}
return pConnection->StopDtmfRequest(callInfo.slotId, pConnection->GetIndex());
}
* SendDtmf
*
* 23014-400_2001 6 Support of DTMF across the air interface
* 3GPP TS 22.030
*
* @param std::map<std::string, BaseConnection>
* @param Dtmf Code
* @param CellularCallInfo
* @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure.
*/
template<typename T>
int32_t SendDtmf(T &&t, char cDtmfCode, const CellularCallInfo &callInfo) const
{
* 3gpp 27007-430_2001
*
* C.2.11 DTMF and tone generation +VTS
*
* This command allows the transmission of DTMF tones and arbitrary tones (see note).
* These tones may be used (for example) when announcing the start of a recording period.
* The command is write only.
* In this profile of commands, this command does not operate in data or fax modes of operation (+FCLASS=0,1,2
7). NOTE 1: D is used only for dialling.
The string parameter of the command consists of combinations of the following separated by commas:
1. <DTMF>. A single ASCII character in the set 0 9, #,*,A D.
This is interpreted as a single ACSII character whose duration is set by the +VTD command.
NOTE 2: In GSM this operates only in voice mode.
2. [<tone1>,<tone2>,<duration>].
This is interpreted as a dual tone of frequencies <tone1> and <tone2>, lasting for a time <duration> (in 10
ms multiples). NOTE 3: This does not operate in GSM.
3. {<DTMF>,<duration>}. This is interpreted as a DTMF tone of different duration from that mandated by the
+VTD command. NOTE 4: In GSM this operates only in voice mode.
*/
TELEPHONY_LOGD("ControlBase::SendDtmf start");
auto pConnection = FindConnectionByIndex<T &, decltype(&t.begin()->second)>(t, callInfo.index);
if (pConnection == nullptr) {
TELEPHONY_LOGE("SendDtmf, error type: connection is null");
return CALL_ERR_CALL_CONNECTION_NOT_EXIST;
}
if (!IsDtmfKey(cDtmfCode)) {
TELEPHONY_LOGE("SendDtmf return, error type: cDtmfCode invalid.");
return CALL_ERR_PARAMETER_OUT_OF_RANGE;
}
return pConnection->SendDtmfRequest(callInfo.slotId, cDtmfCode, pConnection->GetIndex());
}
* GetCallFailReason
*
* 3GPP TS 24.008 V17.4.0 (2021-09) 10.5.4.11 Cause
*
* @return Error Code: Returns TELEPHONY_SUCCESS on success, others on failure.
*/
template<typename T>
int32_t GetCallFailReason(int32_t slotId, T &&t) const
{
decltype(t.begin()->second) connection;
return connection.GetCallFailReasonRequest(slotId);
}
protected:
bool isIgnoredIncomingCall_ = false;
private:
* Check call with airplane mode on
*/
bool CheckAirplaneModeScene(const CellularCallInfo &callInfo);
* check call with activate sim
*/
bool CheckActivateSimScene(int32_t slotId);
* Handle call with airplane mode on
*/
int32_t HandleEcc(const CellularCallInfo &callInfo, bool isEcc, bool isAirplaneModeOn, bool isActivateSim);
bool IsEmergencyCall(int32_t slotId, std::string &phoneString);
private:
std::shared_ptr<AppExecFwk::EventRunner> eventLoop_;
std::condition_variable cv_;
std::mutex mutex_;
};
}
}
#endif