diff -r 000000000000 -r 3553901f7fa8 telephonyprotocols/psdagt/src/psdagt.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/telephonyprotocols/psdagt/src/psdagt.cpp Tue Feb 02 01:41:59 2010 +0200 @@ -0,0 +1,1017 @@ +// Copyright (c) 2003-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: +// + +/** + @file PSDAgt.cpp +*/ + +#include + +#include "psdagt.h" +#include "psdstates.h" +#include "psdlogger.h" + +CPsdOutSM* CPsdOutSM::NewL(MAgentNotify& aObserver, CDialogProcessor* aDlgPrc, CCommsDbAccess& aDbAccess) +/** +Function creates an outbound connection state machine + +@param MAgentObserver& aObserver an observer which will be called back to notify changes in the connection +@param CDialogProcessor* aDlgPrc a pointer to a dialog processor object for use by the state machine +@param CCommsDbAccess& aDbAccess a reference to the comm Db access object to allow the state machine to obtain details from CommDb +@return CPsdOutSM* the newly created object (ownership of the object is passed to the function caller) +*/ + { + __ASSERT_DEBUG(aDlgPrc,User::Invariant()); + CPsdOutSM* sm = new (ELeave) CPsdOutSM(aObserver,aDlgPrc,aDbAccess); + CleanupStack::PushL(sm); + sm->ConstructL(); + CleanupStack::Pop(); + return sm; + } + +CPsdOutSM::CPsdOutSM(MAgentNotify& aObserver, CDialogProcessor* aDlgPrc, CCommsDbAccess& aDbAccess) + : CPsdAgentSMBase(aObserver,aDlgPrc,aDbAccess) +/** +Constructor + +@param MAgentObserver& aObserver an observer which will be called back to notify changes in the connection +@param CDialogProcessor* aDlgPrc a pointer to a dialog processor object for use by the state machine +@param CCommsDbAccess& aDbAccess a reference to the comm Db access object to allow the state machine to obtain details from CommDb +*/ + {} + +CPsdOutSM::~CPsdOutSM() +/** +Destructor +*/ + {} + +void CPsdOutSM::ConstructL() +/** +2nd phase construction of the outgoing state machine +creates the initial state of the state machine +*/ + { + CPsdAgentSMBase::ConstructL(); + iState = new (ELeave) CPsdOutInit(this,this,this); + } + +TCommDbConnectionDirection CPsdOutSM::Direction() +/** +Function indicates the direction of the connection which is in progress + +@return TCommDbConnectionDirection the connection direction +*/ + { return ECommDbConnectionDirectionOutgoing;} + +#ifndef INCOMING_NOT_SUPORTED + +CPsdInSM* CPsdInSM::NewL(MAgentObserver& aObserver, CDialogProcessor* aDlgPrc, CCommsDbAccess& aDbAccess) +/** +Function creates an inbound connection state machine + +@param MAgentObserver& aObserver an observer which will be called back to notify changes in the connection +@param CDialogProcessor* aDlgPrc a pointer to a dialog processor object for use by the state machine +@param CCommsDbAccess& aDbAccess a reference to the comm Db access object to allow the state machine to obtain details from CommDb +@return CPsdInSM* the newly created object (ownership of the object is passed to the function caller) +*/ + { + __ASSERT_DEBUG(aDlgPrc,User::Invariant()); + CPsdInSM* sm = new (ELeave) CPsdInSM(aObserver,aDlgPrc,aDbAccess); + CleanupStack::PushL(sm); + sm->ConstructL(); + CleanupStack::Pop(); + return sm; + } + +CPsdInSM::CPsdInSM(MAgentObserver& aObserver, CDialogProcessor* aDlgPrc, CCommsDbAccess& aDbAccess) + : CPsdAgentSMBase(aObserver,aDlgPrc,aDbAccess) +/** +Constructor + +@param MAgentObserver& aObserver an observer which will be called back to notify changes in the connection +@param CDialogProcessor* aDlgPrc a pointer to a dialog processor object for use by the state machine +@param CCommsDbAccess& aDbAccess a reference to the comm Db access object to allow the state machine to obtain details from CommDb +*/ + {} + +CPsdInSM::~CPsdInSM() +/** +Destructor +*/ + {} + +void CPsdInSM::ConstructL() +/** +2nd phase construction of the incoming state machine +creates the initial state of the state machine +*/ + { + CPsdAgentSMBase::ConstructL(); + iState = new (ELeave) CPsdInInit(this,this,this); + } + +TCommDbConnectionDirection CPsdInSM::Direction() +/** +Function indicates the direction of the connection which is in progress + +@return TCommDbConnectionDirection the connection direction +*/ + { return ECommDbConnectionDirectionIncoming;} +#endif // #ifndef INCOMING_NOT_SUPORTED + +CPsdAgentSMBase::CPsdAgentSMBase(MAgentNotify& aObserver, CDialogProcessor* aDlgPrc, CCommsDbAccess& aDbAccess) + : CAgentSMBase(aObserver,aDlgPrc,aDbAccess), + iIsQoSSupported(ETrue)//let's be optimists +/** +Constructor +*/ + {} + +void CPsdAgentSMBase::ConstructL() +/** +2nd phase construction of the state machine base class +to be called in the ConstuctL of derived classes. +The function creates the logging objects and the objects +that contain the parameters for the Context and the QoS +*/ + { + iEventLogger=CEventLogger::NewL(); + iDataLogger=CDataLogger::NewL(this,this); + InquireModeL(); + iConfig=CPsdContextConfig::NewL(*iDb,iNetworkMode); + iQoSConfig=CPsdContextQoSConfig::NewL(*iDb,iNetworkMode); + } + +CPsdAgentSMBase::~CPsdAgentSMBase() +/** +Destructor +*/ + { + iPacketNetwork.Close(); + iContext.Close(); + iQoS.Close(); + iPhone.Close(); + iTelServer.Close(); + delete iQoSConfig; + delete iConfig; + delete iDataLogger; + delete iEventLogger; + iEventLogger=0; + } + + +TInt CPsdAgentSMBase::GetExcessData(TDes8& /*aBuffer*/) +/** +This is only valid for CSD +To retrieve data for the SM, and accessor functions for the state objects to use. + +@param contains data retrieved from the agent for SM. +@return KErrNotSupported if data is not retrieved. +*/ + { + return KErrNotSupported; + } + +TInt CPsdAgentSMBase::Notification(TNifToAgentEventType /*aEvent*/, TAny* /*aInfo*/) +/** +No NIF to AGENT notifications supported by PSDAGX +Act on / reply to NifMan's notification requests + +@param Type of event from Nifman to Agent. +@param Information about the Agent +@return KErrNotSupported if Event type does not exist. +*/ + { + return KErrNotSupported; + } + +void CPsdAgentSMBase::GetLastError(TInt& aError) +/** +If the context is still open, request last error, otherwise the last error will +have been obtained on closure. + +@param error code if the context is not open. +*/ + { + if (iContext.SubSessionHandle()) + iContext.GetLastErrorCause(aError); + else + aError=iErrorCause; + } + +TBool CPsdAgentSMBase::IsIncomingAllowedL() const +/** +Function to allow clients to inquire if incomming connections are allowed + +@return ETrue if incomming connections allowed else EFalse +*/ + { + // Hurricane does not support Incoming connections so hard code this response to False +#ifdef INCOMING_NOT_SUPORTED + return EFalse; +#else + // Note - the code below should be used when incoming connections are supported + TUint32 allowed; + iDb->GetGlobalL(TPtrC(ACCEPT_INCOMING_GPRS),allowed); + return (TBool)allowed; +#endif + } + +void CPsdAgentSMBase::GetRemotePartyL(TDes& aRemoteParty) const +/** +Function to allow clients to inquire the name of the remote party in the connection + +@param TDes& aRemoteParty reference to a descriptor into which the remote party name will be written. +*/ + { + iDb->GetDesL(TPtrC(KGeneralServiceTable),TPtrC(COMMDB_NAME),aRemoteParty); + } + +void CPsdAgentSMBase::InquireModeL() +/** +Internal function to figure out the current mode and set the iNetworkMode +member appropriately +*/ + { + TBuf serviceType; + iDb->GetServiceTypeL(serviceType); + if(serviceType == TPtrC(OUTGOING_GPRS)) + { + iNetworkMode = EModeWCDMA; + } +#ifndef INCOMING_NOT_SUPORTED + else if(serviceType == TPtrC(INCOMING_GPRS)) + { + iNetworkMode = EModeWCDMA; + } +#endif // #ifndef INCOMING_NOT_SUPORTED + else + { + // The service type is not supported by this AGX so leave + User::Leave(KErrNotSupported); + } + } + +MAgentStateMachineEnv& CPsdAgentSMBase::BaseEnv() + { return *this;} + +RTelServer& CPsdAgentSMBase::TelServer() + { return iTelServer;} + +RPhone& CPsdAgentSMBase::Phone() + { return iPhone;} + +RPacketService& CPsdAgentSMBase::PacketNetwork() + { return iPacketNetwork;} + +RPacketContext& CPsdAgentSMBase::Context() + { return iContext;} + +TBool CPsdAgentSMBase::IsQoSSupported()const + {return iIsQoSSupported;} + +void CPsdAgentSMBase::SetQoSSupported(TBool isSupported) + {iIsQoSSupported=isSupported;} + +RPacketQoS& CPsdAgentSMBase::QoS() + { return iQoS;} + +const CPsdContextConfig& CPsdAgentSMBase::Config() const + { return *iConfig;} + +const CPsdContextQoSConfig& CPsdAgentSMBase::QoSConfig() const + {return *iQoSConfig;} + +TInt& CPsdAgentSMBase::ErrorCause() + { return iErrorCause;} + +CEventLogger* CPsdAgentSMBase::Logger() + { return iEventLogger;} + +CDataLogger* CPsdAgentSMBase::DataLogger() + { return iDataLogger;} + +TBool& CPsdAgentSMBase::AmLogging() +/** +@deprecated since logging requests are stored in a queue now +*/ + { return iAmLogging;} + +TBool CPsdAgentSMBase::TsyLoaded() const + { return iTsyLoaded;} + +void CPsdAgentSMBase::SetTsyLoaded(TBool aStatus) + { iTsyLoaded=aStatus;} + +MPsdEnv::TNetworkMode CPsdAgentSMBase::Mode() const + {return iNetworkMode;} + +CPsdContextConfig* CPsdContextConfig::NewL(CCommsDbAccess& aDbAccess, MPsdEnv::TNetworkMode aMode) +/** +Function creates a CPsdContextConfig object + +@param CCommsDbAccess& aDbAccess a reference to the comm Db access object to allow the class to obtain details from CommDb +@param TNetworkMode aMode the mode of the context config parameters to be created. +@return CPsdContextConfig* the newly created object (ownership of the object is passed to the function caller) +*/ + { + CPsdContextConfig* self = new(ELeave)CPsdContextConfig(aDbAccess,aMode); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); //self + return self; + } + +CPsdContextConfig::CPsdContextConfig(CCommsDbAccess& aDbAccess, MPsdEnv::TNetworkMode aMode) +: iDbAccess(aDbAccess), iMode(aMode) + { + } + +void CPsdContextConfig::ConstructL() +/** +2nd phase construction of CPsdContextConfig calls the appropriate internal construction +function for the current mode +*/ + { + if(iMode == MPsdEnv::EModeWCDMA) + { + GprsConfigConstructL(); + } + } + +CPsdContextConfig::~CPsdContextConfig() +/** +Destructor +*/ + { + delete iConfig; + delete iPackedConfig; + } + +const TPacketDataConfigBase& CPsdContextConfig::Config() const +/** +Function that returns the current context config parameters as a TPacketDataConfigBase + +@return TPacketDataConfigBase& reference to the config parameters. (reurned as the mode agnostic base class) +*/ + { + return *iConfig; + } + +TDesC8& CPsdContextConfig::PackedConfig() const +/** +Function that returns the current context config parameters packed in a descriptor + +@return TDesC8& reference to the config parameters packed in a descriptor. +*/ + { + return *iPackedConfig; + } + +TBool CPsdContextConfig::IsConfigSupportedL(const RPacketService& aPacketData, TCommDbConnectionDirection aDirection) const +/** +Inquiry function to enquire if the TSY is able to support the current context parameters + +@param RPacketService& aPacketData handle to a previously initialised RPacketService object +@param TCommDbConnectionDirection aDirection the direction of the current connection +@return TBool returns ETrue if config supported, EFalse otherwise. +*/ + { + if(!iStaticCaps) + { + // Only get the caps if they havn't been retrieved before + User::LeaveIfError(aPacketData.GetStaticCaps(iStaticCaps,iProtocolType)); + } + TBool result=ETrue; + if(iMode == MPsdEnv::EModeWCDMA) + { + RPacketContext::TContextConfigGPRS& config = *(STATIC_CAST(RPacketContext::TContextConfigGPRS*, iConfig)); + + if ( (config.iAnonymousAccessReqd==RPacketContext::ERequired) + &&(aDirection == ECommDbConnectionDirectionIncoming) ) + { + result=EFalse; + } + else if (!(iStaticCaps & RPacketService::KCapsAASupported) + && (config.iAnonymousAccessReqd==RPacketContext::ERequired)) + { + result=EFalse; + } + else if (!(iStaticCaps & RPacketService::KCapsPdpDataCompSupported) + && (config.iPdpCompression & RPacketContext::KPdpDataCompression)) + { + result=EFalse; + } + else if (!(iStaticCaps & RPacketService::KCapsPdpHeaderCompSupported) + && (config.iPdpCompression & RPacketContext::KPdpHeaderCompression)) + { + result=EFalse; + } + } + return result; + } + + +TBool CPsdContextConfig::TsySupportsDataTransferInfoL(const RPacketService& aPacketData) const +/** +Inquiry function to enquire if the TSY is able to support data transfer inquiries + +@param RPacketService& aPacketData handle to a previously initialised RPacketService object +@return TBool returns ETrue if data transfer inquiry supported, EFalse otherwise. +*/ + { + if(!iStaticCaps) + { + // Only get the caps if they havn't been retrieved before + User::LeaveIfError(aPacketData.GetStaticCaps(iStaticCaps,iProtocolType)); + } + return(iStaticCaps & RPacketService::KCapsGetDataTransferredSupported); + } + +void CPsdContextConfig::GprsConfigConstructL() + +/** +Internal function that constructs the object if the mode is GPRS +interogates CommDb and reads the appropriate parameters from there + +Relies on SetCurrentSettingsL() having already been called by the controller +Also expects the service setting to be opened on the correct GPRS Table (outgoing/incoming) +*/ + { + iConfig=new(ELeave)RPacketContext::TContextConfigGPRS(); + + RPacketContext::TContextConfigGPRS& config = *(STATIC_CAST(RPacketContext::TContextConfigGPRS*, iConfig)); + TUint32 pdptype; + iDbAccess.GetIntL(TPtrC(KGeneralServiceTable),TPtrC(GPRS_PDP_TYPE),pdptype); + config.iPdpType = (RPacketContext::TProtocolType)pdptype; + + // Save the protocol type seperately for easy access when retreiving static caps + iProtocolType = config.iPdpType; + + iDbAccess.GetDesL(TPtrC(KGeneralServiceTable),TPtrC(GPRS_APN),config.iAccessPointName); + iDbAccess.GetDesL(TPtrC(KGeneralServiceTable),TPtrC(GPRS_PDP_ADDRESS),config.iPdpAddress); + + GetGprsCompressionL(config.iPdpCompression); + GetGprsAAL(config.iAnonymousAccessReqd); + + iPackedConfig = new(ELeave)TPckg(config); + } + +void CPsdContextConfig::GetGprsCompressionL(TUint& aCompression) const + { + aCompression = 0; + TBool isCompression; + iDbAccess.GetBoolL(TPtrC(KGeneralServiceTable),TPtrC(GPRS_DATA_COMPRESSION),isCompression); + if (isCompression) + { + aCompression |= RPacketContext::KPdpDataCompression; + } + + iDbAccess.GetBoolL(TPtrC(KGeneralServiceTable),TPtrC(GPRS_HEADER_COMPRESSION),isCompression); + if (isCompression) + { + aCompression |= RPacketContext::KPdpHeaderCompression; + } + } + +void CPsdContextConfig::GetGprsAAL(RPacketContext::TAnonymousAccess& aAnonymous) const + { + TBool isAnonymous; + iDbAccess.GetBoolL(TPtrC(KGeneralServiceTable),TPtrC(GPRS_ANONYMOUS_ACCESS),isAnonymous); + if (isAnonymous) + aAnonymous=RPacketContext::ERequired; + else + aAnonymous=RPacketContext::ENotRequired; + } + +void CPsdContextConfig::GetGprsEdgeL(TBool& aUseEdge) const + { + TBool isUseEdge; + iDbAccess.GetBoolL(TPtrC(KGeneralServiceTable),TPtrC(GPRS_USE_EDGE),isUseEdge); + aUseEdge=isUseEdge; + } + +TBool CPsdContextConfig::QueryIfConfigAcceptable(TDesC8& aNewConfig) const +/** +Function to check if the config passed in the parameter meets the minimum requiremnts +set in CommDb + +@param TDesC8& aNewConfig the config to be checked packed in a descriptor +@return TBool ETrue if the config passed in is above or equal to the minimum values, EFalse otherwise. +*/ + { + TBool ret = ETrue; + if(iMode == MPsdEnv::EModeWCDMA) + { + TPckg configPckg = *((TPckg*)&aNewConfig); + RPacketContext::TContextConfigGPRS& newConfig = configPckg(); + ret = QueryIfGprsConfigAcceptable(newConfig); + } + return ret; + } + +TBool CPsdContextConfig::QueryIfGprsConfigAcceptable(const RPacketContext::TContextConfigGPRS& /*aNewConfig*/) const +/** +Internal function to check if the config passed in the parameter meets the minimum required for GPRS + +@param RPacketContext::TContextConfigGPRS& aNewConfig the config to be checked against the minimum values +@return TBool ETrue if the config passed in is above or equal to the minimum values, EFalse otherwise. +*/ + { + // Apparently the GPRS network has to give you what you asked for otherwise + // it will not complete the connection, so just return ETrue + return ETrue; + } + +TBool CPsdContextConfig::QueryIfIncommingConnectionAcceptable(const RPacketContext::TProtocolType& aProtocolType, const RPacketContext::TProtocolAddress& aProtocolAddress) const +/** +Inquiry function to enquire if incoming connection is valid + +@param RPacketContext::TProtocolType& aProtocolType the protocol type of the incomming connection +@param RPacketContext::TProtocolAddress& aProtocolAddress the address of the incomming connection +@return TBool returns ETrue if connection OK, EFalse otherwise. +*/ + { + if(iMode == MPsdEnv::EModeWCDMA) + { + RPacketContext::TContextConfigGPRS& config = *(STATIC_CAST(RPacketContext::TContextConfigGPRS*, iConfig)); + // For GPRS incoming connection the connection must be IP based and the IP address must be static. + // The IP address should be the one stored in CommDb + if( ((aProtocolType==RPacketContext::EPdpTypeIPv4)||(aProtocolType==RPacketContext::EPdpTypeIPv6)) + && config.iPdpAddress==aProtocolAddress) + { + return ETrue; + } + else + { + return EFalse; + } + } + return EFalse; + } + +//====================================================== +// +// CPsdContextQoSConfig +// +//====================================================== + +CPsdContextQoSConfig* CPsdContextQoSConfig::NewL(CCommsDbAccess& aDbAccess, MPsdEnv::TNetworkMode aMode) +/** +Function creates a CPsdContextQoSConfig object + +@param CCommsDbAccess& aDbAccess a reference to the comm Db access object to allow the class to obtain details from CommDb +@param TNetworkMode aMode the mode of the context config parameters to be created. +@return CPsdContextQoSConfig* the newly created object (ownership of the object is passed to the function caller) +*/ + { + CPsdContextQoSConfig* self = new(ELeave)CPsdContextQoSConfig(aDbAccess,aMode); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); //self + return self; + } + +CPsdContextQoSConfig::CPsdContextQoSConfig(CCommsDbAccess& aDbAccess, MPsdEnv::TNetworkMode aMode) +: iDbAccess(aDbAccess), iMode(aMode) + { + } + +void CPsdContextQoSConfig::ConstructL() +/** +2nd phase construction of CPsdContextQoSConfig calls the appropriate internal construction +function for the current mode +*/ + { + if(iMode == MPsdEnv::EModeWCDMA) + { + GprsQoSConfigConstructL(); + } + } + +CPsdContextQoSConfig::~CPsdContextQoSConfig() +/** +Destructor +*/ + { + delete iPackedQoSConfig; + delete iQoSConfig; + } + +const TPacketDataConfigBase& CPsdContextQoSConfig::QoSConfig() const +/** +Function that returns the current QoS config parameters as a TPacketDataConfigBase + +@return TPacketDataConfigBase& reference to the QoS config parameters. (reurned as the mode agnostic base class) +*/ + { + return *iQoSConfig; + } + +TDes8& CPsdContextQoSConfig::PackedQoSConfig() const +/** +Function that returns the current QoS config parameters packed in a descriptor + +@return TDesC8& reference to the QoS config parameters packed in a descriptor. +*/ + { + return *iPackedQoSConfig; + } + +void CPsdContextQoSConfig::GprsQoSConfigConstructL() +/** +Internal function that constructs the object if the mode is GPRS +interogates CommDb and reads the appropriate parameters from there +*/ + { + iQoSConfig=new(ELeave)RPacketQoS::TQoSGPRSRequested(); + RPacketQoS::TQoSGPRSRequested& qoSConfig = *(STATIC_CAST(RPacketQoS::TQoSGPRSRequested*, iQoSConfig)); + + + TUint32 data; + iDbAccess.GetIntL(TPtrC(KGeneralServiceTable),TPtrC(GPRS_REQ_PRECEDENCE),data); + qoSConfig.iReqPrecedence = (RPacketQoS::TQoSPrecedence)data; + + iDbAccess.GetIntL(TPtrC(KGeneralServiceTable),TPtrC(GPRS_REQ_DELAY),data); + qoSConfig.iReqDelay = (RPacketQoS::TQoSDelay)data; + + iDbAccess.GetIntL(TPtrC(KGeneralServiceTable),TPtrC(GPRS_REQ_RELIABILITY),data); + qoSConfig.iReqReliability = (RPacketQoS::TQoSReliability)data; + + iDbAccess.GetIntL(TPtrC(KGeneralServiceTable),TPtrC(GPRS_REQ_PEAK_THROUGHPUT),data); + qoSConfig.iReqPeakThroughput = (RPacketQoS::TQoSPeakThroughput)data; + + iDbAccess.GetIntL(TPtrC(KGeneralServiceTable),TPtrC(GPRS_REQ_MEAN_THROUGHPUT),data); + qoSConfig.iReqMeanThroughput = (RPacketQoS::TQoSMeanThroughput)data; + + iDbAccess.GetIntL(TPtrC(KGeneralServiceTable),TPtrC(GPRS_MIN_PRECEDENCE),data); + qoSConfig.iMinPrecedence = (RPacketQoS::TQoSPrecedence)data; + + iDbAccess.GetIntL(TPtrC(KGeneralServiceTable),TPtrC(GPRS_MIN_DELAY),data); + qoSConfig.iMinDelay = (RPacketQoS::TQoSDelay)data; + + iDbAccess.GetIntL(TPtrC(KGeneralServiceTable),TPtrC(GPRS_MIN_RELIABILITY),data); + qoSConfig.iMinReliability = (RPacketQoS::TQoSReliability)data; + + iDbAccess.GetIntL(TPtrC(KGeneralServiceTable),TPtrC(GPRS_MIN_PEAK_THROUGHPUT),data); + qoSConfig.iMinPeakThroughput = (RPacketQoS::TQoSPeakThroughput)data; + + iDbAccess.GetIntL(TPtrC(KGeneralServiceTable),TPtrC(GPRS_MIN_MEAN_THROUGHPUT),data); + qoSConfig.iMinMeanThroughput = (RPacketQoS::TQoSMeanThroughput)data; + + iPackedQoSConfig = new(ELeave)TPckg(qoSConfig); + } + +TBool CPsdContextQoSConfig::QueryIfQoSAcceptable(TDesC8& aNewQoS) const +/** +Function to check if the QoS config passed in the parameter meets the minimum requiremnts +set in CommDb + +@param TDesC8& aNewQoS the QoS config to be checked packed in a descriptor +@return TBool ETrue if the QoS config passed in is above or equal to the minimum values, EFalse otherwise. +*/ + { + TBool ret = ETrue; + if(iMode == MPsdEnv::EModeWCDMA) + { + TPckg qoSPckg = *((TPckg*)&aNewQoS); + RPacketQoS::TQoSGPRSNegotiated& newQoS = qoSPckg(); + ret = QueryIfGprsQoSAcceptable(newQoS); + } + return ret; + } + +TBool CPsdContextQoSConfig::QueryIfGprsQoSAcceptable(const RPacketQoS::TQoSGPRSNegotiated& /*aNewQoS*/) const +/** +Internal function to check if the QoS config passed in the parameter meets the minimum required for GPRS + +@param RPacketQoS::TQoSGPRSNegotiated& aNewQoS the QoS config to be checked against the minimum values +@return TBool ETrue if the config passed in is above or equal to the minimum values, EFalse otherwise. +*/ + { + // Apparently the GPRS network has to give you what you asked for otherwise + // it will not complete the connection, so just return ETrue + return ETrue; + } + +// +// +// CPsdContextChangeMonitor +// + +CPsdContextChangeMonitor* CPsdContextChangeMonitor::NewL(MPsdEnv* aEnv, MPsdContextChangeObserver* aObserver) + +/** +Function creates a CPsdContextChangeMonitor object + +@param MPsdEnv* aEnv a pointer to a object that provides the MPsdEnv interface +@param MPsdContextChangeObserver* aObserver a pointer to the observing object that should be called back when the quality drops below the minimum value +@return CPsdContextChangeMonitor* the newly created object (ownership of the object is passed to the function caller) +*/ + { + __ASSERT_DEBUG(aEnv && aObserver,User::Invariant()); + CPsdContextChangeMonitor* self = new(ELeave)CPsdContextChangeMonitor(aEnv,aObserver); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); //self + return self; + } + +CPsdContextChangeMonitor::~CPsdContextChangeMonitor() +/** +Destructor +*/ + { + Cancel(); + iDebounceTimer.Close(); + delete iQoSWatcher; + delete iConfigWatcher; + + delete iPackedActualQoSConfig; + delete iActualQoSConfig; + delete iPackedActualConfig; + delete iActualConfig; + } + +CPsdContextChangeMonitor::CPsdContextChangeMonitor(MPsdEnv* aEnv, MPsdContextChangeObserver* aObserver) +: CActive(EPriorityStandard), iSM(aEnv), iObserver(aObserver), iContextState(CPsdContextChangeMonitor::EContextQualityAcceptable) + { + CActiveScheduler::Add(this); + } + +void CPsdContextChangeMonitor::ConstructL() +/** +2nd phase constructor. Initialises the member variables as appropriate for the current mode. +Constructs a CPsdContextConfigChangeWatcher and a CPsdQoSConfigChangeWatcher object to watch for +cahnges in context config and qos config. +*/ + { + TInt r=iDebounceTimer.CreateLocal(); + if (r!=KErrNone) + User::Leave(r); + TUint32 timeOut = 0; // keeps compiler happy; we know it's always set below + if(iSM->Mode() == MPsdEnv::EModeWCDMA) + { + iActualConfig=new(ELeave)RPacketContext::TContextConfigGPRS(); + RPacketContext::TContextConfigGPRS& config = *(STATIC_CAST(RPacketContext::TContextConfigGPRS*, iActualConfig)); + iPackedActualConfig = new(ELeave)TPckg(config); + + iActualQoSConfig=new(ELeave)RPacketQoS::TQoSGPRSNegotiated(); + RPacketQoS::TQoSGPRSNegotiated& qoSConfig = *(STATIC_CAST(RPacketQoS::TQoSGPRSNegotiated*, iActualQoSConfig)); + iPackedActualQoSConfig = new(ELeave)TPckg(qoSConfig); + // Get timeOut from the Db; default to 0 on error (eg. Db value is NULL) + TRAPD(rOk,iSM->BaseEnv().Db()->GetIntL(TPtrC(KGeneralServiceTable),TPtrC(GPRS_QOS_WARNING_TIMEOUT),timeOut)); + if (rOk != KErrNone) + timeOut = 0; + } + iConfigWatcher = new(ELeave)CPsdContextConfigChangeWatcher(iSM->Context(), *this, *iPackedActualConfig); + + if (iSM->IsQoSSupported())//the tsy might not support QoS + iQoSWatcher = new(ELeave)CPsdQoSConfigChangeWatcher(iSM->QoS(), *this, *iPackedActualQoSConfig); + else + iQoSWatcher=0; + + iDebounceTimeout = timeOut; + if(iDebounceTimeout.Int()>0) + { + // The timeout will be greater than zero if the service loss dialogs are enabled + iConfigWatcher->StartL(); + if (iQoSWatcher)//the tsy might not support QoS + iQoSWatcher->StartL(); + } + } + +void CPsdContextChangeMonitor::ReportConfigChange() +/** +Callback function, called when the CPsdContextConfigChangeWatcher object reports +a change in context config parameters +Checks to see if the changed parameters are below the minimum and if so +starts the timeout which will cause the observer to be informed of the +connection going below quality. +If the context config returns to acceptable values before the timeout completes +the timeout is cancelled and the observer will not be notified of the change +*/ + { + // The config has changed check if it is acceptable + TBool acceptable = iSM->Config().QueryIfConfigAcceptable(*iPackedActualConfig); + // Only report if the context was previously of acceptable quality and now it is not + if(!acceptable && (iContextState == EContextQualityAcceptable)) + { + // the context config has just gone below quality - don't report again until it becomes acceptable + iContextState |= EConfigQualityUnAcceptable; + StartTimeout(); + } + else if(acceptable && (iContextState & EConfigQualityUnAcceptable)) + { + // the context config has become of acceptable quality again + iContextState &= ~EConfigQualityUnAcceptable; + CancelTimeout(); + } + } + +void CPsdContextChangeMonitor::ReportQoSChange() +/** +Callback function, called when the CPsdQoSConfigChangeWatcher object reports +a change in QoS config parameters +Checks to see if the changed parameters are below the minimum and if so +starts the timeout which will cause the observer to be informed of the +connection going below quality. +If the QoS config returns to acceptable values before the timeout completes +the timeout is cancelled and the observer will not be notified of the change +*/ + { + // The QoS config has changed check if it is acceptable + TBool acceptable = iSM->QoSConfig().QueryIfQoSAcceptable(*iPackedActualQoSConfig); + // Only report if the context was previously of acceptable quality and now it is not + if(!acceptable && (iContextState == EContextQualityAcceptable)) + { + // the QoS config has just gone below quality - don't report again until it becomes acceptable + iContextState |= EQoSQualityUnAcceptable; + StartTimeout(); + } + else if(acceptable && (iContextState & EQoSQualityUnAcceptable)) + { + // the context config has become of acceptable quality again + iContextState &= ~EQoSQualityUnAcceptable; + CancelTimeout(); + } + } + +void CPsdContextChangeMonitor::RunL() +/** +The RunL will be called when the timeout completes following a drop below acceptable +QoS or context quality. It informs the observer of the quality drop. +*/ + { + // The timeout has completed this means the context quality has been below acceptable + // for the duration of the timeout, so report it + iObserver->ReportContextBelowAcceptableQuality(); + } + +void CPsdContextChangeMonitor::ReportConfigWatcherError(TInt aError) +/** +Callback function called when an error occurs in the CPsdContextConfigChangeWatcher object + +@param error code for error occurs in the CPsdContextConfigChangeWatcher object +*/ + { + iObserver->ReportError(aError); + } + +void CPsdContextChangeMonitor::ReportQoSWatcherError(TInt aError) +/** +Callback function called when an error occurs in the CPsdQoSConfigChangeWatcher object + +@param error code for error occurs in the CPsdQoSConfigChangeWatcher object +*/ + { + iObserver->ReportError(aError); + } + +void CPsdContextChangeMonitor::StartTimeout() + { + if(!IsActive()) + { + iDebounceTimer.After(iStatus, iDebounceTimeout); + SetActive(); + } + } + +void CPsdContextChangeMonitor::CancelTimeout() + { + if(iContextState == EContextQualityAcceptable) + { + Cancel(); + } + } + +void CPsdContextChangeMonitor::DoCancel() + { + iDebounceTimer.Cancel(); + } +// +// +// CPsdContextConfigChangeWatcher +// + +CPsdContextConfigChangeWatcher::CPsdContextConfigChangeWatcher(const RPacketContext& aContext, MObserver& aObserver, TPtr8& aContextParams) +: CActive(EPriorityStandard), iObserver(aObserver), iContext(aContext), iContextParams(aContextParams) +/** +Overloaded Constructor adding itself to the active scheduler +*/ + { + CActiveScheduler::Add(this); + } + +void CPsdContextConfigChangeWatcher::StartL() +/** +Start notifying observer of changes in context config parameters +*/ + { + iContext.NotifyConfigChanged(iStatus, iContextParams); + SetActive(); + } + +CPsdContextConfigChangeWatcher::~CPsdContextConfigChangeWatcher() +/** +Destructor +*/ + { + Cancel(); + } + +void CPsdContextConfigChangeWatcher::RunL() +/** +RunL completes when the context config parameters have changed - call back +the observer to inform them of the event +*/ + { + if(iStatus != KErrNone) + { + iObserver.ReportConfigWatcherError(iStatus.Int()); + } + else + { + iObserver.ReportConfigChange(); + } + // Renew Request + iContext.NotifyConfigChanged(iStatus, iContextParams); + SetActive(); + } + +void CPsdContextConfigChangeWatcher::DoCancel() +/** +Cancell the changes in the context configuration parameters and notifying its observer when such a change occurs. +*/ + { + iContext.CancelAsyncRequest(EPacketContextNotifyConfigChanged); + } + +// +// +// CPsdQoSConfigChangeWatcher +// + +CPsdQoSConfigChangeWatcher::CPsdQoSConfigChangeWatcher(const RPacketQoS& aQoS, MObserver& aObserver, TPtr8& aQoSParams) +: CActive(EPriorityStandard), iObserver(aObserver), iQoS(aQoS), iQoSParams(aQoSParams) +/** +Overloaded Constructor adding itself to the active scheduler +*/ + { + CActiveScheduler::Add(this); + } + +void CPsdQoSConfigChangeWatcher::StartL() +/** +Start notifying observer of changes in QoS config parameters +*/ + { + iQoS.NotifyProfileChanged(iStatus, iQoSParams); + SetActive(); + } + +CPsdQoSConfigChangeWatcher::~CPsdQoSConfigChangeWatcher() +/** +Destructor +*/ + { + Cancel(); + } + +void CPsdQoSConfigChangeWatcher::RunL() +/** +RunL completes when the QoS config parameters have changed - call back +the observer to inform them of the event +*/ + { + if(iStatus != KErrNone) + { + iObserver.ReportQoSWatcherError(iStatus.Int()); + } + else + { + iObserver.ReportQoSChange(); + } + // Renew Request + iQoS.NotifyProfileChanged(iStatus, iQoSParams); + SetActive(); + } + +void CPsdQoSConfigChangeWatcher::DoCancel() + { + iQoS.CancelAsyncRequest(EPacketQoSNotifyProfileChanged); + } +