Warning
This document is still work in progress. All parts are subject to change following working group discussion.
Status | Work In Progress |
---|---|
Author | Michael Romashov |
Updated | 2024-06-02 |
- 1. Introduction
- 2. Data Link
- 3. Functional Specifications
- Appendix A. Valid Message Elements
- Appendix B. Parameter Formats
This document provides the technical specification for the Flight Simulation Data Link Protocol (FSDLP). FSDLP is designed to enable first-class, realistic text-based communications between pilots and controllers when engaging in networked flight simulation activities.
Historically, this niche has been filled by third-party software operating independently of flight simulation networks. However, the increased complexity of virtual aircraft and the general rise in popularity of flight simulation has warranted a solution with improved availability, realism, and ease of implementation that is best suited for network-level implementation.
The idea behind FSDLP is to delegate the role of delivering messages between pilots and controllers to flight simulation networks instead. To ensure compatibility with existing authentication and data exchange schemes, the protocol remains network-agnostic and only requires that a common interface is made available to aircraft through the network's pilot client. It is entirely up to the network to decide how messages are exchanged between peers on the network.
The following documents have been referenced when designing the specification. Access to these documents may or may not be limited.
- ICAO Doc 10037, Global Operational Data Link (GOLD) Manual, First Edition, 2017
- EUROCONTROL Specification on Data Link Services, Edition 2.1, 2009
- DCIT End-to-End Procedures for CPDLC Operations in the US NAS, Version 2.2, 2023
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 RFC 2119.
In this section we provide an abbreviated overview of how data link communications are carried out in the real world.
The pilot client shall bind to local address 127.0.0.1
on any single port in the range [60860, 60864]
, inclusive. Whenever possible, port 60860
should be used since there is generally little chance for collision.
All messages sent through this socket shall be encoded in JavaScript Object Notation (JSON) as per RFC 8259, with the Content-Type: application/json
HTTP header set where applicable.
An identification endpoint is used to verify that a socket is using a specific verison of FSDLP, as well as obtain information about the network it is connected to.
The pilot client must respond to HTTP requests to GET /id
with the following payload:
{
"protocol": "fsdlp",
"version": "1",
"network": "NAME"
}
The network
field should be populated with any string to identify the name of the network. This information may be shown in virtual cockpits when prompting pilots to logon to the data link network.
An additional endpoint is used to facilitate all other communications between the aircraft and pilot client. This endpoint uses the WebSocket protocol as described in RFC 6455 to provide bidirectional and asynchronous messaging.
The pilot client must respond to WebSocket requests to /fsdlp
in accordance with RFC 6455. When performing the WebSocket handshake, the aircraft shall specify fsdlp
as the subprotocol by using the following HTTP header:
Sec-WebSocket-Protocol: fsdlp
If the subprotocol is not specified, or if a value other than fsdlp
is specified, the pilot client shall respond to the request with 400 Bad Request
.
Before an aircraft can perform any communication with an Air Traffic Services Unit (ATSU), it must perform a "logon" to the data link network.
Data link logons are sent by aircraft to an ATSU, or from one ATSU to another. The method used to perform these logons is known as Data Link Initiation Capability (DLIC). Below is a typical exchange between an aircraft and ATSU using DLIC.
---
config:
mirrorActors: false
showSequenceNumbers: true
---
sequenceDiagram
participant U as ATSU
participant D as Aircraft
D -->> U: Logon Request (FN_CON)
U ->> D: Logon Acknowledgement (FN_AK)
All DLIC payloads will have the following form, where:
facility
is a four-character ICAO identifier of the ATSU that is being logged onto,type
is eitherFN_CON
for Logon Request orFN_AK
for Logon Acknowledgement, anddata
is an object whose keys are dependent on thetype
.
{
"method": "",
"payload": {
"type": "",
"facility": "",
"data": {}
}
}
An initial logon request is performed by an aircraft client that does not have an active data link logon, such as when:
- preparing for departure,
- entering an area where data link services are available from an area where they are not,
- or when instructed by ATC (e.g. following a failed data link transfer).
When performing a logon request, the aircraft must provide information that allows the ATSU to link the request to an existing flight plan. This includes:
ident
- the aircraft's callsign, which must match field 7 in an ICAO flight plan;dep_icao
- the four-character ICAO identifier of the departure airfield, which must match field 13 in an ICAO flight plan; andarr_icao
- the four-character ICAO identifier of the arrival airfield, which must match field 16 in an ICAO flight plan.
The payload for a logon request has a type
of FN_CON
, and includes the aforementioned flight plan information in the data
field. Below is an example of a logon request payload:
{
"method": "DLIC",
"payload": {
"type": "FN_CON",
"facility": "KUSA",
"data": {
"ident": "DAL104",
"dep_icao": "KMIA",
"arr_icao": "KBOS"
}
}
}
A logon acknowledgement is sent by an ATSU to an aircraft that has performed a logon request. The acknowledgement has an associated status
that can either be SUCCESS (status code 0
) or FAILURE (status code 1
).
Upon receiving the logon request, the ATSU shall attempt to correlate the provided flight information with a filed flight plan. If the logon is successfully correlated, the ATSU responds with status code 0
, otherwise the ATSU responds with status code 1
. ATSUs may also validate aircraft position information to ensure that they are within or near the facility they are attempting to logon to.
The payload for a logon response has a type
of FN_AK
, and includes the status code in the data
field. Below is an example of a logon acknowledgement payload:
{
"method": "DLIC",
"payload": {
"type": "FN_AK",
"facility": "KUSA",
"data": {
"status": 0
}
}
}
There is a special case in which an aircraft must be routed from one ATSU onto another. This occurs when an aircraft is transitioning airspaces managed by different ground stations (e.g. LSAZ to EDMM). In this case, the aircraft does not need to perform a logon request, and this is instead processed by the ground stations.
The key idea behind logon forwarding is that the current ATSU informs the aircraft of the next ATSU using UM160 β NEXT DATA AUTHORITY [facility]
, and then communicates directly with the next ATSU to transfer the logon information provided in the initial logon request. The new ATSU should perform the same data correlation verification as in Section 3.2.2 before initiating a connection request.
Below is a typical exchange between an aircraft and two ATSUs involving logon forwarding. Note that "Connection Request," "Connection Confirm," "Termination Request," and "Termination Confirm" are CPDLC messages, not DLIC, and are discussed in greater detail in Section 3.3.
---
config:
mirrorActors: false
showSequenceNumbers: true
---
sequenceDiagram
participant U1 as ATSU 1
participant D as Aircraft
participant U2 as ATSU 2
Note over U1,D: Existing CPDLC connection
U1 ->> D: UM160 β NEXT DATA AUTHORITY [ATSU 2]
U1 ->> U2: Logon Forwarding
U2 ->> D: Connection Request
D -->> U2: Connection Confirm
U1 ->> D: Termination Request
D -->> U1: Termination Confirm
Note over U2,D: Exchange of CPDLC messages
Since logon forwarding is completely transparent to the aircraft, FSDLP does not make any specific requirements for how this is implemented at the network level.
Each CPDLC message has a Message Identification Number (MIN), which is an integer from 0 to 63. Each time a new message is sent, the MIN shall be incremented modulo 64 to ensure messages can be uniqely identified by both clients.
When a message is sent in response to a previously received message (e.g. ATC replies to a pilot request to climb), the Message Reference Number (MRN) is used to identify the original message.
All CPDLC payloads will have the following form, where:
type
is eitherCR1
,CC1
,DR1
,UP
, orDN
,timestamp
is the Unix timestamp representing when the message was sent,min
is the message identification number,mrn
is either the message reference number ornull
, andelements
is a list of message elements associated with the message.
{
"method": "CPDLC",
"payload": {
"type": "",
"timestamp": 0,
"min": 0,
"mrn": null,
"elements": []
}
}
Downlink messages are sent from aircraft to ATSUs.
Below is an example of a downlink message using DM6 REQUEST [altitude]
:
{
"type": "DN",
"timestamp": 1716857807,
"min": 0,
"mrn": null,
"elements": [
{ "id": "DM6", "parameters": [{ "type": "alt-fl", "fl": 350 }] }
],
}
Uplink messages are sent from ATSUs to aircraft.
Below is an example of a downlink message using UM19 MAINTAIN [altitude]
:
{
"type": "UP",
"timestamp": 1716857807,
"min": 0,
"mrn": null,
"elements": [
{ "id": "UM19", "parameters": [{ "type": "alt-ft", "ft": 5000 }] }
],
}
Once an aircraft successfully performs a logon, it may begin to initiate connections with ATSUs and exchange messages with them.
At any time the aircraft may have at most two connections. Only one of these connections may be active, and the other must remain inactive until a logon forwarding procedure is performed. The active connection is called the Current Data Authority (CDA), and the inactive connection is called the Next Data Authority (NDA).
An aircraft shall only exchange messages with the CDA, with the exception of sending a termination confirmation to a prior CDA once the NDA has been established as the new CDA. If an aircraft receives any CPDLC uplink from the NDA, it must respond with DM63 NOT CURRENT DATA AUTHORITY
.
A connection request message is sent by an ATSU to an aircraft to establish itself as the CDA.
If the aircraft receiving the connection request does not have a CDA, it will:
- respond to the request with a connection confirm message, and
- establish the new connection as the CDA.
If the aircraft receiving the connection request already has a CDA, it will accept the connection request if and only if the requesting ATSU is the NDA. In that case, the aircraft will:
- respond to the request with a connection confirm message,
- send the current CDA a termination confirm message, and
- establish the new connection as the new CDA.
Otherwise, the aircraft will respond with a connection reject message.
Below is an example of a connection request message:
{
"method": "CPDLC",
"payload": {
"type": "CR1",
"elements": []
}
}
A connection confirm message is sent by an aircraft to an ATSU to accept an incoming connection request. Depending on the scenario, this may establish the new connection as either a CDA or NDA.
Below is an example of a connection request message:
{
"method": "CPDLC",
"payload": {
"type": "CC1",
"elements": []
}
}
Optionally containing DM63
{
"method": "CPDLC",
"payload": {
"type": "UPLINK",
"elements": []
}
}
This message must include UM161 END SERVICE
.
This message may optionally include UM117 CONTACT
or UM120 MONITOR
.
{
"method": "CPDLC",
"payload": {
"type": "UP",
"elements": [
{ "id": "UM161", "parameters": [] },
{
"id": "UM117",
"parameters": [
{ "type": "unit", "ident": "EPWW", "name": "WARSZAWA", "func": 0 },
{ "type": "freq-vhf", "vhf": 134875 }
]
}
]
}
}
The termination confirm message must not include any message elements.
{
"method": "CPDLC",
"payload": {
"type": "DR1",
"elements": []
}
}
A termination reject message is sent by an aircraft in response to a termination request from an ATSU. There are two cases where a termination request from an ATSU can be rejected by an aircraft:
-
the ATSU is not the current data authority, in which case the aircraft shall respond with
DM63 NOT CURRENT DATA AUTHORITY
; or{ "type": "DN", "timestamp": 1716857807, "min": 0, "mrn": null, "elements": [ { "id": "DM63", "parameters": [] } ], }
-
the request includes a
UM117 CONTACT
orUM120 MONITOR
message element that the flight crew respond to withDM1 UNABLE
.{ "type": "DN", "timestamp": 1716857807, "min": 0, "mrn": null, "elements": [ { "id": "DM1", "parameters": [] } ], }
ID | Formatted Message | Resp. |
---|---|---|
UM0 | UNABLE | N |
UM1 | STANDBY | N |
UM3 | ROGER | N |
UM4 | AFFIRM | N |
UM5 | NEGATIVE | N |
UM19 | MAINTAIN altitude | W/U |
UM20 | CLIMB TO altitude | W/U |
UM23 | DESCEND TO altitude | W/U |
UM26 | CLIMB TO REACH altitude BY time | W/U |
UM27 | CLIMB TO REACH altitude BY position | W/U |
UM28 | DESCEND TO REACH altitude BY time | W/U |
UM29 | DESCEND TO REACH altitude BY position | W/U |
UM30 | MAINTAIN BLOCK altitude TO altitude | W/U |
UM31 | CLIMB TO AND MAINTAIN BLOCK altitude TO altitude | W/U |
UM32 | DESCEND TO AND MAINTAIN BLOCK altitude TO altitude | W/U |
UM36 | EXPEDITE CLIMB TO altitude | W/U |
UM37 | EXPEDITE DESCENT TO altitude | W/U |
UM38 | IMMEDIATELY CLIMB TO altitude | W/U |
UM39 | IMMEDIATELY DESCEND TO altitude | W/U |
UM46 | CROSS position AT altitude | W/U |
UM47 | CROSS position AT OR ABOVE altitude | W/U |
UM48 | CROSS position AT OR BELOW altitude | W/U |
UM49 | CROSS position AT AND MAINTAIN altitude | W/U |
UM51 | CROSS position AT time | W/U |
UM52 | CROSS position AT OR BEFORE time | W/U |
UM53 | CROSS position AT OR AFTER time | W/U |
UM54 | CROSS position BETWEEN time AND time | W/U |
UM55 | CROSS position AT speed | W/U |
UM56 | CROSS position AT OR LESS THAN speed | W/U |
UM57 | CROSS position AT OR GREATER THAN speed | W/U |
UM61 | CROSS position AT altitude AT speed | W/U |
UM64 | OFFSET distance direction OF ROUTE | W/U |
UM72 | RESUME OWN NAVIGATION | W/U |
UM74 | PROCEED DIRECT TO position | W/U |
UM75 | WHEN ABLE PROCEED DIRECT TO position | W/U |
UM76 | AT time PROCEED DIRECT TO position | W/U |
UM77 | AT position PROCEED DIRECT TO position | W/U |
UM78 | AT altitude PROCEED DIRECT TO position | W/U |
UM79 | CLEARED TO position VIA route clearance | W/U |
UM80 | CLEARED route clearance | W/U |
UM81 | CLEARED procedure | W/U |
UM82 | CLEARED TO DEVIATE UP TO distanceoffset direction OF ROUTE | W/U |
UM83 | AT position CLEARED route clearance | W/U |
UM84 | AT position CLEARED procedure | W/U |
UM91 | HOLD AT position MAINTAIN altitude INBOUND TRACK degrees direction TURN LEG TIME leg type | W/U |
UM92 | HOLD AT position AS PUBLISHED MAINTAIN altitude | W/U |
UM93 | EXPECT FURTHER CLEARANCE AT time | R |
UM94 | TURN direction HEADING degrees | W/U |
UM96 | CONTINUE PRESENT HEADING | W/U |
UM106 | MAINTAIN speed | W/U |
UM107 | MAINTAIN PRESENT SPEED | W/U |
UM108 | MAINTAIN speed OR GREATER | W/U |
UM109 | MAINTAIN speed OR LESS | W/U |
UM116 | RESUME NORMAL SPEED | W/U |
UM117 | CONTACT unit name frequency | W/U |
UM120 | MONITOR unit name frequency | W/U |
UM123 | SQUAWK beacon code | W/U |
UM127 | REPORT BACK ON ROUTE | R |
UM134 | CONFIRM SPEED | NE |
UM135 | CONFIRM ASSIGNED ALTITUDE | NE |
UM137 | CONFIRM ASSIGNED ROUTE | NE |
UM148 | WHEN CAN YOU ACCEPT altitude | NE |
UM153 | ALTIMETER altimeter | R |
UM154 | RADAR SERVICES TERMINATED | R |
UM157 | CHECK STUCK MICROPHONE frequency | R |
UM159 | ERROR error information | N |
UM160 | NEXT DATA AUTHORITY facility ident | N |
UM161 | END SERVICE | N |
UM166 | DUE TO TRAFFIC | N |
UM167 | DUE TO AIRSPACE RESTRICTION | N |
UM179 | SQUAWK IDENT | W/U |
UM183 | CURRENT ATC UNIT unit name | N |
UM169 | free text | R |
ID | Formatted Message | Resp. |
---|---|---|
DM0 | WILCO | N |
DM1 | UNABLE | N |
DM2 | STANDBY | N |
DM3 | ROGER | N |
DM4 | AFFIRM | N |
DM5 | NEGATIVE | N |
DM6 | REQUEST altitude | Y |
DM7 | REQUEST BLOCK altitude TO altitude | Y |
DM9 | REQUEST CLIMB TO altitude | Y |
DM10 | REQUEST DESCENT TO altitude | Y |
DM11 | AT position REQUEST CLIENT TO altitude | Y |
DM12 | AT position REQUEST DESCENT TO altitude | Y |
DM13 | AT TIME time REQUEST CLIMB TO altitude | Y |
DM14 | AT TIME time REQUEST DESCENT TO altitude | Y |
DM15 | REQUEST OFFSET distance direction OF ROUTE | Y |
DM18 | REQUEST speed | Y |
DM20 | REQUEST VOICE CONTACT | Y |
DM22 | REQUEST DIRECT TO position | Y |
DM23 | REQUEST procedure | Y |
DM24 | REQUEST route clearance | Y |
DM25 | REQUEST CLEARANCE | Y |
DM27 | REQUEST WEATHER DEVIATION UP TO distance direction OF ROUTE | Y |
DM34 | PRESENT SPEED speed | N |
DM38 | ASSIGNED ALTITUDE altitude | N |
DM40 | ASSIGNED ROUTE route clearance | N |
DM41 | BACK ON ROUTE | N |
DM55 | PAN PAN PAN | N |
DM56 | MAYDAY MAYDAY MAYDAY | N |
DM57 | fuel OF FUEL REMAINING AND souls ON BOARD | N |
DM58 | CANCEL EMERGENCY | N |
DM59 | DIVERTING TO position VIA route clearance | N |
DM60 | OFFSETTING distance offset direction OF ROUTE | N |
DM61 | DESCENDING TO altitude | N |
DM62 | ERROR error information | N |
DM63 | NOT CURRENT DATA AUTHORITY | N |
DM65 | DUE TO WEATHER | N |
DM66 | DUE TO AIRCRAFT PERFORMANCE | N |
DM77 | ASSIGNED BLOCK altitude TO altitude | N |
DM80 | DEVIATING distance offset direction OF ROUTE | N |
DM107 | NOT AUTHORIZED NEXT DATA AUTHORITY | N |
DM67 | free text | N |
DM68 | free text | Y |
Name | Remarks | Format |
---|---|---|
altimeter | Altimeter in inHg (1 unit = 0.01 inHg)(INT 2500..3100) |
{"type": "qnh-inhg", "inhg": 2992} |
Altimeter in hPa (1 unit = 1 hPa)(INT 850..1050) |
{"type": "qnh-hpa", "hpa": 1013} |
|
altitude | Altitude in feet(INT 0..25,000) |
{"type": "alt-ft", "ft": 5000} |
Altitude in flight level(INT 30..600) |
{"type": "alt-fl", "fl": 360} |
|
degrees | Degrees from magnetic North(INT 1..360) |
{"type": "degrees", "deg": 180} |
beacon code | Transponder code(INT 0..7777) |
{"type": "beacon", "code": 7500} |
distance | Distance in nautical miles (1 unit = 0.1 nmi)(INT 0..9999) |
{"type": "distance", "nmi": 30.5} |
direction |
Enumerated directions:
|
{"type": "direction", "dir": 0} |
error information | Error message | {"type": "error", "error": "UNRECOGNIZED MSG REFERENCE NUMBER"} |
facility ident | ICAO facility designation | {"type": "facility", "ident": "LKAA"} |
free text | Free text | {"type": "text", "text": "HELLO, WORLD!"} |
frequency | HF frequency (1 unit = 1 kHz)(INT 2850..28000) |
{"type": "freq-hf", "hf": 13306} |
VHF frequency (1 unit = 1 kHz, precision = 25 kHz)(INT 118000..136975) |
{"type": "freq-vhf", "vhf": 121900} |
|
position | ICAO fix name | {"type": "pos-fix", "fix": "LENDY"} |
ICAO navaid identifier | {"type": "pos-navaid", "navaid": "CRI"} |
|
ICAO airport code | {"type": "pos-airport", "airport": "KJFK"} |
|
Latitude and longitude(FLOAT, FLOAT) |
{"type": "pos-latlon", "lat": 40.6446, "lon": -73.7797} |
|
Place, bearing, and distance | {"type": "pos-pbd", "place": 6, "bearing": 35, "dist": 5.5} |
|
procedure | Standard procedure identifier (i.e. arrival, approach, departure) | {"type": "procedure", "type": TODO, "name": "LENDY8", "transition": null} |
route | Route clearance | {"type": "route", "dep_arpt": "", "dep_rwy": "", "dep_proc": "", "app_proc": "", "arr_proc": "", "airway": "", "seq": "", "additional": ""} |
speed | Indicated airspeed in knots (1 unit = 10 kts)(INT 7..38) |
{"type": "speed-kts", "kts": 6} |
Indicated airspeed in mach (1 unit = 0.01 mach)(INT 61..99) |
{"type": "speed-mach", "mach": 82} |
|
time | Hours and minutes(INT 0..23, INT 0..59) |
{"type": "time", "hrs": 6, "min": 35} |
unit name |
ATSU unit identification
|
{"type": "unit", "ident": "LKAA", "name": "PRAHA", "func": 7} |
πππ