simpleengine/siputils/src/simplerequest.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:    sip request
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 
       
    23 // sip api
       
    24 #include <sip.h>
       
    25 #include <sipconnection.h>
       
    26 #include <sipconnectionobserver.h>
       
    27 #include <sipresponseelements.h>
       
    28 #include <siprequestelements.h>
       
    29 #include <sipclienttransaction.h>
       
    30 #include <siprefresh.h>
       
    31 #include <sipdialog.h>
       
    32 #include <sipsubscribedialogassoc.h>
       
    33 
       
    34 // simple
       
    35 #include "simplesipconnection.h"
       
    36 #include "simplerefreshtimer.h"
       
    37 #include "simpleerrors.h"
       
    38 #include "simplecommon.h"
       
    39 
       
    40 #ifdef _DEBUG
       
    41 #include "simpledebugutils.h"
       
    42 #endif
       
    43 
       
    44 // time limits in seconds
       
    45 const TInt KRefreshLimit = 1200; // limit when KRefreshBefore is used
       
    46 const TInt KRefreshBefore = 600; // how much before expiration a refresh is done
       
    47 const TInt KRetryBefore = 300; // how much before expiration a retry is done
       
    48 const TInt KMinorDelay = 5; // garbage collection and retry delay
       
    49 const TInt KDeleteDelay = 1; // delay before deleting a subscription request
       
    50 const TInt KMinorExpiry = 65; // default expiration time for re-try 
       
    51 
       
    52 
       
    53 // ================= MEMBER FUNCTIONS =======================
       
    54 //
       
    55 
       
    56 // -----------------------------------------------------------------------------
       
    57 // CSimpleRequest::CSimpleRequest
       
    58 // -----------------------------------------------------------------------------
       
    59 
       
    60 CSimpleRequest::CSimpleRequest(
       
    61     MSimpleSipConnCallback& aEngine,
       
    62     MSimpleEngineRequest& aReq,
       
    63     TSimpleSipReqType aType,
       
    64     TUint aExpires )
       
    65     : iEngine(aEngine), iReq(aReq),
       
    66       iTrans(NULL), iSipRefresh(NULL), iType(aType),
       
    67       iDialog(NULL), iStatus(KErrNone),
       
    68       iState(ESimpleInit), iRetryAfter(0),
       
    69       iReason(KErrNone), iExpires(aExpires),
       
    70       iPendingState(ENoPending), iData(NULL),
       
    71       iGivenETag( EFalse ), iSubscriptionState(MSimpleEngineRequest::ESimpleStateNone),
       
    72       iRespCount(0)
       
    73         {}
       
    74 
       
    75 CSimpleRequest::~CSimpleRequest()
       
    76     {
       
    77     StopExpiryTimer();
       
    78     StopRefreshTimer();
       
    79     delete iSipRefresh;
       
    80     delete iRefreshTimer;
       
    81     delete iExpiryTimer;
       
    82     delete iETag;
       
    83     delete iDialog;
       
    84     delete iTrans;
       
    85     delete iData;
       
    86     delete iRecipientId;
       
    87     delete iRequestContentType;
       
    88     }
       
    89 
       
    90 // ----------------------------------------------------------
       
    91 // CSimpleRequest::NewL
       
    92 // ----------------------------------------------------------
       
    93 //
       
    94 CSimpleRequest* CSimpleRequest::NewL(
       
    95     MSimpleSipConnCallback& aEngine,
       
    96     MSimpleEngineRequest& aReq,
       
    97     TSimpleSipReqType aType,
       
    98     TUint aExpires )
       
    99     {
       
   100     CSimpleRequest* self = new (ELeave) CSimpleRequest(
       
   101         aEngine,
       
   102         aReq,
       
   103         aType,
       
   104         aExpires );
       
   105     CleanupStack::PushL( self );
       
   106     self->ConstructL();
       
   107     CleanupStack::Pop( self );
       
   108 #ifdef _DEBUG
       
   109     TSimpleLogger::Log(_L("SimpleRequest: NewL this=%d" ), (TInt)self );
       
   110 #endif
       
   111     return self;
       
   112     }
       
   113 
       
   114 // ----------------------------------------------------------
       
   115 // CSimpleRequest::ConstructL
       
   116 // ----------------------------------------------------------
       
   117 //
       
   118 void CSimpleRequest::ConstructL(  )
       
   119     {
       
   120     iExpiryTimer = new (ELeave) CSimpleExpiryTimer( iEngine, *this );
       
   121     iRefreshTimer = new (ELeave) CSimpleRefreshTimer( iEngine, *this );
       
   122     }
       
   123 
       
   124 // -----------------------------------------------------------------------------
       
   125 // CSimpleRequest::Destroy
       
   126 // -----------------------------------------------------------------------------
       
   127 void CSimpleRequest::Destroy()
       
   128     {
       
   129 #ifdef _DEBUG
       
   130     TSimpleLogger::Log(_L("SimpleRequest: DESTROY this=%d"), (TInt)this );
       
   131 #endif
       
   132     iLink.Deque();
       
   133     delete this;
       
   134     }
       
   135 
       
   136 // -----------------------------------------------------------------------------
       
   137 // CSimpleRequest::DestroyStart
       
   138 // -----------------------------------------------------------------------------
       
   139 void CSimpleRequest::DestroyStart()
       
   140     {
       
   141 #ifdef _DEBUG
       
   142     TSimpleLogger::Log(_L("SimpleRequest: DestroyStart this=%d"), (TInt)this );
       
   143 #endif
       
   144     SetReqState( ESimpleDeleting );
       
   145     // Yield control to active scheduler before deleting a request. The request may have
       
   146     // called multiple callback methods, so it's safer to break the call.
       
   147     StartExpiryTimer( KDeleteDelay );
       
   148     StopRefreshTimer();
       
   149     }
       
   150 
       
   151 // -----------------------------------------------------------------------------
       
   152 // CSimpleRequest::Request
       
   153 // -----------------------------------------------------------------------------
       
   154 MSimpleEngineRequest& CSimpleRequest::Request()
       
   155     {
       
   156     return iReq;
       
   157     }
       
   158 
       
   159 // -----------------------------------------------------------------------------
       
   160 // CSimpleRequest::Transaction
       
   161 // -----------------------------------------------------------------------------
       
   162 CSIPClientTransaction* CSimpleRequest::Transaction()
       
   163     {
       
   164     return iTrans;
       
   165     }
       
   166 
       
   167 // -----------------------------------------------------------------------------
       
   168 // CSimpleRequest::SetTransaction
       
   169 // -----------------------------------------------------------------------------
       
   170 void CSimpleRequest::SetTransaction( CSIPClientTransaction* aTrans )
       
   171     {
       
   172     delete iTrans;
       
   173     iTrans = aTrans;
       
   174     }
       
   175 
       
   176 // -----------------------------------------------------------------------------
       
   177 // CSimpleRequest::Refresh
       
   178 // -----------------------------------------------------------------------------
       
   179 CSIPRefresh* CSimpleRequest::Refresh()
       
   180     {
       
   181     return iSipRefresh;
       
   182     }
       
   183 
       
   184 // -----------------------------------------------------------------------------
       
   185 // CSimpleRequest::Match
       
   186 // -----------------------------------------------------------------------------
       
   187 TBool CSimpleRequest::Match( CSIPClientTransaction& aTrans )
       
   188     {
       
   189     CSIPClientTransaction* tr = Transaction();
       
   190     return ( tr && aTrans == *tr ? ETrue : EFalse );
       
   191     }
       
   192 
       
   193 // -----------------------------------------------------------------------------
       
   194 // CSimpleRequest::Match
       
   195 // -----------------------------------------------------------------------------
       
   196 TBool CSimpleRequest::Match( TSimpleSipReqType aType ) const
       
   197     {
       
   198     return ( aType == iType ? ETrue : EFalse );
       
   199     }
       
   200 
       
   201 // -----------------------------------------------------------------------------
       
   202 // CSimpleRequest::Match
       
   203 // -----------------------------------------------------------------------------
       
   204 TBool CSimpleRequest::Match( const CSIPDialog& aDialog ) const
       
   205     {
       
   206     return aDialog.IsAssociated( *iDialog );
       
   207     }
       
   208 
       
   209 // -----------------------------------------------------------------------------
       
   210 // CSimpleRequest::Match
       
   211 // -----------------------------------------------------------------------------
       
   212 TBool CSimpleRequest::Match( MSimpleEngineRequest& aReq ) const
       
   213     {
       
   214     if ( aReq.OpId() == iReq.OpId() )
       
   215         {
       
   216         return ETrue;
       
   217         }
       
   218     return EFalse;
       
   219     }
       
   220 
       
   221 // -----------------------------------------------------------------------------
       
   222 // CSimpleRequest::Complete
       
   223 // -----------------------------------------------------------------------------
       
   224 void CSimpleRequest::Complete( TInt aStatus )
       
   225     {
       
   226 #ifdef _DEBUG
       
   227     TSimpleLogger::Log(_L("SimpleRequest: Complete %d this=%d"),aStatus, (TInt)this );
       
   228 #endif
       
   229 
       
   230     if ( iState == ESimpleDeleting )
       
   231         {
       
   232         // Tell to other DLL that this can be deleted now.
       
   233         iReq.Complete( aStatus );
       
   234         return;
       
   235         }
       
   236     if (( aStatus == KErrDisconnected ) ||
       
   237         ( aStatus == KErrTimedOut && iType != EReqPublish ))
       
   238         {
       
   239         // This is a serious network problem
       
   240         SetRetryAfter( 0 );
       
   241         StopExpiryTimer();
       
   242         StopRefreshTimer();
       
   243         SetReqState( ESimpleFailed );
       
   244         iReq.Complete( aStatus );
       
   245         return;
       
   246         }
       
   247 
       
   248     if ( iType == EReqRegister )
       
   249         {
       
   250         // stop expiry timer
       
   251         StopExpiryTimer();
       
   252         // Complete the client request
       
   253         iReq.Complete( aStatus );
       
   254         }
       
   255     else if ( iType == EReqPublish )
       
   256         {
       
   257         DoCompletePublication( aStatus );
       
   258         }
       
   259     else if ( EReqSendIM == iType )
       
   260         {
       
   261         iReq.Complete( aStatus );
       
   262         return;
       
   263         }
       
   264     else if ( EReqReceiveIM == iType )
       
   265         {
       
   266         TRAP_IGNORE( iReq.SetResponseDataL( Data() ) )
       
   267         TRAP_IGNORE( iReq.SetRecipientL( RecipientL() ) )
       
   268         iReq.Complete( aStatus );
       
   269         return;
       
   270         }
       
   271     else if ( iType == EReqSubscribe || iType == EReqSubscribeList || iType == EReqSubscribeWinfo )
       
   272         {
       
   273         if ( Request().ResponseMethod( ) == MSimpleEngineRequest::ENotify )
       
   274             {
       
   275             DoCompleteNotification( aStatus );
       
   276             }
       
   277         else
       
   278             {
       
   279             DoCompleteSubscription( aStatus );
       
   280             }
       
   281         }
       
   282     // EReqListEvents will go to CompleteEvent method.
       
   283     }
       
   284 
       
   285 // -----------------------------------------------------------------------------
       
   286 // CSimpleRequest::CompleteEvent
       
   287 // -----------------------------------------------------------------------------
       
   288 void CSimpleRequest::CompleteEvent( )
       
   289     {
       
   290 #ifdef _DEBUG
       
   291     TSimpleLogger::Log(_L("SimpleRequest: CompleteEvent this=%d"),(TInt)this );
       
   292 #endif
       
   293     iReq.Complete( KErrNone );
       
   294     }
       
   295 
       
   296 // -----------------------------------------------------------------------------
       
   297 // CSimpleRequest::SetRefreshTime
       
   298 // -----------------------------------------------------------------------------
       
   299 void CSimpleRequest::SetRefreshTime( TUint aTime )
       
   300     {
       
   301     iRefreshTime = aTime;
       
   302     }
       
   303 
       
   304 // -----------------------------------------------------------------------------
       
   305 // CSimpleRequest::RefreshTime
       
   306 // -----------------------------------------------------------------------------
       
   307 TUint CSimpleRequest::RefreshTime( ) const
       
   308     {
       
   309     return iRefreshTime;
       
   310     }
       
   311 
       
   312 // -----------------------------------------------------------------------------
       
   313 // CSimpleRequest::StartRefreshTimer
       
   314 // -----------------------------------------------------------------------------
       
   315 void CSimpleRequest::StartRefreshTimer( TUint aTime )
       
   316     {
       
   317 
       
   318     // Refresh a little bit earlier, KRefreshBefore sec
       
   319     // If expiration time is greater than 1200 seconds,
       
   320     // the interval is set to 600 seconds lower than expiration time.
       
   321     // Otherwise, interval is set to half of the expiration time.
       
   322 
       
   323     if ( aTime )
       
   324         {
       
   325         // special time used for error recovery
       
   326         iRefreshTimer->Start( aTime );
       
   327         return;
       
   328         }
       
   329 
       
   330     // This time is for garbage collection
       
   331     TUint myTime = iRefreshTime + KMinorDelay;
       
   332 
       
   333     if ( iReq.IsRefresh() )
       
   334         {
       
   335         // This time is for regular PUBLISH refresh
       
   336         if ( iRefreshTime > KRefreshLimit )
       
   337             {
       
   338             myTime = iRefreshTime - KRefreshBefore;
       
   339             }
       
   340         else
       
   341             {
       
   342             myTime = iRefreshTime / 2 ;
       
   343             }
       
   344         }
       
   345 
       
   346     iRefreshTimer->Start( myTime );
       
   347     }
       
   348 
       
   349 // -----------------------------------------------------------------------------
       
   350 // CSimpleRequest::StopRefreshTimer
       
   351 // -----------------------------------------------------------------------------
       
   352 void CSimpleRequest::StopRefreshTimer()
       
   353     {
       
   354     if ( iRefreshTimer )
       
   355         {
       
   356         iRefreshTimer->Cancel();
       
   357         }
       
   358     }
       
   359 
       
   360 // -----------------------------------------------------------------------------
       
   361 // CSimpleRequest::StartExpiryTimer
       
   362 // -----------------------------------------------------------------------------
       
   363 void CSimpleRequest::StartExpiryTimer( TUint aTime )
       
   364     {
       
   365     iExpiryTimer->Start( aTime );
       
   366     }
       
   367 
       
   368 // -----------------------------------------------------------------------------
       
   369 // CSimpleRequest::StopExpiryTimer
       
   370 // -----------------------------------------------------------------------------
       
   371 void CSimpleRequest::StopExpiryTimer()
       
   372     {
       
   373     if ( iExpiryTimer )
       
   374         {
       
   375         iExpiryTimer->Cancel();
       
   376         }
       
   377     }
       
   378 
       
   379 // -----------------------------------------------------------------------------
       
   380 // CSimpleRequest::RetryTime
       
   381 // -----------------------------------------------------------------------------
       
   382 TUint CSimpleRequest::RetryTime()
       
   383     {
       
   384     // Retry (refresh) time in error recovery retry.
       
   385 
       
   386     // If retry-after SIP header value is present then use it.
       
   387 
       
   388     // If retry-after is not available:
       
   389     // A quarter of expires value (=half of the current time until expires),
       
   390     // maximum 300 seconds.
       
   391 
       
   392     // This time policy is in line with SIP stack and presence refreshment policy.
       
   393     // Too long time interval is checked outside this method,
       
   394 
       
   395     TUint myTime(0);
       
   396 
       
   397     if ( iRetryAfter )
       
   398         {
       
   399         // Retry-after header value
       
   400         myTime = iRetryAfter;
       
   401         }
       
   402     else if ( iRefreshTime > KRefreshLimit )
       
   403         {
       
   404         myTime = KRetryBefore;
       
   405         }
       
   406     else
       
   407         {
       
   408         myTime = iRefreshTime / 4 ;
       
   409         }
       
   410     // Minun value is few seconds.
       
   411     return ( myTime > KMinorDelay ? myTime : KMinorDelay );
       
   412     }
       
   413 
       
   414 // -----------------------------------------------------------------------------
       
   415 // CSimpleRequest::RetryExpiryTime
       
   416 // -----------------------------------------------------------------------------
       
   417 TInt CSimpleRequest::RetryExpiryTime()
       
   418     {
       
   419     // Expiry for retry in error cases, should be calculated at the same time as
       
   420     // retry time above.
       
   421     TInt myTime(0);
       
   422 
       
   423     if ( iRefreshTime > KRefreshLimit )
       
   424         {
       
   425         myTime = KRefreshBefore;
       
   426         }
       
   427     else
       
   428         {
       
   429         myTime = iRefreshTime / 2 ;
       
   430         }
       
   431 
       
   432     return ( myTime > KMinorExpiry ? myTime : KMinorExpiry );
       
   433     }
       
   434 
       
   435 // -----------------------------------------------------------------------------
       
   436 // CSimpleRequest::SetETag
       
   437 // -----------------------------------------------------------------------------
       
   438 void CSimpleRequest::SetETag( HBufC8* aTag )
       
   439     {
       
   440     // ownership is transferred
       
   441     delete iETag;
       
   442     iETag = aTag;
       
   443     }
       
   444 
       
   445 // -----------------------------------------------------------------------------
       
   446 // CSimpleRequest::ETag
       
   447 // -----------------------------------------------------------------------------
       
   448 TPtrC8 CSimpleRequest::ETag() const
       
   449     {
       
   450     return iETag ? iETag->Des(): TPtrC8();
       
   451     }
       
   452 
       
   453 // -----------------------------------------------------------------------------
       
   454 // CSimpleRequest::Status
       
   455 // -----------------------------------------------------------------------------
       
   456 TUint CSimpleRequest::Status() const
       
   457     {
       
   458     return iStatus;
       
   459     }
       
   460 
       
   461 // -----------------------------------------------------------------------------
       
   462 // CSimpleRequest::SetStatus
       
   463 // -----------------------------------------------------------------------------
       
   464 void CSimpleRequest::SetStatus( TUint aVal )
       
   465     {
       
   466     iStatus = aVal;
       
   467     }
       
   468 
       
   469 // -----------------------------------------------------------------------------
       
   470 // CSimpleRequest::Dialog
       
   471 // -----------------------------------------------------------------------------
       
   472 CSIPSubscribeDialogAssoc* CSimpleRequest::Dialog( )
       
   473     {
       
   474     return iDialog;
       
   475     }
       
   476 
       
   477 // -----------------------------------------------------------------------------
       
   478 // CSimpleRequest::SetDialog
       
   479 // -----------------------------------------------------------------------------
       
   480  void CSimpleRequest::SetDialog( CSIPSubscribeDialogAssoc* aDialog )
       
   481     {
       
   482     delete iDialog;
       
   483     iDialog = NULL;
       
   484     iDialog = aDialog;
       
   485     }
       
   486 
       
   487 // -----------------------------------------------------------------------------
       
   488 // CSimpleRequest::ReqState
       
   489 // -----------------------------------------------------------------------------
       
   490 CSimpleRequest::TSimpleReqState CSimpleRequest::ReqState() const
       
   491     {
       
   492     return iState;
       
   493     }
       
   494 
       
   495 // -----------------------------------------------------------------------------
       
   496 // CSimpleRequest::SetReqState
       
   497 // -----------------------------------------------------------------------------
       
   498 void CSimpleRequest::SetReqState( CSimpleRequest::TSimpleReqState aState )
       
   499     {
       
   500 #ifdef _DEBUG
       
   501     TSimpleLogger::Log(_L("SimpleRequest: SetReqState %d->%d this=%d"),
       
   502         iState, aState,(TInt)this );
       
   503 #endif
       
   504     iState = aState;
       
   505     if ( aState == ESimpleFailed || aState == ESimpleComplete || aState == ESimpleDeleting )
       
   506         {
       
   507         iSubscriptionState = MSimpleEngineRequest::ESimpleStateTerminated;
       
   508         }        
       
   509     }
       
   510 
       
   511 // -----------------------------------------------------------------------------
       
   512 // CSimpleRequest::SetThrottleTime
       
   513 // -----------------------------------------------------------------------------
       
   514 void CSimpleRequest::SetThrottleTime( TUint aSeconds )
       
   515     {
       
   516     TTime myTime;
       
   517     myTime.HomeTime();
       
   518     myTime += TTimeIntervalSeconds( aSeconds );
       
   519     iThrottleTime = myTime;
       
   520     }
       
   521 
       
   522 // -----------------------------------------------------------------------------
       
   523 // CSimpleRequest::ThrottleTime
       
   524 // -----------------------------------------------------------------------------
       
   525 TTime CSimpleRequest::ThrottleTime( )
       
   526     {
       
   527     return iThrottleTime;
       
   528     }
       
   529 
       
   530 // -----------------------------------------------------------------------------
       
   531 // CSimpleRequest::RetryAfter
       
   532 // -----------------------------------------------------------------------------
       
   533 TUint CSimpleRequest::RetryAfter( )
       
   534     {
       
   535     return iRetryAfter;
       
   536     }
       
   537 
       
   538 // -----------------------------------------------------------------------------
       
   539 // CSimpleRequest::SetRetryAfter
       
   540 // -----------------------------------------------------------------------------
       
   541 void CSimpleRequest::SetRetryAfter( TUint aVal )
       
   542     {
       
   543     iRetryAfter = aVal;
       
   544     }
       
   545 
       
   546 // -----------------------------------------------------------------------------
       
   547 // CSimpleRequest::SetReason
       
   548 // -----------------------------------------------------------------------------
       
   549 void CSimpleRequest::SetReason( TInt aVal )
       
   550     {
       
   551     iReason = aVal;
       
   552     }
       
   553 
       
   554 // -----------------------------------------------------------------------------
       
   555 // CSimpleRequest::Reason
       
   556 // -----------------------------------------------------------------------------
       
   557 TInt CSimpleRequest::Reason( )
       
   558     {
       
   559     return iReason;
       
   560     }
       
   561 
       
   562 // -----------------------------------------------------------------------------
       
   563 // CSimpleRequest::PlusErrNotify
       
   564 // -----------------------------------------------------------------------------
       
   565 void CSimpleRequest::PlusErrCount( )
       
   566     {
       
   567     ++iErrNotify;
       
   568     }
       
   569 
       
   570 // -----------------------------------------------------------------------------
       
   571 // CSimpleRequest::ResetErrNotify
       
   572 // -----------------------------------------------------------------------------
       
   573 void CSimpleRequest::ResetErrCount( )
       
   574     {
       
   575     iErrNotify = 0;
       
   576     }
       
   577 
       
   578 // -----------------------------------------------------------------------------
       
   579 // CSimpleRequest::ErrNotify
       
   580 // -----------------------------------------------------------------------------
       
   581 TInt CSimpleRequest::ErrCount( )
       
   582     {
       
   583     return iErrNotify;
       
   584     }
       
   585 
       
   586 // -----------------------------------------------------------------------------
       
   587 // CSimpleRequest::PendingState
       
   588 // -----------------------------------------------------------------------------
       
   589 CSimpleRequest::TSimplePendingSubState CSimpleRequest::PendingState( )
       
   590     {
       
   591     return iPendingState;
       
   592     }
       
   593     
       
   594 // -----------------------------------------------------------------------------
       
   595 // CSimpleRequest::AddPendingState
       
   596 // -----------------------------------------------------------------------------
       
   597 void CSimpleRequest::AddPendingState( CSimpleRequest::TSimplePendingSubState aVal )
       
   598     {   
       
   599     if (( aVal == EPendingModify && iPendingState == EPendingRefresh ) ||
       
   600         ( aVal == EPendingRefresh && iPendingState == EPendingModify ))
       
   601         {
       
   602         SetPendingState( EPendingModifyAndRefresh );
       
   603         }
       
   604     else if ( aVal == EPendingModify && iPendingState == ENoPending )
       
   605         {
       
   606         SetPendingState( EPendingModify );
       
   607         }   
       
   608     else if ( aVal == EPendingRefresh && iPendingState == ENoPending )
       
   609         {
       
   610         SetPendingState( EPendingRefresh );
       
   611         }                          
       
   612     }    
       
   613 
       
   614 // -----------------------------------------------------------------------------
       
   615 // CSimpleRequest::SetPendingState
       
   616 // -----------------------------------------------------------------------------
       
   617 void CSimpleRequest::SetPendingState( CSimpleRequest::TSimplePendingSubState aVal )
       
   618     {
       
   619 #ifdef _DEBUG
       
   620     TSimpleLogger::Log(_L("SimpleRequest: iPendingState=%d"), aVal );
       
   621 #endif    
       
   622     iPendingState = aVal;
       
   623     }
       
   624 
       
   625 // -----------------------------------------------------------------------------
       
   626 // CSimpleRequest::Data
       
   627 // -----------------------------------------------------------------------------
       
   628 TPtrC8 CSimpleRequest::Data() const
       
   629     {
       
   630     return iData ? iData->Des() : TPtrC8();
       
   631     }
       
   632 
       
   633 // -----------------------------------------------------------------------------
       
   634 // CSimpleRequest::SetRecipientL
       
   635 // -----------------------------------------------------------------------------
       
   636 void CSimpleRequest::SetRecipientL( const TDesC8& aRecipientId )
       
   637     {
       
   638     delete iRecipientId;
       
   639     iRecipientId = NULL;
       
   640     iRecipientId = aRecipientId.AllocL();
       
   641     }
       
   642 
       
   643 // -----------------------------------------------------------------------------
       
   644 // CSimpleRequest::RecipientL
       
   645 // -----------------------------------------------------------------------------
       
   646 TPtrC8 CSimpleRequest::RecipientL() const
       
   647     {
       
   648     return iRecipientId ? iRecipientId->Des() : TPtrC8();
       
   649     }
       
   650 
       
   651 // -----------------------------------------------------------------------------
       
   652 // CSimpleRequest::SetDataL
       
   653 // -----------------------------------------------------------------------------
       
   654 void CSimpleRequest::SetDataL( const TDesC8& aData )
       
   655     {
       
   656     delete iData;
       
   657     iData = NULL;
       
   658     iData = aData.AllocL();
       
   659     }
       
   660     
       
   661 // -----------------------------------------------------------------------------
       
   662 // CSimpleRequest::GivenETag
       
   663 // -----------------------------------------------------------------------------
       
   664 TBool CSimpleRequest::GivenETag() const
       
   665     {
       
   666     return iGivenETag;
       
   667     }
       
   668 
       
   669 // -----------------------------------------------------------------------------
       
   670 // CSimpleRequest::SetGivenETag
       
   671 // -----------------------------------------------------------------------------
       
   672 void CSimpleRequest::SetGivenETag( TBool aVal )
       
   673     {
       
   674     iGivenETag = aVal;
       
   675     }    
       
   676     
       
   677 // ----------------------------------------------------------
       
   678 // CSimpleRequest::RequestContentType
       
   679 // ----------------------------------------------------------
       
   680 //
       
   681 TPtrC8 CSimpleRequest::RequestContentType()
       
   682     {
       
   683     return iRequestContentType ? iRequestContentType->Des() : TPtrC8();
       
   684     }
       
   685     
       
   686 // ----------------------------------------------------------
       
   687 // CSimpleRequest::SetRequestContentTypeL
       
   688 // ----------------------------------------------------------
       
   689 //
       
   690 void CSimpleRequest::SetRequestContentTypeL( const TDesC8& aData )
       
   691     {
       
   692     delete iRequestContentType;
       
   693     iRequestContentType = NULL;
       
   694     iRequestContentType = aData.AllocL(); 
       
   695     }
       
   696     
       
   697 // ----------------------------------------------------------
       
   698 // CSimpleRequest::SipSubscriptionState
       
   699 // ----------------------------------------------------------
       
   700 //
       
   701 MSimpleEngineRequest::TSimpleSipSubscriptionState CSimpleRequest::SipSubscriptionState()
       
   702     {
       
   703     return iSubscriptionState; 
       
   704     }
       
   705 
       
   706 // -----------------------------------------------------------------------------
       
   707 // CSimpleRequest::DoCompleteSubscription
       
   708 // -----------------------------------------------------------------------------
       
   709 void CSimpleRequest::DoCompleteSubscription( TInt aStatus )
       
   710     {
       
   711 #ifdef _DEBUG
       
   712     TSimpleLogger::Log(_L("SimpleRequest: DoCompleteSubscription %d"), aStatus);
       
   713 #endif
       
   714 
       
   715     // This is a part of the the state machine for subscriptions.
       
   716     // Mainly those cases that call API callback
       
   717 
       
   718     TSimpleReqState orig = iState;
       
   719 
       
   720     // Stop expiry timer always except a stop request is a special case, because of then
       
   721     // both 200 and Notify are required, or an error code alone.
       
   722     if ( orig != ESimpleStopping )
       
   723         {
       
   724         StopExpiryTimer();        
       
   725         }
       
   726     // Stop refresh timer used for garbage collection
       
   727     if ( orig != ESimpleRunningInit )
       
   728         {
       
   729         StopRefreshTimer();
       
   730         }
       
   731 
       
   732     if ( orig == ESimpleRunningInit )
       
   733         {
       
   734         if ( aStatus == KErrNone || aStatus == KSimpleErrPending )
       
   735             {
       
   736             if ( iExpires )
       
   737                 {
       
   738                 // OK response [ expires != 0 ]
       
   739                 if ( aStatus == KSimpleErrPending )
       
   740                     {
       
   741                     iSubscriptionState = MSimpleEngineRequest::ESimpleStatePending;
       
   742                     }
       
   743                 SetReqState( ESimpleActiveSubs );
       
   744                 }
       
   745             else
       
   746                 {
       
   747                 // OK response [ expires == 0 ]
       
   748                 SetReqState( ESimpleComplete );
       
   749                 }
       
   750             }
       
   751         else
       
   752             {
       
   753             // error
       
   754             SetReqState( ESimpleFailed );
       
   755             }
       
   756          // Complete API callback always in ESimpleRunningInit
       
   757         iReq.Complete( aStatus );
       
   758         }
       
   759     else if ( orig == ESimpleActiveSubs )
       
   760         {
       
   761         // This happens if refresh has failed without response notify
       
   762         TUint retryTime = RetryTime();
       
   763         // If too long interval in the retry-after header then return an error
       
   764         if ( retryTime > KRetryBefore )
       
   765             {
       
   766             SetReqState( ESimpleFailed );             
       
   767             iReq.Complete( KErrCompletion );
       
   768             return;
       
   769             }
       
   770         SetReqState( ESimpleReTry );          
       
   771         StartRefreshTimer( retryTime );
       
   772         }
       
   773     else if ( orig == ESimpleStopping )
       
   774         {
       
   775         // Stop expiry timer always except a stop request is a special case, because of then
       
   776         // both 200 and Notify are required, or an error code alone.        
       
   777         ++iRespCount;
       
   778         if (( aStatus != KErrNone && aStatus != KSimpleErrPending ) ||
       
   779             ( iRespCount == 2 ) )
       
   780             {
       
   781             SetReqState( ESimpleComplete );  
       
   782             StopExpiryTimer();                       
       
   783             }
       
   784         iReq.Complete( aStatus );
       
   785         }
       
   786     else if ( orig == ESimpleDialogReCre && aStatus == KErrNone )
       
   787         {
       
   788         // OK resp
       
   789         SetReqState( ESimpleActiveSubs );
       
   790         }
       
   791     else
       
   792         {
       
   793         // expires or stop / callback
       
   794         // error / callback
       
   795         // Expires or stop /callbc, respectively
       
   796         SetReqState( ESimpleFailed );
       
   797         iReq.Complete( aStatus );
       
   798         }
       
   799     }
       
   800 
       
   801 // -----------------------------------------------------------------------------
       
   802 // CSimpleRequest::DoCompleteNotification
       
   803 // -----------------------------------------------------------------------------
       
   804 void CSimpleRequest::DoCompleteNotification( TInt aStatus )
       
   805     {
       
   806 #ifdef _DEBUG
       
   807     TSimpleLogger::Log(_L("SimpleRequest: DoCompleteNotification %d"), aStatus);
       
   808 #endif
       
   809 
       
   810     // This is a part of the the state machine for subscriptions.
       
   811     // Mainly those cases that call API callback
       
   812 
       
   813     TSimpleReqState orig = iState;
       
   814 
       
   815     if ( aStatus == KErrNone || aStatus == KSimpleErrPending )
       
   816         {
       
   817         if ( KSimpleErrPending == aStatus )
       
   818             {
       
   819             iSubscriptionState = MSimpleEngineRequest::ESimpleStatePending;
       
   820             }
       
   821         else
       
   822             {
       
   823             iSubscriptionState = MSimpleEngineRequest::ESimpleStateActive;             
       
   824             }    
       
   825            
       
   826         if ( orig == ESimpleStopping && aStatus != KErrNone )
       
   827             {
       
   828             // A stop request is a special case, because of then
       
   829             // both 200 and Notify are required, or an error code alone.             
       
   830             ++iRespCount;
       
   831             if ( iRespCount == 2 )
       
   832                 {
       
   833                 SetReqState( ESimpleComplete );  
       
   834                 StopExpiryTimer();                       
       
   835                 }
       
   836             }
       
   837                     
       
   838         // Notification without error does not change the state,
       
   839         // just pass the notification thru to the API
       
   840         iReq.Complete( aStatus );
       
   841         return;
       
   842         }
       
   843 
       
   844     if ( orig  == ESimpleActiveSubs )
       
   845         {
       
   846         // Ensure that Dialog refreshing will be stopped now.        
       
   847         SetDialog( NULL );
       
   848         if ( iReq.IsRefresh() && aStatus == KSimpleErrTemporary )
       
   849             {
       
   850             // terminated [ refresh ]
       
   851             StopRefreshTimer();
       
   852             TUint retryTime = RetryTime();
       
   853             // If too long interval in the retry-after header then return an error
       
   854             if ( retryTime > KRetryBefore )
       
   855                 {                                 
       
   856                 SetReqState( ESimpleFailed );
       
   857                 iReq.Complete( KErrCompletion );
       
   858                 return;
       
   859                 }
       
   860             // Do not send the notification to the client API now, but
       
   861             // go to retry-state and retry later dialog re-creation.
       
   862             SetReqState( ESimpleReTry );
       
   863             StartRefreshTimer( retryTime );
       
   864             }
       
   865         else
       
   866             {
       
   867             // Expires[ no refresh ]
       
   868             // error [ no refresh ]
       
   869             // Timer may stop the request if not refresh.
       
   870             SetReqState( (aStatus==KErrTimedOut || aStatus==KErrCompletion) ?
       
   871                 ESimpleComplete : ESimpleFailed );                 
       
   872             // Complete API callback
       
   873             iReq.Complete( aStatus );
       
   874             }
       
   875         }
       
   876     else
       
   877         {         
       
   878         iReq.Complete( aStatus );
       
   879         }
       
   880     }
       
   881 
       
   882 // -----------------------------------------------------------------------------
       
   883 // CSimpleRequest::DoCompletePublication
       
   884 // -----------------------------------------------------------------------------
       
   885 void CSimpleRequest::DoCompletePublication( TInt aStatus )
       
   886     {
       
   887 #ifdef _DEBUG
       
   888     TSimpleLogger::Log(_L("SimpleRequest: DoCompletePublication %d"), aStatus);
       
   889 #endif
       
   890 
       
   891     // This is a part of the the state machine for publications.
       
   892     // Mainly those cases that call API callback
       
   893     
       
   894     // SIP error code 412, RFC3903
       
   895     const TUint KMySip412 = 412;        
       
   896     
       
   897     TSimpleReqState orig = iState;
       
   898     TSimplePendingSubState nextSub = ENoPending;
       
   899     
       
   900     // Set ETag that's received from network or reset 
       
   901     // when an error has taken a place. If it fails, it is not very serious, 
       
   902     // and it is very rare OOM situation.
       
   903     TRAP_IGNORE( iReq.SetETagL( ETag() ));    
       
   904 
       
   905     // Stop refresh timer and start only when needed.
       
   906     if ( orig != ESimplePending )
       
   907         {                
       
   908         StopRefreshTimer();
       
   909         }
       
   910 
       
   911     if ( orig == ESimpleRunningInit )
       
   912         {
       
   913         // stop expiry timer
       
   914         StopExpiryTimer();
       
   915         if ( aStatus == KErrNone )
       
   916             {
       
   917             // OK response
       
   918             SetReqState( ESimpleActive );
       
   919             // Ensure API callback when terminated
       
   920             StartRefreshTimer();
       
   921             }
       
   922         else
       
   923             {
       
   924             // error
       
   925             SetReqState( ESimpleFailed );
       
   926             }
       
   927          // Complete API callback always in ESimpleRunningInit
       
   928         iReq.Complete( aStatus );
       
   929         }
       
   930     else if ( orig == ESimpleRunning )
       
   931         {
       
   932         TBool isModify = Request().RequestType() == MSimpleEngineRequest::EPublishModify ? ETrue : EFalse;
       
   933         // Handle pending/running modifify request situation first
       
   934         if ( isModify )
       
   935             {
       
   936             SetReqState( ESimpleActive );
       
   937             // Check SIP status and decide whether publication is terminated or
       
   938             // the modify request failed only.
       
   939             if ( PendingState() != ENoPending )
       
   940                 {
       
   941                 // The previous refresh request is completed and the next one is the
       
   942                 // pending modify request.
       
   943                 if ( aStatus )
       
   944                     {
       
   945                     // error[ callback ]
       
   946                     // terminate the publication
       
   947                     // stop expiry timer
       
   948                     StopExpiryTimer();                    
       
   949                     iReq.Complete( KErrCompletion );
       
   950                     SetReqState( ESimpleFailed );
       
   951                     }
       
   952                 else
       
   953                     {
       
   954                     StartRefreshTimer();
       
   955                     // Send modification request
       
   956                     TInt errx = iEngine.DoSendPendingPublish( *this );
       
   957                     if ( errx )
       
   958                         {
       
   959                         // Modify request failed only
       
   960                         // stop expiry timer
       
   961                         StopExpiryTimer();
       
   962                         iReq.Complete( errx );
       
   963                         SetReqState( ESimpleActive );
       
   964                         }
       
   965                     else
       
   966                         {
       
   967                         // Just wait modify response, do not complete API request.
       
   968                         // Do not stop or restart expiry timer
       
   969                         }
       
   970                     }
       
   971                 } // pending
       
   972             else
       
   973                 {
       
   974                 // This is the actual modify request response.
       
   975                 TUint sipStatus = Status();
       
   976                 // check if not 412, see RFC3903
       
   977                 if ( ( !aStatus || aStatus == KSimpleErrTemporary ) && sipStatus != KMySip412 )
       
   978                     {
       
   979                     // Modify failed only
       
   980                     StartRefreshTimer();
       
   981                     // Complete modification in API callback
       
   982                     iReq.Complete( aStatus );
       
   983                     SetReqState( ESimpleActive );
       
   984                     }
       
   985                 else
       
   986                     {
       
   987                     // The whole publication is terminated
       
   988                     iReq.Complete( KErrCompletion );
       
   989                     SetReqState( ESimpleFailed );
       
   990                     }
       
   991                 // stop expiry timer
       
   992                 StopExpiryTimer();
       
   993                 } // not pending
       
   994             } // modify
       
   995         else
       
   996             {
       
   997             // stop expiry timer
       
   998             StopExpiryTimer();
       
   999             // re-freshing publication
       
  1000             if ( aStatus == KErrNone )
       
  1001                 {
       
  1002                 StartRefreshTimer();
       
  1003                 SetReqState( ESimpleActive );
       
  1004                 // Complete the request for ETag observers only
       
  1005                 iReq.SetResponseMethod( MSimpleEngineRequest::EStatusETag );                
       
  1006                 }
       
  1007             else
       
  1008                 {
       
  1009                 // error, no recovery
       
  1010                 SetReqState( ESimpleFailed );                
       
  1011                 iReq.Complete( aStatus );
       
  1012                 }
       
  1013             }
       
  1014         }
       
  1015     else if ( orig  == ESimpleStopping )
       
  1016         {
       
  1017         // stop expiry timer
       
  1018         StopExpiryTimer();
       
  1019         // Any kind of response is OK for stopping,
       
  1020         // either timeout or OK response except with given ETag the real SIP response
       
  1021         // is sent to the client.
       
  1022         SetReqState( ESimpleComplete );
       
  1023         TInt retVal = GivenETag() ? aStatus : KErrNone;
       
  1024         iReq.Complete( retVal );
       
  1025         }
       
  1026     else if ( orig == ESimplePending && 
       
  1027              ( iPendingState==EPendingModify || iPendingState==EPendingModifyAndRefresh ) &&
       
  1028              aStatus != KErrCompletion )
       
  1029         {
       
  1030         // Check if just modify terminates or the entire publication is terminated
       
  1031         // stop expiry timer
       
  1032         StopExpiryTimer();
       
  1033         // Modify failed, automatic refresh continues
       
  1034         // Complete modification in API callback
       
  1035         iReq.Complete( aStatus );
       
  1036         SetReqState( ESimpleActive );
       
  1037         if ( iPendingState == EPendingModifyAndRefresh && aStatus )
       
  1038             {
       
  1039             // The publication may still be alive but automatic refresh is pending
       
  1040             SetReqState( ESimplePending );            
       
  1041             nextSub = EPendingRefresh;
       
  1042             }
       
  1043         }        
       
  1044     else // odds and ends like time-out
       
  1045         {
       
  1046         // stop expiry timer
       
  1047         StopExpiryTimer();
       
  1048         SetReqState( ESimpleFailed );        
       
  1049         iReq.Complete( aStatus );
       
  1050         }
       
  1051     // Reset the request body data
       
  1052     delete iData;
       
  1053     iData = NULL;
       
  1054     // Reset pendig modify request
       
  1055     SetPendingState( nextSub );
       
  1056     }