--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/ssock/ss_connstates.cpp Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,1720 @@
+// 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:
+//
+
+#include "SS_conn.H"
+#include "ss_connstates.h"
+#include <comms-infras/ss_log.h>
+#include <comms-infras/ss_coreprstates.h>
+#include <comms-infras/ss_corepractivities.h>
+#include "ss_subconn.h"
+#include <comms-infras/ss_mcprnodemessages.h>
+#include <elements/sm_core.h>
+#include <commdbconnpref.h> //TCommDbConnPref
+#include <ss_glob.h> //TCommDbConnPref
+#include <connpref.h> //TConnPrefList
+#include <etelpckt.h>
+#include <comms-infras/metadata.h>
+#include <comms-infras/esock_params.h> //TConnAPPref
+#include <comms-infras/esock_params_internal.h> //TConnCSRPref
+
+#include <comms-infras/es_connectionservparameterbundle.h> // CConnectionServParameterBundle
+#include <comms-infras/es_accesspointstatus.h> // TAccessPointStatusFilter
+#include <comms-infras/cs_connservparams.h> // XAccessPointGenericParameterSet
+#include <comms-infras/cs_connservparams_internal.h>
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <es_enum_internal.h>
+#include <nifvar_internal.h>
+#endif
+
+#include <elements/nm_messages_child.h>
+#include <elements/nm_messages_peer.h>
+#include <comms-infras/ss_nodemessages_dataclient.h>
+#include <comms-infras/ss_nodemessages_legacy.h>
+#include <comms-infras/ss_nodemessages_tiermanager.h>
+#include <comms-infras/ss_nodemessages_serviceprovider.h>
+#include <comms-infras/ss_nodemessages_internal_esock.h>
+#include <comms-infras/ss_nodemessages_selector.h>
+#include <comms-infras/ss_nodemessages_factory.h>
+#include <comms-infras/ss_nodemessages_tiermanagerfactory.h>
+
+#define SYMBIAN_NETWORKING_UPS
+
+#ifdef SYMBIAN_NETWORKING_UPS
+#include <comms-infras/ss_upsaccesspointconfigext.h>
+#include <comms-infras/upsmessages.h>
+#endif
+
+#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_ESockSSockscnsts, "ESockSSockscnsts");
+#endif
+
+using namespace ESock;
+using namespace SubSessActivities;
+using namespace NetStateMachine;
+using namespace ConnStates;
+using namespace ConnActivities;
+using namespace ConnectionServ;
+using namespace Elements;
+using namespace Messages;
+using namespace MeshMachine;
+
+//#ifdef LOG
+// #define KESockActivityTag KESockCoreProviderTag
+// _LIT8(KESockActivitySubTag, "esockactivity");
+//#endif
+
+_LIT (KCConnectionPanic,"CConnectionPanic");
+
+void ConnPanic(TInt aCode)
+ {
+ User::Panic(KCConnectionPanic, aCode);
+ }
+
+//
+//Start
+
+DEFINE_SMELEMENT(ConnStates::TErrorIfAlreadyStartedAttached, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TErrorIfAlreadyStartedAttached::DoL()
+ {
+ __ASSERT_DEBUG((subsessmessage_cast<ECNStart>(&iContext.iMessage))
+ || (subsessmessage_cast<ECNAttach>(&iContext.iMessage)),
+ ConnPanic(KPanicIncorrectMessage));
+ RNodeInterface* sp = iContext.Node().ServiceProvider();
+ User::LeaveIfError(sp? KErrAlreadyExists : KErrNone);
+ }
+
+DEFINE_SMELEMENT(ConnStates::TParseECNStart, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TParseECNStart::DoL()
+ {
+ __ASSERT_DEBUG((subsessmessage_cast<ECNStart>(&iContext.iMessage)), ConnPanic(KPanicIncorrectMessage));
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ ConnActivities::CStartAttachActivity& ac = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity);
+
+ if (ac.Function() == ECNSetStartPrefs)
+ {
+ //Extract preferences if ECNSetStartPrefs
+ TConnPref prefs;
+ ac.ReadL(0, prefs);
+
+ if(prefs.ExtensionId() != TConnPref::EConnPrefEComList)
+ {
+ ac.SelectionPrefs().SetPrefs(prefs);
+ }
+ else
+ {
+ RBuf8 buffer;
+ TInt length = ac.GetDesLengthL(0);
+ buffer.CreateL(length);
+ CleanupClosePushL(buffer);
+ ac.ReadL(0, buffer);
+
+ TConnPrefList* prefsList = TConnPrefList::NewL();
+ CleanupStack::PushL(prefsList);
+ TPtrC8 ptr(buffer);
+ TInt ret = prefsList->Load(ptr);
+ User::LeaveIfError(ret);
+
+ //This loop is used to check that there is no more than 1 instance
+ //of TConnAPPref in the list passed to the CSR. This is not allowed
+ //(as it may have adverse effects in the construction of the stack)
+ //KErrArugment is returned if there is more than 1 instance present
+ TInt instances = 0;
+ for(TInt i=0; i<prefsList->Count(); i++)
+ {
+ TConnAPPref* pref = smetadata_cast<TConnAPPref>((*prefsList)[i]);
+ if(pref)
+ {
+ instances++;
+ }
+ }
+ if(instances > 1)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ TConnCSRPref* csr = TConnCSRPref::NewL();
+ CleanupStack::PushL(csr);
+ ac.SetCSRPreferences(csr);
+ csr->SetScope(TSelectionPrefs::EExplicitConnection);
+ prefsList->AppendL(csr);
+
+ ac.SelectionPrefs().SetPrefs(*prefsList);
+ ac.SetConnPrefList(prefsList);
+
+ CleanupStack::Pop(csr);
+ CleanupStack::Pop(prefsList);
+ CleanupStack::PopAndDestroy(&buffer);
+ }
+
+ // Complete the ECNSetStartPrefs, activity will be held until the 2nd IPC of the Start with Prefs
+ // call is received. Null iSubSession so that the 2nd IPC can be aquired by the activity.
+ ac.iMessage.Complete(KErrNone);
+ ac.iSubSession = NULL;
+ }
+ else
+ {
+ ac.SetSelectionScope(TSelectionPrefs::EExplicitConnection);
+ }
+ }
+
+DEFINE_SMELEMENT(ConnStates::TSendStartingSelectionStateChange, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TSendStartingSelectionStateChange::DoL()
+ {
+ //Send the relevant progress (don't use ReceivedL or you will warp), also use Null Activity id.
+ RNodeInterface::OpenPostMessageClose(iContext.NodeId(), iContext.NodeId(), TCFMessage::TStateChange(TStateChange(KStartingSelection,KErrNone)).CRef());
+ }
+
+DEFINE_SMELEMENT(ConnStates::TClearProgressQueue, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TClearProgressQueue::DoL()
+ {
+ iContext.Node().iProgressQueue.Reset(); // clear progress notification cache
+ iContext.Node().ResetLastProgressError(); // clear last progress in error
+ // Initialise iLastProgress with an invalid progress rather than 0 (which is actually KConnectionUninitialised)
+ // otherwise we can end up unintentionally filtering out a KConnectionUninitialised progress.
+ const TInt KInvalidProgress = -1;
+ iContext.Node().iLastProgress = TStateChange(KInvalidProgress, 0);
+ iContext.Node().iLastProgressError = TStateChange();
+ }
+
+DEFINE_SMELEMENT(ConnStates::TRequestCSRCreation, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TRequestCSRCreation::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ __ASSERT_DEBUG(static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity).CSR().IsNull(), ConnPanic(KPanicExpectedNoCSR));
+ iContext.iNodeActivity->PostRequestTo(SockManGlobals::Get()->GetPlaneFC(TCFPlayerRole(TCFPlayerRole::ETierMgrPlane)), TCFInternalEsock::TCreateCSR(iContext.Node().iTierId).CRef(), EFalse);
+ }
+
+DEFINE_SMELEMENT(ConnStates::TProcessCSRCreation, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TProcessCSRCreation::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ ConnActivities::CStartAttachActivity& ac = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity);
+ __ASSERT_DEBUG(ac.CSR().IsNull(), User::Panic(KSpecAssert_ESockSSockscnsts, 1));
+ ac.SetCSR(message_cast<TCFInternalEsock::TCSRCreated>(iContext.iMessage).iNodeId);
+
+
+ RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), ac.CSR(),
+ TCFMessage::TProvisionConnectionInfo(iContext.Node().ConnectionInfo()).CRef());
+ }
+
+DEFINE_SMELEMENT(ConnStates::TSelectMetaPlane, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TSelectMetaPlane::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ ConnActivities::CStartAttachActivity& ac = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity);
+
+ //Diagnostic only. If attach then it must be ESelectFromExisting
+ __ASSERT_DEBUG(!iContext.Node().IsMonitor()
+ || ac.SelectionPrefs().Scope() & TSelectionPrefs::ESelectFromExisting, User::Panic(KSpecAssert_ESockSSockscnsts, 2));
+
+ if(ac.SelectionPrefs().Prefs().ExtensionId() != TConnPref::EConnPrefEComList)
+ {
+ ac.SelectionPrefs().SetSubSessionUniqueId(iContext.Node().UniqueId());
+ iContext.iNodeActivity->PostRequestTo(
+ ac.CSR(),
+ TCFSelector::TSimpleSelect(ac.SelectionPrefs()).CRef()
+ );
+ }
+ else
+ {
+ ac.CSRPreferences()->SetSubSessionUniqueId(iContext.Node().UniqueId());
+ RConnPrefList handle;
+ handle.Open(ac.ConnPrefList());
+
+ iContext.iNodeActivity->PostRequestTo(
+ ac.CSR(),
+ TCFSelector::TSelect(handle).CRef()
+ );
+ }
+ }
+
+DEFINE_SMELEMENT(ConnStates::TSendFinishedSelectionStateChange, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TSendFinishedSelectionStateChange::DoL()
+ {
+ //Send the relevant progress (don't use ReceivedL or you will warp), also use Null Activity id.
+ RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.NodeId(),
+ TCFMessage::TStateChange(TStateChange(KFinishedSelection,KErrNone)).CRef());
+ }
+
+DEFINE_SMELEMENT(ConnStates::TJoinReceivedCpr, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TJoinReceivedCpr::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ __ASSERT_DEBUG(iContext.Node().ServiceProvider()==NULL, ConnPanic(KPanicExpectedNoServiceProvider));
+
+ TCFDataClient::TBindTo& bt = message_cast<TCFDataClient::TBindTo>(iContext.iMessage);
+ iContext.Node().AddClientL(bt.iNodeId, TClientType(TCFClientType::EServProvider, TCFClientType::EActive));
+
+ //If this is attach, we need to see if we are a monitor or not
+ TClientType clientType(TCFClientType::ECtrl);
+
+ TUint selPrefs = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity).SelectionPrefs().Flags();
+ if (selPrefs & TSelectionPrefs::EMonitor)
+ {
+ clientType.SetFlags(TCFClientType::EMonitor);
+ iContext.Node().iIsMonitor = ETrue;
+ }
+
+ // If it is an attach set the flag cause it is used by NetUPS to check if a JoinRequest comes from an RConnection::Attach
+ if (selPrefs & TSelectionPrefs::EAttach)
+ {
+ clientType.SetFlags(TCFClientType::EAttach);
+ }
+ iContext.iNodeActivity->PostRequestTo(bt.iNodeId,
+ TCFServiceProvider::TJoinRequest(iContext.NodeId(), clientType).CRef());
+ }
+
+DEFINE_SMELEMENT(ConnStates::TJoinReceivedSCpr, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TJoinReceivedSCpr::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ __ASSERT_DEBUG(iContext.iPeer == iContext.Node().ServiceProvider(), ConnPanic(KPanicExpectedNoServiceProvider));
+
+ TCFServiceProvider::TCommsBinderResponse& br = message_cast<TCFServiceProvider::TCommsBinderResponse>(iContext.iMessage);
+ iContext.Node().AddClientL(br.iNodeId, TClientType(TCFClientType::EServProvider, TCFClientType::EDefault));
+
+ //If this is attach, we need to see if we are a monitor or not
+ TCFClientType clientType(TCFClientType::ECtrl);
+
+ TUint selPrefs = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity).SelectionPrefs().Flags();
+ if (selPrefs & TSelectionPrefs::EMonitor)
+ {
+ clientType.SetFlags(TCFClientType::EMonitor);
+ }
+
+ // If it is an attach set the flag cause it is used by NetUPS to check if a JoinRequest comes from an RConnection::Attach
+ if (selPrefs & TSelectionPrefs::EAttach)
+ {
+ clientType.SetFlags(TCFClientType::EAttach);
+ }
+
+ iContext.iNodeActivity->PostRequestTo(br.iNodeId,
+ TCFServiceProvider::TJoinRequest(iContext.NodeId(), clientType).CRef());
+ }
+
+DEFINE_SMELEMENT(ConnStates::TJoinReceivedMcpr, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TJoinReceivedMcpr::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ __ASSERT_DEBUG(iContext.Node().ServiceProvider()==NULL, ConnPanic(KPanicExpectedNoServiceProvider));
+
+ TCFSelector::TSelectComplete& sc = message_cast<TCFSelector::TSelectComplete>(iContext.iMessage);
+ iContext.Node().AddClientL(sc.iNodeId,TClientType(TCFClientType::EServProvider, TCFClientType::EAvailabilityProvider));
+
+
+ iContext.iNodeActivity->PostRequestTo(sc.iNodeId,
+ TCFServiceProvider::TJoinRequest(iContext.NodeId(), TCFClientType(TCFClientType::ECtrl)).CRef());
+ }
+
+DEFINE_SMELEMENT(ConnStates::TRequestCommsBinder, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TRequestCommsBinder::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ RNodeInterface* sp = iContext.Node().ServiceProvider();
+ __ASSERT_DEBUG(sp, ConnPanic(KPanicNoServiceProvider));
+ iContext.iNodeActivity->PostRequestTo(*sp,
+ TCFServiceProvider::TCommsBinderRequest(TSubConnOpen::EAttachToDefault).CRef());
+ }
+
+DEFINE_SMELEMENT(ConnStates::TRequestCommsBinderFromMcpr, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TRequestCommsBinderFromMcpr::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider, TCFClientType::EAvailabilityProvider));
+ RNodeInterface* mcpr = iter[0];
+ __ASSERT_DEBUG(mcpr, ConnPanic(KPanicNoAvailabilityProvider));
+ iContext.iNodeActivity->PostRequestTo(*mcpr,
+ TCFServiceProvider::TCommsBinderRequest().CRef());
+ }
+
+DEFINE_SMELEMENT(ConnStates::TProcessBinderResponseForCpr, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TProcessBinderResponseForCpr::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ __ASSERT_DEBUG(iContext.Node().ServiceProvider()==NULL, ConnPanic(KPanicExpectedNoServiceProvider));
+
+ TCFServiceProvider::TCommsBinderResponse& br = message_cast<TCFServiceProvider::TCommsBinderResponse>(iContext.iMessage);
+
+ iContext.Node().AddClientL(br.iNodeId, TClientType(TCFClientType::EServProvider, TCFClientType::EActive));
+
+ //If this is attach, we need to see if we are a monitor or not
+ TCFClientType clientType;
+
+ TUint selPrefs = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity).SelectionPrefs().Flags();
+ if (selPrefs & TSelectionPrefs::EMonitor)
+ {
+ clientType.SetFlags(TCFClientType::EMonitor);
+ iContext.Node().iIsMonitor = ETrue;
+ }
+
+ if (selPrefs & TSelectionPrefs::EAttach)
+ {
+ clientType.SetFlags(TCFClientType::EAttach);
+ }
+
+ iContext.iNodeActivity->PostRequestTo(br.iNodeId,
+ TCFServiceProvider::TJoinRequest(iContext.NodeId(), clientType).CRef());
+ }
+
+DEFINE_SMELEMENT(ConnStates::TStartConnection, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TStartConnection::DoL()
+ {
+ RNodeInterface* cpr = iContext.Node().ServiceProvider();
+ __ASSERT_DEBUG(cpr, ConnPanic(KPanicNoServiceProvider));
+
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ iContext.iNodeActivity->PostRequestTo(*cpr, TCFServiceProvider::TStart().CRef());
+ }
+
+DEFINE_SMELEMENT(ConnStates::TErrorOrCancel, NetStateMachine::MStateFork, ConnStates::TContext)
+/**
+If the activity has been cancelled, return KCancelTag else return KErrorTag
+ */
+TInt ConnStates::TErrorOrCancel::TransitionTag()
+ {
+ if (iContext.Activity()->Error() == KErrCancel)
+ {
+ return ConnActivities::CStartAttachActivity::KCancelTag;
+ }
+ else
+ {
+ __ASSERT_DEBUG(iContext.Activity()->Error() != KErrNone, User::Panic(KSpecAssert_ESockSSockscnsts, 3)); // meant to be called in error conditions only
+ return KErrorTag;
+ }
+ }
+
+//
+//Attach
+DEFINE_SMELEMENT(ConnStates::TParseECNAttach, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TParseECNAttach::DoL()
+ {
+ __ASSERT_DEBUG((subsessmessage_cast<ECNAttach>(&iContext.iMessage)), ConnPanic(KPanicIncorrectMessage));
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ ConnActivities::CStartAttachActivity& ac = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity);
+
+ //Read preferences
+ const TUint KMaxConnectionInfoLength = 32;
+ TBuf8<KMaxConnectionInfoLength> info;
+ ac.ReadL(1,info);
+ if (info.Length() < KConnInfoPart)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ TUint monitorMode = (RConnection::TConnAttachType)ac.Int0() == RConnection::EAttachTypeMonitor?
+ TSelectionPrefs::EMonitor : 0;
+ // The attach flag should always be set since it is used by NetUPS to check if a JoinRequest comes from an RConnection::Attach
+ ac.SetSelectionFlags(monitorMode | TSelectionPrefs::EAttach);
+
+ TConnArgBase& connInfo = *((TConnArgBase*)&info[0]);
+ if (connInfo.Version() < KConnArgVersion3)
+ {
+ TConnectionInfo& connI = static_cast<TConnectionInfo&>(connInfo);
+ TCommDbConnPref pref;
+ pref.SetIapId(connI.iIapId);
+ ac.SelectionPrefs().SetPrefs(pref);
+ ac.SetSelectionScope(TSelectionPrefs::ESelectFromExisting | TSelectionPrefs::EExplicitConnection);
+ }
+ else
+ {
+ __ASSERT_DEBUG(connInfo.Version() == KConnArgVersion3, User::Panic(KSpecAssert_ESockSSockscnsts, 4)); //Currently no support for > KConnArgVersion3;
+ TConnProviderInfo& provinfo = static_cast<TConnProviderInfo&>(connInfo);
+ __ASSERT_DEBUG(iContext.Node().iTierId.iUid == provinfo.iInfo[0], User::Panic(KSpecAssert_ESockSSockscnsts, 5));
+ ac.SelectionPrefs().SetPrefs(TConnProviderInfoPref(provinfo));
+ ac.SetSelectionScope(TSelectionPrefs::ESelectFromExisting);
+ }
+ }
+
+DEFINE_SMELEMENT(ConnStates::TCompleteLegacyAttach, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TCompleteLegacyAttach::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ iContext.Node().iLegacyConnection.CompleteAttachL(static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity).SelectionPrefs());
+ }
+
+
+//
+//WaitForIncoming
+DEFINE_SMELEMENT(ConnStates::TRequestIncomingConnection, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TRequestIncomingConnection::DoL()
+ {
+ __ASSERT_DEBUG((subsessmessage_cast<ECNWaitForIncoming>(&iContext.iMessage)), ConnPanic(KPanicIncorrectMessage));
+ RNodeInterface* sp = iContext.Node().ServiceProvider();
+ User::LeaveIfError(sp ? KErrNone : KErrNotReady);
+
+ iContext.iNodeActivity->PostRequestTo(*sp,
+ TCFServiceProvider::TCommsBinderRequest(TSubConnOpen::EWaitForIncoming).CRef());
+ }
+
+DEFINE_SMELEMENT(ConnStates::TProcessIncomingConnection, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TProcessIncomingConnection::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ CSubConnection* waitingSubConn = iContext.Node().Session()->CSubConnectionFromHandle(static_cast<CESockClientActivityBase&>(*iContext.iNodeActivity).Int0());
+ User::LeaveIfError(waitingSubConn != NULL ? KErrNone : KErrCancel);
+
+ TCFServiceProvider::TCommsBinderResponse& binderResp = message_cast<TCFServiceProvider::TCommsBinderResponse>(iContext.iMessage);
+ iContext.iNodeActivity->PostRequestTo(waitingSubConn->Id(),
+ TCFDataClient::TBindTo(binderResp.iNodeId).CRef());
+ }
+
+
+//
+//Stop
+DEFINE_SMELEMENT(ConnStates::TSendStopConnection, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TSendStopConnection::DoL()
+ {
+ __ASSERT_DEBUG((subsessmessage_cast<ECNStop>(&iContext.iMessage)), ConnPanic(KPanicIncorrectMessage));
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ CESockClientActivityBase& ac = static_cast<CESockClientActivityBase&>(*iContext.iNodeActivity);
+
+ //Convert the received enum (the stop type) into an error code that will be passed to the interface clients
+ TInt stopCode = KErrCancel;
+ switch (ac.Int0())
+ {
+ case RConnection::EStopNormal:
+ stopCode = KErrCancel;
+ break;
+ case RConnection::EStopAuthoritative:
+ stopCode = KErrConnectionTerminated;
+ break;
+ default:
+ __ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockSSockscnsts, 6));
+ }
+
+ RNodeInterface* sp = iContext.Node().ServiceProvider();
+ if(sp)
+ { // We can only post the 'stop' if we've got a service provider and its not already leaving (e.g., gone down).
+ if (!(sp->Flags() & TClientType::ELeaving))
+ {
+ sp->PostMessage(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), TCFServiceProvider::TStop(stopCode).CRef());
+ }
+ else
+ {
+ MESH_LOG((KESockConnectionTag, _L8("ConnStates::TSendStopConnection:\tDoL - IGNORING POST!")));
+ }
+ }
+ else
+ { // Otherwise just set the activity idle and bail out.
+ iContext.Activity()->SetIdle();
+ }
+ }
+
+DEFINE_SMELEMENT(ConnStates::TConnectionSendStopSCPR, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TConnectionSendStopSCPR::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+
+ TInt stopCode = 0;
+
+ switch (static_cast<CESockClientActivityBase*>(iContext.iNodeActivity)->Int1())
+ {
+ case RConnection::EStopNormal:
+ stopCode = KErrCancel;
+ break;
+
+ case RConnection::EStopAuthoritative:
+ stopCode = KErrConnectionTerminated;
+ break;
+
+ default:
+ __ASSERT_DEBUG( false , User::Panic(KSpecAssert_ESockSSockscnsts, 7)); // CConnection should have verified the parameters before stopping the subconnection
+ }
+
+ // Send the stop message to the subconnection.
+ RNodeInterface* scpr = static_cast<CConnection&>(iContext.Node()).DefaultSubConnectionServiceProvider();
+ __ASSERT_DEBUG( scpr , User::Panic(KSpecAssert_ESockSSockscnsts, 8)); // subconnection must exist or the stop operation should not have been initiated
+ scpr->PostMessage(
+ TNodeCtxId(iContext.ActivityId(), iContext.NodeId()),
+ TCFServiceProvider::TStop(stopCode).CRef()
+ );
+ }
+
+DEFINE_SMELEMENT(ConnStates::TCancelStartOrAttachConnection, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TCancelStartOrAttachConnection::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+
+ if (iContext.Node().FindActivityById(ECFActivityStart))
+ {
+ RClientInterface::OpenPostMessageClose(
+ TNodeCtxId(ECNStart, iContext.NodeId()),
+ TNodeCtxId(ECNStart, iContext.NodeId()),
+ TEBase::TCancel().CRef());
+ }
+ else if (iContext.Node().FindActivityById(ECFActivityConnectionAttach))
+ {
+ RClientInterface::OpenPostMessageClose(
+ TNodeCtxId(ECNAttach, iContext.NodeId()),
+ TNodeCtxId(ECNAttach, iContext.NodeId()),
+ TEBase::TCancel().CRef());
+ }
+ }
+
+//
+//Close
+DEFINE_SMELEMENT(ConnStates::TDetachDataClients, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TDetachDataClients::DoL()
+ {
+ while (ETrue)
+ {
+ TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData));
+ RNodeInterface* client = iter[0];
+ if (client)
+ {
+#if defined(__GCCXML__)
+ CSubConnection& subconn = *reinterpret_cast<CSubConnection*>(&client->RecipientId().Node());
+#else
+ CSubConnection& subconn = *mcfnode_cast<CSubConnection>(&client->RecipientId().Node());
+#endif
+ iContext.Node().RemoveClient(subconn.Id());
+ subconn.RemoveClient(iContext.NodeId());
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+DEFINE_SMELEMENT(ConnStates::TStartOrAttachActive, NetStateMachine::MStateFork, ConnStates::TContext)
+TInt ConnStates::TStartOrAttachActive::TransitionTag()
+ {
+ if (iContext.Node().FindActivityById(ECFActivityStart) || iContext.Node().FindActivityById(ECFActivityConnectionAttach))
+ {
+ return MeshMachine::KActiveTag;
+ }
+ return KNoTag;
+ }
+
+DEFINE_SMELEMENT(ConnStates::TAwaitingGoneDown, NetStateMachine::MState, ConnStates::TContext)
+TBool ConnStates::TAwaitingGoneDown::Accept()
+ {
+ if (!iContext.iMessage.IsMessage<TCFControlClient::TGoneDown>())
+ {
+ return EFalse;
+ }
+
+ //TODO - fix this defect:
+ //1) TGoneDown should not be sent when stopping or closing
+ //2) FindActivityById(ECFActivityStop) is not safe
+ //3) why the condition iContext.Node().ServiceProvider()? Who can be sending TGoneDown if not the service provider?
+ bool stoppingOrClosing = iContext.Node().FindActivityById(ECFActivityStop) || iContext.Node().FindActivityById(ECFActivityDestroy);
+ if (!stoppingOrClosing && iContext.Node().ServiceProvider() &&
+ *iContext.Node().ServiceProvider() == iContext.iSender)
+ {
+ return ETrue;
+ }
+ iContext.iMessage.ClearMessageId();
+ return EFalse;
+ }
+
+DEFINE_SMELEMENT(ConnStates::TGenerateConnectionUpProgress, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TGenerateConnectionUpProgress::DoL()
+ {
+ TCFMessage::TStateChange msg(TStateChange(KConnectionUp, KErrNone));
+ RNodeInterface::OpenPostMessageClose(iContext.Node().Id(), iContext.Node().Id(), msg);
+ }
+
+DEFINE_SMELEMENT(ConnStates::TGenerateConnectionDownProgress, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TGenerateConnectionDownProgress::DoL()
+ {
+ // Do not self-post a message if there is a pending ConnectionClose activity. When the ConnectionGoingDown
+ // activity (calling this method) terminates, the ConnectionClose activity unparks (being synchronised
+ // against ConnectionGoingDown), the CConnection is destroyed, and the subsequent self-dispatch
+ // will panic.
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ TInt error = iContext.iNodeActivity->Error();
+
+ if (error == KErrNone && iContext.iMessage.IsMessage<TCFServiceProvider::TStopped>())
+ {
+ error = message_cast<TCFServiceProvider::TStopped>(iContext.iMessage).iValue;
+ }
+
+ __ASSERT_DEBUG(error != KErrNone, ConnPanic(KPanicIncorrectState));
+
+ if (iContext.Node().CountActivities(ECFActivityDestroy) == 0)
+ {
+ TCFMessage::TStateChange msg(TStateChange(KConnectionDown, error));
+ CConnection& cc = iContext.Node();
+ RNodeInterface::OpenPostMessageClose(cc.Id(), cc.Id(), msg);
+ }
+ }
+
+//
+//Progress & Progress Request
+DEFINE_SMELEMENT(ConnStates::TProcessStateChange, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TProcessStateChange::DoL()
+ {
+ TStateChange& progress = message_cast<TCFMessage::TStateChange>(iContext.iMessage).iStateChange;
+
+ //Check whether KDataTransferUnblocked is received and if yes, then traslate it to KConnectionUp (== KLinkLayerOpen)
+ // the log only sees the translated version, this goes into the queue, so it alright I suppose.
+ if (progress.iStage == KDataTransferUnblocked )
+ {
+ progress.iStage = KConnectionUp; // KLinkLayerOpen
+ }
+
+ LOG( ESockLog::Printf(KESockConnectionTag, _L("CConnection %08x:\tProgressNotification(TInt aStage %d, TInt aError %d)"),
+ &(iContext.Node()), progress.iStage, progress.iError) );
+
+ //Diagnostic assertion.
+ //If ECFActivityConnectionStateChangeRequest is running, it has not been
+ //presented with the TStateChange message (channel activity id != 0?) which is a serious mistake.
+ __ASSERT_DEBUG(iContext.Node().CountActivities(ECFActivityConnectionStateChangeRequest)==0, User::Panic(KSpecAssert_ESockSSockscnsts, 9));
+
+ CConnection& cc = iContext.Node();
+ if (cc.iLastProgress == progress)
+ {
+ return; //ignore this duplicate
+ }
+ cc.iLastProgress = progress;
+
+ if (progress.iError != KErrNone)
+ {
+ cc.iLastProgressError = progress; //Save last progress in error for use by LastProgressErrorL()
+ }
+
+ #ifdef ESOCK_LOGGING_ACTIVE
+ // Check to see if the progress queue is full causing older progress to be discarded.
+ // This has the potential to cause problems if a critical progress item is lost.
+ // Normally the queue is large enough such that this doesn't happen but this log entry
+ // serves as a warning if it ever does.
+ if( cc.iProgressQueue.IsFull() )
+ {
+ LOG( ESockLog::Printf(KESockConnectionTag, _L("CConnection %08x:\tThe maximum progress queue size of %d has been exceeded - discarding old progress to make space for new item"), this, KMaxProgressQueueLength); )
+ }
+ #endif
+
+ //Add the progress to queue
+ cc.iProgressQueue.Enque(progress);
+ }
+
+DEFINE_SMELEMENT(ConnStates::TProcessProgressRequest, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TProcessProgressRequest::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ CESockClientActivityBase& ac = static_cast<CESockClientActivityBase&>(*iContext.iNodeActivity);
+ TUint selectedProgressStage = ac.Int1();
+
+ TStateChange progress;
+ TBool found = EFalse;
+
+ //Are we here as a result of receiving TStateChange (rather than ECNProgressNotification)?
+ TCFMessage::TStateChange* msg = message_cast<TCFMessage::TStateChange>(&iContext.iMessage);
+ if (msg)
+ { //Yes, we have been triggered by a TStateChange message
+ //Check if this is the progress we are waiting for, otherwise dump the progress
+ //Check whether KDataTransferUnblocked is received and if yes, then traslate it to KConnectionUp (== KLinkLayerOpen)
+ if (msg->iStateChange.iStage == KDataTransferUnblocked )
+ {
+ msg->iStateChange.iStage = KConnectionUp; // KLinkLayerOpen
+ }
+ if (selectedProgressStage == KConnProgressDefault
+ || selectedProgressStage == msg->iStateChange.iStage
+ || KErrNone != msg->iStateChange.iError)
+ {
+ progress = msg->iStateChange;
+ found = ETrue;
+ }
+ }
+ else
+ { //No, we must have been triggered by a ECNProgressNotification message
+ __ASSERT_DEBUG((subsessmessage_cast<ECNProgressNotification>(&iContext.iMessage)), ConnPanic(KPanicIncorrectMessage));
+
+ //Process the queue looking for the progress of interest
+ found = iContext.Node().iProgressQueue.Deque(progress);
+ if (found && selectedProgressStage != KConnProgressDefault)
+ {
+ // For a selected progress request, dequeue entries until we find one which
+ // matches the criteria. If we dequeue all entries, fall through without
+ // completing the message. It it not considered useful to retain un-matching
+ // entries on the queue if a selected progress request is pending.
+ while (found)
+ {
+ if (progress.iStage == selectedProgressStage || progress.iError != KErrNone)
+ {
+ break;
+ }
+ found = iContext.Node().iProgressQueue.Deque(progress);
+ }
+ }
+ }
+
+ if (found)
+ {
+ //We have found a progress of interest, finish
+ TPckg<TStateChange> progressPkg(progress);
+ ac.WriteL(0,progressPkg);
+ ac.SetIdle(); //We are done
+ }
+ }
+
+
+//
+//Legacy enumeration
+DEFINE_SMELEMENT(ConnStates::TAwaitingEnumResponse, NetStateMachine::MState, ConnStates::TContext)
+TBool ConnStates::TAwaitingEnumResponse::Accept()
+ {
+ return iContext.iMessage.IsMessage<TCFInternalEsock::TLegacyConnectionEnumResponse>();
+ }
+
+DEFINE_SMELEMENT(ConnStates::TProcessEnumResponse, NetStateMachine::MStateTransition, ConnStates::TContext)
+void ConnStates::TProcessEnumResponse::DoL()
+ {
+ TCFInternalEsock::TLegacyConnectionEnumResponse& msg = message_cast<TCFInternalEsock::TLegacyConnectionEnumResponse>(iContext.iMessage);
+ iContext.Node().iLegacyConnection.CompleteDataPlaneEnumeration(address_cast<TNodeId>(iContext.iSender), msg.iValue1, reinterpret_cast<HBufC8*>(msg.iValue2), msg.iValue3);
+ }
+
+
+//
+//CStartAttachActivity
+MeshMachine::CNodeActivityBase* ConnActivities::CStartAttachActivity::NewWaitForIncomingConnectionActivityL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ //Leave from here will complete the client message
+ User::LeaveIfError(aNode.CountActivities(ECFActivityStart)? KErrInUse : KErrNone);
+ User::LeaveIfError(aNode.CountActivities(ECFActivityConnectionAttach)? KErrInUse : KErrNone);
+
+ // When waiting for an incoming connection we will additionally check that the connection is already started
+ User::LeaveIfError(aNode.CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider)) > 0 ? KErrNone : KErrNotReady );
+
+ return new (ELeave) ConnActivities::CStartAttachActivity(aActivitySig,aNode);
+ }
+
+MeshMachine::CNodeActivityBase* ConnActivities::CStartAttachActivity::NewStartConnectionActivityL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ //Leave from here will complete the client message
+ User::LeaveIfError(aNode.CountActivities(ECFActivityStart)? KErrInUse : KErrNone);
+ User::LeaveIfError(aNode.CountActivities(ECFActivityConnectionAttach)? KErrInUse : KErrNone);
+
+ // When starting a connection we will additionally check that the connection is not already started
+ User::LeaveIfError(aNode.CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider)) > 0 ? KErrInUse : KErrNone);
+
+ return new (ELeave) ConnActivities::CStartAttachActivity(aActivitySig,aNode);
+ }
+
+ConnActivities::CStartAttachActivity::~CStartAttachActivity()
+ {
+ // Call ABindingActivity base class to send TBindToComplete (before TDestroy)
+ FinalReplyToOriginator(KErrAbort);
+
+ if (!iCSR.IsNull())
+ {
+#ifndef __GCCXML__
+ RNodeInterface::OpenPostMessageClose(TNodeCtxId(ActivityId(), iNode.Id()), iCSR, TEChild::TDestroy().CRef());
+#endif
+ iCSR.SetNull(); // = TNodeId::NullCommsId();
+ }
+
+ if(iConnPrefList)
+ {
+ while(iConnPrefList->Count() != 0)
+ {
+ SMetaData* pref = (*iConnPrefList)[0];
+ if(pref != NULL)
+ delete pref;
+ iConnPrefList->Remove(0);
+ }
+
+ delete iConnPrefList;
+ iConnPrefList = NULL;
+ }
+ }
+
+
+TBool ConnActivities::CStartAttachActivity::Next(MeshMachine::TNodeContextBase& aContext)
+ {
+ // If the connection start preferences were set the activity will have completed the initial IPC and will
+ // now be waiting upon the async ECNStart IPC to arrive before proceeding. The TCFInternalEsock::TSubSess
+ // message will use the IPC number in the activity id part of aContext. MatchSender() will expect the
+ // activity Id and so will never give a match. Here we ensure that our second IPC is matched and accepted.
+
+ TCFInternalEsock::TSubSess* msg = message_cast<TCFInternalEsock::TSubSess>(&aContext.iMessage);
+ if (!msg || msg->iMessage.Function() != ECNStart)
+ {
+ return CNodeActivityBase::Next(aContext);
+ }
+
+ MESH_LOG((KESockConnectionTag, _L8("CStartAttachActivity::Next:\tAccepted ECNStart IPC after ECNSetStartPrefs")));
+ TBool nextRet = ACore::Next(&aContext);
+ if(nextRet)
+ {
+ MESH_LOG_ACTIVITY_EXT(KESockConnectionTag, this, &aContext, (_L8("CStartAttachActivity::Next:\tNext->transition")));
+ }
+ return nextRet;
+ }
+
+
+DEFINE_SMELEMENT(CStartAttachActivity::TNoTagOrStartPrefsSetTag, NetStateMachine::MStateFork, ConnStates::TContext)
+TInt CStartAttachActivity::TNoTagOrStartPrefsSetTag::TransitionTag()
+ {
+ CStartAttachActivity& ac = static_cast<CStartAttachActivity&>(*iContext.iNodeActivity);
+
+ if (ac.Function() == ECNSetStartPrefs)
+ {
+ return CStartAttachActivity::KStartPrefsSetTag | NetStateMachine::EForward;
+ }
+ return MeshMachine::KNoTag | NetStateMachine::EForward;
+ }
+
+DEFINE_SMELEMENT(CStartAttachActivity::TNoTagOrLegacyAttach, NetStateMachine::MStateFork, ConnStates::TContext)
+TInt CStartAttachActivity::TNoTagOrLegacyAttach::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ const TConnPref& cp = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity).SelectionPrefs().Prefs();
+ if (cp.ExtensionId()==TConnPref::EConnPrefCommDb)
+ {//this is legacy attach
+ return CStartAttachActivity::KExecuteLegacyAttach;
+ }
+ return KNoTag;
+ }
+
+DEFINE_SMELEMENT(CStartAttachActivity::TNoTagOrWaitAvailable, NetStateMachine::MStateFork, ConnStates::TContext)
+TInt CStartAttachActivity::TNoTagOrWaitAvailable::TransitionTag()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ ConnActivities::CStartAttachActivity& activity = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity);
+
+ TConnPrefList* prefsList = activity.ConnPrefList();
+ if (prefsList)
+ {
+ TBool startAuto = EFalse;
+ for (TInt i = 0; i < prefsList->Count(); i++)
+ {
+ TConnAutoStartPref* pref = smetadata_cast<TConnAutoStartPref>((*prefsList)[i]);
+ if(pref)
+ {
+ startAuto = ETrue;
+ break;
+ }
+ }
+ if (startAuto)
+ {
+ TBool &autoStart = activity.AutoStartPresent();
+ autoStart = ETrue;
+ iContext.iNodeActivity->ClearPostedTo();
+ return KWaitAvailable;
+ }
+
+ }
+ return KNoTag;
+ }
+
+DEFINE_SMELEMENT(CStartAttachActivity::TErrorTagOrWaitAvailableBackward, NetStateMachine::MStateFork, ConnStates::TContext)
+TInt CStartAttachActivity::TErrorTagOrWaitAvailableBackward::TransitionTag()
+ {
+ __ASSERT_DEBUG((message_cast<TEBase::TError>(&iContext.iMessage)), ConnPanic(KPanicIncorrectMessage));
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ ConnActivities::CStartAttachActivity& activity = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity);
+
+ if (!activity.AutoStartPresent())
+ {
+ return KErrorTag;
+ }
+
+ TEBase::TError& msg = message_cast<TEBase::TError>(iContext.iMessage);
+ if (msg.iValue == KErrUmtsMaxNumOfContextExceededByNetwork ||
+ msg.iValue == KErrUmtsMaxNumOfContextExceededByPhone)
+ {
+ return KWaitAvailable | NetStateMachine::EBackward;
+ }
+ else
+ {
+ return KErrorTag;
+ }
+ }
+
+DEFINE_SMELEMENT(CStartAttachActivity::TAwaitingAvailableOrError, NetStateMachine::MState, TContext)
+TInt CStartAttachActivity::TAwaitingAvailableOrError::Accept()
+ {
+ if (iContext.iMessage.IsMessage<TCFAvailabilityControlClient::TAvailabilityNotification>())
+ {
+ TCFAvailabilityControlClient::TAvailabilityNotification& msg = message_cast<TCFAvailabilityControlClient::TAvailabilityNotification>(iContext.iMessage);
+ if (msg.iAvailabilityStatus.Score() > TAvailabilityStatus::EMinAvailabilityScore)
+ {
+ RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.iSender,
+ TEBase::TCancel().CRef());
+ return ETrue;
+ }
+ return EFalse;
+ }
+ else if (iContext.iMessage.IsMessage<TEBase::TError>())
+ {
+ TEBase::TError* msg = message_cast<TEBase::TError>(&iContext.iMessage);
+ iContext.iNodeActivity->SetError(msg->iValue);
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+
+DEFINE_SMELEMENT(CStartAttachActivity::TSubscribeForAvailability, NetStateMachine::MStateTransition, TContext)
+void CStartAttachActivity::TSubscribeForAvailability::DoL()
+ {
+ __ASSERT_DEBUG(iContext.iNodeActivity, ConnPanic(KPanicNoActivity));
+ ConnActivities::CStartAttachActivity& activity = static_cast<ConnActivities::CStartAttachActivity&>(*iContext.iNodeActivity);
+
+ TConnPrefList* connPrefList = activity.ConnPrefList();
+ if (connPrefList && connPrefList->Count()>0)
+ {
+ TBool startAuto = EFalse;
+ for (TInt i = 0; i < connPrefList->Count(); i++)
+ {
+ TConnAutoStartPref* pref = smetadata_cast<TConnAutoStartPref>((*connPrefList)[i]);
+ if(pref)
+ {
+ startAuto = ETrue;
+ break;
+ }
+ }
+ if (startAuto)
+ {
+ TAvailabilitySubscriptionOptions subscriptionOptions;
+ TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider, TCFClientType::EAvailabilityProvider));
+ RNodeInterface* mcpr = iter[0];
+ __ASSERT_DEBUG(mcpr, ConnPanic(KPanicNoAvailabilityProvider));
+ RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), mcpr->RecipientId(),
+ TCFAvailabilityProvider::TAvailabilityNotificationRegistration(subscriptionOptions).CRef());
+ }
+ }
+ }
+
+DEFINE_SMELEMENT(CStartAttachActivity::TAwaitingSelectCompleteOrError, NetStateMachine::MState, TContext)
+TInt CStartAttachActivity::TAwaitingSelectCompleteOrError::Accept()
+ {
+ if (iContext.iMessage.IsMessage<TCFSelector::TSelectComplete>())
+ {
+ return ETrue;
+ }
+ else if(iContext.iMessage.IsMessage<TEBase::TError>())
+ {
+ TEBase::TError& errorMsg = message_cast<TEBase::TError>(iContext.iMessage);
+ iContext.Activity()->SetError(errorMsg.iValue);
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+
+#ifdef SYMBIAN_NETWORKING_UPS
+
+DEFINE_SMELEMENT(CStartAttachActivity::TSendPolicyCheckRequestToServiceProvider, NetStateMachine::MStateTransition, ConnStates::TContext)
+void CStartAttachActivity::TSendPolicyCheckRequestToServiceProvider::DoL()
+ {
+ MPlatsecApiExt* platsec = NULL;
+ iContext.Node().ReturnInterfacePtrL(platsec); // from CConnection
+ // TODO: what to do on an error (see TODO below)
+ __ASSERT_DEBUG(platsec, User::Panic(KSpecAssert_ESockSSockscnsts, 18));
+
+ TProcessId processId;
+ TThreadId threadId;
+ TInt err = platsec->GetProcessAndThreadId(processId, threadId);
+ if (err != KErrNone)
+ {
+ const TNodeId& self = iContext.Node().Id();
+ iContext.Node().SelfInterface().PostMessage(self, TEBase::TError(err).CRef());
+ iContext.Activity()->ClearPostedTo();
+ }
+ else
+ {
+ // KErrCorrupt is a default value for the platsec result. The platsec result must be filled-in by the provider
+ // and not ESock because only the provider knows the (technology specific) policy to check against.
+ // Destination address is not valid in this context, so it is just a null descriptor.
+
+ const TPolicyCheckRequestParams params(processId, threadId, KErrCorrupt, KNullDesC8(), TUpsDestinationAddrType(ETNone), iContext.NodeId());
+
+ const UpsMessage::TPolicyCheckRequest checkMsg(params);
+
+ RNodeInterface* serviceProvider = iContext.Node().ServiceProvider();
+
+ __ASSERT_DEBUG(serviceProvider, User::Panic(KSpecAssert_ESockSSockscnsts, 19));
+ iContext.Activity()->PostRequestTo(*serviceProvider, checkMsg);
+ }
+ }
+
+DEFINE_SMELEMENT(CStartAttachActivity::TNoTagOrUpsErrorTag, NetStateMachine::MStateFork, ConnStates::TContext)
+TInt CStartAttachActivity::TNoTagOrUpsErrorTag::TransitionTag()
+ {
+ UpsMessage::TPolicyCheckResponse* policyCheckResponseMsg = message_cast<UpsMessage::TPolicyCheckResponse>(&iContext.iMessage);
+ if (policyCheckResponseMsg && policyCheckResponseMsg->iValue != KErrNone)
+ {
+ iContext.Activity()->SetError(policyCheckResponseMsg->iValue);
+ return KUpsErrorTag;
+ }
+ else
+ {
+ TEBase::TError* errorMsg = message_cast<TEBase::TError>(&iContext.iMessage);
+ // TODO: there is already code for this isn't there? A template that checks for TError and
+ // sets the activity in error?
+ if (errorMsg)
+ {
+ iContext.Activity()->SetError(errorMsg->iValue);
+ return KUpsErrorTag;
+ }
+ }
+ return KNoTag;
+ }
+#endif
+
+//
+// CTierManagerActivity
+
+MeshMachine::CNodeActivityBase* ConnActivities::CTierManagerActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ return new(ELeave) ConnActivities::CTierManagerActivity(aActivitySig, aNode);
+ }
+
+// States
+
+DEFINE_SMELEMENT(CTierManagerActivity::TAwaitingTierManager, NetStateMachine::MState, TContext)
+TInt CTierManagerActivity::TAwaitingTierManager::Accept()
+ {
+ if(iContext.iMessage.IsMessage<TCFFactory::TPeerFoundOrCreated>())
+ {
+ TCFFactory::TPeerFoundOrCreated& msg = message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage);
+ iContext.Activity()->iTierManager = msg.iNodeId;
+ iContext.Activity()->ClearPostedTo();
+
+ return ETrue;
+ }
+ else if(iContext.iMessage.IsMessage<TEBase::TCancel>())
+ {
+ iContext.Activity()->SetError(KErrCancel);
+
+ return ETrue;
+ }
+ else if(iContext.iMessage.IsMessage<TEBase::TError>())
+ {
+ // Register the error
+ TEBase::TError& errorMsg = message_cast<TEBase::TError>(iContext.iMessage);
+ iContext.Activity()->SetError(errorMsg.iValue);
+
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+DEFINE_SMELEMENT(CTierManagerActivity::TAwaitingJoinComplete, NetStateMachine::MState, TContext)
+TInt CTierManagerActivity::TAwaitingJoinComplete::Accept()
+ {
+ if(iContext.iMessage.IsMessage<TCFPeer::TJoinComplete>())
+ {
+ return ETrue;
+ }
+ else if(iContext.iMessage.IsMessage<TEBase::TCancel>())
+ {
+ iContext.Activity()->SetError(KErrCancel);
+
+ return ETrue;
+ }
+ else if(iContext.iMessage.IsMessage<TEBase::TError>())
+ {
+ // Register the error
+ TEBase::TError& errorMsg = message_cast<TEBase::TError>(iContext.iMessage);
+ iContext.Activity()->SetError(errorMsg.iValue);
+
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+// Transitions
+
+DEFINE_SMELEMENT(CTierManagerActivity::TFindTierManager, NetStateMachine::MStateTransition, TContext)
+void CTierManagerActivity::TFindTierManager::DoL()
+ {
+ __ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+ // Find out if the tier UID has been set.
+ TBool tierUidIsNull = (iContext.Activity()->iTierUid == TUid::Null());
+
+ // Panic in UDEB, Leave in UREL. The tier UID should be set in the derived
+ // class's constructor
+ __ASSERT_DEBUG(!tierUidIsNull, User::Panic(KSpecAssert_ESockSSockscnsts, 10));
+ User::LeaveIfError(tierUidIsNull ? KErrNotReady : KErrNone);
+ TAlwaysFindFactoryQuery query;
+ RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), SockManGlobals::Get()->GetPlaneFC(TCFPlayerRole(TCFPlayerRole::ETierMgrPlane)),
+ TCFFactory::TFindOrCreatePeer(TCFPlayerRole::ETierMgrPlane, iContext.Activity()->iTierUid, &query).CRef());
+ }
+
+DEFINE_SMELEMENT(CTierManagerActivity::TJoinTierManager, NetStateMachine::MStateTransition, TContext)
+void CTierManagerActivity::TJoinTierManager::DoL()
+ {
+ __ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+ RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.Activity()->iTierManager,
+ TCFServiceProvider::TJoinRequest(iContext.NodeId(), TClientType(TCFClientType::EAdministrative)).CRef());
+
+ iContext.Node().AddClientL(iContext.Activity()->iTierManager, TClientType(TCFClientType::EServProvider));
+ }
+
+// This solely exists separately from the other identical-looking version
+// in this file
+// ("AllInterfaceNotificationActivity::TLeaveTierManager::DoL()") because
+// the activities referenced by its TContext have iTierManager
+// at different offsets. This is because they have different parent
+// classes and, as such, have different member variable.
+//
+// The terrible thing is, this is usable in the other place,
+// and builds without complaint... then explodes when it tries
+// to send messages to a garbage iTierManager.
+//
+// TAKE CARE OF IT!!!
+DEFINE_SMELEMENT(CTierManagerActivity::TLeaveTierManager, NetStateMachine::MStateTransition, TContext)
+void CTierManagerActivity::TLeaveTierManager::DoL()
+ {
+ __ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+ RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.Activity()->iTierManager,
+ TEChild::TLeft().CRef());
+
+ iContext.Node().RemoveClient(iContext.Activity()->iTierManager);
+ }
+
+//
+// CAllInterfaceNotificationActivity
+
+CNodeActivityBase* ConnActivities::CAllInterfaceNotificationActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ return new (ELeave) ConnActivities::CAllInterfaceNotificationActivity(aActivitySig, aNode);
+ }
+
+ConnActivities::CAllInterfaceNotificationActivity::~CAllInterfaceNotificationActivity()
+ {
+ //Remove the only client here
+ RNodeInterface* aux = iNode.GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EAux));
+ if (aux)
+ {
+ iNode.RemoveClient(aux->RecipientId());
+ }
+ delete iAllInterfaceNotificationWorker; //delete this node (why via iAllInterfaceNotificationWorker??)
+ }
+
+// States
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TAwaitingStart, NetStateMachine::MState, TContext)
+TInt AllInterfaceNotificationActivity::TAwaitingStart::Accept()
+ {
+ return iContext.iMessage.IsMessage<TCFServiceProvider::TStart>();
+ }
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TAwaitingTierManager, NetStateMachine::MState, TContext)
+TInt AllInterfaceNotificationActivity::TAwaitingTierManager::Accept()
+ {
+ if(iContext.iMessage.IsMessage<TCFFactory::TPeerFoundOrCreated>())
+ {
+ TCFFactory::TPeerFoundOrCreated& msg = message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage);
+ iContext.Activity()->iTierManager = msg.iNodeId;
+ iContext.Activity()->ClearPostedTo();
+
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TAwaitingJoinComplete, NetStateMachine::MState, TContext)
+TInt AllInterfaceNotificationActivity::TAwaitingJoinComplete::Accept()
+ {
+ return iContext.iMessage.IsMessage<TCFPeer::TJoinComplete>();
+ }
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TAwaitingLinkNotification, NetStateMachine::MState, TContext)
+TInt AllInterfaceNotificationActivity::TAwaitingLinkNotification::Accept()
+ {
+ return (iContext.iMessage.IsMessage<TCFTierStatusProvider::TTierNotification>() ||
+ iContext.iMessage.IsMessage<TEBase::TCancel>() ||
+ iContext.iMessage.IsMessage<TEBase::TError>() );
+ }
+
+void AllInterfaceNotificationActivity::TAwaitingLinkNotification::Cancel()
+ {
+ __ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockSSockscnsts, 11));
+ }
+
+
+// for shutdown
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TAwaitingLinkNotificationError, NetStateMachine::MState, TContext)
+TInt AllInterfaceNotificationActivity::TAwaitingLinkNotificationError::Accept()
+ {
+ if(iContext.iMessage.IsMessage<TCFTierStatusProvider::TTierNotification>())
+ {
+ // we're already shutting down. so have detached from CConnection.
+ // so we have to delete the enclosed object instead.
+ LOG( ESockLog::Printf(KESockConnectionTag, _L("AllInterfaceNotification received bundle when already shutting down so deleting it")));
+ TCFTierStatusProvider::TTierNotification& msg = message_cast<TCFTierStatusProvider::TTierNotification>(iContext.iMessage);
+ msg.iBundle->Close();
+ iContext.iMessage.ClearMessageId();
+ }
+ else if(iContext.iMessage.IsMessage<TEBase::TCancel>())
+ {
+ LOG( ESockLog::Printf(KESockConnectionTag, _L("AllInterfaceNotification received TCancel when already shutting down so discarding it")));
+ iContext.iMessage.ClearMessageId();
+ }
+
+ return iContext.iMessage.IsMessage<TEBase::TError>();
+ }
+
+
+// Transitions
+
+DEFINE_SMELEMENT(ConnectionGoingDownActivity::TStoreGoneDownError, NetStateMachine::MStateTransition, TContext)
+void ConnectionGoingDownActivity::TStoreGoneDownError::DoL()
+ {
+ __ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+ TCFControlClient::TGoneDown& goneDownMessage = message_cast<TCFControlClient::TGoneDown>(iContext.iMessage);
+ LOG( ESockLog::Printf(KESockConnectionTag, _L("TStoreGoneDownError. error:%d"), goneDownMessage.iValue1));
+ iContext.Activity()->SetError(goneDownMessage.iValue1);
+ }
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TAddClient, NetStateMachine::MStateTransition, TContext)
+void AllInterfaceNotificationActivity::TAddClient::DoL()
+ {
+ __ASSERT_DEBUG(iContext.Activity() == NULL, ConnPanic(KPanicNoActivity));
+ __ASSERT_DEBUG(iContext.iPeer == NULL, User::Panic(KSpecAssert_ESockSSockscnsts, 12));
+ iContext.iPeer = iContext.Node().AddClientL(address_cast<TNodeId>(iContext.iSender), TClientType(TCFClientType::EAux));
+ }
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TFindTierManager, NetStateMachine::MStateTransition, TContext)
+void AllInterfaceNotificationActivity::TFindTierManager::DoL()
+ {
+ __ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+ // Find out if the tier UID has been set.
+ TBool tierUidIsNull = (iContext.Activity()->iTierUid == TUid::Null());
+
+ // Panic in UDEB, Leave in UREL. The tier UID should be set in the derived
+ // class's constructor
+ __ASSERT_DEBUG(!tierUidIsNull, User::Panic(KSpecAssert_ESockSSockscnsts, 13));
+ User::LeaveIfError(tierUidIsNull ? KErrNotReady : KErrNone);
+
+ TAlwaysFindFactoryQuery query;
+ RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), SockManGlobals::Get()->GetPlaneFC(TCFPlayerRole(TCFPlayerRole::ETierMgrPlane)),
+ TCFFactory::TFindOrCreatePeer(TCFPlayerRole::ETierMgrPlane, iContext.Activity()->iTierUid, &query).CRef());
+ }
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TJoinTierManager, NetStateMachine::MStateTransition, TContext)
+void AllInterfaceNotificationActivity::TJoinTierManager::DoL()
+ {
+ __ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+
+ RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.Activity()->iTierManager,
+ TCFServiceProvider::TJoinRequest(iContext.NodeId(), TClientType(TCFClientType::EAdministrative)).CRef());
+
+ iContext.Node().AddClientL(iContext.Activity()->iTierManager, TClientType(TCFClientType::EServProvider));
+ }
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TStartLinkNotification, NetStateMachine::MStateTransition, TContext)
+void AllInterfaceNotificationActivity::TStartLinkNotification::DoL()
+ {
+ __ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+ CConnectionServParameterBundle* queryBundle = CConnectionServParameterBundle::NewL();
+ CleanupStack::PushL(queryBundle);
+ CRefCountOwnedParameterBundle* bundleOwner = new(ELeave)CRefCountOwnedParameterBundle(queryBundle);
+ CleanupStack::Pop();
+ bundleOwner->Open();
+ CleanupClosePushL(*bundleOwner);
+
+ CParameterSetContainer* psc = CParameterSetContainer::NewL(*queryBundle);
+
+ // Set up a status filter for connected access points only
+ TAccessPointStatusFilter availFilter;
+ availFilter.Configured(EAccessPointFlagIgnore);
+ availFilter.Restricted(EAccessPointFlagIgnore);
+ availFilter.Available(EAccessPointFlagIgnore);
+ availFilter.Started(EAccessPointFlagIgnore);
+ availFilter.Active(EAccessPointFlagMatchAny);
+ queryBundle->AddMatchConditionL(availFilter);
+ queryBundle->AddParameterSetToReturnL(XAccessPointGenericParameterSet::Type());
+ queryBundle->AddParameterSetToReturnL(XIpProtoAccessPointParameterSet::Type());
+
+ const CAllInterfaceNotificationWorker* worker = iContext.Activity()->iAllInterfaceNotificationWorker;
+ const RMessage2* rm2 = &(iContext.Activity()->iAllInterfaceNotificationWorker->iConnection.Message());
+
+ RClientInterface::OpenPostMessageClose(worker->Id(), iContext.Activity()->iTierManager,
+ TCFTierStatusProvider::TTierNotificationRegistration(bundleOwner, rm2).CRef());
+ CleanupStack::Pop(); // bundleOwner
+ }
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TEnqueueNotification, NetStateMachine::MStateTransition, TContext)
+void AllInterfaceNotificationActivity::TEnqueueNotification::DoL()
+ {
+ __ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+ TCFTierStatusProvider::TTierNotification& msg = message_cast<TCFTierStatusProvider::TTierNotification>(iContext.iMessage);
+
+ __ASSERT_DEBUG(msg.iBundle, User::Panic(KSpecAssert_ESockSSockscnsts, 14));
+ if(msg.iBundle->PtrL()->CountParamSetContainers() > 0)
+ {
+ TInt i = 0;
+ TBool found = EFalse;
+ while(const CConnectionServParameterSetContainer* container = static_cast<const CConnectionServParameterSetContainer*>(msg.iBundle->Ptr()->GetParamSetContainer(i++)))
+ {
+ const XAccessPointGenericParameterSet* status = XAccessPointGenericParameterSet::FindInParamSetContainer(*container);
+
+ TConnInterfaceState interfaceState;
+ if (status->AccessPointStatus().Active() == ConnectionServ::EAccessPointFlagTrue)
+ {
+ interfaceState = EInterfaceUp;
+ }
+ else
+ {
+ interfaceState = EInterfaceDown;
+ }
+
+ const XIpProtoAccessPointParameterSet* ipApParams = XIpProtoAccessPointParameterSet::FindInParamSetContainer(*container);
+// ASSERT(ipApParams);
+ if (ipApParams) // commsdat might be broken so XIpProtoAccessPointParameterSet not available
+ {
+ TConnectionInfo connectionInfo(ipApParams->IapId(), ipApParams->NetworkId());
+
+ TInterfaceNotification notification = { connectionInfo, interfaceState };
+
+ iContext.Node().iConnection.iLegacyConnection.iNotificationQueue.Enque(notification);
+
+ found = ETrue;
+ }
+ }
+ if (found)
+ iContext.Node().iConnection.iLegacyConnection.CompleteAllInterfaceNotificationL(KErrNone);
+
+ }
+
+ msg.iBundle->Close();
+ }
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TCancelLinkNotification, NetStateMachine::MStateTransition, TContext)
+void AllInterfaceNotificationActivity::TCancelLinkNotification::DoL()
+ {
+ __ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+ TNodeId goo = iContext.Activity()->iTierManager;
+
+ const CAllInterfaceNotificationWorker* worker = iContext.Activity()->iAllInterfaceNotificationWorker;
+
+ RNodeInterface::OpenPostMessageClose(worker->Id(), iContext.Activity()->iTierManager,
+ TEBase::TCancel().CRef());
+ }
+
+// This solely exists separately from the other identical-looking version
+// in this file ("CTierManagerActivity::TLeaveTierManager::DoL()") because
+// the activities referenced by its TContext have iTierManager
+// at different offsets. This is because they have different parent
+// classes and, as such, have different member variable.
+//
+// The terrible thing is, this is usable in the other place,
+// and builds without complaint... then explodes when it tries
+// to send messages to a garbage iTierManager.
+//
+// TAKE CARE OF IT!!!
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TLeaveTierManager, NetStateMachine::MStateTransition, TContext)
+void AllInterfaceNotificationActivity::TLeaveTierManager::DoL()
+ {
+ __ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+ RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.Activity()->iTierManager,
+ TEChild::TLeft().CRef());
+
+ iContext.Node().RemoveClient(iContext.Activity()->iTierManager);
+ }
+
+DEFINE_SMELEMENT(AllInterfaceNotificationActivity::TSendErrorToConnection, NetStateMachine::MStateTransition, TContext)
+void AllInterfaceNotificationActivity::TSendErrorToConnection::DoL()
+ {
+ // Send a TError to the CConnection to complete the shutdown handshake.
+ RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.Node().iConnection.Id(), TEBase::TError(iContext.Activity()->KickOffMessageId(), KErrCancel).CRef());
+ }
+
+DEFINE_SMELEMENT(TNoTagOrCancelAllInterfaceWorker, NetStateMachine::MStateFork, TContext)
+TInt TNoTagOrCancelAllInterfaceWorker::TransitionTag()
+ {
+ // If this CConnection has an AllInterfaceNotificationWorker, return KCancelAllInterfaceWorker else return KNoTag.
+ AConnectionLegacy& cl = iContext.Node().iLegacyConnection;
+ return cl.iAllInterfaceNotificationWorker.IsNull() ? KNoTag : KCancelAllInterfaceWorker;
+ }
+
+DEFINE_SMELEMENT(TCancelAllInterfaceNotificationWorker, NetStateMachine::MStateTransition, TContext)
+void TCancelAllInterfaceNotificationWorker::DoL()
+ {
+ CConnection& cc = iContext.Node();
+ AConnectionLegacy& cl = cc.iLegacyConnection;
+ // If this CConnection has an AllInterfaceNotificationWorker, send a TCancel to it to begin
+ // the shutdown handshake.
+ if(!cl.iAllInterfaceNotificationWorker.IsNull())
+ {
+ TNodeCtxId dest(ECFActivityConnectionAllInterfaceNotification, cl.iAllInterfaceNotificationWorker);
+ RNodeInterface::OpenPostMessageClose(cc.Id(), dest, TEBase::TCancel().CRef());
+ cl.iAllInterfaceNotificationWorker.SetNull();
+ }
+ }
+
+//
+// CEnumerateConnectionsActivity
+
+MeshMachine::CNodeActivityBase* ConnActivities::CEnumerateConnectionsActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+ {
+ return new(ELeave) ConnActivities::CEnumerateConnectionsActivity(aActivitySig, aNode);
+ }
+
+// States
+
+DEFINE_SMELEMENT(EnumerateConnectionsActivity::TAwaitingTierStatus, NetStateMachine::MState, TContext)
+TInt EnumerateConnectionsActivity::TAwaitingTierStatus::Accept()
+ {
+ TBool isTierStatus = iContext.iMessage.IsMessage<TCFTierStatusProvider::TTierStatus>();
+ TBool isError = iContext.iMessage.IsMessage<TEBase::TError>();
+
+ if(isTierStatus || isError)
+ {
+ // Leave the tier manager
+ RNodeInterface::OpenPostMessageClose(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), iContext.Activity()->iTierManager,
+ TEChild::TLeft().CRef());
+
+ iContext.Node().RemoveClient(iContext.Activity()->iTierManager);
+ }
+
+ return isTierStatus;
+ }
+
+// Transitions
+
+DEFINE_SMELEMENT(EnumerateConnectionsActivity::TQueryTierStatus, NetStateMachine::MStateTransition, TContext)
+void EnumerateConnectionsActivity::TQueryTierStatus::DoL()
+ {
+ __ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+ // Clear the connection info cache
+ iContext.Node().iLegacyConnection.iConnectionInfoPtrArray.ResetAndDestroy();
+
+ CConnectionServParameterBundle* queryBundle = CConnectionServParameterBundle::NewL();
+ CleanupStack::PushL(queryBundle);
+ CRefCountOwnedParameterBundle* bundleOwner = new (ELeave)CRefCountOwnedParameterBundle(queryBundle);
+ CleanupStack::Pop(queryBundle);
+ bundleOwner->Open();
+ CleanupClosePushL(*bundleOwner);
+
+ // Set up a status filter for connected access points only
+ TAccessPointStatusFilter availFilter;
+ availFilter.Configured(EAccessPointFlagIgnore);
+ availFilter.Restricted(EAccessPointFlagIgnore);
+ availFilter.Available(EAccessPointFlagIgnore);
+ availFilter.Started(EAccessPointFlagIgnore);
+ availFilter.Active(EAccessPointFlagMatchTrue);
+
+ queryBundle->AddMatchConditionL(availFilter);
+ queryBundle->AddParameterSetToReturnL(XIpProtoAccessPointParameterSet::Type());
+
+ RClientInterface::OpenPostMessageClose(iContext.NodeId(), iContext.Activity()->iTierManager,
+ TCFTierStatusProvider::TTierStatusQuery(bundleOwner, &iContext.Activity()->iMessage).CRef());
+ CleanupStack::Pop(); // bundleOwner
+ }
+
+DEFINE_SMELEMENT(EnumerateConnectionsActivity::TCompleteClient, NetStateMachine::MStateTransition, TContext)
+void EnumerateConnectionsActivity::TCompleteClient::DoL()
+ {
+ __ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+ TPckg<TUint> pckg(iContext.Node().iLegacyConnection.iConnectionInfoPtrArray.Count());
+ iContext.Activity()->WriteL(0, pckg);
+ }
+
+DEFINE_SMELEMENT(EnumerateConnectionsActivity::TCacheConnectionInfo, NetStateMachine::MStateTransition, TContext)
+void EnumerateConnectionsActivity::TCacheConnectionInfo::DoL()
+ {
+ __ASSERT_DEBUG(iContext.Activity(), ConnPanic(KPanicNoActivity));
+
+ TCFTierStatusProvider::TTierStatus& msg = message_cast<TCFTierStatusProvider::TTierStatus>(iContext.iMessage);
+
+ const CConnectionServParameterSetContainer* container;
+ const XIpProtoAccessPointParameterSet* ipApParams;
+
+ for (TInt i=0; i<msg.iBundle->PtrL()->CountParamSetContainers(); i++)
+ {
+ container = static_cast<const CConnectionServParameterSetContainer*>(msg.iBundle->Ptr()->GetParamSetContainer(i));
+
+ ipApParams = XIpProtoAccessPointParameterSet::FindInParamSetContainer(*container);
+ __ASSERT_DEBUG(ipApParams, User::Panic(KSpecAssert_ESockSSockscnsts, 16));
+
+ TSourcedConnectionInfo* connInfo = new(ELeave) TSourcedConnectionInfo(ipApParams->IapId(), ipApParams->NetworkId(), ipApParams->ConnectionType(), ipApParams->ControlClientId());
+ iContext.Node().iLegacyConnection.iConnectionInfoPtrArray.AppendL(connInfo);
+ }
+
+ msg.iBundle->Close();
+ }
+
+DEFINE_SMELEMENT(ConnectionCleanupActivities::TNoTagOrNoTagBackwards, NetStateMachine::MStateFork, TContext)
+TInt ConnectionCleanupActivities::TNoTagOrNoTagBackwards::TransitionTag()
+ {
+ if ( iContext.iMessage.IsMessage<TEPeer::TLeaveComplete>() )
+ {
+// __ASSERT_DEBUG(iContext.Node().GetClientIter(RNodeInterface::ECtrl|RNodeInterface::EData)[0] == NULL,
+// User::Panic(KCorePRPanic, KPanicClientsStillPresent));
+ if (iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TCFClientType(TCFClientType::EServProvider)) == NULL)
+ { // This was the last service provider
+ return NetStateMachine::EForward | MeshMachine::KNoTag;
+ }
+ // There are more service providers to expect 'leave complete' from so
+ // loop round and wait for the next one.
+ return NetStateMachine::EBackward | MeshMachine::KNoTag;
+ }
+ __ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockSSockscnsts, 17));
+ return KNoTag;
+ }
+
+DEFINE_SMELEMENT(ConnSubConnEventsActivity::TAwaitingSubConnEvent, NetStateMachine::MState, TContext)
+TInt ConnSubConnEventsActivity::TAwaitingSubConnEvent::Accept()
+ {
+ if(iContext.iMessage.IsMessage<TCFInternalEsock::TSubConnectionOpenedEvent>() ||
+ iContext.iMessage.IsMessage<TCFInternalEsock::TSubConnectionClosedEvent>())
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+DEFINE_SMELEMENT(ConnSubConnEventsActivity::TProcessSubConnEvent, NetStateMachine::MStateTransition, TContext)
+void ConnSubConnEventsActivity::TProcessSubConnEvent::DoL()
+ {
+ CConnection& conn = static_cast<CConnection&>(iContext.Node());
+
+ if(iContext.iMessage.IsMessage<TCFInternalEsock::TSubConnectionOpenedEvent>())
+ {
+ const TCFInternalEsock::TSubConnectionOpenedEvent& msg = message_cast<TCFInternalEsock::TSubConnectionOpenedEvent>(iContext.iMessage);
+ conn.iLegacyConnection.SubConnectionEvent(msg.iSubConnectionOpenedEvent);
+ }
+ else
+ {
+ const TCFInternalEsock::TSubConnectionClosedEvent& msg = message_cast<TCFInternalEsock::TSubConnectionClosedEvent>(iContext.iMessage);
+ conn.iLegacyConnection.SubConnectionEvent(msg.iSubConnectionClosedEvent);
+ }
+ }
+
+CNodeActivityBase* CConnLegacyRMessage2Activity::NewL( const TNodeActivity& aActivitySig, AMMNodeBase& aNode )
+ {
+ TUint c = GetNextActivityCountL(aActivitySig,aNode);
+ return new (ELeave) CConnLegacyRMessage2Activity( aActivitySig, aNode, c);
+ }
+
+CConnLegacyRMessage2Activity::CConnLegacyRMessage2Activity( const TNodeActivity& aActivitySig, AMMNodeBase& aNode, TUint aNextActivityCount)
+ : MeshMachine::CNodeParallelMessageStoreActivityBase(aActivitySig, aNode, aNextActivityCount)
+ {
+ }
+
+CConnLegacyRMessage2Activity::~CConnLegacyRMessage2Activity()
+ {
+ if (Error() != KErrNone)
+ {
+ Complete(Error());
+ }
+ if (!iCancelMessage.IsNull())
+ {
+ iCancelMessage.Complete(KErrNone);
+ }
+ SetError(KErrNone);
+ }
+
+void CConnLegacyRMessage2Activity::PanicClient(const TDesC& aCatagory, TInt aCode)
+ {
+ if (!iSafeMessage.IsNull())
+ {
+ iSafeMessage.PanicClient(aCatagory, aCode);
+ }
+ }
+
+void CConnLegacyRMessage2Activity::Complete(TInt aCode)
+ {
+ if (!iSafeMessage.IsNull())
+ {
+ iSafeMessage.Complete(aCode);
+ }
+ }
+
+void CConnLegacyRMessage2Activity::SetCancelRequest(const Den::RSafeMessage& aMessage)
+ {
+ iCancelMessage.Duplicate(aMessage);
+ }
+
+
+DEFINE_SMELEMENT(TProcessLegacyRMessage2, NetStateMachine::MStateTransition, TContext)
+void TProcessLegacyRMessage2::DoL()
+ {
+ ASSERT(iContext.iMessage.IsTypeOf(Meta::STypeId::CreateSTypeId(TCFSigLegacyRMessage2Ext::EUid, TCFSigLegacyRMessage2Ext::ETypeId)));
+ // static_cast as it will be a derivative and message_cast won't work
+ CConnLegacyRMessage2Activity* act = static_cast<CConnLegacyRMessage2Activity*>(iContext.Activity());
+ TCFSigLegacyRMessage2Ext& msg = static_cast<TCFSigLegacyRMessage2Ext&>(iContext.iMessage);
+ act->iSafeMessage.Duplicate(msg.iMessage);
+
+ if (msg.CanProcess(iContext))
+ {
+ msg.ProcessL(iContext);
+ }
+ else
+ {
+ msg.ForwardL(iContext);
+ }
+ }
+
+DEFINE_SMELEMENT(TCompleteRMessage2, NetStateMachine::MStateTransition, TContext)
+void TCompleteRMessage2::DoL()
+ {
+ TCFLegacyMessage::TLegacyRMessage2Processed& msg = message_cast<TCFLegacyMessage::TLegacyRMessage2Processed>(iContext.iMessage);
+ CConnLegacyRMessage2Activity* act = static_cast<CConnLegacyRMessage2Activity*>(iContext.Activity());
+
+ if (msg.iResponse.iType == TLegacyRMessage2Response::EPanic)
+ {
+ act->PanicClient(msg.iResponse.iCatagory, msg.iResponse.iCode);
+ }
+ else
+ {
+ ASSERT(act->Message().IsTypeOf(Meta::STypeId::CreateSTypeId(TCFSigLegacyRMessage2Ext::EUid, TCFSigLegacyRMessage2Ext::ETypeId)));
+ TInt error = static_cast<TCFSigLegacyRMessage2Ext&>(act->Message()).CheckError(iContext, msg.iResponse.iCode);
+ act->Complete(error);
+ }
+ }
+
+DEFINE_SMELEMENT(THandleRMessage2Error, NetStateMachine::MStateTransition, ConnStates::TContext)
+void THandleRMessage2Error::DoL()
+ {
+ CConnLegacyRMessage2Activity* act = static_cast<CConnLegacyRMessage2Activity*>(iContext.Activity());
+
+ ASSERT(act->Message().IsTypeOf(Meta::STypeId::CreateSTypeId(TCFSigLegacyRMessage2Ext::EUid, TCFSigLegacyRMessage2Ext::ETypeId)));
+ TInt error = static_cast<TCFSigLegacyRMessage2Ext&>(act->Message()).CheckError(iContext, act->Error());
+ act->SetError(error);
+ act->Complete(error);
+ }
+
+
+DEFINE_SMELEMENT(TCancelAllLegacyRMessage2Activities, NetStateMachine::MStateTransition, TContext)
+void TCancelAllLegacyRMessage2Activities::DoL()
+ {
+ const RPointerArray<CNodeActivityBase>& activities = iContext.Node().Activities();
+
+ for (TInt i = 0; i < activities.Count(); i++)
+ {
+ if (activities[i]->ActivitySigId() == ESock::ECFActivityConnectionLegacyRMessage2Handler)
+ {
+ activities[i]->Cancel(iContext);
+ }
+ }
+ }
+
+