diff -r 000000000000 -r 7f85d04be362 upnpavcontroller/upnpavcontrollerserver/src/upnpavcontrollerserver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/upnpavcontroller/upnpavcontrollerserver/src/upnpavcontrollerserver.cpp Thu Dec 17 08:52:00 2009 +0200 @@ -0,0 +1,1001 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: AVController server +* +*/ + + + + + + + +// INCLUDE FILES +// System +#include +#include + +// upnp stack +#include + +// upnpframework / avcontroller api +#include "upnpavcontrollerglobals.h" + +// upnpframework / internal api's +#include "upnpconnectionmonitor.h" + +#include "upnpsecaccesscontroller.h" + + +// avcontroller server internal +#include "upnpavcontrollerserver.h" +#include "upnpavcontrollersession.h" + +#include + +#include "upnpavcontrolpoint.h" + + +#include "upnpavdispatcher.h" +#include "upnpdevicerepository.h" +#include "upnpavdeviceextended.h" +#include "upnpaverrorhandler.h" + +_LIT( KComponentLogfile, "upnpavcontrollerserver.txt" ); +#include "upnplog.h" + +// CONSTANTS +_LIT8( KMediaServer, "MediaServer" ); +_LIT8( KUPnPRootDevice, "upnp:rootdevice" ); + +const TInt KMaxDepth = 4; +const TInt KMaxDeviceCount = 6; + +const TUint myRangeCount = 3; + +const TInt myRanges[ myRangeCount ] = + { + 0, // numbers 0-18 + 18, // numbers 18-81 + 81 // numbers 81-KMaxInt + }; + +const TUint8 myElementsIndex[ myRangeCount ] = + { + 0, + 1, + CPolicyServer::ENotSupported + }; + +const CPolicyServer::TPolicyElement myElements[] = + { + {_INIT_SECURITY_POLICY_C3(ECapabilityNetworkServices, + ECapabilityReadUserData, ECapabilityWriteUserData ), + CPolicyServer::EFailClient }, + {_INIT_SECURITY_POLICY_C1(ECapabilityNetworkServices), + CPolicyServer::EFailClient} + }; + +const CPolicyServer::TPolicy myPolicy = + { + CPolicyServer::EAlwaysPass, //specifies all connect attempts should pass + myRangeCount, + myRanges, + myElementsIndex, + myElements, + }; + +// ============================ MEMBER FUNCTIONS ============================ + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::CUpnpAVControllerServer +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +CUpnpAVControllerServer::CUpnpAVControllerServer( TInt aPriority ): + CPolicyServer( aPriority, myPolicy ), + iShutdownTimeoutValue( KTimerCycle10 ), + iServerState( EStateUndefined ) + { + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::ConstructL +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +void CUpnpAVControllerServer::ConstructL() + { + __LOG( "CUpnpAVControllerServer::ConstructL" ); + + iDispatcher = CUPnPAVDispatcher::NewL( *this ); + + iServerState = EStateStartingUp; + + CUpnpSettings* settings = CUpnpSettings::NewL( KCRUidUPnPStack ); + settings->Get( CUpnpSettings::KUPnPStackIapId, iIAP ); + delete settings; + + User::LeaveIfError( iMediaServer.Connect() ); + iMonitor = CUPnPConnectionMonitor::NewL( *this, iIAP ); + + StartL( KAVControllerName ); + + iServerTimer = CUPnPAVTimer::NewL( *this, + CUPnPAVTimer::ETimerServerShutdown ); + + iServerTimer->Start( iShutdownTimeoutValue ); + + iMSTimer = CUPnPAVTimer::NewL( *this, CUPnPAVTimer::ETimerMediaServer ); + __LOG( "CUpnpAVControllerServer::ConstructL - Finished" ); + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::StartUpL +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +void CUpnpAVControllerServer::StartUpL() + { + __LOG( "CUpnpAVControllerServer::StartUpL" ); + + TInt error = KErrNone; + if( iServerState == EStateStartingUp ) + { + __LOG( "StartUpL - Starting up" ); + + + if( !iAVControlPoint ) + { + __LOG( "CUpnpAVControllerServer::StartUpL - CP" ); + + TRAP( error, iAVControlPoint = CUpnpAVControlPoint::NewL( + *iDispatcher )); + // If operation fails for some reason , the 10 second timeout + // is completely useless and wrong in this case. + // The server should be shut down immediately + if( error != KErrNone ) + { + iShutdownTimeoutValue = 0; + User::Leave( error ); + } + } + if( !iDeviceRepository ) + { + iDeviceRepository = CUPnPDeviceRepository::NewL( *iAVControlPoint ); + } + iServerState = EStateRunning; + } + else if( iServerState == EStateShuttingDown ) + { + __LOG( "StartUpL - Wlan disconnected or shutting down, leave" ); + User::Leave( KErrDisconnected ); + } + else + { + __LOG( "StartUpL - Server running" ); + } + + __LOG( "StartUpL - Completed" ); + } + +void CUpnpAVControllerServer::CancelStartUp() + { + __LOG( "CUpnpAVControllerServer::CancelStartUp" ); + + // Cancel can occur only when the av controller instance is deleted + // right after the asyncronous part of the construction has been + // started. There is no proper way to cancel, but we can set the + // shutdown timer to 0, so the server will shutdown immidiately. + + if( iSessionCount <= 1 ) + { + iShutdownTimeoutValue = 0; + } + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::NewLC +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +CUpnpAVControllerServer* CUpnpAVControllerServer::NewLC() + { + CUpnpAVControllerServer* self = new( ELeave ) + CUpnpAVControllerServer( EPriorityNormal ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::~CUpnpAVControllerServer +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +CUpnpAVControllerServer::~CUpnpAVControllerServer() + { + __LOG( "CUpnpAVControllerServer::~CUpnpAVControllerServer" ); + + delete iAVControlPoint; + delete iDispatcher; + delete iDeviceRepository; + + delete iMonitor; + delete iServerTimer; + delete iMSTimer; + + iMediaServer.Close(); + + for( TInt i = 0; i < iStartMessages.Count(); i++ ) + { + iStartMessages[ i ]->Complete( KErrCancel ); + } + iStartMessages.ResetAndDestroy(); + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::NewSessionL +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +CSession2* CUpnpAVControllerServer::NewSessionL( const TVersion& aVersion, + const RMessage2& aMessage ) const + { + __LOG( "CUpnpAVControllerServer::NewSessionL" ); + + if( iServerState == EStateShuttingDown ) + { + __LOG( "NewSessionL - server shutting down, no new sessions \ +are allowed at this point" ); + User::Leave( KErrDisconnected ); + } + else if( iServerState == EStateStartingUp && iSessionCount > 0 ) + { + __LOG( "NewSessionL - server starting up, no new sessions \ +are allowed at this point" ); + User::Leave( KErrServerBusy ); + } + + // Check we're the right version + if ( !User::QueryVersionSupported( TVersion( + KAVControllerMajorVersionNumber, + KAVControllerMinorVersionNumber, + KAVControllerBuildVersionNumber ), + aVersion ) ) + { + User::Leave( KErrNotSupported ); + } + + // Make new session + RThread client; + aMessage.Client(client); + return CUpnpAVControllerSession::NewL( + *(CUpnpAVControllerServer*)this ); + } + + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::UPnPAVTimerCallback +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +void CUpnpAVControllerServer::UPnPAVTimerCallback( + CUPnPAVTimer::TAVTimerType aType ) + { + __LOG( "CUpnpAVControllerServer::UPnPAVTimerCallback" ); + + + if( aType == CUPnPAVTimer::ETimerServerShutdown ) + { + iServerState = EStateShuttingDown; + + if( iMSTimer->IsActive() ) + { + // if the Media Server timer is still running for some reason + iMSTimer->Cancel(); + StopMediaServer(); + } + CActiveScheduler::Stop(); + } + else if( aType == CUPnPAVTimer::ETimerMediaServer ) + { + if( iStartingMS ) + { + StopMediaServer(); + TInt count = iStartMessages.Count(); + for( TInt i = 0; i < count; i++ ) + { + iStartMessages[ i ]->Complete( KErrTimedOut ); + } + iStartMessages.ResetAndDestroy(); + + iStartingMS = EFalse; + } + else // Shutting down + { + StopMediaServer(); + } + } + else + { + + } + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::ConnectionLost +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +void CUpnpAVControllerServer::ConnectionLost() + { + __LOG( "CUpnpAVControllerServer::ConnectionLost" ); + + iShutdownTimeoutValue = 0; // Set shutdown timer value to 0, we want to + // shut down the server immidiately after the last session has been + // closed + + if( iServerState == EStateRunning && iDeviceRepository ) + { + __LOG( "ConnectionLost - Server running" ); + iDeviceRepository->ConnectionLost(); + + CSession2* s; + iSessionIter.SetToFirst(); + while ( ( s = iSessionIter++ ) != NULL ) + { + CUpnpAVControllerSession* sess = + static_cast(s); + if( sess ) + { + sess->ConnectionLost(); + } + }; + iServerState = EStateShuttingDown; + } + else if (iServerState == EStateStartingUp ) + { + __LOG( "ConnectionLost - Server starting up" ); + iServerState = EStateShuttingDown; + } + + // If don't have any clients connect to server and current WLAN connection + // is lost, we want to shut down the server immidiately. + if ( iSessionCount <= 0 ) + { + if ( iServerTimer->IsActive() ) + { + iServerTimer->Cancel(); + } + iServerTimer->Start( iShutdownTimeoutValue ); + } + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::RunError +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +TInt CUpnpAVControllerServer::RunError( TInt aError ) + { + __LOG( "CUpnpAVControllerServer::RunError" ); + + if ( aError == KErrBadDescriptor ) + { + PanicClient( Message(), EAVControllerServerBadDescriptor ); + } + else + { + Message().Complete( aError ); + } + + // The leave will result in an early return from CServer::RunL(), + // skipping the call to request another message. So do that now in order + // to keep the server running. + ReStart(); + // Handled the error fully + return KErrNone; + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::PanicClient +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +void CUpnpAVControllerServer::PanicClient(const RMessage2& aMessage, + TAVControllerServerPanic aPanic) + { + __LOG( "CUpnpAVControllerServer::PanicClient" ); + + aMessage.Panic( KAVControllerName, aPanic ); + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::PanicServer +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +void CUpnpAVControllerServer::PanicServer(TAVControllerServerPanic aPanic) + { + __LOG( "CUpnpAVControllerServer::PanicServer" ); + + User::Panic( KAVControllerName, aPanic ); + } + + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::ThreadFunctionL +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +void CUpnpAVControllerServer::ThreadFunctionL() + { + __LOG( "CUpnpAVControllerServer::ThreadFunctionL" ); + + // Construct active scheduler + CActiveScheduler* activeScheduler = new (ELeave) CActiveScheduler; + CleanupStack::PushL( activeScheduler ); + // Install active scheduler + // We don't need to check whether an active scheduler is already + // installed + // as this is a new thread, so there won't be one + CActiveScheduler::Install( activeScheduler ); + // Construct our server + CUpnpAVControllerServer* server = CUpnpAVControllerServer::NewLC(); + + RProcess::Rendezvous( KErrNone ); + // Start handling requests + CActiveScheduler::Start(); + + CleanupStack::PopAndDestroy( server ); + CleanupStack::PopAndDestroy( activeScheduler ); + + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::HandleEmbeddedDiscoveredDevicesL +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +void CUpnpAVControllerServer::HandleEmbeddedDiscoveredDevicesL( + CUpnpDevice& aDevice, TInt aDepth ) + { + __LOG( "CUpnpAVControllerServer::HandleEmbeddedDiscoveredDevicesL" ); + + if( aDepth <= KMaxDepth && iDiscoveredDeviceCount <= KMaxDeviceCount ) + { + RPointerArray& devList = aDevice.DeviceList(); + TInt count = devList.Count(); + for( TInt i = 0; i < count; i++ ) + { + iDeviceRepository->AddDeviceL( *devList[ i ] ); + TInt sessionId = iAVControlPoint->CmProtocolInfoActionL( + devList[ i ]->Uuid() ); + iDiscoveredDeviceCount++; + + HandleEmbeddedDiscoveredDevicesL( *devList[ i ], ++aDepth ); + } + } + else + { + __LOG( "HandleEmbeddedDiscoveredDevicesL - max depth \ +or count reached" ); + } + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::HandleEmbeddedDisappearedDevicesL +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +void CUpnpAVControllerServer::HandleEmbeddedDisappearedDevicesL( + CUpnpDevice& aDevice, TInt aDepth ) + { + __LOG( "CUpnpAVControllerServer::HandleEmbeddedDisappearedDevicesL" ); + + if( aDepth <= KMaxDepth && iDisappearedDeviceCount <= KMaxDeviceCount ) + { + RPointerArray& devList = aDevice.DeviceList(); + TInt count = devList.Count(); + for( TInt i = 0; i < count; i++ ) + { + CUpnpAVDeviceExtended& ext = iDeviceRepository->FindDeviceL( + devList[ i ]->Uuid() ); + + CSession2* s; + iSessionIter.SetToFirst(); + while ( ( s = iSessionIter++ ) != NULL ) + { + CUpnpAVControllerSession* sess = + static_cast(s); + if( sess ) + { + sess->DeviceDisappearedL( ext ); + } + }; + + iDeviceRepository->Remove( ext.Uuid() ); + + iDisappearedDeviceCount++; + + HandleEmbeddedDisappearedDevicesL( *devList[ i ], ++aDepth ); + } + } + else + { + __LOG( "HandleEmbeddedDisappearedDevicesL - max depth \ +or count reached" ); + } + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::StopMediaServer +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +void CUpnpAVControllerServer::StopMediaServer() + { + __LOG( "CUpnpAVControllerServer::StopMediaServer" ); + + if( iShutdownTimeoutValue ) + { + __LOG( "StopMediaServer - normal shutdown" ); + iMediaServer.Stop( RUpnpMediaServerClient::EStopNormal ); + } + else + { + __LOG( "StopMediaServer - silent shutdown" ); + iMediaServer.Stop( RUpnpMediaServerClient::EStopSilent ); + } + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::ThreadFunction +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +TInt CUpnpAVControllerServer::ThreadFunction() + { + __LOG( "CUpnpAVControllerServer::ThreadFunction" ); + + __UHEAP_MARK; + + User::RenameThread(KAVControllerThreadName); + + CTrapCleanup* cleanupStack = CTrapCleanup::New(); + if ( !(cleanupStack) ) + { + PanicServer( EAVControllerServerCreateTrapCleanup ); + } + + TRAPD( err, ThreadFunctionL() ); + if ( err != KErrNone ) + { + __LOG1( "ThreadFunction, creation failed: %d", err ); + //PanicServer( EAVControllerServerSrvCreateServer ); + } + + delete cleanupStack; + cleanupStack = NULL; + + __UHEAP_MARKEND; + + return err; + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::IncrementSessions +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +void CUpnpAVControllerServer::IncrementSessions() + { + __LOG( "CUpnpAVControllerServer::IncrementSessions" ); + + iSessionCount++; + if( iServerTimer->IsActive() ) + { + iServerTimer->Cancel(); + __LOG( "IncrementSessions - make a search" ); + if( iAVControlPoint ) + { + TRAP_IGNORE( iAVControlPoint->SearchL( KUPnPRootDevice ) ); + } + } + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::DecrementSessions +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +void CUpnpAVControllerServer::DecrementSessions() + { + __LOG( "CUpnpAVControllerServer::DecrementSessions" ); + + iSessionCount--; + if ( iSessionCount <= 0 ) + { + if( iServerTimer->IsActive() ) + { + iServerTimer->Cancel(); + } + iServerTimer->Start( iShutdownTimeoutValue ); + } + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::DeviceDiscoveredL +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +void CUpnpAVControllerServer::DeviceDiscoveredL( CUpnpDevice& aDevice ) + { + __LOG( "CUpnpAVControllerServer::DeviceDiscoveredL" ); + + if( aDevice.Local() && aDevice.DeviceType().Find( KMediaServer ) + != KErrNotFound ) + { + // It's the local S60 MS + + if( iStartingMS ) + { + iMSTimer->Cancel(); + } + CUpnpSecAccessController* accessController = + CUpnpSecAccessController::NewL(); + __LOG( "CUpnpAVControllerServer::DeviceDiscoveredL \ +adding the local media server IP to the list of authorized addresses." ); + + accessController->AddAllowedAddress( aDevice.Address() ); + delete accessController; + accessController = NULL; + } + + iDeviceRepository->AddDeviceL( aDevice ); + TInt sessionId = iAVControlPoint->CmProtocolInfoActionL( + aDevice.Uuid() ); + iDiscoveredDeviceCount = 1; // First (root) device + + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::DeviceDisappearedL +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +void CUpnpAVControllerServer::DeviceDisappearedL( CUpnpDevice& aDevice ) + { + __LOG( "CUpnpAVControllerServer::DeviceDisappearedL" ); + + if( aDevice.Local() && aDevice.DeviceType().Find( KMediaServer ) + != KErrNotFound ) + { + // It's the local S60 MS + iMediaServerOnline = EFalse; + } + + // Get a corresponding device from the device repository + CUpnpAVDeviceExtended& tmp = iDeviceRepository->FindDeviceL( + aDevice.Uuid() ); + + // Let the clients know about the disappeared device + CSession2* s; + iSessionIter.SetToFirst(); + while ( ( s = iSessionIter++ ) != NULL ) + { + CUpnpAVControllerSession* sess = + static_cast(s); + if( sess ) + { + sess->DeviceDisappearedL( tmp ); + } + }; + // Remove from the device repository + iDeviceRepository->Remove( aDevice.Uuid() ); + iDisappearedDeviceCount = 1; + + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::DeviceDisappearedL +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +void CUpnpAVControllerServer::DeviceDisappearedL( const TDesC8& aUuid ) + { + __LOG( "CUpnpAVControllerServer::DeviceDisappearedL uid" ); + // Get a corresponding device from the device repository + CUpnpAVDeviceExtended& tmp = iDeviceRepository->FindDeviceL( + aUuid ); + + // Let the clients know about the disappeared device + CSession2* s; + iSessionIter.SetToFirst(); + while ( ( s = iSessionIter++ ) != NULL ) + { + CUpnpAVControllerSession* sess = + static_cast( s ); + if ( sess ) + { + sess->DeviceDisappearedL( tmp ); + } + } + // Remove from the device repository + iDeviceRepository->Remove( aUuid ); + iDisappearedDeviceCount = 1; + __LOG( "CUpnpAVControllerServer::DeviceDisappearedL uid End" ); + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::StartMediaServerL +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +void CUpnpAVControllerServer::StartMediaServerL( const RMessage2& aMessage ) + { + __LOG( "CUpnpAVControllerServer::StartMediaServerL" ); + + if( iMediaServerOnline ) + { + // Started already, complete the msg + iMSTimer->Cancel(); + aMessage.Complete( EAVControllerStartMediaServerCompleted ); + iServerUserCount++; + } + else + { + // Start the media server and timer + if( iStartMessages.Count() > 0 ) + { + RMessage2* message = new (ELeave) RMessage2( aMessage ); + iStartMessages.AppendL( message ); + } + else + { + // Check if the stack's security is enabled + TBool upnpSecurityEnabled = EFalse; + TRAPD( secCheckError, upnpSecurityEnabled = + CUpnpSecAccessController::IsMediaServerSecurityEnabledL() ); + + // If the security is not enabled, enable it now + if( secCheckError == KErrNone && + !upnpSecurityEnabled ) + { + TRAP_IGNORE( + CUpnpSecAccessController::EnableMediaServerSecurityL() ); + } + + RMessage2* message = new(ELeave) RMessage2( aMessage ); + iStartMessages.AppendL( message ); + User::LeaveIfError( iMediaServer.Start() ); + iMSTimer->Start( iShutdownTimeoutValue ); + iStartingMS = ETrue; + } + } + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::CancelStartMediaServerL +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +void CUpnpAVControllerServer::CancelStartMediaServerL( + const RMessage2& aMessage ) + { + __LOG( "CUpnpAVControllerServer::CancelStartMediaServerL" ); + + if( !iMSActivatedBeforeStart ) + { + StopMediaServer(); + } + + TInt count = iStartMessages.Count(); + for( TInt i = 0; i < count; i++ ) + { + iStartMessages[ i ]->Complete( KErrCancel ); + } + iStartMessages.ResetAndDestroy(); + iMSTimer->Cancel(); + + aMessage.Complete( KErrNone ); + + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::StopMediaServerL +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +void CUpnpAVControllerServer::StopMediaServerL( const RMessage2& aMessage ) + { + __LOG( "CUpnpAVControllerServer::StopMediaServerL" ); + + if( iMediaServerOnline ) + { + iServerUserCount--; + if( iServerUserCount <= 0 ) + { + if( !iMSActivatedBeforeStart ) + { + iMSTimer->Start( iShutdownTimeoutValue ); + } + iServerUserCount = 0; + } + } + aMessage.Complete( KErrNone ); + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::MSServicesInUse +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +void CUpnpAVControllerServer::MSServicesInUse( const RMessage2& aMessage ) + { + if( iServerUserCount > 0 || iStartingMS + || iMSTimer->IsActive() + ) + { + TPckg resp0( ETrue ); + aMessage.Write( 0, resp0 ); + } + else + { + TPckg resp0( EFalse ); + aMessage.Write( 0, resp0 ); + } + aMessage.Complete( KErrNone ); + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::CmProtocolInfoResponse +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +void CUpnpAVControllerServer::CmProtocolInfoResponse( const TDesC8& aUuid, + TInt /*aSessionId*/, TInt aErr, const TDesC8& aSource, + const TDesC8& aSink ) + { + __LOG1( "CUpnpAVControllerServer::CmProtocolInfoResponse, \ +aErr = %d", aErr ); + + aErr = UPnPAVErrorHandler::ConvertToSymbianErrorCode( aErr, + EUPnPConnectionManagerError ); + + if( aErr == KErrNone ) + { + CUpnpAVDeviceExtended* dev = NULL; + TRAPD( err, dev = &iDeviceRepository->AddProtocolInfoL( + aUuid, aSource, aSink ) ); + + if( err == KErrNone ) + { + // Device discovered and protocolinfo was retrieved successfully + CSession2* s; + iSessionIter.SetToFirst(); + while ( ( s = iSessionIter++ ) != NULL ) + { + CUpnpAVControllerSession* sess = + static_cast(s); + if( sess ) + { + TRAP_IGNORE( sess->DeviceDiscoveredL( *dev ) ); + } + }; + + if( dev->Local() ) + { + iMediaServerOnline = ETrue; + + if( iStartingMS ) + { + TInt count = iStartMessages.Count(); + for( TInt i = 0; i < count; i++ ) + { + iStartMessages[ i ]->Complete( + EAVControllerStartMediaServerCompleted ); + iServerUserCount++; + } + iStartMessages.ResetAndDestroy(); + + iStartingMS = EFalse; + } + else + { + __LOG( "Sharing was enabled before AVC server start" ); + iMSActivatedBeforeStart = ETrue; + } + + } + } + else + { + // Could not add protocolinfo, it's invalid or corrupted + // Device cannot be used + HandleFailedProtocolInfoResponse( aUuid ); + } + } + else + { + // A problem occured fetching protocolinfo + // Device cannot be used + HandleFailedProtocolInfoResponse( aUuid ); + } + } + +void CUpnpAVControllerServer::HandleFailedProtocolInfoResponse( + const TDesC8& aUuid ) + { + __LOG( "CUpnpAVControllerServer::HandleFailedProtocolInfoResponse" ); + + CUpnpAVDeviceExtended* dev = NULL; + TRAPD( err, dev = &iDeviceRepository->FindDeviceL( aUuid ) ) + if( err == KErrNone ) + { + if( iStartingMS && dev->Local() ) + { + __LOG( "HandleFailedProtocolInfoResponse - local, stop and \ +complete messages" ); + + StopMediaServer(); + + TInt count = iStartMessages.Count(); + for( TInt i = 0; i < count; i++ ) + { + iStartMessages[ i ]->Complete( err ); + iServerUserCount++; + } + iStartMessages.ResetAndDestroy(); + + iStartingMS = EFalse; + } + } + else + { + // Not found, no can do + __LOG( "HandleFailedProtocolInfoResponse - not found" ); + } + iDeviceRepository->Remove( aUuid ); + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::ControlPoint +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +CUpnpAVControlPoint& CUpnpAVControllerServer::ControlPoint() + { + return *iAVControlPoint; + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::MediaServer +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +RUpnpMediaServerClient& CUpnpAVControllerServer::MediaServer() + { + return iMediaServer; + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::Dispatcher +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +CUPnPAVDispatcher& CUpnpAVControllerServer::Dispatcher() + { + return *iDispatcher; + } + +// -------------------------------------------------------------------------- +// CUpnpAVControllerServer::DeviceRepository +// See upnpavcontrollerserver.h +// -------------------------------------------------------------------------- +CUPnPDeviceRepository& CUpnpAVControllerServer::DeviceRepository() + { + return *iDeviceRepository; + } + +TInt CUpnpAVControllerServer::IAP() + { + return iIAP; + } + +// ============================= LOCAL FUNCTIONS ============================ + +// -------------------------------------------------------------------------- +// E32Main entry point. +// Returns: KErrNone +// -------------------------------------------------------------------------- +TInt E32Main() + { + return CUpnpAVControllerServer::ThreadFunction(); + } + +// End of File +