--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/fotaapplication/fotaserver/FotaServer/src/FotaServer.cpp Thu Dec 17 09:07:52 2009 +0200
@@ -0,0 +1,2578 @@
+/*
+* 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 <aknenv.h>
+#include <apgtask.h>
+#include <apgwgnam.h>
+#include <schtime.h>
+#include <csch_cli.h>
+#include <e32property.h>
+#include <ApUtils.h>
+#include <commdb.h>
+#include <DevManInternalCRKeys.h>
+#include <nsmlconstants.h>
+#include <centralrepository.h>
+#include <sysversioninfo.h>
+#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<KMaxFullName> temp;
+ GetPredefinedNodeL(temp);
+ RNSmlDMCallbackSession session;
+ User::LeaveIfError(session.Connect());
+ CleanupClosePushL(session);
+
+ CBufBase *emptyList = CBufFlat::NewL(0);
+ CleanupStack::PushL(emptyList);
+ CArrayFixFlat <TSmlDmMappingInfo>* UriSegList;
+ UriSegList = new (ELeave) CArrayFixFlat <TSmlDmMappingInfo> (KGranularity);
+
+ CleanupStack::PushL(UriSegList);
+
+ session.GetUriSegListL(KNSmlFotaAdapterUid,KNSmlFumoPath,*UriSegList);
+
+ for ( TUint16 i=0;i<UriSegList->Count();i++)
+ {
+ if (temp.Length() && UriSegList->At(i).iURISeg.Find( temp ) != KErrNotFound)
+ {
+ FLOG(_L("DeleteFUMOTreeL predefined match =%S"), &temp);
+ continue;
+ }
+
+ TBuf8<KMaxFullName> 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<TSmlTransportId> 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;
+ 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<TInt> 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(KOmaDMAppUid), 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->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);
+ 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<KMaxPath> 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<KSysVersionInfoTextLength> 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<KSysVersionInfoTextLength> 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<KSysVersionInfoTextLength> temp;
+ HBufC16* message16=NULL;
+ TBool isPkgvalid(ETrue);
+ if (GetSoftwareVersion(temp) == KErrNone)
+ {
+
+ //TBuf<KSysVersionInfoTextLength>swvfromfile;
+ //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<KMaxFileName> 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; i<anArray.Count();i++)
+ {
+ if (anArray[i].iName.Find(temp)!=KErrNotFound)
+ {
+ aStartUpdate = ETrue;
+ break;
+ }
+ }
+
+ if (aStartUpdate)
+ {
+ FLOG(_L("\t\tReminder expired and update packages found on dir"));
+ iUpdater = CFotaUpdate::NewL(this);
+ iUpdater->StartUpdateL( 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<TInt> 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 >>"));
+ CCommsDatabase* commDb = CCommsDatabase::NewL( EDatabaseTypeIAP );
+ CleanupStack::PushL( commDb );
+ CApUtils* aputils = CApUtils::NewLC(*commDb);
+ TBool exists = aputils->IAPExistsL( aIapId);
+ CleanupStack::PopAndDestroy( aputils );
+ CleanupStack::PopAndDestroy( commDb );
+ 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<KMaxPath> 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;
+ }
+