phoneengine/loghandling/src/cpeloghandling.cpp
changeset 37 ba76fc04e6c2
child 51 f39ed5e045e0
child 76 cfea66083b62
equal deleted inserted replaced
36:2eacb6118286 37:ba76fc04e6c2
       
     1 /*
       
     2 * Copyright (c) 2003-2006 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:  This file contains the implementation of CPELogHandling class 
       
    15 *                member functions.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 //  INCLUDE FILES
       
    22 #include <spsettings.h>
       
    23 #include <spproperty.h>
       
    24 #include <telloggingextension.h>
       
    25 #include <ecom.h> 
       
    26 #include "cpeloghandling.h"
       
    27 #include "cpelogevent.h"
       
    28 #include "cpeloghandlingcommand.h"
       
    29 #include "cpelogexternaldata.h"
       
    30 #include <talogger.h>
       
    31 #include <logcli.h>
       
    32 #include <pepanic.pan>
       
    33 #include <mpephonemodelinternal.h>
       
    34 #include <mpedatastore.h>
       
    35 #include "cpeloginfo.h"
       
    36 #include "cpelogextensionwrapper.h"
       
    37 
       
    38 // EXTERNAL DATA STRUCTURES
       
    39 // None
       
    40 
       
    41 // EXTERNAL FUNCTION PROTOTYPES  
       
    42 /// None
       
    43 
       
    44 // CONSTANTS
       
    45 // None
       
    46 
       
    47 // MACROS
       
    48 // None
       
    49 
       
    50 // LOCAL CONSTANTS AND MACROS
       
    51 // None
       
    52 
       
    53 // MODULE DATA STRUCTURES
       
    54 // None
       
    55 
       
    56 // LOCAL FUNCTION PROTOTYPES
       
    57 // None
       
    58 
       
    59 // -----------------------------------------------------------------------------
       
    60 // CPELogHandling::NewL
       
    61 // Two-phased constructor.
       
    62 // -----------------------------------------------------------------------------
       
    63 //
       
    64 MPELogHandling* CPELogHandling::NewL
       
    65         ( 
       
    66         MPEPhoneModelInternal& aModel,        // Owner of the object
       
    67         RFs& aFsSession                       // Handle to a file server session
       
    68         )  
       
    69     {
       
    70     TEFLOGSTRING(KTAOBJECT, "LOG CPELogHandling::NewL start.");
       
    71     CPELogHandling* self = 
       
    72         new ( ELeave ) CPELogHandling( aModel, aFsSession );
       
    73     CleanupStack::PushL( self );
       
    74     self->ConstructL();
       
    75     CleanupStack::Pop( self );
       
    76     TEFLOGSTRING(KTAOBJECT, "LOG CPELogHandling::NewL complete.");
       
    77     return self;
       
    78     }
       
    79  
       
    80 // -----------------------------------------------------------------------------
       
    81 // CPELogHandling::~CPELogHandling
       
    82 // Destructor.
       
    83 // -----------------------------------------------------------------------------
       
    84 //
       
    85 /*****************************************************
       
    86 *    Series 60 Customer / LOGENG
       
    87 *    Series 60  LOGENG API
       
    88 *****************************************************/
       
    89 EXPORT_C CPELogHandling::~CPELogHandling()
       
    90     {
       
    91     TEFLOGSTRING( KTAOBJECT, "LOG CPELogHandling::~CPELogHandling" );
       
    92     
       
    93     delete iLogExternalData;
       
    94 
       
    95     iFreeLogEventArray.ResetAndDestroy();
       
    96     iActiveLogEventArray.ResetAndDestroy();
       
    97     // All created CPELogEvent objects must be either in Free or Active array
       
    98     // That is, it would be error to destroy objects in queued array.
       
    99     iQueuedLogEventArray.Reset();
       
   100     iActiveCallIds.Close();
       
   101 
       
   102     delete iLogHandlingCommand;
       
   103     delete iLogClient;
       
   104     iPlugins.ResetAndDestroy();
       
   105     REComSession::FinalClose();
       
   106     }
       
   107     
       
   108 // -----------------------------------------------------------------------------
       
   109 // CPELogHandling::CPELogHandling
       
   110 // C++ default constructor can NOT contain any code, that
       
   111 // might leave.
       
   112 // -----------------------------------------------------------------------------
       
   113 //
       
   114 CPELogHandling::CPELogHandling
       
   115         ( 
       
   116         MPEPhoneModelInternal& aModel,
       
   117         RFs& aFsSession        
       
   118         ) : iModel( aModel ),
       
   119             iDataStore( *( aModel.DataStore( ) ) ),
       
   120             iFsSession( aFsSession ),
       
   121             iLogEventUnderProcessing( NULL )
       
   122     {
       
   123     TEFLOGSTRING( KTAOBJECT, "LOG CPELogHandling::CPELogHandling" );
       
   124     }
       
   125 
       
   126 // -----------------------------------------------------------------------------
       
   127 // CPELogHandling::ConstructL
       
   128 // Symbian 2nd phase constructor can leave.
       
   129 // -----------------------------------------------------------------------------
       
   130 //
       
   131 /*****************************************************
       
   132 *    Series 60 Customer / LOGENG
       
   133 *    Series 60  LOGENG API
       
   134 *****************************************************/
       
   135 void CPELogHandling::ConstructL()
       
   136     {
       
   137     TEFLOGSTRING( KTAOBJECT, "LOG CPELogHandling::ConstructL" );
       
   138     // Create new instace of the Log Client
       
   139     iLogClient = CLogClient::NewL( iFsSession ); 
       
   140 
       
   141     // Enumeration for incoming call, get from database 
       
   142     User::LeaveIfError( iLogClient->GetString( iLogStringIn, R_LOG_DIR_IN ) ); 
       
   143     // Enumeration for outgoing call, get from database 
       
   144     User::LeaveIfError( iLogClient->GetString( iLogStringOut, R_LOG_DIR_OUT ) );   
       
   145     // Enumeration for missed call, get from database
       
   146     User::LeaveIfError( iLogClient->GetString( iLogStringMissed, R_LOG_DIR_MISSED ) );   
       
   147     // Enumeration for delivery call, get from database  
       
   148     User::LeaveIfError( iLogClient->GetString( iLogStringDelivery, R_LOG_DEL_NONE ) ); 
       
   149     // Enumeration for incoming auxiliary line, get from database 
       
   150     User::LeaveIfError( iLogClient->GetString( iLogStringInAlt, R_LOG_DIR_IN_ALT ) );   
       
   151     // Enumeration for outgoing auxiliary line, get from database  
       
   152     User::LeaveIfError( iLogClient->GetString( iLogStringOutAlt, R_LOG_DIR_OUT_ALT ) );
       
   153     // Enumeration for unknown name, get from database  
       
   154     User::LeaveIfError( iLogClient->GetString( iLogStringUnknown, R_LOG_REMOTE_UNKNOWN ) );
       
   155       
       
   156     iLogHandlingCommand = new (ELeave) CPELogHandlingCommand( *this, *iLogClient );
       
   157  
       
   158     // Reserve some log events here. We delete these log event objects only on the destructor.
       
   159     for( TInt entryIndex = 0; entryIndex < KPEMaximumNumberOfLogEvents; entryIndex++ )
       
   160         {
       
   161         CPELogEvent* logEvent = CPELogEvent::NewL( *this, *iLogHandlingCommand );
       
   162         CleanupStack::PushL( logEvent );
       
   163         iFreeLogEventArray.AppendL( logEvent );
       
   164         CleanupStack::Pop( logEvent );
       
   165         }
       
   166     // Compress free log event array as it would never contain more objects than create here
       
   167     iFreeLogEventArray.Compress( );
       
   168 
       
   169     iLogExternalData = CPELogExternalData::NewL( *this );
       
   170     }
       
   171 
       
   172 // -----------------------------------------------------------------------------
       
   173 // CPELogHandling::SaveCallEntry
       
   174 // Creates log info and initiates saving call log info by calling SaveCallInfoL.
       
   175 // Do log handling cleanup in case of a leave.
       
   176 // (other items were commented in a header).
       
   177 // -----------------------------------------------------------------------------
       
   178 //
       
   179 EXPORT_C TInt CPELogHandling::SaveCallEntry
       
   180         ( 
       
   181         const TInt aCallId
       
   182         )
       
   183     {
       
   184     TInt errorCode( KErrArgument );
       
   185     if ( CallIdCheck::IsVoice( aCallId ) || 
       
   186          CallIdCheck::IsVideo( aCallId )
       
   187        ) 
       
   188         {
       
   189         CPELogInfo* logInfo( NULL );
       
   190         TRAP( errorCode, logInfo = CPELogInfo::NewL(); );
       
   191             
       
   192         if ( logInfo )
       
   193             {
       
   194             // continue gathering log data
       
   195             
       
   196             // set phonenumber and/or voip address
       
   197             SetRemoteContact( aCallId, *logInfo );
       
   198             logInfo->SetEventData( aCallId, iDataStore ); 
       
   199             TRAP_IGNORE( 
       
   200                 // Contact link can be big, not critical for basic functionality.
       
   201                 if ( &iDataStore.ContactId( aCallId ) )
       
   202                     {
       
   203                     // Pack and add link
       
   204                     HBufC8* buf( iDataStore.ContactId( aCallId ).PackLC() );
       
   205                     TEFLOGSTRING( KTAINT, "Contact id packed" );
       
   206                     logInfo->SetContactLink( buf ); 
       
   207                     CleanupStack::Pop( buf );
       
   208                     }
       
   209                 // default logging strategy is used if error happens while using extension
       
   210                 UpdateLogInfoWithExtensionDataL( aCallId, *logInfo ) );
       
   211             
       
   212             TRAP( errorCode, SaveCallInfoL( *logInfo ) );
       
   213             delete logInfo;
       
   214             }
       
   215         
       
   216         if( errorCode != KErrNone )
       
   217             {
       
   218             DoCleanup();
       
   219             }
       
   220         }
       
   221     return errorCode;
       
   222     }
       
   223 
       
   224 // -----------------------------------------------------------------------------
       
   225 // CPELogHandling::SendMessage
       
   226 // Method reroutes messages from other modules to the CPEPho-object
       
   227 // Note that it does not use base class SendMessage.
       
   228 // -----------------------------------------------------------------------------
       
   229 //
       
   230 void CPELogHandling::SendMessage
       
   231         ( 
       
   232         const MEngineMonitor::TPEMessagesFromPhoneEngine aMessage, // The message id number of the message.
       
   233         TInt aErrorCode
       
   234         )
       
   235     {
       
   236     if ( aMessage == MEngineMonitor::EPEMessageLogEventSaved )
       
   237         {
       
   238         TEFLOGSTRING( KTAINT, "LOG CPELogHandling::SendMessage(), Log event saved" );                        
       
   239         
       
   240         if (aErrorCode == KErrNone )
       
   241             {
       
   242             // flag event entry as added; next event is to be just entry update.
       
   243             iLogEventUnderProcessing->SetAdded( );
       
   244             }
       
   245         
       
   246         if ( iLogEventUnderProcessing->IsCompleted( ) )
       
   247             {
       
   248             TEFLOGSTRING( KTAINT, "LOG CPELogHandling::SendMessage(), Log entry completed" );                       
       
   249                        
       
   250             DeleteArrayEntry( iLogEventUnderProcessing );
       
   251             }
       
   252 
       
   253         // Indicate that no processing of log event is in progress
       
   254         iLogEventUnderProcessing = NULL;            
       
   255             
       
   256         if ( iQueuedLogEventArray.Count( ) > 0 )
       
   257             {
       
   258             TEFLOGSTRING( KTAINT, "LOG CPELogHandling::SendMessage(), Executing queued request" );
       
   259             
       
   260             CPELogEvent* logEvent = iQueuedLogEventArray[0];
       
   261             iQueuedLogEventArray.Remove( 0 );
       
   262             iLogEventUnderProcessing = logEvent;
       
   263             TRAPD( error, logEvent->SaveL( ) );
       
   264             if ( error != KErrNone )
       
   265                 {
       
   266                 DoCleanup();
       
   267                 }
       
   268             }
       
   269         }
       
   270     else
       
   271         {
       
   272         TEFLOGSTRING2( KTAINT, "LOG CPELogHandling::SendMessage(), Message %d not supported", aMessage );
       
   273         }   
       
   274     }
       
   275         
       
   276 // -----------------------------------------------------------------------------
       
   277 // CPELogHandling::LogStringIn
       
   278 // Get log string.
       
   279 // (other items were commented in a header).
       
   280 // -----------------------------------------------------------------------------
       
   281 //
       
   282 TLogString& CPELogHandling::LogStringIn
       
   283         (
       
   284         // None
       
   285         )
       
   286     {
       
   287     return iLogStringIn;
       
   288     }
       
   289 
       
   290 // -----------------------------------------------------------------------------
       
   291 // CPELogHandling::LogStringOut
       
   292 // Get log string.
       
   293 // (other items were commented in a header).
       
   294 // -----------------------------------------------------------------------------
       
   295 //
       
   296 TLogString& CPELogHandling::LogStringOut
       
   297         (
       
   298         // None
       
   299         )
       
   300     {
       
   301     return iLogStringOut;
       
   302     }
       
   303     
       
   304 // -----------------------------------------------------------------------------
       
   305 // CPELogHandling::LogStringMissed
       
   306 // Get log string.
       
   307 // (other items were commented in a header).
       
   308 // -----------------------------------------------------------------------------
       
   309 //
       
   310 TLogString& CPELogHandling::LogStringMissed
       
   311         (
       
   312         // None
       
   313         )
       
   314     {
       
   315     return iLogStringMissed;
       
   316     }
       
   317     
       
   318 // -----------------------------------------------------------------------------
       
   319 // CPELogHandling::LogStringIn
       
   320 // Get log string.
       
   321 // (other items were commented in a header).
       
   322 // -----------------------------------------------------------------------------
       
   323 //
       
   324 TLogString& CPELogHandling::LogStringDelivery
       
   325         (
       
   326         // None
       
   327         )
       
   328     {
       
   329     return iLogStringDelivery;
       
   330     }        
       
   331 
       
   332 // -----------------------------------------------------------------------------
       
   333 // CPELogHandling::LogStringIn
       
   334 // Get log string.
       
   335 // (other items were commented in a header).
       
   336 // -----------------------------------------------------------------------------
       
   337 //
       
   338 TLogString& CPELogHandling::LogStringInAlt
       
   339         (
       
   340         // None
       
   341         )
       
   342     {
       
   343     return iLogStringInAlt;
       
   344     }
       
   345 
       
   346 // -----------------------------------------------------------------------------
       
   347 // CPELogHandling::LogStringOutAlt
       
   348 // Get log string.
       
   349 // (other items were commented in a header).
       
   350 // -----------------------------------------------------------------------------
       
   351 //
       
   352 TLogString& CPELogHandling::LogStringOutAlt
       
   353         (
       
   354         // None
       
   355         )
       
   356     {
       
   357     return iLogStringOutAlt;
       
   358     }
       
   359 
       
   360 // -----------------------------------------------------------------------------
       
   361 // CPELogHandling::LogStringUnknown
       
   362 // Get log string.
       
   363 // (other items were commented in a header).
       
   364 // -----------------------------------------------------------------------------
       
   365 //
       
   366 TLogString& CPELogHandling::LogStringUnknown
       
   367         (
       
   368         // None
       
   369         )
       
   370     {
       
   371     return iLogStringUnknown;
       
   372     }
       
   373 
       
   374 // -----------------------------------------------------------------------------
       
   375 // CPELogHandling::SetRemoteContact
       
   376 // -----------------------------------------------------------------------------
       
   377 //
       
   378 void CPELogHandling::SetRemoteContact( TInt aCallId, CPELogInfo& aLogInfo )
       
   379     {
       
   380     aLogInfo.SetVoipAddress( KNullDesC() );
       
   381     
       
   382     if ( iDataStore.CallDirection( aCallId ) 
       
   383             == RMobileCall::EMobileOriginated )
       
   384         {
       
   385         TEFLOGSTRING2(KTAINT, 
       
   386             "LOG CPELogHandling::CreateLogInfo, WholeOutgoingPhoneNumber, aCallId: %d"
       
   387             , aCallId )
       
   388         aLogInfo.SetPhoneNumber( iDataStore.WholeOutgoingPhoneNumber( aCallId ) );
       
   389         }
       
   390     else
       
   391         {
       
   392         aLogInfo.SetPhoneNumber( iDataStore.RemotePhoneNumber( aCallId ) );
       
   393         }
       
   394     
       
   395     if ( EPECallTypeVoIP == iDataStore.CallType( aCallId ) )
       
   396         {
       
   397         // voip address field must be used for voip calls
       
   398         aLogInfo.SetVoipAddress( aLogInfo.PhoneNumber() );
       
   399         aLogInfo.SetPhoneNumber( KNullDesC() );
       
   400         }
       
   401     }
       
   402 
       
   403 
       
   404 // -----------------------------------------------------------------------------
       
   405 // CPELogHandling::SaveCallInfoL
       
   406 // Update log external data.
       
   407 // Call SaveEventL if event should be saved to log db.
       
   408 // (other items were commented in a header).
       
   409 // -----------------------------------------------------------------------------
       
   410 //
       
   411 void CPELogHandling::SaveCallInfoL
       
   412         ( 
       
   413         const CPELogInfo& aLogInfo // Call information
       
   414         )
       
   415     {
       
   416     TEFLOGSTRING3( KTAINT, "LOG CPELogHandling::SaveCallInfoL(), [CallID: %d], [CallState: %d]", aLogInfo.CallId(), aLogInfo.CallState() );
       
   417     
       
   418     if ( EPEStateConnected == aLogInfo.CallState() )
       
   419         {
       
   420         // Insert the call ID to the active call array when the call state is connected.
       
   421         TInt err = iActiveCallIds.InsertInOrder( aLogInfo.CallId() );
       
   422         if ( err != KErrAlreadyExists )
       
   423             {
       
   424             User::LeaveIfError( err );
       
   425             }
       
   426         
       
   427         // Only for the first call set the first call start time
       
   428         if ( iActiveCallIds.Count() == 1 )
       
   429             {
       
   430             // For Last active call timer. See end part of UpdateLastCallTimer.
       
   431             iLogExternalData->SetFirstCallStartTime( aLogInfo.CallStartTime() );
       
   432             }
       
   433   
       
   434         // We have already store the start time to log database on dialling/ringing state,
       
   435         // but this is the real start time of call.
       
   436         TBuf<KPEESDWFormattedTimeLength> formattedTime;
       
   437         formattedTime.Zero();
       
   438         aLogInfo.CallStartTime().FormatL( formattedTime, KPEESDWTimeFormat ); 
       
   439         TEFLOGSTRING2( KTAINT, "LOG CPELogHandling::SaveCallInfoL() Connected state iCallStartTime > formattedTime: %S", &formattedTime );
       
   440         }
       
   441     else
       
   442         {
       
   443         // logsEntry handling only on Dialling/Ringing and Idle states.
       
   444         if ( EPEStateIdle == aLogInfo.CallState() )
       
   445             {          
       
   446             iLogExternalData->UpdateCallTimers( aLogInfo );
       
   447             if ( aLogInfo.MissedCall() )  
       
   448                 {
       
   449                 iLogExternalData->IncreaseMissedCallValue( aLogInfo.CallId() );
       
   450                 }
       
   451 
       
   452             TInt index = iActiveCallIds.FindInOrder( aLogInfo.CallId() );
       
   453             if ( index >= 0 )
       
   454                 {
       
   455                 // When a call is disconnected, its ID is removed from the active call array.
       
   456                 iActiveCallIds.Remove( index );
       
   457                 iLogExternalData->UpdateLastCallTimerByLine( aLogInfo );
       
   458                 if ( iActiveCallIds.Count() == 0 )
       
   459                     {
       
   460                     TInt duration = iLogExternalData->UpdateLastCallTimer( aLogInfo );
       
   461                     iModel.DataStore()->SetCallDuration( duration );
       
   462                     }
       
   463                 }
       
   464             }
       
   465         if ( aLogInfo.LoggingEnabled() ) 
       
   466             {
       
   467             // We log all voice calls and the following data/fax calls to Log database
       
   468             // MO external Data calls,
       
   469             // MO external Fax calls,
       
   470             // MT external Data calls
       
   471             // MT external Fax calls,
       
   472             // MT internal Data calls,
       
   473             // We don't log the following data/fax calls to Log database
       
   474             // MO internal Data calls
       
   475             // MO internal Fax calls,
       
   476             // MT internal Fax calls, 
       
   477             // these are logged by CSD agent.
       
   478             // But we have to update timers for these calls.            
       
   479             
       
   480             SaveEventL( aLogInfo );
       
   481             }
       
   482         }
       
   483     }
       
   484 
       
   485 
       
   486 // -----------------------------------------------------------------------------
       
   487 // CPELogHandling::SaveEventL
       
   488 // Update log database entry for an event. Manages event queueing.
       
   489 // (other items were commented in a header).
       
   490 // -----------------------------------------------------------------------------
       
   491 //
       
   492 void CPELogHandling::SaveEventL
       
   493         ( 
       
   494         const CPELogInfo& aLogInfo  // Log information
       
   495         ) 
       
   496     {
       
   497     TInt index;
       
   498     CPELogEvent* logEvent;
       
   499     
       
   500     
       
   501     index = FindEventIndexById( aLogInfo.CallId() ); 
       
   502     if ( index == KErrNotFound ) 
       
   503         {
       
   504         // a log event object can't be reused;  
       
   505         TEFLOGSTRING2( KTAINT, "LOG CPELogHandling::SaveEventL(), [CallID: %d]",aLogInfo.CallId() );
       
   506         TEFLOGSTRING2( KTAINT, "LOG CPELogHandling::SaveEventL(), [CallDirection: %d]", aLogInfo.CallDirection() );
       
   507 
       
   508         if ( iFreeLogEventArray.Count() > 0 )
       
   509             {
       
   510             // reuse an already created object from the array of the freed log event objects
       
   511             logEvent = iFreeLogEventArray[ 0 ];
       
   512             iFreeLogEventArray.Remove( 0 );
       
   513             }
       
   514         else 
       
   515             {
       
   516             // create a new object; none available to be reused
       
   517             logEvent = CPELogEvent::NewL( *this, *iLogHandlingCommand );
       
   518             }
       
   519             
       
   520         CleanupStack::PushL( logEvent );
       
   521         iActiveLogEventArray.AppendL( logEvent );
       
   522         CleanupStack::Pop( logEvent );            
       
   523         }
       
   524     else
       
   525         {
       
   526         // the log event object is already active but not completed. reuse it.
       
   527         logEvent = iActiveLogEventArray[ index ];
       
   528         }
       
   529         
       
   530     __ASSERT_ALWAYS( logEvent, Panic(EPEPanicNullPointer) );
       
   531         
       
   532 
       
   533     // Save logInfo for possible queueing.
       
   534     logEvent->UpdateLogInfoL( aLogInfo );
       
   535        
       
   536     if ( iLogEventUnderProcessing )
       
   537         {
       
   538         // queueing can not be done per event because log client
       
   539         // would fail if new request is sent before the previous one
       
   540         // has been processed even if they are for two different events.
       
   541         // See Symbian doc for more details.
       
   542         if ( iQueuedLogEventArray.Find( logEvent ) == KErrNotFound )  
       
   543             {
       
   544             TEFLOGSTRING( KTAINT, "LOG CPELogHandling::SaveEventL(), AO busy, request queued" );                
       
   545             // queue the updated event only if event is not already queued
       
   546             TInt error = iQueuedLogEventArray.Append( logEvent );
       
   547             if ( error != KErrNone )
       
   548                 {
       
   549                 TEFLOGSTRING( KTAERROR, "LOG CPELogHandling::SaveEventL(), Append to QueuedArray failed!" );
       
   550                 TEFLOGSTRING( KTAERROR, "LOG CPELogHandling::SaveEventL(), WARNING: Array Entry will be deleted to prevent memory leak." );
       
   551                        
       
   552                 DeleteArrayEntry( logEvent );
       
   553                 
       
   554                 User::LeaveIfError( error );
       
   555                 }
       
   556             }
       
   557         else // the existing queued request will be executed with updated info
       
   558             {
       
   559             TEFLOGSTRING( KTAINT, "LOG CPELogHandling::SaveEvent(), AO busy, queued request already exists" );
       
   560             }
       
   561         }   
       
   562     else
       
   563         {
       
   564         iLogEventUnderProcessing = logEvent;
       
   565         logEvent->SaveL( );            
       
   566         }
       
   567     }
       
   568     
       
   569 // -----------------------------------------------------------------------------
       
   570 // CPELogsHandling::FindEventIndexById
       
   571 // Find index number from array with given callid.
       
   572 // -----------------------------------------------------------------------------
       
   573 //
       
   574 TInt CPELogHandling::FindEventIndexById
       
   575         ( 
       
   576         const TInt aCallId // Call identification number
       
   577         )
       
   578     {
       
   579     TEFLOGSTRING( KTAINT, 
       
   580         "Log Handling: CPELogHandling::FindEventIndexById() - 1" );
       
   581     for( TInt index = 0; index < iActiveLogEventArray.Count(); index++ )
       
   582         { 
       
   583         TEFLOGSTRING( KTAINT, 
       
   584             "Log Handling: CPELogHandling::FindEventIndexById() - 2" );        
       
   585         if( (iActiveLogEventArray[ index ]->CallId() == aCallId) &&
       
   586             !(iActiveLogEventArray[ index ]->IsCompleted()) )
       
   587             {
       
   588             TEFLOGSTRING( KTAINT, 
       
   589                 "LOG CPELogHandling::FindEventIndexById() - 3" );
       
   590             return index;
       
   591             }
       
   592         }
       
   593     TEFLOGSTRING( KTAINT, 
       
   594         "LOG CPELogHandling::FindEventIndexById() - 4" );
       
   595     return KErrNotFound;
       
   596     }
       
   597 
       
   598 // -----------------------------------------------------------------------------
       
   599 // CPELogsHandling::DeleteArrayEntry
       
   600 // Delete array's enty by given callid.
       
   601 // -----------------------------------------------------------------------------
       
   602 //
       
   603 void CPELogHandling::DeleteArrayEntry
       
   604         ( 
       
   605         CPELogEvent* aLogEvent
       
   606         )
       
   607     {
       
   608     TInt index = iActiveLogEventArray.Find( aLogEvent );
       
   609     TInt queuedIndex = iQueuedLogEventArray.Find( aLogEvent );
       
   610     TInt freeIndex = iFreeLogEventArray.Find( aLogEvent );
       
   611     
       
   612     // Reset event before deletion
       
   613     aLogEvent->ResetEvent( );
       
   614     aLogEvent->ResetLogInfo();
       
   615     
       
   616     // Remove event from queued array as it is there by error and should not be processed after deletion
       
   617     if ( queuedIndex != KErrNotFound )
       
   618         {
       
   619         TEFLOGSTRING( KTAERROR, "LOG CPELogHandling::DeleteArrayEntry: WARNING Log event removed from queued event array. This should not happen." )
       
   620         iQueuedLogEventArray.Remove( queuedIndex );
       
   621         }
       
   622     
       
   623     if ( index != KErrNotFound )
       
   624         {
       
   625         iActiveLogEventArray.Remove( index );
       
   626         }
       
   627     else
       
   628         {
       
   629         TEFLOGSTRING( KTAERROR, "LOG CPELogHandling::DeleteArrayEntry: WARNING Log event NOT in active event array. This should not happen." )
       
   630         }
       
   631         
       
   632     if ( freeIndex == KErrNotFound )
       
   633         {   
       
   634         if ( iFreeLogEventArray.Count( ) < KPEMaximumNumberOfLogEvents )
       
   635             {
       
   636             if (iFreeLogEventArray.Append( aLogEvent ) != KErrNone)
       
   637                 {
       
   638                 // prevent memory leak
       
   639                 delete aLogEvent;
       
   640                 }
       
   641             }
       
   642         else
       
   643             {
       
   644             // prevent memory leak
       
   645             delete aLogEvent;
       
   646             }
       
   647         }
       
   648     }
       
   649 
       
   650 // -----------------------------------------------------------------------------
       
   651 // CPELogsHandling::DoCleanup
       
   652 // Do log handling cleanup in case of leave during handling of a log event.
       
   653 // -----------------------------------------------------------------------------
       
   654 //
       
   655 void CPELogHandling::DoCleanup()
       
   656     {
       
   657     if ( iLogEventUnderProcessing ) 
       
   658         {
       
   659         // delete log event entry only if save leaves and event is completed
       
   660         // otherwise we expect more log events for the same entry that is no need to delete
       
   661         if ( iLogEventUnderProcessing->SaveLeave( ) && 
       
   662              iLogEventUnderProcessing->IsCompleted( ) )
       
   663             {
       
   664             TEFLOGSTRING( KTAERROR, 
       
   665                 "LOG CPELogHandling::DoCleanup(), WARNING: Array Entry will be deleted to prevent memory leak." );
       
   666             
       
   667             DeleteArrayEntry( iLogEventUnderProcessing );
       
   668             }
       
   669         }
       
   670     }
       
   671 
       
   672 
       
   673 // -----------------------------------------------------------------------------
       
   674 // CPELogsHandling::ResetMissedCalls()
       
   675 // Reset missed call.
       
   676 // -----------------------------------------------------------------------------
       
   677 //
       
   678 void CPELogHandling::ResetMissedCalls( TInt aCallId )
       
   679     {
       
   680     TEFLOGSTRING( KTAINT, 
       
   681         "LOG CPELogsHandling::ResetMissedCalls > SetMissedCall" );
       
   682     
       
   683     TEFLOGSTRING2(KTAINT, 
       
   684             "LOG CPELogHandling::ResetMissedCalls, aCallId: %d"
       
   685             , iDataStore.CallId() );
       
   686     iDataStore.SetMissedCall( EFalse, aCallId );
       
   687     }
       
   688 
       
   689 
       
   690 // -----------------------------------------------------------------------------
       
   691 // CPELogHandling::UpdateLogInfoWithExtensionDataL
       
   692 // Log information is not changed if some error happens with extension usage. 
       
   693 // -----------------------------------------------------------------------------
       
   694 //
       
   695 void CPELogHandling::UpdateLogInfoWithExtensionDataL( TInt aCallId, 
       
   696         CPELogInfo& aLogInfo )
       
   697     {
       
   698     TUint serviceId( iDataStore.ServiceId( aCallId ) );
       
   699     CTelLoggingExtension& extension = LoggingExtensionL( serviceId );
       
   700     
       
   701     // initialize extension with original remote contact number/address
       
   702     const TPEPhoneNumber* origRemoteContact = NULL;
       
   703     RMobileCall::EMobileOriginated == iDataStore.CallDirection( aCallId )
       
   704         ? origRemoteContact = &iDataStore.WholeOutgoingPhoneNumber( aCallId )
       
   705         : origRemoteContact = &iDataStore.RemotePhoneNumber( aCallId );
       
   706     __ASSERT_ALWAYS( NULL != origRemoteContact, User::Leave( KErrNotFound ) );
       
   707     extension.InitializeL( serviceId, *origRemoteContact );
       
   708     
       
   709     RBuf phoneNumber;
       
   710     CleanupClosePushL( phoneNumber );
       
   711     User::LeaveIfError( extension.GetPhoneNumber( phoneNumber ) );
       
   712     
       
   713     RBuf voipAddress;
       
   714     CleanupClosePushL( voipAddress );
       
   715     User::LeaveIfError( extension.GetVoipAddress( voipAddress ) );
       
   716     
       
   717     RBuf myAddress;
       
   718     CleanupClosePushL( myAddress );
       
   719     User::LeaveIfError( extension.GetMyAddress( myAddress ) );
       
   720     
       
   721     RBuf remotePartyName;
       
   722     CleanupClosePushL( remotePartyName );
       
   723     User::LeaveIfError( extension.GetRemotePartyName( remotePartyName ) );
       
   724     
       
   725     // update log info with successfully queried extension data
       
   726     SetExtensionData( aLogInfo, phoneNumber, voipAddress, 
       
   727         myAddress, remotePartyName );
       
   728     
       
   729     CleanupStack::PopAndDestroy( 4, &phoneNumber );
       
   730     }
       
   731 
       
   732 
       
   733 // -----------------------------------------------------------------------------
       
   734 // CPELogHandling::LoggingExtensionL
       
   735 // -----------------------------------------------------------------------------
       
   736 //
       
   737 CTelLoggingExtension& CPELogHandling::LoggingExtensionL( TUint aServiceId )
       
   738     {
       
   739     TUid pluginUid = LoggingPluginIdentifierL( aServiceId );
       
   740     
       
   741     CPELogExtensionWrapper* wrapper = NULL;
       
   742     TInt pluginInd = 
       
   743         iPlugins.Find( pluginUid, CPELogExtensionWrapper::MatchByUid );
       
   744     if ( KErrNotFound == pluginInd )
       
   745         {
       
   746         wrapper = CreateExtensionWrapperLC( pluginUid );
       
   747         iPlugins.AppendL( wrapper );
       
   748         CleanupStack::Pop( wrapper );
       
   749         }
       
   750     else
       
   751         {
       
   752         wrapper = iPlugins[pluginInd];
       
   753         }
       
   754     
       
   755     __ASSERT_ALWAYS( NULL != wrapper, User::Leave( KErrNotFound ) );
       
   756     return *wrapper;
       
   757     }
       
   758 
       
   759 
       
   760 // -----------------------------------------------------------------------------
       
   761 // CPELogHandling::LoggingPluginIdentifierL
       
   762 // Resolves plugin identifier for the given service.
       
   763 // -----------------------------------------------------------------------------
       
   764 //
       
   765 TUid CPELogHandling::LoggingPluginIdentifierL( TUint aServiceId ) const
       
   766     {
       
   767     TInt pluginUid( 0 );
       
   768     CSPSettings* settings = CSPSettings::NewLC();
       
   769     CSPProperty* property = CSPProperty::NewLC();
       
   770     
       
   771     TInt result = settings->FindPropertyL( aServiceId, 
       
   772         EPropertyCallLoggingPluginId, *property );
       
   773     User::LeaveIfError( result );
       
   774     User::LeaveIfError( property->GetValue( pluginUid ) );
       
   775     CleanupStack::PopAndDestroy( property );
       
   776     CleanupStack::PopAndDestroy( settings );
       
   777     
       
   778     return TUid::Uid( pluginUid );
       
   779     }
       
   780 
       
   781 
       
   782 // -----------------------------------------------------------------------------
       
   783 // CPELogHandling::SetExtensionData
       
   784 // Lengths of the descriptors gotten from plugin must be checked, because
       
   785 // extension API does not set limits for data length. In case that phone number
       
   786 // is available, voip address is not saved to logs. That enables user to select
       
   787 // call type s/he wants when calling from logs.
       
   788 // -----------------------------------------------------------------------------
       
   789 //
       
   790 void CPELogHandling::SetExtensionData( CPELogInfo& aLogInfo, 
       
   791         const TDesC& aPhoneNumber, const TDesC& aVoipAddress, 
       
   792         const TDesC& aMyAddress, const TDesC& aRemotePartyName )
       
   793     {
       
   794     if ( aPhoneNumber.Length() <= aLogInfo.PhoneNumber().MaxLength() )
       
   795         {
       
   796         aLogInfo.SetPhoneNumber( aPhoneNumber );
       
   797         aLogInfo.SetVoipAddress( KNullDesC() );
       
   798         }
       
   799     
       
   800     if ( aVoipAddress.Length() <= aLogInfo.VoipAddress().MaxLength() )
       
   801         {
       
   802         if ( KNullDesC() == aLogInfo.PhoneNumber() )
       
   803             {
       
   804             aLogInfo.SetVoipAddress( aVoipAddress );
       
   805             }
       
   806         }
       
   807     
       
   808     if ( aMyAddress.Length() <= aLogInfo.MyAddress().MaxLength() )
       
   809         {
       
   810         aLogInfo.SetMyAddress( aMyAddress );
       
   811         }
       
   812     
       
   813     // Try to use user defined contact name from contacts, remote party name
       
   814     // from extension or voip address from extension as a contact name to be
       
   815     // saved in logs, in that order.
       
   816     TBool noContactMatch = ( KNullDesC() == aLogInfo.Name() ); 
       
   817     if ( noContactMatch )
       
   818         {
       
   819         if ( aRemotePartyName.Length() != 0 )
       
   820             {
       
   821             aLogInfo.SetName( aRemotePartyName.Left( aLogInfo.Name().MaxSize() ) );
       
   822             }
       
   823         else if ( KNullDesC() != aLogInfo.VoipAddress() )
       
   824             {
       
   825             aLogInfo.SetName( aLogInfo.VoipAddress() );
       
   826             }
       
   827         else
       
   828             {
       
   829             aLogInfo.SetName( aLogInfo.PhoneNumber() );
       
   830             }
       
   831         }
       
   832     }
       
   833 
       
   834 // -----------------------------------------------------------------------------
       
   835 // CPELogHandling::CreateExtensionWrapperLC
       
   836 // -----------------------------------------------------------------------------
       
   837 //
       
   838 CPELogExtensionWrapper* CPELogHandling::CreateExtensionWrapperLC( 
       
   839         const TUid& aPluginUid ) const
       
   840     {
       
   841     return CPELogExtensionWrapper::NewLC( aPluginUid );
       
   842     }
       
   843 
       
   844 // End of File