Bläddra i källkod

change update by sd to create update file

Robert 2 år sedan
förälder
incheckning
2f1c959d22

+ 6 - 0
App.config

@@ -151,6 +151,12 @@
             <setting name="IsUrlHide" serializeAs="String">
                 <value>False</value>
             </setting>
+            <setting name="OutputFolderPath" serializeAs="String">
+                <value />
+            </setting>
+            <setting name="ModelName" serializeAs="String">
+                <value />
+            </setting>
         </Phihong_EVSE_UI_Tool.Properties.Settings>
     </userSettings>
 </configuration>

+ 154 - 0
FirmwareHeaderBuilder.cs

@@ -0,0 +1,154 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Phihong_EVSE_UI_Tool
+{
+    public class FirmwareHeaderBuilder
+    {
+        public static void AddFirmwareHeader(string temZipPath, string modelName, string outputFilePath)
+        {
+            var modelNameArray = Encoding.ASCII.GetBytes(modelName);
+            var imageDataArray = File.ReadAllBytes(temZipPath);
+
+            byte[] dataSegment1 = new byte[16];
+            byte[] dataSegment2 = new byte[16];
+            byte[] dataSegment3 = new byte[16];
+
+            Array.Clear(dataSegment1, 0, 16);
+            for (int i = 0; i < 16; i++)
+            {
+                dataSegment2[i] = 0xFF;
+                dataSegment3[i] = 0xFF;
+            }
+
+            var Infy_PFC_PrimaryController_Type = new byte[] { 0x10, 0x00, 0x00, 0x10 };
+
+            // 0000h
+            Array.Copy(modelNameArray, 0, dataSegment1, 0, modelNameArray.Length);
+            // 0001h
+            byte[] imgLenBytes = GetImgLenBytes(imageDataArray);
+            byte[] timeBytes = GetCreateTimeBytes();
+            //Array.Copy(imageType.CodeArray, 0, dataSegment2, 0, 4);
+            Array.Copy(Infy_PFC_PrimaryController_Type, 0, dataSegment2, 0, 4);
+            Array.Copy(imgLenBytes, 0, dataSegment2, 4, 4);
+            Array.Copy(timeBytes, 0, dataSegment2, 8, 8);
+            // 0002h
+            Array.Copy(timeBytes, 8, dataSegment3, 0, 2);
+            byte[] crcBytes = GetCRC32(dataSegment1, dataSegment2, dataSegment3, imageDataArray);
+            Array.Copy(crcBytes, 0, dataSegment3, 2, 4);
+
+            List<byte> contents = new List<byte>();
+            contents.AddRange(dataSegment1);
+            contents.AddRange(dataSegment2);
+            contents.AddRange(dataSegment3);
+            contents.AddRange(imageDataArray);
+
+            File.WriteAllBytes(outputFilePath, contents.ToArray());
+        }
+
+        private static byte[] GetImgLenBytes(byte[] imageArray)
+        {
+            // Big Endian
+            byte[] imgLenBytes = BitConverter.GetBytes(imageArray.Length);
+            Array.Reverse(imgLenBytes);
+
+            return imgLenBytes;
+        }
+
+        private static byte[] GetCreateTimeBytes()
+        {
+            string strTime = DateTime.Now.ToString("yyyyMMddHH");
+            return Encoding.ASCII.GetBytes(strTime);
+        }
+
+        private static byte[] GetCRC32(byte[] segment1, byte[] segment2, byte[] segment3, byte[] imageArray)
+        { 
+            var crc32Handler = CRC32.GetInatance();
+            List<byte> crcData = new List<byte>();
+            crcData.AddRange(segment1);
+            crcData.AddRange(segment2);
+            crcData.AddRange(new byte[] { segment3[0], segment3[1] });
+            crcData.AddRange(imageArray);
+
+            ulong crc32 = crc32Handler.Calculate(crcData.ToArray(), crcData.Count);
+
+            // Big Endian
+            byte[] outcome = new byte[4];
+            outcome[0] = (byte)((crc32 & 0xFF000000) >> 24);
+            outcome[1] = (byte)((crc32 & 0x00FF0000) >> 16);
+            outcome[2] = (byte)((crc32 & 0x0000FF00) >> 8);
+            outcome[3] = (byte)(crc32 & 0x000000FF);
+
+            return outcome;
+        }
+    }
+
+    class CRC32
+    {
+        private static CRC32 inatance;
+
+        /// <summary>取得實體。</summary>
+        /// <returns></returns>
+        public static CRC32 GetInatance()
+        {
+            if (inatance == null)
+            {
+                inatance = new CRC32();
+            }
+
+            return inatance;
+        }
+
+        private ulong[] crc32Table;
+
+        /// <summary>初始化 CRC32 類別的新執行個體。</summary>
+        private CRC32()
+        {
+            crc32Table = new ulong[256];
+            GetCRC32Table();
+        }
+
+        /// <summary>計算。</summary>
+        /// <param name="dataArray"></param>
+        /// <param name="length"></param>
+        /// <returns></returns>
+        public ulong Calculate(byte[] dataArray, int length)
+        {
+            ulong crc = 0xFFFFFFFF;
+
+            for (int i = 0; i < length; i++)
+            {
+                crc = (crc >> 8) ^ crc32Table[(crc & 0xFF) ^ dataArray[i]];
+            }
+
+            return crc ^ 0xFFFFFFFF;
+        }
+
+        private void GetCRC32Table()
+        {
+            ulong crc;
+            int i, j;
+
+            for (i = 0; i < 256; i++)
+            {
+                crc = (ulong)i;
+                for (j = 8; j > 0; j--)
+                {
+                    if ((crc & 1) == 1)
+                    {
+                        crc = (crc >> 1) ^ 0xEDB88320;
+                    }
+                    else
+                    {
+                        crc >>= 1;
+                    }
+                }
+                crc32Table[i] = crc;
+            }
+        }
+    }
+}

+ 2 - 2
MainWindow.xaml

@@ -76,7 +76,7 @@
                         <ListViewItem x:Name="uxSaveListViewItem" Padding="1">
                             <StackPanel Orientation="Horizontal">
                                 <md:PackIcon Kind="SdCard" Margin="16,12,6,12" VerticalAlignment="Center"/>
-                                <TextBlock Text="Save to SD Card" FontSize="15" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="12"/>
+                                <TextBlock Text="Save to Update File" FontSize="15" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="12"/>
                             </StackPanel>
                         </ListViewItem>
                     </ListView>
@@ -97,4 +97,4 @@
             </Grid>
         </Grid>
     </local:DpiDecorator>
-</Window>
+</Window>

+ 2 - 0
Phihong EVSE UI Tool.csproj

@@ -72,6 +72,7 @@
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Data" />
+    <Reference Include="System.IO.Compression.FileSystem" />
     <Reference Include="System.Xml" />
     <Reference Include="Microsoft.CSharp" />
     <Reference Include="System.Core" />
@@ -121,6 +122,7 @@
       <DependentUpon>BuildIco.xaml</DependentUpon>
     </Compile>
     <Compile Include="Enums.cs" />
+    <Compile Include="FirmwareHeaderBuilder.cs" />
     <Compile Include="ImageList.cs" />
     <Compile Include="ModifyIco.xaml.cs">
       <DependentUpon>ModifyIco.xaml</DependentUpon>

+ 29 - 5
Properties/Settings.Designer.cs

@@ -1,10 +1,10 @@
 //------------------------------------------------------------------------------
 // <auto-generated>
-//     這段程式碼是由工具產生的。
-//     執行階段版本:4.0.30319.42000
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
 //
-//     對這個檔案所做的變更可能會造成錯誤的行為,而且如果重新產生程式碼,
-//     變更將會遺失。
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
 // </auto-generated>
 //------------------------------------------------------------------------------
 
@@ -12,7 +12,7 @@ namespace Phihong_EVSE_UI_Tool.Properties {
     
     
     [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0")]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")]
     internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
         
         private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
@@ -586,5 +586,29 @@ namespace Phihong_EVSE_UI_Tool.Properties {
                 this["IsUrlHide"] = value;
             }
         }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("")]
+        public string OutputFolderPath {
+            get {
+                return ((string)(this["OutputFolderPath"]));
+            }
+            set {
+                this["OutputFolderPath"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("")]
+        public string ModelName {
+            get {
+                return ((string)(this["ModelName"]));
+            }
+            set {
+                this["ModelName"] = value;
+            }
+        }
     }
 }

+ 6 - 0
Properties/Settings.settings

@@ -143,5 +143,11 @@
     <Setting Name="IsUrlHide" Type="System.Boolean" Scope="User">
       <Value Profile="(Default)">False</Value>
     </Setting>
+    <Setting Name="OutputFolderPath" Type="System.String" Scope="User">
+      <Value Profile="(Default)" />
+    </Setting>
+    <Setting Name="ModelName" Type="System.String" Scope="User">
+      <Value Profile="(Default)" />
+    </Setting>
   </Settings>
 </SettingsFile>

+ 8 - 4
SaveSdCard.xaml

@@ -16,15 +16,19 @@
             <StackPanel>
                 <TextBlock Text="Temporary output folder (DO NOT delete)" HorizontalAlignment="Left" Margin="22,6,0,12"/>
                 <TextBlock Text="{x:Static local:Utility.OUTPUT_DIRECTORY}" HorizontalAlignment="Left" Margin="22,0,0,12" Foreground="{Binding Path=(fd:AccentColors.ImmersiveSystemAccentBrush)}"/>
-                <TextBlock Text="Locate SD card" FontSize="24" HorizontalAlignment="Left" Margin="22,12,0,12"/>
+				
+				<TextBlock Text="Enter EVSE Model Name" FontSize="24" HorizontalAlignment="Left" Margin="22,12,0,12"/>
+				<TextBox x:Name="uxModelNameTestBox" VerticalContentAlignment="Center" HorizontalAlignment="Left" Margin="23,0,100,12" Width="270" Height="35" Style="{StaticResource TextBoxRevealStyle}"/>
+				
+                <TextBlock Text="Locate Output Directory" FontSize="24" HorizontalAlignment="Left" Margin="22,12,0,12"/>
                 <StackPanel x:Name="uxLogoCustomStackPanel" Orientation="Horizontal" Margin="22,0,100,12">
                     <Button Tag="Browse" Content="Browse" HorizontalAlignment="Left" Width="90" Height="35"
                             Style="{StaticResource ButtonRevealStyle}" Click="uxBrowseButton_Click" Foreground="Black"/>
-                    <TextBox x:Name="uxSdBrowseTextBox" VerticalContentAlignment="Center" Margin="1,0,0,0" Width="270" Height="35" 
-                             Style="{StaticResource TextBoxRevealStyle}" Text="Please locate the SD card" IsReadOnly="True"/>
+                    <TextBox x:Name="uxOutputDirectoryBrowseTextBox" VerticalContentAlignment="Center" Margin="1,0,0,0" Width="270" Height="35" 
+                             Style="{StaticResource TextBoxRevealStyle}" IsReadOnly="True"/>
                 </StackPanel>
 
-                <TextBlock Text="Save to SD card" FontSize="24" HorizontalAlignment="Left" Margin="22,18,0,12"/>
+                <TextBlock Text="Save to Update File" FontSize="24" HorizontalAlignment="Left" Margin="22,18,0,12"/>
                 <StackPanel Orientation="Horizontal" Margin="22,0,180,12">
                     <RadioButton x:Name="uxSaveAllRadioButton" Tag="Save" GroupName="saveSelect" Margin="0,0,36,0" Style="{StaticResource MaterialDesignRadioButton}" 
                                  Background="{Binding Path=(fd:AccentColors.ImmersiveSystemAccentBrush)}" IsChecked="True">Save all files</RadioButton>

+ 51 - 22
SaveSdCard.xaml.cs

@@ -2,6 +2,7 @@
 using System;
 using System.Collections.Generic;
 using System.IO;
+using System.IO.Compression;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
@@ -22,19 +23,32 @@ namespace Phihong_EVSE_UI_Tool
     public partial class SaveSdCard : UserControl
     {
         private Properties.Settings mySettings = Properties.Settings.Default;
-        private string sdFolderPath;
+        private string outputFolderPath;
+        private string settingModelName;
         private List<string> toBeSavedFiles = new List<string>();
 
         public SaveSdCard()
         {
             InitializeComponent();
 
-            sdFolderPath = mySettings.SdCardPath;
-            uxSdBrowseTextBox.Text = sdFolderPath;
+            outputFolderPath = mySettings.OutputFolderPath;
+            uxOutputDirectoryBrowseTextBox.Text = outputFolderPath;
+            uxModelNameTestBox.Text = mySettings.ModelName;
         }
 
-        private void SaveToSdCard()
+        private void SaveToDirectory()
         {
+            if (Directory.Exists(Utility.ZIP_SOURCE_DIRECTORY))
+            {
+                Directory.Delete(Utility.ZIP_SOURCE_DIRECTORY, true);
+            }
+            if (Directory.Exists(Utility.ZIP_FILE_DIRECTORY))
+            {
+                Directory.Delete(Utility.ZIP_FILE_DIRECTORY, true);
+            }
+            Directory.CreateDirectory(Utility.ZIP_SOURCE_DIRECTORY);
+            Directory.CreateDirectory(Utility.ZIP_FILE_DIRECTORY);
+
             if (uxSaveAllRadioButton.IsChecked.Value)
             {
                 toBeSavedFiles = new List<string>(Utility.ChangedFiles.Keys);
@@ -46,35 +60,42 @@ namespace Phihong_EVSE_UI_Tool
                                   select p.Key).ToList<string>();
             }
 
-            Directory.CreateDirectory(Path.Combine(sdFolderPath, Utility.SDCARD_SUBDIR));
-
             foreach (string fileName in toBeSavedFiles)
             {
                 File.Copy(Path.Combine(Utility.OUTPUT_DIRECTORY, fileName),
-                          Path.Combine(sdFolderPath, Utility.SDCARD_SUBDIR, fileName), true);
+                          Path.Combine(Utility.ZIP_SOURCE_DIRECTORY, fileName), true);
             }
 
             foreach (string resName in Utility.REQ_FILELIST)
             {
                 Uri srcPath = new Uri(Path.Combine(Utility.REQ_PARENTFOLDER, resName), UriKind.Relative);
-                Utility.CopyFileFromResource(srcPath, Path.Combine(sdFolderPath, Utility.SDCARD_SUBDIR, resName));
+                Utility.CopyFileFromResource(srcPath, Path.Combine(Utility.ZIP_SOURCE_DIRECTORY, resName));
             }
 
+            string modelName = uxModelNameTestBox.Text;
+            string zipFileName = string.Format("{0}_{1}.zip", modelName, DateTime.Now.ToString("yyyyMMddHHmmss"));
+            string temZipPath = Path.Combine(Utility.ZIP_FILE_DIRECTORY, Utility.TEMP_ZIP_FILE_NAME);
+            ZipFile.CreateFromDirectory(Utility.ZIP_SOURCE_DIRECTORY, temZipPath);
+
+            string tempHeaderBuildedZipPath = Path.Combine(Utility.ZIP_FILE_DIRECTORY, zipFileName);
+            FirmwareHeaderBuilder.AddFirmwareHeader(temZipPath, modelName, tempHeaderBuildedZipPath);
+            File.Copy(tempHeaderBuildedZipPath, Path.Combine(outputFolderPath, zipFileName));
+
             switch (toBeSavedFiles.Count())
             {
                 case 0:
-                    uxMessageTextBlock.Text = "Saved no image and 11 required files to SD card";
+                    uxMessageTextBlock.Text = "Archived no image and 11 required files to File";
                     break;
                 case 1:
-                    uxMessageTextBlock.Text = "Saved 1 image and 11 required files to SD card";
+                    uxMessageTextBlock.Text = "Archived 1 image and 11 required files to File";
                     break;
                 default:
-                    uxMessageTextBlock.Text = "Saved " + toBeSavedFiles.Count() + " images and 11 required files to SD card";
+                    uxMessageTextBlock.Text = "Archived " + toBeSavedFiles.Count() + " images and 11 required files to File";
                     break;
             }
 
             System.Diagnostics.Process process = new System.Diagnostics.Process();
-            process.StartInfo.FileName = Path.Combine(sdFolderPath, Utility.SDCARD_SUBDIR);
+            process.StartInfo.FileName = outputFolderPath;
             process.Start();
         }
 
@@ -92,31 +113,39 @@ namespace Phihong_EVSE_UI_Tool
                     var dlg = new CommonOpenFileDialog()
                     {
                         IsFolderPicker = true,
-                        Title = "Locate the SD card",
+                        Title = "Locate the output directory",
                     };
                     if (dlg.ShowDialog() == CommonFileDialogResult.Ok)
                     {
-                        sdFolderPath = dlg.FileName;
-                        uxSdBrowseTextBox.Text = sdFolderPath;
-                        mySettings.SdCardPath = sdFolderPath;
+                        outputFolderPath = dlg.FileName;
+                        uxOutputDirectoryBrowseTextBox.Text = outputFolderPath;
+                        //mySettings.SdCardPath = sdFolderPath;
+                        mySettings.OutputFolderPath = outputFolderPath;
                         mySettings.Save();
                     }
                     break;
                 case "Save":
-                    if(!Directory.Exists(sdFolderPath))
+
+                    if (uxModelNameTestBox.Text.Length != 14)
                     {
-                        MessageBox.Show("Please locate the SD card path first",
+                        MessageBox.Show("Model Name length shoud be 14",
+                                        "Invalid Model Name", MessageBoxButton.OK, MessageBoxImage.Error);
+                        break;
+                    }
+                    mySettings.ModelName = uxModelNameTestBox.Text;
+                    mySettings.Save();
+
+                    if (!Directory.Exists(outputFolderPath))
+                    {
+                        MessageBox.Show("Please locate the output directory first",
                                         "Invalid Path", MessageBoxButton.OK, MessageBoxImage.Error);
                         break;
                     }
-                    SaveToSdCard();
+                    SaveToDirectory();
                     break;
                 default:
                     break;
             }
-
-
-            
         }
     }
 }

+ 5 - 1
Utility.cs

@@ -32,6 +32,8 @@ namespace Phihong_EVSE_UI_Tool
         public const string ICO_URL = "66.bmp";
         public const string ICO_URL_HIDE = "66_hide.bmp";
 
+        public const string TEMP_ZIP_FILE_NAME = @"tmp.zip";
+
         public const string REQ_PARENTFOLDER = "Required";
         public static List<string> REQ_FILELIST = new List<string>()
         {
@@ -40,10 +42,12 @@ namespace Phihong_EVSE_UI_Tool
             "30_Unicode_Roboto_14_28.dzk", "32_Unicode_Roboto_28_56.dzk", "CONFIG.txt"
         };
 
-        public const string SDCARD_SUBDIR = "DWIN_SET";
+        //public const string SDCARD_SUBDIR = "DWIN_SET";
 
         public static readonly string OUTPUT_DIRECTORY = Environment.CurrentDirectory + @"\Output";
         public static readonly string CUSTOM_DIRECTORY = Environment.CurrentDirectory + @"\CustomTemp";
+        public static readonly string ZIP_SOURCE_DIRECTORY = Environment.CurrentDirectory + @"\ZipSource";
+        public static readonly string ZIP_FILE_DIRECTORY = Environment.CurrentDirectory + @"\ZipFile";
 
         public static Dictionary<string, bool> ChangedFiles = new Dictionary<string, bool>()
         {