diff -r 000000000000 -r 307788aac0a8 sipproviderplugins/sipprovider/sipstatemachine/src/transitionengine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sipproviderplugins/sipprovider/sipstatemachine/src/transitionengine.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,1092 @@ +// Copyright (c) 2005-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: +// CSIPTransitionEngine implementation file. +// +// + +/** + @file + @internalComponent +*/ + + +#include "transitionengine.h" +#include "SipStateMachine.h" +#include + + +CSIPTransitionEngine* CSIPTransitionEngine::NewL(CSIP& aSip, TInt aIapId) +/** +Transition Engine Instantiation Function +*/ + { + CSIPTransitionEngine * self = new (ELeave) CSIPTransitionEngine(aSip, aIapId); + CleanupStack::PushL (self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + + +void CSIPTransitionEngine::ConstructL() +/** +2nd Phase construction +*/ + { + __FLOG_1(_L("CSIPTransitionEngine %08x:\tConstructL(), expect 'ConstructL successful', otherwise the method left"), this); + ASSERT(iConnection == NULL); + + // Startup Nokia Stack Related Objects + iConnState = CSIPConnection::EInactive; + + __FLOG_1(_L("CSIPTransitionEngine %08x:\tInstantiating CSIPProfileRegistry - may leave"), this); + iProfileRegistry = CSIPProfileRegistry::NewL(iSIP, *this); + CleanupStack::PushL(iProfileRegistry); + __FLOG_1(_L("CSIPTransitionEngine %08x:\tInstantiating CSIPHttpDigest - may leave"), this); + iDigest = CSIPHttpDigest::NewL(iSIP, *this ); + CleanupStack::PushL(iDigest); + __FLOG_1(_L("CSIPTransitionEngine %08x:\tInstantiating CSIPConnection - may leave"), this); + iConnection = CSIPConnection::NewL(iSIP, iIapId, *this ); + + // Wait for the connectio to become Active + if( iConnection->State() == CSIPConnection::EInit ) + { + iActiveWait.Start(); + } + + __FLOG_1(_L("CSIPTransitionEngine %08x:\tConstructL successful"), this); + CleanupStack::Pop(2); + } + +CSIPTransitionEngine::CSIPTransitionEngine(CSIP& aSip, TInt aIapId) +:iIapId(aIapId), + iSIP(aSip) +/** +constructor +*/ + { + // Open Logs + __FLOG_OPEN(_L8("SipStateMachine"), _L8("TransitionEngine")); + __FLOG_1(_L("[TransitionEngine]:[%x]::CSIPTransitionEngine() "), this); + } + + +CSIPTransitionEngine::~CSIPTransitionEngine() +/** +Destructor , cleanup wil be done here +*/ + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine [%x]::~CSIPTransitionEngine"), this); + // Delete all the State Machines that are there registered + // with the TE + CHLStateMachine *hlSm = NULL; + TInt numElements = iSMArray.Count(); + for(TInt count=0; countiDialog = NULL; + hlSm->iTransaction = NULL; + delete hlSm; + } + iSMArray.Close(); + + // Clean Profiles + numElements = iProfileArray.Count(); + for (TInt count = 0; count> CSIPTransitionEngine [%x]::~CSIPTransitionEngine"), this); + __FLOG_CLOSE; + } + +void CSIPTransitionEngine::ConnectionStateChanged( CSIPConnection::TState aState ) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine [%x]::ConnectionStateChanged()"), this); + // No Matter what the connection state is become we have to stop the wait + if (iActiveWait.IsStarted()) + { + iActiveWait.AsyncStop(); + } + + if (iConnState == CSIPConnection::EActive && aState != CSIPConnection::EActive) + { + //CSIP Connection Lost + //Notify all Registration Clients + for ( TInt count = 0; countErrorOccurred(KErrSIPTransportFailure); + } + + } + } + + +void CSIPTransitionEngine::IncomingRequest( CSIPServerTransaction* aTransaction ) +/** +Incoming request recieved outside a dialog +*/ + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <>"),this); + CleanupStack::PushL(aTransaction); //we're take over the ownership. + + RStringF method = aTransaction->RequestElements()->Method(); + if(method == SIPStrings::StringF(SipStrConsts::EInvite)) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <>"),this); + TSipMsgBundle msgBundle; + // Create a dialog Association and set server transaction + CSIPInviteDialogAssoc* dialogassoc = CSIPInviteDialogAssoc::NewL(*aTransaction); + CleanupStack::PushL(dialogassoc); + msgBundle.iRequest = TSipHLConsts::ERequestInvite; + msgBundle.iDialog = dialogassoc; + msgBundle.iServTransaction = aTransaction; + // Look For the state machine which is responsible for handling + // this particular request + CSipStateMachine* smPtr = FindSMForIncomingCall(); + if(smPtr) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <>"),this); + smPtr->IncomingRequestOutsideDialog(msgBundle); + CleanupStack::Pop(dialogassoc); + CleanupStack::Pop(aTransaction); + } + else + {// return NotFound + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <>"),this); + __FLOG_0(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <>")); + CSIPResponseElements *ResElem = CSIPResponseElements::NewLC( + 404, SIPStrings::StringF(SipStrConsts::EPhraseNotFound)); + aTransaction->SendResponseL(ResElem); + CleanupStack::Pop(ResElem); + CleanupStack::PopAndDestroy(aTransaction); + CleanupStack::PopAndDestroy(dialogassoc); + } + } + else + { // bad request , not supported here + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <>"),this); + __FLOG_0(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <>")); + CSIPResponseElements *ResElem = CSIPResponseElements::NewLC( + 400, SIPStrings::StringF(SipStrConsts::EPhraseBadRequest)); + aTransaction->SendResponseL(ResElem); + CleanupStack::Pop(ResElem); + CleanupStack::PopAndDestroy(aTransaction); + } + } + +void CSIPTransitionEngine::IncomingRequest( CSIPServerTransaction* aTransaction, CSIPDialog& aDialog ) +/** +Incoming request recieved on an established dialog +*/ + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <>"),this); + //find state machine from associated DialogAssoc + CSipStateMachine* smPtr = FindStateMachine(aDialog); + //Extract Method + RStringF method = aTransaction->RequestElements()->Method(); + TSipMsgBundle msgBundle; + + if (method == SIPStrings::StringF(SipStrConsts::EInvite)) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <>"),this); + msgBundle.iRequest = TSipHLConsts::ERequestInvite; + } + else if (method == SIPStrings::StringF(SipStrConsts::EAck)) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <>"),this); + msgBundle.iRequest = TSipHLConsts::ERequestAck; + } + else if (method == SIPStrings::StringF(SipStrConsts::EBye)) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <>"),this); + msgBundle.iRequest = TSipHLConsts::ERequestBye; + } + else if (method == SIPStrings::StringF(SipStrConsts::ECancel)) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <>"),this); + msgBundle.iRequest = TSipHLConsts::ERequestCancel; + } + else if (method == SIPStrings::StringF(SipStrConsts::ENotify)) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <>"),this); + msgBundle.iRequest = TSipHLConsts::ERequestNotify; + } + + msgBundle.iServTransaction = aTransaction; + // Match the state machine which is associated with this message + if(smPtr) + { + __FLOG_0(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingRequest() <>")); + smPtr->IncomingRequestInsideDialog(msgBundle); + } + } + + +void CSIPTransitionEngine::IncomingResponse( CSIPClientTransaction& /*aTransaction*/ ) + { + // We will Not handle this case + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <>"),this); + } + +void CSIPTransitionEngine::IncomingResponse( CSIPClientTransaction& aTransaction, + CSIPDialogAssocBase& aDialogAssoc ) +/** +Incoming Response inside an established dialog is received +*/ + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <>"),this); + CSIPCSeqHeader* CseqHdr = (CSIPCSeqHeader*)aTransaction.ResponseElements()->CSeqHeader(); + RStringF method = CseqHdr->Method(); + TSipMsgBundle msgBundle; + msgBundle.iStatusCode = aTransaction.ResponseElements()->StatusCode(); + msgBundle.iClientTransaction = &aTransaction; + + if (method == SIPStrings::StringF(SipStrConsts::EInvite)) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <>"),this); + msgBundle.iResponse = TSipHLConsts::EResponseInvite; + } + else if (method == SIPStrings::StringF(SipStrConsts::EAck)) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <>"),this); + msgBundle.iResponse = TSipHLConsts::EResponseAck; + } + else if (method == SIPStrings::StringF(SipStrConsts::EBye)) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <>"),this); + msgBundle.iResponse = TSipHLConsts::EResponseBye; + } + else if (method == SIPStrings::StringF(SipStrConsts::ECancel)) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <>"),this); + msgBundle.iResponse = TSipHLConsts::EResponseCancel; + } + else if (method == SIPStrings::StringF(SipStrConsts::ESubscribe)) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <>"),this); + msgBundle.iResponse = TSipHLConsts::EResponseSubscribe; + } + + //Find the StateMachine associated with this Dialog + CSipStateMachine* smPtr = FindStateMachine(aDialogAssoc); + if (smPtr) + { + //Set the error code in case the status code is 3XX 6XX errors. + if(msgBundle.iStatusCode >299) + { + msgBundle.iErrCode= KErrSIPErrorResponse; + smPtr->ErrorOccured(msgBundle); + } + else + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <>"),this); + smPtr->IncomingResponse(msgBundle); + } + } +} + + +void CSIPTransitionEngine::IncomingResponse( CSIPClientTransaction& aTransaction, + CSIPInviteDialogAssoc* aDialogAssoc ) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <>"),this); + CSIPCSeqHeader * CseqHdr = (CSIPCSeqHeader*)aTransaction.ResponseElements()->CSeqHeader(); + RStringF method = CseqHdr->Method(); + TSipMsgBundle msgBundle; + msgBundle.iStatusCode = aTransaction.ResponseElements()->StatusCode(); + + if (method == SIPStrings::StringF(SipStrConsts::EInvite)) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <>"),this); + msgBundle.iResponse = TSipHLConsts::EResponseInvite; + } + else if (method == SIPStrings::StringF(SipStrConsts::EAck)) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <>"),this); + msgBundle.iResponse = TSipHLConsts::EResponseAck; + } + else if (method == SIPStrings::StringF(SipStrConsts::EBye)) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <>"),this); + msgBundle.iResponse = TSipHLConsts::EResponseBye; + } + else if (method == SIPStrings::StringF(SipStrConsts::ECancel)) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <>"),this); + msgBundle.iResponse = TSipHLConsts::EResponseCancel; + } + else if (method == SIPStrings::StringF(SipStrConsts::ESubscribe)) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <>"),this); + msgBundle.iResponse = TSipHLConsts::EResponseSubscribe; + } + + //Find the StateMachine associated with this Dialog + CSipStateMachine* smPtr = FindStateMachine(reinterpret_cast(aDialogAssoc)); + if (smPtr) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <>"),this); + smPtr->IncomingResponse(msgBundle); + } + } + +void CSIPTransitionEngine::IncomingResponse( CSIPClientTransaction& aTransaction, + CSIPRegistrationBinding& aRegistration ) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <>"),this); + + CSipStateMachine* smPtr = FindStateMachine(aTransaction); + if (smPtr) + { + TSipMsgBundle msgBundle; + if (aRegistration.IsContextActive()) // Registeration Response + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <>"),this); + msgBundle.iResponse = TSipHLConsts::EResponseRegister; + msgBundle.iStatusCode = aTransaction.ResponseElements()->StatusCode(); + smPtr->IncomingResponse(msgBundle); + } + else // Unregistration Response + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::IncomingResponse() <>"),this); + msgBundle.iResponse = TSipHLConsts::EResponseUnRegister; + msgBundle.iStatusCode = aTransaction.ResponseElements()->StatusCode(); + smPtr->IncomingResponse(msgBundle); + } + } + } + +void CSIPTransitionEngine::ErrorOccured( TInt aError, + CSIPTransactionBase& aTransaction ) +/** +This function will ask the particular state machine to handle the +error +*/ + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ErrorOccurred(TInt aError,CSIPTransactionBase& aTransaction)"),this); + CSipStateMachine* smPtr = FindStateMachine(aTransaction); + if(smPtr) + { + TSipMsgBundle errBundle; + errBundle.iErrCode = aError; + smPtr->ErrorOccured(errBundle); + } + } + +void CSIPTransitionEngine::ErrorOccured( TInt aError, + CSIPClientTransaction& aTransaction, + CSIPRegistrationBinding& /*aRegistration*/ ) +/** +Handle errors related to Failed Registration. The registration binding is destroyed by +the state machine, so need not to be destroyed here +*/ + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ErrorOccurred(TInt aError,CSIPTransactionBase& aTransaction, CSIPRegistrationBinding & aRegistration)"),this); + CSipStateMachine* smPtr = FindStateMachine(aTransaction); + if(smPtr) + { + __FLOG_0(_L("[TransitionEngine]: <>")); + TSipMsgBundle msgBundle; + msgBundle.iErrCode = aError; + msgBundle.iResponse = TSipHLConsts::EResponseRegister; + const CSIPResponseElements * resElems = aTransaction.ResponseElements(); + if(resElems) + { + msgBundle.iStatusCode = resElems->StatusCode(); + } + else + { + msgBundle.iStatusCode = -1; + } + msgBundle.iClientTransaction = &aTransaction; + smPtr->ErrorOccured(msgBundle); + } + else + { + __FLOG_0(_L("[TransitionEngine]: <>")); + } + } + +void CSIPTransitionEngine::ErrorOccured( TInt aError, + CSIPTransactionBase& /*aTransaction*/, + CSIPDialogAssocBase& aDialogAssoc) +/** +Handles the errors related to failed transaction. No need delete the transaction +or the dialogassoc , as state machine will delete those upon termination +*/ + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ErrorOccurred(TInt aError,CSIPTransactionBase& aTransaction, CSIPDialogAssocBase & aDialogAssoc)"),this); + CSipStateMachine* smPtr = FindStateMachine(aDialogAssoc); + if(smPtr) + { + __FLOG_0(_L("[TransitionEngine]: <>")); + TSipMsgBundle errBundle; + errBundle.iErrCode = aError; + // we cant get status code from response + errBundle.iStatusCode = -1; + smPtr->ErrorOccured(errBundle); + } + else + { + __FLOG_0(_L("[TransitionEngine]: <>")); + // No State Machine, Nothing to do , SM might have been terminated by some + // other request + return; + } + } + +void CSIPTransitionEngine::ErrorOccured(TInt aError, CSIPRefresh & aSIPRefresh) +/** +Handles Errors related to refresh +*/ + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ErrorOccurred(TInt aError,CSIPRefresh & aSIPRefresh)"),this); + TSipMsgBundle errBundle; + // Get The state machine associated with this particular Refresh request + const CSIPClientTransaction * clientTnx = aSIPRefresh.SIPTransaction(); + if(clientTnx) + { + __FLOG_0(_L("[TransitionEngine]: <>")); + CSipStateMachine* smPtr = FindStateMachine(clientTnx); + if(smPtr) + { + errBundle.iErrCode = aError; + const CSIPResponseElements * resElems = clientTnx->ResponseElements(); + if(resElems) + { + errBundle.iStatusCode = resElems->StatusCode(); + } + else + { + errBundle.iStatusCode = -1; + } + smPtr->ErrorOccured(errBundle); + } + else + { + // NO SM , nothing to do + } + } + else + { + __FLOG_0(_L("[TransitionEngine]: <>")); + // No Client Transaction , Noting can be done + } + } + +void CSIPTransitionEngine::ErrorOccured( TInt aError, + CSIPRegistrationBinding& aRegistration) +/** +Handles the error occurred with the periodic refreshing of an registration +binding +*/ + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ErrorOccurred(TInt aError,CSIPRegistrationBinding& aRegistration)"),this); + TSipMsgBundle errBundle; + // Get The state machine to Handle this condition + CSIPRefresh * refresh = aRegistration.SIPRefresh(); + if(refresh) + { + const CSIPClientTransaction *clientTxn = refresh->SIPTransaction(); + if(clientTxn) + { + CSipStateMachine* smPtr = FindStateMachine(clientTxn); + if(smPtr) + { + errBundle.iErrCode = aError; + const CSIPResponseElements * resElems = clientTxn->ResponseElements(); + if(resElems) + { + errBundle.iStatusCode = resElems->StatusCode(); + } + else + { + errBundle.iStatusCode = -1; + } + smPtr->ErrorOccured(errBundle); + } + else + { + // NO SM , nothing to do + } + } + else + { + // No client Txn , Nothing can be done + } + } + else + { + // No Refesh inside nothing can be done + } + } + +void CSIPTransitionEngine::ErrorOccured( TInt aError, + CSIPDialogAssocBase& aDialogAssoc) +/** +Handles SIP errors based That happens on a Existing Dialog association +*/ + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ErrorOccurred(TInt aError,CSIPDialogAssocBase& aDialogAssoc)"),this); + TSipMsgBundle errBundle; + // Find the state machine to Handle this error condition + CSipStateMachine* smPtr = FindStateMachine(aDialogAssoc); + if(smPtr) + { + __FLOG_0(_L("[TransitionEngine]: <>")); + errBundle.iErrCode = aError; + // we dont have handle to SIP message elements from here + errBundle.iStatusCode = -1; + smPtr->ErrorOccured(errBundle); + } + else + { + __FLOG_0(_L("[TransitionEngine]: <>")); + // NO SM , nothing to do + } + } + +void CSIPTransitionEngine::InviteCompleted( CSIPClientTransaction& aTransaction ) +/** +Handles the case related to the Completion of Invite Request +*/ + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::InviteCompleted()"),this); + CSipStateMachine* smPtr = FindStateMachine(aTransaction); + smPtr->InviteCompleted(aTransaction); + } + + +void CSIPTransitionEngine::InviteCanceled( CSIPServerTransaction& aTransaction ) +/** +This callback will be called when a incoming Invite is cancelled by the remote machine +*/ + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::InviteCanceled()"),this); + CSipStateMachine* smPtr = FindStateMachine(aTransaction); + TSipMsgBundle msgBundle; + msgBundle.iServTransaction = &aTransaction; + msgBundle.iRequest = TSipHLConsts::ERequestCancel; + smPtr->IncomingRequest(msgBundle); + } + +//From MSIPProfileRegistryObserver +void CSIPTransitionEngine::ProfileRegistryErrorOccurred(TUint32 aProfileId, TInt aError) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ProfileRegistryErrorOccurred()"),this); + //if(iActiveWait.IsStarted()) + // iActiveWait.AsyncStop(); + CSIPProfile* profile = NULL; + TUint32 profileId; + MSIPRegistrationClient* regClient = FindRegistrationClient(aProfileId); + + TInt size = iProfileArray.Count(); + for (TInt count = 0; countGetParameter(KSIPProfileId, profileId); + if (profileId == aProfileId) + { + iProfileRegistry->Disable(*profile); + iProfileArray.Remove(count); + delete profile; + break; + } + } + + //MSIPRegistrationClient* regClient = FindRegistrationClient(aProfileId); + if(regClient) + { + regClient->ErrorOccurred(aError); + } + } + +void CSIPTransitionEngine::ProfileRegistryEventOccurred(TUint32 aProfileId, TEvent aEvent) +/** +Handle the registry event for Registration and Deregistration +*/ + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ProfileRegistryEventOccurred()"),this); + //if(iActiveWait.IsStarted()) + // iActiveWait.AsyncStop(); + + TUint32 profileId; + CSIPProfile* profile = NULL; + MSIPRegistrationClient* regClient = FindRegistrationClient(aProfileId); + if(regClient == NULL) + { + _LIT(KSipConnProvPanic, "SIPCPR"); + User::Panic(KSipConnProvPanic, KSIPProfileNotFound); + } + switch(aEvent) + { + case EProfileRegistered: + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ProfileRegistryEventOccurred() <>"),this); + regClient->RegistrationComplete(KErrNone); + } + break; + + case EProfileDeregistered: + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ProfileRegistryEventOccurred() <>"),this); + TInt size = iProfileArray.Count(); + for (TInt count = 0; countGetParameter(KSIPProfileId, profileId); + if (profileId == aProfileId) + { + iProfileArray.Remove(count); + delete profile; + break; + } + } + regClient->DeRegistrationComplete(KErrNone); + break; + } + default: + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::ProfileRegistryEventOccurred() <>"),this); + regClient->ErrorOccurred(KErrUnknown); + } + } + + } + +CSipStateMachine* CSIPTransitionEngine::FindStateMachine(CSIPTransactionBase& aTransaction) +/** +Finds the associated state machine with the SIP transaction +*/ + { + for(TInt count = 0;countiTransaction) == aTransaction) + { + return iSMArray[count]->iStateMachine; + } + } + return NULL; + }; + +CSipStateMachine* CSIPTransitionEngine::FindStateMachine(const CSIPTransactionBase* aTransaction) +/** +Finds the associated state machine with the SIP transaction +*/ + { + for(TInt count = 0;countiTransaction == aTransaction) + { + return iSMArray[count]->iStateMachine; + } + } + return NULL; + }; + +CSipStateMachine* CSIPTransitionEngine::FindStateMachine(CSIPDialogAssocBase* aDialogAssoc) +/** +Finds the associated state machine with the SIP Dialog +*/ + { + TInt numElements = iSMArray.Count(); + for(TInt count=0; countiDialog == aDialogAssoc) + { + return iSMArray[count]->iStateMachine; + } + } + return NULL; + + }; + + +CSipStateMachine* CSIPTransitionEngine::FindStateMachine(CSIPDialog& aDialog) +/** +Finds the associated state machine with the SIP Dialog +*/ + { + TInt numElements = iSMArray.Count(); + for(TInt count=0; countiDialog))) + { + return iSMArray[count]->iStateMachine; + } + } + return NULL; + }; + + +CSipStateMachine* CSIPTransitionEngine::FindStateMachine(CSIPDialogAssocBase& aDialogAssoc) +/** +Finds the associated state machine with the SIP Dialog Assocition +*/ + { + TInt numElements = iSMArray.Count(); + for(TInt count=0; countiDialog == &aDialogAssoc) + { + return iSMArray[count]->iStateMachine; + } + } + return NULL; + }; + +EXPORT_C void CSIPTransitionEngine::AddStateMachineL(CSipStateMachine* aStateMachine) +/** +Using this call The client will register the state machine with the Transition +Engine +*/ + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::AddStateMachineL()"),this); + CHLStateMachine *hlSm = new(ELeave) CHLStateMachine; + hlSm->iStateMachine = aStateMachine; + hlSm->iDialog = NULL; + hlSm->iTransaction = NULL; + iSMArray.AppendL(hlSm); + } + +void CSIPTransitionEngine::Cleanup(CSipStateMachine * aStateMachine) +/** +Handles the cleanup related to the transition Engine +*/ + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::Cleanup()"),this); + CHLStateMachine *hlSm = NULL; + TInt numElements = iSMArray.Count(); + for(TInt count=0; countiStateMachine == aStateMachine) + { + hlSm = (CHLStateMachine*)iSMArray[count]; + hlSm->iDialog = NULL; + hlSm->iTransaction = NULL; + delete hlSm; + } + } + } + + +void CSIPTransitionEngine::SetTransaction(CSipStateMachine* aStateMachine, CSIPTransactionBase* aTransaction) +/** +Sets The transaction for a particular state machine +*/ + { + TInt numElements = iSMArray.Count(); + for(TInt count=0; countiStateMachine == aStateMachine) + { + iSMArray[count]->iTransaction = aTransaction; + } + } + } + +void CSIPTransitionEngine::SetDialogAssoc(CSipStateMachine* aStateMachine, CSIPDialogAssocBase* aDialoAssoc) +/** +Sets the dialog association for a particular state machine +*/ + { + TInt numElements = iSMArray.Count(); + for(TInt count=0; countiStateMachine == aStateMachine) + { + iSMArray[count]->iDialog = aDialoAssoc; + } + } + } + +CSipStateMachine * CSIPTransitionEngine::FindSMForIncomingCall() +/** +Find the empty state machine for handling the incoming calls +*/ + { + TInt numElements = iSMArray.Count(); + for(TInt count=0; countiTransaction == NULL && iSMArray[count]->iDialog == NULL) + { + // Check if this empty state machine is for incoming + if(iSMArray[count]->iStateMachine->GetIncomingStatus()) + { + return iSMArray[count]->iStateMachine; + } + } + } + return NULL; + } + + +EXPORT_C void CSIPTransitionEngine::RegisterL(MSIPRegistrationClient* aRegistrationClient) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::RegisterL()"),this); + TUint32 profileId = aRegistrationClient->GetProfileId(); + CSIPProfile* profile = NULL; + iRegClientArray.AppendL(aRegistrationClient); + + TInt err = KErrNone; + if(profileId == KSIPDefaultProfileId) + { + TRAP(err,profile = iProfileRegistry->DefaultProfileL()); + } + else + { + TRAP(err, profile = iProfileRegistry->ProfileL(profileId)); + } + if(err != KErrNone) + { + __FLOG_2(_L("CSIPTransitionEngine %08x:The profile [%d] hasn't been found, aborting..."), this, profileId); + User::Leave(KSIPProfileNotFound); + } + if (!iProfileRegistry->IsEnabled(*profile)) + { + __FLOG_2(_L("CSIPTransitionEngine %08x:The profile [%d] found, enabling..."), this, profileId); + TRAP(err,iProfileRegistry->EnableL( *profile, *this )); + if(err != KErrNone) + { + User::Leave(KSIPProfileNotFound); + } + iProfileArray.AppendL(profile); + } + } + + +EXPORT_C void CSIPTransitionEngine::Deregister(MSIPRegistrationClient* aRegistrationClient) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::Deregister()"),this); + TUint32 regProfId = aRegistrationClient->GetProfileId(); + TUint32 profileId; + CSIPProfile* profile; + TInt size = iProfileArray.Count(); + + for (TInt count = 0; countGetParameter(KSIPProfileId, profileId); + if (profileId == regProfId) + { + iProfileRegistry->Disable(*profile); + break; + } + } + } + + +EXPORT_C TUint32 CSIPTransitionEngine::FindDuplicateProfile(TUint32 aProfileId) + { + __FLOG_1(_L("[TransitionEngine]: CSIPTransitionEngine[%x]::FindDuplicateProfile()"),this); + // IAP,Registrar,User AOR,Contacts, Proxy, Digest User Name, Digest Realm, SecMechanism + if (aProfileId == KSIPInvalidProfileId) + { + return KSIPInvalidProfileId; + } + + CSIPProfile* profile = NULL; + TRAPD(err, profile = iProfileRegistry->ProfileL(aProfileId)); + + if (err != KErrNone) + { + return KErrNone; + } + + TUint32 thisIapId; + TUint32 thisProfileId; + const TDesC8* thisAor = NULL; + const TDesC8* thisRegistrar = NULL; + const TDesC8* thisProxy = NULL; + const TDesC8* thisRegRealm = NULL; + const TDesC8* thisProxyRealm = NULL; + const TDesC8* thisRegUser = NULL; + const TDesC8* thisProxyUser = NULL; + + profile->GetParameter(KSIPProfileId, thisProfileId); + profile->GetParameter(KSIPAccessPointId, thisIapId); + profile->GetParameter(KSIPUserAor, thisAor); + profile->GetParameter(KSIPRegistrar,KSIPServerAddress, thisRegistrar); + profile->GetParameter(KSIPOutboundProxy,KSIPServerAddress, thisProxy); + profile->GetParameter(KSIPRegistrar,KSIPDigestRealm, thisRegRealm); + profile->GetParameter(KSIPRegistrar,KSIPDigestUserName, thisRegUser); + profile->GetParameter(KSIPOutboundProxy,KSIPDigestRealm, thisProxyRealm); + profile->GetParameter(KSIPOutboundProxy,KSIPDigestUserName, thisProxyUser); + + + TInt size = iProfileArray.Count(); + + TUint32 iapId; + TUint32 profileId; + const TDesC8* aor = NULL; + const TDesC8* registrar = NULL; + const TDesC8* proxy = NULL; + const TDesC8* regRealm = NULL; + const TDesC8* proxyRealm = NULL; + const TDesC8* regUser = NULL; + const TDesC8* proxyUser = NULL; + + //Iterate through profiles in iProfileArray + //and match + + for (TInt count=0; countGetParameter(KSIPProfileId, profileId); + if (profileId == thisProfileId) + { + //profile Id for an existing profile was passed + return profileId; + } + iProfileArray[count]->GetParameter(KSIPAccessPointId, iapId); + if (iapId != thisIapId) + { + continue; + } + iProfileArray[count]->GetParameter(KSIPUserAor, aor); + if (aor != thisAor) + { + continue; + } + + iProfileArray[count]->GetParameter(KSIPRegistrar,KSIPServerAddress, registrar); + if (registrar != thisRegistrar) + { + continue; + } + + iProfileArray[count]->GetParameter(KSIPOutboundProxy,KSIPServerAddress, proxy); + if (proxy != thisProxy) + { + continue; + } + + iProfileArray[count]->GetParameter(KSIPRegistrar,KSIPDigestRealm, regRealm); + if(regRealm != thisRegRealm) + { + continue; + } + iProfileArray[count]->GetParameter(KSIPOutboundProxy,KSIPDigestRealm, proxyRealm); + if (proxyRealm != thisProxyRealm) + { + continue; + } + iProfileArray[count]->GetParameter(KSIPRegistrar,KSIPDigestUserName, regUser); + if (regUser != thisRegUser) + { + continue; + } + + iProfileArray[count]->GetParameter(KSIPOutboundProxy,KSIPDigestUserName, proxyUser); + if (proxyUser != thisProxyUser) + { + continue; + } + //Duplicate profile found + return profileId; + } + + return KSIPInvalidProfileId; + } + + + +EXPORT_C void CSIPTransitionEngine::AddCredentialsL(TSIPCredentials aCredential) + { + iCredentialsArray.AppendL(aCredential); + } + +EXPORT_C const TDesC8* CSIPTransitionEngine::GetFromField(TUint32 aProfileId) const + { + TInt size = iProfileArray.Count(); + CSIPProfile* profile = NULL; + const TDesC8* userName = NULL; + TUint32 profileId = KSIPInvalidProfileId; + + for (TInt count = 0; countGetParameter(KSIPProfileId, profileId); + if (profileId == aProfileId) + { + profile->GetParameter(KSIPUserAor, userName); + } + } + return userName; + } + + +MSIPRegistrationClient* CSIPTransitionEngine::FindRegistrationClient(TUint32 aProfileId) + { + TInt size = iRegClientArray.Count(); + for (TInt count = 0; countGetProfileId()) + { + return iRegClientArray[count]; + } + } + return NULL; + } + +//From MSIPHttpDigestChallengeObserver +void CSIPTransitionEngine::ChallengeReceived(const TDesC8& aRealm) + { + //Walkthrough the list of Realms to find credentials + if (!FindAndSetCredentials(aRealm)) + { + TInt size = iSMArray.Count(); + //Walk through State Machines and find the current outgoing active state machine + for (TInt count=0; countiStateMachine; + if(!smPtr->GetIncomingStatus() && smPtr->GetOutgoingStatus()) + { + iDigest->IgnoreChallenge(aRealm); + smPtr->ChallengeIgnored(aRealm); + } + } + } + + } + + +TBool CSIPTransitionEngine::FindAndSetCredentials(const TDesC8& aRealm) + { + TInt size = iCredentialsArray.Count(); + + for (TInt count=0; countSetCredentialsL(iCredentialsArray[count].iRealm, + iCredentialsArray[count].iUserName, + iCredentialsArray[count].iPasswd)); + if(err != KErrNone) + { + return ETrue; + } + } + } + return EFalse; + }