diff -r 7259cf1302ad -r 169364e7e4b4 hti/HtiCommPlugins/HtiIPCommPlugin/src/HtiConnectionManager.cpp --- a/hti/HtiCommPlugins/HtiIPCommPlugin/src/HtiConnectionManager.cpp Tue Jul 06 16:05:13 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,853 +0,0 @@ -/* -* 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 // CCommsDatabase -#include - - -// 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 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 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 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 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 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(); - } - - -