nettools/conntest/Engine/SocketsEngine.cpp
changeset 0 857a3e953887
child 2 4cefe9af9cf4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nettools/conntest/Engine/SocketsEngine.cpp	Thu Dec 17 08:39:25 2009 +0200
@@ -0,0 +1,2076 @@
+/*
+ * Copyright (c) 2006-2009 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: CSocketsEngine implements an engine for connection
+ * component checking: Interface opening/closing, connecting,
+ * sending/receiving data, etc.
+ * CSocketsEngine is an active object
+ *
+ */
+
+// INCLUDE FILES
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <es_sock_partner.h>
+#include <es_enum_internal.h>
+#endif
+#include <eikgted.h>
+#include <in_sock.h>
+#include <e32svr.h>
+#include <es_enum.h>
+#include <commdb.h>
+#include <in_iface.h>
+#include <apgcli.h>
+#include <apaid.h>
+
+#include "SocketsEngine.h"
+#include "TimeOutTimer.h"
+#include "SocketsRead.h"
+#include "SocketsWrite.h"
+#include "ProgressNotifier.h"
+#include "ConnTest.pan"
+#include "uinotify.h"
+#include "HttpHandler.h"
+#include "SettingData.h"
+#include "CustomPrefsData.h"
+#include "Utils.h"
+#include "SendTimer.h"
+#include "alractiveobject.h"
+
+#include <hal.h>
+#include <hal_data.h>
+
+#include <cmmanagerext.h>
+#include <cmdestinationext.h>
+#include <cmapplicationsettingsui.h>
+
+// CONSTANTS
+const TInt KTimeOut = 120000000; // 2 minutes time-out
+
+_LIT(KDefaultServerName, "127.0.0.1");
+const TInt KDefaultPortNumber = 25;
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// CSocketsEngine::NewL(MUINotify& aConsole)
+// EPOC two phased constructor
+// ---------------------------------------------------------
+//
+CSocketsEngine* CSocketsEngine::NewL( MUINotify& aConsole )
+    {
+    CSocketsEngine* self = CSocketsEngine::NewLC( aConsole );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::NewLC(MUINotify& aConsole)
+// EPOC two phased constructor
+// ---------------------------------------------------------
+//
+CSocketsEngine* CSocketsEngine::NewLC( MUINotify& aConsole )
+    {
+    CSocketsEngine* self = new (ELeave) CSocketsEngine( aConsole );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::CSocketsEngine(MUINotify& aConsole)
+// EPOC constructor
+// ---------------------------------------------------------
+//
+CSocketsEngine::CSocketsEngine( MUINotify& aConsole ) :
+    CActive( EPriorityStandard ), iConsole( aConsole ), iPort(
+            KDefaultPortNumber ), iServerName( KDefaultServerName )
+    {
+    iStartTime = 0;
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::~CSocketsEngine()
+// Destructor
+// ---------------------------------------------------------
+//
+CSocketsEngine::~CSocketsEngine()
+    {
+    Cancel();
+    if (iProgressNotifier)
+        {
+        iProgressNotifier->Cancel();
+        }
+
+    delete iSocketsRead;
+    iSocketsRead = NULL;
+
+    delete iSocketsWrite;
+    iSocketsWrite = NULL;
+
+    delete iProgressNotifier;
+    iProgressNotifier = NULL;
+
+    delete iTimer;
+    iTimer = NULL;
+
+    delete iSendTimer;
+
+    delete iHttpClient;
+    iHttpClient = NULL;
+
+    if (iData)
+        {
+        delete iData;
+        iData = NULL;
+        }
+    //delete pointer to mobility API
+    if (iMobility)
+        {
+        delete iMobility;
+        iMobility = NULL;
+        }
+
+    delete iExtPrefs;
+    delete iPrefsList;
+
+    // Note! Closing order matters. Panic occurs if the
+    // closing is made in different order. 
+
+    iConnection.Close();
+    iSocket.Close();
+    iSocketServ.Close();
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::ConstructL()
+// EPOC two phased constructor
+// ---------------------------------------------------------
+//
+void CSocketsEngine::ConstructL()
+    {
+    ChangeStatus( EInterfaceDown );
+
+    iData = HBufC8::NewL( KMaxSendBuffer);
+    // Start a timer
+    iTimer = CTimeOutTimer::NewL( EPriorityHigh, *this );
+
+    CActiveScheduler::Add( this );
+
+    // Open channel to Socket Server
+    User::LeaveIfError( iSocketServ.Connect() );
+
+    // Open connection
+    User::LeaveIfError( iConnection.Open( iSocketServ ) );
+
+    // Create socket read and write active objects
+    iSocketsRead = CSocketsRead::NewL( iConsole, iSocket, *this );
+    iSocketsWrite = CSocketsWrite::NewL( iConsole, iSocket, *this );
+
+    // Create interface notification active object
+    iProgressNotifier = CProgressNotifier::NewL( iConnection, *this );
+    iProgressNotifier->StartNotify();
+
+    //
+    // HTTP framework initialization
+    //
+    iHttpClient = CHttpClient::NewL( iConsole );
+    iHttpClient->SetHttpConnectionInfoL( ETrue, iConnection, iSocketServ );
+
+    // Timer for sending multiple packets
+    if (!iSendTimer)
+        {
+        iSendTimer = CSendTimer::NewL( EPriorityHigh, this );
+        }
+
+    iUseTTime = EFalse;
+    TInt freq;
+    TInt err = HAL::Get( HAL::EFastCounterFrequency, freq );
+    if (err != KErrNone || freq == 0)
+        {
+        iUseTTime = ETrue;
+        }
+
+    //set mobility API flag to false
+    iIsRegisteredToMobAPI = EFalse;
+    SetSocketEngineConnType( ETypeUnknown );
+
+    iExtPrefs = new (ELeave) TExtendedConnPref;
+    iPrefsList = TConnPrefList::NewL();
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::GetSocketEngineState()
+// Return the current state of the socket engine.
+// ---------------------------------------------------------
+//
+CSocketsEngine::TSocketsEngineState CSocketsEngine::GetSocketEngineState()
+    {
+    return iEngineStatus;
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::GetSocketEngineRoamingState()
+// ---------------------------------------------------------
+// 
+CSocketsEngine::TRoamingUIState CSocketsEngine::GetSocketEngineRoamingState()
+    {
+    return iRoamingState;
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::GetMobilityAPI()
+// ---------------------------------------------------------
+// 
+CALRActiveObject* CSocketsEngine::GetMobilityAPI()
+    {
+    return iMobility;
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::GetSocketEngineConnType()
+// Return the current connection type of the socket engine.
+// ---------------------------------------------------------
+//
+CSocketsEngine::TSocketsEngineStartType CSocketsEngine::GetSocketEngineConnType()
+    {
+    return iSockEngineStartType;
+    }
+// ---------------------------------------------------------
+// CSocketsEngine::SetSocketEngineConnType()
+// Set the current conn type of the socket engine.
+// ---------------------------------------------------------
+//
+void CSocketsEngine::SetSocketEngineConnType( const CSocketsEngine::TSocketsEngineStartType aConnStartType )
+    {
+    iSockEngineStartType = aConnStartType;
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::StartConnWithSnapL()
+// Start the connection with snap
+// ---------------------------------------------------------
+//
+void CSocketsEngine::StartConnWithSnapL( TBool aConnect )
+    {
+    if (iEngineStatus == EConnected || iEngineStatus == EInterfaceUp)
+        {
+        return;
+        }
+
+    //start the connection  dialog
+    CCmApplicationSettingsUi* settings = CCmApplicationSettingsUi::NewL();
+    CleanupStack::PushL( settings );
+    TCmSettingSelection selection;
+    settings->RunApplicationSettingsL( selection );
+    CleanupStack::PopAndDestroy( settings );
+
+    switch (selection.iResult)
+        {
+        case CMManager::EConnectionMethod:
+            {
+            // start connection with Iap Id
+            iPrefs.SetIapId( selection.iId );
+            iPrefs.SetDialogPreference( ECommDbDialogPrefDoNotPrompt );
+
+            StartTickCount();
+            iConnection.Start( iPrefs, iStatus );
+            break;
+            }
+        case CMManager::EDestination:
+            {
+            TConnSnapPref pref;
+            
+            pref.SetSnap( selection.iId );
+
+            StartTickCount();
+            //start connection with snap Id
+            iConnection.Start( pref, iStatus );
+            //Set connection type as Snap	
+            SetSocketEngineConnType( ESnap );
+            
+            break;
+            }
+        case CMManager::EAlwaysAsk:
+            {
+            // For testing start without preferences
+            StartTickCount();
+            iConnection.Start( iStatus );
+            ChangeStatus( EStartingInterface );
+            iConnectAfterStartup = ETrue;
+            SetActive();
+            return;
+            }
+        default:
+            {
+            RDebug::Print( _L("ConnTest: Invalid selection"));
+            return;
+            }
+        }
+
+    ChangeStatus( EStartingInterface );
+    //specify if a connection is needed after interface startup(
+    iConnectAfterStartup = aConnect;
+    SetActive();
+    
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::StartInterfaceL(TBool aConnect)
+// Start interface
+// ---------------------------------------------------------
+//
+void CSocketsEngine::StartInterfaceL( TSocketsEngineStartType aStartType,
+        TBool aConnect )
+    {
+    RDebug::Print( _L("ConnTest: StartInterfaceL( Start type = %d )"), aStartType );
+    if (iEngineStatus == EConnected || iEngineStatus == EInterfaceUp)
+        {
+        RDebug::Print( _L("ConnTest: Selection cancelled!"));
+        return;
+        }
+
+    SetSocketEngineConnType( aStartType );
+
+    if (aStartType == EAskIap)
+        {
+        // Get IAP id
+        TUint32 iapId;
+        TInt popupOk = Utils::AskIapIdL( iapId );
+        
+        if (!popupOk)
+            {
+            RDebug::Print( _L("ConnTest: Selection cancelled!"));
+            return;
+            }
+        RDebug::Print( _L("ConnTest: Selected IAP id=%d"), iapId );
+
+        // Create overrides
+        iPrefs.SetIapId( iapId );
+        iPrefs.SetDialogPreference( ECommDbDialogPrefDoNotPrompt );
+        }
+    else if (aStartType == ENetworkId)
+        {
+        // Get network id
+        TUint32 nwkId;
+        TInt popupOk = Utils::AskNetworkIdL( nwkId );
+        
+        if (!popupOk)
+            {
+            RDebug::Print( _L("ConnTest: Selection cancelled!"));
+            return;
+            }
+        RDebug::Print( _L("ConnTest: Selected Network id=%d"), nwkId );
+
+        // Create overrides
+        iPrefs.SetNetId( nwkId );
+        iPrefs.SetDialogPreference( ECommDbDialogPrefDoNotPrompt );
+        }
+
+    // Start the timer after the dialogs
+    StartTickCount();
+
+    // ...And now there are few different kinds of iConnection.Start() functions to call...
+    if (aStartType == EExtPrefs)
+        {
+        iPrefsList->AppendL( iExtPrefs );
+        iConnection.Start( *iPrefsList, iStatus );
+        iPrefsList->Remove( 0 );
+        }
+    else if (aStartType == EExtPrefsInternet)
+        {
+        TExtendedConnPref* tmpExtPrefs = new (ELeave) TExtendedConnPref;
+        tmpExtPrefs->SetSnapPurpose( CMManager::ESnapPurposeInternet );
+        iPrefsList->AppendL( tmpExtPrefs );
+        iConnection.Start( *iPrefsList, iStatus );
+        iPrefsList->Remove( 0 );
+        delete tmpExtPrefs;
+        }
+    else if (aStartType == ENoPrefs)
+        {
+        iConnection.Start( iStatus );
+        }
+    else // (aStartType == EAskIap || aStartType == ENetworkId) - Other values aren't used.
+        {
+        iConnection.Start( iPrefs, iStatus );
+        }
+
+    ChangeStatus( EStartingInterface );
+    iConnectAfterStartup = aConnect;
+    SetActive();
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::RegisterToMobilityAPI(TBool aConnect)
+// Register to mobility API
+// ---------------------------------------------------------
+//
+void CSocketsEngine::RegisterToMobilityAPIL()
+    {
+    if (iEngineStatus == EConnected || iEngineStatus == EInterfaceUp)
+        {
+        if (!iIsRegisteredToMobAPI)
+            {
+            iConsole.PrintNotify( _L("RegisterToMobilityAPI\n"));
+            //create the listener active object
+            iMobility = CALRActiveObject::NewL( iConsole,
+                    (MMobilityProtocolResp*)this );
+            iMobility->OpenL( iConnection );
+            iIsRegisteredToMobAPI = ETrue;
+            }
+        }
+    else
+        {
+        iConsole.PrintNotify( _L("Could not register\n"));
+        }
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::UnRegisterToMobilityAPI(TBool aConnect)
+// UnRegister from mobility API
+// ---------------------------------------------------------
+//
+void CSocketsEngine::UnRegisterFromMobilityAPI()
+    {
+    if (iIsRegisteredToMobAPI && iMobility) //&& 
+    //(iEngineStatus == EConnected || iEngineStatus == EInterfaceUp || iEngineStatus == EConnecting))
+        {
+        delete iMobility;
+        iMobility = NULL;
+        iConsole.PrintNotify( _L("Unregister MobilityAPI\n"));
+        }
+    iIsRegisteredToMobAPI = EFalse;
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::Error()
+// ---------------------------------------------------------
+// 
+void CSocketsEngine::Error( TInt aError )
+    {
+    TBuf8<64> text;
+    text.AppendFormat( _L8("MobilityError: %d\n"), aError );
+    iConsole.PrintNotify( text );
+    UnRegisterFromMobilityAPI();
+    iRoaming = ERoamingOff;
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::PreferredCarrierAvailable()
+// ---------------------------------------------------------
+// 
+void CSocketsEngine::PreferredCarrierAvailable( TAccessPointInfo aOldAP,
+        TAccessPointInfo aNewAP,
+        TBool aIsUpgrade,
+        TBool aIsSeamless )
+    {
+    // silence warnings
+    aOldAP = aOldAP;
+    aIsUpgrade = aIsUpgrade;
+    aIsSeamless = aIsSeamless;
+
+    TBuf8<64> text;
+    
+    if (iRoaming == ERoamingAutomatic)
+        {
+        text.AppendFormat( _L8("Migrating to %i\n"), aNewAP.AccessPoint() );
+        iMobility->MigrateToPreferredCarrier();
+        iRoamingState = EIdle;
+        }
+    else if (iRoaming == ERoamingManual)
+        {
+        text.AppendFormat( _L8("Preferred IAP %i Available\n"), aNewAP.AccessPoint() );
+        iRoamingState = EPendingPreferredCarrier;
+        iConsole.PopupNotify( _L("Migrate or Ignore available"));
+        }
+    else
+        {
+        text.AppendFormat( _L8("Unexpected PreferrredCarrier %i\n"), aNewAP.AccessPoint() );
+        iRoamingState = EIdle;
+        iMobility->IgnorePreferredCarrier();
+        }
+    iConsole.PrintNotify( text );
+    }
+// ---------------------------------------------------------
+// CSocketsEngine::NewCarrierActive()
+// ---------------------------------------------------------
+// 
+void CSocketsEngine::NewCarrierActive( TAccessPointInfo aNewAP,
+        TBool aIsSeamless )
+    {
+    // silence warning
+    aIsSeamless = aIsSeamless;
+
+    TBuf8<64> text;
+    
+    if (iRoaming == ERoamingAutomatic)
+        {
+        iRoamingState = EIdle;
+        iMobility->NewCarrierAccepted();
+        }
+    else if (iRoaming == ERoamingManual)
+        {
+        text.AppendFormat( _L8("IAP %i pending accept\n"), aNewAP.AccessPoint() );
+        iRoamingState = EPendingNewCarrierActive;
+        iConsole.PopupNotify( _L("Accept or Reject available"));
+        }
+    else
+        {
+        iRoamingState = EIdle;
+        text.AppendFormat( _L8("Unexpected NewCarrierActive %i\n"), aNewAP.AccessPoint() );
+        iMobility->NewCarrierRejected();
+        }
+    iConsole.PrintNotify( text );
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::
+// ---------------------------------------------------------
+//
+void CSocketsEngine::Migrate()
+    {
+    if (iRoaming != ERoamingManual)
+        {
+        User::Panic( KPanicSocketsEngine, EConnTestBadRoamingStatus );
+        }
+    iMobility->MigrateToPreferredCarrier();
+    iConsole.PrintNotify( _L("Migration requested"));
+    iRoamingState = EIdle;
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::
+// ---------------------------------------------------------
+//
+void CSocketsEngine::Ignore()
+    {
+    if (iRoaming != ERoamingManual)
+        {
+        User::Panic( KPanicSocketsEngine, EConnTestBadRoamingStatus );
+        }
+    iMobility->IgnorePreferredCarrier();
+    iConsole.PrintNotify( _L("Ignored new carrier"));
+    iRoamingState = EIdle;
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::
+// ---------------------------------------------------------
+//
+void CSocketsEngine::AcceptCarrier()
+    {
+    if (iRoaming != ERoamingManual)
+        {
+        User::Panic( KPanicSocketsEngine, EConnTestBadRoamingStatus );
+        }
+    iMobility->NewCarrierAccepted();
+    iConsole.PrintNotify( _L("Accepted carrier"));
+    iRoamingState = EIdle;
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::
+// ---------------------------------------------------------
+//
+void CSocketsEngine::RejectCarrier()
+    {
+    if (iRoaming != ERoamingManual)
+        {
+        User::Panic( KPanicSocketsEngine, EConnTestBadRoamingStatus );
+        }
+    iMobility->NewCarrierRejected();
+    iConsole.PrintNotify( _L("Rejected carrier"));
+    iRoamingState = EIdle;
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::StartCloseInterfaceL()
+// Start interface for testing RConnection::Close
+// ---------------------------------------------------------
+//
+void CSocketsEngine::StartCloseInterfaceL()
+    {
+    if (iEngineStatus == EConnected || iEngineStatus == EInterfaceUp)
+        {
+        // Already started, simply return
+        return;
+        }
+
+    // Get IAP id
+    TUint32 iapId;
+    TInt popupOk = Utils::AskIapIdL( iapId );
+    
+    if (!popupOk)
+        {
+        // Selection cancelled
+        return;
+        }
+    RDebug::Print( _L("ConnTest: Selected IAP id=%d"), iapId );
+
+    iCloseConnection = new (ELeave) RConnection;
+
+    User::LeaveIfError( iCloseConnection->Open( iSocketServ ) );
+
+    // Create overrides
+    iPrefs.SetIapId( iapId );
+    iPrefs.SetDialogPreference( ECommDbDialogPrefDoNotPrompt );
+
+    ChangeStatus( EStartingInterface );
+
+    iCloseConnection->Start( iPrefs, iStatus );
+    SetActive();
+
+    iTempProgressNotifier = CProgressNotifier::NewL( *iCloseConnection, *this );
+    iTempProgressNotifier->StartNotify();
+    
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::StopInterfaceL()
+// Shutdown interface
+// ---------------------------------------------------------
+//
+void CSocketsEngine::StopInterfaceL()
+    {
+    // Note! Socket is not closed here, because in connected
+    // state only Disconnect menu item is available. Therefore
+    // interface cannot be stopped when connection is open.
+    //
+    // iProgressNotifier->Cancel() is called in ProgressNotifyReceived
+    // method after KLinkLayerClosed has been received.
+    //
+
+    //unregister from mobility API if registered
+    UnRegisterFromMobilityAPI();
+    SetSocketEngineConnType( ETypeUnknown );
+    
+    if (iEngineStatus == EConnected || iEngineStatus == EInterfaceUp)
+        {
+        iConnection.Stop();
+        ChangeStatus( EInterfaceDown );
+        iHttpClient->SetHttpConnectionInfoL( ETrue, iConnection, iSocketServ );
+        
+        if (iCloseConnection)
+            {
+            // So if we are here, interface was started for testing RConnection::Close,
+            // and the corresponding RConnection instance needs to be deleted.
+            iCloseConnection->Close();
+            delete iCloseConnection;
+            iCloseConnection = NULL;
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::CloseInterface()
+// Close interface
+// ---------------------------------------------------------
+//
+void CSocketsEngine::CloseInterface()
+    {
+    if (iCloseConnection)
+        {
+        iCloseConnection->Close();
+        delete iCloseConnection;
+        iCloseConnection = NULL;
+        }
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::ConnectL()
+// Check whether the address is valid IP address. If it's not
+// calls DNS to solve the name.
+// ---------------------------------------------------------
+//
+void CSocketsEngine::ConnectL()
+    {
+    // Just in case (does nothing if interface has already been started)
+    StartInterfaceL( EAskIap, ETrue );
+    
+    // Initiate connection process
+    if ((iEngineStatus == EInterfaceUp) || (iEngineStatus == ETimedOut))
+        {
+        TInetAddr addr;
+        if (addr.Input( iServerName ) == KErrNone)
+            {
+            // server name is already a valid ip address
+            ConnectL( addr );
+            }
+        else // need to look up name using dns
+            {
+            // Initiate DNS
+            User::LeaveIfError( iResolver.Open( iSocketServ, KAfInet,
+                    KProtocolInetUdp, iConnection ) );
+            // DNS request for name resolution
+            StartTickCount();
+            iResolver.GetByName( iServerName, iNameEntry, iStatus );
+
+            ChangeStatus( ELookingUp );
+            // Request time out
+            iTimer->After( KTimeOut );
+            SetActive();
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::ConnectL()
+// Connect to socket
+// ---------------------------------------------------------
+//                          
+void CSocketsEngine::ConnectL( const TInetAddr& aAddr ) // <a name="ConnectL32">
+    {
+    
+    // Initiate attempt to connect to a socket by IP address	
+    if ((iEngineStatus == EInterfaceUp) || (iEngineStatus == ETimedOut))
+        {
+        // Open a TCP socket
+        iSocket.Close(); // Just in case
+        User::LeaveIfError( iSocket.Open( iSocketServ, KAfInet, iSocketType,
+                iProtocol, iConnection ) );
+
+        // Set up address information
+        iAddress = aAddr;
+        iAddress.SetPort( iPort );
+
+        // Initiate socket connection
+        StartTickCount();
+        iSocket.Connect( iAddress, iStatus );
+        ChangeStatus( EConnecting );
+        SetActive();
+        
+        // Start a timeout
+        iTimer->After( KTimeOut );
+        }
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::Disconnect()
+// Shutdown socket
+// ---------------------------------------------------------
+//
+void CSocketsEngine::Disconnect()
+    {
+    if (iEngineStatus == EListening && iProtocol == KProtocolInetTcp)
+        {
+        iListeningSocket.CancelAccept();
+        iListeningSocket.Close();
+        // Remember to close the socket on reader RunL()
+        }
+    if (iEngineStatus == EConnected || iEngineStatus == EListening)
+        {
+        iSocketsRead->Cancel();
+        iSocketsWrite->Cancel();
+
+        // have to do this.
+        iTimer->Cancel();
+
+        // Use Close() instead of Shutdown(). This way we
+        // can handle the situation, where server initiates
+        // the closing process, and sends RST signal instead
+        // of FIN. If server sends RST and Shutdown() is used,
+        // engine stays in EDisconnecting state forever.
+        iSocket.Close();
+        
+        ChangeStatus( EInterfaceUp );
+        }
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::ListenL()
+// Opens listening socket
+// ---------------------------------------------------------
+//
+void CSocketsEngine::ListenL()
+    {
+    // Initiate attempt to connect to a socket by IP address	
+    if ((iEngineStatus == EInterfaceUp) || (iEngineStatus == ETimedOut))
+        {
+        // Open a TCP socket
+        iSocket.Close(); // Just in case
+        iListeningSocket.Close();
+
+        // Set up address information
+        iAddress.SetFamily( 0 );
+        iAddress.SetPort( iPort );
+        switch (iProtocol)
+            {
+            case KProtocolInetTcp:
+                User::LeaveIfError( iSocket.Open( iSocketServ ) );
+                User::LeaveIfError( iListeningSocket.Open( iSocketServ,
+                        KAfInet, iSocketType, iProtocol, iConnection ) );
+                // Bind a port
+                iListeningSocket.Bind( iAddress );
+                // Listens a socket
+                iListeningSocket.Listen( 1 ); // Only one connection allowed
+                // Accepts one connection
+                iListeningSocket.Accept( iSocket, iStatus );
+                ChangeStatus( EListening );
+                SetActive();
+                break;
+            case KProtocolInetUdp:
+                User::LeaveIfError( iSocket.Open( iSocketServ, KAfInet,
+                        iSocketType, iProtocol, iConnection ) );
+                iSocket.Bind( iAddress );
+                ChangeStatus( EListening );
+                iStatus = KErrNone;
+                RunL(); // ugly.
+                break;
+            default:
+                User::Leave( KErrNotSupported );
+                break;
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::Write()
+// Write data to socket
+// ---------------------------------------------------------
+//
+void CSocketsEngine::WriteL( const TDesC8& aData )
+    {
+    RDebug::Print( _L("ConnTest: Sending data, length = %d"),aData.Length() );
+
+    iSocketsRead->SetPerformance( EFalse );
+    
+    // Write data to socket
+    if (iEngineStatus == EConnected)
+        {
+        iSocketsWrite->IssueWriteL( aData, &iAddress, iProtocol );
+        }
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::Write()
+// Write data to socket aCount times
+// ---------------------------------------------------------
+//
+void CSocketsEngine::WriteFloodL( const TDesC8& aData, TInt aCount )
+    {
+    // Write data to socket
+    if (iEngineStatus == EConnected)
+        {
+        iThroughputStartTime.UniversalTime();
+        iSocketsWrite->IssueWriteL( aData, &iAddress, iProtocol, aCount );
+        }
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::SendHttpRequestOverSocketL(TBool aHasBody)
+// Write HTTP request to socket
+// ---------------------------------------------------------
+//
+void CSocketsEngine::SendHttpRequestOverSocketL( TBool aHasBody,
+        TBool aDoPerformance )
+    {
+    iSocketsRead->SetPerformance( aDoPerformance );
+
+    TBuf8<256> req;
+    
+    if (aHasBody)
+        {
+        // Send HTTP POST
+        req.Copy( _L8("POST "));
+
+        // Add '/' if it is not included in the given page name
+        if (!((TChar)iSettingData->iHttpPage[0] == '/'))
+            {
+            req.Append( _L8("/"));
+            }
+
+        req.Append( iSettingData->iHttpPage );
+        req.Append( _L8(" HTTP/1.1\r\n"));
+        req.Append( _L8("Host: "));
+        req.Append( iSettingData->iServerName );
+        req.Append( _L8(":"));
+        req.AppendNum( iSettingData->iPort );
+        req.AppendFormat( _L8("\r\nContent-Length: %d"), iSettingData->iPacketSize
+                * iSettingData->iPackets );
+        req.Append( _L8("\r\n\r\n"));
+        
+        iSocketsWrite->IssueWriteL( req, &iAddress, iProtocol,
+                iSettingData->iPacketSize, iSettingData->iPackets );
+        }
+    else
+        {
+        // Send HTTP GET
+        req.Copy( _L8("GET "));
+
+        // Add '/' if it is not included in the given page name
+        if (!((TChar)iSettingData->iHttpPage[0] == '/'))
+            {
+            req.Append( _L8("/"));
+            }
+
+        req.Append( iSettingData->iHttpPage );
+        req.Append( _L8(" HTTP/1.1\r\n"));
+        req.Append( _L8("Host: "));
+        req.Append( iSettingData->iServerName );
+        req.Append( _L8(":"));
+        req.AppendNum( iSettingData->iPort );
+        req.Append( _L8("\r\n\r\n"));
+
+        StartTickCount();
+        iSocketsWrite->IssueWriteL( req, &iAddress, iProtocol );
+        }
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::Read()
+// Read data from socket
+// ---------------------------------------------------------
+//
+void CSocketsEngine::Read()
+    {
+    // Initiate read of data from socket
+    if ((iEngineStatus == EConnected) && (!iSocketsRead->IsActive()))
+        {
+        iSocketsRead->Start( &iAddress, iProtocol );
+        }
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::RunL()
+// 
+// ---------------------------------------------------------
+//
+void CSocketsEngine::RunL()
+    {
+    // Active object request complete handler.
+    // iEngineStatus flags what request was made, so its
+    // completion can be handled appropriately
+    iTimer->Cancel(); // Cancel TimeOut timer before completion
+    TBuf<64> text( _L(""));
+    switch (iEngineStatus)
+        {
+        case EInterfaceDown:
+            // Just in case, if status is changed in ProgressNotifyReceived
+            // method before this method is called
+            break;
+        case EStartingInterface:
+            text.Format( _L("RConnection::Start()"));
+            StopTickCount( text );
+            // Interface startup request
+            if (iStatus == KErrNone)
+                {
+                // Interface started successfully
+                ChangeStatus( EInterfaceUp );
+
+                if (iCloseConnection)
+                    {
+                    iHttpClient->SetHttpConnectionInfoL( EFalse,
+                            *iCloseConnection, iSocketServ );
+                    }
+                else
+                    {
+                    iHttpClient->SetHttpConnectionInfoL( EFalse, iConnection,
+                            iSocketServ );
+                    }
+
+                if ( ( iSockEngineStartType == ESnap ||
+                       iSockEngineStartType == EExtPrefs ||
+                       iSockEngineStartType == EExtPrefsInternet ) &&
+                     ( iRoaming == ERoamingAutomatic || iRoaming == ERoamingManual ) )
+                    {
+                    RegisterToMobilityAPIL();
+                    }
+                
+                if (iConnectAfterStartup)
+                    {
+                    ConnectL();
+                    }
+                }
+            else
+                {
+                iConsole.ErrorNotify( _L("<CSocketsEngine> Startup failed"), iStatus.Int() );
+                ChangeStatus( EInterfaceDown );
+                SetSocketEngineConnType( ETypeUnknown );
+                }
+            break;
+            
+        case EConnecting:
+            // IP connection request
+            text.Format( _L("RSocket::Connect()"));
+            StopTickCount( text );
+            if (iStatus == KErrNone)
+            // Connection completed successfully
+                {
+                ChangeStatus( EConnected );
+                Read(); //Start CSocketsRead Active object
+                }
+            else
+                {
+                iConsole.ErrorNotify( _L("<CSocketsEngine> Conn. failed"), iStatus.Int() );
+                ChangeStatus( EInterfaceUp );
+                }
+            break;
+            
+        case ELookingUp:
+            text.Format( _L("RHostResolver::GetByName()"));
+            StopTickCount( text );
+            iResolver.Close();
+            if (iStatus == KErrNone)
+                {
+                // DNS look up successful
+                iNameRecord = iNameEntry();
+                // Extract domain name and IP address from name record
+                PrintTextToConsole( _L("\r\nDomain name = "));
+                PrintTextToConsole( iNameRecord.iName );
+                TBuf<64> ipAddr;
+                TInetAddr::Cast( iNameRecord.iAddr ).Output( ipAddr );
+                iConsole.PrintNotify( _L("\r\nIP address = "));
+                PrintTextToConsole( ipAddr );
+                PrintTextToConsole( _L("\r\n"));
+                // And connect to the IP address
+                ChangeStatus( EInterfaceUp );
+                ConnectL( TInetAddr::Cast( iNameRecord.iAddr ) );
+                }
+            else
+                {
+                // DNS lookup failed
+                iConsole.ErrorNotify( _L("<CSocketsEngine> DNS lookup failed"), iStatus.Int() );
+                ChangeStatus( EInterfaceUp );
+                }
+            break;
+        case EListening:
+            // Listening socket accept returned
+            if (iStatus == KErrNone && !iSocketsRead->IsActive())
+            // Connection established
+                {
+                //ChangeStatus(EConnected); Might as well be in listening state.
+                // This how we can keep accepting several connections
+                // Initiate read of data from socket
+                iSocketsRead->StartRAWRead( &iAddress, iProtocol );
+                }
+            else
+                {
+                iConsole.ErrorNotify( _L("<CSocketsEngine> Accept. failed"), iStatus.Int() );
+                iListeningSocket.Close();
+                iSocket.Close();
+                ChangeStatus( EInterfaceUp );
+                }
+            
+            break;
+        case EDisconnecting:
+            if (iStatus == KErrNone)
+                {
+                iSocket.Close();
+                ChangeStatus( EInterfaceUp );
+                }
+            break;
+            
+        default:
+            // Ignore the state check here, because it might happen that state
+            // has already been altered in ProgressNotifyReceived method.
+            break;
+        }
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::DoCancel()
+// Cancel ongoing operations
+// ---------------------------------------------------------
+//
+void CSocketsEngine::DoCancel()
+    {
+    iTimer->Cancel();
+    
+    // Cancel ongoing operation
+    switch (iEngineStatus)
+        {
+        case EStartingInterface:
+
+            if (iCloseConnection)
+                {
+                iCloseConnection->Close();
+                delete iCloseConnection;
+                iCloseConnection = NULL;
+                }
+            else
+                {
+                iConnection.Stop();
+                }
+            
+            UnRegisterFromMobilityAPI();
+            SetSocketEngineConnType( ETypeUnknown );
+            ChangeStatus( EInterfaceDown );
+            
+            break;
+        case EConnecting:
+            iSocket.CancelConnect();
+            iSocket.Close();
+            ChangeStatus( EInterfaceUp );
+            break;
+        case ELookingUp:
+            // Cancel look up attempt
+            iResolver.Cancel();
+            iResolver.Close();
+            ChangeStatus( EInterfaceUp );
+            break;
+        case EDisconnecting:
+            ChangeStatus( EInterfaceUp );
+            iSocket.Close();
+            break;
+        case EListening:
+            ChangeStatus( EInterfaceUp );
+            iListeningSocket.CancelAccept();
+            iListeningSocket.Close();
+            iSocket.Close();
+            break;
+        default:
+            User::Panic( KPanicSocketsEngine, EConnTestBadStatus );
+            break;
+        }
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::ChangeStatus(TSocketsEngineState aNewStatus)
+// Set new status for socket engine and update the status
+// line in console window.
+// ---------------------------------------------------------
+//
+void CSocketsEngine::ChangeStatus( TSocketsEngineState aNewStatus )
+    {
+    // Update the status (and the status display)
+    switch (aNewStatus)
+        {
+        case EInterfaceDown:
+            iConsole.SetStatus( _L("Interface stopped"));
+            break;
+        case EStartingInterface:
+            iConsole.SetStatus( _L("Starting interface..."));
+            break;
+        case EInterfaceUp:
+            iConsole.SetStatus( _L("Interface up"));
+            break;
+        case EConnecting:
+            iConsole.SetStatus( _L("Connecting..."));
+            break;
+        case EConnected:
+            iConsole.SetStatus( _L("Connected"));
+            break;
+        case EListening:
+            iConsole.SetStatus( _L("Listening"));
+            break;
+        case ETimedOut:
+            iConsole.SetStatus( _L("Timed out"));
+            break;
+        case ELookingUp:
+            iConsole.SetStatus( _L("Looking up..."));
+            break;
+        case ELookUpFailed:
+            iConsole.SetStatus( _L("Look up failed"));
+            break;
+        case EConnectFailed:
+            iConsole.SetStatus( _L("Failed"));
+            break;
+        case EDisconnecting:
+            iConsole.SetStatus( _L("Disconnecting..."));
+            break;
+        default:
+            User::Panic( KPanicSocketsEngine, EConnTestBadStatus );
+            break;
+        }
+    iEngineStatus = aNewStatus;
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::PrintTextToConsole(const TDesC& aDes)
+// Helper function for printing notifications, text
+// formatting added.
+// ---------------------------------------------------------
+//
+void CSocketsEngine::PrintTextToConsole( const TDesC& aDes )
+    {
+    // Print some text on the console
+    iConsole.PrintNotify( aDes ); // Try if this works on real hw
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::SetConnectionData(const CSettingData* aData)
+// Set connection information.
+// ---------------------------------------------------------
+//
+void CSocketsEngine::SetConnectionData( const CSettingData* aData )
+    {
+    iServerName.Copy( aData->iServerName );
+    iPort = aData->iPort;
+
+    switch (aData->iProtocol)
+        {
+        case 0:
+            iProtocol = KProtocolInetTcp;
+            iSocketType = KSockStream;
+            break;
+        case 1:
+            iProtocol = KProtocolInetUdp;
+            iSocketType = KSockDatagram;
+            break;
+        default:
+            iProtocol = KProtocolInetTcp;
+            iSocketType = KSockStream;
+            break;
+        }
+
+    iRoaming = (TRoamingSetting)aData->iRoaming;
+
+    iHttpPage = aData->iHttpPage;
+    
+    iSettingData = (CSettingData*)aData;
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::SetCustomPrefs(const CCustomPrefsData* aData)
+// Set custom preferences information.
+// ---------------------------------------------------------
+//
+void CSocketsEngine::SetCustomPrefsData( const CCustomPrefsData* aData )
+    {
+    iCustomPrefsData = (CCustomPrefsData*)aData;
+    iExtPrefs->SetSnapPurpose( (CMManager::TSnapPurpose)aData->iSnapPurpose );
+    iExtPrefs->SetSnapId( aData->iSnapId );
+    iExtPrefs->SetIapId( aData->iIapId );
+    iExtPrefs->SetBearerSet( aData->iBearerSet );
+    iExtPrefs->SetNoteBehaviour( aData->iNoteBehaviour );
+    iExtPrefs->SetDisconnectDialog( aData->iDisconnectDialog );
+    iExtPrefs->SetConnSelectionDialog( aData->iConnSelectionDialog );
+    iExtPrefs->SetForcedRoaming( aData->iForcedRoaming );
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::ConnectionInfo()
+// Display information about current connection and sockets
+// ---------------------------------------------------------
+//
+void CSocketsEngine::ConnectionInfoL()
+    {
+    TInt result;
+    TBuf<40> val;
+    TBuf<40> network;
+    TBuf<20> query;
+    TName name;
+    TUint connCount;
+    TUint i, j;
+    TConnectionEnumArg args;
+    TUint32 networkId;
+    RApaLsSession appSess;
+    TApaAppInfo appInfo;
+    
+    User::LeaveIfError( appSess.Connect() );
+    CleanupClosePushL( appSess );
+
+    HBufC* buf = HBufC::NewLC( 2048 );
+    TPtr infoBuf = buf->Des();
+    
+    infoBuf.AppendFormat( _L("===============\n"));
+    infoBuf.AppendFormat( _L("Connection info:\n"));
+
+    // Connection name.
+    result = iConnection.Name( name );
+    User::LeaveIfError( result );
+    RDebug::Print( _L("ConnTest: Connection name: %S"), &name );
+
+    // Get connection info
+    result = iConnection.EnumerateConnections( connCount );
+    User::LeaveIfError( result );
+    RDebug::Print( _L("ConnTest: Number of connections: %d"), connCount );
+    infoBuf.AppendFormat( _L("Connections: %d\n"), connCount );
+
+    if (connCount == 0)
+        {
+        infoBuf.AppendFormat( _L("---------------\n"));
+        PrintTextToConsole( infoBuf );
+        CleanupStack::PopAndDestroy( buf ); // buf
+        CleanupStack::PopAndDestroy( &appSess );
+        return;
+        }
+
+    //
+    // Get active connection info
+    //
+    infoBuf.AppendFormat( _L("Active connection:\n"));
+
+    // IAP name
+    query.Format( _L("%s\\%s"), IAP, COMMDB_NAME);
+    result = iConnection.GetDesSetting(query, val);
+    if(result == KErrNone)
+        {
+        RDebug::Print(_L("ConnTest: IAP/Name value: %S"), &val);
+        infoBuf.AppendFormat(_L("-IAP: %S\n"), &val);
+        }
+
+    // Network id
+            query.Format(_L("%s\\%s"), IAP, IAP_NETWORK);
+            result = iConnection.GetIntSetting(query, networkId);
+            if(result == KErrNone)
+                {
+                // Get the corresponding network name for this id,
+            // it is user friendlier.
+            RDebug::Print(_L("ConnTest: NetworkId: %d"), networkId);
+
+            // Network name
+            CCommsDatabase* TheDb;
+
+            TheDb = CCommsDatabase::NewL();
+            CleanupStack::PushL(TheDb);
+
+            CCommsDbTableView* view = TheDb->OpenViewMatchingUintLC( TPtrC(NETWORK),
+                    TPtrC(COMMDB_ID),
+                    networkId );
+            result = view->GotoFirstRecord();
+
+            if(result == KErrNone)
+                {
+                view->ReadTextL(TPtrC(COMMDB_NAME), network);
+                RDebug::Print(_L("ConnTest: Network name: %S"), &network);
+                infoBuf.AppendFormat(_L("-net: %S\n"), &network);
+                }
+            CleanupStack::PopAndDestroy(view);
+            CleanupStack::PopAndDestroy(TheDb);
+            }
+
+        // Note! The following doesn't work, because NETWORK table
+        // is not among those tables where information can be
+        // fetched this way. (Perhaps in future.)
+        /*    
+         // Network name
+         query.Format(_L("%s\\%s"), NETWORK, COMMDB_NAME);
+         result = iConnection.GetDesSetting(query, network);
+         RDebug::Print(_L("IAP/Name value: %S"), &val);
+         infoBuf.AppendFormat(_L("Network name: %S\n"), &network);
+         
+         // Network id
+         query.Format(_L("%s\\%s"), NETWORK, COMMDB_ID);
+         result = iConnection.GetIntSetting(query, networkId);
+         RDebug::Print(_L("IAP/Name value: %d"), networkId);
+         infoBuf.AppendFormat(_L("Network id: %d\n"), networkId);
+         */
+
+        // Print transferred data
+        TPckg<TUint> uplinkVolume(0);
+        TPckg<TUint> downlinkVolume(0);
+        TRequestStatus status;
+        iConnection.DataTransferredRequest(uplinkVolume, downlinkVolume, status);
+        User::WaitForRequest(status);
+        if(status.Int() == KErrNone)
+            {
+            infoBuf.AppendFormat(_L("-up=%d, down=%d\n"), uplinkVolume(), downlinkVolume());
+            }
+
+        for(i = 1; i <= connCount; i++)
+            {
+            infoBuf.AppendFormat(_L("\nConnection %d:\n"), i);
+            TPckgBuf<TConnectionInfo> connInfo;
+            result = iConnection.GetConnectionInfo(i, connInfo);
+            User::LeaveIfError(result);
+            RDebug::Print(_L("ConnTest: IapId: %d, NetId: %d"), connInfo().iIapId, connInfo().iNetId);
+            infoBuf.AppendFormat(_L(" -IapId=%d, NetId=%d\n"), connInfo().iIapId, connInfo().iNetId);
+
+            // Get info about clients using this connection
+            args.iIndex = i;
+            TConnEnumArgBuf enumBuf(args);
+
+            TConnectionGetClientInfoArg clientInfoArg;
+            clientInfoArg.iIndex = 1;
+            TConnGetClientInfoArgBuf clientInfoBuf(clientInfoArg);
+
+            TConnectionClientInfo clientInfo;
+
+            result = iConnection.Control(KCOLConnection, KCoEnumerateConnectionClients, enumBuf);
+            User::LeaveIfError(result);
+            infoBuf.AppendFormat(_L(" -clients: %d\n"), enumBuf().iCount);
+
+            for(j = 1; j <= enumBuf().iCount; j++)
+                {
+                clientInfoBuf().iIndex = j;
+                result = iConnection.Control( KCOLConnection,
+                        KCoGetConnectionClientInfo,
+                        clientInfoBuf );
+                User::LeaveIfError(result);
+                clientInfo = clientInfoBuf().iClientInfo;
+
+                TInt id = clientInfo.iProcessId;
+                RDebug::Print(_L("ConnTest: ProcessId: %d"), id);
+
+                // Get application  name
+#ifndef __WINS__
+            result = appSess.GetAppInfo(appInfo, clientInfo.iUid);
+            if(result == KErrNone)
+                {
+                infoBuf.AppendFormat(_L("   client %d=%S\n"), j, &(appInfo.iCaption));
+                }
+            else
+                {
+                // Servers don't have caption name (e.g. Connection Monitor server)
+                infoBuf.AppendFormat(_L("   client %d=%x\n"), j, clientInfo.iUid);
+                }
+#else
+            infoBuf.AppendFormat(_L("   client %d=N/A in WINS\n"), j);
+#endif        
+            }
+
+        // Get info about sockets using this connection
+        TConnectionGetSocketInfoArg socketInfoArg;
+        socketInfoArg.iIndex = i;
+        TConnGetSocketInfoArgBuf socketInfoBuf(socketInfoArg);
+        TConnectionSocketInfo socketInfo;
+
+        result = iConnection.Control( KCOLConnection,
+                KCoEnumerateConnectionSockets,
+                enumBuf);
+        User::LeaveIfError(result);
+        infoBuf.AppendFormat(_L(" -sockets: %d\n"), enumBuf().iCount);
+
+        for(j = 1; j <= enumBuf().iCount; j++)
+            {
+            socketInfoBuf().iIndex = j;
+            result = iConnection.Control( KCOLConnection,
+                    KCoGetConnectionSocketInfo,
+                    socketInfoBuf );
+            User::LeaveIfError(result);
+            socketInfo = socketInfoBuf().iSocketInfo;
+
+            TUint id = socketInfo.iAddressFamily;
+            TBuf<5> prot;
+            socketInfo.iProtocol == KProtocolInetTcp ? prot.Copy(_L("tcp")) : prot.Copy(_L("udp"));
+
+            TSockAddr sa = socketInfo.iSourceAddress;
+            TSockAddr da = socketInfo.iDestinationAddress;
+
+            TInetAddr& source = TInetAddr::Cast(sa);
+            TInetAddr& dest = TInetAddr::Cast(da);
+
+            TBuf<20> a1;
+            source.Output(a1);
+
+            TBuf<20> a2;
+            dest.Output(a2);
+
+            RDebug::Print(_L("ConnTest: ProcessId: %d"), id);
+            infoBuf.AppendFormat(_L("  %d. socket: %S\n   %S->\n   %S\n"), j, &prot, &a1, &a2);
+            }
+        } // for (i...  
+    infoBuf.AppendFormat(_L("---------------\n"));
+    PrintTextToConsole(infoBuf);
+    CleanupStack::PopAndDestroy(buf);
+    CleanupStack::PopAndDestroy(&appSess);
+    }
+
+    // ---------------------------------------------------------
+    // CSocketsEngine::SendHttpFrameworkRequestL()
+    // Send HTTP request
+    // ---------------------------------------------------------
+    //
+void CSocketsEngine::SendHttpFrameworkRequestL( TBool aHasBody,
+        TBool aDoPerformance,
+        TBool aIsSecure )
+    {
+    iHttpClient->SetPerformance( aDoPerformance );
+    iHttpClient->InvokeHttpMethodL( iSettingData, aHasBody, aIsSecure );
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::ProgressNotifyReceivedL(TInt aStage)
+// Progress notification has been received, display the
+// stage in output window.
+// ---------------------------------------------------------
+//
+void CSocketsEngine::ProgressNotifyReceivedL( TInt aStage, TInt aError )
+    {
+    
+    TBuf8<64> text;
+    text.AppendFormat( _L8("Progress: %d, %d"), aStage, aError );
+
+    TBuf8<16> error;
+    error.Format( _L8(", %d"), aError );
+
+    switch (aStage)
+        {
+        case KConnectionUninitialised: // 0
+            iConsole.PrintNotify( _L8("Connection uninit"));
+            iConsole.PrintNotify( error );
+            break;
+        case KStartingSelection: // 1000
+            iConsole.PrintNotify( _L8("Starting selection"));
+            iConsole.PrintNotify( error );
+            break;
+        case KFinishedSelection: // 2000
+            iConsole.PrintNotify( _L8("Finished selection"));
+            iConsole.PrintNotify( error );
+            
+            if (iCloseConnection)
+                {
+                // We are starting RConnection instance for testing RConnection::Close.
+                // At this point we can attach the monitoring RConnection instance to
+                // interface, and delete the temporary progress notifier.
+                //
+                // We may loose few progress notifications at start up, that's small
+                // prize compared to advantages: we get correct notifications when
+                // interface goes down, which is the essential part of this test.
+
+                TBuf<20> query;
+                TUint32 networkId;
+                TInt result;
+                TInt err( KErrNone );
+                TConnectionInfo info;
+                TPckg<TConnectionInfo> pckgInfo( info );
+                
+                // Network id
+                query.Format( _L("%s\\%s"), IAP, IAP_NETWORK);
+                result = iCloseConnection->GetIntSetting(query, networkId);
+                if(result == KErrNone)
+                    {
+                    info.iIapId = iPrefs.IapId();
+                    info.iNetId = networkId;
+                    }
+                err = iConnection.Attach( pckgInfo, RConnection::EAttachTypeMonitor );
+                if ( err != KErrNone )
+                    {
+                    iConsole.ErrorNotify(_L("Attaching failed"), err);
+                    }
+                iTempProgressNotifier->Cancel();
+                delete iTempProgressNotifier;
+                iTempProgressNotifier = NULL;
+                }
+            break;
+            case KConnectionFailure: // 2001
+                        iConsole.PrintNotify(_L8("Connection failure"));
+                        iConsole.PrintNotify(error);
+                        break;
+                        case KMinAgtProgress: // 2500
+                        iConsole.PrintNotify(_L8("Min agt progress"));
+                        iConsole.PrintNotify(error);
+                        break;
+                        case KConnectionOpen: // 3500
+                        iConsole.PrintNotify(_L8("Connection open"));
+                        iConsole.PrintNotify(error);
+                        break;
+                        case KConnectionClosed: // 4500
+                        iConsole.PrintNotify(_L8("Connection closed"));
+                        iConsole.PrintNotify(error);
+                        break;
+                        case KMaxAgtProgress: // 5500
+                        iConsole.PrintNotify(_L8("Max agent progress"));
+                        iConsole.PrintNotify(error);
+                        break;
+                        case KMinNifProgress: // 6000
+                        iConsole.PrintNotify(_L8("Min nif progress"));
+                        iConsole.PrintNotify(error);
+                        break;
+                        case KLinkLayerOpen: // 7000
+                        iConsole.PrintNotify(_L8("Link layer open"));
+                        iConsole.PrintNotify(error);
+                        break;
+                        case KLinkLayerClosed: // 8000
+                        iConsole.PrintNotify(_L8("Link layer closed"));
+                        iConsole.PrintNotify(error);
+                        iHttpClient->SetHttpConnectionInfoL(ETrue, iConnection, iSocketServ);
+
+                        switch (iEngineStatus)
+                            {
+                            case EStartingInterface:
+                            // This case will occur, if username/password prompt dialog
+                            // is used and cancel is selected in dialog, and when error
+                            // occurs during interface startup.
+                            break;
+                            case EInterfaceDown:
+                            // EInterfaceDown must be handled also, because this
+                            // state has been set in StopInterface method.
+                            break;
+                            case EListening:
+                            iListeningSocket.CancelAccept();
+                            iListeningSocket.Close();
+                            // FALLTHROUGH
+                            case ELookingUp:
+                            // Cancel everything depending on state.
+                            iResolver.Cancel();
+                            iResolver.Close();
+                            // FALLTHROUGH
+                            case EConnected:
+                            iSocketsRead->Cancel();
+                            iSocketsWrite->Cancel();
+                            // FALLTHROUGH
+                            case EConnecting:
+                            // This looks awful, but is required because of the fall through
+                            // and buggy implementation of the CancelConnect.
+                            if( EConnecting == iEngineStatus )
+                                {
+                                iSocket.CancelConnect();
+                                }
+                            // FALLTHROUGH
+                            case EDisconnecting:
+                            iSocket.Close();
+                            // FALLTHROUGH
+                            case EInterfaceUp:
+                            if (iRoaming == ERoamingOff)
+                                {
+                                UnRegisterFromMobilityAPI();
+                                SetSocketEngineConnType(ETypeUnknown);
+                                ChangeStatus(EInterfaceDown);
+                                }
+                            else
+                                {
+                                iConsole.PrintNotify(_L8("MobilitySession lost!\n"));
+                                UnRegisterFromMobilityAPI();
+                                SetSocketEngineConnType(ETypeUnknown);
+                                ChangeStatus(EInterfaceDown);
+                                }
+                            break;
+                            default:
+                            User::Panic(KPanicSocketsEngine, EConnTestBadStatus);
+                            break;
+                            }
+
+                        break;
+                        case KMaxNifProgress: // 9000
+                        iConsole.PrintNotify(_L8("Max nif progress\n"));
+                        break;
+                        default:
+                        iConsole.PrintNotify(text);
+                        }
+                    iConsole.PrintNotify(_L8("\f"));
+                    }
+
+                // ---------------------------------------------------------
+                // CSocketsEngine::ProgressNotifyError(TInt aStatus)
+                // Some error has occurred while receiving progress
+                // notifications.
+                // ---------------------------------------------------------
+                //
+void CSocketsEngine::ProgressNotifyError( TInt aStatus )
+    {
+    iConsole.ErrorNotify( _L("<CProgressNotifier> Notify failed"), aStatus );
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::TimerExpired()
+// Cancel ongoing operations
+// ---------------------------------------------------------
+//
+void CSocketsEngine::TimerExpired()
+    {
+    Cancel();
+    iConsole.ErrorNotify( _L("<CSocketsEngine> Timed out"), KErrTimedOut );
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::InterfaceInfoL()
+// Print information about interfaces.
+// ---------------------------------------------------------
+//
+void CSocketsEngine::InterfaceInfoL()
+    {
+    TBuf<128> t;
+    TAutoClose<RSocketServ> ss;
+    User::LeaveIfError( ss.iObj.Connect() );
+    ss.PushL();
+
+    TAutoClose<RSocket> sock;
+    User::LeaveIfError( sock.iObj.Open( ss.iObj, _L("udp")) );
+    sock.PushL();
+
+    User::LeaveIfError(
+            sock.iObj.SetOpt( KSoInetEnumInterfaces, KSolInetIfCtrl ) );
+
+    TProtocolDesc in;
+    User::LeaveIfError( sock.iObj.Info( in ) );
+
+    TPckgBuf<TSoInetInterfaceInfo> info, next;
+    
+    TInt res = sock.iObj.GetOpt( KSoInetNextInterface, KSolInetIfCtrl, info );
+    if (res != KErrNone)
+        {
+        User::Leave( res );
+        }
+    TInt count = 0;
+    while (res == KErrNone)
+        {
+        res = sock.iObj.GetOpt( KSoInetNextInterface, KSolInetIfCtrl, next );
+
+        if (info().iName != _L("") && info().iName != _L("loop6") && info().iName != _L("loop4"))
+            {
+            t.Format( _L("Interface %d\n"),count++ );
+            PrintTextToConsole( t );
+            t.Format( _L("Name \"%S\"\n"), &info().iName );
+            PrintTextToConsole( t );
+
+            t.Format( _L("State "));
+            switch (info().iState)
+                {
+                case EIfPending:
+                    t.AppendFormat( _L("pending\n"));
+                    break;
+                case EIfUp:
+                    t.AppendFormat( _L("up\n"));
+                    break;
+                case EIfBusy:
+                    t.AppendFormat( _L("busy\n"));
+                    break;
+                default:
+                    t.AppendFormat( _L("down\n"));
+                    break;
+                }
+
+            t.AppendFormat( _L("Mtu %d\n"), info().iMtu );
+            t.AppendFormat( _L("Speed Metric %d\n"), info().iSpeedMetric );
+
+            t.Format( _L("Features:"));
+            info().iFeatures & KIfIsLoopback ? t.AppendFormat( _L(" loopback")) : t.AppendFormat( _L(""));
+            info().iFeatures & KIfIsDialup ? t.AppendFormat( _L(" dialup")) : t.AppendFormat( _L(""));
+            info().iFeatures & KIfIsPointToPoint ? t.AppendFormat( _L(" pointtopoint")) : t.AppendFormat( _L(""));
+            info().iFeatures & KIfCanBroadcast ? t.AppendFormat( _L(" canbroadcast")) : t.AppendFormat( _L(""));
+            info().iFeatures & KIfCanMulticast ? t.AppendFormat( _L(" canmulticast")) : t.AppendFormat( _L(""));
+            info().iFeatures & KIfCanSetMTU ? t.AppendFormat( _L(" cansetmtu")) : t.AppendFormat( _L(""));
+            info().iFeatures & KIfHasHardwareAddr ? t.AppendFormat( _L(" hardwareaddr")) : t.AppendFormat( _L(""));
+            info().iFeatures & KIfCanSetHardwareAddr ? t.AppendFormat( _L(" cansethardwareaddr")) : t.AppendFormat( _L(""));
+            t.AppendFormat( _L("\n"));
+
+            TName address;
+            info().iAddress.Output( address );
+            t.Format( _L("Addr: %S\n"), &address );
+
+            if (info().iAddress.IsLinkLocal())
+                {
+                t.AppendFormat( _L("  -link local\n"));
+                }
+            else if (info().iAddress.IsSiteLocal())
+                {
+                t.AppendFormat( _L("  -site local\n"));
+                }
+            else
+                {
+                t.AppendFormat( _L("  -global\n"));
+                }
+            PrintTextToConsole( t );
+
+            info().iBrdAddr.Output( address );
+            info().iDefGate.Output( address );
+            t.Format( _L("Gatew: %S\n"), &address );
+            info().iNameSer1.Output( address );
+            t.AppendFormat( _L("DNS 1: %S\n"), &address );
+            info().iNameSer2.Output( address );
+            t.AppendFormat( _L("DNS 2: %S\n"), &address );
+            PrintTextToConsole( t );
+            
+            if (info().iHwAddr.Family() != KAFUnspec)
+                {
+                PrintTextToConsole( _L("Hardware address "));
+                TUint j;
+                for (j = sizeof(SSockAddr); j < sizeof(SSockAddr) + 6; ++j)
+                    {
+                    if (j < (TUint)info().iHwAddr.Length())
+                        {
+                        t.Format( _L("%02X"), info().iHwAddr[j] );
+                        PrintTextToConsole( t );
+                        }
+                    else
+                        {
+                        PrintTextToConsole( _L("??"));
+                        }
+                    if (j < sizeof(SSockAddr) + 5)
+                        {
+                        PrintTextToConsole( _L("-"));
+                        }
+                    else
+                        {
+                        PrintTextToConsole( _L("\n"));
+                        }
+                    }
+                }
+            }
+        if (res == KErrNone)
+            {
+            info = next;
+            PrintTextToConsole( _L("\n"));
+            }
+        else
+            {
+            PrintTextToConsole( _L("\n"));
+            }
+        }
+    t.Format( _L("Total %d interfaces\n"),count );
+    PrintTextToConsole( t );
+
+    sock.Pop();
+    ss.Pop();
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::SetWLANQoS()
+// Set QoS for WLAN
+// ---------------------------------------------------------
+//
+void CSocketsEngine::SetWLANQoS( TInt aClass )
+    {
+    TInt opt;
+    TInt err;
+    TBuf<64> t;
+    
+    if (iEngineStatus != EConnected)
+        {
+        t.Copy( _L("\nConnect first!\n"));
+        PrintTextToConsole( t );
+        return;
+        }
+
+    err = iSocket.GetOpt( KSoIpTOS, KSolInetIp, opt );
+
+    opt = opt >> 2;
+
+    if (err == KErrNone)
+        {
+        t.Format( _L("Old TOS: %x\n"), opt );
+        }
+    else
+        {
+        t.Format( _L("Cannot get TOS opt\n"));
+        }
+
+    PrintTextToConsole( t );
+
+    switch (aClass)
+        {
+        case 7:
+            err = iSocket.SetOpt( KSoIpTOS, KSolInetIp, 0xE0 );
+            break;
+        case 5:
+            err = iSocket.SetOpt( KSoIpTOS, KSolInetIp, 0xA0 );
+            break;
+        case 3:
+            err = iSocket.SetOpt( KSoIpTOS, KSolInetIp, 0x60 );
+            break;
+        case 1:
+            err = iSocket.SetOpt( KSoIpTOS, KSolInetIp, 0x20 );
+            break;
+        case 0:
+            err = iSocket.SetOpt( KSoIpTOS, KSolInetIp, 0x0 );
+            break;
+        default:
+            break;
+        }
+
+    err = iSocket.GetOpt( KSoIpTOS, KSolInetIp, opt );
+
+    opt = opt >> 2;
+
+    if (err == KErrNone)
+        {
+        t.Format( _L("New TOS: %x\n"), opt );
+        }
+    else
+        {
+        t.Format( _L("Cannot set TOS opt\n"));
+        }
+    
+    PrintTextToConsole( t );
+    
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::QoS1()
+// 
+// ---------------------------------------------------------
+//
+void CSocketsEngine::QoS1()
+    {
+    /*TQoSSelector selector;
+     selector.setAddr(iSocket);
+     
+     RQoSPolicy policy;
+     policy.Open(selector);
+     
+     CQosParameters* parameters = GetparametersL();
+     policy.NotifyEvent(iObserver);
+     policy.SetQoS(*parameters);
+     
+     policy.GetQoS();
+     policy.Close();
+     */
+    }
+
+// ---------------------------------------------------------
+// CSocketsEngine::QoS2()
+// 
+// ---------------------------------------------------------
+//
+void CSocketsEngine::QoS2()
+    {
+    /*CQosParameters* parameters = GetparametersL();
+     
+     RQoSChannel channel;
+     
+     channel.Open(iSocket);
+     channel.NotifyEvent(iObserver);
+     channel.SetQoS(*parameters);
+     
+     channel.Join(iSocket2); 
+     
+     channel.Leave(ISocket);
+     
+     channel.Close();
+     */
+    }
+// ----------------------------------------------------------------------------
+// CSocketsEngine::SendDataL
+// Start the sending of the data
+// ----------------------------------------------------------------------------
+//
+void CSocketsEngine::SendDataL( const TBuf8<KSendDataSize> aData )
+    {
+    RDebug::Print( _L("ConnTest: SendDataL: size = %d"),aData.Length() );
+    iSendCount = 0;
+    iData->Des().Copy( aData );
+    iData->Des().ZeroTerminate();
+    iSocket.SetOpt( KSoUdpSynchronousSend, KSolInetUdp, 1 );
+
+    iTroughputDataSize = 0;
+    iThroughputStartTime.UniversalTime();
+    
+    DoSendDataL();
+    }
+
+// ----------------------------------------------------------------------------
+// CSocketsEngine::DoSendDataL
+// Do the actual sending of the data
+// ----------------------------------------------------------------------------
+//
+void CSocketsEngine::DoSendDataL()
+    {
+    if (iSendCount++ < (iSettingData->iPackets))
+        {
+        // Delay is given in milliseconds, timer uses microseconds.
+        if (iSettingData->iDelay != 0)
+            {
+            if (iSettingData->iProtocol == 1) //  1 == UDP here. Only way to send udp is raw data
+                {
+                RDebug::Print(
+                        _L("ConnTest: DoSendDataL: inserting seq number %d"),iSendCount );
+                TUint32* seqNumberPointer = (TUint32*)(iData->Des().Ptr());
+                *seqNumberPointer = ByteOrder::Swap32( iSendCount ); // put sequence number into to the packet
+                }
+            WriteL( *iData );
+            iSendTimer->After( (iSettingData->iDelay) * 1000 );
+            }
+        else
+            {
+            WriteFloodL( *iData, iSettingData->iPackets );
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// Notifys when a packet has been sent
+// aAmount is th amount of data that has been sent
+// ---------------------------------------------------------
+//
+void CSocketsEngine::NotifySend( TInt aAmount )
+    {
+    if (iThroughputStartTime != 0)
+        {
+        
+        iTroughputDataSize += aAmount;
+        TInt size = iSettingData->iPacketSize;
+        if (iSettingData->iPacketSize > KSendDataSize)
+            {
+            size = KSendDataSize;
+            }
+        // We add 1 for each packet since the create packet appends an extra \n
+        // after each packet
+        if (iTroughputDataSize == (iSettingData->iPackets * size))
+        // + iSettingData->iPackets) )
+            {
+            TBuf8<256> text;
+            Utils::CalculateThroughput( text, iThroughputStartTime,
+                    iTroughputDataSize );
+            iThroughputStartTime = 0;
+            iConsole.PrintNotify( text );
+            iTroughputDataSize = 0;
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// Marks starting time into memory
+//
+// ---------------------------------------------------------
+//
+void inline CSocketsEngine::StartTickCount()
+    {
+    if (!iUseTTime)
+        {
+        iStartTime = User::FastCounter();
+        }
+    else
+        {
+        iStartTTime.UniversalTime();
+        iStartTime = 1; // Non null. iStartTime is also used as flag.
+        }
+    
+    }
+
+// ---------------------------------------------------------
+// Calculates time interval using tick count and prints it
+//
+// ---------------------------------------------------------
+//
+void CSocketsEngine::StopTickCount( const TDesC& aComponentName )
+    {
+    TBuf<128> text;
+    if (!iUseTTime)
+        {
+        TUint32 currentTime = User::FastCounter();
+        currentTime = currentTime - iStartTime;
+
+        if (iStartTime == 0)
+            {
+            return; //do not print if start time hasn't been initialized.
+            }
+        iStartTime = 0;
+
+        TInt freq = 0;
+        TInt err = HAL::Get( HAL::EFastCounterFrequency, freq );
+        if (err != KErrNone || freq == 0)
+            {
+            text.Format( _L("FastCounter error: %d \n"),err );
+            }
+        else
+            {
+            currentTime = (currentTime * 1000.0) / freq;
+            text.Format( _L("%u ms by "), currentTime );
+            text.Append( aComponentName );
+            text.Append( _L("\n"));
+            }
+        }
+    else
+        {
+        TTime currentTime;
+        currentTime.UniversalTime();
+
+        if (iStartTime == 0)
+            {
+            return; //do not print if start time hasn't been initialized.
+            }
+        TTimeIntervalMicroSeconds interval = currentTime.MicroSecondsFrom(
+                iStartTTime );
+        iStartTime = 0;
+
+        TBuf<32> app;
+        app.Format( _L("%u ms by "), interval.Int64() / 1000 );
+        text.Append( app );
+        text.Append( aComponentName );
+        }
+    
+    PrintTextToConsole( text );
+    }
+
+// end of file