/* = StarPU-Top for StarPU = Copyright (C) 2011 William Braik Yann Courtois Jean-Marie Couteyen Anthony Roy This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "communicationmanager.h" // Protocol messages delimiters const char COM_MSG_SEPARATOR = ';'; const char COM_MSG_ENDL = '\n'; CommunicationManager::CommunicationManager(QObject *parent) : QTcpSocket(parent) { static bool instanciated = false; Q_ASSERT_X(instanciated == false, "CommunicationManager's' constructor", "Singleton pattern violated - " "CommunicationManager instanciated more than once"); qDebug() << "CommunicationManager : initializing"; // Init incoming messages initInMessageStrings(); // Init outgoing messages initOutMessageStrings(); // Init session data and communication states initializeSession(); QObject::connect(this, SIGNAL(readyRead()), this, SLOT(messageReceived())); QObject::connect(this, SIGNAL(disconnected()), this, SLOT(clearDescriptions())); QObject::connect(this, SIGNAL(disconnected()), this, SLOT(initializeSession())); instanciated = true; } CommunicationManager::~CommunicationManager() { qDebug() << "CommunicationManager : terminating"; delete _dataDescriptions; delete _paramDescriptions; delete _serverDevices; } void CommunicationManager::initializeSession() { _dataDescriptions = new QList (); _paramDescriptions = new QList (); _serverDevices = new QList ; _serverInfoMsgCount = 0; _state = COM_STATE_INIT; _initServerInfoCompleted = _initDataCompleted = _initParamsCompleted = _initDevCompleted = false; } /* -------------------------------------------------------------------------- */ /* Receive messages */ /* -------------------------------------------------------------------------- */ void CommunicationManager::messageReceived() { while (canReadLine()) { QByteArray message = readLine(); QString messageString = QString(message).trimmed(); switch (_state) { case COM_STATE_INIT: { if (_beginEndMessageStrings.contains(messageString)) { parseInitMessage(messageString); } else { emit protocolError( "Unexpected message received in INIT (" + messageString + ")"); } break; } case COM_STATE_INIT_SERVERINFO: parseInitServerInfoMessage(messageString); break; case COM_STATE_INIT_DATA: parseInitDataMessage(messageString); break; case COM_STATE_INIT_PARAMS: parseInitParamsMessage(messageString); break; case COM_STATE_INIT_DEV: parseInitDevMessage(messageString); break; case COM_STATE_READY: parseReadyMessage(messageString); break; case COM_STATE_LOOP: parseLoopMessage(messageString); break; } } } /* -------------------------------------------------------------------------- */ /* Parse messages */ /* -------------------------------------------------------------------------- */ void CommunicationManager::parseInitMessage(QString messageString) { switch (_inMessageStrings.value(messageString)) { case COM_MSG_IN_SERVERINFO_BEGIN: qDebug() << "CommunicationManager : SERVERINFO BEGIN received in INIT"; _state = COM_STATE_INIT_SERVERINFO; break; case COM_MSG_IN_DATA_BEGIN: qDebug() << "CommunicationManager : DATA BEGIN received in INIT"; _state = COM_STATE_INIT_DATA; break; case COM_MSG_IN_PARAMS_BEGIN: qDebug() << "CommunicationManager : PARAMS BEGIN received in INIT"; _state = COM_STATE_INIT_PARAMS; break; case COM_MSG_IN_DEV_BEGIN: qDebug() << "CommunicationManager : DEV BEGIN received in INIT"; _state = COM_STATE_INIT_DEV; break; default: ; } } void CommunicationManager::parseInitServerInfoMessage(QString messageString) { if (_beginEndMessageStrings.contains(messageString)) { if (_inMessageStrings.value(messageString) == COM_MSG_IN_SERVERINFO_END) { qDebug() << "CommunicationManager : " "SERVERINFO END received in INIT SERVERINFO"; _initServerInfoCompleted = true; emit protoConnected(); if (isInitCompleted()) { _state = COM_STATE_READY; } else { _state = COM_STATE_INIT; } } else { emit protocolError( "Bogus message received in INIT SERVERINFO (" + messageString + ")"); } } else if (_serverInfoMsgCount == 0) { // First server info : Server ID qDebug() << "CommunicationManager : " "SERVERINFO received in INIT SERVERINFO (" << messageString + ")"; _serverID = messageString; _serverInfoMsgCount++; } else if (_serverInfoMsgCount == 1) { // Second server info : Server timestamp qDebug() << "CommunicationManager : " "SERVERTIMESTAMP received in INIT SERVERINFO (" << messageString + ")"; QString serverTimestampString = messageString; bool ok = false; qlonglong serverTimestamp = serverTimestampString.toLongLong(&ok); Q_ASSERT_X(ok == true, "CommunicationManager::parseInitServerInfoMessage()", "Bogus SERVERTIMESTAMP received in INIT SERVERINFO"); emit(sessionTimeSynchronized(serverTimestamp)); _serverTimestamp = serverTimestamp; _serverInfoMsgCount++; } } void CommunicationManager::parseInitDataMessage(QString messageString) { if (_beginEndMessageStrings.contains(messageString)) { if (_inMessageStrings.value(messageString) == COM_MSG_IN_DATA_END) { qDebug() << "CommunicationManager : DATA END received in INIT DATA"; _initDataCompleted = true; if (isInitCompleted()) { _state = COM_STATE_READY; } else { _state = COM_STATE_INIT; } } else { emit protocolError( "Bogus message received in INIT DATA (" + messageString + ")"); } } else { QStringList messageParts = messageString.split(COM_MSG_SEPARATOR); QString typeString = messageParts.at(0); QString idString = messageParts.at(1); bool ok = false; int id = idString.toInt(&ok); // Data ID Q_ASSERT_X(ok == true, "CommunicationManager::parseInitDataMessage()", "Bogus message received in INIT DATA"); QString description = messageParts.at(2); // Data description DataType type; DataWidgetType widget; // Data widget double valMax = 0., valMin = 0.; bool active; Q_ASSERT_X(_typeMessageStrings.contains(typeString), "CommunicationManager::parseInitDataMessage()", "Bogus message received in INIT DATA"); switch (_inMessageStrings.value(typeString)) { case COM_MSG_IN_TYPE_BOOL: { Q_ASSERT_X(messageParts.count() == 4, "CommunicationManager::parseInitDataMessage()", "Bogus message received in INIT DATA"); QString activeString = messageParts.at(3); Q_ASSERT_X( (activeString.compare("0") == 0) || (activeString.compare("1") == 0), "CommunicationManager::parseInitDataMessage()", "Bogus message received in INIT DATA"); if (activeString.compare("1") == 0) { active = true; } else { active = false; } type = DATA_TYPE_BOOL; widget = DEFAULT_DATA_WIDGET_BOOL; break; } case COM_MSG_IN_TYPE_INT: { Q_ASSERT_X(messageParts.count() == 6, "CommunicationManager::parseInitDataMessage()", "Bogus message received in INIT DATA"); QString activeString = messageParts.at(5); bool ok = false; int activeInt = activeString.toInt(&ok); Q_ASSERT_X(ok == true && (activeInt == 0 || activeInt == 1), "CommunicationManager::parseInitDataMessage()", "Bogus message received in INIT DATA"); if (activeInt == 1) { active = true; } else { active = false; } QString valMinString = messageParts.at(3); valMin = valMinString.toDouble(&ok); // Data ID Q_ASSERT_X(ok == true, "CommunicationManager::parseInitDataMessage()", "Bogus message received in INIT DATA"); QString valMaxString = messageParts.at(4); valMax = valMaxString.toDouble(&ok); Q_ASSERT_X(ok == true, "CommunicationManager::parseInitDataMessage()", "Bogus message received in INIT DATA"); type = DATA_TYPE_INT; widget = DEFAULT_DATA_WIDGET_INT; break; } case COM_MSG_IN_TYPE_FLOAT: { Q_ASSERT_X(messageParts.count() == 6, "CommunicationManager::parseInitDataMessage()", "Bogus message received in INIT DATA"); QString activeString = messageParts.at(5); bool ok = false; int activeInt = activeString.toInt(&ok); Q_ASSERT_X(ok == true && (activeInt == 0 || activeInt == 1), "CommunicationManager::parseInitDataMessage()", "Bogus message received in INIT DATA"); if (activeInt == 1) { active = true; } else { active = false; } QString valMinString = messageParts.at(3); valMin = valMinString.toDouble(&ok); Q_ASSERT_X(ok == true, "CommunicationManager::parseInitDataMessage()", "Bogus message received in INIT DATA"); QString valMaxString = messageParts.at(4); valMax = valMaxString.toDouble(&ok); Q_ASSERT_X(ok == true, "CommunicationManager::parseInitDataMessage()", "Bogus message received in INIT DATA"); type = DATA_TYPE_FLOAT; widget = DEFAULT_DATA_WIDGET_FLOAT; break; } default: emit protocolError( "Bogus message received in INIT DATA (" + messageString + ")"); return; } // Build the data description corresponding to this message if (active == false) { widget = DATA_WIDGET_NONE; } DataDescription *dataWidgetDescription = new DataDescription; dataWidgetDescription->id = id; dataWidgetDescription->descriptionString = description; dataWidgetDescription->type = type; dataWidgetDescription->widget = widget; dataWidgetDescription->valMin = valMin; dataWidgetDescription->valMax = valMax; _dataDescriptions->append(dataWidgetDescription); qDebug() << "CommunicationManager : " "DATA MSG successfully parsed in INIT DATA (" << messageString + ")"; } } void CommunicationManager::parseInitParamsMessage(QString messageString) { if (_beginEndMessageStrings.contains(messageString)) { if (_inMessageStrings.value(messageString) == COM_MSG_IN_PARAMS_END) { qDebug() << "CommunicationManager : " "PARAMS END received in INIT PARAMS"; _initParamsCompleted = true; if (isInitCompleted()) { _state = COM_STATE_READY; } else { _state = COM_STATE_INIT; } } else { emit protocolError( "Bogus message received in INIT PARAMS (" + messageString + ")"); } } else { QStringList messageParts = messageString.split(COM_MSG_SEPARATOR); QString typeString = messageParts.at(0); QString idString = messageParts.at(1); bool ok = false; int id = idString.toInt(&ok); // Param ID Q_ASSERT_X(ok == true, "CommunicationManager::parseInitParamsMessage()", "Bogus message received in INIT PARAMS"); QString description = messageParts.at(2); // Param description ParamType type; InteractiveWidgetType widget; bool valInitBool = false; int valInitInt = 0; double valInitDouble = 0.; int valInitEnum = 0; double valMax = 0., valMin = 0.; QStringList enumValues; Q_ASSERT_X(_typeMessageStrings.contains(typeString), "CommunicationManager::parseInitParamsMessage()", "Bogus message received in INIT PARAMS"); switch (_inMessageStrings.value(typeString)) { case COM_MSG_IN_TYPE_BOOL: { QString valInitString = messageParts.at(3); Q_ASSERT_X( messageParts.count() == 4 && (valInitString.compare("0") == 0 || valInitString.compare("1") == 1), "CommunicationManager::parseInitParamsMessage()", "Bogus message received in INIT PARAMS"); if (valInitString.compare("0") == 0) { valInitBool = false; } else { valInitBool = true; } type = PARAM_TYPE_BOOL; widget = DEFAULT_INTERACTIVE_WIDGET_BOOL; break; } case COM_MSG_IN_TYPE_INT: { Q_ASSERT_X(messageParts.count() == 6, "CommunicationManager::parseInitParamsMessage()", "Bogus message received in INIT PARAMS"); QString valInitString = messageParts.at(5); bool ok = false; valInitInt = valInitString.toInt(&ok); Q_ASSERT_X(ok == true, "CommunicationManager::parseInitParamsMessage()", "Bogus message received in INIT PARAMS"); QString valMinString = messageParts.at(3); valMin = valMinString.toDouble(&ok); Q_ASSERT_X(ok == true, "CommunicationManager::parseInitParamsMessage()", "Bogus message received in INIT PARAMS"); QString valMaxString = messageParts.at(4); valMax = valMaxString.toDouble(&ok); Q_ASSERT_X(ok == true, "CommunicationManager::parseInitParamsMessage()", "Bogus message received in INIT PARAMS"); type = PARAM_TYPE_INT; widget = DEFAULT_INTERACTIVE_WIDGET_INT; break; } case COM_MSG_IN_TYPE_FLOAT: { Q_ASSERT_X(messageParts.count() == 6, "CommunicationManager::parseInitParamsMessage()", "Bogus message received in INIT PARAMS"); QString valInitString = messageParts.at(5); bool ok = false; valInitDouble = valInitString.toDouble(&ok); Q_ASSERT_X(ok == true, "CommunicationManager::parseInitParamsMessage()", "Bogus message received in INIT PARAMS"); QString valMinString = messageParts.at(3); valMin = valMinString.toDouble(&ok); Q_ASSERT_X(ok == true, "CommunicationManager::parseInitParamsMessage()", "Bogus message received in INIT PARAMS"); QString valMaxString = messageParts.at(4); valMax = valMaxString.toDouble(&ok); Q_ASSERT_X(ok == true, "CommunicationManager::parseInitParamsMessage()", "Bogus message received in INIT PARAMS"); type = PARAM_TYPE_FLOAT; widget = DEFAULT_INTERACTIVE_WIDGET_FLOAT; break; } case COM_MSG_IN_TYPE_ENUM: { Q_ASSERT_X(messageParts.count() > 4, "CommunicationManager::parseInitParamsMessage()", "Bogus message received in INIT PARAMS"); QString valInitString = messageParts.at(messageParts.count()-1); bool ok = false; valInitEnum = valInitString.toInt(&ok); Q_ASSERT_X(ok == true, "CommunicationManager::parseInitParamsMessage()", "Bogus message received in INIT PARAMS"); QStringList values; for (int i = 3; i < messageParts.count() - 1; i++) { values << messageParts.at(i); } valMin = 0.0; valMax = messageParts.count() - 3 - 1; enumValues = values; type = PARAM_TYPE_ENUM; widget = DEFAULT_INTERACTIVE_WIDGET_ENUM; break; } default: emit protocolError( "Bogus message received in INIT PARAMS (" + messageString + ")"); return; } // Build the param description corresponding to this message ParamDescription *interactiveWidgetDescription = new ParamDescription; interactiveWidgetDescription->id = id; interactiveWidgetDescription->descriptionString = description; interactiveWidgetDescription->type = type; interactiveWidgetDescription->widget = widget; interactiveWidgetDescription->valInitBool = valInitBool; interactiveWidgetDescription->valInitInt = valInitInt; interactiveWidgetDescription->valInitDouble = valInitDouble; interactiveWidgetDescription->valInitEnum = valInitEnum; interactiveWidgetDescription->valMin = valMin; interactiveWidgetDescription->valMax = valMax; interactiveWidgetDescription->enumValues = enumValues; _paramDescriptions->append(interactiveWidgetDescription); qDebug() << "CommunicationManager : " "PARAMS MSG successfully parsed in INIT PARAMS (" << messageString + ")"; } } void CommunicationManager::parseInitDevMessage(QString messageString) { if (_beginEndMessageStrings.contains(messageString)) { if (_inMessageStrings.value(messageString) == COM_MSG_IN_DEV_END) { qDebug() << "CommunicationManager : DEV END received in INIT DEV"; _initDevCompleted = true; if (isInitCompleted()) { _state = COM_STATE_READY; } else { _state = COM_STATE_INIT; } } else { emit protocolError( "Bogus message received in INIT DEV (" + messageString + ")"); } } else { QStringList messageParts = messageString.split(COM_MSG_SEPARATOR); Q_ASSERT_X(messageParts.count() == 3, "CommunicationManager::parseInitDevMessage()", "Bogus message received in INIT DEV"); QString deviceIdString = messageParts.at(0); QString deviceTypeString = messageParts.at(1); QString deviceNameString = messageParts.at(2); bool ok = false; int deviceId = deviceIdString.toInt(&ok); Q_ASSERT_X(ok == true, "CommunicationManager::parseInitDevMessage()", "Bogus message received in INIT DEV"); starpu_top_device_type deviceType; Q_ASSERT_X( deviceTypeString.compare( _inMessageStrings.key(COM_MSG_IN_DEV_CPU)) == 0 || deviceTypeString.compare( _inMessageStrings.key(COM_MSG_IN_DEV_CUDA)) == 0 || deviceTypeString.compare( _inMessageStrings.key(COM_MSG_IN_DEV_OPENCL)) == 0 , "CommunicationManager::parseInitDevMessage()", "Bogus message received in INIT DEV"); if (deviceTypeString.compare(_inMessageStrings.key(COM_MSG_IN_DEV_CPU)) == 0) { deviceType = SERVERDEVICE_CPU; } else if (deviceTypeString.compare( _inMessageStrings.key(COM_MSG_IN_DEV_CUDA)) == 0) { deviceType = SERVERDEVICE_CUDA; } else if (deviceTypeString.compare( _inMessageStrings.key(COM_MSG_IN_DEV_OPENCL)) == 0) { deviceType = SERVERDEVICE_OPENCL; } starpu_top_device device; device.id = deviceId; device.type = deviceType; device.name = deviceNameString; _serverDevices->append(device); qDebug() << "CommunicationManager : " "DEV MSG successfully parsed in INIT DEV (" << messageString + ")"; } } void CommunicationManager::parseReadyMessage(QString messageString) { if (_inMessageStrings.value(messageString) == COM_MSG_IN_READY) { qDebug() << "CommunicationManager : READY received in READY (" << messageString + ")"; emit serverInitCompleted(_serverID, _dataDescriptions, _paramDescriptions, _serverDevices); _state = COM_STATE_LOOP; } else { QStringList messageParts = messageString.split(COM_MSG_SEPARATOR); QString head = messageParts.at(0); Q_ASSERT_X(_widgetStatusChangeMessageStrings.contains(head), "CommunicationManager::parseReadyMessage()", "Bogus message received in READY"); switch (_inMessageStrings.value(head)) { case COM_MSG_IN_SET: parseParamNotificationMessage(messageString); break; default: ; } } } void CommunicationManager::parseLoopMessage(QString messageString) { QStringList messageParts = messageString.split(COM_MSG_SEPARATOR); QString head = messageParts.at(0); if (_widgetStatusChangeMessageStrings.contains(head)) { switch (_inMessageStrings.value(head)) { case COM_MSG_IN_SET: parseParamNotificationMessage(messageString); break; default: ; } } else if (_loopMessageStrings.contains(head)) { switch (_inMessageStrings.value(head)) { case COM_MSG_IN_PREV: parseTaskPrevMessage(messageString); break; case COM_MSG_IN_SHORT_PREV: parseTaskPrevMessage(messageString); break; case COM_MSG_IN_START: parseTaskStartMessage(messageString); break; case COM_MSG_IN_SHORT_START: parseTaskStartMessage(messageString); break; case COM_MSG_IN_END: parseTaskEndMessage(messageString); break; case COM_MSG_IN_SHORT_END: parseTaskEndMessage(messageString); break; case COM_MSG_IN_UPDATE: parseDataUpdateMessage(messageString); break; case COM_MSG_IN_SHORT_UPDATE: parseDataUpdateMessage(messageString); break; default: ; } } else if (_debugMessageStrings.contains(head)) { switch (_inMessageStrings.value(head)) { case COM_MSG_IN_DEBUG: parseDebugEnabledMessage(messageString); break; case COM_MSG_IN_DEBUG_MESSAGE: parseDebugMessageMessage(messageString); break; case COM_MSG_IN_DEBUG_LOCK: parseDebugLockMessage(messageString); break; default: ; } } else { emit protocolError( "Unexpected message received in LOOP (" + messageString + ")"); } } void CommunicationManager::parseTaskPrevMessage(QString messageString) { QStringList messageParts = messageString.split(COM_MSG_SEPARATOR); if (messageParts.count() == 6) { QString taskIdString = messageParts.at(1); QString deviceIdString = messageParts.at(2); QString timestampString = messageParts.at(3); QString timestampStartString = messageParts.at(4); QString timestampEndString = messageParts.at(5); int taskId; int deviceId; qlonglong timestamp; qlonglong timestampStart; qlonglong timestampEnd; bool ok = false; taskId = taskIdString.toInt(&ok); if (ok == false) { emit protocolError( "Unexpected TASK PREV message received in LOOP (" + messageString + ")"); return; } deviceId = deviceIdString.toInt(&ok); if (ok == false) { emit protocolError( "Unexpected TASK PREV message received in LOOP (" + messageString + ")"); return; } timestamp = timestampString.toLongLong(&ok); if (ok == false) { emit protocolError( "Unexpected TASK PREV message received in LOOP (" + messageString + ")"); return; } timestampStart = timestampStartString.toLongLong(&ok); if (ok == false) { emit protocolError( "Unexpected TASK PREV message received in LOOP (" + messageString + ")"); return; } timestampEnd = timestampEndString.toLongLong(&ok); if (ok == false) { emit protocolError( "Unexpected TASK PREV message received in LOOP (" + messageString + ")"); return; } emit notifyTaskPrevUpdate(taskId, deviceId, timestamp, timestampStart, timestampEnd); qDebug() << "CommunicationManager : " "TASK PREV message successfully parsed in LOOP (" << messageString + ")"; } else { emit protocolError( "Unexpected TASK PREV message received in LOOP (" + messageString + ")"); } } void CommunicationManager::parseTaskStartMessage(QString messageString) { QStringList messageParts = messageString.split(COM_MSG_SEPARATOR); if (messageParts.count() == 4) { QString taskIdString = messageParts.at(1); QString deviceIdString = messageParts.at(2); QString timestampString = messageParts.at(3); int taskId; int deviceId; qlonglong timestamp; bool ok = false; taskId = taskIdString.toInt(&ok); if (ok == false) { emit protocolError( "Bogus TASK START message received in LOOP (" + messageString + ")"); return; } deviceId = deviceIdString.toInt(&ok); if (ok == false) { emit protocolError( "Bogus TASK START message received in LOOP (" + messageString + ")"); return; } timestamp = timestampString.toLongLong(&ok); if (ok == false) { emit protocolError( "Bogus TASK START message received in LOOP (" + messageString + ")"); return; } emit notifyTaskStartUpdate(taskId, deviceId, timestamp); qDebug() << "CommunicationManager : " "TASK START message succesfully parsed in LOOP (" << messageString + ")"; } else { emit protocolError( "Bogus TASK START message received in LOOP (" + messageString + ")"); } } void CommunicationManager::parseTaskEndMessage(QString messageString) { QStringList messageParts = messageString.split(COM_MSG_SEPARATOR); if (messageParts.count() == 3) { QString taskIdString = messageParts.at(1); QString timestampString = messageParts.at(2); int taskId; qlonglong timestamp; bool ok = false; taskId = taskIdString.toInt(&ok); if (ok == false) { emit protocolError( "Bogus TASK END message received in LOOP (" + messageString + ")"); return; } timestamp = timestampString.toLongLong(&ok); if (ok == false) { emit protocolError( "Bogus TASK END message received in LOOP (" + messageString + ")"); return; } emit notifyTaskEndUpdate(taskId, timestamp); qDebug() << "CommunicationManager : " "TASK END message successfully parsed in LOOP (" << messageString + ")"; } else { emit protocolError( "Bogus TASK END message received in LOOP (" + messageString + ")"); } } void CommunicationManager::parseDataUpdateMessage(QString messageString) { QStringList messageParts = messageString.split(COM_MSG_SEPARATOR); if (messageParts.count() == 4) { QString dataIdString = messageParts.at(1); QString timestampString = messageParts.at(3); QString dataValueString = messageParts.at(2); int dataId; qlonglong timestamp; bool ok = false; dataId = dataIdString.toInt(&ok); if (ok == false || (dataDescriptionFromId(dataId) == 0)) { emit protocolError( "Bogus UPDATE message received in LOOP (" + messageString + ")"); return; } timestamp = timestampString.toLongLong(&ok); if (ok == false) { emit protocolError( "Bogus UPDATE message received in LOOP (" + messageString + ")"); return; } switch (dataDescriptionFromId(dataId)->type) { case DATA_TYPE_BOOL: { bool dataVal; if (dataValueString.compare("0") == 0) { dataVal = false; } else if (dataValueString.compare("1") == 0) { dataVal = true; } else { emit protocolError( "Bogus UPDATE message received in LOOP (" + messageString + ")"); return; } emit notifyDataUpdate(dataId, dataVal, timestamp); break; } case DATA_TYPE_INT: { int dataVal = dataValueString.toInt(&ok); if (ok == false) { emit protocolError( "Bogus UPDATE message received in LOOP (" + messageString + ")"); return; } emit notifyDataUpdate(dataId, dataVal, timestamp); break; } case DATA_TYPE_FLOAT: { double dataVal = dataValueString.toDouble(&ok); if (ok == false) { emit protocolError( "Bogus UPDATE message received in LOOP (" + messageString + ")"); return; } emit notifyDataUpdate(dataId, dataVal, timestamp); break; } default: emit protocolError( "Bogus UPDATE message received in LOOP (" + messageString + ")"); } qDebug() << "CommunicationManager : " "UPDATE message successfully parsed in LOOP (" << messageString + ")"; } else { emit protocolError( "Bogus UPDATE message received in LOOP (" + messageString + ")"); } } void CommunicationManager::parseParamNotificationMessage(QString messageString) { QStringList messageParts = messageString.split(COM_MSG_SEPARATOR); if (messageParts.count() != 4) { emit protocolError( "Bogus SET message received (" + messageString + ")"); return; } QString paramIdString = messageParts.at(1); QString paramValueString = messageParts.at(2); QString timestampString = messageParts.at(3); int paramId; qlonglong timestamp; bool ok = false; paramId = paramIdString.toInt(&ok); if (ok == false || (paramDescriptionFromId(paramId) == 0)) { emit protocolError( "Bogus SET message received (" + messageString + ")"); return; } timestamp = timestampString.toLongLong(&ok); if (ok == false) { emit protocolError( "Bogus SET message received (" + messageString + ")"); return; } switch (paramDescriptionFromId(paramId)->type) { case PARAM_TYPE_BOOL: { bool paramVal; if (paramValueString.compare("0") == 0) { paramVal = false; } else if (paramValueString.compare("1") == 0) { paramVal = true; } else { emit protocolError( "Bogus SET message received (" + messageString + ")"); return; } emit notifyParamUpdate(paramId, paramVal, timestamp); break; } case PARAM_TYPE_INT: { int paramVal = paramValueString.toInt(&ok); if (ok == false) { emit protocolError( "Bogus SET message received (" + messageString + ")"); return; } emit notifyParamUpdate(paramId, paramVal, timestamp); break; } case PARAM_TYPE_FLOAT: { double paramVal = paramValueString.toDouble(&ok); if (ok == false) { emit protocolError( "Bogus SET message received (" + messageString + ")"); return; } emit notifyParamUpdate(paramId, paramVal, timestamp); break; } case PARAM_TYPE_ENUM: { int paramVal = paramValueString.toInt(&ok); if (ok == false) { emit protocolError( "Bogus SET message received (" + messageString + ")"); return; } emit notifyParamUpdate(paramId, paramVal, timestamp); break; } default: emit protocolError( "Bogus SET message received (" + messageString + ")"); } qDebug() << "CommunicationManager : SET successfully parsed in LOOP (" << messageString + ")"; } void CommunicationManager::parseDebugEnabledMessage(QString messageString) { QStringList messageParts = messageString.split(COM_MSG_SEPARATOR); if (messageParts.count() != 2) { emit protocolError( "Bogus DEBUG message received (" + messageString + ")"); return; } QString debugEnabledString = messageParts.at(1); if (debugEnabledString.compare(_inMessageStrings.key(COM_MSG_IN_DEBUG_ON)) == 0) { qDebug() << "CommunicationManager : DEBUG ON received (" << messageString + ")"; emit notifyDebugEnabled(true); } else if (debugEnabledString.compare( _inMessageStrings.key(COM_MSG_IN_DEBUG_OFF)) == 0) { qDebug() << "CommunicationManager : DEBUG OFF received (" << messageString + ")"; emit notifyDebugEnabled(false); } else { emit protocolError( "Bogus DEBUG message received (" + messageString + ")"); } } void CommunicationManager::parseDebugMessageMessage(QString messageString) { QStringList messageParts = messageString.split(COM_MSG_SEPARATOR); if (messageParts.count() != 2) { emit protocolError( "Bogus DEBUG message received (" + messageString + ")"); return; } QString debugMessageString = messageParts.at(1); emit notifyDebugMessage(debugMessageString); qDebug() << "CommunicationManager : DEBUG MESSAGE received (" << messageString + ")"; } void CommunicationManager::parseDebugLockMessage(QString messageString) { QStringList messageParts = messageString.split(COM_MSG_SEPARATOR); if (messageParts.count() != 2) { emit protocolError( "Bogus DEBUG message received (" + messageString + ")"); return; } QString lockMessageString = messageParts.at(1); emit notifyDebugLock(lockMessageString); qDebug() << "CommunicationManager : DEBUG LOCK received (" << messageString + ")"; } /* -------------------------------------------------------------------------- */ /* Send messages */ /* -------------------------------------------------------------------------- */ void CommunicationManager::sendMessage(QString messageString) { messageString.append(COM_MSG_ENDL); write(messageString.toAscii()); } void CommunicationManager::sendGoMessage() { sendMessage( buildGoMessage()); } void CommunicationManager::sendDataEnableMessage(int dataId) { sendMessage(buildDataEnableMessage(dataId)); } void CommunicationManager::sendDataDisableMessage(int dataId) { sendMessage(buildDataDisableMessage(dataId)); } void CommunicationManager::sendParamSetMessage(int paramId, bool paramValue) { sendMessage(buildParamSetMessage(paramId, paramValue)); } void CommunicationManager::sendParamSetMessage(int paramId, int paramValue) { sendMessage(buildParamSetMessage(paramId, paramValue)); } void CommunicationManager::sendParamSetMessage(int paramId, double paramValue) { sendMessage(buildParamSetMessage(paramId, paramValue)); } void CommunicationManager::sendDebugEnabledMessage(bool enabled) { sendMessage(buildDebugEnabledMessage(enabled)); } void CommunicationManager::sendStepMessage() { sendMessage( buildStepMessage()); } /* -------------------------------------------------------------------------- */ /* Getters */ /* -------------------------------------------------------------------------- */ CommunicationState CommunicationManager::state() const { return _state; } bool CommunicationManager::isInitCompleted() const { return (_initServerInfoCompleted && _initDataCompleted && _initParamsCompleted && _initDevCompleted); } /* -------------------------------------------------------------------------- */ /* Build messages */ /* -------------------------------------------------------------------------- */ QString CommunicationManager::buildGoMessage() { QString messageString = _outMessageStrings.value(COM_MSG_OUT_GO); return messageString; } QString CommunicationManager::buildDataEnableMessage(int dataId) { QString head = _outMessageStrings.value(COM_MSG_OUT_ENABLE); QString dataIdString = QString::number(dataId); QString messageString = head.append(COM_MSG_SEPARATOR).append(dataIdString); return messageString; } QString CommunicationManager::buildDataDisableMessage(int dataId) { QString head = _outMessageStrings.value(COM_MSG_OUT_DISABLE); QString dataIdString = QString::number(dataId); QString messageString = head.append(COM_MSG_SEPARATOR).append(dataIdString); return messageString; } QString CommunicationManager::buildParamSetMessage(int paramId, bool paramValue) { QString head = _outMessageStrings.value(COM_MSG_OUT_SET); QString paramIdString = QString::number(paramId); QString paramValueString = QString::number(paramValue ? 1 : 0); QString messageString = head.append(COM_MSG_SEPARATOR).append(paramIdString).append( COM_MSG_SEPARATOR) .append(paramValueString); return messageString; } QString CommunicationManager::buildParamSetMessage(int paramId, int paramValue) { QString head = _outMessageStrings.value(COM_MSG_OUT_SET); QString paramIdString = QString::number(paramId); QString paramValueString = QString::number(paramValue); QString messageString = head.append(COM_MSG_SEPARATOR).append(paramIdString).append( COM_MSG_SEPARATOR) .append(paramValueString); return messageString; } QString CommunicationManager::buildParamSetMessage(int paramId, double paramValue) { QString head = _outMessageStrings.value(COM_MSG_OUT_SET); QString paramIdString = QString::number(paramId); QString paramValueString = QString::number(paramValue); QString messageString = head.append(COM_MSG_SEPARATOR).append(paramIdString).append( COM_MSG_SEPARATOR) .append(paramValueString); return messageString; } QString CommunicationManager::buildDebugEnabledMessage(bool enabled) { QString head = _outMessageStrings.value(COM_MSG_OUT_DEBUG); QString debugEnabledString = (enabled ? _outMessageStrings.value( COM_MSG_OUT_DEBUG_ON) : _outMessageStrings.value( COM_MSG_OUT_DEBUG_OFF)); QString messageString = head.append(COM_MSG_SEPARATOR).append( debugEnabledString); return messageString; } QString CommunicationManager::buildStepMessage() { QString messageString = _outMessageStrings.value(COM_MSG_OUT_DEBUG_STEP); return messageString; } DataDescription *CommunicationManager::dataDescriptionFromId(int dataId) const { for (int i = 0; i < _dataDescriptions->count(); i++) { if (_dataDescriptions->at(i)->id == dataId) return _dataDescriptions->at(i); } return 0; } ParamDescription *CommunicationManager::paramDescriptionFromId(int paramId) const { for (int i = 0; i < _paramDescriptions->count(); i++) { if (_paramDescriptions->at(i)->id == paramId) return _paramDescriptions->at(i); } return 0; } void CommunicationManager::clearDescriptions() { _dataDescriptions->clear(); _paramDescriptions->clear(); } /* -------------------------------------------------------------------------- */ /* Init message strings */ /* -------------------------------------------------------------------------- */ void CommunicationManager::initInMessageStrings() { // Types _inMessageStrings.insert("BOOL", COM_MSG_IN_TYPE_BOOL); _inMessageStrings.insert("INT", COM_MSG_IN_TYPE_INT); _inMessageStrings.insert("FLOAT", COM_MSG_IN_TYPE_FLOAT); _inMessageStrings.insert("ENUM", COM_MSG_IN_TYPE_ENUM); _typeMessageStrings.insert("BOOL"); _typeMessageStrings.insert("INT"); _typeMessageStrings.insert("FLOAT"); _typeMessageStrings.insert("ENUM"); // Init server ID _inMessageStrings.insert("SERVERINFO", COM_MSG_IN_SERVERINFO_BEGIN); _inMessageStrings.insert("/SERVERINFO", COM_MSG_IN_SERVERINFO_END); _beginEndMessageStrings.insert("SERVERINFO"); _beginEndMessageStrings.insert("/SERVERINFO"); // Init data _inMessageStrings.insert("DATA", COM_MSG_IN_DATA_BEGIN); _inMessageStrings.insert("/DATA", COM_MSG_IN_DATA_END); _beginEndMessageStrings.insert("DATA"); _beginEndMessageStrings.insert("/DATA"); // Init parameters _inMessageStrings.insert("PARAMS", COM_MSG_IN_PARAMS_BEGIN); _inMessageStrings.insert("/PARAMS", COM_MSG_IN_PARAMS_END); _beginEndMessageStrings.insert("PARAMS"); _beginEndMessageStrings.insert("/PARAMS"); // Init devices _inMessageStrings.insert("DEV", COM_MSG_IN_DEV_BEGIN); _inMessageStrings.insert("/DEV", COM_MSG_IN_DEV_END); _inMessageStrings.insert("CPU", COM_MSG_IN_DEV_CPU); _inMessageStrings.insert("GPU", COM_MSG_IN_DEV_CUDA); _inMessageStrings.insert("OPENCL", COM_MSG_IN_DEV_OPENCL); _beginEndMessageStrings.insert("DEV"); _beginEndMessageStrings.insert("/DEV"); // Server ready _inMessageStrings.insert("READY", COM_MSG_IN_READY); // Widget status _inMessageStrings.insert("SET", COM_MSG_IN_SET); _widgetStatusChangeMessageStrings.insert("SET"); // Loop messages // Complete versions _inMessageStrings.insert("PREV", COM_MSG_IN_PREV); _inMessageStrings.insert("START", COM_MSG_IN_START); _inMessageStrings.insert("END", COM_MSG_IN_END); _inMessageStrings.insert("UPDATE", COM_MSG_IN_UPDATE); // Short versions _inMessageStrings.insert("P", COM_MSG_IN_SHORT_PREV); _inMessageStrings.insert("S", COM_MSG_IN_SHORT_START); _inMessageStrings.insert("E", COM_MSG_IN_SHORT_END); _inMessageStrings.insert("U", COM_MSG_IN_SHORT_UPDATE); // Complete versions _loopMessageStrings.insert("PREV"); _loopMessageStrings.insert("START"); _loopMessageStrings.insert("END"); _loopMessageStrings.insert("UPDATE"); // Short versions _loopMessageStrings.insert("P"); _loopMessageStrings.insert("S"); _loopMessageStrings.insert("E"); _loopMessageStrings.insert("U"); // Debug messages _inMessageStrings.insert("DEBUG", COM_MSG_IN_DEBUG); _inMessageStrings.insert("ON", COM_MSG_IN_DEBUG_ON); _inMessageStrings.insert("OFF", COM_MSG_IN_DEBUG_OFF); _inMessageStrings.insert("MESSAGE", COM_MSG_IN_DEBUG_MESSAGE); _inMessageStrings.insert("LOCK", COM_MSG_IN_DEBUG_LOCK); _debugMessageStrings.insert("DEBUG"); _debugMessageStrings.insert("MESSAGE"); _debugMessageStrings.insert("LOCK"); } void CommunicationManager::initOutMessageStrings() { // Launch session on server _outMessageStrings.insert(COM_MSG_OUT_GO, "GO"); // Widget status change _outMessageStrings.insert(COM_MSG_OUT_ENABLE, "ENABLE"); _outMessageStrings.insert(COM_MSG_OUT_DISABLE, "DISABLE"); _outMessageStrings.insert(COM_MSG_OUT_SET, "SET"); // Debug mode _outMessageStrings.insert(COM_MSG_OUT_DEBUG, "DEBUG"); _outMessageStrings.insert(COM_MSG_OUT_DEBUG_ON, "ON"); _outMessageStrings.insert(COM_MSG_OUT_DEBUG_OFF, "OFF"); _outMessageStrings.insert(COM_MSG_OUT_DEBUG_STEP, "STEP"); }