From 8392c611054a5bb058cd778163a7aa4ef8311c94 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Wed, 27 Jun 2012 20:43:57 -0500 Subject: [PATCH] Fix a number of problems --- clients/tde/misc/remotelabui.rc | 32 ++-- clients/tde/src/app/remotemdi.cpp | 93 +++++++--- clients/tde/src/app/remotemdi.h | 5 +- clients/tde/src/app/views/instrumentview.cpp | 10 +- clients/tde/src/part/fpgaview/part.cpp | 105 ++++++++--- clients/tde/src/part/fpgaview/part.h | 4 +- lib/libtqtrla/src/tqtrla.cpp | 4 + lib/libtqtrla/src/tqtrla.h | 2 + protocol.txt | 10 +- servers/auth_server_lin/src/auth_conn.cpp | 180 +++++++++++++------ 10 files changed, 320 insertions(+), 125 deletions(-) diff --git a/clients/tde/misc/remotelabui.rc b/clients/tde/misc/remotelabui.rc index bd409b9..77b519a 100644 --- a/clients/tde/misc/remotelabui.rc +++ b/clients/tde/misc/remotelabui.rc @@ -6,30 +6,34 @@ - - Instrumentation - + + Device Under Test + Instrumentation - - - + + + + Services + - Instrumentation Toolbar + Connection - - Instrumentation Toolbar - + + Device Under Test + - Instrumentation Toolbar - - - + Instrumentation + + + + Services + \ No newline at end of file diff --git a/clients/tde/src/app/remotemdi.cpp b/clients/tde/src/app/remotemdi.cpp index e6a65a3..11ab75e 100644 --- a/clients/tde/src/app/remotemdi.cpp +++ b/clients/tde/src/app/remotemdi.cpp @@ -45,8 +45,6 @@ RemoteMDI::RemoteMDI() KStdAction::keyBindings(TQT_TQOBJECT(this), TQT_SLOT(configKeys()), ac); connect_action = new KAction(i18n("Connect to Server"), "connect_creating", KShortcut(), TQT_TQOBJECT(this), TQT_SLOT(connectToServer()), ac, "connect_server"); disconnect_action = new KAction(i18n("Disconnect from Server"), "connect_no", KShortcut(), TQT_TQOBJECT(this), TQT_SLOT(disconnectFromServer()), ac, "disconnect_server"); - inst_fpgaviewer_menu = new KAction(i18n("Launch Spectrum Analyzer"), "remote", KShortcut(), TQT_TQOBJECT(this), TQT_SLOT(startSpectrumAnalyzer()), ac, "spectrum_analyzer"); - inst_sa_menu = new KAction(i18n("Launch FPGA Viewer"), "remote", KShortcut(), TQT_TQOBJECT(this), TQT_SLOT(startFPGAViewer()), ac, "fpga_viewer"); // Add Window menu if ( !isFakingSDIApplication() ) { @@ -65,6 +63,8 @@ RemoteMDI::RemoteMDI() // Create the status bar statusBar()->message(i18n("No view!")); + processActions(); + processLockouts(); } @@ -82,6 +82,61 @@ RemoteMDI::~RemoteMDI() } } +void RemoteMDI::processActions() { + // Add dynamic actions + // RAJA FIXME + KActionCollection *const ac = actionCollection(); + + TQPtrList dut_actions; + inst_fpgaviewer_menu = new KAction(i18n("Launch FPGA Viewer"), "remote", KShortcut(), TQT_TQOBJECT(this), TQT_SLOT(startModule()), ac, "libremotelab_fpgaviewer"); + dut_actions.append(inst_fpgaviewer_menu); + unplugActionList("dutMenu_actionlist"); + unplugActionList("dutToolBar_actionlist"); + plugActionList("dutMenu_actionlist", dut_actions); + plugActionList("dutToolBar_actionlist", dut_actions); + + TQPtrList instrument_actions; + inst_sa_menu = new KAction(i18n("Launch Spectrum Analyzer"), "remote", KShortcut(), TQT_TQOBJECT(this), TQT_SLOT(startModule()), ac, "libremotelab_commanalyzer"); + instrument_actions.append(inst_sa_menu); + unplugActionList("instrumentMenu_actionlist"); + unplugActionList("instrumentToolBar_actionlist"); + plugActionList("instrumentMenu_actionlist", instrument_actions); + plugActionList("instrumentToolBar_actionlist", instrument_actions); + + TQPtrList service_actions; + // Nothing here yet! + unplugActionList("serviceMenu_actionlist"); + unplugActionList("serviceToolBar_actionlist"); + plugActionList("serviceMenu_actionlist", service_actions); + plugActionList("serviceToolBar_actionlist", service_actions); +} + +void RemoteMDI::startModule() { + const KAction* sendingAction = dynamic_cast(sender()); + if (sendingAction) { + // RAJA FIXME + bool serviceFound = false; + ServiceType st; + for (ServiceList::Iterator it(m_activeStation.services.begin()); it != m_activeStation.services.end(); ++it) { + st = *it; + if (st.clientLibrary == sendingAction->name()) { + serviceFound = true; + } + } + + if (!serviceFound) { + KMessageBox::error(this, i18n("The active laboratory workspace does not support the requested service"), i18n("Service Unavailable")); + return; + } + + RemoteLab::InstrumentView* view = new RemoteLab::InstrumentView(sendingAction->name(), st.name, (mdiMode() == KMdi::ToplevelMode) ? 0 : this); + openNewWindow(view); + if (m_serverHost != "") { + view->connectServer(m_serverHost); + } + } +} + void RemoteMDI::connectToServer() { if (m_rsvSvrSocket) { if (m_rsvSvrSocket->state() != TQSocket::Idle) { @@ -102,9 +157,15 @@ void RemoteMDI::connectToServer() { if (m_serverHost != "") { m_rsvSvrSocket->setServerFQDN(m_serverHost); m_rsvSvrSocket->connectToHost(m_serverHost, 4004); + TQTimer connectionTimeout; + connectionTimeout.start(5000, TRUE); while ((m_rsvSvrSocket->state() == TQSocket::Connecting) || (m_rsvSvrSocket->state() == TQSocket::HostLookup)) { tqApp->processEvents(); + if (!connectionTimeout.isActive()) { + break; + } } + connectionTimeout.stop(); if (m_rsvSvrSocket->state() == TQSocket::Connected) { printf("[DEBUG] Initial connection established...\n\r"); fflush(stdout); if (m_rsvSvrSocket->setUsingKerberos(true) != 0) { @@ -170,12 +231,17 @@ void RemoteMDI::promptForStationType() { ds >> result; printf("[RAJA DEBUG 100.0] '%s'\n\r", result.ascii()); fflush(stdout); if (result == "OK") { - // Success, do nothing + // Success! + m_activeStation = select.m_selectedStation; } else if (result == "ERRUNAVAL") { KMessageBox::error(this, i18n("No stations of the specified type are currently available

Please try again later"), i18n("Insufficient Laboratory Resources")); disconnectFromServer(); } + else if (result == "ERRPREVCN") { + KMessageBox::error(this, i18n("You are already connected to a laboratory station

Please disconnect and try again"), i18n("Multiple Connections Detected")); + disconnectFromServer(); + } else { KMessageBox::error(this, i18n("Unknown server error

Please reconnect and try again"), i18n("Internal Error")); disconnectFromServer(); @@ -204,9 +270,8 @@ void RemoteMDI::disconnectFromServer() { if (m_rsvSvrSocket) { m_rsvSvrSocket->clearPendingData(); m_rsvSvrSocket->close(); - while (m_rsvSvrSocket->state() == TQSocket::Closing) { - tqApp->processEvents(); - } + delete m_rsvSvrSocket; + m_rsvSvrSocket = NULL; } connect_action->setEnabled(true); @@ -249,22 +314,6 @@ void RemoteMDI::setServerHost(TQString server) { m_serverHost = server; } -void RemoteMDI::startSpectrumAnalyzer() { - RemoteLab::InstrumentView* saview = new RemoteLab::InstrumentView("libremotelab_commanalyzer", i18n("Communications Analyzer"), (mdiMode() == KMdi::ToplevelMode) ? 0 : this); - openNewWindow(saview); - if (m_serverHost != "") { - saview->connectServer(m_serverHost); - } -} - -void RemoteMDI::startFPGAViewer() { - RemoteLab::InstrumentView* fpgaview = new RemoteLab::InstrumentView("libremotelab_fpgaviewer", i18n("FPGA Viewer"), (mdiMode() == KMdi::ToplevelMode) ? 0 : this); - openNewWindow(fpgaview); - if (m_serverHost != "") { - fpgaview->connectServer(m_serverHost); - } -} - void RemoteMDI::openNewWindow(KMdiChildView *view) { // Add a child view m_children++; diff --git a/clients/tde/src/app/remotemdi.h b/clients/tde/src/app/remotemdi.h index 84b5a82..a7b62b2 100644 --- a/clients/tde/src/app/remotemdi.h +++ b/clients/tde/src/app/remotemdi.h @@ -63,8 +63,8 @@ class RemoteMDI : public KMdiMainFrm void promptForStationType(); void connectionClosedHandler(); void processLockouts(); - void startSpectrumAnalyzer(); - void startFPGAViewer(); + void processActions(); + void startModule(); protected: virtual bool queryClose(); @@ -79,6 +79,7 @@ class RemoteMDI : public KMdiMainFrm KAction *disconnect_action; KAction *inst_sa_menu; KAction *inst_fpgaviewer_menu; + StationType m_activeStation; }; #endif // _REMOTEMDI_H_ diff --git a/clients/tde/src/app/views/instrumentview.cpp b/clients/tde/src/app/views/instrumentview.cpp index 0b434d4..68b469a 100644 --- a/clients/tde/src/app/views/instrumentview.cpp +++ b/clients/tde/src/app/views/instrumentview.cpp @@ -33,9 +33,9 @@ InstrumentView::~InstrumentView() { void InstrumentView::init() { KLibFactory *factory = KLibLoader::self()->factory(m_libraryName.ascii()); - + if (!factory) { - KMessageBox::error( this, i18n("TDE could not find the %1 part, or it could not be started. Did you 'make install'?").arg(m_libraryName) ); + KMessageBox::error( this, i18n("TDE could not find the %1 Part, or the Remote Laboratory Communications Analyzer Part could not be started. Did you make install?").arg(m_libraryName) ); TQTimer::singleShot(0, this, SLOT(close())); } else { @@ -58,7 +58,9 @@ void InstrumentView::closeConnections() { void InstrumentView::connectServer(TQString server) { if (m_instrumentPart) { - m_instrumentPart->openURL(KURL(server)); + if (m_instrumentPart->openURL(KURL(server))) { + close(); + } } } @@ -72,4 +74,4 @@ void InstrumentView::saveProperties( KConfig *config ) { void InstrumentView::readProperties( KConfig *config ) { } -} //namespace RemoteLab +} //namespace RemoteLab \ No newline at end of file diff --git a/clients/tde/src/part/fpgaview/part.cpp b/clients/tde/src/part/fpgaview/part.cpp index dab2742..4eae27d 100644 --- a/clients/tde/src/part/fpgaview/part.cpp +++ b/clients/tde/src/part/fpgaview/part.cpp @@ -55,14 +55,15 @@ struct exit_exception { namespace RemoteLab { typedef KParts::GenericFactory Factory; -K_EXPORT_COMPONENT_FACTORY( libremotelab_fpgaviewer, RemoteLab::Factory ) +#define CLIENT_LIBRARY "libremotelab_fpgaviewer" +K_EXPORT_COMPONENT_FACTORY(libremotelab_fpgaviewer, RemoteLab::Factory) FPGAViewPart::FPGAViewPart(TQWidget *parentWidget, const char *widgetName, TQObject *parent, const char *name, const TQStringList&) : ReadOnlyPart( parent, name ), m_socket(0), m_base(0) { // Initialize mutex - m_instrumentMutex = new TQMutex(false); + m_connectionMutex = new TQMutex(false); // Initialize kpart setInstance(Factory::instance()); @@ -74,19 +75,36 @@ FPGAViewPart::FPGAViewPart(TQWidget *parentWidget, const char *widgetName, TQObj // Create widgets m_base = new FPGAViewBase(widget()); + processLockouts(); + TQTimer::singleShot(0, this, TQT_SLOT(postInit())); } FPGAViewPart::~FPGAViewPart() { + if (m_connectionMutex->locked()) { + throw exit_exception(-1); + } + if (m_socket) { + m_socket->clearPendingData(); m_socket->close(); - while (m_socket->state() == TQSocket::Closing) { - tqApp->processEvents(); - } delete m_socket; + m_socket = NULL; + } + delete m_connectionMutex; +} + +void FPGAViewPart::processLockouts() { + if ((m_socket) && (m_socket->state() == TQSocket::Connected)) { + widget()->setEnabled(true); + } + else { + widget()->setEnabled(false); } +} - delete m_instrumentMutex; +void FPGAViewPart::connectionClosed() { + closeURL(); } void FPGAViewPart::postInit() { @@ -94,23 +112,27 @@ void FPGAViewPart::postInit() { } bool FPGAViewPart::openURL(const KURL &url) { - return connectToServer(url.url()); + int ret; + ret = connectToServer(url.url()); + processLockouts(); + return (ret != 0); } bool FPGAViewPart::closeURL() { + if (m_connectionMutex->locked()) { + throw exit_exception(-1); + } + if (m_socket) { + m_socket->clearPendingData(); m_socket->close(); - - while (m_socket->state() != TQSocket::Idle) { - tqApp->processEvents(); - } + delete m_socket; + m_socket = NULL; } - m_url = KURL(); + processLockouts(); - if (m_instrumentMutex->locked()) { - throw exit_exception(-1); - } + m_url = KURL(); return true; } @@ -133,13 +155,54 @@ int FPGAViewPart::connectToServer(TQString server) { KMessageBox::error(0, i18n("Unable to establish Kerberos protocol with remote server

Please verify that you currently hold a valid Kerberos ticket"), i18n("Connection Failed")); return -1; } - TQDataStream ds(m_socket); - // RAJA FIXME - // How do we know which service to request? -// ds << TQString("SERV"); -// ds << + connect(m_socket, SIGNAL(connectionClosed()), this, SLOT(connectionClosed())); + try { + m_connectionMutex->lock(); + TQString response; + TQDataStream ds(m_socket); + // Read magic number and proto version from server + TQ_UINT32 magicnum; + TQ_UINT32 protover; + ds >> magicnum; + ds >> protover; + printf("[DEBUG] Got magic number %d and protocol version %d\n\r", magicnum, protover); fflush(stdout); + // Request connection to backend server + ds << TQString("SERV"); + ds << TQString(CLIENT_LIBRARY); + ds >> response; +printf("[RAJA DEBUG 400.0] Got '%s' from the server\n\r", response.ascii()); fflush(stdout); + if (response == "OK") { + m_connectionMutex->unlock(); + return 0; + } + else if (response == "ERRNOCONN") { + KMessageBox::error(0, i18n("Unable to establish connection with backend server

Please verify that you are currently connected to a workspace"), i18n("Connection Failed")); + m_connectionMutex->unlock(); + return -1; + } + else if (response == "ERRNOTAVL") { + KMessageBox::error(0, i18n("The backend server is not available at this time

Please try a different workspace, or try again later"), i18n("Connection Failed")); + m_connectionMutex->unlock(); + return -1; + } + else if (response == "ERRNOSERV") { + KMessageBox::error(0, i18n("The active laboratory workspace does not support the requested service"), i18n("Service Unavailable")); + m_connectionMutex->unlock(); + return -1; + } + else { + KMessageBox::error(0, i18n("Unable to establish connection with remote server"), i18n("Connection Failed")); + m_connectionMutex->unlock(); + return -1; + } - return 0; + m_connectionMutex->unlock(); + return 0; + } + catch (exit_exception& e) { + m_connectionMutex->unlock(); + return -1; + } } void FPGAViewPart::updateDisplay() { diff --git a/clients/tde/src/part/fpgaview/part.h b/clients/tde/src/part/fpgaview/part.h index ff1a5da..0b03e4f 100644 --- a/clients/tde/src/part/fpgaview/part.h +++ b/clients/tde/src/part/fpgaview/part.h @@ -59,11 +59,13 @@ namespace RemoteLab private slots: void postInit(); void updateDisplay(); + void processLockouts(); + void connectionClosed(); private: TDEKerberosClientSocket* m_socket; FPGAViewBase* m_base; - TQMutex* m_instrumentMutex; + TQMutex* m_connectionMutex; TQTimer* m_updateTimer; }; } diff --git a/lib/libtqtrla/src/tqtrla.cpp b/lib/libtqtrla/src/tqtrla.cpp index 71508dd..6daded3 100644 --- a/lib/libtqtrla/src/tqtrla.cpp +++ b/lib/libtqtrla/src/tqtrla.cpp @@ -44,6 +44,8 @@ TQDataStream &operator<<( TQDataStream &s, const ServiceType &st ) s << st.type; s << st.name; s << st.description; + s << st.clientLibrary; + s << st.version; return s; } @@ -60,6 +62,8 @@ TQDataStream &operator>>( TQDataStream &s, ServiceType &st ) s >> st.type; s >> st.name; s >> st.description; + s >> st.clientLibrary; + s >> st.version; return s; } diff --git a/lib/libtqtrla/src/tqtrla.h b/lib/libtqtrla/src/tqtrla.h index 2a6228b..c49c101 100644 --- a/lib/libtqtrla/src/tqtrla.h +++ b/lib/libtqtrla/src/tqtrla.h @@ -29,6 +29,8 @@ class ServiceType TQ_UINT32 type; TQString name; TQString description; + TQString clientLibrary; + int version; }; #ifndef QT_NO_DATASTREAM diff --git a/protocol.txt b/protocol.txt index f01b23d..33df834 100644 --- a/protocol.txt +++ b/protocol.txt @@ -28,7 +28,7 @@ The client may terminate the connection at any time, or provide invalid data to After initial negotiation, the server must enter command mode. In this mode the server expects to receive a command string. The following commands are currently supported: LIST BIND -SERV +SERV QUIT If an invalid command is specified, the server should respond with a string containing the case-sensitive text "ERRINVCMD". @@ -44,17 +44,17 @@ Descriptions should be constructed from station service type flags as known to t BIND : Connects to a specified laboratory station -If a station with the specified Service ID list is available, the server must mark that station as in use by the authenticated user, must return the case-sensitive text "OK", and should block all commands other than QUIT. If a station with the specified Service ID list is not available, the server must respond with a string containing the case-sensitive text "ERRUNAVAL" and must re-enter command mode. +If a station with the specified Service ID list is available, the server must mark that station as in use by the authenticated user, must return the case-sensitive text "OK", and should block all commands other than QUIT. If a station with the specified Service ID list is not available, the server must respond with a string containing the case-sensitive text "ERRUNAVAL" and must re-enter command mode. If the specified user is already connected to a laboratory station, the server must return the case-sensitive text "ERRPREVCN", and should block all commands other than QUIT. Example: BIND StationType -SERV +SERV Requests a connection to the specified backend server on the laboratory station -If BIND was previously commanded on this connection, the server must respond with a string containing the case-sensitive text "ERRINVCMD". If no station has been reserved for this user via a call to BIND on an active connection, the server must respond with a string containing the case-sensitive text "ERRNOCONN". If the backend server is not available, i.e. a connection attempt or attempts have failed to establish a connection, the server should respond with the string "ERRNOTAVL" and must close the client connection. Otherwise, the server must return a string containing the case-sensitive text "OK" and then immediately enter binary pass-through mode between the backend server and the client. +If BIND was previously commanded on this connection, the server must respond with a string containing the case-sensitive text "ERRINVCMD". If no station has been reserved for this user via a call to BIND on an active connection, the server must respond with a string containing the case-sensitive text "ERRNOCONN". If the backend server is not available, i.e. a connection attempt or attempts have failed to establish a connection, the server should respond with the string "ERRNOTAVL" and must close the client connection. If the backend service is not available in the active laboratory workspace, the server should respond with the string "ERRNOSERV" and must close the client connection. Otherwise, the server must return a string containing the case-sensitive text "OK" and then immediately enter binary pass-through mode between the backend server and the client. Example: SERV - ServiceType + libremotelab_fpgaviewer QUIT: Gracefully terminates the connection. diff --git a/servers/auth_server_lin/src/auth_conn.cpp b/servers/auth_server_lin/src/auth_conn.cpp index 14c234f..28c8427 100644 --- a/servers/auth_server_lin/src/auth_conn.cpp +++ b/servers/auth_server_lin/src/auth_conn.cpp @@ -22,6 +22,8 @@ #include +#include + #include #include "auth_conn.h" @@ -165,6 +167,8 @@ int AuthSocket::enterCommandLoop() { if (m_databaseServiceTypesCursor->next()) { svt.name = m_databaseServiceTypesCursor->value("name").toString(); svt.description = m_databaseServiceTypesCursor->value("description").toString(); + svt.clientLibrary = m_databaseServiceTypesCursor->value("client_library").toString(); + svt.version = m_databaseServiceTypesCursor->value("version").toInt(); } if (svt.name == "") { svt.name = i18n(""); @@ -188,35 +192,46 @@ int AuthSocket::enterCommandLoop() { // Attempt to bind to station matching desired Service Type list... m_stationID = -1; - - for (StationList::Iterator it(m_slist.begin()); it != m_slist.end(); ++it) { - if ((*it).services == st.services) { - m_stationID = (*it).id; - break; - } + + // Ensure that this user is not already connected + int activeID = -1; + m_databaseActivityCursor->select(TQString("username='%1' AND realmname='%2'").arg(m_authenticatedUserName).arg(m_authenticatedRealmName)); + if (m_databaseActivityCursor->next()) { + activeID = m_databaseActivityCursor->value("station").toInt(); } + if (activeID < 0) { + for (StationList::Iterator it(m_slist.begin()); it != m_slist.end(); ++it) { + if ((*it).services == st.services) { + m_stationID = (*it).id; + break; + } + } + + if (m_stationID < 0) { + ds << TQString("ERRUNAVAL"); + } + else { + m_bound = true; - if (m_stationID < 0) { - ds << TQString("ERRUNAVAL"); + // Update database + TQSqlRecord *buffer = m_databaseActivityCursor->primeInsert(); + buffer->setValue("station", m_stationID); + buffer->setValue("username", m_authenticatedUserName); + buffer->setValue("realmname", m_authenticatedRealmName); + buffer->setValue("logontime", TQDateTime::currentDateTime().toTime_t()); + m_databaseActivityCursor->insert(); + + ds << TQString("OK"); + } } else { - m_bound = true; - - // Update database - TQSqlRecord *buffer = m_databaseActivityCursor->primeInsert(); - buffer->setValue("station", m_stationID); - buffer->setValue("username", m_authenticatedUserName); - buffer->setValue("realmname", m_authenticatedRealmName); - buffer->setValue("logontime", TQDateTime::currentDateTime().toTime_t()); - m_databaseActivityCursor->insert(); - - ds << TQString("OK"); + ds << TQString("ERRPREVCN"); } } else if (command == "SERV") { - // Get desired Service ID from client - TQ_UINT32 sid; - ds >> sid; + // Get client library name from the client + TQString libname; + ds >> libname; m_databaseActivityCursor->select(TQString("username='%1' AND realmname='%2'").arg(m_authenticatedUserName).arg(m_authenticatedRealmName)); if (m_databaseActivityCursor->next()) { @@ -226,45 +241,98 @@ int AuthSocket::enterCommandLoop() { if (m_bound == true) { ds << TQString("ERRINVCMD"); } - - if (m_stationID < 0) { - ds << TQString("ERRNOCONN"); - } - - // Attempt to connect to the backend server - m_databaseServicesCursor->select(TQString("pk=%1 AND station=%2").arg(sid).arg(m_stationID)); - if (m_databaseServicesCursor->next()) { - TQString serviceHostName = m_databaseServicesCursor->value("hostname").toString(); - int servicePort = m_databaseServicesCursor->value("port").toInt(); - - TDEKerberosClientSocket clientSocket; - clientSocket.setServiceName("remotefpga"); - - clientSocket.setServerFQDN(serviceHostName); - clientSocket.connectToHost(serviceHostName, servicePort); - - while ((clientSocket.state() == TQSocket::Connecting) || (clientSocket.state() == TQSocket::HostLookup)) { - tqApp->processEvents(); + else { + if (m_stationID < 0) { + ds << TQString("ERRNOCONN"); } - if (clientSocket.state() == TQSocket::Connected) { - if (clientSocket.setUsingKerberos(true) != 0) { - clientSocket.close(); - ds << TQString("ERRNOTAVL"); - printf("[DEBUG] Connection failed to %s:%d for user %s@%s due to Kerberos failure\n\r", serviceHostName.ascii(), servicePort, m_authenticatedUserName.ascii(), m_authenticatedRealmName.ascii()); fflush(stdout); + else { + // Find the service ID for the specified client library name + TQ_INT32 sid = -1; + m_databaseServiceTypesCursor->select(TQString("client_library='%1'").arg(libname)); + if (m_databaseServiceTypesCursor->next()) { + sid = m_databaseServiceTypesCursor->value("serviceid").toInt(); + } + if (sid < 0) { + ds << TQString("ERRNOSERV"); } else { - printf("[RAJA DEBUG 600.0] Connect OK!\n\r"); fflush(stdout); - // RAJA FIXME + // Attempt to connect to the backend server + m_databaseServicesCursor->select(TQString("pk=%1 AND station=%2").arg(sid).arg(m_stationID)); + if (m_databaseServicesCursor->next()) { + TQString serviceHostName = m_databaseServicesCursor->value("hostname").toString(); + int servicePort = m_databaseServicesCursor->value("port").toInt(); + + TDEKerberosClientSocket clientSocket; + clientSocket.setServiceName("remotefpga"); + + clientSocket.setServerFQDN(serviceHostName); + clientSocket.connectToHost(serviceHostName, servicePort); + + TQTimer connectionTimeout; + connectionTimeout.start(5000, TRUE); + while ((clientSocket.state() == TQSocket::Connecting) || (clientSocket.state() == TQSocket::HostLookup)) { + tqApp->processEvents(); + if (!connectionTimeout.isActive()) { + break; + } + } + connectionTimeout.stop(); + if (clientSocket.state() == TQSocket::Connected) { + if (clientSocket.setUsingKerberos(true) != 0) { + clientSocket.close(); + ds << TQString("ERRNOTAVL"); + printf("[DEBUG] Connection failed to %s:%d for user %s@%s due to Kerberos failure\n\r", serviceHostName.ascii(), servicePort, m_authenticatedUserName.ascii(), m_authenticatedRealmName.ascii()); fflush(stdout); + } + else { + TQDataStream clientDS(&clientSocket); + TQString server_reply; + connectionTimeout.start(5000, TRUE); + while ((!clientSocket.canReadLine()) && (clientSocket.state() == TQSocket::Connected)) { + tqApp->processEvents(); + if (!connectionTimeout.isActive()) { + break; + } + } + connectionTimeout.stop(); + if ((clientSocket.canReadLine()) && (clientSocket.state() == TQSocket::Connected)) { + clientDS >> server_reply; + } + if (server_reply == "OK") { + ds << TQString("OK"); + TQByteArray ba(8192); + TQ_ULONG reclen; + while ((state() == TQSocket::Connected) && (clientSocket.state() == TQSocket::Connected)) { + // RAJA FIXME + if (canReadLine()) { + reclen = readBlock(ba.data(), 8192); + clientSocket.writeBlock(ba.data(), reclen); + } + if (clientSocket.canReadLine()) { + reclen = clientSocket.readBlock(ba.data(), 8192); + writeBlock(ba.data(), reclen); + } + tqApp->processEvents(); + } + clientSocket.close(); + } + else { + clientSocket.close(); + ds << TQString("ERRNOTAVL"); + printf("[DEBUG] Connection failed to %s:%d for user %s@%s due to remote server returning %s\n\r", serviceHostName.ascii(), servicePort, m_authenticatedUserName.ascii(), m_authenticatedRealmName.ascii(), server_reply.ascii()); fflush(stdout); + } + } + } + else { + clientSocket.close(); + ds << TQString("ERRNOTAVL"); + printf("[DEBUG] Connection failed to %s:%d for user %s@%s\n\r", serviceHostName.ascii(), servicePort, m_authenticatedUserName.ascii(), m_authenticatedRealmName.ascii()); fflush(stdout); + } + } + else { + ds << TQString("ERRNOSERV"); + } } } - else { - clientSocket.close(); - ds << TQString("ERRNOTAVL"); - printf("[DEBUG] Connection failed to %s:%d for user %s@%s\n\r", serviceHostName.ascii(), servicePort, m_authenticatedUserName.ascii(), m_authenticatedRealmName.ascii()); fflush(stdout); - } - } - else { - ds << TQString("ERRNOTAVL"); } } else {