diff -r 000000000000 -r 7f85d04be362 upnpavcontroller/upnpavcontrollerserver/src/upnpdownloadsession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/upnpavcontroller/upnpavcontrollerserver/src/upnpdownloadsession.cpp Thu Dec 17 08:52:00 2009 +0200 @@ -0,0 +1,589 @@ +/* +* Copyright (c) 2008 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: server impl. of session against media server +* +*/ + + + + + + +// INCLUDE FILES +// System +#include + +// upnp stack api +#include +#include +#include +#include + +// upnpframework / avcontroller helper api +#include "upnpconstantdefs.h" // for upnp-specific stuff + +// upnpframework / internal api's +#include "upnpcommonutils.h" +#include "httpdownloader.h" + +// avcontroller internal +#include "upnpdownloadsession.h" +#include "upnpavdeviceextended.h" +#include "upnpfiletransferitem.h" +#include "upnpavcontrollerserver.h" +#include "upnpaverrorhandler.h" + +_LIT( KComponentLogfile, "upnpavcontrollerserver.txt"); +#include "upnplog.h" + +// CONSTANTS +const TUint32 KBufferSize = 0x40000; // 256K +const TInt KParallerTransfers = 1; + +// ======== MEMBER FUNCTIONS ======== + +// -------------------------------------------------------------------------- +// CUPnPDownloadSession::NewL +// See upnpdownloadsession.h +// -------------------------------------------------------------------------- +CUPnPDownloadSession* CUPnPDownloadSession::NewL( CUpnpAVControllerServer& + aServer, TInt aSessionId, const TDesC8& aUuid ) + { + __LOG( "CUPnPDownloadSession::NewL" ); + + CUPnPDownloadSession* self = new (ELeave) CUPnPDownloadSession( + aServer, aSessionId ); + CleanupStack::PushL( self ); + self->ConstructL( aUuid ); + CleanupStack::Pop( self ); + return self; + } + +// -------------------------------------------------------------------------- +// CUPnPDownloadSession::CUPnPDownloadSession +// See upnpdownloadsession.h +// -------------------------------------------------------------------------- +CUPnPDownloadSession::CUPnPDownloadSession( CUpnpAVControllerServer& + aServer, TInt aSessionId ) : + CUPnPFileTransferSessionBase( aServer, aSessionId ) + { + __LOG( "CUPnPDownloadSession::CUPnPDownloadSession" ); + + } + +// -------------------------------------------------------------------------- +// CUPnPDownloadSession::~CUPnPDownloadSession +// See upnpdownloadsession.h +// -------------------------------------------------------------------------- +CUPnPDownloadSession::~CUPnPDownloadSession() + { + __LOG( "CUPnPDownloadSession::~CUPnPDownloadSession" ); + + delete iDownloader; + + __LOG( "CUPnPDownloadSession::~CUPnPDownloadSession - end" ); + } + +// -------------------------------------------------------------------------- +// CUPnPDownloadSession::ConstructL +// See upnpdownloadsession.h +// -------------------------------------------------------------------------- +void CUPnPDownloadSession::ConstructL( const TDesC8& aUuid ) + { + __LOG( "CUPnPDownloadSession::ConstructL" ); + + CUPnPFileTransferSessionBase::ConstructL( aUuid ); + + iDownloader = CHttpDownloader::NewL( *this, (TUint32)iServer.IAP(), + KBufferSize, KParallerTransfers ); + } + +// -------------------------------------------------------------------------- +// CUPnPDownloadSession::TransferProgress +// See upnpdownloadsession.h +// -------------------------------------------------------------------------- +void CUPnPDownloadSession::TransferProgress( TAny* aKey, TInt aBytes, + TInt aTotalBytes ) + { + __LOG( "CUPnPDownloadSession::TransferProgress" ); + + if( iProgressTrackingEnabled ) + { + TUpnpFileTransferEvent item; + TInt err = FindItemByKey( item, (TInt)aKey ); + if( err == KErrNone ) + { + item.iStatus = KErrNone; + item.iParam2 = aTotalBytes; + item.iParam1 = aBytes; + item.iEvent = TUpnpFileTransferEvent::ETransferProgress; + + Complete( item ); + } + else + { + __LOG( "TransferProgress - Not enabled!" ); + } + } + } + +// -------------------------------------------------------------------------- +// CUPnPDownloadSession::ReadyForTransfer +// See upnpdownloadsession.h +// -------------------------------------------------------------------------- +void CUPnPDownloadSession::ReadyForTransferL( TAny* aKey ) + { + __LOG( "CUPnPDownloadSession::ReadyForTransfer" ); + + TUpnpFileTransferEvent item; + TInt err = FindItemByKey( item, (TInt)aKey ); + if( err == KErrNone ) + { + iDownloader->StartTransferL( aKey ); + + item.iEvent = TUpnpFileTransferEvent::ETransferStarted; + Complete( item ); + } + else + { + __LOG( "ReadyForTransfer - key not found" ); + + // Not found + item.iStatus = KErrGeneral; + item.iParam2 = 0; + item.iEvent = TUpnpFileTransferEvent::ETransferCompleted; + + Complete( item ); + } + } + +// -------------------------------------------------------------------------- +// CUPnPDownloadSession::TransferCompleted +// See upnpdownloadsession.h +// -------------------------------------------------------------------------- +void CUPnPDownloadSession::TransferCompleted( TAny* aKey, TInt aStatus ) + { + __LOG( "CUPnPDownloadSession::TransferCompleted" ); + + TUpnpFileTransferEvent item; + TInt index; + TInt err = FindItemByKey( item, (TInt)aKey, index ); + if( err == KErrNone ) + { + item.iStatus = UPnPAVErrorHandler::ConvertToSymbianErrorCode( + aStatus, + EUPnPHTTPError ); + item.iEvent = TUpnpFileTransferEvent::ETransferCompleted; + item.iParam3 = 0; + + const HBufC* path = NULL; + TRAPD( err, path = iDownloader->GetPropertyL( aKey, + CHttpTransferBase::ETargetPath ) ); + + if( iEventMsg ) + { + if( err == KErrNone && path ) + { + // Write path using slot 2 + iEventMsg->Write( 2, *path ); + } + else + { + __LOG( "Error in path handling" ); + } + } + else + { + if( err == KErrNone && path ) + { + HBufC* buf = HBufC::New( path->Length() ); + if( buf ) + { + buf->Des().Copy( *path ); + item.iParam3 = (TAny*)buf; + } + else + { + __LOG( "Error in path handling" ); + } + } + } + Complete( item ); + + iTransferItems.Remove( index ); + } + else + { + // Corresponding key was not found! + __LOG( "TransferCompleted - key not found" ); + + // Not found + item.iStatus = KErrGeneral; + item.iParam2 = 0; + item.iEvent = TUpnpFileTransferEvent::ETransferCompleted; + + Complete( item ); + } + + if( aStatus == KErrDisconnected ) + { + __LOG( "TransferCompleted - Target device lost" ); + + TInt count = iTransferItems.Count(); + for( TInt i = 0; i < count; i++ ) + { + iDownloader->CancelTransfer( (TAny*)iTransferItems[i].iKey ); + } + iTransferItems.Reset(); + iEventQueu.Reset(); + } + } + +// -------------------------------------------------------------------------- +// CUPnPDownloadSession::StartDownloadL +// See upnpdownloadsession.h +// -------------------------------------------------------------------------- +void CUPnPDownloadSession::StartDownloadL( const RMessage2& aMessage ) + { + __LOG( "CUPnPDownloadSession::StartDownloadL" ); + + CUpnpFileTransferItem* tmpTransferItem = CUpnpFileTransferItem::NewLC(); + + ReadTransferItemFromMessageL( aMessage, 1 ,tmpTransferItem ); + + TUpnpFileTransferEvent transferItem; + + if( CheckIfKeyExists( tmpTransferItem->Key() ) ) + { + User::Leave( KErrInUse ); + } + + transferItem.iKey = tmpTransferItem->Key(); + + HBufC* path = HBufC::NewLC( KMaxPath ); + if( tmpTransferItem->Path() == KNullDesC ) + { + // Read path from the settings + CUpnpMediaServerSettings* msSettings = + CUpnpMediaServerSettings::NewL(); + CleanupStack::PushL( msSettings ); + + HBufC8* buf = msSettings->GetL( + UpnpMediaServerSettings::EUploadDirectory ); + + CleanupStack::PopAndDestroy( msSettings ); + + path->Des().Copy( *buf ); + delete buf; + } + else + { + // Get path from the transfer item + path->Des().Copy( tmpTransferItem->Path() ); + } + + __LOG8( tmpTransferItem->Title() ); + + HBufC* title16 = UpnpString::ToUnicodeL( tmpTransferItem->Title() ); + CleanupStack::PushL( title16 ); + + HBufC* title16checked = + UPnPCommonUtils::ReplaceIllegalFilenameCharactersL( *title16 ); + CleanupStack::PopAndDestroy( title16 ); + CleanupStack::PushL( title16checked ); + + CUpnpDlnaProtocolInfo* tmpInfo = CUpnpDlnaProtocolInfo::NewL( + tmpTransferItem->ProtocolInfo() ); + CleanupStack::PushL( tmpInfo ); + HBufC* fileExt = UPnPCommonUtils::FileExtensionByMimeTypeL( + tmpInfo->ThirdField() ); + path->Des().Append( *title16checked ); + + if( fileExt ) + { + path->Des().Append( *fileExt ); + delete fileExt; + } + + iDownloader->InsertFileIntoWaitQueueL( (TAny*)transferItem.iKey, + *path, tmpTransferItem->Uri() ); + + SetHeadersL( *tmpInfo, (TAny*)transferItem.iKey ); + CleanupStack::PopAndDestroy( tmpInfo ); + CleanupStack::PopAndDestroy( title16checked ); + + iTransferItems.Append( transferItem ); + + iDownloader->MoveToTransferQueueL( (TAny*)transferItem.iKey ); + + CleanupStack::PopAndDestroy( path ); + + CleanupStack::PopAndDestroy( tmpTransferItem ); + + aMessage.Complete( KErrNone ); + } + +// -------------------------------------------------------------------------- +// CUPnPDownloadSession::StartDownloadFHL +// See upnpdownloadsession.h +// -------------------------------------------------------------------------- +void CUPnPDownloadSession::StartDownloadFHL( const RMessage2& aMessage ) + { + __LOG( "CUPnPDownloadSession::StartDownloadFHL" ); + + RFile fHandle; + // handle is stored in slots 2 and 3 + User::LeaveIfError( fHandle.AdoptFromClient( aMessage, 2, 3 ) ); + CleanupClosePushL( fHandle ); + + CUpnpFileTransferItem* tmpTransferItem = CUpnpFileTransferItem::NewLC(); + + ReadTransferItemFromMessageL( aMessage, 1 ,tmpTransferItem ); + + TUpnpFileTransferEvent transferItem; + transferItem.iKey = tmpTransferItem->Key(); + + if( CheckIfKeyExists( tmpTransferItem->Key() ) ) + { + User::Leave( KErrInUse ); + } + + CUpnpDlnaProtocolInfo* tmpInfo = CUpnpDlnaProtocolInfo::NewL( + tmpTransferItem->ProtocolInfo() ); + CleanupStack::PushL( tmpInfo ); + + iDownloader->InsertFileIntoWaitQueueL( (TAny*)transferItem.iKey, fHandle, + tmpTransferItem->Uri() ); + + SetHeadersL( *tmpInfo, (TAny*)transferItem.iKey ); + + CleanupStack::PopAndDestroy( tmpInfo ); + + iTransferItems.Append( transferItem ); + + iDownloader->MoveToTransferQueueL( (TAny*)transferItem.iKey ); + + CleanupStack::PopAndDestroy( tmpTransferItem ); + + CleanupStack::PopAndDestroy( &fHandle ); + + aMessage.Complete( KErrNone ); + } + +// -------------------------------------------------------------------------- +// CUPnPDownloadSession::CancelDownloadL +// See upnpdownloadsession.h +// -------------------------------------------------------------------------- +void CUPnPDownloadSession::CancelDownloadL( const RMessage2& aMessage ) + { + __LOG( "CUPnPDownloadSession::CancelDownloadL" ); + + TInt key = aMessage.Int1(); + + TInt index; + if( CheckIfKeyExists( key, index ) ) + { + iDownloader->CancelTransfer( (TAny*)key ); + aMessage.Complete( KErrNone ); + iTransferItems.Remove( index ); + } + else + { + aMessage.Complete( KErrNotFound ); + } + + } + +// -------------------------------------------------------------------------- +// CUPnPDownloadSession::CancelAllDownloadsL +// See upnpdownloadsession.h +// -------------------------------------------------------------------------- +void CUPnPDownloadSession::CancelAllDownloadsL( const RMessage2& aMessage ) + { + __LOG( "CUPnPDownloadSession::CancelAllDownloadsL" ); + + TInt count = iTransferItems.Count(); + for( TInt i = 0; i < count; i++ ) + { + iDownloader->CancelTransfer( (TAny*)iTransferItems[i].iKey ); + } + iTransferItems.Reset(); + iEventQueu.Reset(); + aMessage.Complete( KErrNone ); + } + +// -------------------------------------------------------------------------- +// CUPnPDownloadSession::StartTrackingDownloadProgressL +// See upnpdownloadsession.h +// -------------------------------------------------------------------------- +void CUPnPDownloadSession::StartTrackingDownloadProgressL( + const RMessage2& aMessage ) + { + __LOG( "CUPnPDownloadSession::StartTrackingDownloadProgressL" ); + + TInt key = aMessage.Int1(); + if( CheckIfKeyExists( key ) ) + { + iDownloader->TrackProgress( (TAny*)key, ETrue ); + iProgressTrackingEnabled = ETrue; + aMessage.Complete( KErrNone ); + } + else + { + aMessage.Complete( KErrNotFound ); + } + } + +// -------------------------------------------------------------------------- +// CUPnPDownloadSession::StopTrackingDownloadProgressL +// See upnpdownloadsession.h +// -------------------------------------------------------------------------- +void CUPnPDownloadSession::StopTrackingDownloadProgressL( + const RMessage2& aMessage ) + { + __LOG( "CUPnPDownloadSession::StopTrackingDownloadProgressL" ); + + TInt key = aMessage.Int1(); + if( CheckIfKeyExists( key ) ) + { + iDownloader->TrackProgress( (TAny*)key, EFalse ); + iProgressTrackingEnabled = EFalse; + aMessage.Complete( KErrNone ); + } + else + { + aMessage.Complete( KErrNotFound ); + } + } + +// -------------------------------------------------------------------------- +// CUPnPDownloadSession::GetDownloadEventL +// See upnpdownloadsession.h +// -------------------------------------------------------------------------- +void CUPnPDownloadSession::GetDownloadEventL( const RMessage2& aMessage ) + { + __LOG( "CUPnPDownloadSession::GetDownloadEventL" ); + + if( iEventQueu.Count() ) + { + __LOG1( "GetDownloadEventL, events in queu: %d", + iEventQueu.Count() ); + + // There are events in the queu, write the first queued event back + // to client + TUpnpFileTransferEvent event = iEventQueu[0]; + iEventQueu.Remove( 0 ); + TPckg resp1( event ); + + if( event.iEvent == + TUpnpFileTransferEvent::ETransferCompleted && + event.iParam3 ) + { + // Write path using slot 2 + __LOG16( *( (HBufC*)event.iParam3 ) ); + aMessage.Write( 2, *( (HBufC*)event.iParam3 ) ); + delete (HBufC*)event.iParam3; + } + aMessage.Write( 1, resp1 ); // Write event using slot 1 + aMessage.Complete( KErrNone ); + } + else + { + iEventMsg = new (ELeave) RMessage2( aMessage ); + } + __LOG( "CUPnPDownloadSession::GetDownloadEventL - end" ); + } + +// -------------------------------------------------------------------------- +// CUPnPDownloadSession::CancelGetDownloadEventL +// See upnpdownloadsession.h +// -------------------------------------------------------------------------- +void CUPnPDownloadSession::CancelGetDownloadEventL( + const RMessage2& aMessage ) + { + __LOG( "CUPnPDownloadSession::CancelGetDownloadEventL" ); + + if( iEventMsg ) + { + iEventMsg->Complete( KErrCancel ); + delete iEventMsg; iEventMsg = NULL; + } + aMessage.Complete( KErrNone ); + } + +void CUPnPDownloadSession::DeviceDisappearedL( + CUpnpAVDeviceExtended& aDevice ) + { + __LOG( "CUPnPDownloadSession::DeviceDisappearedL" ); + + if( aDevice.Uuid().Compare( iDevice->Uuid() ) == 0 ) + { + TUpnpFileTransferEvent event; + event.iEvent = TUpnpFileTransferEvent::EDeviceDisconnected; + + Complete( event ); + } + } + +// -------------------------------------------------------------------------- +// CUPnPDownloadSession::SetHeadersL +// See upnpdownloadsession.h +// -------------------------------------------------------------------------- +void CUPnPDownloadSession::SetHeadersL( CUpnpDlnaProtocolInfo& aInfo, + TAny* aKey ) + { + __LOG( "CUPnPDownloadSession::SetHeadersL" ); + + // Check supported transfermodes + // We MUST use background, if it's supported + if( aInfo.DlnaFlag( UpnpDlnaProtocolInfo::TM_B_FLAG ) ) + { + iDownloader->SetHeaderL( aKey, KTransferMode, KBackgroundMode ); + } + else if( aInfo.DlnaFlag( UpnpDlnaProtocolInfo::TM_S_FLAG ) ) + { + iDownloader->SetHeaderL( aKey, KTransferMode, KStreamingMode ); + } + else if( aInfo.DlnaFlag( UpnpDlnaProtocolInfo::TM_I_FLAG ) ) + { + iDownloader->SetHeaderL( aKey, KTransferMode, KInteractiveMode ); + } + else + { + __LOG( "SetHeadersL - No DLNA flags" ); + + // Transfermode is not defined by any flag + // Correction for HALA-7B6FA5 + if( UPnPCommonUtils::IsImageSupported( aInfo.ProtocolInfoL() ) ) + { + __LOG( "SetHeadersL - Image -> Interactive" ); + // It's an image, we should use Interactive-mode + iDownloader->SetHeaderL( aKey, KTransferMode, KInteractiveMode ); + } + else if( + UPnPCommonUtils::IsAudioSupported( aInfo.ProtocolInfoL() ) || + UPnPCommonUtils::IsVideoSupported( aInfo.ProtocolInfoL() ) ) + { + __LOG( "SetHeadersL - A/V -> Streaming" ); + iDownloader->SetHeaderL( aKey, KTransferMode, KStreamingMode ); + } + else + { + __LOG( "SetHeadersL - Unknown type -> No mode" ); + // It' something other + } + } + } + +// End of file