From 8904c86a6da646307356f67d23911c8a01664c34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Fri, 25 Dec 2020 14:48:09 +0100 Subject: [PATCH] Add Discovery and Wakeup for PS5 --- cli/src/discover.c | 4 ++-- cli/src/wakeup.c | 2 +- gui/include/discoverymanager.h | 2 +- gui/src/discoverymanager.cpp | 5 ++--- gui/src/mainwindow.cpp | 3 ++- lib/include/chiaki/discovery.h | 8 +++++--- lib/src/discovery.c | 14 +++++++++----- lib/src/discoveryservice.c | 22 ++++++++++++++++++++-- switch/src/discoverymanager.cpp | 1 - 9 files changed, 42 insertions(+), 19 deletions(-) diff --git a/cli/src/discover.c b/cli/src/discover.c index 3ebb9d1..503b53a 100644 --- a/cli/src/discover.c +++ b/cli/src/discover.c @@ -142,7 +142,7 @@ CHIAKI_EXPORT int chiaki_cli_cmd_discover(ChiakiLog *log, int argc, char *argv[] return 1; } - ((struct sockaddr_in *)host_addr)->sin_port = htons(CHIAKI_DISCOVERY_PORT); // TODO: IPv6 + ((struct sockaddr_in *)host_addr)->sin_port = htons(CHIAKI_DISCOVERY_PORT_PS4); // TODO: IPv6, PS5, should probably use the service ChiakiDiscoveryPacket packet; memset(&packet, 0, sizeof(packet)); @@ -151,7 +151,7 @@ CHIAKI_EXPORT int chiaki_cli_cmd_discover(ChiakiLog *log, int argc, char *argv[] chiaki_discovery_send(&discovery, &packet, host_addr, host_addr_len); while(1) - sleep(1); + sleep(1); // TODO: wtf return 0; } diff --git a/cli/src/wakeup.c b/cli/src/wakeup.c index cc7dcde..cf5ab45 100644 --- a/cli/src/wakeup.c +++ b/cli/src/wakeup.c @@ -73,5 +73,5 @@ CHIAKI_EXPORT int chiaki_cli_cmd_wakeup(ChiakiLog *log, int argc, char *argv[]) uint64_t credential = (uint64_t)strtoull(arguments.registkey, NULL, 16); - return chiaki_discovery_wakeup(log, NULL, arguments.host, credential); + return chiaki_discovery_wakeup(log, NULL, arguments.host, credential, false); } diff --git a/gui/include/discoverymanager.h b/gui/include/discoverymanager.h index 67093de..f03a5e6 100644 --- a/gui/include/discoverymanager.h +++ b/gui/include/discoverymanager.h @@ -44,7 +44,7 @@ class DiscoveryManager : public QObject void SetActive(bool active); - void SendWakeup(const QString &host, const QByteArray ®ist_key); + void SendWakeup(const QString &host, const QByteArray ®ist_key, bool ps5); const QList GetHosts() const { return hosts; } diff --git a/gui/src/discoverymanager.cpp b/gui/src/discoverymanager.cpp index f85dc88..042e68b 100644 --- a/gui/src/discoverymanager.cpp +++ b/gui/src/discoverymanager.cpp @@ -58,7 +58,6 @@ void DiscoveryManager::SetActive(bool active) sockaddr_in addr = {}; addr.sin_family = AF_INET; - addr.sin_port = htons(CHIAKI_DISCOVERY_PORT); addr.sin_addr.s_addr = 0xffffffff; // 255.255.255.255 options.send_addr = reinterpret_cast(&addr); options.send_addr_size = sizeof(addr); @@ -80,7 +79,7 @@ void DiscoveryManager::SetActive(bool active) } -void DiscoveryManager::SendWakeup(const QString &host, const QByteArray ®ist_key) +void DiscoveryManager::SendWakeup(const QString &host, const QByteArray ®ist_key, bool ps5) { QByteArray key = regist_key; for(size_t i=0; iGetHostAddr(), server->registered_host.GetRPRegistKey()); + discovery_manager.SendWakeup(server->GetHostAddr(), server->registered_host.GetRPRegistKey(), + chiaki_target_is_ps5(server->registered_host.GetTarget())); } catch(const Exception &e) { diff --git a/lib/include/chiaki/discovery.h b/lib/include/chiaki/discovery.h index b9fa2ec..50364ac 100644 --- a/lib/include/chiaki/discovery.h +++ b/lib/include/chiaki/discovery.h @@ -21,8 +21,10 @@ typedef unsigned short sa_family_t; extern "C" { #endif -#define CHIAKI_DISCOVERY_PORT 987 -#define CHIAKI_DISCOVERY_PROTOCOL_VERSION "00020020" +#define CHIAKI_DISCOVERY_PORT_PS4 987 +#define CHIAKI_DISCOVERY_PROTOCOL_VERSION_PS4 "00020020" +#define CHIAKI_DISCOVERY_PORT_PS5 9302 +#define CHIAKI_DISCOVERY_PROTOCOL_VERSION_PS5 "00030010" typedef enum chiaki_discovery_cmd_t { @@ -101,7 +103,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_thread_stop(ChiakiDiscoveryThread * Convenience function to send a wakeup packet * @param discovery Discovery to send the packet on. May be NULL, in which case a new temporary Discovery will be created */ -CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_wakeup(ChiakiLog *log, ChiakiDiscovery *discovery, const char *host, uint64_t user_credential); +CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_wakeup(ChiakiLog *log, ChiakiDiscovery *discovery, const char *host, uint64_t user_credential, bool ps5); #ifdef __cplusplus } diff --git a/lib/src/discovery.c b/lib/src/discovery.c index fb910a4..4771456 100644 --- a/lib/src/discovery.c +++ b/lib/src/discovery.c @@ -34,12 +34,13 @@ const char *chiaki_discovery_host_state_string(ChiakiDiscoveryHostState state) CHIAKI_EXPORT int chiaki_discovery_packet_fmt(char *buf, size_t buf_size, ChiakiDiscoveryPacket *packet) { - const char *version_str = packet->protocol_version ? packet->protocol_version : CHIAKI_DISCOVERY_PROTOCOL_VERSION; + if(!packet->protocol_version) + return -1; switch(packet->cmd) { case CHIAKI_DISCOVERY_CMD_SRCH: return snprintf(buf, buf_size, "SRCH * HTTP/1.1\ndevice-discovery-protocol-version:%s\n", - version_str); + packet->protocol_version); case CHIAKI_DISCOVERY_CMD_WAKEUP: return snprintf(buf, buf_size, "WAKEUP * HTTP/1.1\n" @@ -49,7 +50,7 @@ CHIAKI_EXPORT int chiaki_discovery_packet_fmt(char *buf, size_t buf_size, Chiaki "app-type:r\n" "user-credential:%llu\n" "device-discovery-protocol-version:%s\n", - (unsigned long long)packet->user_credential, version_str); + (unsigned long long)packet->user_credential, packet->protocol_version); default: return -1; } @@ -179,6 +180,8 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_send(ChiakiDiscovery *discovery, if((size_t)len >= sizeof(buf)) return CHIAKI_ERR_BUF_TOO_SMALL; + CHIAKI_LOGV(discovery->log, "Discovery sending:"); + chiaki_log_hexdump(discovery->log, CHIAKI_LOG_VERBOSE, (const uint8_t *)buf, (size_t)len + 1); int rc = sendto_broadcast(discovery->log, discovery->socket, buf, (size_t)len + 1, 0, addr, addr_size); if(rc < 0) { @@ -280,7 +283,7 @@ static void *discovery_thread_func(void *user) return NULL; } -CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_wakeup(ChiakiLog *log, ChiakiDiscovery *discovery, const char *host, uint64_t user_credential) +CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_wakeup(ChiakiLog *log, ChiakiDiscovery *discovery, const char *host, uint64_t user_credential, bool ps5) { struct addrinfo *addrinfos; int r = getaddrinfo(host, NULL, NULL, &addrinfos); // TODO: this blocks, use something else @@ -311,10 +314,11 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_wakeup(ChiakiLog *log, ChiakiDisc return CHIAKI_ERR_UNKNOWN; } - ((struct sockaddr_in *)&addr)->sin_port = htons(CHIAKI_DISCOVERY_PORT); + ((struct sockaddr_in *)&addr)->sin_port = htons(ps5 ? CHIAKI_DISCOVERY_PORT_PS5 : CHIAKI_DISCOVERY_PORT_PS4); ChiakiDiscoveryPacket packet = { 0 }; packet.cmd = CHIAKI_DISCOVERY_CMD_WAKEUP; + packet.protocol_version = ps5 ? CHIAKI_DISCOVERY_PROTOCOL_VERSION_PS5 : CHIAKI_DISCOVERY_PROTOCOL_VERSION_PS4; packet.user_credential = user_credential; ChiakiErrorCode err; diff --git a/lib/src/discoveryservice.c b/lib/src/discoveryservice.c index 5ec84e6..463c65f 100644 --- a/lib/src/discoveryservice.c +++ b/lib/src/discoveryservice.c @@ -135,9 +135,27 @@ static void discovery_service_ping(ChiakiDiscoveryService *service) CHIAKI_LOGV(service->log, "Discovery Service sending ping"); ChiakiDiscoveryPacket packet = { 0 }; packet.cmd = CHIAKI_DISCOVERY_CMD_SRCH; + packet.protocol_version = CHIAKI_DISCOVERY_PROTOCOL_VERSION_PS4; + if(service->options.send_addr->sa_family == AF_INET) + ((struct sockaddr_in *)service->options.send_addr)->sin_port = htons(CHIAKI_DISCOVERY_PORT_PS4); + else if(service->options.send_addr->sa_family == AF_INET6) + ((struct sockaddr_in6 *)service->options.send_addr)->sin6_port = htons(CHIAKI_DISCOVERY_PORT_PS4); + else + { + CHIAKI_LOGE(service->log, "Discovery Service send_addr has unknown sa_family"); + return; + } err = chiaki_discovery_send(&service->discovery, &packet, service->options.send_addr, service->options.send_addr_size); if(err != CHIAKI_ERR_SUCCESS) - CHIAKI_LOGE(service->log, "Discovery Service failed to send ping"); + CHIAKI_LOGE(service->log, "Discovery Service failed to send ping for PS4"); + packet.protocol_version = CHIAKI_DISCOVERY_PROTOCOL_VERSION_PS5; + if(service->options.send_addr->sa_family == AF_INET) + ((struct sockaddr_in *)service->options.send_addr)->sin_port = htons(CHIAKI_DISCOVERY_PORT_PS5); + else // if(service->options.send_addr->sa_family == AF_INET6) + ((struct sockaddr_in6 *)service->options.send_addr)->sin6_port = htons(CHIAKI_DISCOVERY_PORT_PS5); + err = chiaki_discovery_send(&service->discovery, &packet, service->options.send_addr, service->options.send_addr_size); + if(err != CHIAKI_ERR_SUCCESS) + CHIAKI_LOGE(service->log, "Discovery Service failed to send ping for PS5"); } static void discovery_service_drop_old_hosts(ChiakiDiscoveryService *service) @@ -264,4 +282,4 @@ static void discovery_service_report_state(ChiakiDiscoveryService *service) // service->state_mutex must be locked if(service->options.cb) service->options.cb(service->hosts, service->hosts_count, service->options.cb_user); -} \ No newline at end of file +} diff --git a/switch/src/discoverymanager.cpp b/switch/src/discoverymanager.cpp index 4c0ebbe..0b8bb4d 100644 --- a/switch/src/discoverymanager.cpp +++ b/switch/src/discoverymanager.cpp @@ -63,7 +63,6 @@ void DiscoveryManager::SetService(bool enable) sockaddr_in addr = {}; addr.sin_family = AF_INET; - addr.sin_port = htons(CHIAKI_DISCOVERY_PORT); addr.sin_addr.s_addr = GetIPv4BroadcastAddr(); options.send_addr = reinterpret_cast(&addr); options.send_addr_size = sizeof(addr);