using Nonemm.Core; namespace Nonemm.Network; /// One computer on the network, as far as this one can tell. The network status /// window shows a row per station and these are its columns. /// /// Everything here is what the station last said, with the time it said it. /// Nothing is asked for on demand: the beacons and the messages carry it, and a /// station that has gone quiet keeps the last thing it said with an older /// `LastHeardUtc`, which is how the window shows it as missing rather than /// blank. public sealed class NetworkedStation { public NetworkedStation(string computerName, string address, int port) { ComputerName = computerName; Address = address; Port = port; // now is when it was heard of, whether that was a beacon or the // operator naming it. Left at nothing, `StationLink.Forget` reads a // station as having been quiet since the beginning of time and drops // the connection to it the moment it is opened LastHeardUtc = DateTime.UtcNow; } /// The name in every message the station sends, and what a contact from it /// is stamped with. N1MM uses the computer's own network name. public string ComputerName { get; } public string Address { get; internal set; } public int Port { get; internal set; } /// Which station of the entry this is. N1MM numbers them so a contact can /// say which position made it; the number arrives in `IAM`. public int StationNumber { get; internal set; } /// The version the station broadcast. N1MM refuses to talk to a station /// whose version is not its own, so a mismatch here is why nothing works. public string Version { get; internal set; } = ""; public string Operator { get; internal set; } = ""; public string ContestName { get; internal set; } = ""; /// Where the station is, from the last `FREQ` or `STATUS` it sent. public Frequency Frequency { get; internal set; } public Mode? Mode { get; internal set; } public Band? Band => Bands.ForFrequency(Frequency); /// Contacts an hour over this station's last ten and last hundred /// contacts, from its `STATUS` message. The two rate columns of the /// network status window. public int Last10 { get; internal set; } public int Last100 { get; internal set; } /// True while the station is running rather than searching. In a /// multi-single entry this is the run station. public bool IsRunning { get; internal set; } public bool IsTransmitting { get; internal set; } /// What the station is sending, which is the caption of the function key /// it pressed. N1MM shows it in the `Msg` column while the station is /// transmitting and clears it when the station stops. public string Message { get; internal set; } = ""; /// True when the station is the second run radio of a two-radio position. /// N1MM shows Run1 or Run2/Mult in its `R/M` column. public bool IsRun2 { get; internal set; } /// A frequency this station has passed, from `PASSFREQ`. N1MM sends the /// frequency alone: which station is on it is what the operator is about to /// say over the talk line. public Frequency PassFrequency { get; internal set; } /// When anything last arrived from the station, and what it was. The window /// shows both: a station whose last message is minutes old is not there any /// more, whatever its connection says. public DateTime LastHeardUtc { get; internal set; } public string LastMessage { get; internal set; } = ""; /// How many messages have gone each way since the program started. N1MM /// shows the same two numbers, and a Send that climbs while Read stands /// still is a station that is not listening. public int Sent { get; internal set; } public int Read { get; internal set; } /// True while a connection to the station is open. It is not the same as /// the station being there: the connection can stand for a while after the /// other program has stopped. public bool IsConnected { get; internal set; } /// How long the last echo took to come back, or null when none has. public TimeSpan? EchoTime { get; internal set; } /// This computer, which is in the list as well. N1MM shows it too, so an /// operator can read its own station number and version off the same /// window. public bool IsMine { get; internal init; } /// What a resync with this station is doing, and how it went. N1MM counts /// the blocks an hour at a time, which is why its columns say hours: `Ok` /// is a block both ends already agreed on, `Fixed` is one this station was /// told to drop and was sent again, `Failed` is one that still did not /// agree after being sent. public bool IsResyncing { get; internal set; } public string ResyncStatus { get; internal set; } = ""; /// Set when this station said it is ahead of us before there was a /// connection to answer over. The resync starts as soon as one opens. internal DateTime? ResyncWanted { get; set; } public int HoursOk { get; internal set; } public int HoursFixed { get; internal set; } public int HoursFailed { get; internal set; } /// Set when the operator closed the connection by hand. The beacons keep /// arriving and the station stays in the list, but nothing opens a /// connection to it again until the operator asks for one. public bool IsReconnectPrevented { get; internal set; } /// Set when the station broadcast a version that is not ours. N1MM turns /// such a station away, so this program says why rather than failing to /// connect for no visible reason. public string Refused { get; internal set; } = ""; }