--- 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 <mmf/common/mmfcontrollerpluginresolver.h>
-
-// upnp stack api
-#include <upnpitem.h>
-#include <upnpattribute.h>
-#include <upnpstring.h>
-#include <upnpdlnaprotocolinfo.h>
-#include <upnpavcontrolpoint.h>
-
-// 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<TUpnpFileTransferEvent> 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<CUpnpObject> 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<CUpnpItem*>( 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<CUpnpAttribute*>( 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<CUPnPUploadSession*>( 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 <mmf/common/mmfcontrollerpluginresolver.h>
+
+// upnp stack api
+#include <upnpstring.h>
+
+// dlnasrv / mediaserver api
+#include <upnpitem.h>
+#include <upnpattribute.h>
+#include <upnpdlnaprotocolinfo.h>
+
+// 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<TUpnpFileTransferEvent> 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<CUpnpObject> 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<CUpnpItem*>( 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<CUpnpAttribute*>( 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<CUPnPUploadSession*>( 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