/* ------------------------------------------------------------------
 * Copyright (C) 1998-2009 PacketVideo
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 * -------------------------------------------------------------------
 */

#include "pvmf_downloadmanager_node.h"
#include "pvmf_download_data_source.h"
#include "pvmf_local_data_source.h"
#include "pvmf_protocol_engine_factory.h"
#include "pvmf_socket_factory.h"
#include "pvmf_socket_node.h"
#include "pvlogger.h"
#include "oscl_error_codes.h"
#include "oscl_str_ptr_len.h" // for OSCL_ASCII_CASE_MAGIC_BIT
#include "pvmi_datastreamuser_interface.h"
#include "pvpvxparser.h"
#include "pv_mime_string_utils.h"
#include "pvmi_kvp_util.h"
#include "pvmf_source_context_data.h"

//Log levels for node commands
#define CMD_LOG_LEVEL PVLOGMSG_INFO
//Log levels for subnode commands.
#define SUB_CMD_LOG_LEVEL PVLOGMSG_INFO


///////////////////////////////////////////////////////////////////////////////
//
// Capability and config interface related constants and definitions
//   - based on pv_player_engine.h
//
///////////////////////////////////////////////////////////////////////////////

static const DownloadManagerKeyStringData DownloadManagerConfig_BaseKeys[] =
{
    {"user-agent", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_WCHARPTR},
    {"http-version", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32},
    {"http-timeout", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32},
    {"download-progress-info", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_CHARPTR},
    {"protocol-extension-header", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_CHARPTR},
    {"num-redirect-attempts", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32},
    {"http-header-request-disabled", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_BOOL},
    {"max-tcp-recv-buffer-size-download", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32},
    {"max-tcp-recv-buffer-count-download", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32}
};

static const uint DownloadManagerConfig_NumBaseKeys =
    (sizeof(DownloadManagerConfig_BaseKeys) /
     sizeof(DownloadManagerKeyStringData));

enum BaseKeys_IndexMapType
{
    BASEKEY_SESSION_CONTROLLER_USER_AGENT = 0,
    BASEKEY_SESSION_CONTROLLER_HTTP_VERSION,
    BASEKEY_SESSION_CONTROLLER_HTTP_TIMEOUT,
    BASEKEY_SESSION_CONTROLLER_DOWNLOAD_PROGRESS_INFO,
    BASEKEY_SESSION_CONTROLLER_PROTOCOL_EXTENSION_HEADER,
    BASEKEY_SESSION_CONTROLLER_NUM_REDIRECT_ATTEMPTS,
    BASEKEY_SESSION_CONTROLLER_NUM_HTTP_HEADER_REQUEST_DISABLED,
    BASEKEY_MAX_TCP_RECV_BUFFER_SIZE,
    BASEKEY_MAX_TCP_RECV_BUFFER_COUNT
};



PVMFDownloadManagerNode::PVMFDownloadManagerNode(int32 aPriority)
        : OsclActiveObject(aPriority, "PVMFDownloadManagerNode")
{
    int32 err;
    OSCL_TRY(err, ConstructL(););
    if (err != OsclErrNone)
    {
        //if a leave happened, cleanup and re-throw the error
        iInputCommands.clear();
        iCurrentCommand.clear();
        iCancelCommand.clear();
        iCapability.iInputFormatCapability.clear();
        iCapability.iOutputFormatCapability.clear();
        OSCL_CLEANUP_BASE_CLASS(PVMFNodeInterface);
        OSCL_CLEANUP_BASE_CLASS(OsclActiveObject);
        OSCL_LEAVE(err);
    }

    iDNodeUuids.clear();
    iDNodeUuidCount = 0;
}

void PVMFDownloadManagerNode::ConstructL()
{
    iDebugMode = false;
    iLogger = NULL;
    iExtensionRefCount = 0;
    iSourceFormat = PVMF_MIME_FORMAT_UNKNOWN;
    iMimeType = PVMF_MIME_FORMAT_UNKNOWN;
    iSourceData = NULL;
    iPlayBackClock = NULL;
    iClockNotificationsInf = NULL;

    iNoPETrackSelect = false;
    iMovieAtomComplete = false;
    iParserInitAfterMovieAtom = false;
    iParserPrepareAfterMovieAtom = false;

    iParserInit = false;
    iDataReady = false;
    iDownloadComplete = false;
    iRecognizerError = false;

    iInitFailedLicenseRequired = false;

    iProtocolEngineNodePort = NULL;
    iSocketNodePort = NULL;
    iPlayerNodeRegistry = NULL;

    //create the sub-node command queue.  Use a reserve to avoid dynamic memory failure later.
    //Max depth is the max number of sub-node commands for any one node command. Init command may take up to 15
    iSubNodeCmdVec.reserve(15);

    //Create the input command queue. Max depth is undetermined -- just reserve 10.
    iInputCommands.Construct(1000 //start cmd id
                             , 10);//reserve.

    //Create the "current command" queue. Max depth is 1 for each of these.
    iCurrentCommand.Construct(0, 1);
    iCancelCommand.Construct(0, 1);

    //create node containers.
    //@TODO this will create unused node containers.  think about
    //optimizing it.
    iFormatParserNode.Construct(PVMFDownloadManagerSubNodeContainerBase::EFormatParser, this);
    iProtocolEngineNode.Construct(PVMFDownloadManagerSubNodeContainerBase::EProtocolEngine, this);
    iSocketNode.Construct(PVMFDownloadManagerSubNodeContainerBase::ESocket, this);
    iRecognizerNode.Construct(PVMFDownloadManagerSubNodeContainerBase::ERecognizer, this);

    //Set the node capability data.
    iCapability.iCanSupportMultipleInputPorts = false;
    iCapability.iCanSupportMultipleOutputPorts = true;
    iCapability.iHasMaxNumberOfPorts = true;
    iCapability.iMaxNumberOfPorts = 6;
    iCapability.iInputFormatCapability.push_back(PVMF_MIME_MPEG4FF);
    iCapability.iInputFormatCapability.push_back(PVMF_MIME_ASFFF);
    iCapability.iInputFormatCapability.push_back(PVMF_MIME_RMFF);
    iCapability.iOutputFormatCapability.push_back(PVMF_MIME_AMR_IETF);
    iCapability.iOutputFormatCapability.push_back(PVMF_MIME_MPEG4_AUDIO);
    iCapability.iOutputFormatCapability.push_back(PVMF_MIME_M4V);
    iCapability.iOutputFormatCapability.push_back(PVMF_MIME_H2631998);
    iCapability.iOutputFormatCapability.push_back(PVMF_MIME_H2632000);
    iCapability.iOutputFormatCapability.push_back(PVMF_MIME_REAL_VIDEO);
    iCapability.iOutputFormatCapability.push_back(PVMF_MIME_WMV);
    iCapability.iOutputFormatCapability.push_back(PVMF_MIME_DIVXFF);

    iFileBufferDatastreamFactory = NULL;
#if(PVMF_DOWNLOADMANAGER_SUPPORT_PPB)
    iMemoryBufferDatastreamFactory = NULL;
#endif//PVMF_DOWNLOADMANAGER_SUPPORT_PPB

    iDownloadFileName = NULL;
    iContentTypeMIMEString = NULL;

    iProtocolEngineNode.iNode = PVMFProtocolEngineNodeFactory::CreatePVMFProtocolEngineNode(OsclActiveObject::EPriorityNominal);
    OsclError::LeaveIfNull(iProtocolEngineNode.iNode);
    iProtocolEngineNode.Connect();

    iSocketNode.iNode = PVMFSocketNodeFactory::CreatePVMFSocketNode(OsclActiveObject::EPriorityNominal);
    OsclError::LeaveIfNull(iSocketNode.iNode);
    iSocketNode.Connect();
}

PVMFDownloadManagerNode::~PVMFDownloadManagerNode()
{
    if (iPlayBackClock != NULL)
    {
        if (iClockNotificationsInf != NULL)
        {
            iClockNotificationsInf->RemoveClockStateObserver(*this);
            iPlayBackClock->DestroyMediaClockNotificationsInterface(iClockNotificationsInf);
        }
    }

    Cancel();
    if (IsAdded())
        RemoveFromScheduler();

    //if any sub-node commands are outstanding, there will be
    //a crash when they callback-- so panic here instead.

    if (iFormatParserNode.CmdPending()
            || iProtocolEngineNode.CmdPending()
            || iSocketNode.CmdPending()
            || iRecognizerNode.CmdPending()
       )
    {
        OSCL_ASSERT(0);
    }

    //this is to ensure that there are no more callbacks from PE node to parser node,
    //in case parser node had some outstanding request resume notifications
    if (iProtocolEngineNode.DownloadProgress() != NULL)
    {
        (iProtocolEngineNode.DownloadProgress())->setFormatDownloadSupportInterface(NULL);
    }

    //make sure the subnodes got cleaned up
    iFormatParserNode.Cleanup();
    iProtocolEngineNode.Cleanup();
    iSocketNode.Cleanup();
    iRecognizerNode.Cleanup();

    //delete the subnodes
    if (iFormatParserNode.iNode)
    {
        iDNodeUuidCount--;

        bool release_status = false;
        int32 leavecode = 0;
        OSCL_TRY(leavecode, release_status = iPlayerNodeRegistry->ReleaseNode(iDNodeUuids[iDNodeUuidCount], iFormatParserNode.iNode));
        //ignore errors.
        iDNodeUuids.clear();
    }

    if (iProtocolEngineNode.iNode)
        PVMFProtocolEngineNodeFactory::DeletePVMFProtocolEngineNode(iProtocolEngineNode.iNode);

    if (iSocketNode.iNode)
        PVMFSocketNodeFactory::DeletePVMFSocketNode(iSocketNode.iNode);

    // delete the data stream factory (This has to come after deleting anybody who uses it, like the protocol engine node or the parser node.)
    if (iFileBufferDatastreamFactory)
    {
        OSCL_DELETE(iFileBufferDatastreamFactory);
        iFileBufferDatastreamFactory = NULL;
    }
#if(PVMF_DOWNLOADMANAGER_SUPPORT_PPB)
    if (iMemoryBufferDatastreamFactory)
    {
        OSCL_DELETE(iMemoryBufferDatastreamFactory);
        iMemoryBufferDatastreamFactory = NULL;
    }
#endif//PVMF_DOWNLOADMANAGER_SUPPORT_PPB

    //The command queues are self-deleting, but we want to notify the observer of unprocessed commands.
    while (!iCurrentCommand.empty())
        CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFFailure, NULL, NULL);
    while (!iCancelCommand.empty())
        CommandComplete(iCancelCommand, iCancelCommand.front(), PVMFFailure, NULL, NULL);
    while (!iInputCommands.empty())
        CommandComplete(iInputCommands, iInputCommands.front(), PVMFFailure, NULL, NULL);
}

//Public API From node interface.
PVMFStatus PVMFDownloadManagerNode::ThreadLogon()
{
    if (iInterfaceState != EPVMFNodeCreated)
        return PVMFErrInvalidState;

    //logon this node.
    if (!IsAdded())
        AddToScheduler();

    iLogger = PVLogger::GetLoggerObject("pvdownloadmanagernode");

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, CMD_LOG_LEVEL, (0, "PVMFDownloadManagerNode::ThreadLogon() called"));

    //logon the sub-nodes.
    if (iProtocolEngineNode.iNode)
        iProtocolEngineNode.iNode->ThreadLogon();

    if (iSocketNode.iNode)
        iSocketNode.iNode->ThreadLogon();

    ChangeNodeState(EPVMFNodeIdle);
    return PVMFSuccess;
}


//Public API From node interface.
PVMFStatus PVMFDownloadManagerNode::ThreadLogoff()
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, CMD_LOG_LEVEL, (0, "PVMFDownloadManagerNode::ThreadLogoff() called"));

    if (iInterfaceState != EPVMFNodeIdle)
        return PVMFErrInvalidState;

    //logoff this node.
    if (IsAdded())
        RemoveFromScheduler();

    iLogger = NULL;

    //logoff the sub-nodes.
    if (iFormatParserNode.iNode)
        iFormatParserNode.iNode->ThreadLogoff();
    if (iProtocolEngineNode.iNode)
        iProtocolEngineNode.iNode->ThreadLogoff();
    if (iSocketNode.iNode)
        iSocketNode.iNode->ThreadLogoff();

    ChangeNodeState(EPVMFNodeCreated);
    return PVMFSuccess;
}


//Public API From node interface.
PVMFStatus PVMFDownloadManagerNode::GetCapability(PVMFNodeCapability& aNodeCapability)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, CMD_LOG_LEVEL, (0, "PVMFDownloadManagerNode::GetCapability() called"));

    aNodeCapability = iCapability;

    return PVMFSuccess;
}


//Public API From node interface.
PVMFPortIter* PVMFDownloadManagerNode::GetPorts(const PVMFPortFilter* aFilter)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, CMD_LOG_LEVEL, (0, "PVMFDownloadManagerNode::GetPorts() called"));

    if (iFormatParserNode.iNode)
        return iFormatParserNode.iNode->GetPorts(aFilter);
    return NULL;
}


//Public API From node interface.
PVMFCommandId PVMFDownloadManagerNode::QueryUUID(PVMFSessionId aSessionId, const PvmfMimeString& aMimeType,
        Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids, bool aExactUuidsOnly, const OsclAny* aContext)
{

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, CMD_LOG_LEVEL, (0, "PVMFDownloadManagerNode::QueryUUID() called"));

    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommandBase::Construct(aSessionId, PVMF_GENERIC_NODE_QUERYUUID, aMimeType, aUuids, aExactUuidsOnly, aContext);
    return QueueCommandL(cmd);
}


//Public API From node interface.
PVMFCommandId PVMFDownloadManagerNode::QueryInterface(PVMFSessionId aSessionId, const PVUuid& aUuid,
        PVInterface*& aInterfacePtr, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, CMD_LOG_LEVEL, (0, "PVMFDownloadManagerNode::QueryInterface() called"));

    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommandBase::Construct(aSessionId, PVMF_GENERIC_NODE_QUERYINTERFACE, aUuid, aInterfacePtr, aContext);
    return QueueCommandL(cmd);
}


//Public API From node interface.
PVMFCommandId PVMFDownloadManagerNode::RequestPort(PVMFSessionId aSessionId, int32 aPortTag,
        const PvmfMimeString* aPortConfig, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, CMD_LOG_LEVEL, (0, "PVMFDownloadManagerNode::RequestPort() called"));

    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommandBase::Construct(aSessionId, PVMF_GENERIC_NODE_REQUESTPORT, aPortTag, aPortConfig, aContext);
    return QueueCommandL(cmd);
}


//Public API From node interface.
PVMFStatus PVMFDownloadManagerNode::ReleasePort(PVMFSessionId aSessionId, PVMFPortInterface& aPort, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, CMD_LOG_LEVEL, (0, "PVMFDownloadManagerNode::ReleasePort() called"));

    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommandBase::Construct(aSessionId, PVMF_GENERIC_NODE_RELEASEPORT, aPort, aContext);
    return QueueCommandL(cmd);
}


//Public API From node interface.
PVMFCommandId PVMFDownloadManagerNode::Init(PVMFSessionId aSessionId, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, CMD_LOG_LEVEL, (0, "PVMFDownloadManagerNode::Init() called"));

    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommandBase::Construct(aSessionId, PVMF_GENERIC_NODE_INIT, aContext);
    return QueueCommandL(cmd);
}


//Public API From node interface.
PVMFCommandId PVMFDownloadManagerNode::Prepare(PVMFSessionId aSessionId, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, CMD_LOG_LEVEL, (0, "PVMFDownloadManagerNode::Prepare() called"));

    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommandBase::Construct(aSessionId, PVMF_GENERIC_NODE_PREPARE, aContext);
    return QueueCommandL(cmd);
}


//Public API From node interface.
PVMFCommandId PVMFDownloadManagerNode::Start(PVMFSessionId aSessionId, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, CMD_LOG_LEVEL, (0, "PVMFDownloadManagerNode::Start() called"));

    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommandBase::Construct(aSessionId, PVMF_GENERIC_NODE_START, aContext);
    return QueueCommandL(cmd);
}


//Public API From node interface.
PVMFCommandId PVMFDownloadManagerNode::Stop(PVMFSessionId aSessionId, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, CMD_LOG_LEVEL, (0, "PVMFDownloadManagerNode::Stop() called"));

    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommandBase::Construct(aSessionId, PVMF_GENERIC_NODE_STOP, aContext);
    return QueueCommandL(cmd);
}


//Public API From node interface.
PVMFCommandId PVMFDownloadManagerNode::Flush(PVMFSessionId aSessionId, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, CMD_LOG_LEVEL, (0, "PVMFDownloadManagerNode::Flush() called"));

    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommandBase::Construct(aSessionId, PVMF_GENERIC_NODE_FLUSH, aContext);
    return QueueCommandL(cmd);
}


//Public API From node interface.
PVMFCommandId PVMFDownloadManagerNode::Pause(PVMFSessionId aSessionId, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, CMD_LOG_LEVEL, (0, "PVMFDownloadManagerNode::Pause() called"));

    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommandBase::Construct(aSessionId, PVMF_GENERIC_NODE_PAUSE, aContext);
    return QueueCommandL(cmd);
}


//Public API From node interface.
PVMFCommandId PVMFDownloadManagerNode::Reset(PVMFSessionId aSessionId, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, CMD_LOG_LEVEL, (0, "PVMFDownloadManagerNode::Reset() called"));

    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommandBase::Construct(aSessionId, PVMF_GENERIC_NODE_RESET, aContext);
    return QueueCommandL(cmd);
}


//Public API From node interface.
PVMFCommandId PVMFDownloadManagerNode::CancelAllCommands(PVMFSessionId aSessionId, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, CMD_LOG_LEVEL, (0, "PVMFDownloadManagerNode::CancelAllCommands() called"));

    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommandBase::Construct(aSessionId, PVMF_GENERIC_NODE_CANCELALLCOMMANDS, aContext);
    return QueueCommandL(cmd);
}


//Public API From node interface.
PVMFCommandId PVMFDownloadManagerNode::CancelCommand(PVMFSessionId aSessionId, PVMFCommandId aCmdId, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, CMD_LOG_LEVEL, (0, "PVMFDownloadManagerNode::CancelCommand() called"));

    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommandBase::Construct(aSessionId, PVMF_GENERIC_NODE_CANCELCOMMAND, aCmdId, aContext);
    return QueueCommandL(cmd);
}

//public API from PVInterface
void PVMFDownloadManagerNode::addRef()
{
    ++iExtensionRefCount;
}

//public API from PVInterface
void PVMFDownloadManagerNode::removeRef()
{
    --iExtensionRefCount;
}

//public API from PVInterface
bool PVMFDownloadManagerNode::queryInterface(const PVUuid& uuid, PVInterface*& iface)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::queryInterface() In"));

    if (uuid == PVMF_TRACK_SELECTION_INTERFACE_UUID)
    {
        PVMFTrackSelectionExtensionInterface* myInterface = OSCL_STATIC_CAST(PVMFTrackSelectionExtensionInterface*, this);
        iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
    }
    else if (uuid == PVMF_DATA_SOURCE_INIT_INTERFACE_UUID)
    {
        PVMFDataSourceInitializationExtensionInterface* myInterface = OSCL_STATIC_CAST(PVMFDataSourceInitializationExtensionInterface*, this);
        iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
    }
    else if (uuid == KPVMFMetadataExtensionUuid)
    {
        PVMFMetadataExtensionInterface* myInterface = OSCL_STATIC_CAST(PVMFMetadataExtensionInterface*, this);
        iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
    }
    else if (uuid == PVMF_DATA_SOURCE_NODE_REGISRTY_INIT_INTERFACE_UUID)
    {
        PVMFDataSourceNodeRegistryInitInterface* myInterface =
            OSCL_STATIC_CAST(PVMFDataSourceNodeRegistryInitInterface*, this);
        iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
    }
    else if (uuid == PvmfDataSourcePlaybackControlUuid)
    {
        PvmfDataSourcePlaybackControlInterface* myInterface = OSCL_STATIC_CAST(PvmfDataSourcePlaybackControlInterface*, this);
        iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
    }
    else if (uuid == PVMI_CAPABILITY_AND_CONFIG_PVUUID)
    {
        PvmiCapabilityAndConfig* myInterface = OSCL_STATIC_CAST(PvmiCapabilityAndConfig*, this);
        iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
    }
    else if (uuid == PVMFCPMPluginLicenseInterfaceUuid)
    {
        PVMFCPMPluginLicenseInterface* myInterface = OSCL_STATIC_CAST(PVMFCPMPluginLicenseInterface*, this);
        iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
    }
    else
    {
        return false;
    }

    ++iExtensionRefCount;
    return true;
}


//public API from data source initialization interface
PVMFStatus PVMFDownloadManagerNode::SetSourceInitializationData(OSCL_wString& aSourceURL, PVMFFormatType& aSourceFormat, OsclAny* aSourceData)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::SetSourceInitializationData() called"));

    //this method must be called before the Init command.
    if (iInterfaceState != EPVMFNodeIdle && iInterfaceState != EPVMFNodeCreated)
        return PVMFErrInvalidState;


    // Pass the source info directly to the protocol engine node.

    if (!iProtocolEngineNode.DataSourceInit())
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0,
                        "PVMFDownloadManagerNode:SetSourceInitializationData() Can't find datasourceinit interface in protocol engine subnode container."));
        return PVMFFailure; //no source init interface.
    }

    PVMFStatus status = (iProtocolEngineNode.DataSourceInit())->SetSourceInitializationData(aSourceURL, aSourceFormat, aSourceData);
    if (status != PVMFSuccess)
        return status;

    if (!iProtocolEngineNode.ProtocolEngineExtension())
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0,
                        "PVMFDownloadManagerNode:SetSourceInitializationData() Can't get ProtocolEngineExtension interface from protocol subnode container."));
        return PVMFFailure; //no ProtocolNodeExtension interface.
    }

    bool socketConfigOK = (iProtocolEngineNode.ProtocolEngineExtension())->GetSocketConfig(iServerAddr);
    if (!socketConfigOK)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0,
                        "PVMFDownloadManagerNode: SetSourceInitializationData() Call to GetSocketConfig() on protocol engine node returned failure."));
        return PVMFErrProcessing;
    }

    if (aSourceFormat == PVMF_MIME_DATA_SOURCE_HTTP_URL)
    {
        if (!aSourceData)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0,
                            "PVMFDownloadManagerNode:SetSourceInitializationData() Missing source data"));
            return PVMFErrArgument;
        }
        PVInterface* pvinterface = (PVInterface*)aSourceData;
        PVUuid uuid(PVMF_DOWNLOAD_DATASOURCE_HTTP_UUID);
        PVInterface* temp = NULL;
        if (pvinterface->queryInterface(uuid, temp))
        {
            PVMFDownloadDataSourceHTTP* data = OSCL_STATIC_CAST(PVMFDownloadDataSourceHTTP*, temp);
            //extract the download file name from the opaque data.
            iDownloadFileName = data->iDownloadFileName;

            //extract the playback mode
            switch (data->iPlaybackControl)
            {
                case PVMFDownloadDataSourceHTTP::ENoPlayback:
                    iPlaybackMode = EDownloadOnly;
                    break;
                case PVMFDownloadDataSourceHTTP::EAfterDownload:
                    iPlaybackMode = EDownloadThenPlay;
                    break;
                case PVMFDownloadDataSourceHTTP::EAsap:
                    iPlaybackMode = EPlayAsap;
                    break;

                case PVMFDownloadDataSourceHTTP::ENoSaveToFile:
#if(PVMF_DOWNLOADMANAGER_SUPPORT_PPB)
                    iPlaybackMode = EPlaybackOnly;
                    break;
#else
                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0,
                                    "PVMFDownloadManagerNode:SetSourceInitializationData() NoSaveToFile is not supported!"));
                    return PVMFErrArgument;//unsupported mode.
#endif//PVMF_DOWNLOADMANAGER_SUPPORT_PPB

                default:
                    iPlaybackMode = EPlayAsap;
                    break;
            }
        }
        else
        {
            PVUuid uuid(PVMF_SOURCE_CONTEXT_DATA_DOWNLOAD_HTTP_UUID);
            temp = NULL;
            if (pvinterface->queryInterface(uuid, temp))
            {
                PVMFSourceContextDataDownloadHTTP* data = OSCL_STATIC_CAST(PVMFSourceContextDataDownloadHTTP*, temp);
                //extract the download file name from the opaque data.
                iDownloadFileName = data->iDownloadFileName;

                //extract the playback mode
                switch (data->iPlaybackControl)
                {
                    case PVMFSourceContextDataDownloadHTTP::ENoPlayback:
                        iPlaybackMode = EDownloadOnly;
                        break;
                    case PVMFSourceContextDataDownloadHTTP::EAfterDownload:
                        iPlaybackMode = EDownloadThenPlay;
                        break;
                    case PVMFSourceContextDataDownloadHTTP::EAsap:
                        iPlaybackMode = EPlayAsap;
                        break;

                    case PVMFSourceContextDataDownloadHTTP::ENoSaveToFile:
#if(PVMF_DOWNLOADMANAGER_SUPPORT_PPB)
                        iPlaybackMode = EPlaybackOnly;
                        break;
#else
                        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0,
                                        "PVMFDownloadManagerNode:SetSourceInitializationData() NoSaveToFile is not supported!"));
                        return PVMFErrArgument;//unsupported mode.
#endif//PVMF_DOWNLOADMANAGER_SUPPORT_PPB

                    default:
                        iPlaybackMode = EPlayAsap;
                        break;
                }
            }
            else
            {//invalid source data
                return PVMFErrArgument;
            }
        }
    }
    else if (aSourceFormat == PVMF_MIME_DATA_SOURCE_PVX_FILE)
    {
        if (!aSourceData)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0,
                            "PVMFDownloadManagerNode:SetSourceInitializationData() Missing source data"));
            return PVMFErrArgument;
        }
        PVInterface* pvinterface = (PVInterface*)aSourceData;
        PVUuid uuid(PVMF_DOWNLOAD_DATASOURCE_PVX_UUID);
        PVInterface* temp = NULL;
        if (pvinterface->queryInterface(uuid, temp))
        {
            PVMFDownloadDataSourcePVX* data = OSCL_STATIC_CAST(PVMFDownloadDataSourcePVX*, temp);
            iDownloadFileName = data->iDownloadFileName;
            //get the playback mode from the PVX info
            switch (data->iPvxInfo.iPlaybackControl)
            {
                case CPVXInfo::ENoPlayback:
                    iPlaybackMode = EDownloadOnly;
                    break;
                case CPVXInfo::EAfterDownload:
                    iPlaybackMode = EDownloadThenPlay;
                    break;
                case CPVXInfo::EAsap:
                    iPlaybackMode = EPlayAsap;
                    break;
                default:
                    iPlaybackMode = EPlayAsap;
                    break;
            }
        }
        else
        {
            PVUuid uuid(PVMF_SOURCE_CONTEXT_DATA_DOWNLOAD_PVX_UUID);
            temp = NULL;
            if (pvinterface->queryInterface(uuid, temp))
            {
                PVMFSourceContextDataDownloadPVX* data = OSCL_STATIC_CAST(PVMFSourceContextDataDownloadPVX*, temp);
                iDownloadFileName = data->iDownloadFileName;
                if (!data->iPvxInfo)
                {//invalid source data
                    return PVMFErrArgument;
                }
                //get the playback mode from the PVX info
                switch (data->iPvxInfo->iPlaybackControl)
                {
                    case CPVXInfo::ENoPlayback:
                        iPlaybackMode = EDownloadOnly;
                        break;
                    case CPVXInfo::EAfterDownload:
                        iPlaybackMode = EDownloadThenPlay;
                        break;
                    case CPVXInfo::EAsap:
                        iPlaybackMode = EPlayAsap;
                        break;
                    default:
                        iPlaybackMode = EPlayAsap;
                        break;
                }
            }
            else
            {//invalid source data
                return PVMFErrArgument;
            }
        }
    }
    else if (aSourceFormat == PVMF_MIME_DATA_SOURCE_SHOUTCAST_URL)
    {
        if (!aSourceData)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0,
                            "PVMFDownloadManagerNode:SetSourceInitializationData() Missing source data"));
            return PVMFErrArgument;
        }
        PVInterface* pvinterface = (PVInterface*)aSourceData;
        PVUuid uuid(PVMF_DOWNLOAD_DATASOURCE_HTTP_UUID);
        PVInterface* temp = NULL;
        if (pvinterface->queryInterface(uuid, temp))
        {
            PVMFDownloadDataSourceHTTP* data = OSCL_STATIC_CAST(PVMFDownloadDataSourceHTTP*, temp);

            //extract the download file name from the opaque data.
            iDownloadFileName = data->iDownloadFileName;

            //extract the playback mode
            switch (data->iPlaybackControl)
            {
                case PVMFDownloadDataSourceHTTP::ENoSaveToFile:

#if(PVMF_DOWNLOADMANAGER_SUPPORT_PPB)
                    iPlaybackMode = EPlaybackOnly;
                    break;
#else
                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0,
                                    "PVMFDownloadManagerNode:SetSourceInitializationData() NoSaveToFile is not supported!"));
                    return PVMFErrArgument;//unsupported mode.
#endif//PVMF_DOWNLOADMANAGER_SUPPORT_PPB

                default:

                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0,
                                    "PVMFDownloadManagerNode:SetSourceInitializationData() Only NoSaveToFile mode is supported for PVMF_MIME_DATA_SOURCE_SHOUTCAST_URL!"));
                    return PVMFErrArgument;//unsupported mode.
                    break;
            }
        }
        else
        {
            PVUuid uuid(PVMF_SOURCE_CONTEXT_DATA_DOWNLOAD_HTTP_UUID);
            if (pvinterface->queryInterface(uuid, temp))
            {
                PVMFSourceContextDataDownloadHTTP* data = OSCL_STATIC_CAST(PVMFSourceContextDataDownloadHTTP*, temp);
                //extract the download file name from the opaque data.
                iDownloadFileName = data->iDownloadFileName;

                //extract the playback mode
                switch (data->iPlaybackControl)
                {
                    case PVMFSourceContextDataDownloadHTTP::ENoSaveToFile:

#if(PVMF_DOWNLOADMANAGER_SUPPORT_PPB)
                        iPlaybackMode = EPlaybackOnly;
                        break;
#else
                        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0,
                                        "PVMFDownloadManagerNode:SetSourceInitializationData() NoSaveToFile is not supported!"));
                        return PVMFErrArgument;//unsupported mode.
#endif//PVMF_DOWNLOADMANAGER_SUPPORT_PPB

                    default:
                        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0,
                                        "PVMFDownloadManagerNode:SetSourceInitializationData() Only NoSaveToFile mode is supported for PVMF_MIME_DATA_SOURCE_SHOUTCAST_URL!"));
                        return PVMFErrArgument;//unsupported mode.
                        break;
                }
            }
            else
            {//invalid source data
                return PVMFErrArgument;
            }
        }
    }
    else
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0,
                        "PVMFDownloadManagerNode:SetSourceInitializationData() Unsupported source type"));
        return PVMFErrArgument;
    }

#if(PVMF_DOWNLOADMANAGER_SUPPORT_PPB)
    //Configure the MBDS
    if (iPlaybackMode == EPlaybackOnly)
    {
        // make sure we have enough TCP buffers for PPB and shoutcast
        if (aSourceFormat == PVMF_MIME_DATA_SOURCE_SHOUTCAST_URL)
        {
            // calculate MBDS cache size in bytes
            // max bitrate in bytes per second * cache size in secs
            uint32 bitRate = PVMF_DOWNLOADMANAGER_MAX_BITRATE_FOR_SC * 1000 / 8;
            uint32 cacheSize = bitRate * PVMF_DOWNLOADMANAGER_CACHE_SIZE_FOR_SC_IN_SECONDS;

            if (iSocketNode.iNode)
            {
                // TCP buffer size for shoutcast is 1564 (1500 data + 64 overhead)
                // add 1 second margin
                ((PVMFSocketNode*)iSocketNode.iNode)->SetMaxTCPRecvBufferCount((cacheSize + bitRate) / PVMF_DOWNLOADMANAGER_TCP_BUFFER_SIZE_FOR_SC);

                ((PVMFSocketNode*)iSocketNode.iNode)->SetMaxTCPRecvBufferSize(PVMF_DOWNLOADMANAGER_TCP_BUFFER_SIZE_FOR_SC + PVMF_DOWNLOADMANAGER_TCP_BUFFER_OVERHEAD);
            }

            // Use Memory Buffer Data Stream for progressive playback and Shoutcast
            iMemoryBufferDatastreamFactory = OSCL_NEW(PVMFMemoryBufferDataStream, (aSourceFormat, cacheSize));
        }
        else
        {
            uint32 bufSize = PVMF_DOWNLOADMANAGER_TCP_BUFFER_SIZE_FOR_PPB;
            if (iSocketNode.iNode)
            {
                ((PVMFSocketNode*)iSocketNode.iNode)->SetMaxTCPRecvBufferCount(PVMF_DOWNLOADMANAGER_MIN_TCP_BUFFERS_FOR_PPB);
                // get buffer size
                ((PVMFSocketNode*)iSocketNode.iNode)->GetMaxTCPRecvBufferSize(bufSize);
            }

            // MBDS cache size calculation
            // TCP buffer size is 64000 (the default), assume worst case that the average packet size is 250 bytes
            // Packet overhead is 64 bytes per packet
            // 8 buffers will yield a cache of 305500, 13 buffers will yield a cache of 560500
            uint32 totalPoolSizeMinusTwoBuffers = (PVMF_DOWNLOADMANAGER_MIN_TCP_BUFFERS_FOR_PPB - PVMF_DOWNLOADMANAGER_TCP_BUFFER_NOT_AVAILABLE) * bufSize;
            uint32 numPacketsToFitInPool = totalPoolSizeMinusTwoBuffers / (PVMF_DOWNLOADMANAGER_TCP_AVG_SMALL_PACKET_SIZE + PVMF_DOWNLOADMANAGER_TCP_BUFFER_OVERHEAD);
            uint32 maxDataMinusOverheadInPool = numPacketsToFitInPool * PVMF_DOWNLOADMANAGER_TCP_AVG_SMALL_PACKET_SIZE;

            // Use Memory Buffer Data Stream for progressive playback and Shoutcast
            iMemoryBufferDatastreamFactory = OSCL_NEW(PVMFMemoryBufferDataStream, (aSourceFormat, maxDataMinusOverheadInPool));
        }

        OSCL_ASSERT(iMemoryBufferDatastreamFactory != NULL);

        iReadFactory  = iMemoryBufferDatastreamFactory->GetReadDataStreamFactoryPtr();
        iWriteFactory = iMemoryBufferDatastreamFactory->GetWriteDataStreamFactoryPtr();
    }
    else
#endif//PVMF_DOWNLOADMANAGER_SUPPORT_PPB
    {
        // Now that we have the download file name, we can instantiate the file buffer data stream object
        // Create the filebuffer data stream factory
        iFileBufferDatastreamFactory = OSCL_NEW(PVMFFileBufferDataStream, (iDownloadFileName));
        OSCL_ASSERT(iFileBufferDatastreamFactory != NULL);
        iReadFactory  = iFileBufferDatastreamFactory->GetReadDataStreamFactoryPtr();
        iWriteFactory = iFileBufferDatastreamFactory->GetWriteDataStreamFactoryPtr();
    }

//save the source info
    iSourceFormat = aSourceFormat;
    iSourceURL = aSourceURL;
    iSourceData = aSourceData;

    return PVMFSuccess;
}

//public API from data source initialization interface
PVMFStatus PVMFDownloadManagerNode::SetClientPlayBackClock(PVMFMediaClock* aClientClock)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::SetClientPlayBackClock() called"));

    iPlayBackClock = aClientClock;
    if (iPlayBackClock)
    {
        iPlayBackClock->ConstructMediaClockNotificationsInterface(iClockNotificationsInf, *this);
    }

    if (iClockNotificationsInf != NULL)
    {
        iClockNotificationsInf->SetClockStateObserver(*this);
    }

    //pass the source info directly to the download node.
    if (NULL == iProtocolEngineNode.DataSourceInit())
        return PVMFFailure;//no source init interface.

    PVMFStatus status = (iProtocolEngineNode.DataSourceInit())->SetClientPlayBackClock(aClientClock);

    return status;
}

//public API from data source initialization interface
PVMFStatus PVMFDownloadManagerNode::SetEstimatedServerClock(PVMFMediaClock*)
{
    //not needed for download.
    return PVMFErrNotSupported;
}

PVMFDownloadManagerSubNodeContainer& PVMFDownloadManagerNode::TrackSelectNode()
{
    //Decide which sub-node is supporting track selection.
    if (iSourceFormat == PVMF_MIME_DATA_SOURCE_PVX_FILE)
    {
        //for pvx file, the PE node may or may not do track selection.
        //the final decision isn't available until PE node prepare is done
        //and we've queried for the TS interface, at which point the
        //iNoPETrackSelect may be set.
        if (iNoPETrackSelect)
            return iFormatParserNode;

        //if download is already complete, such as after a stop, then
        //the parser node will do track selection.
        if (iDownloadComplete && iPlaybackMode != EDownloadOnly)
            return iFormatParserNode;

        return iProtocolEngineNode;
    }
    else
    {
        //for 3gpp & shoutcast, parser does track selection.
        return iFormatParserNode;
    }
}

//Public API From track selection interface.
PVMFStatus PVMFDownloadManagerNode::GetMediaPresentationInfo(PVMFMediaPresentationInfo& aInfo)
{
    //this is assumed to happen only after node initialization.
    if (iInterfaceState != EPVMFNodeInitialized && iInterfaceState != EPVMFNodePrepared)
        return PVMFErrInvalidState;

    if (TrackSelectNode().TrackSelection())
        return (TrackSelectNode().TrackSelection())->GetMediaPresentationInfo(aInfo);
    else
        return PVMFFailure; //no track selection interface!
}

//Public API From track selection interface.
PVMFStatus PVMFDownloadManagerNode::SelectTracks(PVMFMediaPresentationInfo& aInfo)
{
    //this needs to happen after initialization.
    if (iInterfaceState != EPVMFNodeInitialized && iInterfaceState != EPVMFNodePrepared)
        return PVMFErrInvalidState;

    if (TrackSelectNode().TrackSelection())
        return (TrackSelectNode().TrackSelection())->SelectTracks(aInfo);
    else
        return PVMFFailure;//no track selection interface!
}


uint32 PVMFDownloadManagerNode::GetNumMetadataKeys(char* query_key)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::GetNumMetadataKeys() called"));
    if (iFormatParserNode.Metadata())
    {
        return (iFormatParserNode.Metadata())->GetNumMetadataKeys(query_key);
    }
    return 0;
}

uint32 PVMFDownloadManagerNode::GetNumMetadataValues(PVMFMetadataList& aKeyList)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::GetNumMetadataValues() called"));
    if (iFormatParserNode.Metadata())
    {
        return (iFormatParserNode.Metadata())->GetNumMetadataValues(aKeyList);
    }
    return 0;
}


PVMFCommandId PVMFDownloadManagerNode::GetNodeMetadataKeys(PVMFSessionId aSessionId, PVMFMetadataList& aKeyList, uint32 starting_index, int32 max_entries, char* query_key, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::GetNodeMetadataKeys() called"));

    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommand::Construct(aSessionId, PVDLM_NODE_CMD_GETNODEMETADATAKEY, aKeyList, starting_index, max_entries, query_key, aContext);
    return QueueCommandL(cmd);
}


PVMFCommandId PVMFDownloadManagerNode::GetNodeMetadataValues(PVMFSessionId aSessionId, PVMFMetadataList& aKeyList, Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList, uint32 starting_index, int32 max_entries, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::GetNodeMetadataValue() called"));

    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommand::Construct(aSessionId, PVDLM_NODE_CMD_GETNODEMETADATAVALUE, aKeyList, aValueList, starting_index, max_entries, aContext);
    return QueueCommandL(cmd);
}

// From PVMFMetadataExtensionInterface
PVMFStatus PVMFDownloadManagerNode::ReleaseNodeMetadataKeys(PVMFMetadataList& keys,
        uint32 start ,
        uint32 end)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::ReleaseNodeMetadataKeys() called"));
    if (iFormatParserNode.Metadata())
    {
        return iFormatParserNode.Metadata()->ReleaseNodeMetadataKeys(keys, start, end);
    }
    return PVMFFailure;
}

// From PVMFMetadataExtensionInterface
PVMFStatus PVMFDownloadManagerNode::ReleaseNodeMetadataValues(Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList,
        uint32 start,
        uint32 end)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::ReleaseNodeMetadataValues() called"));

    if (iFormatParserNode.Metadata())
    {
        return iFormatParserNode.Metadata()->ReleaseNodeMetadataValues(aValueList, start, end);
    }
    return PVMFFailure;
}

//public API from data source playback interface
PVMFCommandId PVMFDownloadManagerNode::SetDataSourcePosition(PVMFSessionId aSessionId, PVMFTimestamp aTargetNPT,
        PVMFTimestamp& aActualNPT,
        PVMFTimestamp& aActualMediaDataTS,
        bool aSeekToSyncPoint,
        uint32 aStreamID,
        OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFDownloadManagerNode::SetDataSourcePosition: aTargetNPT=%d, aSeekToSyncPoint=%d, aContext=0x%x",
                     aTargetNPT, aSeekToSyncPoint, aContext));

    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommand::Construct(aSessionId, PVDLM_NODE_CMD_SETDATASOURCEPOSITION, aTargetNPT, aActualNPT,
            aActualMediaDataTS, aSeekToSyncPoint, aStreamID, aContext);
    return QueueCommandL(cmd);
}

PVMFCommandId PVMFDownloadManagerNode::QueryDataSourcePosition(PVMFSessionId aSessionId,
        PVMFTimestamp aTargetNPT,
        PVMFTimestamp& aSeekPointBeforeTargetNPT,
        PVMFTimestamp& aSeekPointAfterTargetNPT,
        OsclAny* aContextData,
        bool aSeekToSyncPoint)
{
    OSCL_UNUSED_ARG(aSeekPointAfterTargetNPT);
    // Implemented to complete interface file definition
    // Not tested on logical plane
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFDownloadManagerNode::QueryDataSourcePosition: aTargetNPT=%d, aSeekToSyncPoint=%d, aContext=0x%x", aTargetNPT,
                     aContextData, aSeekToSyncPoint));

    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommand::Construct(aSessionId, PVDLM_NODE_CMD_QUERYDATASOURCEPOSITION, aTargetNPT, aSeekPointBeforeTargetNPT,
            aSeekToSyncPoint, aContextData);
    return QueueCommandL(cmd);
}

PVMFCommandId PVMFDownloadManagerNode::QueryDataSourcePosition(PVMFSessionId aSessionId, PVMFTimestamp aTargetNPT,
        PVMFTimestamp& aActualNPT,
        bool aSeekToSyncPoint,
        OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFDownloadManagerNode::QueryDataSourcePosition: aTargetNPT=%d, aSeekToSyncPoint=%d, aContext=0x%x",
                     aTargetNPT, aSeekToSyncPoint, aContext));

    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommand::Construct(aSessionId, PVDLM_NODE_CMD_QUERYDATASOURCEPOSITION, aTargetNPT, aActualNPT,
            aSeekToSyncPoint, aContext);
    return QueueCommandL(cmd);
}


PVMFCommandId PVMFDownloadManagerNode::SetDataSourceRate(PVMFSessionId aSessionId, int32 aRate, PVMFTimebase* aTimebase, OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFDownloadManagerNode::SetDataSourceRate: aRate=%d", aRate));

    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommand::Construct(aSessionId, PVDLM_NODE_CMD_SETDATASOURCERATE, aRate, aTimebase, aContext);
    return QueueCommandL(cmd);
}

PVMFStatus PVMFDownloadManagerNode::SetPlayerNodeRegistry(PVPlayerNodeRegistryInterface* aRegistry)
{
    iPlayerNodeRegistry = aRegistry;
    return PVMFSuccess;
}

void PVMFDownloadManagerNode::Run()
{
    //Process async node commands.
    if (!iInputCommands.empty())
        ProcessCommand();

    //Issue commands to the sub-nodes.
    if (!iProtocolEngineNode.CmdPending()
            && !iFormatParserNode.CmdPending()
            && !iSocketNode.CmdPending()
            && !iRecognizerNode.CmdPending()
            && !iSubNodeCmdVec.empty())
    {
        PVMFStatus status = iSubNodeCmdVec.front().iNC->IssueCommand(iSubNodeCmdVec.front().iCmd);
        if (status != PVMFPending)
            iSubNodeCmdVec.front().iNC->CommandDone(status, NULL, NULL);
    }
}

PVMFCommandId PVMFDownloadManagerNode::QueueCommandL(PVMFDownloadManagerNodeCommand& aCmd)
{
    //add a command to the async node command queue and return command ID

    PVMFCommandId id = iInputCommands.AddL(aCmd);

    // Wakeup the AO
    RunIfNotReady();

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, CMD_LOG_LEVEL, (0, "PVMFDownloadManagerNode::QueueCommandL() returning %d", id));

    return id;
}

void PVMFDownloadManagerNode::ProcessCommand()
{
    //This call will process the first node command in the input queue.


    //Can't do anything when an asynchronous cancel is in progress -- just need to wait on completion.
    if (!iCancelCommand.empty())
        return; //keep waiting.

    //If a command is in progress, only a hi-pri command can interrupt it.
    if (!iCurrentCommand.empty()
            && !iInputCommands.front().hipri()
       )
    {
        return; //keep waiting
    }

    //The newest or highest pri command is in the front of the queue.
    OSCL_ASSERT(!iInputCommands.empty());
    PVMFDownloadManagerNodeCommand& aCmd = iInputCommands.front();

    PVMFStatus cmdstatus;
    if (aCmd.hipri())
    {
        //Process the Hi-Pri commands.
        switch (aCmd.iCmd)
        {
            case PVMF_GENERIC_NODE_CANCELALLCOMMANDS:
                cmdstatus = DoCancelAllCommands(aCmd);
                break;

            case PVMF_GENERIC_NODE_CANCELCOMMAND:
                cmdstatus = DoCancelCommand(aCmd);
                break;

            case PVDLM_NODE_CMD_CANCEL_GET_LICENSE:
                cmdstatus = DoCancelGetLicense(aCmd);
                break;

            default:
                cmdstatus = PVMFErrNotSupported;
                break;
        }

        //If completion is pending, move the command from
        //the input queue to the cancel queue.
        //This is necessary since the input queue could get
        //rearranged by new commands coming in.
        if (cmdstatus == PVMFPending)
        {
            iCancelCommand.StoreL(aCmd);
            iInputCommands.Erase(&aCmd);
        }
    }
    else
    {
        //Process the normal pri commands.
        switch (aCmd.iCmd)
        {
            case PVMF_GENERIC_NODE_QUERYUUID:
                cmdstatus = DoQueryUuid(aCmd);
                break;

            case PVMF_GENERIC_NODE_QUERYINTERFACE:
                cmdstatus = DoQueryInterface(aCmd);
                break;

            case PVMF_GENERIC_NODE_REQUESTPORT:
                cmdstatus = DoRequestPort(aCmd);
                break;

            case PVMF_GENERIC_NODE_RELEASEPORT:
                cmdstatus = DoReleasePort(aCmd);
                break;

            case PVMF_GENERIC_NODE_INIT:
                cmdstatus = DoInitNode(aCmd);
                break;

            case PVMF_GENERIC_NODE_PREPARE:
                cmdstatus = DoPrepareNode(aCmd);
                break;

            case PVMF_GENERIC_NODE_START:
                cmdstatus = DoStartNode(aCmd);
                break;

            case PVMF_GENERIC_NODE_STOP:
                cmdstatus = DoStopNode(aCmd);
                break;

            case PVMF_GENERIC_NODE_FLUSH:
                cmdstatus = DoFlushNode(aCmd);
                break;

            case PVMF_GENERIC_NODE_PAUSE:
                cmdstatus = DoPauseNode(aCmd);
                break;

            case PVMF_GENERIC_NODE_RESET:
                cmdstatus = DoResetNode(aCmd);
                break;

            case PVDLM_NODE_CMD_GETNODEMETADATAKEY:
                cmdstatus = DoGetNodeMetadataKey(aCmd);
                break;

            case PVDLM_NODE_CMD_GETNODEMETADATAVALUE:
                cmdstatus = DoGetNodeMetadataValue(aCmd);
                break;

            case PVDLM_NODE_CMD_SETDATASOURCEPOSITION:
                cmdstatus = DoSetDataSourcePosition(aCmd);
                break;

            case PVDLM_NODE_CMD_QUERYDATASOURCEPOSITION:
                cmdstatus = DoQueryDataSourcePosition(aCmd);
                break;

            case PVDLM_NODE_CMD_SETDATASOURCERATE:
                // Rate change not supported for download
                cmdstatus = PVMFErrNotSupported;
                break;

            case PVDLM_NODE_CMD_GET_LICENSE_W:
                cmdstatus = DoGetLicense(aCmd, true);
                break;

            case PVDLM_NODE_CMD_GET_LICENSE:
                cmdstatus = DoGetLicense(aCmd);
                break;

            default:
                OSCL_ASSERT(false);
                cmdstatus = PVMFFailure;
                break;
        }

        //If completion is pending, move the command from the input queue to the current command.
        //This is necessary since the input queue could get rearranged by new commands coming in.
        if (cmdstatus == PVMFPending)
        {
            iCurrentCommand.StoreL(aCmd);
            iInputCommands.Erase(&aCmd);
        }
    }

    if (cmdstatus != PVMFPending)
        CommandComplete(iInputCommands, aCmd, cmdstatus, NULL, NULL);
}

void PVMFDownloadManagerNode::CommandComplete(PVMFDownloadManagerNodeCmdQueue& aCmdQ, PVMFDownloadManagerNodeCommand& aCmd, PVMFStatus aStatus,
        PVInterface*aExtMsg, OsclAny* aEventData)
{
    //Complete a node command

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, CMD_LOG_LEVEL, (0, "PVMFDownloadManagerNode::CommandComplete() In Id %d Cmd %d Status %d Context %d Data %d",
                    aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));

    if (aStatus != PVMFSuccess)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, CMD_LOG_LEVEL,
                        (0, "PVMFDownloadManagerNode::CommandComplete() Failure!"));
    }

    //if the command failed or was cancelled there may be un-processed sub-node commands, so clear the vector now.
    if (!iSubNodeCmdVec.empty())
        iSubNodeCmdVec.clear();

    //We may need to wait on the movie atom before the node cmd can complete.
    //This is a good place to catch that condition and suppress the node
    //cmd completion.
    if (iParserInitAfterMovieAtom
            || iParserPrepareAfterMovieAtom)
    {
        if (aStatus == PVMFSuccess)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFDownloadManagerNode::CommandComplete() Blocking Command Completion until Movie Atom Downloaded."));
            return;//keep waiting on movie atom complete.
        }
        else
        {
            //if command failed or was cancelled then clear any movie atom wait
            //flags.
            iParserInitAfterMovieAtom = false;
            iParserPrepareAfterMovieAtom = false;
        }
    }

    //Do the post-command state changes and anything else.
    if (aStatus == PVMFSuccess)
    {
        switch (aCmd.iCmd)
        {
            case PVMF_GENERIC_NODE_INIT:
                ChangeNodeState(EPVMFNodeInitialized);
                break;
            case PVMF_GENERIC_NODE_PREPARE:
                ChangeNodeState(EPVMFNodePrepared);
                break;
            case PVMF_GENERIC_NODE_START:
                ChangeNodeState(EPVMFNodeStarted);
                break;
            case PVMF_GENERIC_NODE_PAUSE:
                ChangeNodeState(EPVMFNodePaused);
                break;
            case PVMF_GENERIC_NODE_STOP:
                ChangeNodeState(EPVMFNodePrepared);
                break;
            case PVMF_GENERIC_NODE_FLUSH:
                ChangeNodeState(EPVMFNodePrepared);
                break;
            case PVMF_GENERIC_NODE_RESET:
                //drive this node back to Created state.
                ChangeNodeState(EPVMFNodeIdle);
                break;
        }
    }

    //create response
    PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, aExtMsg, aEventData);
    PVMFSessionId session = aCmd.iSession;

    //Erase the command from the queue.
    aCmdQ.Erase(&aCmd);

    //Report completion to the session observer.
    ReportCmdCompleteEvent(session, resp);

    //re-schedule if there are more commands and node isn't logged off
    if (!iInputCommands.empty()
            && IsAdded())
        RunIfNotReady();
}


void PVMFDownloadManagerNode::ReportErrorEvent(PVMFEventType aEventType, PVInterface*aExtMsg, OsclAny* aEventData)
{
    //Report a node error event

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::ReportErrorEvent() In Type %d Data %d ExtMsg %d",
                    aEventType, aEventData, aExtMsg));

    PVMFNodeInterface::ReportErrorEvent(aEventType, aEventData, aExtMsg);
}


void PVMFDownloadManagerNode::ReportInfoEvent(PVMFAsyncEvent &aEvent)
{
    //Report a node info event

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::ReportInfoEvent() In Type %d Data %d ExtMsg %d",
                    aEvent.GetEventType(), aEvent.GetEventData(), aEvent.GetEventExtensionInterface()));

    PVMFNodeInterface::ReportInfoEvent(aEvent);

    //For download-then-play mode, generate data ready event when buffering
    //is complete.  We will have suppressed the real initial data ready
    //event from PE node in this case.
    if (aEvent.GetEventType() == PVMFInfoBufferingComplete
            && iPlaybackMode == PVMFDownloadManagerNode::EDownloadThenPlay
            && !iDataReady)
    {
        GenerateDataReadyEvent();
    }
    else if (aEvent.GetEventType() == PVMFInfoContentType)
    {
        // copy and save MIME string for recognizer to use as hint
        iContentTypeMIMEString = (char *)aEvent.GetEventData();
    }
}

void PVMFDownloadManagerNode::GenerateDataReadyEvent()
{
    PVMFAsyncEvent info(PVMFInfoEvent, PVMFInfoDataReady, NULL, NULL);
    ReportInfoEvent(info);
    iDataReady = true;
}

bool PVMFDownloadManagerNode::FilterPlaybackEventsFromSubNodes(const PVMFAsyncEvent& aEvent)
{
    switch (aEvent.GetEventType())
    {
        case PVMFInfoUnderflow:
            //filter any underflow that happens before data ready
            if (!iDataReady)
                return true;
            else
                iDataReady = false;
            break;
        case PVMFInfoDataReady:
            //filter any data ready that happens before download complete
            //in dl-then-play mode
            if (iPlaybackMode == EDownloadThenPlay
                    && !iDownloadComplete)
            {
                return true;
            }
            //filter any data ready in dl-only mode, though I don't
            //think it's possible.
            if (iPlaybackMode == EDownloadOnly)
                return true;

            iDataReady = true;

            break;
        case PVMFInfoRemoteSourceNotification:
            //we get this event for "not pseudostreamable" for both PVX
            //and 3gpp.  Only pass it up for 3gpp.
            if (iSourceFormat != PVMF_MIME_DATA_SOURCE_HTTP_URL)
                return true;
            break;
        default:
            break;
    }
    return false;
}

void PVMFDownloadManagerNode::ChangeNodeState(TPVMFNodeInterfaceState aNewState)
{
    //Update the node state

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::ChangeNodeState() Old %d New %d", iInterfaceState, aNewState));

    PVMFNodeInterface::SetState(aNewState);
}


PVMFStatus PVMFDownloadManagerNode::DoQueryUuid(PVMFDownloadManagerNodeCommand& aCmd)
{
    //Start executing a node command

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::DoQueryUuid() In"));

    OSCL_String* mimetype;
    Oscl_Vector<PVUuid, OsclMemAllocator> *uuidvec;
    bool exactmatch;
    aCmd.PVMFDownloadManagerNodeCommandBase::Parse(mimetype, uuidvec, exactmatch);

    // @TODO Add MIME string matching
    // For now just return all available extension interface UUID
    uuidvec->push_back(PVMF_TRACK_SELECTION_INTERFACE_UUID);
    uuidvec->push_back(PVMF_DATA_SOURCE_INIT_INTERFACE_UUID);
    uuidvec->push_back(KPVMFMetadataExtensionUuid);
    uuidvec->push_back(PvmfDataSourcePlaybackControlUuid);
    uuidvec->push_back(PVMI_CAPABILITY_AND_CONFIG_PVUUID);

    return PVMFSuccess;
}


PVMFStatus PVMFDownloadManagerNode::DoQueryInterface(PVMFDownloadManagerNodeCommand& aCmd)
{
    //Start executing a node command

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::DoQueryInterface() In"));

    PVUuid* uuid;
    PVInterface** ptr;
    aCmd.PVMFDownloadManagerNodeCommandBase::Parse(uuid, ptr);

    if (queryInterface(*uuid, *ptr))
    {
        //Schedule further queries on sub-nodes...
        return ScheduleSubNodeCommands(aCmd);
    }
    else
    {
        //interface not supported
        *ptr = NULL;
        return PVMFFailure;
    }
}

PVMFStatus PVMFDownloadManagerNode::DoRequestPort(PVMFDownloadManagerNodeCommand& aCmd)
{
    //Start executing a node command

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::DoRequestPort() In"));

    if (iInterfaceState != EPVMFNodePrepared)
        return PVMFErrInvalidState;

    return ScheduleSubNodeCommands(aCmd);
}

PVMFStatus PVMFDownloadManagerNode::DoReleasePort(PVMFDownloadManagerNodeCommand& aCmd)
{
    //Start executing a node command

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::DoReleasePort() In"));

    return ScheduleSubNodeCommands(aCmd);
}

PVMFStatus PVMFDownloadManagerNode::DoInitNode(PVMFDownloadManagerNodeCommand& aCmd)
{
    //Start executing a node command

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::DoInitNode() In"));

    if (iInterfaceState != EPVMFNodeIdle)
        return PVMFErrInvalidState;

    return ScheduleSubNodeCommands(aCmd);
}

PVMFStatus PVMFDownloadManagerNode::DoPrepareNode(PVMFDownloadManagerNodeCommand& aCmd)
{
    //Start executing a node command

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::DoPrepareNode() In"));

    if (iInterfaceState != EPVMFNodeInitialized)
        return PVMFErrInvalidState;

    return ScheduleSubNodeCommands(aCmd);
}

PVMFStatus PVMFDownloadManagerNode::DoStartNode(PVMFDownloadManagerNodeCommand& aCmd)
{
    //Start executing a node command

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::DoStartNode() In"));

    if (iInterfaceState != EPVMFNodePrepared
            && iInterfaceState != EPVMFNodePaused)
        return PVMFErrInvalidState;

    return ScheduleSubNodeCommands(aCmd);
}

PVMFStatus PVMFDownloadManagerNode::DoStopNode(PVMFDownloadManagerNodeCommand& aCmd)
{
    //Start executing a node command

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::DoStopNode() In"));

    if (iInterfaceState != EPVMFNodeStarted
            && iInterfaceState != EPVMFNodePaused
            && iInterfaceState != EPVMFNodeError)//allow a stop in error state.
        return PVMFErrInvalidState;

    return ScheduleSubNodeCommands(aCmd);
}

PVMFStatus PVMFDownloadManagerNode::DoFlushNode(PVMFDownloadManagerNodeCommand& aCmd)
{
    //Start executing a node command

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::DoFlushNode() In"));

    if (iInterfaceState != EPVMFNodeStarted
            && iInterfaceState != EPVMFNodePaused)
        return PVMFErrInvalidState;

    return ScheduleSubNodeCommands(aCmd);
}

PVMFStatus PVMFDownloadManagerNode::DoPauseNode(PVMFDownloadManagerNodeCommand& aCmd)
{
    //Start executing a node command

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::DoPauseNode() In"));

    if (iInterfaceState != EPVMFNodeStarted)
        return PVMFErrInvalidState;

    return ScheduleSubNodeCommands(aCmd);
}

PVMFStatus PVMFDownloadManagerNode::DoResetNode(PVMFDownloadManagerNodeCommand& aCmd)
{
    //remove the clock observer
    if (iPlayBackClock != NULL)
    {
        if (iClockNotificationsInf != NULL)
        {
            iClockNotificationsInf->RemoveClockStateObserver(*this);
            iPlayBackClock->DestroyMediaClockNotificationsInterface(iClockNotificationsInf);
            iClockNotificationsInf = NULL;
        }
    }

    //Start executing a node command
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::DoResetNode() In"));

    //Reset the sub-nodes first.
    return ScheduleSubNodeCommands(aCmd);
}

PVMFStatus PVMFDownloadManagerNode::DoCancelAllCommands(PVMFDownloadManagerNodeCommand& aCmd)
{
    OSCL_UNUSED_ARG(aCmd);
    //Start executing a node command

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::DoCancelAllCommands() In"));

    //first cancel the current command if any
    while (!iCurrentCommand.empty())
    {
        if (iFormatParserNode.CancelPendingCommand()
                || iProtocolEngineNode.CancelPendingCommand()
                || iSocketNode.CancelPendingCommand()
                || iRecognizerNode.CancelPendingCommand()
           )
        {
            return PVMFPending;//wait on sub-node cancel to complete.
        }
        CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrCancelled, NULL, NULL);
    }

    //next cancel all queued commands
    //start at element 1 since this cancel command is element 0.
    while (iInputCommands.size() > 1)
    {
        CommandComplete(iInputCommands, iInputCommands[1], PVMFErrCancelled, NULL, NULL);
    }

    return PVMFSuccess;
}

PVMFStatus PVMFDownloadManagerNode::DoCancelCommand(PVMFDownloadManagerNodeCommand& aCmd)
{
    //Start executing a node command

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::DoCancelCommand() In"));

    //extract the command ID from the parameters.
    PVMFCommandId id;
    aCmd.PVMFDownloadManagerNodeCommandBase::Parse(id);

    //first check "current" command if any
    PVMFDownloadManagerNodeCommand* cmd = iCurrentCommand.FindById(id);
    if (cmd)
    {
        if (iFormatParserNode.CancelPendingCommand()
                || iProtocolEngineNode.CancelPendingCommand()
                || iRecognizerNode.CancelPendingCommand()
           )
        {
            return PVMFPending;//wait on sub-node cancel to complete.
        }
        CommandComplete(iCurrentCommand, *cmd, PVMFErrCancelled, NULL, NULL);
        return PVMFSuccess;
    }

    //next check input queue.
    //start at element 1 since this cancel command is element 0.
    cmd = iInputCommands.FindById(id, 1);
    if (cmd)
    {
        //cancel the queued command
        CommandComplete(iInputCommands, *cmd, PVMFErrCancelled, NULL, NULL);
        //report cancel success
        return PVMFSuccess;
    }

    //if we get here the command isn't queued so the cancel fails.
    return PVMFFailure;
}


PVMFStatus PVMFDownloadManagerNode::DoGetNodeMetadataKey(PVMFDownloadManagerNodeCommand& aCmd)
{
    //Start executing a node command

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::DoGetNodeMetadataKey() In"));

    return ScheduleSubNodeCommands(aCmd);
}



PVMFStatus PVMFDownloadManagerNode::DoGetNodeMetadataValue(PVMFDownloadManagerNodeCommand& aCmd)
{
    //Start executing a node command

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::DoGetNodeMetadataValue() In"));

    return ScheduleSubNodeCommands(aCmd);
}



PVMFStatus PVMFDownloadManagerNode::DoSetDataSourcePosition(PVMFDownloadManagerNodeCommand& aCmd)
{
    //Start executing a node command

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::DoSetDataSourcePosition() In"));

    return ScheduleSubNodeCommands(aCmd);
}


PVMFStatus PVMFDownloadManagerNode::DoQueryDataSourcePosition(PVMFDownloadManagerNodeCommand& aCmd)
{
    //Start executing a node command

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::DoQueryDataSourcePosition() In"));

    return ScheduleSubNodeCommands(aCmd);
}

void PVMFDownloadManagerNode::ContinueInitAfterTrackSelectDecision()
{
    //this is called during the Init sequence, once we have enough information
    //to make a definite track select decision.

    //See whether we need to stop to allow track selection on the download server.
    //If it's download-only, we don't offer this option, since the download must
    //be started in the Init.
    if (iPlaybackMode != EDownloadOnly
            && TrackSelectNode().iType == PVMFDownloadManagerSubNodeContainerBase::EProtocolEngine)
    {
        //stop the Init sequence here so we can do track selection on the download
        //server.
        ;
    }
    else
    {
        //else download-only, or there's no track selection available from the
        //PE node.  Continue the Init or Prepare sequence.
        ContinueFromDownloadTrackSelectionPoint();
    }
}

void PVMFDownloadManagerNode::ContinueFromDownloadTrackSelectionPoint()
{
    //Continue the Init or Prepare sequence, stopping at parser init.

    //start the download.
    Push(iProtocolEngineNode, PVMFDownloadManagerSubNodeContainerBase::EStart);

    //initiate file recognize & parse, unless this is download-only mode.
    if (iPlaybackMode != EDownloadOnly)
    {
        //do recognizer sequence if needed.
        if (iSourceFormat == PVMF_MIME_DATA_SOURCE_PVX_FILE)
        {
            //PXV is always assumed to be MP4
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,
                            "PVMFDownloadManagerNode::ContinueFromDownloadTrackSelectionPoint Setting format to MP4"));
            iMimeType = PVMF_MIME_MPEG4FF;
        }
        else
        {
            //for other source formats, use the recognizer to determine the format.
            Push(iRecognizerNode, PVMFDownloadManagerSubNodeContainerBase::ERecognizerStart);
            Push(iRecognizerNode, PVMFDownloadManagerSubNodeContainerBase::ERecognizerClose);
        }

        //create parser
        Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EParserCreate);

        // Send commands to the parser node to query these extension interfaces.
        Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EQueryDataSourceInit);
        Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EQueryTrackSelection);
        Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EQueryMetadata);
        Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EQueryDatastreamUser);
        Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EQueryDataSourcePlayback);
        Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EQueryFFProgDownload);
        Push(iProtocolEngineNode, PVMFDownloadManagerSubNodeContainerBase::ESetFFProgDownloadSupport);
        Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::ECPMQueryLicenseInterface);

        //if this is PVX, we need to wait on movie atom before we can
        //init parser.
        if (iSourceFormat == PVMF_MIME_DATA_SOURCE_PVX_FILE)
        {
            if (iMovieAtomComplete || iDownloadComplete)
            {
                iParserInit = true;
                Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EInit);
            }
            else
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,
                                "PVMFDownloadManagerNode::ContinueFromDownloadTrackSelectionPoint Setting flag to Init Parser after Movie Atom Downloaded"));
                //set this flag to trigger parser init when movie atom is done.
                iParserInitAfterMovieAtom = true;
            }
        }
        else
        {
            //for other formats, go ahead and init parser.  Init will block until
            //receiving movie atom.
            iParserInit = true;
            Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EInit);
        }
    }
}

//Called when movie atom is received, or when download is complete
//but movie atom was never received.
void PVMFDownloadManagerNode::ContinueAfterMovieAtom()
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFDownloadManagerNode::ContinueAfterMovieAtom() "));

    if (!iMovieAtomComplete)
    {
        iMovieAtomComplete = true;
        //see whether we need to continue with parser init
        if (iParserInitAfterMovieAtom)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFDownloadManagerNode::ContinueAfterMovieAtom() Continuing to Parser Init"));
            iParserInitAfterMovieAtom = false;
            iParserInit = true;
            Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EInit);
            RunIfNotReady();
        }
        //see whether we need to continue with parser prepare
        if (iParserPrepareAfterMovieAtom)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                            (0, "PVMFDownloadManagerNode::ContinueAfterMovieAtom() Continuing to Parser Prepare"));
            iParserPrepareAfterMovieAtom = false;
            Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EPrepare);
            RunIfNotReady();
        }
    }
}

PVMFNodeInterface* PVMFDownloadManagerNode::CreateParser()
{
    if (!(iMimeType == PVMF_MIME_FORMAT_UNKNOWN))
    {
        PVMFNodeInterface *iSourceNode = NULL;
        PVMFFormatType outputFormatType = PVMF_MIME_FORMAT_UNKNOWN;
        iFmt = iMimeType.get_str();
        PVMFStatus status =
            iPlayerNodeRegistry->QueryRegistry(iFmt, outputFormatType, iDNodeUuids);
        if ((status == PVMFSuccess) && (iDNodeUuids.size() > 0))
        {
            int32 leavecode = 0;
            OSCL_TRY(leavecode, iSourceNode = iPlayerNodeRegistry->CreateNode(iDNodeUuids[iDNodeUuidCount]));
            OSCL_FIRST_CATCH_ANY(leavecode, return NULL);
            iDNodeUuidCount++;
            return iSourceNode;
        }
    }
    return NULL;
}

PVMFStatus PVMFDownloadManagerNode::ScheduleSubNodeCommands(PVMFDownloadManagerNodeCommand& aCmd)
{
    //given the node command ID, create the sub-node command vector, initiate the processing and return the node command status.

    OSCL_ASSERT(iSubNodeCmdVec.empty());

    //Create the vector of all the commands in the sequence.
    switch (aCmd.iCmd)
    {

        case PVMF_GENERIC_NODE_QUERYINTERFACE:
        {
            //When we get here we've already called queryInterface on this node
            //for the interface.  This code schedules any additional sub-node commands
            //that are needed to support the interface.

            //extract uuid from Node command...
            PVUuid*aUuid;
            PVInterface**aInterface;
            aCmd.PVMFDownloadManagerNodeCommandBase::Parse(aUuid, aInterface);
            OSCL_ASSERT(aUuid != NULL);

            if (*aUuid == PVMF_DATA_SOURCE_INIT_INTERFACE_UUID)
            {
                //To support data source init interface we need a bunch of sub-node interfaces.
                Push(iProtocolEngineNode, PVMFDownloadManagerSubNodeContainerBase::EQueryProtocolEngine);
                Push(iProtocolEngineNode, PVMFDownloadManagerSubNodeContainerBase::EQueryDatastreamUser);
                Push(iProtocolEngineNode, PVMFDownloadManagerSubNodeContainerBase::EQueryDataSourceInit);
                Push(iProtocolEngineNode, PVMFDownloadManagerSubNodeContainerBase::EQueryDownloadProgress);
            }
            //else nothing else needed for other interfaces.
        }
        break;

        case PVMF_GENERIC_NODE_INIT:
            //check for second "Init" command after a license acquire.
            if (iInitFailedLicenseRequired)
            {
                iParserInit = true;
                Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EInit);
            }
            else

            {
                //reset any prior download/playback event
                iDownloadComplete = false;
                iParserInit = false;
                iDataReady = false;
                iMovieAtomComplete = false;
                iParserInitAfterMovieAtom = false;
                iParserPrepareAfterMovieAtom = false;
                iRecognizerError = false;
                iInitFailedLicenseRequired = false;

                //reset any prior track select decisions.
                iFormatParserNode.iTrackSelection = NULL;
                iProtocolEngineNode.iTrackSelection = NULL;
                iNoPETrackSelect = false;

                //reset any prior recognizer decisions.
                iMimeType = PVMF_MIME_FORMAT_UNKNOWN;

                // Send the INIT command to the protocol engine node, followed by the Socket Node.
                Push(iProtocolEngineNode, PVMFDownloadManagerSubNodeContainerBase::EInit);
                Push(iSocketNode, PVMFDownloadManagerSubNodeContainerBase::EInit);
                // Issue the port request to the Protocol Engine Node and the socket node
                // NOTE: The request for the socket node's port must come first, followed by the protocol node,
                // because the code to connect the two ports in CommandDone() will do so when the protocol node's port is returned.
                Push(iSocketNode, PVMFDownloadManagerSubNodeContainerBase::ERequestPort);
                Push(iProtocolEngineNode, PVMFDownloadManagerSubNodeContainerBase::ERequestPort);
                // The two ports will be connected in CommandDone, when the 2nd port request completes.
                // After the ports are connected, the datastream factory is passed to the protocol engine node.
                Push(iSocketNode, PVMFDownloadManagerSubNodeContainerBase::EPrepare);
                Push(iSocketNode, PVMFDownloadManagerSubNodeContainerBase::EStart);
                Push(iProtocolEngineNode, PVMFDownloadManagerSubNodeContainerBase::EPrepare);

                if (TrackSelectNode().iType == PVMFDownloadManagerSubNodeContainerBase::EFormatParser)
                {
                    //parser is doing track selection, there's no question
                    ContinueInitAfterTrackSelectDecision();
                }
                else
                {
                    //PE node may be doing track selection, but to be sure, we need
                    //to wait until it is prepared, then request the track selection interface.
                    iProtocolEngineNode.iTrackSelection = NULL;
                    Push(iProtocolEngineNode, PVMFDownloadManagerSubNodeContainerBase::EQueryTrackSelection);
                    //once this command is complete, we will call ContinueInitAfterTrackSelectDecision()
                }
            }
            break;

        case PVMF_GENERIC_NODE_PREPARE:
            //if protocol engine node did track selection, then we need to continue
            //to the file parse stage here.  Otherwise it was already done in the Init.
            if (TrackSelectNode().iType == PVMFDownloadManagerSubNodeContainerBase::EProtocolEngine)
            {
                ContinueFromDownloadTrackSelectionPoint();
            }
            //if we initiated file parse sequence already, then go ahead and prepare
            //the parser node.
            if (iParserInit)
            {
                Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EPrepare);
            }
            //if we're waiting on movie atom to init parser, then set a flag so we'll
            //also do the parser prepare when it arrives.
            else if (iParserInitAfterMovieAtom)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,
                                "PVMFDownloadManagerNode::ScheduleSubNodeCommands Setting flag to Prepare Parser after Movie Atom Downloaded"));
                iParserPrepareAfterMovieAtom = true;
            }
            break;

        case PVMF_GENERIC_NODE_REQUESTPORT:
            //if file isn't parsed (as in download-only), then fail command
            if (!iFormatParserNode.iNode)
                return PVMFErrNotSupported;
            Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::ERequestPort);
            break;

        case PVMF_GENERIC_NODE_RELEASEPORT:
            //if file isn't parsed (as in download-only), then fail command
            if (!iFormatParserNode.iNode)
                return PVMFErrNotSupported;
            Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EReleasePort);
            break;

        case PVMF_GENERIC_NODE_START:
            //Re-start socket node & PE node in case they were stopped by a prior
            //stop command.
            if (iSocketNode.iNode->GetState() == EPVMFNodePrepared)
                Push(iSocketNode, PVMFDownloadManagerSubNodeContainerBase::EStart);
            if (iProtocolEngineNode.iNode->GetState() == EPVMFNodePrepared)
                Push(iProtocolEngineNode, PVMFDownloadManagerSubNodeContainerBase::EStart);
            //Start or re-start parser node (unless download-only)
            if (iFormatParserNode.iNode)
                Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EStart);
            break;

        case PVMF_GENERIC_NODE_STOP:
            iDataReady = false;
            //Stop parser (unless download-only)
            if (iFormatParserNode.iNode)
                Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EStop);
            //Stop PE node & socket node.
            Push(iProtocolEngineNode, PVMFDownloadManagerSubNodeContainerBase::EStop);
            Push(iSocketNode, PVMFDownloadManagerSubNodeContainerBase::EStop);
            break;

        case PVMF_GENERIC_NODE_FLUSH:
            if (iFormatParserNode.iNode)
                Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EFlush);
            break;

        case PVMF_GENERIC_NODE_PAUSE:
            //note: pause/resume download is not supported.
            if (iFormatParserNode.iNode)
                Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EPause);
            break;

        case PVMF_GENERIC_NODE_RESET:
            //Stop socket node if needed.
            if (iSocketNode.iNode->GetState() == EPVMFNodeStarted
                    || iSocketNode.iNode->GetState() == EPVMFNodePaused)
            {
                Push(iSocketNode, PVMFDownloadManagerSubNodeContainerBase::EStop);
            }
            //Stop PE node if needed.
            if (iProtocolEngineNode.iNode->GetState() == EPVMFNodeStarted
                    || iProtocolEngineNode.iNode->GetState() == EPVMFNodePaused)
            {
                Push(iProtocolEngineNode, PVMFDownloadManagerSubNodeContainerBase::EStop);
            }
            //Reset & cleanup all nodes.
            if (iFormatParserNode.iNode)
                Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EReset);
            Push(iSocketNode, PVMFDownloadManagerSubNodeContainerBase::EReset);
            Push(iProtocolEngineNode, PVMFDownloadManagerSubNodeContainerBase::EReset);
            Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::ECleanup);
            Push(iProtocolEngineNode, PVMFDownloadManagerSubNodeContainerBase::ECleanup);
            Push(iSocketNode, PVMFDownloadManagerSubNodeContainerBase::ECleanup);
            break;

        case PVDLM_NODE_CMD_SETDATASOURCEPOSITION:
            //if file isn't parsed (as in download-only), then fail command
            if (!iFormatParserNode.iNode)
                return PVMFErrNotSupported;
            Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::ESetDataSourcePosition);
            break;

        case PVDLM_NODE_CMD_QUERYDATASOURCEPOSITION:
            //if file isn't parsed (as in download-only), then fail command
            if (!iFormatParserNode.iNode)
                return PVMFErrNotSupported;
            Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EQueryDataSourcePosition);
            break;

        case PVDLM_NODE_CMD_GETNODEMETADATAKEY:
            //if file isn't parsed (as in download-only), then fail command
            if (!iFormatParserNode.iNode)
                return PVMFErrNotSupported;
            Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EGetMetadataKey);
            break;

        case PVDLM_NODE_CMD_GETNODEMETADATAVALUE:
            //if file isn't parsed (as in download-only), then fail command
            if (!iFormatParserNode.iNode)
                return PVMFErrNotSupported;
            Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::EGetMetadataValue);
            break;

        default:
            OSCL_ASSERT(false);
            break;
    }

    if (iSubNodeCmdVec.empty())
    {
        //in a few cases there's nothing needed and no new commands
        //were issued-- so succeed here.
        return PVMFSuccess;
    }
    else
    {
        //Wakeup the node to start issuing the sub-node commands.
        RunIfNotReady();

        //the node command is pending.
        return PVMFPending;
    }
}

void PVMFDownloadManagerNode::Push(PVMFDownloadManagerSubNodeContainerBase& n, PVMFDownloadManagerSubNodeContainerBase::CmdType c)
{
    //push a sub-node command onto the cmd vector
    CmdElem elem;
    elem.iCmd = c;
    elem.iNC = &n;
    iSubNodeCmdVec.push_back(elem);
}

PVMFCommandId
PVMFDownloadManagerNode::GetLicense(PVMFSessionId aSessionId,
                                    OSCL_wString& aContentName,
                                    OsclAny* aData,
                                    uint32 aDataSize,
                                    int32 aTimeoutMsec,
                                    OsclAny* aContextData)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::GetLicense - Wide called"));
    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommand::Construct(aSessionId,
            PVDLM_NODE_CMD_GET_LICENSE_W,
            aContentName,
            aData,
            aDataSize,
            aTimeoutMsec,
            aContextData);
    return QueueCommandL(cmd);
}

PVMFCommandId
PVMFDownloadManagerNode::GetLicense(PVMFSessionId aSessionId,
                                    OSCL_String&  aContentName,
                                    OsclAny* aData,
                                    uint32 aDataSize,
                                    int32 aTimeoutMsec,
                                    OsclAny* aContextData)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::GetLicense - Non-Wide called"));
    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommand::Construct(aSessionId,
            PVDLM_NODE_CMD_GET_LICENSE,
            aContentName,
            aData,
            aDataSize,
            aTimeoutMsec,
            aContextData);
    return QueueCommandL(cmd);
}


PVMFCommandId
PVMFDownloadManagerNode::CancelGetLicense(PVMFSessionId aSessionId
        , PVMFCommandId aCmdId
        , OsclAny* aContextData)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::GetLicense - Non-Wide called"));
    PVMFDownloadManagerNodeCommand cmd;
    cmd.PVMFDownloadManagerNodeCommandBase::Construct(aSessionId,
            PVDLM_NODE_CMD_CANCEL_GET_LICENSE,
            aCmdId,
            aContextData);
    return QueueCommandL(cmd);
}

PVMFStatus PVMFDownloadManagerNode::DoGetLicense(PVMFDownloadManagerNodeCommand& aCmd,
        bool aWideCharVersion)
{
    OSCL_UNUSED_ARG(aCmd);
    if (iFormatParserNode.LicenseInterface() == NULL)
    {
        return PVMFErrNotSupported;
    }

    if (aWideCharVersion == true)
    {
        Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::ECPMGetLicenseW);
    }
    else
    {
        Push(iFormatParserNode, PVMFDownloadManagerSubNodeContainerBase::ECPMGetLicense);
    }
    RunIfNotReady();
    return PVMFPending;
}

void PVMFDownloadManagerNode::CompleteGetLicense()
{
    CommandComplete(iCurrentCommand,
                    iCurrentCommand.front(),
                    PVMFSuccess, NULL, NULL);
}

PVMFStatus PVMFDownloadManagerNode::DoCancelGetLicense(PVMFDownloadManagerNodeCommand& aCmd)
{
    OSCL_UNUSED_ARG(aCmd);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFDownloadManagerNode::DoCancelGetLicense called"));
    if (iFormatParserNode.LicenseInterface() == NULL)
    {
        return PVMFErrNotSupported;
    }
    else
    {
        iFormatParserNode.iCancelCmdState = PVMFDownloadManagerSubNodeContainerBase::EBusy;
        iFormatParserNode.iCPMCancelGetLicenseCmdId =
            iFormatParserNode.LicenseInterface()->CancelGetLicense(iFormatParserNode.iSessionId, iFormatParserNode.iCPMGetLicenseCmdId);
        RunIfNotReady();
    }
    return PVMFPending;
}

//
// PVMFDownloadManagerSubNodeContainer Implementation.
//

PVMFDownloadManagerSubNodeContainerBase::PVMFDownloadManagerSubNodeContainerBase()
{
    iCmdState = EIdle;
    iCancelCmdState = EIdle;
}

void PVMFDownloadManagerSubNodeContainerBase::Construct(NodeType t, PVMFDownloadManagerNode* c)
{
    iContainer = c;
    iType = t;
}

void PVMFDownloadManagerSubNodeContainer::Cleanup()
{
    //release all the queried interfaces.
    if (iDataSourceInit)
    {
        iDataSourceInit->removeRef();
        iDataSourceInit = NULL;
    }
    if (iProtocolEngineExtensionInt)
    {
        iProtocolEngineExtensionInt->removeRef();
        iProtocolEngineExtensionInt = NULL;
    }
    if (iDatastreamUser)
    {
        iDatastreamUser->removeRef();
        iDatastreamUser = NULL;
    }
    if (iTrackSelection)
    {
        iTrackSelection->removeRef();
        iTrackSelection = NULL;
    }
    if (iMetadata)
    {
        iMetadata->removeRef();
        iMetadata = NULL;
    }
    if (iDataSourcePlayback)
    {
        iDataSourcePlayback->removeRef();
        iDataSourcePlayback = NULL;
    }
    if (iFormatProgDownloadSupport)
    {
        iFormatProgDownloadSupport->removeRef();
        iFormatProgDownloadSupport = NULL;
    }
    if (iDownloadProgress)
    {
        iDownloadProgress->removeRef();
        iDownloadProgress = NULL;
    }
    if (iLicenseInterface)
    {
        iLicenseInterface->removeRef();
        iLicenseInterface = NULL;
    }
    //the node instance is cleaned up elsewhere.
}

void PVMFDownloadManagerRecognizerContainer::Cleanup()
{
    // Nothing to do here 'til recognizer is integrated
}

void PVMFDownloadManagerSubNodeContainer::Connect()
{
    //Issue connect command to the sub-node.

    //This container class is the observer.
    PVMFNodeSessionInfo info(this //cmd
                             , this, NULL //info
                             , this, NULL); //err

    if (iNode)
        iSessionId = iNode->Connect(info);
}

#define LOGSUBCMD(x) PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iContainer->iLogger, SUB_CMD_LOG_LEVEL, x)
#define GETNODESTR (iType==EFormatParser)?"Parser":((iType==EProtocolEngine)?"ProtEngine":"SockNode")

PVMFStatus PVMFDownloadManagerSubNodeContainer::IssueCommand(int32 aCmd)
{
    //Issue a command to the sub-node.
    //Return the sub-node completion status-- either pending, success, or failure.

    LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s () In", GETNODESTR));

    OSCL_ASSERT(!CmdPending());

    //find the current node command since we may need its parameters.

    OSCL_ASSERT(!iContainer->iCurrentCommand.empty());
    PVMFDownloadManagerNodeCommand* nodeCmd = &iContainer->iCurrentCommand.front();

    //save the sub-node command code
    iCmd = aCmd;

    switch (aCmd)
    {
        case ECleanup:
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling Cleanup", GETNODESTR));
            Cleanup();
            return PVMFSuccess;

        case EParserCreate:
            iNode = iContainer->CreateParser();
            if (iNode)
            {
                Connect();
                iNode->ThreadLogon();
                return PVMFSuccess;
            }
            return PVMFErrCorrupt;

        case EQueryDataSourceInit:
            OSCL_ASSERT(iNode != NULL);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling QueryInterface(data source init)", GETNODESTR));
            iCmdState = EBusy;
            iCmdId = iNode->QueryInterface(iSessionId, PVMF_DATA_SOURCE_INIT_INTERFACE_UUID, iDataSourceInit);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
            return PVMFPending;

        case EQueryProtocolEngine:
            OSCL_ASSERT(iNode != NULL);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling QueryInterface(ProtocolEngine)", GETNODESTR));
            iCmdState = EBusy;
            iCmdId = iNode->QueryInterface(iSessionId, KPVMFProtocolEngineNodeExtensionUuid, iProtocolEngineExtensionInt);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
            return PVMFPending;

        case EQueryDatastreamUser:
            OSCL_ASSERT(iNode != NULL);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling QueryInterface(DatastreamUser)", GETNODESTR));
            iCmdState = EBusy;
            iCmdId = iNode->QueryInterface(iSessionId, PVMIDatastreamuserInterfaceUuid, iDatastreamUser);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
            return PVMFPending;

        case EQueryTrackSelection:
            OSCL_ASSERT(iNode != NULL);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling QueryInterface(track selection)", GETNODESTR));
            iCmdState = EBusy;
            iCmdId = iNode->QueryInterface(iSessionId, PVMF_TRACK_SELECTION_INTERFACE_UUID, iTrackSelection);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
            return PVMFPending;

        case EQueryMetadata:
            OSCL_ASSERT(iNode != NULL);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling QueryInterface(metadata)", GETNODESTR));
            iCmdState = EBusy;
            iCmdId = iNode->QueryInterface(iSessionId, KPVMFMetadataExtensionUuid, iMetadata);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
            return PVMFPending;

        case ECPMQueryLicenseInterface:
            OSCL_ASSERT(iNode != NULL);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling QueryInterface(License)", GETNODESTR));
            iCmdState = EBusy;
            iCmdId = iNode->QueryInterface(iSessionId, PVMFCPMPluginLicenseInterfaceUuid, iLicenseInterface);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
            return PVMFPending;

        case EQueryDataSourcePlayback:
            OSCL_ASSERT(iNode != NULL);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling QueryInterface(datasourcePB)", GETNODESTR));
            iCmdState = EBusy;
            iCmdId = iNode->QueryInterface(iSessionId, PvmfDataSourcePlaybackControlUuid, iDataSourcePlayback);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
            return PVMFPending;

        case EInit:
            OSCL_ASSERT(iNode != NULL);
            if (iType == EFormatParser)
            {
                // For this command, which gets pushed to the format parser node, we set the source init and also
                // set the datstream factory
                LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling SetSourceInitializationData", GETNODESTR));

                if (!DataSourceInit())
                    return PVMFFailure; //no source init interface?
                if (!DatastreamUser())
                    return PVMFFailure; //no datastreamuser interface?

                //Pass data to the parser node.
                if (iContainer->iInitFailedLicenseRequired)
                {
                    ;//do nothing-- data was already set on the first init call.
                }
                else
                {
                    //Pass source data
                    if (iContainer->iSourceFormat == PVMF_MIME_DATA_SOURCE_PVX_FILE)
                    {
                        // let the parser know this is PVX format.
                        PVMFFormatType fmt = PVMF_MIME_DATA_SOURCE_PVX_FILE;
                        (DataSourceInit())->SetSourceInitializationData(iContainer->iDownloadFileName
                                , fmt
                                , (OsclAny*)&iContainer->iLocalDataSource);
                    }
                    else if (iContainer->iSourceFormat == PVMF_MIME_DATA_SOURCE_SHOUTCAST_URL)
                    {
                        // let the parser node know that it is playing from a shoutcast stream
                        (DataSourceInit())->SetSourceInitializationData(iContainer->iDownloadFileName
                                , iContainer->iSourceFormat
                                , (OsclAny*)iContainer->iSourceData);
                    }
                    else
                    {
                        // pass the recognized format to the parser.
                        (DataSourceInit())->SetSourceInitializationData(iContainer->iDownloadFileName
                                , iContainer->iFmt
                                , (OsclAny*)iContainer->iSourceData);
                    }

                    //Pass datastream data.
                    (DatastreamUser())->PassDatastreamFactory(*(iContainer->iReadFactory), (int32)0);
                    PVMFFileBufferDataStreamWriteDataStreamFactoryImpl* wdsfactory =
                        OSCL_STATIC_CAST(PVMFFileBufferDataStreamWriteDataStreamFactoryImpl*, iContainer->iWriteFactory);
                    int32 leavecode = 0;
                    OSCL_TRY(leavecode,
                             PVMFDataStreamReadCapacityObserver* obs =
                                 OSCL_STATIC_CAST(PVMFDataStreamReadCapacityObserver*, wdsfactory);
                             (DatastreamUser())->PassDatastreamReadCapacityObserver(obs));
                    OSCL_FIRST_CATCH_ANY(leavecode,
                                         LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s PassDatastreamReadCapacityObserver not supported", GETNODESTR));
                                        );
                }

                LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling Init ", GETNODESTR));
                iCmdState = EBusy;
                iCmdId = iNode->Init(iSessionId);
                LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
                return PVMFPending;
            }
            else
            {
                LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling Init ", GETNODESTR));
                iCmdState = EBusy;
                iCmdId = iNode->Init(iSessionId);
                LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
                return PVMFPending;
            }

        case ECPMGetLicenseW:
        {
            OSCL_ASSERT(iNode != NULL);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling ECPMGetLicenseW", GETNODESTR));
            iCmdState = EBusy;
            OSCL_wString* contentName = NULL;
            OsclAny* data = NULL;
            uint32 dataSize = 0;
            int32 timeoutMsec = 0;
            nodeCmd->Parse(contentName,
                           data,
                           dataSize,
                           timeoutMsec);
            iCmdId =
                LicenseInterface()->GetLicense(iSessionId,
                                               *contentName,
                                               data,
                                               dataSize,
                                               timeoutMsec);
            iCPMGetLicenseCmdId = iCmdId;

            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
            return PVMFPending;
        }
        case ECPMGetLicense:
        {
            OSCL_ASSERT(iNode != NULL);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling ECPMGetLicense", GETNODESTR));
            iCmdState = EBusy;
            OSCL_String* contentName = NULL;
            OsclAny* data = NULL;
            uint32 dataSize = 0;
            int32 timeoutMsec = 0;
            nodeCmd->Parse(contentName,
                           data,
                           dataSize,
                           timeoutMsec);
            iCmdId =
                LicenseInterface()->GetLicense(iSessionId,
                                               *contentName,
                                               data,
                                               dataSize,
                                               timeoutMsec);
            iCPMGetLicenseCmdId = iCmdId;

            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
            return PVMFPending;
        }

        case ERequestPort:
            OSCL_ASSERT(iNode != NULL);
            // The parameters to RequestPort vary depending on which node we're getting a port from, so we switch on it.
            switch (iType)
            {
                case EProtocolEngine:
                    LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling RequestPort ", GETNODESTR));
                    iCmdState = EBusy;
                    // For protocol engine port request, we don't need port tag or config info because it's the only port we ask it for.
                    iCmdId = iNode->RequestPort(iSessionId, (int32)0);
                    LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
                    return PVMFPending;

                case ESocket:
                    LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling RequestPort with port config %s", GETNODESTR, iContainer->iServerAddr.get_cstr()));
                    iCmdState = EBusy;
                    //append a mimestring to the port for socket node logging
                    iContainer->iServerAddr += ";mime=download";
                    iCmdId = iNode->RequestPort(iSessionId, PVMF_SOCKET_NODE_PORT_TYPE_PASSTHRU, &iContainer->iServerAddr);
                    LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
                    return PVMFPending;

                case EFormatParser:
                    //extract params from current Node command.
                    OSCL_ASSERT(nodeCmd->iCmd == PVMF_GENERIC_NODE_REQUESTPORT);
                    {
                        int32 aPortTag;
                        OSCL_String*aMimetype;
                        nodeCmd->PVMFDownloadManagerNodeCommandBase::Parse(aPortTag, aMimetype);

                        LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling RequestPort ", GETNODESTR));
                        iCmdState = EBusy;
                        iCmdId = iNode->RequestPort(iSessionId, aPortTag, aMimetype);
                    }
                    LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
                    return PVMFPending;

                default:
                    OSCL_ASSERT(false);
                    return PVMFFailure;
            }

        case EReleasePort:
            OSCL_ASSERT(iNode != NULL);
            {
                //extract params from current Node command.
                OSCL_ASSERT(nodeCmd->iCmd == PVMF_GENERIC_NODE_RELEASEPORT);
                PVMFPortInterface *port;
                nodeCmd->PVMFDownloadManagerNodeCommandBase::Parse(port);
                OSCL_ASSERT(port != NULL);

                LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling ReleasePort", GETNODESTR));
                iCmdState = EBusy;
                iCmdId = iNode->ReleasePort(iSessionId, *port);
                LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
                return PVMFPending;
            }

        case EPrepare:
            OSCL_ASSERT(iNode != NULL);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling Prepare", GETNODESTR));
            iCmdState = EBusy;
            iCmdId = iNode->Prepare(iSessionId);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
            return PVMFPending;

        case EStop:
            OSCL_ASSERT(iNode != NULL);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling Stop", GETNODESTR));
            iCmdState = EBusy;
            iCmdId = iNode->Stop(iSessionId);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
            return PVMFPending;

        case EStart:
            OSCL_ASSERT(iNode != NULL);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling Start", GETNODESTR));
            iCmdState = EBusy;
            iCmdId = iNode->Start(iSessionId);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
            return PVMFPending;

        case EPause:
            OSCL_ASSERT(iNode != NULL);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling Pause", GETNODESTR));
            iCmdState = EBusy;
            iCmdId = iNode->Pause(iSessionId);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
            return PVMFPending;

        case EFlush:
            OSCL_ASSERT(iNode != NULL);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling Flush", GETNODESTR));
            iCmdState = EBusy;
            iCmdId = iNode->Flush(iSessionId);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
            return PVMFPending;

        case EReset:
            OSCL_ASSERT(iNode != NULL);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling Reset", GETNODESTR));
            iCmdState = EBusy;
            iCmdId = iNode->Reset(iSessionId);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
            return PVMFPending;

        case EGetMetadataKey:
            OSCL_ASSERT(iNode != NULL);
            {
                if (!Metadata())
                    return PVMFErrNotSupported;//no interface!

                //extract params from current Node command.
                OSCL_ASSERT(nodeCmd->iCmd == PVDLM_NODE_CMD_GETNODEMETADATAKEY);

                PVMFMetadataList* aKeyList;
                uint32 starting_index;
                int32 max_entries;
                char* query_key;

                nodeCmd->Parse(aKeyList, starting_index, max_entries, query_key);
                OSCL_ASSERT(aKeyList != NULL);
                LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling GetNodeMetadataKeys", GETNODESTR));
                iCmdState = EBusy;
                iCmdId = (Metadata())->GetNodeMetadataKeys(iSessionId, *aKeyList, starting_index, max_entries, query_key, NULL);

                LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
                return PVMFPending;
            }


        case EGetMetadataValue:
            OSCL_ASSERT(iNode != NULL);
            {
                if (!Metadata())
                    return PVMFErrNotSupported;//no interface!

                //extract params from current Node command.
                OSCL_ASSERT(nodeCmd->iCmd == PVDLM_NODE_CMD_GETNODEMETADATAVALUE);
                PVMFMetadataList* aKeyList;
                Oscl_Vector<PvmiKvp, OsclMemAllocator>* aValueList;
                uint32 starting_index;
                int32 max_entries;
                nodeCmd->Parse(aKeyList, aValueList, starting_index, max_entries);
                OSCL_ASSERT(aKeyList != NULL);
                OSCL_ASSERT(aValueList != NULL);

                LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling GetNodeMetadataValues", GETNODESTR));
                iCmdState = EBusy;
                iCmdId = (Metadata())->GetNodeMetadataValues(iSessionId, *aKeyList, *aValueList, starting_index, max_entries, NULL);
                LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
                return PVMFPending;
            }

        case EQueryFFProgDownload:
            OSCL_ASSERT(iNode != NULL);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling QueryInterface (format prog dl)", GETNODESTR));
            iCmdState = EBusy;
            iCmdId = iNode->QueryInterface(iSessionId, PVMF_FF_PROGDOWNLOAD_SUPPORT_INTERFACE_UUID, iFormatProgDownloadSupport);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
            return PVMFPending;

        case EQueryDownloadProgress:
            OSCL_ASSERT(iNode != NULL);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling QueryInterface (dl prog)", GETNODESTR));
            iCmdState = EBusy;
            iCmdId = iNode->QueryInterface(iSessionId, PVMF_DOWNLOAD_PROGRESS_INTERFACE_UUID, iDownloadProgress);
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
            return PVMFPending;

        case ESetFFProgDownloadSupport:
            OSCL_ASSERT(iNode != NULL);

            if (!DownloadProgress() || !iContainer->iFormatParserNode.FormatProgDownloadSupport())
                return PVMFErrNotSupported;//no interface!

            //pass parser node format prog download interface to the protocol node.
            LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling setFormatDownloadSupportInterface", GETNODESTR));
            (DownloadProgress())->setFormatDownloadSupportInterface(iContainer->iFormatParserNode.FormatProgDownloadSupport());
            return PVMFSuccess;

        case ESetDataSourcePosition:
            OSCL_ASSERT(iNode != NULL);
            {
                if (!DataSourcePlayback())
                    return PVMFErrNotSupported;//no interface!

                //extract params from current Node command.
                OSCL_ASSERT(nodeCmd->iCmd == PVDLM_NODE_CMD_SETDATASOURCEPOSITION);
                PVMFTimestamp aTargetNPT;
                PVMFTimestamp* aActualNPT;
                PVMFTimestamp* aActualMediaDataTS;
                uint32 streamID = 0;
                bool aJump;
                nodeCmd->Parse(aTargetNPT, aActualNPT, aActualMediaDataTS, aJump, streamID);
                OSCL_ASSERT(aActualNPT != NULL);
                OSCL_ASSERT(aActualMediaDataTS != NULL);

                LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling SetDataSourcePosition", GETNODESTR));
                iCmdState = EBusy;
                iCmdId = (DataSourcePlayback())->SetDataSourcePosition(iSessionId, aTargetNPT, *aActualNPT, *aActualMediaDataTS, aJump, streamID);
                LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
                return PVMFPending;
            }

        case EQueryDataSourcePosition:
            OSCL_ASSERT(iNode != NULL);
            {
                if (!DataSourcePlayback())
                    return PVMFErrNotSupported;//no interface!

                //extract params from current Node command.
                OSCL_ASSERT(nodeCmd->iCmd == PVDLM_NODE_CMD_QUERYDATASOURCEPOSITION);
                PVMFTimestamp aTargetNPT;
                PVMFTimestamp* aActualNPT;
                bool aJump;
                nodeCmd->Parse(aTargetNPT, aActualNPT, aJump);
                OSCL_ASSERT(aActualNPT != NULL);

                LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s Calling QueryDataSourcePosition", GETNODESTR));
                iCmdState = EBusy;
                iCmdId = (DataSourcePlayback())->QueryDataSourcePosition(iSessionId, aTargetNPT, *aActualNPT, aJump);
                LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::IssueCommand %s CmdId %d ", GETNODESTR, iCmdId));
                return PVMFPending;
            }

        default:
            OSCL_ASSERT(false);
            return PVMFFailure;
    }
}


PVMFStatus PVMFDownloadManagerRecognizerContainer::IssueCommand(int32 aCmd)
{
    //Issue a command to the Recognizer.
    //Return the completion status-- either pending, success, or failure.

    LOGSUBCMD((0, "PVMFDownloadManagerRecognizerContainer::IssueCommand In"));

    OSCL_ASSERT(!CmdPending());

    //save the sub-node command code
    iCmd = aCmd;

    switch (aCmd)
    {
        case ERecognizerStart:
        {
            PVMFStatus status = PVMFRecognizerRegistry::OpenSession(iRecognizerSessionId, (*this));
            if (status == PVMFSuccess)
            {
                //Issue the asynchronous command to the recognizer.
                iCmdState = EBusy;
                iCmdId = PVMFRecognizerRegistry::Recognize(iRecognizerSessionId,
                         *(iContainer->iReadFactory),
                         NULL,
                         iRecognizerResultVec);
                LOGSUBCMD((0, "PVMFDownloadManagerRecognizerContainer::IssueCommand Recognize Pending Cmd ID %d", iCmdId));
                return PVMFPending;
                //wait on the RecognizerCommandCompleted callback.
            }
            else
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iContainer->iLogger, PVLOGMSG_ERR, (0,
                                "PVMFDownloadManagerRecognizerContainer::IssueCommand Open Session Failed, status %d", status));
            }
            return status;
        }
        // break;   This statement was removed to avoid compiler warning for Unreachable Code

        case ERecognizerClose:
            //close the recognizer session.
        {
            PVMFStatus status = PVMFRecognizerRegistry::CloseSession(iRecognizerSessionId);
            if (status != PVMFSuccess)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iContainer->iLogger, PVLOGMSG_ERR, (0,
                                "PVMFDownloadManagerRecognizerContainer::IssueCommand CloseSession status %d", status));
            }
            return status;
        }

        default:
            LOGSUBCMD((0, "PVMFDownloadManagerRecognizerContainer::IssueCommand Error, Unknown Recognizer Command!"));
            OSCL_ASSERT(false);//unknown command type for recognizer.
            return PVMFFailure;
    }
}

//this is the callback from the Recognizer::Recognize command.
void PVMFDownloadManagerRecognizerContainer::RecognizerCommandCompleted(const PVMFCmdResp& aResponse)
{
    if (aResponse.GetCmdId() == iCmdId
            && iCmdState == EBusy)
    {
        //save the result.
        if (aResponse.GetCmdStatus() == PVMFSuccess
                && iRecognizerResultVec.size() > 0)
        {
            // if there is only 1, use it
            // if more than 1, check the confidence level
            if (1 == iRecognizerResultVec.size())
            {
                iContainer->iMimeType = iRecognizerResultVec[0].iRecognizedFormat;
            }
            else
            {
                // if certain, use it
                // if possible, keep looking
                bool found = false;
                for (uint32 i = 0; i < iRecognizerResultVec.size(); i++)
                {
                    if (PVMFRecognizerConfidenceCertain == iRecognizerResultVec[i].iRecognitionConfidence)
                    {
                        found = true;
                        iContainer->iMimeType = iRecognizerResultVec[i].iRecognizedFormat;
                        break;
                    }
                }

                // if Content-Type may not be known, just use the first result
                if (!found && (0 != iContainer->iContentTypeMIMEString.get_size()))
                {
                    // no certain, all possibles
                    // compare with the Content-Type hint, which is in IANA MIME string format
                    // these are file formats, does not include streaming formats
                    // @TODO: need to add the following to "pvmi/pvmf/include/pvmf_format_type.h"
                    //
                    // MP4 + 3GPP = "video/3gpp", "video/mp4", "audio/3gpp", "audio/mp4", "video/3gpp-tt"
                    // AMR = "audio/amr", "audio/amr-wb"
                    // AAC = "audio/aac", "audio/x-aac", "audio/aacp"
                    // MP3 = "audio/mpeg"
                    // WM + ASF = "video/x-ms-wmv", "video/x-ms-wm", "video/x-ms-asf","audio/x-ms-wma",
                    // RM = "video/vnd.rn-realvideo", "audio/vnd.rn-realaudio"
                    // WAV = "audio/wav", "audio/x-wav", "audio/wave"
                    //
                    // the recognizer plugins may return PV proprietary format, X-...
                    // in "pvmi/pvmf/include/pvmf_format_type.h"
                    // #define PVMF_MIME_MPEG4FF               "video/MP4"
                    // #define PVMF_MIME_AMRFF                 "X-AMR-FF"
                    // #define PVMF_MIME_AACFF                 "X-AAC-FF"
                    // #define PVMF_MIME_MP3FF                 "X-MP3-FF"
                    // #define PVMF_MIME_WAVFF                 "X-WAV-FF"
                    // #define PVMF_MIME_ASFFF                 "x-pvmf/mux/asf"
                    // #define PVMF_MIME_RMFF                  "x-pvmf/mux/rm"

                    // need case insensitive compares
                    const char* mimeStr = iContainer->iContentTypeMIMEString.get_cstr();

                    for (uint32 i = 0; !found && i < iRecognizerResultVec.size(); i++)
                    {
                        const char* recognizedStr = iRecognizerResultVec[i].iRecognizedFormat.get_cstr();
                        if (0 == oscl_CIstrcmp(recognizedStr, PVMF_MIME_MPEG4FF))
                        {
                            if ((0 == oscl_CIstrcmp(mimeStr, "video/3gpp"))    ||
                                    (0 == oscl_CIstrcmp(mimeStr, "video/mp4"))     ||
                                    (0 == oscl_CIstrcmp(mimeStr, "audio/3gpp"))    ||
                                    (0 == oscl_CIstrcmp(mimeStr, "audio/mp4"))     ||
                                    (0 == oscl_CIstrcmp(mimeStr, "video/3gpp-tt")))
                            {
                                found = true;
                                iContainer->iMimeType = iRecognizerResultVec[i].iRecognizedFormat;
                            }
                        }
                        else if (0 == oscl_CIstrcmp(recognizedStr, PVMF_MIME_MP3FF))
                        {
                            if ((0 == oscl_CIstrcmp(mimeStr, "audio/mpeg")))
                            {
                                found = true;
                                iContainer->iMimeType = iRecognizerResultVec[i].iRecognizedFormat;
                            }
                        }
                        else if (0 == oscl_CIstrcmp(recognizedStr, PVMF_MIME_AACFF))
                        {
                            if ((0 == oscl_CIstrcmp(mimeStr, "audio/aac"))   ||
                                    (0 == oscl_CIstrcmp(mimeStr, "audio/x-aac")) ||
                                    (0 == oscl_CIstrcmp(mimeStr, "audio/aacp")))
                            {
                                found = true;
                                iContainer->iMimeType = iRecognizerResultVec[i].iRecognizedFormat;
                            }
                        }
                        else if (0 == oscl_CIstrcmp(recognizedStr, PVMF_MIME_AMRFF))
                        {
                            if ((0 == oscl_CIstrcmp(mimeStr, "audio/amr"))  ||
                                    (0 == oscl_CIstrcmp(mimeStr, "audio/amr-wb")))
                            {
                                found = true;
                                iContainer->iMimeType = iRecognizerResultVec[i].iRecognizedFormat;
                            }
                        }
                        else if (0 == oscl_CIstrcmp(recognizedStr, PVMF_MIME_ASFFF))
                        {
                            if ((0 == oscl_CIstrcmp(mimeStr, "video/x-ms-wmv"))  ||
                                    (0 == oscl_CIstrcmp(mimeStr, "video/x-ms-wm"))   ||
                                    (0 == oscl_CIstrcmp(mimeStr, "video/x-ms-asf"))  ||
                                    (0 == oscl_CIstrcmp(mimeStr, "audio/x-ms-wma")))
                            {
                                found = true;
                                iContainer->iMimeType = iRecognizerResultVec[i].iRecognizedFormat;
                            }
                        }
                        else if (0 == oscl_CIstrcmp(recognizedStr, PVMF_MIME_RMFF))
                        {
                            if ((0 == oscl_CIstrcmp(mimeStr, "video/vnd.rn-realvideo"))  ||
                                    (0 == oscl_CIstrcmp(mimeStr, "audio/vnd.rn-realaudio")))
                            {
                                found = true;
                                iContainer->iMimeType = iRecognizerResultVec[i].iRecognizedFormat;
                            }
                        }
                        else if ((0 == oscl_CIstrcmp(recognizedStr, PVMF_MIME_WAVFF)))
                        {
                            if ((0 == oscl_CIstrcmp(mimeStr, "audio/wav"))    ||
                                    (0 == oscl_CIstrcmp(mimeStr, "audio/wave"))   ||
                                    (0 == oscl_CIstrcmp(mimeStr, "audio/x-wav")))
                            {
                                found = true;
                                iContainer->iMimeType = iRecognizerResultVec[i].iRecognizedFormat;
                            }
                        }
                        else
                        {
                            // some new format that this component does not know about
                            // we'll use it
                            found = true;
                            iContainer->iMimeType = iRecognizerResultVec[i].iRecognizedFormat;
                        }
                    }
                }

                // if still no match found
                // need to wait for more data and run the recognizer again, will implement this later
                // just use the first one for now
                if (!found)
                {
                    // @TODO - implement the recognizer loop later
                    iContainer->iMimeType = iRecognizerResultVec[0].iRecognizedFormat;
                }
            }
        }

        CommandDone(aResponse.GetCmdStatus(), aResponse.GetEventExtensionInterface(), aResponse.GetEventData());

        //catch completion of cancel for recognizer commands
        //since there's no cancel to the recognizer module, the cancel
        //is done whenever the current recognizer command is done.
        if (iCancelCmdState != EIdle)
        {
            CancelCommandDone(PVMFSuccess, NULL, NULL);
        }
    }
    else
    {
        OSCL_ASSERT(false);//unexpected response.
    }
}

//from PVMFNodeErrorEventObserver
void PVMFDownloadManagerSubNodeContainer::HandleNodeErrorEvent(const PVMFAsyncEvent& aEvent)
{
    //A sub-node is reporting an event.

    //print events
    switch (iType)
    {
        case EFormatParser:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iContainer->iLogger, PVLOGMSG_ERR, (0,
                            "PVMFDownloadManagerSubNodeContainer::HandleNodeErrorEvent Parser Node Error Event %d", aEvent.GetEventType()));
            break;
        case EProtocolEngine:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iContainer->iLogger, PVLOGMSG_ERR, (0,
                            "PVMFDownloadManagerSubNodeContainer::HandleNodeErrorEvent ProtocolEngine Node Error Event %d", aEvent.GetEventType()));
            break;
        case ESocket:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iContainer->iLogger, PVLOGMSG_ERR, (0,
                            "PVMFDownloadManagerSubNodeContainer::HandleNodeErrorEvent Socket Node Error Event %d", aEvent.GetEventType()));
            if (iContainer->iDownloadComplete)
                return; // Suppress socket node error, if the download is already complete.
            break;
        default:
            OSCL_ASSERT(false);
            break;
    }

    //duplicate any PVMF Error events from either node.
    if (IsPVMFErrCode(aEvent.GetEventType()))
        iContainer->ReportErrorEvent(aEvent.GetEventType(), aEvent.GetEventExtensionInterface(), aEvent.GetEventData());
}

#include "pvmf_protocol_engine_node_events.h"

//from PVMFNodeInfoEventObserver
void PVMFDownloadManagerSubNodeContainer::HandleNodeInformationalEvent(const PVMFAsyncEvent& aEvent)
{
    //A sub-node is reporting an event.

    //detect sub-node error states.
    if (aEvent.GetEventType() == PVMFInfoStateChanged
            && iNode->GetState() == EPVMFNodeError)
    {
        iContainer->SetState(EPVMFNodeError);
    }

    //detect important status events.
    if (iType == EProtocolEngine)
    {
        switch (aEvent.GetEventType())
        {
            case PVMFInfoBufferingComplete:
                iContainer->iDownloadComplete = true;
                iContainer->NotifyDownloadComplete();
                //not sure whether this is possible, but just in case download
                //completes before movie atom notice, go ahead and do anything
                //that was waiting on movie atom.
                if (!iContainer->iMovieAtomComplete)
                    iContainer->ContinueAfterMovieAtom();
                break;
            case PVMFPROTOCOLENGINE_INFO_MovieAtomCompleted:
                //we may be waiting on this event to continue Parser init.
                if (!iContainer->iMovieAtomComplete)
                    iContainer->ContinueAfterMovieAtom();
                if (iContainer->iDebugMode)
                {
                    iContainer->ReportInfoEvent((PVMFAsyncEvent&)aEvent);
                }
                break;
            default:
                break;
        }
    }

    //filter out events that we don't want to pass up to observer
    bool filter = false;
    if (iType == ESocket)
    {
        switch (aEvent.GetEventType())
        {
            case PVMFInfoRemoteSourceNotification:  //To let the socket node events propagate to pvengine
                filter = false;
                break;
            default:
                filter = true;
        }
    }
    else
    {
        switch (aEvent.GetEventType())
        {
            case PVMFInfoStateChanged:
                filter = true;//always ignore
                break;
            case PVMFInfoPortDeleted:
            case PVMFInfoPortCreated:
            case PVMFInfoPortConnected:
            case PVMFInfoPortDisconnected:
                if (iType != EFormatParser)
                    filter = true;//ignore port events unless from format parser
                break;
            case PVMFInfoUnderflow:
            case PVMFInfoDataReady:
            case PVMFInfoRemoteSourceNotification:
                //apply some filtering to these
                if (iContainer->FilterPlaybackEventsFromSubNodes(aEvent))
                    filter = true;
                break;
            default:
                break;
        }
    }

    //duplicate all remaining PVMFInfo events.
    if (!filter
            && IsPVMFInfoCode(aEvent.GetEventType()))
    {
        iContainer->ReportInfoEvent((PVMFAsyncEvent&)aEvent);
    }

    //just print and ignore other events
    switch (iType)
    {
        case EFormatParser:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iContainer->iLogger, PVLOGMSG_DEBUG, (0,
                            "PVMFDownloadManagerSubNodeContainer::HandleNodeInfoEvent Parser Node Info Event %d", aEvent.GetEventType()));
            break;
        case EProtocolEngine:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iContainer->iLogger, PVLOGMSG_DEBUG, (0,
                            "PVMFDownloadManagerSubNodeContainer::HandleNodeInfoEvent ProtocolEngine Node Info Event %d", aEvent.GetEventType()));
            break;
        case ESocket:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iContainer->iLogger, PVLOGMSG_DEBUG, (0,
                            "PVMFDownloadManagerSubNodeContainer::HandleNodeInfoEvent Socket Node Info Event %d", aEvent.GetEventType()));
            break;

        default:
            OSCL_ASSERT(false);
            break;
    }
}

bool PVMFDownloadManagerSubNodeContainer::CancelPendingCommand()
{
    //initiate sub-node command cancel, return True if cancel initiated.

    if (iCmdState != EBusy)
        return false;//nothing to cancel

    iCancelCmdState = EBusy;

    if (iNode)
    {
        LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::CancelPendingCommand Calling Cancel"));
        iCancelCmdId = iNode->CancelCommand(iSessionId, iCmdId, NULL);
        LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::CancelPendingCommand CmdId %d", iCancelCmdId));
    }

    return true;//cancel initiated
}

bool PVMFDownloadManagerRecognizerContainer::CancelPendingCommand()
{
    //initiate sub-node command cancel, return True if cancel initiated.

    if (iCmdState != EBusy)
        return false;//nothing to cancel

    iCancelCmdState = EBusy;

    LOGSUBCMD((0, "PVMFDownloadManagerRecognizerContainer::CancelPendingCommand Calling Cancel"));
    iCancelCmdId = PVMFRecognizerRegistry::CancelCommand(iRecognizerSessionId, iCmdId, NULL);
    LOGSUBCMD((0, "PVMFDownloadManagerRecognizerContainer::CancelPendingCommand CmdId %d", iCancelCmdId));

    return true;//cancel initiated
}


void PVMFDownloadManagerSubNodeContainerBase::CommandDone(PVMFStatus aStatus, PVInterface*aExtMsg, OsclAny*aEventData)
{
    //a sub-node command is done-- process the result.

    OSCL_ASSERT(aStatus != PVMFPending);

    //pop the sub-node command vector.
    OSCL_ASSERT(!iContainer->iSubNodeCmdVec.empty());
    iContainer->iSubNodeCmdVec.erase(&iContainer->iSubNodeCmdVec.front());

    iCmdState = EIdle;

    PVMFStatus status = aStatus;

    // Set "Init Failed License Required" flag with the results of parser Init.
    if (iType == EFormatParser && iCmd == EInit)
    {
        iContainer->iInitFailedLicenseRequired = (status == PVMFErrLicenseRequired);
    }

    // Watch for the request port command completion from the protocol node, because we need to save the port pointer
    if (iType == EProtocolEngine && iCmd == ERequestPort && status == PVMFSuccess)
    {
        iContainer->iProtocolEngineNodePort = (PVMFPortInterface*)aEventData;
        // If both ports are non-null, connect them.
        if (iContainer->iSocketNodePort && iContainer->iProtocolEngineNodePort)
        {
            iContainer->iSocketNodePort->Connect(iContainer->iProtocolEngineNodePort);

            // The ports are connected, so now we pass the datastream factory to the protocol node via the extension interface, if it's available.
            if (iContainer->iProtocolEngineNode.iDatastreamUser)
            {
                ((PVMIDatastreamuserInterface*)iContainer->iProtocolEngineNode.iDatastreamUser)->PassDatastreamFactory(*(iContainer->iWriteFactory), (int32)0);
            }
        }
    }

    // Watch for the request port command completion from the socket node, because we need to save the port pointer
    if (iType == ESocket && iCmd == ERequestPort && status == PVMFSuccess)
    {
        iContainer->iSocketNodePort = (PVMFPortInterface*)aEventData;
    }


    // Watch for the query track selection interface completion from the protocol engine node.
    if (iType == EProtocolEngine && iCmd == EQueryTrackSelection)
    {
        //see whether we got the TS interface from PE node.
        iContainer->iNoPETrackSelect = (status != PVMFSuccess || iContainer->iProtocolEngineNode.iTrackSelection == NULL);
        //ignore cmd failure so it won't terminate the Init sequence
        if (status != PVMFSuccess)
            status = PVMFSuccess;
        //Continue the Init sequence now that we have the track select decision.
        iContainer->ContinueInitAfterTrackSelectDecision();
    }

    // Watch for recognizer start failure
    if (iType == ERecognizer && iCmd == ERecognizerStart && aStatus != PVMFSuccess)
    {
        iContainer->iRecognizerError = true;
        //save the error code to report after recognizer close.
        iContainer->iRecognizerStartStatus = status;
        //purge everything from the subnode command vector except the recognizer
        //close command
        iContainer->iSubNodeCmdVec.clear();
        iContainer->Push(iContainer->iRecognizerNode, PVMFDownloadManagerSubNodeContainerBase::ERecognizerClose);
        //set status to "success" so that we'll continue with processing
        status = PVMFSuccess;
    }
    // Watch for recognizer close completion after a start failure
    else if (iContainer->iRecognizerError)
    {
        OSCL_ASSERT(iCmd == ERecognizerClose);
        iContainer->iRecognizerError = false;
        //restore the original error code from the recognizer start.
        status = iContainer->iRecognizerStartStatus;
    }

    //Check whether the node command is being cancelled.
    if (iCancelCmdState != EIdle)
    {
        if (!iContainer->iSubNodeCmdVec.empty())
        {
            //even if this command succeeded, we want to report
            //the node command status as cancelled since some sub-node
            //commands were not yet issued.
            status = PVMFErrCancelled;
            //go into an error state since it's not clear
            //how to recover from a partially completed command.
            iContainer->SetState(EPVMFNodeError);
        }
    }

    //figure out the next step in the sequence...
    //A node command is done when either all sub-node commands are
    //done or when one fails.
    if (status == PVMFSuccess
            && !iContainer->iSubNodeCmdVec.empty())
    {
        //The node needs to issue the next sub-node command.
        iContainer->RunIfNotReady();
    }
    else
    {
        //node command is done.
        OSCL_ASSERT(!iContainer->iCurrentCommand.empty());
        iContainer->CommandComplete(iContainer->iCurrentCommand, iContainer->iCurrentCommand.front(), status, aExtMsg, aEventData);
    }
}

void PVMFDownloadManagerSubNodeContainerBase::CancelCommandDone(PVMFStatus aStatus, PVInterface*aExtMsg, OsclAny*aEventData)
{
    OSCL_UNUSED_ARG(aExtMsg);
    OSCL_UNUSED_ARG(aEventData);
    //a sub-node cancel command is done-- process the result.

    OSCL_ASSERT(aStatus != PVMFPending);

    iCancelCmdState = EIdle;
    //print and ignore any failed sub-node cancel commands.
    if (aStatus != PVMFSuccess)
    {
        switch (iType)
        {
            case EFormatParser:
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iContainer->iLogger, PVLOGMSG_DEBUG, (0,
                                "PVMFDownloadManagerSubNodeContainer::CancelCommandDone Parser Node Cancel failed"));
                break;
            case EProtocolEngine:
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iContainer->iLogger, PVLOGMSG_DEBUG, (0,
                                "PVMFDownloadManagerSubNodeContainer::CancelCommandDone ProtocolEngine Node Cancel failed"));
                break;
            case ESocket:
                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iContainer->iLogger, PVLOGMSG_DEBUG, (0,
                                "PVMFDownloadManagerSubNodeContainer::CancelCommandDone Socket Node Cancel failed"));
                break;
            default:
                OSCL_ASSERT(false);
                break;
        }
    }

    //Node cancel command is now done.
    OSCL_ASSERT(!iContainer->iCancelCommand.empty());
    iContainer->CommandComplete(iContainer->iCancelCommand, iContainer->iCancelCommand.front(), aStatus, NULL, NULL);
}

//from PVMFNodeCmdStatusObserver
void PVMFDownloadManagerSubNodeContainer::NodeCommandCompleted(const PVMFCmdResp& aResponse)
{
    //A command to a sub-node is complete
    LOGSUBCMD((0, "PVMFDownloadManagerSubNodeContainer::NodeCommandCompleted %s () In CmdId %d Status %d", GETNODESTR, aResponse.GetCmdId(), aResponse.GetCmdStatus()));

    if (aResponse.GetCmdStatus() != PVMFSuccess)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iContainer->iLogger, PVLOGMSG_DEBUG, (0, "PVMFDownloadManagerSubNodeContainer::NodeCommandCompleted Failure! %d", aResponse.GetCmdStatus()));
    }

    if (aResponse.GetCmdId() == iCmdId
            && iCmdState == EBusy)
    {
        //Process normal command response.
        CommandDone(aResponse.GetCmdStatus(), aResponse.GetEventExtensionInterface(), aResponse.GetEventData());
    }
    else if (aResponse.GetCmdId() == iCancelCmdId
             && iCancelCmdState == EBusy)
    {
        //Process node cancel command response
        CancelCommandDone(aResponse.GetCmdStatus(), aResponse.GetEventExtensionInterface(), aResponse.GetEventData());
    }
    //Process Get License cancel command response.
    else if (aResponse.GetCmdId() == iCPMCancelGetLicenseCmdId
             && iCancelCmdState == EBusy)
    {
        CancelCommandDone(aResponse.GetCmdStatus(), aResponse.GetEventExtensionInterface(), aResponse.GetEventData());
    }
    else
    {
        OSCL_ASSERT(false);//unexpected response.
    }
}


//From capability and config interface
PVMFStatus PVMFDownloadManagerNode::getParametersSync(PvmiMIOSession aSession,
        PvmiKeyType aIdentifier,
        PvmiKvp*& aParameters,
        int& aNumParamElements,
        PvmiCapabilityContext aContext)
{
    OSCL_UNUSED_ARG(aSession);
    OSCL_UNUSED_ARG(aContext);
    // Initialize the output parameters
    aNumParamElements = 0;
    aParameters = NULL;

    // Count the number of components and parameters in the key
    int compcount = pv_mime_string_compcnt(aIdentifier);
    // Retrieve the first component from the key string
    char* compstr = NULL;
    pv_mime_string_extract_type(0, aIdentifier, compstr);

    if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf")) < 0) || compcount < 2)
    {
        // First component should be "x-pvmf" and there must
        // be at least two components to go past x-pvmf
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFDownloadManagerNode::getParametersSync() Invalid key string"));
        return PVMFErrArgument;
    }

    // Retrieve the second component from the key string
    pv_mime_string_extract_type(1, aIdentifier, compstr);

    // Check if it is key string for Download manager
    if (pv_mime_strcmp(compstr, _STRLIT_CHAR("net")) < 0)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFDownloadManagerNode::getParametersSync() Unsupported key"));
        return PVMFFailure;
    }


    if (compcount == 2)
    {
        // Since key is "x-pvmf/net" return all
        // nodes available at this level. Ignore attribute
        // since capability is only allowed

        // Allocate memory for the KVP list
        aParameters = (PvmiKvp*)oscl_malloc(DownloadManagerConfig_NumBaseKeys * sizeof(PvmiKvp));
        if (aParameters == NULL)
        {
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFDownloadManagerNode::getParametersSync() Memory allocation for KVP failed"));
            return PVMFErrNoMemory;
        }
        oscl_memset(aParameters, 0, DownloadManagerConfig_NumBaseKeys*sizeof(PvmiKvp));
        // Allocate memory for the key strings in each KVP
        PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(DownloadManagerConfig_NumBaseKeys * DLMCONFIG_KEYSTRING_SIZE * sizeof(char));
        if (memblock == NULL)
        {
            oscl_free(aParameters);
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFDownloadManagerNode::getParametersSync() Memory allocation for key string failed"));
            return PVMFErrNoMemory;
        }
        oscl_strset(memblock, 0, DownloadManagerConfig_NumBaseKeys*DLMCONFIG_KEYSTRING_SIZE*sizeof(char));
        // Assign the key string buffer to each KVP
        uint32 j;
        for (j = 0; j < DownloadManagerConfig_NumBaseKeys; ++j)
        {
            aParameters[j].key = memblock + (j * DLMCONFIG_KEYSTRING_SIZE);
        }
        // Copy the requested info
        for (j = 0; j < DownloadManagerConfig_NumBaseKeys; ++j)
        {
            oscl_strncat(aParameters[j].key, _STRLIT_CHAR("x-pvmf/net/"), 17);
            oscl_strncat(aParameters[j].key, DownloadManagerConfig_BaseKeys[j].iString, oscl_strlen(DownloadManagerConfig_BaseKeys[j].iString));
            oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";type="), 6);
            switch (DownloadManagerConfig_BaseKeys[j].iType)
            {
                case PVMI_KVPTYPE_AGGREGATE:
                    oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_AGGREGATE_STRING), oscl_strlen(PVMI_KVPTYPE_AGGREGATE_STRING));
                    break;

                case PVMI_KVPTYPE_POINTER:
                    oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_POINTER_STRING), oscl_strlen(PVMI_KVPTYPE_POINTER_STRING));
                    break;

                case PVMI_KVPTYPE_VALUE:
                default:
                    oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_VALUE_STRING), oscl_strlen(PVMI_KVPTYPE_VALUE_STRING));
                    break;
            }
            oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";valtype="), 9);
            switch (DownloadManagerConfig_BaseKeys[j].iValueType)
            {
                case PVMI_KVPVALTYPE_RANGE_INT32:
                    oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_INT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_INT32_STRING));
                    break;

                case PVMI_KVPVALTYPE_KSV:
                    oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_KSV_STRING), oscl_strlen(PVMI_KVPVALTYPE_KSV_STRING));
                    break;

                case PVMI_KVPVALTYPE_CHARPTR:
                    oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_CHARPTR_STRING), oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING));
                    break;

                case PVMI_KVPVALTYPE_WCHARPTR:
                    oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_WCHARPTR_STRING), oscl_strlen(PVMI_KVPVALTYPE_WCHARPTR_STRING));
                    break;

                case PVMI_KVPVALTYPE_BOOL:
                    oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_BOOL_STRING), oscl_strlen(PVMI_KVPVALTYPE_BOOL_STRING));
                    break;

                case PVMI_KVPVALTYPE_UINT32:
                default:
                    oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING));
                    break;
            }
            aParameters[j].key[DLMCONFIG_KEYSTRING_SIZE-1] = 0;
        }

        aNumParamElements = DownloadManagerConfig_NumBaseKeys;
    }
    else if (compcount == 3)
    {
        pv_mime_string_extract_type(2, aIdentifier, compstr);

        // Determine what is requested
        PvmiKvpAttr reqattr = GetAttrTypeFromKeyString(aIdentifier);
        if (reqattr == PVMI_KVPATTR_UNKNOWN)
        {
            reqattr = PVMI_KVPATTR_CUR;
        }
        uint i;
        for (i = 0; i < DownloadManagerConfig_NumBaseKeys; i++)
        {
            if (pv_mime_strcmp(compstr, (char*)(DownloadManagerConfig_BaseKeys[i].iString)) >= 0)
            {
                break;
            }
        }

        if (i == DownloadManagerConfig_NumBaseKeys)
        {
            // no match found
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFDownloadManagerNode::getParametersSync() Unsupported key"));
            return PVMFErrNoMemory;
        }
    }
    else
    {
        oscl_free(aParameters);
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFDownloadManagerNode::getParametersSync() Unsupported key"));
        return PVMFErrNoMemory;
    }

    return PVMFSuccess;
}


PVMFStatus PVMFDownloadManagerNode::releaseParameters(PvmiMIOSession aSession,
        PvmiKvp* aParameters,
        int num_elements)
{
    OSCL_UNUSED_ARG(aSession);

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFDownloadManagerNode::releaseParameters() In"));

    if (aParameters == NULL || num_elements < 1)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFDownloadManagerNode::releaseParameters() KVP list is NULL or number of elements is 0"));
        return PVMFErrArgument;
    }

    // Count the number of components and parameters in the key
    int compcount = pv_mime_string_compcnt(aParameters[0].key);
    // Retrieve the first component from the key string
    char* compstr = NULL;
    pv_mime_string_extract_type(0, aParameters[0].key, compstr);

    if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf")) < 0) || compcount < 2)
    {
        // First component should be "x-pvmf" and there must
        // be at least two components to go past x-pvmf
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                        (0, "PVMFDownloadManagerNode::releaseParameters() Unsupported key"));
        return PVMFErrArgument;
    }

    // Retrieve the second component from the key string
    pv_mime_string_extract_type(1, aParameters[0].key, compstr);

    // Assume all the parameters come from the same component so the base components are the same
    if (pv_mime_strcmp(compstr, _STRLIT_CHAR("net")) >= 0)
    {
        // Go through each KVP and release memory for value if allocated from heap
        for (int32 i = 0; i < num_elements; ++i)
        {
            // Next check if it is a value type that allocated memory
            PvmiKvpType kvptype = GetTypeFromKeyString(aParameters[i].key);
            if (kvptype == PVMI_KVPTYPE_VALUE || kvptype == PVMI_KVPTYPE_UNKNOWN)
            {
                PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameters[i].key);
                if (keyvaltype == PVMI_KVPVALTYPE_UNKNOWN)
                {
                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                    (0, "PVMFDownloadManagerNode::releaseParameters() Valtype not specified in key string"));
                    return PVMFErrArgument;
                }

                if (keyvaltype == PVMI_KVPVALTYPE_CHARPTR && aParameters[i].value.pChar_value != NULL)
                {
                    oscl_free(aParameters[i].value.pChar_value);
                    aParameters[i].value.pChar_value = NULL;
                }
                else if (keyvaltype == PVMI_KVPVALTYPE_WCHARPTR && aParameters[i].value.pWChar_value != NULL)
                {
                    oscl_free(aParameters[i].value.pWChar_value);
                    aParameters[i].value.pWChar_value = NULL;
                }
                else if (keyvaltype == PVMI_KVPVALTYPE_CHARPTR && aParameters[i].value.pChar_value != NULL)
                {
                    oscl_free(aParameters[i].value.pChar_value);
                    aParameters[i].value.pChar_value = NULL;
                }
                else if (keyvaltype == PVMI_KVPVALTYPE_KSV && aParameters[i].value.key_specific_value != NULL)
                {
                    oscl_free(aParameters[i].value.key_specific_value);
                    aParameters[i].value.key_specific_value = NULL;
                }
                else if (keyvaltype == PVMI_KVPVALTYPE_RANGE_INT32 && aParameters[i].value.key_specific_value != NULL)
                {
                    range_int32* ri32 = (range_int32*)aParameters[i].value.key_specific_value;
                    aParameters[i].value.key_specific_value = NULL;
                    oscl_free(ri32);
                }
                else if (keyvaltype == PVMI_KVPVALTYPE_RANGE_UINT32 && aParameters[i].value.key_specific_value != NULL)
                {
                    range_uint32* rui32 = (range_uint32*)aParameters[i].value.key_specific_value;
                    aParameters[i].value.key_specific_value = NULL;
                    oscl_free(rui32);
                }
            }
        }

        oscl_free(aParameters[0].key);

        // Free memory for the parameter list
        oscl_free(aParameters);
        aParameters = NULL;
    }
    else
    {
        // Unknown key string
        return PVMFErrArgument;
    }

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFDownloadManagerNode::releaseParameters() Out"));
    return PVMFSuccess;

}

void PVMFDownloadManagerNode::createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext)
{
    OSCL_UNUSED_ARG(aSession);
    OSCL_UNUSED_ARG(aContext);
    // not supported
    OSCL_LEAVE(PVMFErrNotSupported);
}

void PVMFDownloadManagerNode::setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext,
        PvmiKvp* aParameters, int num_parameter_elements)
{
    OSCL_UNUSED_ARG(aSession);
    OSCL_UNUSED_ARG(aContext);
    OSCL_UNUSED_ARG(aParameters);
    OSCL_UNUSED_ARG(num_parameter_elements);
    // not supported
    OSCL_LEAVE(PVMFErrNotSupported);
}

void PVMFDownloadManagerNode::DeleteContext(PvmiMIOSession aSession,
        PvmiCapabilityContext& aContext)
{
    OSCL_UNUSED_ARG(aSession);
    OSCL_UNUSED_ARG(aContext);
    // not supported
    OSCL_LEAVE(PVMFErrNotSupported);
}

void PVMFDownloadManagerNode::setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters,
        int num_elements, PvmiKvp * & aRet_kvp)
{
    OSCL_UNUSED_ARG(aSession);

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFDownloadManagerNode::setParametersSync() In"));

    aRet_kvp = NULL;

    // Go through each parameter
    for (int paramind = 0; paramind < num_elements; ++paramind)
    {
        // Count the number of components and parameters in the key
        int compcount = pv_mime_string_compcnt(aParameters[paramind].key);

        // Retrieve the first component from the key string
        char* compstr = NULL;
        pv_mime_string_extract_type(0, aParameters[paramind].key, compstr);

        if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf")) < 0) || compcount < 2)
        {
            // First component should be "x-pvmf" and there must
            // be at least two components to go past x-pvmf
            aRet_kvp = &aParameters[paramind];
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFDownloadManagerNode::setParametersSync() Unsupported key"));
            return;
        }

        // Retrieve the second component from the key string
        pv_mime_string_extract_type(1, aParameters[paramind].key, compstr);

        // First check if it is key string for the Download manager
        if (pv_mime_strcmp(compstr, _STRLIT_CHAR("net")) >= 0)
        {
            if (compcount == 3)
            {
                pv_mime_string_extract_type(2, aParameters[paramind].key, compstr);
                uint i;
                for (i = 0; i < DownloadManagerConfig_NumBaseKeys; i++)
                {
                    if (pv_mime_strcmp(compstr, (char*)(DownloadManagerConfig_BaseKeys[i].iString)) >= 0)
                    {
                        break;
                    }
                }

                if (DownloadManagerConfig_NumBaseKeys == i)
                {
                    // invalid third component
                    aRet_kvp = &aParameters[paramind];
                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                    (0, "PVMFDownloadManagerNode::setParametersSync() Unsupported key"));
                    return;
                }

                // Verify and set the passed-in setting
                switch (i)
                {
                    case BASEKEY_SESSION_CONTROLLER_USER_AGENT:
                    {
                        if (IsDownloadExtensionHeaderValid(*aParameters))
                        {
                            //setting KVP string for download when mode applied for download or not applied at all.
                            OSCL_wHeapString<OsclMemAllocator> userAgent;
                            userAgent = aParameters[paramind].value.pWChar_value;
                            (iProtocolEngineNode.ProtocolEngineExtension())->SetUserAgent(userAgent, true);
                        }
                    }
                    break;
                    case BASEKEY_SESSION_CONTROLLER_HTTP_VERSION:
                    {
                        uint32 httpVersion;
                        httpVersion = aParameters[paramind].value.uint32_value;
                        (iProtocolEngineNode.ProtocolEngineExtension())->SetHttpVersion(httpVersion);

                    }
                    break;
                    case BASEKEY_SESSION_CONTROLLER_HTTP_TIMEOUT:
                    {
                        uint32 httpTimeout;
                        httpTimeout = aParameters[paramind].value.uint32_value;
                        (iProtocolEngineNode.ProtocolEngineExtension())->SetNetworkTimeout(httpTimeout);
                    }
                    break;
                    case BASEKEY_SESSION_CONTROLLER_DOWNLOAD_PROGRESS_INFO:
                    {
                        OSCL_HeapString<OsclMemAllocator> downloadProgressInfo;
                        downloadProgressInfo = aParameters[paramind].value.pChar_value;
                        DownloadProgressMode aMode = DownloadProgressMode_TimeBased;
                        if (IsByteBasedDownloadProgress(downloadProgressInfo)) aMode = DownloadProgressMode_ByteBased;
                        (iProtocolEngineNode.ProtocolEngineExtension())->SetDownloadProgressMode(aMode);
                    }
                    break;
                    case BASEKEY_SESSION_CONTROLLER_PROTOCOL_EXTENSION_HEADER:
                    {
                        if (IsDownloadExtensionHeaderValid(aParameters[paramind]))
                        {
                            OSCL_HeapString<OsclMemAllocator> extensionHeaderKey;
                            OSCL_HeapString<OsclMemAllocator> extensionHeaderValue;
                            HttpMethod httpMethod = HTTP_GET;
                            bool aPurgeOnRedirect = false;
                            if (GetHttpExtensionHeaderParams(aParameters[paramind],
                                                             extensionHeaderKey,
                                                             extensionHeaderValue,
                                                             httpMethod,
                                                             aPurgeOnRedirect))
                            {
                                (iProtocolEngineNode.ProtocolEngineExtension())->SetHttpExtensionHeaderField(extensionHeaderKey,
                                        extensionHeaderValue,
                                        httpMethod,
                                        aPurgeOnRedirect);
                            }
                        }

                    }
                    break;

                    case BASEKEY_SESSION_CONTROLLER_NUM_REDIRECT_ATTEMPTS:
                    {
                        if (IsDownloadExtensionHeaderValid(*aParameters))
                        {
                            //setting KVP string for download when mode applied for download or not applied at all.
                            uint32 numRedirects = aParameters[paramind].value.uint32_value;
                            (iProtocolEngineNode.ProtocolEngineExtension())->SetNumRedirectTrials(numRedirects);
                        }
                    }
                    break;

                    case BASEKEY_SESSION_CONTROLLER_NUM_HTTP_HEADER_REQUEST_DISABLED:
                    {
                        bool httpHeaderRequestDisabled = aParameters[paramind].value.bool_value;
                        (iProtocolEngineNode.ProtocolEngineExtension())->DisableHttpHeadRequest(httpHeaderRequestDisabled);
                    }
                    break;

                    case BASEKEY_MAX_TCP_RECV_BUFFER_SIZE:
                    {
                        uint32 size = aParameters[paramind].value.uint32_value;
                        PVMFSocketNode* socketNode =
                            (PVMFSocketNode*)(iSocketNode.iNode);
                        if (socketNode != NULL)
                        {
                            socketNode->SetMaxTCPRecvBufferSize(size);
                        }
                    }
                    break;

                    case BASEKEY_MAX_TCP_RECV_BUFFER_COUNT:
                    {
                        uint32 size = aParameters[paramind].value.uint32_value;
                        PVMFSocketNode* socketNode =
                            (PVMFSocketNode*)(iSocketNode.iNode);
                        if (socketNode != NULL)
                        {
                            socketNode->SetMaxTCPRecvBufferCount(size);
                        }
                    }
                    break;

                    default:
                    {
                        aRet_kvp = &aParameters[paramind];
                        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                        (0, "PVMFDownloadManagerNode::setParametersSync() Setting "
                                         "parameter %d failed", paramind));
                    }
                    break;
                }
            }
            else
            {
                // Do not support more than 3 components right now
                aRet_kvp = &aParameters[paramind];
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFDownloadManagerNode::setParametersSync() Unsupported key"));
                return;
            }
        }
        else
        {
            // Unknown key string
            aRet_kvp = &aParameters[paramind];
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                            (0, "PVMFDownloadManagerNode::setParametersSync() Unsupported key"));
            return;
        }
    }

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "PVMFDownloadManagerNode::setParametersSync() Out"));
}

bool PVMFDownloadManagerNode::IsByteBasedDownloadProgress(OSCL_String &aDownloadProgressInfo)
{
    if (aDownloadProgressInfo.get_size() < 4) return false; // 4 => byte
    char *ptr = (char*)aDownloadProgressInfo.get_cstr();
    uint32 len = aDownloadProgressInfo.get_size();

    while (!(((ptr[0]  | OSCL_ASCII_CASE_MAGIC_BIT) == 'b') &&
             ((ptr[1]  | OSCL_ASCII_CASE_MAGIC_BIT) == 'y') &&
             ((ptr[2]  | OSCL_ASCII_CASE_MAGIC_BIT) == 't') &&
             ((ptr[3]  | OSCL_ASCII_CASE_MAGIC_BIT) == 'e')) &&
            len >= 4)
    {
        ptr++;
        len--;
    }
    if (len < 4) return false;

    return true; // find case-insentive string "byte"
}

bool PVMFDownloadManagerNode::GetHttpExtensionHeaderParams(PvmiKvp &aParameter,
        OSCL_String &extensionHeaderKey,
        OSCL_String &extensionHeaderValue,
        HttpMethod  &httpMethod,
        bool &aPurgeOnRedirect)
{
    // check if the extension header is meant for download
    if (!IsHttpExtensionHeaderValid(aParameter)) return false;

    // get aPurgeOnRedirect
    aPurgeOnRedirect = false;
    OSCL_StackString<32> purgeOnRedirect(_STRLIT_CHAR("purge-on-redirect"));
    if (oscl_strstr(aParameter.key, purgeOnRedirect.get_cstr()) != NULL)
    {
        aPurgeOnRedirect = true;
    }

    // get key, value and http method of protocol extension header
    // the string value needs to be structured as follows: "key=app-feature-tag;value=xyz"
    char* extensionHeader = aParameter.value.pChar_value;
    if (!extensionHeader) return false;

    // (1) extract the key
    OSCL_StackString<8> keyTag(_STRLIT_CHAR("key="));

    OSCL_StackString<8> valueTag(_STRLIT_CHAR("value="));
    char *keyStart = OSCL_CONST_CAST(char*, oscl_strstr(extensionHeader, keyTag.get_cstr()));
    if (!keyStart) return false;

    keyStart += keyTag.get_size();
    char *keyEnd = OSCL_CONST_CAST(char*, oscl_strstr(extensionHeader, valueTag.get_cstr()));
    if (!keyEnd) return false;
    uint32 keyLen = getItemLen(keyStart, keyEnd);
    if (keyLen == 0) return false;
    extensionHeaderKey = OSCL_HeapString<OsclMemAllocator> (keyStart, keyLen);

    // (2) extract the value
    char* valueStart = keyEnd;
    valueStart += valueTag.get_size();

    OSCL_StackString<8> methodTag(_STRLIT_CHAR("method="));
    char* valueEnd = OSCL_CONST_CAST(char*, oscl_strstr(valueStart, methodTag.get_cstr()));
    if (!valueEnd) valueEnd = extensionHeader + aParameter.capacity;
    uint32 valueLen = getItemLen(valueStart, valueEnd);
    extensionHeaderValue = OSCL_HeapString<OsclMemAllocator> (valueStart, valueLen);

    // (3) check for optional method
    const char *methodStart = oscl_strstr(extensionHeader, methodTag.get_cstr());
    if (!methodStart)
    {
        httpMethod = HTTP_GET;
        return true;
    }
    methodStart += methodTag.get_size();

    OSCL_StackString<8> methodHttpGet(_STRLIT_CHAR("GET"));
    OSCL_StackString<8> methodHttpHead(_STRLIT_CHAR("HEAD"));
    OSCL_StackString<8> methodHttpPost(_STRLIT_CHAR("POST"));

    const char* methodGet = oscl_strstr(methodStart, methodHttpGet.get_cstr());
    const char* methodHead = oscl_strstr(methodStart, methodHttpHead.get_cstr());
    const char* methodPost = oscl_strstr(methodStart, methodHttpPost.get_cstr());

    httpMethod = HTTP_GET;
    if (methodPost != NULL) httpMethod = HTTP_POST;
    if (methodGet  != NULL) httpMethod = HTTP_GET;
    if (methodHead != NULL) httpMethod = HTTP_HEAD;
    if ((methodGet != NULL) && (methodHead != NULL)) httpMethod = HTTP_ALLMETHOD;

    return true;
}

bool PVMFDownloadManagerNode::IsHttpExtensionHeaderValid(PvmiKvp &aParameter)
{
    OSCL_StackString<32> downloadMode(_STRLIT_CHAR("mode=download"));
    OSCL_StackString<32> streamingMode(_STRLIT_CHAR("mode=streaming"));

    bool isDownloadMode  = (oscl_strstr(aParameter.key, downloadMode.get_cstr())  != NULL);
    bool isStreamingMode = (oscl_strstr(aParameter.key, streamingMode.get_cstr()) != NULL);

    // streaming mode only would fail, download mode specified or not specified will be viewed as true
    if (isStreamingMode && !isDownloadMode) return false;

    return true;
}

// remove the ending ';', ',' or ' ' and calulate value length
uint32 PVMFDownloadManagerNode::getItemLen(char *ptrItemStart, char *ptrItemEnd)
{
    char *ptr = ptrItemEnd - 1;
    uint32 itemLen = ptr - ptrItemStart;
    for (uint32 i = 0; i < itemLen; i++)
    {
        if (*ptr == ';' || *ptr == ',' || *ptr == ' ') --ptr;
        else break;
    }
    itemLen = ptr - ptrItemStart + 1;
    return itemLen;
}


PVMFCommandId PVMFDownloadManagerNode::setParametersAsync(PvmiMIOSession aSession,
        PvmiKvp* aParameters,
        int num_elements,
        PvmiKvp*& aRet_kvp,
        OsclAny* context)
{
    OSCL_UNUSED_ARG(aSession);
    OSCL_UNUSED_ARG(aParameters);
    OSCL_UNUSED_ARG(num_elements);
    OSCL_UNUSED_ARG(aRet_kvp);
    OSCL_UNUSED_ARG(context);
    // not supported
    OSCL_LEAVE(PVMFErrNotSupported);
    return 0;
}

uint32 PVMFDownloadManagerNode::getCapabilityMetric(PvmiMIOSession aSession)
{
    OSCL_UNUSED_ARG(aSession);
    return 0;
}

PVMFStatus PVMFDownloadManagerNode::verifyParametersSync(PvmiMIOSession aSession,
        PvmiKvp* aParameters,
        int num_elements)
{
    OSCL_UNUSED_ARG(aSession);
    OSCL_UNUSED_ARG(aParameters);
    OSCL_UNUSED_ARG(num_elements);
    // not supported
    OSCL_LEAVE(PVMFErrNotSupported);
    return 0;
}

bool PVMFDownloadManagerNode::IsDownloadExtensionHeaderValid(PvmiKvp &aParameter)
{
    OSCL_StackString<32> downloadMode(_STRLIT_CHAR("mode=download"));
    OSCL_StackString<32> streamingMode(_STRLIT_CHAR("mode=streaming"));
    OSCL_StackString<32> dlaMode(_STRLIT_CHAR("mode=dla"));

    bool isDownloadMode  = (oscl_strstr(aParameter.key, downloadMode.get_cstr())  != NULL);
    bool isStreamingMode = (oscl_strstr(aParameter.key, streamingMode.get_cstr()) != NULL);
    bool isDlaMode = (oscl_strstr(aParameter.key, dlaMode.get_cstr()) != NULL);


    // streaming mode only would fail, download mode specified or not specified will be viewed as true
    if (isStreamingMode && !isDownloadMode) return false;

    // dla mode only would fail, download mode specified or not specified will be viewed as true
    if (isDlaMode && !isDownloadMode) return false;

    return true;
}

void PVMFDownloadManagerNode::NotificationsInterfaceDestroyed()
{
    iClockNotificationsInf = NULL;
}

void PVMFDownloadManagerNode::ClockStateUpdated()
{
    if (!iDataReady)
    {
        // Don't let anyone start the clock while the source node is in underflow
        if (iPlayBackClock != NULL)
        {
            if (iPlayBackClock->GetState() == PVMFMediaClock::RUNNING)
            {
                iPlayBackClock->Pause();
            }
        }
    }
}
