196 lines
7.1 KiB
C#
196 lines
7.1 KiB
C#
|
using System.Diagnostics;
|
|||
|
using System.Net.Sockets;
|
|||
|
using CliWrap;
|
|||
|
using CliWrap.Buffered;
|
|||
|
using InnovEnergy.Lib.Protocols.DBus;
|
|||
|
using InnovEnergy.Lib.Protocols.DBus.Daemon;
|
|||
|
using InnovEnergy.Lib.Protocols.DBus.Transport;
|
|||
|
using InnovEnergy.Lib.Utils;
|
|||
|
using InnovEnergy.Lib.Victron.VeDBus;
|
|||
|
|
|||
|
|
|||
|
namespace InnovEnergy.TestBatteryDbus;
|
|||
|
|
|||
|
//Setting up properties
|
|||
|
internal static class Props
|
|||
|
{
|
|||
|
public static VeProperties Properties = new VeProperties();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
public static class Program
|
|||
|
{
|
|||
|
public static Int32 Help()
|
|||
|
{
|
|||
|
Console.WriteLine("Usage: TestDbus name [args]");
|
|||
|
Console.WriteLine("");
|
|||
|
Console.WriteLine("Allowed args:");
|
|||
|
Console.WriteLine(" -f forces the name. only used for com.victronenergy.settings");
|
|||
|
Console.WriteLine(" -h displays this text");
|
|||
|
Console.WriteLine("");
|
|||
|
Console.WriteLine("This program allows you to \"fake\" a process with dbus-connection.");
|
|||
|
Console.WriteLine("It overtakes and duplicates an existing service specified by the first argument name");
|
|||
|
Console.WriteLine("");
|
|||
|
Console.WriteLine("Allowed Commands:");
|
|||
|
Console.WriteLine(" /exit exits the program");
|
|||
|
Console.WriteLine(" /get name gets the value at name");
|
|||
|
Console.WriteLine(" /set name value sets the value at name to value");
|
|||
|
return 0;
|
|||
|
}
|
|||
|
public static async Task<Int32> Main(String[] args)
|
|||
|
{
|
|||
|
if (args.Contains("-h"))
|
|||
|
{
|
|||
|
return Help();
|
|||
|
}
|
|||
|
|
|||
|
var dev = "Release"; //for Debuging change to Debug
|
|||
|
|
|||
|
//Setup DBUS connection
|
|||
|
Console.WriteLine("Setting up Dbus-connection");
|
|||
|
var dbus = new DBusConnection(Bus.System);
|
|||
|
|
|||
|
//Todo Remove me
|
|||
|
if (dev == "Debug")
|
|||
|
{
|
|||
|
var ep = new UnixDomainSocketEndPoint("/home/kim/graber_dbus.sock");
|
|||
|
var auth = AuthenticationMethod.ExternalAsRoot();
|
|||
|
var dbusAddress = new Bus(ep, auth);
|
|||
|
dbus = new DBusConnection(dbusAddress);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//Taking name from args or giving a list of named services to choose from
|
|||
|
var name = args.FirstOrDefault(predicate: (arg) => !arg.StartsWith("-"), await ChooseFromNames(dbus));
|
|||
|
|
|||
|
|
|||
|
//catch settings
|
|||
|
if (name == "com.victronenergy.settings" && !args.Contains("-f"))
|
|||
|
{
|
|||
|
Console.WriteLine("com.victronenergy.settings cannot be simulated as the watchdog would force reboot the system.");
|
|||
|
Console.WriteLine("Use -f to overwrite");
|
|||
|
}
|
|||
|
|
|||
|
// var properties = new VeProperties();
|
|||
|
|
|||
|
//Grab up-to-date dbus items and build mirrored VeProperties
|
|||
|
Console.WriteLine("Success...Grabbing newest settings from:");
|
|||
|
Console.WriteLine(name);
|
|||
|
|
|||
|
// fill properties with preexisting values of the replaced task
|
|||
|
var values = await dbus
|
|||
|
.GetAllValues(name);
|
|||
|
|
|||
|
var texts = await dbus
|
|||
|
.GetAllTexts(name);
|
|||
|
|
|||
|
var keys = values.Keys.Intersect(texts.Keys);
|
|||
|
|
|||
|
foreach (var key in keys)
|
|||
|
{
|
|||
|
//writable true is so our new process will correctly handle set requests
|
|||
|
Props.Properties.Set(key, values[key], text: texts[key], writable: true);
|
|||
|
}
|
|||
|
|
|||
|
//Catch com.victronenergy.settings name
|
|||
|
Console.WriteLine("Success...Catching name and publishing under: ");
|
|||
|
Console.WriteLine(name);
|
|||
|
|
|||
|
//Grabbing process name :1.xx and getting the task process id from that
|
|||
|
var processIdNameOwner = await dbus.GetNameOwner(name);
|
|||
|
var processIdTask = dbus.GetConnectionUnixProcessId(processIdNameOwner);
|
|||
|
Int32 processId = (Int32)await processIdTask;
|
|||
|
|
|||
|
|
|||
|
Console.WriteLine("pid: " + processId);
|
|||
|
|
|||
|
//Setup command accepting loop
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//Queue our task for the name and then kill the old task carrying that name. This should allow us to grab said name and publish to it.
|
|||
|
await dbus.RequestName(name, RequestNameOptions.None);
|
|||
|
|
|||
|
var usurpedProcess = new Process();
|
|||
|
|
|||
|
if (dev == "Debug")
|
|||
|
{
|
|||
|
var result = await Cli.Wrap("ssh").WithArguments($"root@beaglebone kill -9 {processId}").ExecuteBufferedAsync();
|
|||
|
// usurpedProcess = Process.GetProcessById(processId);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
usurpedProcess = Process.GetProcessById(processId);
|
|||
|
usurpedProcess.Kill();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// var commandHandler = new Task(() => {
|
|||
|
// Console.WriteLine("Enter Commands or exit with /exit: ");
|
|||
|
// while (true)
|
|||
|
// {
|
|||
|
// Console.WriteLine("");
|
|||
|
//
|
|||
|
// var cmd = Console.ReadLine()?.ToUpper().Trim();
|
|||
|
//
|
|||
|
// //Get out if the command is invalid or none
|
|||
|
// if (StringUtils.IsNullOrEmpty(cmd)) continue;
|
|||
|
// if (!cmd!.StartsWith("/")) {Help(); continue;}
|
|||
|
//
|
|||
|
// //Handle command and if requested end the program, restart the original service we overtook
|
|||
|
// var exit = ProcessLocalCommand(cmd);
|
|||
|
// if (!exit) continue;
|
|||
|
// if (dev == "Debug")
|
|||
|
// {
|
|||
|
// var result2 = Cli.Wrap("ssh")
|
|||
|
// .WithArguments($"root@beaglebone cd /service && svc -u dbus-fronius") //{usurpedProcess.ProcessName}
|
|||
|
// .ExecuteBufferedAsync();
|
|||
|
// return;
|
|||
|
// }
|
|||
|
// usurpedProcess.Start();
|
|||
|
// return;
|
|||
|
// }});
|
|||
|
|
|||
|
var publishTask = await Props.Properties.PublishOnDBus(dbus);
|
|||
|
|
|||
|
//run publish and command-handler and end the program if exit is called or an exception occurs
|
|||
|
// await Task.WhenAny(commandHandler, publishTask);
|
|||
|
//TODO use second connection for second task
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
private static async Task<String> ChooseFromNames(DBusConnection dbus)
|
|||
|
{
|
|||
|
var names = (await dbus.ListNames()).Where(name => !name.StartsWith(":") && name != "org.freedesktop.DBus").ToList();
|
|||
|
var choice = "Choose name to test as:".ChooseFrom(chooseFrom: names);
|
|||
|
if (choice == null) Environment.Exit(0);
|
|||
|
return choice;
|
|||
|
}
|
|||
|
//
|
|||
|
// private static Boolean ProcessLocalCommand(String cmd)
|
|||
|
// {
|
|||
|
// switch (cmd.Split(" "))
|
|||
|
// {
|
|||
|
// case { } a when a[0] == "/exit":
|
|||
|
// //end program by ending the loop
|
|||
|
// return true;
|
|||
|
//
|
|||
|
// case { } b when b[0] == ("/set"):
|
|||
|
// //set property at first argument to value of second argument
|
|||
|
// Props.Properties.Set(b[1], b[2]);
|
|||
|
// break;
|
|||
|
//
|
|||
|
// case { } c when c[0] == ("/get"):
|
|||
|
// //Get Value of property at first argument
|
|||
|
// Console.WriteLine(Props.Properties.Get(c[1]));
|
|||
|
// break;
|
|||
|
// }
|
|||
|
//
|
|||
|
// //continue the loop
|
|||
|
// return false;
|
|||
|
// }
|
|||
|
}
|
|||
|
|