diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..1165846
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,47 @@
+name: SonarQube
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+ types: [opened, synchronize, reopened]
+jobs:
+ build:
+ name: Build and analyze
+ runs-on: windows-latest
+ steps:
+ - name: Set up JDK 17
+ uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4.8.0
+ with:
+ java-version: 17
+ distribution: "zulu" # Alternative distribution options are available.
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
+ with:
+ fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
+ - name: Cache SonarQube Cloud packages
+ uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
+ with:
+ path: ~\sonar\cache
+ key: ${{ runner.os }}-sonar
+ restore-keys: ${{ runner.os }}-sonar
+ - name: Cache SonarQube Cloud scanner
+ id: cache-sonar-scanner
+ uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
+ with:
+ path: ${{ runner.temp }}\scanner
+ key: ${{ runner.os }}-sonar-scanner
+ restore-keys: ${{ runner.os }}-sonar-scanner
+ - name: Install SonarQube Cloud scanner
+ if: steps.cache-sonar-scanner.outputs.cache-hit != 'true'
+ shell: powershell
+ run: |
+ New-Item -Path ${{ runner.temp }}\scanner -ItemType Directory
+ dotnet tool update dotnet-sonarscanner --tool-path ${{ runner.temp }}\scanner
+ - name: Build and analyze
+ env:
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+ shell: powershell
+ run: |
+ ${{ runner.temp }}\scanner\dotnet-sonarscanner begin /k:"KonstantinDanger_reengineering-course-fork2" /o:"konstantindanger" /d:sonar.token="${{ secrets.SONAR_TOKEN }}"
+ dotnet build
+ ${{ runner.temp }}\scanner\dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}"
diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml
index e784069..cae3cb2 100644
--- a/.github/workflows/sonarcloud.yml
+++ b/.github/workflows/sonarcloud.yml
@@ -1,38 +1,10 @@
-# This workflow uses actions that are not certified by GitHub.
-# They are provided by a third-party and are governed by
-# separate terms of service, privacy policy, and support
-# documentation.
-
-# This workflow helps you trigger a SonarCloud analysis of your code and populates
-# GitHub Code Scanning alerts with the vulnerabilities found.
-# Free for open source project.
-
-# 1. Login to SonarCloud.io using your GitHub account
-
-# 2. Import your project on SonarCloud
-# * Add your GitHub organization first, then add your repository as a new project.
-# * Please note that many languages are eligible for automatic analysis,
-# which means that the analysis will start automatically without the need to set up GitHub Actions.
-# * This behavior can be changed in Administration > Analysis Method.
-#
-# 3. Follow the SonarCloud in-product tutorial
-# * a. Copy/paste the Project Key and the Organization Key into the args parameter below
-# (You'll find this information in SonarCloud. Click on "Information" at the bottom left)
-#
-# * b. Generate a new token and add it to your Github repository's secrets using the name SONAR_TOKEN
-# (On SonarCloud, click on your avatar on top-right > My account > Security
-# or go directly to https://sonarcloud.io/account/security/)
-
-# Feel free to take a look at our documentation (https://docs.sonarcloud.io/getting-started/github/)
-# or reach out to our community forum if you need some help (https://community.sonarsource.com/c/help/sc/9)
-
name: SonarCloud analysis
on:
push:
- branches: [ "master" ]
+ branches: ["master"]
pull_request:
- branches: [ "master" ]
+ branches: ["master"]
workflow_dispatch:
permissions:
@@ -41,14 +13,14 @@ permissions:
jobs:
sonar-check:
name: Sonar Check
- runs-on: windows-latest # безпечно для будь-яких .NET проектів
+ runs-on: windows-latest # безпечно для будь-яких .NET проектів
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: actions/setup-dotnet@v4
with:
- dotnet-version: '8.0.x'
+ dotnet-version: "8.0.x"
# 1) BEGIN: SonarScanner for .NET
- name: SonarScanner Begin
@@ -56,8 +28,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:"KonstantinDanger_reengineering-course-fork2" `
+ /o:"konstantindanger" `
/d:sonar.token="${{ secrets.SONAR_TOKEN }}" `
/d:sonar.cs.opencover.reportsPaths="**/coverage.xml" `
/d:sonar.cpd.cs.minimumTokens=40 `
diff --git a/EchoTcpServer/Program.cs b/EchoTcpServer/Program.cs
index 5966c57..d411eb0 100644
--- a/EchoTcpServer/Program.cs
+++ b/EchoTcpServer/Program.cs
@@ -5,169 +5,173 @@
using System.Threading;
using System.Threading.Tasks;
-///
-/// This program was designed for test purposes only
-/// Not for a review
-///
-public class EchoServer
+namespace EchoServer
{
- private readonly int _port;
- private TcpListener _listener;
- private CancellationTokenSource _cancellationTokenSource;
-
- public EchoServer(int port)
+ ///
+ /// This program was designed for test purposes only
+ /// Not for a review
+ ///
+ public class EchoServer
{
- _port = port;
- _cancellationTokenSource = new CancellationTokenSource();
- }
+ private readonly int _port;
+ private TcpListener _listener;
+ private readonly CancellationTokenSource _cancellationTokenSource;
- public async Task StartAsync()
- {
- _listener = new TcpListener(IPAddress.Any, _port);
- _listener.Start();
- Console.WriteLine($"Server started on port {_port}.");
- while (!_cancellationTokenSource.Token.IsCancellationRequested)
+ public EchoServer(int port)
{
- try
- {
- TcpClient client = await _listener.AcceptTcpClientAsync();
- Console.WriteLine("Client connected.");
-
- _ = Task.Run(() => HandleClientAsync(client, _cancellationTokenSource.Token));
- }
- catch (ObjectDisposedException)
- {
- // Listener has been closed
- break;
- }
+ _port = port;
+ _cancellationTokenSource = new CancellationTokenSource();
}
- Console.WriteLine("Server shutdown.");
- }
-
- private async Task HandleClientAsync(TcpClient client, CancellationToken token)
- {
- using (NetworkStream stream = client.GetStream())
+ public async Task StartAsync()
{
- try
+ _listener = new TcpListener(IPAddress.Any, _port);
+ _listener.Start();
+ Console.WriteLine($"Server started on port {_port}.");
+
+ while (!_cancellationTokenSource.Token.IsCancellationRequested)
{
- byte[] buffer = new byte[8192];
- int bytesRead;
+ try
+ {
+ TcpClient client = await _listener.AcceptTcpClientAsync();
+ Console.WriteLine("Client connected.");
- while (!token.IsCancellationRequested && (bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, token)) > 0)
+ _ = Task.Run(() => HandleClientAsync(client, _cancellationTokenSource.Token));
+ }
+ catch (ObjectDisposedException)
{
- // Echo back the received message
- await stream.WriteAsync(buffer, 0, bytesRead, token);
- Console.WriteLine($"Echoed {bytesRead} bytes to the client.");
+ // Listener has been closed
+ break;
}
}
- catch (Exception ex) when (!(ex is OperationCanceledException))
- {
- Console.WriteLine($"Error: {ex.Message}");
- }
- finally
+
+ Console.WriteLine("Server shutdown.");
+ }
+
+ private async Task HandleClientAsync(TcpClient client, CancellationToken token)
+ {
+ using (NetworkStream stream = client.GetStream())
{
- client.Close();
- Console.WriteLine("Client disconnected.");
+ try
+ {
+ byte[] buffer = new byte[8192];
+ int bytesRead;
+
+ while (!token.IsCancellationRequested && (bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, token)) > 0)
+ {
+ // Echo back the received message
+ await stream.WriteAsync(buffer, 0, bytesRead, token);
+ Console.WriteLine($"Echoed {bytesRead} bytes to the client.");
+ }
+ }
+ catch (Exception ex) when (!(ex is OperationCanceledException))
+ {
+ Console.WriteLine($"Error: {ex.Message}");
+ }
+ finally
+ {
+ client.Close();
+ Console.WriteLine("Client disconnected.");
+ }
}
}
- }
- public void Stop()
- {
- _cancellationTokenSource.Cancel();
- _listener.Stop();
- _cancellationTokenSource.Dispose();
- Console.WriteLine("Server stopped.");
- }
-
- public static async Task Main(string[] args)
- {
- EchoServer server = new EchoServer(5000);
+ public void Stop()
+ {
+ _cancellationTokenSource.Cancel();
+ _listener.Stop();
+ _cancellationTokenSource.Dispose();
+ Console.WriteLine("Server stopped.");
+ }
- // Start the server in a separate task
- _ = Task.Run(() => server.StartAsync());
+ public static async Task Main(string[] args)
+ {
+ EchoServer server = new EchoServer(5000);
- string host = "127.0.0.1"; // Target IP
- int port = 60000; // Target Port
- int intervalMilliseconds = 5000; // Send every 3 seconds
+ // Start the server in a separate task
+ _ = Task.Run(() => server.StartAsync());
- using (var sender = new UdpTimedSender(host, port))
- {
- Console.WriteLine("Press any key to stop sending...");
- sender.StartSending(intervalMilliseconds);
+ string host = "127.0.0.1"; // Target IP
+ int port = 60000; // Target Port
+ int intervalMilliseconds = 5000; // Send every 3 seconds
- Console.WriteLine("Press 'q' to quit...");
- while (Console.ReadKey(intercept: true).Key != ConsoleKey.Q)
+ using (var sender = new UdpTimedSender(host, port))
{
- // Just wait until 'q' is pressed
- }
+ Console.WriteLine("Press any key to stop sending...");
+ sender.StartSending(intervalMilliseconds);
- sender.StopSending();
- server.Stop();
- Console.WriteLine("Sender stopped.");
+ Console.WriteLine("Press 'q' to quit...");
+ while (Console.ReadKey(intercept: true).Key != ConsoleKey.Q)
+ {
+ // Just wait until 'q' is pressed
+ }
+
+ sender.StopSending();
+ server.Stop();
+ Console.WriteLine("Sender stopped.");
+ }
}
}
-}
-public class UdpTimedSender : IDisposable
-{
- private readonly string _host;
- private readonly int _port;
- private readonly UdpClient _udpClient;
- private Timer _timer;
-
- public UdpTimedSender(string host, int port)
+ public class UdpTimedSender : IDisposable
{
- _host = host;
- _port = port;
- _udpClient = new UdpClient();
- }
+ private readonly string _host;
+ private readonly int _port;
+ private readonly UdpClient _udpClient;
+ private Timer _timer;
- public void StartSending(int intervalMilliseconds)
- {
- if (_timer != null)
- throw new InvalidOperationException("Sender is already running.");
+ public UdpTimedSender(string host, int port)
+ {
+ _host = host;
+ _port = port;
+ _udpClient = new UdpClient();
+ }
- _timer = new Timer(SendMessageCallback, null, 0, intervalMilliseconds);
- }
+ public void StartSending(int intervalMilliseconds)
+ {
+ if (_timer != null)
+ throw new InvalidOperationException("Sender is already running.");
- ushort i = 0;
+ _timer = new Timer(SendMessageCallback, null, 0, intervalMilliseconds);
+ }
- private void SendMessageCallback(object state)
- {
- try
+ ushort i = 0;
+
+ private void SendMessageCallback(object state)
{
- //dummy data
- Random rnd = new Random();
- byte[] samples = new byte[1024];
- rnd.NextBytes(samples);
- i++;
+ try
+ {
+ //dummy data
+ Random rnd = new Random();
+ byte[] samples = new byte[1024];
+ rnd.NextBytes(samples);
+ i++;
- byte[] msg = (new byte[] { 0x04, 0x84 }).Concat(BitConverter.GetBytes(i)).Concat(samples).ToArray();
- var endpoint = new IPEndPoint(IPAddress.Parse(_host), _port);
+ byte[] msg = (new byte[] { 0x04, 0x84 }).Concat(BitConverter.GetBytes(i)).Concat(samples).ToArray();
+ var endpoint = new IPEndPoint(IPAddress.Parse(_host), _port);
- _udpClient.Send(msg, msg.Length, endpoint);
- Console.WriteLine($"Message sent to {_host}:{_port} ");
+ _udpClient.Send(msg, msg.Length, endpoint);
+ Console.WriteLine($"Message sent to {_host}:{_port} ");
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Error sending message: {ex.Message}");
+ }
}
- catch (Exception ex)
+
+ public void StopSending()
{
- Console.WriteLine($"Error sending message: {ex.Message}");
+ _timer?.Dispose();
+ _timer = null;
}
- }
-
- public void StopSending()
- {
- _timer?.Dispose();
- _timer = null;
- }
- public void Dispose()
- {
- StopSending();
- _udpClient.Dispose();
+ public void Dispose()
+ {
+ StopSending();
+ _udpClient.Dispose();
+ }
}
}
\ No newline at end of file
diff --git a/NetSdrClientApp/Messages/NetSdrMessageHelper.cs b/NetSdrClientApp/Messages/NetSdrMessageHelper.cs
index 0d69b4d..0ea0982 100644
--- a/NetSdrClientApp/Messages/NetSdrMessageHelper.cs
+++ b/NetSdrClientApp/Messages/NetSdrMessageHelper.cs
@@ -111,7 +111,7 @@ public static IEnumerable GetSamples(ushort sampleSize, byte[] body)
sampleSize /= 8; //to bytes
if (sampleSize > 4)
{
- throw new ArgumentOutOfRangeException();
+ throw new ArgumentOutOfRangeException(sampleSize.ToString(), "sample size was bigger then 4");
}
var bodyEnumerable = body as IEnumerable;
diff --git a/NetSdrClientApp/NetSdrClient.cs b/NetSdrClientApp/NetSdrClient.cs
index b0a7c05..d153baf 100644
--- a/NetSdrClientApp/NetSdrClient.cs
+++ b/NetSdrClientApp/NetSdrClient.cs
@@ -14,8 +14,8 @@ namespace NetSdrClientApp
{
public class NetSdrClient
{
- private ITcpClient _tcpClient;
- private IUdpClient _udpClient;
+ private readonly ITcpClient _tcpClient;
+ private readonly IUdpClient _udpClient;
public bool IQStarted { get; set; }
@@ -66,7 +66,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;
@@ -114,7 +114,7 @@ public async Task ChangeFrequencyAsync(long hz, int channel)
await SendTcpRequest(msg);
}
- private void _udpClient_MessageReceived(object? sender, byte[] e)
+ private static void _udpClient_MessageReceived(object? sender, byte[] e)
{
NetSdrMessageHelper.TranslateMessage(e, out MsgTypes type, out ControlItemCodes code, out ushort sequenceNum, out byte[] body);
var samples = NetSdrMessageHelper.GetSamples(16, body);
@@ -138,7 +138,7 @@ private async Task SendTcpRequest(byte[] msg)
if (!_tcpClient.Connected)
{
Console.WriteLine("No active connection.");
- return null;
+ return [];
}
responseTaskSource = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
@@ -157,7 +157,7 @@ private void _tcpClient_MessageReceived(object? sender, byte[] e)
if (responseTaskSource != null)
{
responseTaskSource.SetResult(e);
- responseTaskSource = null;
+ responseTaskSource = new TaskCompletionSource();
}
Console.WriteLine("Response recieved: " + e.Select(b => Convert.ToString(b, toBase: 16)).Aggregate((l, r) => $"{l} {r}"));
}
diff --git a/README.md b/README.md
index b3a9029..ace6cce 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,5 @@
# Лабораторні з реінжинірингу (8×)
-[](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient)
-[](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient)
-[](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient)
-[](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient)
-[](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient)
-[](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient)
-[](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient)
-[](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient)
+[](https://sonarcloud.io/summary/new_code?id=KonstantinDanger_reengineering-course-fork2)
Цей репозиторій використовується для курсу **реінжиніринг ПЗ**.