diff --git a/Caesar/Caesar/BitUtility.cs b/Caesar/Caesar/BitUtility.cs
index c46290b..71f1fd1 100644
--- a/Caesar/Caesar/BitUtility.cs
+++ b/Caesar/Caesar/BitUtility.cs
@@ -1,4 +1,5 @@
using System;
+using System.Runtime.InteropServices;
using System.Text;
namespace Caesar
@@ -80,6 +81,28 @@ public static byte[] PadBytes(byte[] inData, int finalSize)
return result;
}
+ [StructLayout(LayoutKind.Explicit)]
+ struct UIntFloat
+ {
+ [FieldOffset(0)]
+ public float FloatValue;
+
+ [FieldOffset(0)]
+ public uint IntValue;
+ }
+
+ ///
+ /// Directly converts an in-memory representation of an uint to a float.
+ ///
+ ///
+ ///
+ public static float ToFloat(uint value)
+ {
+ UIntFloat intermediate = new UIntFloat();
+ intermediate.IntValue = value;
+ return intermediate.FloatValue;
+ }
+
// Caesar specific
diff --git a/Caesar/Caesar/DiagPresentation.cs b/Caesar/Caesar/DiagPresentation.cs
index 6afa3da..2ea490d 100644
--- a/Caesar/Caesar/DiagPresentation.cs
+++ b/Caesar/Caesar/DiagPresentation.cs
@@ -35,10 +35,10 @@ public class DiagPresentation
public int Unk18;
public int Unk19;
public int TypeLength_1A;
- public int Unk1b;
+ public int InternalDataType; // discovered by @prj : #37
public int Type_1C;
public int Unk1d;
- public int EnumType_1E;
+ public int SignBit; // discovered by @prj : #37
public int Unk1F;
public int Unk20;
@@ -126,11 +126,11 @@ public DiagPresentation(BinaryReader reader, long baseAddress, int presentations
Unk19 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
TypeLength_1A = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
- Unk1b = CaesarReader.ReadBitflagInt8(ref bitflags, reader, -1);
+ InternalDataType = CaesarReader.ReadBitflagInt8(ref bitflags, reader, -1);
Type_1C = CaesarReader.ReadBitflagInt8(ref bitflags, reader, -1);
Unk1d = CaesarReader.ReadBitflagInt8(ref bitflags, reader);
- EnumType_1E = CaesarReader.ReadBitflagInt8(ref bitflags, reader);
+ SignBit = CaesarReader.ReadBitflagInt8(ref bitflags, reader);
Unk1F = CaesarReader.ReadBitflagInt8(ref bitflags, reader);
Unk20 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
@@ -169,7 +169,7 @@ public string InterpretData(byte[] inBytes, DiagPreparation inPreparation, bool
string descriptionPrefix = describe ? $"{DescriptionString}: " : "";
byte[] workingBytes = inBytes.Skip(inPreparation.BitPosition / 8).Take(TypeLength_1A).ToArray();
- bool isEnumType = (EnumType_1E == 0) && ((Type_1C == 1) || (ScaleCountMaybe > 1));
+ bool isEnumType = (SignBit == 0) && ((Type_1C == 1) || (ScaleCountMaybe > 1));
// hack: sometimes hybrid types (regularly parsed as an scaled value if within bounds) are misinterpreted as pure enums
// this is a temporary fix for kilometerstand until there's a better way to ascertain its type
@@ -212,11 +212,10 @@ public string InterpretData(byte[] inBytes, DiagPreparation inPreparation, bool
string humanReadableType = $"UnhandledType:{dataType}";
string parsedValue = BitUtility.BytesToHex(workingBytes, true);
- if ((dataType == 6 || (dataType == 20)))
+ if (dataType == 20)
{
// parse as a regular int (BE)
-
- for (int i = 0; i < workingBytes.Length; i++)
+ for (int i = 0; i < workingBytes.Length; i++)
{
rawIntInterpretation <<= 8;
rawIntInterpretation |= workingBytes[i];
@@ -225,7 +224,7 @@ public string InterpretData(byte[] inBytes, DiagPreparation inPreparation, bool
humanReadableType = "IntegerType";
parsedValue = rawIntInterpretation.ToString();
- if (dataType == 20)
+ if (dataType == 20)
{
humanReadableType = "ScaledType";
@@ -242,6 +241,31 @@ public string InterpretData(byte[] inBytes, DiagPreparation inPreparation, bool
parsedValue = valueToScale.ToString("0.000000");
}
}
+ else if (dataType == 6)
+ {
+ // type 6 refers to either internal presentation types 8 (ieee754 float) or 5 (unsigned int?)
+ // these values are tagged with an exclamation [!] i (jglim) am not sure if they will work correctly yet
+ // specifically, i am not sure if the big endian float parsing is done correctly
+ uint rawUIntInterpretation = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ rawUIntInterpretation <<= 8;
+ rawUIntInterpretation |= workingBytes[i];
+ }
+
+ if (InternalDataType == 8)
+ {
+ // interpret as big-endian float, https://github.com/jglim/CaesarSuite/issues/37
+ parsedValue = BitUtility.ToFloat(rawUIntInterpretation).ToString("");
+ humanReadableType = "Float [!]";
+ }
+ else if (InternalDataType == 5)
+ {
+ // haven't seen this one around, will parse as a regular int (BE) for now
+ humanReadableType = "UnsignedIntegerType [!]";
+ parsedValue = rawUIntInterpretation.ToString();
+ }
+ }
else if (dataType == 18)
{
humanReadableType = "HexdumpType";
@@ -315,7 +339,6 @@ public string InterpretData(byte[] inBytes, DiagPreparation inPreparation, bool
public int GetDataType()
{
// see DIDiagServiceRealPresType
-
int result = -1;
if (Unk14 != -1)
{
@@ -346,21 +369,21 @@ public int GetDataType()
{
return 18; // hexdump raw
}
- if (Unk1b != -1)
+ if (InternalDataType != -1)
{
- if (Unk1b == 6)
+ if (InternalDataType == 6)
{
return 17; // ascii dump
}
- else if (Unk1b == 7)
+ else if (InternalDataType == 7)
{
return 22; // ?? haven't seen this one around
}
- else if (Unk1b == 8)
+ else if (InternalDataType == 8)
{
- result = 6; // integer
+ result = 6; // IEEE754 float, discovered by @prj in https://github.com/jglim/CaesarSuite/issues/37
}
- else if (Unk1b == 5)
+ else if (InternalDataType == 5)
{
// UNSIGNED integer (i haven't seen a const for uint around, sticking it into a regular int for now)
// this will be an issue for 32-bit+ uints
@@ -375,7 +398,7 @@ public int GetDataType()
Console.WriteLine("typelength and type must be valid");
// might be good to throw an exception here
}
- if ((EnumType_1E == 1) || (EnumType_1E == 2))
+ if ((SignBit == 1) || (SignBit == 2))
{
result = 5; // ?? haven't seen this one around
}
@@ -424,10 +447,10 @@ public void PrintDebug()
Console.WriteLine($"{nameof(Unk18)}: {Unk18}");
Console.WriteLine($"{nameof(Unk19)}: {Unk19}");
- Console.WriteLine($"{nameof(Unk1b)}: {Unk1b}");
+ Console.WriteLine($"{nameof(InternalDataType)}: {InternalDataType}");
Console.WriteLine($"{nameof(Unk1d)}: {Unk1d}");
- Console.WriteLine($"{nameof(EnumType_1E)}: {EnumType_1E}");
+ Console.WriteLine($"{nameof(SignBit)}: {SignBit}");
Console.WriteLine($"{nameof(Unk1F)}: {Unk1F}");
Console.WriteLine($"{nameof(Unk20)}: {Unk20}");
@@ -481,9 +504,9 @@ public string CopyMinDebug()
sb.Append($" {nameof(Unk17)}: {Unk17}");
sb.Append($" {nameof(Unk18)}: {Unk18}");
sb.Append($" {nameof(Unk19)}: {Unk19}");
- sb.Append($" {nameof(Unk1b)}: {Unk1b}");
+ sb.Append($" {nameof(InternalDataType)}: {InternalDataType}");
sb.Append($" {nameof(Unk1d)}: {Unk1d}");
- sb.Append($" {nameof(EnumType_1E)}: {EnumType_1E}");
+ sb.Append($" {nameof(SignBit)}: {SignBit}");
sb.Append($" {nameof(Unk1F)}: {Unk1F}");
sb.Append($" {nameof(Unk20)}: {Unk20}");
sb.Append($" {nameof(TypeLengthBytesMaybe_21)}: {TypeLengthBytesMaybe_21}");
diff --git a/Caesar/Diogenes/Forms/AboutForm.Designer.cs b/Caesar/Diogenes/Forms/AboutForm.Designer.cs
index f2e4ec5..21ec7c4 100644
--- a/Caesar/Diogenes/Forms/AboutForm.Designer.cs
+++ b/Caesar/Diogenes/Forms/AboutForm.Designer.cs
@@ -87,7 +87,7 @@ private void InitializeComponent()
//
this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnClose.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.btnClose.Location = new System.Drawing.Point(493, 325);
+ this.btnClose.Location = new System.Drawing.Point(493, 361);
this.btnClose.Name = "btnClose";
this.btnClose.Size = new System.Drawing.Size(75, 23);
this.btnClose.TabIndex = 4;
@@ -97,6 +97,9 @@ private void InitializeComponent()
//
// lbCredits
//
+ this.lbCredits.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
this.lbCredits.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40)))));
this.lbCredits.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.lbCredits.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
@@ -105,16 +108,18 @@ private void InitializeComponent()
this.lbCredits.ItemHeight = 17;
this.lbCredits.Items.AddRange(new object[] {
"Made possible with the help and support of these projects and individuals:",
+ "",
"Mark James : http://www.famfamfam.com/about/",
"Brian Humlicek : https://github.com/BrianHumlicek/J2534-Sharp/",
"s30shiro (しーちゃん) : http://blog.livedoor.jp/s30shiro/",
"@VladLupashevskyi (Vladyslav Lupashevskyi)",
"@N0cynym (@N0cynym)",
"@Feezex (Сергей)",
- "@rnd-ash (Ashcon Mohseninia)"});
+ "@rnd-ash (Ashcon Mohseninia)",
+ "@prj (@prj)"});
this.lbCredits.Location = new System.Drawing.Point(20, 180);
this.lbCredits.Name = "lbCredits";
- this.lbCredits.Size = new System.Drawing.Size(548, 136);
+ this.lbCredits.Size = new System.Drawing.Size(548, 170);
this.lbCredits.TabIndex = 5;
//
// AboutForm
@@ -122,7 +127,7 @@ private void InitializeComponent()
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40)))));
- this.ClientSize = new System.Drawing.Size(580, 360);
+ this.ClientSize = new System.Drawing.Size(580, 396);
this.Controls.Add(this.lbCredits);
this.Controls.Add(this.btnClose);
this.Controls.Add(this.linkLabel1);
diff --git a/Caesar/Diogenes/Forms/MainForm.cs b/Caesar/Diogenes/Forms/MainForm.cs
index 6ba667b..c5c23fa 100644
--- a/Caesar/Diogenes/Forms/MainForm.cs
+++ b/Caesar/Diogenes/Forms/MainForm.cs
@@ -1130,16 +1130,13 @@ private void genericDebugToolStripMenuItem_Click(object sender, EventArgs e)
{
foreach (ECU ecu in container.CaesarECUs)
{
- foreach (DTC dtc in ecu.GlobalDTCs)
+ foreach (DiagPresentation pres in ecu.GlobalPresentations)
{
- byte[] dtcQualBytes = BitUtility.BytesFromHex(dtc.Qualifier.Substring(1));
- int dtcInt = (dtcQualBytes[0] << 16) | (dtcQualBytes[1] << 8) | dtcQualBytes[2];
- long remainder = dtcInt & 0xFFC00000;
- if (remainder > 0)
+ Console.WriteLine($"Pres : {pres.Qualifier} : {pres.GetDataType()}");
+ if (pres.InternalDataType == 8)
{
- throw new NotImplementedException("fail");
+ throw new NotImplementedException("found a iee754 float!");
}
- Console.WriteLine($"Q: {dtc.Qualifier} {dtcInt:X8} : {dtc.Description}");
}
}
}
@@ -1168,7 +1165,7 @@ private void genericDebugToolStripMenuItem_Click(object sender, EventArgs e)
if (scale.EnumUpBound >= 0)
{
string presOut = pres.InterpretData(BitUtility.BytesFromHex("0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B"), prep);
- Console.WriteLine($"{ds.Qualifier} : {prep.Qualifier} @ {presOut} = {pres.Unk1b}, {pres.EnumMaxValue}");
+ Console.WriteLine($"{ds.Qualifier} : {prep.Qualifier} @ {presOut} = {pres.InternalDataType}, {pres.EnumMaxValue}");
}
}
if (pres.Qualifier == "PRES_ZIELGANG")