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