diff --git a/Source/v2/Meadow.CLI/Commands/Current/App/AppTools.cs b/Source/v2/Meadow.CLI/Commands/Current/App/AppTools.cs index 82282f8e..2b3cd793 100644 --- a/Source/v2/Meadow.CLI/Commands/Current/App/AppTools.cs +++ b/Source/v2/Meadow.CLI/Commands/Current/App/AppTools.cs @@ -42,6 +42,7 @@ internal static async Task DisableRuntimeIfEnabled(IMeadowConnection connection, internal static async Task TrimApplication(string path, IPackageManager packageManager, string? configuration, + IEnumerable? noLinkAssemblies, ILogger? logger, IConsole? console, CancellationToken cancellationToken) @@ -80,8 +81,12 @@ internal static async Task TrimApplication(string path, } logger?.LogInformation($"Trimming application {file.FullName}..."); + if (noLinkAssemblies != null && noLinkAssemblies.Count() > 0) + { + logger?.LogInformation($"Skippping assemblies: {string.Join(", ", noLinkAssemblies)}"); + } - await packageManager.TrimApplication(file, false, null, cancellationToken); + await packageManager.TrimApplication(file, false, noLinkAssemblies, cancellationToken); cts.Cancel(); // illink returns before all files are written - attempt a delay of 1s diff --git a/Source/v2/Meadow.CLI/Commands/Current/Uart/UartProfilerEnableCommand.cs b/Source/v2/Meadow.CLI/Commands/Current/Uart/UartProfilerEnableCommand.cs index c1256e83..ea554128 100644 --- a/Source/v2/Meadow.CLI/Commands/Current/Uart/UartProfilerEnableCommand.cs +++ b/Source/v2/Meadow.CLI/Commands/Current/Uart/UartProfilerEnableCommand.cs @@ -18,17 +18,19 @@ public UartProfilerEnableCommand(MeadowConnectionManager connectionManager, ILog : base(connectionManager, loggerFactory) { } - private void StartNewFile(string outputPath, ref FileStream outputFile, byte[] header, ref int headerIndex, ref int totalBytesWritten, ref int headerFileCount) + private void StartNewFile(string outputPath, FileStream? outputFile, byte[] header, ref int headerIndex, ref int totalBytesWritten, ref int headerFileCount) { if (outputFile != null) { outputFile.Close(); outputFile.Dispose(); } + outputFile = new FileStream(outputPath, FileMode.Create); totalBytesWritten = 0; headerIndex = 0; headerFileCount++; + foreach (var headerByte in header) { outputFile.WriteByte(headerByte); @@ -50,7 +52,7 @@ private void ReadAndSaveSerialData() var outputPath = Path.Combine(outputDirectory, "output.mlpd"); SerialPort port = new SerialPort(SerialInterface, SerialConnection.DefaultBaudRate); - FileStream outputFile = null; + FileStream? outputFile = null; try { @@ -72,7 +74,7 @@ private void ReadAndSaveSerialData() if (headerIndex == header.Length) { Logger?.LogInformation($"Profiling data header found! Writing to {outputPath}..."); - StartNewFile(outputPath, ref outputFile, header, ref headerIndex, ref totalBytesWritten, ref headerFileCount); + StartNewFile(outputPath, outputFile, header, ref headerIndex, ref totalBytesWritten, ref headerFileCount); } } else @@ -84,7 +86,7 @@ private void ReadAndSaveSerialData() else { // Writing to file after a header is found - outputFile.WriteByte((byte)data); + outputFile?.WriteByte((byte)data); totalBytesWritten++; // Check for a new header while writing to a file @@ -97,7 +99,7 @@ private void ReadAndSaveSerialData() // to avoid corrupted profiling data (e.g. device reset while profiling) var newOutputPath = outputDirectory + "output_" + headerFileCount + ".mlpd"; Logger?.LogInformation($"New profiling data header found! Writing to {newOutputPath}..."); - StartNewFile(newOutputPath, ref outputFile, header, ref headerIndex, ref totalBytesWritten, ref headerFileCount); + StartNewFile(newOutputPath, outputFile, header, ref headerIndex, ref totalBytesWritten, ref headerFileCount); } } else diff --git a/Source/v2/Meadow.Cli/AppManager.cs b/Source/v2/Meadow.Cli/AppManager.cs deleted file mode 100644 index 39978447..00000000 --- a/Source/v2/Meadow.Cli/AppManager.cs +++ /dev/null @@ -1,148 +0,0 @@ -using Meadow.Hcom; -using Meadow.Linker; -using Meadow.Package; -using Meadow.Software; -using Microsoft.Extensions.Logging; - -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(); - - var dependencies = new List(); - - 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(); - - // 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); - } -} \ No newline at end of file diff --git a/Source/v2/Meadow.Cli/Commands/Current/App/AppBuildCommand.cs b/Source/v2/Meadow.Cli/Commands/Current/App/AppBuildCommand.cs index 36fd6f92..93bc253e 100644 --- a/Source/v2/Meadow.Cli/Commands/Current/App/AppBuildCommand.cs +++ b/Source/v2/Meadow.Cli/Commands/Current/App/AppBuildCommand.cs @@ -21,7 +21,7 @@ public AppBuildCommand(IPackageManager packageManager, ILoggerFactory loggerFact _packageManager = packageManager; } - protected override async ValueTask ExecuteCommand() + protected override ValueTask ExecuteCommand() { var path = AppTools.ValidateAndSanitizeAppPath(Path); @@ -39,5 +39,7 @@ protected override async ValueTask ExecuteCommand() { Logger?.LogInformation($"Build successful"); } + + return default; } } \ No newline at end of file diff --git a/Source/v2/Meadow.Cli/Commands/Current/App/AppRunCommand.cs b/Source/v2/Meadow.Cli/Commands/Current/App/AppRunCommand.cs index f83ade9c..b919e1bf 100644 --- a/Source/v2/Meadow.Cli/Commands/Current/App/AppRunCommand.cs +++ b/Source/v2/Meadow.Cli/Commands/Current/App/AppRunCommand.cs @@ -20,6 +20,9 @@ public class AppRunCommand : BaseDeviceCommand [CommandParameter(0, Description = Strings.PathMeadowApplication, IsRequired = false)] public string? Path { get; init; } + [CommandOption("nolink", Description = Strings.NoLinkAssemblies, IsRequired = false)] + public string[]? NoLink { get; private set; } + public AppRunCommand(IPackageManager packageManager, MeadowConnectionManager connectionManager, ILoggerFactory loggerFactory) : base(connectionManager, loggerFactory) { @@ -46,7 +49,7 @@ protected override async ValueTask ExecuteCommand() throw new CommandException("Application build failed", CommandExitCode.GeneralError); } - if (!await AppTools.TrimApplication(path, _packageManager, Configuration, Logger, Console, CancellationToken)) + if (!await AppTools.TrimApplication(path, _packageManager, Configuration, NoLink, Logger, Console, CancellationToken)) { throw new CommandException("Application trimming failed", CommandExitCode.GeneralError); } diff --git a/Source/v2/Meadow.Cli/Commands/Current/App/AppTrimCommand.cs b/Source/v2/Meadow.Cli/Commands/Current/App/AppTrimCommand.cs index e912913d..f27d7eef 100644 --- a/Source/v2/Meadow.Cli/Commands/Current/App/AppTrimCommand.cs +++ b/Source/v2/Meadow.Cli/Commands/Current/App/AppTrimCommand.cs @@ -15,6 +15,9 @@ public class AppTrimCommand : BaseCommand [CommandParameter(0, Description = Strings.PathToMeadowProject, IsRequired = false)] public string? Path { get; init; } + [CommandOption("nolink", Description = Strings.NoLinkAssemblies, IsRequired = false)] + public string[]? NoLink { get; private set; } + public AppTrimCommand(IPackageManager packageManager, ILoggerFactory loggerFactory) : base(loggerFactory) { @@ -34,7 +37,7 @@ protected override async ValueTask ExecuteCommand() } } - await AppTools.TrimApplication(path, _packageManager, Configuration, Logger, Console, CancellationToken); + await AppTools.TrimApplication(path, _packageManager, Configuration, NoLink, Logger, Console, CancellationToken); Logger.LogInformation("Application trimmed successfully"); } } \ No newline at end of file diff --git a/Source/v2/Meadow.Cli/Commands/Current/Config/ConfigCommand.cs b/Source/v2/Meadow.Cli/Commands/Current/Config/ConfigCommand.cs index c59f0346..98a1f516 100644 --- a/Source/v2/Meadow.Cli/Commands/Current/Config/ConfigCommand.cs +++ b/Source/v2/Meadow.Cli/Commands/Current/Config/ConfigCommand.cs @@ -12,7 +12,7 @@ public class ConfigCommand : BaseSettingsCommand [CommandParameter(0, Name = "Settings", IsRequired = false)] public string[]? Settings { get; init; } - public ConfigCommand(ISettingsManager settingsManager, ILoggerFactory? loggerFactory) + public ConfigCommand(ISettingsManager settingsManager, ILoggerFactory loggerFactory) : base(settingsManager, loggerFactory) { } diff --git a/Source/v2/Meadow.Cli/Commands/Current/Firmware/FirmwareWriteCommand.cs b/Source/v2/Meadow.Cli/Commands/Current/Firmware/FirmwareWriteCommand.cs index 0f52cc94..2442e995 100644 --- a/Source/v2/Meadow.Cli/Commands/Current/Firmware/FirmwareWriteCommand.cs +++ b/Source/v2/Meadow.Cli/Commands/Current/Firmware/FirmwareWriteCommand.cs @@ -41,9 +41,9 @@ public FirmwareWriteCommand(ISettingsManager settingsManager, FileManager fileMa private int _lastWriteProgress = 0; - private async Task GetConnectionAndDisableRuntime(string? route = null) + private async Task GetConnectionAndDisableRuntime(string? route = null) { - IMeadowConnection? connection = null; + IMeadowConnection connection; if (route != null) { @@ -54,7 +54,7 @@ public FirmwareWriteCommand(ISettingsManager settingsManager, FileManager fileMa connection = await GetCurrentConnection(true); } - if (await connection.Device.IsRuntimeEnabled()) + if (await connection.Device!.IsRuntimeEnabled()) { Logger?.LogInformation($"{Strings.DisablingRuntime}..."); await connection.Device.RuntimeDisable(); @@ -93,11 +93,13 @@ public FirmwareWriteCommand(ISettingsManager settingsManager, FileManager fileMa private bool RequiresDfuForRuntimeUpdates(DeviceInfo info) { return true; - + /* + restore this when we support OtA-style updates again if (System.Version.TryParse(info.OsVersion, out var version)) { return version.Major >= 2; } + */ } private bool RequiresDfuForEspUpdates(DeviceInfo info) @@ -191,12 +193,14 @@ protected override async ValueTask ExecuteCommand() // get a list of ports - it will not have our meadow in it (since it should be in DFU mode) var initialPorts = await MeadowConnectionManager.GetSerialPorts(); - if (await WriteOsWithDfu(dfuDevice, osFileWithBootloader) == false) + try { - throw new CommandException(Strings.DfuWriteFailed); + await WriteOsWithDfu(dfuDevice, osFileWithBootloader!); + } + finally + { + dfuDevice?.Dispose(); } - - dfuDevice?.Dispose(); await Task.Delay(1500); @@ -248,7 +252,7 @@ protected override async ValueTask ExecuteCommand() Logger?.LogInformation(Strings.FirmwareUpdatedSuccessfully); } - async Task FindMeadowConnection(IList portsToIgnore) + private async Task FindMeadowConnection(IList portsToIgnore) { IMeadowConnection? connection = null; @@ -282,7 +286,7 @@ async Task FindMeadowConnection(IList portsToIgnore) } } - Logger?.LogInformation($"Meadow found at {newPort}"); + Logger?.LogInformation($"{Strings.MeadowFoundAt} {newPort}"); connection = await GetConnectionAndDisableRuntime(); @@ -296,7 +300,9 @@ async Task FindMeadowConnection(IList portsToIgnore) private async Task WriteRuntime(IMeadowConnection? connection, DeviceInfo? deviceInfo, FirmwarePackage package) { - Logger?.LogInformation($"{Environment.NewLine}Getting runtime for {package.Version}..."); + Logger?.LogInformation($"{Environment.NewLine}{Strings.GettingRuntimeFor} {package.Version}..."); + + if (package.Runtime == null) { return null; } // get the path to the runtime file var rtpath = package.GetFullyQualifiedPath(package.Runtime); @@ -308,10 +314,15 @@ async Task FindMeadowConnection(IList portsToIgnore) { connection ??= await GetConnectionAndDisableRuntime(); - Logger?.LogInformation($"{Environment.NewLine}Writing Runtime ..."); + Logger?.LogInformation($"{Environment.NewLine}{Strings.WritingRuntime} ..."); deviceInfo ??= await connection.GetDeviceInfo(CancellationToken); + if (deviceInfo == null) + { + throw new CommandException(Strings.UnableToGetDeviceInfo); + } + if (UseDfu || RequiresDfuForRuntimeUpdates(deviceInfo)) { var initialPorts = await MeadowConnectionManager.GetSerialPorts(); @@ -320,7 +331,7 @@ async Task FindMeadowConnection(IList portsToIgnore) if (!await connection!.Device!.WriteRuntime(runtimePath, CancellationToken)) { // TODO: implement a retry timeout - Logger?.LogInformation($"Error writing runtime - retrying"); + Logger?.LogInformation($"{Strings.ErrorWritingRuntime} - {Strings.Retrying}"); goto write_runtime; } @@ -330,14 +341,14 @@ async Task FindMeadowConnection(IList portsToIgnore) { var newPort = await WaitForNewSerialPort(initialPorts); - if (newPort != null) + if (newPort == null) { throw CommandException.MeadowDeviceNotFound; } connection = await GetCurrentConnection(true); - Logger?.LogInformation($"Meadow found at {newPort}"); + Logger?.LogInformation($"{Strings.MeadowFoundAt} {newPort}"); // configure the route to that port for the user Settings.SaveSetting(SettingsManager.PublicSettings.Route, newPort); @@ -357,7 +368,7 @@ private async Task WriteEspFiles(IMeadowConnection? connection, DeviceInfo? devi if (connection == null) { return; } // couldn't find a connected device - Logger?.LogInformation($"{Environment.NewLine}Writing Coprocessor files..."); + Logger?.LogInformation($"{Environment.NewLine}{Strings.WritingCoprocessorFiles}..."); string[] fileList; @@ -377,6 +388,8 @@ private async Task WriteEspFiles(IMeadowConnection? connection, DeviceInfo? devi deviceInfo ??= await connection.GetDeviceInfo(CancellationToken); + if (deviceInfo == null) { throw new CommandException(Strings.UnableToGetDeviceInfo); } + if (UseDfu || RequiresDfuForEspUpdates(deviceInfo)) { await connection.Device!.WriteCoprocessorFiles(fileList, CancellationToken); @@ -425,7 +438,7 @@ private async Task WriteEspFiles(IMeadowConnection? connection, DeviceInfo? devi return devices[0]; } } - throw new CommandException("Multiple devices found in bootloader mode - only connect one device"); + throw new CommandException(Strings.MultipleDfuDevicesFound); } private async Task GetSelectedPackage() @@ -442,14 +455,14 @@ private async Task WriteEspFiles(IMeadowConnection? connection, DeviceInfo? devi if (existing == null) { - Logger?.LogError($"Requested firmware version '{Version}' not found"); + Logger?.LogError(string.Format(Strings.SpecifiedFirmwareVersionNotFound, Version)); return null; } package = existing; } else { - Version = collection.DefaultPackage?.Version ?? throw new CommandException("No default version set"); + Version = collection.DefaultPackage?.Version ?? throw new CommandException($"{Strings.NoDefaultVersionSet}. {Strings.UseCommandFirmwareDefault}."); package = collection.DefaultPackage; } @@ -457,19 +470,16 @@ private async Task WriteEspFiles(IMeadowConnection? connection, DeviceInfo? devi return package; } - private async Task WriteOsWithDfu(ILibUsbDevice? libUsbDevice, string osFile) + private async Task WriteOsWithDfu(ILibUsbDevice? libUsbDevice, string osFile) { // get the device's serial number via DFU - we'll need it to find the device after it resets if (libUsbDevice == null) { - try - { - libUsbDevice = GetLibUsbDeviceForCurrentEnvironment(); - } - catch (Exception ex) + libUsbDevice = GetLibUsbDeviceForCurrentEnvironment(); + + if (libUsbDevice == null) { - Logger?.LogError(ex.Message); - return false; + throw new CommandException(Strings.NoDfuDeviceDetected); } } @@ -479,8 +489,7 @@ private async Task WriteOsWithDfu(ILibUsbDevice? libUsbDevice, string osFi } catch { - Logger?.LogError("Firmware write failed - unable to read device serial number (make sure device is connected)"); - return false; + throw new CommandException($"{Strings.FirmwareWriteFailed} - {Strings.UnableToReadSerialNumber} ({Strings.MakeSureDeviceisConnected})"); } try @@ -493,8 +502,7 @@ await DfuUtils.FlashFile( } catch (ArgumentException) { - Logger?.LogWarning("Unable to write firmware - is Dfu-util installed? Run `meadow dfu install` to install"); - return false; + throw new CommandException($"{Strings.FirmwareWriteFailed} - {Strings.IsDfuUtilInstalled} {Strings.RunMeadowDfuInstall}"); } catch (Exception ex) { @@ -504,13 +512,11 @@ await DfuUtils.FlashFile( // TODO: catch the Win10 DFU error here and change the global provider configuration to "classic" Settings.SaveSetting(SettingsManager.PublicSettings.LibUsb, "classic"); - Logger?.LogWarning("This machine requires an older version of LibUsb. The CLI settings have been updated, re-run the 'firmware write' command to update your device."); - return false; + throw new CommandException("This machine requires an older version of LibUsb. The CLI settings have been updated, re-run the 'firmware write' command to update your device."); } - return true; } - private async Task> WaitForNewSerialPorts(IList ignorePorts) + private async Task> WaitForNewSerialPorts(IList? ignorePorts) { var ports = await MeadowConnectionManager.GetSerialPorts(); @@ -520,16 +526,20 @@ private async Task> WaitForNewSerialPorts(IList ignorePort { if (retryCount++ > 10) { - throw new CommandException("New meadow device not found"); + throw new CommandException(Strings.NewMeadowDeviceNotFound); } await Task.Delay(500); ports = await MeadowConnectionManager.GetSerialPorts(); } - return ports.Except(ignorePorts).ToList(); + if (ignorePorts != null) + { + return ports.Except(ignorePorts).ToList(); + } + return ports.ToList(); } - private async Task WaitForNewSerialPort(IList? ignorePorts) + private async Task WaitForNewSerialPort(IList? ignorePorts) { var ports = await WaitForNewSerialPorts(ignorePorts); diff --git a/Source/v2/Meadow.Cli/Meadow.CLI.csproj b/Source/v2/Meadow.Cli/Meadow.CLI.csproj index 7cb7bfff..ddd9e3f3 100644 --- a/Source/v2/Meadow.Cli/Meadow.CLI.csproj +++ b/Source/v2/Meadow.Cli/Meadow.CLI.csproj @@ -10,7 +10,7 @@ Wilderness Labs, Inc Wilderness Labs, Inc true - 2.0.21.0 + 2.0.22.0 AnyCPU http://developer.wildernesslabs.co/Meadow/Meadow.CLI/ https://github.com/WildernessLabs/Meadow.CLI diff --git a/Source/v2/Meadow.Cli/Properties/AssemblyInfo.cs b/Source/v2/Meadow.Cli/Properties/AssemblyInfo.cs index e2a618a5..f4b93480 100644 --- a/Source/v2/Meadow.Cli/Properties/AssemblyInfo.cs +++ b/Source/v2/Meadow.Cli/Properties/AssemblyInfo.cs @@ -6,6 +6,6 @@ namespace Meadow.CLI { public static class Constants { - public const string CLI_VERSION = "2.0.21.0"; + public const string CLI_VERSION = "2.0.22.0"; } } \ No newline at end of file diff --git a/Source/v2/Meadow.Cli/Properties/launchSettings.json b/Source/v2/Meadow.Cli/Properties/launchSettings.json index 49567f05..ec710b97 100644 --- a/Source/v2/Meadow.Cli/Properties/launchSettings.json +++ b/Source/v2/Meadow.Cli/Properties/launchSettings.json @@ -181,7 +181,7 @@ }, "App Trim": { "commandName": "Project", - "commandLineArgs": "app trim \"H:\\AS\\BlockPuzzleGenerator\\src\\MeadowBoulderScape\\\"" + "commandLineArgs": "app trim C:\\repos\\wilderness\\Meadow.Core.Samples\\Source\\Blinky\\BlinkyCS --nolink Meadow.Core Meadow.Contracts" }, "Dfu Install": { "commandName": "Project", diff --git a/Source/v2/Meadow.Cli/Strings.cs b/Source/v2/Meadow.Cli/Strings.cs index f99dd632..ea7c7c59 100644 --- a/Source/v2/Meadow.Cli/Strings.cs +++ b/Source/v2/Meadow.Cli/Strings.cs @@ -8,6 +8,7 @@ public static class Strings public const string InvalidApplicationPath = "Invalid application path"; public const string InvalidParameter = "Invalid parameter"; public const string GettingDeviceInfo = "Getting device info..."; + public const string UnableToGetDeviceInfo = "Unable to get device info"; public const string RetrievingUserAndOrgInfo = "Retrieving your user and organization information..."; public const string MemberOfMoreThanOneOrg = "You are a member of more than 1 organization. Please specify the desired orgId for this device provisioning."; public const string UnableToFindMatchingOrg = "Unable to find an organization with a Name or ID matching '{0}'"; @@ -43,4 +44,21 @@ public static class Strings public const string BuildConfiguration = "The build configuration"; public const string PathMeadowApplication = "Path to the Meadow application"; public const string PathToMeadowProject = "Path to the Meadow project file"; + public const string NoLinkAssemblies = "Assemblies to skip during linking"; + public const string WritingCoprocessorFiles = "Writing Coprocessor files"; + public const string MeadowFoundAt = "Meadow found at"; + public const string GettingRuntimeFor = "Getting runtime for"; + public const string WritingRuntime = "Writing runtime for"; + public const string ErrorWritingRuntime = "Error writing runtime for"; + public const string Retrying = "retrying"; + public const string MultipleDfuDevicesFound = "Multiple devices found in bootloader mode - only connect one device"; + public const string SpecifiedFirmwareVersionNotFound = "Requested firmware version '{0}' not found"; + public const string NoDefaultVersionSet = "No default version set"; + public const string UseCommandFirmwareDefault = "Use 'meadow firmare default' to set a default version"; + public const string FirmwareWriteFailed = "Firmware write failed"; + public const string UnableToReadSerialNumber = "unable to read device serial number"; + public const string MakeSureDeviceisConnected = "make sure a device is connected"; + public const string IsDfuUtilInstalled = "Is dfu-util installed?"; + public const string RunMeadowDfuInstall = "Run 'meadow dfu install' to install"; + public const string NewMeadowDeviceNotFound = "New Meadow device not found"; } \ No newline at end of file diff --git a/Source/v2/Meadow.Cloud.Client/Devices/AddDeviceRequest.cs b/Source/v2/Meadow.Cloud.Client/Devices/AddDeviceRequest.cs index b0aacbf4..a548bf59 100644 --- a/Source/v2/Meadow.Cloud.Client/Devices/AddDeviceRequest.cs +++ b/Source/v2/Meadow.Cloud.Client/Devices/AddDeviceRequest.cs @@ -1,7 +1,14 @@ namespace Meadow.Cloud.Client.Devices; -public class AddDeviceRequest(string id, string orgId, string publicKey) +public class AddDeviceRequest { + public AddDeviceRequest(string id, string orgId, string publicKey) + { + Id = id; + OrgId = orgId; + PublicKey = publicKey; + } + public AddDeviceRequest(string id, string name, string orgId, string publicKey) : this(id, orgId, publicKey) { @@ -9,24 +16,23 @@ public AddDeviceRequest(string id, string name, string orgId, string publicKey) } public AddDeviceRequest(string id, string name, string orgId, string collectionId, string publicKey) - : this(id, orgId, publicKey) + : this(id, name, orgId, publicKey) { - Name = name; CollectionId = collectionId; } [JsonPropertyName("id")] - public string Id { get; set; } = id; + public string Id { get; set; } [JsonPropertyName("name")] public string? Name { get; set; } [JsonPropertyName("orgId")] - public string OrgId { get; set; } = orgId; + public string OrgId { get; set; } [JsonPropertyName("collectionId")] public string? CollectionId { get; set; } [JsonPropertyName("publicKey")] - public string PublicKey { get; set; } = publicKey; + public string PublicKey { get; set; } } diff --git a/Source/v2/Meadow.Cloud.Client/Devices/AddDeviceResponse.cs b/Source/v2/Meadow.Cloud.Client/Devices/AddDeviceResponse.cs index 529576da..4894fb76 100644 --- a/Source/v2/Meadow.Cloud.Client/Devices/AddDeviceResponse.cs +++ b/Source/v2/Meadow.Cloud.Client/Devices/AddDeviceResponse.cs @@ -1,16 +1,24 @@ namespace Meadow.Cloud.Client.Devices; -public class AddDeviceResponse(string id, string name, string orgId, string collectionId) +public class AddDeviceResponse { + public AddDeviceResponse(string id, string name, string orgId, string collectionId) + { + Id = id; + Name = name; + OrgId = orgId; + CollectionId = collectionId; + } + [JsonPropertyName("id")] - public string Id { get; set; } = id; + public string Id { get; set; } [JsonPropertyName("name")] - public string? Name { get; set; } = name; + public string? Name { get; set; } [JsonPropertyName("orgId")] - public string OrgId { get; set; } = orgId; + public string OrgId { get; set; } [JsonPropertyName("collectionId")] - public string? CollectionId { get; set; } = collectionId; + public string? CollectionId { get; set; } } \ No newline at end of file diff --git a/Source/v2/Meadow.Cloud.Client/Firmware/FirmwareClient.cs b/Source/v2/Meadow.Cloud.Client/Firmware/FirmwareClient.cs index e6ab9142..452d27e6 100644 --- a/Source/v2/Meadow.Cloud.Client/Firmware/FirmwareClient.cs +++ b/Source/v2/Meadow.Cloud.Client/Firmware/FirmwareClient.cs @@ -1,4 +1,6 @@ -namespace Meadow.Cloud.Client.Firmware; +using System.Linq; + +namespace Meadow.Cloud.Client.Firmware; public class FirmwareClient : MeadowCloudClientBase, IFirmwareClient { @@ -19,7 +21,7 @@ public async Task> GetVersions(string t if (response.StatusCode == HttpStatusCode.NotFound) { - return []; + return Enumerable.Empty(); } return await ProcessResponse>(response, cancellationToken); diff --git a/Source/v2/Meadow.Cloud.Client/Firmware/GetFirmwareVersionResponse.cs b/Source/v2/Meadow.Cloud.Client/Firmware/GetFirmwareVersionResponse.cs index ad1a2e88..f377cc68 100644 --- a/Source/v2/Meadow.Cloud.Client/Firmware/GetFirmwareVersionResponse.cs +++ b/Source/v2/Meadow.Cloud.Client/Firmware/GetFirmwareVersionResponse.cs @@ -1,16 +1,24 @@ namespace Meadow.Cloud.Client.Firmware; -public class GetFirmwareVersionResponse(string version, string minCLIVersion, string downloadUrl, string networkDownloadUrl) +public class GetFirmwareVersionResponse { + public GetFirmwareVersionResponse(string version, string minCLIVersion, string downloadUrl, string networkDownloadUrl) + { + Version = version; + MinCLIVersion = minCLIVersion; + DownloadUrl = downloadUrl; + NetworkDownloadUrl = networkDownloadUrl; + } + [JsonPropertyName("version")] - public string Version { get; set; } = version; + public string Version { get; set; } [JsonPropertyName("minCLIVersion")] - public string MinCLIVersion { get; set; } = minCLIVersion; + public string MinCLIVersion { get; set; } [JsonPropertyName("downloadUrl")] - public string DownloadUrl { get; set; } = downloadUrl; + public string DownloadUrl { get; set; } [JsonPropertyName("networkDownloadUrl")] - public string NetworkDownloadUrl { get; set; } = networkDownloadUrl; + public string NetworkDownloadUrl { get; set; } } diff --git a/Source/v2/Meadow.Cloud.Client/Firmware/GetFirmwareVersionsResponse.cs b/Source/v2/Meadow.Cloud.Client/Firmware/GetFirmwareVersionsResponse.cs index 6a4e066a..f3bf5561 100644 --- a/Source/v2/Meadow.Cloud.Client/Firmware/GetFirmwareVersionsResponse.cs +++ b/Source/v2/Meadow.Cloud.Client/Firmware/GetFirmwareVersionsResponse.cs @@ -1,10 +1,16 @@ namespace Meadow.Cloud.Client.Firmware; -public class GetFirmwareVersionsResponse(string version, DateTimeOffset lastModifiedAt) +public class GetFirmwareVersionsResponse { + public GetFirmwareVersionsResponse(string version, DateTimeOffset lastModifiedAt) + { + Version = version; + LastModifiedAt = lastModifiedAt; + } + [JsonPropertyName("version")] - public string Version { get; set; } = version; + public string Version { get; set; } [JsonPropertyName("lastModifiedAt")] - public DateTimeOffset LastModifiedAt { get; set; } = lastModifiedAt; + public DateTimeOffset LastModifiedAt { get; set; } } diff --git a/Source/v2/Meadow.Cloud.Client/Identity/IdentityManager.cs b/Source/v2/Meadow.Cloud.Client/Identity/IdentityManager.cs index 117d7cb3..3e6665f4 100644 --- a/Source/v2/Meadow.Cloud.Client/Identity/IdentityManager.cs +++ b/Source/v2/Meadow.Cloud.Client/Identity/IdentityManager.cs @@ -313,12 +313,18 @@ private void OpenBrowser(string url) } } - private class AccessToken(string token, DateTimeOffset expiresAt, string emailAddress) + private class AccessToken { + public AccessToken(string token, DateTimeOffset expiresAt, string emailAddress) + { + Token = token; + ExpiresAtUtc = expiresAt; + EmailAddress = emailAddress; + } - public string Token { get; } = token; - public DateTimeOffset ExpiresAtUtc { get; } = expiresAt; - public string EmailAddress { get; } = emailAddress; + public string Token { get; } + public DateTimeOffset ExpiresAtUtc { get; } + public string EmailAddress { get; } public bool IsValid => !string.IsNullOrWhiteSpace(Token) && ExpiresAtUtc > DateTimeOffset.UtcNow.AddMinutes(30); } diff --git a/Source/v2/Meadow.Cloud.Client/Meadow.Cloud.Client.csproj b/Source/v2/Meadow.Cloud.Client/Meadow.Cloud.Client.csproj index a441e711..c0d51f6e 100644 --- a/Source/v2/Meadow.Cloud.Client/Meadow.Cloud.Client.csproj +++ b/Source/v2/Meadow.Cloud.Client/Meadow.Cloud.Client.csproj @@ -1,18 +1,19 @@  - - netstandard2.0 - enable - enable - True - 12 - + + + netstandard2.0 + enable + True + 10 + - - - - - - - - + + + + + + + + + diff --git a/Source/v2/Meadow.Cloud.Client/MeadowCloudResponse.cs b/Source/v2/Meadow.Cloud.Client/MeadowCloudResponse.cs index d4ee19e5..97b85d81 100644 --- a/Source/v2/Meadow.Cloud.Client/MeadowCloudResponse.cs +++ b/Source/v2/Meadow.Cloud.Client/MeadowCloudResponse.cs @@ -1,17 +1,28 @@ namespace Meadow.Cloud.Client; -public class MeadowCloudResponse(HttpStatusCode statusCode, IReadOnlyDictionary> headers) +public class MeadowCloudResponse { + public MeadowCloudResponse(HttpStatusCode statusCode, IReadOnlyDictionary> headers) + { + StatusCode = statusCode; + Headers = headers; + } + public MeadowCloudResponse(HttpStatusCode statusCode) : this(statusCode, new Dictionary>()) { } - public HttpStatusCode StatusCode { get; } = statusCode; - public IReadOnlyDictionary> Headers { get; } = headers; + public HttpStatusCode StatusCode { get; } + public IReadOnlyDictionary> Headers { get; } } -public class MeadowCloudResponse(HttpStatusCode statusCode, IReadOnlyDictionary> headers, TResult result) - : MeadowCloudResponse(statusCode, headers) +public class MeadowCloudResponse : MeadowCloudResponse { + public MeadowCloudResponse(HttpStatusCode statusCode, IReadOnlyDictionary> headers, TResult result) + : base(statusCode, headers) + { + Result = result; + } + public MeadowCloudResponse(HttpStatusCode statusCode, TResult result) : this(statusCode, new Dictionary>(), result) { } - public TResult Result { get; } = result; + public TResult Result { get; } } diff --git a/Source/v2/Meadow.Cloud.Client/Services/ApiTokenService.cs b/Source/v2/Meadow.Cloud.Client/Services/ApiTokenService.cs index 621e2d20..1aa41c76 100644 --- a/Source/v2/Meadow.Cloud.Client/Services/ApiTokenService.cs +++ b/Source/v2/Meadow.Cloud.Client/Services/ApiTokenService.cs @@ -68,40 +68,78 @@ public async Task DeleteApiToken(string id, string host, CancellationToken? canc } } -public class GetApiTokenResponse(string id, string name, DateTimeOffset expiresAt, string[] scopes) +public class GetApiTokenResponse { - public string Id { get; set; } = id; - public string Name { get; set; } = name; - public DateTimeOffset ExpiresAt { get; set; } = expiresAt; - public string[] Scopes { get; set; } = scopes; + public GetApiTokenResponse(string id, string name, DateTimeOffset expiresAt, string[] scopes) + { + Id = id; + Name = name; + ExpiresAt = expiresAt; + Scopes = scopes; + } + + public string Id { get; set; } + public string Name { get; set; } + public DateTimeOffset ExpiresAt { get; set; } + public string[] Scopes { get; set; } } -public class CreateApiTokenRequest(string name, int duration, string[] scopes) +public class CreateApiTokenRequest { - public string Name { get; set; } = name; - public int Duration { get; set; } = duration; - public string[] Scopes { get; set; } = scopes; + public CreateApiTokenRequest(string name, int duration, string[] scopes) + { + Name = name; + Duration = duration; + Scopes = scopes; + } + + public string Name { get; set; } + public int Duration { get; set; } + public string[] Scopes { get; set; } } -public class CreateApiTokenResponse(string id, string name, DateTimeOffset expiresAt, string[] scopes, string token) +public class CreateApiTokenResponse { - public string Id { get; set; } = id; - public string Name { get; set; } = name; - public DateTimeOffset ExpiresAt { get; set; } = expiresAt; - public string[] Scopes { get; set; } = scopes; - public string Token { get; set; } = token; + public CreateApiTokenResponse(string id, string name, DateTimeOffset expiresAt, string[] scopes, string token) + { + Id = id; + Name = name; + ExpiresAt = expiresAt; + Scopes = scopes; + Token = token; + } + + public string Id { get; set; } + public string Name { get; set; } + public DateTimeOffset ExpiresAt { get; set; } + public string[] Scopes { get; set; } + public string Token { get; set; } } -public class UpdateApiTokenRequest(string name, string[] scopes) +public class UpdateApiTokenRequest { - public string Name { get; set; } = name; - public string[] Scopes { get; set; } = scopes; + public UpdateApiTokenRequest(string name, string[] scopes) + { + Name = name; + Scopes = scopes; + } + + public string Name { get; set; } + public string[] Scopes { get; set; } } -public class UpdateApiTokenResponse(string id, string name, DateTimeOffset expiresAt, string[] scopes) +public class UpdateApiTokenResponse { - public string Id { get; set; } = id; - public string Name { get; set; } = name; - public DateTimeOffset ExpiresAt { get; set; } = expiresAt; - public string[] Scopes { get; set; } = scopes; + public UpdateApiTokenResponse(string id, string name, DateTimeOffset expiresAt, string[] scopes) + { + Id = id; + Name = name; + ExpiresAt = expiresAt; + Scopes = scopes; + } + + public string Id { get; set; } + public string Name { get; set; } + public DateTimeOffset ExpiresAt { get; set; } + public string[] Scopes { get; set; } } diff --git a/Source/v2/Meadow.Cloud.Client/Users/GetOrganizationResponse.cs b/Source/v2/Meadow.Cloud.Client/Users/GetOrganizationResponse.cs index b690d49f..a974ffaa 100644 --- a/Source/v2/Meadow.Cloud.Client/Users/GetOrganizationResponse.cs +++ b/Source/v2/Meadow.Cloud.Client/Users/GetOrganizationResponse.cs @@ -1,13 +1,20 @@ namespace Meadow.Cloud.Client.Users; -public class GetOrganizationResponse(string id, string name, string defaultCollectionId) +public class GetOrganizationResponse { + public GetOrganizationResponse(string id, string name, string defaultCollectionId) + { + Id = id; + Name = name; + DefaultCollectionId = defaultCollectionId; + } + [JsonPropertyName("id")] - public string Id { get; set; } = id; + public string Id { get; set; } [JsonPropertyName("name")] - public string Name { get; set; } = name; + public string Name { get; set; } [JsonPropertyName("defaultCollectionId")] - public string DefaultCollectionId { get; set; } = defaultCollectionId; + public string DefaultCollectionId { get; set; } } diff --git a/Source/v2/Meadow.Cloud.Client/Users/GetUserResponse.cs b/Source/v2/Meadow.Cloud.Client/Users/GetUserResponse.cs index f0078852..fbe1de23 100644 --- a/Source/v2/Meadow.Cloud.Client/Users/GetUserResponse.cs +++ b/Source/v2/Meadow.Cloud.Client/Users/GetUserResponse.cs @@ -1,19 +1,28 @@ namespace Meadow.Cloud.Client.Users; -public class GetUserResponse(string id, string email, string firstName, string lastName, string fullName) +public class GetUserResponse { + public GetUserResponse(string id, string email, string firstName, string lastName, string fullName) + { + Id = id; + Email = email; + FirstName = firstName; + LastName = lastName; + FullName = fullName; + } + [JsonPropertyName("id")] - public string Id { get; set; } = id; + public string Id { get; set; } [JsonPropertyName("email")] - public string Email { get; set; } = email; + public string Email { get; set; } [JsonPropertyName("firstName")] - public string FirstName { get; set; } = firstName; + public string FirstName { get; set; } [JsonPropertyName("lastName")] - public string LastName { get; set; } = lastName; + public string LastName { get; set; } [JsonPropertyName("fullName")] - public string FullName { get; set; } = fullName; + public string FullName { get; set; } } diff --git a/Source/v2/Meadow.Cloud.Client/Users/UserClient.cs b/Source/v2/Meadow.Cloud.Client/Users/UserClient.cs index 377c7b64..81637206 100644 --- a/Source/v2/Meadow.Cloud.Client/Users/UserClient.cs +++ b/Source/v2/Meadow.Cloud.Client/Users/UserClient.cs @@ -14,7 +14,7 @@ public async Task> GetOrganizations(Cancell if (response.StatusCode == HttpStatusCode.NotFound) { - return []; + return Enumerable.Empty(); } return await ProcessResponse>(response, cancellationToken); diff --git a/Source/v2/Meadow.Cloud.Client/Usings.cs b/Source/v2/Meadow.Cloud.Client/Usings.cs index 1afab391..82ef8b3a 100644 --- a/Source/v2/Meadow.Cloud.Client/Usings.cs +++ b/Source/v2/Meadow.Cloud.Client/Usings.cs @@ -1,10 +1,17 @@ global using Meadow.Cloud.Client.Identity; global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Logging.Abstractions; +global using System; +global using System.Collections.Generic; global using System.Diagnostics; +global using System.IO; +global using System.Linq; global using System.Net; +global using System.Net.Http; global using System.Net.Http.Headers; global using System.Net.Http.Json; global using System.Text; global using System.Text.Json; global using System.Text.Json.Serialization; +global using System.Threading; +global using System.Threading.Tasks; diff --git a/Source/v2/Meadow.Dfu/DfuSharp.cs b/Source/v2/Meadow.Dfu/DfuSharp.cs index 13faa55f..027fff53 100644 --- a/Source/v2/Meadow.Dfu/DfuSharp.cs +++ b/Source/v2/Meadow.Dfu/DfuSharp.cs @@ -1,5 +1,9 @@ -using System.Diagnostics; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; using System.Runtime.InteropServices; +using System.Threading; namespace DfuSharp { diff --git a/Source/v2/Meadow.Dfu/DfuUtils.cs b/Source/v2/Meadow.Dfu/DfuUtils.cs index 3d6611a6..954bf6f0 100644 --- a/Source/v2/Meadow.Dfu/DfuUtils.cs +++ b/Source/v2/Meadow.Dfu/DfuUtils.cs @@ -1,10 +1,15 @@ using Meadow.Hcom; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; +using System; using System.ComponentModel; using System.Diagnostics; +using System.IO; using System.IO.Compression; +using System.Net.Http; using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; namespace Meadow.CLI.Core.Internals.Dfu; diff --git a/Source/v2/Meadow.Dfu/Meadow.Dfu.csproj b/Source/v2/Meadow.Dfu/Meadow.Dfu.csproj index 9f78e4cc..c00495da 100644 --- a/Source/v2/Meadow.Dfu/Meadow.Dfu.csproj +++ b/Source/v2/Meadow.Dfu/Meadow.Dfu.csproj @@ -2,7 +2,6 @@ netstandard2.0 - enable enable 10 diff --git a/Source/v2/Meadow.Hcom/CobsTools.cs b/Source/v2/Meadow.Hcom/CobsTools.cs index 8736353a..4949f366 100644 --- a/Source/v2/Meadow.Hcom/CobsTools.cs +++ b/Source/v2/Meadow.Hcom/CobsTools.cs @@ -1,101 +1,100 @@ -namespace Meadow.Hcom +namespace Meadow.Hcom; + +internal static class CobsTools { - internal static class CobsTools + //============================================================== + // Consistent Overhead Byte Stuffing (COBS) is a scheme to take binary data + // replace an arbituary byte value, usually 0x00, with an encoding that replaces + // this value, in a way, that allows the orginal data can be recovered while + // creating frames around the data. + // + // The following C# code was ported from a 'C' example licensed under MIT License + // https://github.com/bakercp/PacketSerial/blob/master/src/Encoding/COBS.h. + // After porting, I found errors. I referred to the original authors paper at + // http://conferences.sigcomm.org/sigcomm/1997/papers/p062.pdf for additional insights. + // Modifications were needed and adding a starting offset to support large buffers was + // added to allow sub-segments to be encoded. + // + public static int CobsEncoding(byte[] source, int startingSkip, int length, + ref byte[] encoded, int encodeSkip) { - //============================================================== - // Consistent Overhead Byte Stuffing (COBS) is a scheme to take binary data - // replace an arbituary byte value, usually 0x00, with an encoding that replaces - // this value, in a way, that allows the orginal data can be recovered while - // creating frames around the data. - // - // The following C# code was ported from a 'C' example licensed under MIT License - // https://github.com/bakercp/PacketSerial/blob/master/src/Encoding/COBS.h. - // After porting, I found errors. I referred to the original authors paper at - // http://conferences.sigcomm.org/sigcomm/1997/papers/p062.pdf for additional insights. - // Modifications were needed and adding a starting offset to support large buffers was - // added to allow sub-segments to be encoded. - // - public static int CobsEncoding(byte[] source, int startingSkip, int length, - ref byte[] encoded, int encodeSkip) + int sourceOffset = startingSkip; // Offset into source buffer + // Add 1 because first byte filled with first replaceValue value + int encodedOffset = 1; // Offset into destination buffer + int replaceOffset = 0; // Offset where replaceValue is being tracked + byte replaceValue = 1; // Value of the offset to the next delimiter + try { - int sourceOffset = startingSkip; // Offset into source buffer - // Add 1 because first byte filled with first replaceValue value - int encodedOffset = 1; // Offset into destination buffer - int replaceOffset = 0; // Offset where replaceValue is being tracked - byte replaceValue = 1; // Value of the offset to the next delimiter - try + while (sourceOffset < length + startingSkip) { - while (sourceOffset < length + startingSkip) + // Is source value the one we must replace? + if (source[sourceOffset] == 0x00) + { + encoded[encodeSkip + replaceOffset] = replaceValue; // Replace original value with offset to replaceValue + replaceOffset = encodedOffset++; // Update replace offset and bump encoded offset + replaceValue = 1; // Reset replaceValue + } + else { - // Is source value the one we must replace? - if (source[sourceOffset] == 0x00) + if (encodeSkip + encodedOffset == encoded.Length) { - encoded[encodeSkip + replaceOffset] = replaceValue; // Replace original value with offset to replaceValue - replaceOffset = encodedOffset++; // Update replace offset and bump encoded offset - replaceValue = 1; // Reset replaceValue + Console.WriteLine($"encodeSkip + encodedOffset == encoded.Length"); + return -1; } - else - { - if (encodeSkip + encodedOffset == encoded.Length) - { - Console.WriteLine($"encodeSkip + encodedOffset == encoded.Length"); - return -1; - } - encoded[encodeSkip + encodedOffset++] = source[sourceOffset]; // Just copy original value - replaceValue++; // Keep zero offset tracker + encoded[encodeSkip + encodedOffset++] = source[sourceOffset]; // Just copy original value + replaceValue++; // Keep zero offset tracker - // replaceValue has been tracking the delimiter offset. If it's 0xff then - // special action is needed, because we reached the end of a 254 byte block - // of data. And now encoding starts like at the first. - if (replaceValue == 0xff) // Signals maximum possible offset - { - encoded[encodeSkip + replaceOffset] = replaceValue; - replaceOffset = encodedOffset++; - replaceValue = 1; - } + // replaceValue has been tracking the delimiter offset. If it's 0xff then + // special action is needed, because we reached the end of a 254 byte block + // of data. And now encoding starts like at the first. + if (replaceValue == 0xff) // Signals maximum possible offset + { + encoded[encodeSkip + replaceOffset] = replaceValue; + replaceOffset = encodedOffset++; + replaceValue = 1; } - sourceOffset++; // Point to next source value } + sourceOffset++; // Point to next source value } - catch (Exception except) - { - Console.WriteLine($"An exception was caught: {except}"); - Thread.Sleep(10 * 60 * 1000); // Sleep for 10 minutes - throw; - } - - // Last character - encoded[encodeSkip + replaceOffset] = replaceValue; - return encodedOffset; // Number of bytes written to result buffer } - - //--------------------------------------------------------------------------- - public static int CobsDecoding(byte[] encoded, int length, ref byte[] decoded) + catch (Exception except) { - int encodedOffset = 0; // Offset into original (encoded) buffer - int decodedOffset = 0; // Offset into destination (decoded) buffer - byte replaceValue = 0; // Value that will be inserted to indicate replaced value + Console.WriteLine($"An exception was caught: {except}"); + Thread.Sleep(10 * 60 * 1000); // Sleep for 10 minutes + throw; + } - while (encodedOffset < length) - { - replaceValue = encoded[encodedOffset]; // Grab next byte + // Last character + encoded[encodeSkip + replaceOffset] = replaceValue; + return encodedOffset; // Number of bytes written to result buffer + } + + //--------------------------------------------------------------------------- + public static int CobsDecoding(byte[] encoded, int length, ref byte[] decoded) + { + int encodedOffset = 0; // Offset into original (encoded) buffer + int decodedOffset = 0; // Offset into destination (decoded) buffer + byte replaceValue = 0; // Value that will be inserted to indicate replaced value - if (((encodedOffset + replaceValue) > length) && (replaceValue != 1)) - return 0; + while (encodedOffset < length) + { + replaceValue = encoded[encodedOffset]; // Grab next byte - encodedOffset++; // Point to next source + if (((encodedOffset + replaceValue) > length) && (replaceValue != 1)) + return 0; - // Copy all unchanged bytes - // C# would Array.Copy be noticably better? - for (int i = 1; i < replaceValue; i++) - decoded[decodedOffset++] = encoded[encodedOffset++]; + encodedOffset++; // Point to next source - // Sometimes don't need a trailing delimiter added - if (replaceValue < 0xff && encodedOffset != length) - decoded[decodedOffset++] = 0x00; - } + // Copy all unchanged bytes + // C# would Array.Copy be noticably better? + for (int i = 1; i < replaceValue; i++) + decoded[decodedOffset++] = encoded[encodedOffset++]; - return decodedOffset; + // Sometimes don't need a trailing delimiter added + if (replaceValue < 0xff && encodedOffset != length) + decoded[decodedOffset++] = 0x00; } + + return decodedOffset; } } \ No newline at end of file diff --git a/Source/v2/Meadow.Hcom/ConnectionManager.cs b/Source/v2/Meadow.Hcom/ConnectionManager.cs index a9dc569b..5ce7bcee 100644 --- a/Source/v2/Meadow.Hcom/ConnectionManager.cs +++ b/Source/v2/Meadow.Hcom/ConnectionManager.cs @@ -1,29 +1,28 @@ -namespace Meadow.Hcom +namespace Meadow.Hcom; + +public class ConnectionManager { - public class ConnectionManager + private static readonly List _connections = new List(); + + public static TConnection GetConnection(string connectionName) + where TConnection : class, IMeadowConnection { - private static readonly List _connections = new List(); + // see if it already is known + var existing = _connections.FirstOrDefault(c => c.Name == connectionName) as TConnection; + if (existing != null) return existing; - public static TConnection GetConnection(string connectionName) - where TConnection : class, IMeadowConnection + // otherwise create + switch (typeof(TConnection)) { - // see if it already is known - var existing = _connections.FirstOrDefault(c => c.Name == connectionName) as TConnection; - if (existing != null) return existing; - - // otherwise create - switch (typeof(TConnection)) - { - case Type t when t == typeof(SerialConnection): - var c = new SerialConnection(connectionName); - _connections.Add(c); + case Type t when t == typeof(SerialConnection): + var c = new SerialConnection(connectionName); + _connections.Add(c); #pragma warning disable 8603 - return c as TConnection; + return c as TConnection; #pragma warning restore - default: - throw new NotSupportedException(); - }; + default: + throw new NotSupportedException(); + }; - } } } \ No newline at end of file diff --git a/Source/v2/Meadow.Hcom/ConnectionState.cs b/Source/v2/Meadow.Hcom/ConnectionState.cs index b0c3e15b..30434bd1 100644 --- a/Source/v2/Meadow.Hcom/ConnectionState.cs +++ b/Source/v2/Meadow.Hcom/ConnectionState.cs @@ -1,9 +1,8 @@ -namespace Meadow.Hcom +namespace Meadow.Hcom; + +public enum ConnectionState { - public enum ConnectionState - { - Disconnected, - Connected, - MeadowAttached - } + Disconnected, + Connected, + MeadowAttached } \ No newline at end of file diff --git a/Source/v2/Meadow.Hcom/Connections/ConnectionBase.cs b/Source/v2/Meadow.Hcom/Connections/ConnectionBase.cs index 156148b7..227362f6 100755 --- a/Source/v2/Meadow.Hcom/Connections/ConnectionBase.cs +++ b/Source/v2/Meadow.Hcom/Connections/ConnectionBase.cs @@ -1,6 +1,4 @@ -using Microsoft.Extensions.Logging; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; public abstract class ConnectionBase : IMeadowConnection, IDisposable { diff --git a/Source/v2/Meadow.Hcom/Connections/LocalConnection.cs b/Source/v2/Meadow.Hcom/Connections/LocalConnection.cs index 76ce68ce..7332976f 100755 --- a/Source/v2/Meadow.Hcom/Connections/LocalConnection.cs +++ b/Source/v2/Meadow.Hcom/Connections/LocalConnection.cs @@ -1,6 +1,4 @@ -using Microsoft.Extensions.Logging; -using System.Diagnostics; -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Meadow.Hcom; diff --git a/Source/v2/Meadow.Hcom/Connections/SerialConnection.ListenerProc.cs b/Source/v2/Meadow.Hcom/Connections/SerialConnection.ListenerProc.cs index 861e46dc..e7a80112 100644 --- a/Source/v2/Meadow.Hcom/Connections/SerialConnection.ListenerProc.cs +++ b/Source/v2/Meadow.Hcom/Connections/SerialConnection.ListenerProc.cs @@ -1,5 +1,4 @@ -using System.Diagnostics; -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; namespace Meadow.Hcom { diff --git a/Source/v2/Meadow.Hcom/Connections/SerialConnection.cs b/Source/v2/Meadow.Hcom/Connections/SerialConnection.cs index da161bbe..6751a0fb 100755 --- a/Source/v2/Meadow.Hcom/Connections/SerialConnection.cs +++ b/Source/v2/Meadow.Hcom/Connections/SerialConnection.cs @@ -1,10 +1,7 @@ -using Microsoft.Extensions.Logging; -using System.Buffers; -using System.Diagnostics; +using System.Buffers; using System.IO.Ports; using System.Net; using System.Security.Cryptography; -using System.Text; namespace Meadow.Hcom; diff --git a/Source/v2/Meadow.Hcom/Connections/SimulatorConnection.cs b/Source/v2/Meadow.Hcom/Connections/SimulatorConnection.cs index 0574b533..77fb9b2f 100755 --- a/Source/v2/Meadow.Hcom/Connections/SimulatorConnection.cs +++ b/Source/v2/Meadow.Hcom/Connections/SimulatorConnection.cs @@ -1,6 +1,4 @@ -using Microsoft.Extensions.Logging; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; public class SimulatorConnection : ConnectionBase { diff --git a/Source/v2/Meadow.Hcom/Connections/TcpConnection.cs b/Source/v2/Meadow.Hcom/Connections/TcpConnection.cs index 631dc4e0..e6964cb8 100755 --- a/Source/v2/Meadow.Hcom/Connections/TcpConnection.cs +++ b/Source/v2/Meadow.Hcom/Connections/TcpConnection.cs @@ -1,7 +1,4 @@ -using Microsoft.Extensions.Logging; -using System.Text.Json; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; public class TcpConnection : ConnectionBase { diff --git a/Source/v2/Meadow.Hcom/DeviceInfo.cs b/Source/v2/Meadow.Hcom/DeviceInfo.cs index 40e20e1e..1634da7a 100644 --- a/Source/v2/Meadow.Hcom/DeviceInfo.cs +++ b/Source/v2/Meadow.Hcom/DeviceInfo.cs @@ -1,100 +1,97 @@ -using System.Text; +namespace Meadow.Hcom; -namespace Meadow.Hcom +public class DeviceInfo { - public class DeviceInfo + public Dictionary Properties { get; } + + internal DeviceInfo(Dictionary properties) { - public Dictionary Properties { get; } + Properties = properties; + } - internal DeviceInfo(Dictionary properties) + public string? this[string propname] + { + get { - Properties = properties; + return Properties.Keys.Contains(propname) ? Properties[propname] : null; } + } - public string? this[string propname] - { - get - { - return Properties.Keys.Contains(propname) ? Properties[propname] : null; - } - } + public string? Product => this["Product"]; + public string? Model => this["Model"]; + public string? ProcessorType => this["ProcessorType"]; + public string? CoprocessorType => this["CoprocessorType"]; + public string? OsVersion => this["OSVersion"]; + public string? CoprocessorOsVersion => this["CoprocessorVersion"]; + public string? ProcessorId => this["ProcessorId"]; + public string? HardwareVersion => this["Hardware"]; + public string? DeviceName => this["DeviceName"]; + public string? RuntimeVersion => this["MonoVersion"]; + public string? SerialNumber => this["SerialNo"]; + public string? MacAddress => this["WiFiMAC"]; + public string? SoftAPMacAddress => this["SoftAPMac"]; - public string? Product => this["Product"]; - public string? Model => this["Model"]; - public string? ProcessorType => this["ProcessorType"]; - public string? CoprocessorType => this["CoprocessorType"]; - public string? OsVersion => this["OSVersion"]; - public string? CoprocessorOsVersion => this["CoprocessorVersion"]; - public string? ProcessorId => this["ProcessorId"]; - public string? HardwareVersion => this["Hardware"]; - public string? DeviceName => this["DeviceName"]; - public string? RuntimeVersion => this["MonoVersion"]; - public string? SerialNumber => this["SerialNo"]; - public string? MacAddress => this["WiFiMAC"]; - public string? SoftAPMacAddress => this["SoftAPMac"]; + /// + /// String representation of an unknown MAC address. + /// + private const string UNKNOWN_MAC_ADDRESS = "00:00:00:00:00:00"; - /// - /// String representation of an unknown MAC address. - /// - private const string UNKNOWN_MAC_ADDRESS = "00:00:00:00:00:00"; + public override string ToString() + { + var deviceInfo = new StringBuilder(); - public override string ToString() + if (Product != null && Product.Contains(" by Wilderness Labs")) { - var deviceInfo = new StringBuilder(); - - if (Product != null && Product.Contains(" by Wilderness Labs")) - { - deviceInfo.AppendLine(Product); - } - else - { - deviceInfo.AppendLine($"{Product} by Wilderness Labs"); - } + deviceInfo.AppendLine(Product); + } + else + { + deviceInfo.AppendLine($"{Product} by Wilderness Labs"); + } - deviceInfo.AppendLine("Board Information "); - deviceInfo.AppendLine($" Model: {Model}"); - deviceInfo.AppendLine($" Hardware version: {HardwareVersion}"); - deviceInfo.AppendLine($" Device name: {DeviceName}"); - deviceInfo.AppendLine(); - deviceInfo.AppendLine($"Hardware Information "); - deviceInfo.AppendLine($" Processor type: {ProcessorType}"); - deviceInfo.AppendLine($" ID: {ProcessorId}"); - deviceInfo.AppendLine($" Serial number: {SerialNumber}"); - deviceInfo.AppendLine($" Coprocessor type: {CoprocessorType}"); + deviceInfo.AppendLine("Board Information "); + deviceInfo.AppendLine($" Model: {Model}"); + deviceInfo.AppendLine($" Hardware version: {HardwareVersion}"); + deviceInfo.AppendLine($" Device name: {DeviceName}"); + deviceInfo.AppendLine(); + deviceInfo.AppendLine($"Hardware Information "); + deviceInfo.AppendLine($" Processor type: {ProcessorType}"); + deviceInfo.AppendLine($" ID: {ProcessorId}"); + deviceInfo.AppendLine($" Serial number: {SerialNumber}"); + deviceInfo.AppendLine($" Coprocessor type: {CoprocessorType}"); - string macAddresses = string.Empty; - int macCount = 0; - if (!string.IsNullOrEmpty(MacAddress) && MacAddress != UNKNOWN_MAC_ADDRESS) - { - macCount++; - macAddresses += $"\tWiFi: {MacAddress}{Environment.NewLine}"; - } - if (!string.IsNullOrEmpty(SoftAPMacAddress) && SoftAPMacAddress != UNKNOWN_MAC_ADDRESS) + string macAddresses = string.Empty; + int macCount = 0; + if (!string.IsNullOrEmpty(MacAddress) && MacAddress != UNKNOWN_MAC_ADDRESS) + { + macCount++; + macAddresses += $"\tWiFi: {MacAddress}{Environment.NewLine}"; + } + if (!string.IsNullOrEmpty(SoftAPMacAddress) && SoftAPMacAddress != UNKNOWN_MAC_ADDRESS) + { + macCount++; + macAddresses += $"\tAP: {SoftAPMacAddress}{Environment.NewLine}"; + } + if (macCount > 0) + { + if (macCount > 1) { - macCount++; - macAddresses += $"\tAP: {SoftAPMacAddress}{Environment.NewLine}"; + deviceInfo.AppendLine(" MAC Addresses - "); } - if (macCount > 0) + else { - if (macCount > 1) - { - deviceInfo.AppendLine(" MAC Addresses - "); - } - else - { - deviceInfo.AppendLine(" MAC Address - "); - } - deviceInfo.AppendLine($"{macAddresses}"); + deviceInfo.AppendLine(" MAC Address - "); } + deviceInfo.AppendLine($"{macAddresses}"); + } - deviceInfo.AppendLine(); - deviceInfo.AppendLine($"Firmware Versions "); - deviceInfo.AppendLine($" OS: {OsVersion}"); - deviceInfo.AppendLine($" Runtime: {RuntimeVersion}"); - deviceInfo.AppendLine($" Coprocessor: {CoprocessorOsVersion}"); - deviceInfo.AppendLine($" Protocol: {Protocol.HCOM_PROTOCOL_HCOM_VERSION_NUMBER}"); + deviceInfo.AppendLine(); + deviceInfo.AppendLine($"Firmware Versions "); + deviceInfo.AppendLine($" OS: {OsVersion}"); + deviceInfo.AppendLine($" Runtime: {RuntimeVersion}"); + deviceInfo.AppendLine($" Coprocessor: {CoprocessorOsVersion}"); + deviceInfo.AppendLine($" Protocol: {Protocol.HCOM_PROTOCOL_HCOM_VERSION_NUMBER}"); - return deviceInfo.ToString(); - } + return deviceInfo.ToString(); } } \ No newline at end of file diff --git a/Source/v2/Meadow.Hcom/DeviceNotFoundException.cs b/Source/v2/Meadow.Hcom/DeviceNotFoundException.cs index 3a822bc0..eff36cb8 100644 --- a/Source/v2/Meadow.Hcom/DeviceNotFoundException.cs +++ b/Source/v2/Meadow.Hcom/DeviceNotFoundException.cs @@ -1,7 +1,6 @@ -namespace Meadow.Hcom +namespace Meadow.Hcom; + +public class DeviceNotFoundException : Exception { - public class DeviceNotFoundException : Exception - { - internal DeviceNotFoundException() : base() { } - } + internal DeviceNotFoundException() : base() { } } \ No newline at end of file diff --git a/Source/v2/Meadow.Hcom/Firmware/DownloadFileStream.cs b/Source/v2/Meadow.Hcom/Firmware/DownloadFileStream.cs index 4c37a41a..ce60adb9 100644 --- a/Source/v2/Meadow.Hcom/Firmware/DownloadFileStream.cs +++ b/Source/v2/Meadow.Hcom/Firmware/DownloadFileStream.cs @@ -1,6 +1,4 @@ -using Microsoft.Extensions.Logging; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; public class DownloadFileStream : Stream, IDisposable { diff --git a/Source/v2/Meadow.Hcom/Firmware/ReleaseMetadata.cs b/Source/v2/Meadow.Hcom/Firmware/ReleaseMetadata.cs index 823f1e01..723c6d8a 100644 --- a/Source/v2/Meadow.Hcom/Firmware/ReleaseMetadata.cs +++ b/Source/v2/Meadow.Hcom/Firmware/ReleaseMetadata.cs @@ -1,6 +1,4 @@ -using System.Text.Json.Serialization; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; public class ReleaseMetadata { diff --git a/Source/v2/Meadow.Hcom/HttpResponses/DeviceInfoHttpResponse.cs b/Source/v2/Meadow.Hcom/HttpResponses/DeviceInfoHttpResponse.cs index ccdfe3bd..c0f8f224 100644 --- a/Source/v2/Meadow.Hcom/HttpResponses/DeviceInfoHttpResponse.cs +++ b/Source/v2/Meadow.Hcom/HttpResponses/DeviceInfoHttpResponse.cs @@ -1,6 +1,4 @@ -using System.Text.Json.Serialization; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; internal class DeviceInfoHttpResponse { diff --git a/Source/v2/Meadow.Hcom/IConnectionListener.cs b/Source/v2/Meadow.Hcom/IConnectionListener.cs index 09e5e94c..522ed7a2 100644 --- a/Source/v2/Meadow.Hcom/IConnectionListener.cs +++ b/Source/v2/Meadow.Hcom/IConnectionListener.cs @@ -1,14 +1,13 @@ -namespace Meadow.Hcom +namespace Meadow.Hcom; + +public interface IConnectionListener { - public interface IConnectionListener - { - void OnInformationMessageReceived(string message); - void OnStdOutReceived(string message); - void OnStdErrReceived(string message); - void OnDeviceInformationMessageReceived(Dictionary deviceInfo); - void OnTextListReceived(string[] list); - void OnErrorTextReceived(string message); - void OnFileError(); - void OnTextMessageConcluded(int requestType); - } + void OnInformationMessageReceived(string message); + void OnStdOutReceived(string message); + void OnStdErrReceived(string message); + void OnDeviceInformationMessageReceived(Dictionary deviceInfo); + void OnTextListReceived(string[] list); + void OnErrorTextReceived(string message); + void OnFileError(); + void OnTextMessageConcluded(int requestType); } \ No newline at end of file diff --git a/Source/v2/Meadow.Hcom/IMeadowConnection.cs b/Source/v2/Meadow.Hcom/IMeadowConnection.cs index a51bfa2c..20037b24 100755 --- a/Source/v2/Meadow.Hcom/IMeadowConnection.cs +++ b/Source/v2/Meadow.Hcom/IMeadowConnection.cs @@ -1,55 +1,51 @@ -using Microsoft.Extensions.Logging; +namespace Meadow.Hcom; -namespace Meadow.Hcom +public interface IMeadowConnection : IDisposable { - public interface IMeadowConnection : IDisposable - { - event EventHandler<(string message, string? source)> DeviceMessageReceived; - event EventHandler ConnectionError; - event EventHandler ConnectionMessage; - event EventHandler<(string fileName, long completed, long total)> FileWriteProgress; - event EventHandler FileWriteFailed; - event EventHandler DebuggerMessage; - - string Name { get; } - IMeadowDevice? Device { get; } - Task Attach(CancellationToken? cancellationToken = null, int timeoutSeconds = 10); - void Detach(); - Task WaitForMeadowAttach(CancellationToken? cancellationToken = null); - ConnectionState State { get; } - - Task WriteFile(string localFileName, string? meadowFileName = null, CancellationToken? cancellationToken = null); - Task ReadFile(string meadowFileName, string? localFileName = null, CancellationToken? cancellationToken = null); - Task ReadFileString(string fileName, CancellationToken? cancellationToken = null); - Task DeleteFile(string meadowFileName, CancellationToken? cancellationToken = null); - Task GetDeviceInfo(CancellationToken? cancellationToken = null); - Task GetFileList(string folder, bool includeCrcs, CancellationToken? cancellationToken = null); - Task ResetDevice(CancellationToken? cancellationToken = null); - Task IsRuntimeEnabled(CancellationToken? cancellationToken = null); - Task RuntimeDisable(CancellationToken? cancellationToken = null); - Task RuntimeEnable(CancellationToken? cancellationToken = null); - Task GetRtcTime(CancellationToken? cancellationToken = null); - Task SetRtcTime(DateTimeOffset dateTime, CancellationToken? cancellationToken = null); - - Task WriteRuntime(string localFileName, CancellationToken? cancellationToken = null); - Task WriteCoprocessorFile(string localFileName, int destinationAddress, CancellationToken? cancellationToken = null); - - Task TraceEnable(CancellationToken? cancellationToken = null); - Task TraceDisable(CancellationToken? cancellationToken = null); - Task SetTraceLevel(int level, CancellationToken? cancellationToken = null); - - Task SetDeveloperParameter(ushort parameter, uint value, CancellationToken? cancellationToken = null); - - Task UartTraceEnable(CancellationToken? cancellationToken = null); - Task UartTraceDisable(CancellationToken? cancellationToken = null); - Task UartProfilerEnable(CancellationToken? cancellationToken = null); - Task UartProfilerDisable(CancellationToken? cancellationToken = null); - - - Task EraseFlash(CancellationToken? cancellationToken = null); - Task GetPublicKey(CancellationToken? cancellationToken = null); - Task StartDebuggingSession(int port, ILogger? logger, CancellationToken cancellationToken); - Task StartDebugging(int port, ILogger? logger, CancellationToken? cancellationToken); - Task SendDebuggerData(byte[] debuggerData, uint userData, CancellationToken? cancellationToken); - } + event EventHandler<(string message, string? source)> DeviceMessageReceived; + event EventHandler ConnectionError; + event EventHandler ConnectionMessage; + event EventHandler<(string fileName, long completed, long total)> FileWriteProgress; + event EventHandler FileWriteFailed; + + string Name { get; } + IMeadowDevice? Device { get; } + Task Attach(CancellationToken? cancellationToken = null, int timeoutSeconds = 10); + void Detach(); + Task WaitForMeadowAttach(CancellationToken? cancellationToken = null); + ConnectionState State { get; } + + Task WriteFile(string localFileName, string? meadowFileName = null, CancellationToken? cancellationToken = null); + Task ReadFile(string meadowFileName, string? localFileName = null, CancellationToken? cancellationToken = null); + Task ReadFileString(string fileName, CancellationToken? cancellationToken = null); + Task DeleteFile(string meadowFileName, CancellationToken? cancellationToken = null); + Task GetDeviceInfo(CancellationToken? cancellationToken = null); + Task GetFileList(string folder, bool includeCrcs, CancellationToken? cancellationToken = null); + Task ResetDevice(CancellationToken? cancellationToken = null); + Task IsRuntimeEnabled(CancellationToken? cancellationToken = null); + Task RuntimeDisable(CancellationToken? cancellationToken = null); + Task RuntimeEnable(CancellationToken? cancellationToken = null); + Task GetRtcTime(CancellationToken? cancellationToken = null); + Task SetRtcTime(DateTimeOffset dateTime, CancellationToken? cancellationToken = null); + + Task WriteRuntime(string localFileName, CancellationToken? cancellationToken = null); + Task WriteCoprocessorFile(string localFileName, int destinationAddress, CancellationToken? cancellationToken = null); + + Task TraceEnable(CancellationToken? cancellationToken = null); + Task TraceDisable(CancellationToken? cancellationToken = null); + Task SetTraceLevel(int level, CancellationToken? cancellationToken = null); + + Task SetDeveloperParameter(ushort parameter, uint value, CancellationToken? cancellationToken = null); + + Task UartTraceEnable(CancellationToken? cancellationToken = null); + Task UartTraceDisable(CancellationToken? cancellationToken = null); + Task UartProfilerEnable(CancellationToken? cancellationToken = null); + Task UartProfilerDisable(CancellationToken? cancellationToken = null); + + + Task EraseFlash(CancellationToken? cancellationToken = null); + Task GetPublicKey(CancellationToken? cancellationToken = null); + Task StartDebuggingSession(int port, ILogger? logger, CancellationToken cancellationToken); + Task StartDebugging(int port, ILogger? logger, CancellationToken? cancellationToken); + Task SendDebuggerData(byte[] debuggerData, uint userData, CancellationToken? cancellationToken); } \ No newline at end of file diff --git a/Source/v2/Meadow.Hcom/IMeadowDevice.cs b/Source/v2/Meadow.Hcom/IMeadowDevice.cs index 39d17a9e..25eed90a 100755 --- a/Source/v2/Meadow.Hcom/IMeadowDevice.cs +++ b/Source/v2/Meadow.Hcom/IMeadowDevice.cs @@ -1,34 +1,31 @@ -using Microsoft.Extensions.Logging; +namespace Meadow.Hcom; -namespace Meadow.Hcom +public interface IMeadowDevice { - public interface IMeadowDevice - { - Task Reset(CancellationToken? cancellationToken = null); - Task RuntimeDisable(CancellationToken? cancellationToken = null); - Task RuntimeEnable(CancellationToken? cancellationToken = null); - Task IsRuntimeEnabled(CancellationToken? cancellationToken = null); - Task GetDeviceInfo(CancellationToken? cancellationToken = null); - Task GetFileList(string folder, bool includeCrcs, CancellationToken? cancellationToken = null); - Task ReadFile(string meadowFileName, string? localFileName = null, CancellationToken? cancellationToken = null); - Task WriteFile(string localFileName, string? meadowFileName = null, CancellationToken? cancellationToken = null); - Task DeleteFile(string meadowFileName, CancellationToken? cancellationToken = null); - Task WriteRuntime(string localFileName, CancellationToken? cancellationToken = null); - Task GetRtcTime(CancellationToken? cancellationToken = null); - Task SetRtcTime(DateTimeOffset dateTime, CancellationToken? cancellationToken = null); - Task WriteCoprocessorFiles(string[] localFileNames, CancellationToken? cancellationToken = null); - Task TraceEnable(CancellationToken? cancellationToken = null); - Task TraceDisable(CancellationToken? cancellationToken = null); - Task SetTraceLevel(int level, CancellationToken? cancellationToken = null); - Task SetDeveloperParameter(ushort parameter, uint value, CancellationToken? cancellationToken = null); - Task UartTraceEnable(CancellationToken? cancellationToken = null); - Task UartTraceDisable(CancellationToken? cancellationToken = null); - Task UartProfilerEnable(CancellationToken? cancellationToken = null); - Task UartProfilerDisable(CancellationToken? cancellationToken = null); - Task EraseFlash(CancellationToken? cancellationToken = null); - Task ReadFileString(string fileName, CancellationToken? cancellationToken = null); - Task GetPublicKey(CancellationToken? cancellationToken = null); - Task StartDebugging(int port, ILogger? logger, CancellationToken? cancellationToken); - Task SendDebuggerData(byte[] debuggerData, uint userData, CancellationToken? cancellationToken); - } + Task Reset(CancellationToken? cancellationToken = null); + Task RuntimeDisable(CancellationToken? cancellationToken = null); + Task RuntimeEnable(CancellationToken? cancellationToken = null); + Task IsRuntimeEnabled(CancellationToken? cancellationToken = null); + Task GetDeviceInfo(CancellationToken? cancellationToken = null); + Task GetFileList(string folder, bool includeCrcs, CancellationToken? cancellationToken = null); + Task ReadFile(string meadowFileName, string? localFileName = null, CancellationToken? cancellationToken = null); + Task WriteFile(string localFileName, string? meadowFileName = null, CancellationToken? cancellationToken = null); + Task DeleteFile(string meadowFileName, CancellationToken? cancellationToken = null); + Task WriteRuntime(string localFileName, CancellationToken? cancellationToken = null); + Task GetRtcTime(CancellationToken? cancellationToken = null); + Task SetRtcTime(DateTimeOffset dateTime, CancellationToken? cancellationToken = null); + Task WriteCoprocessorFiles(string[] localFileNames, CancellationToken? cancellationToken = null); + Task TraceEnable(CancellationToken? cancellationToken = null); + Task TraceDisable(CancellationToken? cancellationToken = null); + Task SetTraceLevel(int level, CancellationToken? cancellationToken = null); + Task SetDeveloperParameter(ushort parameter, uint value, CancellationToken? cancellationToken = null); + Task UartTraceEnable(CancellationToken? cancellationToken = null); + Task UartTraceDisable(CancellationToken? cancellationToken = null); + Task UartProfilerEnable(CancellationToken? cancellationToken = null); + Task UartProfilerDisable(CancellationToken? cancellationToken = null); + Task EraseFlash(CancellationToken? cancellationToken = null); + Task ReadFileString(string fileName, CancellationToken? cancellationToken = null); + Task GetPublicKey(CancellationToken? cancellationToken = null); + Task StartDebugging(int port, ILogger? logger, CancellationToken? cancellationToken); + Task SendDebuggerData(byte[] debuggerData, uint userData, CancellationToken? cancellationToken); } \ No newline at end of file diff --git a/Source/v2/Meadow.Hcom/Meadow.HCom.csproj b/Source/v2/Meadow.Hcom/Meadow.HCom.csproj index 999b91b0..afe28480 100644 --- a/Source/v2/Meadow.Hcom/Meadow.HCom.csproj +++ b/Source/v2/Meadow.Hcom/Meadow.HCom.csproj @@ -2,7 +2,6 @@ netstandard2.0 - enable enable 10 @@ -18,5 +17,4 @@ - diff --git a/Source/v2/Meadow.Hcom/MeadowDevice.cs b/Source/v2/Meadow.Hcom/MeadowDevice.cs index 2415a598..bb51e176 100755 --- a/Source/v2/Meadow.Hcom/MeadowDevice.cs +++ b/Source/v2/Meadow.Hcom/MeadowDevice.cs @@ -1,175 +1,172 @@ -using Microsoft.Extensions.Logging; +namespace Meadow.Hcom; -namespace Meadow.Hcom +public partial class MeadowDevice : IMeadowDevice { - public partial class MeadowDevice : IMeadowDevice + private readonly IMeadowConnection _connection; + + internal MeadowDevice(IMeadowConnection connection) { - private readonly IMeadowConnection _connection; + _connection = connection; + } - internal MeadowDevice(IMeadowConnection connection) - { - _connection = connection; - } + public async Task IsRuntimeEnabled(CancellationToken? cancellationToken = null) + { + return await _connection.IsRuntimeEnabled(cancellationToken); + } - public async Task IsRuntimeEnabled(CancellationToken? cancellationToken = null) - { - return await _connection.IsRuntimeEnabled(cancellationToken); - } + public async Task Reset(CancellationToken? cancellationToken = null) + { + await _connection.ResetDevice(cancellationToken); + } - public async Task Reset(CancellationToken? cancellationToken = null) - { - await _connection.ResetDevice(cancellationToken); - } + public async Task RuntimeDisable(CancellationToken? cancellationToken = null) + { + await _connection.RuntimeDisable(cancellationToken); + } - public async Task RuntimeDisable(CancellationToken? cancellationToken = null) - { - await _connection.RuntimeDisable(cancellationToken); - } + public async Task RuntimeEnable(CancellationToken? cancellationToken = null) + { + await _connection.RuntimeEnable(cancellationToken); + } - public async Task RuntimeEnable(CancellationToken? cancellationToken = null) - { - await _connection.RuntimeEnable(cancellationToken); - } + public async Task GetDeviceInfo(CancellationToken? cancellationToken = null) + { + return await _connection.GetDeviceInfo(cancellationToken); + } - public async Task GetDeviceInfo(CancellationToken? cancellationToken = null) - { - return await _connection.GetDeviceInfo(cancellationToken); - } + public async Task GetFileList(string folder, bool includeCrcs, CancellationToken? cancellationToken = null) + { + return await _connection.GetFileList(folder, includeCrcs, cancellationToken); + } - public async Task GetFileList(string folder, bool includeCrcs, CancellationToken? cancellationToken = null) - { - return await _connection.GetFileList(folder, includeCrcs, cancellationToken); - } + public async Task ReadFile(string meadowFileName, string? localFileName = null, CancellationToken? cancellationToken = null) + { + return await _connection.ReadFile(meadowFileName, localFileName, cancellationToken); + } - public async Task ReadFile(string meadowFileName, string? localFileName = null, CancellationToken? cancellationToken = null) - { - return await _connection.ReadFile(meadowFileName, localFileName, cancellationToken); - } + public async Task WriteFile(string localFileName, string? meadowFileName = null, CancellationToken? cancellationToken = null) + { + return await _connection.WriteFile(localFileName, meadowFileName, cancellationToken); + } - public async Task WriteFile(string localFileName, string? meadowFileName = null, CancellationToken? cancellationToken = null) - { - return await _connection.WriteFile(localFileName, meadowFileName, cancellationToken); - } + public async Task WriteRuntime(string localFileName, CancellationToken? cancellationToken = null) + { + return await _connection.WriteRuntime(localFileName, cancellationToken); + } - public async Task WriteRuntime(string localFileName, CancellationToken? cancellationToken = null) + public async Task WriteCoprocessorFiles(string[] localFileNames, CancellationToken? cancellationToken = null) + { + foreach (var file in localFileNames) { - return await _connection.WriteRuntime(localFileName, cancellationToken); - } + var result = await _connection.WriteCoprocessorFile( + file, + GetFileTargetAddress(file), + cancellationToken); - public async Task WriteCoprocessorFiles(string[] localFileNames, CancellationToken? cancellationToken = null) - { - foreach (var file in localFileNames) + if (!result) { - var result = await _connection.WriteCoprocessorFile( - file, - GetFileTargetAddress(file), - cancellationToken); - - if (!result) - { - return false; - } + return false; } - - return true; } - public async Task UartTraceEnable(CancellationToken? cancellationToken = null) - { - await _connection.UartTraceEnable(cancellationToken); - } + return true; + } - public async Task UartTraceDisable(CancellationToken? cancellationToken = null) - { - await _connection.UartTraceDisable(cancellationToken); - } + public async Task UartTraceEnable(CancellationToken? cancellationToken = null) + { + await _connection.UartTraceEnable(cancellationToken); + } - public async Task UartProfilerEnable(CancellationToken? cancellationToken = null) - { - await _connection.UartProfilerEnable(cancellationToken); - } + public async Task UartTraceDisable(CancellationToken? cancellationToken = null) + { + await _connection.UartTraceDisable(cancellationToken); + } - public async Task UartProfilerDisable(CancellationToken? cancellationToken = null) - { - await _connection.UartProfilerDisable(cancellationToken); - } + public async Task UartProfilerEnable(CancellationToken? cancellationToken = null) + { + await _connection.UartProfilerEnable(cancellationToken); + } - private int GetFileTargetAddress(string fileName) - { - // TODO: determine device type so we can map the file names to target locations - // for now we only support the F7 so these are static and well-known + public async Task UartProfilerDisable(CancellationToken? cancellationToken = null) + { + await _connection.UartProfilerDisable(cancellationToken); + } - var fn = Path.GetFileName(fileName).ToLower(); - switch (fn) - { - case "meadowcomms.bin": - return 0x10000; - case "bootloader.bin": - return 0x1000; - case "partition-table.bin": - return 0x8000; - default: throw new NotSupportedException($"Unsupported coprocessor file: '{fn}'"); - } - } + private int GetFileTargetAddress(string fileName) + { + // TODO: determine device type so we can map the file names to target locations + // for now we only support the F7 so these are static and well-known - public async Task GetRtcTime(CancellationToken? cancellationToken = null) + var fn = Path.GetFileName(fileName).ToLower(); + switch (fn) { - return await _connection.GetRtcTime(cancellationToken); + case "meadowcomms.bin": + return 0x10000; + case "bootloader.bin": + return 0x1000; + case "partition-table.bin": + return 0x8000; + default: throw new NotSupportedException($"Unsupported coprocessor file: '{fn}'"); } + } - public async Task SetRtcTime(DateTimeOffset dateTime, CancellationToken? cancellationToken = null) - { - await _connection.SetRtcTime(dateTime, cancellationToken); - } + public async Task GetRtcTime(CancellationToken? cancellationToken = null) + { + return await _connection.GetRtcTime(cancellationToken); + } - public async Task TraceEnable(CancellationToken? cancellationToken = null) - { - await _connection.TraceEnable(cancellationToken); - } + public async Task SetRtcTime(DateTimeOffset dateTime, CancellationToken? cancellationToken = null) + { + await _connection.SetRtcTime(dateTime, cancellationToken); + } - public async Task TraceDisable(CancellationToken? cancellationToken = null) - { - await _connection.TraceDisable(cancellationToken); - } + public async Task TraceEnable(CancellationToken? cancellationToken = null) + { + await _connection.TraceEnable(cancellationToken); + } - public async Task SetTraceLevel(int level, CancellationToken? cancellationToken = null) - { - await _connection.SetTraceLevel(level, cancellationToken); - } + public async Task TraceDisable(CancellationToken? cancellationToken = null) + { + await _connection.TraceDisable(cancellationToken); + } - public async Task SetDeveloperParameter(ushort parameter, uint value, CancellationToken? cancellationToken = null) - { - await _connection.SetDeveloperParameter(parameter, value, cancellationToken); - } + public async Task SetTraceLevel(int level, CancellationToken? cancellationToken = null) + { + await _connection.SetTraceLevel(level, cancellationToken); + } - public async Task DeleteFile(string meadowFileName, CancellationToken? cancellationToken = null) - { - await _connection.DeleteFile(meadowFileName, cancellationToken); - } + public async Task SetDeveloperParameter(ushort parameter, uint value, CancellationToken? cancellationToken = null) + { + await _connection.SetDeveloperParameter(parameter, value, cancellationToken); + } - public async Task EraseFlash(CancellationToken? cancellationToken = null) - { - await _connection.EraseFlash(cancellationToken); - } + public async Task DeleteFile(string meadowFileName, CancellationToken? cancellationToken = null) + { + await _connection.DeleteFile(meadowFileName, cancellationToken); + } - public async Task ReadFileString(string fileName, CancellationToken? cancellationToken = null) - { - return await _connection.ReadFileString(fileName, cancellationToken); - } + public async Task EraseFlash(CancellationToken? cancellationToken = null) + { + await _connection.EraseFlash(cancellationToken); + } - public async Task GetPublicKey(CancellationToken? cancellationToken = null) - { - return await _connection.GetPublicKey(cancellationToken); - } + public async Task ReadFileString(string fileName, CancellationToken? cancellationToken = null) + { + return await _connection.ReadFileString(fileName, cancellationToken); + } - public async Task StartDebugging(int port, ILogger? logger, CancellationToken? cancellationToken) - { - await _connection.StartDebugging(port, logger, cancellationToken); - } + public async Task GetPublicKey(CancellationToken? cancellationToken = null) + { + return await _connection.GetPublicKey(cancellationToken); + } - public async Task SendDebuggerData(byte[] debuggerData, uint userData, CancellationToken? cancellationToken) - { - await _connection.SendDebuggerData(debuggerData, userData, cancellationToken); - } + public async Task StartDebugging(int port, ILogger? logger, CancellationToken? cancellationToken) + { + await _connection.StartDebugging(port, logger, cancellationToken); + } + + public async Task SendDebuggerData(byte[] debuggerData, uint userData, CancellationToken? cancellationToken) + { + await _connection.SendDebuggerData(debuggerData, userData, cancellationToken); } } \ No newline at end of file diff --git a/Source/v2/Meadow.Hcom/Protocol.cs b/Source/v2/Meadow.Hcom/Protocol.cs index 0e7feb0d..61cf2731 100644 --- a/Source/v2/Meadow.Hcom/Protocol.cs +++ b/Source/v2/Meadow.Hcom/Protocol.cs @@ -1,38 +1,37 @@ -namespace Meadow.Hcom +namespace Meadow.Hcom; + +internal class Protocol { - internal class Protocol - { - // There is no length field. Since the packet boundaries are delimited and the - // header is fixed length. Therefore, any additional data length is easily - // determined. - public const UInt16 HCOM_PROTOCOL_HCOM_VERSION_NUMBER = 0x0008; - - // COBS needs a specific delimiter. Zero seems to be traditional. - public const UInt16 HCOM_PROTOCOL_COBS_ENCODING_DELIMITER_VALUE = 0x00; - - // What sequence number is used to identify a non-data message? - public const UInt16 HCOM_PROTOCOL_NON_DATA_SEQUENCE_NUMBER = 0; - - // Note: while the MD5 hash is 128-bits (16-bytes), it is 32 character - // hex string from ESP32 - public const UInt16 HCOM_PROTOCOL_COMMAND_MD5_HASH_LENGTH = 32; - - // Define the absolute maximum packet sizes for sent and receive. - // Note: The length on the wire will be longer because it's encoded. - public const int HCOM_PROTOCOL_PACKET_MAX_SIZE = 8192; - public const int HCOM_PROTOCOL_ENCODED_MAX_SIZE = HCOM_PROTOCOL_PACKET_MAX_SIZE; - - // The maximum payload is max packet - header (12 bytes) - public const int HCOM_PROTOCOL_DATA_MAX_SIZE = HCOM_PROTOCOL_PACKET_MAX_SIZE - 12; - - //static public int HcomProtoHdrMessageSize() - //{ - // return Marshal.SizeOf(typeof(HcomProtoHdrMessage)); - //} - - //static public int HcomProtoFSInfoMsgSize() - //{ - // return Marshal.SizeOf(typeof(HcomProtoFSInfoMsg)); - //} - } + // There is no length field. Since the packet boundaries are delimited and the + // header is fixed length. Therefore, any additional data length is easily + // determined. + public const UInt16 HCOM_PROTOCOL_HCOM_VERSION_NUMBER = 0x0008; + + // COBS needs a specific delimiter. Zero seems to be traditional. + public const UInt16 HCOM_PROTOCOL_COBS_ENCODING_DELIMITER_VALUE = 0x00; + + // What sequence number is used to identify a non-data message? + public const UInt16 HCOM_PROTOCOL_NON_DATA_SEQUENCE_NUMBER = 0; + + // Note: while the MD5 hash is 128-bits (16-bytes), it is 32 character + // hex string from ESP32 + public const UInt16 HCOM_PROTOCOL_COMMAND_MD5_HASH_LENGTH = 32; + + // Define the absolute maximum packet sizes for sent and receive. + // Note: The length on the wire will be longer because it's encoded. + public const int HCOM_PROTOCOL_PACKET_MAX_SIZE = 8192; + public const int HCOM_PROTOCOL_ENCODED_MAX_SIZE = HCOM_PROTOCOL_PACKET_MAX_SIZE; + + // The maximum payload is max packet - header (12 bytes) + public const int HCOM_PROTOCOL_DATA_MAX_SIZE = HCOM_PROTOCOL_PACKET_MAX_SIZE - 12; + + //static public int HcomProtoHdrMessageSize() + //{ + // return Marshal.SizeOf(typeof(HcomProtoHdrMessage)); + //} + + //static public int HcomProtoFSInfoMsgSize() + //{ + // return Marshal.SizeOf(typeof(HcomProtoFSInfoMsg)); + //} } \ No newline at end of file diff --git a/Source/v2/Meadow.Hcom/ProtocolType.cs b/Source/v2/Meadow.Hcom/ProtocolType.cs index 7addac69..a4245bff 100644 --- a/Source/v2/Meadow.Hcom/ProtocolType.cs +++ b/Source/v2/Meadow.Hcom/ProtocolType.cs @@ -1,31 +1,30 @@ -namespace Meadow.Hcom +namespace Meadow.Hcom; + +//-------------------------------------------------------------------------- +// HCOM Protocol message type definitions +//-------------------------------------------------------------------------- +public enum ProtocolType : UInt16 { - //-------------------------------------------------------------------------- - // HCOM Protocol message type definitions - //-------------------------------------------------------------------------- - public enum ProtocolType : UInt16 - { - // When the time comes the following Major types should reflect the - // name of the above structure is used to send it. - HCOM_PROTOCOL_HEADER_UNDEFINED_TYPE = 0x0000, + // When the time comes the following Major types should reflect the + // name of the above structure is used to send it. + HCOM_PROTOCOL_HEADER_UNDEFINED_TYPE = 0x0000, - // The header of all mesasges include a 4-byte field called user data. The - // User data field's meaning is determined by the message type + // The header of all mesasges include a 4-byte field called user data. The + // User data field's meaning is determined by the message type - // Header only request types, - HCOM_PROTOCOL_HEADER_ONLY_TYPE = 0x0100, + // Header only request types, + HCOM_PROTOCOL_HEADER_ONLY_TYPE = 0x0100, - // File related types includes 4-byte user data (used for the destination - // partition id), 4-byte file size, 4-byte checksum, 4-byte destination address - // and variable length destination file name. Note: The 4-byte destination address - // is currently only used for the STM32F7 to ESP32 downloads. - HCOM_PROTOCOL_HEADER_FILE_START_TYPE = 0x0200, + // File related types includes 4-byte user data (used for the destination + // partition id), 4-byte file size, 4-byte checksum, 4-byte destination address + // and variable length destination file name. Note: The 4-byte destination address + // is currently only used for the STM32F7 to ESP32 downloads. + HCOM_PROTOCOL_HEADER_FILE_START_TYPE = 0x0200, - // Simple text is a header followed by text without a terminating NULL. - HCOM_PROTOCOL_HEADER_SIMPLE_TEXT_TYPE = 0x0300, + // Simple text is a header followed by text without a terminating NULL. + HCOM_PROTOCOL_HEADER_SIMPLE_TEXT_TYPE = 0x0300, - // Simple binary is a header followed by binary data. The size of the data - // can be up to HCOM_PROTOCOL_PACKET_MAX_SIZE minus header size - HCOM_PROTOCOL_HEADER_SIMPLE_BINARY_TYPE = 0x0400, - } + // Simple binary is a header followed by binary data. The size of the data + // can be up to HCOM_PROTOCOL_PACKET_MAX_SIZE minus header size + HCOM_PROTOCOL_HEADER_SIMPLE_BINARY_TYPE = 0x0400, } \ No newline at end of file diff --git a/Source/v2/Meadow.Hcom/SerialRequests/DebuggerDataRequest.cs b/Source/v2/Meadow.Hcom/SerialRequests/DebuggerDataRequest.cs index b41fc660..4a725113 100644 --- a/Source/v2/Meadow.Hcom/SerialRequests/DebuggerDataRequest.cs +++ b/Source/v2/Meadow.Hcom/SerialRequests/DebuggerDataRequest.cs @@ -1,20 +1,19 @@ -namespace Meadow.Hcom +namespace Meadow.Hcom; + +internal class DebuggerDataRequest : Request { - internal class DebuggerDataRequest : Request - { - public override RequestType RequestType => RequestType.HCOM_MDOW_REQUEST_DEBUGGING_DEBUGGER_DATA; + public override RequestType RequestType => RequestType.HCOM_MDOW_REQUEST_DEBUGGING_DEBUGGER_DATA; - public byte[] DebuggerData + public byte[] DebuggerData + { + get + { + if (Payload == null) return new byte[0]; + return Payload; + } + set { - get - { - if (Payload == null) return new byte[0]; - return Payload; - } - set - { - Payload = value; - } + Payload = value; } } } \ No newline at end of file diff --git a/Source/v2/Meadow.Hcom/SerialRequests/FileDeleteRequest.cs b/Source/v2/Meadow.Hcom/SerialRequests/FileDeleteRequest.cs index 857d8e6d..ff98608f 100644 --- a/Source/v2/Meadow.Hcom/SerialRequests/FileDeleteRequest.cs +++ b/Source/v2/Meadow.Hcom/SerialRequests/FileDeleteRequest.cs @@ -1,6 +1,4 @@ -using System.Text; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; internal class FileDeleteRequest : Request { diff --git a/Source/v2/Meadow.Hcom/SerialRequests/FileInitialBytesRequest.cs b/Source/v2/Meadow.Hcom/SerialRequests/FileInitialBytesRequest.cs index f9aeb82a..8745e3f7 100644 --- a/Source/v2/Meadow.Hcom/SerialRequests/FileInitialBytesRequest.cs +++ b/Source/v2/Meadow.Hcom/SerialRequests/FileInitialBytesRequest.cs @@ -1,6 +1,4 @@ -using System.Text; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; internal class FileInitialBytesRequest : Request { diff --git a/Source/v2/Meadow.Hcom/SerialRequests/GetDeviceInfoRequest.cs b/Source/v2/Meadow.Hcom/SerialRequests/GetDeviceInfoRequest.cs index 7c01c5d7..fd750ef1 100644 --- a/Source/v2/Meadow.Hcom/SerialRequests/GetDeviceInfoRequest.cs +++ b/Source/v2/Meadow.Hcom/SerialRequests/GetDeviceInfoRequest.cs @@ -1,16 +1,15 @@ -namespace Meadow.Hcom +namespace Meadow.Hcom; + +internal class GetDeviceInfoRequest : Request { - internal class GetDeviceInfoRequest : Request - { - public override RequestType RequestType => RequestType.HCOM_MDOW_REQUEST_GET_DEVICE_INFORMATION; + public override RequestType RequestType => RequestType.HCOM_MDOW_REQUEST_GET_DEVICE_INFORMATION; - public GetDeviceInfoRequest() - { - } - // Serialized example: - // message - // 01-00-07-00-12-01-00-00-00-00-00-00" - // encoded - // 00-02-2A-02-06-03-12-01-01-01-01-01-01-01-00 + public GetDeviceInfoRequest() + { } + // Serialized example: + // message + // 01-00-07-00-12-01-00-00-00-00-00-00" + // encoded + // 00-02-2A-02-06-03-12-01-01-01-01-01-01-01-00 } \ No newline at end of file diff --git a/Source/v2/Meadow.Hcom/SerialRequests/GetFileListRequest.cs b/Source/v2/Meadow.Hcom/SerialRequests/GetFileListRequest.cs index 7d8b4ee9..09f83b83 100644 --- a/Source/v2/Meadow.Hcom/SerialRequests/GetFileListRequest.cs +++ b/Source/v2/Meadow.Hcom/SerialRequests/GetFileListRequest.cs @@ -1,6 +1,4 @@ -using System.Text; - -namespace Meadow.Hcom +namespace Meadow.Hcom { internal class GetFileListRequest : Request { diff --git a/Source/v2/Meadow.Hcom/SerialRequests/InitFileReadRequest.cs b/Source/v2/Meadow.Hcom/SerialRequests/InitFileReadRequest.cs index cdd9001d..666eae41 100644 --- a/Source/v2/Meadow.Hcom/SerialRequests/InitFileReadRequest.cs +++ b/Source/v2/Meadow.Hcom/SerialRequests/InitFileReadRequest.cs @@ -1,6 +1,4 @@ -using System.Text; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; internal class InitFileReadRequest : Request { diff --git a/Source/v2/Meadow.Hcom/SerialRequests/InitFileWriteRequest.cs b/Source/v2/Meadow.Hcom/SerialRequests/InitFileWriteRequest.cs index ad6cb803..6c5480c9 100644 --- a/Source/v2/Meadow.Hcom/SerialRequests/InitFileWriteRequest.cs +++ b/Source/v2/Meadow.Hcom/SerialRequests/InitFileWriteRequest.cs @@ -1,6 +1,4 @@ -using System.Text; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; internal static class NuttxCrc { diff --git a/Source/v2/Meadow.Hcom/SerialRequests/RequestBuilder.cs b/Source/v2/Meadow.Hcom/SerialRequests/RequestBuilder.cs index c20117a2..b3279eae 100644 --- a/Source/v2/Meadow.Hcom/SerialRequests/RequestBuilder.cs +++ b/Source/v2/Meadow.Hcom/SerialRequests/RequestBuilder.cs @@ -1,19 +1,18 @@ -namespace Meadow.Hcom +namespace Meadow.Hcom; + +public static class RequestBuilder { - public static class RequestBuilder - { - //private static uint _sequenceNumber; + //private static uint _sequenceNumber; - public static T Build(uint userData = 0, ushort extraData = 0, ushort protocol = Protocol.HCOM_PROTOCOL_HCOM_VERSION_NUMBER) - where T : Request, new() + public static T Build(uint userData = 0, ushort extraData = 0, ushort protocol = Protocol.HCOM_PROTOCOL_HCOM_VERSION_NUMBER) + where T : Request, new() + { + return new T { - return new T - { - SequenceNumber = 0, - ProtocolVersion = protocol, - UserData = userData, - ExtraData = extraData - }; - } + SequenceNumber = 0, + ProtocolVersion = protocol, + UserData = userData, + ExtraData = extraData + }; } } \ No newline at end of file diff --git a/Source/v2/Meadow.Hcom/SerialRequests/ResetDeviceRequest.cs b/Source/v2/Meadow.Hcom/SerialRequests/ResetDeviceRequest.cs index b9529e52..ce9ff926 100644 --- a/Source/v2/Meadow.Hcom/SerialRequests/ResetDeviceRequest.cs +++ b/Source/v2/Meadow.Hcom/SerialRequests/ResetDeviceRequest.cs @@ -1,16 +1,15 @@ -namespace Meadow.Hcom +namespace Meadow.Hcom; + +internal class ResetDeviceRequest : Request { - internal class ResetDeviceRequest : Request - { - public override RequestType RequestType => RequestType.HCOM_MDOW_REQUEST_RESTART_PRIMARY_MCU; + public override RequestType RequestType => RequestType.HCOM_MDOW_REQUEST_RESTART_PRIMARY_MCU; - public ResetDeviceRequest() - { - } - // Serialized example: - // message - // 01-00-07-00-12-01-00-00-00-00-00-00" - // encoded - // 00-02-2A-02-06-03-12-01-01-01-01-01-01-01-00 + public ResetDeviceRequest() + { } + // Serialized example: + // message + // 01-00-07-00-12-01-00-00-00-00-00-00" + // encoded + // 00-02-2A-02-06-03-12-01-01-01-01-01-01-01-00 } \ No newline at end of file diff --git a/Source/v2/Meadow.Hcom/SerialRequests/SetRtcTimeRequest.cs b/Source/v2/Meadow.Hcom/SerialRequests/SetRtcTimeRequest.cs index 41bb7400..9ddf2b4b 100644 --- a/Source/v2/Meadow.Hcom/SerialRequests/SetRtcTimeRequest.cs +++ b/Source/v2/Meadow.Hcom/SerialRequests/SetRtcTimeRequest.cs @@ -1,6 +1,4 @@ -using System.Text; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; internal class SetRtcTimeRequest : Request { diff --git a/Source/v2/Meadow.Hcom/SerialRequests/StartDebuggingRequest.cs b/Source/v2/Meadow.Hcom/SerialRequests/StartDebuggingRequest.cs index 7bcdd5a5..e2a45dcf 100644 --- a/Source/v2/Meadow.Hcom/SerialRequests/StartDebuggingRequest.cs +++ b/Source/v2/Meadow.Hcom/SerialRequests/StartDebuggingRequest.cs @@ -1,7 +1,6 @@ -namespace Meadow.Hcom +namespace Meadow.Hcom; + +internal class StartDebuggingRequest : Request { - internal class StartDebuggingRequest : Request - { - public override RequestType RequestType => RequestType.HCOM_MDOW_REQUEST_MONO_START_DBG_SESSION; - } + public override RequestType RequestType => RequestType.HCOM_MDOW_REQUEST_MONO_START_DBG_SESSION; } \ No newline at end of file diff --git a/Source/v2/Meadow.Hcom/SerialResponses/DeviceInfoSerialResponse.cs b/Source/v2/Meadow.Hcom/SerialResponses/DeviceInfoSerialResponse.cs index bd6bd967..72b127de 100644 --- a/Source/v2/Meadow.Hcom/SerialResponses/DeviceInfoSerialResponse.cs +++ b/Source/v2/Meadow.Hcom/SerialResponses/DeviceInfoSerialResponse.cs @@ -1,6 +1,4 @@ -using System.Text; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; internal class DeviceInfoSerialResponse : SerialResponse { diff --git a/Source/v2/Meadow.Hcom/SerialResponses/FileDownloadFailedResponse.cs b/Source/v2/Meadow.Hcom/SerialResponses/FileDownloadFailedResponse.cs index 26e08104..4437e016 100644 --- a/Source/v2/Meadow.Hcom/SerialResponses/FileDownloadFailedResponse.cs +++ b/Source/v2/Meadow.Hcom/SerialResponses/FileDownloadFailedResponse.cs @@ -1,6 +1,4 @@ -using System.Text; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; internal class FileDownloadFailedResponse : SerialResponse { diff --git a/Source/v2/Meadow.Hcom/SerialResponses/FileInitialBytesSerialResponse.cs b/Source/v2/Meadow.Hcom/SerialResponses/FileInitialBytesSerialResponse.cs index 40705237..cc3003e0 100644 --- a/Source/v2/Meadow.Hcom/SerialResponses/FileInitialBytesSerialResponse.cs +++ b/Source/v2/Meadow.Hcom/SerialResponses/FileInitialBytesSerialResponse.cs @@ -1,6 +1,4 @@ -using System.Text; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; internal class TextPayloadSerialResponse : SerialResponse { diff --git a/Source/v2/Meadow.Hcom/SerialResponses/FileWriteInitFailedSerialResponse.cs b/Source/v2/Meadow.Hcom/SerialResponses/FileWriteInitFailedSerialResponse.cs index 2135f2ea..48b815d9 100644 --- a/Source/v2/Meadow.Hcom/SerialResponses/FileWriteInitFailedSerialResponse.cs +++ b/Source/v2/Meadow.Hcom/SerialResponses/FileWriteInitFailedSerialResponse.cs @@ -1,7 +1,4 @@ -using System.Diagnostics; -using System.Text; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; internal class FileWriteInitFailedSerialResponse : SerialResponse { diff --git a/Source/v2/Meadow.Hcom/SerialResponses/ReconnectRequiredResponse.cs b/Source/v2/Meadow.Hcom/SerialResponses/ReconnectRequiredResponse.cs index fb7cd09c..2fdf16c3 100644 --- a/Source/v2/Meadow.Hcom/SerialResponses/ReconnectRequiredResponse.cs +++ b/Source/v2/Meadow.Hcom/SerialResponses/ReconnectRequiredResponse.cs @@ -1,6 +1,4 @@ -using System.Text; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; internal class ReconnectRequiredResponse : SerialResponse { diff --git a/Source/v2/Meadow.Hcom/SerialResponses/RequestErrorTextResponse.cs b/Source/v2/Meadow.Hcom/SerialResponses/RequestErrorTextResponse.cs index 4b152af2..2f6dc9d9 100644 --- a/Source/v2/Meadow.Hcom/SerialResponses/RequestErrorTextResponse.cs +++ b/Source/v2/Meadow.Hcom/SerialResponses/RequestErrorTextResponse.cs @@ -1,6 +1,4 @@ -using System.Text; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; internal class RequestErrorTextResponse : SerialResponse { diff --git a/Source/v2/Meadow.Hcom/SerialResponses/TextAcceptedResponse.cs b/Source/v2/Meadow.Hcom/SerialResponses/TextAcceptedResponse.cs index 54e044c5..4a0e9798 100644 --- a/Source/v2/Meadow.Hcom/SerialResponses/TextAcceptedResponse.cs +++ b/Source/v2/Meadow.Hcom/SerialResponses/TextAcceptedResponse.cs @@ -1,6 +1,4 @@ -using System.Text; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; internal class TextAcceptedResponse : SerialResponse { diff --git a/Source/v2/Meadow.Hcom/SerialResponses/TextCrcMemberResponse.cs b/Source/v2/Meadow.Hcom/SerialResponses/TextCrcMemberResponse.cs index ef3d64bb..64a7284b 100644 --- a/Source/v2/Meadow.Hcom/SerialResponses/TextCrcMemberResponse.cs +++ b/Source/v2/Meadow.Hcom/SerialResponses/TextCrcMemberResponse.cs @@ -1,6 +1,4 @@ -using System.Text; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; internal class TextCrcMemberResponse : SerialResponse { diff --git a/Source/v2/Meadow.Hcom/SerialResponses/TextInformationResponse.cs b/Source/v2/Meadow.Hcom/SerialResponses/TextInformationResponse.cs index f18d80ed..93d89564 100644 --- a/Source/v2/Meadow.Hcom/SerialResponses/TextInformationResponse.cs +++ b/Source/v2/Meadow.Hcom/SerialResponses/TextInformationResponse.cs @@ -1,6 +1,4 @@ -using System.Text; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; /// /// An unsolicited text response sent by HCOM (i.e. typically a Console.Write) diff --git a/Source/v2/Meadow.Hcom/SerialResponses/TextListMemberResponse.cs b/Source/v2/Meadow.Hcom/SerialResponses/TextListMemberResponse.cs index d6a89661..a44a7c5f 100644 --- a/Source/v2/Meadow.Hcom/SerialResponses/TextListMemberResponse.cs +++ b/Source/v2/Meadow.Hcom/SerialResponses/TextListMemberResponse.cs @@ -1,6 +1,4 @@ -using System.Text; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; internal class TextListMemberResponse : SerialResponse { diff --git a/Source/v2/Meadow.Hcom/SerialResponses/TextRequestRejectedResponse.cs b/Source/v2/Meadow.Hcom/SerialResponses/TextRequestRejectedResponse.cs index 2f6e0023..0c5075e2 100644 --- a/Source/v2/Meadow.Hcom/SerialResponses/TextRequestRejectedResponse.cs +++ b/Source/v2/Meadow.Hcom/SerialResponses/TextRequestRejectedResponse.cs @@ -1,7 +1,4 @@ -using System.Diagnostics; -using System.Text; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; internal class TextRequestRejectedResponse : SerialResponse { diff --git a/Source/v2/Meadow.Hcom/SerialResponses/TextRequestResponse.cs b/Source/v2/Meadow.Hcom/SerialResponses/TextRequestResponse.cs index aee3a25c..6ed62390 100644 --- a/Source/v2/Meadow.Hcom/SerialResponses/TextRequestResponse.cs +++ b/Source/v2/Meadow.Hcom/SerialResponses/TextRequestResponse.cs @@ -1,6 +1,4 @@ -using System.Text; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; /// /// A text response to a solicited host request diff --git a/Source/v2/Meadow.Hcom/SerialResponses/TextStdErrResponse.cs b/Source/v2/Meadow.Hcom/SerialResponses/TextStdErrResponse.cs index e19173bc..2b7677fa 100644 --- a/Source/v2/Meadow.Hcom/SerialResponses/TextStdErrResponse.cs +++ b/Source/v2/Meadow.Hcom/SerialResponses/TextStdErrResponse.cs @@ -1,6 +1,4 @@ -using System.Text; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; internal class TextStdErrResponse : SerialResponse { diff --git a/Source/v2/Meadow.Hcom/SerialResponses/TextStdOutResponse.cs b/Source/v2/Meadow.Hcom/SerialResponses/TextStdOutResponse.cs index 2d40264f..4c2218ec 100644 --- a/Source/v2/Meadow.Hcom/SerialResponses/TextStdOutResponse.cs +++ b/Source/v2/Meadow.Hcom/SerialResponses/TextStdOutResponse.cs @@ -1,6 +1,4 @@ -using System.Text; - -namespace Meadow.Hcom; +namespace Meadow.Hcom; internal class TextStdOutResponse : SerialResponse { diff --git a/Source/v2/Meadow.Hcom/Usings.cs b/Source/v2/Meadow.Hcom/Usings.cs new file mode 100644 index 00000000..ffaad68c --- /dev/null +++ b/Source/v2/Meadow.Hcom/Usings.cs @@ -0,0 +1,12 @@ +global using Microsoft.Extensions.Logging; +global using System; +global using System.Collections.Generic; +global using System.Diagnostics; +global using System.IO; +global using System.Linq; +global using System.Net.Http; +global using System.Text; +global using System.Text.Json; +global using System.Text.Json.Serialization; +global using System.Threading; +global using System.Threading.Tasks; diff --git a/Source/v2/Meadow.Linker/Linker/MeadowLinker.cs b/Source/v2/Meadow.Linker/Linker/MeadowLinker.cs index 2838e511..5f3d7b73 100644 --- a/Source/v2/Meadow.Linker/Linker/MeadowLinker.cs +++ b/Source/v2/Meadow.Linker/Linker/MeadowLinker.cs @@ -18,9 +18,8 @@ public class MeadowLinker public const string PostLinkDirectoryName = "postlink_bin"; public const string PreLinkDirectoryName = "prelink_bin"; - - readonly ILLinker _linker; - readonly ILogger? _logger; + private readonly ILLinker _linker; + private readonly ILogger? _logger; //ToDo ... might need to make this a property or pass it in when used private readonly string _meadowAssembliesPath; @@ -35,7 +34,7 @@ public MeadowLinker(string meadowAssembliesPath, ILogger? logger = null) public async Task Trim( FileInfo meadowAppFile, bool includePdbs = false, - IList? noLink = null) + IEnumerable? noLink = null) { var dependencies = MapDependencies(meadowAppFile); @@ -89,7 +88,7 @@ public void CopyDependenciesToPreLinkFolder( private async Task> TrimMeadowApp( FileInfo file, - IList? noLink) + IEnumerable? noLink) { //set up the paths var prelink_dir = Path.Combine(file.DirectoryName!, PreLinkDirectoryName); @@ -146,7 +145,7 @@ private List GetDependencies(string assemblyPath, Collection x.Contains("App.") == false).ToList(); } - static string? FindAssemblyFullPath(string fileName, string localPath, string meadowAssembliesPath) + private static string? FindAssemblyFullPath(string fileName, string localPath, string meadowAssembliesPath) { //Assembly may not have a file extension, add .dll if it doesn't if (Path.GetExtension(fileName) != ".exe" && diff --git a/Source/v2/Meadow.Tooling.Core/Connection/MeadowConnectionManager.cs b/Source/v2/Meadow.Tooling.Core/Connection/MeadowConnectionManager.cs index bebd6c76..b982d1b6 100644 --- a/Source/v2/Meadow.Tooling.Core/Connection/MeadowConnectionManager.cs +++ b/Source/v2/Meadow.Tooling.Core/Connection/MeadowConnectionManager.cs @@ -209,6 +209,11 @@ public static async Task> GetMeadowSerialPortsForLinux() _ = proc?.WaitForExit(1000); var output = proc?.StandardOutput.ReadToEnd(); + if (output == null) + { + return Array.Empty(); + } + return output.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries) .Where(x => x.Contains("Wilderness_Labs")) .Select( diff --git a/Source/v2/Meadow.Tooling.Core/Package/IPackageManager.cs b/Source/v2/Meadow.Tooling.Core/Package/IPackageManager.cs index e8b34056..ef8e4ea1 100644 --- a/Source/v2/Meadow.Tooling.Core/Package/IPackageManager.cs +++ b/Source/v2/Meadow.Tooling.Core/Package/IPackageManager.cs @@ -18,7 +18,7 @@ bool BuildApplication( Task TrimApplication( FileInfo applicationFilePath, bool includePdbs = false, - IList? noLink = null, + IEnumerable? noLink = null, CancellationToken? cancellationToken = null); Task AssemblePackage(string contentSourceFolder, diff --git a/Source/v2/Meadow.Tooling.Core/Package/PackageManager.cs b/Source/v2/Meadow.Tooling.Core/Package/PackageManager.cs index 9ef23d46..76c3e437 100644 --- a/Source/v2/Meadow.Tooling.Core/Package/PackageManager.cs +++ b/Source/v2/Meadow.Tooling.Core/Package/PackageManager.cs @@ -131,7 +131,7 @@ public bool BuildApplication(string projectFilePath, string configuration = "Rel public Task TrimApplication( FileInfo applicationFilePath, bool includePdbs = false, - IList? noLink = null, + IEnumerable? noLink = null, CancellationToken? cancellationToken = null) { if (!applicationFilePath.Exists)