diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-11-29 18:59:41 +0200 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-11-29 18:59:41 +0200 |
| commit | dd724f118f584eea84a11af90292a88c62ecd022 (patch) | |
| tree | 714e7c0dfb12887ed20d85b0aa5c2b6c24743b44 /Software | |
| parent | 1e2ae1c1973fd5661815f18c93ee1171a5c08da5 (diff) | |
| download | Tango-dd724f118f584eea84a11af90292a88c62ecd022.tar.gz Tango-dd724f118f584eea84a11af90292a88c62ecd022.zip | |
Working on Firmware upgrade !
Diffstat (limited to 'Software')
29 files changed, 993 insertions, 195 deletions
diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf Binary files differindex 31fca8645..355832ca0 100644 --- a/Software/DB/Tango.mdf +++ b/Software/DB/Tango.mdf diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf Binary files differindex dbb972b80..e4f508570 100644 --- a/Software/DB/Tango_log.ldf +++ b/Software/DB/Tango_log.ldf diff --git a/Software/Graphics/firmware_upgrade.png b/Software/Graphics/firmware_upgrade.png Binary files differnew file mode 100644 index 000000000..fc0799143 --- /dev/null +++ b/Software/Graphics/firmware_upgrade.png diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/Tango.MachineStudio.Storage.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/Tango.MachineStudio.Storage.csproj index 991e9fa2e..bceaf7158 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/Tango.MachineStudio.Storage.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/Tango.MachineStudio.Storage.csproj @@ -93,6 +93,7 @@ <Generator>ResXFileCodeGenerator</Generator> <LastGenOutput>Resources.Designer.cs</LastGenOutput> </EmbeddedResource> + <None Include="app.config" /> <None Include="packages.config" /> <None Include="Properties\Settings.settings"> <Generator>SettingsSingleFileGenerator</Generator> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/ViewModels/MainViewVM.cs index 12bb8242a..a9cfed937 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/ViewModels/MainViewVM.cs @@ -12,6 +12,7 @@ using Tango.Core.IO; using Tango.Integration.ExternalBridge; using Tango.Integration.Storage; using Tango.MachineStudio.Common; +using Tango.MachineStudio.Common.FirmwareUpgrade; using Tango.MachineStudio.Common.Notifications; using Tango.MachineStudio.Common.StudioApplication; using Tango.MachineStudio.Storage.Models; @@ -24,6 +25,7 @@ namespace Tango.MachineStudio.Storage.ViewModels private IStudioApplicationManager _applicationManager; private INotificationProvider _notification; + private IFirmwareUpgrader _firmwareUpgrader; private bool _machine_operator_changed = true; private StorageManager _storageManager; @@ -71,10 +73,13 @@ namespace Tango.MachineStudio.Storage.ViewModels public RelayCommand UploadFileCommand { get; set; } - public MainViewVM(IStudioApplicationManager applicationManager, INotificationProvider notificationProvider) + public RelayCommand UploadVersionCommand { get; set; } + + public MainViewVM(IStudioApplicationManager applicationManager, INotificationProvider notificationProvider, IFirmwareUpgrader firmwareUpgrader) { _applicationManager = applicationManager; _notification = notificationProvider; + _firmwareUpgrader = firmwareUpgrader; _applicationManager.ConnectedMachineChanged += _applicationManager_ConnectedMachineChanged; FileHandlers = new ObservableCollection<StorageFileHandlerModel>(); @@ -90,6 +95,7 @@ namespace Tango.MachineStudio.Storage.ViewModels CreateFolderCommand = new RelayCommand(CreateFolder, () => StorageManager != null && StorageManager.CurrentFolder != null); DeleteFolderCommand = new RelayCommand(DeleteFolder, () => StorageManager != null && SelectedStorageItem != null && SelectedStorageItem is StorageFolder); UploadFileCommand = new RelayCommand(UploadFile, () => StorageManager != null && StorageManager.CurrentFolder != null); + UploadVersionCommand = new RelayCommand(UploadVersion, () => StorageManager != null && StorageManager.CurrentFolder != null); } private void UploadFile() @@ -351,5 +357,10 @@ namespace Tango.MachineStudio.Storage.ViewModels FileHandlers.Remove(handler); } } + + private void UploadVersion() + { + _firmwareUpgrader.InvokeUpgradeUI(); + } } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/Views/MainView.xaml index 311d18f54..1f435b696 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/Views/MainView.xaml @@ -62,10 +62,10 @@ </DockPanel> </Button> <Separator/> - <Button Margin="0 5 0 0" Style="{StaticResource MaterialDesignFlatButton}" Padding="20 10" Height="Auto" Foreground="#363636" HorizontalContentAlignment="Left"> + <Button Command="{Binding UploadVersionCommand}" Margin="0 5 0 0" Style="{StaticResource MaterialDesignFlatButton}" Padding="20 10" Height="Auto" Foreground="#363636" HorizontalContentAlignment="Left"> <DockPanel> <materialDesign:PackIcon Kind="BriefcaseUpload" Foreground="#833CEC" Width="32" Height="32" /> - <TextBlock VerticalAlignment="Center" Margin="20 0 0 0" FontSize="18">UPLOAD VERSION</TextBlock> + <TextBlock VerticalAlignment="Center" Margin="20 0 0 0" FontSize="18">UPGRADE VERSION</TextBlock> </DockPanel> </Button> <Button Margin="0 5 0 0" Style="{StaticResource MaterialDesignFlatButton}" Padding="20 10" Height="Auto" Foreground="#363636" HorizontalContentAlignment="Left"> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/app.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/app.config new file mode 100644 index 000000000..5d794b958 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/app.config @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="utf-8"?> +<configuration> + <runtime> + <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> + <dependentAssembly> + <assemblyIdentity name="System.Reactive.Core" publicKeyToken="94bc3704cddfc263" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-3.0.3000.0" newVersion="3.0.3000.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-1.2.2.0" newVersion="1.2.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Reflection.Metadata" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-1.4.2.0" newVersion="1.4.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IO.FileSystem" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IO.FileSystem.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Xml.XPath.XDocument" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Console" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Diagnostics.StackTrace" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" /> + </dependentAssembly> + </assemblyBinding> + </runtime> +</configuration>
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/FirmwareUpgrade/IFirmwareUpgrader.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/FirmwareUpgrade/IFirmwareUpgrader.cs new file mode 100644 index 000000000..4826a0e74 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/FirmwareUpgrade/IFirmwareUpgrader.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Integration.Operation; + +namespace Tango.MachineStudio.Common.FirmwareUpgrade +{ + /// <summary> + /// Firmware Upgrade Manager. + /// </summary> + public interface IFirmwareUpgrader + { + /// <summary> + /// Performs a firmware upgrade. + /// </summary> + /// <param name="tfpStream">The TFP stream.</param> + Task<FirmwareUpgradeHandler> PerformUpgrade(Stream tfpStream); + + /// <summary> + /// Invokes the upgrade dialog. + /// </summary> + void InvokeUpgradeUI(); + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj index 1fbd88167..8cf65a13d 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj @@ -98,6 +98,7 @@ <Compile Include="EventLogging\IEventLogger.cs" /> <Compile Include="ExtensionMethods\CommonDialogExtensions.cs" /> <Compile Include="ExtensionMethods\TangoIOCExtensions.cs" /> + <Compile Include="FirmwareUpgrade\IFirmwareUpgrader.cs" /> <Compile Include="Html\IHtmlPresenter.cs" /> <None Include="Helpers\GraphsHelper.cs" /> <Compile Include="IStudioViewModel.cs" /> @@ -303,7 +304,7 @@ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <ProjectExtensions> <VisualStudio> - <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" /> + <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" /> </VisualStudio> </ProjectExtensions> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/FirmwareUpgrade/DefaultFirmwareUpgrader.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/FirmwareUpgrade/DefaultFirmwareUpgrader.cs new file mode 100644 index 000000000..5568c82ac --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/FirmwareUpgrade/DefaultFirmwareUpgrader.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Integration.Operation; +using Tango.MachineStudio.Common.FirmwareUpgrade; +using Tango.MachineStudio.Common.Notifications; +using Tango.MachineStudio.Common.StudioApplication; +using Tango.MachineStudio.UI.ViewModels; +using Tango.MachineStudio.UI.Views; + +namespace Tango.MachineStudio.UI.FirmwareUpgrade +{ + /// <summary> + /// Default firmware upgrade manager. + /// </summary> + /// <seealso cref="Tango.MachineStudio.Common.FirmwareUpgrade.IFirmwareUpgrader" /> + public class DefaultFirmwareUpgrader : IFirmwareUpgrader + { + private IStudioApplicationManager _applicationManager; + private INotificationProvider _notification; + + /// <summary> + /// Initializes a new instance of the <see cref="DefaultFirmwareUpgrader"/> class. + /// </summary> + public DefaultFirmwareUpgrader(IStudioApplicationManager applicationManager, INotificationProvider notificationProvider) + { + _applicationManager = applicationManager; + _notification = notificationProvider; + } + + /// <summary> + /// Performs a firmware upgrade. + /// </summary> + /// <param name="tfpStream">The TFP stream.</param> + public Task<FirmwareUpgradeHandler> PerformUpgrade(Stream tfpStream) + { + return _applicationManager.ConnectedMachine.UpgradeFirmware(tfpStream); + } + + /// <summary> + /// Invokes the upgrade dialog. + /// </summary> + public void InvokeUpgradeUI() + { + FirmwareUpgradeViewVM vm = new FirmwareUpgradeViewVM(_applicationManager.ConnectedMachine); + + _notification.ShowModalDialog<FirmwareUpgradeViewVM, FirmwareUpgradeView>(vm, (x) => + { + + }, () => { }); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/firmware_upgrade.png b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/firmware_upgrade.png Binary files differnew file mode 100644 index 000000000..fc0799143 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/firmware_upgrade.png diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj index 6e37a97a2..a9a0e1bb9 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj @@ -142,6 +142,7 @@ <DependentUpon>ConsoleWindow.xaml</DependentUpon> </Compile> <Compile Include="Console\ConsoleWindowVM.cs" /> + <Compile Include="FirmwareUpgrade\DefaultFirmwareUpgrader.cs" /> <Compile Include="Html\DefaultHtmlPresenter.cs" /> <Compile Include="Html\HtmlWindow.xaml.cs"> <DependentUpon>HtmlWindow.xaml</DependentUpon> @@ -172,6 +173,7 @@ <Compile Include="ViewModels\AboutViewVM.cs" /> <Compile Include="ViewModels\ConnectedMachineViewVM.cs" /> <Compile Include="ViewModels\ConnectionLostViewVM.cs" /> + <Compile Include="ViewModels\FirmwareUpgradeViewVM.cs" /> <Compile Include="ViewModels\LoadingViewVM.cs" /> <Compile Include="ViewModels\LoginViewVM.cs" /> <Compile Include="ViewModels\MachineConnectionViewVM.cs" /> @@ -193,6 +195,9 @@ <Compile Include="Views\ConnectionLostView.xaml.cs"> <DependentUpon>ConnectionLostView.xaml</DependentUpon> </Compile> + <Compile Include="Views\FirmwareUpgradeView.xaml.cs"> + <DependentUpon>FirmwareUpgradeView.xaml</DependentUpon> + </Compile> <Compile Include="Views\LoadingView.xaml.cs"> <DependentUpon>LoadingView.xaml</DependentUpon> </Compile> @@ -277,6 +282,10 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Views\FirmwareUpgradeView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="Views\LoadingView.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> @@ -505,6 +514,7 @@ <Resource Include="Images\settings.png" /> </ItemGroup> <ItemGroup> + <Resource Include="Images\firmware_upgrade.png" /> <Resource Include="Images\external-bridge-emulator.png" /> <EmbeddedResource Include="..\..\Versioning\ChangeLog.txt"> <Link>ChangeLog.txt</Link> @@ -599,7 +609,7 @@ copy /Y "$(SolutionDir)Referenced Assemblies\Microsoft.WITDataStore32.dll" "$(Ta </Target> <ProjectExtensions> <VisualStudio> - <UserProperties BuildVersion_UseGlobalSettings="False" BuildVersion_DetectChanges="True" BuildVersion_UpdateFileVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.DeltaBaseYearDayOfYear" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_StartDate="2000/1/1" /> + <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_BuildVersioningStyle="None.None.Increment.DeltaBaseYearDayOfYear" BuildVersion_UpdateFileVersion="True" BuildVersion_DetectChanges="True" BuildVersion_UseGlobalSettings="False" /> </VisualStudio> </ProjectExtensions> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs index 8bb33d007..cac4ee0c0 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs @@ -6,6 +6,7 @@ using Tango.Logging; using Tango.MachineStudio.Common.Authentication; using Tango.MachineStudio.Common.Diagnostics; using Tango.MachineStudio.Common.EventLogging; +using Tango.MachineStudio.Common.FirmwareUpgrade; using Tango.MachineStudio.Common.Html; using Tango.MachineStudio.Common.JobRunsLogging; using Tango.MachineStudio.Common.Modules; @@ -17,6 +18,7 @@ using Tango.MachineStudio.Common.Threading; using Tango.MachineStudio.Common.Video; using Tango.MachineStudio.UI.Authentication; using Tango.MachineStudio.UI.Console; +using Tango.MachineStudio.UI.FirmwareUpgrade; using Tango.MachineStudio.UI.Html; using Tango.MachineStudio.UI.Modules; using Tango.MachineStudio.UI.Navigation; @@ -70,6 +72,7 @@ namespace Tango.MachineStudio.UI TangoIOC.Default.Unregister<ITeamFoundationServiceClient>(); TangoIOC.Default.Unregister<IDispatcherProvider>(); TangoIOC.Default.Unregister<IJobRunsLogger>(); + TangoIOC.Default.Unregister<IFirmwareUpgrader>(); TangoIOC.Default.Register<IDispatcherProvider, DefaultDispatcherProvider>(new DefaultDispatcherProvider(Application.Current.Dispatcher)); @@ -85,6 +88,7 @@ namespace Tango.MachineStudio.UI TangoIOC.Default.Register<IEventLogger, DefaultEventLogger>(); TangoIOC.Default.Register<ISpeechProvider, DefaultSpeechProvider>(); TangoIOC.Default.Register<IHtmlPresenter, DefaultHtmlPresenter>(); + TangoIOC.Default.Register<IFirmwareUpgrader, DefaultFirmwareUpgrader>(); TangoIOC.Default.Register<TeamFoundationServiceExtendedClient>(new TeamFoundationServiceExtendedClient("https://twinetfs.visualstudio.com", String.Empty, "szzfokrceo4rhd4eqi5qpmxn3pa5iwl3q7tlqd36l2m7smz2ynoa")); diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/FirmwareUpgradeViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/FirmwareUpgradeViewVM.cs new file mode 100644 index 000000000..ce8b09aa4 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/FirmwareUpgradeViewVM.cs @@ -0,0 +1,100 @@ +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.Commands; +using Tango.Integration.Operation; +using Tango.SharedUI; + +namespace Tango.MachineStudio.UI.ViewModels +{ + public class FirmwareUpgradeViewVM : DialogViewVM + { + private IMachineOperator _operator; + private FileStream _stream; + + private FirmwareUpgradeHandler _handler; + public FirmwareUpgradeHandler Handler + { + get { return _handler; } + set { _handler = value; RaisePropertyChangedAuto(); } + } + + private String _selectedFile; + public String SelectedFile + { + get { return _selectedFile; } + set { _selectedFile = value; RaisePropertyChangedAuto(); } + } + + private int _currentPage; + public int CurrentPage + { + get { return _currentPage; } + set { _currentPage = value; RaisePropertyChangedAuto(); } + } + + public RelayCommand SelectCommand { get; set; } + + public RelayCommand UpgradeCommand { get; set; } + + public RelayCommand AbortCommand { get; set; } + + public FirmwareUpgradeViewVM(IMachineOperator machineOperator) : base() + { + _operator = machineOperator; + SelectCommand = new RelayCommand(BrowseForFile); + UpgradeCommand = new RelayCommand(StartUpgrade, () => SelectedFile != null); + AbortCommand = new RelayCommand(AbortUpgrade, () => Handler != null && Handler.Status != FirmwareUpgradeStatus.Validating && Handler.Status != FirmwareUpgradeStatus.Activating); + } + + private void BrowseForFile() + { + OpenFileDialog dlg = new OpenFileDialog(); + dlg.Title = "Select tango firmware package file"; + dlg.Filter = "Tango Firmware Package|*.tfp"; + if (dlg.ShowDialog().Value) + { + SelectedFile = dlg.FileName; + InvalidateRelayCommands(); + } + } + + private async void StartUpgrade() + { + CurrentPage = 1; + + _stream = new FileStream(SelectedFile, FileMode.Open); + Handler = await _operator.UpgradeFirmware(_stream); + Handler.Progress += (_, e) => + { + InvokeUI(() => + { + AbortCommand.RaiseCanExecuteChanged(); + }); + }; + Handler.Completed += (_, __) => + { + _stream.Dispose(); + CurrentPage = 2; + }; + Handler.Canceled += (_, __) => + { + _stream.Dispose(); + }; + Handler.Failed += (_, __) => + { + _stream.Dispose(); + }; + + } + + private async void AbortUpgrade() + { + await Handler.Cancel(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/FirmwareUpgradeView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/FirmwareUpgradeView.xaml new file mode 100644 index 000000000..b69ad6a5b --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/FirmwareUpgradeView.xaml @@ -0,0 +1,88 @@ +<UserControl x:Class="Tango.MachineStudio.UI.Views.FirmwareUpgradeView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="clr-namespace:Tango.MachineStudio.UI.Views" + xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:vm="clr-namespace:Tango.MachineStudio.UI.ViewModels" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" + mc:Ignorable="d" + d:DesignHeight="300" d:DesignWidth="300" Width="800" Height="400" Background="White" d:DataContext="{d:DesignInstance Type=vm:FirmwareUpgradeViewVM, IsDesignTimeCreatable=False}"> + + <UserControl.Resources> + <converters:EnumToDescriptionConverter x:Key="EnumToDescriptionConverter" /> + </UserControl.Resources> + + <Grid> + <Grid Margin="10"> + <Grid.RowDefinitions> + <RowDefinition Height="121"/> + <RowDefinition Height="1*"/> + </Grid.RowDefinitions> + + <Grid> + <StackPanel> + <StackPanel Orientation="Horizontal"> + <Image Source="/Images/firmware_upgrade.png" Height="100" /> + <TextBlock VerticalAlignment="Center" FontSize="30" FontWeight="SemiBold" Margin="20 0 0 0">FIRMWARE UPGRADE</TextBlock> + </StackPanel> + <Rectangle Stroke="Gainsboro" StrokeDashArray="5 5 5 5" Margin="20 10" /> + </StackPanel> + </Grid> + + <Grid Grid.Row="1"> + <controls:NavigationControl TransitionType="Zoom" SelectedIndex="{Binding CurrentPage}" TransitionDuration="00:00:0.3"> + + <Grid> + <Grid> + <Grid.RowDefinitions> + <RowDefinition Height="174*"/> + <RowDefinition Height="85*"/> + </Grid.RowDefinitions> + <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center"> + <TextBlock TextAlignment="Center"> + <Run>The upgrade wizard will help you upgrade the connected machine firmware version.</Run> + <LineBreak/> + <Run>Press 'SELECT' to browse for a .tfp file (Tango Firmware Package).</Run> + </TextBlock> + <DockPanel Margin="0 30 0 0" Width="600" HorizontalAlignment="Left"> + <Button DockPanel.Dock="Right" Margin="10 0 0 0" Command="{Binding SelectCommand}">SELECT</Button> + <TextBox Style="{x:Null}" VerticalContentAlignment="Center" BorderBrush="{StaticResource AccentColorBrush}" Padding="5 0" Foreground="DimGray" IsReadOnly="True" Text="{Binding SelectedFile,Mode=OneWay}"></TextBox> + </DockPanel> + </StackPanel> + + <Grid Height="60" Grid.Row="1"> + <Button Height="50" Width="200" VerticalAlignment="Top" Command="{Binding UpgradeCommand}"> + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Kind="Flash" Width="32" Height="32" /> + <TextBlock VerticalAlignment="Center" Margin="5 0 0 0">UPGRADE</TextBlock> + </StackPanel> + </Button> + </Grid> + </Grid> + </Grid> + + <Grid> + <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> + <TextBlock HorizontalAlignment="Center" FontSize="18" FontWeight="SemiBold">Upgrading Machine Firmware</TextBlock> + <TextBlock Margin="0 40 0 0" HorizontalAlignment="Center" Foreground="Gray" Text="{Binding Handler.Status,Converter={StaticResource EnumToDescriptionConverter},Mode=OneWay}"></TextBlock> + <ProgressBar Height="15" Width="600" Margin="0 5 0 0" Maximum="{Binding Handler.Total,Mode=OneWay}" Value="{Binding Handler.Current,Mode=OneWay}" ></ProgressBar> + <Button Width="150" Background="#FF5151" BorderBrush="#FF5151" Margin="0 40 0 0" Height="35" Command="{Binding AbortCommand}">ABORT</Button> + </StackPanel> + </Grid> + + <Grid> + <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> + <TextBlock HorizontalAlignment="Center" FontSize="18" FontWeight="SemiBold">Firmware Upgrade Completed</TextBlock> + <materialDesign:PackIcon HorizontalAlignment="Center" Width="100" Margin="0 10 0 0" Height="100" Kind="Check" Foreground="#2DCB2D" /> + <Button Width="150" Margin="0 10 0 0" Height="35" Command="{Binding CloseCommand}">CLOSE</Button> + </StackPanel> + </Grid> + </controls:NavigationControl> + </Grid> + + </Grid> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/FirmwareUpgradeView.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/FirmwareUpgradeView.xaml.cs new file mode 100644 index 000000000..17220e615 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/FirmwareUpgradeView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.MachineStudio.UI.Views +{ + /// <summary> + /// Interaction logic for FirmwareUpgradeView.xaml + /// </summary> + public partial class FirmwareUpgradeView : UserControl + { + public FirmwareUpgradeView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Events/app.config b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Events/app.config index 1e22e6a88..e67f6e7f8 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Events/app.config +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Events/app.config @@ -1,61 +1,65 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> - <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/> + <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> </configSections> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> - <assemblyIdentity name="System.Reactive.Core" publicKeyToken="94bc3704cddfc263" culture="neutral"/> - <bindingRedirect oldVersion="0.0.0.0-3.0.3000.0" newVersion="3.0.3000.0"/> + <assemblyIdentity name="System.Reactive.Core" publicKeyToken="94bc3704cddfc263" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-3.0.3000.0" newVersion="3.0.3000.0" /> </dependentAssembly> <dependentAssembly> - <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/> - <bindingRedirect oldVersion="0.0.0.0-1.2.2.0" newVersion="1.2.2.0"/> + <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-1.2.2.0" newVersion="1.2.2.0" /> </dependentAssembly> <dependentAssembly> - <assemblyIdentity name="System.Reflection.Metadata" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/> - <bindingRedirect oldVersion="0.0.0.0-1.4.2.0" newVersion="1.4.2.0"/> + <assemblyIdentity name="System.Reflection.Metadata" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-1.4.2.0" newVersion="1.4.2.0" /> </dependentAssembly> <dependentAssembly> - <assemblyIdentity name="System.IO.FileSystem" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/> - <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0"/> + <assemblyIdentity name="System.IO.FileSystem" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> </dependentAssembly> <dependentAssembly> - <assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral"/> - <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0"/> + <assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> </dependentAssembly> <dependentAssembly> - <assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral"/> - <bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0"/> + <assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" /> </dependentAssembly> <dependentAssembly> - <assemblyIdentity name="System.IO.FileSystem.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/> - <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0"/> + <assemblyIdentity name="System.IO.FileSystem.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> </dependentAssembly> <dependentAssembly> - <assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/> - <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0"/> + <assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" /> </dependentAssembly> <dependentAssembly> - <assemblyIdentity name="System.Xml.XPath.XDocument" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/> - <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0"/> + <assemblyIdentity name="System.Xml.XPath.XDocument" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> </dependentAssembly> <dependentAssembly> - <assemblyIdentity name="System.Console" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/> - <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0"/> + <assemblyIdentity name="System.Console" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" /> </dependentAssembly> <dependentAssembly> - <assemblyIdentity name="System.Diagnostics.StackTrace" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/> - <bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0"/> + <assemblyIdentity name="System.Diagnostics.StackTrace" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> <entityFramework> - <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework"/> + <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" /> <providers> - <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/> + <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> </providers> </entityFramework> -<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/></startup></configuration> +<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /></startup></configuration> diff --git a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs index 0decf4c9c..4a0758a4c 100644 --- a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs +++ b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs @@ -335,6 +335,12 @@ namespace Tango.Emulations.Emulators case MessageType.FileChunkUploadRequest: HandleFileChunkUploadRequest(MessageFactory.ParseTangoMessageFromContainer<FileChunkUploadRequest>(container)); break; + case MessageType.ValidateVersionRequest: + HandleValidateVersionRequest(MessageFactory.ParseTangoMessageFromContainer<ValidateVersionRequest>(container)); + break; + case MessageType.ActivateVersionRequest: + HandleActivateVersionRequest(MessageFactory.ParseTangoMessageFromContainer<ActivateVersionRequest>(container)); + break; } } @@ -1145,6 +1151,24 @@ namespace Tango.Emulations.Emulators } } + private void HandleValidateVersionRequest(TangoMessage<ValidateVersionRequest> request) + { + Task.Factory.StartNew(() => + { + Thread.Sleep(3000); + Transporter.SendResponse<ValidateVersionResponse>(new ValidateVersionResponse(), request.Container.Token); + }); + } + + private void HandleActivateVersionRequest(TangoMessage<ActivateVersionRequest> request) + { + Task.Factory.StartNew(() => + { + Thread.Sleep(3000); + Transporter.SendResponse<ActivateVersionResponse>(new ActivateVersionResponse(), request.Container.Token); + }); + } + #endregion #region Public Methods diff --git a/Software/Visual_Studio/Tango.Integration/Operation/FirmwareUpgradeHandler.cs b/Software/Visual_Studio/Tango.Integration/Operation/FirmwareUpgradeHandler.cs new file mode 100644 index 000000000..f944a2587 --- /dev/null +++ b/Software/Visual_Studio/Tango.Integration/Operation/FirmwareUpgradeHandler.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core; +using Tango.Integration.Storage; + +namespace Tango.Integration.Operation +{ + public class FirmwareUpgradeHandler : ExtendedObject + { + private Action _cancelAction; + + public event EventHandler<FirmwareUpgradeProgressEventArgs> Progress; + public event EventHandler Completed; + public event EventHandler Canceled; + public event EventHandler<Exception> Failed; + + internal FirmwareUpgradeHandler() + { + + } + + internal FirmwareUpgradeHandler(Action cancelAction) + { + _cancelAction = cancelAction; + } + + private FirmwareUpgradeStatus _status; + public FirmwareUpgradeStatus Status + { + get { return _status; } + private set { _status = value; RaisePropertyChangedAuto(); } + } + + private long _current; + public long Current + { + get { return _current; } + internal set + { + _current = value; RaisePropertyChangedAuto(); + } + } + + private long _total; + public long Total + { + get { return _total; } + internal set { _total = value; RaisePropertyChangedAuto(); } + } + + public Task Cancel() + { + return Task.Factory.StartNew(() => + { + _cancelAction.Invoke(); + Status = FirmwareUpgradeStatus.Canceled; + }); + } + + internal void RaiseCompleted() + { + Status = FirmwareUpgradeStatus.Completed; + Completed?.Invoke(this, new EventArgs()); + } + + internal void RaiseCanceled() + { + Status = FirmwareUpgradeStatus.Canceled; + Canceled?.Invoke(this, new EventArgs()); + } + + internal void RaiseFailed(Exception ex) + { + Status = FirmwareUpgradeStatus.Failed; + Failed?.Invoke(this, ex); + } + + internal void RaiseProgress(long current, FirmwareUpgradeStatus status) + { + Current = current; + Status = status; + + Progress?.Invoke(this, new FirmwareUpgradeProgressEventArgs() + { + Current = Current, + Status = Status, + Total = Total + }); + } + } +} diff --git a/Software/Visual_Studio/Tango.Integration/Operation/FirmwareUpgradeProgressEventArgs.cs b/Software/Visual_Studio/Tango.Integration/Operation/FirmwareUpgradeProgressEventArgs.cs new file mode 100644 index 000000000..4e1c86fe6 --- /dev/null +++ b/Software/Visual_Studio/Tango.Integration/Operation/FirmwareUpgradeProgressEventArgs.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Integration.Operation +{ + public class FirmwareUpgradeProgressEventArgs : EventArgs + { + public long Current { get; set; } + public long Total { get; set; } + public FirmwareUpgradeStatus Status { get; set; } + } +} diff --git a/Software/Visual_Studio/Tango.Integration/Operation/FirmwareUpgradeStatus.cs b/Software/Visual_Studio/Tango.Integration/Operation/FirmwareUpgradeStatus.cs new file mode 100644 index 000000000..e2c956807 --- /dev/null +++ b/Software/Visual_Studio/Tango.Integration/Operation/FirmwareUpgradeStatus.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Integration.Operation +{ + public enum FirmwareUpgradeStatus + { + [Description("Initializing...")] + Initializing, + [Description("Uploading MCU file...")] + UploadingMCU, + [Description("Uploading FPGA 1 file...")] + UploadingFPGA1, + [Description("Uploading FPGA 2 file...")] + UploadingFPGA2, + [Description("Uploading FPGA 3 file...")] + UploadingFPGA3, + [Description("Validating version integrity...")] + Validating, + [Description("Activating version...")] + Activating, + [Description("Waiting for device reboot...")] + WaitingForReboot, + [Description("Connecting...")] + Connecting, + [Description("Completed")] + Completed, + [Description("Aborted")] + Canceled, + [Description("Failed")] + Failed, + } +} diff --git a/Software/Visual_Studio/Tango.Integration/Operation/IMachineOperator.cs b/Software/Visual_Studio/Tango.Integration/Operation/IMachineOperator.cs index afbac482b..1495808cd 100644 --- a/Software/Visual_Studio/Tango.Integration/Operation/IMachineOperator.cs +++ b/Software/Visual_Studio/Tango.Integration/Operation/IMachineOperator.cs @@ -16,6 +16,7 @@ using Google.Protobuf; using Tango.PMR.Connection; using Tango.PMR.Stubs; using Tango.Integration.Storage; +using System.IO; namespace Tango.Integration.Operation { @@ -324,6 +325,13 @@ namespace Tango.Integration.Operation Task<StubFpgaWriteRegResponse> Reset(); /// <summary> + /// Upgrades the firmware. + /// </summary> + /// <param name="tfpStream">The TFP stream (Tango Firmware Package File).</param> + /// <returns></returns> + Task<FirmwareUpgradeHandler> UpgradeFirmware(Stream tfpStream); + + /// <summary> /// Creates a storage manager for managing the machine file system. /// </summary> /// <returns></returns> diff --git a/Software/Visual_Studio/Tango.Integration/Operation/MachineOperator.cs b/Software/Visual_Studio/Tango.Integration/Operation/MachineOperator.cs index 6b6dca4c4..b3d8741b6 100644 --- a/Software/Visual_Studio/Tango.Integration/Operation/MachineOperator.cs +++ b/Software/Visual_Studio/Tango.Integration/Operation/MachineOperator.cs @@ -26,6 +26,9 @@ using Tango.BL.ColorConversion; using Tango.PMR.Stubs; using System.Threading; using Tango.Integration.Storage; +using Ionic.Zip; +using Tango.Core.Threading; +using Tango.PMR.IO; namespace Tango.Integration.Operation { @@ -36,6 +39,12 @@ namespace Tango.Integration.Operation /// <seealso cref="Tango.Integration.Operation.IMachineOperator" /> public class MachineOperator : BasicTransporter, IMachineOperator { + private const String FIRMWARE_UPGRADE_FOLDER_NAME = "UpgradePackage"; + private const String FIRMWARE_MCU_FILE_NAME = "mcu"; + private const String FIRMWARE_FPGA1_FILE_NAME = "fpga1"; + private const String FIRMWARE_FPGA2_FILE_NAME = "fpga2"; + private const String FIRMWARE_FPGA3_FILE_NAME = "fpga3"; + private bool _diagnosticsSent; private bool _eventsSent; private bool _debugSent; @@ -718,6 +727,162 @@ namespace Tango.Integration.Operation #endregion + #region Private Methods + + private async void ResumeJob() + { + LogManager.Log("Checking if a job is in progress..."); + + try + { + var res = await SendRequest<CurrentJobRequest, CurrentJobResponse>(new CurrentJobRequest()); + + if (res.Message.IsJobInProgress) + { + JobTicket jobTicket = res.Message.JobTicket; + + ProcessParametersTable processParameters = new ProcessParametersTable(); + jobTicket.ProcessParameters.MapPrimitivesTo(processParameters); + + ResumingJobEventArgs args = new ResumingJobEventArgs((job) => + { + if (Status != MachineStatuses.ReadyToDye) + { + throw new InvalidOperationException("Could not print while status = " + Status); + } + + RunningJob = null; + RunningJobStatus = null; + + var originalJob = job; + + CurrentProcessParameters = processParameters; + + if (job.NumberOfUnits < 1) + { + job.NumberOfUnits = 1; + } + + job = job.Clone(); + + var segments = job.Segments.ToList(); + + for (int i = 0; i < job.NumberOfUnits - 1; i++) + { + foreach (var s in segments) + { + job.Segments.Add(s); + } + } + + var request = new ResumeCurrentJobRequest(); + + JobHandler handler = null; + + handler = new JobHandler(async () => + { + try + { + var result = await SendRequest<AbortJobRequest, AbortJobResponse>(new AbortJobRequest()); + PrintingAborted?.Invoke(this, new PrintingEventArgs(handler, originalJob)); + handler.RaiseCanceled(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Failed to cancel job."); + } + }, originalJob, jobTicket, processParameters, JobHandlingMode); + + handler.StatusChanged += (x, s) => + { + RunningJobStatus = s; + }; + + LogRequestSent(request); + + bool responseLogged = false; + + SendContinuousRequest<ResumeCurrentJobRequest, ResumeCurrentJobResponse>(request, null, TimeSpan.FromSeconds(2)).Subscribe((response) => + { + handler.RaiseStatusReceived(response.Message.Status); + + if (!responseLogged) + { + responseLogged = true; + Status = MachineStatuses.Printing; + RunningJob = originalJob; + PrintingStarted?.Invoke(this, new PrintingEventArgs(handler, originalJob)); + LogResponseReceived(response.Message); + } + }, (ex) => + { + if (!(ex is ContinuousResponseAbortedException)) + { + Status = MachineStatuses.ReadyToDye; + + if (!handler.IsCanceled) + { + PrintingFailed?.Invoke(this, new PrintingFailedEventArgs(handler, originalJob, ex)); + handler.RaiseFailed(ex); + LogRequestFailed(request, ex); + } + } + else + { + Status = MachineStatuses.ReadyToDye; + } + }, () => + { + Status = MachineStatuses.ReadyToDye; + PrintingCompleted?.Invoke(this, new PrintingEventArgs(handler, originalJob)); + handler.RaiseCompleted(); + }); + + return handler; + }); + + args.JobGuid = jobTicket.Guid; + ResumingJob?.Invoke(this, args); + } + } + catch (Exception ex) + { + LogManager.Log(ex); + } + } + + /// <summary> + /// Logs the request sent. + /// </summary> + /// <param name="message">The message.</param> + protected void LogRequestSent(IMessage message) + { + LogManager.Log(String.Format("Sending request '{0}'...{1}{2}", message.GetType().Name, Environment.NewLine, message.ToJsonString())); + OnRequestSent(message); + } + + /// <summary> + /// Logs the request failed. + /// </summary> + /// <param name="message">The message.</param> + protected void LogRequestFailed(IMessage message, Exception ex) + { + LogManager.Log(String.Format("Request failed '{0}'...{1}{2}{1}{3}", message.GetType().Name, Environment.NewLine, message.ToJsonString(), ex.ToString()), LogCategory.Error); + OnRequestFailed(message, ex); + } + + /// <summary> + /// Logs the response received. + /// </summary> + /// <param name="message">The message.</param> + protected void LogResponseReceived(IMessage message) + { + LogManager.Log(String.Format("Response received '{0}'...{1}{2}", message.GetType().Name, Environment.NewLine, message.ToJsonString())); + OnResponseReceived(message); + } + + #endregion + #region Public Methods /// <summary> @@ -912,40 +1077,40 @@ namespace Tango.Integration.Operation bool responseLogged = false; SendContinuousRequest<JobRequest, JobResponse>(request, null, TimeSpan.FromSeconds(2)).Subscribe((response) => - { - handler.RaiseStatusReceived(response.Message.Status); + { + handler.RaiseStatusReceived(response.Message.Status); - if (!responseLogged) - { - responseLogged = true; - Status = MachineStatuses.Printing; - RunningJob = originalJob; - PrintingStarted?.Invoke(this, new PrintingEventArgs(handler, originalJob)); - LogResponseReceived(response.Message); - } - }, (ex) => - { - if (!(ex is ContinuousResponseAbortedException)) - { - Status = MachineStatuses.ReadyToDye; + if (!responseLogged) + { + responseLogged = true; + Status = MachineStatuses.Printing; + RunningJob = originalJob; + PrintingStarted?.Invoke(this, new PrintingEventArgs(handler, originalJob)); + LogResponseReceived(response.Message); + } + }, (ex) => + { + if (!(ex is ContinuousResponseAbortedException)) + { + Status = MachineStatuses.ReadyToDye; - if (!handler.IsCanceled) - { - PrintingFailed?.Invoke(this, new PrintingFailedEventArgs(handler, originalJob, ex)); - handler.RaiseFailed(ex); - LogRequestFailed(request, ex); - } - } - else - { - Status = MachineStatuses.ReadyToDye; - } - }, () => - { - Status = MachineStatuses.ReadyToDye; - PrintingCompleted?.Invoke(this, new PrintingEventArgs(handler, originalJob)); - handler.RaiseCompleted(); - }); + if (!handler.IsCanceled) + { + PrintingFailed?.Invoke(this, new PrintingFailedEventArgs(handler, originalJob, ex)); + handler.RaiseFailed(ex); + LogRequestFailed(request, ex); + } + } + else + { + Status = MachineStatuses.ReadyToDye; + } + }, () => + { + Status = MachineStatuses.ReadyToDye; + PrintingCompleted?.Invoke(this, new PrintingEventArgs(handler, originalJob)); + handler.RaiseCompleted(); + }); return handler; } @@ -1602,160 +1767,186 @@ namespace Tango.Integration.Operation return new StorageManager(this); } - #endregion - - #region Private Methods - - private async void ResumeJob() + /// <summary> + /// Upgrades the firmware. + /// </summary> + /// <param name="tfpStream">The TFP stream (Tango Firmware Package File).</param> + /// <returns></returns> + public async Task<FirmwareUpgradeHandler> UpgradeFirmware(Stream tfpStream) { - LogManager.Log("Checking if a job is in progress..."); + bool cancel = false; - try + var upgradeHandler = new FirmwareUpgradeHandler(() => { - var res = await SendRequest<CurrentJobRequest, CurrentJobResponse>(new CurrentJobRequest()); - - if (res.Message.IsJobInProgress) - { - JobTicket jobTicket = res.Message.JobTicket; - - ProcessParametersTable processParameters = new ProcessParametersTable(); - jobTicket.ProcessParameters.MapPrimitivesTo(processParameters); - - ResumingJobEventArgs args = new ResumingJobEventArgs((job) => - { - if (Status != MachineStatuses.ReadyToDye) - { - throw new InvalidOperationException("Could not print while status = " + Status); - } + cancel = true; + }); - RunningJob = null; - RunningJobStatus = null; + ZipFile zip = ZipFile.Read(tfpStream); - var originalJob = job; + //Perform zip validation... + if (!zip.Entries.ToList().Exists(x => x.FileName == FIRMWARE_MCU_FILE_NAME)) + { + throw new IOException($"Invalid firmware upgrade package. file {FIRMWARE_MCU_FILE_NAME} could not be found."); + } - CurrentProcessParameters = processParameters; + if (!zip.Entries.ToList().Exists(x => x.FileName == FIRMWARE_FPGA1_FILE_NAME)) + { + throw new IOException($"Invalid firmware upgrade package. file {FIRMWARE_FPGA1_FILE_NAME} could not be found."); + } - if (job.NumberOfUnits < 1) - { - job.NumberOfUnits = 1; - } + if (!zip.Entries.ToList().Exists(x => x.FileName == FIRMWARE_FPGA2_FILE_NAME)) + { + throw new IOException($"Invalid firmware upgrade package. file {FIRMWARE_FPGA2_FILE_NAME} could not be found."); + } - job = job.Clone(); + if (!zip.Entries.ToList().Exists(x => x.FileName == FIRMWARE_FPGA3_FILE_NAME)) + { + throw new IOException($"Invalid firmware upgrade package. file {FIRMWARE_FPGA3_FILE_NAME} could not be found."); + } - var segments = job.Segments.ToList(); + upgradeHandler.Total = zip.Entries.Sum(x => x.UncompressedSize); - for (int i = 0; i < job.NumberOfUnits - 1; i++) - { - foreach (var s in segments) - { - job.Segments.Add(s); - } - } + var storage = CreateStorageManager(); + var drive = await storage.GetStorageDrive(); + var root = await storage.GetRootFolder(); + var existing_folder = root.Items.SingleOrDefault(x => x.Name == FIRMWARE_UPGRADE_FOLDER_NAME); + if (existing_folder != null) + { + await storage.DeleteItem(existing_folder); + } - var request = new ResumeCurrentJobRequest(); + String package_folder = Path.Combine(drive.Root, FIRMWARE_UPGRADE_FOLDER_NAME); - JobHandler handler = null; + await storage.CreateFolder(package_folder); - handler = new JobHandler(async () => - { - try - { - var result = await SendRequest<AbortJobRequest, AbortJobResponse>(new AbortJobRequest()); - PrintingAborted?.Invoke(this, new PrintingEventArgs(handler, originalJob)); - handler.RaiseCanceled(); - } - catch (Exception ex) - { - LogManager.Log(ex, "Failed to cancel job."); - } - }, originalJob, jobTicket, processParameters, JobHandlingMode); + List<StorageFileHandler> handlers = new List<StorageFileHandler>(); + List<ZipEntry> entries = zip.Entries.ToList(); + List<Stream> streams = new List<Stream>(); - handler.StatusChanged += (x, s) => - { - RunningJobStatus = s; - }; + Action uploadNext = null; + Action validate = null; + Action activate = null; + Action postActivation = null; - LogRequestSent(request); + uploadNext = new Action(() => + { + if (entries.Count > 0) + { + try + { + var entry = entries.First(); + entries.Remove(entry); - bool responseLogged = false; + var reader = entry.OpenReader(); + streams.Add(reader); - SendContinuousRequest<ResumeCurrentJobRequest, ResumeCurrentJobResponse>(request, null, TimeSpan.FromSeconds(2)).Subscribe((response) => + var handler = storage.UploadFile(Path.Combine(package_folder, entry.FileName), reader).Result; + handlers.Add(handler); + handler.Canceled += (_, __) => { upgradeHandler.RaiseCanceled(); cancel = true; }; + handler.Completed += (_, __) => uploadNext(); + handler.Failed += (_, failedEx) => { upgradeHandler.RaiseFailed(failedEx); cancel = true; }; + handler.Progress += (_, e) => { - handler.RaiseStatusReceived(response.Message.Status); - - if (!responseLogged) + if (cancel) { - responseLogged = true; - Status = MachineStatuses.Printing; - RunningJob = originalJob; - PrintingStarted?.Invoke(this, new PrintingEventArgs(handler, originalJob)); - LogResponseReceived(response.Message); + handler.Cancel(); + return; } - }, (ex) => - { - if (!(ex is ContinuousResponseAbortedException)) - { - Status = MachineStatuses.ReadyToDye; - if (!handler.IsCanceled) - { - PrintingFailed?.Invoke(this, new PrintingFailedEventArgs(handler, originalJob, ex)); - handler.RaiseFailed(ex); - LogRequestFailed(request, ex); - } - } - else + switch (entry.FileName) { - Status = MachineStatuses.ReadyToDye; + case FIRMWARE_MCU_FILE_NAME: + upgradeHandler.RaiseProgress(upgradeHandler.Current + e.Delta, FirmwareUpgradeStatus.UploadingMCU); + break; + case FIRMWARE_FPGA1_FILE_NAME: + upgradeHandler.RaiseProgress(upgradeHandler.Current + e.Delta, FirmwareUpgradeStatus.UploadingFPGA1); + break; + case FIRMWARE_FPGA2_FILE_NAME: + upgradeHandler.RaiseProgress(upgradeHandler.Current + e.Delta, FirmwareUpgradeStatus.UploadingFPGA2); + break; + case FIRMWARE_FPGA3_FILE_NAME: + upgradeHandler.RaiseProgress(upgradeHandler.Current + e.Delta, FirmwareUpgradeStatus.UploadingFPGA3); + break; } - }, () => - { - Status = MachineStatuses.ReadyToDye; - PrintingCompleted?.Invoke(this, new PrintingEventArgs(handler, originalJob)); - handler.RaiseCompleted(); - }); + }; + } + catch (Exception ex) + { + upgradeHandler.RaiseFailed(ex); + } + } + else + { + validate(); + } + }); - return handler; - }); + List<VersionFileDescriptor> descriptors = new List<VersionFileDescriptor>(); + descriptors.Add(new VersionFileDescriptor() + { + FileName = Path.Combine(package_folder, FIRMWARE_MCU_FILE_NAME), + Destination = VersionFileDestination.Mcu, + }); + descriptors.Add(new VersionFileDescriptor() + { + FileName = Path.Combine(package_folder, FIRMWARE_FPGA1_FILE_NAME), + Destination = VersionFileDestination.Fpga1, + }); + descriptors.Add(new VersionFileDescriptor() + { + FileName = Path.Combine(package_folder, FIRMWARE_FPGA2_FILE_NAME), + Destination = VersionFileDestination.Fpga2, + }); + descriptors.Add(new VersionFileDescriptor() + { + FileName = Path.Combine(package_folder, FIRMWARE_FPGA3_FILE_NAME), + Destination = VersionFileDestination.Fpga3, + }); - args.JobGuid = jobTicket.Guid; - ResumingJob?.Invoke(this, args); + validate = new Action(() => + { + try + { + streams.ForEach(x => x.Dispose()); + upgradeHandler.RaiseProgress(upgradeHandler.Total, FirmwareUpgradeStatus.Validating); + var validateRequest = new ValidateVersionRequest(); + validateRequest.FileDescriptors.AddRange(descriptors); + var validateResponse = SendRequest<ValidateVersionRequest, ValidateVersionResponse>(validateRequest, TimeSpan.FromSeconds(10)).Result; + activate(); } - } - catch (Exception ex) + catch (Exception ex) + { + upgradeHandler.RaiseFailed(ex); + } + }); + + activate = new Action(() => { - LogManager.Log(ex); - } - } + try + { + upgradeHandler.RaiseProgress(upgradeHandler.Total, FirmwareUpgradeStatus.Activating); + var activateRequest = new ActivateVersionRequest(); + activateRequest.FileDescriptors.AddRange(descriptors); + var activateResponse = SendRequest<ActivateVersionRequest, ActivateVersionResponse>(activateRequest, TimeSpan.FromSeconds(10)).Result; + postActivation(); + } + catch (Exception ex) + { + upgradeHandler.RaiseFailed(ex); + } + }); - /// <summary> - /// Logs the request sent. - /// </summary> - /// <param name="message">The message.</param> - protected void LogRequestSent(IMessage message) - { - LogManager.Log(String.Format("Sending request '{0}'...{1}{2}", message.GetType().Name, Environment.NewLine, message.ToJsonString())); - OnRequestSent(message); - } + postActivation = new Action(() => + { + upgradeHandler.RaiseCompleted(); + }); - /// <summary> - /// Logs the request failed. - /// </summary> - /// <param name="message">The message.</param> - protected void LogRequestFailed(IMessage message, Exception ex) - { - LogManager.Log(String.Format("Request failed '{0}'...{1}{2}{1}{3}", message.GetType().Name, Environment.NewLine, message.ToJsonString(), ex.ToString()), LogCategory.Error); - OnRequestFailed(message, ex); - } + ThreadFactory.StartNew(() => + { + uploadNext(); + }); - /// <summary> - /// Logs the response received. - /// </summary> - /// <param name="message">The message.</param> - protected void LogResponseReceived(IMessage message) - { - LogManager.Log(String.Format("Response received '{0}'...{1}{2}", message.GetType().Name, Environment.NewLine, message.ToJsonString())); - OnResponseReceived(message); + return upgradeHandler; } #endregion diff --git a/Software/Visual_Studio/Tango.Integration/Storage/StorageFileHandler.cs b/Software/Visual_Studio/Tango.Integration/Storage/StorageFileHandler.cs index 6a9c5cae4..eaa209e65 100644 --- a/Software/Visual_Studio/Tango.Integration/Storage/StorageFileHandler.cs +++ b/Software/Visual_Studio/Tango.Integration/Storage/StorageFileHandler.cs @@ -42,11 +42,13 @@ namespace Tango.Integration.Storage get { return _current; } internal set { + long previous = _current; _current = value; RaisePropertyChangedAuto(); Progress?.Invoke(this, new StorageFileHandlerProgressEventArgs() { Current = _current, Total = _total, + Delta = _current - previous, }); if (Status != StorageFileHandlerStatus.Active) diff --git a/Software/Visual_Studio/Tango.Integration/Storage/StorageFileHandlerProgressEventArgs.cs b/Software/Visual_Studio/Tango.Integration/Storage/StorageFileHandlerProgressEventArgs.cs index b873ff7b3..51e293535 100644 --- a/Software/Visual_Studio/Tango.Integration/Storage/StorageFileHandlerProgressEventArgs.cs +++ b/Software/Visual_Studio/Tango.Integration/Storage/StorageFileHandlerProgressEventArgs.cs @@ -9,6 +9,7 @@ namespace Tango.Integration.Storage public class StorageFileHandlerProgressEventArgs : EventArgs { public long Current { get; set; } + public long Delta { get; set; } public long Total { get; set; } } } diff --git a/Software/Visual_Studio/Tango.Integration/Storage/StorageManager.cs b/Software/Visual_Studio/Tango.Integration/Storage/StorageManager.cs index c092b5bda..0743fe54d 100644 --- a/Software/Visual_Studio/Tango.Integration/Storage/StorageManager.cs +++ b/Software/Visual_Studio/Tango.Integration/Storage/StorageManager.cs @@ -253,13 +253,7 @@ namespace Tango.Integration.Storage } else { - var a = _transporter.SendRequest<FileChunkUploadRequest, FileChunkUploadResponse>(new FileChunkUploadRequest() - { - IsCanceled = true, - }).Result; - handler.RaiseCanceled(); - return; } } diff --git a/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj b/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj index 8498219bc..14cdc03c5 100644 --- a/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj +++ b/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj @@ -39,6 +39,9 @@ <Reference Include="Google.Protobuf, Version=3.4.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL"> <HintPath>..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll</HintPath> </Reference> + <Reference Include="Ionic.Zip, Version=1.9.1.8, Culture=neutral, PublicKeyToken=edbe51ad942a3f5c, processorArchitecture=MSIL"> + <HintPath>..\packages\Ionic.Zip.1.9.1.8\lib\Ionic.Zip.dll</HintPath> + </Reference> <Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <HintPath>..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll</HintPath> </Reference> @@ -86,6 +89,9 @@ <Compile Include="IntegrationSettings.cs" /> <Compile Include="Operation\DefaultMachineEventsStateProvider.cs" /> <Compile Include="Operation\EmbeddedLogItem.cs" /> + <Compile Include="Operation\FirmwareUpgradeHandler.cs" /> + <Compile Include="Operation\FirmwareUpgradeProgressEventArgs.cs" /> + <Compile Include="Operation\FirmwareUpgradeStatus.cs" /> <Compile Include="Operation\IMachineEventsStateProvider.cs" /> <Compile Include="Operation\IMachineOperator.cs" /> <Compile Include="Operation\JobHandlerModes.cs" /> @@ -160,7 +166,7 @@ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <ProjectExtensions> <VisualStudio> - <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" /> + <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" /> </VisualStudio> </ProjectExtensions> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/Tango.Integration/packages.config b/Software/Visual_Studio/Tango.Integration/packages.config index 826cafd8b..5f277f7aa 100644 --- a/Software/Visual_Studio/Tango.Integration/packages.config +++ b/Software/Visual_Studio/Tango.Integration/packages.config @@ -2,6 +2,7 @@ <packages> <package id="EntityFramework" version="6.0.0" targetFramework="net46" /> <package id="Google.Protobuf" version="3.4.1" targetFramework="net46" /> + <package id="Ionic.Zip" version="1.9.1.8" targetFramework="net461" /> <package id="Newtonsoft.Json" version="8.0.3" targetFramework="net46" /> <package id="System.Reactive" version="3.1.1" targetFramework="net46" /> <package id="System.Reactive.Core" version="3.1.1" targetFramework="net46" /> diff --git a/Software/Visual_Studio/Utilities/Tango.Stubs.UI/App.config b/Software/Visual_Studio/Utilities/Tango.Stubs.UI/App.config index 5ea2123d1..9b987cd67 100644 --- a/Software/Visual_Studio/Utilities/Tango.Stubs.UI/App.config +++ b/Software/Visual_Studio/Utilities/Tango.Stubs.UI/App.config @@ -101,6 +101,50 @@ <assemblyIdentity name="System.Reactive.Core" publicKeyToken="94bc3704cddfc263" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-3.0.3000.0" newVersion="3.0.3000.0" /> </dependentAssembly>--> + <dependentAssembly> + <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-1.2.2.0" newVersion="1.2.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Reflection.Metadata" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-1.4.2.0" newVersion="1.4.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IO.FileSystem" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IO.FileSystem.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Xml.XPath.XDocument" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Console" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Diagnostics.StackTrace" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Reactive.Core" publicKeyToken="94bc3704cddfc263" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-3.0.3000.0" newVersion="3.0.3000.0" /> + </dependentAssembly> </assemblyBinding> </runtime> </configuration>
\ No newline at end of file |
