Index: AlarmMapping.csv =================================================================== diff -u -r200398eaf784dd2965023151086ba1939d2eb746 -r39a9d9b3930ab483df75da6c2e7bf8838fa8ff5e --- AlarmMapping.csv (.../AlarmMapping.csv) (revision 200398eaf784dd2965023151086ba1939d2eb746) +++ AlarmMapping.csv (.../AlarmMapping.csv) (revision 39a9d9b3930ab483df75da6c2e7bf8838fa8ff5e) @@ -83,7 +83,7 @@ 82,"HD syringe pump DAC write failure." 83,"HD syringe pump is running while the BP is off." 84,"HD venous pressure sensor not being read." - 85,"HD venous pressure sensor temperature out of range error." + 85,"This alarm ID is available for use." 86,"HD BP occlusion sensor not being read." 87,"DG heating invalid calibration record." 88,"DG concentrate pumps hall sensor out of range." Index: denali.pro.user =================================================================== diff -u -r200398eaf784dd2965023151086ba1939d2eb746 -r39a9d9b3930ab483df75da6c2e7bf8838fa8ff5e --- denali.pro.user (.../denali.pro.user) (revision 200398eaf784dd2965023151086ba1939d2eb746) +++ denali.pro.user (.../denali.pro.user) (revision 39a9d9b3930ab483df75da6c2e7bf8838fa8ff5e) @@ -1,6 +1,6 @@ - + EnvironmentId Index: sources/cloudsync/CloudSyncController.cpp =================================================================== diff -u -r27cc308ff5113a9386899d3c8f8b29962a8498e1 -r39a9d9b3930ab483df75da6c2e7bf8838fa8ff5e --- sources/cloudsync/CloudSyncController.cpp (.../CloudSyncController.cpp) (revision 27cc308ff5113a9386899d3c8f8b29962a8498e1) +++ sources/cloudsync/CloudSyncController.cpp (.../CloudSyncController.cpp) (revision 39a9d9b3930ab483df75da6c2e7bf8838fa8ff5e) @@ -89,8 +89,8 @@ { connect(&_DeviceController , SIGNAL(didWatchFileChange (const QString &)), this , SLOT( onWatchFileChange (const QString &))); - connect(&_MessageDispatcher , SIGNAL(didActionReceive (GuiActionType,const QVariantList &)), - this , SLOT( onActionReceive (GuiActionType,const QVariantList &))); + connect(&_MessageDispatcher , SIGNAL(didActionReceive (GuiActionType , const QVariantList &)), + this , SLOT( onActionReceive (GuiActionType , const QVariantList &))); connect(&_TreatmentLog , SIGNAL(didTreatmentLogSave(const QString &, const QString &, const QString &)), this , SLOT( onTreatmentLogSave(const QString &, const QString &, const QString &))); } @@ -166,7 +166,7 @@ { bool ok = Storage::FileHandler::makeFolder(_location); QVariantList args {}; - Errors_Enum error = eError_OK; + Errors_Enum error = eError_Unknown; if ( ! ok ) { error = eError_LogFolder; args = {{ _location }}; ok = false; goto lErr; } _date_out_File = _location + // The location @@ -190,48 +190,62 @@ { bool ok = true; QVariantList args {}; - Errors_Enum error = eError_OK; + Errors_Enum error = eError_Unknown; - QStringList lines = vContent.split('\n',QString::SkipEmptyParts); - QString buffer = lines.last(); + QStringList lines; + QString buffer; + + int index = -1; + quint32 count = 0; + + Message message; + QStringList items; + + if ( vContent.isEmpty() ) { error = eError_OutFileEmpty; ok = false; goto lErr; } + + lines = vContent.split('\n',QString::SkipEmptyParts); + buffer = lines.last(); LOG_DEBUG(QString("CloudSync Message received [%1]").arg(buffer)); - int index = -1; - Message message ; - QStringList items = buffer.split(_separator); - int count = items.count(); + items = buffer.split(_separator); + count = items.count(); // check the required message length - if ( count < eMessage_Count ) { error = eError_Count ; ok = false; goto lErr; } - index = eMessage_Timestamp ; message.timestamp = items[index].toInt (&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].toInt (&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; } // getting the parameters - for ( int index = eMessage_Count; index < message.paramCount; index++ ) { + for ( quint32 index = eMessage_Count; index < message.paramCount; index++ ) { message.params.append( items[index] ); } + message.id = CS2UI(static_cast(message.id)); vMessage = message; return true; lErr: // building the error info for each error switch (error) { - case eError_Count : args = { count , eMessage_Count }; 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_ParamCount : args = { items[index].trimmed() }; break; case eError_Parameter : args = { count - eMessage_Count , message.paramCount }; break; - default : break; + case eError_NoHistory : args = { }; break; + case eError_LogFolder : args = { }; break; + case eError_LogFileInp : args = { }; break; } LOG_DEBUG(toText(error) + " " + toInfo(error, args)); return false; @@ -246,10 +260,12 @@ */ QString CloudSyncController::toText(CloudSyncController::Errors_Enum vErrorID) { - QString text; + QString text = tr( "E,CS,Unknown Error" ) ; if ( vErrorID == 0 ) return text; switch (vErrorID) { - case eError_Count : text = tr( "E,CS,Incorrect header" ) ; break; + case eError_Unknown : ; break; + case eError_OutFileEmpty: text = tr( "E,CS,Out buffer empty" ) ; break; + case eError_HeaderCount : text = tr( "E,CS,Incorrect header" ) ; break; case eError_Timestamp : text = tr( "E,CS,Incorrect timestamp" ) ; break; case eError_Sequence : text = tr( "E,CS,Incorrect sequence" ) ; break; case eError_CRC : text = tr( "E,CS,Incorrect CRC" ) ; break; @@ -259,7 +275,6 @@ case eError_NoHistory : text = tr( "E,CS,No history available for the request" ) ; break; case eError_LogFolder : text = tr( "E,CS,The log folder cannot be created." ) ; break; case eError_LogFileInp : text = tr( "E,CS,Error writing to the input file." ) ; break; - default : text = tr( "E,CS,Unknown Error" ) ; break; } return text; } @@ -277,17 +292,20 @@ // It means it is designed to not throw out of bound error and just use "~" as a missing info argument. auto item = [=](uint i) { return vInfoItems.value(i,"~").toString(); }; - QString info = ""; + QString info = QString( "[%1]" ).arg( vErrorID ) ; switch (vErrorID) { - case eError_Count : info = QString( "[%1:%2/%3]" ).arg( vErrorID ).arg( item(0) ).arg( item(1) ) ; 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_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; - default : info = QString( "[%1]" ).arg( vErrorID ) ; break; + case eError_LogFolder : ; break; + case eError_LogFileInp : ; break; } return info; } @@ -360,20 +378,20 @@ { bool ok = true; QVariantList args ; - Errors_Enum error = eError_OK; - quint8 crc = 0; // no crc generation for now. + Errors_Enum error = eError_Unknown; QString inpBuff; _date_inp_File = _location + // The location _dateFormatted + _dateSeparator + _inp_File; // The file name inpBuff = QString::number(_secSinceEpoch); inpBuff += _separator + QString::number(_seq++); - inpBuff += _separator + QString::number(crc); + inpBuff += _separator + QString::number(generateCRC()); inpBuff += _separator + vData; inpBuff += '\n'; // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // writing the message into the buffer. + LOG_EVENT(inpBuff);// FixMe : logs empty if ( ! Storage::FileHandler::write(_date_inp_File, inpBuff) ) { error = eError_LogFileInp; args = { _date_inp_File }; ok = false; goto lErr; } return ok; @@ -384,21 +402,34 @@ /*! * \brief CloudSyncController::sendUIHistory - * \details sends a response to the cloud sync upon request from the stored history. + * \details stores the action data in history, if vData is provided, and sends a response to the cloud sync upon request from the stored history. * \param vAction - the request id, which in current design is same as the Message comes to the UI. + * \param vData - The message data * \return true if a message history is available, false otherwise. */ -bool CloudSyncController::sendUIHistory(qint32 vAction) +bool CloudSyncController::sendUIHistory(const qint32 vAction, const QVariantList &vData) { bool ok = true; QVariantList args ; - Errors_Enum error = eError_OK; - if ( ! _lastReceivedData.contains( vAction ) ) { error = eError_NoHistory; args = { vAction }; ok = false; goto lErr; } + Errors_Enum error = eError_Unknown; + qint32 messageID = UI2CS(static_cast(vAction)); + QStringList data; + + if ( ! vData.empty() ) { + // convert the data to string list + for (auto datum : vData) { data += datum.toString(); } + // store the last message data + _lastReceivedData[messageID] = data; + } + + if ( ! _lastReceivedData.contains( messageID ) ) { error = eError_NoHistory; args = { messageID }; ok = false; goto lErr; } + sendUIBuff(QString("%1,%2,%3") - .arg(vAction) - .arg(_lastReceivedData[ vAction ].count()) - .arg(_lastReceivedData[ vAction ].join(_separator))); + .arg( messageID ) + .arg( _lastReceivedData[ messageID ].count()) + .arg( _lastReceivedData[ messageID ].join(_separator)) + ); return ok; @@ -415,11 +446,6 @@ */ void CloudSyncController::onActionReceive(GuiActionType vAction, const QVariantList &vData) { - // convert the data to the string list store/fetching it out from history. - // the original vData will be used if their actual values needed. - QStringList data; - for (auto datum : vData) { data += datum.toString(); } - switch (vAction) { case GuiActionType::ID_HDOperationModeData: case GuiActionType::ID_PreTreatmentStates : @@ -429,12 +455,10 @@ // TODO: This section is the translation/mapping section // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv // preparing the message + // Same parameters will be sent for these messages for now, so data is not changed. + sendUIHistory(eMessageID_DeviceState, vData); + break; - // store the last message data - _lastReceivedData[eMessageID_DeviceState] = data; - sendUIHistory (eMessageID_DeviceState); - break; - default: break; } Index: sources/cloudsync/CloudSyncController.h =================================================================== diff -u -r27cc308ff5113a9386899d3c8f8b29962a8498e1 -r39a9d9b3930ab483df75da6c2e7bf8838fa8ff5e --- sources/cloudsync/CloudSyncController.h (.../CloudSyncController.h) (revision 27cc308ff5113a9386899d3c8f8b29962a8498e1) +++ sources/cloudsync/CloudSyncController.h (.../CloudSyncController.h) (revision 39a9d9b3930ab483df75da6c2e7bf8838fa8ff5e) @@ -69,8 +69,9 @@ quint64 _seq = 0; enum Errors_Enum { - eError_OK , - eError_Count , + eError_Unknown = 500, // Unknown error, initial error before error check + + eError_HeaderCount , eError_Timestamp , eError_Sequence , eError_CRC , @@ -82,6 +83,8 @@ eError_LogFolder , eError_LogFileInp , + + eError_OutFileEmpty , // Out file has changed from CS2UI but the content is empty. }; typedef QHash MessageList; @@ -98,26 +101,40 @@ typedef QStringList Params; struct Message { - qint64 timestamp = 0; + quint64 timestamp = 0; quint32 sequence = 0; quint8 crc = 0; qint32 id = 0; - qint64 paramCount = 0; + quint32 paramCount = 0; Params params { }; }; + enum Entity_Start_Index { + eUI = 1000, + eCS = 2000, + }; + enum MessageID_Enum { - eMessageID_DeviceInfo = 101, // CS asks for device info and UI sends back - eMessageID_WriteCredentials = 102, // CS asks to store credential and UI stores/confirms - eMessageID_ReadCredentials = 103, // CS asks for credentials and UI reads/sends - eMessageID_ResetFactory = 104, // CS asks for factory reset [no UI ack back yet] + // [ #1( ID ) <-> #2( ID ) ] Description ( #1 Requests and #2 responses ) + // Manufacturing + eMessageID_Error = 0, // [ CS(2000) <-> UI(1000) ] Error Report - eMessageID_DeviceState = 201, // CS asks for device state and UI finds the history/sends - eMessageID_PatientID = 202, // [No CS req defined] UI sends the patient ID - eMessageID_TxReport = 203, // [No CS req defined] UI sends the Tx report - eMessageID_DeviceReport = 204, // [No CS req defined] UI sends the device report + eMessageID_DeviceRegister = 1, // [ UI(1001) -> CS( ) ] Device Registration Request + eMessageID_DeviceInfo = 2, // [ CS(2002) <-> UI(1002) ] Device information Request + eMessageID_SaveCredentials = 3, // [ CS(2003) -> UI(1003) ] Save Credentials Request + eMessageID_SendCredentials = 4, // [ CS(2004) <-> UI(1004) ] Send Credentials Request + eMessageID_ResetFactory = 5, // [ CS(2005) <-> UI(1005) ] Reset Factory Request + // Deployment + eMessageID_DeviceState = 6, // [ CS(2006) <-> UI(1006) ] Device State Request - eMessageID_HeartBeat = 900, // CS sends the periodic Hb and UI can set the interval + eMessageID_TxReport = 7, // [ UI(1007) -> CS(2007) ] TxReport Notify + + // + // Subject to change so has been commented out for now + // + // eMessageID_PatientID = 202, // [No CS req defined] UI sends the patient ID + // eMessageID_DeviceReport = 204, // [No CS req defined] UI sends the device report + // eMessageID_HeartBeat = 900, // CS sends the periodic Hb and UI can set the interval }; protected: @@ -142,14 +159,20 @@ void initThread(QThread &vThread); void quitThread(); - void checkDate (); - bool addCSBuffWatch(); + quint8 generateCRC () { return 0; } // has not been implemented/decided yet + bool validateCRC () { return true; } // has not been implemented/decided yet + + void checkDate (); + bool addCSBuffWatch (); bool sendUIResponse (const QString &vContent); - bool sendUIBuff (const QString &vData); - bool sendUIHistory (qint32 vAction); + bool sendUIBuff (const QString &vData ); + bool sendUIHistory (const qint32 vAction, const QVariantList &vData = {}); bool interpret(const QString &vContent, Message &vMessage); QString toText (Errors_Enum vErrorID); QString toInfo (Errors_Enum vErrorID, const QVariantList &vInfoItems); void toLog (Errors_Enum vErrorID, const QVariantList &vInfoItems); + + qint32 UI2CS (MessageID_Enum vID) { return vID + eUI; } + qint32 CS2UI (MessageID_Enum vID) { return vID - eCS; } };