upnpframework/upnpcommand/src/upnpimagerenderingengine.cpp
changeset 0 7f85d04be362
equal deleted inserted replaced
-1:000000000000 0:7f85d04be362
       
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Engine for rendering images remotely
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 // upnp stack api
       
    21 #include <upnpitem.h>                   // CUpnpItem
       
    22 #include <upnpobject.h>                 // CUpnpObject (cast)
       
    23 
       
    24 // upnpframework / avcontroller api
       
    25 #include "upnpavrenderingsession.h"     // MUPnPAVRenderingSession
       
    26 #include "upnpavsessionobserverbase.h" 
       
    27 
       
    28 // upnpframework / avcontroller helper api
       
    29 #include "upnpconstantdefs.h"           // KFilterCommon
       
    30 #include "upnpitemresolver.h"           // MUPnPItemResolver
       
    31 #include "upnpitemresolverobserver.h"   // MUPnPItemResolverObserver
       
    32 #include "upnpitemresolverfactory.h"    // UPnPItemResolverFactory
       
    33 #include "upnpitemutility.h"            // UPnPItemUtility::BelongsToClass
       
    34 
       
    35 // upnpframework / commonui
       
    36 #include "upnpcommonui.h"               // common UI for upnp video player dlg
       
    37 
       
    38 // command internal
       
    39 #include "upnpimagerenderingengineobserver.h"   // the observer interface
       
    40 #include "upnpimagerenderingengine.h"   // myself
       
    41 #include "upnpperiodic.h"
       
    42 
       
    43 _LIT( KComponentLogfile, "upnpcommand.log");
       
    44 #include "upnplog.h"
       
    45 
       
    46 // CONSTANT DEFINITIONS
       
    47 const TInt KReactionTimerMicrosec = 100000; // 100 millisec.
       
    48 
       
    49 
       
    50 // --------------------------------------------------------------------------
       
    51 // CUpnpImageRenderingEngine::NewL
       
    52 // --------------------------------------------------------------------------
       
    53 //
       
    54 CUpnpImageRenderingEngine* CUpnpImageRenderingEngine::NewL(
       
    55             MUPnPAVController& aAVController,
       
    56             MUPnPAVRenderingSession& aSession,
       
    57             MUpnpImageRenderingEngineObserver& aObserver )
       
    58     {
       
    59     __LOG( "[UpnpCommand]\t CUpnpImageRenderingEngine::NewL" );
       
    60 
       
    61     // Create instance
       
    62     CUpnpImageRenderingEngine* self = NULL;
       
    63     self = new (ELeave) CUpnpImageRenderingEngine(
       
    64             aAVController, aSession, aObserver );
       
    65     CleanupStack::PushL( self );
       
    66     self->ConstructL( );
       
    67     CleanupStack::Pop( self );
       
    68     return self;
       
    69     }
       
    70 
       
    71 // --------------------------------------------------------------------------
       
    72 // CUpnpImageRenderingEngine::CUpnpImageRenderingEngine
       
    73 // --------------------------------------------------------------------------
       
    74 //
       
    75 CUpnpImageRenderingEngine::CUpnpImageRenderingEngine(
       
    76             MUPnPAVController& aAVController,
       
    77             MUPnPAVRenderingSession& aSession,
       
    78             MUpnpImageRenderingEngineObserver& aObserver )
       
    79     : iAVController( aAVController )
       
    80     , iRenderingSession( aSession )
       
    81     , iObserver( aObserver )
       
    82     {
       
    83     __LOG( "[UpnpCommand]\t CUpnpImageRenderingEngine: Constructor" );
       
    84 
       
    85     // Initialise member variables
       
    86     iState = EIdle;
       
    87     iCurrentResolver = 0;
       
    88     iBufferedResolver = 0;
       
    89 
       
    90     // set observer
       
    91     iRenderingSession.SetObserver( *this );
       
    92     }
       
    93 
       
    94 // --------------------------------------------------------------------------
       
    95 // Second phase constructor.
       
    96 // --------------------------------------------------------------------------
       
    97 //
       
    98 void CUpnpImageRenderingEngine::ConstructL()
       
    99     {
       
   100     __LOG( "[UpnpCommand]\t CUpnpImageRenderingEngine::ConstructL" );
       
   101     iTimer = CUPnPPeriodic::NewL( CActive::EPriorityStandard );
       
   102     
       
   103     iWlanActive = ETrue;
       
   104     }
       
   105     
       
   106 // --------------------------------------------------------------------------
       
   107 // Destructor.
       
   108 // --------------------------------------------------------------------------
       
   109 //
       
   110 CUpnpImageRenderingEngine::~CUpnpImageRenderingEngine()
       
   111     {
       
   112     __LOG( "[UpnpCommand]\t CUpnpImageRenderingEngine: Destructor" );
       
   113 
       
   114     Cleanup();
       
   115 
       
   116     // Stop observing the rendering session
       
   117     iRenderingSession.RemoveObserver();
       
   118 
       
   119     __LOG( "[UpnpCommand]\t CUpnpImageRenderingEngine::~CUpnpImageRenderingEngine delete iCurrentResolver" );
       
   120     MUPnPItemResolver* tempCurrentResolver = iCurrentResolver;
       
   121     iCurrentResolver = NULL;
       
   122     delete tempCurrentResolver;
       
   123     
       
   124        if( iTimer )
       
   125         {    
       
   126         iTimer->Cancel();
       
   127         delete iTimer;
       
   128         iTimer = 0;
       
   129         }
       
   130     }
       
   131 
       
   132 // --------------------------------------------------------------------------
       
   133 // CUpnpImageRenderingEngine::Cleanup
       
   134 // --------------------------------------------------------------------------
       
   135 //
       
   136 void CUpnpImageRenderingEngine::Cleanup()
       
   137     {
       
   138     __LOG( "[UpnpCommand]\t CUpnpImageRenderingEngine::Cleanup" );
       
   139 
       
   140     // reset state
       
   141     if ( iState != EShuttingDown )
       
   142         {
       
   143         iState = EIdle;
       
   144         }
       
   145 
       
   146     if( iTimer )
       
   147         {    
       
   148         iTimer->Cancel();
       
   149         }
       
   150 
       
   151     iBufferingNewImage = EFalse;
       
   152 
       
   153     // Delete resolvers
       
   154     // Delete for resolvers is done using temporary variables so that we can
       
   155     // first nullify the members and then delete the actual objects.
       
   156     // This is because local resolver deletion uses active scheduler loops
       
   157     // and therefore other asynchronous events may orrur. So we may end
       
   158     // up here in Cleanup again, during the resolver is being deleted.
       
   159     // if deletion is done the conventional way, the objects get deleted
       
   160     // twice, which is not what we want. :-)
       
   161     
       
   162     __LOG( "[UpnpCommand]\t CUpnpImageRenderingEngine::Cleanup delete iBufferedResolver" );
       
   163     MUPnPItemResolver* tempBufferedResolver = iBufferedResolver;
       
   164     iBufferedResolver = NULL;
       
   165     delete tempBufferedResolver;
       
   166 
       
   167     __LOG( "[UpnpCommand]\t CUpnpImageRenderingEngine::Cleanup end" );
       
   168     }
       
   169 
       
   170 // --------------------------------------------------------------------------
       
   171 // CUpnpImageRenderingEngine::PlayL
       
   172 // --------------------------------------------------------------------------
       
   173 //
       
   174 void CUpnpImageRenderingEngine::PlayL()
       
   175     {
       
   176     __LOG1( "[UpnpCommand]\t CUpnpImageRenderingEngine::PlayL in state %d",
       
   177         iState);
       
   178 
       
   179     if ( iState != EShuttingDown )
       
   180         {
       
   181         if( iTimer->IsActive() )
       
   182             {
       
   183             __LOG( "[UpnpCommand]\t timer already active" );
       
   184             }
       
   185         else
       
   186             {
       
   187             TTimeIntervalMicroSeconds32 delay( KReactionTimerMicrosec );
       
   188             iTimer->Start( delay, delay, TCallBack( Timer, this ) );
       
   189             }
       
   190         }
       
   191     else
       
   192         {
       
   193         __LOG( "[UpnpCommand]\t not doing play in shutting down state" );
       
   194         }
       
   195     }
       
   196 
       
   197 // --------------------------------------------------------------------------
       
   198 // CUpnpImageRenderingEngine::StopL
       
   199 // --------------------------------------------------------------------------
       
   200 //
       
   201 void CUpnpImageRenderingEngine::StopL()
       
   202     {
       
   203     __LOG1( "[UpnpCommand]\t CUpnpImageRenderingEngine::StopL in state %d",
       
   204         iState);
       
   205 
       
   206     // cancel any timers that are going on
       
   207     iTimer->Cancel();
       
   208 
       
   209     // remove buffered images
       
   210     iBufferingNewImage = EFalse;
       
   211     delete iBufferedResolver;
       
   212     iBufferedResolver = 0;
       
   213 
       
   214     switch( iState )
       
   215         {
       
   216         case EIdle:
       
   217         case EResolvingItem:
       
   218         case EResolveComplete:
       
   219         case ESettingUri: // fall through
       
   220             {
       
   221             // just cancel the sequence and do nothing
       
   222             iState = EIdle;
       
   223             break;
       
   224             }
       
   225         case EStartingPlay:
       
   226             {
       
   227             // wait for PLAY complete, then do STOP
       
   228             // then wait for STOP complete
       
   229             iState = EStopping;
       
   230             break;
       
   231             }
       
   232         case EPlaying:
       
   233             {
       
   234             // Send stop action.
       
   235             iRenderingSession.StopL();
       
   236             iState = EStopping;
       
   237             break;
       
   238             }
       
   239         case EStopping:
       
   240             {
       
   241             // already stopping - do nothing
       
   242             break;
       
   243             }
       
   244         case EShuttingDown:
       
   245             {
       
   246             // command not allowed in this state
       
   247             break;
       
   248             }
       
   249         default:
       
   250             {
       
   251             __PANICD( __FILE__, __LINE__ );
       
   252             break;
       
   253             }
       
   254         }
       
   255     }
       
   256 
       
   257 // --------------------------------------------------------------------------
       
   258 // CUpnpImageRenderingEngine::Timer
       
   259 // timer callback
       
   260 // --------------------------------------------------------------------------
       
   261 //
       
   262 TInt CUpnpImageRenderingEngine::Timer( TAny* aArg )
       
   263     {    
       
   264     CUpnpImageRenderingEngine* self =
       
   265         static_cast<CUpnpImageRenderingEngine*>( aArg );
       
   266     TRAPD( error, self->RunTimerL() )
       
   267     if ( error != KErrNone )
       
   268         self->RunError( error );
       
   269     return 0; // do not call again
       
   270     }
       
   271 
       
   272 // --------------------------------------------------------------------------
       
   273 // CUpnpImageRenderingEngine::RunTimerL
       
   274 // Timer has triggered, start rendering media.
       
   275 // --------------------------------------------------------------------------
       
   276 //
       
   277 void CUpnpImageRenderingEngine::RunTimerL()
       
   278     {
       
   279     __LOG1( "[UpnpCommand]\t CUpnpImageRenderingEngine::RunTimerL, state %d",
       
   280         iState );
       
   281         
       
   282     iTimer->Cancel();
       
   283 
       
   284     delete iBufferedResolver;
       
   285     iBufferedResolver = iObserver.GetMedia();
       
   286     if ( iBufferedResolver == 0 )
       
   287         {
       
   288         __LOG( "[UpnpCommand]\t resolver returned zero" );
       
   289         User::Leave( KErrCancel );
       
   290         }
       
   291 
       
   292     switch( iState )
       
   293         {
       
   294         case EIdle: // fall through
       
   295             {
       
   296             StartResolvingL();
       
   297             break;
       
   298             }
       
   299         case EResolvingItem: // fall through
       
   300         case EResolveComplete:
       
   301         case ESettingUri: // fall through
       
   302         case EStartingPlay:
       
   303             {
       
   304             // indicate that new image is being buffered. It will be popped
       
   305             // from buffer in next callback.
       
   306             iBufferingNewImage = ETrue;
       
   307             break;
       
   308             }
       
   309         case EPlaying:
       
   310             {
       
   311             // indicate that new image is being buffered. Send stop signal.
       
   312             // new item will be handled after stop completed.
       
   313             iBufferingNewImage = ETrue;
       
   314             iRenderingSession.StopL();
       
   315             iState = EStopping;
       
   316             break;
       
   317             }
       
   318         case EStopping:
       
   319             {
       
   320             // indicate that new image is being buffered. It will be popped
       
   321             // from buffer in next callback.
       
   322             iBufferingNewImage = ETrue;
       
   323             break;
       
   324             }
       
   325         case EShuttingDown:
       
   326             {
       
   327             // command not allowed in this state
       
   328             break;
       
   329             }
       
   330         default:
       
   331             {
       
   332             __PANICD( __FILE__, __LINE__ );
       
   333             break;
       
   334             }
       
   335         }
       
   336     }
       
   337 
       
   338 // --------------------------------------------------------------------------
       
   339 // CUpnpImageRenderingEngine::StartResolvingL
       
   340 // Handles the start up of the item resolving.
       
   341 // --------------------------------------------------------------------------
       
   342 //
       
   343 void CUpnpImageRenderingEngine::StartResolvingL()
       
   344     {
       
   345     __LOG1( "[UpnpCommand]\t CUpnpImageRenderingEngine::StartResolvingL\
       
   346  in state %d",
       
   347         iState );
       
   348 
       
   349     __ASSERTD( iBufferedResolver, __FILE__, __LINE__ );
       
   350     if ( !iBufferedResolver )
       
   351         {
       
   352         // something is very wrong
       
   353         User::Leave( KErrDisconnected );
       
   354         }
       
   355     
       
   356     // delete old resolver
       
   357     // destruction takes time due to unsharing, so set to null first
       
   358     // so that this wont be used else where
       
   359     MUPnPItemResolver* tempCurrentResolver = iCurrentResolver;
       
   360     iCurrentResolver = NULL;
       
   361     delete tempCurrentResolver;
       
   362     
       
   363     // take queued resolver in use
       
   364     iCurrentResolver = iBufferedResolver;
       
   365     iBufferedResolver = NULL;
       
   366     iBufferingNewImage = EFalse;
       
   367 
       
   368     // Update the state
       
   369     iState = EResolvingItem;
       
   370 
       
   371     // Start resolving the item
       
   372     iCurrentResolver->ResolveL( *this );
       
   373     }
       
   374 
       
   375 // --------------------------------------------------------------------------
       
   376 // CUpnpImageRenderingEngine::ResolveComplete
       
   377 // Indicates that resolving of an item is complete.
       
   378 // --------------------------------------------------------------------------
       
   379 //
       
   380 void CUpnpImageRenderingEngine::ResolveComplete(
       
   381     const MUPnPItemResolver& aResolver,
       
   382     TInt aError )
       
   383     {
       
   384     __LOG1( "[UpnpCommand]\t CUpnpImageRenderingEngine::ResolveComplete\
       
   385  in state %d", iState );
       
   386 
       
   387     // if engine is shutting down, no need to check these
       
   388     if ( iState == EResolvingItem )
       
   389         {
       
   390         __ASSERTD( &aResolver == iCurrentResolver, __FILE__, __LINE__ );
       
   391         if( iBufferingNewImage )
       
   392             {
       
   393             TRAP( aError, StartResolvingL() );
       
   394             }
       
   395         else if( aError == KErrNone )
       
   396             {
       
   397             iState = EResolveComplete;
       
   398             
       
   399             // Now that we have the full metadata of the item available, we
       
   400             // can start the rendering
       
   401             TRAP( aError, InitiateShowingL() );
       
   402             }
       
   403         // error handling
       
   404         if( aError != KErrNone && iState != EShuttingDown )
       
   405             {
       
   406             SendRenderAck( aError );
       
   407             }
       
   408         }
       
   409     else if( iState == EShuttingDown )
       
   410         {
       
   411         // do nothing.
       
   412         iState = EIdle;
       
   413         }
       
   414     else
       
   415         {
       
   416         __LOG( "[UpnpCommand]\t CUpnpImageRenderingEngine: state error." );
       
   417         __PANICD( __FILE__, __LINE__ );
       
   418         iState = EIdle;
       
   419         }
       
   420 
       
   421     }
       
   422 
       
   423 // --------------------------------------------------------------------------
       
   424 // CUpnpImageRenderingEngine::InitiateShowingL
       
   425 // Handles the initiation of rendering (SetUri or video player launching).
       
   426 // --------------------------------------------------------------------------
       
   427 void CUpnpImageRenderingEngine::InitiateShowingL()
       
   428     {
       
   429     __LOG1( "[UpnpCommand]\t CUpnpImageRenderingEngine::InitiateShowingL\
       
   430  in state %d",
       
   431         iState );
       
   432     __ASSERTD( iCurrentResolver, __FILE__, __LINE__ );
       
   433 
       
   434     if ( UPnPItemUtility::BelongsToClass(
       
   435         iCurrentResolver->Item(), KClassImage ) )
       
   436         {
       
   437          // Send the setUri action
       
   438         iRenderingSession.SetURIL(
       
   439             iCurrentResolver->Resource().Value(),
       
   440             iCurrentResolver->Item() );
       
   441         // update the state
       
   442         iState = ESettingUri;
       
   443         }
       
   444     else
       
   445         {
       
   446         User::Leave( KErrNotSupported );
       
   447         }
       
   448     }
       
   449 
       
   450 
       
   451 // --------------------------------------------------------------------------
       
   452 // CUpnpImageRenderingEngine::SetURIResult
       
   453 // UPnP AV Controller calls this method as a result for the 'set uri' request.
       
   454 // --------------------------------------------------------------------------
       
   455 //
       
   456 void CUpnpImageRenderingEngine::SetURIResult( TInt aError )
       
   457     {
       
   458     __LOG1( "[UpnpCommand]\t CUpnpImageRenderingEngine::SetURIResult\
       
   459  in state %d",
       
   460         iState );
       
   461 
       
   462     if ( iState == ESettingUri )
       
   463         {
       
   464         //need check the aError in case of SetURIL cause a error.
       
   465         if( aError != KErrNone )
       
   466             {
       
   467             Cleanup();
       
   468             return;         
       
   469             }
       
   470         __ASSERTD( iCurrentResolver, __FILE__, __LINE__ );
       
   471         if( iBufferingNewImage )
       
   472             {
       
   473             TRAP( aError, StartResolvingL() );
       
   474             }
       
   475         else if( aError == KErrNone )
       
   476             {
       
   477             TRAP( aError, iRenderingSession.PlayL() );
       
   478             if( aError == KErrNone )
       
   479                 {
       
   480                 // Update the state
       
   481                 iState = EStartingPlay;
       
   482                 }
       
   483             }
       
   484         // error handling
       
   485         if( aError != KErrNone )
       
   486             {
       
   487             SendRenderAck( aError );
       
   488             }
       
   489         }
       
   490     else if ( iState == EShuttingDown )
       
   491         {
       
   492         // do nothing
       
   493         }
       
   494     else
       
   495         {
       
   496         __LOG( "[UpnpCommand]\t CUpnpImageRenderingEngine: state error." );
       
   497         __PANICD( __FILE__, __LINE__ );
       
   498         iState = EIdle;
       
   499         }
       
   500 
       
   501     }
       
   502 
       
   503 // --------------------------------------------------------------------------
       
   504 // CUpnpImageRenderingEngine::InteractOperationComplete
       
   505 // Called by UpnpAvController to indicate that play is complete.
       
   506 // --------------------------------------------------------------------------
       
   507 //
       
   508 void CUpnpImageRenderingEngine::InteractOperationComplete(
       
   509     TInt aError,
       
   510     TUPnPAVInteractOperation aOperation )
       
   511     {
       
   512     __LOG2( "[UpnpCommand]\t CUpnpImageRenderingEngine::\
       
   513 InteractOperationComplete (%d) in state %d", aOperation, iState );
       
   514 
       
   515     if ( iState == EStartingPlay )
       
   516         {
       
   517         __ASSERTD( iCurrentResolver, __FILE__, __LINE__ );
       
   518         if( aOperation == EUPnPAVPlay && iBufferingNewImage )
       
   519             {
       
   520             // New image in buffer! call stop, then play new item.
       
   521             TRAP( aError, iRenderingSession.StopL() );
       
   522             if ( aError == KErrNone )
       
   523                 {
       
   524                 iState = EStopping;
       
   525                 }
       
   526             }
       
   527         else if ( aOperation == EUPnPAVPlay && aError == KErrNone )
       
   528             {
       
   529             // update status
       
   530             iState = EPlaying;
       
   531             // response for play request
       
   532             SendRenderAck( KErrNone );
       
   533             }
       
   534         // error handling
       
   535         if ( aError != KErrNone )
       
   536             {
       
   537             SendRenderAck( aError );
       
   538             }
       
   539         }
       
   540     else if ( iState == EPlaying )
       
   541         {
       
   542         if( aOperation == EUPnPAVPlayUser )
       
   543             {
       
   544             // state change event notification
       
   545             // no need to do anything here
       
   546             }
       
   547         else if( aOperation == EUPnPAVStopUser )
       
   548             {
       
   549             // user stop notification
       
   550             // state to idle, so that no stop event will be sent
       
   551             // if starting to process new item
       
   552             iState = EIdle;
       
   553             }
       
   554         }
       
   555     else if ( iState == EStopping )
       
   556         {
       
   557         __ASSERTD( iCurrentResolver, __FILE__, __LINE__ );
       
   558         if( aOperation == EUPnPAVStop && iBufferingNewImage )
       
   559             {
       
   560             TRAP( aError, StartResolvingL() );
       
   561             }
       
   562         else if ( aOperation == EUPnPAVStop && aError == KErrNone )
       
   563             {
       
   564             // succesful stop - go IDLE
       
   565             iState = EIdle;
       
   566             }
       
   567         // error handling
       
   568         if ( aError != KErrNone )
       
   569             {
       
   570             SendRenderAck( aError );
       
   571             }
       
   572         }
       
   573     else if ( iState == EShuttingDown )
       
   574         {
       
   575         if ( aOperation == EUPnPAVStop || aOperation == EUPnPAVPlay )
       
   576             {
       
   577             iState = EIdle;
       
   578             }
       
   579         }
       
   580 
       
   581     __LOG( "[UpnpCommand]\t CUpnpImageRenderingEngine::InteractOperationComplete end " );
       
   582     }
       
   583 
       
   584 
       
   585 
       
   586 
       
   587 // --------------------------------------------------------------------------
       
   588 // CUpnpImageRenderingEngine::MediaRendererDisappeared
       
   589 // Notifies that the Media Renderer we have a session with has disappeared.
       
   590 // Session is now unusable and must be closed. 
       
   591 // --------------------------------------------------------------------------
       
   592 //
       
   593 void CUpnpImageRenderingEngine::MediaRendererDisappeared(
       
   594     TUPnPDeviceDisconnectedReason aReason )
       
   595     {
       
   596     __LOG1( "[UpnpCommand]\t CUpnpImageRenderingEngine::\
       
   597 MediaRendererDisappeared in state %d", iState );
       
   598 
       
   599     if( iState == EShuttingDown )
       
   600         {
       
   601         __LOG( "[UpnpCommand]\t CUpnpImageRenderingEngine::\
       
   602         MediaRendererDisappeared engine already shutting down, do nothing" );
       
   603         }
       
   604     else
       
   605         {
       
   606         if( aReason == MUPnPAVSessionObserverBase::EWLANLost )
       
   607             {
       
   608             iWlanActive = EFalse;
       
   609             }
       
   610         iState = EShuttingDown; // avoid all callbacks
       
   611         iObserver.EngineShutdown( KErrDisconnected );
       
   612         }
       
   613     }
       
   614 
       
   615 // --------------------------------------------------------------------------
       
   616 // CUpnpImageRenderingEngine::RunError
       
   617 // Exception occurred in the timer body
       
   618 // --------------------------------------------------------------------------
       
   619 //
       
   620 TInt CUpnpImageRenderingEngine::RunError( TInt aError )
       
   621     {
       
   622     __LOG2( "[UpnpCommand]\t CUpnpImageRenderingEngine::\
       
   623 RunError in state %d aError %d", iState, aError );
       
   624     Cleanup();
       
   625     SendRenderAck( aError );
       
   626     return KErrNone;
       
   627     }
       
   628 
       
   629 
       
   630 
       
   631 // --------------------------------------------------------------------------
       
   632 // CUpnpImageRenderingEngine::SendRenderAck
       
   633 // Exception occurred in the timer body
       
   634 // --------------------------------------------------------------------------
       
   635 //
       
   636 void CUpnpImageRenderingEngine::SendRenderAck( TInt aError )
       
   637     {
       
   638     __LOG1( "[UpnpCommand]\t CUpnpImageRenderingEngine::\
       
   639 SendRenderAck(%d)", aError );
       
   640 
       
   641     // take a stack copy of some members
       
   642     MUpnpImageRenderingEngineObserver& observer = iObserver;
       
   643     const CUpnpItem* item = NULL;
       
   644     if ( iCurrentResolver  && 
       
   645         !( iState == EIdle || iState == EResolvingItem ) )
       
   646         {
       
   647         item = &iCurrentResolver->Item();
       
   648         }
       
   649 
       
   650     // cleanup if this was an error
       
   651     if ( aError != KErrNone )
       
   652         {
       
   653         __LOG1( "[UpnpCommand]\t CUpnpImageRenderingEngine::\
       
   654 SendRenderAck aError=%d -> Cleanup", aError );
       
   655         Cleanup();
       
   656         }
       
   657 
       
   658     // call the observer
       
   659     TInt resp = observer.RenderAck( aError, item );
       
   660 
       
   661     // in case of disconnected error, do engine shutdown
       
   662     if ( resp == KErrDisconnected )
       
   663         {
       
   664         __LOG1( "[UpnpCommand]\t CUpnpImageRenderingEngine::\
       
   665 SendRenderAck resp=%d -> EngineShutdown", resp );
       
   666         iState = EShuttingDown;
       
   667         observer.EngineShutdown( resp );
       
   668         }
       
   669 
       
   670     }
       
   671     
       
   672     
       
   673 // --------------------------------------------------------------------------
       
   674 // CUpnpImageRenderingEngine::IsWlanActive
       
   675 // If connection to renderer is lost, checks if wlan is still active
       
   676 // --------------------------------------------------------------------------
       
   677 //
       
   678 TBool CUpnpImageRenderingEngine::IsWlanActive()
       
   679     {        
       
   680     return iWlanActive;
       
   681     }
       
   682     
       
   683 // End of File