jce-manager/src/jceConnection/jcesslclient.cpp

337 lines
11 KiB
C++

#include "jcesslclient.h"
/**
* @brief jceSSLClient::jceSSLClient Constructer, setting the signals
*/
jceSSLClient::jceSSLClient() : flag(false), packet(""), networkConf()
{
//setting signals
connect(this,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(checkErrors(QAbstractSocket::SocketError)));
connect(this,SIGNAL(connected()),this,SLOT(setConnected()));
connect(this,SIGNAL(encrypted()),this,SLOT(setEncrypted()));
connect(this,SIGNAL(disconnected()),this,SLOT(setDisconnected()));
connect(&networkConf,SIGNAL(onlineStateChanged(bool)),this,SLOT(setOnlineState(bool)));
//loop event will connect the server, and when it is connected, it will quit - but connection will be open
connect(this, SIGNAL(encrypted()), &loop, SLOT(quit()));
connect(this,SIGNAL(error(QAbstractSocket::SocketError)),&loop,SLOT(quit()));
}
/**
* @brief jceSSLClient::makeConnect connecting to server with given port. using eventloop to assure it wont stuck the application.
* @param server - server to connect to
* @param port - the using port
* @return - true if connected, false otherwise
*/
bool jceSSLClient::makeConnect(QString server, int port)
{
qDebug() << "jceSSLClient::makeConnect; Making connection";
if (isConnected())
{
qWarning() << "jceSSLClient::makeConnect; Was already connected. Aborting.";
makeDiconnect();
}
if (isOpen())
{
qWarning() << "jceSSLClient::makeConnect; IsO pen. Aborting.";
makeDiconnect();
}
qDebug() << "jceSSLClient::makeConnect; Connection to: " << server << "On Port: " << port;
connectToHostEncrypted(server.toStdString().c_str(), port);
loop.exec(); //starting connection, waiting to encryption and then it ends
qDebug() << "jceSSLClient::makeConnect; returning the connection status: " << isConnected();
return isConnected();
}
/**
* @brief jceSSLClient::makeDiconnect from current server
* @return the flag of connection status
*/
bool jceSSLClient::makeDiconnect()
{
if (loop.isRunning())
{
qWarning() << Q_FUNC_INFO << "Killing connection thread";
loop.exit();
}
qDebug() << Q_FUNC_INFO << "emitting disconnected()";
emit disconnected();
return isConnected();
}
/**
* @brief jceSSLClient::isConnected connection checking
* @return regardless to state, it checks if there's a connection
*/
bool jceSSLClient::isConnected()
{
//checking state before returning flag!
if (state() == QAbstractSocket::SocketState::UnconnectedState)
{
flag = false;
}
else if (state() == QAbstractSocket::SocketState::ClosingState)
{
flag = false;
}
else if (state() == QAbstractSocket::SocketState::ConnectedState)
{
if (this->networkConf.isOnline())
flag = true;
else
{
this->setSocketState(QAbstractSocket::SocketState::UnconnectedState);
flag = false;
}
}
if (!this->networkConf.isOnline()) //no link, ethernet\wifi
flag = false;
return flag;
}
/**
* @brief jceSSLClient::sendData - given string, send it to server
* @param str - string to send
* @return true if succeed and byte were written
*/
bool jceSSLClient::sendData(QString str)
{
bool sendDataFlag = false;
if (isConnected()) //if connected
{
write(str.toStdString().c_str(),str.length());
if (waitForBytesWritten())
sendDataFlag = true;
}
qDebug() << "jceSSLClient::sendData; Sending Data status is: " << sendDataFlag;
return sendDataFlag;
}
/**
* @brief jceSSLClient::recieveData
* @param str this variable will store the recieved data
* @param fast true for LOGIN ONLY, false to retrieve all data
* @return true if recieved data bigger than zero
*/
bool jceSSLClient::recieveData(QString &str, bool fast)
{
qDebug() << "jceSSLClient::recieveData Data receiving!";
packet = "";
bool sflag = false;
if (fast) //fast mode connection, good only for login step!!!!
{
qDebug() << "jceSSLClient::recieveData login step receiving";
QEventLoop loop;
connect(this, SIGNAL(readyRead()), &loop, SLOT(quit()));
connect(this, SIGNAL(readyRead()), this, SLOT(readIt()));
loop.exec();
disconnect(this, SIGNAL(readyRead()), &loop, SLOT(quit()));
disconnect(this, SIGNAL(readyRead()), this, SLOT(readIt()));
}
else
{
qDebug() << "jceSSLClient::recieveData normal receiving";
QString p;
while (waitForReadyRead(milisTimeOut))
{
do
{
p = readAll();
packet.append(p);
}while (p.size() > 0);
}
}
str = packet;
qDebug() << "jceSSLClient::recieveData received bytes: " << str.length() ;
if (str.length() > 0)
sflag = true;
qDebug() << "jceSSLClient::recieveData return with flag: " << sflag;
return sflag;
}
/**
* @brief jceSSLClient::readIt function to read for fast mode in recieved data
*/
void jceSSLClient::readIt()
{
QString p;
do
{
p = readAll();
packet.append(p);
}while (p.size() > 0);
}
void jceSSLClient::setOnlineState(bool isOnline)
{
qWarning() << Q_FUNC_INFO << "isOnline status change: " << isOnline;
if (isOnline)
{
this->makeConnect();
}
else
{
this->makeDiconnect();
}
}
/**
* @brief jceSSLClient::setConnected called when signaled with connected, calling the encryption function
*/
void jceSSLClient::setConnected()
{
waitForEncrypted();
}
/**
* @brief jceSSLClient::setDisconnected closing socket, updating state and setting flag to false
*/
void jceSSLClient::setDisconnected()
{
qDebug() << Q_FUNC_INFO << "DISCONNECTED";
this->setSocketState(QAbstractSocket::SocketState::UnconnectedState);
abort();
flag = false;
}
/**
* @brief jceSSLClient::setEncrypted called when signaled with encrypted. setting the buffer size and keeping alive.
*/
void jceSSLClient::setEncrypted()
{
setReadBufferSize(10000);
setSocketOption(QAbstractSocket::KeepAliveOption,1);
if (isConnected());
else
{
qWarning() << "jceSSLClient::setEncrypted(); Connection status didnt change!";
flag = false;
}
}
/**
* @brief jceSSLClient::showIfErrorMsg message box to show the error occured according to socket
* if relevant, we will prompt a message box to informate the user
* otherwise, we will handle the error or ignore it.
*/
void jceSSLClient::showIfErrorMsg()
{
QMessageBox msgBox;
SocketError enumError = error();
QString errorString;
bool relevantError = false;
switch (enumError)
{
case QAbstractSocket::SocketError::ConnectionRefusedError:
errorString = QObject::tr("ConnectionRefusedError");
relevantError = true;
break;
case QAbstractSocket::SocketError::RemoteHostClosedError:
errorString = QObject::tr("RemoteHostClosedError");
relevantError = true;
break;
case QAbstractSocket::SocketError::HostNotFoundError:
errorString = QObject::tr("HostNotFoundError");
relevantError = true;
break;
case QAbstractSocket::SocketError::SocketAccessError:
errorString = QObject::tr("SocketAccessError");
break;
case QAbstractSocket::SocketError::SocketResourceError:
errorString = QObject::tr("SocketResourceError");
break;
case QAbstractSocket::SocketError::SocketTimeoutError:
errorString = QObject::tr("SocketTimeoutError");
if (state() == QAbstractSocket::SocketState::UnconnectedState)
{
relevantError = true;
}
break;
case QAbstractSocket::SocketError::DatagramTooLargeError:
errorString = QObject::tr("DatagramTooLargeError");
break;
case QAbstractSocket::SocketError::NetworkError:
errorString = QObject::tr("NetworkError");
relevantError = true;
break;
case QAbstractSocket::SocketError::AddressInUseError:
errorString = QObject::tr("AddressInUseError");
break;
case QAbstractSocket::SocketError::SocketAddressNotAvailableError:
errorString = QObject::tr("SocketAddressNotAvailableError");
break;
case QAbstractSocket::SocketError::UnsupportedSocketOperationError:
errorString = QObject::tr("UnsupportedSocketOperationError");
break;
case QAbstractSocket::SocketError::ProxyAuthenticationRequiredError:
errorString = QObject::tr("ProxyAuthenticationRequiredError");
break;
case QAbstractSocket::SocketError::SslHandshakeFailedError:
errorString = QObject::tr("SslHandshakeFailedError");
break;
case QAbstractSocket::SocketError::ProxyConnectionRefusedError:
errorString = QObject::tr("ProxyConnectionRefusedError");
break;
case QAbstractSocket::SocketError::UnfinishedSocketOperationError:
errorString = QObject::tr("UnfinishedSocketOperationError");
break;
case QAbstractSocket::SocketError::ProxyConnectionClosedError:
errorString = QObject::tr("ProxyConnectionClosedError");
break;
case QAbstractSocket::SocketError::ProxyConnectionTimeoutError:
errorString = QObject::tr("ProxyConnectionTimeoutError");
break;
case QAbstractSocket::SocketError::ProxyNotFoundError:
errorString = QObject::tr("ProxyNotFoundError");
break;
case QAbstractSocket::SocketError::ProxyProtocolError:
errorString = QObject::tr("ProxyProtocolError");
break;
case QAbstractSocket::SocketError::OperationError:
errorString = QObject::tr("OperationError");
break;
case QAbstractSocket::SocketError::SslInternalError:
errorString = QObject::tr("SslInternalError");
break;
case QAbstractSocket::SocketError::SslInvalidUserDataError:
errorString = QObject::tr("SslInvalidUserDataError");
break;
case QAbstractSocket::SocketError::TemporaryError:
errorString = QObject::tr("TemporaryError");
break;
case QAbstractSocket::SocketError::UnknownSocketError:
errorString = QObject::tr("UnknownSocketError");
relevantError = true;
break;
}
if (relevantError) //informative string to be shown
{
qDebug() << "jceSSLClient::showIfErrorMsg(); relevant error. msgbox popped";
msgBox.setIcon(QMessageBox::Warning);
msgBox.setText(errorString);
msgBox.exec();
}
}
/**
* @brief jceSSLClient::checkErrors this function exctuing when socket error has occured
* @param a includes the error enum from QAbstractSocket::SocketError enum list
*/
void jceSSLClient::checkErrors(QAbstractSocket::SocketError a)
{
qWarning() << Q_FUNC_INFO << "isOnline?: " << this->networkConf.isOnline();
qWarning() << Q_FUNC_INFO << "state is: " << state();
qWarning() << Q_FUNC_INFO << "Var Error: " << a;
qWarning() << Q_FUNC_INFO << "Error: " << errorString();
showIfErrorMsg();
}