--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/ssock/ss_subconn.cpp Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,582 @@
+// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "ss_subconn.h"
+#include "ss_subconnstates.h"
+#include "ss_connstates.h"
+#include <comms-infras/ss_subconnprov.h>
+#include <comms-infras/ss_log.h>
+#include <comms-infras/ss_roles.h>
+#include <ss_glob.h>
+#include <comms-infras/ss_sapshim.h>
+#include "SS_conn.H"
+#include <comms-infras/ss_nodemessages_subconn.h>
+#include <cs_subconevents.h>
+
+#include <comms-infras/ss_msgintercept.h>
+#include "ss_internal_activities.h"
+
+
+#ifdef _DEBUG
+// Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
+// (if it could happen through user error then you should give it an explicit, documented, category + code)
+_LIT(KSpecAssert_ESockSSocks_sbcn, "ESockSSocks_sbcn");
+#endif
+
+using namespace ESock;
+using namespace SubSessActivities;
+using namespace NetStateMachine;
+using namespace SubConnActivities;
+using namespace SubSessStates;
+using namespace CoreStates;
+using namespace Messages;
+using namespace MeshMachine;
+
+#ifdef _DEBUG
+_LIT (KCSubConnectionPanic,"CSubConnectionPanic");
+#endif
+
+//-=========================================================
+//
+//Actvities serving client (RSubConnection) requests
+//
+//-=========================================================
+// Creates a subconnection subsession object. No longer triggers the building of the stack beneath it.
+// This now occurs only when required
+namespace SubConnectionCreate
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivitySubConnectionCreate, SubConCreate, TCFInternalEsock::TSubSess, SubConnActivities::CCreate::NewL)
+ FIRST_NODEACTIVITY_ENTRY(SubSessStates::TAwaitingIPC<ESCCreate>, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, SubConnStates::TNoTagOrAttachToDefaultOrWaitForIncoming)
+
+ // We are attaching to the default subconnection and can therefore build the subconnection stack immediately
+ NODEACTIVITY_ENTRY(CoreNetStates::KAttachToDefault, SubConnStates::TSendBuildStack, SubConnStates::TAwaitingBuildStackResponse, MeshMachine::TNoTag)
+
+ // Must be `ECreateNew` in which case we defer the building of the stack. We are done
+ LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
+
+ // Wait for incoming
+ LAST_NODEACTIVITY_ENTRY(CoreNetStates::KWaitForIncoming, MeshMachine::TDoNothing)
+NODEACTIVITY_END()
+}
+
+namespace SubConnectionNoBearer
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityNoBearer, SubConnNoBearer, TCFControlProvider::TNoBearer, SubConnActivities::CNoBearer::NewL)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingNoBearer, MeshMachine::TNoTag)
+
+ // We don't have a bearer so get the stack built so that we do. Then we can proceed
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubConnActivities::CNoBearer::TStoreFlowParams, CoreNetStates::TNoTagOrNoBearer)
+ NODEACTIVITY_ENTRY(CoreNetStates::KNoBearer, SubConnStates::TSendBuildStack, SubConnStates::TAwaitingBuildStackResponse, MeshMachine::TNoTag)
+
+ // We now/already have a bearer so go ahead with fetching a bearer for the data client that kicked us off
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TRequestServiceProvider, TAcceptErrorState<CoreNetStates::TAwaitingBinderResponse>, MeshMachine::TNoTagOrErrorTag)
+ LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TDoNothing)
+
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendBindTo, CoreNetStates::TAwaitingBindToComplete, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubConnActivities::CNoBearer::TSendBindToComplete, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
+NODEACTIVITY_END()
+}
+
+namespace SubConnectionBuildStack
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityBuildStack, SubConnBuildStack, TCFInternalEsock::TBuildStackRequest, SubConnActivities::CBuildStack::NewL)
+ FIRST_NODEACTIVITY_ENTRY(SubConnActivities::CBuildStack::TAwaitingBuildStack, MeshMachine::TNoTag)
+
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TJoinCPR, CoreStates::TAwaitingJoinComplete, MeshMachine::TNoTag)
+
+ NODEACTIVITY_ENTRY(KNoTag, SubConnActivities::CBuildStack::TRequestServiceProviderFromCPR, TAcceptErrorState<CoreNetStates::TAwaitingBinderResponse>, MeshMachine::TNoTagOrErrorTag)
+
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendControlClientJoinRequest, CoreStates::TAwaitingJoinComplete, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubConnActivities::CBuildStack::TSendBindToComplete, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TLeaveCPR, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, CBuildStack::TSendBuildStackResponse)
+
+ NODEACTIVITY_ENTRY(KErrorTag, SubConnStates::TLeaveCPR, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TTag<KErrorTag>)
+ LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TDoNothing)
+NODEACTIVITY_END()
+}
+
+namespace SubConnectionStart
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStart, SubConStart, TCFInternalEsock::TSubSess, SubSessActivities::CESockClientActivityBase::NewL)
+ FIRST_NODEACTIVITY_ENTRY(SubSessStates::TAwaitingIPC<ESCStart>, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TStartSubConnection, TECABState<CoreNetStates::TAwaitingStarted>, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
+NODEACTIVITY_END()
+}
+
+namespace SubConnectionStop
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStop, SubConStop, TCFInternalEsock::TSubSess, SubSessActivities::CESockClientActivityBase::NewL)
+ FIRST_NODEACTIVITY_ENTRY(SubSessStates::TAwaitingIPC<ESCStop>, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TStopSubConnection, TECABState<CoreNetStates::TAwaitingStopped>, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
+NODEACTIVITY_END()
+}
+
+namespace SubConnectionClose
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityDestroy, SubConClose, TCFInternalEsock::TSubSess, SubSessActivities::CCloseActivity::New)
+ FIRST_NODEACTIVITY_ENTRY(SubSessStates::TAwaitingIPC<ESCClose>, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TCancelAndCloseClientExtIfaces, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, ConnStates::TCancelAllLegacyRMessage2Activities, ConnStates::TNoTagBlockedByLegacyRMessage2Activities)
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TProcessClose, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, TECABTransition<CoreNetStates::TSetIdleIfNoServiceProviders>, MeshMachine::TAwaitingLeaveComplete, CoreActivities::CDestroyActivity::TNoTagOrNoTagBackwards)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
+NODEACTIVITY_END()
+}
+
+namespace SubConnectionAddSocket
+{
+typedef TECABState<SubConnStates::TAwaitingBuildStackResponse> TAwaitingBuildStackResponse;
+typedef MeshMachine::TAcceptErrorState<CoreNetStates::TAwaitingApplyResponse> TAwaitingApplyResponseOrError;
+
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityDataClientJoin, SubConAddSocket, TCFInternalEsock::TSubSess, SubConnActivities::CRejoin::NewL)
+ FIRST_NODEACTIVITY_ENTRY(SubSessStates::TAwaitingIPC<ESCAddSocket>, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, CoreNetStates::TNoTagOrNoBearer)
+
+ // We have no bearer yet so must have the stack built beneath us before continuing
+ NODEACTIVITY_ENTRY(CoreNetStates::KNoBearer, SubConnStates::TSendBuildStack, TECABState<SubConnStates::TAwaitingBuildStackResponse>, MeshMachine::TNoTag)
+
+ // We have a bearer and can now go ahead adding a socket from the default sub connection
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TJoinTheOtherOwner, TECABState<CoreStates::TAwaitingJoinComplete>, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TSendRejoinDataClientRequestToOldOwner, TAcceptErrorState<CoreNetStates::TAwaitingRejoinDataClientComplete>, MeshMachine::TNoTagOrErrorTag)
+ NODEACTIVITY_ENTRY(KErrorTag, SubConnStates::TLeaveTheOtherOwner, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TTag<KErrorTag>)
+ LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TDoNothing)
+
+ //When adding socket, add first, remove later.
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TSendApplyToNewOwner, TAwaitingApplyResponseOrError, MeshMachine::TNoTagOrErrorTag)
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TSendApplyToOldOwner, TAwaitingApplyResponseOrError, MeshMachine::TNoTagOrErrorTag)
+
+ NODEACTIVITY_ENTRY(KErrorTag, SubConnStates::TSendCancelToOldOwner, TAcceptErrorState<CoreStates::TNeverAccept>, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TLeaveTheOtherOwner, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
+NODEACTIVITY_END()
+}
+
+namespace SubConnectionRemoveSocket
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityClientLeave, SubConRemoveSocket, TCFInternalEsock::TSubSess, SubConnActivities::CRejoin::NewL)
+ FIRST_NODEACTIVITY_ENTRY(SubSessStates::TAwaitingIPC<ESCRemoveSocket>, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TJoinTheOtherOwner, TECABState<CoreStates::TAwaitingJoinComplete>, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TSendRejoinDataClientRequestToOldOwner, TAcceptErrorState<CoreNetStates::TAwaitingRejoinDataClientComplete>, MeshMachine::TNoTagOrErrorTag)
+ //When removing socket, remove first, add later.
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TSendApplyToOldOwner, MeshMachine::TAcceptErrorState<CoreNetStates::TAwaitingApplyResponse>, MeshMachine::TNoTagOrErrorTag)
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TSendApplyToNewOwner, MeshMachine::TAcceptErrorState<CoreNetStates::TAwaitingApplyResponse>, MeshMachine::TNoTagOrErrorTag)
+
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TLeaveTheOtherOwner, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KErrorTag, SubConnStates::TLeaveTheOtherOwner, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
+NODEACTIVITY_END()
+}
+
+namespace SubConnectionSetParams
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityParamRequest, SubConSetParams, TCFInternalEsock::TSubSess, SubConnActivities::CSetParameters::NewL)
+ FIRST_NODEACTIVITY_ENTRY(SubSessStates::TAwaitingIPC<ESCSetParameters>, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubConnActivities::CSetParameters::TStoreNewParams, CoreNetStates::TNoTagOrNoBearer)
+
+ // We have no bearer so are going to have to tell ourself to build the stack beneath us
+ NODEACTIVITY_ENTRY(CoreNetStates::KNoBearer, SubConnStates::TSendBuildStack, SubConnStates::TAwaitingBuildStackResponse, MeshMachine::TNoTag)
+
+ // Proceed with sending the parameters to our service provider
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TSendParamsToServiceProvider, TECABState<CoreNetStates::TAwaitingParamResponse>, MeshMachine::TNoTag)
+
+ //it's the legacy behaviour to complete setparams once they have been verified (TParamsResponse received)
+ //but not yet processed.
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubConnActivities::CSetParameters::TCompleteClient, MeshMachine::TNoTag)
+
+ // the params received in response should be stored before send apply
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TStoreParamsAndSendApply, TECABState<MeshMachine::TAcceptErrorState<CoreNetStates::TAwaitingApplyResponse> >, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
+NODEACTIVITY_END()
+}
+
+namespace SubConnectionEventNotificationSubscription
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityNotification, SubConEventSubscr, TCFInternalEsock::TSubSess, SubConnActivities::CEventNotification::NewL)
+ FIRST_NODEACTIVITY_ENTRY(SubConnStates::TAwaitingEventNotificationSubscription, SubConnStates::TNoTagOrAllNotifications)
+ NODEACTIVITY_ENTRY (KNoTag, SubConnStates::TSetupFilteredEventNotification, SubSessStates::TAwaitingIPC<ESCEventNotification>, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(ESCEventAllNotifications, SubConnStates::TSetupAllEventNotification, MeshMachine::TNoTag )
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, SubConnStates::TNoTagOrActiveWhenEventEnqued)
+
+ NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, CoreNetStates::TAwaitingSubConEvent, TTag<KActiveTag>)
+ LAST_NODEACTIVITY_ENTRY(KActiveTag, SubConnStates::TFillInEvent)
+NODEACTIVITY_END()
+}
+
+namespace SubConnectionEventNotification
+{
+DECLARE_DEFINE_NODEACTIVITY(ECFActivityConnectionWaitForIncoming, SubConEvent, TCFSubConnControlClient::TSubConnNotification)
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TEnqueueEvent, CoreNetStates::TAwaitingSubConEvent, MeshMachine::TNoTag)
+NODEACTIVITY_END()
+}
+
+namespace SubConnectionGetParamLength
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityGetParamLength, SubConGetParamLength, TCFInternalEsock::TSubSess, CESockClientActivityBase::NewL)
+ FIRST_NODEACTIVITY_ENTRY(SubSessStates::TAwaitingIPC<ESCGetParametersLength>, MeshMachine::TNoTag)
+ // We must block if SubConnectionSetParams activity is currently running (the activity continues to run after it has completed its client)
+ // as otherwise the stored parameters can be changed underneath us. In particular, this can occur in-between
+ // SubConnectionGetParamLength and SubConnectionGetParam, with the resulting length mismatch causing a KERN-EXEC-3 in the original
+ // client RSubConnection::GetParameters() call.
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, SubConnStates::TNoTagOrParamsPresentBlockedBySetParams )
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TSendParamRequest, CoreNetStates::TAwaitingParamResponse, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TStoreParams, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TWriteSubConnParamsLength)
+ LAST_NODEACTIVITY_ENTRY(PRStates::KParamsPresent, SubConnStates::TWriteSubConnParamsLength)
+NODEACTIVITY_END()
+}
+
+namespace SubConnectionGetParam
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityGetParam, SubConGetParams, TCFInternalEsock::TSubSess, CESockClientActivityBase::NewL)
+ FIRST_NODEACTIVITY_ENTRY(SubSessStates::TAwaitingIPC<ESCGetParameters>, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, SubConnStates::TNoTagOrParamsPresent )
+ NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TSendParamRequest, CoreNetStates::TAwaitingParamResponse, MeshMachine::TNoTag)
+ THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TStoreParams, MeshMachine::TNoTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TWriteSubConnParams)
+ LAST_NODEACTIVITY_ENTRY(PRStates::KParamsPresent, SubConnStates::TWriteSubConnParams)
+NODEACTIVITY_END()
+}
+
+//
+//Activities serving framework requests
+namespace SubConnectionWaitForIncomming
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityBindTo, SubConnBindToRequest, TCFDataClient::TBindTo, PRActivities::CBindToActivity::NewL)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingBindTo, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendControlClientJoinRequest, CoreStates::TAwaitingJoinComplete, MeshMachine::TNoTagOrErrorTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendBindToComplete)
+NODEACTIVITY_END()
+}
+
+namespace SubConnectionLegacyRMessage2Activity
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivitySubConnectionLegacyRMessage2Handler, SubConnectionLegacyRMessage2, TNodeSignal::TNullMessageId, ConnActivities::CConnLegacyRMessage2Activity::NewL)
+ FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingLegacyRMessage2Ext, MeshMachine::TNoTag)
+ NODEACTIVITY_ENTRY(KNoTag, ConnStates::TProcessLegacyRMessage2, TAcceptErrorState<CoreNetStates::TAwaitingRMessage2Processed>, MeshMachine::TNoTagOrErrorTag)
+ LAST_NODEACTIVITY_ENTRY(KNoTag, ConnStates::TCompleteRMessage2)
+ LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TDoNothing)
+NODEACTIVITY_END()
+}
+
+
+namespace SubConnectionActivities
+{
+DECLARE_DEFINE_ACTIVITY_MAP(subconnectionActivities)
+ ACTIVITY_MAP_ENTRY(CoreErrorActivity, CoreError) //Must be first in the table
+ ACTIVITY_MAP_ENTRY(SubConnectionStart, SubConStart)
+ ACTIVITY_MAP_ENTRY(SubConnectionStop, SubConStop)
+ ACTIVITY_MAP_ENTRY(SubConnectionCreate, SubConCreate)
+ ACTIVITY_MAP_ENTRY(SubConnectionClose, SubConClose)
+ ACTIVITY_MAP_ENTRY(SubConnectionAddSocket, SubConAddSocket)
+ ACTIVITY_MAP_ENTRY(SubConnectionRemoveSocket, SubConRemoveSocket)
+ ACTIVITY_MAP_ENTRY(SubConnectionSetParams, SubConSetParams)
+ ACTIVITY_MAP_ENTRY(SubConnectionEventNotificationSubscription, SubConEventSubscr)
+ ACTIVITY_MAP_ENTRY(SubConnectionEventNotification, SubConEvent)
+ ACTIVITY_MAP_ENTRY(SubConnectionGetParamLength, SubConGetParamLength)
+ ACTIVITY_MAP_ENTRY(SubConnectionGetParam, SubConGetParams)
+ ACTIVITY_MAP_ENTRY(SubConnectionWaitForIncomming, SubConnBindToRequest)
+ ACTIVITY_MAP_ENTRY(SubConnectionBuildStack, SubConnBuildStack)
+ ACTIVITY_MAP_ENTRY(SubConnectionNoBearer, SubConnNoBearer)
+ ACTIVITY_MAP_ENTRY(SubConnectionLegacyRMessage2Activity, SubConnectionLegacyRMessage2)
+ ACTIVITY_MAP_ENTRY(PRDataClientJoinActivity, PRDataClientJoin)
+ ACTIVITY_MAP_ENTRY(PRClientLeaveActivity, PRClientLeave)
+ACTIVITY_MAP_END()
+}
+
+
+
+
+
+
+
+//-=========================================================
+//
+//
+//CSubConnection implementation
+//
+//
+//-=========================================================
+CSubConnection* CSubConnection::NewL(CConnection& aConnection, CPlayer* aPlayer, const TSubSessionUniqueId aSubSessionUniqueId)
+/** Create a new CSubConnection instance
+
+@param aConnProvider Connection Provider that this subconnection is a member of
+@param aType Default or new subconnection
+@param aSession Socket Session this subsession is to be a member of
+@return pointer to new CSubConnection instance on success
+@exception leaves if could not allocate memory
+*/
+ {
+ RNodeInterface* conn = aConnection.ServiceProvider();
+ __ASSERT_DEBUG(conn, User::Panic(KSpecAssert_ESockSSocks_sbcn, 1));
+ User::LeaveIfError(conn? KErrNone : KErrNotReady);
+
+ CSubConnection* sc = new (ELeave) CSubConnection(aPlayer, aSubSessionUniqueId);
+ CleanupStack::PushL(sc);
+ sc->ConstructL(aConnection);
+ CleanupStack::Pop(sc);
+
+ ESOCK_DEBUG_REGISTER_GENERAL_NODE(ESockDebug::KSubConnectionNodeUid, sc);
+
+ return sc;
+ }
+
+
+void CSubConnection::ProcessMessageL()
+ {
+ LOG_DETAILED(ESockLog::Printf(_L("CSubConnection(%08x)::ProcessMessageL:\tCommand %d"), this, Message().Function()));
+
+ switch (Message().Function())
+ {
+ case ESCAddSocket:
+ LOG( ESockLog::Printf(KESockSubConnectionTag, _L8("CSubConnection %08x\tESCAddSocket aMessage %08x"), this, &Message()) );
+ //If successful, the ownership of the RMessage2 is taken by the activity, otherwise completed on leave
+ CMMSockSubSession::ReceivedL(ESCAddSocket, TCFInternalEsock::TSubSess(ESCAddSocket,Message()).CRef());
+ break;
+
+ case ESCRemoveSocket:
+ LOG( ESockLog::Printf(KESockSubConnectionTag, _L8("CSubConnection %08x\tESCRemoveSocket aMessage %08x"), this, &Message()) );
+ //If successful, the ownership of the RMessage2 is taken by the activity, otherwise completed on leave
+ CMMSockSubSession::ReceivedL(ESCRemoveSocket, TCFInternalEsock::TSubSess(ESCRemoveSocket,Message()).CRef());
+ break;
+
+ case ESCSetParameters:
+ LOG( ESockLog::Printf(KESockSubConnectionTag, _L8("CSubConnection %08x\tESCSetParameters aMessage %08x"), this, &Message()) );
+ //If successful, the ownership of the RMessage2 is taken by the activity, otherwise completed on leave
+ CMMSockSubSession::ReceivedL(ESCSetParameters, TCFInternalEsock::TSubSess(ESCSetParameters,Message()).CRef());
+ break;
+
+ case ESCGetParameters:
+ LOG( ESockLog::Printf(KESockSubConnectionTag, _L8("CSubConnection %08x\tESCGetParameters aMessage %08x"), this, &Message()) );
+ //If successful, the ownership of the RMessage2 is taken by the activity, otherwise completed on leave
+ CMMSockSubSession::ReceivedL(ESCGetParameters, TCFInternalEsock::TSubSess(ESCGetParameters,Message()).CRef());
+ break;
+
+ case ESCGetParametersLength:
+ LOG( ESockLog::Printf(KESockSubConnectionTag, _L8("CSubConnection %08x\tESCGetParametersLength aMessage %08x"), this, &Message()) );
+ //If successful, the ownership of the RMessage2 is taken by the activity, otherwise completed on leave
+ CMMSockSubSession::ReceivedL(ESCGetParametersLength, TCFInternalEsock::TSubSess(ESCGetParametersLength,Message()).CRef());
+ break;
+
+ case ESCEventNotificationSetup:
+ LOG( ESockLog::Printf(KESockSubConnectionTag, _L8("CSubConnection %08x\tESCEventNotificationSetup aMessage %08x"), this, &Message()) );
+ CMMSockSubSession::ReceivedL(ESCEventNotification, TCFInternalEsock::TSubSess(ESCEventNotificationSetup,Message()).CRef());
+ break;
+
+ case ESCEventNotification:
+ LOG( ESockLog::Printf(KESockSubConnectionTag, _L8("CSubConnection %08x\tESCEventNotification aMessage %08x"), this, &Message()) );
+ CMMSockSubSession::ReceivedL(ECFActivityNotification, TCFInternalEsock::TSubSess(ESCEventNotification,Message()).CRef());
+ break;
+
+ case ESCEventAllNotifications:
+ LOG( ESockLog::Printf(KESockSubConnectionTag, _L8("CSubConnection %08x\tESCEventAllNotifications aMessage %08x"), this, &Message()) );
+ CMMSockSubSession::ReceivedL(ESCEventNotification, TCFInternalEsock::TSubSess(ESCEventAllNotifications,Message()).CRef());
+ break;
+
+ case ESCEventNotificationCancel:
+ LOG( ESockLog::Printf(KESockSubConnectionTag, _L8("CSubConnection %08x\tESCEventNotificationCancel aMessage %08x"), this, &Message()) );
+ //CANCELATION - Do not call DontCompleteCurrentRequest() for ECFActivityNotification to be completed!
+ CMMSockSubSession::ReceivedL(ESCEventNotification, TEBase::TCancel().CRef());
+ break;
+
+ case ESCControl:
+ {
+ LOG( ESockLog::Printf(KESockSubConnectionTag, _L8("CSubConnection %08x\tESCControl aMessage %08x"), this, &Message()) );
+ if (ServiceProvider() == NULL)
+ {
+ User::Leave(KErrNotReady);
+ }
+ TLegacyControlMessage msg(SafeMessage());
+ CMMSockSubSession::ReceivedL(SafeMessage().Function(), msg);
+ DontCompleteCurrentRequest(); //TLegacyControlMessage will complete the message
+ }
+ break;
+
+ case ESCStart:
+ LOG( ESockLog::Printf(KESockSubConnectionTag, _L8("CSubConnection %08x\tESCStart aMessage %08x"), this, &Message()) );
+ //If successful, the ownership of the RMessage2 is taken by the activity, otherwise completed on leave
+ CMMSockSubSession::ReceivedL(ESCStart, TCFInternalEsock::TSubSess(ESCStart,Message()).CRef());
+ break;
+
+ case ESCStop:
+ LOG( ESockLog::Printf(KESockSubConnectionTag, _L8("CSubConnection %08x\tESCStop aMessage %08x"), this, &Message()) );
+ //If successful, the ownership of the RMessage2 is taken by the activity, otherwise completed on leave
+ CMMSockSubSession::ReceivedL(ESCStop, TCFInternalEsock::TSubSess(ESCStop,Message()).CRef());
+ break;
+
+ case ESCClose:
+ LOG( ESockLog::Printf(KESockSubConnectionTag, _L8("CSubConnection %08x\tESCClose aMessage %08x"), this, &Message()) );
+ SetClosing();
+ //If successful, the ownership of the RMessage2 is taken by the activity, otherwise completed on leave
+ CMMSockSubSession::ReceivedL(ESCClose, TCFInternalEsock::TSubSess(ESCClose,Message()).CRef());
+ break;
+
+ default:
+ SetReturn(KErrNotSupported);
+ }
+ }
+
+/**
+Constructor - set up name
+*/
+CSubConnection::CSubConnection(CPlayer* aPlayer, const TSubSessionUniqueId aSubSessionUniqueId)
+ : CMMSockSubSession(SubConnectionActivities::subconnectionActivities::Self(), aPlayer->CurrentSession(), aPlayer, aSubSessionUniqueId),
+ ASubSessionPlatsecApiExt(UniqueId()),
+ TIfStaticFetcherNearestInHierarchy(this)
+ {
+ LOG_NODE_CREATE(KESockComponentTag, CSubConnection);
+ }
+
+class TRevertAddClient
+ {
+ public:
+ TRevertAddClient(MeshMachine::AMMNodeBase& aOwner, const TNodeId& aClient)
+ :iOwner(aOwner),
+ iClient(aClient)
+ {}
+
+ static void Do(TAny* aRevertAddClient)
+ {
+ TRevertAddClient& This = *reinterpret_cast<TRevertAddClient*>(aRevertAddClient);
+ This.Do();
+ }
+
+ void Do()
+ {
+ iOwner.RemoveClient(iClient);
+ }
+
+ private:
+ MeshMachine::AMMNodeBase& iOwner;
+ const TNodeId& iClient;
+ };
+
+void CSubConnection::ConstructL(CConnection& aConnection)
+ {
+ CMMSockSubSession::ConstructL();
+ AddClientL(aConnection.Id(), TClientType(TCFClientType::ECtrlProvider));
+ TRevertAddClient cleanupRevert(*this, aConnection.Id());
+ CleanupStack::PushL(TCleanupItem(TRevertAddClient::Do, &cleanupRevert));
+ aConnection.AddClientL(Id(), TClientType(TCFClientType::EData));
+ CleanupStack::Pop();
+ }
+
+/**
+Destructor, clean up connection preferences and the subconnection provider
+*/
+CSubConnection::~CSubConnection()
+ {
+ if (!iParameterBundle.IsNull())
+ {
+ iParameterBundle.Close();
+ }
+
+ if (CMMSockSubSession::ControlProvider())
+ {
+ ControlProvider().RemoveClient(Id());
+ RemoveClient(ControlProvider().Id());
+ }
+
+ CRefCountOwnedSubConNotification* event = NULL;
+ while (iEventQueue.Deque(event))
+ {
+ __ASSERT_DEBUG(event, User::Panic(KSpecAssert_ESockSSocks_sbcn, 2));
+ event->Close();
+ event = NULL;
+ }
+
+ LOG_NODE_DESTROY(KESockComponentTag, CSubConnection);
+ }
+
+void CSubConnection::Received(TNodeContextBase& aContext)
+ {
+ TNodeSignal::TMessageId noPeerIds[] = {
+ TCFInternalEsock::TSubSess::Id(),
+ TCFPeer::TJoinRequest::Id(),
+ TEPeer::TLeaveRequest::Id(),
+ TNodeSignal::TMessageId()
+ };
+ MeshMachine::AMMNodeBase::Received(noPeerIds, aContext);
+ MeshMachine::AMMNodeBase::PostReceived(aContext);
+ }
+
+void CSubConnection::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage)
+ {
+ ESOCK_DEBUG_MESSAGE_INTERCEPT(aSender, aMessage, aRecipient);
+
+ //First check if this is not our own error
+ if (aMessage.IsMessage<TEBase::TError>()
+ && aSender == Id())
+ {
+ //This is our own error, generated from the client (IPC) activity
+ //It is safe to just ignore it here, as the activity is
+ //completed (and so is the client RMessage2). If the activity didn't have
+ //the chance to acquire ownership of the message it is still safe to ignore it
+ //because there was no call to DoNotCompleteCurrentMessage().
+ //return KErrNone;
+ }
+
+ TNodeContext<CSubConnection> ctx(*this, aMessage, aSender, aRecipient);
+ CSubConnection::Received(ctx);
+ User::LeaveIfError(ctx.iReturn);
+ }
+
+void CSubConnection::FinalCompleteAllBlockedMessages(TInt /*aResult*/)
+ {
+ TNodeNullContext ctx(*this);
+ AbortActivitiesOriginatedBy(ctx); //Abort all activities
+ }
+
+CConnection& CSubConnection::ControlProvider()
+ {
+ RNodeInterface* controlProv = CMMSockSubSession::ControlProvider();
+ __ASSERT_DEBUG(controlProv, User::Panic(KCSubConnectionPanic,KPanicNoConnection));
+#if defined(__GCCXML__)
+ return *reinterpret_cast<CConnection*>(&(controlProv->RecipientId().Node()));
+#else
+ return mcfnode_cast<CConnection>(controlProv->RecipientId().Node());
+#endif
+ }
+
+EXPORT_C RCFParameterFamilyBundleC& CSubConnection::GetOrCreateParameterBundleL()
+ {
+ if( ! iParameterBundle.IsNull())
+ {
+ return iParameterBundle;
+ }
+ return CreateParameterBundleL();
+ }
+
+EXPORT_C RCFParameterFamilyBundleC& CSubConnection::CreateParameterBundleL()
+ {
+ __ASSERT_DEBUG(iParameterBundle.IsNull(), User::Panic(KSpecAssert_ESockSSocks_sbcn, 3));
+
+ RCFParameterFamilyBundle newBundle;
+ newBundle.CreateL();
+ iParameterBundle.Open(newBundle);
+
+ return iParameterBundle;
+ }
+
+