2

I'm working on software to configure a device for communication over CANOpen. In CANOpen there's the concept of an Object Dictionary (OD) which is shared between the consumer and the producer. It acts as a contract between communication endpoints.

To customize what we want to visualize in our application we are building a configuration file in XML. One example is commands that can be executed on a device. An example can be that you need to move the arm of a robot up 500mm. I want to then be able to define this command as "Move Arm Z-Axis" and specify a parameter of a specific type with certain constraints (min, max, etc).

The approach I want to take is use a per device xml file where all these steps can be defined. It does however require me to write c# code inside the xml using specific parsing rules such as any code should be between "{{" "}}" brackets or use specific elements (e.g. <SetVariable>).

<?xml version="1.0" encoding="UTF-8"?>
<DeviceConfiguration>
  <Device name="CanOpenDevice1" />
  <ParameterConfiguration>
    <EntreesToExclude>
      <EntryToExclude Index="0x206B" />
      <EntryToExclude Index="0x2050" />
      <EntryToExclude Index="0x20F1" />
      <EntryToExclude Index="0x20F4" />
    </EntreesToExclude>
    <WriteToFlashCommand>
      <WriteCommand Label="Write to Flash" Index="0x3000" SubIndex="0x0F" Value="0x000000FF" />
    </WriteToFlashCommand>
  </ParameterConfiguration>
  <CommandConfiguration>
    <Commands>
      <WriteCommand Label="Connect Request ON" Index="0x20F2" Value="true" DataType="bool" />
      <WriteCommand Label="Connect Request OFF" Index="0x20F2" Value="false" DataType="bool" />
      <WriteCommand Label="Clear Faults" Index="0x2050" SubIndex="0x01" Value="0x66726c63" DataType="uint" />
      <WriteCommand Label="Reboot" Index="0x2050" SubIndex="0x02" Value="0x00747372" DataType="uint" />
      <!-- Executes in sequential order -->
      <CommandInstructionSet Label="Sync RTC">
        <SetVariable Name="now" Value="{{System.Datetime.UtcNow}}" />
        <WriteCommand Index="0x206B" SubIndex="0x05" Value="{{$now.Second}}" DataType="ushort" />
        <WriteCommand Index="0x206B" SubIndex="0x06" Value="{{$now.Minute}}" DataType="ushort" />
        <WriteCommand Index="0x206B" SubIndex="0x07" Value="{{$now.Hour}}" DataType="ushort" />
        <WriteCommand Index="0x206B" SubIndex="0x08" Value="{{$now.Day}}" DataType="ushort" />
        <WriteCommand Index="0x206B" SubIndex="0x09" Value="{{$now.Month}}" DataType="ushort" />
        <WriteCommand Index="0x206B" SubIndex="0x0A" Value="{{$now.Year - 2000}}" DataType="ushort" />
        <WriteCommand Index="0x206B" SubIndex="0x0B" Value="{{System.DateTime.IsLeapYear($now.Year)}}" DataType="ushort" />
        <WriteCommand Index="0x206B" SubIndex="0x0C" Value="{{$now.DayOfWeek}}" DataType="ushort" />
        <WriteCommand Index="0x206B" SubIndex="0x0E" Value="0x12345678" DataType="uint" />
      </CommandInstructionSet>

      <ReadCommand Label="Reboot" Index="0x2050" SubIndex="0x02" DataType="uint" />
    </Commands>
  </CommandConfiguration>
</DeviceConfiguration>

The idea is to use the Roslyn scripting api to execute and evaluate the code after parsing the syntax.

I would like to know your thoughts and if you know of a better approach to this case. One thing I have a problem with is that I have limited ways of preventing malicious code from sneaking in. The code however only runs on the local machine, not in the cloud or on another server so you'll only be messing up your own device.

Peter
  • 14,221
  • 15
  • 70
  • 110
  • 1
    Values in Xml are normally put into innertext and not as an attribute. – jdweng Aug 06 '20 at 10:51
  • Is it correct that it is possible to execute some functionality after reading the XML and before the actual processing? – ASpirin Aug 06 '20 at 11:09
  • 1
    Yes that's the idea @ASpirin. I was thinking to, after the xml is parsed, creating Action or Func instances for some of these, that are invoked whenever a command is executed for instance. Nothing real yet, it's all still in my head only. – Peter Aug 06 '20 at 11:21
  • 1
    than would be easier just define a set of commands. In XML inject a command tag with its name and, maybe, parameters. And execute required function based on the command in XML. So that will be more secure (no strange code), stable (only the functions you defined would be executed) and maintainable (functions could be tested and debugged separately) – ASpirin Aug 06 '20 at 11:27
  • 1
    Thank you for your suggestion, I see what you mean. The thing is we want to do minimal code changes when we need to add another type of device which will then require more hardcoded functions. I do realize we can't make this too complex as debugging this custom parsed code is difficult. I also don't want to need a cheatsheet to learn all the available commands. – Peter Aug 06 '20 at 11:35

0 Answers0