telephonyutils/etel3rdpartyapi/ExampleApps/IncomingCalls/CMainMenu.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 01:41:59 +0200
changeset 0 3553901f7fa8
child 24 6638e7f4bd8f
permissions -rw-r--r--
Revision: 201005 Kit: 201005

// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
//


#include "CMainMenu.h"
#include <simtsy.h>

/**
Factory constructor.

@param  aConsole Console to which output is printed
@return          Instance of CMainMenu class
*/
CMainMenu* CMainMenu::NewLC(CConsoleBase& aConsole)
	{
	CMainMenu* self = new(ELeave) CMainMenu(aConsole);
	CleanupStack::PushL(self);
	self->ConstructL();
	return self;
	}

/**
Constructor called by CMainMenu::NewLC().

@param Console to which output is printed
*/
CMainMenu::CMainMenu(CConsoleBase& aConsole)
	: CBaseMenuAsync(aConsole)
	{
	iCount = 0;
	iMessages = 0;
	iRecievedCalls = 0;
	iCallWaitingOn = EFalse;
	}

/**
Second phase constructor.
*/
void CMainMenu::ConstructL()
	{
	CBaseMenuAsync::ConstructL();
	iPhoneId = CPhoneId::NewL(this);

	// Create active objects using their factory constructors.
	iCallForwarding = CCallForwardingStatus::NewL(this);
	iCallBarring = CCallBarringStatus::NewL(this);
	iFlightModeInfo = CFlightModeInfo::NewL(this);
	iIdentityService = CIdentityServiceStatus::NewL(this);
	iCallWaiting = CCallWaitingStatus::NewL(this);

	iLineStatus = CLineStatus::NewL(this);
	iAnswerIncomingCall = CAnswerIncomingCall::NewL(this);
	iCallInfo = CCallInfo::NewL(this);
	iDummyAnswer = CDummyAnswer::NewL(this);
	iHangup = CHangup::NewL(this);

	iCallStatus = NULL;

	}

/**
Destructor.
Deletes owned objects.
*/
CMainMenu::~CMainMenu()
	{
	delete iTelephony;
	delete iPhoneId;

	delete iFlightModeInfo;
	delete iCallForwarding;
	delete iCallBarring;
	delete iIdentityService;
	delete iCallWaiting;

	delete iAnswerIncomingCall;
	delete iHangup;
	delete iCallStatus;
	delete iCallInfo;
	delete iDummyAnswer;
	delete iLineStatus;
	}

/**
Provides functionality for member objects to notify the Menu object (their 
owner) that they have completed their request.

@param aDerivedType Type of class derived from CISVAPIBase
*/
void CMainMenu::ExecComplete(TTelISVExampleType aDerivedType)
	{
   if (iState==ESetNotifier)
		{
		switch(aDerivedType)
			{
		case KLineStatus:
			iLastOperation = iLineStatus;
			break;
		case KCallInfo:
			iLastOperation = iCallInfo;
			break;
		case KCallStatus:
			iLastOperation = iCallStatus;
			break;
		case KAnswerIncomingCall:
			iLastOperation = iAnswerIncomingCall;
			break;
		case KHangup:
			iLastOperation = iHangup;
			break;
		case KCallForwardingStatus:
			iLastOperation = iCallForwarding;
			break;
		case KCallBarringStatus:
			iLastOperation = iCallBarring;
			break;
		case KFlightModeInfo:
			iLastOperation = iFlightModeInfo;
			break;
		case KIdentityServiceStatus:
			iLastOperation = iIdentityService;
			break;
		case KCallWaitingStatus:
			iLastOperation = iCallWaiting;
			break;
			}
			
		// Request to be told about particular events occurring.		
		TRAPD(errNotify, iLastOperation->RequestNotificationL());
		if (errNotify != KErrNone)
			{
			iConsole->Printf(_L("Notification Request for TTelISVExampleType"));
			iConsole->Printf(_L("%d left with error code "), aDerivedType);
			iConsole->Printf(_L("%d\n"), errNotify);
			return;
			};
			
		// Check the type of iLastOperation to see what it has been cast to.
		switch(iLastOperation->GetExampleType())
			{
		case KLineStatus:
			iConsole->ClearScreen();
			iConsole->Printf(KMenuMsg);
			CallsCount();
			iConsole->Printf(KAnyMsg);
			GetInput();
			break;
		case KAnswerIncomingCall:
			iCallId = reinterpret_cast<CAnswerIncomingCall*>
			          (iAnswerIncomingCall)->iCallId;
			TRAPD(err, 	iCallStatus = CCallStatus::NewL(this, iCallId));
			if (err != KErrNone)
				{
				iConsole->Printf(_L("CallStatus construction left "));
				iConsole->Printf(_L("with error code %d\n"), err);
				return;
				}
			iState = EGetCallStatus;
			iLastOperation = iCallStatus;
			SetActive();
			CompleteOwnRequest(KErrNone);
			break;
		case KCallInfo:
			iState = EAnswerIncomingCall;
			iLastOperation = iAnswerIncomingCall;
			SetActive();
			CompleteOwnRequest(KErrNone);
			break;
		case KCallStatus:
			iState = EDummyAnswer;
			SetActive();
			CompleteOwnRequest(KErrNone);
			break;
		case KFlightModeInfo:
			if (IsActive())
				{
				Cancel();
				}
			iState = ECallBarring;
			iLastOperation = iCallBarring;
			SetActive();
			CompleteOwnRequest(KErrNone);
			break;
		case KCallBarringStatus:
			iState = ECallForwarding;
			iLastOperation = iCallForwarding;
			SetActive();
			CompleteOwnRequest(KErrNone);
			break;
		case KCallForwardingStatus:
			iState = EIdentityService;
			iLastOperation = iIdentityService;
			SetActive();
			CompleteOwnRequest(KErrNone);
			break;
		case KIdentityServiceStatus:
			iState = ECallWaiting;
			iLastOperation = iCallWaiting;
			SetActive();
			CompleteOwnRequest(KErrNone);
			break;
		case KCallWaitingStatus:
			iCallWaitingOn = EFalse;
			iState = EGetLineStatus;
			iLastOperation = iLineStatus;
			SetActive();
			CompleteOwnRequest(KErrNone);
			break;
		default:

			break;
			}
		}
	else if(aDerivedType == KPhoneId)
		{
		iLastOperation = iFlightModeInfo;
		SetActive();
		CompleteOwnRequest(KErrNone);
		}
	else if (aDerivedType == KNotType)
		{
		iConsole->ClearScreen();
		iConsole->Printf(KMenuMsg);
		CallsCount();
		iConsole->Printf(KHangupMsg);
		GetInput();
		}
	}

/**
Provides functionality for member objects to notify the Menu object (their
owner) that they have been notified of a change.

@param aDerivedType Type of class derived from CISVAPIBase
*/
void CMainMenu::ExecNotify(TTelISVExampleType aDerivedType)
	{
	switch(aDerivedType)
		{
	case KAnswerIncomingCall:
		iCallId = reinterpret_cast<CAnswerIncomingCall*>
		          (iAnswerIncomingCall)->iCallId;
		TRAPD(err, iCallStatus = CCallStatus::NewL(this, iCallId));
		if (err != KErrNone)
			{
			iConsole->Printf(_L("CallStatus construction left "));
			iConsole->Printf(_L("with error code %d\n"), err);
			return;
			}
		iState = EGetCallStatus;
		iLastOperation = iCallStatus;
		SetActive();
		CompleteOwnRequest(KErrNone);
		break;
	case KCallWaitingStatus:
		iCallWaitingOn = ETrue;
		iState = EGetLineStatus;
		iLastOperation = iLineStatus;
		SetActive();
		CompleteOwnRequest(KErrNone);
		break;
	case KLineStatus:
		if (iCallStatus != NULL)
			{
			iConsole->Printf(_L("Call Waiting!\n"));
			iRecievedCalls++;
			iConsole->ClearScreen();
			iConsole->Printf(KMenuMsg);
			CallsCount();
			iConsole->Printf(KHangupMsg);
			GetInput();
			}
		else
			{
			// Request to be told about particular events occuring 
			TRAPD(err, iLineStatus->RequestNotificationL());
			if (err != KErrNone)
				{
				iConsole->Printf(_L("Request left with error code "));
				iConsole->Printf(_L("%d\n"),err);
				return;
				}
			iRecievedCalls++;
			iState = EGetCallInfo;
			iLastOperation = iCallInfo;
			SetActive();
			CompleteOwnRequest(KErrNone);
			}
		break;
	case KCallStatus:
		if (iFlightModeInfo->IsActive())
			{
			iFlightModeInfo->Cancel();
			}
		delete iCallStatus;
		iCallStatus = NULL;
 	  	iLineStatus->Cancel();
		iState = EStart;
		SetActive();
		CompleteOwnRequest(KErrNone);
		break;
	case KCallForwardingStatus:
		iState = ECallForwarding;
		iLastOperation = iCallForwarding;
		SetActive();
		CompleteOwnRequest(KErrNone);
		break;
		}
	}

/**
Responds appropriately depending on what key the user has pressed.
*/
void CMainMenu::RunL()
	{
	switch(iState)
		{
	case EStart:
		iState = EGetFlightModeInfo;
		if (iCount)
			{
			iCount = 0;
			iLastOperation = iFlightModeInfo;
			SetActive();
			CompleteOwnRequest(KErrNone);
			}
		else
			{
			iLastOperation = iPhoneId;
			TRAPD(errPhone, iLastOperation->StartRequestL());
			if (errPhone != KErrNone)
				{
				iConsole->Printf(_L("Request left with error code "));
				iConsole->Printf(_L("%d\n"), errPhone);
				return;
				};
			}
		break;
	case EEnd:
		iFlightModeInfo->Cancel();
		CActiveScheduler::Stop();
		break;
	case ECallWaiting:
	case EGetFlightModeInfo:
	case ECallForwarding:
	case ECallBarring:
	case EIdentityService:
	case EGetLineStatus:
	case EGetCallInfo:
	case EGetCallStatus:
	case EAnswerIncomingCall:
		iState = ESetNotifier;
		TRAPD(errAnswer, iLastOperation->StartRequestL());
		if (errAnswer != KErrNone)
			{
			iConsole->Printf(_L("Request left with error code "));
			iConsole->Printf(_L("%d\n"), errAnswer);
			return;
			};
		break;
	case EHangup:
		iDummyAnswer->Cancel();
		TRAPD(errArg, iLastOperation->StartRequestL(iCallId));
		if (errArg != KErrNone)
			{
			iConsole->Printf(_L("Request left with error code "));
			iConsole->Printf(_L("%d\n"), errArg);
			return;
			}
		break;
	case EDummyAnswer:
		iMessages++;
		iState = EHangup;
		TRAPD(errDummy, iDummyAnswer->StartCount(1000000));
		if (errDummy != KErrNone)
			{
			iConsole->Printf(_L("Request left with error code "));
			iConsole->Printf(_L("%d\n"), errDummy);
			return;
			};
		break;
	case EWaitingForKeyPress:
		{
		TInt c = iConsole->KeyCode();
		switch(c)
			{
		case 'E':
		case 'e':
		case EKeyEscape:
			// Cancel notifications
			if (iAnswerIncomingCall->IsActive())
				{
				iAnswerIncomingCall->Cancel();
				}
			if (iHangup->IsActive())
				{
				iHangup->Cancel();
				}
			if (iCallStatus != NULL && iCallStatus->IsActive())
				{
				iCallStatus->Cancel();
				}
			iFlightModeInfo->Cancel();
			iLineStatus->Cancel();
			CActiveScheduler::Stop();
			break;
		case 'h':
		case 'H':
			if (iDummyAnswer->IsActive())
				{
				iState = EHangup;
				iLastOperation = iHangup;
				SetActive();
				CompleteOwnRequest(KErrNone);
				break;
				}
			else
				{
				GetInput();
				break;
				}
		case 'i':
		case 'I':
			{
			CTelephony::TPhoneLine line = CTelephony::EVoiceLine;
			CTelephony::TCallStatusV1 iLineStatusV1;
  			CTelephony::TCallStatusV1Pckg iLineStatusV1Pckg(iLineStatusV1);
  			iTelephony->GetLineStatus(line, iLineStatusV1Pckg);
			CTelephony::TCallStatus voiceLineStatus = iLineStatusV1.iStatus;
			if (iCount >= 1
				&& iCallWaitingOn
				&& voiceLineStatus != CTelephony::EStatusRinging)
				{
				iCount++;
				TInt ret = RProperty::Set(KUidPSSimTsyCategory,
										  KPSSimTsyIncomingVoiceCall,
										  0);
				break;
				}
			else
				{
				GetInput();
				break;
				}
			}
		default:
		// Pressed a non suggested key to simulate an incoming call
			if (iCount == 0)
				{
				// For SIM TSY to simulate an incoming call
				iCount = 1;
		   		TInt ret = RProperty::Set(KUidPSSimTsyCategory,
		   								  KPSSimTsyIncomingVoiceCall,
		   								  0);
		   		}
		   	else
		   		{
					GetInput();
			   	}
				break;
			}
		}
		break;
	default:
		break;
		} // switch(iState)
	}

/**
Calculates the number of people who did not leave a message and displays result
to the console. Result = Number of received calls - Number of messages received
*/
void CMainMenu::CallsCount()
	{
	iConsole->Printf(_L("You have %d Messages\n"), iMessages);
	TInt difference = iRecievedCalls - iMessages;
	if (difference > 0)
		{
		iConsole->Printf(_L("%d people called and left no message\n"),
		                 difference);
		}
	}

/**
Cancels outstanding asynchronous request.
*/
void CMainMenu::DoCancel()
	{
	if(iState == EStart)
		{
		CompleteOwnRequest(KErrCancel);
		}
	else
		{
		iConsole->ReadCancel();
		}
	}