robincornelius / libedssharp

A CanOpen EDS editor and library in C# with CanOpenNode export for Object Dictionary
GNU General Public License v3.0
231 stars 135 forks source link

OCTET_STRING default values #174

Open aquaid3 opened 5 years ago

aquaid3 commented 5 years ago

Octet strings with default values entered in hex that include letters (e.g. "0A 0B FF") cause the EDSEditor application to crash when outputting the .c/.h files.

Alternatively, if you enter the default value as base-10 byte values (e.g. "10 11 255"), the .c/.h files seem to be output correctly. However, when exporting the EDS file, it will have an incorrect default value (e.g. DefaultValue=1011255).

I haven't looked closely at the code, but it seems like everything would work if the EDSEditor interpreted the 'Default value' field byte values as hex instead of base-10 for OCTET_STRINGs.

aquaid3 commented 4 years ago

Looking into things a bit more, this issue appears to be a non-conformance with CiA306 v1.3.0, sec 4.3:

Octett strings and raw data of domains are stored as sequence of hexadecimal bytes (without leading 0x). Bytes with a high nibble of 0 shall be stored with the leading 0. If the data does not fit within one line, it may be stored in a separate file (refer to chapter 5.3.1). Example for octett string: DemoSeq=01a1053c45aabbccddeeff

If you use this example value 01a1053c45aabbccddeeff for the "Default value" field of an OCTET_STRING object dictionary entry, EDSEditor.exe (git hash 2e53bbcb, running on linux) outputs an .eds file correctly. However, it crashes when you attempt to "Export CanOpenNode c/h":

System.FormatException: Additional unparsable characters are at the end of the string. at System.ParseNumbers.StringToInt (System.String value, System.Int32 fromBase, System.Int32 flags, System.Int32* parsePos) [0x001af] in <8f2c484307284b51944a1a13a14c0266>:0 at System.ParseNumbers.StringToInt (System.String value, System.Int32 fromBase, System.Int32 flags) [0x00000] in <8f2c484307284b51944a1a13a14c0266>:0 at System.Convert.ToByte (System.String value, System.Int32 fromBase) [0x0002e] in <8f2c484307284b51944a1a13a14c0266>:0 at libEDSsharp.CanOpenNodeExporter.formatvaluewithdatatype (System.String defaultvalue, libEDSsharp.DataType dt) [0x0034b] in <34cda97259c9439a8dccffe0165ecaf0>:0 at libEDSsharp.CanOpenNodeExporter.formatvaluewithdatatype (System.String defaultvalue, libEDSsharp.DataType dt) [0x002b6] in <34cda97259c9439a8dccffe0165ecaf0>:0 at libEDSsharp.CanOpenNodeExporter.export_OD_def_array (System.String location) [0x00094] in <34cda97259c9439a8dccffe0165ecaf0>:0 at libEDSsharp.CanOpenNodeExporter.export_c (System.String filename) [0x000f5] in <34cda97259c9439a8dccffe0165ecaf0>:0 at libEDSsharp.CanOpenNodeExporter.export (System.String folderpath, System.String filename, System.String gitVersion, libEDSsharp.EDSsharp eds) [0x0003e] in <34cda97259c9439a8dccffe0165ecaf0>:0 at ODEditor.ODEditor_MainForm.exportCanOpenNodeToolStripMenuItem_Click (System.Object sender, System.EventArgs e) [0x000ae] in :0 at System.Windows.Forms.ToolStripItem.OnClick (System.EventArgs e) [0x0001c] in :0 at System.Windows.Forms.ToolStripMenuItem.OnClick (System.EventArgs e) [0x000a5] in :0 at System.Windows.Forms.ToolStripMenuItem.HandleClick (System.Int32 mouse_clicks, System.EventArgs e) [0x00000] in :0 at System.Windows.Forms.ToolStripItem.FireEvent (System.EventArgs e, System.Windows.Forms.ToolStripItemEventType met) [0x00061] in :0 at (wrapper remoting-invoke-with-check) System.Windows.Forms.ToolStripItem:FireEvent (System.EventArgs,System.Windows.Forms.ToolStripItemEventType) at System.Windows.Forms.ToolStrip.OnMouseUp (System.Windows.Forms.MouseEventArgs mea) [0x00057] in :0 at System.Windows.Forms.ToolStripDropDown.OnMouseUp (System.Windows.Forms.MouseEventArgs mea) [0x00000] in :0 at System.Windows.Forms.Control.WmLButtonUp (System.Windows.Forms.Message& m) [0x0007e] in :0 at System.Windows.Forms.Control.WndProc (System.Windows.Forms.Message& m) [0x0016f] in :0 at System.Windows.Forms.ScrollableControl.WndProc (System.Windows.Forms.Message& m) [0x00000] in :0 at System.Windows.Forms.ToolStrip.WndProc (System.Windows.Forms.Message& m) [0x00000] in :0 at System.Windows.Forms.ToolStripDropDown.WndProc (System.Windows.Forms.Message& m) [0x0001a] in :0 at System.Windows.Forms.Control+ControlWindowTarget.OnMessage (System.Windows.Forms.Message& m) [0x00000] in :0 at System.Windows.Forms.Control+ControlNativeWindow.WndProc (System.Windows.Forms.Message& m) [0x0000b] in :0 at System.Windows.Forms.NativeWindow.WndProc (System.IntPtr hWnd, System.Windows.Forms.Msg msg, System.IntPtr wParam, System.IntPtr lParam) [0x0008e] in :0

Assuming you only want to support the CiA306 format entries (and not the old "00 00 00" format entries), here's a patch that seems to work (I'm using libedssharp in a subtree, so, you probably need to adjust the file paths):

diff --git a/extras/libedssharp/libEDSsharp/CanOpenNodeExporter.cs b/extras/libedssharp/libEDSsharp/CanOpenNodeExporter.cs
index aef6239..c6b56a5 100644
--- a/extras/libedssharp/libEDSsharp/CanOpenNodeExporter.cs
+++ b/extras/libedssharp/libEDSsharp/CanOpenNodeExporter.cs
@@ -1134,13 +1134,19 @@ const CO_OD_entry_t CO_OD[");

                 case DataType.OCTET_STRING:
                     {
-                        string[] bits = defaultvalue.Split(' ');
+                        int valuelen = defaultvalue.Length;
+                        if (valuelen % 2 != 0)
+                        {
+                            Console.Error.Write("Length of octet_string {0} must be even (use leading zero if necessary)\n", defaultvalue);
+                        }
                         string octet = "{";
-                        foreach (string s in bits)
+                        for (int i=0; i<valuelen; i+=2)
                         {
-                            octet += formatvaluewithdatatype(s, DataType.UNSIGNED8);
+                            octet += formatvaluewithdatatype("0x"+
+                                defaultvalue.Substring(i, 2),
+                                DataType.UNSIGNED8);

-                            if (!object.ReferenceEquals(s, bits.Last()))
+                            if (i+2 < valuelen)
                             {
                                 octet += ", ";
                             }
robincornelius commented 4 years ago

Thanks i'll try to take a look a some point soon. been a bit busy with other projects but hoping to get back to this soon.

On Thu, 23 Jan 2020 at 21:53, aquaid3 notifications@github.com wrote:

Looking into things a bit more, this issue appears to be a non-conformance with CiA306 v1.3.0, sec 4.3:

Octett strings and raw data of domains are stored as sequence of hexadecimal bytes (without leading 0x). Bytes with a high nibble of 0 shall be stored with the leading 0. If the data does not fit within one line, it may be stored in a separate file (refer to chapter 5.3.1). Example for octett string: DemoSeq=01a1053c45aabbccddeeff

If you use this example value 01a1053c45aabbccddeeff for the "Default value" field of an OCTET_STRING object dictionary entry, EDSEditor.exe (git hash 2e53bbc https://github.com/robincornelius/libedssharp/commit/2e53bbcb7c012805f02c7b9336efc67c743a95b1, running on linux) outputs an .eds file correctly. However, it crashes when you attempt to "Export CanOpenNode c/h":

System.FormatException: Additional unparsable characters are at the end of the string. at System.ParseNumbers.StringToInt (System.String value, System.Int32 fromBase, System.Int32 flags, System.Int32* parsePos) [0x001af] in

<8f2c484307284b51944a1a13a14c0266>:0 at System.ParseNumbers.StringToInt (System.String value, System.Int32 fromBase, System.Int32 flags) [0x00000] in <8f2c484307284b51944a1a13a14c0266>:0 at System.Convert.ToByte (System.String value, System.Int32 fromBase) [0x0002e] in <8f2c484307284b51944a1a13a14c0266>:0 at libEDSsharp.CanOpenNodeExporter.formatvaluewithdatatype (System.String defaultvalue, libEDSsharp.DataType dt) [0x0034b] in <34cda97259c9439a8dccffe0165ecaf0>:0 at libEDSsharp.CanOpenNodeExporter.formatvaluewithdatatype (System.String defaultvalue, libEDSsharp.DataType dt) [0x002b6] in <34cda97259c9439a8dccffe0165ecaf0>:0 at libEDSsharp.CanOpenNodeExporter.export_OD_def_array (System.String location) [0x00094] in <34cda97259c9439a8dccffe0165ecaf0>:0 at libEDSsharp.CanOpenNodeExporter.export_c (System.String filename) [0x000f5] in <34cda97259c9439a8dccffe0165ecaf0>:0 at libEDSsharp.CanOpenNodeExporter.export (System.String folderpath, System.String filename, System.String gitVersion, libEDSsharp.EDSsharp eds) [0x0003e] in <34cda97259c9439a8dccffe0165ecaf0>:0 at ODEditor.ODEditor_MainForm.exportCanOpenNodeToolStripMenuItem_Click (System.Object sender, System.EventArgs e) [0x000ae] in :0 at System.Windows.Forms.ToolStripItem.OnClick (System.EventArgs e) [0x0001c] in :0 at System.Windows.Forms.ToolStripMenuItem.OnClick (System.EventArgs e) [0x000a5] in :0 at System.Windows.Forms.ToolStripMenuItem.HandleClick (System.Int32 mouse_clicks, System.EventArgs e) [0x00000] in :0 at System.Windows.Forms.ToolStripItem.FireEvent (System.EventArgs e, System.Windows.Forms.ToolStripItemEventType met) [0x00061] in :0 at (wrapper remoting-invoke-with-check) System.Windows.Forms.ToolStripItem:FireEvent (System.EventArgs,System.Windows.Forms.ToolStripItemEventType) at System.Windows.Forms.ToolStrip.OnMouseUp (System.Windows.Forms.MouseEventArgs mea) [0x00057] in :0 at System.Windows.Forms.ToolStripDropDown.OnMouseUp (System.Windows.Forms.MouseEventArgs mea) [0x00000] in :0 at System.Windows.Forms.Control.WmLButtonUp (System.Windows.Forms.Message& m) [0x0007e] in :0 at System.Windows.Forms.Control.WndProc (System.Windows.Forms.Message& m) [0x0016f] in :0 at System.Windows.Forms.ScrollableControl.WndProc (System.Windows.Forms.Message& m) [0x00000] in :0 at System.Windows.Forms.ToolStrip.WndProc (System.Windows.Forms.Message& m) [0x00000] in :0 at System.Windows.Forms.ToolStripDropDown.WndProc (System.Windows.Forms.Message& m) [0x0001a] in :0 at System.Windows.Forms.Control+ControlWindowTarget.OnMessage (System.Windows.Forms.Message& m) [0x00000] in :0 at System.Windows.Forms.Control+ControlNativeWindow.WndProc (System.Windows.Forms.Message& m) [0x0000b] in :0 at System.Windows.Forms.NativeWindow.WndProc (System.IntPtr hWnd, System.Windows.Forms.Msg msg, System.IntPtr wParam, System.IntPtr lParam) [0x0008e] in :0 Assuming you only want to support the CiA306 format entries (and not the old "00 00 00" format entries), here's a patch that seems to work (I'm using libedssharp in a subtree, so, you probably need to adjust the file paths): diff --git a/extras/libedssharp/libEDSsharp/CanOpenNodeExporter.cs b/extras/libedssharp/libEDSsharp/CanOpenNodeExporter.cs index aef6239..c6b56a5 100644 --- a/extras/libedssharp/libEDSsharp/CanOpenNodeExporter.cs +++ b/extras/libedssharp/libEDSsharp/CanOpenNodeExporter.cs @@ -1134,13 +1134,19 @@ const CO_OD_entry_t CO_OD["); case DataType.OCTET_STRING: { - string[] bits = defaultvalue.Split(' '); + int valuelen = defaultvalue.Length; + if (valuelen % 2 != 0) + { + Console.Error.Write("Length of octet_string {0} must be even (use leading zero if necessary)\n", defaultvalue); + } string octet = "{"; - foreach (string s in bits) + for (int i=0; i, or unsubscribe .