mediator/src/Server/MediatorServer.cpp
changeset 0 4e1aa6a622a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mediator/src/Server/MediatorServer.cpp	Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,463 @@
+/*
+* Copyright (c) 2005 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:  Main functions to start the server
+*
+*/
+
+
+#include    <e32base.h>
+#include    <barsc.h>       // RResourceFile
+#include    <barsread.h>    // TResourceReader
+
+#include    "MediatorServer.h"
+#include    "MediatorCommon.h"
+#include    "MediatorServerSession.h"
+#include    "MediatorServerEventHandler.h"
+#include    "MediatorServerCommandHandler.h"
+#include    "MediatorServerObjectHandler.h"
+#include    "MediatorServerPluginHandler.h"
+
+#include    <allowedsids.rsg>
+#include    "MediatorDebug.h"
+#include    "Debug.h"
+
+// CONSTANTS
+// Resource directory
+_LIT(KResourceEventDir, "z:\\private\\10207449\\events\\");
+
+// Resource file containing exceptionally handled SIDs
+_LIT(KAllowedSidsFile, "z:\\private\\10207449\\allowedsids.rsc");
+
+// Domain resource index ( = 1)
+const TInt KEventResourceIndex  = 1;
+
+// Version number count within TVersion structure
+const TInt KVersionNumberCount  = 3;
+
+// NAMESPACE
+using namespace MediatorService;
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CMediatorServer::CMediatorServer
+// -----------------------------------------------------------------------------
+//
+CMediatorServer::CMediatorServer()
+	: CPolicyServer( CActive::EPriorityHigh, KMediatorServerPolicy )
+	{
+	LOG(_L("[Mediator Server]\t CMediatorServer::CMediatorServer"));
+	}
+
+// -----------------------------------------------------------------------------
+// CMediatorServer::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CMediatorServer::ConstructL()
+    {
+    LOG(_L("[Mediator Server]\t CMediatorServer::ConstructL"));
+    StartL( KMediatorServerName );
+    
+    // Create object, event and command handlers
+    iObjectHandler = CMediatorServerObjectHandler::NewL();
+    iEventHandler = CMediatorServerEventHandler::NewL( *iObjectHandler );
+    iCommandHandler = CMediatorServerCommandHandler::NewL( *iObjectHandler );
+    iPluginHandler = CMediatorServerPluginHandler::NewL();
+    
+    RFs fsSession;
+    User::LeaveIfError( fsSession.Connect() );
+    CleanupClosePushL( fsSession );
+    
+    // Do static event registrations
+    ProcessResourceEventsL( fsSession );
+    
+    // read SIDs
+    ReadAllowedSidsFileL( fsSession );
+    
+    CleanupStack::PopAndDestroy( &fsSession );
+    
+    RMediatorDebug::Initialize( this );
+    
+    LOG(_L("[Mediator Server]\t CMediatorServer::ConstructL end"));
+    }
+
+// -----------------------------------------------------------------------------
+// CMediatorServer::NewLC
+// -----------------------------------------------------------------------------
+//
+CMediatorServer* CMediatorServer::NewLC()
+	{
+	LOG(_L("[Mediator Server]\t CMediatorServer::NewLC"));
+	CMediatorServer *self = new (ELeave) CMediatorServer();
+	CleanupStack::PushL( self );
+	self->ConstructL();
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CMediatorServer::~CMediatorServer
+// -----------------------------------------------------------------------------
+//    
+CMediatorServer::~CMediatorServer()
+	{
+	RMediatorDebug::Uninitialize();
+	
+	LOG(_L("[Mediator Server]\t CMediatorServer::~CMediatorServer"));
+	delete iEventHandler;
+	delete iCommandHandler;
+	delete iObjectHandler;
+	delete iPluginHandler;
+	iAllowedSids.Close();
+	}
+
+
+// -----------------------------------------------------------------------------
+// CMediatorServer::NewSessionL
+// Creates a new session to the server if version information is correct.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CSession2 *CMediatorServer::NewSessionL( const TVersion &aVersion, 
+										 const RMessage2 &/*aMessage*/) const
+	{
+	LOG(_L("[Mediator Server]\t CMediatorServer::NewSessionL"));
+	// check we're the right version
+	TVersion version( KMediatorServerMajor, 
+					  KMediatorServerMinor, 
+					  KMediatorServerBuild);
+	if( !User::QueryVersionSupported( version, aVersion ) )
+	    {
+	    ERROR_LOG(_L("[Mediator] CMediatorServer::NewSessionL: Version conflict!\n") );
+	    ERROR_TRACE(Print(_L("[Mediator] Current version:%d.%d.%d\n"), version.iMajor, version.iMinor, version.iBuild ) );
+	    ERROR_TRACE(Print(_L("[Mediator] Connected version:%d.%d.%d\n"), aVersion.iMajor, aVersion.iMinor, aVersion.iBuild ) );
+	    User::Leave( KErrNotSupported );
+	    }
+		
+	// make new session
+	return CMediatorServerSession::NewL();
+	}
+
+// -----------------------------------------------------------------------------
+// CMediatorServer::EventHandler
+// Returns a reference to event handler
+// -----------------------------------------------------------------------------
+//
+CMediatorServerEventHandler& CMediatorServer::EventHandler()
+    {
+    __ASSERT_DEBUG( iEventHandler, PanicServer( EMediatorServerNoEventHandler ));
+    return *iEventHandler;
+    }
+        
+// -----------------------------------------------------------------------------
+// CMediatorServer::EventHandler
+// Returns a reference to command handler
+// -----------------------------------------------------------------------------
+//
+CMediatorServerCommandHandler& CMediatorServer::CommandHandler()
+    {
+    __ASSERT_DEBUG( iCommandHandler, PanicServer( EMediatorServerNoCommandHandler ));
+    return *iCommandHandler;
+    }
+
+// -----------------------------------------------------------------------------
+// CMediatorServer::ObjectHandler
+// Returns a reference to object handler
+// -----------------------------------------------------------------------------
+//
+CMediatorServerObjectHandler& CMediatorServer::ObjectHandler()
+    {
+    __ASSERT_DEBUG( iObjectHandler, PanicServer( EMediatorServerNoObjectHandler ));
+    return *iObjectHandler;
+    }
+
+// -----------------------------------------------------------------------------
+// CMediatorServer::PluginHandler
+// Returns a reference to plugin handler
+// -----------------------------------------------------------------------------
+//
+CMediatorServerPluginHandler& CMediatorServer::PluginHandler()
+    {
+    __ASSERT_DEBUG( iPluginHandler, PanicServer( EMediatorServerNoPluginHandler ));
+    return *iPluginHandler;
+    }
+
+// -----------------------------------------------------------------------------
+// CMediatorServer::CustomSecurityCheckL
+// Performs a custom security check.
+// -----------------------------------------------------------------------------
+//
+
+CPolicyServer::TCustomResult CMediatorServer::CustomSecurityCheckL( const RMessage2& aMsg, 
+                                                                    TInt& /*aAction*/,
+                                                                    TSecurityInfo& /*aMissing*/ )
+    {
+    LOG(_L("[Mediator Server]\t CMediatorServer::CustomSecurityCheckL"));
+    // firstly check if this SwEvent capability, which is OK
+    if ( aMsg.HasCapability( ECapabilitySwEvent ) )
+        {
+        return EPass;
+        }
+    
+    // secondly check if special treatment for this SID is allowed
+    if ( AllowCapabilityException( static_cast<TUid>( aMsg.SecureId() ) ) )
+        {
+        return EPass;
+        }
+    
+    ERROR_TRACE(Print(_L("[Mediator] CMediatorServer::CustomSecurityCheckL: security check fail for client 0x%08X\n"), aMsg.SecureId().iId));
+
+    // client has no right to send this message
+    return EFail;
+    }
+
+// -----------------------------------------------------------------------------
+// CMediatorServer::ProcessResourceEventsL
+// Does static event resource registration processing
+// -----------------------------------------------------------------------------
+//
+void CMediatorServer::ProcessResourceEventsL( RFs& aFsSession )
+    {
+    LOG(_L("[Mediator Server]\t CMediatorServer::ProcessResourceEventsL"));
+    
+    // Gather all files from registration directory
+    CDir* resourceList;
+	
+    TInt err = aFsSession.GetDir( KResourceEventDir,
+		                         KEntryAttNormal,
+		                         ESortByName, 
+		                         resourceList );
+    
+    // If events-directory does not exist, it means that there are no static events registered
+    if ( err != KErrNone && err != KErrPathNotFound )
+        {
+        ERROR_TRACE(Print(_L("[Mediator] CMediatorServer::ProcessResourceEventsL: err=%d\n"), err ) );
+        User::Leave( err );
+        }
+    
+    if ( err != KErrPathNotFound )    		                                  
+        {
+        CleanupStack::PushL( resourceList );
+        TRACE(Print(_L("[Mediator Server]\t ProcessResourceEventsL file count %d\n"), resourceList->Count() ));
+    
+        // Loop through the resource files and process the resources
+        for ( TInt index = 0; index < resourceList->Count(); index++ )
+            {
+            TEntry resourceFile = (*resourceList)[ index ];
+            TBufC<KMaxFileName> fileName = resourceFile.iName;
+            // TRAP error, but continue
+            TRAPD( error, ProcessResourceFileL( aFsSession, fileName ) );
+            
+            if ( error != KErrNone )
+                {
+                ERROR_TRACE(Print(_L("[Mediator] CMediatorServer::ProcessResourceEventsL: error=%d\n"), error ) );
+                }
+                
+            TRACE(Print(_L("[Mediator Server]\t ProcessResourceEventsL file %d process status %d\n"), index, error )); 
+            }
+        CleanupStack::PopAndDestroy( resourceList );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMediatorServer::ProcessResourceFileL
+// Processes one resource file
+// -----------------------------------------------------------------------------
+//
+void CMediatorServer::ProcessResourceFileL( RFs& aFsSession, const TDesC& aFileName )
+    {
+    LOG(_L("[Mediator Server]\t CMediatorServer::ProcessResourceFileL"));
+    
+    // Parse full file name
+    TParse parse;
+    parse.Set( aFileName, &KResourceEventDir, NULL );
+    TFileName fullName = parse.FullName();
+    
+    // Get this thread's secure id
+    RThread thread = RThread();
+    TSecureId secureId = thread.SecureId();
+    
+    // Open resource file
+    RResourceFile resourceFile;
+    resourceFile.OpenL( aFsSession, fullName );
+	CleanupClosePushL( resourceFile );
+		
+    // Read resource information		
+	HBufC8* domainResource = resourceFile.AllocReadLC( KEventResourceIndex );
+	TResourceReader reader;
+	reader.SetBuffer( domainResource );
+	
+	// Read domain from resource
+	TUid domainUid = TUid::Uid( reader.ReadInt32() );
+	// Process categories
+	TInt categoryCount = reader.ReadInt16();
+	for ( TInt index = 0; index < categoryCount; index++ )
+	    {
+	    TUid categoryUid = TUid::Uid( reader.ReadInt32() );
+	    // Process events within category
+	    TInt eventCount = reader.ReadInt16();
+	    REventList eventList;
+	    for ( TInt index2 = 0; index2 < eventCount; index2++ )
+	        {
+	        MediatorService::TEvent newEvent = ReadEvent( reader );
+	        eventList.AppendL( newEvent );
+	        }
+	    // Register events to event handler, if there's something to register
+	    if ( eventList.Count() > 0 )
+	        {
+	        TMediatorCategory newCategory;
+    	    newCategory.iDomain = domainUid;
+    	    newCategory.iCategory = categoryUid;
+    	    // TRAP error, but continue anyway
+    	    TRAPD( error, 
+    	           EventHandler().RegisterEventListL( newCategory, 
+    	                                              eventList, 
+    	                                              secureId ) );
+            
+            if ( error != KErrNone )
+                {
+                ERROR_TRACE(Print(_L("[Mediator] CMediatorServer::ProcessResourceFileL: error=%d\n"), error ) );
+                }
+            
+    	                                              
+    	    TRACE(Print(_L("[Mediator Server]\t ProcessResourceFileL events registered with status %d\n"), error ));                                          
+	        }  
+	    eventList.Close();
+	    }
+		
+	CleanupStack::PopAndDestroy( domainResource);
+	CleanupStack::PopAndDestroy( &resourceFile );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMediatorServer::ReadEvent
+// Reads one event from resource
+// -----------------------------------------------------------------------------
+//
+MediatorService::TEvent CMediatorServer::ReadEvent( TResourceReader& aReader )
+    {
+    MediatorService::TEvent newEvent;
+    
+    // Read Event id
+    newEvent.iEventId =  aReader.ReadInt16();
+    
+    TRACE(Print(_L("[Mediator Server]\t ProcessResourceFileL new event id %d\n"), newEvent.iEventId )); 
+    
+    // Read required capabilities
+    TCapabilitySet capabilitySet;
+    capabilitySet.SetEmpty();
+    TInt capabilityCount = aReader.ReadInt16();
+    for ( TInt index = 0; index < capabilityCount; index++ )
+        {
+        TCapability newCapability = (TCapability) aReader.ReadInt16();
+        capabilitySet.AddCapability( newCapability );  
+        }
+    newEvent.iCaps = capabilitySet;
+    
+    // Read version information
+    TInt versionCount = aReader.ReadInt16();
+    if ( versionCount == KVersionNumberCount ) // Should have 3 values in version structure
+        {
+        TInt major = aReader.ReadInt16();
+        TInt minor = aReader.ReadInt16();
+        TInt build = aReader.ReadInt16();
+        newEvent.iVersion = TVersion( major, minor, build );
+        }
+    else
+        {
+        ERROR_TRACE(Print(_L("[Mediator] CMediatorServer::ReadEvent: Event %d has invalid data, versionCount=%d\n"), newEvent.iEventId, versionCount ) );
+        // Something wrong with the resource --> use zeros as version info
+        newEvent.iVersion = TVersion( 0, 0, 0 );
+        }    
+    // Return event 
+    return newEvent;
+    }
+
+// -----------------------------------------------------------------------------
+// CMediatorServer::ReadAllowedSidsFileL
+// Read resource file containing exeptionally handled SIDs
+// -----------------------------------------------------------------------------
+//
+void CMediatorServer::ReadAllowedSidsFileL( RFs& aFsSession )
+    {
+    LOG(_L("[Mediator Server]\t CMediatorServer::ReadAllowedSidsFileL"));
+    
+    // read settings from resource files
+    TFileName resourceFileName (KAllowedSidsFile);
+    
+    RResourceFile resourceFile;
+    resourceFile.OpenL(aFsSession, resourceFileName);
+    
+    CleanupClosePushL(resourceFile);
+    
+    // Read the SID structure
+    HBufC8* res = resourceFile.AllocReadLC(SID_INFO);
+    TResourceReader theReader;
+    theReader.SetBuffer(res);
+
+    TInt sidCount = theReader.ReadUint16();
+    
+    // read SIDs
+    TUid sid;
+        
+    for (TInt i = 0; i < sidCount; i++)
+        {
+        sid.iUid = theReader.ReadUint32();
+        TRACE(Print(_L("[Mediator Server]\t Allowed SID: 0x%08X\n"), sid.iUid)); 
+        User::LeaveIfError( iAllowedSids.Append( sid ) );
+        }    
+    
+    CleanupStack::PopAndDestroy( res );
+    CleanupStack::PopAndDestroy( &resourceFile );
+    }
+
+// -----------------------------------------------------------------------------
+// CMediatorServer::AllowCapabilityException
+// Returns whether capability requirements can be ignored for the specified client.
+// -----------------------------------------------------------------------------
+//
+TBool CMediatorServer::AllowCapabilityException( const TUid& aSid )
+    {
+    return ( ( iAllowedSids.Find ( aSid ) != KErrNotFound ) ? ETrue : EFalse );
+    }
+
+    
+// -----------------------------------------------------------------------------
+// PanicServer
+// Server panic handler
+// Panic our own thread
+// -----------------------------------------------------------------------------
+//
+void CMediatorServer::PanicServer(TInt aPanic)
+    {
+    ERROR_TRACE(Print(_L("[Mediator] CMediatorServer::PanicServer: Reason = %d\n"), aPanic));
+    User::Panic( KMediatorServerPanic, aPanic );
+    }
+
+// -----------------------------------------------------------------------------
+// PanicClient
+// Client panic handler
+// RMessage2::Panic() also completes the message. This is:
+// (a) important for efficient cleanup within the kernel
+// (b) a problem if the message is completed a second time
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMediatorServer::PanicClient( const RMessage2& aMessage, TInt aPanic )
+    {
+    ERROR_TRACE(Print(_L("[Mediator] CMediatorServer::PanicClient: Reason = %d\n"), aPanic));
+    aMessage.Panic( KMediatorServerPanic, aPanic );
+    }
+
+// End of File