From 2d97fc67977154544f066440a19c65b9d8404d6a Mon Sep 17 00:00:00 2001 From: Ningyuan Li Date: Mon, 30 Sep 2024 00:13:07 +0900 Subject: [PATCH 1/2] uuid based host discovery --- core/libgamestream/src/client.c | 2 +- src/app/backend/pcmanager.h | 4 +- src/app/backend/pcmanager/CMakeLists.txt | 2 + .../pcmanager/discovery/CMakeLists.txt | 19 +-- .../backend/pcmanager/discovery/discovery.c | 62 ++++++++++ .../backend/pcmanager/discovery/discovery.h | 48 ++++++++ .../pcmanager/discovery/impl/CMakeLists.txt | 17 +++ .../{discovery_dnssd.c => impl/dnssd.c} | 0 .../backend/pcmanager/discovery/impl/impl.h | 36 ++++++ .../microdns.c} | 93 +++++--------- .../backend/pcmanager/discovery/throttle.c | 114 ++++++++++++++++++ .../backend/pcmanager/discovery/throttle.h | 27 +++++ .../backend/pcmanager/discovery_callback.c | 67 ++++++++++ src/app/backend/pcmanager/pclist.c | 23 +++- src/app/backend/pcmanager/pclist.h | 2 + src/app/backend/pcmanager/pcmanager.c | 14 ++- src/app/backend/pcmanager/priv.h | 5 +- src/app/backend/pcmanager/worker/manual_add.c | 8 +- src/app/backend/pcmanager/worker/update.c | 18 ++- tests/app/backend/pcmanager/CMakeLists.txt | 4 +- .../pcmanager/discovery/CMakeLists.txt | 1 + .../pcmanager/discovery/test_throttle.c | 42 +++++++ third_party/commons | 2 +- third_party/ss4s | 2 +- 24 files changed, 511 insertions(+), 101 deletions(-) create mode 100644 src/app/backend/pcmanager/discovery/discovery.c create mode 100644 src/app/backend/pcmanager/discovery/discovery.h create mode 100644 src/app/backend/pcmanager/discovery/impl/CMakeLists.txt rename src/app/backend/pcmanager/discovery/{discovery_dnssd.c => impl/dnssd.c} (100%) create mode 100644 src/app/backend/pcmanager/discovery/impl/impl.h rename src/app/backend/pcmanager/discovery/{discovery_libmicrodns.c => impl/microdns.c} (52%) create mode 100644 src/app/backend/pcmanager/discovery/throttle.c create mode 100644 src/app/backend/pcmanager/discovery/throttle.h create mode 100644 src/app/backend/pcmanager/discovery_callback.c create mode 100644 tests/app/backend/pcmanager/discovery/CMakeLists.txt create mode 100644 tests/app/backend/pcmanager/discovery/test_throttle.c diff --git a/core/libgamestream/src/client.c b/core/libgamestream/src/client.c index 8060b982c..4fdd3519d 100644 --- a/core/libgamestream/src/client.c +++ b/core/libgamestream/src/client.c @@ -866,7 +866,7 @@ static int load_server_status(GS_CLIENT hnd, PSERVER_DATA server) { } i++; - } while (ret != GS_OK && i < 2); + } while (ret == GS_ERROR && i < 2); if (ret == GS_OK && !server->unsupported) { if (server->serverMajorVersion > MAX_SUPPORTED_GFE_VERSION) { diff --git a/src/app/backend/pcmanager.h b/src/app/backend/pcmanager.h index 7dc2a3347..f6af837d9 100644 --- a/src/app/backend/pcmanager.h +++ b/src/app/backend/pcmanager.h @@ -133,4 +133,6 @@ bool pcmanager_send_wol(pcmanager_t *manager, const uuidstr_t *uuid, pcmanager_c * @param userdata * @return */ -int pcmanager_update_by_ip(worker_context_t *context, const char *ip, uint16_t port, bool force); \ No newline at end of file +int pcmanager_update_by_ip(worker_context_t *context, const char *ip, uint16_t port, bool force); + +int pcmanager_update_by_addr(worker_context_t *context, sockaddr_t *addr, bool force); \ No newline at end of file diff --git a/src/app/backend/pcmanager/CMakeLists.txt b/src/app/backend/pcmanager/CMakeLists.txt index 9fbfedaa5..c633b46e9 100644 --- a/src/app/backend/pcmanager/CMakeLists.txt +++ b/src/app/backend/pcmanager/CMakeLists.txt @@ -1 +1,3 @@ +target_sources(moonlight-lib PRIVATE discovery_callback.c) + add_subdirectory(discovery) \ No newline at end of file diff --git a/src/app/backend/pcmanager/discovery/CMakeLists.txt b/src/app/backend/pcmanager/discovery/CMakeLists.txt index fb286be64..954775387 100644 --- a/src/app/backend/pcmanager/discovery/CMakeLists.txt +++ b/src/app/backend/pcmanager/discovery/CMakeLists.txt @@ -1,17 +1,2 @@ -include(CheckSymbolExists) - -check_symbol_exists(DNSServiceCreateConnection "dns_sd.h" HAVE_DNSSD) - -if (HAVE_DNSSD) - target_sources(moonlight-lib PRIVATE discovery_dnssd.c) -elseif (OS_WINDOWS) - pkg_check_modules(MICRODNS REQUIRED microdns) - target_link_libraries(moonlight-lib PUBLIC ${MICRODNS_LIBRARIES}) - target_sources(moonlight-lib PRIVATE discovery_libmicrodns.c) -else () - set(BUILD_SHARED_LIBS ON) - include(BuildMicrodns) - target_link_libraries(moonlight-lib PUBLIC microdns) - unset(BUILD_SHARED_LIBS) - target_sources(moonlight-lib PRIVATE discovery_libmicrodns.c) -endif () \ No newline at end of file +target_sources(moonlight-lib PRIVATE discovery.c throttle.c) +add_subdirectory(impl) \ No newline at end of file diff --git a/src/app/backend/pcmanager/discovery/discovery.c b/src/app/backend/pcmanager/discovery/discovery.c new file mode 100644 index 000000000..d2c2672dd --- /dev/null +++ b/src/app/backend/pcmanager/discovery/discovery.c @@ -0,0 +1,62 @@ +#include "discovery.h" +#include "throttle.h" + +#include "impl/impl.h" + +#include "util/bus.h" +#include "logging.h" + +static int discovery_worker_wrapper(void *arg); + +void discovery_init(discovery_t *discovery, discovery_callback callback, void *user_data) { + discovery->lock = SDL_CreateMutex(); + discovery->task = NULL; + discovery_throttle_init(&discovery->throttle, callback, user_data); +} + +void discovery_deinit(discovery_t *discovery) { + discovery_throttle_deinit(&discovery->throttle); + discovery_stop(discovery); + SDL_DestroyMutex(discovery->lock); +} + +void discovery_start(discovery_t *discovery) { + SDL_LockMutex(discovery->lock); + if (discovery->task != NULL) { + SDL_UnlockMutex(discovery->lock); + return; + } + discovery_task_t *task = SDL_calloc(1, sizeof(discovery_task_t)); + commons_log_info("Discovery", "Start task %p", task); + task->discovery = discovery; + task->lock = SDL_CreateMutex(); + task->stop = false; + SDL_Thread *thread = SDL_CreateThread(discovery_worker_wrapper, "discovery", task); + SDL_DetachThread(thread); + discovery->task = task; + SDL_UnlockMutex(discovery->lock); +} + +void discovery_stop(discovery_t *discovery) { + SDL_LockMutex(discovery->lock); + discovery_task_t *task = discovery->task; + if (task == NULL) { + SDL_UnlockMutex(discovery->lock); + return; + } + discovery->task = NULL; + discovery_worker_stop(task); + SDL_UnlockMutex(discovery->lock); +} + +void discovery_discovered(struct discovery_t *discovery, const sockaddr_t *addr) { + discovery_throttle_on_discovered(&discovery->throttle, addr, 10000); +} + +int discovery_worker_wrapper(void *arg) { + discovery_task_t *task = (discovery_task_t *) arg; + int result = discovery_worker(task); + SDL_DestroyMutex(task->lock); + free(arg); + return result; +} \ No newline at end of file diff --git a/src/app/backend/pcmanager/discovery/discovery.h b/src/app/backend/pcmanager/discovery/discovery.h new file mode 100644 index 000000000..6b5905fdb --- /dev/null +++ b/src/app/backend/pcmanager/discovery/discovery.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024 Mariotaku . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + */ + +#pragma once + +#include +#include +#include "sockaddr.h" + +typedef void (*discovery_callback)(const sockaddr_t *addr, void *user_data); + +typedef struct discovery_throttle_host_t discovery_throttle_host_t; + +typedef struct discovery_throttle_t { + discovery_callback callback; + void *user_data; + discovery_throttle_host_t *hosts; + SDL_mutex *lock; +} discovery_throttle_t; + +typedef struct discovery_t { + SDL_mutex *lock; + struct discovery_task_t *task; + discovery_throttle_t throttle; +} discovery_t; + +void discovery_init(discovery_t *discovery, discovery_callback callback, void *user_data); + +void discovery_start(discovery_t *discovery); + +void discovery_stop(discovery_t *discovery); + +void discovery_deinit(discovery_t *discovery); diff --git a/src/app/backend/pcmanager/discovery/impl/CMakeLists.txt b/src/app/backend/pcmanager/discovery/impl/CMakeLists.txt new file mode 100644 index 000000000..4e72134bf --- /dev/null +++ b/src/app/backend/pcmanager/discovery/impl/CMakeLists.txt @@ -0,0 +1,17 @@ +include(CheckSymbolExists) + +check_symbol_exists(DNSServiceCreateConnection "dns_sd.h" HAVE_DNSSD) + +if (HAVE_DNSSD) + target_sources(moonlight-lib PRIVATE dnssd.c) +else () + target_sources(moonlight-lib PRIVATE microdns.c) + if (OS_WINDOWS) + pkg_check_modules(MICRODNS REQUIRED microdns) + target_link_libraries(moonlight-lib PUBLIC ${MICRODNS_LIBRARIES}) + endif () + set(BUILD_SHARED_LIBS ON) + include(BuildMicrodns) + target_link_libraries(moonlight-lib PUBLIC microdns) + unset(BUILD_SHARED_LIBS) +endif () diff --git a/src/app/backend/pcmanager/discovery/discovery_dnssd.c b/src/app/backend/pcmanager/discovery/impl/dnssd.c similarity index 100% rename from src/app/backend/pcmanager/discovery/discovery_dnssd.c rename to src/app/backend/pcmanager/discovery/impl/dnssd.c diff --git a/src/app/backend/pcmanager/discovery/impl/impl.h b/src/app/backend/pcmanager/discovery/impl/impl.h new file mode 100644 index 000000000..369209371 --- /dev/null +++ b/src/app/backend/pcmanager/discovery/impl/impl.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Mariotaku . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + */ + +#pragma once + +#include +#include + +#include "sockaddr.h" + +typedef struct discovery_task_t { + struct discovery_t *discovery; + SDL_mutex *lock; + bool stop; +} discovery_task_t; + +int discovery_worker(discovery_task_t *task); + +void discovery_worker_stop(discovery_task_t *task); + +void discovery_discovered(struct discovery_t *discovery, const sockaddr_t *addr); \ No newline at end of file diff --git a/src/app/backend/pcmanager/discovery/discovery_libmicrodns.c b/src/app/backend/pcmanager/discovery/impl/microdns.c similarity index 52% rename from src/app/backend/pcmanager/discovery/discovery_libmicrodns.c rename to src/app/backend/pcmanager/discovery/impl/microdns.c index 591513657..ae6fe0175 100644 --- a/src/app/backend/pcmanager/discovery/discovery_libmicrodns.c +++ b/src/app/backend/pcmanager/discovery/impl/microdns.c @@ -1,54 +1,31 @@ -#include "backend/pcmanager/priv.h" -#include "logging.h" +/* + * Copyright (c) 2024 Mariotaku . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + */ +#include "impl.h" + #include -#include "util/bus.h" -#include "backend/pcmanager/worker/worker.h" #include "sockaddr.h" - -struct discovery_task_t { - pcmanager_t *manager; - SDL_mutex *lock; - SDL_Thread *thread; - bool stop; -}; - -static int discovery_worker(discovery_task_t *task); - -static bool discovery_stopped(discovery_task_t *task); +#include "logging.h" static void discovery_callback(discovery_task_t *task, int status, const struct rr_entry *entries); -static void discovery_finalize(void *arg, int result); +static bool discovery_is_stopped(discovery_task_t *task); -void pcmanager_auto_discovery_start(pcmanager_t *manager) { - pcmanager_lock(manager); - if (manager->discovery_task != NULL) { - pcmanager_unlock(manager); - return; - } - discovery_task_t *task = SDL_calloc(1, sizeof(discovery_task_t)); - commons_log_info("Discovery", "Start task %p", task); - task->manager = manager; - task->lock = SDL_CreateMutex(); - task->stop = false; - task->thread = SDL_CreateThread((SDL_ThreadFunction) discovery_worker, "discovery", task); - manager->discovery_task = task; - pcmanager_unlock(manager); -} - -void pcmanager_auto_discovery_stop(pcmanager_t *manager) { - pcmanager_lock(manager); - discovery_task_t *task = manager->discovery_task; - if (task == NULL) { - pcmanager_unlock(manager); - return; - } - manager->discovery_task = NULL; - executor_submit(manager->executor, executor_noop, discovery_finalize, task); - pcmanager_unlock(manager); -} - -static int discovery_worker(discovery_task_t *task) { +int discovery_worker(discovery_task_t *task) { int r; char err[128]; static const char *const service_name[] = {"_nvstream._tcp.local"}; @@ -58,7 +35,7 @@ static int discovery_worker(discovery_task_t *task) { goto err; } commons_log_info("Discovery", "Start mDNS discovery"); - if ((r = mdns_listen(ctx, service_name, 1, RR_PTR, 10, (mdns_stop_func) discovery_stopped, + if ((r = mdns_listen(ctx, service_name, 1, RR_PTR, 10, (mdns_stop_func) discovery_is_stopped, (mdns_listen_callback) discovery_callback, task)) < 0) { goto err; } @@ -74,14 +51,13 @@ static int discovery_worker(discovery_task_t *task) { return r; } -static bool discovery_stopped(discovery_task_t *task) { +void discovery_worker_stop(discovery_task_t *task) { SDL_LockMutex(task->lock); - bool stop = task->stop; + task->stop = true; SDL_UnlockMutex(task->lock); - return stop; } -static void discovery_callback(discovery_task_t *task, int status, const struct rr_entry *entries) { +void discovery_callback(discovery_task_t *task, int status, const struct rr_entry *entries) { char err[128]; if (status < 0) { @@ -114,19 +90,12 @@ static void discovery_callback(discovery_task_t *task, int status, const struct if (addr->sa_family == AF_UNSPEC) { return; } - worker_context_t *ctx = worker_context_new(task->manager, NULL, NULL, NULL); - ctx->arg1 = addr; - pcmanager_worker_queue(task->manager, worker_host_discovered, ctx); + discovery_discovered(task->discovery, addr); } -static void discovery_finalize(void *arg, int result) { - (void) result; - commons_log_info("Discovery", "Finalize task %p", arg); - discovery_task_t *task = arg; +bool discovery_is_stopped(discovery_task_t *task) { SDL_LockMutex(task->lock); - task->stop = true; + bool stop = task->stop; SDL_UnlockMutex(task->lock); - SDL_WaitThread(task->thread, NULL); - SDL_DestroyMutex(task->lock); - free(task); -} + return stop; +} \ No newline at end of file diff --git a/src/app/backend/pcmanager/discovery/throttle.c b/src/app/backend/pcmanager/discovery/throttle.c new file mode 100644 index 000000000..93563641e --- /dev/null +++ b/src/app/backend/pcmanager/discovery/throttle.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2024 Mariotaku . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + */ + +#include "throttle.h" +#include +#include + +struct discovery_throttle_host_t { + sockaddr_t *addr; + Uint32 ttl, last_discovered; + discovery_throttle_host_t *next; + discovery_throttle_host_t *prev; +}; + +#define LINKEDLIST_IMPL +#define LINKEDLIST_MODIFIER static +#define LINKEDLIST_TYPE discovery_throttle_host_t +#define LINKEDLIST_PREFIX throttle_hosts +#define LINKEDLIST_DOUBLE 1 + +#include "linked_list.h" + +#undef LINKEDLIST_DOUBLE +#undef LINKEDLIST_TYPE +#undef LINKEDLIST_PREFIX + +static int throttle_hosts_compare_time(discovery_throttle_host_t *a, discovery_throttle_host_t *b); + +static int throttle_hosts_find_addr(discovery_throttle_host_t *node, const void *addr); + +static int throttle_hosts_find_not_expired(discovery_throttle_host_t *node, const void *now); + +static void throttle_hosts_evict(discovery_throttle_host_t **head); + +void discovery_throttle_init(discovery_throttle_t *throttle, discovery_callback callback, void *user_data) { + throttle->callback = callback; + throttle->user_data = user_data; + throttle->hosts = NULL; + throttle->lock = SDL_CreateMutex(); +} + +void discovery_throttle_deinit(discovery_throttle_t *throttle) { + SDL_LockMutex(throttle->lock); + throttle_hosts_free(throttle->hosts, NULL); + SDL_UnlockMutex(throttle->lock); + SDL_DestroyMutex(throttle->lock); +} + +void discovery_throttle_on_discovered(discovery_throttle_t *throttle, const sockaddr_t *addr, Uint32 ttl) { + // Remove all expired hosts + SDL_LockMutex(throttle->lock); + throttle_hosts_evict(&throttle->hosts); + + // Find existing host + discovery_throttle_host_t *find = throttle_hosts_find_by(throttle->hosts, addr, throttle_hosts_find_addr); + + if (find != NULL) { + // Ignore existing host + SDL_UnlockMutex(throttle->lock); + return; + } + + discovery_throttle_host_t *node = throttle_hosts_new(); + node->addr = sockaddr_clone(addr); + node->ttl = ttl; + node->last_discovered = SDL_GetTicks(); + throttle->hosts = throttle_hosts_sortedinsert(throttle->hosts, node, throttle_hosts_compare_time); + + if (throttle->callback != NULL) { + throttle->callback(addr, throttle->user_data); + } + SDL_UnlockMutex(throttle->lock); +} + +int throttle_hosts_compare_time(discovery_throttle_host_t *a, discovery_throttle_host_t *b) { + return (int) a->last_discovered - (int) b->last_discovered; +} + +static int throttle_hosts_find_addr(discovery_throttle_host_t *node, const void *addr) { + return sockaddr_compare(node->addr, addr); +} + +void throttle_hosts_evict(discovery_throttle_host_t **head) { + Uint32 now = SDL_GetTicks(); + discovery_throttle_host_t *find = throttle_hosts_find_by(*head, &now, throttle_hosts_find_not_expired); + if (find != NULL) { + if (find->prev != NULL) { + find->prev->next = NULL; + } + find->prev = NULL; + return; + } + throttle_hosts_free(*head, NULL); + *head = find; +} + +int throttle_hosts_find_not_expired(discovery_throttle_host_t *node, const void *now) { + return SDL_TICKS_PASSED(*(Uint32 *) now, node->last_discovered + node->ttl); +} diff --git a/src/app/backend/pcmanager/discovery/throttle.h b/src/app/backend/pcmanager/discovery/throttle.h new file mode 100644 index 000000000..bdbf1fcb8 --- /dev/null +++ b/src/app/backend/pcmanager/discovery/throttle.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2024 Mariotaku . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + */ + +#pragma once + +#include "discovery.h" + +void discovery_throttle_init(discovery_throttle_t *throttle, discovery_callback callback, void *user_data); + +void discovery_throttle_deinit(discovery_throttle_t *throttle); + +void discovery_throttle_on_discovered(discovery_throttle_t *throttle, const sockaddr_t *addr, Uint32 ttl); diff --git a/src/app/backend/pcmanager/discovery_callback.c b/src/app/backend/pcmanager/discovery_callback.c new file mode 100644 index 000000000..142d57878 --- /dev/null +++ b/src/app/backend/pcmanager/discovery_callback.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2024 Mariotaku . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + */ +#include "priv.h" +#include "pclist.h" +#include "app.h" +#include "errors.h" + +#include "logging.h" + +static void lan_host_status_update(pcmanager_t *manager, SERVER_DATA *server); + +static void lan_host_offline(pcmanager_t *manager, const sockaddr_t *addr); + +void pcmanager_lan_host_discovered(const sockaddr_t *addr, pcmanager_t *manager) { + GS_CLIENT client = app_gs_client_new(manager->app); + SERVER_DATA *server = serverdata_new(); + char ip[64]; + sockaddr_get_ip_str(addr, ip, sizeof(ip)); + int ret = gs_get_status(client, server, strndup(ip, sizeof(ip)), sockaddr_get_port(addr), + app_configuration->unsupported); + if (ret == GS_OK) { + commons_log_info("PCManager", "Finished updating status from %s", ip); + lan_host_status_update(manager, server); + } else { + serverdata_free(server); + const char *gs_error = NULL; + ret = gs_get_error(&gs_error); + if (ret == GS_IO_ERROR) { + commons_log_warn("PCManager", "Error while updating status from %s. Host seems to be offline", ip); + lan_host_offline(manager, addr); + } else { + commons_log_warn("PCManager", "Error while updating status from %s: %d (%s)", ip, ret, gs_error); + } + } + gs_destroy(client); +} + + +void lan_host_status_update(pcmanager_t *manager, SERVER_DATA *server) { + SERVER_STATE state = {.code = server->paired ? SERVER_STATE_AVAILABLE : SERVER_STATE_NOT_PAIRED}; + pclist_upsert(manager, (const uuidstr_t *) server->uuid, &state, server); +} + +void lan_host_offline(pcmanager_t *manager, const sockaddr_t *addr) { + pclist_t *existing = pclist_find_by_addr(manager, addr); + if (!existing) { + return; + } + pcmanager_lock(manager); + existing->state.code = SERVER_STATE_OFFLINE; + pcmanager_unlock(manager); +} \ No newline at end of file diff --git a/src/app/backend/pcmanager/pclist.c b/src/app/backend/pcmanager/pclist.c index 4ccd110bf..5e2da9435 100644 --- a/src/app/backend/pcmanager/pclist.c +++ b/src/app/backend/pcmanager/pclist.c @@ -37,6 +37,8 @@ static void remove_perform(pclist_update_context_t *context); static void pclist_ll_nodefree(pclist_t *node); +static int pclist_ll_compare_ip(pclist_t *other, const void *v); + static int pclist_ll_compare_address(pclist_t *other, const void *v); static int pclist_ll_compare_uuid(pclist_t *other, const void *v); @@ -160,7 +162,15 @@ void pclist_ll_nodefree(pclist_t *node) { pclist_t *pclist_find_by_ip(pcmanager_t *manager, const char *ip) { SDL_assert_release(ip != NULL); pcmanager_lock(manager); - pclist_t *result = pclist_ll_find_by(manager->servers, ip, pclist_ll_compare_address); + pclist_t *result = pclist_ll_find_by(manager->servers, ip, pclist_ll_compare_ip); + pcmanager_unlock(manager); + return result; +} + +pclist_t *pclist_find_by_addr(pcmanager_t *manager, const sockaddr_t *addr) { + SDL_assert_release(addr != NULL); + pcmanager_lock(manager); + pclist_t *result = pclist_ll_find_by(manager->servers, addr, pclist_ll_compare_address); pcmanager_unlock(manager); return result; } @@ -173,7 +183,7 @@ pclist_t *pclist_find_by_uuid(pcmanager_t *manager, const uuidstr_t *uuid) { return result; } -static int pclist_ll_compare_address(pclist_t *other, const void *v) { +static int pclist_ll_compare_ip(pclist_t *other, const void *v) { SDL_assert_release(v); SDL_assert_release(other); SDL_assert_release(other->server); @@ -181,6 +191,15 @@ static int pclist_ll_compare_address(pclist_t *other, const void *v) { return SDL_strcmp(other->server->serverInfo.address, (const char *) v); } +static int pclist_ll_compare_address(pclist_t *other, const void *v) { + SDL_assert_release(v); + SDL_assert_release(other); + SDL_assert_release(other->server); + SDL_assert_release(other->server->serverInfo.address); + const sockaddr_t *addr = (const sockaddr_t *) v; + return 0; +} + static int pclist_ll_compare_uuid(pclist_t *other, const void *v) { SDL_assert_release(v); SDL_assert_release(other); diff --git a/src/app/backend/pcmanager/pclist.h b/src/app/backend/pcmanager/pclist.h index da2f7fdbb..1ee53749d 100644 --- a/src/app/backend/pcmanager/pclist.h +++ b/src/app/backend/pcmanager/pclist.h @@ -29,3 +29,5 @@ void pclist_free(pcmanager_t *manager); pclist_t *pclist_find_by_uuid(pcmanager_t *manager, const uuidstr_t *uuid); pclist_t *pclist_find_by_ip(pcmanager_t *manager, const char *ip); + +pclist_t *pclist_find_by_addr(pcmanager_t *manager, const sockaddr_t *addr); diff --git a/src/app/backend/pcmanager/pcmanager.c b/src/app/backend/pcmanager/pcmanager.c index 1349761fe..a2dd228be 100644 --- a/src/app/backend/pcmanager/pcmanager.c +++ b/src/app/backend/pcmanager/pcmanager.c @@ -1,5 +1,5 @@ - #include "backend/pcmanager.h" +#include "discovery/discovery.h" #include "priv.h" #include "pclist.h" @@ -13,6 +13,7 @@ pcmanager_t *pcmanager_new(app_t *app, executor_t *executor) { manager->executor = executor; manager->thread_id = SDL_ThreadID(); manager->lock = SDL_CreateMutex(); + discovery_init(&manager->discovery, (discovery_callback) pcmanager_lan_host_discovered, manager); pcmanager_load_known_hosts(manager); return manager; } @@ -21,10 +22,20 @@ void pcmanager_destroy(pcmanager_t *manager) { pcmanager_auto_discovery_stop(manager); pcmanager_save_known_hosts(manager); pclist_free(manager); + discovery_deinit(&manager->discovery); SDL_DestroyMutex(manager->lock); SDL_free(manager); } + +void pcmanager_auto_discovery_start(pcmanager_t *manager) { + discovery_start(&manager->discovery); +} + +void pcmanager_auto_discovery_stop(pcmanager_t *manager) { + discovery_stop(&manager->discovery); +} + void pcmanager_lock(pcmanager_t *manager) { SDL_LockMutex(manager->lock); } @@ -129,4 +140,3 @@ bool pcmanager_send_wol(pcmanager_t *manager, const uuidstr_t *uuid, pcmanager_c const pclist_t *pcmanager_servers(pcmanager_t *manager) { return manager->servers; } - diff --git a/src/app/backend/pcmanager/priv.h b/src/app/backend/pcmanager/priv.h index 0c6916e01..82b4d2f32 100644 --- a/src/app/backend/pcmanager/priv.h +++ b/src/app/backend/pcmanager/priv.h @@ -1,6 +1,7 @@ #pragma once #include "../pcmanager.h" +#include "discovery/discovery.h" #include "executor.h" #include "uuidstr.h" #include @@ -29,7 +30,7 @@ struct pcmanager_t { pclist_t *servers; SDL_mutex *lock; pcmanager_listener_list *listeners; - discovery_task_t *discovery_task; + discovery_t discovery; }; void serverdata_free(PSERVER_DATA data); @@ -45,3 +46,5 @@ void pcmanager_unlock(pcmanager_t *manager); void pcmanager_load_known_hosts(pcmanager_t *manager); void pcmanager_save_known_hosts(pcmanager_t *manager); + +void pcmanager_lan_host_discovered(const sockaddr_t *addr, pcmanager_t *manager); \ No newline at end of file diff --git a/src/app/backend/pcmanager/worker/manual_add.c b/src/app/backend/pcmanager/worker/manual_add.c index 274491041..6bdcaac17 100644 --- a/src/app/backend/pcmanager/worker/manual_add.c +++ b/src/app/backend/pcmanager/worker/manual_add.c @@ -14,11 +14,5 @@ int worker_host_discovered(worker_context_t *context) { } int updated_by_addr(worker_context_t *context, bool force) { - struct sockaddr *addr = context->arg1; - char ip[64]; - if (sockaddr_get_ip_str(addr, ip, sizeof(ip)) != 0) { - return GS_FAILED; - } - uint16_t port = sockaddr_get_port(addr); - return pcmanager_update_by_ip(context, ip, port, force); + return pcmanager_update_by_addr(context, context->arg1, force); } diff --git a/src/app/backend/pcmanager/worker/update.c b/src/app/backend/pcmanager/worker/update.c index 17658290c..b769767b4 100644 --- a/src/app/backend/pcmanager/worker/update.c +++ b/src/app/backend/pcmanager/worker/update.c @@ -3,6 +3,8 @@ #include "backend/pcmanager/pclist.h" #include "backend/pcmanager/listeners.h" +#include + #include "errors.h" #include "util/bus.h" #include "app.h" @@ -20,11 +22,17 @@ int worker_host_update(worker_context_t *context) { } int pcmanager_update_by_ip(worker_context_t *context, const char *ip, uint16_t port, bool force) { - SDL_assert_release(context != NULL); - SDL_assert_release(context->manager != NULL); - SDL_assert_release(ip != NULL); + return 0; +} + +int pcmanager_update_by_addr(worker_context_t *context, sockaddr_t *addr, bool force) { + assert(context != NULL); + assert(context->manager != NULL); + assert(addr != NULL); + int ret = 0; pcmanager_t *manager = context->manager; - char *ip_dup = strdup(ip); + // FIXME: Implement this + char *ip_dup = strdup(""); pclist_t *existing = pclist_find_by_ip(manager, ip_dup); if (existing) { SERVER_STATE_ENUM state = existing->state.code; @@ -47,7 +55,7 @@ int pcmanager_update_by_ip(worker_context_t *context, const char *ip, uint16_t p } GS_CLIENT client = app_gs_client_new(context->app); PSERVER_DATA server = serverdata_new(); - int ret = gs_get_status(client, server, ip_dup, port, app_configuration->unsupported); + ret = gs_get_status(client, server, ip_dup, sockaddr_get_port(addr), app_configuration->unsupported); ip_dup = NULL; gs_destroy(client); if (existing) { diff --git a/tests/app/backend/pcmanager/CMakeLists.txt b/tests/app/backend/pcmanager/CMakeLists.txt index bfea330ae..97712bff1 100644 --- a/tests/app/backend/pcmanager/CMakeLists.txt +++ b/tests/app/backend/pcmanager/CMakeLists.txt @@ -1 +1,3 @@ -add_unit_test(test_known_hosts test_known_hosts.c) \ No newline at end of file +add_unit_test(test_known_hosts test_known_hosts.c) + +add_subdirectory(discovery) \ No newline at end of file diff --git a/tests/app/backend/pcmanager/discovery/CMakeLists.txt b/tests/app/backend/pcmanager/discovery/CMakeLists.txt new file mode 100644 index 000000000..f2cf18c55 --- /dev/null +++ b/tests/app/backend/pcmanager/discovery/CMakeLists.txt @@ -0,0 +1 @@ +add_unit_test(test_throttle test_throttle.c) \ No newline at end of file diff --git a/tests/app/backend/pcmanager/discovery/test_throttle.c b/tests/app/backend/pcmanager/discovery/test_throttle.c new file mode 100644 index 000000000..10a14d9bd --- /dev/null +++ b/tests/app/backend/pcmanager/discovery/test_throttle.c @@ -0,0 +1,42 @@ +#include "unity.h" +#include "backend/pcmanager/discovery/throttle.h" + +#include + +static discovery_throttle_t throttle; +static int counter = 0; + +void callback(const sockaddr_t *addr, void *user_data) { + (void) addr; + (void) user_data; + counter++; +} + +void setUp(void) { + counter = 0; + discovery_throttle_init(&throttle, callback, NULL); +} + +void tearDown(void) { + discovery_throttle_deinit(&throttle); +} + +void test_discovery_throttle(void) { + sockaddr_t *addr = sockaddr_new(); + sockaddr_set_ip_str(addr, AF_INET, "192.168.1.110"); + sockaddr_set_port(addr, 47989); + discovery_throttle_on_discovered(&throttle, addr, 10); + discovery_throttle_on_discovered(&throttle, addr, 10); + discovery_throttle_on_discovered(&throttle, addr, 10); + TEST_ASSERT_EQUAL(1, counter); + SDL_Delay(20); + discovery_throttle_on_discovered(&throttle, addr, 10); + TEST_ASSERT_EQUAL(2, counter); + sockaddr_free(addr); +} + +int main() { + UNITY_BEGIN(); + RUN_TEST(test_discovery_throttle); + return UNITY_END(); +} \ No newline at end of file diff --git a/third_party/commons b/third_party/commons index 3a22070ce..a8c933035 160000 --- a/third_party/commons +++ b/third_party/commons @@ -1 +1 @@ -Subproject commit 3a22070ce74b35119f892751d4cd4eb5b2289e02 +Subproject commit a8c93303577178a9b5a66815f031417db7fdeb1f diff --git a/third_party/ss4s b/third_party/ss4s index 03ad710b9..f0e90f0c7 160000 --- a/third_party/ss4s +++ b/third_party/ss4s @@ -1 +1 @@ -Subproject commit 03ad710b9033aa21f83e3c34d6437f11a39bf803 +Subproject commit f0e90f0c7258714f53bdc8d11f7a0abd0b205216 From 89fd54fa74fd63304308e122839bf9141708087c Mon Sep 17 00:00:00 2001 From: Ningyuan Li Date: Thu, 3 Oct 2024 10:11:56 +0900 Subject: [PATCH 2/2] supports host name in addition to IP address --- CMakeLists.txt | 2 +- src/app/backend/pcmanager.h | 6 +- src/app/backend/pcmanager/known_hosts.c | 17 ++-- src/app/backend/pcmanager/pairing.c | 8 +- src/app/backend/pcmanager/worker/manual_add.c | 19 ++--- src/app/backend/pcmanager/worker/update.c | 85 ++++--------------- src/app/backend/pcmanager/worker/worker.h | 4 +- src/app/stream/session_worker.c | 2 +- src/app/stream/session_worker_embedded.c | 2 +- src/app/ui/launcher/add.dialog.c | 11 +-- src/app/ui/launcher/apps.controller.c | 8 +- third_party/commons | 2 +- third_party/ss4s | 2 +- 13 files changed, 54 insertions(+), 114 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ff9f5bfb..b1bbaba8c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -299,7 +299,7 @@ target_link_libraries(moonlight-lib PUBLIC commons-ss4s-modules-list commons-sps target_link_libraries(moonlight-lib PUBLIC commons-logging commons-gamecontrollerdb-updater commons-lazy commons-refcounter commons-executor commons-linked-list commons-wol commons-ini-writer commons-copyfile - commons-sockaddr) + commons-sockaddr commons-host) configure_file(src/app/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h @ONLY) target_include_directories(moonlight-lib PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/src/app/backend/pcmanager.h b/src/app/backend/pcmanager.h index f6af837d9..a4cba18d3 100644 --- a/src/app/backend/pcmanager.h +++ b/src/app/backend/pcmanager.h @@ -7,6 +7,7 @@ #include "libgamestream/client.h" #include "uuidstr.h" #include "sockaddr.h" +#include "host.h" typedef struct app_t app_t; typedef struct pcmanager_t pcmanager_t; @@ -77,7 +78,7 @@ void pcmanager_unregister_listener(pcmanager_t *manager, const pcmanager_listene * @param userdata * @return */ -bool pcmanager_manual_add(pcmanager_t *manager, sockaddr_t *address, pcmanager_callback_t callback, void *userdata); +bool pcmanager_manual_add(pcmanager_t *manager, host_t *host, pcmanager_callback_t callback, void *userdata); /** * @brief Generates a PIN code, and start pairing process. @@ -133,6 +134,5 @@ bool pcmanager_send_wol(pcmanager_t *manager, const uuidstr_t *uuid, pcmanager_c * @param userdata * @return */ -int pcmanager_update_by_ip(worker_context_t *context, const char *ip, uint16_t port, bool force); +int pcmanager_update_by_host(worker_context_t *context, const char *ip, uint16_t port, bool force); -int pcmanager_update_by_addr(worker_context_t *context, sockaddr_t *addr, bool force); \ No newline at end of file diff --git a/src/app/backend/pcmanager/known_hosts.c b/src/app/backend/pcmanager/known_hosts.c index 3b770e41a..60c412e0b 100644 --- a/src/app/backend/pcmanager/known_hosts.c +++ b/src/app/backend/pcmanager/known_hosts.c @@ -80,23 +80,20 @@ void pcmanager_save_known_hosts(pcmanager_t *manager) { if (!cur->server || !cur->known) { continue; } - char address_buf[64] = {0}; const SERVER_DATA *server = cur->server; + host_t *address = host_new(server->serverInfo.address, server->extPort); + if (address == NULL) { + continue; + } ini_write_section(fp, server->uuid); ini_write_string(fp, "mac", server->mac); ini_write_string(fp, "hostname", server->hostname); - struct sockaddr *address = sockaddr_new(); - if (sockaddr_set_ip_str(address, strchr(server->serverInfo.address, ':') ? AF_INET6 : AF_INET, - server->serverInfo.address) != 0) { - free(address); - continue; - } - sockaddr_set_port(address, server->extPort); - sockaddr_to_string(address, address_buf, sizeof(address_buf)); + char address_buf[260] = {0}; + host_to_string(address, address_buf, sizeof(address_buf)); ini_write_string(fp, "address", address_buf); - free(address); + host_free(address); if (!selected_set && cur->selected) { ini_write_bool(fp, "selected", true); diff --git a/src/app/backend/pcmanager/pairing.c b/src/app/backend/pcmanager/pairing.c index 1806a2445..69e43fcde 100644 --- a/src/app/backend/pcmanager/pairing.c +++ b/src/app/backend/pcmanager/pairing.c @@ -28,13 +28,13 @@ bool pcmanager_pair(pcmanager_t *manager, const uuidstr_t *uuid, char *pin, pcma return true; } -bool pcmanager_manual_add(pcmanager_t *manager, sockaddr_t *address, pcmanager_callback_t callback, void *userdata) { - if (address == NULL) { +bool pcmanager_manual_add(pcmanager_t *manager, host_t *host, pcmanager_callback_t callback, void *userdata) { + if (host == NULL) { return false; } worker_context_t *ctx = worker_context_new(manager, NULL, callback, userdata); - ctx->arg1 = address; - pcmanager_worker_queue(manager, worker_add_by_ip, ctx); + ctx->arg1 = host; + pcmanager_worker_queue(manager, worker_add_by_host, ctx); return true; } diff --git a/src/app/backend/pcmanager/worker/manual_add.c b/src/app/backend/pcmanager/worker/manual_add.c index 6bdcaac17..8a38b53d6 100644 --- a/src/app/backend/pcmanager/worker/manual_add.c +++ b/src/app/backend/pcmanager/worker/manual_add.c @@ -1,18 +1,15 @@ +#include #include "worker.h" #include "backend/pcmanager/priv.h" -#include "errors.h" -#include "sockaddr.h" -static int updated_by_addr(worker_context_t *context, bool force); +static int updated_by_host(worker_context_t *context, bool force); -int worker_add_by_ip(worker_context_t *context) { - return updated_by_addr(context, true); +int worker_add_by_host(worker_context_t *context) { + assert(context->arg1 != NULL); + return updated_by_host(context, true); } -int worker_host_discovered(worker_context_t *context) { - return updated_by_addr(context, false); -} - -int updated_by_addr(worker_context_t *context, bool force) { - return pcmanager_update_by_addr(context, context->arg1, force); +int updated_by_host(worker_context_t *context, bool force) { + const host_t *host = context->arg1; + return pcmanager_update_by_host(context, host_get_hostname(host), host_get_port(host), force); } diff --git a/src/app/backend/pcmanager/worker/update.c b/src/app/backend/pcmanager/worker/update.c index b769767b4..24ff3475e 100644 --- a/src/app/backend/pcmanager/worker/update.c +++ b/src/app/backend/pcmanager/worker/update.c @@ -1,7 +1,6 @@ #include "worker.h" #include "backend/pcmanager/priv.h" #include "backend/pcmanager/pclist.h" -#include "backend/pcmanager/listeners.h" #include @@ -11,91 +10,39 @@ #include "logging.h" #include "ui/fatal_error.h" -static void notify_querying(pclist_update_context_t *args); - int worker_host_update(worker_context_t *context) { const pclist_t *node = pcmanager_node(context->manager, &context->uuid); if (node == NULL) { return GS_FAILED; } - return pcmanager_update_by_ip(context, node->server->serverInfo.address, node->server->extPort, true); -} - -int pcmanager_update_by_ip(worker_context_t *context, const char *ip, uint16_t port, bool force) { - return 0; + return pcmanager_update_by_host(context, node->server->serverInfo.address, node->server->extPort, true); } -int pcmanager_update_by_addr(worker_context_t *context, sockaddr_t *addr, bool force) { +int pcmanager_update_by_host(worker_context_t *context, const char *ip, uint16_t port, bool force) { assert(context != NULL); assert(context->manager != NULL); - assert(addr != NULL); + assert(ip != NULL); int ret = 0; + pcmanager_t *manager = context->manager; - // FIXME: Implement this - char *ip_dup = strdup(""); - pclist_t *existing = pclist_find_by_ip(manager, ip_dup); - if (existing) { - SERVER_STATE_ENUM state = existing->state.code; - if (state == SERVER_STATE_QUERYING) { - commons_log_verbose("PCManager", "Skip upsert for querying node. ip: %s", ip_dup); - goto done; - } - if (!force && state & SERVER_STATE_ONLINE) { - goto done; - } - pcmanager_lock(manager); - pclist_update_context_t args = { - .manager = manager, - .uuid = existing->id, - .state = {.code = SERVER_STATE_QUERYING}, - }; - existing->state = args.state; - pcmanager_unlock(manager); - app_bus_post_sync(context->app, (bus_actionfunc) notify_querying, &args); - } - GS_CLIENT client = app_gs_client_new(context->app); - PSERVER_DATA server = serverdata_new(); - ret = gs_get_status(client, server, ip_dup, sockaddr_get_port(addr), app_configuration->unsupported); - ip_dup = NULL; - gs_destroy(client); - if (existing) { - pcmanager_lock(manager); - bool should_remove = ret == GS_OK && !uuidstr_t_equals_s(&existing->id, server->uuid); - pcmanager_unlock(manager); - if (should_remove) { - pclist_remove(manager, &existing->id); - existing = NULL; - } else { - pcmanager_lock(manager); - existing->state.code = SERVER_STATE_NONE; - pcmanager_unlock(manager); - } - } + + // Fetch server info + GS_CLIENT client = app_gs_client_new(manager->app); + SERVER_DATA *server = serverdata_new(); + ret = gs_get_status(client, server, strdup(ip), port, app_configuration->unsupported); if (ret == GS_OK) { - commons_log_info("PCManager", "Finished updating status from %s", server->serverInfo.address); - uuidstr_t uuid; - uuidstr_fromstr(&uuid, server->uuid); SERVER_STATE state = {.code = server->paired ? SERVER_STATE_AVAILABLE : SERVER_STATE_NOT_PAIRED}; - pclist_upsert(manager, &uuid, &state, server); + pclist_upsert(manager, (const uuidstr_t *) server->uuid, &state, server); } else { - const char *gs_error = NULL; - ret = gs_get_error(&gs_error); - commons_log_warn("PCManager", "Error %d while updating status from %s: %s", ret, server->serverInfo.address, - gs_error); - context->error = gs_error != NULL ? strdup(gs_error) : NULL; - if (existing && ret == GS_IO_ERROR) { - SERVER_STATE state = {.code = SERVER_STATE_OFFLINE}; - pclist_upsert(manager, &existing->id, &state, NULL); + const char *error = NULL; + gs_get_error(&error); + if (error) { + context->error = strdup(error); } serverdata_free(server); } - done: - if (ip_dup) { - free(ip_dup); - } + gs_destroy(client); + return ret; } -static void notify_querying(pclist_update_context_t *args) { - pcmanager_listeners_notify(args->manager, &args->uuid, PCMANAGER_NOTIFY_UPDATED); -} \ No newline at end of file diff --git a/src/app/backend/pcmanager/worker/worker.h b/src/app/backend/pcmanager/worker/worker.h index c6881f397..64d8d2b12 100644 --- a/src/app/backend/pcmanager/worker/worker.h +++ b/src/app/backend/pcmanager/worker/worker.h @@ -24,9 +24,7 @@ int worker_quit_app(worker_context_t *context); int worker_wol(worker_context_t *context); -int worker_add_by_ip(worker_context_t *context); - -int worker_host_discovered(worker_context_t *context); +int worker_add_by_host(worker_context_t *context); int worker_host_update(worker_context_t *context); diff --git a/src/app/stream/session_worker.c b/src/app/stream/session_worker.c index 41918001e..1a71b16de 100644 --- a/src/app/stream/session_worker.c +++ b/src/app/stream/session_worker.c @@ -112,7 +112,7 @@ int session_worker(session_t *session) { .app = app, .manager = pcmanager, }; - pcmanager_update_by_ip(&update_ctx, server->serverInfo.address, server->extPort, true); + pcmanager_update_by_host(&update_ctx, server->serverInfo.address, server->extPort, true); // Don't always reset status as error state should be kept session_set_state(session, STREAMING_NONE); diff --git a/src/app/stream/session_worker_embedded.c b/src/app/stream/session_worker_embedded.c index 724f61c15..a8d613de3 100644 --- a/src/app/stream/session_worker_embedded.c +++ b/src/app/stream/session_worker_embedded.c @@ -103,7 +103,7 @@ int session_worker_embedded(session_t *session) { .app = app, .manager = pcmanager, }; - pcmanager_update_by_ip(&update_ctx, server->serverInfo.address, server->extPort, true); + pcmanager_update_by_host(&update_ctx, server->serverInfo.address, server->extPort, true); // Don't always reset status as error state should be kept session_set_state(session, STREAMING_NONE); diff --git a/src/app/ui/launcher/add.dialog.c b/src/app/ui/launcher/add.dialog.c index f4fc70649..c6402ac5f 100644 --- a/src/app/ui/launcher/add.dialog.c +++ b/src/app/ui/launcher/add.dialog.c @@ -99,15 +99,15 @@ static void dialog_cb(lv_event_t *event) { } uint16_t btn = lv_msgbox_get_active_btn(dialog); if (btn == 1) { - sockaddr_t *address = sockaddr_parse(lv_textarea_get_text(controller->input)); - if (!address) { + host_t *host = host_parse(lv_textarea_get_text(controller->input)); + if (!host) { return; } lv_obj_add_state(controller->btns, LV_STATE_DISABLED); lv_obj_add_state(controller->input, LV_STATE_DISABLED); lv_obj_clear_flag(controller->progress, LV_OBJ_FLAG_HIDDEN); lv_obj_add_flag(controller->error, LV_OBJ_FLAG_HIDDEN); - pcmanager_manual_add(pcmanager, address, add_cb, controller); + pcmanager_manual_add(pcmanager, host, add_cb, controller); } else { lv_msgbox_close_async(dialog); } @@ -115,9 +115,10 @@ static void dialog_cb(lv_event_t *event) { static void input_changed_cb(lv_event_t *event) { add_dialog_controller_t *controller = lv_event_get_user_data(event); - sockaddr_t *address = sockaddr_parse(lv_textarea_get_text(controller->input)); - if (address) { + host_t *host = host_parse(lv_textarea_get_text(controller->input)); + if (host) { lv_btnmatrix_clear_btn_ctrl(controller->btns, 1, LV_BTNMATRIX_CTRL_DISABLED); + host_free(host); } else { lv_btnmatrix_set_btn_ctrl(controller->btns, 1, LV_BTNMATRIX_CTRL_DISABLED); } diff --git a/src/app/ui/launcher/apps.controller.c b/src/app/ui/launcher/apps.controller.c index b1405a002..e7c46baff 100644 --- a/src/app/ui/launcher/apps.controller.c +++ b/src/app/ui/launcher/apps.controller.c @@ -319,7 +319,7 @@ static void on_host_updated(const uuidstr_t *uuid, void *userdata) { if (controller != current_instance) { return; } if (!uuidstr_t_equals_t(&controller->uuid, uuid)) { return; } const SERVER_STATE *state = pcmanager_state(pcmanager, uuid); - SDL_assert_release(state != NULL); + assert(state != NULL); if (state->code == SERVER_STATE_AVAILABLE) { apploader_load(controller->apploader); } @@ -346,7 +346,7 @@ static void send_wol_cb(int result, const char *error, const uuidstr_t *uuid, vo if (!controller->base.managed->obj_created) { return; } lv_btnmatrix_clear_btn_ctrl_all(controller->actions, LV_BTNMATRIX_CTRL_DISABLED); const SERVER_STATE *state = pcmanager_state(pcmanager, &controller->uuid); - SDL_assert_release(state != NULL); + assert(state != NULL); if (state->code & SERVER_STATE_ONLINE || result != GS_OK) { return; } pcmanager_request_update(pcmanager, &controller->uuid, host_info_cb, controller); } @@ -360,7 +360,7 @@ static void update_view_state(apps_fragment_t *controller) { lv_obj_t *appload = controller->appload; lv_obj_t *apperror = controller->apperror; const SERVER_STATE *state = pcmanager_state(pcmanager, &controller->uuid); - SDL_assert_release(state != NULL); + assert(state != NULL); switch (state->code) { case SERVER_STATE_NONE: case SERVER_STATE_QUERYING: { @@ -527,7 +527,7 @@ static void appitem_bind(apps_fragment_t *controller, lv_obj_t *item, apploader_ controller->col_width, controller->col_height); lv_label_set_text(holder->title, app->base.name); - SDL_assert_release(controller->node); + assert(controller->node); int current_id = pcmanager_node_current_app(controller->node); if (current_id == app->base.id) { lv_obj_clear_flag(holder->play_indicator, LV_OBJ_FLAG_HIDDEN); diff --git a/third_party/commons b/third_party/commons index a8c933035..e3c8f8535 160000 --- a/third_party/commons +++ b/third_party/commons @@ -1 +1 @@ -Subproject commit a8c93303577178a9b5a66815f031417db7fdeb1f +Subproject commit e3c8f8535f7108bdca51317b1a3f7216ed14acbf diff --git a/third_party/ss4s b/third_party/ss4s index f0e90f0c7..0092bd8c8 160000 --- a/third_party/ss4s +++ b/third_party/ss4s @@ -1 +1 @@ -Subproject commit f0e90f0c7258714f53bdc8d11f7a0abd0b205216 +Subproject commit 0092bd8c84e5d3480ac1104ed63dce607259461b