diff -r 000000000000 -r 7f85d04be362 upnpavcontrolpoint/avcpengine/src/upnpbrowsecommand.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/upnpavcontrolpoint/avcpengine/src/upnpbrowsecommand.cpp Thu Dec 17 08:52:00 2009 +0200 @@ -0,0 +1,345 @@ +/** @file +* Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: CUpnpBrowseCommand +* +*/ + + +#include "upnpbrowsecommand.h" + +#include "upnppathresolver.h" +#include "upnppathelement.h" +#include "upnpavcpmanager.h" +#include "upnpavcontrolpoint.h" + +#include "upnphttpmessagefactory.h" +#include "upnpstring.h" +#include "upnpcons.h" + +#include "upnpavcpenginehelper.h" +using namespace UpnpAVCPEngine; + +// ----------------------------------------------------------------------------- +// CUpnpBrowseCommand::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CUpnpBrowseCommand* CUpnpBrowseCommand::NewL(CUpnpAVCPManager& aAVCPManager, CUpnpAVCPEngineSession& aSession, const RMessage2& aMessage) + { + CUpnpBrowseCommand* self = new( ELeave ) CUpnpBrowseCommand(aAVCPManager, aSession, aMessage); + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + +// ----------------------------------------------------------------------------- +// CUpnpBrowseCommand::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CUpnpBrowseCommand::ConstructL() + { + CUpnpCommand::BaseConstructL(); + } + +// ----------------------------------------------------------------------------- +// CUpnpBrowseCommand::CUpnpBrowseCommand +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +CUpnpBrowseCommand::CUpnpBrowseCommand(CUpnpAVCPManager& aAVCPManager, + CUpnpAVCPEngineSession& aSession, + const RMessage2& aMessage): + CUpnpCommand( aAVCPManager, + aSession, + aMessage) + { + } + +// ----------------------------------------------------------------------------- +// CUpnpBrowseCommand::~CUpnpBrowseCommand +// desctructor +// ----------------------------------------------------------------------------- +// +CUpnpBrowseCommand::~CUpnpBrowseCommand() + { + delete iObjectId; + delete iObjectName; + iResult.Reset(); + } + +// ----------------------------------------------------------------------------- +// CUpnpBrowseCommand::SessionId +// ----------------------------------------------------------------------------- +// +TInt CUpnpBrowseCommand::SessionId() + { + return CUpnpCommand::SessionId(); + } + +// ----------------------------------------------------------------------------- +// CUpnpBrowseCommand::RunError +// ----------------------------------------------------------------------------- +// +void CUpnpBrowseCommand::RunError(TInt aErrorCode) + { + return CUpnpCommand::RunError(aErrorCode); + } + +// ----------------------------------------------------------------------------- +// CUpnpBrowseCommand::ExecuteL +// ----------------------------------------------------------------------------- +// +void CUpnpBrowseCommand::ExecuteL() + { + //ASSERT(iType == EPrepareDirList || iType == EDirAttributes || iType == EFileAttributes); + + HBufC8* uuid = NULL; + HBufC8* path = NULL; + if (iType == EPrepareDirList) + { + DEBUGSTRING(("Execute Browse command (dir listing)")); + // set command id + TPckg numPckg(iId); + iMessage.WriteL(0, numPckg); + + uuid = ReadDes8FromMessageLC(2); + DEBUGSTRING8((" uuid: %S",uuid)); + path = ReadDes8FromMessageLC(3); + DEBUGSTRING8((" path: %S",path)); + } + else + { + DEBUGSTRING(("Execute Browse command (attributes)")); + uuid = ReadDes8FromMessageLC(0); + DEBUGSTRING8((" uuid: %S",uuid)); + path = ReadDes8FromMessageLC(1); + DEBUGSTRING8((" path: %S",path)); + } + + iPathResolver = &(iAVCPManager.PathResolverL(*uuid, &iSession)); + DEBUGSTRING(("Resolve path %S", path)); + iPathResolver->ResolveIdL(*path, *this); + + CleanupStack::PopAndDestroy(path); + CleanupStack::PopAndDestroy(uuid); + } + +// ----------------------------------------------------------------------------- +// CUpnpBrowseCommand::SetResultL +// ----------------------------------------------------------------------------- +// +void CUpnpBrowseCommand::SetResultL(const RMessage2& aMessage) + { + //ASSERT(aMessage.Function() == EDownloadDirList); + + TInt size = iResult.Count(); + TFileInfo* dirs = new TFileInfo[size]; + for (TInt i = 0; i < size; i++) + { + dirs[i] = iResult[i]; + } + TPtr8 result(reinterpret_cast(dirs), sizeof(TFileInfo)*size, sizeof(TFileInfo)*size); + aMessage.WriteL(1, result); + delete[] dirs; + } + + +// ----------------------------------------------------------------------------- +// CUpnpBrowseCommand::SetAttForObject +// ----------------------------------------------------------------------------- +// +TBool CUpnpBrowseCommand::SetAttForObject(RArray& aList, const TDesC8& aName) + { + TBool result(EFalse); + for (TInt i = 0; i < aList.Count(); i++) + { + if (aList[i].iName.Compare(aName) == 0) + { + iAttr = aList[i]; + result = ETrue; + break; + } + } + return result; + } + +// ----------------------------------------------------------------------------- +// CUpnpBrowseCommand::SendHeadRequestL +// ----------------------------------------------------------------------------- +// +void CUpnpBrowseCommand::SendHeadRequestL(const TDesC8& aUrl) + { + DEBUGSTRING8(("Send HTTP HEAD request for %S", &aUrl)); + + HBufC8* resURIencoded = UpnpString::StringReplaceL(aUrl, _L8(" "), _L8("%20")); + + // we want wait for HEAD to get more info + CleanupStack::PushL(resURIencoded); + CUpnpHttpMessage* msg = RUpnpHttpMessageFactory::HttpHeadL( *resURIencoded ); + CleanupStack::PopAndDestroy(resURIencoded); + + CleanupStack::PushL( msg ); + + iAVCPManager.SendL(msg); + iSessionId = msg->SessionId(); + iAVCPManager.RegisterForHttp(*this); + + CleanupStack::PopAndDestroy( msg ); + } + +// ----------------------------------------------------------------------------- +// CUpnpBrowseCommand::Interpret +// ----------------------------------------------------------------------------- +// +void CUpnpBrowseCommand::InterpretL(TInt aErrorCode, CUpnpAction* aAction) + { + DEBUGSTRING(("Interpret action response %d", aErrorCode)); + if (aErrorCode == EHttp200Ok ) + { + + TInt startIndex = StrToIntL( aAction->ArgumentValue( KStartingIndex ) ); + TInt requestCount = StrToIntL( aAction->ArgumentValue( KRequestedCount ) ); + + TInt numberReturned = StrToIntL( aAction->ArgumentValue( KNumberReturned ) ); + TInt totalMatches = StrToIntL( aAction->ArgumentValue( KTotalMatches ) ); + + HBufC8* resURI = NULL; + + if (iType == EFileAttributes) + { + iPathResolver->ParseBrowseResponseL( aAction->ArgumentValue( KResult ), &iResult, *iObjectId, &resURI); + } + else + { + iPathResolver->LockReset(); + iPathResolver->ParseBrowseResponseL( aAction->ArgumentValue( KResult ), &iResult); + } + + if (iType == EPrepareDirList) + { + + if ( startIndex+numberReturned < totalMatches) + { + iStartIndex += KRequestedCountLimit; + iSessionId = iAVCPManager.CdsBrowseActionL(iPathResolver->UUID(),*iObjectId, KBrowseDirectChildren, KDefaultBrowseFilter, iStartIndex, KRequestedCountLimit, KNullDesC8); + iAVCPManager.RegisterForAction(*this); + } + else + { + iPathResolver->UnlockReset(); + TInt num(iResult.Count()); + TPckg numPckg(num); + // size of directory list + iMessage.WriteL(1, numPckg); + iMessage.Complete(KErrNone); + // don't destroy and wait for next command + } + } + else + { + if (SetAttForObject(iResult, *iObjectName)) + { + if (iType == EFileAttributes && resURI) + { + CleanupStack::PushL(resURI); + SendHeadRequestL(*resURI); + CleanupStack::PopAndDestroy(resURI); + resURI = NULL; + } + else + { + TPckg attrPckg(iAttr); + iMessage.WriteL(2,attrPckg); + iMessage.Complete(KErrNone); + delete this; + } + } + else + { + iMessage.Complete(KErrNotFound); + delete resURI; + delete this; + } + } + } + else + { + iPathResolver->UnlockReset(); + iMessage.Complete(KErrAbort); + delete this; + } + + } + +// ----------------------------------------------------------------------------- +// CUpnpBrowseCommand::Interpret +// ----------------------------------------------------------------------------- +// +void CUpnpBrowseCommand::InterpretL(TInt aErrorCode, CUpnpHttpMessage* aMessage) + { + DEBUGSTRING(("HTTP Interpret %d", aErrorCode)); + // transfer pending + if (aErrorCode == KHttpGetStarted) + { + return; + } + iAVCPManager.UnregisterForHttp(*this); + if (aErrorCode == EHttp200Ok || aErrorCode == EHttpPartialContent) + { + // set some attrs + iAttr.iMimeType = aMessage->GetHeaderValue(UpnpHTTP::KHdrContentType); + TDesC8& size = aMessage->GetHeaderValue(UpnpHTTP::KHdrContentLength); + TLex8 intLex( size ); + intLex.Val( iAttr.iSize ); + } + + TPckg attrPckg(iAttr); + iMessage.WriteL(2,attrPckg); + iMessage.Complete(KErrNone); + delete this; + } + +// ----------------------------------------------------------------------------- +// CUpnpBrowseCommand::ResolvedId +// ----------------------------------------------------------------------------- +// +void CUpnpBrowseCommand::ResolvedIdL(TInt aErrCode, CUpnpPathElement* aIdElement) + { + DEBUGSTRING(("ResolvedId %d", aErrCode)); + if (aErrCode == KErrNone) + { + iObjectId = aIdElement->Id().AllocL(); + iObjectName = aIdElement->Name().AllocL(); + DEBUGSTRING(("Resolved object %S %S", iObjectId, iObjectName)); + if (iType == EPrepareDirList) + { + iSessionId = iAVCPManager.CdsBrowseActionL(iPathResolver->UUID(), *iObjectId, KBrowseDirectChildren, KDefaultBrowseFilter, iStartIndex, KRequestedCountLimit, KNullDesC8); + } + else + { + iSessionId = iAVCPManager.CdsBrowseActionL(iPathResolver->UUID(), *iObjectId, KBrowseMetadata, KDefaultBrowseFilter, 0, 0, KNullDesC8); + } + iAVCPManager.RegisterForAction(*this); + } + else + { + iMessage.Complete(KErrNotFound); + delete this; + } + } +// End of File