diff -r c8e5c3d81b42 -r 39aa16f3fdc2 fotaapplication/fotaserver/src/FotaDlClient.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fotaapplication/fotaserver/src/FotaDlClient.cpp Tue Jul 06 15:14:24 2010 +0300 @@ -0,0 +1,615 @@ +/* + * 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 download client + * + */ +#include +#include "FotaDlClient.h" +#include "FotaDlMgrClient.h" + +// ----------------------------------------------------------------------------- +// The constructor of this class +// ----------------------------------------------------------------------------- +DownloadClient::DownloadClient(DownloadManagerClient* Observer) + { + FLOG(_L("DownloadClient::DownloadClient >>")); + + iFotaDlMgrClient = Observer; + iTotalSize = -1; + iSpaceChecked = 0; + iDownload = NULL; + iClientinterrupted = false; + iClientError = ErrorNone; + iContentType = TUnknownType; + + FLOG(_L("DownloadClient::DownloadClient <<")); + } + +// ----------------------------------------------------------------------------- +// The destructor of this class +// ----------------------------------------------------------------------------- +DownloadClient::~DownloadClient() + { + FLOG(_L("DownloadClient::~DownloadClient >>")); + + if (iDownload) + { + disconnect(iDownload, SIGNAL(downloadEvent(DownloadEvent *)), this, + SLOT(DownloadEventRecieved(DownloadEvent *))); + + //Do not delete iDownload as it is owned by download manager. + //delete iDownload; + iDownload = NULL; + } + //Don't delete as it is not owned + iFotaDlMgrClient = NULL; + + FLOG(_L("DownloadClient::~DownloadClient <<")); + } + +// ----------------------------------------------------------------------------- +// Creates a single download with the download manager +// ----------------------------------------------------------------------------- +TInt DownloadClient::CreateDownload(const QString &url, DownloadType type) + { + FLOG(_L("DownloadClient::CreateDownload >>")); + + TInt ret = ENotOk; + + iDownload = iFotaDlMgrClient->Manager()->createDownload(url, type); //Step 6 + + if (iDownload) + { + connect(iDownload, SIGNAL(downloadEvent(DownloadEvent *)), this, + SLOT(DownloadEventRecieved(DownloadEvent *))); + ret = EOk; + } + else + { + FLOG(_L("Download creation is unsuccessful!")); + } + + FLOG(_L("DownloadClient::CreateDownload, ret = %d <<"), ret); + return ret; + } + +// ----------------------------------------------------------------------------- +// Sets the required attributes for the single download. +// ----------------------------------------------------------------------------- +TInt DownloadClient::SetDownloadAttributes() + { + FLOG(_L("DownloadClient::SetDownloadAttributes >>")); + + int ret(EOk); + + iDownload->setAttribute(ProgressInterval, 100); //Step 7 + iDownload->setAttribute(Priority, High); //Step 8 + + //Setting the default path + iDownload->setAttribute(DestinationPath, DefaultPath); + + iDownload->setAttribute(FileName, PackageName); + + FLOG(_L("DownloadClient::SetDownloadAttributes, ret = %d <<"), ret); + + return ret; + } + +// ----------------------------------------------------------------------------- +// Starts the single download. Download should be created and attributes set before this. +// ----------------------------------------------------------------------------- +TInt DownloadClient::Start() + { + FLOG(_L("DownloadClient::Start >>")); + + iClientinterrupted = false; + iDownload->start(); //Step 9 + + FLOG(_L("DownloadClient::Start <<")); + return EOk; + + } + +// ----------------------------------------------------------------------------- +// Gets the attribute of the single download +// ----------------------------------------------------------------------------- +inline QVariant DownloadClient::GetDownloadAttribute(DownloadAttribute attr) + { + FLOG(_L("DownloadClient::GetDownloadAttribute >>")); + + QVariant val; + + val = iDownload->attribute(attr); + + FLOG(_L("DownloadClient::GetDownloadAttribute<<")); + return val; + } + +// ----------------------------------------------------------------------------- +// Pauses the single download. +// ----------------------------------------------------------------------------- +TInt DownloadClient::Pause(TClientErrorType aReason) + { + FLOG(_L("DownloadClient::Pause >>")); + + iClientinterrupted = true; + iClientError = aReason; + + iDownload->pause(); + + FLOG(_L("DownloadClient::Pause <<")); + return EOk; + } + +// ----------------------------------------------------------------------------- +// Resumes the single download. +// ----------------------------------------------------------------------------- +TInt DownloadClient::Resume() + { + FLOG(_L("DownloadClient::Resume >>")); + + int ret(ENotOk); + iSpaceChecked = true; + + if (!iDownload) + { + QList dls = + iFotaDlMgrClient->Manager()->currentDownloads(); + int count = dls.count(); + FLOG(_L("Number of current downloads = %d"), count); + + if (count) + { + iDownload = dls[0]; + FLOG(_L("Connecting to download event")); + connect(iDownload, SIGNAL(downloadEvent(DownloadEvent *)), this, + SLOT(DownloadEventRecieved(DownloadEvent *))); + FLOG(_L("Connecting to download events done")); + } + + } + iClientinterrupted = false; + iClientError = ErrorNone; + + if (iDownload) + { + FLOG(_L("B4 Download Start")); + iDownload->start(); + ret = EOk; + FLOG(_L("After Download Start")); + } + + FLOG(_L("DownloadClient::Resume, ret = %d <<"), ret); + return ret; + } + +// ----------------------------------------------------------------------------- +// Cancels the single download. +// ----------------------------------------------------------------------------- +TInt DownloadClient::Cancel(TClientErrorType aReason) + { + FLOG(_L("DownloadClient::Cancel >>")); + + iClientinterrupted = true; + iClientError = aReason; + + iDownload->cancel(); + + FLOG(_L("DownloadClient::Cancel <<")); + return EOk; + } + +// ----------------------------------------------------------------------------- +// Restarts the single download. This is equivalent to cancel and start on Download. +// ----------------------------------------------------------------------------- +TInt DownloadClient::Restart() + { + FLOG(_L("DownloadClient::Restart >>")); + + QString path(NULL); + int size = iTotalSize; + TFreeSpace avail = iFotaDlMgrClient->GetSuitablePath(size, path); + + if (avail == EFitsToReservation || avail == EFitsToFileSystem) + { + //FLOG(_L("Space is available for download at %S"), TPtrC (reinterpret_cast (path.constData()),path.length())); + + if (iContentType == TOmaDL10Download) + { + ReadDescriptorData(); + } + Resume(); + } + else + { + FLOG(_L("Space not available. Download is stopped!")); + TRAP_IGNORE(iFotaDlMgrClient->ShowDialogL(EFwDLNeedMoreMemory, size)); + } + + FLOG(_L("DownloadClient::Restart >>")); + + return EOk; + } + +// ----------------------------------------------------------------------------- +// The slot which receives all the single download events. +// ----------------------------------------------------------------------------- +bool DownloadClient::DownloadEventRecieved(DownloadEvent *event) + { + FLOG(_L("DownloadClient::event >>")); + + DownloadEvent::Event type = (DownloadEvent::Event) event->type(); + bool eventHandled = false; + int err0(NoError); + + FLOG(_L("Download Event Type: %d"), type); + + switch (type) + { + case DownloadEvent::Started: + { + FLOG(_L("DownloadEventRecieved - DownloadEvent::Started")); + iProgress = true; + iDlState = Download::Created; + + eventHandled = true; + break; + } + + case DownloadEvent::HeadersReceived: + { + FLOG(_L("DownloadEventRecieved - DownloadEvent::HeadersReceived")); + iProgress = true; + iDlState = Download::Created; + + QString contenttype = + GetDownloadAttribute(ContentType).toString(); + HBufC* s_contenttype = XQConversions::qStringToS60Desc(contenttype); + FLOG(_L("Content type received is %S"), s_contenttype); + delete s_contenttype; + + iContentType = CheckContentType(contenttype); + + if (iContentType == THttpDownload) + { + FLOG(_L("Content type: Http; checking the size of download")); + if (!iSpaceChecked) + { + + iTotalSize = GetDownloadAttribute(TotalSize).toInt(); + + FLOG(_L("Size of the firmware update as received is %d"), + iTotalSize); + + if (iTotalSize > 0) + { + QString path(NULL); + + TFreeSpace avail = iFotaDlMgrClient->GetSuitablePath( + iTotalSize, path); + + if (avail == EFitsToReservation || avail + == EFitsToFileSystem) + { + //FLOG(_L("Space is available for download at %S"),TPtrC (reinterpret_cast (path.constData()),path.length())); + iFotaDlMgrClient->DeleteDiskReservation(path); + iDownload->setAttribute(DestinationPath, path); + } + else + { + FLOG( + _L("Space not available. Download is stopped!")); + Pause(NeedMoreMemory); + TRAP_IGNORE(iFotaDlMgrClient->ShowDialogL(EFwDLNeedMoreMemory)); + break; + } + + iSpaceChecked = true; + iFotaDlMgrClient->StartDownloadProgress( + QString::null, QString::null, iTotalSize); + } + } + } + else if (iContentType == TUnknownType) + { + FLOG(_L("Content type unknown; hence cancelling download !")); + Cancel(InvalidContentType); + } + + eventHandled = true; + break; + } + + case DownloadEvent::InProgress: + { + FLOG(_L("DownloadEventRecieved - DownloadEvent::InProgress")); + + iProgress = true; + iDlState = Download::InProgress; + UpdateDownloadProgress(); + + eventHandled = true; + break; + } + + case DownloadEvent::Completed: + { + FLOG(_L("DownloadEventRecieved - DownloadEvent::Completed")); + iProgress = false; + iDlState = Download::Completed; + iTotalSize = 0; + UpdateDownloadProgress(); + + eventHandled = true; + break; + } + + case DownloadEvent::Paused: + { + FLOG(_L("DownloadEventRecieved - DownloadEvent::Paused")); + iProgress = false; + iDlState = Download::Paused; + + eventHandled = true; + break; + } + case DownloadEvent::Failed: + { + FLOG(_L("DownloadEventRecieved - DownloadEvent::Failed")); + iProgress = false; + iDlState = Download::Failed; + + eventHandled = true; + break; + } + case DownloadEvent::Cancelled: + { + FLOG(_L("DownloadEventRecieved - DownloadEvent::Cancelled")); + iProgress = false; + iDlState = Download::Cancelled; + + eventHandled = true; + break; + } + + case DownloadEvent::NetworkLoss: + { + FLOG(_L("DownloadEventRecieved - DownloadEvent::NetworkLoss")); + iProgress = false; + iDlState = Download::Paused; + + eventHandled = true; + break; + } + + case DownloadEvent::Error: + { + FLOG(_L("DownloadEventRecieved - DownloadEvent::Error")); + iProgress = false; + // iDlState = (Download::State) GetDownloadAttribute(State).toInt(); + iDlState = Download::Failed; + eventHandled = true; + break; + } + + case DownloadEvent::DescriptorReady: + { + FLOG(_L("DownloadEventRecieved - DownloadEvent::DescriptorReady")); + iProgress = true; + iDlState = Download::InProgress; + iContentType = TOmaDL10Download; + + iTotalSize = GetDownloadAttribute(DescriptorSize).toInt(); + QString path(NULL); + if (iTotalSize > 0) + { + + TFreeSpace avail = iFotaDlMgrClient->GetSuitablePath( + iTotalSize, path); + + if (avail == EFitsToReservation || avail == EFitsToFileSystem) + { + //FLOG(_L("Space is available for download at %S"), TPtrC (reinterpret_cast (path.constData()),path.length())); + iFotaDlMgrClient->DeleteDiskReservation(path); + } + else + { + FLOG(_L("Space not available. Download is stopped!")); + TRAP_IGNORE(iFotaDlMgrClient->ShowDialogL(EFwDLNeedMoreMemory)); + break; + } + } + ReadDescriptorData(); + Resume(); + SetSubDownloadAttributes(); + + eventHandled = true; + break; + } + case DownloadEvent::CreatingConnection: + { + FLOG( + _L("DownloadEventRecieved - DownloadEvent::CreatingConnection")); + iProgress = true; + iDlState = Download::InProgress; + + eventHandled = true; + break; + } + case DownloadEvent::ConnectionNeeded: + case DownloadEvent::ConnectionDisconnected: + { + FLOG( + _L("DownloadEventRecieved - DownloadEvent::ConnectionNeeded/ConnectionDisconnected")); + iProgress = false; + iDlState = Download::Paused; + err0 = ConnectionFailed; + eventHandled = true; + break; + } + + default: + { + FLOG(_L("DownloadEventRecieved - Skipped this event: %d"), type); + break; + } + } + + if (iProgress == false) + { + + if (iClientinterrupted) + { + //Client has requested for cancellation. Hence provide the same error code + err0 = iClientError; + HandleClientInterrupt(iDlState, err0); + } + else + { + //Download Manager has cancelled download. Hence provide the last error code. + if (err0 == NoError) + err0 = GetDownloadAttribute(LastError).toInt(); + + HandleDownloadComplete(iDlState, err0); + } + + } + + FLOG(_L("DownloadClient::event <<")); + + return eventHandled; + } + +// ----------------------------------------------------------------------------- +// Called to update the progress of download to fota server. This fetches the percentage +// of download from download manager. +// ----------------------------------------------------------------------------- +inline void DownloadClient::UpdateDownloadProgress() + { + FLOG(_L("DownloadClient::UpdateDownloadProgress >>")); + + // Remaining size calculation + int prog = GetDownloadAttribute(Percentage).toInt(); + iFotaDlMgrClient->UpdateDownloadProgress(prog); + + FLOG(_L("DownloadClient::UpdateDownloadProgress, progress = %d <<"), prog); + } + +// ----------------------------------------------------------------------------- +// Called to read the OMA DL1.0 download descriptor. This will update the fota server with size and version. +// ----------------------------------------------------------------------------- +void DownloadClient::ReadDescriptorData() + { + FLOG(_L("DownloadClient::ReadDescriptorData >>")); + + QString name = GetDownloadAttribute(DescriptorName).toString(); // "name" in OMA dd + QString version = GetDownloadAttribute(DescriptorVersion).toString(); // "version" in OMA dd + QString type = GetDownloadAttribute(DescriptorType).toString(); // "type" in OMA dd + int size = GetDownloadAttribute(DescriptorSize).toInt(); // "size" in OMA dd + QString vendor = GetDownloadAttribute(DescriptorVendor).toString(); // "vendor" in OMA dd + QString description = + GetDownloadAttribute(DescriptorDescription).toString(); // "description" in OMA dd + QString nxturl = GetDownloadAttribute(DescriptorNextURL).toString(); // "nextURL" in OMA dd + + TDownloadType gottype = CheckContentType(type); + + if (gottype == THttpDownload) + { + iFotaDlMgrClient->StartDownloadProgress(name, version, size); + } + else + { + FLOG( + _L("The content type in descriptor is not appropriate! Hence cancelling download")); + Cancel(InvalidContentType); + } + + FLOG(_L("DownloadClient::ReadDescriptorData <<")); + } + +// ----------------------------------------------------------------------------- +// Called when download is complete, either successfully or unsuccessfully. +// The arguments to this function is read to know the actual status. +// ----------------------------------------------------------------------------- +void DownloadClient::HandleDownloadComplete(Download::State dlstate, int err0) + { + FLOG(_L("DownloadClient::HandleDownloadComplete, idlstate = %d, err0 = %d>>"), dlstate, err0); + + iFotaDlMgrClient->HandleDownloadEvent(dlstate, err0); + + FLOG(_L("DownloadClient::HandleDownloadComplete <<")); + } + +// ----------------------------------------------------------------------------- +// Called to handle the post download interrupt operation when client cancels/pauses download. +// ----------------------------------------------------------------------------- +void DownloadClient::HandleClientInterrupt(Download::State dlstate, int err0) + { + FLOG(_L("DownloadClient::HandleClientInterrupt, idlstate = %d, err0 = %d >>"), dlstate, err0); + + iFotaDlMgrClient->HandleClientInterrupt(dlstate, err0); + + FLOG(_L("DownloadClient::HandleClientInterrupt <<")); + } + +// ----------------------------------------------------------------------------- +// Called to validate the content type of the download as received in header. +// ----------------------------------------------------------------------------- +TDownloadType DownloadClient::CheckContentType(const QString aContent) + { + FLOG(_L("DownloadClient::CheckContentType >>")); + + TDownloadType type(TUnknownType); + + QString semicollon(";"); + QString contenttype = aContent; + + int index = aContent.indexOf(semicollon, 0); + + if (index > 0) + { + contenttype.chop(aContent.length() - index); + } + + if (contenttype.compare(ContentTypeHttp) == 0) + type = THttpDownload; + else if (contenttype.compare(ContentTypeOmaDl) == 0) + type = TOmaDL10Download; + + FLOG(_L("DownloadClient::CheckContentType, type = %d<<"), type); + + return type; + } + +void DownloadClient::SetSubDownloadAttributes() + { + FLOG(_L("DownloadClient::SetSubDownloadAttributes >>")); + + QList dls = iDownload->subDownloads(); + + if (dls.count() > 0) + { + Download* subdl = dls[0]; + + subdl->setAttribute(FileName, PackageName); + } + else + { + FLOG(_L("Error: There are no sub downloads!")); + } + + FLOG(_L("DownloadClient::SetSubDownloadAttributes <<")); + } + +//End of file