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