pnpmobileservices/pnpms/OnlineSupport/src/Ccmsocketsengine.cpp
changeset 0 3ce708148e4d
--- /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