--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommsengine/mmcesrv/mmceserver/src/mcesipevent.cpp Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,1283 @@
+/*
+* Copyright (c) 2005 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:
+*
+*/
+
+
+
+
+#include <sipmessageelements.h>
+#include <sipnotifydialogassoc.h>
+#include <siprefertoheader.h>
+#include <sipreferdialogassoc.h>
+#include <sipsubscribedialogassoc.h>
+#include <sipsubscriptionstateheader.h>
+#include <siptoheader.h>
+#include <sipexpiresheader.h>
+#include <sipeventheader.h>
+#include <siprequestelements.h>
+#include <sipservertransaction.h>
+#include <sipprofile.h>
+#include <sipdialog.h>
+#include <siptransactionbase.h>
+#include <sipdialogassocbase.h>
+#include "mcesip.h"
+
+#include "mceevent.h"
+#include "mcerefer.h"
+
+#include "mcesipevent.h"
+#include "mcesipconnection.h"
+#include "mceserial.h"
+#include "mceevents.h"
+#include "mceclientserver.h"
+#include "mcesrvlogs.h"
+#include "mcecomevent.h"
+#include "mcesipeventhelper.h"
+
+#include "mcecssessionreceiver.h"
+#include "mcecssubsessionreceiver.h"
+#include "mcecssession.h"
+#include "mcecssessionimplementation.h"
+#include "mcecomevent.h"
+#include "mcesipmanager.h"
+#include "mcesipconnection.h"
+
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::NewL
+// -----------------------------------------------------------------------------
+//
+CMceSipEvent* CMceSipEvent::NewL( CMceCsSession& aClientSession,
+ CMceSipConnection& aSIPConnection,
+ CSIPProfile& aProfile)
+ {
+ CMceSipEvent* self = CMceSipEvent::NewLC( aClientSession,
+ aSIPConnection,
+ aProfile );
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::NewLC
+// -----------------------------------------------------------------------------
+//
+CMceSipEvent* CMceSipEvent::NewLC ( CMceCsSession& aClientSession,
+ CMceSipConnection& aSIPConnection,
+ CSIPProfile& aProfile)
+ {
+ CMceSipEvent* self =
+ new (ELeave) CMceSipEvent( aClientSession, aSIPConnection, aProfile );
+ CleanupStack::PushL(self);
+ self->ConstructL( aClientSession );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::CMceSipEvent
+// -----------------------------------------------------------------------------
+//
+CMceSipEvent::CMceSipEvent ( CMceCsSession& aClientSession,
+ CMceSipConnection& aSIPConnection,
+ CSIPProfile& aProfile )
+: CMceCsSubSession( KMceCSSIPEvent, aClientSession, aSIPConnection, aProfile )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::ConstructL ( CMceCsSession& aClientSession )
+ {
+ CMceCsSubSession::ConstructL( aClientSession );
+
+ MCESRV_DEBUG("MCE SIP event created")
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::~CMceSipEvent
+// -----------------------------------------------------------------------------
+//
+CMceSipEvent::~CMceSipEvent()
+ {
+ MCESRV_DEBUG("MCE SIP event deleted") ;
+ if(iEvent)
+ {
+ delete iEvent;
+ }
+ if ( iIdle )
+ {
+ delete iIdle;
+ }
+ }
+// -----------------------------------------------------------------------------
+// CMceSipEvent::CanDispose
+// -----------------------------------------------------------------------------
+//
+TBool CMceSipEvent::CanDispose()
+ {
+ return !iEvent ||
+ iEvent->EventContext().CurrentState() == KMceTerminatedEventStateIndex;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::HandleSIPEvent
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::HandleSIPEvent( TMceSipEventCode /*aEventCode*/ )
+ {
+ TRAPD( error, iEvent->ProceedL() );
+ if ( error )
+ {
+ ErrorOccured(error);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::ResponseReceived
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::ResponseReceived()
+ {
+ HandleSIPEvent( EMceResponse );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::ProvisionalResponseReceived
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::ProvisionalResponseReceived()
+ {
+ HandleSIPEvent( EMceProvisionalResponse );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::RedirectionResponseReceived
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::RedirectionResponseReceived()
+ {
+ HandleSIPEvent( EMceRedirectionResponse );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::ErrorResponseReceived
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::ErrorResponseReceived()
+ {
+ HandleSIPEvent( EMceErrorResponse );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::RequestReceived
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::RequestReceived( TBool /*aInsideDialog*/, CSIPDialog& /*aDialog*/ )
+ {
+
+ MCESRV_DEBUG( "CMceSipEvent::RequestReceived -- begin" )
+ TInt error=KErrNone;
+ RStringF method = MceSip::Method( Request() );
+
+ if ( AcceptMethod( method ) && iEvent )
+ {
+ MCESRV_DEBUG( "CMceSipEvent::RequestReceived -- passing to event" )
+ TRAP ( error, iEvent->ReceivedRequestL() );
+ MCESRV_DEBUG( "CMceSipEvent::RequestReceived -- handled" )
+ }
+ else
+ {
+ error = KErrGeneral;
+ }
+
+ if ( error != KErrNone )
+ {
+ MceSip::DiscardRequest( Request() );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::StandAloneRequestReceived
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::StandAloneRequestReceived()
+ {
+ MCESRV_DEBUG("CMceSipEvent::StandAloneRequestReceived, Entry");
+ MceSip::DiscardRequest( Request() );
+ MCESRV_DEBUG("CMceSipEvent::StandAloneRequestReceived, Exit");
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::StandAloneResponseReceived
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::StandAloneResponseReceived( TMceSipResponseType /*aResponseType*/ )
+ {
+ MCESRV_DEBUG("CMceSipEvent::StandAloneResponseReceived, Entry");
+ // NOP
+ MCESRV_DEBUG("CMceSipEvent::StandAloneResponseReceived, Exit");
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::ErrorOccured
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::ErrorOccured( TInt aError )
+ {
+ TMceIds ids;
+ ids.iCallbackID = EMceItcStateChanged;
+ ids.iState = CMceEvent::ETerminated;
+
+ SendErrorToClient( ids, aError );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::DoErrorOccured
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::DoErrorOccured( TInt aError,
+ CSIPTransactionBase& /*aTransaction*/ )
+ {
+ ErrorOccured( aError );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::DoConnectionStateChanged
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::DoConnectionStateChanged( TBool aIsActive )
+ {
+ if ( iEvent && !aIsActive )
+ {
+ TRAP_IGNORE( iEvent->PerformActionL( EMceItcTerminateEvent ) );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::Canceled
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::Canceled()
+ {
+ if ( ClientType() == KMceDlgTypeRefer )
+ {
+ TRAP_IGNORE( ClientStateChangedL( CMceRefer::ETerminated, EFalse ) );
+ }
+ else
+ {
+ TRAP_IGNORE( ClientStateChangedL( CMceEvent::ETerminated, EFalse ) );
+ }
+
+ MCE_DELETE( iEvent );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::Terminate
+// -----------------------------------------------------------------------------
+//
+TBool CMceSipEvent::Terminate()
+ {
+ return CanDispose();
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::DoServiceL
+// -----------------------------------------------------------------------------
+//
+HBufC8* CMceSipEvent::DoServiceL( TMceIds& aIds,
+ TMceItcFunctions aFunction )
+ {
+ MCESRV_DEBUG( "CMceSipEvent::DoServiceL(ids), Entry" );
+
+ LocalDoServiceL( aIds, aFunction );
+
+ MCESRV_DEBUG( "CMceSipEvent::DoServiceL(ids), Exit" );
+
+ return NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::DoServiceL
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::DoServiceL( TMceIds& /*aIds*/,
+ TMceItcFunctions /*aFunction*/,
+ const TDesC8& /*aMessage*/ )
+ {
+ MCESRV_DEBUG( "CMceSipEvent::DoServiceL(str), Entry" );
+
+ User::Leave( KErrNotSupported );
+ MCESRV_DEBUG( "CMceSipEvent::DoServiceL(str), Exit" );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::DoServiceL
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::DoServiceL( TMceIds& aIds,
+ TMceItcFunctions aFunction,
+ CMceMsgBase& aMessage )
+ {
+ MCESRV_DEBUG( "CMceSipEvent::DoServiceL(message), Entry" );
+
+ if ( !iEvent )
+ {
+ User::LeaveIfError( aMessage.Type() == EMceItcMsgTypeEvent ?
+ KErrNone : KErrNotSupported );
+ CMceMsgSIPEvent* eventMsg =
+ static_cast< CMceMsgSIPEvent* >( &aMessage );
+ DoInitializeL( aFunction, *eventMsg );
+ }
+
+ CMceMsgSIPData* dataMsg = static_cast< CMceMsgSIPData* >( &aMessage );
+ UpdateDataL( aFunction, *dataMsg );
+
+ LocalDoServiceL( aIds, aFunction, *dataMsg );
+
+ ClearDataL();
+ MCESRV_DEBUG( "CMceSipEvent::ServiceL(message), Exit" );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::DoInitializeIncomingDialogL
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::DoInitializeIncomingDialogL(
+ CSIPServerTransaction& aTransaction )
+ {
+ User::LeaveIfError( Dialog() ? KErrNone : KErrTotalLossOfPrecision );
+ User::LeaveIfError(
+ Dialog()->Type() == SIPStrings::StringF( SipStrConsts::ENotify ) ?
+ KErrNone : KErrNotSupported );
+
+ if( aTransaction.Type() ==
+ SIPStrings::StringF( SipStrConsts::ESubscribe ) )
+ {
+ SetEventStateType( EMtSubscribe );
+ }
+ else
+ {
+ SetEventStateType( EMtRefer );
+ }
+
+ const CSIPNotifyDialogAssoc* notify =
+ static_cast< CSIPNotifyDialogAssoc* >( Dialog() );
+
+ iEvent = CMceComEvent::NewL(
+ *this,
+ notify->SubscriptionState().ExpiresParameter() );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::IncomingSubscribeL
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::IncomingSubscribeL(CDesC8Array* aHeaders,
+ HBufC8* aContentType,
+ HBufC8* aBody)
+ {
+ // get ID of SIP profile this SUBSCRIBE was received to.
+ TUint32 matchId;
+ User::LeaveIfError( Profile().GetParameter( KSIPProfileId, matchId ) );
+
+ // Copy input parameters to avoid ownership transfer problem if leave occurs
+ CDesC8Array* tempHeaders = CopyArrayLC( aHeaders );
+ HBufC8* tempContentType = CopyBufferLC( aContentType );
+
+ // make and encode message for ITC
+ HBufC8* empty = KMceEmpty().AllocLC();
+ HBufC8* recipient = Dialog()->Dialog().ToHeader().ToTextValueLC();
+ HBufC8* originator = Dialog()->Dialog().FromHeader().ToTextValueLC();
+ HBufC8* eventHeader =
+ ( ( CSIPNotifyDialogAssoc* ) Dialog() )->Event().ToTextValueLC();
+ TUint32 id = reinterpret_cast<TUint32>(this);
+ CMceMsgSIPEvent* eventMsg =
+ new (ELeave) CMceMsgSIPEvent( id,
+ DialogId(),
+ EMceItcEventTypeSubscribe,
+ recipient, // recipient
+ originator, // originator
+ eventHeader, // event header
+ empty, // refer to
+ CMceRefer::ENoSuppression, // suppress
+ ( TUint )KErrNotFound, // interval
+ tempHeaders,
+ tempContentType );
+
+ CleanupStack::Pop( eventHeader );
+ CleanupStack::Pop( originator );
+ CleanupStack::Pop( recipient );
+ CleanupStack::Pop( empty );
+ if ( tempContentType )
+ {
+ CleanupStack::Pop( tempContentType );
+ }
+ if ( tempHeaders )
+ {
+ CleanupStack::Pop( tempHeaders );
+ }
+
+ CleanupStack::PushL( eventMsg );
+ eventMsg->EncodeL();
+ HBufC8* encMsg = eventMsg->EncodeBufferCloneL();
+ CleanupStack::PopAndDestroy( eventMsg );
+ CleanupStack::PushL( encMsg );
+
+ TMceIds ids;
+ ids.iManagerType = KMceCSSIPEvent;
+ ids.iProfileID = matchId;
+ ids.iCallbackID = EMceItcObjectAdded;
+ ids.iState = CMceEvent::EIdle;
+ ids.iMsgType = EMceItcMsgTypeEvent;
+
+ // send
+ Client().SendToClientL( ids, encMsg, aBody );
+
+ CleanupStack::Pop( encMsg );
+
+ delete aHeaders;
+ delete aContentType;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::IncomingReferL
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::IncomingReferL(HBufC8* aReferTo,
+ CDesC8Array* aHeaders,
+ HBufC8* aContentType,
+ HBufC8* aBody )
+ {
+ MCESRV_DEBUG( "CMceSipEvent::IncomingReferL -- Begin" );
+ // get ID of SIP profile this REFER was received to.
+ TUint32 matchId;
+ User::LeaveIfError( Profile().GetParameter( KSIPProfileId, matchId ) );
+
+ // Copy input parameters to avoid ownership transfer problem if leave occurs
+ HBufC8* tempReferTo = CopyBufferLC( aReferTo );
+ CDesC8Array* tempHeaders = CopyArrayLC( aHeaders );
+ HBufC8* tempContentType = CopyBufferLC( aContentType );
+
+ // make and encode message for ITC
+ HBufC8* recipient = Dialog()->Dialog().ToHeader().ToTextValueLC();
+ HBufC8* originator = Dialog()->Dialog().FromHeader().ToTextValueLC();
+ HBufC8* eventHeader =
+ ( ( CSIPNotifyDialogAssoc* ) Dialog() )->Event().ToTextValueLC();
+
+
+ TUint32 id = reinterpret_cast<TUint32>(this);
+
+ CMceMsgSIPEvent* eventMsg =
+ new (ELeave) CMceMsgSIPEvent( id,
+ DialogId(),
+ EMceItcEventTypeRefer,
+ recipient, // recipient
+ originator, // originator
+ eventHeader, // event header
+ tempReferTo,
+ iEvent->ReferType(),
+ ( TUint32 )KErrNotFound, // interval
+ tempHeaders,
+ tempContentType );
+
+ CleanupStack::Pop( eventHeader );
+ CleanupStack::Pop( originator );
+ CleanupStack::Pop( recipient );
+ if ( tempContentType )
+ {
+ CleanupStack::Pop( tempContentType );
+ }
+ if ( tempHeaders )
+ {
+ CleanupStack::Pop( tempHeaders );
+ }
+ if ( tempReferTo )
+ {
+ CleanupStack::Pop( tempReferTo );
+ }
+
+ CleanupStack::PushL( eventMsg );
+ eventMsg->EncodeL();
+ HBufC8* encMsg = eventMsg->EncodeBufferCloneL();
+ CleanupStack::PopAndDestroy( eventMsg );
+ CleanupStack::PushL( encMsg );
+
+ // send
+ TMceIds ids;
+ ids.iManagerType = KMceCSSIPEvent;
+ ids.iProfileID = matchId;
+ ids.iCallbackID = EMceItcObjectAdded;
+ ids.iState = CMceRefer::EIdle;
+ ids.iMsgType = EMceItcMsgTypeEvent;
+
+ Client().SendToClientL( ids, encMsg, aBody );
+
+ CleanupStack::Pop( encMsg );
+
+ delete aHeaders;
+ delete aContentType;
+ delete aReferTo;
+
+ MCESRV_DEBUG( "Incoming REFER sent to client" );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::ClientStateChangedL
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::ClientStateChangedL( CMceRefer::TState aState,
+ TBool aIsResponse )
+ {
+ DoClientStateChangedL( aState, aIsResponse );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::ClientStateChangedL
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::ClientStateChangedL( CMceEvent::TState aState,
+ TBool aIsResponse )
+ {
+ DoClientStateChangedL( aState, aIsResponse );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::DoClientStateChangedL
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::DoClientStateChangedL( TUint32 aState, TBool aIsResponse )
+ {
+ MCESRV_DEBUG_DVALUE( "Event state changed. new state", aState );
+
+ // update IDs
+ TMceIds ids;
+ ids.iState = aState;
+ ids.iCallbackID = EMceItcStateChanged;
+ ids.iMsgType = EMceItcMsgTypeSIPReply;
+
+ if ( aIsResponse )
+ {
+ const CSIPResponseElements* response = Response().ResponseElements();
+ RStringF reasonPhrase = response->ReasonPhrase();
+ TUint statusCode = response->StatusCode();
+ CDesC8ArrayFlat* headers = new (ELeave) CDesC8ArrayFlat(1);
+ CleanupStack::PushL( headers );
+
+ const RPointerArray<CSIPHeaderBase>& sipHeaders =
+ response->MessageElements().UserHeaders();
+
+ for (int i=0; i < sipHeaders.Count(); i++)
+ {
+ CSIPHeaderBase* anotherhead = sipHeaders[i];
+ HBufC8* head = anotherhead->ToTextLC();
+ headers->AppendL(*head);
+ CleanupStack::PopAndDestroy( head );
+ }
+
+ HBufC8* reason = reasonPhrase.DesC().AllocLC();
+ HBufC8* empty = KMceEmpty().AllocLC();
+
+ CMceMsgSIPReply* replyMsg = new (ELeave) CMceMsgSIPReply(
+ *reason,
+ statusCode,
+ *headers,
+ *empty );
+ CleanupStack::PushL( replyMsg );
+ replyMsg->EncodeL();
+
+ HBufC8* context = replyMsg->EncodeBufferCloneL();
+ CleanupStack::PopAndDestroy( replyMsg );
+
+ CleanupStack::PushL( context );
+ HBufC8* content = response->MessageElements().Content().AllocLC();
+
+ SendToClientL( ids, context, content );
+
+ CleanupStack::Pop( content);
+ CleanupStack::Pop( context);
+ CleanupStack::PopAndDestroy( empty );
+ CleanupStack::PopAndDestroy( reason );
+ CleanupStack::PopAndDestroy( headers );
+ }
+ else
+ {
+ SendToClient( ids );
+ }
+ MCESRV_DEBUG( "New event state sent to client" );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::NotifyReceived
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::NotifyReceivedL(CDesC8Array* aHeaders,
+ HBufC8* aContentType,
+ HBufC8* aBody )
+ {
+ // update IDs
+ TMceIds ids;
+ ids.iCallbackID = EMceItcNotifyReceived;
+ ids.iMsgType = EMceItcMsgTypeEvent;
+ ids.iState = CMceEvent::EActive;
+
+ // Copy input parameters to avoid ownership transfer problem if leave occurs
+ CDesC8Array* tempHeaders = CopyArrayLC( aHeaders );
+ HBufC8* tempContentType = CopyBufferLC( aContentType );
+
+ // make and encode message for ITC
+ HBufC8* recipient = Dialog()->Dialog().ToHeader().ToTextValueLC();
+ HBufC8* originator = Dialog()->Dialog().FromHeader().ToTextValueLC();
+ HBufC8* emptyEvent = KMceEmpty().AllocLC();
+ HBufC8* emptyReferTo = KMceEmpty().AllocLC();
+
+ CMceMsgSIPEvent* eventMsg =
+ new (ELeave) CMceMsgSIPEvent( ids.iSessionID,
+ DialogId(),
+ EMceItcEventTypeEither,
+ recipient, // recipient
+ originator, // originator
+ emptyEvent, // event header
+ emptyReferTo, // referTo
+ CMceRefer::ENoSuppression, // suppress
+ ( TUint )KErrNotFound, // interval
+ tempHeaders,
+ tempContentType );
+ CleanupStack::Pop( emptyReferTo );
+ CleanupStack::Pop( emptyEvent );
+ CleanupStack::Pop( originator );
+ CleanupStack::Pop( recipient );
+ if ( tempContentType )
+ {
+ CleanupStack::Pop( tempContentType );
+ }
+ if ( tempHeaders )
+ {
+ CleanupStack::Pop( tempHeaders );
+ }
+
+ CleanupStack::PushL( eventMsg );
+ eventMsg->EncodeL();
+ HBufC8* encMsg = eventMsg->EncodeBufferCloneL();
+ CleanupStack::PopAndDestroy( eventMsg );
+ CleanupStack::PushL( encMsg );
+
+ // send
+ SendToClientL( ids, encMsg, aBody );
+
+ CleanupStack::Pop( encMsg );
+
+ delete aHeaders;
+ delete aContentType;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::CreateIncomingDialogL
+// -----------------------------------------------------------------------------
+//
+CSIPDialogAssocBase* CMceSipEvent::CreateIncomingDialogL(
+ CSIPServerTransaction& aTransaction )
+ {
+ User::LeaveIfError(
+ aTransaction.Type() == SIPStrings::StringF( SipStrConsts::ERefer ) ||
+ aTransaction.Type() == SIPStrings::StringF( SipStrConsts::ESubscribe ) ?
+ KErrNone : KErrNotSupported );
+
+ User::LeaveIfError(
+ aTransaction.RequestElements() ? KErrNone : KErrArgument );
+
+ const CSIPMessageElements& message =
+ aTransaction.RequestElements()->MessageElements();
+
+ // get expires header value, if exists.
+ CSIPHeaderBase* expiresHeaderTmp = MceSip::FindHeader( message,
+ SIPStrings::StringF(SipStrConsts::EExpiresHeader ) );
+
+ TUint expires = KMceDefaultSubscrExpire;
+ if ( expiresHeaderTmp )
+ {
+ CSIPExpiresHeader* expiresHeader =
+ static_cast< CSIPExpiresHeader* >( expiresHeaderTmp );
+ expires = expiresHeader->Value();
+ }
+
+ // get event header from the server transaction
+ CSIPHeaderBase* eventHeaderTmp = MceSip::FindHeader( message,
+ SIPStrings::StringF( SipStrConsts::EEventHeader ) );
+
+ CSIPEventHeader* eventHeader = NULL;
+ if ( eventHeaderTmp )
+ {
+ // use event from request, if present
+ eventHeader =
+ static_cast< CSIPEventHeader* >( eventHeaderTmp->CloneL() );
+ }
+ else if ( aTransaction.Type() ==
+ SIPStrings::StringF(SipStrConsts::ERefer ) )
+ {
+ // For REFER, Event is "refer"
+ eventHeader = CSIPEventHeader::NewL( KMceSipEventPackageRefer );
+ }
+ else
+ {
+ // SUBSCRIBE with no Event header
+ User::Leave( KErrNotSupported );
+ }
+ CleanupStack::PushL( eventHeader );
+
+ // create subscription state header
+ CSIPSubscriptionStateHeader* subscrStateHeader = NULL;
+ if ( expires > 0 )
+ {
+ subscrStateHeader =
+ CSIPSubscriptionStateHeader::NewLC( KStateActive );
+ }
+ else
+ {
+ subscrStateHeader =
+ CSIPSubscriptionStateHeader::NewLC( KStateTerminated );
+ }
+ subscrStateHeader->SetExpiresParameterL( expires );
+ // create notify dialog assoc.
+ const MSIPRegistrationContext& profile = Profile();
+ CSIPNotifyDialogAssoc* dialog = CSIPNotifyDialogAssoc::NewL(
+ aTransaction,
+ profile,
+ eventHeader,
+ subscrStateHeader );
+ CleanupStack::Pop( subscrStateHeader );
+ CleanupStack::Pop( eventHeader );
+ return dialog;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::CreateOutgoingDialogL
+// -----------------------------------------------------------------------------
+//
+CSIPDialogAssocBase* CMceSipEvent::CreateOutgoingDialogL(
+ TMceDialogType aDialogType,
+ CDesC8Array& aParams,
+ CSIPDialog& aExistingDialog )
+
+ {
+ User::LeaveIfError( aDialogType == KMceDlgTypeRefer ||
+ aDialogType == KMceDlgTypeSubscribe ?
+ KErrNone : KErrArgument );
+
+ CSIPDialogAssocBase* dialog = NULL;
+
+ if ( aDialogType == KMceDlgTypeSubscribe )
+ {
+ TPtrC8 eventHeader = aParams.MdcaPoint( KMceArrayIndexEventHeader );
+
+ CSIPEventHeader* sipEventHeader =
+ CSIPEventHeader::DecodeL( eventHeader );
+ CleanupStack::PushL( sipEventHeader );
+
+ dialog = CSIPSubscribeDialogAssoc::NewL( aExistingDialog,
+ sipEventHeader );
+
+ CleanupStack::Pop( sipEventHeader );
+ }
+ else
+ {
+ TPtrC8 referTo = aParams.MdcaPoint( KMceArrayIndexEventReferTo );
+
+ CSIPReferToHeader* referToHeader =
+ CSIPReferToHeader::DecodeL( referTo );
+ CleanupStack::PushL( referToHeader );
+ dialog = CSIPReferDialogAssoc::NewL( aExistingDialog,
+ referToHeader );
+
+ CleanupStack::Pop( referToHeader );
+
+ }
+
+
+ return dialog;
+
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::CreateOutgoingDialogL
+// -----------------------------------------------------------------------------
+//
+CSIPDialogAssocBase* CMceSipEvent::CreateOutgoingDialogL(
+ TMceDialogType aDialogType,
+ CDesC8Array& aParams )
+ {
+ User::LeaveIfError( aDialogType == KMceDlgTypeRefer ||
+ aDialogType == KMceDlgTypeSubscribe ?
+ KErrNone : KErrArgument );
+
+ CSIPDialogAssocBase* dialog = NULL;
+
+ CSIPConnection& connection = SIPConnection().Connection();
+ const CSIPProfile& profile = Profile();
+ TPtrC8 eventRemoteUri = aParams.MdcaPoint( KMceArrayIndexEventRemoteURI );
+ TPtrC8 originator = aParams.MdcaPoint( KMceArrayIndexEventOriginator );
+ CSIPToHeader* toHeader = CSIPToHeader::DecodeL( eventRemoteUri );
+ CleanupStack::PushL( toHeader );
+ CUri8* remoteUri = CUri8::NewLC( toHeader->SIPAddress().Uri8().Uri() );
+
+ CSIPFromHeader* fromHeader = NULL;
+ if ( originator.Length() > 0 )
+ {
+ fromHeader = MceSip::ToFromHeaderL( originator );
+ }
+ CleanupStack::PushL( fromHeader );
+
+ if ( aDialogType == KMceDlgTypeSubscribe )
+ {
+ TPtrC8 eventHeader = aParams.MdcaPoint( KMceArrayIndexEventHeader );
+
+ CSIPEventHeader* sipEventHeader =
+ CSIPEventHeader::DecodeL( eventHeader );
+ CleanupStack::PushL( sipEventHeader );
+
+ dialog = CSIPSubscribeDialogAssoc::NewL( connection,
+ remoteUri,
+ profile,
+ sipEventHeader,
+ fromHeader,
+ toHeader );
+
+ CleanupStack::Pop( sipEventHeader );
+ }
+ else
+ {
+ TPtrC8 referTo = aParams.MdcaPoint( KMceArrayIndexEventReferTo );
+
+ CSIPReferToHeader* referToHeader =
+ CSIPReferToHeader::DecodeL( referTo );
+ CleanupStack::PushL( referToHeader );
+ dialog = CSIPReferDialogAssoc::NewL( connection,
+ remoteUri,
+ profile,
+ referToHeader,
+ fromHeader,
+ toHeader );
+
+ CleanupStack::Pop( referToHeader );
+
+ }
+ CleanupStack::Pop( fromHeader );
+ CleanupStack::Pop( remoteUri );
+ CleanupStack::Pop( toHeader );
+
+ return dialog;
+
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::AcceptDialogTransaction
+// -----------------------------------------------------------------------------
+//
+TBool CMceSipEvent::AcceptDialogTransaction(
+ CSIPServerTransaction& aTransaction )
+ {
+ TBool ret = EFalse;
+ TRAP_IGNORE((ret = AcceptDialogTransactionL (aTransaction ) ));
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::AcceptDialogTransactionL
+// -----------------------------------------------------------------------------
+//
+TBool CMceSipEvent::AcceptDialogTransactionL(
+ CSIPServerTransaction& aTransaction )
+ {
+ TBool ret = EFalse;
+ User::LeaveIfError( Dialog() ? KErrNone : KErrArgument );
+ User::LeaveIfError( iEvent ? KErrNone : KErrTotalLossOfPrecision );
+ User::LeaveIfError(
+ aTransaction.RequestElements() ? KErrNone : KErrArgument );
+
+ CSIPHeaderBase* head =
+ MceSip::FindHeader( aTransaction.RequestElements()->MessageElements(),
+ SIPStrings::StringF( SipStrConsts::EEventHeader ) );
+ User::LeaveIfError( head ? KErrNone : KErrArgument );
+
+ const RStringF tranType = aTransaction.Type();
+ const RStringF dlgType = Dialog()->Type();
+
+ CSIPEventHeader* tranEventHeader = static_cast<CSIPEventHeader*>( head );
+ if ( tranType == SIPStrings::StringF( SipStrConsts::ESubscribe ) )
+ {
+ // We have MT SUBSCRIBE or MT REFER
+ // The event package and the id must match to
+ // the one of the NOTIFY dialog assoc.
+ if ( dlgType == SIPStrings::StringF( SipStrConsts::ENotify ) )
+ {
+ // match to NOTIFY dialog event header
+ ret = MCESIPEventHelper::MatchEvents(
+ static_cast< CSIPNotifyDialogAssoc* >( Dialog() )->Event(),
+ *tranEventHeader );
+ }
+ }
+ else if ( tranType == SIPStrings::StringF( SipStrConsts::ENotify ) )
+ {
+ // We have MO SUBSCRIBE or MO REFER
+ if ( iStateType == EMoSubscribe )
+ {
+ if ( dlgType == SIPStrings::StringF( SipStrConsts::ESubscribe ) )
+ {
+ // The event package and id must match to the
+ // one of the subscribe dialog assoc.
+ ret = MCESIPEventHelper::MatchEvents(
+ static_cast< CSIPSubscribeDialogAssoc* >
+ ( Dialog() )->Event(),
+ *tranEventHeader );
+ }
+ }
+ else if ( iStateType == EMoRefer )
+ {
+ // The event package must be "refer" and the
+ // id is either not present or must mach to the
+ // CSeq number of the sent REFER.
+ ret = MCESIPEventHelper::MatchEventsL( KMceSipEventPackageRefer,
+ iEvent->IdValue(),
+ *tranEventHeader );
+ }
+ }
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::AcceptMethod
+// -----------------------------------------------------------------------------
+//
+TBool CMceSipEvent::AcceptMethod( RStringF aMethod )
+ {
+
+ return aMethod == SIPStrings::StringF(SipStrConsts::ERefer ) ||
+ aMethod == SIPStrings::StringF(SipStrConsts::ESubscribe)||
+ aMethod == SIPStrings::StringF(SipStrConsts::ENotify );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::SetEventStateType
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::SetEventStateType(const TEventStateType aEventStateType )
+ {
+ iStateType = aEventStateType;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::EventStateType
+// -----------------------------------------------------------------------------
+//
+TEventStateType CMceSipEvent::EventStateType() const
+ {
+ return iStateType;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::ClearDataL
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::ClearDataL()
+ {
+ iEvent->SetMsgHeaders( NULL );
+ iEvent->SetMsgContentL( NULL, NULL );
+ iEvent->SetReasonPhraseL( ( TUint32 ) KErrNotFound, NULL );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::DoInitializeL
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::DoInitializeL( TMceItcFunctions aFunction,
+ CMceMsgSIPEvent& aMessage )
+ {
+ switch( aFunction )
+ {
+ case EMceItcSubscribe:
+ {
+ //Create MO Subscribe event
+ SetEventStateType( EMoSubscribe );
+ break;
+ }
+ case EMceItcReferEvent:
+ {
+ //Create MO Refer event
+ SetEventStateType( EMoRefer );
+ break;
+ }
+ default:
+ {
+ User::Leave( KErrNotSupported );
+ break;
+ }
+ }
+ iEvent = CMceComEvent::NewL( *this, aMessage.RefreshInterval() );
+ iEvent->SetReferType(
+ static_cast< CMceRefer::TType >( aMessage.ReferType() ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::DoServiceL
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::LocalDoServiceL( TMceIds& aIds,
+ TMceItcFunctions aFunction,
+ CMceMsgSIPData& aMessage )
+ {
+ MCESRV_DEBUG( "CMceSipEvent::LocalDoServiceL( message ), Entry" );
+ switch( aFunction )
+ {
+ case EMceItcRespondEvent:
+ {
+ CMceMsgSIPReply* replyMsg =
+ static_cast< CMceMsgSIPReply* >( &aMessage );
+ TBool terminated =
+ ( replyMsg->iCode >= KMceSipMultipleChoices ? ETrue : EFalse );
+
+ if ( iEvent->ReferType() != CMceRefer::ENoSuppression )
+ {
+ if ( terminated )
+ {
+ aIds.iState = CMceRefer::ETerminated;
+ }
+ else if ( replyMsg->iCode >= KMceSipOK )
+ {
+ aIds.iState = CMceRefer::EAccepted;
+ //Asynchronically put the event in terminated state
+ User::LeaveIfError( !iIdle ?
+ KErrNone : KErrTotalLossOfPrecision );
+ iIdle = CIdle::NewL( CActive::EPriorityIdle );
+ iIdle ->Start( TCallBack( Idle, this ) );
+ }
+ else
+ {
+ // provisional
+ // NOP
+ }
+ }
+ else // not suppressed
+ {
+ aIds.iState = ( terminated ?
+ CMceEvent::ETerminated : CMceEvent::EPending );
+ }
+ break;
+ }
+ default :
+ {
+ // NOP
+ break;
+ }
+ }
+
+ LocalDoServiceL( aIds, aFunction );
+
+ MCESRV_DEBUG( "CMceSipEvent::LocalDoServiceL( message ), Exit" );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::DoServiceL
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::LocalDoServiceL( TMceIds& aIds, TMceItcFunctions aFunction )
+ {
+ MCESRV_DEBUG( "CMceSipEvent::LocalDoServiceL, Entry" );
+ User::LeaveIfError( iEvent ? KErrNone : KErrTotalLossOfPrecision );
+ // call state machine
+ iEvent->PerformActionL( aFunction );
+
+ // update ids and other actions, if needed.
+ switch ( aFunction )
+ {
+ case EMceItcSubscribe:
+ case EMceItcSubscribeUpdate:
+ case EMceItcTerminateEvent:
+ {
+ aIds.iState = CMceEvent::EPending;
+ break;
+ }
+ case EMceItcReferEvent:
+ case EMceItcNotify:
+ {
+ aIds.iState = ( iEvent->ReferType() != CMceRefer::ENoSuppression ?
+ CMceRefer::EPending : CMceEvent::EPending );
+ break;
+ }
+ case EMceItcRespondEvent:
+ {
+ // NOP
+ break;
+ }
+ case EMceItcAcceptEvent:
+ {
+ if ( iEvent->ReferType() != CMceRefer::ENoSuppression )
+ {
+ aIds.iState = CMceRefer::EAccepted;
+ //Asynchronically put the event in terminated state
+ User::LeaveIfError( !iIdle ?
+ KErrNone : KErrTotalLossOfPrecision );
+ iIdle = CIdle::NewL( CActive::EPriorityIdle );
+ iIdle ->Start( TCallBack( Idle, this ) );
+ }
+ else
+ {
+ aIds.iState = CMceEvent::EPending;
+ }
+ break;
+ }
+ case EMceItcRejectEvent:
+ {
+ aIds.iState = ( iEvent->ReferType() != CMceRefer::ENoSuppression ?
+ CMceRefer::ETerminated : CMceEvent::ETerminated );
+ break;
+ }
+ default:
+ {
+ User::Leave( KErrNotSupported );
+ break;
+ }
+ }
+
+ MCESRV_DEBUG( "CMceSipEvent::LocalDoServiceL, Exit" );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::UpdateDataL
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::UpdateDataL( TMceItcFunctions aFunction,
+ CMceMsgSIPData& aMessage )
+ {
+ MCESRV_DEBUG( "CMceSipEvent::UpdateDataL, Entry" );
+
+ switch( aFunction )
+ {
+ case EMceItcSubscribe:
+ case EMceItcNotify:
+ case EMceItcReferEvent:
+ case EMceItcTerminateEvent://only in MT
+ {
+ User::LeaveIfError ( aMessage.Type() == EMceItcMsgTypeEvent ?
+ KErrNone : KErrNotSupported );
+
+ break;
+ }
+ case EMceItcSubscribeUpdate:
+ {
+ User::LeaveIfError ( aMessage.Type() == EMceItcMsgTypeEvent ?
+ KErrNone : KErrNotSupported );
+
+ CMceMsgSIPEvent* eventMsg =
+ static_cast< CMceMsgSIPEvent* >( &aMessage );
+
+ iEvent->SetRefreshInterval( eventMsg->RefreshInterval() );
+ break;
+ }
+ case EMceItcRespondEvent:
+ {
+ User::LeaveIfError ( aMessage.Type() == EMceItcMsgTypeSIPReply ?
+ KErrNone : KErrNotSupported );
+
+ CMceMsgSIPReply* replyMsg =
+ static_cast< CMceMsgSIPReply* >( &aMessage );
+ HBufC8* reason = replyMsg->Reason();
+ CleanupStack::PushL( reason );
+ iEvent->SetReasonPhraseL( replyMsg->iCode, reason );
+ CleanupStack::Pop( reason );
+ break;
+ }
+ default:
+ {
+ User::Leave( KErrNotSupported );
+ break;
+ }
+ }
+
+ iEvent->SetMsgHeaders( aMessage.Headers() );
+
+ HBufC8* content = PopClientContent();
+ CleanupStack::PushL( content );
+ HBufC8* contentType = aMessage.ContentType();
+ CleanupStack::PushL( contentType );
+
+ iEvent->SetMsgContentL( contentType, content );
+ CleanupStack::Pop( contentType );
+ CleanupStack::Pop( content );
+
+
+ MCESRV_DEBUG( "CMceSipEvent::UpdateDataL, Exit" );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::SuppressedReferTerminated
+// -----------------------------------------------------------------------------
+//
+void CMceSipEvent::SuppressedReferTerminated()
+ {
+ delete iIdle;
+ iIdle = NULL;
+ TRAP_IGNORE( ClientStateChangedL( CMceRefer::ETerminated, EFalse ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::Idle
+// -----------------------------------------------------------------------------
+//
+TInt CMceSipEvent::Idle( TAny* aObject )
+ {
+ CMceSipEvent* event = reinterpret_cast< CMceSipEvent* >( aObject );
+ event->SuppressedReferTerminated();
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::CopyArrayLC
+// -----------------------------------------------------------------------------
+//
+CDesC8Array* CMceSipEvent::CopyArrayLC( const CDesC8Array* aArray )
+ {
+ CDesC8Array* tempArray = NULL;
+ if ( aArray )
+ {
+ tempArray = new ( ELeave ) CDesC8ArrayFlat( KMceArrayGranularity );
+ CleanupStack::PushL( tempArray );
+ for ( TInt i = 0; i < aArray->MdcaCount(); i++ )
+ {
+ tempArray->AppendL( aArray->MdcaPoint( i ) );
+ }
+ }
+ return tempArray;
+ }
+
+// -----------------------------------------------------------------------------
+// CMceSipEvent::CopyBufferLC
+// -----------------------------------------------------------------------------
+//
+HBufC8* CMceSipEvent::CopyBufferLC( const HBufC8* aBuffer )
+ {
+ HBufC8* tempBuffer = NULL;
+ if ( aBuffer )
+ {
+ tempBuffer = aBuffer->AllocLC();
+ }
+ return tempBuffer;
+ }
+
+// End of File