diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2012-07-07 16:23:30 -0500 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2012-07-07 16:23:30 -0500 |
commit | fc455268a511d91113f59c04b50fa08b7c37b554 (patch) | |
tree | d61462c8a4496fa788875918dc4113162382962b /servers/fpga_programming_server_lin/src | |
parent | 1b8ef84fb9f47b82d0da6fa6e1b9fe439bc6b05c (diff) | |
download | ulab-fc455268a511d91113f59c04b50fa08b7c37b554.tar.gz ulab-fc455268a511d91113f59c04b50fa08b7c37b554.zip |
Convert to frame based protocol
Finish FPGA programming server/client
Diffstat (limited to 'servers/fpga_programming_server_lin/src')
-rw-r--r-- | servers/fpga_programming_server_lin/src/fpga_conn.cpp | 136 | ||||
-rw-r--r-- | servers/fpga_programming_server_lin/src/fpga_conn.h | 7 |
2 files changed, 119 insertions, 24 deletions
diff --git a/servers/fpga_programming_server_lin/src/fpga_conn.cpp b/servers/fpga_programming_server_lin/src/fpga_conn.cpp index 330e747..341d14a 100644 --- a/servers/fpga_programming_server_lin/src/fpga_conn.cpp +++ b/servers/fpga_programming_server_lin/src/fpga_conn.cpp @@ -25,6 +25,7 @@ #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> /* read() */ +#include <errno.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> @@ -46,8 +47,7 @@ delete s; \ s = NULL; -//#define NETWORK_COMM_TIMEOUT_MS 2000 -#define NETWORK_COMM_TIMEOUT_MS 4000 +#define NETWORK_COMM_TIMEOUT_MS 5000 /* exception handling */ struct exit_exception { @@ -61,7 +61,9 @@ struct exit_exception { instance of this class. */ FPGASocket::FPGASocket(int sock, TQObject *parent, const char *name) : - TDEKerberosServerSocket(parent, name), m_criticalSection(0), m_loopTimer(NULL), m_config(static_cast<FPGAServer*>(parent)->m_config), m_commandLoopState(0) { + TDEKerberosServerSocket(parent, name), m_criticalSection(0), m_loopTimer(NULL), m_config(static_cast<FPGAServer*>(parent)->m_config), m_commandLoopState(0), + m_progpipe(NULL), m_progpipefd(-1), m_progErrorFlag(false), m_progDoneFlag(false) +{ // Initialize timers m_kerberosInitTimer = new TQTimer(); @@ -136,7 +138,9 @@ void FPGASocket::finishKerberosHandshake() { setDataTimeout(NETWORK_COMM_TIMEOUT_MS); TQDataStream ds(this); + ds.setPrintableData(true); ds << TQString("OK"); + writeEndOfFrame(); enterCommandLoop(); return; @@ -155,54 +159,85 @@ void FPGASocket::commandLoop() { try { transferred_data = false; if (state() == TQSocket::Connected) { - if (m_commandLoopState == 0) { -printf("[RAJA DEBUG 499.0] Waiting for command...\n\r"); fflush(stdout); + if ((m_commandLoopState == 0) || (m_commandLoopState == 3) || (m_commandLoopState == 4) || (m_commandLoopState == 5)) { + // Certain commands can come in at any time during some operations if (canReadLine()) { -printf("[RAJA DEBUG 499.1] Processing pending data (buffer: %d)...\n\r", bytesAvailable()); fflush(stdout); processPendingData(); } - if (bytesAvailable() > 0) { + if (canReadFrame()) { TQDataStream ds(this); + ds.setPrintableData(true); TQString command; ds >> command; - printf("[DEBUG] Received command '%s'\n\r", command.ascii()); + clearFrameTail(); if (command == "STATUS") { - ds << TQString("IDLE"); + if (m_logMessages != "") { + ds << TQString("LOGMESSAGES"); + writeEndOfFrame(); + ds << m_logMessages; + writeEndOfFrame(); + m_logMessages = ""; + } + else if (m_progErrorFlag) { + ds << TQString("ERROR"); + m_progErrorFlag = false; + writeEndOfFrame(); + } + else if (m_progDoneFlag) { + ds << TQString("DONE"); + m_progDoneFlag = false; + writeEndOfFrame(); + ds << m_progRetCode; + writeEndOfFrame(); + } + else if (m_commandLoopState == 0) { + ds << TQString("IDLE"); + writeEndOfFrame(); + } + else if ((m_commandLoopState == 3) || (m_commandLoopState == 4) || (m_commandLoopState == 5)) { + ds << TQString("PROGRAMMING"); + writeEndOfFrame(); + } + else { + ds << TQString("UNKNOWN"); + writeEndOfFrame(); + } } - else if (command == "FILE") { - m_commandLoopState = 1; - } - else { - printf("[WARNING] Received unknown command '%s'\n\r", command.ascii()); + else if (m_commandLoopState == 0) { + if (command == "FILE") { + m_commandLoopState = 1; + } + else if (command == "PROGRAM") { + m_commandLoopState = 3; + } + else { + printf("[WARNING] Received unknown command '%s'\n\r", command.ascii()); + } } transferred_data = true; } } - else if (m_commandLoopState == 1) { + if (m_commandLoopState == 1) { if (canReadLine()) { processPendingData(); } -printf("[RAJA DEBUG 500.0] Waiting for file...\n\r"); fflush(stdout); - if (bytesAvailable() > 0) { -printf("[RAJA DEBUG 500.1] Waiting for file (buffer: %d)...\n\r", bytesAvailable()); fflush(stdout); + if (canReadFrame()) { TQDataStream ds(this); + ds.setPrintableData(true); ds >> m_programmingFileSize; + clearFrameTail(); m_servClientTimeout->start(NETWORK_COMM_TIMEOUT_MS, TRUE); m_commandLoopState = 2; } } else if (m_commandLoopState == 2) { if (canReadLine()) { -printf("[RAJA DEBUG 500.2] Processing pending data (buffer: %d)...\n\r", bytesAvailable()); fflush(stdout); m_servClientTimeout->start(NETWORK_COMM_TIMEOUT_MS, TRUE); processPendingData(); } -printf("[RAJA DEBUG 500.3] Waiting for file contents (buffer: %d)...\n\r", bytesAvailable()); fflush(stdout); if (bytesAvailable() >= m_programmingFileSize) { TQByteArray fileContents(m_programmingFileSize); readBlock(fileContents.data(), fileContents.size()); -printf("[RAJA DEBUG 500.4] Received file!\n\r"); fflush(stdout); -printf("[RAJA DEBUG 500.5] fileContents size: %d\n\r", fileContents.size()); fflush(stdout); m_programmingFileName = TQString("/tmp/%1#%2.dat").arg(m_remoteHost).arg(port()); TQFile outputFile(m_programmingFileName); if (outputFile.open(IO_ReadWrite)) { @@ -215,13 +250,66 @@ printf("[RAJA DEBUG 500.5] fileContents size: %d\n\r", fileContents.size()); ffl } else { if (!m_servClientTimeout->isActive()) { - TQDataStream ds(this); - ds << TQString("ERROR"); + m_progErrorFlag = true; transferred_data = true; m_commandLoopState = 0; } } } + else if (m_commandLoopState == 3) { + // Start programming! + + // Open programming process + m_config->setGroup("Programming"); + TQString programmingScript = m_config->readEntry("script"); + programmingScript.replace("%f", m_programmingFileName); + if (!programmingScript.contains("2>&1")) { + programmingScript.append(" 2>&1"); + } + if ((m_progpipe = popen(programmingScript.ascii(), "r")) == NULL) { + m_logMessages.append(TQString("The system was unable to execute '%1'\nPlease contact your system administrator with this information").arg(programmingScript)); + m_progErrorFlag = true; + transferred_data = true; + m_commandLoopState = 0; + } + else { + m_progpipefd = fileno(m_progpipe); + fcntl(m_progpipefd, F_SETFL, O_NONBLOCK); + } + m_commandLoopState = 4; + } + else if (m_commandLoopState == 4) { + // Check programming status + TQCString buf; + buf.resize(8192); + ssize_t r = read(m_progpipefd, buf.data(), buf.size()); + if ((r == -1) && (errno == EAGAIN)) { + // No data available yet + } + else if (r > 0) { + // Data was received + buf.data()[r] = 0; + m_logMessages.append(buf); + } + else { + // Process terminated + m_commandLoopState = 5; + } + } + else if (m_commandLoopState == 5) { + // Programming process terminated; get exit code and clean up + if (m_progpipe) { + m_progRetCode = pclose(m_progpipe); + } + else { + m_progRetCode = -1; + } + m_progpipe = NULL; + m_progpipefd = -1; + + m_progDoneFlag = true; + m_commandLoopState = 0; + } } m_criticalSection--; if (transferred_data) { diff --git a/servers/fpga_programming_server_lin/src/fpga_conn.h b/servers/fpga_programming_server_lin/src/fpga_conn.h index ec2dd65..597b4cc 100644 --- a/servers/fpga_programming_server_lin/src/fpga_conn.h +++ b/servers/fpga_programming_server_lin/src/fpga_conn.h @@ -70,6 +70,13 @@ class FPGASocket : public TDEKerberosServerSocket TQ_ULONG m_programmingFileSize; TQString m_programmingFileName; + FILE *m_progpipe; + int m_progpipefd; + + bool m_progErrorFlag; + bool m_progDoneFlag; + TQ_INT32 m_progRetCode; + TQString m_logMessages; friend class FPGAServer; }; |