--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hti/HtiCommPlugins/HtiIPCommPlugin/src/HtiConnectionManager.cpp Wed Oct 13 16:17:58 2010 +0300
@@ -0,0 +1,853 @@
+/*
+* Copyright (c) 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: ECOM plugin for communication over IP port
+*
+*/
+
+
+// INCLUDE FILES
+#include "HtiIPCommEcomPlugin.h"
+#include "HtiConnectionManager.h"
+#include "HtiCfg.h"
+#include "HtiIPCommLogging.h"
+
+#include <commdb.h> // CCommsDatabase
+#include <HtiCfg.h>
+
+
+// CONSTANTS
+const static TInt KMaxHtiNotifierLength = 128;
+
+_LIT( KHtiIPCommError, "HtiIpCommError" );
+_LIT( KHtiOkButton, "OK" );
+
+_LIT( KHtiCfgPath, "\\" ); // root of drive
+_LIT( KHtiIPCommCfg, "HTIIPComm.cfg" );
+_LIT8( KIAPId, "IAPId" );
+_LIT8( KIAPName, "IAPName" );
+_LIT8( KLocalPort, "LocalPort" );
+_LIT8( KRemoteHost, "RemoteHost" );
+_LIT8( KRemotePort, "RemotePort" );
+_LIT8( KConnectTimeout, "ConnectTimeout" );
+
+
+void LogLocalHost( RSocket& aSocket )
+ {
+#ifdef __ENABLE_LOGGING__
+ // print the local ip to log
+ HTI_LOG_TEXT( "LocalHost:" );
+ TBuf<0x20> tmp;
+ TInetAddr localHost;
+ aSocket.LocalName( localHost );
+ localHost.Output( tmp );
+ tmp.AppendFormat( _L(":%d"), localHost.Port() );
+ HTI_LOG_DES( tmp );
+#else
+ aSocket.LocalPort(); // avoid compiler warning
+#endif
+ }
+
+void LogRemoteHost( RSocket& aSocket )
+ {
+#ifdef __ENABLE_LOGGING__
+ // print the local ip to log
+ HTI_LOG_TEXT( "RemoteHost:" );
+ TBuf<0x20> tmp;
+ TInetAddr remoteHost;
+ aSocket.RemoteName( remoteHost );
+ remoteHost.Output( tmp );
+ tmp.AppendFormat( _L(":%d"), remoteHost.Port() );
+ HTI_LOG_DES( tmp );
+#else
+ aSocket.LocalPort(); // avoid compiler warning
+#endif
+ }
+
+
+CHtiConnectionManager* CHtiConnectionManager::NewL( CHtiIPCommServer* aServer )
+ {
+ HTI_LOG_FUNC_IN( "CHtiConnectionManager::NewL" );
+ CHtiConnectionManager* self = new (ELeave) CHtiConnectionManager( aServer );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ HTI_LOG_FUNC_OUT( "CHtiConnectionManager::NewL" );
+ return self;
+ }
+
+CHtiConnectionManager::CHtiConnectionManager( CHtiIPCommServer* aServer ):
+ CActive( EPriorityStandard ),
+ iServer( aServer ),
+ iCfg( NULL ),
+ iListenPort( 0 ),
+ iState( EDisconnected ),
+ iReceiveRequestComplete( ETrue ),
+ iSendRequestComplete( ETrue ),
+ iSendMonitor( NULL ),
+ iReceiveMonitor( NULL ),
+ iConnectTimer( NULL )
+ {
+ iReceiveBuffer.Zero();
+ iSendBuffer.Zero();
+ CActiveScheduler::Add(this);
+ }
+
+CHtiConnectionManager::~CHtiConnectionManager()
+ {
+ HTI_LOG_FUNC_IN( "CHtiConnectionManager::~CHtiConnectionManager" );
+
+ if ( iCfg )
+ delete iCfg;
+
+ if ( iConnectTimer )
+ delete iConnectTimer;
+
+ if ( iDataSocket.SubSessionHandle() )
+ iDataSocket.Close();
+
+ if ( iListenSocket.SubSessionHandle() )
+ iListenSocket.Close();
+
+ if ( iSendMonitor )
+ delete iSendMonitor;
+
+ if ( iReceiveMonitor )
+ delete iReceiveMonitor;
+
+ if ( iConnection.SubSessionHandle() )
+ iConnection.Close();
+
+ if ( iSocketServ.Handle() )
+ iSocketServ.Close();
+
+ // NOTE: If this is done in the beginning the server will never die!
+ Cancel();
+
+ HTI_LOG_FUNC_OUT( "CHtiConnectionManager::~CHtiConnectionManager" );
+ }
+
+
+void CHtiConnectionManager::ConstructL()
+ {
+ HTI_LOG_FUNC_IN( "CHtiConnectionManager::ConstructL" );
+
+ // Load configuration file
+ iCfg = CHtiCfg::NewL();
+ TRAPD( err, iCfg->LoadCfgL( KHtiCfgPath, KHtiIPCommCfg ) );
+ if ( err )
+ {
+ HTI_LOG_FORMAT( "LoadCfgL err %d", err );
+ ShowErrorNotifierL( _L( "Could not load config file" ), err );
+ User::Leave( err );
+ }
+
+ // Get IAP
+ ReadIAPConfigL();
+
+ // Create monitors and timers
+ iSendMonitor = CHtiSocketMonitor::NewL( MHtiSocketObserver::EWriteSocket, this);
+ iReceiveMonitor = CHtiSocketMonitor::NewL( MHtiSocketObserver::EReadSocket, this);
+ iConnectTimer = CHtiTimer::NewL( *this );
+
+ // Open socket server
+ err = iSocketServ.Connect();
+ if ( err )
+ {
+ HTI_LOG_FORMAT( "error connecting to socket server %d", err);
+ User::Leave( err );
+ }
+
+/*
+ HTI_LOG_TEXT( "Supported protocols:" );
+ TUint numOfProtocols;
+ iSocketServ.NumProtocols( numOfProtocols );
+ for ( TInt i = 1; i <= numOfProtocols; i++ )
+ {
+ TProtocolDesc desc;
+ iSocketServ.GetProtocolInfo( i, desc );
+ HTI_LOG_DES( desc.iName );
+ HTI_LOG_FORMAT( "AddrFamily : %d", desc.iAddrFamily );
+ HTI_LOG_FORMAT( "SockType : %d", desc.iSockType );
+ HTI_LOG_FORMAT( "Protocol : %d", desc.iProtocol );
+ }
+*/
+
+ // Start IAP
+ err = iConnection.Open( iSocketServ );
+ if ( err )
+ {
+ HTI_LOG_FORMAT( "error opening connection %d", err);
+ User::Leave( err );
+ }
+
+ HTI_LOG_TEXT( "Starting IAP" );
+ iConnPref.SetDialogPreference( ECommDbDialogPrefDoNotPrompt );
+ iConnPref.SetIapId( iIAPId );
+ iConnection.Start( iConnPref, iStatus );
+ iState = EStartingIAP;
+ SetActive();
+
+ HTI_LOG_FUNC_IN( "CHtiConnectionManager::ConstructL" );
+ }
+
+
+void CHtiConnectionManager::ReadIAPConfigL()
+ {
+ // Try to read IAP id first
+ TRAPD( err, iIAPId = iCfg->GetParameterIntL( KIAPId ) );
+ if ( err == KErrNone )
+ {
+ HTI_LOG_FORMAT( "Using IAP id %d", iIAPId);
+ }
+ else
+ {
+ // IAP id not defined try reading IAP name
+ TBuf8<KMaxParameterValueLength> IAPNameCfg;
+ TRAP( err, IAPNameCfg = iCfg->GetParameterL( KIAPName ) );
+
+ // If IAP name is not defined it wont be found from commsdb...
+
+ HTI_LOG_TEXT( "Searching for IAP:" );
+ HTI_LOG_DES( IAPNameCfg );
+
+ // open commdb
+ CCommsDatabase* commDb = CCommsDatabase::NewL( EDatabaseTypeIAP );
+ CleanupStack::PushL(commDb);
+
+ // open IAP table
+
+ // Using all bearers from TCommDbBearer because when
+ // using KCommDbBearerUnknown it just leaves
+ TUint32 bearerSet = KCommDbBearerCSD|KCommDbBearerPSD|KCommDbBearerLAN|
+ KCommDbBearerVirtual|KCommDbBearerPAN|
+ KCommDbBearerWLAN;
+
+ CCommsDbTableView* commView =
+ commDb->OpenIAPTableViewMatchingBearerSetLC(bearerSet,
+ ECommDbConnectionDirectionUnknown);
+
+ // search all IAPs
+ HTI_LOG_TEXT( "IAP records:" );
+ if (commView->GotoFirstRecord() == KErrNone)
+ {
+ do
+ {
+ TBuf8<KCommsDbSvrMaxFieldLength> iapName;
+ commView->ReadTextL( TPtrC(COMMDB_NAME), iapName );
+ HTI_LOG_DES( iapName );
+
+ if ( iapName == IAPNameCfg )
+ {
+ commView->ReadUintL( TPtrC(COMMDB_ID), iIAPId );
+ HTI_LOG_FORMAT( "Found it! IAP id %d", iIAPId );
+ }
+
+ }
+ while ( commView->GotoNextRecord() == KErrNone );
+ }
+ CleanupStack::PopAndDestroy(2); // commView, commDb
+ }
+
+ // Cannot start if Internet Access Point is not defined
+ if ( iIAPId == 0 )
+ {
+ HTI_LOG_TEXT( "IAP not defined" );
+ ShowErrorNotifierL( _L( "IAP not defined" ), KErrNotFound );
+ User::Leave( KErrNotFound );
+ }
+ }
+
+
+void CHtiConnectionManager::ReadConnectionConfigL()
+ {
+ // Read listening port number from config file
+ TRAPD( err, iListenPort = iCfg->GetParameterIntL( KLocalPort ) );
+
+ if ( iListenPort == 0)
+ {
+ // ...or remote host to connect
+
+ TBuf8<KMaxParameterValueLength> remoteHostCfg;
+ TRAP( err, remoteHostCfg = iCfg->GetParameterL( KRemoteHost ) );
+ if ( err )
+ {
+ HTI_LOG_TEXT( "No remote host specified!" )
+ ShowErrorNotifierL( _L( "No remote host specified!" ), err );
+ User::Leave( err );
+ }
+
+ // Convert TDesC8 -> TDesC
+ TBuf<KMaxParameterValueLength> tmp;
+ tmp.Copy( remoteHostCfg );
+
+ // Check remote host if its a plain ip address
+ if ( iRemoteHost.Input( tmp ) )
+ {
+ // ...its not. Do a DNS-lookup request
+ HTI_LOG_TEXT( "Do a DSN-lookup request" );
+
+ RHostResolver resolver;
+ err = resolver.Open( iSocketServ, KAfInet, KProtocolInetUdp, iConnection );
+ if ( err )
+ {
+ HTI_LOG_FORMAT( "error opening resolver %d", err );
+ User::Leave( err );
+ }
+
+ TNameEntry entry;
+ err = resolver.GetByName( tmp, entry );
+ if ( err )
+ {
+ HTI_LOG_FORMAT( "error getting address by name %d", err );
+ ShowErrorNotifierL(
+ _L( "Could not resolve remote host!" ), err );
+ User::Leave( err );
+ }
+
+ iRemoteHost = entry().iAddr;
+
+ resolver.Close();
+ }
+
+ // Get remote host port
+ TRAP( err, iRemoteHost.SetPort( iCfg->GetParameterIntL( KRemotePort ) ) );
+ if ( err )
+ {
+ HTI_LOG_TEXT( "No remote port specified!" )
+ ShowErrorNotifierL( _L( "No remote port specified!" ), err );
+ User::Leave( err );
+ }
+
+ // Get connect timeout
+ TRAP( err, iConnectTimeout = iCfg->GetParameterIntL( KConnectTimeout ) );
+ if ( err )
+ {
+ // default is 30 seconds
+ iConnectTimeout = 30;
+ }
+
+ HTI_LOG_FORMAT( "Connect timeout %d", iConnectTimeout );
+ }
+ }
+
+void CHtiConnectionManager::StartConnectingL()
+ {
+ HTI_LOG_FUNC_IN( "CHtiConnectionManager::StartConnectingL" );
+ CancelAllRequests();
+
+ // close if open
+ if ( iDataSocket.SubSessionHandle() )
+ iDataSocket.Close();
+
+ // open data socket
+ TInt err = iDataSocket.Open( iSocketServ,
+ KAfInet,
+ KSockStream,
+ KProtocolInetTcp,
+ iConnection );
+ if ( err )
+ {
+ HTI_LOG_FORMAT( "error opening data socket %d", err );
+ User::Leave( err );
+ }
+
+ iDataSocket.Connect( iRemoteHost, iStatus );
+ iState = EConnecting;
+
+ // Set a timeout for this operation if timer is not
+ // already active and there is a timeout defined
+ if ( iConnectTimeout && !iConnectTimer->IsActive() )
+ {
+ // iConnectTimeout is in seconds
+ iConnectTimer->After( iConnectTimeout*1000000 );
+ }
+
+ SetActive();
+ HTI_LOG_FUNC_OUT( "CHtiConnectionManager::StartConnectingL" );
+ }
+
+
+void CHtiConnectionManager::StartListeningL()
+ {
+ HTI_LOG_FUNC_IN( "CHtiConnectionManager::StartListeningL" );
+ HTI_LOG_FORMAT( "Port %d", iListenPort );
+
+ CancelAllRequests();
+
+ // close if open
+ if ( iDataSocket.SubSessionHandle() )
+ iDataSocket.Close();
+
+ // open empty socket
+ TInt err = iDataSocket.Open( iSocketServ );
+ if ( err )
+ {
+ HTI_LOG_FORMAT( "error opening blank socket %d", err );
+ User::Leave( err );
+ }
+
+ // start listening
+ iListenSocket.Accept( iDataSocket, iStatus );
+ iState = EWaitingConnection;
+
+ SetActive();
+ HTI_LOG_FUNC_OUT( "CHtiConnectionManager::StartListeningL" );
+ }
+
+void CHtiConnectionManager::CancelAllRequests()
+ {
+ HTI_LOG_TEXT( "Cancelling all active server requests" );
+ CancelReceive();
+ CancelSend();
+ }
+
+void CHtiConnectionManager::RunL()
+ {
+ HTI_LOG_FUNC_IN( "CHtiConnectionManager::RunL" );
+ HTI_LOG_FORMAT( "status %d", iStatus.Int() );
+
+ TInt err;
+
+ switch ( iState )
+ {
+ case EStartingIAP:
+
+ HTI_LOG_TEXT( "EStartingIAP" );
+
+ if ( iStatus.Int() )
+ {
+ HTI_LOG_FORMAT( "error starting IAP %d", iStatus.Int() );
+ ShowErrorNotifierL( _L( "Error starting IAP" ), iStatus.Int() );
+ User::Leave( iStatus.Int() );
+ }
+
+ ReadConnectionConfigL();
+
+ // remote host is defined - start connecting to it
+ if ( iListenPort == 0 )
+ {
+ StartConnectingL();
+ }
+ // remote host not defined - start listening
+ else
+ {
+ HTI_LOG_TEXT( "Setting up listen socket" );
+
+ // open listening socket
+ err = iListenSocket.Open( iSocketServ,
+ KAfInet,
+ KSockStream,
+ KProtocolInetTcp,
+ iConnection );
+ if ( err )
+ {
+ HTI_LOG_FORMAT( "error opening listen socket %d", err );
+ User::Leave( err );
+ }
+
+ // set the port to listen
+ err = iListenSocket.SetLocalPort( iListenPort );
+ if ( err )
+ {
+ HTI_LOG_FORMAT( "error setting local port %d", err );
+ User::Leave( err );
+ }
+
+ // set listen queue size
+ err = iListenSocket.Listen( 5 );
+ if ( err )
+ {
+ HTI_LOG_FORMAT( "error settig up listening socket %d", err );
+ User::Leave( err );
+ }
+
+ StartListeningL();
+ }
+
+
+ break;
+
+ case EWaitingConnection:
+ HTI_LOG_TEXT( "EWaitingConnection" );
+
+ if ( iStatus.Int() )
+ {
+ HTI_LOG_FORMAT( "error accepting connection %d", iStatus.Int() );
+ ShowErrorNotifierL(
+ _L( "Error accepting connection!" ), iStatus.Int() );
+ User::Leave( iStatus.Int() );
+ }
+
+ iState = EConnected;
+ HTI_LOG_TEXT( "Connected!" );
+ User::InfoPrint( _L("HtiIPComm: connected!") );
+
+ if ( !iReceiveRequestComplete )
+ {
+ // There is a pending read request
+ HTI_LOG_TEXT( "Pending read request" );
+ ReadSocket();
+ }
+
+ if ( !iSendRequestComplete )
+ {
+ // There is a pending write request
+ HTI_LOG_TEXT( "Pending write request" );
+ WriteSocket();
+ }
+
+ break;
+
+ case EConnecting:
+ HTI_LOG_TEXT( "EConnecting" );
+
+ if ( iStatus.Int() )
+ {
+ HTI_LOG_FORMAT( "error connecting to remote host %d", iStatus.Int() );
+ HTI_LOG_TEXT( "trying again..." );
+ User::After( 1000000 ); // wait 1 second before trying again
+ StartConnectingL();
+ }
+ else
+ {
+ // Cancel the timer
+ iConnectTimer->Cancel();
+
+ iState = EConnected;
+ HTI_LOG_TEXT( "Connected!" );
+ User::InfoPrint( _L("HtiIPComm: connected!") );
+
+ //LogLocalHost( iDataSocket );
+ //LogRemoteHost( iDataSocket );
+
+ if ( !iReceiveRequestComplete )
+ {
+ // There is a pending read request
+ HTI_LOG_TEXT( "Pending read request" );
+ ReadSocket();
+ }
+
+ if ( !iSendRequestComplete )
+ {
+ // There is a pending write request
+ HTI_LOG_TEXT( "Pending write request" );
+ WriteSocket();
+ }
+ }
+
+ break;
+
+ case EConnected:
+ HTI_LOG_TEXT( "EConnected" );
+ break;
+
+ case EDisconnecting:
+ HTI_LOG_TEXT( "EDisconnecting" );
+ break;
+
+ case EDisconnected:
+ HTI_LOG_TEXT( "EDisconnected" );
+ break;
+
+ default:
+ HTI_LOG_TEXT( "Unknown" );
+ User::Panic( _L("HtiIPComm"), EUnknownState );
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiConnectionManager::RunL" );
+ }
+
+
+void CHtiConnectionManager::DoCancel()
+ {
+ HTI_LOG_TEXT( "CHtiConnectionManager::DoCancel" );
+ }
+
+
+TInt CHtiConnectionManager::RunError(TInt aError)
+ {
+ HTI_LOG_FUNC_IN( "CHtiConnectionManager::RunError" );
+ HTI_LOG_FORMAT( "error %d closing server...", aError );
+ iServer->CloseServer();
+ HTI_LOG_FUNC_OUT( "CHtiConnectionManager::RunError" );
+ aError = aError;
+ return KErrNone;
+ }
+
+
+void CHtiConnectionManager::Receive( const RMessage2& aMessage )//( TDes8& aRawdataBuf, TRequestStatus& aStatus )
+ {
+ HTI_LOG_FUNC_IN( "CHtiConnectionManager::Receive" );
+
+ if ( !iReceiveRequestComplete )
+ {
+ HTI_LOG_TEXT( "complete with KErrServerBusy" );
+ aMessage.Complete( KErrServerBusy );
+ }
+ else
+ {
+ iReceiveRequestComplete = EFalse;
+ iReceiveRequest = aMessage;
+
+ if ( iState == EConnected )
+ {
+ ReadSocket();
+ }
+ else
+ {
+ HTI_LOG_TEXT( "not connected" );
+ }
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiConnectionManager::Receive" );
+ }
+
+
+void CHtiConnectionManager::Send( const RMessage2& aMessage )
+ {
+ HTI_LOG_FUNC_IN( "CHtiConnectionManager::Send" );
+
+ if ( !iSendRequestComplete )
+ {
+ HTI_LOG_TEXT( "complete with KErrServerBusy" );
+ aMessage.Complete( KErrServerBusy );
+ }
+ else
+ {
+ iSendRequestComplete = EFalse;
+ iSendRequest = aMessage;
+ TInt err = aMessage.Read( 0, iSendBuffer );
+ if ( err )
+ {
+ User::Panic( _L("HtiIPComm"), EBadDescriptor );
+ }
+
+ if ( iState == EConnected )
+ {
+ WriteSocket();
+ }
+ else
+ {
+ HTI_LOG_TEXT( "not connected" );
+ }
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiConnectionManager::Send" );
+ }
+
+void CHtiConnectionManager::ReadSocket()
+ {
+ HTI_LOG_FUNC_IN( "CHtiConnectionManager::ReadSocket" );
+
+ iReceiveMonitor->Activate();
+ iReceiveBuffer.Zero();
+ iDataSocket.RecvOneOrMore( iReceiveBuffer, 0,
+ iReceiveMonitor->iStatus, iRecvLen );
+
+ // This works fine with the emulator...
+ //iDataSocket.RecvOneOrMore( *(TDes8*) iReceiveRequest.Ptr0(),
+ // 0, iReceiveMonitor->iStatus, iRecvLen );
+
+ HTI_LOG_FUNC_OUT( "CHtiConnectionManager::ReadSocket" );
+ }
+
+void CHtiConnectionManager::WriteSocket()
+ {
+ HTI_LOG_FUNC_IN( "CHtiConnectionManager::WriteSocket" );
+
+ iSendMonitor->Activate();
+ iDataSocket.Write( iSendBuffer, iSendMonitor->iStatus );
+
+ // This works fine with the emulator...
+ //iDataSocket.Write( *(TDesC8*) iSendRequest.Ptr0(),
+ // iSendMonitor->iStatus );
+
+ HTI_LOG_FUNC_OUT( "CHtiConnectionManager::WriteSocket" );
+ }
+
+void CHtiConnectionManager::CancelReceive()
+ {
+ HTI_LOG_TEXT( "CHtiConnectionManager::CancelReceive" );
+
+ if ( !iReceiveRequestComplete )
+ {
+ // Is there an active socket receive?
+ if ( iReceiveMonitor->IsActive() )
+ {
+ // ReportComplete() should complete this
+ HTI_LOG_TEXT( "CancelRecv" );
+ iDataSocket.CancelRecv();
+ }
+ else
+ {
+ HTI_LOG_TEXT( "complete with KErrCancel" );
+ iReceiveRequest.Complete( KErrCancel );
+ iReceiveRequestComplete = ETrue;
+ iReceiveBuffer.Zero();
+ }
+ }
+ }
+
+void CHtiConnectionManager::CancelSend()
+ {
+ HTI_LOG_TEXT( "CHtiConnectionManager::CancelSend" );
+
+ if ( !iSendRequestComplete )
+ {
+ // Is there an active socket send?
+ if ( iSendMonitor->IsActive() )
+ {
+ // ReportComplete() should complete this
+ HTI_LOG_TEXT( "CancelWrite" );
+ iDataSocket.CancelWrite();
+ }
+ else
+ {
+ HTI_LOG_TEXT( "complete with KErrCancel" );
+ iSendRequest.Complete( KErrCancel );
+ iSendRequestComplete = ETrue;
+ iSendBuffer.Zero();
+ }
+ }
+ }
+
+void CHtiConnectionManager::ReportComplete( MHtiSocketObserver::TRequestType aType, TInt aError )
+ {
+ HTI_LOG_FUNC_IN( "CHtiConnectionManager::ReportComplete" );
+
+ HTI_LOG_FORMAT( "error %d", aError );
+
+ TInt err = 0;
+
+ switch ( aType )
+ {
+ case MHtiSocketObserver::EReadSocket:
+ HTI_LOG_TEXT( "EReadSocket" );
+ err = iReceiveRequest.Write( 0 , iReceiveBuffer );
+ if ( err )
+ {
+ HTI_LOG_FORMAT( "Panic! Error writing received data to client buffer %d", err );
+ User::Panic( _L("HtiIPComm"), EBadDescriptor );
+ }
+
+ iReceiveBuffer.Zero();
+ iReceiveRequestComplete = ETrue;
+ iReceiveRequest.Complete( aError );
+
+ break;
+
+ case MHtiSocketObserver::EWriteSocket:
+ HTI_LOG_TEXT( "EWriteSocket" );
+ iSendBuffer.Zero();
+ iSendRequestComplete = ETrue;
+ iSendRequest.Complete( aError );
+ break;
+
+ default:
+ User::Panic( _L("HtiIPComm"), EUnknownCompletion );
+ }
+
+
+ // Disconnect if there is an error.
+ if ( aError &&
+ ( aError != KErrCancel ) ) // ...except when there is a cancel
+ {
+ iState = EDisconnected;
+ HTI_LOG_TEXT( "Disconnected!" );
+ User::InfoPrint( _L("HtiIPComm: Disconnected!") );
+
+ // If disconnected try to listen or connect again
+ if ( iListenPort == 0 )
+ {
+ // wait 1 second before trying again
+ User::After( 1000000 );
+ StartConnectingL();
+ }
+ else
+ {
+ StartListeningL();
+ }
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiConnectionManager::ReportComplete" );
+ }
+
+CHtiTimer* CHtiTimer::NewL( MHtiTimerObserver& aObserver )
+ {
+ CHtiTimer* self = new (ELeave) CHtiTimer( aObserver );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+CHtiTimer::CHtiTimer( MHtiTimerObserver& aObserver ):
+ CTimer( EPriorityUserInput ),
+ iObserver( aObserver)
+ {
+ }
+
+CHtiTimer::~CHtiTimer()
+ {
+ Cancel();
+ }
+
+void CHtiTimer::ConstructL()
+ {
+ CTimer::ConstructL();
+ CActiveScheduler::Add( this );
+ }
+
+void CHtiTimer::RunL()
+ {
+ iObserver.TimerExpiredL();
+ }
+
+TInt CHtiTimer::RunError(TInt aError)
+ {
+ HTI_LOG_FORMAT( "CHtiTimer::RunError %d", aError );
+ aError = aError;
+ return KErrNone;
+ }
+
+void CHtiConnectionManager::TimerExpiredL()
+ {
+ HTI_LOG_TEXT( "Timed out! Closing IPCommServer..." );
+ ShowErrorNotifierL(
+ _L( "Timed out connecting to remote host!" ), KErrTimedOut );
+ iServer->CloseServer();
+ }
+
+void CHtiConnectionManager::ShowErrorNotifierL( const TDesC& aText,
+ TInt aErr )
+ {
+ RNotifier notifier;
+ User::LeaveIfError( notifier.Connect() );
+
+ TBuf<KMaxHtiNotifierLength> errorMsg;
+ // aText is cut if it's too long - leaving some space also for error code
+ errorMsg.Append( aText.Left( errorMsg.MaxLength() - 10 ) );
+ errorMsg.Append( _L("\n") );
+ errorMsg.AppendNum( aErr );
+
+ TRequestStatus status;
+ TInt button;
+ notifier.Notify( KHtiIPCommError, errorMsg,
+ KHtiOkButton, KNullDesC, button, status );
+ User::WaitForRequest( status );
+ notifier.Close();
+ }
+
+
+