One document matched: draft-greevenbosch-appsawg-cbor-cddl-01.xml
<?xml version="1.0"?>
<!DOCTYPE rfc SYSTEM 'rfc2629.dtd'[
<!ENTITY RFC2119 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC7049 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7049.xml">
]>
<?rfc toc="yes"?>
<?rfc symrefs="yes" ?>
<rfc category="info" ipr="trust200902" docName="draft-greevenbosch-appsawg-cbor-cddl-01">
<front>
<title abbrev="CBOR notation">CBOR data definition language: a notational convention to express CBOR data structures.</title>
<author initials="B." surname="Greevenbosch" fullname="Bert Greevenbosch">
<organization abbrev="Huawei Technologies">Huawei Technologies Co., Ltd.</organization>
<address>
<postal>
<street>Huawei Industrial Base</street>
<street>Bantian, Longgang District</street>
<city>Shenzhen</city>
<code>518129</code>
<country>P.R. China</country>
</postal>
<email>bert.greevenbosch@huawei.com</email>
</address>
</author>
<date day="14" month="February" year="2014"/>
<area>Applications</area>
<workgroup></workgroup>
<abstract>
<t>
This document proposes a notational convention to express CBOR data structures.
Its main goal is to make it easy to express message structures for protocols that use CBOR.
</t>
</abstract>
</front>
<middle>
<section title="Requirements notation">
<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL",
"SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
and "OPTIONAL" in this document are to be interpreted as
described in <xref target="RFC2119"/>.
</t>
</section>
<section title="Introduction">
<t>
In this document,
a notational convention to express CBOR <xref target="RFC7049"/> data structures is defined.
</t>
<t>
The main goal for the convention is to provide a unified notation that can be used when defining protocols that use CBOR.
</t>
<t>
The CBOR notational convention has the following goals:
<list style="format (G%d)">
<t>Able to provide an unambiguous description of a CBOR data structures.</t>
<t>Easy for humans to read and write.</t>
<t>Flexibility to express the freedoms of choice in the CBOR data format.</t>
<t>Possibility to restrict format choices where appropriate.</t>
<t>Able to express common CBOR datatypes and structures.</t>
<t>Human and machine readable and processable.</t>
<t>Usable for automatic verification of whether CBOR data is compliant to a predefined format.</t>
</list>
</t>
</section>
<section title="Definitions">
<t>
The following contains a list of used words in this document:
<list style="hanging">
<t hangText=""datatype"">
defines the format of a variable.
</t>
<t hangText=""variable"">
a data component encoded in CBOR.
</t>
</list>
</t>
</section>
<section title="Notational conventions">
<section title="General conventions">
<t>
The basic syntax is as follows:
<list style="symbols">
<t>Each field has a name and a datatype.</t>
<t>
The name is written first, followed by a colon and then the datatype.
The declarations is finished with a semicolon.
Whitespace may appear around the colon and semicolon,
as well as in front of the name.
</t>
<t>The name does not appear in the actual CBOR encoding.</t>
<t>
Comments are preceded by a '#' character.
</t>
<t>
Variable names and datatypes are case sensitive.
</t>
</list>
</t>
</section>
<section title="Keywords for primitive datatypes">
<t>
The following keywords for primitive datatypes are defined:
<list style="hanging">
<t hangText=""bool"">
Boolean value (major type 7, additional information 20 or 21).
</t>
<t hangText=""bstr"">
A byte string (major type 2).
</t>
<t hangText=""float(16)"">
IEEE 754 half-precision float (major type 7, additional information 25).
</t>
<t hangText=""float(32)"">
IEEE 754 single-precision float (major type 7, additional information 26).
</t>
<t hangText=""float(64)"">
IEEE 754 double-precision float (major type 7, additional information 27).
</t>
<t hangText=""int"">
An unsigned integer (major type 0) or a negative integer (major type 1).
</t>
<t hangText=""nint"">
A negative integer (major type 1).
</t>
<t hangText=""simple"">
Simple value (major type 7, additional information 24).
</t>
<t hangText=""tstr"">
Text string (major type 3)
</t>
<t hangText=""uint"">
An unsigned integer (major type 0).
</t>
</list>
</t>
<t>
In addition,
<xref target="tagsec"/> defines datatypes associated with CBOR tags.
</t>
</section>
<section title="Arrays">
<t>
Arrays can be of fixed length or of variable length.
Both fixed length and variable length arrays can be implemented as definite and indefinite length arrays.
</t>
<t>
A fixed length array is is indicated by '[' and ']' characters behind its type,
where number in between specifies the number of elements.
</t>
<t>
A variable length array can be indicated with a "*" behind its type.
</t>
<t>
The following is an example of an array of 4 integers:
</t>
<figure>
<artwork align="center"><![CDATA[
fourNumbers: int[4];
]]></artwork>
</figure>
<t>
The following is an example of a variable length array:
<figure>
<artwork align="center"><![CDATA[
fibonacci : uint*;
]]></artwork>
</figure>
</t>
</section>
<section title="Structures">
<t>
Structures are a logical grouping of CBOR fields.
</t>
<t>
A structure has a name,
which can be used as a value type for other fields.
The name is followed by a '{' character
and the definitions of the variables inside of the structure.
The structure is closed by a '}' character.
</t>
<t>
A structure MAY be encoded as an array,
in which case its name is preceded by a '*' character.
Otherwise there is no CBOR encoding for the grouping.
</t>
<t>
The following is an example of a structure:
<figure>
<artwork align="center"><![CDATA[
*Geography {
city : tstr;
gpsCoordinates : GpsCoordinates;
}
GpsCoordinates {
longitude : uint; # multiplied by 10^7
lattitude : uint; # multiplied by 10^7
}
]]></artwork>
</figure>
</t>
<t>
When encoding,
the Geography structure is encoded using a CBOR array,
whereas the GpsCoordinates do not have their own encompassing array.
</t>
</section>
<section title="Maps">
<t>
If an entity is a map (major type 5),
its datatype has the form
<figure>
<artwork align="center"><![CDATA[
map( x, y )
]]></artwork>
</figure>
where the keys have datatype x,
and the values a datatype y.
</t>
<t>
If either x or y is unspecified
(i.e. free to choose per entry),
it is replaced by a '.'.
</t>
<t>
It is also possible to define a map with predefined keys as a type.
In this case,
type declaration is as follows:
</t>
<figure>
<artwork align="center"><![CDATA[
x: map( y ) {
key1: type1;
key2: type2;
...
}
]]></artwork>
</figure>
<t>
y is the datatype of the keys,
and type1, type2, etc the datatype of the value associated with keys key1, key2 etc.
</t>
<t>
The name of an optional map element is preceded by a '?' character.
</t>
<t>
The example below
the defines a map with display name (as a string),
optionally the name components first name and family name
(see <xref target="optVar"/> for more on optional variables),
and age information (as an unsigned int).
</t>
<figure>
<artwork align="center"><![CDATA[
PersonalData: map( tstr ) {
"displayName": tstr;
?"nameComponents": NameComponents;
"age": uint;
}
NameComponents: map( tstr, tstr ) {
"firstName": tstr;
"familyName" : tstr;
}
]]></artwork>
</figure>
<t>
It is up to the application how to handle unknown tags,
however, it is RECOMMENDED to ignore them.
</t>
</section>
<section title="Tags" anchor="tagsec">
<t>
A variable can have an associated CBOR tag (major type 6).
This is indicated by the tag encapsulated between the square brackets '[' and ']',
just before the variable's datatype definition.
</t>
<t>
For example,
the following defines a positive bignum N:
<figure>
<artwork align="center"><![CDATA[
N: [2]bstr;
]]></artwork>
</figure>
</t>
<t>
<xref target="RFC7049"/> defines several tags.
These tags can be also written using the datatypes from <xref target="tagtable"/>.
For table rows with an empty "possible tag notation" entry,
we refer to Table 3 in <xref target="RFC7049"/> and associated references for the possible encodings.
</t>
<t>
For example,
the following is another way to define the bignum:
</t>
<figure>
<artwork align="center"><![CDATA[
N: bignum;
]]></artwork>
</figure>
<texttable anchor="tagtable">
<ttcol align="left">datatype</ttcol>
<ttcol align="left">possible tag notation</ttcol>
<ttcol align="left">description</ttcol>
<c>b64</c>
<c>[34]tstr</c>
<c>Base 64 (tag 34)</c>
<c>b64url</c>
<c>[33]tstr</c>
<c>Base 64 URL (tag 33)</c>
<c>bigfloat</c>
<c></c>
<c>bigfloat (tag 5)</c>
<c>bignum</c>
<c>[2]bstr or [3]bstr</c>
<c>positive (tag 2) or negative (tag 3) bignum</c>
<c>cbor</c>
<c>[24]bstr</c>
<c>Encoded CBOR data item (tag 24)</c>
<c>decfrac</c>
<c></c>
<c>decimal fraction (tag 4)</c>
<c>eb16</c>
<c></c>
<c>Expected conversion to base16 encoding (tag 23)</c>
<c>eb64</c>
<c></c>
<c>Expected conversion to base64 encoding (tag 22)</c>
<c>eb64url</c>
<c></c>
<c>Expected conversion to base64 url encoding (tag 21)</c>
<c>epochdt</c>
<c></c>
<c>epoch date/time (tag 1)</c>
<c>mime</c>
<c>[36]tstr</c>
<c>Mime message (tag 36)</c>
<c>nbignum</c>
<c>[3]bstr</c>
<c>negative bignum (tag 3)</c>
<c>regex</c>
<c>[35]tstr</c>
<c>regular expression (tag 35)</c>
<c>standarddt</c>
<c>[0]tstr</c>
<c>standard date/time string (tag 0)</c>
<c>ubignum</c>
<c>[2]bstr</c>
<c>positive bignum (tag 2)</c>
<c>uri</c>
<c>[32]tstr</c>
<c>URI (tag 32)</c>
</texttable>
</section>
<section title="Optional variables" anchor="optVar">
<t>
There may be variables or structures whose inclusion is optional.
In this case,
the name of the variable is preceded by a '?' character
</t>
<t>
For example,
the following defines a CBOR structure that is dependent on a boolean value.
<figure>
<artwork align="center"><![CDATA[
*MainStruct {
whichForm : bool;
?data1 : Form1; # when whichForm == true
?data2 : Form2; # when whichForm == false
}
Form1 {
anInteger : int;
aTextString : tstr;
}
Form2 {
aFloat : float(16);
aBinaryString : bstr;
}
]]></artwork>
</figure>
Notice that it is not possible to define the relationship between "whichForm" and
inclusion of either "data1" or "data2" with CBOR content rules.
Such relationship should be otherwise communicated to the implementer,
for example in the text of the specification that uses the CBOR structure,
or with comments as was done in this example.
</t>
<t>
Protocol designers should exhibit utmost care when defining CBOR structures with optional variables,
especially when some of these variables have the same datatype.
</t>
<t>
For example,
the following CBOR data structure is ambiguous:
<figure>
<artwork align="center"><![CDATA[
*DataStruct {
?OptionalVariable : uint;
MandatoryVariable : uint;
?AnotherOptionalVariable : uint;
}
]]></artwork>
</figure>
</t>
<t>
Since optional variables are often detected from their datatype,
it is RECOMMENDED to not have a following of multiple variables of the same datatype,
when some of these variables are optional.
</t>
</section>
</section>
<section title="Examples">
<t>
This section contains various examples of structures defined using the CBOR notational convention.
</t>
<section title="Moves in a computer game">
<t>
A multiplayer computer game uses CBOR to exchange moves between the players.
To ensure a good gaming experience,
the move information needs to be exchanged quickly and frequently.
Therefore,
the game uses CBOR to send its information in a compact format.
<xref target="ComputerGameDef"/> shows definition of the CBOR information exchange format.
</t>
<t>
<figure title="CBOR definition of an information exchange format for a computer game" anchor="ComputerGameDef">
<artwork align="center"><![CDATA[
*UpdateMsg {
move_no : uint; # increases for each move
player_info : PlayerInfo; # general information
moves : Moves*; # moves in this message
}
PlayerInfo {
alias : tstr;
player_id : uint;
experience : uint; # beginner: 0; expert: 3
gold : uint;
supplies : Supplies;
avg_strength : float(16);
}
Supplies : map( uint ) {
0 : uint; # wood
1 : uint; # iron
2 : uint; # grain
}
*Moves {
unit_id : uint;
unit_strength : uint; # between 0 and 100
source_pos : uint[2]; # (x,y)
target_pos : uint[2]; # (x,y)
}
]]></artwork>
</figure>
</t>
<t>
Notice that the supplies have been encoded as a map with integer keys.
In this example,
using string keys would also have been suitable.
However,
the example illustrates the possibility to use other datatypes for keys,
leading to more efficient encoding.
</t>
<t>
Player "Johnny" does two moves.
The game server has assigned Johnny the ID 0x7a3b871f.
Johnny is an amateur player,
so has experience 1.
He currently has 1200 gold,
13 units of wood,
70 units of iron and
29 units of grain.
He has several units,
with a total average strength of 30.25.
</t>
<t>
The units Johnny plays in move 250 are the unit with ID 19, strength 20 from (5,7) to (6,9),
and the unit with ID 87, strength 40 from (7,10) to (6,10).
</t>
<t>
This information is coded in CBOR as depicted in <xref target="ComputerGameInst"/>.
<figure title="CBOR instance for game example" anchor="ComputerGameInst">
<artwork align="center"><![CDATA[
9F
18 FA # move 250
66 4A 6F 68 6E 6E 79 # "Johnny"
1A 7A 3B 87 1F # player_id
01 # experience
19 04 B0 # 1200 gold as uint
A3 # begin map "supplies" with 3 elements
00 # wood:
0C # 13 as uint
01 # iron:
18 86 # 70 as uint
02 # grain:
18 1D # 29 as uint
F9 4F 90 # average strength 30.25 half-precision float
9F # indefinite length "moves" array
84 # 4-element array Moves
13 # unit id 19 as uint
14 # strength 20 as uint
82 # 2-element array source_pos
05 # source_pos.x=5
07 # source_pos.y=7
82 # 2-element array target_pos
06 # target_pos.x=6
09 # target_pos.y=9
84 # 4-element array Moves
18 57 # unit id 87
18 28 # strength 40
82 # 2-element array source_pos
07 # source_pos.x=7
0a # source_pos.y=10
82 # 2-element array target_pos
06 # target_pos.x=6
0a # target_pos.y=10
FF # end of "moves" array
FF
]]></artwork>
</figure>
</t>
</section>
<section title="Fruit">
<t>
<xref target="exCBORstruct"/> contains an example for a CBOR structure that contains information about fruit.
<figure title="Example CBOR structure" anchor="exCBORstruct">
<artwork align="center"><![CDATA[
fruitlist : Fruit*;
*Fruit {
name : FruitName;
colour : uint;
avg_weight : float( 16 );
price : uint;
international_names : map( Lang, tstr );
rfu : bstr; # reserved for future use
}
FruitName : map( tstr ) {
"CN" : tstr; # Chinese
"NL" : tstr; # Dutch
"EN" : tstr; # English
"FR" : tstr; # French
"DE" : tstr; # German
}
]]></artwork>
</figure>
</t>
<t>
The colour integer can have the values from <xref target="colourVal"/>.
</t>
<texttable anchor="colourVal" title="Possible values for the colour field">
<ttcol align='left'>Colour</ttcol>
<ttcol align='left'>Value</ttcol>
<c>black</c>
<c>0</c>
<c>red</c>
<c>1</c>
<c>green</c>
<c>2</c>
<c>yellow</c>
<c>3</c>
<c>blue</c>
<c>4</c>
<c>magenta</c>
<c>5</c>
<c>cyan</c>
<c>6</c>
<c>white</c>
<c>7</c>
<c>orange</c>
<c>8</c>
<c>pink</c>
<c>9</c>
<c>purple</c>
<c>10</c>
<c>brown</c>
<c>11</c>
<c>grey</c>
<c>12</c>
</texttable>
<t>
For example,
apples can be red, yellow or green.
They have an average weight of 0.195kg and a price of 30 cents.
Chinese for "apple" in UTF-8 is [ E8 8B B9 E6 9E 9C ],
the Dutch word is "appel" and the French word "pomme".
</t>
<t>
For simplicity,
let's assume that the colour of oranges can only be orange.
They have an average weight of 0.230kg and a price of 50 cents.
Chinese for "orange" in UTF-8 is [ E6 A9 99 E5 AD 90 ],
the Dutch word is "sinaasappel" and the German word "Orange".
</t>
<t>
This information would be encoded as depicted in <xref target="exCBORinstance"/>.
<figure title="Example CBOR instance" anchor="exCBORinstance">
<artwork align="center"><![CDATA[
9F # indefinite length "fruitlist" array
86 # First "Fruit" instance, 6 elements
65 # text string "name" length 5
61 70 70 6C 65 # "apple"
83 # array for "Colour", 3 elements
01 # "red" as uint
02 # "green" as uint
03 # "yellow" as uint
F9 # Floating point half precision
32 3D # "avg_weight" 0.195
18 1E # "price" 30 as uint
A3 # map "international_names", 3 pairs
62 43 4E # text string length 2, "CN"
66 E8 8B B9 E6 9E 9C # Chinese word for apple
62 4E 4C # "NL"
65 61 70 70 65 6C # "appel"
62 46 52 # "FR"
65 70 6F 6D 6D 65 # "pomme"
40 # byte string "rfu", 0 bytes length
86 # Second "Fruit" instance
66 # text string "name" length 6
6F 72 61 6E 67 65 # "orange"
81 # array for "Colour", 3 elements
08 # "orange" as uint
F9 # Floating point half precision
33 5C # "avg_weight" 0.230
18 32 # "price" 50 as uint
A3 # map "international_names", 3 pairs
62 43 4E # text string length 2, "CN"
66 E6 A9 99 E5 AD 90 # Chinese word for orange
62 4E 4C # "NL"
6B 73 69 6E 61 61 73 61 70 70 65 6C # "sinaasappel"
62 44 45 # "DE"
66 4F 72 61 6E 67 65 # "Orange"
40 # byte string "rfu", 0 bytes length
FF # end of "fruitlist" array
]]></artwork>
</figure>
</t>
<t>
Notice that if the "Fruit" structure did not have the preceding "*",
the two "Fruit" instance arrays would have been omitted.
In addition,
the "fruitlist" array would have had 12 elements instead of 2.
(Although for "fruitlist" the indefinite length approach was chosen,
such that the number of elements is not explicitely signalled.)
</t>
</section>
</section>
<section title="Philosophy">
<t>
The CBOR notational convention can be used to efficiently define the layout of CBOR data.
</t>
<t>
In addition,
it has been specified such that a machine can verify whether or not CBOR data is compliant to its definition.
The thoroughness of this compliance verification depends on the application.
</t>
<t>
For example,
an application may decide not to verify the data structure at all,
and use the CBOR content rules solely as a means to indicate the structure of the data to the programmer.
</t>
<t>
On the other end,
the application may also implement a verification method that goes as far as verifying that all mandatory map keys are available.
</t>
<t>
The matter in how far the data description must be enforced by an application is left to the implementers and specifiers of that application.
</t>
</section>
<section title="Open Issues">
<t>
At least the following issues need further consideration:
<list style="symbols">
<t>
Whether to remove optional variables (other than in maps).
</t>
<t>
More extensive security considerations.
</t>
<t>
Consider whether structures without encapsulating CBOR array encoding should be omitted.
</t>
</list>
</t>
</section>
<section title="Change Log">
<t>
Changes from version 00 to version 01
<list style="symbols">
<t>Removed constants</t>
<t>Updated the tag mechanism</t>
<t>Extended the map structure</t>
<t>Added examples</t>
</list>
</t>
</section>
<section title="Security considerations">
<t>
This document presents a content rules language for expressing CBOR data structures.
As such,
it does not bring any security issues on itself,
although specification of protocols that use CBOR naturally need security analysis when defined.
</t>
</section>
<section title="IANA considerations">
<t>
This document does not require any IANA registrations.
</t>
</section>
<section title="Acknowledgements">
<t>
For this draft,
there has been inspiration from the
C and Pascal languages,
MPEG's conventions for describing structures in the ISO base media file format,
and Andrew Lee Newton's "JSON Content Rules" draft.
</t>
<t>
Useful feedback came from Carsten Bormann and Joe Hildebrand.
</t>
</section>
</middle>
<back>
<references title="Normative References">
&RFC2119;
&RFC7049;
</references>
</back>
</rfc>| PAFTECH AB 2003-2026 | 2026-04-23 05:18:59 |