--- a/telephonyserverplugins/simtsy/src/CSimDataCall.cpp Mon May 03 13:37:20 2010 +0300
+++ b/telephonyserverplugins/simtsy/src/CSimDataCall.cpp Thu May 06 15:10:38 2010 +0100
@@ -1,1515 +1,1515 @@
-// Copyright (c) 2001-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:
-// This file contains the implementation of the Simulator TSY Data Call functionality.
-// The Call classes process the Call-based requests made by ETel clients
-// and passed down to the TSY by the ETel Server.
-//
-//
-
-/**
- @file
-*/
-
-#include <testconfigfileparser.h>
-#include "CSimDataCall.h"
-#include "CSimPhone.h"
-#include "Simlog.h"
-
-CSimDataCall* CSimDataCall::NewL(CSimLine* aLine,const TDesC& aName, CSimPhone* aPhone)
-/**
- * Standard two phase constructor.
- *
- * @param aLine pointer to the Line object.
- * @param aName name of the call to be constructed
- * @return CSimDataCall pointer to the data call object created
- * @leave Leaves if no memory or object is not created for any reason
- */
- {
- CSimDataCall* dataCall=new(ELeave) CSimDataCall(aLine,aName,aPhone);
- TCleanupItem newCallDataClose(CloseCall,dataCall);
- CleanupStack::PushL(newCallDataClose);
- dataCall->ConstructL();
- CleanupStack::Pop();
- return dataCall;
- }
-
-CSimDataCall::CSimDataCall(CSimLine* aLine,const TName& aName, CSimPhone* aPhone)
- : CSimCall(aLine,aName,aPhone), iCommPortLoaned(EFalse)
-/**
- * Trivial constructor. Calls CSimCall to initialise its members
- */
- {
- iCaps=Caps();
- }
-
-void CSimDataCall::ConstructL()
-/**
- * Second phase of 2-Phase Constructor
- * Retrieves all the pausing duration tags from the config file
- *
- * @param aName name of the data call to be constructed
- */
- {
- LOGDATA1("Starting to parse Data Call config parameters...");
-
- iDiallingPause=iLine->CfgFile()->ItemValue(KDiallingPauseDuration,KDefaultDiallingPauseDuration);
- iConnectingPause=iLine->CfgFile()->ItemValue(KConnectingPauseDuration,KDefaultConnectingPauseDuration);
- iDisconnectingPause=iLine->CfgFile()->ItemValue(KDisconnectingPauseDuration,KDefaultDisconnectingPauseDuration);
- iAnswerIncomingPause=iLine->CfgFile()->ItemValue(KAnswerIncomingPauseDuration,KDefaultAnswerIncomingPauseDuration);
- iRemoteHangupPause=iLine->CfgFile()->ItemValue(KRemoteHangupPauseDuration,KDefaultRemoteHangupPauseDuration);
-
-// Read in the CommPort setup
-
- const CTestConfigItem* item=iLine->CfgFile()->Item(KDataCallCaps);
- if(item)
- {
- TPtrC8 speedCaps, protocolCaps, serviceCaps, qosCaps, codingCaps, asymmetryCaps;
- TPtrC8 rlpVersionCaps, v42bisCaps;
- TBool hscsdSupport, userInitUpgrade;
- TInt mClass, MaxRxTimeslots, MaxTxTimeslots, totalRxTxTimeslots;
- TUint8 digit = 0;
-
- TInt ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,speedCaps);
- if(ret!=KErrNone)
- {
- LOGPARSERR("speedCaps",ret,0,&KDataCallCaps);
- }
- else
- if(AsciiToNum(speedCaps, digit)==KErrNone)
- iMobileCallCaps.iSpeedCaps = digit;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,protocolCaps);
- if(ret!=KErrNone)
- {
- LOGPARSERR("protocolCaps",ret,1,&KDataCallCaps);
- }
- else
- if(AsciiToNum(protocolCaps, digit)==KErrNone)
- iMobileCallCaps.iProtocolCaps = digit;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,serviceCaps);
- if(ret!=KErrNone)
- {
- LOGPARSERR("serviceCaps",ret,2,&KDataCallCaps);
- }
- else
- if(AsciiToNum(serviceCaps, digit)==KErrNone)
- iMobileCallCaps.iServiceCaps = digit;
-
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,qosCaps);
- if(ret!=KErrNone)
- {
- LOGPARSERR("qosCaps",ret,3,&KDataCallCaps);
- }
- else
- if(AsciiToNum(qosCaps, digit)==KErrNone)
- iMobileCallCaps.iQoSCaps = digit;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,4,hscsdSupport);
- if(ret!=KErrNone)
- {
- LOGPARSERR("hscsdSupport",ret,4,&KDataCallCaps);
- }
- else
- iMobileCallCaps.iHscsdSupport = hscsdSupport;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,5,mClass);
- if(ret!=KErrNone)
- {
- LOGPARSERR("mClass",ret,5,&KDataCallCaps);
- }
- else
- iMobileCallCaps.iMClass = mClass;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,6,MaxRxTimeslots);
- if(ret!=KErrNone)
- {
- LOGPARSERR("MaxRxTimeslots",ret,6,&KDataCallCaps);
- }
- else
- iMobileCallCaps.iMaxRxTimeSlots = MaxRxTimeslots;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,7,MaxTxTimeslots);
- if(ret!=KErrNone)
- {
- LOGPARSERR("MaxTxTimeslots",ret,7,&KDataCallCaps);
- }
- else
- iMobileCallCaps.iMaxTxTimeSlots = MaxTxTimeslots;
-
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,8,totalRxTxTimeslots);
- if(ret!=KErrNone)
- {
- LOGPARSERR("totalRxTxTimeslots",ret,8,&KDataCallCaps);
- }
- else
- iMobileCallCaps.iTotalRxTxTimeSlots = totalRxTxTimeslots;
-
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,9,codingCaps);
- if(ret!=KErrNone)
- {
- LOGPARSERR("codingCaps",ret,9,&KDataCallCaps);
- }
- else
- if(AsciiToNum(codingCaps, digit)==KErrNone)
- iMobileCallCaps.iCodingCaps = digit;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,10,asymmetryCaps);
- if(ret!=KErrNone)
- {
- LOGPARSERR("asymmetryCaps",ret,10,&KDataCallCaps);
- }
- else
- if(AsciiToNum(asymmetryCaps, digit)==KErrNone)
- iMobileCallCaps.iAsymmetryCaps = digit;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,11,userInitUpgrade);
- if(ret!=KErrNone)
- {
- LOGPARSERR("userInitUpgrade",ret,11,&KDataCallCaps);
- }
- else
- iMobileCallCaps.iUserInitUpgrade = userInitUpgrade;
-
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,10,rlpVersionCaps);
- if(ret!=KErrNone)
- {
- LOGPARSERR("rlpVersionCaps",ret,10,&KDataCallCaps);
- }
- else
- if(AsciiToNum(rlpVersionCaps, digit)==KErrNone)
- iMobileCallCaps.iRLPVersionCaps = digit;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,10,v42bisCaps);
- if(ret!=KErrNone)
- {
- LOGPARSERR("v42bisCaps",ret,10,&KDataCallCaps);
- }
- else
- if(AsciiToNum(v42bisCaps, digit)==KErrNone)
- iMobileCallCaps.iV42bisCaps = digit;
- }
- else //Default Values for Caps
- {
- iMobileCallCaps.iSpeedCaps=RMobileCall::KCapsSpeedAutobauding;
- iMobileCallCaps.iProtocolCaps=RMobileCall::KCapsProtocolV32;
- iMobileCallCaps.iServiceCaps=(RMobileCall::KCapsDataCircuitAsynchronous | RMobileCall::KCapsPacketAccessSyncUDI);
- iMobileCallCaps.iQoSCaps=RMobileCall::KCapsTransparentPreferred;
- iMobileCallCaps.iHscsdSupport=(TBool)(ETrue);
- iMobileCallCaps.iMClass=1;
- iMobileCallCaps.iMaxRxTimeSlots=5;
- iMobileCallCaps.iMaxTxTimeSlots=5;
- iMobileCallCaps.iTotalRxTxTimeSlots=10;
- iMobileCallCaps.iCodingCaps=(RMobileCall::KCapsAiurCoding48 | RMobileCall::KCapsAiurCoding96);
- iMobileCallCaps.iAsymmetryCaps=(RMobileCall::EAsymmetryUplink);
- iMobileCallCaps.iUserInitUpgrade=(TBool)(ETrue);
- iMobileCallCaps.iRLPVersionCaps = 1;
- iMobileCallCaps.iV42bisCaps = 1;
- }
-
- TInt count = iLine->CfgFile()->ItemCount(KDataRLPparams);
- TMobileCallRLPItem iMobileCallRLPItem;
- iMobileCallRLPList = new(ELeave) CArrayFixFlat<TMobileCallRLPItem>(5);
-
- if(count!=0)
- {
- for(TInt i=0;i<count;i++)
- {
-
- item = iLine->CfgFile()->Item(KDataRLPparams,i);
- if(!item)
- break;
-
- TInt iRlpVersion,iIWSMax,iIWSMin,iMWSMax,iMWSMin;
- TInt iT1Max,iT1Min,iN2Max,iN2Min,iT4Max,iT4Min;
-
- TInt ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,iRlpVersion);
- if(ret!=KErrNone)
- {
- LOGPARSERR("iRlpVersion",ret,0,&KDataRLPparams);
- }
- else
- iMobileCallRLPItem.iRlpVersion = iRlpVersion;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,iIWSMax);
- if(ret!=KErrNone)
- {
- LOGPARSERR("iIWSMax",ret,0,&KDataRLPparams);
- }
- else
- iMobileCallRLPItem.iMobileCallRLP.iIWSMax = iIWSMax;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,iIWSMin);
- if(ret!=KErrNone)
- {
- LOGPARSERR("iIWSMin",ret,1,&KDataRLPparams);
- }
- else
- iMobileCallRLPItem.iMobileCallRLP.iIWSMin = iIWSMin;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,iMWSMax);
- if(ret!=KErrNone)
- {
- LOGPARSERR("iMWSMax",ret,2,&KDataRLPparams);
- }
- else
- iMobileCallRLPItem.iMobileCallRLP.iMWSMax = iMWSMax;
-
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,iMWSMin);
- if(ret!=KErrNone)
- {
- LOGPARSERR("iMWSMin",ret,3,&KDataRLPparams);
- }
- else
- iMobileCallRLPItem.iMobileCallRLP.iMWSMin = iMWSMin;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,4,iT1Max);
- if(ret!=KErrNone)
- {
- LOGPARSERR("iT1Max",ret,4,&KDataRLPparams);
- }
- else
- iMobileCallRLPItem.iMobileCallRLP.iT1Max = iT1Max;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,5,iT1Min);
- if(ret!=KErrNone)
- {
- LOGPARSERR("iT1Min",ret,5,&KDataRLPparams);
- }
- else
- iMobileCallRLPItem.iMobileCallRLP.iT1Min = iT1Min;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,6,iN2Max);
- if(ret!=KErrNone)
- {
- LOGPARSERR("iN2Max",ret,6,&KDataRLPparams);
- }
- else
- iMobileCallRLPItem.iMobileCallRLP.iN2Max = iN2Max;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,7,iN2Min);
- if(ret!=KErrNone)
- {
- LOGPARSERR("iN2Min",ret,7,&KDataRLPparams);
- }
- else
- iMobileCallRLPItem.iMobileCallRLP.iN2Min = iN2Min;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,8,iT4Max);
- if(ret!=KErrNone)
- {
- LOGPARSERR("iT4Max",ret,8,&KDataRLPparams);
- }
- else
- iMobileCallRLPItem.iMobileCallRLP.iT4Max = iT4Max;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,9,iT4Min);
- if(ret!=KErrNone)
- {
- LOGPARSERR("iT4Min",ret,9,&KDataRLPparams);
- }
- else
- iMobileCallRLPItem.iMobileCallRLP.iT4Min = iT4Min;
-
- iMobileCallRLPList->AppendL(iMobileCallRLPItem);
- }
- }
- else
- {
- iMobileCallRLPItem.iRlpVersion=1;
- iMobileCallRLPItem.iMobileCallRLP.iIWSMax=10;
- iMobileCallRLPItem.iMobileCallRLP.iIWSMin=5;
- iMobileCallRLPItem.iMobileCallRLP.iMWSMax=8;
- iMobileCallRLPItem.iMobileCallRLP.iMWSMin=4;
- iMobileCallRLPItem.iMobileCallRLP.iT1Max=4;
- iMobileCallRLPItem.iMobileCallRLP.iT1Min=2;
- iMobileCallRLPItem.iMobileCallRLP.iN2Max=12;
- iMobileCallRLPItem.iMobileCallRLP.iN2Min=1;
- iMobileCallRLPItem.iMobileCallRLP.iT4Max=10;
- iMobileCallRLPItem.iMobileCallRLP.iT4Min=2;
- iMobileCallRLPList->AppendL(iMobileCallRLPItem);
- }
-
- item=iLine->CfgFile()->Item(KDynamicHSCSDInfo);
- if(item)
- {
- TPtrC8 iAiur,iCodings;
- TInt iRxTimeSlots,iTxTimeSlots;
-
- TUint8 digit=0;
-
- TInt ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,iAiur);
- if(ret!=KErrNone)
- {
- LOGPARSERR("iAiur",ret,0,&KDynamicHSCSDInfo);
- }
- else
- if(AsciiToNum(iAiur, digit)==KErrNone)
- iHscsdInfo.iAiur = (RMobileCall::TMobileCallAiur) digit;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,iRxTimeSlots);
- if(ret!=KErrNone)
- {
- LOGPARSERR("iRxTimeSlots",ret,1,&KDynamicHSCSDInfo);
- }
- else
- iHscsdInfo.iRxTimeSlots = iRxTimeSlots;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,iTxTimeSlots);
- if(ret!=KErrNone)
- {
- LOGPARSERR("iTxTimeSlots",ret,2,&KDynamicHSCSDInfo);
- }
- else
- iHscsdInfo.iTxTimeSlots = iTxTimeSlots;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,iCodings);
- if(ret!=KErrNone)
- {
- LOGPARSERR("iCodings",ret,3,&KDynamicHSCSDInfo);
- }
- else
- if(AsciiToNum(iCodings, digit)==KErrNone)
- iHscsdInfo.iCodings = (RMobileCall::TMobileCallTchCoding) digit;
- }
- else
- {
- iHscsdInfo.iAiur=RMobileCall::EAiurBps9600;
- iHscsdInfo.iRxTimeSlots=5;
- iHscsdInfo.iTxTimeSlots=10;
- iHscsdInfo.iCodings=RMobileCall::ETchCoding48;
- }
-
- item=iLine->CfgFile()->Item(KCommSetup);
- if(item)
- {
- TPtrC8 portName,csyName;
- TInt err=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,csyName); // The 3rd parameter (0) represents the index of the variable on the config file line
- if (err!=KErrNone)
- {
- LOGPARSERR("csyName",err,0,&KCommSetup);
- iCsyName.Copy(KDefaultCsyName);
- }
- else
- iCsyName.Copy(csyName);
-
- err=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,portName); // The 3rd parameter (1) represents the index of the variable on the config file line
- if (err!=KErrNone)
- {
- LOGPARSERR("portName",err,1,&KCommSetup);
- iPortName.Copy(KDefaultPortName);
- }
- else
- iPortName.Copy(portName);
-
- TInt dataRate,handshake;
- err=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,dataRate); // The 3rd parameter (2) represents the index of the variable on the config file line
- if (err!=KErrNone)
- {
- LOGPARSERR("dataRate",err,2,&KCommSetup);
- iConfig.iRate=KDefaultCommPortRate;
- }
- else
- iConfig.iRate=(TBps)dataRate;
-
- err=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,handshake); // The 3rd parameter (3) represents the index of the variable on the config file line
- if (err!=KErrNone)
- {
- LOGPARSERR("handshake",err,3,&KCommSetup);
- iConfig.iHandshake=KDefaultHandshake;
- }
- else
- iConfig.iHandshake=(TUint)handshake;
- }
- else
- {
- iCsyName.Copy(KDefaultCsyName);
- iPortName.Copy(KDefaultPortName);
- iConfig.iRate=KDefaultCommPortRate;
- iConfig.iHandshake=KDefaultHandshake;
- }
-
-// Read in the Bearer Service information
- item=iLine->CfgFile()->Item(KBearerService);
- if(item)
- {
- TInt bearerCaps,bearerSpeed;
- TInt err=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,bearerCaps); // The 3rd parameter (0) represents the index of the variable on the config file line
- if (err!=KErrNone)
- {
- LOGPARSERR("bearerCaps",err,0,&KBearerService);
- iBearerService.iBearerCaps=KDefaultBearerCaps;
- }
- else
- iBearerService.iBearerCaps=bearerCaps;
-
- err=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,bearerSpeed); // The 3rd parameter (1) represents the index of the variable on the config file line
- if (err!=KErrNone)
- {
- LOGPARSERR("bearerSpeed",err,1,&KBearerService);
- iBearerService.iBearerSpeed=KDefaultBearerSpeed;
- }
- else
- iBearerService.iBearerSpeed=(RCall::TCallBearerSpeed)bearerSpeed;
-
- }
- else
- {
- iBearerService.iBearerCaps=KDefaultBearerCaps;
- iBearerService.iBearerSpeed=KDefaultBearerSpeed;
- }
-
- iTimer=CSimTimer::NewL(iLine->iPhone);
- iNtRas=CSimNtRas::NewL(iLine->iPhone);
- CSimCall::ConstructL();
-
- //If present read in remote party info tag
- TPtrC8 callingname, remotenumber;
- TInt delay=0;
-
- item=iLine->CfgFile()->Item(KNotifyRemotePartyInfo);
-
- TInt ret;
-
- if (item)
- {
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,delay);
- if(ret!=KErrNone)
- {
- LOGPARSERR("delay",ret,0,&KNotifyRemotePartyInfo);
- }
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,callingname);
- if(ret!=KErrNone)
- {
- LOGPARSERR("callingname",ret,1,&KNotifyRemotePartyInfo);
- }
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,remotenumber);
- if(ret!=KErrNone)
- {
- LOGPARSERR("remotenumber",ret,2,&KNotifyRemotePartyInfo);
- }
-
- iNotifyRemotePartyInfoTimer->iDelay = delay;
- iNotifyRemotePartyInfoTimer->iRemotePartyInfoV1.iDirection = RMobileCall::EDirectionUnknown;
- iNotifyRemotePartyInfoTimer->iRemotePartyInfoV1.iCallingName.Copy(callingname);
- iNotifyRemotePartyInfoTimer->iRemotePartyInfoV1.iRemoteNumber.iTelNumber.Copy(remotenumber);
- iNotifyRemotePartyInfoTimer->iRemotePartyInfoV1.iRemoteNumber.iTypeOfNumber = RMobilePhone::EInternationalNumber;
- iNotifyRemotePartyInfoTimer->iRemotePartyInfoV1.iRemoteNumber.iNumberPlan = RMobilePhone::EIsdnNumberPlan;
- iNotifyRemotePartyInfoTimer->iRemotePartyInfoV1.iRemoteIdStatus = RMobileCall::ERemoteIdentityAvailable;
- }
- else
- {
- iNotifyRemotePartyInfoTimer->iRemotePartyInfoV1.iRemoteIdStatus = RMobileCall::ERemoteIdentityUnknown;
- }
-
- LOGDATA1("...Finished parsing Data Call config parameters...");
- }
-
-CSimDataCall::~CSimDataCall()
-/**
- * Destroy all the objects constructed.
- * CSimTimer and CSimSysAgent objects are destroyed here
- */
- {
- delete iNtRas;
- delete iTimer;
- if(iAnswerIncomingCall.iNotifyPending)
- iLine->ResetAutoAnswerCallObject(this);
- if(iMobileCallRLPList)
- {
- iMobileCallRLPList->Delete(0,iMobileCallRLPList->Count());
- delete iMobileCallRLPList;
- }
- }
-
-TInt CSimDataCall::ExtFunc(const TTsyReqHandle aTsyReqHandle,const TInt aIpc,const TDataPackage& aPackage)
-/**
- * ExtFunc is called by the server when it has a "extended", i.e. non-core ETel request
- * for the TSY to process
- * A request handle, request type and request data are passed to the TSY
- *
- * @param aTsyReqHandle
- * @param aIpc IPc number representing the request
- * @param aPackage data for the request
- * @return KErrNone
- */
- {
- TAny* dataPtr=aPackage.Ptr1();
- TAny* dataPtr2=aPackage.Ptr2();
-
- LOGDATA2("CSimDataCall::ExtFunc: IPC Number is %d",aIpc);
- // The request data has to extracted from TDataPackage and the TAny* pointers have to
- // be "cast" to the expected request data type
-
- switch (aIpc)
- {
- //
- // No Flow Control NOR Multiple Completion
- //
- case EMobileCallGetMobileCallCaps:
- return GetMobileCallCaps(aTsyReqHandle,aPackage.Des1n());
-
- case EMobileCallGetMobileDataCallCaps:
- return GetMobileDataCallCaps(aTsyReqHandle,aPackage.Des1n());
-
- case EMobileCallGetMobileDataCallRLPRange:
- return GetMobileDataCallRLPRange(aTsyReqHandle,
- REINTERPRET_CAST(TInt*,dataPtr),
- REINTERPRET_CAST(TDes8*,dataPtr2));
-
- case EMobileCallSetDynamicHscsdParams:
- return SetDynamicHSCSDParams(aTsyReqHandle,
- REINTERPRET_CAST(RMobileCall::TMobileCallAiur*,dataPtr),
- REINTERPRET_CAST(TInt*,dataPtr2));
-
- case EMobileCallGetCurrentHscsdInfo:
- return GetCurrentHSCSDInfo(aTsyReqHandle, aPackage.Des1n());
-
- case EMobileCallGetMobileCallStatus:
- return GetMobileCallStatus(aTsyReqHandle,
- REINTERPRET_CAST(RMobileCall::TMobileCallStatus*,dataPtr));
-
- case EMobileCallGetMobileCallInfo:
- return GetMobileCallInfo(aTsyReqHandle,aPackage.Des1n());
-
- //
- // Multiple Completion Services with Immediate Server Repost
- // (Usually Notifications)
- //
- case EMobileCallNotifyMobileCallStatusChange:
- return NotifyMobileCallStatusChange(aTsyReqHandle,
- REINTERPRET_CAST(RMobileCall::TMobileCallStatus*, dataPtr));
-
- case EMobileCallNotifyMobileCallCapsChange:
- return NotifyMobileCallCapsChange(aTsyReqHandle, aPackage.Des1n());
-
- case EMobileCallNotifyMobileDataCallCapsChange:
- return NotifyMobileDataCapsChange(aTsyReqHandle, aPackage.Des1n());
-
- case EMobileCallNotifyHscsdInfoChange:
- return NotifyHSCSDInfoChange(aTsyReqHandle, aPackage.Des1n());
-
- case EMobileCallNotifyRemotePartyInfoChange:
- return NotifyRemotePartyInfoChange(aTsyReqHandle, aPackage.Des1n());
-
- default:
- LOGDATA2("CSimDataCall::ExtFunc: Unsupported IPC detected - number %d",aIpc);
- break;
- }
-
- return KErrNotSupported;
- }
-
-TInt CSimDataCall::CancelService(const TInt aIpc,const TTsyReqHandle aTsyReqHandle)
-/**
- * Cancel an outstanding request.
- * @param aIpc The IPC number of the request that must be cancelled. Note: this is not the
- * IPC number of the cancel request itself.
- * @param aTsyReqHandle The TSY Request Handle of the request to be cancelled.
- */
- {
- switch(aIpc)
- {
- case EMobileCallNotifyMobileCallStatusChange:
- return NotifyMobileCallStatusChangeCancel(aTsyReqHandle);
-
- case EMobileCallNotifyMobileCallCapsChange:
- return NotifyMobileCallCapsChangeCancel(aTsyReqHandle);
-
- case EMobileCallNotifyMobileDataCallCapsChange:
- return NotifyMobileDataCapsChangeCancel(aTsyReqHandle);
-
- case EMobileCallSetDynamicHscsdParams:
- return SetDynamicHSCSDParamsCancel(aTsyReqHandle);
-
- case EMobileCallGetMobileDataCallCaps:
- return GetMobileDataCallCapsCancel(aTsyReqHandle);
-
- case EMobileCallGetMobileDataCallRLPRange:
- return GetMobileDataCallRLPRangeCancel(aTsyReqHandle);
-
- case EMobileCallNotifyHscsdInfoChange:
- return NotifyHSCSDInfoChangeCancel(aTsyReqHandle);
-
- case EMobileCallNotifyRemotePartyInfoChange:
- return NotifyRemotePartyInfoChangeCancel();
-
- default:
- LOGDATA1("CSimDataCall::CancelService: No match for IPC, defering to base function");
- break;
- }
- return CCallBase::CancelService(aIpc,aTsyReqHandle);
- }
-
-TInt CSimDataCall::Dial(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams,TDesC* /*aTelNumber*/)
-/**
- * Process a client's dial request.
- *
- * @param aTsyReqHandle
- * @param aCallParams the call parameters
- * @param aTelNumber The telephone number to dial
- * @return KErrNone
- */
- {
- LOGDATA1(">>CSimDataCall::Dial");
- iDialRequestHandle=aTsyReqHandle;
- PopulateCallParams(aCallParams);
-
- TInt err=ActionEvent(ECallEventDial,KErrNone);
- if(err!=KErrNone)
- ReqCompleted(aTsyReqHandle,err);
-
- LOGDATA1("<<CSimDataCall::Dial");
- return KErrNone;
- }
-
-TInt CSimDataCall::DialCancel(const TTsyReqHandle /*aTsyReqHandle*/)
-/**
-* Cancels a dial Request
-*
-* @param aTsyReqHandle
-* @return KErrNone if successfully cancelled
-*/
- {
- LOGDATA1(">>CSimDataCall::DialCancel");
- switch(iState)
- {
- case RMobileCall::EStatusIdle:
- case RMobileCall::EStatusConnected:
- SimPanic(EIllegalCancelRequest); // A DialCancel should never reach the TSY in this state.
- break;
-
- case RMobileCall::EStatusDialling:
- case RMobileCall::EStatusConnecting:
- iTimer->Cancel();
-
- TInt err;
- err = KErrNone;
- TRAP(err, ChangeStateL(RMobileCall::EStatusIdle,EFalse,EFalse));
- if (err != KErrNone)
- {
- ReqCompleted(iDialRequestHandle, err);
- }
- else
- {
- ReqCompleted(iDialRequestHandle, KErrCancel);
- }
- break;
-
- default:
- LOGDATA2("CSimDataCall::DialCancel: No action taken - state: %d",iState);
- break;
- }
- LOGDATA1("<<CSimDataCall::DialCancel");
- return KErrNone;
- }
-
-TInt CSimDataCall::AnswerIncomingCall(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams)
-/**
-* Register a client's interest in answering the next incoming call.
-* First register interest in incoming calls with the line, then, if a call
-* is already ringing, start the answer procedure.
-*
-* @param aTsyReqHandle
-* @param aCallParams the call parameters
-* @return KErrNone
-*/
- {
- LOGDATA1(">>CSimDataCall::AnswerIncomingCall");
- TInt err=iLine->SetAutoAnswerCallObject(this);
- if(err!=KErrNone)
- {
- ReqCompleted(aTsyReqHandle,err);
- return KErrNone;
- }
-
- PopulateCallParams(aCallParams);
- iAnswerIncomingCall.iNotifyPending=ETrue;
- iAnswerIncomingCall.iNotifyHandle=aTsyReqHandle;
-
- TInt ret=KErrNone;
- if(iState==RMobileCall::EStatusRinging)
- ActionEvent(ECallEventAnswerIncoming,KErrNone);
- else if(iLine->iState==RMobileCall::EStatusRinging)
- {
- TRAP(ret,ret=ChangeStateL(RMobileCall::EStatusRinging,EFalse,EFalse));
- if(ret == KErrNone)
- {
- ret = ActionEvent(ECallEventAnswerIncoming,KErrNone);
- }
- }
- LOGDATA1("<<CSimDataCall::AnswerIncomingCall");
- return ret;
- }
-
-TInt CSimDataCall::AnswerIncomingCallCancel(const TTsyReqHandle /*aTsyReqHandle*/)
-/**
-* Cancels a AnswerIncomingCall Request
-*
-* @param aTsyReqHandle
-* @return KErrNone if successfully cancelled
-*/
- {
- LOGDATA1(">>CSimDataCall::AnswerIncomingCallCancel");
- if(iAnswerIncomingCall.iNotifyPending)
- {
- iAnswerIncomingCall.iNotifyPending=EFalse;
- iLine->ResetAutoAnswerCallObject(this);
- ReqCompleted(iAnswerIncomingCall.iNotifyHandle,KErrCancel);
- }
- LOGDATA1("<<CSimDataCall::AnswerIncomingCallCancel");
- return KErrNone;
- }
-
-TInt CSimDataCall::Connect(const TTsyReqHandle aTsyReqHandle,const TDesC8* /*aCallParams*/)
- {
- ReqCompleted(aTsyReqHandle,KErrNotSupported);
- return KErrNone;
- }
-
-TInt CSimDataCall::ConnectCancel(const TTsyReqHandle aTsyReqHandle)
- {
- ReqCompleted(aTsyReqHandle,KErrNotSupported);
- return KErrNone;
- }
-
-TInt CSimDataCall::HangUp(const TTsyReqHandle aTsyReqHandle)
-/**
-* Process a client's HangUp request.
-*
-* @param aTsyReqHandle
-* @return KErrNone
-*/
- {
- LOGDATA1(">>CSimDataCall::HangUp");
- iHangUpRequestHandle=aTsyReqHandle;
- TInt err=ActionEvent(ECallEventHangUp,KErrNone);
- if(err!=KErrNone)
- ReqCompleted(aTsyReqHandle,err);
- LOGDATA1("<<CSimDataCall::HangUp");
- return KErrNone;
- }
-
-TInt CSimDataCall::HangUpCancel(const TTsyReqHandle /*aTsyReqHandle*/)
-/**
-* Cancels a HangUp Request
-*
-* @param aTsyReqHandle
-* @return KErrNone if successfully cancelled
-*/
- {
- LOGDATA1(">>CSimDataCall::HangUpCancel");
- switch(iState)
- {
- case RMobileCall::EStatusIdle:
- SimPanic(EIllegalCancelRequest); // A DialCancel should never reach the TSY in this state.
- break;
-
- case RMobileCall::EStatusDisconnecting:
- iTimer->Cancel();
-
- TInt err;
- err = KErrNone;
- TRAP(err, ChangeStateL(RMobileCall::EStatusIdle,EFalse,EFalse));
- if (err != KErrNone)
- {
- ReqCompleted(iHangUpRequestHandle, err);
- }
- else
- {
- ReqCompleted(iHangUpRequestHandle, KErrCancel);
- }
- break;
-
- default:
- LOGDATA2("CSimDataCall::HangUpCancel: No action taken - state: %d",iState);
- break;
- }
- LOGDATA1("<<CSimDataCall::HangUpCancel");
- return KErrNone;
- }
-
-TInt CSimDataCall::RelinquishOwnership()
- {
- return KErrNotSupported;
- }
-
-TInt CSimDataCall::GetBearerServiceInfo(const TTsyReqHandle aTsyReqHandle,RCall::TBearerService* aBearerService)
-/**
- * Retrieves the bearer service info. Bearer service information is only valid
- * when the call is active.
- */
- {
- if(iState!=RMobileCall::EStatusConnected)
- {
- ReqCompleted(aTsyReqHandle,KErrEtelCallNotActive);
- return KErrNone;
- }
-
- *aBearerService=iBearerService;
- ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
-
-TInt CSimDataCall::GetCallParams(const TTsyReqHandle aTsyReqHandle, TDes8* aCallParams)
-/**
- * Retrives the call parameters. This function must handle both core and Multimode
- * extension versions of the function. Call parameter information is only valid
- * when the call is active.
- */
- {
- if(iState!=RMobileCall::EStatusConnected)
- {
- ReqCompleted(aTsyReqHandle,KErrEtelCallNotActive);
- return KErrNone;
- }
-
- TPckg<RCall::TCallParams>* callParamPckg=(TPckg<RCall::TCallParams>*)aCallParams;
- RCall::TCallParams& callParam=(*callParamPckg)();
-
- if(callParam.ExtensionId()==RMobileCall::KETelMobileDataCallParamsV1)
- {
-// If the passed package is MobileParams, then we can just unpackage and copy.
- RMobileCall::TMobileDataCallParamsV1Pckg* mobileCallParamPckg=(RMobileCall::TMobileDataCallParamsV1Pckg*)aCallParams;
- RMobileCall::TMobileDataCallParamsV1& mobileCallParam=(*mobileCallParamPckg)();
-
- // Check that the data structure is supported by the simulated TSY version
- TInt err = iPhone->CheckSimTsyVersion(mobileCallParam);
- if(err != KErrNone)
- {
- ReqCompleted(aTsyReqHandle, err);
- return KErrNone;
- }
-
- mobileCallParam=iMobileCallParams;
- }
-
- else if(callParam.ExtensionId()==RMobileCall::KETelMobileHscsdCallParamsV1)
- {
- TPckg<RMobileCall::TMobileHscsdCallParamsV1>* mobileCallParamPckg=(TPckg<RMobileCall::TMobileHscsdCallParamsV1>*)aCallParams;
- RMobileCall::TMobileHscsdCallParamsV1& mobileCallParam=(*mobileCallParamPckg)();
-
- // Check that the data structure is supported by the simulated TSY version
- TInt err = iPhone->CheckSimTsyVersion(mobileCallParam);
- if(err != KErrNone)
- {
- ReqCompleted(aTsyReqHandle, err);
- return KErrNone;
- }
-
- mobileCallParam=iHscsdSettings;
- }
- else
- {
-// If, however, its a core (or an unrecognised extension), we must only copy the
-// core parameters.
- callParam.iSpeakerControl=iMobileCallParams.iSpeakerControl;
- callParam.iSpeakerVolume=iMobileCallParams.iSpeakerVolume;
- callParam.iInterval=iMobileCallParams.iInterval;
- callParam.iWaitForDialTone=iMobileCallParams.iWaitForDialTone;
- }
-
- ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
-
-TInt CSimDataCall::LoanDataPort(const TTsyReqHandle aReqHandle,RCall::TCommPort* aCommPort)
-/**
- * Loans the comm port to a client for subsequent streaming of data.
- * For the comm port to be loaned the call must be active and the port unloaned.
- */
- {
- if(iState!=RMobileCall::EStatusConnected)
- {
- ReqCompleted(aReqHandle,KErrEtelCallNotActive);
- return KErrNone;
- }
-
- if(iCommPortLoaned)
- {
- ReqCompleted(aReqHandle,KErrEtelPortAlreadyLoaned);
- return KErrNone;
- }
-
- aCommPort->iCsy.Copy(iCsyName);
- aCommPort->iPort.Copy(iPortName);
- iCommPortLoaned=ETrue;
- ReqCompleted(aReqHandle,KErrNone);
- return KErrNone;
- }
-
-TInt CSimDataCall::LoanDataPortCancel(const TTsyReqHandle)
-/**
- * Cancels the LoanDataPort request.
- * The LoanDataPort function completes synchronously, so there is nothing to cancel.
- */
- {
- return KErrNone;
- }
-
-TInt CSimDataCall::RecoverDataPort(const TTsyReqHandle aReqHandle)
-/**
- * Recovers the comm port.
- * The comm port must be loaned in order to recover it.
- */
- {
- if(!iCommPortLoaned)
- {
- ReqCompleted(aReqHandle,KErrEtelPortNotLoanedToClient);
- return KErrNone;
- }
-
- iNtRas->Terminate();
- iCommPortLoaned=EFalse;
- ReqCompleted(aReqHandle,KErrNone);
- return KErrNone;
- }
-
-TInt CSimDataCall::ActionEvent(TCallEvent aEvent,TInt aStatus)
-/**
-* Entry point when an event has occured that may advance the state machine.
-* The aEvent parameter describes the event.
-*
-* This function contains the main state machine for the data call. The outer layer
-* switches on the event type. Where appropriate, there are inner layer switches
-* or conditional statements to handle the different responses that may be required to
-* the same event occurring in different states.
-*
-* @param aEvent The Call event to handle
-* @return value represents the error state caused by the attempted state machine jump.
-*/
- {
- TInt ret=KErrNone;
- __ASSERT_ALWAYS(iState!=RMobileCall::EStatusUnknown,SimPanic(ECallStatusUnknownIllegal));
-
- switch(aEvent)
- {
- case ECallEventDial:
- LOGDATA1(">>CSimDataCall::ActionEvent = [ECallEventDial]");
- if(iState==RMobileCall::EStatusIdle)
- {
- TRAP(ret, ret=ChangeStateL(RMobileCall::EStatusDialling,EFalse,EFalse));
- if(ret==KErrNone)
- iTimer->Start(iDiallingPause,this);
- }
- else
- return KErrEtelCallAlreadyActive;
- break;
-
- case ECallEventHangUp:
- {
- LOGDATA1(">>CSimDataCall::ActionEvent = [ECallEventHangUp]");
- switch(iState)
- {
- case RMobileCall::EStatusConnected:
- iCommPortLoaned=EFalse;
- iNtRas->Terminate();
-// Note: No "break;" - fall through to the rest of the discconnecting code...
- case RMobileCall::EStatusDialling:
- case RMobileCall::EStatusRinging:
- case RMobileCall::EStatusAnswering:
- case RMobileCall::EStatusConnecting:
- iTimer->Cancel();
- TRAP(ret, ret=ChangeStateL(RMobileCall::EStatusDisconnecting,EFalse,EFalse));
- if(ret==KErrNone)
- iTimer->Start(iDisconnectingPause,this);
- break;
- default:
- return KErrEtelCallNotActive;
- }
- }
- break;
-
- case ECallEventIncomingCall:
- LOGDATA1(">>CSimDataCall::ActionEvent = [ECallEventIncomingCall]");
- if(iState==RMobileCall::EStatusIdle)
- {
- if(iAnswerIncomingCall.iNotifyPending)
- {
- TRAP(ret, ret=ProcessAnswerIncomingCallL());
- }
- else
- {
- TRAP(ret, ret=ChangeStateL(RMobileCall::EStatusRinging,EFalse,EFalse));
- if(ret!=KErrNone)
- return ret;
- }
- }
- else
- return KErrEtelCallAlreadyActive;
- break;
-
- case ECallEventAnswerIncoming:
- LOGDATA1(">>CSimDataCall::ActionEvent = [ECallEventAnswerIncoming]");
- if(iState==RMobileCall::EStatusRinging)
- {
- TRAP(ret, ret=ProcessAnswerIncomingCallL());
- }
- else
- SimPanic(EIllegalStateInconsistancy); // The state is checked in AnswerIncomingCall, so there's been an inconsistancy if the state is out of line.
- break;
-
- case ECallEventRemoteHangup:
- LOGDATA1(">>CSimDataCall::ActionEvent = [ECallEventRemoteHangup]");
- if(iState==RMobileCall::EStatusConnected)
- {
- TRAP(ret, ret=ProcessRemoteHangupL());
- }
- else
- SimPanic(EIllegalStateInconsistancy); // The state is checked in RemoteHangup, so there's been an inconsistancy if the state is out of line.
- break;
-
- case ECallEventTimeOut:
- {
- LOGDATA1(">>CSimVoiceCall::ActionEvent = [ECallEventTimeOut]");
- switch(iState)
- {
- case RMobileCall::EStatusDialling:
- LOGDATA1(">>CSimDataCall::State = [EStatusDialling]");
- TRAP(ret, ret=ChangeStateL(RMobileCall::EStatusConnecting,EFalse,EFalse));
- if(ret==KErrNone)
- iTimer->Start(iConnectingPause,this);
- return ret;
-
- case RMobileCall::EStatusConnecting:
- LOGDATA1(">>CSimDataCall::State = [EStatusConnecting]");
-// If the config file has not spec'ed a CSY, then fail the dial...
- if(iCsyName.Length()==0)
- {
- ReqCompleted(iDialRequestHandle,KErrEtelNoCarrier);
- TRAP(ret, ret=ChangeStateL(RMobileCall::EStatusIdle,EFalse,EFalse));
-
- __ASSERT_ALWAYS(ret==KErrNone,SimPanic(EIllegalStateInconsistancy));
- return KErrNone;
- }
- ret=iNtRas->Connect(iCsyName,iPortName,iConfig,this);
- if(ret!=KErrNone)
- ReqCompleted(iDialRequestHandle,ret);
- return ret;
-
- case RMobileCall::EStatusDisconnecting:
- LOGDATA1(">>CSimDataCall::State = [EStatusDisconnecting]");
- TRAP(ret, ret=ChangeStateL(RMobileCall::EStatusIdle,EFalse,EFalse));
- ReqCompleted(iHangUpRequestHandle,ret);
- return ret;
-
- case RMobileCall::EStatusAnswering:
- LOGDATA1(">>CSimDataCall::State = [EStatusAnswering]");
- TRAP(ret, ret=ChangeStateL(RMobileCall::EStatusConnected,EFalse,EFalse));
- ReqCompleted(iAnswerIncomingCall.iNotifyHandle,ret);
- return ret;
-
- default:
- LOGDATA2(">>CSimDataCall::State = [%d]",iState);
- break;
- }
- }
- break;
-
- case ECallEventNtRasConnected:
- if(aStatus!=KErrNone)
- {
- ReqCompleted(iDialRequestHandle,aStatus);
- TRAP(ret, ret=ChangeStateL(RMobileCall::EStatusIdle,EFalse,EFalse));
- __ASSERT_ALWAYS(ret==KErrNone,SimPanic(EIllegalStateInconsistancy));
- return KErrNone;
- }
- else
- {
- TRAP(ret, ret=ChangeStateL(RMobileCall::EStatusConnected,EFalse,EFalse));
- ChangeDynamicInfo();
- ReqCompleted(iDialRequestHandle,ret);
- return KErrNone;
- }
- default:
- SimPanic(EIllegalStateInconsistancy);
- break;
- }
-
- return ret;
- }
-
-
-void CSimDataCall::TimerCallBack(TInt /*aId*/)
-/**
-* Timer callback function. When the timer goes off, it will call back into this
-* function for further processing.
-*/
- {
- LOGDATA1(">>CSimDataCall::TimerCallBack");
- TInt err=ActionEvent(ECallEventTimeOut,KErrNone);
- __ASSERT_ALWAYS(err==KErrNone,SimPanic(ETimeOutEventActionFailed));
- LOGDATA1("<<CSimDataCall::TimerCallBack");
- }
-
-TInt CSimDataCall::ProcessAnswerIncomingCallL()
-/**
-* Answers an Incoming Call.
-* First the call state must be changed to "answering", then the flag indicating
-* that an answer incoming call request is no longer pending. Finally, a new
-* call object must be assigned to receive the details of the next incoming call.
-*/
- {
- LOGDATA1(">>CSimDataCall::ProcessAnswerIncomingCall");
- TInt ret=ChangeStateL(RMobileCall::EStatusAnswering,EFalse,EFalse);
- if(ret!=KErrNone)
- return ret;
- iTimer->Start(iAnswerIncomingPause,this);
- iAnswerIncomingCall.iNotifyPending=EFalse;
- iLine->ResetAutoAnswerCallObject(this);
- LOGDATA1("<<CSimDataCall::ProcessAnswerIncomingCall");
- return ret;
- }
-
-TInt CSimDataCall::ProcessRemoteHangupL()
-/**
-* Hangs up a call from the remote end.
-* First the call state must be changed to "disconnecting", then the flag indicating
-* that a remote hangup request is no longer pending. Finally, a new
-* call object must be assigned to be the next remotely hung up call.
-*/
- {
- LOGDATA1(">>CSimDataCall::ProcessRemoteHangupL");
- TInt ret=ChangeStateL(RMobileCall::EStatusDisconnecting,EFalse,EFalse);
- if(ret!=KErrNone)
- return ret;
- iTimer->Start(iRemoteHangupPause,this);
- iLine->ResetRemoteHangupCallObject(this);
- LOGDATA1("<<CSimDataCall::ProcessRemoteHangupL");
- return ret;
- }
-
-
-void CSimDataCall::PopulateCallParams(const TDesC8* aCallParams)
-/**
- * This function populates the call parameter member variable iMobileCallParams.
- * The function must handle core and multimode extension call parameters.
- * @param aCallParams A pointer to the call parameter variable.
- */
- {
- TPckg<RCall::TCallParams>* callParamPckg=(TPckg<RCall::TCallParams>*)aCallParams;
- RCall::TCallParams& callParam=(*callParamPckg)();
-
- if(callParam.ExtensionId()==RMobileCall::KETelMobileDataCallParamsV1)
- {
-// If the passed package is MobileParams, then we can just unpackage and copy.
- RMobileCall::TMobileDataCallParamsV1Pckg* mobileCallParamPckg=(RMobileCall::TMobileDataCallParamsV1Pckg*)aCallParams;
- RMobileCall::TMobileDataCallParamsV1& mobileCallParam=(*mobileCallParamPckg)();
-
- iHscsdCall=EFalse;
- iMobileCallParams=mobileCallParam;
- }
- else if(callParam.ExtensionId()==RMobileCall::KETelMobileHscsdCallParamsV1)
- {
- TPckg<RMobileCall::TMobileHscsdCallParamsV1>* mobileCallParamPckg=(TPckg<RMobileCall::TMobileHscsdCallParamsV1>*)aCallParams;
- RMobileCall::TMobileHscsdCallParamsV1& mobileCallParam=(*mobileCallParamPckg)();
-
- iHscsdCall=ETrue;
- iHscsdSettings=mobileCallParam;
- }
- else
- {
-// If, however, its core (or an unrecognised extension), we must first reset the member
-// member variable before copying just the core parameters.
- RMobileCall::TMobileDataCallParamsV1 mobileCallParam;
-
- iMobileCallParams=mobileCallParam;
- iHscsdCall=EFalse;
- iMobileCallParams.iSpeakerControl=callParam.iSpeakerControl;
- iMobileCallParams.iSpeakerVolume=callParam.iSpeakerVolume;
- iMobileCallParams.iInterval=callParam.iInterval;
- iMobileCallParams.iWaitForDialTone=callParam.iWaitForDialTone;
- }
- }
-
-void CSimDataCall::NTRasCallBack(TInt aStatus)
-/**
- * NTRas callback function. This function will be called when the NTRAS
- * Server has responded.
- * @param aStatus Standard error value, indicating the success or failure of the NTRAS
- * connection.
- */
- {
- TInt err=ActionEvent(ECallEventNtRasConnected,aStatus);
- __ASSERT_ALWAYS(err==KErrNone,SimPanic(EIllegalStateInconsistancy));
- }
-
-TUint CSimDataCall::Caps()
-/**
- * Return the current capabilities of this call.
- * @return TUint Current call capabilities.
- */
- {
- TUint caps=RCall::KCapsData;
- GenerateCoreCallCaps(caps);
- if(iState==RMobileCall::EStatusConnected)
- {
- if(iCommPortLoaned)
- caps|=RCall::KCapsRecoverDataPort;
- else
- caps|=RCall::KCapsLoanDataPort;
- }
- return caps;
- }
-
-TInt CSimDataCall::GetMobileDataCallCaps(const TTsyReqHandle aTsyReqHandle, TDes8* aCaps)
-/**
-*
-* @param aTsyReqHandle specifies the request handle.
-* @param aCaps is used to return the retrieved capabilities to the client.
-* @return value returns the result of this operation
-*/
- {
- TPckg<RMobileCall::TMobileCallDataCapsV1>* mobileCallCapsPckg=(TPckg<RMobileCall::TMobileCallDataCapsV1>*)aCaps;
- RMobileCall::TMobileCallDataCapsV1& mobileCallCaps=(*mobileCallCapsPckg)();
-
- // Check that the data structure is supported by the simulated TSY version
- TInt err = iPhone->CheckSimTsyVersion(mobileCallCaps);
- if(err != KErrNone)
- {
- ReqCompleted(aTsyReqHandle, err);
- return KErrNone;
- }
-
- if(mobileCallCaps.ExtensionId()==KETelExtMultimodeV1)
- {
- mobileCallCaps=iMobileCallCaps;
- ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
- else
- {
- ReqCompleted(aTsyReqHandle,KErrNotFound);
- return KErrNotFound;
- }
-}
-
-TInt CSimDataCall::GetMobileDataCallCapsCancel(const TTsyReqHandle aTsyReqHandle)
-/**
-*
-* @param aTsyReqHandle specifies the request handle to be canceled
-* @return value returns the result of this operation
-*/
- {
- ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
-
-TInt CSimDataCall::SetDynamicHSCSDParams(const TTsyReqHandle aTsyReqHandle, RMobileCall::TMobileCallAiur* aAiur, TInt* aRxTimeslots)
-/**
-*
-* @param aTsyReqHandle specifies the request handle.
-* @param aAiur is used to dynamically change Aiur for this call
-* @param aRxTimeslots is used to dynamically change RxTimeslots for this call
-* @return value returns the result of this operation
-*/
- {
- iHscsdInfo.iRxTimeSlots=*aRxTimeslots;
- iHscsdInfo.iAiur=*aAiur;
- iHscsdSettings.iWantedRxTimeSlots=*aRxTimeslots;
- iHscsdSettings.iWantedAiur=*aAiur;
-
- if(iNotifyInfo.iNotifyPending)
- {
- *(RMobileCall::TMobileCallHscsdInfoV1*)iNotifyInfo.iNotifyData=iHscsdInfo;
- iNotifyInfo.iNotifyPending=EFalse;
- ReqCompleted(iNotifyInfo.iNotifyHandle,KErrNone);
- }
- ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
-}
-
-TInt CSimDataCall::SetDynamicHSCSDParamsCancel(const TTsyReqHandle aTsyReqHandle)
-/**
-*
-* @param aTsyReqHandle specifies the request handle to be canceled
-* @return value returns the result of this operation
-*/
- {
- ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
-
-TInt CSimDataCall::GetCurrentHSCSDInfo(const TTsyReqHandle aTsyReqHandle, TDes8* aInfo)
-/**
-*
-* @param aTsyReqHandle specifies the request handle.
-* @param aInfo is used to return the current Hscsd information to the client
-* @return value returns the result of this operation
-*/
- {
- TPckg<RMobileCall::TMobileCallHscsdInfoV1>* hscsdInfoPckg=(TPckg<RMobileCall::TMobileCallHscsdInfoV1>*)aInfo;
- RMobileCall::TMobileCallHscsdInfoV1& hscsdInfo=(*hscsdInfoPckg)();
-
- // Check that the data structure is supported by the simulated TSY version
- TInt err = iPhone->CheckSimTsyVersion(hscsdInfo);
- if(err != KErrNone)
- {
- ReqCompleted(aTsyReqHandle, err);
- return KErrNone;
- }
-
- if(hscsdInfo.ExtensionId()==KETelExtMultimodeV1)
- {
- hscsdInfo=iHscsdInfo;
- ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
- else
- {
- ReqCompleted(aTsyReqHandle,KErrNotFound);
- return KErrNotFound;
- }
- }
-
-TInt CSimDataCall::NotifyHSCSDInfoChange(const TTsyReqHandle aTsyReqHandle, TDes8* aHSCSDInfo)
-/**
-*
-* @param aTsyReqHandle specifies the request handle.
-* @param aInfo is used to return the current Hscsd information when the notification completes
-* @return value returns the result of this operation
-*/
- {
- __ASSERT_ALWAYS(!iNotifyInfo.iNotifyPending,SimPanic(ENotificationAlreadyPending));
-
- iNotifyInfo.iNotifyPending = ETrue;
- iNotifyInfo.iNotifyHandle = aTsyReqHandle;
-
- TPckg<RMobileCall::TMobileCallHscsdInfoV1>* hscsdInfo = (TPckg<RMobileCall::TMobileCallHscsdInfoV1>*)aHSCSDInfo;
- RMobileCall::TMobileCallHscsdInfoV1& hscsdInfoV1 = (*hscsdInfo)();
-
- // Check that the data structure is supported by the simulated TSY version
- TInt err = iPhone->CheckSimTsyVersion(hscsdInfoV1);
- if(err != KErrNone)
- {
- ReqCompleted(aTsyReqHandle, err);
- return KErrNone;
- }
-
- iNotifyInfo.iNotifyData = &hscsdInfoV1;
- return KErrNone;
- }
-
-TInt CSimDataCall::NotifyHSCSDInfoChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
-/**
-*
-* @param aTsyReqHandle specifies the request handle to be canceled
-* @return value returns the result of this operation
-*/
- {
- if(iNotifyInfo.iNotifyPending)
- {
- iNotifyInfo.iNotifyPending=EFalse;
- ReqCompleted(iNotifyInfo.iNotifyHandle,KErrCancel);
- }
- return KErrNone;
- }
-
-TInt CSimDataCall::NotifyMobileDataCapsChange(const TTsyReqHandle aTsyReqHandle, TDes8* /*aCaps*/)
- {
-/**
-*
-* @param aTsyReqHandle specifies the request handle to be canceled
-* @return value returns the result of this operation
-*/
- ReqCompleted(aTsyReqHandle,KErrNotSupported);
- return KErrNotSupported;
- }
-
-TInt CSimDataCall::NotifyMobileDataCapsChangeCancel(const TTsyReqHandle aTsyReqHandle)
-/**
-*
-* @param aTsyReqHandle specifies the request handle to be canceled
-* @return value returns the result of this operation
-*/
- {
- ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
-
-TInt CSimDataCall::GetMobileDataCallRLPRange(const TTsyReqHandle aTsyReqHandle, TInt* aRLPVersion, TDes8* aRLPRange)
- {
-/**
-*
-* @param aTsyReqHandle specifies the request handle to be canceled
-* @param aRLPVersion specifies the version for RLP range retrieval
-* @param aRLPRange is used to return the requested RLP range to the client
-* @return value returns the result of this operation
-*/
- TInt ret=SearchRetrieveRlp(aRLPVersion,aRLPRange);
-
- ReqCompleted(aTsyReqHandle,ret);
- return ret;
- }
-
-TInt CSimDataCall::GetMobileDataCallRLPRangeCancel(const TTsyReqHandle aTsyReqHandle)
-/**
-*
-* @param aTsyReqHandle specifies the request handle to be canceled
-* @return value returns the result of this operation
-*/
- {
- ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
-
-void CSimDataCall::ChangeDynamicInfo()
-/**
-*
-* Private function to alter the current Hscsd information
-*/
- {
- if(iHscsdCall)
- {
- // Change to the requested settings
- iHscsdInfo.iAiur=iHscsdSettings.iWantedAiur;
- iHscsdInfo.iRxTimeSlots=iHscsdSettings.iWantedRxTimeSlots;
- iHscsdInfo.iTxTimeSlots=iHscsdSettings.iMaxTimeSlots-iHscsdSettings.iWantedRxTimeSlots;
- iHscsdInfo.iCodings=(RMobileCall::TMobileCallTchCoding) iHscsdSettings.iCodings;
- // Complete a pending notification event for changes in dynamic info of HSCSD
- if(iNotifyInfo.iNotifyPending)
- {
- *(RMobileCall::TMobileCallHscsdInfoV1*)iNotifyInfo.iNotifyData=(RMobileCall::TMobileCallHscsdInfoV1)iHscsdInfo;
- ReqCompleted(iNotifyInfo.iNotifyHandle,KErrNone);
- }
- }
- }
-
-TInt CSimDataCall::SearchRetrieveRlp(TInt* aRLPVersion,TDes8* aRLPRange)
-/**
-*
-* Private function to search the list of available RLP ranges per version
-* and return the appropriate range.
-*/
- {
- TInt count = iMobileCallRLPList->Count();
- TMobileCallRLPItem item;
-
- for(TInt i=0; i<count; i++)
- {
- item=iMobileCallRLPList->At(i);
- if(item.iRlpVersion==*aRLPVersion)
- {
- *(RMobileCall::TMobileDataRLPRangesV1*)aRLPRange=item.iMobileCallRLP;
- return KErrNone;
- }
- }
- return KErrNotFound;
- }
-
+// Copyright (c) 2001-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:
+// This file contains the implementation of the Simulator TSY Data Call functionality.
+// The Call classes process the Call-based requests made by ETel clients
+// and passed down to the TSY by the ETel Server.
+//
+//
+
+/**
+ @file
+*/
+
+#include <testconfigfileparser.h>
+#include "CSimDataCall.h"
+#include "CSimPhone.h"
+#include "Simlog.h"
+
+CSimDataCall* CSimDataCall::NewL(CSimLine* aLine,const TDesC& aName, CSimPhone* aPhone)
+/**
+ * Standard two phase constructor.
+ *
+ * @param aLine pointer to the Line object.
+ * @param aName name of the call to be constructed
+ * @return CSimDataCall pointer to the data call object created
+ * @leave Leaves if no memory or object is not created for any reason
+ */
+ {
+ CSimDataCall* dataCall=new(ELeave) CSimDataCall(aLine,aName,aPhone);
+ TCleanupItem newCallDataClose(CloseCall,dataCall);
+ CleanupStack::PushL(newCallDataClose);
+ dataCall->ConstructL();
+ CleanupStack::Pop();
+ return dataCall;
+ }
+
+CSimDataCall::CSimDataCall(CSimLine* aLine,const TName& aName, CSimPhone* aPhone)
+ : CSimCall(aLine,aName,aPhone), iCommPortLoaned(EFalse)
+/**
+ * Trivial constructor. Calls CSimCall to initialise its members
+ */
+ {
+ iCaps=Caps();
+ }
+
+void CSimDataCall::ConstructL()
+/**
+ * Second phase of 2-Phase Constructor
+ * Retrieves all the pausing duration tags from the config file
+ *
+ * @param aName name of the data call to be constructed
+ */
+ {
+ LOGDATA1("Starting to parse Data Call config parameters...");
+
+ iDiallingPause=iLine->CfgFile()->ItemValue(KDiallingPauseDuration,KDefaultDiallingPauseDuration);
+ iConnectingPause=iLine->CfgFile()->ItemValue(KConnectingPauseDuration,KDefaultConnectingPauseDuration);
+ iDisconnectingPause=iLine->CfgFile()->ItemValue(KDisconnectingPauseDuration,KDefaultDisconnectingPauseDuration);
+ iAnswerIncomingPause=iLine->CfgFile()->ItemValue(KAnswerIncomingPauseDuration,KDefaultAnswerIncomingPauseDuration);
+ iRemoteHangupPause=iLine->CfgFile()->ItemValue(KRemoteHangupPauseDuration,KDefaultRemoteHangupPauseDuration);
+
+// Read in the CommPort setup
+
+ const CTestConfigItem* item=iLine->CfgFile()->Item(KDataCallCaps);
+ if(item)
+ {
+ TPtrC8 speedCaps, protocolCaps, serviceCaps, qosCaps, codingCaps, asymmetryCaps;
+ TPtrC8 rlpVersionCaps, v42bisCaps;
+ TBool hscsdSupport, userInitUpgrade;
+ TInt mClass, MaxRxTimeslots, MaxTxTimeslots, totalRxTxTimeslots;
+ TUint8 digit = 0;
+
+ TInt ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,speedCaps);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("speedCaps",ret,0,&KDataCallCaps);
+ }
+ else
+ if(AsciiToNum(speedCaps, digit)==KErrNone)
+ iMobileCallCaps.iSpeedCaps = digit;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,protocolCaps);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("protocolCaps",ret,1,&KDataCallCaps);
+ }
+ else
+ if(AsciiToNum(protocolCaps, digit)==KErrNone)
+ iMobileCallCaps.iProtocolCaps = digit;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,serviceCaps);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("serviceCaps",ret,2,&KDataCallCaps);
+ }
+ else
+ if(AsciiToNum(serviceCaps, digit)==KErrNone)
+ iMobileCallCaps.iServiceCaps = digit;
+
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,qosCaps);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("qosCaps",ret,3,&KDataCallCaps);
+ }
+ else
+ if(AsciiToNum(qosCaps, digit)==KErrNone)
+ iMobileCallCaps.iQoSCaps = digit;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,4,hscsdSupport);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("hscsdSupport",ret,4,&KDataCallCaps);
+ }
+ else
+ iMobileCallCaps.iHscsdSupport = hscsdSupport;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,5,mClass);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("mClass",ret,5,&KDataCallCaps);
+ }
+ else
+ iMobileCallCaps.iMClass = mClass;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,6,MaxRxTimeslots);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("MaxRxTimeslots",ret,6,&KDataCallCaps);
+ }
+ else
+ iMobileCallCaps.iMaxRxTimeSlots = MaxRxTimeslots;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,7,MaxTxTimeslots);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("MaxTxTimeslots",ret,7,&KDataCallCaps);
+ }
+ else
+ iMobileCallCaps.iMaxTxTimeSlots = MaxTxTimeslots;
+
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,8,totalRxTxTimeslots);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("totalRxTxTimeslots",ret,8,&KDataCallCaps);
+ }
+ else
+ iMobileCallCaps.iTotalRxTxTimeSlots = totalRxTxTimeslots;
+
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,9,codingCaps);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("codingCaps",ret,9,&KDataCallCaps);
+ }
+ else
+ if(AsciiToNum(codingCaps, digit)==KErrNone)
+ iMobileCallCaps.iCodingCaps = digit;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,10,asymmetryCaps);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("asymmetryCaps",ret,10,&KDataCallCaps);
+ }
+ else
+ if(AsciiToNum(asymmetryCaps, digit)==KErrNone)
+ iMobileCallCaps.iAsymmetryCaps = digit;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,11,userInitUpgrade);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("userInitUpgrade",ret,11,&KDataCallCaps);
+ }
+ else
+ iMobileCallCaps.iUserInitUpgrade = userInitUpgrade;
+
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,10,rlpVersionCaps);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("rlpVersionCaps",ret,10,&KDataCallCaps);
+ }
+ else
+ if(AsciiToNum(rlpVersionCaps, digit)==KErrNone)
+ iMobileCallCaps.iRLPVersionCaps = digit;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,10,v42bisCaps);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("v42bisCaps",ret,10,&KDataCallCaps);
+ }
+ else
+ if(AsciiToNum(v42bisCaps, digit)==KErrNone)
+ iMobileCallCaps.iV42bisCaps = digit;
+ }
+ else //Default Values for Caps
+ {
+ iMobileCallCaps.iSpeedCaps=RMobileCall::KCapsSpeedAutobauding;
+ iMobileCallCaps.iProtocolCaps=RMobileCall::KCapsProtocolV32;
+ iMobileCallCaps.iServiceCaps=(RMobileCall::KCapsDataCircuitAsynchronous | RMobileCall::KCapsPacketAccessSyncUDI);
+ iMobileCallCaps.iQoSCaps=RMobileCall::KCapsTransparentPreferred;
+ iMobileCallCaps.iHscsdSupport=(TBool)(ETrue);
+ iMobileCallCaps.iMClass=1;
+ iMobileCallCaps.iMaxRxTimeSlots=5;
+ iMobileCallCaps.iMaxTxTimeSlots=5;
+ iMobileCallCaps.iTotalRxTxTimeSlots=10;
+ iMobileCallCaps.iCodingCaps=(RMobileCall::KCapsAiurCoding48 | RMobileCall::KCapsAiurCoding96);
+ iMobileCallCaps.iAsymmetryCaps=(RMobileCall::EAsymmetryUplink);
+ iMobileCallCaps.iUserInitUpgrade=(TBool)(ETrue);
+ iMobileCallCaps.iRLPVersionCaps = 1;
+ iMobileCallCaps.iV42bisCaps = 1;
+ }
+
+ TInt count = iLine->CfgFile()->ItemCount(KDataRLPparams);
+ TMobileCallRLPItem iMobileCallRLPItem;
+ iMobileCallRLPList = new(ELeave) CArrayFixFlat<TMobileCallRLPItem>(5);
+
+ if(count!=0)
+ {
+ for(TInt i=0;i<count;i++)
+ {
+
+ item = iLine->CfgFile()->Item(KDataRLPparams,i);
+ if(!item)
+ break;
+
+ TInt iRlpVersion,iIWSMax,iIWSMin,iMWSMax,iMWSMin;
+ TInt iT1Max,iT1Min,iN2Max,iN2Min,iT4Max,iT4Min;
+
+ TInt ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,iRlpVersion);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("iRlpVersion",ret,0,&KDataRLPparams);
+ }
+ else
+ iMobileCallRLPItem.iRlpVersion = iRlpVersion;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,iIWSMax);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("iIWSMax",ret,0,&KDataRLPparams);
+ }
+ else
+ iMobileCallRLPItem.iMobileCallRLP.iIWSMax = iIWSMax;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,iIWSMin);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("iIWSMin",ret,1,&KDataRLPparams);
+ }
+ else
+ iMobileCallRLPItem.iMobileCallRLP.iIWSMin = iIWSMin;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,iMWSMax);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("iMWSMax",ret,2,&KDataRLPparams);
+ }
+ else
+ iMobileCallRLPItem.iMobileCallRLP.iMWSMax = iMWSMax;
+
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,iMWSMin);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("iMWSMin",ret,3,&KDataRLPparams);
+ }
+ else
+ iMobileCallRLPItem.iMobileCallRLP.iMWSMin = iMWSMin;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,4,iT1Max);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("iT1Max",ret,4,&KDataRLPparams);
+ }
+ else
+ iMobileCallRLPItem.iMobileCallRLP.iT1Max = iT1Max;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,5,iT1Min);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("iT1Min",ret,5,&KDataRLPparams);
+ }
+ else
+ iMobileCallRLPItem.iMobileCallRLP.iT1Min = iT1Min;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,6,iN2Max);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("iN2Max",ret,6,&KDataRLPparams);
+ }
+ else
+ iMobileCallRLPItem.iMobileCallRLP.iN2Max = iN2Max;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,7,iN2Min);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("iN2Min",ret,7,&KDataRLPparams);
+ }
+ else
+ iMobileCallRLPItem.iMobileCallRLP.iN2Min = iN2Min;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,8,iT4Max);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("iT4Max",ret,8,&KDataRLPparams);
+ }
+ else
+ iMobileCallRLPItem.iMobileCallRLP.iT4Max = iT4Max;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,9,iT4Min);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("iT4Min",ret,9,&KDataRLPparams);
+ }
+ else
+ iMobileCallRLPItem.iMobileCallRLP.iT4Min = iT4Min;
+
+ iMobileCallRLPList->AppendL(iMobileCallRLPItem);
+ }
+ }
+ else
+ {
+ iMobileCallRLPItem.iRlpVersion=1;
+ iMobileCallRLPItem.iMobileCallRLP.iIWSMax=10;
+ iMobileCallRLPItem.iMobileCallRLP.iIWSMin=5;
+ iMobileCallRLPItem.iMobileCallRLP.iMWSMax=8;
+ iMobileCallRLPItem.iMobileCallRLP.iMWSMin=4;
+ iMobileCallRLPItem.iMobileCallRLP.iT1Max=4;
+ iMobileCallRLPItem.iMobileCallRLP.iT1Min=2;
+ iMobileCallRLPItem.iMobileCallRLP.iN2Max=12;
+ iMobileCallRLPItem.iMobileCallRLP.iN2Min=1;
+ iMobileCallRLPItem.iMobileCallRLP.iT4Max=10;
+ iMobileCallRLPItem.iMobileCallRLP.iT4Min=2;
+ iMobileCallRLPList->AppendL(iMobileCallRLPItem);
+ }
+
+ item=iLine->CfgFile()->Item(KDynamicHSCSDInfo);
+ if(item)
+ {
+ TPtrC8 iAiur,iCodings;
+ TInt iRxTimeSlots,iTxTimeSlots;
+
+ TUint8 digit=0;
+
+ TInt ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,iAiur);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("iAiur",ret,0,&KDynamicHSCSDInfo);
+ }
+ else
+ if(AsciiToNum(iAiur, digit)==KErrNone)
+ iHscsdInfo.iAiur = (RMobileCall::TMobileCallAiur) digit;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,iRxTimeSlots);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("iRxTimeSlots",ret,1,&KDynamicHSCSDInfo);
+ }
+ else
+ iHscsdInfo.iRxTimeSlots = iRxTimeSlots;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,iTxTimeSlots);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("iTxTimeSlots",ret,2,&KDynamicHSCSDInfo);
+ }
+ else
+ iHscsdInfo.iTxTimeSlots = iTxTimeSlots;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,iCodings);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("iCodings",ret,3,&KDynamicHSCSDInfo);
+ }
+ else
+ if(AsciiToNum(iCodings, digit)==KErrNone)
+ iHscsdInfo.iCodings = (RMobileCall::TMobileCallTchCoding) digit;
+ }
+ else
+ {
+ iHscsdInfo.iAiur=RMobileCall::EAiurBps9600;
+ iHscsdInfo.iRxTimeSlots=5;
+ iHscsdInfo.iTxTimeSlots=10;
+ iHscsdInfo.iCodings=RMobileCall::ETchCoding48;
+ }
+
+ item=iLine->CfgFile()->Item(KCommSetup);
+ if(item)
+ {
+ TPtrC8 portName,csyName;
+ TInt err=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,csyName); // The 3rd parameter (0) represents the index of the variable on the config file line
+ if (err!=KErrNone)
+ {
+ LOGPARSERR("csyName",err,0,&KCommSetup);
+ iCsyName.Copy(KDefaultCsyName);
+ }
+ else
+ iCsyName.Copy(csyName);
+
+ err=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,portName); // The 3rd parameter (1) represents the index of the variable on the config file line
+ if (err!=KErrNone)
+ {
+ LOGPARSERR("portName",err,1,&KCommSetup);
+ iPortName.Copy(KDefaultPortName);
+ }
+ else
+ iPortName.Copy(portName);
+
+ TInt dataRate,handshake;
+ err=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,dataRate); // The 3rd parameter (2) represents the index of the variable on the config file line
+ if (err!=KErrNone)
+ {
+ LOGPARSERR("dataRate",err,2,&KCommSetup);
+ iConfig.iRate=KDefaultCommPortRate;
+ }
+ else
+ iConfig.iRate=(TBps)dataRate;
+
+ err=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,handshake); // The 3rd parameter (3) represents the index of the variable on the config file line
+ if (err!=KErrNone)
+ {
+ LOGPARSERR("handshake",err,3,&KCommSetup);
+ iConfig.iHandshake=KDefaultHandshake;
+ }
+ else
+ iConfig.iHandshake=(TUint)handshake;
+ }
+ else
+ {
+ iCsyName.Copy(KDefaultCsyName);
+ iPortName.Copy(KDefaultPortName);
+ iConfig.iRate=KDefaultCommPortRate;
+ iConfig.iHandshake=KDefaultHandshake;
+ }
+
+// Read in the Bearer Service information
+ item=iLine->CfgFile()->Item(KBearerService);
+ if(item)
+ {
+ TInt bearerCaps,bearerSpeed;
+ TInt err=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,bearerCaps); // The 3rd parameter (0) represents the index of the variable on the config file line
+ if (err!=KErrNone)
+ {
+ LOGPARSERR("bearerCaps",err,0,&KBearerService);
+ iBearerService.iBearerCaps=KDefaultBearerCaps;
+ }
+ else
+ iBearerService.iBearerCaps=bearerCaps;
+
+ err=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,bearerSpeed); // The 3rd parameter (1) represents the index of the variable on the config file line
+ if (err!=KErrNone)
+ {
+ LOGPARSERR("bearerSpeed",err,1,&KBearerService);
+ iBearerService.iBearerSpeed=KDefaultBearerSpeed;
+ }
+ else
+ iBearerService.iBearerSpeed=(RCall::TCallBearerSpeed)bearerSpeed;
+
+ }
+ else
+ {
+ iBearerService.iBearerCaps=KDefaultBearerCaps;
+ iBearerService.iBearerSpeed=KDefaultBearerSpeed;
+ }
+
+ iTimer=CSimTimer::NewL(iLine->iPhone);
+ iNtRas=CSimNtRas::NewL(iLine->iPhone);
+ CSimCall::ConstructL();
+
+ //If present read in remote party info tag
+ TPtrC8 callingname, remotenumber;
+ TInt delay=0;
+
+ item=iLine->CfgFile()->Item(KNotifyRemotePartyInfo);
+
+ TInt ret;
+
+ if (item)
+ {
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,delay);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("delay",ret,0,&KNotifyRemotePartyInfo);
+ }
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,callingname);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("callingname",ret,1,&KNotifyRemotePartyInfo);
+ }
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,remotenumber);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("remotenumber",ret,2,&KNotifyRemotePartyInfo);
+ }
+
+ iNotifyRemotePartyInfoTimer->iDelay = delay;
+ iNotifyRemotePartyInfoTimer->iRemotePartyInfoV1.iDirection = RMobileCall::EDirectionUnknown;
+ iNotifyRemotePartyInfoTimer->iRemotePartyInfoV1.iCallingName.Copy(callingname);
+ iNotifyRemotePartyInfoTimer->iRemotePartyInfoV1.iRemoteNumber.iTelNumber.Copy(remotenumber);
+ iNotifyRemotePartyInfoTimer->iRemotePartyInfoV1.iRemoteNumber.iTypeOfNumber = RMobilePhone::EInternationalNumber;
+ iNotifyRemotePartyInfoTimer->iRemotePartyInfoV1.iRemoteNumber.iNumberPlan = RMobilePhone::EIsdnNumberPlan;
+ iNotifyRemotePartyInfoTimer->iRemotePartyInfoV1.iRemoteIdStatus = RMobileCall::ERemoteIdentityAvailable;
+ }
+ else
+ {
+ iNotifyRemotePartyInfoTimer->iRemotePartyInfoV1.iRemoteIdStatus = RMobileCall::ERemoteIdentityUnknown;
+ }
+
+ LOGDATA1("...Finished parsing Data Call config parameters...");
+ }
+
+CSimDataCall::~CSimDataCall()
+/**
+ * Destroy all the objects constructed.
+ * CSimTimer and CSimSysAgent objects are destroyed here
+ */
+ {
+ delete iNtRas;
+ delete iTimer;
+ if(iAnswerIncomingCall.iNotifyPending)
+ iLine->ResetAutoAnswerCallObject(this);
+ if(iMobileCallRLPList)
+ {
+ iMobileCallRLPList->Delete(0,iMobileCallRLPList->Count());
+ delete iMobileCallRLPList;
+ }
+ }
+
+TInt CSimDataCall::ExtFunc(const TTsyReqHandle aTsyReqHandle,const TInt aIpc,const TDataPackage& aPackage)
+/**
+ * ExtFunc is called by the server when it has a "extended", i.e. non-core ETel request
+ * for the TSY to process
+ * A request handle, request type and request data are passed to the TSY
+ *
+ * @param aTsyReqHandle
+ * @param aIpc IPc number representing the request
+ * @param aPackage data for the request
+ * @return KErrNone
+ */
+ {
+ TAny* dataPtr=aPackage.Ptr1();
+ TAny* dataPtr2=aPackage.Ptr2();
+
+ LOGDATA2("CSimDataCall::ExtFunc: IPC Number is %d",aIpc);
+ // The request data has to extracted from TDataPackage and the TAny* pointers have to
+ // be "cast" to the expected request data type
+
+ switch (aIpc)
+ {
+ //
+ // No Flow Control NOR Multiple Completion
+ //
+ case EMobileCallGetMobileCallCaps:
+ return GetMobileCallCaps(aTsyReqHandle,aPackage.Des1n());
+
+ case EMobileCallGetMobileDataCallCaps:
+ return GetMobileDataCallCaps(aTsyReqHandle,aPackage.Des1n());
+
+ case EMobileCallGetMobileDataCallRLPRange:
+ return GetMobileDataCallRLPRange(aTsyReqHandle,
+ REINTERPRET_CAST(TInt*,dataPtr),
+ REINTERPRET_CAST(TDes8*,dataPtr2));
+
+ case EMobileCallSetDynamicHscsdParams:
+ return SetDynamicHSCSDParams(aTsyReqHandle,
+ REINTERPRET_CAST(RMobileCall::TMobileCallAiur*,dataPtr),
+ REINTERPRET_CAST(TInt*,dataPtr2));
+
+ case EMobileCallGetCurrentHscsdInfo:
+ return GetCurrentHSCSDInfo(aTsyReqHandle, aPackage.Des1n());
+
+ case EMobileCallGetMobileCallStatus:
+ return GetMobileCallStatus(aTsyReqHandle,
+ REINTERPRET_CAST(RMobileCall::TMobileCallStatus*,dataPtr));
+
+ case EMobileCallGetMobileCallInfo:
+ return GetMobileCallInfo(aTsyReqHandle,aPackage.Des1n());
+
+ //
+ // Multiple Completion Services with Immediate Server Repost
+ // (Usually Notifications)
+ //
+ case EMobileCallNotifyMobileCallStatusChange:
+ return NotifyMobileCallStatusChange(aTsyReqHandle,
+ REINTERPRET_CAST(RMobileCall::TMobileCallStatus*, dataPtr));
+
+ case EMobileCallNotifyMobileCallCapsChange:
+ return NotifyMobileCallCapsChange(aTsyReqHandle, aPackage.Des1n());
+
+ case EMobileCallNotifyMobileDataCallCapsChange:
+ return NotifyMobileDataCapsChange(aTsyReqHandle, aPackage.Des1n());
+
+ case EMobileCallNotifyHscsdInfoChange:
+ return NotifyHSCSDInfoChange(aTsyReqHandle, aPackage.Des1n());
+
+ case EMobileCallNotifyRemotePartyInfoChange:
+ return NotifyRemotePartyInfoChange(aTsyReqHandle, aPackage.Des1n());
+
+ default:
+ LOGDATA2("CSimDataCall::ExtFunc: Unsupported IPC detected - number %d",aIpc);
+ break;
+ }
+
+ return KErrNotSupported;
+ }
+
+TInt CSimDataCall::CancelService(const TInt aIpc,const TTsyReqHandle aTsyReqHandle)
+/**
+ * Cancel an outstanding request.
+ * @param aIpc The IPC number of the request that must be cancelled. Note: this is not the
+ * IPC number of the cancel request itself.
+ * @param aTsyReqHandle The TSY Request Handle of the request to be cancelled.
+ */
+ {
+ switch(aIpc)
+ {
+ case EMobileCallNotifyMobileCallStatusChange:
+ return NotifyMobileCallStatusChangeCancel(aTsyReqHandle);
+
+ case EMobileCallNotifyMobileCallCapsChange:
+ return NotifyMobileCallCapsChangeCancel(aTsyReqHandle);
+
+ case EMobileCallNotifyMobileDataCallCapsChange:
+ return NotifyMobileDataCapsChangeCancel(aTsyReqHandle);
+
+ case EMobileCallSetDynamicHscsdParams:
+ return SetDynamicHSCSDParamsCancel(aTsyReqHandle);
+
+ case EMobileCallGetMobileDataCallCaps:
+ return GetMobileDataCallCapsCancel(aTsyReqHandle);
+
+ case EMobileCallGetMobileDataCallRLPRange:
+ return GetMobileDataCallRLPRangeCancel(aTsyReqHandle);
+
+ case EMobileCallNotifyHscsdInfoChange:
+ return NotifyHSCSDInfoChangeCancel(aTsyReqHandle);
+
+ case EMobileCallNotifyRemotePartyInfoChange:
+ return NotifyRemotePartyInfoChangeCancel();
+
+ default:
+ LOGDATA1("CSimDataCall::CancelService: No match for IPC, defering to base function");
+ break;
+ }
+ return CCallBase::CancelService(aIpc,aTsyReqHandle);
+ }
+
+TInt CSimDataCall::Dial(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams,TDesC* /*aTelNumber*/)
+/**
+ * Process a client's dial request.
+ *
+ * @param aTsyReqHandle
+ * @param aCallParams the call parameters
+ * @param aTelNumber The telephone number to dial
+ * @return KErrNone
+ */
+ {
+ LOGDATA1(">>CSimDataCall::Dial");
+ iDialRequestHandle=aTsyReqHandle;
+ PopulateCallParams(aCallParams);
+
+ TInt err=ActionEvent(ECallEventDial,KErrNone);
+ if(err!=KErrNone)
+ ReqCompleted(aTsyReqHandle,err);
+
+ LOGDATA1("<<CSimDataCall::Dial");
+ return KErrNone;
+ }
+
+TInt CSimDataCall::DialCancel(const TTsyReqHandle /*aTsyReqHandle*/)
+/**
+* Cancels a dial Request
+*
+* @param aTsyReqHandle
+* @return KErrNone if successfully cancelled
+*/
+ {
+ LOGDATA1(">>CSimDataCall::DialCancel");
+ switch(iState)
+ {
+ case RMobileCall::EStatusIdle:
+ case RMobileCall::EStatusConnected:
+ SimPanic(EIllegalCancelRequest); // A DialCancel should never reach the TSY in this state.
+ break;
+
+ case RMobileCall::EStatusDialling:
+ case RMobileCall::EStatusConnecting:
+ iTimer->Cancel();
+
+ TInt err;
+ err = KErrNone;
+ TRAP(err, ChangeStateL(RMobileCall::EStatusIdle,EFalse,EFalse));
+ if (err != KErrNone)
+ {
+ ReqCompleted(iDialRequestHandle, err);
+ }
+ else
+ {
+ ReqCompleted(iDialRequestHandle, KErrCancel);
+ }
+ break;
+
+ default:
+ LOGDATA2("CSimDataCall::DialCancel: No action taken - state: %d",iState);
+ break;
+ }
+ LOGDATA1("<<CSimDataCall::DialCancel");
+ return KErrNone;
+ }
+
+TInt CSimDataCall::AnswerIncomingCall(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams)
+/**
+* Register a client's interest in answering the next incoming call.
+* First register interest in incoming calls with the line, then, if a call
+* is already ringing, start the answer procedure.
+*
+* @param aTsyReqHandle
+* @param aCallParams the call parameters
+* @return KErrNone
+*/
+ {
+ LOGDATA1(">>CSimDataCall::AnswerIncomingCall");
+ TInt err=iLine->SetAutoAnswerCallObject(this);
+ if(err!=KErrNone)
+ {
+ ReqCompleted(aTsyReqHandle,err);
+ return KErrNone;
+ }
+
+ PopulateCallParams(aCallParams);
+ iAnswerIncomingCall.iNotifyPending=ETrue;
+ iAnswerIncomingCall.iNotifyHandle=aTsyReqHandle;
+
+ TInt ret=KErrNone;
+ if(iState==RMobileCall::EStatusRinging)
+ ActionEvent(ECallEventAnswerIncoming,KErrNone);
+ else if(iLine->iState==RMobileCall::EStatusRinging)
+ {
+ TRAP(ret,ret=ChangeStateL(RMobileCall::EStatusRinging,EFalse,EFalse));
+ if(ret == KErrNone)
+ {
+ ret = ActionEvent(ECallEventAnswerIncoming,KErrNone);
+ }
+ }
+ LOGDATA1("<<CSimDataCall::AnswerIncomingCall");
+ return ret;
+ }
+
+TInt CSimDataCall::AnswerIncomingCallCancel(const TTsyReqHandle /*aTsyReqHandle*/)
+/**
+* Cancels a AnswerIncomingCall Request
+*
+* @param aTsyReqHandle
+* @return KErrNone if successfully cancelled
+*/
+ {
+ LOGDATA1(">>CSimDataCall::AnswerIncomingCallCancel");
+ if(iAnswerIncomingCall.iNotifyPending)
+ {
+ iAnswerIncomingCall.iNotifyPending=EFalse;
+ iLine->ResetAutoAnswerCallObject(this);
+ ReqCompleted(iAnswerIncomingCall.iNotifyHandle,KErrCancel);
+ }
+ LOGDATA1("<<CSimDataCall::AnswerIncomingCallCancel");
+ return KErrNone;
+ }
+
+TInt CSimDataCall::Connect(const TTsyReqHandle aTsyReqHandle,const TDesC8* /*aCallParams*/)
+ {
+ ReqCompleted(aTsyReqHandle,KErrNotSupported);
+ return KErrNone;
+ }
+
+TInt CSimDataCall::ConnectCancel(const TTsyReqHandle aTsyReqHandle)
+ {
+ ReqCompleted(aTsyReqHandle,KErrNotSupported);
+ return KErrNone;
+ }
+
+TInt CSimDataCall::HangUp(const TTsyReqHandle aTsyReqHandle)
+/**
+* Process a client's HangUp request.
+*
+* @param aTsyReqHandle
+* @return KErrNone
+*/
+ {
+ LOGDATA1(">>CSimDataCall::HangUp");
+ iHangUpRequestHandle=aTsyReqHandle;
+ TInt err=ActionEvent(ECallEventHangUp,KErrNone);
+ if(err!=KErrNone)
+ ReqCompleted(aTsyReqHandle,err);
+ LOGDATA1("<<CSimDataCall::HangUp");
+ return KErrNone;
+ }
+
+TInt CSimDataCall::HangUpCancel(const TTsyReqHandle /*aTsyReqHandle*/)
+/**
+* Cancels a HangUp Request
+*
+* @param aTsyReqHandle
+* @return KErrNone if successfully cancelled
+*/
+ {
+ LOGDATA1(">>CSimDataCall::HangUpCancel");
+ switch(iState)
+ {
+ case RMobileCall::EStatusIdle:
+ SimPanic(EIllegalCancelRequest); // A DialCancel should never reach the TSY in this state.
+ break;
+
+ case RMobileCall::EStatusDisconnecting:
+ iTimer->Cancel();
+
+ TInt err;
+ err = KErrNone;
+ TRAP(err, ChangeStateL(RMobileCall::EStatusIdle,EFalse,EFalse));
+ if (err != KErrNone)
+ {
+ ReqCompleted(iHangUpRequestHandle, err);
+ }
+ else
+ {
+ ReqCompleted(iHangUpRequestHandle, KErrCancel);
+ }
+ break;
+
+ default:
+ LOGDATA2("CSimDataCall::HangUpCancel: No action taken - state: %d",iState);
+ break;
+ }
+ LOGDATA1("<<CSimDataCall::HangUpCancel");
+ return KErrNone;
+ }
+
+TInt CSimDataCall::RelinquishOwnership()
+ {
+ return KErrNotSupported;
+ }
+
+TInt CSimDataCall::GetBearerServiceInfo(const TTsyReqHandle aTsyReqHandle,RCall::TBearerService* aBearerService)
+/**
+ * Retrieves the bearer service info. Bearer service information is only valid
+ * when the call is active.
+ */
+ {
+ if(iState!=RMobileCall::EStatusConnected)
+ {
+ ReqCompleted(aTsyReqHandle,KErrEtelCallNotActive);
+ return KErrNone;
+ }
+
+ *aBearerService=iBearerService;
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+
+TInt CSimDataCall::GetCallParams(const TTsyReqHandle aTsyReqHandle, TDes8* aCallParams)
+/**
+ * Retrives the call parameters. This function must handle both core and Multimode
+ * extension versions of the function. Call parameter information is only valid
+ * when the call is active.
+ */
+ {
+ if(iState!=RMobileCall::EStatusConnected)
+ {
+ ReqCompleted(aTsyReqHandle,KErrEtelCallNotActive);
+ return KErrNone;
+ }
+
+ TPckg<RCall::TCallParams>* callParamPckg=(TPckg<RCall::TCallParams>*)aCallParams;
+ RCall::TCallParams& callParam=(*callParamPckg)();
+
+ if(callParam.ExtensionId()==RMobileCall::KETelMobileDataCallParamsV1)
+ {
+// If the passed package is MobileParams, then we can just unpackage and copy.
+ RMobileCall::TMobileDataCallParamsV1Pckg* mobileCallParamPckg=(RMobileCall::TMobileDataCallParamsV1Pckg*)aCallParams;
+ RMobileCall::TMobileDataCallParamsV1& mobileCallParam=(*mobileCallParamPckg)();
+
+ // Check that the data structure is supported by the simulated TSY version
+ TInt err = iPhone->CheckSimTsyVersion(mobileCallParam);
+ if(err != KErrNone)
+ {
+ ReqCompleted(aTsyReqHandle, err);
+ return KErrNone;
+ }
+
+ mobileCallParam=iMobileCallParams;
+ }
+
+ else if(callParam.ExtensionId()==RMobileCall::KETelMobileHscsdCallParamsV1)
+ {
+ TPckg<RMobileCall::TMobileHscsdCallParamsV1>* mobileCallParamPckg=(TPckg<RMobileCall::TMobileHscsdCallParamsV1>*)aCallParams;
+ RMobileCall::TMobileHscsdCallParamsV1& mobileCallParam=(*mobileCallParamPckg)();
+
+ // Check that the data structure is supported by the simulated TSY version
+ TInt err = iPhone->CheckSimTsyVersion(mobileCallParam);
+ if(err != KErrNone)
+ {
+ ReqCompleted(aTsyReqHandle, err);
+ return KErrNone;
+ }
+
+ mobileCallParam=iHscsdSettings;
+ }
+ else
+ {
+// If, however, its a core (or an unrecognised extension), we must only copy the
+// core parameters.
+ callParam.iSpeakerControl=iMobileCallParams.iSpeakerControl;
+ callParam.iSpeakerVolume=iMobileCallParams.iSpeakerVolume;
+ callParam.iInterval=iMobileCallParams.iInterval;
+ callParam.iWaitForDialTone=iMobileCallParams.iWaitForDialTone;
+ }
+
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+
+TInt CSimDataCall::LoanDataPort(const TTsyReqHandle aReqHandle,RCall::TCommPort* aCommPort)
+/**
+ * Loans the comm port to a client for subsequent streaming of data.
+ * For the comm port to be loaned the call must be active and the port unloaned.
+ */
+ {
+ if(iState!=RMobileCall::EStatusConnected)
+ {
+ ReqCompleted(aReqHandle,KErrEtelCallNotActive);
+ return KErrNone;
+ }
+
+ if(iCommPortLoaned)
+ {
+ ReqCompleted(aReqHandle,KErrEtelPortAlreadyLoaned);
+ return KErrNone;
+ }
+
+ aCommPort->iCsy.Copy(iCsyName);
+ aCommPort->iPort.Copy(iPortName);
+ iCommPortLoaned=ETrue;
+ ReqCompleted(aReqHandle,KErrNone);
+ return KErrNone;
+ }
+
+TInt CSimDataCall::LoanDataPortCancel(const TTsyReqHandle)
+/**
+ * Cancels the LoanDataPort request.
+ * The LoanDataPort function completes synchronously, so there is nothing to cancel.
+ */
+ {
+ return KErrNone;
+ }
+
+TInt CSimDataCall::RecoverDataPort(const TTsyReqHandle aReqHandle)
+/**
+ * Recovers the comm port.
+ * The comm port must be loaned in order to recover it.
+ */
+ {
+ if(!iCommPortLoaned)
+ {
+ ReqCompleted(aReqHandle,KErrEtelPortNotLoanedToClient);
+ return KErrNone;
+ }
+
+ iNtRas->Terminate();
+ iCommPortLoaned=EFalse;
+ ReqCompleted(aReqHandle,KErrNone);
+ return KErrNone;
+ }
+
+TInt CSimDataCall::ActionEvent(TCallEvent aEvent,TInt aStatus)
+/**
+* Entry point when an event has occured that may advance the state machine.
+* The aEvent parameter describes the event.
+*
+* This function contains the main state machine for the data call. The outer layer
+* switches on the event type. Where appropriate, there are inner layer switches
+* or conditional statements to handle the different responses that may be required to
+* the same event occurring in different states.
+*
+* @param aEvent The Call event to handle
+* @return value represents the error state caused by the attempted state machine jump.
+*/
+ {
+ TInt ret=KErrNone;
+ __ASSERT_ALWAYS(iState!=RMobileCall::EStatusUnknown,SimPanic(ECallStatusUnknownIllegal));
+
+ switch(aEvent)
+ {
+ case ECallEventDial:
+ LOGDATA1(">>CSimDataCall::ActionEvent = [ECallEventDial]");
+ if(iState==RMobileCall::EStatusIdle)
+ {
+ TRAP(ret, ret=ChangeStateL(RMobileCall::EStatusDialling,EFalse,EFalse));
+ if(ret==KErrNone)
+ iTimer->Start(iDiallingPause,this);
+ }
+ else
+ return KErrEtelCallAlreadyActive;
+ break;
+
+ case ECallEventHangUp:
+ {
+ LOGDATA1(">>CSimDataCall::ActionEvent = [ECallEventHangUp]");
+ switch(iState)
+ {
+ case RMobileCall::EStatusConnected:
+ iCommPortLoaned=EFalse;
+ iNtRas->Terminate();
+// Note: No "break;" - fall through to the rest of the discconnecting code...
+ case RMobileCall::EStatusDialling:
+ case RMobileCall::EStatusRinging:
+ case RMobileCall::EStatusAnswering:
+ case RMobileCall::EStatusConnecting:
+ iTimer->Cancel();
+ TRAP(ret, ret=ChangeStateL(RMobileCall::EStatusDisconnecting,EFalse,EFalse));
+ if(ret==KErrNone)
+ iTimer->Start(iDisconnectingPause,this);
+ break;
+ default:
+ return KErrEtelCallNotActive;
+ }
+ }
+ break;
+
+ case ECallEventIncomingCall:
+ LOGDATA1(">>CSimDataCall::ActionEvent = [ECallEventIncomingCall]");
+ if(iState==RMobileCall::EStatusIdle)
+ {
+ if(iAnswerIncomingCall.iNotifyPending)
+ {
+ TRAP(ret, ret=ProcessAnswerIncomingCallL());
+ }
+ else
+ {
+ TRAP(ret, ret=ChangeStateL(RMobileCall::EStatusRinging,EFalse,EFalse));
+ if(ret!=KErrNone)
+ return ret;
+ }
+ }
+ else
+ return KErrEtelCallAlreadyActive;
+ break;
+
+ case ECallEventAnswerIncoming:
+ LOGDATA1(">>CSimDataCall::ActionEvent = [ECallEventAnswerIncoming]");
+ if(iState==RMobileCall::EStatusRinging)
+ {
+ TRAP(ret, ret=ProcessAnswerIncomingCallL());
+ }
+ else
+ SimPanic(EIllegalStateInconsistancy); // The state is checked in AnswerIncomingCall, so there's been an inconsistancy if the state is out of line.
+ break;
+
+ case ECallEventRemoteHangup:
+ LOGDATA1(">>CSimDataCall::ActionEvent = [ECallEventRemoteHangup]");
+ if(iState==RMobileCall::EStatusConnected)
+ {
+ TRAP(ret, ret=ProcessRemoteHangupL());
+ }
+ else
+ SimPanic(EIllegalStateInconsistancy); // The state is checked in RemoteHangup, so there's been an inconsistancy if the state is out of line.
+ break;
+
+ case ECallEventTimeOut:
+ {
+ LOGDATA1(">>CSimVoiceCall::ActionEvent = [ECallEventTimeOut]");
+ switch(iState)
+ {
+ case RMobileCall::EStatusDialling:
+ LOGDATA1(">>CSimDataCall::State = [EStatusDialling]");
+ TRAP(ret, ret=ChangeStateL(RMobileCall::EStatusConnecting,EFalse,EFalse));
+ if(ret==KErrNone)
+ iTimer->Start(iConnectingPause,this);
+ return ret;
+
+ case RMobileCall::EStatusConnecting:
+ LOGDATA1(">>CSimDataCall::State = [EStatusConnecting]");
+// If the config file has not spec'ed a CSY, then fail the dial...
+ if(iCsyName.Length()==0)
+ {
+ ReqCompleted(iDialRequestHandle,KErrEtelNoCarrier);
+ TRAP(ret, ret=ChangeStateL(RMobileCall::EStatusIdle,EFalse,EFalse));
+
+ __ASSERT_ALWAYS(ret==KErrNone,SimPanic(EIllegalStateInconsistancy));
+ return KErrNone;
+ }
+ ret=iNtRas->Connect(iCsyName,iPortName,iConfig,this);
+ if(ret!=KErrNone)
+ ReqCompleted(iDialRequestHandle,ret);
+ return ret;
+
+ case RMobileCall::EStatusDisconnecting:
+ LOGDATA1(">>CSimDataCall::State = [EStatusDisconnecting]");
+ TRAP(ret, ret=ChangeStateL(RMobileCall::EStatusIdle,EFalse,EFalse));
+ ReqCompleted(iHangUpRequestHandle,ret);
+ return ret;
+
+ case RMobileCall::EStatusAnswering:
+ LOGDATA1(">>CSimDataCall::State = [EStatusAnswering]");
+ TRAP(ret, ret=ChangeStateL(RMobileCall::EStatusConnected,EFalse,EFalse));
+ ReqCompleted(iAnswerIncomingCall.iNotifyHandle,ret);
+ return ret;
+
+ default:
+ LOGDATA2(">>CSimDataCall::State = [%d]",iState);
+ break;
+ }
+ }
+ break;
+
+ case ECallEventNtRasConnected:
+ if(aStatus!=KErrNone)
+ {
+ ReqCompleted(iDialRequestHandle,aStatus);
+ TRAP(ret, ret=ChangeStateL(RMobileCall::EStatusIdle,EFalse,EFalse));
+ __ASSERT_ALWAYS(ret==KErrNone,SimPanic(EIllegalStateInconsistancy));
+ return KErrNone;
+ }
+ else
+ {
+ TRAP(ret, ret=ChangeStateL(RMobileCall::EStatusConnected,EFalse,EFalse));
+ ChangeDynamicInfo();
+ ReqCompleted(iDialRequestHandle,ret);
+ return KErrNone;
+ }
+ default:
+ SimPanic(EIllegalStateInconsistancy);
+ break;
+ }
+
+ return ret;
+ }
+
+
+void CSimDataCall::TimerCallBack(TInt /*aId*/)
+/**
+* Timer callback function. When the timer goes off, it will call back into this
+* function for further processing.
+*/
+ {
+ LOGDATA1(">>CSimDataCall::TimerCallBack");
+ TInt err=ActionEvent(ECallEventTimeOut,KErrNone);
+ __ASSERT_ALWAYS(err==KErrNone,SimPanic(ETimeOutEventActionFailed));
+ LOGDATA1("<<CSimDataCall::TimerCallBack");
+ }
+
+TInt CSimDataCall::ProcessAnswerIncomingCallL()
+/**
+* Answers an Incoming Call.
+* First the call state must be changed to "answering", then the flag indicating
+* that an answer incoming call request is no longer pending. Finally, a new
+* call object must be assigned to receive the details of the next incoming call.
+*/
+ {
+ LOGDATA1(">>CSimDataCall::ProcessAnswerIncomingCall");
+ TInt ret=ChangeStateL(RMobileCall::EStatusAnswering,EFalse,EFalse);
+ if(ret!=KErrNone)
+ return ret;
+ iTimer->Start(iAnswerIncomingPause,this);
+ iAnswerIncomingCall.iNotifyPending=EFalse;
+ iLine->ResetAutoAnswerCallObject(this);
+ LOGDATA1("<<CSimDataCall::ProcessAnswerIncomingCall");
+ return ret;
+ }
+
+TInt CSimDataCall::ProcessRemoteHangupL()
+/**
+* Hangs up a call from the remote end.
+* First the call state must be changed to "disconnecting", then the flag indicating
+* that a remote hangup request is no longer pending. Finally, a new
+* call object must be assigned to be the next remotely hung up call.
+*/
+ {
+ LOGDATA1(">>CSimDataCall::ProcessRemoteHangupL");
+ TInt ret=ChangeStateL(RMobileCall::EStatusDisconnecting,EFalse,EFalse);
+ if(ret!=KErrNone)
+ return ret;
+ iTimer->Start(iRemoteHangupPause,this);
+ iLine->ResetRemoteHangupCallObject(this);
+ LOGDATA1("<<CSimDataCall::ProcessRemoteHangupL");
+ return ret;
+ }
+
+
+void CSimDataCall::PopulateCallParams(const TDesC8* aCallParams)
+/**
+ * This function populates the call parameter member variable iMobileCallParams.
+ * The function must handle core and multimode extension call parameters.
+ * @param aCallParams A pointer to the call parameter variable.
+ */
+ {
+ TPckg<RCall::TCallParams>* callParamPckg=(TPckg<RCall::TCallParams>*)aCallParams;
+ RCall::TCallParams& callParam=(*callParamPckg)();
+
+ if(callParam.ExtensionId()==RMobileCall::KETelMobileDataCallParamsV1)
+ {
+// If the passed package is MobileParams, then we can just unpackage and copy.
+ RMobileCall::TMobileDataCallParamsV1Pckg* mobileCallParamPckg=(RMobileCall::TMobileDataCallParamsV1Pckg*)aCallParams;
+ RMobileCall::TMobileDataCallParamsV1& mobileCallParam=(*mobileCallParamPckg)();
+
+ iHscsdCall=EFalse;
+ iMobileCallParams=mobileCallParam;
+ }
+ else if(callParam.ExtensionId()==RMobileCall::KETelMobileHscsdCallParamsV1)
+ {
+ TPckg<RMobileCall::TMobileHscsdCallParamsV1>* mobileCallParamPckg=(TPckg<RMobileCall::TMobileHscsdCallParamsV1>*)aCallParams;
+ RMobileCall::TMobileHscsdCallParamsV1& mobileCallParam=(*mobileCallParamPckg)();
+
+ iHscsdCall=ETrue;
+ iHscsdSettings=mobileCallParam;
+ }
+ else
+ {
+// If, however, its core (or an unrecognised extension), we must first reset the member
+// member variable before copying just the core parameters.
+ RMobileCall::TMobileDataCallParamsV1 mobileCallParam;
+
+ iMobileCallParams=mobileCallParam;
+ iHscsdCall=EFalse;
+ iMobileCallParams.iSpeakerControl=callParam.iSpeakerControl;
+ iMobileCallParams.iSpeakerVolume=callParam.iSpeakerVolume;
+ iMobileCallParams.iInterval=callParam.iInterval;
+ iMobileCallParams.iWaitForDialTone=callParam.iWaitForDialTone;
+ }
+ }
+
+void CSimDataCall::NTRasCallBack(TInt aStatus)
+/**
+ * NTRas callback function. This function will be called when the NTRAS
+ * Server has responded.
+ * @param aStatus Standard error value, indicating the success or failure of the NTRAS
+ * connection.
+ */
+ {
+ TInt err=ActionEvent(ECallEventNtRasConnected,aStatus);
+ __ASSERT_ALWAYS(err==KErrNone,SimPanic(EIllegalStateInconsistancy));
+ }
+
+TUint CSimDataCall::Caps()
+/**
+ * Return the current capabilities of this call.
+ * @return TUint Current call capabilities.
+ */
+ {
+ TUint caps=RCall::KCapsData;
+ GenerateCoreCallCaps(caps);
+ if(iState==RMobileCall::EStatusConnected)
+ {
+ if(iCommPortLoaned)
+ caps|=RCall::KCapsRecoverDataPort;
+ else
+ caps|=RCall::KCapsLoanDataPort;
+ }
+ return caps;
+ }
+
+TInt CSimDataCall::GetMobileDataCallCaps(const TTsyReqHandle aTsyReqHandle, TDes8* aCaps)
+/**
+*
+* @param aTsyReqHandle specifies the request handle.
+* @param aCaps is used to return the retrieved capabilities to the client.
+* @return value returns the result of this operation
+*/
+ {
+ TPckg<RMobileCall::TMobileCallDataCapsV1>* mobileCallCapsPckg=(TPckg<RMobileCall::TMobileCallDataCapsV1>*)aCaps;
+ RMobileCall::TMobileCallDataCapsV1& mobileCallCaps=(*mobileCallCapsPckg)();
+
+ // Check that the data structure is supported by the simulated TSY version
+ TInt err = iPhone->CheckSimTsyVersion(mobileCallCaps);
+ if(err != KErrNone)
+ {
+ ReqCompleted(aTsyReqHandle, err);
+ return KErrNone;
+ }
+
+ if(mobileCallCaps.ExtensionId()==KETelExtMultimodeV1)
+ {
+ mobileCallCaps=iMobileCallCaps;
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+ else
+ {
+ ReqCompleted(aTsyReqHandle,KErrNotFound);
+ return KErrNotFound;
+ }
+}
+
+TInt CSimDataCall::GetMobileDataCallCapsCancel(const TTsyReqHandle aTsyReqHandle)
+/**
+*
+* @param aTsyReqHandle specifies the request handle to be canceled
+* @return value returns the result of this operation
+*/
+ {
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+
+TInt CSimDataCall::SetDynamicHSCSDParams(const TTsyReqHandle aTsyReqHandle, RMobileCall::TMobileCallAiur* aAiur, TInt* aRxTimeslots)
+/**
+*
+* @param aTsyReqHandle specifies the request handle.
+* @param aAiur is used to dynamically change Aiur for this call
+* @param aRxTimeslots is used to dynamically change RxTimeslots for this call
+* @return value returns the result of this operation
+*/
+ {
+ iHscsdInfo.iRxTimeSlots=*aRxTimeslots;
+ iHscsdInfo.iAiur=*aAiur;
+ iHscsdSettings.iWantedRxTimeSlots=*aRxTimeslots;
+ iHscsdSettings.iWantedAiur=*aAiur;
+
+ if(iNotifyInfo.iNotifyPending)
+ {
+ *(RMobileCall::TMobileCallHscsdInfoV1*)iNotifyInfo.iNotifyData=iHscsdInfo;
+ iNotifyInfo.iNotifyPending=EFalse;
+ ReqCompleted(iNotifyInfo.iNotifyHandle,KErrNone);
+ }
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+}
+
+TInt CSimDataCall::SetDynamicHSCSDParamsCancel(const TTsyReqHandle aTsyReqHandle)
+/**
+*
+* @param aTsyReqHandle specifies the request handle to be canceled
+* @return value returns the result of this operation
+*/
+ {
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+
+TInt CSimDataCall::GetCurrentHSCSDInfo(const TTsyReqHandle aTsyReqHandle, TDes8* aInfo)
+/**
+*
+* @param aTsyReqHandle specifies the request handle.
+* @param aInfo is used to return the current Hscsd information to the client
+* @return value returns the result of this operation
+*/
+ {
+ TPckg<RMobileCall::TMobileCallHscsdInfoV1>* hscsdInfoPckg=(TPckg<RMobileCall::TMobileCallHscsdInfoV1>*)aInfo;
+ RMobileCall::TMobileCallHscsdInfoV1& hscsdInfo=(*hscsdInfoPckg)();
+
+ // Check that the data structure is supported by the simulated TSY version
+ TInt err = iPhone->CheckSimTsyVersion(hscsdInfo);
+ if(err != KErrNone)
+ {
+ ReqCompleted(aTsyReqHandle, err);
+ return KErrNone;
+ }
+
+ if(hscsdInfo.ExtensionId()==KETelExtMultimodeV1)
+ {
+ hscsdInfo=iHscsdInfo;
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+ else
+ {
+ ReqCompleted(aTsyReqHandle,KErrNotFound);
+ return KErrNotFound;
+ }
+ }
+
+TInt CSimDataCall::NotifyHSCSDInfoChange(const TTsyReqHandle aTsyReqHandle, TDes8* aHSCSDInfo)
+/**
+*
+* @param aTsyReqHandle specifies the request handle.
+* @param aInfo is used to return the current Hscsd information when the notification completes
+* @return value returns the result of this operation
+*/
+ {
+ __ASSERT_ALWAYS(!iNotifyInfo.iNotifyPending,SimPanic(ENotificationAlreadyPending));
+
+ iNotifyInfo.iNotifyPending = ETrue;
+ iNotifyInfo.iNotifyHandle = aTsyReqHandle;
+
+ TPckg<RMobileCall::TMobileCallHscsdInfoV1>* hscsdInfo = (TPckg<RMobileCall::TMobileCallHscsdInfoV1>*)aHSCSDInfo;
+ RMobileCall::TMobileCallHscsdInfoV1& hscsdInfoV1 = (*hscsdInfo)();
+
+ // Check that the data structure is supported by the simulated TSY version
+ TInt err = iPhone->CheckSimTsyVersion(hscsdInfoV1);
+ if(err != KErrNone)
+ {
+ ReqCompleted(aTsyReqHandle, err);
+ return KErrNone;
+ }
+
+ iNotifyInfo.iNotifyData = &hscsdInfoV1;
+ return KErrNone;
+ }
+
+TInt CSimDataCall::NotifyHSCSDInfoChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
+/**
+*
+* @param aTsyReqHandle specifies the request handle to be canceled
+* @return value returns the result of this operation
+*/
+ {
+ if(iNotifyInfo.iNotifyPending)
+ {
+ iNotifyInfo.iNotifyPending=EFalse;
+ ReqCompleted(iNotifyInfo.iNotifyHandle,KErrCancel);
+ }
+ return KErrNone;
+ }
+
+TInt CSimDataCall::NotifyMobileDataCapsChange(const TTsyReqHandle aTsyReqHandle, TDes8* /*aCaps*/)
+ {
+/**
+*
+* @param aTsyReqHandle specifies the request handle to be canceled
+* @return value returns the result of this operation
+*/
+ ReqCompleted(aTsyReqHandle,KErrNotSupported);
+ return KErrNotSupported;
+ }
+
+TInt CSimDataCall::NotifyMobileDataCapsChangeCancel(const TTsyReqHandle aTsyReqHandle)
+/**
+*
+* @param aTsyReqHandle specifies the request handle to be canceled
+* @return value returns the result of this operation
+*/
+ {
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+
+TInt CSimDataCall::GetMobileDataCallRLPRange(const TTsyReqHandle aTsyReqHandle, TInt* aRLPVersion, TDes8* aRLPRange)
+ {
+/**
+*
+* @param aTsyReqHandle specifies the request handle to be canceled
+* @param aRLPVersion specifies the version for RLP range retrieval
+* @param aRLPRange is used to return the requested RLP range to the client
+* @return value returns the result of this operation
+*/
+ TInt ret=SearchRetrieveRlp(aRLPVersion,aRLPRange);
+
+ ReqCompleted(aTsyReqHandle,ret);
+ return ret;
+ }
+
+TInt CSimDataCall::GetMobileDataCallRLPRangeCancel(const TTsyReqHandle aTsyReqHandle)
+/**
+*
+* @param aTsyReqHandle specifies the request handle to be canceled
+* @return value returns the result of this operation
+*/
+ {
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+
+void CSimDataCall::ChangeDynamicInfo()
+/**
+*
+* Private function to alter the current Hscsd information
+*/
+ {
+ if(iHscsdCall)
+ {
+ // Change to the requested settings
+ iHscsdInfo.iAiur=iHscsdSettings.iWantedAiur;
+ iHscsdInfo.iRxTimeSlots=iHscsdSettings.iWantedRxTimeSlots;
+ iHscsdInfo.iTxTimeSlots=iHscsdSettings.iMaxTimeSlots-iHscsdSettings.iWantedRxTimeSlots;
+ iHscsdInfo.iCodings=(RMobileCall::TMobileCallTchCoding) iHscsdSettings.iCodings;
+ // Complete a pending notification event for changes in dynamic info of HSCSD
+ if(iNotifyInfo.iNotifyPending)
+ {
+ *(RMobileCall::TMobileCallHscsdInfoV1*)iNotifyInfo.iNotifyData=(RMobileCall::TMobileCallHscsdInfoV1)iHscsdInfo;
+ ReqCompleted(iNotifyInfo.iNotifyHandle,KErrNone);
+ }
+ }
+ }
+
+TInt CSimDataCall::SearchRetrieveRlp(TInt* aRLPVersion,TDes8* aRLPRange)
+/**
+*
+* Private function to search the list of available RLP ranges per version
+* and return the appropriate range.
+*/
+ {
+ TInt count = iMobileCallRLPList->Count();
+ TMobileCallRLPItem item;
+
+ for(TInt i=0; i<count; i++)
+ {
+ item=iMobileCallRLPList->At(i);
+ if(item.iRlpVersion==*aRLPVersion)
+ {
+ *(RMobileCall::TMobileDataRLPRangesV1*)aRLPRange=item.iMobileCallRLP;
+ return KErrNone;
+ }
+ }
+ return KErrNotFound;
+ }
+