hti/HtiCommPlugins/HtiIPCommPlugin/src/HtiConnectionManager.cpp
branchRCL_3
changeset 59 8ad140f3dd41
equal deleted inserted replaced
49:7fdc9a71d314 59:8ad140f3dd41
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  ECOM plugin for communication over IP port
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "HtiIPCommEcomPlugin.h"
       
    21 #include "HtiConnectionManager.h"
       
    22 #include "HtiCfg.h"
       
    23 #include "HtiIPCommLogging.h"
       
    24 
       
    25 #include <commdb.h>             // CCommsDatabase
       
    26 #include <HtiCfg.h>
       
    27 
       
    28 
       
    29 // CONSTANTS
       
    30 const static TInt KMaxHtiNotifierLength = 128;
       
    31 
       
    32 _LIT( KHtiIPCommError, "HtiIpCommError" );
       
    33 _LIT( KHtiOkButton, "OK" );
       
    34 
       
    35 _LIT( KHtiCfgPath,      "\\" ); // root of drive
       
    36 _LIT( KHtiIPCommCfg,    "HTIIPComm.cfg" );
       
    37 _LIT8( KIAPId,          "IAPId" );
       
    38 _LIT8( KIAPName,        "IAPName" );
       
    39 _LIT8( KLocalPort,      "LocalPort" );
       
    40 _LIT8( KRemoteHost,     "RemoteHost" );
       
    41 _LIT8( KRemotePort,     "RemotePort" );
       
    42 _LIT8( KConnectTimeout, "ConnectTimeout" );
       
    43 
       
    44 
       
    45 void LogLocalHost( RSocket& aSocket )
       
    46     {
       
    47 #ifdef __ENABLE_LOGGING__
       
    48     // print the local ip to log
       
    49     HTI_LOG_TEXT( "LocalHost:" );
       
    50     TBuf<0x20> tmp;
       
    51     TInetAddr localHost;
       
    52     aSocket.LocalName( localHost );
       
    53     localHost.Output( tmp );
       
    54     tmp.AppendFormat( _L(":%d"), localHost.Port() );
       
    55     HTI_LOG_DES( tmp );
       
    56 #else
       
    57     aSocket.LocalPort();  // avoid compiler warning
       
    58 #endif
       
    59     }
       
    60 
       
    61 void LogRemoteHost( RSocket& aSocket )
       
    62     {
       
    63 #ifdef __ENABLE_LOGGING__
       
    64     // print the local ip to log
       
    65     HTI_LOG_TEXT( "RemoteHost:" );
       
    66     TBuf<0x20> tmp;
       
    67     TInetAddr remoteHost;
       
    68     aSocket.RemoteName( remoteHost );
       
    69     remoteHost.Output( tmp );
       
    70     tmp.AppendFormat( _L(":%d"), remoteHost.Port() );
       
    71     HTI_LOG_DES( tmp );
       
    72 #else
       
    73     aSocket.LocalPort();  // avoid compiler warning
       
    74 #endif
       
    75     }
       
    76 
       
    77 
       
    78 CHtiConnectionManager* CHtiConnectionManager::NewL( CHtiIPCommServer* aServer )
       
    79     {
       
    80     HTI_LOG_FUNC_IN( "CHtiConnectionManager::NewL" );
       
    81     CHtiConnectionManager* self = new (ELeave) CHtiConnectionManager( aServer );
       
    82     CleanupStack::PushL( self );
       
    83     self->ConstructL();
       
    84     CleanupStack::Pop( self );
       
    85     HTI_LOG_FUNC_OUT( "CHtiConnectionManager::NewL" );
       
    86     return self;
       
    87     }
       
    88 
       
    89 CHtiConnectionManager::CHtiConnectionManager( CHtiIPCommServer* aServer ):
       
    90     CActive( EPriorityStandard ),
       
    91     iServer( aServer ),
       
    92     iCfg( NULL ),
       
    93     iListenPort( 0 ),
       
    94     iState( EDisconnected ),
       
    95     iReceiveRequestComplete( ETrue ),
       
    96     iSendRequestComplete( ETrue ),
       
    97     iSendMonitor( NULL ),
       
    98     iReceiveMonitor( NULL ),
       
    99     iConnectTimer( NULL )
       
   100     {
       
   101     iReceiveBuffer.Zero();
       
   102     iSendBuffer.Zero();
       
   103     CActiveScheduler::Add(this);
       
   104     }
       
   105 
       
   106 CHtiConnectionManager::~CHtiConnectionManager()
       
   107     {
       
   108     HTI_LOG_FUNC_IN( "CHtiConnectionManager::~CHtiConnectionManager" );
       
   109 
       
   110     if ( iCfg )
       
   111         delete iCfg;
       
   112 
       
   113     if ( iConnectTimer )
       
   114         delete iConnectTimer;
       
   115 
       
   116     if ( iDataSocket.SubSessionHandle() )
       
   117         iDataSocket.Close();
       
   118 
       
   119     if ( iListenSocket.SubSessionHandle() )
       
   120         iListenSocket.Close();
       
   121 
       
   122     if ( iSendMonitor )
       
   123         delete iSendMonitor;
       
   124 
       
   125     if ( iReceiveMonitor )
       
   126         delete iReceiveMonitor;
       
   127 
       
   128     if ( iConnection.SubSessionHandle() )
       
   129         iConnection.Close();
       
   130 
       
   131     if ( iSocketServ.Handle() )
       
   132         iSocketServ.Close();
       
   133 
       
   134     // NOTE: If this is done in the beginning the server will never die!
       
   135     Cancel();
       
   136 
       
   137     HTI_LOG_FUNC_OUT( "CHtiConnectionManager::~CHtiConnectionManager" );
       
   138     }
       
   139 
       
   140 
       
   141 void CHtiConnectionManager::ConstructL()
       
   142     {
       
   143     HTI_LOG_FUNC_IN( "CHtiConnectionManager::ConstructL" );
       
   144 
       
   145     // Load configuration file
       
   146     iCfg = CHtiCfg::NewL();
       
   147     TRAPD( err, iCfg->LoadCfgL( KHtiCfgPath, KHtiIPCommCfg ) );
       
   148     if ( err )
       
   149         {
       
   150         HTI_LOG_FORMAT( "LoadCfgL err %d", err );
       
   151         ShowErrorNotifierL( _L( "Could not load config file" ), err );
       
   152         User::Leave( err );
       
   153         }
       
   154 
       
   155     // Get IAP
       
   156     ReadIAPConfigL();
       
   157 
       
   158     // Create monitors and timers
       
   159     iSendMonitor    = CHtiSocketMonitor::NewL( MHtiSocketObserver::EWriteSocket, this);
       
   160     iReceiveMonitor = CHtiSocketMonitor::NewL( MHtiSocketObserver::EReadSocket, this);
       
   161     iConnectTimer   = CHtiTimer::NewL( *this );
       
   162 
       
   163     // Open socket server
       
   164     err = iSocketServ.Connect();
       
   165     if ( err )
       
   166         {
       
   167         HTI_LOG_FORMAT( "error connecting to socket server %d", err);
       
   168         User::Leave( err );
       
   169         }
       
   170 
       
   171 /*
       
   172     HTI_LOG_TEXT( "Supported protocols:" );
       
   173     TUint numOfProtocols;
       
   174     iSocketServ.NumProtocols( numOfProtocols );
       
   175     for ( TInt i = 1; i <= numOfProtocols; i++ )
       
   176         {
       
   177         TProtocolDesc desc;
       
   178         iSocketServ.GetProtocolInfo( i, desc  );
       
   179         HTI_LOG_DES( desc.iName );
       
   180         HTI_LOG_FORMAT( "AddrFamily : %d", desc.iAddrFamily );
       
   181         HTI_LOG_FORMAT( "SockType   : %d", desc.iSockType );
       
   182         HTI_LOG_FORMAT( "Protocol   : %d", desc.iProtocol );
       
   183         }
       
   184 */
       
   185 
       
   186     // Start IAP
       
   187     err = iConnection.Open( iSocketServ );
       
   188     if ( err )
       
   189         {
       
   190         HTI_LOG_FORMAT( "error opening connection %d", err);
       
   191         User::Leave( err );
       
   192         }
       
   193 
       
   194     HTI_LOG_TEXT( "Starting IAP" );
       
   195     iConnPref.SetDialogPreference( ECommDbDialogPrefDoNotPrompt );
       
   196     iConnPref.SetIapId( iIAPId );
       
   197     iConnection.Start( iConnPref, iStatus );
       
   198     iState = EStartingIAP;
       
   199     SetActive();
       
   200 
       
   201     HTI_LOG_FUNC_IN( "CHtiConnectionManager::ConstructL" );
       
   202     }
       
   203 
       
   204 
       
   205 void CHtiConnectionManager::ReadIAPConfigL()
       
   206     {
       
   207     // Try to read IAP id first
       
   208     TRAPD( err, iIAPId = iCfg->GetParameterIntL( KIAPId ) );
       
   209     if ( err == KErrNone )
       
   210         {
       
   211         HTI_LOG_FORMAT( "Using IAP id %d", iIAPId);
       
   212         }
       
   213     else
       
   214         {
       
   215         // IAP id not defined try reading IAP name
       
   216         TBuf8<KMaxParameterValueLength> IAPNameCfg;
       
   217         TRAP( err, IAPNameCfg = iCfg->GetParameterL( KIAPName ) );
       
   218 
       
   219         // If IAP name is not defined it wont be found from commsdb...
       
   220 
       
   221         HTI_LOG_TEXT( "Searching for IAP:" );
       
   222         HTI_LOG_DES( IAPNameCfg );
       
   223 
       
   224         // open commdb
       
   225         CCommsDatabase* commDb = CCommsDatabase::NewL( EDatabaseTypeIAP );
       
   226         CleanupStack::PushL(commDb);
       
   227 
       
   228         // open IAP table
       
   229 
       
   230         // Using all bearers from TCommDbBearer because when
       
   231         // using KCommDbBearerUnknown it just leaves
       
   232         TUint32 bearerSet = KCommDbBearerCSD|KCommDbBearerPSD|KCommDbBearerLAN|
       
   233                             KCommDbBearerVirtual|KCommDbBearerPAN|
       
   234                             KCommDbBearerWLAN;
       
   235 
       
   236         CCommsDbTableView* commView =
       
   237             commDb->OpenIAPTableViewMatchingBearerSetLC(bearerSet,
       
   238                                                         ECommDbConnectionDirectionUnknown);
       
   239 
       
   240         // search all IAPs
       
   241         HTI_LOG_TEXT( "IAP records:" );
       
   242         if (commView->GotoFirstRecord() == KErrNone)
       
   243             {
       
   244             do
       
   245                 {
       
   246                 TBuf8<KCommsDbSvrMaxFieldLength> iapName;
       
   247                 commView->ReadTextL( TPtrC(COMMDB_NAME), iapName );
       
   248                 HTI_LOG_DES( iapName );
       
   249 
       
   250                 if ( iapName == IAPNameCfg )
       
   251                     {
       
   252                     commView->ReadUintL( TPtrC(COMMDB_ID), iIAPId );
       
   253                     HTI_LOG_FORMAT( "Found it! IAP id %d", iIAPId );
       
   254                     }
       
   255 
       
   256                 }
       
   257             while ( commView->GotoNextRecord() == KErrNone );
       
   258             }
       
   259         CleanupStack::PopAndDestroy(2); // commView, commDb
       
   260         }
       
   261 
       
   262     // Cannot start if Internet Access Point is not defined
       
   263     if ( iIAPId == 0 )
       
   264         {
       
   265         HTI_LOG_TEXT( "IAP not defined" );
       
   266         ShowErrorNotifierL( _L( "IAP not defined" ), KErrNotFound );
       
   267         User::Leave( KErrNotFound );
       
   268         }
       
   269     }
       
   270 
       
   271 
       
   272 void CHtiConnectionManager::ReadConnectionConfigL()
       
   273     {
       
   274     // Read listening port number from config file
       
   275     TRAPD( err, iListenPort = iCfg->GetParameterIntL( KLocalPort ) );
       
   276 
       
   277     if ( iListenPort == 0)
       
   278         {
       
   279         // ...or remote host to connect
       
   280 
       
   281         TBuf8<KMaxParameterValueLength> remoteHostCfg;
       
   282         TRAP( err, remoteHostCfg = iCfg->GetParameterL( KRemoteHost ) );
       
   283         if ( err )
       
   284             {
       
   285             HTI_LOG_TEXT( "No remote host specified!" )
       
   286             ShowErrorNotifierL( _L( "No remote host specified!" ), err );
       
   287             User::Leave( err );
       
   288             }
       
   289 
       
   290         // Convert TDesC8 -> TDesC
       
   291         TBuf<KMaxParameterValueLength> tmp;
       
   292         tmp.Copy( remoteHostCfg );
       
   293 
       
   294         // Check remote host if its a plain ip address
       
   295         if ( iRemoteHost.Input( tmp ) )
       
   296             {
       
   297             // ...its not. Do a DNS-lookup request
       
   298             HTI_LOG_TEXT( "Do a DSN-lookup request" );
       
   299 
       
   300             RHostResolver resolver;
       
   301             err = resolver.Open( iSocketServ, KAfInet, KProtocolInetUdp, iConnection );
       
   302             if ( err )
       
   303                 {
       
   304                 HTI_LOG_FORMAT( "error opening resolver %d", err );
       
   305                 User::Leave( err );
       
   306                 }
       
   307 
       
   308             TNameEntry entry;
       
   309             err = resolver.GetByName( tmp, entry );
       
   310             if ( err )
       
   311                 {
       
   312                 HTI_LOG_FORMAT( "error getting address by name %d", err );
       
   313                 ShowErrorNotifierL(
       
   314                     _L( "Could not resolve remote host!" ), err );
       
   315                 User::Leave( err );
       
   316                 }
       
   317 
       
   318             iRemoteHost = entry().iAddr;
       
   319 
       
   320             resolver.Close();
       
   321             }
       
   322 
       
   323         // Get remote host port
       
   324         TRAP( err, iRemoteHost.SetPort( iCfg->GetParameterIntL( KRemotePort ) ) );
       
   325         if ( err )
       
   326             {
       
   327             HTI_LOG_TEXT( "No remote port specified!" )
       
   328             ShowErrorNotifierL( _L( "No remote port specified!" ), err );
       
   329             User::Leave( err );
       
   330             }
       
   331 
       
   332         // Get connect timeout
       
   333         TRAP( err, iConnectTimeout = iCfg->GetParameterIntL( KConnectTimeout ) );
       
   334         if ( err )
       
   335             {
       
   336             // default is 30 seconds
       
   337             iConnectTimeout = 30;
       
   338             }
       
   339 
       
   340         HTI_LOG_FORMAT( "Connect timeout %d", iConnectTimeout );
       
   341         }
       
   342     }
       
   343 
       
   344 void CHtiConnectionManager::StartConnectingL()
       
   345     {
       
   346     HTI_LOG_FUNC_IN( "CHtiConnectionManager::StartConnectingL" );
       
   347     CancelAllRequests();
       
   348 
       
   349     // close if open
       
   350     if ( iDataSocket.SubSessionHandle() )
       
   351         iDataSocket.Close();
       
   352 
       
   353     // open data socket
       
   354     TInt err = iDataSocket.Open( iSocketServ,
       
   355                         KAfInet,
       
   356                         KSockStream,
       
   357                         KProtocolInetTcp,
       
   358                         iConnection );
       
   359     if ( err )
       
   360         {
       
   361         HTI_LOG_FORMAT( "error opening data socket %d", err );
       
   362         User::Leave( err );
       
   363         }
       
   364 
       
   365     iDataSocket.Connect( iRemoteHost, iStatus );
       
   366     iState = EConnecting;
       
   367 
       
   368     // Set a timeout for this operation if timer is not
       
   369     // already active and there is a timeout defined
       
   370     if ( iConnectTimeout && !iConnectTimer->IsActive() )
       
   371         {
       
   372         // iConnectTimeout is in seconds
       
   373         iConnectTimer->After( iConnectTimeout*1000000 );
       
   374         }
       
   375 
       
   376     SetActive();
       
   377     HTI_LOG_FUNC_OUT( "CHtiConnectionManager::StartConnectingL" );
       
   378     }
       
   379 
       
   380 
       
   381 void CHtiConnectionManager::StartListeningL()
       
   382     {
       
   383     HTI_LOG_FUNC_IN( "CHtiConnectionManager::StartListeningL" );
       
   384     HTI_LOG_FORMAT( "Port %d", iListenPort );
       
   385 
       
   386     CancelAllRequests();
       
   387 
       
   388     // close if open
       
   389     if ( iDataSocket.SubSessionHandle() )
       
   390         iDataSocket.Close();
       
   391 
       
   392     // open empty socket
       
   393     TInt err = iDataSocket.Open( iSocketServ  );
       
   394     if ( err )
       
   395         {
       
   396         HTI_LOG_FORMAT( "error opening blank socket %d", err );
       
   397         User::Leave( err );
       
   398         }
       
   399 
       
   400     // start listening
       
   401     iListenSocket.Accept( iDataSocket, iStatus );
       
   402     iState = EWaitingConnection;
       
   403 
       
   404     SetActive();
       
   405     HTI_LOG_FUNC_OUT( "CHtiConnectionManager::StartListeningL" );
       
   406     }
       
   407 
       
   408 void CHtiConnectionManager::CancelAllRequests()
       
   409     {
       
   410     HTI_LOG_TEXT( "Cancelling all active server requests" );
       
   411     CancelReceive();
       
   412     CancelSend();
       
   413     }
       
   414 
       
   415 void CHtiConnectionManager::RunL()
       
   416     {
       
   417     HTI_LOG_FUNC_IN( "CHtiConnectionManager::RunL" );
       
   418     HTI_LOG_FORMAT( "status %d", iStatus.Int() );
       
   419 
       
   420     TInt err;
       
   421 
       
   422     switch ( iState )
       
   423         {
       
   424         case EStartingIAP:
       
   425 
       
   426             HTI_LOG_TEXT( "EStartingIAP" );
       
   427 
       
   428             if ( iStatus.Int() )
       
   429                 {
       
   430                 HTI_LOG_FORMAT( "error starting IAP %d", iStatus.Int() );
       
   431                 ShowErrorNotifierL( _L( "Error starting IAP" ), iStatus.Int() );
       
   432                 User::Leave( iStatus.Int() );
       
   433                 }
       
   434 
       
   435             ReadConnectionConfigL();
       
   436 
       
   437             // remote host is defined - start connecting to it
       
   438             if ( iListenPort == 0 )
       
   439                 {
       
   440                 StartConnectingL();
       
   441                 }
       
   442             // remote host not defined - start listening
       
   443             else
       
   444                 {
       
   445                 HTI_LOG_TEXT( "Setting up listen socket" );
       
   446 
       
   447                 // open listening socket
       
   448                 err = iListenSocket.Open( iSocketServ,
       
   449                                     KAfInet,
       
   450                                     KSockStream,
       
   451                                     KProtocolInetTcp,
       
   452                                     iConnection );
       
   453                 if ( err )
       
   454                     {
       
   455                     HTI_LOG_FORMAT( "error opening listen socket %d", err );
       
   456                     User::Leave( err );
       
   457                     }
       
   458 
       
   459                 // set the port to listen
       
   460                 err = iListenSocket.SetLocalPort( iListenPort );
       
   461                 if ( err )
       
   462                     {
       
   463                     HTI_LOG_FORMAT( "error setting local port %d", err );
       
   464                     User::Leave( err );
       
   465                     }
       
   466 
       
   467                 // set listen queue size
       
   468                 err = iListenSocket.Listen( 5 );
       
   469                 if ( err )
       
   470                     {
       
   471                     HTI_LOG_FORMAT( "error settig up listening socket %d", err );
       
   472                     User::Leave( err );
       
   473                     }
       
   474 
       
   475                 StartListeningL();
       
   476                 }
       
   477 
       
   478 
       
   479             break;
       
   480 
       
   481         case EWaitingConnection:
       
   482             HTI_LOG_TEXT( "EWaitingConnection" );
       
   483 
       
   484             if ( iStatus.Int() )
       
   485                 {
       
   486                 HTI_LOG_FORMAT( "error accepting connection %d", iStatus.Int() );
       
   487                 ShowErrorNotifierL(
       
   488                     _L( "Error accepting connection!" ), iStatus.Int() );
       
   489                 User::Leave( iStatus.Int() );
       
   490                 }
       
   491 
       
   492             iState = EConnected;
       
   493             HTI_LOG_TEXT( "Connected!" );
       
   494             User::InfoPrint( _L("HtiIPComm: connected!") );
       
   495 
       
   496             if ( !iReceiveRequestComplete )
       
   497                 {
       
   498                 // There is a pending read request
       
   499                 HTI_LOG_TEXT( "Pending read request" );
       
   500                 ReadSocket();
       
   501                 }
       
   502 
       
   503             if ( !iSendRequestComplete )
       
   504                 {
       
   505                 // There is a pending write request
       
   506                 HTI_LOG_TEXT( "Pending write request" );
       
   507                 WriteSocket();
       
   508                 }
       
   509 
       
   510             break;
       
   511 
       
   512         case EConnecting:
       
   513             HTI_LOG_TEXT( "EConnecting" );
       
   514 
       
   515             if ( iStatus.Int() )
       
   516                 {
       
   517                 HTI_LOG_FORMAT( "error connecting to remote host %d", iStatus.Int() );
       
   518                 HTI_LOG_TEXT( "trying again..." );
       
   519                 User::After( 1000000 ); // wait 1 second before trying again
       
   520                 StartConnectingL();
       
   521                 }
       
   522             else
       
   523                 {
       
   524                 // Cancel the timer
       
   525                 iConnectTimer->Cancel();
       
   526 
       
   527                 iState = EConnected;
       
   528                 HTI_LOG_TEXT( "Connected!" );
       
   529                 User::InfoPrint( _L("HtiIPComm: connected!") );
       
   530 
       
   531                 //LogLocalHost( iDataSocket );
       
   532                 //LogRemoteHost( iDataSocket );
       
   533 
       
   534                 if ( !iReceiveRequestComplete )
       
   535                     {
       
   536                     // There is a pending read request
       
   537                     HTI_LOG_TEXT( "Pending read request" );
       
   538                     ReadSocket();
       
   539                     }
       
   540 
       
   541                 if ( !iSendRequestComplete )
       
   542                     {
       
   543                     // There is a pending write request
       
   544                     HTI_LOG_TEXT( "Pending write request" );
       
   545                     WriteSocket();
       
   546                     }
       
   547                 }
       
   548 
       
   549             break;
       
   550 
       
   551         case EConnected:
       
   552             HTI_LOG_TEXT( "EConnected" );
       
   553             break;
       
   554 
       
   555         case EDisconnecting:
       
   556             HTI_LOG_TEXT( "EDisconnecting" );
       
   557             break;
       
   558 
       
   559         case EDisconnected:
       
   560             HTI_LOG_TEXT( "EDisconnected" );
       
   561             break;
       
   562 
       
   563         default:
       
   564             HTI_LOG_TEXT( "Unknown" );
       
   565             User::Panic( _L("HtiIPComm"), EUnknownState );
       
   566         }
       
   567 
       
   568     HTI_LOG_FUNC_OUT( "CHtiConnectionManager::RunL" );
       
   569     }
       
   570 
       
   571 
       
   572 void CHtiConnectionManager::DoCancel()
       
   573     {
       
   574     HTI_LOG_TEXT( "CHtiConnectionManager::DoCancel" );
       
   575     }
       
   576 
       
   577 
       
   578 TInt CHtiConnectionManager::RunError(TInt aError)
       
   579     {
       
   580     HTI_LOG_FUNC_IN( "CHtiConnectionManager::RunError" );
       
   581     HTI_LOG_FORMAT( "error %d closing server...", aError );
       
   582     iServer->CloseServer();
       
   583     HTI_LOG_FUNC_OUT( "CHtiConnectionManager::RunError" );
       
   584     aError = aError;
       
   585     return KErrNone;
       
   586     }
       
   587 
       
   588 
       
   589 void CHtiConnectionManager::Receive( const RMessage2& aMessage )//( TDes8& aRawdataBuf, TRequestStatus& aStatus )
       
   590     {
       
   591     HTI_LOG_FUNC_IN( "CHtiConnectionManager::Receive" );
       
   592 
       
   593     if ( !iReceiveRequestComplete )
       
   594         {
       
   595         HTI_LOG_TEXT( "complete with KErrServerBusy" );
       
   596         aMessage.Complete( KErrServerBusy );
       
   597         }
       
   598     else
       
   599         {
       
   600         iReceiveRequestComplete = EFalse;
       
   601         iReceiveRequest = aMessage;
       
   602 
       
   603         if ( iState == EConnected )
       
   604             {
       
   605             ReadSocket();
       
   606             }
       
   607         else
       
   608             {
       
   609             HTI_LOG_TEXT( "not connected" );
       
   610             }
       
   611         }
       
   612 
       
   613     HTI_LOG_FUNC_OUT( "CHtiConnectionManager::Receive" );
       
   614     }
       
   615 
       
   616 
       
   617 void CHtiConnectionManager::Send( const RMessage2& aMessage )
       
   618     {
       
   619     HTI_LOG_FUNC_IN( "CHtiConnectionManager::Send" );
       
   620 
       
   621     if ( !iSendRequestComplete )
       
   622         {
       
   623         HTI_LOG_TEXT( "complete with KErrServerBusy" );
       
   624         aMessage.Complete( KErrServerBusy );
       
   625         }
       
   626     else
       
   627         {
       
   628         iSendRequestComplete = EFalse;
       
   629         iSendRequest = aMessage;
       
   630         TInt err = aMessage.Read( 0, iSendBuffer );
       
   631         if ( err )
       
   632             {
       
   633             User::Panic( _L("HtiIPComm"), EBadDescriptor );
       
   634             }
       
   635 
       
   636         if ( iState == EConnected )
       
   637             {
       
   638             WriteSocket();
       
   639             }
       
   640         else
       
   641             {
       
   642             HTI_LOG_TEXT( "not connected" );
       
   643             }
       
   644         }
       
   645 
       
   646     HTI_LOG_FUNC_OUT( "CHtiConnectionManager::Send" );
       
   647     }
       
   648 
       
   649 void CHtiConnectionManager::ReadSocket()
       
   650     {
       
   651     HTI_LOG_FUNC_IN( "CHtiConnectionManager::ReadSocket" );
       
   652 
       
   653     iReceiveMonitor->Activate();
       
   654     iReceiveBuffer.Zero();
       
   655     iDataSocket.RecvOneOrMore( iReceiveBuffer, 0,
       
   656         iReceiveMonitor->iStatus, iRecvLen );
       
   657 
       
   658     // This works fine with the emulator...
       
   659     //iDataSocket.RecvOneOrMore( *(TDes8*) iReceiveRequest.Ptr0(),
       
   660     //                       0, iReceiveMonitor->iStatus, iRecvLen );
       
   661 
       
   662     HTI_LOG_FUNC_OUT( "CHtiConnectionManager::ReadSocket" );
       
   663     }
       
   664 
       
   665 void CHtiConnectionManager::WriteSocket()
       
   666     {
       
   667     HTI_LOG_FUNC_IN( "CHtiConnectionManager::WriteSocket" );
       
   668 
       
   669     iSendMonitor->Activate();
       
   670     iDataSocket.Write( iSendBuffer, iSendMonitor->iStatus );
       
   671 
       
   672     // This works fine with the emulator...
       
   673     //iDataSocket.Write( *(TDesC8*) iSendRequest.Ptr0(),
       
   674     //               iSendMonitor->iStatus );
       
   675 
       
   676     HTI_LOG_FUNC_OUT( "CHtiConnectionManager::WriteSocket" );
       
   677     }
       
   678 
       
   679 void CHtiConnectionManager::CancelReceive()
       
   680     {
       
   681     HTI_LOG_TEXT( "CHtiConnectionManager::CancelReceive" );
       
   682 
       
   683     if ( !iReceiveRequestComplete )
       
   684         {
       
   685         // Is there an active socket receive?
       
   686         if ( iReceiveMonitor->IsActive() )
       
   687             {
       
   688             // ReportComplete() should complete this
       
   689             HTI_LOG_TEXT( "CancelRecv" );
       
   690             iDataSocket.CancelRecv();
       
   691             }
       
   692         else
       
   693             {
       
   694             HTI_LOG_TEXT( "complete with KErrCancel" );
       
   695             iReceiveRequest.Complete( KErrCancel );
       
   696             iReceiveRequestComplete = ETrue;
       
   697             iReceiveBuffer.Zero();
       
   698             }
       
   699         }
       
   700     }
       
   701 
       
   702 void CHtiConnectionManager::CancelSend()
       
   703     {
       
   704     HTI_LOG_TEXT( "CHtiConnectionManager::CancelSend" );
       
   705 
       
   706     if ( !iSendRequestComplete )
       
   707         {
       
   708         // Is there an active socket send?
       
   709         if ( iSendMonitor->IsActive() )
       
   710             {
       
   711             // ReportComplete() should complete this
       
   712             HTI_LOG_TEXT( "CancelWrite" );
       
   713             iDataSocket.CancelWrite();
       
   714             }
       
   715         else
       
   716             {
       
   717             HTI_LOG_TEXT( "complete with KErrCancel" );
       
   718             iSendRequest.Complete( KErrCancel );
       
   719             iSendRequestComplete = ETrue;
       
   720             iSendBuffer.Zero();
       
   721             }
       
   722         }
       
   723     }
       
   724 
       
   725 void CHtiConnectionManager::ReportComplete( MHtiSocketObserver::TRequestType aType, TInt aError )
       
   726     {
       
   727     HTI_LOG_FUNC_IN( "CHtiConnectionManager::ReportComplete" );
       
   728 
       
   729     HTI_LOG_FORMAT( "error %d", aError );
       
   730 
       
   731     TInt err = 0;
       
   732 
       
   733     switch ( aType )
       
   734         {
       
   735         case MHtiSocketObserver::EReadSocket:
       
   736             HTI_LOG_TEXT( "EReadSocket" );
       
   737             err = iReceiveRequest.Write( 0 , iReceiveBuffer );
       
   738             if ( err )
       
   739                 {
       
   740                 HTI_LOG_FORMAT( "Panic! Error writing received data to client buffer %d", err );
       
   741                 User::Panic( _L("HtiIPComm"), EBadDescriptor );
       
   742                 }
       
   743 
       
   744             iReceiveBuffer.Zero();
       
   745             iReceiveRequestComplete = ETrue;
       
   746             iReceiveRequest.Complete( aError );
       
   747 
       
   748             break;
       
   749 
       
   750         case MHtiSocketObserver::EWriteSocket:
       
   751             HTI_LOG_TEXT( "EWriteSocket" );
       
   752             iSendBuffer.Zero();
       
   753             iSendRequestComplete = ETrue;
       
   754             iSendRequest.Complete( aError );
       
   755             break;
       
   756 
       
   757         default:
       
   758             User::Panic( _L("HtiIPComm"), EUnknownCompletion );
       
   759         }
       
   760 
       
   761 
       
   762     // Disconnect if there is an error.
       
   763     if ( aError &&
       
   764         ( aError != KErrCancel ) ) // ...except when there is a cancel
       
   765         {
       
   766         iState = EDisconnected;
       
   767         HTI_LOG_TEXT( "Disconnected!" );
       
   768         User::InfoPrint( _L("HtiIPComm: Disconnected!") );
       
   769 
       
   770         // If disconnected try to listen or connect again
       
   771         if ( iListenPort == 0 )
       
   772             {
       
   773             // wait 1 second before trying again
       
   774             User::After( 1000000 );
       
   775             StartConnectingL();
       
   776             }
       
   777         else
       
   778             {
       
   779             StartListeningL();
       
   780             }
       
   781         }
       
   782 
       
   783     HTI_LOG_FUNC_OUT( "CHtiConnectionManager::ReportComplete" );
       
   784     }
       
   785 
       
   786 CHtiTimer* CHtiTimer::NewL( MHtiTimerObserver& aObserver )
       
   787     {
       
   788     CHtiTimer* self = new (ELeave) CHtiTimer( aObserver );
       
   789     CleanupStack::PushL( self );
       
   790     self->ConstructL();
       
   791     CleanupStack::Pop( self );
       
   792     return self;
       
   793     }
       
   794 
       
   795 CHtiTimer::CHtiTimer( MHtiTimerObserver& aObserver ):
       
   796     CTimer( EPriorityUserInput ),
       
   797     iObserver( aObserver)
       
   798     {
       
   799     }
       
   800 
       
   801 CHtiTimer::~CHtiTimer()
       
   802     {
       
   803     Cancel();
       
   804     }
       
   805 
       
   806 void CHtiTimer::ConstructL()
       
   807     {
       
   808     CTimer::ConstructL();
       
   809     CActiveScheduler::Add( this );
       
   810     }
       
   811 
       
   812 void CHtiTimer::RunL()
       
   813     {
       
   814     iObserver.TimerExpiredL();
       
   815     }
       
   816 
       
   817 TInt CHtiTimer::RunError(TInt aError)
       
   818     {
       
   819     HTI_LOG_FORMAT( "CHtiTimer::RunError %d", aError );
       
   820     aError = aError;
       
   821     return KErrNone;
       
   822     }
       
   823 
       
   824 void CHtiConnectionManager::TimerExpiredL()
       
   825     {
       
   826     HTI_LOG_TEXT( "Timed out! Closing IPCommServer..." );
       
   827     ShowErrorNotifierL(
       
   828         _L( "Timed out connecting to remote host!" ), KErrTimedOut );
       
   829     iServer->CloseServer();
       
   830     }
       
   831 
       
   832 void CHtiConnectionManager::ShowErrorNotifierL( const TDesC& aText,
       
   833                                                    TInt aErr )
       
   834     {
       
   835     RNotifier notifier;
       
   836     User::LeaveIfError( notifier.Connect() );
       
   837 
       
   838     TBuf<KMaxHtiNotifierLength> errorMsg;
       
   839     // aText is cut if it's too long - leaving some space also for error code
       
   840     errorMsg.Append( aText.Left( errorMsg.MaxLength() - 10 ) );
       
   841     errorMsg.Append( _L("\n") );
       
   842     errorMsg.AppendNum( aErr );
       
   843 
       
   844     TRequestStatus status;
       
   845     TInt button;
       
   846     notifier.Notify( KHtiIPCommError, errorMsg,
       
   847                      KHtiOkButton, KNullDesC, button, status );
       
   848     User::WaitForRequest( status );
       
   849     notifier.Close();
       
   850     }
       
   851 
       
   852 
       
   853