Skip to content
Open
6 changes: 4 additions & 2 deletions .github/workflows/sonarcloud.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ on:

permissions:
pull-requests: read # allows SonarCloud to decorate PRs with analysis results
contents: read


jobs:
sonar-check:
Expand All @@ -56,8 +58,8 @@ jobs:
dotnet tool install --global dotnet-sonarscanner
echo "$env:USERPROFILE\.dotnet\tools" >> $env:GITHUB_PATH
dotnet sonarscanner begin `
/k:"ppanchen_NetSdrClient" `
/o:"ppanchen" `
/k:"slavik22_ReengineeringCourse" `
/o:"slavik22" `
/d:sonar.token="${{ secrets.SONAR_TOKEN }}" `
/d:sonar.cs.opencover.reportsPaths="**/coverage.xml" `
/d:sonar.cpd.cs.minimumTokens=40 `
Expand Down
10 changes: 2 additions & 8 deletions NetSdrClientApp/Messages/NetSdrMessageHelper.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.PortableExecutable;
using System.Text;
using System.Threading.Tasks;


namespace NetSdrClientApp.Messages
{
//TODO: analyze possible use of [StructLayout] for better performance and readability
Expand Down Expand Up @@ -111,7 +105,7 @@ public static IEnumerable<int> GetSamples(ushort sampleSize, byte[] body)
sampleSize /= 8; //to bytes
if (sampleSize > 4)
{
throw new ArgumentOutOfRangeException();
throw new ArgumentOutOfRangeException(nameof(sampleSize), sampleSize, "Sample size must be 8, 16, 24, or 32 bits.");
}

var bodyEnumerable = body as IEnumerable<byte>;
Expand Down
20 changes: 6 additions & 14 deletions NetSdrClientApp/NetSdrClient.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
using NetSdrClientApp.Messages;
using NetSdrClientApp.Networking;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
using static NetSdrClientApp.Messages.NetSdrMessageHelper;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace NetSdrClientApp
{
public class NetSdrClient
{
private ITcpClient _tcpClient;
private IUdpClient _udpClient;
private readonly ITcpClient _tcpClient;
private readonly IUdpClient _udpClient;

public bool IQStarted { get; set; }

Expand Down Expand Up @@ -66,7 +58,7 @@ public async Task StartIQAsync()
return;
}

; var iqDataMode = (byte)0x80;
var iqDataMode = (byte)0x80;
var start = (byte)0x02;
var fifo16bitCaptureMode = (byte)0x01;
var n = (byte)1;
Expand Down Expand Up @@ -116,7 +108,7 @@ public async Task ChangeFrequencyAsync(long hz, int channel)

private void _udpClient_MessageReceived(object? sender, byte[] e)
{
NetSdrMessageHelper.TranslateMessage(e, out MsgTypes type, out ControlItemCodes code, out ushort sequenceNum, out byte[] body);
NetSdrMessageHelper.TranslateMessage(e, out _, out _, out _, out byte[] body);
var samples = NetSdrMessageHelper.GetSamples(16, body);

Console.WriteLine($"Samples recieved: " + body.Select(b => Convert.ToString(b, toBase: 16)).Aggregate((l, r) => $"{l} {r}"));
Expand All @@ -131,9 +123,9 @@ private void _udpClient_MessageReceived(object? sender, byte[] e)
}
}

private TaskCompletionSource<byte[]> responseTaskSource;
private TaskCompletionSource<byte[]>? responseTaskSource;

private async Task<byte[]> SendTcpRequest(byte[] msg)
private async Task<byte[]?> SendTcpRequest(byte[] msg)
{
if (!_tcpClient.Connected)
{
Expand Down
9 changes: 1 addition & 8 deletions NetSdrClientApp/Networking/ITcpClient.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace NetSdrClientApp.Networking
namespace NetSdrClientApp.Networking
{
public interface ITcpClient
{
Expand Down
17 changes: 10 additions & 7 deletions NetSdrClientApp/Networking/IUdpClient.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@

public interface IUdpClient

namespace NetSdrClientApp.Networking
{
event EventHandler<byte[]>? MessageReceived;
public interface IUdpClient
{
event EventHandler<byte[]>? MessageReceived;

Task StartListeningAsync();
Task StartListeningAsync();

void StopListening();
void Exit();
}
void StopListening();
void Exit();
}
}
18 changes: 6 additions & 12 deletions NetSdrClientApp/Networking/TcpClientWrapper.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Sockets;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace NetSdrClientApp.Networking
{
public class TcpClientWrapper : ITcpClient
{
private string _host;
private int _port;
private readonly string _host;
private readonly int _port;
private TcpClient? _tcpClient;
private NetworkStream? _stream;
private CancellationTokenSource _cts;
private CancellationTokenSource? _cts;

public bool Connected => _tcpClient != null && _tcpClient.Connected && _stream != null;

Expand Down Expand Up @@ -57,6 +50,7 @@ public void Disconnect()
if (Connected)
{
_cts?.Cancel();
_cts?.Dispose();
_stream?.Close();
_tcpClient?.Close();

Expand Down Expand Up @@ -117,7 +111,7 @@ private async Task StartListeningAsync()
}
}
}
catch (OperationCanceledException ex)
catch (OperationCanceledException)
{
//empty
}
Expand Down
122 changes: 61 additions & 61 deletions NetSdrClientApp/Networking/UdpClientWrapper.cs
Original file line number Diff line number Diff line change
@@ -1,85 +1,85 @@
using System;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

public class UdpClientWrapper : IUdpClient
namespace NetSdrClientApp.Networking
{
private readonly IPEndPoint _localEndPoint;
private CancellationTokenSource? _cts;
private UdpClient? _udpClient;

public event EventHandler<byte[]>? MessageReceived;

public UdpClientWrapper(int port)
public class UdpClientWrapper : IUdpClient
{
_localEndPoint = new IPEndPoint(IPAddress.Any, port);
}
private readonly IPEndPoint _localEndPoint;
private CancellationTokenSource? _cts;
private UdpClient? _udpClient;

public async Task StartListeningAsync()
{
_cts = new CancellationTokenSource();
Console.WriteLine("Start listening for UDP messages...");
public event EventHandler<byte[]>? MessageReceived;

try
public UdpClientWrapper(int port)
{
_udpClient = new UdpClient(_localEndPoint);
while (!_cts.Token.IsCancellationRequested)
_localEndPoint = new IPEndPoint(IPAddress.Any, port);
}

public async Task StartListeningAsync()
{
_cts = new CancellationTokenSource();
Console.WriteLine("Start listening for UDP messages...");

try
{
UdpReceiveResult result = await _udpClient.ReceiveAsync(_cts.Token);
MessageReceived?.Invoke(this, result.Buffer);
_udpClient = new UdpClient(_localEndPoint);
while (!_cts.Token.IsCancellationRequested)
{
UdpReceiveResult result = await _udpClient.ReceiveAsync(_cts.Token);
MessageReceived?.Invoke(this, result.Buffer);

Console.WriteLine($"Received from {result.RemoteEndPoint}");
Console.WriteLine($"Received from {result.RemoteEndPoint}");
}
}
catch (OperationCanceledException)
{
//empty
}
catch (Exception ex)
{
Console.WriteLine($"Error receiving message: {ex.Message}");
}
}
catch (OperationCanceledException ex)
{
//empty
}
catch (Exception ex)
{
Console.WriteLine($"Error receiving message: {ex.Message}");
}
}

public void StopListening()
{
try
public void StopListening()
{
_cts?.Cancel();
_udpClient?.Close();
Console.WriteLine("Stopped listening for UDP messages.");
}
catch (Exception ex)
{
Console.WriteLine($"Error while stopping: {ex.Message}");
try
{
_cts?.Cancel();
_cts?.Dispose();
_udpClient?.Close();
Console.WriteLine("Stopped listening for UDP messages.");
}
catch (Exception ex)
{
Console.WriteLine($"Error while stopping: {ex.Message}");
}
}
}

public void Exit()
{
try
{
_cts?.Cancel();
_udpClient?.Close();
Console.WriteLine("Stopped listening for UDP messages.");
}
catch (Exception ex)
public void Exit()
{
Console.WriteLine($"Error while stopping: {ex.Message}");
try
{
_cts?.Cancel();
_udpClient?.Close();
Console.WriteLine("Stopped listening for UDP messages.");
}
catch (Exception ex)
{
Console.WriteLine($"Error while stopping: {ex.Message}");
}
}
}

public override int GetHashCode()
{
var payload = $"{nameof(UdpClientWrapper)}|{_localEndPoint.Address}|{_localEndPoint.Port}";
public override int GetHashCode()
{
var payload = $"{nameof(UdpClientWrapper)}|{_localEndPoint.Address}|{_localEndPoint.Port}";

using var md5 = MD5.Create();
var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(payload));
var hash = MD5.HashData(Encoding.UTF8.GetBytes(payload));

return BitConverter.ToInt32(hash, 0);
return BitConverter.ToInt32(hash, 0);
}
}
}
}