diff --git a/orbisrpc/daemon.c b/orbisrpc/daemon.c index dbba98e..72bef1f 100644 --- a/orbisrpc/daemon.c +++ b/orbisrpc/daemon.c @@ -317,14 +317,19 @@ int daemon_run(const char *fixed_game_name){ log_msg("health: boot marked healthy"); } char name[128] = ""; + int scan_unknown = 0; if(fixed_game_name){ strncpy(name, fixed_game_name, sizeof name-1); name[sizeof name-1] = 0; }else{ /* detect_current_game already checks foreground-active - * internally; don't double-call it. */ - if(detect_current_game(name, sizeof name, NULL, 0) != 0) + * internally; don't double-call it. -2 means the scan + * itself failed: hold position, touch nothing. */ + scan_unknown = (detect_current_game(name, sizeof name, NULL, 0) == -2); + if(scan_unknown){ + log_dbg("detect scan failed; holding"); name[0] = 0; + } } if(name[0]){ @@ -376,7 +381,7 @@ int daemon_run(const char *fixed_game_name){ active = 1; need_post = 0; } } - }else if(active){ + }else if(active && !scan_unknown){ cand_title[0] = 0; cand_hits = 0; if(++miss_hits >= 2){ @@ -390,7 +395,7 @@ int daemon_run(const char *fixed_game_name){ last[0]=0; sess_tid[0]=0; active=0; started=0; home_posted = 0; } - } else if(!home_posted){ + } else if(!home_posted && !scan_unknown){ /* Home screen support: no game running. Post a timerless * home presence once (instead of bare online), clear it * the moment a game commits. */ diff --git a/orbisrpc/detect.c b/orbisrpc/detect.c index d403967..b13cc14 100644 --- a/orbisrpc/detect.c +++ b/orbisrpc/detect.c @@ -56,14 +56,14 @@ static int is_title_prefix(const char *n); static int proc_has_eboot(void){ int mib[4] = { 1, 14, 8, 0 }; size_t sz = 0; - if(sysctl(mib, 4, NULL, &sz, NULL, 0) != 0) return 0; + if(sysctl(mib, 4, NULL, &sz, NULL, 0) != 0) return -1; static unsigned char buf[256*1024]; - if(sz > sizeof buf) return 0; - if(sysctl(mib, 4, buf, &sz, NULL, 0) != 0) return 0; + if(sz > sizeof buf) return -1; + if(sysctl(mib, 4, buf, &sz, NULL, 0) != 0) return -1; size_t off = 0; while(off + 4 <= sz){ int recsz = *(int *)(buf + off); - if(recsz <= 0 || off + (size_t)recsz > sz) break; + if(recsz <= 0 || off + (size_t)recsz > sz) return -1; if(recsz >= 479 && !memcmp(buf + off + 447, "eboot.bin", 10)) return 1; off += (size_t)recsz; @@ -394,7 +394,14 @@ int detect_current_game(char *out_name, size_t cap, char *out_path, size_t p_cap if(!out_name || cap==0) return -1; out_name[0] = 0; if(out_path && p_cap) out_path[0] = 0; - if(!detect_foreground_active()) return -1; + { + /* Tri-state foreground: 1 game, 0 none, -1 scan failed (unknown). + * Unknown must NOT count as disappearance — it means "keep whatever + * we had", never a transition. */ + int fg = detect_foreground_active(); + if(fg < 0) return -2; + if(!fg) return -1; + } char titleId[16]=""; int named=0, have_tid=0; #ifdef ORBISRPC_SDK_PAYLOAD /* Spawned processes see no ShellCoreUtil/UserService and /data/app is diff --git a/orbisrpc/detect.h b/orbisrpc/detect.h index ffa9dc9..d15af67 100644 --- a/orbisrpc/detect.h +++ b/orbisrpc/detect.h @@ -6,7 +6,8 @@ * Returns -1 when no game is active or the arguments are invalid. * out_path is optional and receives the per-title cache path when provided. */ int detect_current_game(char *out_name, size_t cap, char *out_path, size_t p_cap); -/* Returns 1 if a foreground user app is running, otherwise 0. */ +/* Returns 1 if a foreground user app is running, 0 if definitely none, + * -1 if the scan itself failed (unknown: keep previous state). */ int detect_foreground_active(void); /* Resolve a display name for a KNOWN title id (plugin mode). */ int detect_name_for_title(const char *titleId, char *out_name, size_t cap); diff --git a/orbisrpc/log.c b/orbisrpc/log.c index 1e0e22c..5b77c45 100644 --- a/orbisrpc/log.c +++ b/orbisrpc/log.c @@ -17,6 +17,7 @@ static int g_klog = -1; static volatile int g_log_lock = 0; static volatile int g_debug = 0; void log_set_debug(int on){ g_debug = on ? 1 : 0; } +int log_is_debug(void){ return g_debug; } static void log_lock(void){ while(__sync_lock_test_and_set(&g_log_lock, 1)) usleep(1000); } static void log_unlock(void){ __sync_lock_release(&g_log_lock); } diff --git a/orbisrpc/log.h b/orbisrpc/log.h index b22fc6e..593cda8 100644 --- a/orbisrpc/log.h +++ b/orbisrpc/log.h @@ -8,6 +8,7 @@ void log_msg(const char *fmt, ...); /* Debug logging: compiled in, emitted only when log_set_debug(1) is on. * Zero overhead otherwise. For per-poll detail — never for secrets. */ void log_set_debug(int on); +int log_is_debug(void); void log_dbg(const char *fmt, ...); void log_close(void); -#endif \ No newline at end of file +#endif diff --git a/orbisrpc/tls.c b/orbisrpc/tls.c index 2e56a97..4bfd024 100644 --- a/orbisrpc/tls.c +++ b/orbisrpc/tls.c @@ -37,7 +37,10 @@ * code into the exact failing step. */ static void tls_mbedtls_dbg(void *ctx, int level, const char *file, int line, const char *str){ - (void)ctx; (void)level; + (void)ctx; + /* mbedTLS chat (levels 1-3) only in debug mode: at threshold 3 every + * TLS record logs a line, which is pure I/O load in production. */ + if(level > 0 && !log_is_debug()) return; const char *base = strrchr(file, '/'); base = base ? base + 1 : file; size_t n = strlen(str);