Index: denali.qrc
===================================================================
diff -u -rd26aff743bca7eceb609ce5b30cea7cbfa39748f -r59625af31d9009df82fa48310b54c0f247e829fc
--- denali.qrc (.../denali.qrc) (revision d26aff743bca7eceb609ce5b30cea7cbfa39748f)
+++ denali.qrc (.../denali.qrc) (revision 59625af31d9009df82fa48310b54c0f247e829fc)
@@ -25,6 +25,7 @@
sources/gui/qml/pages/settings/SettingsManufacturingSetup.qml
sources/gui/qml/pages/settings/SettingsFactoryReset.qml
sources/gui/qml/pages/settings/SettingsDecommission.qml
+ sources/gui/qml/pages/settings/SettingsStartSoftwareUpdate.qml
sources/gui/qml/dialogs/ConfirmDialog.qml
Index: sources/device/DeviceController.cpp
===================================================================
diff -u -r1bf8c894c5cc5ea6d62af0662fcf5a18e1a06459 -r59625af31d9009df82fa48310b54c0f247e829fc
--- sources/device/DeviceController.cpp (.../DeviceController.cpp) (revision 1bf8c894c5cc5ea6d62af0662fcf5a18e1a06459)
+++ sources/device/DeviceController.cpp (.../DeviceController.cpp) (revision 59625af31d9009df82fa48310b54c0f247e829fc)
@@ -1181,3 +1181,55 @@
// log error and exit
return;
}
+
+///////////////////////////////////////////// DeviceStartSoftwareUpdate
+void DeviceController::onAttributeRequest(const DeviceStartSoftwareUpdateRequestData &vData)
+{
+ _deviceStartSoftwareUpdateRequest._data = vData;
+
+ // ----- check that script exists.
+ QString script = Device_StartSoftwareUpdateScriptPath;
+ DeviceError::Scripts_Error_Enum err = DeviceError::eDevice_OK;
+ QFileInfo info(script);
+ if ( ! info.exists () ) { err = DeviceError::eDevice_Scripts_Error_NotFound ;}
+ if ( ! info.isExecutable() ) { err = DeviceError::eDevice_Scripts_Error_NotExecutable ;}
+
+ if ( checkError(err, _deviceStartSoftwareUpdateResponse, script) )
+ return;
+
+ // ----- check if the process is not running
+ if ( _processStartSoftwareUpdate.state() != QProcess::NotRunning ) {
+ checkError(DeviceError::eDevice_Scripts_Error_IsRunning, _deviceStartSoftwareUpdateResponse);
+ return;
+ }
+
+ // ----- run the process
+ int timeout_ms = 10000;
+ TimedProcess *timedProcess = new TimedProcess(&_processStartSoftwareUpdate, script, timeout_ms, { vData.mUpdateFilePath });
+ timedProcess->start();
+
+ MDeviceStartSoftwareUpdateResponse model;
+ model._data.mAccepted = false; // will indirectly set the property startSoftwareUpdateEnabled
+ model._data.mMessage = tr("Software Update started.");
+ didAttributeResponse(model.data());
+}
+
+/*!
+ * \brief DeviceController::onProcessStartSoftwareUpdateExitCode
+ * \param vExitCode
+ * \param vStatus
+ */
+void DeviceController::onProcessStartSoftwareUpdateExitCode(int vExitCode, QProcess::ExitStatus vStatus)
+{
+ // The Exit code in this script is not used.
+ // any other checking is done by UI Software at the moment this script is called.
+ // The only thing matters is the paired device info in text and it will be empty string if error happens.
+ MDeviceStartSoftwareUpdateResponse model;
+ QByteArray deviceInfo;
+ if ( vStatus ) vExitCode = Device::DeviceError::eDevice_Scripts_Error_Status;
+ else deviceInfo = _processStartSoftwareUpdate.readAll();
+ model.fromByteArray( deviceInfo, &vExitCode );
+ // DEBUG: qDebug() << model._data.mMessage << deviceInfo;
+ didAttributeResponse(model.data());
+ LOG_APPED_UI(model.data().mMessage);
+}
Index: sources/device/DeviceError.h
===================================================================
diff -u -r1bf8c894c5cc5ea6d62af0662fcf5a18e1a06459 -r59625af31d9009df82fa48310b54c0f247e829fc
--- sources/device/DeviceError.h (.../DeviceError.h) (revision 1bf8c894c5cc5ea6d62af0662fcf5a18e1a06459)
+++ sources/device/DeviceError.h (.../DeviceError.h) (revision 59625af31d9009df82fa48310b54c0f247e829fc)
@@ -67,6 +67,7 @@
eDevice_FactoryReset_Error ,
eDevice_Decommission_Error ,
eDevice_USBMount_Error ,
+ eDevice_StartSoftwareUpdate_Error ,
eDevice_Error_End
Index: sources/device/DeviceGlobals.h
===================================================================
diff -u -r80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803 -r59625af31d9009df82fa48310b54c0f247e829fc
--- sources/device/DeviceGlobals.h (.../DeviceGlobals.h) (revision 80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803)
+++ sources/device/DeviceGlobals.h (.../DeviceGlobals.h) (revision 59625af31d9009df82fa48310b54c0f247e829fc)
@@ -173,6 +173,7 @@
DEVICE_DEV_PARENT ( FactoryReset ) \
DEVICE_DEV_PARENT ( Decommission ) \
DEVICE_DEV_PARENT ( USBMount ) \
+ DEVICE_DEV_PARENT ( StartSoftwareUpdate ) \
#define DEVICE_DEV_INIT_CONNECTIONS_LIST \
DEVICE_DEV_INIT_CONNECTIONS ( Brightness ) \
@@ -183,6 +184,7 @@
DEVICE_DEV_INIT_CONNECTIONS ( FactoryReset ) \
DEVICE_DEV_INIT_CONNECTIONS ( Decommission ) \
DEVICE_DEV_INIT_CONNECTIONS ( USBMount ) \
+ DEVICE_DEV_INIT_CONNECTIONS ( StartSoftwareUpdate ) \
#define DEVICE_DEV_DEFINITION_LIST \
DEVICE_DEV_DEFINITION ( Brightness ) \
@@ -193,8 +195,10 @@
DEVICE_DEV_DEFINITION ( FactoryReset ) \
DEVICE_DEV_DEFINITION ( Decommission ) \
DEVICE_DEV_DEFINITION ( USBMount ) \
+ DEVICE_DEV_DEFINITION ( StartSoftwareUpdate ) \
+
/* ---------------------------- APP */
#define DEVICE_APP_INIT_CONNECTIONS_LIST \
DEVICE_APP_INIT_CONNECTIONS ( Brightness ) \
@@ -204,6 +208,7 @@
DEVICE_APP_INIT_CONNECTIONS ( RootSSHAccess ) \
DEVICE_APP_INIT_CONNECTIONS ( FactoryReset ) \
DEVICE_APP_INIT_CONNECTIONS ( Decommission ) \
+ DEVICE_APP_INIT_CONNECTIONS ( StartSoftwareUpdate ) \
#define DEVICE_APP_BRIDGE_DEFINITION_LIST \
DEVICE_APP_BRIDGE_DEFINITION( Brightness ) \
@@ -214,6 +219,7 @@
DEVICE_APP_BRIDGE_DEFINITION( FactoryReset ) \
DEVICE_APP_BRIDGE_DEFINITION( Decommission ) \
DEVICE_APP_BRIDGE_DEFINITION( USBMount ) \
+ DEVICE_APP_BRIDGE_DEFINITION( StartSoftwareUpdate ) \
/* ---------------------------- GUI */
#define DEVICE_GUI_BRIDGE_DEFINITION_LIST \
@@ -224,6 +230,7 @@
DEVICE_GUI_BRIDGE_DEFINITION( RootSSHAccess ) \
DEVICE_GUI_BRIDGE_DEFINITION( FactoryReset ) \
DEVICE_GUI_BRIDGE_DEFINITION( Decommission ) \
+ DEVICE_GUI_BRIDGE_DEFINITION( StartSoftwareUpdate ) \
#define DEVICE_GUI_INIT_CONNECTIONS_LIST \
DEVICE_GUI_INIT_CONNECTIONS ( Brightness ) \
@@ -233,6 +240,7 @@
DEVICE_GUI_INIT_CONNECTIONS ( RootSSHAccess ) \
DEVICE_GUI_INIT_CONNECTIONS ( FactoryReset ) \
DEVICE_GUI_INIT_CONNECTIONS ( Decommission ) \
+ DEVICE_GUI_INIT_CONNECTIONS ( StartSoftwareUpdate ) \
/* ---------------------------- VIEW */
#define DEVICE_VIEW_INIT_CONNECTIONS_LIST \
@@ -243,4 +251,5 @@
DEVICE_VIEW_INIT_CONNECTIONS( RootSSHAccess ) \
DEVICE_VIEW_INIT_CONNECTIONS( FactoryReset ) \
DEVICE_VIEW_INIT_CONNECTIONS( Decommission ) \
+ DEVICE_VIEW_INIT_CONNECTIONS( StartSoftwareUpdate ) \
Index: sources/device/DeviceModels.cpp
===================================================================
diff -u -r80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803 -r59625af31d9009df82fa48310b54c0f247e829fc
--- sources/device/DeviceModels.cpp (.../DeviceModels.cpp) (revision 80b5e8f1ebb90c03c37d90d90cd2da3bd95d6803)
+++ sources/device/DeviceModels.cpp (.../DeviceModels.cpp) (revision 59625af31d9009df82fa48310b54c0f247e829fc)
@@ -282,3 +282,35 @@
lOut:
return _data.mAccepted;
}
+
+
+
+/*!
+ * \brief MDeviceStartSoftwareUpdateResponse::fromByteArray
+ * \details Checks the response and sets up the mode data.
+ * \param vExitCode - Passed script exit code
+ * \return true if passed.
+ */
+bool MDeviceStartSoftwareUpdateResponse::fromByteArray(const QByteArray &vByteArray, int *vExitCode)
+{
+ // initialize data
+ int error = 0;
+ _data.mAccepted = false;
+
+ // check if the vExitCode passed and it has a value other than zero
+ if ( vExitCode && *vExitCode ){ _data.mReason = Device::DeviceError::eDevice_StartSoftwareUpdate_Error; error = *vExitCode; }
+ else _data.mReason = Device::DeviceError::eDevice_OK;
+
+ // if vExitCode is not zero go to error since the data is no longer valid
+ if ( _data.mReason ) goto lError; // non-zero Exit code
+
+ // Now everything is good to extract the data
+ _data.mAccepted = true;
+ _data.mMessage = QObject::tr("The Start Software Update Command Complete."); goto lOut ; // normal return
+
+lError:
+ _data.mMessage = Device::DeviceError::deviceErrorText(static_cast(_data.mReason), error) + "\n" + vByteArray;
+
+lOut:
+ return _data.mAccepted;
+}
Index: sources/device/DeviceModels.h
===================================================================
diff -u -ra7c580f0998ee781c47314384f677249cea4c4b4 -r59625af31d9009df82fa48310b54c0f247e829fc
--- sources/device/DeviceModels.h (.../DeviceModels.h) (revision a7c580f0998ee781c47314384f677249cea4c4b4)
+++ sources/device/DeviceModels.h (.../DeviceModels.h) (revision 59625af31d9009df82fa48310b54c0f247e829fc)
@@ -368,6 +368,36 @@
Data data ( ) const { return _data; }
bool fromByteArray(const QByteArray &vByteArray, int *vExitCode = nullptr) override;
};
+
+// ---------- MDeviceStartSoftwareUpdate ---------- //
+/*!
+ * \brief The MDeviceStartSoftwareUpdateRequest class
+ * \details The model for the decommission script call.
+ */
+class MDeviceStartSoftwareUpdateRequest : public MDeviceRequestBase {
+public:
+ struct Data {
+ QString mUpdateFilePath = "";
+ } _data;
+
+ QString toString() {
+ return MDeviceRequestBase::toString("StartSoftwareUpdate", { });
+ }
+};
+
+/*!
+ * \brief The MDeviceStartSoftwareUpdateResponse class
+ * \details The model for the decommission script call returned value / response.
+ */
+class MDeviceStartSoftwareUpdateResponse : public MDeviceResponseBase {
+public:
+ struct Data : MDeviceResponseBase::Data {
+ } _data;
+ QVariantList parameters ( ) const override { return { }; }
+ QString infoText ( ) const override { return QString("StartSoftwareUpdate"); }
+ Data data ( ) const { return _data; }
+ bool fromByteArray(const QByteArray &vByteArray, int *vExitCode = nullptr) override;
+};
}
typedef Model::MDeviceResponseBase ::Data DeviceResponseBaseData ;
@@ -395,3 +425,7 @@
typedef Model::MDeviceUSBMountRequest ::Data DeviceUSBMountRequestData ;
typedef Model::MDeviceUSBMountResponse::Data DeviceUSBMountResponseData;
+
+typedef Model::MDeviceStartSoftwareUpdateRequest ::Data DeviceStartSoftwareUpdateRequestData ;
+typedef Model::MDeviceStartSoftwareUpdateResponse::Data DeviceStartSoftwareUpdateResponseData;
+
Index: sources/device/DeviceView.cpp
===================================================================
diff -u -ra7c580f0998ee781c47314384f677249cea4c4b4 -r59625af31d9009df82fa48310b54c0f247e829fc
--- sources/device/DeviceView.cpp (.../DeviceView.cpp) (revision a7c580f0998ee781c47314384f677249cea4c4b4)
+++ sources/device/DeviceView.cpp (.../DeviceView.cpp) (revision 59625af31d9009df82fa48310b54c0f247e829fc)
@@ -258,6 +258,36 @@
response(true);
}
+// ================================================= Start Software Update
+void VDevice::doInitStartSoftwareUpdate() {
+ // Nothing for now.
+}
+
+void VDevice::startSoftwareUpdateRequest(const QString& vUpdateFilePath) {
+ // DEBUG : qDebug() << "HERE Request" << vUpdateFilePath;
+
+ startSoftwareUpdateEnabled(true);
+
+ DeviceStartSoftwareUpdateRequestData data;
+ data.mUpdateFilePath = vUpdateFilePath;
+ emit didAttributeRequest(data);
+}
+
+void VDevice::onAttributeResponse(const DeviceStartSoftwareUpdateResponseData &vData) {
+ //QDEBUG : qDebug() << "HERE Response " << Q_FUNC_INFO << " accepted: "<< vData.mAccepted << vData.mReason;
+ // this has to be called to let Gui to set to old value that device controller provided.
+ status(vData.mMessage);
+
+ accepted(vData.mAccepted);
+ reason (vData.mReason );
+
+ startSoftwareUpdateEnabled(isCompleteResponse(vData));
+
+ // has to be the last one
+ response(true);
+}
+
+
void VDevice::onPOSTOSVersionData(const QString &vOSVersion)
{
osVersion(vOSVersion);
Index: sources/device/DeviceView.h
===================================================================
diff -u -ra7c580f0998ee781c47314384f677249cea4c4b4 -r59625af31d9009df82fa48310b54c0f247e829fc
--- sources/device/DeviceView.h (.../DeviceView.h) (revision a7c580f0998ee781c47314384f677249cea4c4b4)
+++ sources/device/DeviceView.h (.../DeviceView.h) (revision 59625af31d9009df82fa48310b54c0f247e829fc)
@@ -60,6 +60,9 @@
ATTRIBUTE ( QString , decommission , "", Decommission )
PROPERTY ( bool , decommissionEnabled , true )
+ ATTRIBUTE ( QString , startSoftwareUpdate , "", StartSoftwareUpdate )
+ PROPERTY ( bool , startSoftwareUpdateEnabled , true )
+
VIEW_DEC_CLASS(VDevice)
private slots:
Index: sources/gui/qml/pages/settings/SettingsStack.qml
===================================================================
diff -u -ra7c580f0998ee781c47314384f677249cea4c4b4 -r59625af31d9009df82fa48310b54c0f247e829fc
--- sources/gui/qml/pages/settings/SettingsStack.qml (.../SettingsStack.qml) (revision a7c580f0998ee781c47314384f677249cea4c4b4)
+++ sources/gui/qml/pages/settings/SettingsStack.qml (.../SettingsStack.qml) (revision 59625af31d9009df82fa48310b54c0f247e829fc)
@@ -70,9 +70,8 @@
readonly property bool visibleSetDateTime : loggedIn || onlyUpdating
readonly property bool visibleDeviceConfiguration : onlyManufacturing && loggedIn
readonly property bool visibleDeviceRegistration : onlyManufacturing && loggedIn
+ readonly property bool visibleStartSoftwareUpdate : loggedIn
-
-
enum ItemsIndex {
Information ,
VolumeBrightness ,
@@ -91,7 +90,8 @@
SWUpdate ,
RootSSHAccess ,
FactoryReset ,
- Decommission
+ Decommission ,
+ StartSoftwareUpdate
}
property var itemsText : [
qsTr("Information" ), // Information
@@ -112,6 +112,7 @@
qsTr("Enable Root SSH" ), // RootSSHAccess
qsTr("Factory Reset" ), // FactoryReset
qsTr("Decommissioning" ), // Decommission
+ qsTr("Software Update" ), // Software Update Request
]
property var itemsEnabled : [
true , // Information
@@ -132,6 +133,7 @@
true , // RootSSHAccess
true , // FactoryReset
true , // Decommission
+ true , // Software Update Request
]
property var itemsVisible : [
visibleInformation , // Information
@@ -152,6 +154,7 @@
visibleRootSSHAccess , // RootSSHAccess
visibleFactoryReset , // FactoryReset
visibleDecommission , // Decommission
+ visibleStartSoftwareUpdate , // Software update request
]
SettingsHome { id : _settingsHome
@@ -246,6 +249,10 @@
push( _serviceDecommission )
break
+ case SettingsStack.StartSoftwareUpdate:
+ push( _serviceStartSoftwareUpdate )
+ break
+
default:
console.debug("Unknown Index", vIndex)
break
@@ -268,6 +275,7 @@
SettingsRootSSHAccess { id: _SettingsRootSSHAccess }
SettingsFactoryReset { id: _serviceFactoryReset }
SettingsDecommission { id: _serviceDecommission }
+ SettingsStartSoftwareUpdate { id: _serviceStartSoftwareUpdate }
function gotoServiceMode( vservice ) {
//DEBUG console.log (" 0 ---------- ", _GuiView.manufactMode, _GuiView.manufactSetup, vservice, stackView.initialItem, stackView.currentItem, stackView.depth)
Index: sources/gui/qml/pages/settings/SettingsStartSoftwareUpdate.qml
===================================================================
diff -u
--- sources/gui/qml/pages/settings/SettingsStartSoftwareUpdate.qml (revision 0)
+++ sources/gui/qml/pages/settings/SettingsStartSoftwareUpdate.qml (revision 59625af31d9009df82fa48310b54c0f247e829fc)
@@ -0,0 +1,119 @@
+/*!
+ *
+ * Copyright (c) 2023-2023 Diality Inc. - All Rights Reserved.
+ * \copyright
+ * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN
+ * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER.
+ *
+ * \file SettingsStartSoftwareUpdate.qml
+ * \author (last) Vy Duong
+ * \date (last) 04-Dec-2023
+ * \author (original) Vy Duong
+ * \date (original) 04-Dec-2023
+ *
+ */
+
+// Qt
+import QtQuick 2.12
+import Qt.labs.folderlistmodel 2.12
+
+// Qml imports
+import "qrc:/globals"
+import "qrc:/pages"
+import "qrc:/components"
+
+/*!
+ * \brief SettingsStartSoftwareUpdate is the screen
+ * which asks for confirmation of performing a software update with the selected file
+ */
+UserConfirmation { id : _root
+ message : vDevice.startSoftwareUpdateEnabled ? qsTr("Do you want to perform the %1?").arg(title.toLowerCase())
+ : qsTr("Please wait ...")
+ itemIndex : SettingsStack.StartSoftwareUpdate
+ notificationText : vDevice.status
+
+ confirmVisible : true
+ confirmEnabled : vDevice.startSoftwareUpdateEnabled
+
+ backVisible : true
+ backEnabled : vDevice.startSoftwareUpdateEnabled
+
+ Column {
+ width : 800
+ height : 500
+ spacing : 30
+
+ anchors.centerIn: parent
+
+ Text { id : _message
+ text : _root.message
+ color : Colors.textMain
+ font.pixelSize : Fonts.fontPixelTitle
+ }
+
+ Rectangle { id: _listViewBackground
+ color : Colors.backgroundMain
+ border.color : Colors.borderButton
+ radius : Variables.dialogRadius
+ border.width : Variables.borderWidth
+ width : 800
+ height : 400
+
+ ListView { id : _usbFolderView
+ property string selectedFileName : ""
+ width : 750
+ height : 350
+ enabled : vDevice.startSoftwareUpdateEnabled
+ clip : true
+ anchors.centerIn : parent
+ spacing : 3
+ // TODO need a CPP Class model for the files, only temp for demo
+ FolderListModel { id : _usbFolder
+ property string path : "/media/usb/"
+ showDirs : false
+ sortField : FolderListModel.Time
+ folder : "file:" + path // TODO need to be in CPP
+ nameFilters: ["*"]
+ }
+ model : _usbFolder
+ delegate :_folderDelegate
+
+ Component{ id: _folderDelegate
+ Rectangle { id : _sdcFileRow
+ width : 775
+ height : 50
+ color: _usbFolderView.selectedFileName === fileName ? Colors.backgroundButtonSelect : Colors.backgroundMain
+
+ Text { id : _sdcFileNameText
+ x : 2
+ clip : true
+ width : _sdcFileRow.width
+ text : fileName
+ color : Colors.textMain
+ font.pixelSize : Fonts.fontPixelTextRectExtra
+ verticalAlignment : Text.AlignVCenter
+ horizontalAlignment : Text.AlignLeft
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked : { console.log(fileName); _usbFolderView.selectedFileName = fileName; }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ onConfirmClicked : {
+ _confirmDialog.titleText = _root.title
+ _confirmDialog.open()
+ }
+
+ Connections { target: _confirmDialog
+ function onAccepted() {
+ if ( _confirmDialog.titleText == _root.title ) { // use the title as the indication of what has been confirmed and if that is related to this function.
+ vDevice.startSoftwareUpdate = _usbFolder.path + _usbFolderView.selectedFileName // Need to set to something (ie: emtpy string) to trigger CPP code
+ }
+ }
+ }
+}
Index: sources/model/MModel.h
===================================================================
diff -u -ra7c580f0998ee781c47314384f677249cea4c4b4 -r59625af31d9009df82fa48310b54c0f247e829fc
--- sources/model/MModel.h (.../MModel.h) (revision a7c580f0998ee781c47314384f677249cea4c4b4)
+++ sources/model/MModel.h (.../MModel.h) (revision 59625af31d9009df82fa48310b54c0f247e829fc)
@@ -299,6 +299,8 @@
REGISTER_METATYPE( DeviceDecommissionResponseData ) \
REGISTER_METATYPE( DeviceUSBMountRequestData ) \
REGISTER_METATYPE( DeviceUSBMountResponseData ) \
+ REGISTER_METATYPE( DeviceStartSoftwareUpdateRequestData ) \
+ REGISTER_METATYPE( DeviceStartSoftwareUpdateResponseData ) \
/* Settings */ \
REGISTER_METATYPE( SettingsData ) \
REGISTER_METATYPE( WifiNetworkData ) \
Index: sources/storage/StorageGlobals.cpp
===================================================================
diff -u -r1a9eb2756f33ec0387dd360e5c051ed9a04b9c1c -r59625af31d9009df82fa48310b54c0f247e829fc
--- sources/storage/StorageGlobals.cpp (.../StorageGlobals.cpp) (revision 1a9eb2756f33ec0387dd360e5c051ed9a04b9c1c)
+++ sources/storage/StorageGlobals.cpp (.../StorageGlobals.cpp) (revision 59625af31d9009df82fa48310b54c0f247e829fc)
@@ -201,4 +201,7 @@
const char *USB_Unmount = "usb_unmount.sh";
const char *USB_Mount = "usb_mount.sh";
+ // Start Software Update
+ const char *Device_StartSoftwareUpdateScriptPath = "/opt/bin/upgrade_install.sh";
+
}
Index: sources/storage/StorageGlobals.h
===================================================================
diff -u -r1a9eb2756f33ec0387dd360e5c051ed9a04b9c1c -r59625af31d9009df82fa48310b54c0f247e829fc
--- sources/storage/StorageGlobals.h (.../StorageGlobals.h) (revision 1a9eb2756f33ec0387dd360e5c051ed9a04b9c1c)
+++ sources/storage/StorageGlobals.h (.../StorageGlobals.h) (revision 59625af31d9009df82fa48310b54c0f247e829fc)
@@ -141,4 +141,7 @@
extern const char *USB_Unmount;
extern const char *USB_Mount;
+ // Device Start Software Update
+ extern const char *Device_StartSoftwareUpdateScriptPath;
+
}