#include "NetworkManager.h"
#include <QByteArray>
#include <QDebug>
#include <QJsonDocument>
#include <QJsonObject>
#include "ConfigManager.h"
NetworkManager::NetworkManager(QObject *parent)
: QObject(parent), socket(nullptr), server(nullptr), m_connected(false), currentRole(Role::Client) {}
NetworkManager::~NetworkManager() {
disconnectFromPeer();
}
void NetworkManager::startConnection(Route route, Role role) {
if (socket) {
socket->disconnect(this);
socket->abort();
socket->deleteLater();
socket = nullptr;
}
currentRole = role;
if (currentRole == Role::Client) {
if (route == Route::USB) { runAdbForward(); }
setupClient(route);
} else {
setupServer();
}
}
void NetworkManager::runAdbForward() {
emit statusChanged("ADB Tunnel", false);
QString portStr = QString("tcp:%1").arg(PORT);
QProcess::execute("adb", QStringList() << "forward" << portStr << portStr);
}
void NetworkManager::setupClient(Route route) {
socket = new QTcpSocket(this);
connect(socket, &QTcpSocket::connected, this, &NetworkManager::handleConnected);
connect(socket, &QTcpSocket::disconnected, this, &NetworkManager::handleDisconnected);
connect(socket, &QTcpSocket::readyRead, this, &NetworkManager::handleReadyRead);
connect(socket, &QTcpSocket::errorOccurred,
this, &NetworkManager::handleSocketError);
emit statusChanged("Connecting", false);
QString targetHost = (route == Route::USB) ? "127.0.0.1" : ConfigManager::loadNote().ipAddress;
socket->connectToHost(targetHost, PORT);
}
void NetworkManager::setupServer() {
server = new QTcpServer(this);
connect(server, &QTcpServer::newConnection, this, &NetworkManager::handleNewConnection);
if (!server->listen(QHostAddress::Any, PORT)) {
emit statusChanged("Failed", false);
} else {
emit statusChanged("Listening", false);
}
}
void NetworkManager::handleNewConnection() {
if (!server) return;
socket = server->nextPendingConnection();
server->close();
connect(socket, &QTcpSocket::disconnected, this, &NetworkManager::handleDisconnected);
connect(socket, &QTcpSocket::readyRead, this, &NetworkManager::handleReadyRead);
handleConnected();
}
void NetworkManager::handleConnected() {
m_connected = true;
emit statusChanged("Connected", true);
}
void NetworkManager::handleDisconnected() {
m_connected = false;
emit statusChanged("Disconnected", false);
if (socket) {
socket->disconnect();
socket->deleteLater();
socket = nullptr;
}
if (server) {
server->close();
server->deleteLater();
server = nullptr;
}
}
void NetworkManager::handleSocketError(QAbstractSocket::SocketError) {
if (socket) {
emit statusChanged(socket->errorString(), false);
handleDisconnected();
}
}
void NetworkManager::handleReadyRead() {
if (!socket) return;
while (socket->canReadLine()) {
QByteArray line = socket->readLine().trimmed();
if (!line.isEmpty()) {
QByteArray decodedBytes = QByteArray::fromBase64(line);
QJsonDocument doc = QJsonDocument::fromJson(decodedBytes);
if (doc.isObject()) {
QJsonObject json = doc.object();
QString receivedKey = json["key"].toString();
QString cleanMessage = json["data"].toString();
QString localKey = ConfigManager::loadNote().passKey;
if (receivedKey != localKey) {
qDebug() << "Key Fail";
emit statusChanged("Pass Key Incorrect", false);
return;
}
emit contentReceived(cleanMessage);
emit statusChanged("Received", true);
}
}
}
}
void NetworkManager::sendNoteContent(const QString &content, const QString &passKey, qint64 lastModified) {
if (!m_connected || !socket) return;
QJsonObject json;
json["key"] = passKey;
json["date"] = lastModified;
json["data"] = content;
QByteArray encodedPayload = QJsonDocument(json).toJson(QJsonDocument::Compact).toBase64();
encodedPayload.append('\n');
if (socket->write(encodedPayload) != -1) {
socket->flush();
emit statusChanged("Sent", true);
}
}
bool NetworkManager::isConnected() const {
return m_connected;
}
void NetworkManager::disconnectFromPeer() {
if (currentRole == Role::Client) {
QProcess::execute("adb", QStringList() << "forward" << "--remove-all");
QProcess::execute("adb", QStringList() << "kill-server");
}
if (socket && socket->state() != QAbstractSocket::UnconnectedState) {
socket->abort();
} else {
handleDisconnected();
}
}