FirmwareHeaderBuilder.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace Phihong_EVSE_UI_Tool
  8. {
  9. public class FirmwareHeaderBuilder
  10. {
  11. public static void AddFirmwareHeader(string temZipPath, string modelName, string outputFilePath)
  12. {
  13. var modelNameArray = Encoding.ASCII.GetBytes(modelName);
  14. var imageDataArray = File.ReadAllBytes(temZipPath);
  15. byte[] dataSegment1 = new byte[16];
  16. byte[] dataSegment2 = new byte[16];
  17. byte[] dataSegment3 = new byte[16];
  18. Array.Clear(dataSegment1, 0, 16);
  19. for (int i = 0; i < 16; i++)
  20. {
  21. dataSegment2[i] = 0xFF;
  22. dataSegment3[i] = 0xFF;
  23. }
  24. var Lcm_Type = new byte[] { 0x10, 0x00, 0x00, 0x0F };
  25. // 0000h
  26. Array.Copy(modelNameArray, 0, dataSegment1, 0, modelNameArray.Length);
  27. // 0001h
  28. byte[] imgLenBytes = GetImgLenBytes(imageDataArray);
  29. byte[] timeBytes = GetCreateTimeBytes();
  30. //Array.Copy(imageType.CodeArray, 0, dataSegment2, 0, 4);
  31. Array.Copy(Lcm_Type, 0, dataSegment2, 0, 4);
  32. Array.Copy(imgLenBytes, 0, dataSegment2, 4, 4);
  33. Array.Copy(timeBytes, 0, dataSegment2, 8, 8);
  34. // 0002h
  35. Array.Copy(timeBytes, 8, dataSegment3, 0, 2);
  36. byte[] crcBytes = GetCRC32(dataSegment1, dataSegment2, dataSegment3, imageDataArray);
  37. Array.Copy(crcBytes, 0, dataSegment3, 2, 4);
  38. List<byte> contents = new List<byte>();
  39. contents.AddRange(dataSegment1);
  40. contents.AddRange(dataSegment2);
  41. contents.AddRange(dataSegment3);
  42. contents.AddRange(imageDataArray);
  43. File.WriteAllBytes(outputFilePath, contents.ToArray());
  44. }
  45. private static byte[] GetImgLenBytes(byte[] imageArray)
  46. {
  47. // Big Endian
  48. byte[] imgLenBytes = BitConverter.GetBytes(imageArray.Length);
  49. Array.Reverse(imgLenBytes);
  50. return imgLenBytes;
  51. }
  52. private static byte[] GetCreateTimeBytes()
  53. {
  54. string strTime = DateTime.Now.ToString("yyyyMMddHH");
  55. return Encoding.ASCII.GetBytes(strTime);
  56. }
  57. private static byte[] GetCRC32(byte[] segment1, byte[] segment2, byte[] segment3, byte[] imageArray)
  58. {
  59. var crc32Handler = CRC32.GetInatance();
  60. List<byte> crcData = new List<byte>();
  61. crcData.AddRange(segment1);
  62. crcData.AddRange(segment2);
  63. crcData.AddRange(new byte[] { segment3[0], segment3[1] });
  64. crcData.AddRange(imageArray);
  65. ulong crc32 = crc32Handler.Calculate(crcData.ToArray(), crcData.Count);
  66. // Big Endian
  67. byte[] outcome = new byte[4];
  68. outcome[0] = (byte)((crc32 & 0xFF000000) >> 24);
  69. outcome[1] = (byte)((crc32 & 0x00FF0000) >> 16);
  70. outcome[2] = (byte)((crc32 & 0x0000FF00) >> 8);
  71. outcome[3] = (byte)(crc32 & 0x000000FF);
  72. return outcome;
  73. }
  74. }
  75. class CRC32
  76. {
  77. private static CRC32 inatance;
  78. /// <summary>取得實體。</summary>
  79. /// <returns></returns>
  80. public static CRC32 GetInatance()
  81. {
  82. if (inatance == null)
  83. {
  84. inatance = new CRC32();
  85. }
  86. return inatance;
  87. }
  88. private ulong[] crc32Table;
  89. /// <summary>初始化 CRC32 類別的新執行個體。</summary>
  90. private CRC32()
  91. {
  92. crc32Table = new ulong[256];
  93. GetCRC32Table();
  94. }
  95. /// <summary>計算。</summary>
  96. /// <param name="dataArray"></param>
  97. /// <param name="length"></param>
  98. /// <returns></returns>
  99. public ulong Calculate(byte[] dataArray, int length)
  100. {
  101. ulong crc = 0xFFFFFFFF;
  102. for (int i = 0; i < length; i++)
  103. {
  104. crc = (crc >> 8) ^ crc32Table[(crc & 0xFF) ^ dataArray[i]];
  105. }
  106. return crc ^ 0xFFFFFFFF;
  107. }
  108. private void GetCRC32Table()
  109. {
  110. ulong crc;
  111. int i, j;
  112. for (i = 0; i < 256; i++)
  113. {
  114. crc = (ulong)i;
  115. for (j = 8; j > 0; j--)
  116. {
  117. if ((crc & 1) == 1)
  118. {
  119. crc = (crc >> 1) ^ 0xEDB88320;
  120. }
  121. else
  122. {
  123. crc >>= 1;
  124. }
  125. }
  126. crc32Table[i] = crc;
  127. }
  128. }
  129. }
  130. }