diff -r 000000000000 -r af10295192d8 networkcontrol/ipnetworklayer/src/ipprotodeftscprstates.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/networkcontrol/ipnetworklayer/src/ipprotodeftscprstates.cpp Tue Jan 26 15:23:49 2010 +0200 @@ -0,0 +1,476 @@ +// Copyright (c) 2006-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: +// IPProto SubConnection Provider states/transitions +// +// + +/** + @file + @internalComponent +*/ + +#include +#include +#include +#include +#include +#include // for TLinkMessage +#include "ipprotodeftscpr.h" +#include "ipprotodeftscprstates.h" +#include "ItfInfoConfigExt.h" +#include +#include +#include +#include + +using namespace Messages; +using namespace MeshMachine; +using namespace ESock; +using namespace NetStateMachine; +using namespace IPProtoDeftSCpr; + + +DEFINE_SMELEMENT(TStoreProvision, NetStateMachine::MStateTransition, IPProtoDeftSCpr::TContext) +void IPProtoDeftSCpr::TStoreProvision::DoL() + { + PRStates::TStoreProvision storeProvision(iContext); + storeProvision.DoL(); // set up iContext.Node().iProvisionConfig + + // Allocate and add the data monitoring shared memory pointers the provisioning info + CIPProtoDeftSubConnectionProvider& node = iContext.Node(); + TDataMonitoringSubConnProvisioningInfo* subConnProvisioningInfo = const_cast(static_cast(node.AccessPointConfig().FindExtension(STypeId::CreateSTypeId(TDataMonitoringSubConnProvisioningInfo::iUid, TDataMonitoringSubConnProvisioningInfo::iId)))); + ASSERT(subConnProvisioningInfo); + +#ifdef _DEBUG + _LIT8(KNote, "Note"); + if (subConnProvisioningInfo->iDataVolumesPtr || subConnProvisioningInfo->iThresholdsPtr) + { + __CFLOG_VAR((KIPProtoDeftScprTag, KNote, _L8("IPProtoDeftSCpr %x:\tNOTE: data monitoring subconnection structure re-assigned"), &node)); + } +#endif + + // In the situation where there is an existing IPProtoSCPr in the ELeaving state (which has been + // stopped and has had a TDestroy sent to it) we can safely re-assign the pointers in the (shared) + // data monitoring subconnection structure from pointing to that IPProtoSCPr instance to this one. + // This is because the IP Shim Flow corresponding to that IPProtoSCPr should not be performing any + // data transfer, after having unbound from its lower flow and closed its binders in response to a + // TDataClientStop. The structure itself is allocated in the CPR. + + ::new (subConnProvisioningInfo) TDataMonitoringSubConnProvisioningInfo(&node.iDataVolumes, &node.iThresholds); + } + +//-========================================================= +// Data monitoring support +//-========================================================= +DEFINE_SMELEMENT(TAwaitingDataMonitoringNotification, NetStateMachine::MState, IPProtoDeftSCpr::TContext) +TBool IPProtoDeftSCpr::TAwaitingDataMonitoringNotification::Accept() + { + return iContext.iMessage.IsMessage(); + } + +DEFINE_SMELEMENT(TProcessDataMonitoringNotification, NetStateMachine::MStateTransition, IPProtoDeftSCpr::TContext) +void IPProtoDeftSCpr::TProcessDataMonitoringNotification::DoL() + { + TCFDataMonitoringNotification::TDataMonitoringNotification& msg = + message_cast(iContext.iMessage); + + iContext.Node().DataNotificationL(msg); + } + +// NetCfgExtension Support +//-========================================================= +DEFINE_SMELEMENT(TAwaitingStateChangeOrCancel, NetStateMachine::MState, IPProtoDeftSCpr::TContext) +TBool IPProtoDeftSCpr::TAwaitingStateChangeOrCancel::Accept() + { + return (iContext.iMessage.IsMessage() || iContext.iMessage.IsMessage()); + } + +DEFINE_SMELEMENT(TAwaitingStateChange, NetStateMachine::MState, IPProtoDeftSCpr::TContext) +TBool IPProtoDeftSCpr::TAwaitingStateChange::Accept() + { + return (iContext.iMessage.IsMessage()); + } + +DEFINE_SMELEMENT(TAwaitingConfigureNetwork, NetStateMachine::MState, IPProtoDeftSCpr::TContext) +TBool IPProtoDeftSCpr::TAwaitingConfigureNetwork::Accept() + { + return iContext.iMessage.IsMessage(); + } + +DEFINE_SMELEMENT(TAwaitingNetworkConfiguredOrError, NetStateMachine::MState, IPProtoDeftSCpr::TContext) +TBool IPProtoDeftSCpr::TAwaitingNetworkConfiguredOrError::Accept() + { + return (iContext.iMessage.IsMessage() + || iContext.iMessage.IsMessage()); + } + +DEFINE_SMELEMENT(TNoTagOrSwallowMessage, NetStateMachine::MStateFork, IPProtoDeftSCpr::TContext) +TInt IPProtoDeftSCpr::TNoTagOrSwallowMessage::TransitionTag() + { + const RMetaExtensionContainerC& mec = iContext.Node().AccessPointConfig(); + const CNetCfgExtProvision* provision = static_cast(mec.FindExtension( + STypeId::CreateSTypeId(CNetCfgExtProvision::EUid, CNetCfgExtProvision::ETypeId))); + TCFMessage::TStateChange& msg = message_cast(iContext.iMessage); + + if (provision && KLinkLayerOpen == msg.iStateChange.iStage) + { + return KSwallowMessage; + } + else + { + return KNoTag; + } + } + +DEFINE_SMELEMENT(TStopNetCfgExtOrNoTag, NetStateMachine::MStateFork, IPProtoDeftSCpr::TContext) +TInt IPProtoDeftSCpr::TStopNetCfgExtOrNoTag::TransitionTag() + { + if (iContext.Node().iControl) + return KStopNetCfgExt; + + return KNoTag; + } + +DEFINE_SMELEMENT(TNetworkConfiguredOrErrorTagOrCancelTagOrNoTag, NetStateMachine::MStateFork, IPProtoDeftSCpr::TContext) +TInt IPProtoDeftSCpr::TNetworkConfiguredOrErrorTagOrCancelTagOrNoTag::TransitionTag() + { + if (iContext.iMessage.IsMessage()) + { + iContext.iNodeActivity->SetError(KErrCancel); + return KCancelTag; + } + + TCFMessage::TStateChange& msg = message_cast(iContext.iMessage); + + if (msg.iStateChange.iError != KErrNone) + { + iContext.iNodeActivity->SetError(msg.iStateChange.iError); + return KErrorTag; + } + + if (msg.iStateChange.iStage == KLinkLayerOpen) + { + return KNetworkConfigured; + } + + return KNoTag; + } + +DEFINE_SMELEMENT(TNetworkConfiguredOrErrorTagOrCancelTagOrNoTagBackward, NetStateMachine::MStateFork, IPProtoDeftSCpr::TContext) +TInt IPProtoDeftSCpr::TNetworkConfiguredOrErrorTagOrCancelTagOrNoTagBackward::TransitionTag() + { + TInt tag = IPProtoDeftSCpr::TNetworkConfiguredOrErrorTagOrCancelTagOrNoTag::TransitionTag(); + if (tag == KNoTag) + return tag | NetStateMachine::EBackward; + return tag; + } + +DEFINE_SMELEMENT(TErrorTagOrNoTag, NetStateMachine::MStateFork, IPProtoDeftSCpr::TContext) +TInt IPProtoDeftSCpr::TErrorTagOrNoTag::TransitionTag() + { + TEBase::TError *error = message_cast(&iContext.iMessage); + if (error) + { + iContext.iNodeActivity->SetError(error->iValue); + + return KErrorTag; + } + TCFIPProtoMessage::TNetworkConfigured* msg = message_cast(&iContext.iMessage); + + if (msg->iValue != KErrNone) + { + iContext.iNodeActivity->SetError(msg->iValue); + + return KErrorTag; + } + return KNoTag; + } + +DEFINE_SMELEMENT(TNoTagOrConfigureNetwork, NetStateMachine::MStateFork, IPProtoDeftSCpr::TContext) +TInt IPProtoDeftSCpr::TNoTagOrConfigureNetwork::TransitionTag() + { + const RMetaExtensionContainerC& mec = iContext.Node().AccessPointConfig(); + const CNetCfgExtProvision* provision = static_cast(mec.FindExtension( + STypeId::CreateSTypeId(CNetCfgExtProvision::EUid, CNetCfgExtProvision::ETypeId))); + + if (provision) + { + return KConfigureNetwork; + } + else + { + return KNoTag; + } + } + +DEFINE_SMELEMENT(TNoTagOrProviderStoppedOrDaemonReleased, NetStateMachine::MStateFork, IPProtoDeftSCpr::TContext) +TInt IPProtoDeftSCpr::TNoTagOrProviderStoppedOrDaemonReleased::TransitionTag() + { + iContext.iNodeActivity->SetError(message_cast(iContext.iMessage).iValue); + if (iContext.Node().GetFirstClient(TClientType(TCFClientType::EData, TCFClientType::EStarted)) != NULL) + { + // At least one data client started + if(iContext.Node().iControl) + { + return MeshMachine::KNoTag; + } + else + { + return KDaemonReleased; + } + } + return CoreNetStates::KProviderStopped; + } + +DEFINE_SMELEMENT(TDaemonReleasedStateChangedOrNoTagBackward, NetStateMachine::MStateFork, IPProtoDeftSCpr::TContext) +TInt IPProtoDeftSCpr::TDaemonReleasedStateChangedOrNoTagBackward::TransitionTag() + { + TInt tag = IPProtoDeftSCpr::TDaemonReleasedStateChangedOrNoTag::TransitionTag(); + if (tag == KNoTag) + return tag | NetStateMachine::EBackward; + return tag; + } + +DEFINE_SMELEMENT(TDaemonReleasedStateChangedOrNoTag, NetStateMachine::MStateFork, IPProtoDeftSCpr::TContext) +TInt IPProtoDeftSCpr::TDaemonReleasedStateChangedOrNoTag::TransitionTag() + { + TCFMessage::TStateChange& msg = message_cast(iContext.iMessage); + + if (msg.iStateChange.iStage == KConfigDaemonFinishedDeregistrationStop) + { + return KDaemonReleasedStateChanged; + } + return KNoTag; + } + +DEFINE_SMELEMENT(TConfigureNetwork, NetStateMachine::MStateTransition, IPProtoDeftSCpr::TContext) +void IPProtoDeftSCpr::TConfigureNetwork::DoL() + { + iContext.iNodeActivity->PostRequestTo(iContext.NodeId(), TCFIPProtoMessage::TConfigureNetwork().CRef()); + } + +DEFINE_SMELEMENT(TSendNetworkConfigured, NetStateMachine::MStateTransition, IPProtoDeftSCpr::TContext) +void IPProtoDeftSCpr::TSendNetworkConfigured::DoL() + { + TCFIPProtoMessage::TNetworkConfigured resp(iContext.iNodeActivity->Error()); + iContext.iNodeActivity->SetError(KErrNone); + iContext.iNodeActivity->PostToOriginators(resp); + } + +DEFINE_SMELEMENT(TStartNetCfgExt, NetStateMachine::MStateTransition, IPProtoDeftSCpr::TContext) +void IPProtoDeftSCpr::TStartNetCfgExt::DoL() + { + ASSERT(!iContext.Node().iNotify); + ASSERT(!iContext.Node().iControl); + + iContext.Node().iNotify = CNetCfgExtNotify::NewL(&iContext.Node()); + iContext.Node().iControl = CNifConfigurationControl::NewL(*iContext.Node().iNotify); + iContext.Node().iControl->ConfigureNetworkL(); + } + + +DEFINE_SMELEMENT(TStopNetCfgExt, NetStateMachine::MStateTransition, IPProtoDeftSCpr::TContext) +void IPProtoDeftSCpr::TStopNetCfgExt::DoL() + { + if(!iContext.Node().iControl) return; + + iContext.Node().iControl->Deregister(EConfigDaemonDeregisterCauseStop); + } + +DEFINE_SMELEMENT(TStopNetCfgExtDelete, NetStateMachine::MStateTransition, IPProtoDeftSCpr::TContext) +void IPProtoDeftSCpr::TStopNetCfgExtDelete::DoL() + { + if(!iContext.Node().iControl) + { + return; + } + iContext.Node().iControl->AsyncDelete(); + iContext.Node().iControl = NULL; + + delete iContext.Node().iNotify; + iContext.Node().iNotify = NULL; + } + +DEFINE_SMELEMENT(TResetSentTo, NetStateMachine::MStateTransition, IPProtoDeftSCpr::TContext) +void IPProtoDeftSCpr::TResetSentTo::DoL() + { + iContext.iNodeActivity->ClearPostedTo(); + } + +//-========================================================= +// Ioctl Support +//-========================================================= +DEFINE_SMELEMENT(TAwaitingIoctlProcessed, NetStateMachine::MState, IPProtoDeftSCpr::TContext) +TBool IPProtoDeftSCpr::TAwaitingIoctlProcessed::Accept() + { + return iContext.iMessage.IsMessage(); + } + +void IPProtoDeftSCpr::TAwaitingIoctlProcessed::Cancel() + { + CIPProtoDeftSubConnectionProvider* node = static_cast(&iContext.Node()); + if (node->iControl) + { + node->iControl->CancelControl(); + } + + iContext.Activity()->SetError(KErrCancel); + } + +DEFINE_SMELEMENT(TNoTagOrTryNetCfgExt, NetStateMachine::MStateFork, IPProtoDeftSCpr::TContext) +TInt IPProtoDeftSCpr::TNoTagOrTryNetCfgExt::TransitionTag() + { + TCFLegacyMessage::TLegacyRMessage2Processed& msg = message_cast(iContext.iMessage); + + if ((msg.iResponse.iType == ESock::TLegacyRMessage2Response::ENormal && msg.iResponse.iCode == KErrNone) + || msg.iResponse.iType == ESock::TLegacyRMessage2Response::EPanic) + { + return KNoTag; + } + else + { + return KTryNetCfgExt; + } + } + +DEFINE_SMELEMENT(TTryServiceProviderOrTryNetCfgExt, NetStateMachine::MStateFork, IPProtoDeftSCpr::TContext) +TInt IPProtoDeftSCpr::TTryServiceProviderOrTryNetCfgExt::TransitionTag() + { + MeshMachine::CNodeParallelMessageStoreActivityBase* act = static_cast(iContext.Activity()); + + ASSERT(act->Message().IsTypeOf(Meta::STypeId::CreateSTypeId(TCFSigLegacyRMessage2Ext::EUid, TCFSigLegacyRMessage2Ext::ETypeId))); + if ((static_cast(act->Message()).iMessage.Int0() == KCOLConfiguration + && static_cast(act->Message()).iMessage.Int1() == KConnGetSipServerAddr)) + { + return KTryServiceProvider; + } + else + { + return KTryNetCfgExt; + } + } + +DEFINE_SMELEMENT(TForwardToServiceProvider, NetStateMachine::MStateTransition, IPProtoDeftSCpr::TContext) +void IPProtoDeftSCpr::TForwardToServiceProvider::DoL() + { + ASSERT(iContext.iMessage.IsTypeOf(Meta::STypeId::CreateSTypeId(TCFSigLegacyRMessage2Ext::EUid, TCFSigLegacyRMessage2Ext::ETypeId))); + + MeshMachine::CNodeParallelMessageStoreActivityBase* act = static_cast(iContext.Activity()); + + TCFSigLegacyRMessage2Ext::RReadOnlyRMessage& ioctl(static_cast(act->Message()).iMessage); + RLegacyResponseMsg r(iContext, static_cast(act->Message()).iMessage, static_cast(act->Message()).iMessage.Int0()); + + // currently only supporting configuration ioctls + if (ioctl.Int0() == KCOLConfiguration && ioctl.Int1() == KConnGetSipServerAddr) + { + TSipServerAddrBuf sipAddr; + if (ioctl.GetDesLengthL(2) != sipAddr.Length()) + { + r.Panic(KESockClientPanic, EBadDescriptor); + act->ClearPostedTo(); + return; // the sip address handlers will complete the message + } + } + + RNodeInterface* dc = iContext.Node().GetFirstClient(TClientType(TCFClientType::EServProvider)); + + iContext.Activity()->PostRequestTo(*dc, iContext.iMessage); + } + +DEFINE_SMELEMENT(THandoffToNetCfgExt, NetStateMachine::MStateTransition, IPProtoDeftSCpr::TContext) +void IPProtoDeftSCpr::THandoffToNetCfgExt::DoL() + { + ASSERT(iContext.Activity()); + MeshMachine::CNodeParallelMessageStoreActivityBase* act = static_cast(iContext.Activity()); + + TCFSigLegacyRMessage2Ext::RReadOnlyRMessage& ioctl(static_cast(act->Message()).iMessage); + RLegacyResponseMsg r(iContext, static_cast(act->Message()).iMessage, static_cast(act->Message()).iMessage.Int0()); + + if (ioctl.Int0() == KCOLConfiguration && ioctl.Int1() == KConnGetSipServerAddr) + { + TCFSigLegacyRMessage2Ext::RReadOnlyRMessage& ioctl(static_cast(act->Message()).iMessage); + TSipServerAddrBuf sipAddr; + if (ioctl.GetDesLengthL(2) != sipAddr.Length()) + { + r.Panic(KESockClientPanic, EBadDescriptor); + act->ClearPostedTo(); + return; // the sip address handlers will complete the message + } + } + + if ((ioctl.Int0() == KCOLConfiguration && ioctl.Int1() == KConnGetSipServerAddr)) + { + TSipServerAddrBuf sipBuf; + ioctl.ReadL( 2, sipBuf ); + + if( sipBuf().index != 0 ) + { + r.Complete(KErrNotFound); + act->ClearPostedTo(); + return; + } + } + + // IPProto returns KErrNotSupported if DHCP is not configured for the IAP + // so we want to make sure DHCP fallback is only ever tried once for index + // zero. Otherwise, the last address index that the caller tries may return + // KErrNotSupported instead of the expected KErrNotFound. + if (iContext.Node().iControl) + { + iContext.Node().iControl->SendIoctlMessageL(r); + act->ClearPostedTo(); + } + else + { + const RMetaExtensionContainerC& mec = iContext.Node().AccessPointConfig(); + const CNetCfgExtProvision* provision = static_cast(mec.FindExtension( + STypeId::CreateSTypeId(CNetCfgExtProvision::EUid, CNetCfgExtProvision::ETypeId))); + + if (provision) + { + r.Complete(KErrNotReady); + act->ClearPostedTo(); + } + else + { + r.Complete(KErrNotSupported); + act->ClearPostedTo(); + } + } + } + +// +// support for AgentEventNotification +// +DEFINE_SMELEMENT(TAwaitingAgentEventNotification, NetStateMachine::MState, IPProtoDeftSCpr::TContext) +TBool IPProtoDeftSCpr::TAwaitingAgentEventNotification::Accept() + { + return iContext.iMessage.IsMessage(); + } + +DEFINE_SMELEMENT(TProcessAgentEvent, NetStateMachine::MStateTransition, IPProtoDeftSCpr::TContext) +void IPProtoDeftSCpr::TProcessAgentEvent::DoL() + { + if (iContext.Node().iControl) + { + // AgentEventNotification originates from the AgentSCPr as a result of an AgentEvent() + // call from the Agent. Although the message is generic, it was primarily created to pass the + // event ECurrentNetworkChangeEvent from the Agent towards the NetCfgExt for CDMA2000 support. + // The "aEventData" and "aSource" fields of the EventNotification() call are not used for this + // event, and hence are passed as null values. + TLinkMessage::TAgentEventNotification& msg = message_cast(iContext.iMessage); + iContext.Node().iControl->EventNotification(TNetworkAdaptorEventType(msg.iValue1), msg.iValue2, KNullDesC8, NULL); + } + } +