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