phoneengine/loghandling/src/cpelogevent.cpp
changeset 0 5f000ab63145
child 9 8871b09be73b
child 21 92ab7f8d0eab
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phoneengine/loghandling/src/cpelogevent.cpp	Mon Jan 18 20:18:27 2010 +0200
@@ -0,0 +1,693 @@
+/*
+* Copyright (c) 2002-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:  This module contains the implementation of CPELogEvent class
+*
+*/
+
+
+//  INCLUDE FILES
+#include "cpelogevent.h"
+#include "cpeloginfo.h"
+#include "cpeloghandling.h"
+#include "cpeloghandlingcommand.h"
+#include <PbkFields.hrh>
+#include <talogger.h>
+#include <logcli.h>
+#include <LogsApiConsts.h>
+
+
+// EXTERNAL DATA STRUCTURES
+//None
+
+// EXTERNAL FUNCTION PROTOTYPES  
+//None
+
+// CONSTANTS
+const TInt KPhonebookTypeIdLength = 11;
+
+// Defined in \s60\app\contacts\logsui\EngineIncLogsEngConsts.h as KLogEventALS
+const TLogFlags KPELogEventALS = 0x4;
+
+const TInt KOneChar = 1;
+
+// MACROS
+//None
+
+// LOCAL CONSTANTS AND MACROS
+//None
+
+// MODULE DATA STRUCTURES
+//None
+
+// LOCAL FUNCTION PROTOTYPES
+//None
+
+// FORWARD DECLARATIONS
+//None
+
+
+// ==================== LOCAL FUNCTIONS =====================================
+
+// -----------------------------------------------------------------------------
+// CPELogEvent::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CPELogEvent* CPELogEvent::NewL
+        ( 
+        CPELogHandling& aOwner,  // Owner of the object
+        CPELogHandlingCommand& aLogHandlingCommand
+        )
+    {
+    TEFLOGSTRING(KTAOBJECT, "LOG CPELogEvent::NewL start.");
+    CPELogEvent* self = new ( ELeave ) CPELogEvent( aOwner, aLogHandlingCommand );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    TEFLOGSTRING(KTAOBJECT, "LOG CPELogEvent::NewL complete.");
+    return self;
+    }
+  
+// Destructor
+/*****************************************************
+*    Series 60 Customer / LOGENG
+*    Series 60  LOGENG API
+*****************************************************/
+CPELogEvent::~CPELogEvent
+        (
+        // None
+        )
+    {
+    TEFLOGSTRING( KTAOBJECT, "LOG CPELogEvent::~CPELogEvent()" );
+    delete iEvent;
+    delete iLogInfo;
+    }
+
+
+// ================= MEMBER FUNCTIONS =======================================
+// -----------------------------------------------------------------------------
+// CPELogEvent::CPELogEvent
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CPELogEvent::CPELogEvent
+        ( 
+        CPELogHandling& aOwner,
+        CPELogHandlingCommand& aLogHandlingCommand
+        ) : iOwner( aOwner ),
+            iLogHandlingCommand( aLogHandlingCommand ),
+            iCompleted( EFalse ),
+            iAdded( EFalse ),
+            iSaveLeave( EFalse )
+    {
+    }
+// -----------------------------------------------------------------------------
+// CPELogEvent::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+/*****************************************************
+*    Series 60 Customer / LOGENG
+*    Series 60  LOGENG API
+*****************************************************/
+void CPELogEvent::ConstructL
+        (
+        // None
+        )
+    {
+    iEvent = CLogEvent::NewL();
+    ResetEvent( );
+    iLogInfo = CPELogInfo::NewL();
+    }
+    
+// -----------------------------------------------------------------------------
+// CPELogEvent::Save
+// Saves the event to the log.
+// -----------------------------------------------------------------------------
+//
+void CPELogEvent::SaveL()
+    {
+    iSaveLeave = ETrue;
+    // iCopleted flag must be set before the function leave as it is used 
+    // in log subsytem recovery procedure in case of leave.
+    if ( EPEStateIdle == iLogInfo->CallState() || iLogInfo->ForcedCompletion() )
+        {
+        iCompleted = ETrue;
+        }
+        
+    if ( !iAdded )
+        {
+        TEFLOGSTRING2( KTAINT, "LOG CPELogEvent::SaveL() > CPELogHandlingCommand::AddEvent(), callId=%d", iLogInfo->CallId() );  
+        SetPhoneNumberId();
+        SetEventTypeL();
+        SetLogEvent();
+        SetDuration();
+        SetServiceIdL();
+        
+        if ( &iLogInfo->ContactLink() )
+            {
+            SetContactLinkL();
+            }
+        // event under processing will always be of index 0 in the queued array
+        User::LeaveIfError( iLogHandlingCommand.AddEvent( *iEvent ) );
+        }
+    else
+        { 
+        TEFLOGSTRING2( KTAINT, "LOG CPELogEvent::SaveL() > CPELogHandlingCommand::ChangeEvent(), callId=%d", iLogInfo->CallId() );            
+        SetLogEvent();
+        SetDuration();
+        User::LeaveIfError( iLogHandlingCommand.ChangeEvent( *iEvent ) );
+        }
+    // indicates no leave happened in Save function
+    iSaveLeave = EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CPELogEvent::UpdateLogInfo
+// Update log database entry.
+// -----------------------------------------------------------------------------
+//
+void CPELogEvent::UpdateLogInfoL
+        ( 
+        const CPELogInfo& aLogInfo // Call information
+        ) 
+    {
+    // CPELogHandling generic loginfo must be replicated to this event
+    iLogInfo->CopyL( aLogInfo );
+    }
+
+// -----------------------------------------------------------------------------
+// CPELogEvent::ResetLogInfo
+// Reset log info.
+// -----------------------------------------------------------------------------
+//
+void CPELogEvent::ResetLogInfo() 
+    {
+    TEFLOGSTRING( KTAINT, "LOG CPELogEvent::ResetLogInfo: start" );  
+    iLogInfo->Reset();
+    TEFLOGSTRING( KTAINT, "LOG CPELogEvent::ResetLogInfo: complete" ); 
+    }
+    
+// -----------------------------------------------------------------------------
+// CPELogEvent::ResetEvent
+// Reset event on the idle state.
+// -----------------------------------------------------------------------------
+//
+/*****************************************************
+*    Series 60 Customer / LOGENG
+*    Series 60  LOGENG API
+*****************************************************/
+void CPELogEvent::ResetEvent()
+    {
+    iAdded = EFalse;
+    iCompleted = EFalse;
+    iSaveLeave = EFalse;
+
+    // CLogEvent -variables
+    iEvent->SetId( KLogNullId );
+    iEvent->SetEventType( KNullUid );
+    iEvent->SetRemoteParty( KNullDesC );
+    iEvent->SetDirection( KNullDesC );
+    iEvent->SetTime( Time::NullTTime() );
+    iEvent->SetDurationType( KLogNullDurationType );
+    iEvent->SetDuration( KLogNullDuration );
+    iEvent->SetStatus( KNullDesC );
+    iEvent->SetSubject( KNullDesC );
+    iEvent->SetNumber( KNullDesC );
+    iEvent->SetContact( KNullContactId );
+    iEvent->SetLink( KLogNullLink );
+    iEvent->SetDescription( KNullDesC );
+    iEvent->ClearFlags( KLogFlagsMask );
+    TRAPD( error, iEvent->SetDataL( KNullDesC8 ) );
+    if ( error != KErrNone )
+        {
+        // SetDataL leave should not cause log subsystem to fail. Just log the error.
+        TEFLOGSTRING2( KTAERROR, "LOG CPELogEvent::Save()>CPELogHandlingCommand::ResetEvent(), error=%d", error );  
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPELogEvent::CallId
+// Get call id of the event.
+// -----------------------------------------------------------------------------
+//
+TInt CPELogEvent::CallId
+        (
+        // None
+        )
+    {
+    return iLogInfo->CallId();
+    }
+
+// -----------------------------------------------------------------------------
+// CPELogEvent::IsCompleted
+// Returns flag if the entry has been completed, ie. no further updates are expected
+// -----------------------------------------------------------------------------
+//
+TBool CPELogEvent::IsCompleted
+        (
+        // None
+        )
+    {       
+    return iCompleted;
+    }
+
+// -----------------------------------------------------------------------------
+// CPELogEvent::Added
+// iAdded flag is set to ETrue
+// -----------------------------------------------------------------------------
+//
+void CPELogEvent::SetAdded
+        (
+        // None
+        )
+    {       
+    iAdded = ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// CPELogEvent::SaveLeave
+// Return value of save leave flag
+// -----------------------------------------------------------------------------
+//
+TBool CPELogEvent::SaveLeave
+        (
+        // None
+        )
+    {       
+    return iSaveLeave;
+    }
+
+// -----------------------------------------------------------------------------
+// CPELogEvent::SetPhoneNumberId
+// Set event subject.
+// -----------------------------------------------------------------------------
+//
+/*****************************************************
+*    Series 60 Customer / LOGENG
+*    Series 60  LOGENG API
+*****************************************************/
+void CPELogEvent::SetPhoneNumberId()
+    {
+    TBuf<KPhonebookTypeIdLength> subject;
+    subject.Zero();
+
+    switch ( iLogInfo->PhoneNumberId() )
+        {
+        case EPEMobileNumber:
+            subject.AppendNum( EPbkFieldIdPhoneNumberMobile );
+            break;
+        case EPETelephoneNumber:
+            subject.AppendNum( EPbkFieldIdPhoneNumberGeneral );
+            break;
+        case EPEPager:
+            subject.AppendNum( EPbkFieldIdPagerNumber );
+            break;
+        case EPEFaxNumber:
+            subject.AppendNum( EPbkFieldIdFaxNumber );
+            break; 
+        case EPEAssistantNumber:
+            subject.AppendNum( EPbkFieldIdAssistantNumber);
+            break;
+        case EPECarNumber:
+            subject.AppendNum( EPbkFieldIdCarNumber);
+            break;
+        default:
+            subject.AppendNum( EPbkFieldIdNone );
+            break;
+        }
+
+    if ( subject.Length() > 0 )
+        {
+        iEvent->SetSubject( subject );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEGsmLogsEntry::SetEventType
+// Set event type.
+// -----------------------------------------------------------------------------
+//
+/*****************************************************
+*    Series 60 Customer / LOGENG
+*    Series 60  LOGENG API
+*****************************************************/
+void CPELogEvent::SetEventTypeL()
+    {
+    switch ( iLogInfo->EventType() )
+        {
+        case CPELogInfo::EPEVoiceEvent:
+            
+            {
+            iEvent->SetEventType( KLogCallEventTypeUid );
+            }
+            break;
+        case CPELogInfo::EPEVideoCallEvent:
+            {           
+            iEvent->SetEventType( KLogCallEventTypeUid );
+            iEvent->SetDataL( KLogsDataFldTag_VT );
+            TEFLOGSTRING( KTAINT, "LOG CPELogEvent::SetEventTypeL() video" );                
+            }
+            break;
+        case CPELogInfo::EPEEmergecyEvent:
+            {           
+            iEvent->SetEventType( KLogCallEventTypeUid );
+            iEvent->SetDataL( KLogsDataFldTag_Emergency );
+            TEFLOGSTRING( KTAINT, "LOG CPELogEvent::SetEventTypeK() Emergecy" );                
+            }
+            break;
+        case CPELogInfo::EPEVoIPEvent:
+            {
+            iEvent->SetEventType( KLogCallEventTypeUid );
+            iEvent->SetDataL( KLogsDataFldTag_IP );
+            TEFLOGSTRING( KTAINT, "LOG CPELogEvent::SetEventTypeL() VoIP" );                
+            }
+            break;
+        case CPELogInfo::EPEUnknownEvent:
+        default:
+            {
+            iEvent->SetEventType( KLogCallEventTypeUid );
+            }
+            break;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPELogEvent::SetLogEvent
+// Set the rest of event information.
+// -----------------------------------------------------------------------------
+//
+/*****************************************************
+*    Series 60 Customer / LOGENG
+*    Series 60  LOGENG API
+*****************************************************/
+void CPELogEvent::SetLogEvent()
+    {
+    if( CCCECallParameters::ECCELineTypeAux == iLogInfo->CurrentLine() )
+        {
+        iEvent->SetFlags( KPELogEventALS );             
+        }
+    if ( RMobileCall::EMobileOriginated == iLogInfo->CallDirection() )
+        {     
+        if ( CCCECallParameters::ECCELineTypeAux == iLogInfo->CurrentLine() )
+            {
+            iEvent->SetDirection( iOwner.LogStringOutAlt( ) );
+            }
+        else
+            {
+            iEvent->SetDirection( iOwner.LogStringOut( ) );    
+            }
+        }
+    else if ( RMobileCall::EMobileTerminated == iLogInfo->CallDirection() )
+        {
+        if ( iLogInfo->MissedCall() && EPEStateIdle == iLogInfo->CallState() )
+            {
+            iEvent->SetDirection( iOwner.LogStringMissed( ) );
+            }
+        else
+            //Logging on states Connected and Idle
+            {
+            if ( CCCECallParameters::ECCELineTypeAux == iLogInfo->CurrentLine() )
+                {
+                iEvent->SetDirection( iOwner.LogStringInAlt( ) );
+                }
+            else
+                {
+                iEvent->SetDirection( iOwner.LogStringIn( ) );
+                }
+            }
+        }
+
+    SetRemoteParty( *iEvent, *iLogInfo );
+    iEvent->SetStatus( iOwner.LogStringDelivery( ) );
+    
+    SetRemoteContact( *iEvent, *iLogInfo );
+    
+    if ( KNullDesC() != iLogInfo->MyAddress() )
+        {
+        TRAPD( error, SetDataFieldL( KLogsDataFldTag_MA, iLogInfo->MyAddress() ) );
+        if ( error )
+            {
+            TEFLOGSTRING2( KTAERROR, 
+                "LOG CPELogEvent::SetLogEvent()>SetDataFieldL(), error=%d", 
+                    error )
+            }
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CPELogEvent::SetDuration
+// Set the event duration
+// -----------------------------------------------------------------------------
+//
+/*****************************************************
+*    Series 60 Customer / LOGENG
+*    Series 60  LOGENG API
+*****************************************************/
+void CPELogEvent::SetDuration()
+    {
+    iEvent->SetDurationType( KLogDurationValid );
+    iEvent->SetDuration( static_cast <TLogDuration> ( iLogInfo->Duration().Int() ) );
+
+#ifdef _DEBUG
+    if ( EPEStateIdle == iLogInfo->CallState() )
+        {
+        // debug logging of the event start time.
+        TBuf<KPEESDWFormattedTimeLength> formattedTime;
+        formattedTime.Zero();
+        TRAPD( error, iEvent->Time().FormatL( formattedTime, KPEESDWTimeFormat ) );    
+        if( error == KErrNone )
+            {
+            TEFLOGSTRING2( KTAINT, "LOG CPELogEvent::SetDuration() Idle state > formattedTime: %S", &formattedTime );
+            }
+        else
+            {
+            TEFLOGSTRING( KTAERROR, "LOG CPELogEvent::SetDuration() Idle state > time conversion failed!");
+            }        
+        }
+#endif // _DEBUG
+    }
+
+// -----------------------------------------------------------------------------
+// CPELogEvent::SetServiceIdL
+// Set callers service id to log event.
+// -----------------------------------------------------------------------------
+//
+void CPELogEvent::SetServiceIdL()
+    {
+    HBufC8* eventData = NULL; 
+    if ( iEvent->Data().Length() )
+        {
+        // There are existing data logged.
+        eventData = HBufC8::NewLC( iEvent->Data().Length() 
+                   + KLogsDataFldNameDelimiter().Length() // separator
+                   + KLogsDataFldTag_ServiceId().Length()
+                   + KLogsDataFldValueDelimiter().Length()
+                   + KTUintCharLength );    
+                   
+        // Copy existing data to temp buffer.
+        eventData->Des().Copy( iEvent->Data() );
+   
+        // Append tag separator.
+        eventData->Des().Append( KLogsDataFldNameDelimiter );    
+        }
+    else
+        {
+        // No existing data logged. 
+        eventData = HBufC8::NewLC( 
+            KLogsDataFldTag_ServiceId().Length()
+            + KLogsDataFldValueDelimiter().Length()
+            + KTUintCharLength ); 
+        }
+    
+    // Append service id
+    eventData->Des().Append( KLogsDataFldTag_ServiceId );
+    eventData->Des().Append( KLogsDataFldValueDelimiter );
+    eventData->Des().AppendNum( (TInt)iLogInfo->ServiceId() );
+    
+    iEvent->SetDataL( *eventData );
+    TEFLOGSTRING( KTAINT, "LOG CPELogEvent::SetServiceIdL() Service id set ok" );  
+    CleanupStack::PopAndDestroy( eventData );
+    }
+
+// -----------------------------------------------------------------------------
+// Sets callers contact link to log event.
+// Contact link data might accidentally contain "\t"(KLogsDataFldNameDelimiter),
+// because of this, those "accidents" are stuffed with another "\t". They are
+// removed in logs handling side when data is read in.
+// -----------------------------------------------------------------------------
+//
+void CPELogEvent::SetContactLinkL()
+    {
+    HBufC8* eventData = NULL;
+    
+    TPtrC8 pDelimiter( iLogInfo->ContactLink() );
+    TInt delimiterCount = 0;
+    // Check how many "delimiters" data contains so that we can
+    // reserve space for data duplication
+    while ( KErrNotFound != pDelimiter.Find( KLogsDataFldNameDelimiter ) )
+        {
+        // Skip first \t to see if there exists another one after that 
+        pDelimiter.Set( pDelimiter.Mid( pDelimiter.Find( KLogsDataFldNameDelimiter ) + KOneChar ) );
+        ++delimiterCount;
+        }
+    if ( iEvent->Data().Length() )
+        {
+        // There is previous data logged
+        eventData = HBufC8::NewLC( 
+            iEvent->Data().Length() 
+            + KLogsDataFldNameDelimiter().Length() // separator
+            + KLogsDataFldTag_ContactLink().Length() 
+            + KLogsDataFldValueDelimiter().Length()
+            + iLogInfo->ContactLink().Length() 
+            + delimiterCount );
+                   
+        // Copy previous data to temp buffer
+        eventData->Des().Copy( iEvent->Data() );
+   
+        // Append tag separator
+        eventData->Des().Append( KLogsDataFldNameDelimiter );    
+        }
+    else
+        {
+        // No previous data logged. 
+        eventData = HBufC8::NewLC( 
+                KLogsDataFldTag_ContactLink().Length() 
+            + KLogsDataFldValueDelimiter().Length()
+            + iLogInfo->ContactLink().Length() 
+            + delimiterCount ); 
+        }
+    
+    TPtr8 eventDataPtr( eventData->Des() );
+    eventDataPtr.Append( KLogsDataFldTag_ContactLink );
+    eventDataPtr.Append( KLogsDataFldValueDelimiter );
+    
+    if ( delimiterCount )
+        {
+        // Link data contained unintended \t chars
+        TPtrC8 linkPtr( iLogInfo->ContactLink() );
+        TInt dataLength = 0;
+        // Copy link data between \t chars
+        for ( TInt i = 0; i < delimiterCount; i++ )
+            {
+            // Plus one because we need length, not offset
+            dataLength = linkPtr.Find( KLogsDataFldNameDelimiter ) + KOneChar;
+            // Append from beginning of data, including \t
+            eventDataPtr.Append( linkPtr.Left( dataLength ) );
+            // Add another \t
+            eventDataPtr.Append( KLogsDataFldNameDelimiter );
+            linkPtr.Set( linkPtr.Mid( dataLength ) );
+            }
+        // Copy rest of link data
+        eventDataPtr.Append( linkPtr );
+        }
+    else
+        {
+        // Link data didn't contain \t, so normal copy is possible
+        eventDataPtr.Append( iLogInfo->ContactLink() );
+        }
+    
+    iEvent->SetDataL( *eventData );
+    TEFLOGSTRING( KTAINT, "LOG CPELogEvent::ContactLinkL() Contact link set ok" );
+    CleanupStack::PopAndDestroy( eventData );
+    }
+
+// -----------------------------------------------------------------------------
+// CPELogEvent::SetDataFieldL
+// -----------------------------------------------------------------------------
+//
+void CPELogEvent::SetDataFieldL( const TDesC8& aTag, const TDesC& aFieldData )
+    {
+    __ASSERT_ALWAYS( aTag.Length() != 0 && aFieldData.Length() != 0 ,
+        User::Leave( KErrArgument ) );
+    
+    if ( KErrNotFound == iEvent->Data().Find( aTag ) )
+        {
+        HBufC8* eventData = NULL;
+        const TInt fieldLength = aTag.Length() 
+            + KLogsDataFldValueDelimiter().Length()
+            + aFieldData.Length();
+        const TInt oldDataFieldLength = iEvent->Data().Length();
+        
+        if ( oldDataFieldLength != 0 )
+            {
+            const TInt newDataFieldLength = oldDataFieldLength 
+                + KLogsDataFldNameDelimiter().Length()
+                + fieldLength;
+            
+            eventData = HBufC8::NewLC( newDataFieldLength );
+            
+            // Copy previous data
+            eventData->Des().Copy( iEvent->Data() );
+            eventData->Des().Append( KLogsDataFldNameDelimiter );
+            }
+        else
+            {
+            eventData = HBufC8::NewLC( fieldLength );
+            }
+        
+        // Add a new data field.
+        eventData->Des().Append( aTag );
+        eventData->Des().Append( KLogsDataFldValueDelimiter );
+        eventData->Des().Append( aFieldData );     
+        iEvent->SetDataL( *eventData );
+        
+        CleanupStack::PopAndDestroy( eventData );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPELogEvent::SetRemoteParty
+// -----------------------------------------------------------------------------
+//
+void CPELogEvent::SetRemoteParty( CLogEvent& aEvent, 
+        const CPELogInfo& aLogInfo )
+    {
+    if ( KNullDesC() != aLogInfo.Name() )
+        {
+        aEvent.SetRemoteParty( aLogInfo.Name() );
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CPELogEvent::SetRemoteContact
+// -----------------------------------------------------------------------------
+//
+void CPELogEvent::SetRemoteContact( CLogEvent& aEvent, 
+        const CPELogInfo& aLogInfo )
+    {
+    if ( KNullDesC() != aLogInfo.PhoneNumber() )
+        {
+        aEvent.SetNumber( aLogInfo.PhoneNumber() );
+        }
+    
+    if ( KNullDesC() != aLogInfo.VoipAddress() )
+        {
+        TRAPD( error, SetDataFieldL( KLogsDataFldTag_URL, aLogInfo.VoipAddress() ) );
+        if ( error )
+            {
+            TEFLOGSTRING2( KTAERROR, 
+                "LOG CPELogEvent::SetLogEvent()>SetDataFieldL(), error=%d", error )
+            }
+        }
+    }
+
+
+// ================= OTHER EXPORTED FUNCTIONS ===============================
+
+//  End of File 
+