/* * Remote Laboratory GPIB Server * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (c) 2012 Timothy Pearson * Raptor Engineering * http://www.raptorengineeringinc.com */ #include /* perror() */ #include /* atoi() */ #include #include #include /* read() */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "gpib_functions.h" #include "scope_functions.h" #include "signal_functions.h" #include "commanalyzer_functions.h" #include "companalyzer_functions.h" #include "gpib_conn.h" #define ABORT_SOCKET(s) s->close(); \ s->disconnect(); \ delete s; \ s = NULL; #define NETWORK_COMM_TIMEOUT_MS 5000 /* exception handling */ struct exit_exception { int c; exit_exception(int c):c(c) { } }; /* The GPIBSocket class provides a socket that is connected with a client. For every client that connects to the server, the server creates a new instance of this class. */ GPIBSocket::GPIBSocket(int sock, TQObject *parent, const char *name) : TDEKerberosServerSocket(parent, name), m_criticalSection(0), m_loopTimer(NULL), m_config(static_cast(parent)->m_config), m_serverParent(static_cast(parent)), m_commandLoopState(0) { // Initialize timers m_kerberosInitTimer = new TQTimer(); connect(m_kerberosInitTimer, SIGNAL(timeout()), this, SLOT(finishKerberosHandshake())); m_servClientTimeout = new TQTimer(); setServiceName("ulab"); line = 0; connect(this, SIGNAL(connectionClosed()), SLOT(connectionClosedHandler())); connect(this, SIGNAL(connectionClosed()), parent, SLOT(remoteConnectionClosed())); setSocket(sock); } GPIBSocket::~GPIBSocket() { if (m_servClientTimeout) { m_servClientTimeout->stop(); delete m_servClientTimeout; m_servClientTimeout = NULL; } if (m_kerberosInitTimer) { m_kerberosInitTimer->stop(); delete m_kerberosInitTimer; m_kerberosInitTimer = NULL; } if (m_loopTimer) { m_loopTimer->stop(); delete m_loopTimer; m_loopTimer = NULL; } } void GPIBSocket::close() { if (state() == TQSocket::Connected) { TDEKerberosServerSocket::close(); connectionClosedHandler(); TQTimer::singleShot(0, parent(), SLOT(remoteConnectionClosed())); } } void GPIBSocket::connectionClosedHandler() { printf("[DEBUG] Connection from %s closed\n\r", m_remoteHost.ascii()); if (m_criticalSection > 0) { throw exit_exception(-1); } } void GPIBSocket::initiateKerberosHandshake() { setUsingKerberos(true); m_kerberosInitTimer->start(100, TRUE); } void GPIBSocket::finishKerberosHandshake() { if (kerberosStatus() == TDEKerberosServerSocket::KerberosInitializing) { m_kerberosInitTimer->start(100, TRUE); return; } if (kerberosStatus() == TDEKerberosServerSocket::KerberosInUse) { m_config->setGroup("Security"); TQString masterUser = m_config->readEntry("masteruser"); TQString masterRealm = m_config->readEntry("masterrealm"); if (masterRealm == "") { masterRealm = "(NULL)"; } if ((m_authenticatedUserName != masterUser) || (m_authenticatedRealmName != masterRealm)) { printf("[DEBUG] Connection from %s closed due to authentication failure (attempted connection as user %s@%s)\n\r", m_remoteHost.ascii(), m_authenticatedUserName.ascii(), m_authenticatedRealmName.ascii()); close(); return; } setDataTimeout(NETWORK_COMM_TIMEOUT_MS); TQDataStream ds(this); ds.setPrintableData(true); ds << TQString("OK"); writeEndOfFrame(); enterCommandLoop(); return; } else { printf("[DEBUG] Connection from %s closed due to Kerberos failure\n\r", m_remoteHost.ascii()); fflush(stdout); close(); return; } } void GPIBSocket::commandLoop() { bool transferred_data; m_criticalSection++; try { transferred_data = false; if (state() == TQSocket::Connected) { if (m_commandLoopState == 0) { if (canReadLine()) { processPendingData(); } if (canReadFrame()) { TQDataStream ds(this); ds.setPrintableData(true); TQString instrumentRequest; ds >> instrumentRequest; clearFrameTail(); m_activeDeviceType = 0; if (instrumentRequest == "LIST") { TQStringList deviceList; if (m_serverParent->m_serialDevice != "") { deviceList.append("SERIAL PORT"); } if (m_serverParent->m_scopeType != "") { deviceList.append("OSCILLOSCOPE"); } if (m_serverParent->m_funcgenType != "") { deviceList.append("FUNCTION GENERATOR"); } if (m_serverParent->m_commanalyzerType != "") { deviceList.append("COMMUNICATIONS ANALYZER"); } if (m_serverParent->m_companalyzerType != "") { deviceList.append("COMPONENT ANALYZER"); } ds << deviceList; writeEndOfFrame(); } else if (instrumentRequest == "SERIAL PORT") { m_activeDeviceType = 1; } else if (instrumentRequest == "OSCILLOSCOPE") { m_activeDeviceType = 2; } else if (instrumentRequest == "FUNCTION GENERATOR") { m_activeDeviceType = 3; } else if (instrumentRequest == "COMMUNICATIONS ANALYZER") { m_activeDeviceType = 4; } 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) { if (canReadLine()) { processPendingData(); } if (m_activeDeviceType == 1) { // Serial port if (canReadFrame()) { TQDataStream ds(this); ds.setPrintableData(true); TQByteArray recData; ds >> recData; clearFrameTail(); if (recData.size() > 0) { if (write(m_serverParent->m_serialDeviceSocket, recData.data(), recData.size()) < 0) { // ERROR } transferred_data = true; printf("[DEBUG] Got %d bytes from the network interface\n\r", recData.size()); fflush(stdout); } } TQByteArray txData; txData.resize(10000); int cc = read(m_serverParent->m_serialDeviceSocket, txData.data(), txData.size()); if (cc > 0) { TQDataStream ds(this); ds.setPrintableData(true); ds << txData; writeEndOfFrame(); transferred_data = true; printf("[DEBUG] Got %d bytes from the serial port\n\r", cc); fflush(stdout); } } else { if (canReadFrame()) { TQDataStream ds(this); ds.setPrintableData(true); ds >> m_instrumentCommand; if (m_instrumentCommand != "") { if (m_activeDeviceType == 2) { // Oscilloscope if (m_instrumentCommand == "RESET") { // Want to reset scope if (scope_reset(m_serverParent->m_funcgenType.ascii(), m_serverParent->m_funcgenDeviceSocket) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK");; writeEndOfFrame(); } } else if (m_instrumentCommand == "SETHORIZTIMEBASE") { // Want to change horizontal timebase double value; ds >> value; if (scope_set_timebase(value, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "GETHORIZTIMEBASE") { // Want horizontal timebase double timebase; if (scope_get_timebase(&timebase, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) { ds << TQString("ACK"); ds << timebase; writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if ((m_instrumentCommand == "GETCHANNELTRACE")) { // Want channel trace TQ_INT32 value; ds >> value; TQ_INT32 traceLength; traceLength = scope_get_channel_trace(value, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket); if (traceLength > 0) { long i; TQDoubleArray traceData; TQDoubleArray positionData; traceData.resize(traceLength); positionData.resize(traceLength); for (i=0; i> value1; double value2; ds >> value2; if (scope_set_volts_div(value1, value2, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "GETVOLTSDIV") { // Want to get volts per division double voltsdiv; TQ_INT32 value; ds >> value; if (scope_get_channel_volts_div(&voltsdiv, value, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) { ds << TQString("ACK"); ds << voltsdiv; writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "GETSECONDSSDIV") { // Want to get seconds per division double secondsdiv; TQ_INT32 value; ds >> value; if (scope_get_channel_seconds_div(&secondsdiv, value, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) { ds << TQString("ACK"); ds << secondsdiv; writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "GETTRACESAMPLECOUNT") { // Want to get number of samples in the trace unsigned long samples; TQ_INT32 value; ds >> value; if (scope_get_channel_sample_count(&samples, value, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) { ds << TQString("ACK"); TQ_INT32 safeSamples = samples; ds << safeSamples; writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETRUNNING") { // Want to change run status TQ_INT16 value; ds >> value; if (scope_set_acquisition(value, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "GETRUNNING") { // Want to get run status int running; if (scope_get_acquisition(&running, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) { TQ_INT16 safeRunning; safeRunning = running; ds << TQString("ACK"); ds << safeRunning; writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETCHANNELACTIVE") { // Want to change channel enable TQ_INT32 value1; ds >> value1; TQ_INT16 value2; ds >> value2; if (scope_set_channel_state(value1, value2, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETTRIGGERCHANNEL") { // Want to change trigger channel TQ_INT16 value; ds >> value; if (scope_set_trigger_channel(value, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "GETTRIGGERCHANNEL") { // Want to get trigger channel int channel; if (scope_get_trigger_channel(&channel, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) { TQ_INT16 safeChannel = channel; ds << TQString("ACK"); ds << safeChannel; writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETTRIGGERLEVEL") { // Want to change trigger level double value; ds >> value; if (scope_set_trigger_level(value, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "GETTRIGGERLEVEL") { // Want to get trigger level double triggerlevel; if (scope_get_trigger_level(&triggerlevel, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) { ds << TQString("ACK"); ds << triggerlevel; writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETCHANVERTPOS") { // Want to change channel vertical position TQ_INT32 value1; ds >> value1; float value2; ds >> value2; if (scope_set_channel_position(value1, value2, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "GETHORIZONTALDIVCOUNT") { // Want the number of horizontal divisions available TQ_INT16 divisions = scope_get_number_of_vertical_divisions(m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket); if (divisions >= 0) { ds << TQString("ACK"); ds << divisions; writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "GETVERTICALDIVCOUNT") { // Want the number of vertical divisions available TQ_INT16 divisions = scope_get_number_of_horizontal_divisions(m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket); if (divisions >= 0) { ds << TQString("ACK"); ds << divisions; writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "GETNUMBEROFCHANNELS") { // Want the number of channels available TQ_INT16 divisions = scope_get_number_of_channels(m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket); if (divisions >= 0) { ds << TQString("ACK"); ds << divisions; writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "GETCHANNELACTIVE") { // Want to get channel activity int state; TQ_INT32 value; ds >> value; if (scope_get_channel_state(&state, value, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) { TQ_INT16 safeState = state; ds << TQString("ACK"); ds << safeState; writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "GETPERMITTEDVDIVS") { // Want to get permitted volts/div settings double attenuation_mult; double* permitted_array; int permitted_count; TQ_INT32 value; ds >> value; if (scope_get_probe_attenuation_multiplier(&attenuation_mult, value, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) { if (scope_get_permitted_volts_div_settings_at_1x(&permitted_count, &permitted_array, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) { long i; TQDoubleList permittedValues; for (i=0; im_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) { long i; TQDoubleList permittedValues; for (i=0; im_funcgenType.ascii(), m_serverParent->m_funcgenDeviceSocket, errorbuf) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString(errorbuf); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETFREQUENCY") { // Want to change frequency double value; ds >> value; if (signal_set_frequency(value, m_serverParent->m_funcgenType.ascii(), m_serverParent->m_funcgenDeviceSocket, errorbuf) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString(errorbuf); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETDUTYCYCLE") { // Want to change duty cycle double value; ds >> value; if (signal_set_duty_cycle(value, m_serverParent->m_funcgenType.ascii(), m_serverParent->m_funcgenDeviceSocket, errorbuf) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString(errorbuf); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETSHAPESQUARE") { // Want to set square wave if (signal_set_waveform("SQUARE", m_serverParent->m_funcgenType.ascii(), m_serverParent->m_funcgenDeviceSocket, errorbuf) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString(errorbuf); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETSHAPESINE") { // Want to set sine wave if (signal_set_waveform("SINUSOID", m_serverParent->m_funcgenType.ascii(), m_serverParent->m_funcgenDeviceSocket, errorbuf) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString(errorbuf); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETSHAPETRIANGLE") { // Want to set triangle wave if (signal_set_waveform("RAMP", m_serverParent->m_funcgenType.ascii(), m_serverParent->m_funcgenDeviceSocket, errorbuf) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString(errorbuf); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETSHAPENOISE") { // Want to set noise wave if (signal_set_waveform("NOISE", m_serverParent->m_funcgenType.ascii(), m_serverParent->m_funcgenDeviceSocket, errorbuf) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString(errorbuf); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETPEAKPEAKVOLTAGE") { // Want to change P-P voltage 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"); writeEndOfFrame(); } else { ds << TQString(errorbuf); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETOFFSETVOLTAGE") { // Want to change offset voltage double value; ds >> value; if (signal_set_offset_voltage(value, m_serverParent->m_funcgenType.ascii(), m_serverParent->m_funcgenDeviceSocket, errorbuf) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString(errorbuf); writeEndOfFrame(); } } else { printf("[WARNING] Received unknown command %s from host %s\n\r", m_instrumentCommand.ascii(), m_remoteHost.ascii()); fflush(stdout); } } else if (m_activeDeviceType == 4) { // Communications analyzer if (m_instrumentCommand == "SETMODESPECTRUMANALYZER") { // Want to set SA mode if (commanalyzer_switch_to_spectrum_analyzer_mode(m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if ((m_instrumentCommand == "GETSPECTRUMTRACE")) { // Want SA trace 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()); TQDoubleArray traceData; traceData.resize(tracelen); for (i=0; im_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { commanalyzer_set_display_brightness(0, m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket); // Don't burn in the screen ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETGENMODETRACKING") { // Want to set generator to tracking mode if (commanalyzer_spectrum_analyzer_set_generator_mode_tracking(m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETGENMODEFIXED") { // Want to set generator to fixed mode if (commanalyzer_spectrum_analyzer_set_generator_mode_fixed(m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETCENTERFREQUENCY") { // Want to change center frequency 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"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETFREQUENCYSPAN") { // Want to change frequency span 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"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETRFINPUTDEDICATED") { // Want to set RF input to dedicated connector if (commanalyzer_spectrum_analyzer_set_rf_input_dedicated(m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETRFINPUTMULTIPLEXED") { // Want to set RF input to multiplexed connector if (commanalyzer_spectrum_analyzer_set_rf_input_muxed(m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETGENOUTPUTDEDICATED") { // Want to set generator output to dedicated connector if (commanalyzer_spectrum_analyzer_set_generator_output_dedicated(m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETGENOUTPUTMULTIPLEXED") { // Want to set generator output to multiplexed connector if (commanalyzer_spectrum_analyzer_set_generator_output_muxed(m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETINPUTATTENUATION") { // Want to change input attenuation 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"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETVERTICALSCALE") { // Want to change scale double value; ds >> value; if (commanalyzer_set_spectrum_analyzer_scale(value, m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETINPUTATTENMODEAUTO") { // Want to set RF input attenuator mode to automatic if (commanalyzer_set_spectrum_analyzer_input_attenuator_mode_auto(m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETINPUTATTENMODEFIXED") { // Want to set RF input attenuator mode to fixed if (commanalyzer_set_spectrum_analyzer_input_attenuator_mode_fixed(m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETGENOUTPUTPOWER") { // Want to change generator output power 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"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETGENOUTPUTFREQUENCY") { // Want to change generator output frequency 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"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETGENSWEEPASCENDING") { // Want to set generator sweep to ascending if (commanalyzer_spectrum_analyzer_set_generator_sweep_ascending(m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETGENSWEEPDESCENDING") { // Want to set generator sweep to descending if (commanalyzer_spectrum_analyzer_set_generator_sweep_descending(m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETTRACEAVERAGING") { // Want to set trace averaging 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"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETREFERENCEPOWERLEVEL") { // Want to set reference power level 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"); writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "GETHORIZONTALDIVCOUNT") { // Want the number of horizontal divisions available TQ_INT16 divisions = commanalyzer_get_spectrum_analyzer_number_of_horizontal_divisions(m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket); if (divisions >= 0) { ds << TQString("ACK"); ds << divisions; writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "GETVERTICALDIVCOUNT") { // Want the number of vertical divisions available TQ_INT16 divisions = commanalyzer_get_spectrum_analyzer_number_of_vertical_divisions(m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket); if (divisions >= 0) { ds << TQString("ACK"); ds << divisions; writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "GETTRACESAMPLECOUNT") { // Want the number of samples in a trace TQ_INT16 divisions = commanalyzerTraceLength(m_serverParent->m_commanalyzerType.ascii()); if (divisions >= 0) { ds << TQString("ACK"); ds << divisions; writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "GETREFERENCEPOWERLEVEL") { // Want the reference power level double rpower; if (commanalyzer_get_spectrum_analyzer_reference_power_level(&rpower, m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); ds << rpower; writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "GETVERTDIVSCALE") { // Want the vertical division scale double scale; if (commanalyzer_get_spectrum_analyzer_scale(&scale, m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); ds << scale; writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } 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"); ds << freq; writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "GETFREQUENCYSPAN") { // Want to get the frequency span double freq; if (commanalyzer_get_spectrum_analyzer_span(&freq, m_serverParent->m_commanalyzerType.ascii(), m_serverParent->m_commanalyzerDeviceSocket) == 0) { ds << TQString("ACK"); ds << freq; writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else { printf("[WARNING] Received unknown command %s from host %s\n\r", m_instrumentCommand.ascii(), m_remoteHost.ascii()); fflush(stdout); } } else if (m_activeDeviceType == 5) { // Component analyzer char errorbuf[1000]; if (m_instrumentCommand == "GETMEASUREMENT") { // Want a new component measurement with the configured parameters TQ_UINT8 number_of_parameters = 2; companalyzer_measurements_t measurement; int retcode = companalyzer_get_parameter_measurement(&measurement, m_serverParent->m_companalyzerType.ascii(), m_serverParent->m_companalyzerDeviceSocket); if (retcode == 0) { ds << TQString("ACK"); ds << number_of_parameters; ds << (TQ_UINT32&)measurement.parameter_a_status; ds << (TQ_UINT32&)measurement.parameter_a; ds << (TQ_UINT32&)measurement.parameter_a_type; ds << measurement.parameter_a_value; ds << (TQ_UINT32&)measurement.parameter_b_status; ds << (TQ_UINT32&)measurement.parameter_b; ds << (TQ_UINT32&)measurement.parameter_b_type; ds << measurement.parameter_b_value; writeEndOfFrame(); } else { ds << TQString("NCK"); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETMEASUREDPARAMETERS") { // Want to set the measured parameters uint8_t all_ok = 1; uint8_t number_of_parameters; companalyzer_measurement::companalyzer_measurement_t parameter_a; companalyzer_measurement::companalyzer_measurement_t parameter_b; ds >> number_of_parameters; if (number_of_parameters == 2) { ds >> (TQ_UINT32&)parameter_a; ds >> (TQ_UINT32&)parameter_b; if (companalyzer_set_measurement_parameters(parameter_a, parameter_b, m_serverParent->m_companalyzerType.ascii(), m_serverParent->m_companalyzerDeviceSocket, errorbuf) != 0) { all_ok = false; } } else { sprintf(errorbuf, "EXTInvalid number of parameters provided°"); all_ok = false; } if (all_ok) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString(errorbuf); writeEndOfFrame(); } } else if (m_instrumentCommand == "SETMEASUREMENTFREQUENCY") { // Want to set the measurement frequency double frequency; ds >> frequency; if (companalyzer_set_measurement_frequency(frequency, m_serverParent->m_companalyzerType.ascii(), m_serverParent->m_companalyzerDeviceSocket, errorbuf) == 0) { ds << TQString("ACK"); writeEndOfFrame(); } else { ds << TQString(errorbuf); writeEndOfFrame(); } } else { printf("[WARNING] Received unknown command %s from host %s\n\r", m_instrumentCommand.ascii(), m_remoteHost.ascii()); fflush(stdout); } } else { // Unknown transferred_data = true; m_commandLoopState = 0; } m_servClientTimeout->start(NETWORK_COMM_TIMEOUT_MS, TRUE); transferred_data = true; m_commandLoopState = 1; } clearFrameTail(); } } } } m_criticalSection--; if (transferred_data) { if (m_loopTimer) m_loopTimer->start(0, TRUE); } else { if (m_loopTimer) m_loopTimer->start(100, TRUE); } return; } catch (...) { m_criticalSection--; return; } } int GPIBSocket::enterCommandLoop() { m_commandLoopState = 0; if (!m_loopTimer) { m_loopTimer = new TQTimer(); connect(m_loopTimer, SIGNAL(timeout()), this, SLOT(commandLoop())); } if (m_loopTimer) m_loopTimer->start(0, TRUE); return 0; } /* The GPIBServer class handles new connections to the server. For every client that connects, it creates a new GPIBSocket -- that instance is now responsible for the communication with that client. */ GPIBServer::GPIBServer(TQObject* parent, int port, KSimpleConfig* config) : TQServerSocket( port, 1, parent ), m_config(config), m_numberOfConnections(0), m_scopeDeviceSocket(-1), m_funcgenDeviceSocket(-1), m_commanalyzerDeviceSocket(-1), m_companalyzerDeviceSocket(-1) { if ( !ok() ) { printf("[ERROR] Failed to bind to port %d\n\r", port); exit(1); } if (readConfig() != 0) { exit(-1); } printf("[INFO] Server started on port %d\n\r", port); fflush(stdout); } GPIBServer::~GPIBServer() { // } void GPIBServer::newConnection(int socket) { GPIBSocket *s = new GPIBSocket(socket, this); s->m_remoteHost = s->peerAddress().toString(); printf("[DEBUG] New connection from %s\n\r", s->m_remoteHost.ascii()); connect(s, SIGNAL(connectionClosed()), s, SLOT(deleteLater())); s->initiateKerberosHandshake(); emit newConnect(s); } void GPIBServer::remoteConnectionClosed() { m_numberOfConnections--; } int GPIBServer::readConfig() { // Serial port m_config->setGroup("Serial Port"); m_serialDevice = m_config->readEntry("device", ""); TQString desiredBaudRate = m_config->readEntry("baudrate", "9600"); if (desiredBaudRate == "1200") { m_serialBaud = B1200; } else if (desiredBaudRate == "9600") { m_serialBaud = B9600; } else if (desiredBaudRate == "19200") { m_serialBaud = B19200; } else if (desiredBaudRate == "115200") { m_serialBaud = B115200; } else { printf("[WARNING] Invalid baudrate %s specified, selecting 9600 instead\n\r", desiredBaudRate.ascii()); fflush(stdout); desiredBaudRate = "9600"; m_serialBaud = B9600; } // Oscilloscope m_config->setGroup("Oscilloscope"); m_scopeType = m_config->readEntry("type", ""); m_scopeConnection = m_config->readEntry("connection", "gpib"); m_scopeBoard = m_config->readNumEntry("board", 0); m_scopeDevice = m_config->readNumEntry("device", 0); // Function generator m_config->setGroup("Function Generator"); m_funcgenType = m_config->readEntry("type", ""); m_funcgenConnection = m_config->readEntry("connection", "gpib"); m_funcgenBoard = m_config->readNumEntry("board", 0); m_funcgenDevice = m_config->readNumEntry("device", 0); // Communications analyzer m_config->setGroup("Communications Analyzer"); m_commanalyzerType = m_config->readEntry("type", ""); m_commanalyzerConnection = m_config->readEntry("connection", "gpib"); m_commanalyzerBoard = m_config->readNumEntry("board", 0); m_commanalyzerDevice = m_config->readNumEntry("device", 0); // Component analyzer m_config->setGroup("Component Analyzer"); m_companalyzerType = m_config->readEntry("type", ""); m_companalyzerConnection = m_config->readEntry("connection", "gpib"); m_companalyzerBoard = m_config->readNumEntry("board", 0); m_companalyzerDevice = m_config->readNumEntry("device", 0); if (m_serialDevice != "") { struct termios oldtio, newtio; m_serialDeviceSocket = ::open(m_serialDevice.ascii(), O_RDWR | O_NOCTTY | O_NONBLOCK | O_APPEND); if (m_serialDeviceSocket < 0) { printf("[FAIL] Unable to open serial device %s\n\r", m_serialDevice.ascii()); fflush(stdout); return 1; } tcgetattr(m_serialDeviceSocket, &oldtio); // Save current port settings bzero(&newtio, sizeof(newtio)); newtio.c_cflag = m_serialBaud | CS8 | CLOCAL | CREAD; newtio.c_iflag = IGNPAR; newtio.c_oflag = 0; // Set input mode (non-canonical, no echo,...) newtio.c_lflag = 0; newtio.c_cc[VTIME] = 0; // Inter-character timer unused newtio.c_cc[VMIN] = 0; // Blocking read unused tcflush(m_serialDeviceSocket, TCIFLUSH); tcsetattr(m_serialDeviceSocket, TCSANOW, &newtio); printf("[INFO] Serial port on node %s activated at %s baud\n\r", m_serialDevice.ascii(), desiredBaudRate.ascii()); } if (m_scopeType != "") { printf("[INFO] Oscilloscope conjectured to be on GPIB address %d:%d\n\r", m_scopeBoard, m_scopeDevice); m_scopeDeviceSocket = open_gpib_device(m_scopeBoard, m_scopeDevice); if (m_scopeDeviceSocket < 0) { // return -1; } else { time_t rawtime; struct tm * timeinfo; char datebuffer [80]; char timebuffer [80]; time ( &rawtime ); timeinfo = localtime ( &rawtime ); strftime(timebuffer,80,"TIME \"%H:%M:%S\"",timeinfo); strftime(datebuffer,80,"DATE \"%Y-%m-%d\"",timeinfo); printf("[INFO] Configuring %s oscilloscope\n\r", scopeLongDescription(m_scopeType.ascii())); printf("[INFO] %s\n\r", datebuffer); printf("[INFO] %s\n\r", timebuffer); if (gpib_write(m_scopeDeviceSocket, timebuffer) == 0) { gpib_write(m_scopeDeviceSocket, datebuffer); scope_perform_initial_setup(m_scopeType.ascii(), m_scopeDeviceSocket); printf("[INFO] Communication verified\n\r"); } else { printf("[WARN] Communication failed!\n\r"); } } } if (m_funcgenType != "") { printf("[INFO] Function generator conjectured to be on GPIB address %d:%d\n\r", m_funcgenBoard, m_funcgenDevice); m_funcgenDeviceSocket = open_gpib_device(m_funcgenBoard, m_funcgenDevice); if (m_funcgenDeviceSocket < 0) { //return 1; } else { printf("[INFO] Configuring %s function generator\n\r", funcgenLongDescription(m_funcgenType.ascii())); if (gpib_write(m_funcgenDeviceSocket, "RESET") == 0) { printf("[INFO] Communication verified\n\r"); } else { printf("[WARN] Communication failed!\n\r"); } } } if (m_commanalyzerType != "") { printf("[INFO] Communications analyzer conjectured to be on GPIB address %d:%d\n\r", m_commanalyzerBoard, m_commanalyzerDevice); m_commanalyzerDeviceSocket = open_gpib_device(m_commanalyzerBoard, m_commanalyzerDevice); if (m_commanalyzerDeviceSocket < 0) { //return 1; } else { time_t rawtime; struct tm * timeinfo; time ( &rawtime ); timeinfo = localtime ( &rawtime ); printf("[INFO] Configuring %s communications analyzer\n\r", commanalyzerLongDescription(m_commanalyzerType.ascii())); if (commanalyzer_set_time(timeinfo, m_commanalyzerType.ascii(), m_commanalyzerDeviceSocket) == 0) { commanalyzer_set_date(timeinfo, m_commanalyzerType.ascii(), m_commanalyzerDeviceSocket); printf("[INFO] Communication verified\n\r"); } else { printf("[WARN] Communication failed!\n\r"); } } } if (m_companalyzerType != "") { printf("[INFO] Component analyzer conjectured to be on GPIB address %d:%d\n\r", m_companalyzerBoard, m_companalyzerDevice); m_companalyzerDeviceSocket = open_gpib_device(m_companalyzerBoard, m_companalyzerDevice); if (m_companalyzerDeviceSocket < 0) { //return 1; } else { time_t rawtime; struct tm * timeinfo; time ( &rawtime ); timeinfo = localtime ( &rawtime ); printf("[INFO] Configuring %s component analyzer\n\r", companalyzerLongDescription(m_companalyzerType.ascii())); if (companalyzer_set_time(timeinfo, m_companalyzerType.ascii(), m_companalyzerDeviceSocket) == 0) { companalyzer_set_date(timeinfo, m_companalyzerType.ascii(), m_companalyzerDeviceSocket); printf("[INFO] Communication verified\n\r"); } else { printf("[WARN] Communication failed!\n\r"); } } } return 0; }