javaextensions/satsa/apdu/src.s60/cstsapduexchanger.cpp
branchRCL_3
changeset 14 04becd199f91
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javaextensions/satsa/apdu/src.s60/cstsapduexchanger.cpp	Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,339 @@
+/*
+* Copyright (c) 2008 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 FILES
+#include "cstsapduexchanger.h"
+#include "stsapduconstants.h"
+#include "cstscmdapdu.h"
+#include "cstsrespapdu.h"
+#include "cstscardoperationsfacade.h"
+#include "mstsresphandler.h"
+#include "cstsgetresponse.h"
+#include "fs_methodcall.h"
+#include "logger.h"
+
+namespace java
+{
+namespace satsa
+{
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CSTSApduExchanger::CSTSApduExchanger
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+
+CSTSApduExchanger::CSTSApduExchanger(CSTSCardOperationsFacade* aCOFacade) :
+        CActive(EPriorityNormal)
+{
+    CActiveScheduler::Add(this);
+    iCOFacade = aCOFacade;
+}
+
+// -----------------------------------------------------------------------------
+// CSTSApduExchanger::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CSTSApduExchanger::ConstructL()
+{
+    iWait = new(ELeave) CActiveSchedulerWait();
+    iRespBuf = HBufC8::NewL(KSTSResponseApduMaxLength);
+    iRespApdu = CSTSRespApdu::NewL(KSTSResponseApduMaxLength);
+    iGetResponseApdu = CSTSGetResponse::NewL(0x00, //empty at this point
+                       CSTSApdu::ESTSUICC);
+}
+
+// -----------------------------------------------------------------------------
+// CSTSApduExchanger::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CSTSApduExchanger* CSTSApduExchanger::NewL(JNIEnv* aJni, jobject aPeer,
+        CSTSCardOperationsFacade* aCOFacade)
+{
+    CSTSApduExchanger* self = new(ELeave) CSTSApduExchanger(aCOFacade);
+    self->mJni = aJni;
+    self->mPeer = aPeer;
+
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+}
+
+// Destructor
+CSTSApduExchanger::~CSTSApduExchanger()
+{
+    Cancel();
+    delete iRespBuf;
+    delete iWait;
+    delete iRespApdu;
+    delete iGetResponseApdu;
+}
+
+// -----------------------------------------------------------------------------
+// CSTSApduExchanger::DoExchange
+// Set channel, apdu and empties response buffer. Exchanges apdu message
+// asynchronously
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSTSApduExchanger::DoExchange(CSTSCmdApdu& aCmdApdu)
+{
+    LOG(ESATSA, EInfo, "+ CSTSApduExchanger::DoExchange");
+    aCmdApdu.SetChannel(iChannel);
+
+    iCmdApdu = &aCmdApdu;
+    //response buffer is "reusable" so empty length before next use
+    iRespBuf->Des().SetLength(0);
+    //send apdu to card
+    LOG(ESATSA, EInfo, "CSTSApduExchanger::DoExchange: send apdu to card");
+    iCOFacade->SendAPDUReq(iStatus, (TUint8) iReader, &aCmdApdu.ApduBytes());
+    SetActive();
+}
+
+// -----------------------------------------------------------------------------
+// CSTSApduExchanger::ExchangeApduL
+// Exchanges apdu message synchronously
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CSTSApduExchanger::ExchangeApdu(CSTSCmdApdu& aCmdApdu,
+                                     CSTSRespApdu& aRespApdu)
+{
+    DoExchange(aCmdApdu);
+    if (!iWait->IsStarted())
+    {
+        iWait->Start();
+    }
+    //save response
+    aRespApdu.ResponseBytes() = iRespBuf->Des();
+    return iStatus.Int();
+
+}
+
+// -----------------------------------------------------------------------------
+// CSTSApduExchanger::ExchangeApdu
+// Exchanges apdu message asynchronously
+// Sets iClientStatus information for RunL purposes.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSTSApduExchanger::ExchangeApduAsync(CSTSCmdApdu& aCmdApdu,
+        MSTSRespHandler* aRespHandler)
+{
+    LOG(ESATSA, EInfo, "+ CSTSApduExchanger::ExchangeApduAsync 1");
+
+    iRespHandler = aRespHandler;
+    LOG(ESATSA, EInfo, "Calling DoExchnage()");
+    DoExchange(aCmdApdu);
+}
+
+// -----------------------------------------------------------------------------
+// CSTSApduExchanger::ExchangeApdu
+// Exchanges apdu message asynchronously
+// Response must be get separately after asynchronous call is returned
+// When using this method for sending apdu and GetResponseBytes method for
+// getting response bytes there is no checked is resend needed or get response
+// needed.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSTSApduExchanger::ExchangeApduAsync(TRequestStatus& aStatus,
+        CSTSCmdApdu& aCmdApdu)
+{
+    aCmdApdu.SetChannel(iChannel);
+    // send apdu to card
+    iCOFacade->SendAPDUReq(aStatus, (TUint8) iReader, &aCmdApdu.ApduBytes());
+}
+
+// -----------------------------------------------------------------------------
+// CSTSApduExchanger::GetResponseBytes
+
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSTSApduExchanger::GetResponseBytes(CSTSRespApdu& aRespApdu)
+{
+    iCOFacade->GetResponseBytes(&aRespApdu.ResponseBytes());
+}
+
+// -----------------------------------------------------------------------------
+// CSTSApduExchanger::SetChannel
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSTSApduExchanger::SetChannel(TInt aChannel)
+{
+    LOG(ESATSA, EInfo, "+ CSTSApduExchanger::SetChannel");
+    iChannel = aChannel;
+}
+
+// -----------------------------------------------------------------------------
+// CSTSApduExchanger::SetReader
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSTSApduExchanger::SetReader(TInt aReader)
+{
+    iReader = aReader;
+}
+
+// -----------------------------------------------------------------------------
+// CSTSApduExchanger::SetConnectionType
+// Sets connection target to response adpu
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSTSApduExchanger::SetConnectionType(TBool aSatConnection)
+{
+    if (aSatConnection)
+    {
+        iRespApdu->SetConnectionTarget(CSTSRespApdu::ESTSUSAT);
+    }
+    else
+    {
+        iRespApdu->SetConnectionTarget(CSTSRespApdu::ESTSAID);
+    }
+}
+
+// -----------------------------------------------------------------------------
+// CSTSApduExchanger::CancelExchange
+// Can be used, if J2ME application calls CLOSE method in another thread for
+// closing connection and in other thread is pending apdu send at the same time.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSTSApduExchanger::CancelExchange()
+{
+    Cancel();
+}
+
+// -----------------------------------------------------------------------------
+// CSTSApduExchanger::RunL
+// If apdu send was called synchronously, CActiveSchedulerWait is used to continue
+// in ExchangeApduL method. If apdu send was called synchronously, we notify
+// and deliver response to java side
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSTSApduExchanger::RunL()
+{
+    LOG(ESATSA, EInfo, "+ CSTSApduExchanger::RunL");
+    if (iStatus == KErrNone)
+    {
+        LOG(ESATSA, EInfo, "CSTSApduExchanger::RunL:Status is KErrNone.");
+        iRespApdu->ResponseBytes().SetLength(0);
+        iCOFacade->GetResponseBytes(&iRespApdu->ResponseBytes());
+
+        //append new response after old response
+        iRespBuf->Des().Append(iRespApdu->ResponseBytes());
+
+        TUint8 newRespLength = 0x00;
+        if (iRespApdu->GetResponseNeeded(newRespLength))
+        {
+            LOG(ESATSA, EInfo, "CSTSApduExchanger::RunL:GetResponseNeeded");
+            //remove sw1 and sw2, because more data will be appended
+            iRespBuf->Des().SetLength(iRespBuf->Length() - 2);
+            //we got new length from earlier called method
+            iGetResponseApdu->SetExpectedResponseLength(newRespLength);
+            iGetResponseApdu->SetChannel(iChannel);
+
+            //send get response apdu to card
+            LOG(ESATSA, EInfo, "send get response apdu to card");
+            iCOFacade->SendAPDUReq(iStatus, (TUint8) iReader,
+                                   &iGetResponseApdu->ApduBytes());
+            SetActive();
+        }
+        else if (iRespApdu->ResendNeeded(newRespLength))
+        {
+            LOG(ESATSA, EInfo, "CSTSApduExchanger::RunL: Resend needed ");
+            //Resend apdu with correct length
+            iCmdApdu->SetLe(newRespLength);
+            iRespBuf->Des().SetLength(0); //empty old response
+
+            LOG(ESATSA, EInfo, "send same apdu to card again (resend)");
+            //send same apdu to card again (resend)
+            iCOFacade->SendAPDUReq(iStatus, (TUint8) iReader,
+                                   &iCmdApdu->ApduBytes());
+            SetActive();
+        }
+        else
+        {
+            //if synchronous ExchangeApdu was called
+            if (iWait->IsStarted())
+            {
+                LOG(ESATSA, EInfo, "Synch Exchng called!");
+                iWait->AsyncStop();
+            }
+            //if asynchronous ExchangeApduAsync was called
+            else
+            {
+                LOG(ESATSA, EInfo, "calling response handler to complete operation");
+                iRespHandler->OperationComplete(mJni, mPeer, iRespBuf, KErrNone);
+            }
+        }
+    }
+    else //if the iStatus is not KErrNone
+    {
+        LOG(ESATSA, EInfo, "CSTSApduExchanger::RunL:iStatus is not KErrNone");
+        //if synchronous ExchangeApdu was called
+        if (iWait->IsStarted())
+        {
+            iWait->AsyncStop();
+        }
+        else
+        {
+            LOG(ESATSA, EInfo, "calling response handler to complete operation");
+            iRespHandler->OperationComplete(mJni, mPeer, NULL, KSTSErrIO);
+        }
+    }
+}
+
+// -----------------------------------------------------------------------------
+// CSTSApduExchanger::DoCancel
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSTSApduExchanger::DoCancel()
+{
+
+    if (iWait->IsStarted())
+    {
+        //synchronous call can not be cancelled
+
+    }
+    else
+    {
+        iCOFacade->CancelAPDUReq();
+        iRespHandler->OperationComplete(mJni, mPeer, NULL, KSTSErrInterruptedIO
+                                        + KSTSErrIIConnClosedDuring);
+    }
+}
+
+} // namespace satsa
+} // namespace java
+//  End of File
+