diff -r b183ec05bd8c -r 19bba8228ff0 fotaapplication/fotaserver/FotaServer/src/FotaServer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fotaapplication/fotaserver/FotaServer/src/FotaServer.cpp Wed Sep 01 12:27:42 2010 +0100 @@ -0,0 +1,2592 @@ +/* +* Copyright (c) 2005 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: Fota server update and download functionality +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "FotaSrvApp.h" +#include "FotaServer.h" +#include "FotaSrvDebug.h" +#include "FotasrvSession.h" +#include "fotaConst.h" +#include "nsmldmtreedbclient.h" +#include "fotaserverPrivatePSKeys.h" +#include "FotaNetworkRegStatus.h" +_LIT(KSizePass, "contentsize"); +#include "DevEncController.h" +#define __LEAVE_IF_ERROR(x) if(KErrNone!=x) {FLOG(_L("LEAVE in %s: %d"), __FILE__, __LINE__); User::Leave(x); } +// ============================= LOCAL FUNCTIONS ============================= + +// --------------------------------------------------------------------------- +// ToDesC16LC +// Converts to 16bit desc +// --------------------------------------------------------------------------- +HBufC* ToDesC16LC( const TDesC8& a ) + { + HBufC* bf = HBufC::NewLC( a.Length() ); + bf->Des().Copy(a); + return bf; + } +// --------------------------------------------------------------------------- +// GetPredefinedNodeL +// function to get preconfigured node for FUMO +// --------------------------------------------------------------------------- +void GetPredefinedNodeL(TDes8& aNode) + { + FLOG(_L("GetPredefinedNodeL() Begin")); + CRepository* centrep( NULL); + aNode.Zero(); + centrep = CRepository::NewLC( TUid::Uid(0x101F9A0A) ); + + if ( centrep ) + { + FLOG(_L("centralrepository found End")); + TFullName temp; + + if (centrep->Get( KDevManFUMOPredefinedNodes, temp )==KErrNone && temp.Length() ) + { + temp.Trim(); + aNode.Copy(temp); + } + CleanupStack::PopAndDestroy(centrep); + } + FLOG(_L("GetPredefinedNodeL() End")); + } +// --------------------------------------------------------------------------- +// DeleteFUMOTreeL +// function to get preconfigured node for FUMO +// --------------------------------------------------------------------------- +void DeleteFUMOTreeL () + { + FLOG(_L("DeleteFUMOTreeL() Begin")); + const TUint32 KNSmlFotaAdapterUid = 0x101F9A09; + _LIT8( KNSmlFumoPath, "FUMO" ); + _LIT8( KNSmlFumoSeparator, "/" ); + const TInt KGranularity = 10; + TBuf8 temp; + GetPredefinedNodeL(temp); + RNSmlDMCallbackSession session; + User::LeaveIfError(session.Connect()); + CleanupClosePushL(session); + + CBufBase *emptyList = CBufFlat::NewL(0); + CleanupStack::PushL(emptyList); + CArrayFixFlat * UriSegList; + UriSegList = new (ELeave) CArrayFixFlat (KGranularity); + + CleanupStack::PushL(UriSegList); + + session.GetUriSegListL(KNSmlFotaAdapterUid,KNSmlFumoPath,*UriSegList); + + for ( TUint16 i=0;iCount();i++) + { + if (temp.Length() && UriSegList->At(i).iURISeg.Find( temp ) != KErrNotFound) + { + FLOG(_L("DeleteFUMOTreeL predefined match =%S"), &temp); + continue; + } + + TBuf8 tempFumo; + tempFumo.Append(KNSmlFumoPath); + tempFumo.Append(KNSmlFumoSeparator); + tempFumo.Append(UriSegList->At(i).iURISeg); + FLOG(_L("DeleteFUMOTreeL() call update mapping info for node %S"),&tempFumo); + session.UpdateMappingInfoL(KNSmlFotaAdapterUid,tempFumo,*emptyList); + + } + // session.UpdateMappingInfoL(KNSmlFotaAdapterUid,KNSmlFumoPath,*emptyList); + CleanupStack::PopAndDestroy(UriSegList); + CleanupStack::PopAndDestroy(emptyList); + CleanupStack::PopAndDestroy(&session); //session + FLOG(_L("DeleteFUMOTreeL() End")); + } + +// --------------------------------------------------------------------------- +// CFotaServer::GetProfileDataL +// --------------------------------------------------------------------------- +void CFotaServer::GetProfileDataL( RSyncMLSession* aSyncml + ,const TSmlProfileId aProf, TInt& aIapId, TSmlServerAlertedAction& aSrvAA + ,TBool& aUIJob, TInt& aSanVal) + { + FLOG(_L("CFotaServer::GetProfileDataL prof %d"),aProf); + __ASSERT_ALWAYS( aSyncml, User::Panic(KFotaPanic, KErrArgument) ); + __ASSERT_ALWAYS( aSyncml->Handle(), User::Panic(KFotaPanic, KErrBadHandle) ); + // GET IAP FROM PROFILE ---------------------------------------------- + TSmlJobId jobid( KErrNotFound ); + TInt jobidFromUI( KErrNotFound ); + RSyncMLDevManProfile smlprof; + RArray connections; + TSmlTransportId transport; + RSyncMLConnection connection; + + CleanupClosePushL(smlprof); + CleanupClosePushL(connections); + CleanupClosePushL(connection); + FLOG(_L("[FotaServer] 1")); + + FLOG(_L("[FotaServer] 1.1 opening syncml \ + profileid %d "), aProf); + smlprof.OpenL(*aSyncml, aProf, ESmlOpenRead); + FLOG(_L("[FotaServer] 1.1")); + smlprof.ListConnectionsL(connections); + FLOG(_L("[FotaServer] 1.3")); + transport = connections[0]; + connection.OpenL(smlprof,transport); + TBuf8<20> iapid2 = connection.GetPropertyL ( KNSmlIAPId ); + TLex8 iapid3(iapid2); + iapid3.Val(aIapId); + + // 1. Profile's "accepted" field. + aSrvAA = smlprof.SanUserInteraction (); + FLOG(_L("[FotaServer] 1.4 \ + SanUserInteraction:%d"),aSrvAA ); + + // 2. Has job been started from omadmappui. That is, did user start the job + TSmlUsageType dmusagetype(ESmlDevMan); + aSyncml->CurrentJobL( jobid,dmusagetype ); + RProperty::Get( TUid::Uid(KOmaDMAppUid), KNsmlCurrentJobId, jobidFromUI); + aUIJob = ( jobidFromUI == jobid && jobid!=KErrNotFound ); + + aSanVal = KErrNotFound; + if ( aUIJob ) + { + //First for not server alert or SAN not supported value is -1 + RProperty::Get( TUid::Uid(KOmaDMAppUid), KNsmlSanUIMode, aSanVal); + if ( aSanVal != -1 ) //SAN Supported + { + aUIJob = 0; + } + } + FLOG(_L(" jobidFromUI: %d jobid: %d, aUIJob: %d, aSanVal: %d"),jobidFromUI,jobid,aUIJob,aSanVal); + CleanupStack::PopAndDestroy (&connection); + CleanupStack::PopAndDestroy (&connections); + CleanupStack::PopAndDestroy (&smlprof); + } + +// -------------------------------------------------------------------------- +// CreateDeviceManagementSessionL +// Creates DM session +// -------------------------------------------------------------------------- +void CFotaServer::CreateDeviceManagementSessionL( TPackageState& aState ) + { + FLOG(_L("[cfotasever] CreateDeviceManagementSessionL dms >> profid %d\ + %d counts left ,sml handle %d, iNetworkAvailable=%d"), aState.iProfileId, aState.iSmlTryCount + , iSyncMLSession.Handle(),iNetworkAvailable); + + SetStartupReason(EFotaPendingGenAlert); + + if (!iNetworkAvailable) + { + iRetryingGASend = ETrue; + iStoredState = aState; + StartNetworkMonitorL(); + } + else + { + + TBool dbAlreadyOpen = iDatabase->IsOpen(); + TBool triesLeft( EFalse ); + + iNetworkAvailable = EFalse; // to check network again when GA is sent next time + + if ( iSyncMLSession.Handle() ) + { + User::Leave( KErrAlreadyExists ); + } + + if ( !dbAlreadyOpen ) iDatabase->OpenDBL(); + // There is still tries left + if ( aState.iSmlTryCount > 0 ) + { + triesLeft = ETrue; + FLOG(_L(" decrementing the retry count")); + aState.iSmlTryCount = aState.iSmlTryCount - 1; + iDatabase->SetStateL( aState, KNullDesC8, EFDBSmlTryCount ); + } + // out of tries, set state to idle + else + { + triesLeft = EFalse; + FLOG(_L(" out of tries, resetting pkg state")); + + SetStartupReason(EFotaDefault); + aState.iState = RFotaEngineSession::EIdle; + aState.iResult = KErrNotFound; + iDatabase->SetStateL( aState, KNullDesC8, EFDBState|EFDBResult ); + } + if ( !dbAlreadyOpen ) iDatabase->CloseAndCommitDB(); + + if ( triesLeft ) + { + TInt iapid; + TSmlServerAlertedAction tmp; + TBool tmp2; + TInt tmp3; + iSyncMLSession.OpenL(); + GetProfileDataL( &iSyncMLSession,aState.iProfileId,iapid,tmp,tmp2,tmp3); + FLOG(_L("Using IAP: %d to send GA"),iapid); + FLOG(_L("From Db Using IAP: %d to send GA"),aState.iIapId); + RSyncMLDevManJob dmJob; + + RProperty::Define(KPSUidNSmlSOSServerKey,KNSmlDMSilentJob,RProperty::EInt,KAllowAllPolicy,KWritePolicy); + TInt r2=RProperty::Set(KPSUidNSmlSOSServerKey,KNSmlDMSilentJob,ESilent); + FLOG(_L("CFotaServer::CreateDeviceManagementSessionL KNSmlDMSilentJob set err %d"),r2); + TBuf<10> genalertap,temp; + genalertap.Zero(); + temp.Zero(); + genalertap.Append(KNSmlDMJobIapPrefix); + temp.Num(aState.iIapId);//Decimal Iap + if( temp.Length() <= KNSmlHalfTransportIdLength && + aState.iIapId > KErrNotFound && CheckIapExistsL(aState.iIapId) ) + { + genalertap.AppendFill('0',KNSmlHalfTransportIdLength-temp.Length()); + genalertap.Append(temp); + TLex gavalue(genalertap); + gavalue.Val(iIapId); + dmJob.CreateL( iSyncMLSession, aState.iProfileId,iIapId); + iSyncMLAttempts = KSyncmlAttemptCount; + } + else + { + iSyncMLAttempts = 0; + dmJob.CreateL( iSyncMLSession, aState.iProfileId); + } + + // If there's no iapid defined, sml will pop up connection dialog. + // In that case, only one connection attempt is allowed. + iSyncJobId = dmJob.Identifier(); + iSyncProfile = aState.iProfileId; + dmJob.Close(); + iSyncMLSession.RequestEventL( *this ); + } + } + + FLOG(_L("[cfotasever] CreateDeviceManagementSessionL dms << profid %d") + ,aState.iProfileId); + } + + +// ============================= MEMBER FUNCTIONS ============================ + +// -------------------------------------------------------------------------- +// CFotaServer::CFotaServer() +// -------------------------------------------------------------------------- +// +CFotaServer::CFotaServer() : iInitialized(EFalse), iNeedToClose(0), iParentApp(0) +, iDatabase(0),iDownloader(0), iUpdater(0) + , iDownloadFinalizer(0), iUpdateFinalizer(0), iTimedExecuteResultFile(0) + , iTimedSMLSessionClose(0), iStorage(0), iAppShutter(0), iMonitor (NULL), iSyncJobId(-1), iRetryingGASend (EFalse), iNetworkAvailable (EFalse) + , iIapId(KErrNotFound),iSessMode(0),iUserResume(KErrNotFound), iInstallupdClient(EFalse), iDEController(NULL) + { + RProcess pr; TFullName fn = pr.FullName(); TUint prid = pr.Id(); + FLOG(_L( "CFotaServer::CFotaServer process(id %d)%S. this 0x%x"),prid,&fn + ,this); + + } + + +// -------------------------------------------------------------------------- +// CFotaServer::DoExecuteResultFileL +// Interprets result of update (file update.resp) +// -------------------------------------------------------------------------- +// +void CFotaServer::DoExecuteResultFileL() + { + FLOG(_L("CFotaServer::DoExecuteResultFileL() >>")); + + if ( iTimedExecuteResultFile ) + { + iTimedExecuteResultFile->Cancel(); + delete iTimedExecuteResultFile; + iTimedExecuteResultFile = NULL; + } + iUpdater = CFotaUpdate::NewL(this); + iUpdater->ExecuteUpdateResultFileL( iFs ); + FLOG(_L("CFotaServer::DoExecuteResultFileL() <<")); + } + +// -------------------------------------------------------------------------- +// StaticDoExecuteResultFile +// -------------------------------------------------------------------------- +// +static TInt StaticDoExecuteResultFile(TAny *aPtr) + { + FLOG(_L("[cfotaserver] StaticDoExecuteResultFile() >>")); + __ASSERT_ALWAYS( aPtr, User::Panic(KFotaPanic, KErrBadHandle) ); + CFotaServer* srv = (CFotaServer*) aPtr; + TRAPD( err, srv->DoExecuteResultFileL() ); + if(err) + { + FLOG(_L("[cfotaserver] StaticDoExecuteResultFile ERROR %d"),err); + TRAP_IGNORE(srv->DoDeleteUpdateResultFileL()); + } + + FLOG(_L("[cfotaserver] StaticDoExecuteResultFile() <<")); + return err; + } + + +// -------------------------------------------------------------------------- +// CFotaServer::CFotaServer() +// Constructor. Can't do all constructing since fotaserver might call itself +// recursively (via downloadmgr). +// -------------------------------------------------------------------------- +// +void CFotaServer::ConstructL(const TDesC &aFixedServerName) + { + FLOG(_L("CFotaServer::ConstructL() >> name=%S"), &aFixedServerName); + TBool updated (EFalse); + TInt err; + CAknAppServer::ConstructL( aFixedServerName ); + + User::LeaveIfError( iFs.Connect() ); + + err = iFs.CreatePrivatePath(EDriveC); + if ( err != KErrNone && err != KErrAlreadyExists ) { User::Leave (err); } + User::LeaveIfError( iFs.SetSessionToPrivate( EDriveC ) ); + + if ( !iDatabase ) + { + TRAPD( err,iDatabase = CFotaDB::NewL() ); + if ( err ) + { + FLOG(_L("CFotaServer:: DB creationg error %d"), err); + User::Leave( err ); + } + } + + updated = CFotaUpdate::CheckUpdateResults( iFs ); + + // Update has happened, and result file is in place + if ( updated ) + { + FLOG(_L("scheduling update result file execution")); + if ( iTimedExecuteResultFile ) + { + iTimedExecuteResultFile->Cancel(); + delete iTimedExecuteResultFile; + iTimedExecuteResultFile = NULL; + } + iTimedExecuteResultFile = CPeriodic::NewL (EPriorityNormal) ; + iTimedExecuteResultFile->Start ( + TTimeIntervalMicroSeconds32(KDownloadFinalizerWaitTime) + , TTimeIntervalMicroSeconds32(KDownloadFinalizerWaitTime) + , TCallBack(StaticDoExecuteResultFile,this) ) ; + } + + iEikEnv = CEikonEnv::Static(); + FLOG(_L("CFotaServer::ConstructL() <<")); + } + + +// -------------------------------------------------------------------------- +// CFotaServer::ClientAwareConstructL +// Does rest of constructing, if not done. If parent of this fotaserver +// instance is another fotaserver, skip maintenance operations (since parent +// takes care of them). DmHOstserver triggers cleanup for states: 20,70,80 +// ,90,100 , must handle state 60 here +// -------------------------------------------------------------------------- +void CFotaServer::ClientAwareConstructL( const RMessage2 &aMessage ) + { + FLOG(_L("CFotaServer::ClientAwareConstructL >>")); + if ( iInitialized ) return; + CFotaSrvSession::TClient client + = CFotaSrvSession::CheckClientSecureIdL ( aMessage ); + // temporary fix to keep FS from polluting FSW in case it was opened from omadmappui + if ( client == CFotaSrvSession::EOMADMAppUi || client == CFotaSrvSession::EFotaServer || + client == CFotaSrvSession::ESoftwareChecker || client == CFotaSrvSession::ESoftwareCheckerBackground ) + { + //Loading the storage plugin (during DM UI launch) to adjust the reserved memory accordingly. + StoragePluginL(); + iParentApp->SetUIVisibleL ( EFalse, ETrue ); // + } + + // Do constructing if client is other that fotaserver + if ( client != CFotaSrvSession::EFotaServer ) + { + RArray states; + TPackageState state; + CleanupClosePushL (states); + iDatabase->OpenDBL(); + iDatabase->GetAllL ( states ); + TBool value (EFalse); + if (iDownloader) + { + value = iDownloader->IsDownloadActive(); + } + else + { + TInt err = RProperty::Get(TUid::Uid(KFotaServerUid), KFotaDownloadActive, value ); + FLOG(_L("value of KFotaDownloadActive & err as %d,%d "), (TInt)value,err); + } + FLOG(_L("Download active value is:%d "), (TInt)value); + // Loop states. + for(TInt i = 0; i < states.Count(); ++i ) + { + TPackageState tmp; + TBool toIdle(EFalse); + tmp = iDatabase->GetStateL( states[i] ); + FLOG(_L(" 1 got state id:%d state:%d result:%d"), tmp.iPkgId + , tmp.iState, tmp.iResult); + + if ( tmp.iState == RFotaEngineSession::EStartingUpdate ) + + { + TBool ispkgvalid= ETrue; + TRAPD(err1,ispkgvalid= CheckSWVersionL() ) + if (!ispkgvalid && err1 == KErrNone) + { + StoragePluginL()->DeleteUpdatePackageL ( tmp.iPkgId ); + tmp.iState = RFotaEngineSession::EUpdateFailed; + tmp.iResult = RFotaEngineSession::EResPackageMismatch; + iDatabase->SetStateL( tmp,KNullDesC8, EFDBState | EFDBResult ); + + } + } + // Update has been started (60) + // If there is no result file, means that update agent failed + // to run. Must get back to 50 to allow user to try again. + if ( tmp.iState == RFotaEngineSession::EUpdateProgressing + && iTimedExecuteResultFile==NULL ) + { + FLOG(_L(" State 60 found, UA didnt run! id %d "), tmp.iPkgId); + tmp.iState = RFotaEngineSession::EStartingUpdate; + iDatabase->SetStateL( tmp,KNullDesC8, EFDBState); + } + + // These states need must trigger generic alert! (70+ ) + if ( tmp.iState >= RFotaEngineSession::EUpdateFailed ) + { + if ( iSyncMLSession.Handle() == NULL ) + { + iDatabase->CloseAndCommitDB(); + CreateDeviceManagementSessionL( tmp ); + iDatabase->OpenDBL(); + } + } + + if (tmp.iState == RFotaEngineSession::EDownloadComplete && tmp.iResult == RFotaEngineSession::EResSuccessful ) + { + CreateDeviceManagementSessionL( tmp ); + } + + if (value != 1) //if download is not active, EStartingDownload should be reset to EDownloadFailed + { + if (tmp.iState == RFotaEngineSession::EStartingDownload || + tmp.iState == RFotaEngineSession::EDownloadProgressing ) + { + FLOG(_L("Resetting state %d to 20..."), tmp.iState); + tmp.iState = RFotaEngineSession::EDownloadFailed; + iDatabase->SetStateL( tmp,KNullDesC8, EFDBState ) ; + iDatabase->CloseAndCommitDB(); + iDatabase->OpenDBL(); + } + } + + if ( tmp.iState == RFotaEngineSession::EDownloadFailed ) + { + StoragePluginL()->DeleteUpdatePackageL( tmp.iPkgId ); + tmp.iResult = RFotaEngineSession::EResDLFailDueToNWIssues; + iDatabase->SetStateL( tmp,KNullDesC8, EFDBResult ) ; + iDatabase->CloseAndCommitDB(); + CreateDeviceManagementSessionL( tmp ); + iDatabase->OpenDBL(); + } + + // Reset package state to idle + if ( toIdle ) + { + FLOG(_L(" 2 resetting state %d to idle"), tmp.iPkgId); + tmp.iState = RFotaEngineSession::EIdle; + iDatabase->SetStateL( tmp,KNullDesC8, EFDBState ) ; + DeleteFUMOTreeL(); + } + } + iDatabase->CloseAndCommitDB(); + CleanupStack::PopAndDestroy( &states ); + } + else // client is child fotaserver + { + } + iInitialized = ETrue; + FLOG(_L("CFotaServer::ClientAwareConstructL <<")); + } + + +// --------------------------------------------------------------------------- +// CFotaServer::StoragePluginL +// Getter function for iStorage. If it doesn't exist, load it. +// --------------------------------------------------------------------------- +// +CFotaStorage* CFotaServer::StoragePluginL() + { + if ( iStorage == NULL ) + { + LoadStoragePluginL(); + } + return iStorage; + } + + +// -------------------------------------------------------------------------- +// CFotaServer::LoadStoragePluginL +// Load update storage plugin via ecom framework. +// -------------------------------------------------------------------------- +// +void CFotaServer::LoadStoragePluginL () + { + FLOG(_L("CFotaServer::LoadStoragePluginL")); + if(iStorage) + { + UnLoadStoragePluginL (); + } + TUid if_uid; + if_uid.iUid = ( KStorageIFUid ); + RImplInfoPtrArray pluginArray; + REComSession::ListImplementationsL( if_uid, pluginArray ); + CleanupClosePushL( pluginArray ); + + if( pluginArray.Count() ) + { + for( TInt i = 0; i < pluginArray.Count(); i++ ) + { + CImplementationInformation* info = pluginArray[ i ]; + TUid id = info->ImplementationUid(); + delete info; + info = NULL; + iStorage =(CFotaStorage*) REComSession::CreateImplementationL( id + ,iStorageDtorKey); + } + } + else + { + FLOG(_L(" storage plugin not found, ERROR")); + User::Leave ( KErrNotFound ); + } + CleanupStack::PopAndDestroy( &pluginArray ); + } + +// -------------------------------------------------------------------------- +// CFotaServer::UnLoadStoragePluginL +// Unloads storage plugin +// -------------------------------------------------------------------------- +// +void CFotaServer::UnLoadStoragePluginL () + { + FLOG(_L("CFotaServer::UnLoadStoragePluginL")); + if ( iStorage ) + { + delete iStorage; + iStorage=NULL; + } + FLOG(_L(" destroying")); + REComSession::DestroyedImplementation(iStorageDtorKey); // zeroes referenc + // count of plugin + FLOG(_L(" finalclosing")); + REComSession::FinalClose(); + } + + +// -------------------------------------------------------------------------- +// StaticDoFinalizeUpdate +// Intermediate function +// -------------------------------------------------------------------------- +static TInt StaticDoFinalizeUpdate(TAny *aPtr) + { + FLOG(_L("[cfotaserver] StaticDoFinalizeUpdate() >>")); + CFotaServer* srv = (CFotaServer*) aPtr; + TRAPD( err, srv->DoFinalizeUpdateL() ); + if(err) + { + FLOG(_L("[cfotaserver] StaticDoFinalizeUpdate ERROR %d"),err); + } + + FLOG(_L("[cfotaserver] StaticDoFinalizeUpdate() <<")); + return err; + } + + +// -------------------------------------------------------------------------- +// CFotaServer::FinalizeUpdate() +// Initialize finalization of updater +// -------------------------------------------------------------------------- +// +void CFotaServer::FinalizeUpdateL() + { + FLOG(_L("CFotaServer::FinalizeUpdate() >>")); + if ( iUpdateFinalizer ) + { + iUpdateFinalizer->Cancel(); + delete iUpdateFinalizer; + iUpdateFinalizer=NULL; + } + iUpdateFinalizer = CPeriodic::NewL (EPriorityNormal) ; + iUpdateFinalizer->Start ( + TTimeIntervalMicroSeconds32(KDownloadFinalizerWaitTime) + ,TTimeIntervalMicroSeconds32(KDownloadFinalizerWaitTime) + ,TCallBack(StaticDoFinalizeUpdate,this) ) ; + FLOG(_L("CFotaServer::FinalizeUpdate() <<")); + } + + +// -------------------------------------------------------------------------- +// CFotaServer::DoFinalizeUpdateL +// Finalize update. Free resources +// -------------------------------------------------------------------------- +// +void CFotaServer::DoFinalizeUpdateL() + { + FLOG(_L("CFotaServer::DoFinalizeUpdateL() >>")); + + // Free resources + FLOG(_L("iupdater = %d"), iUpdater); + if ( iUpdater ) + { + FLOG(_L("Deleting iupdater...")); + iUpdater->Cancel(); + delete iUpdater; + iUpdater=NULL; + } + + if ( iUpdateFinalizer ) + { + iUpdateFinalizer->Cancel(); + } + // Hide UI + iParentApp->SetUIVisibleL ( EFalse, ETrue ); + FLOG(_L("CFotaServer::DoFinalizeUpdateL() <<")); + } + + +// -------------------------------------------------------------------------- +// StaticDoFinalizeDownload +// Intermediate function +// -------------------------------------------------------------------------- +static TInt StaticDoFinalizeDownload(TAny *aPtr) + { + FLOG(_L("[cfotaserver] StaticDoFinalizeDownload() >>")); + CFotaServer* srv = (CFotaServer*) aPtr; + TRAPD( err, srv->DoFinalizeDownloadL() ); + if(err) + { + FLOG(_L("[cfotaserver] StaticDoFinalizeDownload ERROR %d"),err); + } + + FLOG(_L("[cfotaserver] StaticDoFinalizeDownload() <<")); + return err; + } + + +// -------------------------------------------------------------------------- +// CFotaServer::FinalizeDownload +// Initialize finalization of download +// -------------------------------------------------------------------------- +// +void CFotaServer::FinalizeDownloadL( const TPackageState& aDLState ) + { + FLOG(_L("CFotaServer::FinalizeDownload() >> state:%d result:%d") + ,aDLState.iState, aDLState.iResult); + __ASSERT_ALWAYS( iDownloader, User::Panic(KFotaPanic, KErrBadHandle )); + + SetStartupReason(EFotaDefault); + + if ( iDownloadFinalizer ) + { + iDownloadFinalizer->Cancel(); + delete iDownloadFinalizer; + iDownloadFinalizer=NULL; + } + iDownloadFinalizer = CPeriodic::NewL (EPriorityMuchMore) ; + iDLFinalizeState = aDLState; + + // Not restarting,quick finalize + if ( iDownloader->iRestartCounter<=0 ) + { + iDownloadFinalizer->Start( + TTimeIntervalMicroSeconds32(KDownloadFinalizerWaitTime) + ,TTimeIntervalMicroSeconds32(KDownloadFinalizerWaitTime) + ,TCallBack(StaticDoFinalizeDownload,this) ) ; + } + // Restarting, wait some time + else + { + iDownloadFinalizer->Start( + TTimeIntervalMicroSeconds32(2000000) + ,TTimeIntervalMicroSeconds32(2000000) + ,TCallBack(StaticDoFinalizeDownload,this) ) ; + } + FLOG(_L("CFotaServer::FinalizeDownload() <<")); + } + + +// -------------------------------------------------------------------------- +// CFotaServer::DoFinalizeDownloadL +// Finalize download. Free resources +// -------------------------------------------------------------------------- +// +void CFotaServer::DoFinalizeDownloadL() + { + FLOG(_L("CFotaServer::DoFinalizeDownloadL() >> state:%d result:%d") + ,iDLFinalizeState.iState, iDLFinalizeState.iResult ); + __ASSERT_ALWAYS( iDownloader, User::Panic(KFotaPanic, KErrBadHandle )); + + if ( iDownloadFinalizer ) + { + iDownloadFinalizer->Cancel(); + } + + if (iDownloader->iDLState.iState == RFotaEngineSession::EDownloadFailed) + StoragePluginL()->DeleteUpdatePackageL ( iDownloader->iDLState.iPkgId ); + + // Download not to be restarted, delete + if ( iDownloader ) + { + if ( iDownloader->iRestartCounter<=0 ) + { + // Set downloader's ending state to DB + iDatabase->OpenDBL(); + iDatabase->SetStateL(iDLFinalizeState + ,KNullDesC8,EFDBState|EFDBResult); + iDatabase->CloseAndCommitDB(); + + iDownloader->SetDownloadActive(EFalse); + iParentApp->SetUIVisibleL( EFalse,ETrue); + + // Initiate update + if ( iDownloader && iDownloader->iUpdateAfterDownload ) + { + UpdateL( iDownloader->iDLState ); + } + // Report status to DM server + else + { + if (iDownloader->iDLState.iState == RFotaEngineSession::EDownloadProgressingWithResume ) + { + if (iDownloader->IsFMSEnabled()) + { + FLOG(_L("Invoking FMS...")); + InvokeFmsL(); + SetStartupReason(EFotaDownloadInterrupted); + } + } + else + { + CreateDeviceManagementSessionL( iDownloader->iDLState ); + } + } + + // Free resources + if ( iDownloader ) + { + iDownloader->Cancel(); + iDownloader->CancelDownload (ETrue); + delete iDownloader; + iDownloader=NULL; + } + TInt val (EFalse); + TInt err = RProperty::Get(TUid::Uid(KOmaDMAppUid), KFotaDMRefresh, val ); + if (val!=EFalse) + err = RProperty::Set(TUid::Uid(KOmaDMAppUid), KFotaDMRefresh, EFalse ); + FLOG(_L("RProperty KFotaDMRefresh EFalse, err = %d"), err); + } + } + // Download to be restarted + else + { + __ASSERT_ALWAYS( iDownloader->iUrl + ,User::Panic(KFotaPanic, KErrBadHandle )); + FLOG(_L(" Restarting download(iRestartCounter %d)"),iDownloader->iRestartCounter); + + // Reuse url and iapid + HBufC8* url = iDownloader->iUrl->AllocLC(); + TInt iapid = iDownloader->iDLState.iIapId; + + TBool update= iDownloader->iUpdateAfterDownload; + TInt restart=iDownloader->iRestartCounter; + + iDownloader->CancelDownload( EFalse ); //Doesn't actually deletes downloads when S&R feature is supported. + + iDownloader->DownloadL( iDLFinalizeState , *url,update,iapid, restart); + CleanupStack::PopAndDestroy( url ); + } + + + FLOG(_L("CFotaServer::DoFinalizeDownloadL() <<")); + } + + +// -------------------------------------------------------------------------- +// StaticDoCloseSMLSession +// Intermediate function +// -------------------------------------------------------------------------- +static TInt StaticDoCloseSMLSession ( TAny *aPtr ) + { + FLOG(_L("[cfotaserver] StaticDoCloseSMLSession() >>")); + CFotaServer* srv = (CFotaServer*) aPtr; + TRAPD( err, srv->DoCloseSMLSessionL() ); + if(err) + { + FLOG(_L("[cfotaserver] StaticDoCloseSMLSession ERROR %d"),err); + } + + FLOG(_L("[cfotaserver] StaticDoCloseSMLSession() <<")); + return err; + } + +// -------------------------------------------------------------------------- +// CFotaServer::DoCloseSMLSessionL +// Close syncml session, or resync +// -------------------------------------------------------------------------- +// +void CFotaServer::DoCloseSMLSessionL() + { + FLOG(_L("CFotaServer::DoCloseSMLSessionL() >>")); + + // Must still try to sync + if ( iSyncMLAttempts > 0 ) + { + FLOG(_L(" trycount %d => creating new job"),iSyncMLAttempts); + RSyncMLDevManJob dmJob; + if(iIapId > KErrNotFound) + { + FLOG(_L("DoCloseSMLSessionL new job uses iap from fotadb %d"), + iIapId); + RProperty::Define(KPSUidNSmlSOSServerKey,KNSmlDMSilentJob,RProperty::EInt,KAllowAllPolicy,KWritePolicy); + TInt r2=RProperty::Set(KPSUidNSmlSOSServerKey,KNSmlDMSilentJob,ESilent); + FLOG(_L("CFotaServer::DoCloseSMLSessionL() KNSmlDMSilentJob set err %d"),r2); + dmJob.CreateL( iSyncMLSession, iSyncProfile,iIapId ); + } + else + { + FLOG(_L("DoCloseSMLSessionL new job uses iap from profile")); + dmJob.CreateL( iSyncMLSession, iSyncProfile ); + } + iSyncMLAttempts--; + iSyncJobId = dmJob.Identifier(); + dmJob.Close(); + } + else + // We ran out of attempts, close sml + { + if ( iSyncMLSession.Handle() ) + { + FLOG(_L(" Closing syncml session")); + iSyncMLSession.CancelEvent(); + iSyncMLSession.Close(); + } + } + + if ( iTimedSMLSessionClose ) + { + FLOG(_L(" closing smlsession timer")); + iTimedSMLSessionClose->Cancel(); + delete iTimedSMLSessionClose; + iTimedSMLSessionClose = NULL; + } + + FLOG(_L("CFotaServer::DoCloseSMLSessionL() <<")); + } + + +// -------------------------------------------------------------------------- +// CFotaServer::ReadChunkL +// Read data from chunk created by client. +// -------------------------------------------------------------------------- +// +void CFotaServer::ReadChunkL( const TInt aSize,TInt aError ) + { + __ASSERT_ALWAYS( aSize>=0 , User::Panic(KFotaPanic, KErrArgument) ); + TUint8* b = iChunk.Base(); + TPtr8 data(b, aSize, aSize ); + + iStorage->iBytesWritten += aSize; + FLOG(_L(" CFotaServer::ReadChunkL >> reading %d bytes"),aSize); + if (iStorageStream && aError !=KErrServerTerminated && + aError !=KErrDiskFull ) + {FLOG(_L(" CFotaServer::ReadChunkL >> inside if(iStorageStream)")); + TRAPD ( err, iStorageStream->WriteL(data) ); + + if ( !err ) + { + iStorageStream->CommitL(); + } + else + { + FLOG(_L("Error when writing pkg %d"), err); + iStorageStream->Close(); + iStorageStream = NULL; + User::Leave ( err ); + } + } + FLOG(_L(" CFotaServer::ReadChunkL << ")); + } + + +// -------------------------------------------------------------------------- +// CFotaServer::OpenUpdatePackageStoreL +// Opens package store. Calling chain in case of oma DL: +// fotaserver->downloadmgr->codhandler->fotaserver (subject to change, +// depending on downloadmgr&codhandler changes) +// Fotaadapter calls this function in direct way: fotaadapter->fotaserver +// +// -------------------------------------------------------------------------- +// +void CFotaServer::OpenUpdatePackageStoreL ( const RMessage2& aMessage ) + { + FLOG(_L("CFotaServer::OpenUpdatePackageStoreL >>")); + + // If chunk is already open, bail out + THandleInfo info; + TInt pkgid; + iChunk.HandleInfo(&info); + + + if(info.iNumOpenInProcess>0) + { + FLOG(_L("CFotaServer::SetChunkHandleL chunk is open %d times by \ + current process (%d times in thread)"),info.iNumOpenInProcess + ,info.iNumOpenInThread); + User::Leave(KErrInUse); + } + + // Set package state + pkgid = aMessage.Int0(); + iStorageDownloadPackageId = pkgid; + + TPackageState state = GetStateL(pkgid); + + // AS 16.02.05: must be in failed state until complete + + FLOG(_L("CFotaServer::OpenUpdatePackageStoreL opening update pkg storage\ + ffor pkgid: %d "),pkgid); + + TInt size2 = state.iPkgSize; + // Use storage api to save update pkg + StoragePluginL()->OpenUpdatePackageStoreL(pkgid,size2, iStorageStream); + + User::LeaveIfError( iChunk.Open(aMessage,1,EFalse) ); + TInt err = RProperty::Define( TUid::Uid(KFotaServerUid), + KFotaLrgObjDl,RProperty::EInt, + KReadPolicy, KWritePolicy ); + TInt err1 = RProperty::Set( TUid::Uid(KFotaServerUid), + KFotaLrgObjDl, KErrNotFound ); + FLOG(_L("CFotaServer::OpenUpdatePackageStoreL err for KFotaLrgObjDl define is %d err is %d"), + err,err1 ); + err = RProperty::Define( TUid::Uid(KFotaServerUid), + KFotaLrgObjProfileId,RProperty::EInt, + KReadPolicy,KWritePolicy ); + err1 = RProperty::Set( TUid::Uid(KFotaServerUid), + KFotaLrgObjProfileId, KErrNotFound ); + FLOG(_L("CFotaServer::OpenUpdatePackageStoreL err for KFotaLrgObjProfileId define is %d err is %d"), + err,err1 ); + FLOG(_L("CFotaServer::OpenUpdatePackageStoreL <<")); + } + +// -------------------------------------------------------------------------- +// CFotaServer::GetDownloadUpdatePackageSizeL +// Gets the downloaded update package size in bytes +// -------------------------------------------------------------------------- +// +void CFotaServer::GetDownloadUpdatePackageSizeL (const TInt aPkgId, TInt& aDownloadedSize, TInt& aTotalSize) + { + FLOG(_L("CFotaServer::GetDownloadUpdatePackageSize, aPkgId = %d >>"),aPkgId); + TPackageState temp; + + //Getting the total package size from database. + iDatabase->OpenDBL(); + temp = iDatabase->GetStateL(aPkgId); + iDatabase->CloseAndCommitDB(); + + FLOG(_L("fota state for given pkg id is = %d"),temp.iState); + if (temp.iState == RFotaEngineSession::EDownloadProgressing + || temp.iState == RFotaEngineSession::EDownloadProgressingWithResume + || temp.iState == RFotaEngineSession::EDownloadComplete + || temp.iState == RFotaEngineSession::EStartingUpdate) + { + aTotalSize = temp.iPkgSize; + //Getting the downloaded update package size from storage pluggin. + StoragePluginL()->GetDownloadedUpdatePackageSizeL(aPkgId, aDownloadedSize); + } + else + { + FLOG(_L("No progressing/suspended/completed download corresponding to the given pkgid (%d)"),aPkgId); + User::Leave (KErrNotFound); + } + + + FLOG(_L("CFotaServer::GetDownloadUpdatePackageSize, aDownloadedSize = %d, aTotalSize = %d <<"),aDownloadedSize, aTotalSize); + } + +// -------------------------------------------------------------------------- +// CFotaServer::TryResumeDownloadL +// Tries to resume the download operation +// -------------------------------------------------------------------------- +// +void CFotaServer::TryResumeDownloadL(TBool aUserInitiated) + { + FLOG(_L("CFotaServer::TryResumeDownloadL, aUserInitiated = %d >>"),aUserInitiated); + //Check whether there is a paused resume actually. + if(aUserInitiated) + iUserResume = ETrue; + else + iUserResume = EFalse; + TPackageState temp = GetStateL(-1); //Gets the state of the current/last fota download + iSessMode = temp.iSessionType; + FLOG(_L("iSessMode = %d ,temp.iSessionType=%d "),iSessMode, + temp.iSessionType); + if ( temp.iState != RFotaEngineSession::EDownloadProgressingWithResume ) + { + FLOG(_L("There are no paused downloads currently; hence leaving with KErrNotFound...")); + User::Leave (KErrNotFound); + } + + //Resume download now + if(!iDownloader) + { + FLOG(_L("Creating new idownloader")); + iDownloader = CFotaDownload::NewL( this ); + } + if (iDownloader->IsDownloadActive()) + { + FLOG(_L("Another download is already active, hence returning...")); + User::Leave (KErrAlreadyExists); + } + iDownloader->iDLState = temp; + SetStartupReason(EFotaDownloadInterrupted); + iDownloader->TryResumeDownloadL(aUserInitiated); + + FLOG(_L("CFotaServer::TryResumeDownloadL <<")); + } + +// -------------------------------------------------------------------------- +// CFotaServer::InvokeFmsL +// Starts Fota Monitory Service with relevant parameters for monitoring. +// -------------------------------------------------------------------------- +// +void CFotaServer::InvokeFmsL() + { + FLOG(_L("CFotaServer::InvokeFmsL >>")); + //Collect all information needed to invoke FMS. + TPackageState temp = GetStateL(iDownloader->iDLState.iPkgId); + FLOG(_L("State as recorded in fota db:")); + FLOG(_L("iPkgId = %d"),temp.iPkgId); + FLOG(_L("iProfileId = %d"),temp.iProfileId); + FLOG(_L("iPkgName = %S"),&temp.iPkgName); + FLOG(_L("iPkgVersion = %S"),&temp.iPkgVersion); + FLOG(_L("iSendAlert = %d"),temp.iSendAlert); + FLOG(_L("iIapId = %d"),temp.iIapId); + FLOG(_L("iPkgSize = %d"),temp.iPkgSize); + FLOG(_L("iSessionType = %d"),temp.iSessionType); + FLOG(_L("iState = %d"),temp.iState); + FLOG(_L("iResult = %d"),temp.iResult); + + + //Finding the reason for download interrupt + TOmaDLInterruptReason reason (EGeneralInterrupt); // 3 + + switch (iDownloader->iDLState.iResult) + { + case RFotaEngineSession::EResUserCancelled: + { + reason = EUserInterrupt; //0 + break; + } + case RFotaEngineSession::EResDLFailDueToNWIssues: + { + reason = ENetworkInterrupt; //1 + break; + } + case RFotaEngineSession::EResDLFailDueToDeviceOOM: + { + reason = EMemoryInterrupt; //2 + break; + } + default: + { + //reason is already EGeneralInterrupt + break; + } + } + //FotaState has the last successfully worked IAP. Hence use this for FMS monitoring. +// TInt apid = iDownloader->iDLState.iIapId; + TInt apid = temp.iIapId; + + //Finding the drive number + TBuf8 path8; + path8.Zero(); + StoragePluginL()->GetUpdatePackageLocationL(iDownloader->iDLState.iPkgId, path8); + TPath path16; + path16.Copy(path8); + + + TInt drive (EDriveC ); //Default drive is Phone Memory + TParse p; + if (!p.Set(path16,NULL,NULL)) + { + TDriveName drivename(p.Drive()); + TDriveUnit driveunit(drivename); + if (iFs.IsValidDrive((TInt) driveunit)) + drive = driveunit; + } + else + { + FLOG(_L("Error while parsing for drive number! defaulting to Phone Memory (C)")); + } + + TInt dlsize, tsize; + GetDownloadUpdatePackageSizeL(iDownloader->iDLState.iPkgId, dlsize, tsize); + TInt neededsize = tsize - dlsize; + FLOG(_L("Launching FMS with params... reason = %d, iapid = %d, drive = %d, neededsize = %d"),reason, apid, drive, neededsize); + iFMSClient.OpenL(); + iFMSClient.NotifyForResumeL( reason, apid, (TDriveNumber)drive, neededsize ); + iFMSClient.Close(); + + FLOG(_L("CFotaServer::InvokeFmsL <<")); + } + +// -------------------------------------------------------------------------- +// CFotaServer::CancelFmsL +// Cancels any outstanding monitoring requests in Fota Monitory Service +// -------------------------------------------------------------------------- +// +void CFotaServer::CancelFmsL() + { + FLOG(_L("CFotaServer::CancelFmsL >>")); + + iFMSClient.OpenL(); + iFMSClient.CancelNotifyForResume(); + iFMSClient.Close(); + + FLOG(_L("CFotaServer::CancelFmsL <<")); + } + +// -------------------------------------------------------------------------- +// CFotaServer::SetStartupReason +// Sets the startup reason for Fota. This is used in Fota Startup pluggin. +// -------------------------------------------------------------------------- +// +void CFotaServer::SetStartupReason(TInt aReason) + { + FLOG(_L("CFotaServer::SetStartupReason, aReason = %d >>"), aReason); + + CRepository* centrep = NULL; + TRAPD( err, centrep = CRepository::NewL( KCRUidFotaServer ) ) + if (err==KErrNone ) + { + centrep->Set( KFotaUpdateState, aReason ); + } + delete centrep; + centrep = NULL; + + FLOG(_L("CFotaServer::SetStartupReason <<")); + } + +// -------------------------------------------------------------------------- +// CFotaServer::~CFotaServer() +// Frees database, download, chunk, filewriter, etc resources +// -------------------------------------------------------------------------- +// +CFotaServer::~CFotaServer() + { + FLOG(_L("CFotaServer::~CFotaServer >>")); + + if(iDatabase) + { + iDatabase->CloseAndCommitDB(); + delete iDatabase; + iDatabase = NULL; + } + + if(iDownloader) + { + iDownloader->Cancel(); + delete iDownloader; + iDownloader = NULL; + } + + if(iUpdater) + { + iUpdater->Cancel(); + delete iUpdater; + iUpdater = NULL; + } + + if(iDownloadFinalizer) + { + iDownloadFinalizer->Cancel(); + delete iDownloadFinalizer; + iDownloadFinalizer = NULL; + } + + if(iUpdateFinalizer) + { + iUpdateFinalizer->Cancel(); + delete iUpdateFinalizer; + iUpdateFinalizer = NULL; + } + + if ( iTimedExecuteResultFile ) + { + iTimedExecuteResultFile->Cancel(); + delete iTimedExecuteResultFile; + iTimedExecuteResultFile = NULL; + } + + if ( iAppShutter ) + { + iAppShutter->Cancel(); + delete iAppShutter; + iAppShutter=NULL; + } + + if ( iMonitor ) + { + delete iMonitor; + iMonitor = NULL; + } + //don't delete iEikEnv, fw will take care. + if (iChunk.Handle()) + iChunk.Close(); + + if (iStorageStream) { + TRAP_IGNORE(iStorageStream->CommitL()); + iStorageStream->Close(); + iStorageStream = NULL; + } + iSyncMLSession.Close(); + TRAP_IGNORE( UnLoadStoragePluginL () ); + iFs.Close(); + + + if (iFMSClient.Handle()) + iFMSClient.Close(); + + if ( iNotifHandler ) + { + iNotifHandler->Cancel(); + delete iNotifHandler; + } + TInt err = RProperty::Delete(TUid::Uid(KFotaServerUid), + KFotaLrgObjDl); + FLOG( _L( "CFotaServer::~CFotaServer err for KFotaLrgObjDl is %d " ),err ); + err = RProperty::Delete(TUid::Uid(KFotaServerUid), + KFotaLrgObjDl); + FLOG( _L( "CFotaServer::~CFotaServer err for KFotaLrgObjProfileId is %d " ),err ); + err = RProperty::Delete(TUid::Uid(KFotaServerUid), + KFotaLrgObjProfileId); + + if (iDEController) + { + delete iDEController; + iDEController = NULL; + } + + FLOG(_L("CFotaServer::~CFotaServer <<")); + } + + +// --------------------------------------------------------------------------- +// CFotaServer::UpdatePackageDownloadCompleteL +// Sets state and package streaming related objects. If this is child +// fotaserver (not largeobject), don't set state since parent fotaserver does +// it. +// --------------------------------------------------------------------------- +void CFotaServer::UpdatePackageDownloadCompleteL(TBool aLargObj + , const TInt aPkgId) + { + FLOG(_L("CFotaServer::UpdatePackageDownloadCompleteL %d >>"),aPkgId); + TInt pkgid(aPkgId); + + // Set state in case of lrg obj download + // If not lrg ob download, calling app sets state + if (aLargObj) + { + TPackageState s; + s.iPkgId = aPkgId; + s.iState = RFotaEngineSession::EStartingUpdate; + iDatabase->OpenDBL(); + iDatabase->SetStateL( s,KNullDesC8,EFDBState ); + iDatabase->CloseAndCommitDB(); + //To refresh in DM UI for OMA DM large object + TInt err = RProperty::Define( TUid::Uid(KOmaDMAppUid), + KFotaDMRefresh, + RProperty::EInt,KReadPolicy,KWritePolicy); + FLOG(_L("CFotaServer::UpdatePackageDownloadCompleteL KFotaDMRefresh Define, err = %d") + , err); + if (err != KErrAlreadyExists && err != KErrNone) + { + User::LeaveIfError(err); + } + //notify DM UI, EFalse indicates no Download going on + err = RProperty::Set( TUid::Uid(KOmaDMAppUid), + KFotaDMRefresh, + EFalse ); + FLOG(_L("RProperty KFotaDMRefresh Set ETrue, err = %d"), err); + } + // Free resources + iChunk.Close(); + iStorage->UpdatePackageDownloadCompleteL(pkgid); + FLOG(_L("CFotaServer::UpdatePackageDownloadCompleteL %d <<"),aPkgId); + } + + +// --------------------------------------------------------------------------- +// CFotaServer::DeletePackageL +// Deletes update package from db +// --------------------------------------------------------------------------- +void CFotaServer::DeletePackageL ( const TInt aPkgId) + { + FLOG(_L("CFotaServer::DeletePackageL >> id %d"),aPkgId ); + // TInt err; + + StoragePluginL()->DeleteUpdatePackageL ( aPkgId ); +// User::LeaveIfError( err ); + FLOG(_L("CFotaServer::DeletePackageL <<") ); + } + + +// --------------------------------------------------------------------------- +// CFotaServer::DownloadL +// Create package downloader and download update package. +// --------------------------------------------------------------------------- +void CFotaServer::DownloadL(TDownloadIPCParams aParams, const TDesC8& aPkgURL) + { + FLOG(_L("[FotaServer] Download >>")); + + // If download already in progress, delete it + if ( iDownloader ) + { + FLOG(_L("CFotaServer::DownloadL already downloading!")); + User::Leave (KErrAlreadyExists); + } + + if(!iDownloader) + { + iDownloader = CFotaDownload::NewL( this ); + } + + TBuf temp; + if (GetSoftwareVersion(temp) == KErrNone) + { + + RFileWriteStream wstr; + CleanupClosePushL ( wstr ); + TInt err1=wstr.Replace( iFs,KSWversionFile, EFileWrite ); + if(err1==KErrNone) + { + HBufC16* swv; + swv = HBufC16::NewLC ( temp.Length() ); + swv->Des().Copy( temp ); + wstr.WriteInt16L( swv->Des().Length()); // length + wstr.WriteL( swv->Des() ); + wstr.WriteInt16L( 0 ); + CleanupStack::PopAndDestroy( swv ); + + } + + CleanupStack::PopAndDestroy( &wstr ); // wstr + } + + iDownloader->DownloadL(aParams,aPkgURL,EFalse); + FLOG(_L("[FotaServer] Download <<")); + } + + +// -------------------------------------------------------------------------- +// CFotaServer::DownloadAndUpdateL +// Downloads update package and updates fw +// -------------------------------------------------------------------------- +// +void CFotaServer::DownloadAndUpdateL(TDownloadIPCParams aParams + ,const TDesC8& aPkgURL) + { + FLOG(_L("CFotaServer::DownloadAndUpdateL >>")); + + // If download already in progress, delete it + if ( iDownloader ) + { + FLOG(_L("CFotaServer::DownloadAndUpdateL already downloading!")); + User::Leave (KErrAlreadyExists); + } + if (!iDownloader) + { + iDownloader = CFotaDownload::NewL(this); + } + TBuf temp; + if (GetSoftwareVersion(temp) == KErrNone) + { + RFileWriteStream wstr; + CleanupClosePushL ( wstr ); + TInt err = wstr.Replace( iFs ,KSWversionFile, EFileWrite ); + if(err ==KErrNone) + { + HBufC16* swv; + swv = HBufC16::NewLC ( temp.Length( ) ); + swv->Des().Copy( temp ); + wstr.WriteInt16L( swv->Des().Length()); // length + wstr.WriteL( swv->Des() ); + wstr.WriteInt16L( 0 ); + CleanupStack::PopAndDestroy( swv ); + + } + + CleanupStack::PopAndDestroy( &wstr ); // wstr + + } + iDownloader->DownloadL( aParams,aPkgURL,ETrue ); + FLOG(_L("CFotaServer::DownloadAndUpdateL <<")); + } + +// -------------------------------------------------------------------------- +// CFotaServer::UpdateL +// Start update +// -------------------------------------------------------------------------- +// +void CFotaServer::UpdateL( const TDownloadIPCParams &aParams ) + { + FLOG(_L("CFotaServer::UpdateL >>")); + + TBool isPkgvalid(ETrue); + isPkgvalid = CheckSWVersionL(); + + if (isPkgvalid) + { + + FLOG(_L("CFotaServer::UpdateL package is valid >>")); + if(!iUpdater) + { + iUpdater = CFotaUpdate::NewL(this); + } + iUpdater->StartUpdateL( aParams ); + } + else + { + FLOG(_L("IMPORTANT:: Firmware version mismatch! Resetting fota state")); + ResetFotaStateL(aParams); + } + + FLOG(_L("CFotaServer::UpdateL <<")); + } + + + +// -------------------------------------------------------------------------- +// CFotaServer::CheckSWVersionL +// Check the s/w version +// -------------------------------------------------------------------------- +// + +TBool CFotaServer::CheckSWVersionL() + +{ + + + FLOG(_L("CFotaServer::CheckSWVersionL >>")); + TBuf temp; + HBufC16* message16=NULL; + TBool isPkgvalid(ETrue); + if (GetSoftwareVersion(temp) == KErrNone) + { + + //TBufswvfromfile; + //Fetch the software version ... + RFileReadStream rstr; + TInt err1=rstr.Open(iFs,KSWversionFile ,EFileRead); + if(err1== KErrNone) + { + CleanupClosePushL( rstr ); + TInt msglen = rstr.ReadInt16L(); + if(msglen > 0) + { + message16 = HBufC16::NewLC(msglen + 1); + TPtr16 tempswv = message16->Des(); + TRAPD(err, rstr.ReadL(tempswv,msglen )); + + if ( err != KErrNone && err != KErrEof) + { + FLOG(_L(" file read err %d"),err); //User::Leave( err ); + msglen =0; + } + else + { + FLOG(_L(" msglen %d"),msglen); + TPtr swvfromfile = message16->Des(); + + FLOG(_L(" swvfromfile=%S"),message16); + + //Compare the software versions to decide whether the download is still valid or not. + if (msglen != temp.Length() || temp.Compare(tempswv)!=KErrNone) + { + isPkgvalid = EFalse; + FLOG(_L("CFotaServer::software not matching >>")); + + } + } + + CleanupStack::PopAndDestroy( message16 ); + } + CleanupStack::PopAndDestroy( &rstr ); + + + } + + } + + FLOG(_L("CFotaServer::CheckSWVersionL <<")); + return isPkgvalid; + + +} + + +// -------------------------------------------------------------------------- +// CFotaServer::ScheduledUpdateL +// Update, triggered by scheduler +// -------------------------------------------------------------------------- +void CFotaServer::ScheduledUpdateL( TFotaScheduledUpdate aUpdate ) + { + FLOG(_L("CFotaServer::ScheduledUpdateL")); + TPackageState s = GetStateL( aUpdate.iPkgId ); + + // If update is in progress, do not start new one (multiple popups) + if ( iUpdater ) + { + FLOG(_L("\t\tupdate in progress")); + return; + } + else + { + + //Check to find whether the user has already installed the package before the + //reminder could expire + + RFs aRfs; + RDir aDir; + TEntryArray anArray; + User::LeaveIfError(aRfs.Connect()); + + + TBuf16 temp; + temp.Zero(); + temp.Copy(KSwupdPath8); + + if(aDir.Open(aRfs,temp,KEntryAttNormal)==KErrNone) + { + TInt error = aDir.Read(anArray); + } + aDir.Close(); + aRfs.Close(); + + temp.Zero(); + temp.Copy(KSwupdFileExt8); + + TBool aStartUpdate(EFalse); + + for (TInt i=0; iStartUpdateL( s ); + } + else + { + FLOG(_L("\t\tReminder expired, but no update package is found on dir; skipping")); + } + } + } + +// -------------------------------------------------------------------------- +// CFotaServer::DoConnect +// From CServer2. Initializes class members. +// -------------------------------------------------------------------------- +void CFotaServer::DoConnect(const RMessage2 &aMessage) + { + FLOG(_L("CFotaServer::DoConnect(const RMessage2 &aMessage) >>") ); + + // In case shutdown is in progress, cancel it. + if ( iAppShutter ) + { + iAppShutter->Cancel(); + delete iAppShutter; + iAppShutter=NULL; + } + + if ( iInitialized == EFalse ) + { + TRAPD( err, ClientAwareConstructL( aMessage ) ); + if ( err ) FLOG(_L(" ClientAwareConstructL err %d"),err); + } + + CAknAppServer::DoConnect( aMessage ); + FLOG(_L("CFotaServer::DoConnect(const RMessage2 &aMessage) <<")); + } + + +// -------------------------------------------------------------------------- +// CFotaServer::GetStateL +// Get state of a download package +// -------------------------------------------------------------------------- +TPackageState CFotaServer::GetStateL( const TInt aPkgId) + { + TPackageState s=RFotaEngineSession::EIdle; + + if (aPkgId >= 0) // Used by all clients + { + iDatabase->OpenDBL(); + s = iDatabase->GetStateL( aPkgId ); + iDatabase->CloseAndCommitDB(); + } + else if (aPkgId == -2) //Used by DM UI to check if fota ui has to be in foreground + { + TBool value (EFalse); + /** This P&S Key is used to notify DM UI on any download event. key=0 for idle and key=1 for download */ + TInt err = RProperty::Get(TUid::Uid(KOmaDMAppUid), + KFotaDMRefresh, + value); + FLOG(_L("RProperty KFotaDMRefresh Get, err = %d, val = %d"), err,value); + if (err==KErrNone && value) + { + FLOG(_L("Ongoing download operation detected!")); + s=RFotaEngineSession::EDownloadProgressing; + } + } + else if ( aPkgId == -1) //Used by DM UI to get the state of last fota operation + { + //Read status from fotastate last entry + + iDatabase->OpenDBL(); + + RArray states; + CleanupClosePushL (states); + iDatabase->GetAllL ( states ); + // Loop states. + for(TInt i = 0; i < states.Count(); ++i ) + { + TPackageState tmp; + tmp = iDatabase->GetStateL( states[i] ); + FLOG(_L("***Package: %d, State = %d"),states[i],(TInt) tmp.iState); + if (tmp.iState!=RFotaEngineSession::EIdle) + { + s=tmp; + } + } + FLOG(_L("Status of current operation is %d"),(TInt)s.iState); + + CleanupStack::PopAndDestroy( &states ); + iDatabase->CloseAndCommitDB(); + } + return s; + } + + +// -------------------------------------------------------------------------- +// CFotaServer::IsPackageStoreSizeAvailable +// Checks if update package fits into storage +// -------------------------------------------------------------------------- +// +TBool CFotaServer::IsPackageStoreSizeAvailableL ( const TInt aSize) + { + FLOG(_L("CFotaServer::IsPackageStoreSizeAvailableL >>")); + TInt size=aSize; + + // Write content size for later use (flexible memory usage) + RFileWriteStream str; + TUint32 size2 = aSize; + User::LeaveIfError(str.Replace(iFs, KSizePass, EFileWrite)); + CleanupClosePushL(str); + str.WriteUint32L(size2); + CleanupStack::PopAndDestroy(1); + + + CFotaStorage::TFreeSpace avail = StoragePluginL()->IsPackageStoreSizeAvailableL(size); + FLOG(_L("CFotaServer::IsPackageStoreSizeAvailableL <<")); + return avail==CFotaStorage::EDoesntFitToFileSystem ? EFalse : ETrue; + } + +// -------------------------------------------------------------------------- +// CFotaServer::OnSyncMLSessionEvent +// -------------------------------------------------------------------------- +// +void CFotaServer::OnSyncMLSessionEvent(TEvent aEvent, TInt aIdentifier + , TInt aError, TInt /*aAdditionalData*/) + { + if ( iSyncJobId != aIdentifier ) return; + FLOG(_L("CFotaServer::OnSyncMLSessionEvent %d err:%d (id %d==%d?)") + , aEvent,aError,aIdentifier,iSyncJobId); + + if ( iSyncJobId == aIdentifier ) + { + TTimeIntervalMicroSeconds32 close(0); + TBool end ( EFalse ); + switch( aEvent ) + { + //EJobStart = 0 + case EJobStartFailed: // 1 E + { + end = ETrue; + } + break; + case EJobStop: // 2 E + { + end = ETrue; + // Sync ok => do not try anymore + if ( aError == KErrNone ) + { + iSyncMLAttempts=0; + } + } + break; + case EJobRejected: // 3 E + { + end = ETrue; + } + break; + // ETransportTimeout , // 7 + default: + { + } + break; + } + + + // sml session OK,close it + if ( end && iSyncMLAttempts == 0 ) + { + FLOG(_L(" Sml OK, scheduling close")); + if( aError == KErrNone ) //always ask session successful + { + TInt val = KErrNotFound; + TInt err1 = RProperty::Get( TUid::Uid(KFotaServerUid), + KFotaLrgObjDl, val ); + FLOG( _L( "CFotaSrvDocument::OnSyncMLSessionEvent KFotaLrgObjDl val & err is %d, %d" ) + ,val,err1 ); + if( val == EOmaDmLrgObjDlFail ) //if large object + { + err1 = RProperty::Set( TUid::Uid(KFotaServerUid), + KFotaLrgObjDl, KErrNotFound ); + FLOG( _L( "CFotaSrvDocument::OnSyncMLSessionEvent err for KFotaLrgObjDl is %d" ) + ,err1 ); + err1 = RProperty::Set( TUid::Uid(KFotaServerUid), + KFotaLrgObjProfileId, KErrNotFound ); + FLOG( _L( "CFotaSrvDocument::OnSyncMLSessionEvent err for KFotaLrgObjProfileId is %d") + ,err1 ); + FLOG( _L( "[FotaServer] CFotaSrvDocument::OnSyncMLSessionEvent pkgid is %d" ) + ,iStorageDownloadPackageId ); + TRAP_IGNORE(GenericAlertSentL( iStorageDownloadPackageId )); + } + } + close = TTimeIntervalMicroSeconds32( 100000 ); + } + // sml session NOK, retry + if ( end && iSyncMLAttempts>0) + { + FLOG(_L(" Sml OK, scheduling retry")); + close = TTimeIntervalMicroSeconds32( KSyncmlSessionRetryInterval); + } + + if ( close > TTimeIntervalMicroSeconds32(0) ) + { + if ( iTimedSMLSessionClose ) + { + FLOG(_L(" closing smlsession timer")); + iTimedSMLSessionClose->Cancel(); + delete iTimedSMLSessionClose; + iTimedSMLSessionClose = NULL; + } + FLOG(_L(" starting smlsession timer")); + TRAPD( err2, iTimedSMLSessionClose = CPeriodic::NewL (EPriorityNormal) ); + if ( !err2 ) + { + iTimedSMLSessionClose->Start ( + close + , TTimeIntervalMicroSeconds32( KSyncmlSessionRetryInterval ) + , TCallBack( StaticDoCloseSMLSession,this ) ) ; + } + else FLOG(_L(" iTimedSMLSessionClose err %d"),err2); + } + } + } + + +// -------------------------------------------------------------------------- +// CFotaServer::TryToShutDownFotaServer() +// Try to shut down. After last client left, this is tried periodically. +// -------------------------------------------------------------------------- +// +TInt CFotaServer::TryToShutDownFotaServer() + { + RProcess pr; TFullName fn = pr.FullName(); TUint prid = pr.Id(); + FLOG(_L( "CFotaServer::TryToShutDownFotaServer process(id %d)%S. this 0x%x") + ,prid,&fn,this); + FLOG(_L("CFotaServer::TryToShutDownFotaServer()")); + FLOG(_L("iSessMode:%d,iUserResume:%d,iNeedToClose:%d"),iSessMode, + iUserResume,iNeedToClose); + TBool val (EFalse); + if (iNotifHandler) + val = iNotifHandler->IsOpen(); + if( !iDownloader && !iUpdater && !iTimedExecuteResultFile + && !iSyncMLSession.Handle() && !iRetryingGASend && !val + && !( iDownloader + && iDownloader->IsDownloadActive() && iUserResume == EFalse /*FMS*/ + && !iNeedToClose )) + { + + FLOG(_L(" shutting down fotaserver")); + if (iDownloader && iDownloader->IsDownloadActive() ) + { + FLOG(_L("Shutting down active in TryToShutDownFotaServer...")); + StopDownload(RFotaEngineSession::EResUndefinedError); + } + CAknAppServer::HandleAllClientsClosed(); + return 1; + } + else + { + FLOG(_L(" shutdownwait:%d.%d.%d.%d.%d"), iDownloader,iUpdater + , iTimedExecuteResultFile,iSyncMLSession.Handle(),val); + } + return 0; + } + + +// --------------------------------------------------------------------------- +// StaticApplicationShutter +// Intermediate function +// --------------------------------------------------------------------------- +static TInt StaticApplicationShutter(TAny *aPtr) + { + __ASSERT_ALWAYS( aPtr, User::Panic(KFotaPanic, KErrArgument) ); + CFotaServer* srv = (CFotaServer*) aPtr; + srv->TryToShutDownFotaServer(); + return KErrNone; + } + + +// --------------------------------------------------------------------------- +// CFotaServer::HandleAllClientsClosed() +// Tries to shut down fotaserver. If unsuccesfull, periodically try it again +// and again and again ... +// --------------------------------------------------------------------------- +void CFotaServer::HandleAllClientsClosed() + { + FLOG(_L("CFotaServer::HandleAllClientsClosed() >>")); + + if ( TryToShutDownFotaServer() == 0) + { + FLOG(_L(" starting application shutdown" )); + if ( iAppShutter ) + { + iAppShutter->Cancel(); + delete iAppShutter; + iAppShutter=NULL; + } + TRAPD ( err , iAppShutter = CPeriodic::NewL (EPriorityNormal) ); + __ASSERT_ALWAYS( err == KErrNone , User::Panic(KFotaPanic, err) ); + FLOG(_L("iSessMode = %d iUserResume:%d,iNeedToClose:%d"), + iSessMode,iUserResume,iNeedToClose); + if (iDownloader && iDownloader->IsDownloadActive() && + !(iUserResume == EFalse /*FMS*/ + && !iNeedToClose ) ) + { + FLOG(_L("Shutting down active...")); + StopDownload(RFotaEngineSession::EResUndefinedError); + } + + iAppShutter->Start( KFotaTimeShutDown , KFotaTimeShutDown + , TCallBack(StaticApplicationShutter,this) ) ; + } + + FLOG(_L("CFotaServer::HandleAllClientsClosed() <<")); + } + +// -------------------------------------------------------------------------- +// CFotaServer::GetUpdateTimeStampL +// Gets time of last update. It is stored in a file. +// -------------------------------------------------------------------------- +void CFotaServer::GetUpdateTimeStampL (TDes16& aTime) + { + FLOG(_L("CFotaServer::GetUpdateTimeStampL >>")); + TInt err; + + RFileReadStream rstr; + err = rstr.Open( iFs, _L("updatetimestamp"), EFileRead ); + + if ( err == KErrNone) + { + FLOG(_L(" update time stamp file found,reading")); + CleanupClosePushL (rstr); + TInt year = rstr.ReadInt32L(); + TInt month = rstr.ReadInt32L(); + TInt day = rstr.ReadInt32L(); + TInt hour = rstr.ReadInt32L(); + TInt minute = rstr.ReadInt32L(); + TInt year16 = year; + TInt month16 = month; + TInt day16 = day; + TInt hour16 = hour; + TInt minute16 = minute; + CleanupStack::PopAndDestroy( &rstr ); + aTime.Append (year16); + aTime.Append (month16); + aTime.Append (day16); + aTime.Append (hour16); + aTime.Append (minute16); + } + else if ( err != KErrNotFound ) + { + User::Leave ( err ); + } + + if ( err == KErrNotFound ) + { + FLOG(_L(" update time stamp not found ")); + } + + FLOG(_L("CFotaServer::GetUpdateTimeStampL <<")); + } + +// -------------------------------------------------------------------------- +// CFotaServer::GetUpdatePackageIdsL +// -------------------------------------------------------------------------- +// +void CFotaServer::GetUpdatePackageIdsL(TDes16& aPackageIdList) + { + FLOG(_L("CFotaServer::GetUpdatePackageIdsL()")); + StoragePluginL()->GetUpdatePackageIdsL( aPackageIdList ); + } + + + +// -------------------------------------------------------------------------- +// CFotaServer::GenericAlertSentL +// Generic alert sent, do cleanup. FUMO spec specifies cleanup need to have +// for states 20,70,80,90,100. Called by syncml framework when it has sent +// generic alert +// -------------------------------------------------------------------------- +// +void CFotaServer::GenericAlertSentL( const TInt aPackageID ) + { + FLOG(_L("CFotaServer::GenericAlertSentL %d"), aPackageID); + TPackageState state; + TBool toidle(EFalse); + TBool deletepkg(EFalse); + + iDatabase->OpenDBL(); + state = iDatabase->GetStateL( aPackageID ); + + switch( state.iState ) + { + case RFotaEngineSession::EDownloadFailed: + { + toidle = ETrue; + deletepkg = ETrue; + } + break; + case RFotaEngineSession::EUpdateFailed: + { + toidle = ETrue; + deletepkg = ETrue; + } + break; + case RFotaEngineSession::EUpdateFailedNoData: + { + toidle = ETrue; + } + break; + case RFotaEngineSession::EUpdateSuccessful: + { + toidle = ETrue; + deletepkg = ETrue; + } + break; + case RFotaEngineSession::EUpdateSuccessfulNoData: + { + toidle = ETrue; + } + break; + case RFotaEngineSession::EDownloadComplete: + { + state.iState = RFotaEngineSession::EStartingUpdate; + state.iResult = KErrNotFound; + iDatabase->SetStateL( state,KNullDesC8, EFDBState ); + toidle = EFalse; + } + break; + default: + { + FLOG(_L(" pkg %d (state:%d) doesnt need cleanup"), aPackageID + ,state.iState ); + } + break; + } + + if ( toidle ) + { + state.iState = RFotaEngineSession::EIdle; + state.iResult = KErrNotFound; + iDatabase->SetStateL( state,KNullDesC8, EFDBState|EFDBResult ); + DeleteFUMOTreeL(); + } + + + SetStartupReason(EFotaDefault); + + iDatabase->CloseAndCommitDB(); + + if ( deletepkg ) + { + StoragePluginL()->DeleteUpdatePackageL( aPackageID ); + } + + // this should already be done when user was notified + // about update result + DoDeleteUpdateResultFileL(); + } + +// -------------------------------------------------------------------------- +// CFotaServer::DoDeleteUpdateResultFileL +// Deletes the update resule file +// -------------------------------------------------------------------------- +void CFotaServer::DoDeleteUpdateResultFileL() + { + CFotaUpdate::DeleteUpdateResultFileL( iFs ); + } + +// -------------------------------------------------------------------------- +// CFotaServer::CreateServiceL +// Creates session object +// -------------------------------------------------------------------------- +CApaAppServiceBase* CFotaServer::CreateServiceL( TUid aServiceType ) const + { + FLOG(_L( "CFotaServer::CreateServiceL 0x%x " ), aServiceType.iUid ); + if ( aServiceType.iUid == KFotaServiceUid ) + { + return ((CApaAppServiceBase*) (new (ELeave) CFotaSrvSession)); + } + else + { + return CAknAppServer::CreateServiceL ( aServiceType ); + } + } + +// -------------------------------------------------------------------------- +// CFotaServer::GetEikEnv +// Gets the EikonEnv object +// -------------------------------------------------------------------------- +CEikonEnv* CFotaServer::GetEikEnv() + { + return iEikEnv; + } + +// -------------------------------------------------------------------------- +// CFotaServer::StartNetworkMonitorL +// Starts Network Monitoring operation for defined interval and retries (FotaNetworkRegMonitor.h) +// -------------------------------------------------------------------------- +void CFotaServer::StartNetworkMonitorL() + { + FLOG(_L("CFotaServer::StartNetworkMonitorL >>")); + if (!iMonitor) + iMonitor = CFotaNetworkRegStatus::NewL (this); + iMonitor->StartMonitoringL(); + + FLOG(_L("CFotaServer::StartNetworkMonitorL <<")); + } + +// -------------------------------------------------------------------------- +// CFotaServer::ReportNetworkStatus +// called by CFotaNetworkRegStatus for reporting status +// -------------------------------------------------------------------------- +void CFotaServer::ReportNetworkStatus(TBool status) + { + FLOG(_L("CFotaServer::ReportNetworkStatus, status = %d >>"),status); + iRetryingGASend = EFalse; + iNetworkAvailable = status; + + if (iNetworkAvailable) + { + TRAPD (err, CreateDeviceManagementSessionL (iStoredState)); + if (err!=KErrNone) + { + FLOG(_L("Error %d occured while sending GA after retries"),err); + } + } + //No need of iMonitor anymore + if ( iMonitor ) + { + delete iMonitor; + iMonitor = NULL; + } + + FLOG(_L("CFotaServer::ReportNetworkStatus >>")); + } + +// -------------------------------------------------------------------------- +// CFotaServer::ShutApp +// Shuts the DM App ui. This is used when End key is pressed during fota operation. +// -------------------------------------------------------------------------- +// +void CFotaServer::ShutApp() + { + FLOG(_L("CFotaServer::ShutApp >>")); + FLOG(_L("Ending DM UI....")); + TApaTaskList taskList(GetEikEnv()->WsSession()); + TApaTask task=taskList.FindApp(TUid::Uid(KOmaDMAppUid)); + if(task.Exists()) + { + task.EndTask(); + } + FLOG(_L("CFotaServer::ShutApp <<")); + } + +// -------------------------------------------------------------------------- +// CFotaServer::StopDownload +// Stops any ongoing download operation. Depending on the property of download, the later is either paused +// or cancelled. +// -------------------------------------------------------------------------- +// +void CFotaServer::StopDownload(TInt aReason) + { + FLOG(_L("CFotaServer::StopDownload, aReason = %d >>"), aReason); + iUserResume = KErrNotFound; + iSessMode = KErrNotFound; + if (iDownloader) + { + FLOG(_L("stopping fota download")); + iNeedToClose = EFalse; + if (iDownloader->IsDownloadResumable()) + { + TRAP_IGNORE(iDownloader->RunDownloadSuspendL(aReason)); + } + else + { + TRAP_IGNORE(iDownloader->RunDownloadCancelL(aReason)); + } + } + FLOG(_L("CFotaServer::StopDownload <<")); + } + +// -------------------------------------------------------------------------- +// CFotaServer::UpdateDBdataL +// For OMA DM large object download failure, this method updates the database +// and sends the generic alert. +// -------------------------------------------------------------------------- +// +void CFotaServer::UpdateDBdataL() + { + TInt val(KErrNotFound),UserCancel(KErrNotFound); + TInt err = RProperty::Get( TUid::Uid(KFotaServerUid), + KFotaLrgObjDl, val); + FLOG(_L("CFotaServer::UpdateDBdata KFotaLrgObjDl value & err is %d, %d "),val,err); + //val = 1 means LrgObj Download & its failed , -1 means not lrg object download / stream commited + if( val == EOmaDmLrgObjDlFail ) + { + err = RProperty::Get( TUid::Uid(KOmaDMAppUid), + KDmJobCancel, UserCancel); + FLOG(_L("CFotaServer::UpdateDBdataL KDmJobCancel value & err is %d, %d "),UserCancel,err); + if( UserCancel == KErrCancel ) + { + TInt ProfId(KErrNotFound); + err = RProperty::Get( TUid::Uid(KFotaServerUid), + KFotaLrgObjProfileId, ProfId); + FLOG(_L("CFotaServer::UpdateDBdataL KFotaLrgObjProfileId value & err is %d, %d,pkgid is %d "), + ProfId,err,iStorageDownloadPackageId); + if(iStorageDownloadPackageId > KErrNotFound && ProfId > KErrNotFound ) + { + iDatabase->OpenDBL(); + FLOG(_L("CFotaServer::UpdateDBdataL after iDatabase->OpenDBL() ")); + TPackageState state; + state.iPkgId = iStorageDownloadPackageId; + state.iProfileId = ProfId; + state.iState = RFotaEngineSession::EDownloadFailed; + state.iResult = RFotaEngineSession::EResUserCancelled; + iDatabase->SetStateL( state,KNullDesC8, EFDBState | EFDBResult ) ; + FLOG(_L("CFotaServer::UpdateDBdataL after iDatabase->SetStateL")); + iDatabase->CloseAndCommitDB(); + FLOG(_L("CFotaServer::UpdateDBdataL after iDatabase->CloseAndCommitDB ")); + // Free resources + iChunk.Close(); + FLOG(_L("CFotaServer::UpdateDBdataL ,chunk released ")); + iStorage->UpdatePackageDownloadCompleteL(iStorageDownloadPackageId); + CreateDeviceManagementSessionL(state); + } + + } + } + } +// -------------------------------------------------------------------------- +// CFotaServer::MonitorBatteryL() +// Monitors for the battery +// +// -------------------------------------------------------------------------- +// +void CFotaServer::MonitorBattery(TInt aLevel) +{ FLOG(_L("CFotaServer::MonitorBatteryL(), level = %d >>"), aLevel); + SetStartupReason(EFotaUpdateInterrupted); + RFMSClient fmsclient; + TRAPD(err,fmsclient.OpenL()); + if(err == KErrNone) + { FLOG(_L("CFotaServer::going into FMS client side MonitorBatteryL() >>")); + //fmsclient.Cancel(); + TRAPD(err1,fmsclient.MonitorForBatteryL(aLevel)); + if(err1) + { + FLOG(_L("CFotaServer:: MonitorBatteryL() left with error %d >>"), err1); + } + fmsclient.Close(); + + } + + FLOG(_L("CFotaServer::MonitorBatteryL() <<")); + + +} + +// -------------------------------------------------------------------------- +// CFotaServer::CheckIapExistsL +// Checks for IAP Id exists or not in commsdb +// IAP Id used for resuming the download or for sending Generic alert +// -------------------------------------------------------------------------- +// +TBool CFotaServer::CheckIapExistsL(TUint32 aIapId) + { + FLOG(_L("CFotaServer::CheckIapExistsL >>")); + TBool exists = EFalse; + RCmManager cmManager; + cmManager.OpenLC(); + RCmConnectionMethod conn; + TRAPD(err, conn = cmManager.ConnectionMethodL( aIapId )); + if(err == KErrNone)//connection method exists + exists = ETrue; + conn.Close(); + CleanupStack::PopAndDestroy();//cmManager + FLOG(_L("CFotaServer::CheckIapExistsL <<")); + return exists; + } + +// -------------------------------------------------------------------------- +// CFotaServer::GetSoftwareVersion +// Gets the software version +// +// -------------------------------------------------------------------------- +// +TInt CFotaServer::GetSoftwareVersion(TDes& aVersion) + { + FLOG(_L("CFotaServer::GetSoftwareVersion >>")); + aVersion.Zero(); + + SysVersionInfo::TVersionInfoType what = SysVersionInfo::EFWVersion; + TInt error (KErrNone); + error = SysVersionInfo::GetVersionInfo(what,aVersion); + FLOG(_L("CFotaServer::GetSoftwareVersion,SwV=%S <<"),&aVersion); + return error; + } + +// -------------------------------------------------------------------------- +// CFotaServer::ResetFotaStateL +// Resets the Fotastate +// +// -------------------------------------------------------------------------- +// +void CFotaServer::ResetFotaStateL(const TDownloadIPCParams& aParams) + { + FLOG(_L("CFotaServer::ResetFotaStateL >>")); + + TPackageState state; + if (!iDatabase->IsOpen()) iDatabase->OpenDBL(); + //Fetch the software version that was before download from db. + state = iDatabase->GetStateL(aParams.iPkgId); + state.iState = RFotaEngineSession::EUpdateFailed; + state.iResult = RFotaEngineSession::EResPackageMismatch; + iDatabase->SetStateL( state,KNullDesC8, EFDBState | EFDBResult ); + iDatabase->CloseAndCommitDB(); + + StoragePluginL()->DeleteUpdatePackageL ( aParams.iPkgId ); + + CreateDeviceManagementSessionL(state); + + FLOG(_L("CFotaServer::ResetFotaStateL <<")); + } + +// -------------------------------------------------------------------------- +// CFotaServer::SetInstallUpdateClientL +// Set's who is the client triggering the update +// -------------------------------------------------------------------------- +// +void CFotaServer::SetInstallUpdateClientL(TInt aClient) + { + iInstallupdClient = aClient; + FLOG(_L("CFotaServer::SetInstallUpdateClientL() client:%d<<"),iInstallupdClient); + } + +// -------------------------------------------------------------------------- +// CFotaServer::GetInstallUpdateClientL +// returns the client who triggered the update +// -------------------------------------------------------------------------- +// +TInt CFotaServer::GetInstallUpdateClientL() + { + FLOG(_L("CFotaServer::GetInstallUpdateClientL() client:%d<<"),iInstallupdClient); + return iInstallupdClient ; + } + +// CFotaServer::NeedToDecryptL +// This method is called to check if decryption is needed. +// +// -------------------------------------------------------------------------- +// +TBool CFotaServer::NeedToDecryptL(const TInt &aPkgId, TDriveNumber &aDrive) + { + FLOG(_L("CFotaServer::NeedToDecryptL >>")); + + TBool ret (EFalse); + + //Finding the drive number + TBuf8 path8; + path8.Zero(); + StoragePluginL()->GetUpdatePackageLocationL(aPkgId, path8); + TPath path16; + path16.Copy(path8); + + + TDriveNumber drive (EDriveC ); //Default drive is Phone Memory + TParse p; + if (!p.Set(path16,NULL,NULL)) + { + TDriveName drivename(p.Drive()); + TDriveUnit driveunit(drivename); + if (iFs.IsValidDrive((TInt) driveunit)) + { + drive = (TDriveNumber) driveunit.operator TInt(); + iStorageDrive = drive; + } + } + else + { + FLOG(_L("Error while parsing for drive number! defaulting to Phone Memory (C)")); + } + FLOG(_L("Package storage drive is %d"), (TInt) drive); + + if (!iDEController) + { + TRAPD(err, iDEController = CDevEncController::NewL(this)); + if (err == KErrNotSupported) + { + //Encryption feature is not on. + return EFalse; + } + else + { + __LEAVE_IF_ERROR(err); + } + } + TRAPD(err, ret = iDEController->NeedToDecryptL(drive)); + + delete iDEController; iDEController = NULL; + + if (err == KErrNotSupported) + { + //Encryption feature is ON, but the encryption adaptation is note present. + ret = EFalse; + } + else + { + __LEAVE_IF_ERROR(err); + } + + //Set the appropriate drive when ret is true + if (ret) + { + aDrive = drive; + } + + FLOG(_L("CFotaServer::NeedToDecryptL ret = %d, drive = %d <<"), ret, drive); + return ret; + + } + +// -------------------------------------------------------------------------- +// CFotaServer::DoStartDecryptionL +// This method is called to start the decryption operation. +// +// -------------------------------------------------------------------------- +// +void CFotaServer::DoStartDecryptionL() + { + FLOG(_L("CFotaServer::DoStartDecryptionL >>")); + + if (!iDEController) + iDEController = CDevEncController::NewL(this); + + iDEController->DoStartDecryptionL(iStorageDrive); + + FLOG(_L("CFotaServer::DoStartDecryptionL <<")); + } + +// -------------------------------------------------------------------------- +// CFotaServer::HandleDecryptionCompleteL +// This method is called to when decryption operation is complete. +// +// -------------------------------------------------------------------------- +// +void CFotaServer::HandleDecryptionCompleteL(TInt aResult, TInt aValue) + { + FLOG(_L("CFotaServer::HandleDecryptionCompleteL, result = %d, value = %d >>"), aResult, aValue); + + if (aResult == KErrNone) + { + //Skip battery test as it is already performed before decryption + iUpdater->HandleUpdateAcceptStartL(ETrue); + } + else + { + FLOG(_L("Can't start update because of error %d"), aResult); + iUpdater->HandleUpdateErrorL(aResult, aValue); + } + + if (iDEController) + { + delete iDEController; iDEController = NULL; + } + + FLOG(_L("CFotaServer::HandleDecryptionCompleteL <<")); + } + + +// -------------------------------------------------------------------------- +// CFotaServer::NeedToEncryptL +// This method is called to check if encryption is needed. +// +// -------------------------------------------------------------------------- +// +TBool CFotaServer::NeedToEncryptL(TDriveNumber &aDrive) + { + FLOG(_L("CFotaServer::NeedToEncryptL >>")); + + TDriveNumber drive; + if (!iDEController) + { + TRAPD(err, iDEController = CDevEncController::NewL(this)); + if (err == KErrNotSupported) + { + return EFalse; + } + else + { + __LEAVE_IF_ERROR(err); + } + } + + TBool ret = iDEController->NeedToEncryptL(drive); + delete iDEController; iDEController = NULL; + + if (ret) + { + aDrive = drive; + iStorageDrive = drive; + } + + FLOG(_L("CFotaServer::NeedToEncryptL, ret = %d drive = %d << "), ret, aDrive); + return ret; + } + +// -------------------------------------------------------------------------- +// CFotaServer::DoStartEncryptionL +// This method is called to start the encryption operation. +// +// -------------------------------------------------------------------------- +// +void CFotaServer::DoStartEncryptionL() + { + FLOG(_L("CFotaServer::DoStartEncryptionL >>")); + + if (!iDEController) + iDEController = CDevEncController::NewL(this); + + iDEController->DoStartEncryptionL(iStorageDrive); + + FLOG(_L("CFotaServer::DoStartEncryptionL <<")); + } + +// -------------------------------------------------------------------------- +// CFotaServer::HandleEncryptionCompleteL +// This method is called when the encryption operation is complete. +// +// -------------------------------------------------------------------------- +// +void CFotaServer::HandleEncryptionCompleteL(TInt aResult, TInt aValue) + { + FLOG(_L("CFotaServer::HandleEncryptionCompleteL, result = %d, value = %d >>"), aResult, aValue); + + if (aResult == KErrNone) + { + //Do nothing + } + else + { + FLOG(_L("Can't start update because of error %d"), aResult); + iUpdater->HandleEncryptionErrorL(aResult); + } + + if (iDEController) + { + delete iDEController; iDEController = NULL; + } + + FLOG(_L("CFotaServer::HandleEncryptionCompleteL <<")); + } + + +// -------------------------------------------------------------------------- +// CFotaServer::GetDEOperation +// This method returns the device encryption operation. +// +// -------------------------------------------------------------------------- +// +TInt CFotaServer::GetDEOperation() + { + FLOG(_L("CFotaServer::GetDEOperation >>")); + TInt ret (EIdle); + + if (iDEController) + ret = iDEController->GetDEOperation(); + + FLOG(_L("CFotaServer::GetDEOperation, ret = %d <<"), ret); + return ret; + } +