04/09/2019
Where do I find more information on how to parse DataSetFieldFlags? I’m referring to Part 6 and Part 14 and all I could find is the following:
This unfortunately is not enough for me to parse the incoming bytes!
6.2.2.1.4 DataSetFieldFlags
This DataType defines flags for DataSet fields.
The DataSetFieldFlags is formally defined in Table 6.Table 6 – DataSetFieldFlags Values
Value Bit No. Description PromotedField 0 The flag indicates if the field is promoted to the NetworkMessages or transport protocol header.
Setting this flag increases the size of the NetworkMessages since information from the DataSetMessage body is also promoted to the header.Depending on the used security, the header including the field may be unencrypted. Promoted fields are always included in the header even if the DataSetMessage payload is a delta frame and the DataSet field is not included in the delta frame. In this case the last sent value is sent in the header.
The order of the fields in the DataSetMetaData promoted to the header shall match the order of the fields in the header unless the header includes field names.
05/30/2017
Following that table you see:
The DataSetFieldFlags representation in the AddressSpace is defined in Table 7.
In Table 7 you see:
Subtype of UInt16 defined in Part 5.
and
HasProperty Variable OptionSetValues LocalizedText [ ]
This tells you the value is encoded as a UInt16 and the text values associated with the bits can be found by reading the OptionSetValues property.
07/10/2020
jothi.sankkarraj@eon.com said
That example that I gave was a binary data. So as per your statements, I just need to read 2 bytes? In my example above would be the first 2 bytes which is 1 and 0?
I encountered a similar scenario. From the example you have mentioned above, the first 2 bytes (1 and 0) are dedicated to DataSetFieldFlags. Did you figure out how could we deal with the rest 8 bytes of binary data?
I understand that succeeding those 10 bytes, we are parsing an UByte, NodeId, and other members of FieldMetaData.
07/03/2020
Maybe someone can help us if we put these strange 10 bytes supposed to represent an instance of DataSetFieldFlags into the bigger context of a complete sample of the FieldMetaData structure, see the paste below.
Although the DataSetFieldFlags should be – according to our understanding of the standard – 2 bytes (UInt16) instead of 10 bytes, parsing the data works out if we skip those 10 bytes instead of reading one UInt16. Furthermore, from a semantic perspective, the flag PromotedField within DataSetFieldFlags should be 0 in our case, and we don’t know how this fits to these strange 10 bytes.
How to read the following paste? Each byte of the sample corresponds to one line of the paste. In the four leftmost columns we present each byte of the sample in hexadecimal, binary, decimal, and ASCII representation. On the right side we indicate the parsed structure according to our understanding. The beginning of each element of FieldMetaData is indicated in the line of the corresponding byte. If the element itself is a structure, the structure is expanded to the right with a list of its own elements. Unfortunately, the preformatted text does not use a monospace font (at least in my view of the post), and thus the alignment is disturbed – for a better visual appearance copy the text into a text editor with monospace font.
FieldMetaData (shortened/redacted where content is not needed for understanding the data)
Hex Binary Dec ASCII 0x36 0b00110110 54 6 + String name + Int32 length (== 54) 0x00 0b00000000 0 . | | 0x00 0b00000000 0 . | | 0x00 0b00000000 0 . | | 0x$$ 0b$$$$$$$$ $ $ | + Byte[n] value (52 lines skipped) | | 0x$$ 0b$$$$$$$$ $ $ | * 0x00 0b00000000 0 . + LocalizedText description (all bits zero => no fields present) 0x01 0b00000001 1 . + DataSetFieldFlags fieldFlags ??? 0x00 0b00000000 0 . 0x00 0b00000000 0 . 0x00 0b00000000 0 . 0x00 0b00000000 0 . 0x01 0b00000001 1 . 0x00 0b00000000 0 . 0x00 0b00000000 0 . 0x00 0b00000000 0 . 0x01 0b00000001 1 . 0x16 0b00010110 22 . + Byte builtInType (== ExtensionObject) 0x01 0b00000001 1 . + NodeId dataType + Byte encoding (== FourByte) 0x01 0b00000001 1 . | + Byte namespace 0x03 0b00000011 3 . | + Uint16 identifier 0x00 0b00000000 0 . | * 0xFF 0b11111111 255 . + Int32 valueRank (== -1 == scalar) 0xFF 0b11111111 255 . | 0xFF 0b11111111 255 . | 0xFF 0b11111111 255 . | 0xFF 0b11111111 255 . + UInt32[] arrayDimensions + Int32 number (== -1 => array is null) 0xFF 0b11111111 255 . | | 0xFF 0b11111111 255 . | | 0xFF 0b11111111 255 . | * 0x00 0b00000000 0 . + Uint32 maxStringLength (== 0) 0x00 0b00000000 0 . | 0x00 0b00000000 0 . | 0x00 0b00000000 0 . | 0x$$ 0b$$$$$$$$ $ $ + Guid dataSetFieldId + UInt32 Data1 0x$$ 0b$$$$$$$$ $ $ | | 0x$$ 0b$$$$$$$$ $ $ | | 0x$$ 0b$$$$$$$$ $ $ | | 0x$$ 0b$$$$$$$$ $ $ | + UInt16 Data2 0x$$ 0b$$$$$$$$ $ $ | | 0x$$ 0b$$$$$$$$ $ $ | + UInt16 Data3 0x$$ 0b$$$$$$$$ $ $ | | 0x$$ 0b$$$$$$$$ $ $ | + Byte[8] Data4 0x$$ 0b$$$$$$$$ $ $ | | 0x$$ 0b$$$$$$$$ $ $ | | 0x$$ 0b$$$$$$$$ $ $ | | 0x$$ 0b$$$$$$$$ $ $ | | 0x$$ 0b$$$$$$$$ $ $ | | 0x$$ 0b$$$$$$$$ $ $ | | 0x$$ 0b$$$$$$$$ $ $ | * 0x02 0b00000010 2 . + KeyValuePair[] properties + Int32 number (== 2) 0x00 0b00000000 0 . | | 0x00 0b00000000 0 . | | 0x00 0b00000000 0 . | | 0x01 0b00000001 1 . | + KeyValuePair properties[0] + QualifiedName key + UInt16 namespaceIndex 0x00 0b00000000 0 . | | | | 0x06 0b00000110 6 . | | | + String name + Int32 length (== 6) 0x00 0b00000000 0 . | | | | | 0x00 0b00000000 0 . | | | | | 0x00 0b00000000 0 . | | | | | 0x50 0b01010000 80 P | | | | + Byte[n] value 0x72 0b01110010 114 r | | | | | 0x65 0b01100101 101 e | | | | | 0x66 0b01100110 102 f | | | | | 0x69 0b01101001 105 i | | | | | 0x78 0b01111000 120 x | | | * * 0x0C 0b00001100 12 . | | + BaseDataType value ??? 0x00 0b00000000 0 . | | 0x00 0b00000000 0 . | | 0x00 0b00000000 0 . | | 0x00 0b00000000 0 . | | 0x01 0b00000001 1 . | + KeyValuePair properties[1] + QualifiedName key + UInt16 namespaceIndex 0x00 0b00000000 0 . | | | | 0x04 0b00000100 4 . | | | + String name + Int32 length (== 4) 0x00 0b00000000 0 . | | | | | 0x00 0b00000000 0 . | | | | | 0x00 0b00000000 0 . | | | | | 0x55 0b01010101 85 U | | | | + Byte[n] value 0x6E 0b01101110 110 n | | | | | 0x69 0b01101001 105 i | | | | | 0x74 0b01110100 116 t | | | * * 0x0C 0b00001100 12 . | | + BaseDataType value ??? 0x00 0b00000000 0 . | | 0x00 0b00000000 0 . | | 0x00 0b00000000 0 . | | 0x00 0b00000000 0 . * *
Any thoughts and insights regarding how to deal with the DataSetFieldFlags are appreciated. We also need an advice how to understand the element “value” of type BaseDataType within the structure KeyValuePair.
05/30/2017
The value is encoded according to the UA Binary encoding rules for Variant defined in Part 6.
https://reference.opcfoundatio…../#5.2.2.16
It is union that can contain any of the other types. You need to be more specific on what the issue is.
The Part 14 tables do not leave much to chance. Are you sure you followed all of the possible branches? The bytes have to be there for a reason.
That said. \ it may be bug in the publisher. Where does the data come from and do other products interoperate?
07/03/2020
Many thanks, Randy Armstrong!
Regarding the value of the KeyValuePair, your hint towards the type Variant solved my problem of understanding. Now we can decode a KeyVauePair as follows:
KeyValuePair
Hex Binary Dec ASCII 0x01 0b00000001 1 . + QualifiedName key + UInt16 namespaceIndex 0x00 0b00000000 0 . | | 0x04 0b00000100 4 . | + String name + Int32 length (== 4) 0x00 0b00000000 0 . | | | 0x00 0b00000000 0 . | | | 0x00 0b00000000 0 . | | | 0x55 0b01010101 85 U | | + Byte[n] value 0x6E 0b01101110 110 n | | | 0x69 0b01101001 105 i | | | 0x74 0b01110100 116 t | * * 0x0C 0b00001100 12 . + Variant(BaseDataType) value + Byte encodingMask (== String) 0x00 0b00000000 0 . | + String value + Int32 length (== 0) 0x00 0b00000000 0 . | | | 0x00 0b00000000 0 . | | | 0x00 0b00000000 0 . * * *
I’ll make a separate reply regarding the other issue.
07/03/2020
Many thanks also for your thoughts on the DataSetFieldFlags, Randy Armstrong!
The PubSub data comes from a third-party appliance at one of our business partners. Hence it’s hard to reach the people who know the implementation of the software on this appliance. Maybe there is really a bug in the implementation. Currently, we are the only consumer of the data.
We couldn’t find an alternative parsing route in the specification of the type FieldMetaData (https://reference.opcfoundatio…..#6.2.2.1.3). We’ll try to parse the data with other software, and we’ll try to understand, what the other software does at the 10 bytes we suppose to be the DataSetFieldFlags.
1 Guest(s)