diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2009-03-15 06:38:17 +0000 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2009-03-15 06:38:17 +0000 |
commit | 4f627e90862866164d1e0e1c0ac3ca85e8373f56 (patch) | |
tree | b9cf75dba85794f10c627025ed1cbcfa12d6bd2a | |
parent | b3f49700b7f032a4cd0fe5d15ef4b747ad580f9f (diff) | |
download | gpsd-4f627e90862866164d1e0e1c0ac3ca85e8373f56.tar.gz |
Check in AIVDM regression tests for sentence types 1-4.
-rw-r--r-- | Makefile.am | 21 | ||||
-rw-r--r-- | bits.c | 39 | ||||
-rw-r--r-- | packet.c | 4 | ||||
-rw-r--r-- | test/schwehr.aivdm | 125 | ||||
-rw-r--r-- | test/schwehr.aivdm.chk | 118 | ||||
-rw-r--r-- | www/AIVDM.txt | 41 |
6 files changed, 320 insertions, 28 deletions
diff --git a/Makefile.am b/Makefile.am index efd89229..4ae29d71 100644 --- a/Makefile.am +++ b/Makefile.am @@ -438,6 +438,25 @@ rtcm-makeregress: gpsdecode $(srcdir)/gpsdecode < $${f} > $${f}.chk; \ done + +# Regression-test the AIVDM decoder. +aivdm-regress: gpsdecode + @echo "Testing AIVDM decoding..." + @mkdir -p test + @for f in $(srcdir)/test/*.aivdm; do \ + echo "Testing $${f}..."; \ + $(srcdir)/gpsdecode <$${f} >test/test.chk; \ + diff -ub $${f}.chk test/test.chk; \ + done; \ + rm test/test.chk + +# Rebuild the AIVDM regression tests. +aivdm-makeregress: gpsdecode + @for f in $(srcdir)/test/*.aivdm; do \ + $(srcdir)/gpsdecode < $${f} > $${f}.chk; \ + done + + # Regression-test the packet getter. packet-regress: test_packet @echo "Testing detection of invalid packets..." @@ -471,7 +490,7 @@ time_regress: test_mkgmtime ./test_mkgmtime # Do all normal regression tests -testregress: gps-regress rtcm-regress packet-regress undump-regress time_regress +testregress: gps-regress rtcm-regress aidvm-regress packet-regress undump-regress time_regress @echo "Regressions complete." # We would like "${MAKE} check" to run the regression tests. automake @@ -30,25 +30,30 @@ unsigned long long ubits(char buf[], unsigned int start, unsigned int width) fld <<= BITS_PER_BYTE; fld |= (unsigned char)buf[i]; } -#ifdef UDEBUG - printf("Extracting %d:%d from %s: segment 0x%llx = %lld\n", start, width, - gpsd_hexdump(buf, 12), fld, fld); -#endif /* UDEBUG */ +#ifdef DEBUG + (void)printf("%d:%d from %s:\n", start, width, gpsd_hexdump(buf, 32)); +#endif +#ifdef DEBUG + (void)printf(" segment=0x%llx,", fld); +#endif /* DEBUG */ end = (start + width) % BITS_PER_BYTE; if (end != 0) { fld >>= (BITS_PER_BYTE - end); -#ifdef UDEBUG - printf("After downshifting by %d bits: 0x%llx = %lld\n", - BITS_PER_BYTE - end, fld, fld); +#ifdef DEBUG + (void)printf(" after downshifting by %d bits: 0x%llx", + BITS_PER_BYTE - end, fld); #endif /* UDEBUG */ } +#ifdef DEBUG + (void)printf(" = %lld\n", fld); +#endif /* UDEBUG */ fld &= ~(-1LL << width); -#ifdef UDEBUG - printf("After selecting out the bottom %u bits: 0x%llx = %lld\n", - width, fld, fld); -#endif /* UDEBUG */ +#ifdef DEBUG + (void)printf(" after selecting out the bottom %u bits: 0x%llx = %lld\n", + width, fld, fld); +#endif /* DEBUG */ return fld; } @@ -58,19 +63,19 @@ signed long long sbits(char buf[], unsigned int start, unsigned int width) { unsigned long long fld = ubits(buf, start, width); -#ifdef DEBUG +#ifdef SDEBUG (void)fprintf(stderr, "sbits(%d, %d) extracts %llx\n", start, width, fld); -#endif /* DEBUG */ +#endif /* SDEBUG */ /*@ +relaxtypes */ if (fld & (1 << (width-1))) { -#ifdef DEBUG +#ifdef SDEBUG (void)fprintf(stderr, "%llx is signed\n", fld); -#endif /* DEBUG */ +#endif /* SDEBUG */ fld |= (-1LL << (width-1)); } -#ifdef DEBUG +#ifdef SDEBUG (void)fprintf(stderr, "sbits(%d, %d) returns %lld\n", start, width, (signed long long)fld); -#endif /* DEBUG */ +#endif /* SDEBUG */ return (signed long long)fld; /*@ -relaxtypes */ } @@ -968,8 +968,10 @@ void packet_parse(struct gps_packet_t *lexer) else #endif /* AIVDM_ENABLE */ packet_accept(lexer, NMEA_PACKET); - } else + } else { + gpsd_report(LOG_WARN, "bad checksum in NMEA packet.\n"); lexer->state = GROUND_STATE; + } packet_discard(lexer); break; } diff --git a/test/schwehr.aivdm b/test/schwehr.aivdm new file mode 100644 index 00000000..1ed0c9a2 --- /dev/null +++ b/test/schwehr.aivdm @@ -0,0 +1,125 @@ +# Sample AIVDM data sentences provided from real data by Kurt Schwehr +# +# Sample sentences of types 1-4. +# +!AIVDM,1,1,,A,15RTgt0PAso;90TKcjM8h6g208CQ,0*4A +# MessageID: 1 +# RepeatIndicator: 0 +# UserID: 371798000 +# NavigationStatus: 0 +# ROT: -127 +# SOG: 12.3 +# PositionAccuracy: 1 +# longitude: -123.395383333 +# latitude: 48.38163333333 +# COG: 224 +# TrueHeading: 215 +# TimeStamp: 33 +# RegionalReserved: 0 +# Spare: 0 +# RAIM: False +# state_syncstate: 0 +# state_slotoffset: 4252 +# +!AIVDM,1,1,,A,16SteH0P00Jt63hHaa6SagvJ087r,0*42 +# MessageID: 1 +# RepeatIndicator: 0 +# UserID: 440348000 +# NavigationStatus: 0 +# ROT: -128 +# SOG: 0 +# PositionAccuracy: 0 +# longitude: -70.7582 +# latitude: 43.08015 +# COG: 93.4 +# TrueHeading: 511 +# TimeStamp: 13 +# RegionalReserved: 0 +# Spare: 0 +# RAIM: False +# state_syncstate: 0 +# stare_slottimeout: 2 +# state_slotoffset: 506 +# +# 2 is really uncommon +# +!AIVDM,1,1,,B,25Cjtd0Oj;Jp7ilG7=UkKBoB0<06,0*60 +# MessageID: 2 +# RepeatIndicator: 0 +# UserID: 356302000 +# NavigationStatus: 0 +# ROT: 127 +# SOG: 13.9 +# PositionAccuracy: 0 +# longitude: -71.62614333333333333333333333 +# latitude: 40.39235833333333333333333333 +# COG: 87.7 +# TrueHeading: 91 +# TimeStamp: 41 +# RegionalReserved: 0 +# Spare: 0 +# RAIM: False +# state_syncstate: 0 +# state_slottimeout: 3 +# state_slotoffset: 6 +# +!AIVDM,1,1,,A,38Id705000rRVJhE7cl9n;160000,0*40 +# MessageID: 3 +# RepeatIndicator: 0 +# UserID: 563808000 +# NavigationStatus: 5 +# ROT: 0 +# SOG: 0 +# PositionAccuracy: 1 +# longitude: -76.32753333333333333333333333 +# latitude: 36.91 +# COG: 252 +# TrueHeading: 352 +# TimeStamp: 35 +# RegionalReserved: 0 +# Spare: 0 +# RAIM: False +# state_syncstate: 0 +# state_slottimeout: 0 +# state_slotoffset: 0 +# +!AIVDM,1,1,,A,403OviQuMGCqWrRO9>E6fE700@GO,0*4D +# MessageID: 4 +# RepeatIndicator: 0 +# UserID: 3669702 +# Time_year: 2007 +# Time_month: 5 +# Time_day: 14 +# Time_hour: 19 +# Time_min: 57 +# Time_sec: 39 +# PositionAccuracy: 1 +# Position_longitude: -76.35236166666666666666666667 +# Position_latitude: 36.88376666666666666666666667 +# fixtype: 7 +# Spare: 0 +# RAIM: False +# state_syncstate: 0 +# state_slottimeout: 4 +# state_slotoffset: 1503 +# +!AIVDM,1,1,,A,403OviQuMGCqWrRO9>E6fE700@GO,0*4D +# MessageID: 4 +# RepeatIndicator: 0 +# UserID: 3669702 +# Time_year: 2007 +# Time_month: 5 +# Time_day: 14 +# Time_hour: 19 +# Time_min: 57 +# Time_sec: 39 +# PositionAccuracy: 1 +# Position_longitude: -76.35236166666666666666666667 +# Position_latitude: 36.88376666666666666666666667 +# fixtype: 7 +# Spare: 0 +# RAIM: False +# state_syncstate: 0 +# state_slottimeout: 4 +# state_slotoffset: 1503 +# diff --git a/test/schwehr.aivdm.chk b/test/schwehr.aivdm.chk new file mode 100644 index 00000000..f3d22f7f --- /dev/null +++ b/test/schwehr.aivdm.chk @@ -0,0 +1,118 @@ +# Sample AIVDM data sentences provided from real data by Kurt Schwehr +# +# Sample sentences of types 1-4. +# +1,0,371798000,Under way using engine,fastleft,12.3,1,-123.3954,48.3816,2240,215,33,0,0,84e1 +# RepeatIndicator: 0 +# UserID: 371798000 +# NavigationStatus: 0 +# ROT: -127 +# SOG: 12.3 +# PositionAccuracy: 1 +# longitude: -123.395383333 +# latitude: 48.38163333333 +# COG: 224 +# TrueHeading: 215 +# TimeStamp: 33 +# RegionalReserved: 0 +# Spare: 0 +# RAIM: False +# state_syncstate: 0 +# state_slotoffset: 4252 +# +1,0,440348000,Under way using engine,nan,0.0,0,-70.7582,43.0802,934,511,13,0,0,81fa +# RepeatIndicator: 0 +# UserID: 440348000 +# NavigationStatus: 0 +# ROT: -128 +# SOG: 0 +# PositionAccuracy: 0 +# longitude: -70.7582 +# latitude: 43.08015 +# COG: 93.4 +# TrueHeading: 511 +# TimeStamp: 13 +# RegionalReserved: 0 +# Spare: 0 +# RAIM: False +# state_syncstate: 0 +# stare_slottimeout: 2 +# state_slotoffset: 506 +# +# 2 is really uncommon +# +2,0,356302000,Under way using engine,fastright,13.9,0,-71.6261,40.3924,877,91,41,0,0,c006 +# RepeatIndicator: 0 +# UserID: 356302000 +# NavigationStatus: 0 +# ROT: 127 +# SOG: 13.9 +# PositionAccuracy: 0 +# longitude: -71.62614333333333333333333333 +# latitude: 40.39235833333333333333333333 +# COG: 87.7 +# TrueHeading: 91 +# TimeStamp: 41 +# RegionalReserved: 0 +# Spare: 0 +# RAIM: False +# state_syncstate: 0 +# state_slottimeout: 3 +# state_slotoffset: 6 +# +3,1,563808000,Moored,0,0.0,1,-76.3275,36.9100,2520,352,35,0,0,0 +# RepeatIndicator: 0 +# UserID: 563808000 +# NavigationStatus: 5 +# ROT: 0 +# SOG: 0 +# PositionAccuracy: 1 +# longitude: -76.32753333333333333333333333 +# latitude: 36.91 +# COG: 252 +# TrueHeading: 352 +# TimeStamp: 35 +# RegionalReserved: 0 +# Spare: 0 +# RAIM: False +# state_syncstate: 0 +# state_slottimeout: 0 +# state_slotoffset: 0 +# +4,0,003669702,2007:05:14T19:57:39Z,1,36.8838,-76.3524,Surveyed,0,82ef +# RepeatIndicator: 0 +# UserID: 3669702 +# Time_year: 2007 +# Time_month: 5 +# Time_day: 14 +# Time_hour: 19 +# Time_min: 57 +# Time_sec: 39 +# PositionAccuracy: 1 +# Position_longitude: -76.35236166666666666666666667 +# Position_latitude: 36.88376666666666666666666667 +# fixtype: 7 +# Spare: 0 +# RAIM: False +# state_syncstate: 0 +# state_slottimeout: 4 +# state_slotoffset: 1503 +# +# RepeatIndicator: 0 +# UserID: 3669702 +# Time_year: 2007 +# Time_month: 5 +# Time_day: 14 +# Time_hour: 19 +# Time_min: 57 +# Time_sec: 39 +# PositionAccuracy: 1 +# Position_longitude: -76.35236166666666666666666667 +# Position_latitude: 36.88376666666666666666666667 +# fixtype: 7 +# Spare: 0 +# RAIM: False +# state_syncstate: 0 +# state_slottimeout: 4 +# state_slotoffset: 1503 +# diff --git a/www/AIVDM.txt b/www/AIVDM.txt index 9f7b891e..76a9c620 100644 --- a/www/AIVDM.txt +++ b/www/AIVDM.txt @@ -30,23 +30,29 @@ found at <<AIS>>. == Standards == -The relevant standard is ITU Recommendation M.1371, "Technical -Characteristics for a Universal Shipborne Automatic. Identification -System Using Time Division Multiple Access" <<ITU1371>>, issued in 2001. It is -proprietary, expensive, and surrounded by attack lawyers, which is why -this document exists. I have not looked at it. +ITU Recommendation M.1371, "Technical Characteristics for a Universal +Shipborne Automatic. Identification System Using Time Division +Multiple Access" <<ITU1371>>, issued in 2001, describes the format of +AIS binary messages. It is proprietary, expensive, and surrounded by +attack lawyers, which is why this document exists. I have not looked +at it. ITU-R M.1371 is expanded and clarified by "IALA Technical Clarifications on Recommendation ITU-R M.1371-1" <<IALA>>, which is freely available. +I have been unable to determine what technical standard sets the ASCII +format for AIS messages; most likely it is <<NMEA>>, which I also have +not looked at because it is proprietary and expensive and surrounded +by even more rapacious attack lawyers. + == Information Sources == Together, the the IALA Technical Clarifications at <<IALA>> and the Coast Guard's AIS pages at <<NAVCEN>> describe AIS message payloads almost completely. The detail information on payload formats in this document is derived from these. Together, they explain everything -except the Repeat Indicator found in some messages +except the Repeat Indicator found in some messages. The AIVDM ASCII packet format is described at <<BOSUN>>. @@ -56,7 +62,7 @@ There's a web form that does sentence decoding at http://rl.se/aivdm. AIVDM/AIVDO is a two-layer protocol. The outer layer is a variant of NMEA 0183, the ancient standard for data interchange in marine -navigation systems, described at <<NMEA>>. +navigation systems; NMEA 0183 is described at <<NMEA>>. Here is a typical AIVDM data packet: @@ -180,7 +186,7 @@ software. Field Len Description Units ------------------------------------------------------------------------------- 0-5 6 Message Type Unsigned integer: 1-24 -6-7 2 Repeat Indicator Unknown +6-7 2 Repeat Indicator Unknown; 3 = "Do not repeat". 8-37 30 MMSI Unsigned integer: 9 decimal digits 38-41 4 Navigation Status See table below 42-49 8 Rate of Turn (ROT) Signed integer: see below @@ -242,7 +248,7 @@ default. Latitude is given in in 1/10000 min. Values up to plus or minus 90 degrees, North = positive, South = negative. A value of 91 degrees (0x3412140 -hex) indicates latitude is not available (default). +hex) indicates latitude is not available and is the default. Seconds in UTC timestamp should be 0-59, except for these special values: @@ -418,6 +424,20 @@ Code Ship & Cargo Classification 99 Other Type, no additional information ------------------------------------------------------------- +== Local extensions == + +Some regional authorities extend the AIS message set. + +The St. Lawrence Seaway broadcasts hydrological and lock-scheduling +messages using special encodings of the binary data of message types 6 +and 8 (described in <<SEAWAY>>, freely available), and safety +information using types 12 and 14. + +The U.S. Coast Guard has a system called PAWSS (Port and Water Safety +System) which uses extended AIS formats. <<SEAWAY>> says it's +intercompatible with the St. Lawrence Seaway system; I have not +been able to find any message documentation, however. + == References == [bibliography] @@ -439,3 +459,6 @@ Identification System] - [[[BOSUN]]] http://www.bosunsmate.org/ais/[Marine Automatic Identification System (AIS)] - [[[NMEA]]] http://gpsd.berlios.de/standards/NMEA.txt[NMEA sentences] + +- [[[SEAWAY]]] http://www.greatlakes-seaway.com/en/pdf/aisdata.pdf[St. Lawrence + Seaway AIS Data Messaging Formats and Specifications] |