--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntsimutility/src/cntsimutility.cpp Tue Aug 31 15:05:21 2010 +0300
@@ -0,0 +1,488 @@
+/*
+* Copyright (c) 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:
+*
+*/
+#include "cntsimutility.h"
+#include <mmtsy_names.h>
+#include <startupdomainpskeys.h>
+#include <e32property.h>
+#include <centralrepository.h>
+
+// Number of keys used in central repository to keep latest import date
+// from SIM card: 5 IMSI strings and 5 dates.
+const int KCenRepKeysNumber = 10;
+const int KIMSISize = 15;
+const int KCenRepUid = 0x200315A8;
+
+CntSimUtility::CntSimUtility(StoreType type, int& error, QObject *parent)
+ : QObject(parent),
+ m_etelStoreInfoPckg(m_etelStoreInfo),
+ m_serviceTablePckg(m_serviceTable),
+ m_asyncWorker(NULL),
+ m_activeRequest(ENoActiveRequest),
+ m_securitySettings(NULL)
+{
+#ifdef __WINS__
+ error = KErrNotSupported;
+ return;
+#endif
+
+ error = m_etelServer.Connect();
+ if (error == KErrNone) {
+ error = m_etelServer.LoadPhoneModule(KMmTsyModuleName);
+ }
+ if (error == KErrNone) {
+ RTelServer::TPhoneInfo info;
+ error = m_etelServer.GetPhoneInfo(0, info);
+ if (error == KErrNone) {
+ error = m_etelPhone.Open(m_etelServer, info.iName);
+ }
+ }
+ if (error == KErrNone) {
+ // open specified Etel store
+ if (type == AdnStore) {
+ error = m_etelStore.Open(m_etelPhone, KETelIccAdnPhoneBook);
+ }
+ else if (type == SdnStore) {
+ error = m_etelStore.Open(m_etelPhone, KETelIccSdnPhoneBook);
+ }
+ else if (type == FdnStore) {
+ error = m_etelStore.Open(m_etelPhone, KETelIccFdnPhoneBook);
+ }
+ else {
+ error = KErrNotSupported;
+ }
+ }
+
+ if (error == KErrNone) {
+ error = m_customPhone.Open(m_etelPhone);
+ }
+
+ if (error == KErrNone) {
+ TRAP(error,
+ m_asyncWorker = new (ELeave)AsyncWorker(this);
+ TSecUi::InitializeLibL();
+ m_securitySettings = CSecuritySettings::NewL();
+ );
+ }
+}
+
+CntSimUtility::~CntSimUtility()
+{
+ m_etelStore.Close();
+ m_etelPhone.Close();
+ m_etelServer.Close();
+
+ delete m_asyncWorker;
+ delete m_securitySettings;
+ TSecUi::UnInitializeLib();
+}
+
+CntSimUtility::SimInfo CntSimUtility::getSimInfo(int& error)
+{
+ TRequestStatus requestStatus;
+ m_etelStore.GetInfo(requestStatus, (TDes8&)m_etelStoreInfoPckg);
+ User::WaitForRequest(requestStatus);
+ error = requestStatus.Int();
+ SimInfo results;
+
+ if (error == KErrNone) {
+ results.totalEntries = m_etelStoreInfo.iTotalEntries;
+ results.usedEntries = m_etelStoreInfo.iUsedEntries;
+ results.maxNumLength = m_etelStoreInfo.iMaxNumLength;
+ results.maxTextLength = m_etelStoreInfo.iMaxTextLength;
+ results.maxSecondNames = m_etelStoreInfo.iMaxSecondNames;
+ results.maxTextLengthSecondName = m_etelStoreInfo.iMaxTextLengthSecondName;
+ results.maxAdditionalNumbers = m_etelStoreInfo.iMaxAdditionalNumbers;
+ results.maxNumLengthAdditionalNumber = m_etelStoreInfo.iMaxNumLengthAdditionalNumber;
+ results.maxTextLengthAdditionalNumber = m_etelStoreInfo.iMaxTextLengthAdditionalNumber;
+ results.maxGroupNames = m_etelStoreInfo.iMaxGroupNames;
+ results.maxTextLengthGroupName = m_etelStoreInfo.iMaxTextLengthGroupName;
+ results.maxEmailAddr = m_etelStoreInfo.iMaxEmailAddr;
+ results.maxTextLengthEmailAddr = m_etelStoreInfo.iMaxTextLengthEmailAddr;
+ }
+ return results;
+}
+
+CntSimUtility::AvailableStores CntSimUtility::getAvailableStores(int& error)
+{
+ AvailableStores availableStores;
+ if (!isSimInserted()) {
+ error = KErrNone;
+ return availableStores;
+ }
+
+ m_serviceTableType = RMobilePhone::ESIMServiceTable;
+ unsigned long int iccCaps;
+ TRequestStatus requestStatus;
+
+ int result = m_etelPhone.GetIccAccessCaps(iccCaps);
+ if (result == KErrNone && (iccCaps & RMobilePhone::KCapsUSimAccessSupported)) {
+ m_serviceTableType = RMobilePhone::EUSIMServiceTable;
+ }
+
+ m_etelPhone.GetServiceTable(requestStatus, m_serviceTableType, m_serviceTablePckg);
+ User::WaitForRequest(requestStatus);
+ error = requestStatus.Int();
+
+ if (error == KErrNone) {
+ //parse service table to find what stores are supported
+ ParseServiceTable(&availableStores);
+ }
+ return availableStores;
+}
+
+bool CntSimUtility::verifyPin2Code()
+{
+ bool verified = false;
+ TRAP_IGNORE(verified = m_securitySettings->AskPin2L(););
+ return verified;
+}
+
+bool CntSimUtility::isFdnActive()
+{
+ RMobilePhone::TMobilePhoneFdnStatus fdnStatus;
+ (void)m_etelPhone.GetFdnStatus(fdnStatus);
+ if (fdnStatus == RMobilePhone::EFdnActive ||
+ fdnStatus == RMobilePhone::EFdnPermanentlyActive) {
+ return true;
+ }
+ return false;
+}
+
+int CntSimUtility::setFdnStatus(bool activated)
+{
+ RMobilePhone::TMobilePhoneFdnSetting fdnStatus = RMobilePhone::EFdnSetOff;
+ if (activated) {
+ fdnStatus = RMobilePhone::EFdnSetOn;
+ }
+ TRequestStatus status;
+ m_etelPhone.SetFdnSetting(status, fdnStatus);
+ User::WaitForRequest(status);
+ return status.Int();
+}
+
+QDateTime CntSimUtility::getLastImportTime(int& error)
+{
+ error = KErrNone;
+ if (!isSimInserted()) {
+ error = KErrAccessDenied;
+ return QDateTime();
+ }
+
+ // get IMSI
+ TBuf<KIMSISize> imsiBuf;
+ TRequestStatus reqStatus;
+ m_etelPhone.GetSubscriberId(reqStatus, imsiBuf);
+ User::WaitForRequest(reqStatus);
+ if (reqStatus.Int() != KErrNone) {
+ error = reqStatus.Int();
+ return QDateTime();
+ }
+
+ CRepository* cenrep = NULL;
+ TRAPD(err, cenrep = CRepository::NewL(TUid::Uid(KCenRepUid)));
+ if (err != KErrNone) {
+ error = err;
+ return QDateTime();
+ }
+
+ // find current IMSI in the stored values
+ int lastImportDate = 0;
+ for (int i = 1; i <= KCenRepKeysNumber; i+=2) {
+ TBuf<KIMSISize> storedImsiBuf;
+ if (cenrep->Get(i, storedImsiBuf) == KErrNone) {
+ if (storedImsiBuf.Compare(imsiBuf) == 0) {
+ if (cenrep->Get(i+1, lastImportDate) == KErrNone) {
+ break;
+ }
+ }
+ }
+ }
+ delete cenrep;
+ cenrep = NULL;
+
+ if (lastImportDate == 0) {
+ error = KErrNotFound;
+ return QDateTime();
+ }
+
+ QDateTime retLastImportDate;
+ retLastImportDate.setTime_t(lastImportDate);
+ return retLastImportDate;
+}
+
+void CntSimUtility::setLastImportTime(int& error)
+{
+ error = KErrNone;
+ if (!isSimInserted()) {
+ error = KErrAccessDenied;
+ return;
+ }
+
+ // get IMSI
+ TBuf<KIMSISize> imsiBuf;
+ TRequestStatus reqStatus;
+ m_etelPhone.GetSubscriberId(reqStatus, imsiBuf);
+ User::WaitForRequest(reqStatus);
+ if (reqStatus.Int() != KErrNone) {
+ error = reqStatus.Int();
+ return;
+ }
+
+ CRepository* cenrep = NULL;
+ TRAPD(err, cenrep = CRepository::NewL(TUid::Uid(KCenRepUid)));
+ if (err != KErrNone) {
+ error = err;
+ return;
+ }
+
+ // find current IMSI in the stored values
+ int lastImportDate = QDateTime::currentDateTime().toTime_t();
+ bool importDateUpdated = false;
+ for (int i = 1; i <= KCenRepKeysNumber; i+=2) {
+ TBuf<KIMSISize> storedImsiBuf;
+ if (cenrep->Get(i, storedImsiBuf) == KErrNone) {
+ if (storedImsiBuf.Compare(imsiBuf) == 0) {
+ //current IMSI already stored, update import date
+ if (cenrep->Set(i+1, lastImportDate) != KErrNone) {
+ error = KErrAccessDenied;
+ }
+ importDateUpdated = true;
+ break;
+ }
+ }
+ }
+
+ if (!importDateUpdated) {
+ int oldestDate = 0;
+ int key = 0;
+ // contacts were not imported from this SIM before,
+ // find oldest import date and replace it
+ for (int j = 2; j <= KCenRepKeysNumber; j+=2) {
+ int date;
+ if (cenrep->Get(j, date) == KErrNone) {
+ if (date >= oldestDate ) {
+ oldestDate = date;
+ key = j;
+ }
+ }
+ }
+
+ if (key == 0) {
+ error = KErrAccessDenied;
+ }
+ else {
+ if (cenrep->Set(key, lastImportDate) != KErrNone) {
+ error = KErrAccessDenied;
+ }
+ if (cenrep->Set(key-1, imsiBuf) != KErrNone) {
+ error = KErrAccessDenied;
+ }
+ }
+ }
+
+ delete cenrep;
+ cenrep = NULL;
+}
+
+bool CntSimUtility::startGetSimInfo()
+{
+ if(m_asyncWorker->IsActive()) {
+ return false;
+ }
+
+ m_etelStore.GetInfo(m_asyncWorker->iStatus, (TDes8&)m_etelStoreInfoPckg);
+ m_asyncWorker->SetActive();
+ m_activeRequest = EGetInfo;
+ return true;
+}
+
+bool CntSimUtility::startGetAvailableStores()
+{
+ if(m_asyncWorker->IsActive()) {
+ return false;
+ }
+
+ if (!isSimInserted()) {
+ AvailableStores availableStores;
+ emit availableStoresReady(availableStores, KErrNone);
+ return true;
+ }
+
+ m_serviceTableType = RMobilePhone::ESIMServiceTable;
+ unsigned long int iccCaps;
+ TRequestStatus requestStatus;
+
+ int result = m_etelPhone.GetIccAccessCaps(iccCaps);
+ if (result == KErrNone && (iccCaps & RMobilePhone::KCapsUSimAccessSupported)) {
+ m_serviceTableType = RMobilePhone::EUSIMServiceTable;
+ }
+ m_etelPhone.GetServiceTable(m_asyncWorker->iStatus, m_serviceTableType, m_serviceTablePckg);
+ m_asyncWorker->SetActive();
+ m_activeRequest = EGetAvailableStores;
+ return true;
+}
+
+bool CntSimUtility::notifyAdnCacheStatus()
+{
+ if(m_asyncWorker->IsActive()) {
+ return false;
+ }
+ CacheStatus cacheStatus;
+
+ //check current cache status
+ TRequestStatus requestStatus;
+ RMmCustomAPI::TPndCacheStatus pndStatus;
+ TName storeName;
+ storeName.Copy(KETelIccAdnPhoneBook);
+ m_customPhone.GetPndCacheStatus(requestStatus, pndStatus, storeName);
+ User::WaitForRequest(requestStatus);
+ if (requestStatus.Int() != KErrNone) {
+ return false;
+ }
+
+ if (pndStatus == RMmCustomAPI::ECacheReady ||
+ pndStatus == RMmCustomAPI::ECacheNotUsed) {
+ cacheStatus = ECacheReady;
+ emit adnCacheStatusReady(cacheStatus, KErrNone);
+ return true;
+ }
+ else if (pndStatus == RMmCustomAPI::ECacheFailed) {
+ cacheStatus = ECacheFailed;
+ emit adnCacheStatusReady(cacheStatus, KErrNone);
+ return true;
+ }
+ else if (pndStatus == RMmCustomAPI::ECacheNotReady) {
+ //wait for cache notification
+ m_customPhone.NotifyPndCacheReady(m_asyncWorker->iStatus, m_etelStoreNameCached);
+ m_asyncWorker->SetActive();
+ m_activeRequest = EGetCacheStatus;
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+void CntSimUtility::RequestCompleted(int error)
+{
+ if (m_activeRequest == EGetInfo) {
+ SimInfo results;
+ if (error == KErrNone) {
+ results.totalEntries = m_etelStoreInfo.iTotalEntries;
+ results.usedEntries = m_etelStoreInfo.iUsedEntries;
+ results.maxNumLength = m_etelStoreInfo.iMaxNumLength;
+ results.maxTextLength = m_etelStoreInfo.iMaxTextLength;
+ results.maxSecondNames = m_etelStoreInfo.iMaxSecondNames;
+ results.maxTextLengthSecondName = m_etelStoreInfo.iMaxTextLengthSecondName;
+ results.maxAdditionalNumbers = m_etelStoreInfo.iMaxAdditionalNumbers;
+ results.maxNumLengthAdditionalNumber = m_etelStoreInfo.iMaxNumLengthAdditionalNumber;
+ results.maxTextLengthAdditionalNumber = m_etelStoreInfo.iMaxTextLengthAdditionalNumber;
+ results.maxGroupNames = m_etelStoreInfo.iMaxGroupNames;
+ results.maxTextLengthGroupName = m_etelStoreInfo.iMaxTextLengthGroupName;
+ results.maxEmailAddr = m_etelStoreInfo.iMaxEmailAddr;
+ results.maxTextLengthEmailAddr = m_etelStoreInfo.iMaxTextLengthEmailAddr;
+ }
+ emit simInfoReady(results, error);
+ }//EGetInfo
+ else if (m_activeRequest == EGetAvailableStores) {
+ AvailableStores availableStores;
+ if (error == KErrNone) {
+ //parse service table to find what stores are supported
+ ParseServiceTable(&availableStores);
+ }
+ emit availableStoresReady(availableStores, error);
+ }//EGetAvailableStores
+ else if (m_activeRequest == EGetCacheStatus) {
+ if ( m_etelStoreNameCached.Compare(KETelIccAdnPhoneBook) == 0) {
+ //ADN cache is ready
+ CacheStatus cacheStatus;
+ if (error != KErrNone) {
+ cacheStatus = ECacheFailed;
+ emit adnCacheStatusReady(cacheStatus, error);
+ }
+ else {
+ cacheStatus = ECacheReady;
+ emit adnCacheStatusReady(cacheStatus, error);
+ }
+ }
+ else {
+ //another store is cached, continue listening for ADN cache
+ notifyAdnCacheStatus();
+ }
+ }//EGetCacheStatus
+
+ if (!m_asyncWorker->IsActive()) {
+ m_activeRequest = ENoActiveRequest;
+ }
+}
+
+void CntSimUtility::ParseServiceTable(AvailableStores* availableStores) const
+{
+ availableStores->SimPresent = true;
+ if (m_serviceTableType == RMobilePhone::EUSIMServiceTable) {
+ //ADN store is always present if SIM card is inserted
+ availableStores->AdnStorePresent = true;
+
+ if (m_serviceTable.iServices1To8 & RMobilePhone::KUstSDN ) {
+ availableStores->SdnStorePresent = true;
+ }
+ else {
+ availableStores->SdnStorePresent = false;
+ }
+
+ if (m_serviceTable.iServices1To8 & RMobilePhone::KUstFDN) {
+ availableStores->FdnStorePresent = true;
+ }
+ else {
+ availableStores->FdnStorePresent = false;
+ }
+ }
+ else if (m_serviceTableType == RMobilePhone::ESIMServiceTable) {
+ //ADN store is always present if SIM card is inserted
+ availableStores->AdnStorePresent = true;
+
+ if (m_serviceTable.iServices17To24 & RMobilePhone::KSstSDN) {
+ availableStores->SdnStorePresent = true;
+ }
+ else {
+ availableStores->SdnStorePresent = false;
+ }
+
+ if (m_serviceTable.iServices1To8 & RMobilePhone::KSstFDN) {
+ availableStores->FdnStorePresent = true;
+ }
+ else {
+ availableStores->FdnStorePresent = false;
+ }
+ }
+}
+
+bool CntSimUtility::isSimInserted() const
+{
+ bool result = false;
+
+ RProperty property;
+ int simStatus = KErrNotFound;
+
+ int ret = property.Get(KPSUidStartup, KPSSimStatus, simStatus);
+ if (simStatus == ESimUsable && ret == KErrNone) {
+ result = true;
+ }
+
+ property.Close();
+ return result;
+}