adaptationlayer/dataport/dataport_csy/src/dpflowctrl.cpp
changeset 0 63b37f68c1ce
child 5 8ccc39f9d787
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/adaptationlayer/dataport/dataport_csy/src/dpflowctrl.cpp	Fri Nov 06 17:28:23 2009 +0000
@@ -0,0 +1,395 @@
+/*
+* Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+
+
+// INCLUDE FILES
+#include "dpdef.h"          // dataport definitions
+#include "dpdataport.h"     // dataport main and c32 interface
+#include "dpflowctrl.h"     // flow control handling
+#include "dppif.h"          // dcs pipe interface
+#include <iscdefinitions.h>
+#include "dplog.h"          // dataport logging
+#include "osttracedefinitions.h"
+#ifdef OST_TRACE_COMPILER_IN_USE
+#include "dpflowctrltraces.h"
+#endif
+
+// EXTERNAL DATA STRUCTURES
+// none
+
+// EXTERNAL FUNCTION PROTOTYPES
+// none
+
+// CONSTANTS
+// none
+
+// MACROS
+// none
+
+// LOCAL CONSTANTS AND MACROS
+// none
+
+// MODULE DATA STRUCTURES
+// none
+
+// LOCAL FUNCTION PROTOTYPES
+// none
+
+// FORWARD DECLARATIONS
+// none
+
+// ============================= LOCAL FUNCTIONS ===============================
+// none
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CDpFlowCtrl::CDpFlowCtrl
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CDpFlowCtrl::CDpFlowCtrl(
+    CDpDataPort& aDataPort ) :
+    CActive( KDpFlowCtrlPriority ),
+    iDataPort( aDataPort ),
+    iPifDcs( iDataPort.Pif() ),
+    iFlowCtrlDp2Dcs( EFlowControlOn ),
+    iFlowCtrlDcs2Dp( EFlowControlOff ),
+    iLastFlowControlSentToClient( EFlowControlOn ),
+    iIsDataportReadyforDteFlow( EFalse )
+    {
+    OstTrace0( TRACE_NORMAL, CDPFLOWCTRL_CDPFLOWCTRL, "CDpFlowCtrl::CDpFlowCtrl" );
+    LOGM(" CDpFlowCtrl::CDpFlowCtrl");
+
+    iIscFlowCtrlStatus = EIscFlowControlOn;
+
+    CActiveScheduler::Add( this );
+    }
+
+// -----------------------------------------------------------------------------
+// CDpFlowCtrl::~CDpFlowCtrl
+// Destructor
+// -----------------------------------------------------------------------------
+CDpFlowCtrl::~CDpFlowCtrl()
+    {
+    OstTrace0( TRACE_NORMAL, DUP1_CDPFLOWCTRL_CDPFLOWCTRL, "CDpFlowCtrl::~CDpFlowCtrl" );
+    LOGM(" CDpFlowCtrl::~CDpFlowCtrl");
+    }
+
+// -----------------------------------------------------------------------------
+// CDpFlowCtrl::RunL
+// This method sets water mark according Isc Api' proxy's flow
+// control status, if Dcs2Dp flow control status is not already set.
+// Isc Api pipe data message buffer request is renewed.
+// -----------------------------------------------------------------------------
+//
+void CDpFlowCtrl::RunL()
+    {
+    OstTrace0( TRACE_NORMAL, CDPFLOWCTRL_RUNL, "CDpFlowCtrl::RunL" );
+    OstTrace1( TRACE_NORMAL, DUP1_CDPFLOWCTRL_RUNL, "CDpFlowCtrl:: Port: %u", iDataPort.PortUnit() );
+
+    LOGM1("CDpFlowCtrl::RunL - Port %d", iDataPort.PortUnit() );
+
+    switch ( iIscFlowCtrlStatus )
+        {
+        // Dataport's Proxy's pipe data message buffer has reached HighWaterMark
+        case EIscFlowControlOn:
+            {
+            LOG(" CDpFlowCtrl::RunL, Proxy's High WaterMarkReached");
+            OstTrace0( TRACE_NORMAL, DUP2_CDPFLOWCTRL_RUNL, "CDpFlowCtrl:: Proxy's High WaterMarkReached" );
+
+            iFlowCtrlDp2Dcs = EFlowControlOn;
+            break;
+            }
+        // Dataport's Proxy's pipe data message buffer has reached LowWaterMark
+        case EIscFlowControlOff:
+            {
+            LOG(" CDpFlowCtrl::RunL, Proxy's Low WaterMarkReached");
+            OstTrace0( TRACE_NORMAL, DUP3_CDPFLOWCTRL_RUNL, "CDpFlowCtrl:: Proxy's Low WaterMarkReached" );
+
+            iFlowCtrlDp2Dcs = EFlowControlOff;
+            iPifDcs.SetPipeState( CDpPif::EDpPipeEnabled );
+            break;
+            }
+        // Connection closed, data transmission ended
+        case EIscTransmissionEnd:
+            {
+            LOG(" CDpFlowCtrl::RunL, Transmission End");
+            OstTrace0( TRACE_NORMAL, DUP4_CDPFLOWCTRL_RUNL, "CDpFlowCtrl:: Transmission End" );
+
+            // set flow control on
+            iFlowCtrlDp2Dcs = EFlowControlOn;
+            iFlowCtrlDcs2Dp = EFlowControlOn;
+            iPifDcs.SetPipeState( CDpPif::EDpPipeDisconnected );
+            break;
+            }
+        default:
+            {
+            // This should newer happen, No actions needed.
+            LOG(" CDpFlowCtrl::RunL, Proxy buffer reached HWM or LWM, but no action needed");
+            OstTrace0( TRACE_NORMAL, DUP5_CDPFLOWCTRL_RUNL, "CDpFlowCtrl:: Proxy buffer reached HWM or LWM, but no action needed" );
+
+            }
+        }
+
+    // inform client
+    if ( iFlowControlNotify )
+        {
+        InformFlowControlToClient();
+        }
+    // no else
+
+    // inform other modules
+    Notify();
+
+    if ( EIscTransmissionEnd != iIscFlowCtrlStatus )
+        {
+        // renew flow control request
+        RequestIscFlowControlNotification();
+        }
+    else
+        {
+        // Check if DataPort is ready to be deleted
+        if ( iDataPort.IsReadyToDestruct() )
+            {
+            iDataPort.DeleteDataPort();
+            }
+        //no else
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CDpFlowCtrl::RunError
+// Leave in RunL() is handled here. Error code is returned,
+// when internal error has occured.
+// -----------------------------------------------------------------------------
+//
+TInt CDpFlowCtrl::RunError(
+    TInt aError )
+    {
+    OstTrace0( TRACE_NORMAL, CDPFLOWCTRL_RUNERROR, "CDpFlowCtrl::RunError" );
+    OstTraceExt2( TRACE_NORMAL, DUP1_CDPFLOWCTRL_RUNERROR, "CDpFlowCtrl:: Port: %u, error code: %d", iDataPort.PortUnit(), aError );
+
+    LOGM2("CDpFlowCtrl::RunError - Port %d, error code: %d",
+        iDataPort.PortUnit(), aError );
+
+    return aError;
+    }
+
+// -----------------------------------------------------------------------------
+// CDpFlowCtrl::RequestIscFlowControlNotification
+// This method requests Isc Api pipe data message buffer status.
+// -----------------------------------------------------------------------------
+//
+
+void CDpFlowCtrl::RequestIscFlowControlNotification()
+    {
+    OstTrace0( TRACE_NORMAL, CDPFLOWCTRL_REQUESTISCFLOWCONTROLNOTIFICATION, "CDpFlowCtrl::RequestIscFlowControlNotification" );
+    OstTrace1( TRACE_NORMAL, DUP1_CDPFLOWCTRL_REQUESTISCFLOWCONTROLNOTIFICATION, "CDpFlowCtrl:: Port: %u", iDataPort.PortUnit() );
+
+    LOGM1(" CDpFlowCtrl::RequestIscFlowControlNotification - Port %d",
+        iDataPort.PortUnit() );
+
+    if ( !IsActive() )
+        {
+        iDataPort.ISAHandle().NotifyFlowControl(
+            iStatus, iIscFlowCtrlStatus );
+        SetActive();
+        }
+    // no else
+    }
+
+// -----------------------------------------------------------------------------
+// CDpFlowCtrl::DoCancel
+// This method cancels this active object by RequestComplete().
+// Must be called directly (not through Cancel()), when RunL()
+// should be completed with KErrCancel.
+// -----------------------------------------------------------------------------
+//
+void CDpFlowCtrl::DoCancel()
+    {
+    OstTrace0( TRACE_NORMAL, CDPFLOWCTRL_DOCANCEL, "CDpFlowCtrl::DoCancel" );
+    LOG(" CDpFlowCtrl::DoCancel");
+
+    // do the required signaling
+    iDataPort.ISAHandle().NotifyFlowControlCancel();
+    }
+
+// -----------------------------------------------------------------------------
+// CDpFlowCtrl::GetDp2DcsFlowControlStatus
+// Gets flowcontrol status of DP-->DCS
+// -----------------------------------------------------------------------------
+//
+void CDpFlowCtrl::GetDp2DcsFlowControlStatus(
+    TFlowControl& aFlowControl )
+    {
+    OstTrace0( TRACE_NORMAL, CDPFLOWCTRL_GETDP2DCSFLOWCONTROLSTATUS, "CDpFlowCtrl::GetDp2DcsFlowControlStatus" );
+    LOGM(" CDpFlowCtrl::GetDp2DcsFlowControlStatus");
+
+    aFlowControl = iFlowCtrlDp2Dcs;
+    }
+
+// -----------------------------------------------------------------------------
+// CDpFlowCtrl::SetFlowControlNotify
+// Set the flow control notify enabled/disabled.
+// -----------------------------------------------------------------------------
+//
+void CDpFlowCtrl::SetFlowControlNotify(
+    const TBool aEnableNotify )
+    {
+    OstTrace0( TRACE_NORMAL, CDPFLOWCTRL_SETFLOWCONTROLNOTIFY, "CDpFlowCtrl::SetFlowControlNotify" );
+    LOGM(" CDpFlowCtrl::SetFlowControlNotify");
+
+    iFlowControlNotify = aEnableNotify;
+    // new flow control message is received while notification was not active.
+    if ( aEnableNotify && ( iLastFlowControlSentToClient != iFlowCtrlDp2Dcs ) )
+        {
+        InformFlowControlToClient();
+        }
+    // no else
+    }
+
+// -----------------------------------------------------------------------------
+// CDpFlowCtrl::WaterMarkLowReached
+// RX buffer or Isc Api's proxy has reached low water mark.
+// Sets the local FlowCtrlDcs2Dp flow OFF and sends flow
+// change to DCS, if needed. Notify flow control users
+// (flow control observers).
+// -----------------------------------------------------------------------------
+//
+void CDpFlowCtrl::WaterMarkLowReached()
+    {
+    OstTrace0( TRACE_NORMAL, CDPFLOWCTRL_WATERMARKLOWREACHED, "CDpFlowCtrl::WaterMarkLowReached" );
+    OstTrace1( TRACE_NORMAL, DUP1_CDPFLOWCTRL_WATERMARKLOWREACHED, "CDpFlowCtrl:: Port: %u", iDataPort.PortUnit() );
+    OstTrace0( TRACE_NORMAL, DUP2_CDPFLOWCTRL_WATERMARKLOWREACHED, "CDpFlowCtrl:: LOW WATER MARK" );
+
+    LOGM1(" CDpFlowCtrl::WaterMarkLowReached - Port %d",
+        iDataPort.PortUnit() );
+    LOG(" CDpFlowCtrl - LOW WATER MARK");
+
+    // flow control is set OFF, i.e. data is being transmitted
+    iFlowCtrlDcs2Dp = EFlowControlOff;
+    // inform flow control users
+    Notify();
+    }
+
+// -----------------------------------------------------------------------------
+// CDpFlowCtrl::WaterMarkHighReached
+// RX buffer or Isc Api's proxy has reached high water mark.
+// Sets the local RX flow ON. Sends flow change to DCS if needed.
+// Notify flow control users (flow control observers).
+// -----------------------------------------------------------------------------
+//
+void CDpFlowCtrl::WaterMarkHighReached()
+    {
+    OstTrace0( TRACE_NORMAL, CDPFLOWCTRL_WATERMARKHIGHREACHED, "CDpFlowCtrl::WaterMarkHighReached" );
+    OstTrace1( TRACE_NORMAL, DUP1_CDPFLOWCTRL_WATERMARKHIGHREACHED, "CDpFlowCtrl:: Port: %u", iDataPort.PortUnit() );
+    OstTrace0( TRACE_NORMAL, DUP2_CDPFLOWCTRL_WATERMARKHIGHREACHED, "CDpFlowCtrl:: HIGH WATER MARK" );
+
+    LOGM1(" CDpFlowCtrl::WaterMarkHighReachedL - Port %d",
+        iDataPort.PortUnit() );
+    LOG(" CDpFlowCtrl - HIGH WATER MARK");
+
+    // flow control is set ON, ie data is inhibited
+    iFlowCtrlDcs2Dp = EFlowControlOn;
+    // inform flow control users
+    Notify();
+    }
+
+// -----------------------------------------------------------------------------
+// CDpFlowCtrl::NotifyClientDatapotReadyforDteFlow
+// Notifies client about flow control change when starting DataPort.
+// -----------------------------------------------------------------------------
+//
+void CDpFlowCtrl::NotifyClientDatapotReadyforDteFlow()
+    {
+    OstTrace0( TRACE_NORMAL, CDPFLOWCTRL_NOTIFYCLIENTDATAPOTREADYFORDTEFLOW, "CDpFlowCtrl::NotifyClientDatapotReadyforDteFlow" );
+    LOGM(" CDpFlowCtrl::NotifyClientDatapotReadyforDteFlow");
+
+    if ( ( !iIsDataportReadyforDteFlow ) && iFlowCtrlDp2Dcs )
+        {
+        InformFlowControlToClient();
+        }
+    // no else
+    }
+
+// -----------------------------------------------------------------------------
+// CDpFlowCtrl::InformFlowControlToClient
+// Informs client about the flow control change.
+// -----------------------------------------------------------------------------
+//
+void CDpFlowCtrl::InformFlowControlToClient()
+    {
+    OstTrace0( TRACE_NORMAL, CDPFLOWCTRL_INFORMFLOWCONTROLTOCLIENT, "CDpFlowCtrl::InformFlowControlToClient" );
+    LOGM(" CDpFlowCtrl::InformFlowControlToClient");
+
+    if ( EFlowControlOn == iFlowCtrlDp2Dcs )
+        {
+        LOG("  CDpFlowCtrl::InformFlowControlToClient, EFlowControlOn (completed)");
+        OstTrace0( TRACE_NORMAL, DUP1_CDPFLOWCTRL_INFORMFLOWCONTROLTOCLIENT, "CDpFlowCtrl:: EFlowControlOn (completed)" );
+        }
+    else
+        {
+        LOG("  CDpFlowCtrl::InformFlowControlToClient, EFlowControlOff (completed)");
+        OstTrace0( TRACE_NORMAL, DUP2_CDPFLOWCTRL_INFORMFLOWCONTROLTOCLIENT, "CDpFlowCtrl:: EFlowControlOff (completed)" );
+        }
+
+    iDataPort.FlowControlChangeCompleted( iFlowCtrlDp2Dcs, KErrNone );
+    iLastFlowControlSentToClient = iFlowCtrlDp2Dcs;
+
+    iIsDataportReadyforDteFlow = ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// CDpFlowCtrl::Attach
+// Attach observer to CDpSubject.
+// -----------------------------------------------------------------------------
+//
+void CDpFlowCtrl::Attach( CDpObserver& aObserver )
+    {
+    OstTrace0( TRACE_NORMAL, CDPFLOWCTRL_ATTACH, "CDpFlowCtrl::Attach" );
+    iDpSubject.Attach( aObserver );
+    }
+
+// -----------------------------------------------------------------------------
+// CDpFlowCtrl::Detach
+// Detach observer from CDpSubject.
+// -----------------------------------------------------------------------------
+//
+void CDpFlowCtrl::Detach( CDpObserver& aObserver )
+    {
+    OstTrace0( TRACE_NORMAL, CDPFLOWCTRL_DETACH, "CDpFlowCtrl::Detach" );
+    iDpSubject.Detach( aObserver );
+    }
+
+// -----------------------------------------------------------------------------
+// CDpFlowCtrl::Notify
+// Notify all observers of CDpSubject object.
+// -----------------------------------------------------------------------------
+//
+void CDpFlowCtrl::Notify()
+    {
+    OstTrace0( TRACE_NORMAL, CDPFLOWCTRL_NOTIFY, "CDpFlowCtrl::Notify" );
+    iDpSubject.Notify();
+    }
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+// none
+
+//  End of File