summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2012-07-21 21:38:03 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2012-07-21 21:38:03 -0500
commit3ecb5d9be7d2099cb75f4644bcf87441fd820fd2 (patch)
tree3ee96c4446bf79240d5017f293a56c69627d98bc
parent25abfd3c581c1098532d464ae303fd7e43fce46e (diff)
downloadulab-3ecb5d9be7d2099cb75f4644bcf87441fd820fd2.tar.gz
ulab-3ecb5d9be7d2099cb75f4644bcf87441fd820fd2.zip
Initial sensor monitor server client
-rw-r--r--clients/tde/configure.in1
-rw-r--r--clients/tde/src/part/scope/part.cpp1
-rw-r--r--clients/tde/src/part/sensormonitor/part.cpp468
-rw-r--r--clients/tde/src/part/sensormonitor/part.h90
-rw-r--r--lib/libtqtrla/src/tqtrla.cpp42
-rw-r--r--lib/libtqtrla/src/tqtrla.h22
-rw-r--r--servers/sensor_monitor_server_lin/src/Makefile.am8
-rw-r--r--servers/sensor_monitor_server_lin/src/main.cpp2
-rw-r--r--servers/sensor_monitor_server_lin/src/sensor_conn.cpp256
-rw-r--r--servers/sensor_monitor_server_lin/src/sensor_conn.h36
10 files changed, 738 insertions, 188 deletions
diff --git a/clients/tde/configure.in b/clients/tde/configure.in
index 58e7262..072a245 100644
--- a/clients/tde/configure.in
+++ b/clients/tde/configure.in
@@ -90,6 +90,7 @@ AC_CONFIG_FILES([ src/part/commanalyzer/Makefile ])
AC_CONFIG_FILES([ src/part/fpgaprogram/Makefile ])
AC_CONFIG_FILES([ src/part/fpgaview/Makefile ])
AC_CONFIG_FILES([ src/part/scope/Makefile ])
+AC_CONFIG_FILES([ src/part/sensormonitor/Makefile ])
AC_CONFIG_FILES([ src/widgets/Makefile ])
AC_OUTPUT
# Check if KDE_SET_PREFIX was called, and --prefix was passed to configure
diff --git a/clients/tde/src/part/scope/part.cpp b/clients/tde/src/part/scope/part.cpp
index 03b6b25..7e64592 100644
--- a/clients/tde/src/part/scope/part.cpp
+++ b/clients/tde/src/part/scope/part.cpp
@@ -396,6 +396,7 @@ void ScopePart::setTickerMessage(TQString message) {
} \
else { \
m_commHandlerState = ScopeState_ExternalCommandRequest; \
+ EXEC_NEXT_STATE_IMMEDIATELY \
}
#define EXEC_NEXT_STATE_IMMEDIATELY m_forcedUpdateTimer->start(0, TRUE);
diff --git a/clients/tde/src/part/sensormonitor/part.cpp b/clients/tde/src/part/sensormonitor/part.cpp
index 469f24d..31f1213 100644
--- a/clients/tde/src/part/sensormonitor/part.cpp
+++ b/clients/tde/src/part/sensormonitor/part.cpp
@@ -40,6 +40,7 @@
#include <tqvbox.h>
#include <tqsocket.h>
#include <tqmutex.h>
+#include <tqlayout.h>
#include <tqeventloop.h>
#include <tqapplication.h>
#include <tqgroupbox.h>
@@ -58,13 +59,21 @@
#define NETWORK_COMM_TIMEOUT_MS 2500
enum connectionModes {
- ModeIdle = 0
+ ModeIdle = 0,
+ ModeInterruptRequested = 1,
+ ModeGetSample = 2
};
enum connectionStates {
- ModeIdle_StateStatusRequest = 0,
- ModeIdle_StateProcessStatus = 1,
- ModeIdle_StateDelay = 2
+ ModeIdle_StateSensorListRequest = 0,
+ ModeIdle_StateProcessSensorList = 1,
+ ModeIdle_StateStatusRequest = 2,
+ ModeIdle_StateProcessStatus = 3,
+ ModeIdle_StateDelay = 4,
+ ModeIdle_StatePaused = 5,
+ ModeIdle_StateExternalRequest = 6,
+ ModeGetSample_StateSampleRequest = 7,
+ ModeGetSample_StateProcessSample = 8
};
namespace RemoteLab {
@@ -73,8 +82,103 @@ typedef KParts::GenericFactory<RemoteLab::SensorMonitorPart> Factory;
#define CLIENT_LIBRARY "libremotelab_sensormonitor"
K_EXPORT_COMPONENT_FACTORY(libremotelab_sensormonitor, RemoteLab::Factory)
+TQValueTimer::TQValueTimer(TQObject *parent, const char *name)
+ : TQTimer(parent, name)
+{
+ connect(this, SIGNAL(timeout()), this, SLOT(timeoutHandler()));
+}
+
+TQValueTimer::~TQValueTimer() {
+ //
+}
+
+void TQValueTimer::timeoutHandler() {
+ emit(valueTimeout(m_value));
+}
+
+int TQValueTimer::value() {
+ return m_value;
+}
+
+void TQValueTimer::setValue(int value) {
+ m_value = value;
+}
+
+TraceControlWidget::TraceControlWidget(TQWidget *parent, const char *name)
+ : TQWidget(parent, name), m_minimumTimeStep(0.0), m_nominalTimeStep(1.0)
+{
+ TQGridLayout *topGrid = new TQGridLayout(this);
+ m_groupBox = new TQGroupBox(this);
+ m_groupBox->setColumnLayout(0, TQt::Vertical);
+ topGrid->addMultiCellWidget(m_groupBox, 0, 0, 0, 0);
+ m_groupBox->setTitle(i18n("Unknown Channel"));
+ m_primaryLayout = new TQGridLayout(m_groupBox->layout(), KDialog::marginHint(), KDialog::spacingHint());
+
+ m_channelEnabledCheckBox = new TQCheckBox(m_groupBox);
+ connect(m_channelEnabledCheckBox, SIGNAL(clicked()), this, SLOT(enableClicked()));
+ m_channelEnabledCheckBox->setText(i18n("Enable"));
+ m_primaryLayout->addMultiCellWidget(m_channelEnabledCheckBox, 0, 0, 0, 0);
+
+ m_timestepSpinBox = new FloatSpinBox(m_groupBox);
+ m_timestepSpinBox->setFloatMax(60*60*24); // 1 day
+ connect(m_timestepSpinBox, SIGNAL(floatValueChanged(double)), this, SLOT(timestepChanged(double)));
+ m_primaryLayout->addMultiCellWidget(m_timestepSpinBox, 0, 0, 1, 1);
+
+ m_sampleTimer = new TQTimer();
+ connect(m_sampleTimer, SIGNAL(timeout()), this, SIGNAL(newSampleDesired()));
+}
+
+TraceControlWidget::~TraceControlWidget() {
+ m_sampleTimer->stop();
+ delete m_sampleTimer;
+}
+
+void TraceControlWidget::startSampleTimer(int msecs) {
+ if (m_channelEnabledCheckBox->isOn()) {
+ m_nominalTimeStep = msecs/1.0e3;
+ m_sampleTimer->start(msecs, FALSE);
+ }
+ else {
+ m_sampleTimer->stop();
+ }
+}
+
+void TraceControlWidget::stopSampleTimer() {
+ m_sampleTimer->stop();
+}
+
+void TraceControlWidget::setTraceEnabled(bool enabled) {
+ m_channelEnabledCheckBox->setChecked(enabled);
+}
+
+void TraceControlWidget::setTraceName(TQString name) {
+ m_groupBox->setTitle(name);
+}
+
+void TraceControlWidget::setTimestep(double seconds) {
+ m_nominalTimeStep = seconds;
+ m_timestepSpinBox->setFloatValue(m_nominalTimeStep);
+ startSampleTimer(m_nominalTimeStep*1.0e3);
+}
+
+void TraceControlWidget::setMinTimestep(double seconds) {
+ m_minimumTimeStep = seconds;
+ m_timestepSpinBox->setFloatMin(seconds);
+}
+
+void TraceControlWidget::enableClicked() {
+ bool enabled = m_channelEnabledCheckBox->isOn();
+ emit(enableChanged(enabled));
+ startSampleTimer(m_nominalTimeStep*1.0e3);
+}
+
+void TraceControlWidget::timestepChanged(double value) {
+ m_sampleTimer->stop();
+ startSampleTimer(value*1.0e3);
+}
+
SensorMonitorPart::SensorMonitorPart(TQWidget *parentWidget, const char *widgetName, TQObject *parent, const char *name, const TQStringList&)
- : RemoteInstrumentPart( parent, name ), m_base(NULL), m_commHandlerState(0), m_connectionActiveAndValid(false), m_tickerState(0)
+ : RemoteInstrumentPart( parent, name ), m_base(NULL), m_commHandlerState(0), m_connectionActiveAndValid(false), m_tickerState(0), stopTraceUpdate(false)
{
// Initialize important base class variables
m_clientLibraryName = CLIENT_LIBRARY;
@@ -94,12 +198,57 @@ SensorMonitorPart::SensorMonitorPart(TQWidget *parentWidget, const char *widgetN
m_pingDelayTimer = new TQTimer(this);
connect(m_pingDelayTimer, SIGNAL(timeout()), this, SLOT(mainEventLoop()));
+ // Initialize data
+ m_hdivs = 10;
+ m_vdivs = 8;
+ m_maxNumberOfTraces = 0;
+ for (int traceno=0; traceno<=MAXTRACES; traceno++) {
+ m_samplesInTrace[traceno] = 0;
+ m_channelActive[traceno] = false;
+ m_traceUnits[traceno] = "";
+ m_traceControlWidgetList[traceno] = NULL;
+ m_sampleRequestInProgress[traceno] = false;
+ }
+
// Create widgets
m_base = new SensorMonitorBase(widget());
+ m_traceControlWidgetGrid = new TQGridLayout(m_base->traceControlLayoutWidget);
+ m_traceWidget = m_base->traceWidget;
+ m_traceWidget->setSizePolicy(TQSizePolicy(TQSizePolicy::MinimumExpanding, TQSizePolicy::MinimumExpanding));
+ m_traceWidget->setNumberOfCursors(4);
+ m_traceWidget->setZoomCursorStartIndex(0);
+ m_traceWidget->setCursorOrientation(0, TQt::Horizontal);
+ m_traceWidget->setCursorOrientation(1, TQt::Horizontal);
+ m_traceWidget->setCursorOrientation(2, TQt::Vertical);
+ m_traceWidget->setCursorOrientation(3, TQt::Vertical);
+ m_traceWidget->setCursorEnabled(0, true);
+ m_traceWidget->setCursorEnabled(1, true);
+ m_traceWidget->setCursorEnabled(2, true);
+ m_traceWidget->setCursorEnabled(3, true);
+ m_traceWidget->setCursorName(0, "Cursor H1");
+ m_traceWidget->setCursorName(1, "Cursor H2");
+ m_traceWidget->setCursorName(2, "Cursor V1");
+ m_traceWidget->setCursorName(3, "Cursor V2");
+ m_traceWidget->setCursorPosition(0, 25);
+ m_traceWidget->setCursorPosition(1, 75);
+ m_traceWidget->setCursorPosition(2, 25);
+ m_traceWidget->setCursorPosition(3, 75);
+ TraceNumberList activeTraces;
+ for (uint trace=0; trace<MAXTRACES; trace++) {
+ activeTraces.append(trace);
+ }
+ m_traceWidget->setCursorActiveTraceList(0, activeTraces);
+ m_traceWidget->setCursorActiveTraceList(1, activeTraces);
+ m_traceWidget->setCursorActiveTraceList(2, activeTraces);
+ m_traceWidget->setCursorActiveTraceList(3, activeTraces);
+ m_traceWidget->setZoomBoxEnabled(true);
+
+ m_base->traceZoomWidget->setSizePolicy(TQSizePolicy(TQSizePolicy::MinimumExpanding, TQSizePolicy::MinimumExpanding));
+ connect(m_traceWidget, SIGNAL(zoomBoxChanged(const TQRectF&)), this, SLOT(updateZoomWidgetLimits(const TQRectF&)));
// Initialize widgets
- connect(m_base->runControlStartButton, SIGNAL(clicked()), this, SLOT(programStartButtonClicked()));
- connect(m_base->runControlStopButton, SIGNAL(clicked()), this, SLOT(programStopButtonClicked()));
+ connect(m_base->runControlStartButton, SIGNAL(clicked()), this, SLOT(acquisitionStartButtonClicked()));
+ connect(m_base->runControlStopButton, SIGNAL(clicked()), this, SLOT(acquisitionStopButtonClicked()));
TQTimer::singleShot(0, this, TQT_SLOT(postInit()));
}
@@ -123,6 +272,14 @@ void SensorMonitorPart::processLockouts() {
mainWidget->setEnabled(false);
}
}
+ if (stopTraceUpdate) {
+ m_base->runControlStartButton->setEnabled(true);
+ m_base->runControlStopButton->setEnabled(false);
+ }
+ else {
+ m_base->runControlStartButton->setEnabled(false);
+ m_base->runControlStopButton->setEnabled(true);
+ }
}
void SensorMonitorPart::resizeToHint() {
@@ -160,7 +317,7 @@ void SensorMonitorPart::connectionFinishedCallback() {
m_socket->processPendingData();
connect(m_socket, SIGNAL(newDataReceived()), this, SLOT(mainEventLoop()));
m_tickerState = 0;
- m_commHandlerState = ModeIdle_StateStatusRequest;
+ m_commHandlerState = ModeIdle_StateSensorListRequest;
m_commHandlerMode = ModeIdle;
m_socket->setDataTimeout(NETWORK_COMM_TIMEOUT_MS);
m_updateTimeoutTimer->start(NETWORK_COMM_TIMEOUT_MS, TRUE);
@@ -177,6 +334,9 @@ void SensorMonitorPart::connectionStatusChangedCallback() {
m_tickerState = 0; \
m_commHandlerState = ModeIdle_StateStatusRequest; \
m_commHandlerMode = ModeIdle; \
+ for (int traceno=0; traceno<=MAXTRACES; traceno++) { \
+ m_sampleRequestInProgress[traceno] = false; \
+ } \
m_socket->clearIncomingData(); \
setStatusMessage(i18n("Server ping timeout. Please verify the status of your network connection.")); \
m_updateTimeoutTimer->start(NETWORK_COMM_TIMEOUT_MS, TRUE); \
@@ -186,7 +346,14 @@ void SensorMonitorPart::connectionStatusChangedCallback() {
#define SET_WATCHDOG_TIMER if (!m_updateTimeoutTimer->isActive()) m_updateTimeoutTimer->start(NETWORK_COMM_TIMEOUT_MS, TRUE);
#define PAT_WATCHDOG_TIMER m_updateTimeoutTimer->stop(); m_updateTimeoutTimer->start(NETWORK_COMM_TIMEOUT_MS, TRUE);
-#define SET_NEXT_STATE(x) m_commHandlerState = x;
+#define SET_NEXT_STATE(x) if ((m_commHandlerMode == ModeIdle) || (m_commHandlerMode == ModeGetSample)) { \
+ m_commHandlerState = x; \
+ } \
+ else { \
+ m_commHandlerState = ModeIdle_StateExternalRequest; \
+ EXEC_NEXT_STATE_IMMEDIATELY \
+ }
+#define SET_NEXT_STATE_DATA_WAITING(x) m_commHandlerState = x;
#define EXEC_NEXT_STATE_IMMEDIATELY m_forcedUpdateTimer->start(0, TRUE);
@@ -224,17 +391,42 @@ void SensorMonitorPart::mainEventLoop() {
}
if (m_socket) {
- if (m_commHandlerMode == ModeIdle) {
+ if ((m_commHandlerMode == ModeIdle) || (m_commHandlerMode == ModeInterruptRequested)) {
// Normal operation
switch (m_commHandlerState) {
+ case ModeIdle_StateSensorListRequest:
+ PAT_WATCHDOG_TIMER
+ ds << TQString("SENSORS");
+ m_socket->writeEndOfFrame();
+ SET_NEXT_STATE_DATA_WAITING(ModeIdle_StateProcessSensorList)
+ break;
+ case ModeIdle_StateProcessSensorList:
+ if (m_socket->canReadFrame()) {
+ PAT_WATCHDOG_TIMER
+
+ ds >> m_sensorList;
+ m_socket->clearFrameTail();
+
+ m_maxNumberOfTraces = m_sensorList.count();
+ updateTraceControlWidgets();
+
+ SET_NEXT_STATE(ModeIdle_StateStatusRequest)
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else {
+ if (!m_updateTimeoutTimer->isActive()) {
+ UPDATEDISPLAY_TIMEOUT
+ }
+ }
+ break;
case ModeIdle_StateStatusRequest:
- // Get status of remote system
- // Clear buffers to synchronize frames in case of data corruption
- m_socket->clearIncomingData();
- ds << TQString("STATUS");
+ PAT_WATCHDOG_TIMER
+
+ // Ping remote system
+ ds << TQString("PING");
m_socket->writeEndOfFrame();
- SET_NEXT_STATE(ModeIdle_StateProcessStatus)
+ SET_NEXT_STATE_DATA_WAITING(ModeIdle_StateProcessStatus)
break;
case ModeIdle_StateProcessStatus:
// Get all data
@@ -249,16 +441,14 @@ void SensorMonitorPart::mainEventLoop() {
// Transfer probably failed
UPDATEDISPLAY_TIMEOUT
}
- else if (status == "IDLE") {
+ else if (status == "PONG") {
// Do nothing
}
setTickerMessage(i18n("Connected"));
- if (m_commHandlerState == ModeIdle_StateProcessStatus) {
- m_pingDelayTimer->start(250, TRUE);
- SET_NEXT_STATE(ModeIdle_StateDelay);
- }
+ m_pingDelayTimer->start(250, TRUE);
+ SET_NEXT_STATE(ModeIdle_StateDelay);
}
else {
if (!m_updateTimeoutTimer->isActive()) {
@@ -275,6 +465,67 @@ void SensorMonitorPart::mainEventLoop() {
}
PAT_WATCHDOG_TIMER
break;
+ case ModeIdle_StatePaused:
+ PAT_WATCHDOG_TIMER
+ break;
+ case ModeIdle_StateExternalRequest:
+ m_commHandlerMode = ModeGetSample;
+ m_commHandlerState = m_commHandlerNextState;
+ break;
+ }
+ }
+ else if (m_commHandlerMode == ModeGetSample) {
+ if (m_commHandlerState == ModeGetSample_StateSampleRequest) {
+ PAT_WATCHDOG_TIMER
+ ds << TQString("SAMPLE");
+ ds << m_sampleRequestIndex;
+ m_socket->writeEndOfFrame();
+ SET_NEXT_STATE_DATA_WAITING(ModeGetSample_StateProcessSample)
+ setTickerMessage(i18n("Obtaining new data point for sensor %1").arg(m_sensorList[m_sampleRequestIndex].name));
+ }
+ else if (m_commHandlerState == ModeGetSample_StateProcessSample) {
+ if (m_socket->canReadFrame()) {
+ PAT_WATCHDOG_TIMER
+
+ TQString result;
+ double newValue;
+ TQDateTime timestamp;
+
+ ds >> result;
+ if (result == "ACK") {
+ ds >> newValue;
+ ds >> timestamp;
+
+ TQDoubleArray sampleArray = m_traceWidget->samples(m_sampleRequestIndex);
+ TQDoubleArray positionArray = m_traceWidget->positions(m_sampleRequestIndex);
+ m_samplesInTrace[m_sampleRequestIndex]++;
+ sampleArray.resize(m_samplesInTrace[m_sampleRequestIndex]);
+ positionArray.resize(m_samplesInTrace[m_sampleRequestIndex]);
+ sampleArray[m_samplesInTrace[m_sampleRequestIndex]-1] = newValue;
+ positionArray[m_samplesInTrace[m_sampleRequestIndex]-1] = (timestamp.toTime_t()+(timestamp.time().msec()*1.0e-3));
+
+ m_traceWidget->setSamples(m_sampleRequestIndex, sampleArray);
+ m_traceWidget->setPositions(m_sampleRequestIndex, positionArray);
+ m_base->traceZoomWidget->setSamples(m_sampleRequestIndex, sampleArray);
+ m_base->traceZoomWidget->setPositions(m_sampleRequestIndex, positionArray);
+
+ updateGraticule();
+ m_traceWidget->repaint(false);
+ m_base->traceZoomWidget->repaint(false);
+ }
+
+ m_socket->clearFrameTail();
+ m_sampleRequestInProgress[m_sampleRequestIndex] = false;
+ m_commHandlerMode = ModeIdle;
+ m_pingDelayTimer->start(250, TRUE);
+ SET_NEXT_STATE(ModeIdle_StateDelay);
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else {
+ if (!m_updateTimeoutTimer->isActive()) {
+ UPDATEDISPLAY_TIMEOUT
+ }
+ }
}
}
@@ -288,6 +539,183 @@ void SensorMonitorPart::mainEventLoop() {
m_connectionMutex->unlock();
}
+void SensorMonitorPart::updateZoomWidgetLimits(const TQRectF& zoomRect) {
+ for (int traceno=0; traceno<m_maxNumberOfTraces; traceno++) {
+ TQRectF fullZoomRect = m_traceWidget->displayLimits(traceno);
+ double widthSpan = fullZoomRect.width()-fullZoomRect.x();
+ double heightSpan = fullZoomRect.height()-fullZoomRect.y();
+
+ TQRectF zoomLimitsRect((fullZoomRect.x()+(widthSpan*(zoomRect.x()/100.0))), (fullZoomRect.y()+(heightSpan*(zoomRect.y()/100.0))), (fullZoomRect.x()+(widthSpan*((zoomRect.x()/100.0)+(zoomRect.width()/100.0)))), (fullZoomRect.y()+(heightSpan*((zoomRect.y()/100.0)+(zoomRect.height()/100.0)))));
+
+ m_base->traceZoomWidget->setDisplayLimits(traceno, zoomLimitsRect);
+ }
+}
+
+void SensorMonitorPart::updateGraticule() {
+ m_traceWidget->setNumberOfHorizontalDivisions(m_hdivs);
+ m_traceWidget->setNumberOfVerticalDivisions(m_vdivs);
+ m_base->traceZoomWidget->setNumberOfHorizontalDivisions(m_hdivs);
+ m_base->traceZoomWidget->setNumberOfVerticalDivisions(m_vdivs);
+
+ if (m_maxNumberOfTraces > 0) m_traceWidget->setTraceColor(0, TQColor(255, 255, 255));
+ if (m_maxNumberOfTraces > 1) m_traceWidget->setTraceColor(1, TQColor(128, 255, 128));
+ if (m_maxNumberOfTraces > 2) m_traceWidget->setTraceColor(2, TQColor(255, 255, 128));
+ if (m_maxNumberOfTraces > 3) m_traceWidget->setTraceColor(3, TQColor(128, 128, 255));
+
+ if (m_maxNumberOfTraces > 0) m_base->traceZoomWidget->setTraceColor(0, TQColor(255, 255, 255));
+ if (m_maxNumberOfTraces > 1) m_base->traceZoomWidget->setTraceColor(1, TQColor(128, 255, 128));
+ if (m_maxNumberOfTraces > 2) m_base->traceZoomWidget->setTraceColor(2, TQColor(255, 255, 128));
+ if (m_maxNumberOfTraces > 3) m_base->traceZoomWidget->setTraceColor(3, TQColor(128, 128, 255));
+
+ for (int traceno=0; traceno<m_maxNumberOfTraces; traceno++) {
+ m_traceWidget->setTraceEnabled(traceno, m_channelActive[traceno]);
+ m_traceWidget->setTraceName(traceno, m_sensorList[traceno].name);
+ m_traceWidget->setTraceHorizontalUnits(traceno, "s");
+ m_traceWidget->setTraceVerticalUnits(traceno, m_sensorList[traceno].units);
+
+ m_base->traceZoomWidget->setTraceEnabled(traceno, m_channelActive[traceno], false);
+ m_base->traceZoomWidget->setTraceName(traceno, m_sensorList[traceno].name);
+ m_base->traceZoomWidget->setTraceHorizontalUnits(traceno, "s");
+ m_base->traceZoomWidget->setTraceVerticalUnits(traceno, m_sensorList[traceno].units);
+
+ m_traceWidget->setNumberOfSamples(traceno, m_samplesInTrace[traceno]);
+ m_base->traceZoomWidget->setNumberOfSamples(traceno, m_samplesInTrace[traceno]);
+
+ double starttime = 0.0;
+ double endtime = 0.0;
+ if (m_samplesInTrace[traceno] > 0) {
+ starttime = m_traceWidget->positions(traceno)[0];
+ endtime = m_traceWidget->positions(traceno)[m_samplesInTrace[traceno]-1];
+ }
+ m_traceWidget->setDisplayLimits(traceno, TQRectF(starttime, m_sensorList[traceno].max, endtime, m_sensorList[traceno].min));
+ if (m_traceControlWidgetList[traceno]) {
+ m_traceControlWidgetList[traceno]->setTraceEnabled(m_channelActive[traceno]);
+ }
+ }
+ updateZoomWidgetLimits(m_traceWidget->zoomBox());
+}
+
+void SensorMonitorPart::updateTraceControlWidgets() {
+ // Add or remove trace control widgets as needed...
+ int i;
+ for (i=0; i<m_maxNumberOfTraces;i++) {
+ if (!m_traceControlWidgetList[i]) {
+ m_traceControlWidgetList[i] = new TraceControlWidget(m_base->traceControlLayoutWidget);
+ connect(m_traceControlWidgetList[i], SIGNAL(enableChanged(bool)), this, SLOT(traceControlEnableChanged(bool)));
+ connect(m_traceControlWidgetList[i], SIGNAL(newSampleDesired()), this, SLOT(processNewSampleRequest()));
+ m_traceControlWidgetGrid->addMultiCellWidget(m_traceControlWidgetList[i], i, i, 0, 0);
+ m_traceControlWidgetList[i]->setTraceName(m_sensorList[i].name);
+ m_traceControlWidgetList[i]->show();
+ // Set sample rate
+ m_traceControlWidgetList[i]->setMinTimestep(m_sensorList[i].mininterval);
+ m_traceControlWidgetList[i]->setTimestep(m_sensorList[i].nominalinterval);
+ }
+ }
+ for (i=m_maxNumberOfTraces; i<MAXTRACES;i++) {
+ if (m_traceControlWidgetList[i]) {
+ m_traceControlWidgetGrid->remove(m_traceControlWidgetList[i]);
+ delete m_traceControlWidgetList[i];
+ }
+ }
+}
+
+void SensorMonitorPart::traceControlEnableChanged(bool enabled) {
+ int i;
+ int channel = -1;
+ const TraceControlWidget* widget = dynamic_cast<const TraceControlWidget*>(sender());
+ if (widget) {
+ for (i=0; i<MAXTRACES;i++) {
+ if (m_traceControlWidgetList[i] == widget) {
+ channel = i;
+ break;
+ }
+ }
+ if ((channel >= 0) && (channel <=MAXTRACES)) {
+ m_channelActive[channel] = enabled;
+ }
+ }
+
+ updateGraticule();
+ m_traceWidget->repaint(false);
+ m_base->traceZoomWidget->repaint(false);
+ updateTraceControlWidgets();
+}
+
+void SensorMonitorPart::processNewSampleRequest() {
+ int i;
+ int channel = -1;
+ const TraceControlWidget* widget = dynamic_cast<const TraceControlWidget*>(sender());
+ if (widget) {
+ for (i=0; i<MAXTRACES;i++) {
+ if (m_traceControlWidgetList[i] == widget) {
+ channel = i;
+ break;
+ }
+ }
+ if ((channel >= 0) && (channel <=MAXTRACES)) {
+ if (!stopTraceUpdate) {
+ if (!m_sampleRequestInProgress[channel]) {
+ m_sampleRequestInProgress[channel] = true;
+ processNewSampleRequest(channel);
+ }
+ else {
+ printf("[WARNING] Sample request made while previous sample not collected. Some data was not captured (therefore lost)...\n\r");
+ }
+ }
+ }
+ }
+}
+
+void SensorMonitorPart::processNewSampleRequest(int channel) {
+ TQValueTimer* senderTimer = const_cast<TQValueTimer*>(dynamic_cast<const TQValueTimer*>(sender()));
+ if (senderTimer) {
+ senderTimer->stop();
+ delete senderTimer;
+ }
+ if (m_commHandlerMode == ModeIdle) {
+ // Request a sample
+ if (m_commHandlerState == ModeIdle_StateDelay) {
+ m_commHandlerMode = ModeGetSample;
+ m_commHandlerState = ModeGetSample_StateSampleRequest;
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else {
+ m_commHandlerMode = ModeInterruptRequested;
+ m_commHandlerNextState = ModeGetSample_StateSampleRequest;
+ }
+ m_sampleRequestIndex = channel;
+ }
+ else {
+ // The main loop is already getting a sample
+ // Resubmit the request later on
+ TQValueTimer* timer = new TQValueTimer;
+ timer->setValue(channel);
+ connect(timer, SIGNAL(valueTimeout(int)), this, SLOT(processNewSampleRequest(int)));
+ timer->start(10, TRUE);
+ }
+}
+
+void SensorMonitorPart::acquisitionStartButtonClicked() {
+ stopTraceUpdate = false;
+ processLockouts();
+ if (m_socket) m_socket->clearIncomingData();
+ m_commHandlerMode = ModeIdle;
+ m_commHandlerState = ModeIdle_StateStatusRequest;
+ EXEC_NEXT_STATE_IMMEDIATELY
+}
+
+void SensorMonitorPart::acquisitionStopButtonClicked() {
+ stopTraceUpdate = true;
+ processLockouts();
+ for (int i=0; i<MAXTRACES;i++) {
+ m_sampleRequestInProgress[i] = false;
+ }
+ m_commHandlerMode = ModeIdle;
+ m_commHandlerState = ModeIdle_StatePaused;
+ setStatusMessage(i18n("Acquisition stopped"));
+ mainEventLoop();
+}
+
KAboutData* SensorMonitorPart::createAboutData() {
return new KAboutData( APP_NAME, I18N_NOOP( APP_PRETTYNAME ), APP_VERSION );
}
diff --git a/clients/tde/src/part/sensormonitor/part.h b/clients/tde/src/part/sensormonitor/part.h
index a6c176c..27b40a5 100644
--- a/clients/tde/src/part/sensormonitor/part.h
+++ b/clients/tde/src/part/sensormonitor/part.h
@@ -33,21 +33,83 @@
#include <kparts/statusbarextension.h>
#include <kparts/part.h>
#include <kurl.h>
-#include <kled.h>
#include <tqtrla.h>
+#include "floatspinbox.h"
+
+#define MAXTRACES 255
+
class KAboutData;
using KParts::StatusBarExtension;
class TraceWidget;
class TQSocket;
class TQTimer;
class TQMutex;
+class TQRectF;
+class TQGridLayout;
+class TQCheckBox;
+class TQGroupBox;
class TQFile;
class SensorMonitorBase;
namespace RemoteLab
{
+ class Q_EXPORT TQValueTimer : public TQTimer
+ {
+ Q_OBJECT
+
+ public:
+ TQValueTimer(TQObject *parent=0, const char *name=0);
+ ~TQValueTimer();
+ int value();
+ void setValue(int);
+
+ signals:
+ void valueTimeout(int);
+
+ private slots:
+ void timeoutHandler();
+
+ private:
+ int m_value;
+ };
+
+ class TraceControlWidget : public TQWidget
+ {
+ Q_OBJECT
+
+ public:
+ TraceControlWidget(TQWidget *parent=0, const char *name=0);
+ ~TraceControlWidget();
+
+ public:
+ void setTraceEnabled(bool enabled);
+ void setTraceName(TQString name);
+ void setTimestep(double seconds);
+ void setMinTimestep(double seconds);
+ void startSampleTimer(int msecs);
+ void stopSampleTimer();
+
+ signals:
+ void enableChanged(bool enabled);
+ void newSampleDesired();
+
+ private slots:
+ void enableClicked();
+ void timestepChanged(double);
+
+ private:
+ TQGroupBox* m_groupBox;
+ TQGridLayout* m_primaryLayout;
+ TQCheckBox* m_channelEnabledCheckBox;
+ FloatSpinBox* m_timestepSpinBox;
+ TQTimer* m_sampleTimer;
+
+ double m_minimumTimeStep;
+ double m_nominalTimeStep;
+ };
+
class SensorMonitorPart : public KParts::RemoteInstrumentPart
{
Q_OBJECT
@@ -62,6 +124,7 @@ namespace RemoteLab
public slots:
virtual bool openURL(const KURL &url);
+ void updateZoomWidgetLimits(const TQRectF& zoomRect);
private slots:
void postInit();
@@ -73,9 +136,19 @@ namespace RemoteLab
void disconnectFromServerCallback();
void connectionStatusChangedCallback();
void setTickerMessage(TQString message);
+
+ void updateGraticule();
+ void updateTraceControlWidgets();
+ void traceControlEnableChanged(bool enabled);
+ void processNewSampleRequest();
+ void processNewSampleRequest(int channel);
+ void acquisitionStartButtonClicked();
+ void acquisitionStopButtonClicked();
private:
SensorMonitorBase* m_base;
+ TraceWidget* m_traceWidget;
+ TQGridLayout* m_traceControlWidgetGrid;
TQMutex* m_connectionMutex;
TQTimer* m_pingDelayTimer;
TQTimer* m_forcedUpdateTimer;
@@ -87,9 +160,18 @@ namespace RemoteLab
int m_commHandlerNextMode;
bool m_connectionActiveAndValid;
unsigned char m_tickerState;
- TQByteArray m_programmingFileData;
- TQ_ULONG m_programmingFileTotalSize;
- TQ_ULONG m_programmingFileTransferredBytes;
+
+ bool stopTraceUpdate;
+ SensorList m_sensorList;
+ TQ_INT16 m_maxNumberOfTraces;
+ TQ_INT16 m_hdivs;
+ TQ_INT16 m_vdivs;
+ TQ_INT32 m_samplesInTrace[MAXTRACES+1];
+ bool m_channelActive[MAXTRACES+1];
+ TQString m_traceUnits[MAXTRACES+1];
+ TraceControlWidget* m_traceControlWidgetList[MAXTRACES];
+ TQ_UINT32 m_sampleRequestIndex;
+ bool m_sampleRequestInProgress[MAXTRACES+1];
};
}
diff --git a/lib/libtqtrla/src/tqtrla.cpp b/lib/libtqtrla/src/tqtrla.cpp
index 711804e..75bae5e 100644
--- a/lib/libtqtrla/src/tqtrla.cpp
+++ b/lib/libtqtrla/src/tqtrla.cpp
@@ -454,5 +454,47 @@ TQDataStream &operator>>( TQDataStream &s, StationType &st )
s >> st.description;
return s;
}
+
+/*!
+ \relates SensorType
+
+ Writes the SensorType \a str to the stream \a s.
+
+ See also \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const SensorType &st )
+{
+ s << st.index;
+ s << st.name;
+ s << st.description;
+ s << st.units;
+ s << st.min;
+ s << st.max;
+ s << st.mininterval;
+ s << st.nominalinterval;
+ return s;
+}
+
+/*!
+ \relates SensorType
+
+ Reads a SensorType from the stream \a s into SensorType \a str.
+
+ See also \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, SensorType &st )
+{
+ s >> st.index;
+ s >> st.name;
+ s >> st.description;
+ s >> st.units;
+ s >> st.min;
+ s >> st.max;
+ s >> st.mininterval;
+ s >> st.nominalinterval;
+ return s;
+}
#endif // QT_NO_DATASTREAM
diff --git a/lib/libtqtrla/src/tqtrla.h b/lib/libtqtrla/src/tqtrla.h
index be105b8..e46e2fc 100644
--- a/lib/libtqtrla/src/tqtrla.h
+++ b/lib/libtqtrla/src/tqtrla.h
@@ -163,4 +163,26 @@ typedef TQValueList<StationType> StationList;
// =============================================================================
+class SensorType
+{
+ public:
+ TQ_UINT32 index;
+ TQString name;
+ TQString description;
+ TQString units;
+ double min;
+ double max;
+ double mininterval;
+ double nominalinterval;
+};
+
+#ifndef QT_NO_DATASTREAM
+Q_EXPORT TQDataStream &operator<<(TQDataStream &, const SensorType &);
+Q_EXPORT TQDataStream &operator>>(TQDataStream &, SensorType &);
+#endif
+
+typedef TQValueList<SensorType> SensorList;
+
+// =============================================================================
+
#endif // TQTRLA_H \ No newline at end of file
diff --git a/servers/sensor_monitor_server_lin/src/Makefile.am b/servers/sensor_monitor_server_lin/src/Makefile.am
index bd6b9ee..7b28ea9 100644
--- a/servers/sensor_monitor_server_lin/src/Makefile.am
+++ b/servers/sensor_monitor_server_lin/src/Makefile.am
@@ -1,11 +1,11 @@
INCLUDES= $(all_includes) $(KDE_INCLUDES)/tde -I/usr/include/sasl
KDE_CXXFLAGS = $(USE_EXCEPTIONS)
-bin_PROGRAMS = remotefpga_fpgaprogserver
+bin_PROGRAMS = remotefpga_sensormonserver
-remotefpga_fpgaprogserver_SOURCES = main.cpp fpga_conn.cpp
+remotefpga_sensormonserver_SOURCES = main.cpp sensor_conn.cpp
-remotefpga_fpgaprogserver_METASOURCES = AUTO
-remotefpga_fpgaprogserver_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -lktexteditor -ltdekrbsocket -ltqtrla
+remotefpga_sensormonserver_METASOURCES = AUTO
+remotefpga_sensormonserver_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -lktexteditor -ltdekrbsocket -ltqtrla
KDE_OPTIONS = nofinal
diff --git a/servers/sensor_monitor_server_lin/src/main.cpp b/servers/sensor_monitor_server_lin/src/main.cpp
index 3a5012b..763c6a2 100644
--- a/servers/sensor_monitor_server_lin/src/main.cpp
+++ b/servers/sensor_monitor_server_lin/src/main.cpp
@@ -58,7 +58,7 @@ int main(int argc, char *argv[])
KSimpleConfig config(TQDir::currentDirPath() + "/remotefpga_sensormonserver.conf", false);
config.setGroup("Server");
- SensorServer fpgasvr(0, config.readNumEntry("port", 4014), &config);
+ SensorServer sensorsvr(0, config.readNumEntry("port", 4014), &config);
return app.exec();
}
diff --git a/servers/sensor_monitor_server_lin/src/sensor_conn.cpp b/servers/sensor_monitor_server_lin/src/sensor_conn.cpp
index b73e480..86b8db0 100644
--- a/servers/sensor_monitor_server_lin/src/sensor_conn.cpp
+++ b/servers/sensor_monitor_server_lin/src/sensor_conn.cpp
@@ -56,12 +56,7 @@ struct exit_exception {
};
enum connectionStates {
- StateIdle = 0,
- StateGetFileSize = 1,
- StateGetFileContents = 2,
- StateStartProgramming = 3,
- StateCheckProgrammingStatus = 4,
- StateProgammingFinished = 5
+ StateIdle = 0
};
/*
@@ -70,24 +65,37 @@ enum connectionStates {
instance of this class.
*/
SensorSocket::SensorSocket(int sock, TQObject *parent, const char *name) :
- TDEKerberosServerSocket(parent, name), m_criticalSection(0), m_loopTimer(NULL), m_config(static_cast<SensorServer*>(parent)->m_config), m_commandLoopState(StateIdle),
- m_progpipe(NULL), m_progpipefd(-1), m_progErrorFlag(false), m_progDoneFlag(false)
+ TDEKerberosServerSocket(parent, name), m_criticalSection(0), m_loopTimer(NULL), m_config(static_cast<SensorServer*>(parent)->m_config), m_commandLoopState(StateIdle)
{
// Initialize timers
m_kerberosInitTimer = new TQTimer();
connect(m_kerberosInitTimer, SIGNAL(timeout()), this, SLOT(finishKerberosHandshake()));
m_servClientTimeout = new TQTimer();
+
+ // Initialize data structures
+ int i;
+ for (i=0;i<MAX_SENSORS;i++) {
+ m_sensorMinIntervalTimers[i] = NULL;
+ }
+
+ initializeSensors();
setServiceName("remotefpga");
- line = 0;
connect(this, SIGNAL(connectionClosed()), SLOT(connectionClosedHandler()));
connect(this, SIGNAL(connectionClosed()), parent, SLOT(remoteConnectionClosed()));
setSocket(sock);
}
SensorSocket::~SensorSocket() {
+ for (int j=0;j<MAX_SENSORS;j++) {
+ if (m_sensorMinIntervalTimers[j]) {
+ m_sensorMinIntervalTimers[j]->stop();
+ delete m_sensorMinIntervalTimers[j];
+ m_sensorMinIntervalTimers[j] = NULL;
+ }
+ }
if (m_servClientTimeout) {
m_servClientTimeout->stop();
delete m_servClientTimeout;
@@ -161,6 +169,49 @@ void SensorSocket::finishKerberosHandshake() {
}
}
+void SensorSocket::initializeSensors() {
+ int i=0;
+ m_sensorList.clear();
+ m_sensorExecInfo.clear();
+ m_config->setGroup("Sensors");
+ TQStringList sensorNameList = m_config->readListEntry("active");
+ for (TQStringList::Iterator it = sensorNameList.begin(); it != sensorNameList.end(); ++it) {
+ TQString sensorName = *it;
+ if (m_config->hasGroup(TQString("Sensor %1").arg(sensorName))) {
+ SensorType st;
+ m_config->setGroup(TQString("Sensor %1").arg(sensorName));
+ st.index = i;
+ st.name = sensorName;
+ st.description = m_config->readEntry("name", i18n("<unknown>"));
+ st.units = m_config->readEntry("units", i18n("<unknown>"));
+ st.min = m_config->readDoubleNumEntry("minvalue", 0.0);
+ st.max = m_config->readDoubleNumEntry("maxvalue", 1.0);
+ st.mininterval = m_config->readDoubleNumEntry("mininterval", 1.0);
+ st.nominalinterval = m_config->readDoubleNumEntry("nominalinterval", 10.0);
+ m_sensorList.append(st);
+ m_sensorExecInfo[i] = m_config->readEntry("exec", "echo 0 && exit");
+ if (!m_sensorMinIntervalTimers[i]) m_sensorMinIntervalTimers[i] = new TQTimer();
+ m_sensorMinIntervalTimers[i]->stop();
+ printf("[DEBUG] Added new sensor %s at index %d\n\r", st.name.ascii(), st.index);
+ i++;
+ }
+ else {
+ printf("[WARNING] Unknown sensor %s specified in sensor list. Ignoring...\n\r", sensorName.ascii());
+ }
+ if (i>=MAX_SENSORS) {
+ printf("[WARNING] MAX_SENSORS (%d) exceeded. Ignoring any additional sensor definitions...\n\r", MAX_SENSORS);
+ break;
+ }
+ }
+ for (int j=i;j<MAX_SENSORS;j++) {
+ if (m_sensorMinIntervalTimers[j]) {
+ m_sensorMinIntervalTimers[j]->stop();
+ delete m_sensorMinIntervalTimers[j];
+ m_sensorMinIntervalTimers[j] = NULL;
+ }
+ }
+}
+
void SensorSocket::commandLoop() {
bool transferred_data;
@@ -168,8 +219,7 @@ void SensorSocket::commandLoop() {
try {
transferred_data = false;
if (state() == TQSocket::Connected) {
- if ((m_commandLoopState == StateIdle) || (m_commandLoopState == StateStartProgramming) || (m_commandLoopState == StateCheckProgrammingStatus) || (m_commandLoopState == StateProgammingFinished)) {
- // Certain commands can come in at any time during some operations
+ if (m_commandLoopState == StateIdle) {
if (canReadLine()) {
processPendingData();
}
@@ -178,145 +228,71 @@ void SensorSocket::commandLoop() {
ds.setPrintableData(true);
TQString command;
ds >> command;
- clearFrameTail();
- if (command == "STATUS") {
- if (m_logMessages != "") {
- ds << TQString("LOGMESSAGES");
- writeEndOfFrame();
- ds << m_logMessages;
- writeEndOfFrame();
- m_logMessages = "";
- }
- else if (m_progErrorFlag) {
- ds << TQString("ERROR");
- m_progErrorFlag = false;
- writeEndOfFrame();
- }
- else if (m_progDoneFlag) {
- ds << TQString("DONE");
- ds << m_progRetCode;
- m_progDoneFlag = false;
- writeEndOfFrame();
- }
- else if (m_commandLoopState == StateIdle) {
- ds << TQString("IDLE");
- writeEndOfFrame();
- }
- else if ((m_commandLoopState == StateStartProgramming) || (m_commandLoopState == StateCheckProgrammingStatus) || (m_commandLoopState == StateProgammingFinished)) {
- ds << TQString("PROGRAMMING");
- writeEndOfFrame();
- }
- else {
- ds << TQString("UNKNOWN");
- writeEndOfFrame();
- }
+ if (command == "SENSORS") {
+ clearFrameTail();
+ ds << m_sensorList;
+ writeEndOfFrame();
}
- else if (m_commandLoopState == StateIdle) {
- if (command == "FILE") {
- m_commandLoopState = StateGetFileSize;
+ else if (command == "SAMPLE") {
+ TQ_UINT32 sensorIndex;
+ ds >> sensorIndex;
+ clearFrameTail();
+ printf("[DEBUG] Requested sample from sensor at index %d\n\r", sensorIndex);
+ if (sensorIndex >= m_sensorList.count()) {
+ ds << TQString("NCK");
}
- else if (command == "PROGRAM") {
- m_commandLoopState = StateStartProgramming;
+ else if (m_sensorMinIntervalTimers[sensorIndex]->isActive()) {
+ ds << TQString("DLY");
}
else {
- printf("[WARNING] Received unknown command '%s'\n\r", command.ascii());
+ double sampleValue;
+ bool commandSuccess = true;
+ long long intervalMsec = (m_sensorList[sensorIndex].mininterval*1.0e3);
+ m_sensorMinIntervalTimers[sensorIndex]->start(intervalMsec, TRUE);
+ TQDateTime timestamp = TQDateTime::currentDateTime(TQt::UTC);
+ TQString command = m_sensorExecInfo[sensorIndex];
+ FILE* pipe = popen(command.ascii(), "r");
+ if (!pipe) {
+ commandSuccess = false;
+ }
+ else {
+ char buffer[1024];
+ TQString result = "";
+ while(!feof(pipe)) {
+ if (fgets(buffer, 1024, pipe) != NULL) {
+ result += buffer;
+ }
+ }
+ TQ_INT32 retcode = pclose(pipe);
+ sampleValue = result.toDouble();
+ if (retcode != 0) {
+ commandSuccess = false;
+ }
+ }
+ if (commandSuccess) {
+ ds << TQString("ACK");
+ ds << sampleValue;
+ ds << timestamp;
+ }
+ else {
+ ds << TQString("NCK");
+ }
}
+ writeEndOfFrame();
}
- transferred_data = true;
- }
- }
- if (m_commandLoopState == StateGetFileSize) {
- if (canReadLine()) {
- processPendingData();
- }
- if (canReadFrame()) {
- TQDataStream ds(this);
- ds.setPrintableData(true);
- ds >> m_programmingFileSize;
- clearFrameTail();
- m_servClientTimeout->start(NETWORK_COMM_TIMEOUT_MS, TRUE);
- m_commandLoopState = StateGetFileContents;
- }
- }
- else if (m_commandLoopState == StateGetFileContents) {
- if (canReadLine()) {
- m_servClientTimeout->start(NETWORK_COMM_TIMEOUT_MS, TRUE);
- processPendingData();
- }
- if (bytesAvailable() >= m_programmingFileSize) {
- TQByteArray fileContents(m_programmingFileSize);
- readBlock(fileContents.data(), fileContents.size());
- m_programmingFileName = TQString("/tmp/%1#%2.dat").arg(m_remoteHost).arg(port());
- TQFile outputFile(m_programmingFileName);
- if (outputFile.open(IO_ReadWrite)) {
- outputFile.writeBlock(fileContents);
- outputFile.flush();
- outputFile.close();
+ else if (command == "PING") {
+ clearFrameTail();
+ ds << TQString("PONG");
+ writeEndOfFrame();
}
- transferred_data = true;
- m_commandLoopState = StateIdle;
- }
- else {
- if (!m_servClientTimeout->isActive()) {
- m_progErrorFlag = true;
- transferred_data = true;
- m_commandLoopState = StateIdle;
+ else {
+ clearFrameTail();
+ printf("[WARNING] Received unknown command %s from host %s\n\r", command.ascii(), m_remoteHost.ascii()); fflush(stdout);
+ ds << TQString("NCK");
+ writeEndOfFrame();
}
- }
- }
- else if (m_commandLoopState == StateStartProgramming) {
- // Start programming!
-
- // Open programming process
- m_config->setGroup("Programming");
- TQString programmingScript = m_config->readEntry("script");
- programmingScript.replace("%f", m_programmingFileName);
- if (!programmingScript.contains("2>&1")) {
- programmingScript.append(" 2>&1");
- }
- if ((m_progpipe = popen(programmingScript.ascii(), "r")) == NULL) {
- m_logMessages.append(TQString("The system was unable to execute '%1'\nPlease contact your system administrator with this information").arg(programmingScript));
- m_progErrorFlag = true;
transferred_data = true;
- m_commandLoopState = StateIdle;
- }
- else {
- m_progpipefd = fileno(m_progpipe);
- fcntl(m_progpipefd, F_SETFL, O_NONBLOCK);
- }
- m_commandLoopState = StateCheckProgrammingStatus;
- }
- else if (m_commandLoopState == StateCheckProgrammingStatus) {
- // Check programming status
- TQCString buf;
- buf.resize(8192);
- ssize_t r = read(m_progpipefd, buf.data(), buf.size());
- if ((r == -1) && (errno == EAGAIN)) {
- // No data available yet
}
- else if (r > 0) {
- // Data was received
- buf.data()[r] = 0;
- m_logMessages.append(buf);
- }
- else {
- // Process terminated
- m_commandLoopState = StateProgammingFinished;
- }
- }
- else if (m_commandLoopState == StateProgammingFinished) {
- // Programming process terminated; get exit code and clean up
- if (m_progpipe) {
- m_progRetCode = pclose(m_progpipe);
- }
- else {
- m_progRetCode = -1;
- }
- m_progpipe = NULL;
- m_progpipefd = -1;
-
- m_progDoneFlag = true;
- m_commandLoopState = StateIdle;
}
}
m_criticalSection--;
diff --git a/servers/sensor_monitor_server_lin/src/sensor_conn.h b/servers/sensor_monitor_server_lin/src/sensor_conn.h
index 9486c6f..05c939a 100644
--- a/servers/sensor_monitor_server_lin/src/sensor_conn.h
+++ b/servers/sensor_monitor_server_lin/src/sensor_conn.h
@@ -38,13 +38,17 @@
#define MAGIC_NUMBER 1
#define PROTOCOL_VERSION 1
-class SensorServer : public TDEKerberosServerSocket
+#define MAX_SENSORS 255
+
+typedef TQMap<TQ_UINT32, TQString> SensorStringMap;
+
+class SensorSocket : public TDEKerberosServerSocket
{
Q_OBJECT
public:
- SensorServer(int sock, TQObject *parent=0, const char *name=0);
- ~SensorServer();
+ SensorSocket(int sock, TQObject *parent=0, const char *name=0);
+ ~SensorSocket();
public:
void close();
@@ -55,9 +59,9 @@ class SensorServer : public TDEKerberosServerSocket
void finishKerberosHandshake();
void connectionClosedHandler();
void commandLoop();
+ void initializeSensors();
private:
- int line;
int m_criticalSection;
TQString m_remoteHost;
@@ -68,26 +72,20 @@ class SensorServer : public TDEKerberosServerSocket
KSimpleConfig* m_config;
int m_commandLoopState;
- TQ_ULONG m_programmingFileSize;
- TQString m_programmingFileName;
- FILE *m_progpipe;
- int m_progpipefd;
-
- bool m_progErrorFlag;
- bool m_progDoneFlag;
- TQ_INT32 m_progRetCode;
- TQString m_logMessages;
+ SensorList m_sensorList;
+ SensorStringMap m_sensorExecInfo;
+ TQTimer* m_sensorMinIntervalTimers[MAX_SENSORS];
- friend class FPGAServer;
+ friend class SensorServer;
};
-class FPGAServer : public TQServerSocket
+class SensorServer : public TQServerSocket
{
Q_OBJECT
public:
- FPGAServer(TQObject* parent=0, int port=0, KSimpleConfig* config=0);
- ~FPGAServer();
+ SensorServer(TQObject* parent=0, int port=0, KSimpleConfig* config=0);
+ ~SensorServer();
void newConnection(int socket);
@@ -95,12 +93,12 @@ class FPGAServer : public TQServerSocket
void remoteConnectionClosed();
signals:
- void newConnect(SensorServer*);
+ void newConnect(SensorSocket*);
private:
KSimpleConfig* m_config;
int m_numberOfConnections;
- friend class SensorServer;
+ friend class SensorSocket;
}; \ No newline at end of file