/*! * * Copyright (c) 2021-2024 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 DeviceGlobals.h * \author (last) Behrouz NematiPour * \date (last) 18-Jul-2023 * \author (original) Behrouz NematiPour * \date (original) 03-Jun-2021 * */ #pragma once // Qt // Project #include "StorageGlobals.h" /* DEVICE ATTRIBUTE PROPERTY DEFINITION */ // The FLC in vATTRIBUTEFLC means First Letter Capital #define ATTRIBUTE( vTYPE, vATTRIBUTE, vDEFAULT, vATTRIBUTEFLC) \ private: \ /*! the private property member variable */ \ vTYPE _##vATTRIBUTE = vDEFAULT; \ /*! the property definition */ \ Q_PROPERTY( vTYPE vATTRIBUTE \ READ vATTRIBUTE /*! it shall only be called in bg by qml */ \ WRITE qml##vATTRIBUTE \ NOTIFY vATTRIBUTE##Changed) \ /*! the READ/getter method */ \ vTYPE vATTRIBUTE ( ) { \ return _##vATTRIBUTE; \ } \ /*! the WRITE method and it shall only be called in bg by qml */ \ void qml##vATTRIBUTE (const vTYPE & v##vATTRIBUTE ) { \ /*! This write method is not changing the actual property, And instead will send only a request to change to device, and if only device successfully changes, it will notify the view */ \ vATTRIBUTE##Request ( v##vATTRIBUTE ); \ } \ /*! the response write method and can be used in c++ response update */ \ void vATTRIBUTE (const vTYPE & v##vATTRIBUTE ) { \ if ( _##vATTRIBUTE != v##vATTRIBUTE ) { \ _##vATTRIBUTE = v##vATTRIBUTE ; \ emit vATTRIBUTE##Changed ( v##vATTRIBUTE ); \ } \ } \ public Q_SLOTS : \ /*! \ * \brief VDevice::doInit \ * \details the slot to be called to initialize the attribute. }\ */ \ void doInit##vATTRIBUTEFLC ( ); \ Q_SIGNALS: /*! the signals for property bindings(Changed) and communications */ \ void vATTRIBUTE##Changed (const vTYPE & v##vATTRIBUTE ); \ private : \ /*! \ * \brief VDevice::Request \ * \details The slot which will be called in case \ * the attribute value has been updated in the QML. \ * The updated value is wrapped in the corresponding model \ * and will be used to call the assigned script eventually. \ */ \ void vATTRIBUTE##Request (const vTYPE & v##vATTRIBUTE ); \ Q_SIGNALS : \ void didAttributeRequest (const Device##vATTRIBUTEFLC##RequestData &vData ); \ private Q_SLOTS : \ /*! \ * \brief VDevice::onAttributeResponse \ * \details The slot which will be called in case the updated value for the attribute\ * has been receive by the output of designated script. \ * \param vData - the data model containing the values. \ */ \ void onAttributeResponse(const Device##vATTRIBUTEFLC##ResponseData &vData ); \ private : /* ---------------------------- DEVICE DEFINITIONS */ /* ---------------------------- DEV */ #define DEVICE_DEV_PARENT( vATTRIBUTEFLC ) \ _process##vATTRIBUTEFLC .setParent(this); #define DEVICE_DEV_DEFINITION( vATTRIBUTEFLC ) \ QProcess _process##vATTRIBUTEFLC; \ Model::MDevice##vATTRIBUTEFLC##Request _device##vATTRIBUTEFLC##Request ; \ Model::MDevice##vATTRIBUTEFLC##Response _device##vATTRIBUTEFLC##Response; \ Q_SIGNALS : void didAttributeResponse (const Device##vATTRIBUTEFLC##ResponseData &); \ private Q_SLOTS : \ /*! \ * \brief DeviceController::onAttributeRequest \ * \details This slot will be called in case the attribute is updated in the QML, \ * to start the corresponding process and call the script assigned to it. \ */ \ void onAttributeRequest (const Device##vATTRIBUTEFLC##RequestData &vData); \ private : \ /*! \ * \brief DeviceController::onProcessExitCode \ * \details The slot which is being called once the started process is returning a value \ * as an exit code, probably from within the called script \ * \param vExitCode - the returned exit code \ * \param vStatus - the status of the process \ */ \ void process##vATTRIBUTEFLC##Response(int vExitCode, QProcess::ExitStatus vStatus, \ QProcess::ProcessChannel vChannel ); \ void process##vATTRIBUTEFLC##ReadyOut( M##Device##vATTRIBUTEFLC##Response &); \ void process##vATTRIBUTEFLC##ReadyErr( M##Device##vATTRIBUTEFLC##Response &); \ void process##vATTRIBUTEFLC##Complete( M##Device##vATTRIBUTEFLC##Response &, \ int vExitCode, QProcess::ExitStatus vStatus); \ #define DEVICE_DEV_DECLARATION( vATTRIBUTEFLC ) \ void DeviceController::process##vATTRIBUTEFLC##ReadyOut(M##Device##vATTRIBUTEFLC##Response &vModel) { \ vModel._data.mCompleted = false; \ vModel._data.mAccepted = false; \ vModel._data.mMessage = _process##vATTRIBUTEFLC.readAllStandardOutput(); \ } \ void DeviceController::process##vATTRIBUTEFLC##ReadyErr(M##Device##vATTRIBUTEFLC##Response &vModel) { \ vModel._data.mCompleted = false; \ vModel._data.mAccepted = false; \ vModel._data.mMessage = "Err:" +_process##vATTRIBUTEFLC.readAllStandardError(); \ } \ void DeviceController::process##vATTRIBUTEFLC##Complete(M##Device##vATTRIBUTEFLC##Response &vModel, \ int vExitCode, QProcess::ExitStatus vStatus) { \ vModel._data.mCompleted = true; \ vModel._data.mAccepted = false; \ if (vStatus) vExitCode = Device::DeviceError::eDevice_Scripts_Error_Status; /* CrashExit */ \ vModel.fromByteArray( vModel._data.mMessage.toLatin1(), &vExitCode ); \ } \ #define DEVICE_DEV_INIT_CONNECTIONS( vATTRIBUTEFLC ) \ /* App -> Dev //TODO: Add the error LOG connection */ \ connect(&_ApplicationController , SIGNAL(didAttributeRequest(const Device##vATTRIBUTEFLC##RequestData &)), \ this , SLOT( onAttributeRequest(const Device##vATTRIBUTEFLC##RequestData &))); \ connect(&_process##vATTRIBUTEFLC, QOverload::of(&QProcess::finished), \ this , [=](int vExitCode, QProcess::ExitStatus vStatus) { \ process##vATTRIBUTEFLC##Response(vExitCode, vStatus , QProcess::StandardOutput ); \ }); \ connect(&_process##vATTRIBUTEFLC, &QProcess::readyReadStandardOutput, \ this , [=]( ) { \ process##vATTRIBUTEFLC##Response(-1, QProcess::NormalExit, QProcess::StandardOutput ); \ }); \ connect(&_process##vATTRIBUTEFLC, &QProcess::readyReadStandardError , \ this , [=]( ) { \ process##vATTRIBUTEFLC##Response(-1, QProcess::NormalExit, QProcess::StandardError ); \ }); \ /* ---------------------------- APP */ #define DEVICE_APP_BRIDGE_DEFINITION( vATTRIBUTEFLC ) \ Q_SIGNALS : void didAttributeRequest (const Device##vATTRIBUTEFLC##RequestData &); \ private Q_SLOTS : void onAttributeRequest (const Device##vATTRIBUTEFLC##RequestData &vData) { \ /* this is a bridge only if it is required later can be removed and implemented */ \ emit didAttributeRequest(vData); /* Gui -> App */ \ } \ Q_SIGNALS : void didAttributeResponse(const Device##vATTRIBUTEFLC##ResponseData &); \ private Q_SLOTS : void onAttributeResponse(const Device##vATTRIBUTEFLC##ResponseData &vData) { \ /* this is a bridge only if it is required later can be removed and implemented */ \ emit didAttributeResponse(vData); /* Gui <- App */ \ } \ private : #define DEVICE_APP_INIT_CONNECTIONS( vATTRIBUTEFLC ) \ /* Gui -> App */ \ connect(&_GuiController , SIGNAL(didAttributeRequest (const Device##vATTRIBUTEFLC##RequestData &)), \ this , SLOT( onAttributeRequest (const Device##vATTRIBUTEFLC##RequestData &))); \ /* App <- Dev */ \ connect(&_DeviceController , SIGNAL(didAttributeResponse(const Device##vATTRIBUTEFLC##ResponseData &)), \ this , SLOT( onAttributeResponse(const Device##vATTRIBUTEFLC##ResponseData &))); /* ---------------------------- GUI */ #define DEVICE_GUI_BRIDGE_DEFINITION( vATTRIBUTEFLC ) \ Q_SIGNALS : void didAttributeRequest (const Device##vATTRIBUTEFLC##RequestData &); \ public Q_SLOTS : void doAttributeRequest (const Device##vATTRIBUTEFLC##RequestData &vData) { \ /* this is a bridge only if it is required later can be removed and implemented */ \ emit didAttributeRequest(vData); /* Gui -> App */ \ } \ Q_SIGNALS : void didAttributeResponse(const Device##vATTRIBUTEFLC##ResponseData &); \ public Q_SLOTS : void onAttributeResponse(const Device##vATTRIBUTEFLC##ResponseData &vData) { \ /* this is a bridge only if it is required later can be removed and implemented */ \ emit didAttributeResponse(vData); /* Gui <- App */ \ } \ private : #define DEVICE_GUI_INIT_CONNECTIONS( vATTRIBUTEFLC ) \ /* Gui <- App */ \ connect(&_ApplicationController, SIGNAL(didAttributeResponse(const Device##vATTRIBUTEFLC##ResponseData &)), \ this , SLOT( onAttributeResponse(const Device##vATTRIBUTEFLC##ResponseData &))); /* ---------------------------- VIEW */ #define DEVICE_VIEW_INIT_CONNECTIONS( vATTRIBUTEFLC ) \ /* to convert the value to the model and emit the signal to go to the controller (Qml -> View) */ \ connect(this , SIGNAL(didAttributeRequest (const Device##vATTRIBUTEFLC##RequestData &)), \ &_GuiController , SLOT( doAttributeRequest (const Device##vATTRIBUTEFLC##RequestData &))); \ /* View <- Gui */ \ connect(&_GuiController , SIGNAL(didAttributeResponse(const Device##vATTRIBUTEFLC##ResponseData &)), \ this , SLOT( onAttributeResponse(const Device##vATTRIBUTEFLC##ResponseData &))); /* ---------------------------- DEVICE DEFINITIONS LISTS */ /* Please list all the device attributes here for each list */ /* ---------------------------- DEV */ // All the device attributes need to be listed here to be re-parented. #define DEVICE_DEV_PARENT_LIST \ DEVICE_DEV_PARENT ( Brightness ) \ DEVICE_DEV_PARENT ( USBMount ) \ DEVICE_DEV_PARENT ( WifiList ) \ DEVICE_DEV_PARENT ( WifiInfo ) \ DEVICE_DEV_PARENT ( ConnectWifi ) \ /* DEVICE_DEV_PARENT ( BluetoothPairedReset ) \ DEVICE_DEV_PARENT ( BluetoothPairedQuery ) \ DEVICE_DEV_PARENT ( CryptSetup ) \ DEVICE_DEV_PARENT ( RootSSHAccess ) \ DEVICE_DEV_PARENT ( FactoryReset ) \ DEVICE_DEV_PARENT ( Decommission ) \ */ // All the device attributes need to be listed here to be connected to the signal slots. #define DEVICE_DEV_INIT_CONNECTIONS_LIST \ DEVICE_DEV_INIT_CONNECTIONS ( Brightness ) \ DEVICE_DEV_INIT_CONNECTIONS ( USBMount ) \ DEVICE_DEV_INIT_CONNECTIONS ( WifiList ) \ DEVICE_DEV_INIT_CONNECTIONS ( WifiInfo ) \ DEVICE_DEV_INIT_CONNECTIONS ( ConnectWifi ) \ /* DEVICE_DEV_INIT_CONNECTIONS ( BluetoothPairedReset ) \ DEVICE_DEV_INIT_CONNECTIONS ( BluetoothPairedQuery ) \ DEVICE_DEV_INIT_CONNECTIONS ( CryptSetup ) \ DEVICE_DEV_INIT_CONNECTIONS ( RootSSHAccess ) \ DEVICE_DEV_INIT_CONNECTIONS ( FactoryReset ) \ DEVICE_DEV_INIT_CONNECTIONS ( Decommission ) \ */ // All the device attributes need to be listed here to be defined with needed signal, slots, values, ... . #define DEVICE_DEV_DEFINITION_LIST \ DEVICE_DEV_DEFINITION ( Brightness ) \ DEVICE_DEV_DEFINITION ( USBMount ) \ DEVICE_DEV_DEFINITION ( WifiList ) \ DEVICE_DEV_DEFINITION ( WifiInfo ) \ DEVICE_DEV_DEFINITION ( ConnectWifi ) \ /* DEVICE_DEV_DEFINITION ( BluetoothPairedReset ) \ DEVICE_DEV_DEFINITION ( BluetoothPairedQuery ) \ DEVICE_DEV_DEFINITION ( CryptSetup ) \ DEVICE_DEV_DEFINITION ( RootSSHAccess ) \ DEVICE_DEV_DEFINITION ( FactoryReset ) \ DEVICE_DEV_DEFINITION ( Decommission ) \ */ // All the device attributes need to be listed here to be defined with needed signal, slots, values, ... . #define DEVICE_DEV_DECLARATION_LIST \ DEVICE_DEV_DECLARATION ( Brightness ) \ DEVICE_DEV_DECLARATION ( USBMount ) \ DEVICE_DEV_DECLARATION ( WifiList ) \ DEVICE_DEV_DECLARATION ( WifiInfo ) \ DEVICE_DEV_DECLARATION ( ConnectWifi ) \ /* DEVICE_DEV_DECLARATION ( BluetoothPairedReset ) \ DEVICE_DEV_DECLARATION ( BluetoothPairedQuery ) \ DEVICE_DEV_DECLARATION ( CryptSetup ) \ DEVICE_DEV_DECLARATION ( RootSSHAccess ) \ DEVICE_DEV_DECLARATION ( FactoryReset ) \ DEVICE_DEV_DECLARATION ( Decommission ) \ */ /* ---------------------------- APP */ // All the device attributes if added here will make a connection on Application controller for the following: // Gui -> App <- Dev #define DEVICE_APP_INIT_CONNECTIONS_LIST \ DEVICE_APP_INIT_CONNECTIONS ( Brightness ) \ DEVICE_APP_INIT_CONNECTIONS ( WifiList ) \ DEVICE_APP_INIT_CONNECTIONS ( WifiInfo ) \ DEVICE_APP_INIT_CONNECTIONS ( ConnectWifi ) \ /* DEVICE_APP_INIT_CONNECTIONS ( BluetoothPairedReset ) \ DEVICE_APP_INIT_CONNECTIONS ( BluetoothPairedQuery ) \ DEVICE_APP_INIT_CONNECTIONS ( CryptSetup ) \ DEVICE_APP_INIT_CONNECTIONS ( RootSSHAccess ) \ DEVICE_APP_INIT_CONNECTIONS ( Decommission ) \ DEVICE_APP_INIT_CONNECTIONS ( FactoryReset ) \ */ #define DEVICE_APP_BRIDGE_DEFINITION_LIST \ DEVICE_APP_BRIDGE_DEFINITION( Brightness ) \ DEVICE_APP_BRIDGE_DEFINITION( USBMount ) \ DEVICE_APP_BRIDGE_DEFINITION( WifiList ) \ DEVICE_APP_BRIDGE_DEFINITION( WifiInfo ) \ DEVICE_APP_BRIDGE_DEFINITION( ConnectWifi ) \ /* DEVICE_APP_BRIDGE_DEFINITION( BluetoothPairedReset ) \ DEVICE_APP_BRIDGE_DEFINITION( BluetoothPairedQuery ) \ DEVICE_APP_BRIDGE_DEFINITION( CryptSetup ) \ DEVICE_APP_BRIDGE_DEFINITION( RootSSHAccess ) \ DEVICE_APP_BRIDGE_DEFINITION( FactoryReset ) \ DEVICE_APP_BRIDGE_DEFINITION( Decommission ) \ */ /* ---------------------------- GUI */ // All the device attributes if added here will make a connection on Gui controller for the following: // Gui <- App #define DEVICE_GUI_INIT_CONNECTIONS_LIST \ DEVICE_GUI_INIT_CONNECTIONS ( Brightness ) \ DEVICE_GUI_INIT_CONNECTIONS ( WifiList ) \ DEVICE_GUI_INIT_CONNECTIONS ( WifiInfo ) \ DEVICE_GUI_INIT_CONNECTIONS ( ConnectWifi ) \ /* DEVICE_GUI_INIT_CONNECTIONS ( BluetoothPairedReset ) \ DEVICE_GUI_INIT_CONNECTIONS ( BluetoothPairedQuery ) \ DEVICE_GUI_INIT_CONNECTIONS ( CryptSetup ) \ DEVICE_GUI_INIT_CONNECTIONS ( RootSSHAccess ) \ DEVICE_GUI_INIT_CONNECTIONS ( FactoryReset ) \ DEVICE_GUI_INIT_CONNECTIONS ( Decommission ) \ */ #define DEVICE_GUI_BRIDGE_DEFINITION_LIST \ DEVICE_GUI_BRIDGE_DEFINITION( Brightness ) \ DEVICE_GUI_BRIDGE_DEFINITION( WifiList ) \ DEVICE_GUI_BRIDGE_DEFINITION( WifiInfo ) \ DEVICE_GUI_BRIDGE_DEFINITION( ConnectWifi ) \ /* DEVICE_GUI_BRIDGE_DEFINITION( BluetoothPairedReset ) \ DEVICE_GUI_BRIDGE_DEFINITION( BluetoothPairedQuery ) \ DEVICE_GUI_BRIDGE_DEFINITION( CryptSetup ) \ DEVICE_GUI_BRIDGE_DEFINITION( RootSSHAccess ) \ DEVICE_GUI_BRIDGE_DEFINITION( FactoryReset ) \ DEVICE_GUI_BRIDGE_DEFINITION( Decommission ) \ */ /* ---------------------------- VIEW */ // All the device attributes if added here will make a connection on Gui controller for the following: // Qml -> View <- Gui #define DEVICE_VIEW_INIT_CONNECTIONS_LIST \ DEVICE_VIEW_INIT_CONNECTIONS( Brightness ) \ DEVICE_VIEW_INIT_CONNECTIONS( WifiList ) \ DEVICE_VIEW_INIT_CONNECTIONS( WifiInfo ) \ DEVICE_VIEW_INIT_CONNECTIONS( ConnectWifi ) \ /* DEVICE_VIEW_INIT_CONNECTIONS( BluetoothPairedReset ) \ DEVICE_VIEW_INIT_CONNECTIONS( BluetoothPairedQuery ) \ DEVICE_VIEW_INIT_CONNECTIONS( CryptSetup ) \ DEVICE_VIEW_INIT_CONNECTIONS( RootSSHAccess ) \ DEVICE_VIEW_INIT_CONNECTIONS( FactoryReset ) \ DEVICE_VIEW_INIT_CONNECTIONS( Decommission ) \ */