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 <e32base.h>
+#include <e32base_private.h>
+#include <e32property.h>
+#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());
+ }
+ }