Add preliminary support for UDP connection to GVRET devices, fix TCP/IP connection so it is more tolerant of network latency and jitter.

This commit is contained in:
Collin Kidder
2018-07-01 21:54:13 -04:00
parent 22386826a7
commit fba31ab641
2 changed files with 51 additions and 10 deletions
+48 -9
View File
@@ -18,9 +18,10 @@ GVRetSerial::GVRetSerial(QString portName, bool useTcp) :
serial = NULL; serial = NULL;
tcpClient = NULL; tcpClient = NULL;
udpClient = NULL;
rx_state = IDLE; rx_state = IDLE;
rx_step = 0; rx_step = 0;
gotValidated = true; validationCounter = 4; //how many times we can miss validation before we die
isAutoRestart = false; isAutoRestart = false;
timeBasis = 0; timeBasis = 0;
@@ -40,7 +41,7 @@ GVRetSerial::~GVRetSerial()
void GVRetSerial::sendToSerial(const QByteArray &bytes) void GVRetSerial::sendToSerial(const QByteArray &bytes)
{ {
if (serial == NULL && tcpClient == NULL) if (serial == NULL && tcpClient == NULL && udpClient == NULL)
{ {
debugOutput("Attempt to write to serial port when it has not been initialized!"); debugOutput("Attempt to write to serial port when it has not been initialized!");
return; return;
@@ -58,6 +59,12 @@ void GVRetSerial::sendToSerial(const QByteArray &bytes)
return; return;
} }
if (udpClient && !udpClient->isOpen())
{
debugOutput("Attempt to write to UDP Socket when it is not open!");
return;
}
QString buildDebug; QString buildDebug;
buildDebug = "Write to serial -> "; buildDebug = "Write to serial -> ";
foreach (int byt, bytes) { foreach (int byt, bytes) {
@@ -68,6 +75,7 @@ void GVRetSerial::sendToSerial(const QByteArray &bytes)
if (serial) serial->write(bytes); if (serial) serial->write(bytes);
if (tcpClient) tcpClient->write(bytes); if (tcpClient) tcpClient->write(bytes);
if (udpClient) udpClient->write(bytes);
} }
void GVRetSerial::piStarted() void GVRetSerial::piStarted()
@@ -227,8 +235,10 @@ bool GVRetSerial::piSendFrame(const CANFrame& frame)
framesRapid++; framesRapid++;
if (serial == NULL) return false; if (serial == NULL && tcpClient == NULL && udpClient == NULL) return false;
if (!serial->isOpen()) return false; if (serial && !serial->isOpen()) return false;
if (tcpClient && !tcpClient->isOpen()) return false;
if (udpClient && !udpClient->isOpen()) return false;
//if (!isConnected) return false; //if (!isConnected) return false;
// Doesn't make sense to send an error frame // Doesn't make sense to send an error frame
@@ -283,6 +293,8 @@ void GVRetSerial::connectDevice()
disconnectDevice(); disconnectDevice();
if(tcpClient) if(tcpClient)
disconnectDevice(); disconnectDevice();
if (udpClient)
disconnectDevice();
/* open new device */ /* open new device */
@@ -290,11 +302,23 @@ void GVRetSerial::connectDevice()
// if (getPort().contains('.')) //TCP/IP mode then since it looks like an IP address // if (getPort().contains('.')) //TCP/IP mode then since it looks like an IP address
if (useTcp) if (useTcp)
{ {
qDebug() << "TCP Connection to a GVRET device"; qDebug() << "TCP Connection to a GVRET device";
tcpClient = new QTcpSocket(); tcpClient = new QTcpSocket();
tcpClient->connectToHost(getPort(), 23); tcpClient->connectToHost(getPort(), 23);
connect(tcpClient, SIGNAL(readyRead()), this, SLOT(readSerialData())); connect(tcpClient, SIGNAL(readyRead()), this, SLOT(readSerialData()));
connect(tcpClient, SIGNAL(connected()), this, SLOT(tcpConnected())); connect(tcpClient, SIGNAL(connected()), this, SLOT(tcpConnected()));
debugOutput("Created TCP Socket");
/*
qDebug() << "UDP Connection to a GVRET device";
udpClient = new QUdpSocket();
udpClient->connectToHost(getPort(), 17222);
connect(udpClient, SIGNAL(readyRead()), this, SLOT(readSerialData()));
//connect(udpClient, SIGNAL(connected()), this, SLOT(tcpConnected()));
debugOutput("Created UDP Socket");
tcpConnected();
*/
} }
else { else {
qDebug() << "Serial connection to a GVRET device"; qDebug() << "Serial connection to a GVRET device";
@@ -332,6 +356,7 @@ void GVRetSerial::connectDevice()
void GVRetSerial::tcpConnected() void GVRetSerial::tcpConnected()
{ {
qDebug() << "Connected to GVRET Device!"; qDebug() << "Connected to GVRET Device!";
debugOutput("Connected to GVRET Device!");
QByteArray output; QByteArray output;
output.append((unsigned char)0xE7); //this puts the device into binary comm mode output.append((unsigned char)0xE7); //this puts the device into binary comm mode
output.append((unsigned char)0xE7); output.append((unsigned char)0xE7);
@@ -408,6 +433,17 @@ void GVRetSerial::disconnectDevice() {
delete tcpClient; delete tcpClient;
tcpClient = NULL; tcpClient = NULL;
} }
if (udpClient != NULL)
{
if (udpClient->isOpen())
{
udpClient->close();
}
udpClient->disconnect();
delete udpClient;
udpClient = NULL;
}
setStatus(CANCon::NOT_CONNECTED); setStatus(CANCon::NOT_CONNECTED);
CANConStatus stats; CANConStatus stats;
stats.conStatus = getStatus(); stats.conStatus = getStatus();
@@ -491,7 +527,7 @@ void GVRetSerial::connectionTimeout()
{ {
//one second after trying to connect are we actually connected? //one second after trying to connect are we actually connected?
//if (CANCon::NOT_CONNECTED==getStatus()) //no? //if (CANCon::NOT_CONNECTED==getStatus()) //no?
if (!gotValidated) if (validationCounter == 0)
{ {
//then emit the the failure signal and see if anyone cares //then emit the the failure signal and see if anyone cares
qDebug() << "Failed to connect to GVRET at that com port"; qDebug() << "Failed to connect to GVRET at that com port";
@@ -509,6 +545,7 @@ void GVRetSerial::readSerialData()
if (serial) data = serial->readAll(); if (serial) data = serial->readAll();
if (tcpClient) data = tcpClient->readAll(); if (tcpClient) data = tcpClient->readAll();
if (udpClient) data = udpClient->readAll();
debugOutput("Got data from serial. Len = " % QString::number(data.length())); debugOutput("Got data from serial. Len = " % QString::number(data.length()));
//qDebug() << (tr("Got data from serial. Len = %0").arg(data.length())); //qDebug() << (tr("Got data from serial. Len = %0").arg(data.length()));
@@ -571,7 +608,7 @@ void GVRetSerial::procRXChar(unsigned char c)
rx_step = 0; rx_step = 0;
break; break;
case 9: case 9:
gotValidated = true; validationCounter++;
//qDebug() << "Got validated"; //qDebug() << "Got validated";
rx_state = IDLE; rx_state = IDLE;
break; break;
@@ -932,10 +969,12 @@ void GVRetSerial::handleTick()
if( CANCon::CONNECTED == getStatus() ) if( CANCon::CONNECTED == getStatus() )
{ {
if (!gotValidated && doValidation) if (doValidation) validationCounter--;
qDebug() << validationCounter;
if (validationCounter == 0 && doValidation)
{ {
if (serial == NULL && tcpClient == NULL) return; if (serial == NULL && tcpClient == NULL) return;
if ( (serial && serial->isOpen()) || (tcpClient && tcpClient->isOpen())) //if it's still false we have a problem... if ( (serial && serial->isOpen()) || (tcpClient && tcpClient->isOpen()) || (udpClient && udpClient->isOpen())) //if it's still false we have a problem...
{ {
qDebug() << "Comm validation failed. "; qDebug() << "Comm validation failed. ";
@@ -952,6 +991,7 @@ void GVRetSerial::handleTick()
} }
if (doValidation && serial && serial->isOpen()) sendCommValidation(); if (doValidation && serial && serial->isOpen()) sendCommValidation();
if (doValidation && tcpClient && tcpClient->isOpen()) sendCommValidation(); if (doValidation && tcpClient && tcpClient->isOpen()) sendCommValidation();
if (doValidation && udpClient && udpClient->isOpen()) sendCommValidation();
} }
@@ -959,7 +999,6 @@ void GVRetSerial::sendCommValidation()
{ {
QByteArray output; QByteArray output;
gotValidated = false;
output.append((unsigned char)0xF1); //another command to the GVRET output.append((unsigned char)0xF1); //another command to the GVRET
output.append((unsigned char)0x09); //request a reply to get validation output.append((unsigned char)0x09); //request a reply to get validation
+3 -1
View File
@@ -6,6 +6,7 @@
#include <QThread> #include <QThread>
#include <QTimer> #include <QTimer>
#include <QTcpSocket> #include <QTcpSocket>
#include <QUdpSocket>
/*************/ /*************/
#include <QDateTime> #include <QDateTime>
@@ -79,12 +80,13 @@ protected:
QThread mThread; QThread mThread;
bool doValidation; bool doValidation;
bool gotValidated; int validationCounter;
bool isAutoRestart; bool isAutoRestart;
bool continuousTimeSync; bool continuousTimeSync;
bool useTcp; bool useTcp;
QSerialPort *serial; QSerialPort *serial;
QTcpSocket *tcpClient; QTcpSocket *tcpClient;
QUdpSocket *udpClient;
int framesRapid; int framesRapid;
STATE rx_state; STATE rx_state;
uint32_t rx_step; uint32_t rx_step;