--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mtpdataproviders/mtppictbridgedp/src/cptpsession.cpp Tue Feb 02 01:11:40 2010 +0200
@@ -0,0 +1,530 @@
+// Copyright (c) 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:
+//
+
+
+#include <mtp/mmtpdataproviderframework.h>
+#include <f32file.h>
+#include "cptpsession.h"
+#include "cptpserver.h"
+#include "cptpreceivedmsghandler.h"
+#include "cmtppictbridgeprinter.h"
+#include "cptptimer.h"
+#include "mtppictbridgedpconst.h"
+#include "ptpdef.h"
+
+// --------------------------------------------------------------------------
+//
+// 2-phased constructor.
+// --------------------------------------------------------------------------
+//
+CPtpSession* CPtpSession::NewL(CPtpServer* aServer)
+ {
+ CPtpSession* self= new (ELeave) CPtpSession(aServer);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// --------------------------------------------------------------------------
+//
+// C++ constructor.
+// --------------------------------------------------------------------------
+//
+CPtpSession::CPtpSession(CPtpServer* aServer) : iServerP(aServer)
+ {
+ iServerP->Printer()->RegisterObserver(this); // since PTP register service
+ // is deprecated we register the observer at session creation
+ iServerP->IncrementSessionCount();
+ }
+
+// --------------------------------------------------------------------------
+//
+// --------------------------------------------------------------------------
+//
+void CPtpSession::ConstructL()
+ {
+ __FLOG_OPEN(KMTPSubsystem, KPtpServerLog);
+ iTimerP=CPtpTimer::NewL(*this);
+ }
+// --------------------------------------------------------------------------
+//
+// C++ destructor.
+// --------------------------------------------------------------------------
+//
+CPtpSession::~CPtpSession()
+ {
+ __FLOG(_L8(">>>CPtpSession::~"));
+ delete iTimerP;
+ CancelOutstandingRequest();
+ TRAP_IGNORE(CleanupL()); // there is not much we can do at this phase if the removal fails, so just ignore
+ if(iServerP->NumSession())
+ {
+ iServerP->DecrementSessionCount();
+ }
+ __FLOG(_L8("<<<CPtpSession::~"));
+ __FLOG_CLOSE;
+ }
+
+// --------------------------------------------------------------------------
+//
+// From CSession2, passes the request forward to DispatchMessageL.
+// --------------------------------------------------------------------------
+//
+void CPtpSession::ServiceL( const RMessage2& aMessage )
+ {
+ __FLOG(_L8(">>>CPtpSession::ServiceL"));
+ DispatchMessageL(aMessage);
+ __FLOG(_L8("<<<CPtpSession::ServiceL"));
+ }
+
+// --------------------------------------------------------------------------
+// Cleans up the previously received DPS file, since the files are used only
+// for communication
+// --------------------------------------------------------------------------
+//
+void CPtpSession::CleanupL()
+ {
+ __FLOG(_L8(">>>CPtpSession::Cleanup"));
+ if(iReceivedFile.Size())
+ {
+ __FLOG_VA((_L16(" deleting file %S"), &iReceivedFile));
+ User::LeaveIfError(iServerP->Framework().Fs().Delete(iReceivedFile));
+ __FLOG(_L8(" removing from DB"));
+ iServerP->RemoveObjectL(iReceivedFile);
+ iReceivedFile.Zero();
+ }
+ __FLOG(_L8("<<<CPtpSession::Cleanup"));
+ }
+
+// --------------------------------------------------------------------------
+// Handles the request from client.
+// --------------------------------------------------------------------------
+//
+void CPtpSession::DispatchMessageL( const RMessage2& aMessage )
+ {
+ __FLOG_VA((_L8(">>>CPtpSession::DispatchMessageL %d"), aMessage.Function()));
+ TInt ret = KErrNone;
+ TBool complete = ETrue;
+ CleanupL(); // calling this here assumes that the client never makes a new call
+ // before it has handled the received DPS message
+ switch( aMessage.Function() )
+ {
+ case EIsDpsPrinter:
+ ret = IsDpsPrinter(aMessage, complete);
+ break;
+
+ case ECancelIsDpsPrinter:
+ CancelIsDpsPrinter();
+ break;
+
+ case EGetObjectHandleByName:
+ GetObjectHandleByNameL(aMessage);
+ break;
+
+ case EGetNameByObjectHandle:
+ GetNameByObjectHandleL(aMessage);
+ break;
+
+ case ESendObject:
+ ret = SendObject(aMessage, complete);
+ break;
+
+ case ECancelSendObject:
+ CancelSendObject();
+ break;
+
+ case EObjectReceivedNotify:
+ ret = ObjectReceivedNotify(aMessage, complete);
+ break;
+
+ case ECancelObjectReceivedNotify:
+ CancelObjectReceivedNotify();
+ break;
+
+ case EPtpFolder:
+ ret = PtpFolder(aMessage);
+ break;
+
+ default:
+ __FLOG(_L8("!!!Error: ---Wrong param from client!!!"));
+ aMessage.Panic(KPTPClientPanicCategory, EBadRequest);
+ break;
+ }
+
+ if (complete)
+ {
+ aMessage.Complete(ret);
+ }
+ __FLOG_VA((_L8("<<<PtpSession::DispatchMessageL ret=%d"), ret));
+ }
+
+// --------------------------------------------------------------------------
+// CPtpSession::CancelIsDpsPrinter()
+// Cancels Asynchronous request IsDpsPrinter
+// --------------------------------------------------------------------------
+//
+void CPtpSession::CancelIsDpsPrinter()
+ {
+ __FLOG(_L8(">>>CPtpSession::CancelIsDpsPrinter"));
+ if (iDpsPrinterMsg.Handle())
+ {
+ iDpsPrinterMsg.Complete(KErrCancel);
+ iServerP->Printer()->DeRegisterDpsPrinterNotify(this);
+ iTimerP->Cancel();
+ iServerP->CancelNotifyOnMtpSessionOpen(this);
+ }
+ __FLOG(_L8("<<<CPtpSession::CancelIsDpsPrinter"));
+ }
+
+// --------------------------------------------------------------------------
+// CPtpSession::CancelSendObject()
+// Cancel Asynchronous request send Object
+// --------------------------------------------------------------------------
+//
+void CPtpSession::CancelSendObject()
+ {
+ __FLOG(_L8(">>>CancelSendObject"));
+ if (iSendObjectMsg.Handle())
+ {
+ iServerP->Printer()->CancelSendDpsFile();
+ iSendObjectMsg.Complete(KErrCancel);
+ iTimerP->Cancel();
+ }
+ __FLOG(_L8("<<<CancelSendObject"));
+ }
+
+// --------------------------------------------------------------------------
+// CPtpSession::CancelObjectReceivedNotify()
+// Deregisters for Object received notification
+// --------------------------------------------------------------------------
+//
+void CPtpSession::CancelObjectReceivedNotify()
+ {
+ __FLOG(_L8(">>>CancelObjectReceivedNotify"));
+ if (iObjectReceivedNotifyMsg.Handle())
+ {
+ __FLOG_VA((_L8("the handle is 0x%x"), iObjectReceivedNotifyMsg.Handle()));
+ iServerP->Printer()->MsgHandlerP()->DeRegisterReceiveObjectNotify();
+ iObjectReceivedNotifyMsg.Complete(KErrCancel);
+ }
+ __FLOG(_L8("<<<CancelObjectReceivedNotifiy"));
+ }
+
+// --------------------------------------------------------------------------
+// CPtpSession::IsDpsPrinter()
+// --------------------------------------------------------------------------
+//
+TInt CPtpSession::IsDpsPrinter(const RMessage2& aMessage, TBool& aComplete)
+ {
+ __FLOG(_L8(">>>IsDpsPrinter"));
+ TInt ret=EPrinterNotAvailable;
+ if (!iDpsPrinterMsg.Handle()) // not already pending
+ {
+ switch (iServerP->Printer()->Status())
+ {
+ case CMTPPictBridgePrinter::ENotConnected:
+ iDpsPrinterMsg = aMessage;
+ iServerP->Printer()->RegisterDpsPrinterNotify(this);
+ aComplete = EFalse;
+ if(iServerP->MtpSessionOpen())
+ {
+ if (!iTimerP->IsActive())
+ {
+ iTimerP->After(KDiscoveryTime);
+ }
+ }
+ else
+ {
+ iServerP->NotifyOnMtpSessionOpen(this);
+ }
+ // we do not set ret since the value does not really matter, we will be waiting for the discovery to complete
+ __FLOG(_L8(" waiting"));
+ break;
+
+ case CMTPPictBridgePrinter::EConnected:
+ ret=EPrinterAvailable;
+ aComplete = ETrue;
+ __FLOG(_L8(" connected"));
+ break;
+
+ case CMTPPictBridgePrinter::ENotPrinter:
+ ret=EPrinterNotAvailable;
+ aComplete = ETrue;
+ __FLOG(_L8(" not connected"));
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ {
+ __FLOG(_L8("!!!Error: client message error, duplicated IsDpsPrinter"));
+ aMessage.Panic(KPTPClientPanicCategory, ERequestPending);
+ aComplete = EFalse;
+ }
+ __FLOG(_L8("<<<IsDpsPrinter"));
+ return ret;
+ }
+
+// --------------------------------------------------------------------------
+// start the timer for printer detection, since we have now session open and
+// we are ready to communicate wioth the host
+// --------------------------------------------------------------------------
+void CPtpSession::MTPSessionOpened()
+ {
+ __FLOG(_L8(">>>CPtpSession::MTPSessionOpened"));
+ if (!iTimerP->IsActive() && iDpsPrinterMsg.Handle())
+ {
+ __FLOG(_L8(" CPtpSession::MTPSessionOpened timer started"));
+ iTimerP->After(KDiscoveryTime);
+ }
+ __FLOG(_L8("<<<CPtpSession::MTPSessionOpened"));
+ }
+
+// --------------------------------------------------------------------------
+// CPtpSession::GetObjectHandleByNameL()
+//
+// --------------------------------------------------------------------------
+//
+void CPtpSession::GetObjectHandleByNameL(const RMessage2& aMessage)
+ {
+ __FLOG(_L8(">>>CPtpSession::GetObjectHandleByNameL"));
+ TFileName file;
+ User::LeaveIfError(aMessage.Read(0, file));
+ __FLOG_VA((_L16("--the file is %S"), &file));
+ TUint32 handle=0;
+ TRAP_IGNORE(iServerP->GetObjectHandleByNameL(file, handle));
+ TPckgBuf<TUint32> handlePckg(handle);
+ aMessage.WriteL(1, handlePckg);
+ __FLOG_VA((_L16("<<<CPtpSession::GetObjectHandleByNameL handle=%d"), handle));
+ }
+
+// --------------------------------------------------------------------------
+// CPtpSession::GetNameByObjectHandle()
+
+// --------------------------------------------------------------------------
+//
+void CPtpSession::GetNameByObjectHandleL(const RMessage2& aMessage)
+ {
+ __FLOG(_L8(">>>CPtpSession::GetNameByObjectHandle"));
+ TUint32 handle = 0;
+ TPckgBuf<TUint32> pckgHandle(handle);
+ User::LeaveIfError(aMessage.Read(1, pckgHandle));
+ TFileName file;
+ handle = pckgHandle();
+ __FLOG_VA((_L8("---handle is %x"), handle));
+ TRAP_IGNORE(iServerP->GetObjectNameByHandleL(file, handle));
+ __FLOG_VA((_L16("the file is %S"), &file));
+ aMessage.WriteL(0, file);
+
+ __FLOG(_L8("<<<CPtpSession::GetNameByObjectHandle"));
+ }
+
+// --------------------------------------------------------------------------
+// CPtpSession::SendObject()
+// Asynch. request send Object
+// --------------------------------------------------------------------------
+//
+TInt CPtpSession::SendObject(const RMessage2& aMessage, TBool& aComplete)
+ {
+ __FLOG(_L8(">>>CPtpSession::SendObject"));
+ TInt err(KErrNone);
+
+ if (iSendObjectMsg.Handle())
+ {
+ __FLOG(_L8("!!!!Error: client message error, duplicated SendObject"));
+ aMessage.Panic(KPTPClientPanicCategory, ERequestPending);
+ aComplete = EFalse;
+ return KErrNone;
+ }
+ else
+ {
+ // Parameter add is depracated. We do not send Object added and we do not keep ther DPS object permanently in
+ // our system.
+ //
+ // Sending ObjectAdded Event is not mandatory ( See Appendix B page 78. DPS Usage of USB and PTP in CIPA DC-001-2003)
+
+ TBool timeout = aMessage.Int2();
+ __FLOG_VA((_L8("---timeout is %d"), timeout));
+ TFileName file;
+ err = aMessage.Read(0, file);
+ if (err == KErrNone)
+ {
+ __FLOG_VA((_L16("---the file is %S"), &file));
+ TInt size = aMessage.Int3();
+ __FLOG_VA((_L8("---the file size is %d"), size)); // size is deprecated and not used anymore
+ TRAP(err, iServerP->Printer()->SendDpsFileL(file, timeout, size));
+ if (err == KErrNone)
+ {
+ iSendObjectMsg = aMessage;
+ aComplete = EFalse;
+ }
+ }
+ if ((EFalse != timeout) && !iTimerP->IsActive())
+ {
+ iTimerP->After(KSendTimeout);
+ }
+ __FLOG_VA((_L8("<<<CPtpSession::SendObject err=%d"), err));
+ return err;
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPtpSession::ObjectReceivedNotify()
+//
+// --------------------------------------------------------------------------
+//
+TInt CPtpSession::ObjectReceivedNotify(const RMessage2& aMessage,
+ TBool& aComplete)
+ {
+ __FLOG(_L8(">>>CPtpSession::ObjectReceivedNotify"));
+ if (iObjectReceivedNotifyMsg.Handle())
+ {
+ __FLOG(_L8("!!!!Error: client message error, duplicated ObjectReceivedNotify"));
+ aMessage.Panic(KPTPClientPanicCategory, ERequestPending);
+ aComplete = EFalse;
+ return KErrNone;
+ }
+ else
+ {
+ //TBool del = aMessage.Int2();
+ //__FLOG_VA((_L8("---the del is %d"), del));
+
+ TBuf<KFileExtLength> ext;
+ TInt err = aMessage.Read(0, ext);
+ if (err == KErrNone)
+ {
+ __FLOG_VA((_L16("the extension is %S"), &ext));
+
+ iObjectReceivedNotifyMsg = aMessage;
+ aComplete = EFalse;
+ iServerP->Printer()->MsgHandlerP()->RegisterReceiveObjectNotify(ext);
+ }
+ __FLOG(_L8("<<<CPtpSession::ObjectReceivedNotify"));
+ return err;
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPtpSession::PtpFolder()
+// Returns PtpFolder Name and Path
+// --------------------------------------------------------------------------
+//
+TInt CPtpSession::PtpFolder(const RMessage2& aMessage)
+ {
+ __FLOG(_L8(">>>CPtpSession::PtpFolder"));
+ TInt err(KErrNotReady);
+ TFileName folder = iServerP->PtpFolder();
+ err = aMessage.Write(0,folder);
+ __FLOG_VA((_L16("<<<CPtpSession::PtpFolder %S err(%d)"), &folder, err));
+ return err;
+ }
+
+// --------------------------------------------------------------------------
+// CPtpSession::SendObjectCompleted()
+//
+// --------------------------------------------------------------------------
+//
+void CPtpSession::SendObjectCompleted(TInt aStatus)
+ {
+ __FLOG_VA((_L16(">>>CPtpSession::SendObjectCompleted status(%d)"), aStatus));
+ if (iSendObjectMsg.Handle())
+ {
+ iSendObjectMsg.Complete(aStatus);
+ iTimerP->Cancel();
+ }
+ else
+ {
+ __FLOG(_L8("!!!Warning: CPtpSession::SendObjectCompleted: UNEXPECTED CALL"));
+ }
+ __FLOG(_L8("<<<CPtpSession::SendObjectCompleted"));
+ }
+
+// --------------------------------------------------------------------------
+// CPtpSession::IsDpsPrinterCompleted()
+//
+// --------------------------------------------------------------------------
+//
+void CPtpSession::IsDpsPrinterCompleted(TDpsPrinterState aState)
+ {
+ __FLOG(_L8(">>>CPtpSession::IsDpsPrinterCompleted"));
+ if (iDpsPrinterMsg.Handle())
+ {
+ iDpsPrinterMsg.Complete(aState);
+ iTimerP->Cancel();
+ iServerP->Printer()->DeRegisterDpsPrinterNotify(this);
+ }
+ else
+ {
+ __FLOG(_L8("!!!Warning: CPtpSession::IsDpsPrinterCompleted: UNEXPECTED CALL"));
+ }
+ __FLOG(_L8("<<<CPtpSession::IsDpsPrinterCompleted"));
+ }
+
+// --------------------------------------------------------------------------
+// CPtpSession::ReceivedObjectCompleted()
+//
+// --------------------------------------------------------------------------
+//
+void CPtpSession::ReceivedObjectCompleted(TDes& aFile)
+ {
+ __FLOG(_L8(">>>CPtpSession::ReceivedObjectCompleted"));
+ if (iObjectReceivedNotifyMsg.Handle())
+ {
+ TInt err = iObjectReceivedNotifyMsg.Write(1, aFile);
+ iReceivedFile.Copy(aFile);
+ __FLOG_VA((_L8("***CPtpSession::ReceivedObjectCompleted err=%d"), err));
+ iObjectReceivedNotifyMsg.Complete(err);
+ }
+ else
+ {
+ __FLOG(_L8("!!!Warning: Strange Happened!!!"));
+ }
+ __FLOG(_L8("<<<CPtpSession::ReceivedObjectCompleted"));
+ }
+
+// --------------------------------------------------------------------------
+//
+// Cancels outstanding request
+// --------------------------------------------------------------------------
+//
+void CPtpSession::CancelOutstandingRequest()
+ {
+ __FLOG(_L8(">>>CPtpSession::CancelOutstandingRequest"));
+ if (iSendObjectMsg.Handle())
+ {
+ iSendObjectMsg.Complete(KErrCancel);
+ }
+ if (iObjectReceivedNotifyMsg.Handle())
+ {
+ iObjectReceivedNotifyMsg.Complete(KErrCancel);
+ }
+ if (iDpsPrinterMsg.Handle())
+ {
+ iDpsPrinterMsg.Complete(KErrCancel);
+ }
+ __FLOG(_L8("<<<CPtpSession::CancelOutstandingRequest"));
+ }
+// --------------------------------------------------------------------------
+//
+// --------------------------------------------------------------------------
+//
+CPtpServer* CPtpSession::ServerP() const
+ {
+ return iServerP;
+ }
+