diff -r 9ddb1d67ebaf -r 9644881fedd0 datacommsserver/esockserver/test/providers/dummy/src/dummypr_flow.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/datacommsserver/esockserver/test/providers/dummy/src/dummypr_flow.cpp Tue May 25 14:00:39 2010 +0300 @@ -0,0 +1,439 @@ +// Copyright (c) 2008-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: +// Dummy implementation file for network tier flow +// +// + +/** + @file + @internalComponent +*/ + + +#include +#include +#include +#include +#include +#include "dummypr_flow.h" + + +#ifdef _DEBUG +// Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module +// (if it could happen through user error then you should give it an explicit, documented, category + code) +_LIT(KSpecAssert_ESockTestdmyprnt, "ESockTestdmyprnt"); +#endif + +using namespace ESock; +using namespace Messages; + + + + +// Construction +//------------- +CDummyFlow* CDummyFlow::NewL(CSubConnectionFlowFactoryBase& aFactory, const Messages::TNodeId& aSubConn, CProtocolIntfBase* aProtocolIntf) + { + CDummyFlow* self = new (ELeave) CDummyFlow(aFactory, aSubConn, aProtocolIntf); + return self; + } + +CDummyFlow::CDummyFlow(CSubConnectionFlowFactoryBase& aFactory, const Messages::TNodeId& aSubConn, CProtocolIntfBase* aProtocolIntf) +: CSubConnectionFlowBase(aFactory, aSubConn, aProtocolIntf) + { + LOG_NODE_CREATE(KESockFlowTag, CDummyFlow) + } + +CDummyFlow::~CDummyFlow() + { + LOG_NODE_DESTROY(KESockFlowTag, CDummyFlow) + } + +MSessionControl* CDummyFlow::GetControlL( + TInt /*aSessionType*/, + MSessionControlNotify& aSessionControlNotify) + { + // Apply binding locally + __ASSERT_DEBUG(iSessionControlNotify == NULL, User::Panic(KSpecAssert_ESockTestdmyprnt, 1)); + iSessionControlNotify = &aSessionControlNotify; + + return this; + } + +MSessionData* CDummyFlow::BindL(MSessionDataNotify& aNotify) + { + LOG( ESockLog::Printf(_L8("CDummyFlow %08x:\tBindL(aNotify 0x%08x)"), this, &aNotify) ); + + // Apply binding locally + __ASSERT_DEBUG(iSessionDataNotify == NULL, User::Panic(KSpecAssert_ESockTestdmyprnt, 3)); + iSessionDataNotify = &aNotify; + iSubConnectionProvider.RNodeInterface::PostMessage( + Id(), + TCFControlProvider::TActive().CRef()); + return this; + } + +void CDummyFlow::Unbind() + { + LOG( ESockLog::Printf(_L8("CDummyFlow %08x:\tUnbind()"), this) ); + ASSERT(iSessionDataNotify); //who else is it calling then? + + iSessionControlNotify = NULL; + iSessionDataNotify = NULL; + + ASSERT(iSubConnectionProvider.IsOpen()); + iSubConnectionProvider.RNodeInterface::PostMessage( + Id(), + TCFControlProvider::TIdle().CRef() + ); + } + +ESock::CSubConnectionFlowBase& CDummyFlow::CloneFlowL() + { + TDefaultFlowFactoryQuery query (iProtocolIntf->ControlProviderId(), iSubConnectionProvider.RecipientId()); + + ESock::CSubConnectionFlowBase& flow = static_cast(*(Factory().CreateObjectL(query))); + + // Have the new flow become a data client of our subconnection too + __ASSERT_DEBUG(iSubConnectionProvider.IsOpen(), User::Panic(KSpecAssert_ESockTestdmyprnt, 6)); + TCFPeer::TJoinRequest msg( + flow.Id(), + TCFClientType(TCFClientType::EData, TCFClientType::EActive) + ); + + iSubConnectionProvider.PostMessage(Id(), msg); + + return flow; + } + +CSubConnectionFlowBase* CDummyFlow::Flow() + { + return this; + } + + +// MSessionControl +//---------------- +void CDummyFlow::Start() + {/*__ASSERT_DEBUG(iLowerFlowControl, User::Panic(KSpecAssert_ESockTestdmyprnt, 7)); return iLowerFlowControl->Start()*/;} + +void CDummyFlow::LocalName(TSockAddr& anAddr) const + {__ASSERT_DEBUG(iLowerFlowControl, User::Panic(KSpecAssert_ESockTestdmyprnt, 8)); return iLowerFlowControl->LocalName(anAddr);} + +void CDummyFlow::SetLocalName(TSockAddr& /*anAddr*/) + { + // Fetch the current flow parameters (those that were sent to us) and create a new set for the flow we want + TFlowParams flowParams; + flowParams.iProtocol = CDummyFlow::EProtocolId; + flowParams.iSocketType = KSockDatagram; + + // Create and load a parameter set with the flow parameters that form our binder request + CFlowRequestParameters* paramSet = CFlowRequestParameters::NewL(); + CleanupStack::PushL(paramSet); + paramSet->SetFlowParams(flowParams); + RCFParameterFamilyBundle flowParamsBundle; + flowParamsBundle.CreateL(); + RParameterFamily family = flowParamsBundle.CreateFamilyL(KFlowParametersFamily); + family.AddParameterSetL(paramSet, RParameterFamily::ERequested); + + iParamBundle.Open(flowParamsBundle); + // Construct and send the message + iSubConnectionProvider.RNodeInterface::PostMessage( + Id(), + TCFControlProvider::TNoBearer(iParamBundle).CRef() + ); + + CleanupStack::Pop(paramSet); + } + +void CDummyFlow::RemName(TSockAddr& anAddr) const + {__ASSERT_DEBUG(iLowerFlowControl, User::Panic(KSpecAssert_ESockTestdmyprnt, 10)); iLowerFlowControl->RemName(anAddr);} + +TInt CDummyFlow::SetRemName(TSockAddr& anAddr) + {__ASSERT_DEBUG(iLowerFlowControl, User::Panic(KSpecAssert_ESockTestdmyprnt, 11)); return iLowerFlowControl->SetRemName(anAddr);} + +const TInt KDummyNetworkFlowOptionLevel = CDummyFlowFactory::iUid; +const TInt KFlowProtocolName = 1; + +TInt CDummyFlow::GetOption(TUint aLevel, TUint aName, TDes8& anOption) const + { + __ASSERT_DEBUG(iLowerFlowControl, User::Panic(KSpecAssert_ESockTestdmyprnt, 12)); + + if(aLevel == KDummyNetworkFlowOptionLevel && aName == KFlowProtocolName) + { + anOption.Copy(KDummyProtocolName); + return KErrNone; + } + else + { + return iLowerFlowControl->GetOption(aLevel, aName, anOption); + } + } + +void CDummyFlow::Ioctl(TUint aLevel, TUint aName, TDes8* anOption) + {__ASSERT_DEBUG(iLowerFlowControl, User::Panic(KSpecAssert_ESockTestdmyprnt, 13)); iLowerFlowControl->Ioctl(aLevel, aName, anOption);} + +void CDummyFlow::CancelIoctl(TUint aLevel, TUint aName) + {__ASSERT_DEBUG(iLowerFlowControl, User::Panic(KSpecAssert_ESockTestdmyprnt, 14)); iLowerFlowControl->CancelIoctl(aLevel, aName);} + +TInt CDummyFlow::SetOption(TUint /*aLevel*/, TUint /*aName*/, const TDesC8 &/*anOption*/) + { return KErrNone; } + +void CDummyFlow::ActiveOpen() + {__ASSERT_DEBUG(iLowerFlowControl, User::Panic(KSpecAssert_ESockTestdmyprnt, 16)); iLowerFlowControl->ActiveOpen();} + +void CDummyFlow::ActiveOpen(const TDesC8& aConnectionData) + {__ASSERT_DEBUG(iLowerFlowControl, User::Panic(KSpecAssert_ESockTestdmyprnt, 17)); iLowerFlowControl->ActiveOpen(aConnectionData);} + +TInt CDummyFlow::PassiveOpen(TUint aQueueSize) + {__ASSERT_DEBUG(iLowerFlowControl, User::Panic(KSpecAssert_ESockTestdmyprnt, 18)); return iLowerFlowControl->PassiveOpen(aQueueSize);} + +TInt CDummyFlow::PassiveOpen(TUint aQueueSize, const TDesC8& aConnectionData) + {__ASSERT_DEBUG(iLowerFlowControl, User::Panic(KSpecAssert_ESockTestdmyprnt, 19)); return iLowerFlowControl->PassiveOpen(aQueueSize, aConnectionData);} + +void CDummyFlow::Shutdown(MSessionControl::TCloseType aOption) + { + if (iLowerFlowControl) + { + iLowerFlowControl->Shutdown(aOption); + } + else + { + iSessionControlNotify->CanClose(MSessionControlNotify::EDelete); + } + } + +void CDummyFlow::Shutdown(MSessionControl::TCloseType aOption, const TDesC8& aDisconnectionData) + {__ASSERT_DEBUG(iLowerFlowControl, User::Panic(KSpecAssert_ESockTestdmyprnt, 21)); iLowerFlowControl->Shutdown(aOption, aDisconnectionData);} + +void CDummyFlow::AutoBind() + {__ASSERT_DEBUG(iLowerFlowControl, User::Panic(KSpecAssert_ESockTestdmyprnt, 22)); iLowerFlowControl->AutoBind();} + +TInt CDummyFlow::SecurityCheck(MProvdSecurityChecker* /*aChecker*/) + { return KErrNone;} + + +// MSessionData +//------------- +TUint CDummyFlow::Write(const TDesC8& aDesc, TUint aOptions, TSockAddr* anAddr) + {__ASSERT_DEBUG(iLowerFlowData, User::Panic(KSpecAssert_ESockTestdmyprnt, 24)); return iLowerFlowData->Write(aDesc, aOptions, anAddr);} + +TInt CDummyFlow::Write(RMBufChain& aData, TUint aOptions, TSockAddr* anAddr) + {__ASSERT_DEBUG(iLowerFlowData, User::Panic(KSpecAssert_ESockTestdmyprnt, 25)); return iLowerFlowData->Write(aData, aOptions, anAddr);} + +void CDummyFlow::GetData(TDes8& aDesc, TUint aOptions, TSockAddr* anAddr) + {__ASSERT_DEBUG(iLowerFlowData, User::Panic(KSpecAssert_ESockTestdmyprnt, 26)); iLowerFlowData->GetData(aDesc, aOptions, anAddr);} + +TInt CDummyFlow::GetData(RMBufChain& aData, TUint aLength, TUint aOptions, TSockAddr* anAddr) + {__ASSERT_DEBUG(iLowerFlowData, User::Panic(KSpecAssert_ESockTestdmyprnt, 27)); return iLowerFlowData->GetData(aData, aLength, aOptions, anAddr);} + + +// MSessionControlNotify +//---------------------- +void CDummyFlow::ConnectComplete() + {__ASSERT_DEBUG(iSessionControlNotify, User::Panic(KSpecAssert_ESockTestdmyprnt, 28)); iSessionControlNotify->ConnectComplete();} + +void CDummyFlow::ConnectComplete(const TDesC8& aConnectData) + {__ASSERT_DEBUG(iSessionControlNotify, User::Panic(KSpecAssert_ESockTestdmyprnt, 29)); iSessionControlNotify->ConnectComplete(aConnectData);} + +void CDummyFlow::ConnectComplete(CSubConnectionFlowBase& anSSP) + {__ASSERT_DEBUG(iSessionControlNotify, User::Panic(KSpecAssert_ESockTestdmyprnt, 30)); iSessionControlNotify->ConnectComplete(anSSP);} + +void CDummyFlow::ConnectComplete(CSubConnectionFlowBase& anSSP,const TDesC8& aConnectData) + {__ASSERT_DEBUG(iSessionControlNotify, User::Panic(KSpecAssert_ESockTestdmyprnt, 31)); iSessionControlNotify->ConnectComplete(anSSP, aConnectData);} + +void CDummyFlow::CanClose(MSessionControlNotify::TDelete aDelete) + {__ASSERT_DEBUG(iSessionControlNotify, User::Panic(KSpecAssert_ESockTestdmyprnt, 32)); iSessionControlNotify->CanClose(aDelete);} + +void CDummyFlow::CanClose( + const TDesC8& aDisconnectData, + MSessionControlNotify::TDelete aDelete) + {__ASSERT_DEBUG(iSessionControlNotify, User::Panic(KSpecAssert_ESockTestdmyprnt, 33)); iSessionControlNotify->CanClose(aDisconnectData, aDelete);} + +TInt CDummyFlow::Error(TInt anError,TUint anOperationMask) + {__ASSERT_DEBUG(iSessionControlNotify, User::Panic(KSpecAssert_ESockTestdmyprnt, 34)); return iSessionControlNotify->Error(anError, anOperationMask);} + +void CDummyFlow::Disconnect() + {__ASSERT_DEBUG(iSessionControlNotify, User::Panic(KSpecAssert_ESockTestdmyprnt, 35)); iSessionControlNotify->Disconnect();} + +void CDummyFlow::Disconnect(TDesC8& aDisconnectData) + {__ASSERT_DEBUG(iSessionControlNotify, User::Panic(KSpecAssert_ESockTestdmyprnt, 36)); iSessionControlNotify->Disconnect(aDisconnectData);} + +void CDummyFlow::IoctlComplete(TDesC8* aBuf) + {__ASSERT_DEBUG(iSessionControlNotify, User::Panic(KSpecAssert_ESockTestdmyprnt, 37)); iSessionControlNotify->IoctlComplete(aBuf);} + +void CDummyFlow::DisconnectFromListener(CSubConnectionFlowBase& aSSP) + { + __ASSERT_DEBUG(iSessionControlNotify, User::Panic(KSpecAssert_ESockTestdmyprnt, 53)); + iSessionControlNotify->DisconnectFromListener(aSSP); + } +void CDummyFlow::SetLocalNameComplete() + { + __ASSERT_DEBUG(iSessionControlNotify, User::Panic(KSpecAssert_ESockTestdmyprnt, 52)); + iSessionControlNotify->SetLocalNameComplete(); + } + +// MSessionDataNotify +//------------------- +void CDummyFlow::NewData(TUint aCount) + {__ASSERT_DEBUG(iSessionDataNotify, User::Panic(KSpecAssert_ESockTestdmyprnt, 39)); iSessionDataNotify->NewData(aCount);} + +void CDummyFlow::CanSend() + {__ASSERT_DEBUG(iSessionDataNotify, User::Panic(KSpecAssert_ESockTestdmyprnt, 40)); iSessionDataNotify->CanSend();} + +MFlowBinderControl* CDummyFlow::DoGetBinderControlL() + { + return this; + } + + +// Node stuff +//----------- +void CDummyFlow::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage) + { + CSubConnectionFlowBase::ReceivedL(aSender, aRecipient, aMessage); + TInt err = KErrNone; + + if ( aMessage.IsMessage() ) + { + ASSERT(EFalse); //To be implemented + } + else if ( aMessage.IsMessage() ) + { + } + else if (aMessage.IsMessage()) + { + } + else if (TEChild::ERealmId == aMessage.MessageId().Realm()) + { + switch (aMessage.MessageId().MessageId()) + { + case TEChild::TDestroy::EId : + DeleteThisFlow(); + break; + default: + __ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockTestdmyprnt, 41)); //For debug configurations + User::Leave(KErrNotSupported); //For release configurations + } + } + else if (TCFDataClient::ERealmId == aMessage.MessageId().Realm()) + { + switch (aMessage.MessageId().MessageId()) + { + case TCFDataClient::TStart::EId : + iSubConnectionProvider.PostMessage(Id(), TCFDataClient::TStarted().CRef()); + break; + case TCFDataClient::TStop::EId : + iParamBundle.Close(); //[RZ] There is a problem with RCFParameterBundle. Nominally this should be cleared (closed) on TBeaer + //but that means that this thread (which constructed the bundle) will call Close before the recipient + //refcounting will mean that it's the recipient that would then dealocate and crash against different heap. + //Best if RCFParameterBundle were changed. Alternativelly, CNoBearer could get rid of the params + //earlier. + + if (iLowerFlowBinderControl) + { + iLowerFlowBinderControl->Unbind(NULL,NULL); + iLowerFlowBinderControl->Unbind(); + iLowerFlowBinderControl = NULL; + iLowerFlowControl = NULL; + iLowerFlowData = NULL; + } + + iSubConnectionProvider.PostMessage(Id(), TCFDataClient::TStopped( + message_cast(aMessage).iValue).CRef()); + break; + case TCFDataClient::TProvisionConfig::EId: + break; + case TCFDataClient::TBindTo::EId: + { + TCFDataClient::TBindTo& bindToMsg(static_cast(aMessage)); + TRAP(err, BindToL(bindToMsg)); + + if(err == KErrNone) + { + RClientInterface::OpenPostMessageClose(Id(), aSender, TCFDataClient::TBindToComplete().CRef()); + } + else + { + RClientInterface::OpenPostMessageClose(Id(), aSender, TEBase::TError(aMessage.MessageId(), err).CRef()); + } + + if (iSessionControlNotify && !iParamBundle.IsNull()) + { + iSessionControlNotify->SetLocalNameComplete(); + } + } + break; + default: + __ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockTestdmyprnt, 42)); //For debug configurations + User::Leave(KErrNotSupported); //For release configurations + } + } + else + { + __ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockTestdmyprnt, 45)); //For debug configurations + User::Leave(KErrNotSupported); //For release configurations + } + } + +void CDummyFlow::BindToL(TCFDataClient::TBindTo& aBindTo) +/** +Request from control side (at network layer) to indicate that the SubConnection is +up and running and that we should bind to a Flow below. + +@param aLowerFlow Flow below to bind to. +*/ + { + //provisioning message must come before bindto in case we didn't get it after we've joined + //the sub-connection + if (aBindTo.iNodeId == Messages::TNodeId::NullId()) + { + return; + } + NM_LOG((KESockServerTag, _L8("CDummyFlow %08x:\tSynchronous call: From=%08x To=%08x Func=BindToL"), + this, static_cast(this), &aBindTo.iNodeId.Node()) ) + + const TNodeId& commsId = aBindTo.iNodeId; + +#if defined(__GCCXML__) + CSubConnectionFlowBase* flow = reinterpret_cast(&commsId.Node()); +#else + CSubConnectionFlowBase* flow = Messages::mnode_cast(&commsId.Node()); +#endif + + // Flows can only be directly bound when running in the same thread + __ASSERT_DEBUG(commsId.Thread() == Id().Thread(), User::Panic(KSpecAssert_ESockTestdmyprnt, 47)); + + if (iLowerFlowBinderControl && iLowerFlowBinderControl->Flow() != flow ) + { + // Already bound to something else so unbind first + iLowerFlowBinderControl->Unbind(NULL,NULL); + iLowerFlowBinderControl = NULL; + + iLowerFlowBinderControl->Unbind(); + iLowerFlowControl = NULL; + iLowerFlowData = NULL; + } + + if (iLowerFlowBinderControl == NULL) + { + // Protocol binding + iLowerFlowBinderControl = flow->GetBinderControlL(); + iLowerFlowControl = iLowerFlowBinderControl->GetControlL(KSockDatagram, *this); + iLowerFlowData = iLowerFlowBinderControl->BindL(*this); + } + } + + +