mtpdataproviders/mtppictbridgedp/src/cptpsession.cpp
changeset 0 d0791faffa3f
--- /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;    
+    }
+