COAA planeplotter protocol description
RPi-based uploader to PlanePlotter protocol description
This is a draft. It is known to be incomplet and incorrekt, with bad formatting.
Communication on port 9742/UDP. List of possible request message headers: "TRSEND ", "TRSeND ", "WhoAmI" (we respond with "IAm %d.%d.%d.%d" string where %d.%d.%d.%d is an IP of incoming connection).
Request: 0000 54 52 53 65 4e 44 20 31 34 39 36 38 30 35 31 31 TRSeND 149680511 0010 32 20 31 30 20 31 38 38 2e 36 34 2e 31 39 31 2e 2 10 188.64.191. 0020 33 35 35 Description: TRSeND (unixtimestamp) (time offset) (source ip) Response: 0000 56 57 ×× ×× ×× ×× ×× ×× ×× ×× ×× ×× ×× ×× ×× ×× VW×××××××××××××× 0010 ×× ×× 47 46 46 4e 43 47 45 49 40 40 40 40 40 40 ××GFFNCGEI@@@@@@ 0020 40 40 40 46 4a 40 4c 41 40 47 4f 4d 4b 46 4b 43 @@@FJ@LA@GOMKFKC 0030 4c 41 45 4d 40 46 4a 40 4c 41 47 44 43 4b 43 4c LAEM@FJ@LAGDCKCL 0040 40 43 40 40 40 40 40 40 40 40 40 40 40 40 40 40 @C@@@@@@@@@@@@@@ 0050 40 40 20 20 @@ 0000 56 57 ×× ×× ×× ×× ×× ×× ×× ×× ×× ×× ×× ×× ×× ×× VW×××××××××××××× 0010 ×× ×× 4f 49 46 4e 43 47 45 49 40 40 40 40 40 40 ××OIFNCGEI@@@@@@ 0020 40 40 44 44 40 48 42 48 40 41 49 49 40 4a 4c 4d @@DD@HBH@AII@JLM 0030 4d 40 48 4d 44 44 40 48 42 48 45 48 4b 49 48 44 M@HMDD@HBHEHKIHD 0040 4d 4b 40 46 42 43 46 4a 49 46 47 47 48 47 40 43 MK@FBCFJIFGGHG@C 0050 40 40 20 20 @@ 0000 56 57 ×× ×× ×× ×× ×× ×× ×× ×× ×× ×× ×× ×× ×× ×× VW×××××××××××××× 0010 ×× ×× 4f 4a 46 4e 43 47 45 49 40 40 40 40 40 40 ××OJFNCGEI@@@@@@ 0020 40 40 44 4b 4d 41 44 49 40 41 49 4a 41 4a 4b 4e @@DKMADI@AIJAJKN 0030 4b 4a 48 4d 44 4b 4d 41 44 49 49 40 45 43 43 44 KJHMDKMADII@ECCD 0040 4b 4a 46 40 42 46 45 4c 45 40 4f 4a 48 41 40 43 KJF@BFELE@OJHA@C 0050 40 40 20 20 @@
payload[0] = 0x56 (86) header; 1 byte payload[1] = 0x57 (87) header; 1 byte payload[2..10) = user latitude; 8 bytes [enc] payload[10..18) = user longitude; 8 bytes [enc] payload[18..34) = aircraft seen on client, unix timestamp; 16 bytes [enc] payload[34..40) = ICAO; 6 bytes [enc] paylaod[40..42) = COAA msg type (encoded enum values: 1, 5, 7); 2 bytes [enc] payload[42..50) = Message mode timestamp blk (see dump1090 source); 8 bytes [enc] if paylaod[40..42) == 0x4140 (decoded to 1): ; aircraft message length 14 bytes payload[50..78) = aircraft message; 28 bytes [enc] payload[78] = 0x40 end of message; 1 byte [enc] paylaod[79] = 0x43 end of message; 1 byte [enc] if paylaod[40..42) == 0x4540 (decoded to 5): ; I never seen packet with this message type if paylaod[40..42) == 0x4740 (decoded to 7): ; aircraft message length 7 bytes payload[50..64) = aircraft message; 14 bytes [enc] payload[64] = 0x40 end of message; 1 byte [enc] paylaod[65] = 0x43 end of message; 1 byte [enc] payload[82] = 0x20 (32) end of payload; 1 byte payload[83] = 0x20 (32) end of payload; 1 byte
Response payload is encrypted by following encoder:
int coaaEncrypt(uint8_t *out, const uint8_t *in, int size) { if (size <= 0) { return 0; } const uint8_t *last = &in[size]; for (; in != last;) { out[0] = (*in >> 4) + 64; out[1] = (*in & 0xF) + 64; in++; out += 2; } return 2 * size; }
Matching decryptor:
int coaaDecrypt(uint8_t *out, const uint8_t *in, int size) { if (size <= 0) { return 0; } if (size % 2 != 0) { return 0; } const uint8_t *last = &in[size]; for (; in != last;) { // out[0] = ((in[0] - 64) << 4) | ((in[1] - 64) & 0xF); out[0] = ((in[0] & 0xF) << 4) | (in[1] & 0xF); in += 2; out++; } return size / 2; }Decoded UDP payloads:
'VW××××××××××××××××GGFNCGEI@@@@@@@@DKMADI@AONFBFBJGHMDKMADII@FMADIOKBCBNHBLKCH@@C@@ ' '67××××××××××××××××776e3759000000004bd14901fe6262a78d4bd149906d149fb232e82cb380030000' head (type 'str') 67 Lat (type 'float') × Lon (type 'float') × seen (type 'long') 1496804983 (59376e77) icao (type 'str') 4bd149 msgtype (type 'str') 01 msgtimestamp (type 'long') 2808242942 (a76262fe) msg (type 'str') 8d4bd149906d149fb232e82cb38003 'VW××××××××××××××××GHFNCGEI@@@@@@@@@FJ@LA@GOODJODNOEM@FJ@LAGDCKBL@C@@@@@@@@@@@@@@@@ ' '67××××××××××××××××786e37590000000006a0c107ff4af4ef5d06a0c1743b2c03000000000000000000' head (type 'str') 67 Lat (type 'float') × Lon (type 'float') × seen (type 'long') 1496804984 (59376e78) icao (type 'str') 06a0c1 msgtype (type 'str') 07 msgtimestamp (type 'long') 4025764607 (eff44aff) msg (type 'str') 5d06a0c1743b2c03 'VW××××××××××××××××GHFNCGEI@@@@@@@@DKMADI@AOOIHAGOGHMDKMADII@FKOABMGLDOMHFJCFGO@C@@ ' '67××××××××××××××××786e3759000000004bd14901ff9817f78d4bd149906bf12d7c4fd86a367f030000' head (type 'str') 67 Lat (type 'float') × Lon (type 'float') × seen (type 'long') 1496804984 (59376e78) icao (type 'str') 4bd149 msgtype (type 'str') 01 msgtimestamp (type 'long') 4145518847 (f71798ff) msg (type 'str') 8d4bd149906bf12d7c4fd86a367f03 'VW××××××××××××××××GHFNCGEI@@@@@@@@DD@HBH@A@@CBJBBBHMDD@HBHEHKIHDOHFJBOK@K@CBEE@C@@ ' '67××××××××××××××××786e375900000000440828010032a2228d44082858b984f86a2fb0b03255030000' head (type 'str') 67 Lat (type 'float') × Lon (type 'float') × seen (type 'long') 1496804984 (59376e78) icao (type 'str') 440828 msgtype (type 'str') 01 msgtimestamp (type 'long') 581054976 (22a23200) msg (type 'str') 8d44082858b984f86a2fb0b0325503 'VW××××××××××××××××GHFNCGEI@@@@@@@@@FJ@LA@G@@MFLICCEM@FJ@LAGDCKCI@C@@@@@@@@@@@@@@@@ ' '67××××××××××××××××786e37590000000006a0c10700d6c9335d06a0c1743b3903000000000000000000' head (type 'str') 67 Lat (type 'float') × Lon (type 'float') × seen (type 'long') 1496804984 (59376e78) icao (type 'str') 06a0c1 msgtype (type 'str') 07 msgtimestamp (type 'long') 868865536 (33c9d600) msg (type 'str') 5d06a0c1743b3903 'VW××××××××××××××××GIFNCGEI@@@@@@@@@FJ@LA@G@@EJFHLOEM@FJ@LAGDCK@G@C@@@@@@@@@@@@@@@@ ' '67××××××××××××××××796e37590000000006a0c107005a68cf5d06a0c1743b0703000000000000000000' head (type 'str') 67 Lat (type 'float') × Lon (type 'float') × seen (type 'long') 1496804985 (59376e79) icao (type 'str') 06a0c1 msgtype (type 'str') 07 msgtimestamp (type 'long') 3479722496 (cf685a00) msg (type 'str') 5d06a0c1743b0703msgtimestamp field is encoded using following algorithm before encryption:
/* msgType = msg[0] >> 3; */ uint64_t timestamp_mangle(const uint64_t llTimestamp, int msgType) { uint64_t lo = llTimestamp << 2; uint64_t hi = llTimestamp >> 30; uint64_t mix = (hi << 32) | lo; uint64_t sum = llTimestamp + mix; uint64_t div = sum / 3; if (msgType == 17) { // BYTE3(v24) = 1; coaa msg type int32_t ror = __ROR__(div + 1120, 24); return (((div + 1120) << 8) & 0xffffff00) | (ror & 0xff); } else if (msgType == 11) { // BYTE3(v24) = 7; coaa msg type int32_t ror = __ROR__(div, 24); return (((div) << 8) & 0xffffff00) | (ror & 0xff); } return -1; }
Reg, Auth, Hla, Hlo are credentials from coaa.h file generated by Dump1090 Software Registration Request.
// coaa.h #define USER_REGNO [int] #define USER_AUTHCODE [hex string] #define USER_LATITUDE [float] #define USER_LONGITUDE [float]
Periodic (once per minute) plane position upload HTTP payload send to www.coaa.co.uk:80:
0000 50 4f 53 54 20 2f 70 6c 61 6e 65 69 6e 66 6f 39 POST /planeinfo9 0010 75 2e 70 68 70 20 48 54 54 50 2f 31 2e 31 0d 0a u.php HTTP/1.1.. 0020 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 61 70 Content-Type: ap 0030 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 77 77 77 2d plication/x-www- 0040 66 6f 72 6d 2d 75 72 6c 65 6e 63 6f 64 65 64 0d form-urlencoded. 0050 0a 55 73 65 72 2d 41 67 65 6e 74 3a 20 50 6c 61 .User-Agent: Pla 0060 6e 65 50 6c 6f 74 74 65 72 0d 0a 48 6f 73 74 3a nePlotter..Host: 0070 20 77 77 77 2e 63 6f 61 61 2e 63 6f 2e 75 6b 0d www.coaa.co.uk. 0080 0a 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a .Content-Length: 0090 20 36 37 35 0d 0a 43 61 63 68 65 2d 43 6f 6e 74 675..Cache-Cont 00a0 72 6f 6c 3a 20 6e 6f 2d 63 61 63 68 65 0d 0a 0d rol: no-cache... 00b0 0a 52 65 67 3d ×× ×× ×× ×× ×× ×× 26 56 65 72 3d .Reg=××××××&Ver= 00c0 31 2e 31 30 2e 33 30 31 30 2e 31 34 26 41 75 74 1.10.3010.14&Aut 00d0 68 3d ×× ×× ×× ×× ×× ×× ×× ×× ×× 26 48 6c 61 3d h=×××××××××&Hla= 00e0 ×× ×× ×× ×× ×× ×× ×× ×× ×× ×× 26 48 6c 6f 3d ×× ××××××××××&Hlo=× 00f0 ×× ×× ×× ×× ×× ×× ×× ×× ×× 26 54 74 3d 31 34 39 ×××××××××&Tt=149 0100 36 38 30 34 39 38 34 26 4c 69 6e 65 73 3d 35 26 6804984&Lines=5& 0110 6c 69 6e 65 30 30 30 31 3d 20 20 20 20 20 20 20 line0001= 0120 20 20 20 20 20 20 20 20 20 30 36 41 30 43 31 20 06A0C1 0130 20 20 20 20 20 20 20 20 20 20 20 20 20 20 30 2e 0. 0140 30 30 30 30 30 30 20 30 2e 30 30 30 30 30 30 20 000000 0.000000 0150 20 20 20 20 20 20 30 2e 30 20 20 20 33 31 34 2e 0.0 314. 0160 30 20 20 20 34 39 30 2e 30 20 31 34 39 36 38 30 0 490.0 149680 0170 34 39 38 33 20 35 34 20 30 30 30 30 20 2d 36 34 4983 54 0000 -64 0180 26 6c 69 6e 65 30 30 30 32 3d 20 20 20 20 20 20 &line0002= 0190 20 20 20 20 20 20 20 20 20 20 34 42 44 31 34 39 4BD149 01a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 01b0 34 39 2e 37 36 35 31 33 34 20 20 20 32 30 2e 34 49.765134 20.4 01c0 32 36 38 35 30 20 20 20 32 30 36 30 30 2e 30 20 26850 20600.0 01d0 20 20 33 31 36 2e 30 20 20 20 33 37 36 2e 30 20 316.0 376.0 01e0 31 34 39 36 38 30 34 39 38 33 20 35 34 20 36 31 1496804983 54 61 01f0 34 34 20 2d 32 33 30 34 26 6c 69 6e 65 30 30 30 44 -2304&line000 0200 33 3d 41 55 41 36 39 30 20 20 20 20 20 20 20 20 3=AUA690 0210 20 20 34 34 30 38 32 38 20 20 20 20 20 20 20 20 440828 0220 20 20 20 20 20 20 20 20 35 30 2e 32 39 35 36 38 50.29568 0230 35 20 20 20 32 30 2e 33 36 38 32 31 39 20 20 20 5 20.368219 0240 33 36 30 30 30 2e 30 20 20 20 32 32 31 2e 30 20 36000.0 221.0 0250 20 20 33 38 34 2e 30 20 31 34 39 36 38 30 34 39 384.0 14968049 0260 38 33 20 35 34 20 36 32 35 32 20 30 26 6c 69 6e 83 54 6252 0&lin 0270 65 30 30 30 34 3d 53 44 4d 35 37 37 35 20 20 20 e0004=SDM5775 0280 20 20 20 20 20 20 34 32 34 35 37 41 20 20 20 20 42457A 0290 20 20 20 20 20 20 20 20 20 20 20 20 34 39 2e 36 49.6 02a0 37 34 37 32 39 20 20 20 32 31 2e 36 31 31 33 36 74729 21.61136 02b0 39 20 20 20 33 36 30 30 30 2e 30 20 20 20 31 39 9 36000.0 19 02c0 31 2e 30 20 20 20 33 37 39 2e 30 20 31 34 39 36 1.0 379.0 1496 02d0 38 30 34 39 36 33 20 35 34 20 34 35 32 35 20 30 804963 54 4525 0 02e0 26 6c 69 6e 65 30 30 30 35 3d 4c 4c 50 38 37 37 &line0005=LLP877 02f0 37 20 20 20 20 20 20 20 20 20 34 38 39 43 31 36 7 489C16 0300 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 0310 34 39 2e 35 30 30 30 30 30 20 20 20 32 30 2e 33 49.500000 20.3 0320 34 36 33 31 38 20 20 20 33 34 30 30 30 2e 30 20 46318 34000.0 0330 20 20 31 38 32 2e 30 20 20 20 33 39 35 2e 30 20 182.0 395.0 0340 31 34 39 36 38 30 34 39 38 31 20 35 34 20 34 35 1496804981 54 45 0350 33 31 20 30 31 0 Aircraft position available (printf-style): "&line%04d=%8s %06X %10.6lf %11.6lf %7d.0 %5d.0 %5d.0 %d 54 %04X %d", line_no++, a.flight, a.addr (ICAO), a.lat (latitude), a.lon (longitude), a.altitude, a.track, a.speed, a.seenLatLon, a.modeA (Squawk), a.vert_rate Empty aircraft position (printf-style): "&line%04d=%8s %06X 0.000000 0.000000 %7d.0 %5d.0 %5d.0 %d 54 %04X %d", line_no++, a.flight, a.addr (ICAO), a.altitude, a.track, a.speed, a.seen, a.modeA (Squawk), a.vert_rateFields are from struct aircraft.