telephonyutils/etel3rdpartyapi/src/TelephonyFuncLine.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) 2009 Sony Ericsson Mobile Communications AB
* 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:
* Sony Ericsson Mobile Communications AB - initial contribution.
* Nokia Corporation - additional changes.
* 
* Contributors:
* 
* Description:
* Code for TelephonyFuncLine class, used by CTelephony class.
*
*/


/**
 @file
*/

#include <e32def.h>
#include "TelephonyFunctions.h"


TInt CTelephonyFunctions::GetLineStatus(const CTelephony::TPhoneLine& aLine, TDes8& aStatus)
/**
Get the current line status.
*/
	{
	TInt ret=KErrAccessDenied;
	
	if(IsFlightModeOn())
		{
		return KErrAccessDenied;
		}

	CTelephony::TCallStatusV1& CallStatusV1 = reinterpret_cast<CTelephony::TCallStatusV1&> ( const_cast<TUint8&> ( *aStatus.Ptr() ) );
	RMobileCall::TMobileCallStatus callStatus=RMobileCall::EStatusUnknown;

	switch(aLine)
	{
	case CTelephony::EVoiceLine:
		ret= iLineVoice.GetMobileLineStatus(callStatus);
		break;
	case CTelephony::EDataLine:
		if(iLineIsDataOpen)
			{
			ret= iLineData.GetMobileLineStatus(callStatus);
			}
		else
			{
			return KErrNotSupported;
			}
		break;
	case CTelephony::EFaxLine:
		if(iLineIsFaxOpen)
			{
			ret= iLineFax.GetMobileLineStatus(callStatus);
			}
		else
			{
			return KErrNotSupported;
			}
		break;
	default:
		return KErrNotFound;
	}
	GetCallStatus(callStatus, CallStatusV1.iStatus);
	return ret;
	}	

LOCAL_C void CloseArrayOfCallObjects(TAny* aCallArray)
/**
Close and delete the call object array.
*/
	{
	CArrayFixFlat<RMobileCall>* callArray = reinterpret_cast<CArrayFixFlat<RMobileCall>*>(aCallArray);
	TInt count = callArray->Count();
	for (TInt i=count-1; i>=0; --i)
		{
		callArray->At(i).Close();
		}	
	delete callArray;
 	callArray = NULL; 	
	}

TInt CTelephonyFunctions::GetCallInfoL(TDes8& aCallSelect, TDes8& aCallInfo, TDes8& aRemoteInfo)
/**
Get the current call information.
*/
	{
    CTelephony::TCallSelectionV1& CallSelectionV1 = reinterpret_cast<CTelephony::TCallSelectionV1&> 
                                                        ( const_cast<TUint8&> ( *aCallSelect.Ptr() ) );
    
	if(CallSelectionV1.iLine != CTelephony::EVoiceLine)
		{
		return KErrAccessDenied;
		}

	if(IsFlightModeOn())
		{
		return KErrAccessDenied;
		}

    CTelephony::TCallInfoV1& CallInfoV1 = reinterpret_cast<CTelephony::TCallInfoV1&> 
                                                        ( const_cast<TUint8&> ( *aCallInfo.Ptr() ) );

    CTelephony::TRemotePartyInfoV1& RemotePartyInfoV1 = reinterpret_cast<CTelephony::TRemotePartyInfoV1&> 
                                                        ( const_cast<TUint8&> ( *aRemoteInfo.Ptr() ) );	

	TPtr8* callInfoPkgPtr;
	RMobileCall::TMobileCallInfoV1* callInfoObjPtr;

	if(iTsyVersion == KNoMultimodeTsy)
		{
		return KErrNotSupported;
		}
	else if(iTsyVersion==KETelExtMultimodeV1 || iTsyVersion==KETelExtMultimodeV2)
		{
		RMobileCall::TMobileCallInfoV1*  callInfoV1 = new(ELeave) RMobileCall::TMobileCallInfoV1; 
		CleanupStack::PushL(callInfoV1);
		RMobileCall::TMobileCallInfoV1Pckg* callInfoV1Pckg = new(ELeave) RMobileCall::TMobileCallInfoV1Pckg(*callInfoV1); 
		CleanupStack::PushL(callInfoV1Pckg);
		callInfoPkgPtr = callInfoV1Pckg;
		callInfoObjPtr = callInfoV1;
		}
	else	//TSY v3
		{
		RMobileCall::TMobileCallInfoV3*  callInfoV3 = new(ELeave) RMobileCall::TMobileCallInfoV3; 
		CleanupStack::PushL(callInfoV3);
		RMobileCall::TMobileCallInfoV3Pckg* callInfoV3Pckg = new(ELeave) RMobileCall::TMobileCallInfoV3Pckg(*callInfoV3); 
		CleanupStack::PushL(callInfoV3Pckg);
		callInfoPkgPtr = callInfoV3Pckg;
		callInfoObjPtr = callInfoV3;
		}
 
	TInt numOfCalls=0;
	User::LeaveIfError(iLineVoice.EnumerateCall(numOfCalls));
	if (numOfCalls==0)
		{
		User::Leave(KErrNotFound);
		}
	CArrayFixFlat<RMobileCall>* tempCallArray = new (ELeave) CArrayFixFlat<RMobileCall>(numOfCalls);
	CleanupStack::PushL(TCleanupItem(CloseArrayOfCallObjects, tempCallArray));
	TInt i;
	
	RLine::TCallInfo callinfo;
	RMobileCall::TMobileCallStatus callStatus;
	TBool callFound=EFalse;
	for(i=0; i<numOfCalls; i++)
   		{
   		User::LeaveIfError(iLineVoice.GetCallInfo(i,callinfo));
   		RMobileCall tempCall; 
 		
 		tempCallArray->AppendL(tempCall);
 		User::LeaveIfError(tempCallArray->At(i).OpenExistingCall(iLineVoice,callinfo.iCallName));
		User::LeaveIfError(tempCallArray->At(i).GetMobileCallStatus(callStatus));
		 				
		if((callStatus==RMobileCall::EStatusConnected) &&
			(CallSelectionV1.iSelect==CTelephony::EActiveCall))
			{
			User::LeaveIfError(tempCallArray->At(i).GetMobileCallInfo(*callInfoPkgPtr));
			callFound=ETrue;
			break;
			}
		else if((callStatus==RMobileCall::EStatusHold) &&
			(CallSelectionV1.iSelect==CTelephony::EHeldCall))
			{
			User::LeaveIfError(tempCallArray->At(i).GetMobileCallInfo(*callInfoPkgPtr));
			callFound=ETrue;
			break;
			}
		else if(((callStatus==RMobileCall::EStatusDialling) ||
			  	(callStatus==RMobileCall::EStatusRinging) ||
			 	(callStatus==RMobileCall::EStatusAnswering) ||
				(callStatus==RMobileCall::EStatusConnecting) ||
				(callStatus==RMobileCall::EStatusReconnectPending) ||
				(callStatus==RMobileCall::EStatusDisconnecting) ||
				(callStatus==RMobileCall::EStatusDisconnectingWithInband) ||
				(callStatus==RMobileCall::EStatusTransferring) ||
				(callStatus==RMobileCall:: EStatusTransferAlerting) 
				) &&
			(CallSelectionV1.iSelect==CTelephony::EInProgressCall))
			{
			User::LeaveIfError(tempCallArray->At(i).GetMobileCallInfo(*callInfoPkgPtr));
			callFound=ETrue;
			break;
			}
		
		}	
	
	CleanupStack::PopAndDestroy(tempCallArray);	//tempCallArray
	if(!callFound)
		{
		CleanupStack::PopAndDestroy(2); //(callInfoV1Pckg or callInfoV3Pckg) AND (callInfoV1 or callInfoV3)		
		return KErrNotFound;
		}
	
	GetCallStatus(callInfoObjPtr->iStatus, CallInfoV1.iStatus);	

	if (callInfoObjPtr->iValid & RMobileCall::KCallSecurity)
		{
		if(callInfoObjPtr->ExtensionId() == KETelExtMultimodeV3)
			{
			RMobileCall::TMobileCallInfoV3* callInfoV3Ptr = reinterpret_cast<RMobileCall::TMobileCallInfoV3*>(callInfoObjPtr);
			
			switch(callInfoV3Ptr->iSecurity)
				{
			case RMobilePhone::ECipheringGSM:
				CallInfoV1.iSecurity = CTelephony::ECipheringGSM;
				break;
			case RMobilePhone::ECipheringWCDMA:
				CallInfoV1.iSecurity = CTelephony::ECipheringWCDMA;
				break;
			case RMobilePhone::ECipheringOff:
			default:
				CallInfoV1.iSecurity = CTelephony::ECipheringOff;
				break;
				}		
			}
		else
			CallInfoV1.iSecurity = CTelephony::ECipheringOff;
		}
	else
		{
		CallInfoV1.iSecurity = CTelephony::TPhoneNetworkSecurity();
		}

	
	if (callInfoObjPtr->iValid & RMobileCall::KCallStartTime)
		{
		CallInfoV1.iStartTime = callInfoObjPtr->iStartTime;
		}
	else
		{
		CallInfoV1.iStartTime = TDateTime();
		}
	if (callInfoObjPtr->iValid & RMobileCall::KCallDuration)
		{
		CallInfoV1.iDuration = callInfoObjPtr->iDuration;
		}
	else
		{
		CallInfoV1.iDuration = 0;
		}
	if (callInfoObjPtr->iValid & RMobileCall::KCallExitCode)
		{
		CallInfoV1.iExitCode = callInfoObjPtr->iExitCode;
		}
	else
		{
		CallInfoV1.iExitCode = 0;
		}
	
	if (callInfoObjPtr->iValid & RMobileCall::KCallDialledParty)
		{
		CopyTelAddress(callInfoObjPtr->iDialledParty, CallInfoV1.iDialledParty);
		}
	else
		{
		CallInfoV1.iDialledParty = CTelephony::TTelAddress();
		}

	//see whether we have an existing handle on the call
	CallInfoV1.iCallId = -1;
	RMobileCall* poolCall=NULL;
	RMobileCall::TMobileCallInfoV1  poolCallInfoV1;
	RMobileCall::TMobileCallInfoV1Pckg poolCallInfoV1Pckg(poolCallInfoV1);
	TInt err;
	
	for(int k=0;k<CTelephony::EISVMaxNumOfCalls;k++)
		{
		//get RMobileCall object
		if((poolCall = Call((CTelephony::TCallId)k)) != NULL)
			{
			//get call name
			err = poolCall->GetMobileCallInfo(poolCallInfoV1Pckg);
			if(err ==KErrNone)
				{
				//compare call names
				if(poolCallInfoV1.iCallName.MatchF(callinfo.iCallName)==0)
					{
					CallInfoV1.iCallId = k;
					break;			
					}
				}			
			}		
		}
		
	//fill TRemotePartyInfoV1
	RMobileCall::TMobileCallRemotePartyInfoV1& mobileRemoteParty = callInfoObjPtr->iRemoteParty;
	
	switch(mobileRemoteParty.iRemoteIdStatus)
		{
	case RMobileCall::ERemoteIdentityAvailable:
		RemotePartyInfoV1.iRemoteIdStatus = CTelephony::ERemoteIdentityAvailable;
		break;
	case RMobileCall::ERemoteIdentitySuppressed:
		RemotePartyInfoV1.iRemoteIdStatus = CTelephony::ERemoteIdentitySuppressed;
		break;
	case RMobileCall::ERemoteIdentityUnknown:
	default:
		RemotePartyInfoV1.iRemoteIdStatus = CTelephony::ERemoteIdentityUnknown;		
		break;
		}
		
	RemotePartyInfoV1.iCallingName.Copy(mobileRemoteParty.iCallingName);
	CopyTelAddress(mobileRemoteParty.iRemoteNumber, RemotePartyInfoV1.iRemoteNumber);
		
	switch(mobileRemoteParty.iDirection)
		{
	case RMobileCall::EMobileOriginated:
		RemotePartyInfoV1.iDirection = CTelephony::EMobileOriginated;
		break;
	case RMobileCall::EMobileTerminated:
		RemotePartyInfoV1.iDirection = CTelephony::EMobileTerminated;
		break;
	case RMobileCall::EDirectionUnknown:
	default:
		RemotePartyInfoV1.iDirection = CTelephony::EDirectionUnknown;
		break;
		}	
	
	CleanupStack::PopAndDestroy(2); //(callInfoV1Pckg or callInfoV3Pckg) AND (callInfoV1 or callInfoV3)
	
	return KErrNone;
	}	
	
void CTelephonyFunctions::CopyTelAddress(const RMobilePhone::TMobileAddress& aFromAddress, CTelephony::TTelAddress& aToAddress)
/**
Maps a RMobilePhone::TMobileAddress object to a CTelephony::TTelAddress object.
*/
	{
	aToAddress.iTelNumber.Copy(aFromAddress.iTelNumber);
	
	switch(aFromAddress.iTypeOfNumber)
		{
	case RMobilePhone::EInternationalNumber:
		aToAddress.iTypeOfNumber=CTelephony::EInternationalNumber;
		break;
	case RMobilePhone::ENationalNumber:
		aToAddress.iTypeOfNumber=CTelephony::ENationalNumber;
		break;
	case RMobilePhone::ENetworkSpecificNumber:
		aToAddress.iTypeOfNumber=CTelephony::ENetworkSpecificNumber;
		break;
	case RMobilePhone::ESubscriberNumber:
		aToAddress.iTypeOfNumber=CTelephony::ESubscriberNumber;
		break;
	case RMobilePhone::EAlphanumericNumber:
		aToAddress.iTypeOfNumber=CTelephony::EAlphanumericNumber;
		break;
	case RMobilePhone::EAbbreviatedNumber:
		aToAddress.iTypeOfNumber=CTelephony::EAbbreviatedNumber;
		break;
	case RMobilePhone::EUnknownNumber:
	default:
		aToAddress.iTypeOfNumber=CTelephony::EUnknownNumber;
		break;
		}

	switch(aFromAddress.iNumberPlan)
		{
	case RMobilePhone::EIsdnNumberPlan:
		aToAddress.iNumberPlan=CTelephony::EIsdnNumberPlan;
		break;
	case RMobilePhone::EDataNumberPlan:
		aToAddress.iNumberPlan=CTelephony::EDataNumberPlan;
		break;
	case RMobilePhone::ETelexNumberPlan:
		aToAddress.iNumberPlan=CTelephony::ETelexNumberPlan;
		break;
	case RMobilePhone::EServiceCentreSpecificPlan1:
		aToAddress.iNumberPlan=CTelephony::EServiceCentreSpecificPlan1;
		break;
	case RMobilePhone::EServiceCentreSpecificPlan2:
		aToAddress.iNumberPlan=CTelephony::EServiceCentreSpecificPlan2;
		break;
	case RMobilePhone::ENationalNumberPlan:
		aToAddress.iNumberPlan=CTelephony::ENationalNumberPlan;
		break;
	case RMobilePhone::EPrivateNumberPlan:
		aToAddress.iNumberPlan=CTelephony::EPrivateNumberPlan;
		break;
	case RMobilePhone::EERMESNumberPlan:
		aToAddress.iNumberPlan=CTelephony::EERMESNumberPlan;
		break;
	case RMobilePhone::EUnknownNumberingPlan:
	default:
		aToAddress.iNumberPlan=CTelephony::EUnknownNumberingPlan;
		break;
		}
	}