Skip to content

Commit 596faeb

Browse files
authored
Merge pull request #111 from meshtastic/udp-simulator
Start of Virtual node with UDP
2 parents da11a7f + 79a9c64 commit 596faeb

25 files changed

+663
-13
lines changed

Directory.Packages.props

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,32 @@
33
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
44
</PropertyGroup>
55
<ItemGroup>
6+
<PackageVersion Include="BouncyCastle.Cryptography" Version="2.5.1" />
67
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
78
<PackageVersion Include="FluentAssertions" Version="7.1.0" />
89
<PackageVersion Include="ILogger.Moq" Version="1.1.10" />
9-
<PackageVersion Include="Google.Protobuf" Version="3.29.3" />
10-
<PackageVersion Include="Google.Protobuf.Tools" Version="3.29.3" />
11-
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.1" />
12-
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.1" />
13-
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="9.0.1" />
14-
<PackageVersion Include="Microsoft.Extensions.Logging.Debug" Version="9.0.1" />
15-
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
10+
<PackageVersion Include="Google.Protobuf" Version="3.30.1" />
11+
<PackageVersion Include="Google.Protobuf.Tools" Version="3.30.1" />
12+
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.3" />
13+
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.3" />
14+
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.3" />
15+
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="9.0.3" />
16+
<PackageVersion Include="Microsoft.Extensions.Logging.Debug" Version="9.0.3" />
17+
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
18+
<PackageVersion Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
1619
<PackageVersion Include="Moq" Version="4.20.72" />
1720
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
1821
<PackageVersion Include="NUnit" Version="4.3.2" />
1922
<PackageVersion Include="NUnit3TestAdapter" Version="5.0.0" />
2023
<PackageVersion Include="NUnit.Analyzers" Version="4.6.0" />
2124
<PackageVersion Include="MQTTnet" Version="5.0.1.1416" />
25+
<PackageVersion Include="Portable.BouncyCastle" Version="1.9.0" />
2226
<PackageVersion Include="QRCoder" Version="1.6.0" />
2327
<PackageVersion Include="SimpleExec" Version="12.0.0" />
2428
<PackageVersion Include="Spectre.Console" Version="0.49.1" />
2529
<PackageVersion Include="Spectre.Console.Json" Version="0.49.1" />
2630
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
27-
<PackageVersion Include="System.IO.Ports" Version="9.0.1" />
31+
<PackageVersion Include="System.IO.Ports" Version="9.0.3" />
2832
<PackageVersion Include="YamlDotNet" Version="16.3.0" />
2933
</ItemGroup>
3034
</Project>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using Meshtastic.Crypto;
2+
using Meshtastic.Protobufs;
3+
4+
namespace Meshtastic.Test.Crypto;
5+
6+
public class PacketCryptoTests
7+
{
8+
[SetUp]
9+
public void Setup()
10+
{
11+
}
12+
13+
[Test]
14+
public void TestDefaultKeyDecrypt()
15+
{
16+
//{ "packet": { "from": 4202784164, "to": 4294967295, "channel": 8, "encrypted": "kiDV39nDDsi8AON+Czei6zUpy+F/7E+lyIpicxJR40KXBFmPkqFUEnobI5voQadha+s=", "id": 1777428186, "hopLimit": 3, "priority": "BACKGROUND", "hopStart": 3 }, "channelId": "LongFast", "gatewayId": "!fa8165a4" }
17+
var nonce = new NonceGenerator(4202784164, 1777428186).Create();
18+
19+
var decrypted = PacketEncryption.TransformPacket(Convert.FromBase64String("kiDV39nDDsi8AON+Czei6zUpy+F/7E+lyIpicxJR40KXBFmPkqFUEnobI5voQadha+s="), nonce, Resources.DEFAULT_PSK);
20+
var testMessage = Meshtastic.Protobufs.Data.Parser.ParseFrom(decrypted);
21+
testMessage.Portnum.Should().Be(PortNum.NodeinfoApp);
22+
var nodeInfo = User.Parser.ParseFrom(testMessage.Payload);
23+
nodeInfo.LongName.Should().Be("Meshtastic 65a4");
24+
}
25+
}

Meshtastic.Virtual.Service/Dockerfile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
2+
3+
# This stage is used when running from VS in fast mode (Default for Debug configuration)
4+
FROM mcr.microsoft.com/dotnet/runtime:9.0 AS base
5+
USER $APP_UID
6+
WORKDIR /app
7+
8+
9+
# This stage is used to build the service project
10+
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
11+
ARG BUILD_CONFIGURATION=Release
12+
WORKDIR /src
13+
COPY ["Directory.Packages.props", "."]
14+
COPY ["Meshtastic.Virtual.Service/Meshtastic.Virtual.Service.csproj", "Meshtastic.Virtual.Service/"]
15+
RUN dotnet restore "./Meshtastic.Virtual.Service/Meshtastic.Virtual.Service.csproj"
16+
COPY . .
17+
WORKDIR "/src/Meshtastic.Virtual.Service"
18+
RUN dotnet build "./Meshtastic.Virtual.Service.csproj" -c $BUILD_CONFIGURATION -o /app/build
19+
20+
# This stage is used to publish the service project to be copied to the final stage
21+
FROM build AS publish
22+
ARG BUILD_CONFIGURATION=Release
23+
RUN dotnet publish "./Meshtastic.Virtual.Service.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
24+
25+
# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
26+
FROM base AS final
27+
WORKDIR /app
28+
COPY --from=publish /app/publish .
29+
ENTRYPOINT ["dotnet", "Meshtastic.Virtual.Service.dll"]
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Worker">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<UserSecretsId>dotnet-Meshtastic.Virtual.Service-f04ea7a8-15a0-4fec-b79a-3106e594e1a5</UserSecretsId>
8+
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="Microsoft.Extensions.Hosting" />
13+
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" />
14+
</ItemGroup>
15+
16+
<ItemGroup>
17+
<ProjectReference Include="..\Meshtastic\Meshtastic.csproj" />
18+
</ItemGroup>
19+
</Project>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
3+
using System.Net.NetworkInformation;
4+
5+
namespace Meshtastic.Virtual.Service.Network;
6+
7+
public static class InterfaceUtility
8+
{
9+
public static PhysicalAddress GetMacAddress()
10+
{
11+
return NetworkInterface
12+
.GetAllNetworkInterfaces()
13+
.Where(nic => nic.OperationalStatus == OperationalStatus.Up && nic.NetworkInterfaceType != NetworkInterfaceType.Loopback)
14+
.Select(nic => nic.GetPhysicalAddress())
15+
.First();
16+
}
17+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace Meshtastic.Virtual.Service.Persistance;
2+
3+
public static class FilePaths
4+
{
5+
public const string NODE_FILE = "node.proto";
6+
public const string MYNODEINFO_FILE = "mynodeinfo.proto";
7+
public const string CHANNELS_FILE = "channels.proto";
8+
public const string CONFIG_FILE = "config.proto";
9+
public const string MODULE_FILE = "module.store";
10+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using static System.Environment;
2+
3+
namespace Meshtastic.Virtual.Service.Persistance;
4+
5+
public class FilePersistance(ILogger<IFilePersistance> logger) : IFilePersistance
6+
{
7+
private static readonly string basePath = Path.Combine(GetFolderPath(SpecialFolder.LocalApplicationData, SpecialFolderOption.DoNotVerify), "meshtastic");
8+
9+
public async Task<bool> Save(string fileName, byte[] data)
10+
{
11+
try
12+
{
13+
// Ensure the directory and all its parents exist.
14+
Directory.CreateDirectory(basePath);
15+
await File.WriteAllBytesAsync(fileName, data);
16+
return true;
17+
}
18+
catch (Exception ex)
19+
{
20+
logger.LogError(ex, "Error saving file {FileName}", fileName);
21+
return false;
22+
}
23+
}
24+
25+
public async Task<byte[]> Load(string fileName)
26+
{
27+
return await File.ReadAllBytesAsync(fileName);
28+
}
29+
30+
public async Task<bool> Exists(string fileName)
31+
{
32+
return await Task.FromResult(File.Exists(fileName));
33+
}
34+
35+
public async Task<bool> Delete(string fileName)
36+
{
37+
try
38+
{
39+
if (File.Exists(fileName))
40+
{
41+
File.Delete(fileName);
42+
return true;
43+
}
44+
return await Task.FromResult(false);
45+
}
46+
catch (Exception ex)
47+
{
48+
logger.LogError(ex, "Error deleting file {FileName}", fileName);
49+
return false;
50+
}
51+
}
52+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace Meshtastic.Virtual.Service.Persistance;
2+
3+
public interface IFilePersistance
4+
{
5+
Task<bool> Delete(string fileName);
6+
Task<bool> Exists(string fileName);
7+
Task<byte[]> Load(string fileName);
8+
Task<bool> Save(string fileName, byte[] data);
9+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using Meshtastic.Protobufs;
2+
3+
namespace Meshtastic.Virtual.Service.Persistance;
4+
5+
public interface IVirtualStore
6+
{
7+
Task Load();
8+
Task Save();
9+
10+
NodeInfo Node { get; }
11+
LocalConfig LocalConfig { get; }
12+
LocalModuleConfig LocalModuleConfig { get; }
13+
List<Channel> Channels { get; }
14+
MyNodeInfo MyNodeInfo { get; }
15+
List<NodeInfo> Nodes { get; }
16+
}

0 commit comments

Comments
 (0)