summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2009-09-01 09:41:37 +0000
committerEric S. Raymond <esr@thyrsus.com>2009-09-01 09:41:37 +0000
commit17a2237540735cfe3284226e4422bb1d09e71b4e (patch)
tree14f4529031e2c64c6850bcf9ca3bd6704f9c3af9
parentafb11120aba9cbe40e2e3e0f04550833817253e5 (diff)
downloadgpsd-17a2237540735cfe3284226e4422bb1d09e71b4e.tar.gz
Fix dumping of AIS message 19 (dte was missing).
Code generation for AIS messages up to 19. Rebuild two affected regression tests (all tests pass).
-rw-r--r--driver_aivdm.c10
-rw-r--r--gps.h12
-rw-r--r--gpsd_json.c50
-rw-r--r--gpsdecode.c13
-rwxr-xr-xjsongen.py117
-rw-r--r--test/schwehr.aivdm.chk2
-rw-r--r--test/stable/ait250.log (renamed from test/stable/at250.log)0
-rw-r--r--www/AIVDM.txt4
8 files changed, 163 insertions, 45 deletions
diff --git a/driver_aivdm.c b/driver_aivdm.c
index 825b6300..71c0e403 100644
--- a/driver_aivdm.c
+++ b/driver_aivdm.c
@@ -372,11 +372,11 @@ bool aivdm_decode(char *buf, size_t buflen, struct aivdm_context_t *ais_context)
ais->type18.heading = UBITS(124, 9);
ais->type18.second = UBITS(133, 6);
ais->type18.regional = UBITS(139, 2);
- ais->type18.cs_flag = UBITS(141, 1)!=0;
- ais->type18.display_flag = UBITS(142, 1)!=0;
- ais->type18.dsc_flag = UBITS(143, 1)!=0;
- ais->type18.band_flag = UBITS(144, 1)!=0;
- ais->type18.msg22_flag = UBITS(145, 1)!=0;
+ ais->type18.cs = UBITS(141, 1)!=0;
+ ais->type18.display = UBITS(142, 1)!=0;
+ ais->type18.dsc = UBITS(143, 1)!=0;
+ ais->type18.band = UBITS(144, 1)!=0;
+ ais->type18.msg22 = UBITS(145, 1)!=0;
ais->type18.assigned = UBITS(146, 1)!=0;
ais->type18.raim = UBITS(147, 1)!=0;
ais->type18.radio = UBITS(148, 20);
diff --git a/gps.h b/gps.h
index becc2ea2..9e50da98 100644
--- a/gps.h
+++ b/gps.h
@@ -660,16 +660,18 @@ struct ais_t
uint speed; /* speed over ground in deciknots */
bool accuracy; /* position accuracy */
int lon; /* longitude */
+#define AIS_GNS_LON_NOT_AVAILABLE 0x1a838
int lat; /* latitude */
+#define AIS_GNS_LAT_NOT_AVAILABLE 0xd548
uint course; /* course over ground */
uint heading; /* true heading */
uint second; /* seconds of UTC timestamp */
uint regional; /* regional reserved */
- bool cs_flag; /* carrier sense unit flag */
- bool display_flag; /* unit has attached display? */
- bool dsc_flag; /* unit attached to radio with DSC? */
- bool band_flag; /* unit can switch frequency bands? */
- bool msg22_flag; /* can accept Message 22 management? */
+ bool cs; /* carrier sense unit flag */
+ bool display; /* unit has attached display? */
+ bool dsc; /* unit attached to radio with DSC? */
+ bool band; /* unit can switch frequency bands? */
+ bool msg22; /* can accept Message 22 management? */
bool assigned; /* assigned-mode flag */
bool raim; /* RAIM flag */
uint radio; /* radio status bits */
diff --git a/gpsd_json.c b/gpsd_json.c
index 24462a03..e68267d0 100644
--- a/gpsd_json.c
+++ b/gpsd_json.c
@@ -877,11 +877,11 @@ void aivdm_json_dump(struct ais_t *ais, bool scaled, char *buf, size_t buflen)
"\"text\":\"%s\"}\r\n",
json_stringify(buf1, sizeof(buf1), ais->type14.text));
break;
- case 15:
+ case 15: /* Interrogation */
(void)snprintf(buf+strlen(buf), buflen-strlen(buf),
- "mmsi1=%u,\"type1_1\"=%u,\"offset1_1\"=%u,"
- "\"type1_2\"=%u,\"offset1_2\"=%u,\"mmsi2\"=%u,"
- "\"type2_1\"=%u,\"offset2_1\"=%u}\r\n",
+ "mmsi1:%u,\"type1_1\":%u,\"offset1_1\":%u,"
+ "\"type1_2\":%u,\"offset1_2\":%u,\"mmsi2\":%u,"
+ "\"type2_1\":%u,\"offset2_1\":%u}\r\n",
ais->type15.mmsi1,
ais->type15.type1_1,
ais->type15.offset1_1,
@@ -893,8 +893,8 @@ void aivdm_json_dump(struct ais_t *ais, bool scaled, char *buf, size_t buflen)
break;
case 16:
(void)snprintf(buf+strlen(buf), buflen-strlen(buf),
- "\"mmsi1\"=%u,\"offset1\"=%u,\"increment1\"=%u,"
- "\"mmsi2\"=%u,\"offset2\"=%u,\"increment2\"=%u}\r\n",
+ "\"mmsi1\":%u,\"offset1\":%u,\"increment1\":%u,"
+ "\"mmsi2\":%u,\"offset2\":%u,\"increment2\":%u}\r\n",
ais->type16.mmsi1,
ais->type16.offset1,
ais->type16.increment1,
@@ -927,8 +927,8 @@ void aivdm_json_dump(struct ais_t *ais, bool scaled, char *buf, size_t buflen)
"\"reserved\":%u,\"speed\":%.1f,\"accuracy\":%s,"
"\"lon\":%.4f,\"lat\":%.4f,\"course\":%.1f,"
"\"heading\":%d,\"second\":%u,\"regional\":%d,"
- "\"cs\":%u,\"display\":%u,\"dsc\":%u,\"band\":%u,"
- "\"msg22\":%u,\"raim\":%s,\"radio\":%d}\r\n",
+ "\"cs\":%s,\"display\":%s,\"dsc\":%s,\"band\":%s,"
+ "\"msg22\":%s,\"raim\":%s,\"radio\":%d}\r\n",
ais->type18.reserved,
ais->type18.speed / 10.0,
JSON_BOOL(ais->type18.accuracy),
@@ -938,11 +938,11 @@ void aivdm_json_dump(struct ais_t *ais, bool scaled, char *buf, size_t buflen)
ais->type18.heading,
ais->type18.second,
ais->type18.regional,
- ais->type18.cs_flag,
- ais->type18.display_flag,
- ais->type18.dsc_flag,
- ais->type18.band_flag,
- ais->type18.msg22_flag,
+ JSON_BOOL(ais->type18.cs),
+ JSON_BOOL(ais->type18.display),
+ JSON_BOOL(ais->type18.dsc),
+ JSON_BOOL(ais->type18.band),
+ JSON_BOOL(ais->type18.msg22),
JSON_BOOL(ais->type18.raim),
ais->type18.radio);
} else {
@@ -950,8 +950,8 @@ void aivdm_json_dump(struct ais_t *ais, bool scaled, char *buf, size_t buflen)
"\"reserved\":%u,\"speed\":%u,\"accuracy\":%s,"
"\"lon\":%d,\"lat\":%d,\"course\":%u,"
"\"heading\":%d,\"second\":%u,\"regional\":%d,"
- "\"cs\":%u,\"display\":%u,\"dsc\":%u,\"band\":%u,"
- "\"msg22\":%u,\"raim\":%s,\"radio\":%d}\r\n",
+ "\"cs\":%s,\"display\":%s,\"dsc\":%s,\"band\":%s,"
+ "\"msg22\":%s,\"raim\":%s,\"radio\":%d}\r\n",
ais->type18.reserved,
ais->type18.speed,
JSON_BOOL(ais->type18.accuracy),
@@ -961,11 +961,11 @@ void aivdm_json_dump(struct ais_t *ais, bool scaled, char *buf, size_t buflen)
ais->type18.heading,
ais->type18.second,
ais->type18.regional,
- ais->type18.cs_flag,
- ais->type18.display_flag,
- ais->type18.dsc_flag,
- ais->type18.band_flag,
- ais->type18.msg22_flag,
+ JSON_BOOL(ais->type18.cs),
+ JSON_BOOL(ais->type18.display),
+ JSON_BOOL(ais->type18.dsc),
+ JSON_BOOL(ais->type18.band),
+ JSON_BOOL(ais->type18.msg22),
JSON_BOOL(ais->type18.raim),
ais->type18.radio);
}
@@ -979,7 +979,7 @@ void aivdm_json_dump(struct ais_t *ais, bool scaled, char *buf, size_t buflen)
"\"shipname\":\"%s\",\"shiptype\":\"%s\","
"\"to_bow\":%u,\"to_stern\":%u,\"to_port\":%u,"
"\"to_starboard\":%u,\"epfd\":\"%s\",\"raim\":%s,"
- "\"assigned\":%d}\r\n",
+ "\"dte\":%u,\"assigned\":%s}\r\n",
ais->type19.reserved,
ais->type19.speed / 10.0,
JSON_BOOL(ais->type19.accuracy),
@@ -997,7 +997,8 @@ void aivdm_json_dump(struct ais_t *ais, bool scaled, char *buf, size_t buflen)
ais->type19.to_starboard,
epfd_legends[ais->type19.epfd],
JSON_BOOL(ais->type19.raim),
- ais->type19.assigned);
+ ais->type19.dte,
+ JSON_BOOL(ais->type19.assigned));
} else {
(void)snprintf(buf+strlen(buf), buflen-strlen(buf),
"\"reserved\":%u,\"speed\":%u,\"accuracy\":%s,"
@@ -1006,7 +1007,7 @@ void aivdm_json_dump(struct ais_t *ais, bool scaled, char *buf, size_t buflen)
"\"shipname\":\"%s\",\"shiptype\":%u,"
"\"to_bow\":%u,\"stern\":%u,\"port\":%u,"
"\"starboard\":%u,\"epfd\":%u,\"raim\":%s,"
- "\"assigned\":%d}\r\n",
+ "\"dte\":%u,\"assigned\":%s}\r\n",
ais->type19.reserved,
ais->type19.speed,
JSON_BOOL(ais->type19.accuracy),
@@ -1024,7 +1025,8 @@ void aivdm_json_dump(struct ais_t *ais, bool scaled, char *buf, size_t buflen)
ais->type19.to_starboard,
ais->type19.epfd,
JSON_BOOL(ais->type19.raim),
- ais->type19.assigned);
+ ais->type19.dte,
+ JSON_BOOL(ais->type19.assigned));
}
break;
case 20: /* Data Link Management Message */
diff --git a/gpsdecode.c b/gpsdecode.c
index 2f4054dd..923960f3 100644
--- a/gpsdecode.c
+++ b/gpsdecode.c
@@ -211,17 +211,17 @@ static void aivdm_csv_dump(struct ais_t *ais, char *buf, size_t buflen)
ais->type18.heading,
ais->type18.second,
ais->type18.regional,
- ais->type18.cs_flag,
- ais->type18.display_flag,
- ais->type18.dsc_flag,
- ais->type18.band_flag,
- ais->type18.msg22_flag,
+ ais->type18.cs,
+ ais->type18.display,
+ ais->type18.dsc,
+ ais->type18.band,
+ ais->type18.msg22,
ais->type18.raim,
ais->type18.radio);
break;
case 19:
(void)snprintf(buf+strlen(buf), buflen-strlen(buf),
- "%u,%u,%u,%d,%d,%u,%u,%u,0x%x,%s,%u,%u,%u,%u,%u,%u,%d,0x%x",
+ "%u,%u,%u,%d,%d,%u,%u,%u,0x%x,%s,%u,%u,%u,%u,%u,%u,%d,%u,%u",
ais->type19.reserved,
ais->type19.speed,
(uint)ais->type19.accuracy,
@@ -239,6 +239,7 @@ static void aivdm_csv_dump(struct ais_t *ais, char *buf, size_t buflen)
ais->type19.to_starboard,
ais->type19.epfd,
ais->type19.raim,
+ ais->type19.dte,
ais->type19.assigned);
break;
case 20: /* Data Link Management Message */
diff --git a/jsongen.py b/jsongen.py
index 9c7cca16..fbbd2a31 100755
--- a/jsongen.py
+++ b/jsongen.py
@@ -19,7 +19,7 @@ ais_specs = (
{
"initname" : "json_ais1",
"header": "\tAIS_HEADER,",
- "structname": "ais->type123",
+ "structname": "ais->type1",
"fieldmap":(
# fieldname type default
('status', 'uinteger', '0'),
@@ -36,6 +36,7 @@ ais_specs = (
('radio', 'integer', '0'),
),
},
+ # Message types 2 and 3 duplicate 1
{
"initname" : "json_ais4",
"header": "\tAIS_HEADER,",
@@ -140,6 +141,7 @@ ais_specs = (
('dest_mmsi', 'uinteger', '0'),
),
},
+ # Message type 11 duplicates 4
{
"initname" : "json_ais12",
"header": "\tAIS_HEADER,",
@@ -164,17 +166,128 @@ ais_specs = (
('mmsi4', 'uinteger', '0'),
),
},
+ {
+ "initname" : "json_ais14",
+ "header": "\tAIS_HEADER,",
+ "structname": "ais->type14",
+ "fieldmap":(
+ # fieldname type default
+ ('text', 'string', None),
+ ),
+ },
+ {
+ "initname" : "json_ais15",
+ "header": "\tAIS_HEADER,",
+ "structname": "ais->type15",
+ "fieldmap":(
+ # fieldname type default
+ ('mmsi1', 'uinteger', '0'),
+ ('type1_1', 'uinteger', '0'),
+ ('offset1_1', 'uinteger', '0'),
+ ('type1_2', 'uinteger', '0'),
+ ('offset1_2', 'uinteger', '0'),
+ ('mmsi2', 'uinteger', '0'),
+ ('type2_1', 'uinteger', '0'),
+ ('offset2_1', 'uinteger', '0'),
+ ),
+ },
+ {
+ "initname" : "json_ais16",
+ "header": "\tAIS_HEADER,",
+ "structname": "ais->type16",
+ "fieldmap":(
+ # fieldname type default
+ ('mmsi1', 'uinteger', '0'),
+ ('offset1', 'uinteger', '0'),
+ ('increment1', 'uinteger', '0'),
+ ('mmsi2', 'uinteger', '0'),
+ ('offset2', 'uinteger', '0'),
+ ('increment2', 'uinteger', '0'),
+ ),
+ },
+ {
+ "initname" : "json_ais17",
+ "header": "\tAIS_HEADER,",
+ "structname": "ais->type17",
+ "fieldmap":(
+ # fieldname type default
+ ('lon', 'integer', 'AIS_GNS_LON_NOT_AVAILABLE'),
+ ('lat', 'integer', 'AIS_GNS_LAT_NOT_AVAILABLE'),
+ ('data', 'string', None),
+ ),
+ },
+ {
+ "initname" : "json_ais18",
+ "header": "\tAIS_HEADER,",
+ "structname": "ais->type18",
+ "fieldmap":(
+ # fieldname type default
+ ('reserved', 'uinteger', '0'),
+ ('speed', 'uinteger', 'AIS_SPEED_NOT_AVAILABLE'),
+ ('accuracy', 'boolean', 'false'),
+ ('lon', 'integer', 'AIS_LON_NOT_AVAILABLE'),
+ ('lat', 'integer', 'AIS_LAT_NOT_AVAILABLE'),
+ ('course', 'uinteger', 'AIS_COURSE_NOT_AVAILABLE'),
+ ('heading', 'integer', 'AIS_HEADING_NOT_AVAILABLE'),
+ ('second', 'uinteger', 'AIS_SEC_NOT_AVAILABLE'),
+ ('regional', 'integer', '0'),
+ ('cs', 'boolean', 'false'),
+ ('display', 'boolean', 'false'),
+ ('dsc', 'boolean', 'false'),
+ ('band', 'boolean', 'false'),
+ ('msg22', 'boolean', 'false'),
+ ('raim', 'boolean', 'false'),
+ ('radio', 'integer', '0'),
+ ),
+ },
+ {
+ "initname" : "json_ais19",
+ "header": "\tAIS_HEADER,",
+ "structname": "ais->type19",
+ "fieldmap":(
+ # fieldname type default
+ ('reserved', 'uinteger', '0'),
+ ('speed', 'uinteger', 'AIS_SPEED_NOT_AVAILABLE'),
+ ('accuracy', 'boolean', 'false'),
+ ('lon', 'integer', 'AIS_LON_NOT_AVAILABLE'),
+ ('lat', 'integer', 'AIS_LAT_NOT_AVAILABLE'),
+ ('course', 'uinteger', 'AIS_COURSE_NOT_AVAILABLE'),
+ ('heading', 'integer', 'AIS_HEADING_NOT_AVAILABLE'),
+ ('second', 'uinteger', 'bAIS_SEC_NOT_AVAILABLE'),
+ ('regional', 'integer', '0'),
+ ('shipname', 'string', None),
+ ('shiptype', 'uinteger', '0'),
+ ('to_bow', 'uinteger', '0'),
+ ('stern', 'uinteger', '0'),
+ ('port', 'uinteger', '0'),
+ ('starboard', 'uinteger', '0'),
+ ('epfd', 'uinteger', '0'),
+ ('raim', 'boolean', 'false'),
+ ('dte', 'integer', '1'),
+ ('assigned', 'boolean', 'false'),
+ ),
+ },
)
# Give this global the string spec you need to convert with -g
# We do it this mildly odd way only because passing Python multiline
# string literals on the command line is inconvenient.
stringspec = \
- "\"mmsi1\":%u,\"mmsi2\":%u,\"mmsi3\":%u,\"mmsi4\":%u}\r\n"
+ "\"reserved\":%u,\"speed\":%u,\"accuracy\":%s,"\
+ "\"lon\":%d,\"lat\":%d,\"course\":%u,"\
+ "\"heading\":%d,\"second\":%u,\"regional\":%d,"\
+ "\"shipname\":\"%s\",\"shiptype\":%u,"\
+ "\"to_bow\":%u,\"stern\":%u,\"port\":%u,"\
+ "\"starboard\":%u,\"epfd\":%u,\"raim\":%s,"\
+ "\"dte\":%s,\"assigned\":%s}\r\n"
# You should not need to modify anything below this liine.
def generate(spec):
+ print """/*
+ * This is code generated by jsongen.py. Do not hand-hack it.
+ */
+"""
outboard = []
for (attr, itype, default) in spec["fieldmap"]:
if attr in spec.get("stringbuffered", []):
diff --git a/test/schwehr.aivdm.chk b/test/schwehr.aivdm.chk
index f88bdfd7..eb9cb1dd 100644
--- a/test/schwehr.aivdm.chk
+++ b/test/schwehr.aivdm.chk
@@ -12,6 +12,6 @@
11,0,304137000,2009:05:22T02:22:40Z,1,-56644610,17045470,1,0,0x0
18,0,338087471,0,1,0,-44443279,24410724,796,511,49,0x0,1,0,1,1,1,1,0xe0006
18,0,338088483,0,0,0,-42486718,25869335,1716,511,20,0x0,1,0,1,1,1,1,0xe0006
-19,0,367059850,248,87,0,-53286235,17726217,3359,511,46,0x4,CAPT.J.RIMES,70,5,21,4,4,0,0,0x0
+19,0,367059850,248,87,0,-53286235,17726217,3359,511,46,0x4,CAPT.J.RIMES,70,5,21,4,4,0,0,0,0
24,0,367405970,0,CAPTAIN`S PARADISE
24,2,338085242,1,54,ACR1234,WDD7883,8,3,2,1
diff --git a/test/stable/at250.log b/test/stable/ait250.log
index e8dc3199..e8dc3199 100644
--- a/test/stable/at250.log
+++ b/test/stable/ait250.log
diff --git a/www/AIVDM.txt b/www/AIVDM.txt
index 4cbcf16c..512926d8 100644
--- a/www/AIVDM.txt
+++ b/www/AIVDM.txt
@@ -975,8 +975,8 @@ Field Len Description Member Units
Nore that latitude and longitude are in units of a tenth of a minute;
sign interpretation and out-of-band values are as in the Common
Navigation Clock. (Note, howeverm that the hex representastion of
-the out-of-band values differs; it is 181 * 60 * 10 = 0x1a838 for
-longitude, 91 * 60 * 10 = 0xd548 for latitude.)
+the out-of-band values differs; it is 181 \* 60 \* 10 = 0x1a838 for
+longitude, 91 \* 60 \* 10 = 0xd548 for latitude.)
The <<IALA>> description of the payload portion subfields has been
omitted, as it appears to be tied to the now obsolete RTCM2 protocol.