Tizen 2.0 Release
[apps/osp/Phone.git] / src / PhnTelephonyManager.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://floralicense.org/license/
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an AS IS BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 /**
18  * @file        PhnTelephonyManager.cpp
19  * @brief       Call log item provider
20  */
21 #include <stdio.h>
22 #include <FBaseSys.h>
23 #include <FSystem.h>
24 #include "ITapiModem.h"
25 #include "ITapiSim.h"
26 #include "PhnCallInfo.h"
27 #include "PhnTelephonyManager.h"
28 #include "PhnSettingsManager.h"
29 #include "PhnTypes.h"
30
31 using namespace Tizen::Base;
32 using namespace Tizen::Graphics;
33 using namespace Tizen::Social;
34 using namespace Tizen::System;
35 using namespace Tizen::Base::Collection;
36
37 const char* callEventList[] = {
38                 TAPI_NOTI_VOICE_CALL_STATUS_IDLE,
39                 TAPI_NOTI_VOICE_CALL_STATUS_ACTIVE,
40                 TAPI_NOTI_VOICE_CALL_STATUS_HELD,
41                 TAPI_NOTI_VOICE_CALL_STATUS_DIALING,
42                 TAPI_NOTI_VOICE_CALL_STATUS_ALERT,
43                 /*TAPI_NOTI_VOICE_CALL_STATUS_INCOMING,*/
44                 TAPI_NOTI_VOICE_CALL_STATUS_WAITING,
45                 TAPI_NOTI_CALL_INFO_CALL_CONNECTED_LINE,
46                 TAPI_NOTI_CALL_INFO_WAITING,
47                 TAPI_NOTI_CALL_INFO_CUG,
48                 TAPI_NOTI_CALL_INFO_FORWARDED,
49                 TAPI_NOTI_CALL_INFO_BARRED_INCOMING,
50                 TAPI_NOTI_CALL_INFO_BARRED_OUTGOING,
51                 TAPI_NOTI_CALL_INFO_DEFLECTED,
52                 TAPI_NOTI_CALL_INFO_CLIR_SUPPRESSION_REJECT,
53                 TAPI_NOTI_CALL_INFO_FORWARD_UNCONDITIONAL,
54                 TAPI_NOTI_CALL_INFO_FORWARD_CONDITIONAL,
55                 TAPI_NOTI_CALL_INFO_CALL_LINE_IDENTITY,
56                 TAPI_NOTI_CALL_INFO_CALL_NAME_INFORMATION,
57                 TAPI_NOTI_CALL_INFO_FORWARDED_CALL,
58                 TAPI_NOTI_CALL_INFO_CUG_CALL,
59                 TAPI_NOTI_CALL_INFO_DEFLECTED_CALL,
60                 TAPI_NOTI_CALL_INFO_TRANSFERED_CALL,
61                 TAPI_NOTI_CALL_INFO_HELD,
62                 TAPI_NOTI_CALL_INFO_ACTIVE,
63                 TAPI_NOTI_CALL_INFO_JOINED,
64                 TAPI_NOTI_CALL_INFO_RELEASED_ON_HOLD,
65                 TAPI_NOTI_CALL_INFO_TRANSFER_ALERT,
66                 TAPI_NOTI_CALL_INFO_TRANSFERED,
67                 TAPI_NOTI_CALL_INFO_CF_CHECK_MESSAGE,
68 };
69
70 TelephonyManager* TelephonyManager::__pManager = null;
71
72 TelephonyManager::TelephonyManager(ITelephonyEventListener* pEventListener)
73 : __pEventListener(pEventListener)
74 {
75         __pDialedCall = null;
76         __pIncomingCall = null;
77         __pActiveCallList = null;
78         __pSettingsManager = null;
79         __pTapiHandle = null;
80         __isIncomingCallPresent = false;
81         __pAddressBook = null;
82         __pCachedContact = null;
83         __isMuted = false;
84         __isSpeakerOn = false;
85         __pSoundManager = null;
86         __pCalllogMgr = null;
87 }
88
89 TelephonyManager::~TelephonyManager(void)
90 {
91         if (__pActiveCallList != null)
92         {
93                 delete __pActiveCallList;
94         }
95
96         if (__pDialedCall != null)
97         {
98                 delete __pDialedCall;
99                 __pDialedCall = null;
100         }
101
102         if (__pIncomingCall != null)
103         {
104                 delete __pIncomingCall;
105                 __pIncomingCall = null;
106         }
107
108         if (__pAddressBook != null)
109         {
110                 delete __pAddressBook;
111                 __pAddressBook = null;
112         }
113         if (__pCachedContact != null)
114         {
115                 delete __pCachedContact;
116                 __pCachedContact = null;
117         }
118
119         //unregister for events from TAPI Lib.
120         UnregisterEvents();
121
122         //De-initialize the TAPI Library
123         if(__pTapiHandle != null)
124         {
125                 tel_deinit(__pTapiHandle);
126         }
127
128         if (__pSoundManager != null)
129         {
130                 delete __pSoundManager;
131         }
132
133         if (__pCalllogMgr)
134         {
135                 __pCalllogMgr = null;
136         }
137 }
138
139 TelephonyManager*
140 TelephonyManager::GetInstance(ITelephonyEventListener* pEventListener)
141 {
142         if (__pManager == null)
143         {
144                 CreateInstance(pEventListener);
145         }
146         return __pManager;
147 }
148
149 void
150 TelephonyManager::CreateInstance(ITelephonyEventListener* pEventListener)
151 {
152         __pManager = new (std::nothrow) TelephonyManager(pEventListener);
153         result r = __pManager->Initialize();
154         if (IsFailed(r))
155         {
156                 delete __pManager;
157                 __pManager = null;
158         }
159         atexit(&(TelephonyManager::DestroyInstance));
160 }
161
162 void
163 TelephonyManager::DestroyInstance(void)
164 {
165         if (__pManager != null)
166         {
167                 __pManager->EndAllCalls();
168                 delete __pManager;
169                 __pManager = null;
170         }
171 }
172
173 result
174 TelephonyManager::Initialize(void)
175 {
176         //Initialize telephony library
177         result r = InitializeTelephonyLibrary();
178         if (IsFailed(r))
179         {
180                 return r;
181         }
182         __pActiveCallList = new (std::nothrow) HashMapT<long, CallInfo>();
183         __pActiveCallList->Construct(IDI_MAX_ACTIVE_CALLS);
184
185         //Initialize the Settings Manager to fetch call settings
186         __pSettingsManager = SettingsManager::GetInstance();
187
188         //initialize address book to fetch contacts information
189         __pAddressBook = new (std::nothrow) Addressbook();
190         r = __pAddressBook->Construct();
191         if (IsFailed(r))
192         {
193                 //TODO: handle the issue: Out of memory, etx.
194                 return r;
195         }
196         __pSoundManager = new (std::nothrow) SoundManager();
197         __pCalllogMgr = CallLogManager::GetInstance();
198         return r;
199 }
200
201 result
202 TelephonyManager::InitializeTelephonyLibrary(void)
203 {
204         result r = E_FAILURE;
205
206         __pTapiHandle = tel_init(null);
207         if (__pTapiHandle != null)
208         {
209                 //register telephony events
210                 int errorCode = RegisterEvents();
211                 if (errorCode == TAPI_CAUSE_SUCCESS)
212                 {
213                         r = E_SUCCESS;
214                 }
215         }
216
217         //TAPI Library is initialized and events registered successfully
218         return r;
219 }
220
221 int
222 TelephonyManager::RegisterEvents(void)
223 {
224         int errCode = -1;
225         int eventCount = sizeof(callEventList) / sizeof(char *);
226         for (int index = 0; index < eventCount; index++)
227         {
228                 errCode = tel_register_noti_event(__pTapiHandle, callEventList[index], &HandleCallback, this);
229                 if (errCode != TAPI_API_SUCCESS)
230                 {
231                         return errCode;
232                 }
233         }
234         return errCode;
235 }
236
237 void
238 TelephonyManager::UnregisterEvents(void)
239 {
240         int eventCount = sizeof(callEventList) / sizeof(char *);
241         for (int index = 0; index < eventCount; index++)
242         {
243                 tel_deregister_noti_event(__pTapiHandle, callEventList[index]);
244         }
245 }
246
247 ErrorCodes
248 TelephonyManager::SetupMoCall(String& contactNumber, bool isEmergency)
249 {
250         ErrorCodes r = ERROR_TAPI_ERROR;
251         result res = E_SUCCESS;
252
253         res = CheckValidTelePhoneNumber(contactNumber);
254         if (IsFailed(res))
255         {
256                 return ERROR_INVALID_NUMBER;
257         }
258
259         //if dialing an emeregency call and active calls exist
260         //then end all active calls.
261         if (isEmergency && __pActiveCallList->GetCount() > 0)
262         {
263                 //Get first call handle
264                 CallInfo endCallInfo;
265                 IListT<CallInfo>* pCallList = __pActiveCallList->GetValuesN();
266                 pCallList->GetAt(0, endCallInfo);
267                 int callHandle = endCallInfo.GetCallHandle()->ToLong();
268                 delete pCallList;
269                 pCallList = null;
270
271                 //release all active or held calls
272                 int tapires = tel_end_call(__pTapiHandle, callHandle, TAPI_CALL_END_ALL, &HandleCallbackResponse, this);
273                 if (tapires == TAPI_CAUSE_SUCCESS)
274                 {
275                         __pActiveCallList->RemoveAll();
276                         r = ERROR_NONE;
277                         res = E_SUCCESS;
278                 }
279                 else
280                 {
281                         r = ERROR_TAPI_ERROR;
282                         return r;
283                 }
284         }
285         else if (__pActiveCallList->GetCount() == 1)
286         {
287                 //Check if there is already an active call,
288                 //Put the already active call on hold.
289                 CallInfo holdCallInfo;
290                 IListT<CallInfo>* pCallList = __pActiveCallList->GetValuesN();
291
292                 pCallList->GetAt(0, holdCallInfo);
293                 //Check if call is active, then put on hold
294                 if (holdCallInfo.IsOnHold() == false)
295                 {
296                         res = HoldActiveCall(&holdCallInfo, true);
297                 }
298                 delete pCallList;
299                 pCallList = null;
300         }
301
302         //make the next call, only if any existing active call
303         //is successfully put on hold or is already on hold.
304         //make the next call, only if any existing active call
305         //is successfully put on hold or is already on hold.
306         if (res == E_SUCCESS)
307         {
308                 res = DialOutgoingCall(contactNumber, isEmergency);
309         }
310         if(res == E_SUCCESS)
311         {
312                 return ERROR_NONE;
313         }
314         {
315                 return ERROR_TAPI_ERROR;
316         }
317 }
318
319 void
320 TelephonyManager::EndAllCalls(void)
321 {
322         if(__pDialedCall != null)
323         {
324                 if(__pDialedCall->GetCallHandle() != null)
325                 {
326                         tel_end_call(__pTapiHandle, __pDialedCall->GetCallHandle()->ToLong(), TAPI_CALL_END, &HandleCallbackResponse, this);
327                 }
328         }
329         tel_end_call(__pTapiHandle, -1, TAPI_CALL_END_HOLD_ALL, &HandleCallbackResponse, this);
330         //end all active calls before terminating application
331         tel_end_call(__pTapiHandle, -1, TAPI_CALL_END_ALL, &HandleCallbackResponse, this);
332 }
333
334 result
335 TelephonyManager::EndCall(Long callHandle)
336 {
337         result r = E_SUCCESS;
338         CallInfo endCall;
339         bool endDialedCall = false;
340
341         //fetch ended callInfo
342         IListT<CallInfo>* pCallList = __pActiveCallList->GetValuesN();
343         int callCount = pCallList->GetCount();
344         for (int index = 0; index < callCount; index++)
345         {
346                 pCallList->GetAt(index, endCall);
347                 if(endCall.GetCallHandle()->Equals(callHandle))
348                 {
349                         //Found the call to be ended.
350                         r = E_SUCCESS;
351                         break;
352                 }
353
354         }
355         delete pCallList;
356         pCallList = null;
357
358         if (r == E_SUCCESS && __pDialedCall != null)
359         {
360                 if (__pDialedCall->GetCallHandle()->Equals(callHandle) )
361                 {
362                         r = E_SUCCESS;
363                         endCall = *__pDialedCall;
364                         endDialedCall = true;
365                 }
366
367         }
368
369         if (r == E_SUCCESS)
370         {
371                 unsigned int callHandle = -1;
372                 if (endCall.GetCallHandle() != null)
373                 {
374                         callHandle = endCall.GetCallHandle()->ToLong();
375                         TelCallEndType_t endType = TAPI_CALL_END;
376                         int res = -1;
377                         res = tel_end_call(__pTapiHandle, callHandle, endType, &HandleEndDialedCallResponse, this);
378
379                         if (res == TAPI_CAUSE_SUCCESS)
380                         {
381                                 if (endDialedCall == true)
382                                 {
383                                         String endCause(L"Call Rejected");
384                                         __pDialedCall->SetEndCallCause(endCause);
385                                 }
386                                 r = E_SUCCESS;
387                         }
388                         else
389                         {
390                                 r = E_FAILURE;
391                         }
392                 }
393                 else
394                 {
395                         r = E_FAILURE;
396                 }
397         }
398         return r;
399 }
400
401 result
402 TelephonyManager::EndCall(String& contactNumber)
403 {
404         result r = E_SUCCESS;
405         CallInfo endCall;
406         bool endDialedCall = false;
407         if (contactNumber.IsEmpty())
408         {
409                 return E_FAILURE;
410         }
411
412         //fetch ended callInfo
413         IListT<CallInfo>* pCallList = __pActiveCallList->GetValuesN();
414         int callCount = pCallList->GetCount();
415         for (int index = 0; index < callCount; index++)
416         {
417                 pCallList->GetAt(index, endCall);
418                 if (endCall.GetContactNumber().Equals(contactNumber))
419                 {
420                         //Found the call to be ended.
421                         r = E_SUCCESS;
422                         break;
423                 }
424         }
425         delete pCallList;
426         pCallList = null;
427
428         if (r == E_SUCCESS && __pDialedCall != null)
429         {
430                 if (__pDialedCall->GetContactNumber().Equals(contactNumber))
431                 {
432                         r = E_SUCCESS;
433                         endCall = *__pDialedCall;
434                         endDialedCall = true;
435                 }
436         }
437
438         if (r == E_SUCCESS)
439         {
440                 unsigned int callHandle = -1;
441                 if (endCall.GetCallHandle() != null)
442                 {
443                         callHandle = endCall.GetCallHandle()->ToLong();
444                         TelCallEndType_t endType = TAPI_CALL_END;
445                         int res = -1;
446                         res = tel_end_call(__pTapiHandle, callHandle, endType, &HandleEndDialedCallResponse, this);
447
448                         if (res == TAPI_CAUSE_SUCCESS)
449                         {
450                                 if (endDialedCall == true)
451                                 {
452                                         String endCause(L"Call Rejected");
453                                         __pDialedCall->SetEndCallCause(endCause);
454                                 }
455                                 r = E_SUCCESS;
456                         }
457                         else
458                         {
459                                 r = E_FAILURE;
460                         }
461                 }
462                 else
463                 {
464                         r = E_FAILURE;
465                 }
466         }
467         return r;
468 }
469
470 result
471 TelephonyManager::AnswerCall(int callHandle, bool acceptCall)
472 {
473         result r = E_FAILURE;
474         __pSoundManager->StopAlert();
475         TelCallAnswerType_t answerType = TAPI_CALL_ANSWER_ACCEPT;
476         int res = -1;
477         if (acceptCall == true)
478         {
479                 answerType = TAPI_CALL_ANSWER_ACCEPT;
480                 // redirect to dummy call back handler as the flow already handled in registered event callback
481                 res = tel_answer_call(__pTapiHandle, callHandle, answerType, &HandleCallbackResponse, this);
482         }
483         else
484         {
485                 answerType = TAPI_CALL_ANSWER_REJECT;
486                 // redirect to reject call back handler as the flow has to be handled
487                 res = tel_answer_call(__pTapiHandle, callHandle, answerType, &HandleRejectCallbackResponse, this);
488         }
489
490         if (res == TAPI_CAUSE_SUCCESS)
491         {
492                 r = E_SUCCESS;
493         }
494         else
495         {
496                 r = E_FAILURE;
497         }
498         return r;
499 }
500
501 result
502 TelephonyManager::AcceptCall(CallAnswerOptions answerOptions,int callHandle)
503 {
504         result r = E_FAILURE;
505         __pSoundManager->StopAlert();
506         __pSoundManager->SetSoundMode(SOUND_MODE_VOICE);
507
508         if (__pActiveCallList->GetCount())
509         {
510                 if (__pActiveCallList->GetCount() == 1)
511                 {
512                         r = AcceptSecondCall(answerOptions,callHandle);
513                 }
514                 else
515                 {
516                         r = AcceptMultipleCall(answerOptions,callHandle);
517                         if (__pIncomingCall != null)
518                         {
519                                 delete __pIncomingCall;
520                                 __pIncomingCall = null;
521                         }
522                 }
523
524                 return r;
525         }
526         else
527         {
528                 return r;
529         }
530 }
531
532 result
533 TelephonyManager::AcceptSecondCall(CallAnswerOptions answerOptions,int callHandle)
534 {
535         result r = E_FAILURE;
536         IListT<CallInfo>* pCallList = __pActiveCallList->GetValuesN();
537         int res = -1;
538         CallInfo* pFirstCallInfo  = new (std::nothrow) CallInfo();
539         pCallList->GetAt(0,*pFirstCallInfo);
540         delete pCallList;
541         pCallList = null;
542         switch (answerOptions)
543         {
544         case CALL_ANSWER_HOLD_ACCEPT:
545         {
546                 //todo: try answering call with option as TAPI_CALL_ANSWER_HOLD_AND_ACCEPT
547                 if (pFirstCallInfo->IsConferenceCall() == false)
548                 {
549                         r = HoldActiveCall(pFirstCallInfo,true);
550                 }
551                 else
552                 {
553                         r = HoldConferenceCall(true);
554                 }
555
556                 if (callHandle == (unsigned int)__pIncomingCall->GetCallHandle()->ToLong())
557                 {
558                         //handle call connected - save info
559                         String contactNo;
560                         contactNo.Append(__pIncomingCall->GetContactNumber());
561                         result r = FetchContactInfoForNumber(contactNo);
562                         if (!IsFailed(r))
563                         {
564                                 __pIncomingCall->SetContactInfo(*__pCachedContact);
565                         }
566                 }
567                 else
568                 {
569                         delete __pIncomingCall;
570                         TelCallStatus_t callStatus;
571                         tel_get_call_status(__pTapiHandle, callHandle, &callStatus);
572                         __pIncomingCall = new (std::nothrow) CallInfo();
573                         __pIncomingCall->SetCallHandle(callHandle);
574                         __pIncomingCall->SetCalllogType(CALL_LOG_TYPE_VOICE_INCOMING);
575                         String contactNumber(callStatus.pNumber);
576                         __pIncomingCall->SetContactNumber(contactNumber);
577                         result r = FetchContactInfoForNumber(contactNumber);
578                         if (!IsFailed(r))
579                         {
580                                 __pIncomingCall->SetContactInfo(*__pCachedContact);
581                         }
582                         //set emergency state
583                         if(callStatus.CallType == TAPI_CALL_TYPE_E911)
584                         {
585                                 __pIncomingCall->SetEmergency(true);
586                         }
587                         else
588                         {
589                                 __pIncomingCall->SetEmergency(false);
590                         }
591                         //set start time, when call is connected
592                         long long startTime = 0;
593                         SystemTime::GetTicks(startTime);
594                         __pIncomingCall->SetCallNotificationTime(startTime);
595                 }
596                 //set start time, when call is connected
597                 long long startTime = 0;
598                 SystemTime::GetTicks(startTime);
599                 __pIncomingCall->SetCallConnectTime(startTime);
600                 r = E_SUCCESS;
601                 break;
602         }
603         case CALL_ANSWER_END_ACTIVE_ACCEPT:
604         {
605                 //todo: try answering call with option as TAPI_CALL_ANSWER_REPLACE
606                 __pActiveCallList->RemoveAll();
607                 if (pFirstCallInfo->IsConferenceCall() == false)
608                 {
609                         r = HoldActiveCall(pFirstCallInfo,true);
610                 }
611                 else
612                 {
613                         res = tel_hold_call(__pTapiHandle, pFirstCallInfo->GetCallHandle()->ToLong(), &HandleCallbackResponse, this);
614                 }
615                 // call should be active now. end the active call now
616                 if (pFirstCallInfo->IsConferenceCall() == false)
617                 {
618                         TelCallEndType_t endType = TAPI_CALL_END;
619                         unsigned int callHandleToBeEnded = pFirstCallInfo->GetCallHandle()->ToLong();
620                         tel_end_call(__pTapiHandle, callHandleToBeEnded, endType, &HandleCallbackResponse, this);
621                         //Add call ended to call log database
622                         __pCalllogMgr->AddCallogInfoToDatabase(pFirstCallInfo);
623                 }
624                 else
625                 {
626                         int confCallCount = pFirstCallInfo->GetCallerListCount();
627                         IListT<CallInfo>* pCallList = pFirstCallInfo->GetCallerList();
628                         for (int index = 0; index < confCallCount; index++)
629                         {
630                                 CallInfo callInfo;
631                                 pCallList->GetAt(index, callInfo);
632                                 //Add call ended to call log database
633                                 __pCalllogMgr->AddCallogInfoToDatabase(&callInfo);
634                         }
635                         unsigned int callHandleToBeEnded = pFirstCallInfo->GetCallHandle()->ToLong();
636                         TelCallEndType_t endType = TAPI_CALL_END_HOLD_ALL;
637                         tel_end_call(__pTapiHandle, callHandleToBeEnded, endType, &HandleCallbackResponse, this);
638                 }
639                 r = E_SUCCESS;
640
641                 if (callHandle == (unsigned int)__pIncomingCall->GetCallHandle()->ToLong())
642                 {
643                         //handle call connected - save info
644                         String contactNo;
645                         contactNo.Append(__pIncomingCall->GetContactNumber());
646                         result r = FetchContactInfoForNumber(contactNo);
647                         if (!IsFailed(r))
648                         {
649                                 __pIncomingCall->SetContactInfo(*__pCachedContact);
650                         }
651                 }
652                 else
653                 {
654                         delete __pIncomingCall;
655                         TelCallStatus_t callStatus;
656                         tel_get_call_status(__pTapiHandle, callHandle, &callStatus);
657                         __pIncomingCall = new (std::nothrow) CallInfo();
658                         __pIncomingCall->SetCallHandle(callHandle);
659                         __pIncomingCall->SetCalllogType(CALL_LOG_TYPE_VOICE_INCOMING);
660                         String contactNumber(callStatus.pNumber);
661                         __pIncomingCall->SetContactNumber(contactNumber);
662                         result r = FetchContactInfoForNumber(contactNumber);
663                         if (!IsFailed(r))
664                         {
665                                 __pIncomingCall->SetContactInfo(*__pCachedContact);
666                         }
667                         //set emergency state
668                         if(callStatus.CallType == TAPI_CALL_TYPE_E911)
669                         {
670                                 __pIncomingCall->SetEmergency(true);
671                         }
672                         else
673                         {
674                                 __pIncomingCall->SetEmergency(false);
675                         }
676                         //set start time, when call is connected
677                         long long startTime = 0;
678                         SystemTime::GetTicks(startTime);
679                         __pIncomingCall->SetCallNotificationTime(startTime);
680                 }
681                 //set start time, when call is connected
682                 long long startTime = 0;
683                 SystemTime::GetTicks(startTime);
684                 __pIncomingCall->SetCallConnectTime(startTime);
685                 break;
686         }
687         default:
688                 break;
689         }
690         delete pFirstCallInfo;
691         return r;
692 }
693
694 result
695 TelephonyManager::AcceptMultipleCall(CallAnswerOptions answerOptions,int callHandle)
696 {
697         result r = E_FAILURE;
698         IListT<CallInfo>* pCallList = __pActiveCallList->GetValuesN();
699         IListT<long>* pKeyList = __pActiveCallList->GetKeysN();
700         long firstKey;
701         long secondKey;
702         long activeCallKey;
703         long heldCallKey;
704         CallInfo* pFirstCallInfo = new (std::nothrow) CallInfo();
705         pCallList->GetAt(0,*pFirstCallInfo);
706         pKeyList->GetAt(0,firstKey);
707         CallInfo* pSecondCallInfo = new (std::nothrow) CallInfo();
708         pCallList->GetAt(1,*pSecondCallInfo);
709         pKeyList->GetAt(1,secondKey);
710         delete pCallList;
711         delete pKeyList;
712         CallInfo heldCall;
713         CallInfo activeCall;
714         if (pFirstCallInfo->IsOnHold() == false)
715         {
716                 activeCall = *pFirstCallInfo;
717                 activeCallKey = firstKey;
718                 heldCall = *pSecondCallInfo;
719                 heldCallKey = secondKey;
720         }
721         else
722         {
723                 activeCall = *pSecondCallInfo;
724                 activeCallKey = secondKey;
725                 heldCall = *pFirstCallInfo;
726                 heldCallKey = firstKey;
727         }
728         delete pFirstCallInfo;
729         delete pSecondCallInfo;
730
731         switch (answerOptions)
732         {
733         case CALL_ANSWER_END_ACTIVE_ACCEPT:
734         {
735                 //todo: try answering call with option as TAPI_CALL_ANSWER_REPLACE
736                 __pActiveCallList->Remove(activeCallKey);
737                 TelCallStatus_t callStatus;
738                 int res = tel_get_call_status(__pTapiHandle, callHandle, &callStatus);
739                 if (res == TAPI_CAUSE_SUCCESS)
740                 {
741                         CallInfo* pCallInfo = new (std::nothrow) CallInfo();
742                         pCallInfo->SetCallHandle(callHandle);
743
744                         String contactNumber(callStatus.pNumber);
745                         pCallInfo->SetContactNumber(contactNumber);
746                         result r = FetchContactInfoForNumber(contactNumber);
747                         if (!IsFailed(r))
748                         {
749                                 pCallInfo->SetContactInfo(*__pCachedContact);
750                         }
751                         //set emergency state
752                         if(callStatus.CallType == TAPI_CALL_TYPE_E911)
753                         {
754                                 pCallInfo->SetEmergency(true);
755                         }
756                         else
757                         {
758                                 pCallInfo->SetEmergency(false);
759                         }
760                         //set start time, when call is connected
761                         long long startTime = 0;
762                         SystemTime::GetTicks(startTime);
763                         pCallInfo->SetCallConnectTime(startTime);
764                         pCallInfo->SetCallNotificationTime(startTime);
765
766                         //transfer ownership to Active calls list
767                         __pActiveCallList->Add(callHandle, *(pCallInfo));
768                         pCallInfo = null;
769                 }
770
771                 TelCallEndType_t endType = TAPI_CALL_END;
772                 if (activeCall.IsConferenceCall() == false)
773                 {
774                         unsigned int callHandleToBeEnded = activeCall.GetCallHandle()->ToLong();
775                         tel_end_call(__pTapiHandle, callHandleToBeEnded, endType, &HandleCallbackResponse, this);
776                         //Add call ended to call log database
777                         __pCalllogMgr->AddCallogInfoToDatabase(&activeCall);
778                 }
779                 else
780                 {
781                         int confCallCount = activeCall.GetCallerListCount();
782                         IListT<CallInfo>* pCallList = activeCall.GetCallerList();
783                         for (int index = 0; index < confCallCount; index++)
784                         {
785                                 CallInfo callInfo;
786                                 pCallList->GetAt(index, callInfo);
787                                 unsigned int calloBeEnded = callInfo.GetCallHandle()->ToLong();
788                                 //Add call ended to call log database
789                                 __pCalllogMgr->AddCallogInfoToDatabase(&callInfo);
790                                 tel_end_call(__pTapiHandle, calloBeEnded, endType, &HandleCallbackResponse, this);
791                         }
792                 }
793                 if (callStatus.CallState == TAPI_CALL_STATE_WAITING || callStatus.CallState == TAPI_CALL_STATE_INCOMING)
794                 {
795                         res = tel_active_call(__pTapiHandle, callHandle, &HandleCallbackResponse, this);
796                         if (res == TAPI_CAUSE_SUCCESS)
797                         {
798                                 r = E_SUCCESS;
799                         }
800                         else
801                         {
802                                 r = E_FAILURE;
803                         }
804                 }
805                 break;
806         }
807         case CALL_ANSWER_END_HELD_ACCEPT:
808         {
809                 unsigned int callHandleToBeEnded = heldCall.GetCallHandle()->ToLong();
810                 __pActiveCallList->Remove(heldCallKey);
811                 TelCallStatus_t callStatus;
812                 int res = tel_get_call_status(__pTapiHandle, callHandle, &callStatus);
813                 if (res == TAPI_CAUSE_SUCCESS)
814                 {
815                         CallInfo* pCallInfo = new (std::nothrow) CallInfo();
816                         pCallInfo->SetCallHandle(callHandle);
817
818                         String contactNumber(callStatus.pNumber);
819                         pCallInfo->SetContactNumber(contactNumber);
820                         result r = FetchContactInfoForNumber(contactNumber);
821                         if (!IsFailed(r))
822                         {
823                                 pCallInfo->SetContactInfo(*__pCachedContact);
824                         }
825                         //set emergency state
826                         if(callStatus.CallType == TAPI_CALL_TYPE_E911)
827                         {
828                                 pCallInfo->SetEmergency(true);
829                         }
830                         else
831                         {
832                                 pCallInfo->SetEmergency(false);
833                         }
834                         //set start time, when call is connected
835                         long long startTime = 0;
836                         SystemTime::GetTicks(startTime);
837                         pCallInfo->SetCallConnectTime(startTime);
838                         pCallInfo->SetCallNotificationTime(__pIncomingCall->GetCallNotificationTime());
839
840                         //transfer ownership to Active calls list
841                         __pActiveCallList->Add(callHandle, *(pCallInfo));
842                         pCallInfo = null;
843                 }
844                 TelCallEndType_t endType = TAPI_CALL_END;
845                 if (heldCall.IsConferenceCall() == false)
846                 {
847                         tel_end_call(__pTapiHandle, callHandleToBeEnded, endType, &HandleCallbackResponse, this);
848                         //Add call ended to call log database
849                         __pCalllogMgr->AddCallogInfoToDatabase(&heldCall);
850                 }
851                 else
852                 {
853                         int confCallCount = heldCall.GetCallerListCount();
854                         IListT<CallInfo>* pCallList = heldCall.GetCallerList();
855                         for (int index = 0; index < confCallCount; index++)
856                         {
857                                 CallInfo callInfo;
858                                 pCallList->GetAt(index, callInfo);
859                                 //Add call ended to call log database
860                                 __pCalllogMgr->AddCallogInfoToDatabase(&callInfo);
861                                 unsigned int calloBeEnded = callInfo.GetCallHandle()->ToLong();
862                                 tel_end_call(__pTapiHandle, calloBeEnded, endType, &HandleCallbackResponse, this);
863                         }
864                 }
865                 //Set held flag on active call
866                 CallInfo* pHeldCallInfo = new (std::nothrow) CallInfo();
867                 //copy state into new callinfo object
868                 *pHeldCallInfo = activeCall;
869                 //set call to hold state
870                 pHeldCallInfo->SetOnHold(true);
871                 //replace old object with new
872                 __pActiveCallList->SetValue(activeCallKey, *pHeldCallInfo);
873                 if (callStatus.CallState == TAPI_CALL_STATE_WAITING || callStatus.CallState == TAPI_CALL_STATE_INCOMING)
874                 {
875                         res = tel_active_call(__pTapiHandle, callHandle, &HandleCallbackResponse, this);
876                         if (res == TAPI_CAUSE_SUCCESS)
877                         {
878                                 r = E_SUCCESS;
879                         }
880                         else
881                         {
882                                 r = E_FAILURE;
883                         }
884                 }
885                 break;
886         }
887         case CALL_ANSWER_END_ALL_ACCEPT:
888         {
889                 unsigned int callHandleToBeEnded = activeCall.GetCallHandle()->ToLong();
890                 __pActiveCallList->RemoveAll();
891                 TelCallEndType_t endType = TAPI_CALL_END;
892                 if (activeCall.IsConferenceCall() == false)
893                 {
894                         tel_end_call(__pTapiHandle, callHandleToBeEnded, endType, &HandleCallbackResponse, this);
895                         //Add call ended to call log database
896                         __pCalllogMgr->AddCallogInfoToDatabase(&activeCall);
897                 }
898                 else
899                 {
900                         int confCallCount = activeCall.GetCallerListCount();
901                         IListT<CallInfo>* pCallList = activeCall.GetCallerList();
902                         for (int index = 0; index < confCallCount; index++)
903                         {
904                                 CallInfo callInfo;
905                                 pCallList->GetAt(index, callInfo);
906                                 //Add call ended to call log database
907                                 __pCalllogMgr->AddCallogInfoToDatabase(&callInfo);
908                                 unsigned int calloBeEnded = callInfo.GetCallHandle()->ToLong();
909                                 tel_end_call(__pTapiHandle, calloBeEnded, endType, &HandleCallbackResponse, this);
910                         }
911                 }
912                 callHandleToBeEnded = heldCall.GetCallHandle()->ToLong();
913                 if (heldCall.IsConferenceCall() == false)
914                 {
915                         tel_end_call(__pTapiHandle, callHandleToBeEnded, endType, &HandleCallbackResponse, this);
916                         //Add call ended to call log database
917                         __pCalllogMgr->AddCallogInfoToDatabase(&heldCall);
918                 }
919                 else
920                 {
921                         int confCallCount = heldCall.GetCallerListCount();
922                         IListT<CallInfo>* pCallList = heldCall.GetCallerList();
923                         for (int index = 0; index < confCallCount; index++)
924                         {
925                                 CallInfo callInfo;
926                                 pCallList->GetAt(index, callInfo);
927                                 //Add call ended to call log database
928                                 __pCalllogMgr->AddCallogInfoToDatabase(&callInfo);
929                                 unsigned int calloBeEnded = callInfo.GetCallHandle()->ToLong();
930                                 tel_end_call(__pTapiHandle, calloBeEnded, endType, &HandleCallbackResponse, this);
931                         }
932                 }
933                 TelCallStatus_t callStatus;
934                 int res = tel_get_call_status(__pTapiHandle, callHandle, &callStatus);
935                 if (callStatus.CallState == TAPI_CALL_STATE_WAITING || callStatus.CallState == TAPI_CALL_STATE_INCOMING)
936                 {
937                         res = tel_active_call(__pTapiHandle, callHandle, &HandleCallbackResponse, this);
938                         if (res == TAPI_CAUSE_SUCCESS)
939                         {
940                                 r = E_SUCCESS;
941                                 CallInfo* pCallInfo = null;
942                                 if (callHandle == (unsigned int)__pIncomingCall->GetCallHandle()->ToLong())
943                                 {
944                                         //handle call connected - save info
945                                         pCallInfo = new (std::nothrow) CallInfo();
946                                         *pCallInfo = *(__pIncomingCall);
947                                         String contactNo;
948                                         contactNo.Append(pCallInfo->GetContactNumber());
949                                         result r = FetchContactInfoForNumber(contactNo);
950                                         if (!IsFailed(r))
951                                         {
952                                                 pCallInfo->SetContactInfo(*__pCachedContact);
953                                         }
954                                 }
955                                 else
956                                 {
957                                         TelCallStatus_t callStatus;
958                                         tel_get_call_status(__pTapiHandle, callHandle, &callStatus);
959                                         pCallInfo = new (std::nothrow) CallInfo();
960                                         pCallInfo->SetCallHandle(callHandle);
961                                         pCallInfo->SetCalllogType(CALL_LOG_TYPE_VOICE_INCOMING);
962                                         String contactNumber(callStatus.pNumber);
963                                         pCallInfo->SetContactNumber(contactNumber);
964                                         result r = FetchContactInfoForNumber(contactNumber);
965                                         if (!IsFailed(r))
966                                         {
967                                                 pCallInfo->SetContactInfo(*__pCachedContact);
968                                         }
969                                         //set emergency state
970                                         if(callStatus.CallType == TAPI_CALL_TYPE_E911)
971                                         {
972                                                 pCallInfo->SetEmergency(true);
973                                         }
974                                         else
975                                         {
976                                                 pCallInfo->SetEmergency(false);
977                                         }
978                                         //set start time, when call is connected
979                                         long long startTime = 0;
980                                         SystemTime::GetTicks(startTime);
981                                         pCallInfo->SetCallNotificationTime(startTime);
982                                 }
983                                 //set start time, when call is connected
984                                 long long startTime = 0;
985                                 SystemTime::GetTicks(startTime);
986                                 pCallInfo->SetCallConnectTime(startTime);
987
988                                 //transfer ownership to Active calls list
989                                 __pActiveCallList->Add(callHandle, *(pCallInfo));
990                                 pCallInfo = null;
991                         }
992                         else
993                         {
994                                 r = E_FAILURE;
995                         }
996                 }
997                 break;
998         }
999         default:
1000                 break;
1001         }
1002         return r;
1003 }
1004
1005 result
1006 TelephonyManager::HoldCall(Tizen::Base::Long callHandle, bool holdCall)
1007 {
1008         result r = E_SUCCESS;
1009         //Check if there are any existing active calls
1010         if (__pActiveCallList->GetCount())
1011         {
1012                 IListT<CallInfo>* pCallList = __pActiveCallList->GetValuesN();
1013                 int callCount = pCallList->GetCount();
1014                 for (int index = 0; index < callCount; index++)
1015                 {
1016                         CallInfo holdCallInfo;
1017
1018                         r = pCallList->GetAt(index, holdCallInfo);
1019                         //check if an active call is found with matching contact no.
1020                         if ((r == E_SUCCESS) && (holdCallInfo.GetCallHandle()->Equals(callHandle)))
1021                         {
1022                                 r = HoldActiveCall(&holdCallInfo, holdCall);
1023                                 break;
1024                         }
1025                 }
1026                 delete pCallList;
1027                 pCallList = null;
1028         }
1029
1030         return r;
1031 }
1032
1033 result
1034 TelephonyManager::EndConferenceCall(void)
1035 {
1036         result r = E_FAILURE;
1037         //fetch ended callInfo
1038         CallInfo endConfCall;
1039         int res = -1;
1040         bool isConferenceCallFound = false;
1041
1042         IListT<CallInfo>* pCallList = __pActiveCallList->GetValuesN();
1043         int callCount = pCallList->GetCount();
1044         for (int index = 0; index < callCount; index++)
1045         {
1046                 pCallList->GetAt(index, endConfCall);
1047                 if (endConfCall.IsConferenceCall() == true)
1048                 {
1049                         isConferenceCallFound = true;
1050                         break;
1051                 }
1052         }
1053         if (isConferenceCallFound == false)
1054         {
1055                 delete pCallList;
1056                 pCallList = null;
1057                 return r;
1058         }
1059         unsigned int callHandle = endConfCall.GetCallHandle()->ToLong();
1060         if (callCount == 1)
1061         {
1062                 if (endConfCall.IsOnHold() == false)
1063                 {
1064                         TelCallEndType_t endType = TAPI_CALL_END_ACTIVE_ALL;
1065                         res = tel_end_call(__pTapiHandle, callHandle, endType, &HandleEndDialedCallResponse, this);
1066                 }
1067                 else
1068                 {
1069                         TelCallEndType_t endType = TAPI_CALL_END_HOLD_ALL;
1070                         res = tel_end_call(__pTapiHandle, callHandle, endType, &HandleEndDialedCallResponse, this);
1071                 }
1072         }
1073         else
1074         {
1075                 //End each call in conference as using the end_all/Hold_all
1076                 //automatically activates the held call
1077                 TelCallEndType_t endType = TAPI_CALL_END;
1078                 int confCallCount = endConfCall.GetCallerListCount();
1079                 IListT<CallInfo>* pConfCallList = endConfCall.GetCallerList();
1080                 for (int index = 0; index < confCallCount; index++)
1081                 {
1082                         CallInfo callInfo;
1083                         pConfCallList->GetAt(index, callInfo);
1084                         unsigned int calloBeEnded = callInfo.GetCallHandle()->ToLong();
1085                         res = tel_end_call(__pTapiHandle, calloBeEnded, endType, &HandleEndDialedCallResponse, this);
1086                 }
1087         }
1088
1089         if (res == TAPI_CAUSE_SUCCESS)
1090         {
1091                 r = E_SUCCESS;
1092                 CallInfo* pConfCallInfo = new (std::nothrow) CallInfo();
1093                 *pConfCallInfo = endConfCall;
1094                 __pActiveCallList->Remove(callHandle);
1095                 __pActiveCallList->Add(callHandle, *pConfCallInfo);
1096         }
1097         else
1098         {
1099                 r = E_FAILURE;
1100         }
1101
1102         delete pCallList;
1103         pCallList = null;
1104         return r;
1105 }
1106
1107 result
1108 TelephonyManager::HoldConferenceCall(bool holdCall)
1109 {
1110         result r = E_FAILURE;
1111         int confCallIndex = -1;
1112         CallInfo endConfCall;
1113         bool isConferenceCallFound = false;
1114
1115         IListT<CallInfo>* pCallList = __pActiveCallList->GetValuesN();
1116         int confCallCount = pCallList->GetCount();
1117
1118         for (int index = 0; index < confCallCount; index++)
1119         {
1120                 pCallList->GetAt(index, endConfCall);
1121                 if (endConfCall.IsConferenceCall() == true)
1122                 {
1123                         isConferenceCallFound = true;
1124                         confCallIndex = index;
1125                         //Found the Conference call to be ended.
1126                         break;
1127                 }
1128         }
1129
1130         if (isConferenceCallFound == false)
1131         {
1132                 delete pCallList;
1133                 pCallList = null;
1134                 return r;
1135         }
1136
1137         unsigned int callHandle = endConfCall.GetCallHandle()->ToLong();
1138         int res = TAPI_API_INVALID_INPUT;
1139         if (holdCall == true)
1140         {
1141                 res = tel_hold_call(__pTapiHandle, callHandle, &HandleCallbackResponse, this);
1142         }
1143         else
1144         {
1145                 res = tel_active_call(__pTapiHandle, callHandle, &HandleCallbackResponse, this);
1146         }
1147         if (res == TAPI_API_SUCCESS)
1148         {
1149                 r = E_SUCCESS;
1150                 if (holdCall == true)
1151                 {
1152                         endConfCall.SetOnHold(true);
1153                 }
1154                 else
1155                 {
1156                         endConfCall.SetOnHold(false);
1157                 }
1158                 CallInfo* pConfCallInfo = new (std::nothrow) CallInfo();
1159                 *pConfCallInfo = endConfCall;
1160                 __pActiveCallList->Remove(callHandle);
1161                 __pActiveCallList->Add(callHandle, *pConfCallInfo);
1162         }
1163         else
1164         {
1165                 r = E_FAILURE;
1166         }
1167
1168         delete pCallList;
1169         pCallList = null;
1170         return r;
1171 }
1172
1173 result
1174 TelephonyManager::JoinCall(void)
1175 {
1176         result r = E_FAILURE;
1177         int res = -1;
1178         CallInfo activeCall;
1179         CallInfo heldCall;
1180         // Use enumerator to access elements in the map
1181         IListT<CallInfo>* pCallList = __pActiveCallList->GetValuesN();
1182         r = pCallList->GetAt(0, activeCall);
1183
1184         if (r == E_SUCCESS)
1185         {
1186                 r = pCallList->GetAt(1, heldCall);
1187                 if (r == E_SUCCESS)
1188                 {
1189                         unsigned int activeCallHandle = activeCall.GetCallHandle()->ToLong();
1190                         unsigned int heldCallHandle = heldCall.GetCallHandle()->ToLong();
1191
1192                         //Check if participants in conference call are under limit.
1193                         if ((heldCall.IsConferenceCall() == true) && (heldCall.GetCallerListCount() < IDI_MAX_CONF_CALL_PARTICIPANTS))
1194                         {
1195                                 res = tel_join_call(__pTapiHandle, heldCallHandle, activeCallHandle, &HandleJoinCallbackResponse, this);
1196                         }
1197                         else if (activeCall.GetCallerListCount() < IDI_MAX_CONF_CALL_PARTICIPANTS)
1198                         {
1199                                 res = tel_join_call(__pTapiHandle, activeCallHandle, heldCallHandle, &HandleJoinCallbackResponse, this);
1200                         }
1201                 }
1202         }
1203         delete pCallList;
1204         pCallList = null;
1205         if (res == TAPI_API_SUCCESS)
1206         {
1207                 r = E_SUCCESS;
1208         }
1209         else
1210         {
1211                 r = E_FAILURE;
1212         }
1213         return r;
1214 }
1215
1216 result
1217 TelephonyManager::HoldActiveCall(CallInfo* pActiveCallInfo, bool holdCall)
1218 {
1219         unsigned int callHandle = pActiveCallInfo->GetCallHandle()->ToLong();
1220         int retStatus = -1;
1221         if (holdCall == true)
1222         {
1223                 retStatus = tel_hold_call(__pTapiHandle, callHandle, &HandleCallbackResponse, this);
1224         }
1225         else
1226         {
1227                 retStatus = tel_active_call(__pTapiHandle, callHandle, &HandleCallbackResponse, this);
1228         }
1229
1230         if (retStatus == TAPI_CAUSE_SUCCESS)
1231         {
1232                 CallInfo* pHeldCallInfo = new (std::nothrow) CallInfo();
1233                 //copy state into new callinfo object
1234                 *pHeldCallInfo = *pActiveCallInfo;
1235
1236                 //set call to hold state
1237                 pHeldCallInfo->SetOnHold(holdCall);
1238
1239                 __pActiveCallList->Remove(callHandle);
1240                 //replace old object with new
1241                 __pActiveCallList->Add(callHandle, *pHeldCallInfo);
1242                 return E_SUCCESS;
1243         }
1244         else
1245         {
1246                 return E_FAILURE;
1247         }
1248 }
1249
1250 result
1251 TelephonyManager::DialOutgoingCall(String& contactNumber, bool isEmergency)
1252 {
1253         TelCallDial_t structDialCall;
1254
1255         //conversion "contactNumber" to char*
1256         const wchar_t* pContact = contactNumber.GetPointer();
1257         int len = contactNumber.GetLength()+1;
1258         char* pNumber = new (std::nothrow) char[len];
1259         wcstombs(pNumber, pContact, len);
1260
1261         //initialize request parameter
1262         memset(&structDialCall, '\0', sizeof(TelCallDial_t));
1263         memcpy(structDialCall.szNumber, pNumber, strlen(pNumber));
1264
1265         if(isEmergency == true)
1266         {
1267                 structDialCall.CallType = TAPI_CALL_TYPE_E911;
1268         }
1269         else
1270         {
1271                 structDialCall.CallType = TAPI_CALL_TYPE_VOICE;
1272         }
1273
1274         int res = tel_dial_call(__pTapiHandle, &structDialCall, &HandleDialCallbackResponse, this);
1275         if (__pSoundManager == null)
1276         {
1277                 __pSoundManager = new (std::nothrow) SoundManager();
1278         }
1279         __pSoundManager->StartSession();
1280         delete[] pNumber;
1281         pNumber = null;
1282
1283         if (res == TAPI_CAUSE_SUCCESS)
1284         {
1285                 if (__pDialedCall != null)
1286                 {
1287                         delete __pDialedCall;
1288                         __pDialedCall = null;
1289                 }
1290                 __pDialedCall = new (std::nothrow) CallInfo();
1291                 __pDialedCall->SetContactNumber(contactNumber);
1292                 __pDialedCall->SetEmergency(isEmergency);
1293                 result r = FetchContactInfoForNumber(contactNumber);
1294                 if (!IsFailed(r))
1295                 {
1296                         __pDialedCall->SetContactInfo(*__pCachedContact);
1297                 }
1298                 return E_SUCCESS;
1299         }
1300         else
1301         {
1302                 return E_FAILURE;
1303         }
1304 }
1305
1306 result
1307 TelephonyManager::SwapCalls(void)
1308 {
1309         result r = E_FAILURE;
1310
1311         //check if there are atleast 2 active calls
1312         if (__pActiveCallList->GetCount() == IDI_MAX_ACTIVE_CALLS)
1313         {
1314                 int retStatus = 0;
1315
1316                 //fetch call handles
1317                 IListT<long>* pCallHandleList = __pActiveCallList->GetKeysN();
1318                 long callHandle1 = 0;
1319                 pCallHandleList->GetAt(0, callHandle1);
1320                 long callHandle2 = 0;
1321                 pCallHandleList->GetAt(1, callHandle2);
1322
1323                 retStatus = tel_swap_call(__pTapiHandle, callHandle1, callHandle2, &HandleSwapCallbackResponse, this);
1324
1325                 if (retStatus == TAPI_CAUSE_SUCCESS)
1326                 {
1327                         r = E_SUCCESS;
1328                 }
1329                 delete pCallHandleList;
1330                 pCallHandleList = null;
1331         }
1332
1333         return r;
1334 }
1335
1336 result
1337 TelephonyManager::SendCallDTMF(String& textToBeSent)
1338 {
1339         result r = E_FAILURE;
1340         //check if there is an active Call
1341         if (__pActiveCallList->GetCount() > 0)
1342         {
1343                 //conversion "textToBeSent" to char*
1344                 const wchar_t* pTextToBeSent = textToBeSent.GetPointer();
1345                 int len = textToBeSent.GetLength() + 1;
1346                 char* pNumber = new (std::nothrow) char[len];
1347                 wcstombs(pNumber, pTextToBeSent, len);
1348                 int retStatus = tel_call_dtmf(__pTapiHandle, pNumber, &HandleCallbackResponse, this);
1349                 delete []pNumber;
1350                 pNumber = null;
1351                 if (retStatus == TAPI_CAUSE_SUCCESS)
1352                 {
1353                         r = E_SUCCESS;
1354                 }
1355         }
1356         return r;
1357 }
1358
1359 result
1360 TelephonyManager::EndFromConference(int callHandle)
1361 {
1362         result r = E_FAILURE;
1363         int confCallIndex = -1;
1364         CallInfo endConfCall;
1365         bool isConferenceCallFound = false;
1366
1367         IListT<CallInfo>* pCallList = __pActiveCallList->GetValuesN();
1368         int callCount = pCallList->GetCount();
1369         for (int index = 0; index < callCount; index++)
1370         {
1371                 pCallList->GetAt(index, endConfCall);
1372                 if (endConfCall.IsConferenceCall() == true)
1373                 {
1374                         isConferenceCallFound = true;
1375                         confCallIndex = index;
1376                         //Found the Conference call to be ended.
1377                         break;
1378                 }
1379         }
1380
1381         if (isConferenceCallFound == false)
1382         {
1383                 delete pCallList;
1384                 pCallList = null;
1385                 return r;
1386         }
1387         delete pCallList;
1388         pCallList = null;
1389         //Identify the call to be ended and remove from list on API success
1390         CallInfo callToBeEnded;
1391         pCallList = endConfCall.GetCallerList();
1392         callCount = pCallList->GetCount();
1393         for (int index = 0; index < callCount; index++)
1394         {
1395                 pCallList->GetAt(index, callToBeEnded);
1396                 if (callToBeEnded.GetCallHandle()->ToLong() == callHandle)
1397                 {
1398                         //Identify the call to be ended and remove from list on API success
1399                         TelCallEndType_t endType = TAPI_CALL_END;
1400
1401                         int res = tel_end_call(__pTapiHandle, callHandle, endType, &HandleEndFromConferenceCallbackResponse, this);
1402                         if (res == TAPI_CAUSE_SUCCESS)
1403                         {
1404                                 r = E_SUCCESS;
1405                         }
1406                         else
1407                         {
1408                                 r = E_FAILURE;
1409                         }
1410                         break;
1411                 }
1412         }
1413
1414         return r;
1415 }
1416
1417 result
1418 TelephonyManager::SplitFromConference(int callHandle)
1419 {
1420         result r = E_FAILURE;
1421         int confCallIndex = -1;
1422         CallInfo endConfCall;
1423         bool isConferenceCallFound = false;
1424
1425         IListT<CallInfo>* pCallList = __pActiveCallList->GetValuesN();
1426         int callCount = pCallList->GetCount();
1427         for (int index = 0; index < callCount; index++)
1428         {
1429                 pCallList->GetAt(index, endConfCall);
1430                 if (endConfCall.IsConferenceCall() == true)
1431                 {
1432                         isConferenceCallFound = true;
1433                         confCallIndex = index;
1434                         //Found the Conference call to be ended.
1435                         break;
1436                 }
1437         }
1438
1439         if (isConferenceCallFound == false)
1440         {
1441                 delete pCallList;
1442                 pCallList = null;
1443                 return r;
1444         }
1445         pCallList = null;
1446         //Identify the call to be ended and remove from list on API success
1447         CallInfo callToBeEnded;
1448         pCallList = endConfCall.GetCallerList();
1449         callCount = pCallList->GetCount();
1450         for (int index = 0; index < callCount; index++)
1451         {
1452                 pCallList->GetAt(index, callToBeEnded);
1453                 if (callToBeEnded.GetCallHandle()->ToLong() == callHandle)
1454                 {
1455                         int res = tel_split_call(__pTapiHandle, callHandle, &HandleSplitFromConferenceCallbackResponse, this);
1456                         if (res == TAPI_CAUSE_SUCCESS)
1457                         {
1458                                 r = E_SUCCESS;
1459                         }
1460                         else
1461                         {
1462                                 r = E_FAILURE;
1463                         }
1464                         break;
1465                 }
1466         }
1467
1468         return r;
1469 }
1470
1471 result
1472 TelephonyManager::SetMuteStatus(bool setMute)
1473 {
1474         TelSoundMuteStatus_t muteStatus;
1475         result r = E_FAILURE;
1476         if (setMute == true)
1477         {
1478                 muteStatus = TAPI_SOUND_MUTE_STATUS_ON;
1479         }
1480         else
1481         {
1482                 muteStatus = TAPI_SOUND_MUTE_STATUS_OFF;
1483         }
1484         int res = tel_set_call_mute_status(__pTapiHandle, muteStatus, &HandleCallbackResponse, this);
1485         if (res == TAPI_CAUSE_SUCCESS)
1486         {
1487                 __isMuted = setMute;
1488                 r = E_SUCCESS;
1489         }
1490         else
1491         {
1492                 r = E_FAILURE;
1493         }
1494         return r;
1495 }
1496
1497 bool
1498 TelephonyManager::IsCallMuted(void)
1499 {
1500         return __isMuted;
1501 }
1502
1503 result
1504 TelephonyManager::SetSpeakerStatus(bool setSpeaker)
1505 {
1506         result r = E_FAILURE;
1507         TelCallSoundPathInfo_t callSoundPathInfo;
1508         __pSoundManager->SetSpeakerStatus(setSpeaker);
1509         if (setSpeaker == true)
1510         {
1511                 callSoundPathInfo.path = TAPI_SOUND_PATH_SPK_PHONE;
1512         }
1513         else
1514         {
1515                 callSoundPathInfo.path = TAPI_SOUND_PATH_HANDSET;
1516         }
1517         callSoundPathInfo.ex_volume = TelCallSoundPathInfo_t::TAPI_SOUND_EX_VOLUME_ON;
1518
1519         int res = tel_set_call_sound_path(__pTapiHandle, &callSoundPathInfo, &HandleCallbackResponse, this);
1520
1521         if (res == TAPI_CAUSE_SUCCESS)
1522         {
1523                 __isSpeakerOn = setSpeaker;
1524                 r = E_SUCCESS;
1525         }
1526         else
1527         {
1528                 r = E_FAILURE;
1529         }
1530         return r;
1531 }
1532
1533 bool
1534 TelephonyManager::IsSpeakerOn(void)
1535 {
1536         return __isSpeakerOn;
1537 }
1538
1539 bool
1540 TelephonyManager::IsSplitAllowed(void)
1541 {
1542         // Split functionality is allowed only if a one call is present.
1543         // The call can be a single call or a conference call
1544         if (__pActiveCallList->GetCount() == 1)
1545         {
1546                 return true;
1547         }
1548         return false;
1549 }
1550 //Currently does nothing
1551 void
1552 TelephonyManager::HandleCallbackResponse(TapiHandle* pHandle, int callBackResult, void* pData, void* pUserData)
1553 {
1554 }
1555
1556 void
1557 TelephonyManager::HandleEndDialedCallResponse(TapiHandle* pHandle, int callBackResult, void* pData, void* pUserData)
1558 {
1559         TelCallEndCnf_t callEndInfo;
1560         TelephonyManager* pTelManager = (TelephonyManager*) pUserData;
1561         //Handle ending of dialed call
1562         if (pTelManager->__pDialedCall != null)
1563         {
1564                 unsigned int dialedCallHandle = (unsigned int)pTelManager->__pDialedCall->GetCallHandle()->ToLong();
1565                 memset(&callEndInfo, 0,sizeof(TelCallEndCnf_t));
1566                 memcpy(&callEndInfo, pData,sizeof(TelCallEndCnf_t));
1567                 if (callEndInfo.id == dialedCallHandle)
1568                 {
1569                         //Get current status of the call. idle callback received if call has been ended
1570                         TelCallStatus_t callStatus;
1571                         tel_get_call_status(pTelManager->__pTapiHandle,callEndInfo.id,&callStatus);
1572                         if (callStatus.CallState == TAPI_CALL_STATE_IDLE)
1573                         {
1574                                 //check if the ended call was the last call
1575                                 bool isLastCall = (pTelManager->__pActiveCallList->GetCount() == 0);
1576                                 ArrayListT<CallInfo>* pCallList = null;
1577                                 if (isLastCall)
1578                                 {
1579                                         pCallList = new (std::nothrow) ArrayListT<CallInfo>();
1580                                 }
1581                                 else
1582                                 {
1583                                         pCallList = static_cast<ArrayListT<CallInfo>*>(pTelManager->__pActiveCallList->GetValuesN());
1584                                 }
1585                                 //notify listener that call is connected.
1586                                 pTelManager->__pEventListener->HandleCallDisconnected(isLastCall, *pCallList);
1587                                 delete pCallList;
1588                                 pCallList = null;
1589                                 delete pTelManager->__pDialedCall;
1590                                 pTelManager->__pDialedCall = null;
1591                                 pTelManager->__pSoundManager->SetSoundMode(SOUND_MODE_VOICE);
1592                         }
1593                 }
1594         }
1595 }
1596
1597 void
1598 TelephonyManager::HandleDialCallbackResponse(TapiHandle* pHandle, int callBackResult, void* pData, void* pUserData)
1599 {
1600         TelephonyManager* pTelManager = (TelephonyManager*) pUserData;
1601         if (callBackResult != TAPI_CAUSE_SUCCESS)
1602         {
1603                 if (pTelManager->__pDialedCall != null)
1604                 {
1605                         delete pTelManager->__pDialedCall;
1606                         pTelManager->__pDialedCall = null;
1607                 }
1608                 pTelManager->__pEventListener->HandleTelephonyError(ERROR_DIAL_FAILED);
1609         }
1610 }
1611
1612 void
1613 TelephonyManager::HandleRejectCallbackResponse(TapiHandle* pHandle, int callBackResult, void* pData, void* pUserData)
1614 {
1615         // This callback comes only if user has either rejected an incoming call from IncomingCallForm.
1616         // or the incoming call was automatically rejected.
1617         TelephonyManager* pTelManager = (TelephonyManager*) pUserData;
1618         if (pData != null && callBackResult == TAPI_API_SUCCESS)
1619         {
1620                 unsigned int tempHandle = 0;
1621                 TelCallStatus_t callStatus;
1622                 memcpy(&tempHandle, pData, sizeof(TS_UINT));
1623                 int res = tel_get_call_status(pTelManager->__pTapiHandle, tempHandle, &callStatus);
1624                 if (res == TAPI_CAUSE_SUCCESS)
1625                 {
1626                         String contactNumber(callStatus.pNumber);
1627                         //Fetch contact details from address book.
1628                         Contact* pContactDetails = pTelManager->GetContactN(contactNumber);
1629
1630                         //Check if number was automatically rejected using settings, then don't give any notification to user.
1631                         bool showIncomingCallRejectedNotification = true;
1632                         if (((pTelManager->__pSettingsManager->GetUnknownRejectStatus() == true) && (pContactDetails == null))
1633                                                 || (pTelManager->__pSettingsManager->IsCallToBeRejected(contactNumber) == true))
1634                         {
1635                                 showIncomingCallRejectedNotification = false;
1636                         }
1637
1638                         if (showIncomingCallRejectedNotification == true)
1639                         {
1640                                 long long phNumber = 0;
1641                                 LongLong::Parse(contactNumber, phNumber);
1642                                 //handle call connected - save info
1643                                 if (pTelManager->__pIncomingCall != null)
1644                                 {
1645                                         CallInfo* pIncomingCall = new (std::nothrow) CallInfo();
1646                                         *pIncomingCall = *(pTelManager->__pIncomingCall);
1647                                         pIncomingCall->SetCalllogType(CALL_LOG_TYPE_VOICE_REJECTED);
1648                                         result r = pTelManager->FetchContactInfoForNumber(contactNumber);
1649                                         if (!IsFailed(r))
1650                                         {
1651                                                 pIncomingCall->SetContactInfo(*(pTelManager->__pCachedContact));
1652                                         }
1653                                         //check if the ended call was the last call
1654                                         bool isLastCall = (pTelManager->__pActiveCallList->GetCount() == 0);
1655                                         ArrayListT<CallInfo>* pCallList = null;
1656                                         if (isLastCall)
1657                                         {
1658                                                 pCallList = new (std::nothrow) ArrayListT<CallInfo>();
1659                                                 pCallList->Construct(1);
1660
1661                                                 //save end call details
1662                                                 String endCause(L"Call Rejected");
1663                                                 pIncomingCall->SetEndCallCause(endCause);
1664
1665                                                 //save to list
1666                                                 pCallList->Add(*pIncomingCall);
1667                                         }
1668                                         else
1669                                         {
1670                                                 pCallList = static_cast<ArrayListT<CallInfo>*>(pTelManager->__pActiveCallList->GetValuesN());
1671                                         }
1672
1673                                         //Add to call log
1674                                         pTelManager->__pCalllogMgr->AddCallogInfoToDatabase(pIncomingCall);
1675
1676                                         delete pTelManager->__pIncomingCall;
1677                                         pTelManager->__pIncomingCall = null;
1678
1679                                         if (pTelManager->__isIncomingCallPresent == true)
1680                                         {
1681                                                 if(pTelManager->__pSoundManager != null)
1682                                                 {
1683                                                         pTelManager->__pSoundManager->StopAlert();
1684                                                         //Do not call stop session if there is already a call going on
1685                                                         if(pTelManager->__pActiveCallList->GetCount() == 0)
1686                                                         {
1687                                                                 pTelManager->__pSoundManager->StopSession();
1688                                                         }
1689                                                 }
1690                                                 pTelManager->__pEventListener->HandleCallDisconnected(isLastCall, *pCallList);
1691                                                 delete pCallList;
1692                                                 pCallList = null;
1693                                         }
1694                                         pTelManager->__isIncomingCallPresent = false;
1695                                         delete pIncomingCall;
1696                                         pIncomingCall = null;
1697                                 }
1698                         }
1699                 }
1700         }
1701         else
1702         {
1703                 pTelManager->__pEventListener->HandleTelephonyError(ERROR_REJECT_FAILED);
1704         }
1705 }
1706
1707 void
1708 TelephonyManager::HandleJoinCallbackResponse(TapiHandle* pHandle, int callBackResult, void* pData, void* pUserData)
1709 {
1710         TelephonyManager* pTelManager = (TelephonyManager*) pUserData;
1711         if (callBackResult == TAPI_API_SUCCESS && pData != null)
1712         {
1713                 unsigned int tempHandle = 0;
1714                 TelCallInfoJoinedNoti_t joinedInfoNotification;
1715                 CallInfo confCallInfo;
1716
1717                 memcpy(&tempHandle, pData, sizeof(TS_UINT));
1718                 joinedInfoNotification.id = tempHandle;
1719                 CallInfo activeCall;
1720                 CallInfo heldCall;
1721                 // Use enumerator to access elements in the map
1722                 IListT<CallInfo>* pCallList = pTelManager->__pActiveCallList->GetValuesN();
1723                 result r = pCallList->GetAt(0, activeCall);
1724
1725                 if (r == E_SUCCESS)
1726                 {
1727                         r = pCallList->GetAt(1, heldCall);
1728                         if (r == E_SUCCESS)
1729                         {
1730                                 CallInfo* pConfCallInfo = new (std::nothrow) CallInfo();
1731                                 unsigned int activeCallHandle = activeCall.GetCallHandle()->ToLong();
1732                                 unsigned int heldCallHandle = heldCall.GetCallHandle()->ToLong();
1733                                 if (activeCall.IsConferenceCall() == true)
1734                                 {
1735                                         r = E_SUCCESS;
1736                                         //When joined both become active
1737                                         activeCall.SetOnHold(false);
1738                                         heldCall.SetOnHold(false);
1739                                         *pConfCallInfo = activeCall;
1740                                         pConfCallInfo->AddCallToCallerList(heldCall);
1741                                         pConfCallInfo->SetCallHandle(activeCallHandle);
1742                                         //Set call start time
1743                                         if (pConfCallInfo->GetCallConnectTime() > heldCall.GetCallConnectTime())
1744                                         {
1745                                                 pConfCallInfo->SetCallConnectTime(heldCall.GetCallConnectTime());
1746                                                 pConfCallInfo->SetCallNotificationTime(heldCall.GetCallNotificationTime());
1747                                         }
1748                                 }
1749                                 else if (heldCall.IsConferenceCall() == true)
1750                                 {
1751                                         r = E_SUCCESS;
1752                                         heldCall.SetOnHold(false);
1753                                         activeCall.SetOnHold(false);
1754                                         *pConfCallInfo = heldCall;
1755                                         pConfCallInfo->AddCallToCallerList(activeCall);
1756                                         pConfCallInfo->SetCallHandle(heldCallHandle);
1757                                         //Set call start time
1758                                         if (pConfCallInfo->GetCallConnectTime() > activeCall.GetCallConnectTime())
1759                                         {
1760                                                 pConfCallInfo->SetCallConnectTime(activeCall.GetCallConnectTime());
1761                                                 pConfCallInfo->SetCallNotificationTime(activeCall.GetCallNotificationTime());
1762                                         }
1763                                 }
1764                                 else
1765                                 {
1766                                         r = E_SUCCESS;
1767                                         pConfCallInfo->SetConference(true);
1768                                         heldCall.SetOnHold(false);
1769                                         activeCall.SetOnHold(false);
1770                                         pConfCallInfo->AddCallToCallerList(activeCall);
1771                                         pConfCallInfo->AddCallToCallerList(heldCall);
1772                                         pConfCallInfo->SetCallHandle(activeCallHandle);
1773                                         //Set call start time
1774                                         if (activeCall.GetCallConnectTime() > heldCall.GetCallConnectTime())
1775                                         {
1776                                                 pConfCallInfo->SetCallConnectTime(heldCall.GetCallConnectTime());
1777                                                 pConfCallInfo->SetCallNotificationTime(heldCall.GetCallNotificationTime());
1778                                         }
1779                                         else
1780                                         {
1781                                                 pConfCallInfo->SetCallConnectTime(activeCall.GetCallConnectTime());
1782                                                 pConfCallInfo->SetCallNotificationTime(activeCall.GetCallNotificationTime());
1783                                         }
1784                                 }
1785                                 pConfCallInfo->SetCallHandle(joinedInfoNotification.id);
1786                                 pTelManager->__pActiveCallList->RemoveAll();
1787                                 //only one call in the list
1788                                 pTelManager->__pActiveCallList->Add(joinedInfoNotification.id, *pConfCallInfo);
1789                                 //notify listener that call is connected.
1790                                 pTelManager->__pEventListener->HandleConferenceCall(*pConfCallInfo);
1791                                 delete pCallList;
1792                                 pCallList = null;
1793                         }
1794                 }
1795         }
1796         else
1797         {
1798                 pTelManager->__pEventListener->HandleTelephonyError(ERROR_JOIN_FAILED);
1799         }
1800 }
1801
1802 void
1803 TelephonyManager::HandleSwapCallbackResponse(TapiHandle* pHandle, int callBackResult, void* pData, void* pUserData)
1804 {
1805         TelephonyManager* pTelManager = (TelephonyManager*) pUserData;
1806         if (callBackResult == TAPI_CAUSE_SUCCESS)
1807         {
1808                 IListT<CallInfo>* pCallList = pTelManager->__pActiveCallList->GetValuesN();
1809                 IListT<long>* pKeyList = pTelManager->__pActiveCallList->GetKeysN();
1810                 int callCount = pTelManager->__pActiveCallList->GetCount();
1811                 for (int index = 0; index < callCount; index++)
1812                 {
1813                         CallInfo* pTempCallInfo = new (std::nothrow) CallInfo();
1814                         pCallList->GetAt(index, *pTempCallInfo);
1815                         (pTempCallInfo->IsOnHold() == false) ? pTempCallInfo->SetOnHold(true) : pTempCallInfo->SetOnHold(false);
1816                         long callHandle;
1817                         pKeyList->GetAt(index, callHandle);
1818                         pTelManager->__pActiveCallList->SetValue(callHandle, *pTempCallInfo);
1819                 }
1820                 delete pCallList;
1821                 pCallList = null;
1822                 delete pKeyList;
1823                 pKeyList = null;
1824                 pCallList = pTelManager->__pActiveCallList->GetValuesN();
1825                 pTelManager->__pEventListener->HandleCallSwapOccured(*pCallList);
1826         }
1827         else
1828         {
1829                 pTelManager->__pEventListener->HandleTelephonyError(ERROR_SWAP_FAILED);
1830         }
1831 }
1832
1833 void
1834 TelephonyManager::HandleEndFromConferenceCallbackResponse(TapiHandle* pHandle, int callBackResult, void* pData, void* pUserData)
1835 {
1836         TelephonyManager* pTelManager = (TelephonyManager*) pUserData;
1837         if (callBackResult == TAPI_CAUSE_SUCCESS && pData != null)
1838         {
1839                 TelCallEndCnf_t callEndNotification;
1840                 memcpy(&callEndNotification, pData, sizeof(TelCallEndCnf_t));
1841                 int confCallIndex = -1;
1842                 CallInfo endConfCall;
1843                 bool isConferenceCallFound = false;
1844
1845                 IListT<CallInfo>* pCallList = pTelManager->__pActiveCallList->GetValuesN();
1846                 int callCount = pCallList->GetCount();
1847                 for (int index = 0; index < callCount; index++)
1848                 {
1849                         pCallList->GetAt(index, endConfCall);
1850                         if (endConfCall.IsConferenceCall() == true)
1851                         {
1852                                 isConferenceCallFound = true;
1853                                 confCallIndex = index;
1854                                 //Found the Conference call to be ended.
1855                                 break;
1856                         }
1857                 }
1858
1859                 if (isConferenceCallFound == false)
1860                 {
1861                         delete pCallList;
1862                         pCallList = null;
1863                         return;
1864                 }
1865                 delete pCallList;
1866                 pCallList = null;
1867                 //Identify the call to be ended and remove from list on API success
1868                 CallInfo callToBeEnded;
1869                 pCallList = endConfCall.GetCallerList();
1870                 callCount = pCallList->GetCount();
1871                 for (int index = 0; index < callCount; index++)
1872                 {
1873                         pCallList->GetAt(index, callToBeEnded);
1874                         if ((unsigned int)callToBeEnded.GetCallHandle()->ToLong() == callEndNotification.id)
1875                         {
1876                                 //Identified the call to be ended and remove from conference list
1877                                 endConfCall.RemoveCallFromCallerList(index);
1878                                 pTelManager->__pCalllogMgr->AddCallogInfoToDatabase(&callToBeEnded);
1879                                 break;
1880                         }
1881                 }
1882                 unsigned int confCallHandle = (unsigned int)endConfCall.GetCallHandle()->ToLong();
1883                 //Chk if last participant removed. if so switch to single active view
1884                 if (endConfCall.GetCallerListCount() == 1)
1885                 {
1886                         CallInfo callFromList;
1887                         pCallList = endConfCall.GetCallerList();
1888                         pCallList->GetAt(0, callFromList);
1889                         CallInfo* pActiveCall = new (std::nothrow) CallInfo();
1890                         *pActiveCall = callFromList;
1891                         pActiveCall->SetConference(false);
1892                         pTelManager->__pActiveCallList->Remove(confCallHandle);
1893                         pTelManager->__pActiveCallList->Add(pActiveCall->GetCallHandle()->ToLong(), *pActiveCall);
1894                         pActiveCall = null;
1895                         //using the callConnected to switch to single active screen
1896                         pCallList = pTelManager->__pActiveCallList->GetValuesN();
1897                         pTelManager->__pEventListener->HandleCallConnected(*pCallList);
1898                         pCallList = null;
1899                 }
1900                 else
1901                 {
1902                         CallInfo callFromList;
1903                         pCallList = endConfCall.GetCallerList();
1904                         pCallList->GetAt(0, callFromList);
1905
1906                         CallInfo* pConfCallInfo = new (std::nothrow) CallInfo();
1907                         *pConfCallInfo = endConfCall;
1908                         if (confCallHandle == callEndNotification.id)
1909                         {
1910                                 //Call Handle is same as conf call handle.
1911                                 //Change conf call handle
1912                                 pTelManager->__pActiveCallList->Remove(confCallHandle);
1913                                 int tmpCallHandle = callFromList.GetCallHandle()->ToLong();
1914                                 pConfCallInfo->SetCallHandle(tmpCallHandle);
1915                                 pTelManager->__pActiveCallList->Add(tmpCallHandle, *pConfCallInfo);
1916                         }
1917                         else
1918                         {
1919                                 pTelManager->__pActiveCallList->SetValue(confCallHandle, *pConfCallInfo );
1920                         }
1921                         pTelManager->__pEventListener->HandleConferenceChange();
1922                 }
1923         }
1924         else
1925         {
1926                 pTelManager->__pEventListener->HandleTelephonyError(ERROR_END_FROM_CONFERENCE_FAILED);
1927         }
1928 }
1929
1930 void
1931 TelephonyManager::HandleSplitFromConferenceCallbackResponse(TapiHandle* pHandle, int callBackResult, void* pData, void* pUserData)
1932 {
1933         TelephonyManager* pTelManager = (TelephonyManager*) pUserData;
1934         if (callBackResult == TAPI_CAUSE_SUCCESS && pData != null)
1935         {
1936                 TelCallSplitCnf_t callSplitNotification;
1937                 memcpy(&callSplitNotification, pData, sizeof(TelCallSplitCnf_t));
1938                 int confCallIndex = -1;
1939                 CallInfo endConfCall;
1940                 bool isConferenceCallFound = false;
1941
1942                 IListT<CallInfo>* pCallList = pTelManager->__pActiveCallList->GetValuesN();
1943                 int callCount = pCallList->GetCount();
1944                 for (int index = 0; index < callCount; index++)
1945                 {
1946                         pCallList->GetAt(index, endConfCall);
1947                         if (endConfCall.IsConferenceCall() == true)
1948                         {
1949                                 isConferenceCallFound = true;
1950                                 confCallIndex = index;
1951                                 //Found the Conference call to be ended.
1952                                 break;
1953                         }
1954                 }
1955
1956                 if (isConferenceCallFound == false)
1957                 {
1958                         delete pCallList;
1959                         pCallList = null;
1960                         return;
1961                 }
1962                 delete pCallList;
1963                 pCallList = null;
1964                 //Identify the call to be ended and remove from list on API success
1965                 CallInfo callToBeEnded;
1966                 pCallList = endConfCall.GetCallerList();
1967                 callCount = pCallList->GetCount();
1968                 for (int index = 0; index < callCount; index++)
1969                 {
1970                         pCallList->GetAt(index, callToBeEnded);
1971                         if ((unsigned int)callToBeEnded.GetCallHandle()->ToLong() == callSplitNotification.id)
1972                         {
1973                                 //Identified the call to be ended and remove from conference list
1974                                 //Add this to the active call list
1975                                 endConfCall.RemoveCallFromCallerList(index);
1976                                 break;
1977                         }
1978                 }
1979                 unsigned int confCallHandle = (unsigned int)endConfCall.GetCallHandle()->ToLong();
1980                 //Set the hold flags correctly and make the changes to the active call list
1981                 if (endConfCall.GetCallerListCount() == 1)
1982                 {
1983                         //Set hold for the other single call
1984                         // and add to the list
1985                         CallInfo callFromList;
1986                         pCallList = endConfCall.GetCallerList();
1987                         pCallList->GetAt(0, callFromList);
1988                         CallInfo* pHeldCall = new (std::nothrow) CallInfo();
1989                         *pHeldCall = callFromList;
1990                         pHeldCall->SetConference(false);
1991                         pHeldCall->SetOnHold(true);
1992                         pTelManager->__pActiveCallList->Remove(confCallHandle);
1993                         pTelManager->__pActiveCallList->Add(pHeldCall->GetCallHandle()->ToLong(), *pHeldCall);
1994                         pHeldCall = null;
1995                 }
1996                 else
1997                 {
1998                         //Set hold flag for conference call
1999                         endConfCall.SetOnHold(true);
2000                         CallInfo callFromList;
2001                         pCallList = endConfCall.GetCallerList();
2002                         pCallList->GetAt(0, callFromList);
2003
2004                         CallInfo* pConfCallInfo = new (std::nothrow) CallInfo();
2005                         *pConfCallInfo = endConfCall;
2006                         if (confCallHandle == callSplitNotification.id)
2007                         {
2008                                 //Call Handle is same as conf call handle.
2009                                 //Change conf call handle
2010                                 pTelManager->__pActiveCallList->Remove(confCallHandle);
2011                                 int tmpCallHandle = callFromList.GetCallHandle()->ToLong();
2012                                 pConfCallInfo->SetCallHandle(tmpCallHandle);
2013                                 pTelManager->__pActiveCallList->Add(callFromList.GetCallHandle()->ToLong(), *pConfCallInfo);
2014                         }
2015                         else
2016                         {
2017                                 pTelManager->__pActiveCallList->Remove(confCallHandle);
2018                                 pTelManager->__pActiveCallList->Add(confCallHandle, *pConfCallInfo);
2019                         }
2020                 }
2021                 //Add the new active call to active call list
2022                 CallInfo* pActiveCall = new (std::nothrow) CallInfo();
2023                 *pActiveCall = callToBeEnded;
2024                 pActiveCall->SetConference(false);
2025                 pActiveCall->SetOnHold(false);
2026                 pTelManager->__pActiveCallList->Remove(pActiveCall->GetCallHandle()->ToLong());
2027                 pTelManager->__pActiveCallList->Add(pActiveCall->GetCallHandle()->ToLong(), *pActiveCall);
2028                 pActiveCall = null;
2029                 //using the callConnected to switch to Multiple active screen
2030                 pCallList = pTelManager->__pActiveCallList->GetValuesN();
2031                 pTelManager->__pEventListener->HandleCallConnected(*pCallList);
2032                 pCallList = null;
2033         }
2034         else
2035         {
2036                 pTelManager->__pEventListener->HandleTelephonyError(ERROR_SPLIT_FROM_CONFERENCE_FAILED);
2037         }
2038 }
2039
2040 void
2041 TelephonyManager::HandleIdleCallBack(void* pData, TelephonyManager* pTelManager)
2042 {
2043         TelCallStatusIdleNoti_t idleNotification;
2044         memcpy(&idleNotification, pData, sizeof(TelCallStatusIdleNoti_t));
2045         //handle end call event, show next screen
2046         unsigned int endCallHandle = idleNotification.id;
2047
2048         //fetch ended call details
2049         CallInfo endCallInfo;
2050         result r = pTelManager->__pActiveCallList->GetValue(endCallHandle, endCallInfo);
2051
2052         if (r == E_SUCCESS)
2053         {
2054                 //              if (endCallInfo.IsConferenceCall() == true && endCallInfo.GetCallerListCount() > 0 )
2055                 //              {
2056                 //                      pTelManager->__pSoundManager->SetSoundMode(SOUND_MODE_VOICE);
2057                 //                      return;
2058                 //              }
2059
2060                 //remove the call handle from active call list
2061                 pTelManager->__pActiveCallList->Remove(endCallHandle);
2062
2063                 //check if the ended call was the last call
2064                 bool isLastCall = (pTelManager->__pActiveCallList->GetCount() == 0);
2065
2066                 ArrayListT<CallInfo>* pCallList = null;
2067                 if (isLastCall)
2068                 {
2069                         pCallList = new (std::nothrow) ArrayListT<CallInfo>();
2070                         pCallList->Construct(1);
2071
2072                         //save end call details
2073                         //TODO: map error cause "idleNotification.cause" to error string.
2074                         String endCause(L"Call Ended Successfully");
2075                         endCallInfo.SetEndCallCause(endCause);
2076
2077                         //  long callDuration = abs(endInfo.CallEndTime - endInfo.CallStartTime);
2078                         // endCallInfo.SetEndCallDuration(callDuration);
2079                         //save to list
2080                         pCallList->Add(endCallInfo);
2081                 }
2082                 else
2083                 {
2084                         pCallList = static_cast<ArrayListT<CallInfo>*>(pTelManager->__pActiveCallList->GetValuesN());
2085                 }
2086
2087                 if (pTelManager->__isIncomingCallPresent == true)
2088                 {
2089                         pTelManager->__pSoundManager->StopAlert();
2090                         pTelManager->__isIncomingCallPresent = false;
2091                 }
2092                 // call should be active now. end the active call now
2093                 if (endCallInfo.IsConferenceCall() == false)
2094                 {
2095                         //Add call ended to call log database
2096                         pTelManager->__pCalllogMgr->AddCallogInfoToDatabase(&endCallInfo);
2097                         if(pTelManager->__pIncomingCall != null && ((unsigned int)pTelManager->__pIncomingCall->GetCallHandle()->ToLong() == endCallHandle))
2098                         {
2099                                 delete pTelManager->__pIncomingCall;
2100                                 pTelManager->__pIncomingCall = null;
2101                         }
2102                 }
2103                 else
2104                 {
2105                         int confCallCount = endCallInfo.GetCallerListCount();
2106                         IListT<CallInfo>* pCallList = endCallInfo.GetCallerList();
2107                         for (int index = 0; index < confCallCount; index++)
2108                         {
2109                                 CallInfo callInfo;
2110                                 pCallList->GetAt(index, callInfo);
2111                                 //Add call ended to call log database
2112                                 pTelManager->__pCalllogMgr->AddCallogInfoToDatabase(&callInfo);
2113                         }
2114                         //Once conference calls are added delete the incoming call info
2115                         if(pTelManager->__pIncomingCall != null )
2116                         {
2117                                 delete pTelManager->__pIncomingCall;
2118                                 pTelManager->__pIncomingCall = null;
2119                         }
2120                 }
2121                 if(pTelManager->__pActiveCallList->GetCount() == 0)
2122                 {
2123                         pTelManager->__pSoundManager->StopSession();
2124                 }
2125                 //notify listener that call is connected.
2126                 pTelManager->__pEventListener->HandleCallDisconnected(isLastCall, *pCallList);
2127                 delete pCallList;
2128                 pCallList = null;
2129         }
2130         else
2131         {
2132                 //check if the ended call was the dialed call
2133                 bool isLastCall = (pTelManager->__pActiveCallList->GetCount() == 0);
2134                 ArrayListT<CallInfo>* pCallList = null;
2135                 if (((pTelManager->__pDialedCall != null)  && (((unsigned int)pTelManager->__pDialedCall->GetCallHandle()->ToLong()) == idleNotification.id)))
2136                 {
2137                         //Call Ended is the dialed call
2138                         endCallInfo = *(pTelManager->__pDialedCall);
2139                         delete pTelManager->__pDialedCall;
2140                         pTelManager->__pDialedCall = null;
2141                         pTelManager->__pCalllogMgr->AddCallogInfoToDatabase(&endCallInfo);
2142                 }
2143                 else
2144                 {
2145                         //Could be incoming call. So notify if incoming call is present
2146                         if (isLastCall)
2147                         {
2148                                 pCallList = new (std::nothrow) ArrayListT<CallInfo>();
2149                         }
2150                         else
2151                         {
2152                                 pCallList = static_cast<ArrayListT<CallInfo>*>(pTelManager->__pActiveCallList->GetValuesN());
2153                         }
2154                         if(pTelManager->__pIncomingCall != null && ((unsigned int)pTelManager->__pIncomingCall->GetCallHandle()->ToLong() == endCallHandle))
2155                         {
2156                                 if((pTelManager->__pSettingsManager->IsCallToBeRejected(pTelManager->__pIncomingCall->GetContactNumber()) == false)
2157                                         && (pTelManager->__pSettingsManager->GetUnknownRejectStatus() == false))
2158                                 {
2159                                         //Missed Call
2160                                         pTelManager->__pIncomingCall->SetCalllogType(CALL_LOG_TYPE_VOICE_MISSED);
2161                                         pTelManager->__pCalllogMgr->AddCallogInfoToDatabase(pTelManager->__pIncomingCall);
2162                                 }
2163
2164                                 delete pTelManager->__pIncomingCall;
2165                                 pTelManager->__pIncomingCall = null;
2166                         }
2167                         if (pTelManager->__isIncomingCallPresent == true)
2168                         {
2169                                 pTelManager->__pSoundManager->StopAlert();
2170                                 pTelManager->__isIncomingCallPresent = false;
2171                                 if(pTelManager->__pActiveCallList->GetCount() == 0)
2172                                 {
2173                                         pTelManager->__pSoundManager->StopSession();
2174                                 }
2175                                 pTelManager->__pEventListener->HandleCallDisconnected(isLastCall, *pCallList);
2176                         }
2177                         delete pCallList;
2178                         pCallList = null;
2179                         pTelManager->__pSoundManager->SetSoundMode(SOUND_MODE_VOICE);
2180                         return;
2181                 }
2182
2183                 if (isLastCall)
2184                 {
2185                         pCallList = new (std::nothrow) ArrayListT<CallInfo>();
2186                         pCallList->Construct(1);
2187
2188                         //save end call details
2189                         //TODO: map error cause "idleNotification.cause" to error string.
2190                         String endCause(L"Call Ended Successfully");
2191                         endCallInfo.SetEndCallCause(endCause);
2192
2193                         //  long callDuration = abs(endInfo.CallEndTime - endInfo.CallStartTime);
2194                         // endCallInfo.SetEndCallDuration(callDuration);
2195                         //save to list
2196                         pCallList->Add(endCallInfo);
2197                 }
2198                 else
2199                 {
2200                         pCallList = static_cast<ArrayListT<CallInfo>*>(pTelManager->__pActiveCallList->GetValuesN());
2201                 }
2202                 if(pTelManager->__pActiveCallList->GetCount() == 0)
2203                 {
2204                         //notify listener that call is disconnected.
2205                         pTelManager->__pSoundManager->StopSession();
2206                 }
2207                 pTelManager->__pEventListener->HandleCallDisconnected(isLastCall, *pCallList);
2208                 delete pCallList;
2209                 pCallList = null;
2210         }
2211         pTelManager->__pSoundManager->SetSoundMode(SOUND_MODE_VOICE);
2212 }
2213
2214 void
2215 TelephonyManager::HandleDialingCallBack(void* pData, TelephonyManager* pTelManager)
2216 {
2217         unsigned int tempHandle = 0;
2218         TelCallStatusDialingNoti_t dialingNotification;
2219         memcpy(&tempHandle, pData, sizeof(TS_UINT));
2220         dialingNotification.id = tempHandle;
2221         if (pTelManager->__pDialedCall)
2222         {
2223                 pTelManager->__pDialedCall->SetCallHandle(dialingNotification.id);
2224                 //set start time, when call is connected
2225                 long long startTime = 0;
2226                 SystemTime::GetTicks(startTime);
2227                 pTelManager->__pDialedCall->SetCallNotificationTime(startTime);
2228                 pTelManager->__pDialedCall->SetCalllogType(CALL_LOG_TYPE_VOICE_OUTGOING);
2229         }
2230         else
2231         {
2232                 delete pTelManager->__pDialedCall;
2233                 pTelManager->__pDialedCall = new (std::nothrow) CallInfo();
2234                 pTelManager->__pDialedCall->SetCallHandle(dialingNotification.id);
2235                 TelCallStatus_t callStatus;
2236                 int res = tel_get_call_status(pTelManager->__pTapiHandle, dialingNotification.id, &callStatus);
2237                 if (res == TAPI_CAUSE_SUCCESS)
2238                 {
2239                         String contactNumber(callStatus.pNumber);
2240                         pTelManager->__pDialedCall->SetContactNumber(contactNumber);
2241                         result r = pTelManager->FetchContactInfoForNumber(contactNumber);
2242                         if (!IsFailed(r))
2243                         {
2244                                 pTelManager->__pDialedCall->SetContactInfo(*(pTelManager->__pCachedContact));
2245                         }
2246                         //set start time, when call is connected
2247                         long long startTime = 0;
2248                         SystemTime::GetTicks(startTime);
2249                         pTelManager->__pDialedCall->SetCallNotificationTime(startTime);
2250                         pTelManager->__pDialedCall->SetCalllogType(CALL_LOG_TYPE_VOICE_OUTGOING);
2251                         //set emergency state
2252                         if(callStatus.CallType == TAPI_CALL_TYPE_E911)
2253                         {
2254                                 pTelManager->__pDialedCall->SetEmergency(true);
2255                         }
2256                         else
2257                         {
2258                                 pTelManager->__pDialedCall->SetEmergency(false);
2259                         }
2260                 }
2261         }
2262 }
2263
2264 void
2265 TelephonyManager::HandleActiveCallBack(void* pData, TelephonyManager* pTelManager)
2266 {
2267         unsigned int tempHandle = 0;
2268         TelCallStatusActiveNoti_t activeNotification;
2269         memcpy(&tempHandle, pData, sizeof(TS_UINT));
2270         activeNotification.id = tempHandle;
2271         IListT<CallInfo>* pCallList = pTelManager->__pActiveCallList->GetValuesN();
2272
2273         //Check if the activated call is already present in already activated calls.
2274         bool toHandleEvent = true;
2275         for (int callIndex = 0; (callIndex < pCallList->GetCount() && toHandleEvent == true); callIndex++ )
2276         {
2277                 CallInfo tempCallInfo;
2278                 pCallList->GetAt(callIndex, tempCallInfo);
2279                 unsigned int tempCallHandle = tempCallInfo.GetCallHandle()->ToLong();
2280                 //Check if active callback came for "HandleJoinCallbackResponse"
2281                 //or for "UnHold Conf Call or normal call".
2282                 if(tempCallInfo.IsConferenceCall() == true)
2283                 {
2284                         if (tempCallHandle == activeNotification.id)
2285                         {
2286                                 toHandleEvent = false;
2287                         }
2288                         else
2289                         {
2290                                 //check individual participants of conf call
2291                                 IListT<CallInfo>* pConfCallList = tempCallInfo.GetCallerList();
2292                                 int confCallCount  = pConfCallList->GetCount();
2293                                 for (int callIndex = 0; (callIndex < confCallCount && toHandleEvent == true); callIndex++)
2294                                 {
2295                                         CallInfo confCallerInfo;
2296                                         pConfCallList->GetAt(callIndex, confCallerInfo);
2297                                         unsigned int confCallerHandle = confCallerInfo.GetCallHandle()->ToLong();
2298                                         if (confCallerHandle == activeNotification.id)
2299                                         {
2300                                                 toHandleEvent = false;
2301                                         }
2302                                 }
2303                         }
2304                 }
2305                 else if(tempCallHandle == activeNotification.id)
2306                 {
2307                         //If normal call is UnHold
2308                         toHandleEvent = false;
2309                 }
2310         }
2311         //If duplicate call handle, then to ignore the duplicate event.
2312         if(toHandleEvent == false)
2313         {
2314                 delete pCallList;
2315                 pCallList = null;
2316                 return;
2317         }
2318
2319         IListT<long>* pKeyList = pTelManager->__pActiveCallList->GetKeysN();
2320         if( pKeyList->Contains(activeNotification.id) == false)
2321         {
2322                 //handle call connected - save info
2323                 if (pTelManager->__pDialedCall != null)
2324                 {
2325                         pTelManager->__pDialedCall->SetCallHandle(activeNotification.id);
2326                         //set start time, when call is connected
2327                         long long startTime = 0;
2328                         SystemTime::GetTicks(startTime);
2329                         pTelManager->__pDialedCall->SetCallConnectTime(startTime);
2330
2331                         if (pTelManager->__pIncomingCall != null && activeNotification.id == (unsigned int)pTelManager->__pIncomingCall->GetCallHandle()->ToLong())
2332                         {
2333                                 pTelManager->__pDialedCall->SetCalllogType(CALL_LOG_TYPE_VOICE_INCOMING);
2334                                 delete pTelManager->__pIncomingCall;
2335                                 pTelManager->__pIncomingCall = null;
2336                         }
2337                         //transfer ownership to Active calls list
2338                         pTelManager->__pActiveCallList->Add(activeNotification.id, *(pTelManager->__pDialedCall));
2339                 }
2340                 else
2341                 {
2342                         //Construct a new CallInfo object for call
2343                         //This case will normally come here with incoming call
2344                         pTelManager->__pDialedCall = new (std::nothrow) CallInfo();
2345                         //__pDialedCall->SetRequestId(requestId);
2346                         pTelManager->__pDialedCall->SetCallHandle(activeNotification.id);
2347                         TelCallStatus_t callStatus;
2348                         memcpy(&tempHandle, pData, sizeof(TS_UINT));
2349                         int res = tel_get_call_status(pTelManager->__pTapiHandle, activeNotification.id, &callStatus);
2350                         if (res == TAPI_CAUSE_SUCCESS)
2351                         {
2352                                 String contactNumber(callStatus.pNumber);
2353                                 pTelManager->__pDialedCall->SetContactNumber(contactNumber);
2354                                 result r = pTelManager->FetchContactInfoForNumber(contactNumber);
2355                                 if (!IsFailed(r))
2356                                 {
2357                                         pTelManager->__pDialedCall->SetContactInfo(*(pTelManager->__pCachedContact));
2358                                 }
2359                                 //set emergency state
2360                                 if(callStatus.CallType == TAPI_CALL_TYPE_E911)
2361                                 {
2362                                         pTelManager->__pDialedCall->SetEmergency(true);
2363                                 }
2364                                 else
2365                                 {
2366                                         pTelManager->__pDialedCall->SetEmergency(false);
2367                                 }
2368                                 //set start time, when call is connected
2369                                 long long startTime = 0;
2370                                 SystemTime::GetTicks(startTime);
2371                                 pTelManager->__pDialedCall->SetCallConnectTime(startTime);
2372                                 if (pTelManager->__pIncomingCall != null && (activeNotification.id == (unsigned int)pTelManager->__pIncomingCall->GetCallHandle()->ToLong()))
2373                                 {
2374                                         pTelManager->__pDialedCall->SetCalllogType(CALL_LOG_TYPE_VOICE_INCOMING);
2375                                         pTelManager->__pDialedCall->SetCallNotificationTime(pTelManager->__pIncomingCall->GetCallNotificationTime());
2376                                 }
2377                                 //transfer ownership to Active calls list
2378                                 pTelManager->__pActiveCallList->Add(activeNotification.id, *(pTelManager->__pDialedCall));
2379                         }
2380                 }
2381         }
2382         delete pKeyList;
2383         pKeyList = null;
2384         pTelManager->__pDialedCall = null;
2385
2386         //notify listener that call is connected.
2387         pCallList = pTelManager->__pActiveCallList->GetValuesN();
2388         pTelManager->__pSoundManager->SetSoundMode(SOUND_MODE_VOICE);
2389         pTelManager->__pEventListener->HandleCallConnected(*pCallList);
2390         if (pTelManager->__isIncomingCallPresent == true)
2391         {
2392                 pTelManager->__pSoundManager->StopAlert();
2393                 pTelManager->__isIncomingCallPresent = false;
2394         }
2395         delete pCallList;
2396         pCallList = null;
2397 }
2398
2399 void
2400 TelephonyManager::HandleIncomingCallBack(void* pData, TelephonyManager* pTelManager)
2401 {
2402         unsigned int tempHandle = 0;
2403         TelCallStatus_t callStatus;
2404         memcpy(&tempHandle, pData, sizeof(TS_UINT));
2405         int res = tel_get_call_status(pTelManager->__pTapiHandle, tempHandle, &callStatus);
2406         if (res == TAPI_CAUSE_SUCCESS)
2407         {
2408                 //This case will normally come here with incoming call
2409                 delete pTelManager->__pIncomingCall;
2410                 pTelManager->__pIncomingCall = new (std::nothrow) CallInfo();
2411                 pTelManager->__pIncomingCall->SetCallHandle(tempHandle);
2412                 String contactNumber(callStatus.pNumber);
2413                 pTelManager->__pIncomingCall->SetContactNumber(contactNumber);
2414                 //set emergency state
2415                 if(callStatus.CallType == TAPI_CALL_TYPE_E911)
2416                 {
2417                         pTelManager->__pIncomingCall->SetEmergency(true);
2418                 }
2419                 else
2420                 {
2421                         pTelManager->__pIncomingCall->SetEmergency(false);
2422                 }
2423                 //set start time, when call is connected
2424                 long long startTime = 0;
2425                 SystemTime::GetTicks(startTime);
2426                 pTelManager->__pIncomingCall->SetCallNotificationTime(startTime);
2427                 pTelManager->__pIncomingCall->SetCalllogType(CALL_LOG_TYPE_VOICE_INCOMING);
2428                 //Check whether to reject incoming call or show incoming call screen to user.
2429                 bool isRejected = pTelManager->CheckIncomingCallToBeRejected(pTelManager->__pIncomingCall);
2430                 if(isRejected == false)
2431                 {
2432                         //show incoming call notification
2433                         CallInfo* pIncomingCall = new (std::nothrow) CallInfo();
2434                         *pIncomingCall = *(pTelManager->__pIncomingCall);
2435                         pTelManager->__pEventListener->HandleIncomingCall(*pIncomingCall);
2436                         delete pIncomingCall;
2437                 }
2438         }
2439 }
2440
2441 bool
2442 TelephonyManager::CheckIncomingCallToBeRejected(CallInfo* pIncomingCallInfo)
2443 {
2444         int callHandle = pIncomingCallInfo->GetCallHandle()->ToLong();
2445         String contactNumber(L"");
2446         contactNumber.Append(pIncomingCallInfo->GetContactNumber());
2447         //Fetch contact details from address book.
2448         Contact* pContactDetails = GetContactN(contactNumber);
2449         //Check if "reject unknown calls" is set and contact number is not present in AddressBook
2450         //or if contact number is blacklisted
2451         __isIncomingCallPresent = true;
2452         if (((__pSettingsManager->GetUnknownRejectStatus() == true) && (pContactDetails == null))
2453                         || (__pSettingsManager->IsCallToBeRejected(contactNumber) == true))
2454         {
2455                 AnswerCall(callHandle,false);
2456                 //save call rejected info
2457                 CallInfo* pRejectedCall = new (std::nothrow) CallInfo();
2458                 *pRejectedCall = *pIncomingCallInfo;
2459                 pRejectedCall->SetCalllogType(CALL_LOG_TYPE_VOICE_BLOCKED);
2460                 __pCalllogMgr->AddCallogInfoToDatabase(pRejectedCall);
2461                 delete pRejectedCall;
2462                 delete pContactDetails;
2463                 return true;
2464         }
2465         else
2466         {
2467                 //update contact person info
2468                 if (pContactDetails != null)
2469                 {
2470                         pIncomingCallInfo->SetContactInfo(*pContactDetails);
2471                         delete pContactDetails;
2472                 }
2473                 return false;
2474         }
2475 }
2476
2477 void
2478 TelephonyManager::HandleCallback(TapiHandle* pHandle, const char* pNotiId, void* pData, void* pUserData)
2479 {
2480         unsigned int tempHandle = 0;
2481         TelephonyManager* pTelManager = (TelephonyManager*) pUserData;
2482         if (pTelManager->__pSoundManager == null)
2483         {
2484                 AppLog("Creating Sound Manager");
2485                 pTelManager->__pSoundManager = new (std::nothrow) SoundManager();
2486         }
2487
2488
2489         if (strcmp(pNotiId, TAPI_NOTI_VOICE_CALL_STATUS_IDLE) == 0)
2490         {
2491                 HandleIdleCallBack(pData, pTelManager);
2492         }
2493         else if (strcmp(pNotiId, TAPI_NOTI_VOICE_CALL_STATUS_ACTIVE) == 0)
2494         {
2495                 pTelManager->__pSoundManager->StartSession();
2496                 HandleActiveCallBack(pData, pTelManager);
2497         }
2498         else if (strcmp(pNotiId, TAPI_NOTI_VOICE_CALL_STATUS_DIALING) == 0)
2499         {
2500                 HandleDialingCallBack(pData, pTelManager);
2501         }
2502         /*else if (strcmp(pNotiId, TAPI_NOTI_VOICE_CALL_STATUS_INCOMING) == 0)
2503         {
2504                 HandleIncomingCallBack(pData, pTelManager);
2505         }*/
2506         else if (strcmp(pNotiId, TAPI_NOTI_VOICE_CALL_STATUS_HELD) == 0)
2507         {
2508                 //TelCallStatusHeldNoti_t heldNotification;
2509                 memcpy(&tempHandle, pData, sizeof(TS_UINT));
2510         }
2511         else if (strcmp(pNotiId, TAPI_NOTI_CALL_INFO_WAITING) == 0)
2512         {
2513                 //TelCallInfoWaitingNoti_t waitingInfoNotification;
2514                 memcpy(&tempHandle, pData, sizeof(TS_UINT));
2515         }
2516         else if (strcmp(pNotiId, TAPI_NOTI_CALL_INFO_HELD) == 0)
2517         {
2518                 //TelCallInfoHeldNoti_t heldInfoNotification;
2519                 memcpy(&tempHandle, pData, sizeof(TS_UINT));
2520         }
2521         else if (strcmp(pNotiId, TAPI_NOTI_VOICE_CALL_STATUS_ALERT) == 0)
2522         {
2523                 //TelCallStatusAlertNoti_t alertNotification;
2524                 memcpy(&tempHandle, pData, sizeof(TS_UINT));
2525         }
2526         else if (strcmp(pNotiId, TAPI_NOTI_VOICE_CALL_STATUS_WAITING) == 0)
2527         {
2528                 //TelCallStatusWaitingNoti_t waitingNotification;
2529                 memcpy(&tempHandle, pData, sizeof(TS_UINT));
2530         }
2531         else if (strcmp(pNotiId, TAPI_NOTI_CALL_INFO_CALL_CONNECTED_LINE) == 0)
2532         {
2533                 //TelCallConnectedNumberInfo_t connectedNumberInfo;
2534                 memcpy(&tempHandle, pData, sizeof(TS_UINT));
2535         }
2536         else if (strcmp(pNotiId, TAPI_NOTI_CALL_INFO_ACTIVE) == 0)
2537         {
2538                 //TelCallInfoActiveNoti_t activeInfoNotification;
2539                 memcpy(&tempHandle, pData, sizeof(TS_UINT));
2540         }
2541         else if (strcmp(pNotiId, TAPI_NOTI_CALL_INFO_JOINED) == 0)
2542         {
2543                 //TelCallInfoJoinedNoti_t joinedInfoNotification;
2544                 memcpy(&tempHandle, pData, sizeof(TS_UINT));
2545         }
2546         else if (strcmp(pNotiId, TAPI_NOTI_CALL_INFO_RELEASED_ON_HOLD) == 0)
2547         {
2548                 memcpy(&tempHandle, pData, sizeof(TS_UINT));
2549         }
2550         else
2551         {
2552                 memcpy(&tempHandle, pData, sizeof(TS_UINT));
2553         }
2554 }
2555
2556 CallInfo*
2557 TelephonyManager::GetConferenceCallInfoN(void)
2558 {
2559         CallInfo* pConfCallInfo = null;
2560
2561         IListT<CallInfo>* pCallList = __pActiveCallList->GetValuesN();
2562         int callCount = pCallList->GetCount();
2563         for (int index = 0; index < callCount; index++)
2564         {
2565                 CallInfo callInfo;
2566                 pCallList->GetAt(index, callInfo);
2567                 if (callInfo.IsConferenceCall() == true)
2568                 {
2569                         pConfCallInfo = new (std::nothrow) CallInfo();
2570                         *pConfCallInfo = callInfo;
2571                         //Found the Conference call to be ended.
2572                         break;
2573                 }
2574         }
2575         delete pCallList;
2576         pCallList = null;
2577
2578         return pConfCallInfo;
2579 }
2580
2581 IListT<CallInfo>*
2582 TelephonyManager::GetCallListN(void)
2583 {
2584         ArrayListT<CallInfo>* pCallList = null;
2585         if (__pActiveCallList != null)
2586         {
2587                 pCallList = static_cast<ArrayListT<CallInfo>*>(__pActiveCallList->GetValuesN());
2588         }
2589         return pCallList;
2590 }
2591
2592 int
2593 TelephonyManager::GetCurrentCallCount(void)
2594 {
2595         if (__pActiveCallList != null)
2596         {
2597                 return __pActiveCallList->GetCount();
2598         }
2599         return 0;
2600 }
2601
2602 void
2603 TelephonyManager::StartAlert(CallInfo& incomingCallInfo)
2604 {
2605         __isIncomingCallPresent = true;
2606         String contactRingTone(L"");
2607         String contactNumber = incomingCallInfo.GetContactNumber();
2608         //check if not hidden call
2609         if(contactNumber.IsEmpty() == false)
2610         {
2611                 //fetch contact info from Db
2612                 Contact* foundContact = GetContactN(contactNumber);
2613                 if(foundContact != null)
2614                 {
2615                         //fetch custom ringtone for contact
2616                         result r = foundContact->GetValue(CONTACT_PROPERTY_ID_RINGTONE, contactRingTone);
2617                         AppLog("ringtone fetched - r = %d", r);
2618                         delete foundContact;
2619                         foundContact = null;
2620                 }
2621         }
2622         __pSoundManager->StartAlert(contactRingTone);
2623 }
2624
2625 void
2626 TelephonyManager::StopAlert(void)
2627 {
2628         __pSoundManager->StopAlert();
2629 }
2630
2631 result
2632 TelephonyManager::CheckValidTelePhoneNumber(const String& contactNumber)
2633 {
2634         result r = E_SUCCESS;
2635         if (contactNumber.GetLength() > TAPI_CALL_DIALDIGIT_LEN_MAX)
2636         {
2637                 r = E_FAILURE;
2638         }
2639         //TODO: check if valid phonenumber else return error message
2640         return r;
2641 }
2642
2643 result
2644 TelephonyManager::CheckIfMOCallIsPossible()
2645 {
2646         result r = E_SUCCESS;
2647
2648         //Check modem power status
2649         int modemStatus = 0;
2650         int errorCode = tel_check_modem_power_status(__pTapiHandle, &modemStatus);
2651         if (errorCode != TAPI_API_SUCCESS || modemStatus == TAPI_PHONE_POWER_STATUS_OFF
2652                         || modemStatus == TAPI_PHONE_POWER_STATUS_ERROR)
2653         {
2654                 r = E_FAILURE;
2655         }
2656         else
2657         {
2658                 TelSimCardStatus_t simStatus;
2659                 int simChangedStatus;
2660                 //fetch sim initialization status
2661                 int errorCode = tel_get_sim_init_info(__pTapiHandle, &simStatus, &simChangedStatus);
2662                 if (errorCode != TAPI_API_SUCCESS)
2663                 {
2664                         r = E_FAILURE;
2665                 }
2666                 else
2667                 {
2668                         switch (simStatus)
2669                         {
2670                         case TAPI_SIM_STATUS_SIM_INIT_COMPLETED: // Sim Initialization ok
2671                                 r = E_SUCCESS;
2672                                 break;
2673
2674                         case TAPI_SIM_STATUS_UNKNOWN: //initial state
2675                         case TAPI_SIM_STATUS_CARD_NOT_PRESENT: //Card not present
2676                         case TAPI_SIM_STATUS_CARD_REMOVED: //Card removed
2677                         case TAPI_SIM_STATUS_CARD_ERROR: // Bad card / On the fly, SIM gone bad
2678                                 //TODO: might want to set different error code, to give proper message to user
2679                                 r = E_FAILURE;
2680                                 break;
2681                         default:
2682                                 r = E_FAILURE;
2683                                 break;
2684                         }
2685                 }
2686         }
2687         return r;
2688 }
2689
2690 bool
2691 TelephonyManager::CheckIfMOCallIsEmergency(const String& contactNumber, bool isSimInitialized)
2692 {
2693         //TODO: extract actual telephone number from contactNumber
2694         //by deleting prefix,'P','W', etx.
2695
2696         bool isEmergency = false;
2697         //conversion "contactNumber" to char*
2698         const wchar_t* pContact = contactNumber.GetPointer();
2699         int len = contactNumber.GetLength() + 1;
2700         char* pNumber = new (std::nothrow) char[len];
2701         wcstombs(pNumber, pContact, len);
2702
2703         if(isSimInitialized)
2704         {
2705                 //used to get Ecc information for 2G and 3G.
2706                 TelSimEccList_t simEccList;
2707                 memset(&simEccList, 0x00, sizeof(TelSimEccList_t));
2708                 //Check if given number matches the sim card's emergency numbers
2709                 int errorCode = tel_get_sim_ecc(__pTapiHandle, &simEccList);
2710                 if (errorCode == TAPI_API_SUCCESS && simEccList.ecc_count > 0)
2711                 {
2712                         for (int index = 0; index < simEccList.ecc_count; index++)
2713                         {
2714                                 if ((strcmp(pNumber, simEccList.list[index].number) == 0))
2715                                 {
2716                                         isEmergency = true;
2717                                 }
2718                         }
2719                 }
2720         }
2721         else
2722         {
2723                 //TODO: check if we need to also check SOS call numbers, if sim not present.
2724         }
2725
2726         delete[] pNumber;
2727         pNumber = null;
2728         return isEmergency;
2729 }
2730
2731 result
2732 TelephonyManager::FetchContactInfoForNumber(const String& phoneNumberStr)
2733 {
2734         result r = E_FAILURE;
2735
2736         //delete previously cached data
2737         if (__pCachedContact != null)
2738         {
2739                 delete __pCachedContact;
2740                 __pCachedContact = null;
2741         }
2742
2743         //Searches contacts by phone number.
2744         IList* pContactList = __pAddressBook->SearchContactsByPhoneNumberN(phoneNumberStr);
2745         if (pContactList == null || IsFailed(GetLastResult()))
2746         {
2747                 return r;
2748         }
2749
2750         //Fetch the contact's info to be displayed
2751         IEnumerator* pContactEnum = pContactList->GetEnumeratorN();
2752         while ((E_SUCCESS == pContactEnum->MoveNext()) && (__pCachedContact == null))
2753         {
2754                 Contact* pContact = static_cast<Contact*>(pContactEnum->GetCurrent());
2755
2756                 IList* pPhoneNumberList = pContact->GetValuesN(CONTACT_MPROPERTY_ID_PHONE_NUMBERS);
2757                 if (pPhoneNumberList != null)
2758                 {
2759                         IEnumerator* pPhoneEnum = pPhoneNumberList->GetEnumeratorN();
2760                         while (E_SUCCESS == pPhoneEnum->MoveNext())
2761                         {
2762                                 PhoneNumber* pPhoneNumber = (PhoneNumber*) pPhoneEnum->GetCurrent();
2763                                 //Check if this is the correct contact
2764                                 if (pPhoneNumber->GetPhoneNumber().Equals(phoneNumberStr))
2765                                 {
2766                                         //save newly fetched contact info.
2767                                         __pCachedContact = new (std::nothrow) Contact(*pContact);
2768                                         r = E_SUCCESS;
2769                                         break;
2770                                 }
2771                         }
2772                         delete pPhoneEnum;
2773                         pPhoneNumberList->RemoveAll(true);
2774                         delete pPhoneNumberList;
2775                 }
2776         }
2777         delete pContactEnum;
2778         pContactList->RemoveAll(true);
2779         delete pContactList;
2780
2781         return r;
2782 }
2783
2784 Contact*
2785 TelephonyManager::GetContactN(const String& phoneNumber)
2786 {
2787         result r = FetchContactInfoForNumber(phoneNumber);
2788         if (!IsFailed(r))
2789         {
2790                 return new (std::nothrow) Contact(*__pCachedContact);
2791         }
2792         return null;
2793 }
2794
2795 CallInfo*
2796 TelephonyManager::FetchIncomingCallHandleN(const String& callHandle, const String& contactNumber)
2797 {
2798         if(__pIncomingCall != null)
2799         {
2800                 delete __pIncomingCall;
2801                 __pIncomingCall = null;
2802         }
2803
2804         if(callHandle.IsEmpty() == false)
2805         {
2806                 int incomingHandle;
2807                 Integer::Parse(callHandle,incomingHandle);
2808                 //This API call is synchronous
2809                 TelCallStatus_t callStatus;
2810                 int errCode = tel_get_call_status(__pTapiHandle, incomingHandle, &callStatus);
2811                 if (errCode != TAPI_API_SUCCESS)
2812                 {
2813                         AppLogDebug("tel_get_call_status_all failed");
2814                         return null;
2815                 }
2816                 //construct incoming call info object
2817                 __pIncomingCall = new (std::nothrow) CallInfo();
2818                 __pIncomingCall->SetCallHandle(incomingHandle);
2819
2820                 //contact number
2821                 String phoneNumber(contactNumber);
2822                 if(phoneNumber.IsEmpty() == true)
2823                 {
2824                         phoneNumber.Append(callStatus.pNumber);
2825                 }
2826                 __pIncomingCall->SetContactNumber(phoneNumber);
2827                 //set emergency state
2828                 if(callStatus.CallType == TAPI_CALL_TYPE_E911)
2829                 {
2830                         __pIncomingCall->SetEmergency(true);
2831                 }
2832                 else
2833                 {
2834                         __pIncomingCall->SetEmergency(false);
2835                 }
2836                 //set start time, when call is connected
2837                 long long startTime = 0;
2838                 SystemTime::GetTicks(startTime);
2839                 __pIncomingCall->SetCallNotificationTime(startTime);
2840                 __pIncomingCall->SetCalllogType(CALL_LOG_TYPE_VOICE_INCOMING);
2841         }
2842         else
2843         {
2844                 //TODO: This 'else' block can be removed once AppControl request API is stabilized.
2845                 //This API call is synchronous and 'HandleIncomingCallStatusCallBack' is called for each active call.
2846                 int errCode = tel_get_call_status_all(__pTapiHandle, &HandleIncomingCallStatusCallBack, this);
2847                 if (errCode != TAPI_API_SUCCESS)
2848                 {
2849                         return null;
2850                 }
2851         }
2852
2853         //construct a new callinfo object to pass its ownership to caller.
2854         if(__pIncomingCall != null)
2855         {
2856                 CallInfo* pNewIncomingCall = new (std::nothrow) CallInfo();
2857                 *pNewIncomingCall = *__pIncomingCall;
2858                 return pNewIncomingCall;
2859         }
2860         //return null, if no incoming call found
2861         return null;
2862 }
2863
2864 void
2865 TelephonyManager::HandleIncomingCallStatusCallBack(TelCallStatus_t* pCallStatus, void* pUserData)
2866 {
2867         TelephonyManager* pTelManager = (TelephonyManager*) pUserData;
2868         if (pCallStatus != null && pCallStatus->bMoCall == false
2869                         && ((pCallStatus->CallState == TAPI_CALL_STATE_INCOMING)
2870                                         || (pCallStatus->CallState == TAPI_CALL_STATE_WAITING)))
2871         {
2872                 //construct incoming call details
2873                 pTelManager->__pIncomingCall = new (std::nothrow) CallInfo();
2874                 pTelManager->__pIncomingCall->SetCallHandle(pCallStatus->CallHandle);
2875                 //contact number
2876                 String contactNumber(pCallStatus->pNumber);
2877                 pTelManager->__pIncomingCall->SetContactNumber(contactNumber);
2878                 //set emergency state
2879                 if(pCallStatus->CallType == TAPI_CALL_TYPE_E911)
2880                 {
2881                         pTelManager->__pIncomingCall->SetEmergency(true);
2882                 }
2883                 else
2884                 {
2885                         pTelManager->__pIncomingCall->SetEmergency(false);
2886                 }
2887                 //set start time, when call is connected
2888                 long long startTime = 0;
2889                 SystemTime::GetTicks(startTime);
2890                 pTelManager->__pIncomingCall->SetCallNotificationTime(startTime);
2891                 pTelManager->__pIncomingCall->SetCalllogType(CALL_LOG_TYPE_VOICE_INCOMING);
2892         }
2893 }