diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2012-07-11 01:44:02 -0500 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2012-07-11 01:44:02 -0500 |
commit | 89702662657667460d0e5914794366d190f11534 (patch) | |
tree | f5ea5b866bba0095675bcfe0190685b839d0ff4e | |
parent | 8d3c1358eeaefec559c4a09995ff5b26393a9620 (diff) | |
download | ulab-89702662657667460d0e5914794366d190f11534.tar.gz ulab-89702662657667460d0e5914794366d190f11534.zip |
Fix commanalyzer functionality
-rw-r--r-- | clients/tde/src/part/commanalyzer/Makefile.am | 4 | ||||
-rw-r--r-- | clients/tde/src/part/commanalyzer/part.cpp | 787 | ||||
-rw-r--r-- | clients/tde/src/part/commanalyzer/part.h | 34 | ||||
-rw-r--r-- | clients/tde/src/widgets/Makefile.am | 3 | ||||
-rw-r--r-- | clients/tde/src/widgets/floatspinbox.cpp | 23 | ||||
-rw-r--r-- | clients/tde/src/widgets/tracewidget.cpp | 13 | ||||
-rw-r--r-- | clients/tde/src/widgets/tracewidget.h | 7 | ||||
-rw-r--r-- | lib/libtqtrla/src/tqtrla.cpp | 21 | ||||
-rw-r--r-- | lib/libtqtrla/src/tqtrla.h | 9 | ||||
-rw-r--r-- | servers/gpib_server_lin/src/gpib_conn.cpp | 42 |
10 files changed, 580 insertions, 363 deletions
diff --git a/clients/tde/src/part/commanalyzer/Makefile.am b/clients/tde/src/part/commanalyzer/Makefile.am index d2db726..26e58a2 100644 --- a/clients/tde/src/part/commanalyzer/Makefile.am +++ b/clients/tde/src/part/commanalyzer/Makefile.am @@ -1,10 +1,10 @@ -INCLUDES = $(all_includes) -I$(top_srcdir)/src -I$(top_srcdir)/src/widgets +INCLUDES = $(all_includes) -I$(top_srcdir)/src -I$(top_srcdir)/src/widgets $(KDE_INCLUDES)/tde KDE_CXXFLAGS = $(USE_EXCEPTIONS) METASOURCES = AUTO #Part kde_module_LTLIBRARIES = libremotelab_commanalyzer.la libremotelab_commanalyzer_la_LIBADD = ../../widgets/libtracewidget.la ../../widgets/libfloatspinbox.la $(LIB_KFILE) $(LIB_KPARTS) $(LIB_TDEUI) $(LIB_QT) -libremotelab_commanalyzer_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -ltdecore -ltdeui -lkio -ltdefx +libremotelab_commanalyzer_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -ltdecore -ltdeui -lkio -ltdefx -ltdekrbsocket -ltqtrla libremotelab_commanalyzer_la_SOURCES = \ part.cpp layout.ui diff --git a/clients/tde/src/part/commanalyzer/part.cpp b/clients/tde/src/part/commanalyzer/part.cpp index dbee9be..5d339e3 100644 --- a/clients/tde/src/part/commanalyzer/part.cpp +++ b/clients/tde/src/part/commanalyzer/part.cpp @@ -13,7 +13,7 @@ #include <kstatusbar.h> #include <kstdaction.h> #include <tqfile.h> //encodeName() -#include <tqtimer.h> //postInit() hack +#include <tqtimer.h> #include <tqvbox.h> #include <tqsocket.h> #include <tqmutex.h> @@ -26,6 +26,8 @@ #include "floatspinbox.h" #include "layout.h" +#define NETWORK_COMM_TIMEOUT_MS 15000 + /* exception handling */ struct exit_exception { int c; @@ -35,12 +37,16 @@ struct exit_exception { namespace RemoteLab { typedef KParts::GenericFactory<RemoteLab::CommAnalyzerPart> Factory; +#define CLIENT_LIBRARY "libremotelab_commanalyzer" K_EXPORT_COMPONENT_FACTORY( libremotelab_commanalyzer, RemoteLab::Factory ) CommAnalyzerPart::CommAnalyzerPart( TQWidget *parentWidget, const char *widgetName, TQObject *parent, const char *name, const TQStringList& ) - : ReadOnlyPart( parent, name ), m_traceWidget(0), m_socket(0), m_base(0), stopTraceUpdate(false) + : RemoteInstrumentPart( parent, name ), m_traceWidget(0), m_commHandlerState(-1), m_commHandlerMode(0), m_commHandlerCommandState(0), m_base(0), stopTraceUpdate(false) { + // Initialize important base class variables + m_clientLibraryName = CLIENT_LIBRARY; + // Initialize mutex m_instrumentMutex = new TQMutex(false); @@ -48,6 +54,10 @@ CommAnalyzerPart::CommAnalyzerPart( TQWidget *parentWidget, const char *widgetNa setInstance(Factory::instance()); setWidget(new TQVBox(parentWidget, widgetName)); + // Create timers + m_updateTimeoutTimer = new TQTimer(this); + connect(m_updateTimeoutTimer, SIGNAL(timeout()), this, SLOT(mainEventLoop())); + // Create widgets m_base = new CommAnalyzerBase(widget()); m_traceWidget = m_base->traceWidget; @@ -61,347 +71,529 @@ CommAnalyzerPart::CommAnalyzerPart( TQWidget *parentWidget, const char *widgetNa } CommAnalyzerPart::~CommAnalyzerPart() { - if (m_traceWidget) { - delete m_traceWidget; - } - if (m_socket) { - m_socket->close(); - while (m_socket->state() == TQSocket::Closing) { - tqApp->processEvents(); - } - delete m_socket; + if (m_instrumentMutex->locked()) { + printf("[WARNING] Exiting when data transfer still in progress!\n\r"); fflush(stdout); } + disconnectFromServer(); delete m_instrumentMutex; } void CommAnalyzerPart::postInit() { - m_updateTimer = new TQTimer(this); - connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(updateTrace())); + // } bool CommAnalyzerPart::openURL(const KURL &url) { - connectToServer(url.url()); + int ret; + ret = connectToServer(url.url()); + processLockouts(); + return (ret != 0); } bool CommAnalyzerPart::closeURL() { - if (m_socket) { - m_socket->close(); - - while (m_socket->state() != TQSocket::Idle) { - tqApp->processEvents(); - } - } - + disconnectFromServer(); m_url = KURL(); + return true; +} - if (m_instrumentMutex->locked()) { - throw exit_exception(-1); - } +void CommAnalyzerPart::processLockouts() { +} - return true; +void CommAnalyzerPart::disconnectFromServerCallback() { + m_updateTimeoutTimer->stop(); } -TQString CommAnalyzerPart::callServerMethod(int command) { - if (m_instrumentMutex->locked() == true) { - printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout); - return TQString::null; +void CommAnalyzerPart::connectionFinishedCallback() { + connect(m_socket, SIGNAL(readyRead()), m_socket, SLOT(processPendingData())); + m_socket->processPendingData(); + connect(m_socket, SIGNAL(newDataReceived()), this, SLOT(mainEventLoop())); + m_tickerState = 0; + m_commHandlerState = 0; + m_commHandlerMode = 0; + m_socket->setDataTimeout(NETWORK_COMM_TIMEOUT_MS); + m_updateTimeoutTimer->start(NETWORK_COMM_TIMEOUT_MS, TRUE); + processLockouts(); + mainEventLoop(); + return; +} + +#define UPDATEDISPLAY_TIMEOUT m_connectionActiveAndValid = false; \ + m_tickerState = 0; \ + m_commHandlerState = 2; \ + m_commHandlerMode = 0; \ + m_socket->clearIncomingData(); \ + setStatusMessage(i18n("Server ping timeout. Please verify the status of your network connection.")); \ + m_updateTimeoutTimer->start(NETWORK_COMM_TIMEOUT_MS, TRUE); \ + m_instrumentMutex->unlock(); \ + return; + +#define COMMUNICATIONS_FAILED m_connectionActiveAndValid = false; \ + m_tickerState = 0; \ + m_commHandlerState = 2; \ + m_commHandlerMode = 0; \ + m_socket->clearIncomingData(); \ + setStatusMessage(i18n("Instrument communication failure. Please verify the status of your network connection.")); \ + m_updateTimeoutTimer->start(NETWORK_COMM_TIMEOUT_MS, TRUE); \ + m_instrumentMutex->unlock(); \ + return; + +#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) if (m_commHandlerMode == 0) { \ + m_commHandlerState = x; \ + } \ + else { \ + m_commHandlerState = 255; \ + } + +void CommAnalyzerPart::mainEventLoop() { + TQDataStream ds(m_socket); + ds.setPrintableData(true); + + if (!m_instrumentMutex->tryLock()) { + TQTimer::singleShot(0, this, SLOT(mainEventLoop())); // Handle the concurrently received call immediately after current execution + return; } - try { - m_instrumentMutex->lock(); - if (m_socket->state() == TQSocket::Connected) { - TQString cmd = TQChar(command); - cmd.append('\r'); - m_socket->writeBlock(cmd.latin1(), cmd.length()); - // Read from the server - TQString serverRet; - while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) { - char data[1]; - if( m_socket->readBlock(data, 1) > 0) { - serverRet.append(data[0]); + + if (m_socket) { + if ((m_commHandlerMode == 0) || (m_commHandlerMode == 1)) { + if (m_commHandlerState == 0) { + // Request communications analyzer access + ds << TQString("COMMUNICATIONS ANALYZER"); + m_socket->writeEndOfFrame(); + + m_commHandlerState = 1; + } + else if (m_commHandlerState == 1) { + // Get response data + if (m_socket->canReadFrame()) { + PAT_WATCHDOG_TIMER + + // Get command status + TQString result; + ds >> result; + m_socket->clearFrameTail(); + + if (result == "ACK") { + SET_NEXT_STATE(2) + } + else { + COMMUNICATIONS_FAILED + } + } + else { + if (!m_updateTimeoutTimer->isActive()) { + UPDATEDISPLAY_TIMEOUT + } } - tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents); } - m_instrumentMutex->unlock(); - return serverRet; - } - else { - m_instrumentMutex->unlock(); - return TQString::null; - } - } - catch (exit_exception& e) { - m_instrumentMutex->unlock(); - return TQString::null; - } -} + else if (m_commHandlerState == 2) { + // Set spectrum analyzer mode + ds << TQString("SETMODESPECTRUMANALYZER"); + m_socket->writeEndOfFrame(); -int16_t CommAnalyzerPart::callServerMethodInt16(int command) { - if (m_instrumentMutex->locked() == true) { - printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout); - return 0; - } - try { - m_instrumentMutex->lock(); - if (m_socket->state() == TQSocket::Connected) { - TQString cmd = TQChar(command); - cmd.append('\r'); - m_socket->writeBlock(cmd.latin1(), cmd.length()); - // Read from the server - int bytesread = 0; - int16_t data[1]; - while ((bytesread < 2) && (m_socket->state() == TQSocket::Connected)) { - int ret = m_socket->readBlock(((char*)data)+bytesread, 1); - if (ret > 0) { - bytesread += ret; + SET_NEXT_STATE(3) + } + else if (m_commHandlerState == 3) { + // Get response data + if (m_socket->canReadFrame()) { + PAT_WATCHDOG_TIMER + + // Get command status + TQString result; + ds >> result; + m_socket->clearFrameTail(); + + if (result == "ACK") { + // Set spectrum analyzer mode + ds << TQString("SETMODESPECTRUMANALYZER"); + m_socket->writeEndOfFrame(); + + SET_NEXT_STATE(4) + } + else { + COMMUNICATIONS_FAILED + } + } + else { + if (!m_updateTimeoutTimer->isActive()) { + UPDATEDISPLAY_TIMEOUT + } } - tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents); } - TQString serverRet; - while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) { - char data[1]; - if( m_socket->readBlock(data, 1) > 0) { - serverRet.append(data[0]); + else if (m_commHandlerState == 4) { + // Get response data + if (m_socket->canReadFrame()) { + PAT_WATCHDOG_TIMER + + // Get command status + TQString result; + ds >> result; + m_socket->clearFrameTail(); + + if (result == "ACK") { + // Get number of samples in trace, step 1 + ds << TQString("GETTRACESAMPLECOUNT"); + m_socket->writeEndOfFrame(); + + SET_NEXT_STATE(5) + } + else { + COMMUNICATIONS_FAILED + } + } + else { + if (!m_updateTimeoutTimer->isActive()) { + UPDATEDISPLAY_TIMEOUT + } } - tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents); } - m_instrumentMutex->unlock(); - return data[0]; - } - else { - m_instrumentMutex->unlock(); - return 0; - } - } - catch (exit_exception& e) { - m_instrumentMutex->unlock(); - return 0; - } -} - -double CommAnalyzerPart::callServerMethodDouble(int command) { - if (m_instrumentMutex->locked() == true) { - printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout); - return 0; - } - try { - m_instrumentMutex->lock(); - if (m_socket->state() == TQSocket::Connected) { - TQString cmd = TQChar(command); - cmd.append('\r'); - m_socket->writeBlock(cmd.latin1(), cmd.length()); - // Read from the server - unsigned int bytesread = 0; - double data[1]; - while ((bytesread < sizeof(double)) && (m_socket->state() == TQSocket::Connected)) { - int ret = m_socket->readBlock(((char*)data)+bytesread, 1); - if (ret > 0) { - bytesread += ret; + else if (m_commHandlerState == 5) { + // Get response data + if (m_socket->canReadFrame()) { + PAT_WATCHDOG_TIMER + + // Get number of samples in trace, step 2 + TQString result; + ds >> result; + if (result == "ACK") { + ds >> m_samplesInTrace; + } + m_socket->clearFrameTail(); + + if (result == "ACK") { + // Get number of horizontal divisions, step 1 + ds << TQString("GETHORIZONTALDIVCOUNT"); + m_socket->writeEndOfFrame(); + + SET_NEXT_STATE(6) + } + else { + COMMUNICATIONS_FAILED + } + } + else { + if (!m_updateTimeoutTimer->isActive()) { + UPDATEDISPLAY_TIMEOUT + } } - tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents); } - TQString serverRet; - while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) { - char data[1]; - if( m_socket->readBlock(data, 1) > 0) { - serverRet.append(data[0]); + else if (m_commHandlerState == 6) { + // Get response data + if (m_socket->canReadFrame()) { + PAT_WATCHDOG_TIMER + + // Get number of horizontal divisions, step 2 + TQString result; + ds >> result; + if (result == "ACK") { + ds >> m_hdivs; + } + m_socket->clearFrameTail(); + + if (result == "ACK") { + // Get number of vertical divisions, step 1 + ds << TQString("GETVERTICALDIVCOUNT"); + m_socket->writeEndOfFrame(); + + SET_NEXT_STATE(7) + } + else { + COMMUNICATIONS_FAILED + } + } + else { + if (!m_updateTimeoutTimer->isActive()) { + UPDATEDISPLAY_TIMEOUT + } } - tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents); } - m_instrumentMutex->unlock(); - return data[0]; - } - else { - m_instrumentMutex->unlock(); - return 0; - } - } - catch (exit_exception& e) { - m_instrumentMutex->unlock(); - return 0; - } -} + else if (m_commHandlerState == 7) { + // Get response data + if (m_socket->canReadFrame()) { + PAT_WATCHDOG_TIMER + + // Get number of vertical divisions, step 2 + TQString result; + ds >> result; + if (result == "ACK") { + ds >> m_vdivs; + } + m_socket->clearFrameTail(); + + if (result == "ACK") { + // Get reference power level, step 1 + ds << TQString("GETREFERENCEPOWERLEVEL"); + m_socket->writeEndOfFrame(); -void CommAnalyzerPart::sendServerCommandWithParameter(int command, TQString param) { - if (m_instrumentMutex->locked() == true) { - printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout); - return; - } - try { - m_instrumentMutex->lock(); - if (m_socket->state() == TQSocket::Connected) { - TQString cmd = TQChar(command); - param = TQString("%1%2%3").arg(param).arg(TQChar('°')).arg(TQChar('\r')); - cmd += param; - m_socket->writeBlock(cmd.ascii(), cmd.length()); - // Read from the server - TQString serverRet; - while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) { - char data[1]; - if( m_socket->readBlock(data, 1) > 0) { - serverRet.append(data[0]); + SET_NEXT_STATE(8) + } + else { + COMMUNICATIONS_FAILED + } + } + else { + if (!m_updateTimeoutTimer->isActive()) { + UPDATEDISPLAY_TIMEOUT + } } - tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents); } - } - m_instrumentMutex->unlock(); - return; - } - catch (exit_exception& e) { - m_instrumentMutex->unlock(); - return; - } -} - -void CommAnalyzerPart::sendServerCommand(int command) { - if (m_instrumentMutex->locked() == true) { - printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout); - return; - } - try { - m_instrumentMutex->lock(); - if (m_socket->state() == TQSocket::Connected) { - TQString cmd = TQChar(command); - cmd.append('\r'); - m_socket->writeBlock(cmd.latin1(), cmd.length()); - // Read from the server - TQString serverRet; - while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) { - char data[1]; - if( m_socket->readBlock(data, 1) > 0) { - serverRet.append(data[0]); + else if (m_commHandlerState == 8) { + // Get response data + if (m_socket->canReadFrame()) { + PAT_WATCHDOG_TIMER + + // Get reference power level, step 2 + TQString result; + ds >> result; + if (result == "ACK") { + ds >> m_rpower; + } + m_socket->clearFrameTail(); + + if (result == "ACK") { + // Get vertical division scale, step 1 + ds << TQString("GETVERTDIVSCALE"); + m_socket->writeEndOfFrame(); + + SET_NEXT_STATE(9) + } + else { + COMMUNICATIONS_FAILED + } + } + else { + if (!m_updateTimeoutTimer->isActive()) { + UPDATEDISPLAY_TIMEOUT + } } - tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents); } - } - m_instrumentMutex->unlock(); - return; - } - catch (exit_exception& e) { - m_instrumentMutex->unlock(); - return; - } -} - -void CommAnalyzerPart::callServerMethodDoubleArray(int command, double * array, int arrayLen) { - if (m_instrumentMutex->locked() == true) { - printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout); - return; - } - try { - m_instrumentMutex->lock(); - if (m_socket->state() == TQSocket::Connected) { - TQString cmd = TQChar(command); - cmd.append('\r'); - m_socket->writeBlock(cmd.latin1(), cmd.length()); - // Read from the server - TQString serverRet; - while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) { - char data[1]; - if( m_socket->readBlock(data, 1) > 0) { - serverRet.append(data[0]); + else if (m_commHandlerState == 9) { + // Get response data + if (m_socket->canReadFrame()) { + PAT_WATCHDOG_TIMER + + // Get vertical division scale, step 2 + TQString result; + ds >> result; + if (result == "ACK") { + ds >> m_vscale; + } + m_socket->clearFrameTail(); + + if (result == "ACK") { + // Get center frequency, step 1 + ds << TQString("GETCENTERFREQUENCY"); + m_socket->writeEndOfFrame(); + + SET_NEXT_STATE(10) + } + else { + COMMUNICATIONS_FAILED + } + } + else { + if (!m_updateTimeoutTimer->isActive()) { + UPDATEDISPLAY_TIMEOUT + } } - tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents); } - unsigned int bytesread = 0; - int16_t data[1]; - while ((bytesread < 2) && (m_socket->state() == TQSocket::Connected)) { - int ret = m_socket->readBlock(((char*)data)+bytesread, 1); - if (ret > 0) { - bytesread += ret; + else if (m_commHandlerState == 10) { + // Get response data + if (m_socket->canReadFrame()) { + PAT_WATCHDOG_TIMER + + // Get center frequency, step 2 + TQString result; + ds >> result; + if (result == "ACK") { + ds >> m_centerfreq; + } + m_socket->clearFrameTail(); + + if (result == "ACK") { + // Get frequency span, step 1 + ds << TQString("GETFREQUENCYSPAN"); + m_socket->writeEndOfFrame(); + + SET_NEXT_STATE(11) + } + else { + COMMUNICATIONS_FAILED + } + } + else { + if (!m_updateTimeoutTimer->isActive()) { + UPDATEDISPLAY_TIMEOUT + } } - tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents); } - serverRet = ""; - while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) { - char data[1]; - if( m_socket->readBlock(data, 1) > 0) { - serverRet.append(data[0]); + else if (m_commHandlerState == 11) { + // Get response data + if (m_socket->canReadFrame()) { + PAT_WATCHDOG_TIMER + + // Get frequency span, step 2 + TQString result; + ds >> result; + if (result == "ACK") { + ds >> m_spanfreq; + } + m_socket->clearFrameTail(); + + if (result == "ACK") { + // Update display widget(s) + updateGraticule(); + } + + if (result == "ACK") { + // Get trace, step 1 + ds << TQString("GETSPECTRUMTRACE"); + m_socket->writeEndOfFrame(); + + SET_NEXT_STATE(12) + } + else { + COMMUNICATIONS_FAILED + } + } + else { + if (!m_updateTimeoutTimer->isActive()) { + UPDATEDISPLAY_TIMEOUT + } } - tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents); } - bytesread = 0; - int elementsread = 0; - for (elementsread=0;elementsread<arrayLen;elementsread++) { - bytesread = 0; - while ((bytesread < sizeof(double)) && (m_socket->state() == TQSocket::Connected)) { - if (m_socket->size() < 1) { - tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents); - } - int ret = m_socket->readBlock(((char*)array)+bytesread+(elementsread*sizeof(double)), 1); - if (ret > 0) { - bytesread += ret; + else if (m_commHandlerState == 12) { + // Get response data + if (m_socket->canReadFrame()) { + PAT_WATCHDOG_TIMER + + // Get trace, step 2 + TQDoubleArray trace; + TQString result; + ds >> result; + if (result == "ACK") { + ds >> trace; + } + m_socket->clearFrameTail(); + + if (result == "ACK") { + // Update display widget(s) + m_traceWidget->setSamples(trace); + postProcessTrace(); + m_traceWidget->repaint(); + } + + if (result == "ACK") { + SET_NEXT_STATE(2) + } + else { + COMMUNICATIONS_FAILED } } + else { + if (!m_updateTimeoutTimer->isActive()) { + UPDATEDISPLAY_TIMEOUT + } + } + } + else if (m_commHandlerState == 255) { + // Execute pending command + m_commHandlerMode = 2; + m_socket->clearIncomingData(); } + SET_WATCHDOG_TIMER } - m_instrumentMutex->unlock(); - return; - } - catch (exit_exception& e) { - m_instrumentMutex->unlock(); - return; - } -} - -int CommAnalyzerPart::connectToServer(TQString server) { - if (!m_socket) { - m_socket = new TQSocket(this); - } - m_socket->connectToHost(server, 4002); - while ((m_socket->state() != TQSocket::Connected) && (m_socket->state() != TQSocket::Idle)) { - tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents); - } - if (m_socket->state() != TQSocket::Connected) { - return -1; - } + else if (m_commHandlerMode == 2) { + if (m_commHandlerCommandState == 0) { + m_commHandlerMode = 0; + m_commHandlerState = 2; + } + else if (m_commHandlerCommandState == 1) { + // Set reference power level + ds << TQString("SETREFERENCEPOWERLEVEL"); + ds << m_rpower; + m_socket->writeEndOfFrame(); - // Gather information from the server - if (callServerMethod(41) == "NCK") { - // FIXME - // Display message and exit - return -1; - } - sendServerCommand(40); // Set spectrum analyzer mode - m_samplesInTrace = callServerMethodInt16(63); // Get number of samples in trace - m_traceWidget->setNumberOfSamples(m_samplesInTrace); - m_hdivs = callServerMethodInt16(62); // Get number of horizontal divisions - m_traceWidget->setNumberOfHorizontalDivisions(m_hdivs); - m_vdivs = callServerMethodInt16(64); // Get number of vertical divisions - m_traceWidget->setNumberOfVerticalDivisions(m_vdivs); + m_commHandlerCommandState = 2; + } + else if (m_commHandlerCommandState == 2) { + // Get response data + if (m_socket->canReadFrame()) { + PAT_WATCHDOG_TIMER + + // Set reference power level, step 2 + TQString result; + ds >> result; + m_socket->clearFrameTail(); + + if (result == "ACK") { + // Get reference power level, step 1 + ds << TQString("GETREFERENCEPOWERLEVEL"); + m_socket->writeEndOfFrame(); - m_rpower = callServerMethodDouble(65); // Get reference power level - m_vscale = callServerMethodDouble(66); // Get vertical division scale + m_commHandlerCommandState = 3; + } + else { + COMMUNICATIONS_FAILED + } + } + else { + if (!m_updateTimeoutTimer->isActive()) { + UPDATEDISPLAY_TIMEOUT + } + } + } + else if (m_commHandlerCommandState == 3) { + // Get response data + if (m_socket->canReadFrame()) { + PAT_WATCHDOG_TIMER + + // Get reference power level, step 2 + TQString result; + ds >> result; + if (result == "ACK") { + ds >> m_rpower; + } + m_socket->clearFrameTail(); - m_centerfreq = callServerMethodDouble(67); // Get center frequency - m_spanfreq = callServerMethodDouble(68); // Get frequency span + // Update display as needed + updateGraticule(); - updateGraticule(); + if (result == "ACK") { + m_commHandlerCommandState = 0; + TQTimer::singleShot(0, this, SLOT(mainEventLoop())); + } + else { + COMMUNICATIONS_FAILED + } + } + else { + if (!m_updateTimeoutTimer->isActive()) { + UPDATEDISPLAY_TIMEOUT + } + } + } + } + } + else { + m_commHandlerState = 0; + m_commHandlerCommandState = 0; + } - // Start trace update timer - m_updateTimer->start(10, FALSE); + m_instrumentMutex->unlock(); } void CommAnalyzerPart::postProcessTrace() { return; } -void CommAnalyzerPart::updateTrace() { - m_updateTimer->stop(); - callServerMethodDoubleArray(42, m_traceWidget->samples(), m_samplesInTrace); - postProcessTrace(); - m_traceWidget->repaint(); - if (m_socket->state() == TQSocket::Connected) { - if (stopTraceUpdate == true) { - stopTraceUpdate = false; - } - else { - m_updateTimer->start(10, FALSE); - } - } -} - void CommAnalyzerPart::updateGraticule() { + m_traceWidget->setNumberOfSamples(m_samplesInTrace); + m_traceWidget->setNumberOfHorizontalDivisions(m_hdivs); + m_traceWidget->setNumberOfVerticalDivisions(m_vdivs); + m_leftFrequency = m_centerfreq - (m_spanfreq/2.0); m_rightFrequency = m_centerfreq + (m_spanfreq/2.0); m_traceWidget->setDisplayLimits(m_leftFrequency, m_rpower, m_rightFrequency, m_rpower-(m_vscale*m_hdivs)); @@ -413,25 +605,10 @@ void CommAnalyzerPart::updateGraticule() { } void CommAnalyzerPart::saRefLevelChanged(double newval) { - // We cannot directly send data to the remote instrument because the GUI event may have ocurred during a remote instrument transaction - // This "flaw" is a direct result of maximizing performance by processing GUI events during network transfers, as well as the fact that this client is a multithreaded application m_rpower = newval; - stopTraceUpdate = true; - TQTimer::singleShot(0, this, SLOT(changeSaRefLevel())); -} - -void CommAnalyzerPart::changeSaRefLevel() { - // Keep trying to set the new power level - if (m_instrumentMutex->locked() == false) { - sendServerCommandWithParameter(61, TQString("%1").arg(m_rpower, 0, 'E')); // Set reference power level - m_rpower = callServerMethodDouble(65); // Get reference power level - updateGraticule(); // Update the display grid - m_updateTimer->start(10, FALSE); // Restart trace update timer - } - else { - tqApp->eventLoop()->processEvents(TQEventLoop::ExcludeUserInput); - TQTimer::singleShot(0, this, SLOT(changeSaRefLevel())); - } + m_commHandlerMode = 1; + m_commHandlerCommandState = 1; + mainEventLoop(); } KAboutData* CommAnalyzerPart::createAboutData() { diff --git a/clients/tde/src/part/commanalyzer/part.h b/clients/tde/src/part/commanalyzer/part.h index 196706b..252a67c 100644 --- a/clients/tde/src/part/commanalyzer/part.h +++ b/clients/tde/src/part/commanalyzer/part.h @@ -9,6 +9,8 @@ #include <kparts/part.h> #include <kurl.h> +#include <tqtrla.h> + class KAboutData; using KParts::StatusBarExtension; class TraceWidget; @@ -19,7 +21,7 @@ class CommAnalyzerBase; namespace RemoteLab { - class CommAnalyzerPart : public KParts::ReadOnlyPart + class CommAnalyzerPart : public KParts::RemoteInstrumentPart { Q_OBJECT @@ -30,40 +32,38 @@ namespace RemoteLab virtual bool openFile() { return false; } // pure virtual in the base class virtual bool closeURL(); static KAboutData *createAboutData(); - int connectToServer(TQString server); public slots: virtual bool openURL(const KURL &url); private slots: void postInit(); - void updateTrace(); + void processLockouts(); void updateGraticule(); + void connectionFinishedCallback(); + void disconnectFromServerCallback(); +// void connectionStatusChangedCallback(); + void mainEventLoop(); virtual void postProcessTrace(); void saRefLevelChanged(double); - void changeSaRefLevel(); - - private: - TQString callServerMethod(int command); - void sendServerCommand(int command); - int16_t callServerMethodInt16(int command); - double callServerMethodDouble(int command); - void callServerMethodDoubleArray(int command, double * array, int arrayLen); - void sendServerCommandWithParameter(int command, TQString param); private: TraceWidget* m_traceWidget; - TQSocket* m_socket; - int16_t m_samplesInTrace; + int m_commHandlerState; + int m_commHandlerMode; + int m_commHandlerCommandState; + TQTimer* m_updateTimeoutTimer; + bool m_connectionActiveAndValid; + unsigned char m_tickerState; + TQ_INT16 m_samplesInTrace; double m_leftFrequency; double m_rightFrequency; - int16_t m_hdivs; - int16_t m_vdivs; + TQ_INT16 m_hdivs; + TQ_INT16 m_vdivs; double m_centerfreq; double m_spanfreq; double m_rpower; double m_vscale; - TQTimer* m_updateTimer; CommAnalyzerBase* m_base; TQMutex* m_instrumentMutex; bool stopTraceUpdate; diff --git a/clients/tde/src/widgets/Makefile.am b/clients/tde/src/widgets/Makefile.am index be1f9ba..fac5e76 100644 --- a/clients/tde/src/widgets/Makefile.am +++ b/clients/tde/src/widgets/Makefile.am @@ -1,5 +1,6 @@ -INCLUDES = $(all_includes) +INCLUDES = $(all_includes) $(KDE_INCLUDES)/tde METASOURCES = AUTO noinst_LTLIBRARIES = libtracewidget.la libfloatspinbox.la libtracewidget_la_SOURCES = tracewidget.cpp +libtracewidget_la_LDFLAGS = $(all_libraries) -ltqtrla libfloatspinbox_la_SOURCES = floatspinbox.cpp
\ No newline at end of file diff --git a/clients/tde/src/widgets/floatspinbox.cpp b/clients/tde/src/widgets/floatspinbox.cpp index 266225a..10d9020 100644 --- a/clients/tde/src/widgets/floatspinbox.cpp +++ b/clients/tde/src/widgets/floatspinbox.cpp @@ -13,15 +13,15 @@ #define ROUND(x) ((int)(0.5 + (x))) -FloatSpinBox::FloatSpinBox(double fmin, double fmax, double fvalue, TQWidget *parent) : TQSpinBox(parent) -{ +FloatSpinBox::FloatSpinBox(double fmin, double fmax, double fvalue, TQWidget *parent) : TQSpinBox(parent) { init(fmin, fmax, fvalue); connect( this, SIGNAL(valueChanged(int)), SLOT(acceptValueChanged(int)) ); } -FloatSpinBox::FloatSpinBox(TQWidget *parent , const char* name) : TQSpinBox(parent, name) -{ +FloatSpinBox::FloatSpinBox(TQWidget *parent , const char* name) : TQSpinBox(parent, name) { + init(0, 0, 0); + connect( this, SIGNAL(valueChanged(int)), SLOT(acceptValueChanged(int)) ); } @@ -52,16 +52,14 @@ void FloatSpinBox::setFloatMax(double fmax) { init(min, fmax, value); } -TQString FloatSpinBox::mapValueToText(int ival) -{ +TQString FloatSpinBox::mapValueToText(int ival) { TQString str; value = min + (double)ival * pow(10, -dec); - str.sprintf("%.*f", dec, value); + str.sprintf("%.*f", dec, value); // This can hang as 'value' may (randomly) have an insanely high precision that is very difficult to convert to text return( str ); } -int FloatSpinBox::mapTextToValue (bool * ok) -{ +int FloatSpinBox::mapTextToValue (bool * ok) { TQString str = cleanText(); double tryValue = str.toDouble( ok ); if (*ok) { @@ -70,14 +68,13 @@ int FloatSpinBox::mapTextToValue (bool * ok) return ROUND( (value - min) * pow( 10, dec ) ); } -void FloatSpinBox::setFloatValue(double d) -{ +void FloatSpinBox::setFloatValue(double d) { value = d; setValue( ROUND( (value - min) * pow( 10, dec )) ); } -void FloatSpinBox::acceptValueChanged(int ival) -{ +void FloatSpinBox::acceptValueChanged(int ival) { + Q_UNUSED(ival); emit floatValueChanged( value ); } diff --git a/clients/tde/src/widgets/tracewidget.cpp b/clients/tde/src/widgets/tracewidget.cpp index 9b771bc..d6e5d31 100644 --- a/clients/tde/src/widgets/tracewidget.cpp +++ b/clients/tde/src/widgets/tracewidget.cpp @@ -16,7 +16,6 @@ TraceWidget::TraceWidget(TQWidget* parent, const char* name) : TQWidget(parent, m_rightEdge(0), m_topEdge(0), m_bottomEdge(0), - m_sampleArray(0), m_graticulePixmap(0) { setBackgroundMode(NoBackground); @@ -30,10 +29,7 @@ TraceWidget::~TraceWidget() { void TraceWidget::setNumberOfSamples(unsigned int samples) { m_samples = samples; - if (m_sampleArray) { - delete [] m_sampleArray; - } - m_sampleArray = new double[m_samples]; + m_sampleArray.resize(m_samples); updateGraticule(); } @@ -55,10 +51,15 @@ void TraceWidget::setDisplayLimits(double x, double y, double w, double h) { m_bottomEdge = h; } -double* TraceWidget::samples() { +TQDoubleArray& TraceWidget::samples() { return m_sampleArray; } +void TraceWidget::setSamples(TQDoubleArray& tqda) { + m_sampleArray = tqda; + m_samples = tqda.size(); +} + void TraceWidget::updateGraticule() { unsigned int d,s,x,y; diff --git a/clients/tde/src/widgets/tracewidget.h b/clients/tde/src/widgets/tracewidget.h index 19c7806..21cced7 100644 --- a/clients/tde/src/widgets/tracewidget.h +++ b/clients/tde/src/widgets/tracewidget.h @@ -3,6 +3,8 @@ #include <tqwidget.h> +#include <tqtrla.h> + class TQPixmap; class TraceWidget : public TQWidget @@ -18,7 +20,8 @@ class TraceWidget : public TQWidget void setNumberOfVerticalDivisions(unsigned int divisions); void setDisplayLimits(double x, double y, double w, double h); - double* samples(); + TQDoubleArray& samples(); + void setSamples(TQDoubleArray&); protected: virtual void paintEvent(TQPaintEvent*); @@ -35,6 +38,6 @@ class TraceWidget : public TQWidget double m_rightEdge; double m_topEdge; double m_bottomEdge; - double* m_sampleArray; + TQDoubleArray m_sampleArray; TQPixmap* m_graticulePixmap; };
\ No newline at end of file diff --git a/lib/libtqtrla/src/tqtrla.cpp b/lib/libtqtrla/src/tqtrla.cpp index 96c2274..bda048d 100644 --- a/lib/libtqtrla/src/tqtrla.cpp +++ b/lib/libtqtrla/src/tqtrla.cpp @@ -295,6 +295,27 @@ TQDataStream &operator>>( TQDataStream &s, TQFloatArray &data ) { return s; } +TQDataStream &operator<<( TQDataStream &s, const TQDoubleArray &data ) { + TQ_UINT32 i; + TQ_UINT32 count = data.count(); + s << count; + for (i=0; i<count; i++) { + s << data[i]; + } + return s; +} + +TQDataStream &operator>>( TQDataStream &s, TQDoubleArray &data ) { + TQ_UINT32 i; + TQ_UINT32 count; + s >> count; + data.resize(count); + for (i=0; i<count; i++) { + s >> data[i]; + } + return s; +} + bool operator==( const ServiceType &s1, const ServiceType &s2 ) { bool identical = true; diff --git a/lib/libtqtrla/src/tqtrla.h b/lib/libtqtrla/src/tqtrla.h index a982946..faca985 100644 --- a/lib/libtqtrla/src/tqtrla.h +++ b/lib/libtqtrla/src/tqtrla.h @@ -102,6 +102,15 @@ Q_EXPORT TQDataStream &operator>>(TQDataStream &, TQFloatArray &); // ============================================================================= +typedef TQMemArray<double> TQDoubleArray; + +#ifndef QT_NO_DATASTREAM +Q_EXPORT TQDataStream &operator<<(TQDataStream &, const TQDoubleArray &); +Q_EXPORT TQDataStream &operator>>(TQDataStream &, TQDoubleArray &); +#endif + +// ============================================================================= + class ServiceType { public: diff --git a/servers/gpib_server_lin/src/gpib_conn.cpp b/servers/gpib_server_lin/src/gpib_conn.cpp index a17ee1f..d27c049 100644 --- a/servers/gpib_server_lin/src/gpib_conn.cpp +++ b/servers/gpib_server_lin/src/gpib_conn.cpp @@ -209,10 +209,17 @@ void GPIBSocket::commandLoop() { } if (m_activeDeviceType != 0) { + ds << TQString("ACK"); + writeEndOfFrame(); + m_servClientTimeout->start(NETWORK_COMM_TIMEOUT_MS, TRUE); transferred_data = true; m_commandLoopState = 1; } + else { + ds << TQString("NCK"); + writeEndOfFrame(); + } } } else if (m_commandLoopState == 1) { @@ -226,6 +233,7 @@ void GPIBSocket::commandLoop() { ds.setPrintableData(true); TQByteArray recData; ds >> recData; + clearFrameTail(); if (recData.size() > 0) { if (write(m_serverParent->m_serialDeviceSocket, recData.data(), recData.size()) < 0) { // ERROR @@ -251,12 +259,12 @@ void GPIBSocket::commandLoop() { TQDataStream ds(this); ds.setPrintableData(true); ds >> m_instrumentCommand; - + if (m_instrumentCommand != "") { if (m_activeDeviceType == 2) { // Oscilloscope if (m_instrumentCommand == "SETHORIZTIMEBASE") { // Want to change horizontal timebase - float value; + double value; ds >> value; if (scope_set_timebase(value, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) { ds << TQString("ACK"); @@ -341,7 +349,7 @@ void GPIBSocket::commandLoop() { } } else if (m_instrumentCommand == "SETTRIGGERLEVEL") { // Want to change trigger level - float value; + double value; ds >> value; if (scope_set_trigger_level(value, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) { ds << TQString("ACK"); @@ -381,7 +389,7 @@ void GPIBSocket::commandLoop() { } } else if (m_instrumentCommand == "SETFREQUENCY") { // Want to change frequency - float value; + double value; ds >> value; if (signal_set_frequency(value, m_serverParent->m_funcgenType.ascii(), m_serverParent->m_funcgenDeviceSocket, errorbuf) == 0) { ds << TQString("ACK"); @@ -393,7 +401,7 @@ void GPIBSocket::commandLoop() { } } else if (m_instrumentCommand == "SETDUTYCYCLE") { // Want to change duty cycle - float value; + double value; ds >> value; if (signal_set_duty_cycle(value, m_serverParent->m_funcgenType.ascii(), m_serverParent->m_funcgenDeviceSocket, errorbuf) == 0) { ds << TQString("ACK"); @@ -445,7 +453,7 @@ void GPIBSocket::commandLoop() { } } else if (m_instrumentCommand == "SETPEAKPEAKVOLTAGE") { // Want to change P-P voltage - float value; + double value; ds >> value; if (signal_set_peak_peak_voltage(value, m_serverParent->m_funcgenType.ascii(), m_serverParent->m_funcgenDeviceSocket, errorbuf) == 0) { ds << TQString("ACK"); @@ -457,7 +465,7 @@ void GPIBSocket::commandLoop() { } } else if (m_instrumentCommand == "SETOFFSETVOLTAGE") { // Want to change offset voltage - float value; + double value; ds >> value; if (signal_set_offset_voltage(value, m_serverParent->m_funcgenType.ascii(), m_serverParent->m_funcgenDeviceSocket, errorbuf) == 0) { ds << TQString("ACK"); @@ -485,7 +493,7 @@ void GPIBSocket::commandLoop() { if (commanalyzer_get_spectrum_analyzer_trace(m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { int i; int tracelen = commanalyzerTraceLength(m_serverParent->m_commanalyzerType.ascii()); - TQFloatArray traceData; + TQDoubleArray traceData; traceData.resize(tracelen); for (i=0; i<tracelen; i++) { traceData[i] = commanalyzer_raw_trace_data[i]; @@ -531,7 +539,7 @@ void GPIBSocket::commandLoop() { } } else if (m_instrumentCommand == "SETCENTERFREQUENCY") { // Want to change center frequency - float value; + double value; ds >> value; if (commanalyzer_set_spectrum_analyzer_center_frequency(value, m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); @@ -543,7 +551,7 @@ void GPIBSocket::commandLoop() { } } else if (m_instrumentCommand == "SETFREQUENCYSPAN") { // Want to change frequency span - float value; + double value; ds >> value; if (commanalyzer_set_spectrum_analyzer_frequency_span(value, m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); @@ -595,7 +603,7 @@ void GPIBSocket::commandLoop() { } } else if (m_instrumentCommand == "SETINPUTATTENUATION") { // Want to change input attenuation - float value; + double value; ds >> value; if (commanalyzer_set_spectrum_analyzer_input_attenuation(value, m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); @@ -607,7 +615,7 @@ void GPIBSocket::commandLoop() { } } else if (m_instrumentCommand == "SETVERTICALSCALE") { // Want to change scale - float value; + double value; ds >> value; if (commanalyzer_set_spectrum_analyzer_scale(value, m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); @@ -639,7 +647,7 @@ void GPIBSocket::commandLoop() { } } else if (m_instrumentCommand == "SETGENOUTPUTPOWER") { // Want to change generator output power - float value; + double value; ds >> value; if (commanalyzer_set_spectrum_analyzer_generator_power(value, m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); @@ -651,7 +659,7 @@ void GPIBSocket::commandLoop() { } } else if (m_instrumentCommand == "SETGENOUTPUTFREQUENCY") { // Want to change generator output frequency - float value; + double value; ds >> value; if (commanalyzer_set_spectrum_analyzer_generator_frequency(value, m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); @@ -683,7 +691,7 @@ void GPIBSocket::commandLoop() { } } else if (m_instrumentCommand == "SETTRACEAVERAGING") { // Want to set trace averaging - float value; + double value; ds >> value; if (commanalyzer_set_spectrum_analyzer_trace_averaging(value, m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); @@ -695,7 +703,7 @@ void GPIBSocket::commandLoop() { } } else if (m_instrumentCommand == "SETREFERENCEPOWERLEVEL") { // Want to set reference power level - float value; + double value; ds >> value; if (commanalyzer_set_spectrum_analyzer_reference_power_level(value, m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); @@ -766,7 +774,7 @@ void GPIBSocket::commandLoop() { writeEndOfFrame(); } } - else if (m_instrumentCommand == "SETCENTERFREQUENCY") { // Want to get the center frequency + else if (m_instrumentCommand == "GETCENTERFREQUENCY") { // Want to get the center frequency double freq; if (commanalyzer_get_spectrum_analyzer_center_frequency(&freq, m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); |