diff -r 000000000000 -r 7f85d04be362 upnpavcontroller/upnpavcontrollerserver/src/upnpuploadsession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/upnpavcontroller/upnpavcontrollerserver/src/upnpuploadsession.cpp Thu Dec 17 08:52:00 2009 +0200 @@ -0,0 +1,938 @@ +/* +* 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.Append( 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