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

#include "pvmf_clientserver_socket_node.h"
#include "oscl_string_utils.h"
#include "pvmf_basic_errorinfomessage.h"
#include "pvmf_errorinfomessage_extension.h"
#include "oscl_byte_order.h"
#include "pvmf_media_cmd.h"
#include "pvmf_media_msg_format_ids.h"
#include "oscl_tickcount.h"
#include "oscl_rand.h"
#include "oscl_time.h"
#include "oscl_bin_stream.h"

// Use default DLL entry point for Symbian
#include "oscl_dll.h"

//////////////////////////////////////////////////
// Standard Node APIs
//////////////////////////////////////////////////

OSCL_EXPORT_REF PVMFClientServerSocketNode::PVMFClientServerSocketNode(OsclTCPSocket* aSocketHandle, int32 aPriority)
        : OsclActiveObject(aPriority, "PVMFClientServerSocketNode")
        , iSockServ(NULL)
        , TIMEOUT_CONNECT(-1)
        , TIMEOUT_SEND(-1)
        , TIMEOUT_RECV(-1)
        , TIMEOUT_SHUTDOWN(-1)
        , iSocketHandle(aSocketHandle)
        , iSockConfig(NULL)
{
    iLogger = NULL;
    iDataPathLogger = NULL;
    iOsclErrorTrapImp = NULL;
    iExtensionRefCount = 0;
    iMaxTcpRecvBufferSize = SNODE_DEFAULT_SOCKET_TCP_BUFFER_SIZE;
    iMaxTcpRecvBufferCount = SNODE_DEFAULT_SOCKET_TCP_BUFFER_COUNT;
    iSocketID = 0;
    iCommandErrorCode = PVMFSocketNodeErrorEventStart;
    iErrorEventErrorCode = PVMFSocketNodeErrorEventStart;

    iPVMFPort = NULL;
    iNumStopPortActivityPending = (-1);//inactive.

    int32 err;
    OSCL_TRY(err,

             iPendingCmdQueue.Construct(PVMF_SOCKET_NODE_COMMAND_ID_START,
                                        PVMF_SOCKET_NODE_COMMAND_VECTOR_RESERVE);

             //Create the "current command" queue.  It will only contain one
             //command at a time, so use a reserve of 1.
             iCurrentCmdQueue.Construct(0, 1);
             iCancelCmdQueue.Construct(0, 1);
            );

    if (err != OsclErrNone)
    {
        //if a leave happened, cleanup and re-throw the error
        iPendingCmdQueue.clear();
        iCurrentCmdQueue.clear();
        iCancelCmdQueue.clear();
        if (iPVMFPort)
        {
            iPVMFPort->Disconnect();
            delete iPVMFPort;
            iPVMFPort = NULL;
        }
        OSCL_CLEANUP_BASE_CLASS(PVMFNodeInterface);
        OSCL_CLEANUP_BASE_CLASS(OsclActiveObject);
        OSCL_LEAVE(err);
    }
}


OSCL_EXPORT_REF PVMFClientServerSocketNode::~PVMFClientServerSocketNode()
{
    Cancel();

    //thread logoff
    if (IsAdded())
        RemoveFromScheduler();

    /* Cleanup allocated ports */
    CleanupPorts();

    //Cleanup commands
    while (!iCurrentCmdQueue.empty())
    {
        CommandComplete(iCurrentCmdQueue, iCurrentCmdQueue.front(), PVMFFailure);
    }
    while (!iPendingCmdQueue.empty())
    {
        CommandComplete(iPendingCmdQueue, iPendingCmdQueue.front(), PVMFFailure);
    }
    while (!iCancelCmdQueue.empty())
    {
        CommandComplete(iCancelCmdQueue, iCancelCmdQueue.front(), PVMFFailure);
    }
}


OSCL_EXPORT_REF PVMFStatus PVMFClientServerSocketNode::ThreadLogon()
{
    switch (iInterfaceState)
    {
        case EPVMFNodeCreated:
            if (!IsAdded())
                AddToScheduler();
            iLogger = PVLogger::GetLoggerObject("PVMFClientServerSocketNode");
            iDataPathLogger = PVLogger::GetLoggerObject("datapath.socketnode");
            iOsclErrorTrapImp = OsclErrorTrap::GetErrorTrapImp();
            SetState(EPVMFNodeIdle);
            return PVMFSuccess;
        default:
            return PVMFErrInvalidState;
    }
}


OSCL_EXPORT_REF PVMFStatus PVMFClientServerSocketNode::ThreadLogoff()
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:ThreadLogoff"));

    switch (iInterfaceState)
    {
        case EPVMFNodeIdle:
        {
            if (IsAdded())
                RemoveFromScheduler();
            iLogger = NULL;
            iDataPathLogger = NULL;
            iOsclErrorTrapImp = NULL;
            SetState(EPVMFNodeCreated);
            return PVMFSuccess;
        }
        default:
            return PVMFErrInvalidState;
    }
}


OSCL_EXPORT_REF PVMFStatus PVMFClientServerSocketNode::GetCapability(PVMFNodeCapability& aNodeCapability)
{
    OSCL_UNUSED_ARG(aNodeCapability);
    return PVMFSuccess;
}

OSCL_EXPORT_REF PVMFPortIter* PVMFClientServerSocketNode::GetPorts(const PVMFPortFilter* aFilter)
{
    OSCL_UNUSED_ARG(aFilter);
    //retrive a port iterator
    return (PVMFPortIter*)iPVMFPort;
}

OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::QueryUUID(PVMFSessionId s, const PvmfMimeString& aMimeType,
        Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids,
        bool aExactUuidsOnly,
        const OsclAny* aContext)
{
    PVMFSocketNodeCommand cmd;
    cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_QUERYUUID, aMimeType, aUuids, aExactUuidsOnly, aContext);
    return QueueCommandL(cmd);
}

OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::QueryInterface(PVMFSessionId s, const PVUuid& aUuid,
        PVInterface*& aInterfacePtr,
        const OsclAny* aContext)
{
    PVMFSocketNodeCommand cmd;
    cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_QUERYINTERFACE, aUuid, aInterfacePtr, aContext);
    return QueueCommandL(cmd);
}

OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::RequestPort(PVMFSessionId s, int32 aPortTag, const PvmfMimeString* aPortConfig, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:RequestPort"));
    PVMFSocketNodeCommand cmd;
    cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_REQUESTPORT, aPortTag, aPortConfig, aContext);
    return QueueCommandL(cmd);
}

OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::ReleasePort(PVMFSessionId s, PVMFPortInterface& aPort, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:ReleasePort"));
    PVMFSocketNodeCommand cmd;
    cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_RELEASEPORT, aPort, aContext);
    return QueueCommandL(cmd);
}

OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::Init(PVMFSessionId s, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:Init"));
    PVMFSocketNodeCommand cmd;
    cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_INIT, aContext);
    return QueueCommandL(cmd);
}

OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::Prepare(PVMFSessionId s, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:Init"));
    PVMFSocketNodeCommand cmd;
    cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_PREPARE, aContext);
    return QueueCommandL(cmd);
}

OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::Start(PVMFSessionId s, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:Start"));
    PVMFSocketNodeCommand cmd;
    cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_START, aContext);
    return QueueCommandL(cmd);
}

OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::Stop(PVMFSessionId s, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:Stop"));
    PVMFSocketNodeCommand cmd;
    cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_STOP, aContext);
    return QueueCommandL(cmd);
}

OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::Flush(PVMFSessionId s, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:Flush"));
    PVMFSocketNodeCommand cmd;
    cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_FLUSH, aContext);
    return QueueCommandL(cmd);
}

OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::Pause(PVMFSessionId s, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:Pause"));
    PVMFSocketNodeCommand cmd;
    cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_PAUSE, aContext);
    return QueueCommandL(cmd);
}

OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::Reset(PVMFSessionId s, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:Reset"));
    PVMFSocketNodeCommand cmd;
    cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_RESET, aContext);
    return QueueCommandL(cmd);
}

OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::CancelAllCommands(PVMFSessionId s, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:CancelAllCommands"));
    PVMFSocketNodeCommand cmd;
    cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_CANCELALLCOMMANDS, aContext);
    return QueueCommandL(cmd);
}

OSCL_EXPORT_REF PVMFCommandId PVMFClientServerSocketNode::CancelCommand(PVMFSessionId s, PVMFCommandId aCmdId, const OsclAny* aContext)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:CancelCommand"));
    PVMFSocketNodeCommand cmd;
    cmd.PVMFSocketNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_CANCELCOMMAND, aCmdId, aContext);
    return QueueCommandL(cmd);
}

//Port activity handler
void PVMFClientServerSocketNode::HandlePortActivity(const PVMFPortActivity &aActivity)
{
    PVMFClientServerSocketPort* sockPort = NULL;
    switch (aActivity.iType)
    {
        case PVMF_PORT_ACTIVITY_CONNECT:
        {
            sockPort = OSCL_STATIC_CAST(PVMFClientServerSocketPort*, aActivity.iPort);
            OSCL_ASSERT(sockPort && sockPort->iConfig);
            *iSockConfig = *sockPort->iConfig;

            setSocketPortMemAllocator(aActivity.iPort, sockPort->iAllocSharedPtr);

            //Receives may have been blocked waiting on the port to be connected, so check here.
            if (CanReceive())
                StartRecvOperation();
        }
        break;

        case PVMF_PORT_ACTIVITY_INCOMING_MSG:
        {
            sockPort = (PVMFClientServerSocketPort*)(aActivity.iPort);
            OSCL_ASSERT(sockPort && sockPort->iConfig);

            //Try to process this message now.
            if (CanProcessIncomingMsg())
                ProcessIncomingMsg();
            //Otherwise, ignore this event now.  Other code will check
            //the input queue as needed.
        }
        break;

        case PVMF_PORT_ACTIVITY_CONNECTED_PORT_READY:
        {
            sockPort = (PVMFClientServerSocketPort*)(aActivity.iPort);
            OSCL_ASSERT(sockPort && sockPort->iConfig);
            SocketPortConfig& aSockConfig = *sockPort->iConfig;

            if (aSockConfig.iState.iRecvOperation == EPVSocketPortRecvOperation_WaitOnConnectedPort)
            {
                RecvOperationComplete(PVMFSuccess, NULL);
            }

            //Otherwise ignore this event now.  Other code will check connected
            //port status as needed.
        }
        break;

        default:
            //all other events can be ignored.
            break;
    }
}


OSCL_EXPORT_REF void PVMFClientServerSocketNode::addRef()
{
    ++iExtensionRefCount;
}

OSCL_EXPORT_REF void PVMFClientServerSocketNode::removeRef()
{
    --iExtensionRefCount;
}

OSCL_EXPORT_REF bool PVMFClientServerSocketNode::queryInterface(const PVUuid& uuid, PVInterface*& iface)
{
    OSCL_UNUSED_ARG(uuid);
    OSCL_UNUSED_ARG(iface);
    return false;
}

void PVMFClientServerSocketNode::Run()
{
    //Process node commands
    while (CanProcessCommand())
        ProcessCommand(iPendingCmdQueue, iPendingCmdQueue.front());
}


bool PVMFClientServerSocketNode::CanProcessCommand()
{
    return (!iPendingCmdQueue.empty()
            && (iCurrentCmdQueue.empty()
                || (iPendingCmdQueue.front().hipri() && iCancelCmdQueue.empty())));
}

//Process an input command.
void PVMFClientServerSocketNode::ProcessCommand(PVMFSocketNodeCmdQ& aCmdQ, PVMFSocketNodeCommand& aCmd)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFSocketNodeCommand::ProcessCommand() in"));

    PVMFStatus status = PVMFFailure;
    iCommandErrorCode = PVMFSocketNodeErrorEventStart; //no error

    if (aCmd.hipri())
    {
        //calling logic should prevent multiple cancels in progress.
        OSCL_ASSERT(iCancelCmdQueue.empty());

        switch (aCmd.iCmd)
        {
            case PVMF_GENERIC_NODE_CANCELALLCOMMANDS:
                status = DoCancelAllCommands(aCmd);
                break;

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

            default://unknown command type
                status = PVMFFailure;
                break;
        }

        //If the command was not finished in this call, then move it to the
        //"cancel cmd" queue where it will remain until it is completed.
        if (status == PVMFPending)
        {
            //move the new cmd to the "cancel cmd" queue where it will
            //remain until complete.
            int32 err;
            OSCL_TRY(err, iCancelCmdQueue.StoreL(aCmd););

            //we reserved space in the CancelCmdQueue already, so
            //it should not be possible to fail here.
            OSCL_ASSERT(err == OsclErrNone);

            //erase the original command
            aCmdQ.Erase(&aCmd);
        }
        else
        {
            CommandComplete(aCmdQ, aCmd, status, NULL);
        }
    }
    else
    {
        //calling logic should prevent multiple commands in progress.
        OSCL_ASSERT(iCurrentCmdQueue.empty());

        OsclAny* eventData = NULL;

        switch (aCmd.iCmd)
        {
            case PVMF_GENERIC_NODE_QUERYUUID:
                status = DoQueryUuid(aCmd);
                break;

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

            case PVMF_GENERIC_NODE_REQUESTPORT:
            {
                status = DoRequestPort(aCmd);
                eventData = iPVMFPort;
                break;
            }

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

            case PVMF_GENERIC_NODE_INIT:
                status = DoInit(aCmd);
                break;

            case PVMF_GENERIC_NODE_PREPARE:
                status = DoPrepare(aCmd);
                if (status == PVMFSuccess)
                {
                    ChangeExternalState(EPVMFNodePrepared);
                }
                break;

            case PVMF_GENERIC_NODE_START:
                status = DoStart(aCmd);
                break;

            case PVMF_GENERIC_NODE_STOP:
                status = DoStop(aCmd);
                break;

            case PVMF_GENERIC_NODE_FLUSH:
                status = DoFlush(aCmd);
                break;

            case PVMF_GENERIC_NODE_PAUSE:
                status = DoPause(aCmd);
                break;

            case PVMF_GENERIC_NODE_RESET:
                status = DoReset(aCmd);
                break;

            default://unknown command type
                status = PVMFFailure;
                break;
        }

        if (status == PVMFPending)
        {
            int32 err;
            OSCL_TRY(err, iCurrentCmdQueue.StoreL(aCmd););
            OSCL_ASSERT(err == OsclErrNone);

            //erase the original command
            aCmdQ.Erase(&aCmd);
        }
        else
        {
            CommandComplete(aCmdQ, aCmd, status, eventData);
        }
    }
}

//Called to complete a node command.
void PVMFClientServerSocketNode::CommandComplete(PVMFSocketNodeCmdQ& aCmdQ,
        PVMFSocketNodeCommand& aCmd,
        PVMFStatus aStatus,
        OsclAny* aEventData,
        PVUuid* aEventUUID,
        int32* aEventCode)

{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode:CommandComplete Id %d Cmd %d Status %d Context %d Data %d"
                    , aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));

    bool canProcess = CanProcessCommand();

    PVMFStatus status = aStatus;

    if (aStatus == PVMFSuccess)
    {
        switch (aCmd.iCmd)
        {
            case PVMF_GENERIC_NODE_INIT:
                ChangeExternalState(EPVMFNodeInitialized);
                break;

            case PVMF_GENERIC_NODE_PREPARE:
                ChangeExternalState(EPVMFNodePrepared);
                break;

            case PVMF_GENERIC_NODE_START:
                ChangeExternalState(EPVMFNodeStarted);
                break;

            case PVMF_GENERIC_NODE_STOP:
                ChangeExternalState(EPVMFNodePrepared);
                break;

            case PVMF_GENERIC_NODE_PAUSE:
                ChangeExternalState(EPVMFNodePaused);
                break;

            case PVMF_GENERIC_NODE_RESET:
                ChangeExternalState(EPVMFNodeCreated);

                //Complete the reset command.
                {
                    //cleanup all ports.
                    CleanupPorts();
                    SetState(EPVMFNodeIdle);
                }
                break;

            case PVMF_GENERIC_NODE_CANCELALLCOMMANDS:
                //Complete the reset command.
            {
                //Since "cancel all" is effectively used as a Reset,
                //go ahead and cleanup all ports.
                CleanupPorts();
            }
            break;
            default:
                break;
        }
    }

    PVInterface* extif = NULL;
    PVMFBasicErrorInfoMessage* errormsg = NULL;
    if (aEventUUID && aEventCode)
    {
        errormsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
        extif = OSCL_STATIC_CAST(PVInterface*, errormsg);
    }
    //else if no error input, see if "command error code" was set.
    else if (iCommandErrorCode != PVMFSocketNodeErrorEventStart)
    {
        PVUuid eventuuid = PVMFSocketNodeEventTypeUUID;
        errormsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (iCommandErrorCode, eventuuid, NULL));
        extif = OSCL_STATIC_CAST(PVInterface*, errormsg);
    }

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

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

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

    if (errormsg)
    {
        errormsg->removeRef();
    }
    iCommandErrorCode = PVMFSocketNodeErrorEventStart;//reset.

    //See if there was a pending cancel waiting on the current command to
    //complete.
    if (!iCancelCmdQueue.empty()
            && iCancelCmdQueue.front().iCmd == PVMF_GENERIC_NODE_CANCELCOMMAND)
    {
        CommandComplete(iCancelCmdQueue, iCancelCmdQueue.front(), PVMFSuccess);
    }

    //May need to resume command handling if the AO was blocked
    //waiting on asynchronous command completion, but it's unblocked now.
    if (!canProcess
            && CanProcessCommand()
            && IsAdded())
    {
        RunIfNotReady();
    }
}

PVMFCommandId PVMFClientServerSocketNode::QueueCommandL(PVMFSocketNodeCommand& aCmd)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::QueueCommandL()"));
    PVMFCommandId id;

    id = iPendingCmdQueue.AddL(aCmd);

    //This may be a processing trigger.
    //Wakeup the AO if needed.
    if (IsAdded()
            && CanProcessCommand())
    {
        RunIfNotReady();
    }

    return id;
}

//This is the callback from Oscl Sockets for socket operation completion.
OSCL_EXPORT_REF  void PVMFClientServerSocketNode::HandleSocketEvent(int32 aId, TPVSocketFxn aFxn, TPVSocketEvent aEvent, int32 aError)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::HandleSocketEvent() In aId=%d, aFxn=%d, aEvent=%d, aError=%d", aId, aFxn, aEvent, aError));

    if (iSockConfig && aEvent == EPVSocketSuccess)
    {
        PVMFSocketActivity activity((aEvent == EPVSocketSuccess) ? PVMFSuccess : PVMFFailure, aId, aFxn, aEvent, aError);

        //Call the appropriate handler
        switch (aFxn)
        {
            case EPVSocketRecv:
                OSCL_ASSERT(iSockConfig->iState.iRecvOperation == EPVSocketPortRecvOperation_Recv);

                RecvOperationComplete(activity.iStatus, &activity);
                break;

            case EPVSocketSend:
                OSCL_ASSERT(iSockConfig->iState.iSendOperation == EPVSocketPortSendOperation_Send);

                SendOperationComplete(activity.iStatus, &activity);
                break;

            case EPVSocketShutdown:
                //OSCL_ASSERT(iSockConfig->iState.iConnectOperation==EPVSocketPortConnectOperation_Shutdown);
                SequenceComplete(PVMFSuccess);
                //ConnectOperationComplete(activity.iStatus,&activity);
                break;

            default:
                OSCL_ASSERT(0);//unexpected
                break;
        }
    }
    else if (aEvent == EPVSocketCancel)
    {
        switch (aFxn)
        {
            case EPVSocketRecv:
                if (iSockConfig->iState.iSendOperation == EPVSocketPortSendOperation_Send
                        && iSockConfig->iState.iSendOperationCanceled == false)
                {//if does hv anything to send, cancel it
                    CancelSendOperation();
                }
                else
                {   //shutdown
                    CloseSocketConnection();
                }
                break;

            case EPVSocketSend:
                if (iSockConfig->iState.iRecvOperation == EPVSocketPortRecvOperation_Recv
                        && iSockConfig->iState.iRecvOperationCanceled == false)
                {
                    CancelRecvOperation();
                }
                else
                {
                    //shutdown
                    CloseSocketConnection();
                }
                break;

            case EPVSocketShutdown:
                //quite difficult to cancel shutdown
                break;

            default:
                OSCL_ASSERT(0);//unexpected
                break;
        }
    }
    else
    {//failure
        switch (aFxn)
        {
            case EPVSocketRecv:
                iSockConfig->iState.iRecvOperation = EPVSocketPortRecvOperation_None;
                iSockConfig->iState.iRecvOperationCanceled = true;
                break;

            case EPVSocketSend:
                iSockConfig->iState.iSendOperation = EPVSocketPortSendOperation_None;
                iSockConfig->iState.iSendOperationCanceled = true;
                break;

            case EPVSocketShutdown:
            default:
                OSCL_ASSERT(0);//unexpected
                break;
        }
    }
}


//Allocate a node port and add it to the port vector.
PVMFStatus PVMFClientServerSocketNode::AddPort(int32 tag)
{
    iPVMFPort = new PVMFClientServerSocketPort((int32)tag,
            this,
            DEFAULT_DATA_QUEUE_CAPACITY,
            DEFAULT_DATA_QUEUE_CAPACITY,
            DEFAULT_READY_TO_RECEIVE_THRESHOLD_PERCENT,
            //the output queue is empty because
            //this node pushes data directly to the
            //connecte port's input.
            0, 0, 0);

    return PVMFSuccess;
}


PVMFStatus PVMFClientServerSocketNode::AllocatePortMemPool(int32 tag, PVMFSocketNodeMemPool* & aMemPool)
{
    aMemPool = NULL;
    OsclAny *MemPtr = NULL;
    MemPtr = iAlloc.ALLOCATE(sizeof(PVMFSocketNodeMemPool));
    if (MemPtr == NULL)
    {
        return PVMFErrNoMemory;
    }

    int32 errcode = 0;
    OSCL_TRY(errcode, aMemPool = OSCL_PLACEMENT_NEW(MemPtr, PVMFSocketNodeMemPool(SNODE_DEFAULT_NUMBER_MEDIADATA_IN_MEMPOOL);));
    if (errcode != OsclErrNone)
    {
        PVMF_SOCKETNODE_LOGERROR((0, "PVMFClientServerSocketNode::DoRequestPort: PVMFSocketNodeMemPool Construct Failed Ln %d", errcode, __LINE__));
        iAlloc.deallocate(MemPtr);
        return PVMFErrNoMemory;
    }

    aMemPool->iPortTag = tag;
    return PVMFSuccess;
}


PVMFStatus PVMFClientServerSocketNode::CancelSendOperation()
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::CancelSendOperation()"));

    PVMFStatus status = PVMFSuccess;

    switch (iSockConfig->iState.iSendOperation)
    {
        case EPVSocketPortSendOperation_None:
            break;

        case EPVSocketPortSendOperation_Send:
            if (iSockConfig->iTCPSocket)
            {
                if (!iSockConfig->iState.iSendOperationCanceled)
                {
                    iSockConfig->iState.iSendOperationCanceled = true;
                    iSockConfig->iTCPSocket->CancelSend();
                }
                status = PVMFPending;
                //wait on send to complete in HandleSocketEvent
            }
            break;

        default:
            OSCL_ASSERT(0);
            status = PVMFFailure;
            break;
    }
    return status;
}


PVMFStatus PVMFClientServerSocketNode::DoStopNodeActivity()
{
    if (iNumStopPortActivityPending > 0)
        return PVMFPending;

    //Stop socket activity on all ports.
    uint32 nPortsPending = 0;
    if (iSockConfig)
    {
        // discard any saved socket activity events
        iSockConfig->iSocketRecvActivity.iValid = false;

        //if a request port is going on, be sure to complete the command,
        //although we will interrupt the current processing.
        if (iSockConfig->iState.iSequence == EPVSocketPortSequence_RequestPort
                && iCurrentCmdQueue.size()
                && iCurrentCmdQueue.front().iCmd == PVMF_GENERIC_NODE_REQUESTPORT)
        {
            CommandComplete(iCurrentCmdQueue, iCurrentCmdQueue.front(), PVMFErrCancelled, NULL);
        }

        //if a cleanup is already underway, just keep waiting for it to complete,
        //else start a new sequence
        if (iSockConfig->iState.iSequence == EPVSocketPortSequence_SocketCleanup)
        {
            nPortsPending++;
        }
        else if (StartSequence(iSockConfig->iState.iSequence = EPVSocketPortSequence_SocketCleanup) == PVMFPending)
        {
            nPortsPending++;
        }
    }

    if (nPortsPending > 0)
        iNumStopPortActivityPending = nPortsPending;

    if (iNumStopPortActivityPending > 0)
        return PVMFPending; //wait on completion in SequenceComplete.

    return PVMFSuccess;
}

//Flush is implemented for this node, but hasn't been tested.
PVMFStatus PVMFClientServerSocketNode::DoFlush(PVMFSocketNodeCommand& aCmd)
{
    OSCL_UNUSED_ARG(aCmd);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::DoFlush() In"));

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

    PVMFStatus status = PVMFSuccess;
    {
        iPVMFPort->SuspendInput();
        if (status != PVMFPending
                && iPVMFPort->IncomingMsgQueueSize() > 0)
        {
            status = PVMFPending;//Wait on this queue to empty.
            //Completion is detected in SequenceComplete.
        }
    }
    return status;
}

//Pause is a do-nothing for this node.
PVMFStatus PVMFClientServerSocketNode::DoPause(PVMFSocketNodeCommand& aCmd)
{
    OSCL_UNUSED_ARG(aCmd);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::DoPause() In"));

    if (iInterfaceState == EPVMFNodePaused)
    {
        return PVMFSuccess;
    }

    if (iInterfaceState != EPVMFNodeStarted)
    {
        return PVMFErrInvalidState;
    }

    return PVMFSuccess;
}


PVMFStatus PVMFClientServerSocketNode::DoReset(PVMFSocketNodeCommand& aCmd)
{
    OSCL_UNUSED_ARG(aCmd);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::DoReset()"));

    /* This node allows a reset from any state */

    return DoStopNodeActivity();
}

PVMFStatus PVMFClientServerSocketNode::DoQueryUuid(PVMFSocketNodeCommand& aCmd)
{
    OSCL_UNUSED_ARG(aCmd);
    /*  //This node supports Query UUID from any state

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

        //Try to match the input mimetype against any of
        //the custom interfaces for this node

        //Match against custom interface1...
        if (*mimetype==PVMF_SOCKET_NODE_EXTENSION_INTERFACE_MIMETYPE
            //also match against base mimetypes for custom interface1,
            //unless exactmatch is set.
            || (!exactmatch && *mimetype==PVMF_SOCKET_NODE_MIMETYPE)
            || (!exactmatch && *mimetype==PVMF_SOCKET_NODE_BASEMIMETYPE))
        {

            PVUuid uuid(PVMF_SOCKET_NODE_EXTENSION_INTERFACE_UUID);
            uuidvec->push_back(uuid);
        }*/
    return PVMFSuccess;
}


PVMFStatus PVMFClientServerSocketNode::DoQueryInterface(PVMFSocketNodeCommand&  aCmd)
{
    OSCL_UNUSED_ARG(aCmd);
    return PVMFSuccess;
}

PVMFStatus PVMFClientServerSocketNode::DoRequestPort(PVMFSocketNodeCommand& aCmd)
{
    OSCL_UNUSED_ARG(aCmd);
    //retrieve port tag.
    int32 tag;
    OSCL_String* portconfig;
    aCmd.PVMFSocketNodeCommandBase::Parse(tag, portconfig);

    PVMFStatus status = AddPort(tag);
    if (status != PVMFSuccess)
        return status;

    //create the socket config
    iSockConfig = OSCL_NEW(SocketPortConfig, ());
    iPVMFPort->iConfig = iSockConfig;
    iSockConfig->iPVMFPort = iPVMFPort;

    iSockConfig->iContainer = this;
    iSockConfig->iSockId = iSocketID++;
    iSockConfig->iTag = tag;
    iSockConfig->iTCPSocket = iSocketHandle;

    //create the mem pool
    PVMFSocketNodeMemPool* memPool;
    status = AllocatePortMemPool(tag, memPool);
    if (status == PVMFSuccess)
        iSockConfig->iMemPool = memPool;
    return status;
}


//Release ports is a do-nothing for this node.
PVMFStatus PVMFClientServerSocketNode::DoReleasePort(PVMFSocketNodeCommand& aCmd)
{
    OSCL_UNUSED_ARG(aCmd);
    return PVMFSuccess;
}


PVMFStatus PVMFClientServerSocketNode::DoInit(PVMFSocketNodeCommand& aCmd)
{
    OSCL_UNUSED_ARG(aCmd);
    if (iInterfaceState != EPVMFNodeIdle)
    {
        return PVMFErrInvalidState;
    }
    return PVMFSuccess;
}


//Prepare is a do-nothing for this node.
PVMFStatus PVMFClientServerSocketNode::DoPrepare(PVMFSocketNodeCommand& aCmd)
{
    OSCL_UNUSED_ARG(aCmd);
    PVMF_SOCKETNODE_LOGSTACKTRACE((0, "PVMFClientServerSocketNode::DoPrepare() In"));

    if (iInterfaceState != EPVMFNodeInitialized)
    {
        return PVMFErrInvalidState;
    }
    return PVMFSuccess;
}


PVMFStatus PVMFClientServerSocketNode::DoStart(PVMFSocketNodeCommand& aCmd)
{
    OSCL_UNUSED_ARG(aCmd);
    if (iInterfaceState == EPVMFNodeStarted)
    {
        return PVMFSuccess;//already started.
    }

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

    TPVMFNodeInterfaceState curState = iInterfaceState;
    ChangeExternalState(EPVMFNodeStarted);

    PVMFStatus status = PVMFSuccess;
    if (iSockConfig)
    {
        //Start handling incoming messages
        if (CanProcessIncomingMsg())
            ProcessIncomingMsg();

        //Start the receives.
        if (CanReceive())
        {
            status = StartRecvOperation();
            if (status == PVMFPending)
            {
                status = PVMFSuccess;
            }
            else if (status != PVMFSuccess)
            {
                ChangeExternalState(curState);
            }
        }
    }
    return status;
}



PVMFStatus PVMFClientServerSocketNode::DoStop(PVMFSocketNodeCommand& aCmd)
{
    OSCL_UNUSED_ARG(aCmd);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::DoStop() In"));

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


PVMFStatus PVMFClientServerSocketNode::DoCancelCommand(PVMFSocketNodeCommand& aCmd)
{
    OSCL_UNUSED_ARG(aCmd);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::DoCancelCommand() Called"));

    // extract the command ID from the parameters.
    PVMFCommandId cmdId;
    aCmd.PVMFSocketNodeCommandBase::Parse(cmdId);

    if (!iCurrentCmdQueue.empty()
            && iCurrentCmdQueue.front().iId == cmdId)
    {
        return DoCancelCurrentCommand(iCurrentCmdQueue, iCurrentCmdQueue.front());
        //wait on current command to complete.  The cancel command
        //will ultimately be completed in the "CommandComplete" for the current command.
    }

    {
        // start at element 1 since this cancel command is element 0
        PVMFSocketNodeCommand* cmd = iPendingCmdQueue.FindById(cmdId, 1);
        if (cmd)
        {
            // cancel the queued command.  Note this will complete out-of-order.
            CommandComplete(iPendingCmdQueue, *cmd, PVMFErrCancelled);
            // no further action is required.
            return PVMFSuccess;
        }
    }

    //this command fails if the given command is not queued or in progress.
    return PVMFErrArgument;
}

PVMFStatus PVMFClientServerSocketNode::DoCancelAllCommands(PVMFSocketNodeCommand& aCmd)
{
    OSCL_UNUSED_ARG(aCmd);
    PVMFStatus status = DoStopNodeActivity();

    if (!iCurrentCmdQueue.empty())
        CommandComplete(iCurrentCmdQueue, iCurrentCmdQueue.front(), PVMFErrCancelled);

    //Cancel all other pending commands, except for this one which is
    //element 0 in the queue
    for (uint32 i = 1; i < iPendingCmdQueue.size(); i++)
        CommandComplete(iPendingCmdQueue, iPendingCmdQueue[i], PVMFErrCancelled);

    //May need to wait on completion of StopNodeActivity.
    return status;
}


PVMFStatus PVMFClientServerSocketNode::DoCancelCurrentCommand(PVMFSocketNodeCmdQ& aCmdQ, PVMFSocketNodeCommand& aCmd)
{
    OSCL_UNUSED_ARG(aCmdQ);
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::DoCancelCurrentCommand()"));
    switch (aCmd.iCmd)
    {

        case PVMF_GENERIC_NODE_REQUESTPORT:
            //there may be a connect operation pending-- cancel it.
        {
            if (iPVMFPort)
            {
                //SocketPortConfig* iSockConfig=iRequestedPort->iConfig;
                if (iSockConfig)
                {
                    //  CancelConnectOperation();
                    return PVMFPending;//wait on the operation to complete
                    //in HandleSocketEvent or HandleDNSEvent
                }
            }
            //shouldn't get here...
            return PVMFFailure;
        }
        break;

        case PVMF_GENERIC_NODE_RESET:
            //it's too complicated to cancel a reset, so just wait on completion
            return PVMFPending;

        case PVMF_GENERIC_NODE_FLUSH:
            //to cancel a flush, just discard all remaining port messages
            //and keep waiting on completion of current message.
        {
            iPVMFPort->ClearMsgQueues();
        }
        return PVMFPending;//keep waiting on flush completion in SequenceComplete.

        case PVMF_GENERIC_NODE_CANCELCOMMAND:
        case PVMF_GENERIC_NODE_CANCELALLCOMMANDS:
            //these have asynchronous completion, but the command handling prevents
            //processing a cancel during a cancel, so we shouldn't get here.
            OSCL_ASSERT(0);
            return PVMFFailure;

        default:
            //no other node commands have asynchronous completion, so this is unexpected.
            OSCL_ASSERT(0);
            return PVMFFailure;
    }
}

PVMFStatus PVMFClientServerSocketNode::CancelRecvOperation()
{
    PVMF_SOCKETNODE_LOGSTACKTRACE((0, "PVMFClientServerSocketNode::CancelRecvOperation() In"));

    PVMFStatus status = PVMFSuccess;

    switch (iSockConfig->iState.iRecvOperation)
    {
        case EPVSocketPortRecvOperation_None:
            break;

        case EPVSocketPortRecvOperation_Recv:
            if (iSockConfig->iTCPSocket)
            {
                if (!iSockConfig->iState.iRecvOperationCanceled)
                {
                    iSockConfig->iState.iRecvOperationCanceled = true;
                    iSockConfig->iTCPSocket->CancelRecv();
                }
                status = PVMFPending;
                //wait on recv to complete in HandleSocketEvent
            }
            break;

        case EPVSocketPortRecvOperation_WaitOnConnectedPort:
            //just clear the state
            iSockConfig->iState.iRecvOperation = EPVSocketPortRecvOperation_None;
            //also discard the received data and the associated recv activity
            if (iSockConfig->iSocketRecvActivity.iValid)
                iSockConfig->iSocketRecvActivity.iValid = false;
            if (iSockConfig->iPendingRecvMediaData.GetRep())
                iSockConfig->iPendingRecvMediaData.Unbind();
            break;

        case EPVSocketPortRecvOperation_WaitOnMemory:
            if (iSockConfig->iMemPool != NULL)
                iSockConfig->iMemPool->CancelFreeChunkAvailableCallback();
            //clear the state
            iSockConfig->iState.iRecvOperation = EPVSocketPortRecvOperation_None;
            break;

        default:
            OSCL_ASSERT(0);//add code for this case
            status = PVMFFailure;
            break;
    }
    return status;
}

//a memory pool callback
void SocketPortConfig::freechunkavailable(OsclAny* aContextData)
{
    OSCL_UNUSED_ARG(aContextData);
    //complete the "wait on memory" state
    if (iState.iRecvOperation == EPVSocketPortRecvOperation_WaitOnMemory)
    {
        iContainer->RecvOperationComplete(PVMFSuccess, NULL);   //*this,
    }
}


void PVMFClientServerSocketNode::CleanupTCP()
{
    //cleanup media messages
    if (iSockConfig->iPendingRecvMediaData.GetRep() != NULL)
    {
        iSockConfig->iPendingRecvMediaData.Unbind();

    }
    if (iSockConfig->iPendingSendMediaData.GetRep() != NULL)
    {
        iSockConfig->iPendingSendMediaData.Unbind();
    }
}


void PVMFClientServerSocketNode::CleanupPorts()
{
    if (iPVMFPort)
    {
        SocketPortConfig* it = iPVMFPort->iConfig;
        if (it)
        {
            //unlink the PVMFPort so we won't try to send any EOS msg
            //during the TCP cleanup.
            it->iPVMFPort = NULL;
            it->CleanupMemPools();
            OSCL_DELETE(it);
            iPVMFPort->iConfig = NULL;
        }

        iPVMFPort->Disconnect();
        delete iPVMFPort;
        iPVMFPort = NULL;
    }
}


PVMFSocketNodeMemPool::PVMFSocketNodeMemPool(uint32 aMemPoolNumBufs)
        : iMediaDataMemPool(NULL)
{
    iMediaDataMemPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (aMemPoolNumBufs, MEDIA_DATA_CLASS_SIZE));
    iInternalAlloc = NULL;
}


void SocketPortConfig::DoSetSocketPortMemAllocator(PVLogger* aLogger, OsclSharedPtr<PVMFSharedSocketDataBufferAlloc> aAlloc)
{
    if (aAlloc.GetRep())
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, aLogger, PVLOGMSG_INFO, (0, "SocketPortConfig::DoSetSocketPortMemAllocator() Using input mem allocator"));
        /*
         * Deletion of any previously created allocators is handled as part of
         * reset / node delete. So just re-assign the shared ptr here.
         */
        if (iMemPool->iSocketAllocSharedPtr.GetRep() != NULL)
        {
            iMemPool->iSocketAllocSharedPtr.Unbind();
        }
        iMemPool->iSocketAllocSharedPtr = aAlloc;
    }
    else
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, aLogger, PVLOGMSG_INFO, (0, "SocketPortConfig::DoSetSocketPortMemAllocator() no mem allocator. Create one"));

        uint aligned_socket_alloc_size = oscl_mem_aligned_size(sizeof(PVMFSMSharedBufferAllocWithReSize));

        uint aligned_refcnt_size =  oscl_mem_aligned_size(sizeof(OsclRefCounterSA<PVMFSharedSocketDataBufferAllocCleanupSA>));

        OsclMemAllocator my_alloc;
        uint8 *my_ptr = (uint8*) my_alloc.ALLOCATE(aligned_refcnt_size + aligned_socket_alloc_size);
        OsclRefCounter *my_refcnt = OSCL_PLACEMENT_NEW(my_ptr, OsclRefCounterSA<PVMFSharedSocketDataBufferAllocCleanupSA>(my_ptr));
        my_ptr += aligned_refcnt_size;

        // allow one resize for a maximum mempool size of TCP_BUFFER_SIZE*TCP_BUFFER_IN_MEMPOOL
        iMemPool->iInternalAlloc = OSCL_NEW(PVMFSMSharedBufferAllocWithReSize, (
                                                iContainer->iMaxTcpRecvBufferSize * (iContainer->iMaxTcpRecvBufferCount - 1), "TCPsocketBuffer",
                                                1, iContainer->iMaxTcpRecvBufferSize));

        PVMFSharedSocketDataBufferAlloc *alloc_ptr = OSCL_PLACEMENT_NEW(my_ptr, PVMFSharedSocketDataBufferAlloc(iMemPool->iInternalAlloc));

        OsclSharedPtr<PVMFSharedSocketDataBufferAlloc> shared_alloc(alloc_ptr, my_refcnt);
        iMemPool->iSocketAllocSharedPtr = shared_alloc;
    }
}

void SocketPortConfig::CleanupMemPools()
{
    if (iMemPool->iInternalAlloc != NULL)
    {
        iMemPool->iInternalAlloc->DecrementKeepAliveCount();
        uint32 numOutStandingBuffers =
            iMemPool->iInternalAlloc->getNumOutStandingBuffers();
        if (numOutStandingBuffers == 0)
        {
            OSCL_DELETE((iMemPool->iInternalAlloc));
            iMemPool->iInternalAlloc = NULL;
        }
    }
    PVMFSocketNodeAllocator alloc;
    iMemPool->~PVMFSocketNodeMemPool();
    alloc.deallocate((OsclAny*)(iMemPool));
    iMemPool = NULL;
}


void PVMFClientServerSocketNode::ReportErrorEvent(PVMFEventType aEventType,
        OsclAny* aEventData,
        PVUuid* aEventUUID,
        int32* aEventCode)
{
    if (aEventUUID && aEventCode)
    {
        PVMFBasicErrorInfoMessage* eventmsg =
            OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
        PVMFAsyncEvent asyncevent(PVMFErrorEvent,
                                  aEventType,
                                  NULL,
                                  OSCL_STATIC_CAST(PVInterface*, eventmsg),
                                  aEventData,
                                  NULL,
                                  0);
        PVMFNodeInterface::ReportErrorEvent(asyncevent);
        eventmsg->removeRef();
    }
    else
    {
        PVMFNodeInterface::ReportErrorEvent(aEventType, aEventData);
    }
}

void PVMFClientServerSocketNode::ReportInfoEvent(PVMFEventType aEventType,
        OsclAny* aEventData,
        PVUuid* aEventUUID,
        int32* aEventCode)
{
    if (aEventUUID && aEventCode)
    {
        PVMFBasicErrorInfoMessage* eventmsg =
            OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
        PVMFAsyncEvent asyncevent(PVMFInfoEvent,
                                  aEventType,
                                  NULL,
                                  OSCL_STATIC_CAST(PVInterface*, eventmsg),
                                  aEventData,
                                  NULL,
                                  0);
        PVMFNodeInterface::ReportInfoEvent(asyncevent);
        eventmsg->removeRef();
    }
    else
    {
        PVMFNodeInterface::ReportInfoEvent(aEventType, aEventData);
    }
}

OSCL_EXPORT_REF bool PVMFClientServerSocketNode::setSocketPortMemAllocator(PVMFPortInterface* aInPort,
        OsclSharedPtr<PVMFSharedSocketDataBufferAlloc> aAlloc)
{

    PVMFClientServerSocketPort* aPort = OSCL_STATIC_CAST(PVMFClientServerSocketPort*, aInPort);
    SocketPortConfig* tmpSockConfig = (aPort) ? aPort->iConfig : NULL;
    if (NULL != tmpSockConfig)
    {
        tmpSockConfig->DoSetSocketPortMemAllocator(iLogger, aAlloc);
        return true;
    }
    return false;
}


bool PVMFClientServerSocketNode::CanProcessIncomingMsg()
{
    return
        //node is started
        iInterfaceState == EPVMFNodeStarted
        //port has input messages
        && iSockConfig->iPVMFPort && iSockConfig->iPVMFPort->IncomingMsgQueueSize() > 0
        //port is not busy with any sequence
        && iSockConfig->iState.iSequence == EPVSocketPortSequence_None;
}


void PVMFClientServerSocketNode::ProcessIncomingMsg()
{
    PVMF_SOCKETNODE_LOGSTACKTRACE((0, "PVMFClientServerSocketNode::ProcessIncomingMsg: aPort=0x%x", iSockConfig->iPVMFPort));

    //Dequeue the incoming message
    PVMFSharedMediaMsgPtr msg;
    PVMFStatus status = iSockConfig->iPVMFPort->DequeueIncomingMsg(msg);
    if (status != PVMFSuccess)
    {
        PVMF_SOCKETNODE_LOGERROR((0, "PVMFClientServerSocketNode::ProcessIncomingDataMsg: Error - DequeueIncomingMsg failed"));
        ReportErrorEvent(PVMFErrPortProcessing);
        return ;
    }

    OSCL_ASSERT(iSockConfig->iState.iSequence == EPVSocketPortSequence_None);

    //Handle 3 types of messages
    if (msg->getFormatID() == PVMF_MEDIA_CMD_SOCKET_DISCONNECT_FORMAT_ID)
    {
        //Disconnect message
        StartSequence(EPVSocketPortSequence_InputDisconnectMsg);
    }
    else if (msg->getFormatID() == PVMF_MEDIA_MSG_DATA_FORMAT_ID)
    {
        //Start the sequence
        StartSequence(EPVSocketPortSequence_InputDataMsg, (OsclAny*)&msg);
    }
    else
    {
        //unexpected message type
        ReportErrorEvent(PVMFErrPortProcessing);
    }
}


PVMFStatus PVMFClientServerSocketNode::StartSendOperation(PVMFSharedMediaMsgPtr& aMsg)
{
    PVMF_SOCKETNODE_LOGSTACKTRACE((0, "PVMFClientServerSocketNode::StartSendOperation() In"));

    //caller should have verified we can send now.
    OSCL_ASSERT(iSockConfig->iState.iSendOperation == EPVSocketPortSendOperation_None);

    //caller should provide a media data message as input
    OSCL_ASSERT(aMsg->getFormatID() == PVMF_MEDIA_MSG_DATA_FORMAT_ID);

    //there should be either a UDP or TCP socket on this port
    if (!iSockConfig->iTCPSocket)
    {
        return PVMFFailure;
    }

    // Retrieve memory fragment to write to
    if (iSockConfig->iPendingSendMediaData.GetRep())
        iSockConfig->iPendingSendMediaData.Unbind();

    convertToPVMFMediaData(iSockConfig->iPendingSendMediaData, aMsg);
    OsclRefCounterMemFrag refCtrMemFragOut;
    iSockConfig->iPendingSendMediaData->getMediaFragment(0, refCtrMemFragOut);

    PVMFStatus status = PVMFFailure;

    if (iSockConfig->iTCPSocket)
    {
        iSockConfig->iState.iSendOperation = EPVSocketPortSendOperation_Send;

        TPVSocketEvent retVal = iSockConfig->iTCPSocket->Send((uint8*)refCtrMemFragOut.getMemFragPtr(),
                                refCtrMemFragOut.getMemFragSize(),
                                TIMEOUT_SEND);

        if (retVal == EPVSocketPending)
            status = PVMFPending;//wait on HandleSocketEvent callback
        else
            status = PVMFFailure;

        if (PVMFPending != status)
        {
            PVMF_SOCKETNODE_LOGERROR((0, "PVMFClientServerSocketNode::StartSendOperation: TCP - Error. status=%d", status));
        }
    }

    //Handle synchronous completion or failures
    if (status != PVMFPending)
        status = SendOperationComplete(status, NULL);

    return status;
}


PVMFStatus PVMFClientServerSocketNode::SendOperationComplete(PVMFStatus aStatus, PVMFSocketActivity* aSocketActivity)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::SendOperationComplete()"));

    OSCL_ASSERT(aStatus != PVMFPending);

    PVMFStatus status = aStatus;

    //Update the send state
    TPVSocketPortSendOperation curOp = iSockConfig->iState.iSendOperation;
    iSockConfig->iState.iSendOperation = EPVSocketPortSendOperation_None;
    iSockConfig->iState.iSendOperationStatus = aStatus;
    iSockConfig->iState.iSendOperationCanceled = false;

    //Release the media buffer after each send operation, regardless of success/fail.
    if (iSockConfig->iPendingSendMediaData.GetRep() != NULL)
        iSockConfig->iPendingSendMediaData.Unbind();

    if (aSocketActivity)
    {
        //Datapath logging
        switch (aSocketActivity->iEvent)
        {
            case EPVSocketSuccess:
                //PVMF_SOCKETNODE_LOGDATATRAFFIC_I((0,"PVMFClientServerSocketNode::SendOperationComplete - Success - SockId=%d, Mime=%s", iSockConfig->iSockId, iSockConfig->iMime.get_str()));
                break;
            case EPVSocketTimeout:
                //PVMF_SOCKETNODE_LOGDATATRAFFIC_E((0,"PVMFClientServerSocketNode::SendOperationComplete - TimeOut - SockId=%d, Mime=%s", iSockConfig->iSockId, iSockConfig->iMime.get_str()));
                break;
            case EPVSocketFailure:
                //PVMF_SOCKETNODE_LOGDATATRAFFIC_E((0,"PVMFClientServerSocketNode::SendOperationComplete - Failed - SockId=%d, Mime=%s", iSockConfig->iSockId, iSockConfig->iMime.get_str()));
                break;
            case EPVSocketCancel:
                //PVMF_SOCKETNODE_LOGDATATRAFFIC_E((0,"PVMFClientServerSocketNode::SendOperationComplete - Cancelled - SockId=%d, Mime=%s", iSockConfig->iSockId, iSockConfig->iMime.get_str()));
                break;
            default:
                OSCL_ASSERT(0);
                break;
        }
    }

    //report TCP errors.
    if (aStatus != PVMFSuccess
            && curOp == EPVSocketPortSendOperation_Send)
    {
        ReportSocketNodeError(PVMFErrResource, PVMFSocketNodeErrorTCPSocketSendError);
    }

    //This completes an input data message sequence
    if (iSockConfig->iState.iSequence == EPVSocketPortSequence_InputDataMsg)
        SequenceComplete(aStatus);
    return status;
}


bool PVMFClientServerSocketNode::CanReceive()
{
    return
        //node is started
        iInterfaceState == EPVMFNodeStarted
        //port is connected
        && iSockConfig->iPVMFPort && iSockConfig->iPVMFPort->IsConnected()
        //socket exists (gets created during request port or connect sequence)
        && (iSockConfig->iTCPSocket)
        //port is not busy with any sequence other than sending data
        && (iSockConfig->iState.iSequence == EPVSocketPortSequence_None
            || iSockConfig->iState.iSequence == EPVSocketPortSequence_InputDataMsg)
        //port is not busy with any receive operation.
        && iSockConfig->iState.iRecvOperation == EPVSocketPortRecvOperation_None
        //there's no node stop going on.
        && iNumStopPortActivityPending < 0;
}

//Enter the "wait on memory" state
void PVMFClientServerSocketNode::StartRecvWaitOnMemory(int32 aSize)
{
    PVMF_SOCKETNODE_LOGSTACKTRACE((0, "PVMFClientServerSocketNode::StartRecvWaitOnMemory() In"));

    iSockConfig->iState.iRecvOperation = EPVSocketPortRecvOperation_WaitOnMemory;

    if (aSize)
    {//wait on data buffer
        iSockConfig->iMemPool->notifyfreechunkavailable(*iSockConfig, aSize, NULL);
    }
    else
    {//wait on media data wrapper
        iSockConfig->iMemPool->iMediaDataMemPool->notifyfreechunkavailable(*iSockConfig, NULL);
    }
}

//Enter the "wait on connected port" state
void PVMFClientServerSocketNode::StartRecvWaitOnConnectedPort(PVMFSocketActivity& aSocketActivity)
{
    PVMF_SOCKETNODE_LOGSTACKTRACE((0, "PVMFClientServerSocketNode::StartRecvWaitOnConnectedPort() In"));

    //outgoing queue is busy-- must queue this event for later processing
    switch (aSocketActivity.iFxn)
    {
        case EPVSocketRecv:
        case EPVSocketRecvFrom:
            iSockConfig->iSocketRecvActivity.Set(aSocketActivity.iStatus
                                                 , aSocketActivity.iId
                                                 , aSocketActivity.iFxn
                                                 , aSocketActivity.iEvent
                                                 , aSocketActivity.iError);
            break;
        default:
            OSCL_ASSERT(false);//invalid input arg.
            break;
    }

    //current state shoudl be idle
    OSCL_ASSERT(iSockConfig->iState.iRecvOperation == EPVSocketPortRecvOperation_None);

    iSockConfig->iState.iRecvOperation = EPVSocketPortRecvOperation_WaitOnConnectedPort;
}


PVMFStatus PVMFClientServerSocketNode::StartRecvOperation()
{
    PVMF_SOCKETNODE_LOGSTACKTRACE((0, "PVMFClientServerSocketNode::StartRecvOperation() In"));

    //caller should have verified we can receive data right now.
    OSCL_ASSERT(iSockConfig->iState.iRecvOperation == EPVSocketPortRecvOperation_None);

    //there should be either a UDP or TCP socket on this port and a memory pool.
    if (!iSockConfig->iTCPSocket)
    {
        return PVMFFailure;
    }
    if (!iSockConfig->iMemPool)
    {
        return PVMFFailure;
    }

    PVMFStatus status = PVMFFailure;

    if (iSockConfig->iTCPSocket)
    {
        iSockConfig->iState.iRecvOperation = EPVSocketPortRecvOperation_Recv;

        //Allocate memory
        int32 err;
        OsclSharedPtr<PVMFMediaDataImpl> mediaDataImpl;
        OSCL_TRY(err,
                 mediaDataImpl = iSockConfig->iMemPool->getMediaDataImpl(iMaxTcpRecvBufferSize););
        if (err != OsclErrNone)
        {
            StartRecvWaitOnMemory(iMaxTcpRecvBufferSize);
            status = PVMFPending;
            //wait on memory pool callback "notifyfreechunkavailable"
        }

        else
        {
            OSCL_TRY(err, iSockConfig->iPendingRecvMediaData = PVMFMediaData::createMediaData(
                         mediaDataImpl, iSockConfig->iMemPool->iMediaDataMemPool););
            if (err != OsclErrNone)
            {
                StartRecvWaitOnMemory();
                status = PVMFPending;
                //wait on memory pool callback "notifyfreechunkavailable"
            }

            else
            {
                // Retrieve memory fragment to write to
                OsclRefCounterMemFrag refCtrMemFragOut;
                iSockConfig->iPendingRecvMediaData->getMediaFragment(0, refCtrMemFragOut);

                //Issue the Oscl socket request
                TPVSocketEvent retVal = iSockConfig->iTCPSocket->Recv((uint8*)refCtrMemFragOut.getMemFragPtr()
                                        , refCtrMemFragOut.getCapacity()
                                        , TIMEOUT_RECV);
                if (EPVSocketPending != retVal)
                {
                    status = PVMFFailure;
                }
                else
                {
                    status = PVMFPending;
                    //wait on HandleSocketEvent callback.
                }
            }
        }
    }
    else    //for (iTCPSocket==NULL)
    {
        PVMF_SOCKETNODE_LOGERROR((0, "PVMFClientServerSocketNode::StartRecvOperation() Unexpected error, no socket"));
    }

    //Handle synchronous completion or failure.
    if (status != PVMFPending
            && status != PVMFFailure)
    {
        PVMF_SOCKETNODE_LOGERROR((0, "PVMFClientServerSocketNode::StartRecvOperation: Error. status=%d", status));
    }

    if (status != PVMFPending)
        status = RecvOperationComplete(status, NULL);

    return status;
}

PVMFStatus PVMFClientServerSocketNode::RecvOperationComplete(PVMFStatus aStatus, PVMFSocketActivity* aSocketActivity)
{
    PVMF_SOCKETNODE_LOGSTACKTRACE((0, "PVMFClientServerSocketNode::RecvOperationComplete() In"));

    //status should never be pending here
    OSCL_ASSERT(aStatus != PVMFPending);

    PVMFStatus status = aStatus;
    bool recvOperationCanceled = iSockConfig->iState.iRecvOperationCanceled;

    //check the condition of reset here
    if (iSockConfig->iState.iSequence == EPVSocketPortSequence_SocketCleanup
            || recvOperationCanceled)
    {
        return PVMFSuccess;
    }

    //Update the state
    TPVSocketPortRecvOperation curOp = iSockConfig->iState.iRecvOperation;
    iSockConfig->iState.iRecvOperation = EPVSocketPortRecvOperation_None;
    iSockConfig->iState.iRecvOperationStatus = aStatus;
    iSockConfig->iState.iRecvOperationCanceled = false;

    switch (curOp)
    {
        case EPVSocketPortRecvOperation_WaitOnMemory:
            //a memory wait is complete.
            //PVMF_SOCKETNODE_LOGDATATRAFFIC_I((0, "PVMFClientServerSocketNode::RecvOperationComplete WaitOnMemory - SockId=%d, Mime=%s ", iSockConfig->iSockId, iSockConfig->iMime.get_str()));
            break;

        case EPVSocketPortRecvOperation_WaitOnConnectedPort:
            //a port wait is complete
            if (iSockConfig->iSocketRecvActivity.iValid)
            {
                iSockConfig->iSocketRecvActivity.iValid = false;

                switch (iSockConfig->iSocketRecvActivity.iFxn)
                {
                    case EPVSocketRecv:
                        HandleRecvComplete(iSockConfig->iSocketRecvActivity.iStatus
                                           , &iSockConfig->iSocketRecvActivity, recvOperationCanceled);
                        break;
                    default:
                        OSCL_ASSERT(0);//invalid arg
                        break;
                }
            }
            break;

        case EPVSocketPortRecvOperation_Recv:
            HandleRecvComplete(aStatus, aSocketActivity, recvOperationCanceled);
            break;

        default:
            OSCL_ASSERT(0);//add code for this case
            break;
    }

    if (CanReceive())
        status = StartRecvOperation();

    return status;
}


void PVMFClientServerSocketNode::HandleRecvComplete(PVMFStatus aStatus, PVMFSocketActivity* aSocketActivity, bool aRecvOperationCanceled)
{
    OSCL_UNUSED_ARG(aRecvOperationCanceled);
    PVMF_SOCKETNODE_LOGSTACKTRACE((0, "PVMFClientServerSocketNode::HandleRecvComplete() In"));

    //operation should be complete when this is called.
    OSCL_ASSERT(aStatus != PVMFPending);

    //If there's no socket activity input, then this must be a failure in initiating
    //a Recv operation.
    if (!aSocketActivity || !iSockConfig->iPVMFPort
            || !iSockConfig->iPVMFPort->IsConnected())
    {
        OSCL_ASSERT(aStatus != PVMFSuccess);
        ReportSocketNodeError(PVMFErrResource, PVMFSocketNodeErrorSocketFailure);
        //release media data
        if (iSockConfig->iPendingRecvMediaData.GetRep())
            iSockConfig->iPendingRecvMediaData.Unbind();
        return;
    }

    if (aSocketActivity->iEvent == EPVSocketSuccess)
    {
        if (iSockConfig->iPVMFPort->IsOutgoingQueueBusy())
        {
            //wait on port so we can send recv data.
            StartRecvWaitOnConnectedPort(*aSocketActivity);
            return;
        }
    }

    //If we get here then it's time to process the recv result.

    //Release media data on failure
    if (aStatus != PVMFSuccess)
    {
        if (iSockConfig->iPendingRecvMediaData.GetRep())
            iSockConfig->iPendingRecvMediaData.Unbind();
    }

    switch (aSocketActivity->iEvent)
    {
        case EPVSocketSuccess:
        {
            //Get data length and set media buffer size
            int32 len;
            iSockConfig->iTCPSocket->GetRecvData(&len);
            if (len <= 0)
            {
                PVMF_SOCKETNODE_LOGERROR((0, "PVMFClientServerSocketNode::HandleRecvComplete - Sucessful Recv With Zero Length"));
                OSCL_ASSERT(false);
            }
            iSockConfig->iPendingRecvMediaData->setMediaFragFilledLen(0, len);

            // Resize the buffer
            if (iSockConfig->iMemPool)
            {
                OsclSharedPtr<PVMFMediaDataImpl> mediaMsgImpl;
                iSockConfig->iPendingRecvMediaData->getMediaDataImpl(mediaMsgImpl);
                iSockConfig->iMemPool->resizeSocketDataBuffer(mediaMsgImpl);
            }
            else
            {
                PVMF_SOCKETNODE_LOGERROR((0, "PVMFClientServerSocketNode::HandleRecvComplete() ERROR:mempool not found"));
                OSCL_ASSERT(0);
                return ;
            }

            //queue to next port
            PVMFSharedMediaMsgPtr aMediaMsgPtr;
            convertToPVMFMediaMsg(aMediaMsgPtr, iSockConfig->iPendingRecvMediaData);

            PVMFStatus status = iSockConfig->iPVMFPort->QueueOutgoingMsg(aMediaMsgPtr);
            if (status != PVMFSuccess)
            {
                ReportErrorEvent(PVMFErrPortProcessing);
                return ;
            }
        }
        break;

        case EPVSocketTimeout:
        {
            ReportSocketNodeError(PVMFErrTimeout, PVMFSocketNodeErrorSocketTimeOut);
        }
        break;

        case EPVSocketCancel:
            break;

        case EPVSocketFailure:
        {
            //After a receive failure, we may need to do a TCP shutdown.
            //Check what else is currently happening on the port.
            switch (iSockConfig->iState.iSequence)
            {
                case EPVSocketPortSequence_RequestPort:
                case EPVSocketPortSequence_InputDisconnectMsg:
                case EPVSocketPortSequence_SocketCleanup:
                    break;

                case EPVSocketPortSequence_None:
                case EPVSocketPortSequence_InputDataMsg:
                    //for these cases, start a shutdown sequence
                    //start the sequence
                    iSockConfig->iState.iSequence = EPVSocketPortSequence_SocketCleanup;
                    StartSequence(EPVSocketPortSequence_SocketCleanup);
                    break;

                default:
                    //need code to handle this case.
                    OSCL_ASSERT(0);
                    break;
            }
        }
        break;

        default:
            OSCL_ASSERT(0);
            break;
    }
}



OSCL_EXPORT_REF PVMFStatus PVMFClientServerSocketNode::SetMaxTCPRecvBufferSize(uint32 aBufferSize)
{
    if ((aBufferSize > 0) && (aBufferSize < SNODE_DEFAULT_MAX_TCP_RECV_BUFFER_SIZE))
    {
        iMaxTcpRecvBufferSize = aBufferSize;
        return PVMFSuccess;
    }
    return PVMFErrArgument;
}

OSCL_EXPORT_REF PVMFStatus PVMFClientServerSocketNode::GetMaxTCPRecvBufferSize(uint32& aSize)
{
    aSize = iMaxTcpRecvBufferSize;
    return PVMFSuccess;
}

OSCL_EXPORT_REF PVMFStatus PVMFClientServerSocketNode::SetMaxTCPRecvBufferCount(uint32 aBufferSize)
{
    iMaxTcpRecvBufferCount = aBufferSize;
    return PVMFSuccess;
}

OSCL_EXPORT_REF PVMFStatus PVMFClientServerSocketNode::GetMaxTCPRecvBufferCount(uint32& aSize)
{
    aSize = iMaxTcpRecvBufferCount;
    return PVMFSuccess;
}

PVMFStatus PVMFClientServerSocketNode::StartSequence(TPVSocketPortSequence aSequence, OsclAny* aParam)
{
    PVMFStatus status = PVMFFailure;
    //Set the sequence.
    iSockConfig->iState.iSequence = aSequence;

    switch (aSequence)
    {
        case EPVSocketPortSequence_InputDataMsg:
        {
            OSCL_ASSERT(aParam);
            return StartSendOperation(*((PVMFSharedMediaMsgPtr*)aParam));
        }

        case EPVSocketPortSequence_InputDisconnectMsg:
        {
            status = CloseSocketConnection();
        }
        break;

        case EPVSocketPortSequence_SocketCleanup:
            if (iSockConfig->iTCPSocket)
            {
                //CancelRecvOperation();
                //CancelSendOperation();
                status = CloseSocketConnection();
            }
            break;

        default:
        {
            OSCL_ASSERT(0);
            return PVMFFailure;
        }
    }

    if (status != PVMFPending)
    {
        //nothing needed.
        SequenceComplete(PVMFSuccess);
        return PVMFSuccess;
    }
    return status;
}



PVMFStatus PVMFClientServerSocketNode::CloseSocketConnection()
{
    PVMFStatus status;
    iSockConfig->iState.iSequence = EPVSocketPortSequence_SocketCleanup;
    if (!iSockConfig->iTCPSocket)
    {
        status = PVMFFailure;//unexpected
        return status;
    }
    //Initiate a socket shutdown.
    TPVSocketEvent ret = iSockConfig->iTCPSocket->Shutdown(EPVSocketBothShutdown, TIMEOUT_SHUTDOWN);
    if (ret == EPVSocketPending)
    {
        status = PVMFPending;
        //wait on the socket shutdown to complete in HandleSocketEvent callback
    }
    else
    {
        status = PVMFFailure;
    }
    return status;
}


void PVMFClientServerSocketNode::SequenceComplete(PVMFStatus aStatus)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFClientServerSocketNode::SequenceComplete() Sequence %d Status %d ", iSockConfig->iState.iSequence, aStatus));

    TPVSocketPortSequence curSequence = iSockConfig->iState.iSequence;
    iSockConfig->iState.iSequence = EPVSocketPortSequence_None;
    iSockConfig->iState.iSequenceStatus = aStatus;

    switch (curSequence)
    {
        case EPVSocketPortSequence_RequestPort:
            //may need to complete the node command
            if (iCurrentCmdQueue.size()
                    && iCurrentCmdQueue.front().iCmd == PVMF_GENERIC_NODE_REQUESTPORT)
            {
                CommandComplete(iCurrentCmdQueue, iCurrentCmdQueue.front(), aStatus, iPVMFPort);
            }
            break;

        case EPVSocketPortSequence_InputDisconnectMsg:
        case EPVSocketPortSequence_InputDataMsg:
            //If we've just completed an input port message, this may complete a node Flush command
            if (!iCurrentCmdQueue.empty()
                    && iCurrentCmdQueue.front().iCmd == PVMF_GENERIC_NODE_FLUSH)
            {
                //Flush is done when all input ports are empty.
                if (iPVMFPort->IncomingMsgQueueSize() > 0)
                    return;//keep waiting
                CommandComplete(iCurrentCmdQueue, iCurrentCmdQueue.front(), PVMFSuccess);
            }
            break;


        case EPVSocketPortSequence_SocketCleanup:
        {
            iPVMFPort->SuspendInput();
            iPVMFPort->ClearMsgQueues();

            CleanupPorts();
            //This port is done-- decrement the counter
            iNumStopPortActivityPending--;

            //When counter reaches zero, all ports are done and the sequence is complete.
            if (iNumStopPortActivityPending == 0)
            {
                //Reset the counter to the "idle" value.
                iNumStopPortActivityPending = (-1);

                //There may be a Reset or CancelAll command waiting on
                //this to complete.
                if (!iCurrentCmdQueue.empty()
                        && iCurrentCmdQueue.front().iCmd == PVMF_GENERIC_NODE_RESET)
                {
                    CommandComplete(iCurrentCmdQueue, iCurrentCmdQueue.front(), PVMFSuccess);
                }
                else if (!iCancelCmdQueue.empty()
                         && iCancelCmdQueue.front().iCmd == PVMF_GENERIC_NODE_CANCELALLCOMMANDS)
                {
                    CommandComplete(iCancelCmdQueue, iCancelCmdQueue.front(), PVMFSuccess);
                }
                return;
            }
        }
        break;

        default:
            break;
    }

    if (curSequence != EPVSocketPortSequence_InputDataMsg
            && CanReceive())
    {
        StartRecvOperation();
    }

    if (CanProcessIncomingMsg())
        ProcessIncomingMsg();
}
