using System.Runtime.InteropServices;
using XFESystem.Network;
namespace XFESystem.NativeRuntime.Application.Network;
/// <summary>Lazy network initialization belongs to the caller's network worker, never the desktop UI.</summary>
public static class NativeNetwork
{
static readonly object gate = new();
static Func<uint>? random;
static Ipv4Network? network;
static E1000Device? device;
public static void ConfigureEntropy(Func<uint> random32)
{ ArgumentNullException.ThrowIfNull(random32); lock (gate) random = random32; }
public static Stream OpenTcp(string host, int port, int timeoutMilliseconds = 15000)
{
Func<uint>? entropy = Volatile.Read(ref random);
if (entropy == null) throw new InvalidOperationException("Native TCP requires an explicitly configured strong random source.");
if (timeoutMilliseconds is < 1 or > 120000) throw new ArgumentOutOfRangeException(nameof(timeoutMilliseconds));
long deadline = checked(NativePlatform.Milliseconds() + timeoutMilliseconds);
long remaining = deadline - NativePlatform.Milliseconds();
if (remaining <= 0 || !Monitor.TryEnter(gate, checked((int)remaining))) throw new IOException("Native network ownership timed out.");
try
{
if (NativePlatform.Milliseconds() >= deadline) throw new IOException("Native network ownership timed out.");
if (network == null)
{
var platform = new Platform(entropy);
device = new E1000Device(new Hardware(), platform, deadline);
network = new Ipv4Network(device, platform, Ipv4Configuration.QemuUserNat);
NativePlatform.Write("XFE_NETWORK_CONFIGURATION|Mode|ExplicitStaticQemuUserNat|Address|10.0.2.15|Mask|255.255.255.0|Gateway|10.0.2.2|Dns|10.0.2.3|Dhcp|0\n");
}
return network.OpenTcpUntil(host, port, deadline, timeoutMilliseconds);
}
finally { Monitor.Exit(gate); }
}
sealed class Platform(Func<uint> random32) : INetworkPlatform
{
public long Milliseconds => NativePlatform.Milliseconds();
public void Wait(int milliseconds) => Thread.Sleep(milliseconds);
public uint Random32() => random32();
public void Trace(string text) => NativePlatform.Write(text);
}
sealed unsafe class Hardware : IE1000Hardware
{
const string Library = "xfe_pal";
[DllImport(Library, EntryPoint = "xfe_network_pci_read", CallingConvention = CallingConvention.Cdecl)] static extern uint PciRead(uint bus, uint device, uint function, uint offset);
[DllImport(Library, EntryPoint = "xfe_network_pci_write", CallingConvention = CallingConvention.Cdecl)] static extern int PciWrite(uint bus, uint device, uint function, uint offset, uint value);
[DllImport(Library, EntryPoint = "xfe_network_map_mmio", CallingConvention = CallingConvention.Cdecl)] static extern ulong Map(ulong physical, uint bytes);
[DllImport(Library, EntryPoint = "xfe_mmio_read32", CallingConvention = CallingConvention.Cdecl)] static extern uint MmioRead(ulong address);
[DllImport(Library, EntryPoint = "xfe_mmio_write32", CallingConvention = CallingConvention.Cdecl)] static extern void MmioWrite(ulong address, uint value);
[DllImport(Library, EntryPoint = "xfe_network_dma_allocate", CallingConvention = CallingConvention.Cdecl)] static extern void* Allocate(uint pages, ulong* physical);
[DllImport(Library, EntryPoint = "xfe_network_dma_free", CallingConvention = CallingConvention.Cdecl)] static extern int Free(void* address, uint pages);
public uint ReadPci(uint bus, uint device, uint function, uint offset) => PciRead(bus, device, function, offset);
public void WritePci(uint bus, uint device, uint function, uint offset, uint value)
{ if (PciWrite(bus, device, function, offset, value) != 1) throw new IOException("Invalid PCI configuration write."); }
public nuint MapMmio(ulong physical, uint bytes) => checked((nuint)Map(physical, bytes));
public uint ReadMmio(nuint address) => MmioRead(address);
public void WriteMmio(nuint address, uint value) => MmioWrite(address, value);
public DmaMemory AllocateDma(uint pages)
{ ulong physical = 0; void* address = Allocate(pages, &physical); return new((nuint)address, physical, pages); }
public void FreeDma(DmaMemory memory)
{ if (Free((void*)memory.Address, memory.Pages) != 1) throw new IOException("Native DMA ownership release failed."); }
}
}
using System.Runtime.InteropServices;
using XFESystem.Network;
namespace XFESystem.NativeRuntime.Application.Network;
/// <summary>Lazy network initialization belongs to the caller's network worker, never the desktop UI.</summary>
public static class NativeNetwork
{
static readonly object gate = new();
static Func<uint>? random;
static Ipv4Network? network;
static E1000Device? device;
public static void ConfigureEntropy(Func<uint> random32)
{ ArgumentNullException.ThrowIfNull(random32); lock (gate) random = random32; }
public static Stream OpenTcp(string host, int port, int timeoutMilliseconds = 15000)
{
Func<uint>? entropy = Volatile.Read(ref random);
if (entropy == null) throw new InvalidOperationException("Native TCP requires an explicitly configured strong random source.");
if (timeoutMilliseconds is < 1 or > 120000) throw new ArgumentOutOfRangeException(nameof(timeoutMilliseconds));
long deadline = checked(NativePlatform.Milliseconds() + timeoutMilliseconds);
long remaining = deadline - NativePlatform.Milliseconds();
if (remaining <= 0 || !Monitor.TryEnter(gate, checked((int)remaining))) throw new IOException("Native network ownership timed out.");
try
{
if (NativePlatform.Milliseconds() >= deadline) throw new IOException("Native network ownership timed out.");
if (network == null)
{
var platform = new Platform(entropy);
device = new E1000Device(new Hardware(), platform, deadline);
network = new Ipv4Network(device, platform, Ipv4Configuration.QemuUserNat);
NativePlatform.Write("XFE_NETWORK_CONFIGURATION|Mode|ExplicitStaticQemuUserNat|Address|10.0.2.15|Mask|255.255.255.0|Gateway|10.0.2.2|Dns|10.0.2.3|Dhcp|0\n");
}
return network.OpenTcpUntil(host, port, deadline, timeoutMilliseconds);
}
finally { Monitor.Exit(gate); }
}
sealed class Platform(Func<uint> random32) : INetworkPlatform
{
public long Milliseconds => NativePlatform.Milliseconds();
public void Wait(int milliseconds) => Thread.Sleep(milliseconds);
public uint Random32() => random32();
public void Trace(string text) => NativePlatform.Write(text);
}
sealed unsafe class Hardware : IE1000Hardware
{
const string Library = "xfe_pal";
[DllImport(Library, EntryPoint = "xfe_network_pci_read", CallingConvention = CallingConvention.Cdecl)] static extern uint PciRead(uint bus, uint device, uint function, uint offset);
[DllImport(Library, EntryPoint = "xfe_network_pci_write", CallingConvention = CallingConvention.Cdecl)] static extern int PciWrite(uint bus, uint device, uint function, uint offset, uint value);
[DllImport(Library, EntryPoint = "xfe_network_map_mmio", CallingConvention = CallingConvention.Cdecl)] static extern ulong Map(ulong physical, uint bytes);
[DllImport(Library, EntryPoint = "xfe_mmio_read32", CallingConvention = CallingConvention.Cdecl)] static extern uint MmioRead(ulong address);
[DllImport(Library, EntryPoint = "xfe_mmio_write32", CallingConvention = CallingConvention.Cdecl)] static extern void MmioWrite(ulong address, uint value);
[DllImport(Library, EntryPoint = "xfe_network_dma_allocate", CallingConvention = CallingConvention.Cdecl)] static extern void* Allocate(uint pages, ulong* physical);
[DllImport(Library, EntryPoint = "xfe_network_dma_free", CallingConvention = CallingConvention.Cdecl)] static extern int Free(void* address, uint pages);
public uint ReadPci(uint bus, uint device, uint function, uint offset) => PciRead(bus, device, function, offset);
public void WritePci(uint bus, uint device, uint function, uint offset, uint value)
{ if (PciWrite(bus, device, function, offset, value) != 1) throw new IOException("Invalid PCI configuration write."); }
public nuint MapMmio(ulong physical, uint bytes) => checked((nuint)Map(physical, bytes));
public uint ReadMmio(nuint address) => MmioRead(address);
public void WriteMmio(nuint address, uint value) => MmioWrite(address, value);
public DmaMemory AllocateDma(uint pages)
{ ulong physical = 0; void* address = Allocate(pages, &physical); return new((nuint)address, physical, pages); }
public void FreeDma(DmaMemory memory)
{ if (Free((void*)memory.Address, memory.Pages) != 1) throw new IOException("Native DMA ownership release failed."); }
}
}