simpleengine/engine/src/simplewatcher.cpp
changeset 0 c8caa15ef882
equal deleted inserted replaced
-1:000000000000 0:c8caa15ef882
       
     1 /*
       
     2 * Copyright (c) 2006,2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:    Simple Engine
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 
       
    23 #include <e32std.h>
       
    24 #include <s32mem.h>
       
    25 
       
    26 // own simple
       
    27 #include "msimpleconnection.h"
       
    28 #include "simpleconnection.h"
       
    29 #include "simplecommon.h"
       
    30 #include "simpleenginerequest.h"
       
    31 #include "msimpledocument.h"
       
    32 #include "msimplefilterdocument.h"
       
    33 #include "msimplewatcherobserver.h"
       
    34 #include "msimplepresencelist.h"
       
    35 #include "simplewatcher.h"
       
    36 #include "simpleerrors.h"
       
    37 #include "simplexmlfactory.h"
       
    38 
       
    39 #include "simplesipconnection.h"
       
    40 
       
    41 #ifdef _DEBUG
       
    42 #include "simpledebugutils.h"
       
    43 #endif
       
    44 
       
    45 const TInt KExpandSize = 512;
       
    46 
       
    47 
       
    48 // ================= MEMBER FUNCTIONS =======================
       
    49 //
       
    50 
       
    51 // ----------------------------------------------------------
       
    52 // CSimpleWatcher::CSimpleWatcher
       
    53 // ----------------------------------------------------------
       
    54 //
       
    55 CSimpleWatcher::CSimpleWatcher(
       
    56     MSimpleConnection& aConn,
       
    57     MSimpleWatcherObserver& aObserver )
       
    58 : CSimpleClient( aConn ),
       
    59   iObserver( aObserver ),
       
    60   iResCount(0), iComplete( EFalse ),
       
    61   iBuffer(NULL)
       
    62     {
       
    63     }
       
    64 
       
    65 // ----------------------------------------------------------
       
    66 // CSimpleWatcher::~CSimpleWatcher
       
    67 // ----------------------------------------------------------
       
    68 //
       
    69 CSimpleWatcher::~CSimpleWatcher()
       
    70     {
       
    71 #ifdef _DEBUG
       
    72     TSimpleLogger::Log(_L("Watcher: Destructor this=%d" ), (TInt)this );
       
    73 #endif
       
    74     delete iBuffer;
       
    75     }
       
    76 
       
    77 // ----------------------------------------------------------
       
    78 // CSimpleWatcher::ConstructL
       
    79 // ----------------------------------------------------------
       
    80 //
       
    81 void CSimpleWatcher::ConstructL()
       
    82     {
       
    83     BaseConstructL();
       
    84     iBuffer = CBufFlat::NewL(KExpandSize);   
       
    85     }
       
    86 
       
    87 // ----------------------------------------------------------
       
    88 // CSimpleWatcher::NewL
       
    89 // ----------------------------------------------------------
       
    90 //
       
    91 CSimpleWatcher* CSimpleWatcher::NewL(
       
    92     MSimpleConnection& aConn,
       
    93     MSimpleWatcherObserver& aObserver )
       
    94     {
       
    95     CSimpleWatcher* self = new (ELeave) CSimpleWatcher(
       
    96         aConn, aObserver );
       
    97     CleanupStack::PushL( self );
       
    98     self->ConstructL();
       
    99     CleanupStack::Pop( self );
       
   100 #ifdef _DEBUG
       
   101     TSimpleLogger::Log(_L("Watcher: NewL this=%d" ), (TInt)self );
       
   102 #endif     
       
   103     return self;
       
   104     }
       
   105 
       
   106 // ----------------------------------------------------------
       
   107 // CSimpleWatcher::Connection
       
   108 // ----------------------------------------------------------
       
   109 //
       
   110 const MSimpleConnection& CSimpleWatcher::Connection()
       
   111     {
       
   112     return iConn;
       
   113     }
       
   114 
       
   115 // ----------------------------------------------------------
       
   116 // CSimpleWatcher::SIPStatus
       
   117 // ----------------------------------------------------------
       
   118 //
       
   119 TUint CSimpleWatcher::SIPStatus()
       
   120     {
       
   121     return DoSIPStatus();
       
   122     }
       
   123     
       
   124 // ----------------------------------------------------------
       
   125 // CSimpleWatcher::SIPRetryAfter
       
   126 // ----------------------------------------------------------
       
   127 //
       
   128 TUint CSimpleWatcher::SIPRetryAfter()
       
   129     {
       
   130     return DoRetryAfter();
       
   131     }
       
   132     
       
   133 // ----------------------------------------------------------
       
   134 // CSimpleWatcher::SipSubscriptionState
       
   135 // ----------------------------------------------------------
       
   136 //
       
   137 MSimpleWatcher::TSimpleSipSubscriptionState CSimpleWatcher::SipSubscriptionState()
       
   138     {
       
   139     MSimpleWatcher::TSimpleSipSubscriptionState retVal = ESimpleStateNone;
       
   140     
       
   141     // get the old request
       
   142     CSimpleEngineRequest* req = SearchRequests( iSubsId );
       
   143     if ( req )
       
   144         {
       
   145         CSimpleConnection* conn = STATIC_CAST( CSimpleConnection*, &iConn); //lint !e826
       
   146         CSimpleSipConnection* engine = conn->Connection();                       
       
   147         MSimpleEngineRequest::TSimpleSipSubscriptionState intVal = engine->SipSubscriptionState( *req );
       
   148         switch ( intVal )
       
   149             {
       
   150             case MSimpleEngineRequest::ESimpleStateNone:
       
   151                 retVal = MSimpleWatcher::ESimpleStateNone;
       
   152                 break;
       
   153             case MSimpleEngineRequest::ESimpleStatePending:
       
   154                 retVal = MSimpleWatcher::ESimpleStatePending;
       
   155                 break;
       
   156             case MSimpleEngineRequest::ESimpleStateActive:
       
   157                 retVal = MSimpleWatcher::ESimpleStateActive;
       
   158                 break;            
       
   159             case MSimpleEngineRequest::ESimpleStateTerminated:
       
   160             default:
       
   161                 retVal = MSimpleWatcher::ESimpleStateTerminated;
       
   162                 break;            
       
   163             }
       
   164         }  
       
   165     return retVal;
       
   166     }    
       
   167       
       
   168 
       
   169 // ----------------------------------------------------------
       
   170 // CSimpleWatcher::Close
       
   171 // ----------------------------------------------------------
       
   172 //
       
   173 void CSimpleWatcher::Close( )
       
   174     {
       
   175     delete this;
       
   176     }
       
   177 
       
   178 // ----------------------------------------------------------
       
   179 // CSimpleWatcher::NewRequestL
       
   180 // ----------------------------------------------------------
       
   181 //
       
   182 void CSimpleWatcher::NewRequestL( MSimpleEngineRequest& aReq )
       
   183     {
       
   184     TPtrC8 content = aReq.ResponseData();
       
   185     TPtrC8 contType = aReq.ResponseContentType();
       
   186     TPtrC8 p8;
       
   187     p8.Set( KSimpleDocumentType );
       
   188     TInt mySize = p8.Length();
       
   189     p8.Set( KSimpleMultipartType );
       
   190     TInt mySize2 = p8.Length();
       
   191     if (!contType.Left(mySize).CompareF(KSimpleDocumentType))
       
   192         {
       
   193         MSimpleDocument* d = TSimpleXmlFactory::NewDocumentL( content );
       
   194         CleanupClosePushL( *d );
       
   195 #ifdef _DEBUG
       
   196         TSimpleLogger::Log(_L("Watcher: call WatcherNotificationL"));
       
   197 #endif
       
   198         iObserver.WatcherNotificationL( *d );
       
   199         CleanupStack::PopAndDestroy( d );
       
   200         }
       
   201     else if ( !(contType.Left(mySize2).CompareF( KSimpleMultipartType )))
       
   202         {
       
   203     // Detect the difference between multipart/related cases
       
   204     // application/pidf+xml and application/rlmi+xml
       
   205         if ( contType.FindF( KSimpleDocumentType ) > 0 )  
       
   206             {
       
   207             // Multipart for a single presentity having a direct content.            
       
   208             MSimpleDocument* d = TSimpleXmlFactory::NewDocumentInMultiPartL(
       
   209                 content, aReq.ResponseBoundary(), aReq.ResponseStart() );            
       
   210             CleanupClosePushL( *d );
       
   211 #ifdef _DEBUG
       
   212             TSimpleLogger::Log(_L("Watcher: call WatcherNotificationL (content)"));
       
   213 #endif
       
   214             iObserver.WatcherNotificationL( *d );
       
   215             CleanupStack::PopAndDestroy( d );            
       
   216             }
       
   217         else
       
   218             {
       
   219             // Multipart for a presence list.
       
   220             MSimplePresenceList* l = TSimpleXmlFactory::NewPresenceListL( 
       
   221                 content, aReq.ResponseBoundary(), aReq.ResponseStart() );
       
   222             CleanupClosePushL( *l );
       
   223 #ifdef _DEBUG
       
   224             TSimpleLogger::Log(_L("Watcher: call WatcherListNotificationL"));
       
   225 #endif            
       
   226             iObserver.WatcherListNotificationL( *l );
       
   227             CleanupStack::PopAndDestroy( l );            
       
   228             }    
       
   229         }
       
   230     else
       
   231         {
       
   232         // Unsupported content type, ignore it.
       
   233         }
       
   234     }
       
   235 
       
   236 // ----------------------------------------------------------
       
   237 // CSimpleWatcher::Complete
       
   238 // ----------------------------------------------------------
       
   239 //
       
   240 void CSimpleWatcher::Complete(
       
   241     TInt aOpId, TInt aStatus, MSimpleEngineRequest& aReq )
       
   242     {   
       
   243 #ifdef _DEBUG
       
   244     TSimpleLogger::Log(_L("Watcher: Complete opid=%d status=%d" ),
       
   245     aOpId, aStatus );
       
   246 #endif
       
   247 
       
   248     // FUNCTIONALITY
       
   249     // Get
       
   250     // - SIP ok + terminated -> WatcherReqCompleteL(ok) + WatcherNotificationL(terminated)
       
   251     // - terminated + SIP ok -> WatcherNotificationL(terminated) + WatcherReqCompleteL(ok)
       
   252     //
       
   253     // Stop
       
   254     // - terminated + SIP ok -> WatcherReqCompleteL(ok)
       
   255     // - SIP ok + terminated -> WatcherReqCompleteL(ok)    
       
   256     //
       
   257     // Subscribe
       
   258     // - SIP error -> WatcherReqCompleteL(error)
       
   259     // - SIP ok + terminated ->
       
   260     //    WatcherReqCompleteL(ok) + WatcherNotificationL(terminated) + WatcherTerminated()
       
   261     // - SIP ok + active + terminated ->
       
   262     //        WatcherReqCompleteL(ok) + WatcherNotificationL(active) +
       
   263     //        WatcherNotificationL(terminated) + WatcherTErminated
       
   264     // - active + SIP ok + terminated ->
       
   265     //        WatcherNotificationL(active) + WatcherReqCompleteL(ok) +
       
   266     //        WatcherNotificationL(terminated) + WatcherTerminated
       
   267     //
       
   268 
       
   269     TBool completeNow( EFalse );
       
   270     MSimpleEngineRequest::TSimpleRequest orig = aReq.RequestType();
       
   271 
       
   272     if ( orig == MSimpleEngineRequest::EDestroyStart )
       
   273         {
       
   274         // It's time to delete the request of delayed deletion from both DLLs.
       
   275         // Delete immediately from another DLL.
       
   276         aReq.ModifyType( MSimpleEngineRequest::EDestroy );
       
   277         TRAP_IGNORE( SendReqL( aReq ));
       
   278         // Delete from this DLL,
       
   279         aReq.Destroy();
       
   280         return;
       
   281         }
       
   282 
       
   283     GetSIPStatus( aOpId );
       
   284 
       
   285     // Reset data buffer
       
   286     iBuffer->Reset();
       
   287 
       
   288     // Set the member to point to stack variable
       
   289     TBool destroyed( EFalse );
       
   290     iDestroyedPtr = &destroyed;
       
   291 
       
   292     MSimpleEngineRequest::TSimpleSIPResponse respMet = aReq.ResponseMethod();
       
   293 
       
   294     // Convert KSimpleErrPending to OK when needed
       
   295     if ( aStatus == KSimpleErrPending )
       
   296         {
       
   297         aStatus = KErrNone;
       
   298         }
       
   299 
       
   300     // Handle SIP notification first
       
   301     if ( respMet == MSimpleEngineRequest::ENotify )
       
   302         {
       
   303         // This is true in notifications. Ignore some responses.
       
   304         if ( aStatus == KErrCompletion )
       
   305             {
       
   306             iResCount++;
       
   307             }
       
   308         if ( orig != MSimpleEngineRequest::ESubscribeStop )
       
   309             {
       
   310             TRAP_IGNORE( NewRequestL( aReq ) );
       
   311             // Check whether an application has called destructor in callback method.
       
   312             // Destructor will handle deletion of all the open requests.
       
   313             if ( destroyed )
       
   314                 {
       
   315                 return;
       
   316                 }
       
   317             } 
       
   318         else if ( iResCount > 1  )
       
   319             {
       
   320             // Stop request is not completed until ok + Notify(terminated) received.  
       
   321             // Error completes the stop reqest without Notification.        
       
   322             completeNow = ETrue;
       
   323             if ( DoCallReqComplete( aOpId, KErrNone ))
       
   324                 {
       
   325                 return;
       
   326                 }            
       
   327             }    
       
   328         }
       
   329     else
       
   330         {
       
   331         // SIP Status response or client originated cancellation
       
   332         iResCount++;
       
   333         if ( aStatus != KErrNone )        
       
   334             {
       
   335             iResCount++;
       
   336             if ( orig == MSimpleEngineRequest::ESubscribeStop )     
       
   337                 {
       
   338                 // Any response to stop subscribe is ok.
       
   339                 aStatus = KErrNone;
       
   340                 }
       
   341             }
       
   342                
       
   343         if ( !iComplete && 
       
   344               ( orig != MSimpleEngineRequest::ESubscribeStop || 
       
   345                 orig == MSimpleEngineRequest::ESubscribeStop && iResCount > 1 ) )
       
   346             {
       
   347             // Stop request is not completed until ok + Notify(terminated) received.  
       
   348             // Error completes the stop reqest without Notification.        
       
   349             completeNow = ETrue;
       
   350             if ( DoCallReqComplete( aOpId, aStatus ))
       
   351                 {
       
   352                 return;
       
   353                 }
       
   354             }
       
   355         }
       
   356 
       
   357     // Delete request when not needed
       
   358     if ( iResCount > 1 )
       
   359         {
       
   360         iRequest = MSimpleEngineRequest::ENone;
       
   361         iComplete = EFalse;
       
   362         TInt reason = ResponseReason( aReq );
       
   363         // Delete corresponding request from another DLL with delay. This decreases
       
   364         // the counter of active subscriptions there.
       
   365         aReq.ModifyType( MSimpleEngineRequest::EDestroyStart );
       
   366         TRAP_IGNORE( SendReqL( aReq ));
       
   367         // call WatcherTerminatedL when needed, i.e. no Stop or Get
       
   368         if ( orig != MSimpleEngineRequest::ESubscribeStop &&
       
   369              orig != MSimpleEngineRequest::ESubscribeGet &&
       
   370              !completeNow )
       
   371             {
       
   372 #ifdef _DEBUG
       
   373             TSimpleLogger::Log(_L("Watcher: call WatcherTerminatedL opid=%d"),
       
   374                 aOpId );
       
   375 #endif
       
   376             TRAP_IGNORE( iObserver.WatcherTerminatedL( aOpId, reason ));
       
   377             // Check whether an application has called destructor in callback method.
       
   378             // Destructor of CSimpleClient base class will handle deletion of
       
   379             // all the open requests.
       
   380             if ( destroyed )
       
   381                 {
       
   382                 return;
       
   383                 }
       
   384             }
       
   385         // delete request from this DLL later
       
   386         }
       
   387 
       
   388     iDestroyedPtr = NULL;
       
   389     }
       
   390 
       
   391 // ----------------------------------------------------------
       
   392 // CSimpleWatcher::SubscribeL
       
   393 // ----------------------------------------------------------
       
   394 //
       
   395 TInt CSimpleWatcher::SubscribeL(
       
   396     const TDesC8& aURI,
       
   397     MSimpleFilterDocument* aFilter,
       
   398     TBool aRefresh,
       
   399     TBool aAnonymous  )
       
   400     {
       
   401 
       
   402     if ( iRequest != MSimpleEngineRequest::ENone )
       
   403         {
       
   404 #ifdef _DEBUG
       
   405         TSimpleLogger::Log(_L("Watcher: SubscribeL IN-USE **" ) );
       
   406 #endif
       
   407         User::Leave( KErrInUse );
       
   408         }
       
   409 
       
   410     IncreaseOpId();
       
   411 
       
   412 #ifdef _DEBUG
       
   413     TSimpleLogger::Log(_L("Watcher: SubscribeL opid=%d" ), iOpId );
       
   414 #endif
       
   415 
       
   416     CSimpleEngineRequest* req = CSimpleEngineRequest::NewL(
       
   417         *this, MSimpleEngineRequest::ESubscribe, iOpId );
       
   418     CleanupStack::PushL( req );
       
   419     req->SetRemoteURIL( aURI );
       
   420     req->SetRefresh( aRefresh );
       
   421     if ( aAnonymous )
       
   422         {
       
   423         req->SetAux( 1 );
       
   424         }
       
   425 
       
   426     // handle optional filter document
       
   427     if ( aFilter )
       
   428         {
       
   429         StreamDocumentL( *req, *aFilter );
       
   430         }
       
   431 
       
   432     SendReqL( *req );
       
   433     iRequestList.AddLast( *req );
       
   434     CleanupStack::Pop( req );
       
   435 
       
   436     iRequest = MSimpleEngineRequest::ESubscribe;
       
   437     iResCount = 0;
       
   438     iSubsId = iOpId;
       
   439 
       
   440     return iOpId;
       
   441     }
       
   442 
       
   443 // ----------------------------------------------------------
       
   444 // CSimpleWatcher::SubscribeListL
       
   445 // ----------------------------------------------------------
       
   446 //
       
   447 TInt CSimpleWatcher::SubscribeListL(
       
   448     const TDesC8& aURI,
       
   449     MSimpleFilterDocument* aFilter,
       
   450     TBool aRefresh,
       
   451     TBool aAnonymous )
       
   452     {
       
   453     if ( iRequest != MSimpleEngineRequest::ENone )
       
   454         {
       
   455 #ifdef _DEBUG
       
   456         TSimpleLogger::Log(_L("Watcher: SubscribeListL IN-USE **" ) );
       
   457 #endif
       
   458         User::Leave( KErrInUse );
       
   459         }
       
   460 
       
   461     IncreaseOpId();
       
   462 #ifdef _DEBUG
       
   463     TSimpleLogger::Log(_L("Watcher: SubscribeListL opid=%d" ), iOpId);
       
   464 #endif
       
   465 
       
   466     CSimpleEngineRequest* req = CSimpleEngineRequest::NewL(
       
   467         *this, MSimpleEngineRequest::ESubscribeLista, iOpId );
       
   468     CleanupStack::PushL( req );
       
   469     req->SetRemoteURIL( aURI );
       
   470     req->SetRefresh( aRefresh );
       
   471     if ( aAnonymous )
       
   472         {
       
   473         req->SetAux( 1 );
       
   474         }
       
   475 
       
   476     // handle optional filter document
       
   477     if ( aFilter )
       
   478         {
       
   479         StreamDocumentL( *req, *aFilter );
       
   480         }
       
   481 
       
   482     SendReqL( *req );
       
   483     iRequestList.AddLast( *req );
       
   484     CleanupStack::Pop( req );
       
   485 
       
   486     iRequest = MSimpleEngineRequest::ESubscribeLista;
       
   487     iResCount = 0;
       
   488     iSubsId = iOpId;
       
   489 
       
   490     return iOpId;
       
   491     }
       
   492 
       
   493 // ----------------------------------------------------------
       
   494 // CSimpleWatcher::GetPresenceL
       
   495 // ----------------------------------------------------------
       
   496 //
       
   497 TInt CSimpleWatcher::GetPresenceL(
       
   498     const TDesC8& aURI,
       
   499     MSimpleFilterDocument* aFilter,
       
   500     TBool aAnonymous  )
       
   501     {
       
   502     if ( iRequest != MSimpleEngineRequest::ENone )
       
   503         {
       
   504 #ifdef _DEBUG
       
   505         TSimpleLogger::Log(_L("Watcher: GetPresenceL IN-USE **" ) );
       
   506 #endif
       
   507         User::Leave( KErrInUse );
       
   508         }
       
   509 
       
   510     IncreaseOpId();
       
   511 #ifdef _DEBUG
       
   512     TSimpleLogger::Log(_L("Watcher: GetPresenceL opid=%d" ), iOpId );
       
   513 #endif
       
   514 
       
   515     CSimpleEngineRequest* req = CSimpleEngineRequest::NewL(
       
   516         *this, MSimpleEngineRequest::ESubscribeGet, iOpId );
       
   517     CleanupStack::PushL( req );
       
   518     req->SetRemoteURIL( aURI );
       
   519     if ( aAnonymous )
       
   520         {
       
   521         req->SetAux( 1 );
       
   522         }
       
   523 
       
   524     // handle optional filter document
       
   525     if ( aFilter )
       
   526         {
       
   527         StreamDocumentL( *req, *aFilter );
       
   528         }
       
   529 
       
   530     SendReqL( *req );
       
   531     iRequestList.AddLast( *req );
       
   532     CleanupStack::Pop( req );
       
   533 
       
   534     iRequest = MSimpleEngineRequest::ESubscribeGet;
       
   535     iResCount = 0;
       
   536 
       
   537     return iOpId;
       
   538     }
       
   539 
       
   540 // ----------------------------------------------------------
       
   541 // CSimpleWatcher::UnsubscribeL
       
   542 // ----------------------------------------------------------
       
   543 //
       
   544 TInt CSimpleWatcher::UnsubscribeL( )
       
   545     {
       
   546 
       
   547 #ifdef _DEBUG
       
   548     TSimpleLogger::Log(_L("Watcher: UnsubscribeL opid=%d" ), iSubsId);
       
   549 #endif
       
   550     // use the old opid and request
       
   551     CSimpleEngineRequest* req = SearchRequests( iSubsId );
       
   552     if ( !req )
       
   553         {
       
   554         User::Leave( KErrNotFound );
       
   555         }
       
   556     req->ModifyType( MSimpleEngineRequest::ESubscribeStop );
       
   557 
       
   558     SendReqL( *req );
       
   559 
       
   560     iRequest = MSimpleEngineRequest::ESubscribeStop;
       
   561     iComplete = EFalse;
       
   562     iResCount = 0;
       
   563 
       
   564     return iOpId;
       
   565     }
       
   566 
       
   567 // ----------------------------------------------------------
       
   568 // CSimpleWatcher::StreamDocumentL
       
   569 // ----------------------------------------------------------
       
   570 //
       
   571 void CSimpleWatcher::StreamDocumentL(
       
   572     CSimpleEngineRequest& aReq,
       
   573     MSimpleFilterDocument& aFilter )
       
   574     {
       
   575     // add request data
       
   576     // externalize the document a stream
       
   577     iBuffer->Reset();
       
   578     RBufWriteStream stream( *iBuffer );
       
   579     stream.Open( *iBuffer );
       
   580     aFilter.ExternalizeL( stream );
       
   581     stream.Close();
       
   582     aReq.SetRequestData( iBuffer->Ptr(0) );
       
   583     }
       
   584     
       
   585 // ----------------------------------------------------------
       
   586 // CSimpleWatcher::DoCallReqComplete
       
   587 // ----------------------------------------------------------
       
   588 //
       
   589 TInt CSimpleWatcher::DoCallReqComplete(
       
   590     TInt aOpId, TInt aStatus )
       
   591     {
       
   592     // Set the member to point to stack variable
       
   593     TBool destroyed( EFalse );
       
   594     iDestroyedPtr = &destroyed;
       
   595         
       
   596     iComplete = ETrue;    
       
   597 #ifdef _DEBUG
       
   598     TSimpleLogger::Log(_L("Watcher: call WatcherReqCompleteL opid=%d status=%d"),
       
   599         aOpId, aStatus);
       
   600 #endif
       
   601     TRAP_IGNORE( iObserver.WatcherReqCompleteL( aOpId, aStatus ));
       
   602     // Check whether an application has called destructor in callback method.
       
   603     // Destructor will handle deletion of all the open requests.
       
   604     if ( destroyed )
       
   605         {
       
   606         return KErrGeneral;
       
   607         }
       
   608     return KErrNone; 
       
   609     }
       
   610