Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 #ifndef PVMF_SM_FSP_BASE_IMPL_H
     19 #include "pvmf_sm_fsp_base_impl.h"
     20 #endif
     21 
     22 #ifndef PVMF_BASIC_ERRORINFOMESSAGE_H_INCLUDED
     23 #include "pvmf_basic_errorinfomessage.h"
     24 #endif
     25 
     26 #ifndef OSCL_MIME_STRING_UTILS_H
     27 #include "pv_mime_string_utils.h"
     28 #endif
     29 
     30 #ifndef PVMI_KVP_UTIL_H_INCLUDED
     31 #include "pvmi_kvp_util.h"
     32 #endif
     33 
     34 #ifndef PVMI_DRM_KVP_H_INCLUDED
     35 #include "pvmi_drm_kvp.h"
     36 #endif
     37 
     38 #ifndef PVMF_SM_FSP_BASE_METADATA_H_INCLUDED
     39 #include "pvmf_sm_fsp_base_metadata.h"
     40 #endif
     41 
     42 #ifndef OSCL_SNPRINTF_H_INCLUDED
     43 #include "oscl_snprintf.h"
     44 #endif
     45 
     46 #ifndef PVMF_JITTER_BUFFER_FACTORY_H
     47 #include "pvmf_jitter_buffer_factory.h"
     48 #endif
     49 
     50 //////////////////////////////////////////////////
     51 // Node Constructor & Destructor
     52 //////////////////////////////////////////////////
     53 
     54 PVMFSMFSPBaseNode::PVMFSMFSPBaseNode(int32 aPriority): OsclActiveObject(aPriority, "PVMFSMFSPBaseNode")
     55         , iPlayListRepositioningSupported(false)
     56         , iMetaDataInfo(NULL)
     57         , iUseCPMPluginRegistry(false)
     58         , iSMBaseLogger(NULL)
     59         , iChildNodeErrHandler(NULL)
     60 {
     61     ResetNodeParams(false);
     62     iCPM = NULL;
     63 }
     64 
     65 void PVMFSMFSPBaseNode::Construct()
     66 {
     67     CreateCommandQueues();
     68     iSessionSourceInfo = OSCL_NEW(PVMFSMFSPSessionSourceInfo, ());
     69     iMetaDataInfo = OSCL_NEW(PVMFSMSessionMetaDataInfo, ());
     70     iChildNodeErrHandler = PVMFSMFSPChildNodeErrorHandler::CreateErrHandler(this);
     71 }
     72 
     73 void PVMFSMFSPBaseNode::CreateCommandQueues()
     74 {
     75     int32 err;
     76     OSCL_TRY(err,
     77              /*
     78               * Create the input command queue.  Use a reserve to avoid lots of
     79               * dynamic memory allocation.
     80               */
     81              iInputCommands.Construct(PVMF_SM_FSP_NODE_COMMAND_ID_START,
     82                                       PVMF_SM_FSP_VECTOR_RESERVE);
     83 
     84              /*
     85               * Create the "current command" queue.  It will only contain one
     86               * command at a time, so use a reserve of 1.
     87               */
     88              iCurrentCommand.Construct(0, 1);
     89 
     90              /*
     91               * Create the "cancel command" queue.  It will only contain one
     92               * command at a time, so use a reserve of 1.
     93               */
     94              iCancelCommand.Construct(0, 1);
     95 
     96              iErrHandlingCommandQ.Construct(0, 2);
     97             );
     98     if (err != OsclErrNone)
     99     {
    100         CleanUp();
    101         OSCL_LEAVE(err);
    102     }
    103 }
    104 
    105 PVMFSMFSPBaseNode::~PVMFSMFSPBaseNode()
    106 {
    107     if (IsAdded())
    108     {
    109         Cancel();
    110         RemoveFromScheduler();
    111     }
    112     CleanUp();
    113 }
    114 
    115 void PVMFSMFSPBaseNode::CleanUp()
    116 {
    117     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::CleanUp - In"));
    118     ResetNodeParams();
    119     if (iCPM != NULL)
    120     {
    121         iCPM->ThreadLogoff();
    122         PVMFCPMFactory::DestroyContentPolicyManager(iCPM);
    123         iCPM = NULL;
    124     }
    125     PVMFSMFSPChildNodeErrorHandler::DeleteErrHandler(iChildNodeErrHandler);
    126     iChildNodeErrHandler = NULL;
    127     iFSPChildNodeContainerVec.clear();
    128     OSCL_DELETE(iMetaDataInfo);
    129     OSCL_DELETE(iSessionSourceInfo);
    130     iErrHandlingCommandQ.clear();
    131     iCancelCommand.clear();
    132     iCurrentCommand.clear();
    133     iInputCommands.clear();
    134     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::CleanUp - Out"));
    135 }
    136 
    137 ///////////////////////////////////////////////////////////////////////////////
    138 //Implementation of virtuals declared in PVMFNodeInterface
    139 ///////////////////////////////////////////////////////////////////////////////
    140 /**
    141  * Do thread-specific node creation and go to "Idle" state.
    142  */
    143 PVMFStatus PVMFSMFSPBaseNode::ThreadLogon()
    144 {
    145     PVMFStatus status = PVMFSuccess;
    146     switch (iInterfaceState)
    147     {
    148         case EPVMFNodeCreated:
    149         {
    150             if (!IsAdded())
    151                 AddToScheduler();
    152             iCommandSeqLogger = PVLogger::GetLoggerObject("pvplayercmdseq.streamingmanager");
    153             iSMBaseLogger = PVLogger::GetLoggerObject("PVMFSMFSPBaseNode");
    154             /*
    155              * Call thread logon for all the children nodes
    156              */
    157             for (uint32 i = 0; i < iFSPChildNodeContainerVec.size(); i++)
    158             {
    159                 if (iFSPChildNodeContainerVec[i].iNode->ThreadLogon() != PVMFSuccess)
    160                 {
    161                     PVMF_SM_FSP_BASE_LOGERR((0, "PVMFSMFSPBaseNode - Child Node:ThreadLogon Failed, Node Tag %d", iFSPChildNodeContainerVec[i].iNodeTag));
    162                     status = PVMFFailure;
    163                     break;
    164                 }
    165             }
    166             if (PVMFSuccess == status)
    167             {
    168                 PVMF_SM_FSP_BASE_LOGDEBUG((0, "PVMFSMFSPBaseNode::ThreadLogon() - State - EPVMFNodeIdle"));
    169                 SetState(EPVMFNodeIdle);
    170             }
    171         }
    172         break;
    173         default:
    174             status = PVMFErrInvalidState;
    175             break;
    176     }
    177 
    178     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::ThreadLogon - Out %d status", status));
    179     return (status);
    180 }
    181 
    182 /**
    183  * Do thread-specific node cleanup and go to "Created" state.
    184  */
    185 PVMFStatus PVMFSMFSPBaseNode::ThreadLogoff()
    186 {
    187     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::ThreadLogoff - In"));
    188 
    189     PVMFStatus status = PVMFSuccess;
    190     switch (iInterfaceState)
    191     {
    192         case EPVMFNodeIdle:
    193         {
    194             /* Reset the metadata key list */
    195             /* Clean up CPM related variables */
    196             /* Call thread logoff for all the children nodes */
    197             for (uint32 i = 0; i < iFSPChildNodeContainerVec.size(); i++)
    198             {
    199                 PVMFNodeInterface* node = iFSPChildNodeContainerVec[i].iNode;
    200                 if (node->GetState() != EPVMFNodeCreated)
    201                 {
    202                     if ((status = node->ThreadLogoff()) != PVMFSuccess)
    203                     {
    204                         PVMF_SM_FSP_BASE_LOGERR((0, "PVMFSMFSPBaseNode - Child Node:ThreadLogoff Failed, Node Tag %d status %d", iFSPChildNodeContainerVec[i].iNodeTag, status));
    205                     }
    206                 }
    207             }
    208             ResetNodeParams();
    209             SetState(EPVMFNodeCreated);
    210             PVMF_SM_FSP_BASE_LOGDEBUG((0, "PVMFSMFSPBaseNode::ThreadLogoff() - State - EPVMFNodeIdle"));
    211             iSMBaseLogger = NULL;
    212             iLogger = NULL;
    213             if (IsAdded())
    214                 RemoveFromScheduler();
    215         }
    216         break;
    217 
    218         case EPVMFNodeCreated:
    219             status = PVMFSuccess;
    220             break;
    221 
    222         default:
    223             status = PVMFErrInvalidState;
    224             break;
    225     }
    226     return (status);
    227 }
    228 
    229 /**
    230  * Makes session with PVMFSMFSPBaseNode node.
    231  * The purpose of this node(or of the concrete implementation of the node
    232  * derived from this node) is to handle most of the commands, which otherwise
    233  * would have been handled by the source node or various extension interfaces
    234  * that would have been exposed by it [PVMFStreamingManagerNode].
    235  * SM node and FSP will handle the command in mutually exclusive manner.
    236  * Whatever command will be issued to source node. Firstly, Streaming Manager Node
    237  * will try to service it. If SM node could not service it, it will route the
    238  * command to the FSP.
    239  * In order to send the response of the command completion (of the command
    240  * serviced by the FSP) directly to the node connected to the SM Node,
    241  * observer and the session id of the session for both the SM Node
    242  * and the FSP should be same.
    243  */
    244 PVMFSessionId PVMFSMFSPBaseNode::Connect(const PVMFNodeSessionInfo &aSessionInfo)
    245 {
    246     OSCL_UNUSED_ARG(aSessionInfo);
    247     OSCL_ASSERT(false);
    248     return 0;
    249 }
    250 
    251 OSCL_EXPORT_REF PVMFSessionId PVMFSMFSPBaseNode::Connect(const PVMFNodeSession &aUpstreamSession)
    252 {
    253     PVMFNodeSession session;
    254     session.iId = aUpstreamSession.iId;
    255     session.iInfo = aUpstreamSession.iInfo;
    256     iSessions.push_back(session);
    257     return session.iId;
    258 }
    259 
    260 /**
    261  * retrieve node capabilities.
    262  */
    263 PVMFStatus PVMFSMFSPBaseNode::GetCapability(PVMFNodeCapability& aNodeCapability)
    264 {
    265     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode:GetCapability"));
    266     aNodeCapability = iCapability;
    267     return PVMFSuccess;
    268 }
    269 
    270 /**
    271  * retrive a port iterator.
    272  */
    273 PVMFPortIter* PVMFSMFSPBaseNode::GetPorts(const PVMFPortFilter* aFilter)
    274 {
    275     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode:GetPorts"));
    276     OSCL_UNUSED_ARG(aFilter);//port filter is not implemented.
    277     return NULL;
    278 }
    279 
    280 //Implementation of Synchronous Commands
    281 
    282 /**
    283  * Provides interface with uuid PVMF_DATA_SOURCE_INIT_INTERFACE_UUID to the caller
    284 */
    285 bool PVMFSMFSPBaseNode::queryInterface(const PVUuid& uuid, PVInterface*& iface)
    286 {
    287     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMRTSPUnicastNode::queryInterface - In"));
    288 
    289     if (uuid == PVMF_DATA_SOURCE_INIT_INTERFACE_UUID)
    290     {
    291         iface = OSCL_STATIC_CAST(PVMFDataSourceInitializationExtensionInterface*, this);
    292     }
    293     else
    294     {
    295         PVMF_SM_FSP_BASE_LOGERR((0, "PVMFSMFSPBaseNode::queryInterface() please call async version for this UUID."));
    296         return false;
    297     }
    298 
    299     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::queryInterface - Out"));
    300     return true;
    301 }
    302 
    303 //Asynchronous commands
    304 /**
    305  * Queue an asynchronous QueryUUID command
    306  * QueryUUID for the streaming manager node is not complete until QueryUUIDs
    307  * are complete for all the children node (viz. session controller, jitter buffer
    308  * controller etc)
    309  */
    310 PVMFCommandId PVMFSMFSPBaseNode::QueryUUID(PVMFSessionId aSession
    311         , const PvmfMimeString& aMimeType
    312         , Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids
    313         , bool aExactUuidsOnly
    314         , const OsclAny* aContext)
    315 {
    316     OSCL_UNUSED_ARG(aSession);
    317     OSCL_UNUSED_ARG(aMimeType);
    318     OSCL_UNUSED_ARG(aUuids);
    319     OSCL_UNUSED_ARG(aExactUuidsOnly);
    320     OSCL_UNUSED_ARG(aContext);
    321     PVMF_SM_FSP_BASE_LOGERR((0, "PVMFSMFSPBaseNode::QueryUUID - Error not expected"));
    322     OSCL_ASSERT(false);
    323     return 0;
    324 }
    325 
    326 /**
    327  * Queue an asynchronous node command QueryInterface
    328  */
    329 PVMFCommandId PVMFSMFSPBaseNode::QueryInterface(PVMFSessionId aSession
    330         , const PVUuid& aUuid
    331         , PVInterface*& aInterfacePtr
    332         , const OsclAny* aContext)
    333 {
    334     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::QueryInterface - In"));
    335     PVMFSMFSPBaseNodeCommand cmd;
    336     cmd.PVMFSMFSPBaseNodeCommandBase::Construct(aSession, PVMF_SMFSP_NODE_QUERYINTERFACE, aUuid, aInterfacePtr, aContext);
    337     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::QueryInterface - Out"));
    338     return QueueCommandL(cmd);
    339 }
    340 
    341 /**
    342  * Queue an asynchronous node command - RequestPort
    343  */
    344 PVMFCommandId PVMFSMFSPBaseNode::RequestPort(PVMFSessionId aSession
    345         , int32 aPortTag
    346         , const PvmfMimeString* aPortConfig
    347         , const OsclAny* aContext)
    348 {
    349     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::RequestPort - In"));
    350     PVMFSMFSPBaseNodeCommand cmd;
    351     cmd.PVMFSMFSPBaseNodeCommandBase::Construct(aSession,
    352             PVMF_SMFSP_NODE_REQUESTPORT,
    353             aPortTag,
    354             aPortConfig,
    355             aContext);
    356     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::RequestPort - Out"));
    357     return QueueCommandL(cmd);
    358 }
    359 
    360 /**
    361  * Queue an asynchronous node command - ReleasePort
    362  */
    363 PVMFCommandId PVMFSMFSPBaseNode::ReleasePort(PVMFSessionId aSession
    364         , PVMFPortInterface& aPort
    365         , const OsclAny* aContext)
    366 {
    367     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::ReleasePort - In"));
    368     PVMFSMFSPBaseNodeCommand cmd;
    369     cmd.PVMFSMFSPBaseNodeCommandBase::Construct(aSession, PVMF_SMFSP_NODE_RELEASEPORT, aPort, aContext);
    370     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::ReleasePort - Out"));
    371     return QueueCommandL(cmd);
    372 }
    373 
    374 /**
    375  * Queue an asynchronous node command - Init
    376  */
    377 PVMFCommandId PVMFSMFSPBaseNode::Init(PVMFSessionId aSession, const OsclAny* aContext)
    378 {
    379     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::Init - In"));
    380     PVMFSMFSPBaseNodeCommand cmd;
    381     cmd.PVMFSMFSPBaseNodeCommandBase::Construct(aSession, PVMF_SMFSP_NODE_INIT, aContext);
    382     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::Init - Out"));
    383     return QueueCommandL(cmd);
    384 }
    385 
    386 /**
    387  * Queue an asynchronous node command - Prepare
    388  */
    389 PVMFCommandId PVMFSMFSPBaseNode::Prepare(PVMFSessionId aSession
    390         , const OsclAny* aContext)
    391 {
    392     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::Prepare - In"));
    393     /* Queue an internal command for Graph construct */
    394     PVMFSMFSPBaseNodeCommand cmdGC;
    395     cmdGC.PVMFSMFSPBaseNodeCommandBase::Construct(aSession,
    396             PVMF_SMFSP_NODE_CONSTRUCT_SESSION,
    397             NULL);
    398 
    399     QueueCommandL(cmdGC);
    400 
    401     PVMFSMFSPBaseNodeCommand cmdPrep;
    402     cmdPrep.PVMFSMFSPBaseNodeCommandBase::Construct(aSession,
    403             PVMF_SMFSP_NODE_PREPARE,
    404             aContext);
    405 
    406     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::Prepare - Out"));
    407     return QueueCommandL(cmdPrep);
    408 }
    409 
    410 /**
    411  * Queue an asynchronous node command - Start
    412  */
    413 PVMFCommandId PVMFSMFSPBaseNode::Start(PVMFSessionId aSession
    414                                        , const OsclAny* aContext)
    415 {
    416     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::Start - In"));
    417     PVMFSMFSPBaseNodeCommand cmd;
    418     cmd.PVMFSMFSPBaseNodeCommandBase::Construct(aSession, PVMF_SMFSP_NODE_START, aContext);
    419     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::Start - Out"));
    420     return QueueCommandL(cmd);
    421 }
    422 
    423 /**
    424  * Queue an asynchronous node command - Stop
    425  */
    426 PVMFCommandId PVMFSMFSPBaseNode::Stop(PVMFSessionId aSession
    427                                       , const OsclAny* aContext)
    428 {
    429     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::Stop - In"));
    430     PVMFSMFSPBaseNodeCommand cmd;
    431     cmd.PVMFSMFSPBaseNodeCommandBase::Construct(aSession, PVMF_SMFSP_NODE_STOP, aContext);
    432     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::Stop - Out"));
    433     return QueueCommandL(cmd);
    434 }
    435 
    436 /**
    437  * Queue an asynchronous node command - Flush
    438  */
    439 PVMFCommandId PVMFSMFSPBaseNode::Flush(PVMFSessionId aSession
    440                                        , const OsclAny* aContext)
    441 {
    442     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::Flush - In"));
    443     PVMFSMFSPBaseNodeCommand cmd;
    444     cmd.PVMFSMFSPBaseNodeCommandBase::Construct(aSession, PVMF_SMFSP_NODE_FLUSH, aContext);
    445     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::Flush - Out"));
    446     return QueueCommandL(cmd);
    447 }
    448 
    449 /**
    450  * Queue an asynchronous node command - Pause
    451  */
    452 PVMFCommandId PVMFSMFSPBaseNode::Pause(PVMFSessionId aSession
    453                                        , const OsclAny* aContext)
    454 {
    455     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::Pause - In"));
    456     PVMFSMFSPBaseNodeCommand cmd;
    457     cmd.PVMFSMFSPBaseNodeCommandBase::Construct(aSession, PVMF_SMFSP_NODE_PAUSE, aContext);
    458     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::Pause - Out"));
    459     return QueueCommandL(cmd);
    460 }
    461 
    462 /**
    463  * Queue an asynchronous node command - Reset
    464  */
    465 PVMFCommandId PVMFSMFSPBaseNode::Reset(PVMFSessionId aSession
    466                                        , const OsclAny* aContext)
    467 {
    468     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::Reset - In"));
    469     PVMFSMFSPBaseNodeCommand cmd;
    470     cmd.PVMFSMFSPBaseNodeCommandBase::Construct(aSession, PVMF_SMFSP_NODE_RESET, aContext);
    471     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::Reset - Out"));
    472     return QueueCommandL(cmd);
    473 }
    474 
    475 /**
    476  * Queue an asynchronous node command - CancelAllCommands
    477  */
    478 PVMFCommandId PVMFSMFSPBaseNode::CancelAllCommands(PVMFSessionId aSession
    479         , const OsclAny* aContextData)
    480 {
    481     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode:CancelAllCommands"));
    482     PVMFSMFSPBaseNodeCommand cmd;
    483     cmd.PVMFSMFSPBaseNodeCommandBase::Construct(aSession, PVMF_SMFSP_NODE_CANCELALLCOMMANDS, aContextData);
    484     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::CancelAllCommands - Out"));
    485     return QueueCommandL(cmd);
    486 }
    487 
    488 /**
    489  * Queue an asynchronous node command - CancelCommand
    490  */
    491 PVMFCommandId PVMFSMFSPBaseNode::CancelCommand(PVMFSessionId aSession
    492         , PVMFCommandId aCmdId
    493         , const OsclAny* aContextData)
    494 {
    495     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode:CancelCommand CommandId [%d]", aCmdId));
    496     PVMFSMFSPBaseNodeCommand cmd;
    497     cmd.PVMFSMFSPBaseNodeCommandBase::Construct(aSession, PVMF_SMFSP_NODE_CANCELCOMMAND, aCmdId, aContextData);
    498     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::CancelCommand - Out"));
    499     return QueueCommandL(cmd);
    500 }
    501 
    502 /**
    503  *Implementation of HandlePortActivity
    504  */
    505 void PVMFSMFSPBaseNode::HandlePortActivity(const PVMFPortActivity& aActivity)
    506 {
    507     OSCL_UNUSED_ARG(aActivity);
    508     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode:HandlePortActivity - Not Implemented"));
    509 }
    510 
    511 ///////////////////////////////////////////////////////////////////////////////
    512 // Implementation of virtuals from OsclActiveObject
    513 ///////////////////////////////////////////////////////////////////////////////
    514 void PVMFSMFSPBaseNode::Run()
    515 {
    516     if (EPVMFNodeError == iInterfaceState)
    517     {
    518         if (!iErrHandlingCommandQ.empty())
    519         {
    520             if (ProcessCommand(iErrHandlingCommandQ.front()))
    521             {
    522                 /*
    523                  * re-schedule if more commands to do
    524                  * and node isn't reset.
    525                  */
    526                 if (!iErrHandlingCommandQ.empty() && iInterfaceState != EPVMFNodeCreated)
    527                 {
    528                     if (IsAdded())
    529                     {
    530                         RunIfNotReady();
    531                     }
    532                 }
    533                 return;
    534             }
    535         }
    536         return;
    537     }
    538     /* Process commands */
    539     if (!iInputCommands.empty())
    540     {
    541         if (ProcessCommand(iInputCommands.front()))
    542         {
    543             /*
    544              * re-schedule if more commands to do
    545              * and node isn't reset.
    546              */
    547             if (!iInputCommands.empty() && iInterfaceState != EPVMFNodeCreated)
    548             {
    549                 if (IsAdded())
    550                 {
    551                     RunIfNotReady();
    552                 }
    553             }
    554             return;
    555         }
    556     }
    557 
    558     /*
    559      * If we get here we did not process any commands.
    560      * Check for completion of a flush command...
    561      */
    562     if (FlushPending())
    563     {
    564         /*
    565          * Flush is complete.  Go to initialized state.
    566          */
    567         SetState(EPVMFNodeInitialized);
    568         CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
    569         if (IsAdded())
    570         {
    571             RunIfNotReady();
    572         }
    573     }
    574 }
    575 
    576 void PVMFSMFSPBaseNode::DoCancel()
    577 {
    578     /* the base class cancel operation is sufficient */
    579     OsclActiveObject::DoCancel();
    580 }
    581 
    582 ///////////////////////////////////////////////////////////////////////////////
    583 //Implemenataion fo pure virtual asyn calls from PvmiCapabilityAndConfig
    584 ///////////////////////////////////////////////////////////////////////////////
    585 PVMFCommandId PVMFSMFSPBaseNode::setParametersAsync(PvmiMIOSession aSession,
    586         PvmiKvp* aParameters,
    587         int num_elements,
    588         PvmiKvp*& aRet_kvp,
    589         OsclAny* context)
    590 {
    591     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::setParametersAsync - In"));
    592     PVMFSMFSPBaseNodeCommand cmd;
    593     cmd.PVMFSMFSPBaseNodeCommand::Construct(0,
    594                                             PVMF_SMFSP_NODE_CAPCONFIG_SETPARAMS,
    595                                             aSession, aParameters, num_elements, aRet_kvp, context);
    596     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::setParametersAsync - Out"));
    597     return QueueCommandL(cmd);
    598 }
    599 
    600 ///////////////////////////////////////////////////////////////////////////////
    601 //Implementation of PvmfDataSourcePlaybackControlInterface's async pure virtual func
    602 ///////////////////////////////////////////////////////////////////////////////
    603 /**
    604  * Queue an asynchronous node command - SetDataSourcePosition
    605  */
    606 PVMFCommandId PVMFSMFSPBaseNode::SetDataSourcePosition(PVMFSessionId aSessionId,
    607         PVMFTimestamp aTargetNPT,
    608         PVMFTimestamp& aActualNPT,
    609         PVMFTimestamp& aActualMediaDataTS,
    610         bool aSeekToSyncPoint,
    611         uint32 aStreamID,
    612         OsclAny* aContext)
    613 {
    614     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::SetDataSourcePosition - In"));
    615 
    616     PVMFSMFSPBaseNodeCommand cmd;
    617     cmd.PVMFSMFSPBaseNodeCommand::Construct(aSessionId,
    618                                             PVMF_SMFSP_NODE_SET_DATASOURCE_POSITION,
    619                                             aTargetNPT,
    620                                             &aActualNPT,
    621                                             &aActualMediaDataTS,
    622                                             aSeekToSyncPoint,
    623                                             aStreamID,
    624                                             aContext);
    625     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::SetDataSourcePosition - Out"));
    626     return QueueCommandL(cmd);
    627 }
    628 
    629 /**
    630  * Queue an asynchronous node command - SetDataSourcePosition (if supported)
    631  */
    632 PVMFCommandId PVMFSMFSPBaseNode::SetDataSourcePosition(PVMFSessionId aSessionId,
    633         PVMFDataSourcePositionParams& aPVMFDataSourcePositionParams,
    634         OsclAny* aContext)
    635 {
    636     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::SetDataSourcePosition - Playlist In"));
    637     PVMFSMFSPBaseNodeCommand cmd;
    638     if (iPlayListRepositioningSupported)
    639     {
    640         cmd.PVMFSMFSPBaseNodeCommand::Construct(aSessionId,
    641                                                 PVMF_SMFSP_NODE_SET_DATASOURCE_POSITION,
    642                                                 &aPVMFDataSourcePositionParams,
    643                                                 aContext);
    644         iPlayListRepositioning = true;
    645     }
    646     else
    647     {
    648         PVMF_SM_FSP_BASE_LOGERR((0, "PVMFSMFSPBaseNode::SetDataSourcePosition - PlayList - Not Supported for non RTSP"));
    649         OSCL_LEAVE(PVMFErrNotSupported);
    650     }
    651     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::SetDataSourcePosition - Playlist Out"));
    652     return QueueCommandL(cmd);
    653 }
    654 
    655 /**
    656  * Queue an asynchronous node command - QueryDataSourcePosition
    657  */
    658 PVMFCommandId PVMFSMFSPBaseNode::QueryDataSourcePosition(PVMFSessionId aSessionId,
    659         PVMFTimestamp aTargetNPT,
    660         PVMFTimestamp& aActualNPT,
    661         bool aSeekToSyncPoint,
    662         OsclAny* aContext
    663                                                         )
    664 {
    665     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::QueryDataSourcePosition - In"));
    666     PVMFSMFSPBaseNodeCommand cmd;
    667     cmd.PVMFSMFSPBaseNodeCommand::Construct(aSessionId,
    668                                             PVMF_SMFSP_NODE_QUERY_DATASOURCE_POSITION,
    669                                             aTargetNPT,
    670                                             &aActualNPT,
    671                                             aSeekToSyncPoint,
    672                                             aContext);
    673 
    674     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::QueryDataSourcePosition - Out"));
    675     return QueueCommandL(cmd);
    676 }
    677 
    678 /**
    679  * Queue an asynchronous node command - QueryDataSourcePosition
    680  */
    681 PVMFCommandId PVMFSMFSPBaseNode::QueryDataSourcePosition(PVMFSessionId aSessionId,
    682         PVMFTimestamp aTargetNPT,
    683         PVMFTimestamp& aSyncBeforeTargetNPT,
    684         PVMFTimestamp& aSyncAfterTargetNPT,
    685         OsclAny* aContext,
    686         bool aSeekToSyncPoint
    687                                                         )
    688 {
    689     // This is only to comply the interface file change due to Mp4 parser node.
    690     // Actual testing/supportfs will be done here if required.
    691     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::QueryDataSourcePosition - In"));
    692     PVMFSMFSPBaseNodeCommand cmd;
    693     cmd.PVMFSMFSPBaseNodeCommand::Construct(aSessionId,
    694                                             PVMF_SMFSP_NODE_QUERY_DATASOURCE_POSITION,
    695                                             aTargetNPT,
    696                                             &aSyncBeforeTargetNPT,
    697                                             &aSyncAfterTargetNPT,
    698                                             aContext,
    699                                             aSeekToSyncPoint);
    700     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::QueryDataSourcePosition - Out"));
    701     return QueueCommandL(cmd);
    702 }
    703 
    704 /**
    705  * Queue an asynchronous node command - SetDataSourceRate (if supported)
    706  */
    707 PVMFCommandId PVMFSMFSPBaseNode::SetDataSourceRate(PVMFSessionId aSessionId,
    708         int32 aRate,
    709         PVMFTimebase* aTimebase,
    710         OsclAny* aContext)
    711 {
    712     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::SetDataSourceRate - In"));
    713     OSCL_UNUSED_ARG(aSessionId);
    714     OSCL_UNUSED_ARG(aRate);
    715     OSCL_UNUSED_ARG(aTimebase);
    716     OSCL_UNUSED_ARG(aContext);
    717     OSCL_LEAVE(OsclErrNotSupported);
    718     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::SetDataSourceRate - Out"));
    719     return 0;
    720 }
    721 
    722 ///////////////////////////////////////////////////////////////////////////////
    723 //Implementation of virtuals declared in PVMFMetadataExtensionInterface
    724 ///////////////////////////////////////////////////////////////////////////////
    725 uint32 PVMFSMFSPBaseNode::GetNumMetadataKeysBase(char* aQueryKeyString)
    726 {
    727     uint32 num_entries = 0;
    728 
    729     if (aQueryKeyString == NULL)
    730     {
    731         // No query key so just return all the available keys
    732         num_entries = iAvailableMetadataKeys.size();
    733     }
    734     else
    735     {
    736         // Determine the number of metadata keys based on the query key string provided
    737         uint32 i;
    738         for (i = 0; i < iAvailableMetadataKeys.size(); i++)
    739         {
    740             // Check if the key matches the query key
    741             if (pv_mime_strcmp(iAvailableMetadataKeys[i].get_cstr(), aQueryKeyString) >= 0)
    742             {
    743                 num_entries++;
    744             }
    745         }
    746     }
    747 
    748     if ((iCPMMetaDataExtensionInterface != NULL) && (iSessionSourceInfo->iDRMProtected  == true))
    749     {
    750         num_entries +=
    751             iCPMMetaDataExtensionInterface->GetNumMetadataKeys(aQueryKeyString);
    752     }
    753 
    754     return num_entries;
    755 }
    756 
    757 uint32 PVMFSMFSPBaseNode::GetNumMetadataValuesBase(PVMFMetadataList& aKeyList)
    758 {
    759 
    760     uint32 numkeys = aKeyList.size();
    761 
    762     if ((numkeys == 0) || !(iMetaDataInfo->iMetadataAvailable))
    763     {
    764         return 0;
    765     }
    766 
    767     // Get Num Tracks
    768     uint32 numtracks = iMetaDataInfo->iNumTracks;
    769 
    770     uint32 numvalentries = 0;
    771     for (uint32 lcv = 0; lcv < numkeys; lcv++)
    772     {
    773         if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_ALBUM_KEY) == 0 &&
    774                 iMetaDataInfo->iAlbumPresent)
    775         {
    776             // Album
    777             // Increment the counter for the number of values found so far
    778             ++numvalentries;
    779         }
    780         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_AUTHOR_KEY) == 0 &&
    781                  iMetaDataInfo->iAuthorPresent)
    782         {
    783             // Author
    784             // Increment the counter for the number of values found so far
    785             ++numvalentries;
    786         }
    787         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_ARTIST_KEY) == 0 &&
    788                  iMetaDataInfo->iPerformerPresent)
    789         {
    790             // Artist/performer
    791             // Increment the counter for the number of values found so far
    792             ++numvalentries;
    793         }
    794         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TITLE_KEY) == 0 &&
    795                  iMetaDataInfo->iTitlePresent)
    796         {
    797             // Title
    798             // Increment the counter for the number of values found so far
    799             ++numvalentries;
    800         }
    801         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_DESCRIPTION_KEY) == 0 &&
    802                  iMetaDataInfo->iDescriptionPresent)
    803         {
    804             // Description
    805             // Increment the counter for the number of values found so far
    806             ++numvalentries;
    807         }
    808         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_RATING_KEY) == 0 &&
    809                  iMetaDataInfo->iRatingPresent)
    810         {
    811             // Rating
    812             // Increment the counter for the number of values found so far
    813             ++numvalentries;
    814         }
    815         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_COPYRIGHT_KEY) == 0 &&
    816                  iMetaDataInfo->iCopyRightPresent)
    817         {
    818             // Copyright
    819             // Increment the counter for the number of values found so far
    820             ++numvalentries;
    821         }
    822         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_GENRE_KEY) == 0 &&
    823                  iMetaDataInfo->iGenrePresent)
    824         {
    825             // Genre
    826             // Increment the counter for the number of values found so far
    827             ++numvalentries;
    828         }
    829         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_LYRICS_KEY) == 0 &&
    830                  iMetaDataInfo->iLyricsPresent)
    831         {
    832             // Lyrics
    833             // Increment the counter for the number of values found so far
    834             ++numvalentries;
    835         }
    836         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_CLASSIFICATION_KEY) == 0 &&
    837                  iMetaDataInfo->iClassificationPresent)
    838         {
    839             // Classification
    840             // Increment the counter for the number of values found so far
    841             ++numvalentries;
    842         }
    843         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_KEYWORDS_KEY) == 0 &&
    844                  iMetaDataInfo->iKeyWordsPresent)
    845         {
    846             // Keywords
    847             // Increment the counter for the number of values found so far
    848             numvalentries += iMetaDataInfo->iNumKeyWords;
    849         }
    850         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_LOCATION_KEY) == 0 &&
    851                  iMetaDataInfo->iLocationPresent)
    852         {
    853             // Location
    854             // Increment the counter for the number of values found so far
    855             ++numvalentries;
    856         }
    857         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_DURATION_KEY) == 0)
    858         {
    859             // Session Duration
    860             // Increment the counter for the number of values found so far
    861             ++numvalentries;
    862         }
    863         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_NUMTRACKS_KEY) == 0 &&
    864                  numtracks > 0)
    865         {
    866             // Number of tracks
    867             // Increment the counter for the number of values found so far
    868             ++numvalentries;
    869         }
    870         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_RANDOM_ACCESS_DENIED_KEY) == 0)
    871         {
    872             // Increment the counter for the number of values found so far
    873             ++numvalentries;
    874         }
    875         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_YEAR_KEY) == 0)
    876         {
    877             // Increment the counter for the number of values found so far
    878             ++numvalentries;
    879         }
    880         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_NUM_GRAPHICS_KEY) == 0 &&
    881                  iMetaDataInfo->iWMPicturePresent)
    882         {
    883             // Num Picture
    884             // Increment the counter for the number of values found so far
    885             ++numvalentries;
    886         }
    887         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_GRAPHICS_KEY) == 0 &&
    888                  iMetaDataInfo->iWMPicturePresent)
    889         {
    890             // Picture
    891             // Increment the counter for the number of values found so far
    892             uint32 startindex = 0;
    893             const uint32 numPictures = iMetaDataInfo->iWMPictureIndexVec.size();
    894             uint32 endindex = numPictures - 1;
    895             /* Check if the index parameter is present */
    896             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
    897             if (indexstr != NULL)
    898             {
    899                 /* Retrieve the index values */
    900                 GetIndexParamValues(indexstr, startindex, endindex);
    901             }
    902 
    903             /* Validate the indices */
    904             if (startindex > endindex || startindex >= numPictures || endindex >= numPictures)
    905             {
    906                 continue;
    907             }
    908 
    909             // Increment the counter for the number of values found so far
    910             numvalentries += (endindex + 1 - startindex);
    911         }
    912         else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_TYPE_KEY) != NULL)
    913         {
    914             // Track type
    915             // Determine the index requested. Default to all tracks
    916             uint32 startindex = 0;
    917             uint32 endindex = numtracks - 1;
    918             // Check if the index parameter is present
    919             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
    920             if (indexstr != NULL)
    921             {
    922                 // Retrieve the index values
    923                 GetIndexParamValues(indexstr, startindex, endindex);
    924             }
    925             // Validate the indices
    926             if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks)
    927             {
    928                 continue;
    929             }
    930 
    931             for (uint32 i = startindex; i <= endindex; ++i)
    932             {
    933                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
    934                 {
    935                     PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
    936                     if (trackMetaDataInfo.iMimeType.get_cstr())
    937                     {
    938                         numvalentries ++;
    939                     }
    940                 }
    941             }
    942 
    943         }
    944         else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_DURATION_KEY) != NULL)
    945         {
    946             // Track duration
    947             // Determine the index requested. Default to all tracks
    948             uint32 startindex = 0;
    949             uint32 endindex = numtracks - 1;
    950             // Check if the index parameter is present
    951             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
    952             if (indexstr != NULL)
    953             {
    954                 // Retrieve the index values
    955                 GetIndexParamValues(indexstr, startindex, endindex);
    956             }
    957             // Validate the indices
    958             if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks)
    959             {
    960                 continue;
    961             }
    962 
    963             // Increment the counter for the number of values found so far
    964             numvalentries += (endindex + 1 - startindex);
    965         }
    966         else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_SELECTED_KEY) != NULL)
    967         {
    968             // Track selected
    969             // Determine the index requested. Default to all tracks
    970             uint32 startindex = 0;
    971             uint32 endindex = numtracks - 1;
    972             // Check if the index parameter is present
    973             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
    974             if (indexstr != NULL)
    975             {
    976                 // Retrieve the index values
    977                 GetIndexParamValues(indexstr, startindex, endindex);
    978             }
    979             // Validate the indices
    980             if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks)
    981             {
    982                 continue;
    983             }
    984             // Increment the counter for the number of values found so far
    985             numvalentries += (endindex + 1 - startindex);
    986         }
    987         else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_WIDTH_KEY) != NULL))
    988         {
    989             /*
    990              * Codec Description
    991              * Determine the index requested.
    992              */
    993             uint32 startindex = 0;
    994             uint32 endindex   = 0;
    995             /* Check if the index parameter is present */
    996             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr(aKeyList[lcv].get_cstr(),
    997                                              PVMFSTREAMINGMGRNODE_INDEX));
    998             if (indexstr != NULL)
    999             {
   1000                 /* Retrieve the index values */
   1001                 GetIndexParamValues(indexstr, startindex, endindex);
   1002             }
   1003             /* Validate the indices */
   1004             if ((startindex > endindex) ||
   1005                     (startindex >= (uint32)numtracks) ||
   1006                     (endindex >= (uint32)numtracks))
   1007             {
   1008                 continue;
   1009             }
   1010             numvalentries += (endindex + 1 - startindex);
   1011         }
   1012         else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_HEIGHT_KEY) != NULL))
   1013         {
   1014             /*
   1015              * Codec Description
   1016              * Determine the index requested.
   1017              */
   1018             uint32 startindex = 0;
   1019             uint32 endindex   = 0;
   1020             /* Check if the index parameter is present */
   1021             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr(aKeyList[lcv].get_cstr(),
   1022                                              PVMFSTREAMINGMGRNODE_INDEX));
   1023             if (indexstr != NULL)
   1024             {
   1025                 /* Retrieve the index values */
   1026                 GetIndexParamValues(indexstr, startindex, endindex);
   1027             }
   1028             /* Validate the indices */
   1029             if ((startindex > endindex) ||
   1030                     (startindex >= (uint32)numtracks) ||
   1031                     (endindex >= (uint32)numtracks))
   1032             {
   1033                 continue;
   1034             }
   1035             numvalentries += (endindex + 1 - startindex);
   1036         }
   1037         else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_SAMPLERATE_KEY) != NULL))
   1038         {
   1039             /*
   1040              * Codec Description
   1041              * Determine the index requested.
   1042              */
   1043             uint32 startindex = 0;
   1044             uint32 endindex   = 0;
   1045             /* Check if the index parameter is present */
   1046             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr(aKeyList[lcv].get_cstr(),
   1047                                              PVMFSTREAMINGMGRNODE_INDEX));
   1048             if (indexstr != NULL)
   1049             {
   1050                 /* Retrieve the index values */
   1051                 GetIndexParamValues(indexstr, startindex, endindex);
   1052             }
   1053             /* Validate the indices */
   1054             if ((startindex > endindex) ||
   1055                     (startindex >= (uint32)numtracks) ||
   1056                     (endindex >= (uint32)numtracks))
   1057             {
   1058                 continue;
   1059             }
   1060             numvalentries += (endindex + 1 - startindex);
   1061         }
   1062         else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_NUMCHANNELS_KEY) != NULL))
   1063         {
   1064             /*
   1065              * Codec Description
   1066              * Determine the index requested.
   1067              */
   1068             uint32 startindex = 0;
   1069             uint32 endindex   = 0;
   1070             /* Check if the index parameter is present */
   1071             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr(aKeyList[lcv].get_cstr(),
   1072                                              PVMFSTREAMINGMGRNODE_INDEX));
   1073             if (indexstr != NULL)
   1074             {
   1075                 /* Retrieve the index values */
   1076                 GetIndexParamValues(indexstr, startindex, endindex);
   1077             }
   1078             /* Validate the indices */
   1079             if ((startindex > endindex) ||
   1080                     (startindex >= (uint32)numtracks) ||
   1081                     (endindex >= (uint32)numtracks))
   1082             {
   1083                 continue;
   1084             }
   1085             numvalentries += (endindex + 1 - startindex);
   1086         }
   1087         else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_AUDIO_BITS_PER_SAMPLE_KEY) != NULL))
   1088         {
   1089             /*
   1090              * Codec Description
   1091              * Determine the index requested.
   1092              */
   1093             uint32 startindex = 0;
   1094             uint32 endindex   = 0;
   1095             /* Check if the index parameter is present */
   1096             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr(aKeyList[lcv].get_cstr(),
   1097                                              PVMFSTREAMINGMGRNODE_INDEX));
   1098             if (indexstr != NULL)
   1099             {
   1100                 /* Retrieve the index values */
   1101                 GetIndexParamValues(indexstr, startindex, endindex);
   1102             }
   1103             /* Validate the indices */
   1104             if ((startindex > endindex) ||
   1105                     (startindex >= (uint32)numtracks) ||
   1106                     (endindex >= (uint32)numtracks))
   1107             {
   1108                 continue;
   1109             }
   1110             numvalentries += (endindex + 1 - startindex);
   1111         }
   1112         else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_TRACKID_KEY) != NULL))
   1113         {
   1114             /*
   1115              * Codec Description
   1116              * Determine the index requested.
   1117              */
   1118             uint32 startindex = 0;
   1119             uint32 endindex   = 0;
   1120             /* Check if the index parameter is present */
   1121             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr(aKeyList[lcv].get_cstr(),
   1122                                              PVMFSTREAMINGMGRNODE_INDEX));
   1123             if (indexstr != NULL)
   1124             {
   1125                 /* Retrieve the index values */
   1126                 GetIndexParamValues(indexstr, startindex, endindex);
   1127             }
   1128             /* Validate the indices */
   1129             if ((startindex > endindex) ||
   1130                     (startindex >= (uint32)numtracks) ||
   1131                     (endindex >= (uint32)numtracks))
   1132             {
   1133                 continue;
   1134             }
   1135             numvalentries += (endindex + 1 - startindex);
   1136         }
   1137         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_CLIP_TYPE_KEY) == 0)
   1138         {
   1139             // Increment the counter for the number of values found so far
   1140             ++numvalentries;
   1141         }
   1142         else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_FRAME_RATE_KEY) != NULL))
   1143         {
   1144             /*
   1145              * Codec Description
   1146              * Determine the index requested.
   1147              */
   1148             uint32 startindex = 0;
   1149             uint32 endindex   = 0;
   1150             /* Check if the index parameter is present */
   1151             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr(aKeyList[lcv].get_cstr(),
   1152                                              PVMFSTREAMINGMGRNODE_INDEX));
   1153             if (indexstr != NULL)
   1154             {
   1155                 /* Retrieve the index values */
   1156                 GetIndexParamValues(indexstr, startindex, endindex);
   1157             }
   1158             /* Validate the indices */
   1159             if ((startindex > endindex) ||
   1160                     (startindex >= (uint32)numtracks) ||
   1161                     (endindex >= (uint32)numtracks))
   1162             {
   1163                 continue;
   1164             }
   1165             numvalentries += (endindex + 1 - startindex);
   1166         }
   1167         else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_NAME_KEY) != NULL))
   1168         {
   1169             /*
   1170              * Codec Name
   1171              * Determine the index requested.
   1172              */
   1173             uint32 startindex = 0;
   1174             uint32 endindex   = 0;
   1175             /* Check if the index parameter is present */
   1176             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr(aKeyList[lcv].get_cstr(),
   1177                                              PVMFSTREAMINGMGRNODE_INDEX));
   1178             if (indexstr != NULL)
   1179             {
   1180                 /* Retrieve the index values */
   1181                 GetIndexParamValues(indexstr, startindex, endindex);
   1182             }
   1183             /* Validate the indices */
   1184             if ((startindex > endindex) ||
   1185                     (startindex >= (uint32)numtracks) ||
   1186                     (endindex >= (uint32)numtracks))
   1187             {
   1188                 continue;
   1189             }
   1190 
   1191             for (uint32 i = startindex; i <= endindex; ++i)
   1192             {
   1193                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   1194                 {
   1195                     PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   1196                     if (trackMetaDataInfo.iCodecName.get_size() > 0)
   1197                     {
   1198                         ++numvalentries;
   1199                     }
   1200                 }
   1201             }
   1202         }
   1203         else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_DESCRIPTION_KEY) != NULL))
   1204         {
   1205             /*
   1206              * Codec Description
   1207              * Determine the index requested.
   1208              */
   1209             uint32 startindex = 0;
   1210             uint32 endindex   = 0;
   1211             /* Check if the index parameter is present */
   1212             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr(aKeyList[lcv].get_cstr(),
   1213                                              PVMFSTREAMINGMGRNODE_INDEX));
   1214             if (indexstr != NULL)
   1215             {
   1216                 /* Retrieve the index values */
   1217                 GetIndexParamValues(indexstr, startindex, endindex);
   1218             }
   1219             /* Validate the indices */
   1220             if ((startindex > endindex) ||
   1221                     (startindex >= (uint32)numtracks) ||
   1222                     (endindex >= (uint32)numtracks))
   1223             {
   1224                 continue;
   1225             }
   1226             for (uint32 i = startindex; i <= endindex; ++i)
   1227             {
   1228                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   1229                 {
   1230                     PVMFSMTrackMetaDataInfo trackInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   1231                     if (trackInfo.iCodecDescription.get_size() > 0)
   1232                     {
   1233                         ++numvalentries;
   1234                     }
   1235                 }
   1236             }
   1237         }
   1238         else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_DATA_KEY) != NULL))
   1239         {
   1240             /*
   1241              * Codec Description
   1242              * Determine the index requested.
   1243              */
   1244             uint32 startindex = 0;
   1245             uint32 endindex   = 0;
   1246             /* Check if the index parameter is present */
   1247             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr(aKeyList[lcv].get_cstr(),
   1248                                              PVMFSTREAMINGMGRNODE_INDEX));
   1249             if (indexstr != NULL)
   1250             {
   1251                 /* Retrieve the index values */
   1252                 GetIndexParamValues(indexstr, startindex, endindex);
   1253             }
   1254             /* Validate the indices */
   1255             if ((startindex > endindex) ||
   1256                     (startindex >= (uint32)numtracks) ||
   1257                     (endindex >= (uint32)numtracks))
   1258             {
   1259                 continue;
   1260             }
   1261             for (uint32 i = startindex; i <= endindex; ++i)
   1262             {
   1263                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   1264                 {
   1265                     PVMFSMTrackMetaDataInfo trackInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   1266                     if (trackInfo.iCodecSpecificInfo.getMemFragPtr())
   1267                     {
   1268                         ++numvalentries;
   1269                     }
   1270                 }
   1271             }
   1272         }
   1273         else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVMF_DRM_INFO_IS_PROTECTED_QUERY) == 0)
   1274                  && ((iUseCPMPluginRegistry == false) || (iSessionSourceInfo->iDRMProtected == false)))
   1275         {
   1276             /*
   1277              * is-protected
   1278              * Increment the counter for the number of values found so far
   1279              */
   1280             ++numvalentries;
   1281         }
   1282         else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_BITRATE_KEY) != NULL)
   1283         {
   1284             // Track bitrate
   1285             // Determine the index requested. Default to all tracks
   1286             uint32 startindex = 0;
   1287             uint32 endindex = numtracks - 1;
   1288             // Check if the index parameter is present
   1289             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
   1290             if (indexstr != NULL)
   1291             {
   1292                 // Retrieve the index values
   1293                 GetIndexParamValues(indexstr, startindex, endindex);
   1294             }
   1295             // Validate the indices
   1296             if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks)
   1297             {
   1298                 continue;
   1299             }
   1300             // Increment the counter for the number of values found so far
   1301             numvalentries += (endindex + 1 - startindex);
   1302         }
   1303         else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_PAUSE_DENIED_KEY) != NULL)
   1304         {
   1305             ++numvalentries;
   1306         }
   1307         else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_MAX_BITRATE_KEY) != NULL)
   1308         {
   1309             // Track bitrate
   1310             // Determine the index requested. Default to all tracks
   1311             uint32 startindex = 0;
   1312             uint32 endindex = numtracks - 1;
   1313             // Check if the index parameter is present
   1314             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr(aKeyList[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
   1315             if (indexstr != NULL)
   1316             {
   1317                 // Retrieve the index values
   1318                 GetIndexParamValues(indexstr, startindex, endindex);
   1319             }
   1320             // Validate the indices
   1321             if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks)
   1322             {
   1323                 continue;
   1324             }
   1325 
   1326             // Increment the counter for the number of values found so far
   1327             numvalentries += (endindex + 1 - startindex);
   1328         }
   1329         else
   1330         {
   1331             /* Check the extended meta data list */
   1332             for (uint32 i = 0; i < iMetaDataInfo->iExtendedMetaDataNameVec.size(); i++)
   1333             {
   1334                 OSCL_HeapString<OsclMemAllocator> extMetaDataName =
   1335                     iMetaDataInfo->iExtendedMetaDataNameVec[i];
   1336                 if (oscl_strcmp(aKeyList[lcv].get_cstr(), extMetaDataName.get_cstr()) == 0)
   1337                 {
   1338                     /*
   1339                      * Increment the counter for the number of values found so far
   1340                      */
   1341                     ++numvalentries;
   1342                 }
   1343             }
   1344         }
   1345     }
   1346     if ((iCPMMetaDataExtensionInterface != NULL) &&
   1347             (iSessionSourceInfo->iDRMProtected  == true))
   1348     {
   1349         numvalentries +=
   1350             iCPMMetaDataExtensionInterface->GetNumMetadataValues(aKeyList);
   1351     }
   1352 
   1353     return numvalentries; // Number of elements
   1354 }
   1355 
   1356 PVMFCommandId PVMFSMFSPBaseNode::GetNodeMetadataKeys(PVMFSessionId aSessionId,
   1357         PVMFMetadataList& aKeyList,
   1358         uint32 aStartingKeyIndex,
   1359         int32 aMaxKeyEntries,
   1360         char* aQueryKeyString,
   1361         const OsclAny* aContextData)
   1362 {
   1363     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::GetNodeMetadataKeys - In"));
   1364     PVMFSMFSPBaseNodeCommand cmd;
   1365     cmd.PVMFSMFSPBaseNodeCommand::Construct(aSessionId,
   1366                                             PVMF_SMFSP_NODE_GETNODEMETADATAKEYS,
   1367                                             aKeyList,
   1368                                             aStartingKeyIndex,
   1369                                             aMaxKeyEntries,
   1370                                             aQueryKeyString,
   1371                                             aContextData);
   1372     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::GetNodeMetadataKeys - Out"));
   1373     return QueueCommandL(cmd);
   1374 }
   1375 
   1376 PVMFCommandId PVMFSMFSPBaseNode::GetNodeMetadataValues(PVMFSessionId aSessionId,
   1377         PVMFMetadataList& aKeyList,
   1378         Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList,
   1379         uint32 aStartingValueIndex,
   1380         int32 aMaxValueEntries,
   1381         const OsclAny* aContextData)
   1382 {
   1383     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::GetNodeMetadataValues - In"));
   1384     PVMFSMFSPBaseNodeCommand cmd;
   1385     cmd.PVMFSMFSPBaseNodeCommand::Construct(aSessionId,
   1386                                             PVMF_SMFSP_NODE_GETNODEMETADATAVALUES,
   1387                                             aKeyList,
   1388                                             aValueList,
   1389                                             aStartingValueIndex,
   1390                                             aMaxValueEntries,
   1391                                             aContextData);
   1392     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::GetNodeMetadataValues - Out"));
   1393     return QueueCommandL(cmd);
   1394 }
   1395 
   1396 PVMFStatus PVMFSMFSPBaseNode::ReleaseNodeMetadataKeysBase(PVMFMetadataList& aKeyList,
   1397         uint32 aStartingKeyIndex,
   1398         uint32 aEndKeyIndex)
   1399 {
   1400     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::ReleaseNodeMetadataKeys() called"));
   1401     OSCL_UNUSED_ARG(aKeyList);
   1402     OSCL_UNUSED_ARG(aStartingKeyIndex);
   1403     OSCL_UNUSED_ARG(aEndKeyIndex);
   1404     //nothing needed-- there's no dynamic allocation in this node's key list
   1405     return PVMFSuccess;
   1406 }
   1407 
   1408 PVMFStatus PVMFSMFSPBaseNode::ReleaseNodeMetadataValuesBase(Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList,
   1409         uint32 aStartingValueIndex,
   1410         uint32 aEndValueIndex)
   1411 {
   1412     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::ReleaseNodeMetadataValues() called"));
   1413 
   1414     if (aStartingValueIndex > aEndValueIndex || aValueList.size() == 0)
   1415     {
   1416         PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::ReleaseNodeMetadataValues() Invalid start/end index"));
   1417         return PVMFErrArgument;
   1418     }
   1419 
   1420     //Only CPM related metadata is retrived. Then this one should be 0.
   1421     if (iPVMFStreamingManagerNodeMetadataValueCount == 0) return PVMFSuccess;
   1422 
   1423     //To remove madatada related with un-drm value
   1424     aEndValueIndex = iPVMFStreamingManagerNodeMetadataValueCount - 1;
   1425     if (aEndValueIndex >= aValueList.size())
   1426     {
   1427         aEndValueIndex = aValueList.size() - 1;
   1428     }
   1429 
   1430     for (uint32 i = aStartingValueIndex; i <= aEndValueIndex; i++)
   1431     {
   1432         if (aValueList[i].key != NULL)
   1433         {
   1434             switch (GetValTypeFromKeyString(aValueList[i].key))
   1435             {
   1436                 case PVMI_KVPVALTYPE_WCHARPTR:
   1437                     if (aValueList[i].value.pWChar_value != NULL)
   1438                     {
   1439                         OSCL_ARRAY_DELETE(aValueList[i].value.pWChar_value);
   1440                         aValueList[i].value.pWChar_value = NULL;
   1441                     }
   1442                     break;
   1443 
   1444                 case PVMI_KVPVALTYPE_CHARPTR:
   1445                     if (aValueList[i].value.pChar_value != NULL)
   1446                     {
   1447                         OSCL_ARRAY_DELETE(aValueList[i].value.pChar_value);
   1448                         aValueList[i].value.pChar_value = NULL;
   1449                     }
   1450                     break;
   1451 
   1452                 case PVMI_KVPVALTYPE_UINT8PTR:
   1453                     if (aValueList[i].value.pUint8_value != NULL)
   1454                     {
   1455                         OSCL_ARRAY_DELETE(aValueList[i].value.pUint8_value);
   1456                         aValueList[i].value.pUint8_value = NULL;
   1457                     }
   1458                     break;
   1459 
   1460                 case PVMI_KVPVALTYPE_UINT32:
   1461                 case PVMI_KVPVALTYPE_FLOAT:
   1462                 case PVMI_KVPVALTYPE_BOOL:
   1463                     // No need to free memory for this valtype
   1464                     break;
   1465 
   1466                 case PVMI_KVPVALTYPE_KSV:
   1467                 {
   1468                     //PVMFSTREAMINGMGRNODE_GRAPHICS_KEY value need to be freed in derived class (cos alocation also took there)
   1469                 }
   1470                 break;
   1471 
   1472                 default:
   1473                     // Should not get a value that wasn't created from this node
   1474                     OSCL_ASSERT(false);
   1475                     break;
   1476             }
   1477 
   1478             OSCL_ARRAY_DELETE(aValueList[i].key);
   1479             aValueList[i].key = NULL;
   1480         }
   1481     }
   1482 
   1483     return PVMFSuccess;
   1484 }
   1485 
   1486 ///////////////////////////////////////////////////////////////////////////////
   1487 //Implementation of virtuals declared in PVMFNodeErrorEventObserver
   1488 ///////////////////////////////////////////////////////////////////////////////
   1489 void PVMFSMFSPBaseNode::HandleNodeErrorEvent(const PVMFAsyncEvent& aEvent)
   1490 {
   1491     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::HandleNodeErrorEvent - In iInterfaceState[%d]", iInterfaceState));
   1492     //If node is already in error state, then dont propagate the err event up and ignore it
   1493     if (EPVMFNodeError == iInterfaceState)
   1494     {
   1495         return;
   1496     }
   1497     //check if the err event is fatal err event (requires err handling to be done)
   1498     //if yes, then move the node in err state and propagate the err event up ONLY after completion of err handling
   1499     if (IsFatalErrorEvent(aEvent.GetEventType()))
   1500     {
   1501         PVMF_SM_FSP_BASE_LOGDEBUG((0, "PVMFSMFSPBaseNode::HandleNodeErrorEvent - Fatal Error"));
   1502         //Do we have a pending command in current command Q/Cancel Q
   1503 
   1504         if (EPVMFNodeError != iInterfaceState)
   1505         {
   1506             SetState(EPVMFNodeError);
   1507             iChildNodeErrHandler->InitiateErrorHandling(aEvent);
   1508         }
   1509     }
   1510     return;
   1511 }
   1512 
   1513 ///////////////////////////////////////////////////////////////////////////////
   1514 //Implementation of some asyn functions of PVMFNodeInterface serviced in the
   1515 //base class
   1516 ///////////////////////////////////////////////////////////////////////////////
   1517 void PVMFSMFSPBaseNode::DoCancelAllCommands(PVMFSMFSPBaseNodeCommand& aCmd)
   1518 {
   1519     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::DoCancelAllCommands In"));
   1520 
   1521     //first cancel the current command if any
   1522     if (iCurrentCommand.size() > 0)
   1523     {
   1524         PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoCancelAllCommands iCurrentCommand.size()>0"));
   1525         {
   1526             //We wipe all node cmd states, since we are no longer going to care about cmd completes
   1527             //coming from nodes for anything other than cancelall
   1528             ResetNodeContainerCmdState();
   1529             for (uint32 i = 0; i < iFSPChildNodeContainerVec.size(); i++)
   1530             {
   1531                 PVMFSMFSPCommandContext* internalCmd = RequestNewInternalCmd();
   1532                 if (internalCmd != NULL)
   1533                 {
   1534                     internalCmd->cmd =
   1535                         iFSPChildNodeContainerVec[i].commandStartOffset +
   1536                         PVMF_SM_FSP_NODE_INTERNAL_CANCEL_ALL_OFFSET;
   1537                     internalCmd->parentCmd = PVMF_SMFSP_NODE_CANCELALLCOMMANDS;
   1538                     OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
   1539                     PVMFNodeInterface* iNode = iFSPChildNodeContainerVec[i].iNode;
   1540                     iNode->CancelAllCommands(iFSPChildNodeContainerVec[i].iSessionId, cmdContextData);
   1541                     iFSPChildNodeContainerVec[i].iNodeCmdState = PVMFSMFSP_NODE_CMD_CANCEL_PENDING;
   1542                 }
   1543                 else
   1544                 {
   1545                     PVMF_SM_FSP_BASE_LOGERR((0, "PVMFStreamingManagerNode:DoCancelAllCommands:RequestNewInternalCmd - Failed"));
   1546                     CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
   1547                     return;
   1548                 }
   1549             }
   1550         }
   1551         MoveCmdToCancelQueue(aCmd);
   1552     }
   1553     else
   1554     {
   1555         //Assumptions:
   1556         //Command in front of input Q is cancel command.
   1557         //None of other commands in the input queue is hipri cmd, and hence are store in the order of their cmd id's
   1558         //All commands in the input Q with command id < command id of the cancel command need to be completed
   1559         //with cancelled status.
   1560         const int32 cancelCmdId = iInputCommands.front().iId;
   1561         const int32 inputCmndsSz = iInputCommands.size();
   1562         for (int ii = inputCmndsSz - 1; ii > 0 ; ii--) //we dont want to process element at index 0 (being cancel command)
   1563         {
   1564             if (iInputCommands[ii].iId < cancelCmdId)
   1565             {
   1566                 if (IsInternalCmd(iInputCommands[ii].iCmd))
   1567                 {
   1568                     InternalCommandComplete(iInputCommands, iInputCommands[ii], PVMFErrCancelled);
   1569                 }
   1570                 else
   1571                 {
   1572                     CommandComplete(iInputCommands, iInputCommands[ii], PVMFErrCancelled);
   1573                 }
   1574             }
   1575         }
   1576         CommandComplete(iInputCommands, aCmd, PVMFSuccess); //complete the cancel all command
   1577     }
   1578 
   1579     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::DoCancelAllCommands Out"));
   1580 }
   1581 
   1582 void PVMFSMFSPBaseNode::DoCancelAllPendingCommands(PVMFSMFSPBaseNodeCommand& aCmd)
   1583 {
   1584     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::DoCancelAllPendingCommands In"));
   1585     //First cancel the current command if any...
   1586     if (iCurrentCommand.size() > 0)
   1587     {
   1588         PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::DoCancelAllPendingCommands iCurrentCommand.size()>0"));
   1589         {
   1590             for (uint32 i = 0; i < iFSPChildNodeContainerVec.size(); i++)
   1591             {
   1592                 if (iFSPChildNodeContainerVec[i].iNodeCmdState == PVMFSMFSP_NODE_CMD_PENDING)
   1593                 {
   1594                     PVMFSMFSPCommandContext* internalCmd = RequestNewInternalCmd();
   1595                     if (internalCmd != NULL)
   1596                     {
   1597                         internalCmd->cmd =
   1598                             iFSPChildNodeContainerVec[i].commandStartOffset +
   1599                             PVMF_SM_FSP_NODE_INTERNAL_CANCEL_ALL_OFFSET;
   1600                         internalCmd->parentCmd = PVMF_SMFSP_NODE_CANCELALLCOMMANDS;
   1601                         OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
   1602                         PVMFNodeInterface* iNode = iFSPChildNodeContainerVec[i].iNode;
   1603                         iNode->CancelAllCommands(iFSPChildNodeContainerVec[i].iSessionId, cmdContextData);
   1604                         iFSPChildNodeContainerVec[i].iNodeCmdState = PVMFSMFSP_NODE_CMD_CANCEL_PENDING;
   1605                     }
   1606                     else
   1607                     {
   1608                         PVMF_SM_FSP_BASE_LOGERR((0, "PVMFStreamingManagerNode:DoCancelAllPendingCommands:RequestNewInternalCmd - Failed"));
   1609                         CommandComplete(iErrHandlingCommandQ, aCmd, PVMFErrNoMemory);
   1610                         return;
   1611                     }
   1612                 }
   1613             }
   1614         }
   1615         MoveErrHandlingCmdToCurErrHandlingQ(aCmd);
   1616     }
   1617     else
   1618     {
   1619         iChildNodeErrHandler->ErrHandlingCommandComplete(iErrHandlingCommandQ, aCmd, PVMFSuccess);
   1620     }
   1621     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::DoCancelAllPendingCommands Out"));
   1622 }
   1623 
   1624 void PVMFSMFSPBaseNode::DoResetDueToErr(PVMFSMFSPBaseNodeCommand& aCmd)
   1625 {
   1626     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::DoResetDueToErr - In"));
   1627     /* this node allows a reset from any state, as long as the AO is in scheduler queue */
   1628     OSCL_ASSERT(IsAdded());
   1629     /*
   1630      * Reset for streaming manager cannot be completed unless
   1631      * Reset for all the children nodes are complete
   1632      */
   1633     if ((iCPM) && (iSessionSourceInfo->iDRMProtected == true) && iDRMResetPending == false)
   1634     {
   1635         iDRMResetPending = true;
   1636         SendUsageComplete();
   1637     }
   1638 
   1639 
   1640     PVMFSMFSPChildNodeContainerVector::iterator it;
   1641     for (it = iFSPChildNodeContainerVec.begin(); it != iFSPChildNodeContainerVec.end(); it++)
   1642     {
   1643         PVMFSMFSPCommandContext* internalCmd = RequestNewInternalCmd();
   1644         if (internalCmd != NULL)
   1645         {
   1646             internalCmd->cmd =
   1647                 it->commandStartOffset +
   1648                 PVMF_SM_FSP_NODE_INTERNAL_RESET_CMD_OFFSET;
   1649             internalCmd->parentCmd = aCmd.iCmd;
   1650             OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
   1651             PVMFNodeInterface* iNode = it->iNode;
   1652             iNode->Reset(it->iSessionId, cmdContextData);
   1653             it->iNodeCmdState = PVMFSMFSP_NODE_CMD_PENDING;
   1654         }
   1655         else
   1656         {
   1657             PVMF_SM_FSP_BASE_LOGERR((0, "PVMFSMFSPBaseNode:DoReset:RequestNewInternalCmd - Failed"));
   1658             CommandComplete(iErrHandlingCommandQ, aCmd, PVMFErrNoMemory);
   1659             return;
   1660         }
   1661     }
   1662     MoveErrHandlingCmdToCurErrHandlingQ(aCmd);
   1663 
   1664     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::DoResetDueToErr - Out"));
   1665 }
   1666 
   1667 void PVMFSMFSPBaseNode::CompleteChildNodesCmdCancellation()
   1668 {
   1669     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::CompleteCancelAll - In"));
   1670     if (CheckChildrenNodesCancelAll())
   1671     {
   1672         if (PVMF_SMFSP_NODE_CANCELALLCOMMANDS == iCancelCommand.front().iCmd)
   1673         {
   1674             /*
   1675              * CancelAllCommands is issued by upper layer
   1676              */
   1677             if (!iCurrentCommand.empty())
   1678             {
   1679                 if (IsInternalCmd(iCurrentCommand.front().iCmd) == false)
   1680                 {
   1681                     CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrCancelled);
   1682                 }
   1683                 else
   1684                 {
   1685                     InternalCommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrCancelled);
   1686                 }
   1687             }
   1688 
   1689             //Assumptions:
   1690             //Command in front of cancel Q is cancelall command.
   1691             //None of commands in the input queue is hipri cmd, and hence are store in the order of their cmd id's
   1692             //All commands in the input Q with command id < command id of the cancel command need to be completed
   1693             //with cancelled status.
   1694             const int32 cancelCmdId = iCancelCommand.front().iId;
   1695             const int32 inputCmndsSz = iInputCommands.size();
   1696             for (int ii = inputCmndsSz - 1; ii >= 0 ; ii--)
   1697             {
   1698                 if (iInputCommands[ii].iId < cancelCmdId)
   1699                 {
   1700                     if (IsInternalCmd(iInputCommands[ii].iCmd))
   1701                     {
   1702                         InternalCommandComplete(iInputCommands, iInputCommands[ii], PVMFErrCancelled);
   1703                     }
   1704                     else
   1705                     {
   1706                         CommandComplete(iInputCommands, iInputCommands[ii], PVMFErrCancelled);
   1707                     }
   1708                 }
   1709             }
   1710 
   1711             /* finally send command complete for the cancel all command */
   1712             PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::CompleteCancelAll - CancelAllCommands complete"));
   1713             CommandComplete(iCancelCommand,
   1714                             iCancelCommand.front(),
   1715                             PVMFSuccess);
   1716         }
   1717         else if (PVMF_SMFSP_NODE_CANCELCOMMAND == iCancelCommand.front().iCmd)
   1718         {
   1719             if (!iCurrentCommand.empty())
   1720             {
   1721                 if (IsInternalCmd(iCurrentCommand.front().iCmd) == false)
   1722                 {
   1723                     CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrCancelled);
   1724                 }
   1725                 else
   1726                 {
   1727                     InternalCommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrCancelled);
   1728                 }
   1729             }
   1730             /* end command complete for the cancel all command */
   1731             PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::CompleteCancelAll - CancelCmd complete"));
   1732             CommandComplete(iCancelCommand,
   1733                             iCancelCommand.front(),
   1734                             PVMFSuccess);
   1735         }
   1736     }
   1737 
   1738     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFStreamingManagerNode::CompleteCancelAll - Out"));
   1739     return;
   1740 }
   1741 
   1742 bool PVMFSMFSPBaseNode::CheckChildrenNodesCancelAll()
   1743 {
   1744     for (uint32 i = 0; i < iFSPChildNodeContainerVec.size(); i++)
   1745     {
   1746         if (iFSPChildNodeContainerVec[i].iNodeCmdState != PVMFSMFSP_NODE_CMD_IDLE)
   1747         {
   1748             return false;
   1749         }
   1750     }
   1751     return true;
   1752 }
   1753 
   1754 void PVMFSMFSPBaseNode::DoCancelCommand(PVMFSMFSPBaseNodeCommand& aCmd)
   1755 {
   1756     //todo:need to implement
   1757     OSCL_UNUSED_ARG(aCmd);
   1758     OSCL_ASSERT(false);
   1759 }
   1760 
   1761 /**
   1762  * Called by the command handler AO to do the node Reset.
   1763  */
   1764 void PVMFSMFSPBaseNode::DoReset(PVMFSMFSPBaseNodeCommand& aCmd)
   1765 {
   1766     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::DoReset - In"));
   1767     /* this node allows a reset from any state, as long as the AO is in scheduler queue */
   1768     OSCL_ASSERT(IsAdded());
   1769     /*
   1770      * Reset for streaming manager cannot be completed unless
   1771      * Reset for all the children nodes are complete
   1772      */
   1773     if ((iCPM) && (iSessionSourceInfo->iDRMProtected == true) && iDRMResetPending == false)
   1774     {
   1775         iDRMResetPending = true;
   1776         SendUsageComplete();
   1777     }
   1778 
   1779     bool childNodeResetPending = false;
   1780     PVMFSMFSPChildNodeContainerVector::iterator it;
   1781     for (it = iFSPChildNodeContainerVec.begin(); it != iFSPChildNodeContainerVec.end(); it++)
   1782     {
   1783         if (EPVMFNodeCreated != it->iNode->GetState())
   1784         {
   1785             PVMFSMFSPCommandContext* internalCmd = RequestNewInternalCmd();
   1786             if (internalCmd != NULL)
   1787             {
   1788                 internalCmd->cmd =
   1789                     it->commandStartOffset +
   1790                     PVMF_SM_FSP_NODE_INTERNAL_RESET_CMD_OFFSET;
   1791                 internalCmd->parentCmd = aCmd.iCmd;
   1792                 OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
   1793                 PVMFNodeInterface* iNode = it->iNode;
   1794                 iNode->Reset(it->iSessionId, cmdContextData);
   1795                 childNodeResetPending = true;
   1796                 it->iNodeCmdState = PVMFSMFSP_NODE_CMD_PENDING;
   1797             }
   1798             else
   1799             {
   1800                 PVMF_SM_FSP_BASE_LOGERR((0, "PVMFSMFSPBaseNode:DoReset:RequestNewInternalCmd - Failed"));
   1801                 CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
   1802                 return;
   1803             }
   1804         }
   1805     }
   1806 
   1807     if (iDRMResetPending || childNodeResetPending)
   1808         MoveCmdToCurrentQueue(aCmd);
   1809     else
   1810     {
   1811         PVMFStatus status = ThreadLogoff();
   1812         CommandComplete(iInputCommands, aCmd, status);
   1813     }
   1814 
   1815     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::DoReset - Out"));
   1816 }
   1817 
   1818 
   1819 
   1820 void PVMFSMFSPBaseNode::CompleteReset()
   1821 {
   1822     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::CompleteReset - In"));
   1823     if (CheckChildrenNodesReset() && iDRMResetPending == false)
   1824     {
   1825         ResetNodeContainerCmdState();
   1826         if (!iCurrentCommand.empty() && iCancelCommand.empty())
   1827         {
   1828             /* Indicates that the init for Children Nodes was successfull */
   1829             /* At protected clip, Reset CPM also was successfull */
   1830             PVMFSMFSPBaseNodeCommand& aCmd = iCurrentCommand.front();
   1831             if (aCmd.iCmd == PVMF_SMFSP_NODE_RESET)
   1832             {
   1833                 /* logoff & go back to Created state */
   1834                 SetState(EPVMFNodeIdle);
   1835                 /* Reset Params */
   1836                 ResetNodeParams();
   1837                 CommandComplete(iCurrentCommand, aCmd, PVMFSuccess);
   1838             }
   1839         }
   1840     }
   1841     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::CompleteReset - Out"));
   1842     return;
   1843 }
   1844 
   1845 void PVMFSMFSPBaseNode::CompleteResetDueToErr()
   1846 {
   1847     ResetNodeContainerCmdState();
   1848     //check the state of the child nodes
   1849     bool childNodesResetSucccessful = true;
   1850 
   1851     for (uint32 i = 0; i < iFSPChildNodeContainerVec.size(); i++)
   1852     {
   1853         TPVMFNodeInterfaceState childNodeState = iFSPChildNodeContainerVec[i].iNode->GetState();
   1854         if ((childNodeState != EPVMFNodeIdle) && (childNodeState != EPVMFNodeCreated))
   1855         {
   1856             childNodesResetSucccessful = false;
   1857             break;
   1858         }
   1859     }
   1860 
   1861     if (childNodesResetSucccessful)
   1862     {
   1863         SetState(EPVMFNodeIdle);
   1864         /* Reset Params */
   1865         ResetNodeParams();
   1866     }
   1867     else
   1868     {
   1869         OSCL_ASSERT(false);
   1870     }
   1871 }
   1872 
   1873 bool PVMFSMFSPBaseNode::CheckChildrenNodesReset()
   1874 {
   1875     for (uint32 i = 0; i < iFSPChildNodeContainerVec.size(); i++)
   1876     {
   1877         if (iFSPChildNodeContainerVec[i].iNodeCmdState != PVMFSMFSP_NODE_CMD_IDLE)
   1878         {
   1879             return false;
   1880         }
   1881     }
   1882     return true;
   1883 }
   1884 
   1885 void PVMFSMFSPBaseNode::DoFlush(PVMFSMFSPBaseNodeCommand& aCmd)
   1886 {
   1887     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::DoFlush - In"));
   1888     switch (iInterfaceState)
   1889     {
   1890         case EPVMFNodeStarted:
   1891         case EPVMFNodePaused:
   1892         {
   1893             /*
   1894              * Flush for streaming manager cannot be completed unless
   1895              * Flush for all the children nodes are complete
   1896              */
   1897             PVMFSMFSPChildNodeContainerVector::iterator it;
   1898             for (it = iFSPChildNodeContainerVec.begin(); it != iFSPChildNodeContainerVec.end(); it++)
   1899             {
   1900                 PVMFSMFSPCommandContext* internalCmd = RequestNewInternalCmd();
   1901                 if (internalCmd != NULL)
   1902                 {
   1903                     internalCmd->cmd =
   1904                         it->commandStartOffset +
   1905                         PVMF_SM_FSP_NODE_INTERNAL_FLUSH_CMD_OFFSET;
   1906                     internalCmd->parentCmd = aCmd.iCmd;
   1907 
   1908                     OsclAny *cmdContextData = OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
   1909 
   1910                     PVMFNodeInterface* iNode = it->iNode;
   1911 
   1912                     iNode->Flush(it->iSessionId, cmdContextData);
   1913                     it->iNodeCmdState = PVMFSMFSP_NODE_CMD_PENDING;
   1914                 }
   1915                 else
   1916                 {
   1917                     PVMF_SM_FSP_BASE_LOGERR((0, "StreamingManagerNode:DoFlush:RequestNewInternalCmd - Failed"));
   1918                     CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
   1919                     return;
   1920                 }
   1921             }
   1922             MoveCmdToCurrentQueue(aCmd);
   1923             /*
   1924              * Notify all ports to suspend their input - TBD
   1925              */
   1926             /*
   1927              * If the node is not running we need to wakeup the
   1928              * AO to further complete the flush, which means all
   1929              * port activity needs to be completed.
   1930              */
   1931             if (IsAdded())
   1932             {
   1933                 RunIfNotReady();
   1934             }
   1935         }
   1936         break;
   1937 
   1938         default:
   1939             CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
   1940             break;
   1941     }
   1942     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::DoFlush - Out"));
   1943 }
   1944 
   1945 void PVMFSMFSPBaseNode::CompleteFlush()
   1946 {
   1947     /*
   1948     * If the node is not running we need to wakeup the
   1949     * AO to further complete the flush, which means all
   1950     * port activity needs to be completed.
   1951     */
   1952     if (iInterfaceState != EPVMFNodeStarted)
   1953     {
   1954         if (IsAdded())
   1955         {
   1956             RunIfNotReady();
   1957         }
   1958     }
   1959     return;
   1960 }
   1961 
   1962 bool PVMFSMFSPBaseNode::CheckChildrenNodesFlush()
   1963 {
   1964     for (uint32 i = 0; i < iFSPChildNodeContainerVec.size(); i++)
   1965     {
   1966         if (iFSPChildNodeContainerVec[i].iNodeCmdState != PVMFSMFSP_NODE_CMD_IDLE)
   1967         {
   1968             return false;
   1969         }
   1970     }
   1971     return true;
   1972 }
   1973 /**
   1974 ///////////////////////////////////////////////////////////////////////////////
   1975 //Implementation of virtuals declared in PVMFSMFSPBaseNode
   1976 ///////////////////////////////////////////////////////////////////////////////
   1977 */
   1978 
   1979 void PVMFSMFSPBaseNode::ReportInfoEvent(PVMFEventType aEventType,
   1980                                         OsclAny* aEventData,
   1981                                         PVUuid* aEventUUID,
   1982                                         int32* aEventCode)
   1983 
   1984 {
   1985     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode::NodeInfoEvent Type %d Data %d"
   1986                                     , aEventType, aEventData));
   1987 
   1988     if (aEventUUID && aEventCode)
   1989     {
   1990         PVMFBasicErrorInfoMessage* eventmsg =
   1991             OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
   1992         PVMFAsyncEvent asyncevent(PVMFInfoEvent,
   1993                                   aEventType,
   1994                                   NULL,
   1995                                   OSCL_STATIC_CAST(PVInterface*, eventmsg),
   1996                                   aEventData,
   1997                                   NULL,
   1998                                   0);
   1999         PVMFNodeInterface::ReportInfoEvent(asyncevent);
   2000         eventmsg->removeRef();
   2001     }
   2002     else
   2003     {
   2004         PVMFNodeInterface::ReportInfoEvent(aEventType, aEventData);
   2005     }
   2006 }
   2007 
   2008 
   2009 void PVMFSMFSPBaseNode::CommandComplete(PVMFFSPNodeCmdQ& aCmdQ,
   2010                                         PVMFSMFSPBaseNodeCommand& aCmd,
   2011                                         PVMFStatus aStatus,
   2012                                         OsclAny* aEventData,
   2013                                         PVUuid* aEventUUID,
   2014                                         int32* aEventCode,
   2015                                         PVInterface* aExtMsg,
   2016                                         uint32 aEventDataLen)
   2017 {
   2018     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "StreamingManagerNode:CommandComplete Id %d Cmd %d Status %d Context %d Data %d"
   2019                                     , aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));
   2020 
   2021     PVInterface* extif = NULL;
   2022     PVMFBasicErrorInfoMessage* errormsg = NULL;
   2023     if (aExtMsg)
   2024     {
   2025         extif = aExtMsg;
   2026     }
   2027     else if (aEventUUID && aEventCode)
   2028     {
   2029         errormsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
   2030         extif = OSCL_STATIC_CAST(PVInterface*, errormsg);
   2031     }
   2032 
   2033     /* create response */
   2034     PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, extif, aEventData);
   2035     if (aEventDataLen != 0)
   2036     {
   2037         resp.SetEventDataLen(aEventDataLen);
   2038     }
   2039 
   2040     if (ErrorHandlingRequired(aStatus))
   2041     {
   2042         HandleError(resp);
   2043         if (errormsg)
   2044         {
   2045             errormsg->removeRef();
   2046         }
   2047         return;
   2048     }
   2049 
   2050     PVMFSessionId session = aCmd.iSession;
   2051 
   2052     /* Erase the command from the queue */
   2053     aCmdQ.Erase(&aCmd);
   2054 
   2055     /* Report completion to the session observer */
   2056     ReportCmdCompleteEvent(session, resp);
   2057 
   2058     if (errormsg)
   2059     {
   2060         errormsg->removeRef();
   2061     }
   2062 
   2063     /* Reschedule AO if input command queue is not empty */
   2064     if (!iInputCommands.empty() && IsAdded())
   2065     {
   2066         if (IsAdded())
   2067         {
   2068             RunIfNotReady();
   2069         }
   2070     }
   2071 }
   2072 
   2073 void PVMFSMFSPBaseNode::InternalCommandComplete(PVMFFSPNodeCmdQ& aCmdQ,
   2074         PVMFSMFSPBaseNodeCommand& aCmd,
   2075         PVMFStatus aStatus,
   2076         OsclAny* aEventData,
   2077         PVUuid* aEventUUID,
   2078         int32* aEventCode,
   2079         PVInterface* aExtMsg)
   2080 {
   2081     PVMF_SM_FSP_BASE_LOGSTACKTRACE((0, "PVMFSMFSPBaseNode:CommandComplete Id %d Cmd %d Status %d Context %x"
   2082                                     , aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext));
   2083 
   2084     PVInterface* extif = NULL;
   2085     PVMFBasicErrorInfoMessage* errormsg = NULL;
   2086     if (aExtMsg)
   2087     {
   2088         extif = aExtMsg;
   2089     }
   2090     else if (aEventUUID && aEventCode)
   2091     {
   2092         errormsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
   2093         extif = OSCL_STATIC_CAST(PVInterface*, errormsg);
   2094     }
   2095 
   2096     /* create response */
   2097     PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, extif, aEventData);
   2098 
   2099     if (ErrorHandlingRequired(aStatus))
   2100     {
   2101         HandleError(resp);
   2102         if (errormsg)
   2103         {
   2104             errormsg->removeRef();
   2105         }
   2106         return;
   2107     }
   2108 
   2109 
   2110     /* Erase the command from the queue */
   2111     aCmdQ.Erase(&aCmd);
   2112 
   2113     /* Reschedule AO if input command queue is not empty */
   2114     if (!iInputCommands.empty() && IsAdded())
   2115     {
   2116         if (IsAdded())
   2117         {
   2118             RunIfNotReady();
   2119         }
   2120     }
   2121 
   2122 }
   2123 
   2124 
   2125 
   2126 
   2127 /**
   2128 //////////////////////////////////////////////////
   2129 // Utility functions
   2130 //////////////////////////////////////////////////
   2131 */
   2132 
   2133 bool PVMFSMFSPBaseNode::IsInternalCmd(PVMFCommandId aId)
   2134 {
   2135     if ((PVMF_SMFSP_NODE_CONSTRUCT_SESSION == aId) || (PVMF_SMFSP_NODE_CANCEL_DUE_TO_ERROR == aId) ||
   2136             IsFSPInternalCmd(aId))
   2137     {
   2138         return true;
   2139     }
   2140     return false;
   2141 }
   2142 
   2143 bool PVMFSMFSPBaseNode::IsFatalErrorEvent(const PVMFEventType& event)
   2144 {
   2145     bool retval = false;
   2146     switch (event)
   2147     {
   2148         case PVMFErrCorrupt:
   2149         case PVMFErrOverflow:
   2150         case PVMFErrResource:
   2151         case PVMFErrProcessing:
   2152         case PVMFErrUnderflow:
   2153         case PVMFErrNoResources:
   2154         case PVMFErrResourceConfiguration:
   2155         case PVMFErrTimeout:
   2156         case PVMFErrNoMemory:
   2157         case PVMFFailure:
   2158             retval = true;
   2159             break;
   2160         default:
   2161             retval = false;
   2162     }
   2163     return retval;
   2164 }
   2165 
   2166 bool PVMFSMFSPBaseNode::ErrorHandlingRequired(PVMFStatus aStatus)
   2167 {
   2168     if ((EPVMFNodeIdle != iInterfaceState) && (PVMFSuccess != aStatus) && (PVMFErrCancelled != aStatus) && (PVMFErrLicenseRequired != aStatus) && (PVMFErrNotSupported != aStatus) && (PVMFErrArgument != aStatus))
   2169     {
   2170         return true;
   2171     }
   2172     return false;
   2173 }
   2174 
   2175 PVMFStatus PVMFSMFSPBaseNode::GetIndexParamValues(char* aString, uint32& aStartIndex, uint32& aEndIndex)
   2176 {
   2177     // This parses a string of the form "index=N1...N2" and extracts the integers N1 and N2.
   2178     // If string is of the format "index=N1" then N2=N1
   2179 
   2180     if (aString == NULL)
   2181     {
   2182         return PVMFErrArgument;
   2183     }
   2184 
   2185     // Go to end of "index="
   2186     char* n1string = aString + 6;
   2187 
   2188     PV_atoi(n1string, 'd', oscl_strlen(n1string), aStartIndex);
   2189 
   2190     char* n2string = OSCL_CONST_CAST(char*, oscl_strstr(aString, _STRLIT_CHAR("...")));
   2191 
   2192     if (n2string == NULL)
   2193     {
   2194         aEndIndex = aStartIndex;
   2195     }
   2196     else
   2197     {
   2198         // Go to end of "index=N1..."
   2199         n2string += 3;
   2200 
   2201         PV_atoi(n2string, 'd', oscl_strlen(n2string), aEndIndex);
   2202     }
   2203 
   2204     return PVMFSuccess;
   2205 }
   2206 
   2207 /**
   2208 //A routine to tell if a flush operation is in progress.
   2209 */
   2210 bool PVMFSMFSPBaseNode::FlushPending()
   2211 {
   2212     if ((iCurrentCommand.size() > 0) &&
   2213             (iCurrentCommand.front().iCmd == PVMF_SMFSP_NODE_FLUSH) &&
   2214             (CheckChildrenNodesFlush() == false))
   2215     {
   2216         return true;
   2217     }
   2218     return false;
   2219 }
   2220 
   2221 ///////////////////////////////////////////////////////////////////////////////
   2222 ///////////////////////////////////////////////////////////////////////////////
   2223 PVMFSMFSPCommandContext* PVMFSMFSPBaseNode::RequestNewInternalCmd()
   2224 {
   2225     int32 i = 0;
   2226     /* Search for the next free node command in the pool */
   2227     while (i < PVMF_SMFSP_INTERNAL_CMDQ_SIZE)
   2228     {
   2229         if (iInternalCmdPool[i].oFree)
   2230         {
   2231             iInternalCmdPool[i].oFree = false;
   2232             return &(iInternalCmdPool[i]);
   2233         }
   2234         ++i;
   2235     }
   2236     /* Free one not found so return NULL */
   2237     return NULL;
   2238 }
   2239 
   2240 void PVMFSMFSPBaseNode::ResetNodeContainerCmdState()
   2241 {
   2242     for (uint32 i = 0; i < iFSPChildNodeContainerVec.size(); i++)
   2243     {
   2244         iFSPChildNodeContainerVec[i].iNodeCmdState = PVMFSMFSP_NODE_CMD_IDLE;
   2245     }
   2246 }
   2247 
   2248 PVMFSMFSPChildNodeContainer* PVMFSMFSPBaseNode::getChildNodeContainer(int32 tag)
   2249 {
   2250     for (uint32 i = 0; i < iFSPChildNodeContainerVec.size(); i++)
   2251     {
   2252         if (iFSPChildNodeContainerVec[i].iNodeTag == tag)
   2253         {
   2254             return (&(iFSPChildNodeContainerVec[i]));
   2255         }
   2256     }
   2257     return NULL;
   2258 }
   2259 
   2260 ///////////////////////////////////////////////////////////////////////////////
   2261 //Command Q processing functions
   2262 ///////////////////////////////////////////////////////////////////////////////
   2263 //For processing command Queues
   2264 void PVMFSMFSPBaseNode::MoveCmdToCurrentQueue(PVMFSMFSPBaseNodeCommand& aCmd)
   2265 {
   2266     int32 err;
   2267     OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
   2268     if (err != OsclErrNone)
   2269     {
   2270         CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
   2271         return;
   2272     }
   2273     iInputCommands.Erase(&aCmd);
   2274     return;
   2275 }
   2276 
   2277 void PVMFSMFSPBaseNode::MoveCmdToCancelQueue(PVMFSMFSPBaseNodeCommand& aCmd)
   2278 {
   2279     /*
   2280      * note: the StoreL cannot fail since the queue is never more than 1 deep
   2281      * and we reserved space.
   2282      */
   2283     iCancelCommand.StoreL(aCmd);
   2284     iInputCommands.Erase(&aCmd);
   2285     return;
   2286 }
   2287 
   2288 void PVMFSMFSPBaseNode::MoveErrHandlingCmdToCurErrHandlingQ(PVMFSMFSPBaseNodeCommand& aCmd)
   2289 {
   2290     iCurrErrHandlingCommand.StoreL(aCmd);
   2291     iErrHandlingCommandQ.Erase(&aCmd);
   2292     return;
   2293 }
   2294 
   2295 /**
   2296  * This routine is called by various command APIs to queue an
   2297  * asynchronous command for processing by the command handler AO.
   2298  * This function may leave if the command can't be queued due to
   2299  * memory allocation failure.
   2300  */
   2301 PVMFCommandId PVMFSMFSPBaseNode::QueueCommandL(PVMFSMFSPBaseNodeCommand& aCmd)
   2302 {
   2303     PVMFCommandId id = -1;
   2304     id = iInputCommands.AddL(aCmd);
   2305     PVMF_SM_FSP_BASE_LOGCMDSEQ((0, "Added command [%d] to Q, PVMFCommandId returned [%d]", aCmd.iCmd, id));
   2306     if (IsAdded())
   2307     {
   2308         //wakeup the AO
   2309         RunIfNotReady();
   2310     }
   2311     else
   2312     {
   2313         PVMF_SM_FSP_BASE_LOGERR((0, "AO not in queueu while attempting to add command [%d] to Q, PVMFCommandId returned [%d]", aCmd.iCmd, id));
   2314     }
   2315     return id;
   2316 }
   2317 
   2318 /**
   2319  * This routine is called by various command APIs to queue an
   2320  * asynchronous command for processing by the command handler AO.
   2321  * This function may leave if the command can't be queued due to
   2322  * memory allocation failure.
   2323  */
   2324 PVMFCommandId PVMFSMFSPBaseNode::QueueErrHandlingCommandL(PVMFSMFSPBaseNodeCommand& aCmd)
   2325 {
   2326     PVMFCommandId id = -1;
   2327     id = iErrHandlingCommandQ.AddL(aCmd);
   2328     PVMF_SM_FSP_BASE_LOGCMDSEQ((0, "Added command [%d] to Q, PVMFCommandId returned [%d]", aCmd.iCmd, id));
   2329     if (IsAdded())
   2330     {
   2331         //wakeup the AO
   2332         RunIfNotReady();
   2333     }
   2334     else
   2335     {
   2336         PVMF_SM_FSP_BASE_LOGERR((0, "AO not in queueu while attempting to add command [%d] to Q, PVMFCommandId returned [%d]", aCmd.iCmd, id));
   2337     }
   2338     return id;
   2339 }
   2340 
   2341 ///////////////////////////////////////////////////////////////////////////////
   2342 //Command Completion/Error event notification/Info event notification functions
   2343 ///////////////////////////////////////////////////////////////////////////////
   2344 void PVMFSMFSPBaseNodeCommand::Copy(const PVMFGenericNodeCommand<OsclMemAllocator>& aCmd)
   2345 {
   2346     PVMFGenericNodeCommand<OsclMemAllocator>::Copy(aCmd);
   2347     switch (aCmd.iCmd)
   2348     {
   2349         case PVMF_SMFSP_NODE_GETNODEMETADATAKEYS:
   2350             if (aCmd.iParam4)
   2351             {
   2352                 /* copy the allocated string */
   2353                 OSCL_HeapString<OsclMemAllocator>* aStr =
   2354                     (OSCL_HeapString<OsclMemAllocator>*)aCmd.iParam4;
   2355                 Oscl_TAlloc<OSCL_HeapString<OsclMemAllocator>, OsclMemAllocator> str;
   2356                 iParam4 = str.ALLOC_AND_CONSTRUCT(*aStr);
   2357             }
   2358             break;
   2359         default:
   2360             break;
   2361     }
   2362 }
   2363 
   2364 /* need to overlaod the base Destroy routine to cleanup metadata key */
   2365 void PVMFSMFSPBaseNodeCommand::Destroy()
   2366 {
   2367     PVMFGenericNodeCommand<OsclMemAllocator>::Destroy();
   2368     switch (iCmd)
   2369     {
   2370         case PVMF_SMFSP_NODE_GETNODEMETADATAKEYS:
   2371             if (iParam4)
   2372             {
   2373                 /* cleanup the allocated string */
   2374                 Oscl_TAlloc<OSCL_HeapString<OsclMemAllocator>, OsclMemAllocator> str;
   2375                 str.destruct_and_dealloc(iParam4);
   2376             }
   2377             break;
   2378         default:
   2379             break;
   2380     }
   2381 }
   2382 
   2383 /* Called during a Reset */
   2384 void PVMFSMFSPBaseNode::ResetNodeParams(bool aReleaseMem)
   2385 {
   2386     //This function will reset the member variables to their initial values.
   2387     //except command queues
   2388     //This function intentionally does not reset the command queues.
   2389     //Reason:This func may be called in response to handle some asyn command(say Reset).
   2390     //So the command will be in the some of the Q. Reporting command completion for
   2391     //non existing command in Q will result in segmentation fault.
   2392 
   2393     iCapability.iCanSupportMultipleInputPorts = false;
   2394     iCapability.iCanSupportMultipleOutputPorts = true;
   2395     iCapability.iHasMaxNumberOfPorts = false;
   2396     iCapability.iMaxNumberOfPorts = 0;
   2397 
   2398     iRepositioning = false;
   2399     iPlaylistPlayInProgress = false;
   2400     iRepositionRequestedStartNPTInMS = 0;
   2401     iActualRepositionStartNPTInMS = 0;
   2402     iActualRepositionStartNPTInMSPtr = NULL;
   2403     iActualMediaDataTS = 0;
   2404     iActualMediaDataTSPtr = NULL;
   2405     iJumpToIFrame = false;
   2406 
   2407     iSessionStartTime = 0;
   2408     iSessionStopTime = 0;
   2409     iSessionStopTimeAvailable = true;
   2410     iSessionSeekAvailable = false;
   2411 
   2412     iPVMFDataSourcePositionParamsPtr = NULL;
   2413     iStreamID = 0;
   2414     iPlayListRepositioning = false;
   2415 
   2416     iNoOfValuesPushedInValueVect = 0;
   2417 
   2418     iNumRequestPortsPending = 0;
   2419     iTotalNumRequestPortsComplete = 0;
   2420     iGraphConstructComplete = false;
   2421     iGraphConnectComplete = false;
   2422 
   2423     iAvailableMetadataKeys.clear();
   2424     iCPMMetadataKeys.clear();
   2425 
   2426     if (iMetaDataInfo)
   2427         iMetaDataInfo->Reset();
   2428 
   2429     //CPM related
   2430     ResetCPMParams(aReleaseMem);
   2431     for (int32 i = 0; i < PVMF_STREAMING_MANAGER_INTERNAL_CMDQ_SIZE; i++)
   2432     {
   2433         iInternalCmdPool[i].cmd = PVMF_STREAMING_MANAGER_INTERNAL_CMDQ_SIZE;
   2434         iInternalCmdPool[i].oFree = true;
   2435     }
   2436 
   2437     PVMFSMFSPChildNodeContainerVector::iterator it;
   2438     for (it = iFSPChildNodeContainerVec.begin();
   2439             it != iFSPChildNodeContainerVec.end();
   2440             it++)
   2441     {
   2442         it->iInputPorts.clear();
   2443         it->iOutputPorts.clear();
   2444         it->iFeedBackPorts.clear();
   2445     }
   2446 
   2447     if (aReleaseMem)
   2448     {
   2449         OSCL_DELETE(iJBFactory);
   2450     }
   2451     iJBFactory = NULL;
   2452 }
   2453 
   2454 void PVMFSMFSPBaseNode::ResetCPMParams(bool aReleaseMem)
   2455 {
   2456     if (aReleaseMem)
   2457     {
   2458         if (iCPMContentAccessFactory != NULL)
   2459         {
   2460             if (iDecryptionInterface != NULL)
   2461             {
   2462                 iDecryptionInterface->Reset();
   2463                 /* Remove the decrpytion interface */
   2464                 PVUuid uuid = PVMFCPMPluginDecryptionInterfaceUuid;
   2465                 iCPMContentAccessFactory->DestroyPVMFCPMPluginAccessInterface(uuid, iDecryptionInterface);
   2466                 iDecryptionInterface = NULL;
   2467             }
   2468             iCPMContentAccessFactory->removeRef();
   2469             iCPMContentAccessFactory = NULL;
   2470         }
   2471 
   2472         if (iRequestedUsage.key)
   2473         {
   2474             OSCL_ARRAY_DELETE(iRequestedUsage.key);
   2475             iRequestedUsage.key = NULL;
   2476         }
   2477 
   2478         if (iApprovedUsage.key)
   2479         {
   2480             OSCL_ARRAY_DELETE(iApprovedUsage.key);
   2481             iApprovedUsage.key = NULL;
   2482         }
   2483 
   2484         if (iAuthorizationDataKvp.key)
   2485         {
   2486             OSCL_ARRAY_DELETE(iAuthorizationDataKvp.key);
   2487             iAuthorizationDataKvp.key = NULL;
   2488         }
   2489     }
   2490     iCPMMetadataKeys.clear();
   2491     iPreviewMode = false;
   2492     iUseCPMPluginRegistry = false;
   2493     iDRMResetPending = false;
   2494     iCPMInitPending = false;
   2495     maxPacketSize = 0;
   2496     iPVMFStreamingManagerNodeMetadataValueCount = 0;
   2497 
   2498     iCPMSourceData.iRefCounter = 0;
   2499     iCPMSourceData.iFileHandle  = NULL;
   2500     iCPMSourceData.iStreamStatsLoggingURL = _STRLIT("");
   2501     iCPMSourceData.iPreviewMode = false;
   2502     iCPMSourceData.iIntent = BITMASK_PVMF_SOURCE_INTENT_PLAY;
   2503     iCPMSourceData.iProxyName = _STRLIT("");
   2504     iCPMSourceData.iProxyPort = 0;
   2505     PVMFSourceContextData tmpObj;
   2506     iSourceContextData = tmpObj;
   2507     iSourceContextDataValid = false;
   2508     iCPMSessionID = 0xFFFFFFFF;
   2509     iCPMContentType = PVMF_CPM_CONTENT_FORMAT_UNKNOWN;
   2510     iCPMContentAccessFactory = NULL;
   2511     iDecryptionInterface = NULL;
   2512     iCPMLicenseInterface = NULL;
   2513     iCPMLicenseInterfacePVI = NULL;
   2514     iCPMCapConfigInterface = NULL;
   2515     iCPMCapConfigInterfacePVI = NULL;
   2516     iCPMMetaDataExtensionInterface = NULL;
   2517     iCPMKvpStore.destroy();
   2518     iRequestedUsage.key = NULL;
   2519     iApprovedUsage.key = NULL;
   2520     iAuthorizationDataKvp.key = NULL;
   2521     iUsageID = 0;
   2522     iCPMRequestUsageCommandStatus = 0;
   2523 
   2524     iCPMInitCmdId = 0;
   2525     iCPMOpenSessionCmdId = 0;
   2526     iCPMRegisterContentCmdId = 0;
   2527     iCPMRequestUsageId = 0;
   2528     iCPMUsageCompleteCmdId = 0;
   2529     iCPMCloseSessionCmdId = 0;
   2530     iCPMResetCmdId = 0;
   2531     iCPMGetMetaDataKeysCmdId = 0;
   2532     iCPMGetMetaDataValuesCmdId = 0;
   2533     iCPMGetLicenseInterfaceCmdId = 0;
   2534     iCPMGetLicenseCmdId = 0;
   2535     iCPMGetCapConfigCmdId = 0;
   2536     iCPMCancelGetLicenseCmdId = 0;
   2537 }
   2538 
   2539 void PVMFSMFSPBaseNode::PopulateAvailableMetadataKeys()
   2540 {
   2541     iAvailableMetadataKeys.clear();
   2542 
   2543     int32 leavecode = OsclErrNone;
   2544     OSCL_TRY(leavecode,
   2545              iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_DURATION_KEY);
   2546              if (iMetaDataInfo->iAlbumPresent)
   2547 {
   2548     iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_ALBUM_KEY);
   2549     }
   2550     if (iMetaDataInfo->iAuthorPresent)
   2551 {
   2552     iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_AUTHOR_KEY);
   2553     }
   2554     if (iMetaDataInfo->iPerformerPresent)
   2555 {
   2556     iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_ARTIST_KEY);
   2557     }
   2558     if (iMetaDataInfo->iTitlePresent)
   2559 {
   2560     iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_TITLE_KEY);
   2561     }
   2562     if (iMetaDataInfo->iDescriptionPresent)
   2563 {
   2564     iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_DESCRIPTION_KEY);
   2565     }
   2566     if (iMetaDataInfo->iRatingPresent)
   2567 {
   2568     iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_RATING_KEY);
   2569     }
   2570     if (iMetaDataInfo->iCopyRightPresent)
   2571 {
   2572     iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_COPYRIGHT_KEY);
   2573     }
   2574     if (iMetaDataInfo->iGenrePresent)
   2575 {
   2576     iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_GENRE_KEY);
   2577     }
   2578     if (iMetaDataInfo->iLyricsPresent)
   2579 {
   2580     iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_LYRICS_KEY);
   2581     }
   2582     if (iMetaDataInfo->iClassificationPresent)
   2583 {
   2584     iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_CLASSIFICATION_KEY);
   2585     }
   2586     if (iMetaDataInfo->iKeyWordsPresent)
   2587 {
   2588     iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_KEYWORDS_KEY);
   2589     }
   2590     if (iMetaDataInfo->iLocationPresent)
   2591 {
   2592     iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_LOCATION_KEY);
   2593     }
   2594     if (iMetaDataInfo->iNumTracks > 0)
   2595 {
   2596     iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_NUMTRACKS_KEY);
   2597 
   2598         // Create the parameter string for the index range
   2599         char indexparam[18];
   2600         oscl_snprintf(indexparam, 18, ";index=0...%d", (iMetaDataInfo->iNumTracks - 1));
   2601         indexparam[17] = NULL_TERM_CHAR;
   2602 
   2603         bool valueAvailableForKey = false;
   2604         {
   2605             for (uint32 i = 0; i < (iMetaDataInfo->iNumTracks - 1); i++)
   2606             {
   2607                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   2608                 {
   2609                     PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   2610                     if (trackMetaDataInfo.iMimeType.get_cstr())
   2611                     {
   2612                         valueAvailableForKey = true;
   2613                         break;
   2614                     }
   2615                 }
   2616             }
   2617         }
   2618         if (valueAvailableForKey)
   2619         {
   2620             iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_TYPE_KEY);
   2621             iAvailableMetadataKeys[0] += indexparam;
   2622         }
   2623 
   2624         iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_DURATION_KEY);
   2625         iAvailableMetadataKeys[0] += indexparam;
   2626 
   2627         iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_SELECTED_KEY);
   2628         iAvailableMetadataKeys[0] += indexparam;
   2629 
   2630         valueAvailableForKey = false;
   2631         {
   2632             for (uint32 i = 0; i < (iMetaDataInfo->iNumTracks - 1); i++)
   2633             {
   2634                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   2635                 {
   2636                     PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   2637                     if (trackMetaDataInfo.iCodecName.get_size() > 0)
   2638                     {
   2639                         valueAvailableForKey = true;
   2640                         break;
   2641                     }
   2642                 }
   2643             }
   2644         }
   2645         if (valueAvailableForKey)
   2646         {
   2647             iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_NAME_KEY);
   2648             iAvailableMetadataKeys[0] += indexparam;
   2649         }
   2650 
   2651         valueAvailableForKey = false;
   2652         {
   2653             for (uint32 i = 0; i < (iMetaDataInfo->iNumTracks - 1); i++)
   2654             {
   2655                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   2656                 {
   2657                     PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   2658                     if (trackMetaDataInfo.iCodecDescription.get_size() > 0)
   2659                     {
   2660                         valueAvailableForKey = true;
   2661                         break;
   2662                     }
   2663                 }
   2664             }
   2665         }
   2666         if (valueAvailableForKey)
   2667         {
   2668             iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_DESCRIPTION_KEY);
   2669             iAvailableMetadataKeys[0] += indexparam;
   2670         }
   2671 
   2672         valueAvailableForKey = false;
   2673         {
   2674             for (uint32 i = 0; i < (iMetaDataInfo->iNumTracks - 1); i++)
   2675             {
   2676                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   2677                 {
   2678                     PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   2679                     if (trackMetaDataInfo.iCodecSpecificInfo.getMemFragPtr())
   2680                     {
   2681                         valueAvailableForKey = true;
   2682                         break;
   2683                     }
   2684                 }
   2685             }
   2686         }
   2687         if (valueAvailableForKey)
   2688         {
   2689             iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_DATA_KEY);
   2690             iAvailableMetadataKeys[0] += indexparam;
   2691         }
   2692 
   2693         iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_TRACKID_KEY);
   2694         iAvailableMetadataKeys[0] += indexparam;
   2695     }
   2696 
   2697     if (iMetaDataInfo->iYear)
   2698 {
   2699     iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_YEAR_KEY);
   2700     }
   2701     if (iMetaDataInfo->iWMPicturePresent)
   2702 {
   2703     iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_NUM_GRAPHICS_KEY);
   2704     }
   2705     if (iMetaDataInfo->iWMPicturePresent)
   2706 {
   2707     // Create the parameter string for the index range
   2708     char indexparam[18];
   2709         oscl_snprintf(indexparam, 18, ";index=0...%d", (iMetaDataInfo->iWMPictureIndexVec.size() - 1));
   2710         indexparam[17] = NULL_TERM_CHAR;
   2711         iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_GRAPHICS_KEY);
   2712         iAvailableMetadataKeys[0] += indexparam;
   2713     }
   2714     iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_RANDOM_ACCESS_DENIED_KEY);
   2715 
   2716     iAvailableMetadataKeys.push_back(PVMFSTREAMINGMGRNODE_CLIP_TYPE_KEY);
   2717 
   2718     if ((iUseCPMPluginRegistry == false) || (iSessionSourceInfo->iDRMProtected == false))
   2719 {
   2720     iAvailableMetadataKeys.push_back(PVMF_DRM_INFO_IS_PROTECTED_QUERY);
   2721     }
   2722     uint32 i = 0;
   2723     for (i = 0; i < iMetaDataInfo->iTrackMetaDataInfoVec.size(); i++)
   2724 {
   2725     PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   2726 
   2727         char indexparam[18];
   2728         oscl_snprintf(indexparam, 18, ";index=%d", (i));
   2729         indexparam[17] = NULL_TERM_CHAR;
   2730 
   2731         if (trackMetaDataInfo.iTrackWidth > 0)
   2732         {
   2733             iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_WIDTH_KEY);
   2734             iAvailableMetadataKeys[0] += indexparam;
   2735         }
   2736         if (trackMetaDataInfo.iTrackHeight > 0)
   2737         {
   2738             iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_HEIGHT_KEY);
   2739             iAvailableMetadataKeys[0] += indexparam;
   2740         }
   2741         if (trackMetaDataInfo.iVideoFrameRate > 0)
   2742         {
   2743             iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_FRAME_RATE_KEY);
   2744             iAvailableMetadataKeys[0] += indexparam;
   2745         }
   2746         if (trackMetaDataInfo.iAudioSampleRate > 0)
   2747         {
   2748             iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_SAMPLERATE_KEY);
   2749             iAvailableMetadataKeys[0] += indexparam;
   2750         }
   2751         if (trackMetaDataInfo.iAudioNumChannels > 0)
   2752         {
   2753             iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_NUMCHANNELS_KEY);
   2754             iAvailableMetadataKeys[0] += indexparam;
   2755         }
   2756         if (trackMetaDataInfo.iAudioBitsPerSample > 0)
   2757         {
   2758             iAvailableMetadataKeys.push_front(PVMFSTREAMINGMGRNODE_TRACKINFO_AUDIO_BITS_PER_SAMPLE_KEY);
   2759             iAvailableMetadataKeys[0] += indexparam;
   2760         }
   2761     }
   2762             );
   2763     if (leavecode != OsclErrNone)
   2764     {
   2765         OSCL_LEAVE(leavecode);
   2766     }
   2767 }
   2768 
   2769 PVMFStatus PVMFSMFSPBaseNode::DoGetMetadataKeysBase(PVMFSMFSPBaseNodeCommand& aCmd)
   2770 {
   2771     if (!iMetaDataInfo->iMetadataAvailable)
   2772     {
   2773         return PVMFErrInvalidState;
   2774     }
   2775 
   2776     iCPMMetadataKeys.clear();
   2777     /* Get Metadata keys from CPM for protected content only */
   2778     if ((iCPMMetaDataExtensionInterface != NULL) &&
   2779             (iSessionSourceInfo->iDRMProtected == true))
   2780     {
   2781         GetCPMMetaDataKeys();
   2782         return PVMFPending;
   2783     }
   2784 
   2785     return (CompleteGetMetadataKeys(aCmd));
   2786 }
   2787 
   2788 PVMFStatus PVMFSMFSPBaseNode::CompleteGetMetadataKeys(PVMFSMFSPBaseNodeCommand& aCmd)
   2789 {
   2790     PVMFMetadataList* keylistptr = NULL;
   2791     uint32 starting_index;
   2792     int32 max_entries;
   2793     char* query_key = NULL;
   2794 
   2795     aCmd.PVMFSMFSPBaseNodeCommand::Parse(keylistptr, starting_index, max_entries, query_key);
   2796 
   2797     // Check parameters
   2798     if (keylistptr == NULL)
   2799     {
   2800         // The list pointer is invalid
   2801         return PVMFErrArgument;
   2802     }
   2803 
   2804     if ((starting_index > (iAvailableMetadataKeys.size() - 1)) || max_entries == 0)
   2805     {
   2806         // Invalid starting index and/or max entries
   2807         return PVMFErrArgument;
   2808     }
   2809 
   2810     // Copy the requested keys
   2811     uint32 num_entries = 0;
   2812     int32 num_added = 0;
   2813     uint32 lcv = 0;
   2814     for (lcv = 0; lcv < iAvailableMetadataKeys.size(); lcv++)
   2815     {
   2816         if (query_key == NULL)
   2817         {
   2818             // No query key so this key is counted
   2819             ++num_entries;
   2820             if (num_entries > starting_index)
   2821             {
   2822                 // Past the starting index so copy the key
   2823                 PVMFStatus status = PushKeyToMetadataList(keylistptr, iAvailableMetadataKeys[lcv]);
   2824                 if (PVMFSuccess == status)
   2825                     num_added++;
   2826                 else
   2827                     return status;
   2828             }
   2829         }
   2830         else
   2831         {
   2832             // Check if the key matche the query key
   2833             if (pv_mime_strcmp(iAvailableMetadataKeys[lcv].get_cstr(), query_key) >= 0)
   2834             {
   2835                 // This key is counted
   2836                 ++num_entries;
   2837                 if (num_entries > starting_index)
   2838                 {
   2839                     PVMFStatus status = PushKeyToMetadataList(keylistptr, iAvailableMetadataKeys[lcv]);
   2840                     if (PVMFSuccess == status)
   2841                         num_added++;
   2842                     else
   2843                         return status;
   2844                 }
   2845             }
   2846         }
   2847     }
   2848     for (lcv = 0; lcv < iCPMMetadataKeys.size(); lcv++)
   2849     {
   2850         if (query_key == NULL)
   2851         {
   2852             /* No query key so this key is counted */
   2853             ++num_entries;
   2854             if (num_entries > (uint32)starting_index)
   2855             {
   2856                 PVMFStatus status = PushKeyToMetadataList(keylistptr, iCPMMetadataKeys[lcv]);
   2857                 if (PVMFSuccess == status)
   2858                     num_added++;
   2859                 else
   2860                     return status;
   2861             }
   2862         }
   2863         else
   2864         {
   2865             /* Check if the key matches the query key */
   2866             if (pv_mime_strcmp(iCPMMetadataKeys[lcv].get_cstr(), query_key) >= 0)
   2867             {
   2868                 /* This key is counted */
   2869                 ++num_entries;
   2870                 if (num_entries > (uint32)starting_index)
   2871                 {
   2872                     PVMFStatus status = PushKeyToMetadataList(keylistptr, iCPMMetadataKeys[lcv]);
   2873                     if (PVMFSuccess == status)
   2874                         num_added++;
   2875                     else
   2876                         return status;
   2877                 }
   2878             }
   2879         }
   2880         // Check if max number of entries have been copied
   2881         if (max_entries > 0 && num_added >= max_entries)
   2882         {
   2883             break;
   2884         }
   2885     }
   2886     return PVMFSuccess;
   2887 }
   2888 
   2889 PVMFStatus PVMFSMFSPBaseNode::PushKeyToMetadataList(PVMFMetadataList* aMetaDataListPtr, const OSCL_HeapString<OsclMemAllocator> & aKey)const
   2890 {
   2891     PVMFStatus status = PVMFSuccess;
   2892     if (aMetaDataListPtr)
   2893     {
   2894         int32 leavecode = 0;
   2895         OSCL_TRY(leavecode, aMetaDataListPtr->push_back(aKey));
   2896         OSCL_FIRST_CATCH_ANY(leavecode,
   2897                              PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFSMFSPBaseNode::PushKeyToMetadataList - Memory allocation failure when copying metadata key"));
   2898                              status = PVMFErrNoMemory);
   2899     }
   2900     else
   2901         status = PVMFErrArgument;
   2902     return status;
   2903 
   2904 }
   2905 
   2906 PVMFStatus PVMFSMFSPBaseNode::DoGetMetadataValuesBase(PVMFSMFSPBaseNodeCommand& aCmd)
   2907 {
   2908 
   2909     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFStreamingManagerNode::DoGetMetadataValues() In"));
   2910 
   2911     if (!iMetaDataInfo->iMetadataAvailable)
   2912     {
   2913         return PVMFErrInvalidState;
   2914     }
   2915 
   2916     PVMFMetadataList* keylistptr = NULL;
   2917     Oscl_Vector<PvmiKvp, OsclMemAllocator>* valuelistptr = NULL;
   2918     uint32 starting_index;
   2919     int32 max_entries;
   2920 
   2921     aCmd.PVMFSMFSPBaseNodeCommand::Parse(keylistptr, valuelistptr, starting_index, max_entries);
   2922 
   2923     // Check the parameters
   2924     if (keylistptr == NULL || valuelistptr == NULL)
   2925     {
   2926         return PVMFErrArgument;
   2927     }
   2928 
   2929     uint32 numkeys = keylistptr->size();
   2930 
   2931     if (numkeys <= 0 || max_entries == 0)
   2932     {
   2933         // Don't do anything
   2934         return PVMFErrArgument;
   2935     }
   2936 
   2937     uint32 numvalentries = iNoOfValuesIteratedForValueVect;
   2938     int32 numentriesadded = iNoOfValuesPushedInValueVect;
   2939     for (uint32 lcv = 0; lcv < numkeys; lcv++)
   2940     {
   2941         int32 leavecode = 0;
   2942         PvmiKvp KeyVal;
   2943         KeyVal.key = NULL;
   2944         KeyVal.value.pWChar_value = NULL;
   2945         KeyVal.value.pChar_value = NULL;
   2946 
   2947         if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_ALBUM_KEY) == 0 &&
   2948                 iMetaDataInfo->iAlbumPresent)
   2949         {
   2950             // Album
   2951             // Increment the counter for the number of values found so far
   2952             ++numvalentries;
   2953 
   2954             // Create a value entry if past the starting index
   2955             if (numvalentries > starting_index)
   2956             {
   2957                 PVMFStatus retval;
   2958                 if (iMetaDataInfo->iIsAuthorUnicode == false)
   2959                 {
   2960                     retval = PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal,
   2961                              PVMFSTREAMINGMGRNODE_ALBUM_KEY,
   2962                              iMetaDataInfo->iAlbum.get_cstr());
   2963                 }
   2964                 else
   2965                 {
   2966                     retval = PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal,
   2967                              PVMFSTREAMINGMGRNODE_ALBUM_KEY,
   2968                              iMetaDataInfo->iAlbumUnicode);
   2969                 }
   2970                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
   2971                 {
   2972                     break;
   2973                 }
   2974             }
   2975         }
   2976         else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_AUTHOR_KEY) == 0 &&
   2977                  iMetaDataInfo->iAuthorPresent)
   2978         {
   2979             // Author
   2980             // Increment the counter for the number of values found so far
   2981             ++numvalentries;
   2982 
   2983             // Create a value entry if past the starting index
   2984             if (numvalentries > starting_index)
   2985             {
   2986                 PVMFStatus retval;
   2987                 if (iMetaDataInfo->iIsAuthorUnicode == false)
   2988                 {
   2989                     retval = PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal,
   2990                              PVMFSTREAMINGMGRNODE_AUTHOR_KEY,
   2991                              iMetaDataInfo->iAuthor.get_cstr());
   2992                 }
   2993                 else
   2994                 {
   2995                     retval = PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal,
   2996                              PVMFSTREAMINGMGRNODE_AUTHOR_KEY,
   2997                              iMetaDataInfo->iAuthorUnicode);
   2998                 }
   2999                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3000                 {
   3001                     break;
   3002                 }
   3003             }
   3004         }
   3005         else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_ARTIST_KEY) == 0 &&
   3006                  iMetaDataInfo->iPerformerPresent)
   3007         {
   3008             // Artist/performer
   3009             // Increment the counter for the number of values found so far
   3010             ++numvalentries;
   3011 
   3012             // Create a value entry if past the starting index
   3013             if (numvalentries > starting_index)
   3014             {
   3015                 PVMFStatus retval;
   3016                 if (iMetaDataInfo->iIsPerformerUnicode == false)
   3017                 {
   3018                     retval = PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal,
   3019                              PVMFSTREAMINGMGRNODE_ARTIST_KEY,
   3020                              iMetaDataInfo->iPerformer.get_cstr());
   3021                 }
   3022                 else
   3023                 {
   3024                     retval = PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal,
   3025                              PVMFSTREAMINGMGRNODE_ARTIST_KEY,
   3026                              iMetaDataInfo->iPerformerUnicode);
   3027                 }
   3028                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3029                 {
   3030                     break;
   3031                 }
   3032             }
   3033         }
   3034         else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TITLE_KEY) == 0 &&
   3035                  iMetaDataInfo->iTitlePresent)
   3036         {
   3037             // Title
   3038             // Increment the counter for the number of values found so far
   3039             ++numvalentries;
   3040 
   3041             // Create a value entry if past the starting index
   3042             if (numvalentries > starting_index)
   3043             {
   3044                 PVMFStatus retval;
   3045                 if (iMetaDataInfo->iIsTitleUnicode == false)
   3046                 {
   3047                     retval = PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal,
   3048                              PVMFSTREAMINGMGRNODE_TITLE_KEY,
   3049                              iMetaDataInfo->iTitle.get_cstr());
   3050                 }
   3051                 else
   3052                 {
   3053                     retval = PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal,
   3054                              PVMFSTREAMINGMGRNODE_TITLE_KEY,
   3055                              iMetaDataInfo->iTitleUnicode);
   3056                 }
   3057                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3058                 {
   3059                     break;
   3060                 }
   3061             }
   3062         }
   3063         else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_DESCRIPTION_KEY) == 0 &&
   3064                  iMetaDataInfo->iDescriptionPresent)
   3065         {
   3066             // Description
   3067             // Increment the counter for the number of values found so far
   3068             ++numvalentries;
   3069 
   3070             // Create a value entry if past the starting index
   3071             if (numvalentries > starting_index)
   3072             {
   3073                 PVMFStatus retval;
   3074                 if (iMetaDataInfo->iIsDescriptionUnicode == false)
   3075                 {
   3076                     retval = PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal,
   3077                              PVMFSTREAMINGMGRNODE_DESCRIPTION_KEY,
   3078                              iMetaDataInfo->iDescription.get_cstr());
   3079                 }
   3080                 else
   3081                 {
   3082                     retval = PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal,
   3083                              PVMFSTREAMINGMGRNODE_DESCRIPTION_KEY,
   3084                              iMetaDataInfo->iDescriptionUnicode);
   3085                 }
   3086                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3087                 {
   3088                     break;
   3089                 }
   3090             }
   3091         }
   3092         else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_RATING_KEY) == 0 &&
   3093                  iMetaDataInfo->iRatingPresent)
   3094         {
   3095             // Rating
   3096             // Increment the counter for the number of values found so far
   3097             ++numvalentries;
   3098 
   3099             // Create a value entry if past the starting index
   3100             if (numvalentries > starting_index)
   3101             {
   3102                 PVMFStatus retval;
   3103                 if (iMetaDataInfo->iIsRatingUnicode == false)
   3104                 {
   3105                     retval = PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal,
   3106                              PVMFSTREAMINGMGRNODE_RATING_KEY,
   3107                              iMetaDataInfo->iRating.get_cstr());
   3108                 }
   3109                 else
   3110                 {
   3111                     retval = PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal,
   3112                              PVMFSTREAMINGMGRNODE_RATING_KEY,
   3113                              iMetaDataInfo->iRatingUnicode);
   3114                 }
   3115                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3116                 {
   3117                     break;
   3118                 }
   3119             }
   3120         }
   3121         else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_COPYRIGHT_KEY) == 0 &&
   3122                  iMetaDataInfo->iCopyRightPresent)
   3123         {
   3124             // Copyright
   3125             // Increment the counter for the number of values found so far
   3126             ++numvalentries;
   3127 
   3128             // Create a value entry if past the starting index
   3129             if (numvalentries > starting_index)
   3130             {
   3131                 PVMFStatus retval;
   3132                 if (iMetaDataInfo->iIsCopyRightUnicode == false)
   3133                 {
   3134                     retval = PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal,
   3135                              PVMFSTREAMINGMGRNODE_COPYRIGHT_KEY,
   3136                              iMetaDataInfo->iCopyright.get_cstr());
   3137                 }
   3138                 else
   3139                 {
   3140                     retval = PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal,
   3141                              PVMFSTREAMINGMGRNODE_COPYRIGHT_KEY,
   3142                              iMetaDataInfo->iCopyrightUnicode);
   3143                 }
   3144                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3145                 {
   3146                     break;
   3147                 }
   3148             }
   3149         }
   3150         else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_GENRE_KEY) == 0 &&
   3151                  iMetaDataInfo->iGenrePresent)
   3152         {
   3153             // Genre
   3154             // Increment the counter for the number of values found so far
   3155             ++numvalentries;
   3156 
   3157             // Create a value entry if past the starting index
   3158             if (numvalentries > starting_index)
   3159             {
   3160                 PVMFStatus retval;
   3161                 if (iMetaDataInfo->iIsGenreUnicode == false)
   3162                 {
   3163                     retval = PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal,
   3164                              PVMFSTREAMINGMGRNODE_GENRE_KEY,
   3165                              iMetaDataInfo->iGenre.get_cstr());
   3166                 }
   3167                 else
   3168                 {
   3169                     retval = PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal,
   3170                              PVMFSTREAMINGMGRNODE_GENRE_KEY,
   3171                              iMetaDataInfo->iGenreUnicode);
   3172                 }
   3173                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3174                 {
   3175                     break;
   3176                 }
   3177             }
   3178         }
   3179         else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_LYRICS_KEY) == 0 &&
   3180                  iMetaDataInfo->iLyricsPresent)
   3181         {
   3182             // Lyrics
   3183             // Increment the counter for the number of values found so far
   3184             ++numvalentries;
   3185 
   3186             // Create a value entry if past the starting index
   3187             if (numvalentries > starting_index)
   3188             {
   3189                 PVMFStatus retval;
   3190                 if (iMetaDataInfo->iIsLyricsUnicode == false)
   3191                 {
   3192                     retval = PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal,
   3193                              PVMFSTREAMINGMGRNODE_LYRICS_KEY,
   3194                              iMetaDataInfo->iLyrics.get_cstr());
   3195                 }
   3196                 else
   3197                 {
   3198                     retval = PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal,
   3199                              PVMFSTREAMINGMGRNODE_LYRICS_KEY,
   3200                              iMetaDataInfo->iLyricsUnicode);
   3201                 }
   3202                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3203                 {
   3204                     break;
   3205                 }
   3206             }
   3207         }
   3208         else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_CLASSIFICATION_KEY) == 0 &&
   3209                  iMetaDataInfo->iClassificationPresent)
   3210         {
   3211             // Classification
   3212             // Increment the counter for the number of values found so far
   3213             ++numvalentries;
   3214 
   3215             // Create a value entry if past the starting index
   3216             if (numvalentries > starting_index)
   3217             {
   3218                 PVMFStatus retval;
   3219                 if (iMetaDataInfo->iIsClassificationUnicode == false)
   3220                 {
   3221                     retval = PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal,
   3222                              PVMFSTREAMINGMGRNODE_CLASSIFICATION_KEY,
   3223                              iMetaDataInfo->iClassification.get_cstr());
   3224                 }
   3225                 else
   3226                 {
   3227                     retval = PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal,
   3228                              PVMFSTREAMINGMGRNODE_CLASSIFICATION_KEY,
   3229                              iMetaDataInfo->iClassificationUnicode);
   3230                 }
   3231                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3232                 {
   3233                     break;
   3234                 }
   3235             }
   3236         }
   3237         else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_KEYWORDS_KEY) == 0 &&
   3238                  iMetaDataInfo->iKeyWordsPresent)
   3239         {
   3240             for (uint32 i = 0; i < iMetaDataInfo->iNumKeyWords; i++)
   3241             {
   3242                 // Keywords
   3243                 // Increment the counter for the number of values found so far
   3244                 PvmiKvp keywordKVP;
   3245                 keywordKVP.key = NULL;
   3246 
   3247                 if (iMetaDataInfo->iIsKeyWordsUnicode)
   3248                 {
   3249                     if (iMetaDataInfo->iKeyWordUnicode[i].get_cstr())
   3250                     {
   3251                         ++numvalentries;
   3252                     }
   3253                 }
   3254                 else
   3255                 {
   3256                     if (iMetaDataInfo->iKeyWords[i].get_cstr())
   3257                     {
   3258                         ++numvalentries;
   3259                     }
   3260                 }
   3261 
   3262                 // Create a value entry if past the starting index
   3263                 if (numvalentries > starting_index)
   3264                 {
   3265                     PVMFStatus retval;
   3266                     KeyVal.value.pChar_value = NULL;
   3267                     KeyVal.value.pWChar_value = NULL;
   3268                     if (iMetaDataInfo->iIsKeyWordsUnicode == false)
   3269                     {
   3270                         retval = PVMFCreateKVPUtils::CreateKVPForCharStringValue(keywordKVP,
   3271                                  PVMFSTREAMINGMGRNODE_KEYWORDS_KEY,
   3272                                  iMetaDataInfo->iKeyWords[i].get_cstr());
   3273                     }
   3274                     else
   3275                     {
   3276                         retval = PVMFCreateKVPUtils::CreateKVPForWStringValue(keywordKVP,
   3277                                  PVMFSTREAMINGMGRNODE_KEYWORDS_KEY,
   3278                                  iMetaDataInfo->iKeyWordUnicode[i]);
   3279                     }
   3280                     if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3281                     {
   3282                         break;
   3283                     }
   3284                     if (keywordKVP.key != NULL)
   3285                     {
   3286                         if (PVMFSuccess != PushKVPToMetadataValueList(valuelistptr, keywordKVP))
   3287                         {
   3288                             if (keywordKVP.value.pChar_value != NULL)
   3289                             {
   3290                                 OSCL_ARRAY_DELETE(KeyVal.value.pChar_value);
   3291                                 keywordKVP.value.pChar_value = NULL;
   3292                             }
   3293                             if (keywordKVP.value.pWChar_value != NULL)
   3294                             {
   3295                                 OSCL_ARRAY_DELETE(KeyVal.value.pWChar_value);
   3296                                 keywordKVP.value.pChar_value = NULL;
   3297                             }
   3298                             OSCL_ARRAY_DELETE(keywordKVP.key);
   3299                             keywordKVP.key = NULL;
   3300                         }
   3301                         else
   3302                         {
   3303                             // Increment the value list entry counter
   3304                             ++numentriesadded;
   3305                         }
   3306 
   3307                         // Check if the max number of value entries were added
   3308                         if (max_entries > 0 && numentriesadded >= max_entries)
   3309                         {
   3310                             iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
   3311                             return PVMFSuccess;
   3312                         }
   3313                     }
   3314 
   3315                 }
   3316             }
   3317         }
   3318         else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_LOCATION_KEY) == 0 &&
   3319                  iMetaDataInfo->iLocationPresent)
   3320         {
   3321             // Location - Valid only for RTSP Streaming
   3322             // Increment the counter for the number of values found so far
   3323 
   3324             ++numvalentries;
   3325             // Create a value entry if past the starting index
   3326             if (numvalentries > starting_index)
   3327             {
   3328                 //memory for this struct is owned in SDP parser lib
   3329                 PVMFStatus retval;
   3330                 retval = PVMFCreateKVPUtils::CreateKVPForKSVValue(KeyVal,
   3331                          PVMFSTREAMINGMGRNODE_LOCATION_KEY,
   3332                          (OsclAny*)(&(iMetaDataInfo->iLocationStruct)));
   3333                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3334                 {
   3335                     break;
   3336                 }
   3337             }
   3338         }
   3339         else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_DURATION_KEY) == 0)
   3340         {
   3341             // Session Duration
   3342             // Increment the counter for the number of values found so far
   3343             ++numvalentries;
   3344 
   3345             // Create a value entry if past the starting index
   3346             if (numvalentries > starting_index)
   3347             {
   3348                 if (iMetaDataInfo->iSessionDurationAvailable == true)
   3349                 {
   3350                     uint32 duration = Oscl_Int64_Utils::get_uint64_lower32(iMetaDataInfo->iSessionDuration);
   3351                     char timescalestr[20];
   3352                     oscl_snprintf(timescalestr, 20, ";%s%d", PVMFSTREAMINGMGRNODE_TIMESCALE, iMetaDataInfo->iSessionDurationTimeScale);
   3353                     timescalestr[19] = NULL_TERM_CHAR;
   3354                     PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal,
   3355                                         PVMFSTREAMINGMGRNODE_DURATION_KEY,
   3356                                         duration,
   3357                                         timescalestr);
   3358                     if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3359                     {
   3360                         break;
   3361                     }
   3362                 }
   3363                 else
   3364                 {
   3365                     OSCL_StackString<32> unknownDuration(_STRLIT_CHAR("unknown"));
   3366                     PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal,
   3367                                         PVMFSTREAMINGMGRNODE_DURATION_KEY,
   3368                                         unknownDuration.get_cstr());
   3369                     if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3370                     {
   3371                         break;
   3372                     }
   3373                 }
   3374             }
   3375         }
   3376         else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_NUMTRACKS_KEY) == 0 &&
   3377                  iMetaDataInfo->iNumTracks > 0)
   3378         {
   3379             // Number of tracks
   3380             // Increment the counter for the number of values found so far
   3381             ++numvalentries;
   3382 
   3383             // Create a value entry if past the starting index
   3384             if (numvalentries > starting_index)
   3385             {
   3386                 PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal,
   3387                                     PVMFSTREAMINGMGRNODE_NUMTRACKS_KEY,
   3388                                     iMetaDataInfo->iNumTracks);
   3389                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3390                 {
   3391                     break;
   3392                 }
   3393             }
   3394         }
   3395         else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_RANDOM_ACCESS_DENIED_KEY) == 0)
   3396         {
   3397             // random access
   3398             // Increment the counter for the number of values found so far
   3399             ++numvalentries;
   3400 
   3401             // Create a value entry if past the starting index
   3402             if (numvalentries > starting_index)
   3403             {
   3404                 PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForBoolValue(KeyVal,
   3405                                     PVMFSTREAMINGMGRNODE_RANDOM_ACCESS_DENIED_KEY,
   3406                                     iMetaDataInfo->iRandomAccessDenied);
   3407                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3408                 {
   3409                     break;
   3410                 }
   3411             }
   3412         }
   3413         else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_YEAR_KEY) == 0 &&
   3414                  iMetaDataInfo->iYear)
   3415         {
   3416             // Year
   3417             // Increment the counter for the number of values found so far
   3418             ++numvalentries;
   3419 
   3420             // Create a value entry if past the starting index
   3421             if (numvalentries > starting_index)
   3422             {
   3423                 PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal,
   3424                                     PVMFSTREAMINGMGRNODE_YEAR_KEY,
   3425                                     iMetaDataInfo->iYear);
   3426                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3427                 {
   3428                     break;
   3429                 }
   3430             }
   3431         }
   3432         else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_NUM_GRAPHICS_KEY) == 0 &&
   3433                  iMetaDataInfo->iWMPicturePresent)
   3434         {
   3435             /*
   3436              * Num Picture
   3437              * Increment the counter for the number of values found so far
   3438              */
   3439             ++numvalentries;
   3440 
   3441             /* Create a value entry if past the starting index */
   3442             if (numvalentries > (uint32)starting_index)
   3443             {
   3444                 PVMFStatus retval =
   3445                     PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal,
   3446                             PVMFSTREAMINGMGRNODE_NUM_GRAPHICS_KEY,
   3447                             iMetaDataInfo->iNumWMPicture,
   3448                             NULL);
   3449                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3450                 {
   3451                     break;
   3452                 }
   3453             }
   3454         }
   3455         //value of Graphics key to be provided by FSP
   3456         else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_TYPE_KEY) != NULL)
   3457         {
   3458             // Track type
   3459 
   3460             // Determine the index requested. Default to all tracks
   3461             uint32 startindex = 0;
   3462             uint32 endindex   = iMetaDataInfo->iNumTracks - 1;
   3463             // Check if the index parameter is present
   3464             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
   3465             if (indexstr != NULL)
   3466             {
   3467                 // Retrieve the index values
   3468                 GetIndexParamValues(indexstr, startindex, endindex);
   3469             }
   3470             // Validate the indices
   3471             if (startindex > endindex || startindex >= iMetaDataInfo->iNumTracks || endindex >= iMetaDataInfo->iNumTracks)
   3472             {
   3473                 continue;
   3474             }
   3475 
   3476             // Return a KVP for each index
   3477             for (uint32 i = startindex; i <= endindex; ++i)
   3478             {
   3479                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   3480                 {
   3481                     PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   3482 
   3483                     PvmiKvp trackkvp;
   3484                     trackkvp.key = NULL;
   3485                     trackkvp.value.pChar_value = NULL;
   3486 
   3487                     // Increment the counter for the number of values found so far
   3488                     const char* mimeType = trackMetaDataInfo.iMimeType.get_cstr();
   3489                     if (mimeType)
   3490                     {
   3491                         ++numvalentries;
   3492                     }
   3493                     // Add the value entry if past the starting index
   3494                     PVMFStatus retval = PVMFErrArgument;
   3495                     if (numvalentries > starting_index)
   3496                     {
   3497                         char indexparam[16];
   3498                         oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
   3499                         indexparam[15] = NULL_TERM_CHAR;
   3500                         retval = PVMFCreateKVPUtils::CreateKVPForCharStringValue(trackkvp,
   3501                                  PVMFSTREAMINGMGRNODE_TRACKINFO_TYPE_KEY,
   3502                                  mimeType,
   3503                                  indexparam);
   3504                     }
   3505 
   3506                     if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3507                     {
   3508                         break;
   3509                     }
   3510 
   3511                     if (trackkvp.key != NULL)
   3512                     {
   3513                         leavecode = 0;
   3514                         if (PVMFSuccess != PushKVPToMetadataValueList(valuelistptr, trackkvp))
   3515                         {
   3516                             if (trackkvp.value.pChar_value != NULL)
   3517                             {
   3518                                 OSCL_ARRAY_DELETE(trackkvp.value.pChar_value);
   3519                                 trackkvp.value.pChar_value = NULL;
   3520                             }
   3521 
   3522                             OSCL_ARRAY_DELETE(trackkvp.key);
   3523                             trackkvp.key = NULL;
   3524                         }
   3525                         else
   3526                         {
   3527                             // Increment the value list entry counter
   3528                             ++numentriesadded;
   3529                         }
   3530 
   3531                         // Check if the max number of value entries were added
   3532                         if (max_entries > 0 && numentriesadded >= max_entries)
   3533                         {
   3534                             iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
   3535                             return PVMFSuccess;
   3536                         }
   3537                     }
   3538                 }
   3539             }
   3540         }
   3541         else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_DURATION_KEY) != NULL)
   3542         {
   3543             // Track duration
   3544 
   3545             // Determine the index requested. Default to all tracks
   3546             uint32 startindex = 0;
   3547             uint32 endindex = iMetaDataInfo->iNumTracks - 1;
   3548             // Check if the index parameter is present
   3549             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
   3550             if (indexstr != NULL)
   3551             {
   3552                 // Retrieve the index values
   3553                 GetIndexParamValues(indexstr, startindex, endindex);
   3554             }
   3555             // Validate the indices
   3556             if (startindex > endindex || startindex >= iMetaDataInfo->iNumTracks || endindex >= iMetaDataInfo->iNumTracks)
   3557             {
   3558                 continue;
   3559             }
   3560 
   3561             // Return a KVP for each index
   3562             for (uint32 i = startindex; i <= endindex; ++i)
   3563             {
   3564                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   3565                 {
   3566                     PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   3567 
   3568                     PvmiKvp trackkvp;
   3569                     trackkvp.key = NULL;
   3570 
   3571                     // Increment the counter for the number of values found so far
   3572                     ++numvalentries;
   3573                     // Add the value entry if past the starting index
   3574                     PVMFStatus retval = PVMFErrArgument;
   3575                     if (numvalentries > starting_index)
   3576                     {
   3577                         if (trackMetaDataInfo.iTrackDurationAvailable == true)
   3578                         {
   3579                             char indextimescaleparam[36];
   3580                             oscl_snprintf(indextimescaleparam, 36, ";%s%d;%s%d", PVMFSTREAMINGMGRNODE_INDEX, i, PVMFSTREAMINGMGRNODE_TIMESCALE, trackMetaDataInfo.iTrackDurationTimeScale);
   3581                             indextimescaleparam[35] = NULL_TERM_CHAR;
   3582 
   3583                             uint32 trackduration =
   3584                                 Oscl_Int64_Utils::get_uint64_lower32(trackMetaDataInfo.iTrackDuration);
   3585                             retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(trackkvp,
   3586                                      PVMFSTREAMINGMGRNODE_TRACKINFO_DURATION_KEY,
   3587                                      trackduration,
   3588                                      indextimescaleparam);
   3589                         }
   3590                         else
   3591                         {
   3592                             char indextimescaleparam[36];
   3593                             oscl_snprintf(indextimescaleparam, 36, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
   3594                             indextimescaleparam[35] = NULL_TERM_CHAR;
   3595 
   3596                             OSCL_StackString<32> unknownDuration(_STRLIT_CHAR("unknown"));
   3597                             PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForCharStringValue(trackkvp,
   3598                                                 PVMFSTREAMINGMGRNODE_TRACKINFO_DURATION_KEY,
   3599                                                 unknownDuration.get_cstr(),
   3600                                                 indextimescaleparam);
   3601                             if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3602                             {
   3603                                 break;
   3604                             }
   3605                         }
   3606 
   3607                     }
   3608 
   3609                     if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3610                     {
   3611                         break;
   3612                     }
   3613 
   3614                     if (trackkvp.key != NULL)
   3615                     {
   3616                         if (PVMFSuccess != PushKVPToMetadataValueList(valuelistptr, trackkvp))
   3617                         {
   3618                             OSCL_ARRAY_DELETE(trackkvp.key);
   3619                             trackkvp.key = NULL;
   3620                         }
   3621                         else
   3622                         {
   3623                             // Increment the value list entry counter
   3624                             ++numentriesadded;
   3625                         }
   3626 
   3627                         // Check if the max number of value entries were added
   3628                         if (max_entries > 0 && numentriesadded >= max_entries)
   3629                         {
   3630                             iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
   3631                             return PVMFSuccess;
   3632                         }
   3633                     }
   3634                 }
   3635             }
   3636         }
   3637         else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_SELECTED_KEY) != NULL)
   3638         {
   3639             // Track bitrate
   3640 
   3641             // Determine the index requested. Default to all tracks
   3642             uint32 startindex = 0;
   3643             uint32 endindex = iMetaDataInfo->iNumTracks - 1;
   3644             // Check if the index parameter is present
   3645             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
   3646             if (indexstr != NULL)
   3647             {
   3648                 // Retrieve the index values
   3649                 GetIndexParamValues(indexstr, startindex, endindex);
   3650             }
   3651             // Validate the indices
   3652             if (startindex > endindex || startindex >= iMetaDataInfo->iNumTracks || endindex >= iMetaDataInfo->iNumTracks)
   3653             {
   3654                 continue;
   3655             }
   3656 
   3657             // Return a KVP for each index
   3658             for (uint32 i = startindex; i <= endindex; ++i)
   3659             {
   3660                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   3661                 {
   3662                     PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   3663 
   3664                     PvmiKvp trackkvp;
   3665                     trackkvp.key = NULL;
   3666 
   3667                     // Increment the counter for the number of values found so far
   3668                     ++numvalentries;
   3669                     // Add the value entry if past the starting index
   3670                     PVMFStatus retval = PVMFErrArgument;
   3671                     if (numvalentries > starting_index)
   3672                     {
   3673                         char indexparam[16];
   3674                         oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
   3675 
   3676                         indexparam[15] = NULL_TERM_CHAR;
   3677 
   3678                         bool selected = trackMetaDataInfo.iTrackSelected;
   3679                         retval = PVMFCreateKVPUtils::CreateKVPForBoolValue(trackkvp,
   3680                                  PVMFSTREAMINGMGRNODE_TRACKINFO_SELECTED_KEY,
   3681                                  selected,
   3682                                  indexparam);
   3683                     }
   3684 
   3685                     if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3686                     {
   3687                         break;
   3688                     }
   3689 
   3690                     if (trackkvp.key != NULL)
   3691                     {
   3692                         if (PVMFSuccess != PushKVPToMetadataValueList(valuelistptr, trackkvp))
   3693                         {
   3694                             OSCL_ARRAY_DELETE(trackkvp.key);
   3695                             trackkvp.key = NULL;
   3696                         }
   3697                         else
   3698                         {
   3699                             // Increment the value list entry counter
   3700                             ++numentriesadded;
   3701                         }
   3702 
   3703                         // Check if the max number of value entries were added
   3704                         if (max_entries > 0 && numentriesadded >= max_entries)
   3705                         {
   3706                             iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
   3707                             return PVMFSuccess;
   3708                         }
   3709                     }
   3710                 }
   3711             }
   3712         }
   3713         else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_WIDTH_KEY) != NULL)
   3714         {
   3715             // Determine the index requested. Default to all tracks
   3716             uint32 startindex = 0;
   3717             uint32 endindex = iMetaDataInfo->iNumTracks - 1;
   3718             // Check if the index parameter is present
   3719             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
   3720             if (indexstr != NULL)
   3721             {
   3722                 // Retrieve the index values
   3723                 GetIndexParamValues(indexstr, startindex, endindex);
   3724             }
   3725             // Validate the indices
   3726             if (startindex > endindex || startindex >= iMetaDataInfo->iNumTracks || endindex >= iMetaDataInfo->iNumTracks)
   3727             {
   3728                 continue;
   3729             }
   3730 
   3731             // Return a KVP for each index
   3732             for (uint32 i = startindex; i <= endindex; ++i)
   3733             {
   3734                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   3735                 {
   3736                     PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   3737 
   3738                     PvmiKvp trackkvp;
   3739                     trackkvp.key = NULL;
   3740 
   3741                     // Increment the counter for the number of values found so far
   3742                     ++numvalentries;
   3743                     // Add the value entry if past the starting index
   3744                     PVMFStatus retval = PVMFErrArgument;
   3745                     if (numvalentries > starting_index)
   3746                     {
   3747                         char indexparam[16];
   3748                         oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
   3749                         indexparam[15] = NULL_TERM_CHAR;
   3750 
   3751                         retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(trackkvp,
   3752                                  PVMFSTREAMINGMGRNODE_TRACKINFO_WIDTH_KEY,
   3753                                  trackMetaDataInfo.iTrackWidth,
   3754                                  indexparam);
   3755                     }
   3756 
   3757                     if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3758                     {
   3759                         break;
   3760                     }
   3761 
   3762                     if (trackkvp.key != NULL)
   3763                     {
   3764                         if (PVMFSuccess != PushKVPToMetadataValueList(valuelistptr, trackkvp))
   3765                         {
   3766                             OSCL_ARRAY_DELETE(trackkvp.key);
   3767                             trackkvp.key = NULL;
   3768                         }
   3769                         else
   3770                         {
   3771                             // Increment the value list entry counter
   3772                             ++numentriesadded;
   3773                         }
   3774 
   3775                         // Check if the max number of value entries were added
   3776                         if (max_entries > 0 && numentriesadded >= max_entries)
   3777                         {
   3778                             iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
   3779                             return PVMFSuccess;
   3780                         }
   3781                     }
   3782                 }
   3783             }
   3784         }
   3785         else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_HEIGHT_KEY) != NULL)
   3786         {
   3787             // Determine the index requested. Default to all tracks
   3788             uint32 startindex = 0;
   3789             uint32 endindex = iMetaDataInfo->iNumTracks - 1;
   3790             // Check if the index parameter is present
   3791             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
   3792             if (indexstr != NULL)
   3793             {
   3794                 // Retrieve the index values
   3795                 GetIndexParamValues(indexstr, startindex, endindex);
   3796             }
   3797             // Validate the indices
   3798             if (startindex > endindex || startindex >= iMetaDataInfo->iNumTracks || endindex >= iMetaDataInfo->iNumTracks)
   3799             {
   3800                 continue;
   3801             }
   3802 
   3803             // Return a KVP for each index
   3804             for (uint32 i = startindex; i <= endindex; ++i)
   3805             {
   3806                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   3807                 {
   3808                     PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   3809 
   3810                     PvmiKvp trackkvp;
   3811                     trackkvp.key = NULL;
   3812 
   3813                     // Increment the counter for the number of values found so far
   3814                     ++numvalentries;
   3815                     // Add the value entry if past the starting index
   3816                     PVMFStatus retval = PVMFErrArgument;
   3817                     if (numvalentries > starting_index)
   3818                     {
   3819                         char indexparam[16];
   3820                         oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
   3821                         indexparam[15] = NULL_TERM_CHAR;
   3822 
   3823                         retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(trackkvp,
   3824                                  PVMFSTREAMINGMGRNODE_TRACKINFO_HEIGHT_KEY,
   3825                                  trackMetaDataInfo.iTrackHeight,
   3826                                  indexparam);
   3827                     }
   3828 
   3829                     if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3830                     {
   3831                         break;
   3832                     }
   3833 
   3834                     if (trackkvp.key != NULL)
   3835                     {
   3836                         if (PVMFSuccess != PushKVPToMetadataValueList(valuelistptr, trackkvp))
   3837                         {
   3838                             OSCL_ARRAY_DELETE(trackkvp.key);
   3839                             trackkvp.key = NULL;
   3840                         }
   3841                         else
   3842                         {
   3843                             // Increment the value list entry counter
   3844                             ++numentriesadded;
   3845                         }
   3846 
   3847                         // Check if the max number of value entries were added
   3848                         if (max_entries > 0 && numentriesadded >= max_entries)
   3849                         {
   3850                             iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
   3851                             return PVMFSuccess;
   3852                         }
   3853                     }
   3854                 }
   3855             }
   3856         }
   3857         else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_SAMPLERATE_KEY) != NULL)
   3858         {
   3859             // Determine the index requested. Default to all tracks
   3860             uint32 startindex = 0;
   3861             uint32 endindex = iMetaDataInfo->iNumTracks - 1;
   3862             // Check if the index parameter is present
   3863             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
   3864             if (indexstr != NULL)
   3865             {
   3866                 // Retrieve the index values
   3867                 GetIndexParamValues(indexstr, startindex, endindex);
   3868             }
   3869             // Validate the indices
   3870             if (startindex > endindex || startindex >= iMetaDataInfo->iNumTracks || endindex >= iMetaDataInfo->iNumTracks)
   3871             {
   3872                 continue;
   3873             }
   3874 
   3875             // Return a KVP for each index
   3876             for (uint32 i = startindex; i <= endindex; ++i)
   3877             {
   3878                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   3879                 {
   3880                     PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   3881 
   3882                     PvmiKvp trackkvp;
   3883                     trackkvp.key = NULL;
   3884 
   3885                     // Increment the counter for the number of values found so far
   3886                     ++numvalentries;
   3887                     // Add the value entry if past the starting index
   3888                     PVMFStatus retval = PVMFErrArgument;
   3889                     if (numvalentries > starting_index)
   3890                     {
   3891                         char indexparam[16];
   3892                         oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
   3893                         indexparam[15] = NULL_TERM_CHAR;
   3894 
   3895                         retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(trackkvp,
   3896                                  PVMFSTREAMINGMGRNODE_TRACKINFO_SAMPLERATE_KEY,
   3897                                  trackMetaDataInfo.iAudioSampleRate,
   3898                                  indexparam);
   3899                     }
   3900 
   3901                     if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3902                     {
   3903                         break;
   3904                     }
   3905 
   3906                     if (trackkvp.key != NULL)
   3907                     {
   3908                         if (PVMFSuccess != PushKVPToMetadataValueList(valuelistptr, trackkvp))
   3909                         {
   3910                             OSCL_ARRAY_DELETE(trackkvp.key);
   3911                             trackkvp.key = NULL;
   3912                         }
   3913                         else
   3914                         {
   3915                             // Increment the value list entry counter
   3916                             ++numentriesadded;
   3917                         }
   3918 
   3919                         // Check if the max number of value entries were added
   3920                         if (max_entries > 0 && numentriesadded >= max_entries)
   3921                         {
   3922                             iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
   3923                             return PVMFSuccess;
   3924                         }
   3925                     }
   3926                 }
   3927             }
   3928         }
   3929         else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_NUMCHANNELS_KEY) != NULL)
   3930         {
   3931             // Determine the index requested. Default to all tracks
   3932             uint32 startindex = 0;
   3933             uint32 endindex = iMetaDataInfo->iNumTracks - 1;
   3934             // Check if the index parameter is present
   3935             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
   3936             if (indexstr != NULL)
   3937             {
   3938                 // Retrieve the index values
   3939                 GetIndexParamValues(indexstr, startindex, endindex);
   3940             }
   3941             // Validate the indices
   3942             if (startindex > endindex || startindex >= iMetaDataInfo->iNumTracks || endindex >= iMetaDataInfo->iNumTracks)
   3943             {
   3944                 continue;
   3945             }
   3946 
   3947             // Return a KVP for each index
   3948             for (uint32 i = startindex; i <= endindex; ++i)
   3949             {
   3950                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   3951                 {
   3952                     PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   3953 
   3954                     PvmiKvp trackkvp;
   3955                     trackkvp.key = NULL;
   3956 
   3957                     // Increment the counter for the number of values found so far
   3958                     ++numvalentries;
   3959                     // Add the value entry if past the starting index
   3960                     PVMFStatus retval = PVMFErrArgument;
   3961                     if (numvalentries > starting_index)
   3962                     {
   3963                         char indexparam[16];
   3964                         oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
   3965                         indexparam[15] = NULL_TERM_CHAR;
   3966 
   3967                         retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(trackkvp,
   3968                                  PVMFSTREAMINGMGRNODE_TRACKINFO_NUMCHANNELS_KEY,
   3969                                  trackMetaDataInfo.iAudioNumChannels,
   3970                                  indexparam);
   3971                     }
   3972 
   3973                     if (retval != PVMFSuccess && retval != PVMFErrArgument)
   3974                     {
   3975                         break;
   3976                     }
   3977 
   3978                     if (trackkvp.key != NULL)
   3979                     {
   3980                         if (PVMFSuccess != PushKVPToMetadataValueList(valuelistptr, trackkvp))
   3981                         {
   3982                             OSCL_ARRAY_DELETE(trackkvp.key);
   3983                             trackkvp.key = NULL;
   3984                         }
   3985                         else
   3986                         {
   3987                             // Increment the value list entry counter
   3988                             ++numentriesadded;
   3989                         }
   3990 
   3991                         // Check if the max number of value entries were added
   3992                         if (max_entries > 0 && numentriesadded >= max_entries)
   3993                         {
   3994                             iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
   3995                             return PVMFSuccess;
   3996                         }
   3997                     }
   3998                 }
   3999             }
   4000         }
   4001         else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_AUDIO_BITS_PER_SAMPLE_KEY) != NULL)
   4002         {
   4003             // Determine the index requested. Default to all tracks
   4004             uint32 startindex = 0;
   4005             uint32 endindex = iMetaDataInfo->iNumTracks - 1;
   4006             // Check if the index parameter is present
   4007             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
   4008             if (indexstr != NULL)
   4009             {
   4010                 // Retrieve the index values
   4011                 GetIndexParamValues(indexstr, startindex, endindex);
   4012             }
   4013             // Validate the indices
   4014             if (startindex > endindex || startindex >= iMetaDataInfo->iNumTracks || endindex >= iMetaDataInfo->iNumTracks)
   4015             {
   4016                 continue;
   4017             }
   4018 
   4019             // Return a KVP for each index
   4020             for (uint32 i = startindex; i <= endindex; ++i)
   4021             {
   4022                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   4023                 {
   4024                     PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   4025 
   4026                     PvmiKvp trackkvp;
   4027                     trackkvp.key = NULL;
   4028 
   4029                     // Increment the counter for the number of values found so far
   4030                     ++numvalentries;
   4031                     // Add the value entry if past the starting index
   4032                     PVMFStatus retval = PVMFErrArgument;
   4033                     if (numvalentries > starting_index)
   4034                     {
   4035                         char indexparam[16];
   4036                         oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
   4037                         indexparam[15] = NULL_TERM_CHAR;
   4038 
   4039                         retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(trackkvp,
   4040                                  PVMFSTREAMINGMGRNODE_TRACKINFO_AUDIO_BITS_PER_SAMPLE_KEY,
   4041                                  trackMetaDataInfo.iAudioBitsPerSample,
   4042                                  indexparam);
   4043                     }
   4044 
   4045                     if (retval != PVMFSuccess && retval != PVMFErrArgument)
   4046                     {
   4047                         break;
   4048                     }
   4049 
   4050                     if (trackkvp.key != NULL)
   4051                     {
   4052                         if (PVMFSuccess != PushKVPToMetadataValueList(valuelistptr, trackkvp))
   4053                         {
   4054                             OSCL_ARRAY_DELETE(trackkvp.key);
   4055                             trackkvp.key = NULL;
   4056                         }
   4057                         else
   4058                         {
   4059                             // Increment the value list entry counter
   4060                             ++numentriesadded;
   4061                         }
   4062 
   4063                         // Check if the max number of value entries were added
   4064                         if (max_entries > 0 && numentriesadded >= max_entries)
   4065                         {
   4066                             iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
   4067                             return PVMFSuccess;
   4068                         }
   4069                     }
   4070                 }
   4071             }
   4072         }
   4073         else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_TRACKID_KEY) != NULL)
   4074         {
   4075             /* Codec Description */
   4076             /* Determine the index requested. Default to all tracks */
   4077             uint32 startindex = 0;
   4078             uint32 endindex = (uint32)iMetaDataInfo->iNumTracks - 1;
   4079             /* Check if the index parameter is present */
   4080             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
   4081             if (indexstr != NULL)
   4082             {
   4083                 /* Retrieve the index values */
   4084                 GetIndexParamValues(indexstr, startindex, endindex);
   4085             }
   4086             /* Validate the indices */
   4087             if (startindex > endindex || startindex >= iMetaDataInfo->iNumTracks || endindex >= iMetaDataInfo->iNumTracks)
   4088             {
   4089                 continue;
   4090             }
   4091             /* Return a KVP for each index */
   4092             for (uint32 i = startindex; i <= endindex; ++i)
   4093             {
   4094                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   4095                 {
   4096                     PVMFSMTrackMetaDataInfo trackInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   4097                     PvmiKvp trackkvp;
   4098                     trackkvp.key = NULL;
   4099                     /* Increment the counter for the number of values found so far */
   4100                     ++numvalentries;
   4101                     /* Add the value entry if past the starting index */
   4102                     PVMFStatus retval = PVMFErrArgument;
   4103                     if (numvalentries > (uint32)starting_index)
   4104                     {
   4105                         char indexparam[29];
   4106                         oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
   4107                         indexparam[15] = NULL_TERM_CHAR;
   4108                         retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(trackkvp,
   4109                                  PVMFSTREAMINGMGRNODE_TRACKINFO_TRACKID_KEY,
   4110                                  trackInfo.iTrackID,
   4111                                  indexparam);
   4112                     }
   4113                     if (retval != PVMFSuccess && retval != PVMFErrArgument)
   4114                     {
   4115                         break;
   4116                     }
   4117                     if (trackkvp.key != NULL)
   4118                     {
   4119                         if (PVMFSuccess != PushKVPToMetadataValueList(valuelistptr, trackkvp))
   4120                         {
   4121                             OSCL_ARRAY_DELETE(trackkvp.key);
   4122                             trackkvp.key = NULL;
   4123                         }
   4124                         else
   4125                         {
   4126                             // Increment the value list entry counter
   4127                             ++numentriesadded;
   4128                         }
   4129 
   4130                         // Check if the max number of value entries were added
   4131                         if (max_entries > 0 && numentriesadded >= max_entries)
   4132                         {
   4133                             iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
   4134                             return PVMFSuccess;
   4135                         }
   4136                     }
   4137                 }
   4138             }
   4139         }
   4140         else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_CLIP_TYPE_KEY) == 0)
   4141         {
   4142             /*
   4143              * Clip Type
   4144              * Increment the counter for the number of values found so far
   4145              */
   4146             ++numvalentries;
   4147 
   4148             /* Create a value entry if past the starting index */
   4149             if (numvalentries > (uint32)starting_index)
   4150             {
   4151                 uint32 len = 0;
   4152                 char* clipType = NULL;
   4153                 len = oscl_strlen("streaming");
   4154                 clipType = OSCL_ARRAY_NEW(char, len + 1);
   4155                 oscl_memset(clipType, 0, len + 1);
   4156                 oscl_strncpy(clipType, ("streaming"), len);
   4157                 PVMFStatus retval =
   4158                     PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal,
   4159                             PVMFSTREAMINGMGRNODE_CLIP_TYPE_KEY,
   4160                             clipType);
   4161 
   4162                 OSCL_ARRAY_DELETE(clipType);
   4163                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
   4164                 {
   4165                     break;
   4166                 }
   4167 
   4168             }
   4169         }
   4170         else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_FRAME_RATE_KEY) != NULL)
   4171         {
   4172             // Determine the index requested. Default to all tracks
   4173             uint32 startindex = 0;
   4174             uint32 endindex = iMetaDataInfo->iNumTracks - 1;
   4175             // Check if the index parameter is present
   4176             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
   4177             if (indexstr != NULL)
   4178             {
   4179                 // Retrieve the index values
   4180                 GetIndexParamValues(indexstr, startindex, endindex);
   4181             }
   4182             // Validate the indices
   4183             if (startindex > endindex || startindex >= iMetaDataInfo->iNumTracks || endindex >= iMetaDataInfo->iNumTracks)
   4184             {
   4185                 continue;
   4186             }
   4187 
   4188             // Return a KVP for each index
   4189             for (uint32 i = startindex; i <= endindex; ++i)
   4190             {
   4191                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   4192                 {
   4193                     PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   4194 
   4195                     PvmiKvp trackkvp;
   4196                     trackkvp.key = NULL;
   4197 
   4198                     // Increment the counter for the number of values found so far
   4199                     ++numvalentries;
   4200                     // Add the value entry if past the starting index
   4201                     PVMFStatus retval = PVMFErrArgument;
   4202                     if (numvalentries > starting_index)
   4203                     {
   4204                         char indexparam[16];
   4205                         oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
   4206                         indexparam[15] = NULL_TERM_CHAR;
   4207 
   4208                         retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(trackkvp,
   4209                                  PVMFSTREAMINGMGRNODE_TRACKINFO_FRAME_RATE_KEY,
   4210                                  trackMetaDataInfo.iVideoFrameRate,
   4211                                  indexparam);
   4212                     }
   4213 
   4214                     if (retval != PVMFSuccess && retval != PVMFErrArgument)
   4215                     {
   4216                         break;
   4217                     }
   4218 
   4219                     if (trackkvp.key != NULL)
   4220                     {
   4221                         if (PVMFSuccess != PushKVPToMetadataValueList(valuelistptr, trackkvp))
   4222                         {
   4223                             OSCL_ARRAY_DELETE(trackkvp.key);
   4224                             trackkvp.key = NULL;
   4225                         }
   4226                         else
   4227                         {
   4228                             // Increment the value list entry counter
   4229                             ++numentriesadded;
   4230                         }
   4231 
   4232                         // Check if the max number of value entries were added
   4233                         if (max_entries > 0 && numentriesadded >= max_entries)
   4234                         {
   4235                             iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
   4236                             return PVMFSuccess;
   4237                         }
   4238                     }
   4239                 }
   4240             }
   4241         }
   4242         else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_NAME_KEY) != NULL)
   4243         {
   4244             /* Codec Name */
   4245             /* Determine the index requested. Default to all tracks */
   4246             uint32 startindex = 0;
   4247             uint32 endindex = iMetaDataInfo->iNumTracks - 1;
   4248             /* Check if the index parameter is present */
   4249             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
   4250             if (indexstr != NULL)
   4251             {
   4252                 /* Retrieve the index values */
   4253                 GetIndexParamValues(indexstr, startindex, endindex);
   4254             }
   4255             /* Validate the indices */
   4256             if (startindex > endindex || startindex >= iMetaDataInfo->iNumTracks || endindex >= iMetaDataInfo->iNumTracks)
   4257             {
   4258                 continue;
   4259             }
   4260             /* Return a KVP for each index */
   4261             for (uint32 i = startindex; i <= endindex; ++i)
   4262             {
   4263                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   4264                 {
   4265 
   4266                     PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   4267 
   4268                     PvmiKvp trackkvp;
   4269                     trackkvp.key = NULL;
   4270                     /* Increment the counter for the number of values found so far */
   4271                     if (trackMetaDataInfo.iCodecName.get_size() > 0)
   4272                     {
   4273                         ++numvalentries;
   4274                     }
   4275                     /* Add the value entry if past the starting index */
   4276                     PVMFStatus retval = PVMFErrArgument;
   4277                     if (numvalentries > (uint32)starting_index)
   4278                     {
   4279                         char indexparam[29];
   4280                         oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
   4281                         indexparam[15] = NULL_TERM_CHAR;
   4282                         char* maxsizestr = OSCL_CONST_CAST(char*, oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_MAXSIZE));
   4283                         char* truncatestr = OSCL_CONST_CAST(char*, oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRUNCATE_FLAG));
   4284                         uint32 maxSize = 0xFFFFFFFF;
   4285                         if (maxsizestr != NULL)
   4286                         {
   4287                             if (GetMaxSizeValue(maxsizestr, maxSize) != PVMFSuccess)
   4288                             {
   4289                                 break;
   4290                             }
   4291                         }
   4292 
   4293                         uint32 truncateFlag = true;
   4294 
   4295                         if (truncatestr != NULL)
   4296                         {
   4297                             if (GetTruncateFlagValue(truncatestr, truncateFlag) != PVMFSuccess)
   4298                             {
   4299                                 break;
   4300                             }
   4301                         }
   4302 
   4303                         uint32 codecNameLen = trackMetaDataInfo.iCodecName.get_size();
   4304                         char maxsizemessage[13];
   4305                         maxsizemessage[0] = '\0';
   4306                         if (maxSize < codecNameLen)
   4307 
   4308                         {
   4309                             if (!truncateFlag)
   4310                             {
   4311                                 oscl_snprintf(maxsizemessage, 13, ";%s%d", PVMFSTREAMINGMGRNODE_REQSIZE, codecNameLen);
   4312                                 oscl_strncat(indexparam, maxsizemessage, oscl_strlen(maxsizemessage));
   4313                             }
   4314                         }
   4315 
   4316                         retval =
   4317                             PVMFCreateKVPUtils::CreateKVPForWStringValue(trackkvp,
   4318                                     PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_NAME_KEY,
   4319                                     (trackMetaDataInfo.iCodecName),
   4320                                     indexparam, maxSize, truncateFlag);
   4321                     }
   4322                     if (retval != PVMFSuccess && retval != PVMFErrArgument)
   4323                     {
   4324                         break;
   4325                     }
   4326                     if (trackkvp.key != NULL)
   4327                     {
   4328                         if (PVMFSuccess != PushKVPToMetadataValueList(valuelistptr, trackkvp))
   4329                         {
   4330                             OSCL_ARRAY_DELETE(trackkvp.key);
   4331                             trackkvp.key = NULL;
   4332                         }
   4333                         else
   4334                         {
   4335                             // Increment the value list entry counter
   4336                             ++numentriesadded;
   4337                         }
   4338 
   4339                         // Check if the max number of value entries were added
   4340                         if (max_entries > 0 && numentriesadded >= max_entries)
   4341                         {
   4342                             iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
   4343                             return PVMFSuccess;
   4344                         }
   4345                     }
   4346 
   4347                 }
   4348             }
   4349         }
   4350         else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_DESCRIPTION_KEY) != NULL)
   4351         {
   4352             /* Codec Description */
   4353             /* Determine the index requested. Default to all tracks */
   4354             uint32 startindex = 0;
   4355             uint32 endindex = (uint32)iMetaDataInfo->iNumTracks - 1;
   4356             /* Check if the index parameter is present */
   4357             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
   4358             if (indexstr != NULL)
   4359             {
   4360                 /* Retrieve the index values */
   4361                 GetIndexParamValues(indexstr, startindex, endindex);
   4362             }
   4363             /* Validate the indices */
   4364             if (startindex > endindex || startindex >= iMetaDataInfo->iNumTracks || endindex >= iMetaDataInfo->iNumTracks)
   4365             {
   4366                 continue;
   4367             }
   4368             /* Return a KVP for each index */
   4369             for (uint32 i = startindex; i <= endindex; ++i)
   4370             {
   4371                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   4372                 {
   4373                     PVMFSMTrackMetaDataInfo trackInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   4374                     PvmiKvp trackkvp;
   4375                     trackkvp.key = NULL;
   4376                     /* Increment the counter for the number of values found so far */
   4377                     if (trackInfo.iCodecDescription.get_size() > 0)
   4378                     {
   4379                         ++numvalentries;
   4380                     }
   4381                     /* Add the value entry if past the starting index */
   4382                     PVMFStatus retval = PVMFErrArgument;
   4383                     if (numvalentries > (uint32)starting_index)
   4384                     {
   4385                         char indexparam[29];
   4386                         oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
   4387                         indexparam[15] = NULL_TERM_CHAR;
   4388                         char* maxsizestr = OSCL_CONST_CAST(char*, oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_MAXSIZE));
   4389                         char* truncatestr = OSCL_CONST_CAST(char*, oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRUNCATE_FLAG));
   4390                         uint32 maxSize = 0xFFFFFFFF;
   4391                         if (maxsizestr != NULL)
   4392                         {
   4393                             if (GetMaxSizeValue(maxsizestr, maxSize) != PVMFSuccess)
   4394                             {
   4395                                 break;
   4396                             }
   4397                         }
   4398 
   4399                         uint32 truncateFlag = true;
   4400 
   4401                         if (truncatestr != NULL)
   4402                         {
   4403                             if (GetTruncateFlagValue(truncatestr, truncateFlag) != PVMFSuccess)
   4404                             {
   4405                                 break;
   4406                             }
   4407                         }
   4408 
   4409                         uint32 codecDescLen = trackInfo.iCodecDescription.get_size();
   4410                         char maxsizemessage[13];
   4411                         maxsizemessage[0] = '\0';
   4412                         if (maxSize < codecDescLen)
   4413                         {
   4414                             if (!truncateFlag)
   4415                             {
   4416                                 oscl_snprintf(maxsizemessage, 13, ";%s%d", PVMFSTREAMINGMGRNODE_REQSIZE, codecDescLen);
   4417                                 oscl_strncat(indexparam, maxsizemessage, oscl_strlen(maxsizemessage));
   4418                             }
   4419                         }
   4420 
   4421                         retval =
   4422                             PVMFCreateKVPUtils::CreateKVPForWStringValue(trackkvp,
   4423                                     PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_DESCRIPTION_KEY,
   4424                                     (trackInfo.iCodecDescription),
   4425                                     indexparam, maxSize, truncateFlag);
   4426                     }
   4427                     if (retval != PVMFSuccess && retval != PVMFErrArgument)
   4428                     {
   4429                         break;
   4430                     }
   4431                     if (trackkvp.key != NULL)
   4432                     {
   4433                         if (PVMFSuccess != PushKVPToMetadataValueList(valuelistptr, trackkvp))
   4434                         {
   4435                             OSCL_ARRAY_DELETE(trackkvp.key);
   4436                             trackkvp.key = NULL;
   4437                         }
   4438                         else
   4439                         {
   4440                             // Increment the value list entry counter
   4441                             ++numentriesadded;
   4442                         }
   4443 
   4444                         // Check if the max number of value entries were added
   4445                         if (max_entries > 0 && numentriesadded >= max_entries)
   4446                         {
   4447                             iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
   4448                             return PVMFSuccess;
   4449                         }
   4450                     }
   4451                 }
   4452             }
   4453         }
   4454         else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_DATA_KEY) != NULL)
   4455         {
   4456             /* Codec Description */
   4457             /* Determine the index requested. Default to all tracks */
   4458             uint32 startindex = 0;
   4459             uint32 endindex = (uint32)iMetaDataInfo->iNumTracks - 1;
   4460             /* Check if the index parameter is present */
   4461             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
   4462             if (indexstr != NULL)
   4463             {
   4464                 /* Retrieve the index values */
   4465                 GetIndexParamValues(indexstr, startindex, endindex);
   4466             }
   4467             /* Validate the indices */
   4468             if (startindex > endindex || startindex >= iMetaDataInfo->iNumTracks || endindex >= iMetaDataInfo->iNumTracks)
   4469             {
   4470                 continue;
   4471             }
   4472             /* Return a KVP for each index */
   4473             for (uint32 i = startindex; i <= endindex; ++i)
   4474             {
   4475                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   4476                 {
   4477                     PVMFSMTrackMetaDataInfo trackInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   4478                     PvmiKvp trackkvp;
   4479                     trackkvp.key = NULL;
   4480                     /* Increment the counter for the number of values found so far */
   4481                     if ((uint8*)(trackInfo.iCodecSpecificInfo.getMemFragPtr()))
   4482                     {
   4483                         ++numvalentries;
   4484                     }
   4485                     /* Add the value entry if past the starting index */
   4486                     PVMFStatus retval = PVMFErrArgument;
   4487                     if (numvalentries > (uint32)starting_index)
   4488                     {
   4489                         char indexparam[29];
   4490                         oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
   4491                         indexparam[15] = NULL_TERM_CHAR;
   4492                         retval =
   4493                             PVMFCreateKVPUtils::CreateKVPForByteArrayValue(trackkvp,
   4494                                     PVMFSTREAMINGMGRNODE_TRACKINFO_CODEC_DATA_KEY,
   4495                                     (uint8*)(trackInfo.iCodecSpecificInfo.getMemFragPtr()),
   4496                                     (uint32)trackInfo.iCodecSpecificInfo.getMemFragSize()
   4497                                     , indexparam);
   4498                     }
   4499                     if (retval != PVMFSuccess && retval != PVMFErrArgument)
   4500                     {
   4501                         break;
   4502                     }
   4503                     if (trackkvp.key != NULL)
   4504                     {
   4505                         if (PVMFSuccess != PushKVPToMetadataValueList(valuelistptr, trackkvp))
   4506                         {
   4507                             OSCL_ARRAY_DELETE(trackkvp.key);
   4508                             trackkvp.key = NULL;
   4509                         }
   4510                         else
   4511                         {
   4512                             // Increment the value list entry counter
   4513                             ++numentriesadded;
   4514                         }
   4515 
   4516                         // Check if the max number of value entries were added
   4517                         if (max_entries > 0 && numentriesadded >= max_entries)
   4518                         {
   4519                             iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
   4520                             return PVMFSuccess;
   4521                         }
   4522                     }
   4523                 }
   4524             }
   4525         }
   4526         else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMF_DRM_INFO_IS_PROTECTED_QUERY) == 0)
   4527                  && ((iUseCPMPluginRegistry == false) || (iSessionSourceInfo->iDRMProtected == false)))
   4528         {
   4529             /*
   4530              * is-protected
   4531              * Increment the counter for the number of values found so far
   4532              */
   4533             ++numvalentries;
   4534 
   4535             /* Create a value entry if past the starting index */
   4536             if (numvalentries > (uint32)starting_index)
   4537             {
   4538                 PVMFStatus retval =
   4539                     PVMFCreateKVPUtils::CreateKVPForBoolValue(KeyVal,
   4540                             PVMF_DRM_INFO_IS_PROTECTED_QUERY,
   4541                             iSessionSourceInfo->iDRMProtected,
   4542                             NULL);
   4543 
   4544                 if (retval != PVMFSuccess && retval != PVMFErrArgument)
   4545                 {
   4546                     break;
   4547                 }
   4548             }
   4549         }
   4550         else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_BITRATE_KEY) != NULL)
   4551         {
   4552             // Track bitrate
   4553 
   4554             // Determine the index requested. Default to all tracks
   4555             uint32 startindex = 0;
   4556             uint32 endindex = iMetaDataInfo->iNumTracks - 1;
   4557             // Check if the index parameter is present
   4558             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
   4559             if (indexstr != NULL)
   4560             {
   4561                 // Retrieve the index values
   4562                 GetIndexParamValues(indexstr, startindex, endindex);
   4563             }
   4564             // Validate the indices
   4565             if (startindex > endindex || startindex >= iMetaDataInfo->iNumTracks || endindex >= iMetaDataInfo->iNumTracks)
   4566             {
   4567                 continue;
   4568             }
   4569 
   4570             // Return a KVP for each index
   4571             for (uint32 i = startindex; i <= endindex; ++i)
   4572             {
   4573                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   4574                 {
   4575                     PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   4576 
   4577                     PvmiKvp trackkvp;
   4578                     trackkvp.key = NULL;
   4579 
   4580                     // Increment the counter for the number of values found so far
   4581                     ++numvalentries;
   4582                     // Add the value entry if past the starting index
   4583                     PVMFStatus retval = PVMFErrArgument;
   4584                     if (numvalentries > starting_index)
   4585                     {
   4586                         char indexparam[16];
   4587                         oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
   4588                         indexparam[15] = NULL_TERM_CHAR;
   4589 
   4590                         uint32 trackbitrate = trackMetaDataInfo.iTrackBitRate;
   4591                         retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(trackkvp,
   4592                                  PVMFSTREAMINGMGRNODE_TRACKINFO_BITRATE_KEY,
   4593                                  trackbitrate,
   4594                                  indexparam);
   4595                     }
   4596 
   4597                     if (retval != PVMFSuccess && retval != PVMFErrArgument)
   4598                     {
   4599                         break;
   4600                     }
   4601 
   4602                     if (trackkvp.key != NULL)
   4603                     {
   4604                         if (PVMFSuccess != PushKVPToMetadataValueList(valuelistptr, trackkvp))
   4605                         {
   4606                             OSCL_ARRAY_DELETE(trackkvp.key);
   4607                             trackkvp.key = NULL;
   4608                         }
   4609                         else
   4610                         {
   4611                             // Increment the value list entry counter
   4612                             ++numentriesadded;
   4613                         }
   4614 
   4615                         // Check if the max number of value entries were added
   4616                         if (max_entries > 0 && numentriesadded >= max_entries)
   4617                         {
   4618                             iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
   4619                             return PVMFSuccess;
   4620                         }
   4621                     }
   4622                 }
   4623             }
   4624         }
   4625         else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_TRACKINFO_MAX_BITRATE_KEY) != NULL)
   4626         {
   4627             // Track bitrate
   4628 
   4629             // Determine the index requested. Default to all tracks
   4630             uint32 startindex = 0;
   4631             uint32 endindex = iMetaDataInfo->iNumTracks - 1;
   4632             // Check if the index parameter is present
   4633             char* indexstr = OSCL_CONST_CAST(char*, oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMFSTREAMINGMGRNODE_INDEX));
   4634             if (indexstr != NULL)
   4635             {
   4636                 // Retrieve the index values
   4637                 GetIndexParamValues(indexstr, startindex, endindex);
   4638             }
   4639             // Validate the indices
   4640             if (startindex > endindex || startindex >= iMetaDataInfo->iNumTracks || endindex >= iMetaDataInfo->iNumTracks)
   4641             {
   4642                 continue;
   4643             }
   4644 
   4645             // Return a KVP for each index
   4646             for (uint32 i = startindex; i <= endindex; ++i)
   4647             {
   4648                 if (i < iMetaDataInfo->iTrackMetaDataInfoVec.size())
   4649                 {
   4650                     PVMFSMTrackMetaDataInfo trackMetaDataInfo = iMetaDataInfo->iTrackMetaDataInfoVec[i];
   4651 
   4652                     PvmiKvp trackkvp;
   4653                     trackkvp.key = NULL;
   4654                     uint32 trackbitrate = trackMetaDataInfo.iTrackMaxBitRate;
   4655                     if (trackbitrate > 0)
   4656                     {
   4657                         // Increment the counter for the number of values found so far
   4658                         ++numvalentries;
   4659                         // Add the value entry if past the starting index
   4660                         PVMFStatus retval = PVMFErrArgument;
   4661                         if (numvalentries > starting_index)
   4662                         {
   4663                             char indexparam[16];
   4664                             oscl_snprintf(indexparam, 16, ";%s%d", PVMFSTREAMINGMGRNODE_INDEX, i);
   4665                             indexparam[15] = NULL_TERM_CHAR;
   4666                             retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(trackkvp,
   4667                                      PVMFSTREAMINGMGRNODE_TRACKINFO_MAX_BITRATE_KEY,
   4668                                      trackbitrate,
   4669                                      indexparam);
   4670                         }
   4671 
   4672                         if (retval != PVMFSuccess && retval != PVMFErrArgument)
   4673                         {
   4674                             break;
   4675                         }
   4676 
   4677                         if (trackkvp.key != NULL)
   4678                         {
   4679                             if (PVMFSuccess != PushKVPToMetadataValueList(valuelistptr, trackkvp))
   4680                             {
   4681                                 OSCL_ARRAY_DELETE(trackkvp.key);
   4682                                 trackkvp.key = NULL;
   4683                             }
   4684                             else
   4685                             {
   4686                                 // Increment the value list entry counter
   4687                                 ++numentriesadded;
   4688                             }
   4689 
   4690                             // Check if the max number of value entries were added
   4691                             if (max_entries > 0 && numentriesadded >= max_entries)
   4692                             {
   4693                                 iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
   4694                                 return PVMFSuccess;
   4695                             }
   4696                         }
   4697                     }
   4698                 }
   4699             }
   4700         }
   4701 //Check with FSP
   4702         // Add the KVP to the list if the key string was created
   4703         if (KeyVal.key != NULL)
   4704         {
   4705             if (PVMFSuccess != PushKVPToMetadataValueList(valuelistptr, KeyVal))
   4706             {
   4707                 switch (GetValTypeFromKeyString(KeyVal.key))
   4708                 {
   4709                     case PVMI_KVPVALTYPE_CHARPTR:
   4710                         if (KeyVal.value.pChar_value != NULL)
   4711                         {
   4712                             OSCL_ARRAY_DELETE(KeyVal.value.pChar_value);
   4713                             KeyVal.value.pChar_value = NULL;
   4714                         }
   4715                         break;
   4716 
   4717                     default:
   4718                         // Add more case statements if other value types are returned
   4719                         break;
   4720                 }
   4721 
   4722                 OSCL_ARRAY_DELETE(KeyVal.key);
   4723                 KeyVal.key = NULL;
   4724             }
   4725             else
   4726             {
   4727                 // Increment the counter for number of value entries added to the list
   4728                 ++numentriesadded;
   4729             }
   4730 
   4731             // Check if the max number of value entries were added
   4732             if (max_entries > 0 && numentriesadded >= max_entries)
   4733             {
   4734                 // Maximum number of values added so break out of the loop
   4735                 break;
   4736             }
   4737         }
   4738     }
   4739 
   4740     iNoOfValuesPushedInValueVect = numentriesadded;
   4741     iNoOfValuesIteratedForValueVect = numvalentries;
   4742     iPVMFStreamingManagerNodeMetadataValueCount = (*valuelistptr).size();
   4743 
   4744 
   4745     if ((iCPMMetaDataExtensionInterface != NULL) &&
   4746             (iSessionSourceInfo->iDRMProtected  == true))
   4747     {
   4748         if (OSCL_STATIC_CAST(int32, iNoOfValuesPushedInValueVect) < max_entries)
   4749         {
   4750             uint32 cpmStartingIndex = 0;
   4751             uint32 cpmMaxEntries = max_entries - iNoOfValuesPushedInValueVect;
   4752 
   4753             if (iNoOfValuesIteratedForValueVect >= starting_index)
   4754             {
   4755                 cpmStartingIndex = 0;
   4756             }
   4757             else
   4758             {
   4759                 cpmStartingIndex = starting_index - iNoOfValuesIteratedForValueVect;
   4760             }
   4761             iCPMGetMetaDataValuesCmdId =
   4762                 iCPMMetaDataExtensionInterface->GetNodeMetadataValues(iCPMSessionID,
   4763                         (*keylistptr),
   4764                         (*valuelistptr),
   4765                         cpmStartingIndex,
   4766                         cpmMaxEntries
   4767                                                                      );
   4768             return PVMFPending;
   4769         }
   4770     }
   4771 
   4772 
   4773 
   4774     return PVMFSuccess;
   4775 }
   4776 
   4777 PVMFStatus PVMFSMFSPBaseNode::PushKVPToMetadataValueList(Oscl_Vector<PvmiKvp, OsclMemAllocator>* aValueList, const PvmiKvp& aKVP)const
   4778 {
   4779     PVMFStatus status = PVMFSuccess;
   4780     if (aValueList)
   4781     {
   4782         int32 leavecode = 0;
   4783         OSCL_TRY(leavecode, aValueList->push_back(aKVP));
   4784         OSCL_FIRST_CATCH_ANY(leavecode,
   4785                              PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFSMFSPBaseNode::PushKeyToMetadataList - Memory allocation failure when copying metadata key"));
   4786                              status = PVMFErrNoMemory);
   4787     }
   4788     else
   4789         status = PVMFErrArgument;
   4790     return status;
   4791 }
   4792 
   4793 PVMFStatus PVMFSMFSPBaseNode::GetMaxSizeValue(char* aString, uint32& aMaxSize)
   4794 {
   4795     aMaxSize = 0xFFFFFFFF;
   4796     /*
   4797      * This parses a string of the form "maxsize=N1" and extracts the integer N1.
   4798      */
   4799     if (aString == NULL)
   4800     {
   4801         return PVMFErrArgument;
   4802     }
   4803 
   4804     /* Go to end of "maxsize=" */
   4805     char* n1string = aString + 8;
   4806     char* truncatestr = OSCL_CONST_CAST(char*, oscl_strstr(n1string, PVMFSTREAMINGMGRNODE_TRUNCATE_FLAG));
   4807 
   4808     uint32 maxsizelen = 0;
   4809 
   4810     if (truncatestr != NULL)
   4811     {
   4812         maxsizelen = oscl_strlen(n1string) - (oscl_strlen(truncatestr) + 1);
   4813         n1string[maxsizelen] = '\0';
   4814     }
   4815 
   4816     if (PV_atoi(n1string, 'd', oscl_strlen(n1string), aMaxSize))
   4817     {
   4818         return PVMFSuccess;
   4819     }
   4820     return PVMFFailure;
   4821 }
   4822 
   4823 PVMFStatus PVMFSMFSPBaseNode::GetTruncateFlagValue(char* aString, uint32& aTruncateFlag)
   4824 {
   4825     aTruncateFlag = 0;
   4826     /*
   4827      * This parses a string of the form "truncate=N1" and extracts the integer N1.
   4828      */
   4829     if (aString == NULL)
   4830     {
   4831         return PVMFErrArgument;
   4832     }
   4833 
   4834     /* Go to end of "truncate=" */
   4835     char* n1string = aString + 9;
   4836 
   4837     if (!oscl_strcmp(n1string, "true"))
   4838     {
   4839         aTruncateFlag = true;
   4840     }
   4841     else if (!oscl_strcmp(n1string, "false"))
   4842     {
   4843         aTruncateFlag = false;
   4844     }
   4845     else
   4846     {
   4847         return PVMFFailure;
   4848     }
   4849     return PVMFSuccess;
   4850 
   4851 }
   4852 
   4853 void PVMFSMFSPBaseNode::HandleError(const PVMFCmdResp& aResponse)
   4854 {
   4855     PVMFSMFSPCommandContext *cmdContextData =
   4856         OSCL_REINTERPRET_CAST(PVMFSMFSPCommandContext*, aResponse.GetContext());
   4857     if (EPVMFNodeError != iInterfaceState)
   4858     {
   4859         if (cmdContextData) //It may be possible that cmdContextData == NULL for internal commands
   4860         {
   4861             OSCL_ASSERT(cmdContextData->parentCmd != PVMF_SMFSP_NODE_RESET);
   4862         }
   4863         SetState(EPVMFNodeError);
   4864         iChildNodeErrHandler->InitiateErrorHandling(aResponse);
   4865     }
   4866     else
   4867     {
   4868         iChildNodeErrHandler->CompleteErrorHandling(aResponse);
   4869     }
   4870 }
   4871 
   4872 void PVMFSMFSPBaseNode::ErrHandlingComplete(const PVMFSMFSPBaseNodeCommand* aErroneousCmd)
   4873 {
   4874     OSCL_ASSERT(iChildNodeErrHandler);
   4875     if (!iChildNodeErrHandler)
   4876     {
   4877         PVMF_SM_FSP_BASE_LOGERR((0, "PVMFSMFSPBaseNode::ErrHandlingComplete Error - iChildNodeErrHandler not available"));
   4878         return;
   4879     }
   4880     if (aErroneousCmd)
   4881     {
   4882         const PVMFCmdResp* const cmdResponse = iChildNodeErrHandler->GetErroneousCmdResponse();
   4883         OSCL_ASSERT(cmdResponse);
   4884         if (!cmdResponse)
   4885         {
   4886             PVMF_SM_FSP_BASE_LOGERR((0, "PVMFSMFSPBaseNode::ErrHandlingComplete Error - Command Response not available"));
   4887             return;
   4888         }
   4889 
   4890 
   4891         if (iCancelCommand.size() > 0)
   4892         {
   4893             //We got err during cancel command
   4894             if (PVMF_SMFSP_NODE_CANCELALLCOMMANDS == iCancelCommand.front().iCmd)
   4895             {
   4896                 if (!iCurrentCommand.empty())
   4897                 {
   4898                     if (IsInternalCmd(iCurrentCommand.front().iCmd) == false)
   4899                     {
   4900                         CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrCancelled);
   4901                     }
   4902                     else
   4903                     {
   4904                         InternalCommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrCancelled);
   4905                     }
   4906                 }
   4907 
   4908                 //Assumptions:
   4909                 //Command in front of cancel Q is cancel command.
   4910                 //None of commands in the input queue is hipri cmd, and hence are store in the order of their cmd id's
   4911                 //All commands in the input Q with command id < command id of the cancel command need to be completed
   4912                 //with cancelled status.
   4913                 const int32 cancelCmdId = iCancelCommand.front().iId;
   4914                 const int32 inputCmndsSz = iInputCommands.size();
   4915                 for (int ii = inputCmndsSz - 1; ii >= 0 ; ii--)
   4916                 {
   4917                     if (iInputCommands[ii].iId < cancelCmdId)
   4918                     {
   4919                         if (IsInternalCmd(iInputCommands[ii].iCmd))
   4920                         {
   4921                             InternalCommandComplete(iInputCommands, iInputCommands[ii], PVMFErrCancelled);
   4922                         }
   4923                         else
   4924                         {
   4925                             CommandComplete(iInputCommands, iInputCommands[ii], PVMFErrCancelled);
   4926                         }
   4927                     }
   4928                 }
   4929                 /* finally send command complete for the cancel all command */
   4930                 PVMF_SM_FSP_BASE_LOGERR((0, "PVMFSMFSPBaseNode::CompleteCancelAll - CancelAllCommands complete error"));
   4931                 bool eventDataLenAvailable = false;
   4932                 uint32 eventDataLength = 0;
   4933                 cmdResponse->GetEventDataLen(eventDataLenAvailable, eventDataLength);
   4934                 CommandComplete(iCancelCommand, iCancelCommand.front(), cmdResponse->GetCmdStatus(), cmdResponse->GetEventData(), NULL, NULL, cmdResponse->GetEventExtensionInterface(), eventDataLenAvailable ? eventDataLength : 0);
   4935             }
   4936             else if (PVMF_SMFSP_NODE_CANCELCOMMAND == iCancelCommand.front().iCmd)
   4937             {
   4938                 if (!iCurrentCommand.empty())
   4939                 {
   4940                     if (IsInternalCmd(iCurrentCommand.front().iCmd) == false)
   4941                     {
   4942                         CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrCancelled);
   4943                     }
   4944                     else
   4945                     {
   4946                         InternalCommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFErrCancelled);
   4947                     }
   4948                 }
   4949                 /* end command complete for the cancel all command */
   4950                 PVMF_SM_FSP_BASE_LOGERR((0, "PVMFSMFSPBaseNode::CompleteCancelAll - CancelCmd complete error"));
   4951                 bool eventDataLenAvailable = false;
   4952                 uint32 eventDataLength = 0;
   4953                 cmdResponse->GetEventDataLen(eventDataLenAvailable, eventDataLength);
   4954                 CommandComplete(iCancelCommand, iCancelCommand.front(), PVMFFailure, cmdResponse->GetEventData(), NULL, NULL, cmdResponse->GetEventExtensionInterface(), eventDataLenAvailable ? eventDataLength : 0);
   4955             }
   4956             else
   4957             {
   4958                 //Only commands in cancel Q can be cancel command/cancelall command,or some command entertained by CPM plugin.
   4959                 //Err handling logic is done only for the child nodes of the  SM node, CPM plugin is not handled by current err handling logic
   4960                 OSCL_ASSERT(false);
   4961             }
   4962         }
   4963         else
   4964         {
   4965             //We got err during command other than cancel command
   4966             //Command may be present in input command Q/current command Q
   4967             if (iCurrentCommand.size() > 0)
   4968             {
   4969                 if (IsInternalCmd(iCurrentCommand.front().iCmd))
   4970                 {
   4971                     //aErroneousCmd
   4972                     //We do not use the event data of cmd response and asyn event , becuas ewe cache the response/event and hence data may be dangling when we attempt to use it after caching.
   4973                     InternalCommandComplete(iCurrentCommand, iCurrentCommand.front(), cmdResponse->GetCmdStatus(), NULL, NULL, NULL, cmdResponse->GetEventExtensionInterface());
   4974                 }
   4975                 else
   4976                 {
   4977                     bool eventDataLenAvailable = false;
   4978                     uint32 eventDataLength = 0;
   4979                     cmdResponse->GetEventDataLen(eventDataLenAvailable, eventDataLength);
   4980                     CommandComplete(iCurrentCommand, iCurrentCommand.front(), cmdResponse->GetCmdStatus(), cmdResponse->GetEventData(), NULL, NULL, cmdResponse->GetEventExtensionInterface(), eventDataLenAvailable ? eventDataLength : 0);
   4981                 }
   4982             }
   4983             else
   4984             {
   4985                 if (IsInternalCmd(iInputCommands.front().iCmd))
   4986                 {
   4987                     //aErroneousCmd
   4988                     //We do not use the event data of cmd response and asyn event , becuas ewe cache the response/event and hence data may be dangling when we attempt to use it after caching.
   4989                     InternalCommandComplete(iInputCommands, iInputCommands.front(), cmdResponse->GetCmdStatus(), NULL, NULL, NULL, cmdResponse->GetEventExtensionInterface());
   4990                 }
   4991                 else
   4992                 {
   4993                     bool eventDataLenAvailable = false;
   4994                     uint32 eventDataLength = 0;
   4995                     cmdResponse->GetEventDataLen(eventDataLenAvailable, eventDataLength);
   4996                     CommandComplete(iInputCommands, iInputCommands.front(), cmdResponse->GetCmdStatus(), cmdResponse->GetEventData(), NULL, NULL, cmdResponse->GetEventExtensionInterface(), eventDataLenAvailable ? eventDataLength : 0);
   4997                 }
   4998             }
   4999         }
   5000     }
   5001     else
   5002     {
   5003         OSCL_ASSERT(iChildNodeErrHandler->GetAsyncErrEvent());
   5004         if (!iChildNodeErrHandler->GetAsyncErrEvent())
   5005             return;
   5006         else
   5007         {
   5008             PVMFAsyncEvent event = OSCL_CONST_CAST(PVMFAsyncEvent, *(iChildNodeErrHandler->GetAsyncErrEvent()));
   5009             PVMFNodeInterface::ReportErrorEvent(event);
   5010         }
   5011     }
   5012     iChildNodeErrHandler->Reset();
   5013     //remove commands from the input command Q
   5014     const int32 inputCmndsSz = iInputCommands.size();
   5015     if (inputCmndsSz > 0 && (!iInputCommands[0].hipri()))   //For command at index 0 is hipri, let the command complete asynchronously in next AO cycles.
   5016     {
   5017         for (int ii = 0; ii < inputCmndsSz ; ii++)
   5018         {
   5019             if (iInputCommands[ii].iCmd !=  PVMF_SMFSP_NODE_RESET)
   5020             {
   5021                 if (IsInternalCmd(iInputCommands[ii].iCmd))
   5022                 {
   5023                     InternalCommandComplete(iInputCommands, iInputCommands[ii], PVMFFailure);
   5024                 }
   5025                 else
   5026                 {
   5027                     CommandComplete(iInputCommands, iInputCommands[ii], PVMFFailure);
   5028                 }
   5029             }
   5030             else
   5031                 break;
   5032         }
   5033     }
   5034     if (IsAdded())
   5035     {
   5036         RunIfNotReady();
   5037     }
   5038 
   5039 }
   5040 
   5041 bool PVMFSMFSPBaseNode::SupressInfoEvent()
   5042 {
   5043     if ((iInterfaceState == EPVMFNodeError) ||
   5044             (!iCancelCommand.empty() || (iCurrentCommand.front().iCmd == PVMF_SMFSP_NODE_RESET)))
   5045     {
   5046         return true;
   5047     }
   5048     return false;
   5049 }
   5050 
   5051 ///////////////////////////////////////////////////////////////////////////////
   5052 //PVMFSMFSPChildNodeErrorHandler
   5053 ///////////////////////////////////////////////////////////////////////////////
   5054 PVMFSMFSPChildNodeErrorHandler* PVMFSMFSPChildNodeErrorHandler::CreateErrHandler(PVMFSMFSPBaseNode* aFSPBaseNode)
   5055 {
   5056     PVMFSMFSPChildNodeErrorHandler* errHandler = NULL;
   5057     int32 err;
   5058     OSCL_TRY(err,
   5059              errHandler = OSCL_NEW(PVMFSMFSPChildNodeErrorHandler, (aFSPBaseNode));
   5060              errHandler->Construct();
   5061             );
   5062     return errHandler;
   5063 }
   5064 
   5065 void PVMFSMFSPChildNodeErrorHandler::DeleteErrHandler(PVMFSMFSPChildNodeErrorHandler*& aErrHandler)
   5066 {
   5067     if (aErrHandler)
   5068         OSCL_DELETE(aErrHandler);
   5069     aErrHandler = NULL;
   5070 }
   5071 
   5072 void PVMFSMFSPChildNodeErrorHandler::InitiateErrorHandling(const PVMFCmdResp& aCmdResponse)
   5073 {
   5074     PVMF_SM_ERRHANDLER_LOGSTACKTRACE((0, "PVMFSMFSPChildNodeErrorHandler::InitiateErrorHandling In CmdId [%d]", aCmdResponse.GetCmdId()));
   5075     iCmdResponse = NULL;
   5076     SaveErrorInfo(aCmdResponse);
   5077     PerformErrorHandling();
   5078 }
   5079 
   5080 void PVMFSMFSPChildNodeErrorHandler::InitiateErrorHandling(const PVMFAsyncEvent& aAsyncEvent)
   5081 {
   5082     PVMF_SM_ERRHANDLER_LOGSTACKTRACE((0, "PVMFSMFSPChildNodeErrorHandler::InitiateErrorHandling In Event [%d]", aAsyncEvent.GetEventType()));
   5083     iAsyncEvent = NULL;
   5084     SaveErrorInfo(aAsyncEvent);
   5085     PerformErrorHandling();
   5086 }
   5087 
   5088 void PVMFSMFSPChildNodeErrorHandler::CompleteErrorHandling(const PVMFCmdResp& aResponse)    //called by NodeCommandCompleted
   5089 {
   5090     PVMF_SM_ERRHANDLER_LOGSTACKTRACE((0, "PVMFSMFSPChildNodeErrorHandler::CompleteErrorHandling In CmdId [%d] ErrHandlerState [%d]", aResponse.GetCmdId(), iState));
   5091     OSCL_UNUSED_ARG(aResponse);
   5092 
   5093     switch (iState)
   5094     {
   5095         case SMFSP_ERRHANDLER_WAITING_FOR_CANCEL_COMPLETION:
   5096         {
   5097             ContinueChildNodesCmdCancellation();
   5098         }
   5099         case SMFSP_ERRHANDLER_WAITING_FOR_CANCEL_DUE_TO_ERR_COMPLETION:
   5100         {
   5101             CompleteChildNodesCmdCancellationDueToErr();
   5102         }
   5103         break;
   5104         case SMFSP_ERRHANDLER_WAITING_FOR_RESET_DUE_TO_ERR_COMPLETION:
   5105         {
   5106             OSCL_ASSERT(aResponse.GetCmdStatus() != PVMFFailure);
   5107             CompleteChildNodesResetDueToError();
   5108         }
   5109         break;
   5110         default:
   5111             OSCL_ASSERT(false);
   5112     }
   5113 }
   5114 
   5115 void PVMFSMFSPChildNodeErrorHandler::Reset()
   5116 {
   5117     PVMF_SM_ERRHANDLER_LOGSTACKTRACE((0, "PVMFSMFSPChildNodeErrorHandler::Reset"));
   5118     bool eventDataLenAvailable = false;
   5119     uint32 eventDataLen = 0;
   5120     if (SMFSP_ERR_SOURCE_EVENT == iErrSource)
   5121     {
   5122         iAsyncEvent->GetEventDataLen(eventDataLenAvailable, eventDataLen);
   5123         if (iAsyncEvent)
   5124         {
   5125             if (eventDataLenAvailable)
   5126             {
   5127                 OSCL_ARRAY_DELETE(OSCL_STATIC_CAST(octet*, iAsyncEvent->GetEventData()));
   5128             }
   5129             if (iAsyncEvent->GetEventExtensionInterface())
   5130                 iAsyncEvent->GetEventExtensionInterface()->removeRef();
   5131             OSCL_DELETE(iAsyncEvent);
   5132             iAsyncEvent = NULL;
   5133         }
   5134     }
   5135     if (SMFSP_ERR_SOURCE_NODE_CMD_COMPLETION == iErrSource)
   5136     {
   5137         iCmdResponse->GetEventDataLen(eventDataLenAvailable, eventDataLen);
   5138         if (iCmdResponse)
   5139         {
   5140             if (eventDataLenAvailable)
   5141             {
   5142                 OSCL_ARRAY_DELETE(OSCL_STATIC_CAST(octet*, iCmdResponse->GetEventData()));
   5143             }
   5144             if (iCmdResponse->GetEventExtensionInterface())
   5145                 iCmdResponse->GetEventExtensionInterface()->removeRef();
   5146             OSCL_DELETE(iCmdResponse);
   5147             iCmdResponse = NULL;
   5148         }
   5149     }
   5150     iErrCmd = NULL;
   5151     if (iErroneousCmdResponse)
   5152         OSCL_DELETE(iErroneousCmdResponse);
   5153     iErrSource = SMFSP_ERR_SOURCE_INDETERMINATE;
   5154     iState = SMFSP_ERRHANDLER_IDLE;
   5155 }
   5156 
   5157 const PVMFCmdResp* PVMFSMFSPChildNodeErrorHandler::GetErroneousCmdResponse()
   5158 {
   5159     PVMF_SM_ERRHANDLER_LOGSTACKTRACE((0, "PVMFSMFSPChildNodeErrorHandler::GetErroneousCmdResponse [%x]", iErrCmd));
   5160     if (iErrCmd)
   5161         return iErroneousCmdResponse;
   5162     else
   5163         return NULL;
   5164 }
   5165 
   5166 const PVMFAsyncEvent* PVMFSMFSPChildNodeErrorHandler::GetAsyncErrEvent()
   5167 {
   5168     PVMF_SM_ERRHANDLER_LOGSTACKTRACE((0, "PVMFSMFSPChildNodeErrorHandler::GetAsyncErrEvent [%x]", iAsyncEvent));
   5169     if (SMFSP_ERR_SOURCE_EVENT == iErrSource)
   5170         return iAsyncEvent;
   5171     else
   5172         return NULL;
   5173 }
   5174 
   5175 
   5176 void PVMFSMFSPChildNodeErrorHandler::SaveErrorInfo(const PVMFCmdResp& aCmdResponse)
   5177 {
   5178     PVMF_SM_ERRHANDLER_LOGSTACKTRACE((0, "PVMFSMFSPChildNodeErrorHandler::SaveErrorInfo - ErrSource is Command Completion"));
   5179     iErrSource = SMFSP_ERR_SOURCE_NODE_CMD_COMPLETION;
   5180     if (!iCmdResponse)  //make deep copy of aCmdResponse, may be we can use the response info to persist event data too
   5181     {
   5182         bool eventDataLenAvailable = false;
   5183         uint32 eventDataLen = 0;
   5184         octet* eventData = OSCL_STATIC_CAST(octet*, aCmdResponse.GetEventData());
   5185         aCmdResponse.GetEventDataLen(eventDataLenAvailable, eventDataLen);
   5186         if (eventDataLenAvailable)
   5187         {
   5188             eventData = OSCL_ARRAY_NEW(octet, eventDataLen);
   5189             oscl_memcpy(eventData, aCmdResponse.GetEventData(), eventDataLen);
   5190             iCmdResponse = OSCL_NEW(PVMFCmdResp , (aCmdResponse.GetCmdId(), aCmdResponse.GetContext(), aCmdResponse.GetCmdStatus(), aCmdResponse.GetEventExtensionInterface(), eventData));
   5191             iCmdResponse->SetEventDataLen(eventDataLen);
   5192         }
   5193         else
   5194             iCmdResponse = OSCL_NEW(PVMFCmdResp , (aCmdResponse.GetCmdId(), aCmdResponse.GetContext(), aCmdResponse.GetCmdStatus(), aCmdResponse.GetEventExtensionInterface(), eventData));
   5195         if (iCmdResponse->GetEventExtensionInterface())
   5196             iCmdResponse->GetEventExtensionInterface()->addRef();
   5197     }
   5198 }
   5199 
   5200 void PVMFSMFSPChildNodeErrorHandler::SaveErrorInfo(const PVMFAsyncEvent& aAsyncEvent)
   5201 {
   5202     PVMF_SM_ERRHANDLER_LOGSTACKTRACE((0, "PVMFSMFSPChildNodeErrorHandler::SaveErrorInfo - ErrSource is Event"));
   5203     iErrSource = SMFSP_ERR_SOURCE_EVENT;
   5204     if (!iAsyncEvent) //make deep copy of aAsyncEvent, may be we can use the event info to persist event data too
   5205     {
   5206         bool eventDataLenAvailable = false;
   5207         uint32 eventDataLen = 0;
   5208         octet* eventData = OSCL_STATIC_CAST(octet*, aAsyncEvent.GetEventData());
   5209         aAsyncEvent.GetEventDataLen(eventDataLenAvailable, eventDataLen);
   5210         if (eventDataLenAvailable)
   5211         {
   5212             eventData = OSCL_ARRAY_NEW(octet, eventDataLen);
   5213             oscl_memcpy(eventData, aAsyncEvent.GetEventData(), eventDataLen);
   5214             iAsyncEvent = OSCL_NEW(PVMFAsyncEvent, (OSCL_CONST_CAST(PVMFAsyncEvent&, aAsyncEvent).IsA(), aAsyncEvent.GetEventType(), OSCL_CONST_CAST(OsclAny*, (aAsyncEvent.GetContext())), aAsyncEvent.GetEventExtensionInterface(), eventData, aAsyncEvent.GetLocalBuffer(), aAsyncEvent.GetLocalBufferSize()));
   5215             iAsyncEvent->SetEventDataLen(eventDataLen);
   5216         }
   5217         else
   5218             iAsyncEvent = OSCL_NEW(PVMFAsyncEvent, (OSCL_CONST_CAST(PVMFAsyncEvent&, aAsyncEvent).IsA(), aAsyncEvent.GetEventType(), OSCL_CONST_CAST(OsclAny*, (aAsyncEvent.GetContext())), aAsyncEvent.GetEventExtensionInterface(), eventData, aAsyncEvent.GetLocalBuffer(), aAsyncEvent.GetLocalBufferSize()));
   5219         if (iAsyncEvent->GetEventExtensionInterface())
   5220             iAsyncEvent->GetEventExtensionInterface()->addRef();
   5221     }
   5222 }
   5223 
   5224 void PVMFSMFSPChildNodeErrorHandler::PerformErrorHandling()
   5225 {
   5226     PVMF_SM_ERRHANDLER_LOGSTACKTRACE((0, "PVMFSMFSPChildNodeErrorHandler::PerformErrorHandling In"));
   5227     // Three Cases:
   5228     //Case 1: There is some comand in the command Q that was being processed and error occurs
   5229     //queue cancelduetoerr and cancelduetoreset in the error Q.
   5230     //Let the canceduetoerr and resetduetoerr complete
   5231     //Complete the pending command with error info
   5232 
   5233     //Case 2:There is some comand in the command Q that was being cancelled and error occurred while cancellation
   5234     //Let the cancel complete but do not report comepltion to observer of SM node.
   5235     //Queue the Resetduetoerr.
   5236     //Complete resetduetoerr and notify current command's completion to the obs of the SM node
   5237     //If the cancel command is CancelAll, notify command completion of all teh command in the input command Q, with command id < cmdid of cancelall
   5238     //Notify command completion of cance/cancelall to the obs of the SM node
   5239 
   5240 
   5241     //Case 3: There is no command in the current command Q and error was notified via error event
   5242     //queue resetduetoerr in the error Q.
   5243     //Let the resetduetoerr complete
   5244     //Report err event to observer
   5245 
   5246     if (iSMFSPNode->iCancelCommand.size() > 0)
   5247     {
   5248         iErrCmd = &(iSMFSPNode->iCancelCommand.front());
   5249     }
   5250     else if (iSMFSPNode->iCurrentCommand.size() > 0)
   5251     {
   5252         iErrCmd = &(iSMFSPNode->iCurrentCommand.front());
   5253     }
   5254 
   5255     if ((iErrSource == SMFSP_ERR_SOURCE_NODE_CMD_COMPLETION) && (NULL == iErrCmd))
   5256     {
   5257         iErrCmd = &(iSMFSPNode->iInputCommands.front());
   5258     }
   5259 
   5260     if (iErrCmd)
   5261     {
   5262         bool eventDataLenAvailable = false;
   5263         uint32 eventDataLength = 0;
   5264         if (SMFSP_ERR_SOURCE_EVENT == iErrSource)
   5265         {
   5266             iErroneousCmdResponse = OSCL_NEW(PVMFCmdResp, (iErrCmd->iId, iAsyncEvent->GetContext(), PVMFFailure, iAsyncEvent->GetEventExtensionInterface(), iAsyncEvent->GetEventData()));
   5267             iAsyncEvent->GetEventDataLen(eventDataLenAvailable, eventDataLength);
   5268             if (eventDataLenAvailable)
   5269                 iErroneousCmdResponse->SetEventDataLen(eventDataLength);
   5270         }
   5271         else
   5272         {
   5273             iErroneousCmdResponse = OSCL_NEW(PVMFCmdResp , (iCmdResponse->GetCmdId(), iCmdResponse->GetContext(), iCmdResponse->GetCmdStatus(), iCmdResponse->GetEventExtensionInterface(), iCmdResponse->GetEventData()));
   5274             iCmdResponse->GetEventDataLen(eventDataLenAvailable, eventDataLength);
   5275             if (eventDataLenAvailable)
   5276                 iErroneousCmdResponse->SetEventDataLen(eventDataLength);
   5277         }
   5278 
   5279         //Do we have any pending command with any of the child node?
   5280         bool hasPendingChildNodeCmd = false;
   5281         for (uint32 i = 0; i < iSMFSPNode->iFSPChildNodeContainerVec.size(); i++)
   5282         {
   5283             if (iSMFSPNode->iFSPChildNodeContainerVec[i].iNodeCmdState == PVMFSMFSP_NODE_CMD_PENDING)
   5284             {
   5285                 hasPendingChildNodeCmd = true;
   5286                 break;
   5287             }
   5288         }
   5289         if ((PVMF_SMFSP_NODE_CANCELALLCOMMANDS == iErrCmd->iCmd) || (PVMF_SMFSP_NODE_CANCELCOMMAND == iErrCmd->iCmd))
   5290         {
   5291             if (hasPendingChildNodeCmd)
   5292                 iState = SMFSP_ERRHANDLER_WAITING_FOR_CANCEL_COMPLETION;
   5293             else
   5294             {
   5295                 PVMFSessionId s = 0;
   5296                 PVMFSMFSPBaseNodeCommand cmdResetDueToErr;
   5297                 cmdResetDueToErr.PVMFSMFSPBaseNodeCommandBase::Construct(s,
   5298                         PVMF_SMFSP_NODE_RESET_DUE_TO_ERROR,
   5299                         NULL);
   5300                 iSMFSPNode->QueueErrHandlingCommandL(cmdResetDueToErr);
   5301                 iState = SMFSP_ERRHANDLER_WAITING_FOR_RESET_DUE_TO_ERR_COMPLETION;
   5302             }
   5303 
   5304         }
   5305         else
   5306         {
   5307             if (hasPendingChildNodeCmd)
   5308             {
   5309                 PVMFSessionId s = 0;
   5310                 PVMFSMFSPBaseNodeCommand cmdCancelPendingCmdDueToErr;
   5311                 cmdCancelPendingCmdDueToErr.PVMFSMFSPBaseNodeCommandBase::Construct(s,
   5312                         PVMF_SMFSP_NODE_CANCEL_DUE_TO_ERROR,
   5313                         NULL);
   5314                 iSMFSPNode->QueueErrHandlingCommandL(cmdCancelPendingCmdDueToErr);
   5315                 iState = SMFSP_ERRHANDLER_WAITING_FOR_CANCEL_DUE_TO_ERR_COMPLETION;
   5316             }
   5317             else
   5318             {
   5319                 PVMFSessionId s = 0;
   5320                 PVMFSMFSPBaseNodeCommand cmdResetDueToErr;
   5321                 cmdResetDueToErr.PVMFSMFSPBaseNodeCommandBase::Construct(s,
   5322                         PVMF_SMFSP_NODE_RESET_DUE_TO_ERROR,
   5323                         NULL);
   5324                 iSMFSPNode->QueueErrHandlingCommandL(cmdResetDueToErr);
   5325                 iState = SMFSP_ERRHANDLER_WAITING_FOR_RESET_DUE_TO_ERR_COMPLETION;
   5326             }
   5327         }
   5328     }
   5329     else
   5330     {
   5331         PVMFSessionId s = 0;
   5332         PVMFSMFSPBaseNodeCommand cmdResetDueToErr;
   5333         cmdResetDueToErr.PVMFSMFSPBaseNodeCommandBase::Construct(s,
   5334                 PVMF_SMFSP_NODE_RESET_DUE_TO_ERROR,
   5335                 NULL);
   5336         iSMFSPNode->QueueErrHandlingCommandL(cmdResetDueToErr);
   5337         iState = SMFSP_ERRHANDLER_WAITING_FOR_RESET_DUE_TO_ERR_COMPLETION;
   5338     }
   5339     PVMF_SM_ERRHANDLER_LOGSTACKTRACE((0, "PVMFSMFSPChildNodeErrorHandler::PerformErrorHandling Out iErrCmd - [%x] iState [%d]", iErrCmd, iState));
   5340 }
   5341 
   5342 void PVMFSMFSPChildNodeErrorHandler::ContinueChildNodesCmdCancellation()
   5343 {
   5344     PVMF_SM_ERRHANDLER_LOGSTACKTRACE((0, "PVMFSMFSPChildNodeErrorHandler::ContinueChildNodesCmdCancellation In"));
   5345     if (iSMFSPNode->CheckChildrenNodesCancelAll())
   5346     {
   5347         PVMF_SM_ERRHANDLER_LOGSTACKTRACE((0, "PVMFSMFSPChildNodeErrorHandler::ContinueChildNodesCmdCancellation - Q Reset Due To Err"));
   5348         PVMFSessionId s = 0;
   5349         PVMFSMFSPBaseNodeCommand cmdResetDueToErr;
   5350         cmdResetDueToErr.PVMFSMFSPBaseNodeCommandBase::Construct(s,
   5351                 PVMF_SMFSP_NODE_RESET_DUE_TO_ERROR,
   5352                 NULL);
   5353         iSMFSPNode->QueueErrHandlingCommandL(cmdResetDueToErr);
   5354         iState = SMFSP_ERRHANDLER_WAITING_FOR_RESET_DUE_TO_ERR_COMPLETION;
   5355     }
   5356 }
   5357 
   5358 void PVMFSMFSPChildNodeErrorHandler::CompleteChildNodesCmdCancellationDueToErr()
   5359 {
   5360     PVMF_SM_ERRHANDLER_LOGSTACKTRACE((0, "PVMFSMFSPChildNodeErrorHandler::CompleteChildNodesCmdCancellationDueToErr In"));
   5361     if (iSMFSPNode->CheckChildrenNodesCancelAll())
   5362     {
   5363         //There are two possible cases:
   5364         //- Before command for cancellation due to error could even be queued up, all the pending commands got completed.
   5365         //- Cancel due to error got completed
   5366         if ((iSMFSPNode->iErrHandlingCommandQ.size() > 0) && (PVMF_SMFSP_NODE_CANCEL_DUE_TO_ERROR == iSMFSPNode->iErrHandlingCommandQ.front().iCmd))
   5367         {
   5368             iSMFSPNode->iErrHandlingCommandQ.Erase(&iSMFSPNode->iErrHandlingCommandQ.front());
   5369             PVMFSessionId s = 0;
   5370             PVMFSMFSPBaseNodeCommand cmdResetDueToErr;
   5371             cmdResetDueToErr.PVMFSMFSPBaseNodeCommandBase::Construct(s,
   5372                     PVMF_SMFSP_NODE_RESET_DUE_TO_ERROR,
   5373                     NULL);
   5374             iSMFSPNode->QueueErrHandlingCommandL(cmdResetDueToErr);
   5375             iState = SMFSP_ERRHANDLER_WAITING_FOR_RESET_DUE_TO_ERR_COMPLETION;
   5376         }
   5377         else
   5378         {
   5379             PVMF_SM_ERRHANDLER_LOGSTACKTRACE((0, "PVMFSMFSPChildNodeErrorHandler::CompleteChildNodesCmdCancellationDueToErr- Cancellation complete"));
   5380             OSCL_ASSERT(iSMFSPNode->iCurrErrHandlingCommand.size() > 0 && (PVMF_SMFSP_NODE_CANCEL_DUE_TO_ERROR == iSMFSPNode->iCurrErrHandlingCommand.front().iCmd));
   5381             ErrHandlingCommandComplete(iSMFSPNode->iCurrErrHandlingCommand, iSMFSPNode->iCurrErrHandlingCommand.front(), PVMFSuccess);
   5382         }
   5383     }
   5384     return;
   5385 }
   5386 
   5387 void PVMFSMFSPChildNodeErrorHandler::CompleteChildNodesResetDueToError()
   5388 {
   5389     PVMF_SM_ERRHANDLER_LOGSTACKTRACE((0, "PVMFSMFSPChildNodeErrorHandler::CompleteChildNodesResetDueToErrorIn"));
   5390     if (iSMFSPNode->CheckChildrenNodesReset() && iSMFSPNode->iDRMResetPending == false)
   5391     {
   5392         PVMF_SM_ERRHANDLER_LOGSTACKTRACE((0, "PVMFSMFSPChildNodeErrorHandler::CompleteChildNodesResetDueToErrorIn - Restting Child Nodes complete %d", iSMFSPNode->iDRMResetPending));
   5393         OSCL_ASSERT(iSMFSPNode->iCurrErrHandlingCommand.size() > 0 && (iSMFSPNode->iCurrErrHandlingCommand.front().iCmd == PVMF_SMFSP_NODE_RESET_DUE_TO_ERROR));
   5394         ErrHandlingCommandComplete(iSMFSPNode->iCurrErrHandlingCommand, iSMFSPNode->iCurrErrHandlingCommand.front(), PVMFSuccess);
   5395     }
   5396 }
   5397 
   5398 
   5399 void PVMFSMFSPChildNodeErrorHandler::ErrHandlingCommandComplete(PVMFFSPNodeCmdQ& aCmdQ,
   5400         PVMFSMFSPBaseNodeCommand& aCmd,
   5401         PVMFStatus aStatus,
   5402         OsclAny* aData,
   5403         PVUuid* aEventUUID,
   5404         int32* aEventCode,
   5405         PVInterface* aExtMsg)
   5406 {
   5407     OSCL_UNUSED_ARG(aStatus);
   5408     OSCL_UNUSED_ARG(aData);
   5409     OSCL_UNUSED_ARG(aEventUUID);
   5410     OSCL_UNUSED_ARG(aEventCode);
   5411     OSCL_UNUSED_ARG(aExtMsg);
   5412 
   5413     PVMF_SM_ERRHANDLER_LOGSTACKTRACE((0, "PVMFSMFSPChildNodeErrorHandler::ErrHandlingCommandComplete In iCmd[%d]", aCmd.iCmd));
   5414     switch (aCmd.iCmd)
   5415     {
   5416         case PVMF_SMFSP_NODE_CANCEL_DUE_TO_ERROR:
   5417         {
   5418             PVMF_SM_ERRHANDLER_LOGDEBUG((0, "PVMFSMFSPChildNodeErrorHandler::ErrHandlingCommandComplete Queing Reset Due To Err"));
   5419             PVMFSessionId s = 0;
   5420             PVMFSMFSPBaseNodeCommand cmdResetDueToErr;
   5421             cmdResetDueToErr.PVMFSMFSPBaseNodeCommandBase::Construct(s,
   5422                     PVMF_SMFSP_NODE_RESET_DUE_TO_ERROR,
   5423                     NULL);
   5424             iSMFSPNode->QueueErrHandlingCommandL(cmdResetDueToErr);
   5425             iState = SMFSP_ERRHANDLER_WAITING_FOR_RESET_DUE_TO_ERR_COMPLETION;
   5426         }
   5427         break;
   5428         case PVMF_SMFSP_NODE_RESET_DUE_TO_ERROR:
   5429         {
   5430             PVMF_SM_ERRHANDLER_LOGDEBUG((0, "PVMFSMFSPChildNodeErrorHandler::ErrHandlingCommandComplete - Reset Due To Err completed"));
   5431 
   5432             //Do command completion or notify err event
   5433             iState = SMFSP_ERRHANDLER_IDLE; //error handling complete
   5434             iSMFSPNode->CompleteResetDueToErr();
   5435             iSMFSPNode->ErrHandlingComplete(iErrCmd);
   5436         }
   5437         break;
   5438     }
   5439 
   5440     /* Erase the command from the queue */
   5441     aCmdQ.Erase(&aCmd);
   5442 
   5443     /* Reschedule AO if input command queue is not empty */
   5444     if (!iSMFSPNode->iErrHandlingCommandQ.empty() && iSMFSPNode->IsAdded())
   5445     {
   5446         iSMFSPNode->RunIfNotReady();
   5447     }
   5448 }
   5449 
   5450 ///////////////////////////////////////////////////////////////////////////////
   5451 //PVMFSMNodeKVPStore
   5452 ///////////////////////////////////////////////////////////////////////////////
   5453 PVMFStatus PVMFSMNodeKVPStore::addKVPString(const char* aKeyTypeString, OSCL_wString& aValString)
   5454 {
   5455     PvmiKvp aKeyVal;
   5456     aKeyVal.key = NULL;
   5457     PVMFStatus status = PVMFCreateKVPUtils::CreateKVPForWStringValue(aKeyVal, aKeyTypeString, aValString);
   5458     if (status != PVMFSuccess) return status;
   5459     KVPValueTypeForMemoryRelease valType = KVPValueTypeForMemoryRelease_WString;
   5460     return pushKVPToVector(aKeyVal, valType);
   5461 }
   5462 
   5463 // add kvp string with normal string value
   5464 PVMFStatus PVMFSMNodeKVPStore::addKVPString(const char* aKeyTypeString, const char* aValString)
   5465 {
   5466     PvmiKvp aKeyVal;
   5467     aKeyVal.key = NULL;
   5468     PVMFStatus status = PVMFCreateKVPUtils::CreateKVPForCharStringValue(aKeyVal, aKeyTypeString, aValString);
   5469     if (status != PVMFSuccess) return status;
   5470     KVPValueTypeForMemoryRelease valType = KVPValueTypeForMemoryRelease_String;
   5471     return pushKVPToVector(aKeyVal, valType);
   5472 }
   5473 
   5474 void PVMFSMNodeKVPStore::releaseMemory()
   5475 {
   5476     OSCL_ASSERT(iKvpVector.size() == iKVPValueTypeForMemoryRelease.size());
   5477 
   5478     for (uint32 i = 0; i < iKvpVector.size(); i++)
   5479     {
   5480         if (iKvpVector[i].key) OSCL_ARRAY_DELETE(iKvpVector[i].key);
   5481 
   5482         // release memory for appropriate types of KVP value
   5483         if ((KVPValueTypeForMemoryRelease)iKVPValueTypeForMemoryRelease[i] == KVPValueTypeForMemoryRelease_WString &&
   5484                 iKvpVector[i].value.pWChar_value) OSCL_ARRAY_DELETE(iKvpVector[i].value.pWChar_value);
   5485         if ((KVPValueTypeForMemoryRelease)iKVPValueTypeForMemoryRelease[i] == KVPValueTypeForMemoryRelease_String &&
   5486                 iKvpVector[i].value.pChar_value) OSCL_ARRAY_DELETE(iKvpVector[i].value.pChar_value);
   5487     }
   5488 }
   5489 
   5490 PVMFStatus PVMFSMNodeKVPStore::addKVPuint32Value(const char* aKeyTypeString, uint32 aValue)
   5491 {
   5492     PvmiKvp aKeyVal;
   5493     aKeyVal.key = NULL;
   5494     PVMFStatus status = PVMFCreateKVPUtils::CreateKVPForUInt32Value(aKeyVal, aKeyTypeString, aValue);
   5495     if (status != PVMFSuccess) return status;
   5496     KVPValueTypeForMemoryRelease valType = KVPValueTypeForMemoryRelease_NoInterest;
   5497     return pushKVPToVector(aKeyVal, valType);
   5498 }
   5499 
   5500 PVMFStatus PVMFSMNodeKVPStore::pushKVPToVector(const PvmiKvp& aKeyVal, const KVPValueTypeForMemoryRelease& aValueTypeForMemoryRelease)
   5501 {
   5502     int32 err = 0;
   5503     OSCL_TRY(err,
   5504              iKvpVector.push_back(aKeyVal);
   5505              iKVPValueTypeForMemoryRelease.push_back(OSCL_STATIC_CAST(uint32, aValueTypeForMemoryRelease));
   5506             );
   5507     return (err == 0 ? PVMFSuccess : PVMFErrNoMemory);
   5508 }
   5509 
   5510