/*
* 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 <e32svr.h>
#include <f32file.h>
// upnp stack
#include <upnpdevice.h>
// 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 <upnpsettings.h>
#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<CUpnpAVControllerSession*>(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<CUpnpDevice>& 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<CUpnpDevice>& 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<CUpnpAVControllerSession*>(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<CUpnpAVControllerSession*>(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<CUpnpAVControllerSession*>( 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<TBool> resp0( ETrue );
aMessage.Write( 0, resp0 );
}
else
{
TPckg<TBool> 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<CUpnpAVControllerSession*>(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