Table of Contents

Felix Network

Felix Network is a standalone companion library to SquidStd: secure, cross-platform binary mesh networking for .NET — and for a constrained C target such as the ESP32. It lives in its own repository and ships its own NuGet packages under the SquidStd.Felix.* prefix.

What it does

Felix sends AES-256-GCM encrypted, optionally DEFLATE-compressed binary messages between nodes over ENet (reliable UDP), behind a small portable binary frame that a non-.NET target can speak byte-for-byte. On top of that secure node it adds an optional self-forming mesh layer (seed discovery + gossip of the peer list with auto-connect).

  • Secure node — ENet transport, the portable frame (its header is authenticated as AES-GCM additional data), best-effort DEFLATE, and a raw (type, bytes) API.
  • Typed layer — optional Send<T> / On<T> over MemoryPack with a [FelixMessage(id)] attribute mapping message types to wire ids.
  • Mesh — fully-connected, self-healing peer discovery via seeds and portable gossip.
  • Pluggable transport — the encrypted frame is transport-agnostic; ITransport decouples the node from the link (ENet ships; a serial/UART transport carries Felix over a reliable serial or Bluetooth RFCOMM stream without WiFi).
  • Portable — the wire format is documented for non-.NET targets, with a host-testable C core (felix-c) and ESP32 (ESP-IDF) examples proving byte-for-byte C↔.NET parity.

Packages

Package What it is
SquidStd.Felix The secure node: ENet transport, portable frame codec, AES-256-GCM, best-effort DEFLATE, raw SendRaw / OnRaw API.
SquidStd.Felix.MemoryPack Optional typed layer: Send<T> / On<T> with [FelixMessage(id)].
SquidStd.Felix.Mesh Self-forming full mesh: seed discovery + portable gossip of the peer list with auto-connect.
SquidStd.Felix.Transport.Serial A stream-based serial/UART transport (ITransport) to run Felix over a reliable serial link.

Quick start

dotnet add package SquidStd.Felix
using Felix;
using Felix.Data;
using Felix.Interfaces;

var key = new byte[32]; // 32-byte pre-shared key, shared by both ends

using IFelixNode listener = new FelixNode(new FelixOptions { ListenPort = 9000, PreSharedKey = key });
listener.OnRaw(7, (peer, bytes) => Console.WriteLine($"got {bytes.Length} bytes"));
listener.Start();

using IFelixNode client = new FelixNode(new FelixOptions { PreSharedKey = key });
client.Start();
FelixPeer peer = await client.ConnectAsync("127.0.0.1", 9000);
client.SendRaw(peer, type: 7, "hello"u8.ToArray());

Typed messages (SquidStd.Felix.MemoryPack)

[FelixMessage(7)]
[MemoryPackable]
public partial record Ping(long Ts);

listener.On<Ping>((peer, ping) => Console.WriteLine(ping.Ts));
client.Send(peer, new Ping(Environment.TickCount64));

Mesh (SquidStd.Felix.Mesh)

var node = new FelixNode(new FelixOptions { ListenPort = 9000, PreSharedKey = key });
using var mesh = new FelixMesh(node, new MeshOptions
{
    AdvertisedPort = 9000,
    Seeds = [ new MeshSeed("10.0.0.1", 9000) ],
});
mesh.MeshPeerJoined += p => Console.WriteLine($"join {p.Host}:{p.Port}");
mesh.Start();
mesh.Broadcast(type: 7, "hi mesh"u8.ToArray());

ESP32 / C interop

The protocol is portable. The Felix repository ships a portable C core (felix-c: AES-256-GCM over mbedTLS, raw-DEFLATE inflate, the Felix frame, an ENet leaf transport, and a felix_serial UART module) plus host harnesses — all testable without an ESP32, proving byte-for-byte C↔.NET parity. The same C builds on an ESP32 (ESP-IDF), over ENet/WiFi or over UART / Bluetooth Classic SPP.

Learn more

See the Felix Network repository for the protocol specification, the mesh protocol, the transport guide, and the ESP32 / C examples.