--- a/telephonyserverplugins/simtsy/src/csimsmartcardeap.cpp Mon May 03 13:37:20 2010 +0300
+++ b/telephonyserverplugins/simtsy/src/csimsmartcardeap.cpp Thu May 06 15:10:38 2010 +0100
@@ -1,1338 +1,1338 @@
-// 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:
-// Defines the CSimSmartCardEap class componenet
-//
-//
-
-/**
- @file
-*/
-
-#include <testconfigfileparser.h>
-#include "csimsmartcardeap.h"
-#include "Simlog.h"
-#include "etelext.h"
-
-// CSimSmartCardEapManager implementation; related to CSimSmartCardEap //
-
-/**
-Default constructor to initialise Ptrs.
-*/
-TEapChngResp::TEapChngResp()
-: iChallenge(NULL), iResp(NULL),
- iAuthStatus(RMobileSmartCardEap::ENoAuthStarted)
- {
- }
-
-/**
-Default constructor to initialise Ptrs.
-*/
-TEapProcedureData::TEapProcedureData()
-: iEapKey(NULL), iEapExtKey(NULL), iEapId(NULL), iEapPsId(NULL)
- {
- }
-
-/**
-Factory constructor.
-*/
-CSimSmartCardEapManager* CSimSmartCardEapManager::NewL(CSimPhone *aPhone)
- {
- CSimSmartCardEapManager* phone = new(ELeave) CSimSmartCardEapManager(aPhone);
- CleanupStack::PushL(phone);
- phone->ConstructL();
- CleanupStack::Pop();
- return phone;
- }
-
-/**
-Default constructor, initialises a pointer to the owner phone object.
-*/
-CSimSmartCardEapManager::CSimSmartCardEapManager(CSimPhone *aPhone)
-: iPhone(aPhone)
- {
- }
-
-/**
-Second-phase constructor.
-*/
-void CSimSmartCardEapManager::ConstructL()
- {
- LOGPHONE1("CSimSmartCardEapManager second phase construction created");
-
- ParseEapInfoL();
-
- LOGPHONE1("CSimSmartCardEapManager second phase construction completed");
- }
-
-/**
-If this is destroyed then so should all EAP sub-session objects.
-*/
-CSimSmartCardEapManager::~CSimSmartCardEapManager()
- {
- LOGPHONE1("CSimSmartCardEapManager destructing");
-
- for (TInt jj = iSubSessionObjs.Count()-1; jj >= 0; jj--)
- {
- delete iSubSessionObjs[jj];
- }
-
- iSubSessionObjs.Close();
-
- ClearParsedData();
-
- LOGPHONE1("CSimSmartCardEapManager destructed");
- }
-
-void CSimSmartCardEapManager::ClearParsedData()
- {
- // Cleanup remaining unused parsed EAP procedure data
- for (TInt jjj = 0; jjj < iEapProcData.Count(); jjj++)
- {
- for (TInt aa = 0; aa < iEapProcData[jjj].iChResp.Count(); aa++)
- {
- TEapChngResp& temp = iEapProcData[jjj].iChResp[aa];
- delete (temp.iChallenge);
- delete (temp.iResp);
- temp.iChallenge = NULL;
- temp.iResp = NULL;
- }
- iEapProcData[jjj].iChResp.Close();
-
- delete iEapProcData[jjj].iEapKey;
- delete iEapProcData[jjj].iEapExtKey;
- delete iEapProcData[jjj].iEapId;
- delete iEapProcData[jjj].iEapPsId;
- iEapProcData[jjj].iEapKey = NULL;
- iEapProcData[jjj].iEapExtKey = NULL;
- iEapProcData[jjj].iEapId = NULL;
- iEapProcData[jjj].iEapPsId = NULL;
- }
-
- iEapProcData.Close();
- iDiscardedProcedure.Close();
- }
-
-/**
-Returns a pointer to the selected config.txt file section.
-*/
-const CTestConfigSection* CSimSmartCardEapManager::CfgFile()
- {
- return iPhone->CfgFile();
- }
-
-/**
-Parses the UICC App EAP specific settings from the config.txt.
-*/
-void CSimSmartCardEapManager::ParseEapInfoL()
- {
- LOGPHONE1("CSimSmartCardEapManager::ParseEapInfoL called");
-
- CTestConfigItem* item = NULL;
-
- LOGPHONE1("Starting to Parse Smart Card EAP Info");
- TInt count = CfgFile()->ItemCount(KScEapProcedures);
-
- // Used in parsing to keep track of the nested items
- TInt nestedKeyTag = 0;
- TInt nestedExtKeyTag = 0;
- TInt nestedIdTag = 0;
- TInt nestedPsIdTag = 0;
- TInt nestedChlTag = 0;
-
- // Counts of the total number of tags (considered as nested tags)
- TInt countKey = CfgFile()->ItemCount(KScEapKeyMSK);
- TInt countExtKey = CfgFile()->ItemCount(KScEapKeyEMSK);
- TInt countId = CfgFile()->ItemCount(KScEapIdentity);
- TInt countPsId = CfgFile()->ItemCount(KScEapPsIdentity);
- TInt countChl = CfgFile()->ItemCount(KScEapChallenge);
-
-
- for (TInt index = 0; index < count; index++)
- {
- item = const_cast<CTestConfigItem*>(CfgFile()->Item(KScEapProcedures, index));
- if(item == NULL)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: SC EAP PROC INFO tag not read [%d]", index);
- continue;
- }
-
- TInt dataFrmt = 0;
- TInt numChallenges = 0;
- TInt ret = KErrNone;
- TPtrC8 appId, eapType;
-
- // To be populated and appended to iEapProcData later
- TEapProcedureData procInfo;
-
- // Get AID; convert to bin if required
- ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 0, appId);
- if(ret != KErrNone)
- {
- LOGPARSERR("appId", ret,0,&KScEapProcedures);
- continue;
- }
- else
- {
- procInfo.iAID = appId;
-
- // AID is always in binary format (because of the RMobileSmartCardEap::Open construction)
- ParseMixedBinaryAsciiDataL(procInfo.iAID);
- }
-
- // Get eap type
- ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 1, eapType);
- if(ret != KErrNone)
- {
- LOGPARSERR("eapType", ret,1,&KScEapProcedures);
- continue;
- }
- else
- {
- // EAP type is always in ASCII
- procInfo.iEapType = eapType;
- }
-
- // Find number of challenges
- ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 2, numChallenges);
- if(ret != KErrNone)
- {
- LOGPARSERR("numChallenges", ret,2,&KScEapProcedures);
- continue;
- }
- else if (numChallenges > (countChl - nestedChlTag))
- {
- LOGPHONE2("ERROR CONFIGURATION FILE PARSING: error SC EAP PROC INFO specifies more challenges than available [%d]", index);
- continue;
- }
- else if (numChallenges < 0)
- {
- LOGPHONE2("ERROR CONFIGURATION FILE PARSING: error SC EAP PROC INFO specifies -ve challenge number [%d]", index);
- continue;
- }
-
- // Get optional data format; this format is used for all data of this parsed procedure
- ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 3, dataFrmt);
- if(ret != KErrNone)
- {
- LOGPHONE2("CONFIGURATION FILE PARSING: SC EAP PROC INFO tag with no data format [%d]", index);
- }
- else if (dataFrmt >= EMaxConfigDataFormat)
- {
- LOGPHONE2("WARNING IN CONFIGURATION FILE PARSING - error wrong data format value SC EAP PROC INFO tag [%d] (ASCII format will be used)", index);
- dataFrmt = EConfigDataFormatAscii;
- }
-
- TPtrC8 ptr;
- TPtr8 tempPtr(NULL,0);
- HBufC8* startData = NULL;
-
- // Get MSK
- if (nestedKeyTag < countKey)
- {
- item = const_cast<CTestConfigItem*>(CfgFile()->Item(KScEapKeyMSK, nestedKeyTag++));
-
- // parse delay and key
- if (item == NULL)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Key tag [%d]", nestedKeyTag-1);
- }
- else
- {
- ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 0, ptr);
- if (ret != KErrNone)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Key tag's data [%d]", nestedKeyTag-1);
- }
- else
- {
- TRAPD(kAllocErr, startData = ptr.AllocL());
- if (kAllocErr != KErrNone)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Key data [%d]", nestedKeyTag-1);
- }
- else
- {
- tempPtr.Set(startData->Des());
- switch (dataFrmt)
- {
- case EConfigDataFormatMixedBinaryAndAscii:
- ParseMixedBinaryAsciiDataL(tempPtr);
- break;
- //case EConfigDataFormatAscii: // Do nothing
- //default:
- }
- // need to re-copy because converting to binary changes size
- TRAP(kAllocErr, procInfo.iEapKey = tempPtr.AllocL());
- if (kAllocErr != KErrNone)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Key data copy [%d]", nestedKeyTag-1);
- }
- delete startData;
- startData = NULL;
- }
- }
- }
- }
- else
- {
- LOGPHONE1("ERROR CONFIGURATION FILE PARSING: NO SC EAP KEY INFO TAG");
- }
-
- // Get EMSK
- if (nestedExtKeyTag < countExtKey)
- {
- item = const_cast<CTestConfigItem*>(CfgFile()->Item(KScEapKeyEMSK, nestedExtKeyTag++));
-
- // parse key
- if (item == NULL)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Ext Key tag [%d]", nestedExtKeyTag-1);
- }
- else
- {
- ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 0, ptr);
- if (ret != KErrNone)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Ext Key tag's data [%d]", nestedExtKeyTag-1);
- }
- else
- {
- TRAPD(kAllocErr, startData = ptr.AllocL());
- if (kAllocErr != KErrNone)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Ext Key data [%d]", nestedExtKeyTag-1);
- }
- else
- {
- tempPtr.Set(startData->Des());
- switch (dataFrmt)
- {
- case EConfigDataFormatMixedBinaryAndAscii:
- ParseMixedBinaryAsciiDataL(tempPtr);
- break;
- //case EConfigDataFormatAscii: // Do nothing
- //default:
- }
- // need to re-copy because converting to binary changes size
- TRAP(kAllocErr, procInfo.iEapExtKey = tempPtr.AllocL());
- if (kAllocErr != KErrNone)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Ext Key data copy [%d]", nestedExtKeyTag-1);
- }
- delete startData;
- startData = NULL;
- }
- }
- }
- }
- else
- {
- LOGPHONE1("ERROR CONFIGURATION FILE PARSING: NO SC EAP EXT KEY INFO TAG");
- }
-
- // Get Permanent Identity
- if (nestedIdTag < countId)
- {
- item = const_cast<CTestConfigItem*>(CfgFile()->Item(KScEapIdentity, nestedIdTag++));
-
- // parse id
- if (item == NULL)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP id tag [%d]", nestedIdTag-1);
- }
- else
- {
- ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 0, ptr);
- if (ret != KErrNone)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Id tag's data [%d]", nestedIdTag-1);
- }
- else
- {
- TRAPD(idAllocErr, startData = ptr.AllocL());
- if (idAllocErr != KErrNone)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Id data [%d]", nestedIdTag-1);
- }
- else
- {
- TPtr8 tempPtr(NULL,0);
- tempPtr.Set(startData->Des());
- switch (dataFrmt)
- {
- case EConfigDataFormatMixedBinaryAndAscii:
- ParseMixedBinaryAsciiDataL(tempPtr);
- break;
- //case EConfigDataFormatAscii: // Do nothing
- //default:
- }
- // need to re-copy because converting to binary changes size
- TRAP(idAllocErr, procInfo.iEapId = tempPtr.AllocL());
- if (idAllocErr != KErrNone)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Id data copy [%d]", nestedIdTag-1);
- }
- delete startData;
- startData = NULL;
- }
- }
- }
- }
- else
- {
- LOGPHONE1("WARNING CONFIGURATION FILE PARSING: NO SC EAP ID INFO TAG");
- }
-
- // Get Pseudonym Identity
- if (nestedPsIdTag < countPsId)
- {
- item = const_cast<CTestConfigItem*>(CfgFile()->Item(KScEapPsIdentity, nestedPsIdTag++));
-
- // parse id
- if (item == NULL)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Pseudonym id tag [%d]", nestedPsIdTag-1);
- }
- else
- {
- ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 0, ptr);
- if (ret != KErrNone)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Pseudonym Id tag's data [%d]", nestedPsIdTag-1);
- }
- else
- {
- TRAPD(idAllocErr, startData = ptr.AllocL());
- if (idAllocErr != KErrNone)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Pseudonym Id data [%d]", nestedPsIdTag-1);
- }
- else
- {
- TPtr8 tempPtr(NULL,0);
- tempPtr.Set(startData->Des());
- switch (dataFrmt)
- {
- case EConfigDataFormatMixedBinaryAndAscii:
- ParseMixedBinaryAsciiDataL(tempPtr);
- break;
- //case EConfigDataFormatAscii: // Do nothing
- //default:
- }
- // need to re-copy because converting to binary changes size
- TRAP(idAllocErr, procInfo.iEapPsId = tempPtr.AllocL());
- if (idAllocErr != KErrNone)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Pseudonym Id data copy [%d]", nestedPsIdTag-1);
- }
- delete startData;
- startData = NULL;
- }
- }
- }
- }
- else
- {
- LOGPHONE1("WARNING CONFIGURATION FILE PARSING: NO SC EAP PS ID INFO TAG");
- }
-
- // Get challenges
- // numChallenges is what is parsed from config.txt and will be
- // decremented in loop till zero is reached.
- // nestedChlTag keeps track of the current KScEapChallenge tag
- // being read of the total; i.e. not just nested.
- // countChl is the total number of KScEapChallenge found.
- while (numChallenges != 0)
- {
- if (nestedChlTag >= countChl)
- {
- LOGPHONE1("WARNING CONFIGURATION FILE PARSING: NO MORE SC EAP Challenge INFO TAG");
- break;
- }
-
- item = const_cast<CTestConfigItem*>(CfgFile()->Item(KScEapChallenge, nestedChlTag++));
- numChallenges--;
-
- // parse delay and challenge/response and auth status
- if (item == NULL)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP challenge tag [%d]", nestedChlTag-1);
- continue;
- }
-
- // Parse challenge
- ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 0, ptr);
- if (ret != KErrNone)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP challenge data [%d]", nestedChlTag-1);
- continue;
- }
-
- TRAPD(leaveErr, startData = ptr.AllocL());
- if (leaveErr != KErrNone)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP challenge data [%d]", nestedChlTag-1);
- continue;
- }
- tempPtr.Set(startData->Des());
- switch (dataFrmt)
- {
- case EConfigDataFormatMixedBinaryAndAscii:
- ParseMixedBinaryAsciiDataL(tempPtr);
- break;
- //case EConfigDataFormatAscii: // Do nothing
- //default:
- }
- TEapChngResp newChRespData;
- TRAP(leaveErr, newChRespData.iChallenge = tempPtr.AllocL());
- if (leaveErr != KErrNone)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP challenge data copy [%d]", nestedKeyTag-1);
- }
- delete startData;
- startData = NULL;
-
- // Parse response
- ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 1, ptr);
- if (ret != KErrNone)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP response data [%d]", nestedChlTag-1);
- continue;
- }
-
- TRAP(leaveErr, startData = ptr.AllocL());
- if (leaveErr != KErrNone)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP response data [%d]", nestedChlTag-1);
- continue;
- }
- tempPtr.Set(startData->Des());
- switch (dataFrmt)
- {
- case EConfigDataFormatMixedBinaryAndAscii:
- ParseMixedBinaryAsciiDataL(tempPtr);
- break;
- //case EConfigDataFormatAscii: // Do nothing
- //default:
- }
- TRAP(leaveErr, newChRespData.iResp = tempPtr.AllocL());
- if (leaveErr != KErrNone)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP response data copy [%d]", nestedKeyTag-1);
- }
- delete startData;
- startData = NULL;
-
- // Parse status
- TInt stat;
- ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 2, stat);
- if (ret != KErrNone)
- {
- LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP auth status [%d]", nestedChlTag-1);
- continue;
- }
-
- newChRespData.iAuthStatus = static_cast<RMobileSmartCardEap::TEapAuthStatus>(stat);
-
- leaveErr = procInfo.iChResp.Append(newChRespData);
- if (leaveErr != KErrNone)
- {
- LOGPHONE3("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP challenge/resp data [%d] [err=%d]", nestedChlTag-1, leaveErr);
- }
- } // end while
-
- TInt errAppend = iEapProcData.Append(procInfo);
- if (errAppend != KErrNone)
- {
- LOGPHONE2("ERROR CONFIGURATION FILE PARSING: Could not store parsed EAP procedure data [err=%d]", errAppend);
- }
- else
- {
- iDiscardedProcedure.Append(EFalse);
- }
- } // end for; parsing EAP procedures from config.txt
-
- LOGPHONE1("CSimSmartCardEapManager::ParseEapInfoL completed");
- }
-
-/**
-Function leaves if <aAID,aEapType> is not in config file.
-
-@leave KErrNotFound if <aAID,aEapType> is not found.
-*/
-void CSimSmartCardEapManager::AID_EapType_ExistsInConfigL(const RMobilePhone::TAID& aAID, const RMobileSmartCardEap::TEapType& aEapType)
- {
- for (TInt ii = 0; ii < iEapProcData.Count(); ii++)
- {
- TEapProcedureData& temp = iEapProcData[ii];
- if (temp.iAID == aAID)
- {
- // two ifs rather than && to help debug
- if (temp.iEapType == aEapType)
- {
- if (!iDiscardedProcedure[ii])
- {
- return;
- }
- }
- }
- }
- User::Leave(KErrNotFound);
- }
-
-CTelObject* CSimSmartCardEapManager::CreateScEapSubSessionL(RMobilePhone::TAID& aAID, RMobileSmartCardEap::TEapType& aEapType)
- {
- LOGPHONE1("CSimSmartCardEapManager::CreateScEapSubSessionL called");
- // If no config exists for this eapAID,eapType pair, then this will leave
- AID_EapType_ExistsInConfigL(aAID, aEapType);
-
- // If exists then phoneScEap guaranteed to get data in
- // InitialiseEapMethod, since only one object can be created
- // using the unique <iAID,iEapType> pair.
-
- CSimSmartCardEap* phoneScEap = NULL;
- TRAPD(err, phoneScEap = CSimSmartCardEap::NewL(iPhone, this, aAID, aEapType));
-
- if (err != KErrNone)
- {
- LOGPHONE2("ERROR could not create CSimSmartCardEap object [err=%d]", err);
- User::Leave(err);
- }
-
- return phoneScEap;
- }
-
-/**
-Returns the first procedure data section, as parsed from the
-config.txt, with aAID and aEapType.
-
-@param aAID
-@param aEapType
-@return The first procedure data with aAID and aEapType from the
- config.txt. NULL if no such procedure data is found.
-*/
-TEapProcedureData* CSimSmartCardEapManager::ProcData(const RMobilePhone::TAID& aAID, const RMobileSmartCardEap::TEapType& aEapType)
- {
- for (TInt ii = 0; ii < iEapProcData.Count(); ii++)
- {
- if (iEapProcData[ii].iAID == aAID)
- {
- // two ifs rather than && to help debug
- if (iEapProcData[ii].iEapType == aEapType)
- {
- if (!iDiscardedProcedure[ii])
- {
- return &iEapProcData[ii];
- }
- }
- }
- }
- return NULL;
- }
-
-void CSimSmartCardEapManager::ProcDataUseCompleted(const TEapProcedureData* aProcData)
- {
- if (aProcData == NULL)
- {
- return;
- }
-
- TInt pos = KErrNotFound;
-
- for (TInt ii = 0; ii < iEapProcData.Count(); ii++)
- {
- if ((&iEapProcData[ii]) == aProcData)
- {
- pos = ii;
- break;
- }
- }
-
- if (pos != KErrNotFound)
- {
- iDiscardedProcedure[pos] = ETrue;
- }
- }
-
-/**
-Register a sub-session object. At the present time, list is maintained
-for clean-up only; i.e. this object stores pointers to all EAP sub-
-session objects.
-*/
-void CSimSmartCardEapManager::RegisterSubSessionL(CSimSmartCardEap* aToRegister)
- {
- iSubSessionObjs.AppendL(aToRegister);
- }
-
-/**
-Remove a sub-session object from list of active sub-sessions.
-*/
-TInt CSimSmartCardEapManager::DeRegisterSubSession(const CSimSmartCardEap* aToDeRegister)
- {
- TInt index = iSubSessionObjs.Find(aToDeRegister);
-
- if (index < 0)
- {
- return index;
- }
-
- iSubSessionObjs.Remove(index);
- iSubSessionObjs.Compress();
-
- return KErrNone;
- }
-
-// CSimSmartCardEap implementation //
-
-CSimSmartCardEap* CSimSmartCardEap::NewL(CSimPhone *aPhone, CSimSmartCardEapManager* aEapMan, RMobilePhone::TAID& aAID, RMobileSmartCardEap::TEapType& aEapType)
- {
- CSimSmartCardEap* phone = new(ELeave) CSimSmartCardEap(aPhone, aAID, aEapType);
- CleanupStack::PushL(phone);
- phone->ConstructL(aEapMan);
- CleanupStack::Pop();
- return phone;
- }
-
-CSimSmartCardEap::CSimSmartCardEap(CSimPhone *aPhone, RMobilePhone::TAID& aAID, RMobileSmartCardEap::TEapType& aEapType)
-: iPhone(aPhone), iProcedureData(NULL), iSSInitialised(EFalse),
- iAccessStatus(RMobileSmartCardEap::EEapMethodAvailable), iAuthStatus(RMobileSmartCardEap::ENoAuthStarted),
- iCliTerminationListener(NULL), iCurrentChallenge(0)
- {
- iAID = aAID;
- iEapType = aEapType;
- }
-
-void CSimSmartCardEap::ConstructL(CSimSmartCardEapManager* aEapMan)
- {
- LOGPHONE1("CSimSmartCardEap: starting second phase construction");
-
- iSemaphr.CreateGlobal(KNullDesC, EOwnerThread);
- aEapMan->RegisterSubSessionL(this);
- iEapMan = aEapMan;
-
- LOGPHONE1("CSimSmartCardEap created");
- }
-
-CSimSmartCardEap::~CSimSmartCardEap()
- {
- if (iCliTerminationListener != NULL)
- {
- delete iCliTerminationListener;
- iCliTerminationListener = NULL;
- }
- iSemaphr.Close();
-
- // remove config entry from manager
- if (iProcedureData != NULL)
- {
- iEapMan->ProcDataUseCompleted(iProcedureData);
- iProcedureData = NULL;
- }
-
- TInt err = iEapMan->DeRegisterSubSession(this);
- LOGPHONE2("CSimSmartCardEap destroyed, deregistering returned %d", err);
-
- iEapMan = NULL;
- }
-
-
-void CSimSmartCardEap::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* CSimSmartCardEap::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* CSimSmartCardEap::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 CSimSmartCardEap::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 CSimSmartCardEap::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 CSimSmartCardEap::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 CSimSmartCardEap::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 CSimSmartCardEap::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 SimInitialiseEapMethod(aTsyReqHandle,
- reinterpret_cast<TThreadId*>(dataPtr));
-
- case EMobileSmartCardEapGetUserIdentity:
- return SimGetUserIdentity(aTsyReqHandle,
- reinterpret_cast<RMobileSmartCardEap::TEapUserIdType*>(dataPtr),
- aPackage.Des2n());
-
- case EMobileSmartCardEapGetAuthenticationStatus:
- return SimGetAuthenticationStatus(aTsyReqHandle,
- reinterpret_cast<RMobileSmartCardEap::TEapAuthStatus*>(dataPtr));
-
- case EMobileSmartCardEapGetEapKey:
- return SimGetEapKey(aTsyReqHandle,
- reinterpret_cast<RMobileSmartCardEap::TEapKeyTag*>(dataPtr),
- aPackage.Des2n());
-
- case EMobileSmartCardEapAuthenticationPhase1:
- return SimSetAuthenticateDataForPhase1(aTsyReqHandle,
- aPackage.Des1n(), reinterpret_cast<TInt*>(dataPtr2));
-
- case EMobileSmartCardEapAuthenticationPhase2:
- return SimGetAuthenticateDataForPhase2(aTsyReqHandle,
- aPackage.Des1n(), aPackage.Des2n());
-
- case EMobileSmartCardEapReleaseEapMethod:
- return SimReleaseEapMethod(aTsyReqHandle);
-
- case EMobileSmartCardEapGetEapMethodAccessStatus:
- return SimGetEapMethodAccessStatus(aTsyReqHandle,
- reinterpret_cast<RMobileSmartCardEap::TEapMethodAccessStatus*>(dataPtr));
-
- case EMobileSmartCardEapNotifyEapMethodAccessStatusChange:
- return SimNotifyEapMethodAccessStatusChange(aTsyReqHandle,
- reinterpret_cast<RMobileSmartCardEap::TEapMethodAccessStatus*>(dataPtr));
-
- default:
- return KErrNotSupported;
- }
- }
-
-TInt CSimSmartCardEap::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 SimGetUserIdentityCancel(aTsyReqHandle);
- case EMobileSmartCardEapGetAuthenticationStatus:
- return SimGetAuthenticationStatusCancel(aTsyReqHandle);
- case EMobileSmartCardEapGetEapKey:
- return SimGetEapKeyCancel(aTsyReqHandle);
- case EMobileSmartCardEapInitialiseEapMethod:
- return SimInitialiseEapMethodCancel(aTsyReqHandle);
- case EMobileSmartCardEapAuthenticationPhase1:
- case EMobileSmartCardEapAuthenticationPhase2:
- return SimSmartCardEapAuthenticationCancel(aTsyReqHandle);
- case EMobileSmartCardEapNotifyEapMethodAccessStatusChange:
- return SimNotifyEapMethodAccessStatusChangeCancel(aTsyReqHandle);
- default:
- return KErrNotSupported;
- }
- }
-
-RHandleBase* CSimSmartCardEap::GlobalKernelObjectHandle()
- {
- return &iSemaphr;
- }
-
-TInt CSimSmartCardEap::SimInitialiseEapMethod(const TTsyReqHandle aTsyReqHandle, TThreadId* aThreadId)
- {
- LOGPHONE1("CSimSmartCardEap::SimInitialiseEapMethod called");
- // This can only be called through RMobileSmartCardEap for one instance
-
- if (iSSInitialised)
- {
- // re-initialise request sent, so will be treated as a mistake
- // and nothing will happen!
- ReqCompleted(aTsyReqHandle, KErrNone);
- }
- else
- {
- delete iCliTerminationListener;
- TRAPD(err, iCliTerminationListener = CThreadTerminationListener::NewL(this, *aThreadId));
- if (err != KErrNone)
- {
- LOGPHONE2("ERROR could not create a client termination listener [err=%d] (not initialised)", err);
- ReqCompleted(aTsyReqHandle, err);
- }
- else
- {
- iProcedureData = iEapMan->ProcData(iAID, iEapType);
- if (iProcedureData == NULL)
- {
- LOGPHONE1("ERROR could not find sub-session's procedure");
- ReqCompleted(aTsyReqHandle, KErrNotFound);
- return KErrNone;
- }
-
- iSSInitialised = ETrue;
- iCliTerminationListener->Start();
- iAccessStatus = RMobileSmartCardEap::EEapMethodInUseApplicationActive;
- SimCompleteNotifyEapMethodAccessStatusChange();
- ReqCompleted(aTsyReqHandle, KErrNone);
- }
- }
-
- return KErrNone;
- }
-
-TInt CSimSmartCardEap::SimInitialiseEapMethodCancel(const TTsyReqHandle aTsyReqHandle)
- {
- LOGPHONE1("CSimSmartCardEap::SimInitialiseEapMethodCancel called");
- iProcedureData = NULL;
- iSSInitialised = EFalse;
- iAccessStatus = RMobileSmartCardEap::EEapMethodAvailable;
- SimCompleteNotifyEapMethodAccessStatusChange();
- ReqCompleted(aTsyReqHandle, KErrCancel);
- return KErrNone;
- }
-
-TInt CSimSmartCardEap::SimGetUserIdentity(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapUserIdType* aEapIdType, TDes8* aUserId)
- {
- LOGPHONE1("CSimSmartCardEap::SimGetUserIdentity called");
-
- RMobileSmartCardEap::TEapUserIdentityV6Pckg *userIdPckg = reinterpret_cast<RMobileSmartCardEap::TEapUserIdentityV6Pckg*>(aUserId);
- RMobileSmartCardEap::TEapUserIdentityV6 &userId = (*userIdPckg)();
-
- // Check that the data structure is supported by the simulated TSY version
- TInt err = iPhone->CheckSimTsyVersion(userId);
- if(err != KErrNone)
- {
- iPhone->ReqCompleted(aTsyReqHandle, err);
- return KErrNone;
- }
-
- if (*aEapIdType == RMobileSmartCardEap::EPermanentIdentity)
- {
- if (iProcedureData->iEapId == NULL)
- {
- ReqCompleted(aTsyReqHandle, KErrNotFound);
- LOGPHONE1("ERROR EAP sub-session does not contain EPermanentIdentity");
- return KErrNone;
- }
-
- userId.iEapId = iProcedureData->iEapId->Des();
- }
- else if (*aEapIdType == RMobileSmartCardEap::EPseudonymIdentity)
- {
- if (iProcedureData->iEapPsId == NULL)
- {
- ReqCompleted(aTsyReqHandle, KErrNotFound);
- LOGPHONE1("ERROR EAP sub-session does not contain EPseudonymIdentity");
- return KErrNone;
- }
-
- userId.iEapId = iProcedureData->iEapPsId->Des();
- }
- else
- {
- ReqCompleted(aTsyReqHandle, KErrArgument);
- LOGPHONE2("ERROR invalid EAP id type requested [tag=%d]", *aEapIdType);
- return KErrNone;
- }
-
- ReqCompleted(aTsyReqHandle, KErrNone);
- return KErrNone;
- }
-
-TInt CSimSmartCardEap::SimGetUserIdentityCancel(const TTsyReqHandle aTsyReqHandle)
- {
- LOGPHONE1("CSimSmartCardEap::SimGetUserIdentityCancel called");
- ReqCompleted(aTsyReqHandle, KErrCancel);
- return KErrNone;
- }
-
-TInt CSimSmartCardEap::SimGetAuthenticationStatus(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapAuthStatus* aAuthStatus)
- {
- LOGPHONE1("CSimSmartCardEap::SimGetAuthenticationStatus called");
-
- (*aAuthStatus) = iAuthStatus;
-
- ReqCompleted(aTsyReqHandle, KErrNone);
- return KErrNone;
- }
-
-TInt CSimSmartCardEap::SimGetAuthenticationStatusCancel(const TTsyReqHandle aTsyReqHandle)
- {
- LOGPHONE1("CSimSmartCardEap::SimGetAuthenticationStatusCancel called");
- ReqCompleted(aTsyReqHandle, KErrCancel);
- return KErrNone;
- }
-
-TInt CSimSmartCardEap::SimGetEapKey(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapKeyTag* aEapKeyTag, TDes8* aKey)
- {
- LOGPHONE1("CSimSmartCardEap::SimGetEapKey called");
-
- RMobileSmartCardEap::TEapKeyV6Pckg *keyPckg = reinterpret_cast<RMobileSmartCardEap::TEapKeyV6Pckg*>(aKey);
- RMobileSmartCardEap::TEapKeyV6 &key = (*keyPckg)();
-
- // Check that the data structure is supported by the simulated TSY version
- TInt err = iPhone->CheckSimTsyVersion(key);
- if(err != KErrNone)
- {
- iPhone->ReqCompleted(aTsyReqHandle, err);
- return KErrNone;
- }
-
- if (*aEapKeyTag == RMobileSmartCardEap::EEapKeyMSK)
- {
- if (iProcedureData->iEapKey == NULL)
- {
- ReqCompleted(aTsyReqHandle, KErrNotFound);
- LOGPHONE1("ERROR EAP sub-session does not contain EEapKeyMSK");
- return KErrNone;
- }
-
- key.iEapKey = iProcedureData->iEapKey->Des();
- }
- else if (*aEapKeyTag == RMobileSmartCardEap::EEapKeyEMSK)
- {
- if (iProcedureData->iEapExtKey == NULL)
- {
- ReqCompleted(aTsyReqHandle, KErrNotFound);
- LOGPHONE1("ERROR EAP sub-session does not contain EEapKeyEMSK");
- return KErrNone;
- }
-
- key.iEapKey = iProcedureData->iEapExtKey->Des();
- }
- else
- {
- ReqCompleted(aTsyReqHandle, KErrArgument);
- LOGPHONE2("ERROR invalid EAP key tag requested [tag=%d]", *aEapKeyTag);
- return KErrNone;
- }
-
- ReqCompleted(aTsyReqHandle, KErrNone);
- return KErrNone;
- }
-
-TInt CSimSmartCardEap::SimGetEapKeyCancel(const TTsyReqHandle aTsyReqHandle)
- {
- LOGPHONE1("CSimSmartCardEap::SimGetEapKeyCancel called");
- ReqCompleted(aTsyReqHandle, KErrCancel);
- return KErrNone;
- }
-
-TInt CSimSmartCardEap::SimSetAuthenticateDataForPhase1(const TTsyReqHandle aTsyReqHandle, TDes8* aEapAuthData, TInt* aPhase1Size)
- {
- LOGPHONE1("CSimSmartCardEap::SimSetAuthenticateDataForPhase1 called");
-
- if (iCurrentChallenge >= iProcedureData->iChResp.Count())
- {
- ReqCompleted(aTsyReqHandle, KErrAccessDenied);
- return KErrNone;
- }
-
- RMobileSmartCardEap::CEapAuthenticateRequestDataV6* authReq = NULL;
- TRAPD(err, authReq = RMobileSmartCardEap::CEapAuthenticateRequestDataV6::NewL());
- if (err != KErrNone)
- {
- LOGPHONE2("ERR Could not allocate memory for challenge request object [err=%d]", err);
- ReqCompleted(aTsyReqHandle, err);
- return KErrNone;
- }
-
- TRAP(err, authReq->InternalizeL(*aEapAuthData));
- if (err != KErrNone)
- {
- LOGPHONE2("ERR Could not allocate memory for challenge request [err=%d]", err);
- ReqCompleted(aTsyReqHandle, err);
- return KErrNone;
- }
-
- TPtr8 reqPacket = authReq->GetEapReqPacket();
-
- TPtr8 tempPtr(NULL, 0);
- tempPtr.Set(iProcedureData->iChResp[iCurrentChallenge].iChallenge->Des());
-
- if (reqPacket != tempPtr)
- {
- LOGPHONE2("ERR challenge request does not match config [currentChallenge=%d]", iCurrentChallenge);
- ReqCompleted(aTsyReqHandle, KErrCorrupt);
- return KErrNone;
- }
-
- (*aPhase1Size) = iProcedureData->iChResp[iCurrentChallenge].iResp->Length();
-
- ReqCompleted(aTsyReqHandle, KErrNone);
- return KErrNone;
- }
-
-TInt CSimSmartCardEap::SimGetAuthenticateDataForPhase2(const TTsyReqHandle aTsyReqHandle, TDes8* /*aEapAuthData*/, TDes8* aPhase2Resp)
- {
- LOGPHONE1("CSimSmartCardEap::SimSetAuthenticateDataForPhase2 called");
-
- if (iCurrentChallenge >= iProcedureData->iChResp.Count())
- {
- ReqCompleted(aTsyReqHandle, KErrAccessDenied);
- return KErrNone;
- }
-
- TPtr8 tempPtr(NULL, 0);
- tempPtr.Set(iProcedureData->iChResp[iCurrentChallenge].iResp->Des());
-
- aPhase2Resp->Copy(tempPtr);
- iAuthStatus = iProcedureData->iChResp[iCurrentChallenge].iAuthStatus;
- iCurrentChallenge++;
-
- ReqCompleted(aTsyReqHandle, KErrNone);
- return KErrNone;
- }
-
-TInt CSimSmartCardEap::SimSmartCardEapAuthenticationCancel(const TTsyReqHandle aTsyReqHandle)
- {
- LOGPHONE1("CSimSmartCardEap::SimSmartCardEapAuthenticationCancel called");
- ReqCompleted(aTsyReqHandle, KErrCancel);
- return KErrNone;
- }
-
-TInt CSimSmartCardEap::SimReleaseEapMethod(const TTsyReqHandle aTsyReqHandle)
- {
- LOGPHONE1("CSimSmartCardEap::SimReleaseEapMethod called");
- iSSInitialised = EFalse;
- iAccessStatus = RMobileSmartCardEap::EEapMethodAvailable;
- ReqCompleted(aTsyReqHandle, KErrNone);
-
- SimCompleteNotifyEapMethodAccessStatusChange();
-
- // remove config entry from manager
- iEapMan->ProcDataUseCompleted(iProcedureData);
- iProcedureData = NULL;
-
- return KErrNone;
- }
-
-TInt CSimSmartCardEap::SimGetEapMethodAccessStatus(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapMethodAccessStatus* aEapState)
- {
- LOGPHONE1("CSimSmartCardEap::SimGetEapMethodAccessStatus called");
- *aEapState = iAccessStatus;
- ReqCompleted(aTsyReqHandle, KErrNone);
- return KErrNone;
- }
-
-TInt CSimSmartCardEap::SimNotifyEapMethodAccessStatusChange(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapMethodAccessStatus* aEapState)
- {
- LOGPHONE1("CSimSmartCardEap::SimNotifyEapMethodAccessStatusChange called");
- __ASSERT_ALWAYS(!iEapAccessNotifyData.iNotifyPending, PanicClient(EEtelPanicRequestAsyncTwice));
-
- iEapAccessNotifyData.iNotifyPending = ETrue;
- iEapAccessNotifyData.iNotifyHandle = aTsyReqHandle;
- iEapAccessNotifyData.iNotifyData = aEapState;
-
- return KErrNone;
- }
-
-TInt CSimSmartCardEap::SimNotifyEapMethodAccessStatusChangeCancel(const TTsyReqHandle aTsyReqHandle)
- {
- LOGPHONE1("CSimSmartCardEap::SimNotifyEapMethodAccessStatusChangeCancel called");
- if(iEapAccessNotifyData.iNotifyPending)
- {
- iEapAccessNotifyData.iNotifyPending = EFalse;
- ReqCompleted(aTsyReqHandle, KErrCancel);
- return KErrNone;
- }
-
-// iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
-
-void CSimSmartCardEap::SimCompleteNotifyEapMethodAccessStatusChange()
- {
- LOGPHONE1("CSimSmartCardEap::SimCompleteNotifyEapMethodAccessStatusChange called");
-
- if(iEapAccessNotifyData.iNotifyPending)
- {
- iEapAccessNotifyData.iNotifyPending = EFalse;
- *(reinterpret_cast<RMobileSmartCardEap::TEapMethodAccessStatus*>(iEapAccessNotifyData.iNotifyData)) = iAccessStatus;
- ReqCompleted(iEapAccessNotifyData.iNotifyHandle, KErrNone);
- }
- }
-
-void CSimSmartCardEap::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.
-
- switch (iAccessStatus)
- {
- case RMobileSmartCardEap::EEapMethodInUseApplicationActive:
- iSSInitialised = EFalse;
- iAccessStatus = RMobileSmartCardEap::EEapMethodAvailable;
- SimCompleteNotifyEapMethodAccessStatusChange();
- iSemaphr.Signal();
-
- // remove config entry from manager
- iEapMan->ProcDataUseCompleted(iProcedureData);
- iProcedureData = NULL;
-
- break;
-
- case RMobileSmartCardEap::EEapMethodInUseApplicationInactive:
- iAccessStatus = RMobileSmartCardEap::EEapMethodAvailable;
- SimCompleteNotifyEapMethodAccessStatusChange();
- iSemaphr.Signal();
- break;
-
- default:
- ;
- }
- }
-
-//
-// Class definition for monitoring thread termination
-//
-
-CSimSmartCardEap::CThreadTerminationListener* CSimSmartCardEap::CThreadTerminationListener::NewL(CSimSmartCardEap* aSubSess, const TThreadId& aId)
- {
- CThreadTerminationListener* self = new(ELeave) CThreadTerminationListener(aSubSess);
- CleanupStack::PushL(self);
- self->ConstructL(aId);
- CleanupStack::Pop(self);
- return self;
- }
-
-CSimSmartCardEap::CThreadTerminationListener::CThreadTerminationListener(CSimSmartCardEap* aSubSess)
-: CActive(EPriorityStandard), iSubSess(aSubSess)
- {
- }
-
-void CSimSmartCardEap::CThreadTerminationListener::ConstructL(const TThreadId& aId)
- {
- TInt openTh = iCliThread.Open(aId);
- User::LeaveIfError(openTh);
- CActiveScheduler::Add(this);
- }
-
-void CSimSmartCardEap::CThreadTerminationListener::Start()
- {
- iCliThread.Logon(iStatus);
- SetActive();
- }
-
-void CSimSmartCardEap::CThreadTerminationListener::RunL()
- {
- iSubSess->ClientHasTerminated(iStatus.Int());
- }
-
-void CSimSmartCardEap::CThreadTerminationListener::DoCancel()
- {
- iCliThread.LogonCancel(iStatus);
- }
-
-CSimSmartCardEap::CThreadTerminationListener::~CThreadTerminationListener()
- {
- Cancel();
- iCliThread.Close();
- }
+// 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:
+// Defines the CSimSmartCardEap class componenet
+//
+//
+
+/**
+ @file
+*/
+
+#include <testconfigfileparser.h>
+#include "csimsmartcardeap.h"
+#include "Simlog.h"
+#include "etelext.h"
+
+// CSimSmartCardEapManager implementation; related to CSimSmartCardEap //
+
+/**
+Default constructor to initialise Ptrs.
+*/
+TEapChngResp::TEapChngResp()
+: iChallenge(NULL), iResp(NULL),
+ iAuthStatus(RMobileSmartCardEap::ENoAuthStarted)
+ {
+ }
+
+/**
+Default constructor to initialise Ptrs.
+*/
+TEapProcedureData::TEapProcedureData()
+: iEapKey(NULL), iEapExtKey(NULL), iEapId(NULL), iEapPsId(NULL)
+ {
+ }
+
+/**
+Factory constructor.
+*/
+CSimSmartCardEapManager* CSimSmartCardEapManager::NewL(CSimPhone *aPhone)
+ {
+ CSimSmartCardEapManager* phone = new(ELeave) CSimSmartCardEapManager(aPhone);
+ CleanupStack::PushL(phone);
+ phone->ConstructL();
+ CleanupStack::Pop();
+ return phone;
+ }
+
+/**
+Default constructor, initialises a pointer to the owner phone object.
+*/
+CSimSmartCardEapManager::CSimSmartCardEapManager(CSimPhone *aPhone)
+: iPhone(aPhone)
+ {
+ }
+
+/**
+Second-phase constructor.
+*/
+void CSimSmartCardEapManager::ConstructL()
+ {
+ LOGPHONE1("CSimSmartCardEapManager second phase construction created");
+
+ ParseEapInfoL();
+
+ LOGPHONE1("CSimSmartCardEapManager second phase construction completed");
+ }
+
+/**
+If this is destroyed then so should all EAP sub-session objects.
+*/
+CSimSmartCardEapManager::~CSimSmartCardEapManager()
+ {
+ LOGPHONE1("CSimSmartCardEapManager destructing");
+
+ for (TInt jj = iSubSessionObjs.Count()-1; jj >= 0; jj--)
+ {
+ delete iSubSessionObjs[jj];
+ }
+
+ iSubSessionObjs.Close();
+
+ ClearParsedData();
+
+ LOGPHONE1("CSimSmartCardEapManager destructed");
+ }
+
+void CSimSmartCardEapManager::ClearParsedData()
+ {
+ // Cleanup remaining unused parsed EAP procedure data
+ for (TInt jjj = 0; jjj < iEapProcData.Count(); jjj++)
+ {
+ for (TInt aa = 0; aa < iEapProcData[jjj].iChResp.Count(); aa++)
+ {
+ TEapChngResp& temp = iEapProcData[jjj].iChResp[aa];
+ delete (temp.iChallenge);
+ delete (temp.iResp);
+ temp.iChallenge = NULL;
+ temp.iResp = NULL;
+ }
+ iEapProcData[jjj].iChResp.Close();
+
+ delete iEapProcData[jjj].iEapKey;
+ delete iEapProcData[jjj].iEapExtKey;
+ delete iEapProcData[jjj].iEapId;
+ delete iEapProcData[jjj].iEapPsId;
+ iEapProcData[jjj].iEapKey = NULL;
+ iEapProcData[jjj].iEapExtKey = NULL;
+ iEapProcData[jjj].iEapId = NULL;
+ iEapProcData[jjj].iEapPsId = NULL;
+ }
+
+ iEapProcData.Close();
+ iDiscardedProcedure.Close();
+ }
+
+/**
+Returns a pointer to the selected config.txt file section.
+*/
+const CTestConfigSection* CSimSmartCardEapManager::CfgFile()
+ {
+ return iPhone->CfgFile();
+ }
+
+/**
+Parses the UICC App EAP specific settings from the config.txt.
+*/
+void CSimSmartCardEapManager::ParseEapInfoL()
+ {
+ LOGPHONE1("CSimSmartCardEapManager::ParseEapInfoL called");
+
+ CTestConfigItem* item = NULL;
+
+ LOGPHONE1("Starting to Parse Smart Card EAP Info");
+ TInt count = CfgFile()->ItemCount(KScEapProcedures);
+
+ // Used in parsing to keep track of the nested items
+ TInt nestedKeyTag = 0;
+ TInt nestedExtKeyTag = 0;
+ TInt nestedIdTag = 0;
+ TInt nestedPsIdTag = 0;
+ TInt nestedChlTag = 0;
+
+ // Counts of the total number of tags (considered as nested tags)
+ TInt countKey = CfgFile()->ItemCount(KScEapKeyMSK);
+ TInt countExtKey = CfgFile()->ItemCount(KScEapKeyEMSK);
+ TInt countId = CfgFile()->ItemCount(KScEapIdentity);
+ TInt countPsId = CfgFile()->ItemCount(KScEapPsIdentity);
+ TInt countChl = CfgFile()->ItemCount(KScEapChallenge);
+
+
+ for (TInt index = 0; index < count; index++)
+ {
+ item = const_cast<CTestConfigItem*>(CfgFile()->Item(KScEapProcedures, index));
+ if(item == NULL)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: SC EAP PROC INFO tag not read [%d]", index);
+ continue;
+ }
+
+ TInt dataFrmt = 0;
+ TInt numChallenges = 0;
+ TInt ret = KErrNone;
+ TPtrC8 appId, eapType;
+
+ // To be populated and appended to iEapProcData later
+ TEapProcedureData procInfo;
+
+ // Get AID; convert to bin if required
+ ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 0, appId);
+ if(ret != KErrNone)
+ {
+ LOGPARSERR("appId", ret,0,&KScEapProcedures);
+ continue;
+ }
+ else
+ {
+ procInfo.iAID = appId;
+
+ // AID is always in binary format (because of the RMobileSmartCardEap::Open construction)
+ ParseMixedBinaryAsciiDataL(procInfo.iAID);
+ }
+
+ // Get eap type
+ ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 1, eapType);
+ if(ret != KErrNone)
+ {
+ LOGPARSERR("eapType", ret,1,&KScEapProcedures);
+ continue;
+ }
+ else
+ {
+ // EAP type is always in ASCII
+ procInfo.iEapType = eapType;
+ }
+
+ // Find number of challenges
+ ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 2, numChallenges);
+ if(ret != KErrNone)
+ {
+ LOGPARSERR("numChallenges", ret,2,&KScEapProcedures);
+ continue;
+ }
+ else if (numChallenges > (countChl - nestedChlTag))
+ {
+ LOGPHONE2("ERROR CONFIGURATION FILE PARSING: error SC EAP PROC INFO specifies more challenges than available [%d]", index);
+ continue;
+ }
+ else if (numChallenges < 0)
+ {
+ LOGPHONE2("ERROR CONFIGURATION FILE PARSING: error SC EAP PROC INFO specifies -ve challenge number [%d]", index);
+ continue;
+ }
+
+ // Get optional data format; this format is used for all data of this parsed procedure
+ ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 3, dataFrmt);
+ if(ret != KErrNone)
+ {
+ LOGPHONE2("CONFIGURATION FILE PARSING: SC EAP PROC INFO tag with no data format [%d]", index);
+ }
+ else if (dataFrmt >= EMaxConfigDataFormat)
+ {
+ LOGPHONE2("WARNING IN CONFIGURATION FILE PARSING - error wrong data format value SC EAP PROC INFO tag [%d] (ASCII format will be used)", index);
+ dataFrmt = EConfigDataFormatAscii;
+ }
+
+ TPtrC8 ptr;
+ TPtr8 tempPtr(NULL,0);
+ HBufC8* startData = NULL;
+
+ // Get MSK
+ if (nestedKeyTag < countKey)
+ {
+ item = const_cast<CTestConfigItem*>(CfgFile()->Item(KScEapKeyMSK, nestedKeyTag++));
+
+ // parse delay and key
+ if (item == NULL)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Key tag [%d]", nestedKeyTag-1);
+ }
+ else
+ {
+ ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 0, ptr);
+ if (ret != KErrNone)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Key tag's data [%d]", nestedKeyTag-1);
+ }
+ else
+ {
+ TRAPD(kAllocErr, startData = ptr.AllocL());
+ if (kAllocErr != KErrNone)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Key data [%d]", nestedKeyTag-1);
+ }
+ else
+ {
+ tempPtr.Set(startData->Des());
+ switch (dataFrmt)
+ {
+ case EConfigDataFormatMixedBinaryAndAscii:
+ ParseMixedBinaryAsciiDataL(tempPtr);
+ break;
+ //case EConfigDataFormatAscii: // Do nothing
+ //default:
+ }
+ // need to re-copy because converting to binary changes size
+ TRAP(kAllocErr, procInfo.iEapKey = tempPtr.AllocL());
+ if (kAllocErr != KErrNone)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Key data copy [%d]", nestedKeyTag-1);
+ }
+ delete startData;
+ startData = NULL;
+ }
+ }
+ }
+ }
+ else
+ {
+ LOGPHONE1("ERROR CONFIGURATION FILE PARSING: NO SC EAP KEY INFO TAG");
+ }
+
+ // Get EMSK
+ if (nestedExtKeyTag < countExtKey)
+ {
+ item = const_cast<CTestConfigItem*>(CfgFile()->Item(KScEapKeyEMSK, nestedExtKeyTag++));
+
+ // parse key
+ if (item == NULL)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Ext Key tag [%d]", nestedExtKeyTag-1);
+ }
+ else
+ {
+ ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 0, ptr);
+ if (ret != KErrNone)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Ext Key tag's data [%d]", nestedExtKeyTag-1);
+ }
+ else
+ {
+ TRAPD(kAllocErr, startData = ptr.AllocL());
+ if (kAllocErr != KErrNone)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Ext Key data [%d]", nestedExtKeyTag-1);
+ }
+ else
+ {
+ tempPtr.Set(startData->Des());
+ switch (dataFrmt)
+ {
+ case EConfigDataFormatMixedBinaryAndAscii:
+ ParseMixedBinaryAsciiDataL(tempPtr);
+ break;
+ //case EConfigDataFormatAscii: // Do nothing
+ //default:
+ }
+ // need to re-copy because converting to binary changes size
+ TRAP(kAllocErr, procInfo.iEapExtKey = tempPtr.AllocL());
+ if (kAllocErr != KErrNone)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Ext Key data copy [%d]", nestedExtKeyTag-1);
+ }
+ delete startData;
+ startData = NULL;
+ }
+ }
+ }
+ }
+ else
+ {
+ LOGPHONE1("ERROR CONFIGURATION FILE PARSING: NO SC EAP EXT KEY INFO TAG");
+ }
+
+ // Get Permanent Identity
+ if (nestedIdTag < countId)
+ {
+ item = const_cast<CTestConfigItem*>(CfgFile()->Item(KScEapIdentity, nestedIdTag++));
+
+ // parse id
+ if (item == NULL)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP id tag [%d]", nestedIdTag-1);
+ }
+ else
+ {
+ ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 0, ptr);
+ if (ret != KErrNone)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Id tag's data [%d]", nestedIdTag-1);
+ }
+ else
+ {
+ TRAPD(idAllocErr, startData = ptr.AllocL());
+ if (idAllocErr != KErrNone)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Id data [%d]", nestedIdTag-1);
+ }
+ else
+ {
+ TPtr8 tempPtr(NULL,0);
+ tempPtr.Set(startData->Des());
+ switch (dataFrmt)
+ {
+ case EConfigDataFormatMixedBinaryAndAscii:
+ ParseMixedBinaryAsciiDataL(tempPtr);
+ break;
+ //case EConfigDataFormatAscii: // Do nothing
+ //default:
+ }
+ // need to re-copy because converting to binary changes size
+ TRAP(idAllocErr, procInfo.iEapId = tempPtr.AllocL());
+ if (idAllocErr != KErrNone)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Id data copy [%d]", nestedIdTag-1);
+ }
+ delete startData;
+ startData = NULL;
+ }
+ }
+ }
+ }
+ else
+ {
+ LOGPHONE1("WARNING CONFIGURATION FILE PARSING: NO SC EAP ID INFO TAG");
+ }
+
+ // Get Pseudonym Identity
+ if (nestedPsIdTag < countPsId)
+ {
+ item = const_cast<CTestConfigItem*>(CfgFile()->Item(KScEapPsIdentity, nestedPsIdTag++));
+
+ // parse id
+ if (item == NULL)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Pseudonym id tag [%d]", nestedPsIdTag-1);
+ }
+ else
+ {
+ ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 0, ptr);
+ if (ret != KErrNone)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Pseudonym Id tag's data [%d]", nestedPsIdTag-1);
+ }
+ else
+ {
+ TRAPD(idAllocErr, startData = ptr.AllocL());
+ if (idAllocErr != KErrNone)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Pseudonym Id data [%d]", nestedPsIdTag-1);
+ }
+ else
+ {
+ TPtr8 tempPtr(NULL,0);
+ tempPtr.Set(startData->Des());
+ switch (dataFrmt)
+ {
+ case EConfigDataFormatMixedBinaryAndAscii:
+ ParseMixedBinaryAsciiDataL(tempPtr);
+ break;
+ //case EConfigDataFormatAscii: // Do nothing
+ //default:
+ }
+ // need to re-copy because converting to binary changes size
+ TRAP(idAllocErr, procInfo.iEapPsId = tempPtr.AllocL());
+ if (idAllocErr != KErrNone)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Pseudonym Id data copy [%d]", nestedPsIdTag-1);
+ }
+ delete startData;
+ startData = NULL;
+ }
+ }
+ }
+ }
+ else
+ {
+ LOGPHONE1("WARNING CONFIGURATION FILE PARSING: NO SC EAP PS ID INFO TAG");
+ }
+
+ // Get challenges
+ // numChallenges is what is parsed from config.txt and will be
+ // decremented in loop till zero is reached.
+ // nestedChlTag keeps track of the current KScEapChallenge tag
+ // being read of the total; i.e. not just nested.
+ // countChl is the total number of KScEapChallenge found.
+ while (numChallenges != 0)
+ {
+ if (nestedChlTag >= countChl)
+ {
+ LOGPHONE1("WARNING CONFIGURATION FILE PARSING: NO MORE SC EAP Challenge INFO TAG");
+ break;
+ }
+
+ item = const_cast<CTestConfigItem*>(CfgFile()->Item(KScEapChallenge, nestedChlTag++));
+ numChallenges--;
+
+ // parse delay and challenge/response and auth status
+ if (item == NULL)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP challenge tag [%d]", nestedChlTag-1);
+ continue;
+ }
+
+ // Parse challenge
+ ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 0, ptr);
+ if (ret != KErrNone)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP challenge data [%d]", nestedChlTag-1);
+ continue;
+ }
+
+ TRAPD(leaveErr, startData = ptr.AllocL());
+ if (leaveErr != KErrNone)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP challenge data [%d]", nestedChlTag-1);
+ continue;
+ }
+ tempPtr.Set(startData->Des());
+ switch (dataFrmt)
+ {
+ case EConfigDataFormatMixedBinaryAndAscii:
+ ParseMixedBinaryAsciiDataL(tempPtr);
+ break;
+ //case EConfigDataFormatAscii: // Do nothing
+ //default:
+ }
+ TEapChngResp newChRespData;
+ TRAP(leaveErr, newChRespData.iChallenge = tempPtr.AllocL());
+ if (leaveErr != KErrNone)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP challenge data copy [%d]", nestedKeyTag-1);
+ }
+ delete startData;
+ startData = NULL;
+
+ // Parse response
+ ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 1, ptr);
+ if (ret != KErrNone)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP response data [%d]", nestedChlTag-1);
+ continue;
+ }
+
+ TRAP(leaveErr, startData = ptr.AllocL());
+ if (leaveErr != KErrNone)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP response data [%d]", nestedChlTag-1);
+ continue;
+ }
+ tempPtr.Set(startData->Des());
+ switch (dataFrmt)
+ {
+ case EConfigDataFormatMixedBinaryAndAscii:
+ ParseMixedBinaryAsciiDataL(tempPtr);
+ break;
+ //case EConfigDataFormatAscii: // Do nothing
+ //default:
+ }
+ TRAP(leaveErr, newChRespData.iResp = tempPtr.AllocL());
+ if (leaveErr != KErrNone)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP response data copy [%d]", nestedKeyTag-1);
+ }
+ delete startData;
+ startData = NULL;
+
+ // Parse status
+ TInt stat;
+ ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 2, stat);
+ if (ret != KErrNone)
+ {
+ LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP auth status [%d]", nestedChlTag-1);
+ continue;
+ }
+
+ newChRespData.iAuthStatus = static_cast<RMobileSmartCardEap::TEapAuthStatus>(stat);
+
+ leaveErr = procInfo.iChResp.Append(newChRespData);
+ if (leaveErr != KErrNone)
+ {
+ LOGPHONE3("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP challenge/resp data [%d] [err=%d]", nestedChlTag-1, leaveErr);
+ }
+ } // end while
+
+ TInt errAppend = iEapProcData.Append(procInfo);
+ if (errAppend != KErrNone)
+ {
+ LOGPHONE2("ERROR CONFIGURATION FILE PARSING: Could not store parsed EAP procedure data [err=%d]", errAppend);
+ }
+ else
+ {
+ iDiscardedProcedure.Append(EFalse);
+ }
+ } // end for; parsing EAP procedures from config.txt
+
+ LOGPHONE1("CSimSmartCardEapManager::ParseEapInfoL completed");
+ }
+
+/**
+Function leaves if <aAID,aEapType> is not in config file.
+
+@leave KErrNotFound if <aAID,aEapType> is not found.
+*/
+void CSimSmartCardEapManager::AID_EapType_ExistsInConfigL(const RMobilePhone::TAID& aAID, const RMobileSmartCardEap::TEapType& aEapType)
+ {
+ for (TInt ii = 0; ii < iEapProcData.Count(); ii++)
+ {
+ TEapProcedureData& temp = iEapProcData[ii];
+ if (temp.iAID == aAID)
+ {
+ // two ifs rather than && to help debug
+ if (temp.iEapType == aEapType)
+ {
+ if (!iDiscardedProcedure[ii])
+ {
+ return;
+ }
+ }
+ }
+ }
+ User::Leave(KErrNotFound);
+ }
+
+CTelObject* CSimSmartCardEapManager::CreateScEapSubSessionL(RMobilePhone::TAID& aAID, RMobileSmartCardEap::TEapType& aEapType)
+ {
+ LOGPHONE1("CSimSmartCardEapManager::CreateScEapSubSessionL called");
+ // If no config exists for this eapAID,eapType pair, then this will leave
+ AID_EapType_ExistsInConfigL(aAID, aEapType);
+
+ // If exists then phoneScEap guaranteed to get data in
+ // InitialiseEapMethod, since only one object can be created
+ // using the unique <iAID,iEapType> pair.
+
+ CSimSmartCardEap* phoneScEap = NULL;
+ TRAPD(err, phoneScEap = CSimSmartCardEap::NewL(iPhone, this, aAID, aEapType));
+
+ if (err != KErrNone)
+ {
+ LOGPHONE2("ERROR could not create CSimSmartCardEap object [err=%d]", err);
+ User::Leave(err);
+ }
+
+ return phoneScEap;
+ }
+
+/**
+Returns the first procedure data section, as parsed from the
+config.txt, with aAID and aEapType.
+
+@param aAID
+@param aEapType
+@return The first procedure data with aAID and aEapType from the
+ config.txt. NULL if no such procedure data is found.
+*/
+TEapProcedureData* CSimSmartCardEapManager::ProcData(const RMobilePhone::TAID& aAID, const RMobileSmartCardEap::TEapType& aEapType)
+ {
+ for (TInt ii = 0; ii < iEapProcData.Count(); ii++)
+ {
+ if (iEapProcData[ii].iAID == aAID)
+ {
+ // two ifs rather than && to help debug
+ if (iEapProcData[ii].iEapType == aEapType)
+ {
+ if (!iDiscardedProcedure[ii])
+ {
+ return &iEapProcData[ii];
+ }
+ }
+ }
+ }
+ return NULL;
+ }
+
+void CSimSmartCardEapManager::ProcDataUseCompleted(const TEapProcedureData* aProcData)
+ {
+ if (aProcData == NULL)
+ {
+ return;
+ }
+
+ TInt pos = KErrNotFound;
+
+ for (TInt ii = 0; ii < iEapProcData.Count(); ii++)
+ {
+ if ((&iEapProcData[ii]) == aProcData)
+ {
+ pos = ii;
+ break;
+ }
+ }
+
+ if (pos != KErrNotFound)
+ {
+ iDiscardedProcedure[pos] = ETrue;
+ }
+ }
+
+/**
+Register a sub-session object. At the present time, list is maintained
+for clean-up only; i.e. this object stores pointers to all EAP sub-
+session objects.
+*/
+void CSimSmartCardEapManager::RegisterSubSessionL(CSimSmartCardEap* aToRegister)
+ {
+ iSubSessionObjs.AppendL(aToRegister);
+ }
+
+/**
+Remove a sub-session object from list of active sub-sessions.
+*/
+TInt CSimSmartCardEapManager::DeRegisterSubSession(const CSimSmartCardEap* aToDeRegister)
+ {
+ TInt index = iSubSessionObjs.Find(aToDeRegister);
+
+ if (index < 0)
+ {
+ return index;
+ }
+
+ iSubSessionObjs.Remove(index);
+ iSubSessionObjs.Compress();
+
+ return KErrNone;
+ }
+
+// CSimSmartCardEap implementation //
+
+CSimSmartCardEap* CSimSmartCardEap::NewL(CSimPhone *aPhone, CSimSmartCardEapManager* aEapMan, RMobilePhone::TAID& aAID, RMobileSmartCardEap::TEapType& aEapType)
+ {
+ CSimSmartCardEap* phone = new(ELeave) CSimSmartCardEap(aPhone, aAID, aEapType);
+ CleanupStack::PushL(phone);
+ phone->ConstructL(aEapMan);
+ CleanupStack::Pop();
+ return phone;
+ }
+
+CSimSmartCardEap::CSimSmartCardEap(CSimPhone *aPhone, RMobilePhone::TAID& aAID, RMobileSmartCardEap::TEapType& aEapType)
+: iPhone(aPhone), iProcedureData(NULL), iSSInitialised(EFalse),
+ iAccessStatus(RMobileSmartCardEap::EEapMethodAvailable), iAuthStatus(RMobileSmartCardEap::ENoAuthStarted),
+ iCliTerminationListener(NULL), iCurrentChallenge(0)
+ {
+ iAID = aAID;
+ iEapType = aEapType;
+ }
+
+void CSimSmartCardEap::ConstructL(CSimSmartCardEapManager* aEapMan)
+ {
+ LOGPHONE1("CSimSmartCardEap: starting second phase construction");
+
+ iSemaphr.CreateGlobal(KNullDesC, EOwnerThread);
+ aEapMan->RegisterSubSessionL(this);
+ iEapMan = aEapMan;
+
+ LOGPHONE1("CSimSmartCardEap created");
+ }
+
+CSimSmartCardEap::~CSimSmartCardEap()
+ {
+ if (iCliTerminationListener != NULL)
+ {
+ delete iCliTerminationListener;
+ iCliTerminationListener = NULL;
+ }
+ iSemaphr.Close();
+
+ // remove config entry from manager
+ if (iProcedureData != NULL)
+ {
+ iEapMan->ProcDataUseCompleted(iProcedureData);
+ iProcedureData = NULL;
+ }
+
+ TInt err = iEapMan->DeRegisterSubSession(this);
+ LOGPHONE2("CSimSmartCardEap destroyed, deregistering returned %d", err);
+
+ iEapMan = NULL;
+ }
+
+
+void CSimSmartCardEap::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* CSimSmartCardEap::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* CSimSmartCardEap::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 CSimSmartCardEap::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 CSimSmartCardEap::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 CSimSmartCardEap::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 CSimSmartCardEap::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 CSimSmartCardEap::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 SimInitialiseEapMethod(aTsyReqHandle,
+ reinterpret_cast<TThreadId*>(dataPtr));
+
+ case EMobileSmartCardEapGetUserIdentity:
+ return SimGetUserIdentity(aTsyReqHandle,
+ reinterpret_cast<RMobileSmartCardEap::TEapUserIdType*>(dataPtr),
+ aPackage.Des2n());
+
+ case EMobileSmartCardEapGetAuthenticationStatus:
+ return SimGetAuthenticationStatus(aTsyReqHandle,
+ reinterpret_cast<RMobileSmartCardEap::TEapAuthStatus*>(dataPtr));
+
+ case EMobileSmartCardEapGetEapKey:
+ return SimGetEapKey(aTsyReqHandle,
+ reinterpret_cast<RMobileSmartCardEap::TEapKeyTag*>(dataPtr),
+ aPackage.Des2n());
+
+ case EMobileSmartCardEapAuthenticationPhase1:
+ return SimSetAuthenticateDataForPhase1(aTsyReqHandle,
+ aPackage.Des1n(), reinterpret_cast<TInt*>(dataPtr2));
+
+ case EMobileSmartCardEapAuthenticationPhase2:
+ return SimGetAuthenticateDataForPhase2(aTsyReqHandle,
+ aPackage.Des1n(), aPackage.Des2n());
+
+ case EMobileSmartCardEapReleaseEapMethod:
+ return SimReleaseEapMethod(aTsyReqHandle);
+
+ case EMobileSmartCardEapGetEapMethodAccessStatus:
+ return SimGetEapMethodAccessStatus(aTsyReqHandle,
+ reinterpret_cast<RMobileSmartCardEap::TEapMethodAccessStatus*>(dataPtr));
+
+ case EMobileSmartCardEapNotifyEapMethodAccessStatusChange:
+ return SimNotifyEapMethodAccessStatusChange(aTsyReqHandle,
+ reinterpret_cast<RMobileSmartCardEap::TEapMethodAccessStatus*>(dataPtr));
+
+ default:
+ return KErrNotSupported;
+ }
+ }
+
+TInt CSimSmartCardEap::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 SimGetUserIdentityCancel(aTsyReqHandle);
+ case EMobileSmartCardEapGetAuthenticationStatus:
+ return SimGetAuthenticationStatusCancel(aTsyReqHandle);
+ case EMobileSmartCardEapGetEapKey:
+ return SimGetEapKeyCancel(aTsyReqHandle);
+ case EMobileSmartCardEapInitialiseEapMethod:
+ return SimInitialiseEapMethodCancel(aTsyReqHandle);
+ case EMobileSmartCardEapAuthenticationPhase1:
+ case EMobileSmartCardEapAuthenticationPhase2:
+ return SimSmartCardEapAuthenticationCancel(aTsyReqHandle);
+ case EMobileSmartCardEapNotifyEapMethodAccessStatusChange:
+ return SimNotifyEapMethodAccessStatusChangeCancel(aTsyReqHandle);
+ default:
+ return KErrNotSupported;
+ }
+ }
+
+RHandleBase* CSimSmartCardEap::GlobalKernelObjectHandle()
+ {
+ return &iSemaphr;
+ }
+
+TInt CSimSmartCardEap::SimInitialiseEapMethod(const TTsyReqHandle aTsyReqHandle, TThreadId* aThreadId)
+ {
+ LOGPHONE1("CSimSmartCardEap::SimInitialiseEapMethod called");
+ // This can only be called through RMobileSmartCardEap for one instance
+
+ if (iSSInitialised)
+ {
+ // re-initialise request sent, so will be treated as a mistake
+ // and nothing will happen!
+ ReqCompleted(aTsyReqHandle, KErrNone);
+ }
+ else
+ {
+ delete iCliTerminationListener;
+ TRAPD(err, iCliTerminationListener = CThreadTerminationListener::NewL(this, *aThreadId));
+ if (err != KErrNone)
+ {
+ LOGPHONE2("ERROR could not create a client termination listener [err=%d] (not initialised)", err);
+ ReqCompleted(aTsyReqHandle, err);
+ }
+ else
+ {
+ iProcedureData = iEapMan->ProcData(iAID, iEapType);
+ if (iProcedureData == NULL)
+ {
+ LOGPHONE1("ERROR could not find sub-session's procedure");
+ ReqCompleted(aTsyReqHandle, KErrNotFound);
+ return KErrNone;
+ }
+
+ iSSInitialised = ETrue;
+ iCliTerminationListener->Start();
+ iAccessStatus = RMobileSmartCardEap::EEapMethodInUseApplicationActive;
+ SimCompleteNotifyEapMethodAccessStatusChange();
+ ReqCompleted(aTsyReqHandle, KErrNone);
+ }
+ }
+
+ return KErrNone;
+ }
+
+TInt CSimSmartCardEap::SimInitialiseEapMethodCancel(const TTsyReqHandle aTsyReqHandle)
+ {
+ LOGPHONE1("CSimSmartCardEap::SimInitialiseEapMethodCancel called");
+ iProcedureData = NULL;
+ iSSInitialised = EFalse;
+ iAccessStatus = RMobileSmartCardEap::EEapMethodAvailable;
+ SimCompleteNotifyEapMethodAccessStatusChange();
+ ReqCompleted(aTsyReqHandle, KErrCancel);
+ return KErrNone;
+ }
+
+TInt CSimSmartCardEap::SimGetUserIdentity(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapUserIdType* aEapIdType, TDes8* aUserId)
+ {
+ LOGPHONE1("CSimSmartCardEap::SimGetUserIdentity called");
+
+ RMobileSmartCardEap::TEapUserIdentityV6Pckg *userIdPckg = reinterpret_cast<RMobileSmartCardEap::TEapUserIdentityV6Pckg*>(aUserId);
+ RMobileSmartCardEap::TEapUserIdentityV6 &userId = (*userIdPckg)();
+
+ // Check that the data structure is supported by the simulated TSY version
+ TInt err = iPhone->CheckSimTsyVersion(userId);
+ if(err != KErrNone)
+ {
+ iPhone->ReqCompleted(aTsyReqHandle, err);
+ return KErrNone;
+ }
+
+ if (*aEapIdType == RMobileSmartCardEap::EPermanentIdentity)
+ {
+ if (iProcedureData->iEapId == NULL)
+ {
+ ReqCompleted(aTsyReqHandle, KErrNotFound);
+ LOGPHONE1("ERROR EAP sub-session does not contain EPermanentIdentity");
+ return KErrNone;
+ }
+
+ userId.iEapId = iProcedureData->iEapId->Des();
+ }
+ else if (*aEapIdType == RMobileSmartCardEap::EPseudonymIdentity)
+ {
+ if (iProcedureData->iEapPsId == NULL)
+ {
+ ReqCompleted(aTsyReqHandle, KErrNotFound);
+ LOGPHONE1("ERROR EAP sub-session does not contain EPseudonymIdentity");
+ return KErrNone;
+ }
+
+ userId.iEapId = iProcedureData->iEapPsId->Des();
+ }
+ else
+ {
+ ReqCompleted(aTsyReqHandle, KErrArgument);
+ LOGPHONE2("ERROR invalid EAP id type requested [tag=%d]", *aEapIdType);
+ return KErrNone;
+ }
+
+ ReqCompleted(aTsyReqHandle, KErrNone);
+ return KErrNone;
+ }
+
+TInt CSimSmartCardEap::SimGetUserIdentityCancel(const TTsyReqHandle aTsyReqHandle)
+ {
+ LOGPHONE1("CSimSmartCardEap::SimGetUserIdentityCancel called");
+ ReqCompleted(aTsyReqHandle, KErrCancel);
+ return KErrNone;
+ }
+
+TInt CSimSmartCardEap::SimGetAuthenticationStatus(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapAuthStatus* aAuthStatus)
+ {
+ LOGPHONE1("CSimSmartCardEap::SimGetAuthenticationStatus called");
+
+ (*aAuthStatus) = iAuthStatus;
+
+ ReqCompleted(aTsyReqHandle, KErrNone);
+ return KErrNone;
+ }
+
+TInt CSimSmartCardEap::SimGetAuthenticationStatusCancel(const TTsyReqHandle aTsyReqHandle)
+ {
+ LOGPHONE1("CSimSmartCardEap::SimGetAuthenticationStatusCancel called");
+ ReqCompleted(aTsyReqHandle, KErrCancel);
+ return KErrNone;
+ }
+
+TInt CSimSmartCardEap::SimGetEapKey(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapKeyTag* aEapKeyTag, TDes8* aKey)
+ {
+ LOGPHONE1("CSimSmartCardEap::SimGetEapKey called");
+
+ RMobileSmartCardEap::TEapKeyV6Pckg *keyPckg = reinterpret_cast<RMobileSmartCardEap::TEapKeyV6Pckg*>(aKey);
+ RMobileSmartCardEap::TEapKeyV6 &key = (*keyPckg)();
+
+ // Check that the data structure is supported by the simulated TSY version
+ TInt err = iPhone->CheckSimTsyVersion(key);
+ if(err != KErrNone)
+ {
+ iPhone->ReqCompleted(aTsyReqHandle, err);
+ return KErrNone;
+ }
+
+ if (*aEapKeyTag == RMobileSmartCardEap::EEapKeyMSK)
+ {
+ if (iProcedureData->iEapKey == NULL)
+ {
+ ReqCompleted(aTsyReqHandle, KErrNotFound);
+ LOGPHONE1("ERROR EAP sub-session does not contain EEapKeyMSK");
+ return KErrNone;
+ }
+
+ key.iEapKey = iProcedureData->iEapKey->Des();
+ }
+ else if (*aEapKeyTag == RMobileSmartCardEap::EEapKeyEMSK)
+ {
+ if (iProcedureData->iEapExtKey == NULL)
+ {
+ ReqCompleted(aTsyReqHandle, KErrNotFound);
+ LOGPHONE1("ERROR EAP sub-session does not contain EEapKeyEMSK");
+ return KErrNone;
+ }
+
+ key.iEapKey = iProcedureData->iEapExtKey->Des();
+ }
+ else
+ {
+ ReqCompleted(aTsyReqHandle, KErrArgument);
+ LOGPHONE2("ERROR invalid EAP key tag requested [tag=%d]", *aEapKeyTag);
+ return KErrNone;
+ }
+
+ ReqCompleted(aTsyReqHandle, KErrNone);
+ return KErrNone;
+ }
+
+TInt CSimSmartCardEap::SimGetEapKeyCancel(const TTsyReqHandle aTsyReqHandle)
+ {
+ LOGPHONE1("CSimSmartCardEap::SimGetEapKeyCancel called");
+ ReqCompleted(aTsyReqHandle, KErrCancel);
+ return KErrNone;
+ }
+
+TInt CSimSmartCardEap::SimSetAuthenticateDataForPhase1(const TTsyReqHandle aTsyReqHandle, TDes8* aEapAuthData, TInt* aPhase1Size)
+ {
+ LOGPHONE1("CSimSmartCardEap::SimSetAuthenticateDataForPhase1 called");
+
+ if (iCurrentChallenge >= iProcedureData->iChResp.Count())
+ {
+ ReqCompleted(aTsyReqHandle, KErrAccessDenied);
+ return KErrNone;
+ }
+
+ RMobileSmartCardEap::CEapAuthenticateRequestDataV6* authReq = NULL;
+ TRAPD(err, authReq = RMobileSmartCardEap::CEapAuthenticateRequestDataV6::NewL());
+ if (err != KErrNone)
+ {
+ LOGPHONE2("ERR Could not allocate memory for challenge request object [err=%d]", err);
+ ReqCompleted(aTsyReqHandle, err);
+ return KErrNone;
+ }
+
+ TRAP(err, authReq->InternalizeL(*aEapAuthData));
+ if (err != KErrNone)
+ {
+ LOGPHONE2("ERR Could not allocate memory for challenge request [err=%d]", err);
+ ReqCompleted(aTsyReqHandle, err);
+ return KErrNone;
+ }
+
+ TPtr8 reqPacket = authReq->GetEapReqPacket();
+
+ TPtr8 tempPtr(NULL, 0);
+ tempPtr.Set(iProcedureData->iChResp[iCurrentChallenge].iChallenge->Des());
+
+ if (reqPacket != tempPtr)
+ {
+ LOGPHONE2("ERR challenge request does not match config [currentChallenge=%d]", iCurrentChallenge);
+ ReqCompleted(aTsyReqHandle, KErrCorrupt);
+ return KErrNone;
+ }
+
+ (*aPhase1Size) = iProcedureData->iChResp[iCurrentChallenge].iResp->Length();
+
+ ReqCompleted(aTsyReqHandle, KErrNone);
+ return KErrNone;
+ }
+
+TInt CSimSmartCardEap::SimGetAuthenticateDataForPhase2(const TTsyReqHandle aTsyReqHandle, TDes8* /*aEapAuthData*/, TDes8* aPhase2Resp)
+ {
+ LOGPHONE1("CSimSmartCardEap::SimSetAuthenticateDataForPhase2 called");
+
+ if (iCurrentChallenge >= iProcedureData->iChResp.Count())
+ {
+ ReqCompleted(aTsyReqHandle, KErrAccessDenied);
+ return KErrNone;
+ }
+
+ TPtr8 tempPtr(NULL, 0);
+ tempPtr.Set(iProcedureData->iChResp[iCurrentChallenge].iResp->Des());
+
+ aPhase2Resp->Copy(tempPtr);
+ iAuthStatus = iProcedureData->iChResp[iCurrentChallenge].iAuthStatus;
+ iCurrentChallenge++;
+
+ ReqCompleted(aTsyReqHandle, KErrNone);
+ return KErrNone;
+ }
+
+TInt CSimSmartCardEap::SimSmartCardEapAuthenticationCancel(const TTsyReqHandle aTsyReqHandle)
+ {
+ LOGPHONE1("CSimSmartCardEap::SimSmartCardEapAuthenticationCancel called");
+ ReqCompleted(aTsyReqHandle, KErrCancel);
+ return KErrNone;
+ }
+
+TInt CSimSmartCardEap::SimReleaseEapMethod(const TTsyReqHandle aTsyReqHandle)
+ {
+ LOGPHONE1("CSimSmartCardEap::SimReleaseEapMethod called");
+ iSSInitialised = EFalse;
+ iAccessStatus = RMobileSmartCardEap::EEapMethodAvailable;
+ ReqCompleted(aTsyReqHandle, KErrNone);
+
+ SimCompleteNotifyEapMethodAccessStatusChange();
+
+ // remove config entry from manager
+ iEapMan->ProcDataUseCompleted(iProcedureData);
+ iProcedureData = NULL;
+
+ return KErrNone;
+ }
+
+TInt CSimSmartCardEap::SimGetEapMethodAccessStatus(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapMethodAccessStatus* aEapState)
+ {
+ LOGPHONE1("CSimSmartCardEap::SimGetEapMethodAccessStatus called");
+ *aEapState = iAccessStatus;
+ ReqCompleted(aTsyReqHandle, KErrNone);
+ return KErrNone;
+ }
+
+TInt CSimSmartCardEap::SimNotifyEapMethodAccessStatusChange(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapMethodAccessStatus* aEapState)
+ {
+ LOGPHONE1("CSimSmartCardEap::SimNotifyEapMethodAccessStatusChange called");
+ __ASSERT_ALWAYS(!iEapAccessNotifyData.iNotifyPending, PanicClient(EEtelPanicRequestAsyncTwice));
+
+ iEapAccessNotifyData.iNotifyPending = ETrue;
+ iEapAccessNotifyData.iNotifyHandle = aTsyReqHandle;
+ iEapAccessNotifyData.iNotifyData = aEapState;
+
+ return KErrNone;
+ }
+
+TInt CSimSmartCardEap::SimNotifyEapMethodAccessStatusChangeCancel(const TTsyReqHandle aTsyReqHandle)
+ {
+ LOGPHONE1("CSimSmartCardEap::SimNotifyEapMethodAccessStatusChangeCancel called");
+ if(iEapAccessNotifyData.iNotifyPending)
+ {
+ iEapAccessNotifyData.iNotifyPending = EFalse;
+ ReqCompleted(aTsyReqHandle, KErrCancel);
+ return KErrNone;
+ }
+
+// iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+
+void CSimSmartCardEap::SimCompleteNotifyEapMethodAccessStatusChange()
+ {
+ LOGPHONE1("CSimSmartCardEap::SimCompleteNotifyEapMethodAccessStatusChange called");
+
+ if(iEapAccessNotifyData.iNotifyPending)
+ {
+ iEapAccessNotifyData.iNotifyPending = EFalse;
+ *(reinterpret_cast<RMobileSmartCardEap::TEapMethodAccessStatus*>(iEapAccessNotifyData.iNotifyData)) = iAccessStatus;
+ ReqCompleted(iEapAccessNotifyData.iNotifyHandle, KErrNone);
+ }
+ }
+
+void CSimSmartCardEap::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.
+
+ switch (iAccessStatus)
+ {
+ case RMobileSmartCardEap::EEapMethodInUseApplicationActive:
+ iSSInitialised = EFalse;
+ iAccessStatus = RMobileSmartCardEap::EEapMethodAvailable;
+ SimCompleteNotifyEapMethodAccessStatusChange();
+ iSemaphr.Signal();
+
+ // remove config entry from manager
+ iEapMan->ProcDataUseCompleted(iProcedureData);
+ iProcedureData = NULL;
+
+ break;
+
+ case RMobileSmartCardEap::EEapMethodInUseApplicationInactive:
+ iAccessStatus = RMobileSmartCardEap::EEapMethodAvailable;
+ SimCompleteNotifyEapMethodAccessStatusChange();
+ iSemaphr.Signal();
+ break;
+
+ default:
+ ;
+ }
+ }
+
+//
+// Class definition for monitoring thread termination
+//
+
+CSimSmartCardEap::CThreadTerminationListener* CSimSmartCardEap::CThreadTerminationListener::NewL(CSimSmartCardEap* aSubSess, const TThreadId& aId)
+ {
+ CThreadTerminationListener* self = new(ELeave) CThreadTerminationListener(aSubSess);
+ CleanupStack::PushL(self);
+ self->ConstructL(aId);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CSimSmartCardEap::CThreadTerminationListener::CThreadTerminationListener(CSimSmartCardEap* aSubSess)
+: CActive(EPriorityStandard), iSubSess(aSubSess)
+ {
+ }
+
+void CSimSmartCardEap::CThreadTerminationListener::ConstructL(const TThreadId& aId)
+ {
+ TInt openTh = iCliThread.Open(aId);
+ User::LeaveIfError(openTh);
+ CActiveScheduler::Add(this);
+ }
+
+void CSimSmartCardEap::CThreadTerminationListener::Start()
+ {
+ iCliThread.Logon(iStatus);
+ SetActive();
+ }
+
+void CSimSmartCardEap::CThreadTerminationListener::RunL()
+ {
+ iSubSess->ClientHasTerminated(iStatus.Int());
+ }
+
+void CSimSmartCardEap::CThreadTerminationListener::DoCancel()
+ {
+ iCliThread.LogonCancel(iStatus);
+ }
+
+CSimSmartCardEap::CThreadTerminationListener::~CThreadTerminationListener()
+ {
+ Cancel();
+ iCliThread.Close();
+ }