sipproviderplugins/sipprovider/sipconnectionplugins/src/sipcpr.cpp
changeset 0 307788aac0a8
child 4 dd3853b8dc3f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sipproviderplugins/sipprovider/sipconnectionplugins/src/sipcpr.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,277 @@
+// 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 Connection Provider implementation
+// 
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include <comms-infras/ss_log.h>
+#include <comms-infras/corecprstates.h>
+#include <comms-infras/corecpractivities.h>
+#include <comms-infras/metatype.h>
+#include "sipcpr.h"
+#include "sipcprstates.h"
+#include "sipprovisioninfo.h"
+#include <elements/mm_states.h>
+
+
+using namespace SipCprStates;
+using namespace SipCpr;
+using namespace ESock;
+using namespace NetStateMachine;
+using namespace Messages;
+using namespace MeshMachine;
+using namespace Meta;
+using namespace CprActivities;
+
+//
+//=========================================================
+//
+// Activities
+//
+//-=========================================================
+
+
+
+// provision activity to store provision message containing TransitionEngineMgr,ProfileId,appUid
+// from MCPR
+namespace SipCprProvisionActivity
+{
+DECLARE_DEFINE_NODEACTIVITY(ECFActivityStoreProvision, SipCprProvision, TCFDataClient::TProvisionConfig)
+	FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingProvision,  MeshMachine::TNoTagOrErrorTag)	
+	LAST_NODEACTIVITY_ENTRY(KNoTag, SipCprStates::TStoreProvision)	
+NODEACTIVITY_END()
+}
+
+
+namespace SipCprBinderRequestActivity
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityBinderRequest, SipCprBinderRequest, TCFServiceProvider::TCommsBinderRequest, PRActivities::CCommsBinderActivity::NewL)
+	FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingBinderRequest,PRActivities::CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExistingDefaultBlockedByBinderRequest)		
+	NODEACTIVITY_ENTRY(KNoTag, PRStates::TCreateDataClient, CoreNetStates::TAwaitingDataClientJoin, MeshMachine::TNoTag)    	
+	NODEACTIVITY_ENTRY(CoreNetStates::KWaitForIncoming, SipCprStates::TProcessWaitForIncmg, CoreNetStates::TAwaitingDataClientJoin, MeshMachine::TNoTag)	
+	// Below this point we need to modify the error handling approach. If we're getting a TError on TBinderResponse,
+	// this means the client requesting the binder couldn't bind to it. As far as the client is concerned, this
+	// activity is finished (it has flagged an error). The standard error handling will result in erroring
+	// the originator. In this case we shouoldn't error the originator, instead, wrap up quietly.
+	
+	THROUGH_NODEACTIVITY_ENTRY(KNoTag, SipCprStates::TProcessSCPRCreation, SipCprStates::TWaitForIncomingOrUseExisting)
+	// Wait for the incomingconnection message from SIP SCPR 
+	NODEACTIVITY_ENTRY(CoreNetStates::KWaitForIncoming,SipCprStates::TSetPostedToScpr, SipCprStates::TAwaitingIncomingConnection, MeshMachine::TTag<CoreStates::KUseExisting>)
+	NODEACTIVITY_ENTRY(CoreStates::KUseExisting, PRActivities::CCommsBinderActivity::TSendBinderResponse, PRActivities::CCommsBinderActivity::TAwaitingBindToComplete/*CoreNetStates::TAwaitingBindToComplete*/, MeshMachine::TNoTagOrErrorTag)	
+	LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)	
+	LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TRaiseAndClearActivityError)
+	
+NODEACTIVITY_END() 
+}
+
+//start activity
+//this could have a race condition.Please check SipCprStates::RegisterCpr
+namespace SipCprStartActivity
+{
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStart, SipCprStart, TCFServiceProvider::TStart, PRActivities::CStartActivity::NewL)
+    FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingStart, SipCprStates::TNoTagOrRegisteredBlockedByStop)		
+	NODEACTIVITY_ENTRY(KNoTag, SipCprStates::TRegisterCpr, SipCprStates::TAwaitingRegistrationComplete, MeshMachine::TNoTagOrErrorTag)
+	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TStartSelf, CoreNetStates::TAwaitingDataClientStarted, MeshMachine::TNoTag)
+	LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendStarted)	
+	LAST_NODEACTIVITY_ENTRY(SipCprStates::KRegistered, CoreNetStates::TSendStarted)	
+	LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TRaiseAndClearActivityError)
+NODEACTIVITY_END()
+}
+
+namespace SipCprStopActivity
+{
+DECLARE_DEFINE_NODEACTIVITY(ECFActivityStop, SipCprStop, TCFServiceProvider::TStop)
+	FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingStop, MeshMachine::TActiveOrNoTag<ECFActivityStartDataClient>)	
+	THROUGH_NODEACTIVITY_ENTRY(MeshMachine::KActiveTag, CoreNetStates::TCancelDataClientStart, MeshMachine::TNoTag)
+	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientStopped, SipCprStates::TNoTagOrDeRegister)
+	NODEACTIVITY_ENTRY(SipCprStates::KDeRegister, SipCprStates::TDeRegisterCpr, SipCprStates::TAwaitingDeRegistrationComplete, MeshMachine::TNoTagOrErrorTag)
+	LAST_NODEACTIVITY_ENTRY(KNoTag, /*SipCprStates::TSendStopped*/PRStates::TSendStoppedAndGoneDown)
+	LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TRaiseAndClearActivityError)	
+NODEACTIVITY_END()
+}
+
+//Activity Map
+namespace SipCprActivities	
+	{	
+	DECLARE_DEFINE_ACTIVITY_MAP(activityMap)
+		ACTIVITY_MAP_ENTRY(SipCprProvisionActivity, SipCprProvision)
+		ACTIVITY_MAP_ENTRY(SipCprBinderRequestActivity, SipCprBinderRequest)
+		ACTIVITY_MAP_ENTRY(SipCprStartActivity, SipCprStart)
+		ACTIVITY_MAP_ENTRY(SipCprStopActivity, SipCprStop)				
+		
+	ACTIVITY_MAP_END_BASE(CprActivities, coreCprActivities)	
+	}
+
+
+//-=========================================================
+//
+// CSipConnectionProvider methods
+//
+//-=========================================================	
+   	
+/**
+Creates the SIP connection provider
+*/
+CSipConnectionProvider* CSipConnectionProvider::NewL(CConnectionProviderFactoryBase& aFactory)
+    {
+    __CFLOG_VAR((KSipCprTag, KSipCprSubTag, _L8("CSipConnectionProvider:\tNewL()")));    
+    CSipConnectionProvider* prov = new (ELeave) CSipConnectionProvider(aFactory);
+    CleanupStack::PushL(prov);
+    prov->ConstructL();
+    CleanupStack::Pop(prov);
+    return prov;
+    }
+    
+void CSipConnectionProvider::ConstructL()
+    {    
+    CCoreConnectionProvider::ConstructL();
+    iProvisionInfo = NULL;
+    iTransitionEngine = NULL;
+    iIsIncoming = NULL;    
+    }    
+
+/**
+Frees the memory for the transition engine
+*/
+CSipConnectionProvider::~CSipConnectionProvider()
+    {
+    __CFLOG_VAR((KSipCprTag, KSipCprSubTag, _L8("CSipConnectionProvider:\t ~CSipConnectionProvider()")));
+    LOG_NODE_DESTROY(KSipCprTag, CSipConnectionProvider); 
+	if(iTransitionEngine)
+    iTransitionEngineMgr->Detach(iTransitionEngine);    
+	//delete 	iProvisionInfo;	
+	iProvisionInfo = NULL;	
+    }
+
+CSipConnectionProvider::CSipConnectionProvider(ESock::CConnectionProviderFactoryBase& aFactory)
+	: CCoreConnectionProvider(aFactory, SipCprActivities::activityMap::Self()),
+	  iStage(EFresh),iConnStatus(EConnOutgoing)
+    {
+    LOG_NODE_CREATE(KSipCprTag, CSipConnectionProvider);
+    iSelf.Open(NodeId());
+    }
+    
+ 
+void CSipConnectionProvider::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage)
+    {
+	TNodeContext<CSipConnectionProvider> ctx(*this, aMessage, aSender, aRecipient);
+    CCoreConnectionProvider::Received(ctx);
+    User::LeaveIfError(ctx.iReturn);
+	}
+
+/*
+Constructs SIP CPR provision and appends it to the access point config
+*/
+void CSipConnectionProvider::SetConfigL()
+	{	 
+	// This function will be called two times while creation of default SCPR
+	// and non-default SCPR.
+	if (iProvisionInfo != NULL)
+		{
+		//delete 	iProvisionInfo;	
+		iProvisionInfo = NULL;		
+		}	
+		
+	iProvisionInfo = new (ELeave) TSipCprProvisionInfo();
+	
+	iProvisionInfo->iTransitionEngine = GetTE();
+		
+	//its safe to get the iFromField only after Registration.
+	//We assume that the since SetConfig is invoked by the Send Provision activity
+	//registration would have already been done	
+	
+	if(iFromField == NULL && iTransitionEngine != NULL)
+		{
+		iFromField = const_cast<TDesC8* >(iTransitionEngine->GetFromField(iProfileId));
+		iProvisionInfo->iFromField = iFromField;
+		}
+	
+	// A local object for RMetaExtensionContainer is created which has it's own base container class 
+	// and the extension is appended into the array of this base container class.
+	// At the second time for non- default scpr when this function is called again a new local copy of
+	// RMetaExtensionContainer is created and the previous extension added is not present in the array of this object. 
+	// The extension is added in new container class without panicing the code.
+	
+		RMetaExtensionContainer mec;
+		mec.Open(AccessPointConfig());
+		CleanupClosePushL(mec);
+		mec.AppendExtensionL(iProvisionInfo);
+		AccessPointConfig().Close();
+		AccessPointConfig().Open(mec);
+		CleanupStack::PopAndDestroy(&mec);
+					
+	}	
+	
+//-=========================================================
+// MSIPRegistrationClient methods
+//-=========================================================
+// Will be called when the registration is successful
+void CSipConnectionProvider::RegistrationComplete(TInt aError)
+	{
+	__CFLOG_VAR((KSipCprTag, KSipCprSubTag, _L8("CSipConnectionProvider::RegistrationComplete() errorcode=%d"), aError));
+	ASSERT(iStage == SipCpr::EStarting);	
+	
+	// Send the RegistrationComplete message for waiting start activity
+	iSelf.PostMessage(TNodeCtxId(iActivityAwaitingResponse, Id()),TSipCprMessages::TRegistrationComplete(aError).CRef());
+	iActivityAwaitingResponse = MeshMachine::KActivityNull;
+	}
+
+
+// Will be called when the De-Registration is successful
+void CSipConnectionProvider::DeRegistrationComplete(TInt aError)
+	{
+	__CFLOG_VAR((KSipCprTag, KSipCprSubTag, _L8("CSipConnectionProvider::DeRegistrationComplete() errorcode=%d"), aError));
+	ASSERT(iStage == SipCpr::EStopping);
+	iStage = SipCpr::EStopped;
+	
+	// Send the De-RegistrationComplete message for waiting stop activity
+	iSelf.PostMessage(TNodeCtxId(iActivityAwaitingResponse, Id()),TSipCprMessages::TDeRegistrationComplete(aError).CRef());
+	iActivityAwaitingResponse = MeshMachine::KActivityNull;
+	}
+
+
+// will be called when error occured. The error can occur either in registration or de-registration
+void CSipConnectionProvider::ErrorOccurred(TInt aError)
+	{
+	__CFLOG_VAR((KSipCprTag, KSipCprSubTag, _L8("CSipConnectionProvider::ErrorOccurred() errorcode=%d"), aError));
+	
+	if (iActivityAwaitingResponse == ESock::ECFActivityStop)
+		{
+		//Error occured during DeRegistration
+    	iSelf.PostMessage(TNodeCtxId(iActivityAwaitingResponse, Id()),TSipCprMessages::TDeRegistrationComplete(aError).CRef());
+		}
+	else /*if (iActivityAwaitingResponse == ESock::ECFActivityStart)*/
+		{
+		//Error should have occured during Registration
+    	iSelf.PostMessage(TNodeCtxId(iActivityAwaitingResponse, Id()),TSipCprMessages::TRegistrationComplete(aError).CRef());
+		}	
+	}
+
+TUint32 CSipConnectionProvider::GetProfileId()
+	{
+	return iProfileId;
+	}
+TUid CSipConnectionProvider::GetAppUid()
+	{
+	return iAppUid;
+	}
+CSIPTransitionEngine* CSipConnectionProvider::GetTE()
+{
+	return iTransitionEngine;
+}