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