420 lines
12 KiB
C++
420 lines
12 KiB
C++
/*******************************************************************************
|
|
* *
|
|
* Société de Transports de Montréal. *
|
|
* 2015 *
|
|
* *
|
|
* Projet Zones Tests *
|
|
* *
|
|
* *
|
|
* *
|
|
*******************************************************************************/
|
|
/*
|
|
Description:
|
|
Classe qui contient toute la logique du protocole de communication par réseau
|
|
entre la Zone Test et le logiciel d'analyse.
|
|
|
|
*/
|
|
|
|
/* ************************************************************************** */
|
|
/* Revision:
|
|
### 20121210 JFM
|
|
Verision d'origine.
|
|
|
|
### YYYYMMDD Description du besoin ou du bug
|
|
Description du changement.
|
|
*/
|
|
|
|
/* ************************************************************************** */
|
|
|
|
#include "TCPProtocol.h"
|
|
#include <QByteArray>
|
|
#include <QDataStream>
|
|
#include <QDebug>
|
|
|
|
CTCPProtocol::CTCPProtocol()
|
|
{
|
|
}
|
|
//
|
|
unsigned int CTCPProtocol::AnalyzeNewData(QByteArray data)
|
|
{
|
|
QDataStream stream(data);
|
|
stream.device()->seek(0);
|
|
|
|
switch(mProtocolRxState)
|
|
{
|
|
case TCP_PROTOCOL_GET_HEADER_STATE:
|
|
{
|
|
quint32 header = 0;
|
|
qint32 msg = 0;
|
|
|
|
stream >> header;
|
|
|
|
if(header != TCP_PROTOCOL_HEADER)
|
|
{
|
|
return RET_ERROR;
|
|
}
|
|
|
|
stream >> msg;
|
|
stream >> mCurTransactionDataSize;
|
|
|
|
mCurTransactionMsg = (eTCPMessage)msg;
|
|
|
|
if(mCurTransactionDataSize != 0)
|
|
{
|
|
mCurTransactionData = stream.device()->readAll();
|
|
if(mCurTransactionData.size() < mCurTransactionDataSize)
|
|
{
|
|
mProtocolRxState = TCP_PROTOCOL_GET_DATA_STATE;
|
|
}
|
|
else if(mCurTransactionData.size() > mCurTransactionDataSize)
|
|
{
|
|
//error
|
|
qDebug("Rx data > Transaction data. Aborting transaction");
|
|
ResetRxStateMachine();
|
|
}
|
|
else
|
|
{
|
|
DecodeTCPMessage();
|
|
ResetRxStateMachine();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DecodeTCPMessage();
|
|
ResetRxStateMachine();
|
|
}
|
|
|
|
break;
|
|
}
|
|
case TCP_PROTOCOL_GET_MSG_STATE:
|
|
{
|
|
break;
|
|
}
|
|
case TCP_PROTOCOL_GET_DATASIZE_STATE:
|
|
{
|
|
break;
|
|
}
|
|
case TCP_PROTOCOL_GET_DATA_STATE:
|
|
{
|
|
mCurTransactionData.append(data);
|
|
if(mCurTransactionData.size() == mCurTransactionDataSize)
|
|
{
|
|
//All data received
|
|
DecodeTCPMessage();
|
|
ResetRxStateMachine();
|
|
}
|
|
else if(mCurTransactionData.size() > mCurTransactionDataSize)
|
|
{
|
|
//error
|
|
qDebug("Rx data > Transaction data. Aborting transaction");
|
|
ResetRxStateMachine();
|
|
}
|
|
else
|
|
{
|
|
qDebug() << "Chunk received. New data size = " << mCurTransactionData.size();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
QByteArray CTCPProtocol::GetHeartbeatPacket()
|
|
{
|
|
QByteArray request;
|
|
QDataStream stream(&request,QIODevice::WriteOnly);
|
|
stream.device()->seek(0);
|
|
|
|
request.clear();
|
|
stream << TCP_PROTOCOL_HEADER << (qint32)TCP_MSG_HEARTBEAT_RESPONSE << (qint64)0; ;
|
|
//no data...
|
|
|
|
// TCPTxRequest(request);
|
|
|
|
|
|
return request;
|
|
}
|
|
|
|
QByteArray CTCPProtocol::GetStationNamePacket(QString StationName)
|
|
{
|
|
QByteArray request;
|
|
QDataStream stream(&request,QIODevice::WriteOnly);
|
|
stream.device()->seek(0);
|
|
|
|
|
|
request.clear();
|
|
stream << TCP_PROTOCOL_HEADER;
|
|
stream << (qint32)TCP_MSG_STATION_NAME_RESPONSE;
|
|
stream << (qint64)StationName.size();
|
|
request.append(StationName);
|
|
|
|
//no data...
|
|
|
|
// TCPTxRequest(request);
|
|
return request;
|
|
}
|
|
|
|
QByteArray CTCPProtocol::GetZTStatusPacket(CTCPZTStatus *Status)
|
|
{
|
|
QByteArray request;
|
|
request.clear();
|
|
QByteArray data;
|
|
data.clear();
|
|
|
|
QDataStream datastream(&data,QIODevice::WriteOnly);
|
|
datastream.device()->seek(0);
|
|
datastream << *Status;
|
|
|
|
QDataStream requeststream(&request,QIODevice::WriteOnly);
|
|
requeststream.device()->seek(0);
|
|
|
|
requeststream << TCP_PROTOCOL_HEADER
|
|
<< (qint32)TCP_MSG_ZT_STATUS_RESPONSE
|
|
<< (qint64)data.size();
|
|
|
|
request.append(data);
|
|
|
|
// TCPTxRequest(request);
|
|
|
|
return request;
|
|
}
|
|
|
|
QByteArray CTCPProtocol::GetZTLogPacket(QString *ZTLog)
|
|
{
|
|
QByteArray request;
|
|
request.clear();
|
|
QByteArray data;
|
|
data.clear();
|
|
|
|
data = ZTLog->toUtf8();
|
|
|
|
QDataStream requeststream(&request,QIODevice::WriteOnly);
|
|
requeststream.device()->seek(0);
|
|
|
|
requeststream << TCP_PROTOCOL_HEADER
|
|
<< (qint32)TCP_MSG_ZTLOG_DOWNLOAD_RESPONSE
|
|
<< (qint64)data.size();
|
|
|
|
request.append(data);
|
|
return request;
|
|
}
|
|
|
|
QByteArray CTCPProtocol::GetTrainLogsDownloadAckPacket(qint32 FileCount)
|
|
{
|
|
QByteArray request;
|
|
request.clear();
|
|
|
|
QDataStream requeststream(&request,QIODevice::WriteOnly);
|
|
requeststream.device()->seek(0);
|
|
|
|
requeststream << TCP_PROTOCOL_HEADER
|
|
<< (qint32)TCP_MSG_TRAINSLOGS_DOWNLOAD_ACK
|
|
<< (qint64)sizeof(FileCount)
|
|
<< FileCount;
|
|
|
|
return request;
|
|
}
|
|
|
|
QByteArray *CTCPProtocol::GetTrainLogDataPacket(const QByteArray &FileData)
|
|
{
|
|
QByteArray *request = new QByteArray;
|
|
request->clear();
|
|
|
|
QDataStream requeststream(request,QIODevice::WriteOnly);
|
|
requeststream.device()->seek(0);
|
|
|
|
requeststream << TCP_PROTOCOL_HEADER
|
|
<< (qint32)TCP_MSG_TRAINLOG_FILE_DATA
|
|
<< (qint64)FileData.size();
|
|
|
|
request->append(FileData);
|
|
|
|
return request; //MUST BE DELETED BY CALLER !!!!
|
|
}
|
|
|
|
QByteArray CTCPProtocol::GetTrainLogsDownloadFinishedPacket()
|
|
{
|
|
QByteArray request;
|
|
QDataStream stream(&request,QIODevice::WriteOnly);
|
|
stream.device()->seek(0);
|
|
|
|
request.clear();
|
|
stream << TCP_PROTOCOL_HEADER << (qint32)TCP_MSG_TRAINLOGS_DOWNLOAD_FINISHED << (qint64)0; ;
|
|
|
|
return request;
|
|
}
|
|
|
|
QByteArray CTCPProtocol::GetDeleteZTLogsAckPacket(qint32 Acknowledge)
|
|
{
|
|
QByteArray request;
|
|
QDataStream stream(&request,QIODevice::WriteOnly);
|
|
stream.device()->seek(0);
|
|
|
|
request.clear();
|
|
stream << TCP_PROTOCOL_HEADER << (qint32)TCP_MSG_DELETE_ZTLOG_ACK << (qint64)4 << Acknowledge;
|
|
|
|
return request;
|
|
}
|
|
|
|
QByteArray CTCPProtocol::GetSetZTFunctionsConfigAckPacket(qint32 Ack)
|
|
{
|
|
QByteArray request;
|
|
QDataStream stream(&request,QIODevice::WriteOnly);
|
|
stream.device()->seek(0);
|
|
|
|
request.clear();
|
|
stream << TCP_PROTOCOL_HEADER << (qint32)TCP_MSG_SET_ZT_FUNCTIONS_ACK << (qint64)4 << Ack;
|
|
|
|
return request;
|
|
}
|
|
|
|
|
|
void CTCPProtocol::TCPTxRequest(QByteArray request)
|
|
{
|
|
Q_UNUSED(request)
|
|
qDebug("No reimplementation of TXRequest in TCPProtocol.c. Request not sent...");
|
|
}
|
|
|
|
void CTCPProtocol::ResetRxStateMachine()
|
|
{
|
|
mCurTransactionData.clear();
|
|
mCurTransactionDataSize = 0;
|
|
mCurTransactionMsg = TCP_MSG_UNKNOWN;
|
|
mProtocolRxState = TCP_PROTOCOL_GET_HEADER_STATE;
|
|
|
|
}
|
|
|
|
int CTCPProtocol::DecodeTCPMessage()
|
|
{
|
|
switch(mCurTransactionMsg)
|
|
{
|
|
case TCP_MSG_HEARTBEAT_REQUEST:
|
|
{
|
|
TCPHeartbeatRequest();
|
|
break;
|
|
}
|
|
case TCP_MSG_STATION_NAME_REQUEST:
|
|
{
|
|
TCPStationNameRequest();
|
|
break;
|
|
}
|
|
case TCP_MSG_ZT_STATUS_REQUEST:
|
|
{
|
|
TCPStatusRequest();
|
|
break;
|
|
}
|
|
case TCP_MSG_ZTLOG_DOWNLOAD_REQUEST:
|
|
{
|
|
TCPZTLogDownloadRequest();
|
|
break;
|
|
}
|
|
case TCP_MSG_TRAINLOGS_DOWNLOAD_REQUEST:
|
|
{
|
|
TCPTrainLogsDownloadRequest();
|
|
break;
|
|
}
|
|
case TCP_MSG_TRAINLOG_FILE_DATA_ACK:
|
|
{
|
|
qint32 ack = TCP_PROTOCOL_INVALID_ACK;
|
|
QDataStream strm(mCurTransactionData);
|
|
strm.device()->seek(0);
|
|
strm >> ack;
|
|
|
|
TCPTrainLogFileDataAck((eTCPProtocolAcknowledge)ack);
|
|
|
|
break;
|
|
}
|
|
case TCP_MSG_DELETE_ZTLOG_REQUEST:
|
|
{
|
|
TCPDeleteZTLogRequest();
|
|
break;
|
|
}
|
|
case TCP_MSG_SET_ZT_FUNCTIONS:
|
|
{
|
|
TCPSetZTFunctionsConfigRequest(mCurTransactionData);
|
|
break;
|
|
}
|
|
|
|
case TCP_MSG_SET_ZT_FUNCTIONS_ACK:
|
|
case TCP_MSG_DELETE_ZTLOG_ACK:
|
|
case TCP_MSG_ZT_STATUS_RESPONSE:
|
|
case TCP_MSG_HEARTBEAT_RESPONSE:
|
|
case TCP_MSG_STATION_NAME_RESPONSE:
|
|
case TCP_MSG_ZTLOG_DOWNLOAD_RESPONSE:
|
|
case TCP_MSG_TRAINSLOGS_DOWNLOAD_ACK:
|
|
case TCP_MSG_TRAINLOG_FILE_DATA:
|
|
case TCP_MSG_TRAINLOGS_DOWNLOAD_FINISHED:
|
|
case TCP_MSG_UNKNOWN:
|
|
{
|
|
qDebug() << "Received invalid msg:" << mCurTransactionMsg;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
QDataStream &operator<<(QDataStream &out, const CTCPZTStatus &source)
|
|
{
|
|
out << source.mZT1Status
|
|
<< source.mZT2Status
|
|
<< source.mNbPass
|
|
<< source.mNbTrigs
|
|
<< source.mZTStartDateTime
|
|
<< source.mActualDateTime
|
|
<< source.mPGTreshold
|
|
<< source.mModeMaintenanceON
|
|
<< source.mCalibModeON
|
|
<< source.mFNTKActive
|
|
<< source.mFNAnalysisActive
|
|
<< source.mPGTKActive
|
|
<< source.mPGAnalysisActive
|
|
<< source.mPP1TKActive
|
|
<< source.mPP1AnalysisActive
|
|
<< source.mPP2TKActive
|
|
<< source.mPP2AnalysisActive
|
|
<< source.mZT1TKActive
|
|
<< source.mZT1AnalysisActive
|
|
<< source.mZT2TKActive
|
|
<< source.mZT2AnalysisActive
|
|
<< source.mUSBKeyConnected;
|
|
|
|
return out;
|
|
}
|
|
QDataStream &operator>>(QDataStream &in, CTCPZTFunctionsStatus &dest)
|
|
{
|
|
in >> dest.mFNTKActive
|
|
>> dest.mFNAnalysisActive
|
|
>> dest.mPGTKActive
|
|
>> dest.mPGAnalysisActive
|
|
>> dest.mPP1TKActive
|
|
>> dest.mPP1AnalysisActive
|
|
>> dest.mPP2TKActive
|
|
>> dest.mPP2AnalysisActive
|
|
>> dest.mZT1TKActive
|
|
>> dest.mZT1AnalysisActive
|
|
>> dest.mZT2TKActive
|
|
>> dest.mZT2AnalysisActive;
|
|
|
|
return in;
|
|
}
|
|
|
|
QDataStream &operator<<(QDataStream &out, const CTCPZTFunctionsStatus &source)
|
|
{
|
|
out << source.mFNTKActive
|
|
<< source.mFNAnalysisActive
|
|
<< source.mPGTKActive
|
|
<< source.mPGAnalysisActive
|
|
<< source.mPP1TKActive
|
|
<< source.mPP1AnalysisActive
|
|
<< source.mPP2TKActive
|
|
<< source.mPP2AnalysisActive
|
|
<< source.mZT1TKActive
|
|
<< source.mZT1AnalysisActive
|
|
<< source.mZT2TKActive
|
|
<< source.mZT2AnalysisActive;
|
|
|
|
return out;
|
|
}
|