diff -r 000000000000 -r c8caa15ef882 simpleengine/engine/src/simplewinfowatcher.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/simpleengine/engine/src/simplewinfowatcher.cpp Tue Feb 02 01:05:17 2010 +0200 @@ -0,0 +1,407 @@ +/* +* Copyright (c) 2006 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: Simple Engine +* +*/ + + + + +// INCLUDE FILES + +#include +#include + +// own simple +#include "msimpleconnection.h" +#include "simplecommon.h" +#include "simpleenginerequest.h" +#include "msimplewinfo.h" +#include "msimplefilterdocument.h" +#include "msimplewinfoobserver.h" +#include "simplewinfowatcher.h" +#include "simplexmlfactory.h" +#include "simplesipconnection.h" +#include "simpleerrors.h" + +#ifdef _DEBUG +#include "simpledebugutils.h" +#endif + +const TInt KExpandSize = 512; + +// ================= MEMBER FUNCTIONS ======================= +// + +// ---------------------------------------------------------- +// CSimpleWinfoWatcher::CSimpleWinfoWatcher +// ---------------------------------------------------------- +// +CSimpleWinfoWatcher::CSimpleWinfoWatcher( + MSimpleConnection& aConn, + MSimpleWinfoObserver& aObserver ) +: CSimpleClient( aConn ), + iObserver( aObserver ), + iResCount(0), iComplete( EFalse ), + iBuffer(NULL) + { + } + +// ---------------------------------------------------------- +// CSimpleWinfoWatcher::~CSimpleWinfoWatcher +// ---------------------------------------------------------- +// +CSimpleWinfoWatcher::~CSimpleWinfoWatcher() + { +#ifdef _DEBUG + TSimpleLogger::Log(_L("WinfoWatcher: Destructor this=%d" ), (TInt)this ); +#endif + delete iBuffer; + } + +// ---------------------------------------------------------- +// CSimpleWinfoWatcher::ConstructL +// ---------------------------------------------------------- +// +void CSimpleWinfoWatcher::ConstructL() + { + BaseConstructL(); + iBuffer = CBufFlat::NewL(KExpandSize); + } + +// ---------------------------------------------------------- +// CSimpleWinfoWatcher::NewL +// ---------------------------------------------------------- +// +CSimpleWinfoWatcher* CSimpleWinfoWatcher::NewL( + MSimpleConnection& aConn, + MSimpleWinfoObserver& aObserver ) + { + CSimpleWinfoWatcher* self = new (ELeave) CSimpleWinfoWatcher( + aConn, aObserver ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); +#ifdef _DEBUG + TSimpleLogger::Log(_L("WinfoWatcher: NewL this=%d"), (TInt)self ); +#endif + return self; + } + +// ---------------------------------------------------------- +// CSimpleWinfoWatcher::Connection +// ---------------------------------------------------------- +// +const MSimpleConnection& CSimpleWinfoWatcher::Connection() + { + return iConn; + } + +// ---------------------------------------------------------- +// CSimpleWinfoWatcher::SIPStatus +// ---------------------------------------------------------- +// +TUint CSimpleWinfoWatcher::SIPStatus() + { + return DoSIPStatus(); + } + +// ---------------------------------------------------------- +// CSimpleWinfoWatcher::SIPRetryAfter +// ---------------------------------------------------------- +// +TUint CSimpleWinfoWatcher::SIPRetryAfter() + { + return DoRetryAfter(); + } + +// ---------------------------------------------------------- +// CSimpleWinfoWatcher::Close +// ---------------------------------------------------------- +// +void CSimpleWinfoWatcher::Close( ) + { + delete this; + } + +// ---------------------------------------------------------- +// CSimpleWinfoWatcher::NewRequestL +// ---------------------------------------------------------- +// +void CSimpleWinfoWatcher::NewRequestL( MSimpleEngineRequest& aReq ) + { + TPtrC8 content = aReq.ResponseData(); + TPtrC8 contType = aReq.ResponseContentType(); + TPtrC8 p8; + p8.Set( KSimpleWinfoType ); + TInt mySize = p8.Length(); + + if ( !contType.Left(mySize).CompareF(KSimpleWinfoType)) + { + MSimpleWinfo* d = TSimpleXmlFactory::NewWinfoL( content ); + CleanupClosePushL( *d ); +#ifdef _DEBUG + TSimpleLogger::Log(_L("WinfoWatcher: call WinfoNotificationL")); +#endif + iObserver.WinfoNotificationL( *d ); + CleanupStack::PopAndDestroy( d ); + } + } + +// ---------------------------------------------------------- +// CSimpleWinfoWatcher::Complete +// ---------------------------------------------------------- +// +void CSimpleWinfoWatcher::Complete( + TInt aOpId, TInt aStatus, MSimpleEngineRequest& aReq ) + { +#ifdef _DEBUG + TSimpleLogger::Log(_L("WinfoWatcher: Complete opid=%d, status=%d" ), + aOpId, aStatus ); +#endif + + TBool completeNow( EFalse ); + MSimpleEngineRequest::TSimpleRequest orig = aReq.RequestType(); + + if ( orig == MSimpleEngineRequest::EDestroyStart ) + { + // It's time to delete the request of delayed deletion from both DLLs. + // Delete immediately from another DLL. + aReq.ModifyType( MSimpleEngineRequest::EDestroy ); + TRAP_IGNORE( SendReqL( aReq )); + // Delete from this DLL, + aReq.Destroy(); + return; + } + + GetSIPStatus( aOpId ); + + // Reset data buffer + iBuffer->Reset(); + + // Set the member to point to stack variable + TBool destroyed( EFalse ); + iDestroyedPtr = &destroyed; + + MSimpleEngineRequest::TSimpleSIPResponse respMet = aReq.ResponseMethod(); + + // Convert KSimpleErrPending to OK when needed + if ( aStatus == KSimpleErrPending ) + { + aStatus = KErrNone; + } + + // Handle SIP notification first + if ( respMet == MSimpleEngineRequest::ENotify ) + { + // This is true in notifications. Ignore some responses. + if ( aStatus == KErrCompletion ) + { + iResCount++; + } + if ( orig != MSimpleEngineRequest::ESubscribeStop ) + { + TRAP_IGNORE( NewRequestL( aReq ) ); + // Check whether an application has called destructor in callback method. + // Destructor will handle deletion of all the open requests. + if ( destroyed ) + { + return; + } + } + else if ( iResCount > 1 ) + { + // Stop request is not completed until ok + Notify(terminated) received. + // Error completes the stop reqest without Notification. + completeNow = ETrue; + if ( DoCallReqComplete( aOpId, KErrNone )) + { + return; + } + } + } + else + { + // SIP Status response or client originated cancellation + iResCount++; + if ( aStatus != KErrNone ) + { + iResCount++; + if ( orig == MSimpleEngineRequest::ESubscribeStop ) + { + // Any response to stop subscribe is ok. + aStatus = KErrNone; + } + } + + if ( !iComplete && + ( orig != MSimpleEngineRequest::ESubscribeStop || + orig == MSimpleEngineRequest::ESubscribeStop && iResCount > 1 ) ) + { + // Stop request is not completed until ok + Notify(terminated) received. + // Error completes the stop reqest without Notification. + completeNow = ETrue; + if ( DoCallReqComplete( aOpId, aStatus )) + { + return; + } + } + } + + // Delete request when not needed + if ( iResCount > 1 ) + { + iRequest = MSimpleEngineRequest::ENone; + iComplete = EFalse; + TInt reason = ResponseReason( aReq ); + // Delete corresponding request from another DLL with delay. This decreases + // the counter of active subscriptions there. + aReq.ModifyType( MSimpleEngineRequest::EDestroyStart ); + TRAP_IGNORE( SendReqL( aReq )); + // call WinfoTerminatedL when needed, i.e. no Stop + if ( orig != MSimpleEngineRequest::ESubscribeStop && + !completeNow ) + { +#ifdef _DEBUG + TSimpleLogger::Log(_L("WinfoWatcher: call WinfoTerminatedL opid=%d"), + aOpId ); +#endif + TRAP_IGNORE( iObserver.WinfoTerminatedL( aOpId, reason ) ); + // Check whether an application has called destructor in callback method. + // Destructor of CSimpleClient base class will handle deletion of + // all the open requests. + if ( destroyed ) + { + return; + } + } + // delete request from this DLL later. + } + + iDestroyedPtr = NULL; + } + +// ---------------------------------------------------------- +// CSimpleWinfoWatcher::SubscribeWatcherListL +// ---------------------------------------------------------- +// +TInt CSimpleWinfoWatcher::SubscribeWatcherListL( + MSimpleFilterDocument* aFilter ) + { + + if ( iRequest != MSimpleEngineRequest::ENone ) + { +#ifdef _DEBUG + TSimpleLogger::Log(_L("winfoWatcher: SubscribeWatcherListL IN-USE **" ) ); +#endif + User::Leave( KErrInUse ); + } + + IncreaseOpId(); + +#ifdef _DEBUG + TSimpleLogger::Log(_L("WinfoWatcher: SubscribeWatcherListL opid=%d"),iOpId); +#endif + CSimpleEngineRequest* req = CSimpleEngineRequest::NewL( + *this, MSimpleEngineRequest::ESubscribeWinfo, iOpId ); + CleanupStack::PushL( req ); + + // handle optional filter document + if ( aFilter ) + { + StreamDocumentL( *req, *aFilter ); + } + + SendReqL( *req ); + iRequestList.AddLast( *req ); + CleanupStack::Pop( req ); + + iRequest = MSimpleEngineRequest::ESubscribeWinfo; + iResCount = 0; + iSubsId = iOpId; + + return iOpId; + } + +// ---------------------------------------------------------- +// CSimpleWinfoWatcher::UnsubscribeL +// ---------------------------------------------------------- +// +TInt CSimpleWinfoWatcher::UnsubscribeL( ) + { + +#ifdef _DEBUG + TSimpleLogger::Log(_L("WinfoWatcher: UnsubscribeL opid=%d" ), iSubsId); +#endif + // use the old opid and request + CSimpleEngineRequest* req = SearchRequests( iSubsId ); + if ( !req ) + { + User::Leave( KErrNotFound ); + } + req->ModifyType( MSimpleEngineRequest::ESubscribeStop ); + + SendReqL( *req ); + + iRequest = MSimpleEngineRequest::ESubscribeStop; + iComplete = EFalse; + iResCount = 0; + + return iOpId; + } + +// ---------------------------------------------------------- +// CSimpleWinfoWatcher::StreamDocumentL +// ---------------------------------------------------------- +// +void CSimpleWinfoWatcher::StreamDocumentL( + CSimpleEngineRequest& aReq, + MSimpleFilterDocument& aFilter ) + { + // add request data + // externalize the document a stream + iBuffer->Reset(); + RBufWriteStream stream( *iBuffer ); + stream.Open( *iBuffer ); + aFilter.ExternalizeL( stream ); + stream.Close(); + aReq.SetRequestData( iBuffer->Ptr(0) ); + } + +// ---------------------------------------------------------- +// CSimpleWinfoWatcher::DoCallReqComplete +// ---------------------------------------------------------- +// +TInt CSimpleWinfoWatcher::DoCallReqComplete( + TInt aOpId, TInt aStatus ) + { + // Set the member to point to stack variable + TBool destroyed( EFalse ); + iDestroyedPtr = &destroyed; + + iComplete = ETrue; +#ifdef _DEBUG + TSimpleLogger::Log(_L("WinfoWatcher: call WinfoReqCompleteL opid=%d status=%d"), + aOpId, aStatus); +#endif + TRAP_IGNORE( iObserver.WinfoReqCompleteL( aOpId, aStatus )); + // Check whether an application has called destructor in callback method. + // Destructor will handle deletion of all the open requests. + if ( destroyed ) + { + return KErrGeneral; + } + return KErrNone; + } +