mtpfws/mtpfw/daemon/server/src/cmtpserver.cpp
author hgs
Thu, 04 Nov 2010 15:31:42 +0800
changeset 60 841f70763fbe
parent 52 866b4af7ffbe
permissions -rw-r--r--
201044_04

// Copyright (c) 2006-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:
//

/**
 @file
 @internalTechnology
*/

#include <ecom/ecom.h>

#include "cmtpconnectionmgr.h"
#include "cmtpdataprovidercontroller.h"
#include "cmtpserver.h"
#include "cmtpserversession.h"
#include "cmtpshutdown.h"
#include "mtpclientserver.h"
#include "mtpdebug.h"
#include "rmtpframework.h"
#include "OstTraceDefinitions.h"
#ifdef OST_TRACE_COMPILER_IN_USE
#include "cmtpserverTraces.h"
#endif


#define UNUSED_VAR(a) (a) = (a)

/**
PlatSec policy.
*/ 
const TUint8 KMTPPolicyElementNetworkAndLocal = 0;

const TInt KMTPFunctionCodeRanges[] = 
    {    
    EMTPClientStartTransport, 
    EMTPClientNotSupported,
    };

const TUint KMTPFunctionCodeRangeCount(sizeof(KMTPFunctionCodeRanges) / sizeof(KMTPFunctionCodeRanges[0]));

const TUint8 KMtpElementsIndex[KMTPFunctionCodeRangeCount] =
    {
    KMTPPolicyElementNetworkAndLocal,
    CPolicyServer::ENotSupported,
    };

const CPolicyServer::TPolicyElement KMtpPolicyElements[] = 
    { 
    {_INIT_SECURITY_POLICY_C2(ECapabilityNetworkServices, ECapabilityLocalServices), CPolicyServer::EFailClient},
    };

const static CPolicyServer::TPolicy KMTPServerPolicy =
    {
    CPolicyServer::EAlwaysPass, //specifies all connect attempts should pass
    KMTPFunctionCodeRangeCount,
    KMTPFunctionCodeRanges,
    KMtpElementsIndex,     // what each range is compared to 
    KMtpPolicyElements     // what policies range is compared to
    };
    
/**
Destructor.
*/
CMTPServer::~CMTPServer()
    {
    OstTraceFunctionEntry0( CMTPSERVER_CMTPSERVER_DES_ENTRY ); 
    delete iShutdown;
    iShutdown = NULL;
    if(iFrameworkSingletonsOpened)
        {
        iFrameworkSingletons.ConnectionMgr().StopTransports();
        iFrameworkSingletons.DpController().UnloadDataProviders();
        iFrameworkSingletons.Close();	 
        iFrameworkSingletonsOpened = EFalse;
        }
    REComSession::FinalClose();
    OstTraceFunctionExit0( CMTPSERVER_CMTPSERVER_DES_EXIT );
    }

/**
Creates and executes a new CMTPServer instance.
@leave One of the system wide error codes, if a processing failure occurs.
*/
void CMTPServer::RunServerL()
    {
    OstTraceFunctionEntry0( CMTPSERVER_RUNSERVERL_ENTRY );
    
    // Naming the server thread after the server helps to debug panics
    TInt ret = User::RenameProcess(KMTPServerName);
    LEAVEIFERROR(ret, OstTrace0(TRACE_ERROR, CMTPSERVER_RUNSERVERL, "Rename process error"));
    
    // Create and install the active scheduler.
    CActiveScheduler* scheduler(new(ELeave) CActiveScheduler);
    CleanupStack::PushL(scheduler);
    CActiveScheduler::Install(scheduler);
    
    // Create the server and leave it on the cleanup stack.
    CMTPServer* server(CMTPServer::NewLC());
    
    // Initialisation complete, signal the client
    RProcess::Rendezvous(KErrNone);
    
    // Execute the server.
    OstTraceDef0( OST_TRACE_CATEGORY_PRODUCTION, TRACE_IMPORTANT, DUP1_CMTPSERVER_RUNSERVERL, "MTP server starts up" );
    CActiveScheduler::Start();
    OstTraceDef0( OST_TRACE_CATEGORY_PRODUCTION, TRACE_IMPORTANT, DUP2_CMTPSERVER_RUNSERVERL, "MTP server closed" );

	// Server shutting down. 
	CleanupStack::PopAndDestroy(server);
        
    CleanupStack::PopAndDestroy(1); // scheduler
    OstTraceFunctionExit0( CMTPSERVER_RUNSERVERL_EXIT );
    } 

/**
Adds a new CMTPServer session.
*/
void CMTPServer::AddSession()
    {  
    OstTraceFunctionEntry0( CMTPSERVER_ADDSESSION_ENTRY );
    if(iShutdown && iShutdown->IsActive())
        {  
        iShutdown->Cancel();
        }
    ++iSessionCount;
    OstTraceFunctionExit0( CMTPSERVER_ADDSESSION_EXIT );
    }

/**
Removes a CMTPServer session. If there are no active MTP client API sessions 
remaining and no active MTP connections, then a shutdown timer is started to 
terminate the server thread.
*/
void CMTPServer::DropSession()
    {
    OstTraceFunctionEntry0( CMTPSERVER_DROPSESSION_ENTRY );
         
    if (--iSessionCount==0 && iFrameworkSingletonsOpened && iFrameworkSingletons.ConnectionMgr().TransportCount() == 0)
        {
        // No active MTP client API sessions remain, start the shutdown timer.
        if (iShutdown)
            {
            OstTrace0( TRACE_NORMAL, CMTPSERVER_DROPSESSION, "Shutdown Started" );           
            iShutdown->Start();
            }
        }
    OstTraceFunctionExit0( CMTPSERVER_DROPSESSION_EXIT );
    }
    
CSession2* CMTPServer::NewSessionL(const TVersion&,const RMessage2&) const
    {
    OstTraceFunctionEntry0( CMTPSERVER_NEWSESSIONL_ENTRY );
    OstTraceFunctionExit0( CMTPSERVER_NEWSESSIONL_Exit );
    return new(ELeave) CMTPServerSession();
    }
       
/**
CMTPServer factory method. A pointer to the constructed CMTPServer instance is
placed on the cleanup stack.
@return A pointer to a new CMTPServer instance. Ownership IS transfered.
@leave One of the system wide error codes if a processing failure occurs.
*/
CMTPServer* CMTPServer::NewLC()
    {
    CMTPServer* self=new(ELeave) CMTPServer;
    CleanupStack::PushL(self);
    self->ConstructL();
    return self;
    }

/**
Constructor.
*/    
CMTPServer::CMTPServer() : 
    CPolicyServer(CActive::EPriorityStandard, KMTPServerPolicy),iFrameworkSingletonsOpened(EFalse)
    {

    }
    
/**
second-phase constructor.
*/
void CMTPServer::ConstructL()
    {
    OstTraceFunctionEntry0( CMTPSERVER_CONSTRUCTL_ENTRY );
    StartL(KMTPServerName);
    iFrameworkSingletons.OpenL();
    iFrameworkSingletonsOpened = ETrue;
    if (!iShutdown)
        {
        TRAPD(error, iShutdown = CMTPShutdown::NewL());
        OstTrace0( TRACE_NORMAL, CMTPSERVER_CONSTRUCTL, "CMTPShutdown Loaded" );            
        UNUSED_VAR(error);    
        }    
    OstTraceFunctionExit0( CMTPSERVER_CONSTRUCTL_EXIT );
    }
        
/*
RMessage::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
@param aMessage Message to be paniced.
@param aPanic Panic code.
*/
void PanicClient(const RMessagePtr2& aMessage,TMTPPanic aPanic)
    {
    OstTraceFunctionEntry0( _PANICCLIENT_ENTRY );
    OstTraceDef1(OST_TRACE_CATEGORY_PRODUCTION, TRACE_IMPORTANT, _PANICCLIENT, "Panic = %d", aPanic );
    
    _LIT(KPanic,"MTPServer");
    aMessage.Panic(KPanic, aPanic);
    OstTraceFunctionExit0( _PANICCLIENT_EXIT );
    }

/**
Process entry point
*/
TInt E32Main()
    {
    __UHEAP_MARK;
    OstTraceFunctionEntry0( CMTPSERVER_E32MAIN_ENTRY );
#ifdef OST_TRACE_COMPILER_IN_USE
    __MTP_HEAP_OSTTRACE(OstTraceExt4(TRACE_NORMAL,CMTPSERVER_E32MAIN_HEAP,"Heap: Size = %d, Allocated = %d, Available = %d, Largest block = %d", size, allocated, available, largest));
#endif
    
    CTrapCleanup* cleanup=CTrapCleanup::New();
    TInt ret = KErrNoMemory;
    if (cleanup)
        {
#ifdef __OOM_TESTING__
        TInt i = 0;
        while (ret == KErrNoMemory || ret == KErrNone)
             {
             __UHEAP_SETFAIL(RHeap::EDeterministic,i++);
             __UHEAP_MARK;

             TRAP(nRet, RunServerL());

             __UHEAP_MARKEND;
             __UHEAP_RESET;
             }
#else
        TRAP(ret, CMTPServer::RunServerL());
      
#endif        
        delete cleanup;
        }
    
    OstTraceFunctionExit0( CMTPSERVER_E32MAIN_EXIT );
    __UHEAP_MARKEND;

    return ret;
    }