--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/upnpmediaserver/mediaserverengine/src/upnpmediaserver.cpp Thu Dec 17 08:52:00 2009 +0200
@@ -0,0 +1,1049 @@
+/** @file
+* Copyright (c) 2005-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: Media Server
+*
+*/
+
+
+// INCLUDE FILES
+#include "upnpmediaserver.h"
+#include "upnpcontentdirectoryservice.h"
+#include "upnpmediaserversession.h"
+#include "upnpmediaserverglobals.h"
+#include "upnpcontentdirectoryglobals.h"
+#include "upnpmediaserverclient.h"
+#include "upnpsecuritymanager.h"
+#include "upnpfiletransferevent.h"
+#include <upnpdevicedescriptionstore.h>
+
+#include "upnpdeviceimplementation.h"
+#include "upnpcm.h"
+#include "upnpiconmanager.h"
+#include "upnpdiskremovedetector.h"
+#include <sysutil.h>
+#define KLogFile _L("upnpmediaserver.txt")
+#include "upnpcustomlog.h"
+#include <upnpconnectionmanagernetworkeventprovider.h>
+#include "upnpmediaserverdescriptionprovider.h"
+
+const TVersion KServerSupportedVersion(
+ KMediaServerMajorVersionNumber,
+ KMediaServerMinorVersionNumber,
+ KMediaServerBuildVersionNumber );
+
+using namespace UpnpMediaServerSettings;
+
+_LIT8( KUriMediaServer, "/mediaserver1/mediaserver1.xml" );
+_LIT8( KUriContentDirectory, "/mediaserver1/contentdirectory1.xml" );
+_LIT8( KUriConnectionManager, "/mediaserver1/connectionmanager1.xml" );
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::CUpnpMediaServer
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CUpnpMediaServer::CUpnpMediaServer():
+ iMsStatus( RUpnpMediaServerClient::EStopped )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::ConstructL()
+ {
+ BaseConstructL();
+ iSettings = CUpnpMediaServerSettings::NewL();
+ iDiskDetector = CUpnpDiskRemoveDetector::NewL( this );
+ iStopAVMediaServerTimer = CUpnpNotifyTimer::NewL( this );
+ iConnectionManagerNetworkEventProvider =
+ CUpnpConnectionManagerNetworkEventProvider::NewL( *this );
+ iDescriptionProvider = CUpnpMediaServerDescriptionProvider::NewL();
+
+ InitializeL( EFalse );
+
+ iDescriptionStore = CUpnpDeviceDescriptionStore::NewL( *iMsName );
+ iIconManager = CUpnpIconManager::NewL( *iDescriptionStore, *iDescriptionProvider );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CUpnpSymbianServerBase* CUpnpMediaServer::NewLC()
+ {
+ CUpnpMediaServer* self = new( ELeave ) CUpnpMediaServer();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ }
+
+// Destructor
+CUpnpMediaServer::~CUpnpMediaServer()
+ {
+ if ( iDescriptionStore )
+ {
+ TRAP_IGNORE( iDescriptionStore->SaveL() );
+ }
+
+ ASSERT( CanBeStopped() );//check if we are in correct state
+ delete iStopAVMediaServerTimer;
+ delete iMsName;
+ delete iCdName;
+ delete iCmName;
+
+ delete iConnectionManagerNetworkEventProvider;
+
+ iObserverList.ResetAndDestroy();
+
+ delete iSettings;
+ delete iManager;
+ delete iIconManager;
+
+ delete iDevice;
+ delete iDescriptionStore;
+ delete iContentDirecory;
+ delete iCm;
+ delete iDiskDetector;
+ delete iDescriptionProvider;
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::StopAVMediaServer
+//
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::StopAVMediaServer( TBool aSilent )
+ {
+ LOGS( "CUpnpMediaServer::StopAVMediaServer begin" );
+ iIsSilentShutdown = aSilent;
+ //ms will be stopped in KStopAVMediaServerDelay unless he gets start request
+ iStopAVMediaServerTimer->Start( KStopAVMediaServerDelay );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::StopAVMediaServerImmediately
+// Immediately stops media server ( no delay )
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::StopAVMediaServerImmediately( TBool aSilent, TBool aWlanLost )
+ {
+ iStopAVMediaServerTimer->Cancel();
+ iDiskDetector->Cancel();
+
+ delete iManager;
+ iManager = NULL;
+
+ // we do not want any stop devices in case of WLAN lost
+ if ( !aWlanLost )
+ {
+ if ( iDevice )
+ {
+ if ( !aSilent )
+ {
+ TRAP_IGNORE( iDevice->StopL() );
+ }
+ else
+ {
+ TRAP_IGNORE( iDevice->StopL( CUpnpDeviceImplementation::EStopSilent ) );
+ }
+ }
+ }
+
+ delete iContentDirecory;
+ iContentDirecory = NULL;
+
+ delete iCm;
+ iCm = NULL;
+
+ delete iDevice;
+ iDevice = NULL;
+
+ SetStatus( RUpnpMediaServerClient::EStopped );
+
+ SuggestShutdown();
+ LOGS( "CUpnpMediaServer::StopAVMediaServer end" );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::NewSessionL
+// Create new session.
+// -----------------------------------------------------------------------------
+//
+CSession2* CUpnpMediaServer::NewSessionL( const RMessage2& /*aMessage*/ ) const
+ {
+ return CUpnpMediaServerSession::NewL( (CUpnpMediaServer*) this );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::Status
+// Check status of the server.
+// -----------------------------------------------------------------------------
+//
+RUpnpMediaServerClient::TServerStatus CUpnpMediaServer::Status() const
+ {
+ if ( iStopAVMediaServerTimer && iStopAVMediaServerTimer->IsActive() )
+ {
+ return RUpnpMediaServerClient::EStopped;
+ }
+ return iMsStatus;
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::StartAVMediaServerL
+// Create and start the AV Media Server.
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::StartAVMediaServerL()
+ {
+ LOGS( "CUpnpMediaServer::StartAVMediaServerL begin" );
+
+ // cleanup because previous start could fail
+ StopAVMediaServerImmediately( EFalse, EFalse );
+
+ // save description
+ iDescriptionStore->SaveL();
+
+ // create device
+ iDevice = CUpnpDeviceImplementation::NewL( KUriMediaServer,
+ *iDescriptionStore,
+ *iDescriptionProvider );
+
+ // create security manager
+ iManager = CUpnpSecurityManager::NewInstanceFromUpnpSettingsL();
+ //iDevice->SetSecurityManager( iManager );
+
+ // create content direcory service
+ HBufC8* uploadtmp = iSettings->GetL( EUploadDirectory );
+ CleanupStack::PushL( uploadtmp );
+ if ( uploadtmp->Length() == 0 )
+ {
+ User::Leave( KErrNotReady );
+ }
+ HBufC* uploaddir = HBufC::NewL( uploadtmp->Length() );
+ CleanupStack::PushL( uploaddir );
+ uploaddir->Des().Copy( uploadtmp->Des() );
+ HBufC* thumbnaildir = HBufC::NewL( uploaddir->Length()
+ + KThumbnailDirLen );
+ CleanupStack::PushL( thumbnaildir );
+ thumbnaildir->Des().Copy( uploaddir->Des() );
+ thumbnaildir->Des().Append( KThumbnailSubDir );
+
+ TInt createThumbnails;
+ User::LeaveIfError( iSettings->Get( EUpnpMediaServerThumbnails,
+ createThumbnails ) );
+
+ TInt maxReqCount;
+ User::LeaveIfError( iSettings->Get( KUpnpMediaServerBrowseLimit,
+ maxReqCount ) );
+
+ TUpnpCdSettings cdset =
+ {
+ iDevice, *uploaddir, *thumbnaildir, *iCdName, NULL, createThumbnails,
+ maxReqCount, this, KNullDesC(), NULL
+ };
+
+ iContentDirecory = CUpnpContentDirectoryService::NewL( cdset );
+
+ // create connection manager service
+ HBufC8* media = iSettings->GetL( ESupportedMedia );
+ CleanupStack::PushL( media );
+ if ( media->Length() == 0 )
+ {
+ User::Leave( KErrNotReady );
+ }
+ iCm = CUpnpCM::NewL( *iDevice, *media, *iCmName );
+ CleanupStack::PopAndDestroy( media );
+
+ CleanupStack::PopAndDestroy( thumbnaildir );
+ CleanupStack::PopAndDestroy( uploaddir );
+ CleanupStack::PopAndDestroy( uploadtmp );
+
+ SetDescriptionSettingsL( iDevice );
+
+ // start media server
+ iDevice->StartL();
+ iDiskDetector->StartL();
+
+ SetStatus( RUpnpMediaServerClient::EStartedOnline );
+ LOGS( "CUpnpMediaServer::StartAVMediaServerL end" );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::StartAVMediaServerOfflineL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::StartAVMediaServerOfflineL()
+ {
+ LOGS( "StartAVMediaServerOfflineL begin" );
+
+ // cleanup because previous start could fail
+ StopAVMediaServerImmediately( EFalse, EFalse );
+
+ // create content directory
+ iContentDirecory = CUpnpContentDirectoryService::NewL();
+ SetStatus( RUpnpMediaServerClient::EStartedOffline );
+ LOGS( "StartAVMediaServerOfflineL end" );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::RestartAVMediaServerL
+// Start and stop the AV Media Server.
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::RestartAVMediaServerL()
+ {
+ if ( iDevice )
+ {
+ iDevice->StopL();
+ SetDescriptionSettingsL( iDevice );
+ iDevice->StartL();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::SetFriendlyNameL
+// Sets friendly name for device, changes are available after restarting
+// the server
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::SetDescriptionSettingsL(
+ CUpnpDeviceImplementation* aDevice )
+ {
+ SetDescriptionRequiredPropertyL( aDevice, EFriendlyName, KFriendlyName );
+ SetDescriptionRequiredPropertyL( aDevice, EModelName, KModelName );
+ SetDescriptionRequiredPropertyL( aDevice, EManufacturer, KManufacturer );
+
+ SetDescriptionPropertyL( aDevice, EModelUrl, KModelUrl );
+ SetDescriptionPropertyL( aDevice, EModelDescription, KModelDescription );
+ SetDescriptionPropertyL( aDevice, EModelNumber, KModelNumber );
+ SetDescriptionPropertyL( aDevice, ESerialNumber, KSerialNumber );
+ SetDescriptionPropertyL( aDevice, EPresentationUrl, KPresentationUrl );
+ SetDescriptionPropertyL( aDevice, EManufacturerUrl, KManufacturerUrl );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::RemoveIconL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::RemoveIconL( const TDesC8& aUrl )
+ {
+ iIconManager->RemoveIconL( aUrl );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::RemoveIconsL
+// ------------------------------------------------------------------------------
+//
+void CUpnpMediaServer::RemoveIconsL()
+ {
+ iIconManager->RemoveIconsL();
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::AddIconL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::AddIconL( const TDesC8& aProperty )
+ {
+ iIconManager->AddIconL( aProperty );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::UpdateIconL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::UpdateIconL( const TDesC8& aProperty,
+ const TDesC8& aUrl )
+ {
+ iIconManager->UpdateIconL( aProperty, aUrl );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::SetUploadDirToCDL
+// Set the download and thumbnail in CD according to the value
+// of the upload directory
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::SetUploadDirToCDL( const TDesC& aPath )
+ {
+ if ( iContentDirecory )
+ {
+ HBufC* uploaddir= NULL;
+
+ if ( aPath != KNullDesC() )
+ {
+ uploaddir = aPath.AllocLC();
+ }
+ else
+ {
+ HBufC8* uploadtmp = iSettings->GetL( EUploadDirectory );
+ CleanupStack::PushL( uploadtmp );
+
+ uploaddir = HBufC::NewL( uploadtmp->Length() );
+ uploaddir->Des().Copy( uploadtmp->Des() );
+ CleanupStack::PopAndDestroy( uploadtmp );
+ CleanupStack::PushL( uploaddir );
+ }
+
+ HBufC* thumbnaildir = HBufC::NewL( uploaddir->Length()
+ + KThumbnailDirLen );
+ CleanupStack::PushL( thumbnaildir );
+ thumbnaildir->Des().Copy( uploaddir->Des() );
+ thumbnaildir->Des().Append( KThumbnailSubDir );
+
+ iContentDirecory->SetDownloadDirectoryL( uploaddir->Des() );
+ iContentDirecory->SetThumbnailDirectoryL( thumbnaildir->Des() );
+
+ CleanupStack::PopAndDestroy( thumbnaildir );
+ CleanupStack::PopAndDestroy( uploaddir );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::SetUploadDirL
+// Set the upload and thumbnail path in CD and central repository.
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::SetUploadDirL( const TDesC& aPath )
+ {
+ User::LeaveIfError( iSettings->Set(
+ UpnpMediaServerSettings::EUploadDirectory, aPath ) ) ;
+
+ SetUploadDirToCDL( KNullDesC( )); // empty descriptor -> it means, value will be taken directly from cenrep
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::SetDescriptionPropertyL
+// Sets description property for device
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::SetDescriptionPropertyL(
+ CUpnpDeviceImplementation* aDevice, TInt aKey, const TDesC8& aName )
+ {
+ HBufC8* value = iSettings->GetL( aKey );
+ CleanupStack::PushL( value );
+ if ( value->Size() )
+ {
+ aDevice->SetDescriptionPropertyL( aName, *value );
+ }
+ else
+ {
+ aDevice->RemoveDescriptionPropertyL( aName );
+ }
+
+ CleanupStack::PopAndDestroy( value );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::SetDescriptionRequiredPropertyL
+// Sets description required property for device
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::SetDescriptionRequiredPropertyL(
+ CUpnpDeviceImplementation* aDevice, TInt aKey, const TDesC8& aName )
+ {
+ HBufC8* value = iSettings->GetL( aKey );
+
+ if ( !value )
+ {
+ User::Leave( KErrNotFound );
+ }
+ else
+ {
+ CleanupStack::PushL( value );
+
+ HBufC8* tmpBuf = (*value).AllocLC();
+ TPtr8 tmpPtr(tmpBuf->Des() );
+
+ RemoveWhiteSpaces( tmpPtr );
+ if ( tmpPtr.Length() == 0 )
+ {
+ User::Leave( KErrNotFound );
+ }
+ CleanupStack::PopAndDestroy( tmpBuf );
+ }
+
+ TRAPD( error, aDevice->SetDescriptionPropertyL( aName, *value ) )
+ if ( error != KErrNotFound )
+ {
+ User::LeaveIfError( error );
+ }
+
+ CleanupStack::PopAndDestroy( value );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::RemoveWhiteSpaces
+// Removes white characters from input descriptor
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::RemoveWhiteSpaces( TDes8& aString )
+ {
+ for ( TInt i=0; i<aString.Length(); i++ )
+ {
+ if ( aString[i] == ' ' || aString[i] == '\r' || aString[i] == '\n'
+ || aString[i] == '\t' )
+ {
+ aString.Replace( i, 1, KNullDesC8() );
+ i--;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::InitPrivateDir
+// Init Media Server directory structure in private directory
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::InitPrivateDirL( RFs &aFs )
+ {
+ TParse fp;
+ TFileName path;
+ aFs.PrivatePath( path );
+ fp.Set( KDefaultMediaDrive(), &path, 0 );
+ User::LeaveIfError( fp.AddDir( KMSPublicAccessedDir() ) );
+ User::LeaveIfError( fp.AddDir( KMSDeviceXmlDescDir() ) );
+ User::LeaveIfError( fp.AddDir( KIconDirectory() ) );
+ path = fp.DriveAndPath();
+
+ aFs.MkDirAll( path ) ;
+ fp.PopDir();
+ User::LeaveIfError( fp.AddDir( KMSMediaDir ) );
+ path = fp.DriveAndPath();
+ aFs.MkDirAll( path );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::InitDescFileL
+// Checks is description file exists. If not creates it from teplate stored on Z:
+// -----------------------------------------------------------------------------
+//
+HBufC* CUpnpMediaServer::InitDescFileL( RFs &aFs,
+ const TDesC& aTempleteDescFile, TBool aOverwrite )
+ {
+ TUint temp;
+ HBufC* descName = CreateFullNameL( aFs, KDefaultMediaDrive(),
+ aTempleteDescFile );
+ CleanupStack::PushL( descName );
+
+ if ( aFs.Att( *descName, temp ) != KErrNone || aOverwrite )
+ {
+
+ HBufC* templName = CreateFullNameL( aFs, KDescTemplateDrive(),
+ aTempleteDescFile );
+ CleanupStack::PushL( templName );
+ CFileMan* fileMan = CFileMan::NewL( aFs );
+ CleanupStack::PushL( fileMan );
+ User::LeaveIfError( fileMan->Copy( *templName, *descName ) );
+ User::LeaveIfError( fileMan->Attribs( *descName, KEntryAttNormal,
+ KEntryAttReadOnly, TTime( 0 ) ) );
+ CleanupStack::PopAndDestroy( fileMan );
+ CleanupStack::PopAndDestroy( templName );
+ }
+ CleanupStack::Pop( descName );
+ return descName;
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::InitializeL
+// Initialize Media Server using files from drive z:
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::InitializeL( TBool aOverwrite )
+ {
+ RFs fs;
+ User::LeaveIfError( fs.Connect() );
+ CleanupClosePushL( fs );
+
+ if ( SysUtil::DiskSpaceBelowCriticalLevelL( &fs, KMSDescriptionMaxSize,
+ EDriveC ) )
+ {
+ User::Leave( KErrDiskFull );
+ }
+
+ InitPrivateDirL( fs );
+
+ delete iMsName;
+ iMsName= NULL;
+ iMsName = InitDescFileL( fs, KMSDeviceXmlDescFile(), aOverwrite );
+ iDescriptionProvider->AddUriToFileMapL( KUriMediaServer(), iMsName->Des() );
+ delete iCdName;
+ iCdName = NULL;
+ iCdName = InitDescFileL( fs, KCDXmlDescFile(), aOverwrite );
+ iDescriptionProvider->AddUriToFileMapL( KUriContentDirectory(), iCdName->Des() );
+ delete iCmName;
+ iCmName = NULL;
+ iCmName = InitDescFileL( fs, KCMXmlDescFile(), aOverwrite );
+ iDescriptionProvider->AddUriToFileMapL( KUriConnectionManager(), iCmName->Des() );
+
+ CleanupStack::PopAndDestroy( &fs );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::ResetDbL
+// Reset database, renaming name of original DB
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::ResetDbL()
+ {
+ RFs fs;
+ User::LeaveIfError( fs.Connect() );
+ CleanupClosePushL( fs );
+
+ TFileName orgPath;
+
+ User::LeaveIfError( fs.PrivatePath( orgPath ) );
+
+ TParse fp;
+ fp.Set( KDatabaseFileName(), &orgPath, 0 );
+ orgPath = fp.FullName();
+
+ TFileName newPath;
+ newPath = orgPath;
+ newPath.Append( KBackupSuffix );
+
+ CFileMan* fileMan = CFileMan::NewL( fs );
+ CleanupStack::PushL( fileMan );
+ User::LeaveIfError( fileMan->Rename( orgPath, newPath ) );
+ CleanupStack::PopAndDestroy( fileMan );
+
+ CleanupStack::PopAndDestroy( &fs );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::DeleteDbL
+// Delete database
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::DeleteDbL()
+ {
+ RFs fs;
+ User::LeaveIfError( fs.Connect() );
+ CleanupClosePushL( fs );
+
+ TFileName orgPath;
+
+ User::LeaveIfError( fs.PrivatePath( orgPath ) );
+
+ TParse fp;
+ fp.Set( KDatabaseFileName(), &orgPath, 0 );
+ orgPath = fp.FullName();
+
+ CFileMan* fileMan = CFileMan::NewL( fs );
+ CleanupStack::PushL( fileMan );
+ User::LeaveIfError( fileMan->Delete( orgPath ) );
+ CleanupStack::PopAndDestroy( fileMan );
+
+ CleanupStack::PopAndDestroy( &fs );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::SettingChangedL
+// Function notify when setting will change
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::SettingChangedL()
+ {
+ //no actions needed
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::CreateFullNameL
+// Create full name using drive MS directory structure and file name.
+// -----------------------------------------------------------------------------
+//
+HBufC* CUpnpMediaServer::CreateFullNameL( RFs &aFs, const TDesC& aDrive,
+ const TDesC& aName )
+ {
+ TParse fp;
+ TFileName path;
+ User::LeaveIfError( aFs.PrivatePath( path ) );
+ fp.Set( aDrive, &path, &aName );
+ User::LeaveIfError( fp.AddDir( KMSPublicAccessedDir() ) );
+ User::LeaveIfError( fp.AddDir( KMSDeviceXmlDescDir() ) );
+ return fp.FullName().AllocL();
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::ShareItemL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::ShareObjectL( CUpnpObject* aItem )
+ {
+ iContentDirecory->ShareObjectL( aItem );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::ShareReferenceL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::ShareReferenceL( CUpnpItem* aItem )
+ {
+ iContentDirecory->ShareReferenceL( aItem );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::ShareReferenceListL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::ShareReferenceListL( CUpnpItemList* aItemList,
+ TInt* aStatus )
+ {
+ iContentDirecory->ShareReferenceListL( aItemList, aStatus );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::ShareItemListL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::ShareItemListL( CUpnpItemList* aItemList, TInt* aStatus )
+ {
+ iContentDirecory->ShareItemListL( aItemList, aStatus );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::UnshareRootL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::UnshareRootL()
+ {
+ TBool online = ETrue;
+
+ if ( Status()==RUpnpMediaServerClient::EStartedOnline )
+ {
+ online = ETrue;
+ }
+ else if ( Status()==RUpnpMediaServerClient::EStartedOffline )
+ {
+ online = EFalse;
+ }
+
+ StopAVMediaServerImmediately( EFalse, EFalse );
+
+ DeleteDbL();
+
+ if ( online )
+ {
+ StartAVMediaServerL();
+ }
+ else
+ {
+ StartAVMediaServerOfflineL();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::UnshareItemL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::UnshareItemL( TInt aId )
+ {
+ iContentDirecory->UnshareItemL( aId );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::UnshareContainerL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::UnshareContainerL( TInt aId )
+ {
+ iContentDirecory->UnshareContainerL( aId );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::GetSharedItemL
+// -----------------------------------------------------------------------------
+//
+CUpnpItem* CUpnpMediaServer::GetSharedItemL( TInt aItem )
+ {
+ return iContentDirecory->GetSharedItemL( aItem );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::GetSingleContainerL
+// -----------------------------------------------------------------------------
+//
+CUpnpContainer* CUpnpMediaServer::GetSingleContainerL( TInt aContainerId )
+ {
+ return iContentDirecory->GetSingleContainerL( aContainerId );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::UnshareItemListL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::UnshareItemListL( RArray<TInt>& aItemList,
+ TInt* aExecutionStatus )
+ {
+ iContentDirecory->UnshareItemListL( aItemList, aExecutionStatus );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::GetSharedItemListL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::GetSharedItemListL( TInt aContId,
+ CUpnpBrowseCriteria* aBrowseCriteria, TInt* TotalMatches,
+ CUpnpItemList* aItemList )
+ {
+ iContentDirecory->GetItemListL( aContId, aBrowseCriteria, TotalMatches,
+ aItemList );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::GetSharedContainerListL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::GetSharedContainerListL( TInt aContId,
+ CUpnpBrowseCriteria* aBrowseCriteria, TInt* TotalMatches,
+ CUpnpContainerList* aContainerList )
+ {
+ iContentDirecory->GetContainerListL( aContId, aBrowseCriteria,
+ TotalMatches, aContainerList );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::GetIpAndPortL
+// -----------------------------------------------------------------------------
+//
+TInetAddr CUpnpMediaServer::GetAddress()
+ {
+ return iContentDirecory->GetAddress();
+ }
+
+// ============================= EVENT FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::SubscribeEvents
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::SubscribeEvents(
+ MUpnpContentDirectoryEventObserver* aObserver )
+ {
+ iObserverList.Append( aObserver );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::UnsubscribeEvents
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::UnsubscribeEvents(
+ MUpnpContentDirectoryEventObserver* aObserver )
+ {
+ TInt index = iObserverList.Find( aObserver );
+ if ( index != KErrNotFound )
+ {
+ iObserverList.Remove( index );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::FileTransferEvent
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::FileTransferEvent( CUpnpFileTransferEvent* aMessage )
+ {
+ for ( TInt i=0; i<iObserverList.Count(); i++ )
+ {
+ iObserverList[i]->FileTransferEvent( aMessage );
+ }
+ delete aMessage;
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::IsInterfaceUp
+// -----------------------------------------------------------------------------
+//
+TBool CUpnpMediaServer::IsInterfaceUp()
+ {
+ return ( iMsStatus == RUpnpMediaServerClient::EStartedOnline );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::CancelAVMediaServerStop
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::CancelAVMediaServerStop()
+ {
+ iStopAVMediaServerTimer->Cancel();
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::CanBeStopped
+// -----------------------------------------------------------------------------
+//
+TBool CUpnpMediaServer::CanBeStopped() const
+ {
+ return RUpnpMediaServerClient::EStopped == Status(); //note: Status(),not iMsStatus
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::TimerEventL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::TimerEventL( CUpnpNotifyTimer* aTimer )
+ {
+ if ( aTimer == iStopAVMediaServerTimer )
+ {
+ StopAVMediaServerImmediately( iIsSilentShutdown, EFalse );
+ }
+ else
+ {
+ CUpnpSymbianServerBase::TimerEventL( aTimer );
+ }
+ }
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::SupportedVersion
+// -----------------------------------------------------------------------------
+//
+TVersion CUpnpMediaServer::SupportedVersion() const
+ {
+ return KServerSupportedVersion;
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::ServerName
+// -----------------------------------------------------------------------------
+//
+const TDesC& CUpnpMediaServer::ServerName() const
+ {
+ return KMediaServerName;
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::NetworkEvent
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::NetworkEvent( CUpnpNetworkEventBase* aEvent )
+ {
+ LOG_FUNC_NAME;
+
+ if ( aEvent->SubscriberError() < KErrNone && aEvent->Type() == EUnknownEvent )
+ {
+ LOGS( "CUpnpMediaServer::NetworkEvent error" );
+ return;
+ }
+
+ switch ( aEvent->Type() )
+ {
+ case EWlanLostEvent:
+ {
+ if ( IsInterfaceUp() )
+ {
+ StopAVMediaServerImmediately( ETrue, ETrue );
+ NotifyStatusChanged();
+ }
+ }
+ break;
+
+ case EAddressChangeEvent:
+ {
+ if ( iMsStatus == RUpnpMediaServerClient::EStartedOnline )
+ {
+ TRAPD( error, RestartAVMediaServerL() );
+ if ( error != KErrNone )
+ {
+ if ( iStopAVMediaServerTimer->IsActive() )
+ {
+ StopAVMediaServerImmediately( EFalse, EFalse );
+ }
+ TRAP( error, StartAVMediaServerL() );
+ if ( error != KErrNone )
+ {
+ StopAVMediaServerImmediately( EFalse, EFalse );
+ NotifyStatusChanged();
+ }
+ }
+ else if ( iContentDirecory )
+ {
+ TRAP( error, iContentDirecory->AddressChangeL() );
+ if ( error != KErrNone )
+ {
+ StopAVMediaServerImmediately( EFalse, EFalse );
+ NotifyStatusChanged();
+ }
+ }
+ }
+ }
+ break;
+
+ case EConnectionClosedEvent:
+ {
+ ASSERT( iMsStatus != RUpnpMediaServerClient::EStartedOnline );
+ }
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::SetStatus
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::SetStatus( RUpnpMediaServerClient::TServerStatus aStatus )
+ {
+ iMsStatus = aStatus;
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::NotifyStatusChanged
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::NotifyStatusChanged()
+ {
+ CUpnpMediaServerSession* ses = NULL;
+ iSessionIter.SetToFirst();
+ CSession2* cses = iSessionIter++;
+ ses = reinterpret_cast<CUpnpMediaServerSession*>( cses );
+ while ( ses )
+ {
+ ses->StatusChanged();
+ ses = reinterpret_cast<CUpnpMediaServerSession*>( iSessionIter++ );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpMediaServer::RunL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMediaServer::RunL()
+ {
+ const RUpnpMediaServerClient::TServerStatus beforeStatus = Status();
+ CUpnpSymbianServerBase::RunL();
+ if ( Status() != beforeStatus )
+ {
+ NotifyStatusChanged();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// E32Main entry point.
+// Returns: KErrNone
+// -----------------------------------------------------------------------------
+//
+TInt E32Main()
+ {
+ return CUpnpMediaServer::StartServer(
+ KMediaServerThreadName, CUpnpMediaServer::NewLC );
+ }
+
+
+// End of File