--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/fotaapplication/fotaserver/FotaEngine/SRC/fotaengine.cpp Thu Dec 17 09:07:52 2009 +0200
@@ -0,0 +1,559 @@
+/*
+* 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: Client for fotaserver
+*
+*/
+
+
+
+
+// INCLUDES
+#include <bldvariant.hrh>
+#include "fotaengine.h"
+#include "FotaIPCTypes.h"
+#include "fotaConst.h"
+#include "fotaenginedebug.h"
+#include <apgcli.h>
+#include <AknServerApp.h>
+
+// CONSTANTS
+_LIT(KServerNameFormat, "%08x_%08x_AppServer");
+
+// =================== LOCAL FUNCTIONS ========================================
+
+// ---------------------------------------------------------------------------
+// IsClientFota() Checks if client is another fotaserver
+// ---------------------------------------------------------------------------
+TBool IsClientFota()
+ {
+ RThread thread;
+ TUid fota,dlmgr;
+ fota.iUid = KFotaServerUid;
+ dlmgr.iUid = KDLMgrServerUid;
+ if (thread.SecureId() == fota.iUid || thread.SecureId() == dlmgr.iUid )
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::StartServerL()
+// Start application server
+// ---------------------------------------------------------------------------
+//
+void RFotaEngineSession::StartApplicationL( const TUid& aNameUid
+ , const TUid& aAppServerUid )
+ {
+ TInt err;
+ FLOG(_L("RFotaEngineSession::StartApplicationL >>"));
+ RApaLsSession apa;
+ err = apa.Connect();
+ User::LeaveIfError(err);
+ CleanupClosePushL(apa);
+
+ // Get application information
+ TApaAppInfo info;
+ err=0;
+ for(TInt i = 20; ((err = apa.GetAppInfo(info,
+ aAppServerUid)) == RApaLsSession::EAppListInvalid) && i > 0; i--)
+ {
+ User::After(500000);
+ }
+ User::LeaveIfError(err);
+
+ // Start aplication server
+ CApaCommandLine* cmdLine = CApaCommandLine::NewLC();
+ cmdLine->SetExecutableNameL(info.iFullName);
+ cmdLine->SetServerRequiredL( aNameUid.iUid );
+ cmdLine->SetCommandL(EApaCommandBackground);
+ TThreadId srvid;
+ err = apa.StartApp(*cmdLine, srvid);
+ User::LeaveIfError(err);
+
+ // Wait until server is running.
+
+ // Rendezvous() is not reliable for synchronising with the new server
+ // in this case as we may not be able
+ // to open the server thread before it has reached its rendezvous
+ // point, in which case we hang.
+ // So, the standby algorithm is to poll for server existence (yuk)
+ const TInt maxPoll = 100;
+ const TInt waitDelay = 100000; // 0.1 seconds
+ TFullName serverName;
+ serverName.Format(KServerNameFormat, aNameUid, aAppServerUid);
+ for (TInt ii = 0; ii < maxPoll; ii++)
+ {
+ // look for the server name
+ TFindServer find(serverName);
+ TFullName fullName;
+ err = find.Next(fullName);
+ if ( err == KErrNone)
+ {
+ break; // found the server, so return
+ }
+ User::After(waitDelay); // wait before trying again
+ }
+ User::LeaveIfError(err); // failed to find the server, bomb out
+
+ CleanupStack::PopAndDestroy(2, &apa); // cmdLine and apa
+ FLOG(_L("RFotaEngineSession::StartApplicationL <<"));
+ }
+
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::StartServerL()
+// Connect to existing server
+// ---------------------------------------------------------------------------
+//
+void RFotaEngineSession::ConnectToServerL( const TUid& aNameUid
+ , const TUid& aAppServerUid )
+ {
+ RWsSession ws;
+ TInt err;
+
+ FLOG(_L("RFotaEngineSession::ConnectToServerL >>"));
+ if (aAppServerUid == KNullUid)
+ {
+ User::Leave(KErrGeneral);
+ }
+
+ // Connect to server
+ TFullName serverName;
+ serverName.Format(KServerNameFormat,
+ aNameUid, aAppServerUid);
+ TRAP(err, ConnectExistingByNameL(serverName) );
+ if(err)
+ {
+ TVersion vers(0,0,1);
+ err = CreateSession (serverName, vers);
+ User::LeaveIfError(err);
+ }
+ FLOG(_L(" 3"));
+
+ FLOG(_L("RFotaEngineSession::ConnectToServerL <<"));
+ }
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::OpenL( )
+// Opens session to fotaserver.
+// ---------------------------------------------------------------------------
+EXPORT_C void RFotaEngineSession::OpenL( )
+{
+ RProcess pr; TFullName fn = pr.FullName();
+ TInt err(0);
+ TUid diff1 = TUid::Uid(KUikonUidPluginInterfaceNotifiers);
+ FLOG(_L("[RFotaEngineSession] OpenL\tcalled by '%S' >>"),&fn );
+
+ // -------------------------------------------- V
+ err = KErrNotFound;
+ // If client is fotaserver - MUST create new server
+ if( !IsClientFota() )
+ {
+ TRAP(err, ConnectToServerL( diff1 , TUid::Uid(KFotaServerUid)) );
+ }
+ else
+ {
+ diff1 = TUid::Uid(KUikonUidPluginInterfaceNotifiers+1);
+ }
+
+ if(err!=KErrNone)
+ {
+ StartApplicationL( diff1 , TUid::Uid(KFotaServerUid));
+ ConnectToServerL( diff1 , TUid::Uid(KFotaServerUid));
+ }
+ FLOG(_L("[RFotaEngineSession]\tconnected <<") );
+}
+
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::Close( )
+// Closes session to fotaserver
+// ---------------------------------------------------------------------------
+EXPORT_C void RFotaEngineSession::Close( )
+{
+ RProcess pr; TFullName fn = pr.FullName();
+ FLOG(_L("[RFotaEngineSession] RFotaEngineSession::Close() >> called by '%S'"),&fn );
+
+ if ( iStream )
+ {
+ iStream->Close(); // this uses iChunk
+ delete iStream; iStream=0;
+ }
+ iChunk.Close();
+
+ // Tell server that generic alert is sent for this pkg, so state is
+ // cleaned up
+ if ( iGenericAlertSentPkgID != -1 )
+ {
+ TInt err = SendReceive( EGenericAlertSentForPackage
+ , TIpcArgs(iGenericAlertSentPkgID) );
+ }
+
+ REikAppServiceBase::Close();
+ FLOG(_L("[RFotaEngineSession] RFotaEngineSession::Close() <<") );
+}
+
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::Download
+// Starts download of upd package.
+// ---------------------------------------------------------------------------
+EXPORT_C TInt RFotaEngineSession::Download(const TInt aPkgId
+ , const TDesC8& aPkgURL, const TSmlProfileId aProfileId
+ , const TDesC8& aPkgName, const TDesC8& aPkgVersion)
+{
+ TInt err;
+ TDownloadIPCParams ipcparam;
+ ipcparam.iPkgId = aPkgId;
+ ipcparam.iProfileId = aProfileId;
+ ipcparam.iPkgName.Copy (aPkgName);
+ ipcparam.iPkgVersion.Copy (aPkgVersion);
+ TPckg<TDownloadIPCParams> pkg(ipcparam);
+ err = SendReceive ( EFotaDownload , TIpcArgs(&pkg, &aPkgURL));
+ return err;
+}
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::DownloadAndUpdate
+// Starts download and update of update pakcage
+// ---------------------------------------------------------------------------
+EXPORT_C TInt RFotaEngineSession::DownloadAndUpdate(const TInt aPkgId
+ ,const TDesC8& aPkgURL, const TSmlProfileId aProfileId
+ ,const TDesC8& aPkgName, const TDesC8& aPkgVersion)
+{
+ TInt err;
+ TDownloadIPCParams ipcparam;
+ ipcparam.iPkgId = aPkgId;
+ ipcparam.iProfileId = aProfileId;
+ ipcparam.iPkgName.Copy (aPkgName);
+ ipcparam.iPkgVersion.Copy (aPkgVersion);
+ TPckg<TDownloadIPCParams> pkg(ipcparam);
+ err = SendReceive( EFotaDownloadAndUpdate, TIpcArgs(&pkg, &aPkgURL));
+ return err;
+}
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::Update
+// Starts update of update package
+// ---------------------------------------------------------------------------
+EXPORT_C TInt RFotaEngineSession::Update(const TInt aPkgId
+ ,const TSmlProfileId aProfileId, const TDesC8& aPkgName
+ ,const TDesC8& aPkgVersion)
+{
+ TInt err;
+ TDownloadIPCParams ipcparam;
+ ipcparam.iPkgId = aPkgId;
+ ipcparam.iProfileId = aProfileId;
+ ipcparam.iPkgName.Copy (aPkgName);
+ ipcparam.iPkgVersion.Copy (aPkgVersion);
+ TPckg<TDownloadIPCParams> pkg(ipcparam);
+ err = SendReceive ( EFotaUpdate , TIpcArgs(&pkg));
+ return err;
+}
+
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::IsPackageStoreSizeAvailable
+// Checks if there's space enough for update package
+// ---------------------------------------------------------------------------
+EXPORT_C TBool RFotaEngineSession::IsPackageStoreSizeAvailable(
+ const TInt aSize)
+ {
+// // -------------------------------------------- v
+// if( IsClientFota() )
+// {
+// FLOG(_L(" IsPackageStoreSizeAvailable NOT CONNECTING"));
+// return ETrue;
+// }
+// // -------------------------------------------- ^
+ TInt err;
+ TBool available;
+ TPckg<TBool> pavailable(available);
+ err = SendReceive ( EIsPackageStoreSizeAvailable, TIpcArgs(aSize
+ , &pavailable ) );
+ if ( err )
+ {
+ FLOG(_L("RFotaEngineSession::IsPackageStoreSizeAvailable error %d")
+ ,err);
+ }
+ return available;
+ }
+
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::OpenUpdatePackageStore
+// OPens update package storage for writing.
+// ---------------------------------------------------------------------------
+EXPORT_C TInt RFotaEngineSession::OpenUpdatePackageStore(const TInt aPkgId
+ ,RWriteStream*& aPkgStore)
+ {
+ FLOG(_L( "RFotaEngineSession::OpenUpdatePackageStore >> pkgid %d " )
+ ,aPkgId );
+ TInt err;
+ err = iChunk.CreateGlobal( KNullDesC, KFotaChunkMinSize, KFotaChunkMaxSize );
+ if(err) return err;
+ iStream = new RFotaWriteStream();
+ iStream->iFotaEngineSession = this;
+ TRAP( err, iStream->OpenL(aPkgId) );
+ aPkgStore = iStream;
+ if(err) return err;
+
+ TIpcArgs args;
+ args.Set(0,aPkgId);
+ args.Set(1,iChunk );
+ err = SendReceive( EFotaOpenUpdatePackageStore, args );
+ FLOG(_L( "RFotaEngineSession::OpenUpdatePackageStore << err %d" ),err );
+ return err;
+ }
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::GetDownloadUpdatePackageSize
+// Gets the downloaded and full size of the update package.
+// Implementation is not ready and will be provided later.
+// ---------------------------------------------------------------------------
+EXPORT_C TInt RFotaEngineSession::GetDownloadUpdatePackageSize(const TInt aPkgId, TInt& aDownloadedSize, TInt& aTotalSize)
+ {
+ FLOG(_L("RFotaEngineSession::GetDownloadUpdatePackageSize, aPkgId=%d >>"),aPkgId);
+ TInt err (KErrNone);
+ TPckg<TInt> pkg1(aDownloadedSize);
+ TPckg<TInt> pkg2(aTotalSize);
+ err = SendReceive( EFotaGetDownloadUpdatePackageSize,TIpcArgs(aPkgId,&pkg1, &pkg2) );
+ FLOG(_L("RFotaEngineSession::GetDownloadUpdatePackageSize << err = %d, aDownloadedSize = %d, aTotalSize = %d" ), err, aDownloadedSize, aTotalSize);
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::TryResumeDownload
+// Requests to resume the suspended download of the update package.
+// Implementation is not ready and will be provided later.
+// ---------------------------------------------------------------------------
+EXPORT_C TInt RFotaEngineSession::TryResumeDownload()
+ {
+ FLOG(_L("RFotaEngineSession::TryResumeDownload >>"));
+
+ TInt err = KErrNone;
+
+ err = SendReceive( EFotaTryResumeDownload );
+
+ FLOG(_L("RFotaEngineSession::TryResumeDownload << err = %d" ),err);
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::UpdatePackageDownloadComplete
+// Ends update pkg storing. Closes resources.
+// ---------------------------------------------------------------------------
+EXPORT_C void RFotaEngineSession::UpdatePackageDownloadComplete(
+ const TInt aPkgId)
+ {
+ FLOG(_L("RFotaEngineSession::UpdatePackageDownloadComplete >> id %d")
+ ,aPkgId);
+ if ( iStream )
+ {
+ iStream->Close();
+ delete iStream;
+ iStream=0;
+ }
+ TInt err = SendReceive(EUpdatePackageDownloadComplete, TIpcArgs(aPkgId) );
+ FLOG(_L("RFotaEngineSession::UpdatePackageDownloadComplete << error %d ")
+ ,err);
+ }
+
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::GetState
+// ---------------------------------------------------------------------------
+EXPORT_C RFotaEngineSession::TState RFotaEngineSession::GetState(
+ const TInt aPkgId)
+ {
+ FLOG(_L("RFotaEngineSession::GetState"));
+ TInt err(0);
+ RFotaEngineSession::TState state;
+ TPckg<RFotaEngineSession::TState> pkgstate(state);
+ err = SendReceive ( EGetState , TIpcArgs(aPkgId, &pkgstate));
+ if ( err )
+ {
+ FLOG(_L("RFotaEngineSession::GetState error %d"),err);
+ }
+ return state;
+ }
+
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::GetResult
+// ---------------------------------------------------------------------------
+EXPORT_C TInt RFotaEngineSession::GetResult(const TInt aPkgId)
+ {
+ FLOG(_L("RFotaEngineSession::GetResult"));
+ TInt result;
+ TPckg<TInt> pkgresult(result);
+ SendReceive ( EGetResult , TIpcArgs(aPkgId, &pkgresult));
+ return result;
+ }
+
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::DeleteUpdatePackage
+// ---------------------------------------------------------------------------
+EXPORT_C TInt RFotaEngineSession::DeleteUpdatePackage(const TInt aPkgId)
+{
+ TInt err = SendReceive(EDeletePackage, TIpcArgs(aPkgId) );
+ return err;
+}
+
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::LastUpdate
+// ---------------------------------------------------------------------------
+EXPORT_C TInt RFotaEngineSession::LastUpdate(TTime& aUpdates)
+ {
+ TInt err;
+ FLOG(_L("RFotaEngineSession::LastUpdate >>"));
+ TBuf<15> timestamp;
+ err = SendReceive ( EGetUpdateTimestamp, TIpcArgs(×tamp) );
+
+ if ( timestamp.Length() > 0 )
+ {
+ TInt year = timestamp[0];
+ TInt month = timestamp[1];
+ TInt day = timestamp[2];
+ TInt hour = timestamp[3];
+ TInt minute = timestamp[4];
+ aUpdates = TDateTime (year,(TMonth)month,day,hour,minute,0,0 );
+ }
+ else
+ {
+ aUpdates.Set( _L( "19900327:101010.000000" ) );
+ err = KErrUnknown;
+ }
+ FLOG(_L("RFotaEngineSession::LastUpdate <<"));
+ return err;
+ }
+
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::CurrentVersion
+// ---------------------------------------------------------------------------
+EXPORT_C TInt RFotaEngineSession::CurrentVersion(TDes& aSWVersion)
+ {
+ aSWVersion.Copy(_L("1.0"));
+ return KErrNone;
+ }
+
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::ExtensionInterface
+// ---------------------------------------------------------------------------
+EXPORT_C void RFotaEngineSession::ExtensionInterface(TUid /*aInterfaceId*/
+ ,TAny*& /*aImplementation*/)
+ {
+ RProcess pr; TFullName fn = pr.FullName();
+ FLOG(_L("RFotaEngineSession::ExtensionInterface called by %S"), &fn);
+ }
+
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::RFotaEngineSession
+// ---------------------------------------------------------------------------
+EXPORT_C RFotaEngineSession::RFotaEngineSession() : iStream(0)
+ , iGenericAlertSentPkgID(-1)
+ {
+ FLOG(_L("RFotaEngineSession::RFotaEngineSession() >>"));
+ FLOG(_L("RFotaEngineSession::RFotaEngineSession() <<"));
+ }
+
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::GetUpdatePackageIds
+// Gets ids of the update packages present in the system.
+// ---------------------------------------------------------------------------
+EXPORT_C TInt RFotaEngineSession::GetUpdatePackageIds(TDes16& aPackageIdList)
+ {
+ TInt err;
+ FLOG(_L("RFotaEngineSession::GetUpdatePackageIds >>"));
+ TBuf<10> b; b.Copy(_L("dkkd"));
+ TPkgIdList pkgids;
+ TPckg<TPkgIdList> pkgids_pkg(pkgids);
+ TIpcArgs args ( &pkgids_pkg);
+ err = SendReceive ( EGetUpdatePackageIds, args);
+ aPackageIdList.Copy(pkgids);
+ FLOG(_L("RFotaEngineSession::GetUpdatePackageIds <<"));
+ return err;
+ }
+
+
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::GenericAlertSentL
+// marks genereic alert being sent
+// ---------------------------------------------------------------------------
+EXPORT_C void RFotaEngineSession::GenericAlertSentL ( const TInt aPackageID )
+ {
+ iGenericAlertSentPkgID = aPackageID;
+ }
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::ScheduledUpdateL
+// Update fw
+// ---------------------------------------------------------------------------
+EXPORT_C TInt RFotaEngineSession::ScheduledUpdateL ( const TFotaScheduledUpdate aSchedule )
+ {
+ TInt err(KErrNotSupported);
+
+ TPckg<TFotaScheduledUpdate> p(aSchedule);
+ err = SendReceive( EScheduledUpdate, TIpcArgs(&p) );
+
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::ServiceUid
+// Apparc asks which session class to create in server side
+// ---------------------------------------------------------------------------
+TUid RFotaEngineSession::ServiceUid() const
+ {
+ RProcess pr; TFullName fn = pr.FullName();
+ FLOG(_L( "RFotaEngineSession::ServiceUid() >> called by: %S" ), &fn );
+ FLOG(_L( "RFotaEngineSession::ServiceUid() << ret: 0x%X" ),
+ KFotaServiceUid );
+ return TUid::Uid( KFotaServiceUid );
+ }
+
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::SendChunkL
+// Tells server to read chunk contnets
+// ---------------------------------------------------------------------------
+void RFotaEngineSession::SendChunkL(const TUint8* aP1, const TUint8* aP2)
+ {
+ TInt writecount = aP2-aP1;
+ TInt err = SendReceive(EFotaSendChunk, TIpcArgs(writecount) );
+
+ if ( err )
+ {
+ FLOG(_L("RFotaEngineSession::SendChunkL error %d"),err);
+ }
+ User::LeaveIfError ( err );
+ }
+
+
+// ---------------------------------------------------------------------------
+// RFotaEngineSession::ReleaseChunkHandle()
+// Releases server's handle to the chuhnk
+// ---------------------------------------------------------------------------
+TInt RFotaEngineSession::ReleaseChunkHandle()
+ {
+ return Send( EFotaReleaseChunkHandle);
+ }