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