diff -r 000000000000 -r 3553901f7fa8 telephonyserverplugins/simtsy/src/CSimPhoneSmartCardApp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/telephonyserverplugins/simtsy/src/CSimPhoneSmartCardApp.cpp Tue Feb 02 01:41:59 2010 +0200 @@ -0,0 +1,2047 @@ +// Copyright (c) 2002-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: +// Implements the Phone Smart Card application and file manipulation code. +// +// + +/** + @file +*/ + +#include +#include +#include "CSimPhone.h" +#include "Simlog.h" + +// +// CSimPhoneSmartCardApp +// + +CSimPhoneSmartCardApp* CSimPhoneSmartCardApp::NewL(CSimPhone* aPhone) +/** + * Standard two phase constructor. + * @param aPhone The phone object from which the Phone Smart Card applications will open + */ + { + CSimPhoneSmartCardApp* obj=new(ELeave) CSimPhoneSmartCardApp(aPhone); + CleanupStack::PushL(obj); + obj->ConstructL(); + CleanupStack::Pop(); + return obj; + } + +CSimPhoneSmartCardApp::CSimPhoneSmartCardApp(CSimPhone* aPhone) +: iPhone(aPhone), iCurrentSelection(RMobilePhone::EUSimSelectionAutomatic), + iFoundScAppTags(EFalse) +/** + * Trivial first phase constructor. + * @param aPhone The phone object from which this Phone SmartCard App was opened. + */ + {} + +void CSimPhoneSmartCardApp::Init() + {} + +void CSimPhoneSmartCardApp::ConstructL() +/** +* Second phase of the 2-phase constructor. +* Constructs all the member data and retrieves all the data from the config file specific to this class. +* +* @leave Leaves due to not enough memory or if any data member does not construct for any reason. +*/ + { + LOGPHONE1("Starting to parse Phone Smart Card applications additional config parameters..."); + ParseSmartCardApplicationInfoL(); + ParseSmartCardFileInfoL(); + MapUSimAppsL(); + LOGPHONE1("Finished parsing Phone Smart Card applications additional config parameters..."); + } + + +CSimPhoneSmartCardApp::~CSimPhoneSmartCardApp() +/** + * Standard destructor. Any objects created by the ::ConstructL() function + * will be destroyed here. + */ + { + delete iTimer; + if(iSmartCardAppEventList) + { + iSmartCardAppEventList->Delete(0, iSmartCardAppEventList->Count()); + delete iSmartCardAppEventList; + } + if(iSmartCardAppList) + { + iSmartCardAppList->Delete(0, iSmartCardAppList->Count()); + delete iSmartCardAppList; + } + if (iSmartCardFileList) + { + iSmartCardFileList->ResetAndDestroy(); + delete iSmartCardFileList; + } + if(iUSimAppList) + { + iUSimAppList->Close(); + delete iUSimAppList; + } + } + + +TInt CSimPhoneSmartCardApp::ExtFunc(const TTsyReqHandle aTsyReqHandle,const TInt aIpc, const TDataPackage& aPckg) +/** +* ExtFunc is called by the server when it has an "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 +* +* @param aTsyReqHandle The request handle for completing the request +* @param aIpc Ipc representing the request +* @param aPackage any data associated with the request +* @return err KErrNone if request completes ok +*/ + { + + TAny* dataPtr = aPckg.Ptr1(); + TAny* dataPtr2 = aPckg.Ptr2(); + + // The following requests can be completed even if the completion of another request is pending. + switch(aIpc) + { + case EMobilePhoneGetCurrentActiveUSimApplication: + return GetCurrentActiveUSimApplication(aTsyReqHandle, + reinterpret_cast(dataPtr)); + + case EMobilePhoneEnumerateUSimApplications: + return EnumerateUSimApplications(aTsyReqHandle, + reinterpret_cast (dataPtr), + reinterpret_cast (dataPtr2)); + + case EMobilePhoneSetUSimApplicationStatus: + return SetUSimApplicationStatus(aTsyReqHandle, + reinterpret_cast (dataPtr), + reinterpret_cast (dataPtr2)); + + case EMobilePhoneGetUSimApplicationsInfo: + return GetUSimApplicationInfo(aTsyReqHandle, + reinterpret_cast (dataPtr), + aPckg.Des2n()); + + case EMobilePhoneNotifyUSimApplicationsInfoChange: + return NotifyUSimApplicationsInfoChange(aTsyReqHandle, + reinterpret_cast (dataPtr), + reinterpret_cast (dataPtr2)); + + case EMobilePhoneEnumerateSmartCardApplications: + return EnumerateScApplications(aTsyReqHandle, + reinterpret_cast(dataPtr)); + + case EMobilePhoneGetSmartCardApplicationInfo: + return GetScApplicationInfo(aTsyReqHandle, + reinterpret_cast(dataPtr), + aPckg.Des2n()); + + case EMobilePhoneSetSmartCardApplicationStatus: + return SetScApplicationStatus(aTsyReqHandle, + reinterpret_cast(dataPtr), + reinterpret_cast(dataPtr2)); + + case EMobilePhoneNotifySmartCardApplicationInfoChange: + return NotifyScApplicationInfoChange(aTsyReqHandle, + reinterpret_cast(dataPtr), + reinterpret_cast(dataPtr2)); + + case EMobilePhoneGetUSimAppsSelectionMode: + return GetUSimAppsSelectionMode(aTsyReqHandle, + reinterpret_cast(dataPtr)); + + case EMobilePhoneSetUSimAppsSelectionMode: + return SetUSimAppsSelectionMode(aTsyReqHandle, + reinterpret_cast(dataPtr)); + + case EMobilePhoneNotifyUSimAppsSelectionModeChange: + return NotifyUSIMAppsSelectionModeChange(aTsyReqHandle, + reinterpret_cast(dataPtr)); + + case EMobilePhoneGetScFileInfo: + return GetScFileInfo(aTsyReqHandle, + *reinterpret_cast(dataPtr), + aPckg.Des2n()); + + case EMobilePhoneReadScFile: + return ReadScFile(aTsyReqHandle, + *reinterpret_cast(dataPtr), + aPckg.Des2n()); + + case EMobilePhoneUpdateScFile: + return UpdateScFile(aTsyReqHandle, + *reinterpret_cast(dataPtr), + aPckg.Des2n()); + + default: + break; + } + return KErrNotSupported; + } + + +CTelObject::TReqMode CSimPhoneSmartCardApp::ReqModeL(const TInt aIpc) +/** + * This function returns the Request Mode for the request with the passed IPC value. + * The function leaves if the IPC is not found. + * + * @param aIpc The IPC number of the request. + * @return TReqMode The request mode. + */ + { + CTelObject::TReqMode ret=0; + + switch(aIpc) + { + case EMobilePhoneGetCurrentActiveUSimApplication: + case EMobilePhoneEnumerateUSimApplications: + case EMobilePhoneSetUSimApplicationStatus: + case EMobilePhoneGetUSimApplicationsInfo: + case EMobilePhoneEnumerateSmartCardApplications: + case EMobilePhoneSetSmartCardApplicationStatus: + case EMobilePhoneGetSmartCardApplicationInfo: + case EMobilePhoneGetUSimAppsSelectionMode: + case EMobilePhoneSetUSimAppsSelectionMode: + case EMobilePhoneGetScFileInfo: + case EMobilePhoneReadScFile: + case EMobilePhoneUpdateScFile: + break; + + case EMobilePhoneNotifyUSimAppsSelectionModeChange: + case EMobilePhoneNotifyUSimApplicationsInfoChange: + case EMobilePhoneNotifySmartCardApplicationInfoChange: + ret=KReqModeMultipleCompletionEnabled | KReqModeRePostImmediately; + break; + + default: + User::Leave(KErrNotSupported); + break; + } + + return ret; + } + +TInt CSimPhoneSmartCardApp::RegisterNotification(const TInt /*aIpc*/) +/** + * The ETel Server calls this function when the first client makes a notification + * request. If supported by the underlying protocol controlling the + * signalling stack, this can be used to start requesting updates for the relevant + * service. + */ + { + return KErrNone; + } + +TInt CSimPhoneSmartCardApp::DeregisterNotification(const TInt /*aIpc*/) +/** + * The ETel Server calls this function when the last client that had previously + * made a notification request closes its ETel Server handle. If supported by + * the underlying protocol controlling the signalling stack, this can be used + * to stop requesting updates for the relevant service. + */ + { + return KErrNone; + } + +CTelObject* CSimPhoneSmartCardApp::OpenNewObjectByNameL(const TDesC& /*aName*/) +/** + * The API does not support any objects that could be opened from this one. + */ + { + User::Leave(KErrNotSupported); + return NULL; + } + +CTelObject* CSimPhoneSmartCardApp::OpenNewObjectL(TDes&) +/** + * The API does not support any objects that could be opened from this one. + */ + { + User::Leave(KErrNotSupported); + return NULL; + } + + +TInt CSimPhoneSmartCardApp::NumberOfSlotsL(const TInt aIpc) +/** + * Return the number of slots that the ETel Server should allocate for buffering requests + * of the given IPC number. + * + * @param aIpc The IPC number of the request. + */ + { + TInt numberOfSlots = 0; + + switch(aIpc) + { + case EMobilePhoneNotifyUSimAppsSelectionModeChange: + case EMobilePhoneNotifyUSimApplicationsInfoChange: + case EMobilePhoneNotifySmartCardApplicationInfoChange: + numberOfSlots = KDefaultNumberOfSlots; + break; + default: + LOGPHONE1("CSimPhoneSmartCardApp: Number of Slots error, unknown IPC"); + User::Leave(KErrNotSupported); + break; + } + return numberOfSlots; + } + + +TInt CSimPhoneSmartCardApp::CancelService(const TInt aIpc,const TTsyReqHandle aTsyReqHandle) +/** + * Cancel an outstanding request. + * @param aIpc The IPC number of the request that is to be cancelled. + * @param aTsyReqHandle The TSY request handle of the request that is to be cancelled. + * @return Standard return value. + */ + { + + switch(aIpc) + { + case EMobilePhoneEnumerateSmartCardApplications: + return EnumerateScApplicationsCancel(aTsyReqHandle); + + case EMobilePhoneEnumerateUSimApplications: + return EnumerateUSimApplicationsCancel(aTsyReqHandle); + + case EMobilePhoneSetUSimApplicationStatus: + return SetUSimApplicationStatusCancel(aTsyReqHandle); + + case EMobilePhoneGetUSimApplicationsInfo: + return GetUSimApplicationInfoCancel(aTsyReqHandle); + + case EMobilePhoneNotifyUSimApplicationsInfoChange: + return NotifyUSimApplicationsInfoChangeCancel(aTsyReqHandle); + + case EMobilePhoneSetSmartCardApplicationStatus: + return SetScApplicationStatusCancel(aTsyReqHandle); + + case EMobilePhoneGetSmartCardApplicationInfo: + return GetScApplicationInfoCancel(aTsyReqHandle); + + case EMobilePhoneGetCurrentActiveUSimApplication: + return GetCurrentActiveUSimApplicationCancel(aTsyReqHandle); + + case EMobilePhoneNotifySmartCardApplicationInfoChange: + return NotifyScApplicationInfoChangeCancel(aTsyReqHandle); + + case EMobilePhoneSetUSimAppsSelectionMode: + return SetUSimAppsSelectionModeCancel(aTsyReqHandle); + + case EMobilePhoneGetUSimAppsSelectionMode: + return GetUSimAppsSelectionModeCancel(aTsyReqHandle); + + case EMobilePhoneNotifyUSimAppsSelectionModeChange: + return NotifyUSIMAppsSelectionModeChangeCancel(aTsyReqHandle); + + case EMobilePhoneGetScFileInfo: + return GetScFileInfoCancel(aTsyReqHandle); + + case EMobilePhoneReadScFile: + return ReadScFileCancel(aTsyReqHandle); + + case EMobilePhoneUpdateScFile: + return UpdateScFileCancel(aTsyReqHandle); + + default: + break; + } + return KErrNone; + } + + +const CTestConfigSection* CSimPhoneSmartCardApp::CfgFile() +/** +* Returns a pointer to the config file section +* +* @return CTestConfigSection a pointer to the configuration file data section +*/ + { + LOGPHONE1(">>CSimPhoneSmartCardApp::CfgFile"); + return iPhone->CfgFile(); + } + +void CSimPhoneSmartCardApp::TimerCallBack(TInt /*aId*/) +/** +* Timer callback function. When the timer goes off, it will call back into this +* function for further processing. +* +* @param aId an id identifying which timer callback is being called +*/ + { + if(iNotifyScInfo.iNotifyPending || iNotifyUSimInfo.iNotifyPending) + { + TSmartCardAppEvent theEvent=iSmartCardAppEventList->At(iEventPointer); + TInt ret; + RMobilePhone::TSmartCardApplicationEvent occuredEvent; + TBool isUSimAppAffected = EFalse; + + if(theEvent.iAction == RMobilePhone::EScApplicationActivate) + { + ret=ActivateSmartCardApp(theEvent.iAID, isUSimAppAffected); + occuredEvent = RMobilePhone::EScApplicationActivated; + } + else + { + ret=TerminateSmartCardApp(theEvent.iAID, isUSimAppAffected); + occuredEvent = RMobilePhone::EScApplicationTerminated; + } + + if (ret == KErrNone) + { + iEventPointer++; + + //notify any ScApp client if such notify request is pending + if(iNotifyScInfo.iNotifyPending) + { + iNotifyScInfo.iNotifyPending=EFalse; + *(RMobilePhone::TAID*)iNotifyScInfo.iNotifyData1=theEvent.iAID; + *(RMobilePhone::TSmartCardApplicationEvent*)iNotifyScInfo.iNotifyData2=occuredEvent; + iPhone->ReqCompleted(iNotifyScInfo.iNotifyHandle,KErrNone); + } + + //notify any USimApp client if such notify request is pending + if(isUSimAppAffected && iNotifyUSimInfo.iNotifyPending) + { + iNotifyUSimInfo.iNotifyPending=EFalse; + + if(occuredEvent == RMobilePhone::EScApplicationActivated) + { + *(RMobilePhone::TAID*)iNotifyUSimInfo.iNotifyData1=theEvent.iAID; + } + else + { + *(RMobilePhone::TAID*)iNotifyUSimInfo.iNotifyData1=_L8(""); + } + + *(TInt*)iNotifyUSimInfo.iNotifyData2=iUSimAppList->Count(); + iPhone->ReqCompleted(iNotifyUSimInfo.iNotifyHandle,KErrNone); + } + } + }//end if(iNotifyScInfo.iNotifyPending... + } + +TBool CSimPhoneSmartCardApp::FoundScAppTags() +/** +* Returns a value to indicate whether SCApp tags were found in the Config file +* +*/ + { + return iFoundScAppTags; + } + + +void CSimPhoneSmartCardApp::TSmartCardFile::GetFileInfo(RMobilePhone::TScFileInfoV5& aScFileInfo) +/** +* Gets the SmartCard file's File info +* +* @param aScFileInfo The function passes back the file info through this reference +*/ + { + aScFileInfo.iFileID = iFileID; + aScFileInfo.iType = iType; + aScFileInfo.iTotalLength = iTotalLength; + aScFileInfo.iRecordLength = iRecordLength; + aScFileInfo.iNumberRecords = iNumberRecords; + } + +CSimPhoneSmartCardApp::TCyclicSmartCardFile::TCyclicSmartCardFile() + :iOldestRecord(0) + {} + +TInt CSimPhoneSmartCardApp::TCyclicSmartCardFile::ReadFile( + const RMobilePhone::TScFilePathWithAccessOffsets& aFilePathOffsets, TDes8* aReadBuffer) +/** +* Concrete implementation of the ReadFile() method for reading file data from a record based +* cyclic smart card file. Reads precisely one record (iRecordLength bytes). +* +* Note: Records are numbered from 1 to n NOT 0 to n-1 +* +* @param aFilePathOffsets Information about which file to read (path) and where in the file to read data from (offsets) +* @param aReadBuffer The requested data is read into this buffer +*/ + { + //check that the client has provided a buffer of sufficient size + if(aReadBuffer->MaxSize() < iRecordLength) + { + return KErrOverflow; + } + + //check that the client has specified a valid start offset + else if(aFilePathOffsets.iStartOffset < 1 || aFilePathOffsets.iStartOffset > iNumberRecords) + { + LOGPHONE1("ERROR: File start offset information invalid."); + return KErrMMEtelScRecordNotFound; + } + + else + { + //Var filepointer initially holds a pointer to the beginning of the specified record + //The record to read is specified as an offset from the oldest record. I.e. Record 1 is the + //newest record. + TInt filePointer = iOldestRecord + (aFilePathOffsets.iStartOffset * iRecordLength); + if(filePointer >= iTotalLength) + { + filePointer = filePointer - iTotalLength; + } + + aReadBuffer->SetLength(iRecordLength); + aReadBuffer->FillZ(); + + TInt index; + + for(index = 0; index < iRecordLength; index++) + { + (*aReadBuffer)[index] = iFileData[filePointer]; + filePointer++; + } + return KErrNone; + } + } + +TInt CSimPhoneSmartCardApp::TCyclicSmartCardFile::UpdateFile( + const RMobilePhone::TScFilePathWithAccessOffsets& /*aFilePathOffsets*/, TDes8* aWriteBuffer) +/** +* Concrete implementation of the UpdateFile() method for updating file data in a record based +* cyclic smart card file. Updates precisely one record (iRecordLength bytes). The record that is +* updated is the oldest record. +* +* Note: Records are numbered from 1 to n NOT 0 to n-1 +* +* @param aReadBuffer The data with which the file should be updated. +*/ + { + //Check that the client has provided a buffer of sufficient size + if(aWriteBuffer->Size() != iRecordLength) + { + return KErrMMEtelScWrongLength; + } + else + { + TInt filePointer = iOldestRecord ; + + TInt index; + + for(index = 0; index < iRecordLength; index++) + { + iFileData[filePointer] = (*aWriteBuffer)[index]; + filePointer++; + } + UpdateOldestRecordPointer(); + return KErrNone; + } + } + +void CSimPhoneSmartCardApp::TCyclicSmartCardFile::UpdateOldestRecordPointer() + { + //IF the OldestRecord pointer is set to point to the beginning of the buffer + if(iOldestRecord==0) + { + //Set it to point to the beginning of the last record in the buffer + iOldestRecord = iTotalLength - iRecordLength; + } + //ELSE set it to point to the beginning of previous record (the second oldest record) + else + { + iOldestRecord = iOldestRecord - iRecordLength; + } + } + + +TInt CSimPhoneSmartCardApp::TLinearSmartCardFile::ReadFile( + const RMobilePhone::TScFilePathWithAccessOffsets& aFilePathOffsets, TDes8* aReadBuffer) +/** +* Concrete implementation of the ReadFile() method for reading file data from a record based +* linear fixed smart card file. Reads precisely one record (iRecordLength bytes). +* +* Note: Records are numbered from 1 to n NOT 0 to n-1 +* +* @param aFilePathOffsets Information about which file to read (path) and where in the file to read data from (offsets) +* @param aReadBuffer The requested data is read into this buffer +*/ + { + //check that the client has provided a buffer of sufficient size + if(aReadBuffer->MaxSize() < iRecordLength) + { + return KErrOverflow; + } + + //check that the client has specified a valid start offset + else if(aFilePathOffsets.iStartOffset < 1 || aFilePathOffsets.iStartOffset > iNumberRecords) + { + LOGPHONE1("ERROR: File start offset information invalid."); + return KErrMMEtelScRecordNotFound; + } + else + { + TInt filePointer = (aFilePathOffsets.iStartOffset - 1) * iRecordLength; + TInt index; + + aReadBuffer->SetLength(iRecordLength); + aReadBuffer->FillZ(); + + for(index = 0; index < iRecordLength; index++) + { + (*aReadBuffer)[index] = iFileData[filePointer]; + filePointer++; + } + return KErrNone; + } + } + +TInt CSimPhoneSmartCardApp::TLinearSmartCardFile::UpdateFile( + const RMobilePhone::TScFilePathWithAccessOffsets& aFilePathOffsets, TDes8* aWriteBuffer) +/** +* Concrete implementation of the UpdateFile() method for updating data in a record based +* linear fixed smart card file. Updates precisely one record (iRecordLength bytes). +* +* Note: Records are numbered from 1 to n NOT 0 to n-1 +* +* @param aFilePathOffsets Information about which file to update (path) and where in the file to write data to (offsets) +* @param aReadBuffer The data with which the file should be updated. +*/ + { + //check that the client has provided a buffer of sufficient size + if(aWriteBuffer->Size() != iRecordLength) + { + return KErrMMEtelScWrongLength; + } + + //check that the client has specified a valid start offset + else if(aFilePathOffsets.iStartOffset < 1 || aFilePathOffsets.iStartOffset > iNumberRecords) + { + LOGPHONE1("ERROR: File start offset information invalid."); + return KErrMMEtelScRecordNotFound; + } + else + { + TInt filePointer = (aFilePathOffsets.iStartOffset - 1) * iRecordLength; + TInt index; + + for(index = 0; index < iRecordLength; index++) + { + iFileData[filePointer] = (*aWriteBuffer)[index]; + filePointer++; + } + return KErrNone; + } + } + +TInt CSimPhoneSmartCardApp::TTransparentSmartCardFile::ReadFile( + const RMobilePhone::TScFilePathWithAccessOffsets& aFilePathOffsets, TDes8* aReadBuffer) +/** +* Concrete implementation of the ReadFile() method for reading file data from a binary transparent +* smart card file. +* +* @param aFilePathOffsets Information about which file to read (path) and where in the file to read data from (offsets) +* @param aReadBuffer The requested data is read into this buffer +*/ + { + const TInt& bytesToRead = aFilePathOffsets.iCount; + TInt filePointer = aFilePathOffsets.iStartOffset; + + //check that the client has provided a buffer of sufficient size + if(aReadBuffer->MaxSize() < bytesToRead) + { + return KErrOverflow; + } + + //check that the client has specified a valid start offset + else if(aFilePathOffsets.iStartOffset >= (TUint)iTotalLength) + { + LOGPHONE1("ERROR: File start offset information invalid."); + return KErrMMEtelScReferencedDataNotFound; + } + + //check the client is not requesting to read too many bytes, resulting in reading + //off the end of the file + else if((bytesToRead + filePointer) > iTotalLength) + { + LOGPHONE1("ERROR: Path offset information results in reading off the end of the file"); + return KErrMMEtelScEofReached; + } + else + { + aReadBuffer->SetLength(bytesToRead); + aReadBuffer->FillZ(); + + TInt index; + + for(index = 0; index < bytesToRead; index++) + { + (*aReadBuffer)[index] = iFileData[filePointer]; + filePointer++; + } + return KErrNone; + } + } + +TInt CSimPhoneSmartCardApp::TTransparentSmartCardFile::UpdateFile( + const RMobilePhone::TScFilePathWithAccessOffsets& aFilePathOffsets, TDes8* aWriteBuffer) +/** +* Concrete implementation of the UpdateFile() method for updating data in a binary transparent +* smart card file. +* +* @param aFilePathOffsets Information about which file to update (path) and where in the file to write data to (offsets) +* @param aReadBuffer The data with which the file should be updated. +*/ + { + const TInt& bytesToWrite = aFilePathOffsets.iCount; + TInt filePointer = aFilePathOffsets.iStartOffset; + TInt index; + + //check that the client has provided a buffer of sufficient size + if(aWriteBuffer->Size() != bytesToWrite) + { + //The length of the provided buffer does not match the number of bytes that client has requested + //should be updated in the file. + return KErrArgument; + } + + //check that the client has specified a valid start offset + else if(aFilePathOffsets.iStartOffset >= (TUint)iTotalLength) + { + LOGPHONE1("ERROR: File start offset information invalid."); + return KErrMMEtelScReferencedDataNotFound; + } + + //check the client is not requesting to write too many bytes, resulting in writing + //off the end of the file + else if((bytesToWrite + filePointer) > iTotalLength) + { + LOGPHONE1("ERROR: Path offset information results in reading off the end of the file"); + return KErrMMEtelScEofReached; + } + else + { + for(index = 0; index < bytesToWrite; index++) + { + iFileData[filePointer] = (*aWriteBuffer)[index]; + filePointer++; + } + + return KErrNone; + } + } + +RMobilePhone::TAID CSimPhoneSmartCardApp::GetActiveUSim() +/** +* Returns the active aid (internally) +* +*/ + { + return iActiveUSimApp; + } + +TInt CSimPhoneSmartCardApp::GetCurrentActiveUSimApplication(const TTsyReqHandle aTsyReqHandle, RMobilePhone::TAID* aAID) +/** +* Returns the active aid +* +* @param aReqHandle The TSY request handle for this request. +* @param aAID Returns the AID of the Active USim Application +* @return KErrNone +*/ + { + if(iActiveUSimApp.Size() == 0) + { + iPhone->ReqCompleted(aTsyReqHandle, KErrMMEtelScApplicationNotActive); + } + else + { + *aAID=iActiveUSimApp; + iPhone->ReqCompleted(aTsyReqHandle, KErrNone); + } + return KErrNone; + } + +TInt CSimPhoneSmartCardApp::GetCurrentActiveUSimApplicationCancel(const TTsyReqHandle aTsyReqHandle) +/** +* Attempts to cancel a pending GetActiveUSimApplication request (unsuccessfully) +* +*/ + { + iPhone->ReqCompleted(aTsyReqHandle, KErrNone); + return KErrNone; + } + + +TInt CSimPhoneSmartCardApp::EnumerateUSimApplications(TTsyReqHandle aTsyReqHandle, TInt* aCount, RMobilePhone::TAID* aActiveAID) +/** +* Enumerates the number of USim applications in the UICC and returns the +* AID of the active application. +* +* @param aTsyReqHandle A handle belonging to the client that created the +* session with this TSY server. +* @param aCount Returns the number of USim applications. +* @param aActiveAID Returns the AID of the currently active application. +* @return KErrNone. +*/ + { + *aCount=iUSimAppList->Count(); + aActiveAID->Copy(iActiveUSimApp); + iPhone->ReqCompleted(aTsyReqHandle, KErrNone); + return KErrNone; + } + + +TInt CSimPhoneSmartCardApp::EnumerateUSimApplicationsCancel(TTsyReqHandle aTsyReqHandle) +/** +*Attempts to cancel a pending EnumerateUSimApplications request (unsuccesfully). +* +*@param aTsyReqHandle A handle belonging to the client that created the +* session with this TSY server. +*/ + { + iPhone->ReqCompleted(aTsyReqHandle, KErrNone); + return KErrNone; + } + + +TInt CSimPhoneSmartCardApp::GetUSimApplicationInfo(TTsyReqHandle aTsyReqHandle, TInt* aUSimAppIndex, TDes8* aInfo) +/** +* Retrieves information for a specified USim application +* +* @param aTsyReqHandle A handle belonging to the client that created the +* session with this TSY server. +* @param aUSimAppIndex Used to specify the index of the application. +* @param aInfo Returns the information of the specified appplication. +* @return KErrNone. +*/ + { + if(*aUSimAppIndex>=iUSimAppList->Count()) + { + iPhone->ReqCompleted(aTsyReqHandle, KErrNotFound); + return KErrNone; + } + else + { + TPckg* infoPckg = + (TPckg*)aInfo; + + RMobilePhone::TUSimApplicationInfoV2& info = (*infoPckg)(); + + // Check that the data structure is supported by the simulated TSY version + TInt err = iPhone->CheckSimTsyVersion(info); + if(err != KErrNone) + { + iPhone->ReqCompleted(aTsyReqHandle, err); + return KErrNone; + } + + info.iAID = (*iUSimAppList)[*aUSimAppIndex]->iAID; + info.iLabel = (*iUSimAppList)[*aUSimAppIndex]->iLabel; + iPhone->ReqCompleted(aTsyReqHandle, KErrNone); + } + + return KErrNone; + } + +/** +Attempts to cancel a pending GetUSimApplicationInfo request +(unsuccesfully). + +@param aTsyReqHandle A handle belonging to the client that created the + session with this TSY server. +*/ +TInt CSimPhoneSmartCardApp::GetUSimApplicationInfoCancel(TTsyReqHandle aTsyReqHandle) + { + iPhone->ReqCompleted(aTsyReqHandle, KErrNone); + return KErrNone; + } + + +TInt CSimPhoneSmartCardApp::SetUSimApplicationStatus(TTsyReqHandle aTsyReqHandle, RMobilePhone::TAID* aAID, RMobilePhone::TUSimAppAction* aUsimAppAction) +/** +* Attempts to set the status of a specific USim application. +* +* @param aTsyReqHandle A handle belonging to the client that created the +* session with this TSY server. +* @param aAID The specific application's ID whose status is to be set. +* @param aUsimAppAction The status to apply to the application identified +* by aAID. +* @return KErrNone on completion of request, unless the aAID given is not +* identifiable, in which case KErrArgument is returned. +*/ + { + TInt ret; + RMobilePhone::TAID aAidToAction; + RMobilePhone::TSmartCardApplicationEvent aScEvent; + TBool isUSimAppAffected = EFalse; + + //if the request is to activate a USimApp + if(*aUsimAppAction == RMobilePhone::EUSimActivate) + { + //if another USimApp is active. + if(iActiveUSimApp.Size() != 0) + { + //terminate active USimApp + aAidToAction = iActiveUSimApp; + aScEvent = RMobilePhone::EScApplicationTerminated; + isUSimAppAffected = EFalse; + ret = TerminateSmartCardApp(aAidToAction, isUSimAppAffected); + + //if No error terminating + if (ret == KErrNone) + { + //notify ScApp client if notify request is pending + if(iNotifyScInfo.iNotifyPending) + { + *(RMobilePhone::TAID*)iNotifyScInfo.iNotifyData1=aAidToAction; + *(RMobilePhone::TSmartCardApplicationEvent*)iNotifyScInfo.iNotifyData2=aScEvent; + iNotifyScInfo.iNotifyPending=EFalse; + iPhone->ReqCompleted(iNotifyScInfo.iNotifyHandle,KErrNone); + } + } + }//end if(iActiveUSimApp.Size() != 0) + + //activate the requested application + aAidToAction = *aAID; + aScEvent = RMobilePhone::EScApplicationActivated; + isUSimAppAffected = EFalse; + ret=ActivateSmartCardApp(*aAID, isUSimAppAffected); + + //if no error activating + if (ret == KErrNone) + { + //notify any ScApp client if such notify request is pending + if(iNotifyScInfo.iNotifyPending) + { + iNotifyScInfo.iNotifyPending=EFalse; + *(RMobilePhone::TAID*)iNotifyScInfo.iNotifyData1=aAidToAction; + *(RMobilePhone::TSmartCardApplicationEvent*)iNotifyScInfo.iNotifyData2=aScEvent; + iPhone->ReqCompleted(iNotifyScInfo.iNotifyHandle,KErrNone); + } + //notify any USimApp client if such notify request is pending + if(iNotifyUSimInfo.iNotifyPending) + { + iNotifyUSimInfo.iNotifyPending=EFalse; + *(RMobilePhone::TAID*)iNotifyUSimInfo.iNotifyData1=aAidToAction; + *(TInt*)iNotifyUSimInfo.iNotifyData2=iUSimAppList->Count(); + iPhone->ReqCompleted(iNotifyUSimInfo.iNotifyHandle,KErrNone); + } + } + + //complete requests and return + iPhone->ReqCompleted(aTsyReqHandle,ret); + return KErrNone; + + } + + else + { + //the request is to terminate a USimApp + aAidToAction = *aAID; + aScEvent = RMobilePhone::EScApplicationTerminated; + + //terminate active USimApp + isUSimAppAffected = EFalse; + ret = TerminateSmartCardApp(aAidToAction, isUSimAppAffected); + + //if No error terminating + if (ret == KErrNone) + { + //notify ScApp client if such notify request is pending + if(iNotifyScInfo.iNotifyPending) + { + *(RMobilePhone::TAID*)iNotifyScInfo.iNotifyData1=aAidToAction; + *(RMobilePhone::TSmartCardApplicationEvent*)iNotifyScInfo.iNotifyData2=aScEvent; + iNotifyScInfo.iNotifyPending=EFalse; + iPhone->ReqCompleted(iNotifyScInfo.iNotifyHandle,KErrNone); + } + //notify any USimApp client if such notify request is pending + if(iNotifyUSimInfo.iNotifyPending) + { + *(RMobilePhone::TAID*)iNotifyUSimInfo.iNotifyData1=_L8(""); + *(TInt*)iNotifyUSimInfo.iNotifyData2=iUSimAppList->Count(); + iNotifyUSimInfo.iNotifyPending=EFalse; + iPhone->ReqCompleted(iNotifyUSimInfo.iNotifyHandle,KErrNone); + } + } + //complete requests and return + iPhone->ReqCompleted(aTsyReqHandle,ret); + return KErrNone; + } + } + + +TInt CSimPhoneSmartCardApp::SetUSimApplicationStatusCancel(TTsyReqHandle aTsyReqHandle) +/** +* Attempts to cancel a pending SetUSimApplicationStatus request (unsuccesfully). +* +* @param aTsyReqHandle A handle belonging to the client that created the +* session with this TSY server. +* @return KErrNone. +*/ + { + iPhone->ReqCompleted(aTsyReqHandle, KErrNone); + return KErrNone; + } + + +TInt CSimPhoneSmartCardApp::NotifyUSimApplicationsInfoChange(const TTsyReqHandle aTsyReqHandle, TInt* aCount, RMobilePhone::TAID* aActiveAID) +/** +* Notifies the client when the specified USim application's information +* changes. +* +* @param aTsyReqHandle A handle belonging to the client that created the +* session with this TSY server. +* @param aCount Returns the total number of USim applications when the +* request completes. +* @param aActiveAID The application's AID whose infromation change will +* be notified to the client. +* @return KErrNone. +*/ + { + __ASSERT_ALWAYS(!iNotifyUSimInfo.iNotifyPending,SimPanic(ENotificationReqAlreadyOutstanding)); + + TInt count=iSmartCardAppEventList->Count(); + + if(iEventPointerAt(iEventPointer); + + if (iTimer != NULL) + { + iTimer->Start(event.iDuration,this); + iTimerStarted = ETrue; + } + } + + iNotifyUSimInfo.iNotifyPending=ETrue; + iNotifyUSimInfo.iNotifyHandle=aTsyReqHandle; + iNotifyUSimInfo.iNotifyData1=aActiveAID; + iNotifyUSimInfo.iNotifyData2=aCount; + return KErrNone; + } + + +/** +*Attempts to cancel a pending NotifyUSimApplicationsInfoChange request. +* +*@param aTsyReqHandle A handle belonging to the client that created the +* session with this TSY server. +*@param KErrNone +*/ +TInt CSimPhoneSmartCardApp::NotifyUSimApplicationsInfoChangeCancel(TTsyReqHandle aTsyReqHandle) + { + if(iNotifyUSimInfo.iNotifyPending) + { + iNotifyUSimInfo.iNotifyPending=EFalse; + iPhone->ReqCompleted(aTsyReqHandle,KErrCancel); + } + return KErrNone; + } + + +TInt CSimPhoneSmartCardApp::EnumerateScApplications(const TTsyReqHandle aTsyReqHandle, TUint* aCount) +/** +* Enumerates the number of Smart Card applications on the UICC +* +* @param aReqHandle The TSY request handle for this request +* @param aCount Returns the number of Smart Card applications +* @return KErrNone +*/ + + { + *aCount=iSmartCardAppList->Count(); + iPhone->ReqCompleted(aTsyReqHandle, KErrNone); + return KErrNone; + } + +TInt CSimPhoneSmartCardApp::EnumerateScApplicationsCancel(const TTsyReqHandle aTsyReqHandle) +/** +* Attempts to cancel a pending EnumerateUSimApplications request (unsuccessfully) +* +* @param aReqHandle The TSY request handle for this request +*/ + { + iPhone->ReqCompleted(aTsyReqHandle, KErrNone); + return KErrNone; + } + +TInt CSimPhoneSmartCardApp::GetScApplicationInfo(const TTsyReqHandle aTsyReqHandle, TInt* aAppIndex, TDes8* aInfo) +/** +* Retrieves information for a specified Smart Card application +* +* @param aReqHandle The TSY request handle for this request +* @param aAppIndex is used to specify the index of the application +* @param aInfo Returns the information of the specified appplication +* @return KErrNone +*/ + { + if(*aAppIndex>=iSmartCardAppList->Count()) + { + iPhone->ReqCompleted(aTsyReqHandle, KErrNotFound); + } + else + { + TPckg* infoPckg = + (TPckg*)aInfo; + + RMobilePhone::TSmartCardApplicationInfoV5& info = (*infoPckg)(); + + // Check that the data structure is supported by the simulated TSY version + TInt err = iPhone->CheckSimTsyVersion(info); + if(err != KErrNone) + { + iPhone->ReqCompleted(aTsyReqHandle, err); + return KErrNone; + } + + info.iAID=iSmartCardAppList->At(*aAppIndex).iAID; + info.iLabel=iSmartCardAppList->At(*aAppIndex).iLabel; + if (info.ExtensionId() == KEtelExtMultimodeV6) + { + RMobilePhone::TUiccApplicationEapInfoV6& withEapInfo = static_cast(info); + withEapInfo.iEapTypeList = iSmartCardAppList->At(*aAppIndex).iEapList; + } + iPhone->ReqCompleted(aTsyReqHandle, KErrNone); + } + + return KErrNone; + } + +TInt CSimPhoneSmartCardApp::GetScApplicationInfoCancel(const TTsyReqHandle aTsyReqHandle) +/** +* Attempts to cancel a pending GetScApplicationInfo request (unsuccessfully) +* +*/ + { + iPhone->ReqCompleted(aTsyReqHandle, KErrNone); + return KErrNone; + } + +TInt CSimPhoneSmartCardApp::NotifyScApplicationInfoChange(const TTsyReqHandle aTsyReqHandle, + RMobilePhone::TAID* aAID, RMobilePhone::TSmartCardApplicationEvent* aEvent) +/** +* Notifies of any Smart Card application information changes +* +* @param aReqHandle The TSY request handle for this request +* @param aAID Return the AID of the application whose status has changed +* @param aEvent Return the event that took place on application aAID +* @return KErrNone +*/ + + { + __ASSERT_ALWAYS(!iNotifyScInfo.iNotifyPending,SimPanic(ENotificationReqAlreadyOutstanding)); + + TInt count=iSmartCardAppEventList->Count(); + + if(iEventPointerAt(iEventPointer); + + if (iTimer != NULL) + { + iTimer->Start(event.iDuration,this); + iTimerStarted = ETrue; + } + } + iNotifyScInfo.iNotifyPending=ETrue; + iNotifyScInfo.iNotifyHandle=aTsyReqHandle; + iNotifyScInfo.iNotifyData1=aAID; + iNotifyScInfo.iNotifyData2=aEvent; + return KErrNone; + } + +TInt CSimPhoneSmartCardApp::NotifyScApplicationInfoChangeCancel(const TTsyReqHandle aTsyReqHandle) +/** +* Attempts to cancel a pending NotifyUSimApplicationsInfoChange request +* +*/ + { + if(iNotifyScInfo.iNotifyPending) + { + iNotifyScInfo.iNotifyPending=EFalse; + iPhone->ReqCompleted(aTsyReqHandle,KErrCancel); + } + return KErrNone; + } + + +TInt CSimPhoneSmartCardApp::SetScApplicationStatus(const TTsyReqHandle aTsyReqHandle, RMobilePhone::TAID* aAID, RMobilePhone::TSmartCardApplicationAction* aAction) +/** +* Sets the Application Status for specified smart card application +* +* @param aReqHandle The TSY request handle for this request +* @param aAID The AID of the application whose status should be changed +* @param aAction The action that should take place on the specified application +* @return KErrNone +*/ + { + TInt ret; + RMobilePhone::TSmartCardApplicationEvent event; + TBool isUSimAppAffected = EFalse; + + if(*aAction==RMobilePhone::EScApplicationActivate) + { + event=RMobilePhone::EScApplicationActivated; + ret=ActivateSmartCardApp(*aAID, isUSimAppAffected); + } + else + { + event=RMobilePhone::EScApplicationTerminated; + ret=TerminateSmartCardApp(*aAID, isUSimAppAffected); + } + + if(ret==KErrNone) + { + if(iNotifyScInfo.iNotifyPending) + { + iNotifyScInfo.iNotifyPending=EFalse; + *(RMobilePhone::TAID*)iNotifyScInfo.iNotifyData1=*aAID; + *(RMobilePhone::TSmartCardApplicationEvent*)iNotifyScInfo.iNotifyData2=event; + iPhone->ReqCompleted(iNotifyScInfo.iNotifyHandle,KErrNone); + } + + //If the affected ScApp is a USimApp... + //notify any USimApp client if such notify request is pending + if(isUSimAppAffected && iNotifyUSimInfo.iNotifyPending) + { + iNotifyUSimInfo.iNotifyPending=EFalse; + + if(event == RMobilePhone::EScApplicationActivated) + { + *(RMobilePhone::TAID*)iNotifyUSimInfo.iNotifyData1=*aAID; + } + else + { + *(RMobilePhone::TAID*)iNotifyUSimInfo.iNotifyData1=_L8(""); + } + + *(TInt*)iNotifyUSimInfo.iNotifyData2=iUSimAppList->Count(); + iPhone->ReqCompleted(iNotifyUSimInfo.iNotifyHandle,KErrNone); + } + } + + iPhone->ReqCompleted(aTsyReqHandle,ret); + return KErrNone; + } + +TInt CSimPhoneSmartCardApp::SetScApplicationStatusCancel(const TTsyReqHandle aTsyReqHandle) +/** +* Attempts to cancel a pending SetScApplicationStatus request (unsuccessfully) +* +*/ + { + iPhone->ReqCompleted(aTsyReqHandle, KErrNone); + return KErrNone; + } + +TInt CSimPhoneSmartCardApp::SetUSimAppsSelectionMode(TTsyReqHandle aTsyReqHandle, RMobilePhone::TUSimSelectionMode* aUSimSelectionMode) +/** +* Sets the Selection mode for USim applications +* +* @param aReqHandle The TSY request handle for this request +* @param aUSimSelectionMode is used to specify the new selection mode for applications +* @return KErrNone +*/ + { + iCurrentSelection=*aUSimSelectionMode; + if(iNotifyMode.iNotifyPending) + { + iNotifyMode.iNotifyPending=EFalse; + *(RMobilePhone::TUSimSelectionMode*)iNotifyMode.iNotifyData=iCurrentSelection; + iPhone->ReqCompleted(iNotifyMode.iNotifyHandle,KErrNone); + } + iPhone->ReqCompleted(aTsyReqHandle, KErrNone); + return KErrNone; + } + +TInt CSimPhoneSmartCardApp::SetUSimAppsSelectionModeCancel(const TTsyReqHandle aTsyReqHandle) +/** +* Attempts to cancel a pending SetUSimAppsSelectionMode request (unsuccessfully) +* +*/ + { + iPhone->ReqCompleted(aTsyReqHandle, KErrNone); + return KErrNone; + } + +TInt CSimPhoneSmartCardApp::GetUSimAppsSelectionMode(TTsyReqHandle aTsyReqHandle, RMobilePhone::TUSimSelectionMode* aUSimSelectionMode) +/** +* Gets the Selection mode for USim applications +* +* @param aReqHandle The TSY request handle for this request +* @param aUSimSelectionMode Returns the selection mode for applications +* @return KErrNone +*/ + { + *aUSimSelectionMode=iCurrentSelection; + iPhone->ReqCompleted(aTsyReqHandle, KErrNone); + return KErrNone; + } + +TInt CSimPhoneSmartCardApp::GetUSimAppsSelectionModeCancel(const TTsyReqHandle aTsyReqHandle) +/** +* Attempts to cancel a pending GetUSimAppsSelectionMode request (unsuccessfully) +* +*/ + { + iPhone->ReqCompleted(aTsyReqHandle, KErrNone); + return KErrNone; + } + +TInt CSimPhoneSmartCardApp::NotifyUSIMAppsSelectionModeChange(TTsyReqHandle aTsyReqHandle, RMobilePhone::TUSimSelectionMode* aUSimSelectionMode) +/** +* Notifies for any Selection mode changes for USim applications +* +* @param aReqHandle The TSY request handle for this request +* @param aUSimSelectionMode Returns the new selection mode for applications +* @return KErrNone +*/ + { + __ASSERT_ALWAYS(!iNotifyMode.iNotifyPending,SimPanic(ENotificationReqAlreadyOutstanding)); + iNotifyMode.iNotifyPending=ETrue; + iNotifyMode.iNotifyHandle=aTsyReqHandle; + iNotifyMode.iNotifyData=aUSimSelectionMode; + return KErrNone; + } + +TInt CSimPhoneSmartCardApp::NotifyUSIMAppsSelectionModeChangeCancel(TTsyReqHandle aTsyReqHandle) +/** +* Attempts to cancel a pending NotifyUSIMAppsSelectionModeChange request +* +*/ + { + if(iNotifyMode.iNotifyPending) + { + iNotifyMode.iNotifyPending=EFalse; + iPhone->ReqCompleted(aTsyReqHandle,KErrCancel); + } + return KErrNone; + } + + +TInt CSimPhoneSmartCardApp::GetScFileInfo(const TTsyReqHandle aTsyReqHandle, + const RMobilePhone::TScFilePath& aFilePathId, TDes8* aInfo) +/** +* Gets information about the specified smart card file +* +* @param aReqHandle The TSY request handle for this request +* @param aFilePathId Used to specify path of the file for which information should be retrieved +* @param aInfo Used to return the retrieved file information +*/ + { + + LOGPHONE1("CSimPhoneSmartCardApp::GetScFileInfo called"); + + RMobilePhone::TScFileInfoV5Pckg *scFileInfoPckg = reinterpret_cast(aInfo); + RMobilePhone::TScFileInfoV5 &scFileInfo = (*scFileInfoPckg)(); + + // Check that the data structure is supported by the simulated TSY version + TInt err = iPhone->CheckSimTsyVersion(scFileInfo); + if(err != KErrNone) + { + iPhone->ReqCompleted(aTsyReqHandle, err); + return KErrNone; + } + + if(scFileInfo.ExtensionId() == KEtelExtMultimodeV5) + { + TSmartCardFile* scFile = NULL; + TInt ret = FindScFile(aFilePathId, scFile); + if(ret==KErrNone) + { + scFile->GetFileInfo(scFileInfo); + iPhone->ReqCompleted(aTsyReqHandle,KErrNone); + } + else + { + iPhone->ReqCompleted(aTsyReqHandle,ret); + } + } + + else + { + iPhone->ReqCompleted(aTsyReqHandle,KErrCorrupt); + } + + return KErrNone; + } + + +TInt CSimPhoneSmartCardApp::GetScFileInfoCancel(const TTsyReqHandle aTsyReqHandle) +/** +* Attempts to cancel a pending GetScFileInfo request (unsuccessfully) +* +*/ + { + LOGPHONE1("CSimPhoneSmartCardApp::GetScFileInfoCancel called"); + + iPhone->ReqCompleted(aTsyReqHandle, KErrNone); + return KErrNone; + } + + +TInt CSimPhoneSmartCardApp::ReadScFile(const TTsyReqHandle aTsyReqHandle, + const RMobilePhone::TScFilePathWithAccessOffsets& aFilePathOffsets, TDes8* aReadBuffer) +/** +* Reads a specified amount of data from a specified smart card file +* +* @param aReqHandle The TSY request handle for this request +* @param aFilePathOffsets Used to specify which file to read (path) and where in the file to read data from (offsets) +* @param aReadBuffer Used to return the read file data +*/ + { + TSmartCardFile* scFile = NULL; + TInt ret = FindScFile((RMobilePhone::TScFilePath)aFilePathOffsets, scFile); + if(ret==KErrNone) + { + ret = scFile->ReadFile(aFilePathOffsets, aReadBuffer); + } + + iPhone->ReqCompleted(aTsyReqHandle,ret); + return KErrNone; + } + + +TInt CSimPhoneSmartCardApp::ReadScFileCancel(const TTsyReqHandle aTsyReqHandle) +/** +* Attempts to cancel a pending ReadScFileInfo request (unsuccessfully) +* +*/ + { + LOGPHONE1("CSimPhoneSmartCardApp::ReadScFileInfoCancel called"); + + iPhone->ReqCompleted(aTsyReqHandle, KErrNone); + return KErrNone; + } + + +TInt CSimPhoneSmartCardApp::UpdateScFile(const TTsyReqHandle aTsyReqHandle, + const RMobilePhone::TScFilePathWithAccessOffsets& aFilePathOffsets, TDes8* aWriteBuffer) +/** +* Writes a specified amount of data to a specified smart card file +* +* @param aReqHandle The TSY request handle for this request +* @param aFilePathOffsets Used to specify which file to update (path) and where in the file to write data to (offsets) +* @param aReadBuffer Used to return the read file data +*/ + { + TSmartCardFile* scFile = NULL; + TInt ret = FindScFile((RMobilePhone::TScFilePath)aFilePathOffsets, scFile); + if(ret==KErrNone) + { + ret = scFile->UpdateFile(aFilePathOffsets, aWriteBuffer); + } + + iPhone->ReqCompleted(aTsyReqHandle,ret); + return KErrNone; + } + + +TInt CSimPhoneSmartCardApp::UpdateScFileCancel(const TTsyReqHandle aTsyReqHandle) +/** +* Attempts to cancel a pending UpdateScFileInfo request (unsuccessfully) +* +*/ + { + LOGPHONE1("CSimPhoneSmartCardApp::UpdateScFileInfoCancel called"); + + iPhone->ReqCompleted(aTsyReqHandle, KErrNone); + return KErrNone; + } + + +void CSimPhoneSmartCardApp::ParseSmartCardApplicationInfoL() +/** +* Parses all Smart Card Application related tags from the config file +* +*/ + { + const CTestConfigItem* item=NULL; + TInt ret=KErrNone; + TInt index; + TPtrC8 activeUSimApp, aid, label, eap; + TInt type; + + TSmartCardApplication appInfo; + + TRAP_IGNORE(iTimer=CSimTimer::NewL(iPhone)); + + + LOGPHONE1("Starting to Parse MaxActiveSmartCardApp Info"); + iMaxActiveSmartCardApps = CfgFile()->ItemValue(KMaxActiveSmartCardApps ,KDefaultMaxActiveSmartCardApps); + + + LOGPHONE1("Starting to Parse ActiveUSIMApp Info"); + activeUSimApp.Set(CfgFile()->ItemValue(KActiveUSIMApp, KEmptyString)); + if(activeUSimApp.Length() == 0) + { + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: ACTIVE USIM APP NOT SPECIFIED!"); + } + + + TInt count = CfgFile()->ItemCount(KSmartCardAppInfo); + iSmartCardAppList=new(ELeave) CArrayFixFlat(count+1); + + LOGPHONE1("Starting to Load and Parse Smart Card Application Info"); + for(index=0;indexItem(KSmartCardAppInfo,index); + if(!item) + { + break; + } + + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,aid); + if(ret!=KErrNone) + { + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD APP INFO TAG"); + continue; + } + else + { + appInfo.iAID.Copy(aid); + } + + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,label); + if(ret!=KErrNone) + { + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD APP INFO TAG"); + continue; + } + else + { + appInfo.iLabel.Copy(label); + } + + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,type); + if(ret!=KErrNone) + { + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD APP INFO TAG"); + continue; + } + else + { + appInfo.iAppType = (TSmartCardAppType)type; + } + + if((appInfo.iAppType == EUSimApp) && (appInfo.iAID == activeUSimApp)) + { + //Make this the active USim App + iActiveUSimApp = appInfo.iAID; + appInfo.iAppStatus = EActive; + iNumActiveSmartCardApps++; + } + else + { + appInfo.iAppStatus = EInactive; + } + + ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 3, eap); + if (ret != KErrNone) + { + LOGPHONE2("CONFIGURATION FILE PARSING: BAD OR NO (OPTIONAL) EAP LIST @ SMARTCARD APP INFO TAG [%d]", index); + _LIT8(emptyEapList, ""); + eap.Set(emptyEapList); + } + // Append empty string if no info is given + appInfo.iEapList.Copy(eap); + + iSmartCardAppList->AppendL(appInfo); + iFoundScAppTags = ETrue; + }//end of FOR loop + + if(iActiveUSimApp.Length() == 0) + { + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: AID FOR ACTIVE USIM APP NOT FOUND!"); + } + + + count=CfgFile()->ItemCount(KSmartCardAppEvent); + iSmartCardAppEventList=new(ELeave) CArrayFixFlat(count+1); + TSmartCardAppEvent appEvent; + TInt duration, action; + + LOGPHONE1("Starting to Load and Parse Smart Card Application Event Info"); + + for(index=0;indexItem(KSmartCardAppEvent,index); + if(!item) + { + break; + } + + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0, duration); + if(ret!=KErrNone) + { + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMART CARD APP EVENT TAG"); + continue; + } + else + { + appEvent.iDuration=duration; + } + + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1, aid); + if(ret!=KErrNone) + { + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING; BAD SMART CARD APP EVENT TAG"); + continue; + } + else + { + appEvent.iAID.Copy(aid); + } + + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2, action); + if(ret!=KErrNone) + { + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING; BAD SMART CARD APP EVENT TAG"); + continue; + } + else + { + appEvent.iAction = (RMobilePhone::TSmartCardApplicationAction)action; + } + + iSmartCardAppEventList->AppendL(appEvent); + }//end FOR loop + } + + +void CSimPhoneSmartCardApp::ParseSmartCardFileInfoL() +/** +* Parses all Smart Card File related tags from the config file +* +*/ + { + const CTestConfigItem* item=NULL; + TInt ret=KErrNone; + TPtrC8 fileId, filePath, fileData; + TInt aidIndex, fileType, fileLength, recordLength, numRecords, index; + TSmartCardFile* file = NULL; + + LOGPHONE1("Starting to Parse Smart Card File Info"); + TInt count = CfgFile()->ItemCount(KSmartCardFile); + iSmartCardFileList = new(ELeave) CArrayPtrFlat(count+1); + + for(index=0;indexItem(KSmartCardFile,index); + if(!item) + { + break; + } + + //Get the file's type information + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,fileType); + if(ret!=KErrNone) + { + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD FILE TAG"); + continue; + } + else + { + switch ((RMobilePhone::TScFileType)fileType) + { + case RMobilePhone::ELinearFixed: + file = new(ELeave) TLinearSmartCardFile; + break; + case RMobilePhone::ECyclic: + file = new(ELeave) TCyclicSmartCardFile; + break; + case RMobilePhone::ETransparent: + file = new(ELeave) TTransparentSmartCardFile; + break; + default: + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING:"); + LOGPHONE1("ENCOUNTERED UNKNOWN SMART CARD FILE TYPE."); + continue; + } + file->iType = (RMobilePhone::TScFileType)fileType; + } + + //Get the FID of the file + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,fileId); + if(ret!=KErrNone) + { + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD FILE TAG"); + delete file; + continue; + } + //check that the FID is precisely 4 bytes long + else if(fileId.Length() != KMaxHexFIDLen) + { + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD FILE FID"); + delete file; + continue; + } + else + { + TBuf8 fileIdBuffer; + TextToBin(fileId, fileIdBuffer); + file->iFileID = (RMobilePhone::TScFileID)((fileIdBuffer[0] <<8) + (fileIdBuffer[1])); + } + + //Get the Index of the AID of the application the file belongs to + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,aidIndex); + if(ret!=KErrNone) + { + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD FILE TAG"); + delete file; + continue; + } + else + { + file->iAIDIndex = aidIndex; + } + + //Get the file's path information + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,filePath); + if(ret!=KErrNone) + { + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD FILE TAG"); + delete file; + continue; + } + else + { + file->iPath = filePath; + } + + //Get the information about the total length of the file + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,4,fileLength); + if(ret!=KErrNone) + { + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD FILE TAG"); + delete file; + continue; + } + else + { + file->iTotalLength = fileLength; + } + + //Get information about the length of each record in the file + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,5,recordLength); + if(ret!=KErrNone) + { + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD FILE TAG"); + delete file; + continue; + } + else + { + file->iRecordLength = recordLength; + } + + //Get information about the number of records in the file + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,6,numRecords); + if(ret!=KErrNone) + { + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD FILE TAG"); + delete file; + continue; + } + else + { + file->iNumberRecords = numRecords; + } + + //If the file is Cyclic or Linear record based file... + //Check that record Length * number of records = Total length of file + if((fileType != RMobilePhone::ETransparent) && ((recordLength*numRecords) != fileLength)) + { + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING:..."); + LOGPHONE1("...Record Length * Number of Records != File Length"); + delete file; + continue; + } + + //Get file data + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,7,fileData); + if(ret!=KErrNone) + { + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD FILE TAG"); + delete file; + continue; + } + else if((fileData.Length() % 2 ) != 0) + { + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD FILE DATA"); + continue; + } + else + { + TBuf8 fileDataBuffer; + TextToBin(fileData, fileDataBuffer); + if(fileDataBuffer.Length() != fileLength) + { + LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING:INCONSISTANT DATA FILE LENGTH"); + delete file; + continue; + } + file->iFileData = fileDataBuffer; + } + + iSmartCardFileList->AppendL(file); + }//end FOR Loop + } + +void CSimPhoneSmartCardApp::MapUSimAppsL() + { + iUSimAppList=new(ELeave) RPointerArray(iSmartCardAppList->Count() + 1); + TInt index; + TSmartCardApplication* SmartCardApp = NULL; + + //iterate through the list of smart card applications + for(index=0; index < iSmartCardAppList->Count(); index++) + { + SmartCardApp = &(iSmartCardAppList->At(index)); + + //if the smart card application is a USim App + if(SmartCardApp->iAppType == EUSimApp) + { + //add a pointer to it in the list of USim Apps + iUSimAppList->AppendL(SmartCardApp); + } + }//end FOR loop + + } + + +TInt CSimPhoneSmartCardApp::FindScFile(const RMobilePhone::TScFilePath& aFilePathInfo, TSmartCardFile*& aSmartCardFile) +/** + * Helper function + * + * Searches through the SimTSYs internal list of Smart Card files and returns a pointer + * to the requested file. If the file is under an application a check is done to ensure + * the application is active. + * + * @param aFilePathInfo Some information about the file that the client is looking for + * @param aSmartCardFile A pointer to the Smart Card File the client was looking for + */ + { + TInt index; + TInt aidIndex = KNoAID; + + //If the user has specified a file that is under an application + if(aFilePathInfo.iAID.Size() != 0) + { + //search the list of Smart Card Applications and get an index for the specifed AID + for(index=0; index < iSmartCardAppList->Count(); index++) + { + if(iSmartCardAppList->At(index).iAID == aFilePathInfo.iAID) + { + aidIndex = index; + break; + } + } + + //if the AID is not found + if(aidIndex == KNoAID) + { + return KErrNotFound; + } + else + { + //return an error if the specified application is inactive + if(iSmartCardAppList->At(aidIndex).iAppStatus == EInactive) + { + return KErrMMEtelScApplicationNotActive; + } + } + }//end if(aFilePathInfo.iAID.Size() != 0) + + //Find the specified file + TSmartCardFile* scFile=NULL; + + for(index = 0; index < iSmartCardFileList->Count(); index++) + { + scFile = iSmartCardFileList->At(index); + if((scFile->iAIDIndex == aidIndex) && (scFile->iPath == aFilePathInfo.iPath)) + { + aSmartCardFile = scFile; + return KErrNone; + } + } + + return KErrMMEtelScFileNotFound; + } + + +TInt CSimPhoneSmartCardApp::ActivateSmartCardApp(const RMobilePhone::TAID aAID, TBool& aActivatedUSimApp) +/** +* Performs the logic for Activating a Smart Card application +* +* @param aAID The AID of the application that should be activated +*/ + { + TInt index; + TSmartCardApplication* smartCardApp = NULL; + + for(index=0; index < iSmartCardAppList->Count(); index++) + { + smartCardApp = &(iSmartCardAppList->At(index)); + if(smartCardApp->iAID == aAID) + { + //Check that 1)iMaxActiveSmartCardApps will not be exceeded by activating + //a new smart card application; 2)The application is not already active + if((iNumActiveSmartCardAppsiAppStatus != CSimPhoneSmartCardApp::EActive)) + { + //if we are activating a USIM and another USIM app is already active, + //fail with KErrAlreadyExists + if((smartCardApp->iAppType == CSimPhoneSmartCardApp::EUSimApp) && + (iActiveUSimApp.Length() != 0)) + { + return KErrAlreadyExists; + } + else + { + smartCardApp->iAppStatus = CSimPhoneSmartCardApp::EActive; + iNumActiveSmartCardApps++; + + if(smartCardApp->iAppType == CSimPhoneSmartCardApp::EUSimApp) + { + iActiveUSimApp = smartCardApp->iAID; + aActivatedUSimApp = ETrue; + } + + return KErrNone; + } + } + + else + { + if(smartCardApp->iAppStatus == CSimPhoneSmartCardApp::EActive) + { + LOGPHONE1("REACTIVATING AN ALREADY ACTIVE APPLICATION"); + return KErrNone; + } + else + { + //iMaxActiveSmartCardApps will be exceeded + LOGPHONE1("WARNING: CANNOT PROCESS ACTIVATING APPLICATION"); + return KErrMMEtelScMaxApplicationsActive; + } + } + + } + }//end for loop + + LOGPHONE1("WARNING: AID NOT FOUND. CANNOT PROCESS EVENT"); + return KErrNotFound; + } + + +TInt CSimPhoneSmartCardApp::TerminateSmartCardApp(const RMobilePhone::TAID aAID, TBool& aTerminatedUSimApp) +/** +* Performs the logic for terminating a Smart Card application +* +* @param aAID The AID of the application that should be terminated +*/ + { + TInt index; + TSmartCardApplication* smartCardApp = NULL; + for(index=0; index < iSmartCardAppList->Count(); index++) + { + smartCardApp = &(iSmartCardAppList->At(index)); + if(smartCardApp->iAID == aAID) + { + if(smartCardApp->iAppStatus == CSimPhoneSmartCardApp::EActive) + { + smartCardApp->iAppStatus = CSimPhoneSmartCardApp::EInactive; + iNumActiveSmartCardApps--; + + if(smartCardApp->iAppType == CSimPhoneSmartCardApp::EUSimApp) + { + iActiveUSimApp.Zero(); + aTerminatedUSimApp = ETrue; + } + + return KErrNone; + } + else + { + LOGPHONE1("ATTEMPTED TO TERMINATE NON-ACTIVE APPLICATION"); + return KErrMMEtelScApplicationNotActive; + } + } + + }//end for loop + LOGPHONE1("WARNING: AID NOT FOUND. CANNOT PROCESS EVENT"); + return KErrNotFound; + } + + +void CSimPhoneSmartCardApp::TextToBin(const TDesC8& aSrc, TDes8& aDst) +/** + * Helper function + * + * Converts a text descriptor containing Hex information to binary. + * + * @param aSrc The input buffer + * @param aDst The output buffer + */ + { + //LOG_ASSERT((aSrc.Length() % 2) == 0, "Not passed in an even-length string?"); + + aDst.SetLength(aSrc.Length() / 2); + + for (TInt i = 0; i < aSrc.Length(); i += 2) + { + TInt val = 0; + if ((aSrc[i] >= '0') && (aSrc[i] <= '9')) + { + val = ((aSrc[i] - '0') << 4); + } + else if ((aSrc[i] >= 'A') && (aSrc[i] <= 'F')) + { + val = ((aSrc[i] - 'A' + 10) << 4); + } + else + { + __DEBUGGER(); + } + + if ((aSrc[i+1] >= '0') && (aSrc[i+1] <= '9')) + { + val += (aSrc[i+1] - '0'); + } + else if ((aSrc[i+1] >= 'A') && (aSrc[i+1] <= 'F')) + { + val += (aSrc[i+1] - 'A' + 10); + } + else + { + __DEBUGGER(); + } + + aDst[i/2] = (TUint8) val; + } + }