diff -r 000000000000 -r dfb7c4ff071f datacommsserver/esockserver/ssock/ss_subconn.cpp --- /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 +#include +#include +#include +#include +#include "SS_conn.H" +#include +#include + +#include +#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, 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, 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, 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) + 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, MeshMachine::TNoTag) + THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, MeshMachine::TNoTag) + NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TStartSubConnection, TECABState, 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, MeshMachine::TNoTag) + THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, MeshMachine::TNoTag) + NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TStopSubConnection, TECABState, 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, 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, MeshMachine::TAwaitingLeaveComplete, CoreActivities::CDestroyActivity::TNoTagOrNoTagBackwards) + LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing) +NODEACTIVITY_END() +} + +namespace SubConnectionAddSocket +{ +typedef TECABState TAwaitingBuildStackResponse; +typedef MeshMachine::TAcceptErrorState TAwaitingApplyResponseOrError; + +DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityDataClientJoin, SubConAddSocket, TCFInternalEsock::TSubSess, SubConnActivities::CRejoin::NewL) + FIRST_NODEACTIVITY_ENTRY(SubSessStates::TAwaitingIPC, 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, 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, MeshMachine::TNoTag) + NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TSendRejoinDataClientRequestToOldOwner, TAcceptErrorState, MeshMachine::TNoTagOrErrorTag) + NODEACTIVITY_ENTRY(KErrorTag, SubConnStates::TLeaveTheOtherOwner, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TTag) + 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, 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, MeshMachine::TNoTag) + THROUGH_NODEACTIVITY_ENTRY(KNoTag, SubSessStates::TAcquireMessageOwnership, MeshMachine::TNoTag) + NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TJoinTheOtherOwner, TECABState, MeshMachine::TNoTag) + NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TSendRejoinDataClientRequestToOldOwner, TAcceptErrorState, MeshMachine::TNoTagOrErrorTag) + //When removing socket, remove first, add later. + NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TSendApplyToOldOwner, MeshMachine::TAcceptErrorState, MeshMachine::TNoTagOrErrorTag) + NODEACTIVITY_ENTRY(KNoTag, SubConnStates::TSendApplyToNewOwner, MeshMachine::TAcceptErrorState, 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, 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, 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::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, 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) + 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, 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, 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, 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(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() + && 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 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(&(controlProv->RecipientId().Node())); +#else + return mcfnode_cast(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; + } + +