vpnengine/eventmediator/src/eventmediatorsession.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 14 Sep 2010 23:16:15 +0300
branchRCL_3
changeset 25 735de8341ce4
permissions -rw-r--r--
Revision: 201033 Kit: 201035

/*
* Copyright (c) 2003-2010 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 defines event mediator server side session.
*
*/

#include "eventmediatorsession.h"
#include "eventmediator.h"
#include "eventmediatorclientservercommon.h"
#include "eventlogger.h"
#include "sit.h"
#include "log_em.h"

#define FIRST_ARGUMENT 0
#define SECOND_ARGUMENT 1
#define THIRD_ARGUMENT 2
#define FOURTH_ARGUMENT 3


// ============================= CEventMediatorSession =============================     

CEventMediatorSession* CEventMediatorSession::NewL(CEventMediatorServer& aServer, 
                                                   TBool aIsSitSession)
    {
    LOG(Log::Printf(_L("CEventMediatorSession::NewL - begin\n")));
    
    CEventMediatorSession* self = new (ELeave) CEventMediatorSession(aServer, aIsSitSession);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(); // self

    LOG(Log::Printf(_L("CEventMediatorSession::NewL - end\n")));
    return self;
    }

CEventMediatorSession::CEventMediatorSession(CEventMediatorServer& aServer, TBool aIsSitSession)
    : iListenedEvents(2), iServer(aServer), iIsSitSession(aIsSitSession)
    {
    }

void CEventMediatorSession::ConstructL()
    {
    if ( !IsASitSession() )
        {
        User::LeaveIfError(iFs.Connect()); // For EventLog
        iEventLogFileOpen = EFalse;
        }    
    }


CEventMediatorSession::~CEventMediatorSession(void)
    {
    LOG(Log::Printf(_L("CEventMediatorSession::~CEventMediatorSession\n")));
    CancelAll();

    // If this too is a normal session and is dying,
    // decrement the normal session count by one
    if (!IsASitSession())
        {
        iEventLogFile.Close();
        iEventLogFileOpen = EFalse;
        iFs.Close();         
        }
    iServer.SessionDeleted(IsASitSession());    
    }

void CEventMediatorSession::ServiceL(const RMessage2& aMessage)
    {
    TInt status = 0;

    switch (aMessage.Function())
        {
        case KEventMediatorListen:
            ListenToEventL(aMessage);
            break;

        case KEventMediatorListenWithSpec:
            ListenToEventWithSpecL(aMessage);
            break;

        case KEventMediatorCancel:
            CancelListening(aMessage);        
            aMessage.Complete(KErrNone);
            break;

        case KEventMediatorCancelWithSpec:
            CancelListeningWithSpecL(aMessage);        
            aMessage.Complete(KErrNone);
            break;

        case KEventMediatorCancelAll:
            CancelAll();        
            aMessage.Complete(KErrNone);
            break;

        case KEventMediatorReportEvent:
            ReportEventL(aMessage);
            aMessage.Complete(KErrNone);
            break;

        case KEventMediatorReportEventWithSpec:
            ReportEventWithSpecL(aMessage);
            aMessage.Complete(KErrNone);
            break;

        case KEventMediatorFetchData:
            status = FetchDataL(aMessage);
            aMessage.Complete(status);
            break;

        case KEventMediatorReportLogEvent:
            ReportLogEventL(aMessage);
            aMessage.Complete(KErrNone);
            break;

        case KEventMediatorNewEventSpecId:
            NewEventSpecIdL(aMessage);
            aMessage.Complete(KErrNone);
            break;
        case KEventMediatorDeletePrivateFiles:
            status = DeletePrivateFiles();
            aMessage.Complete(status);
            break;

        case KEventMediatorGetEventLogSize:
            status = GetEventLogSize(aMessage);
            aMessage.Complete(status);
            break;

        case KEventMediatorGetEventLogHeader:
            status = GetEventLogHeader(aMessage);
            aMessage.Complete(status);
            break;
        case KEventMediatorGetEventLogData:
            status = GetEventLogData(aMessage);
            aMessage.Complete(status);
            break;
        case KEventMediatorClearEventLog:
            status = ClearEventLog();
            aMessage.Complete(status);
            break;
        default:
            aMessage.Complete(KErrGeneral);
            break;
        }
    }

TInt CEventMediatorSession::ListenToEventL(const RMessage2& aMessage)
    {
    CListenerContainer* listener = new (ELeave) CListenerContainer(aMessage, NULL, iServer);
    CleanupStack::PushL(listener);

    iListenedEvents.AppendL(listener);
    CleanupStack::Pop(); // listener

    listener->AnalyzeRequestL();

    return KErrNone;
    }

TInt CEventMediatorSession::ListenToEventWithSpecL(const RMessage2& aMessage)
    {
    HBufC8* specBuf = NULL;

    // Read specification
    specBuf = ReadSpecificationFromClientL(aMessage);
    CleanupStack::PushL(specBuf);

    // Ownership of specBuf is given to listener
    CListenerContainer* listener = new (ELeave) CListenerContainer(aMessage, specBuf, iServer);
    CleanupStack::Pop(); // specBuf
    CleanupStack::PushL(listener);
        
    iListenedEvents.AppendL(listener);
    CleanupStack::Pop(); // listener

    listener->AnalyzeRequestL();

    return KErrNone;
    }

void CEventMediatorSession::CancelListening(const RMessage2& aMessage)
    {
    TInt index;
    
    while (FindListenerMsg((TEventType)aMessage.Int0(), index))
        {
        CompleteListener(index, KErrCancel);
        }
    }

void CEventMediatorSession::CancelListeningWithSpecL(const RMessage2& aMessage)
    {
    HBufC8* specBuf = NULL;
    TInt index;
    
    // Read specification
    specBuf = ReadSpecificationFromClientL(aMessage);
    CleanupStack::PushL(specBuf);

    // Cancel listeners
    while (FindListenerMsg((TEventType)aMessage.Int0(), specBuf, index))
        {
        CompleteListener(index, KErrCancel);
        }
    CleanupStack::PopAndDestroy(); // specBuf
    }

void CEventMediatorSession::CancelAll()
    {
    TInt nEvents = iListenedEvents.Count();
    for (TInt i = 0; i < nEvents; i++)  
        {
        iListenedEvents.At(i)->Complete(KErrCancel);
        delete iListenedEvents.At(i);
        iListenedEvents.At(i) = NULL;
        }
    iListenedEvents.Reset();
    }

void CEventMediatorSession::ReportEventL(const RMessage2& aMessage)
    {
    TEventType eventType = (TEventType)aMessage.Int0();
    LOG(Log::Printf(_L("CEventMediatorSession::ReportEventL - event type = %d\n"), eventType));
    // Read data
    HBufC8* dataBuf = ReadEventDataFromClientL(aMessage);
    CleanupStack::PushL(dataBuf);
    // Report event to server
    iServer.ReportEventL(eventType, NULL, dataBuf);
    CleanupStack::Pop();
    }

void CEventMediatorSession::ReportEventWithSpecL(const RMessage2& aMessage)
    {
    TEventType eventType=(TEventType) aMessage.Int0();
    LOG(Log::Printf(_L("CEventMediatorSession::ReportEventWithSpecL - event type = %d\n"), eventType));
    // Read data
    HBufC8* dataBuf = ReadEventDataFromClientL(aMessage);
    CleanupStack::PushL(dataBuf);
    // Read specification
    HBufC8* specBuf = ReadSpecificationFromClientL(aMessage);
    CleanupStack::PushL(specBuf);
    // Report event to server
    iServer.ReportEventL(eventType, specBuf, dataBuf);
    CleanupStack::PopAndDestroy(); // specBuf
    CleanupStack::Pop(); // dataBuf 
    }

void CEventMediatorSession::ReportLogEventL(const RMessage2& aMessage)
    {
    LOG(Log::Printf(_L("CEventMediatorSession::ReportLogEventL\n")));
    // Read event
    TLogEvent event;
    TPckg<TLogEvent> eventPckg(event);
    aMessage.ReadL(FIRST_ARGUMENT, eventPckg);

    // Create one buffer to contain put everything in a normal buffer and
    TInt lengthsDesLth = event.iDesCount * sizeof(TInt);
    TInt position = eventPckg.Length();
    TInt dataLength = position + lengthsDesLth + aMessage.Int2();
    HBufC8* dataBuf = HBufC8::NewLC(dataLength);
    TPtr8 dataPtr = dataBuf->Des();

    // Copy event to buffer
    dataPtr.Append(eventPckg);
    // Read lengths to buffer
    TPtr8 tmpPtr(&dataPtr[position], 0, dataLength - position);
    aMessage.ReadL(SECOND_ARGUMENT, tmpPtr);
    // Read descriptors to the buffer
    position= dataPtr.Length();
    tmpPtr.Set(&dataPtr[position], 0, dataLength - position);
    aMessage.ReadL(THIRD_ARGUMENT, tmpPtr);

    // Report event to server
    iServer.ReportEventL(ELogEvent, NULL, dataBuf);
    CleanupStack::Pop();
    }

TInt CEventMediatorSession::FetchDataL(const RMessage2& aMessage)
    {
    LOG(Log::Printf(_L("CEventMediatorSession::FetchDataL\n")));
    return iServer.CopyEventDataL(aMessage);
    }

TInt CEventMediatorSession::CheckEventL(const TEventType aType, const TDesC8* aSpec,
                                        const TDesC8* aData, TInt aStatus)
    {
    TInt index;
    TInt listenerCount = 0;
    TInt dataLth = 0;
    // Some events don't not have data
    if (aData)
        {
        dataLth = aData->Length();
        }
    TPckg<TInt> lengthpckg(dataLth);
    TPckgC<const TAny*> ptrpckg(aData);

    while (FindListenerMsg(aType, aSpec, index))
        {
        RMessage2& listener = iListenedEvents.At(index)->Message();

        if (aStatus == KErrNone)
            {
            // Write info about data
            listener.WriteL(SECOND_ARGUMENT, lengthpckg);
            listener.WriteL(THIRD_ARGUMENT, ptrpckg);

            // Complete listener
            listener.Complete(KErrNone);
            }
        else
            {
            listener.Complete(aStatus);
            }
        
        delete iListenedEvents.At(index);
        iListenedEvents.Delete(index);
        listenerCount++;    
        }

    return listenerCount;
    }

TBool CEventMediatorSession::FindListenerMsg(const TEventType aType, TInt& index)
    {
    for (TInt i = 0; i < iListenedEvents.Count(); i++)
        {
        if (iListenedEvents.At(i)->Type() == aType)
            {
            index=i;
            return ETrue;
            }
        }
    return EFalse;
    }

TBool CEventMediatorSession::FindListenerMsg(const TEventType aType, const TDesC8* aSpec, TInt& index)
    {
    for (TInt i = 0; i < iListenedEvents.Count(); i++)
        {
        if (iListenedEvents.At(i)->HandlesEvent(aType, aSpec))
            {
            index = i;
            return ETrue;
            }
        }
    return EFalse;
    }

TBool CEventMediatorSession::FindTaskRequestListenerMsg(TInt& index)
    {
    for (TInt i = 0; i < iListenedEvents.Count(); i++)
        {
        if (CSit::EventRequiresSit(iListenedEvents.At(i)->Type()))
            {
            index = i;
            return ETrue;
            }
        }
    return EFalse;
    }
    
HBufC8* CEventMediatorSession::ReadSpecificationFromClientL(const RMessage2& aMessage)
    {
    HBufC8* specBuf;
    // Read specification descriptor length from client, create specification buffer
    const TAny* desPtr = aMessage.Ptr3();
    if (desPtr == NULL)
        {
        return NULL;
        }
    TInt specLength = aMessage.GetDesLength(FOURTH_ARGUMENT);
    // Create spcification buffer
    specBuf = HBufC8::NewLC(specLength);
    TPtr8 ptr = specBuf->Des();
    // Read specification
    aMessage.ReadL(FOURTH_ARGUMENT, ptr);
    CleanupStack::Pop(); // specBuf
    return specBuf;
    }

HBufC8* CEventMediatorSession::ReadEventDataFromClientL(const RMessage2& aMessage)
    {
    HBufC8* dataBuf = NULL;
    TInt desLength = aMessage.Int1();
    
    if (desLength != 0) // Some events have no data 
        {
        dataBuf = HBufC8::NewLC(desLength);
        TPtr8 ptr = dataBuf->Des();
        aMessage.ReadL(THIRD_ARGUMENT, ptr);
        CleanupStack::Pop(); // dataBuf
        }
    return dataBuf;
    }

CListenerContainer* CEventMediatorSession::FindWaitingTaskRequest()
    {
    CListenerContainer* listener = NULL;
    
    for (TInt i = 0; i < iListenedEvents.Count(); i++)
        {
        if (iListenedEvents.At(i)->WaitingForFulfilling())
            {
            listener = iListenedEvents.At(i);
            break;
            }
        }

    return listener;
    }

CListenerContainer* CEventMediatorSession::FindListener(TEventType aEventType,
                                                        TInt aEventSpecId)
    {
    CListenerContainer* listener = NULL;
    
    for (TInt i = 0; i < iListenedEvents.Count(); i++)
        {
        if (iListenedEvents.At(i)->Type() == aEventType)
            {
            TEventSpec* eventSpec = (TEventSpec*)(iListenedEvents.At(i)->Specification()->Ptr());

            if (eventSpec->iId == aEventSpecId)
                {
                listener = iListenedEvents.At(i);
                break;
                }
            }
        }

    return listener;
    }
    
CListenerContainer* CEventMediatorSession::FindListener(TEventType aEventType,
                                                        const TDesC8* aEventSpec)
    {
    CListenerContainer* listener = NULL;
    
    for (TInt i = 0; i < iListenedEvents.Count(); i++)
        {
        if (iListenedEvents.At(i)->HandlesEvent(aEventType, aEventSpec))
            {
            listener = iListenedEvents.At(i);
            break;
            }
        }

    return listener;
    }

void CEventMediatorSession::CompleteListener(TEventType aEventType,
                                             const TDesC8* aEventSpec,
                                             TInt aStatus)
    {
    TInt index;
    while (FindListenerMsg(aEventType, aEventSpec, index))
        {
        CompleteListener(index, aStatus);
        }
    }
        
void CEventMediatorSession::CompleteListener(TInt aIndex, TInt aStatus)
    {
    iListenedEvents.At(aIndex)->Complete(aStatus);
    delete iListenedEvents.At(aIndex);
    iListenedEvents.Delete(aIndex);
    }

void CEventMediatorSession::CompleteTaskRequests(TInt aStatus)
    {
    LOG(Log::Printf(_L("CEventMediatorSession::CompleteTaskRequests\n")));
    TInt index;
    while (FindTaskRequestListenerMsg(index))
        {
        CompleteListener(index, aStatus);
        }
    }

TBool CEventMediatorSession::IsASitSession()
    {
    return iIsSitSession;
    }

void CEventMediatorSession::NewEventSpecIdL(const RMessage2& aMessage)
    {
    TInt newEventSpecId = iServer.NewEventSpecId();
    TPckg<TInt> newEventSpecIdDes(newEventSpecId);
    aMessage.WriteL(FIRST_ARGUMENT, newEventSpecIdDes);
    }

TInt CEventMediatorSession::DeletePrivateFiles()
    {
    TRAPD(err, DeletePrivateFilesL());
    if ( err )
        {
        LOG(Log::Printf(_L("DeletePrivateFilesL() leave error %d\n"), err));
        return err;
        }

    return KErrNone;
    }

void CEventMediatorSession::DeletePrivateFilesL()
    {
    LOG(Log::Printf(_L("DeletePrivateFilesL() called\n")));

    CFileMan* fileMan = CFileMan::NewL(iFs);
    CleanupStack::PushL(fileMan);

    TPath privateDir;
    User::LeaveIfError(iFs.PrivatePath(privateDir));

    TInt err = fileMan->RmDir(privateDir);
    if (err != KErrNone && err != KErrPathNotFound && err != KErrNotFound)
        {
        User::Leave(err);
        }
    CleanupStack::PopAndDestroy(); //fileMan
    }

TInt CEventMediatorSession::GetEventLogSize(
    const RMessage2& aMessage)
    {
    if ( iEventLogFileOpen )
        {
        iEventLogFile.Close();
        iEventLogFileOpen = EFalse;
        }

    TInt err = iEventLogFile.Open(iFs, iServer.EventLogFileName(), EFileRead | EFileShareAny);
    if ( err )
        return err;

    TInt size(0);
    err = iEventLogFile.Size(size);
    if ( err )
        {
        iEventLogFile.Close();
        return err;
        }
    
    TPckg<TInt> sizePckg(size);
    err = aMessage.Write(FIRST_ARGUMENT, sizePckg);
    if ( err )
        {
        iEventLogFile.Close();
        return err;
        }

    iEventLogFileOpen = ETrue;
    
    return KErrNone;
    }

TInt CEventMediatorSession::GetEventLogHeader(
    const RMessage2& aMessage)
    {
    TInt err(0);
    
    if ( !iEventLogFileOpen )
        {
        err = iEventLogFile.Open(iFs, iServer.EventLogFileName(), EFileRead | EFileShareAny);
        if ( err )
            return err;
        iEventLogFileOpen = ETrue;
        }
    
    TInt position = 0;
    err = iEventLogFile.Seek(ESeekStart, position);     
    if (err != KErrNone)
        return err;

    TBuf8<EVENTLOG_FILE_HEADER_LTH> fileHeaderBuf;
    err = iEventLogFile.Read(fileHeaderBuf, EVENTLOG_FILE_HEADER_LTH);
    if (err != KErrNone)
        return err;

    TRAP(err, aMessage.WriteL(FIRST_ARGUMENT, fileHeaderBuf));
    if ( err )
        return err;

    return KErrNone;
    }
    
TInt CEventMediatorSession::GetEventLogData(
    const RMessage2& aMessage)
    {
    TInt err(0);

    if ( !iEventLogFileOpen )
        {
        err = iEventLogFile.Open(iFs, iServer.EventLogFileName(), EFileRead | EFileShareAny);
        if ( err )
            return err;
        iEventLogFileOpen = ETrue;
        }
    
    TInt size(0);
    err = iEventLogFile.Size(size);
    if ( err )
        return err;

    if ( size < EVENTLOG_FILE_HEADER_LTH )
        return KErrNotFound;

    HBufC8* eventLogFileBuf = NULL;
    TRAP(err, eventLogFileBuf = HBufC8::NewL(size));
    if ( err )
        {
        return err;
        }
    
    TPtr8 eventLogDataPtr(eventLogFileBuf->Des());
    TInt position(0);
    err = iEventLogFile.Seek(ESeekStart, position);
    if ( err )
        {
        delete eventLogFileBuf;
        return err;
        }
    err = iEventLogFile.Read(eventLogDataPtr); // iLogFileSize);
    if ( err )
        {
        delete eventLogFileBuf;
        return err;
        }
    
    TRAP( err, aMessage.WriteL(FIRST_ARGUMENT, eventLogDataPtr));
    if ( err )
        {
        delete eventLogFileBuf;
        return err;
        }

    delete eventLogFileBuf;
    eventLogFileBuf = NULL;
    
    return KErrNone;
    }
    
TInt CEventMediatorSession::ClearEventLog()
    {
    if ( iEventLogFileOpen )
        {
        iEventLogFile.Close();
        iEventLogFileOpen = EFalse;
        }

    TInt err = iFs.Delete(iServer.EventLogFileName());

    return err;
    }