Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rhp2lib-net

A C# client library (multi-targets .NET 8 and .NET 10), test harness, and command-line toolkit for RHPv2 — the JSON-over-TCP "Remote Host Protocol" used by XRouter to expose its multi-protocol packet engine to applications.

📖 Full documentation: https://rhp2lib.pages.dev/ 📦 Install: dotnet add package RhpV2.Client  ·  self-contained rhp CLI binaries for Linux / Windows / macOS at GitHub Releases.

The protocol is described in PWP-0222 and PWP-0245 (Paula Dowie, G8PZT et al., June 2023).

Layout

src/RhpV2.Client/                    reusable client library + in-process mock server
src/RhpV2.Tools/                     `rhp` CLI (chat, mon, send, probe, serve)
tests/RhpV2.Client.Tests/            xunit suite (framing, codecs, mock-driven)
tests/RhpV2.Client.IntegrationTests/ Testcontainers suite — drives ghcr.io/packethacking/xrouter

The library

using RhpV2.Client;
using RhpV2.Client.Protocol;

await using var rhp = await RhpClient.ConnectAsync("xrouter.local");
await rhp.AuthenticateAsync("g8pzt", "secret");

rhp.Received += (_, e) =>
    Console.WriteLine($"<- {e.Message.Data}");

var handle = await rhp.OpenAsync(
    ProtocolFamily.Ax25, SocketMode.Stream,
    port: "1", local: "G8PZT", remote: "GB7PZT",
    flags: OpenFlags.Active);

await rhp.SendOnHandleAsync(handle, "hello\r");

Highlights:

  • Length-prefixed (2-byte big-endian) framing, exact to spec.
  • Strongly-typed messages (AuthMessage, OpenMessage, RecvMessage, …).
  • Async request/reply correlation via auto-assigned id field.
  • Asynchronous notifications surfaced as events (Received, Accepted, StatusChanged, Closed, UnknownReceived, Disconnected).
  • Tolerates spec quirks (errCode on AUTHREPLY, ConnectReply PascalCase).
  • Forward-compatible: unknown message types arrive as UnknownMessage.

CLI (rhp)

rhp probe   --host xrouter.local --port 9000 --user g8pzt --pass …
rhp chat    --pfam ax25 --radio 1 --local G8PZT --remote GB7PZT
rhp mon     --pfam ax25 --radio 1                    # TRACE-mode monitor
rhp send    --pfam ax25 --radio 1 --local G8PZT --remote G8PZT-1 "Hi"
rhp serve   --port 9000                              # local mock for dev

All commands share a common --host/--port/--user/--pass vocabulary.

Tests / harness

The MockRhpServer (in RhpV2.Client.Testing) is shipped with the library itself so downstream applications can write integration tests without spinning up a real XRouter:

await using var server = new MockRhpServer();
server.Start();
await using var client =
    await RhpClient.ConnectAsync("127.0.0.1", server.Endpoint.Port);
// ... drive any sequence you like; assert against server.ReceivedFrames.

The same mock backs rhp serve, so the CLI doubles as a self-test driver.

Build & test

dotnet build
dotnet test
  • Unit suite (49 tests; runs everywhere): framing, codec, polymorphic JSON dispatch, correlated request/reply, server-pushed notifications, transport teardown.
  • Integration suite (36 tests; requires Docker): pulls ghcr.io/packethacking/xrouter via Testcontainers and pins the client against the real RHP server. A two-container fixture links the nodes by AXUDP and seeds the NetRom routing table so routing works on first boot. Coverage spans: AX.25 stream connect / send / recv / close (real SABM/UA/I/RR); passive listener accepting an inbound peer connection; peer-initiated close firing Closed; TRACE-mode frame capture (frametype, srce/dest, ctrl, pid, ptcl); RAW-mode complete on-the-wire frames; DGRAM (UI frame) sendto with binary-byte round-trip; NetRom stream connect through to the peer's command processor; pfam=inet stream GET to xrouter's HTTP server with server-initiated close; seqpkt / custom socket allocation; connect-to-unreachable lifecycle (FRACK retries → status=0 → close); BUSY flag in sendReply.status on large writes; Duplicate socket on duplicate listen; handle namespace global across connections. The fixture fails loudly if Docker isn't reachable — there's no silent skip, so a green run actually means the integration paths were exercised.

About

C# / .NET 10 client library, mock server, and rhp CLI for the XRouter RHPv2 protocol (PWP-0222/0245)

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages