ZT/sources/TCPProtocol.cpp

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;
}