vpnengine/eventmediator/src/eventmediatorsession.cpp
branchRCL_3
changeset 44 735de8341ce4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vpnengine/eventmediator/src/eventmediatorsession.cpp	Tue Sep 14 23:16:15 2010 +0300
@@ -0,0 +1,666 @@
+/*
+* 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;
+    }
+