diff -r 000000000000 -r 307788aac0a8 sipproviderplugins/sipprovider/sipconnectionplugins/src/sipcpr.cpp --- /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 +#include +#include +#include +#include "sipcpr.h" +#include "sipcprstates.h" +#include "sipprovisioninfo.h" +#include + + +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) + 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) + 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 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(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; +}