summaryrefslogtreecommitdiffstats
path: root/clients/tde/src/part/commanalyzer/part.cpp
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2012-04-30 16:46:20 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2012-04-30 16:46:20 -0500
commit408e828f4732c9bb4aa3673c87d85109e06c08e1 (patch)
treeecd25f872402cea120a442d3f2744d74d699b675 /clients/tde/src/part/commanalyzer/part.cpp
parentf8d372779417eeb809088893ca58ad6a318ab418 (diff)
downloadulab-408e828f4732c9bb4aa3673c87d85109e06c08e1.tar.gz
ulab-408e828f4732c9bb4aa3673c87d85109e06c08e1.zip
Fixups for ca server
Add very preliminary client for ca and TDE
Diffstat (limited to 'clients/tde/src/part/commanalyzer/part.cpp')
-rw-r--r--clients/tde/src/part/commanalyzer/part.cpp396
1 files changed, 396 insertions, 0 deletions
diff --git a/clients/tde/src/part/commanalyzer/part.cpp b/clients/tde/src/part/commanalyzer/part.cpp
new file mode 100644
index 0000000..3fd89eb
--- /dev/null
+++ b/clients/tde/src/part/commanalyzer/part.cpp
@@ -0,0 +1,396 @@
+//Author: Timothy Pearson <kb9vqf@pearsoncomputing.net>, (C) 2012
+//Copyright: See COPYING file that comes with this distribution
+
+#include "debug.h"
+#include "define.h"
+#include "part.h"
+
+#include <kaboutdata.h> //::createAboutData()
+#include <kaction.h>
+#include <klocale.h>
+#include <kmessagebox.h> //::start()
+#include <kparts/genericfactory.h>
+#include <kstatusbar.h>
+#include <kstdaction.h>
+#include <tqfile.h> //encodeName()
+#include <tqtimer.h> //postInit() hack
+#include <tqvbox.h>
+#include <tqsocket.h>
+#include <tqmutex.h>
+#include <tqeventloop.h>
+#include <tqapplication.h>
+#include <unistd.h> //access()
+#include <stdint.h>
+
+#include "tracewidget.h"
+#include "floatspinbox.h"
+#include "layout.h"
+
+namespace RemoteLab {
+
+typedef KParts::GenericFactory<RemoteLab::CommAnalyzerPart> Factory;
+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)
+{
+ // Initialize mutex
+ m_instrumentMutex = new TQMutex(false);
+
+ // Initialize kpart
+ setInstance(Factory::instance());
+ setWidget(new TQVBox(parentWidget, widgetName));
+
+ // Create widgets
+ m_base = new CommAnalyzerBase(widget());
+ m_traceWidget = m_base->traceWidget;
+ m_base->saRefLevel->setFloatMin(-128);
+ m_base->saRefLevel->setFloatMax(128);
+ m_base->saRefLevel->setLineStep(1);
+
+ connect(m_base->saRefLevel, SIGNAL(floatValueChanged(double)), this, SLOT(saRefLevelChanged(double)));
+
+ TQTimer::singleShot(0, this, TQT_SLOT(postInit()));
+}
+
+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;
+ }
+
+ 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());
+}
+
+bool CommAnalyzerPart::closeURL() {
+ m_socket->close();
+
+ while (m_socket->state() != TQSocket::Idle) {
+ tqApp->processEvents();
+ }
+
+ m_url = KURL();
+
+ return true;
+}
+
+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;
+ }
+ 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]);
+ }
+ tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
+ }
+ m_instrumentMutex->unlock();
+ return serverRet;
+ }
+ else {
+ m_instrumentMutex->unlock();
+ return TQString::null;
+ }
+}
+
+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;
+ }
+ 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;
+ }
+ 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]);
+ }
+ tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
+ }
+ m_instrumentMutex->unlock();
+ return data[0];
+ }
+ else {
+ 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;
+ }
+ 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;
+ }
+ 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]);
+ }
+ tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
+ }
+ m_instrumentMutex->unlock();
+ return data[0];
+ }
+ else {
+ m_instrumentMutex->unlock();
+ return 0;
+ }
+}
+
+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;
+ }
+ 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]);
+ }
+ tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
+ }
+ }
+ m_instrumentMutex->unlock();
+}
+
+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;
+ }
+ 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]);
+ }
+ tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
+ }
+ }
+ m_instrumentMutex->unlock();
+}
+
+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;
+ }
+ 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]);
+ }
+ 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;
+ }
+ 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]);
+ }
+ 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;
+ }
+ }
+ }
+ }
+ m_instrumentMutex->unlock();
+}
+
+int CommAnalyzerPart::connectToServer(TQString server) {
+ if (!m_socket) {
+ m_socket = new TQSocket(this);
+// connect(m_socket, SIGNAL(connected()), SLOT(socketConnected()));
+// connect(m_socket, SIGNAL(connectionClosed()), SLOT(socketConnectionClosed()));
+// connect(m_socket, SIGNAL(readyRead()), SLOT(socketReadyRead()));
+// connect(m_socket, SIGNAL(error(int)), SLOT(socketError(int)));
+ }
+ 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;
+ }
+
+ // 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_rpower = callServerMethodDouble(65); // Get reference power level
+ m_vscale = callServerMethodDouble(66); // Get vertical division scale
+
+ m_centerfreq = callServerMethodDouble(67); // Get center frequency
+ m_spanfreq = callServerMethodDouble(68); // Get frequency span
+
+ updateGraticule();
+
+ // Start trace update timer
+ m_updateTimer->start(10, FALSE);
+}
+
+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_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));
+
+ // Also update controls
+ m_base->saRefLevel->blockSignals(true);
+ m_base->saRefLevel->setFloatValue(m_rpower);
+ m_base->saRefLevel->blockSignals(false);
+}
+
+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()));
+ }
+}
+
+KAboutData* CommAnalyzerPart::createAboutData() {
+ return new KAboutData( APP_NAME, I18N_NOOP( APP_PRETTYNAME ), APP_VERSION );
+}
+
+} //namespace RemoteLab
+
+#include "part.moc"