2024-05-15 15:44:45 -04:00
|
|
|
#include "backend.h"
|
|
|
|
|
2024-05-24 03:08:17 -04:00
|
|
|
#include <QCoreApplication>
|
|
|
|
#include <QDir>
|
2024-05-24 11:37:54 -04:00
|
|
|
#include <QMessageBox>
|
2024-08-02 13:46:16 -04:00
|
|
|
#include <QNetworkDatagram>
|
2024-08-04 13:53:00 -04:00
|
|
|
#include <QtConcurrent/QtConcurrent>
|
2024-05-24 03:08:17 -04:00
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
#include <arpa/inet.h>
|
2024-05-23 22:47:32 -04:00
|
|
|
#include <fcntl.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <unistd.h>
|
2024-05-15 15:44:45 -04:00
|
|
|
#include <vanilla.h>
|
|
|
|
|
2024-05-23 22:47:32 -04:00
|
|
|
#include "../pipe/pipe.h"
|
|
|
|
|
2024-05-15 15:44:45 -04:00
|
|
|
void vanillaEventHandler(void *context, int type, const char *data, size_t dataLength)
|
|
|
|
{
|
|
|
|
Backend *backend = static_cast<Backend*>(context);
|
|
|
|
|
2024-05-18 15:55:00 -04:00
|
|
|
switch (type) {
|
|
|
|
case VANILLA_EVENT_VIDEO:
|
|
|
|
emit backend->videoAvailable(QByteArray(data, dataLength));
|
|
|
|
break;
|
|
|
|
case VANILLA_EVENT_AUDIO:
|
|
|
|
emit backend->audioAvailable(QByteArray(data, dataLength));
|
|
|
|
break;
|
|
|
|
case VANILLA_EVENT_VIBRATE:
|
2024-05-29 03:09:17 -04:00
|
|
|
emit backend->vibrate(*data);
|
2024-05-18 15:55:00 -04:00
|
|
|
break;
|
|
|
|
}
|
2024-05-15 15:44:45 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
Backend::Backend(QObject *parent) : QObject(parent)
|
|
|
|
{
|
2024-08-02 13:46:16 -04:00
|
|
|
}
|
2024-05-24 03:08:17 -04:00
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
void Backend::init()
|
|
|
|
{
|
|
|
|
emit ready();
|
|
|
|
}
|
2024-05-24 11:37:54 -04:00
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
BackendViaLocalRoot::BackendViaLocalRoot(const QString &wirelessInterface, QObject *parent) : Backend(parent)
|
|
|
|
{
|
|
|
|
m_wirelessInterface = wirelessInterface;
|
|
|
|
}
|
2024-05-24 11:37:54 -04:00
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
BackendViaPipe::BackendViaPipe(QObject *parent) : Backend(parent)
|
|
|
|
{
|
|
|
|
}
|
2024-05-24 11:37:54 -04:00
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
BackendViaNamedPipe::BackendViaNamedPipe(const QString &wirelessInterface, QObject *parent) : BackendViaPipe(parent)
|
|
|
|
{
|
|
|
|
m_pipeIn = -1;
|
|
|
|
m_pipeOut = -1;
|
|
|
|
m_pipeThread = new QThread(this);
|
|
|
|
m_pipe = new BackendPipe(wirelessInterface, this);
|
|
|
|
connect(m_pipe, &BackendPipe::pipesAvailable, this, &BackendViaNamedPipe::setUpPipes);
|
|
|
|
connect(m_pipe, &BackendPipe::closed, this, &BackendViaNamedPipe::closed);
|
2024-05-24 03:08:17 -04:00
|
|
|
}
|
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
void BackendViaNamedPipe::init()
|
2024-05-24 03:08:17 -04:00
|
|
|
{
|
2024-08-02 13:46:16 -04:00
|
|
|
m_pipe->setParent(nullptr);
|
|
|
|
m_pipeThread->start();
|
|
|
|
m_pipe->moveToThread(m_pipeThread);
|
|
|
|
QMetaObject::invokeMethod(m_pipe, &BackendPipe::start, Qt::QueuedConnection);
|
|
|
|
}
|
2024-05-24 11:37:54 -04:00
|
|
|
|
2024-08-04 13:53:00 -04:00
|
|
|
BackendViaSocket::BackendViaSocket(const QHostAddress &backendAddr, quint16 backendPort, QObject *parent) : BackendViaPipe(parent)
|
2024-08-02 13:46:16 -04:00
|
|
|
{
|
|
|
|
m_socket = new BackendUdpWrapper(backendAddr, backendPort, this);
|
2024-08-04 13:53:00 -04:00
|
|
|
connect(m_socket, &BackendUdpWrapper::socketReady, this, &BackendViaSocket::socketReady);
|
|
|
|
connect(m_socket, &BackendUdpWrapper::receivedData, this, &BackendViaSocket::receivedData, Qt::DirectConnection);
|
|
|
|
connect(m_socket, &BackendUdpWrapper::closed, this, &BackendViaSocket::closed);
|
|
|
|
connect(m_socket, &BackendUdpWrapper::error, this, &BackendViaSocket::error);
|
2024-08-02 13:46:16 -04:00
|
|
|
|
|
|
|
m_socketThread = new QThread(this);
|
2024-05-24 03:08:17 -04:00
|
|
|
}
|
|
|
|
|
2024-08-04 13:53:00 -04:00
|
|
|
BackendViaSocket::~BackendViaSocket()
|
2024-05-24 03:08:17 -04:00
|
|
|
{
|
2024-08-02 13:46:16 -04:00
|
|
|
m_socket->deleteLater();
|
|
|
|
m_socketThread->quit();
|
|
|
|
m_socketThread->wait();
|
2024-05-24 03:08:17 -04:00
|
|
|
}
|
|
|
|
|
2024-08-04 13:53:00 -04:00
|
|
|
void BackendViaSocket::init()
|
2024-05-24 03:08:17 -04:00
|
|
|
{
|
2024-08-02 13:46:16 -04:00
|
|
|
m_socketThread->start();
|
|
|
|
m_socket->setParent(nullptr);
|
|
|
|
m_socket->moveToThread(m_socketThread);
|
|
|
|
QMetaObject::invokeMethod(m_socket, &BackendUdpWrapper::start, Qt::QueuedConnection);
|
2024-05-15 15:44:45 -04:00
|
|
|
}
|
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
void BackendViaPipe::quitPipe()
|
2024-05-15 15:44:45 -04:00
|
|
|
{
|
2024-08-02 13:46:16 -04:00
|
|
|
pipe_control_code cmd;
|
|
|
|
cmd.code = VANILLA_PIPE_IN_QUIT;
|
|
|
|
writeToPipe(&cmd, sizeof(cmd));
|
2024-05-24 03:08:17 -04:00
|
|
|
}
|
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
BackendViaNamedPipe::~BackendViaNamedPipe()
|
2024-05-24 03:08:17 -04:00
|
|
|
{
|
2024-08-02 13:46:16 -04:00
|
|
|
quitPipe();
|
|
|
|
|
|
|
|
m_pipe->deleteLater();
|
|
|
|
m_pipeThread->quit();
|
|
|
|
m_pipeThread->wait();
|
2024-05-15 15:44:45 -04:00
|
|
|
}
|
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
void BackendViaLocalRoot::interrupt()
|
2024-06-13 21:43:58 -04:00
|
|
|
{
|
2024-08-02 13:46:16 -04:00
|
|
|
vanilla_stop();
|
2024-06-13 21:43:58 -04:00
|
|
|
}
|
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
void BackendViaPipe::interrupt()
|
2024-05-15 15:44:45 -04:00
|
|
|
{
|
2024-08-02 13:46:16 -04:00
|
|
|
pipe_control_code cmd;
|
|
|
|
cmd.code = VANILLA_PIPE_IN_INTERRUPT;
|
|
|
|
writeToPipe(&cmd, sizeof(cmd));
|
|
|
|
}
|
2024-05-24 03:08:17 -04:00
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
void BackendViaLocalRoot::requestIDR()
|
|
|
|
{
|
|
|
|
vanilla_request_idr();
|
|
|
|
}
|
2024-05-24 03:08:17 -04:00
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
void BackendViaPipe::requestIDR()
|
|
|
|
{
|
|
|
|
pipe_control_code cmd;
|
|
|
|
cmd.code = VANILLA_PIPE_IN_REQ_IDR;
|
|
|
|
writeToPipe(&cmd, sizeof(cmd));
|
|
|
|
}
|
2024-05-24 03:08:17 -04:00
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
void BackendViaLocalRoot::connectToConsole()
|
|
|
|
{
|
2024-08-04 13:53:00 -04:00
|
|
|
QtConcurrent::run(connectInternal, this, m_wirelessInterface);
|
|
|
|
}
|
|
|
|
|
|
|
|
int BackendViaLocalRoot::connectInternal(BackendViaLocalRoot *instance, const QString &intf)
|
|
|
|
{
|
|
|
|
QByteArray wirelessInterfaceC = intf.toUtf8();
|
|
|
|
return vanilla_connect_to_console(wirelessInterfaceC.constData(), vanillaEventHandler, instance);
|
2024-08-02 13:46:16 -04:00
|
|
|
}
|
2024-05-24 03:08:17 -04:00
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
void BackendViaPipe::connectToConsole()
|
|
|
|
{
|
|
|
|
// Request pipe to connect
|
|
|
|
pipe_control_code conn_cmd;
|
|
|
|
conn_cmd.code = VANILLA_PIPE_IN_CONNECT;
|
|
|
|
writeToPipe(&conn_cmd, sizeof(conn_cmd));
|
|
|
|
|
|
|
|
uint8_t cmd[UINT16_MAX];
|
|
|
|
while (true) {
|
|
|
|
ssize_t read_size = readFromPipe(cmd, sizeof(cmd));
|
|
|
|
if (read_size == 0) {
|
|
|
|
continue;
|
|
|
|
}
|
2024-05-24 03:08:17 -04:00
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
pipe_control_code *cc = (pipe_control_code *) cmd;
|
2024-05-24 03:08:17 -04:00
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
if (cc->code == VANILLA_PIPE_OUT_EOF) {
|
|
|
|
break;
|
|
|
|
} else if (cc->code == VANILLA_PIPE_OUT_DATA) {
|
|
|
|
pipe_data_command *event = (pipe_data_command *) cmd;
|
|
|
|
event->data_size = ntohs(event->data_size);
|
|
|
|
vanillaEventHandler(this, event->event_type, (const char *) event->data, event->data_size);
|
2024-05-24 03:08:17 -04:00
|
|
|
}
|
|
|
|
}
|
2024-05-15 15:44:45 -04:00
|
|
|
}
|
2024-05-20 19:16:40 -04:00
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
void BackendViaLocalRoot::updateTouch(int x, int y)
|
2024-05-20 19:16:40 -04:00
|
|
|
{
|
2024-08-02 13:46:16 -04:00
|
|
|
vanilla_set_touch(x, y);
|
2024-05-23 21:47:04 -04:00
|
|
|
}
|
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
void BackendViaPipe::updateTouch(int x, int y)
|
2024-05-23 21:47:04 -04:00
|
|
|
{
|
2024-08-02 13:46:16 -04:00
|
|
|
pipe_touch_command cmd;
|
|
|
|
cmd.base.code = VANILLA_PIPE_IN_TOUCH;
|
|
|
|
cmd.x = htonl(x);
|
|
|
|
cmd.y = htonl(y);
|
|
|
|
writeToPipe(&cmd, sizeof(cmd));
|
2024-05-23 21:47:04 -04:00
|
|
|
}
|
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
void BackendViaLocalRoot::setButton(int button, int32_t value)
|
2024-06-19 14:58:02 -04:00
|
|
|
{
|
2024-08-02 13:46:16 -04:00
|
|
|
vanilla_set_button(button, value);
|
2024-06-19 14:58:02 -04:00
|
|
|
}
|
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
void BackendViaPipe::setButton(int button, int32_t value)
|
2024-06-19 16:11:32 -04:00
|
|
|
{
|
2024-08-02 13:46:16 -04:00
|
|
|
pipe_button_command cmd;
|
|
|
|
cmd.base.code = VANILLA_PIPE_IN_BUTTON;
|
|
|
|
cmd.id = htonl(button);
|
|
|
|
cmd.value = htonl(value);
|
|
|
|
writeToPipe(&cmd, sizeof(cmd));
|
2024-06-19 16:11:32 -04:00
|
|
|
}
|
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
void BackendViaLocalRoot::setRegion(int region)
|
2024-05-23 21:47:04 -04:00
|
|
|
{
|
2024-08-02 13:46:16 -04:00
|
|
|
vanilla_set_region(region);
|
|
|
|
}
|
2024-05-24 03:08:17 -04:00
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
void BackendViaPipe::setRegion(int region)
|
|
|
|
{
|
|
|
|
pipe_region_command cmd;
|
|
|
|
cmd.base.code = VANILLA_PIPE_IN_REGION;
|
|
|
|
cmd.region = region;
|
|
|
|
writeToPipe(&cmd, sizeof(cmd));
|
|
|
|
}
|
2024-05-24 03:08:17 -04:00
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
void BackendViaLocalRoot::setBatteryStatus(int status)
|
|
|
|
{
|
|
|
|
vanilla_set_battery_status(status);
|
|
|
|
}
|
|
|
|
|
|
|
|
void BackendViaPipe::setBatteryStatus(int status)
|
|
|
|
{
|
|
|
|
pipe_battery_command cmd;
|
|
|
|
cmd.base.code = VANILLA_PIPE_IN_BATTERY;
|
|
|
|
cmd.battery = status;
|
|
|
|
writeToPipe(&cmd, sizeof(cmd));
|
|
|
|
}
|
2024-05-24 03:08:17 -04:00
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
void BackendViaLocalRoot::sync(uint16_t code)
|
|
|
|
{
|
2024-08-04 13:53:00 -04:00
|
|
|
QFutureWatcher<int> *watcher = new QFutureWatcher<int>(this);
|
2024-08-04 14:28:08 -04:00
|
|
|
connect(watcher, &QFutureWatcher<int>::finished, this, &BackendViaLocalRoot::syncFutureCompleted);
|
2024-08-04 13:53:00 -04:00
|
|
|
watcher->setFuture(QtConcurrent::run(syncInternal, m_wirelessInterface, code));
|
|
|
|
}
|
|
|
|
|
|
|
|
int BackendViaLocalRoot::syncInternal(const QString &intf, uint16_t code)
|
|
|
|
{
|
|
|
|
QByteArray wirelessInterfaceC = intf.toUtf8();
|
|
|
|
return vanilla_sync_with_console(wirelessInterfaceC.constData(), code);
|
|
|
|
}
|
|
|
|
|
|
|
|
void BackendViaLocalRoot::syncFutureCompleted()
|
|
|
|
{
|
|
|
|
QFutureWatcher<int> *watcher = static_cast<QFutureWatcher<int>*>(sender());
|
|
|
|
int r = watcher->result();
|
2024-08-02 13:46:16 -04:00
|
|
|
emit syncCompleted(r == VANILLA_SUCCESS);
|
2024-08-04 13:53:00 -04:00
|
|
|
watcher->deleteLater();
|
2024-08-02 13:46:16 -04:00
|
|
|
}
|
2024-05-23 22:47:32 -04:00
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
void BackendViaPipe::sync(uint16_t code)
|
|
|
|
{
|
|
|
|
// Request pipe to sync
|
|
|
|
pipe_sync_command cmd;
|
|
|
|
cmd.base.code = VANILLA_PIPE_IN_SYNC;
|
2024-08-04 12:53:51 -04:00
|
|
|
cmd.code = htons(code);
|
2024-08-02 13:46:16 -04:00
|
|
|
writeToPipe(&cmd, sizeof(cmd));
|
|
|
|
|
|
|
|
// See if pipe accepted our request to sync
|
|
|
|
uint8_t cc;
|
|
|
|
readFromPipe(&cc, sizeof(cc));
|
|
|
|
if (cc != VANILLA_PIPE_ERR_SUCCESS) {
|
|
|
|
emit syncCompleted(false);
|
|
|
|
return;
|
|
|
|
}
|
2024-05-23 22:47:32 -04:00
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
// Wait for sync status
|
|
|
|
readFromPipe(&cc, sizeof(cc));
|
|
|
|
if (cc == VANILLA_PIPE_OUT_SYNC_STATE) {
|
|
|
|
readFromPipe(&cc, sizeof(cc));
|
|
|
|
emit syncCompleted(cc == VANILLA_SUCCESS);
|
2024-05-23 22:47:32 -04:00
|
|
|
} else {
|
2024-08-02 13:46:16 -04:00
|
|
|
emit syncCompleted(false);
|
2024-05-23 22:47:32 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
void BackendViaNamedPipe::setUpPipes(const QString &in, const QString &out)
|
2024-05-23 22:47:32 -04:00
|
|
|
{
|
2024-06-19 21:20:55 -04:00
|
|
|
QByteArray inUtf8 = in.toUtf8();
|
|
|
|
QByteArray outUtf8 = out.toUtf8();
|
|
|
|
m_pipeIn = open(inUtf8.constData(), O_RDONLY);
|
2024-05-24 11:37:54 -04:00
|
|
|
if (m_pipeIn == -1) {
|
|
|
|
QMessageBox::critical(nullptr, tr("Pipe Error"), tr("Failed to create in pipe: %1").arg(strerror(errno)));
|
|
|
|
}
|
2024-06-19 21:20:55 -04:00
|
|
|
m_pipeOut = open(outUtf8.constData(), O_WRONLY);
|
2024-05-24 11:37:54 -04:00
|
|
|
if (m_pipeOut == -1) {
|
|
|
|
QMessageBox::critical(nullptr, tr("Pipe Error"), tr("Failed to create out pipe: %1").arg(strerror(errno)));
|
|
|
|
}
|
|
|
|
|
2024-05-30 15:58:58 -04:00
|
|
|
printf("Established connection with backend\n");
|
2024-08-02 13:46:16 -04:00
|
|
|
emit ready();
|
2024-05-24 11:37:54 -04:00
|
|
|
}
|
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
BackendPipe::BackendPipe(const QString &wirelessInterface, QObject *parent) : QObject(parent)
|
2024-05-24 11:37:54 -04:00
|
|
|
{
|
|
|
|
m_process = nullptr;
|
2024-08-02 13:46:16 -04:00
|
|
|
m_wirelessInterface = wirelessInterface;
|
2024-05-24 11:37:54 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
BackendPipe::~BackendPipe()
|
|
|
|
{
|
|
|
|
waitForFinished();
|
2024-06-19 21:20:55 -04:00
|
|
|
|
|
|
|
QFile::remove(m_pipeInFilename);
|
|
|
|
QFile::remove(m_pipeOutFilename);
|
2024-05-24 11:37:54 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void BackendPipe::waitForFinished()
|
|
|
|
{
|
|
|
|
if (m_process) {
|
|
|
|
m_process->waitForFinished();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void BackendPipe::start()
|
|
|
|
{
|
|
|
|
const QString pipe_bin = QDir(QCoreApplication::applicationDirPath()).filePath(QStringLiteral("vanilla-pipe"));
|
|
|
|
m_process = new QProcess(this);
|
|
|
|
m_process->setReadChannel(QProcess::StandardError);
|
|
|
|
connect(m_process, &QProcess::readyReadStandardError, this, &BackendPipe::receivedData);
|
2024-08-02 13:46:16 -04:00
|
|
|
connect(m_process, &QProcess::finished, this, &BackendPipe::closed);
|
2024-06-19 21:20:55 -04:00
|
|
|
|
|
|
|
m_pipeOutFilename = QStringLiteral("/tmp/vanilla-fifo-in-%0").arg(QString::number(QDateTime::currentMSecsSinceEpoch()));
|
|
|
|
m_pipeInFilename = QStringLiteral("/tmp/vanilla-fifo-out-%0").arg(QString::number(QDateTime::currentMSecsSinceEpoch()));
|
|
|
|
|
2024-08-02 13:46:16 -04:00
|
|
|
m_process->start(QStringLiteral("pkexec"), {pipe_bin, m_wirelessInterface, QStringLiteral("-pipe"), m_pipeOutFilename, m_pipeInFilename});
|
2024-05-24 11:37:54 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void BackendPipe::receivedData()
|
|
|
|
{
|
|
|
|
while (m_process->canReadLine()) {
|
|
|
|
QByteArray a = m_process->readLine().trimmed();
|
2024-06-19 21:20:55 -04:00
|
|
|
if (a == QByteArrayLiteral("READY")) {
|
|
|
|
emit pipesAvailable(m_pipeInFilename, m_pipeOutFilename);
|
2024-05-24 11:37:54 -04:00
|
|
|
} else {
|
|
|
|
printf("%s\n", a.constData());
|
2024-05-24 03:08:17 -04:00
|
|
|
}
|
2024-05-23 22:47:32 -04:00
|
|
|
}
|
2024-08-02 13:46:16 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
ssize_t BackendViaNamedPipe::readFromPipe(void *data, size_t length)
|
|
|
|
{
|
|
|
|
return read(m_pipeIn, data, length);
|
|
|
|
}
|
|
|
|
|
|
|
|
ssize_t BackendViaNamedPipe::writeToPipe(const void *data, size_t length)
|
|
|
|
{
|
|
|
|
return write(m_pipeOut, data, length);
|
|
|
|
}
|
|
|
|
|
|
|
|
BackendUdpWrapper::BackendUdpWrapper(const QHostAddress &backendAddr, quint16 backendPort, QObject *parent) : QObject(parent)
|
|
|
|
{
|
|
|
|
m_backendAddress = backendAddr;
|
|
|
|
m_backendPort = backendPort;
|
|
|
|
|
|
|
|
m_socket = new QUdpSocket(this);
|
|
|
|
connect(m_socket, &QUdpSocket::readyRead, this, &BackendUdpWrapper::readPendingDatagrams);
|
|
|
|
}
|
|
|
|
|
|
|
|
void BackendUdpWrapper::start()
|
|
|
|
{
|
|
|
|
bool connected = false;
|
|
|
|
|
|
|
|
for (m_frontendPort = 10100; m_frontendPort < 10200; m_frontendPort++) {
|
|
|
|
printf("Trying to bind to port %u\n", m_frontendPort);
|
|
|
|
if (m_socket->bind(QHostAddress::Any, m_frontendPort)) {
|
|
|
|
printf("Bound to port %u\n", m_frontendPort);
|
|
|
|
connected = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (connected) {
|
|
|
|
emit socketReady(m_frontendPort);
|
|
|
|
} else {
|
|
|
|
printf("Failed to bind to port\n");
|
|
|
|
emit error(tr("Failed to bind to UDP port"));
|
|
|
|
emit closed();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void BackendUdpWrapper::readPendingDatagrams()
|
|
|
|
{
|
|
|
|
while (m_socket->hasPendingDatagrams()) {
|
|
|
|
QNetworkDatagram datagram = m_socket->receiveDatagram();
|
|
|
|
emit receivedData(datagram.data());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void BackendUdpWrapper::write(const QByteArray &data)
|
|
|
|
{
|
|
|
|
m_socket->writeDatagram(data, m_backendAddress, m_backendPort);
|
|
|
|
}
|
|
|
|
|
2024-08-04 13:53:00 -04:00
|
|
|
ssize_t BackendViaSocket::readFromPipe(void *data, size_t length)
|
2024-08-02 13:46:16 -04:00
|
|
|
{
|
|
|
|
m_readMutex.lock();
|
2024-08-04 12:53:51 -04:00
|
|
|
if (m_buffer.isEmpty()) {
|
2024-08-02 13:46:16 -04:00
|
|
|
m_readWaitCond.wait(&m_readMutex);
|
|
|
|
}
|
2024-08-04 12:53:51 -04:00
|
|
|
if (m_buffer.size() < length) {
|
|
|
|
length = m_buffer.size();
|
|
|
|
}
|
2024-08-02 13:46:16 -04:00
|
|
|
memcpy(data, m_buffer.constData(), length);
|
|
|
|
m_buffer.remove(0, length);
|
|
|
|
m_readMutex.unlock();
|
|
|
|
return length;
|
|
|
|
}
|
|
|
|
|
2024-08-04 13:53:00 -04:00
|
|
|
ssize_t BackendViaSocket::writeToPipe(const void *data, size_t length)
|
2024-08-02 13:46:16 -04:00
|
|
|
{
|
|
|
|
QMetaObject::invokeMethod(m_socket, "write", Q_ARG(QByteArray, QByteArray((const char *) data, length)));
|
|
|
|
return length;
|
|
|
|
}
|
|
|
|
|
2024-08-04 13:53:00 -04:00
|
|
|
void BackendViaSocket::receivedData(const QByteArray &data)
|
2024-08-02 13:46:16 -04:00
|
|
|
{
|
|
|
|
m_readMutex.lock();
|
|
|
|
m_buffer.append(data);
|
|
|
|
m_readWaitCond.wakeAll();
|
|
|
|
m_readMutex.unlock();
|
|
|
|
}
|
|
|
|
|
2024-08-04 13:53:00 -04:00
|
|
|
void BackendViaSocket::socketReady(quint16 port)
|
2024-08-02 13:46:16 -04:00
|
|
|
{
|
|
|
|
pipe_control_code cmd;
|
|
|
|
cmd.code = VANILLA_PIPE_IN_BIND;
|
|
|
|
writeToPipe(&cmd, sizeof(cmd));
|
|
|
|
|
|
|
|
uint8_t cc;
|
|
|
|
readFromPipe(&cc, sizeof(cc));
|
|
|
|
if (cc == VANILLA_PIPE_OUT_BOUND_SUCCESSFUL) {
|
|
|
|
emit ready();
|
|
|
|
}
|
2024-05-20 19:16:40 -04:00
|
|
|
}
|