Skip to content

Commit

Permalink
Merge pull request #52 from meshtastic/wip
Browse files Browse the repository at this point in the history
Update protos and add remove-node command
  • Loading branch information
thebentern authored Nov 19, 2023
2 parents 8aff5ff + 4cd8852 commit ae36bcd
Show file tree
Hide file tree
Showing 17 changed files with 1,244 additions and 281 deletions.
70 changes: 70 additions & 0 deletions Meshtastic.Cli/CommandHandlers/CaptureCommandHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using Meshtastic.Data;
using Meshtastic.Data.MessageFactories;
using Meshtastic.Display;
using Meshtastic.Protobufs;
using Meshtastic.Extensions;

namespace Meshtastic.Cli.CommandHandlers;

public class CaptureCommandHandler : DeviceCommandHandler
{
public CaptureCommandHandler(DeviceConnectionContext context, CommandContext commandContext) : base(context, commandContext) { }

public async Task<DeviceStateContainer> Handle()
{
var wantConfig = new ToRadioMessageFactory().CreateWantConfigMessage();
var container = await Connection.WriteToRadio(wantConfig, CompleteOnConfigReceived);
Connection.Disconnect();
return container;
}

public override async Task OnCompleted(FromRadio packet, DeviceStateContainer container)
{
await Connection.ReadFromRadio((fromRadio, container) =>
{
if (fromRadio!.PayloadVariantCase == FromRadio.PayloadVariantOneofCase.Packet) {
var fromRadioDecoded = new FromRadioDecoded(fromRadio)
{
PortNum = fromRadio.Packet?.Decoded?.Portnum,
PayloadSize = fromRadio.Packet?.Decoded?.Payload.Length ?? 0,
ReceivedAt = DateTime.Now,
};
if (fromRadio.GetPayload<AdminMessage>() != null)
fromRadioDecoded.DecodedPayload = fromRadio.GetPayload<AdminMessage>();
else if (fromRadio.GetPayload<XModem>() != null)
fromRadioDecoded.DecodedPayload = fromRadio.GetPayload<XModem>();
else if (fromRadio.GetPayload<NodeInfo>() != null)
fromRadioDecoded.DecodedPayload = fromRadio.GetPayload<NodeInfo>();
else if (fromRadio.GetPayload<Position>() != null)
fromRadioDecoded.DecodedPayload = fromRadio.GetPayload<Position>();
else if (fromRadio.GetPayload<Waypoint>() != null)
fromRadioDecoded.DecodedPayload = fromRadio.GetPayload<Waypoint>();
else if (fromRadio.GetPayload<Telemetry>() != null)
fromRadioDecoded.DecodedPayload = fromRadio.GetPayload<Telemetry>();
else if (fromRadio.GetPayload<Routing>() != null)
fromRadioDecoded.DecodedPayload = fromRadio.GetPayload<Routing>();
else if (fromRadio.GetPayload<RouteDiscovery>() != null)
fromRadioDecoded.DecodedPayload = fromRadio.GetPayload<RouteDiscovery>();
else if (fromRadio.GetPayload<string>() != null)
fromRadioDecoded.DecodedPayload = fromRadio.GetPayload<string>();
}

return Task.FromResult(false);
});
}
}

public class FromRadioDecoded
{
public FromRadioDecoded(FromRadio fromRadio)
{
Packet = fromRadio;
}

public FromRadio Packet { get; set; }
public object? DecodedPayload { get; set; }
public PortNum? PortNum { get; set; }
public int PayloadSize { get; set; }
public int TotalSize { get; set; }
public DateTime ReceivedAt { get; set; }
}
39 changes: 39 additions & 0 deletions Meshtastic.Cli/CommandHandlers/RemoveNodeCommandHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Meshtastic.Data;
using Meshtastic.Data.MessageFactories;
using Meshtastic.Protobufs;
using Microsoft.Extensions.Logging;

namespace Meshtastic.Cli.CommandHandlers;

public class RemoveNodeCommandHandler : DeviceCommandHandler
{
private readonly uint nodeNum;

public RemoveNodeCommandHandler(uint nodeNum, DeviceConnectionContext context,
CommandContext commandContext) : base(context, commandContext)
{
this.nodeNum = nodeNum;
}

public async Task<DeviceStateContainer> Handle()
{
var wantConfig = new ToRadioMessageFactory().CreateWantConfigMessage();
var container = await Connection.WriteToRadio(wantConfig, CompleteOnConfigReceived);
Connection.Disconnect();
return container;
}

public override async Task OnCompleted(FromRadio packet, DeviceStateContainer container)
{
if (!container.Nodes.Any(n => n.Num == nodeNum))
{
Logger.LogError($"Node with nodenum {nodeNum} not found in device's NodeDB");
return;
}

Logger.LogInformation("Removing device from NodeDB..");
var adminMessageFactory = new AdminMessageFactory(container, Destination);
var adminMessage = adminMessageFactory.CreateRemoveByNodenumMessage(nodeNum);
await Connection.WriteToRadio(ToRadioMessageFactory.CreateMeshPacketMessage(adminMessage), AnyResponseReceived);
}
}
21 changes: 21 additions & 0 deletions Meshtastic.Cli/Commands/CaptureCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Meshtastic.Cli.Binders;
using Meshtastic.Cli.CommandHandlers;
using Meshtastic.Cli.Enums;
using Microsoft.Extensions.Logging;

namespace Meshtastic.Cli.Commands;

public class CaptureCommand : Command
{
public CaptureCommand(string name, string description, Option<string> port, Option<string> host,
Option<OutputFormat> output, Option<LogLevel> log) : base(name, description)
{
this.SetHandler(async (context, commandContext) =>
{
var handler = new CaptureCommandHandler(context, commandContext);
await handler.Handle();
},
new DeviceConnectionBinder(port, host),
new CommandContextBinder(log, output, new Option<uint?>("dest") { }, new Option<bool>("select-dest") { }));
}
}
26 changes: 26 additions & 0 deletions Meshtastic.Cli/Commands/RemoveNodeCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Meshtastic.Cli.Binders;
using Meshtastic.Cli.CommandHandlers;
using Meshtastic.Cli.Enums;
using Microsoft.Extensions.Logging;

namespace Meshtastic.Cli.Commands;

public class RemoveNodeCommand : Command
{
public RemoveNodeCommand(string name, string description, Option<string> port, Option<string> host,
Option<OutputFormat> output, Option<LogLevel> log, Option<uint?> dest, Option<bool> selectDest) :
base(name, description)
{
var nodeNumArgument = new Argument<uint>("nodenum", "Nodenum of the node to remove from the device NodeDB");
AddArgument(nodeNumArgument);

this.SetHandler(async (nodeNum, context, commandContext) =>
{
var handler = new RemoveNodeCommandHandler(nodeNum, context, commandContext);
await handler.Handle();
},
nodeNumArgument,
new DeviceConnectionBinder(port, host),
new CommandContextBinder(log, output, dest, selectDest));
}
}
5 changes: 4 additions & 1 deletion Meshtastic.Cli/Mappings/HardwareModelMappings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ internal static class HardwareModelMappings
{
public static readonly IEnumerable<HardwareModel> NrfHardwareModels = new[]
{
HardwareModel.TEcho, HardwareModel.Rak4631
HardwareModel.TEcho,
HardwareModel.Rak4631,
HardwareModel.NanoG2Ultra,
HardwareModel.Nrf52Unknown
};

public static readonly Dictionary<HardwareModel, string> FileNameMappings = new()
Expand Down
2 changes: 2 additions & 0 deletions Meshtastic.Cli/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
root.AddCommand(new FactoryResetCommand("factory-reset", "Factory reset configuration of the device", port, host, output, log, dest, selectDest));
root.AddCommand(new FixedPositionCommand("fixed-position", "Set the device to a fixed position", port, host, output, log, dest, selectDest));
root.AddCommand(new SendTextCommand("text", "Send a text message from the device", port, host, output, log, dest, selectDest));
root.AddCommand(new RemoveNodeCommand("remove-node", "Remove single node by nodenum from node db of the device", port, host, output, log, dest, selectDest));
root.AddCommand(new ResetNodeDbCommand("reset-nodedb", "Reset the node db of the device", port, host, output, log, dest, selectDest));
root.AddCommand(new TraceRouteCommand("trace-route", "Trace the sequence of nodes routing to the destination", port, host, output, log, dest, selectDest));
root.AddCommand(new CannedMessagesCommand("canned-messages", "Get or set the collection of canned messages on the device", port, host, output, log, dest, selectDest));
Expand All @@ -62,6 +63,7 @@
root.AddCommand(new ImportCommand("import", "Import the profile export from a yaml file and set the connected device", port, host, output, log));
root.AddCommand(new MqttProxyCommand("mqtt-proxy", "Proxy to the MQTT server referenced in the MQTT module config of the connected device", port, host, output, log));
root.AddCommand(new RequestTelemetryCommand("request-telemetry", "Request a telemetry packet from a repeater by nodenum", port, host, output, log, dest, selectDest));
root.AddCommand(new CaptureCommand("capture", "Capture all of the FromRadio messages for the device and store in MongoDB instance", port, host, output, log));

var parser = new CommandLineBuilder(root)
.UseExceptionHandler((ex, context) =>
Expand Down
4 changes: 4 additions & 0 deletions Meshtastic.Cli/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@
"mqtt": {
"commandName": "Project",
"commandLineArgs": "mqtt-proxy"
},
"remove-node": {
"commandName": "Project",
"commandLineArgs": "remove-node 123456"
}
}
}
1 change: 0 additions & 1 deletion Meshtastic/Data/DeviceStateContainer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Google.Protobuf;
using Meshtastic.Protobufs;
using System.Linq;

namespace Meshtastic.Data;

Expand Down
4 changes: 4 additions & 0 deletions Meshtastic/Data/MessageFactories/AdminMessageFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ public MeshPacket CreateNodeDbResetMessage()
{
return GetNewMeshPacket(new AdminMessage() { NodedbReset = 1 });
}
public MeshPacket CreateRemoveByNodenumMessage(uint nodeNum)
{
return GetNewMeshPacket(new AdminMessage() { RemoveByNodenum = nodeNum });
}
public MeshPacket CreateSetCannedMessage(string message)
{
return GetNewMeshPacket(new AdminMessage() { SetCannedMessageModuleMessages = message });
Expand Down
6 changes: 2 additions & 4 deletions Meshtastic/Extensions/ToRadioExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,8 @@ private static bool IsValidMeshPacket(ToRadio toRadio)
else if (typeof(TResult) == typeof(Waypoint) && toRadio.Packet?.Decoded?.Portnum == PortNum.WaypointApp)
return NodeInfo.Parser.ParseFrom(toRadio.Packet?.Decoded?.Payload) as TResult;

else if (typeof(TResult) == typeof(string) && toRadio.Packet?.Decoded?.Portnum == PortNum.TextMessageApp)
return toRadio.Packet?.Decoded?.Payload.ToStringUtf8() as TResult;

else if (typeof(TResult) == typeof(string) && toRadio.Packet?.Decoded?.Portnum == PortNum.SerialApp)
else if (typeof(TResult) == typeof(string) &&
(toRadio.Packet?.Decoded?.Portnum == PortNum.TextMessageApp || toRadio.Packet?.Decoded?.Portnum == PortNum.DetectionSensorApp || toRadio.Packet?.Decoded?.Portnum == PortNum.RangeTestApp))
return toRadio.Packet?.Decoded?.Payload.ToStringUtf8() as TResult;

return null;
Expand Down
Loading

0 comments on commit ae36bcd

Please sign in to comment.