Abstract Syntax Notation One (ASN.1) - The Tutorial and Reference
Abstract Syntax Notation One (ASN.1) - The Tutorial and Reference
1)
- The Tutorial and Reference by Doug Steedman
https://www.bgbm.org/TDWG/acc/Documents/asn1gloss.htm
Development Phase
Source Language (e.g. “C”)
Data Structures
ASN.1 ASN.1
Definitions Compiler
Encoder
Encoder
Encoder
Decoder
Decoder
Decoder
Run-Time
Encoded Octets (e.g. using BER)
Parameterized
Source Language Encoder
Data Structure Decoder
WeatherReport ::=SEQUENCE
{
stationNumber INTEGER (1..99999),
timeOfReport UTCTime,
pressure INTEGER (850..1100),
temperature INTEGER (-100..60),
humidity INTEGER (0..100),
windVelocity INTEGER (0..500),
windDirection INTEGER (0..48)
}
WeatherReport ::=SEQUENCE
{
stationNumber INTEGER (1..99999),
timeOfReport UTCTime
pressure INTEGER (850..1100)
temperature INTEGER (-100..60)
humidity INTEGER (0..100)
windVelocity INTEGER (0..500)
windDirection INTEGER (0..48)
}
defines a type called WeatherReport. Everything following the "::=" constitutes valid type notation (for
a structured type which comprises a sequence of simple and structured types).
A value assignment is similar, but has an additional syntactic component: the type to which the value
belongs. This appears between the value reference (the name being allocated to the value), and the
"::=". For example:
sampleReport WeatherReport::=SEQUENCE
{
stationNumber 73290
timeOfReport "900102125703Z",
pressure 1056,
temperature -3,
humidity 26,
windVelocity 15,
windDirection 0
}
defines a value of type WeatherReport called sampleReport. The characters after the "::=" constitute
valid notation for a value of WeatherReport.
The definition of types and values is almost the only thing that ASN.1 users do. Of these two, the
definition of types predominates. This is because an abstract syntax itself is a type, as are its
components, and their components, and so on. In a specification, it is the types, the sets of possible
values, which are most significant. Individual values only appear as examples and defaults. Consider
how much more useful in a specification is the type INTEGER than the particular value 314 (or any
other integer value for that matter). Conversely, in instances of communication it is values which are
significant.
E.2.2 Subtypes
Frequently the designer intends only some subset of the values of an ASN.1 type to be valid in some
situation. For instance, in conveying a measure of humidity as a percentage, only numbers in the range
0 to 100 are valid, or when conveying a postal code only strings with certain characters and whose
length falls within a certain range are to be permitted. Perhaps when some protocol message is used in
a certain context, the optional checksum field is to be absent.
These are all examples of constraints which can be expressed by defining a subtype of a suitable parent
type. This is done by appending to the notation for the parent a suitable subtype specification. The
result is itself a type and can be used anywhere a type is allowed. (Thus a subtype specification can also
be applied to a subtype, in which case it may serve to further reduce the set of values).
A subtype specification consists of one or more subtype value sets, separated by "|" (pronounced "or").
The whole list is in round brackets(()).
For example in:
Weekend ::= DaysOfTheWeek (saturday | sunday)
the type Weekend is defined by appending a subtype specification to a parent type DaysOfTheWeek.
The subtype specification (the expression in round brackets) defines which of the values of
DaysOfTheWeek are also to be values of Weekend.
There are six different value set notations. Two of these are applicable to all parent types, others to only
certain parent types.
The value set notations that are applicable to all parent types are single value and contained subtype.
The former notation is simply some value of the a parent type, the resulting value set consisting of that
value alone. Examples of this are "saturday" and "sunday" above, each of which is a single value of
DaysOfTheWeek. The contained subtype notation comprises the keyword INCLUDES, followed by
some other subtype of the same parent type, and denotes the value set consisting of all the values in that
subtype.
For example, given:
LongWeekend ::= DaysOfTheWeek
(INCLUDES Weekend | monday)
the type LongWeekend includes the three values saturday, sunday, and monday, the union of the value
sets used in its definition
Each value set defines some subset of the values of the parent type. The resulting subtype has the
values in the union of these subsets, which must be non-empty..
The value range notation can be used to subtype any type whose values are ordered (for example, the
integer type). It involves specifying the lower and upper bounds of the range.
A size range can be included for any type whose values have a defined size (for example, the bit string
type). Here the value set includes all of the values whose size, measured in the appropriate units, is
within the designated range.
An alphabet limitation can be applied only to character string types and allows only the values formed
from some subset of the characters.
Finally, inner subtyping can be employed to define value sets of structured types (for example, set and
set-of-types). Here the value set includes all those values whose component values meet certain
constraints.
E.2.3 Names
Several categories of object in ASN.1 have names by which they can be referenced. We have actually
met examples of each of these kinds of name above, as follows:
The first character in a name must be a letter. The case of the letters in a name is significant, so that
"borders" and "Borders" are different names. In fact the case of the initial letter is of special
significance, as type references (and also module references, see below) must start with an upper-case
letter, while value references and identifiers must start with a lower-case letter. It is not a good idea,
however, to use two or more names which differ only by the case of some of their letters.
The names chosen by users must be chosen so as to avoid clashing with the reserved words of ASN.1
(which include most of the keywords of the language). Since the keywords are generally in upper-case,
the use of lower-case letters in names makes it easy to adhere to this, and also generally makes the
names more readable. There is no upper limit on the length of names, and this allows the use of an
appropriate phrase as the name of an object.
Examples of legal (and probably appropriate) names are:
UnformattedPostalAddress
Access-control-list
ACL
Temperature
MverifyPDU
recordLow
ib-g3facsimile-non-basic-parameters
The first few of these examples are valid for use as type references, the others as identifiers or value
references.
Notice that two different conventions are used in these examples for forming multi-word names, since
spaces are not valid in names and thus can not be used to separate the individual works.
E.2.4 Modules
As with any modern programming language ASN.1 is modular. A module is a named collection of
definitions of types and values (and macros - see next section). A module normally groups together a
set of related definitions, such as all those used in defining some abstract syntax. However, the basis for
grouping definitions into modules is entirely in the hands of the designer, who could put all definitions
into one module, or organise them into several modules, according to taste.
Within a module, definitions can appear in any order, with none of the restrictions sometimes found in
programming languages, such as "define before use". It is up to the designer to organise the definitions
to make the result most understandable to the reader.
All types and values defined in a single module must be allocated distinct references, and within the
module such a reference unambiguously identifies the applicable type or value.
A module consists of, in order: the module identifier; the keyword DEFINITIONS; optionally, the tag
style default; the symbol "::="; the module body. The module body consists of the exports and imports
statements, if any, followed by the type and value assignments, all enclosed between BEGIN and END.
An example of a module is as follows. The component parts - what should be inside the second and
third curly brackets - are omitted, but see Section E.2.1 for what would be entered.
WeatherReporting {2 6 6 247 1} DEFINITIONS ::=
BEGIN
WeatherReport ::= SEQUENCE { ..... }
sampleReport WeatherReport ::= { .....}
END
The module identifier (which precedes the keyword DEFINITIONS) constitutes the complete and
unambiguous identification of the module. It consists of two components, the first a module reference
and the second an object identifier value; in the example they are WeatherReporting and {2 6 6 247 1}
respectively.
A module reference is the same (syntactically) as a type reference. The module reference should be
chosen so as to be suggestive of the contents of the module in some way, and, if possible,
unambiguous.
The other component, the object identifier value, is a globally unique identification for the module,
made up of a sequence of non-negative numbers.
Object Identifier was originally developed as part of the ASN.1 standard, but is now ubiquitous. It is
essential in any global network as it is a unique naming space. It allows any communications object to
be uniquely identified. It is a hierarchical naming space, with the authority to specify Object Identifiers
being passed down the hierarchy. Thus an enterprise may register itself and then sub-allocate number
space to its branches or subsidiaries.
Specifically Object Identifiers are becoming used more and more to identify Managed Objects whether
these are SMTP or ISO Managed Objects. This allows for global network management on the basis that
every type of object has a unique identification.
While the object identifier value is optional, this (being optional) is largely for backwards compatibility
reasons, because it was not present in the first version of ASN.1. In practice it is not a good idea to omit
it.
E.3 Macros
ASN.1 provides a mechanism whereby users can extend the notation for their own use, or for use by
others. This allows the designer to extend the language to define a new "object" such as a modem or a
switch. These have "normal" ASN.1 properties and additional properties such as parenthood and
physical location. For example an "asynchronous modem" may have "generic modem" as a parent. It
inherits properties from the parent. A modem may physically be in the same rack as others and we have
a second hierarchy of physical location. ASN.1’s standard notation itself can be used to define
properties such as:
modem ::= SEQUENCE {
speed INTEGER
modulation IA5 String
manufacturer IA5 String }
but the additional features require the MACRO extensions to specify them. This generates a form of
"template" for the designer to fill in.
A user extending the notation does so by defining one or more macros, using the macro definition
notation (MDN). Each macro has a macro reference (like a type reference except that all letters, not
just the first, must be in upper-case), and grammars for type and value notation. These grammars are
defined by the macro designer using Baccus Naur Format (BNF).
A macro definition can be imported and exported by means of its macro reference, just as with type and
value definitions.
The macro capability provides fairly powerful abilities for the definition of new type and value notation
within ASN.1 modules, with the full power of BNF available to the designer, as well as some powerful
built-in symbols, such as for types and values.
The macro defines a kind of definition form or template for a concept which is more complex than just
an ASN.1 type and value. In fact it is an assemblage of related types and values, related through being
aspects of the same operation.
Such a form or template could clearly have been defined by means outside of ASN.1. However,
because many or all of the aspects of such a concept are specified using ASN.1, it proves very
convenient to be able to include the definition within an ASN.1, module along with the definitions of
the types and values involved. Furthermore, because the use of macros results in ASN.1 types and
values, they can be given reference names, can be included in modules, and can be imported and
exported using all of the same mechanisms already provided in ASN.1.
The macro corresponds to some concept, more complex than a data type, of which users can define
instances. The type notation defines the form or template, with all of the appropriate degrees of
freedom provided. The value notation is almost always an integer or object identifier value which is the
delivered value, and which constitutes the "run-time" identification of the instance.
[This chapter is based on extracts from Doug Steedman's book Abstract Syntax Notation One (ASN.1)
- The Tutorial and Reference, published by Technology Appraisals]
Further Reading
[1] Steedman, Douglas., Abstract Syntax Notation One (ASN.1) - The Tutorial and Reference, Technology Appraisals,
1990.