simpleengine/engine/src/simplewinfowatcher.cpp
changeset 0 c8caa15ef882
equal deleted inserted replaced
-1:000000000000 0:c8caa15ef882
       
     1 /*
       
     2 * Copyright (c) 2006 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 "simplecommon.h"
       
    29 #include "simpleenginerequest.h"
       
    30 #include "msimplewinfo.h"
       
    31 #include "msimplefilterdocument.h"
       
    32 #include "msimplewinfoobserver.h"
       
    33 #include "simplewinfowatcher.h"
       
    34 #include "simplexmlfactory.h"
       
    35 #include "simplesipconnection.h"
       
    36 #include "simpleerrors.h"
       
    37 
       
    38 #ifdef _DEBUG
       
    39 #include "simpledebugutils.h"
       
    40 #endif
       
    41 
       
    42 const TInt KExpandSize = 512;
       
    43 
       
    44 // ================= MEMBER FUNCTIONS =======================
       
    45 //
       
    46 
       
    47 // ----------------------------------------------------------
       
    48 // CSimpleWinfoWatcher::CSimpleWinfoWatcher
       
    49 // ----------------------------------------------------------
       
    50 //
       
    51 CSimpleWinfoWatcher::CSimpleWinfoWatcher(
       
    52     MSimpleConnection& aConn,
       
    53     MSimpleWinfoObserver& aObserver )
       
    54 : CSimpleClient( aConn ),
       
    55   iObserver( aObserver ),
       
    56   iResCount(0), iComplete( EFalse ),
       
    57   iBuffer(NULL)
       
    58     {
       
    59     }
       
    60 
       
    61 // ----------------------------------------------------------
       
    62 // CSimpleWinfoWatcher::~CSimpleWinfoWatcher
       
    63 // ----------------------------------------------------------
       
    64 //
       
    65 CSimpleWinfoWatcher::~CSimpleWinfoWatcher()
       
    66     {
       
    67 #ifdef _DEBUG
       
    68     TSimpleLogger::Log(_L("WinfoWatcher: Destructor this=%d" ), (TInt)this );
       
    69 #endif
       
    70     delete iBuffer;
       
    71     }
       
    72 
       
    73 // ----------------------------------------------------------
       
    74 // CSimpleWinfoWatcher::ConstructL
       
    75 // ----------------------------------------------------------
       
    76 //
       
    77 void CSimpleWinfoWatcher::ConstructL()
       
    78     {
       
    79     BaseConstructL();
       
    80     iBuffer = CBufFlat::NewL(KExpandSize);
       
    81     }
       
    82 
       
    83 // ----------------------------------------------------------
       
    84 // CSimpleWinfoWatcher::NewL
       
    85 // ----------------------------------------------------------
       
    86 //
       
    87 CSimpleWinfoWatcher* CSimpleWinfoWatcher::NewL(
       
    88     MSimpleConnection& aConn,
       
    89     MSimpleWinfoObserver& aObserver )
       
    90     {
       
    91     CSimpleWinfoWatcher* self = new (ELeave) CSimpleWinfoWatcher(
       
    92         aConn, aObserver );
       
    93     CleanupStack::PushL( self );
       
    94     self->ConstructL();
       
    95     CleanupStack::Pop( self );
       
    96 #ifdef _DEBUG
       
    97     TSimpleLogger::Log(_L("WinfoWatcher: NewL this=%d"), (TInt)self );
       
    98 #endif    
       
    99     return self;
       
   100     }
       
   101 
       
   102 // ----------------------------------------------------------
       
   103 // CSimpleWinfoWatcher::Connection
       
   104 // ----------------------------------------------------------
       
   105 //
       
   106 const MSimpleConnection& CSimpleWinfoWatcher::Connection()
       
   107     {
       
   108     return iConn;
       
   109     }
       
   110 
       
   111 // ----------------------------------------------------------
       
   112 // CSimpleWinfoWatcher::SIPStatus
       
   113 // ----------------------------------------------------------
       
   114 //
       
   115 TUint CSimpleWinfoWatcher::SIPStatus()
       
   116     {
       
   117     return DoSIPStatus();
       
   118     }
       
   119 
       
   120 // ----------------------------------------------------------
       
   121 // CSimpleWinfoWatcher::SIPRetryAfter
       
   122 // ----------------------------------------------------------
       
   123 //
       
   124 TUint CSimpleWinfoWatcher::SIPRetryAfter()
       
   125     {
       
   126     return DoRetryAfter();
       
   127     }
       
   128 
       
   129 // ----------------------------------------------------------
       
   130 // CSimpleWinfoWatcher::Close
       
   131 // ----------------------------------------------------------
       
   132 //
       
   133 void CSimpleWinfoWatcher::Close( )
       
   134     {
       
   135     delete this;
       
   136     }
       
   137 
       
   138 // ----------------------------------------------------------
       
   139 // CSimpleWinfoWatcher::NewRequestL
       
   140 // ----------------------------------------------------------
       
   141 //
       
   142 void CSimpleWinfoWatcher::NewRequestL( MSimpleEngineRequest& aReq )
       
   143     {
       
   144     TPtrC8 content = aReq.ResponseData();
       
   145     TPtrC8 contType = aReq.ResponseContentType();
       
   146     TPtrC8 p8;
       
   147     p8.Set( KSimpleWinfoType );
       
   148     TInt mySize = p8.Length();
       
   149 
       
   150     if ( !contType.Left(mySize).CompareF(KSimpleWinfoType))
       
   151         {
       
   152         MSimpleWinfo* d = TSimpleXmlFactory::NewWinfoL( content );
       
   153         CleanupClosePushL( *d );
       
   154 #ifdef _DEBUG
       
   155         TSimpleLogger::Log(_L("WinfoWatcher: call WinfoNotificationL"));
       
   156 #endif
       
   157         iObserver.WinfoNotificationL( *d );
       
   158         CleanupStack::PopAndDestroy( d );
       
   159         }
       
   160     }
       
   161 
       
   162 // ----------------------------------------------------------
       
   163 // CSimpleWinfoWatcher::Complete
       
   164 // ----------------------------------------------------------
       
   165 //
       
   166 void CSimpleWinfoWatcher::Complete(
       
   167     TInt aOpId, TInt aStatus, MSimpleEngineRequest& aReq )
       
   168     {
       
   169 #ifdef _DEBUG
       
   170     TSimpleLogger::Log(_L("WinfoWatcher: Complete opid=%d, status=%d" ),
       
   171                        aOpId, aStatus );
       
   172 #endif
       
   173 
       
   174     TBool completeNow( EFalse );
       
   175     MSimpleEngineRequest::TSimpleRequest orig = aReq.RequestType();
       
   176 
       
   177     if ( orig == MSimpleEngineRequest::EDestroyStart )
       
   178         {
       
   179         // It's time to delete the request of delayed deletion from both DLLs.
       
   180         // Delete immediately from another DLL.
       
   181         aReq.ModifyType( MSimpleEngineRequest::EDestroy );
       
   182         TRAP_IGNORE( SendReqL( aReq ));
       
   183         // Delete from this DLL,
       
   184         aReq.Destroy();
       
   185         return;
       
   186         }
       
   187 
       
   188     GetSIPStatus( aOpId );
       
   189 
       
   190     // Reset data buffer
       
   191     iBuffer->Reset();
       
   192 
       
   193     // Set the member to point to stack variable
       
   194     TBool destroyed( EFalse );
       
   195     iDestroyedPtr = &destroyed;
       
   196 
       
   197     MSimpleEngineRequest::TSimpleSIPResponse respMet = aReq.ResponseMethod();
       
   198 
       
   199     // Convert KSimpleErrPending to OK when needed
       
   200     if ( aStatus == KSimpleErrPending )
       
   201         {
       
   202         aStatus = KErrNone;
       
   203         }
       
   204 
       
   205     // Handle SIP notification first
       
   206     if ( respMet == MSimpleEngineRequest::ENotify )
       
   207         {
       
   208         // This is true in notifications. Ignore some responses.
       
   209         if ( aStatus == KErrCompletion )
       
   210             {
       
   211             iResCount++;
       
   212             }
       
   213         if ( orig != MSimpleEngineRequest::ESubscribeStop )
       
   214             {
       
   215             TRAP_IGNORE( NewRequestL( aReq ) );
       
   216             // Check whether an application has called destructor in callback method.
       
   217             // Destructor will handle deletion of all the open requests.
       
   218             if ( destroyed )
       
   219                 {
       
   220                 return;
       
   221                 }
       
   222             } 
       
   223         else if ( iResCount > 1  )
       
   224             {
       
   225             // Stop request is not completed until ok + Notify(terminated) received.  
       
   226             // Error completes the stop reqest without Notification.        
       
   227             completeNow = ETrue;
       
   228             if ( DoCallReqComplete( aOpId, KErrNone ))
       
   229                 {
       
   230                 return;
       
   231                 }            
       
   232             }    
       
   233         }
       
   234     else
       
   235         {
       
   236         // SIP Status response or client originated cancellation
       
   237         iResCount++;
       
   238         if ( aStatus != KErrNone )        
       
   239             {
       
   240             iResCount++;  
       
   241             if ( orig == MSimpleEngineRequest::ESubscribeStop )     
       
   242                     {
       
   243                     // Any response to stop subscribe is ok.
       
   244                     aStatus = KErrNone;
       
   245                     }                      
       
   246             }
       
   247                
       
   248         if ( !iComplete && 
       
   249               ( orig != MSimpleEngineRequest::ESubscribeStop || 
       
   250                 orig == MSimpleEngineRequest::ESubscribeStop && iResCount > 1 ) )
       
   251             {
       
   252             // Stop request is not completed until ok + Notify(terminated) received.  
       
   253             // Error completes the stop reqest without Notification.        
       
   254             completeNow = ETrue;
       
   255             if ( DoCallReqComplete( aOpId, aStatus ))
       
   256                 {
       
   257                 return;
       
   258                 }
       
   259             }
       
   260         }
       
   261 
       
   262     // Delete request when not needed
       
   263     if ( iResCount > 1 )
       
   264         {
       
   265         iRequest = MSimpleEngineRequest::ENone;
       
   266         iComplete = EFalse;
       
   267         TInt reason = ResponseReason( aReq );
       
   268         // Delete corresponding request from another DLL with delay. This decreases
       
   269         // the counter of active subscriptions there.
       
   270         aReq.ModifyType( MSimpleEngineRequest::EDestroyStart );
       
   271         TRAP_IGNORE( SendReqL( aReq ));        
       
   272         // call WinfoTerminatedL when needed, i.e. no Stop 
       
   273         if ( orig != MSimpleEngineRequest::ESubscribeStop &&
       
   274              !completeNow )
       
   275             {
       
   276 #ifdef _DEBUG
       
   277             TSimpleLogger::Log(_L("WinfoWatcher: call WinfoTerminatedL opid=%d"),
       
   278                 aOpId );
       
   279 #endif
       
   280             TRAP_IGNORE( iObserver.WinfoTerminatedL( aOpId, reason ) );
       
   281             // Check whether an application has called destructor in callback method.
       
   282             // Destructor of CSimpleClient base class will handle deletion of
       
   283             // all the open requests.
       
   284             if ( destroyed )
       
   285                 {
       
   286                 return;
       
   287                 }
       
   288             }
       
   289         // delete request from this DLL later.
       
   290         }
       
   291 
       
   292     iDestroyedPtr = NULL;
       
   293     }
       
   294 
       
   295 // ----------------------------------------------------------
       
   296 // CSimpleWinfoWatcher::SubscribeWatcherListL
       
   297 // ----------------------------------------------------------
       
   298 //
       
   299 TInt CSimpleWinfoWatcher::SubscribeWatcherListL(
       
   300     MSimpleFilterDocument* aFilter )
       
   301     {
       
   302 
       
   303     if ( iRequest != MSimpleEngineRequest::ENone )
       
   304         {
       
   305 #ifdef _DEBUG
       
   306         TSimpleLogger::Log(_L("winfoWatcher: SubscribeWatcherListL IN-USE **" ) );
       
   307 #endif
       
   308         User::Leave( KErrInUse );
       
   309         }
       
   310 
       
   311     IncreaseOpId();
       
   312 
       
   313 #ifdef _DEBUG
       
   314     TSimpleLogger::Log(_L("WinfoWatcher: SubscribeWatcherListL opid=%d"),iOpId);
       
   315 #endif
       
   316     CSimpleEngineRequest* req = CSimpleEngineRequest::NewL(
       
   317         *this, MSimpleEngineRequest::ESubscribeWinfo, iOpId );
       
   318     CleanupStack::PushL( req );
       
   319 
       
   320     // handle optional filter document
       
   321     if ( aFilter )
       
   322         {
       
   323         StreamDocumentL( *req, *aFilter );
       
   324         }
       
   325 
       
   326     SendReqL( *req );
       
   327     iRequestList.AddLast( *req );
       
   328     CleanupStack::Pop( req );
       
   329 
       
   330     iRequest = MSimpleEngineRequest::ESubscribeWinfo;
       
   331     iResCount = 0;
       
   332     iSubsId = iOpId;
       
   333 
       
   334     return iOpId;
       
   335     }
       
   336 
       
   337 // ----------------------------------------------------------
       
   338 // CSimpleWinfoWatcher::UnsubscribeL
       
   339 // ----------------------------------------------------------
       
   340 //
       
   341 TInt CSimpleWinfoWatcher::UnsubscribeL( )
       
   342     {
       
   343 
       
   344 #ifdef _DEBUG
       
   345     TSimpleLogger::Log(_L("WinfoWatcher: UnsubscribeL opid=%d" ), iSubsId);
       
   346 #endif
       
   347     // use the old opid and request
       
   348     CSimpleEngineRequest* req = SearchRequests( iSubsId );
       
   349     if ( !req )
       
   350         {
       
   351         User::Leave( KErrNotFound );
       
   352         }
       
   353     req->ModifyType( MSimpleEngineRequest::ESubscribeStop );
       
   354 
       
   355     SendReqL( *req );
       
   356 
       
   357     iRequest = MSimpleEngineRequest::ESubscribeStop;
       
   358     iComplete = EFalse;
       
   359     iResCount = 0;
       
   360 
       
   361     return iOpId;
       
   362     }
       
   363 
       
   364 // ----------------------------------------------------------
       
   365 // CSimpleWinfoWatcher::StreamDocumentL
       
   366 // ----------------------------------------------------------
       
   367 //
       
   368 void CSimpleWinfoWatcher::StreamDocumentL(
       
   369     CSimpleEngineRequest& aReq,
       
   370     MSimpleFilterDocument& aFilter )
       
   371     {
       
   372     // add request data
       
   373     // externalize the document a stream
       
   374     iBuffer->Reset();
       
   375     RBufWriteStream stream( *iBuffer );
       
   376     stream.Open( *iBuffer );
       
   377     aFilter.ExternalizeL( stream );
       
   378     stream.Close();
       
   379     aReq.SetRequestData( iBuffer->Ptr(0) );
       
   380     }
       
   381     
       
   382 // ----------------------------------------------------------
       
   383 // CSimpleWinfoWatcher::DoCallReqComplete
       
   384 // ----------------------------------------------------------
       
   385 //
       
   386 TInt CSimpleWinfoWatcher::DoCallReqComplete(
       
   387     TInt aOpId, TInt aStatus )
       
   388     {
       
   389     // Set the member to point to stack variable
       
   390     TBool destroyed( EFalse );
       
   391     iDestroyedPtr = &destroyed;
       
   392         
       
   393     iComplete = ETrue;    
       
   394 #ifdef _DEBUG
       
   395     TSimpleLogger::Log(_L("WinfoWatcher: call WinfoReqCompleteL opid=%d status=%d"),
       
   396         aOpId, aStatus);
       
   397 #endif
       
   398     TRAP_IGNORE( iObserver.WinfoReqCompleteL( aOpId, aStatus ));
       
   399     // Check whether an application has called destructor in callback method.
       
   400     // Destructor will handle deletion of all the open requests.
       
   401     if ( destroyed )
       
   402         {
       
   403         return KErrGeneral;
       
   404         }
       
   405     return KErrNone; 
       
   406     }
       
   407