upnp/upnpstack/dlnawebserver/src/upnptcpsessionreader.cpp
changeset 0 f5a58ecadc66
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/upnp/upnpstack/dlnawebserver/src/upnptcpsessionreader.cpp	Tue Feb 02 01:12:20 2010 +0200
@@ -0,0 +1,265 @@
+/** @file
+* Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies  this distribution, and is available 
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  CUpnpTcpSessionReader is a class responsible for 
+*                   asynchronous reading from socket owned by CUpnpTcpSession.
+*
+*/
+
+
+
+#include "upnptcpsession.h"
+#include "upnptcpsessionreader.h"
+#define KLogFile _L("DLNAWebServer.txt")
+#include "upnpcustomlog.h"
+#include "inet6err.h"
+
+static const TInt KMaxRetryErrors = 5;
+static const TInt KRetryWaitTime = 1000000;
+static const TInt KTwoSec = 2000000;
+static const TInt KOneSec = 1000000;
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CUpnpTcpSessionReader::NewL
+// Factory method.
+// ---------------------------------------------------------------------------
+//
+CUpnpTcpSessionReader* CUpnpTcpSessionReader::NewL( CUpnpTcpSession& aSession,
+                                                    RSocket& aSocket,
+                                                    TThreadPriority aPriority,
+                                                    TInt aBufferSize )
+    {
+    CUpnpTcpSessionReader* self = new ( ELeave ) 
+                CUpnpTcpSessionReader( aSession, aSocket, aPriority, aBufferSize );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+    
+// ---------------------------------------------------------------------------
+// CUpnpTcpSessionReader::CUpnpTcpSessionReader
+// C++ constructor.
+// ---------------------------------------------------------------------------
+//
+CUpnpTcpSessionReader::CUpnpTcpSessionReader( CUpnpTcpSession& aSession,
+                                              RSocket& aSocket, 
+                                              TThreadPriority aPriority,
+                                              TInt aBufferSize )
+    :CActive( aPriority ),
+    iSocket( aSocket ),
+    iSession( aSession ),
+    iBufferSize( aBufferSize )
+    {
+    LOGS1( "%i, CUpnpTcpSessionReader::CUpnpTcpSessionReader", iSession.Id() );
+    
+    }
+
+// ---------------------------------------------------------------------------
+// CUpnpTcpSessionReader::TcpConstructL
+// Two-phased constructor
+// constructor that can leave. Used from derived classes.
+// ---------------------------------------------------------------------------
+//
+void CUpnpTcpSessionReader::ConstructL()
+    {
+    CActiveScheduler::Add( this );
+    
+    iReceiveBuffer.CreateL( iBufferSize );
+        
+    iRetryTimer = CUpnpNotifyTimer::NewL( this );
+    iCancelTimer = CUpnpNotifyTimer::NewL( this );        
+    }
+    
+// ---------------------------------------------------------------------------
+// CUpnpTcpSessionReader::~CUpnpTcpSessionReader
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CUpnpTcpSessionReader::~CUpnpTcpSessionReader()
+    {
+    LOGS1( "%i, CUpnpTcpSessionReader::~CUpnpTcpSessionReader", iSession.Id() );
+    Cancel();
+    
+    iReceiveBuffer.Close();  
+    
+    delete iRetryTimer;
+    delete iCancelTimer;   
+    }
+    
+// ---------------------------------------------------------------------------
+// CUpnpTcpSessionReader::Start
+// Starts reading.
+// ---------------------------------------------------------------------------
+//
+void CUpnpTcpSessionReader::Start()
+    {
+    LOGS1( "%i, CUpnpTcpSessionReader::Start", iSession.Id() );
+    // Initiate a new read from socket into iBuffer
+    if ( !IsActive() )
+        {
+        IssueRead();
+        }
+    }    
+    
+// ---------------------------------------------------------------------------
+// CUpnpTcpSessionReader::DoCancel
+// From class CActive.
+// Cancels issued reading.
+// ---------------------------------------------------------------------------
+//
+void CUpnpTcpSessionReader::DoCancel()
+    {
+    LOGS1( "%i, CUpnpTcpSessionReader::DoCancel", iSession.Id() );
+    // Cancel asychronous read request
+    iSocket.CancelRead();
+    }
+
+// ---------------------------------------------------------------------------
+// CUpnpTcpSessionReader::CancelRetry
+// ---------------------------------------------------------------------------
+//
+void CUpnpTcpSessionReader::CancelTimers()
+    {
+	iRetryTimer->Cancel();
+	iCancelTimer->Cancel();
+    }       
+    
+// ---------------------------------------------------------------------------
+// CUpnpTcpSessionReader::RunL
+// From class CActive.
+// Function is called as a callback when the issued reading is completed.
+// ---------------------------------------------------------------------------
+//
+void CUpnpTcpSessionReader::RunL()
+    {
+    LOGS2( "%i, CUpnpTcpSessionReader::RunL(), iStatus %i",
+    		iSession.Id(), iStatus.Int() );
+
+    // Active object request complete handler
+    switch ( iStatus.Int() )
+        {
+        case KErrNone:
+           	iRetryErrorCount = 0;
+           	iCancelTimer->Cancel();
+
+            // Forward read data to HTTPSession 
+            iSession.ReceivingCompletedL( iReceiveBuffer );
+            break;
+            
+         case KErrCancel:
+            if(iCancelFromTimer) 
+                {          
+                IssueRead();
+                iCancelFromTimer = EFalse;
+                }
+            break;
+       
+        case KErrNoMemory:
+        case KErrNotReady:
+        case KErrInet6AddressExpired:
+            if( iRetryErrorCount < KMaxRetryErrors )
+	            {
+	        	iRetryTimer->Cancel();
+				iRetryTimer->After( KRetryWaitTime * ++iRetryErrorCount, EFalse );
+				break;
+	            }
+            
+        default:
+            iSession.HandleErrorL( iStatus.Int() );
+            break;
+        }
+    }
+// -----------------------------------------------------------------------------
+// CUpnpTcpSessionWriter::RunError
+// RunError is called when RunL leaves.
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpTcpSessionReader::RunError( TInt aError )
+    {
+    LOGS2( "%i, CUpnpTcpSessionReader::RunError - %d"
+    		, iSession.Id(), aError);
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpTcpSessionReader::TimerEventL
+// Retry read
+// -----------------------------------------------------------------------------
+//        
+void CUpnpTcpSessionReader::TimerEventL( CUpnpNotifyTimer* aTimer )
+    {
+    if( aTimer == iCancelTimer )
+        {
+        iCancelFromTimer = ETrue;
+        iSocket.CancelRecv();
+        }
+    else if( aTimer == iRetryTimer )
+        {
+        IssueRead();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpTcpSessionReader::StartCancelTimer
+// -----------------------------------------------------------------------------
+//  
+void CUpnpTcpSessionReader::StartCancelTimer()
+    {
+    TInt timeout = iSession.TimeoutCurrentValue();
+   	iCancelTimer->Cancel();
+   	
+   	timeout = timeout/2 - KTwoSec;
+   	if( timeout <= 0 ) timeout = KOneSec;
+   	
+	iCancelTimer->After( timeout, EFalse );
+    iCancelFromTimer = EFalse;
+    }
+   
+// ---------------------------------------------------------------------------
+// CUpnpTcpSessionReader::IssueRead
+// Issues reading.
+// ---------------------------------------------------------------------------
+//
+void CUpnpTcpSessionReader::IssueRead()
+    {
+    LOGS1( "%i, CUpnpTcpSessionReader::IssueRead", iSession.Id());
+    // Initiate a new read from socket into iBuffer
+    if( IsActive() )
+        {
+        LOGS1( "%i, PANIC: CUpnpTcpSessionReader::IssueRead!", iSession.Id() );
+        User::Panic( _L("CUpnpTcpSessionReader is active" ), KErrGeneral );    
+        } 
+                                               
+    if( iSession.IsConnected() )
+        {
+      	LOGS1( "%i, CUpnpTcpSessionReader::IssueRead"
+          	, iSession.Id());
+          	
+        Deque();
+        CActiveScheduler::Add(this);
+          	
+        iReceiveBuffer.Zero();
+        
+        StartCancelTimer();
+
+        iSocket.RecvOneOrMore( iReceiveBuffer, 0, iStatus, iLen );   
+        SetActive();
+        }
+    }
+
+    
+//  End of File