--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/telephonyserverplugins/simtsy/src/CSimDataCall.cpp Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +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;
+ }
+