- 1. Elements
- 1.1. bit
- 1.2. case
- 1.3. cstr
- 1.4. default
- 1.5. enc
- 1.6. export
- 1.7. field
- 1.8. fragment
- 1.9. if
- 1.10. item
- 1.11. jump
- 1.12. oob
- 1.13. pad
- 1.14. peek
- 1.15. prop
- 1.16. range
- 1.17. record
- 1.18. repeat
- 1.19. script
- 1.20. setprop
- 1.21. start
- 1.22. switch
- 1.23. type
- 1.24. uint16
- 1.25. uint32
- 1.26. uint64
- 1.27. uint8
- 1.28. while
- 1.29. xddl
- 2. Attribute Types
- 3. Common Children
A <bit> is a bit.
attribute name | type | required |
---|---|---|
name |
string |
✔ |
type |
url |
|
bias |
integer |
|
default |
expression |
The following example is a one bit message:
<xddl>
<bit name="x"/>
</xddl>
And decoding a bit with idm:
# idm obp.xddl @1 Name Length Value Hex Description x 1 1 @1
The <case> element only appears as a child of the <switch> element. It is similar to the case keyword in C++.
attribute name | type | required |
---|---|---|
value |
integer |
✔ |
children: Common Children
See the <switch> element for example usage.
The <cstr> element represents a null-terminated C string.
attribute name | type | required |
---|---|---|
max |
expression |
|
name |
string |
✔ |
children: none
Example:
<xddl>
<cstr name="greeting"/>
</xddl>
Decoding the ASCII hex for "Hello" yields:
# idm cstr.xddl 48656C6C6F00 Name Length Value Hex Description greeting 48 79600447942400 #48656C6C6F00 Hello
The <default> element only appears as a child of the <switch> element. It is similar to the default keyword in C/C++.
attributes: none
children: Common Children
See the <switch> element for example usage.
The <enc> element is used to encapsulate encoding fields. Encoding fields are by default not displayed in the idm.
attributes: none
children: <fragment>, <start>, <type>, Common Children
Here is an example that reads a size
field and then a field of that length.
In this case, we consider size
to be an encoding field, and not an important part of
the message for display purposes. We surround it with <enc> to indicate so.
<xddl>
<enc>
<uint8 name="size"/>
</enc>
<field name="value" length="size"/>
</xddl>
And decoding 080F
with the idm skips over the length
field:
# idm enc.xddl 080F Name Length Value Hex Description value 8 15 #0F
But running idm with the --encoding
flag will display it:
# idm --encoding enc.xddl 080F Name Length Value Hex Description size 8 8 #08 value 8 15 #0F
However, records inserted within an encoding range are themselves not considered to be encoding.
<export> provides a way to create global properties in a message. These properties <can> be used and set by different records as a message is being parsed.
attributes: none
children: <prop>
The following file creates a global property, size. The A record references this size and creates a field based on its length. The B record also creates a field based on the value of size, but since there is a local size property defined in its scope (with the value of 16), it is used instead.
<xddl>
<export>
<prop name="size" value="8"/>
</export>
<record id="A">
<field name="b" length="size"/>
</record>
<record id="B">
<prop name="size" value="16"/>
<field name="b" length="size"/>
</record>
<start>
<record name="A" href="#A"/>
<record name="B" href="#B"/>
</start>
</xddl>
Decoding three bytes yields:
# idm export.xddl 010203 Name Length Value Hex Description A b 8 1 #01 B b 16 515 #0203
These properties are also visible to records that are included from different files. There are no "file local" properties.
The <field> element identifies an integer unit of information specific to the message being represented.
It must have a name
and length
attribute. The length
is specified in bits, and
may be any nonnegative integer value. It does not have to be byte aligned within the
record it appears.
The optional bias
attribute is added to the value by a fixed amount when displayed
in the idm. See the bias
example in the description below.
attribute name | type | required |
---|---|---|
name |
string |
✔ |
type |
url |
|
bias |
integer |
|
length |
expression |
✔ |
default |
expression |
This is a simple example that defines a field named "foo" and is 4 bits long. The
name
and length
are required attributes, and typically they are the only ones
used. Here is an example describing a simple message consisting of one 4 bit field.
<xddl>
<start>
<field name="sequence" length="4"/>
</start>
</xddl>
Parsing the four bit message "@1111" results in:
# idm simple_field.xddl @1111 Name Length Value Hex Description sequence 4 15 @1111
The optional bias
attribute is used to offset the value of field by a
fixed amount. Here’s an example:
<xddl>
<field name="a" length="1" bias="-10"/>
<field name="b" length="1" bias="-9"/>
<field name="c" length="1" bias="-8"/>
<field name="d" length="1" bias="-7"/>
<field name="e" length="1" bias="1"/>
<field name="f" length="1" bias="2"/>
<field name="g" length="1" bias="3"/>
<field name="h" length="1" bias="4"/>
</xddl>
Each field is just 1 bit long, but we are biasing them by varying amounts. The bias is applied after the fields are parsed. If we parse a message of all zeroes, here is what we get:
# idm bias.xddl @00000000 Name Length Value Hex Description a 1 -10 @0 b 1 -9 @0 c 1 -8 @0 d 1 -7 @0 e 1 1 @0 f 1 2 @0 g 1 3 @0 h 1 4 @0
As you can see, the Value column is offset by the bias
. The Hex
column still reflects the original bit pattern.
The optional type
attribute references a <type> element’s id
. See the <type> element
reference for examples.
This example references a locally defined <type>.
<xddl>
<type id="HelloType">
<item key="0" value="Goodbye World!"/>
<item key="1" value="Hello World!"/>
</type>
<bit name="A" type="#HelloType"/>
<bit name="B" type="#HelloType"/>
</xddl>
And decoding the bits 10
yields:
# idm hello.xddl @10 Name Length Value Hex Description A 1 1 @1 Hello World! B 1 0 @0 Goodbye World!
The <fragment> element is similar to a record link, except the contents of the referenced record are inserted "inline" in the resulting message.
attribute name | type | required |
---|---|---|
href |
url |
✔ |
children: none
The following example parses the same record twice, once as a fragment, and then once as a record.
<xddl>
<record id="A">
<field name="b" length="8"/>
</record>
<start>
<fragment href="#A"/>
<record name="A" href="#A"/>
</start>
</xddl>
The result:
# idm fragment.xddl 0102 Name Length Value Hex Description b 8 1 #01 A b 8 2 #02
Fragments are useful sometimes when many messages contain the same handfull of fields.
The <if> element provides a way to conditionally include other elements based on an expression.
attribute name | type | required |
---|---|---|
expr |
expression |
✔ |
children: Common Children
The following example illustrates the conditional inclususion of a field:
<xddl>
<start>
<field name="Included" length="8"/>
<if expr="Included">
<field name="More" length="8"/>
</if>
</start>
</xddl>
Now we parse two messages with the above file. The first one will
include the More
field and the second one will not:
# idm if.xddl 0105 00 Name Length Value Hex Description Included 8 1 #01 More 8 5 #05 Name Length Value Hex Description Included 8 0 #00
The expr
attribute may be any XDDL expression. As long as it does not
evaluate to zero, the conditional elements will be included.
The <item> element only appears as a child of the <type> element. It is used to specify an item of an enumerated list.
attribute name | type | required |
---|---|---|
key |
integer |
✔ |
href |
url |
|
value |
string |
✔ |
children: none
The option href attribute can be specified and is used in conjuntion with the <jump> element.
See <type> for example usage.
A <jump> element provides an easy way to choose a record to parse based on a value.
attribute name | type | required |
---|---|---|
base |
jump_name |
✔ |
children: none
A common pattern among parsing messages is to choose one of many records to parse based on a single field’s value, a message type, for example. This can easy enough be done with a <switch> element:
<uint8 name="msg-id"/> <switch expr="msg-id"> <case value="1"> <record href="#A"/> </case> <case value="2"> <record href="#B"/> </case> <case value="3"> <record href="#C"/> </case> . . . </switch>
<uint8 name="msg-id" type="#msg-id"/> <type id="msg-type"> <item key="1" value="A" href="#A"/> <item key="2" value="B" href="#B"/> <item key="3" value="C" href="#C"/> . . . </type> <jump base="msg-id"/>
The above two listings are functionally equivalent.
attributes: none
children: <export>, <start>, <type>, Common Children
The <pad> element is used to align a record to a boundary. Typically, this will be a byte boundary, but can be changed by using the attributes.
It’s length is not determined by a fixed value or expression, rather it is determined by the current bit number of the message or record it appears in.
attribute name | type | required |
---|---|---|
mod |
pos_integer |
|
name |
string |
|
offset |
size |
children: none
Without attributes specified, the <pad> element will consume bits of the record until the record is byte aligned. For example, the <pad> element in following document will consume 3 bits in order to make the message byte aligned.
<xddl>
<field name="A" length="5"/>
<pad/>
<field name="B" length="8"/>
</xddl>
And parsing:
# idm pad.xddl A014 Name Length Value Hex Description A 5 20 @10100 pad 3 0 @000 B 8 20 #14
As we can see, the length of the pad is 3.
If we change the length of the A field to 2, we get a pad of 6.
<xddl>
<field name="A" length="2"/>
<pad/>
<field name="B" length="8"/>
</xddl>
# idm pad1.xddl A014 Name Length Value Hex Description A 2 2 @10 pad 6 32 @100000 B 8 20 #14
The <peek> element provides access to data ahead in the message. This information can then be referenced in expressions.
attribute name | type | required |
---|---|---|
name |
string |
✔ |
length |
expression |
✔ |
offset |
size |
✔ |
children: none
In some protocols a field cannot be decoded correctly until a subsequent field is known. The <peek> element provides a solution for this situation.
<xddl>
<peek name="pd" offset="4" length="4"/>
<switch expr="pd">
<case value="0">
<field length="4" name="security header"/>
<field length="4" name="protocol descriminator"/>
</case>
<case value="1">
<field length="4" name="bearer identity"/>
<field length="4" name="protocol descriminator"/>
</case>
</switch>
</xddl>
The <prop> element declares and initializes a property. Properties can be referenced in expressions just like fields.
attribute name | type | required |
---|---|---|
name |
string |
✔ |
type |
url |
|
value |
expression |
|
visible |
bool |
Properties provide a way to create a data member in the current scope. This property can later be referenced in expressions. It is similar to a field, but does not consume data from the message, and it can later be changed using the <setprop> element.
attribute name | type | required |
---|---|---|
end |
integer |
✔ |
href |
url |
|
value |
string |
|
start |
integer |
✔ |
children: none
The <range> elements can exist along side <item> elements. The <item> values are evaluated first, and the <range> second. This means a <range> can overlap existing items. Using these two mechanics, we can use a <range> as a default if no items match a particular value.
The following example illustrates this. The first part of the enumerated type lists several colors with their RGB Hex Triplet. The <range> at the bottom will be used if no <item> matches.
<xddl>
<type id="colors">
<item key="#F0F8FF" value="Alice blue"/>
<item key="#E32636" value="Alizarin"/>
<item key="#E52B50" value="Amaranth"/>
<item key="#FFBF00" value="Amber"/>
<item key="#9966CC" value="Amethyst"/>
<item key="#FBCEB1" value="Apricot"/>
<item key="#00FFFF" value="Aqua"/>
<item key="#7FFFD4" value="Aquamarine"/>
<item key="#4B5320" value="Army green"/>
<item key="#7BA05B" value="Asparagus"/>
<item key="#FF9966" value="Atomic tangerine"/>
<item key="#6D351A" value="Auburn"/>
<item key="#007FFF" value="Azure (color wheel)"/>
<item key="#F0FFFF" value="Azure (web)"/>
<range start="0" end="#FFFFFF" value="Unknown Color"/>
</type>
<start>
<field length="24" name="first" type="#colors"/>
<field length="24" name="second" type="#colors"/>
<field length="24" name="third" type="#colors"/>
<field length="24" name="fourth" type="#colors"/>
<field length="24" name="fifth" type="#colors"/>
<field length="24" name="sixth" type="#colors"/>
<field length="24" name="seventh" type="#colors"/>
<field length="24" name="eighth" type="#colors"/>
<field length="24" name="ninth" type="#colors"/>
</start>
</xddl>
Parsing a message with this file yields:
# idm range.xddl E3263600FFFF0000FFF0FFFF66FF00ACE1AF4B5320FF9966F19CBB Name Length Value Hex Description first 24 14886454 #E32636 Alizarin second 24 65535 #00FFFF Aqua third 24 255 #0000FF Unknown Color fourth 24 15794175 #F0FFFF Azure (web) fifth 24 6749952 #66FF00 Unknown Color sixth 24 11329967 #ACE1AF Unknown Color seventh 24 4936480 #4B5320 Army green eighth 24 16750950 #FF9966 Atomic tangerine ninth 24 15834299 #F19CBB Unknown Color
See the <type> element reference for more usage of types.
A <record> is a way to group elements together, including other records. If given an id, records can then be referenced from other places in the document, or from a different document, using URL notation.
Hence, <record> can be used in two different ways:
[[Record Definition]] ==== Record Definition
Define a <record>.
attribute name | type | required |
---|---|---|
id |
id_url |
|
name |
string |
|
length |
expression |
children: Common Children
Example:
<record id="ack"> <uint8 name="sequence number"/> <uint8 name="error"/> </record>
[[Record Link]] ==== Record Link
Link to a record defined someplace else.
attribute name | type | required |
---|---|---|
name |
string |
|
href |
url |
|
length |
expression |
children: none
The record definition in the example above can be referenced with:
<record href="#ack"/>
The <repeat> element repeats its child elements a certain number of times, creating a record for each iteration. There are three different ways to use <repeat>, based on the attribute signature, described below.
[[Repeat Indefinitely]] ==== Repeat Indefinitely
This form will repeat until all the available bits are consumed.
attribute name | type | required |
---|---|---|
name |
string |
|
minlen |
size |
children: Common Children
A common pattern for this usage is to combine it with a fixed size record, for example:
<xddl>
<record length="8">
<repeat>
<bit name="a"/>
<bit name="b"/>
</repeat>
<uint8 name="crc"/>
</record>
</xddl>
Example decode:
# idm repeat1.xddl A3FF Name Length Value Hex Description record repeat record a 1 1 @1 b 1 0 @0 record a 1 1 @1 b 1 0 @0 record a 1 0 @0 b 1 0 @0 record a 1 1 @1 b 1 1 @1 crc 0 0
[[Numbered Repeat]] ==== Numbered Repeat
This version repeats based on an expression.
attribute name | type | required |
---|---|---|
num |
expression |
✔ |
name |
string |
children: Common Children
[[Bound Repeat]] ==== Bound Repeat
This version will repeat its contents at least min times and no more than max.
attribute name | type | required |
---|---|---|
min |
expression |
|
max |
expression |
|
name |
string |
|
minlen |
integer |
children: Common Children
The <script> element contains XddlScript. It appears as a child of the <type> element and is used to specify or refine a field’s description.
attributes: none
children: none
The language is [Lua](http://www.lua.org) based. Documentation on Lua can be found at [www.lua.org](http://www.lua.org).
The purpose of the <script> element is to set a field’s (or property’s) description. This is done by setting a variable named description to a string. Here’s a simple example that uses a <script> to treat a value as an ASCII string.
<type id="string"> <script> description = string.format("link:#s[<s>]", ascii()); </script> </type>
The ascii() function is an XddlScript function that interprets the current value as an ASCII string.
The following table lists all the currently supported XddlScript functions and is subject to change. The function availability when used used by <field> or <prop> elements is also noted.
Function | fields | props | Description |
---|---|---|---|
ascii |
✔ |
Return the current value as an ASCII string |
|
ascii7 |
✔ |
Return the current value as a 7 bit ASCII string |
|
Description(name) |
✔ |
✔ |
Return the description of a previous field |
EnumValue |
✔ |
✔ |
Return the <enum> description of the current value if it has one |
Value(name) |
✔ |
✔ |
Return the value of another field |
slice(offset, length) |
✔ |
Slice a field into pieces, see description below |
|
TwosComplement |
✔ |
Return the current value as a two’s complement integer |
|
search(name) |
✔ |
✔ |
Return the description of a node in the message by name |
The ascii() string does not have to be null terminated. However, if it is null terminated, the characters after the termination character will be ignored. Any non-printable characters will be printed as periods.
The Description() function will return the description of a node that is in scope. The search() function will do a depth-first search for a field from the top of the message.
The slice() function can take the current value and return a value of just a bit range, a subset of the entire bitstring that makes up the value. A good example is taking a 32-bit IP address type and representing it in the familiar dot notation:
<xddl>
<type id="ip_address">
<script>
description = string.format("%d.%d.%d.%d", slice(0, 8), slice(8, 8), slice(16, 8), slice(24, 8))
</script>
</type>
<start>
<uint32 name="address" type="#ip_address"/>
</start>
</xddl>
And parsing some data:
# idm ipscript.xddl AF38B1E6 Name Length Value Hex Description address 32 2939728358 #AF38B1E6 175.56.177.230
The <setprop> element provides a way to change the value or type of a property.
attribute name | type | required |
---|---|---|
name |
setprop_name |
✔ |
type |
url |
|
value |
expression |
✔ |
children: <item>, <range>, <script>, Common Children
The name is the name of a property that was previously created using the <prop> element. It must exist and be in scope. The type will set a new <type> reference of the property. This must be specified even if the type hasn’t changed, otherwise the type will be removed. The value is the new value of the property.
The <start> element is optional and specifies the starting record of a document. If the <start> is not specified, then parsing will begin at the beginning of the document.
attributes: none
children: Common Children
A typical XDDL specification contains many records, one for each message type to be parsed. It is convenient to have an explicit starting point for parsing, and that is what <start> is for. It is analogous to the main() function in C/C++.
The <switch> element is similar in function to the switch statement in popular general purpose programming languages. Based on the evaluation of the expr attribute, a particular <case> element’s contents will be parsed.
attribute name | type | required |
---|---|---|
expr |
expression |
✔ |
In order for it to be parsed, the <switch> element’s expr attribute must evaluate to the <case> element’s value attribute.
The value of each <case> child must be unique.
There is no need for a corresponding break. Execution will only "fall-through" if the <case> being executed is empty.
If no matches are found, and a <default> element exists as a child of the <switch>, then its contents will be parsed. There can be at most one default child.
Otherwise, nothing will be parsed.
The following example illustrates the use of a <switch>. It describes a message of three octets. The first octet is used for the expr in the <switch> element. The second octet is read by the corresponding <case> contents, and the final octet is read into the check field.
<xddl>
<start>
<field name="choice" length="8"/>
<switch expr="choice">
<case value="1">
<field name="a" length="4"/>
<field name="b" length="4"/>
</case>
<case value="2">
<field name="c" length="1"/>
<field name="d" length="7"/>
</case>
<case value="3"/> <!-- "fall through" -->
<case value="4">
<field name="e" length="2"/>
<field name="f" length="6"/>
</case>
<default>
<field name="g" length="2"/>
<field name="h" length="6"/>
</default>
</switch>
<field name="check" length="8"/>
</start>
</xddl>
We can parse the file with different messages to see the different paths are followed:
Here we follow the first case:
# idm choice.xddl 0104FF Name Length Value Hex Description choice 8 1 #01 a 4 0 @0000 b 4 4 @0100 check 8 255 #FF
The "fall-through" case:
# idm choice.xddl 031AFF 041AFF Name Length Value Hex Description choice 8 3 #03 e 2 0 @00 f 6 26 @011010 check 8 255 #FF Name Length Value Hex Description choice 8 4 #04 e 2 0 @00 f 6 26 @011010 check 8 255 #FF
Both of the above messages follow the value="4"
case.
And finally the <default> case can be followed if we specify a choice that does not match any other <case>:
# idm choice.xddl AAFEFF Name Length Value Hex Description choice 8 170 #AA g 2 3 @11 h 6 62 @111110 check 8 255 #FF
The <type> tag is used to specify valid values for <field> elements. It is also used to specify a field’s description.
attribute name | type | required |
---|---|---|
id |
id_url |
✔ |
name |
string |
The [field example](#type-Attribute) above shows a typical usage of <type>.
Often it is easier to specify a field’s valid values by placing them as children of the <field>. The following example illustrates this.
<xddl>
<bit name="A">
<item key="0" value="Goodbye World!"/>
<item key="1" value="Hello World!"/>
</bit>
</xddl>
And running:
# idm anon.xddl @1 @0 Name Length Value Hex Description A 1 1 @1 Hello World! Name Length Value Hex Description A 1 0 @0 Goodbye World!
Note, since an anonymous type has no id, it cannot be referenced from any other field.
This is equivalent to a <field> with length 16.
attribute name | type | required |
---|---|---|
name |
string |
✔ |
type |
url |
|
bias |
integer |
|
default |
expression |
This is equivalent to a <field> with length 32.
attribute name | type | required |
---|---|---|
name |
string |
✔ |
type |
url |
|
bias |
integer |
|
default |
expression |
This is equivalent to a <field> with length 64.
attribute name | type | required |
---|---|---|
name |
string |
✔ |
type |
url |
|
bias |
integer |
|
default |
expression |
This is equivalent to a <field> with length 8.
attribute name | type | required |
---|---|---|
name |
string |
✔ |
type |
url |
|
bias |
integer |
|
default |
expression |
Repeat the contents of the <while> as long as expr is true.
attribute name | type | required |
---|---|---|
name |
string |
|
expr |
expression |
✔ |
children: Common Children
Type | Default | Description |
---|---|---|
bool |
false |
true or false |
integer |
0 |
Any integer will do |
pos_integer |
1 |
Positive integer |
size |
0 |
Non-negative integer |
string |
||
expression |
XDDL expression |
|
setprop_name |
Name of a property that is in scope |
|
url |
Link to a record |
|
id_url |
id used in record definitions |
|
jump_name |
Field name used for jump element |