vpnengine/eventmediator/src/eventmediator.cpp
changeset 0 33413c0669b9
child 44 735de8341ce4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vpnengine/eventmediator/src/eventmediator.cpp	Thu Dec 17 09:14:51 2009 +0200
@@ -0,0 +1,1354 @@
+/*
+* Copyright (c) 2003-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 eventmediator and the services of it.
+*
+*/
+
+
+
+/**  
+ * @file eventmediator.cpp
+ *
+ * This module contains eventmediator and the services of it.
+ *
+ */
+#include <es_sock.h>
+#include "eventmediator.h"
+#include "eventlogger.h"
+#include "eventmediatordefs.h"
+#include "sit.h"
+#include "log_em.h"
+
+#define FIRST_ARGUMENT 0
+#define SECOND_ARGUMENT 1
+#define THIRD_ARGUMENT 2
+#define FOURTH_ARGUMENT 3
+
+// ============================= CEventMediatorServer =============================
+
+const TUint CEventMediatorServer::iRangeCount = 2;
+    
+const TInt CEventMediatorServer::iRanges[iRangeCount] = 
+    {
+    CEventMediatorSession::KEventMediatorListen,
+    CEventMediatorSession::KEventMediatorClearEventLog+1
+    };
+
+const TUint8 CEventMediatorServer::iElementIndex[iRangeCount] = 
+    {
+    0,
+    CPolicyServer::ENotSupported
+    };
+
+const CPolicyServer::TPolicyElement CEventMediatorServer::iElements[] =
+    {
+    {_INIT_SECURITY_POLICY_C1(ECapabilityNetworkControl), CPolicyServer::EFailClient},
+    };
+
+const CPolicyServer::TPolicy CEventMediatorServer::iPolicy =
+    {
+    0,              // All connect attempts are checked
+    iRangeCount,    // Count of ranges
+    iRanges,        // 0...9, 9...
+    iElementIndex,  // Only range 1000-1008 are checked
+    iElements       // The list of policy elements
+    };
+
+
+CEventMediatorServer::CEventMediatorServer(void)
+    : CPolicyServer(EPriorityNormal,iPolicy), iStoredEvents(1)
+    {
+    }
+
+CEventMediatorServer* CEventMediatorServer::NewL()
+    {
+    LOG(Log::Printf(_L("CEventMediatorServer::NewL - begin\n")));
+    CEventMediatorServer* server = CEventMediatorServer::NewLC();
+    CleanupStack::Pop(); // server
+    LOG(Log::Printf(_L("CEventMediatorServer::NewL - end\n")));
+    return server;
+    }
+
+CEventMediatorServer* CEventMediatorServer::NewLC()
+    {
+    LOG(Log::Printf(_L("CEventMediatorServer::NewLC - begin\n")));
+    CEventMediatorServer* server = new (ELeave) CEventMediatorServer();
+    CleanupStack::PushL(server); 
+    server->ConstructL(server);
+    LOG(Log::Printf(_L("CEventMediatorServer::NewLC - end\n")));
+    return server;
+    }
+
+void CEventMediatorServer::ConstructL(CEventMediatorServer* aServer)
+    {
+    RFs fs;
+    User::LeaveIfError(fs.Connect());
+    CleanupClosePushL(fs);
+
+    fs.CreatePrivatePath(EDriveC);
+    
+    TPath privateDir;
+    User::LeaveIfError(fs.PrivatePath(privateDir));
+    iEventLogFileName.Copy(privateDir);
+    iEventLogFileName.Append(KEventLogFile);
+    
+    CleanupStack::PopAndDestroy(); // fs
+    
+    aServer->iLogger = CEventLogger::NewL(this);
+    iSit = new (ELeave) CSit(this);
+    StartL(KEventMediatorServer);
+    }
+
+CEventMediatorServer::~CEventMediatorServer(void)
+    {
+    LOG(Log::Printf(_L("CEventMediatorServer::~CEventMediatorServer\n")));
+    // Delete stored events
+    TInt nEvents = this->iStoredEvents.Count();
+    for (TInt i = 0; i < nEvents; i++)  
+        {
+        delete iStoredEvents.At(i)->iData;
+        delete iStoredEvents.At(i);
+        }
+    iStoredEvents.Delete(0, iStoredEvents.Count());
+
+    // Delete log writer
+    delete iLogger;
+
+    delete iSit;
+    }
+
+// ----------------------------------------------------------------------------
+// CEventMediatorServer::StopEventMediator
+// Stops Event Mediator service if there are no sessions left.
+// ----------------------------------------------------------------------------
+//
+void CEventMediatorServer::StopEventMediator(void)
+    {
+    if (iSessionCount == 0) 
+        {
+        LOG(Log::Printf(_L("CEventMediatorServer::StopEventMediator - session count 0, stopping scheduler and thus the server\n")));
+        CActiveScheduler::Stop();   
+        }   
+    }
+
+TInt CEventMediatorServer::RunError(TInt aError)
+    {
+    LOG(Log::Printf(_L("CEventMediatorServer::RunError - error = %d\n"), aError));
+    Message().Complete(aError);
+
+    // The leave will result in an early return from CServer::RunL(),
+    // skipping the call to request another message. So we issue the
+    // request here in order to keep the server running.
+    ReStart();
+
+    // Handled the error fully
+    return KErrNone;    
+    }
+
+// ----------------------------------------------------------------------------
+// CEventMediatorServer::NewSessionL
+// Creates a new session and returns the handle to the session.
+// ----------------------------------------------------------------------------
+//
+CSession2* CEventMediatorServer::NewSessionL(
+    const TVersion& /*aVersion*/,
+    const RMessage2& aMessage) const
+    {
+    // New sessions are not accepted if the server is shutting down
+    // (it's just waiting for the last session (from SIT) to die)
+    if (iShuttingDown)
+        {
+        User::Leave(KErrServerTerminated);
+        }
+    
+    CSession2* session = CEventMediatorSession::NewL(CONST_CAST(CEventMediatorServer*, this), aMessage);
+    return session;
+    }
+
+void CEventMediatorServer::ReportEventL(const TEventType aType, TDesC8* aSpec,
+                                        TDesC8* aData, TInt aStatus)
+    {
+    LOG(Log::Printf(_L("CEventMediatorServer::ReportEventL - event type = %d\n"), aType));
+    TInt listenerCount = 0;
+    CEventMediatorSession* session;
+    iSessionIter.SetToFirst();
+    session = (CEventMediatorSession*) iSessionIter++;
+
+    while (session != NULL)
+        {
+        // Some listeners listen this event with specification
+        listenerCount += session->CheckEventL(aType, aSpec, aData, aStatus); 
+        // Some without specification, all events are good for them
+        if (aSpec != NULL)
+            {
+            listenerCount += session->CheckEventL(aType, NULL, aData, aStatus);
+            }
+        session = (CEventMediatorSession*) iSessionIter++;
+        }
+    if (listenerCount)
+        {
+        // Need to save the event data as it may/will be fetched later
+        TEventContainer* container = new (ELeave) TEventContainer(listenerCount, aData);
+        CleanupStack::PushL(container);
+        iStoredEvents.AppendL(container);
+        CleanupStack::Pop();
+        }
+    // Write event to log
+    if (aType == ELogEvent && iLogger)
+        {
+        LOG(Log::Printf(_L("CEventMediatorServer::ReportEventL - calling iLogger->LogEvent\n")));
+        iLogger->LogEvent(*aData);
+        }
+
+    // If there are no listeners, delete data
+    if (listenerCount == 0)
+        {
+        delete aData;
+        }
+    }
+
+TInt CEventMediatorServer::CopyEventDataL(const RMessage2& aMessage)
+    {
+    TBool found = EFalse;
+    TInt i = 0;
+    TInt err = KErrNone;
+    while (!found && i < iStoredEvents.Count())
+        {
+        if (iStoredEvents.At(i)->iData == aMessage.Ptr0())
+            {
+            found = ETrue;
+            }
+        else
+            {
+            i++;
+            }
+        }
+    if (found)
+        {
+        aMessage.WriteL(SECOND_ARGUMENT, *(iStoredEvents.At(i)->iData));
+        MarkStoredEventListened(i);
+        }
+    else
+        {
+        err = KErrNotFound;
+        }
+    return err;
+    }
+
+void CEventMediatorServer::MarkStoredEventListened(TInt aIndex)
+    {
+    iStoredEvents.At(aIndex)->iListenerCount--;
+    if (iStoredEvents.At(aIndex)->iListenerCount == 0)
+        {
+        delete iStoredEvents.At(aIndex)->iData;
+        delete iStoredEvents.At(aIndex);
+        iStoredEvents.Delete(aIndex);
+        }
+    }
+
+TBool CEventMediatorServer::IsClientTheSitL(const RMessage2& aMessage)
+    {
+    LOG(Log::Printf(_L("CEventMediatorServer::IsClientTheSitL\n")));
+    TBool isClientTheSit = EFalse;
+    
+    RThread clientThread;
+    User::LeaveIfError(aMessage.Client(clientThread));
+    
+    if (clientThread.Id() == iSit->ThreadId())
+        {
+        LOG(Log::Printf(_L("CEventMediatorServer::IsClientTheSitL - YES\n")));
+        isClientTheSit = ETrue;
+        }
+
+    clientThread.Close();
+
+    return isClientTheSit;
+    }
+    
+void CEventMediatorServer::MakeSureSitIsRunningL()
+    {
+    LOG(Log::Printf(_L("CEventMediatorServer::MakeSureSitIsRunningL\n")));
+    // If the SIT has not yet been started
+    // or has died, try to start it
+    iSit->StartL();
+    }
+
+void CEventMediatorServer::SetTaskArrivalListenerL(CListenerContainer* aListener)
+    {
+    LOG(Log::Printf(_L("CEventMediatorServer::SetTaskArrivalListenerL\n")));
+    if (aListener)
+        {
+        // Task arrival observation requests must
+        // come from the SIT
+        if (!IsClientTheSitL(aListener->Message()))
+            {
+            User::Leave(KErrNotSupported);
+            }
+
+        // Only one task arrival observation request
+        // is allowed to be present at the same time
+        if (iTaskArrivalListener && (aListener != iTaskArrivalListener))
+            {
+            User::Leave(KErrNotSupported);
+            }
+        }
+
+    iTaskArrivalListener = aListener;
+    }
+
+void CEventMediatorServer::ClearTaskArrivalListener()
+    {
+    LOG(Log::Printf(_L("CEventMediatorServer::ClearTaskArrivalListener\n")));
+    iTaskArrivalListener = NULL;
+    }
+
+CListenerContainer* CEventMediatorServer::TaskArrivalListener()
+    {
+    return iTaskArrivalListener;
+    }
+
+void CEventMediatorServer::TaskRequestArrivedL(CListenerContainer* aTaskRequest)
+    {
+    LOG(Log::Printf(_L("CEventMediatorServer::TaskRequestArrivedL\n")));
+    CompleteTaskArrivalObservationRequestL(aTaskRequest->Type(), aTaskRequest->Specification());
+    }
+
+void CEventMediatorServer::TaskArrivalObservationRequestArrivedL()
+    {
+    LOG(Log::Printf(_L("CEventMediatorServer::TaskArrivalObservationRequestArrivedL\n")));
+    // Go through all pending event listening requests to see if any
+    // one of those should be passed to the SIT (i.e. if the task
+    // arrival observation request should be completed immediately)
+    
+    CListenerContainer* taskRequest = FindWaitingTaskRequest();
+    
+    if (taskRequest)
+        {
+        CompleteTaskArrivalObservationRequestL(taskRequest->Type(), taskRequest->Specification());
+        }
+    }
+
+void CEventMediatorServer::TaskRequestEventSpecFetchingRequestArrivedL(CListenerContainer* aFetchingRequest)
+    {
+    LOG(Log::Printf(_L("CEventMediatorServer::TaskRequestEventSpecFetchingRequestArrivedL\n")));
+    TFetchTaskInfoEventSpec taskRequestInfo;
+    TPckg<TFetchTaskInfoEventSpec> taskRequestInfoDes(taskRequestInfo);
+    taskRequestInfoDes.Copy(*(aFetchingRequest->Specification()));
+
+    // Find the task request whose event specification
+    // we should return to the SIT TH
+    CListenerContainer* taskRequest = FindListener(taskRequestInfo.iEventType, taskRequestInfo.iEventSpecId);
+
+    if (taskRequest && !taskRequest->BeingFulfilled())
+        {
+        CompleteTaskRequestEventSpecFetchingRequestL(KErrNone, aFetchingRequest->Specification(),
+                                                     taskRequest->Specification());
+        taskRequest->MarkAsBeingFulfilled();
+        }
+    else
+        {
+        CompleteTaskRequestEventSpecFetchingRequestL(KErrNotFound, aFetchingRequest->Specification(), NULL);
+        }
+    }
+
+void CEventMediatorServer::TaskCancellationObservationRequestArrivedL(CListenerContainer* aRequest)
+    {
+    LOG(Log::Printf(_L("CEventMediatorServer::TaskCancellationObservationRequestArrivedL\n")));
+    // Try to find a task request event type that corresponds to the received
+    // event type. This will only succeed if the received event type is
+    // one that is used to listen to the cancellation of a task request.
+    TEventType taskRequestEventType = CSit::FindTaskRequestEventType(aRequest->Type());
+
+    // If a corresponding task request type was found...
+    if (taskRequestEventType != EUnfoundEvent)
+        {
+        // Try to find the listener container of the task request
+        CListenerContainer* taskRequest = FindListener(taskRequestEventType, aRequest->Specification());
+
+        // The listener container for the task request was not found
+        // (i.e. the task request has been cancelled or the
+        // corresponding client session has been closed), so we
+        // complete the cancellation observation request right away
+        if (taskRequest == NULL)
+            {
+            ReportEventL(aRequest->Type(), aRequest->Specification(), NULL);
+            }
+        }
+    }
+
+void CEventMediatorServer::CompleteTaskArrivalObservationRequestL(TEventType aEventType, TDesC8* aSpec)
+    {
+    LOG(Log::Printf(_L("CEventMediatorServer::CompleteTaskArrivalObservationRequestL\n")));
+    if (iTaskArrivalListener)
+        {
+        // In SIT events, the event specification
+        // begins with the event specification ID
+        TEventSpec* sitEventSpec = (TEventSpec*)(aSpec->Ptr());
+        
+        TTaskArrivedEventData eventData;
+        eventData.iEventType = aEventType;
+        eventData.iEventSpecId = sitEventSpec->iId;
+        TPckg<TTaskArrivedEventData> eventDataDes(eventData);
+        
+        HBufC8* eventDataCopy = eventDataDes.AllocL();
+        CleanupStack::PushL(eventDataCopy);
+
+        ReportEventL(ETaskArrivedEvent, NULL, eventDataCopy);
+        
+        CleanupStack::Pop(); // eventDataCopy, freed elsewhere
+        }
+    }
+
+void CEventMediatorServer::CompleteTaskRequestEventSpecFetchingRequestL(TInt aStatus, TDesC8* aEventSpec,
+                                                                        TDesC8* aTaskRequestEventSpec)
+    {
+    LOG(Log::Printf(_L("CEventMediatorServer::CompleteTaskRequestEventSpecFetchingRequestL\n")));
+    // The event specification of the task request
+    // is returned to the SIT TH as event data
+    if (aTaskRequestEventSpec)
+        {
+        HBufC8* eventData = aTaskRequestEventSpec->AllocL();
+        CleanupStack::PushL(eventData);
+
+        ReportEventL(EFetchTaskInfoEvent, aEventSpec, eventData, aStatus);
+
+        CleanupStack::Pop(); // eventData, freed elsewhere
+        }
+    else
+        {
+        ReportEventL(EFetchTaskInfoEvent, aEventSpec, NULL, aStatus);
+        }
+    }
+    
+CListenerContainer* CEventMediatorServer::FindWaitingTaskRequest()
+    {
+    CEventMediatorSession* session;
+    iSessionIter.SetToFirst();
+    session = (CEventMediatorSession*) iSessionIter++;
+
+    CListenerContainer* listener = NULL;
+    
+    while (session != NULL)
+        {
+        listener = session->FindWaitingTaskRequest();
+        if (listener != NULL)
+            {
+            break;
+            }
+        session = (CEventMediatorSession*) iSessionIter++;
+        }
+
+    return listener;
+    }
+
+CListenerContainer* CEventMediatorServer::FindListener(TEventType aEventType,    
+                                                       TInt aEventSpecId)
+    {
+    CEventMediatorSession* session;
+    iSessionIter.SetToFirst();
+    session = (CEventMediatorSession*) iSessionIter++;
+
+    CListenerContainer* listener = NULL;
+    
+    while (session != NULL)
+        {
+        listener = session->FindListener(aEventType, aEventSpecId);
+        if (listener != NULL)
+            {
+            break;
+            }
+        session = (CEventMediatorSession*) iSessionIter++;
+        }
+
+    return listener;
+    }
+    
+CListenerContainer* CEventMediatorServer::FindListener(TEventType aEventType,    
+                                                       const TDesC8* aEventSpec)
+    {
+    CEventMediatorSession* session;
+    iSessionIter.SetToFirst();
+    session = (CEventMediatorSession*) iSessionIter++;
+
+    CListenerContainer* listener = NULL;
+    
+    while (session != NULL)
+        {
+        listener = session->FindListener(aEventType, aEventSpec);
+        if (listener != NULL)
+            {
+            break;
+            }
+        session = (CEventMediatorSession*) iSessionIter++;
+        }
+
+    return listener;
+    }
+
+void CEventMediatorServer::CompleteListener(TEventType aEventType, const TDesC8* aEventSpec, TInt aStatus)
+    {
+    CEventMediatorSession* session;
+    iSessionIter.SetToFirst();
+    session = (CEventMediatorSession*) iSessionIter++;
+
+    while (session != NULL)
+        {
+        session->CompleteListener(aEventType, aEventSpec, aStatus);
+        session = (CEventMediatorSession*) iSessionIter++;
+        }
+    }
+
+TInt CEventMediatorServer::NormalSessionCount()
+    {
+    TInt normalSessionCount = 0;
+    
+    CEventMediatorSession* session;
+    iSessionIter.SetToFirst();
+    session = (CEventMediatorSession*) iSessionIter++;
+
+    while (session != NULL)
+        {
+        if (!(session->IsASitSession()))
+            {
+            normalSessionCount++;
+            }
+        session = (CEventMediatorSession*) iSessionIter++;
+        }
+
+    return normalSessionCount;
+    }
+
+TInt CEventMediatorServer::NewEventSpecId()
+    {
+    return ++iNextEventSpecId;
+    }
+
+TPtrC CEventMediatorServer::EventLogFileName(void)
+    {
+    TPtrC name(iEventLogFileName);
+    return name;
+    }
+    
+void CEventMediatorServer::SitDied()
+    {
+    LOG(Log::Printf(_L("CEventMediatorServer::SitDied\n")));
+    CompleteTaskRequests(KErrDied);
+    }
+    
+void CEventMediatorServer::CompleteTaskRequests(TInt aStatus)
+    {
+    LOG(Log::Printf(_L("CEventMediatorServer::CompleteTaskRequests\n")));    
+    CEventMediatorSession* session;
+    iSessionIter.SetToFirst();
+    session = (CEventMediatorSession*) iSessionIter++;
+
+    while (session != NULL)
+        {
+        session->CompleteTaskRequests(aStatus);
+        session = (CEventMediatorSession*) iSessionIter++;
+        }
+    }
+
+void CEventMediatorServer::SetShuttingDown(TBool aShuttingDown)
+    {
+    iShuttingDown = aShuttingDown;
+    }
+
+// ============================= CEventMediatorSession =============================     
+
+CEventMediatorSession* CEventMediatorSession::NewL(CEventMediatorServer* aServer, const RMessage2& aMessage)
+    {
+    LOG(Log::Printf(_L("CEventMediatorSession::NewL - begin\n")));
+    CEventMediatorSession* self;
+    self = new (ELeave) CEventMediatorSession(aServer);
+    CleanupStack::PushL(self);
+
+    // Marks the session as a "SIT session"
+    // if the client is the SIT thread
+    self->iIsSitSession = aServer->IsClientTheSitL(aMessage);
+
+    aServer->iSessionCount++;
+
+    if ( !self->IsASitSession() )
+        {
+        User::LeaveIfError(self->iFs.Connect()); // For EventLog
+        self->iEventLogFileOpen = EFalse;
+        }
+
+    CleanupStack::Pop(); // self
+
+    LOG(Log::Printf(_L("CEventMediatorSession::NewL - end\n")));
+    return self;
+    }
+
+CEventMediatorSession::CEventMediatorSession(CEventMediatorServer* aServer)
+    : iListenedEvents(2), iServer(aServer)
+    {
+    }
+
+CEventMediatorSession::~CEventMediatorSession(void)
+    {
+    LOG(Log::Printf(_L("CEventMediatorSession::~CEventMediatorSession\n")));
+    CancelAll();
+    if (iServer)
+        {        
+        TInt normalSessionCount = iServer->NormalSessionCount();
+
+        // If this too is a normal session and is dying,
+        // decrement the normal session count by one
+        if (!IsASitSession())
+            {
+            normalSessionCount--;
+            
+            if (iEventLogFileOpen)
+                {
+                iEventLogFile.Close();
+                iEventLogFileOpen = EFalse;
+                }
+            iFs.Close(); // For EventLog
+            
+            }
+
+        if (normalSessionCount == 0)
+            {
+            // If "normal" (non-sit) sessions are no longer present,
+            // we complete the task arrival observation request, thus
+            // causing the SIT to terminate and close its connection
+            // to this server. This should be the last connection whose
+            // closing will cause this server to terminate.
+            // NOTE. KErrCancel cannot be used here as the Event Mediator 
+            // does not report it to the caller
+            LOG(Log::Printf(_L("CEventMediatorSession::~CEventMediatorSession - normal session count = 0\n")));
+            iServer->CompleteListener(ETaskArrivedEvent, NULL, KErrAbort);
+
+            // Set the server state to "shutting down". This will
+            // cause the server to discard any new connect requests
+            // with KErrServerTerminated.
+            iServer->SetShuttingDown(ETrue);
+            }
+
+        if (iServer->iSessionCount)
+            {
+            iServer->iSessionCount--;
+            }
+
+        iServer->StopEventMediator();
+        }
+    }
+
+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;
+    }
+
+
+    
+// ============================= CEventMediatorServer =============================    
+
+CListenerContainer::CListenerContainer(const RMessage2& aMessage, TDesC8* aSpec,
+                                       CEventMediatorServer* aServer)
+    : iSpec(aSpec), iMessage(aMessage), iServer(aServer)
+    {
+    iEventType = Type();
+    }
+
+void CListenerContainer::AnalyzeRequestL()
+    {
+    LOG(Log::Printf(_L("CListenerContainer::AnalyzeRequestL\n")));
+    if (CSit::EventRequiresSit(iEventType))
+        {
+        LOG(Log::Printf(_L("CListenerContainer::AnalyzeRequestL - event type = %d, requires SIT\n"), iEventType));
+        iServer->MakeSureSitIsRunningL();
+        iServer->TaskRequestArrivedL(this);
+        }
+
+    // If this event listening request is the one
+    // made by the SIT task arrival observer...
+    if (iEventType == ETaskArrivedEvent)
+        {
+        iServer->SetTaskArrivalListenerL(this);
+        iServer->TaskArrivalObservationRequestArrivedL();
+        }
+
+    // If this event listening request is one
+    // made by a SIT TH to fetch a task...
+    if (iEventType == EFetchTaskInfoEvent)
+        {
+        iServer->TaskRequestEventSpecFetchingRequestArrivedL(this);
+        }
+
+    // If the event listening request is one
+    // made by a SIT TH to listen to the cancellation
+    // of the task request it is handling
+    if (CSit::IsTaskCancellationObservationRequest(iEventType))
+        {
+        iServer->TaskCancellationObservationRequestArrivedL(this);
+        }
+    }
+    
+CListenerContainer::~CListenerContainer()
+    {
+    delete iSpec;
+
+    if (iServer->TaskArrivalListener() == this)
+        {
+        iServer->ClearTaskArrivalListener();
+        }
+    }
+
+TBool CListenerContainer::HandlesEvent(TEventType aEventType, const TDesC8* aEventSpec)
+    {
+    if (iEventType == aEventType)
+        {
+        // Specs are same if both are NULL
+        if (iSpec == NULL && aEventSpec == NULL)
+            {
+            return ETrue;
+            }
+        // or data in buffers are identical
+        else if (iSpec != NULL && aEventSpec != NULL && (*iSpec) == (*aEventSpec))
+            {
+            return ETrue;
+            }
+        }
+    return EFalse;
+    }
+    
+void CListenerContainer::Complete(TInt status)
+    {
+    // If there's a SIT fulfilling this event listening
+    // request (i.e. if this is a task request) and this
+    // task request is being cancelled...
+    if (status == KErrCancel)
+        {
+        // See if we can find a task request cancellation observation
+        // event type that corresponds to this event type
+        TEventType cancelEventType = CSit::FindCancelEventType(iEventType);
+        
+        if (cancelEventType != EUnfoundEvent)
+            {
+            // Complete the task request cancellation
+            // observation, if found
+            iServer->CompleteListener(cancelEventType, iSpec, KErrNone);
+            }
+        }
+    
+    iMessage.Complete(status);
+    }
+
+TBool CListenerContainer::WaitingForFulfilling()
+    {
+    if (CSit::EventRequiresSit(iEventType) && !iBeingFulfilledBySit)
+        {
+        return ETrue;
+        }
+    else
+        {
+        return EFalse;
+        }
+    }
+
+void CListenerContainer::MarkAsBeingFulfilled()
+    {
+    iBeingFulfilledBySit = ETrue;
+    }
+
+TBool CListenerContainer::BeingFulfilled()
+    {
+    return iBeingFulfilledBySit;
+    }