diff -r 6b1d113cdff3 -r 6638e7f4bd8f telephonyserver/etelmultimode/DTsy/MMTSYSMARTCARDEAP.cpp --- a/telephonyserver/etelmultimode/DTsy/MMTSYSMARTCARDEAP.cpp Mon May 03 13:37:20 2010 +0300 +++ b/telephonyserver/etelmultimode/DTsy/MMTSYSMARTCARDEAP.cpp Thu May 06 15:10:38 2010 +0100 @@ -1,623 +1,623 @@ -// Copyright (c) 2006-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: -// Dummy TSY testing functionality for Smart Card Application EAP support. -// -// - -/** - @file -*/ - - -#include "mmtsy.h" -#include "testdef.h" -#include "ETELMM.H" -#include -#include "Dmmlog.h" -#include - -// -// CSmartCardEapDMmTsy -// -CSmartCardEapDMmTsy* CSmartCardEapDMmTsy::NewL(CPhoneDMmTsy *aPhone, RMobilePhone::TAID& aAID, RMobileSmartCardEap::TEapType& aEapType, CPhoneFactoryDummyBase* aFac) - { - CSmartCardEapDMmTsy* phone=new(ELeave) CSmartCardEapDMmTsy(aPhone, aAID, aEapType, aFac); - CleanupStack::PushL(phone); - phone->ConstructL(); - CleanupStack::Pop(); - return phone; - } - -CSmartCardEapDMmTsy::CSmartCardEapDMmTsy(CPhoneDMmTsy *aPhone, RMobilePhone::TAID& aAID, RMobileSmartCardEap::TEapType& aEapType, CPhoneFactoryDummyBase* aFac) -: CSubSessionExtDummyBase(aFac), iPhone(aPhone), iSSInitialised(EFalse), - iAccessStatus(RMobileSmartCardEap::EEapMethodAvailable), iCliTerminationNotifier(NULL) - { - iAID = aAID; - iEapType = aEapType; - } - -void CSmartCardEapDMmTsy::ConstructL() - { - iSemaphr.CreateGlobal(KNullDesC, EOwnerThread); - LOGTEXT(_L8("CSmartCardEapDMmTsy created")); - } - -CSmartCardEapDMmTsy::~CSmartCardEapDMmTsy() - { - delete iCliTerminationNotifier; - iSemaphr.Close(); - LOGTEXT(_L8("CSmartCardEapDMmTsy destroyed")); - } - -void CSmartCardEapDMmTsy::Init() - { - // server calls this function once it has created the sub-session - // it gives the TSY chance to do any initialisation it may need to do for - // this sub-session - } - -CTelObject* CSmartCardEapDMmTsy::OpenNewObjectByNameL(const TDesC& /*aName*/) - { - // Server calls this function when a client is opening an object from the phone - // for the first time. - // Multiple clients opening handles to the same sub-session object will be dealt with - // by the server - i.e. by reference counting - User::Leave(KErrNotSupported); - return NULL; - } - -CTelObject* CSmartCardEapDMmTsy::OpenNewObjectL(TDes& /*aNewName*/) - { - // all objects opened from the phone are opened by name, hence this method - // is not supported - User::Leave(KErrNotSupported); - return NULL; - } - -CTelObject::TReqMode CSmartCardEapDMmTsy::ReqModeL(const TInt aIpc) - { - // ReqModeL is called from the server's CTelObject::ReqAnalyserL - // in order to check the type of request it has - - // The following are example request types for this dummy TSY - // All TSYs do not have to have these request types but they have been given - // "sensible" values in this test code - - CTelObject::TReqMode ret = 0; - - switch (aIpc) - { - // Non flow-controlled requests - case EMobileSmartCardEapInitialiseEapMethod: - case EMobileSmartCardEapGetUserIdentity: - case EMobileSmartCardEapGetAuthenticationStatus: - case EMobileSmartCardEapGetEapKey: - case EMobileSmartCardEapAuthenticationPhase1: - case EMobileSmartCardEapAuthenticationPhase2: - case EMobileSmartCardEapReleaseEapMethod: - case EMobileSmartCardEapGetEapMethodAccessStatus: - break; - - case EMobileSmartCardEapNotifyEapMethodAccessStatusChange: - ret = KReqModeMultipleCompletionEnabled; - break; - - default: - User::Leave(KErrNotSupported); - break; - } - - return ret; - } - -TInt CSmartCardEapDMmTsy::RegisterNotification(const TInt /*aIpc*/) - { - // RegisterNotification is called when the server recognises that this notification - // is being posted for the first time on this sub-session object. - - // It enables the TSY to "turn on" any regular notification messages that it may - // receive from the phone - - return KErrNone; - } - -TInt CSmartCardEapDMmTsy::DeregisterNotification(const TInt /*aIpc*/) - { - // DeregisterNotification is called when the server recognises that this notification - // will not be posted again because the last client to have a handle on this sub-session - // object has just closed the handle. - - // It enables the TSY to "turn off" any regular notification messages that it may - // receive from the phone - - return KErrNone; - } - -TInt CSmartCardEapDMmTsy::NumberOfSlotsL(const TInt aIpc) - { - // NumberOfSlotsL is called by the server when it is registering a new notification - // It enables the TSY to tell the server how many buffer slots to allocate for - // "repost immediately" notifications that may trigger before clients collect them - - TInt numberOfSlots = 1; - - switch (aIpc) - { - case EMobileSmartCardEapNotifyEapMethodAccessStatusChange: - numberOfSlots = 3; - break; - - default: - // Unknown or invalid Phone IPC - User::Leave(KErrNotSupported); - break; - } - - return numberOfSlots; - } - -TInt CSmartCardEapDMmTsy::ExtFunc(const TTsyReqHandle aTsyReqHandle,const TInt aIpc, - const TDataPackage& aPackage) - { - // ExtFunc is called by the server when it has a "extended", i.e. non-core ETel request - // for the TSY to process - // A request handle, request type and request data are passed to the TSY - - TAny* dataPtr = aPackage.Ptr1(); - TAny* dataPtr2 = aPackage.Ptr2(); - - // The request data has to extracted from TDataPackage and the TAny* pointers have to - // be "cast" to the expected request data type - - switch(aIpc) - { - // Non-Flow controlled requests - - case EMobileSmartCardEapInitialiseEapMethod: - return DMmInitialiseEapMethod(aTsyReqHandle, - reinterpret_cast(dataPtr)); - - case EMobileSmartCardEapGetUserIdentity: - return DMmGetUserIdentity(aTsyReqHandle, - reinterpret_cast(dataPtr), - aPackage.Des2n()); - - case EMobileSmartCardEapGetAuthenticationStatus: - return DMmGetAuthenticationStatus(aTsyReqHandle, - reinterpret_cast(dataPtr)); - - case EMobileSmartCardEapGetEapKey: - return DMmGetEapKey(aTsyReqHandle, - reinterpret_cast(dataPtr), - aPackage.Des2n()); - - case EMobileSmartCardEapAuthenticationPhase1: - return DMmSetAuthenticateDataForPhase1(aTsyReqHandle, - aPackage.Des1n(), reinterpret_cast(dataPtr2)); - - case EMobileSmartCardEapAuthenticationPhase2: - return DMmGetAuthenticateDataForPhase2(aTsyReqHandle, - aPackage.Des1n(), aPackage.Des2n()); - - case EMobileSmartCardEapReleaseEapMethod: - return DMmReleaseEapMethod(aTsyReqHandle); - - case EMobileSmartCardEapGetEapMethodAccessStatus: - return DMmGetEapMethodAccessStatus(aTsyReqHandle, - reinterpret_cast(dataPtr)); - - case EMobileSmartCardEapNotifyEapMethodAccessStatusChange: - return DMmNotifyEapMethodAccessStatusChange(aTsyReqHandle, - reinterpret_cast(dataPtr)); - - default: - return KErrNotSupported; - } - } - -TInt CSmartCardEapDMmTsy::CancelService(const TInt aIpc,const TTsyReqHandle aTsyReqHandle) - { - // CancelService is called by the server when it is "cleaning-up" any still outstanding - // asynchronous requests before closing a client's sub-session. - // This will happen if a client closes its R-class handle without cancelling outstanding - // asynchronous requests. - - switch (aIpc) - { - case EMobileSmartCardEapGetUserIdentity: - return DMmGetUserIdentityCancel(aTsyReqHandle); - case EMobileSmartCardEapGetAuthenticationStatus: - return DMmGetAuthenticationStatusCancel(aTsyReqHandle); - case EMobileSmartCardEapGetEapKey: - return DMmGetEapKeyCancel(aTsyReqHandle); - case EMobileSmartCardEapInitialiseEapMethod: - return DMmInitialiseEapMethodCancel(aTsyReqHandle); - case EMobileSmartCardEapAuthenticationPhase1: - case EMobileSmartCardEapAuthenticationPhase2: - return DMmSmartCardEapAuthenticationCancel(aTsyReqHandle); - case EMobileSmartCardEapNotifyEapMethodAccessStatusChange: - return DMmNotifyEapMethodAccessStatusChangeCancel(aTsyReqHandle); - default: - return KErrNotSupported; - } - } - -TInt CSmartCardEapDMmTsy::DMmInitialiseEapMethod(const TTsyReqHandle aTsyReqHandle, TThreadId* aThreadId) - { - LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmInitialiseEapMethod called")); - - if (iAID != DMMTSY_PHONE_EAPAPP_AID() || iEapType != DMMTSY_PHONE_EAP_METHOD) - { - ReqCompleted(aTsyReqHandle, KErrNotFound); - } - else if (iSSInitialised) - { - ReqCompleted(aTsyReqHandle, KErrNone); - } - else - { - delete iCliTerminationNotifier; - TRAPD(err, iCliTerminationNotifier = CThreadTerminationNotifier::NewL(this, *aThreadId)); - if (err != KErrNone) - { - ReqCompleted(aTsyReqHandle, err); - } - else - { - iSSInitialised = ETrue; - iCliTerminationNotifier->Start(); - iAccessStatus = RMobileSmartCardEap::EEapMethodInUseApplicationActive; - DMmCompleteNotifyEapMethodAccessStatusChange(); - iPhone->AddDelayedReq(aTsyReqHandle, this); - } - } - - return KErrNone; - } - -TInt CSmartCardEapDMmTsy::DMmInitialiseEapMethodCancel(const TTsyReqHandle aTsyReqHandle) - { - LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmInitialiseEapMethodCancel called")); - iPhone->RemoveDelayedReq(aTsyReqHandle); - iSSInitialised = EFalse; - iAccessStatus = RMobileSmartCardEap::EEapMethodAvailable; - DMmCompleteNotifyEapMethodAccessStatusChange(); - ReqCompleted(aTsyReqHandle, KErrCancel); - return KErrNone; - } - -TInt CSmartCardEapDMmTsy::DMmGetUserIdentity(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapUserIdType* aEapIdType, TDes8* aUserId) - { - LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmGetUserIdentity called")); - RMobileSmartCardEap::TEapUserIdentityV6Pckg *userIdPckg = reinterpret_cast(aUserId); - RMobileSmartCardEap::TEapUserIdentityV6 &userId = (*userIdPckg)(); - - if (*aEapIdType == DMMTSY_PHONE1_EAP_IDTYPE) - { - userId.iEapId = DMMTSY_PHONE1_EAP_UID; - iPhone->AddDelayedReq(aTsyReqHandle, this); - } - else if (*aEapIdType == DMMTSY_PHONE2_EAP_IDTYPE) - { - userId.iEapId = DMMTSY_PHONE2_EAP_UID; - iPhone->AddDelayedReq(aTsyReqHandle, this); - } - else - { - ReqCompleted(aTsyReqHandle, KErrArgument); - } - - return KErrNone; - } - -TInt CSmartCardEapDMmTsy::DMmGetUserIdentityCancel(const TTsyReqHandle aTsyReqHandle) - { - LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmGetUserIdentityCancel called")); - iPhone->RemoveDelayedReq(aTsyReqHandle); - ReqCompleted(aTsyReqHandle, KErrCancel); - return KErrNone; - } - -TInt CSmartCardEapDMmTsy::DMmGetAuthenticationStatus(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapAuthStatus* aAuthStatus) - { - LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmGetAuthenticationStatus called")); - - *aAuthStatus = DMMTSY_PHONE_EAPAUTHSTATUS; - iPhone->AddDelayedReq(aTsyReqHandle, this); - - return KErrNone; - } - -TInt CSmartCardEapDMmTsy::DMmGetAuthenticationStatusCancel(const TTsyReqHandle aTsyReqHandle) - { - LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmGetAuthenticationStatusCancel called")); - iPhone->RemoveDelayedReq(aTsyReqHandle); - ReqCompleted(aTsyReqHandle, KErrCancel); - return KErrNone; - } - -TInt CSmartCardEapDMmTsy::DMmGetEapKey(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapKeyTag* aEapKeyTag, TDes8* aKey) - { - LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmGetEapKey called")); - - RMobileSmartCardEap::TEapKeyV6Pckg *keyPckg = reinterpret_cast(aKey); - RMobileSmartCardEap::TEapKeyV6 &key = (*keyPckg)(); - - if (*aEapKeyTag == DMMTSY_PHONE1_EAPKEYTAG) - { - key.iEapKey = DMMTSY_PHONE1_EAPKEY; - iPhone->AddDelayedReq(aTsyReqHandle, this); - } - else if (*aEapKeyTag == DMMTSY_PHONE2_EAPKEYTAG) - { - key.iEapKey = DMMTSY_PHONE2_EAPKEY; - iPhone->AddDelayedReq(aTsyReqHandle, this); - } - else - { - ReqCompleted(aTsyReqHandle, KErrArgument); - } - - return KErrNone; - } - -TInt CSmartCardEapDMmTsy::DMmGetEapKeyCancel(const TTsyReqHandle aTsyReqHandle) - { - LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmGetEapKeyCancel called")); - iPhone->RemoveDelayedReq(aTsyReqHandle); - ReqCompleted(aTsyReqHandle, KErrCancel); - return KErrNone; - } - -TInt CSmartCardEapDMmTsy::DMmSetAuthenticateDataForPhase1(const TTsyReqHandle aTsyReqHandle, TDes8* aEapAuthData, TInt* aPhase1Size) - { - LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmSetAuthenticateDataForPhase1 called")); - - RMobileSmartCardEap::CEapAuthenticateRequestDataV6* authReq = NULL; - TRAPD(err, authReq = RMobileSmartCardEap::CEapAuthenticateRequestDataV6::NewL()); - if (err != KErrNone) - { - ReqCompleted(aTsyReqHandle, err); - return KErrNone; - } - - TRAP(err, authReq->InternalizeL(*aEapAuthData)); - if (err != KErrNone) - { - ReqCompleted(aTsyReqHandle, err); - return KErrNone; - } - - TPtr8 reqPacket = authReq->GetEapReqPacket(); - if (reqPacket == DMMTSY_PHONE1_EAPPACKET) - { - iRespPtrC.Set(DMMTSY_PHONE2_EAPPACKET); - *aPhase1Size = iRespPtrC.Length(); - } - else if (reqPacket == DMMTSY_PHONE1_EAPPACKET2) - { - iRespPtrC.Set(DMMTSY_PHONE2_EAPPACKET2); - *aPhase1Size = iRespPtrC.Length(); - } - else - { - ReqCompleted(aTsyReqHandle, KErrCorrupt); - return KErrNone; - } - - iPhone->AddDelayedReq(aTsyReqHandle, this); - return KErrNone; - } - -TInt CSmartCardEapDMmTsy::DMmGetAuthenticateDataForPhase2(const TTsyReqHandle aTsyReqHandle, TDes8* aEapAuthData, TDes8* aPhase2Resp) - { - LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmSetAuthenticateDataForPhase2 called")); - - RMobileSmartCardEap::CEapAuthenticateRequestDataV6* authReq = NULL; - TRAPD(err, authReq = RMobileSmartCardEap::CEapAuthenticateRequestDataV6::NewL()); - if (err != KErrNone) - { - ReqCompleted(aTsyReqHandle, err); - return KErrNone; - } - - TRAP(err, authReq->InternalizeL(*aEapAuthData)); - if (err != KErrNone) - { - ReqCompleted(aTsyReqHandle, err); - return KErrNone; - } - - TPtr8 reqPacket = authReq->GetEapReqPacket(); - if (reqPacket != DMMTSY_PHONE1_EAPPACKET && - reqPacket != DMMTSY_PHONE1_EAPPACKET2) - { - ReqCompleted(aTsyReqHandle, KErrCorrupt); - return KErrNone; - } - - aPhase2Resp->Copy(iRespPtrC); - - iPhone->AddDelayedReq(aTsyReqHandle, this); - - return KErrNone; - } - -TInt CSmartCardEapDMmTsy::DMmSmartCardEapAuthenticationCancel(const TTsyReqHandle aTsyReqHandle) - { - LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmSmartCardEapAuthenticationCancel called")); - iPhone->RemoveDelayedReq(aTsyReqHandle); - ReqCompleted(aTsyReqHandle, KErrCancel); - iRespPtrC.Set(NULL, 0); - return KErrNone; - } - -TInt CSmartCardEapDMmTsy::DMmReleaseEapMethod(const TTsyReqHandle aTsyReqHandle) - { - LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmReleaseEapMethod called")); - iSSInitialised = EFalse; - iAccessStatus = RMobileSmartCardEap::EEapMethodUnableToInitialise; - ReqCompleted(aTsyReqHandle, KErrNone); - - DMmCompleteNotifyEapMethodAccessStatusChange(); - - // Simulate availability after 2 secs. - User::After(2000000); - iAccessStatus = RMobileSmartCardEap::EEapMethodAvailable; - DMmCompleteNotifyEapMethodAccessStatusChange(); - - return KErrNone; - } - -TInt CSmartCardEapDMmTsy::DMmGetEapMethodAccessStatus(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapMethodAccessStatus* aEapState) - { - LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmGetEapMethodAccessStatus called")); - *aEapState = iAccessStatus; - ReqCompleted(aTsyReqHandle, KErrNone); - return KErrNone; - } - -TInt CSmartCardEapDMmTsy::DMmNotifyEapMethodAccessStatusChange(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapMethodAccessStatus* aEapState) - { - __ASSERT_ALWAYS(!iEapAccessNotifyData.iNotifyPending, PanicClient(EEtelPanicRequestAsyncTwice)); - - iEapAccessNotifyData.iNotifyPending = ETrue; - iEapAccessNotifyData.iNotifyHandle = aTsyReqHandle; - iEapAccessNotifyData.iNotifyData = aEapState; - - return KErrNone; - } - -TInt CSmartCardEapDMmTsy::DMmNotifyEapMethodAccessStatusChangeCancel(const TTsyReqHandle aTsyReqHandle) - { - if(iEapAccessNotifyData.iNotifyPending) - { - iEapAccessNotifyData.iNotifyPending = EFalse; - ReqCompleted(aTsyReqHandle, KErrCancel); - return KErrNone; - } - - iPhone->ReqCompleted(aTsyReqHandle,KErrNone); - return KErrNone; - } - -void CSmartCardEapDMmTsy::DMmCompleteNotifyEapMethodAccessStatusChange() - { - if(iEapAccessNotifyData.iNotifyPending) - { - iEapAccessNotifyData.iNotifyPending = EFalse; - *(reinterpret_cast(iEapAccessNotifyData.iNotifyData)) = iAccessStatus; - ReqCompleted(iEapAccessNotifyData.iNotifyHandle, KErrNone); - } - } - -RHandleBase* CSmartCardEapDMmTsy::GlobalKernelObjectHandle() - { - return &iSemaphr; - } - -void CSmartCardEapDMmTsy::ClientHasTerminated(TInt aExitReason) - { - // Can TSY do anything with the thread's exit reason? - // Exit code can be a zero (e.g. for KERN-EXEC 0) a positive value - // (e.g. for KERN-EXEC 3) or a negative error. - (void) aExitReason; - - switch (iAccessStatus) - { - case RMobileSmartCardEap::EEapMethodInUseApplicationActive: - iSSInitialised = EFalse; - iAccessStatus = RMobileSmartCardEap::EEapMethodUnableToInitialise; - DMmCompleteNotifyEapMethodAccessStatusChange(); - iSemaphr.Signal(); - - // Simulate availability after 2 secs. - User::After(2000000); - iAccessStatus = RMobileSmartCardEap::EEapMethodAvailable; - DMmCompleteNotifyEapMethodAccessStatusChange(); - break; - - case RMobileSmartCardEap::EEapMethodInUseApplicationInactive: - iAccessStatus = RMobileSmartCardEap::EEapMethodAvailable; - DMmCompleteNotifyEapMethodAccessStatusChange(); - iSemaphr.Signal(); - break; - - default: - ; - } - - //iSemaphr.Signal(); - } - -// -// Class definition for monitoring thread termination -// - -CSmartCardEapDMmTsy::CThreadTerminationNotifier* CSmartCardEapDMmTsy::CThreadTerminationNotifier::NewL(CSmartCardEapDMmTsy* aSubSess, const TThreadId& aId) - { - CThreadTerminationNotifier* self = new(ELeave) CThreadTerminationNotifier(aSubSess); - CleanupStack::PushL(self); - self->ConstructL(aId); - CleanupStack::Pop(self); - return self; - } - -CSmartCardEapDMmTsy::CThreadTerminationNotifier::CThreadTerminationNotifier(CSmartCardEapDMmTsy* aSubSess) -: CActive(EPriorityStandard), iSubSess(aSubSess) - { - } - -void CSmartCardEapDMmTsy::CThreadTerminationNotifier::ConstructL(const TThreadId& aId) - { - TInt openTh = iCliThread.Open(aId); - User::LeaveIfError(openTh); - CActiveScheduler::Add(this); - } - -void CSmartCardEapDMmTsy::CThreadTerminationNotifier::Start() - { - iCliThread.Logon(iStatus); - SetActive(); - } - -void CSmartCardEapDMmTsy::CThreadTerminationNotifier::RunL() - { - iSubSess->ClientHasTerminated(iStatus.Int()); - } - -void CSmartCardEapDMmTsy::CThreadTerminationNotifier::DoCancel() - { - iCliThread.LogonCancel(iStatus); - } - -CSmartCardEapDMmTsy::CThreadTerminationNotifier::~CThreadTerminationNotifier() - { - Cancel(); - iCliThread.Close(); - } - -// -// methods for CActiveListNode -// - -CSmartCardEapDMmTsy::CActiveListNode::CActiveListNode(CActive *aActive, const TTsyReqHandle aTsyReqHandle) : - iActive(aActive), iTsyReqHandle(aTsyReqHandle) - { - } - -CSmartCardEapDMmTsy::CActiveListNode::~CActiveListNode() - { - delete iActive; - } +// Copyright (c) 2006-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: +// Dummy TSY testing functionality for Smart Card Application EAP support. +// +// + +/** + @file +*/ + + +#include "mmtsy.h" +#include "testdef.h" +#include "ETELMM.H" +#include +#include "Dmmlog.h" +#include + +// +// CSmartCardEapDMmTsy +// +CSmartCardEapDMmTsy* CSmartCardEapDMmTsy::NewL(CPhoneDMmTsy *aPhone, RMobilePhone::TAID& aAID, RMobileSmartCardEap::TEapType& aEapType, CPhoneFactoryDummyBase* aFac) + { + CSmartCardEapDMmTsy* phone=new(ELeave) CSmartCardEapDMmTsy(aPhone, aAID, aEapType, aFac); + CleanupStack::PushL(phone); + phone->ConstructL(); + CleanupStack::Pop(); + return phone; + } + +CSmartCardEapDMmTsy::CSmartCardEapDMmTsy(CPhoneDMmTsy *aPhone, RMobilePhone::TAID& aAID, RMobileSmartCardEap::TEapType& aEapType, CPhoneFactoryDummyBase* aFac) +: CSubSessionExtDummyBase(aFac), iPhone(aPhone), iSSInitialised(EFalse), + iAccessStatus(RMobileSmartCardEap::EEapMethodAvailable), iCliTerminationNotifier(NULL) + { + iAID = aAID; + iEapType = aEapType; + } + +void CSmartCardEapDMmTsy::ConstructL() + { + iSemaphr.CreateGlobal(KNullDesC, EOwnerThread); + LOGTEXT(_L8("CSmartCardEapDMmTsy created")); + } + +CSmartCardEapDMmTsy::~CSmartCardEapDMmTsy() + { + delete iCliTerminationNotifier; + iSemaphr.Close(); + LOGTEXT(_L8("CSmartCardEapDMmTsy destroyed")); + } + +void CSmartCardEapDMmTsy::Init() + { + // server calls this function once it has created the sub-session + // it gives the TSY chance to do any initialisation it may need to do for + // this sub-session + } + +CTelObject* CSmartCardEapDMmTsy::OpenNewObjectByNameL(const TDesC& /*aName*/) + { + // Server calls this function when a client is opening an object from the phone + // for the first time. + // Multiple clients opening handles to the same sub-session object will be dealt with + // by the server - i.e. by reference counting + User::Leave(KErrNotSupported); + return NULL; + } + +CTelObject* CSmartCardEapDMmTsy::OpenNewObjectL(TDes& /*aNewName*/) + { + // all objects opened from the phone are opened by name, hence this method + // is not supported + User::Leave(KErrNotSupported); + return NULL; + } + +CTelObject::TReqMode CSmartCardEapDMmTsy::ReqModeL(const TInt aIpc) + { + // ReqModeL is called from the server's CTelObject::ReqAnalyserL + // in order to check the type of request it has + + // The following are example request types for this dummy TSY + // All TSYs do not have to have these request types but they have been given + // "sensible" values in this test code + + CTelObject::TReqMode ret = 0; + + switch (aIpc) + { + // Non flow-controlled requests + case EMobileSmartCardEapInitialiseEapMethod: + case EMobileSmartCardEapGetUserIdentity: + case EMobileSmartCardEapGetAuthenticationStatus: + case EMobileSmartCardEapGetEapKey: + case EMobileSmartCardEapAuthenticationPhase1: + case EMobileSmartCardEapAuthenticationPhase2: + case EMobileSmartCardEapReleaseEapMethod: + case EMobileSmartCardEapGetEapMethodAccessStatus: + break; + + case EMobileSmartCardEapNotifyEapMethodAccessStatusChange: + ret = KReqModeMultipleCompletionEnabled; + break; + + default: + User::Leave(KErrNotSupported); + break; + } + + return ret; + } + +TInt CSmartCardEapDMmTsy::RegisterNotification(const TInt /*aIpc*/) + { + // RegisterNotification is called when the server recognises that this notification + // is being posted for the first time on this sub-session object. + + // It enables the TSY to "turn on" any regular notification messages that it may + // receive from the phone + + return KErrNone; + } + +TInt CSmartCardEapDMmTsy::DeregisterNotification(const TInt /*aIpc*/) + { + // DeregisterNotification is called when the server recognises that this notification + // will not be posted again because the last client to have a handle on this sub-session + // object has just closed the handle. + + // It enables the TSY to "turn off" any regular notification messages that it may + // receive from the phone + + return KErrNone; + } + +TInt CSmartCardEapDMmTsy::NumberOfSlotsL(const TInt aIpc) + { + // NumberOfSlotsL is called by the server when it is registering a new notification + // It enables the TSY to tell the server how many buffer slots to allocate for + // "repost immediately" notifications that may trigger before clients collect them + + TInt numberOfSlots = 1; + + switch (aIpc) + { + case EMobileSmartCardEapNotifyEapMethodAccessStatusChange: + numberOfSlots = 3; + break; + + default: + // Unknown or invalid Phone IPC + User::Leave(KErrNotSupported); + break; + } + + return numberOfSlots; + } + +TInt CSmartCardEapDMmTsy::ExtFunc(const TTsyReqHandle aTsyReqHandle,const TInt aIpc, + const TDataPackage& aPackage) + { + // ExtFunc is called by the server when it has a "extended", i.e. non-core ETel request + // for the TSY to process + // A request handle, request type and request data are passed to the TSY + + TAny* dataPtr = aPackage.Ptr1(); + TAny* dataPtr2 = aPackage.Ptr2(); + + // The request data has to extracted from TDataPackage and the TAny* pointers have to + // be "cast" to the expected request data type + + switch(aIpc) + { + // Non-Flow controlled requests + + case EMobileSmartCardEapInitialiseEapMethod: + return DMmInitialiseEapMethod(aTsyReqHandle, + reinterpret_cast(dataPtr)); + + case EMobileSmartCardEapGetUserIdentity: + return DMmGetUserIdentity(aTsyReqHandle, + reinterpret_cast(dataPtr), + aPackage.Des2n()); + + case EMobileSmartCardEapGetAuthenticationStatus: + return DMmGetAuthenticationStatus(aTsyReqHandle, + reinterpret_cast(dataPtr)); + + case EMobileSmartCardEapGetEapKey: + return DMmGetEapKey(aTsyReqHandle, + reinterpret_cast(dataPtr), + aPackage.Des2n()); + + case EMobileSmartCardEapAuthenticationPhase1: + return DMmSetAuthenticateDataForPhase1(aTsyReqHandle, + aPackage.Des1n(), reinterpret_cast(dataPtr2)); + + case EMobileSmartCardEapAuthenticationPhase2: + return DMmGetAuthenticateDataForPhase2(aTsyReqHandle, + aPackage.Des1n(), aPackage.Des2n()); + + case EMobileSmartCardEapReleaseEapMethod: + return DMmReleaseEapMethod(aTsyReqHandle); + + case EMobileSmartCardEapGetEapMethodAccessStatus: + return DMmGetEapMethodAccessStatus(aTsyReqHandle, + reinterpret_cast(dataPtr)); + + case EMobileSmartCardEapNotifyEapMethodAccessStatusChange: + return DMmNotifyEapMethodAccessStatusChange(aTsyReqHandle, + reinterpret_cast(dataPtr)); + + default: + return KErrNotSupported; + } + } + +TInt CSmartCardEapDMmTsy::CancelService(const TInt aIpc,const TTsyReqHandle aTsyReqHandle) + { + // CancelService is called by the server when it is "cleaning-up" any still outstanding + // asynchronous requests before closing a client's sub-session. + // This will happen if a client closes its R-class handle without cancelling outstanding + // asynchronous requests. + + switch (aIpc) + { + case EMobileSmartCardEapGetUserIdentity: + return DMmGetUserIdentityCancel(aTsyReqHandle); + case EMobileSmartCardEapGetAuthenticationStatus: + return DMmGetAuthenticationStatusCancel(aTsyReqHandle); + case EMobileSmartCardEapGetEapKey: + return DMmGetEapKeyCancel(aTsyReqHandle); + case EMobileSmartCardEapInitialiseEapMethod: + return DMmInitialiseEapMethodCancel(aTsyReqHandle); + case EMobileSmartCardEapAuthenticationPhase1: + case EMobileSmartCardEapAuthenticationPhase2: + return DMmSmartCardEapAuthenticationCancel(aTsyReqHandle); + case EMobileSmartCardEapNotifyEapMethodAccessStatusChange: + return DMmNotifyEapMethodAccessStatusChangeCancel(aTsyReqHandle); + default: + return KErrNotSupported; + } + } + +TInt CSmartCardEapDMmTsy::DMmInitialiseEapMethod(const TTsyReqHandle aTsyReqHandle, TThreadId* aThreadId) + { + LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmInitialiseEapMethod called")); + + if (iAID != DMMTSY_PHONE_EAPAPP_AID() || iEapType != DMMTSY_PHONE_EAP_METHOD) + { + ReqCompleted(aTsyReqHandle, KErrNotFound); + } + else if (iSSInitialised) + { + ReqCompleted(aTsyReqHandle, KErrNone); + } + else + { + delete iCliTerminationNotifier; + TRAPD(err, iCliTerminationNotifier = CThreadTerminationNotifier::NewL(this, *aThreadId)); + if (err != KErrNone) + { + ReqCompleted(aTsyReqHandle, err); + } + else + { + iSSInitialised = ETrue; + iCliTerminationNotifier->Start(); + iAccessStatus = RMobileSmartCardEap::EEapMethodInUseApplicationActive; + DMmCompleteNotifyEapMethodAccessStatusChange(); + iPhone->AddDelayedReq(aTsyReqHandle, this); + } + } + + return KErrNone; + } + +TInt CSmartCardEapDMmTsy::DMmInitialiseEapMethodCancel(const TTsyReqHandle aTsyReqHandle) + { + LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmInitialiseEapMethodCancel called")); + iPhone->RemoveDelayedReq(aTsyReqHandle); + iSSInitialised = EFalse; + iAccessStatus = RMobileSmartCardEap::EEapMethodAvailable; + DMmCompleteNotifyEapMethodAccessStatusChange(); + ReqCompleted(aTsyReqHandle, KErrCancel); + return KErrNone; + } + +TInt CSmartCardEapDMmTsy::DMmGetUserIdentity(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapUserIdType* aEapIdType, TDes8* aUserId) + { + LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmGetUserIdentity called")); + RMobileSmartCardEap::TEapUserIdentityV6Pckg *userIdPckg = reinterpret_cast(aUserId); + RMobileSmartCardEap::TEapUserIdentityV6 &userId = (*userIdPckg)(); + + if (*aEapIdType == DMMTSY_PHONE1_EAP_IDTYPE) + { + userId.iEapId = DMMTSY_PHONE1_EAP_UID; + iPhone->AddDelayedReq(aTsyReqHandle, this); + } + else if (*aEapIdType == DMMTSY_PHONE2_EAP_IDTYPE) + { + userId.iEapId = DMMTSY_PHONE2_EAP_UID; + iPhone->AddDelayedReq(aTsyReqHandle, this); + } + else + { + ReqCompleted(aTsyReqHandle, KErrArgument); + } + + return KErrNone; + } + +TInt CSmartCardEapDMmTsy::DMmGetUserIdentityCancel(const TTsyReqHandle aTsyReqHandle) + { + LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmGetUserIdentityCancel called")); + iPhone->RemoveDelayedReq(aTsyReqHandle); + ReqCompleted(aTsyReqHandle, KErrCancel); + return KErrNone; + } + +TInt CSmartCardEapDMmTsy::DMmGetAuthenticationStatus(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapAuthStatus* aAuthStatus) + { + LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmGetAuthenticationStatus called")); + + *aAuthStatus = DMMTSY_PHONE_EAPAUTHSTATUS; + iPhone->AddDelayedReq(aTsyReqHandle, this); + + return KErrNone; + } + +TInt CSmartCardEapDMmTsy::DMmGetAuthenticationStatusCancel(const TTsyReqHandle aTsyReqHandle) + { + LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmGetAuthenticationStatusCancel called")); + iPhone->RemoveDelayedReq(aTsyReqHandle); + ReqCompleted(aTsyReqHandle, KErrCancel); + return KErrNone; + } + +TInt CSmartCardEapDMmTsy::DMmGetEapKey(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapKeyTag* aEapKeyTag, TDes8* aKey) + { + LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmGetEapKey called")); + + RMobileSmartCardEap::TEapKeyV6Pckg *keyPckg = reinterpret_cast(aKey); + RMobileSmartCardEap::TEapKeyV6 &key = (*keyPckg)(); + + if (*aEapKeyTag == DMMTSY_PHONE1_EAPKEYTAG) + { + key.iEapKey = DMMTSY_PHONE1_EAPKEY; + iPhone->AddDelayedReq(aTsyReqHandle, this); + } + else if (*aEapKeyTag == DMMTSY_PHONE2_EAPKEYTAG) + { + key.iEapKey = DMMTSY_PHONE2_EAPKEY; + iPhone->AddDelayedReq(aTsyReqHandle, this); + } + else + { + ReqCompleted(aTsyReqHandle, KErrArgument); + } + + return KErrNone; + } + +TInt CSmartCardEapDMmTsy::DMmGetEapKeyCancel(const TTsyReqHandle aTsyReqHandle) + { + LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmGetEapKeyCancel called")); + iPhone->RemoveDelayedReq(aTsyReqHandle); + ReqCompleted(aTsyReqHandle, KErrCancel); + return KErrNone; + } + +TInt CSmartCardEapDMmTsy::DMmSetAuthenticateDataForPhase1(const TTsyReqHandle aTsyReqHandle, TDes8* aEapAuthData, TInt* aPhase1Size) + { + LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmSetAuthenticateDataForPhase1 called")); + + RMobileSmartCardEap::CEapAuthenticateRequestDataV6* authReq = NULL; + TRAPD(err, authReq = RMobileSmartCardEap::CEapAuthenticateRequestDataV6::NewL()); + if (err != KErrNone) + { + ReqCompleted(aTsyReqHandle, err); + return KErrNone; + } + + TRAP(err, authReq->InternalizeL(*aEapAuthData)); + if (err != KErrNone) + { + ReqCompleted(aTsyReqHandle, err); + return KErrNone; + } + + TPtr8 reqPacket = authReq->GetEapReqPacket(); + if (reqPacket == DMMTSY_PHONE1_EAPPACKET) + { + iRespPtrC.Set(DMMTSY_PHONE2_EAPPACKET); + *aPhase1Size = iRespPtrC.Length(); + } + else if (reqPacket == DMMTSY_PHONE1_EAPPACKET2) + { + iRespPtrC.Set(DMMTSY_PHONE2_EAPPACKET2); + *aPhase1Size = iRespPtrC.Length(); + } + else + { + ReqCompleted(aTsyReqHandle, KErrCorrupt); + return KErrNone; + } + + iPhone->AddDelayedReq(aTsyReqHandle, this); + return KErrNone; + } + +TInt CSmartCardEapDMmTsy::DMmGetAuthenticateDataForPhase2(const TTsyReqHandle aTsyReqHandle, TDes8* aEapAuthData, TDes8* aPhase2Resp) + { + LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmSetAuthenticateDataForPhase2 called")); + + RMobileSmartCardEap::CEapAuthenticateRequestDataV6* authReq = NULL; + TRAPD(err, authReq = RMobileSmartCardEap::CEapAuthenticateRequestDataV6::NewL()); + if (err != KErrNone) + { + ReqCompleted(aTsyReqHandle, err); + return KErrNone; + } + + TRAP(err, authReq->InternalizeL(*aEapAuthData)); + if (err != KErrNone) + { + ReqCompleted(aTsyReqHandle, err); + return KErrNone; + } + + TPtr8 reqPacket = authReq->GetEapReqPacket(); + if (reqPacket != DMMTSY_PHONE1_EAPPACKET && + reqPacket != DMMTSY_PHONE1_EAPPACKET2) + { + ReqCompleted(aTsyReqHandle, KErrCorrupt); + return KErrNone; + } + + aPhase2Resp->Copy(iRespPtrC); + + iPhone->AddDelayedReq(aTsyReqHandle, this); + + return KErrNone; + } + +TInt CSmartCardEapDMmTsy::DMmSmartCardEapAuthenticationCancel(const TTsyReqHandle aTsyReqHandle) + { + LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmSmartCardEapAuthenticationCancel called")); + iPhone->RemoveDelayedReq(aTsyReqHandle); + ReqCompleted(aTsyReqHandle, KErrCancel); + iRespPtrC.Set(NULL, 0); + return KErrNone; + } + +TInt CSmartCardEapDMmTsy::DMmReleaseEapMethod(const TTsyReqHandle aTsyReqHandle) + { + LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmReleaseEapMethod called")); + iSSInitialised = EFalse; + iAccessStatus = RMobileSmartCardEap::EEapMethodUnableToInitialise; + ReqCompleted(aTsyReqHandle, KErrNone); + + DMmCompleteNotifyEapMethodAccessStatusChange(); + + // Simulate availability after 2 secs. + User::After(2000000); + iAccessStatus = RMobileSmartCardEap::EEapMethodAvailable; + DMmCompleteNotifyEapMethodAccessStatusChange(); + + return KErrNone; + } + +TInt CSmartCardEapDMmTsy::DMmGetEapMethodAccessStatus(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapMethodAccessStatus* aEapState) + { + LOGTEXT(_L8("CSmartCardEapDMmTsy::DMmGetEapMethodAccessStatus called")); + *aEapState = iAccessStatus; + ReqCompleted(aTsyReqHandle, KErrNone); + return KErrNone; + } + +TInt CSmartCardEapDMmTsy::DMmNotifyEapMethodAccessStatusChange(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapMethodAccessStatus* aEapState) + { + __ASSERT_ALWAYS(!iEapAccessNotifyData.iNotifyPending, PanicClient(EEtelPanicRequestAsyncTwice)); + + iEapAccessNotifyData.iNotifyPending = ETrue; + iEapAccessNotifyData.iNotifyHandle = aTsyReqHandle; + iEapAccessNotifyData.iNotifyData = aEapState; + + return KErrNone; + } + +TInt CSmartCardEapDMmTsy::DMmNotifyEapMethodAccessStatusChangeCancel(const TTsyReqHandle aTsyReqHandle) + { + if(iEapAccessNotifyData.iNotifyPending) + { + iEapAccessNotifyData.iNotifyPending = EFalse; + ReqCompleted(aTsyReqHandle, KErrCancel); + return KErrNone; + } + + iPhone->ReqCompleted(aTsyReqHandle,KErrNone); + return KErrNone; + } + +void CSmartCardEapDMmTsy::DMmCompleteNotifyEapMethodAccessStatusChange() + { + if(iEapAccessNotifyData.iNotifyPending) + { + iEapAccessNotifyData.iNotifyPending = EFalse; + *(reinterpret_cast(iEapAccessNotifyData.iNotifyData)) = iAccessStatus; + ReqCompleted(iEapAccessNotifyData.iNotifyHandle, KErrNone); + } + } + +RHandleBase* CSmartCardEapDMmTsy::GlobalKernelObjectHandle() + { + return &iSemaphr; + } + +void CSmartCardEapDMmTsy::ClientHasTerminated(TInt aExitReason) + { + // Can TSY do anything with the thread's exit reason? + // Exit code can be a zero (e.g. for KERN-EXEC 0) a positive value + // (e.g. for KERN-EXEC 3) or a negative error. + (void) aExitReason; + + switch (iAccessStatus) + { + case RMobileSmartCardEap::EEapMethodInUseApplicationActive: + iSSInitialised = EFalse; + iAccessStatus = RMobileSmartCardEap::EEapMethodUnableToInitialise; + DMmCompleteNotifyEapMethodAccessStatusChange(); + iSemaphr.Signal(); + + // Simulate availability after 2 secs. + User::After(2000000); + iAccessStatus = RMobileSmartCardEap::EEapMethodAvailable; + DMmCompleteNotifyEapMethodAccessStatusChange(); + break; + + case RMobileSmartCardEap::EEapMethodInUseApplicationInactive: + iAccessStatus = RMobileSmartCardEap::EEapMethodAvailable; + DMmCompleteNotifyEapMethodAccessStatusChange(); + iSemaphr.Signal(); + break; + + default: + ; + } + + //iSemaphr.Signal(); + } + +// +// Class definition for monitoring thread termination +// + +CSmartCardEapDMmTsy::CThreadTerminationNotifier* CSmartCardEapDMmTsy::CThreadTerminationNotifier::NewL(CSmartCardEapDMmTsy* aSubSess, const TThreadId& aId) + { + CThreadTerminationNotifier* self = new(ELeave) CThreadTerminationNotifier(aSubSess); + CleanupStack::PushL(self); + self->ConstructL(aId); + CleanupStack::Pop(self); + return self; + } + +CSmartCardEapDMmTsy::CThreadTerminationNotifier::CThreadTerminationNotifier(CSmartCardEapDMmTsy* aSubSess) +: CActive(EPriorityStandard), iSubSess(aSubSess) + { + } + +void CSmartCardEapDMmTsy::CThreadTerminationNotifier::ConstructL(const TThreadId& aId) + { + TInt openTh = iCliThread.Open(aId); + User::LeaveIfError(openTh); + CActiveScheduler::Add(this); + } + +void CSmartCardEapDMmTsy::CThreadTerminationNotifier::Start() + { + iCliThread.Logon(iStatus); + SetActive(); + } + +void CSmartCardEapDMmTsy::CThreadTerminationNotifier::RunL() + { + iSubSess->ClientHasTerminated(iStatus.Int()); + } + +void CSmartCardEapDMmTsy::CThreadTerminationNotifier::DoCancel() + { + iCliThread.LogonCancel(iStatus); + } + +CSmartCardEapDMmTsy::CThreadTerminationNotifier::~CThreadTerminationNotifier() + { + Cancel(); + iCliThread.Close(); + } + +// +// methods for CActiveListNode +// + +CSmartCardEapDMmTsy::CActiveListNode::CActiveListNode(CActive *aActive, const TTsyReqHandle aTsyReqHandle) : + iActive(aActive), iTsyReqHandle(aTsyReqHandle) + { + } + +CSmartCardEapDMmTsy::CActiveListNode::~CActiveListNode() + { + delete iActive; + }