ACARS/VDLM2 Position Sources
The live aircraft map is currently fed from positions extracted out of the following coordinate-bearing families. Where POA is referenced, it means "plain old ACARS", received via acarsdec, as opposed to VDLM2 collected from dumpvdl2.
The acceptance and rejection rules described here were developed from repeated comparison against a months-long corpus of contemporaneous ACARS/VDL2 and ADS-B observations collected at the same station. References below to a format being “validated,” “established,” or “demonstrated” refer to that empirical work and to the behavior observed in this corpus. This note documents the resulting receiver logic rather than the full underlying validation exercise. The complete test corpus, matching runs, and statistical analysis are not reproduced here because that write-up would be boring as heck (to me), and because this is not academia. It's my hobby and therefore supposed to be fun... Sorry. ¯\_(ツ)_/¯
Family ID Live source(s) Time basis ---------------------- ----------------------------------- ---------------------------------- ADS_C dumpvdl2 + POA reception AGFSR dumpvdl2 + POA onboard, else reception fallback POSRPT dumpvdl2 onboard, else reception fallback POS02 POA reception OBS POA reception LABEL16_COMPACT dumpvdl2 + POA onboard LABEL16_EXPLICIT_POS dumpvdl2 + POA onboard LABEL16_AUTPOS dumpvdl2 onboard H1_STAR_POS dumpvdl2 + POA onboard H1_PAREN_POS dumpvdl2 onboard H1_TRP dumpvdl2 onboard H1_ACMS_RLINE dumpvdl2 + POA reception LABEL21_POS dumpvdl2 + POA onboard LABEL22_POS dumpvdl2 + POA onboard LABEL12_7FIELD dumpvdl2 onboard LABEL36_28E dumpvdl2 onboard LABEL37 dumpvdl2 live path reception LABEL44_POS dumpvdl2; POA for plaintext POS02 onboard GENERIC_TEXT_POS dumpvdl2 onboard AFN_FPO dumpvdl2 onboard LABEL414344_FB_AD dumpvdl2 reception LABEL10_LDR01 dumpvdl2 reception LABEL10_SLASH dumpvdl2 reception XID dumpvdl2 VDL2 XID reception proxy -----------------------------------------------------------------------------------------------
On what actually reaches readsb
A parser match alone is not enough. A point reaches the visualization only after all of these conditions are met:
- Physical/transport gate: the family-specific label/frame, direction, integrity, completeness and source requirements that have actually been validated are met. These gates intentionally differ by family. Some/most are discussed below.
- Exact family grammar: anchored record shape. No broad "find something coordinate-looking" extraction.
- Coordinate semantics: the parser must know whether the digits are decimal degrees, DDM, DMS, or structured numeric fields.
- Bounds and freshness: minutes/seconds/dateline are checked, and families with validated onboard clocks enforce their own freshness windows.
- Identity: ultimately a valid ICAO hex code backed by transmission or a unique registration lookup is required for visualization.
- Qualified contract: non-ADS-C data must be a branded "NonAuthoritativeAircraftPosition" (i.e. belong to one of the following families). Arbitrary normalized coordinates are ignored by the exporter.
- Exporter checks: record/contract identity agreement, dedupe, queueing and isolated SBS output.
The practical result is intentionally conservative: coordinates are promoted family-by-family, not because a message happens to contain something that looks like latitude/longitude. Unknown adjacent fields stay unknown, ambiguous layouts fail closed, stale/reference positions are withheld where the corpus has shown that risk, and ADS-C retains its separate authoritative meaning.
Now on to the actual coordinate-bearing families...
ADS_C
Label 4T AGFSR
Label 80 POSRPT
Label 16 - POS02
Label 16 - OBS
Compact Label 16 - LABEL16_COMPACT
Explicit POS Label 16 - LABEL16_EXPLICIT_POS
LABEL16_AUTPOS
Fixed-width *POS - H1_STAR_POS
Parenthesized POS - H1_PAREN_POS
H1_TRP
ACMS R-line - H1_ACMS_RLINE
Labels 21 and 22 - LABEL21_POS, LABEL22_POS
LABEL12_7FIELD
LABEL36_28E
LABEL37
Label 44 POS - LABEL44_POS
Generic text POS - GENERIC_TEXT_POS
AFN /FPO - AFN_FPO
-
Labels 41/43/44 /FB /AD - LABEL414344_FB_AD
What it is:
A validated JetBlue current-position family observed on physical ACARS Labels 41, 43 and 44. The three labels share the same /FB ... /AD ... /N ...,W ... coordinate header, but only specific application identifiers are accepted.What it looks like:
/FB 0130/AD TNCA/N 17.138,W 70.223,JBU1457,INA03,TNCA,2240Extraction:
Common record regex:
^ \/FB (\d{4})\/AD ([A-Z]{4})\/N (\d{2}\.\d{3}),W (\d{2,3}\.\d{3}),(JBU[0-9A-Z]{1,4}),([A-Z0-9]{5}),([^\r\n]*)$Gates:
Physical label/application combinations are restricted to Label 41 with SOM03, MLM03, MCM03 or MSX03; Label 43 with ATI03 or TWX03; and Label 44 with INA03 or INR03. The frame must be dumpvdl2, air to ground, with err=false, crc_ok=true and more=false, and must carry a transmitted ICAO-hex aircraft identity. /FB must contain exactly four digits: reports where that field was unavailable showed catastrophic stale coordinates in the retained corpus. /AD must contain four letters. If an outer B6 flight number is present, it must agree with the embedded JBU flight. Coordinates are decimal degrees and reception time is used as the position timestamp. No altitude, speed or track is inferred from the remaining fields. -
Label 10 - LABEL10_LDR01, LABEL10_SLASH
What it is:
Two separately validated current-position formats carried on physical ACARS Label 10. LDR01 is a 34-field comma-separated record using decimal-degree coordinates. The slash family is a 15- or 16-field record using degrees and decimal minutes and additionally carries validated track and altitude.What it looks like:
LDR01:
LDR01,189,D,SWA-2600-019,0,N 21.513,W 68.959,37001, 25.3,KMCO,TJSJ,TJSJ,10/, 8/,/,0,0,,,,,,,0,0,0,00,,115.0,23.2,138.2,,,
Slash-delimited:
/N19.063/W067.599/10/0.65/128/209/TJBQ/2349/0046/00018/AQABA/ODEZZ/2338/INNES/2338/
Extraction:
LDR01 coordinate regexes:
latitude: ^N (\d{2}\.\d{3})$
longitude: ^W (\d{2}\.\d{3})$Slash-family coordinate regexes:
latitude: ^N(\d{2})\.(\d{2})(\d)$
longitude: ^W(\d{3})\.(\d{2})(\d)$The slash coordinates are DDM, not decimal degrees. Thus N19.063 means N19°06.3′ and W067.599 means W067°59.9′.
Gates:
Both families require physical Label 10, literal raw acars.msg_text, dumpvdl2 air-to-ground reception, err=false, crc_ok=true, more=false, and an exact raw ASCII ICAO-hex transmitted aircraft identity.LDR01 must contain exactly 34 comma-separated fields beginning LDR01,189,D,...,0. Only the validated SWA-2600-019 and ENG-2600-20E variants are accepted. Its coordinates are retained, but the apparent adjacent telemetry fields remain uninterpreted. Reception time is used as the position timestamp.
The slash family must contain exactly 15 or 16 fields. Coordinate minutes must be less than 60. Field 4 is validated as track 000 through 359; field 5 is altitude in hundreds of feet. Field 12 must be a valid four-digit HHMM value and is used only as a stale-state sentinel: resolved to the nearest UTC day, it may not be more than 60 seconds behind reception. It is deliberately not treated as the position timestamp. Reports with unavailable field 12 are withheld. Reception time remains the position timestamp, and all other field semantics are withheld.
VDL2 XID aircraft location - XID
What it is:
ARINC 622 ADS-C decoded structurally by libacars. Coordinates come from `adsc.tags[].basic_report`; speed/track/vertical rate may come from `earth_ref_data`.
What it looks like:
{
"arinc622": {
"msg_type": "adsc_msg",
"crc_ok": true,
"adsc": {
"err": false,
"tags": [
{"basic_report": {"lat": 19.0, "lon": -68.0, "alt": 35000}},
{"earth_ref_data": {
"gnd_spd_kts": 440,
"true_trk_deg": 270,
"vspd_ftmin": 0
}}
]
}
}
}
Extraction and gates:
`msg_type` must be `adsc_msg`, inner ARINC 622
CRC must be good, `adsc.err === false`, and coordinates must be
finite/in bounds. On dumpvdl2 the outer ACARS frame must also have
`crc_ok === true` and `err === false`. POA/acarsdec ADS-C reaches the
bridge only when the transmitted registration resolves uniquely to an
ICAO hex. Predicted route points never qualify.
What it is:
Slash-delimited airline flight-status text carrying route, report time, position and flight level.
What it looks like:
AGFSR AC7264/20/21/PUJBOG/0534Z/661/1723.5N06940.3W/372A spacing variant such as 1938.0N 6920.3W is also accepted after whitespace removal.
Extraction:
Regex: ^(\d{2})(\d{2}(?:\.\d+)?)([NS])(\d{1,3})(\d{2}(?:\.\d+)?)([EW])$
This is DD + minutes + hemisphere, followed by DDD + minutes + hemisphere. Minutes must be < 60; final coordinates are bounds-checked.
Gates:
Physical label must be 4T; the AGFSR prefix and first eight slash fields must exist.
Flight level is accepted only from 0 to 600 and multiplied by 100.
The report day plus HHMMZ is resolved near reception; implausible onboard time falls back to reception time with a warning.
POA observations without a uniquely resolvable hex may parse and remain in history, but cannot be emitted to readsb.
What it is:
Airline textual position reports. Four production variants are accepted: 3N01, 3N02, 3N03, and 3P01.
What it looks like:
3N01 POSRPT 0259/22 TJSJ/SKBO .N913AV/01F 22:48 /WYP CLAYO /NWYP SCAPA /HDG 210/MCH 654 /POS N1808.3W06614.5/FL 194/TAS 414/SAT -009 /SWND 006/DWND 040/FOB N008090/ETA --:--.-
3N02 POSRPT 8705/19 KFLL/SBKP .PR-ANU /POS N16000W068406/WP ILKIT/ALT 37001/MCH 0816/FOB 38329/ETA 2054
3N03 POSRPT 1913/19 TJSJ/KDTW .N893DN /POS N19486W067173/TIME 1855/ALT 245/FOB 0362 /MCH 73/WND 271 011/OAT /TAS /ETA 2247
/FB 0164/AD KFLL/N2010.6,W06919.0,3P01 POSRPT 2072/22 TJBQ/KFLL .N3132J /UTC 204919/POS N2010.6 W06919.0/ALT 31726 /SPD 448/FOB 0164/ETA 2238
Extraction:
Regex: ^([NS])(\d{2})(\d{2})(?:\.(\d)|([0-9]))\s*([EW])(\d{3})(\d{2})(?:\.(\d)|([0-9]))$
Both N1808.3W06614.5 and compact N18083W066145 mean degrees plus tenths of minutes.
Gates:
Only physical Label 80 is considered in production.
Duplicate named fields make the report ambiguous and reject it.
If a transmitted registration is present, it must agree with the POSRPT registration.
3P01 has an additional redundancy gate: its /FB , /AD , and prefix coordinate must agree with the main report.
3N03 /ALT is deliberately **not** promoted as altitude because its units remain unconfirmed.
Current runtime promotion is dumpvdl2-only.
What it is:
A two-line route/position report observed on POA/acarsdec.
What it looks like:
POS02 TFL365/21211737EHAMTNCC N15140W065564,37998,173738,-124,-033,18,492,1822,-78,267,0.839,-51,8.2Three or four spaces after POS02 are accepted.
Extraction:
Regex: ^([NS])(\d{2})(\d{3})([EW])(\d{3})(\d{3})$
The three minute digits are tenths of minutes: N15140W065564 = N15°14.0′ W065°56.4′.
Gates:
Exact two-line structure, exactly 13 CSV fields, two explicit four-letter airports, and all remaining fields numeric.
Placeholder airports are rejected. The accompanying numeric fields are intentionally uninterpreted.
Current runtime source: POA/acarsdec;
export requires a unique registration→hex lookup.
What it is:
A 13-field Label 16 POA report with explicit route and decimal-degree coordinates.
What it looks like:
OBS0851,-,LPPT,MDPC,N20.988,W 66.148,39997,2219,477.375, 8.3, 167.0,339, 39
Extraction:
Regex:
latitude: ^([NS])(\d{1,2}\.\d{3})$
longitude: ^([EW])\s*(\d{1,3}\.\d{3})$
Gates:
Exact 13 fields, OBSdddd identifier, literal - in field 1, valid non-placeholder airports, numeric trailing fields, and global coordinate bounds.
Those trailing numbers are not assigned altitude/speed/time semantics. POA/acarsdec only; export requires a unique hex lookup.
What it is:
Another Label 16 variant. Coordinates are decimal degrees with explicit hemispheres. The first field is onboard HHMMSS, resolved to the nearest UTC day within two
hours. The three adjacent numeric fields remain uninterpreted.
What it looks like:
214616,36000,0158, 272,N 18.489 W 66.493
Extraction:
Core record regex: ^(\d{6}),(\d{1,5}),(\d{4}),([ ]{0,3}\d{1,4}),([NS]) (\d{1,2}\.\d{3}) ([EW]) (\d{1,3}\.\d{3})$
Gates:
G60200 and G60201 are explicitly excluded because the retained corpus established reference-location rather than ownship semantics for those applications.
What it is:
Another observed Label 16 variant with explicit decimal degrees.
What it looks like:
POS /CS BRS01/TN FAB2101/POS N 16.025 W 65.911/TIM 182254/ALT 36017/SPD 258/FOB 115/ETA 2231/DST KJFKA leading * ( *POS ... ) is also accepted.
Extraction:
The coordinate core regex is: /POS ([NS]) (\d{1,2}\.\d{3}) ([EW]) (\d{1,3}\.\d{3})/TIM (\d{6})/
Gates:
The onboard time must resolve within two hours. Altitude/speed/fuel fields are structurally required but currently withheld from the position contract because their semantics have not been independently validated.
What it is:
Another observed Label 16 variant containing the keyword AUTPOS.
What it looks like:
210062/AUTPOS/LLD N204039 W0684042 /ALT 12980/SAT **** /WND ******/TAT ****/TAS ****/CRZ *** /FOB 042600 /DAT 260921/TIM 034901
Extraction:
Regexes:
lat: ^\d{6}$
lon: ^\d{7}$
Gates:
Minutes/seconds must be 0 to 59 , with pole/dateline edge checks.
YYMMDD/HHMMSS must be within 30 seconds of reception.
The altitude field is withheld because its modulo-32768 interpretation remains ambiguous.
What it is:
This shape was observed from UPS freight aircraft. Two coordinate layouts are accepted. The linebreak is in the original.
What it looks like:
Whole-minute variant:
*POS 09210119N2114W06853400329034818M5500345Tenths-minute variant:
*POS 09261134N21141W070121350331022789M4310312
Extraction:
whole-minute variant regex:
^(\d{8})([NS])(\d{2})(\d{2})([EW])(\d{3})(\d{2})(\d{3})(\d{9}[MP]\d{7})(?:TOD[A-Z]{6}[ 0-9]{4})?$
tenths-minute variant regex:
^(\d{8})([NS])(\d{2})(\d{3})([EW])(\d{3})(\d{3})(\d{3})(\d{9}[MP]\d{7})$
Gates:
The first eight digits are MMDDHHMM, required within two hours of reception. Coordinate minutes are either whole minutes or tenths.
The three-digit altitude field is hundreds of feet and is accepted only through 70,000 ft.
Both dumpvdl2 and POA/acarsdec can qualify; POA still needs unique registration→hex identity for export.
What it is:
As you can see from the examples, these variants have been observed mainly from KLM aircraft.
First variant is ordinary whole-minute. Second variant is validated minute-60 carry.
What it looks like:
(POS-KLM741 -1918N06712W/012242 F330 RMK/FUEL 44.9 M0.86)
(POS-KLM741 -1660N06604W/012242 F330 RMK/FUEL 44.9 M0.86)
Extraction:
Regex: ^\(POS-(.{8})-(\d{2})(\d{2})([NS])(\d{3})(\d{2})([EW])\/(\d{6}) F(\d{3})\r?\nRMK\/FUEL {2,3}\d+\.\d+ M\d+\.\d+\)$
Gates:
The eight-column identifier must be blank or alphanumeric plus space padding.
Exact minute 60 is accepted only by carrying once into the next degree; larger values fail.
HHMMSS must be within 30 seconds of reception. Flight level 001 through 700 becomes feet; otherwise altitude
is suppressed while a valid position may survive. Dumpvdl2/transmitted-hex only.
What it is:
Four validated physical shapes feed three variants. Only coordinates are exported; the three adjacent telemetry fields remain uninterpreted.
On both multi-line shapes, only A5 is current!
What it looks like:
Direct numeric:
TRP 193217 19.0676 -66.7516 146 120.8 371 2288 0.02258Five-point space layout --- only A5 is current:
TRP KPHL TJSJ 8 8 /A1 151808 22.1000 -69.1000 350 146.0 450 0.000000 /A2 152108 21.8000 -69.0000 350 145.9 451 0.000000 /A3 152408 21.5000 -68.8000 350 145.7 452 0.000000 /A4 152708 21.3000 -68.5000 350 145.5 453 0.000000 /A5 153008 21.0647 -68.2586 350 145.4 454 0.000000A321 REP291 comma layout --- again only A5 is current:
A321,015060,1,1,TB000000/REP291,00,00,4/ TRP KPHL TJSJ 8 8 /A1 162425, 23.0483,- 70.3143,329,167.8,450,0.000158, 0.000079, 6.28,- 48.02, 14.0,-45, 7.04,0 /A2 162725, 22.7500,- 70.0500,330,167.5,454,0.000200, 0.000100, 7.61,- 38.46, 13.7,-45, 7.06,0 /A3 163025, 22.4500,- 69.8000,330,167.2,458,0.000300, 0.000150, 9.45,- 56.77, 13.5,-45, 7.04,0 /A4 163325, 22.1500,- 69.5700,330,166.9,462,0.000500, 0.000250, 7.34,- 44.21, 13.2,-45, 7.05,0 /A5 163625, 21.8571,- 69.3506,330,166.6,466,0.000729, 0.000365, 7.54,- 50.78, 12.9,-45, 7.05,0A321 REP191 single-point layout:
A321,017890,1,1,TB000000/REP191,00,00,4/ TRP TLPL KCLT 8 0 205122, 18.4548,- 66.1494,300,181.2,472,0.007227,0.003572, 15.65, 136.44, 30.8,-30, 8.89,0,0.02418, 1.131, 0.805, 0.055,-0.059, 3,294, 0,10
Extraction:
Regexes:
lat: [+-]?\d{1,2}\.\d{4}
lon: [+-]?\d{1,3}\.\d{4}
Gates:
The embedded HHMMSS must be within 60 seconds. A-series reports require an exact ordered A1--A5 set and exact continuation scaffolding.
REP191 requires its exact five-line transport. dumpvdl2/transmitted-hex only.
What it is:
Qualified report numbers are RPT36, RPT39, RPT40, and RPT42.
What it looks like:
A RPT36 PG1 L-ECS TEST REAL B .N852GT 20SEP26 0219 GTI057 KMIA/SBKP CMC-802 GE-805 ER R +161302 -0705406 298 +33005 +148 508
Extraction:
Regexes:
header: ^[ \t]*A RPT(\d{1,3})(?:[ \t]|$)
R-line: ^[ \t]*R[ \t]+([+-])(\d{6})[ \t]+([+-])(\d{7})(?=[ \t]|$)
Gates:
Latitude is DDMM.mm encoded as six digits; longitude is DDDMM.mm encoded as seven.
DDM bounds are enforced. R-lines are bounded to their own report body.
If a physical reception contains more than one qualified R-line, production fails closed instead of choosing one.
The coordinate's onboard timestamp has not been validated, so reception time is used and all adjacent telemetry is withheld.
Both dumpvdl2 and POA can qualify.
On dumpvdl2, an explicit ACARS error or explicit CRC failure rejects the candidate; POA requires an error-free downlink.
A continuation flag does not by itself reject a self-contained R-line.
What it is:
These are paired current-position formats.
What it looks like:
Label 21 - decimal degrees:
POSN 19.151W 66.053, 288,051854,16889,12927, 9,- 6,081548,TJSJLabel 22 - DMS seconds:
N 190900W 660307,-------,051854,16889, , , ,M 6,12927 9, 288,
Extraction:
Coordinate core regex:
^([NS]) (\d{2})(\d{2})(\d{2})([EW]) (\d{2})(\d{2})(\d{2}),-------,(\d{6}),...$
Gates:
The embedded HHMMSS must be within 30 seconds of reception.
The mirrored ---- reference-coordinate subtype is deliberately rejected:
the retained paired corpus established that it is not current ownship position.
Unknown telemetry fields are shape-checked but not assigned semantics.
dumpvdl2 requires transmitted hex; POA requires unique registration-to-hex resolution.
What it is:
Label 12, seven field messages.
What it looks like:
N 21.045,W 70.347,38000,163025, 146,.C-GYYS,1745
Extraction:
Regexes:
lat: ^N (\d{2}\.\d{3})$
lon: ^W (\d{2}\.\d{3})$
Gates:
The entire record must contain exactly seven fields.
HHMMSS must be within 60 seconds of reception.
The embedded registration must match the reception identity after canonicalization.
Fields 2, 4 and 6 are structurally checked but uninterpreted.
The apparent altitude-like field is therefore not exported as altitude.
Masked MMMM.MMM coordinate reports are explicitly withheld.
dumpvdl2/transmitted-hex only.
What it is:
Two coordinate layouts that share the same application scaffold.
What it looks like:
Decimal degrees variant:
28,E,25AUG26,214406,N 17.381,W 65.690,34981, 15960,KJFK,TTPP,TTPP,10/,/,,,,,,,,1,0,0,0,0,0,0,,152.9,011.0,and, compact DDM variant:
28,E,27AUG26,025830,N2033.8,W06935.0,39001,7825,KTPA,TJSJ,TJSJ,10/,/,,,,,,,,0,0,0,0,0,0,0,,102.8,
Extraction:
For the decimal degrees variant:
Regexes:
lat: ^N (\d{2}\.\d{3})$
lon: ^W (\d{2}\.\d{3})$
For the compact DDM variant:
Regexes:
lat: ^N(\d{2})(\d{2})\.(\d)$
lon: ^W(\d{3})(\d{2})\.(\d)$
Gates:
The exact DDMMMYY/HHMMSS timestamp must be within 60 seconds.
The record must have the expected field count and airport triplet.
A literal field-7 ------ is rejected because the corpus demonstrated a catastrophic stale-coordinate state there.
Altitude is retained.
The decimal-degree population is still marked non-authoritative because residuals up to roughly 10 NM were observed.
dumpvdl2/transmitted-hex only.
What it is:
Six report subtypes are currently allowed to contribute positions under this label.
These are POS01, HGD03, CLB02, ETA03, INR04, and GAM02.
What it looks like:
01POS01 TJSJ,KBWI,N 19.034,W 66.433,18583,292,393,.617,25.6,1315,330,213,004,? 5,161200
04HGD03 KTPA,TJSJ,N 20.791,W 69.806,30998,289,472,.780,25.6,1315,330,213,004,? 5,161200
01CLB02 TJSJ,KMCO,N 18.716,W 66.232The validated six-field CLB02 form is also accepted:
01CLB02 TJSJ,KMCO,N 18.778,W 66.297,19.8,1202
08ETA03 TJSJ,KMCO,0441,19.7,N 19.028,W 66.579
05INR04 KMCO,TJSJ,0023,0010,12.0,N 19.135,W 66.408
07GAM02 TJSJ,KMCO,0445,N 18.721,W 66.238
Extraction:
The shared decoded coordinate shape regex is:
latitude: ^[NS] \d{2}\.\d{3}$
longitude: ^[EW] \d{2,3}\.\d{3}$
Gates:
POS01/HGD03 additionally require the validated telemetry prefix
altitude \d{4,5}, two three-digit speed fields, and Mach \.\d{3}.
CLB02 requires exactly 4 or 6 logical fields. ETA03/INR04/GAM02 have
subtype-specific field-position gates before their coordinates are
exposed.
Coordinates are decimal degrees with hemisphere sign. Final global
bounds are checked again by the position contract. POS01/HGD03 may
carry altitude and ground speed; the other four contribute coordinates
only. The position timestamp is reception time. Current live automatic
promotion is on the dumpvdl2 path.
What it is:
Three validated shapes are accepted.
What it looks like:
POS02,N18160W068219,180,MDPC,SEGU,0926,0713,0820,016.4
POS02,N020319W 69533,---,KDAL,TIST,0926,0713,,---.-
00POS02,N19060W069177,210,KBCT,MDPC,0926,1450,1503,*****
Extraction:
Header regex:
^(?:\d{2})?(POS0[123])$
Coordinate regex:
^([NS])(\d{2})(\d{3})([EW])(\d{3})(\d{3})$
Gates:
The coordinate is DDM to tenths of a minute.
Physical Label 44, air to ground direction, valid transmitted ICAO hex, and acceptable outer integrity are required.
Altitude is three digits x100 ft, or GRD/GR. for no altitude.
MMDD/HHMM must be contemporary within two hours; only the validated immediately-previous-date rollover anomaly is corrected.
Current live promotion is dumpvdl2-only.
What it is:
This is the validated compact text-POS family on labels H1, 3P, and 20.
What it looks like:
POSN18160W068219,MDPC,222400,180,SEGU,014400,N19000W069000
Extraction:
The first field must match the following regex:
^POS([NS]\d{5}[EW]\d{6})$
Production then re-parses the coordinate through the stricter bounded DDM helper:
^([NS])(\d{2})(\d{3})([EW])(\d{3})(\d{3})$
Gates:
Only dumpvdl2 air to ground frames with "err=false", "crc_ok=true", a transmitted six-hex identity, and labels H1/3P/20 qualify.
Time 1 must be a valid HHMMSS within two hours of reception.
/TS fallback and reception-time fallback remain research-only and cannot drive readsb.
Flight level 001 to 700 becomes feet; invalid/unavailable flight level is suppressed without discarding an otherwise valid position.
What it is:
An AFN message where the FMH supplies identity/time and /FPO supplies current position.
What it looks like:
/KZWY.AFN/FMHTEST12,.N12345,A4FC9A,010200/FPON17457W068155,1/FCOATC,01/FCOADS,0163A7
Extraction:
The FPO coordinate uses the same bounded compact-DDM grammar:
^([NS])(\d{2})(\d{3})([EW])(\d{3})(\d{3})$
Gates:
dumpvdl2 only, air to ground, err=false, crc_ok=true, transmitted ICAO-hex identity.
.AFN/FMH present, trailing four char checksum present, and exactly one AFN header, one FMH segment and one FPO segment.
The FMH embedded hex must exactly equal the AVLC aircraft hex.
FMH HHMMSS must resolve within two hours.
No altitude/speed/track is inferred from the surrounding fields.
What it is:
XID is not an ACARS text label, but it is part of the same VDL2-fed visualization and therefore belongs in this guide.
The same structured shape is accepted for three variants: Handoff Initiation, Handoff Response, and Link Establishment.
What it looks like:
{
"frame_type": "U",
"cmd": "XID",
"src": {"type": "Aircraft", "addr": "A4FC9A"},
"dst": {"type": "Ground station", "addr": "1028BA"},
"xid": {
"err": false,
"type_descr": "Link Establishment",
"vdl_params": [
{
"name": "ac_location",
"value": {
"loc": {"lat": 18.5, "lon": -67.1},
"alt": 18000
}
}
]
}
}
Extraction:
It's JSON. There is no coordinate regex.
Gates:
loc.lat and loc.lon must be finite numbers in global bounds.
The frame must be U/XID, aircraft to ground station, xid.err === false, and contain exactly one ac_location. The AVLC source address supplies the transmitted six-hex identity.
Reports where both decoded coordinates are exact whole degrees are rejected because native ADS-B validation identified that population as pathologically inaccurate.
XID altitude is retained only when it is an integer from 1,000 through 70,000 ft and an exact multiple of 1,000; otherwise altitude is suppressed.
Reception time is used as a proxy timestamp.