2024-09-22 05:44:30 -04:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Copyright (C) 2024 Jon Beniston, M7RCE <jon@beniston.com> //
|
|
|
|
// //
|
|
|
|
// This program is free software; you can redistribute it and/or modify //
|
|
|
|
// it under the terms of the GNU General Public License as published by //
|
|
|
|
// the Free Software Foundation as version 3 of the License, or //
|
|
|
|
// (at your option) any later version. //
|
|
|
|
// //
|
|
|
|
// This program is distributed in the hope that it will be useful, //
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
|
|
|
// GNU General Public License V3 for more details. //
|
|
|
|
// //
|
|
|
|
// You should have received a copy of the GNU General Public License //
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
#include "socket.h"
|
|
|
|
|
|
|
|
Socket::Socket(QObject *socket, QObject *parent) :
|
|
|
|
QObject(parent),
|
|
|
|
m_socket(socket)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Socket::~Socket()
|
|
|
|
{
|
|
|
|
delete m_socket;
|
|
|
|
}
|
|
|
|
|
|
|
|
TCPSocket::TCPSocket(QTcpSocket *socket) :
|
|
|
|
Socket(socket)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
qint64 TCPSocket::write(const char *data, qint64 length)
|
|
|
|
{
|
|
|
|
QTcpSocket *socket = qobject_cast<QTcpSocket *>(m_socket);
|
|
|
|
|
|
|
|
return socket->write(data, length);
|
|
|
|
}
|
|
|
|
|
|
|
|
qint64 TCPSocket::read(char *data, qint64 length)
|
|
|
|
{
|
|
|
|
QTcpSocket *socket = qobject_cast<QTcpSocket *>(m_socket);
|
|
|
|
|
|
|
|
return socket->read(data, length);
|
|
|
|
}
|
|
|
|
|
2024-10-08 12:20:18 -04:00
|
|
|
QByteArray TCPSocket::readAll()
|
|
|
|
{
|
|
|
|
QTcpSocket *socket = qobject_cast<QTcpSocket *>(m_socket);
|
|
|
|
|
|
|
|
return socket->readAll();
|
|
|
|
}
|
|
|
|
|
2024-09-22 05:44:30 -04:00
|
|
|
void TCPSocket::close()
|
|
|
|
{
|
|
|
|
QTcpSocket *socket = qobject_cast<QTcpSocket *>(m_socket);
|
|
|
|
|
|
|
|
socket->close();
|
|
|
|
}
|
|
|
|
|
|
|
|
qint64 TCPSocket::bytesAvailable()
|
|
|
|
{
|
|
|
|
QTcpSocket *socket = qobject_cast<QTcpSocket *>(m_socket);
|
|
|
|
|
|
|
|
return socket->bytesAvailable();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TCPSocket::flush()
|
|
|
|
{
|
|
|
|
QTcpSocket *socket = qobject_cast<QTcpSocket *>(m_socket);
|
|
|
|
|
|
|
|
socket->flush();
|
|
|
|
}
|
|
|
|
|
|
|
|
QHostAddress TCPSocket::peerAddress()
|
|
|
|
{
|
|
|
|
QTcpSocket *socket = qobject_cast<QTcpSocket *>(m_socket);
|
|
|
|
|
|
|
|
return socket->peerAddress();
|
|
|
|
}
|
|
|
|
|
|
|
|
quint16 TCPSocket::peerPort()
|
|
|
|
{
|
|
|
|
QTcpSocket *socket = qobject_cast<QTcpSocket *>(m_socket);
|
|
|
|
|
|
|
|
return socket->peerPort();
|
|
|
|
}
|
|
|
|
|
2024-10-08 12:20:18 -04:00
|
|
|
bool TCPSocket::isConnected()
|
|
|
|
{
|
|
|
|
QTcpSocket *socket = qobject_cast<QTcpSocket *>(m_socket);
|
|
|
|
|
|
|
|
return socket->state() == QAbstractSocket::ConnectedState;
|
|
|
|
}
|
|
|
|
|
2024-09-22 05:44:30 -04:00
|
|
|
WebSocket::WebSocket(QWebSocket *socket) :
|
|
|
|
Socket(socket)
|
|
|
|
{
|
|
|
|
m_rxBuffer.reserve(64000);
|
|
|
|
m_txBuffer.reserve(64000);
|
|
|
|
connect(socket, &QWebSocket::binaryFrameReceived, this, &WebSocket::binaryFrameReceived);
|
|
|
|
}
|
|
|
|
|
|
|
|
qint64 WebSocket::write(const char *data, qint64 length)
|
|
|
|
{
|
|
|
|
//QWebSocket *socket = qobject_cast<QWebSocket *>(m_socket);
|
|
|
|
//return socket->sendBinaryMessage(QByteArray(data, length));
|
|
|
|
|
|
|
|
m_txBuffer.append(data, length);
|
|
|
|
return length;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebSocket::flush()
|
|
|
|
{
|
|
|
|
QWebSocket *socket = qobject_cast<QWebSocket *>(m_socket);
|
|
|
|
if (m_txBuffer.size() > 0)
|
|
|
|
{
|
|
|
|
qint64 len = socket->sendBinaryMessage(m_txBuffer);
|
|
|
|
if (len != m_txBuffer.size()) {
|
|
|
|
qDebug() << "WebSocket::flush: Failed to send all of message" << len << "/" << m_txBuffer.size();
|
|
|
|
}
|
|
|
|
m_txBuffer.clear();
|
|
|
|
}
|
|
|
|
socket->flush();
|
|
|
|
}
|
|
|
|
|
|
|
|
qint64 WebSocket::read(char *data, qint64 length)
|
|
|
|
{
|
|
|
|
length = std::min(length, (qint64)m_rxBuffer.size());
|
|
|
|
|
|
|
|
memcpy(data, m_rxBuffer.constData(), length);
|
|
|
|
|
|
|
|
m_rxBuffer = m_rxBuffer.mid(length); // Yep, not very efficient
|
|
|
|
|
|
|
|
return length;
|
|
|
|
}
|
|
|
|
|
2024-10-08 12:20:18 -04:00
|
|
|
QByteArray WebSocket::readAll()
|
|
|
|
{
|
|
|
|
QByteArray b = m_rxBuffer;
|
|
|
|
|
|
|
|
m_rxBuffer.clear();
|
|
|
|
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
2024-09-22 05:44:30 -04:00
|
|
|
void WebSocket::close()
|
|
|
|
{
|
|
|
|
QWebSocket *socket = qobject_cast<QWebSocket *>(m_socket);
|
|
|
|
|
2024-10-08 12:20:18 -04:00
|
|
|
// Will crash if we call close on unopened socket
|
|
|
|
if (socket->state() != QAbstractSocket::UnconnectedState) {
|
|
|
|
socket->close();
|
|
|
|
}
|
2024-09-22 05:44:30 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
qint64 WebSocket::bytesAvailable()
|
|
|
|
{
|
|
|
|
return m_rxBuffer.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebSocket::binaryFrameReceived(const QByteArray &frame, bool isLastFrame)
|
|
|
|
{
|
|
|
|
(void) isLastFrame;
|
|
|
|
|
|
|
|
m_rxBuffer.append(frame);
|
|
|
|
}
|
|
|
|
|
|
|
|
QHostAddress WebSocket::peerAddress()
|
|
|
|
{
|
|
|
|
QWebSocket *socket = qobject_cast<QWebSocket *>(m_socket);
|
|
|
|
|
|
|
|
return socket->peerAddress();
|
|
|
|
}
|
|
|
|
|
|
|
|
quint16 WebSocket::peerPort()
|
|
|
|
{
|
|
|
|
QWebSocket *socket = qobject_cast<QWebSocket *>(m_socket);
|
|
|
|
|
|
|
|
return socket->peerPort();
|
|
|
|
}
|
2024-10-08 12:20:18 -04:00
|
|
|
|
|
|
|
bool WebSocket::isConnected()
|
|
|
|
{
|
|
|
|
QWebSocket *socket = qobject_cast<QWebSocket *>(m_socket);
|
|
|
|
|
|
|
|
return socket->state() == QAbstractSocket::ConnectedState;
|
|
|
|
}
|