diff -r 3785f754ee62 -r 5360b7ddc251 upnpavcontroller/upnpavcontrollerserver/src/upnpuploadsession.cpp --- a/upnpavcontroller/upnpavcontrollerserver/src/upnpuploadsession.cpp Fri Sep 17 08:31:21 2010 +0300 +++ b/upnpavcontroller/upnpavcontrollerserver/src/upnpuploadsession.cpp Mon Nov 01 12:37:49 2010 +0200 @@ -1,938 +1,1032 @@ -/* -* Copyright (c) 2007 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 -#include - -// upnpframework / avcontroller helper api -#include "upnpconstantdefs.h" // for upnp-specific stuff -#include "upnpitemutility.h" // FindElementByNameL, GetResElements - -// upnpframework / xmlparser api -#include "upnpxmlparser.h" - -// upnpframework / internal api's -#include "upnpcdsreselementutility.h" -#include "httpuploader.h" -#include "upnpmetadatafetcher.h" -#include "upnpcommonutils.h" - -// INTERNAL INCLUDES -#include "upnpuploadsession.h" -#include "upnpfiletransferitem.h" -#include "upnpavcontrollerserver.h" -#include "upnpfiletransferitem.h" -#include "upnpavdeviceextended.h" -#include "upnpavdispatcher.h" -#include "upnpaverrorhandler.h" -#include "upnpresourcehelper.h" - -_LIT( KComponentLogfile, "upnpavcontrollerserver.txt"); -#include "upnplog.h" - -// CONSTANTS -_LIT8( KImportUri, "importUri" ); -_LIT8( KAsterisk, "*" ); -const TUint32 KBufferSize = 0x40000; // 256K -const TInt KParallerTransfers = 1; - -// ======== MEMBER FUNCTIONS ======== - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::NewL -// See upnpuploadsession.h -// -------------------------------------------------------------------------- -CUPnPUploadSession* CUPnPUploadSession::NewL( CUpnpAVControllerServer& - aServer, TInt aSessionId, const TDesC8& aUuid ) - { - CUPnPUploadSession* self = new (ELeave) CUPnPUploadSession( - aServer, aSessionId ); - CleanupStack::PushL( self ); - self->ConstructL( aUuid ); - CleanupStack::Pop( self ); - return self; - } - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::CUPnPUploadSession -// See upnpuploadsession.h -// -------------------------------------------------------------------------- -CUPnPUploadSession::CUPnPUploadSession( CUpnpAVControllerServer& aServer, - TInt aSessionId ) : - CUPnPFileTransferSessionBase( aServer, aSessionId ), - iResourceIndex( KErrNotFound ), - iAsyncError( KErrNone ), - iIPSessionId( KErrNotFound ), - iSchedulerStopped( ETrue ) - { - } - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::~CUPnPUploadSession -// See upnpuploadsession.h -// -------------------------------------------------------------------------- -CUPnPUploadSession::~CUPnPUploadSession() - { - __LOG( "CUPnPUploadSession::~CUPnPUploadSession" ); - - delete iUploader; - iResources.ResetAndDestroy(); - - __LOG( "CUPnPUploadSession::~CUPnPUploadSession - end" ); - } - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::ConstructL -// See upnpuploadsession.h -// -------------------------------------------------------------------------- -void CUPnPUploadSession::ConstructL( const TDesC8& aUuid ) - { - __LOG( "CUPnPUploadSession::ConstructL" ); - - CUPnPFileTransferSessionBase::ConstructL( aUuid ); - - iUploader = CHttpUploader::NewL( *this, (TUint32)iServer.IAP(), - KBufferSize, KParallerTransfers ); - } - -// -------------------------------------------------------------------------- -// CUPnPDownloadSession::TransferProgress -// See upnpdownloadsession.h -// -------------------------------------------------------------------------- -void CUPnPUploadSession::TransferProgress( TAny* aKey, TInt aBytes, - TInt aTotalBytes ) - { - __LOG( "CUPnPUploadSession::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!" ); - } - } - } - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::ReadyForTransfer -// See upnpdownloadsession.h -// -------------------------------------------------------------------------- -void CUPnPUploadSession::ReadyForTransferL( TAny* aKey ) - { - __LOG( "CUPnPUploadSession::ReadyForTransferL" ); - - TUpnpFileTransferEvent event; - if( FindItemByKey( event, (TInt)aKey, iResourceIndex ) == KErrNone ) - { - ReadyForTransferL( event ); - - event.iEvent = TUpnpFileTransferEvent::ETransferStarted; - Complete( event ); - } - else - { - __LOG( "ReadyForTransfer - Key not found" ); - - // Not found - event.iStatus = KErrGeneral; - event.iParam2 = 0; - event.iEvent = TUpnpFileTransferEvent::ETransferCompleted; - - Complete( event ); - } - } - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::TransferCompleted -// See upnpdownloadsession.h -// -------------------------------------------------------------------------- -void CUPnPUploadSession::TransferCompleted( TAny* aKey, TInt aStatus ) - { - __LOG2( "CUPnPUploadSession::TransferCompleted, key = %d, status = %d", - (TInt)aKey, aStatus ); - - TUpnpFileTransferEvent item; - TInt index; - TInt err = FindItemByKey( item, (TInt)aKey, index ); - if( err == KErrNone ) - { - item.iStatus = UPnPAVErrorHandler::ConvertToSymbianErrorCode( aStatus, - EUPnPHTTPError ); - - item.iEvent = TUpnpFileTransferEvent::ETransferCompleted; - Complete( item ); - - iTransferItems.Remove( index ); - delete iResources[ index ]; - iResources.Remove( index ); - } - else - { - __LOG( "TransferCompleted - Key not found" ); - - // Not found - if( aStatus == KErrCancel ) - { - item.iStatus = aStatus; - } - else - { - 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++ ) - { - iUploader->CancelTransfer( (TAny*)iTransferItems[i].iKey ); - - if( iResources[ i ]->ItemId() ) - { - // Send destroyobject - __LOG( "CancelAllUploadsL - sending destroyobject" ); - TRAP_IGNORE( iServer.ControlPoint().CdsDestroyObjectActionL( - iDevice->Uuid(), *iResources[ i ]->ItemId() ) ); - } - } - iResources.ResetAndDestroy(); - iTransferItems.Reset(); - } - } - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::CdsCreateObjectResponse -// See upnpbrowsingsession.h -// -------------------------------------------------------------------------- -void CUPnPUploadSession::CdsCreateObjectResponse( - const TDesC8& /*aUuid*/, - TInt aSessionId, - TInt aErr, - const TDesC8& /*aContainerID*/, - const TDesC8& /*aElements*/, - const TDesC8& aObjectID, - const TDesC8& aResult ) - { - __LOG1( "CUPnPUploadSession::CdsCreateObjectResponse: %d" , aErr ); - - __ASSERTD( iIPSessionId == aSessionId, __FILE__, __LINE__ ); - - __ASSERTD( iTransferItems.Count() == iResources.Count(), __FILE__, - __LINE__ ); - - iServer.Dispatcher().UnRegister( iIPSessionId ); - iIPSessionId = KErrNotFound; - - aErr = UPnPAVErrorHandler::ConvertToSymbianErrorCode( aErr, - EUPnPContentDirectoryError ); - - if( aErr == KErrNone ) - { - TRAP( aErr, HandleObjectResponseL( aObjectID, aResult ) ); - } - - iAsyncError = aErr; - StopWait(); - } - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::StartUploadL -// See upnpbrowsingsession.h -// -------------------------------------------------------------------------- -void CUPnPUploadSession::StartUploadL( const RMessage2& aMessage ) - { - __LOG( "CUPnPUploadSession::StartUploadL" ); - - __ASSERTD( iTransferItems.Count() == iResources.Count(), __FILE__, - __LINE__ ); - - CUpnpFileTransferItem* tmpTransferItem = CUpnpFileTransferItem::NewLC(); - - ReadTransferItemFromMessageL( aMessage, 1 ,tmpTransferItem ); - - if( CheckIfKeyExists( tmpTransferItem->Key() ) ) - { - User::Leave( KErrInUse ); - } - - TUpnpFileTransferEvent transferItem; - transferItem.iKey = tmpTransferItem->Key(); - - CUpnpItem* tmpUpnpItem = UPnPMetadataFetcher::CreateItemFromFileLC( - tmpTransferItem->Path() ); - - tmpUpnpItem->SetIdL( KNullDesC8 ); - tmpUpnpItem->SetParentIdL( KContainerIdAny ); - tmpUpnpItem->SetRestricted( EFalse ); - - const CUpnpElement& resEl = UPnPItemUtility::FindElementByNameL( - *tmpUpnpItem, KElementRes ); - - const CUpnpAttribute* pInfo = UPnPItemUtility::FindAttributeByName( - resEl, KAttributeProtocolInfo ); - - if( iDevice->DlnaCompatible() ) - { - // Dlna device, additional checks required - __LOG( "StartUploadL - DLNA device" ); - - TPtrC8 objectClass = tmpUpnpItem->ObjectClass(); - if( objectClass.Find( KClassAudio ) != KErrNotFound && - iDevice->AudioUpload() ) - { - // Trying to upload audio and it's supported - } - else if( objectClass.Find( KClassImage ) != KErrNotFound && - iDevice->ImageUpload() ) - { - // Trying to upload images and it's supported - } - else if( objectClass.Find( KClassVideo ) != KErrNotFound && - iDevice->VideoUpload() ) - { - // Trying to upload video and it's supported - } - else - { - // Unknown media type, or copy not supported - __LOG( "StartUploadL - Unknown media type, or copy not \ -supported" ); - User::Leave( KErrNotSupported ); - } - - if( iDevice->ValidateTransfer( pInfo->Value() ) ) - { - __LOG( "StartUploadL - Match by protocolInfo succeeded" ); - // Continue with DLNA upload - // ProtocolInfo is in DLNA format - } - else - { - __LOG( "StartUploadL - Match by protocolInfo failed, upload \ -as UPnP content" ); - // Continue with UPnP upload - // Check the protocolInfo - ProtocolInfoToUPnPL( pInfo ); - } - } - else - { - __LOG( "StartUploadL - UPnP Device -> UPnP upload" ); - // Continue with UPnP upload - // Check the protocolInfo - ProtocolInfoToUPnPL( pInfo ); - } - - iUploader->InsertFileIntoWaitQueueL( (TAny*)transferItem.iKey, - tmpTransferItem->Path(), KNullDesC8 ); - - SetHeadersL( pInfo->Value(), (TAny*)transferItem.iKey ); - - iTransferItems.Append( transferItem ); - - CUPnPResourceHelper* helper = CUPnPResourceHelper::NewL(); - CleanupStack::Pop( tmpUpnpItem ); - helper->SetItem( tmpUpnpItem ); // Transfer ownership - iResources.AppendL( helper ); - - iUploader->MoveToTransferQueueL( (TAny*)transferItem.iKey ); - - CleanupStack::PopAndDestroy( tmpTransferItem ); - - aMessage.Complete( KErrNone ); - - __LOG( "CUPnPUploadSession::StartUploadL - end " ); - } - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::CancelUploadL -// See upnpbrowsingsession.h -// -------------------------------------------------------------------------- -void CUPnPUploadSession::CancelUploadL( const RMessage2& aMessage ) - { - __LOG( "CUPnPUploadSession::CancelUploadL" ); - - __ASSERTD( iTransferItems.Count() == iResources.Count(), __FILE__, - __LINE__ ); - - TInt key = aMessage.Int1(); - - TInt index; - if( CheckIfKeyExists( key, index ) ) - { - iUploader->CancelTransfer( (TAny*)key ); - aMessage.Complete( KErrNone ); - iTransferItems.Remove( index ); - if( iResources[ index ]->ItemId() ) - { - // Send destroyobject - iServer.ControlPoint().CdsDestroyObjectActionL( iDevice->Uuid(), - *iResources[ index ]->ItemId() ); - } - delete iResources[index ]; - iResources.Remove( index ); - } - else - { - aMessage.Complete( KErrNotFound ); - } - - __LOG( "CUPnPUploadSession::CancelUploadL - end" ); - } - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::CancelAllUploadsL -// See upnpbrowsingsession.h -// -------------------------------------------------------------------------- -void CUPnPUploadSession::CancelAllUploadsL( const RMessage2& aMessage ) - { - __LOG( "CUPnPUploadSession::CancelAllUploadsL" ); - - __ASSERTD( iTransferItems.Count() == iResources.Count(), __FILE__, - __LINE__ ); - - TInt count = iTransferItems.Count(); - for( TInt i = 0; i < count; i++ ) - { - iUploader->CancelTransfer( (TAny*)iTransferItems[i].iKey ); - - if( iResources[ i ]->ItemId() ) - { - // Send destroyobject - __LOG( "CancelAllUploadsL - sending destroyobject" ); - iServer.ControlPoint().CdsDestroyObjectActionL( iDevice->Uuid(), - *iResources[ i ]->ItemId() ); - } - } - iResources.ResetAndDestroy(); - iTransferItems.Reset(); - iEventQueu.Reset(); - - // Scheduler loop started, stop it and ignore createobject-resp - __LOG( "CancelAllUploadsL - Un register" ); - iServer.Dispatcher().UnRegister( iIPSessionId ); - iIPSessionId = KErrNotFound; - iAsyncError = KErrCancel; - - __LOG( "CancelAllUploadsL - Stop scheduler loop" ); - StopWait(); - - aMessage.Complete( KErrNone ); - - __LOG( "CUPnPUploadSession::CancelAllUploadsL - end" ); - } - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::StartTrackingUploadProgressL -// See upnpbrowsingsession.h -// -------------------------------------------------------------------------- -void CUPnPUploadSession::StartTrackingUploadProgressL( const RMessage2& - aMessage ) - { - __LOG( "CUPnPUploadSession::StartTrackingUploadProgressL" ); - - TInt key = aMessage.Int1(); - if( CheckIfKeyExists( key ) ) - { - iUploader->TrackProgress( (TAny*)key, ETrue ); - iProgressTrackingEnabled = ETrue; - aMessage.Complete( KErrNone ); - } - else - { - aMessage.Complete( KErrNotFound ); - } - } - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::StopTrackingUploadProgressL -// See upnpbrowsingsession.h -// -------------------------------------------------------------------------- -void CUPnPUploadSession::StopTrackingUploadProgressL( const RMessage2& - aMessage ) - { - __LOG( "CUPnPUploadSession::StopTrackingUploadProgressL" ); - - TInt key = aMessage.Int1(); - if( CheckIfKeyExists( key ) ) - { - iUploader->TrackProgress( (TAny*)key, EFalse ); - iProgressTrackingEnabled = EFalse; - aMessage.Complete( KErrNone ); - } - else - { - aMessage.Complete( KErrNotFound ); - } - } - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::GetUploadEventL -// See upnpbrowsingsession.h -// -------------------------------------------------------------------------- -void CUPnPUploadSession::GetUploadEventL( const RMessage2& aMessage ) - { - __LOG( "CUPnPUploadSession::GetUploadEventL" ); - - if( iEventQueu.Count() ) - { - // There are events in the queu, write the first queued event back - // to client - __LOG1( "GetUploadEventL - events in queu, count = %d", - iEventQueu.Count() ); - TPckg resp1( iEventQueu[0] ); - aMessage.Write( 1, resp1 ); // Write response using slot 1 - aMessage.Complete( KErrNone ); - - iEventQueu.Remove( 0 ); - } - else - { - __ASSERTD( !iEventMsg, __FILE__, __LINE__ ); - __LOG( "GetUploadEventL - Store msg" ); - iEventMsg = new (ELeave) RMessage2( aMessage ); - } - __LOG( "CUPnPUploadSession::GetUploadEventL - end" ); - } - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::CancelGetUploadEventL -// See upnpbrowsingsession.h -// -------------------------------------------------------------------------- -void CUPnPUploadSession::CancelGetUploadEventL( const RMessage2& aMessage ) - { - __LOG( "CUPnPUploadSession::CancelGetUploadEventL" ); - - if( iEventMsg ) - { - iEventMsg->Complete( KErrCancel ); - delete iEventMsg; iEventMsg = NULL; - } - aMessage.Complete( KErrNone ); - } - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::DeviceDisappearedL -// See upnpbrowsingsession.h -// -------------------------------------------------------------------------- -void CUPnPUploadSession::DeviceDisappearedL( - CUpnpAVDeviceExtended& aDevice ) - { - __LOG( "CUPnPUploadSession::DeviceDisappearedL" ); - - if( aDevice.Uuid().Compare( iDevice->Uuid() ) == 0 ) - { - TUpnpFileTransferEvent event; - event.iEvent = TUpnpFileTransferEvent::EDeviceDisconnected; - - Complete( event ); - } - } - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::SetHeadersL -// See upnpbrowsingsession.h -// -------------------------------------------------------------------------- -void CUPnPUploadSession::SetHeadersL( const TDesC8& aInfo, TAny* aKey ) - { - CUpnpDlnaProtocolInfo* tmpInfo = CUpnpDlnaProtocolInfo::NewL( aInfo ); - CleanupStack::PushL( tmpInfo ); - - // Set the content-type header - iUploader->SetHeaderL( aKey, KContentType, - tmpInfo->ThirdField() ); - - // Set the expect header - iUploader->SetHeaderL( aKey, KExpectHeader, K100Continue ); - - CleanupStack::PopAndDestroy( tmpInfo ); - } - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::ReadyForTransferL -// See upnpbrowsingsession.h -// -------------------------------------------------------------------------- -void CUPnPUploadSession::ReadyForTransferL( TUpnpFileTransferEvent& aEvent ) - { - __LOG( "CUPnPUploadSession::ReadyForTransferL" ); - - if ( !iSchedulerStopped || iWait.IsStarted() ) - { - __LOG1( "CUPnPUploadSession::ReadyForTransferL\ - IsStarted = %d", (TInt)iWait.IsStarted() ); - __LOG1( "CUPnPUploadSession::ReadyForTransferL\ - iSchedulerStopped = %d", (TInt)iSchedulerStopped ); - User::Leave( KErrNotReady ); - } - - __ASSERTD( iTransferItems.Count() == iResources.Count(), __FILE__, - __LINE__ ); - - CUpnpItem* tmpUpnpItem = iResources[ iResourceIndex ]->Item(); - if( !tmpUpnpItem ) - { - User::Leave( KErrCorrupt ); - } - - HBufC8* xmlDoc = CUPnPXMLParser::XmlForCreateObjectLC( - *tmpUpnpItem ); - - iIPSessionId = iServer.ControlPoint().CdsCreateObjectActionL( - iDevice->Uuid(), KContainerIdAny, *xmlDoc ); - - if( iIPSessionId > 0 ) - { - // Register - iServer.Dispatcher().RegisterL( iIPSessionId, *this ); - } - else - { - User::Leave( iIPSessionId ); - } - - CleanupStack::PopAndDestroy( xmlDoc ); - - iWait.Start(); - - __LOG1( "CUPnPUploadSession::ReadyForTransferL\ - iAsyncError = %d", iAsyncError ); - - User::LeaveIfError( iAsyncError ); - - const CUpnpElement& resEl = UPnPItemUtility::FindElementByNameL( - *iResources[ iResourceIndex ]->Item(), KElementRes ); - - const CUpnpAttribute* pInfo = UPnPItemUtility::FindAttributeByName( - resEl, KAttributeProtocolInfo ); - - CUpnpDlnaProtocolInfo* tmpInfo = CUpnpDlnaProtocolInfo::NewL( - pInfo->Value() ); - CleanupStack::PushL( tmpInfo ); - - // Set DLNA specific headers - if( tmpInfo->PnParameter().Length() ) - { - // DLNA content, set the content-features header - iUploader->SetHeaderL( (TAny*)aEvent.iKey, KContentFeatures, - tmpInfo->FourthField() ); - - // Check if background mode is available and use it if it is - if( tmpInfo->DlnaFlag( UpnpDlnaProtocolInfo::TM_B_FLAG ) ) - { - __LOG( "ReadyForTransferL - Use background mode" ); - - iUploader->SetHeaderL( (TAny*)aEvent.iKey, KTransferMode, - KBackgroundMode ); - } - else - { - // Background is not available for some reason. - // Check if media specific transfer mode is available - if( UPnPCommonUtils::IsImageSupported( tmpInfo->ProtocolInfoL() ) ) - { - // Uploading image, alternative for background is interactive - if( tmpInfo->DlnaFlag( UpnpDlnaProtocolInfo::TM_I_FLAG ) ) - { - __LOG( "ReadyForTransferL - Use interactive mode" ); - iUploader->SetHeaderL( (TAny*)aEvent.iKey, KTransferMode, - KInteractiveMode ); - } - else - { - // Target DMS does not support appropriate transfer mode - __LOG( "ReadyForTransferL - No appropriate mode" ); - // Still, give a try and use background - iUploader->SetHeaderL( (TAny*)aEvent.iKey, KTransferMode, - KBackgroundMode ); - } - } - else if( UPnPCommonUtils::IsAudioSupported( - tmpInfo->ProtocolInfoL() ) || - UPnPCommonUtils::IsVideoSupported( - tmpInfo->ProtocolInfoL() ) ) - { - // Uploading A/V, alternative for background is streaming - if( tmpInfo->DlnaFlag( UpnpDlnaProtocolInfo::TM_S_FLAG ) ) - { - __LOG( "ReadyForTransferL - Use streaming mode" ); - iUploader->SetHeaderL( (TAny*)aEvent.iKey, KTransferMode, - KStreamingMode ); - } - else - { - // Target DMS does not support appropriate transfer mode - __LOG( "ReadyForTransferL - No appropriate mode" ); - // Still, give a try and use background - iUploader->SetHeaderL( (TAny*)aEvent.iKey, KTransferMode, - KBackgroundMode ); - } - } - else - { - __LOG( "ReadyForTransferL - Unknown media type" ); - } - - } - - } - - CleanupStack::PopAndDestroy( tmpInfo ); - - iUploader->SetPropertyL( (TAny*)aEvent.iKey, - CHttpTransferBase::ETargetURI, - *iResources[ iResourceIndex ]->Resource() ); - - iUploader->StartTransferL( (TAny*)aEvent.iKey ); - - __LOG( "CUPnPUploadSession::ReadyForTransferL - end" ); - } - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::ParseCreateObjectResponseL -// See upnpbrowsingsession.h -// -------------------------------------------------------------------------- -void CUPnPUploadSession::HandleObjectResponseL( const TDesC8& aObjectID, - const TDesC8& aResult ) - { - __LOG( "CUPnPUploadSession::HandleObjectResponseL" ); - - HBufC8* importUri = ParseCreateObjectResponseL( aResult ); - CleanupStack::PushL( importUri ); - - HBufC8* tmpUri = UpnpString::EncodeXmlStringL( importUri ); - CleanupStack::PopAndDestroy( importUri ); - CleanupStack::PushL( tmpUri ); - - HBufC* tmpUri16 = UpnpString::ToUnicodeL( *tmpUri ); - CleanupStack::PopAndDestroy( tmpUri ); - - iResources[ iResourceIndex ]->SetResource( tmpUri16 ); - - HBufC8* tmpID = aObjectID.AllocL(); - iResources[ iResourceIndex ]->SetItemId( tmpID ); - } - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::ParseCreateObjectResponseL -// See upnpbrowsingsession.h -// -------------------------------------------------------------------------- -HBufC8* CUPnPUploadSession::ParseCreateObjectResponseL( - const TDesC8& aResponse ) - { - __LOG( "CUPnPUploadSession::ParseCreateObjectResponseL" ); - - HBufC8* importURI = NULL; - - CUPnPXMLParser* parser = CUPnPXMLParser::NewL(); - CleanupStack::PushL( parser ); - - RPointerArray array; - CleanupResetAndDestroyPushL( array ); - - parser->ParseResultDataL( array, aResponse ); - - TInt count = array.Count(); - - // Lets find the first item with an import URI and use that - for( TInt i = 0; i < count; i++ ) - { - importURI = ImportURIFromItemL( *array[ i ] ); - if( importURI ) - { - // Transfer ownership, casting is safe - // (array[ 0 ]->ObjectType() == EUPnPItem) - CUpnpItem* item = static_cast( array[ i ] ); - iResources[ iResourceIndex ]->SetItem( item ); - array.Remove( i ); - i = count; - } - } - if( !importURI ) // no suitable items, leave - { - User::Leave( KErrGeneral ); - } - - CleanupStack::PopAndDestroy( &array ); - CleanupStack::PopAndDestroy( parser ); - - if( !UpnpCdsResElementUtility::IsUriAbsolute( *importURI ) ) - { - // Import uri is not absolute, upload not supported. leave. - delete importURI; importURI = NULL; - User::Leave( KErrGeneral ); - } - - return importURI; - } - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::ImportURIFromItemL -// See upnpbrowsingsession.h -// -------------------------------------------------------------------------- -HBufC8* CUPnPUploadSession::ImportURIFromItemL( const CUpnpObject& aObject ) - { - HBufC8* importURI = NULL; - if( aObject.ObjectType() == EUPnPItem ) - { - // Get the res-elements - RUPnPElementsArray elArray; - CleanupClosePushL( elArray ); - UPnPItemUtility::GetResElements( aObject, elArray ); - - // Find the import uri - TInt count = elArray.Count(); - for( TInt i = 0; i < count; i++ ) - { - const CUpnpAttribute* attribute = NULL; - attribute = &UPnPItemUtility::FindAttributeByNameL( - *elArray[ i ], KImportUri ); - if( attribute ) - { - // import uri found - i = count; - importURI = attribute->Value().AllocL(); - } - } - CleanupStack::PopAndDestroy( &elArray ); - } - return importURI; - } - -// -------------------------------------------------------------------------- -// CUPnPUploadSession::ProtocolInfoToUPnPL -// See upnpbrowsingsession.h -// -------------------------------------------------------------------------- -void CUPnPUploadSession::ProtocolInfoToUPnPL( const CUpnpAttribute* aInfo ) - { - __LOG( "CUPnPUploadSession::ProtocolInfoToUPnPL" ); - - CUpnpDlnaProtocolInfo* destInfo = - CUpnpDlnaProtocolInfo::NewL( aInfo->Value() ); - CleanupStack::PushL( destInfo ); - - if( destInfo->PnParameter().Length() ) - { - __LOG( "ProtocolInfoToUPnPL - Convert to UPnP" ); - - CUpnpProtocolInfo* targetInfo = CUpnpProtocolInfo::NewL(); - CleanupStack::PushL( targetInfo ); - - targetInfo->SetFirstFieldL( destInfo->FirstField() ); - targetInfo->SetSecondFieldL( KAsterisk ); - targetInfo->SetThirdFieldL( destInfo->ThirdField() ); - targetInfo->SetFourthFieldL( KAsterisk ); - - // A bit dirty const cast.. but makes implementation much easier - CUpnpAttribute* bute = const_cast( aInfo ); - bute->SetValueL( targetInfo->ProtocolInfoL() ); - - CleanupStack::PopAndDestroy( targetInfo ); - } - else - { - __LOG( "ProtocolInfoToUPnPL - UPnP content -> do nothing" ); - // Not DLNA content, do nothing - } - - CleanupStack::PopAndDestroy( destInfo ); - } - -//--------------------------------------------------------------------------- -// CUPnPUploadSession::StopWait() -// See upnpbrowsingsession.h -//--------------------------------------------------------------------------- -// -void CUPnPUploadSession::StopWait() - { - __LOG( "ProtocolInfoToUPnPL::StopWait" ); - if ( iWait.IsStarted() ) - { - if ( iWait.CanStopNow() ) - { - __LOG( "ProtocolInfoToUPnPL::StopWait - stop" ); - iWait.AsyncStop(); - iSchedulerStopped = ETrue; - } - else - { - __LOG( "CUPnPUploadSession::StopWait\ -- not able to stop now, use callback" ); - iSchedulerStopped = EFalse; - iWait.AsyncStop( TCallBack( - SchedulerStoppedCallBack, - this ) ); - } - } - } - -//--------------------------------------------------------------------------- -// CUPnPUploadSession::SchedulerStoppedCallBack() -// See upnpbrowsingsession.h -//--------------------------------------------------------------------------- -// -TInt CUPnPUploadSession::SchedulerStoppedCallBack( TAny* aPtr ) - { - CUPnPUploadSession* self = - static_cast( aPtr ); - self->DoSchedulerStoppedCallBack(); - return 0; - } - -//--------------------------------------------------------------------------- -// CUPnPUploadSession::DoSchedulerStoppedCallBack() -// See upnpbrowsingsession.h -//--------------------------------------------------------------------------- -// -void CUPnPUploadSession::DoSchedulerStoppedCallBack() - { - __LOG( "ProtocolInfoToUPnPL::DoSchedulerStoppedCallBack" ); - iSchedulerStopped = ETrue; - } - -// End of file +/* +* Copyright (c) 2007 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 + +// dlnasrv / mediaserver api +#include +#include +#include + +// dlnasrv / avcontroller helper api +#include "upnpconstantdefs.h" // for upnp-specific stuff +#include "upnpitemutility.h" // FindElementByNameL, GetResElements + +// dlnasrv / xmlparser api +#include "upnpxmlparser.h" + +// dlnasrv / internal api's +#include "upnpcdsreselementutility.h" +#include "httpuploader.h" +#include "upnpmetadatafetcher.h" +#include "upnpcommonutils.h" + +// dlnasrv / avcontroller internal api's +#include "upnpuploadsession.h" +#include "upnpfiletransferitem.h" +#include "upnpavcontrollerserver.h" +#include "upnpfiletransferitem.h" +#include "upnpavdeviceextended.h" +#include "upnpavdispatcher.h" +#include "upnpaverrorhandler.h" +#include "upnpavcpstrings.h" +#include "upnpresourcehelper.h" +#include "upnpavcontrolpoint.h" + +using namespace UpnpAVCPStrings; + +_LIT( KComponentLogfile, "upnpavcontrollerserver.txt"); +#include "upnplog.h" + +// CONSTANTS +_LIT8( KImportUri, "importUri" ); +_LIT8( KAsterisk, "*" ); +const TUint32 KBufferSize = 0x40000; // 256K +const TInt KParallerTransfers = 1; + +// ======== MEMBER FUNCTIONS ======== + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::NewL +// See upnpuploadsession.h +// -------------------------------------------------------------------------- +CUPnPUploadSession* CUPnPUploadSession::NewL( CUpnpAVControllerServer& + aServer, TInt aSessionId, const TDesC8& aUuid ) + { + CUPnPUploadSession* self = new (ELeave) CUPnPUploadSession( + aServer, aSessionId ); + CleanupStack::PushL( self ); + self->ConstructL( aUuid ); + CleanupStack::Pop( self ); + return self; + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::CUPnPUploadSession +// See upnpuploadsession.h +// -------------------------------------------------------------------------- +CUPnPUploadSession::CUPnPUploadSession( CUpnpAVControllerServer& aServer, + TInt aSessionId ) : + CUPnPFileTransferSessionBase( aServer, aSessionId ), + iResourceIndex( KErrNotFound ), + iAsyncError( KErrNone ), + iIPSessionId( KErrNotFound ), + iSchedulerStopped( ETrue ) + { + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::~CUPnPUploadSession +// See upnpuploadsession.h +// -------------------------------------------------------------------------- +CUPnPUploadSession::~CUPnPUploadSession() + { + __LOG( "CUPnPUploadSession::~CUPnPUploadSession" ); + + delete iUploader; + iResources.ResetAndDestroy(); + + __LOG( "CUPnPUploadSession::~CUPnPUploadSession - end" ); + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::ConstructL +// See upnpuploadsession.h +// -------------------------------------------------------------------------- +void CUPnPUploadSession::ConstructL( const TDesC8& aUuid ) + { + __LOG( "CUPnPUploadSession::ConstructL" ); + + CUPnPFileTransferSessionBase::ConstructL( aUuid ); + + iUploader = CHttpUploader::NewL( *this, (TUint32)iServer.IAP(), + KBufferSize, KParallerTransfers ); + + // Gets related ControlPoint device (CUpnpDevice). + // It is needed for CUpnpAVControlPoint. + iCpDevice = iServer.ControlPoint().Device( aUuid ); + if ( !iCpDevice ) + { + User::Leave( KErrNotFound ); + } + + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::ActionResponseL +// From MUpnpAVControlPointObserver +// -------------------------------------------------------------------------- +void CUPnPUploadSession::ActionResponseL( CUpnpAction* aAction ) + { + if (aAction->Name().Compare(KCreateObject) == 0) + { + __ASSERT( iIPSessionId == aAction->SessionId(), + __FILE__, __LINE__ ); + CdsCreateObjectResponse( + aAction->Error(), + aAction->ArgumentValue(KObjectID), + aAction->ArgumentValue(KResult) + ); + } + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::ActionResponseL +// From MUpnpAVControlPointObserver +// -------------------------------------------------------------------------- +void CUPnPUploadSession::StateUpdatedL( CUpnpService* /*aService*/ ) + { + // No implementation required + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::ActionResponseL +// From MUpnpAVControlPointObserver +// -------------------------------------------------------------------------- +void CUPnPUploadSession::HttpResponseL( CUpnpHttpMessage* /*aMessage*/ ) + { + // No implementation required + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::ActionResponseL +// From MUpnpAVControlPointObserver +// -------------------------------------------------------------------------- +void CUPnPUploadSession::DeviceDiscoveredL( CUpnpDevice* /*aDevice*/ ) + { + // No implementation required + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::ActionResponseL +// From MUpnpAVControlPointObserver +// -------------------------------------------------------------------------- +void CUPnPUploadSession::DeviceDisappearedL( CUpnpDevice* /*aDevice*/ ) + { + // No implementation required + } + +// -------------------------------------------------------------------------- +// CUPnPDownloadSession::TransferProgress +// See upnpdownloadsession.h +// -------------------------------------------------------------------------- +void CUPnPUploadSession::TransferProgress( TAny* aKey, TInt aBytes, + TInt aTotalBytes ) + { + __LOG( "CUPnPUploadSession::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!" ); + } + } + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::ReadyForTransfer +// See upnpdownloadsession.h +// -------------------------------------------------------------------------- +void CUPnPUploadSession::ReadyForTransferL( TAny* aKey ) + { + __LOG( "CUPnPUploadSession::ReadyForTransferL" ); + + TUpnpFileTransferEvent event; + if( FindItemByKey( event, (TInt)aKey, iResourceIndex ) == KErrNone ) + { + ReadyForTransferL( event ); + + event.iEvent = TUpnpFileTransferEvent::ETransferStarted; + Complete( event ); + } + else + { + __LOG( "ReadyForTransfer - Key not found" ); + + // Not found + event.iStatus = KErrGeneral; + event.iParam2 = 0; + event.iEvent = TUpnpFileTransferEvent::ETransferCompleted; + + Complete( event ); + } + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::TransferCompleted +// See upnpdownloadsession.h +// -------------------------------------------------------------------------- +void CUPnPUploadSession::TransferCompleted( TAny* aKey, TInt aStatus ) + { + __LOG2( "CUPnPUploadSession::TransferCompleted, key = %d, status = %d", + (TInt)aKey, aStatus ); + + TUpnpFileTransferEvent item; + TInt index; + TInt err = FindItemByKey( item, (TInt)aKey, index ); + if( err == KErrNone ) + { + item.iStatus = UPnPAVErrorHandler::ConvertToSymbianErrorCode( aStatus, + EUPnPHTTPError ); + + item.iEvent = TUpnpFileTransferEvent::ETransferCompleted; + Complete( item ); + + iTransferItems.Remove( index ); + delete iResources[ index ]; + iResources.Remove( index ); + } + else + { + __LOG( "TransferCompleted - Key not found" ); + + // Not found + if( aStatus == KErrCancel ) + { + item.iStatus = aStatus; + } + else + { + 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++ ) + { + iUploader->CancelTransfer( (TAny*)iTransferItems[i].iKey ); + + if( iResources[ i ]->ItemId() ) + { + // Send destroyobject + __LOG( "CancelAllUploadsL - sending destroyobject" ); + TRAP_IGNORE( DestroyObjectL( *iResources[ i ]->ItemId() ) ); + } + } + iResources.ResetAndDestroy(); + iTransferItems.Reset(); + } + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::CdsCreateObjectResponse +// See upnpbrowsingsession.h +// -------------------------------------------------------------------------- +void CUPnPUploadSession::CdsCreateObjectResponse( + TInt aErr, + const TDesC8& aObjectID, + const TDesC8& aResult ) + { + __LOG1( "CUPnPUploadSession::CdsCreateObjectResponse: %d" , aErr ); + + __ASSERTD( iTransferItems.Count() == iResources.Count(), __FILE__, + __LINE__ ); + + iServer.Dispatcher().UnRegister( iIPSessionId ); + iIPSessionId = KErrNotFound; + + aErr = UPnPAVErrorHandler::ConvertToSymbianErrorCode( aErr, + EUPnPContentDirectoryError ); + + if( aErr == KErrNone ) + { + TRAP( aErr, HandleObjectResponseL( aObjectID, aResult ) ); + } + + iAsyncError = aErr; + StopWait(); + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::StartUploadL +// See upnpbrowsingsession.h +// -------------------------------------------------------------------------- +void CUPnPUploadSession::StartUploadL( const RMessage2& aMessage ) + { + __LOG( "CUPnPUploadSession::StartUploadL" ); + + __ASSERTD( iTransferItems.Count() == iResources.Count(), __FILE__, + __LINE__ ); + + CUpnpFileTransferItem* tmpTransferItem = CUpnpFileTransferItem::NewLC(); + + ReadTransferItemFromMessageL( aMessage, 1 ,tmpTransferItem ); + + if( CheckIfKeyExists( tmpTransferItem->Key() ) ) + { + User::Leave( KErrInUse ); + } + + TUpnpFileTransferEvent transferItem; + transferItem.iKey = tmpTransferItem->Key(); + + CUpnpItem* tmpUpnpItem = UPnPMetadataFetcher::CreateItemFromFileLC( + tmpTransferItem->Path() ); + + tmpUpnpItem->SetIdL( KNullDesC8 ); + tmpUpnpItem->SetParentIdL( KContainerIdAny ); + tmpUpnpItem->SetRestricted( EFalse ); + + const CUpnpElement& resEl = UPnPItemUtility::FindElementByNameL( + *tmpUpnpItem, KElementRes ); + + const CUpnpAttribute* pInfo = UPnPItemUtility::FindAttributeByName( + resEl, KAttributeProtocolInfo ); + + if( iDevice->DlnaCompatible() ) + { + // Dlna device, additional checks required + __LOG( "StartUploadL - DLNA device" ); + + TPtrC8 objectClass = tmpUpnpItem->ObjectClass(); + if( objectClass.Find( KClassAudio ) != KErrNotFound && + iDevice->AudioUpload() ) + { + // Trying to upload audio and it's supported + } + else if( objectClass.Find( KClassImage ) != KErrNotFound && + iDevice->ImageUpload() ) + { + // Trying to upload images and it's supported + } + else if( objectClass.Find( KClassVideo ) != KErrNotFound && + iDevice->VideoUpload() ) + { + // Trying to upload video and it's supported + } + else + { + // Unknown media type, or copy not supported + __LOG( "StartUploadL - Unknown media type, or copy not \ +supported" ); + User::Leave( KErrNotSupported ); + } + + if( iDevice->ValidateTransfer( pInfo->Value() ) ) + { + __LOG( "StartUploadL - Match by protocolInfo succeeded" ); + // Continue with DLNA upload + // ProtocolInfo is in DLNA format + } + else + { + __LOG( "StartUploadL - Match by protocolInfo failed, upload \ +as UPnP content" ); + // Continue with UPnP upload + // Check the protocolInfo + ProtocolInfoToUPnPL( pInfo ); + } + } + else + { + __LOG( "StartUploadL - UPnP Device -> UPnP upload" ); + // Continue with UPnP upload + // Check the protocolInfo + ProtocolInfoToUPnPL( pInfo ); + } + + iUploader->InsertFileIntoWaitQueueL( (TAny*)transferItem.iKey, + tmpTransferItem->Path(), KNullDesC8 ); + + SetHeadersL( pInfo->Value(), (TAny*)transferItem.iKey ); + + iTransferItems.Append( transferItem ); + + CUPnPResourceHelper* helper = CUPnPResourceHelper::NewL(); + CleanupStack::Pop( tmpUpnpItem ); + CleanupStack::PushL( helper ); + helper->SetItem( tmpUpnpItem ); // Transfer ownership + if( iResources.Append( helper )!= KErrNone ) + { + CleanupStack::PopAndDestroy( helper ); + } + CleanupStack::Pop( helper ); + + iUploader->MoveToTransferQueueL( (TAny*)transferItem.iKey ); + + CleanupStack::PopAndDestroy( tmpTransferItem ); + + aMessage.Complete( KErrNone ); + + __LOG( "CUPnPUploadSession::StartUploadL - end " ); + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::CancelUploadL +// See upnpbrowsingsession.h +// -------------------------------------------------------------------------- +void CUPnPUploadSession::CancelUploadL( const RMessage2& aMessage ) + { + __LOG( "CUPnPUploadSession::CancelUploadL" ); + + __ASSERTD( iTransferItems.Count() == iResources.Count(), __FILE__, + __LINE__ ); + + TInt key = aMessage.Int1(); + + TInt index; + if( CheckIfKeyExists( key, index ) ) + { + iUploader->CancelTransfer( (TAny*)key ); + aMessage.Complete( KErrNone ); + iTransferItems.Remove( index ); + if( iResources[ index ]->ItemId() ) + { + // Send destroyobject + DestroyObjectL( *iResources[ index ]->ItemId() ); + } + delete iResources[index ]; + iResources.Remove( index ); + } + else + { + aMessage.Complete( KErrNotFound ); + } + + __LOG( "CUPnPUploadSession::CancelUploadL - end" ); + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::CancelAllUploadsL +// See upnpbrowsingsession.h +// -------------------------------------------------------------------------- +void CUPnPUploadSession::CancelAllUploadsL( const RMessage2& aMessage ) + { + __LOG( "CUPnPUploadSession::CancelAllUploadsL" ); + + __ASSERTD( iTransferItems.Count() == iResources.Count(), __FILE__, + __LINE__ ); + + TInt count = iTransferItems.Count(); + for( TInt i = 0; i < count; i++ ) + { + iUploader->CancelTransfer( (TAny*)iTransferItems[i].iKey ); + + if( iResources[ i ]->ItemId() ) + { + // Send destroyobject + __LOG( "CancelAllUploadsL - sending destroyobject" ); + DestroyObjectL( *iResources[ i ]->ItemId() ); + } + } + iResources.ResetAndDestroy(); + iTransferItems.Reset(); + iEventQueu.Reset(); + + // Scheduler loop started, stop it and ignore createobject-resp + __LOG( "CancelAllUploadsL - Un register" ); + iServer.Dispatcher().UnRegister( iIPSessionId ); + iIPSessionId = KErrNotFound; + iAsyncError = KErrCancel; + + __LOG( "CancelAllUploadsL - Stop scheduler loop" ); + StopWait(); + + aMessage.Complete( KErrNone ); + + __LOG( "CUPnPUploadSession::CancelAllUploadsL - end" ); + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::StartTrackingUploadProgressL +// See upnpbrowsingsession.h +// -------------------------------------------------------------------------- +void CUPnPUploadSession::StartTrackingUploadProgressL( const RMessage2& + aMessage ) + { + __LOG( "CUPnPUploadSession::StartTrackingUploadProgressL" ); + + TInt key = aMessage.Int1(); + if( CheckIfKeyExists( key ) ) + { + iUploader->TrackProgress( (TAny*)key, ETrue ); + iProgressTrackingEnabled = ETrue; + aMessage.Complete( KErrNone ); + } + else + { + aMessage.Complete( KErrNotFound ); + } + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::StopTrackingUploadProgressL +// See upnpbrowsingsession.h +// -------------------------------------------------------------------------- +void CUPnPUploadSession::StopTrackingUploadProgressL( const RMessage2& + aMessage ) + { + __LOG( "CUPnPUploadSession::StopTrackingUploadProgressL" ); + + TInt key = aMessage.Int1(); + if( CheckIfKeyExists( key ) ) + { + iUploader->TrackProgress( (TAny*)key, EFalse ); + iProgressTrackingEnabled = EFalse; + aMessage.Complete( KErrNone ); + } + else + { + aMessage.Complete( KErrNotFound ); + } + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::GetUploadEventL +// See upnpbrowsingsession.h +// -------------------------------------------------------------------------- +void CUPnPUploadSession::GetUploadEventL( const RMessage2& aMessage ) + { + __LOG( "CUPnPUploadSession::GetUploadEventL" ); + + if( iEventQueu.Count() ) + { + // There are events in the queu, write the first queued event back + // to client + __LOG1( "GetUploadEventL - events in queu, count = %d", + iEventQueu.Count() ); + TPckg resp1( iEventQueu[0] ); + aMessage.Write( 1, resp1 ); // Write response using slot 1 + aMessage.Complete( KErrNone ); + + iEventQueu.Remove( 0 ); + } + else + { + __ASSERTD( !iEventMsg, __FILE__, __LINE__ ); + __LOG( "GetUploadEventL - Store msg" ); + iEventMsg = new (ELeave) RMessage2( aMessage ); + } + __LOG( "CUPnPUploadSession::GetUploadEventL - end" ); + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::CancelGetUploadEventL +// See upnpbrowsingsession.h +// -------------------------------------------------------------------------- +void CUPnPUploadSession::CancelGetUploadEventL( const RMessage2& aMessage ) + { + __LOG( "CUPnPUploadSession::CancelGetUploadEventL" ); + + if( iEventMsg ) + { + iEventMsg->Complete( KErrCancel ); + delete iEventMsg; iEventMsg = NULL; + } + aMessage.Complete( KErrNone ); + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::DeviceDisappearedL +// See upnpbrowsingsession.h +// -------------------------------------------------------------------------- +void CUPnPUploadSession::DeviceDisappearedL( + CUpnpAVDeviceExtended& aDevice ) + { + __LOG( "CUPnPUploadSession::DeviceDisappearedL" ); + + if( aDevice.Uuid().Compare( iDevice->Uuid() ) == 0 ) + { + TUpnpFileTransferEvent event; + event.iEvent = TUpnpFileTransferEvent::EDeviceDisconnected; + + Complete( event ); + } + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::SetHeadersL +// See upnpbrowsingsession.h +// -------------------------------------------------------------------------- +void CUPnPUploadSession::SetHeadersL( const TDesC8& aInfo, TAny* aKey ) + { + CUpnpDlnaProtocolInfo* tmpInfo = CUpnpDlnaProtocolInfo::NewL( aInfo ); + CleanupStack::PushL( tmpInfo ); + + // Set the content-type header + iUploader->SetHeaderL( aKey, KContentType, + tmpInfo->ThirdField() ); + + // Set the expect header + iUploader->SetHeaderL( aKey, KExpectHeader, K100Continue ); + + CleanupStack::PopAndDestroy( tmpInfo ); + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::ReadyForTransferL +// See upnpbrowsingsession.h +// -------------------------------------------------------------------------- +void CUPnPUploadSession::ReadyForTransferL( TUpnpFileTransferEvent& aEvent ) + { + __LOG( "CUPnPUploadSession::ReadyForTransferL" ); + + if ( !iSchedulerStopped || iWait.IsStarted() ) + { + __LOG1( "CUPnPUploadSession::ReadyForTransferL\ + IsStarted = %d", (TInt)iWait.IsStarted() ); + __LOG1( "CUPnPUploadSession::ReadyForTransferL\ + iSchedulerStopped = %d", (TInt)iSchedulerStopped ); + User::Leave( KErrNotReady ); + } + + __ASSERTD( iTransferItems.Count() == iResources.Count(), __FILE__, + __LINE__ ); + + CUpnpItem* tmpUpnpItem = iResources[ iResourceIndex ]->Item(); + if( !tmpUpnpItem ) + { + User::Leave( KErrCorrupt ); + } + + HBufC8* xmlDoc = CUPnPXMLParser::XmlForCreateObjectLC( + *tmpUpnpItem ); + + iIPSessionId = CreateObjectL( KContainerIdAny, *xmlDoc ); + + // Register + iServer.Dispatcher().RegisterL( iIPSessionId, *this ); + + CleanupStack::PopAndDestroy( xmlDoc ); + + iWait.Start(); + + __LOG1( "CUPnPUploadSession::ReadyForTransferL\ + iAsyncError = %d", iAsyncError ); + + User::LeaveIfError( iAsyncError ); + + const CUpnpElement& resEl = UPnPItemUtility::FindElementByNameL( + *iResources[ iResourceIndex ]->Item(), KElementRes ); + + const CUpnpAttribute* pInfo = UPnPItemUtility::FindAttributeByName( + resEl, KAttributeProtocolInfo ); + + CUpnpDlnaProtocolInfo* tmpInfo = CUpnpDlnaProtocolInfo::NewL( + pInfo->Value() ); + CleanupStack::PushL( tmpInfo ); + + // Set DLNA specific headers + if( tmpInfo->PnParameter().Length() ) + { + // DLNA content, set the content-features header + iUploader->SetHeaderL( (TAny*)aEvent.iKey, KContentFeatures, + tmpInfo->FourthField() ); + + // Check if background mode is available and use it if it is + if( tmpInfo->DlnaFlag( UpnpDlnaProtocolInfo::TM_B_FLAG ) ) + { + __LOG( "ReadyForTransferL - Use background mode" ); + + iUploader->SetHeaderL( (TAny*)aEvent.iKey, KTransferMode, + KBackgroundMode ); + } + else + { + // Background is not available for some reason. + // Check if media specific transfer mode is available + if( UPnPCommonUtils::IsImageSupported( + tmpInfo->ProtocolInfoL() ) ) + { + // Uploading image, alternative for background is interactive + if( tmpInfo->DlnaFlag( UpnpDlnaProtocolInfo::TM_I_FLAG ) ) + { + __LOG( "ReadyForTransferL - Use interactive mode" ); + iUploader->SetHeaderL( (TAny*)aEvent.iKey, KTransferMode, + KInteractiveMode ); + } + else + { + // Target DMS does not support appropriate transfer mode + __LOG( "ReadyForTransferL - No appropriate mode" ); + // Still, give a try and use background + iUploader->SetHeaderL( (TAny*)aEvent.iKey, KTransferMode, + KBackgroundMode ); + } + } + else if( UPnPCommonUtils::IsAudioSupported( + tmpInfo->ProtocolInfoL() ) || + UPnPCommonUtils::IsVideoSupported( + tmpInfo->ProtocolInfoL() ) ) + { + // Uploading A/V, alternative for background is streaming + if( tmpInfo->DlnaFlag( UpnpDlnaProtocolInfo::TM_S_FLAG ) ) + { + __LOG( "ReadyForTransferL - Use streaming mode" ); + iUploader->SetHeaderL( (TAny*)aEvent.iKey, KTransferMode, + KStreamingMode ); + } + else + { + // Target DMS does not support appropriate transfer mode + __LOG( "ReadyForTransferL - No appropriate mode" ); + // Still, give a try and use background + iUploader->SetHeaderL( (TAny*)aEvent.iKey, KTransferMode, + KBackgroundMode ); + } + } + else + { + __LOG( "ReadyForTransferL - Unknown media type" ); + } + + } + + } + + CleanupStack::PopAndDestroy( tmpInfo ); + + iUploader->SetPropertyL( (TAny*)aEvent.iKey, + CHttpTransferBase::ETargetURI, + *iResources[ iResourceIndex ]->Resource() ); + + iUploader->StartTransferL( (TAny*)aEvent.iKey ); + + __LOG( "CUPnPUploadSession::ReadyForTransferL - end" ); + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::ParseCreateObjectResponseL +// See upnpbrowsingsession.h +// -------------------------------------------------------------------------- +void CUPnPUploadSession::HandleObjectResponseL( const TDesC8& aObjectID, + const TDesC8& aResult ) + { + __LOG( "CUPnPUploadSession::HandleObjectResponseL" ); + + HBufC8* importUri = ParseCreateObjectResponseL( aResult ); + CleanupStack::PushL( importUri ); + + HBufC8* tmpUri = UpnpString::EncodeXmlStringL( importUri ); + CleanupStack::PopAndDestroy( importUri ); + CleanupStack::PushL( tmpUri ); + + HBufC* tmpUri16 = UpnpString::ToUnicodeL( *tmpUri ); + CleanupStack::PopAndDestroy( tmpUri ); + + iResources[ iResourceIndex ]->SetResource( tmpUri16 ); + + HBufC8* tmpID = aObjectID.AllocL(); + iResources[ iResourceIndex ]->SetItemId( tmpID ); + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::ParseCreateObjectResponseL +// See upnpbrowsingsession.h +// -------------------------------------------------------------------------- +HBufC8* CUPnPUploadSession::ParseCreateObjectResponseL( + const TDesC8& aResponse ) + { + __LOG( "CUPnPUploadSession::ParseCreateObjectResponseL" ); + + HBufC8* importURI = NULL; + + CUPnPXMLParser* parser = CUPnPXMLParser::NewL(); + CleanupStack::PushL( parser ); + + RPointerArray array; + CleanupResetAndDestroyPushL( array ); + + parser->ParseResultDataL( array, aResponse ); + + TInt count = array.Count(); + + // Lets find the first item with an import URI and use that + for( TInt i = 0; i < count; i++ ) + { + importURI = ImportURIFromItemL( *array[ i ] ); + if( importURI ) + { + // Transfer ownership, casting is safe + // (array[ 0 ]->ObjectType() == EUPnPItem) + CUpnpItem* item = static_cast( array[ i ] ); + iResources[ iResourceIndex ]->SetItem( item ); + array.Remove( i ); + i = count; + } + } + if( !importURI ) // no suitable items, leave + { + User::Leave( KErrGeneral ); + } + + CleanupStack::PopAndDestroy( &array ); + CleanupStack::PopAndDestroy( parser ); + + if( !UpnpCdsResElementUtility::IsUriAbsolute( *importURI ) ) + { + // Import uri is not absolute, upload not supported. leave. + delete importURI; importURI = NULL; + User::Leave( KErrGeneral ); + } + + return importURI; + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::ImportURIFromItemL +// See upnpbrowsingsession.h +// -------------------------------------------------------------------------- +HBufC8* CUPnPUploadSession::ImportURIFromItemL( const CUpnpObject& aObject ) + { + HBufC8* importURI = NULL; + if( aObject.ObjectType() == EUPnPItem ) + { + // Get the res-elements + RUPnPElementsArray elArray; + CleanupClosePushL( elArray ); + UPnPItemUtility::GetResElements( aObject, elArray ); + + // Find the import uri + TInt count = elArray.Count(); + for( TInt i = 0; i < count; i++ ) + { + const CUpnpAttribute* attribute = NULL; + attribute = &UPnPItemUtility::FindAttributeByNameL( + *elArray[ i ], KImportUri ); + if( attribute ) + { + // import uri found + i = count; + importURI = attribute->Value().AllocL(); + } + } + CleanupStack::PopAndDestroy( &elArray ); + } + return importURI; + } + +// -------------------------------------------------------------------------- +// CUPnPUploadSession::ProtocolInfoToUPnPL +// See upnpbrowsingsession.h +// -------------------------------------------------------------------------- +void CUPnPUploadSession::ProtocolInfoToUPnPL( const CUpnpAttribute* aInfo ) + { + __LOG( "CUPnPUploadSession::ProtocolInfoToUPnPL" ); + + CUpnpDlnaProtocolInfo* destInfo = + CUpnpDlnaProtocolInfo::NewL( aInfo->Value() ); + CleanupStack::PushL( destInfo ); + + if( destInfo->PnParameter().Length() ) + { + __LOG( "ProtocolInfoToUPnPL - Convert to UPnP" ); + + CUpnpProtocolInfo* targetInfo = CUpnpProtocolInfo::NewL(); + CleanupStack::PushL( targetInfo ); + + targetInfo->SetFirstFieldL( destInfo->FirstField() ); + targetInfo->SetSecondFieldL( KAsterisk ); + targetInfo->SetThirdFieldL( destInfo->ThirdField() ); + targetInfo->SetFourthFieldL( KAsterisk ); + + // A bit dirty const cast.. but makes implementation much easier + CUpnpAttribute* bute = const_cast( aInfo ); + bute->SetValueL( targetInfo->ProtocolInfoL() ); + + CleanupStack::PopAndDestroy( targetInfo ); + } + else + { + __LOG( "ProtocolInfoToUPnPL - UPnP content -> do nothing" ); + // Not DLNA content, do nothing + } + + CleanupStack::PopAndDestroy( destInfo ); + } + +//--------------------------------------------------------------------------- +// CUPnPUploadSession::StopWait() +// See upnpbrowsingsession.h +//--------------------------------------------------------------------------- +// +void CUPnPUploadSession::StopWait() + { + __LOG( "ProtocolInfoToUPnPL::StopWait" ); + if ( iWait.IsStarted() ) + { + if ( iWait.CanStopNow() ) + { + __LOG( "ProtocolInfoToUPnPL::StopWait - stop" ); + iWait.AsyncStop(); + iSchedulerStopped = ETrue; + } + else + { + __LOG( "CUPnPUploadSession::StopWait\ +- not able to stop now, use callback" ); + iSchedulerStopped = EFalse; + iWait.AsyncStop( TCallBack( + SchedulerStoppedCallBack, + this ) ); + } + } + } + +//--------------------------------------------------------------------------- +// CUPnPUploadSession::SchedulerStoppedCallBack() +// See upnpbrowsingsession.h +//--------------------------------------------------------------------------- +// +TInt CUPnPUploadSession::SchedulerStoppedCallBack( TAny* aPtr ) + { + CUPnPUploadSession* self = + static_cast( aPtr ); + self->DoSchedulerStoppedCallBack(); + return 0; + } + +//--------------------------------------------------------------------------- +// CUPnPUploadSession::DoSchedulerStoppedCallBack() +// See upnpbrowsingsession.h +//--------------------------------------------------------------------------- +// +void CUPnPUploadSession::DoSchedulerStoppedCallBack() + { + __LOG( "ProtocolInfoToUPnPL::DoSchedulerStoppedCallBack" ); + iSchedulerStopped = ETrue; + } + +//--------------------------------------------------------------------------- +// CUPnPUploadSession::CreateObjectL() +//--------------------------------------------------------------------------- +// +int CUPnPUploadSession::CreateObjectL( const TDesC8& aContainerId, + const TDesC8& aElements ) + { + CUpnpAction* action = iServer.ControlPoint().CreateActionLC( + iCpDevice, KContentDirectory, KCreateObject ); + + action->SetArgumentL( KContainerID, aContainerId ); + action->SetArgumentL( KElements, aElements ); + + iServer.ControlPoint().SendL( action ); + CleanupStack::Pop( action ); + if (action->SessionId() < 0) + { + User::Leave( action->SessionId() ); + } + return action->SessionId(); + } + +//--------------------------------------------------------------------------- +// CUPnPUploadSession::DestroyObjectL() +//--------------------------------------------------------------------------- +// +int CUPnPUploadSession::DestroyObjectL( const TDesC8& aObjectId ) + { + CUpnpAction* action = iServer.ControlPoint().CreateActionLC( + iCpDevice, KContentDirectory, KDestroyObject ); + + action->SetArgumentL( KObjectID, aObjectId ); + + iServer.ControlPoint().SendL( action ); + CleanupStack::Pop( action ); + if (action->SessionId() < 0) + { + User::Leave( action->SessionId() ); + } + return action->SessionId(); + } + +// End of file