--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/syncmlfw/common/obex/obexclient/src/NSmlObexClient.cpp Thu Dec 17 09:07:52 2009 +0200
@@ -0,0 +1,527 @@
+/*
+* Copyright (c) 2002 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: SyncML Obex client
+*
+*/
+
+
+#include "NSmlObexClient.h"
+#include "NSmlObexServiceSearcher.h"
+#include "ObexSearcherBase.h"
+#include "Obexsearcherfactory.h"
+#include "ExtBTSearcherObserver.h"
+#include <nsmlconstants.h>
+#include <nsmldebug.h>
+
+#include "nsmlerror.h"
+#include "wbxml2xmlconverter.h"
+
+//============================================================
+// CNsmlObexClient definition
+//============================================================
+
+
+//------------------------------------------------------------
+// CNsmlObexClient::NewL()
+//------------------------------------------------------------
+CNsmlObexClient* CNsmlObexClient::NewL()
+ {
+ CNsmlObexClient* self = new (ELeave) CNsmlObexClient();
+ CleanupStack::PushL( self );
+ self->ConstructL( ObexName );
+ CleanupStack::Pop(); //self
+ return self;
+ }
+
+//------------------------------------------------------------
+// CNsmlObexClient::CNsmlObexClient()
+//------------------------------------------------------------
+CNsmlObexClient::CNsmlObexClient(): CActive(CActive::EPriorityStandard),
+ iState(EDisconnected), iDataPtr( 0, 0 )
+ {
+ CActiveScheduler::Add( this );
+ }
+
+//------------------------------------------------------------
+// CNsmlObexClient* CreateCNsmlObexClientL()
+//------------------------------------------------------------
+EXPORT_C CNsmlObexClient* CreateCNsmlObexClientL()
+ {
+ return CNsmlObexClient::NewL();
+ }
+
+//------------------------------------------------------------
+// CNsmlObexClient::ConstructL( const TDesC8& /*aName*/ )
+//------------------------------------------------------------
+void CNsmlObexClient::ConstructL( const TDesC8& /*aName*/ )
+ {
+ iDataBuf = CBufFlat::NewL( KNSmlObexClientGranularity );
+ iCurrObject = CObexBufObject::NewL( iDataBuf );
+ }
+
+//------------------------------------------------------------
+// CNsmlObexClient::~CNsmlObexClient()
+//------------------------------------------------------------
+CNsmlObexClient::~CNsmlObexClient()
+ {
+ if( iClient )
+ {
+ iClient->Disconnect(iStatus);
+ User::After( 500000 );
+ delete iClient;
+ User::WaitForRequest( iStatus );
+ }
+
+ Cancel();
+ delete iDataBuf;
+ delete iMimeType;
+ delete iCurrObject;
+ delete iObexSearcher;
+ }
+
+//------------------------------------------------------------
+// CNsmlObexClient::DoCancel()
+//------------------------------------------------------------
+void CNsmlObexClient::DoCancel()
+ {
+ TRequestStatus* status = iAgentStatus;
+
+ delete iClient;
+ iClient = NULL;
+
+ if( *status == KRequestPending )
+ {
+ User::RequestComplete( status, KErrCancel );
+ }
+ }
+
+//------------------------------------------------------------
+// CNsmlObexClient::RunL()
+//------------------------------------------------------------
+void CNsmlObexClient::RunL()
+ {
+ TInt error( iStatus.Int() );
+ TRequestStatus* status = iAgentStatus;
+
+ DBG_FILE_CODE( iStatus.Int(), _S8("CNsmlObexClient::RunL \
+ Before error conversion : ") );
+ ErrorConversion( iStatus.Int(), error );
+
+ if ( iStatus != KErrNone )
+ {
+ if ( iState == EGettingConnection &&
+ iStatus == KErrIrObexClientPeerDoesNotHaveObex )
+ {
+ iState = EConnectionFailed;
+ ConnectToServerL();
+ }
+ else if ( iState == EDisconnecting && iStatus == KErrDisconnected )
+ {
+ iState = EDisconnected;
+ User::RequestComplete( status, error );
+ }
+ else
+ {
+ iState = EDisconnected;
+ User::RequestComplete( status, KErrCancel );
+ }
+ }
+ else
+ {
+ switch ( iState )
+ {
+ case EGettingConnection:
+ case EConnectionFailed:
+ iState = EWaitingToSend;
+ User::RequestComplete( status, error );
+ break;
+
+ case EWaitingToSend:
+ iState = EWaitingToReceive;
+ User::RequestComplete( status, error );
+ break;
+
+ case EWaitingToReceive:
+ iDataPtr = this->iDataBuf->Ptr( 0 );
+ iState = EWaitingToSend;
+ User::RequestComplete( status, error );
+DBG_DUMP((void*)iDataPtr.Ptr(), iDataPtr.Length(), _S8("ReceiveDataL (WBXML)"));
+#ifdef __NSML_DEBUG__
+_DBG_FILE("CNsmlObexClient::RunL: CWbxml2XmlConverter::ConvertL() begin");
+CWbxml2XmlConverter* c;
+c = CWbxml2XmlConverter::NewLC();
+c->ConvertL(iDataPtr.Ptr(), iDataPtr.Length());
+DBG_DUMP((void*)c->Document().Ptr(), c->Document().Length(), _S8("ReceiveDataL (XML)") );
+CleanupStack::PopAndDestroy(); // c
+_DBG_FILE("CNsmlObexClient::RunL: CWbxml2XmlConverter::ConvertL() end");
+#endif // __NSML_DEBUG__
+ break;
+
+ case EDisconnecting:
+ iState = EDisconnected;
+ User::RequestComplete( iAgentStatus, KErrNone );
+ break;
+
+ default:
+ Panic( EBTObjectExchangeSdpRecordDelete );
+ break;
+ };
+ }
+ }
+
+//------------------------------------------------------------
+// CNsmlObexClient::ConnectL( TNSmlObexTransport aTransport, TBool /*aServerAlerted*/, TDesC8& aMimeType, TRequestStatus &aStatus )
+//------------------------------------------------------------
+void CNsmlObexClient::ConnectL(
+ TNSmlObexTransport aTransport,
+ TBool /*aServerAlerted*/,
+ TDesC8& aMimeType,
+ TRequestStatus &aStatus )
+ {
+ iAgentStatus = &aStatus;
+ // agent
+ *iAgentStatus = KRequestPending;
+
+ delete iMimeType;
+ iMimeType = NULL;
+ iMimeType = HBufC8::NewL( aMimeType.Length() );
+ TPtr8 iMIMEptr( iMimeType->Des() );
+ iMIMEptr.Copy( aMimeType );
+
+ if ( iState == EDisconnected && !IsActive() )
+ {
+
+ //Delete old and create new device/service searcher
+ delete iObexSearcher;
+ iObexSearcher = NULL;
+
+ //Handle bluetooth as a special case:
+ if ( aTransport == EObexBt )
+ {
+ iObexSearcher = CObexSearcherFactory::CreateBTSearcherL( iBTConnInfo );
+ iObexSearcher->SetObserver( this );
+ iObexSearcher->SetExtObserver( iExtObserver );
+
+ //Search device first if the device address is undefined
+ if ( iBTConnInfo.iDevAddr == TBTDevAddr() )
+ {
+ iObexSearcher->SearchDeviceL();
+ }
+ else
+ {
+ //else skip device search and jump straight to the service search
+ iObexSearcher->SearchServiceL();
+ }
+ }
+ else
+ {
+ //Other cases, only IrDA so far
+ iObexSearcher = CObexSearcherFactory::CreateObexSearcherL( aTransport );
+ iObexSearcher->SetObserver( this );
+ iObexSearcher->SetExtObserver( iExtObserver );
+ iObexSearcher->SearchDeviceL();
+ }
+
+ }
+ else
+ {
+ //debug here
+ User::Leave( KErrInUse );
+ }
+ }
+
+//------------------------------------------------------------
+// CNsmlObexClient::ConnectToServerL()
+//------------------------------------------------------------
+void CNsmlObexClient::ConnectToServerL()
+ {
+ if (iClient)
+ {
+ delete iClient;
+ iClient = NULL;
+ }
+
+ //Let the obex searcher create the obex client
+ iClient = iObexSearcher->CreateObexClientL();
+
+ iCurrObject->SetTargetL( KClientTargetHeader );
+ iClient->Connect( *iCurrObject, iStatus );
+ SetActive();
+ }
+
+//------------------------------------------------------------
+// CNsmlObexClient::SendDataL( TDesC8& aStartPtr, TBool /*aFinalPacket*/, TRequestStatus &aStatus )
+//------------------------------------------------------------
+void CNsmlObexClient::SendDataL( TDesC8& aStartPtr, TBool /*aFinalPacket*/, TRequestStatus &aStatus )
+ {
+ iAgentStatus = &aStatus;
+ // agent
+ *iAgentStatus = KRequestPending;
+
+ if ( iState == EWaitingToReceive )
+ {
+ iClient->Abort();
+ iState = EWaitingToSend;
+ }
+ if ( iState != EWaitingToSend )
+ {
+ User::Leave( KErrDisconnected );
+ }
+ else if ( IsActive() )
+ {
+ User::Leave( KErrInUse );
+ }
+
+ iCurrObject->Reset();
+
+ DBG_DUMP((void*)aStartPtr.Ptr(), aStartPtr.Length(),
+ _S8("SendDataL (WBXML)") );
+#ifdef __NSML_DEBUG__
+ _DBG_FILE("CNsmlObexClient::SendDataL: CWbxml2XmlConverter::ConvertL() begin");
+ CWbxml2XmlConverter* c = CWbxml2XmlConverter::NewLC();
+ c->ConvertL(aStartPtr.Ptr(), aStartPtr.Length());
+ DBG_DUMP((void*)c->Document().Ptr(), c->Document().Length(),
+ _S8("SendDataL (XML)") );
+ CleanupStack::PopAndDestroy(); // c
+ _DBG_FILE("CNsmlObexClient::SendDataL: CWbxml2XmlConverter::ConvertL() end");
+#endif // __NSML_DEBUG__
+
+ iDocumentLength = aStartPtr.Length();
+
+ iDataBuf->Reset();
+ iDataBuf->InsertL( 0, aStartPtr );
+ TRAPD( err, iCurrObject->SetDataBufL( iDataBuf ) );
+
+ if( KErrNone == err )
+ {
+ TBuf8<KNameLen> str;
+ str.Copy( this->iMimeType->Des() );
+ iCurrObject->SetTypeL( str );
+
+ iClient->Put( *iCurrObject, iStatus );
+ SetActive ();
+ }
+ }
+//------------------------------------------------------------
+// CNsmlObexClient::ReceiveDataL( TDes8& aStartPtr, TRequestStatus &aStatus )
+//------------------------------------------------------------
+void CNsmlObexClient::ReceiveDataL( TPtr8& aStartPtr, TRequestStatus &aStatus )
+ {
+ iAgentStatus = &aStatus;
+ // agent
+ *iAgentStatus = KRequestPending;
+
+ iDataPtr.Set( aStartPtr );
+
+ if ( iState != EWaitingToReceive )
+ {
+ User::Leave( KErrDisconnected );
+ }
+ else if ( IsActive() )
+ {
+ User::Leave( KErrInUse );
+ }
+ iDataBuf->Reset();
+ iCurrObject->Reset();
+
+ TBuf8<KNameLen> str;
+ str.Copy( this->iMimeType->Des() );
+ iCurrObject->SetTypeL( str );
+
+ iClient->Get( *iCurrObject, iStatus );
+
+ DBG_DUMP((void*)aStartPtr.Ptr(), aStartPtr.Length(),
+ _S8("ReceiveDataL (WBXML)"));
+#ifdef __NSML_DEBUG__
+ _DBG_FILE("CNsmlObexClient::ReceiveDataL: CWbxml2XmlConverter::ConvertL()\
+ begin");
+ CWbxml2XmlConverter* c = CWbxml2XmlConverter::NewLC();
+ c->ConvertL(aStartPtr.Ptr(), aStartPtr.Length());
+ DBG_DUMP((void*)c->Document().Ptr(), c->Document().Length(),
+ _S8("ReceiveDataL (XML)") );
+ CleanupStack::PopAndDestroy(); // c
+ _DBG_FILE("CNsmlObexClient::ReceiveDataL: CWbxml2XmlConverter::ConvertL() end");
+#endif // __NSML_DEBUG__
+
+ SetActive ();
+ }
+//------------------------------------------------------------
+// CNsmlObexClient::CloseCommunicationL( TRequestStatus &aStatus )
+//------------------------------------------------------------
+void CNsmlObexClient::CloseCommunicationL( TRequestStatus &aStatus )
+ {
+ iAgentStatus = &aStatus;
+
+ DisconnectL();
+
+ if( *iAgentStatus == KRequestPending )
+ {
+ User::RequestComplete( iAgentStatus, KErrCancel );
+ }
+ }
+//------------------------------------------------------------
+// CNsmlObexClient::StopL()
+//------------------------------------------------------------
+void CNsmlObexClient::StopL()
+ {
+ if ( iClient )
+ {
+ delete iClient;
+ iClient = NULL;
+ }
+ }
+//------------------------------------------------------------
+// CNsmlObexClient::DisconnectL()
+//------------------------------------------------------------
+void CNsmlObexClient::DisconnectL()
+ {
+ if ( iObexSearcher )
+ {
+ iObexSearcher->Cancel();
+ }
+
+ StopL();
+ iState = EDisconnected;
+ }
+
+//------------------------------------------------------------
+// CNsmlObexClient::IsBusy()
+//------------------------------------------------------------
+TBool CNsmlObexClient::IsBusy()
+ {
+ return IsActive();
+ }
+
+//------------------------------------------------------------
+// CNsmlObexClient::IsConnected()
+//------------------------------------------------------------
+TBool CNsmlObexClient::IsConnected()
+ {
+ return iState != EDisconnected;
+ }
+
+//----------------------------------------------------------------------------
+// CNsmlObexClient::HandleDeviceFoundL()
+//----------------------------------------------------------------------------
+//
+void CNsmlObexClient::HandleDeviceFoundL()
+ {
+ TRAPD( err, iObexSearcher->SearchServiceL(); )
+
+ DBG_FILE_CODE( err, _S8("CNsmlObexClient::HandleDeviceFoundL \
+ Before error conversion : ") );
+ ErrorConversion( err, err );
+
+ if ( err != KErrNone )
+ {
+ TRequestStatus* status = iAgentStatus;
+ User::RequestComplete( status, err );
+ }
+ }
+
+//----------------------------------------------------------------------------
+// CNsmlObexClient::HandleDeviceErrorL( TInt aErr )
+//----------------------------------------------------------------------------
+//
+void CNsmlObexClient::HandleDeviceErrorL( TInt aErr )
+ {
+ DBG_FILE_CODE( aErr, _S8("CNsmlObexClient::HandleDeviceErrorL \
+ Before error conversion : ") );
+ ErrorConversion( aErr, aErr );
+
+ TRequestStatus* status = iAgentStatus;
+ User::RequestComplete( status, aErr );
+ }
+
+//----------------------------------------------------------------------------
+// CNsmlObexClient::HandleServiceFoundL()
+//----------------------------------------------------------------------------
+//
+void CNsmlObexClient::HandleServiceFoundL()
+ {
+ TRAPD( err,
+ iState = EGettingConnection;
+ ConnectToServerL();
+ )
+
+ DBG_FILE_CODE( err, _S8("CNsmlObexClient::HandleServiceFoundL \
+ Before error conversion : ") );
+ ErrorConversion( err, err );
+
+ if ( err != KErrNone )
+ {
+ TRequestStatus* status = iAgentStatus;
+ User::RequestComplete( status, err );
+ }
+ }
+
+//----------------------------------------------------------------------------
+// CNsmlObexClient::HandleServiceErrorL( TInt aErr )
+//----------------------------------------------------------------------------
+//
+void CNsmlObexClient::HandleServiceErrorL( TInt aErr )
+ {
+ DBG_FILE_CODE( aErr, _S8("CNsmlObexClient::HandleServiceErrorL \
+ Before error conversion : ") );
+ ErrorConversion( aErr, aErr );
+
+ TRequestStatus* status = iAgentStatus;
+ User::RequestComplete( status, aErr );
+ }
+
+//----------------------------------------------------------------------------
+// CNsmlObexClient::SetBTConnInfo( const TBTDevAddr aBTDevAddr, const TUUID aUid )
+//----------------------------------------------------------------------------
+//
+void CNsmlObexClient::SetBTConnInfo( const TBTDevAddr aBTDevAddr, const TUUID aUid )
+ {
+ TBTConnInfo info;
+ info.iDevAddr = aBTDevAddr;
+ info.iServiceClass = aUid;
+
+ iBTConnInfo = info;
+ }
+
+//----------------------------------------------------------------------------
+// CNsmlObexClient::SetExtObserver( MExtBTSearcherObserver* aExtObserver )
+//----------------------------------------------------------------------------
+//
+void CNsmlObexClient::SetExtObserver( MExtBTSearcherObserver* aExtObserver )
+ {
+ iExtObserver = aExtObserver;
+ }
+
+//----------------------------------------------------------------------------
+// CNsmlObexClient::ErrorConversion( const TInt aError, TInt& aErrCode )
+//----------------------------------------------------------------------------
+//
+void CNsmlObexClient::ErrorConversion( const TInt aError, TInt& aErrCode )
+ {
+ if ( aError > -6000 && aError <= -1 )
+ {
+ aErrCode = KErrCancel;
+ return;
+ }
+ else if ( aError > -7000 && aError <= -6000 )
+ {
+ // Conversion of EPageTimedOut and ERemoteHostTimeout errors
+ aErrCode = TNSmlError::ESmlCommunicationError;
+ return;
+ }
+
+ aErrCode = aError;
+ }
+
+//End of File
+