rtp/rtpstack/src/rtpcommsend.cpp
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rtp/rtpstack/src/rtpcommsend.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,305 @@
+/*
+* Copyright (c) 2002-2003 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:   
+*
+*/
+
+
+
+
+#include "rtpcommsend.h"
+
+// CONSTANTS
+
+/////////////////////Class CRtpCommSend///////////////////////////////////////
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------------------------
+// Set to address
+// ---------------------------------------------------------------------------
+// 
+void CRtpCommSend::SetToAddress(TInetAddr& aAddr)
+    {
+    iToAddr.SetAddress( aAddr.Address() ); 
+    iToAddr.SetPort( aAddr.Port() );     
+    if (aAddr.Family() == KAfInet6 )
+    	{
+    	iToAddr.SetAddress( aAddr.Ip6Address() ); 
+    	}  
+    }
+
+// ---------------------------------------------------------------------------
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// ---------------------------------------------------------------------------
+//
+CRtpCommSend::CRtpCommSend( RSocket& aSocket, MRtpErrNotify& aErrNotify, TInetAddr& aAddr ) 
+    : CActive( EPriorityStandard ), 
+      iSocket( aSocket ),
+      iToAddr(aAddr),      
+      iWriteStatus( EWaiting ),
+      iBufPtr( NULL, 0 ),
+      iRtpErrNotify( aErrNotify ),
+      iSendQue(CRtpSendItem::iOffset ),
+      iQueueIter(iSendQue)
+    {
+    CActiveScheduler::Add( this );
+    }
+  
+// ---------------------------------------------------------------------------
+// Symbian 2nd phase constructor can leave.
+// ---------------------------------------------------------------------------
+// 
+void CRtpCommSend::ConstructL( /*TInt aBufSize */)
+    {
+
+   	}
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+CRtpCommSend* CRtpCommSend::NewL( RSocket& aSocket, MRtpErrNotify& aErrNotify,
+                                  /*TInt aBufSize,*/ TInetAddr& aAddr )
+    {
+    CRtpCommSend* self = new ( ELeave ) CRtpCommSend( aSocket, aErrNotify, aAddr );
+    CleanupStack::PushL( self );
+    self->ConstructL( /*aBufSize*/ );
+    CleanupStack::Pop(); //self
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// Destructor
+// 
+// ---------------------------------------------------------------------------
+//
+CRtpCommSend::~CRtpCommSend()
+    {
+    Cancel();
+    CompleteAndRemoveRequests( KErrAbort );
+    }
+
+// ---------------------------------------------------------------------------
+// CRtpCommSend::RunL()
+// Called when request has completed.
+// ---------------------------------------------------------------------------
+//
+void CRtpCommSend::RunL()
+    {
+    // Active object request complete handler
+    if ( iStatus == KErrNone )
+        {
+        RemoveFromQueue();
+		
+        switch( iWriteStatus )
+            {
+            case ESending:
+                SendNextPacket();
+                break;
+            default:
+                RTP_DEBUG_DETAIL( "Tx state error" );
+                User::Leave( KErrInUse );
+                break;
+            }
+        }
+    else 
+        {
+        RTP_DEBUG_DETAIL_DVALUE( "CRtpCommSend::RunL, ERR: ", iStatus.Int() );
+        
+        // Client originated cancelling is handled in CancelAsyncSend() function.
+        if ( KErrCancel != iStatus.Int() )
+            {
+            CompleteAndRemoveRequests( iStatus.Int() );
+            }
+        
+        iRtpErrNotify.ErrorNotify( iStatus.Int() );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CRtpCommSend::RemoveFromQueue()
+// Remove Item from Queue
+// ---------------------------------------------------------------------------
+//
+void CRtpCommSend::RemoveFromQueue()
+	{
+	if ( !( iSendQue.IsEmpty() ) )
+		{
+		CRtpSendItem* item = iSendQue.First();
+		CompleteClientRequest( *item, KErrNone );
+		iSendQue.Remove(*item);
+		delete item;
+		}
+	}
+// ---------------------------------------------------------------------------
+// CRtpCommSend::DoCancel()
+// Cancel ongoing requests.
+// ---------------------------------------------------------------------------
+//
+void CRtpCommSend::DoCancel()
+    {	
+    // Cancel asychronous send request
+    CancelAsyncSend();
+    } 
+
+// ---------------------------------------------------------------------------
+// CRtpCommSend::CancelAsyncSend()
+// 
+// ---------------------------------------------------------------------------
+//
+void CRtpCommSend::CancelAsyncSend()
+	{
+    RTP_DEBUG_DETAIL( "CRtpCommSend::CancelAsyncSend" );
+
+    iSocket.CancelSend();
+    CompleteAndRemoveRequests( KErrCancel );
+	}
+
+// ---------------------------------------------------------------------------
+// CRtpCommSend::Send()
+// 
+// ---------------------------------------------------------------------------
+//
+void CRtpCommSend::Send( const TDesC8& aPacket, TRequestStatus& aStatus )
+    {
+    RTP_DEBUG_DETAIL( "CRtpCommSend::Send -- ASynchronous" );
+    
+    aStatus = KRequestPending;
+    
+    TInt err( KErrNone );
+    TRAP( err, 
+        iSendQue.AddLast( *CRtpSendItem::NewL( aPacket, iStatus, aStatus ) ) );
+    
+    if ( KErrNone == err )
+        {
+        if ( !IsActive() )
+            {
+            SendNextPacket();
+            }
+        }
+    else
+        {
+        // Probably out of memory, so don't send any more packets
+        TRequestStatus* status = &aStatus;
+        User::RequestComplete( status, err );
+        CompleteAndRemoveRequests( err );
+        RTP_DEBUG_DETAIL( "Error Occured while put Packet to Send Item Que" );
+        iRtpErrNotify.ErrorNotify( err );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CRtpCommSend::Send()
+// 
+// ---------------------------------------------------------------------------
+//
+TInt CRtpCommSend::Send( const TDesC8& aPacket )
+    {
+    RTP_DEBUG_DETAIL( "CRtpCommSend::Send -- Synchronous Entry" );
+    
+    TInt err( KErrNone );
+    if ( ( iWriteStatus != EWaiting ) && ( iWriteStatus != ESending ) )
+        {
+        RTP_DEBUG_DETAIL( "Write status is not correct" );
+        return KErrDisconnected;
+        }
+    
+    // Put in in our buffer
+    TRAP( err, iSendQue.AddLast(*CRtpSendItem::NewL(aPacket, iStatus)) );
+	RTP_DEBUG_DETAIL( "Put Packet to Send Item Que" );
+    
+    if ( err != KErrNone )
+        {
+        // Probably out of memory, so don't send any more packets
+        CompleteAndRemoveRequests( err );
+        
+		RTP_DEBUG_DETAIL( "Error Occured while put Packet to Send Item Que" );
+        return err;
+        }
+    
+    if ( !IsActive() )
+        {
+        SendNextPacket();
+		}
+	
+	RTP_DEBUG_DETAIL( "CRtpCommSend::Send -- Synchronous Exit" );
+    return err;
+    }
+
+// ---------------------------------------------------------------------------
+// CRtpCommSend::SendNextPacket()
+// Write data from buffer to socket.
+// ---------------------------------------------------------------------------
+//
+void CRtpCommSend::SendNextPacket()
+    {
+    RTP_DEBUG_DETAIL( "CRtpCommSend::SendNextPacket Entry" );
+    
+    iWriteStatus = EWaiting;
+    iQueueIter.SetToFirst();
+	CRtpSendItem* item;
+    if ( ( item=iQueueIter++ ) != NULL )
+        {
+        iSocket.SendTo( item->GetData(), iToAddr, 0, item->iStatus );
+        SetActive();
+        iWriteStatus = ESending;
+        }
+
+    RTP_DEBUG_DETAIL( "CRtpCommSend::SendNextPacket Exit" );
+    }
+
+// ---------------------------------------------------------------------------
+// CRtpCommSend::CompleteAndRemoveRequests()
+// Removes all requests in the queue.
+// ---------------------------------------------------------------------------
+//
+void CRtpCommSend::CompleteAndRemoveRequests( TInt aError )
+    {
+    RTP_DEBUG_DETAIL( "CRtpCommSend::CompleteAndRemoveRequests Entry" );
+    
+    CRtpSendItem* item;
+    iQueueIter.SetToFirst();
+    item = iQueueIter++;
+    while ( item )
+        {
+        CompleteClientRequest( *item, aError );
+        iSendQue.Remove( *item );
+        delete item;
+        item = iQueueIter++;
+        }
+    
+    RTP_DEBUG_DETAIL( "CRtpCommSend::CompleteAndRemoveRequests Exit" );
+    }
+
+// ---------------------------------------------------------------------------
+// CRtpCommSend::CompleteClientRequest()
+// Completes the request.
+// ---------------------------------------------------------------------------
+//
+void CRtpCommSend::CompleteClientRequest( CRtpSendItem& aItem, 
+    TInt aReason ) const
+    {
+    RTP_DEBUG_DETAIL( "CRtpCommSend::CompleteClientRequest Entry" );
+
+    TRequestStatus* status = aItem.ClientStatus();
+    if ( NULL != status )
+        {
+        User::RequestComplete( status, aReason );
+        }
+    }
+
+// End of file
+
+