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.");
142 for (int i = 0; i < _CALL_NOTI_MAX; i++)
144 tel_deregister_noti_event(__pHandle, __pCallEventType[i]);
147 if (__pHandle != null)
149 tel_deinit(__pHandle);
157 _CallManagerImpl::SetCallForwardListener(ITelephonyCallForwardListener* pListener)
159 SysTryReturnResult(NID_TEL, __pTelephonyServiceProxy != null, E_SYSTEM, "A system error has occurred. IPC instance has not been constructed yet.");
161 result r = __pTelephonyServiceProxy->HasCallForwardPrivilege();
162 SysTryReturnResult(NID_TEL, r == E_SUCCESS, r, "Propagating.");
164 if (__pCallForwardListener != null)
166 __pCallForwardEvent->RemoveListener(*__pCallForwardListener);
167 __pCallForwardListener = null;
171 // Creates event object
172 if (__pCallForwardEvent == null && pListener != null)
174 std::unique_ptr<_CallForwardEvent> pCallForwardEvent(new (std::nothrow) _CallForwardEvent());
176 SysTryReturnResult(NID_TEL, pCallForwardEvent != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
178 r = pCallForwardEvent->Construct();
179 SysTryReturnResult(NID_TEL, r == E_SUCCESS, r, "Propagating.");
181 __pCallForwardEvent = move(pCallForwardEvent);
185 if (pListener != null)
187 __pCallForwardListener = pListener;
188 r = __pCallForwardEvent->AddListener(*__pCallForwardListener, true);
193 __pCallForwardEvent.reset(null);
194 SysLogException(NID_TEL, r, "[%s] Propagating.", GetErrorMessage(r));
201 _CallManagerImpl::RequestCallForward(const String& phoneNumber)
203 result r = E_SUCCESS;
205 switch (__curCallFwdState)
207 case _CALL_FORWARD_REQUESTING:
209 SysLogException(NID_TEL, E_IN_PROGRESS, "[%s] The previous request is in progress.", GetErrorMessage(E_IN_PROGRESS));
210 return E_IN_PROGRESS;
213 case _CALL_FORWARD_ON_SERVICE:
214 case _CALL_FORWARD_STOPPING:
216 SysLogException(NID_TEL, E_INVALID_STATE, "[%s] The current state of the instance prohibits the execution of this operation.", GetErrorMessage(E_IN_PROGRESS));
217 return E_INVALID_STATE;
224 SysLog(NID_TEL, "The phonenumber is %ls", phoneNumber.GetPointer());
226 SysTryReturnResult(NID_TEL, _NetworkManagerImpl::IsNetworkAvailable(), E_NETWORK_UNAVAILABLE,
227 "The operation failed because the device is in the offline mode.");
228 SysTryReturnResult(NID_TEL, _NetworkManagerImpl::IsServiceAvailable(), E_SERVICE_UNAVAILABLE,
229 "The operation failed because the device is out of the coverage area or in the emergency mode.");
230 SysTryReturnResult(NID_TEL, !phoneNumber.IsEmpty(), E_INVALID_FORMAT, "The phone number is empty string.");
231 SysTryReturnResult(NID_TEL, IsPhoneNumberValid(phoneNumber), E_INVALID_FORMAT, "The phone number is invalid format");
233 r = __pTelephonyServiceProxy->RequestCallForward(this, phoneNumber);
234 SysTryReturnResult(NID_TEL, r == E_SUCCESS, r, "Propagating.");
236 __curCallFwdState = _CALL_FORWARD_REQUESTING;
242 _CallManagerImpl::StopCallForward(void)
244 switch (__curCallFwdState)
246 case _CALL_FORWARD_STOPPING:
248 SysLogException(NID_TEL, E_IN_PROGRESS, "[%s] The previous request is in progress.", GetErrorMessage(E_IN_PROGRESS));
249 return E_IN_PROGRESS;
251 case _CALL_FORWARD_IDLE:
252 case _CALL_FORWARD_REQUESTING:
254 SysLogException(NID_TEL, E_INVALID_STATE, "[%s] The current state of the instance prohibits the execution of this operation.", GetErrorMessage(E_INVALID_STATE));
255 return E_INVALID_STATE;
260 SysTryReturnResult(NID_TEL, _NetworkManagerImpl::IsNetworkAvailable(), E_NETWORK_UNAVAILABLE,
261 "The operation has failed because the device is in the offline mode.");
262 SysTryReturnResult(NID_TEL, _NetworkManagerImpl::IsServiceAvailable(), E_SERVICE_UNAVAILABLE,
263 "The operation failed because the device is out of the coverage area or in the emergency mode.");
265 result r = __pTelephonyServiceProxy->StopCallForward(this);
266 SysTryReturnResult(NID_TEL, r == E_SUCCESS, r, "Propagating.");
268 __curCallFwdState = _CALL_FORWARD_STOPPING;
274 _CallManagerImpl::GetCallForwardNumber(void)
276 SysTryReturnResult(NID_TEL, __pCallForwardListener != null, E_INVALID_OPERATION,
277 "The ITelephonyCallForwardListener has not been registered yet.");
278 SysTryReturnResult(NID_TEL, !__isReqCallFwdNumInProgress, E_IN_PROGRESS, "The previous request is in progress.");
279 SysTryReturnResult(NID_TEL, _NetworkManagerImpl::IsNetworkAvailable(), E_NETWORK_UNAVAILABLE,
280 "The operation has failed because the device is in the offline mode.");
281 SysTryReturnResult(NID_TEL, _NetworkManagerImpl::IsServiceAvailable(), E_SERVICE_UNAVAILABLE,
282 "The operation failed because the device is out of the coverage area or in the emergency mode.");
284 result r = __pTelephonyServiceProxy->GetCallForwardNumber(this);
285 SysTryReturnResult(NID_TEL, r == E_SUCCESS, r, "Propagating.");
287 __isReqCallFwdNumInProgress = true;
293 _CallManagerImpl::GetCurrentCallType(void) const
295 CallType type = TYPE_UNDEFINED_CALL;
296 int err = TAPI_API_SUCCESS;
298 err = tel_get_call_status_all(__pHandle, OnCallTypeCallback, &type);
304 _CallManagerImpl::GetCurrentCallStatus(void) const
306 return __curCallState;
310 _CallManagerImpl::OnCallStatusChangedCallback(TapiHandle* pHandle, const char* pNotiId, void* pData, void* pUserData)
312 SysLog(NID_TEL, "The pNotiId value is %s", pNotiId);
314 CallType callType = TYPE_UNDEFINED_CALL;
317 _CallManagerImpl* pCallManagerImpl = static_cast <_CallManagerImpl*>(pUserData);
319 if (strcmp(pNotiId, TAPI_NOTI_VOICE_CALL_STATUS_IDLE) == 0
320 || strcmp(pNotiId,TAPI_NOTI_VIDEO_CALL_STATUS_IDLE) == 0)
322 TelCallStatusIdleNoti_t* pNotiData = (TelCallStatusIdleNoti_t*)pData;
323 callId = pNotiData->id;
324 pCallManagerImpl->__curCallState = CALL_STATUS_IDLE;
328 if (strcmp(pNotiId, TAPI_NOTI_VOICE_CALL_STATUS_ACTIVE) == 0
329 || strcmp(pNotiId,TAPI_NOTI_VIDEO_CALL_STATUS_ACTIVE) == 0)
331 TelCallStatusActiveNoti_t* pNotiData = (TelCallStatusActiveNoti_t*)pData;
332 callId = pNotiData->id;
334 else if (strcmp(pNotiId,TAPI_NOTI_VOICE_CALL_STATUS_INCOMING) == 0
335 || strcmp(pNotiId,TAPI_NOTI_VIDEO_CALL_STATUS_INCOMING) == 0)
337 TelCallStatusIncomingNoti_t* pNotiData = (TelCallStatusIncomingNoti_t*)pData;
338 callId = pNotiData->id;
340 else if (strcmp(pNotiId,TAPI_NOTI_VOICE_CALL_STATUS_DIALING) == 0
341 || strcmp(pNotiId, TAPI_NOTI_VIDEO_CALL_STATUS_DIALING) == 0)
343 TelCallStatusDialingNoti_t* pNotiData = (TelCallStatusDialingNoti_t*)pData;
344 callId = pNotiData->id;
346 else if (strcmp(pNotiId,TAPI_NOTI_VOICE_CALL_STATUS_HELD) == 0)
348 TelCallStatusHeldNoti_t* pNotiData = (TelCallStatusHeldNoti_t*)pData;
349 callId = pNotiData->id;
351 else if (strcmp(pNotiId,TAPI_NOTI_CALL_INFO_HELD) == 0)
353 TelCallInfoHeldNoti_t* pNotiData = (TelCallInfoHeldNoti_t*)pData;
354 callId = pNotiData->id;
356 else if (strcmp(pNotiId,TAPI_NOTI_CALL_INFO_ACTIVE) == 0)
358 TelCallInfoActiveNoti_t* pNotiData = (TelCallInfoActiveNoti_t*)pData;
359 callId = pNotiData->id;
362 int err = tel_get_call_status_all(pHandle, OnCallStatusCallback, pCallManagerImpl);
363 SysLog(NID_TEL, "The tel_get_call_status_all() returned %d value", err);
365 phoneNumber = pCallManagerImpl->GetPhoneNumber(pHandle, callId);
366 SysLog(NID_TEL, "The phonenumber is %ls", phoneNumber.GetPointer());
370 callType = pCallManagerImpl->GetCurrentCallType();
372 if (pCallManagerImpl->__curCallState != CALL_STATUS_UNDEFINED)
374 unique_ptr<CallInfo> pCallInfo(null);
375 _CallInfoImpl* pCallInfoImpl = null;
377 pCallInfo.reset(new (std::nothrow) CallInfo());
378 SysTryReturnVoidResult(NID_TEL, pCallInfo != null, E_OUT_OF_MEMORY,
379 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
381 pCallInfoImpl = _CallInfoImpl::GetInstance(*pCallInfo);
382 pCallInfoImpl->SetCallType(callType);
383 pCallInfoImpl->SetNumber(phoneNumber);
385 _CallManagerEventArg* pEventArg = new (std::nothrow)_CallManagerEventArg(pCallManagerImpl->__curCallState, pCallInfo.get());
386 SysTryReturnVoidResult(NID_TEL,pEventArg != null, E_OUT_OF_MEMORY,
387 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
391 SysLog(NID_TEL, "The current call type is %d, and the phonenumber is %ls", callType, phoneNumber.GetPointer());
392 (void)pCallManagerImpl->__pCallManagerEvent->Fire(*pEventArg);
397 _CallManagerImpl::OnTelephonyCallForwardNumberReceived(Tizen::Base::String phoneNumber, result r)
399 SysLog(NID_TEL, "The listener has called with result %s and phonenumber is %ls", GetErrorMessage(r), phoneNumber.GetPointer());
401 _CallForwardEventArg* pEventArg = new (std::nothrow)_CallForwardEventArg(_CALL_FORWARD_EVENT_NUMBER_RECEIVED, phoneNumber, r);
403 SysTryReturnVoidResult(NID_TEL,pEventArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
405 (void)__pCallForwardEvent->Fire(*pEventArg);
407 __isReqCallFwdNumInProgress = false;
411 _CallManagerImpl::OnTelephonyCallForwardResponseReceived(Tizen::Base::String phoneNumber, result r)
413 SysLog(NID_TEL, "The listener has called with result %s and phonenumber is %ls", GetErrorMessage(r), phoneNumber.GetPointer());
415 _CallForwardEventArg* pEventArg = new (std::nothrow)_CallForwardEventArg(_CALL_FORWARD_EVENT_RESPONSE_RECEIVED, phoneNumber, r);
417 SysTryReturnVoidResult(NID_TEL, pEventArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
419 (void)__pCallForwardEvent->Fire(*pEventArg);
423 __curCallFwdState = _CALL_FORWARD_IDLE;
427 __curCallFwdState = _CALL_FORWARD_ON_SERVICE;
432 _CallManagerImpl::OnTelephonyCallForwardStopped(Tizen::Base::String phoneNumber, result r)
434 SysLog(NID_TEL, "The listener has called with result %s and phonenumber is %ls", GetErrorMessage(r), phoneNumber.GetPointer());
436 _CallForwardEventArg* pEventArg = new (std::nothrow)_CallForwardEventArg(_CALL_FORWARD_EVENT_STOPPED, phoneNumber, r);
438 SysTryReturnVoidResult(NID_TEL, pEventArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
440 (void)__pCallForwardEvent->Fire(*pEventArg);
444 __curCallFwdState = _CALL_FORWARD_ON_SERVICE;
448 __curCallFwdState = _CALL_FORWARD_IDLE;
453 _CallManagerImpl::OnCallStatusCallback(TelCallStatus_t* status, void* pUserData)
455 _CallManagerImpl* pImpl = static_cast<_CallManagerImpl*>(pUserData);
457 // Priority : Ringing/Dialing > Communicating > Hold
458 // ToDO : multi party call scenario
460 switch (status->CallState)
462 case TAPI_CALL_STATE_IDLE:
463 pImpl->__curCallState = CALL_STATUS_IDLE;
465 case TAPI_CALL_STATE_ACTIVE:
466 pImpl->__curCallState = CALL_STATUS_COMMUNICATING;
468 case TAPI_CALL_STATE_HELD:
469 pImpl->__curCallState = CALL_STATUS_HOLDING;
471 case TAPI_CALL_STATE_INCOMING:
472 pImpl->__curCallState = CALL_STATUS_RINGING;
474 case TAPI_CALL_STATE_DIALING:
475 case TAPI_CALL_STATE_ALERT:
476 pImpl->__curCallState = CALL_STATUS_DIALING;
486 _CallManagerImpl::OnCallTypeCallback(TelCallStatus_t* status, void* pUserData)
488 CallType* pCallType = static_cast<CallType*>(pUserData);
490 switch (status->CallType)
492 case TAPI_CALL_TYPE_VOICE:
493 *pCallType = TYPE_VOICE_CALL;
495 case TAPI_CALL_TYPE_DATA:
496 *pCallType = TYPE_VIDEO_CALL;
506 _CallManagerImpl::IsPhoneNumberValid(const String& phoneNumber) const
512 if (phoneNumber.StartsWith("+", 0))
517 for (int i = startIndex; i < phoneNumber.GetLength(); i++)
519 phoneNumber.GetCharAt(i, chr);
521 if (!Character::IsDigit(chr))
531 _CallManagerImpl::InitializeInternalCallStatus(void)
533 int err = TAPI_API_SUCCESS;
534 result r = E_SUCCESS;
536 err = tel_get_call_status_all(__pHandle, OnCallStatusCallback, this);
537 SysLog(NID_TEL, "The tel_get_call_status_all() returned %d value", err);
539 if (err != TAPI_API_SUCCESS)
541 if (err == TAPI_API_OPERATION_FAILED)
543 __curCallState = CALL_STATUS_IDLE;
555 _CallManagerImpl::GetPhoneNumber(TapiHandle* pCallHandle, int callId) const
557 int err = TAPI_API_SUCCESS;
560 TelCallStatus_t callStatus = {};
561 err = tel_get_call_status(pCallHandle, callId, &callStatus);
562 if (err == TAPI_API_SUCCESS)
564 (void)(StringUtil::Utf8ToString(callStatus.pNumber, phoneNumber));
565 SysLog(NID_TEL, "The phone number is %ls", phoneNumber.GetPointer());
569 SysLog(NID_TEL, "The tel_get_call_status_all() returned %d value", err);
576 _CallManagerImpl::GetStringOfCallState(void) const
578 static const char* pStateStr[] =
580 "CALL_STATUS_UNDEFINED",
582 "CALL_STATUS_ACTIVE",
583 "CALL_STATUS_COMMUNICATING",
584 "CALL_STATUS_RINGING",
585 "CALL_STATUS_DIALING",
586 "CALL_STATUS_HOLDING"
589 return pStateStr[__curCallState + 1];
593 _CallManagerImpl::GetStringOfCallFwdState(void) const
595 static const char* pFwdStateStr[] =
598 "CALL_FORWARD_REQUESTING",
599 "CALL_FORWARD_ON_SERVICE",
600 "CALL_FORWARD_STOPPING"
603 return pFwdStateStr[__curCallFwdState];
607 _CallManagerImpl::GetStringOfCallEventType(int type) const
609 static const char* pEventType[] =
612 "Voice Communicating",
617 "Video Communicating",
624 return pEventType[type];
628 _CallManagerImpl::GetInstance(CallManager& callManager)
630 return callManager.__pCallManagerImpl;
633 const _CallManagerImpl*
634 _CallManagerImpl::GetInstance(const CallManager& callManager)
636 return callManager.__pCallManagerImpl;
639 }} // Tizen::Telephony