diff -r 000000000000 -r dfb7c4ff071f datacommsserver/esockserver/ssock/ss_subconnstates.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/datacommsserver/esockserver/ssock/ss_subconnstates.cpp Thu Dec 17 09:22:25 2009 +0200 @@ -0,0 +1,877 @@ +// Copyright (c) 2005-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: +// ss_connstates.cpp +// +// + +#include "ss_subconn.h" +#include "ss_subconnstates.h" +#include +#include +#include +#include +#include "ss_subconn.h" +#include "SS_conn.H" +#include + +#include +#include +#include + +#include + + +#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_ESockSSocksbcnst, "ESockSSocksbcnst"); +#endif + +using namespace ESock; +using namespace SubSessActivities; +using namespace Messages; +using namespace MeshMachine; + +#ifdef _DEBUG +_LIT (KCSubConnectionPanic,"CSubConnectionPanic"); +#endif + +//-========================================================= +// +// +//States +// +// +//-========================================================= + +//-========================================================= +// Build stack +//-========================================================= +DEFINE_SMELEMENT(SubConnStates::TAwaitingBuildStackResponse, NetStateMachine::MState, SubConnStates::TContext) +TBool SubConnStates::TAwaitingBuildStackResponse::Accept() + { + return iContext.iMessage.IsMessage(); + } + +DEFINE_SMELEMENT(SubConnStates::TSendBuildStack, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TSendBuildStack::DoL() + { + // The flow request parameters are stored within the subconnection node + RCFParameterFamilyBundleC subConnectionParameters = iContext.Node().iParameterBundle; + + // Send build stack to ourself to kick off a stack building activity + iContext.iNodeActivity->PostRequestTo( iContext.Node().Id(), + TCFInternalEsock::TBuildStackRequest(subConnectionParameters).CRef()); + } + +DEFINE_SMELEMENT(SubConnActivities::CBuildStack::TAwaitingBuildStack, NetStateMachine::MState, SubConnActivities::CBuildStack::TContext) +TBool SubConnActivities::CBuildStack::TAwaitingBuildStack::Accept() + { + return iContext.iMessage.IsMessage(); + } + +DEFINE_SMELEMENT(SubConnActivities::CNoBearer::TStoreFlowParams, NetStateMachine::MStateTransition, SubConnActivities::CNoBearer::TContext) +void SubConnActivities::CNoBearer::TStoreFlowParams::DoL() + { + // Store the received flow params in the activity + TCFControlProvider::TNoBearer& noBearerMessage = message_cast(iContext.iMessage); + SubConnActivities::CNoBearer* noBearerActivity = static_cast(iContext.iNodeActivity); + noBearerActivity->SetFlowRequestParameters(noBearerMessage.iFamilyBundle); + } + +//-========================================================= +//Create +//-========================================================= + +DEFINE_SMELEMENT(SubConnStates::TJoinCPR, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TJoinCPR::DoL() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + if (iContext.Node().ControlProvider().ServiceProvider() == NULL) + { + User::Leave(KErrNotReady); + } + + iContext.Node().AddClientL(iContext.Node().ControlProvider().ServiceProvider()->RecipientId(), TClientType(TCFClientType::EServProvider)); + iContext.iNodeActivity->PostRequestTo(*iContext.Node().ControlProvider().ServiceProvider(), + TCFServiceProvider::TJoinRequest(iContext.NodeId(), TCFClientType::ECtrl).CRef()); + } + +DEFINE_SMELEMENT(SubConnStates::TRequestServiceProvider, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TRequestServiceProvider::DoL() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + + // The flow request parameters are stored within the activity itself + SubConnActivities::CNoBearer* noBearerActivity = static_cast(iContext.iNodeActivity); + RCFParameterFamilyBundleC flowParams = noBearerActivity->GetFlowRequestParameters(); + + // Send our service provider a comms binder carrying the necessary flow request parameters + iContext.iNodeActivity->PostRequestTo( + *iContext.Node().ServiceProvider(), + TCFServiceProvider::TCommsBinderRequest( + TSubConnOpen::ECreateNew, + flowParams + ).CRef() + ); + } + +DEFINE_SMELEMENT(SubConnStates::TLeaveCPR, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TLeaveCPR::DoL() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + __ASSERT_DEBUG(iContext.Node().ControlProvider().ServiceProvider() != NULL, User::Panic(KSpecAssert_ESockSSocksbcnst, 1)); + +#ifdef _DEBUG + TInt count = iContext.Node().CountClients(TClientType(TCFClientType::EServProvider), TClientType(0, TCFClientType::EActive)); + // Now the subconn had joined SCPR, and CPR. The relationship between subconn and CPR is temporary and + // should be terminate here in this transition. So in here make sure there's ONLY 1 SP inactive and + // that's supposed to be the CPR, any other cases are wrong + __ASSERT_DEBUG(count == 1, User::Panic(KCSubConnectionPanic, KPanicNoServiceProvider)); +#endif + + // Find the SP which is not EActive because EActive is not set on the CPR's flag in the first place + RNodeInterface * cpr = iContext.Node().GetFirstClient(TClientType(TCFClientType::EServProvider), TClientType(0, TCFClientType::EActive)); + iContext.iNodeActivity->PostRequestTo(*cpr, TEPeer::TLeaveRequest().CRef()); + cpr->SetFlags(TCFClientType::ELeaving); + } + +//-========================================================= +//Rejoin +//-========================================================= + +DEFINE_SMELEMENT(SubConnStates::TJoinTheOtherOwner, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TJoinTheOtherOwner::DoL() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + SubConnActivities::CRejoin* rejoinActivity = static_cast(iContext.iNodeActivity); + rejoinActivity->InitialiseL(iContext.Node()); + + //MZTODO: activity using this transition - and possibly the whole approach - must be redesigned + //so that all destinations are safe! (used to be: TCtrlClientJoinRequestUnsafeDst). + rejoinActivity->SetOldOwnerIntf(iContext.Node().AddClientL(rejoinActivity->TheOtherOwner(), TClientType(TCFClientType::EServProvider))); + iContext.iNodeActivity->ClearPostedTo(); + + RClientInterface::OpenPostMessageClose(iContext.NodeId(), rejoinActivity->TheOtherOwner(), + TCFServiceProvider::TJoinRequest(iContext.NodeId(), TClientType(TCFClientType::ECtrl)).CRef()); + } + +DEFINE_SMELEMENT(SubConnStates::TLeaveTheOtherOwner, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TLeaveTheOtherOwner::DoL() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + SubConnActivities::CRejoin* rejoinActivity = static_cast(iContext.iNodeActivity); + + RClientInterface::OpenPostMessageClose(iContext.NodeId(), rejoinActivity->TheOtherOwner(), + TEPeer::TLeaveRequest().CRef()); + + rejoinActivity->OldOwnerIntf()->SetFlags(ESock::TCFClientType::ELeaving); + } + +DEFINE_SMELEMENT(SubConnStates::TSendRejoinDataClientRequestToOldOwner, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TSendRejoinDataClientRequestToOldOwner::DoL() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + SubConnActivities::CRejoin* rejoinActivity = static_cast(iContext.iNodeActivity); + + RClientInterface::OpenPostMessageClose(iContext.NodeId(), rejoinActivity->OldOwner(), + TCFRejoiningProvider::TRejoinDataClientRequest(rejoinActivity->Flow(), rejoinActivity->NewOwner()).CRef()); + } + +DEFINE_SMELEMENT(SubConnStates::TSendApplyToOldOwner, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TSendApplyToOldOwner::DoL() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + SubConnActivities::CRejoin* rejoinActivity = static_cast(iContext.iNodeActivity); + RClientInterface::OpenPostMessageClose(iContext.NodeId(), rejoinActivity->OldOwner(), + TCFScpr::TApplyRequest().CRef()); + } + +DEFINE_SMELEMENT(SubConnStates::TSendApplyToNewOwner, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TSendApplyToNewOwner::DoL() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + SubConnActivities::CRejoin* rejoinActivity = static_cast(iContext.iNodeActivity); + RClientInterface::OpenPostMessageClose(iContext.NodeId(), rejoinActivity->NewOwner(), + TCFScpr::TApplyRequest().CRef()); + } + +DEFINE_SMELEMENT(SubConnStates::TSendCancelToOldOwner, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TSendCancelToOldOwner::DoL() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + SubConnActivities::CRejoin* rejoinActivity = static_cast(iContext.iNodeActivity); + + RClientInterface::OpenPostMessageClose(iContext.NodeId(), rejoinActivity->OldOwner(), + TEBase::TCancel().CRef()); + } + + +//-========================================================= +//SetParameters +//-========================================================= +DEFINE_SMELEMENT(SubConnStates::TSendParamsToServiceProvider, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TSendParamsToServiceProvider::DoL() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + SubConnActivities::CSetParameters& setParamsActivity = + static_cast(*iContext.iNodeActivity); + + if (iContext.Node().SubConnType() == RSubConnection::EAttachToDefault) + { + // SubConnections opened with EAttachToDefault require the NetworkControl capability for changing QoS + setParamsActivity.HasCapabilityL (ECapabilityNetworkControl, "CSubConnection::SetParametersL(): EAttachToDefault requires NetworkControl"); + } +#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW + iContext.iNodeActivity->PostRequestTo(*iContext.Node().ServiceProvider(), + TCFScpr::TSetParamsRequest(setParamsActivity.GetParameterBundleL()).CRef()); +#else + iContext.iNodeActivity->PostRequestTo(*iContext.Node().ServiceProvider(), + TCFScpr::TParamsRequest(setParamsActivity.GetParameterBundleL()).CRef()); +#endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW + } + +DEFINE_SMELEMENT(SubConnStates::TStoreParams, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TStoreParams::DoL() + { +#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW + TCFScpr::TSetParamsResponse& paramResponse = message_cast(iContext.iMessage); +#else + TCFScpr::TParamsResponse& paramResponse = message_cast(iContext.iMessage); +#endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW + if(! iContext.Node().iParameterBundle.IsNull()) + { + iContext.Node().iParameterBundle.Close(); + } + iContext.Node().iParameterBundle.Open(paramResponse.iFamilyBundle); + } + +DEFINE_SMELEMENT(SubConnStates::TSendParamRequest, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TSendParamRequest::DoL() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockSSocksbcnst, 2)); + __ASSERT_DEBUG(iContext.Node().ServiceProvider(), User::Panic(KSpecAssert_ESockSSocksbcnst, 3)); +#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW + iContext.iNodeActivity->PostRequestTo(*iContext.Node().ServiceProvider(), + TCFScpr::TSetParamsRequest(iContext.Node().iParameterBundle).CRef()); +#else + iContext.iNodeActivity->PostRequestTo(*iContext.Node().ServiceProvider(), + TCFScpr::TParamsRequest(iContext.Node().iParameterBundle).CRef()); +#endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW + } + +DEFINE_SMELEMENT(SubConnStates::TNoTagOrParamsPresent, NetStateMachine::MStateFork, SubConnStates::TContext) +TInt SubConnStates::TNoTagOrParamsPresent::TransitionTag() + { + return iContext.Node().iParameterBundle.IsNull() ? MeshMachine::KNoTag : PRStates::KParamsPresent; + } + +DEFINE_SMELEMENT(SubConnStates::TWriteSubConnParamsLength, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TWriteSubConnParamsLength::DoL() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + __ASSERT_DEBUG( ! iContext.Node().iParameterBundle.IsNull() , User::Panic(KSpecAssert_ESockSSocksbcnst, 4)); + CESockClientActivityBase& esockActivity = + static_cast(*iContext.iNodeActivity); + + //I know!! + esockActivity.SetError(iContext.Node().iParameterBundle.IsNull() ? KErrNotReady : (TInt) iContext.Node().iParameterBundle.Length() ); + } + +DEFINE_SMELEMENT(SubConnStates::TWriteSubConnParams, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TWriteSubConnParams::DoL() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + __ASSERT_DEBUG(! iContext.Node().iParameterBundle.IsNull() , User::Panic(KSpecAssert_ESockSSocksbcnst, 5)); + CESockClientActivityBase& esockActivity = + static_cast(*iContext.iNodeActivity); + RCFParameterFamilyBundleC& pfb = iContext.Node().iParameterBundle; + pfb.CheckOpenL(); + + RBuf8 buffer; + buffer.CreateL(pfb.Length()); + CleanupClosePushL(buffer); + User::LeaveIfError(pfb.Store(buffer)); + #ifdef ESOCK_LOGGING_ACTIVE + if(esockActivity.GetDesMaxLengthL(0) < buffer.Length()) + { + LOG(ESockLog::Printf(_L("ESock: SubConnStates[%x]\tTWriteSubConnParams: client supplied buffer of size %d is too small to store parameter bundle of size %d"), this, esockActivity.GetDesMaxLengthL(0), buffer.Length())); + } + #endif + esockActivity.WriteL(0, buffer); + CleanupStack::PopAndDestroy(); // buffer + } + +//-========================================================= +//Events +//-========================================================= + +DEFINE_SMELEMENT(SubConnStates::TAwaitingEventNotificationSubscription, NetStateMachine::MState, SubConnStates::TContext) +TBool SubConnStates::TAwaitingEventNotificationSubscription::Accept() + { + if (subsessmessage_cast(&iContext.iMessage) || + subsessmessage_cast(&iContext.iMessage)) + { + return ETrue; + } + return EFalse; + } + +DEFINE_SMELEMENT(SubConnStates::TNoTagOrAllNotifications, NetStateMachine::MStateFork, SubConnStates::TContext) +TInt SubConnStates::TNoTagOrAllNotifications::TransitionTag() + { + if (subsessmessage_cast(&iContext.iMessage)) + { + return ESCEventAllNotifications; + } + return MeshMachine::KNoTag; + } + +DEFINE_SMELEMENT(SubConnStates::TSetupFilteredEventNotification, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TSetupFilteredEventNotification::DoL() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + SubConnActivities::CEventNotification& eventNotificationActivity = + static_cast(*iContext.iNodeActivity); + + eventNotificationActivity.RequestEventNotificationSetupL(); + } + +DEFINE_SMELEMENT(SubConnStates::TSetupAllEventNotification, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TSetupAllEventNotification::DoL() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + SubConnActivities::CEventNotification& eventNotificationActivity = + static_cast(*iContext.iNodeActivity); + + eventNotificationActivity.RequestAllEventNotificationsL(); + } + +DEFINE_SMELEMENT(SubConnStates::TFillInEvent, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TFillInEvent::DoL() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + SubConnActivities::CEventNotification& eventNotificationActivity = + static_cast(*iContext.iNodeActivity); + + if (iContext.iMessage.IsMessage()) + { + TEnqueueEvent enqueueEvent(iContext); + enqueueEvent.DoL(); + } + + CRefCountOwnedSubConNotification* eventRefCountOwner = NULL; + TBool eventConsumed = EFalse; + while (iContext.Node().iEventQueue.Deque(eventRefCountOwner)) + { + __ASSERT_DEBUG(eventRefCountOwner && eventRefCountOwner->Ptr(), User::Panic(KSpecAssert_ESockSSocksbcnst, 6)); + eventConsumed = eventNotificationActivity.FillInEvent(*eventRefCountOwner->Ptr()); + eventRefCountOwner->Close(); + if (eventConsumed) + { + break; + } + } + } + +DEFINE_SMELEMENT(SubConnStates::TEnqueueEvent, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TEnqueueEvent::CreateOrUpdateBundleL(CSubConGenEventParamsGranted* aEvent) + { + RCFParameterFamilyBundleC& myBundle = iContext.Node().GetOrCreateParameterBundleL(); + + RParameterFamily family=myBundle.FindFamily(KSubConQoSFamily); + if ( family.IsNull() ) + { + RCFParameterFamilyBundle newBundle; + newBundle.CreateL(); + newBundle.Open(myBundle); + family = newBundle.CreateFamilyL(KSubConQoSFamily); + //family = myBundle.CreateFamilyL(KSubConQoSFamily); //PJLEFT + newBundle.Close(); + } + + family.ClearAllParameters (RParameterFamily::EGranted); + + CSubConGenericParameterSet* origGeneric = const_cast(aEvent->GetGenericSet()); + if (origGeneric) + { + // A copy must be used because parameters owned by the event will be destructed + // along with it. + CSubConGenericParameterSet* copyGeneric = static_cast(CSubConGenericParameterSet::NewL (origGeneric->GetTypeId())); + CleanupStack::PushL (copyGeneric); + copyGeneric->Copy (*origGeneric); + family.AddParameterSetL (copyGeneric, RParameterFamily::EGranted); + CleanupStack::Pop (copyGeneric); + } + + TInt max = aEvent->GetNumExtensionSets(); + for (TInt i=0; i(aEvent->GetExtensionSet (i)); + CSubConExtensionParameterSet* copyExtension = static_cast(CSubConExtensionParameterSet::NewL(origExtension->GetTypeId())); + CleanupStack::PushL (copyExtension); + copyExtension->Copy (*origExtension); + family.AddParameterSetL(copyExtension, RParameterFamily::EGranted); + CleanupStack::Pop (copyExtension); + } + } + + +void SubConnStates::TEnqueueEvent::DoL() + { + TCFSubConnControlClient::TSubConnNotification& eventMsg = message_cast(iContext.iMessage); + __ASSERT_DEBUG(eventMsg.iRefCountOwnedSubConNotification, User::Panic(KSpecAssert_ESockSSocksbcnst, 7)); + __ASSERT_DEBUG(eventMsg.iRefCountOwnedSubConNotification->Ptr(), User::Panic(KSpecAssert_ESockSSocksbcnst, 8)); + iContext.Node().iEventQueue.Enque(eventMsg.iRefCountOwnedSubConNotification); + const CSubConNotificationEvent* event = eventMsg.iRefCountOwnedSubConNotification->Ptr(); + //If param related event - update the params. + if (event->GroupId() == KSubConnGenericEventsImplUid + && (event->Id() == KSubConGenericEventParamsGranted + || event->Id() == KSubConGenericEventParamsChanged)) + { + CreateOrUpdateBundleL(const_cast(static_cast(event))); + } + } + +DEFINE_SMELEMENT(SubConnStates::TNoTagOrActiveWhenEventEnqued, NetStateMachine::MStateFork, SubConnStates::TContext) +TInt SubConnStates::TNoTagOrActiveWhenEventEnqued::TransitionTag() + { + if (!iContext.Node().iEventQueue.IsEmpty()) + { + return KActiveTag; + } + return MeshMachine::KNoTag; + } + + +//-========================================================= +//Start/Stop Connection +//-========================================================= +DEFINE_SMELEMENT(SubConnStates::TStartSubConnection, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TStartSubConnection::DoL() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + if (iContext.Node().ServiceProvider() == NULL) + { + User::Leave(KErrNotReady); + } + iContext.iNodeActivity->PostRequestTo(*iContext.Node().ServiceProvider(), + TCFServiceProvider::TStart().CRef()); + } + +DEFINE_SMELEMENT(SubConnStates::TStopSubConnection, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TStopSubConnection::DoL() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + if (iContext.Node().ServiceProvider() == NULL) + { + iContext.iNodeActivity->SetIdle(); + } + else + { + iContext.iNodeActivity->PostRequestTo(*iContext.Node().ServiceProvider(), + TCFServiceProvider::TStop(KErrCancel).CRef()); + } + } + +//-========================================================= +//Close +//-========================================================= +DEFINE_SMELEMENT(SubConnStates::TDetachControlProvider, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnStates::TDetachControlProvider::DoL() + { + TClientIter iter = iContext.Node().GetClientIter(TClientType(TCFClientType::ECtrlProvider)); + if (iter[0]) + { +#if defined(__GCCXML__) + CConnection& conn = *reinterpret_cast(&(iter[0]->RecipientId().Node())); +#else + CConnection& conn = mcfnode_cast(iter[0]->RecipientId().Node()); +#endif + iContext.Node().RemoveClient(conn.Id()); + conn.RemoveClient(iContext.NodeId()); + } + } +//-========================================================= +// +// +//Activities +// +// +//-========================================================= +//-========================================================= +//CNoBearer +//-========================================================= +MeshMachine::CNodeActivityBase* SubConnActivities::CNoBearer::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode) + { + SubConnActivities::CNoBearer* noBearerActivity = new SubConnActivities::CNoBearer(aActivitySig, aNode); + if (noBearerActivity == NULL) + { + User::Leave(KErrNoMemory); + } + return noBearerActivity; + } + +SubConnActivities::CNoBearer::~CNoBearer() + { + //Destroy the subconnection if the ownership hasn't been released! + iFlowRequestBundle.Close(); + if(Error() != KErrNone) + { + PostToOriginators(TEBase::TError(KickOffMessageId(), Error()).CRef()); + } + } + +void SubConnActivities::CNoBearer::SetFlowRequestParameters(const ESock::RCFParameterFamilyBundleC& aParams) + { + if(!iFlowRequestBundle.IsNull()) + { + iFlowRequestBundle.Close(); + } + iFlowRequestBundle.Open(aParams); + } + +//-========================================================= +//CBuildStack +//-========================================================= +MeshMachine::CNodeActivityBase* SubConnActivities::CBuildStack::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode) + { + SubConnActivities::CBuildStack* createActivity = new SubConnActivities::CBuildStack(aActivitySig, aNode); + if (createActivity == NULL) + { + User::Leave(KErrNoMemory); + } + return createActivity; + } + +SubConnActivities::CBuildStack::CBuildStack(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode) + : MeshMachine::CNodeActivityBase(aActivitySig, aNode), + CoreActivities::ABindingActivity(aNode.Id()), + TIfStaticFetcherNearestInHierarchy(this) + { + } + +SubConnActivities::CBuildStack::~CBuildStack() + { + } + +DEFINE_SMELEMENT(SubConnActivities::CBuildStack::TSendBuildStackResponse, NetStateMachine::MStateTransition, CBuildStack::TContext) +void SubConnActivities::CBuildStack::TSendBuildStackResponse::DoL() + { + iContext.iNodeActivity->PostToOriginators( + TCFInternalEsock::TBuildStackResponse().CRef()); + } + +DEFINE_SMELEMENT(SubConnActivities::CBuildStack::TRequestServiceProviderFromCPR, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnActivities::CBuildStack::TRequestServiceProviderFromCPR::DoL() + { + // This transition sends a request for a comms binder to the CPR + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + SubConnActivities::CBuildStack& buildStackActivity = + static_cast(*iContext.iNodeActivity); + + // The activity is a friend of the subconn so lets call on it to do the job + buildStackActivity.RequestServiceProviderFromCPRL(iContext); + } + +void SubConnActivities::CBuildStack::RequestServiceProviderFromCPRL(TContext& aContext) + { + if (aContext.Node().ControlProvider().ServiceProvider() == NULL) + { + User::Leave(KErrNotReady); + } + + // Post the request to our controls provider's service provider (that the top level CPR that manages our connection) + aContext.iNodeActivity->PostRequestTo( + *aContext.Node().ControlProvider().ServiceProvider(), + TCFServiceProvider::TCommsBinderRequest(aContext.Node().iSubConnType, + aContext.Node().iParameterBundle + ).CRef() + ); + } + + +//-========================================================= +//CCreate +//-========================================================= +MeshMachine::CNodeActivityBase* SubConnActivities::CCreate::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode) + { + SubConnActivities::CCreate* createActivity = new SubConnActivities::CCreate(aActivitySig, aNode); + if (createActivity == NULL) + { +#ifndef __GCCXML__ + RClientInterface::OpenPostMessageClose(aNode.Id(), aNode.Id(), TCFInternalEsock::TSubSess(ESCClose,RMessage2()).CRef()); +#endif + User::Leave(KErrNoMemory); + } + return createActivity; + } + +SubConnActivities::CCreate::~CCreate() + { + //Destroy the subconnection if the ownership hasn't been released! + if (Error() != KErrNone) + { + RClientInterface::OpenPostMessageClose(iSubConnectionNode, iSubConnectionNode, + TCFInternalEsock::TSubSess(ESCClose,RMessage2()).CRef()); + } + } + +DEFINE_SMELEMENT(SubConnStates::TNoTagOrWaitForIncoming, NetStateMachine::MStateFork, SubConnStates::TContext) +TInt SubConnStates::TNoTagOrWaitForIncoming::TransitionTag() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + CESockClientActivityBase& ac = static_cast(*iContext.iNodeActivity); + + TPckgBuf argPkg; + ac.ReadL(0,argPkg); + iContext.Node().iSubConnType = static_cast(argPkg().iType); + if (iContext.Node().iSubConnType == RSubConnection::EWaitIncoming) + { + return CoreNetStates::KWaitForIncoming; + } + return MeshMachine::KNoTag; + } + +DEFINE_SMELEMENT(SubConnStates::TNoTagOrAttachToDefaultOrWaitForIncoming, NetStateMachine::MStateFork, SubConnStates::TContext) +TInt SubConnStates::TNoTagOrAttachToDefaultOrWaitForIncoming::TransitionTag() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + CESockClientActivityBase& ac = static_cast(*iContext.iNodeActivity); + + TPckgBuf argPkg; + ac.ReadL(0,argPkg); + iContext.Node().iSubConnType = static_cast(argPkg().iType); + if (iContext.Node().iSubConnType == RSubConnection::EWaitIncoming) + { + return CoreNetStates::KWaitForIncoming; + } + else if (iContext.Node().iSubConnType == RSubConnection::EAttachToDefault) + { + return CoreNetStates::KAttachToDefault; + } + return MeshMachine::KNoTag; + } + +//-========================================================= +//CRejoin +//-========================================================= +MeshMachine::CNodeActivityBase* SubConnActivities::CRejoin::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode) + { + return new (ELeave) SubConnActivities::CRejoin(aActivitySig, aNode); + } + +SubConnActivities::CRejoin::~CRejoin() + { + } + +void SubConnActivities::CRejoin::InitialiseL(CSubConnection& aSC) + { + if (!iNewOwner.IsNull()) + { + __ASSERT_DEBUG(!iOldOwner.IsNull() && !iFlow.IsNull(), User::Panic(KSpecAssert_ESockSSocksbcnst, 9)); + return; + } + + if (aSC.ServiceProvider() == NULL) + { + User::Leave(KErrNotReady); + } + + __ASSERT_DEBUG(aSC.Session(), User::Panic(KSpecAssert_ESockSSocksbcnst, 10)); + if (!aSC.Session()->FlowAndSCPRFromSocketHandle(iMessage.Int0(), iFlow, iOldOwner)) + { + User::Leave(KErrNotFound); + } + + if (iMessage.Function() == ESCRemoveSocket) + { + RNodeInterface* conn = aSC.ControlProvider().ServiceProvider(); + __ASSERT_DEBUG(conn, User::Panic(KSpecAssert_ESockSSocksbcnst, 11)); + User::LeaveIfError(conn? KErrNone : KErrArgument); + +#if defined(__GCCXML__) + CConnectionProviderBase& p = *reinterpret_cast(&(conn->RecipientId().Node())); +#else + CConnectionProviderBase& p = mcfnode_cast(conn->RecipientId().Node()); +#endif + RNodeInterface* primarySc = p.DefaultSubConnectionProvider(); + __ASSERT_DEBUG( primarySc , User::Panic(KSpecAssert_ESockSSocksbcnst, 12)); + + iNewOwner = primarySc->RecipientId(); + } + else if (iMessage.Function() == ESCAddSocket) + { + iNewOwner = aSC.ServiceProvider()->RecipientId(); + } + else + { + __ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockSSocksbcnst, 13)); + } + if (iNewOwner == iOldOwner) + { + User::Leave(KErrAlreadyExists); + } + } + +//-========================================================= +//CSetParameters +//-========================================================= +MeshMachine::CNodeActivityBase* SubConnActivities::CSetParameters::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode) + { + return new (ELeave) SubConnActivities::CSetParameters(aActivitySig, aNode); + } + +SubConnActivities::CSetParameters::~CSetParameters() + { + if (! iParameterBundle.IsNull()) + { + iParameterBundle.Close(); + } + } + +RCFParameterFamilyBundleC& SubConnActivities::CSetParameters::GetParameterBundleL() + { + if ( ! iParameterBundle.IsNull() ) + { + return iParameterBundle; + } + //Extract the parameter bundle. + TInt length = iMessage.GetDesLengthL(0); + RBuf8 buffer; + buffer.CreateL(length); + CleanupClosePushL(buffer); + iMessage.ReadL(0, buffer); + + iParameterBundle.LoadL(buffer); + CleanupStack::PopAndDestroy(&buffer); + return iParameterBundle; + } + +void SubConnActivities::CSetParameters::CompleteMessage() + { + LOG(ESockLog::Printf(_L("SubConnActivities::CSetParameters::CompleteMessage - (%08X) with %d"), iMessage.Handle(), Error())); + + __ASSERT_DEBUG(!iMessage.IsNull(), User::Panic(KSpecAssert_ESockSSocksbcnst, 14)); + iMessage.Complete(Error()); + } + +DEFINE_SMELEMENT(SubConnActivities::CSetParameters::TCompleteClient, NetStateMachine::MStateTransition, TContext) +void SubConnActivities::CSetParameters::TCompleteClient::DoL() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + SubConnActivities::CSetParameters& setparamActivity = static_cast(*iContext.Activity()); + setparamActivity.CompleteMessage(); + } +DEFINE_SMELEMENT(SubConnActivities::CSetParameters::TStoreNewParams, NetStateMachine::MStateTransition, SubConnStates::TContext) +void SubConnActivities::CSetParameters::TStoreNewParams::DoL() + { + __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCSubConnectionPanic,KPanicNoActivity)); + SubConnActivities::CSetParameters& setParamsActivity = + static_cast(*iContext.iNodeActivity); + + // Store the parameters in the subconnection node + setParamsActivity.StoreParametersInSubConn(iContext); + } + +void SubConnActivities::CSetParameters::StoreParametersInSubConn(TContext& aContext) + { + // Store the parameters in the CSubConnection node + if (!aContext.Node().iParameterBundle.IsNull()) + { + aContext.Node().iParameterBundle.Close(); + } + aContext.Node().iParameterBundle.Open(GetParameterBundleL()); + aContext.Node().iParameterBundle.Open(); + } + +//-========================================================= +//CEventNotification +//-========================================================= +MeshMachine::CNodeActivityBase* SubConnActivities::CEventNotification::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode) + { + return new (ELeave) SubConnActivities::CEventNotification(aActivitySig, aNode); + } + +SubConnActivities::CEventNotification::~CEventNotification() + { + } + +void SubConnActivities::CEventNotification::RequestEventNotificationSetupL() + { + if (iMessage.Ptr0()) + { + TPtr8 ptr((TUint8*)iEventUidFilterList, KMaxUidFilterListLen*sizeof(RSubConnection::TEventFilter)); + TInt ret = iMessage.Read(0, ptr, 0); + iEventUidFilterListLength = ptr.Length() / sizeof(RSubConnection::TEventFilter); + + if (ret != KErrNone) + { + // Null filter list + Mem::FillZ ((void*)iEventUidFilterList, KMaxUidFilterListLen*sizeof(RSubConnection::TEventFilter)); + iEventUidFilterListLength = 0; + } + } + else + { + // Null filter list + Mem::FillZ ((void*)iEventUidFilterList, KMaxUidFilterListLen*sizeof(RSubConnection::TEventFilter)); + iEventUidFilterListLength = 0; + } + } + +void SubConnActivities::CEventNotification::RequestAllEventNotificationsL() + { + RSubConnection::TEventFilter & filter = iEventUidFilterList[0]; + if ( iMessage.Int1() ) //ie request only generic events + { + filter.iEventGroupUid = KSubConnGenericEventsImplUid; + filter.iEventMask = 0xffffffff; + iEventUidFilterListLength = 1; + } + else + { + iEventUidFilterListLength = 0; + } + } + + +TBool SubConnActivities::CEventNotification::FillInEvent(const CSubConNotificationEvent& aEvent) + { + TBool sendEvent(iEventUidFilterListLength == 0); + for (TUint i = 0; i < iEventUidFilterListLength; ++i) + { + if (iEventUidFilterList[i].iEventGroupUid == aEvent.GroupId() && + iEventUidFilterList[i].iEventMask & aEvent.Id()) + { + sendEvent = ETrue; + break; + } + } + if (sendEvent) + { + TBuf8 eventBuffer; + TPtr8 ptr((TUint8*)eventBuffer.Ptr(),eventBuffer.MaxLength()); + if (aEvent.Store(ptr) == KErrNone) + { + LOG(ESockLog::Printf(_L("ESock: CSubConnection[%x]: Notification Sent. Event Type %d"), this, aEvent.Id())); + eventBuffer.SetLength(ptr.Length()); + TInt err = iMessage.Write(0, eventBuffer); + } + } + return sendEvent; + } + + +