btobexprofiles/obexsendservices/obexservicesendutils/src/BTServiceClient.cpp
changeset 37 91746b151f97
child 45 b0aebde9b1fb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/btobexprofiles/obexsendservices/obexservicesendutils/src/BTServiceClient.cpp	Fri Jun 11 13:48:51 2010 +0300
@@ -0,0 +1,600 @@
+/*
+* Copyright (c) 2002-2007 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:  Obex client implementation
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <apgcli.h> // RApaLSession
+
+#include "BTServiceClient.h"
+#include "BTServiceUtils.h"
+#include "BTConnectionTimer.h"
+#include "BTSUDebug.h"
+
+const TUint16 KMtuSizeReceiv    = 0xFFFF;  // 64kB
+const TUint16 KMtuSizeTrans     = 0x3000;  // 12kB 
+const TInt    KBufferSize       = 0x4000;  // 16kB
+
+const TInt KBTConnectionTimeout = 20000000; // 20 seconds
+const TInt KBTAbortTimeout      = 2000000;  // 20 seconds
+
+// CONSTANTS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CBTServiceClient::CBTServiceClient
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CBTServiceClient::CBTServiceClient( MBTServiceClientObserver* aObserver ) 
+    : CActive( EPriorityStandard ), 
+      iClientState( EBTSCliIdle ), 
+      iObserver( aObserver )                           
+    {
+    CActiveScheduler::Add( this );
+    }
+
+// -----------------------------------------------------------------------------
+// CBTServiceClient::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CBTServiceClient::ConstructL( const TBTDevAddr& aRemoteDevice,
+                                   const TUint aRemotePort,
+                                   RArray<CObexHeader*> aHeaderList )
+    {
+    FLOG(_L("[BTSU]\t CBTServiceClient::ConstructL()"));
+
+    iTotalBytesSent = 0;
+    // Create Obex Client
+    //
+    TObexBluetoothProtocolInfo info;
+    info.iTransport = KBTSProtocol;
+    info.iAddr.SetBTAddr( aRemoteDevice );
+    info.iAddr.SetPort( aRemotePort );
+    
+    TObexProtocolPolicy obexProtocolPolicy;
+    obexProtocolPolicy.SetReceiveMtu( KMtuSizeReceiv  );
+    obexProtocolPolicy.SetTransmitMtu( KMtuSizeTrans  );
+	
+    iClient = CObexClient::NewL( info, obexProtocolPolicy );
+    iClient->SetCallBack( *this );
+    iPasskeyRequest = new (ELeave) CBTSUPasskeyRequest();
+
+    // Create Connect-object
+    //
+    iConnectObject = CObexNullObject::NewL();
+
+    if ( aHeaderList.Count() > 0 )
+        {
+        for ( TInt index = 0; index < aHeaderList.Count(); index++ )
+            {
+            iConnectObject->AddHeaderL( *aHeaderList[index] );
+            }
+        }
+
+    // Establish client connection
+    //
+    iClient->Connect( *iConnectObject, iStatus );
+    SetActive();
+    iClientState = EBTSCliConnecting;
+    iConnectionTimer = CBTConnectionTimer::NewL(this);
+    iConnectionTimer -> SetTimeOut ( TTimeIntervalMicroSeconds32( KBTConnectionTimeout ) );    
+    iConnectionTimer -> Start();
+
+    FLOG(_L("[BTSU]\t CBTServiceClient::ConstructL() completed"));
+    }
+
+// -----------------------------------------------------------------------------
+// CBTServiceClient::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CBTServiceClient* CBTServiceClient::NewL( MBTServiceClientObserver* aObserver,
+                                          const TBTDevAddr& aRemoteDevice,
+                                          const TUint aRemotePort,
+                                          RArray<CObexHeader*> aHeaderList )
+    {
+    CBTServiceClient* self = new( ELeave ) CBTServiceClient( aObserver );
+    CleanupStack::PushL( self );
+    self->ConstructL( aRemoteDevice, aRemotePort, aHeaderList );
+    CleanupStack::Pop();
+    return self;
+    }
+
+    
+// Destructor
+CBTServiceClient::~CBTServiceClient()
+    {
+    FLOG(_L("[BTSU]\t CBTServiceClient::~CBTServiceClient()"));
+    
+    if(iConnectionTimer)
+        {
+        iConnectionTimer->Cancel();
+        delete iConnectionTimer;
+        iConnectionTimer=NULL;
+        }    
+    Cancel();
+    if(iClient)
+        {
+        delete iClient;
+        iClient = NULL;
+        }    
+    delete iPasskeyRequest;
+    iPasskeyRequest = NULL;
+
+    if ( iConnectObject )
+        {
+        iConnectObject->Reset();
+        delete iConnectObject;
+        iConnectObject = NULL;
+        }
+    if ( iObjectBuffer )
+        {
+        iObjectBuffer->Reset();
+        delete iObjectBuffer;
+        iObjectBuffer = NULL;
+        }
+    if ( iGetObject )
+        {
+        delete iGetObject;
+        iGetObject = NULL;
+        }
+    if ( iPutObject )
+        {
+        iPutObject->Reset();
+        delete iPutObject;
+        iPutObject = NULL;
+        }
+     if ( iPutBufObject )
+        {
+        iPutBufObject->Reset();
+        delete iPutBufObject;
+        iPutBufObject = NULL;
+        }
+           
+    if(iBuffer)
+        {
+        delete iBuffer;
+        iBuffer = NULL;
+        }
+
+    FLOG(_L("[BTSU]\t CBTServiceClient::~CBTServiceClient() completed"));
+    }
+
+// -----------------------------------------------------------------------------
+// CBTServiceClient::GetObjectL
+// -----------------------------------------------------------------------------
+//
+void CBTServiceClient::GetObjectL( RArray<CObexHeader*>& aHeaderList,
+                                   const TDesC& aFileName )
+    {
+    FLOG(_L("[BTSU]\t CBTServiceClient::GetObjectL()"));
+
+    if ( iGetObject )
+        {
+        iGetObject->Reset();
+        delete iGetObject;
+        iGetObject = NULL;
+        }
+
+    // Create object
+    //
+    if ( aFileName == KNullDesC )
+        {
+        iObjectBuffer = CBufFlat::NewL( KBTSUDataBufferExpandSize );
+        iGetObject = CObexBufObject::NewL( iObjectBuffer );
+        }
+    else
+        {        
+        iGetObject = CObexBufObject::NewL( NULL );
+        iGetObject->SetDataBufL( aFileName );
+        }
+
+    // Set headers
+    //
+    if ( aHeaderList.Count() > 0 )
+        {
+        for ( TInt index = 0; index < aHeaderList.Count(); index++ )
+            {
+            iGetObject->AddHeaderL( *aHeaderList[index] );
+            }
+        }
+
+    // Send get request
+    //
+    iClient->Get( *iGetObject, iStatus );
+    SetActive();
+    iClientState = EBTSCliGetting;
+
+    FLOG(_L("[BTSU]\t CBTServiceClient::GetObjectL() completed"));
+    }
+
+
+// -----------------------------------------------------------------------------
+// CBTServiceClient::PutObjectL
+// -----------------------------------------------------------------------------
+//
+void CBTServiceClient::PutObjectL( RArray<CObexHeader*>& aHeaderList,
+                                   const TDesC& aFileName )
+    {
+    FLOG(_L("[BTSU]\t CBTServiceClient::PutObjectL()"));
+
+    if ( iPutObject )
+        {
+        iPutObject->Reset();
+        delete iPutObject;
+        iPutObject = NULL;
+        }
+
+    // Create object
+    //
+    iPutObject = CObexFileObject::NewL();
+
+    // Set body
+    //
+    
+    if ( aFileName != KNullDesC )
+        {
+        iPutObject->InitFromFileL ( aFileName );
+        }
+    
+    // Set headers
+    //
+    if ( aHeaderList.Count() > 0 )
+        {
+        for ( TInt index = 0; index < aHeaderList.Count(); index++ )
+            {
+            iPutObject->AddHeaderL( *aHeaderList[index] );
+            }
+        }
+
+    // Send object
+    //
+    iClient->Put( *iPutObject, iStatus );
+	SetActive();
+    iClientState = EBTSCliPutting;
+
+    FLOG(_L("[BTSU]\t CBTServiceClient::PutObjectL() completed"));
+    }
+
+// -----------------------------------------------------------------------------
+// CBTServiceClient::PutObjectL
+// -----------------------------------------------------------------------------
+//
+void CBTServiceClient::PutObjectL( RArray<CObexHeader*>& aHeaderList,
+                                   RFile& aFile )
+    {
+    FLOG(_L("[BTSU]\t CBTServiceClient::PutObjectL()"));
+
+    if ( iPutObject )
+        {
+        iPutObject->Reset();
+        delete iPutObject;
+        iPutObject = NULL;
+        }
+
+    if ( iPutBufObject )
+        {
+        iPutBufObject->Reset();
+        delete iPutBufObject;
+        iPutBufObject = NULL;
+        }
+    // Create object
+    //
+    iPutBufObject = CObexBufObject::NewL(NULL);
+
+    // Resolve MIME type
+    //
+    
+    RApaLsSession session;
+    HBufC8* mimeType = NULL;
+    TDataType type;
+    
+    TUid uid;
+    // Set headers
+    //
+    if ( aHeaderList.Count() > 0 )
+        {
+        for ( TInt index = 0; index < aHeaderList.Count(); index++ )
+            {
+            iPutBufObject->AddHeaderL( *aHeaderList[index] );
+            }
+        }
+        
+    TDesC8 typeheader=iPutBufObject->Type();   
+    if ( typeheader == KNullDesC8 )    
+        {        
+        User::LeaveIfError( session.Connect() );
+        CleanupClosePushL( session );
+        TInt error = session.AppForDocument( aFile, uid, type );    
+        if ( error == KErrNone )
+            {
+            mimeType = type.Des8().AllocLC();
+            iPutBufObject->SetTypeL(*mimeType);    
+            CleanupStack::PopAndDestroy();
+            }          
+        CleanupStack::Pop(); // session
+        session.Close();       
+        }    
+    
+    //Set object information
+    //
+    TFileName filename;    
+    aFile.Name(filename);
+    
+    TInt size;
+    aFile.Size(size);
+    iPutBufObject->SetLengthL(size);			
+    iPutBufObject->SetNameL(filename);
+    
+    TTime time;
+	if ( aFile.Modified(time) == KErrNone )
+	    {
+		iPutBufObject->SetTimeL(time);
+	    }
+	    
+    RFile file;    
+    file.Duplicate(aFile);
+    
+    iBuffer = CBufFlat::NewL(KBufferSize);
+    iBuffer ->ResizeL(KBufferSize);
+    
+    TObexRFileBackedBuffer bufferdetails(*iBuffer,file,CObexBufObject::ESingleBuffering);  
+    iPutBufObject->SetDataBufL(bufferdetails);         
+    
+    // Send object
+    //        
+    iClient->Put( *iPutBufObject, iStatus );
+	SetActive();
+    iClientState = EBTSCliPutting;
+
+    FLOG(_L("[BTSU]\t CBTServiceClient::PutObjectL() completed"));
+    }
+
+// -----------------------------------------------------------------------------
+// CBTServiceClient::CloseClientConnection
+// -----------------------------------------------------------------------------
+//
+void CBTServiceClient::CloseClientConnection()
+    {
+    FLOG(_L("[BTSU]\t CBTServiceClient::CloseClientConnection()"));
+
+    iClient->Disconnect( iStatus );
+   	SetActive();
+    iClientState = EBTSCliDisconnecting;
+
+    FLOG(_L("[BTSU]\t CBTServiceClient::CloseClientConnection() completed"));
+    }
+
+// -----------------------------------------------------------------------------
+// CBTServiceClient::GetProgressStatus
+// -----------------------------------------------------------------------------
+//
+TInt CBTServiceClient::GetProgressStatus()
+    {
+    FLOG(_L("[BTSU]\t CBTServiceClient::GetProgressStatus()"));
+
+    TInt bytesSent = 0;
+    if ( iPutBufObject )
+        {
+        bytesSent = iPutBufObject->BytesSent();
+        }
+    if ( iPutObject )
+        {
+        bytesSent = iPutObject->BytesSent();
+        }
+
+    FTRACE(FPrint(_L("[BTSU]\t CBTServiceClient::GetProgressStatus() completed, bytes sent %d"), iTotalBytesSent + bytesSent ) );
+
+   // return iTotalBytesSent + bytesSent;
+    return bytesSent;
+    }
+
+// -----------------------------------------------------------------------------
+// CBTServiceClient::GetUserPasswordL
+// -----------------------------------------------------------------------------
+//
+void CBTServiceClient::GetUserPasswordL( const TDesC& /*aRealm*/ )
+    {
+    FLOG(_L("[BTSU]\t CBTServiceClient::GetUserPasswordL()"));
+
+    iPasskeyRequest->StartPassKeyRequestL( iClient );
+
+    FLOG(_L("[BTSU]\t CBTServiceClient::GetUserPasswordL() completed"));
+    }
+
+// -----------------------------------------------------------------------------
+// CBTServiceClient::DoCancel
+// -----------------------------------------------------------------------------
+//
+void CBTServiceClient::DoCancel()
+    {
+    FLOG(_L("[BTSU]\t CBTServiceClient::DoCancel()"));
+    
+    if ( iConnectionTimer )
+        {
+        iConnectionTimer->Cancel();
+        delete iConnectionTimer;
+        iConnectionTimer=NULL;
+        }    
+    // Deleting obexclient is the only way to cancel active requests
+    //                
+    if ( iClient )
+        {
+        delete iClient;
+        iClient = NULL;
+        }    
+    
+    FLOG(_L("[BTSU]\t CBTServiceClient::DoCancel() completed"));
+    }
+
+// -----------------------------------------------------------------------------
+// CBTServiceClient::RunL
+// -----------------------------------------------------------------------------
+//
+void CBTServiceClient::RunL()
+    {
+    FTRACE(FPrint(_L("[BTSU]\t CBTServiceClient::RunL() status %d"), iStatus.Int() ) );
+    if ( !iObserver )
+        {
+        return;    
+        }
+    switch ( iClientState )
+        {
+        case EBTSCliConnecting:
+            {
+            FLOG(_L("[BTSU]\t CBTServiceClient::RunL() EBTSCliConnecting"));
+            iConnectObject->Reset();
+            if(iConnectionTimer)
+                {
+                iConnectionTimer->Cancel();
+                delete iConnectionTimer;
+                iConnectionTimer=NULL;
+                }    
+            iObserver->ConnectCompleted( iStatus.Int() );
+            break;
+            }
+
+        case EBTSCliPutting:
+            {
+            FLOG(_L("[BTSU]\t CBTServiceClient::RunL() EBTSCliPutting"));
+            if(iPutBufObject)
+                {
+                iTotalBytesSent += iPutBufObject->BytesSent();    
+                }
+            else
+                {
+                 iTotalBytesSent += iPutObject->BytesSent();         
+                }
+			   
+			const CObexHeaderSet& response=iClient->GetPutFinalResponseHeaders();		
+			if ( iPutBufObject )
+				{
+				iPutBufObject->Reset();
+				delete iPutBufObject;
+				iPutBufObject = NULL;
+				}
+				
+			if ( iPutObject )
+				{
+				iPutObject->Reset();
+				delete iPutObject;
+				iPutObject = NULL;
+				}
+			if(iBuffer)
+                {
+                delete iBuffer;
+                iBuffer = NULL;
+                }
+			//put there call getEnv
+            iObserver->PutCompleted( iStatus.Int(), &response);
+            FLOG(_L("[BTSU]\t CBTServiceClient::RunL() EBTSCliPutting done"));
+            break;
+            }
+
+        case EBTSCliGetting:
+            {
+            iObserver->GetCompleted( iStatus.Int(), iGetObject );
+            break;
+            }
+
+        case EBTSCliDisconnecting:
+            {
+            // Any errors are ignored
+            //
+            iObserver->ClientConnectionClosed();
+            break;
+            }
+
+        case EBTSCliIdle:
+        default:
+           {
+           FLOG(_L("[BTSU]\t CBTServiceClient::RunL() ERROR, unhandled case"));           
+           break;
+           }
+        }
+
+    FLOG(_L("[BTSU]\t CBTServiceClient::RunL() completed"));
+    }
+    
+// -----------------------------------------------------------------------------
+// CBTServiceClient::ConnectionTimedOut
+// -----------------------------------------------------------------------------
+//	
+void CBTServiceClient::ConnectionTimedOut()
+    {
+    FLOG(_L("[BTSU]\t CBTServiceClient::ConnectionTimedOut"));    
+    switch ( iClientState )
+        {
+        case EBTSCliConnecting:
+            {
+            iObserver->ConnectTimedOut();      
+            break;
+            }
+        case EBTSCliGetting:
+            {
+            iObserver->GetCompleted( KErrAbort, iGetObject );    
+            break;
+            }    
+        case EBTSCliPutting:
+            {
+            const CObexHeaderSet& response=iClient->GetPutFinalResponseHeaders();	    
+            iObserver->PutCompleted( KErrAbort, &response );    
+			break;
+            }        
+        default:    
+        FLOG(_L("[BTSU]\t CBTServiceClient::ConnectionTimedOut unhandled client state "));
+        }
+          
+    FLOG(_L("[BTSU]\t CBTServiceClient::ConnectionTimedOut"));    
+    }
+// -----------------------------------------------------------------------------
+// CBTServiceClient::Abort
+// -----------------------------------------------------------------------------
+//	    
+void CBTServiceClient::Abort()
+    {
+    FLOG(_L("[BTSU]\t CBTServiceClient::Abort"));        
+    if ( iClient && ( iClientState == EBTSCliPutting || iClientState == EBTSCliGetting )  )
+        {    
+        if ( iConnectionTimer )    
+            {
+            delete iConnectionTimer;
+            iConnectionTimer = NULL;    
+            }
+        TRAPD(trapErr, iConnectionTimer = CBTConnectionTimer::NewL(this) );
+        if ( trapErr  != KErrNone)
+            {
+            iObserver->ConnectCompleted( KErrAbort );        
+            return;
+            }        
+        iConnectionTimer -> SetTimeOut ( TTimeIntervalMicroSeconds32( KBTAbortTimeout ) );    
+        iConnectionTimer -> Start();    
+        iClient->Abort();    
+        }
+    else if ( iClient && iClientState == EBTSCliConnecting)
+        {
+        iObserver->ConnectCompleted( KErrAbort );    
+        }
+    FLOG(_L("[BTSU]\t CBTServiceClient::Abort"));            
+    
+    }
+
+//  End of File