Index: sources/device/DeviceController.cpp =================================================================== diff -u -r5a4a26f106ba03759e3a89b19690fa678f8a3aca -r3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475 --- sources/device/DeviceController.cpp (.../DeviceController.cpp) (revision 5a4a26f106ba03759e3a89b19690fa678f8a3aca) +++ sources/device/DeviceController.cpp (.../DeviceController.cpp) (revision 3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475) @@ -410,27 +410,12 @@ * \param vDevice - USB device to be mounted (e.g. /dev/sda1) * \return true on successful mount */ -bool DeviceController::usbMount(const QString &vDevice) +void DeviceController::usbMount(const QString &vDevice) { // disabled coco begin validated: This needs user interaction to plug-in the USB device // has been tested manually - bool ok; _usbDrive = vDevice.toLatin1().constData(); - ok = ::mount(_usbDrive, USB_Mount_Point, USB_File_System, - MS_SYNCHRONOUS | - MS_NOEXEC | // Disallow program execution - MS_NODEV | - MS_NOSUID , // Setting this option on a file system prevents users from introducing privileged programs onto the system and allowing non-root users to execute them. - "") == 0; - if (ok) { - _mounted = true; - _removed = false; - LOG_DEBUG(QString("USB flash drive %1 has been mounted on %2").arg(vDevice).arg(USB_Mount_Point)); - emit didUSBDriveMount(); - } else { - usbError(vDevice); - } - return ok; + requestUSBMount(false, _usbDrive); } // disabled coco end @@ -441,21 +426,11 @@ * \param vDevice - USB device to be unmounted (e.g. /dev/sda1) * \return true on successful unmount */ -bool DeviceController::usbUmount(const QString &vDevice) +void DeviceController::usbUmount(const QString &vDevice) { // disabled coco begin validated: This needs user interaction to plug-out the USB device // has been tested manually - bool ok; - ok = ::umount(vDevice.toLatin1().constData()) == 0; - if (ok) { - _mounted = false; - LOG_DEBUG(QString("USB drive %2 unmounted").arg(vDevice)); - emit didUSBDriveUmount(); - } else { - // the error is irrelevant, commented out for now - //usbError(vDevice); - } - return ok; + requestUSBMount(true, vDevice.toLatin1().constData()); } // disabled coco end @@ -993,3 +968,71 @@ didAttributeResponse(model.data()); LOG_APPED_UI(model.data().mMessage); } + +///////////////////////////////////////////// DeviceUSBMounting +/*! + * \brief DeviceController::onAttributeRequest + * \details Calls the Usb unmount/mount script with the model data DeviceUSBRequestData + * \param vData - the model data + */ +void DeviceController::onAttributeRequest(const DeviceUSBMountRequestData &vData) +{ + Q_UNUSED(vData) + // TODO - VY ideally we don't have this function, but macros used needs it declared +} +void DeviceController::requestUSBMount(bool vIsUnmount, const QString vUSBDrive) +{ + _deviceUSBMountRequest._data.isUnmountRequest = vIsUnmount; + + // ----- check that script exists. + QString script; + if ( checkError( DeviceError::checkScript(script, (vIsUnmount ? UnmountUSB : MountUSB)), _deviceUSBMountResponse, script) ) + return; + + // ----- check if the process is not running + if ( _processUSBMount.state() != QProcess::NotRunning ) { + checkError(DeviceError::eDevice_Scripts_Error_IsRunning, _deviceUSBMountResponse); + return; + } + + // ----- run the process + int timeout_ms = 10000; + TimedProcess *timedProcess = new TimedProcess(&_processUSBMount, script, timeout_ms, {vUSBDrive, USB_Mount_Point, USB_File_System}); + timedProcess->start(); + + MDeviceUSBMountResponse model; + model._data.mAccepted = false; + model._data.mMessage = vIsUnmount ? tr("USB unmount started.") : tr("USB mount started"); + didAttributeResponse(model.data()); +} + +/*! + * \brief DeviceController::onProcessFactoryResetExitCode + * \param vExitCode + * \param vStatus + */ +void DeviceController::onProcessUSBMountExitCode(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. + MDeviceUSBMountResponse model; + QByteArray deviceInfo = _processUSBMount.readAll(); + if ( vStatus ) vExitCode = Device::DeviceError::eDevice_Scripts_Error_Status; + else deviceInfo = _processUSBMount.readAll(); + model.fromByteArray( deviceInfo, &vExitCode ); + // DEBUG: qDebug() << model._data.mMessage << deviceInfo; + didAttributeResponse(model.data()); + LOG_APPED_UI(model.data().mMessage); + + if(_deviceUSBMountRequest._data.isUnmountRequest) { + _mounted = false; +// LOG_DEBUG(QString("USB drive %2 unmounted").arg(_deviceUSBMountRequest._data.usbDrive)); + emit didUSBDriveUmount(); + } else { + _mounted = true; + _removed = false; +// LOG_DEBUG(QString("USB flash drive %1 has been mounted on %2").arg(_deviceUSBMountRequest._data.usbDrive).arg(_deviceUSBMountRequest._data.usbMountPoint)); + emit didUSBDriveMount(); + } +} Index: sources/device/DeviceController.h =================================================================== diff -u -rfb43510552969e9fb3c3f10ae693ba81ea7e8d52 -r3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475 --- sources/device/DeviceController.h (.../DeviceController.h) (revision fb43510552969e9fb3c3f10ae693ba81ea7e8d52) +++ sources/device/DeviceController.h (.../DeviceController.h) (revision 3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475) @@ -122,6 +122,9 @@ // to be able to kill the process automatically after the set time out. DEVICE_DEV_DEFINITION_LIST +public: + void requestUSBMount(bool vIsUnmount, const QString vUSBDrive); + public slots: bool init(); bool init(QThread &vThread); @@ -258,8 +261,8 @@ // ----- USB void usbCheck(); - bool usbMount (const QString &vDevice); - bool usbUmount(const QString &vDevice); + void usbMount(const QString &vDevice); + void usbUmount(const QString &vDevice); void usbRemove(); void usbError (const QString &vDevice); Index: sources/device/DeviceError.h =================================================================== diff -u -r5a4a26f106ba03759e3a89b19690fa678f8a3aca -r3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475 --- sources/device/DeviceError.h (.../DeviceError.h) (revision 5a4a26f106ba03759e3a89b19690fa678f8a3aca) +++ sources/device/DeviceError.h (.../DeviceError.h) (revision 3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475) @@ -65,6 +65,7 @@ eDevice_CryptSetup_Error , eDevice_FactoryReset_Error , eDevice_Decommission_Error , + eDevice_USBMount_Error , eDevice_Error_End Index: sources/device/DeviceGlobals.h =================================================================== diff -u -r5a4a26f106ba03759e3a89b19690fa678f8a3aca -r3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475 --- sources/device/DeviceGlobals.h (.../DeviceGlobals.h) (revision 5a4a26f106ba03759e3a89b19690fa678f8a3aca) +++ sources/device/DeviceGlobals.h (.../DeviceGlobals.h) (revision 3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475) @@ -172,6 +172,7 @@ DEVICE_DEV_PARENT ( RootSSHAccess ) \ DEVICE_DEV_PARENT ( FactoryReset ) \ DEVICE_DEV_PARENT ( Decommission ) \ + DEVICE_DEV_PARENT ( USBMount ) \ #define DEVICE_DEV_INIT_CONNECTIONS_LIST \ DEVICE_DEV_INIT_CONNECTIONS ( Brightness ) \ @@ -181,6 +182,7 @@ DEVICE_DEV_INIT_CONNECTIONS ( RootSSHAccess ) \ DEVICE_DEV_INIT_CONNECTIONS ( FactoryReset ) \ DEVICE_DEV_INIT_CONNECTIONS ( Decommission ) \ + DEVICE_DEV_INIT_CONNECTIONS ( USBMount ) \ #define DEVICE_DEV_DEFINITION_LIST \ DEVICE_DEV_DEFINITION ( Brightness ) \ @@ -190,6 +192,7 @@ DEVICE_DEV_DEFINITION ( RootSSHAccess ) \ DEVICE_DEV_DEFINITION ( FactoryReset ) \ DEVICE_DEV_DEFINITION ( Decommission ) \ + DEVICE_DEV_DEFINITION ( USBMount ) \ /* ---------------------------- APP */ @@ -201,6 +204,7 @@ DEVICE_APP_INIT_CONNECTIONS ( RootSSHAccess ) \ DEVICE_APP_INIT_CONNECTIONS ( FactoryReset ) \ DEVICE_APP_INIT_CONNECTIONS ( Decommission ) \ + DEVICE_APP_INIT_CONNECTIONS ( USBMount ) \ #define DEVICE_APP_BRIDGE_DEFINITION_LIST \ DEVICE_APP_BRIDGE_DEFINITION( Brightness ) \ @@ -210,6 +214,7 @@ DEVICE_APP_BRIDGE_DEFINITION( RootSSHAccess ) \ DEVICE_APP_BRIDGE_DEFINITION( FactoryReset ) \ DEVICE_APP_BRIDGE_DEFINITION( Decommission ) \ + DEVICE_APP_BRIDGE_DEFINITION( USBMount ) \ /* ---------------------------- GUI */ #define DEVICE_GUI_BRIDGE_DEFINITION_LIST \ @@ -220,6 +225,7 @@ DEVICE_GUI_BRIDGE_DEFINITION( RootSSHAccess ) \ DEVICE_GUI_BRIDGE_DEFINITION( FactoryReset ) \ DEVICE_GUI_BRIDGE_DEFINITION( Decommission ) \ + DEVICE_GUI_BRIDGE_DEFINITION( USBMount ) \ #define DEVICE_GUI_INIT_CONNECTIONS_LIST \ DEVICE_GUI_INIT_CONNECTIONS ( Brightness ) \ @@ -229,6 +235,7 @@ DEVICE_GUI_INIT_CONNECTIONS ( RootSSHAccess ) \ DEVICE_GUI_INIT_CONNECTIONS ( FactoryReset ) \ DEVICE_GUI_INIT_CONNECTIONS ( Decommission ) \ + DEVICE_GUI_INIT_CONNECTIONS ( USBMount ) \ /* ---------------------------- VIEW */ #define DEVICE_VIEW_INIT_CONNECTIONS_LIST \ @@ -239,4 +246,5 @@ DEVICE_VIEW_INIT_CONNECTIONS( RootSSHAccess ) \ DEVICE_VIEW_INIT_CONNECTIONS( FactoryReset ) \ DEVICE_VIEW_INIT_CONNECTIONS( Decommission ) \ + DEVICE_VIEW_INIT_CONNECTIONS( USBMount ) \ Index: sources/device/DeviceModels.cpp =================================================================== diff -u -r49b21798fb65ce44a04ae4e771ef7c3c1c119fa6 -r3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475 --- sources/device/DeviceModels.cpp (.../DeviceModels.cpp) (revision 49b21798fb65ce44a04ae4e771ef7c3c1c119fa6) +++ sources/device/DeviceModels.cpp (.../DeviceModels.cpp) (revision 3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475) @@ -252,3 +252,33 @@ lOut: return _data.mAccepted; } + +/*! + * \brief MDeviceUSBMountResponse::fromByteArray + * \details Checks the response and sets up the mode data. + * \param vExitCode - Passed script exit code + * \return true if passed. + */ +bool MDeviceUSBMountResponse::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_USBMount_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 USB unmount/mount 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 -r5a4a26f106ba03759e3a89b19690fa678f8a3aca -r3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475 --- sources/device/DeviceModels.h (.../DeviceModels.h) (revision 5a4a26f106ba03759e3a89b19690fa678f8a3aca) +++ sources/device/DeviceModels.h (.../DeviceModels.h) (revision 3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475) @@ -337,9 +337,38 @@ Data data ( ) const { return _data; } bool fromByteArray(const QByteArray &vByteArray, int *vExitCode = nullptr) override; }; -} +// ---------- MDeviceUSBMount ---------- // +/*! + * \brief The MDeviceUSBMountRequest class + * \details The model for the usb unmount/mount script call. + */ +class MDeviceUSBMountRequest : public MDeviceRequestBase { +public: + struct Data { + bool isUnmountRequest = false; + } _data; + QString toString() { + return MDeviceRequestBase::toString("USBMountRequest", { }); + } +}; + +/*! + * \brief The MDeviceUSBMountResponse class + * \details The model for the usb mount/unmount script call returned value / response. + */ +class MDeviceUSBMountResponse : public MDeviceResponseBase { +public: + struct Data : MDeviceResponseBase::Data { + } _data; + QVariantList parameters ( ) const override { return { }; } + QString infoText ( ) const override { return QString("DeviceUSBMounting"); } + Data data ( ) const { return _data; } + bool fromByteArray(const QByteArray &vByteArray, int *vExitCode = nullptr) override; +}; +} + typedef Model::MDeviceResponseBase ::Data DeviceResponseBaseData ; typedef Model::MDeviceBrightnessRequest ::Data DeviceBrightnessRequestData ; @@ -362,3 +391,6 @@ typedef Model::MDeviceDecommissionRequest ::Data DeviceDecommissionRequestData ; typedef Model::MDeviceDecommissionResponse::Data DeviceDecommissionResponseData; + +typedef Model::MDeviceUSBMountRequest ::Data DeviceUSBMountRequestData ; +typedef Model::MDeviceUSBMountResponse::Data DeviceUSBMountResponseData; Index: sources/device/DeviceView.cpp =================================================================== diff -u -r9ebd78edd3127e38ee92b2e870430f12731244bc -r3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475 --- sources/device/DeviceView.cpp (.../DeviceView.cpp) (revision 9ebd78edd3127e38ee92b2e870430f12731244bc) +++ sources/device/DeviceView.cpp (.../DeviceView.cpp) (revision 3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475) @@ -251,3 +251,37 @@ // has to be the last one response(true); } + +// ================================================= USBMount +// TODO - VY might be removed since we don't need the ATTRIBUTE to expose to QML... +void VDevice::doInitUSBMount() { + // Nothing for now. +} + +void VDevice::usbMountRequest(const QString &vCommand) { + + bool isMountCmd = vCommand == "mount"; + bool isUnmountCmd = vCommand == "unmount"; + DeviceUSBMountRequestData data; + bool ok = isMountCmd || isUnmountCmd; + if ( ! ok ) { + status(tr("Invalid USB mount request")); + } + else { + data.isUnmountRequest = isUnmountCmd; + emit didAttributeRequest(data); + } + emit didAttributeRequest(data); +} + +void VDevice::onAttributeResponse(const DeviceUSBMountResponseData &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 ); + + // has to be the last one + response(true); +} Index: sources/device/DeviceView.h =================================================================== diff -u -r9ebd78edd3127e38ee92b2e870430f12731244bc -r3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475 --- sources/device/DeviceView.h (.../DeviceView.h) (revision 9ebd78edd3127e38ee92b2e870430f12731244bc) +++ sources/device/DeviceView.h (.../DeviceView.h) (revision 3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475) @@ -58,6 +58,9 @@ ATTRIBUTE ( QString , decommission , "", Decommission ) PROPERTY ( bool , decommissionEnabled , true ) + //TODO remove- We don't really need this - VY - but removing needs more code changes to avoid compile error + ATTRIBUTE ( QString , usbMount , "", USBMount ) + VIEW_DEC_CLASS(VDevice) private: Index: sources/model/MModel.h =================================================================== diff -u -r5a4a26f106ba03759e3a89b19690fa678f8a3aca -r3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475 --- sources/model/MModel.h (.../MModel.h) (revision 5a4a26f106ba03759e3a89b19690fa678f8a3aca) +++ sources/model/MModel.h (.../MModel.h) (revision 3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475) @@ -292,6 +292,8 @@ REGISTER_METATYPE( DeviceFactoryResetResponseData ) \ REGISTER_METATYPE( DeviceDecommissionRequestData ) \ REGISTER_METATYPE( DeviceDecommissionResponseData ) \ + REGISTER_METATYPE( DeviceUSBMountRequestData ) \ + REGISTER_METATYPE( DeviceUSBMountResponseData ) \ /* Settings */ \ REGISTER_METATYPE( SettingsData ) \ REGISTER_METATYPE( WifiNetworkData ) \ Index: sources/storage/StorageGlobals.cpp =================================================================== diff -u -r1f5b2250ae70d305654d014a9aa1fd8baa29779c -r3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475 --- sources/storage/StorageGlobals.cpp (.../StorageGlobals.cpp) (revision 1f5b2250ae70d305654d014a9aa1fd8baa29779c) +++ sources/storage/StorageGlobals.cpp (.../StorageGlobals.cpp) (revision 3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475) @@ -200,4 +200,8 @@ const char *CloudSyncPath = "/var/configurations/CloudSync/credentials/"; + // USB unmount/ mount + const char *UnmountUSB = "unmountUSB.sh"; + const char *MountUSB = "mountUSB.sh"; + } Index: sources/storage/StorageGlobals.h =================================================================== diff -u -r1f5b2250ae70d305654d014a9aa1fd8baa29779c -r3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475 --- sources/storage/StorageGlobals.h (.../StorageGlobals.h) (revision 1f5b2250ae70d305654d014a9aa1fd8baa29779c) +++ sources/storage/StorageGlobals.h (.../StorageGlobals.h) (revision 3b402a2cfb9e673bf0bac3fcc8eeee75a0adc475) @@ -137,4 +137,8 @@ extern const char *CloudSyncPath; + // USB mount/unmount + extern const char *UnmountUSB; + extern const char *MountUSB; + }