diff -r 000000000000 -r a41df078684a userlibandfileserver/fileserver/shostmassstorage/server/src/cusbhostmssession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/userlibandfileserver/fileserver/shostmassstorage/server/src/cusbhostmssession.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,206 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "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 +#include +#include +#include "msctypes.h" +#include "mscutils.h" +#include "shared.h" +#include "msgservice.h" +#include "cusbhostmslogicalunit.h" +#include "cusbhostmsdevice.h" +#include "cusbhostmsserver.h" +#include "usbmshostpanic.h" +#include "cusbhostmsdevicethread.h" +#include "cusbhostmssession.h" +#include "msdebug.h" +#include "debug.h" + +/** Construct a Symbian OS session object. + + param aServer Service the session will be a member of + param aMessage The message from the client. + return A new CUsbHostMsSession object + */ +CUsbHostMsSession* CUsbHostMsSession::NewL(CUsbHostMsServer& aServer) + { + __MSFNSLOG + CUsbHostMsSession* r = new (ELeave) CUsbHostMsSession(aServer); + CleanupStack::PushL(r); + r->ConstructL(); + CleanupStack::Pop(); + return r; + } + +/** + Constructor. + + param aServer Service the session will be a member of + */ +CUsbHostMsSession::CUsbHostMsSession(CUsbHostMsServer& aServer) + : iUsbHostMsServer(aServer) + { + __MSFNLOG + iMsgCount = 0; + } + + +/** + 2nd Phase Construction. + */ +void CUsbHostMsSession::ConstructL() + { + __MSFNLOG + iUsbHostMsServer.IncrementSessionCount(); + __HOSTPRINT1(_L("\tiSessionCount: %d\n"), iUsbHostMsServer.SessionCount()); + } + + +/** + Destructor. + */ +CUsbHostMsSession::~CUsbHostMsSession() + { + __MSFNLOG + + iUsbHostMsServer.DecrementSessionCount(); + iThread.Close(); + __HOSTPRINT1(_L("\tClosed a session -> iSessionCount: %d\n"), iUsbHostMsServer.SessionCount()); + } + +/** + Called when a message is received from the client. + + param aMessage Message received from the client + */ +void CUsbHostMsSession::ServiceL(const RMessage2& aMessage) + { + __MSFNLOG + DispatchMessageL(aMessage); + } + + +/** + Handles the request (in the form of a message) received from the client + + param aMessage The received message + */ +void CUsbHostMsSession::DispatchMessageL(const RMessage2& aMessage) + { + __MSFNLOG + TInt r = KErrNone; + switch (aMessage.Function()) + { + case EUsbHostMsRegisterInterface: + TRAP(r, CreateDeviceThreadL(aMessage)); + if(r != KErrNone) + { + aMessage.Complete(r); + return; + } + break; + /* If it is a cleanup then we need to delete the iDeviceThread */ + case EUsbHostMsFinalCleanup: + if(iDeviceThread->IsActive()) + { + TRequestStatus* s=&iDeviceThread->iStatus; + iThread.RequestComplete(s, KErrSessionClosed); + } + iDeviceThread->Cancel(); + delete iDeviceThread; + iThread.Kill(KErrNone); + aMessage.Complete(KErrNone); + return; + default: + break; + } + + __HOSTPRINT1(_L("Queuing %d message"), ++iMsgCount); + __ASSERT_DEBUG(iDeviceThread != NULL, User::Panic(KUsbMsHostPanicCat, EDeviceThreadDoesNotExist)); + + r = iDeviceThread->QueueMsg(aMessage); + if(r != KErrNone) + { + aMessage.Complete(r); + return; + } + + if(iDeviceThread->IsActive()) + { + iDeviceThread->Lock(); + if(iDeviceThread->iIsSignalled) + { + iDeviceThread->Unlock(); + return; + } + iDeviceThread->iIsSignalled = ETrue; + iDeviceThread->Unlock(); + __HOSTPRINT(_L("Signaling device thread to handle message")); + TRequestStatus* s=&iDeviceThread->iStatus; + iThread.RequestComplete(s, KErrNone); + } + } + + +void CUsbHostMsSession::CreateDeviceThreadL(const RMessage2& aMessage) + { + THostMassStorageConfig msDeviceConfig; + TPtr8 ptr((TUint8*)&msDeviceConfig,sizeof(THostMassStorageConfig)); + + aMessage.ReadL(0, ptr); + __HOSTPRINT1(_L("EUsbHostMsRegisterInterface Token=%d "), msDeviceConfig.iInterfaceToken); + + TInt r = KErrNone; + TName nameBuf; + TRequestStatus aStatus; + + nameBuf.Format(_L("Host Ms Thread%d"), msDeviceConfig.iInterfaceToken); + iDeviceThread = CUsbHostMsDeviceThread::NewL(msDeviceConfig.iInterfaceToken); + + RHeap* h = (RHeap*)&User::Allocator(); + TInt maxsize = h->MaxLength(); // loader heap max size = file server heap max size + const TUint KHeapMinSize = 2048; + + r = iThread.Create(nameBuf, CUsbHostMsDeviceThread::Entry, KDefaultStackSize, KHeapMinSize, maxsize, iDeviceThread); + if(r != KErrNone) + { + delete iDeviceThread; + iDeviceThread = NULL; + User::Leave(r); + } + iThread.SetPriority(EPriorityAbsoluteBackgroundNormal); + iThread.Rendezvous(aStatus); + iThread.Resume(); + User::WaitForRequest(aStatus); + if(aStatus != KErrNone) + { + if(iDeviceThread->IsActive()) + { + TRequestStatus* s=&iDeviceThread->iStatus; + iThread.RequestComplete(s, KErrSessionClosed); + } + iDeviceThread->Cancel(); + delete iDeviceThread; + iDeviceThread = NULL; + iThread.Kill(KErrNone); + User::Leave(aStatus.Int()); + } + }