Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extension v2 prep #516

Merged
merged 2 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions Source/v2/Meadow.CLI.v2.sln
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.Linker", "Meadow.Lin
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.Dfu", "Meadow.Dfu\Meadow.Dfu.csproj", "{6AE8C9EA-87AF-49AC-A63B-9A9416DD76E0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.Package", "Meadow.Package\Meadow.Package.csproj", "{E34A4BFA-1E92-4951-A5F9-B847EAAB05F8}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.Firmware", "Meadow.Firmware\Meadow.Firmware.csproj", "{D2274F30-A001-482A-99E3-0AB1970CF695}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meadow.Firmware", "Meadow.Firmware\Meadow.Firmware.csproj", "{D2274F30-A001-482A-99E3-0AB1970CF695}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meadow.Tooling.Core", "Meadow.Tooling.Core\Meadow.Tooling.Core.csproj", "{A22DBF4A-E472-445E-96C0-930C126039C2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -116,14 +116,14 @@ Global
{6AE8C9EA-87AF-49AC-A63B-9A9416DD76E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6AE8C9EA-87AF-49AC-A63B-9A9416DD76E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6AE8C9EA-87AF-49AC-A63B-9A9416DD76E0}.Release|Any CPU.Build.0 = Release|Any CPU
{E34A4BFA-1E92-4951-A5F9-B847EAAB05F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E34A4BFA-1E92-4951-A5F9-B847EAAB05F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E34A4BFA-1E92-4951-A5F9-B847EAAB05F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E34A4BFA-1E92-4951-A5F9-B847EAAB05F8}.Release|Any CPU.Build.0 = Release|Any CPU
{D2274F30-A001-482A-99E3-0AB1970CF695}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D2274F30-A001-482A-99E3-0AB1970CF695}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D2274F30-A001-482A-99E3-0AB1970CF695}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D2274F30-A001-482A-99E3-0AB1970CF695}.Release|Any CPU.Build.0 = Release|Any CPU
{A22DBF4A-E472-445E-96C0-930C126039C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A22DBF4A-E472-445E-96C0-930C126039C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A22DBF4A-E472-445E-96C0-930C126039C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A22DBF4A-E472-445E-96C0-930C126039C2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
2 changes: 1 addition & 1 deletion Source/v2/Meadow.Cli/Meadow.CLI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
<ItemGroup>
<ProjectReference Include="..\Meadow.Dfu\Meadow.Dfu.csproj" />
<ProjectReference Include="..\Meadow.Linker\Meadow.Linker.csproj" />
<ProjectReference Include="..\Meadow.Package\Meadow.Package.csproj" />
<ProjectReference Include="..\Meadow.Tooling.Core\Meadow.Tooling.Core.csproj" />
<ProjectReference Include="..\Meadow.UsbLibClassic\Meadow.UsbLibClassic.csproj" />
<ProjectReference Include="..\Meadow.UsbLib\Meadow.UsbLib.csproj" />
</ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion Source/v2/Meadow.Cli/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@
},
"Firmware Write version": {
"commandName": "Project",
"commandLineArgs": "firmware write -v 1.9.0.0"
"commandLineArgs": "firmware write -v 1.9.1.7"
},
"Firmware Write runtime": {
"commandName": "Project",
Expand Down
3 changes: 3 additions & 0 deletions Source/v2/Meadow.Linker/Linker/ILLinker.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;

namespace Meadow.Linker
{
Expand Down
5 changes: 5 additions & 0 deletions Source/v2/Meadow.Linker/Linker/MeadowLinker.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
using Microsoft.Extensions.Logging;
using Mono.Cecil;
using Mono.Collections.Generic;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace Meadow.Linker;

Expand Down
1 change: 0 additions & 1 deletion Source/v2/Meadow.Linker/Meadow.Linker.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>10</LangVersion>
</PropertyGroup>
Expand Down
20 changes: 0 additions & 20 deletions Source/v2/Meadow.Package/Meadow.Package.csproj

This file was deleted.

8 changes: 6 additions & 2 deletions Source/v2/Meadow.SoftwareManager/CrcTools.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
namespace Meadow.Software;
using System;
using System.IO;
using System.Threading.Tasks;

namespace Meadow.Software;

public static class CrcTools
{
Expand Down Expand Up @@ -76,4 +80,4 @@ public static async Task<string> CalculateCrc32FileHash(string filePath)
Array.Reverse(checkSum); // make big endian
return BitConverter.ToString(checkSum).Replace("-", "").ToLower();
}
}
}
5 changes: 4 additions & 1 deletion Source/v2/Meadow.SoftwareManager/DownloadFileStream.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
namespace Meadow.Software;
using System;
using System.IO;

namespace Meadow.Software;

internal class DownloadFileStream : Stream, IDisposable
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
namespace Meadow.Software;
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace Meadow.Software;

internal class F7FirmwareDownloadManager
{
Expand Down
10 changes: 8 additions & 2 deletions Source/v2/Meadow.SoftwareManager/F7FirmwarePackageCollection.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
namespace Meadow.Software;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace Meadow.Software;

public class F7FirmwarePackageCollection : IFirmwarePackageCollection
{
Expand All @@ -13,7 +19,7 @@ public class F7FirmwarePackageCollection : IFirmwarePackageCollection

private readonly List<FirmwarePackage> _f7Packages = new();
private FirmwarePackage? _defaultPackage;
private F7FirmwareDownloadManager _downloadManager;
private readonly F7FirmwareDownloadManager _downloadManager;

public string PackageFileRoot { get; }

Expand Down
6 changes: 5 additions & 1 deletion Source/v2/Meadow.SoftwareManager/FileManager.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
namespace Meadow.Software;
using System;
using System.IO;
using System.Threading.Tasks;

namespace Meadow.Software;

public class FileManager
{
Expand Down
4 changes: 3 additions & 1 deletion Source/v2/Meadow.SoftwareManager/FirmwarePackage.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace Meadow.Software;
using System.IO;

namespace Meadow.Software;

public class FirmwarePackage
{
Expand Down
5 changes: 4 additions & 1 deletion Source/v2/Meadow.SoftwareManager/FirmwareStore.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
namespace Meadow.Software;
using System.Collections.Generic;
using System.Linq;

namespace Meadow.Software;

public class FirmwareStore : IEnumerable<IFirmwarePackageCollection>
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
namespace Meadow.Software;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Meadow.Software;

public interface IFirmwarePackageCollection : IEnumerable<FirmwarePackage>
{
Expand All @@ -23,4 +27,4 @@ public interface IFirmwarePackageCollection : IEnumerable<FirmwarePackage>
FirmwarePackage this[int index] { get; }
FirmwarePackage? this[string version] { get; }
string PackageFileRoot { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>10</LangVersion>
</PropertyGroup>
Expand Down
154 changes: 154 additions & 0 deletions Source/v2/Meadow.Tooling.Core/App/AppManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
using Meadow.Hcom;
using Meadow.Linker;
using Meadow.Package;
using Meadow.Software;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Meadow.CLI;

public static class AppManager
{
private static bool MatchingDllExists(string file)
{
return File.Exists(Path.ChangeExtension(file, ".dll"));
}

private static bool IsPdb(string file)
{
return string.Compare(Path.GetExtension(file), ".pdb", StringComparison.OrdinalIgnoreCase) == 0;
}

private static bool IsXmlDoc(string file)
{
if (string.Compare(Path.GetExtension(file), ".xml", StringComparison.OrdinalIgnoreCase) == 0)
{
return MatchingDllExists(file);
}
return false;
}

public static async Task DeployApplication(
IPackageManager packageManager,
IMeadowConnection connection,
string localBinaryDirectory,
bool includePdbs,
bool includeXmlDocs,
ILogger? logger,
CancellationToken cancellationToken)
{
// TODO: add sub-folder support when HCOM supports it
var localFiles = new Dictionary<string, uint>();

var dependencies = new List<string>();

var processedAppPath = localBinaryDirectory;

//check if there's a post link folder
if (Directory.Exists(Path.Combine(localBinaryDirectory, MeadowLinker.PostLinkDirectoryName)))
{
processedAppPath = Path.Combine(localBinaryDirectory, MeadowLinker.PostLinkDirectoryName);

//add all dlls from the postlink_bin folder to the dependencies
dependencies = Directory.EnumerateFiles(processedAppPath, "*.dll", SearchOption.TopDirectoryOnly).ToList();
dependencies.Remove(Path.Combine(processedAppPath, "App.dll"));

//add all pdbs from the postlink_bin folder to the dependencies if includePdbs is true
if (includePdbs)
{
dependencies.AddRange(Directory.EnumerateFiles(processedAppPath, "*.pdb", SearchOption.TopDirectoryOnly));
dependencies.Remove(Path.Combine(processedAppPath, "App.pdb"));
}
}
else
{
dependencies = packageManager.GetDependencies(new FileInfo(Path.Combine(processedAppPath, "App.dll")));
}
dependencies.Add(Path.Combine(localBinaryDirectory, "App.dll"));

if (includePdbs)
{
dependencies.Add(Path.Combine(localBinaryDirectory, "App.pdb"));
}

var binaries = Directory.EnumerateFiles(localBinaryDirectory, "*.*", SearchOption.TopDirectoryOnly)
.Where(s => new FileInfo(s).Extension != ".dll")
.Where(s => new FileInfo(s).Extension != ".pdb")
.Where(s => !s.Contains(".DS_Store")).ToList();
dependencies.AddRange(binaries);

logger?.LogInformation("Generating list of files to deploy...");

foreach (var file in dependencies)
{
// TODO: add any other filtering capability here
if (!includePdbs && IsPdb(file)) { continue; }
if (!includeXmlDocs && IsXmlDoc(file)) { continue; }

// read the file data so we can generate a CRC
using FileStream fs = File.Open(file, FileMode.Open);
var len = (int)fs.Length;
var bytes = new byte[len];

await fs.ReadAsync(bytes, 0, len, cancellationToken);

var crc = CrcTools.Crc32part(bytes, len, 0);

localFiles.Add(file, crc);
}

if (localFiles.Count == 0)
{
logger?.LogInformation($"No new files to deploy");
}

// get a list of files on-device, with CRCs
var deviceFiles = await connection.GetFileList("/meadow0/", true, cancellationToken) ?? Array.Empty<MeadowFileInfo>();

// get a list of files of the device files that are not in the list we intend to deploy
var removeFiles = deviceFiles
.Select(f => Path.GetFileName(f.Name))
.Except(localFiles.Keys
.Select(f => Path.GetFileName(f))).ToList();

// delete those files
foreach (var file in removeFiles)
{
logger?.LogInformation($"Deleting file '{file}'...");
await connection.DeleteFile(file, cancellationToken);
}

// now send all files with differing CRCs
foreach (var localFile in localFiles)
{
var existing = deviceFiles.FirstOrDefault(f => Path.GetFileName(f.Name) == Path.GetFileName(localFile.Key));

if (existing != null && existing.Crc != null)
{
var crc = uint.Parse(existing.Crc.Substring(2), System.Globalization.NumberStyles.HexNumber);

if (crc == localFile.Value)
{ // exists and has a matching CRC, skip it
continue;
}
}

send_file:

if (!await connection.WriteFile(localFile.Key, null, cancellationToken))
{
logger?.LogWarning($"Error sending'{Path.GetFileName(localFile.Key)}' - retrying");
await Task.Delay(100);
goto send_file;
}
}

//on macOS, if we don't write a blank line we lose the writing notifcation for the last file
logger?.LogInformation(string.Empty);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
using Meadow.Hcom;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Management;
using System.Net;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;

namespace Meadow.CLI.Commands.DeviceManagement;

Expand Down Expand Up @@ -52,9 +58,13 @@ public MeadowConnectionManager(ISettingsManager settingsManager)
{
uri = $"http://{route}:5000";
}
else if (IPEndPoint.TryParse(route, out var endpoint))
else
{
uri = $"http://{route}";
var parts = route.Split(':');
if (parts.Length == 2 && IPAddress.TryParse(parts[0], out ipAddress) && int.TryParse(parts[1], out var port))
{
uri = $"http://{parts[0]}:{port}"; // Construct URI with specified IP and port
}
}

if (uri != null)
Expand Down
Loading
Loading