// Copyright (C) 2026 SharpEmu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later using System; using System.Collections.Concurrent; using System.Threading; using SharpEmu.HLE; namespace SharpEmu.Libs.Network; public static class Http2Exports { private const int Http2ErrorInvalidId = unchecked((int)0x80436004); private const int Http2ErrorInvalidArgument = unchecked((int)0x80436016); private static readonly ConcurrentDictionary _contexts = new(); private static int _nextContextId; private sealed record Http2Context(int NetId, int SslId, ulong PoolSize, int MaxRequests); [SysAbiExport( Nid = "3JCe3lCbQ8A", ExportName = "sceHttp2Init", Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libSceHttp2")] public static int Http2Init(CpuContext ctx) { var netId = unchecked((int)ctx[CpuRegister.Rdi]); var sslId = unchecked((int)ctx[CpuRegister.Rsi]); var poolSize = ctx[CpuRegister.Rdx]; var maxRequests = unchecked((int)ctx[CpuRegister.Rcx]); if (poolSize == 0 || maxRequests <= 0) { return SetReturn(ctx, Http2ErrorInvalidArgument); } var id = Interlocked.Increment(ref _nextContextId); _contexts[id] = new Http2Context(netId, sslId, poolSize, maxRequests); TraceHttp2("init", id, unchecked((ulong)netId), unchecked((ulong)sslId), poolSize, unchecked((ulong)maxRequests)); ctx[CpuRegister.Rax] = unchecked((ulong)id); return (int)OrbisGen2Result.ORBIS_GEN2_OK; } [SysAbiExport( Nid = "YiBUtz-pGkc", ExportName = "sceHttp2Term", Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libSceHttp2")] public static int Http2Term(CpuContext ctx) { var id = unchecked((int)ctx[CpuRegister.Rdi]); if (!_contexts.TryRemove(id, out _)) { return SetReturn(ctx, Http2ErrorInvalidId); } TraceHttp2("term", id, 0, 0, 0, 0); return SetReturn(ctx, 0); } private static int SetReturn(CpuContext ctx, int result) { ctx[CpuRegister.Rax] = unchecked((ulong)result); return result; } private static void TraceHttp2(string operation, int id, ulong arg0, ulong arg1, ulong arg2, ulong arg3) { if (!string.Equals(Environment.GetEnvironmentVariable("SHARPEMU_LOG_HTTP2"), "1", StringComparison.Ordinal)) { return; } Console.Error.WriteLine( $"[LOADER][TRACE] http2.{operation} id={id} arg0=0x{arg0:X16} arg1=0x{arg1:X16} arg2=0x{arg2:X16} arg3=0x{arg3:X16}"); } }