Skip to content

Commit 922b91b

Browse files
committed
Hello world virtual node. Still missing a lot of things
1 parent baa507d commit 922b91b

20 files changed

+304
-55
lines changed

Meshtastic.Simulator.Service/Program.cs

Lines changed: 0 additions & 11 deletions
This file was deleted.

Meshtastic.Simulator.Service/SimulatorWorker.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
namespace Meshtastic.Simulator.Service;
99

10-
public class SimulatorWorker(ILogger<SimulatorWorker> logger, ISimulatorStore store) : BackgroundService
10+
public class VirtualWorker(ILogger<VirtualWorker> logger, IVirtualStore store) : BackgroundService
1111
{
1212
private UdpClient? udpClient;
1313

@@ -73,7 +73,7 @@ private async Task<bool> HandleMeshPacket(UdpReceiveResult udpData)
7373
var responsePacket = CreateMeshPacket(new Protobufs.Data
7474
{
7575
Portnum = PortNum.NodeinfoApp,
76-
Payload = store.User.ToByteString(),
76+
Payload = store.Node.User.ToByteString(),
7777
WantResponse = false,
7878
});
7979
var responseBytes = responsePacket.ToByteArray();

Meshtastic.Simulator.Service/Dockerfile renamed to Meshtastic.Virtual.Service/Dockerfile

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,19 @@ FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
1111
ARG BUILD_CONFIGURATION=Release
1212
WORKDIR /src
1313
COPY ["Directory.Packages.props", "."]
14-
COPY ["Meshtastic.Simulator.Service/Meshtastic.Simulator.Service.csproj", "Meshtastic.Simulator.Service/"]
15-
RUN dotnet restore "./Meshtastic.Simulator.Service/Meshtastic.Simulator.Service.csproj"
14+
COPY ["Meshtastic.Virtual.Service/Meshtastic.Virtual.Service.csproj", "Meshtastic.Virtual.Service/"]
15+
RUN dotnet restore "./Meshtastic.Virtual.Service/Meshtastic.Virtual.Service.csproj"
1616
COPY . .
17-
WORKDIR "/src/Meshtastic.Simulator.Service"
18-
RUN dotnet build "./Meshtastic.Simulator.Service.csproj" -c $BUILD_CONFIGURATION -o /app/build
17+
WORKDIR "/src/Meshtastic.Virtual.Service"
18+
RUN dotnet build "./Meshtastic.Virtual.Service.csproj" -c $BUILD_CONFIGURATION -o /app/build
1919

2020
# This stage is used to publish the service project to be copied to the final stage
2121
FROM build AS publish
2222
ARG BUILD_CONFIGURATION=Release
23-
RUN dotnet publish "./Meshtastic.Simulator.Service.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
23+
RUN dotnet publish "./Meshtastic.Virtual.Service.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
2424

2525
# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
2626
FROM base AS final
2727
WORKDIR /app
2828
COPY --from=publish /app/publish .
29-
ENTRYPOINT ["dotnet", "Meshtastic.Simulator.Service.dll"]
29+
ENTRYPOINT ["dotnet", "Meshtastic.Virtual.Service.dll"]

Meshtastic.Simulator.Service/Meshtastic.Simulator.Service.csproj renamed to Meshtastic.Virtual.Service/Meshtastic.Virtual.Service.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<TargetFramework>net9.0</TargetFramework>
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
7-
<UserSecretsId>dotnet-Meshtastic.Simulator.Service-f04ea7a8-15a0-4fec-b79a-3106e594e1a5</UserSecretsId>
7+
<UserSecretsId>dotnet-Meshtastic.Virtual.Service-f04ea7a8-15a0-4fec-b79a-3106e594e1a5</UserSecretsId>
88
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
99
</PropertyGroup>
1010

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+
}

Meshtastic.Simulator.Service/Persistance/FilePaths.cs renamed to Meshtastic.Virtual.Service/Persistance/FilePaths.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
namespace Meshtastic.Simulator.Service.Persistance;
1+
namespace Meshtastic.Virtual.Service.Persistance;
22

33
public static class FilePaths
44
{
5-
public const string USER_FILE = "user.proto";
5+
public const string NODE_FILE = "node.proto";
66
public const string MYNODEINFO_FILE = "mynodeinfo.proto";
77
public const string CHANNELS_FILE = "channels.proto";
88
public const string CONFIG_FILE = "config.proto";

Meshtastic.Simulator.Service/Persistance/FilePersistance.cs renamed to Meshtastic.Virtual.Service/Persistance/FilePersistance.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using static System.Environment;
22

3-
namespace Meshtastic.Simulator.Service.Persistance;
3+
namespace Meshtastic.Virtual.Service.Persistance;
44

55
public class FilePersistance(ILogger<IFilePersistance> logger) : IFilePersistance
66
{
@@ -49,9 +49,4 @@ public async Task<bool> Delete(string fileName)
4949
return false;
5050
}
5151
}
52-
53-
Task<byte[]> IFilePersistance.Save(string fileName, byte[] data)
54-
{
55-
throw new NotImplementedException();
56-
}
5752
}
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
namespace Meshtastic.Simulator.Service.Persistance;
1+
namespace Meshtastic.Virtual.Service.Persistance;
22

33
public interface IFilePersistance
44
{
55
Task<bool> Delete(string fileName);
66
Task<bool> Exists(string fileName);
77
Task<byte[]> Load(string fileName);
8-
Task<byte[]> Save(string fileName, byte[] data);
8+
Task<bool> Save(string fileName, byte[] data);
99
}

Meshtastic.Simulator.Service/Persistance/ISimulatorStore.cs renamed to Meshtastic.Virtual.Service/Persistance/IVirtualStore.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
using Meshtastic.Protobufs;
22

3-
namespace Meshtastic.Simulator.Service.Persistance;
3+
namespace Meshtastic.Virtual.Service.Persistance;
44

5-
public interface ISimulatorStore
5+
public interface IVirtualStore
66
{
77
Task Load();
88
Task Save();
99

10-
User User { get; }
10+
NodeInfo Node { get; }
1111
LocalConfig LocalConfig { get; }
1212
LocalModuleConfig LocalModuleConfig { get; }
1313
List<Channel> Channels { get; }

Meshtastic.Simulator.Service/Persistance/SimulatorStore.cs renamed to Meshtastic.Virtual.Service/Persistance/VirtualStore.cs

Lines changed: 90 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,89 @@
44
using Google.Protobuf;
55
using Meshtastic.Data;
66
using Meshtastic.Protobufs;
7+
using Meshtastic.Virtual.Service.Network;
8+
using Org.BouncyCastle.Crypto.Generators;
9+
using Org.BouncyCastle.Crypto.Parameters;
10+
using Org.BouncyCastle.Security;
11+
using static Meshtastic.Protobufs.Config.Types;
12+
using static Meshtastic.Protobufs.ModuleConfig.Types;
713

8-
namespace Meshtastic.Simulator.Service.Persistance;
14+
namespace Meshtastic.Virtual.Service.Persistance;
915

10-
public class SimulatorStore(IFilePersistance filePersistance) : ISimulatorStore
16+
public class VirtualStore(IFilePersistance filePersistance) : IVirtualStore
1117
{
1218
private readonly DeviceStateContainer deviceStateContainer = new();
1319

14-
public User User => deviceStateContainer.User;
1520
public LocalConfig LocalConfig => deviceStateContainer.LocalConfig;
1621
public LocalModuleConfig LocalModuleConfig => deviceStateContainer.LocalModuleConfig;
1722
public List<Channel> Channels => deviceStateContainer.Channels;
1823
public ChannelSet ChannelSettings => deviceStateContainer.ChannelSettings;
1924
public MyNodeInfo MyNodeInfo => deviceStateContainer.MyNodeInfo;
25+
public NodeInfo Node => deviceStateContainer.Node;
2026
public List<NodeInfo> Nodes => deviceStateContainer.Nodes;
2127

2228
public async Task Load()
2329
{
24-
var macAddress = NetworkInterface
25-
.GetAllNetworkInterfaces()
26-
.Where(nic => nic.OperationalStatus == OperationalStatus.Up && nic.NetworkInterfaceType != NetworkInterfaceType.Loopback)
27-
.Select(nic => nic.GetPhysicalAddress())
28-
.First();
29-
30+
var macAddress = InterfaceUtility.GetMacAddress();
3031
byte[] nodeNum = [.. macAddress.GetAddressBytes().TakeLast(4)];
3132
var shortName = Convert.ToHexString(nodeNum)[^4..];
3233

33-
if (await filePersistance.Exists(FilePaths.USER_FILE))
34+
if (await filePersistance.Exists(FilePaths.CONFIG_FILE))
3435
{
35-
deviceStateContainer.User = User.Parser.ParseFrom(await filePersistance.Load(FilePaths.USER_FILE));
36+
deviceStateContainer.LocalConfig = LocalConfig.Parser.ParseFrom(await filePersistance.Load(FilePaths.CONFIG_FILE));
37+
}
38+
else
39+
{
40+
var generator = new Ed25519KeyPairGenerator();
41+
var parameters = new Ed25519KeyGenerationParameters(new SecureRandom());
42+
generator.Init(parameters);
43+
var keyPair = generator.GenerateKeyPair();
44+
var privateKey = ((Ed25519PrivateKeyParameters)keyPair.Private).GetEncoded();
45+
var publicKey = ((Ed25519PublicKeyParameters)keyPair.Public).GetEncoded();
46+
47+
deviceStateContainer.LocalConfig = new LocalConfig
48+
{
49+
Bluetooth = new BluetoothConfig
50+
{
51+
Enabled = false
52+
},
53+
Device = new DeviceConfig
54+
{
55+
Role = DeviceConfig.Types.Role.Client,
56+
NodeInfoBroadcastSecs = 900,
57+
},
58+
Lora = new LoRaConfig
59+
{
60+
TxEnabled = false,
61+
HopLimit = 3,
62+
Region = LoRaConfig.Types.RegionCode.Unset,
63+
UsePreset = true,
64+
ModemPreset = LoRaConfig.Types.ModemPreset.LongFast,
65+
},
66+
Network = new NetworkConfig
67+
{
68+
EnabledProtocols = (uint)NetworkConfig.Types.ProtocolFlags.UdpBroadcast,
69+
},
70+
Position = new PositionConfig
71+
{
72+
GpsMode = PositionConfig.Types.GpsMode.NotPresent
73+
},
74+
Power = new PowerConfig
75+
{
76+
IsPowerSaving = false,
77+
MinWakeSecs = Int32.MaxValue,
78+
},
79+
Security = new SecurityConfig
80+
{
81+
PrivateKey = ByteString.CopyFrom(privateKey),
82+
PublicKey = ByteString.CopyFrom(publicKey),
83+
},
84+
};
85+
}
86+
87+
if (await filePersistance.Exists(FilePaths.NODE_FILE))
88+
{
89+
deviceStateContainer.Node = NodeInfo.Parser.ParseFrom(await filePersistance.Load(FilePaths.NODE_FILE));
3690
}
3791
else
3892
{
@@ -43,7 +97,14 @@ public async Task Load()
4397
LongName = $"Simulator_{shortName}",
4498
ShortName = shortName,
4599
};
46-
deviceStateContainer.User = user;
100+
deviceStateContainer.Node = new NodeInfo
101+
{
102+
User = user,
103+
Num = BitConverter.ToUInt32(nodeNum, 0),
104+
Channel = 0,
105+
HopsAway = 0,
106+
IsFavorite = true,
107+
};
47108
}
48109
if (await filePersistance.Exists(FilePaths.MYNODEINFO_FILE))
49110
{
@@ -56,17 +117,26 @@ public async Task Load()
56117
MyNodeNum = BitConverter.ToUInt32(nodeNum, 0),
57118
};
58119
}
59-
if (await filePersistance.Exists(FilePaths.CONFIG_FILE))
60-
{
61-
deviceStateContainer.LocalConfig = LocalConfig.Parser.ParseFrom(await filePersistance.Load(FilePaths.CONFIG_FILE));
62-
}
120+
63121
if (await filePersistance.Exists(FilePaths.MODULE_FILE))
64122
{
65123
deviceStateContainer.LocalModuleConfig = LocalModuleConfig.Parser.ParseFrom(await filePersistance.Load(FilePaths.MODULE_FILE));
66124
}
125+
else {
126+
deviceStateContainer.LocalModuleConfig = new LocalModuleConfig
127+
{
128+
Mqtt = new MQTTConfig
129+
{
130+
Enabled = false,
131+
Address = "mqtt.meshtastic.org",
132+
Username = "meshdev",
133+
Password = "large4cats",
134+
},
135+
};
136+
}
67137
if (await filePersistance.Exists(FilePaths.CHANNELS_FILE))
68138
{
69-
// FIXME: deviceStateContainer.Channels =
139+
// FIXME: Open channels
70140
}
71141
else {
72142
deviceStateContainer.Channels = [
@@ -127,10 +197,12 @@ public async Task Load()
127197
},
128198
];
129199
}
200+
await Save();
130201
}
202+
131203
public async Task Save()
132204
{
133-
await filePersistance.Save(FilePaths.USER_FILE, deviceStateContainer.User.ToByteArray());
205+
await filePersistance.Save(FilePaths.NODE_FILE, deviceStateContainer.Node.ToByteArray());
134206
// await filePersistance.Save(FilePaths.CHANNELS_FILE, deviceStateContainer.Channels);
135207
await filePersistance.Save(FilePaths.CONFIG_FILE, deviceStateContainer.LocalConfig.ToByteArray());
136208
await filePersistance.Save(FilePaths.MODULE_FILE, deviceStateContainer.LocalModuleConfig.ToByteArray());

Meshtastic.Virtual.Service/Program.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using Meshtastic.Virtual.Service;
2+
using Meshtastic.Virtual.Service.Persistance;
3+
4+
var builder = Host.CreateApplicationBuilder(args);
5+
builder.Services.AddLogging();
6+
builder.Services.AddSingleton<IFilePersistance, FilePersistance>();
7+
builder.Services.AddSingleton<IVirtualStore, VirtualStore>();
8+
builder.Services.AddHostedService<VirtualWorker>();
9+
10+
var host = builder.Build();
11+
host.Run();

Meshtastic.Simulator.Service/Properties/launchSettings.json renamed to Meshtastic.Virtual.Service/Properties/launchSettings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"profiles": {
3-
"Meshtastic.Simulator.Service": {
3+
"Meshtastic.Virtual.Service": {
44
"commandName": "Project",
55
"environmentVariables": {
66
"DOTNET_ENVIRONMENT": "Development"

0 commit comments

Comments
 (0)