diff --git a/dvmusrp/Config.cs b/dvmusrp/Config.cs index 483a524..6a7b468 100644 --- a/dvmusrp/Config.cs +++ b/dvmusrp/Config.cs @@ -1,9 +1,24 @@ -using YamlDotNet.Serialization; -using System.IO; +// SPDX-License-Identifier: AGPL-3.0-only +/** +* Digital Voice Modem - DVMUSRP +* AGPLv3 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / DVMUSRP +* @license AGPLv3 License (https://opensource.org/licenses/AGPL-3.0) +* +* Copyright (C) 2024 Caleb, KO4UYJ +* +*/ + +using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; namespace dvmusrp { + /// + /// Configuration object + /// public class Config { public DvmConfig dvm = new DvmConfig(); @@ -11,6 +26,11 @@ namespace dvmusrp public Config() { /* stub */ } + /// + /// Helper to load YAML config file + /// + /// + /// public static Config Load(string filePath) { var yamlContent = File.ReadAllText(filePath); @@ -21,6 +41,9 @@ namespace dvmusrp } } + /// + /// DVM Configuration object + /// public class DvmConfig { public string ReceiveAddress { get; set; } @@ -32,6 +55,9 @@ namespace dvmusrp public DvmConfig() { /* sub */ } } + /// + /// USRP Configuration object + /// public class UsrpConfig { public string ReceiveAddress { get; set; } diff --git a/dvmusrp/Network.DVM.cs b/dvmusrp/Network.DVM.cs index 0ffe816..c9a2444 100644 --- a/dvmusrp/Network.DVM.cs +++ b/dvmusrp/Network.DVM.cs @@ -1,19 +1,49 @@ -using System.Net.Sockets; +// SPDX-License-Identifier: AGPL-3.0-only +/** +* Digital Voice Modem - DVMUSRP +* AGPLv3 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / DVMUSRP +* @license AGPLv3 License (https://opensource.org/licenses/AGPL-3.0) +* +* Copyright (C) 2024 Caleb, KO4UYJ +* +*/ + +using System.Net.Sockets; using System.Text; namespace dvmusrp { + /// + /// DVM networking class + /// public class NetworkDVM : Network { private NetworkUSRP usrpNetwork; + /// + /// Creates an instance of + /// + /// + /// + /// + /// public NetworkDVM(int receivePort, int sendPort, string receiveAddress, string sendAddress) : base(receivePort, sendPort, receiveAddress, sendAddress) { } + /// + /// Helper to set the instance of + /// + /// public void SetUSRPNetwork(NetworkUSRP usrpNetwork) { this.usrpNetwork = usrpNetwork; } + /// + /// Start the receive loop + /// public override void Start() { Task.Run(async () => @@ -37,28 +67,43 @@ namespace dvmusrp }); } + /// + /// Forward, parse, and convert DVM to USRP + /// + /// private void ForwardToUSRP(byte[] packet) { - byte[] usrpData = new byte[352]; + byte[] usrpData = new byte[352]; // 32 byte header + PCM data byte[] audio = new byte[320]; byte[] usrpHeader = new byte[32]; if (packet.Length != 324) { - Console.WriteLine("DVM meta data is not yet supported"); + Console.WriteLine($"Unexpected DVM data length: {packet.Length}"); return; } + if (packet.Length == 332) + { + Array.Copy(packet, 12, audio, 0, audio.Length); // Skip DVM meta data + } else + { + Array.Copy(packet, 4, audio, 0, audio.Length); // No meta data, just skip PCM length + } + Array.Copy(Encoding.ASCII.GetBytes("USRP"), usrpHeader, 4); Array.Copy(usrpHeader, usrpData, usrpHeader.Length); - Array.Copy(packet, 4, audio, 0, audio.Length); Array.Copy(audio, 0, usrpData, 32, audio.Length); - // Console.WriteLine(Utils.HexDump(usrpData)); + // Console.WriteLine("USRP DATA:\n" + Utils.HexDump(usrpData)); usrpNetwork.SendData(usrpData); } + /// + /// Helper to send data to DVM + /// + /// public void SendData(byte[] data) { Send(data, sendAddress, sendPort); diff --git a/dvmusrp/Network.USRP.cs b/dvmusrp/Network.USRP.cs index e74ae9f..677defc 100644 --- a/dvmusrp/Network.USRP.cs +++ b/dvmusrp/Network.USRP.cs @@ -1,19 +1,48 @@ -using System.Net.Sockets; -using System.Text; +// SPDX-License-Identifier: AGPL-3.0-only +/** +* Digital Voice Modem - DVMUSRP +* AGPLv3 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / DVMUSRP +* @license AGPLv3 License (https://opensource.org/licenses/AGPL-3.0) +* +* Copyright (C) 2024 Caleb, KO4UYJ +* +*/ + +using System.Net.Sockets; namespace dvmusrp { + /// + /// USRP networking class + /// public class NetworkUSRP : Network { private NetworkDVM dvmNetwork; + /// + /// Creates an instance of + /// + /// + /// + /// + /// public NetworkUSRP(int receivePort, int sendPort, string receiveAddress, string sendAddress) : base(receivePort, sendPort, receiveAddress, sendAddress) { } + /// + /// Helper to set the instance + /// + /// public void SetDVMNetwork(NetworkDVM dvmNetwork) { this.dvmNetwork = dvmNetwork; } + /// + /// Start the receive loop + /// public override void Start() { Task.Run(async () => @@ -37,10 +66,14 @@ namespace dvmusrp }); } + /// + /// Forward, parse, and convert USRP to DVM + /// + /// private void ForwardToDVM(byte[] packet) { - // TODO: Parse meta data for possible DVM use - byte[] audio = new byte[324]; + // TODO: Parse USRP header for possible DVM use + byte[] audio = new byte[324]; // PCM length + PCM data byte[] usrpHeader = new byte[32]; Array.Copy(packet, usrpHeader, usrpHeader.Length); @@ -62,6 +95,10 @@ namespace dvmusrp dvmNetwork.SendData(audio); } + /// + /// Helper to send data to USRP + /// + /// public void SendData(byte[] data) { Send(data, sendAddress, sendPort); diff --git a/dvmusrp/Network.cs b/dvmusrp/Network.cs index b6a30ea..fc99863 100644 --- a/dvmusrp/Network.cs +++ b/dvmusrp/Network.cs @@ -1,12 +1,23 @@ -using System; -using System.Collections.Generic; -using System.Linq; +// SPDX-License-Identifier: AGPL-3.0-only +/** +* Digital Voice Modem - DVMUSRP +* AGPLv3 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / DVMUSRP +* @license AGPLv3 License (https://opensource.org/licenses/AGPL-3.0) +* +* Copyright (C) 2024 Caleb, KO4UYJ +* +*/ + using System.Net.Sockets; -using System.Text; -using System.Threading.Tasks; namespace dvmusrp { + /// + /// Base networking class for UDP communications + /// public abstract class Network { protected int receivePort; @@ -17,6 +28,13 @@ namespace dvmusrp protected UdpClient udpClient; + /// + /// Creatse an instance of + /// + /// + /// + /// + /// protected Network(int receivePort, int sendPort, string receiveAddress, string sendAddress) { this.receivePort = receivePort; @@ -25,8 +43,17 @@ namespace dvmusrp this.sendAddress = sendAddress; } + /// + /// Start the receive loop + /// public abstract void Start(); + /// + /// Helper to send data + /// + /// + /// + /// protected void Send(byte[] data, string destinationIp, int destinationPort) { using (var client = new UdpClient()) diff --git a/dvmusrp/Program.cs b/dvmusrp/Program.cs index 7d55f62..2dc77e7 100644 --- a/dvmusrp/Program.cs +++ b/dvmusrp/Program.cs @@ -1,7 +1,28 @@ -using dvmusrp; +// SPDX-License-Identifier: AGPL-3.0-only +/** +* Digital Voice Modem - DVMUSRP +* AGPLv3 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / DVMUSRP +* @license AGPLv3 License (https://opensource.org/licenses/AGPL-3.0) +* +* Copyright (C) 2024 Caleb, KO4UYJ +* +*/ +using dvmusrp; + +/// +/// +/// internal class Program { + /// + /// Application entry point + /// + /// + /// static async Task Main(string[] args) { var configFilePath = GetConfigFilePath(args); @@ -12,10 +33,10 @@ internal class Program return; } - var config = Config.Load(configFilePath); + Config config = Config.Load(configFilePath); - var usrpNetwork = new NetworkUSRP(config.usrp.ReceivePort, config.usrp.SendPort, config.usrp.ReceiveAddress, config.usrp.SendAddress); - var dvmNetwork = new NetworkDVM(config.dvm.ReceivePort, config.dvm.SendPort, config.dvm.ReceiveAddress, config.dvm.ReceiveAddress); + NetworkUSRP usrpNetwork = new NetworkUSRP(config.usrp.ReceivePort, config.usrp.SendPort, config.usrp.ReceiveAddress, config.usrp.SendAddress); + NetworkDVM dvmNetwork = new NetworkDVM(config.dvm.ReceivePort, config.dvm.SendPort, config.dvm.ReceiveAddress, config.dvm.ReceiveAddress); usrpNetwork.SetDVMNetwork(dvmNetwork); dvmNetwork.SetUSRPNetwork(usrpNetwork); @@ -23,9 +44,26 @@ internal class Program usrpNetwork.Start(); dvmNetwork.Start(); + Console.WriteLine("USRP: "); + Console.WriteLine($" Receive Port: {config.usrp.ReceivePort}"); + Console.WriteLine($" Send Port: {config.usrp.SendPort}"); + Console.WriteLine($" Receive Address: {config.usrp.ReceiveAddress}"); + Console.WriteLine($" Send Address: {config.usrp.SendAddress}"); + Console.WriteLine("DVM: "); + Console.WriteLine($" Receive Port: {config.dvm.ReceivePort}"); + Console.WriteLine($" Send Port: {config.dvm.SendPort}"); + Console.WriteLine($" Receive Address: {config.dvm.ReceiveAddress}"); + Console.WriteLine($" Send Address: {config.dvm.SendAddress}"); + Console.WriteLine("DVMUSRP Started"); + await Task.Delay(Timeout.Infinite); } + /// + /// Helper to psrse args + /// + /// + /// static string GetConfigFilePath(string[] args) { for (int i = 0; i < args.Length; i++) diff --git a/dvmusrp/config.example.yml b/dvmusrp/config.example.yml index cfeda01..0fca2f2 100644 --- a/dvmusrp/config.example.yml +++ b/dvmusrp/config.example.yml @@ -1,11 +1,23 @@ +# DVMBridge UDP configuration dvm: + # Receive address receiveAddress: 127.0.0.1 + # Receive port receivePort: 33000 + + # Send port sendPort: 35000 + # Send address sendAddress: 127.0.0.1 - + +# USRP UDP Configuration usrp: + # Receive address receiveAddress: 0.0.0.0 + # Receive port receivePort: 34001 + + # Send port sendPort: 32001 + # Send address sendAddress: 192.168.198.131 \ No newline at end of file