diff -r 7e41d162e158 -r abbed5a4b42a networkcontrol/ipscpr/src/deft_scpr.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/networkcontrol/ipscpr/src/deft_scpr.cpp Tue Aug 31 16:45:15 2010 +0300 @@ -0,0 +1,460 @@ +// Copyright (c) 2004-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: +// Implementation file for the IP SubConnection Provider +// +// + +/** + @file +*/ + +#include +#include +#include +#include "deft_scpr.h" +#include "ipscprlog.h" +#ifdef SYMBIAN_NETWORKING_UMTSR5 +#include "MAppIdInfo.h" +#include +#include +#endif //SYMBIAN_NETWORKING_UMTSR5 + +#ifdef SYMBIAN_NETWORKING_UMTSR5 + const TUint32 KSIPSecureId = 270490934; + const TUint32 KDHCPSecureId = 270522821; + const TUint32 KDNSSecureId = 268437634; +#endif //SYMBIAN_NETWORKING_UMTSR5 + +CEmptySubConnectionProvider::~CEmptySubConnectionProvider() + { + __IPCPRLOG(IpCprLog::Printf(_L("~CEmptySubConnectionProvider [this=%08x]"), this)); + if (iConnectionProvider) + { + iConnectionProvider->Leave(*this); + } + } + +void CEmptySubConnectionProvider::DoControlClientJoiningL(MSubConnectionControlClient& aControlClient) + { + (void)aControlClient; + __IPCPRLOG(IpCprLog::Printf(_L("CEmptySubConnectionProvider [this=%08x]:\tDoControlClientJoiningL() [iControlClients.Count=%d] [aControlClient=%08x]"), this, iControlClients.Count(), &aControlClient)); + } + +void CEmptySubConnectionProvider::DoControlClientLeaving(MSubConnectionControlClient& aControlClient) + { + (void)aControlClient; + __IPCPRLOG(IpCprLog::Printf(_L("CEmptySubConnectionProvider [this=%08x]:\tDoControlClientLeaving() [iControlClients.Count=%d] [aControlClient=%08x]"), this, iControlClients.Count(), &aControlClient)); + } + +void CEmptySubConnectionProvider::EnumerateClientsL(TUint& aCount, TDes8& aDes, CConnectionProviderBase::TEnumClients aClientType) + { + STypeId tid = STypeId::CreateSTypeId(KConnectionClientExtUid,EConnectionClientDesc); + TInt max = iControlClients.Count(); + for ( TInt n = 0; n < max; n++ ) + { + MConnectionClientDesc* intf = reinterpret_cast(iControlClients[n]->FetchInterfaceInstanceL(*this,tid)); + if ( intf ) + { + TConnectionProcessInfo cinfo; + cinfo.GetInfoL(aClientType,aCount, *intf, aDes); + } + } + STypeId tid2 = STypeId::CreateSTypeId(KConnectionClientExtUid,EConnectionEnumerateClients); + max = iDataClients.Count(); + for ( TInt n = 0; n < max; n++ ) + { + MConnectionEnumerateClients* intf = reinterpret_cast(iDataClients[n]->FetchInterfaceInstanceL(*this,tid2)); + if ( intf ) + { + intf->EnumerateClientsL(aCount,aDes,aClientType); + } + } + } + +void CEmptySubConnectionProvider::ConnectionError(TInt /*aStage*/, TInt aError) + {//it's comming from connection at the same level so forward it sideways + //with an origin EConnection + TInt max = iDataClients.Count(); + for ( TInt n = max - 1; n >= 0; n-- ) + { + iDataClients[n]->SubConnectionError(*this, MSubConnectionDataClient::EConnection, aError); + } + } + +MConnectionDataClient* CEmptySubConnectionProvider::DoSelfConnectionDataClient() + { + return this; + } + + +// Methods to be overriden be derived subconnection provider +void CDefaultSubConnectionProvider::DoControlClientJoiningL(MSubConnectionControlClient& aControlClient) + { + (void)aControlClient; + __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider::DoControlClientJoiningL [this=%08x]"), this)); + if (NULL != NextLayer()) + { + __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP exists - joined with provider"))); + } + else + { + __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP doesn't exists - not joined"))); + } + + } + +void CDefaultSubConnectionProvider::DoDataClientJoiningL(MSubConnectionDataClient& aDataClient) + { +#ifdef SYMBIAN_NETWORKING_UMTSR5 + // This piece of code is being added as per the requirements of PREQ 635 of dedicated PDP signalling + // context. When Primary PDP Context is created Network will return back the code saying whether it + // accepts the request to be dedicated signalling context or not. If Network decided to allow for dedicated + // signalling context then UmtsGprs SCPR add the information into the iParameterBundle of the UmtsGprsScpr + + // However, if the User doesnt do RSubConnection::SetParamter(EAttachDefault), which actually the user shouldn't do + // then we have to Get the parameter from the Next Layer, which again might or might not be UmtsGprs SubConnection Provider. + // Nevertheless if we call SetParameter() on iNextLayer then SetParameters across all the Layers below will get called, and + // since I knew that if any of the layer below is UmtsGprsSCpr, it will update the IMCN Signalling flag in the + // parameter Bundle which I will pass with the SetParameter() + + // We Initialize this variable everytime so that it can it can point to proper next layer + // everytime. Just a safety measure because it will anyway be initialised by the code written + // below + iSubConNextLayer = NULL; + if (NULL == iNextLayer) + { + // Find the Next Layer , otherwise iSubConNextLayer will be NULL by default. + CConnectionProviderBase* lowerConnectionProvider = iConnectionProvider->NextLayer(); + if (lowerConnectionProvider) + { + TUint nextLayerFactoryId = lowerConnectionProvider->CanDoSubConnection(RSubConnection::EAttachToDefault); + if (nextLayerFactoryId != 0) + { + TSockManData* sockManData = SockManGlobals::Get(); + CSubConnectionFactoryContainer* subConnectionFactories = sockManData->iSubConnectionFactories; + XSubConnectionFactoryQuery query(lowerConnectionProvider, RSubConnection::EAttachToDefault); + iSubConNextLayer = subConnectionFactories->FindOrCreateProviderL(nextLayerFactoryId, query); + } + + } + } + else + { + // We have a NextLayer, Point iSubConNextLayer to the same + iSubConNextLayer = iNextLayer; + } + + // Get The parameter Bundle for this SubConnectionProvider Instance. if Not available create one + // and Get the parameters from the Next Lyer + CSubConParameterBundle *tempBundle = NULL; + if (iSubConNextLayer != NULL) + { + tempBundle = iParameterBundle != NULL? iParameterBundle :CSubConParameterBundle::NewL(); + TRAP_IGNORE(iSubConNextLayer->SetParametersL(*tempBundle)); + } + + // Get the family if Available + CSubConParameterFamily *imcnFamily = tempBundle != NULL ? tempBundle->FindFamily(KSubConnContextDescrParamsFamily) : NULL; + if (imcnFamily) + { + // Find the family, Look for the IMCN value, using CSubConImsExtParamSet defined in Qos3gpp + CSubConImsExtParamSet *imcnSigParams = static_cast + (imcnFamily->FindExtensionSet(STypeId::CreateSTypeId(KSubConIPParamsUid,KSubConImsExtParamsType), + CSubConParameterFamily::EGranted)); + // If Family contains IMCN Signalling Parameters + if (imcnSigParams&& imcnSigParams->GetImsSignallingIndicator()) + { + // Check and Delete + if (tempBundle != iParameterBundle) + { + tempBundle->Close(); + tempBundle=NULL; + } + // Fetch the interface from the connection provider + STypeId typeID = STypeId::CreateSTypeId(KConnectionAppInfoInterfaceId,0); // IP Conenction provider factory Uid + TAny* intf = iConnectionProvider->FetchInterfaceInstanceL(typeID); + if (!intf) + { + // We are not able to get the AppSId so leaving + User::Leave(KErrNotSupported); + } + MConnectionAppIdInfo *appIdIP = static_cast(intf); + TUint32 appSecureId = appIdIP->GetAppSecureId(); + + // if socket is being opened by any application other than SIP, DHCP, and DNS we need to + // restrict the socket from being Created. + + + if ( ( appSecureId==KSIPSecureId || iAppId == KSIPSecureId) || + (appSecureId==KDHCPSecureId || iAppId == KDHCPSecureId) || + (appSecureId==KDNSSecureId || iAppId == KDNSSecureId) ) + { + aDataClient.JoinComplete(*this); + } + else + { + User::Leave(KErrPermissionDenied); + } + } // if (imcnSigParams&& imcnSigParams->GetImsSignallingIndicator()) + else + { + if (iConnectionProvider->IsLayerUp()) + { + aDataClient.JoinComplete(*this); + } + + } + } // if (imcnFamily) + // Check and Delete + if (tempBundle != iParameterBundle && tempBundle!=NULL) + { + tempBundle->Close(); + } +#else + + if (iConnectionProvider->IsLayerUp()) + { + aDataClient.JoinComplete(*this); + } +#endif // #ifdef SYMBIAN_NETWORKING_UMTSR5 + + } + +void CDefaultSubConnectionProvider::DoDataClientLeaving(MSubConnectionDataClient& aDataClient) + { + aDataClient.LeaveComplete(*this); + } + +void CDefaultSubConnectionProvider::DoSourceAddressUpdate(MSubConnectionDataClient& /*aDataClient*/, const TSockAddr& /*aSource*/) + { + } + +void CDefaultSubConnectionProvider::DoDestinationAddressUpdate(MSubConnectionDataClient& /*aDataClient*/, const TSockAddr& /*aDestination*/) + { + } + +void CDefaultSubConnectionProvider::DoDataClientRouted(MSubConnectionDataClient& /*aDataClient*/, const TSockAddr& /*aSource*/, const TSockAddr& /*aDestination*/, const TDesC8& /*aConnectionInfo*/) + { + } + +#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS +void CDefaultSubConnectionProvider::DoParametersAboutToBeSetL(CSubConParameterBundle& aParameterBundle) + { + __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider::DoParametersAboutToBeSetL [this=%08x]"), this)); + if (NULL != NextLayer()) + { + __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP exists - forwarding the request"))); + iNextLayer->SetParametersL(aParameterBundle); + } + else + { + __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP doesn't exists - the request not supported"))); + User::Leave(KErrNotSupported); + } + } + +#else +void CDefaultSubConnectionProvider::DoParametersAboutToBeSetL(CSubConParameterBundle& /*)aParameterBundle*/) + {//this could potentially fetch a current parameters from GuQoS and return them back as granted ones + User::Leave(KErrNotSupported); + } +#endif + +#ifdef SYMBIAN_NETWORKING_UMTSR5 +TInt CDefaultSubConnectionProvider::DoControl(TUint aOptionLevel, TUint /*aOptionName*/, TDes8& /*aOption*/) +#else +TInt CDefaultSubConnectionProvider::DoControl(TUint /*aOptionLevel*/, TUint /*aOptionName*/, TDes8& /*aOption*/) +#endif //#ifdef SYMBIAN_NETWORKING_UMTSR5 + { +#ifdef SYMBIAN_NETWORKING_UMTSR5 +//This control is used to send application secure ID of Active Connection. This Id +//will be used to for adding socket as data client to the subconnection. + iAppId=aOptionLevel; + return KErrNone; +#else + return KErrNotSupported; +#endif //#ifdef SYMBIAN_NETWORKING_UMTSR5 + } + +void CDefaultSubConnectionProvider::DoStartL() + { + __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider::DoStartL [this=%08x]"), this)); + } + +void CDefaultSubConnectionProvider::DoStop() + { + __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider::DoStop [this=%08x]"), this)); +#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS + if (iNextLayer) + { + __IPCPRLOG(IpCprLog::Printf(_L("Leaving Lower subconnection provider"))); + iNextLayer->Leave(*this); + iNextLayer = NULL; + } +#endif + } + +CSubConnectionProviderBase* CDefaultSubConnectionProvider::DoNextLayer() + { +#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS + __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider [this=%08x]:\tDoNextLayer()"), this)); + if (NULL == iNextLayer) + { + CConnectionProviderBase* lowerConnectionProvider = iConnectionProvider->NextLayer(); + if (!lowerConnectionProvider) + { + //This could denote the connection isn't started and perhaps should be from here, + // but since the selection isn't separated from startup, we don't have enough + // information to do it here. + __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider [this=%08x]:\tDoNextLayer() Connection Provider is missing its NextLayer"), this)); + return NULL; // No Lower layer,so leaving rhostresolver without connection. + } + + TUint nextLayerFactoryId = lowerConnectionProvider->CanDoSubConnection(RSubConnection::EAttachToDefault); + TRAP_IGNORE( + + if (nextLayerFactoryId != 0) + { + //'This' not started yet. The lower layer unknown + //This is as much as we can delay with resolving the subconnection stack + TSockManData* sockManData = SockManGlobals::Get(); + CSubConnectionFactoryContainer* subConnectionFactories = sockManData->iSubConnectionFactories; + + XSubConnectionFactoryQuery query(lowerConnectionProvider, RSubConnection::EAttachToDefault); + iNextLayer = subConnectionFactories->FindOrCreateProviderL(nextLayerFactoryId, query); + } + + if (iNextLayer) + { + __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP found.. Joining"))); + iNextLayer->JoinL(*this); + } + else + { + __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP not found.. Continuing"))); + } + ); + + } + + return iNextLayer; + +#else + __IPCPRLOG(IpCprLog::Printf(_L("Lower subconnection provider for IP not supported"))); + return NULL; +#endif +//SYMBIAN_NETWORKING_3GPPDEFAULTQOS + } + +CConnDataTransfer& CDefaultSubConnectionProvider::DoDataTransferL() + { + User::Leave(KErrNotSupported); + //unreachable code + return iNextLayer->DataTransferL(); + } + +//MConnectionDataClient +TAny* CDefaultSubConnectionProvider::FetchInterfaceInstanceL(CConnectionProviderBase& /*aProvider*/, const STypeId& aTid) + { + return (aTid == STypeId::CreateSTypeId(KConnectionClientExtUid,EConnectionEnumerateClients)) ? static_cast(this) : NULL; + } + +void CDefaultSubConnectionProvider::ConnectionGoingDown(CConnectionProviderBase& /*aConnProvider*/) + { + __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider [this=%08x]:\tConnectionGoingDown()"), this)); + iConnectionProvider = NULL; + DeleteMeNow(); + } + +void CDefaultSubConnectionProvider::Notify(MConnectionDataClient::TNotify aNotifyType, CConnectionProviderBase* /*aConnProvider*/, TInt aError, const CConNotificationEvent* /*aConNotificationEvent*/) + { + int count = iControlClients.Count(); + for (int i = count - 1; i >= 0; --i) + { + iControlClients[i]->SubConnectionEvent(*this, aNotifyType, aError, NULL); + } + if (aNotifyType == ENotifyLayerUp) + {//complete outstanding data client joins + TInt max = iDataClients.Count(); + for ( TInt n = max - 1; n >= 0; n-- ) + { + if (aError == KErrNone) + { + iDataClients[n]->JoinComplete(*this); + } + else + { + iDataClients[n]->JoinFailed(*this,aError); + } + } + } + } + +void CDefaultSubConnectionProvider::AttachToNext(CSubConnectionProviderBase* /*aSubConnProvider*/) + { + } + +CDefaultSubConnectionProvider::~CDefaultSubConnectionProvider () + { + __IPCPRLOG(IpCprLog::Printf(_L("~CDefaultSubConnectionProvider [this=%08x]"), this)); +#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS + if (iNextLayer) + { + iNextLayer->Leave (*this); + } +#endif + } + + +#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS +void CDefaultSubConnectionProvider::DoControlClientLeaving(MSubConnectionControlClient& aControlClient) + { + (void)aControlClient; + __IPCPRLOG(IpCprLog::Printf(_L("CDefaultSubConnectionProvider [this=%08x]:\tDoControlClientLeaving() [iControlClients.Count=%d] [aControlClient=%08x]"), this, iControlClients.Count(), &aControlClient)); + + // Note: control client count == 1 because the the client has not been removed yet + if (iNextLayer && iControlClients.Count() == 1 && iDataClients.Count() == 0) + { + iNextLayer->Leave (*this); + iNextLayer = NULL; + } + } + +void CDefaultSubConnectionProvider::SubConnectionEvent(CSubConnectionProviderBase& /*aSubConnProvider*/, MConnectionDataClient::TNotify /*aNotifyType*/, TInt /*aError*/, const CSubConNotificationEvent* aEvent) + { + NotifyClientEvent(*aEvent); + } + + +void CDefaultSubConnectionProvider::SubConnectionGoingDown(CSubConnectionProviderBase& /*aSubConnProvider*/) + { + TInt max = iControlClients.Count(); + for ( TInt n = max - 1; n >= 0; n-- ) + { + iControlClients[n]->SubConnectionGoingDown(*this); + } + } + + +void CDefaultSubConnectionProvider::LayerUp(CSubConnectionProviderBase& /*aSubConnProvider*/, TInt /*aError*/) + { + } + +void CDefaultSubConnectionProvider::IncomingConnection(CSubConnectionProviderBase* /*aSubConnProvider*/, CSubConParameterBundle* /*aParameterBundle*/, TInt /*aError*/) + { + } + +#endif +// SYMBIAN_NETWORKING_3GPPDEFAULTQOS +