upnpavcontrolpoint/avcpengine/src/upnpbrowsecommand.cpp
author hgs
Mon, 04 Oct 2010 13:32:20 +0300
changeset 34 eab116a48b80
parent 0 7f85d04be362
permissions -rw-r--r--
201039_02

/** @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<TInt> 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];
     CleanupStack::PushL(TCleanupItem(CleanupArray, dirs));
      for (TInt i = 0; i < size; i++) 
      	{
         dirs[i] = iResult[i];
      	}
      TPtr8 result(reinterpret_cast<TUint8*>(dirs), sizeof(TFileInfo)*size, sizeof(TFileInfo)*size);          
      aMessage.WriteL(1, result);  
	  CleanupStack::PopAndDestroy(dirs);
	}
	
// -----------------------------------------------------------------------------
// CUpnpBrowseCommand::CleanupArray
// -----------------------------------------------------------------------------
// 
void CUpnpBrowseCommand::CleanupArray(TAny* aDirs)
    {
    TFileInfo* dirs = (TFileInfo*) aDirs ;
    delete[] dirs;
    }


// -----------------------------------------------------------------------------
// CUpnpBrowseCommand::SetAttForObject
// -----------------------------------------------------------------------------
// 
TBool CUpnpBrowseCommand::SetAttForObject(RArray<TFileInfo>& 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<TInt> 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<TFileInfo> 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<TFileInfo> 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