├── .gitignore ├── Libs ├── FTD2XX_NET.dll ├── J2534DotNet.dll ├── J2534DotNet.dll.config ├── LibUsbDotNet.dll ├── canlib32.dll ├── canlibCLSNET.dll ├── canlibCLSNET.xml ├── canusbdrv_net.dll └── combilib-net.dll ├── Local.testsettings ├── SetupCANFlash ├── SetupCANFlash.vdproj └── version.bat ├── SetupCANFlasher ├── SetupCANFlasher.wixproj ├── TrionicCANFlash.wxs ├── disclaimer.rtf └── version.bat ├── TraceAndTestImpact.testsettings ├── TrionicCANFlasher ├── EditParameters.Designer.cs ├── EditParameters.cs ├── EditParameters.resx ├── FTD2XX_NET.dll ├── LibUsbDotNet.dll ├── NLog.config ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resources │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── ReleaseAsset.cs ├── T8CANFlasher.pidb ├── T8CANFlasher.userprefs ├── TrionicCANFlasher.csproj ├── TrionicCANFlasher.csproj.user ├── TrionicCanFlasher.ico ├── TrionicCanFlasher.pdf ├── app.config ├── canlib32.dll ├── combilib-net.dll ├── documentation │ └── TrionicCanFlasher.odt ├── frmChecksum.Designer.cs ├── frmChecksum.cs ├── frmChecksum.resx ├── frmMain.Designer.cs ├── frmMain.cs ├── frmMain.resources ├── frmMain.resx ├── frmSettings.Designer.cs ├── frmSettings.cs ├── frmSettings.resx ├── frmUpdateAvailable.Designer.cs ├── frmUpdateAvailable.cs ├── frmUpdateAvailable.resx ├── msiupdater.cs └── packages.config ├── TrionicCANLib ├── BitTools.cs ├── BlockManager.cs ├── Bootloader.cs ├── Bootloader_legion.cs ├── ByteCoder.cs ├── CAN │ ├── CANELM327Device.cs │ ├── CANListener.cs │ ├── CANMessage.cs │ ├── CANUSBDevice.cs │ ├── EasySync232Device.cs │ ├── EasySyncDevice.cs │ ├── ICANDevice.cs │ ├── ICANListener.cs │ ├── J2534CANDevice.cs │ ├── Just4TrionicDevice.cs │ ├── KvaserCANDevice.cs │ └── LPCCANDevice.cs ├── CIMKEYS.CS ├── Checksum │ ├── ChecksumDelegate.cs │ ├── ChecksumResult.cs │ ├── ChecksumT5.cs │ ├── ChecksumT7.cs │ ├── ChecksumT8.cs │ └── T7FileHeader.cs ├── EnumHelper.cs ├── FileTools.cs ├── Firmware │ ├── BaseFile.cs │ ├── FileME96.cs │ ├── FileT5.cs │ ├── FileT7.cs │ ├── FileT8.cs │ └── FileT8mcp.cs ├── FlashReadArguments.cs ├── ITrionic.cs ├── KWP │ ├── ELM327Device.cs │ ├── IKWPDevice.cs │ ├── KWPCANDevice.cs │ ├── KWPCANListener.cs │ ├── KWPHandler.cs │ ├── KWPReply.cs │ └── KWPRequest.cs ├── Md5Tools.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── SeedKey │ ├── Algorithm.cs │ ├── AlgorithmDictionary.cs │ ├── GM-seedkey.doc │ ├── SeedKeyGM.cs │ └── Step.cs ├── SeedToKey.cs ├── T8CANLib.pidb ├── T8CANLib.userprefs ├── Trionic5.cs ├── Trionic7.cs ├── Trionic8.cs ├── TrionicCANLib.csproj ├── TrionicEnums.cs ├── WMI │ ├── COMPortInfo.cs │ └── ProcessConnection.cs ├── flasher │ ├── IFlasher.cs │ ├── T7CombiFlasher.cs │ └── T7Flasher.cs ├── packages.config └── z22se_preloader.cs ├── TrionicCANLibTest ├── Properties │ └── AssemblyInfo.cs ├── SeedKeyGMTest.cs └── TrionicCANLibTest.csproj ├── TrionicCanFlasher.sln ├── TrionicCanFlasher.sln.switchReferences.xml ├── TrionicCanFlasher.vsmdi ├── packages └── repositories.config ├── releaseTrionicCanFlash.bat └── releaseTrionicCanFlasher.bat /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | 131 | # NuGet Packages Directory 132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 133 | #packages/ 134 | 135 | # Windows Azure Build Output 136 | csx 137 | *.build.csdef 138 | 139 | # Windows Store app package directory 140 | AppPackages/ 141 | 142 | # Others 143 | sql/ 144 | *.Cache 145 | ClientBin/ 146 | [Ss]tyle[Cc]op.* 147 | ~$* 148 | *~ 149 | *.dbmdl 150 | *.[Pp]ublish.xml 151 | *.pfx 152 | *.publishsettings 153 | 154 | # RIA/Silverlight projects 155 | Generated_Code/ 156 | 157 | # Backup & report files from converting an old project file to a newer 158 | # Visual Studio version. Backup files are not needed, because we have git ;-) 159 | _UpgradeReport_Files/ 160 | Backup*/ 161 | UpgradeLog*.XML 162 | UpgradeLog*.htm 163 | 164 | # SQL Server files 165 | App_Data/*.mdf 166 | App_Data/*.ldf 167 | 168 | ############# 169 | ## Windows detritus 170 | ############# 171 | 172 | # Windows image file caches 173 | Thumbs.db 174 | ehthumbs.db 175 | 176 | # Folder config file 177 | Desktop.ini 178 | 179 | # Recycle Bin used on file shares 180 | $RECYCLE.BIN/ 181 | 182 | # Mac crap 183 | .DS_Store 184 | 185 | 186 | ############# 187 | ## Python 188 | ############# 189 | 190 | *.py[co] 191 | 192 | # Packages 193 | *.egg 194 | *.egg-info 195 | dist/ 196 | build/ 197 | eggs/ 198 | parts/ 199 | var/ 200 | sdist/ 201 | develop-eggs/ 202 | .installed.cfg 203 | 204 | # Installer logs 205 | pip-log.txt 206 | 207 | # Unit test / coverage reports 208 | .coverage 209 | .tox 210 | 211 | #Translations 212 | *.mo 213 | 214 | #Mr Developer 215 | .mr.developer.cfg 216 | /logs 217 | /FTDICANUSB/FTDICANUSB.csproj 218 | 219 | 220 | ############# 221 | ## NuGet 222 | ############# 223 | # Ignore NuGet Packages 224 | *.nupkg 225 | 226 | # Ignore the packages folder 227 | **/packages/* 228 | 229 | # Include packages/build/, which is used as an MSBuild target 230 | !**/packages/build/ 231 | 232 | # Uncomment if necessary; generally it's regenerated when needed 233 | !**/packages/repositories.config 234 | 235 | # Ignore other intermediate files that NuGet might create. project.lock.json is used in conjunction 236 | # with project.json; project.assets.json is used in conjunction with the PackageReference format. 237 | project.lock.json 238 | project.assets.json 239 | *.nuget.props -------------------------------------------------------------------------------- /Libs/FTD2XX_NET.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattiasclaesson/Trionic/dd8c3fae77d1a6175193486f1dac2dd28cbdeab5/Libs/FTD2XX_NET.dll -------------------------------------------------------------------------------- /Libs/J2534DotNet.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattiasclaesson/Trionic/dd8c3fae77d1a6175193486f1dac2dd28cbdeab5/Libs/J2534DotNet.dll -------------------------------------------------------------------------------- /Libs/J2534DotNet.dll.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Libs/LibUsbDotNet.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattiasclaesson/Trionic/dd8c3fae77d1a6175193486f1dac2dd28cbdeab5/Libs/LibUsbDotNet.dll -------------------------------------------------------------------------------- /Libs/canlib32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattiasclaesson/Trionic/dd8c3fae77d1a6175193486f1dac2dd28cbdeab5/Libs/canlib32.dll -------------------------------------------------------------------------------- /Libs/canlibCLSNET.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattiasclaesson/Trionic/dd8c3fae77d1a6175193486f1dac2dd28cbdeab5/Libs/canlibCLSNET.dll -------------------------------------------------------------------------------- /Libs/canusbdrv_net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattiasclaesson/Trionic/dd8c3fae77d1a6175193486f1dac2dd28cbdeab5/Libs/canusbdrv_net.dll -------------------------------------------------------------------------------- /Libs/combilib-net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattiasclaesson/Trionic/dd8c3fae77d1a6175193486f1dac2dd28cbdeab5/Libs/combilib-net.dll -------------------------------------------------------------------------------- /Local.testsettings: -------------------------------------------------------------------------------- 1 |  2 | 3 | These are default test settings for a local test run. 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /SetupCANFlash/version.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | set TrionicCANFlasher.version=0.1.73.0 3 | set TrionicCANLib.version=0.1.59.0 4 | set SetupCANFlash.version=0.1.73 -------------------------------------------------------------------------------- /SetupCANFlasher/SetupCANFlasher.wixproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | x86 6 | 3.10 7 | {3d666e41-0263-4efc-9b80-743cce5494d6} 8 | 2.0 9 | TrionicCANFlasher 10 | Package 11 | $(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets 12 | $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets 13 | 14 | 15 | bin\$(Configuration)\ 16 | obj\$(Configuration)\ 17 | Debug 18 | 19 | 20 | bin\$(Configuration)\ 21 | obj\$(Configuration)\ 22 | 23 | 24 | 25 | 26 | 27 | 28 | TrionicCANFlasher 29 | {ad7871be-0280-47d4-9492-2181bb1c789b} 30 | True 31 | True 32 | Binaries;Content;Satellites 33 | INSTALLFOLDER 34 | 35 | 36 | TrionicCANLib 37 | {3fe690b8-7a3b-425e-913c-bff7a55f7bc4} 38 | True 39 | True 40 | Binaries;Content;Satellites 41 | INSTALLFOLDER 42 | 43 | 44 | 45 | 46 | $(WixExtDir)\WixNetFxExtension.dll 47 | WixNetFxExtension 48 | 49 | 50 | $(WixExtDir)\WixUIExtension.dll 51 | WixUIExtension 52 | 53 | 54 | 55 | 56 | 57 | 58 | 66 | -------------------------------------------------------------------------------- /SetupCANFlasher/TrionicCANFlash.wxs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 107 | 108 | -------------------------------------------------------------------------------- /SetupCANFlasher/disclaimer.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\deff0{\fonttbl{\f0\fnil\fcharset0 Calibri;}} 2 | {\*\generator Msftedit 5.41.21.2510;}\viewkind4\uc1\pard\sa200\sl276\slmult1\lang29\f0\fs22 The T8Suite, T7Suite, T5Suite II, T5 CAN Flasher 2 and Trionic CAN Flasher are Open Source software tools that pokes around in your car\rquote s control system. The authors of the tools shall not be held accountable for how you decide to use the tools. If you are not careful, you can easily brick your car with these tools so please use this software with care.\par 3 | } 4 | -------------------------------------------------------------------------------- /SetupCANFlasher/version.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | set TrionicCANFlasher.version=0.1.56.0 3 | set TrionicCANLib.version=0.1.44.0 4 | set SetupCANFlasher.version=0.1.56 -------------------------------------------------------------------------------- /TraceAndTestImpact.testsettings: -------------------------------------------------------------------------------- 1 |  2 | 3 | These are test settings for Trace and Test Impact. 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /TrionicCANFlasher/EditParameters.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | using TrionicCANLib.API; 10 | 11 | namespace TrionicCANFlasher 12 | { 13 | public partial class EditParameters : Form 14 | { 15 | public EditParameters() 16 | { 17 | InitializeComponent(); 18 | } 19 | 20 | public bool Convertible 21 | { 22 | get 23 | { 24 | return cbCab.Checked; 25 | } 26 | set 27 | { 28 | cbCab.Checked = value; 29 | } 30 | } 31 | 32 | public bool SAI 33 | { 34 | get 35 | { 36 | return cbSAI.Checked; 37 | } 38 | set 39 | { 40 | cbSAI.Checked = value; 41 | } 42 | } 43 | 44 | public bool Highoutput 45 | { 46 | get 47 | { 48 | return cbOutput.Checked; 49 | } 50 | set 51 | { 52 | cbOutput.Checked = value; 53 | } 54 | } 55 | 56 | public bool Biopower 57 | { 58 | get 59 | { 60 | return cbBiopower.Checked; 61 | } 62 | set 63 | { 64 | cbBiopower.Checked = value; 65 | } 66 | } 67 | 68 | public string VIN 69 | { 70 | get 71 | { 72 | return tbVIN.Text; 73 | } 74 | set 75 | { 76 | tbVIN.Text = value; 77 | } 78 | } 79 | 80 | public int TopSpeed 81 | { 82 | get 83 | { 84 | int speed; 85 | int.TryParse(tbTopSpeed.Text, out speed); 86 | return speed; 87 | } 88 | set 89 | { 90 | tbTopSpeed.Text = value.ToString(); 91 | } 92 | } 93 | 94 | public float E85 95 | { 96 | get 97 | { 98 | float e85; 99 | float.TryParse(tbE85.Text, out e85); 100 | return e85; 101 | } 102 | set 103 | { 104 | tbE85.Text = value.ToString(); 105 | } 106 | } 107 | 108 | public float Oil 109 | { 110 | get 111 | { 112 | float oil; 113 | float.TryParse(tbOilQuality.Text, out oil); 114 | return oil; 115 | } 116 | set 117 | { 118 | tbOilQuality.Text = value.ToString(); 119 | } 120 | } 121 | 122 | public bool ClutchStart 123 | { 124 | get 125 | { 126 | return cbClutchStart.Checked; 127 | } 128 | set 129 | { 130 | cbClutchStart.Checked = value; 131 | } 132 | } 133 | 134 | public DiagnosticType DiagnosticType 135 | { 136 | get 137 | { 138 | return (DiagnosticType)comboBoxDiag.SelectedIndex; 139 | } 140 | set 141 | { 142 | comboBoxDiag.SelectedIndex = (int)value; 143 | } 144 | } 145 | 146 | public TankType TankType 147 | { 148 | get 149 | { 150 | return (TankType)comboBoxTank.SelectedIndex; 151 | } 152 | set 153 | { 154 | comboBoxTank.SelectedIndex = (int)value; 155 | } 156 | } 157 | 158 | public void setECU(ECU ecu) 159 | { 160 | if(ecu == ECU.TRIONIC8) 161 | { 162 | tbVIN.Show(); 163 | cbCab.Show(); 164 | cbSAI.Show(); 165 | cbOutput.Show(); 166 | tbTopSpeed.Show(); 167 | tbE85.Show(); 168 | tbOilQuality.Show(); 169 | cbBiopower.Show(); 170 | cbClutchStart.Show(); 171 | comboBoxDiag.Show(); 172 | comboBoxTank.Show(); 173 | } 174 | else if(ecu == ECU.MOTRONIC96) 175 | { 176 | tbVIN.Show(); 177 | cbCab.Hide(); 178 | cbSAI.Hide(); 179 | cbOutput.Hide(); 180 | tbTopSpeed.Show(); 181 | tbE85.Hide(); 182 | tbOilQuality.Hide(); 183 | cbBiopower.Hide(); 184 | cbClutchStart.Hide(); 185 | comboBoxDiag.Hide(); 186 | comboBoxTank.Hide(); 187 | } 188 | else if(ecu == ECU.TRIONIC7) 189 | { 190 | tbVIN.Hide(); 191 | cbCab.Hide(); 192 | cbSAI.Hide(); 193 | cbOutput.Hide(); 194 | tbTopSpeed.Hide(); 195 | tbE85.Show(); 196 | tbOilQuality.Hide(); 197 | cbBiopower.Hide(); 198 | cbClutchStart.Hide(); 199 | comboBoxDiag.Hide(); 200 | comboBoxTank.Hide(); 201 | } 202 | } 203 | 204 | private void btnWriteToECU_Click(object sender, EventArgs e) 205 | { 206 | this.DialogResult = DialogResult.OK; 207 | this.Close(); 208 | } 209 | 210 | private void closeButton_Click(object sender, EventArgs e) 211 | { 212 | this.DialogResult = DialogResult.Cancel; 213 | this.Close(); 214 | } 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /TrionicCANFlasher/FTD2XX_NET.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattiasclaesson/Trionic/dd8c3fae77d1a6175193486f1dac2dd28cbdeab5/TrionicCANFlasher/FTD2XX_NET.dll -------------------------------------------------------------------------------- /TrionicCANFlasher/LibUsbDotNet.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattiasclaesson/Trionic/dd8c3fae77d1a6175193486f1dac2dd28cbdeab5/TrionicCANFlasher/LibUsbDotNet.dll -------------------------------------------------------------------------------- /TrionicCANFlasher/NLog.config: -------------------------------------------------------------------------------- 1 |  2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /TrionicCANFlasher/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Forms; 5 | 6 | namespace TrionicCANFlasher 7 | { 8 | static class Program 9 | { 10 | /// 11 | /// The main entry point for the application. 12 | /// 13 | [STAThread] 14 | static void Main() 15 | { 16 | Application.EnableVisualStyles(); 17 | Application.SetCompatibleTextRenderingDefault(false); 18 | Application.Run(new frmMain()); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /TrionicCANFlasher/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TrionicCANFlasher")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("MattiasC")] 12 | [assembly: AssemblyProduct("TrionicCANFlasher")] 13 | [assembly: AssemblyCopyright("Copyright © 2024 Dilemma/Mattias Claesson")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("2fb67516-27cc-43f6-98b6-b18f77e028bb")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("0.1.73.0")] 36 | [assembly: AssemblyFileVersion("0.1.73.0")] 37 | -------------------------------------------------------------------------------- /TrionicCANFlasher/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34209 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace TrionicCANFlasher.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TrionicCANFlasher.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /TrionicCANFlasher/Properties/Resources.resources: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattiasclaesson/Trionic/dd8c3fae77d1a6175193486f1dac2dd28cbdeab5/TrionicCANFlasher/Properties/Resources.resources -------------------------------------------------------------------------------- /TrionicCANFlasher/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /TrionicCANFlasher/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34209 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace TrionicCANFlasher.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /TrionicCANFlasher/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /TrionicCANFlasher/ReleaseAsset.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | 6 | public class ReleaseAsset 7 | { 8 | public string browser_download_url { get; set; } 9 | } -------------------------------------------------------------------------------- /TrionicCANFlasher/T8CANFlasher.pidb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattiasclaesson/Trionic/dd8c3fae77d1a6175193486f1dac2dd28cbdeab5/TrionicCANFlasher/T8CANFlasher.pidb -------------------------------------------------------------------------------- /TrionicCANFlasher/T8CANFlasher.userprefs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /TrionicCANFlasher/TrionicCANFlasher.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {AD7871BE-0280-47D4-9492-2181BB1C789B} 9 | WinExe 10 | Properties 11 | TrionicCANFlasher 12 | TrionicCANFlasher 13 | v4.0 14 | 512 15 | C589B2F2173448DD0C8506BAC6BB0F520170CCE5 16 | T8CANFlasher_TemporaryKey.pfx 17 | true 18 | false 19 | false 20 | C:\publish\ 21 | true 22 | Disk 23 | false 24 | Foreground 25 | 7 26 | Days 27 | false 28 | false 29 | true 30 | true 31 | 1 32 | 1.0.0.%2a 33 | false 34 | true 35 | true 36 | TrionicCanFlasher.ico 37 | 38 | 39 | 3.5 40 | 41 | 42 | 43 | 44 | true 45 | full 46 | false 47 | bin\Debug\ 48 | DEBUG;TRACE 49 | prompt 50 | 4 51 | 52 | 53 | pdbonly 54 | true 55 | bin\Release\ 56 | TRACE 57 | prompt 58 | 4 59 | 60 | 61 | true 62 | bin\x86\Debug\ 63 | DEBUG;TRACE 64 | full 65 | x86 66 | prompt 67 | 68 | 69 | bin\x86\Release\ 70 | TRACE 71 | true 72 | pdbonly 73 | x86 74 | prompt 75 | 76 | 77 | 78 | ..\packages\Newtonsoft.Json.9.0.1\lib\net40\Newtonsoft.Json.dll 79 | True 80 | 81 | 82 | ..\packages\NLog.4.4.12\lib\net40\NLog.dll 83 | True 84 | 85 | 86 | 87 | 3.5 88 | 89 | 90 | 3.5 91 | 92 | 93 | 3.5 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | Form 104 | 105 | 106 | EditParameters.cs 107 | 108 | 109 | Form 110 | 111 | 112 | frmChecksum.cs 113 | 114 | 115 | Form 116 | 117 | 118 | frmSettings.cs 119 | 120 | 121 | Form 122 | 123 | 124 | frmUpdateAvailable.cs 125 | 126 | 127 | Form 128 | 129 | 130 | frmMain.cs 131 | 132 | 133 | 134 | 135 | 136 | 137 | EditParameters.cs 138 | 139 | 140 | frmChecksum.cs 141 | 142 | 143 | frmMain.cs 144 | Designer 145 | 146 | 147 | frmSettings.cs 148 | 149 | 150 | frmUpdateAvailable.cs 151 | 152 | 153 | ResXFileCodeGenerator 154 | Resources.Designer.cs 155 | Designer 156 | 157 | 158 | True 159 | Resources.resx 160 | True 161 | 162 | 163 | 164 | PreserveNewest 165 | 166 | 167 | PreserveNewest 168 | 169 | 170 | 171 | SettingsSingleFileGenerator 172 | Settings.Designer.cs 173 | 174 | 175 | True 176 | Settings.settings 177 | True 178 | 179 | 180 | 181 | 182 | False 183 | .NET Framework Client Profile 184 | false 185 | 186 | 187 | False 188 | .NET Framework 2.0 %28x86%29 189 | false 190 | 191 | 192 | False 193 | .NET Framework 3.0 %28x86%29 194 | false 195 | 196 | 197 | False 198 | .NET Framework 3.5 199 | false 200 | 201 | 202 | False 203 | .NET Framework 3.5 SP1 204 | true 205 | 206 | 207 | False 208 | Windows Installer 3.1 209 | true 210 | 211 | 212 | 213 | 214 | PreserveNewest 215 | 216 | 217 | PreserveNewest 218 | 219 | 220 | 221 | 222 | {3FE690B8-7A3B-425E-913C-BFF7A55F7BC4} 223 | TrionicCANLib 224 | 225 | 226 | 227 | 228 | 229 | 230 | 237 | -------------------------------------------------------------------------------- /TrionicCANFlasher/TrionicCANFlasher.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | C:\publish\ 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | en-US 16 | false 17 | ProjectFiles 18 | false 19 | 20 | -------------------------------------------------------------------------------- /TrionicCANFlasher/TrionicCanFlasher.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattiasclaesson/Trionic/dd8c3fae77d1a6175193486f1dac2dd28cbdeab5/TrionicCANFlasher/TrionicCanFlasher.ico -------------------------------------------------------------------------------- /TrionicCANFlasher/TrionicCanFlasher.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattiasclaesson/Trionic/dd8c3fae77d1a6175193486f1dac2dd28cbdeab5/TrionicCANFlasher/TrionicCanFlasher.pdf -------------------------------------------------------------------------------- /TrionicCANFlasher/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /TrionicCANFlasher/canlib32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattiasclaesson/Trionic/dd8c3fae77d1a6175193486f1dac2dd28cbdeab5/TrionicCANFlasher/canlib32.dll -------------------------------------------------------------------------------- /TrionicCANFlasher/combilib-net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattiasclaesson/Trionic/dd8c3fae77d1a6175193486f1dac2dd28cbdeab5/TrionicCANFlasher/combilib-net.dll -------------------------------------------------------------------------------- /TrionicCANFlasher/documentation/TrionicCanFlasher.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattiasclaesson/Trionic/dd8c3fae77d1a6175193486f1dac2dd28cbdeab5/TrionicCANFlasher/documentation/TrionicCanFlasher.odt -------------------------------------------------------------------------------- /TrionicCANFlasher/frmChecksum.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace TrionicCANFlasher 2 | { 3 | partial class frmChecksum 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmChecksum)); 32 | this.groupBox1 = new System.Windows.Forms.GroupBox(); 33 | this.label2 = new System.Windows.Forms.Label(); 34 | this.label1 = new System.Windows.Forms.Label(); 35 | this.textBox2 = new System.Windows.Forms.TextBox(); 36 | this.textBox1 = new System.Windows.Forms.TextBox(); 37 | this.btnIgnore = new System.Windows.Forms.Button(); 38 | this.btnUpdate = new System.Windows.Forms.Button(); 39 | this.groupBox1.SuspendLayout(); 40 | this.SuspendLayout(); 41 | // 42 | // groupBox1 43 | // 44 | this.groupBox1.Controls.Add(this.label2); 45 | this.groupBox1.Controls.Add(this.label1); 46 | this.groupBox1.Controls.Add(this.textBox2); 47 | this.groupBox1.Controls.Add(this.textBox1); 48 | this.groupBox1.Location = new System.Drawing.Point(12, 12); 49 | this.groupBox1.Name = "groupBox1"; 50 | this.groupBox1.Size = new System.Drawing.Size(448, 106); 51 | this.groupBox1.TabIndex = 0; 52 | this.groupBox1.TabStop = false; 53 | this.groupBox1.Text = "Checksum validation Layer 1"; 54 | // 55 | // label2 56 | // 57 | this.label2.AutoSize = true; 58 | this.label2.Location = new System.Drawing.Point(17, 61); 59 | this.label2.Name = "label2"; 60 | this.label2.Size = new System.Drawing.Size(89, 13); 61 | this.label2.TabIndex = 2; 62 | this.label2.Text = "Actual checksum"; 63 | // 64 | // label1 65 | // 66 | this.label1.AutoSize = true; 67 | this.label1.Location = new System.Drawing.Point(17, 35); 68 | this.label1.Name = "label1"; 69 | this.label1.Size = new System.Drawing.Size(75, 13); 70 | this.label1.TabIndex = 1; 71 | this.label1.Text = "File checksum"; 72 | // 73 | // textBox2 74 | // 75 | this.textBox2.Location = new System.Drawing.Point(119, 58); 76 | this.textBox2.Name = "textBox2"; 77 | this.textBox2.Size = new System.Drawing.Size(323, 20); 78 | this.textBox2.TabIndex = 1; 79 | // 80 | // textBox1 81 | // 82 | this.textBox1.Location = new System.Drawing.Point(119, 32); 83 | this.textBox1.Name = "textBox1"; 84 | this.textBox1.Size = new System.Drawing.Size(323, 20); 85 | this.textBox1.TabIndex = 0; 86 | // 87 | // btnIgnore 88 | // 89 | this.btnIgnore.Location = new System.Drawing.Point(239, 128); 90 | this.btnIgnore.Name = "btnIgnore"; 91 | this.btnIgnore.Size = new System.Drawing.Size(75, 23); 92 | this.btnIgnore.TabIndex = 1; 93 | this.btnIgnore.Text = "Ignore"; 94 | this.btnIgnore.UseVisualStyleBackColor = true; 95 | this.btnIgnore.Click += new System.EventHandler(this.btnIgnore_Click); 96 | // 97 | // btnUpdate 98 | // 99 | this.btnUpdate.Location = new System.Drawing.Point(320, 128); 100 | this.btnUpdate.Name = "btnUpdate"; 101 | this.btnUpdate.Size = new System.Drawing.Size(140, 23); 102 | this.btnUpdate.TabIndex = 2; 103 | this.btnUpdate.Text = "Update and close"; 104 | this.btnUpdate.UseVisualStyleBackColor = true; 105 | this.btnUpdate.Click += new System.EventHandler(this.btnUpdate_Click); 106 | // 107 | // frmChecksum 108 | // 109 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 110 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 111 | this.ClientSize = new System.Drawing.Size(472, 163); 112 | this.Controls.Add(this.btnUpdate); 113 | this.Controls.Add(this.btnIgnore); 114 | this.Controls.Add(this.groupBox1); 115 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 116 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 117 | this.MaximizeBox = false; 118 | this.MinimizeBox = false; 119 | this.Name = "frmChecksum"; 120 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 121 | this.Text = "Trionic checksum"; 122 | this.groupBox1.ResumeLayout(false); 123 | this.groupBox1.PerformLayout(); 124 | this.ResumeLayout(false); 125 | 126 | } 127 | 128 | #endregion 129 | 130 | private System.Windows.Forms.GroupBox groupBox1; 131 | private System.Windows.Forms.Label label2; 132 | private System.Windows.Forms.Label label1; 133 | private System.Windows.Forms.TextBox textBox2; 134 | private System.Windows.Forms.TextBox textBox1; 135 | private System.Windows.Forms.Button btnIgnore; 136 | private System.Windows.Forms.Button btnUpdate; 137 | } 138 | } -------------------------------------------------------------------------------- /TrionicCANFlasher/frmChecksum.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | 10 | namespace TrionicCANFlasher 11 | { 12 | public partial class frmChecksum : Form 13 | { 14 | public frmChecksum() 15 | { 16 | InitializeComponent(); 17 | } 18 | 19 | public string Layer 20 | { 21 | set 22 | { 23 | groupBox1.Text = value; 24 | } 25 | } 26 | 27 | public string FileChecksum 28 | { 29 | set 30 | { 31 | textBox1.Text = value; 32 | } 33 | } 34 | 35 | public string RealChecksum 36 | { 37 | set 38 | { 39 | textBox2.Text = value; 40 | } 41 | } 42 | 43 | private void btnUpdate_Click(object sender, EventArgs e) 44 | { 45 | DialogResult = DialogResult.OK; 46 | this.Close(); 47 | } 48 | 49 | private void btnIgnore_Click(object sender, EventArgs e) 50 | { 51 | DialogResult = DialogResult.Cancel; 52 | this.Close(); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /TrionicCANFlasher/frmMain.resources: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattiasclaesson/Trionic/dd8c3fae77d1a6175193486f1dac2dd28cbdeab5/TrionicCANFlasher/frmMain.resources -------------------------------------------------------------------------------- /TrionicCANFlasher/frmUpdateAvailable.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace TrionicCANFlasher 2 | { 3 | partial class frmUpdateAvailable 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmUpdateAvailable)); 32 | this.button1 = new System.Windows.Forms.Button(); 33 | this.button2 = new System.Windows.Forms.Button(); 34 | this.richTextBox1 = new System.Windows.Forms.RichTextBox(); 35 | this.label1 = new System.Windows.Forms.Label(); 36 | this.SuspendLayout(); 37 | // 38 | // button1 39 | // 40 | this.button1.Location = new System.Drawing.Point(457, 150); 41 | this.button1.Name = "button1"; 42 | this.button1.Size = new System.Drawing.Size(75, 23); 43 | this.button1.TabIndex = 0; 44 | this.button1.Text = "OK"; 45 | this.button1.UseVisualStyleBackColor = true; 46 | this.button1.Click += new System.EventHandler(this.button1_Click); 47 | // 48 | // button2 49 | // 50 | this.button2.DialogResult = System.Windows.Forms.DialogResult.Cancel; 51 | this.button2.Location = new System.Drawing.Point(376, 150); 52 | this.button2.Name = "button2"; 53 | this.button2.Size = new System.Drawing.Size(75, 23); 54 | this.button2.TabIndex = 1; 55 | this.button2.Text = "Ignore"; 56 | this.button2.UseVisualStyleBackColor = true; 57 | this.button2.Click += new System.EventHandler(this.button2_Click); 58 | // 59 | // richTextBox1 60 | // 61 | this.richTextBox1.Font = new System.Drawing.Font("Tahoma", 21.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 62 | this.richTextBox1.Location = new System.Drawing.Point(12, 12); 63 | this.richTextBox1.Name = "richTextBox1"; 64 | this.richTextBox1.ReadOnly = true; 65 | this.richTextBox1.Size = new System.Drawing.Size(520, 96); 66 | this.richTextBox1.TabIndex = 4; 67 | this.richTextBox1.Text = "TrionicCANFlasher automatic updater found some new toys for you!"; 68 | // 69 | // label1 70 | // 71 | this.label1.AutoSize = true; 72 | this.label1.Font = new System.Drawing.Font("Tahoma", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 73 | this.label1.Location = new System.Drawing.Point(178, 115); 74 | this.label1.Name = "label1"; 75 | this.label1.Size = new System.Drawing.Size(166, 18); 76 | this.label1.TabIndex = 5; 77 | this.label1.Text = "Available version: 1.0.54"; 78 | // 79 | // frmUpdateAvailable 80 | // 81 | this.AcceptButton = this.button1; 82 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 83 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 84 | this.CancelButton = this.button2; 85 | this.ClientSize = new System.Drawing.Size(544, 185); 86 | this.Controls.Add(this.label1); 87 | this.Controls.Add(this.richTextBox1); 88 | this.Controls.Add(this.button2); 89 | this.Controls.Add(this.button1); 90 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 91 | this.MaximizeBox = false; 92 | this.MinimizeBox = false; 93 | this.Name = "frmUpdateAvailable"; 94 | this.Text = "New version TrionicCANFlasher available..."; 95 | this.ResumeLayout(false); 96 | this.PerformLayout(); 97 | 98 | } 99 | 100 | #endregion 101 | 102 | private System.Windows.Forms.Button button1; 103 | private System.Windows.Forms.Button button2; 104 | private System.Windows.Forms.RichTextBox richTextBox1; 105 | private System.Windows.Forms.Label label1; 106 | } 107 | } -------------------------------------------------------------------------------- /TrionicCANFlasher/frmUpdateAvailable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | 10 | namespace TrionicCANFlasher 11 | { 12 | public partial class frmUpdateAvailable : Form 13 | { 14 | public frmUpdateAvailable() 15 | { 16 | InitializeComponent(); 17 | } 18 | 19 | public void SetVersionNumber(string version) 20 | { 21 | label1.Text = "Available version: " + version; 22 | } 23 | 24 | private void button1_Click(object sender, EventArgs e) 25 | { 26 | DialogResult = DialogResult.OK; 27 | this.Close(); 28 | } 29 | 30 | private void button2_Click(object sender, EventArgs e) 31 | { 32 | DialogResult = DialogResult.Cancel; 33 | this.Close(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /TrionicCANFlasher/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /TrionicCANLib/BitTools.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace TrionicCANLib 6 | { 7 | internal class BitTools 8 | { 9 | /// 10 | /// Reverses the order of bytes in the input 11 | /// 12 | /// 13 | /// 14 | internal static ulong ReverseOrder(ulong input) 15 | { 16 | ulong output = 0; 17 | output |= (input << 56) & 0xFFUL << 56; 18 | output |= (input << 40) & 0xFFUL << 48; 19 | output |= (input << 24) & 0xFFUL << 40; 20 | output |= (input << 8) & 0xFFUL << 32; 21 | output |= (input >> 8) & 0xFFUL << 24; 22 | output |= (input >> 24) & 0xFFUL << 16; 23 | output |= (input >> 40) & 0xFFUL << 8; 24 | output |= (input >> 56) & 0xFFUL; 25 | 26 | return output; 27 | } 28 | 29 | /// 30 | /// Gets size of can data (in correct order) i.e. 0x20900200000000 31 | /// 32 | /// 33 | /// 34 | internal static int GetDataSize(ulong input) 35 | { 36 | int size = 8; 37 | ulong mask = 0xFF; 38 | while ((input & mask) == 0) 39 | { 40 | size--; 41 | mask <<= 8; 42 | } 43 | return size; 44 | } 45 | 46 | /// 47 | /// Shifts the input, so it can be easily formatted for ELM interface 48 | /// 49 | /// 50 | /// 51 | internal static ulong GetShiftedData(ulong input) 52 | { 53 | int count = 8; 54 | while ((input & 0xFF) == 0 && count > 0) 55 | { 56 | input >>= 8; 57 | count--; 58 | } 59 | return input; 60 | } 61 | 62 | internal static ulong GetUlong(byte[] arr, int startIndex, int count) 63 | { 64 | ulong result = 0x00; 65 | for (int i = startIndex+count-1; i >= startIndex; i--) 66 | { 67 | result <<= 8; 68 | result += arr[i]; 69 | } 70 | return result; 71 | } 72 | 73 | internal static ulong GetFrameBytes(int frameNo, byte[] array, int startIndex) 74 | { 75 | var res = GetUlong(array, startIndex, 7); 76 | res = res << 8 | (ulong)(frameNo & 0xFF); 77 | return res; 78 | } 79 | 80 | internal static bool GetBit(byte b, int pos) 81 | { 82 | return (b & (1 << pos)) != 0; 83 | } 84 | 85 | internal static byte SetBit(byte b, int pos, bool value) 86 | { 87 | byte mask = (byte)(1 << pos); 88 | return (byte)(value ? (b | mask) : (b & ~mask)); 89 | } 90 | 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /TrionicCANLib/BlockManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.IO; 5 | using TrionicCANLib.Firmware; 6 | 7 | namespace TrionicCANLib 8 | { 9 | public class BlockManager 10 | { 11 | private int _blockNumber = 0; 12 | private long Len = 0; 13 | 14 | private string _filename = string.Empty; 15 | byte[] filebytes = null; 16 | 17 | public bool SetFilename(string filename) 18 | { 19 | if (File.Exists(filename)) 20 | { 21 | FileInfo fi = new FileInfo(filename); 22 | 23 | if (fi.Length == FileT8.Length || fi.Length == FileT8mcp.Length) 24 | { 25 | Len = fi.Length; 26 | _filename = filename; 27 | filebytes = File.ReadAllBytes(_filename); 28 | return true; 29 | } 30 | } 31 | return false; 32 | } 33 | 34 | public byte[] GetNextBlock() 35 | { 36 | byte[] returnarray = GetCurrentBlock(); 37 | _blockNumber++; 38 | return returnarray; 39 | 40 | } 41 | 42 | public byte[] GetCurrentBlock() 43 | { 44 | // get 0xEA bytes from the current file but return 0xEE bytes (7 * 34 = 238 = 0xEE bytes) 45 | // if the blocknumber is 0xF50 return less bytes because that is the last block 46 | int address = 0x020000 + _blockNumber * 0xEA; 47 | ByteCoder bc = new ByteCoder(); 48 | if (_blockNumber == 0xF50) 49 | { 50 | byte[] array = new byte[0xE0]; 51 | bc.ResetCounter(); 52 | for (int byteCount = 0; byteCount < 0xE0; byteCount++) 53 | { 54 | array[byteCount] = bc.codeByte(filebytes[address++]); 55 | } 56 | return array; 57 | } 58 | else 59 | { 60 | byte[] array = new byte[0xEE]; 61 | bc.ResetCounter(); 62 | for (int byteCount = 0; byteCount < 0xEA; byteCount++) 63 | { 64 | array[byteCount] = bc.codeByte(filebytes[address++]); 65 | } 66 | return array; 67 | } 68 | } 69 | 70 | // Determine last part of the FLASH chip that is used (to save time when reading (DUMPing)) 71 | // Address 0x020140 stores a pointer to the BIN file Header which is the last used area in FLASH 72 | public int GetLastBlockNumber() 73 | { 74 | int lastAddress = (int)filebytes[0x020141] << 16 | (int)filebytes[0x020142] << 8 | (int)filebytes[0x020143]; 75 | // Add another 512 bytes to include header region (with margin)!!! 76 | lastAddress += 0x200; 77 | return (lastAddress - 0x020000) / 0xEA; 78 | } 79 | 80 | // Determine last address for md5-verification after flashing Trionic 8; main 81 | public uint GetLasAddress() 82 | { 83 | // Add another 512 bytes to include header region (with margin)!!! 84 | // Note; Legion is hardcoded to also add 512 bytes. -Do not change! 85 | return (uint)((int)filebytes[0x020141] << 16 | (int)filebytes[0x020142] << 8 | (int)filebytes[0x020143]) + 0x200; 86 | } 87 | 88 | // Legion hacks 89 | public bool mcpswapped() 90 | { 91 | if (filebytes[0] == 0x08 && filebytes[1] == 0x00 && 92 | filebytes[2] == 0x00 && filebytes[3] == 0x20) 93 | return true; 94 | 95 | return false; 96 | } 97 | public byte[] GetCurrentBlock_128(int block, bool byteswapped) 98 | { 99 | _blockNumber = block; 100 | int address = _blockNumber * 0x80; 101 | 102 | byte[] buffer = new byte[0x80]; 103 | byte[] array = new byte[0x88]; 104 | 105 | if (byteswapped) 106 | { 107 | for (int byteCount = 0; byteCount < 0x80; byteCount+=2) 108 | { 109 | buffer[byteCount + 1] = filebytes[address]; 110 | buffer[byteCount] = filebytes[address + 1]; 111 | address += 2; 112 | } 113 | } 114 | else 115 | { 116 | for (int byteCount = 0; byteCount < 0x80; byteCount++) 117 | { 118 | buffer[byteCount] = filebytes[address++]; 119 | } 120 | } 121 | 122 | ByteCoder bc = new ByteCoder(); 123 | bc.ResetCounter(); 124 | 125 | for (int byteCount = 0; byteCount < 0x80; byteCount++) 126 | { 127 | array[byteCount] = bc.codeByte(buffer[byteCount]); 128 | } 129 | 130 | return array; 131 | } 132 | 133 | /// 134 | /// Scan a defined block for 0xFF 135 | /// 136 | /// Where current block starts 137 | /// Size of block 138 | /// True if everything is 0xFF, otherwise false 139 | public bool FFblock(int address, int size) 140 | { 141 | int count = 0; 142 | 143 | for (int byteCount = 0; byteCount < size; byteCount++) 144 | { 145 | if (address == Len) 146 | break; 147 | if (filebytes[address] == 0xFF) 148 | count++; 149 | 150 | address++; 151 | } 152 | 153 | if (count == size) 154 | return true; 155 | 156 | return false; 157 | } 158 | 159 | // Generate checksum-32 of file 160 | public uint GetChecksum32() 161 | { 162 | uint checksum32 = 0; 163 | 164 | for (uint i = 0; i < Len; i++) 165 | checksum32 += (byte)filebytes[i]; 166 | 167 | return checksum32; 168 | } 169 | 170 | // Partition table of Trionic 8; Main 171 | private static uint[] T8parts = 172 | { 173 | 0x000000, // Boot (0) 174 | 0x004000, // NVDM 175 | 0x006000, // NVDM 176 | 0x008000, // HWIO 177 | 0x020000, // APP 178 | 0x040000, // APP 179 | 0x060000, // APP 180 | 0x080000, // APP 181 | 0x0C0000, // APP 182 | 0x100000, // End (9) 183 | 184 | 0x000000, // Special cases for range-md5 instead of partitions 185 | 0x004000, 186 | 0x020000 187 | }; 188 | 189 | /// 190 | /// Generate md5 of selected partition/region 191 | /// 192 | /// 6 for main flash, 5 for MCP flash 193 | /// Partition/Region to generate md5 from 194 | /// 16-byte array of calculated md5 195 | public byte[] GetPartitionmd5(uint device, uint partition) 196 | { 197 | uint start = 0, e = 0, end = 0x40100; 198 | byte[] hash = new byte[16]; 199 | bool byteswapped = false; 200 | 201 | // Trionic 8, Main 202 | if (partition < 13 && device == 6) 203 | { 204 | if (partition > 0) 205 | { 206 | start = (partition < 10) ? T8parts[partition - 1] : T8parts[partition]; 207 | end = (partition < 10) ? T8parts[partition ] : GetLasAddress(); 208 | } 209 | else 210 | end = T8parts[9]; 211 | } 212 | // Trionic 8; MCP 213 | else if (partition < 10 && device == 5) 214 | { 215 | byteswapped = mcpswapped(); 216 | if (partition > 0) 217 | { 218 | end = (partition == 9) ? (uint)0x40100 : (partition << 15); 219 | start = (partition == 9) ? (uint)0x40000 : (end - 0x8000); 220 | } 221 | } 222 | else 223 | return hash; 224 | 225 | byte[] buf = new byte[end - start]; 226 | 227 | System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); 228 | md5.Initialize(); 229 | 230 | if (!byteswapped) 231 | { 232 | for (uint i = start; i < end; i++) 233 | buf[e++] = filebytes[i]; 234 | } 235 | else 236 | { 237 | for (uint i = start; i < end; i+=2) 238 | { 239 | buf[e++] = filebytes[i + 1]; 240 | buf[e++] = filebytes[i]; 241 | } 242 | } 243 | 244 | return md5.ComputeHash(buf); 245 | } 246 | } 247 | } 248 | -------------------------------------------------------------------------------- /TrionicCANLib/ByteCoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace TrionicCANLib 6 | { 7 | public class ByteCoder 8 | { 9 | private int btcount = 0; 10 | private int cnt = 0; 11 | 12 | public void ResetCounter() 13 | { 14 | cnt = 0; 15 | } 16 | 17 | public byte codeByte(byte b) 18 | { 19 | byte rb = b; 20 | try 21 | { 22 | if (cnt == 0) rb = (byte)(b ^ 0x39); 23 | else if (cnt == 1) rb = (byte)(b ^ 0x68); 24 | else if (cnt == 2) rb = (byte)(b ^ 0x77); 25 | else if (cnt == 3) rb = (byte)(b ^ 0x6D); 26 | else if (cnt == 4) rb = (byte)(b ^ 0x47); 27 | else if (cnt == 5) rb = (byte)(b ^ 0x39); 28 | } 29 | catch (Exception) 30 | { 31 | 32 | } 33 | btcount++; 34 | cnt++; 35 | if (cnt == 6) cnt = 0; 36 | return rb; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /TrionicCANLib/CAN/CANListener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading; 5 | using System.IO; 6 | using System.Diagnostics; 7 | using NLog; 8 | 9 | namespace TrionicCANLib.CAN 10 | { 11 | /// 12 | /// CANListener is used by the CANDevice for listening for CAN messages. 13 | /// 14 | class CANListener : ICANListener 15 | { 16 | private const int QUEUE_SIZE = 128; 17 | 18 | private Logger logger = LogManager.GetCurrentClassLogger(); 19 | private uint m_waitMsgID = 0; 20 | private uint m_additionalWaitMsgID = 0; 21 | 22 | public override bool messagePending() 23 | { 24 | return messageReceived; 25 | } 26 | 27 | //--------------------------------------------------------------------- 28 | /** 29 | */ 30 | public void setupWaitMessage(uint can_id) 31 | { 32 | this.m_waitMsgID = can_id; 33 | } 34 | 35 | public void setupWaitMessage(uint can_id, uint additional_can_id) 36 | { 37 | this.m_waitMsgID = can_id; 38 | m_additionalWaitMsgID = additional_can_id; 39 | } 40 | 41 | //--------------------------------------------------------------------- 42 | /** 43 | */ 44 | 45 | private Stopwatch sw = new Stopwatch(); 46 | 47 | public CANMessage waitMessage(int a_timeout, uint can_id) 48 | { 49 | setupWaitMessage(can_id); 50 | return waitMessage(a_timeout); 51 | } 52 | 53 | public CANMessage waitMessage(int a_timeout) 54 | { 55 | logger.Debug("waitMessage"); 56 | sw.Reset(); 57 | sw.Start(); 58 | CANMessage retMsg = new CANMessage(); 59 | while (sw.ElapsedMilliseconds < a_timeout) 60 | { 61 | // search queue for the desired message 62 | if (_receiveMessageIndex < _readMessageIndex) 63 | { 64 | // first upto (_queue.Length - 1) 65 | for (int idx = _readMessageIndex; idx < _queue.Length; idx++) 66 | { 67 | if (_queue[idx].getID() == this.m_waitMsgID || _queue[idx].getID() == this.m_additionalWaitMsgID) 68 | { 69 | retMsg = _queue[idx]; 70 | _readMessageIndex = idx + 1; 71 | if (_readMessageIndex > _queue.Length - 1) _readMessageIndex = 0; // make it circular 72 | 73 | sw.Stop(); 74 | return retMsg; 75 | } 76 | } 77 | for (int idx = 0; idx < _receiveMessageIndex; idx++) 78 | { 79 | if (_queue[idx].getID() == this.m_waitMsgID || _queue[idx].getID() == this.m_additionalWaitMsgID) 80 | { 81 | retMsg = _queue[idx]; 82 | _readMessageIndex = idx + 1; 83 | if (_readMessageIndex > _queue.Length - 1) _readMessageIndex = 0; // make it circular 84 | sw.Stop(); 85 | return retMsg; 86 | } 87 | } 88 | } 89 | else 90 | { 91 | for (int idx = _readMessageIndex; idx < _receiveMessageIndex; idx++) 92 | { 93 | if (_queue[idx].getID() == this.m_waitMsgID || _queue[idx].getID() == this.m_additionalWaitMsgID) 94 | { 95 | retMsg = _queue[idx]; 96 | _readMessageIndex = idx + 1; 97 | if (_readMessageIndex > _queue.Length - 1) _readMessageIndex = 0; // make it circular 98 | sw.Stop(); 99 | return retMsg; 100 | } 101 | } 102 | } 103 | Thread.Sleep(1); 104 | } 105 | sw.Stop(); 106 | return retMsg; 107 | } 108 | 109 | private bool messageReceived = false; 110 | 111 | 112 | private int _receiveMessageIndex = 0; 113 | private int _readMessageIndex = 0; 114 | private CANMessage[] _queue; 115 | 116 | public override void dumpQueue() 117 | { 118 | for (int idx = 0; idx < _queue.Length; idx ++) 119 | { 120 | if (_receiveMessageIndex == idx && _readMessageIndex == idx) 121 | { 122 | logger.Debug(_queue[idx].getID().ToString("X3") + " " + _queue[idx].getData().ToString("X16") + " RX RD"); 123 | } 124 | else if (_receiveMessageIndex == idx) 125 | { 126 | logger.Debug(_queue[idx].getID().ToString("X3") + " " + _queue[idx].getData().ToString("X16") + " RX"); 127 | } 128 | else if (_readMessageIndex == idx) 129 | { 130 | logger.Debug(_queue[idx].getID().ToString("X3") + " " + _queue[idx].getData().ToString("X16") + " RD"); 131 | } 132 | else 133 | { 134 | logger.Debug(_queue[idx].getID().ToString("X3") + " " + _queue[idx].getData().ToString("X16")); 135 | 136 | } 137 | } 138 | } 139 | 140 | public override void FlushQueue() 141 | { 142 | logger.Debug("FlushQueue"); 143 | _queue = new CANMessage[QUEUE_SIZE]; 144 | _receiveMessageIndex = 0; 145 | _readMessageIndex = 0; 146 | } 147 | 148 | override public void handleMessage(CANMessage a_message) 149 | { 150 | logger.Debug("handleMessage"); 151 | if (_queue == null) 152 | { 153 | _queue = new CANMessage[QUEUE_SIZE]; 154 | _receiveMessageIndex = 0; 155 | _readMessageIndex = 0; 156 | } 157 | 158 | // add the message to a queue for later processing ... 159 | // the queue is a ringbuffer for CANMessage objects. 160 | // X objects are supported 161 | // we need a receive and a read pointer for this to work properly 162 | messageReceived = false; 163 | //_queue[_receiveMessageIndex] = a_message; 164 | _queue[_receiveMessageIndex] = new CANMessage(); 165 | _queue[_receiveMessageIndex].setData(a_message.getData()); 166 | _queue[_receiveMessageIndex].setID(a_message.getID()); 167 | _queue[_receiveMessageIndex].setLength(a_message.getLength()); 168 | 169 | _receiveMessageIndex++; 170 | if(_receiveMessageIndex > _queue.Length - 1) _receiveMessageIndex = 0; // make it circular 171 | 172 | DetermineSize(); 173 | } 174 | 175 | private void DetermineSize() 176 | { 177 | 178 | int size = 0; 179 | if (_receiveMessageIndex > _readMessageIndex) 180 | { 181 | size = _receiveMessageIndex - _readMessageIndex; 182 | } 183 | else 184 | { 185 | size = (_queue.Length - 1) - _readMessageIndex + _receiveMessageIndex; 186 | } 187 | if (size > 1) 188 | { 189 | logger.Debug("Buffering: " + size.ToString() + " messages"); 190 | //dumpQueue(); 191 | } 192 | } 193 | 194 | /// 195 | /// Clears the queue (advances internal indexes) sp that all old messages will be ignored 196 | /// 197 | public void ClearQueue() 198 | { 199 | logger.Debug("ClearQueue"); 200 | _readMessageIndex = _receiveMessageIndex; 201 | } 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /TrionicCANLib/CAN/CANMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace TrionicCANLib.CAN 6 | { 7 | /// 8 | /// The CANMessage class represents a generic CAN message that can be used by virtually 9 | /// all CAN devices. 10 | /// 11 | public class CANMessage 12 | { 13 | 14 | /// 15 | /// m_id is the CAN id 16 | /// 17 | private uint m_id; // 11/29 bit Identifier 18 | /// 19 | /// m_timestamp is the time stamp for the message set by the CAN device 20 | /// 21 | private uint m_timestamp; // Hardware Timestamp (0-9999mS) 22 | /// 23 | /// m_flags is flags set by the CAN device (vendor dependent) 24 | /// 25 | private byte m_flags; // Message Flags 26 | /// 27 | /// m_length is the number of bytes in the message 28 | /// 29 | private byte m_length; // Number of data bytes 0-8. 30 | /// 31 | /// m_data is the data contained in the CAN message. 32 | /// Data is ordered in reverse orded compared to the CAN message. If the message should 33 | /// contain [0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88] m_data should have the 34 | /// value 0x887766554432211. 35 | /// 36 | private ulong m_data; // Data Bytes 0..7 37 | 38 | 39 | /// 40 | /// Used by ELM to indicate number of expected responses 41 | /// 42 | public int elmExpectedResponses=-1; 43 | 44 | /// 45 | /// Constructor for CANMessage 46 | /// 47 | /// CAN id 48 | /// Time stamp 49 | /// Flags 50 | /// Length of data 51 | /// The data 52 | public CANMessage(uint a_id, uint a_timestamp, byte a_flags, byte a_length, ulong a_data) 53 | { 54 | m_id = a_id; 55 | m_timestamp = a_timestamp; 56 | m_flags = a_flags; 57 | m_length = a_length; 58 | m_data = a_data; 59 | } 60 | 61 | /// 62 | /// Constructor for CANMessage 63 | /// 64 | /// CAN id 65 | /// Flags 66 | /// Length of data 67 | public CANMessage(uint a_id, byte a_flags, byte a_length) 68 | { 69 | m_id = a_id; 70 | m_timestamp = 0; 71 | m_flags = a_flags; 72 | m_length = a_length; 73 | m_data = 0; 74 | } 75 | 76 | /// 77 | /// Constructor for CANMessage 78 | /// 79 | public CANMessage() 80 | { 81 | m_id = 0; 82 | m_timestamp = 0; 83 | m_flags = 0; 84 | m_length = 0; 85 | m_data = 0; 86 | } 87 | 88 | public uint getID() { return m_id; } 89 | public uint getTimeStamp() { return m_timestamp; } 90 | public byte getFlags() { return m_flags; } 91 | public byte getLength() { return m_length; } 92 | public ulong getData() { return m_data; } 93 | public void setID(uint a_id) { m_id = a_id; } 94 | public void setTimeStamp(uint a_timeStamp) { m_timestamp = a_timeStamp; } 95 | public void setFlags(byte a_flags) { m_flags = a_flags; } 96 | public void setLength(byte a_length) { m_length = a_length; } 97 | public void setData(ulong a_data) { m_data = a_data; } 98 | 99 | /// 100 | /// Set a byte in the data of a CANMessage 101 | /// 102 | /// The byte to set 103 | /// The index of the byte to be set [0..7] 104 | public void setCanData(byte a_byte, uint a_index) 105 | { 106 | if (a_index > 7) 107 | throw new Exception("Index out of range"); 108 | ulong tmp = (ulong)a_byte; 109 | tmp = tmp << (int)(a_index * 8); 110 | m_data = m_data | tmp; 111 | } 112 | 113 | /// 114 | /// Set a byte array as data of a CANMessage 115 | /// 116 | /// The bytes to set 117 | /// Length of data 118 | public void setCanData(byte[] a_bytes, byte a_length) 119 | { 120 | setData(0L); 121 | 122 | m_length = a_length; 123 | for (uint i = 0; i < m_length; i++) 124 | { 125 | setCanData(a_bytes[i], i); 126 | } 127 | } 128 | 129 | /// 130 | /// Get a byte of the data contained in a CANMessage 131 | /// 132 | /// 133 | /// 134 | public byte getCanData(uint a_index) 135 | { 136 | return (byte)(m_data >> (int)(a_index * 8)); 137 | } 138 | 139 | public ulong getDataEasySync() 140 | { 141 | ulong _data = 0; 142 | _data |= (ulong)((ulong)((m_data & 0xFF00000000000000)) >> (7 * 8)); 143 | _data |= (ulong)((ulong)((m_data & 0x00FF000000000000)) >> (5 * 8)); 144 | _data |= (ulong)((ulong)((m_data & 0x0000FF0000000000)) >> (3 * 8)); 145 | _data |= (ulong)((ulong)((m_data & 0x000000FF00000000)) >> (1 * 8)); 146 | _data |= (ulong)((ulong)((m_data & 0x00000000FF000000)) << (1 * 8)); 147 | _data |= (ulong)((ulong)((m_data & 0x0000000000FF0000)) << (3 * 8)); 148 | _data |= (ulong)((ulong)((m_data & 0x000000000000FF00)) << (5 * 8)); 149 | _data |= (ulong)((ulong)((m_data & 0x00000000000000FF)) << (7 * 8)); 150 | return _data; 151 | } 152 | 153 | public byte[] getDataAsByteArray() 154 | { 155 | byte[] msg = new byte[m_length]; 156 | for (uint i = 0; i < m_length; i++) 157 | { 158 | msg[i] = getCanData(i); 159 | } 160 | return msg; 161 | } 162 | 163 | public byte[] getHeaderAndData() 164 | { 165 | byte[] msg = new byte[m_length+4]; 166 | msg[2] = (byte)(m_id >> 8); 167 | msg[3] = (byte)m_id; 168 | 169 | for (uint i = 0; i < m_length; i++) 170 | { 171 | msg[i+4] = getCanData(i); 172 | } 173 | return msg; 174 | } 175 | 176 | public CANMessage Clone() 177 | { 178 | return new CANMessage(m_id, m_timestamp, m_flags, m_length, m_data); 179 | } 180 | 181 | public bool NeedRepeat { get; set; } 182 | public bool ForceSend { get; set; } 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /TrionicCANLib/CAN/ICANDevice.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using TrionicCANLib.API; 5 | using NLog; 6 | 7 | namespace TrionicCANLib.CAN 8 | { 9 | /// 10 | /// OpenResult is returned by the open method to report the status of the opening. 11 | /// 12 | public enum OpenResult 13 | { 14 | OK, 15 | OpenError 16 | } 17 | /// 18 | /// CloseResult is returned by the close method to report the status of the closening. 19 | /// 20 | public enum CloseResult 21 | { 22 | OK, 23 | CloseError 24 | } 25 | 26 | /// 27 | /// ICANDevice is an interface class for CAN devices. It is used to hide the differences 28 | /// there are in the CAN drivers from different manufactureres (since there is no 29 | /// standardised driver model for CAN devices). 30 | /// For each new CAN device there must be a class that inherits from this and all 31 | /// the abstract methods must be implemented in the sub class. 32 | /// 33 | public abstract class ICANDevice 34 | { 35 | public class InformationFrameEventArgs : System.EventArgs 36 | { 37 | private CANMessage _message; 38 | 39 | public CANMessage Message 40 | { 41 | get 42 | { 43 | return _message; 44 | } 45 | set 46 | { 47 | _message = value; 48 | } 49 | } 50 | 51 | public InformationFrameEventArgs(CANMessage message) 52 | { 53 | this._message = message; 54 | } 55 | } 56 | 57 | public class InformationEventArgs : System.EventArgs 58 | { 59 | private string _info; 60 | 61 | public string Info 62 | { 63 | get 64 | { 65 | return _info; 66 | } 67 | set 68 | { 69 | _info = value; 70 | } 71 | } 72 | 73 | public InformationEventArgs(string info) 74 | { 75 | this._info = info; 76 | } 77 | } 78 | 79 | public delegate void ReceivedAdditionalInformation(object sender, InformationEventArgs e); 80 | public event ReceivedAdditionalInformation onReceivedAdditionalInformation; 81 | 82 | 83 | public delegate void ReceivedAdditionalInformationFrame(object sender, InformationFrameEventArgs e); 84 | public event ReceivedAdditionalInformationFrame onReceivedAdditionalInformationFrame; 85 | 86 | public void CastInformationEvent(CANMessage message) 87 | { 88 | if (onReceivedAdditionalInformationFrame != null) 89 | { 90 | onReceivedAdditionalInformationFrame(this, new InformationFrameEventArgs(message)); 91 | } 92 | } 93 | 94 | public void CastInformationEvent(string info) 95 | { 96 | if (onReceivedAdditionalInformation != null) 97 | { 98 | onReceivedAdditionalInformation(this, new InformationEventArgs(info)); 99 | } 100 | } 101 | 102 | private bool m_OnlyPBus = true; 103 | 104 | public bool UseOnlyPBus 105 | { 106 | get { return m_OnlyPBus; } 107 | set { m_OnlyPBus = value; } 108 | } 109 | 110 | protected List m_AcceptedMessageIds; 111 | 112 | public virtual List AcceptOnlyMessageIds 113 | { 114 | get { return m_AcceptedMessageIds; } 115 | set { m_AcceptedMessageIds = value; } 116 | } 117 | 118 | private ECU m_ECU = ECU.TRIONIC7; 119 | 120 | public ECU TrionicECU 121 | { 122 | get { return m_ECU; } 123 | set { m_ECU = value; } 124 | } 125 | 126 | private Logger logger = LogManager.GetCurrentClassLogger(); 127 | 128 | /// 129 | /// This method opens the device for reading and writing. 130 | /// There is no mechanism for setting the bus speed so this method must 131 | /// detect this. 132 | /// 133 | /// OpenResult 134 | abstract public OpenResult open(); 135 | 136 | /// 137 | /// This method closes the device for reading and writing. 138 | /// 139 | /// CloseResult 140 | abstract public CloseResult close(); 141 | 142 | /// 143 | /// This method checks if the CAN device is opened or closed. 144 | /// 145 | /// true if device is open, otherwise false 146 | abstract public bool isOpen(); 147 | 148 | /// 149 | /// This method sends a CANMessage to the CAN device. 150 | /// The open method must have been called and returned possitive result 151 | /// before this method is called. 152 | /// 153 | /// The CANMessage 154 | /// true on success, otherwise false. 155 | public bool sendMessage(CANMessage a_message) 156 | { 157 | bool result = sendMessageDevice(a_message); 158 | string prefix = result == true ? "tx:" : "tx failed:"; 159 | 160 | logger.Trace(String.Format("{0} {1:X3} {2:X16}", prefix, a_message.getID(), BitTools.ReverseOrder(a_message.getData()))); 161 | return result; 162 | } 163 | abstract protected bool sendMessageDevice(CANMessage a_message); 164 | 165 | abstract public uint waitForMessage(uint a_canID, uint timeout, out CANMessage canMsg); 166 | 167 | public void receivedMessage(CANMessage a_message) 168 | { 169 | lock (m_listeners) 170 | { 171 | logger.Trace(String.Format("rx: {0:X3} {1:X16}", a_message.getID(), BitTools.ReverseOrder(a_message.getData()))); 172 | foreach (ICANListener listener in m_listeners) 173 | { 174 | listener.handleMessage(a_message); 175 | } 176 | } 177 | } 178 | 179 | abstract public float GetThermoValue(); 180 | abstract public float GetADCValue(uint channel); 181 | 182 | static public string[] GetAdapterNames(){return new string[0];} 183 | abstract public void SetSelectedAdapter(string adapter); 184 | 185 | /// 186 | /// This method adds a ICANListener. Any number of ICANListeners can be added (well, 187 | /// it's limited to processor speed and memory). 188 | /// 189 | /// The ICANListener to be added. 190 | /// true on success, otherwise false. 191 | public bool addListener(ICANListener a_listener) 192 | { 193 | lock (m_listeners) 194 | { 195 | m_listeners.Add(a_listener); 196 | } 197 | return true; 198 | } 199 | 200 | /// 201 | /// This method removes a ICANListener. 202 | /// 203 | /// The ICANListener to remove. 204 | /// true on success, otherwise false 205 | public bool removeListener(ICANListener a_listener) 206 | { 207 | lock (m_listeners) 208 | { 209 | m_listeners.Remove(a_listener); 210 | } 211 | return true; 212 | } 213 | 214 | protected bool acceptMessageId(uint msgId) 215 | { 216 | bool accept = m_AcceptedMessageIds == null ? true : m_AcceptedMessageIds.Contains(msgId); 217 | if (!accept) 218 | { 219 | logger.Debug(String.Format("Skipped message with id= {0:X3}", msgId)); 220 | } 221 | 222 | return accept; 223 | } 224 | 225 | abstract public int ForcedBaudrate 226 | { 227 | get; 228 | set; 229 | } 230 | 231 | abstract public bool bypassCANfilters 232 | { 233 | get; 234 | set; 235 | } 236 | 237 | protected List m_listeners = new List(); 238 | 239 | #region ELM327 specific 240 | 241 | /// 242 | /// Used for ELM327 only to stop waiting for messages. This is because when getting lots of responses (i.e. 19 for getting flash) 243 | /// ELM will wait for next message for some time (30-50ms), and this slows down the flash download 244 | /// 245 | public virtual void RequestDeviceReady() 246 | { 247 | } 248 | 249 | #endregion ELM327 specific 250 | } 251 | } 252 | -------------------------------------------------------------------------------- /TrionicCANLib/CAN/ICANListener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace TrionicCANLib.CAN 6 | { 7 | /// 8 | /// ICANListener is an interface class for receiveing CANMessages from ICANDevices. 9 | /// Derived classes must implement the handleMessage method that will receive all 10 | /// CANMessages published by the ICANDevice. 11 | /// There is a possibility to add CAN id filters to remove uniteresting messages. 12 | /// 13 | public abstract class ICANListener 14 | { 15 | public abstract bool messagePending(); 16 | public abstract void dumpQueue(); 17 | public abstract void FlushQueue(); 18 | 19 | /// 20 | /// This method is called by ICANDevices where derived objects of this class 21 | /// are registered. The method is called for each received CANMessage. 22 | /// What this method does is application dependent. 23 | /// 24 | /// The CANMessage to be handled by this method. 25 | public abstract void handleMessage(CANMessage a_canMessage); 26 | 27 | /// 28 | /// This method adds a filter for messages that shouldn't be handled. 29 | /// 30 | /// The ID of the messages that should be filtered. 31 | public void addIDFilter(uint a_canID) { m_idFilter.Add(a_canID); } 32 | 33 | /// 34 | /// This method removed a filter for messages that shouldn't be handled. 35 | /// 36 | /// The ID of the messages that no longer should be filtered. 37 | public void removeIDFilter(uint a_canID) { m_idFilter.Remove(a_canID); } 38 | 39 | /// 40 | /// List of CAN IDs that should be filtered. 41 | /// 42 | private List m_idFilter = new List(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /TrionicCANLib/Checksum/ChecksumDelegate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TrionicCANLib.Checksum 7 | { 8 | public class ChecksumDelegate 9 | { 10 | public delegate bool ChecksumUpdate(string layer, string filechecksum, string realchecksum); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /TrionicCANLib/Checksum/ChecksumResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace TrionicCANLib.Checksum 6 | { 7 | public enum ChecksumResult : int 8 | { 9 | Ok, 10 | InvalidFileLength, 11 | Layer1Failed, 12 | Layer2Failed, 13 | Invalid, 14 | UpdateFailed, 15 | ChecksumFWFailed, 16 | ChecksumF2Failed, 17 | ChecksumFBFailed 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /TrionicCANLib/Checksum/ChecksumT5.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.IO; 5 | using NLog; 6 | using TrionicCANLib.Firmware; 7 | using System.Text; 8 | 9 | namespace TrionicCANLib.Checksum 10 | { 11 | public class ChecksumT5 12 | { 13 | static private Logger logger = LogManager.GetCurrentClassLogger(); 14 | 15 | /// 16 | /// Validates a binary before flashing. 17 | /// 18 | /// filename to flash 19 | /// ChecksumResult.Ok if checksum is correct 20 | public static ChecksumResult VerifyChecksum(string filename, bool autocorrect, ChecksumDelegate.ChecksumUpdate delegateShouldUpdate) 21 | { 22 | FileInfo fi = new FileInfo(filename); 23 | long len = fi.Length; 24 | uint End; 25 | uint Checksum; 26 | 27 | if (!FileT5.VerifyFileSize(len)) 28 | { 29 | return ChecksumResult.InvalidFileLength; 30 | } 31 | 32 | // Store file in a local buffer. 33 | byte[] Bufr = FileTools.readdatafromfile(filename, 0, (int)len); 34 | 35 | 36 | // No need for further checks if result is ok. 37 | if (ChecksumMatch(Bufr, (uint)len, out End, out Checksum) == true) 38 | { 39 | return ChecksumResult.Ok; 40 | } 41 | 42 | // Can't do anything if footer is broken. 43 | else if (End == 0) 44 | { 45 | return ChecksumResult.Invalid; 46 | } 47 | 48 | uint StoredChecksum = (uint)( 49 | Bufr[len - 4] << 24 | Bufr[len - 3] << 16 | 50 | Bufr[len - 2] << 8 | Bufr[len - 1]); 51 | 52 | if (autocorrect == true) 53 | { 54 | Writefile(filename, Checksum, (uint)len); 55 | return ChecksumResult.Ok; 56 | } 57 | else 58 | { 59 | string CalculatedSum = Checksum.ToString("X"); 60 | string ActualSum = StoredChecksum.ToString("X"); 61 | 62 | if (delegateShouldUpdate(null, ActualSum, CalculatedSum)) 63 | { 64 | Writefile(filename, Checksum, (uint)len); 65 | return ChecksumResult.Ok; 66 | } 67 | } 68 | 69 | return ChecksumResult.Invalid; 70 | } 71 | 72 | /// 73 | /// Writes an updated checksum to the binary. 74 | /// 75 | /// Filename to open for writing. 76 | /// Actual buffer to be written. 77 | /// Length of buffer. 78 | private static void Writefile(string a_filename, uint newChecksum, uint Len) 79 | { 80 | if (!File.Exists(a_filename)) 81 | File.Create(a_filename); 82 | 83 | try 84 | { 85 | FileStream fs = new FileStream(a_filename, FileMode.Open, FileAccess.ReadWrite); 86 | fs.Seek(0, SeekOrigin.Begin); 87 | fs.Position = Len - 4; 88 | 89 | for (byte i = 0; i < 4; i++) 90 | { 91 | fs.WriteByte((byte) (newChecksum >> ((3 - i) * 8))); 92 | } 93 | fs.Close(); 94 | } 95 | 96 | catch (Exception E) 97 | { 98 | logger.Debug(E.Message); 99 | } 100 | } 101 | 102 | /// 103 | /// Converts one ASCII character into one nibble. 104 | /// 105 | /// One ASCII character 106 | /// One nibble in binary format 107 | private static int ToNibble(char In) 108 | { 109 | if (In > 0x29 && In < 0x40) // 0 - 9 110 | return In & 0xF; 111 | else if ((In > 0x40 && In < 0x47) || // A - F 112 | (In > 0x60 && In < 0x67)) // a - f 113 | return (In + 9) & 0xF; 114 | else 115 | return -1; // Not ASCII! 116 | } 117 | 118 | /// 119 | /// Determine if it's even possible to extract the last used address from the footer area. 120 | /// 121 | /// 122 | /// 123 | /// Last used address or 0 if it can't be determined 124 | private static uint retLastAddress(byte[] Bufr, uint Len) 125 | { 126 | uint Loc = Len - 5; // Current location in file. 127 | uint End = 0x00000; // Last used address. 128 | 129 | // Attempt to find the 0xFE container. 130 | while (Bufr[Loc - 1] != 0xFE) 131 | { 132 | Loc -= ((uint)(Bufr[Loc]) + 2); 133 | 134 | // No binary has this little data; Abort! 135 | if (Loc < (Len / 2)) 136 | { 137 | logger.Debug("Could not find container!"); 138 | return 0; 139 | } 140 | } 141 | 142 | // Store length of end-marker string. 143 | int MrkL = Bufr[Loc]; 144 | 145 | // Abort if string is longer than 8 chars. 146 | if (MrkL > 8) 147 | { 148 | logger.Debug("Marker too long!"); 149 | return 0; 150 | } 151 | 152 | // Convert ASCII string into usable data. 153 | for (int i = MrkL; i > 0; i--) 154 | { 155 | int Nibble = ToNibble((char)Bufr[(Loc - (MrkL - i)) - 2]); 156 | 157 | // Abort if non-ASCII characters are read! 158 | if (Nibble == -1) 159 | { 160 | logger.Debug("Read invalid data!"); 161 | return 0; 162 | } 163 | 164 | // Bitshift result into the correct location. 165 | End |= (uint)Nibble << ((i - 1) * 4); 166 | } 167 | 168 | // Convert from physical address to file address. 169 | End -= (0x7FFFF - Len); 170 | 171 | // Do not checksum outside of binary. 172 | if (End > Len - 7) 173 | { 174 | logger.Debug("Pointer outside of binary!"); 175 | return 0; 176 | } 177 | 178 | return End; 179 | } 180 | 181 | /// 182 | /// Verifies whether a binary has the correct checksum or not. 183 | /// 184 | /// A buffered copy of the binary 185 | /// Length of passed buffer 186 | /// Checksum correct: true or false 187 | private static bool ChecksumMatch(byte[] Bufr, uint Len, out uint End, out uint Checksum) 188 | { 189 | Checksum = 0; 190 | 191 | // Last four bytes contains a Checksum. Store those for further processing. 192 | uint StoredChecksum = (uint)( 193 | Bufr[Len - 4] << 24 | Bufr[Len - 3] << 16 | 194 | Bufr[Len - 2] << 8 | Bufr[Len - 1]); 195 | 196 | // Extract last used address from footer 197 | End = retLastAddress(Bufr, Len); 198 | 199 | // There is nothing that can be done if the footer is broken. 200 | if (End == 0) 201 | { 202 | return false; 203 | } 204 | 205 | // Calculate actual checksum 206 | for (uint i = 0; i < End; i++) 207 | { 208 | Checksum += (byte)Bufr[i]; 209 | } 210 | 211 | return StoredChecksum == Checksum ? true : false; 212 | } 213 | 214 | /// 215 | /// Validates a dumped binary. 216 | /// 217 | /// buffered copy of current binary 218 | /// true for trionic 5.5, false for 5.2 219 | /// Checksum match: true or false 220 | public static bool ValidateDump(byte[] Bufr, bool IsT55) 221 | { 222 | uint csum; 223 | uint end; 224 | 225 | return ChecksumMatch(Bufr, IsT55 ? FileT5.LengthT55 : FileT5.LengthT52, out end, out csum); 226 | } 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /TrionicCANLib/EnumHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.ComponentModel; 5 | using System.Reflection; 6 | 7 | namespace TrionicCANLib.API 8 | { 9 | public static class EnumHelper 10 | { 11 | 12 | public static string GetDescription(Enum value) 13 | { 14 | FieldInfo fi = value.GetType().GetField(value.ToString()); 15 | 16 | DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); 17 | 18 | if (attributes != null && attributes.Length > 0) 19 | { 20 | return attributes[0].Description; 21 | } 22 | else 23 | { 24 | return value.ToString(); 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /TrionicCANLib/FileTools.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.IO; 5 | using NLog; 6 | using System.Windows.Forms; 7 | 8 | namespace TrionicCANLib 9 | { 10 | class FileTools 11 | { 12 | private readonly static Logger logger = LogManager.GetCurrentClassLogger(); 13 | 14 | public static byte[] readdatafromfile(string filename, int address, int length) 15 | { 16 | if (length <= 0) return new byte[1]; 17 | byte[] retval = new byte[length]; 18 | try 19 | { 20 | using (FileStream fsi1 = File.OpenRead(filename)) 21 | { 22 | while (address > fsi1.Length) address -= (int)fsi1.Length; 23 | BinaryReader br1 = new BinaryReader(fsi1); 24 | fsi1.Position = address; 25 | string temp = string.Empty; 26 | for (int i = 0; i < length; i++) 27 | { 28 | retval.SetValue(br1.ReadByte(), i); 29 | } 30 | fsi1.Flush(); 31 | br1.Close(); 32 | fsi1.Close(); 33 | fsi1.Dispose(); 34 | } 35 | } 36 | catch (Exception E) 37 | { 38 | logger.Debug(E.Message); 39 | } 40 | return retval; 41 | } 42 | 43 | public static bool savedatatobinary(int address, int length, byte[] data, string filename) 44 | { 45 | if (address > 0 && address < Firmware.FileT8.Length) // TODO: mattias support other firmwares 46 | { 47 | try 48 | { 49 | using (FileStream fsi1 = File.OpenWrite(filename)) 50 | { 51 | BinaryWriter bw1 = new BinaryWriter(fsi1); 52 | fsi1.Position = address; 53 | for (int i = 0; i < length; i++) 54 | { 55 | bw1.Write((byte)data.GetValue(i)); 56 | } 57 | fsi1.Flush(); 58 | bw1.Close(); 59 | fsi1.Close(); 60 | fsi1.Dispose(); 61 | } 62 | 63 | // TODO: mattias add TransactionEntry in projectTransactionLog 64 | // implement as event? 65 | 66 | return true; 67 | } 68 | catch (Exception E) 69 | { 70 | MessageBox.Show("Failed to write to binary. Is it read-only? Details: " + E.Message); 71 | logger.Debug(E.Message); 72 | } 73 | } 74 | return false; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /TrionicCANLib/Firmware/BaseFile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace TrionicCANLib.Firmware 6 | { 7 | public class BaseFile 8 | { 9 | static public bool VerifyFileSize(long size) 10 | { 11 | return false; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /TrionicCANLib/Firmware/FileME96.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.IO; 5 | 6 | namespace TrionicCANLib.Firmware 7 | { 8 | public class FileME96 : BaseFile 9 | { 10 | public const uint Length = 0x200000; 11 | public const uint LengthComplete = 0x280000; 12 | 13 | public const uint MainOSAddress = 0x40000; 14 | public const uint EngineCalibrationAddress = 0x1C2000; 15 | public const uint EngineCalibrationAddressEnd = 0x1E0000; 16 | public const uint VersionOffset = 5; 17 | 18 | private static byte[] expectedBegin = {0x48, 0x01, 0x10, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x03, 0xC6, 0x00, 0x00, 0x00, 0x00}; 19 | private static byte[] filled = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 20 | 21 | static public string getFileInfo(string filename) 22 | { 23 | byte[] filebytes = File.ReadAllBytes(filename); 24 | string damosinfo = string.Empty; 25 | 26 | // find damos info indicator 27 | for (int i = 0; i < filebytes.Length; i++) 28 | { 29 | if (i < filebytes.Length - 8) 30 | { 31 | if (filebytes[i] == 'M' && filebytes[i + 1] == 'E' && filebytes[i + 2] == '9' && filebytes[i + 3] == '.' && filebytes[i + 4] == '6') 32 | { 33 | for (int j = 0; j < 44; j++) damosinfo += Convert.ToChar(filebytes[i - 5 + j]); 34 | break; 35 | } 36 | } 37 | } 38 | return damosinfo; 39 | } 40 | 41 | static public bool hasBootloader(string filename) 42 | { 43 | using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) 44 | { 45 | using (BinaryReader br = new BinaryReader(fs)) 46 | { 47 | byte[] read = br.ReadBytes(16); 48 | if (read.AsEnumerable().SequenceEqual(expectedBegin)) 49 | { 50 | return true; 51 | } 52 | } 53 | } 54 | 55 | return false; 56 | } 57 | 58 | static public string getMainOSVersion(string filename) 59 | { 60 | string version = string.Empty; 61 | using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) 62 | { 63 | fs.Seek(MainOSAddress + VersionOffset, SeekOrigin.Begin); //Example 55566563 64 | using (BinaryReader br = new BinaryReader(fs)) 65 | { 66 | byte[] read = br.ReadBytes(8); 67 | if (read.AsEnumerable().SequenceEqual(filled)) 68 | { 69 | return string.Empty; 70 | } 71 | version = System.Text.Encoding.Default.GetString(read); 72 | } 73 | } 74 | 75 | return version; 76 | } 77 | 78 | static public string getEngineCalibrationVersion(string filename) 79 | { 80 | string version = string.Empty; 81 | using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) 82 | { 83 | fs.Seek(EngineCalibrationAddress + VersionOffset, SeekOrigin.Begin); //Example 55569071 84 | using (BinaryReader br = new BinaryReader(fs)) 85 | { 86 | byte[] read = br.ReadBytes(8); 87 | if (read.AsEnumerable().SequenceEqual(filled)) 88 | { 89 | return string.Empty; 90 | } 91 | version = System.Text.Encoding.Default.GetString(read); 92 | } 93 | } 94 | 95 | return version; 96 | } 97 | 98 | static public new bool VerifyFileSize(long size) 99 | { 100 | return size == Length || size == LengthComplete; 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /TrionicCANLib/Firmware/FileT5.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace TrionicCANLib.Firmware 6 | { 7 | public class FileT5 : BaseFile 8 | { 9 | public const uint LengthT52 = 0x20000; 10 | public const uint LengthT55 = 0x40000; 11 | 12 | static public new bool VerifyFileSize(long size) 13 | { 14 | return size == LengthT52 || size == LengthT55; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /TrionicCANLib/Firmware/FileT7.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace TrionicCANLib.Firmware 6 | { 7 | public class FileT7 : BaseFile 8 | { 9 | public const uint Length = 0x80000; 10 | public const uint SRAMAddress = 0x0F00000; 11 | 12 | static public new bool VerifyFileSize(long size) 13 | { 14 | return size == Length; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /TrionicCANLib/Firmware/FileT8.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace TrionicCANLib.Firmware 6 | { 7 | public class FileT8 : BaseFile 8 | { 9 | public const uint Length = 0x100000; 10 | public const uint SRAMAddress = 0x100000; 11 | 12 | static public new bool VerifyFileSize(long size) 13 | { 14 | return size == Length; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /TrionicCANLib/Firmware/FileT8mcp.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace TrionicCANLib.Firmware 6 | { 7 | public class FileT8mcp : BaseFile 8 | { 9 | public const uint Length = 0x40100; 10 | 11 | static public new bool VerifyFileSize(long size) 12 | { 13 | return size == Length; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /TrionicCANLib/FlashReadArguments.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace TrionicCANLib.API 6 | { 7 | public class FlashReadArguments 8 | { 9 | public string FileName { get; set; } 10 | public int start { get; set; } 11 | public int end { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /TrionicCANLib/KWP/IKWPDevice.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using TrionicCANLib.CAN; 5 | 6 | namespace TrionicCANLib.KWP 7 | { 8 | 9 | public enum RequestResult 10 | { 11 | NoError, 12 | ErrorSending, 13 | Timeout, 14 | ErrorReceiving, 15 | Unknown, 16 | InvalidLength 17 | } 18 | 19 | /// 20 | /// IKWPDevice is an interface class for KWP devices (Key Word Protocol). 21 | /// See KWPCANDevice for a description of KWP. 22 | /// 23 | /// All devices that supports KWP must implementd this interface. 24 | /// 25 | public abstract class IKWPDevice 26 | { 27 | /// 28 | /// This method starts a new KWP session. It must be called before the sendRequest 29 | /// method can be called. 30 | /// 31 | /// true on success, otherwise false. 32 | public abstract bool startSession(); 33 | 34 | public abstract bool EnableLog 35 | { 36 | get; 37 | set; 38 | } 39 | 40 | abstract public int ForcedBaudrate 41 | { 42 | get; 43 | set; 44 | } 45 | 46 | abstract public string ForcedComport 47 | { 48 | get; 49 | set; 50 | } 51 | 52 | public abstract void setCANDevice(ICANDevice a_canDevice); 53 | 54 | /// 55 | /// This method sends a KWP request and returns a KWPReply. The method returns 56 | /// when a reply has been received, after a failure or after a timeout. 57 | /// The open and startSession methods must be called and returned possitive result 58 | /// before this method is used. 59 | /// 60 | /// The KWPRequest. 61 | /// The reply to the KWPRequest. 62 | /// RequestResult. 63 | public abstract RequestResult sendRequest(KWPRequest a_request, out KWPReply r_reply); 64 | 65 | /// 66 | /// This method opens a KWP device for usage. 67 | /// 68 | /// true on success, otherwise false. 69 | public abstract bool open(); 70 | 71 | /// 72 | /// This method closes a KWP device for usage. 73 | /// 74 | /// true on success, otherwise false. 75 | public abstract bool close(); 76 | 77 | /// 78 | /// This method checks if the IKWPDevice is opened or not. 79 | /// 80 | /// true if device is open, otherwise false. 81 | public abstract bool isOpen(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /TrionicCANLib/KWP/KWPCANListener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading; 5 | using TrionicCANLib.CAN; 6 | 7 | namespace TrionicCANLib.KWP 8 | { 9 | /// 10 | /// KWPCANListener is used by the KWPCANDevice for listening for CAN messages. 11 | /// 12 | class KWPCANListener : ICANListener 13 | { 14 | private CANMessage m_canMessage = new CANMessage(); 15 | private CANMessage m_EmptyMessage = new CANMessage(); 16 | private uint m_waitMsgID = 0; 17 | private AutoResetEvent m_resetEvent = new AutoResetEvent(false); 18 | private bool messageReceived = false; 19 | 20 | public override void FlushQueue() 21 | { 22 | 23 | } 24 | 25 | public override void dumpQueue() 26 | { 27 | 28 | } 29 | 30 | public override bool messagePending() 31 | { 32 | return messageReceived; 33 | } 34 | 35 | //--------------------------------------------------------------------- 36 | /** 37 | */ 38 | public void setupWaitMessage(uint can_id) 39 | { 40 | this.m_canMessage.setID(0); 41 | lock (this.m_canMessage) 42 | { 43 | this.m_waitMsgID = can_id; 44 | } 45 | } 46 | 47 | //--------------------------------------------------------------------- 48 | /** 49 | */ 50 | public CANMessage waitMessage(int a_timeout) 51 | { 52 | CANMessage retMsg; 53 | 54 | if(m_resetEvent.WaitOne(a_timeout, true)) 55 | { 56 | lock (m_canMessage) 57 | { 58 | retMsg = m_canMessage; 59 | } 60 | } 61 | else 62 | { 63 | retMsg = m_EmptyMessage; 64 | } 65 | messageReceived = false; 66 | return retMsg; 67 | } 68 | 69 | override public void handleMessage(CANMessage a_message) 70 | { 71 | lock (m_canMessage) 72 | { 73 | if (a_message.getID() == m_waitMsgID) 74 | { 75 | m_canMessage.setData(a_message.getData()); 76 | m_canMessage.setFlags(a_message.getFlags()); 77 | m_canMessage.setID(a_message.getID()); 78 | m_canMessage.setLength(a_message.getLength()); 79 | m_canMessage.setTimeStamp(a_message.getTimeStamp()); 80 | messageReceived = true; 81 | m_resetEvent.Set(); 82 | } 83 | } 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /TrionicCANLib/KWP/KWPReply.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using NLog; 5 | 6 | namespace TrionicCANLib.KWP 7 | { 8 | /// 9 | /// KWPReply represents a KWP reply. See KWPCANHandler for description of KWP. 10 | /// 11 | public class KWPReply 12 | { 13 | private Logger logger = LogManager.GetCurrentClassLogger(); 14 | byte[] m_reply; 15 | uint m_nrOfPid; 16 | 17 | /// 18 | /// Constructor. 19 | /// 20 | /// Data representing all bytes in the reply. 21 | /// Number of PIDs. Should originate from the KWPRequest. 22 | public KWPReply(byte[] a_reply, uint a_nrOfPid) 23 | { 24 | if (a_nrOfPid > 2) 25 | throw new Exception("Nr of PID out of range"); 26 | m_reply = a_reply; 27 | if (m_reply == null) 28 | { 29 | logger.Debug("Reply was NULL"); 30 | } 31 | m_nrOfPid = a_nrOfPid; 32 | } 33 | 34 | /// 35 | /// Constructor. 36 | /// 37 | public KWPReply() 38 | { 39 | } 40 | 41 | /// 42 | /// Set the data in the KWPReply. 43 | /// 44 | /// The data. 45 | public void setData(byte[] a_data) 46 | { 47 | m_reply = a_data; 48 | } 49 | 50 | /// 51 | /// Set the number of PIDs there are in this KWPReply. 52 | /// 53 | /// Number of PIDs. 54 | public void setNrOfPID(uint a_nr) { m_nrOfPid = a_nr; } 55 | 56 | /// 57 | /// Get the number of PIDs there are in this KWPReply. 58 | /// 59 | /// Number of PIDs in this reply. 60 | public uint getNrOfPID() { return m_nrOfPid; } 61 | 62 | /// 63 | /// Get the length of the KWPReply. 64 | /// Note. The array containing the data in a KWPReply may be longer than the KWP length. 65 | /// 66 | /// The length of the KWP reply. 67 | public byte getLength() 68 | { 69 | return m_reply[0]; 70 | } 71 | 72 | /// 73 | /// Get the mode of the KWPReply. 74 | /// 75 | /// The mode of the KWP reply. 76 | public byte getMode() 77 | { 78 | if (m_reply != null) 79 | { 80 | return m_reply[1]; 81 | } 82 | return 0; 83 | } 84 | 85 | /// 86 | /// Get the PID of this KWPReply. 87 | /// This method should be used if there is only one PID. 88 | /// 89 | /// The PID. 90 | public byte getPid() 91 | { 92 | return m_reply[2]; 93 | } 94 | 95 | /// 96 | /// Get the high PID (the first PID). 97 | /// This method should be used if there are two PIDs in a KWPReply. 98 | /// 99 | /// The high PID. 100 | public byte getPidHigh() 101 | { 102 | return m_reply[2]; 103 | } 104 | 105 | /// 106 | /// Get the low PID (the second PID). 107 | /// This method should be used if there are two PIDs in a KWPReply. 108 | /// 109 | /// The low PID. 110 | public byte getPidLow() 111 | { 112 | return m_reply[3]; 113 | } 114 | 115 | /// 116 | /// Returns the KWPReply as a byte array. 117 | /// Note that the length of the byte array might be longer than then length 118 | /// of the contained KWP reply. 119 | /// 120 | /// Byte array representing the KWP reply. 121 | public byte[] getData() 122 | { 123 | uint length = 0; 124 | if (getLength() == 1) 125 | { 126 | length = 1; 127 | byte[] data = new byte[length]; 128 | data[0] = m_reply[1]; 129 | return data; 130 | } 131 | else 132 | { 133 | length = getLength() - m_nrOfPid - 1; 134 | byte[] data = new byte[length]; 135 | uint i; 136 | if (m_nrOfPid == 1) 137 | i = 3; 138 | else 139 | i = 4; 140 | for (uint j = 0; j < data.Length; i++, j++) 141 | data[j] = m_reply[i]; 142 | return data; 143 | } 144 | /*uint length = 0; 145 | if (getLength() == 1) 146 | length = 1; 147 | else 148 | length = getLength() - m_nrOfPid - 1; 149 | byte[] data = new byte[length]; 150 | if (length == 1) 151 | { 152 | data[0] = m_reply[1]; 153 | return data; 154 | } 155 | uint i; 156 | if (m_nrOfPid == 1) 157 | i = 3; 158 | else 159 | i = 4; 160 | for (uint j = 0; j < data.Length; i++, j++) 161 | data[j] = m_reply[i]; 162 | return data;*/ 163 | } 164 | 165 | override public String ToString() 166 | { 167 | if(m_reply == null) 168 | return "Empty reply"; 169 | if(m_reply.Length == 0) 170 | return "Empty reply"; 171 | StringBuilder hex = new StringBuilder(); 172 | hex.Append("Reply: "); 173 | for (int i = 0; i < m_reply[0]+1; i++) 174 | { 175 | hex.Append(m_reply[i].ToString("X2") + ","); 176 | } 177 | hex.Remove(hex.Length - 1, 1); 178 | return hex.ToString(); 179 | } 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /TrionicCANLib/KWP/KWPRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using NLog; 5 | 6 | namespace TrionicCANLib.KWP 7 | { 8 | /// 9 | /// KWPRequst represents a KWP request message (see KWPCANDevice for description of KWP). 10 | /// 11 | public class KWPRequest 12 | { 13 | private static Logger logger = LogManager.GetCurrentClassLogger(); 14 | byte[] m_request; 15 | uint m_nrOfPid; 16 | 17 | /// 18 | /// Get the number of PIDs in this KWPRequest. 19 | /// 20 | /// The number of PIDs. 21 | public uint getNrOfPID() { return m_nrOfPid; } 22 | 23 | private int elmResponseResponses = -1; 24 | /// 25 | /// Tells elm how many responses to expect back 26 | /// 27 | public int ElmExpectedResponses { get { return elmResponseResponses; } set { elmResponseResponses = value; } } 28 | 29 | /// 30 | /// Constructor for request with one PID. 31 | /// 32 | /// The mode. 33 | /// The PID. 34 | public KWPRequest(byte a_mode, byte a_pid) 35 | { 36 | int i = 0; 37 | byte length = 2; 38 | m_request = new byte[length + 1]; 39 | m_request[i++] = length; 40 | m_request[i++] = a_mode; 41 | m_request[i++] = a_pid; 42 | m_nrOfPid = 1; 43 | } 44 | 45 | /// 46 | /// Constructor for requests with no PID. 47 | /// 48 | /// The mode. 49 | /// The data. 50 | public KWPRequest(byte a_mode, byte[] a_data) 51 | { 52 | int i = 0; 53 | byte length = (byte)(1 + a_data.Length); 54 | m_request = new byte[length + 1]; 55 | //Set length of request 56 | m_request[i++] = length; 57 | m_request[i++] = a_mode; 58 | for (int j = 0; i < m_request.Length; i++, j++) 59 | m_request[i] = a_data[j]; 60 | m_nrOfPid = 0; 61 | } 62 | 63 | /// 64 | /// Constructor for requests with no PID and no data. 65 | /// 66 | /// The mode. 67 | public KWPRequest(byte a_mode) 68 | { 69 | int i = 0; 70 | byte length = 1; 71 | m_request = new byte[length + 1]; 72 | //Set length of request 73 | m_request[i++] = length; 74 | m_request[i++] = a_mode; 75 | m_nrOfPid = 0; 76 | } 77 | 78 | /// 79 | /// Constructor for requests with one PID and data. 80 | /// 81 | /// The mode. 82 | /// The PID. 83 | /// The data. 84 | public KWPRequest(byte a_mode, byte a_pid, byte[] a_data) 85 | { 86 | int i = 0; 87 | byte length = (byte)(2 + a_data.Length); 88 | if(a_mode == 0x3D && a_pid == 0x80) 89 | { 90 | logger.Debug("KWPRequest length: " + length.ToString("X8")); 91 | } 92 | m_request = new byte[length + 1]; 93 | //Set length of request 94 | m_request[i++] = length; 95 | m_request[i++] = a_mode; 96 | m_request[i++] = a_pid; 97 | for (int j = 0; i < m_request.Length; i++, j++) 98 | m_request[i] = a_data[j]; 99 | m_nrOfPid = 1; 100 | } 101 | 102 | /// 103 | /// Constructor for requests with two PIDs. 104 | /// 105 | /// The mode. 106 | /// The high PID (the first PID). 107 | /// The low PID (the second PID). 108 | /// The data. 109 | public KWPRequest(byte a_mode, byte a_pidHigh, byte a_pidLow, byte[] a_data) 110 | { 111 | int i = 0; 112 | byte length = (byte)(3 + a_data.Length); 113 | m_request = new byte[length + 1]; 114 | m_request[i++] = length; 115 | m_request[i++] = a_mode; 116 | m_request[i++] = a_pidHigh; 117 | m_request[i++] = a_pidLow; 118 | for (int j = 0; i < m_request.Length; i++, j++) 119 | m_request[i] = a_data[j]; 120 | m_nrOfPid = 2; 121 | } 122 | 123 | /// 124 | /// Get the KWPRequest represented as a byte array. 125 | /// 126 | /// Byte array representing the KWPRequest. 127 | public byte[] getData() { return m_request; } 128 | 129 | 130 | override public String ToString() 131 | { 132 | if (m_request.Length == 0) 133 | return "Empty reply"; 134 | StringBuilder hex = new StringBuilder(); 135 | hex.Append("Request: "); 136 | for (int i = 0; i < m_request[0]+1; i++) 137 | { 138 | //if (m_request[i] < 10) 139 | // hex.Append("0"); 140 | hex.Append(m_request[i].ToString("X2")+","); 141 | } 142 | hex.Remove(hex.Length - 1, 1); 143 | return hex.ToString(); 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /TrionicCANLib/Md5Tools.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Security.Cryptography; 6 | using System.IO; 7 | 8 | namespace TrionicCANLib 9 | { 10 | public class Md5Tools 11 | { 12 | public static string GetMd5Hash(MD5 md5Hash, byte[] input) 13 | { 14 | 15 | // Convert the input string to a byte array and compute the hash. 16 | byte[] hash = md5Hash.ComputeHash(input); 17 | return BuildHashString(hash); 18 | } 19 | 20 | // Verify a hash against a string. 21 | public static bool VerifyMd5Hash(MD5 md5Hash, byte[] input, string hash) 22 | { 23 | // Hash the input. 24 | string hashOfInput = GetMd5Hash(md5Hash, input); 25 | 26 | // Create a StringComparer an compare the hashes. 27 | StringComparer comparer = StringComparer.OrdinalIgnoreCase; 28 | 29 | if (0 == comparer.Compare(hashOfInput, hash)) 30 | { 31 | return true; 32 | } 33 | else 34 | { 35 | return false; 36 | } 37 | } 38 | 39 | public static void WriteMd5HashFromByteBuffer(string filename, byte[] buf) 40 | { 41 | using (MD5 md5Hash = MD5.Create()) 42 | { 43 | WriteMd5File(filename, GetMd5Hash(md5Hash, buf)); 44 | } 45 | } 46 | 47 | public static void WriteMd5Hash(MD5 md5Hash, string filename) 48 | { 49 | md5Hash.TransformFinalBlock(new byte[0], 0, 0); 50 | WriteMd5File(filename, BuildHashString(md5Hash.Hash)); 51 | } 52 | 53 | private static void WriteMd5File(string filename, string hash) 54 | { 55 | string md5filename = Path.GetDirectoryName(filename); 56 | md5filename = Path.Combine(md5filename, Path.GetFileNameWithoutExtension(filename) + ".md5"); 57 | File.WriteAllText(md5filename, hash); 58 | } 59 | 60 | private static string BuildHashString(byte[] hash) 61 | { 62 | // Create a new Stringbuilder to collect the bytes 63 | // and create a string. 64 | StringBuilder sBuilder = new StringBuilder(); 65 | 66 | // Loop through each byte of the hashed data 67 | // and format each one as a hexadecimal string. 68 | for (int i = 0; i < hash.Length; i++) 69 | { 70 | sBuilder.Append(hash[i].ToString("x2")); 71 | } 72 | 73 | // Return the hexadecimal string. 74 | return sBuilder.ToString(); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /TrionicCANLib/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TrionicCANLib")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("MattiasC")] 12 | [assembly: AssemblyProduct("TrionicCANLib")] 13 | [assembly: AssemblyCopyright("Copyright © 2022 Dilemma, Mattias Claesson")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("58b9eea3-5809-4cf3-a44b-b8f3ebad815f")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("0.1.59.0")] 36 | [assembly: AssemblyFileVersion("0.1.59.0")] 37 | -------------------------------------------------------------------------------- /TrionicCANLib/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34209 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace TrionicCANLib.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TrionicCANLib.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /TrionicCANLib/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /TrionicCANLib/SeedKey/Algorithm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TrionicCANLib.SeedKey 7 | { 8 | public class Algorithm 9 | { 10 | Step[] steps; 11 | 12 | public Algorithm(Step step0, Step step1, Step step2, Step step3) 13 | { 14 | steps = new Step[4]; 15 | steps[0] = step0; 16 | steps[1] = step1; 17 | steps[2] = step2; 18 | steps[3] = step3; 19 | } 20 | 21 | public UInt16 SeedToKey(UInt16 seed) 22 | { 23 | UInt16 key = seed; 24 | 25 | foreach (Step step in steps) 26 | { 27 | // Perform the operation on the seed value. 28 | key = (UInt16)step.Operation(key); 29 | } 30 | 31 | return key; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /TrionicCANLib/SeedKey/AlgorithmDictionary.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using TrionicCANLib.API; 6 | 7 | namespace TrionicCANLib.SeedKey 8 | { 9 | public static class AlgorithmDictionary 10 | { 11 | private static Dictionary algorithms = new Dictionary 12 | { 13 | {ECU.TRIONIC8, new Algorithm(new Step(0x6B, 0x65, 0x07), new Step(0x4C, 0x0A, 0x77), new Step(0x7E, 0xF8, 0xDA), new Step(0x98, 0x3F, 0x52))}, // 39 000002E5 EC 6B 65 07 4C 0A 77 7E F8 DA 98 3F 52 .ke.L.w~...?R 14 | {ECU.MOTRONIC96, new Algorithm(new Step(0x98, 0x38, 0x08), new Step(0x7E, 0xF2, 0x94), new Step(0x6B, 0xE0, 0x02), new Step(0x4C, 0x03, 0x48))}, // 0B 0000008F 3D 98 38 08 7E F2 94 6B E0 02 4C 03 48 =.8.~..k..L.H 15 | {ECU.MOTRONIC961, new Algorithm(new Step(0xF8, 0x1F, 0x80), new Step(0x05, 0x31, 0x6B), new Step(0x2A, 0x03, 0x4D), new Step(0x75, 0x68, 0x15))}, 16 | {ECU.EDC16C39, new Algorithm(new Step(0x6B, 0x7A, 0x04), new Step(0x7E, 0x82, 0x74), new Step(0x4C, 0x05,0x43), new Step(0x05, 0x1B, 0x9D))}, 17 | {ECU.EDC17C19, new Algorithm(new Step(0x75, 0x50, 0xB0), new Step(0x6B, 0x2C, 0x01), new Step(0x05, 0xC3, 0x42), new Step(0x14, 0x40, 0x93))} 18 | }; 19 | 20 | public static bool TryGetValue(ECU ecu, out Algorithm result) 21 | { 22 | return (algorithms.TryGetValue(ecu, out result)); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /TrionicCANLib/SeedKey/GM-seedkey.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattiasclaesson/Trionic/dd8c3fae77d1a6175193486f1dac2dd28cbdeab5/TrionicCANLib/SeedKey/GM-seedkey.doc -------------------------------------------------------------------------------- /TrionicCANLib/SeedKey/SeedKeyGM.cs: -------------------------------------------------------------------------------- 1 | using NLog; 2 | using System; 3 | using TrionicCANLib.API; 4 | 5 | namespace TrionicCANLib.SeedKey 6 | { 7 | public class SeedKeyGM 8 | { 9 | static private Logger logger = LogManager.GetCurrentClassLogger(); 10 | 11 | public static byte[] CalculateKey(ECU ecu, byte[] seed) 12 | { 13 | UInt16 combinedSeed = (UInt16)(seed[0] << 8 | seed[1]); 14 | 15 | UInt16 key = CalculateKey(ecu, combinedSeed); 16 | 17 | byte[] returnKey = new byte[2]; 18 | returnKey[0] = (byte)((key >> 8) & 0xFF); 19 | returnKey[1] = (byte)(key & 0xFF); 20 | return returnKey; 21 | } 22 | 23 | public static UInt16 CalculateKey(ECU ecu, UInt16 seed) 24 | { 25 | Algorithm algorithm; 26 | AlgorithmDictionary.TryGetValue(ecu, out algorithm); 27 | UInt16 key = algorithm.SeedToKey(seed); 28 | return key; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /TrionicCANLib/SeedKey/Step.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using NLog; 4 | 5 | 6 | namespace TrionicCANLib.SeedKey 7 | { 8 | public class Step 9 | { 10 | private Logger logger = LogManager.GetCurrentClassLogger(); 11 | 12 | private byte operation; 13 | private byte parameter0; 14 | private byte parameter1; 15 | 16 | public Step(byte operation, byte parameter0, byte parameter1) 17 | { 18 | this.operation = operation; 19 | this.parameter0 = parameter0; 20 | this.parameter1 = parameter1; 21 | } 22 | 23 | private static uint RotateLeft(uint value, int count) 24 | { 25 | return (value << count) | (value >> (16 - count)); 26 | } 27 | 28 | private static uint RotateRight(uint value, int count) 29 | { 30 | return (value >> count) | (value << (16 - count)); 31 | } 32 | 33 | private static uint Subtract(uint key, byte parameter0, byte parameter1) 34 | { 35 | return key - (UInt16)(parameter1 + (UInt16)((parameter0) << 8)); 36 | } 37 | 38 | public uint Operation(uint key) 39 | { 40 | logger.Debug(string.Format("Key {0} Operation {1} Param0 {2} Param1 {3}", key, operation, parameter0, parameter1)); 41 | switch (operation) 42 | { 43 | case 5: 44 | return RotateLeft(key, 8); 45 | case 0x14: 46 | return key + (UInt16)(parameter1 + (UInt16)((parameter0) << 8)); 47 | case 0x2A: 48 | if (parameter0 < parameter1) 49 | return ~key + 1; 50 | else 51 | return ~key; 52 | case 0x37: 53 | return key & (UInt16)(parameter0 + (UInt16)((parameter1) << 8)); 54 | case 0x4C: 55 | return RotateLeft(key, parameter0); 56 | case 0x52: 57 | return key | (UInt16)(parameter0 + (UInt16)((parameter1) << 8)); 58 | case 0x6B: 59 | return RotateRight(key, parameter1); 60 | case 0x75: 61 | return key + (UInt16)(parameter0 + (UInt16)((parameter1) << 8)); 62 | case 0x7E: 63 | if (parameter0 >= parameter1) 64 | return RotateLeft(key, 8) + parameter1 + (UInt16)(parameter0 << 8); 65 | else 66 | return RotateLeft(key, 8) + parameter0 + (UInt16)(parameter1 << 8); 67 | case 0x98: 68 | return Subtract(key, parameter0, parameter1); 69 | case 0xF8: 70 | return key - (UInt16)(parameter0 + (UInt16)((parameter1) << 8)); 71 | default: 72 | break; 73 | } 74 | 75 | return key; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /TrionicCANLib/SeedToKey.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace TrionicCANLib 6 | { 7 | public enum AccessLevel : int 8 | { 9 | AccessLevel01, 10 | AccessLevelFB, 11 | AccessLevelFD // Highest access level 12 | } 13 | 14 | public class SeedToKey 15 | { 16 | 17 | public byte[] calculateKey(byte[] a_seed, AccessLevel level) 18 | { 19 | int seed = a_seed[0] << 8 | a_seed[1]; 20 | int key = 0; 21 | byte[] returnKey = new byte[2]; 22 | key = convertSeed(seed); 23 | if (level == AccessLevel.AccessLevelFD) 24 | { 25 | key /= 3; 26 | key ^= 0x8749; 27 | key += 0x0ACF; 28 | key ^= 0x81BF; 29 | } 30 | else if (level == AccessLevel.AccessLevelFB) 31 | { 32 | key ^= 0x8749; 33 | key += 0x06D3; 34 | key ^= 0xCFDF; 35 | } 36 | returnKey[0] = (byte)((key >> 8) & 0xFF); 37 | returnKey[1] = (byte)(key & 0xFF); 38 | return returnKey; 39 | } 40 | 41 | public byte[] calculateKeyForCIM(byte[] a_seed) 42 | { 43 | int seed = a_seed[0] << 8 | a_seed[1]; 44 | int key = 0; 45 | byte[] returnKey = new byte[2]; 46 | key = convertSeedCIM(seed); 47 | 48 | returnKey[0] = (byte)((key >> 8) & 0xFF); 49 | returnKey[1] = (byte)(key & 0xFF); 50 | return returnKey; 51 | } 52 | 53 | public byte[] calculateKeyForME96(byte[] a_seed) 54 | { 55 | int seed = a_seed[0] << 8 | a_seed[1]; 56 | int key = 0; 57 | byte[] returnKey = new byte[2]; 58 | key = RetSeed(seed); 59 | //key = keys[seed]; 60 | 61 | returnKey[0] = (byte)((key >> 8) & 0xFF); 62 | returnKey[1] = (byte)(key & 0xFF); 63 | return returnKey; 64 | } 65 | 66 | private int convertSeed(int seed) 67 | { 68 | int key = (seed >> 5) | (seed << 11); 69 | return (key + 0xB988) & 0xFFFF; 70 | } 71 | 72 | private int convertSeedCIM(int seed) 73 | { 74 | int key = (seed + 0x9130) & 0xFFFF; 75 | key = (key >> 8) | (key << 8); 76 | return (0x3FC7 - key) & 0xFFFF; 77 | } 78 | 79 | private int RetSeed(int Seed) 80 | { 81 | // Not correct but it works with a patch 82 | int Component2 = (0xEB + Seed) & 0xFF; 83 | 84 | // Catch Anomalies 85 | if (Seed >= 0x3808 && Seed < 0xA408) 86 | Component2 -= 1; 87 | 88 | return ((Component2 << 9) | ((((0x5BF8 + Seed) >> 8) & 0xFF) << 1) | ((Component2 >> 7) & 1)) & 0xFFFF; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /TrionicCANLib/T8CANLib.pidb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattiasclaesson/Trionic/dd8c3fae77d1a6175193486f1dac2dd28cbdeab5/TrionicCANLib/T8CANLib.pidb -------------------------------------------------------------------------------- /TrionicCANLib/T8CANLib.userprefs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /TrionicCANLib/TrionicCANLib.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {3FE690B8-7A3B-425E-913C-BFF7A55F7BC4} 9 | Library 10 | Properties 11 | TrionicCANLib 12 | TrionicCANLib 13 | v4.0 14 | 512 15 | 16 | 17 | 3.5 18 | 19 | 20 | 21 | 22 | true 23 | full 24 | false 25 | bin\Debug\ 26 | DEBUG;TRACE 27 | prompt 28 | 4 29 | 30 | 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | 38 | 39 | true 40 | bin\x86\Debug\ 41 | DEBUG;TRACE 42 | full 43 | x86 44 | prompt 45 | 46 | 47 | bin\x86\Release\ 48 | TRACE 49 | true 50 | pdbonly 51 | x86 52 | prompt 53 | 54 | 55 | 56 | False 57 | ..\Libs\canlibCLSNET.dll 58 | 59 | 60 | False 61 | ..\Libs\canusbdrv_net.dll 62 | 63 | 64 | False 65 | ..\Libs\combilib-net.dll 66 | 67 | 68 | False 69 | ..\Libs\FTD2XX_NET.dll 70 | 71 | 72 | False 73 | ..\Libs\J2534DotNet.dll 74 | 75 | 76 | False 77 | ..\Libs\LibUsbDotNet.dll 78 | 79 | 80 | ..\packages\NLog.4.4.12\lib\net40\NLog.dll 81 | True 82 | 83 | 84 | 85 | 86 | 3.5 87 | 88 | 89 | 90 | 91 | 92 | 3.5 93 | 94 | 95 | 3.5 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | True 144 | True 145 | Resources.resx 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | Code 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | ResXFileCodeGenerator 167 | Resources.Designer.cs 168 | Designer 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 186 | -------------------------------------------------------------------------------- /TrionicCANLib/TrionicEnums.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.ComponentModel; 5 | 6 | namespace TrionicCANLib.API 7 | { 8 | public enum ActivityType : int 9 | { 10 | StartUploadingBootloader, 11 | UploadingBootloader, 12 | FinishedUploadingBootloader, 13 | StartFlashing, 14 | UploadingFlash, 15 | FinishedFlashing, 16 | StartErasingFlash, 17 | ErasingFlash, 18 | FinishedErasingFlash, 19 | DownloadingSRAM, 20 | ConvertingFile, 21 | StartDownloadingFlash, 22 | DownloadingFlash, 23 | FinishedDownloadingFlash, 24 | StartDownloadingFooter, 25 | DownloadingFooter, 26 | FinishedDownloadingFooter, 27 | CalculatingChecksum, 28 | QueryingECUTypeInfo 29 | } 30 | 31 | public enum CANBusAdapter : int 32 | { 33 | [Description("Lawicel CANUSB")] 34 | LAWICEL, 35 | [Description("CombiAdapter")] 36 | COMBI, 37 | [Description("OBDLink SX")] 38 | ELM327, 39 | [Description("Just4Trionic")] 40 | JUST4TRIONIC, 41 | [Description("Kvaser HS")] 42 | KVASER, 43 | [Description("J2534")] 44 | J2534 45 | }; 46 | 47 | public enum ECU : int 48 | { 49 | [Description("Trionic 5")] 50 | TRIONIC5, 51 | [Description("Trionic 7")] 52 | TRIONIC7, 53 | [Description("Trionic 8; Main")] 54 | TRIONIC8, 55 | [Description("Trionic 8; MCP (Experimental)")] 56 | TRIONIC8_MCP, 57 | 58 | [Description("Bosch ME9.6")] 59 | MOTRONIC96, 60 | 61 | [Description("Z22SE; Main (Experimental)")] 62 | Z22SEMain_LEG, 63 | [Description("Z22SE; MCP (Experimental)")] 64 | Z22SEMCP_LEG, 65 | 66 | 67 | // Sorry for moving these but the enumration gets borked when items are "disabled" 68 | 69 | // [Description("Bosch ME9.6.1")] 70 | MOTRONIC961, 71 | 72 | // [Description("EDC16C39 car XX")] 73 | EDC16C39, 74 | 75 | // [Description("EDC17C19")] 76 | EDC17C19 77 | }; 78 | 79 | public enum SleepTime : int 80 | { 81 | Default = 2, 82 | ELM327 = 0 83 | }; 84 | 85 | public enum ComSpeed : int 86 | { 87 | S115200, 88 | S230400, 89 | S1Mbit, 90 | S2Mbit 91 | }; 92 | 93 | public enum Latency : int 94 | { 95 | Low, 96 | Default 97 | }; 98 | } 99 | -------------------------------------------------------------------------------- /TrionicCANLib/WMI/COMPortInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Management; 5 | 6 | // A way of using WMI to find the right COM port number from its 'friendly name' 7 | // 8 | // Shamelessly plagiarised from: 9 | // https://dariosantarelli.wordpress.com/2010/10/18/c-how-to-programmatically-find-a-com-port-by-friendly-name/ 10 | // 11 | // Add a refernce to Windows System Management: 12 | // using System.Management; 13 | // and System.Management.dll to project references: 14 | // In Solution Explorer, right click on your project and choose the Add Reference menu. 15 | // 16 | // Example of how to use: 17 | // foreach (COMPortInfo comPort in COMPortInfo.GetCOMPortsInfo()) 18 | // { 19 | // logger.Debug(string.Format("{0} – {1}", comPort.Name, comPort.Description)); 20 | // } 21 | 22 | namespace TrionicCANLib.WMI 23 | { 24 | public class COMPortInfo 25 | { 26 | public string Name { get; set; } 27 | public string Description { get; set; } 28 | 29 | public static List GetCOMPortsInfo() 30 | { 31 | List comPortInfoList = new List(); 32 | 33 | ConnectionOptions options = ProcessConnection.ProcessConnectionOptions(); 34 | ManagementScope connectionScope = ProcessConnection.ConnectionScope(Environment.MachineName, options, @"\root\CIMV2"); 35 | 36 | ObjectQuery objectQuery = new ObjectQuery("SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode = 0"); 37 | ManagementObjectSearcher comPortSearcher = new ManagementObjectSearcher(connectionScope, objectQuery); 38 | 39 | using (comPortSearcher) 40 | { 41 | string caption = null; 42 | foreach (ManagementObject obj in comPortSearcher.Get()) 43 | { 44 | if (obj != null) 45 | { 46 | object captionObj = obj["Caption"]; 47 | if (captionObj != null) 48 | { 49 | caption = captionObj.ToString(); 50 | if (caption.Contains("(COM")) 51 | { 52 | COMPortInfo comPortInfo = new COMPortInfo() 53 | { 54 | Name = caption.Substring(caption.LastIndexOf("(COM")).Replace("(", string.Empty).Replace(")", string.Empty), 55 | Description = caption 56 | }; 57 | comPortInfoList.Add(comPortInfo); 58 | } 59 | } 60 | } 61 | } 62 | } 63 | return comPortInfoList; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /TrionicCANLib/WMI/ProcessConnection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Management; 5 | 6 | namespace TrionicCANLib.WMI 7 | { 8 | internal class ProcessConnection 9 | { 10 | 11 | public static ConnectionOptions ProcessConnectionOptions() 12 | { 13 | ConnectionOptions options = new ConnectionOptions() 14 | { 15 | Impersonation = ImpersonationLevel.Impersonate, 16 | Authentication = AuthenticationLevel.Default, 17 | EnablePrivileges = true 18 | }; 19 | return options; 20 | } 21 | 22 | public static ManagementScope ConnectionScope(string machineName, ConnectionOptions options, string path) 23 | { 24 | ManagementScope connectScope = new ManagementScope() 25 | { 26 | Path = new ManagementPath(String.Format(@"\\{0}{1}", machineName, path)), 27 | Options = options 28 | }; 29 | connectScope.Connect(); 30 | return connectScope; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /TrionicCANLib/flasher/IFlasher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace TrionicCANLib.Flasher 5 | { 6 | //----------------------------------------------------------------------------- 7 | /** 8 | Trionic 7 CAN flasher base class. 9 | */ 10 | abstract public class IFlasher 11 | { 12 | public delegate void StatusChanged(object sender, StatusEventArgs e); 13 | abstract public event StatusChanged onStatusChanged; 14 | 15 | public class StatusEventArgs : System.EventArgs 16 | { 17 | private string _info; 18 | 19 | public string Info 20 | { 21 | get { return _info; } 22 | set { _info = value; } 23 | } 24 | 25 | public StatusEventArgs(string info) 26 | { 27 | this._info = info; 28 | } 29 | } 30 | 31 | 32 | // flasher commands 33 | public enum FlashCommand 34 | { 35 | ReadCommand, 36 | ReadMemoryCommand, 37 | ReadSymbolMapCommand, 38 | ReadSymbolNameCommand, 39 | WriteCommand, 40 | StopCommand, 41 | NoCommand 42 | }; 43 | 44 | // status of current flashing session 45 | public enum FlashStatus 46 | { 47 | Reading, 48 | Writing, 49 | Eraseing, 50 | NoSequrityAccess, 51 | DoinNuthin, 52 | Completed, 53 | NoSuchFile, 54 | EraseError, 55 | WriteError, 56 | ReadError, 57 | StartingFlashSession, 58 | WritingBaseSection, 59 | WritingLastSection 60 | }; 61 | 62 | // dynamic state 63 | protected FlashStatus m_flashStatus; ///< current status 64 | protected FlashCommand m_command; ///< command 65 | protected Object m_synchObject = new Object(); ///< state lock 66 | 67 | //------------------------------------------------------------------------- 68 | /** 69 | Default constructor. 70 | */ 71 | public IFlasher() 72 | { 73 | // clear state 74 | this.m_flashStatus = FlashStatus.DoinNuthin; 75 | this.m_command = FlashCommand.NoCommand; 76 | } 77 | 78 | public abstract void cleanup(); 79 | 80 | //------------------------------------------------------------------------- 81 | /** 82 | Returns the current status of flasher. 83 | 84 | @return status 85 | */ 86 | public virtual FlashStatus getStatus() 87 | { 88 | return this.m_flashStatus; 89 | } 90 | 91 | public abstract int getNrOfBytesRead(); 92 | 93 | //------------------------------------------------------------------------- 94 | /** 95 | Interrupts ongoing read or write session. 96 | */ 97 | public virtual void stopFlasher() 98 | { 99 | lock (this.m_synchObject) 100 | { 101 | this.m_command = FlashCommand.StopCommand; 102 | this.m_flashStatus = FlashStatus.DoinNuthin; 103 | } 104 | } 105 | 106 | //------------------------------------------------------------------------- 107 | /** 108 | Starts a flash reading session. 109 | 110 | @param a_fileName name of target file 111 | */ 112 | public virtual void readFlash(string a_fileName) 113 | { 114 | lock (this.m_synchObject) 115 | { 116 | this.m_command = FlashCommand.ReadCommand; 117 | } 118 | } 119 | 120 | //------------------------------------------------------------------------- 121 | /** 122 | Starts a SRAM reading session. 123 | 124 | @param a_fileName name of target file 125 | @param a_offset source offset 126 | @param a_length source length, bytes 127 | */ 128 | public virtual void readMemory(string a_fileName, UInt32 a_offset, 129 | UInt32 a_length) 130 | { 131 | lock (this.m_synchObject) 132 | { 133 | m_command = FlashCommand.ReadMemoryCommand; 134 | } 135 | } 136 | 137 | //------------------------------------------------------------------------- 138 | /** 139 | Starts a symbol map reading session. 140 | 141 | @param a_fileName name of target file 142 | */ 143 | public virtual void readSymbolMap(string a_fileName) 144 | { 145 | lock (m_synchObject) 146 | { 147 | m_command = FlashCommand.ReadSymbolMapCommand; 148 | } 149 | } 150 | 151 | //------------------------------------------------------------------------- 152 | /** 153 | Starts writing to flash memory. 154 | 155 | @param a_fileName name of source file 156 | */ 157 | public virtual void writeFlash(string a_fileName) 158 | { 159 | lock (m_synchObject) 160 | { 161 | m_command = FlashCommand.WriteCommand; 162 | } 163 | } 164 | }; 165 | } 166 | -------------------------------------------------------------------------------- /TrionicCANLib/flasher/T7CombiFlasher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using Combi; 5 | using NLog; 6 | 7 | namespace TrionicCANLib.Flasher 8 | { 9 | //------------------------------------------------------------------------------------------------- 10 | public class T7CombiFlasher : IFlasher 11 | { 12 | // dynamic state 13 | private readonly caCombiAdapter combi; ///< adapter object 14 | 15 | // events 16 | public override event IFlasher.StatusChanged onStatusChanged; 17 | 18 | private Logger logger = LogManager.GetCurrentClassLogger(); 19 | 20 | //--------------------------------------------------------------------------------------------- 21 | /** 22 | Constructor. 23 | 24 | @param _combi adapter object 25 | */ 26 | public T7CombiFlasher(caCombiAdapter _combi) 27 | { 28 | Debug.Assert(_combi != null); 29 | combi = _combi; 30 | } 31 | 32 | //--------------------------------------------------------------------------------------------- 33 | /** 34 | Returns the current status of flasher. 35 | 36 | @return status 37 | */ 38 | public override FlashStatus getStatus() 39 | { 40 | if (combi.OperationRunning()) 41 | { 42 | // in progress 43 | return m_flashStatus; 44 | } 45 | 46 | if (!combi.OperationSucceeded()) 47 | { 48 | // failed (no way to know the real reason) 49 | switch (m_command) 50 | { 51 | case FlashCommand.ReadCommand: 52 | case FlashCommand.ReadMemoryCommand: 53 | case FlashCommand.ReadSymbolMapCommand: 54 | case FlashCommand.ReadSymbolNameCommand: 55 | return FlashStatus.ReadError; 56 | 57 | case FlashCommand.WriteCommand: 58 | return FlashStatus.WriteError; 59 | }; 60 | } 61 | 62 | return FlashStatus.Completed; 63 | } 64 | 65 | //--------------------------------------------------------------------------------------------- 66 | /** 67 | Returns the number of bytes that has been read or written so far; 0 is 68 | returned if there is no read or write session ongoing. 69 | 70 | @return number of bytes 71 | */ 72 | public override int getNrOfBytesRead() 73 | { 74 | return (int)combi.GetOperationProgress(); 75 | } 76 | 77 | //--------------------------------------------------------------------------------------------- 78 | /** 79 | Interrupts ongoing read or write session. 80 | */ 81 | public override void stopFlasher() 82 | { 83 | endSession(); 84 | 85 | base.stopFlasher(); 86 | m_flashStatus = FlashStatus.Completed; 87 | } 88 | 89 | //--------------------------------------------------------------------------------------------- 90 | /** 91 | Starts a flash reading session. 92 | 93 | @param a_fileName name of target file 94 | */ 95 | public override void readFlash(string a_fileName) 96 | { 97 | base.readFlash(a_fileName); 98 | 99 | try 100 | { 101 | // connect to ECU; this may take some time as both 102 | // P-Bus and I-bus are checked for traffic 103 | if (!beginSession()) 104 | { 105 | throw new Exception("Failed to start session"); 106 | } 107 | 108 | // read flash 109 | combi.CAN_ReadFlash(a_fileName); 110 | m_flashStatus = FlashStatus.Reading; 111 | } 112 | 113 | catch (Exception e) 114 | { 115 | logger.Debug("Read error: " + e.Message); 116 | m_flashStatus = FlashStatus.ReadError; 117 | } 118 | } 119 | 120 | //--------------------------------------------------------------------------------------------- 121 | /** 122 | Starts a flash writing session. 123 | 124 | @param a_fileName name of target file 125 | */ 126 | public override void writeFlash(string a_fileName) 127 | { 128 | base.writeFlash(a_fileName); 129 | 130 | try 131 | { 132 | // connect to ECU; this may take some time as both 133 | // P-Bus and I-bus are checked for traffic 134 | if (!beginSession()) 135 | { 136 | throw new Exception("Failed to start session"); 137 | } 138 | 139 | // read flash 140 | combi.CAN_WriteFlash(a_fileName, 0); 141 | m_flashStatus = FlashStatus.Writing; 142 | } 143 | 144 | catch (Exception e) 145 | { 146 | logger.Debug("Write error: " + e.Message); 147 | m_flashStatus = FlashStatus.WriteError; 148 | } 149 | } 150 | 151 | //--------------------------------------------------------------------------------------------- 152 | /** 153 | Begins a communication session with ECU. 154 | 155 | @return succ / fail 156 | */ 157 | public bool beginSession() 158 | { 159 | try 160 | { 161 | combi.CAN_ConnectECU(3); 162 | return true; 163 | } 164 | 165 | catch (Exception e) 166 | { 167 | logger.Debug("Session error: " + e.Message); 168 | return false; 169 | } 170 | } 171 | 172 | //--------------------------------------------------------------------------------------------- 173 | /** 174 | Ends a communication session with ECU. 175 | */ 176 | public void endSession() 177 | { 178 | logger.Debug("End communication session"); 179 | combi.CAN_DisconnectECU(false); 180 | } 181 | 182 | public override void cleanup() 183 | { 184 | } 185 | }; 186 | } 187 | -------------------------------------------------------------------------------- /TrionicCANLib/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /TrionicCANLibTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TrionicCANLibTest")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("TrionicCANLibTest")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0e0a92ee-48af-49d0-9f9c-6054c799ebfc")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /TrionicCANLibTest/SeedKeyGMTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using TrionicCANLib.API; 4 | using TrionicCANLib.SeedKey; 5 | 6 | namespace TrionicCANLibTest 7 | { 8 | [TestClass] 9 | public class SeedKeyGMTest 10 | { 11 | [TestMethod] 12 | public void TestT8KeySeedUsingByteArray() 13 | { 14 | // Given 15 | // T8 SecurityLevel = AccessLevel.AccessLevel01 16 | // seed 5f94 [0 high][1 low] 17 | // key 5c84 [0 high][1 low] 18 | byte[] seed = { 0x5F, 0x94 }; 19 | byte[] expectedKey = { 0x5C, 0x84 }; 20 | 21 | // When 22 | byte[] actualKey = SeedKeyGM.CalculateKey(ECU.TRIONIC8, seed); 23 | 24 | // Then 25 | CollectionAssert.AreEqual(expectedKey, actualKey); 26 | } 27 | 28 | [TestMethod] 29 | public void TestT8KeySeedUsingUInt16() 30 | { 31 | // Given 32 | // T8 SecurityLevel = AccessLevel.AccessLevel01 33 | // seed 5f94 [0 high][1 low] 34 | // key 5c84 [0 high][1 low] 35 | UInt16 seed = 0x5F94; 36 | UInt16 expectedKey = 0x5C84; 37 | 38 | // When 39 | UInt16 actualKey = SeedKeyGM.CalculateKey(ECU.TRIONIC8, seed); 40 | 41 | // Then 42 | Assert.AreEqual(expectedKey, actualKey); 43 | } 44 | 45 | [TestMethod] 46 | public void TestME96KeySeedUsingByteArray() 47 | { 48 | // Given 49 | // ME96 50 | // seed C72B [0 high][1 low] 51 | // key 2C46 [0 high][1 low] 52 | byte[] seed = { 0xC7, 0x2B }; 53 | byte[] expectedKey = { 0x2C, 0x46 }; 54 | 55 | // When 56 | byte[] actualKey = SeedKeyGM.CalculateKey(ECU.MOTRONIC96, seed); 57 | 58 | // Then 59 | CollectionAssert.AreEqual(expectedKey, actualKey); 60 | } 61 | 62 | [TestMethod] 63 | public void TestEDC16C39KeySeedUsingByteArray() 64 | { 65 | // Given 66 | //EDC16C39 67 | // seed 6808 [0 high][1 low] 68 | // key 405F [0 high][1 low] 69 | byte[] seed = { 0x68, 0x08 }; 70 | byte[] expectedKey = { 0x40, 0x5F }; 71 | 72 | // When 73 | byte[] actualKey = SeedKeyGM.CalculateKey(ECU.EDC16C39, seed); 74 | 75 | // Then 76 | CollectionAssert.AreEqual(expectedKey, actualKey); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /TrionicCANLibTest/TrionicCANLibTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 7 | 8 | 2.0 9 | {BCF4ED01-FD79-4FC3-926A-906123E4E9B7} 10 | Library 11 | Properties 12 | TrionicCANLibTest 13 | TrionicCANLibTest 14 | v4.0 15 | 512 16 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | true 37 | bin\x86\Debug\ 38 | DEBUG;TRACE 39 | full 40 | x86 41 | bin\Debug\TrionicCANLibTest.dll.CodeAnalysisLog.xml 42 | true 43 | GlobalSuppressions.cs 44 | prompt 45 | MinimumRecommendedRules.ruleset 46 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets 47 | true 48 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules 49 | true 50 | 51 | 52 | bin\x86\Release\ 53 | TRACE 54 | true 55 | pdbonly 56 | x86 57 | bin\Release\TrionicCANLibTest.dll.CodeAnalysisLog.xml 58 | true 59 | GlobalSuppressions.cs 60 | prompt 61 | MinimumRecommendedRules.ruleset 62 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets 63 | true 64 | ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules 65 | true 66 | 67 | 68 | 69 | 70 | 71 | 3.5 72 | 73 | 74 | 75 | 76 | False 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | {3FE690B8-7A3B-425E-913C-BFF7A55F7BC4} 86 | TrionicCANLib 87 | 88 | 89 | 90 | 97 | -------------------------------------------------------------------------------- /TrionicCanFlasher.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 11.00 2 | # Visual Studio 2010 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TrionicCANFlasher", "TrionicCANFlasher\TrionicCANFlasher.csproj", "{AD7871BE-0280-47D4-9492-2181BB1C789B}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TrionicCANLib", "TrionicCANLib\TrionicCANLib.csproj", "{3FE690B8-7A3B-425E-913C-BFF7A55F7BC4}" 6 | EndProject 7 | Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "SetupCANFlasher", "SetupCANFlasher\SetupCANFlasher.wixproj", "{3D666E41-0263-4EFC-9B80-743CCE5494D6}" 8 | EndProject 9 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TrionicCANLibTest", "TrionicCANLibTest\TrionicCANLibTest.csproj", "{BCF4ED01-FD79-4FC3-926A-906123E4E9B7}" 10 | EndProject 11 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{61E3A862-4BC0-4BE7-804E-C22562EE9B72}" 12 | ProjectSection(SolutionItems) = preProject 13 | Local.testsettings = Local.testsettings 14 | TraceAndTestImpact.testsettings = TraceAndTestImpact.testsettings 15 | TrionicCanFlasher.vsmdi = TrionicCanFlasher.vsmdi 16 | EndProjectSection 17 | EndProject 18 | Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "SetupCANFlash", "SetupCANFlash\SetupCANFlash.vdproj", "{C5FB4725-76EA-4C2A-A6AA-1BD3D5BFE04A}" 19 | EndProject 20 | Global 21 | GlobalSection(TestCaseManagementSettings) = postSolution 22 | CategoryFile = TrionicCanFlasher.vsmdi 23 | EndGlobalSection 24 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 25 | Debug|Any CPU = Debug|Any CPU 26 | Debug|x86 = Debug|x86 27 | Release|Any CPU = Release|Any CPU 28 | Release|x86 = Release|x86 29 | EndGlobalSection 30 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 31 | {AD7871BE-0280-47D4-9492-2181BB1C789B}.Debug|Any CPU.ActiveCfg = Debug|x86 32 | {AD7871BE-0280-47D4-9492-2181BB1C789B}.Debug|Any CPU.Build.0 = Debug|x86 33 | {AD7871BE-0280-47D4-9492-2181BB1C789B}.Debug|x86.ActiveCfg = Debug|x86 34 | {AD7871BE-0280-47D4-9492-2181BB1C789B}.Debug|x86.Build.0 = Debug|x86 35 | {AD7871BE-0280-47D4-9492-2181BB1C789B}.Release|Any CPU.ActiveCfg = Release|x86 36 | {AD7871BE-0280-47D4-9492-2181BB1C789B}.Release|Any CPU.Build.0 = Release|x86 37 | {AD7871BE-0280-47D4-9492-2181BB1C789B}.Release|x86.ActiveCfg = Release|x86 38 | {AD7871BE-0280-47D4-9492-2181BB1C789B}.Release|x86.Build.0 = Release|x86 39 | {3FE690B8-7A3B-425E-913C-BFF7A55F7BC4}.Debug|Any CPU.ActiveCfg = Debug|x86 40 | {3FE690B8-7A3B-425E-913C-BFF7A55F7BC4}.Debug|Any CPU.Build.0 = Debug|x86 41 | {3FE690B8-7A3B-425E-913C-BFF7A55F7BC4}.Debug|x86.ActiveCfg = Debug|x86 42 | {3FE690B8-7A3B-425E-913C-BFF7A55F7BC4}.Debug|x86.Build.0 = Debug|x86 43 | {3FE690B8-7A3B-425E-913C-BFF7A55F7BC4}.Release|Any CPU.ActiveCfg = Release|x86 44 | {3FE690B8-7A3B-425E-913C-BFF7A55F7BC4}.Release|Any CPU.Build.0 = Release|x86 45 | {3FE690B8-7A3B-425E-913C-BFF7A55F7BC4}.Release|x86.ActiveCfg = Release|x86 46 | {3FE690B8-7A3B-425E-913C-BFF7A55F7BC4}.Release|x86.Build.0 = Release|x86 47 | {3D666E41-0263-4EFC-9B80-743CCE5494D6}.Debug|Any CPU.ActiveCfg = Debug|x86 48 | {3D666E41-0263-4EFC-9B80-743CCE5494D6}.Debug|x86.ActiveCfg = Debug|x86 49 | {3D666E41-0263-4EFC-9B80-743CCE5494D6}.Release|Any CPU.ActiveCfg = Release|x86 50 | {3D666E41-0263-4EFC-9B80-743CCE5494D6}.Release|x86.ActiveCfg = Release|x86 51 | {BCF4ED01-FD79-4FC3-926A-906123E4E9B7}.Debug|Any CPU.ActiveCfg = Debug|x86 52 | {BCF4ED01-FD79-4FC3-926A-906123E4E9B7}.Debug|Any CPU.Build.0 = Debug|x86 53 | {BCF4ED01-FD79-4FC3-926A-906123E4E9B7}.Debug|x86.ActiveCfg = Debug|x86 54 | {BCF4ED01-FD79-4FC3-926A-906123E4E9B7}.Release|Any CPU.ActiveCfg = Release|Any CPU 55 | {BCF4ED01-FD79-4FC3-926A-906123E4E9B7}.Release|Any CPU.Build.0 = Release|Any CPU 56 | {BCF4ED01-FD79-4FC3-926A-906123E4E9B7}.Release|x86.ActiveCfg = Release|Any CPU 57 | {C5FB4725-76EA-4C2A-A6AA-1BD3D5BFE04A}.Debug|Any CPU.ActiveCfg = Debug 58 | {C5FB4725-76EA-4C2A-A6AA-1BD3D5BFE04A}.Debug|Any CPU.Build.0 = Debug 59 | {C5FB4725-76EA-4C2A-A6AA-1BD3D5BFE04A}.Debug|x86.ActiveCfg = Debug 60 | {C5FB4725-76EA-4C2A-A6AA-1BD3D5BFE04A}.Debug|x86.Build.0 = Debug 61 | {C5FB4725-76EA-4C2A-A6AA-1BD3D5BFE04A}.Release|Any CPU.ActiveCfg = Release 62 | {C5FB4725-76EA-4C2A-A6AA-1BD3D5BFE04A}.Release|Any CPU.Build.0 = Release 63 | {C5FB4725-76EA-4C2A-A6AA-1BD3D5BFE04A}.Release|x86.ActiveCfg = Release 64 | {C5FB4725-76EA-4C2A-A6AA-1BD3D5BFE04A}.Release|x86.Build.0 = Release 65 | EndGlobalSection 66 | GlobalSection(SolutionProperties) = preSolution 67 | HideSolutionNode = FALSE 68 | EndGlobalSection 69 | EndGlobal 70 | -------------------------------------------------------------------------------- /TrionicCanFlasher.sln.switchReferences.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /TrionicCanFlasher.vsmdi: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /packages/repositories.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /releaseTrionicCanFlash.bat: -------------------------------------------------------------------------------- 1 | call SetupCANFlash\version.bat 2 | devenv TrionicCanFlasher.sln /Rebuild Release /project SetupCANFlash 3 | 4 | pushd SetupCANFlash\Release\ 5 | "C:\md5sum.exe" TrionicCANFlash.msi >> TrionicCANFlash.md5 6 | "C:\Program Files\7-Zip\7z.exe" a -tzip TrionicCANFlash.zip TrionicCANFlash.* setup.exe 7 | popd 8 | 9 | mkdir z:\TrionicCANFlasher\%SetupCANFlash.version% 10 | xcopy SetupCANFlash\version.bat z:\TrionicCANFlasher\%SetupCANFlash.version%\ 11 | xcopy SetupCANFlash\Release\TrionicCANFlash.msi z:\TrionicCANFlasher\%SetupCANFlash.version%\ 12 | xcopy SetupCANFlash\Release\TrionicCANFlash.md5 z:\TrionicCANFlasher\%SetupCANFlash.version%\ 13 | xcopy SetupCANFlash\Release\TrionicCANFlash.zip z:\TrionicCANFlasher\%SetupCANFlash.version%\ 14 | xcopy SetupCANFlash\Release\setup.exe z:\TrionicCANFlasher\%SetupCANFlash.version%\ 15 | 16 | 17 | echo ^ > z:\TrionicCANFlasher\version.xml 18 | echo ^ >> z:\TrionicCANFlasher\version.xml 19 | 20 | git tag SetupCANFlash_v%SetupCANFlash.version% 21 | git tag TrionicCanFlasher_v%TrionicCANFlasher.version% 22 | git tag TrionicCANLib_v%TrionicCANLib.version% 23 | 24 | git push --tags 25 | 26 | gh release create TrionicCanFlasher_v%TrionicCANFlasher.version% --generate-notes --verify-tag 27 | gh release upload TrionicCanFlasher_v%TrionicCANFlasher.version% SetupCANFlash\Release\TrionicCANFlash.zip 28 | gh release upload TrionicCanFlasher_v%TrionicCANFlasher.version% SetupCANFlash\Release\TrionicCANFlash.msi 29 | gh release upload TrionicCanFlasher_v%TrionicCANFlasher.version% SetupCANFlash\Release\TrionicCANFlash.md5 -------------------------------------------------------------------------------- /releaseTrionicCanFlasher.bat: -------------------------------------------------------------------------------- 1 | call SetupCANFlasher\version.bat 2 | devenv TrionicCanFlasher.sln /Rebuild Release /project SetupCANFlasher 3 | 4 | pushd SetupCANFlasher\bin\Release\ 5 | "C:\md5sum.exe" TrionicCANFlasher.msi >> TrionicCANFlasher.md5 6 | popd 7 | 8 | mkdir z:\TrionicCANFlasher\%SetupCANFlasher.version% 9 | xcopy SetupCANFlasher\version.bat z:\TrionicCANFlasher\%SetupCANFlasher.version%\ 10 | xcopy SetupCANFlasher\bin\Release\TrionicCANFlasher.msi z:\TrionicCANFlasher\%SetupCANFlasher.version%\ 11 | xcopy SetupCANFlasher\bin\Release\TrionicCANFlasher.md5 z:\TrionicCANFlasher\%SetupCANFlasher.version%\ 12 | 13 | echo ^ > z:\TrionicCANFlasher\version.xml 14 | echo ^ >> z:\TrionicCANFlasher\version.xml 15 | 16 | git tag SetupCANFlasher_v%SetupCANFlasher.version% 17 | git tag TrionicCanFlasher_v%TrionicCANFlasher.version% 18 | git tag TrionicCANLib_v%TrionicCANLib.version% --------------------------------------------------------------------------------