501 lines
14 KiB
C++
501 lines
14 KiB
C++
#include "NetworkManager.h"
|
|
#include <QDebug>
|
|
#include "OutilZT.h"
|
|
|
|
CNetworkManager CNetworkManager::mSingleton;
|
|
|
|
CNetworkManager::CNetworkManager(QObject *parent) :
|
|
QObject(parent)
|
|
{
|
|
mConfig = 0;
|
|
mCurZTID = 0;
|
|
mProgramHandle = 0;
|
|
mZTUDPSocket = 0;
|
|
mUDPServerAdress = QHostAddress::Null;
|
|
|
|
mNetworkSMState = NETWORK_SM_STANDBY_STATE;
|
|
mOnlineCheckNetworkSMState = NETWORK_ONLINE_CHK_SM_STANDBY_STATE;
|
|
|
|
// mZTTcpSocket.setSocketOption(QAbstractSocket::LowDelayOption,1);
|
|
connect(&mZTTcpSocket,SIGNAL(connected()),this,SLOT(SocketConnected()));
|
|
connect(&mZTTcpSocket,SIGNAL(disconnected()),this,SLOT(SocketDisconnected()));
|
|
connect(&mZTTcpSocket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(SocketError(QAbstractSocket::SocketError)));
|
|
connect(&mZTTcpSocket,SIGNAL(readyRead()),this,SLOT(SocketDataReady()));
|
|
|
|
mZTOnlineCheckingSocket.setSocketOption(QAbstractSocket::LowDelayOption,1);
|
|
connect(&mZTOnlineCheckingSocket,SIGNAL(connected()),this,SLOT(OnlineCheckSocketConnected()));
|
|
connect(&mZTOnlineCheckingSocket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(OnlineCheckSocketError(QAbstractSocket::SocketError)));
|
|
|
|
}
|
|
CNetworkManager::~CNetworkManager()
|
|
{
|
|
mZTTcpSocket.disconnectFromHost();
|
|
mZTOnlineCheckingSocket.disconnectFromHost();
|
|
}
|
|
|
|
void CNetworkManager::BindPointers(COutilZT *ProgramHandle)
|
|
{
|
|
mProgramHandle = ProgramHandle;
|
|
}
|
|
|
|
void CNetworkManager::OnlineCheckStateMachine(eNetworkSMEvent event)
|
|
{
|
|
switch(mOnlineCheckNetworkSMState)
|
|
{
|
|
case NETWORK_ONLINE_CHK_SM_INIT_STATE:
|
|
{
|
|
break;
|
|
}
|
|
case NETWORK_ONLINE_CHK_SM_STANDBY_STATE:
|
|
{
|
|
break;
|
|
}
|
|
case NETWORK_ONLINE_CHK_SM_CHECK_CONNECTIONS_STATE:
|
|
{
|
|
switch(event)
|
|
{
|
|
case NETWORK_SM_SOCKET_CONNECTED_EVENT:
|
|
{
|
|
// qDebug("%s Connected",mConfig->mNetworkCfgList.at(mCurZTID).mIPAdress.toAscii().data());
|
|
emit NetworkZTConnectionStatus(mOnlineCheckZTID,ZT_NETWORK_ONLINE_STATUS);
|
|
break;
|
|
}
|
|
case NETWORK_SM_SOCKET_ERROR_EVENT:
|
|
{
|
|
// qDebug("%s Not connected",mConfig->mNetworkCfgList.at(mCurZTID).mIPAdress.toAscii().data());
|
|
emit NetworkZTConnectionStatus(mOnlineCheckZTID,ZT_NETWORK_OFFLINE_STATUS);
|
|
break;
|
|
}
|
|
case NETWORK_SM_SOCKET_DISCONNECTED_EVENT:
|
|
{
|
|
//Nothing to do here but we need to manage it because it will be received each time we disconnect.
|
|
return;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
// qDebug("Unmanaged event in NETWORK_ONLINE_CHK_SM_CHECK_CONNECTIONS_STATE : %d",event);
|
|
return;
|
|
break;
|
|
}
|
|
}
|
|
|
|
mOnlineCheckZTID++;
|
|
if(mNetworkSMState != NETWORK_SM_STANDBY_STATE)
|
|
{
|
|
//Skip the connected ZT if there is one.
|
|
if(mOnlineCheckZTID == mCurZTID)
|
|
{
|
|
mOnlineCheckZTID++;
|
|
}
|
|
}
|
|
if(mOnlineCheckZTID >= NB_ZT_ID)
|
|
{
|
|
mOnlineCheckNetworkSMState = NETWORK_ONLINE_CHK_SM_STANDBY_STATE;
|
|
mZTOnlineCheckingSocket.disconnectFromHost();
|
|
}
|
|
else
|
|
{
|
|
mZTOnlineCheckingSocket.disconnectFromHost();
|
|
// qDebug("Attempting to connect to %s",mConfig->mNetworkCfgList.at(mOnlineCheckZTID).mIPAdress.toAscii().data());
|
|
emit NetworkZTConnectionStatus(mOnlineCheckZTID,ZT_NETWORK_SEARCHING_STATUS);
|
|
mZTOnlineCheckingSocket.connectToHost(mConfig->mNetworkCfgList.at(mOnlineCheckZTID).mIPAdress,ZT_TCP_PORT);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CNetworkManager::NetworkStateMachine(eNetworkSMEvent event)
|
|
{
|
|
switch(mNetworkSMState)
|
|
{
|
|
case NETWORK_SM_INIT_STATE:
|
|
{
|
|
break;
|
|
}
|
|
case NETWORK_SM_STANDBY_STATE:
|
|
{
|
|
break;
|
|
}
|
|
case NETWORK_SM_INITIATE_CLIENT_CONNECTION_STATE:
|
|
{
|
|
switch(event)
|
|
{
|
|
case NETWORK_SM_SOCKET_CONNECTED_EVENT:
|
|
{
|
|
qDebug("%s Connected",mConfig->mNetworkCfgList.at(mCurZTID).mIPAdress.toAscii().data());
|
|
emit NetworkZTConnected(mCurZTID);
|
|
emit NetworkZTConnectionStatus(mCurZTID,ZT_NETWORK_CONNECTED_STATUS);
|
|
|
|
//RequestHeartbeat();
|
|
//mZTTcpSocket.write(GetStationNameReqPacket());
|
|
TCPTxRequest(GetStationNameReqPacket());
|
|
mNetworkSMState = NETWORK_SM_CLIENT_CONNECTED_STATE;
|
|
break;
|
|
}
|
|
case NETWORK_SM_SOCKET_ERROR_EVENT:
|
|
{
|
|
qDebug("%s Socket error",mConfig->mNetworkCfgList.at(mCurZTID).mIPAdress.toAscii().data());
|
|
emit NetworkZTConnectionError(mCurZTID);
|
|
mNetworkSMState = NETWORK_SM_STANDBY_STATE;
|
|
break;
|
|
}
|
|
case NETWORK_SM_SOCKET_DISCONNECTED_EVENT:
|
|
{
|
|
mNetworkSMState = NETWORK_SM_STANDBY_STATE;
|
|
emit NetworkZTConnectionStatus(mOnlineCheckZTID,ZT_NETWORK_UNKNOWN_STATUS);
|
|
emit NetworkZTConnectionError(mCurZTID);
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
mNetworkSMState = NETWORK_SM_STANDBY_STATE;
|
|
qDebug("Invalid event in NETWORK_SM_INITIATE_CLIENT_CONNECTION_STATE : %d",event);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case NETWORK_SM_CLIENT_CONNECTED_STATE:
|
|
{
|
|
switch(event)
|
|
{
|
|
case NETWORK_SM_SOCKET_ERROR_EVENT:
|
|
{
|
|
qDebug("%s Socket error",mConfig->mNetworkCfgList.at(mCurZTID).mIPAdress.toAscii().data());
|
|
break;
|
|
}
|
|
case NETWORK_SM_SOCKET_DISCONNECTED_EVENT:
|
|
{
|
|
emit NetworkZTDisconnected(mCurZTID);
|
|
emit NetworkZTConnectionStatus(mCurZTID,ZT_NETWORK_UNKNOWN_STATUS);
|
|
mNetworkSMState = NETWORK_SM_STANDBY_STATE;
|
|
//qDebug("%s Disconnected",mConfig->mNetworkCfgList.at(mCurZTID).mIPAdress.toAscii().data());
|
|
qDebug("TCP Socket disconnected");
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
qDebug("Unmanaged event in NETWORK_SM_CLIENT_CONNECTED_STATE : %d",event);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
unsigned int CNetworkManager::InitUDPConnection(int ZTID)
|
|
{
|
|
mZTUDPSocket = new QUdpSocket(this);
|
|
if(mZTUDPSocket->bind(QHostAddress::Any,ZT_UDP_PORT) == false)
|
|
return RET_ERROR;
|
|
|
|
mUDPServerAdress = QHostAddress(mConfig->mNetworkCfgList.at(ZTID).mIPAdress);
|
|
|
|
connect(mZTUDPSocket,SIGNAL(readyRead()),this,SLOT(UDPSocketDataReady()));
|
|
|
|
QByteArray packet = GetInitUDPConnectionPacket();
|
|
mZTUDPSocket->writeDatagram(packet,mUDPServerAdress,ZT_UDP_PORT);
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
unsigned int CNetworkManager::StopUDPStream()
|
|
{
|
|
if(mZTUDPSocket == 0)
|
|
return RET_ERROR;
|
|
|
|
|
|
QByteArray packet = GetCloseUDPConnectionPacket();
|
|
mZTUDPSocket->writeDatagram(packet,mUDPServerAdress,ZT_UDP_PORT);
|
|
mZTUDPSocket->waitForBytesWritten();
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
unsigned int CNetworkManager::CloseUDPConnection()
|
|
{
|
|
if(mZTUDPSocket == 0)
|
|
return RET_ERROR;
|
|
|
|
|
|
// QByteArray packet = GetCloseUDPConnectionPacket();
|
|
// mZTUDPSocket->writeDatagram(packet,mUDPServerAdress,ZT_UDP_PORT);
|
|
// mZTUDPSocket->flush();
|
|
|
|
delete mZTUDPSocket;
|
|
mZTUDPSocket = 0;
|
|
mUDPServerAdress = QHostAddress::Null;
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
int CNetworkManager::CheckZTConnectionsStatus()
|
|
{
|
|
if(mOnlineCheckNetworkSMState != NETWORK_ONLINE_CHK_SM_STANDBY_STATE)
|
|
return RET_ERROR;
|
|
|
|
mOnlineCheckZTID = 0;
|
|
mOnlineCheckNetworkSMState = NETWORK_ONLINE_CHK_SM_CHECK_CONNECTIONS_STATE;
|
|
|
|
emit NetworkZTConnectionStatus(mOnlineCheckZTID,ZT_NETWORK_SEARCHING_STATUS);
|
|
// qDebug("Attempting to connect to %s",mConfig->mNetworkCfgList.at(mOnlineCheckZTID).mIPAdress.toAscii().data());
|
|
mZTOnlineCheckingSocket.connectToHost(mConfig->mNetworkCfgList.at(mOnlineCheckZTID).mIPAdress,ZT_TCP_PORT);
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
|
|
unsigned int CNetworkManager::SetConfig(CSettingsData *Config)
|
|
{
|
|
mConfig = Config;
|
|
return RET_OK;
|
|
}
|
|
|
|
unsigned int CNetworkManager::ConnectToZT(int ZTID)
|
|
{
|
|
if(ZTID >= NB_ZT_ID)
|
|
{
|
|
qDebug("Cannot connect: Invalid ZT ID");
|
|
return RET_ERROR;
|
|
}
|
|
|
|
if(mNetworkSMState != NETWORK_SM_STANDBY_STATE)
|
|
{
|
|
qDebug("Cannot connect: Invalid State machine state : %d",mNetworkSMState);
|
|
return RET_ERROR;
|
|
}
|
|
|
|
|
|
mCurZTID = ZTID;
|
|
mNetworkSMState = NETWORK_SM_INITIATE_CLIENT_CONNECTION_STATE;
|
|
mZTTcpSocket.connectToHost(mConfig->mNetworkCfgList.at(mCurZTID).mIPAdress,ZT_TCP_PORT);
|
|
qDebug("Connecting to %s", mConfig->mNetworkCfgList.at(mCurZTID).mIPAdress.toAscii().data());
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
unsigned int CNetworkManager::DisconnectZT()
|
|
{
|
|
// if(mNetworkSMState == NETWORK_SM_STANDBY_STATE)
|
|
// return RET_ERROR;
|
|
|
|
if(mNetworkSMState != NETWORK_SM_CLIENT_CONNECTED_STATE)
|
|
{
|
|
qDebug("Aborting connection from ZT. Socket state : %d",mZTTcpSocket.state());
|
|
mZTTcpSocket.abort();
|
|
NetworkStateMachine(NETWORK_SM_SOCKET_DISCONNECTED_EVENT);
|
|
}
|
|
else
|
|
{
|
|
qDebug("Disconnecting from ZT. Socket state : %d",mZTTcpSocket.state());
|
|
mZTTcpSocket.disconnectFromHost();
|
|
}
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
void CNetworkManager::TCPTxRequest(const QByteArray &request)
|
|
{
|
|
qDebug() << "Tx request in Network Manager : " << request.size() << " bytes : " << request.toHex();
|
|
emit NetworkTCPTx();
|
|
mZTTcpSocket.write(request);
|
|
}
|
|
|
|
unsigned int CNetworkManager::RefreshRemoteZTStatus()
|
|
{
|
|
if(mNetworkSMState != NETWORK_SM_CLIENT_CONNECTED_STATE)
|
|
return RET_ERROR;
|
|
|
|
TCPTxRequest(GetZTStatusReqPacket());
|
|
return RET_OK;
|
|
}
|
|
|
|
unsigned int CNetworkManager::DownloadZTLog()
|
|
{
|
|
if(mNetworkSMState != NETWORK_SM_CLIENT_CONNECTED_STATE)
|
|
return RET_ERROR;
|
|
|
|
TCPTxRequest(GetZTLogDownloadReqPacket());
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
unsigned int CNetworkManager::DownloadTrainLogs()
|
|
{
|
|
if(mNetworkSMState != NETWORK_SM_CLIENT_CONNECTED_STATE)
|
|
return RET_ERROR;
|
|
|
|
TCPTxRequest(GetTrainLogsDownloadReqPacket());
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
unsigned int CNetworkManager::DeleteRemoteZTLog()
|
|
{
|
|
if(mNetworkSMState != NETWORK_SM_CLIENT_CONNECTED_STATE)
|
|
return RET_ERROR;
|
|
TCPTxRequest(GetDeleteZTLogReqPacket());
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
unsigned int CNetworkManager::SetZTFunctions(const CTCPZTFunctionsStatus &ZTFunctions)
|
|
{
|
|
if(mNetworkSMState != NETWORK_SM_CLIENT_CONNECTED_STATE)
|
|
return RET_ERROR;
|
|
|
|
QByteArray data;
|
|
QDataStream strm(&data,QIODevice::WriteOnly);
|
|
strm.device()->seek(0);
|
|
|
|
strm << ZTFunctions;
|
|
|
|
TCPTxRequest(GetSetZTFunctionsPacket(data));
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
|
|
//slots
|
|
void CNetworkManager::SocketConnected()
|
|
{
|
|
qDebug("Socket connected slot");
|
|
NetworkStateMachine(NETWORK_SM_SOCKET_CONNECTED_EVENT);
|
|
}
|
|
void CNetworkManager::SocketDisconnected()
|
|
{
|
|
qDebug("Socket disconnected slot");
|
|
NetworkStateMachine(NETWORK_SM_SOCKET_DISCONNECTED_EVENT);
|
|
}
|
|
void CNetworkManager::SocketError(QAbstractSocket::SocketError socketError)
|
|
{
|
|
qDebug("Socket error slot. Error:[%d]",socketError);
|
|
NetworkStateMachine(NETWORK_SM_SOCKET_ERROR_EVENT);
|
|
}
|
|
void CNetworkManager::SocketDataReady()
|
|
{
|
|
// qDebug() << "Socket data ready:" << mZTTcpSocket.bytesAvailable();
|
|
emit NetworkTCPRx();
|
|
AnalyzeNewData(mZTTcpSocket.readAll());
|
|
}
|
|
void CNetworkManager::OnlineCheckSocketConnected()
|
|
{
|
|
OnlineCheckStateMachine(NETWORK_SM_SOCKET_CONNECTED_EVENT);
|
|
}
|
|
void CNetworkManager::OnlineCheckSocketError(QAbstractSocket::SocketError socketError)
|
|
{
|
|
OnlineCheckStateMachine(NETWORK_SM_SOCKET_ERROR_EVENT);
|
|
}
|
|
|
|
void CNetworkManager::TCPRxHeartbeat()
|
|
{
|
|
qDebug() << "TCP: Received Heartbeat";
|
|
}
|
|
|
|
void CNetworkManager::TCPRxStationName(QString Name)
|
|
{
|
|
qDebug() << "TCP: Received station name:" << Name;
|
|
mProgramHandle->RxStationName(Name);
|
|
|
|
mZTTcpSocket.write(GetZTStatusReqPacket());
|
|
}
|
|
|
|
void CNetworkManager::TCPRxZTStatus(const QByteArray &data)
|
|
{
|
|
|
|
CTCPZTStatus status;
|
|
|
|
QDataStream stream(data);
|
|
stream.device()->seek(0);
|
|
|
|
stream >> status;
|
|
|
|
qDebug() << "TCP: Received ZT Status";
|
|
|
|
mProgramHandle->RxZTStatus(status);
|
|
}
|
|
|
|
void CNetworkManager::TCPRxZTLog(QString ZTLog)
|
|
{
|
|
mProgramHandle->RxZTLog(ZTLog);
|
|
}
|
|
|
|
void CNetworkManager::TCPRxTrainLogsDownladAck(qint32 NbFiles)
|
|
{
|
|
qDebug("TCP: Received downoad train files ack : %d",NbFiles);
|
|
mProgramHandle->DownloadTrainLogsBegin(NbFiles);
|
|
|
|
|
|
mZTTcpSocket.write(GetTrainLogsFileDataAckPacket((qint32)TCP_PROTOCOL_ACK));
|
|
}
|
|
|
|
void CNetworkManager::TCPRxTrainLogFileData(const QByteArray &TrainFileData)
|
|
{
|
|
QDataStream strm(TrainFileData);
|
|
strm.device()->seek(0);
|
|
|
|
QString LogFilePathName;
|
|
strm >> LogFilePathName;
|
|
|
|
LogFilePathName.prepend(mProgramHandle->GetTrainLogsTempPath());
|
|
|
|
QFile* BinaryLogFile = new QFile(LogFilePathName);
|
|
if(BinaryLogFile)
|
|
{
|
|
if(BinaryLogFile->open(QIODevice::WriteOnly) == false)
|
|
{
|
|
qDebug("Could not create log file : %s",LogFilePathName.toLatin1().data());
|
|
delete BinaryLogFile;
|
|
return;
|
|
}
|
|
}
|
|
|
|
BinaryLogFile->write(strm.device()->readAll());
|
|
|
|
BinaryLogFile->close();
|
|
delete BinaryLogFile;
|
|
|
|
mProgramHandle->RxTrainLogData(LogFilePathName);
|
|
|
|
mZTTcpSocket.write(GetTrainLogsFileDataAckPacket((qint32)TCP_PROTOCOL_ACK));
|
|
}
|
|
|
|
void CNetworkManager::TCPRxTrainLogsDownloadFinished()
|
|
{
|
|
mProgramHandle->RxTrainLogsDownloadFinished();
|
|
}
|
|
|
|
void CNetworkManager::TCPRxDeleteZTLogAck(bool success)
|
|
{
|
|
mProgramHandle->RemoteZTLogDeleted(success);
|
|
}
|
|
|
|
void CNetworkManager::TCPRxSetZTFunctionsAck(bool ack)
|
|
{
|
|
mProgramHandle->SetZTFunctionsSatusDone(ack);
|
|
}
|
|
|
|
void CNetworkManager::UDPSocketDataReady()
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|