Technical topic: Hints to model complex packet encodings with ASN.1 and ACN

Revision as of 11:41, 8 June 2018 by Mperrotin (talk | contribs)
Jump to: navigation, search

In this page we are giving recipes and hints to help making use of ASN.1 and ACN to model complex packet structures. The example is based on the ECSS Standard named "PUS-C". This standard defines the packet structure for Telecommand and Telemetries used to exchange data between the Earth and Satellites.

Context: Legacy Binary Encodings

ASN.1 is providing simple contructs to define data types which are independent from implementation languages. ASN.1 helps focusing on your application semantics rather than on how data will eventually be physically represented in memory, for example for network transmission.

This is essential in any kind of distributed systems and embedded systems in general. When you want to send a meaningful set of data over a physical link, you can never count on how your local machine will store it. For example, if you use a type named "t_int16" in your code, you can never be sure that is you memory-dump it and send it as-is to a remote node that it will be properly decoded. Why? Because some machine would store the first byte first followed by the other one, while other would do the opposite. This is one example (endianness), but there are many others.

In some situations (actually, most of the time), you need to comply to some pre-established encoding rules, that are explicitly telling you, for a given protocol, how each packet shall be encoded.

ASN.1 is widely used and is popular because it provides built-in standard encoding rules that range from compact binary encoding (uPER, standing for unaligned Packed Encoding Rules) to ugly verbose XML encodings. Many telecommunication protocols are using these encoding rules. They allow users to rely on existing tools - you provide your ASN.1 grammar, and the tools provide encoders and decoders following the standard, therefore ensuring inter-operability.

However sometimes this is not sufficient... Some communication protocols (too many...) come with custom, proprietary encoding rules that are incompatible with any existing standard. In those situations, the usual approach consists in hand-writing binary encoding/decoding functions. ASN.1 may look far less relevant in that case, as automation can hardly be achieved...

Well, this is not exactly true. ASN.1 has two options to deal with that family of problems (legacy encodings). The ECN language (Encoding Control Notation) is a full-blown ISO standard that allows to formally describe custom encoding rules. It is powerful, but also extremely complex. ACN, on the other hand, is a light, free and open-source language that was developed by the European Space Agency to cover the same need but in a more user-friendly way (simple syntax and less features).

The Packet Utilization Standard (PUS-C)

The PUS-C is a 600+ pages standard that was designed by European Space industries and agencies to have common grounds to control satellites in orbit. It details a number of services that have to be implemented in space systems, for example for monitoring the health of instruments in space, for patching memory areas, or for executing functions on-board.

A large part of the standard defines the bit layout of the telecommand and telemetry packets... Which makes it the perfect candidate for ASN.1 and ACN modelling. ACN was in fact originally created to support the automatic generation of PUS packets from C and Ada applications...

ASN.1 and ACN : the approach

The PUS packets look like this:


Using ASN.1 you represent only the so-called application semantics. This means you first remove all the fields that have no interest to the end user of the packet (padding fields, length fields, etc.). This leaves you with a clean data structure that keeps only useful information that your application will process.

(add ASN.1 example)


The missing fields are later added in the ACN model. ACN allows to link fields together, define their relative position in the packet, and specify how many bits are needed for each of them.


The ASN.1 compiler then takes the ASN.1 and ACN models and generate code, documentation and test scripts. The code contains data structure (in C or in Ada) corresponding to the ASN.1 model, as well as functions to make a binary representation of the packets that is compliant to the description provided in the ACN model (representing in our case the complete PUS packets).

The following section gives an example to create proper ASN.1 and ACN models for PUS.

How to start?

There are of course several ways to deal with the PUS modelling. You have the possibility to define your own level of granularity in the models, and decide yourself what are the fields which matter to you for your application. However, a very important design driver should be to avoid repeating information and to keep the models as simple as possible - to ease the maintenance effort, namely.

1. PUS is based on high-level services that group functionalities of the same kind as "subservices" => mimic this structure using ASN.1 CHOICEs. 2. Create a aggregation of all high-level services 3. Create a SEQUENCE (record) container that contains additional fields possibly needed by PUS users 4. Some PUS services use project-specific data (constants, dedicated types) => use ASN.1 Templates (parameterized types) for that purpose 5. Create an ACN model to describe the actual PUS packets