mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-14 18:57:07 -07:00
Implement Wakeup
This commit is contained in:
parent
52cacecaa0
commit
4fadc02947
9 changed files with 132 additions and 8 deletions
|
@ -59,6 +59,8 @@ class DiscoveryManager : public QObject
|
|||
|
||||
void SetActive(bool active);
|
||||
|
||||
void SendWakeup(const QString &host, const QByteArray ®ist_key);
|
||||
|
||||
const QList<DiscoveryHost> GetHosts() const { return hosts; }
|
||||
|
||||
signals:
|
||||
|
|
|
@ -56,6 +56,7 @@ class MainWindow : public QMainWindow
|
|||
QList<DisplayServer> display_servers;
|
||||
|
||||
DisplayServer *DisplayServerFromSender();
|
||||
void SendWakeup(const DisplayServer *server);
|
||||
|
||||
private slots:
|
||||
void ServerItemWidgetSelected();
|
||||
|
|
|
@ -37,6 +37,7 @@ class ServerItemWidget : public QFrame
|
|||
ServerIconWidget *icon_widget;
|
||||
|
||||
QAction *delete_action;
|
||||
QAction *wake_action;
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#include <utility>
|
||||
|
||||
/*
|
||||
* This file is part of Chiaki.
|
||||
*
|
||||
|
@ -18,7 +16,9 @@
|
|||
*/
|
||||
|
||||
#include <discoverymanager.h>
|
||||
#include <exception.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#define PING_MS 500
|
||||
|
@ -86,6 +86,78 @@ void DiscoveryManager::SetActive(bool active)
|
|||
|
||||
}
|
||||
|
||||
void DiscoveryManager::SendWakeup(const QString &host, const QByteArray ®ist_key)
|
||||
{
|
||||
addrinfo *addrinfos;
|
||||
int r = getaddrinfo(host.toLocal8Bit().constData(), nullptr, nullptr, &addrinfos);
|
||||
if(r != 0)
|
||||
{
|
||||
CHIAKI_LOGE(&log, "DiscoveryManager failed to getaddrinfo for wakeup");
|
||||
throw Exception("Failed to getaddrinfo");
|
||||
}
|
||||
sockaddr addr = {};
|
||||
socklen_t addr_len = 0;
|
||||
for(addrinfo *ai=addrinfos; ai; ai=ai->ai_next)
|
||||
{
|
||||
if(ai->ai_family != AF_INET)
|
||||
continue;
|
||||
if(ai->ai_protocol != IPPROTO_UDP)
|
||||
continue;
|
||||
if(ai->ai_addrlen > sizeof(addr))
|
||||
continue;
|
||||
std::memcpy(&addr, ai->ai_addr, ai->ai_addrlen);
|
||||
addr_len = ai->ai_addrlen;
|
||||
break;
|
||||
}
|
||||
freeaddrinfo(addrinfos);
|
||||
|
||||
if(!addr_len)
|
||||
{
|
||||
CHIAKI_LOGE(&log, "DiscoveryManager failed to get suitable address from getaddrinfo for wakeup");
|
||||
throw Exception("Failed to get addr from getaddrinfo");
|
||||
}
|
||||
|
||||
((sockaddr_in *)&addr)->sin_port = htons(CHIAKI_DISCOVERY_PORT);
|
||||
|
||||
QByteArray key = regist_key;
|
||||
for(size_t i=0; i<key.size(); i++)
|
||||
{
|
||||
if(!key.at(i))
|
||||
{
|
||||
key.resize(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool ok;
|
||||
uint64_t credential = (uint64_t)QString::fromUtf8(key).toULongLong(&ok, 16);
|
||||
if(key.size() > 8 || !ok)
|
||||
{
|
||||
CHIAKI_LOGE(&log, "DiscoveryManager got invalid regist key for wakeup");
|
||||
throw Exception("Invalid regist key");
|
||||
}
|
||||
|
||||
ChiakiDiscoveryPacket packet = {};
|
||||
packet.cmd = CHIAKI_DISCOVERY_CMD_WAKEUP;
|
||||
packet.user_credential = credential;
|
||||
|
||||
ChiakiErrorCode err;
|
||||
if(service_active)
|
||||
err = chiaki_discovery_send(&service.discovery, &packet, &addr, addr_len);
|
||||
else
|
||||
{
|
||||
ChiakiDiscovery discovery;
|
||||
err = chiaki_discovery_init(&discovery, &log, AF_INET);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
throw Exception(QString("Failed to init Discovery: %1").arg(chiaki_error_string(err)));
|
||||
err = chiaki_discovery_send(&discovery, &packet, &addr, addr_len);
|
||||
chiaki_discovery_fini(&discovery);
|
||||
}
|
||||
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
throw Exception(QString("Failed to send Packet: %1").arg(chiaki_error_string(err)));
|
||||
}
|
||||
|
||||
void DiscoveryManager::DiscoveryServiceHosts(QList<DiscoveryHost> hosts)
|
||||
{
|
||||
this->hosts = std::move(hosts);
|
||||
|
|
|
@ -121,6 +121,24 @@ DisplayServer *MainWindow::DisplayServerFromSender()
|
|||
return &display_servers[index];
|
||||
}
|
||||
|
||||
void MainWindow::SendWakeup(const DisplayServer *server)
|
||||
{
|
||||
if(!server->registered)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
discovery_manager.SendWakeup(server->GetHostAddr(), server->registered_host.GetRPRegistKey());
|
||||
}
|
||||
catch(const Exception &e)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Wakeup failed"), tr("Failed to send Wakeup packet:\n%1").arg(e.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
QMessageBox::information(this, tr("Wakeup"), tr("Wakeup packet sent."));
|
||||
}
|
||||
|
||||
void MainWindow::ServerItemWidgetTriggered()
|
||||
{
|
||||
auto server = DisplayServerFromSender();
|
||||
|
@ -129,6 +147,21 @@ void MainWindow::ServerItemWidgetTriggered()
|
|||
|
||||
if(server->registered)
|
||||
{
|
||||
if(server->discovered && server->discovery_host.state == CHIAKI_DISCOVERY_HOST_STATE_STANDBY)
|
||||
{
|
||||
int r = QMessageBox::question(this,
|
||||
tr("Start Stream"),
|
||||
tr("The Console is currently in standby mode.\nShould we send a Wakeup packet instead of trying to connect immediately?"),
|
||||
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
|
||||
if(r == QMessageBox::Yes)
|
||||
{
|
||||
SendWakeup(server);
|
||||
return;
|
||||
}
|
||||
else if(r == QMessageBox::Cancel)
|
||||
return;
|
||||
}
|
||||
|
||||
QString host = server->GetHostAddr();
|
||||
StreamSessionConnectInfo info(settings, host, server->registered_host.GetRPRegistKey(), server->registered_host.GetRPKey());
|
||||
try
|
||||
|
@ -165,9 +198,7 @@ void MainWindow::ServerItemWidgetWakeTriggered()
|
|||
auto server = DisplayServerFromSender();
|
||||
if(!server)
|
||||
return;
|
||||
|
||||
// TODO
|
||||
printf("TODO: Wakeup\n");
|
||||
SendWakeup(server);
|
||||
}
|
||||
|
||||
void MainWindow::UpdateDiscoveryEnabled()
|
||||
|
|
|
@ -51,7 +51,7 @@ ServerItemWidget::ServerItemWidget(QWidget *parent) : QFrame(parent)
|
|||
addAction(delete_action);
|
||||
connect(delete_action, &QAction::triggered, this, [this]{ emit DeleteTriggered(); });
|
||||
|
||||
auto wake_action = new QAction(tr("Send Wakeup Packet"), this);
|
||||
wake_action = new QAction(tr("Send Wakeup Packet"), this);
|
||||
addAction(wake_action);
|
||||
connect(wake_action, &QAction::triggered, this, [this]{ emit WakeTriggered(); });
|
||||
|
||||
|
@ -83,6 +83,7 @@ void ServerItemWidget::SetSelected(bool selected)
|
|||
void ServerItemWidget::Update(const DisplayServer &display_server)
|
||||
{
|
||||
delete_action->setEnabled(!display_server.discovered);
|
||||
wake_action->setEnabled(display_server.registered);
|
||||
|
||||
icon_widget->SetState(display_server.discovered ? display_server.discovery_host.state : CHIAKI_DISCOVERY_HOST_STATE_UNKNOWN);
|
||||
|
||||
|
|
|
@ -35,13 +35,15 @@ extern "C" {
|
|||
|
||||
typedef enum chiaki_discovery_cmd_t
|
||||
{
|
||||
CHIAKI_DISCOVERY_CMD_SRCH
|
||||
CHIAKI_DISCOVERY_CMD_SRCH,
|
||||
CHIAKI_DISCOVERY_CMD_WAKEUP
|
||||
} ChiakiDiscoveryCmd;
|
||||
|
||||
typedef struct chiaki_discovery_packet_t
|
||||
{
|
||||
ChiakiDiscoveryCmd cmd;
|
||||
char *protocol_version;
|
||||
uint64_t user_credential; // for wakeup, this is just the regist key interpreted as hex
|
||||
} ChiakiDiscoveryPacket;
|
||||
|
||||
typedef enum chiaki_discovery_host_state_t
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
const char *chiaki_discovery_host_state_string(ChiakiDiscoveryHostState state)
|
||||
|
@ -49,6 +50,16 @@ CHIAKI_EXPORT int chiaki_discovery_packet_fmt(char *buf, size_t buf_size, Chiaki
|
|||
case CHIAKI_DISCOVERY_CMD_SRCH:
|
||||
return snprintf(buf, buf_size, "SRCH * HTTP/1.1\ndevice-discovery-protocol-version:%s\n",
|
||||
version_str);
|
||||
case CHIAKI_DISCOVERY_CMD_WAKEUP:
|
||||
return snprintf(buf, buf_size,
|
||||
"WAKEUP * HTTP/1.1\n"
|
||||
"client-type:vr\n"
|
||||
"auth-type:R\n"
|
||||
"model:w\n"
|
||||
"app-type:r\n"
|
||||
"user-credential:%llu\n"
|
||||
"device-discovery-protocol-version:%s\n",
|
||||
(unsigned long long)packet->user_credential, version_str);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
@ -169,7 +180,10 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_send(ChiakiDiscovery *discovery,
|
|||
|
||||
ssize_t rc = sendto(discovery->socket, buf, (size_t)len + 1, 0, addr, addr_size);
|
||||
if(rc < 0)
|
||||
{
|
||||
CHIAKI_LOGE(discovery->log, "Discovery failed to send: %s", strerror(errno));
|
||||
return CHIAKI_ERR_NETWORK;
|
||||
}
|
||||
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -346,7 +346,7 @@ static int regist_search_connect(ChiakiRegist *regist, struct addrinfo *addrinfo
|
|||
}
|
||||
|
||||
in_addr_t ip = ((struct sockaddr_in *)send_addr)->sin_addr.s_addr;
|
||||
((struct sockaddr_in *)send_addr)->sin_addr.s_addr = INADDR_ANY;
|
||||
((struct sockaddr_in *)send_addr)->sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
r = bind(sock, send_addr, *send_addr_len);
|
||||
((struct sockaddr_in *)send_addr)->sin_addr.s_addr = ip;
|
||||
if(r < 0)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue