--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sipproviderplugins/sipprovider/sipconnectionplugins/src/sipscprstates.cpp Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,272 @@
+// Copyright (c) 2007-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:
+// SIP SubConnection Provider states/transitions
+//
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include "sipdeftscpr.h"
+#include "sipscpr.h"
+#include "sipscprstates.h"
+
+
+
+using namespace ESock;
+using namespace NetStateMachine;
+using namespace SipSCpr;
+using namespace SipSCprStates;
+
+
+//===========================================
+//
+// SIP Sub Connection Provider States
+//
+//===========================================
+namespace SipSCprStates
+{
+
+//===================================================================================
+//
+// StartConnection Activity
+//
+//====================================================================================
+
+DEFINE_SMELEMENT(TNoTagOrAlreadyStarted,NetStateMachine::MStateFork, SipSCprStates::TContext)
+DEFINE_SMELEMENT(TStartSession, NetStateMachine::MStateTransition, SipSCprStates::TContext)
+DEFINE_SMELEMENT(TAwaitingSessionEstablished,NetStateMachine::MState, SipSCprStates::TContext)
+
+
+TInt TNoTagOrAlreadyStarted::TransitionTag()
+ {
+ if(iContext.Node().iStage == SipSCpr::EActive)
+ {
+ return CoreNetStates::KAlreadyStarted;
+ }
+ return MeshMachine::KNoTag;
+ }
+
+void TStartSession::DoL()
+ {
+ //check error conditions before starting sip session
+ TInt stage = iContext.Node().iStage;
+ const Messages::TNodeId& self = iContext.Node().NodeId();
+ if(stage != SipSCpr::EFresh)
+ {
+ switch(stage)
+ {
+ case SipSCpr::EStopped:
+ __CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("Cannot start stopped subconnection")));
+
+ Messages::RClientInterface::OpenPostMessageClose(self,Messages::TNodeCtxId(ECFActivityStart,self),TSipSCprMessages::TSipSessionEstablished(KErrAbort).CRef());
+ break;
+ case SipSCpr::EStopping:
+ __CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("Cannot start stopping subconnection")));
+ Messages::RClientInterface::OpenPostMessageClose(self,Messages::TNodeCtxId(ECFActivityStart,self),TSipSCprMessages::TSipSessionEstablished(KErrAbort).CRef());
+ break;
+ }
+ }
+
+ //In the case of SIP SubConnection, the session params should be be set before we start a call.
+ TSipParams& sipParams = iContext.Node().iSipSm->GetSipParams();
+ // Check should be made only to non-incoming request. For incoming request the
+ // sipParams won't be set in SIP SCPR. The incoming params will be saved in iParameterBundle
+ TInt err;
+ if(!(iContext.Node().iAwaitingSubConnection) && sipParams.iRequest == TSipHLConsts::ERequestNone)
+ {
+ __CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("Cannot start SIP subconnection if Params are notset")));
+ err = KErrNotSupported;
+ }
+ else
+ {
+ if (iContext.Node().subconType == RSubConnection::EWaitIncoming)
+ {
+ __CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("appears to be an incoming call subconection, accepting")));
+ err = iContext.Node().iSipSm->AcceptCall();
+ }
+ else
+ {
+ err = iContext.Node().iSipSm->StartCall();
+ }
+ }
+
+ if (KErrNone != err)
+ {
+ __CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("Cannot start SIP subconnection if Params are notset")));
+ Messages::RClientInterface::OpenPostMessageClose(self,Messages::TNodeCtxId(ECFActivityStart,self),TSipSCprMessages::TSipSessionEstablished(err).CRef());
+ }
+ //Expect Response
+ iContext.Node().iActivityAwaitingResponse = iContext.iNodeActivity->ActivityId();
+ iContext.iNodeActivity->SetPostedTo(iContext.Node().NodeId());
+ iContext.Node().iStage = SipSCpr::EStarting;
+ }
+
+TBool TAwaitingSessionEstablished::Accept()
+ {
+ if(iContext.iMessage.IsMessage<TSipSCprMessages::TSipSessionEstablished>())
+ {
+ TSipSCprMessages::TSipSessionEstablished* msg = Messages::message_cast<TSipSCprMessages::TSipSessionEstablished>(&iContext.iMessage);
+ if (msg->iValue == KErrNone)
+ {
+ // This means we have a successful session
+ iContext.Node().iStage = SipSCpr::EActive;
+ return ETrue;
+ }
+ else
+ {
+ //session start failed
+ //Set the error for activity and will be cleared using TClearError
+ TInt error = msg->iValue;
+ iContext.iNodeActivity->SetError(error);
+ return ETrue;
+ }
+ }
+
+ return EFalse;
+ }
+
+//========================================================================================================
+//
+// Stop Activiity
+//
+//========================================================================================================
+
+DEFINE_SMELEMENT(TNoTagOrAlreadyStopped, NetStateMachine::MStateFork, SipSCprStates::TContext)
+DEFINE_SMELEMENT(TStopSession, NetStateMachine::MStateTransition, SipSCprStates::TContext)
+DEFINE_SMELEMENT(TAwaitingSessionTerminated,NetStateMachine::MState, SipSCprStates::TContext)
+
+
+TInt TNoTagOrAlreadyStopped::TransitionTag()
+ {
+
+ //iStage defined only for non-deft SCPR
+ TInt stage = iContext.Node().iStage;
+ if (iContext.Node().iStage && iContext.Node().iStage >= SipSCpr::EStopping)
+ {
+ return CoreNetStates::KAlreadyStopped;
+ }
+ return MeshMachine::KNoTag;
+ }
+
+void TStopSession::DoL()
+ {
+ __CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("AStopSession::DoL")));
+
+ //there's no need to check message type before casting as it should've been checked
+ //by the State::Accept() => cast & assert if not the desired type
+ iContext.Node().iStopCode = Messages::message_cast<TCFServiceProvider::TStop>(iContext.iMessage).iValue;
+ TInt err;
+
+ if (iContext.Node().iStage == SipSCpr::EFresh)
+ {
+ err = KErrNotReady;
+ }
+ //If this is an incoming call that hasn't been accepted yet. We should
+ //reject it. Otherwise we should just stop it.
+ else if (iContext.Node().iAwaitingSubConnection && iContext.Node().iStage == SipSCpr::EStarting)
+ {
+ err = iContext.Node().iSipSm->RejectCall();
+ }
+ else
+ {
+ err = iContext.Node().iSipSm->StopCall();
+ }
+
+ if (KErrNone != err)
+ {
+ __CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("Cannot stop SIP subconnection if Params are notset")));
+ const Messages::TNodeId& self = iContext.Node().NodeId();
+ Messages::RClientInterface::OpenPostMessageClose(self,Messages::TNodeCtxId(ECFActivityStop,self),TSipSCprMessages::TSipSessionTerminated(err).CRef());
+ }
+
+ iContext.Node().iActivityAwaitingResponse = iContext.iNodeActivity->ActivityId();
+ iContext.iNodeActivity->SetPostedTo(iContext.Node().NodeId());
+ iContext.Node().iStage = SipSCpr::EStopping;
+ }
+
+TBool TAwaitingSessionTerminated::Accept()
+ {
+ if(iContext.iMessage.IsMessage<TSipSCprMessages::TSipSessionTerminated>())
+ {
+ TSipSCprMessages::TSipSessionTerminated* msg = Messages::message_cast<TSipSCprMessages::TSipSessionTerminated>(&iContext.iMessage);
+ if (msg->iValue == KErrNone)
+ {
+ iContext.Node().iStage = SipSCpr::EStopped;
+ return ETrue;
+ }
+ else
+ {
+ //Set the error for activity and will be cleared using TClearError
+ TInt error = msg->iValue;
+ iContext.iNodeActivity->SetError(error);
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+
+//=================================================================================================
+//
+//Set Params
+//
+//==================================================================================================
+
+DEFINE_SMELEMENT(TSetParameters,NetStateMachine::MStateTransition, SipSCprStates::TContext)
+void TSetParameters::DoL()
+ {
+ TRAPD(err, iContext.Node().DoParametersAboutToBeSetL(iContext.Node().iParameterBundle));
+ if(KErrNone != err)
+ {
+ __CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("call to DoParemetersAboutToBeSet failed in ASetParameters::DoL() [error=%d]"), err));
+ User::Leave(err);
+ }
+#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+ iContext.PostToSender(TCFScpr::TSetParamsResponse(iContext.Node().iParameterBundle).CRef());
+#else
+ iContext.PostToSender(TCFScpr::TParamsResponse(iContext.Node().iParameterBundle).CRef());
+#endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+ }
+
+
+
+DEFINE_SMELEMENT(TStoreProvision, NetStateMachine::MStateTransition, SipSCprStates::TContext)
+void TStoreProvision::DoL()
+ {
+ __CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("AStoreProvision::DoL()")));
+ PRStates::TStoreProvision storeProvision(iContext);
+ storeProvision.DoL();
+
+ const TSipCprProvisionInfo* ext = static_cast<const TSipCprProvisionInfo*>(iContext.Node().AccessPointConfig().FindExtension(STypeId::CreateSTypeId(TSipCprProvisionInfo::EUid, TSipCprProvisionInfo::ETypeId)));
+ if (ext)
+ {
+ iContext.Node().iTransitionEngine = ext->iTransitionEngine;
+ iContext.Node().iFromField = ext->iFromField;
+
+ // Set the falg for WaitForIncoming connection
+ if (iContext.Node().iAwaitingSubConnection)
+ {
+ iContext.Node().iActivityAwaitingResponse = iContext.ActivityId();
+ }
+ // Create the SIP state machine
+ iContext.Node().CreateStateMachineL();
+ __CFLOG_VAR((KSipSCprTag, KSipSCprSubTag, _L8("CSipSubConnectionProvider::TStoreProvision() [this=%08x]\t -- SIP State Machine created "), this));
+
+ }
+ }
+}//namespace SipSCprStates
+