Add CW keying, function key messages and the documentation

The function keys send through cwdaemon or a WinKeyer, with N1MM's message
macros. Escape stops sending.

Settings are read with the reflection serializer rather than a generated one:
the generated one hands back null for every property the file leaves out
instead of the value the property is declared with, which crashed the program
the first time a new setting was added.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Erik
2026-08-27 11:23:30 +00:00
parent d96cbe146b
commit f5aa77ece3
25 changed files with 1002 additions and 26 deletions

View File

@@ -0,0 +1,52 @@
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace Nonemm.Keying.Tests;
/// The sender is tested against a socket that speaks cwdaemon's side of the
/// protocol, so what goes on the wire is what is asserted.
public class CwDaemonSenderTests : IDisposable
{
private readonly UdpClient daemon = new(new IPEndPoint(IPAddress.Loopback, 0));
private int Port => ((IPEndPoint)daemon.Client.LocalEndPoint!).Port;
public void Dispose()
{
daemon.Dispose();
GC.SuppressFinalize(this);
}
private async Task<byte[]> NextDatagram(Func<Task> send)
{
Task<UdpReceiveResult> receiving = daemon.ReceiveAsync();
await send();
UdpReceiveResult received = await receiving.WaitAsync(TimeSpan.FromSeconds(5));
return received.Buffer;
}
[Fact]
public async Task TextGoesOutInUpperCase()
{
using CwDaemonSender sender = new("127.0.0.1", Port);
byte[] sent = await NextDatagram(() => sender.SendAsync("cq test de dl1abc"));
Assert.Equal("CQ TEST DE DL1ABC", Encoding.ASCII.GetString(sent));
}
[Fact]
public async Task AbortIsTheEscapeFourCommand()
{
using CwDaemonSender sender = new("127.0.0.1", Port);
byte[] sent = await NextDatagram(() => sender.AbortAsync());
Assert.Equal([0x1B, (byte)'4'], sent);
}
[Fact]
public async Task SpeedIsTheEscapeTwoCommand()
{
using CwDaemonSender sender = new("127.0.0.1", Port);
byte[] sent = await NextDatagram(() => sender.SetSpeedAsync(32));
Assert.Equal([0x1B, (byte)'2', (byte)'3', (byte)'2'], sent);
}
}

View File

@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Nonemm.Keying\Nonemm.Keying.csproj" />
</ItemGroup>
</Project>