2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
18 * @file FTel_CallManagerImpl.cpp
19 * @brief This is the implementation file for _CallManagerImpl class.
24 #include <tapi_common.h>
25 #include <tapi_event.h>
26 #include <TapiUtility.h>
27 #include <ITapiCall.h>
28 #include <FBaseString.h>
29 #include <FBaseUtilStringUtil.h>
30 #include <FTelITelephonyCallEventListener.h>
31 #include <FTelITelephonyCallForwardListener.h>
32 #include <FTelCallManager.h>
33 #include <FBaseSysLog.h>
34 #include "FTel_CallInfoImpl.h"
35 #include "FTel_CallManagerImpl.h"
36 #include "FTel_CallManagerEvent.h"
37 #include "FTel_CallManagerEventArg.h"
38 #include "FTel_CallForwardEvent.h"
39 #include "FTel_CallForwardEventArg.h"
40 #include "FTel_TelephonyIpcProxy.h"
41 #include "FTel_NetworkManagerImpl.h"
44 using namespace Tizen::App;
45 using namespace Tizen::Base;
46 using namespace Tizen::Base::Utility;
49 namespace Tizen { namespace Telephony
52 _CallManagerImpl::_CallManagerImpl(void)
53 : __pCallEventListener(null)
54 , __pCallForwardListener(null)
56 , __callFwdSubscriptionId(0)
57 , __callFwdStatusSubscriptionId(0)
58 , __callFwdReqId(INVALID_REQUEST_ID)
59 , __callFwdReqNumId(INVALID_REQUEST_ID)
60 , __isReqCallFwdNumInProgress(false)
61 , __curCallState(CALL_STATUS_IDLE)
62 , __curCallFwdState(_CALL_FORWARD_IDLE)
63 , __pCallManagerEvent(null)
64 , __pCallForwardEvent(null)
67 __pCallEventType[_CALL_NOTI_VOICE_CALL_IDLE] = TAPI_NOTI_VOICE_CALL_STATUS_IDLE;
68 __pCallEventType[_CALL_NOTI_VOICE_CALL_COMMUNICATING] = TAPI_NOTI_VOICE_CALL_STATUS_ACTIVE;
69 __pCallEventType[_CALL_NOTI_VOICE_CALL_RINGING] = TAPI_NOTI_VOICE_CALL_STATUS_INCOMING;
70 __pCallEventType[_CALL_NOTI_VOICE_CALL_DIALING] = TAPI_NOTI_VOICE_CALL_STATUS_DIALING;
71 __pCallEventType[_CALL_NOTI_VOICE_CALL_HOLDING] = TAPI_NOTI_VOICE_CALL_STATUS_HELD;
72 __pCallEventType[_CALL_NOTI_VIDEO_CALL_IDLE] = TAPI_NOTI_VIDEO_CALL_STATUS_IDLE;
73 __pCallEventType[_CALL_NOTI_VIDEO_CALL_COMMUNICATING] = TAPI_NOTI_VIDEO_CALL_STATUS_ACTIVE;
74 __pCallEventType[_CALL_NOTI_VIDEO_CALL_RINGING] = TAPI_NOTI_VIDEO_CALL_STATUS_INCOMING;
75 __pCallEventType[_CALL_NOTI_VIDEO_CALL_DIALING] = TAPI_NOTI_VIDEO_CALL_STATUS_DIALING;
76 __pCallEventType[_CALL_NOTI_PEER_CALL_HELD] = TAPI_NOTI_CALL_INFO_HELD;
77 __pCallEventType[_CALL_NOTI_PEER_CALL_RETRIEVED] = TAPI_NOTI_CALL_INFO_ACTIVE;
81 _CallManagerImpl::~_CallManagerImpl(void)
83 if (__pHandle != null)
85 for (int i = 0; i < _CALL_NOTI_MAX; i++)
87 tel_deregister_noti_event(__pHandle, __pCallEventType[i]);
90 tel_deinit(__pHandle);
95 _CallManagerImpl::Construct(ITelephonyCallEventListener* pListener)
97 SysLog(NID_TEL, "The current call state is %s", GetStringOfCallState());
100 int err = TAPI_API_SUCCESS;
102 __pHandle = tel_init(null);
103 SysTryCatch(NID_TEL, __pHandle != null, r = E_SYSTEM, E_SYSTEM, "[%s] A system error has occurred. Failed to initialize TApi library.", GetErrorMessage(E_SYSTEM));
105 if (pListener != null)
107 for (int i = 0; i < _CALL_NOTI_MAX; i++)
109 err = tel_register_noti_event(__pHandle, __pCallEventType[i], OnCallStatusChangedCallback, this);
110 SysLog(NID_TEL, "The registered call type is %s", GetStringOfCallEventType(_CALL_NOTI_VOICE_CALL_IDLE + i));
112 SysTryCatch(NID_TEL, err == TAPI_API_SUCCESS, r = E_SYSTEM, E_SYSTEM,
113 "[%s] A system error has occurred. Failed to register the callback function.", GetErrorMessage(E_SYSTEM));
116 unique_ptr<_CallManagerEvent> pCallManagerEvent(new (std::nothrow) _CallManagerEvent);
117 SysTryReturnResult(NID_TEL, pCallManagerEvent != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
119 r = pCallManagerEvent->Construct();
120 SysTryReturnResult(NID_TEL, r != E_OUT_OF_MEMORY, r, "Propagating.");
121 SysTryReturnResult(NID_TEL, r == E_SUCCESS, E_SYSTEM, "A system error has occurred. Failed to construct CallManagerEvent.");
123 pCallManagerEvent->AddListener(*pListener, true);
125 __pCallManagerEvent = move(pCallManagerEvent);
129 r = InitializeInternalCallStatus();
130 SysTryCatch(NID_TEL, r == E_SUCCESS, , E_SYSTEM, "[%s] A system error has occurred. Failed to initialize internal call state.", GetErrorMessage(E_SYSTEM));
132 __pTelephonyServiceProxy = _TelephonyIpcProxy::GetInstance();
134 if (__pTelephonyServiceProxy == null)
136 SysLog(NID_TEL, "Creating an IPC instance to connect with the Connectivity service daemon has failed.");
140 __pTelephonyServiceProxy->SetCallManagerImpl(*this);
146 for (int i = 0; i < _CALL_NOTI_MAX; i++)
148 tel_deregister_noti_event(__pHandle, __pCallEventType[i]);
151 if (__pHandle != null)
153 tel_deinit(__pHandle);
161 _CallManagerImpl::SetCallForwardListener(ITelephonyCallForwardListener* pListener)
163 SysTryReturnResult(NID_TEL, __pTelephonyServiceProxy != null, E_SYSTEM, "A system error has occurred. IPC instance has not been constructed yet.");
165 result r = __pTelephonyServiceProxy->HasCallForwardPrivilege();
166 SysTryReturnResult(NID_TEL, r == E_SUCCESS, r, "Propagating.");
168 if (__pCallForwardListener != null)
170 __pCallForwardEvent->RemoveListener(*__pCallForwardListener);
171 __pCallForwardListener = null;
175 // Creates event object
176 if (__pCallForwardEvent == null && pListener != null)
178 std::unique_ptr<_CallForwardEvent> pCallForwardEvent(new (std::nothrow) _CallForwardEvent());
180 SysTryReturnResult(NID_TEL, pCallForwardEvent != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
182 r = pCallForwardEvent->Construct();
183 SysTryReturnResult(NID_TEL, r == E_SUCCESS, r, "Propagating.");
185 __pCallForwardEvent = move(pCallForwardEvent);
189 if (pListener != null)
191 __pCallForwardListener = pListener;
192 r = __pCallForwardEvent->AddListener(*__pCallForwardListener, true);
197 __pCallForwardEvent.reset(null);
198 SysLogException(NID_TEL, r, "[%s] Propagating.", GetErrorMessage(r));
205 _CallManagerImpl::RequestCallForward(const String& phoneNumber)
207 result r = E_SUCCESS;
209 switch (__curCallFwdState)
211 case _CALL_FORWARD_REQUESTING:
213 SysLogException(NID_TEL, E_IN_PROGRESS, "[%s] The previous request is in progress.", GetErrorMessage(E_IN_PROGRESS));
214 return E_IN_PROGRESS;
217 case _CALL_FORWARD_ON_SERVICE:
218 case _CALL_FORWARD_STOPPING:
220 SysLogException(NID_TEL, E_INVALID_STATE, "[%s] The current state of the instance prohibits the execution of this operation.", GetErrorMessage(E_IN_PROGRESS));
221 return E_INVALID_STATE;
228 SysLog(NID_TEL, "The phonenumber is %ls", phoneNumber.GetPointer());
230 SysTryReturnResult(NID_TEL, _NetworkManagerImpl::IsNetworkAvailable(), E_NETWORK_UNAVAILABLE,
231 "The operation failed because the device is in the offline mode.");
232 SysTryReturnResult(NID_TEL, _NetworkManagerImpl::IsServiceAvailable(), E_SERVICE_UNAVAILABLE,
233 "The operation failed because the device is out of the coverage area or in the emergency mode.");
234 SysTryReturnResult(NID_TEL, !phoneNumber.IsEmpty(), E_INVALID_FORMAT, "The phone number is empty string.");
235 SysTryReturnResult(NID_TEL, IsPhoneNumberValid(phoneNumber), E_INVALID_FORMAT, "The phone number is invalid format");
237 r = __pTelephonyServiceProxy->RequestCallForward(phoneNumber);
238 SysTryReturnResult(NID_TEL, r == E_SUCCESS, r, "Propagating.");
240 __curCallFwdState = _CALL_FORWARD_REQUESTING;
246 _CallManagerImpl::StopCallForward(void)
248 switch (__curCallFwdState)
250 case _CALL_FORWARD_STOPPING:
252 SysLogException(NID_TEL, E_IN_PROGRESS, "[%s] The previous request is in progress.", GetErrorMessage(E_IN_PROGRESS));
253 return E_IN_PROGRESS;
255 case _CALL_FORWARD_IDLE:
256 case _CALL_FORWARD_REQUESTING:
258 SysLogException(NID_TEL, E_INVALID_STATE, "[%s] The current state of the instance prohibits the execution of this operation.", GetErrorMessage(E_INVALID_STATE));
259 return E_INVALID_STATE;
264 SysTryReturnResult(NID_TEL, _NetworkManagerImpl::IsNetworkAvailable(), E_NETWORK_UNAVAILABLE,
265 "The operation has failed because the device is in the offline mode.");
266 SysTryReturnResult(NID_TEL, _NetworkManagerImpl::IsServiceAvailable(), E_SERVICE_UNAVAILABLE,
267 "The operation failed because the device is out of the coverage area or in the emergency mode.");
269 result r = __pTelephonyServiceProxy->StopCallForward();
270 SysTryReturnResult(NID_TEL, r == E_SUCCESS, r, "Propagating.");
272 __curCallFwdState = _CALL_FORWARD_STOPPING;
278 _CallManagerImpl::GetCallForwardNumber(void)
280 SysTryReturnResult(NID_TEL, __pCallForwardListener != null, E_INVALID_OPERATION,
281 "The ITelephonyCallForwardListener has not been registered yet.");
282 SysTryReturnResult(NID_TEL, !__isReqCallFwdNumInProgress, E_IN_PROGRESS, "The previous request is in progress.");
283 SysTryReturnResult(NID_TEL, _NetworkManagerImpl::IsNetworkAvailable(), E_NETWORK_UNAVAILABLE,
284 "The operation has failed because the device is in the offline mode.");
285 SysTryReturnResult(NID_TEL, _NetworkManagerImpl::IsServiceAvailable(), E_SERVICE_UNAVAILABLE,
286 "The operation failed because the device is out of the coverage area or in the emergency mode.");
288 result r = __pTelephonyServiceProxy->GetCallForwardNumber();
289 SysTryReturnResult(NID_TEL, r == E_SUCCESS, r, "Propagating.");
291 __isReqCallFwdNumInProgress = true;
297 _CallManagerImpl::GetCurrentCallType(void) const
299 CallType type = TYPE_UNDEFINED_CALL;
300 int err = TAPI_API_SUCCESS;
302 err = tel_get_call_status_all(__pHandle, OnCallTypeCallback, &type);
308 _CallManagerImpl::GetCurrentCallStatus(void) const
310 return __curCallState;
314 _CallManagerImpl::OnCallStatusChangedCallback(TapiHandle* pHandle, const char* pNotiId, void* pData, void* pUserData)
316 SysLog(NID_TEL, "The pNotiId value is %s", pNotiId);
318 CallType callType = TYPE_UNDEFINED_CALL;
321 _CallManagerImpl* pCallManagerImpl = static_cast <_CallManagerImpl*>(pUserData);
323 if (strcmp(pNotiId, TAPI_NOTI_VOICE_CALL_STATUS_IDLE) == 0
324 || strcmp(pNotiId,TAPI_NOTI_VIDEO_CALL_STATUS_IDLE) == 0)
326 TelCallStatusIdleNoti_t* pNotiData = (TelCallStatusIdleNoti_t*)pData;
327 callId = pNotiData->id;
328 pCallManagerImpl->__curCallState = CALL_STATUS_IDLE;
332 if (strcmp(pNotiId, TAPI_NOTI_VOICE_CALL_STATUS_ACTIVE) == 0
333 || strcmp(pNotiId,TAPI_NOTI_VIDEO_CALL_STATUS_ACTIVE) == 0)
335 TelCallStatusActiveNoti_t* pNotiData = (TelCallStatusActiveNoti_t*)pData;
336 callId = pNotiData->id;
338 else if (strcmp(pNotiId,TAPI_NOTI_VOICE_CALL_STATUS_INCOMING) == 0
339 || strcmp(pNotiId,TAPI_NOTI_VIDEO_CALL_STATUS_INCOMING) == 0)
341 TelCallStatusIncomingNoti_t* pNotiData = (TelCallStatusIncomingNoti_t*)pData;
342 callId = pNotiData->id;
344 else if (strcmp(pNotiId,TAPI_NOTI_VOICE_CALL_STATUS_DIALING) == 0
345 || strcmp(pNotiId, TAPI_NOTI_VIDEO_CALL_STATUS_DIALING) == 0)
347 TelCallStatusDialingNoti_t* pNotiData = (TelCallStatusDialingNoti_t*)pData;
348 callId = pNotiData->id;
350 else if (strcmp(pNotiId,TAPI_NOTI_VOICE_CALL_STATUS_HELD) == 0)
352 TelCallStatusHeldNoti_t* pNotiData = (TelCallStatusHeldNoti_t*)pData;
353 callId = pNotiData->id;
355 else if (strcmp(pNotiId,TAPI_NOTI_CALL_INFO_HELD) == 0)
357 TelCallInfoHeldNoti_t* pNotiData = (TelCallInfoHeldNoti_t*)pData;
358 callId = pNotiData->id;
360 else if (strcmp(pNotiId,TAPI_NOTI_CALL_INFO_ACTIVE) == 0)
362 TelCallInfoActiveNoti_t* pNotiData = (TelCallInfoActiveNoti_t*)pData;
363 callId = pNotiData->id;
366 int err = tel_get_call_status_all(pHandle, OnCallStatusCallback, pCallManagerImpl);
367 SysLog(NID_TEL, "The tel_get_call_status_all() returned %d value", err);
369 phoneNumber = pCallManagerImpl->GetPhoneNumber(pHandle, callId);
370 SysLog(NID_TEL, "The phonenumber is %ls", phoneNumber.GetPointer());
374 callType = pCallManagerImpl->GetCurrentCallType();
376 if (pCallManagerImpl->__curCallState != CALL_STATUS_UNDEFINED)
378 unique_ptr<CallInfo> pCallInfo(null);
379 _CallInfoImpl* pCallInfoImpl = null;
381 pCallInfo.reset(new (std::nothrow) CallInfo());
382 SysTryReturnVoidResult(NID_TEL, pCallInfo != null, E_OUT_OF_MEMORY,
383 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
385 pCallInfoImpl = _CallInfoImpl::GetInstance(*pCallInfo);
386 pCallInfoImpl->SetCallType(callType);
387 pCallInfoImpl->SetNumber(phoneNumber);
389 _CallManagerEventArg* pEventArg = new (std::nothrow)_CallManagerEventArg(pCallManagerImpl->__curCallState, pCallInfo.get());
390 SysTryReturnVoidResult(NID_TEL,pEventArg != null, E_OUT_OF_MEMORY,
391 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
395 SysLog(NID_TEL, "The current call type is %d, and the phonenumber is %ls", callType, phoneNumber.GetPointer());
396 (void)pCallManagerImpl->__pCallManagerEvent->Fire(*pEventArg);
401 _CallManagerImpl::OnTelephonyCallForwardNumberReceived(Tizen::Base::String phoneNumber, result r)
403 SysLog(NID_TEL, "The listener has called with result %s and phonenumber is %ls", GetErrorMessage(r), phoneNumber.GetPointer());
405 _CallForwardEventArg* pEventArg = new (std::nothrow)_CallForwardEventArg(_CALL_FORWARD_EVENT_NUMBER_RECEIVED, phoneNumber, r);
407 SysTryReturnVoidResult(NID_TEL,pEventArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
409 (void)__pCallForwardEvent->Fire(*pEventArg);
411 __isReqCallFwdNumInProgress = false;
415 _CallManagerImpl::OnTelephonyCallForwardResponseReceived(Tizen::Base::String phoneNumber, result r)
417 SysLog(NID_TEL, "The listener has called with result %s and phonenumber is %ls", GetErrorMessage(r), phoneNumber.GetPointer());
419 _CallForwardEventArg* pEventArg = new (std::nothrow)_CallForwardEventArg(_CALL_FORWARD_EVENT_RESPONSE_RECEIVED, phoneNumber, r);
421 SysTryReturnVoidResult(NID_TEL, pEventArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
423 (void)__pCallForwardEvent->Fire(*pEventArg);
427 __curCallFwdState = _CALL_FORWARD_IDLE;
431 __curCallFwdState = _CALL_FORWARD_ON_SERVICE;
436 _CallManagerImpl::OnTelephonyCallForwardStopped(Tizen::Base::String phoneNumber, result r)
438 SysLog(NID_TEL, "The listener has called with result %s and phonenumber is %ls", GetErrorMessage(r), phoneNumber.GetPointer());
440 _CallForwardEventArg* pEventArg = new (std::nothrow)_CallForwardEventArg(_CALL_FORWARD_EVENT_STOPPED, phoneNumber, r);
442 SysTryReturnVoidResult(NID_TEL, pEventArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
444 (void)__pCallForwardEvent->Fire(*pEventArg);
448 __curCallFwdState = _CALL_FORWARD_ON_SERVICE;
452 __curCallFwdState = _CALL_FORWARD_IDLE;
457 _CallManagerImpl::OnCallStatusCallback(TelCallStatus_t* status, void* pUserData)
459 _CallManagerImpl* pImpl = static_cast<_CallManagerImpl*>(pUserData);
461 // Priority : Ringing/Dialing > Communicating > Hold
462 // ToDO : multi party call scenario
464 switch (status->CallState)
466 case TAPI_CALL_STATE_IDLE:
467 pImpl->__curCallState = CALL_STATUS_IDLE;
469 case TAPI_CALL_STATE_ACTIVE:
470 pImpl->__curCallState = CALL_STATUS_COMMUNICATING;
472 case TAPI_CALL_STATE_HELD:
473 pImpl->__curCallState = CALL_STATUS_HOLDING;
475 case TAPI_CALL_STATE_INCOMING:
476 pImpl->__curCallState = CALL_STATUS_RINGING;
478 case TAPI_CALL_STATE_DIALING:
479 case TAPI_CALL_STATE_ALERT:
480 pImpl->__curCallState = CALL_STATUS_DIALING;
490 _CallManagerImpl::OnCallTypeCallback(TelCallStatus_t* status, void* pUserData)
492 CallType* pCallType = static_cast<CallType*>(pUserData);
494 switch (status->CallType)
496 case TAPI_CALL_TYPE_VOICE:
497 *pCallType = TYPE_VOICE_CALL;
499 case TAPI_CALL_TYPE_DATA:
500 *pCallType = TYPE_VIDEO_CALL;
510 _CallManagerImpl::IsPhoneNumberValid(const String& phoneNumber) const
516 if (phoneNumber.StartsWith("+", 0))
521 for (int i = startIndex; i < phoneNumber.GetLength(); i++)
523 phoneNumber.GetCharAt(i, chr);
525 if (!Character::IsDigit(chr))
535 _CallManagerImpl::InitializeInternalCallStatus(void)
537 int err = TAPI_API_SUCCESS;
538 result r = E_SUCCESS;
540 err = tel_get_call_status_all(__pHandle, OnCallStatusCallback, this);
541 SysLog(NID_TEL, "The tel_get_call_status_all() returned %d value", err);
543 if (err != TAPI_API_SUCCESS)
545 if (err == TAPI_API_OPERATION_FAILED)
547 __curCallState = CALL_STATUS_IDLE;
559 _CallManagerImpl::GetPhoneNumber(TapiHandle* pCallHandle, int callId) const
561 int err = TAPI_API_SUCCESS;
564 TelCallStatus_t callStatus = {};
565 err = tel_get_call_status(pCallHandle, callId, &callStatus);
566 if (err == TAPI_API_SUCCESS)
568 (void)(StringUtil::Utf8ToString(callStatus.pNumber, phoneNumber));
569 SysLog(NID_TEL, "The phone number is %ls", phoneNumber.GetPointer());
573 SysLog(NID_TEL, "The tel_get_call_status_all() returned %d value", err);
580 _CallManagerImpl::GetStringOfCallState(void) const
582 static const char* pStateStr[] =
584 "CALL_STATUS_UNDEFINED",
586 "CALL_STATUS_ACTIVE",
587 "CALL_STATUS_COMMUNICATING",
588 "CALL_STATUS_RINGING",
589 "CALL_STATUS_DIALING",
590 "CALL_STATUS_HOLDING"
593 return pStateStr[__curCallState + 1];
597 _CallManagerImpl::GetStringOfCallFwdState(void) const
599 static const char* pFwdStateStr[] =
602 "CALL_FORWARD_REQUESTING",
603 "CALL_FORWARD_ON_SERVICE",
604 "CALL_FORWARD_STOPPING"
607 return pFwdStateStr[__curCallFwdState];
611 _CallManagerImpl::GetStringOfCallEventType(int type) const
613 static const char* pEventType[] =
616 "Voice Communicating",
621 "Video Communicating",
628 return pEventType[type];
632 _CallManagerImpl::GetInstance(CallManager& callManager)
634 return callManager.__pCallManagerImpl;
637 const _CallManagerImpl*
638 _CallManagerImpl::GetInstance(const CallManager& callManager)
640 return callManager.__pCallManagerImpl;
643 }} // Tizen::Telephony