--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pnpmobileservices/pnpms/OnlineSupport/src/Ccmsocketsengine.cpp Thu Dec 17 08:40:12 2009 +0200
@@ -0,0 +1,632 @@
+/*
+* Copyright (c) 2003-2006 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: Class for the DNS query
+*
+*/
+
+
+
+
+// INCLUDE FILES
+#include <in_sock.h>
+#include <commdbconnpref.h>
+#include <http.h>
+#include <commdb.h>
+#include <ApDataHandler.h> // for CApDataHandler
+#include <ApAccessPointItem.h> // for EApHasProxySettings
+#include <ApUtils.h> // for CApUtils
+#include <basched.h> // for KLeaveExit
+#include "CCMSocketsEngine.h"
+#include "MCMSocketsEngineNotifier.h"
+#include "OnlineSupportLogger.h"
+
+// EXTERNAL DATA STRUCTURES
+// None
+
+// EXTERNAL FUNCTION PROTOTYPES
+// None
+
+// CONSTANTS
+// None
+
+// MACROS
+// None
+
+// LOCAL CONSTANTS AND MACROS
+// None
+
+// MODULE DATA STRUCTURES
+// None
+
+// LOCAL FUNCTION PROTOTYPES
+// None
+
+// FORWARD DECLARATIONS
+// None
+
+// ============================= LOCAL FUNCTIONS ===============================
+// None
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CCMSocketsEngine::CCMSocketsEngine
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+
+CCMSocketsEngine::CCMSocketsEngine( MCMSocketsEngineNotifier& aNotifier )
+ : CActive( CActive::EPriorityStandard ),
+ iSocketsEngineNotifier( aNotifier ),
+ iConnectionOpen( EFalse ),
+ iResolverExsists( EFalse ),
+ iLeaveOpen( EFalse ),
+ iProxyPort(0),
+ iProxyDefined( EFalse ),
+ iHttpSessionOpen( EFalse ),
+ iTransactionOpen( EFalse ),
+ iIapId(0)
+ {
+ }
+
+
+// -----------------------------------------------------------------------------
+// CCMSocketsEngine::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CCMSocketsEngine::ConstructL()
+ {
+ // Open channel to Socket Server
+ User::LeaveIfError( iSocketServ.Connect() );
+ CActiveScheduler::Add(this);
+ iProxyIp = HBufC::NewL(1);
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSocketsEngine::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CCMSocketsEngine* CCMSocketsEngine::NewL( MCMSocketsEngineNotifier& aNotifier)
+ {
+ LOGSTRING( "Enter to CCMSocketsEngine::NewL " );
+ CCMSocketsEngine* self = new( ELeave ) CCMSocketsEngine( aNotifier );
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ LOGSTRING( "Exit from CCMSocketsEngine::NewL " );
+ return self;
+ }
+
+
+// Destructor
+CCMSocketsEngine::~CCMSocketsEngine()
+ {
+ LOGSTRING( "Enter to CCMSocketsEngine::~CCMSocketsEngine()" );
+ if( IsActive() )
+ {
+ Cancel();
+ }
+
+ LOGSTRING( "CCMSocketsEngine::~CCMSocketsEngine() - 2" );
+
+ if( iTransactionOpen )
+ {
+ LOGSTRING("Canceling transaction");
+ iTransaction.Cancel();
+ LOGSTRING("Closing transaction");
+ iTransaction.Close();
+ iTransactionOpen = EFalse;
+ LOGSTRING("closed");
+ }
+ if( iHttpSessionOpen )
+ {
+ LOGSTRING("Closing session");
+ iSession.Close();
+ iHttpSessionOpen = EFalse;
+ LOGSTRING("closed");
+ }
+ delete iProxyIp;
+ if ( !iLeaveOpen )
+ {
+ LOGSTRING( "CCMSocketsEngine::~CCMSocketsEngine() - 3" );
+ if( iConnectionOpen )
+ {
+ LOGSTRING("Closing connection");
+ iConnection.Close();
+ iConnectionOpen = EFalse;
+ LOGSTRING("closed");
+ }
+ LOGSTRING( "CCMSocketsEngine::~CCMSocketsEngine() - 4" );
+ iSocketServ.Close();
+ }
+ LOGSTRING( "Exit from CCMSocketsEngine::~CCMSocketsEngine()" );
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSocketsEngine::Connect( const TDesC& aAddress )
+// starts the DNS query for the address
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCMSocketsEngine::ConnectL( TUint32 aAp, const TDesC& aAddress )
+ {
+ LOGSTRING( "CCMSocketsEngine::ConnectL" );
+ LOGSTRING2( "Enter iEngine.Connect() %i", aAp );
+
+ if ( IsActive() )
+ {
+ Cancel();
+ }
+
+ TCommDbConnPref prefs;
+ if( aAp == 0 )
+ {
+ prefs.SetDialogPreference(ECommDbDialogPrefPrompt);
+ }
+ else
+ {
+ prefs.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
+ }
+ prefs.SetIapId( aAp );
+
+#ifdef __WINS__ // do not try to connect on the emulator
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, KErrNone );
+#else
+ // Open connection
+ TInt err;
+ err = iConnection.Open( iSocketServ );
+ if (err != KErrNone) // error occured
+ {
+ LOGSTRING2( "iConnection.Open err: %i", err );
+ User::Leave( err );
+ }
+ iConnectionOpen = ETrue;
+ iConnection.Start( prefs, iStatus );
+#endif
+
+ iEngineStatus = EStatusConnecting;
+ iWapPage = aAddress;
+ SetActive();
+
+ LOGSTRING( "Exit from CCMSocketsEngine::Connect(). " );
+ }
+
+
+void CCMSocketsEngine::ConnectL( const TDesC& aAddress )
+ {
+ LOGSTRING( "CCMSocketsEngine::ConnectL. " );
+ if ( IsActive() )
+ {
+ Cancel();
+ }
+
+#ifdef __WINS__ // do not try to connect on the emulator
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, KErrNone );
+#else
+ // Open connection
+ TInt err;
+ err = iConnection.Open( iSocketServ );
+ if (err != KErrNone) // error occured
+ {
+ LOGSTRING2( "iConnection.Open err: %i", err );
+ User::Leave( err );
+ }
+ iConnectionOpen = ETrue;
+ iConnection.Start( iStatus );
+#endif
+
+ iEngineStatus = EStatusConnecting;
+ iWapPage = aAddress;
+ SetActive();
+
+ LOGSTRING( "Exit ftom CCMSocketsEngine::Connect(). " );
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSocketsEngine::Disconnect()
+// Disconnects the engine
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCMSocketsEngine::Disconnect()
+ {
+ LOGSTRING( "CCMSocketsEngine::Disconnect()" );
+ if ( IsActive() )
+ {
+ LOGSTRING("Canceling");
+ Cancel();
+ LOGSTRING("Canceled");
+ }
+ if( iTransactionOpen )
+ {
+ LOGSTRING("Closing transaction");
+ iTransaction.Close();
+ iTransactionOpen = EFalse;
+ LOGSTRING("closed");
+ }
+ if( iHttpSessionOpen )
+ {
+ LOGSTRING("Closing session");
+ iSession.Close();
+ iHttpSessionOpen = EFalse;
+ LOGSTRING("closed");
+ }
+ if ( iEngineStatus == EStatusResolving || iEngineStatus == EStatusReady )
+ {
+ if( iResolverExsists )
+ {
+ LOGSTRING( "CCMSocketsEngine::Disconnect() resolver exists" );
+ iResolver.Cancel();
+ iResolver.Close();
+ iResolverExsists = EFalse;
+ }
+ iEngineStatus = EStatusUnknown;
+ }
+ if( iConnectionOpen )
+ {
+ LOGSTRING("Closing connection");
+ iConnection.Close();
+ iConnectionOpen = EFalse;
+ LOGSTRING("closed");
+ }
+
+ iEngineStatus = EStatusUnknown;
+ LOGSTRING( "CCMSocketsEngine::Disconnect() - done" );
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSocketsEngine::SetOpen()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCMSocketsEngine::SetOpen( TBool aOpen )
+ {
+ iLeaveOpen = aOpen;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSocketsEngine::DoCancel()
+// Cancels the DNS query
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCMSocketsEngine::DoCancel()
+ {
+ LOGSTRING( "CCMSocketsEngine::DoCancel()" );
+ if( iTransactionOpen )
+ {
+ LOGSTRING("completing requeststatus");
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, KErrCancel );
+ LOGSTRING("Closing transaction");
+ iTransaction.Close();
+ iTransactionOpen = EFalse;
+ LOGSTRING("closed");
+ }
+ if( iHttpSessionOpen )
+ {
+ LOGSTRING("Closing session");
+ iSession.Close();
+ iHttpSessionOpen = EFalse;
+ LOGSTRING("closed");
+ }
+ if( iResolverExsists )
+ {
+ LOGSTRING( "iResolver.Cancel()" );
+ iResolver.Cancel();
+ LOGSTRING( "iResolver.Close()" );
+ iResolver.Close();
+ iResolverExsists= EFalse;
+ }
+ if( iConnectionOpen )
+ {
+ LOGSTRING("Closing connection");
+ iConnection.Close();
+ iConnectionOpen = EFalse;
+ LOGSTRING("closed");
+ }
+ iEngineStatus = EStatusUnknown;
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSocketsEngine::RunL()
+// Handles object’s request completion event
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCMSocketsEngine::RunL()
+ {
+ LOGSTRING( "CCMSocketsEngine::RunL()" );
+ if ( iStatus.Int() != KErrNone )
+ {
+ iSocketsEngineNotifier.ConnectionResultL( iStatus.Int() );
+ }
+ else
+ {
+ switch( iEngineStatus )
+ {
+ case EStatusUnknown:
+ LOGSTRING( "EStatusUnknown" );
+ case EStatusConnecting:
+ {
+ LOGSTRING( "EStatusConnecting" );
+#ifdef __WINS__ // do not try to connect on the emulator
+ iSocketsEngineNotifier.ConnectionResultL( iStatus.Int() );
+ iEngineStatus = EStatusReady;
+ break;
+#else
+ _LIT( KIapId, "IAP\\Id" );
+ User::LeaveIfError( iConnection.GetIntSetting( KIapId, iIapId ) );
+ const TBool proxyDefined = CheckForProxyL( iIapId );
+
+ if( proxyDefined )
+ {
+ MakeHttpHeadRequestL( *iProxyIp, iProxyPort );
+ iStatus = KRequestPending;
+ SetActive();
+ }
+ else
+ {
+ // Initiate a DNS query
+ LOGSTRING( "opening resolver, using udp protocol" );
+ TInt errorCode = iResolver.Open( iSocketServ, KAfInet, KProtocolInetUdp, iConnection );
+ //LOGSTRING( "opening resolver, using icmp protocol" );
+ //TInt errorCode = iResolver.Open( iSocketServ, KAfInet, KProtocolInetIcmp, iConnection );
+ //LOGSTRING( "opening resolver, using tcp protocol" );
+ //TInt errorCode = iResolver.Open( iSocketServ, KAfInet, KProtocolInetTcp, iConnection );
+
+ if ( errorCode != KErrNone )
+ {
+ LOGSTRING( "Error while opening resolver" );
+ iSocketsEngineNotifier.ConnectionResultL( errorCode );
+ break;
+ }
+ else
+ {
+ LOGSTRING( "Resolver exists" );
+ iResolverExsists = ETrue;
+ // DNS request for name resolution
+ LOGSTRING( "Querying url:" );
+ LOGTEXT( iWapPage );
+ iResolver.GetByName( iWapPage, iNameEntry, iStatus );
+ SetActive();
+ iEngineStatus = EStatusResolving;
+ }
+ }
+ break;
+#endif
+ }
+ case EStatusMakingHttpHeadRequest:
+ LOGSTRING( "EStatusMakingHttpHeadRequest" );
+ iSocketsEngineNotifier.ConnectionResultL( iStatus.Int() );
+ iEngineStatus = EStatusReady;
+ break;
+ case EStatusResolving:
+ LOGSTRING( "EStatusResolving" );
+ iSocketsEngineNotifier.ConnectionResultL( iStatus.Int() );
+ iEngineStatus = EStatusReady;
+ break;
+ case EStatusReady:
+ LOGSTRING( "EStatusReady" );
+ default:
+ break;
+ };
+ }
+ //iSocketsEngineNotifier.ConnectionResultL( iStatus.Int() );
+ LOGSTRING( " Exit from CCMSocketsEngine::runL " );
+ }
+
+// -----------------------------------------------------------------------------
+// CCMSocketsEngine::ReturnIAPID()
+// Returns IAPID set when user selects access point before launching browser
+//
+// -----------------------------------------------------------------------------
+//
+
+TUint32 CCMSocketsEngine::ReturnIAPID()
+{
+
+ return iIapId;
+}
+
+
+// -----------------------------------------------------------------------------
+// CCMSocketsEngine::RunError()
+// Handles leaves from RunL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CCMSocketsEngine::RunError(TInt aError)
+ {
+ LOGSTRING2( "CCMSocketsEngine::RunError: %i", aError );
+ if( aError == KLeaveExit )
+ {
+ return aError;
+ }
+ iSocketsEngineNotifier.UnhandledLeave( aError );
+ return KErrNone;
+ }
+
+
+TBool CCMSocketsEngine::CheckForProxyL( const TUint32 aIapId )
+ {
+ LOGSTRING("CCMSocketsEngine::CheckForProxyL")
+
+ // Check for proxy usage
+ CCommsDatabase* commDb = CCommsDatabase::NewL( EDatabaseTypeIAP );
+ CleanupStack::PushL( commDb );
+
+ CApDataHandler* dataHandler = CApDataHandler::NewLC( *commDb );
+ CApAccessPointItem* apItem = CApAccessPointItem::NewLC();
+ CApUtils* utils = CApUtils::NewLC( *commDb );
+
+ TUint32 id = utils->WapIdFromIapIdL( aIapId );
+ dataHandler->AccessPointDataL( id, *apItem );
+
+ TBool hasProxySettings;
+ User::LeaveIfError( apItem->ReadBool( EApHasProxySettings, hasProxySettings ) );
+
+ if( hasProxySettings )
+ {
+ LOGSTRING("HasProxySettings, reading proxy params");
+
+ // Ownership not transferred
+ const HBufC* proxyIp = apItem->ReadConstLongTextL( EApProxyServerAddress );
+ delete iProxyIp;
+ iProxyIp = 0;
+ iProxyIp = HBufC::NewL( proxyIp->Length() );
+ iProxyIp->Des().Copy( *proxyIp );
+ LOGTEXT( *iProxyIp );
+
+ TUint32 temp(0);
+ apItem->ReadUint( EApProxyPortNumber, temp );
+ iProxyPort = temp;
+ }
+
+ CleanupStack::PopAndDestroy( utils );
+ CleanupStack::PopAndDestroy( apItem );
+ CleanupStack::PopAndDestroy( dataHandler );
+ CleanupStack::PopAndDestroy( commDb );
+
+ LOGSTRING("CCMSocketsEngine::CheckForProxyL - done")
+ return hasProxySettings;
+ }
+
+void CCMSocketsEngine::MakeHttpHeadRequestL(
+ const TDesC& aProxyAddress,
+ const TUint aProxyPort )
+ {
+ LOGSTRING( "CCMSocketsEngine::MakeHttpHeadRequestL" );
+ _LIT8( KHttpProtString, "HTTP/TCP" );
+ // Opens session using protocol HTTP/TCP
+ LOGSTRING( "CCMSocketsEngine: iSession.OpenL" );
+ iSession.OpenL( KHttpProtString );
+ iHttpSessionOpen = ETrue;
+ LOGSTRING( "CCMSocketsEngine: iSession.OpenL - done" );
+ iSessionStringPool = iSession.StringPool();
+
+ RHTTPConnectionInfo connectionInfo = iSession.ConnectionInfo();
+
+ // Set SocketServ and Connection explicitly as we do not want to show
+ // the AP selection list to the user when making submit for the request
+ connectionInfo.SetPropertyL(
+ iSessionStringPool.StringF( HTTP::EHttpSocketServ, RHTTPSession::GetTable() ),
+ iSocketServ.Handle() );
+ connectionInfo.SetPropertyL(
+ iSessionStringPool.StringF( HTTP::EHttpSocketConnection, RHTTPSession::GetTable() ),
+ reinterpret_cast< TInt > ( &iConnection ) );
+ connectionInfo.SetPropertyL(
+ iSessionStringPool.StringF( HTTP::EProxyUsage, RHTTPSession::GetTable() ),
+ iSessionStringPool.StringF( HTTP::EUseProxy, RHTTPSession::GetTable() ) );
+
+ LOGSTRING("Set Proxy address");
+ HBufC8* proxy = HBufC8::NewLC( 100 );
+ TPtr8 proxyPtr = proxy->Des();
+ proxyPtr.Copy( aProxyAddress );
+ proxyPtr.Append( _L8( ":" ) );
+ proxyPtr.AppendNum( aProxyPort );
+ LOGTEXT( proxyPtr );
+
+ RStringF proxyF = iSessionStringPool.OpenFStringL( *proxy );
+ CleanupClosePushL( proxyF );
+
+ connectionInfo.SetPropertyL(
+ iSessionStringPool.StringF( HTTP::EProxyAddress, RHTTPSession::GetTable() ),
+ proxyF );
+
+ CleanupStack::PopAndDestroy(1); // proxyF.Close()
+ CleanupStack::PopAndDestroy( proxy );
+
+ TUriParser8 uriParser;
+ LOGSTRING( "CCMSocketsEngine uri:" );
+ _LIT( KHttp, "http://" );
+ TBuf8<128> uri;
+ if( iWapPage.Find( KHttp ) != 0 )
+ {
+ uri.Append( KHttp );
+ }
+ uri.Append( iWapPage.Left(100) );
+ LOGTEXT( uri );
+ User::LeaveIfError( uriParser.Parse( uri ) );
+
+ LOGSTRING( "CCMSocketsEngine: iSession.OpenTransactionL" );
+ iTransaction = iSession.OpenTransactionL( uriParser, *this, iSessionStringPool.StringF( HTTP::EHEAD, RHTTPSession::GetTable() ) );
+ iTransactionOpen = ETrue;
+ LOGSTRING( "CCMSocketsEngine: iSession.OpenTransactionL - done" );
+
+ iTransaction.SubmitL();
+ LOGSTRING( "CCMSocketsEngine: SubmitL - done" );
+
+ iEngineStatus = EStatusMakingHttpHeadRequest;
+ }
+
+
+void CCMSocketsEngine::MHFRunL( RHTTPTransaction aTransaction, const THTTPEvent &aEvent )
+ {
+ LOGSTRING( "CCMSocketsEngine::MHFRunL" );
+
+ switch( aEvent.iStatus )
+ {
+ case THTTPEvent::ESubmit:
+ {
+ LOGSTRING( "CCMSocketsEngine::MHFRunL:ESubmit" );
+ LOGTEXT( aTransaction.Request().URI().UriDes() );
+ break;
+ }
+ case THTTPEvent::EGotResponseHeaders:
+ {
+ LOGSTRING( "CCMSocketsEngine::MHFRunL:EGotResponseHeaders" );
+ // Success
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, KErrNone );
+ break;
+ }
+ case THTTPEvent::EFailed:
+ LOGSTRING( "CCMSocketsEngine::MHFRunL:EFailed" );
+ // Failed
+ User::Leave( KErrGeneral );
+ break;
+ default:
+ {
+ LOGSTRING2( "CCMSocketsEngine::MHFRunL:event: %i", aEvent.iStatus );
+ break;
+ }
+ }
+ // Keep compiler happy
+ (void)aTransaction;
+ LOGSTRING( "CCMSocketsEngine::MHFRunL - done" );
+ }
+
+TInt CCMSocketsEngine::MHFRunError( TInt aError, RHTTPTransaction /*aTransaction*/, const THTTPEvent& /*aEvent*/ )
+ {
+ LOGSTRING2( "CCMSocketsEngine::MHFRunError %i", aError );
+ if( iTransactionOpen )
+ {
+ LOGSTRING("Closing transaction");
+ iTransaction.Close();
+ iTransactionOpen = EFalse;
+ LOGSTRING("closed");
+ }
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, aError );
+ return KErrNone;
+ }
+
+// End of File