Msrp/MsrpClient/src/CMSRPSessionImplementation.cpp
branchMSRP_FrameWork
changeset 25 505ad3f0ce5c
child 58 cdb720e67852
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Msrp/MsrpClient/src/CMSRPSessionImplementation.cpp	Sat Jun 12 14:30:11 2010 +0530
@@ -0,0 +1,633 @@
+/*
+* Copyright (c) 2009-2010 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:
+* MSRP Implementation
+*
+*/
+
+//  Include Files
+#include "CMSRPSessionImplementation.h"
+#include "msrpstrings.h"
+#include "MSRPStrConsts.h"
+#include "RMSRPSession.h"
+#include "MMSRPSessionObserver.h"
+#include "CMSRPConnectionListener.h"
+#include "CMSRPIncomingListener.h"
+#include "CMSRPSendResultListener.h"
+#include "CMSRPMessage.h"
+#include "CMSRPToPathHeader.h"
+#include "CMSRPFromPathHeader.h"
+#include "CMSRPMessageIdHeader.h"
+#include "CMSRPSuccessReportHeader.h"
+#include "CMsrpFailureReportHeader.h"
+#include "CMsrpContentTypeHeader.h"
+#include "CMSRPSessionParams.h"
+
+
+// SYSTEM INCLUDES
+#include <e32math.h>
+
+
+// Constants
+const TInt KMsrpFixedLength=19; // fixed length of a uri
+
+
+//  Member Functions
+
+CMSRPSessionImplementation* CMSRPSessionImplementation::NewL( RMSRP& aRMSRP,
+                                                              MMSRPSessionObserver& aObserver,
+                                                              const TUint aIapId )
+	{
+	MSRPLOG("CMSRPSessionImplementation::NewL");
+	CMSRPSessionImplementation *self = CMSRPSessionImplementation::NewLC( aRMSRP, aObserver, aIapId );
+
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+
+CMSRPSessionImplementation* CMSRPSessionImplementation::NewLC( RMSRP& aRMSRP,
+                                                               MMSRPSessionObserver& aObserver,
+                                                               const TUint aIapId )
+    {
+    MSRPLOG("CMSRPSessionImplementation::NewLC");
+    CMSRPSessionImplementation *self = new (ELeave) CMSRPSessionImplementation( aRMSRP, aObserver );                                                            
+
+    CleanupStack::PushL(self);                                                       
+    self->ConstructL( aIapId );
+    return self;
+    }
+
+CMSRPSessionImplementation::CMSRPSessionImplementation( RMSRP& aRMSRP,
+                                                        MMSRPSessionObserver& aObserver )
+                                                        :iRMSRP(aRMSRP), 
+                                                        iSessionObserver(aObserver),
+                                                        iSuccessReport(ENo),
+                                                        iFailureReport(EYes)
+    {
+    MSRPLOG("CMSRPSessionImplementation::Ctor");
+	}
+
+
+void CMSRPSessionImplementation::ConstructL( const TUint aIapId )
+	{
+	MSRPLOG("CMSRPSessionImplementation::ConstructL enter");
+	
+	MSRPStrings::OpenL();
+	iMSRPSession = new ( ELeave ) RMSRPSession();
+	    
+	User::LeaveIfError(iMSRPSession->CreateServerSubSession( iRMSRP, aIapId ) );
+	MSRPLOG("Sub session opened successfully!");
+		
+	RBuf8 sessionID;
+	sessionID.CreateL( KMaxLengthOfSessionId );
+	CleanupClosePushL( sessionID );
+	
+	RBuf8 localHost;
+	localHost.CreateL( KMaxLengthOfHost );
+	CleanupClosePushL( localHost );
+	
+	iMSRPSession->GetLocalPathL( localHost, sessionID );
+	
+	iLocalMsrpPath.CreateL( KMsrpUriScheme, KMsrpFixedLength + localHost.Length() + sessionID.Length() );
+		
+	iLocalMsrpPath.Append( localHost );
+	iLocalMsrpPath.Append( KColon );
+	iLocalMsrpPath.AppendNum( KMsrpPort );
+	iLocalMsrpPath.Append( KForwardSlash );   
+	iLocalMsrpPath.Append( sessionID );
+	iLocalMsrpPath.Append( KSemicolon );
+	iLocalMsrpPath.Append( KTransport );
+	
+	
+	iConnectionListener = CMSRPConnectionListener::NewL(
+	        *this, *iMSRPSession );
+	iIncomingListener = CMSRPIncomingListener::NewL(
+	        *this, *iMSRPSession );
+	iSendResultListener = CMSRPSendResultListener::NewL(
+	        *this, *iMSRPSession, sessionID );
+	
+	CleanupStack::PopAndDestroy(2); //sessionID and localHost
+	MSRPLOG("CMSRPSessionImplementation::ConstructL exit");
+	}
+
+
+CMSRPSessionImplementation::~CMSRPSessionImplementation()
+    {
+    MSRPLOG("CMSRPSessionImplementation::Dtor Entered");
+        
+    MSRPStrings::Close();
+    iLocalMsrpPath.Close();
+    iRemoteMsrpPath.Close();
+    
+    delete iConnectionListener;
+    delete iIncomingListener;
+    delete iSendResultListener;
+    
+    iSentMessages.ResetAndDestroy();
+    iSentMessages.Close();
+    
+    if( iMSRPSession )
+        {
+        iMSRPSession->CloseServerSubSession();
+        }    
+    delete iMSRPSession;
+
+    MSRPLOG("CMSRPSessionImplementation::Dtor Exit");    
+    }
+
+
+TDesC8& CMSRPSessionImplementation::LocalMSRPPath()
+    {
+    MSRPLOG("CMSRPSessionImplementation::LocalMSRPPath");
+    return iLocalMsrpPath;
+    }
+
+
+void CMSRPSessionImplementation::SetSessionParams( CMSRPSessionParams& aSessionParams )
+    {
+    MSRPLOG("CMSRPSessionImplementation::SetSessionParams");
+    iSuccessReport = aSessionParams.SuccessReportHeader();
+    iFailureReport = aSessionParams.FailureReportHeader();
+    }
+
+
+void CMSRPSessionImplementation::GetRemotePathComponentsL( TPtrC8& aRemoteHost, TUint& aRemotePort, TPtrC8& aRemoteSessionID )
+    {
+    MSRPLOG("CMSRPSessionImplementation::GetRemotePathComponentsL enter");
+    TUriParser8 parser;
+    User::LeaveIfError( parser.Parse( iRemoteMsrpPath ) ); 
+ 
+    aRemoteHost.Set( parser.Extract( EUriHost ) );
+    
+    const TDesC8& remPort = parser.Extract( EUriPort );
+
+    TLex8 portLex(remPort);
+    User::LeaveIfError( portLex.Val( aRemotePort ) );
+        
+    const TDesC8& remotePath = parser.Extract( EUriPath );
+    
+    TInt loc = remotePath.Find( KSemicolon );
+    aRemoteSessionID.Set( remotePath.Mid( 1, loc-1) );    
+    MSRPLOG("CMSRPSessionImplementation::GetRemotePathComponentsL exit");
+    }
+
+
+void CMSRPSessionImplementation::ConnectL( const TDesC8& aRemoteMsrpPath )
+    {
+    MSRPLOG("CMSRPSessionImplementation::ConnectL enter");
+    
+    iRemoteMsrpPath.CreateL( aRemoteMsrpPath );
+    
+    TPtrC8 remoteHost;
+    TPtrC8 remoteSessionID;
+    TUint remotePort;
+    
+    GetRemotePathComponentsL( remoteHost, remotePort, remoteSessionID );
+    
+    iConnectionListener->ConnectL( remoteHost, remotePort, remoteSessionID );
+    MSRPLOG("CMSRPSessionImplementation::ConnectL exit");
+    }
+
+
+void CMSRPSessionImplementation::ListenL( const TDesC8& aRemoteMsrpPath )
+    {    
+    MSRPLOG("CMSRPSessionImplementation::ListenL enter");
+    
+    iRemoteMsrpPath.CreateL( aRemoteMsrpPath );
+    
+    TPtrC8 remoteHost;
+    TPtrC8 remoteSessionID;
+    TUint remotePort;
+    
+    GetRemotePathComponentsL( remoteHost, remotePort, remoteSessionID );
+    
+    iIncomingListener->ListenConnections( remoteHost, remotePort, remoteSessionID );     
+    MSRPLOG("CMSRPSessionImplementation::ListenL exit");
+    }
+
+
+void CMSRPSessionImplementation::ConnectionEstablishedL( TInt aStatus )
+    {
+    
+    MSRPLOG("CMSRPSessionImplementation::ConnectionEstablished enter");
+    
+    iSessionObserver.ConnectStatus(aStatus);
+    if ( aStatus == KErrNone )
+        {
+        // start listening to incoming messages directed to this session
+        iIncomingListener->ListenMessages( );
+
+        // start listening when message has been sent,  to responses
+        iSendResultListener->ListenSendResultL( );                
+        }
+    
+    MSRPLOG("CMSRPSessionImplementation::ConnectionEstablished exit");
+    }
+    
+
+void CMSRPSessionImplementation::HandleIncomingMessageL(
+    const TDesC8& aIncomingMessage, TInt aStatus )
+    {
+    MSRPLOG( "CMSRPSessionImplementation::HandleIncomingMessageL enter" )
+
+    // the incoming buffer must be internalized
+    RDesReadStream readStream( aIncomingMessage );
+
+    if ( CMSRPMessage::IsMessage( aIncomingMessage ) )
+        {
+        CMSRPMessage* message = NULL;
+        message = CMSRPMessage::InternalizeL( readStream );
+        CleanupStack::PushL(message);
+        
+        HBufC8* messageContent = NULL;
+        if(message->IsContent())
+            {
+            messageContent = HBufC8::NewL(message->Content().Length());
+            CleanupStack::PushL( messageContent );
+            *messageContent = message->Content();
+            }
+        else
+            {
+            messageContent = HBufC8::NewL(KNullDesC8().Length());
+            CleanupStack::PushL( messageContent );
+            *messageContent = KNullDesC8();
+            }
+
+        iSessionObserver.IncomingMessage( messageContent, aStatus );
+        CleanupStack::Pop( messageContent );
+        CleanupStack::PopAndDestroy(message);
+        }
+    else
+        {
+        User::Leave( KErrArgument );
+        }
+    
+    MSRPLOG( "CMSRPSessionImplementation::HandleIncomingMessageL exit" )
+    }
+
+void CMSRPSessionImplementation::ReceiveProgress(TInt aBytesReceived, TInt aTotalBytes)
+    {
+    iSessionObserver.FileReceiveProgress(aBytesReceived, aTotalBytes);
+    }
+
+void CMSRPSessionImplementation::SendProgress(TInt aBytesSent, TInt aTotalBytes)
+    {
+    iSessionObserver.FileSendProgress(aBytesSent, aTotalBytes);    
+    }
+
+CMSRPMessage* CMSRPSessionImplementation::CreateMsrpMessageL(
+    const TDesC8& aMessage, const TDesC8& aToPath,
+    const TDesC8& aFromPath, const TDesC8& aMimeType )
+    {
+    
+    MSRPLOG( "CMSRPSessionImplementation::CreateMsrpMessageL enter" )
+    
+    // To path
+    CMSRPMessage* msrpMessage = new ( ELeave ) CMSRPMessage();
+    CleanupStack::PushL( msrpMessage );
+    CMSRPToPathHeader* toPath = CMSRPToPathHeader::DecodeL( aToPath );
+    msrpMessage->SetToPathHeader( toPath );
+
+    // from path
+    CMSRPFromPathHeader* fromPath = CMSRPFromPathHeader::DecodeL( aFromPath );
+    msrpMessage->SetFromPathHeader( fromPath );
+
+    // message id header
+    TTime now;
+    now.HomeTime();
+    TInt64 seed = now.Int64();
+    // Create a random number as the session ID
+    TInt random = Math::Rand( seed );
+    TBuf8< 100 > idString;
+    idString.AppendNum( random );
+    CMSRPMessageIdHeader* messageIdHeader = CMSRPMessageIdHeader::NewL( idString );
+    msrpMessage->SetMessageIdHeader( messageIdHeader );
+
+    // success report header
+    if( iSuccessReport != ENo )
+        {
+        RStringF string = MSRPStrings::StringF( MSRPStrConsts::EYes );
+        CMSRPSuccessReportHeader* successReportHeader = CMSRPSuccessReportHeader::NewL( string );
+        msrpMessage->SetSuccessReportHeader( successReportHeader );
+        }
+    
+    // failure report header
+    if( iFailureReport != EYes )
+        {
+        RStringF string;
+        CleanupClosePushL(string);
+        if( iFailureReport == ENo )
+            {
+            string = MSRPStrings::StringF( MSRPStrConsts::ENo );
+            }
+        else
+            {
+            string = MSRPStrings::StringF( MSRPStrConsts::EPartial );
+            }
+        CMSRPFailureReportHeader* failureReportHeader = CMSRPFailureReportHeader::NewL( string );
+        msrpMessage->SetFailureReportHeader( failureReportHeader );
+        CleanupStack::PopAndDestroy(); // string
+        }
+     
+    // content type
+    if(aMimeType.Length())
+        {
+        CMSRPContentTypeHeader* contentType = CMSRPContentTypeHeader::NewL( aMimeType );
+        msrpMessage->SetContentTypeHeader( contentType );
+        
+        if(aMessage.Length())
+            {
+            // content of the message
+            HBufC8* contentOfMessage = HBufC8::NewL( aMessage.Length() );
+            *contentOfMessage = aMessage;
+
+            msrpMessage->SetContent( contentOfMessage );
+            }        
+        }
+    
+    CleanupStack::Pop(msrpMessage);
+    MSRPLOG( "CMSRPSessionImplementation::CreateMsrpMessageL exit" )
+    return msrpMessage;
+    }
+
+
+void CMSRPSessionImplementation::SendMessageL( CMSRPMessage* aMessage )
+    {
+    MSRPLOG( "CMSRPSessionImplementation::SendMessageL enter" )
+
+    iSentMessages.AppendL( aMessage );
+
+    // making sure the required headers are included
+    if ( !aMessage->FromPathHeader() || !aMessage->ToPathHeader() || !aMessage->MessageIdHeader() )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    CBufSeg* buf1 = CBufSeg::NewL( 256 ); // expandsize 256
+    CleanupStack::PushL( buf1 );
+    RBufWriteStream writeStream( *buf1 );
+    CleanupClosePushL( writeStream );
+
+    aMessage->ExternalizeL( writeStream );
+    writeStream.CommitL();
+
+    // MSRP message externalized to buffer, now let's move it to flat buffer
+    if ( buf1->Size() > KMaxLengthOfIncomingMessageExt )
+        {
+        // invalid message size
+        User::Leave( KErrArgument );
+        }
+
+    buf1->Read( 0, iExtMessageBuffer, buf1->Size() );
+    CleanupStack::PopAndDestroy( 2 ); // buf1, writestream
+
+    // message creation complete, send the message
+    // synchronously sent the message
+    User::LeaveIfError( iMSRPSession->SendMessage( iExtMessageBuffer ) );
+    
+    MSRPLOG( "CMSRPSessionImplementation::SendMessageL exit" )
+    }
+
+
+HBufC8* CMSRPSessionImplementation::SendBufferL(
+    const TDesC8& aMessage,
+    const TDesC8& aMimeType )
+    {
+    MSRPLOG( "CMSRPSessionImplementation::SendBufferL enter" )
+    
+    if(aMessage.Length() && !aMimeType.Length())
+        {
+        User::Leave( KErrArgument );
+        }
+    
+    CMSRPMessage* msrpMessage = CreateMsrpMessageL(
+                                aMessage, iRemoteMsrpPath, iLocalMsrpPath, aMimeType );
+    CleanupStack::PushL( msrpMessage );
+    SendMessageL( msrpMessage );
+    HBufC8* messageId = msrpMessage->MessageIdHeader()->ToTextValueLC();
+    CleanupStack::Pop(messageId);
+    CleanupStack::Pop( msrpMessage );
+    MSRPLOG( "CMSRPSessionImplementation::SendBufferL exit" )
+    return messageId;
+    }
+
+
+void CMSRPSessionImplementation::CancelSendingL( TDesC8& aMessageId )
+    {
+    MSRPLOG( "CMSRPSessionImplementation::CancelSendingL " )
+    // then let's send a message to server to cancel sending
+    User::LeaveIfError( iMSRPSession->CancelSending( aMessageId ) );
+    }
+
+
+void CMSRPSessionImplementation::SendStatusL( TInt aStatus, const TDesC8& aMessageid )
+    {
+    MSRPLOG2( "CMSRPSessionImplementation::SendStatus = %d", aStatus )
+    if(isReceiveFile || isSendFile )
+        {
+        if(isReceiveFile)
+            {
+            iSessionObserver.ReceiveFileNotification( aStatus );
+           
+            }
+        if(isSendFile)
+            {
+            iSessionObserver.SendFileNotification( aStatus );
+            }
+        }
+     else
+        {
+        for ( TInt i = 0; i < iSentMessages.Count(); i++ )
+            {
+            HBufC8* messageid = iSentMessages[ i ]->MessageIdHeader()->ToTextValueLC();
+            if ( *messageid == aMessageid )
+                {
+                // match
+                delete iSentMessages[ i ];
+                iSentMessages.Remove( i );
+                iSessionObserver.SendResult( aStatus, aMessageid );
+                CleanupStack::PopAndDestroy(messageid); // messageid from above
+                break;
+                }
+            CleanupStack::PopAndDestroy(messageid); // messageid from above
+            }
+        }
+
+    MSRPLOG( "CMSRPSessionImplementation::SendStatus exit" )
+    }
+
+void CMSRPSessionImplementation::HandleConnectionErrors( TInt aErrorStatus )
+    {
+    MSRPLOG2( "CMSRPSessionImplementation::HandleConnectionErrors Error = %d", aErrorStatus )
+    iSessionObserver.ListenPortFailure(aErrorStatus);  
+    
+    }
+
+void CMSRPSessionImplementation::SendFileL(const TFileName& aFileName, const TDesC8& aMimeType)
+    {
+    MSRPLOG( "CMSRPSessionImplementation::SendFileL enter" );
+   
+    if(aFileName.Length() && !aMimeType.Length())
+        {
+        User::Leave( KErrArgument );
+        }
+     isSendFile = ETrue;
+    CMSRPMessage* iFile = SetFileParamsL(aFileName,iRemoteMsrpPath, iLocalMsrpPath,aMimeType );
+    
+     //Set progress indication
+    iFile->SetNotifyProgress(iProgress);
+     
+    CBufSeg* buf = CBufSeg::NewL( 100 ); // expandsize to 100 
+    
+    //todo need to check what's optimal value here
+    CleanupStack::PushL( buf );
+    RBufWriteStream writeStr( *buf );
+    CleanupClosePushL( writeStr );
+    iFile->ExternalizeL( writeStr );
+    writeStr.CommitL();
+    
+    // MSRP message externalized to buffer, now let's move it to flat buffer
+    if ( buf->Size() > KMaxLengthOfIncomingMessageExt )
+        {
+        // invalid message size
+        User::Leave( KErrArgument );
+        }
+
+    buf->Read( 0, iExtMessageBuffer, buf->Size() );
+    CleanupStack::PopAndDestroy( 2 ); // buf, writestream
+   
+    delete iFile;
+	iFile = NULL;
+    // send the filename
+   User::LeaveIfError( iMSRPSession->SendFileL( iExtMessageBuffer ) );
+   MSRPLOG( "CMSRPSessionImplementation::SendFileL exit" ); 
+    }  
+    
+void CMSRPSessionImplementation::ReceiveFileL(const TFileName& aFileName,const TInt aFileSize, const TDesC8& aMimeType)
+    {
+    MSRPLOG( "CMSRPSessionImplementation::ReceiveFileL enter" );
+    isReceiveFile = ETrue;
+    if(aFileName.Length() && !aMimeType.Length())
+            {
+            User::Leave( KErrArgument );
+            }
+    CMSRPMessage* iFile = SetFileParamsL(aFileName,iRemoteMsrpPath, iLocalMsrpPath,aMimeType );
+       
+       //Set FileSize
+       iFile->SetFileSize(aFileSize);
+       
+       //Set progress indication
+       iFile->SetNotifyProgress(iProgress);
+        
+       CBufSeg* buf = CBufSeg::NewL( 100 ); // expandsize to 100 
+       
+       //todo need to check what's optimal value here
+       CleanupStack::PushL( buf );
+       RBufWriteStream writeStr( *buf );
+       CleanupClosePushL( writeStr );
+       iFile->ExternalizeL( writeStr );
+       writeStr.CommitL();
+       
+       // MSRP message externalized to buffer, now let's move it to flat buffer
+       if ( buf->Size() > KMaxLengthOfIncomingMessageExt )
+           {
+           // invalid message size
+           User::Leave( KErrArgument );
+           }
+
+       buf->Read( 0, iExtMessageBuffer, buf->Size() );
+       CleanupStack::PopAndDestroy( 2 ); // buf, writestream
+       
+       delete iFile;
+	   iFile = NULL;
+          // send the filename
+          User::LeaveIfError( iMSRPSession->ReceiveFileL( iExtMessageBuffer ) );
+       
+       
+    }
+
+CMSRPMessage* CMSRPSessionImplementation::SetFileParamsL(const TFileName& aFileName,const TDesC8& aToPath,
+                                                        const TDesC8& aFromPath, 
+                                                        const TDesC8& aMimeType )
+    {
+      MSRPLOG( "CMSRPSessionImplementation::SetFileParamsL enter" );
+    
+      CMSRPMessage* msrpMessage = new ( ELeave ) CMSRPMessage();
+      CleanupStack::PushL( msrpMessage );
+    
+      //set filename
+      msrpMessage->SetFileName( aFileName );
+    
+      //set to path
+      CMSRPToPathHeader* toPath = CMSRPToPathHeader::DecodeL( aToPath );
+      msrpMessage->SetToPathHeader( toPath );
+
+      //set from path
+      CMSRPFromPathHeader* fromPath = CMSRPFromPathHeader::DecodeL( aFromPath );
+      msrpMessage->SetFromPathHeader( fromPath );
+
+      //set content type
+      if(aMimeType.Length())
+          {
+          CMSRPContentTypeHeader* contentType = CMSRPContentTypeHeader::NewL( aMimeType );
+          msrpMessage->SetContentTypeHeader( contentType );
+          }
+      
+      //set  message id header
+      TTime now;
+      now.HomeTime();
+      TInt64 seed = now.Int64();
+      // Create a random number as the session ID
+      TInt random = Math::Rand( seed );
+      TBuf8< 100 > idString;
+      idString.AppendNum( random );
+      CMSRPMessageIdHeader* messageIdHeader = CMSRPMessageIdHeader::NewL( idString );
+      msrpMessage->SetMessageIdHeader( messageIdHeader );
+      
+      // success report header
+        if( iSuccessReport != ENo )
+            {
+            RStringF string = MSRPStrings::StringF( MSRPStrConsts::EYes );
+            CMSRPSuccessReportHeader* successReportHeader = CMSRPSuccessReportHeader::NewL( string );
+            msrpMessage->SetSuccessReportHeader( successReportHeader );
+            }
+        
+        // failure report header
+        if( iFailureReport != EYes )
+            {
+            RStringF string;
+            CleanupClosePushL(string);
+            if( iFailureReport == ENo )
+                {
+                string = MSRPStrings::StringF( MSRPStrConsts::ENo );
+                }
+            else
+                {
+                string = MSRPStrings::StringF( MSRPStrConsts::EPartial );
+                }
+            CMSRPFailureReportHeader* failureReportHeader = CMSRPFailureReportHeader::NewL( string );
+            msrpMessage->SetFailureReportHeader( failureReportHeader );
+            CleanupStack::PopAndDestroy(); // string
+            }
+      
+          CleanupStack::Pop(msrpMessage); // msrpMessage
+         
+     MSRPLOG( "CMSRPSessionImplementation::SetFileParamsL enter" );
+	 return msrpMessage;
+    }
+
+
+void CMSRPSessionImplementation::NotifyProgress(TBool aFlag)
+    {
+     iProgress = aFlag;
+    }