/*
* 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 transport interface
*
*/
#include <CoreApplicationUIsSDKCRKeys.h>
#include <btengdomaincrkeys.h>
#include <centralrepository.h>
#include <ApUtils.h>
#include "nsmltransport.h"
#include "nsmlhttp.h"
#include "NSmlObexClient.h"
#include "nsmlobexserverbinding.h"
#include "nsmlerror.h"
#include <featmgr.h>
//============================================================
// CNSmlTransport definition
//============================================================
EXPORT_C CNSmlTransport::CNSmlTransport()
{
}
//------------------------------------------------------------
// desctructor
//------------------------------------------------------------
EXPORT_C CNSmlTransport::~CNSmlTransport()
{
DBG_FILE(_S8("CNSmlTransport::~CNSmlTransport() begin"));
if( iObexBinding )
{
DBG_FILE(_S8("delete iObexBinding"));
delete iObexBinding;
iObexBinding = NULL;
iObexLibrary.Close();
}
if( iHTTPBinding )
{
DBG_FILE(_S8("delete iHTTPBinding"));
delete iHTTPBinding;
iHTTPBinding = NULL;
iHTTPLibrary.Close();
}
if( iObexServerBinding )
{
DBG_FILE(_S8("delete iObexServerBinding"));
delete iObexServerBinding;
iObexServerBinding = NULL;
iObexServerBindingLib.Close();
}
DBG_FILE(_S8("CNSmlTransport::~CNSmlTransport() end"));
}
// ---------------------------------------------------------
// CNSmlTransport::NewL()
// Creates new instance of CNSmlTransport.
// Does not leave instance pointer to CleanupStack.
// ---------------------------------------------------------
EXPORT_C CNSmlTransport* CNSmlTransport::NewL()
{
CNSmlTransport* self = CNSmlTransport::NewLC();
CleanupStack::Pop();
return( self );
}
// ---------------------------------------------------------
// CNSmlTransport::NewLC()
// Creates new instance of CNSmlTransport
// Leaves instance pointer to CleanupStack.
// ---------------------------------------------------------
EXPORT_C CNSmlTransport* CNSmlTransport::NewLC()
{
CNSmlTransport* self = new (ELeave) CNSmlTransport();
CleanupStack::PushL( self );
self->ConstructL();
return( self );
}
//------------------------------------------------------------
// 2-phase construct
//------------------------------------------------------------
EXPORT_C void CNSmlTransport::ConstructL()
{
iObex = EFalse;
iObexServer = EFalse;
iBTObserver = 0;
iBTDevAddr = TBTDevAddr( 0 );
iServiceUid = TUUID( 0 );
FeatureManager::InitializeLibL();
iWLANBearer = FeatureManager::FeatureSupported( KFeatureIdProtocolWlan );
FeatureManager::UnInitializeLib();
}
//------------------------------------------------------------
// CNSmlTransport::LoadObexServerBindingDllL()
// Loads OBEX client dll.
//------------------------------------------------------------
void CNSmlTransport::LoadObexServerBindingDllL()
{
DBG_FILE(_S8("CNSmlTransport::LoadObexServerBindingDllL()"));
// Dynamically load DLL
User::LeaveIfError( iObexServerBindingLib.Load( KSmlObexServerBindingLibName ) );
if( iObexServerBindingLib.Type()[1] != KSmlTransBindingUid )
{
DBG_FILE(_S8("KSmlTransBindingUid incorrect..."));
iObexServerBindingLib.Close();
User::Leave( KErrNotFound );
}
TNSmlCreateObexServerBindingFunc CreateCNsmlObexServerBindingL = (TNSmlCreateObexServerBindingFunc)iObexServerBindingLib.Lookup(1);
iObexServerBinding = (CNSmlObexServerBinding*)CreateCNsmlObexServerBindingL();
}
//------------------------------------------------------------
// CNSmlTransport::LoadObexDllL()
// Loads OBEX client dll.
//------------------------------------------------------------
void CNSmlTransport::LoadObexDllL()
{
DBG_FILE(_S8("CNSmlTransport::LoadObexDllL()"));
// Dynamically load DLL
// Check what is the used medium type and load the correct DLL
// BT, IR, USB
if ( iCurrMedium == KUidNSmlMediumTypeUSB )
{
User::LeaveIfError( iObexLibrary.Load( KSmlObexUsbClientLibName ) );
}
else
{
User::LeaveIfError( iObexLibrary.Load( KSmlObexClientLibName ) );
}
if( iObexLibrary.Type()[1] != KSmlTransBindingUid )
{
iObexLibrary.Close();
User::Leave( KErrNotFound );
}
TNSmlCreateObexClientFunc createObexClientL = (TNSmlCreateObexClientFunc)iObexLibrary.Lookup(1);
iObexBinding = (CNsmlObexClient*)createObexClientL();
}
//------------------------------------------------------------
// CNSmlTransport::LoadHTTPDllL()
// Loads HTTP client dll.
//------------------------------------------------------------
void CNSmlTransport::LoadHTTPDllL()
{
DBG_FILE(_S8("CNSmlTransport::LoadHTTPDllL()"));
// Dynamically load DLL
User::LeaveIfError( iHTTPLibrary.Load( KSmlHTTPClientLibName ) );
if( iHTTPLibrary.Type()[1] != KSmlTransBindingUid )
{
iHTTPLibrary.Close();
User::Leave( KErrNotFound );
}
TNSmlCreateHTTPFunc createHTTPClientL = (TNSmlCreateHTTPFunc)iHTTPLibrary.Lookup(1);
iHTTPBinding = (CNSmlHTTP*)createHTTPClientL();
}
// 1.2 CHANGES: Offline mode
//------------------------------------------------------------
// CNSmlTransport::IsInOfflineMode()
// Checks if device is at offline mode
//------------------------------------------------------------
TBool CNSmlTransport::IsInOfflineModeL()
{
TInt operationsAllowed( ECoreAppUIsNetworkConnectionAllowed );
CRepository* rep = CRepository::NewLC( KCRUidCoreApplicationUIs );
rep->Get(KCoreAppUIsNetworkConnectionAllowed, operationsAllowed );
CleanupStack::PopAndDestroy(); //rep
return ( operationsAllowed == ECoreAppUIsNetworkConnectionNotAllowed ) ? ETrue : EFalse;
}
// Changes end
//------------------------------------------------------------
// CNSmlTransport::Connect
// Establishes a communication using the protocol service with the given ID.
//------------------------------------------------------------
EXPORT_C void CNSmlTransport::ConnectL( TUid aMediumType, TBool aServerAlerted, CArrayFixFlat<TUint32>* aIAPIdArray, TDesC8& aURI, TDesC8& aMimeType, TRequestStatus &aStatus, TDesC8& aHTTPusername, TDesC8& aHTTPpassword, TInt aHTTPauthused )
{
DBG_FILE(_S8("Connect starts..."));
iAgentStatus = &aStatus;
iCurrMedium = aMediumType;
if( aMediumType != KUidNSmlMediumTypeInternet )
{
TNSmlObexTransport obexTransport;
if ( aMediumType == KUidNSmlMediumTypeUSB )
{
obexTransport = EObexUsb;
}
else if ( aMediumType == KUidNSmlMediumTypeIrDA )
{
obexTransport = EObexIr;
}
else
{
obexTransport = EObexBt;
if ( IsInOfflineModeL() )
{
TInt btActivationEnabled( EBTEnabledInOfflineMode );
CRepository* rep = CRepository::NewLC( KCRUidBluetoothEngine );
TInt properr = rep->Get( KBTEnabledInOffline, btActivationEnabled );
CleanupStack::PopAndDestroy();
if ( btActivationEnabled == EBTDisabledInOfflineMode )
{
DBG_FILE(_S8("Offline mode set!"));
*iAgentStatus = KRequestPending;
TRequestStatus* status = iAgentStatus;
User::RequestComplete( status, TNSmlError::ESmlStatusNotPossibleInOfflineMode );
return;
}
}
}
Connect( obexTransport, aServerAlerted, aMimeType, aStatus );
}
else
{
TBool errormsg = EFalse;
if(IsInOfflineModeL())
{
// 1.2 CHANGES: Offline mode
if( !iWLANBearer ) // offline mode and no WLAN support
{
errormsg = ETrue;
}
else
{
// used, so it is ok to use first one in the list.
if ( aIAPIdArray->At(0) != 0xffffffff && aIAPIdArray->At(0) != 0xfffffffe )
// 0xffffffff is same as -1 (KErrNotFound) and -2 for Default connection
{
TUint32 accesspointId = aIAPIdArray->At(0);
CCommsDatabase* commDb = CCommsDatabase::NewL();
CleanupStack::PushL(commDb);
CApUtils* aputils = CApUtils::NewLC( *commDb );
TRAP_IGNORE( accesspointId = aputils->WapIdFromIapIdL( accesspointId ) );
TApBearerType bearerType = aputils->BearerTypeL( accesspointId );
CleanupStack::PopAndDestroy( 2 ); //commdb,aputils
if ( bearerType != EApBearerTypeWLAN )
{
errormsg = ETrue;
}
}
}
}
if(errormsg)
{
DBG_FILE(_S8("Offline mode set!"));
*iAgentStatus = KRequestPending;
TRequestStatus* status = iAgentStatus;
User::RequestComplete( status, TNSmlError::ESmlStatusNotPossibleInOfflineMode );
return;
}
// Changes end
// New attributes username and password to support HTTP authentication
Connect( aIAPIdArray, aURI, aMimeType, aStatus, aHTTPusername, aHTTPpassword, aHTTPauthused );
}
}
//------------------------------------------------------------
// CNSmlTransport::Connect
// Establishes a communication for OBEX.
//------------------------------------------------------------
void CNSmlTransport::Connect( TNSmlObexTransport aTransport,TBool aServerAlerted, TDesC8& aMimeType, TRequestStatus &aStatus )
{
DBG_FILE(_S8("OBEX Connect starts..."));
iObex = ETrue;
TInt err( KErrNone );
iAgentStatus = &aStatus;
if( !aServerAlerted ) // starting OBEX client
{
DBG_FILE(_S8("starting OBEX client..."));
if( iObexBinding == NULL )
{
TRAP( err, LoadObexDllL() );
if( err != KErrNone )
{
DBG_FILE(_S8("LoadObexDllL() failed!"));
*iAgentStatus = KRequestPending;
TRequestStatus* status = iAgentStatus;
User::RequestComplete( status, err );
}
}
if( iObexBinding && aTransport == EObexBt && !err )
{
// Set observer to get partners bluetooth address/name
if( iBTObserver )
{
iObexBinding->SetExtObserver( iBTObserver );
}
// Set bluetooth connection info
if( iBTDevAddr != TBTDevAddr( 0 ) || iServiceUid != TUUID( 0 ) )
{
iObexBinding->SetBTConnInfo( iBTDevAddr, iServiceUid );
}
}
if( iObexBinding && !err )
{
TRAP( err, iObexBinding->ConnectL( aTransport, aServerAlerted, aMimeType, aStatus ) );
if( err != KErrNone )
{
DBG_FILE(_S8("iObexBinding->ConnectL() failed"));
*iAgentStatus = KRequestPending;
TRequestStatus* status = iAgentStatus;
User::RequestComplete( status, err );
}
}
}
else
{
DBG_FILE(_S8("starting OBEX server binding..."));
iObexServer = ETrue;
if( iObexServerBinding == NULL )
{
TRAP( err, LoadObexServerBindingDllL() );
if( err != KErrNone )
{
DBG_FILE(_S8("LoadObexServerBindingDllL() failed!"));
*iAgentStatus = KRequestPending;
TRequestStatus* status = iAgentStatus;
User::RequestComplete( status, err );
}
}
if( iObexServerBinding && !err )
{
iObexServerBinding->Connect( aTransport, aServerAlerted, aMimeType, aStatus );
}
}
}
//------------------------------------------------------------
// CNSmlTransport::Connect
// Establishes a communication using the protocol service with the given ID.
//------------------------------------------------------------
void CNSmlTransport::Connect( CArrayFixFlat<TUint32>* aIAPIdArray, TDesC8& aURI, TDesC8& aMimeType, TRequestStatus &aStatus, TDesC8& aHTTPusername, TDesC8& aHTTPpassword, TInt aHTTPauthused )
{
DBG_FILE(_S8("HTTP Connect starts..."));
TInt err( KErrNone );
iAgentStatus = &aStatus;
iObex = EFalse;
if( iHTTPBinding == NULL )
{
TRAP( err, LoadHTTPDllL() );
if( err != KErrNone )
{
DBG_FILE(_S8("LoadHTTPDllL() failed!"));
*iAgentStatus = KRequestPending;
TRequestStatus* status = iAgentStatus;
User::RequestComplete( status, err );
}
}
if( iHTTPBinding && !err )
{
TRAP( err, iHTTPBinding->OpenCommunicationL( aIAPIdArray, aURI, aMimeType, aStatus, aHTTPusername, aHTTPpassword, aHTTPauthused ) );
if( err != KErrNone )
{
DBG_FILE(_S8("iHTTPBinding->OpenCommunicationL() failed!"));
*iAgentStatus = KRequestPending;
TRequestStatus* status = iAgentStatus;
User::RequestComplete( status, err );
}
}
}
//------------------------------------------------------------
// CNSmlTransport::Disconnect
// Closes a previously opened communication.
//------------------------------------------------------------
EXPORT_C void CNSmlTransport::Disconnect( )
{
DBG_FILE(_S8("CNSmlTransport::Disconnect( )"));
if( iObex )
{
if( iObexBinding != NULL )
{
DBG_FILE(_S8("iObexBinding->Cancel() starts.."));
iObexBinding->Cancel();
TRequestStatus* status = iAgentStatus;
TInt err( KErrNone );
TRAP(err, iObexBinding->CloseCommunicationL( *status ) );
}
if( iObexServerBinding != NULL )
{
DBG_FILE(_S8("iObexServerBinding->Cancel() starts.."));
iObexServerBinding->Cancel();
iObexServerBinding->Disconnect();
}
}
else
{
if( iHTTPBinding != NULL )
{
DBG_FILE(_S8("iHTTPBinding->Cancel() starts.."));
iHTTPBinding->Cancel();
}
}
}
//------------------------------------------------------------
// CNSmlTransport::Receive
// Read data across a connection.
//------------------------------------------------------------
EXPORT_C void CNSmlTransport::Receive( TPtr8& aStartPtr, TRequestStatus &aStatus )
{
DBG_FILE(_S8("CNSmlTransport::Receive starts..."));
TInt err( KErrNone );
if( iObex )
{
if( iObexServer )
{
DBG_FILE(_S8("OBEX server binding Receive starts..."));
this->iObexServerBinding->Receive( aStartPtr, aStatus );
}
else
{
DBG_FILE(_S8("OBEX ReceiveDataL starts..."));
TRAP( err, this->iObexBinding->ReceiveDataL( aStartPtr, aStatus ) );
if( err != KErrNone )
{
DBG_FILE(_S8("iObexBinding->ReceiveDataL failed!"));
*iAgentStatus = KRequestPending;
TRequestStatus* status = iAgentStatus;
User::RequestComplete( status, err );
}
}
}
else
{
DBG_FILE(_S8("HTTP ReceiveDataL starts..."));
TRAP( err, this->iHTTPBinding->ReceiveDataL( aStartPtr, aStatus ) );
if( err != KErrNone )
{
DBG_FILE(_S8("iHTTPBinding->ReceiveDataL failed!"));
*iAgentStatus = KRequestPending;
TRequestStatus* status = iAgentStatus;
User::RequestComplete( status, err );
}
}
}
//------------------------------------------------------------
// CNSmlTransport::Send
// Send data across a connection.
//------------------------------------------------------------
EXPORT_C void CNSmlTransport::Send( TDesC8& aStartPtr, TBool /*aFinalPacket*/, TRequestStatus &aStatus )
{
DBG_FILE(_S8("CNSmlTransport::Send starts..."));
TInt err( KErrNone );
if( iObex )
{
if ( iObexServer )
{
DBG_FILE(_S8("OBEX server binding SendDataL starts..."));
this->iObexServerBinding->Send( aStartPtr, ETrue, aStatus );
}
else
{
DBG_FILE(_S8("OBEX client SendDataL starts..."));
TRAP( err, this->iObexBinding->SendDataL( aStartPtr, ETrue, aStatus ) );
if( err != KErrNone )
{
DBG_FILE(_S8("iObexBinding->SendDataL() failed!"));
*iAgentStatus = KRequestPending;
TRequestStatus* status = iAgentStatus;
User::RequestComplete( status, err );
}
}
}
else
{
// 1.2 CHANGES: Offline mode
TBool offline = EFalse;
TInt offlineError( KErrNone );
TRAP( offlineError, offline = IsInOfflineModeL() );
if ( offline && !iWLANBearer )
{
DBG_FILE(_S8("Offline mode selected!"));
*iAgentStatus = KRequestPending;
TRequestStatus* status = iAgentStatus;
User::RequestComplete( status, TNSmlError::ESmlStatusNotPossibleInOfflineMode );
return;
}
// Changes end
DBG_FILE(_S8("HTTP SendDataL starts..."));
TRAP( err, this->iHTTPBinding->SendDataL( aStartPtr, ETrue, aStatus ) );
if( err != KErrNone )
{
DBG_FILE(_S8("iHTTPBinding->SendDataL() failed!"));
*iAgentStatus = KRequestPending;
TRequestStatus* status = iAgentStatus;
User::RequestComplete( status, err );
}
}
}
//------------------------------------------------------------
// CNSmlTransport::ChangeTargetURIL
// Changes target URI
//------------------------------------------------------------
EXPORT_C void CNSmlTransport::ChangeTargetURIL( TDesC8& aURI )
{
if( iObex )
{
}
else
{
DBG_FILE(_S8("HTTP ChangeTargetURIL starts..."));
this->iHTTPBinding->ChangeTargetURIL( aURI );
}
}
//------------------------------------------------------------
// CNSmlTransport::SetBTConnInfo()
// Set BT device address and service class uid
//------------------------------------------------------------
EXPORT_C void CNSmlTransport::SetBTConnInfo( const TBTDevAddr aBTDevAddr,
const TUUID aUid )
{
iBTDevAddr = aBTDevAddr;
iServiceUid = aUid;
}
//------------------------------------------------------------
// CNSmlTransport::SetExtObserver( MExtBTSearcherObserver* aExtObserver )
// Set observer to get callbacks
//------------------------------------------------------------
EXPORT_C void CNSmlTransport::SetExtObserver( MExtBTSearcherObserver* aExtObserver )
{
iBTObserver = aExtObserver;
}
//End of File