diff -r bb2423252ea3 -r c1029e558ef5 linklayerprotocols/tundriver/src/tundriverflow.cpp --- a/linklayerprotocols/tundriver/src/tundriverflow.cpp Wed Sep 15 13:53:10 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,510 +0,0 @@ -/** -* Copyright (c) 2010 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: -* Flow implementation for data path for tunnel driver. -* -* -*/ - -/** - @file tundriverflow.cpp - @internalTechnology -*/ - -#include -#include -#include -#include -#include - -#include "ss_subconnflow.h" -#include -#include "tundriverflow.h" -#include "tundriverbinder.h" -#include "tundriverprovision.h" - -using namespace Messages; -using namespace MeshMachine; -using namespace ESock; - -#ifdef SYMBIAN_TRACE_ENABLE -_LIT8(KNif,"tundriver"); -#endif - -CTunDriverSubConnectionFlowFactory* CTunDriverSubConnectionFlowFactory::NewL(TAny* aConstructionParameters) -/** -* CTunDriverSubConnectionFlowFactory::NewL constructs a Default SubConnection Flow Factory -* @param aConstructionParameters construction data passed by ECOM -* @returns pointer to a constructed factory object. -*/ - { - CTunDriverSubConnectionFlowFactory* ptr = new (ELeave) CTunDriverSubConnectionFlowFactory(TUid::Uid(KTunDriverFlowImplementationUid), *(reinterpret_cast(aConstructionParameters))); - return ptr; - } - - -CTunDriverSubConnectionFlowFactory::CTunDriverSubConnectionFlowFactory(TUid aFactoryId, CSubConnectionFlowFactoryContainer& aParentContainer) -: CSubConnectionFlowFactoryBase(aFactoryId, aParentContainer) -/** -* CTunDriverSubConnectionFlowFactory::CTunDriverSubConnectionFlowFactory is a Default SubConnection Flow Factory -* @param aFactoryId ECOM Implementation Id -* @param aParentContainer Object Owner -*/ - { - } - -CSubConnectionFlowBase* CTunDriverSubConnectionFlowFactory::DoCreateFlowL(CProtocolIntfBase* aProtocolIntf, TFactoryQueryBase& aQuery) -/** -* CTunDriverSubConnectionFlowFactory::DoCreateFlowL will create SubConnection Flow. -* @param aFactoryId ECOM Implementation Id -* @param aParentContainer Object Owner -*/ - { - const TDefaultFlowFactoryQuery& query = static_cast(aQuery); - return CTunDriverSubConnectionFlow::NewL(*this, query.iSCprId, aProtocolIntf); - } - -CTunDriverSubConnectionFlow::CTunDriverSubConnectionFlow(CSubConnectionFlowFactoryBase& aFactory, const TNodeId& aSubConnId, CProtocolIntfBase* aProtocolIntf) -: CSubConnectionFlowBase(aFactory, aSubConnId, aProtocolIntf) -/** -* CTunDriverSubConnectionFlow::CTunDriverSubConnectionFlow is a Default Constructor -* @param aFactoryId ECOM Implementation Id -* @param aParentContainer Object Owner -*/ - { - __FLOG_OPEN(KCFNodeTag, KNif); - LOG_NODE_CREATE(KNif, CTunDriverSubConnectionFlow); - } - -CTunDriverSubConnectionFlow::~CTunDriverSubConnectionFlow() -/** -* CTunDriverSubConnectionFlowFactory::~CTunDriverSubConnectionFlow is a Default destructor -* @param aFactoryId ECOM Implementation Id -* @param aParentContainer Object Owner -*/ - { - delete iBinder4; - iBinder4 = NULL; -#ifdef IPV6SUPPORT - delete iBinder6; - iBinder6 = NULL; -#endif - LOG_NODE_DESTROY(KNif, CTunDriverSubConnectionFlow); - __FLOG_CLOSE; - } - -CTunDriverSubConnectionFlow* CTunDriverSubConnectionFlow::NewL(CSubConnectionFlowFactoryBase& aFactory, const TNodeId& aSubConnId, CProtocolIntfBase* aProtocolIntf) -/** -* CTunDriverSubConnectionFlowFactory::NewL is a first phase Constructor. -* @param aFactoryId ECOM Implementation Id -* @param aParentContainer Object Owner -*/ - { - CTunDriverSubConnectionFlow* flow = new (ELeave) CTunDriverSubConnectionFlow(aFactory, aSubConnId, aProtocolIntf); - return flow; - } - -void CTunDriverSubConnectionFlow::FlowDown(TInt aError, TInt aAction /*= MNifIfNotify::EDisconnect*/) -/** -* CTunDriverSubConnectionFlowFactory::FlowDown will post the message. -* @param aError obtained from the upper CF Layer. -* @param aAction and the action message for aError. -*/ - { - PostFlowDownMessage(aError, aAction); - } - -void CTunDriverSubConnectionFlow::Progress(TInt aStage, TInt aError) -/** -* CTunDriverSubConnectionFlowFactory::Progress Binder requesting a Progress() message be sent to SCPR -* @param aStage and the action message for aError. -* @param aError obtained from the upper CF Layer. -*/ - { - PostProgressMessage(aStage, aError); - } - -const TTunDriverIp4Provision* CTunDriverSubConnectionFlow::Ip4Provision() const -/** -* CTunDriverSubConnectionFlowFactory::Ip4Provision -* @param -* @return iIp4Provision. -*/ - { - ASSERT(iProvision); - return &iProvision->iIp4Provision; - } - -#ifdef IPV6SUPPORT -const TTunDriverIp6Provision* CTunDriverSubConnectionFlow::Ip6Provision() const -/** -* CTunDriverSubConnectionFlowFactory::Ip6Provision -* @param -* @return iIp6Provision. -*/ - { - ASSERT(iProvision); - return &iProvision->iIp6Provision; - } -#endif - -//-========================================================= -// Messages::ANode methods -//-========================================================= - -#define __FRAMEWORK_PRODUCTION_ERRORHANDLING(c,p) (void)((c)||(p,0)) -void CTunDriverSubConnectionFlow::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage) -/** -* CTunDriverSubConnectionFlowFactory::ReceivedL called on incoming SCPR Messages. -* CTunDriverSubConnectionFlow functions will be called Based on message type -* @param aCFMessage message base -*/ - { - #ifdef __FLOG_ACTIVE - TAny* senderAddr = NULL; - const TNodeId* senderNodeId = address_cast(&aSender); - __ASSERT_DEBUG(senderNodeId!=NULL,User::LeaveIfError(KErrCorrupt)); - senderAddr = senderNodeId->Ptr(); - __FLOG_4(_L8("CTunDriverSubConnectionFlow(%x):\tReceivedL() Sender Id: %x, Msg Realm: %X, Msg ID: %d"), this, senderAddr, aMessage.MessageId().Realm(), aMessage.MessageId().MessageId()); - #endif - - CSubConnectionFlowBase::ReceivedL(aSender, aRecipient, aMessage); - if (aMessage.IsMessage()) - { - SubConnectionError(static_cast(aMessage).iValue); - } - else if (TEChild::ERealmId == aMessage.MessageId().Realm()) - { - switch (aMessage.MessageId().MessageId()) - { - case TEChild::TCancel::EId: - CancelFlow(KErrCancel); - case TEChild::TDestroy::EId : - Destroy(); - break; - default: - ASSERT(EFalse); - } - } - else if (TCFDataClient::ERealmId == aMessage.MessageId().Realm()) - { - switch (aMessage.MessageId().MessageId()) - { - case TCFDataClient::TStart::EId : - StartFlowL(); - break; - case TCFDataClient::TStop::EId : - StopFlow(static_cast(aMessage).iValue); - break; - case TCFDataClient::TProvisionConfig::EId: - ProvisionConfig(static_cast(aMessage).iConfig); - break; - case TCFDataClient::TBindTo::EId: - { - TCFDataClient::TBindTo& bindToReq = message_cast(aMessage); - __FRAMEWORK_PRODUCTION_ERRORHANDLING(bindToReq.iNodeId.IsNull(),User::LeaveIfError(KErrNotSupported)); - RClientInterface::OpenPostMessageClose(Id(), aSender, TCFDataClient::TBindToComplete().CRef()); - } - break; - default: - ASSERT(EFalse); - } - } - else - { - User::Leave(KErrNotSupported); - } - } - -void CTunDriverSubConnectionFlow::StartFlowL() -/** -* CTunDriverSubConnectionFlowFactory::StartFlowL starts the flow on receiving the message TStart. -* This function is called from CTunDriverSubConnectionFlowFactory::ReceivedL -*/ - { - __FLOG(_L8("CTunDriverSubConnectionFlow:\tStartFlowL()")); - - if(iMMState == EStarted) - { - //Flow can be started multiple times. - //For example a start may fail on an upper layer in which case the upper layer will not be able - //to stop our layer and we need to accept start again. - PostProgressMessage(KLinkLayerOpen, KErrNone); - PostDataClientStartedMessage(); - return; - } - iMMState = EStarted; - - // If the processing of the ProvisionConfig message failed earlier, send the error response - // here to the StartFlow message as there is no response to ProvisionConfig. - User::LeaveIfError(iSavedError); - - PostProgressMessage(KLinkLayerOpen, KErrNone); - PostDataClientStartedMessage(); - iBinder4->StartSending(); -#ifdef IPV6SUPPORT - if(iBinder6) - { - iBinder6->StartSending(); - } -#endif - } - -void CTunDriverSubConnectionFlow::CancelFlow(TInt aError) -/** -* CTunDriverSubConnectionFlowFactory::CancelFlow cancels the flow on receiving the message TCancel. -* It will post the message as KErrCancel. -* This function is called from CTunDriverSubConnectionFlowFactory::ReceivedL -*/ - { - __FLOG_1(_L8("CTunDriverSubConnectionFlow:\tCancelFlow(%d)"), aError); - - if(iMMState == EStarted) - { - PostFlowDownMessage(aError); - } - } - -void CTunDriverSubConnectionFlow::StopFlow(TInt aError) -/** -* CTunDriverSubConnectionFlowFactory::StopFlow stops the flow on receiving the message TStop. -* It will post the message as KLinkLayerClosed and KErrCancel. -* This function is called from CTunDriverSubConnectionFlowFactory::ReceivedL -*/ - { - __FLOG_1(_L8("CTunDriverSubConnectionFlow:\tStopFlow(%d)"), aError); - - PostProgressMessage(KLinkLayerClosed, aError); - iMMState = EStopped; - PostFlowDownMessage(aError); - } - -void CTunDriverSubConnectionFlow::ProvisionConfig(const ESock::RMetaExtensionContainerC& aConfigData) -/** -* CTunDriverSubConnectionFlowFactory::Provisionconfig on receipt of the ProvisionConfig message, the pointer contained within it is stored -* in iAccessPointConfig and the information contained within the iAccessPointConfig array is validated: -* CTunDriverProtoProvision must be present. It is added by the TunDriverMCPr and populated from CommsDat. -* It is a 'C' class to take advantage of zero initialisation. -* Any errors are saved in iSavedError - there is no response to ProvisionConfig, -* so an error response is sent later to StartFlow message. -* -* on receipt of TCFDataClient::TStart: -* iSavedError is checked and, if non-zero, an Error message is sent to the SCPr -* TunDriverAgentProvision must be present. It is added by the TunDriverAgentHandler and populated via calls -* to the Agent. It is a 'T' class because it requires no zero initialisation. If missing, -* an Error message is signalled to the SCPr. -* This function is called from CTunDriverSubConnectionFlowFactory::ReceivedL -* @param aData pointer to provisioning structure -*/ - { - __FLOG_0(_L8("CTunDriverSubConnectionFlow:\tProvisionConfig message received")); - iSavedError = KErrNone; - iAccessPointConfig.Close(); - iAccessPointConfig.Open(aConfigData); - - const CTunDriverProtoProvision* provision = static_cast(AccessPointConfig().FindExtension( - STypeId::CreateSTypeId(CTunDriverProtoProvision::EUid, CTunDriverProtoProvision::ETypeId))); - __FRAMEWORK_PRODUCTION_ERRORHANDLING(provision!=NULL,iSavedError = KErrCorrupt); - - iProvision = provision; - } - -void CTunDriverSubConnectionFlow::Destroy() -/** -* CTunDriverSubConnectionFlowFactory::Destroy -* Request from SCPR to destroy -* This function is called from CTunDriverSubConnectionFlowFactory::ReceivedL -*/ - { - DeleteThisFlow(); - } - -void CTunDriverSubConnectionFlow::SubConnectionGoingDown() -/** -* CTunDriverSubConnectionFlowFactory::SubConnectionGoingDown -* Request from Agemt SCPR -*/ - { - __FLOG(_L8("CTunDriverSubConnectionFlow:\tSubConnectionGoingDown")); - } - -void CTunDriverSubConnectionFlow::SubConnectionError(TInt /*aError*/) -/** -* CTunDriverSubConnectionFlowFactory::SubConnectionError -* Request from Agemt SCPR -*/ - { - __FLOG(_L8("CTunDriverSubConnectionFlow:\tSubConnectionError")); - } - -MFlowBinderControl* CTunDriverSubConnectionFlow::DoGetBinderControlL() -/** -* CTunDriverSubConnectionFlowFactory::DoGetBinderControlL Called by upper layer for binding -* Request from Agemt SCPR -* @return MFlowBinderControl instance -*/ - { - __FLOG(_L8("CTunDriverSubConnectionFlow::DoGetBinderControlL")); - return this; - } - -//-========================================================= -// MFlowBinderControl methods -// - -MLowerControl* CTunDriverSubConnectionFlow::GetControlL(const TDesC8& aProtocol) -/** -* CTunDriverSubConnectionFlow::GetControlL -* Create and return an MLowerControl instance of the specified binder type. -* Called from upper layer during binding procedure. -* @param aProtocol Protocol type of the binder -* @return MLowerControl instance of the protocol type -*/ - { - MLowerControl* lowerControl = NULL; - __FLOG(_L8("CTunDriverSubConnectionFlow:\tGetLowerControlL(KProtocol4)")); - if(aProtocol.Compare(KProtocol4()) == 0) - { - iBinder4 = CTunDriverBinder4::NewL(*this); - lowerControl = iBinder4; - } -#ifdef IPV6SUPPORT - else - if (aProtocol.CompareF(KProtocol6()) == 0) - { - __FLOG(_L8("CTunDriverSubConnectionFlow::GetLowerControlL(KProtocol6)- Should Return KErrNotSupported")); - iBinder6 = CTunDriverBinder6::NewL(*this); - lowerControl = iBinder6; - } -#endif - return lowerControl; - } - -MLowerDataSender* CTunDriverSubConnectionFlow::BindL(const TDesC8& aProtocol, MUpperDataReceiver* aReceiver, MUpperControl* aControl) -/** -* CTunDriverSubConnectionFlow::BindL Create and return an MLowerDataSender instance of the specified protocol type. -* This is bound to the specified upper layer objects. -* Called from upper layer to bind to this layer. -* @param aProtocol Protocol type of the binder (same as in GetControlL()) -* @param aReceiver upper layer's MUpperDataReceiver instance for this binder to associate with -* @param aControl upper layer's MUpperControl instance for this binder to associate with -* @return MLowerDataSender instance -*/ - { - __FLOG(_L8("CTunDriverSubConnectionFlow:\tBindL()")); - - MLowerDataSender* lowerDataSender = NULL; - - if(aProtocol.CompareF(KProtocol4()) == 0) - { - lowerDataSender = iBinder4->Bind(*aReceiver, *aControl); - } -#ifdef IPV6SUPPORT - else - if (aProtocol.CompareF(KProtocol6()) == 0) - { - lowerDataSender = iBinder6->Bind(*aReceiver, *aControl); - } -#endif - if(lowerDataSender != NULL) - { - iSubConnectionProvider.PostMessage(Id(), TCFControlProvider::TActive().CRef()); - } - return lowerDataSender; - } - -void CTunDriverSubConnectionFlow::Unbind(MUpperDataReceiver* aReceiver, MUpperControl* aControl) -/** -* CTunDriverSubConnectionFlow::Unbind will Unbind from the upper layer. -* Called from the upper layer during unbinding. -* @param aReceiver -* @param aControl -*/ - { - __FLOG(_L8("CTunDriverSubConnectionFlow:\tUnbind()")); - if (iBinder4 && iBinder4->MatchesUpperControl(aControl)) - { - iBinder4->Unbind(*aReceiver, *aControl); - delete iBinder4; - iBinder4 = NULL; - } -#ifdef IPV6SUPPORT - if (iBinder6 && iBinder6->MatchesUpperControl(aControl)) - { - iBinder6->Unbind(*aReceiver, *aControl); - delete iBinder6; - iBinder6 = NULL; - } -#endif - iSubConnectionProvider.PostMessage(Id(), TCFControlProvider::TIdle().CRef()); - } - -ESock::CSubConnectionFlowBase* CTunDriverSubConnectionFlow::Flow() -/** -* CTunDriverSubConnectionFlow::Flow will Return the flow object corresponding to the MFlowBinderControl -* Called from the UpperLayer get the instance of the flow. -*/ - { - return this; - } - -void CTunDriverSubConnectionFlow::PostProgressMessage(TInt aStage, TInt aError) -/* -* CTunDriverSubConnectionFlow::PostProgressMessage will send the state change message with the param values. -* -*/ - { - iSubConnectionProvider.PostMessage(Id(), TCFMessage::TStateChange(Elements::TStateChange(aStage, aError)).CRef()); - } - -void CTunDriverSubConnectionFlow::PostDataClientStartedMessage() -/* -* CTunDriverSubConnectionFlow::PostDataClientStartedMessage will send the started message with the param values. -*/ - { - iLastRequestOriginator.ReplyTo(Id(), TCFDataClient::TStarted().CRef()); - } - -void CTunDriverSubConnectionFlow::PostFlowDownMessage(TInt aError, TInt aAction /*= MNifIfNotify::EDisconnect*/) -/* -* CTunDriverSubConnectionFlow::PostFlowDownMessage will send the DataClient Down message with the param values. -*/ - { - if (iMMState == EStarted) - { - iMMState = EStopped; - iSubConnectionProvider.PostMessage(Id(), TCFControlProvider::TDataClientGoneDown(aError, aAction).CRef()); - } - else - { - iLastRequestOriginator.ReplyTo(Id(), TCFDataClient::TStopped(aError).CRef()); - } - } - -void CTunDriverSubConnectionFlow::MaybePostDataClientIdle() -/* -* CTunDriverSubConnectionFlow::MaybePostDataClientIdle will send the Idle message with the param values. -*/ - { - // Can only send DataClientIdle when the upper layer has unbound and the flow is stopped - if( iBinder4 == NULL -#ifdef IPV6SUPPORT - || iBinder6 == NULL -#endif - ) - { - iSubConnectionProvider.PostMessage(Id(), TCFControlProvider::TIdle().CRef()); - } - } -