Pprzlink

From PaparazziUAV
Jump to navigation Jump to search

PPRZLINK is the communication library used by the Paparazzi UAV project and other related projects.

It provides:

  • Bulleted list item
  • a set of messages definitions
  • various encapsulation protocols
  • several high-level access to physical layers (serial, udp, Ivy)
  • several language support (Ocaml, C, Python)

Source code can be download from Github: https://github.com/paparazzi/pprzlink

The creation of PPRZLINK as a separated project from the main Paparazzi source code is the result of the communication roadmap. At the moment it is released under GPL v2, but it may be changed to LGPL in order to ease integration into third-party projects.

A (not very complete) documentation is also available on the readthedocs platform.

Some useful related project:


Messages' definition

The messages are organized three main classes:

  • telemetry: messages sent by the aircraft, usually to the ground, a.k.a. downlink stream
  • datalink: messages sent by the ground to the aircraft, a.k.a. uplink
  • ground: messages exchanged between ground agents over the Ivy software bus

Pprz communication agents.gif

The generated documentation is available here: http://docs.paparazziuav.org/latest/paparazzi_messages.html

New messages can be integrated mainstream in the messages xml file from PPRZLINK. When using with Paparazzi, it is also possible to use an temporary file placed in the conf folder. If not present, the default set is used.

Protocols

Principles

PPRZLINK is based on encapsulation. The first layer is the message level, mostly containing the data and the required information to decode them. The structure of this part is always the same. The second layer called transport can be changed according to the actual physical layer being used. The basic type (pprz) is just providing synchronization byte and checksum, but other transports offer more possibility of routing like the XBee' transport (especially the possibility to use point-to-point or broadcast).

The message formats are described here. A secured version is currently under development.

Differences between version 1 and 2

A new version (v2) have been developed to overcome several limitations. With version 1, only the message ID (1 byte) and the sender ID (1 byte) are provided in the message layer before the data part. It means that:

  • messages can't be addressed to a particular receiver unless the transport layer can provide the service
  • it is not possible to determine the class of messages, so it is assumed that telemetry messages are strictly downlink and datalink messages strictly uplink, thus preventing direct air-to-air communications

With the version two of the protocol, two extra bytes have been added to the message header:

  • the receiver ID (1 byte)
  • a class ID (4 bits)
  • a component ID (4 bits)

The class and component are part of the same byte. Even if the component ID is not really used at the moment (provision for future use), the class ID avoid ambiguities on messages. With the receiver ID, it is now possible to perform air-to-air communications and to broadcast messages from an aircraft (previously only possible from the ground).

See messages format page for more details.

Interfaces

Currently, the available interfaces are:

  • serial stream
  • udp packet
  • Ivy based messages (publisher/subscriber middelware over TCP/IP, should only be used on the ground side)

In addition a bridge to the ROS middleware is available at https://github.com/enacuavlab/pprzros

Language supports

The supported languages are:

  • C language
    • generation of code (header files) for sending and decoding messages
    • mostly used for the airborne code of Paparazzi
  • Ocaml
    • library based high-level functions for binding, subscribing and parsing messages
    • mostly used by the ground station agents: links, GCS, server, ...
  • Python
    • Provide similar functionality than the Ocaml implemetation
    • used in a large variety of smaller tools and ground agents
  • Rust
    • similar to Python implementation, plus added memory safety
    • used mainly for secure pprzlink (see below)

Secure Ppprzlink

Secure Paparazzi link uses symmetric key encryption with Chacha20 cipher.

s-pprzlink uses a formally verified cryptographic library HACL* developed by the Prosecco team at INRIA Paris in collaboration with Microsoft Research, as part of Project Everest.

Because certain data have to be sent in plaintext (such as the message counter), s-pprzlink uses Authenticated Encryption with Associated Data (AEAD) algorithm to authenticate such data before use. Authentication means that any unauthorized change in data is detected upon decryption. Authentication is important because if we decide to send SENDER_ID or DESTINATION_ID in plaintext - so the receiver can decide whether to decrypt the message - we don't want it to be tampered with. s-pprzlink uses a modified Galois Embedded Crypto algorithm for the symmetric key exchange.

The overhead for encrypted communication is 21 bytes (1 byte signaling crypto/plaintext message, 4 bytes of the counter, 16 bytes of the authentication tag), for plaintext messages (such as key-exchange and some info messages) is only one byte.


Installation

Secure link requires Rust. The recommended way to install Rust on your computer is via rustup.rs. The rest is handled by the paparazzi build system.

Message Format

Secure link is simply a wrapper around pprzlink message. The main difference is an additional CRYPTO BYTE which determines whether the message is encrypted (CRYPTO BYTE=0xaa) or not (CRYPTO BYTE=0x55). If the message is not encrypted, the rest of the message is identical to a standard pprzlink message (SOURCE_ID .. optional MSG Payload) as shown below.

If the message is encrypted, we add 4 bytes of message counter (which is also used as IV for encryption/decryption), and 16 bytes of authentication tag (to authenticate the message before decryption). The counter is transmitted in plaintext and is not authenticated, because if it is tampered with, the decryption will fail. Message routing information (SENDER ID and DESTINATION ID) are transmitted in plaintext so the message can be properly routed in multi-node network, but the data are authenticated - so any change is detected before decryption occurs (thus discarding the whole message). The message structure is shown below (note that Pprzlink 2.0 is the default version for Paparazzi).

Pprzlink 1.0

S-Pprzlink v1.0
byte Value Type
0 PPRZ_STX (0x99) Header
1 length N (PPRZ_STX->checksum B) Header
2 crypto byte Crypto byte
3 counter LSB 1 Counter
4 counter LSB 2 Counter
5 counter LSB 3 Counter
6 counter LSB 4 Counter
7 source ID Authenticated data
8 message ID Encrypted payload
9..(N-16) (optional) message payload (0-234 bytes) Encrypted payload
(N-15)..(N-2) tag (16 bytes) Authentication tag
N-1 checksum A Header
N checksum B Header


Pprzlink 1.0 plaintext message
Pprzlink 1.0 encrypted message


Pprzlink 2.0

S-Pprzlink v2.0
byte Value Type
0 PPRZ_STX (0x99) Header
1 length N (PPRZ_STX->checksum B) Header
2 crypto byte Crypto byte
3 counter LSB 1 Counter
4 counter LSB 2 Counter
5 counter LSB 3 Counter
6 counter LSB 4 Counter
7 source ID Authenticated data
8 destination ID Authenticated data
9 class component Encrypted payload
10 message ID Encrypted payload
11..(N-16) (optional) message payload (0-234 bytes) Encrypted payload
(N-15)..(N-2) tag (16 bytes) Authentication tag
N-1 checksum A Header
N checksum B Header


Pprzlink 2.0 plaintext message
Pprzlink 2.0 encrypted message

Encryption and Key exchange

TODO

Pprzlink proxy

When using several UAVs using UDP communication (or NPS simulations), the functionalities provided by the server agent is enough as long as there is no direct (air-to-air) communications (using v2 protocol). Otherwise, each UAV have to be accessed based on it's IP address or a specific port when simulating several aircraft on the same computer. The connections between the ground and airborne agents then have to be done through the Pprzlink_proxy tool by associating the aircraft IDs with output and input ports (and eventually an IP address if different from the default value).

Here is a list of usage examples:

./pprzlink_proxy.py --ac=101:4244:4245 --ac=102:4256:4247
./pprzlink_proxy.py --ac=101:4244:4245 --ac=102:4256:4247 --addr=192.168.1.1
./pprzlink_proxy.py --ac=101:4244:4245 --ac=102:192.168.1.2:4256:4247 --gcs=192.168.1.2
./pprzlink_proxy.py --script=proxy.txt

where 'proxy.txt' contains a list of parameters with the same format than the command line options (possibly one per line) and

./pprzlink_proxy.py -h

will show the complete list of options.