simpleengine/siputils/src/simplesipconnectionobserver.cpp
changeset 0 c8caa15ef882
child 17 2669f8761a99
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 connection
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 #include <sipconnectionobserver.h>
       
    23 #include <sipmessageelements.h>
       
    24 #include <sipresponseelements.h>
       
    25 #include <sipregistrationbinding.h>
       
    26 #include <sipconnection.h>
       
    27 #include <siprefresh.h>
       
    28 #include <sipdialog.h>
       
    29 #include <sipdialogassocbase.h>
       
    30 #include <sipsubscribedialogassoc.h>
       
    31 #include <sipstrings.h>
       
    32 #include <sipstrconsts.h>
       
    33 #include <sipclienttransaction.h>
       
    34 #include <sipservertransaction.h>
       
    35 #include <siprequestelements.h>
       
    36 
       
    37 #include <sipretryafterheader.h>
       
    38 #include <sipextensionheader.h>
       
    39 #include <sipcontenttypeheader.h>
       
    40 
       
    41 #include <siperr.h>
       
    42 #include <sipaddress.h>
       
    43 #include <sipfromheader.h>
       
    44 
       
    45 #include "simplecommon.h"
       
    46 #include "simplesipconnectionobserver.h"
       
    47 #include "simplesipconncallback.h"
       
    48 #include "simplerequest.h"
       
    49 #include "simpleerrors.h"
       
    50 
       
    51 #ifdef _DEBUG
       
    52 #include "simpledebugutils.h"
       
    53 #endif
       
    54 
       
    55 // SIP response Call/Transaction does not exists
       
    56 const TUint  KSimple481 = 481;
       
    57 
       
    58 _LIT8 ( KSimpleBoundary, "boundary" );
       
    59 _LIT8 ( KSimpleStart, "start");
       
    60 _LIT8 ( KAt, "@" );
       
    61 
       
    62 #ifdef _DEBUG
       
    63 #include "simpledebugutils.h"
       
    64 #ifdef __LOCAL_MODE
       
    65 //  INTERNAL TEST SUITE
       
    66 #include "simplelocalmodeutils.h"
       
    67 #endif
       
    68 #endif
       
    69 
       
    70 // ============================ MEMBER FUNCTIONS ===============================
       
    71 
       
    72 
       
    73 // -----------------------------------------------------------------------------
       
    74 // CSimpleSipConnectionObserver::CSimpleSipConnectionObserver
       
    75 // C++ default constructor can NOT contain any code, that
       
    76 // might leave.
       
    77 // -----------------------------------------------------------------------------
       
    78 //
       
    79 CSimpleSipConnectionObserver::CSimpleSipConnectionObserver(
       
    80     MSimpleSipConnCallback& aCallback )
       
    81     : iCallback( aCallback )
       
    82     {
       
    83     }
       
    84 
       
    85 // -----------------------------------------------------------------------------
       
    86 // CSimpleSipConnectionObserver::~CSimpleSipConnectionObserver
       
    87 // -----------------------------------------------------------------------------
       
    88 //
       
    89 CSimpleSipConnectionObserver::~CSimpleSipConnectionObserver()
       
    90     {
       
    91 #ifdef _DEBUG
       
    92     TSimpleLogger::Log(_L("SipConnectionObserver: DESTRUCTOR this=%d"), (TInt)this);
       
    93 #ifdef __LOCAL_MODE
       
    94     /**
       
    95      * INTERNAL TEST SUITE
       
    96      */
       
    97     delete iLocalModeUtils;
       
    98 #endif        
       
    99 #endif
       
   100     }
       
   101 
       
   102 // -----------------------------------------------------------------------------
       
   103 // CSimpleSipConnectionObserver::NewL
       
   104 // -----------------------------------------------------------------------------
       
   105 //
       
   106 CSimpleSipConnectionObserver* CSimpleSipConnectionObserver::NewL(
       
   107     MSimpleSipConnCallback& aCallback )
       
   108     {
       
   109     CSimpleSipConnectionObserver* self = new (ELeave) CSimpleSipConnectionObserver( aCallback );
       
   110     CleanupStack::PushL( self );
       
   111     self->ConstructL();
       
   112     CleanupStack::Pop( self );
       
   113 #ifdef _DEBUG
       
   114     TSimpleLogger::Log(_L("SipConnectionObserver: NewL this=%d"), (TInt)self);
       
   115 #endif
       
   116     return self;
       
   117     }
       
   118 
       
   119 // -----------------------------------------------------------------------------
       
   120 // CSimpleSipConnectionObserver::ConstructL
       
   121 // -----------------------------------------------------------------------------
       
   122 //
       
   123 void CSimpleSipConnectionObserver::ConstructL()
       
   124     {
       
   125 #ifdef _DEBUG
       
   126 #ifdef __LOCAL_MODE
       
   127     /**
       
   128      * INTERNAL TEST SUITE
       
   129      */
       
   130     iLocalModeUtils = CSimpleLocalModeUtils::NewL( );
       
   131     iLocalModeUtils->SubscribeNetworkStateL( this );
       
   132 #endif
       
   133 #endif
       
   134     }
       
   135 
       
   136 // -----------------------------------------------------------------------------
       
   137 // CSimpleSipConnectionObserver::ConnectionStateChanged
       
   138 // -----------------------------------------------------------------------------
       
   139 //
       
   140 void CSimpleSipConnectionObserver::ConnectionStateChanged(
       
   141     CSIPConnection::TState aState )
       
   142     {
       
   143 #ifdef _DEBUG
       
   144     TSimpleLogger::Log(_L("SipConnectionObserver: ConnectionStateChanged state=%d sip=%d"), aState );
       
   145 #endif  
       
   146     ConnectionStateChanged2( aState, KErrNone );
       
   147     }
       
   148     
       
   149 // -----------------------------------------------------------------------------
       
   150 // CSimpleSipConnectionObserver::ProfileStateChanged
       
   151 // -----------------------------------------------------------------------------
       
   152 //
       
   153 void CSimpleSipConnectionObserver::ProfileStateChanged(
       
   154     CSIPConnection::TState aState, TInt aSipError )
       
   155     {
       
   156 #ifdef _DEBUG
       
   157     TSimpleLogger::Log(_L("SipConnectionObserver: ProfileStateChanged state=%d sip=%d"), aState );
       
   158 #endif
       
   159       ConnectionStateChanged2( aState, aSipError );      
       
   160     }     
       
   161     
       
   162 // -----------------------------------------------------------------------------
       
   163 // CSimpleSipConnectionObserver::ProfileUpdated
       
   164 // -----------------------------------------------------------------------------
       
   165 //
       
   166 void CSimpleSipConnectionObserver::ProfileUpdated()
       
   167     {
       
   168 #ifdef _DEBUG
       
   169     TSimpleLogger::Log(_L("SipConnectionObserver: ProfileUpdated"));
       
   170 #endif
       
   171     iCallback.ConnectionChanged();
       
   172     }
       
   173 
       
   174 // -----------------------------------------------------------------------------
       
   175 // CSimpleSipConnectionObserver::ConnectionStateChanged2
       
   176 // -----------------------------------------------------------------------------
       
   177 //
       
   178 void CSimpleSipConnectionObserver::ConnectionStateChanged2(
       
   179     CSIPConnection::TState aState, TInt aSipError )
       
   180     {
       
   181     TInt retErr = aSipError ? ConvertSipCode( aSipError, EFalse, EFalse ) : KErrNone;
       
   182     switch ( aState )
       
   183       {
       
   184       // Here is a logic, how to tell active state upward after waiting both
       
   185       // connection and profile to be ok.
       
   186       case CSIPConnection::EInit:
       
   187           iCallback.ConnectionStateChange( ESimpleSipIdle, retErr );
       
   188           break;
       
   189       case CSIPConnection::EActive:                      
       
   190          iCallback.ConnectionStateChange( ESimpleSipActive, retErr );
       
   191           break;
       
   192       case CSIPConnection::ESuspended:
       
   193           iCallback.ConnectionStateChange( ESimpleSipSuspend, retErr);
       
   194           break;
       
   195       case CSIPConnection::EInactive:
       
   196           iCallback.ConnectionStateChange( ESimpleSipInactive, retErr );
       
   197           break;
       
   198       case CSIPConnection::EUnavailable:
       
   199           iCallback.ConnectionStateChange( ESimpleSipUnavailable, retErr );
       
   200           break;
       
   201       default:
       
   202           break;
       
   203       }; 
       
   204     }    
       
   205 
       
   206 // -----------------------------------------------------------------------------
       
   207 // CSimpleSipConnectionObserver::IncomingResponse
       
   208 // -----------------------------------------------------------------------------
       
   209 //
       
   210 void CSimpleSipConnectionObserver::IncomingResponse (
       
   211     CSIPClientTransaction& /*aTransaction*/,
       
   212     CSIPRegistrationBinding& /*aRegistration*/)
       
   213     {
       
   214 #ifdef _DEBUG
       
   215     TSimpleLogger::Log(_L("SipConnectionObserver: IncomingResponse" ));
       
   216 #endif
       
   217     }
       
   218 
       
   219 // -----------------------------------------------------------------------------
       
   220 // CSimpleSipConnectionObserver::ErrorOccured
       
   221 // -----------------------------------------------------------------------------
       
   222 //
       
   223 void CSimpleSipConnectionObserver::ErrorOccured (
       
   224     TInt aError,
       
   225     CSIPClientTransaction& /*aTransaction*/,
       
   226     CSIPRegistrationBinding& /*aRegistration*/)
       
   227     {
       
   228     iError = aError;
       
   229 #ifdef _DEBUG
       
   230     TSimpleLogger::Log(_L("SipConnectionObserver: ErrorOccured 1 err=%d"), aError );
       
   231 #endif
       
   232     }
       
   233 
       
   234 // -----------------------------------------------------------------------------
       
   235 // CSimpleSipConnectionObserver::ErrorOccured
       
   236 // -----------------------------------------------------------------------------
       
   237 //
       
   238 void CSimpleSipConnectionObserver::ErrorOccured (
       
   239     TInt aError,
       
   240     CSIPRegistrationBinding& /*aRegistration*/)
       
   241     {
       
   242     iError = aError;
       
   243 #ifdef _DEBUG
       
   244     TSimpleLogger::Log(_L("SipConnectionObserver: ErrorOccured 2 err=%d" ), aError);
       
   245 #endif
       
   246     }
       
   247 
       
   248 // -----------------------------------------------------------------------------
       
   249 // CSimpleSipConnectionObserver::ErrorOccured
       
   250 // This is mainly for Publish errors, no dialog.
       
   251 // -----------------------------------------------------------------------------
       
   252 //
       
   253 void CSimpleSipConnectionObserver::ErrorOccured (
       
   254     TInt aError,
       
   255     CSIPTransactionBase& aTransaction )
       
   256     {
       
   257     iError = aError;
       
   258 #ifdef _DEBUG
       
   259     TSimpleLogger::Log(_L("SipConnectionObserver: ErrorOccured 3 err=%d" ), aError);
       
   260 #endif
       
   261     if ( aTransaction.IsSIPClientTransaction() )
       
   262         {
       
   263         CSIPTransactionBase::TState sipState = CSIPTransactionBase::ETrying;
       
   264         TRAP_IGNORE( sipState = aTransaction.StateL() );
       
   265         CSimpleRequest* r = iCallback.GetRequest(
       
   266             STATIC_CAST( CSIPClientTransaction&, aTransaction) );
       
   267         if ( r && sipState == CSIPTransactionBase::ETerminated )
       
   268             {
       
   269             TInt retCode = aError == KErrSIPForbidden ? KErrAccessDenied : KErrCommsBreak;
       
   270             r->SetStatus( 0 );
       
   271             // update response method
       
   272             r->Request().SetResponseMethod( MSimpleEngineRequest::EUnknownResponse );
       
   273             r->Complete( retCode );
       
   274             }
       
   275         else
       
   276             {
       
   277             // nothing to do
       
   278             }
       
   279         }
       
   280     else
       
   281         {
       
   282         // nothing to do
       
   283         }
       
   284     }
       
   285 
       
   286 // -----------------------------------------------------------------------------
       
   287 // CSimpleSipConnectionObserver::ErrorOccured
       
   288 // Dialog refresh has failed, a transaction has been deleted.
       
   289 // -----------------------------------------------------------------------------
       
   290 //
       
   291 void CSimpleSipConnectionObserver::ErrorOccured (
       
   292     TInt aError,
       
   293     CSIPDialogAssocBase& aDialogAssoc )
       
   294     {
       
   295     // This is called when SUBSCRIBE refresh fails with
       
   296     // an error response from a remote server.
       
   297     iError = aError;
       
   298 #ifdef _DEBUG
       
   299     TSimpleLogger::Log(_L("SipConnectionObserver: ErrorOccured 4 err=%d" ), aError );
       
   300 #endif
       
   301 
       
   302     TInt retCode = aError == KErrSIPForbidden ? KErrAccessDenied : KErrCommsBreak;
       
   303     TUint status(0);
       
   304     TUint myRefresh(0);
       
   305 
       
   306     CSIPSubscribeDialogAssoc& myDialogA = STATIC_CAST( CSIPSubscribeDialogAssoc&, aDialogAssoc );
       
   307     const CSIPDialog& myDialog = myDialogA.Dialog();
       
   308     CSimpleRequest* r = iCallback.GetdDialogRequest( myDialog );
       
   309     if ( !r )
       
   310         {
       
   311         // request not found
       
   312         return;
       
   313         }
       
   314 
       
   315     if ( aError == KErrSIPTerminatedWithResponse )
       
   316         {
       
   317         // It's subscription's response with data
       
   318         const CSIPRefresh* refresh = myDialogA.SIPRefresh();
       
   319         if ( refresh  )
       
   320             {
       
   321             // This instance is not the initial transaction but
       
   322             // the refresh transaction instance.
       
   323             // Ownership is not transferred. May be NULL.
       
   324             const CSIPClientTransaction* trans = refresh->SIPTransaction();
       
   325             if ( trans )
       
   326                 {
       
   327                 // ownership isn't transferred.
       
   328                 // Elems must exist with KErrSIPTerminatedWithResponse
       
   329                 const CSIPResponseElements* elems = trans->ResponseElements();
       
   330                // Get retry-after header value
       
   331                 myRefresh = GetRetryAfter( elems );
       
   332                 // Get SIP Status
       
   333                 status = elems->StatusCode();
       
   334                 if ( status >= KSimpleOK )
       
   335                     {
       
   336                     retCode = ConvertSipCode( status, myRefresh ? ETrue: EFalse, EFalse );
       
   337                     }
       
   338                 }
       
   339             }
       
   340         }
       
   341 
       
   342     // Update the request entity and complete it.
       
   343     r->SetRetryAfter( myRefresh );
       
   344     r->SetStatus( status );
       
   345     r->Request().SetResponseMethod( MSimpleEngineRequest::EUnknownResponse );
       
   346     r->Complete( retCode );
       
   347     }
       
   348 
       
   349 // -----------------------------------------------------------------------------
       
   350 // CSimpleSipConnectionObserver::ErrorOccured
       
   351 // Sending of either request or response failed, dialog specific.
       
   352 // -----------------------------------------------------------------------------
       
   353 //
       
   354 void CSimpleSipConnectionObserver::ErrorOccured (
       
   355     TInt aError,
       
   356     CSIPTransactionBase& aTransaction,
       
   357     CSIPDialogAssocBase& /*aDialogAssoc*/)
       
   358     {
       
   359 #ifdef _DEBUG
       
   360     TSimpleLogger::Log(_L("SipConnectionObserver: ErrorOccured 5 err=%d" ), aError);
       
   361 #endif
       
   362 
       
   363     TInt retCode = aError == KErrSIPForbidden ? KErrAccessDenied : KErrCommsBreak;
       
   364     TUint status = 0;
       
   365 
       
   366     if ( aTransaction.IsSIPClientTransaction() )
       
   367         {
       
   368         // This is an initial SUBSCRIBE transaction that has failed.
       
   369         CSimpleRequest* r2 = iCallback.GetRequest(
       
   370             STATIC_CAST( CSIPClientTransaction&, aTransaction )); 
       
   371         if ( !r2 )
       
   372             {
       
   373             // request not found
       
   374             return;
       
   375             }                               
       
   376         // This instance is the initial transaction.
       
   377         CSIPClientTransaction& trans = STATIC_CAST( CSIPClientTransaction&, aTransaction );
       
   378         // ownership isn't transferred.
       
   379         const CSIPResponseElements* elems = trans.ResponseElements();
       
   380         if ( elems )
       
   381             {
       
   382             status = elems->StatusCode();
       
   383             }
       
   384         // convert SIP status code
       
   385         if ( status >= KSimpleOK )
       
   386             {
       
   387             retCode = ConvertSipCode( status, EFalse, EFalse );
       
   388             }
       
   389         r2->SetStatus( status );
       
   390         // update response method
       
   391         r2->Request().SetResponseMethod( MSimpleEngineRequest::EUnknownResponse );
       
   392         r2->Complete( retCode );
       
   393         }
       
   394     else
       
   395         {
       
   396         // Server transactions are not handled.
       
   397         // An error in responding to NOTIFY request comes here.
       
   398         }
       
   399     }
       
   400 
       
   401 // -----------------------------------------------------------------------------
       
   402 // CSimpleSipConnectionObserver::ErrorOccured
       
   403 // This is not really needed because of engine does not use standalone CSIPRefesh
       
   404 // requests.
       
   405 // -----------------------------------------------------------------------------
       
   406 //
       
   407 void CSimpleSipConnectionObserver::ErrorOccured (
       
   408     TInt /*aError*/,
       
   409     CSIPRefresh& /*aRefresh*/)
       
   410     {
       
   411 #ifdef _DEBUG
       
   412     TSimpleLogger::Log(_L("SipConnectionObserver: ErrorOccured 6" ));
       
   413 #endif
       
   414     }
       
   415 
       
   416 // -----------------------------------------------------------------------------
       
   417 // A SIP request outside a dialog has been received from the network.
       
   418 // CSimpleSipConnectionObserver::IncomingRequest
       
   419 // -----------------------------------------------------------------------------
       
   420 //
       
   421 void CSimpleSipConnectionObserver::IncomingRequest(
       
   422     CSIPServerTransaction* aTransaction )
       
   423     {
       
   424 #ifdef _DEBUG
       
   425     TSimpleLogger::Log(
       
   426         _L("CSimpleSipConnectionObserver::IncomingRequest" ) );
       
   427 #endif
       
   428     
       
   429     TRAP_IGNORE( DoIncomingRequestL( aTransaction ) );
       
   430     }
       
   431 
       
   432 // -----------------------------------------------------------------------------
       
   433 // CSimpleSipConnectionObserver::IncomingRequest
       
   434 // Dialog specific request from server..
       
   435 // -----------------------------------------------------------------------------
       
   436 //
       
   437 void CSimpleSipConnectionObserver::IncomingRequest (
       
   438     CSIPServerTransaction* aTransaction,
       
   439     CSIPDialog& aDialog )
       
   440     {
       
   441 #ifdef _DEBUG
       
   442     TSimpleLogger::Log(_L("SipConnectionObserver: IncomingRequest (dialog)" ));
       
   443 #endif
       
   444 
       
   445     TRAP_IGNORE( DoIncomingRequestL( aTransaction, aDialog ) );
       
   446     }
       
   447 
       
   448 // -----------------------------------------------------------------------------
       
   449 // CSimpleSipConnectionObserver::IncomingResponse
       
   450 // -----------------------------------------------------------------------------
       
   451 //
       
   452 void CSimpleSipConnectionObserver::IncomingResponse(
       
   453     CSIPClientTransaction& aTransaction)
       
   454     {
       
   455 #ifdef _DEBUG
       
   456     TInt status = aTransaction.ResponseElements()->StatusCode();
       
   457     TSimpleLogger::Log(_L("SipConnectionObserver: IncomingResponse status=%d" ), status);
       
   458 #endif
       
   459 
       
   460     DoIncomingResponse( aTransaction );
       
   461     }
       
   462 
       
   463 // -----------------------------------------------------------------------------
       
   464 // CSimpleSipConnectionObserver::IncomingResponse
       
   465 // -----------------------------------------------------------------------------
       
   466 //
       
   467 void CSimpleSipConnectionObserver::IncomingResponse(
       
   468     CSIPClientTransaction& aTransaction,
       
   469     CSIPDialogAssocBase& aDialogAssoc)
       
   470     {
       
   471 #ifdef _DEBUG
       
   472     TInt status( KErrNone );
       
   473     status = aTransaction.ResponseElements()->StatusCode();
       
   474     TSimpleLogger::Log(_L("SipConnectionObserver: IncomingResponse (dialog) status=%d"), status);
       
   475 #endif
       
   476 
       
   477     DoIncomingResponse( aTransaction, aDialogAssoc );
       
   478     }
       
   479 
       
   480 // -----------------------------------------------------------------------------
       
   481 // CSimpleSipConnectionObserver::IncomingResponse
       
   482 // Invite not supported by SIMPLE
       
   483 // -----------------------------------------------------------------------------
       
   484 //
       
   485 void CSimpleSipConnectionObserver::IncomingResponse (
       
   486     CSIPClientTransaction& /*aTransaction*/,
       
   487     CSIPInviteDialogAssoc* /*aDialogAssoc*/)
       
   488     {
       
   489 #ifdef _DEBUG
       
   490     TSimpleLogger::Log(_L("SipConnectionObserver: IncomingResponse (invite)" ));
       
   491 #endif
       
   492     }
       
   493 
       
   494 // -----------------------------------------------------------------------------
       
   495 // CSimpleSipConnectionObserver::InviteCompleted
       
   496 // -----------------------------------------------------------------------------
       
   497 //
       
   498 void CSimpleSipConnectionObserver::InviteCompleted (
       
   499     CSIPClientTransaction& /*aTransaction*/)
       
   500     {
       
   501 #ifdef _DEBUG
       
   502     TSimpleLogger::Log(_L("SipConnectionObserver: InviteCompleted" ));
       
   503 #endif
       
   504     }
       
   505 
       
   506 // -----------------------------------------------------------------------------
       
   507 // CSimpleSipConnectionObserver::InviteCanceled
       
   508 // -----------------------------------------------------------------------------
       
   509 //
       
   510 void CSimpleSipConnectionObserver::InviteCanceled (
       
   511     CSIPServerTransaction& /*aTransaction*/)
       
   512     {
       
   513 #ifdef _DEBUG
       
   514     TSimpleLogger::Log(_L("SipConnectionObserver: InviteCanceled" ));
       
   515 #endif
       
   516     }
       
   517 
       
   518 // -----------------------------------------------------------------------------
       
   519 // CSimpleSipConnectionObserver::DoHandleSrvrReqContentL
       
   520 // -----------------------------------------------------------------------------
       
   521 //
       
   522 void CSimpleSipConnectionObserver::DoHandleSrvrReqContentL(
       
   523     const CSIPMessageElements& aElems,
       
   524     MSimpleEngineRequest& aR )
       
   525     {
       
   526     RStringF boundary = SIPStrings::Pool().OpenFStringL( KSimpleBoundary );
       
   527     CleanupClosePushL( boundary );
       
   528     RStringF start = SIPStrings::Pool().OpenFStringL( KSimpleStart );
       
   529     CleanupClosePushL( start );
       
   530     RStringF value;
       
   531 
       
   532     // ownership of typeHeader is not transferred and it may be NULL.
       
   533     const CSIPContentTypeHeader* typeHeader = aElems.ContentType();
       
   534     if ( typeHeader )
       
   535         {
       
   536         // buffer ownership is transferred
       
   537         HBufC8* buffer = typeHeader->ToTextValueL();
       
   538         aR.SetResponseContentType( buffer );
       
   539         aR.SetResponseDataL( aElems.Content() );
       
   540         // set boundary
       
   541         if ( typeHeader->HasParam( boundary ) )
       
   542             {
       
   543             value = typeHeader->ParamValue( boundary );
       
   544             aR.SetResponseBoundaryL( value.DesC() );
       
   545             }
       
   546         // set start-content-id
       
   547         if ( typeHeader->HasParam( start ) )
       
   548             {
       
   549             value = typeHeader->ParamValue( start );
       
   550             aR.SetResponseStartL( value.DesC() );
       
   551             }
       
   552 #ifdef _DEBUG
       
   553         RFs myFs;
       
   554         (void)myFs.Connect();
       
   555         TSimpleLogger::Dump( aR.ResponseData(), myFs, 1 );
       
   556         myFs.Close();
       
   557 #endif
       
   558         }
       
   559     CleanupStack::PopAndDestroy( &start );
       
   560     CleanupStack::PopAndDestroy( &boundary );
       
   561     }
       
   562 
       
   563 // -----------------------------------------------------------------------------
       
   564 // CSimpleSipConnectionObserver::DoIncomingRequestL
       
   565 // -----------------------------------------------------------------------------
       
   566 //
       
   567 void CSimpleSipConnectionObserver::DoIncomingRequestL(
       
   568     CSIPServerTransaction* aTransaction )
       
   569     {
       
   570     const CSIPRequestElements* elems = aTransaction->RequestElements();
       
   571     const CSIPContentTypeHeader* contentType = elems->MessageElements().
       
   572         ContentType();
       
   573     
       
   574     if( KSimpleMediaType() == contentType->MediaType() &&
       
   575         KSimpleMediaSubType() == contentType->MediaSubtype() )
       
   576         {
       
   577         const CSIPFromHeader* fromHeader = elems->FromHeader();
       
   578         const TDesC8& content = elems->MessageElements().Content();
       
   579         const TDesC8& user = fromHeader->SIPAddress().Uri8().Uri().
       
   580             Extract( EUriUserinfo );
       
   581         const TDesC8& host = fromHeader->SIPAddress().Uri8().Uri().
       
   582             Extract( EUriHost );
       
   583         
       
   584         CleanupStack::PushL( aTransaction ); // CS: 1
       
   585         
       
   586         HBufC8* from = HBufC8::NewLC( user.Length() + KAt().Length() +
       
   587             host.Length() ); // CS: 1
       
   588         from->Des().Copy( user );
       
   589         from->Des().Append( KAt() );
       
   590         from->Des().Append( host );
       
   591         
       
   592         CSIPResponseElements* respElem = CSIPResponseElements::NewLC( // CS: 3
       
   593             KSimpleOK, SIPStrings::StringF( SipStrConsts::EPhraseOk ) );
       
   594         
       
   595         // Use the transaction to send 200 OK
       
   596         aTransaction->SendResponseL( respElem );
       
   597         
       
   598         CleanupStack::Pop( respElem );     // CS: 2
       
   599 
       
   600         iCallback.HandleReceivedMessage( *from, content );
       
   601         CleanupStack::PopAndDestroy( from ); // CS: 1
       
   602         CleanupStack::Pop( aTransaction ); // CS: 0
       
   603         }
       
   604     
       
   605     // We no longer need aTransaction. Just delete it.
       
   606     delete aTransaction;
       
   607     aTransaction = NULL;
       
   608     }
       
   609 
       
   610 // -----------------------------------------------------------------------------
       
   611 // CSimpleSipConnectionObserver::DoIncomingRequestL
       
   612 // -----------------------------------------------------------------------------
       
   613 //
       
   614 void CSimpleSipConnectionObserver::DoIncomingRequestL (
       
   615     CSIPServerTransaction* aTransaction,
       
   616     CSIPDialog& aDialog )
       
   617     {
       
   618     // Ownership of aTransaction is transferred.
       
   619     CleanupStack::PushL( aTransaction );
       
   620 
       
   621     const CSIPRequestElements* reqE = aTransaction->RequestElements();
       
   622     TPtrC8 method = reqE->Method().DesC();
       
   623 
       
   624     // search the right request
       
   625     CSimpleRequest* req = iCallback.GetdDialogRequest( aDialog );
       
   626     if ( ! req )
       
   627         {
       
   628 #ifdef _DEBUG
       
   629         TSimpleLogger::Log(_L("SipConnectionObserver: IncomingRequest ERROR **" ));
       
   630 #endif
       
   631 
       
   632         // This is unknown response, send response 481 in order to unsubscribe the dialog.
       
   633         // See RFC3265
       
   634         CSIPResponseElements* resE = CSIPResponseElements::NewLC( KSimple481,
       
   635         SIPStrings::StringF( SipStrConsts::EPhraseCallTransactionDoesNotExist ) );
       
   636         aTransaction->SendResponseL( resE );
       
   637         // resE ownership is transferred
       
   638         CleanupStack::Pop( resE );
       
   639         CleanupStack::PopAndDestroy( aTransaction );
       
   640         return;
       
   641         }
       
   642 
       
   643     // send a response to PA in NOTIFY
       
   644     if ( aTransaction->ResponseAllowed()  )
       
   645         {
       
   646         if ( !method.CompareF( KSimpleNOTIFY ))
       
   647             {
       
   648             CSIPResponseElements* resE = CSIPResponseElements::NewLC( KSimpleOK,
       
   649             SIPStrings::StringF( SipStrConsts::EPhraseOk ) );
       
   650             aTransaction->SendResponseL( resE );
       
   651             // resE ownership is transferred
       
   652             CleanupStack::Pop( resE );
       
   653 #ifdef _DEBUG
       
   654             TSimpleLogger::Log(_L("SipConnectionObserver: response sent *" ));
       
   655 #endif
       
   656             }
       
   657         }
       
   658 
       
   659     // Fill the data of the request
       
   660     const CSIPMessageElements& elems = reqE->MessageElements();
       
   661     TRAPD( err, DoHandleSrvrReqContentL( elems, req->Request() ));
       
   662     // Update expires when necessary
       
   663     if ( !err )
       
   664         {
       
   665         // This completes the client request when needed
       
   666         TRAP( err, iCallback.HandleDialogRequestL( elems, *req, method ));
       
   667         }
       
   668 
       
   669     CleanupStack::PopAndDestroy( aTransaction );
       
   670     }
       
   671 
       
   672 // -----------------------------------------------------------------------------
       
   673 // CSimpleSipConnectionObserver::DoIncomingResponse
       
   674 // -----------------------------------------------------------------------------
       
   675 //
       
   676 void CSimpleSipConnectionObserver::DoIncomingResponse(
       
   677     CSIPClientTransaction& aTransaction)
       
   678     {
       
   679     const CSIPResponseElements* elems = aTransaction.ResponseElements();
       
   680     // elems ownership is not transferred
       
   681     TUint status = elems->StatusCode();
       
   682 
       
   683     if ( status >= KSimpleOK )
       
   684         {
       
   685         // Final response received
       
   686 
       
   687         // Search the right request
       
   688         CSimpleRequest* req = iCallback.GetRequest( aTransaction );
       
   689         
       
   690         if ( req )
       
   691             {
       
   692             if( req->Match( CSimpleRequest::EReqSendIM ) )
       
   693                 {
       
   694                 TBool isModify = MSimpleEngineRequest::ESendIM ==
       
   695                     req->Request().RequestType() ? ETrue : EFalse;
       
   696                 
       
   697                 // Get retry-after header value
       
   698                 TUint myRefresh = GetRetryAfter( elems );
       
   699                 req->SetRetryAfter( myRefresh );
       
   700                 
       
   701                 TInt retCode = ConvertSipCode( status, myRefresh ?
       
   702                     ETrue: EFalse, isModify );
       
   703                 req->SetStatus( status );
       
   704                 req->Request().SetResponseMethod(
       
   705                     MSimpleEngineRequest::EStatus );
       
   706                 TInt err( KErrNone );
       
   707                 
       
   708                 //  Complete the client request and change the request state
       
   709                 req->Complete( err ? err : retCode );
       
   710                 }
       
   711             else if ( req->Match( CSimpleRequest::EReqPublish ) )
       
   712                 {
       
   713                 TBool isModify = req->Request().RequestType() ==
       
   714                     MSimpleEngineRequest::EPublishModify ? ETrue : EFalse;
       
   715                 
       
   716                 // Get retry-after header value
       
   717                 TUint myRefresh = GetRetryAfter( elems );
       
   718                 req->SetRetryAfter( myRefresh );
       
   719                 
       
   720                 TInt retCode = ConvertSipCode( status, myRefresh ?
       
   721                     ETrue: EFalse, isModify );
       
   722                 req->SetStatus( status );
       
   723                 req->Request().SetResponseMethod(
       
   724                     MSimpleEngineRequest::EStatus );
       
   725 
       
   726                 // Make response to a client when necessary, i.e. response to
       
   727                 // the first PUBLISH.
       
   728                 // This handles STOP publish also, since it's
       
   729                 // actually a new publish request with expires=0 and ETag.
       
   730                 const CSIPMessageElements& mElems = elems->MessageElements();
       
   731                 TInt err( KErrNone );
       
   732                 TRAP( err, iCallback.HandlePublishRespL( mElems, req ) );
       
   733                 //  Complete the client request and change the request state
       
   734                 req->Complete( err ? err : retCode );
       
   735                 }
       
   736             else
       
   737                 {
       
   738                 // This is unknown response
       
   739                 #ifdef _DEBUG
       
   740                     TSimpleLogger::Log( _L("SipConnectionObserver: IncomingResponse IGNORED") );
       
   741                 #endif
       
   742                 }
       
   743             }
       
   744         else
       
   745             {
       
   746             // Request not found
       
   747             #ifdef _DEBUG
       
   748                 TSimpleLogger::Log( _L("SipConnectionObserver: IncomingResponse IGNORED") );
       
   749             #endif
       
   750             }
       
   751         }
       
   752     }
       
   753 
       
   754 // -----------------------------------------------------------------------------
       
   755 // CSimpleSipConnectionObserver::DoIncomingResponse
       
   756 // -----------------------------------------------------------------------------
       
   757 //
       
   758 void CSimpleSipConnectionObserver::DoIncomingResponse(
       
   759     CSIPClientTransaction& aTransaction,
       
   760     CSIPDialogAssocBase& /*aDialogAssoc*/)
       
   761     {
       
   762     // ownership of elems is not transferred.
       
   763     const CSIPResponseElements* elems = aTransaction.ResponseElements();
       
   764     if ( !elems )
       
   765         {
       
   766         return;
       
   767         }
       
   768     // elems ownership is not transferred
       
   769     TUint status = elems->StatusCode();          
       
   770 
       
   771     if ( status >= KSimpleOK )
       
   772         {
       
   773         // Final response received
       
   774 
       
   775         // search the right request
       
   776         CSimpleRequest* req = iCallback.GetRequest( aTransaction );
       
   777         if ( ! req )
       
   778             {
       
   779 #ifdef _DEBUG
       
   780            TSimpleLogger::Log(_L("SipConnectionObserver: Unknown response **" ));
       
   781 #endif
       
   782             // This is unknown response
       
   783             return;
       
   784             }
       
   785 
       
   786         req->SetStatus( status );
       
   787 
       
   788         // update response method
       
   789         req->Request().SetResponseMethod( MSimpleEngineRequest::EStatus );
       
   790         req->Complete( ConvertSipCode( status, EFalse, EFalse ) );
       
   791 
       
   792         }
       
   793     }
       
   794 
       
   795 // ----------------------------------------------------------
       
   796 // CSimpleSipConnectionObserver::ConvertSipCode
       
   797 // ----------------------------------------------------------
       
   798 //
       
   799 TInt CSimpleSipConnectionObserver::ConvertSipCode(
       
   800     TUint aSip, TBool aRetryAfter, TBool aPublishModify )
       
   801     {
       
   802     // The SIP status codes are converted to engine error codes
       
   803     if ( aSip < KSimpleOK )
       
   804         {
       
   805         return KErrNone;
       
   806         }
       
   807     if ( aPublishModify )
       
   808         {
       
   809         return ConvertSipModifyCode( aSip );
       
   810         }
       
   811     switch ( aSip )
       
   812         {
       
   813         case KSimpleOK: // 200
       
   814             return KErrNone;
       
   815         case KSimpleAccepted: // 202
       
   816             return KSimpleErrPending;
       
   817         case 404:  // Not Found
       
   818             return KSimpleErrNotFound;
       
   819         case 401: //  Unauthorized
       
   820         case 407: //  Proxy Authentication Required
       
   821             return KSimpleErrAuthorization;
       
   822         case 302: // Moved Temporarily
       
   823         case 408: // Request Timeout
       
   824         case 412: // Conditional Request Failed, RFC3903
       
   825         case 480: // Temporarily Unavailable
       
   826         case 481: // Call/Transaction Does Not Exist
       
   827         case 482: // Loop Detected
       
   828         case 483: // Too Many Hops
       
   829         case 486: // Busy Here
       
   830         case 487: // Request Terminated (BYE/CANCEL) ** should not happen
       
   831         case 491: // Request Pending
       
   832         case 503: // Service Unavailable
       
   833         case 504: // Server Time-out
       
   834             return KSimpleErrTemporary;
       
   835         case 413: // Request Entity Too Large
       
   836             if ( aRetryAfter )
       
   837                 {
       
   838                 return KSimpleErrTemporary;
       
   839                 }
       
   840             else
       
   841                 {
       
   842                 return KSimpleErrPermanent;
       
   843                 }
       
   844         default:
       
   845             return KSimpleErrPermanent;
       
   846         }
       
   847     }
       
   848 
       
   849 // ----------------------------------------------------------
       
   850 // CSimpleSipConnectionObserver::ConvertSipModifyCode
       
   851 // ----------------------------------------------------------
       
   852 //
       
   853 TInt CSimpleSipConnectionObserver::ConvertSipModifyCode( 
       
   854     TUint aSip )
       
   855     {
       
   856     // The SIP status codes are converted to engine error codes
       
   857     if ( aSip < KSimpleOK )
       
   858         {
       
   859         return KErrNone;
       
   860         }
       
   861     switch ( aSip )
       
   862         {
       
   863         case KSimpleOK: // 200
       
   864             return KErrNone;
       
   865         case KSimpleAccepted: // 202
       
   866             return KSimpleErrPending;
       
   867         case 404:  // Not Found
       
   868             return KSimpleErrNotFound;
       
   869         case 401: //  Unauthorized
       
   870         case 407: //  Proxy Authentication Required
       
   871             return KSimpleErrAuthorization;
       
   872         case 400: // Bad request
       
   873         case 408: // Request Time Out
       
   874         case 415: // Unsupported media type
       
   875         case 508: // Server Timed-Out
       
   876             return KSimpleErrTemporary;
       
   877         default:
       
   878             return KSimpleErrPermanent;
       
   879         }
       
   880     }
       
   881 // ----------------------------------------------------------
       
   882 // CSimpleSipConnectionObserver::GetRetryAfter
       
   883 // ----------------------------------------------------------
       
   884 //
       
   885 TUint CSimpleSipConnectionObserver::GetRetryAfter( const CSIPResponseElements* aElems )
       
   886     {
       
   887     TUint ret(0);
       
   888 
       
   889     // aElems must exist
       
   890     const CSIPMessageElements& mes = aElems->MessageElements();
       
   891 
       
   892     // Scan user headers
       
   893     const RPointerArray<CSIPHeaderBase>& userHs = mes.UserHeaders();
       
   894     for ( TInt i = 0; i < userHs.Count(); i++ )
       
   895         {
       
   896         const CSIPHeaderBase* header = userHs[ i ];
       
   897         if ( header->Name() == SIPStrings::StringF( SipStrConsts::ERetryAfterHeader ))
       
   898             {
       
   899             CSIPRetryAfterHeader* retryH = (CSIPRetryAfterHeader*)header;
       
   900             ret = retryH->RetryAfter();
       
   901             }
       
   902         else
       
   903             {
       
   904             // We ignore other than Retry-After header
       
   905             }
       
   906         }
       
   907 
       
   908     return ret;
       
   909     }