Fix commanalyzer functionality

master
Timothy Pearson 12 years ago
parent 8d3c1358ee
commit 8970266265

@ -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

@ -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() {

@ -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;

@ -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

@ -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 );
}

@ -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;

@ -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;
};

@ -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;

@ -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:

@ -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");

Loading…
Cancel
Save