Skip to content

Commit

Permalink
Merge pull request #16 from OpenIPC/master
Browse files Browse the repository at this point in the history
0.0.2 Release
  • Loading branch information
mikecarr authored Nov 20, 2024
2 parents 33d7230 + 47cc67c commit 094a7b3
Show file tree
Hide file tree
Showing 13 changed files with 125 additions and 23 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build_and_release_all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ jobs:
## What's Changed
- Automatically generated release for version v${{ env.VERSION }}.
- Includes builds for macOS (x64, arm64), Windows (x64, arm64) and Linux (Ubuntu) (x64, arm64)..
- IOS Users, must run 'xattr -cr OpenIPC_Config.app' to remove the quarantine flag. Until this is properly signed.
draft: false
prerelease: false

Expand Down
1 change: 1 addition & 0 deletions OpenIPC_Config/Models/OpenIPC.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public enum FileType
public const string LocalBetaFlightFontsFolder = "binaries/fonts/bf";
public const string LocalINavFontsFolder = "binaries/fonts/inav";

public const string KeyMD5Sum = "24767056dc165963fe6db7794aee12cd";
// public const string LocalFwFolder = "binaries/fw";


Expand Down
2 changes: 2 additions & 0 deletions OpenIPC_Config/Services/ISshClientService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Task<SshCommand> ExecuteCommandWithResponse(DeviceConfig deviceConfig, string co
Task UploadFileStringAsync(DeviceConfig deviceConfig, string remotePath, string fileContent);

// Downloads a file from the remote device and returns its content as a string
Task<byte[]> DownloadFileBytesAsync(DeviceConfig deviceConfig, string remotePath);

Task<string> DownloadFileAsync(DeviceConfig deviceConfig, string remotePath);

// Downloads a file from the remote path to the local path asynchronously using SCP
Expand Down
49 changes: 44 additions & 5 deletions OpenIPC_Config/Services/SshClientService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,44 @@ await Task.Run(() =>
}
});
}

public async Task<byte[]> DownloadFileBytesAsync(DeviceConfig deviceConfig, string remotePath)
{
Log.Information($"Downloading file from '{remotePath}' on {deviceConfig.IpAddress}.");

byte[] fileContent = Array.Empty<byte>(); // Initialize an empty byte array

await Task.Run(() =>
{
var connectionInfo = new ConnectionInfo(deviceConfig.IpAddress, deviceConfig.Port, deviceConfig.Username,
new PasswordAuthenticationMethod(deviceConfig.Username, deviceConfig.Password));
using (var client = new ScpClient(connectionInfo))
{
try
{
client.Connect();
using (var memoryStream = new MemoryStream())
{
// Download the file content into a MemoryStream using ScpClient
client.Download(remotePath, memoryStream);
fileContent = memoryStream.ToArray(); // Get the file content as a byte array
Log.Information("File downloaded successfully.");
}
}
catch (Exception ex)
{
Log.Error($"Error downloading file: {ex.Message}");
}
finally
{
client.Disconnect();
}
}
});

return fileContent; // Return the file content as a byte array
}


/// <summary>
/// Downloads a file from the device at <paramref name="remotePath" /> and returns its content as a string.
Expand All @@ -203,9 +241,9 @@ await Task.Run(() =>
public async Task<string> DownloadFileAsync(DeviceConfig deviceConfig, string remotePath)
{
Log.Information($"Downloading file from '{remotePath}' on {deviceConfig.IpAddress}.");

var fileContent = string.Empty;

await Task.Run(() =>
{
var connectionInfo = new ConnectionInfo(deviceConfig.IpAddress, deviceConfig.Port, deviceConfig.Username,
Expand Down Expand Up @@ -234,7 +272,7 @@ await Task.Run(() =>
}
}
});

return fileContent; // Return the content of the file
}

Expand Down Expand Up @@ -283,8 +321,9 @@ public async Task DownloadFileLocalAsync(DeviceConfig deviceConfig, string remot
{
try
{
var fileContent = await DownloadFileAsync(deviceConfig, remotePath);
if (fileContent.Length != 0) File.WriteAllText(localPath, fileContent);
var fileContentBytes = await DownloadFileAsync(deviceConfig, remotePath);

if (fileContentBytes.Length != 0) File.WriteAllText(localPath, fileContentBytes);
}
catch (Exception ex)
{
Expand Down
21 changes: 21 additions & 0 deletions OpenIPC_Config/Services/Utilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,27 @@ public static string RemoveSpecialCharacters(string input)
return output;
}

public static string ComputeMd5Hash(byte[] rawData)
{
// Use MD5 to compute the hash
using (var md5Hash = MD5.Create())
{
// Compute the hash for the byte array
var bytes = md5Hash.ComputeHash(rawData);

// Convert the bytes to a hexadecimal string
var builder = new StringBuilder();
foreach (var b in bytes)
{
builder.Append(b.ToString("x2"));
}

return builder.ToString();
}
}



public static string ComputeSha256Hash(string rawData)
{
// Create a SHA256 instance
Expand Down
30 changes: 22 additions & 8 deletions OpenIPC_Config/ViewModels/ConnectControlsViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
using System;
using System.IO;
using System.Net;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using Avalonia.Layout;
using Avalonia.Logging;
using Avalonia.Media;
using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
Expand All @@ -20,7 +23,7 @@

namespace OpenIPC_Config.ViewModels;

public class ConnectControlsViewModel : ViewModelBase
public partial class ConnectControlsViewModel : ViewModelBase
{
private readonly CancellationTokenSource? _cancellationTokenSourc;

Expand All @@ -31,7 +34,6 @@ public class ConnectControlsViewModel : ViewModelBase
private readonly SolidColorBrush _onlineColorBrush = new(Colors.Green);
private readonly Ping _ping = new();


private bool _canConnect;

private DeviceConfig _deviceConfig;
Expand Down Expand Up @@ -412,11 +414,19 @@ await MessageBoxManager.GetMessageBoxStandard("Error", "Failed to download /etc/
_eventAggregator.GetEvent<AppMessageEvent>().Publish(new AppMessage { Message = "Downloading gskey" });

var gsKeyContent =
await _sshClientService.DownloadFileAsync(_deviceConfig, Models.OpenIPC.RemoteGsKeyPath);
await _sshClientService.DownloadFileBytesAsync(_deviceConfig, Models.OpenIPC.RemoteGsKeyPath);

if (!string.IsNullOrEmpty(gsKeyContent))
if (gsKeyContent != null)
{
var droneKey = Utilities.ComputeSha256Hash(gsKeyContent);
var droneKey = Utilities.ComputeMd5Hash(gsKeyContent);
if (droneKey != OpenIPC.KeyMD5Sum)
{
Log.Warning("GS key MD5 checksum mismatch");
}
else
{
Log.Information("GS key MD5 checksum matched default key");
}

var deviceContentUpdatedMessage = new DeviceContentUpdatedMessage();
_deviceConfig = DeviceConfig.Instance;
Expand Down Expand Up @@ -484,11 +494,15 @@ private async void processCameraFiles()
{
// get /home/radxa/scripts/screen-mode
var droneKeyContent =
await _sshClientService.DownloadFileAsync(_deviceConfig, Models.OpenIPC.RemoteDroneKeyPath);
await _sshClientService.DownloadFileBytesAsync(_deviceConfig, Models.OpenIPC.RemoteDroneKeyPath);

if (!string.IsNullOrEmpty(droneKeyContent))


if (droneKeyContent != null)
{
var droneKey = Utilities.ComputeSha256Hash(droneKeyContent);
//byte[] fileBytes = Encoding.UTF8.GetBytes(droneKeyContent);

var droneKey = Utilities.ComputeMd5Hash(droneKeyContent);

var deviceContentUpdatedMessage = new DeviceContentUpdatedMessage();
_deviceConfig = DeviceConfig.Instance;
Expand Down
25 changes: 21 additions & 4 deletions OpenIPC_Config/ViewModels/SetupTabViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public partial class SetupTabViewModel : ViewModelBase
[ObservableProperty] private bool _canConnect;
[ObservableProperty] private int _downloadProgress;

[ObservableProperty] private string _chkSumStatusColor;

private readonly IEventAggregator _eventAggregator;

[ObservableProperty] public ObservableCollection<string> _firmwareVersions;
Expand Down Expand Up @@ -68,6 +70,8 @@ public SetupTabViewModel()

KeyChecksum = string.Empty;

ChkSumStatusColor = "Green";

ScanIpLabel = "192.168.1.";

ShowProgressBarCommand = new RelayCommand(() => IsProgressBarVisible = true);
Expand Down Expand Up @@ -97,7 +101,7 @@ public SetupTabViewModel()


public ICommand FirmwareUpdateCommand =>
_firmwareUpdateCommand ??= new RelayCommand(FirmwareUpdate);
_firmwareUpdateCommand ??= new RelayCommand(SysUpgradeFirmwareUpdate);

public ICommand SendDroneKeyCommand =>
_sendDroneKeyCommand ??= new RelayCommand(SendDroneKey);
Expand Down Expand Up @@ -135,7 +139,17 @@ private async void OnDeviceContentUpdate(DeviceContentUpdatedMessage _deviceCont
if (_deviceContentUpdatedMessage != null)
if (_deviceContentUpdatedMessage.DeviceConfig != null)
if (!string.IsNullOrEmpty(_deviceContentUpdatedMessage.DeviceConfig.KeyChksum))
{
KeyChecksum = _deviceContentUpdatedMessage.DeviceConfig.KeyChksum;
if(KeyChecksum != OpenIPC.KeyMD5Sum)
{
ChkSumStatusColor = "Red";
}
else
{
ChkSumStatusColor = "Green";
}
}
}

private void OnAppMessage(AppMessage appMessage)
Expand Down Expand Up @@ -258,15 +272,15 @@ private async void SensorFilesUpdate()

ProgressText = "Starting upload...";
DownloadProgress = 50;
_sshClientService.UploadBinaryAsync(DeviceConfig.Instance, Models.OpenIPC.RemoteSensorsFolder,
await _sshClientService.UploadBinaryAsync(DeviceConfig.Instance, Models.OpenIPC.RemoteSensorsFolder,
Models.OpenIPC.FileType.Sensors, selectedSensor);

ProgressText = "Updating Majestic file...";
DownloadProgress = 75;
// update majestic file
// what is .video0.sensorConfig used for?
//_sshClientService.ExecuteCommandAsync(DeviceConfig.Instance, $"yaml-cli -s .video0.sensorConfig {OpenIPC_Config.RemoteSensorsFolder}/{selectedSensor}");
_sshClientService.ExecuteCommandAsync(DeviceConfig.Instance,
await _sshClientService.ExecuteCommandAsync(DeviceConfig.Instance,
$"yaml-cli -s .isp.sensorConfig {Models.OpenIPC.RemoteSensorsFolder}/{selectedSensor}");

// echo y | pscp -scp -pw %3 sensors/%4 root@%2:/etc/sensors/
Expand All @@ -275,6 +289,9 @@ private async void SensorFilesUpdate()

//_sshClientService.UploadDirectoryAsync(DeviceConfig.Instance, OpenIPC_Config.LocalSensorsFolder,
// OpenIPC_Config.RemoteSensorsFolder);
ProgressText = "Restarting Majestic...";
await _sshClientService.ExecuteCommandAsync(DeviceConfig.Instance,DeviceCommands.MajesticRestartCommand);

ProgressText = "Done updating sensor...";
DownloadProgress = 100;
}
Expand Down Expand Up @@ -501,7 +518,7 @@ await _sshClientService.ExecuteCommandWithProgressAsync(DeviceConfig.Instance,
}


private async void FirmwareUpdate()
private async void SysUpgradeFirmwareUpdate()
{
Log.Debug("FirmwareUpdate executed");
// if "%1" == "sysup" (
Expand Down
1 change: 1 addition & 0 deletions OpenIPC_Config/Views/SetupCameraButtonsView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
<TextBlock Grid.Row="7" Grid.ColumnSpan="2"
TextWrapping="Wrap"
MaxWidth="375"
Foreground="{Binding ChkSumStatusColor}"
Text="{Binding KeyChecksum} " />


Expand Down
3 changes: 2 additions & 1 deletion OpenIPC_Config/Views/SetupRadxaButtonsView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@

<TextBlock Grid.Row="6" FontWeight="Bold" Text="Device Checksum" />
<TextBlock Grid.Row="7" Grid.ColumnSpan="2"
Text="{Binding KeyChecksum}" />
Text="{Binding KeyChecksum}"
Foreground="{Binding ChkSumStatusColor}" />


</Grid>
Expand Down
1 change: 1 addition & 0 deletions OpenIPC_Config/Views/VRXTabView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
<ComboBox Grid.Row="1" Grid.Column="1" Width="250" ItemsSource="{Binding Fps}"
SelectedItem="{Binding SelectedFps,
Mode=TwoWay}" />

<TextBlock Grid.Row="2" Grid.Column="1" FontSize="12"
Text="{Binding DroneKeyChecksum}" />

Expand Down
1 change: 1 addition & 0 deletions OpenIPC_Config/Views/WfbGSTabView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@

<TextBox Grid.Row="3" Grid.Column="1"
Text="{Binding GsMavlink, Mode=TwoWay}" />

<TextBox Grid.Row="4" Grid.Column="1"
Text="{Binding GsVideo, Mode=TwoWay}" />

Expand Down
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ Based off of MarioFPV's [OpenIPC Config](https://github.com/OpenIPC/configurator

[Demo on YouTube](https://www.youtube.com/watch?v=iJXXMcnOC7w)

## TODO:
* Fix UI and views
* Cleanup code
* Add more features
* Android and IOS versions coming soon!


## Features

* **Camera settings management**: configure camera settings such as resolution, frame rate, and exposure
Expand Down Expand Up @@ -38,10 +45,6 @@ Based off of MarioFPV's [OpenIPC Config](https://github.com/OpenIPC/configurator
* Windows: %APPDATA%\OpenIPC_Config\Logs
* Linux: ~/.config/openipc-configurator.log

## TODO:
* Fix UI and views
* Cleanup code
* Add more features

Based on your folder structure, here’s an explanation of each project and what it likely targets:

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.1
0.0.2

0 comments on commit 094a7b3

Please sign in to comment.