I can second Ben idea of String handling cause each and every driver now
is forced to have a helper just to read/write variable length text. I
believe that almost every driver have it.
One suggestion I have here is to *make* encoding an expression too. This
is due to fact that for example some BACnet devices can be deployed in
different countries which have different character set than UTF-8. This
is really an runtime parameter with UTF-8 as an default.
One thing Chris showed to me earlier when I worked with ADS strings, you
can use implicit field to automatically prepend size of string value
when writing to the wire:
[type 'PascalString'
[implicit int 32 'stringLength' 'COUNT(stringValue)']
[optional string 'stringLength * 8' 'UTF-8' 'stringValue'
'stringLength >= 0']
]
Best,
Łukasz
On 14.02.2021 12:47, Ben Hutcheson wrote:
> Hi,
>
> While working on the OPC UA native driver I have come across a couple of
> cases where it was beneficial to modify mspec. I'd like to bring these up
> for discussion.
>
> - OPC UA makes heavy use of pascal strings. This is where the length of the
> string precedes the string. Currently when specifying a string in mspec we
> have two options. If the string is a predefined length just use the length
> in bits. If it is a variable length then we would need to call a manual
> function such as what the S7 mspec does.
>
> ['IEC61131_STRING' STRING
> [manual string 'UTF-8' 'value'
> 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.parseS7String",
> io, stringLength, _type.encoding)'
> 'STATIC_CALL("org.apache.plc4x.java.s7.utils.StaticHelper.serializeS7String",
> io, _value, stringLength, _type.encoding)' '_value.length + 2']
> ]
>
> My proposal would be to allow the length of the string length to be an
> inline mspec function.
>
> [type 'PascalString'
> [simple int 32 'stringLength']
> [optional string 'stringLength * 8' 'UTF-8' 'stringValue'
> 'stringLength >= 0']
> ]
>
> This allows us to specify a variable length string using the preceding
> string length. We could also expand this to have a variable length field
> for any data type, however I'll leave that out of this scope.
>
>
> - We have a field type in mspec to be able to specify a value is an
> enumerated type. However if we then need to make that field a discriminator
> for a typeswitch we can't.
>
> discriminatedType 'ExpandedNodeId'
> [simple bit 'namespaceURISpecified']
> [simple bit 'serverIndexSpecified']
> [discriminator NodeIdType 'nodeIdType']
> [typeSwitch 'nodeIdType'
> ['NodeIdType.TwoByte' ExpandedNodeIdTwoByte
> [simple TwoByteNodeId 'id']
> ]
> ['NodeIdType.FourByte' ExpandedNodeIdFourByte
> [simple FourByteNodeId 'id']
> ]
> ['NodeIdType.Numeric' ExpandedNodeIdNumeric
> [simple NumericNodeId 'id']
> ]
> ['NodeIdType.String' ExpandedNodeIdString
> [simple StringNodeId 'id']
> ]
> ['NodeIdType.Guid' ExpandedNodeIdGuid
> [simple GuidNodeId 'id']
> ]
> ['NodeIdType.nodeIdTypeByteString' ExpandedNodeIdByteString
> [simple ByteStringNodeId 'id']
> ]
> ]
> [optional PascalString 'namespaceURI' 'namespaceURISpecified']
> [optional uint 32 'serverIndex' 'serverIndexSpecified']
> ]
>
> Shown above is my proposal where the nodeIdType is an enum and is used as
> the typeSwitch parameter. This allows us to retain the use of an enum when
> we also need to use it as a discriminator.
>
> Looking forward to hearing your opinion.
>
> Ben
>