Index: sources/cloudsync/CloudSyncController.cpp =================================================================== diff -u -r6531fd93584d910ce4313638b868d5fd20e77b68 -r3f60b9a1c0b3a43ec1c5c72955dce0d80354e35c --- sources/cloudsync/CloudSyncController.cpp (.../CloudSyncController.cpp) (revision 6531fd93584d910ce4313638b868d5fd20e77b68) +++ sources/cloudsync/CloudSyncController.cpp (.../CloudSyncController.cpp) (revision 3f60b9a1c0b3a43ec1c5c72955dce0d80354e35c) @@ -200,6 +200,7 @@ Message message; QStringList items; + quint8 id; if ( vContent.isEmpty() ) { error = eError_OutFileEmpty; ok = false; goto lErr; } @@ -212,22 +213,28 @@ count = items.count(); // check the required message length - if ( count < eMessage_Count ) { error = eError_HeaderCount ; ok = false; goto lErr; } - index = eMessage_Timestamp ; message.timestamp = items[index].toUInt(&ok); if (!ok) { error = eError_Timestamp ; ok = false; goto lErr; } - index = eMessage_Sequence ; message.sequence = items[index].toUInt(&ok); if (!ok) { error = eError_Sequence ; ok = false; goto lErr; } - index = eMessage_CRC ; message.crc = items[index].toUInt(&ok); if (!ok) { error = eError_CRC ; ok = false; goto lErr; } - index = eMessage_MessageID ; message.id = items[index].toInt (&ok); if (!ok) { error = eError_MessageID ; ok = false; goto lErr; } - index = eMessage_ParamCount; message.paramCount = items[index].toUInt(&ok); if (!ok) { error = eError_ParamCount ; ok = false; goto lErr; } + if ( count < eMessage_Count ) { error = eError_HeaderCount ; ok = false; goto lErr; } + index = eMessage_Timestamp ; message.timestamp = items[index].toUInt(&ok); if (!ok) { error = eError_Timestamp ; ok = false; goto lErr; } + index = eMessage_Sequence ; message.sequence = items[index].toUInt(&ok); if (!ok) { error = eError_Sequence ; ok = false; goto lErr; } + index = eMessage_CRC ; message.crc = items[index].toUInt(&ok); if (!ok) { error = eError_CRC ; ok = false; goto lErr; } + index = eMessage_MessageID ; message.id = items[index].toInt (&ok); if (!ok) { error = eError_MessageID ; ok = false; goto lErr; } + index = eMessage_ParamCount; message.paramCount = items[index].toUInt(&ok); if (!ok) { error = eError_ParamCount ; ok = false; goto lErr; } // check the parameters count - if ( count - eMessage_Count < message.paramCount ) { error = eError_Parameter ; ok = false; goto lErr; } + if ( count - eMessage_Count != message.paramCount ) { error = eError_ParamMismatch ; ok = false; goto lErr; } + // check missing parameters + id = CS2UI(message.id); + if ( ! paramCount.contains(id)) paramCount[id] = 0; + if ( paramCount[id] != message.paramCount ) { error = eError_ParamMissing ; ok = false; goto lErr; } + + // convert the message id and check its validity message.id = CS2UI(static_cast(message.id)); - if ( eMessageID_Start > message.id || message.id > eMessageID_Count ) { error = eError_InvalidID ; ok = false; goto lErr; } + if ( eMessageID_Start > message.id || message.id > eMessageID_Count ) { error = eError_InvalidID ; ok = false; goto lErr; } // getting the parameters - for ( quint32 index = eMessage_Count; index < message.paramCount; index++ ) { + for ( quint32 index = eMessage_Count; index < eMessage_Count + message.paramCount; index++ ) { message.params.append( items[index] ); } @@ -239,19 +246,19 @@ lErr: // building the error info for each error switch (error) { - case eError_Unknown : args = { }; break; - case eError_OutFileEmpty: args = { }; break; - case eError_HeaderCount : args = { count , eMessage_Count }; break; - case eError_Timestamp : args = { items[index].trimmed() }; break; - case eError_Sequence : args = { items[index].trimmed() }; break; - case eError_CRC : args = { items[index].trimmed() }; break; - case eError_MessageID : args = { items[index].trimmed() }; break; - case eError_InvalidID : args = { items[index].trimmed() }; break; - case eError_ParamCount : args = { items[index].trimmed() }; break; - case eError_Parameter : args = { count - eMessage_Count , message.paramCount }; break; - case eError_NoHistory : args = { }; break; - case eError_LogFolder : args = { }; break; - case eError_LogFileInp : args = { }; break; + case eError_Unknown : args = { }; break; + case eError_OutFileEmpty : args = { }; break; + case eError_HeaderCount : args = { count , eMessage_Count }; break; + case eError_Timestamp : args = { items[index].trimmed() }; break; + case eError_Sequence : args = { items[index].trimmed() }; break; + case eError_CRC : args = { items[index].trimmed() }; break; + case eError_MessageID : args = { items[index].trimmed() }; break; + case eError_InvalidID : args = { items[index].trimmed() }; break; + case eError_ParamCount : args = { items[index].trimmed() }; break; + case eError_ParamMismatch : args = { count - eMessage_Count , message.paramCount }; break; + case eError_ParamMissing : args = { paramCount[message.id] , message.paramCount }; break; + // Interpreter function only handles the message parsing errors. So default can be used. + default : break; } toLog(error, args); return false; @@ -266,22 +273,27 @@ */ QString CloudSyncController::toText(CloudSyncController::Errors_Enum vErrorID) { - QString text = tr( "CS Unknown Error" ) ; - if ( vErrorID == 0 ) return text; + QString text = tr( "CS Unknown Error" ) ; + if ( vErrorID == 0 ) return text; switch (vErrorID) { - case eError_Unknown : ; break; - case eError_OutFileEmpty: text = tr( "CS Out buffer empty" ) ; break; - case eError_HeaderCount : text = tr( "CS Incorrect header" ) ; break; - case eError_Timestamp : text = tr( "CS Incorrect timestamp" ) ; break; - case eError_Sequence : text = tr( "CS Incorrect sequence" ) ; break; - case eError_CRC : text = tr( "CS Incorrect CRC" ) ; break; - case eError_MessageID : text = tr( "CS Incorrect ID" ) ; break; - case eError_InvalidID : text = tr( "CS Invalid ID" ) ; break; - case eError_ParamCount : text = tr( "CS Incorrect parameter length" ) ; break; - case eError_Parameter : text = tr( "CS Incorrect parameter count" ) ; break; - case eError_NoHistory : text = tr( "CS No history available" ) ; break; - case eError_LogFolder : text = tr( "CS The log folder cannot be created." ) ; break; - case eError_LogFileInp : text = tr( "CS Error writing to the input file." ) ; break; + case eError_Unknown : /* "CS Unknown Error" */ ; break; + case eError_OutFileEmpty : text = tr( "CS Out buffer empty" ) ; break; + case eError_HeaderCount : text = tr( "CS Incorrect header" ) ; break; + case eError_Timestamp : text = tr( "CS Incorrect timestamp" ) ; break; + case eError_Sequence : text = tr( "CS Incorrect sequence" ) ; break; + case eError_CRC : text = tr( "CS Incorrect CRC" ) ; break; + case eError_MessageID : text = tr( "CS Incorrect ID" ) ; break; + case eError_ParamCount : text = tr( "CS Incorrect parameter count" ) ; break; + case eError_InvalidID : text = tr( "CS Invalid ID" ) ; break; + case eError_ParamMismatch : text = tr( "CS Mismatch parameter count" ) ; break; + case eError_ParamMissing : text = tr( "CS Missing parameter" ) ; break; + case eError_NoHistory : text = tr( "CS No history available" ) ; break; + case eError_LogFolder : text = tr( "CS The log folder cannot be created." ) ; break; + case eError_LogFileInp : text = tr( "CS Error writing to the input file." ) ; break; + case eError_CredentialFile : text = tr( "CS The credentials file does not exist." ) ; break; + case eError_CredentialMake : text = tr( "CS The credentials folder make failed." ) ; break; + case eError_CredentialCopy : text = tr( "CS The credentials file copy failed." ) ; break; + case eError_CredentialRemove: text = tr( "CS The credentials file remove failed." ) ; break; } return text; } @@ -301,19 +313,24 @@ QString info = QString( "[%1]" ).arg( vErrorID ) ; switch (vErrorID) { - case eError_Unknown : ; break; - case eError_OutFileEmpty: ; break; - case eError_HeaderCount : info = QString( "[%1:%2/%3]" ).arg( vErrorID ).arg( item(0) ).arg( item(1) ) ; break; - case eError_Timestamp : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break; - case eError_Sequence : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break; - case eError_CRC : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break; - case eError_MessageID : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break; - case eError_InvalidID : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break; - case eError_ParamCount : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break; - case eError_Parameter : info = QString( "[%1:%2/%3]" ).arg( vErrorID ).arg( item(0) ).arg( item(1) ) ; break; - case eError_NoHistory : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break; - case eError_LogFolder : ; break; - case eError_LogFileInp : ; break; + case eError_Unknown : ; break; + case eError_OutFileEmpty : ; break; + case eError_HeaderCount : info = QString( "[%1:%2/%3]" ).arg( vErrorID ).arg( item(0) ).arg( item(1) ) ; break; + case eError_Timestamp : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break; + case eError_Sequence : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break; + case eError_CRC : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break; + case eError_MessageID : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break; + case eError_InvalidID : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break; + case eError_ParamCount : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break; + case eError_ParamMismatch : info = QString( "[%1:%2/%3]" ).arg( vErrorID ).arg( item(0) ).arg( item(1) ) ; break; + case eError_ParamMissing : info = QString( "[%1:%2/%3]" ).arg( vErrorID ).arg( item(0) ).arg( item(1) ) ; break; + case eError_NoHistory : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break; + case eError_LogFolder : ; break; + case eError_LogFileInp : ; break; + case eError_CredentialFile : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break; + case eError_CredentialMake : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break; + case eError_CredentialCopy : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break; + case eError_CredentialRemove: info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break; } return info; } @@ -351,7 +368,7 @@ bool ok = true; Message message; if ( ! interpret(vContent, message) ) return false; // The error handling internal to interpret method. - ok = sendMessage(message.id); + ok = sendMessage(message); return ok; } @@ -508,11 +525,11 @@ // Same parameters will be sent for these messages for now, so data is not changed. switch (vAction) { + // case GuiActionType::ID_PreTreatmentStates : // has not been discussed how to be sent out. + // case GuiActionType::ID_TreatmentStates : // has not been discussed how to be sent out. + // case GuiActionType::ID_PostTreatmentStates : // has not been discussed how to be sent out. + // case GuiActionType::ID_DisinfectStates : // has not been discussed how to be sent out. case GuiActionType::ID_HDOperationModeData : - case GuiActionType::ID_PreTreatmentStates : - case GuiActionType::ID_TreatmentStates : - case GuiActionType::ID_PostTreatmentStates : - case GuiActionType::ID_DisinfectStates : saveUIHistory(eMessageID_DeviceState , vData ); sendUIHistory(eMessageID_DeviceState ); // can be removed if CS doesn't need it. break; @@ -548,20 +565,20 @@ * Some messages are sent out upon request form the last received on the history and will not be asked from FW. * \return true if there is a history for that message and no error happened. */ -bool CloudSyncController::sendMessage(const qint32 vAction) { +bool CloudSyncController::sendMessage(const Message &vMessage) { bool ok = false; // this function is used int sendUIResponse, therefore the message IDs which are responses should be implemented here. - switch (vAction) { - case eMessageID_DeviceRegister : /* No Request/Response */ break; + switch (vMessage.id) { + case eMessageID_DeviceRegister : /* No Request/Response */ break; - case eMessageID_DeviceInfo : ok = sendDeviceInfo(); break; - case eMessageID_SaveCredentials : break; - case eMessageID_SendCredentials : break; - case eMessageID_ResetFactory : ok = sendResetFactory(); break; - case eMessageID_DeviceState : ok = sendDeviceState(); break; + case eMessageID_DeviceInfo : ok = sendDeviceInfo ( ); break; + case eMessageID_CredentialsSave : ok = sendCredentialsSave( vMessage ); break; + case eMessageID_CredentialsSend : ok = sendCredentialsSend( ); break; + case eMessageID_ResetFactory : ok = sendResetFactory ( ); break; + case eMessageID_DeviceState : ok = sendDeviceState ( ); break; - case eMessageID_TxReport : break; + case eMessageID_TxReport : break; } return ok; @@ -607,6 +624,57 @@ } /*! + * \brief CloudSyncController::sendCredentialsSave + * \details saves the credentials files which their location have been sent. + * \param vMessage - the message received from CloudSync + * \return true on successfully saving the files. + */ +bool CloudSyncController::sendCredentialsSave( const Message &vMessage) +{ + bool ok = true; + QString destination = QString(Storage::CloudSync_Base_Path_Name) + Storage::CloudSync_Credentials_Folder_Name; + + // create the destination folder if does not exist. + if ( ! Storage::FileHandler::makeFolder( destination ) ) { toLog(eError_CredentialMake , { }); ok = false; goto lOut; } + + // file existence has been separated from copy remove to avoid partial copy. + for ( auto fileName : vMessage.params ) { + if ( ! QFileInfo::exists(fileName) ) { toLog(eError_CredentialFile , {fileName }); ok = false; goto lOut; } + } + + if ( ok ) { + for ( auto sourceFile : vMessage.params ) { + QString fileName = QFileInfo(sourceFile).fileName(); + if ( ! QFile::copy (sourceFile, destination + fileName) ) { toLog(eError_CredentialCopy , {fileName }); ok = false; goto lOut; } + if ( ! QFile::remove(sourceFile ) ) { toLog(eError_CredentialRemove , {fileName }); ok = false; goto lOut; } + } + } + +lOut: + return ok; +} + +/*! + * \brief CloudSyncController::sendSaveCredentials + * \details saves the credentials files which their location have been sent. + * \param vMessage - the message received from CloudSync + * \return true on successfully saving the files. + */ +bool CloudSyncController::sendCredentialsSend() +{ + bool ok = true; + qint32 messageID = UI2CS(eMessageID_CredentialsSend); + QString source = QString(Storage::CloudSync_Base_Path_Name) + Storage::CloudSync_Credentials_Folder_Name; + QString destination = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/" + Storage::CloudSync_Credentials_Folder_Name; + + if ( Storage::FileHandler::copyFolder(source, destination) != 0 ) { toLog(eError_CredentialCopy , {destination }); ok = false; goto lOut; } + ok = sendUIBuff(QString("%1,1,%2").arg( messageID ).arg(destination)); + +lOut: + return ok; +} + +/*! * \brief CloudSyncController::sendDeviceRegister * \details sends the device registration request * \return true on successful send.