telephonyserverplugins/simtsy/src/csimsmartcardeap.cpp
changeset 0 3553901f7fa8
child 19 630d2f34d719
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Defines the CSimSmartCardEap class componenet
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20 */
       
    21 
       
    22 #include <testconfigfileparser.h>
       
    23 #include "csimsmartcardeap.h"
       
    24 #include "Simlog.h"
       
    25 #include "etelext.h"
       
    26 
       
    27 // CSimSmartCardEapManager implementation; related to CSimSmartCardEap //
       
    28 
       
    29 /**
       
    30 Default constructor to initialise Ptrs.
       
    31 */
       
    32 TEapChngResp::TEapChngResp()
       
    33 : iChallenge(NULL), iResp(NULL),
       
    34   iAuthStatus(RMobileSmartCardEap::ENoAuthStarted)
       
    35 	{
       
    36 	}
       
    37 
       
    38 /**
       
    39 Default constructor to initialise Ptrs.
       
    40 */
       
    41 TEapProcedureData::TEapProcedureData()
       
    42 : iEapKey(NULL), iEapExtKey(NULL), iEapId(NULL), iEapPsId(NULL)
       
    43 	{
       
    44 	}
       
    45 
       
    46 /**
       
    47 Factory constructor.
       
    48 */
       
    49 CSimSmartCardEapManager* CSimSmartCardEapManager::NewL(CSimPhone *aPhone)
       
    50 	{
       
    51 	CSimSmartCardEapManager* phone = new(ELeave) CSimSmartCardEapManager(aPhone);
       
    52 	CleanupStack::PushL(phone);
       
    53 	phone->ConstructL();
       
    54 	CleanupStack::Pop();
       
    55 	return phone;
       
    56 	}
       
    57 
       
    58 /**
       
    59 Default constructor, initialises a pointer to the owner phone object.
       
    60 */
       
    61 CSimSmartCardEapManager::CSimSmartCardEapManager(CSimPhone *aPhone)
       
    62 : iPhone(aPhone)
       
    63 	{
       
    64 	}
       
    65 
       
    66 /**
       
    67 Second-phase constructor.
       
    68 */
       
    69 void CSimSmartCardEapManager::ConstructL()
       
    70 	{
       
    71 	LOGPHONE1("CSimSmartCardEapManager second phase construction created");
       
    72 
       
    73 	ParseEapInfoL();
       
    74 
       
    75 	LOGPHONE1("CSimSmartCardEapManager second phase construction completed");
       
    76 	}
       
    77 
       
    78 /**
       
    79 If this is destroyed then so should all EAP sub-session objects.
       
    80 */
       
    81 CSimSmartCardEapManager::~CSimSmartCardEapManager()
       
    82 	{
       
    83 	LOGPHONE1("CSimSmartCardEapManager destructing");
       
    84 
       
    85 	for (TInt jj = iSubSessionObjs.Count()-1; jj >= 0; jj--)
       
    86 		{
       
    87 		delete iSubSessionObjs[jj];
       
    88 		}
       
    89 
       
    90 	iSubSessionObjs.Close();
       
    91 
       
    92 	ClearParsedData();
       
    93 
       
    94 	LOGPHONE1("CSimSmartCardEapManager destructed");
       
    95 	}
       
    96 
       
    97 void CSimSmartCardEapManager::ClearParsedData()
       
    98 	{
       
    99 	// Cleanup remaining unused parsed EAP procedure data
       
   100 	for (TInt jjj = 0; jjj < iEapProcData.Count(); jjj++)
       
   101 		{
       
   102 		for (TInt aa = 0; aa < iEapProcData[jjj].iChResp.Count(); aa++)
       
   103 			{
       
   104 			TEapChngResp& temp = iEapProcData[jjj].iChResp[aa];
       
   105 			delete (temp.iChallenge);
       
   106 			delete (temp.iResp);
       
   107 			temp.iChallenge = NULL;
       
   108 			temp.iResp = NULL;
       
   109 			}
       
   110 		iEapProcData[jjj].iChResp.Close();
       
   111 
       
   112 		delete iEapProcData[jjj].iEapKey;
       
   113 		delete iEapProcData[jjj].iEapExtKey;
       
   114 		delete iEapProcData[jjj].iEapId;
       
   115 		delete iEapProcData[jjj].iEapPsId;
       
   116 		iEapProcData[jjj].iEapKey = NULL;
       
   117 		iEapProcData[jjj].iEapExtKey = NULL;
       
   118 		iEapProcData[jjj].iEapId = NULL;
       
   119 		iEapProcData[jjj].iEapPsId = NULL;
       
   120 		}
       
   121 
       
   122 	iEapProcData.Close();
       
   123 	iDiscardedProcedure.Close();
       
   124 	}
       
   125 
       
   126 /**
       
   127 Returns a pointer to the selected config.txt file section.
       
   128 */
       
   129 const CTestConfigSection* CSimSmartCardEapManager::CfgFile()
       
   130 	{
       
   131 	return iPhone->CfgFile();
       
   132 	}
       
   133 
       
   134 /**
       
   135 Parses the UICC App EAP specific settings from the config.txt.
       
   136 */
       
   137 void CSimSmartCardEapManager::ParseEapInfoL()
       
   138 	{
       
   139 	LOGPHONE1("CSimSmartCardEapManager::ParseEapInfoL called");
       
   140 
       
   141 	CTestConfigItem* item = NULL;
       
   142 
       
   143 	LOGPHONE1("Starting to Parse Smart Card EAP Info");
       
   144 	TInt count = CfgFile()->ItemCount(KScEapProcedures);
       
   145 
       
   146 	// Used in parsing to keep track of the nested items
       
   147 	TInt nestedKeyTag = 0;
       
   148 	TInt nestedExtKeyTag = 0;
       
   149 	TInt nestedIdTag = 0;
       
   150 	TInt nestedPsIdTag = 0;
       
   151 	TInt nestedChlTag = 0;
       
   152 
       
   153 	// Counts of the total number of tags (considered as nested tags)
       
   154 	TInt countKey = CfgFile()->ItemCount(KScEapKeyMSK);
       
   155 	TInt countExtKey = CfgFile()->ItemCount(KScEapKeyEMSK);
       
   156 	TInt countId = CfgFile()->ItemCount(KScEapIdentity);
       
   157 	TInt countPsId = CfgFile()->ItemCount(KScEapPsIdentity);
       
   158 	TInt countChl = CfgFile()->ItemCount(KScEapChallenge);
       
   159 
       
   160 
       
   161 	for (TInt index = 0; index < count; index++)
       
   162 		{
       
   163 		item = const_cast<CTestConfigItem*>(CfgFile()->Item(KScEapProcedures, index));
       
   164 		if(item == NULL)
       
   165 			{
       
   166 			LOGPHONE2("WARNING CONFIGURATION FILE PARSING: SC EAP PROC INFO tag not read [%d]", index);
       
   167 			continue;
       
   168 			}
       
   169 
       
   170 		TInt dataFrmt = 0;
       
   171 		TInt numChallenges = 0;
       
   172 		TInt ret = KErrNone;
       
   173 		TPtrC8 appId, eapType;
       
   174 
       
   175 		// To be populated and appended to iEapProcData later
       
   176 		TEapProcedureData procInfo;
       
   177 
       
   178 		// Get AID; convert to bin if required
       
   179 		ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 0, appId);
       
   180 		if(ret != KErrNone)
       
   181 			{
       
   182 			LOGPARSERR("appId", ret,0,&KScEapProcedures);
       
   183 			continue;
       
   184 			}
       
   185 		else
       
   186 			{
       
   187 			procInfo.iAID = appId;
       
   188 
       
   189 			// AID is always in binary format (because of the RMobileSmartCardEap::Open construction)
       
   190 			ParseMixedBinaryAsciiDataL(procInfo.iAID);
       
   191 			}
       
   192 
       
   193 		// Get eap type
       
   194 		ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 1, eapType);
       
   195 		if(ret != KErrNone)
       
   196 			{
       
   197 			LOGPARSERR("eapType", ret,1,&KScEapProcedures);
       
   198 			continue;
       
   199 			}
       
   200 		else
       
   201 			{
       
   202 			// EAP type is always in ASCII
       
   203 			procInfo.iEapType = eapType;
       
   204 			}
       
   205 
       
   206 		// Find number of challenges
       
   207 		ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 2, numChallenges);
       
   208 		if(ret != KErrNone)
       
   209 			{
       
   210 			LOGPARSERR("numChallenges", ret,2,&KScEapProcedures);
       
   211 			continue;
       
   212 			}
       
   213 		else if (numChallenges > (countChl - nestedChlTag))
       
   214 			{
       
   215 			LOGPHONE2("ERROR CONFIGURATION FILE PARSING: error SC EAP PROC INFO specifies more challenges than available [%d]", index);
       
   216 			continue;
       
   217 			}
       
   218 		else if (numChallenges < 0)
       
   219 			{
       
   220 			LOGPHONE2("ERROR CONFIGURATION FILE PARSING: error SC EAP PROC INFO specifies -ve challenge number [%d]", index);
       
   221 			continue;
       
   222 			}
       
   223 
       
   224 		// Get optional data format; this format is used for all data of this parsed procedure
       
   225 		ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 3, dataFrmt);
       
   226 		if(ret != KErrNone)
       
   227 			{
       
   228 			LOGPHONE2("CONFIGURATION FILE PARSING: SC EAP PROC INFO tag with no data format [%d]", index);
       
   229 			}
       
   230 		else if (dataFrmt >= EMaxConfigDataFormat)
       
   231 			{
       
   232 			LOGPHONE2("WARNING IN CONFIGURATION FILE PARSING - error wrong data format value SC EAP PROC INFO tag [%d] (ASCII format will be used)", index);
       
   233 			dataFrmt = EConfigDataFormatAscii;
       
   234 			}
       
   235 
       
   236 		TPtrC8 ptr;
       
   237 		TPtr8 tempPtr(NULL,0);
       
   238 		HBufC8* startData = NULL;
       
   239 
       
   240 		// Get MSK
       
   241 		if (nestedKeyTag < countKey)
       
   242 			{
       
   243 			item = const_cast<CTestConfigItem*>(CfgFile()->Item(KScEapKeyMSK, nestedKeyTag++));
       
   244 
       
   245 			// parse delay and key
       
   246 			if (item == NULL)
       
   247 				{
       
   248 				LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Key tag [%d]", nestedKeyTag-1);
       
   249 				}
       
   250 			else
       
   251 				{
       
   252 				ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 0, ptr);
       
   253 				if (ret != KErrNone)
       
   254 					{
       
   255 					LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Key tag's data [%d]", nestedKeyTag-1);
       
   256 					}
       
   257 				else
       
   258 					{
       
   259 					TRAPD(kAllocErr, startData = ptr.AllocL());
       
   260 					if (kAllocErr != KErrNone)
       
   261 						{
       
   262 						LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Key data [%d]", nestedKeyTag-1);
       
   263 						}
       
   264 					else
       
   265 						{
       
   266 						tempPtr.Set(startData->Des());
       
   267 						switch (dataFrmt)
       
   268 							{
       
   269 						case EConfigDataFormatMixedBinaryAndAscii:
       
   270 							ParseMixedBinaryAsciiDataL(tempPtr);
       
   271 							break;
       
   272 						//case EConfigDataFormatAscii: // Do nothing
       
   273 						//default:
       
   274 							}
       
   275 						// need to re-copy because converting to binary changes size
       
   276 						TRAP(kAllocErr, procInfo.iEapKey = tempPtr.AllocL());
       
   277 						if (kAllocErr != KErrNone)
       
   278 							{
       
   279 							LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Key data copy [%d]", nestedKeyTag-1);
       
   280 							}
       
   281 						delete startData;
       
   282 						startData = NULL;
       
   283 						}
       
   284 					}
       
   285 				}
       
   286 			}
       
   287 		else
       
   288 			{
       
   289 			LOGPHONE1("ERROR CONFIGURATION FILE PARSING: NO SC EAP KEY INFO TAG");
       
   290 			}
       
   291 
       
   292 		// Get EMSK
       
   293 		if (nestedExtKeyTag < countExtKey)
       
   294 			{
       
   295 			item = const_cast<CTestConfigItem*>(CfgFile()->Item(KScEapKeyEMSK, nestedExtKeyTag++));
       
   296 
       
   297 			// parse key
       
   298 			if (item == NULL)
       
   299 				{
       
   300 				LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Ext Key tag [%d]", nestedExtKeyTag-1);
       
   301 				}
       
   302 			else
       
   303 				{
       
   304 				ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 0, ptr);
       
   305 				if (ret != KErrNone)
       
   306 					{
       
   307 					LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Ext Key tag's data [%d]", nestedExtKeyTag-1);
       
   308 					}
       
   309 				else
       
   310 					{
       
   311 					TRAPD(kAllocErr, startData = ptr.AllocL());
       
   312 					if (kAllocErr != KErrNone)
       
   313 						{
       
   314 						LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Ext Key data [%d]", nestedExtKeyTag-1);
       
   315 						}
       
   316 					else
       
   317 						{
       
   318 						tempPtr.Set(startData->Des());
       
   319 						switch (dataFrmt)
       
   320 							{
       
   321 						case EConfigDataFormatMixedBinaryAndAscii:
       
   322 							ParseMixedBinaryAsciiDataL(tempPtr);
       
   323 							break;
       
   324 						//case EConfigDataFormatAscii: // Do nothing
       
   325 						//default:
       
   326 							}
       
   327 						// need to re-copy because converting to binary changes size
       
   328 						TRAP(kAllocErr, procInfo.iEapExtKey = tempPtr.AllocL());
       
   329 						if (kAllocErr != KErrNone)
       
   330 							{
       
   331 							LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Ext Key data copy [%d]", nestedExtKeyTag-1);
       
   332 							}
       
   333 						delete startData;
       
   334 						startData = NULL;
       
   335 						}
       
   336 					}
       
   337 				}
       
   338 			}
       
   339 		else
       
   340 			{
       
   341 			LOGPHONE1("ERROR CONFIGURATION FILE PARSING: NO SC EAP EXT KEY INFO TAG");
       
   342 			}
       
   343 
       
   344 		// Get Permanent Identity
       
   345 		if (nestedIdTag < countId)
       
   346 			{
       
   347 			item = const_cast<CTestConfigItem*>(CfgFile()->Item(KScEapIdentity, nestedIdTag++));
       
   348 
       
   349 			// parse id
       
   350 			if (item == NULL)
       
   351 				{
       
   352 				LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP id tag [%d]", nestedIdTag-1);
       
   353 				}
       
   354 			else
       
   355 				{
       
   356 				ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 0, ptr);
       
   357 				if (ret != KErrNone)
       
   358 					{
       
   359 					LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Id tag's data [%d]", nestedIdTag-1);
       
   360 					}
       
   361 				else
       
   362 					{
       
   363 					TRAPD(idAllocErr, startData = ptr.AllocL());
       
   364 					if (idAllocErr != KErrNone)
       
   365 						{
       
   366 						LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Id data [%d]", nestedIdTag-1);
       
   367 						}
       
   368 					else
       
   369 						{
       
   370 						TPtr8 tempPtr(NULL,0);
       
   371 						tempPtr.Set(startData->Des());
       
   372 						switch (dataFrmt)
       
   373 							{
       
   374 						case EConfigDataFormatMixedBinaryAndAscii:
       
   375 							ParseMixedBinaryAsciiDataL(tempPtr);
       
   376 							break;
       
   377 						//case EConfigDataFormatAscii: // Do nothing
       
   378 						//default:
       
   379 							}
       
   380 						// need to re-copy because converting to binary changes size
       
   381 						TRAP(idAllocErr, procInfo.iEapId = tempPtr.AllocL());
       
   382 						if (idAllocErr != KErrNone)
       
   383 							{
       
   384 							LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Id data copy [%d]", nestedIdTag-1);
       
   385 							}
       
   386 						delete startData;
       
   387 						startData = NULL;
       
   388 						}
       
   389 					}
       
   390 				}
       
   391 			}
       
   392 		else
       
   393 			{
       
   394 			LOGPHONE1("WARNING CONFIGURATION FILE PARSING: NO SC EAP ID INFO TAG");
       
   395 			}
       
   396 
       
   397 		// Get Pseudonym Identity
       
   398 		if (nestedPsIdTag < countPsId)
       
   399 			{
       
   400 			item = const_cast<CTestConfigItem*>(CfgFile()->Item(KScEapPsIdentity, nestedPsIdTag++));
       
   401 
       
   402 			// parse id
       
   403 			if (item == NULL)
       
   404 				{
       
   405 				LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Pseudonym id tag [%d]", nestedPsIdTag-1);
       
   406 				}
       
   407 			else
       
   408 				{
       
   409 				ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 0, ptr);
       
   410 				if (ret != KErrNone)
       
   411 					{
       
   412 					LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP Pseudonym Id tag's data [%d]", nestedPsIdTag-1);
       
   413 					}
       
   414 				else
       
   415 					{
       
   416 					TRAPD(idAllocErr, startData = ptr.AllocL());
       
   417 					if (idAllocErr != KErrNone)
       
   418 						{
       
   419 						LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Pseudonym Id data [%d]", nestedPsIdTag-1);
       
   420 						}
       
   421 					else
       
   422 						{
       
   423 						TPtr8 tempPtr(NULL,0);
       
   424 						tempPtr.Set(startData->Des());
       
   425 						switch (dataFrmt)
       
   426 							{
       
   427 						case EConfigDataFormatMixedBinaryAndAscii:
       
   428 							ParseMixedBinaryAsciiDataL(tempPtr);
       
   429 							break;
       
   430 						//case EConfigDataFormatAscii: // Do nothing
       
   431 						//default:
       
   432 							}
       
   433 						// need to re-copy because converting to binary changes size
       
   434 						TRAP(idAllocErr, procInfo.iEapPsId = tempPtr.AllocL());
       
   435 						if (idAllocErr != KErrNone)
       
   436 							{
       
   437 							LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP Pseudonym Id data copy [%d]", nestedPsIdTag-1);
       
   438 							}
       
   439 						delete startData;
       
   440 						startData = NULL;
       
   441 						}
       
   442 					}
       
   443 				}
       
   444 			}
       
   445 		else
       
   446 			{
       
   447 			LOGPHONE1("WARNING CONFIGURATION FILE PARSING: NO SC EAP PS ID INFO TAG");
       
   448 			}
       
   449 
       
   450 		// Get challenges
       
   451 		// numChallenges is what is parsed from config.txt and will be
       
   452 		//    decremented in loop till zero is reached.
       
   453 		// nestedChlTag keeps track of the current KScEapChallenge tag
       
   454 		//    being read of the total; i.e. not just nested.
       
   455 		// countChl is the total number of KScEapChallenge found.
       
   456 		while (numChallenges != 0)
       
   457 			{
       
   458 			if (nestedChlTag >= countChl)
       
   459 				{
       
   460 				LOGPHONE1("WARNING CONFIGURATION FILE PARSING: NO MORE SC EAP Challenge INFO TAG");
       
   461 				break;
       
   462 				}
       
   463 
       
   464 			item = const_cast<CTestConfigItem*>(CfgFile()->Item(KScEapChallenge, nestedChlTag++));
       
   465 			numChallenges--;
       
   466 
       
   467 			// parse delay and challenge/response and auth status
       
   468 			if (item == NULL)
       
   469 				{
       
   470 				LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP challenge tag [%d]", nestedChlTag-1);
       
   471 				continue;
       
   472 				}
       
   473 
       
   474 			// Parse challenge
       
   475 			ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 0, ptr);
       
   476 			if (ret != KErrNone)
       
   477 				{
       
   478 				LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP challenge data [%d]", nestedChlTag-1);
       
   479 				continue;
       
   480 				}
       
   481 
       
   482 			TRAPD(leaveErr, startData = ptr.AllocL());
       
   483 			if (leaveErr != KErrNone)
       
   484 				{
       
   485 				LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP challenge data [%d]", nestedChlTag-1);
       
   486 				continue;
       
   487 				}
       
   488 			tempPtr.Set(startData->Des());
       
   489 			switch (dataFrmt)
       
   490 				{
       
   491 			case EConfigDataFormatMixedBinaryAndAscii:
       
   492 				ParseMixedBinaryAsciiDataL(tempPtr);
       
   493 				break;
       
   494 			//case EConfigDataFormatAscii: // Do nothing
       
   495 			//default:
       
   496 				}
       
   497 			TEapChngResp newChRespData;
       
   498 			TRAP(leaveErr, newChRespData.iChallenge = tempPtr.AllocL());
       
   499 			if (leaveErr != KErrNone)
       
   500 				{
       
   501 				LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP challenge data copy [%d]", nestedKeyTag-1);
       
   502 				}
       
   503 			delete startData;
       
   504 			startData = NULL;
       
   505 
       
   506 			// Parse response
       
   507 			ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 1, ptr);
       
   508 			if (ret != KErrNone)
       
   509 				{
       
   510 				LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP response data [%d]", nestedChlTag-1);
       
   511 				continue;
       
   512 				}
       
   513 
       
   514 			TRAP(leaveErr, startData = ptr.AllocL());
       
   515 			if (leaveErr != KErrNone)
       
   516 				{
       
   517 				LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP response data [%d]", nestedChlTag-1);
       
   518 				continue;
       
   519 				}
       
   520 			tempPtr.Set(startData->Des());
       
   521 			switch (dataFrmt)
       
   522 				{
       
   523 			case EConfigDataFormatMixedBinaryAndAscii:
       
   524 				ParseMixedBinaryAsciiDataL(tempPtr);
       
   525 				break;
       
   526 			//case EConfigDataFormatAscii: // Do nothing
       
   527 			//default:
       
   528 				}
       
   529 			TRAP(leaveErr, newChRespData.iResp = tempPtr.AllocL());
       
   530 			if (leaveErr != KErrNone)
       
   531 				{
       
   532 				LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP response data copy [%d]", nestedKeyTag-1);
       
   533 				}
       
   534 			delete startData;
       
   535 			startData = NULL;
       
   536 
       
   537 			// Parse status
       
   538 			TInt stat;
       
   539 			ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 2, stat);
       
   540 			if (ret != KErrNone)
       
   541 				{
       
   542 				LOGPHONE2("WARNING CONFIGURATION FILE PARSING: could not read EAP auth status [%d]", nestedChlTag-1);
       
   543 				continue;
       
   544 				}
       
   545 
       
   546 			newChRespData.iAuthStatus = static_cast<RMobileSmartCardEap::TEapAuthStatus>(stat);
       
   547 
       
   548 			leaveErr = procInfo.iChResp.Append(newChRespData);
       
   549 			if (leaveErr != KErrNone)
       
   550 				{
       
   551 				LOGPHONE3("WARNING CONFIGURATION FILE PARSING: could not allocate mem for EAP challenge/resp data [%d] [err=%d]", nestedChlTag-1, leaveErr);
       
   552 				}
       
   553 			} // end while
       
   554 
       
   555 		TInt errAppend = iEapProcData.Append(procInfo);
       
   556 		if (errAppend != KErrNone)
       
   557 			{
       
   558 			LOGPHONE2("ERROR CONFIGURATION FILE PARSING: Could not store parsed EAP procedure data [err=%d]", errAppend);
       
   559 			}
       
   560 		else
       
   561 			{
       
   562 			iDiscardedProcedure.Append(EFalse);
       
   563 			}
       
   564 		} // end for; parsing EAP procedures from config.txt
       
   565 
       
   566 	LOGPHONE1("CSimSmartCardEapManager::ParseEapInfoL completed");
       
   567 	}
       
   568 
       
   569 /**
       
   570 Function leaves if <aAID,aEapType> is not in config file.
       
   571 
       
   572 @leave KErrNotFound if <aAID,aEapType> is not found.
       
   573 */
       
   574 void CSimSmartCardEapManager::AID_EapType_ExistsInConfigL(const RMobilePhone::TAID& aAID, const RMobileSmartCardEap::TEapType& aEapType)
       
   575 	{
       
   576 	for (TInt ii = 0; ii < iEapProcData.Count(); ii++)
       
   577 		{
       
   578 		TEapProcedureData& temp = iEapProcData[ii];
       
   579 		if (temp.iAID == aAID)
       
   580 			{
       
   581 			// two ifs rather than && to help debug
       
   582 			if (temp.iEapType == aEapType)
       
   583 				{
       
   584 				if (!iDiscardedProcedure[ii])
       
   585 					{
       
   586 					return;
       
   587 					}
       
   588 				}
       
   589 			}
       
   590 		}
       
   591 	User::Leave(KErrNotFound);
       
   592 	}
       
   593 
       
   594 CTelObject* CSimSmartCardEapManager::CreateScEapSubSessionL(RMobilePhone::TAID& aAID, RMobileSmartCardEap::TEapType& aEapType)
       
   595 	{
       
   596 	LOGPHONE1("CSimSmartCardEapManager::CreateScEapSubSessionL called");
       
   597 	// If no config exists for this eapAID,eapType pair, then this will leave
       
   598 	AID_EapType_ExistsInConfigL(aAID, aEapType);
       
   599 
       
   600 	// If exists then phoneScEap guaranteed to get data in
       
   601 	// InitialiseEapMethod, since only one object can be created
       
   602 	// using the unique <iAID,iEapType> pair.
       
   603 
       
   604 	CSimSmartCardEap* phoneScEap = NULL;
       
   605 	TRAPD(err, phoneScEap = CSimSmartCardEap::NewL(iPhone, this, aAID, aEapType));
       
   606 
       
   607 	if (err != KErrNone)
       
   608 		{
       
   609 		LOGPHONE2("ERROR could not create CSimSmartCardEap object [err=%d]", err);
       
   610 		User::Leave(err);
       
   611 		}
       
   612 
       
   613 	return phoneScEap;
       
   614 	}
       
   615 
       
   616 /**
       
   617 Returns the first procedure data section, as parsed from the
       
   618 config.txt, with aAID and aEapType.
       
   619 
       
   620 @param aAID
       
   621 @param aEapType
       
   622 @return The first procedure data with aAID and aEapType from the
       
   623         config.txt.  NULL if no such procedure data is found.
       
   624 */
       
   625 TEapProcedureData* CSimSmartCardEapManager::ProcData(const RMobilePhone::TAID& aAID, const RMobileSmartCardEap::TEapType& aEapType)
       
   626 	{
       
   627 	for (TInt ii = 0; ii < iEapProcData.Count(); ii++)
       
   628 		{
       
   629 		if (iEapProcData[ii].iAID == aAID)
       
   630 			{
       
   631 			// two ifs rather than && to help debug
       
   632 			if (iEapProcData[ii].iEapType == aEapType)
       
   633 				{
       
   634 				if (!iDiscardedProcedure[ii])
       
   635 					{
       
   636 					return &iEapProcData[ii];
       
   637 					}
       
   638 				}
       
   639 			}
       
   640 		}
       
   641 	return NULL;
       
   642 	}
       
   643 
       
   644 void CSimSmartCardEapManager::ProcDataUseCompleted(const TEapProcedureData* aProcData)
       
   645 	{
       
   646 	if (aProcData == NULL)
       
   647 		{
       
   648 		return;
       
   649 		}
       
   650 
       
   651 	TInt pos = KErrNotFound;
       
   652 
       
   653 	for (TInt ii = 0; ii < iEapProcData.Count(); ii++)
       
   654 		{
       
   655 		if ((&iEapProcData[ii]) == aProcData)
       
   656 			{
       
   657 			pos = ii;
       
   658 			break;
       
   659 			}
       
   660 		}
       
   661 
       
   662 	if (pos != KErrNotFound)
       
   663 		{
       
   664 		iDiscardedProcedure[pos] = ETrue;
       
   665 		}
       
   666 	}
       
   667 
       
   668 /**
       
   669 Register a sub-session object.  At the present time, list is maintained
       
   670 for clean-up only; i.e. this object stores pointers to all EAP sub-
       
   671 session objects.
       
   672 */
       
   673 void CSimSmartCardEapManager::RegisterSubSessionL(CSimSmartCardEap* aToRegister)
       
   674 	{
       
   675 	iSubSessionObjs.AppendL(aToRegister);
       
   676 	}
       
   677 
       
   678 /**
       
   679 Remove a sub-session object from list of active sub-sessions.
       
   680 */
       
   681 TInt CSimSmartCardEapManager::DeRegisterSubSession(const CSimSmartCardEap* aToDeRegister)
       
   682 	{
       
   683 	TInt index = iSubSessionObjs.Find(aToDeRegister);
       
   684 
       
   685 	if (index < 0)
       
   686 		{
       
   687 		return index;
       
   688 		}
       
   689 
       
   690 	iSubSessionObjs.Remove(index);
       
   691 	iSubSessionObjs.Compress();
       
   692 
       
   693 	return KErrNone;
       
   694 	}
       
   695 
       
   696 // CSimSmartCardEap implementation //
       
   697 
       
   698 CSimSmartCardEap* CSimSmartCardEap::NewL(CSimPhone *aPhone, CSimSmartCardEapManager* aEapMan, RMobilePhone::TAID& aAID, RMobileSmartCardEap::TEapType& aEapType)
       
   699 	{
       
   700 	CSimSmartCardEap* phone = new(ELeave) CSimSmartCardEap(aPhone, aAID, aEapType);
       
   701 	CleanupStack::PushL(phone);
       
   702 	phone->ConstructL(aEapMan);
       
   703 	CleanupStack::Pop();
       
   704 	return phone;
       
   705 	}
       
   706 
       
   707 CSimSmartCardEap::CSimSmartCardEap(CSimPhone *aPhone, RMobilePhone::TAID& aAID, RMobileSmartCardEap::TEapType& aEapType)
       
   708 : iPhone(aPhone), iProcedureData(NULL), iSSInitialised(EFalse),
       
   709   iAccessStatus(RMobileSmartCardEap::EEapMethodAvailable), iAuthStatus(RMobileSmartCardEap::ENoAuthStarted),
       
   710   iCliTerminationListener(NULL), iCurrentChallenge(0)
       
   711 	{
       
   712 	iAID = aAID;
       
   713 	iEapType = aEapType;
       
   714 	}
       
   715 
       
   716 void CSimSmartCardEap::ConstructL(CSimSmartCardEapManager* aEapMan)
       
   717 	{
       
   718 	LOGPHONE1("CSimSmartCardEap: starting second phase construction");
       
   719 
       
   720 	iSemaphr.CreateGlobal(KNullDesC, EOwnerThread);
       
   721 	aEapMan->RegisterSubSessionL(this);
       
   722 	iEapMan = aEapMan;
       
   723 
       
   724 	LOGPHONE1("CSimSmartCardEap created");
       
   725 	}
       
   726 
       
   727 CSimSmartCardEap::~CSimSmartCardEap()
       
   728 	{
       
   729 	if (iCliTerminationListener != NULL)
       
   730 		{
       
   731 		delete iCliTerminationListener;
       
   732 		iCliTerminationListener = NULL;
       
   733 		}
       
   734 	iSemaphr.Close();
       
   735 
       
   736 	// remove config entry from manager
       
   737 	if (iProcedureData != NULL)
       
   738 		{
       
   739 		iEapMan->ProcDataUseCompleted(iProcedureData);
       
   740 		iProcedureData = NULL;
       
   741 		}
       
   742 
       
   743 	TInt err = iEapMan->DeRegisterSubSession(this);
       
   744 	LOGPHONE2("CSimSmartCardEap destroyed, deregistering returned %d", err);
       
   745 
       
   746 	iEapMan = NULL;
       
   747 	}
       
   748 
       
   749 
       
   750 void CSimSmartCardEap::Init()
       
   751 	{
       
   752 	// server calls this function once it has created the sub-session
       
   753 	// it gives the TSY chance to do any initialisation it may need to do for
       
   754 	// this sub-session
       
   755 	}
       
   756 
       
   757 CTelObject* CSimSmartCardEap::OpenNewObjectByNameL(const TDesC& /*aName*/)
       
   758 	{
       
   759 	// Server calls this function when a client is opening an object from the phone
       
   760 	// for the first time.
       
   761 	// Multiple clients opening handles to the same sub-session object will be dealt with
       
   762 	// by the server - i.e. by reference counting
       
   763 	User::Leave(KErrNotSupported);
       
   764 	return NULL;
       
   765 	}
       
   766 
       
   767 CTelObject* CSimSmartCardEap::OpenNewObjectL(TDes& /*aNewName*/)
       
   768 	{
       
   769 	// all objects opened from the phone are opened by name, hence this method
       
   770 	// is not supported
       
   771 	User::Leave(KErrNotSupported);
       
   772 	return NULL;
       
   773 	}
       
   774 
       
   775 CTelObject::TReqMode CSimSmartCardEap::ReqModeL(const TInt aIpc)
       
   776 	{
       
   777 	// ReqModeL is called from the server's CTelObject::ReqAnalyserL
       
   778 	// in order to check the type of request it has
       
   779 
       
   780 	// The following are example request types for this dummy TSY
       
   781 	// All TSYs do not have to have these request types but they have been given
       
   782 	// "sensible" values in this test code
       
   783 
       
   784 	CTelObject::TReqMode ret = 0;
       
   785 
       
   786 	switch (aIpc)
       
   787 		{
       
   788 	// Non flow-controlled requests
       
   789 	case EMobileSmartCardEapInitialiseEapMethod:
       
   790 	case EMobileSmartCardEapGetUserIdentity:
       
   791 	case EMobileSmartCardEapGetAuthenticationStatus:
       
   792 	case EMobileSmartCardEapGetEapKey:
       
   793 	case EMobileSmartCardEapAuthenticationPhase1:
       
   794 	case EMobileSmartCardEapAuthenticationPhase2:
       
   795 	case EMobileSmartCardEapReleaseEapMethod:
       
   796 	case EMobileSmartCardEapGetEapMethodAccessStatus:
       
   797 		break;
       
   798 
       
   799 	case EMobileSmartCardEapNotifyEapMethodAccessStatusChange:
       
   800 		ret = KReqModeMultipleCompletionEnabled;
       
   801 		break;
       
   802 
       
   803 	default:
       
   804 		User::Leave(KErrNotSupported);
       
   805 		break;
       
   806 		}
       
   807 
       
   808 	return ret;
       
   809 	}
       
   810 
       
   811 TInt CSimSmartCardEap::RegisterNotification(const TInt /*aIpc*/)
       
   812 	{
       
   813 	// RegisterNotification is called when the server recognises that this notification
       
   814 	// is being posted for the first time on this sub-session object.
       
   815 
       
   816 	// It enables the TSY to "turn on" any regular notification messages that it may 
       
   817 	// receive from the phone
       
   818 
       
   819 	return KErrNone;
       
   820 	}
       
   821 
       
   822 TInt CSimSmartCardEap::DeregisterNotification(const TInt /*aIpc*/)
       
   823 	{
       
   824 	// DeregisterNotification is called when the server recognises that this notification
       
   825 	// will not be posted again because the last client to have a handle on this sub-session
       
   826 	// object has just closed the handle.
       
   827 
       
   828 	// It enables the TSY to "turn off" any regular notification messages that it may
       
   829 	// receive from the phone
       
   830 
       
   831 	return KErrNone;
       
   832 	}
       
   833 
       
   834 TInt CSimSmartCardEap::NumberOfSlotsL(const TInt aIpc)
       
   835 	{
       
   836 	// NumberOfSlotsL is called by the server when it is registering a new notification
       
   837 	// It enables the TSY to tell the server how many buffer slots to allocate for
       
   838 	// "repost immediately" notifications that may trigger before clients collect them
       
   839 
       
   840 	TInt numberOfSlots = 1;
       
   841 
       
   842 	switch (aIpc)
       
   843 		{
       
   844 	case EMobileSmartCardEapNotifyEapMethodAccessStatusChange:
       
   845 		numberOfSlots = 3;
       
   846 		break;
       
   847 
       
   848 	default:
       
   849 		// Unknown or invalid Phone IPC
       
   850 		User::Leave(KErrNotSupported);
       
   851 		break;
       
   852 		}
       
   853 
       
   854 	return numberOfSlots;
       
   855 	}
       
   856 
       
   857 TInt CSimSmartCardEap::ExtFunc(const TTsyReqHandle aTsyReqHandle,const TInt aIpc,
       
   858                                const TDataPackage& aPackage)
       
   859 	{
       
   860 	// ExtFunc is called by the server when it has a "extended", i.e. non-core ETel request 
       
   861 	// for the TSY to process
       
   862 	// A request handle, request type and request data are passed to the TSY
       
   863 
       
   864 	TAny* dataPtr = aPackage.Ptr1();
       
   865 	TAny* dataPtr2 = aPackage.Ptr2();
       
   866 
       
   867 	// The request data has to extracted from TDataPackage and the TAny* pointers have to
       
   868 	// be "cast" to the expected request data type
       
   869 
       
   870 	switch(aIpc)
       
   871 		{
       
   872 	// Non-Flow controlled requests
       
   873 
       
   874 	case EMobileSmartCardEapInitialiseEapMethod:
       
   875 		return SimInitialiseEapMethod(aTsyReqHandle,
       
   876 		         reinterpret_cast<TThreadId*>(dataPtr));
       
   877 
       
   878 	case EMobileSmartCardEapGetUserIdentity:
       
   879 		return SimGetUserIdentity(aTsyReqHandle,
       
   880 		         reinterpret_cast<RMobileSmartCardEap::TEapUserIdType*>(dataPtr),
       
   881 		         aPackage.Des2n());
       
   882 
       
   883 	case EMobileSmartCardEapGetAuthenticationStatus:
       
   884 		return SimGetAuthenticationStatus(aTsyReqHandle, 
       
   885 		         reinterpret_cast<RMobileSmartCardEap::TEapAuthStatus*>(dataPtr));
       
   886 
       
   887 	case EMobileSmartCardEapGetEapKey:
       
   888 		return SimGetEapKey(aTsyReqHandle,
       
   889 		         reinterpret_cast<RMobileSmartCardEap::TEapKeyTag*>(dataPtr),
       
   890 		         aPackage.Des2n());
       
   891 
       
   892 	case EMobileSmartCardEapAuthenticationPhase1:
       
   893 		return SimSetAuthenticateDataForPhase1(aTsyReqHandle,
       
   894 		         aPackage.Des1n(), reinterpret_cast<TInt*>(dataPtr2));
       
   895 
       
   896 	case EMobileSmartCardEapAuthenticationPhase2:
       
   897 		return SimGetAuthenticateDataForPhase2(aTsyReqHandle,
       
   898 		         aPackage.Des1n(), aPackage.Des2n());
       
   899 
       
   900 	case EMobileSmartCardEapReleaseEapMethod:
       
   901 		return SimReleaseEapMethod(aTsyReqHandle);
       
   902 
       
   903 	case EMobileSmartCardEapGetEapMethodAccessStatus:
       
   904 		return SimGetEapMethodAccessStatus(aTsyReqHandle,
       
   905 		         reinterpret_cast<RMobileSmartCardEap::TEapMethodAccessStatus*>(dataPtr));
       
   906 
       
   907 	case EMobileSmartCardEapNotifyEapMethodAccessStatusChange:
       
   908 		return SimNotifyEapMethodAccessStatusChange(aTsyReqHandle,
       
   909 		         reinterpret_cast<RMobileSmartCardEap::TEapMethodAccessStatus*>(dataPtr));
       
   910 
       
   911 	default:
       
   912 		return KErrNotSupported;
       
   913 		}
       
   914 	}
       
   915 
       
   916 TInt CSimSmartCardEap::CancelService(const TInt aIpc,const TTsyReqHandle aTsyReqHandle)
       
   917 	{
       
   918 	// CancelService is called by the server when it is "cleaning-up" any still outstanding
       
   919 	// asynchronous requests before closing a client's sub-session.
       
   920 	// This will happen if a client closes its R-class handle without cancelling outstanding
       
   921 	// asynchronous requests.
       
   922 
       
   923 	switch (aIpc)
       
   924 		{
       
   925 	case EMobileSmartCardEapGetUserIdentity:
       
   926 		return SimGetUserIdentityCancel(aTsyReqHandle);
       
   927 	case EMobileSmartCardEapGetAuthenticationStatus:
       
   928 		return SimGetAuthenticationStatusCancel(aTsyReqHandle);
       
   929 	case EMobileSmartCardEapGetEapKey:
       
   930 		return SimGetEapKeyCancel(aTsyReqHandle);
       
   931 	case EMobileSmartCardEapInitialiseEapMethod:
       
   932 		return SimInitialiseEapMethodCancel(aTsyReqHandle);
       
   933 	case EMobileSmartCardEapAuthenticationPhase1:
       
   934 	case EMobileSmartCardEapAuthenticationPhase2:
       
   935 		return SimSmartCardEapAuthenticationCancel(aTsyReqHandle);
       
   936 	case EMobileSmartCardEapNotifyEapMethodAccessStatusChange:
       
   937 		return SimNotifyEapMethodAccessStatusChangeCancel(aTsyReqHandle);
       
   938 	default:
       
   939 		return KErrNotSupported;
       
   940 		}
       
   941 	}
       
   942 
       
   943 RHandleBase* CSimSmartCardEap::GlobalKernelObjectHandle()
       
   944 	{
       
   945 	return &iSemaphr;
       
   946 	}
       
   947 
       
   948 TInt CSimSmartCardEap::SimInitialiseEapMethod(const TTsyReqHandle aTsyReqHandle, TThreadId* aThreadId)
       
   949 	{
       
   950 	LOGPHONE1("CSimSmartCardEap::SimInitialiseEapMethod called");
       
   951 	// This can only be called through RMobileSmartCardEap for one instance
       
   952 
       
   953 	if (iSSInitialised)
       
   954 		{
       
   955 		// re-initialise request sent, so will be treated as a mistake
       
   956 		// and nothing will happen!
       
   957 		ReqCompleted(aTsyReqHandle, KErrNone);
       
   958 		}
       
   959 	else
       
   960 		{
       
   961 		delete iCliTerminationListener;
       
   962 		TRAPD(err, iCliTerminationListener = CThreadTerminationListener::NewL(this, *aThreadId));
       
   963 		if (err != KErrNone)
       
   964 			{
       
   965 			LOGPHONE2("ERROR could not create a client termination listener [err=%d] (not initialised)", err);
       
   966 			ReqCompleted(aTsyReqHandle, err);
       
   967 			}
       
   968 		else
       
   969 			{
       
   970 			iProcedureData = iEapMan->ProcData(iAID, iEapType);
       
   971 			if (iProcedureData == NULL)
       
   972 				{
       
   973 				LOGPHONE1("ERROR could not find sub-session's procedure");
       
   974 				ReqCompleted(aTsyReqHandle, KErrNotFound);
       
   975 				return KErrNone;
       
   976 				}
       
   977 
       
   978 			iSSInitialised = ETrue;
       
   979 			iCliTerminationListener->Start();
       
   980 			iAccessStatus = RMobileSmartCardEap::EEapMethodInUseApplicationActive;
       
   981 			SimCompleteNotifyEapMethodAccessStatusChange();
       
   982 			ReqCompleted(aTsyReqHandle, KErrNone);
       
   983 			}
       
   984 		}
       
   985 
       
   986 	return KErrNone;
       
   987 	}
       
   988 
       
   989 TInt CSimSmartCardEap::SimInitialiseEapMethodCancel(const TTsyReqHandle aTsyReqHandle)
       
   990 	{
       
   991 	LOGPHONE1("CSimSmartCardEap::SimInitialiseEapMethodCancel called");
       
   992 	iProcedureData = NULL;
       
   993 	iSSInitialised = EFalse;
       
   994 	iAccessStatus = RMobileSmartCardEap::EEapMethodAvailable;
       
   995 	SimCompleteNotifyEapMethodAccessStatusChange();
       
   996 	ReqCompleted(aTsyReqHandle, KErrCancel);
       
   997 	return KErrNone;
       
   998 	}
       
   999 
       
  1000 TInt CSimSmartCardEap::SimGetUserIdentity(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapUserIdType* aEapIdType, TDes8* aUserId)
       
  1001 	{
       
  1002 	LOGPHONE1("CSimSmartCardEap::SimGetUserIdentity called");
       
  1003 
       
  1004 	RMobileSmartCardEap::TEapUserIdentityV6Pckg *userIdPckg = reinterpret_cast<RMobileSmartCardEap::TEapUserIdentityV6Pckg*>(aUserId);
       
  1005 	RMobileSmartCardEap::TEapUserIdentityV6 &userId = (*userIdPckg)();
       
  1006 	
       
  1007 	// Check that the data structure is supported by the simulated TSY version
       
  1008 	TInt err = iPhone->CheckSimTsyVersion(userId);
       
  1009 		if(err != KErrNone)
       
  1010 			{
       
  1011 			iPhone->ReqCompleted(aTsyReqHandle, err);
       
  1012 			return KErrNone;
       
  1013 			}
       
  1014 
       
  1015 	if (*aEapIdType == RMobileSmartCardEap::EPermanentIdentity)
       
  1016 		{
       
  1017 		if (iProcedureData->iEapId == NULL)
       
  1018 			{
       
  1019 			ReqCompleted(aTsyReqHandle, KErrNotFound);
       
  1020 			LOGPHONE1("ERROR EAP sub-session does not contain EPermanentIdentity");
       
  1021 			return KErrNone;
       
  1022 			}
       
  1023 
       
  1024 		userId.iEapId = iProcedureData->iEapId->Des();
       
  1025 		}
       
  1026 	else if (*aEapIdType == RMobileSmartCardEap::EPseudonymIdentity)
       
  1027 		{
       
  1028 		if (iProcedureData->iEapPsId == NULL)
       
  1029 			{
       
  1030 			ReqCompleted(aTsyReqHandle, KErrNotFound);
       
  1031 			LOGPHONE1("ERROR EAP sub-session does not contain EPseudonymIdentity");
       
  1032 			return KErrNone;
       
  1033 			}
       
  1034 
       
  1035 		userId.iEapId = iProcedureData->iEapPsId->Des();
       
  1036 		}
       
  1037 	else
       
  1038 		{
       
  1039 		ReqCompleted(aTsyReqHandle, KErrArgument);
       
  1040 		LOGPHONE2("ERROR invalid EAP id type requested [tag=%d]", *aEapIdType);
       
  1041 		return KErrNone;
       
  1042 		}
       
  1043 
       
  1044 	ReqCompleted(aTsyReqHandle, KErrNone);
       
  1045 	return KErrNone;
       
  1046 	}
       
  1047 
       
  1048 TInt CSimSmartCardEap::SimGetUserIdentityCancel(const TTsyReqHandle aTsyReqHandle)
       
  1049 	{
       
  1050 	LOGPHONE1("CSimSmartCardEap::SimGetUserIdentityCancel called");
       
  1051 	ReqCompleted(aTsyReqHandle, KErrCancel);
       
  1052 	return KErrNone;
       
  1053 	}
       
  1054 	
       
  1055 TInt CSimSmartCardEap::SimGetAuthenticationStatus(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapAuthStatus* aAuthStatus)
       
  1056 	{
       
  1057 	LOGPHONE1("CSimSmartCardEap::SimGetAuthenticationStatus called");
       
  1058 
       
  1059 	(*aAuthStatus) = iAuthStatus;
       
  1060 
       
  1061 	ReqCompleted(aTsyReqHandle, KErrNone);
       
  1062 	return KErrNone;
       
  1063 	}
       
  1064 	
       
  1065 TInt CSimSmartCardEap::SimGetAuthenticationStatusCancel(const TTsyReqHandle aTsyReqHandle)
       
  1066 	{
       
  1067 	LOGPHONE1("CSimSmartCardEap::SimGetAuthenticationStatusCancel called");
       
  1068 	ReqCompleted(aTsyReqHandle, KErrCancel);
       
  1069 	return KErrNone;
       
  1070 	}
       
  1071 
       
  1072 TInt CSimSmartCardEap::SimGetEapKey(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapKeyTag* aEapKeyTag, TDes8* aKey)
       
  1073 	{
       
  1074 	LOGPHONE1("CSimSmartCardEap::SimGetEapKey called");
       
  1075 
       
  1076 	RMobileSmartCardEap::TEapKeyV6Pckg *keyPckg = reinterpret_cast<RMobileSmartCardEap::TEapKeyV6Pckg*>(aKey);
       
  1077 	RMobileSmartCardEap::TEapKeyV6 &key = (*keyPckg)();
       
  1078 
       
  1079 	// Check that the data structure is supported by the simulated TSY version
       
  1080 	TInt err = iPhone->CheckSimTsyVersion(key);
       
  1081 		if(err != KErrNone)
       
  1082 			{
       
  1083 			iPhone->ReqCompleted(aTsyReqHandle, err);
       
  1084 			return KErrNone;
       
  1085 			}
       
  1086 
       
  1087 	if (*aEapKeyTag == RMobileSmartCardEap::EEapKeyMSK)
       
  1088 		{
       
  1089 		if (iProcedureData->iEapKey == NULL)
       
  1090 			{
       
  1091 			ReqCompleted(aTsyReqHandle, KErrNotFound);
       
  1092 			LOGPHONE1("ERROR EAP sub-session does not contain EEapKeyMSK");
       
  1093 			return KErrNone;
       
  1094 			}
       
  1095 
       
  1096 		key.iEapKey = iProcedureData->iEapKey->Des();
       
  1097 		}
       
  1098 	else if (*aEapKeyTag == RMobileSmartCardEap::EEapKeyEMSK)
       
  1099 		{
       
  1100 		if (iProcedureData->iEapExtKey == NULL)
       
  1101 			{
       
  1102 			ReqCompleted(aTsyReqHandle, KErrNotFound);
       
  1103 			LOGPHONE1("ERROR EAP sub-session does not contain EEapKeyEMSK");
       
  1104 			return KErrNone;
       
  1105 			}
       
  1106 
       
  1107 		key.iEapKey = iProcedureData->iEapExtKey->Des();
       
  1108 		}
       
  1109 	else
       
  1110 		{
       
  1111 		ReqCompleted(aTsyReqHandle, KErrArgument);
       
  1112 		LOGPHONE2("ERROR invalid EAP key tag requested [tag=%d]", *aEapKeyTag);
       
  1113 		return KErrNone;
       
  1114 		}
       
  1115 
       
  1116 	ReqCompleted(aTsyReqHandle, KErrNone);
       
  1117 	return KErrNone;
       
  1118 	}
       
  1119 
       
  1120 TInt CSimSmartCardEap::SimGetEapKeyCancel(const TTsyReqHandle aTsyReqHandle)
       
  1121 	{
       
  1122 	LOGPHONE1("CSimSmartCardEap::SimGetEapKeyCancel called");
       
  1123 	ReqCompleted(aTsyReqHandle, KErrCancel);
       
  1124 	return KErrNone;
       
  1125 	}
       
  1126 
       
  1127 TInt CSimSmartCardEap::SimSetAuthenticateDataForPhase1(const TTsyReqHandle aTsyReqHandle, TDes8* aEapAuthData, TInt* aPhase1Size)
       
  1128 	{
       
  1129 	LOGPHONE1("CSimSmartCardEap::SimSetAuthenticateDataForPhase1 called");
       
  1130 
       
  1131 	if (iCurrentChallenge >= iProcedureData->iChResp.Count())
       
  1132 		{
       
  1133 		ReqCompleted(aTsyReqHandle, KErrAccessDenied);
       
  1134 		return KErrNone;
       
  1135 		}
       
  1136 
       
  1137 	RMobileSmartCardEap::CEapAuthenticateRequestDataV6* authReq = NULL;
       
  1138 	TRAPD(err, authReq = RMobileSmartCardEap::CEapAuthenticateRequestDataV6::NewL());
       
  1139 	if (err != KErrNone)
       
  1140 		{
       
  1141 		LOGPHONE2("ERR Could not allocate memory for challenge request object [err=%d]", err);
       
  1142 		ReqCompleted(aTsyReqHandle, err);
       
  1143 		return KErrNone;
       
  1144 		}
       
  1145 
       
  1146 	TRAP(err, authReq->InternalizeL(*aEapAuthData));
       
  1147 	if (err != KErrNone)
       
  1148 		{
       
  1149 		LOGPHONE2("ERR Could not allocate memory for challenge request [err=%d]", err);
       
  1150 		ReqCompleted(aTsyReqHandle, err);
       
  1151 		return KErrNone;
       
  1152 		}
       
  1153 
       
  1154 	TPtr8 reqPacket = authReq->GetEapReqPacket();
       
  1155 
       
  1156 	TPtr8 tempPtr(NULL, 0);
       
  1157 	tempPtr.Set(iProcedureData->iChResp[iCurrentChallenge].iChallenge->Des());
       
  1158 
       
  1159 	if (reqPacket != tempPtr)
       
  1160 		{
       
  1161 		LOGPHONE2("ERR challenge request does not match config [currentChallenge=%d]", iCurrentChallenge);
       
  1162 		ReqCompleted(aTsyReqHandle, KErrCorrupt);
       
  1163 		return KErrNone;
       
  1164 		}
       
  1165 
       
  1166 	(*aPhase1Size) = iProcedureData->iChResp[iCurrentChallenge].iResp->Length();
       
  1167 
       
  1168 	ReqCompleted(aTsyReqHandle, KErrNone);
       
  1169 	return KErrNone;
       
  1170 	}
       
  1171 
       
  1172 TInt CSimSmartCardEap::SimGetAuthenticateDataForPhase2(const TTsyReqHandle aTsyReqHandle, TDes8* /*aEapAuthData*/, TDes8* aPhase2Resp)
       
  1173 	{
       
  1174 	LOGPHONE1("CSimSmartCardEap::SimSetAuthenticateDataForPhase2 called");
       
  1175 
       
  1176 	if (iCurrentChallenge >= iProcedureData->iChResp.Count())
       
  1177 		{
       
  1178 		ReqCompleted(aTsyReqHandle, KErrAccessDenied);
       
  1179 		return KErrNone;
       
  1180 		}
       
  1181 
       
  1182 	TPtr8 tempPtr(NULL, 0);
       
  1183 	tempPtr.Set(iProcedureData->iChResp[iCurrentChallenge].iResp->Des());
       
  1184 
       
  1185 	aPhase2Resp->Copy(tempPtr);
       
  1186  	iAuthStatus = iProcedureData->iChResp[iCurrentChallenge].iAuthStatus;
       
  1187  	iCurrentChallenge++;
       
  1188 
       
  1189 	ReqCompleted(aTsyReqHandle, KErrNone);
       
  1190 	return KErrNone;
       
  1191 	}
       
  1192 
       
  1193 TInt CSimSmartCardEap::SimSmartCardEapAuthenticationCancel(const TTsyReqHandle aTsyReqHandle)
       
  1194 	{
       
  1195 	LOGPHONE1("CSimSmartCardEap::SimSmartCardEapAuthenticationCancel called");
       
  1196 	ReqCompleted(aTsyReqHandle, KErrCancel);
       
  1197 	return KErrNone;
       
  1198 	}
       
  1199 
       
  1200 TInt CSimSmartCardEap::SimReleaseEapMethod(const TTsyReqHandle aTsyReqHandle)
       
  1201 	{
       
  1202 	LOGPHONE1("CSimSmartCardEap::SimReleaseEapMethod called");
       
  1203 	iSSInitialised = EFalse;
       
  1204 	iAccessStatus = RMobileSmartCardEap::EEapMethodAvailable;
       
  1205 	ReqCompleted(aTsyReqHandle, KErrNone);
       
  1206 
       
  1207 	SimCompleteNotifyEapMethodAccessStatusChange();
       
  1208 
       
  1209 	// remove config entry from manager
       
  1210 	iEapMan->ProcDataUseCompleted(iProcedureData);
       
  1211 	iProcedureData = NULL;
       
  1212 
       
  1213 	return KErrNone;
       
  1214 	}
       
  1215 
       
  1216 TInt CSimSmartCardEap::SimGetEapMethodAccessStatus(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapMethodAccessStatus* aEapState)
       
  1217 	{
       
  1218 	LOGPHONE1("CSimSmartCardEap::SimGetEapMethodAccessStatus called");
       
  1219 	*aEapState = iAccessStatus;
       
  1220 	ReqCompleted(aTsyReqHandle, KErrNone);
       
  1221 	return KErrNone;
       
  1222 	}
       
  1223 
       
  1224 TInt CSimSmartCardEap::SimNotifyEapMethodAccessStatusChange(const TTsyReqHandle aTsyReqHandle, RMobileSmartCardEap::TEapMethodAccessStatus* aEapState)
       
  1225 	{
       
  1226 	LOGPHONE1("CSimSmartCardEap::SimNotifyEapMethodAccessStatusChange called");
       
  1227 	__ASSERT_ALWAYS(!iEapAccessNotifyData.iNotifyPending, PanicClient(EEtelPanicRequestAsyncTwice));
       
  1228 
       
  1229 	iEapAccessNotifyData.iNotifyPending = ETrue;
       
  1230 	iEapAccessNotifyData.iNotifyHandle = aTsyReqHandle;
       
  1231 	iEapAccessNotifyData.iNotifyData = aEapState;
       
  1232 
       
  1233 	return KErrNone;
       
  1234 	}
       
  1235 
       
  1236 TInt CSimSmartCardEap::SimNotifyEapMethodAccessStatusChangeCancel(const TTsyReqHandle aTsyReqHandle)
       
  1237 	{
       
  1238 	LOGPHONE1("CSimSmartCardEap::SimNotifyEapMethodAccessStatusChangeCancel called");
       
  1239 	if(iEapAccessNotifyData.iNotifyPending)
       
  1240 		{
       
  1241 		iEapAccessNotifyData.iNotifyPending = EFalse;
       
  1242 		ReqCompleted(aTsyReqHandle, KErrCancel);
       
  1243 		return KErrNone;
       
  1244 		}	
       
  1245 
       
  1246 //	iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
       
  1247 	return KErrNone;
       
  1248 	}
       
  1249 
       
  1250 void CSimSmartCardEap::SimCompleteNotifyEapMethodAccessStatusChange()
       
  1251 	{
       
  1252 	LOGPHONE1("CSimSmartCardEap::SimCompleteNotifyEapMethodAccessStatusChange called");
       
  1253 
       
  1254 	if(iEapAccessNotifyData.iNotifyPending)
       
  1255 		{
       
  1256 		iEapAccessNotifyData.iNotifyPending = EFalse;
       
  1257 		*(reinterpret_cast<RMobileSmartCardEap::TEapMethodAccessStatus*>(iEapAccessNotifyData.iNotifyData)) = iAccessStatus;
       
  1258 		ReqCompleted(iEapAccessNotifyData.iNotifyHandle, KErrNone);
       
  1259 		}
       
  1260 	}
       
  1261 
       
  1262 void CSimSmartCardEap::ClientHasTerminated(TInt /*aExitReason*/)
       
  1263 	{
       
  1264 	// Can TSY do anything with the thread's exit reason?
       
  1265 	// Exit code can be a zero (e.g. for KERN-EXEC 0) a positive value
       
  1266 	// (e.g. for KERN-EXEC 3) or a negative error.
       
  1267 
       
  1268 	switch (iAccessStatus)
       
  1269 		{
       
  1270 	case RMobileSmartCardEap::EEapMethodInUseApplicationActive:
       
  1271 		iSSInitialised = EFalse;
       
  1272 		iAccessStatus = RMobileSmartCardEap::EEapMethodAvailable;
       
  1273 		SimCompleteNotifyEapMethodAccessStatusChange();
       
  1274 		iSemaphr.Signal();
       
  1275 
       
  1276 		// remove config entry from manager
       
  1277 		iEapMan->ProcDataUseCompleted(iProcedureData);
       
  1278 		iProcedureData = NULL;
       
  1279 
       
  1280 		break;
       
  1281 
       
  1282 	case RMobileSmartCardEap::EEapMethodInUseApplicationInactive:
       
  1283 		iAccessStatus = RMobileSmartCardEap::EEapMethodAvailable;
       
  1284 		SimCompleteNotifyEapMethodAccessStatusChange();
       
  1285 		iSemaphr.Signal();
       
  1286 		break;
       
  1287 
       
  1288 	default:
       
  1289 		;
       
  1290 		}
       
  1291 	}
       
  1292 
       
  1293 //
       
  1294 // Class definition for monitoring thread termination
       
  1295 //
       
  1296 
       
  1297 CSimSmartCardEap::CThreadTerminationListener* CSimSmartCardEap::CThreadTerminationListener::NewL(CSimSmartCardEap* aSubSess, const TThreadId& aId)
       
  1298 	{
       
  1299 	CThreadTerminationListener* self = new(ELeave) CThreadTerminationListener(aSubSess);
       
  1300 	CleanupStack::PushL(self);
       
  1301 	self->ConstructL(aId);
       
  1302 	CleanupStack::Pop(self);
       
  1303 	return self;
       
  1304 	}
       
  1305 
       
  1306 CSimSmartCardEap::CThreadTerminationListener::CThreadTerminationListener(CSimSmartCardEap* aSubSess)
       
  1307 : CActive(EPriorityStandard), iSubSess(aSubSess)
       
  1308 	{
       
  1309 	}
       
  1310 
       
  1311 void CSimSmartCardEap::CThreadTerminationListener::ConstructL(const TThreadId& aId)
       
  1312 	{
       
  1313 	TInt openTh = iCliThread.Open(aId);
       
  1314 	User::LeaveIfError(openTh);
       
  1315     CActiveScheduler::Add(this);
       
  1316 	}
       
  1317 
       
  1318 void CSimSmartCardEap::CThreadTerminationListener::Start()
       
  1319 	{
       
  1320 	iCliThread.Logon(iStatus);
       
  1321 	SetActive();
       
  1322 	}
       
  1323 
       
  1324 void CSimSmartCardEap::CThreadTerminationListener::RunL()
       
  1325 	{
       
  1326 	iSubSess->ClientHasTerminated(iStatus.Int());
       
  1327 	}
       
  1328 
       
  1329 void CSimSmartCardEap::CThreadTerminationListener::DoCancel()
       
  1330 	{
       
  1331 	iCliThread.LogonCancel(iStatus);
       
  1332 	}
       
  1333 
       
  1334 CSimSmartCardEap::CThreadTerminationListener::~CThreadTerminationListener()
       
  1335 	{
       
  1336 	Cancel();
       
  1337 	iCliThread.Close();
       
  1338 	}