From 77d904797cfe8d1d2499e58c5cf316aa4731fa36 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 1 Sep 2009 10:21:48 +0000 Subject: Fix dumping of AIS message 20. All regression tests pass. Checkpoint before attempting to generate code for the rather nasty two-part message 24. --- gpsd_json.c | 92 +++++++++++++-------------- jsongen.py | 199 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- www/AIVDM.txt | 4 ++ 3 files changed, 241 insertions(+), 54 deletions(-) diff --git a/gpsd_json.c b/gpsd_json.c index e68267d0..6a1e9079 100644 --- a/gpsd_json.c +++ b/gpsd_json.c @@ -1031,14 +1031,14 @@ void aivdm_json_dump(struct ais_t *ais, bool scaled, char *buf, size_t buflen) break; case 20: /* Data Link Management Message */ (void)snprintf(buf+strlen(buf), buflen-strlen(buf), - "\"offset1\":\"%u\",\"number1\":\"%u\"," - "\"timeout1\":\"%u\",\"increment1\":\"%u\"," - "\"offset2\":\"%u\",\"number2\":\"%u\"," - "\"timeout2\":\"%u\",\"increment2\":\"%u\"," - "\"offset3\":\"%u\",\"number3\":\"%u\"," - "\"timeout3\":\"%u\",\"increment3\":\"%u\"," - "\"offset4\":\"%u\",\"number4\":\"%u\"," - "\"timeout4\":\"%u\",\"increment4\":\"%u\"}\r\n", + "\"offset1\":%u,\"number1\":%u," + "\"timeout1\":%u,\"increment1\":%u," + "\"offset2\":%u,\"number2\":%u," + "\"timeout2\":%u,\"increment2\":%u," + "\"offset3\":%u,\"number3\":%u," + "\"timeout3\":%u,\"increment3\":%u," + "\"offset4\":%u,\"number4\":%u," + "\"timeout4\":%u,\"increment4\":%u}\r\n", ais->type20.offset1, ais->type20.number1, ais->type20.timeout1, @@ -1087,8 +1087,8 @@ void aivdm_json_dump(struct ais_t *ais, bool scaled, char *buf, size_t buflen) "\"lon\":%d,\"lat\":%d,\"to_bow\":%u," "\"to_stern\":%u,\"to_port\":%u,\"to_starboard\":%u," "\"epfd\":%u,\"second\":%u,\"regional\":%d," - "\"off_position\":%d,\"raim\":%s," - "\"virtual_aid\":%u}\r\n", + "\"off_position\":%s,\"raim\":%s," + "\"virtual_aid\":%s}\r\n", ais->type21.type, ais->type21.name, JSON_BOOL(ais->type21.accuracy), @@ -1101,52 +1101,52 @@ void aivdm_json_dump(struct ais_t *ais, bool scaled, char *buf, size_t buflen) ais->type21.epfd, ais->type21.second, ais->type21.regional, - ais->type21.off_position, + JSON_BOOL(ais->type21.off_position), JSON_BOOL(ais->type21.raim), - ais->type21.virtual_aid); + JSON_BOOL(ais->type21.virtual_aid)); } break; case 22: /* Channel Management */ if (scaled) { (void)snprintf(buf+strlen(buf), buflen-strlen(buf), - "\"channel_a\":\"%u\",\"channel_b\":\"%u\"," - "\"mode\":\"%u\",\"power\":\"%u\"," + "\"channel_a\":%u,\"channel_b\":%u," + "\"mode\":%u,\"power\":%s," "\"ne_lon\":\"%f\",\"ne_lat\":\"%f\"," "\"sw_lon\":\"%f\",\"sw_lat\":\"%f\"," - "\"addressed\":\"%u\",\"band_a\":\"%u\"," - "\"band_b\":\"%u\",\"zonesize\":\":%u}\r\n", - ais->type22.channel_a, - ais->type22.channel_b, - ais->type22.mode, - ais->type22.power, - ais->type22.ne_lon / AIS_CHANNEL_LATLON_SCALE, - ais->type22.ne_lat / AIS_CHANNEL_LATLON_SCALE, - ais->type22.sw_lon / AIS_CHANNEL_LATLON_SCALE, - ais->type22.sw_lat / AIS_CHANNEL_LATLON_SCALE, - ais->type22.addressed, - ais->type22.band_a, - ais->type22.band_b, - ais->type22.zonesize); + "\"addressed\":%s,\"band_a\":%s," + "\"band_b\":%s,\"zonesize\":\":%u}\r\n", + ais->type22.channel_a, + ais->type22.channel_b, + ais->type22.mode, + JSON_BOOL(ais->type22.power), + ais->type22.ne_lon / AIS_CHANNEL_LATLON_SCALE, + ais->type22.ne_lat / AIS_CHANNEL_LATLON_SCALE, + ais->type22.sw_lon / AIS_CHANNEL_LATLON_SCALE, + ais->type22.sw_lat / AIS_CHANNEL_LATLON_SCALE, + JSON_BOOL(ais->type22.addressed), + JSON_BOOL(ais->type22.band_a), + JSON_BOOL(ais->type22.band_b), + ais->type22.zonesize); } else { (void)snprintf(buf+strlen(buf), buflen-strlen(buf), - "\"channel_a\":\"%u\",\"channel_b\":\"%u\"," - "\"mode\":\"%u\",\"power\":\"%u\"," - "\"ne_lon\":\"%d\",\"ne_lat\":\"%d\"," - "\"sw_lon\":\"%d\",\"sw_lat\":\"%d\"," - "\"addressed\":\"%u\",\"band_a\":\"%u\"," - "\"band_b\":\"%u\",\"zonesize\":\":%u}\r\n", - ais->type22.channel_a, - ais->type22.channel_b, - ais->type22.mode, - ais->type22.power, - ais->type22.ne_lon, - ais->type22.ne_lat, - ais->type22.sw_lon, - ais->type22.sw_lat, - ais->type22.addressed, - ais->type22.band_a, - ais->type22.band_b, - ais->type22.zonesize); + "\"channel_a\":%u,\"channel_b\":%u," + "\"mode\":%u,\"power\":%s," + "\"ne_lon\":%d,\"ne_lat\":%d," + "\"sw_lon\":%d,\"sw_lat\":%d," + "\"addressed\":%s,\"band_a\":%s," + "\"band_b\":%s,\"zonesize\":\":%u}\r\n", + ais->type22.channel_a, + ais->type22.channel_b, + ais->type22.mode, + JSON_BOOL(ais->type22.power), + ais->type22.ne_lon, + ais->type22.ne_lat, + ais->type22.sw_lon, + ais->type22.sw_lat, + JSON_BOOL(ais->type22.addressed), + JSON_BOOL(ais->type22.band_a), + JSON_BOOL(ais->type22.band_b), + ais->type22.zonesize); } break; case 24: /* Class B CS Static Data Report */ diff --git a/jsongen.py b/jsongen.py index fbbd2a31..ac7447f6 100755 --- a/jsongen.py +++ b/jsongen.py @@ -253,7 +253,123 @@ ais_specs = ( ('lat', 'integer', 'AIS_LAT_NOT_AVAILABLE'), ('course', 'uinteger', 'AIS_COURSE_NOT_AVAILABLE'), ('heading', 'integer', 'AIS_HEADING_NOT_AVAILABLE'), - ('second', 'uinteger', 'bAIS_SEC_NOT_AVAILABLE'), + ('second', 'uinteger', 'AIS_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'), + ), + }, + { + "initname" : "json_ais20", + "header": "\tAIS_HEADER,", + "structname": "ais->type20", + "fieldmap":( + # fieldname type default + ('offset1', 'uinteger', '0'), + ('number1', 'uinteger', '0'), + ('timeout1', 'uinteger', '0'), + ('increment1', 'uinteger', '0'), + ('offset2', 'uinteger', '0'), + ('number2', 'uinteger', '0'), + ('timeout2', 'uinteger', '0'), + ('increment2', 'uinteger', '0'), + ('offset3', 'uinteger', '0'), + ('number3', 'uinteger', '0'), + ('timeout3', 'uinteger', '0'), + ('increment3', 'uinteger', '0'), + ('offset4', 'uinteger', '0'), + ('number4', 'uinteger', '0'), + ('timeout4', 'uinteger', '0'), + ('increment4', 'uinteger', '0'), + ), + }, + { + "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', 'AIS_SEC_NOT_AVAILABLE'), ('regional', 'integer', '0'), ('shipname', 'string', None), ('shiptype', 'uinteger', '0'), @@ -267,19 +383,86 @@ ais_specs = ( ('assigned', 'boolean', 'false'), ), }, + { + "initname" : "json_ais20", + "header": "\tAIS_HEADER,", + "structname": "ais->type20", + "fieldmap":( + # fieldname type default + ('offset1', 'uinteger', '0'), + ('number1', 'uinteger', '0'), + ('timeout1', 'uinteger', '0'), + ('increment1', 'uinteger', '0'), + ('offset2', 'uinteger', '0'), + ('number2', 'uinteger', '0'), + ('timeout2', 'uinteger', '0'), + ('increment2', 'uinteger', '0'), + ('offset3', 'uinteger', '0'), + ('number3', 'uinteger', '0'), + ('timeout3', 'uinteger', '0'), + ('increment3', 'uinteger', '0'), + ('offset4', 'uinteger', '0'), + ('number4', 'uinteger', '0'), + ('timeout4', 'uinteger', '0'), + ('increment4', 'uinteger', '0'), + ), + }, + { + "initname" : "json_ais21", + "header": "\tAIS_HEADER,", + "structname": "ais->type21", + "fieldmap":( + # fieldname type default + ('type', 'uinteger', '0'), + ('name', 'string', None), + ('accuracy', 'boolean', 'false'), + ('lon', 'integer', 'AIS_LON_NOT_AVAILABLE'), + ('lat', 'integer', 'AIS_LAT_NOT_AVAILABLE'), + ('to_bow', 'uinteger', '0'), + ('to_stern', 'uinteger', '0'), + ('to_port', 'uinteger', '0'), + ('to_starboard', 'uinteger', '0'), + ('epfd', 'uinteger', '0'), + ('second', 'uinteger', '0'), + ('regional', 'integer', '0'), + ('off_position', 'boolean', 'false'), + ('raim', 'boolean', 'false'), + ('virtual_aid', 'boolean', 'false'), + ), + }, + { + "initname" : "json_ais22", + "header": "\tAIS_HEADER,", + "structname": "ais->type22", + "fieldmap":( + # fieldname type default + ('channel_a', 'uinteger', '0'), + ('channel_b', 'uinteger', '0'), + ('mode', 'uinteger', '0'), + ('power', 'boolean', 'false'), + ('ne_lon', 'integer', 'AIS_GNS_LON_NOT_AVAILABLE'), + ('ne_lat', 'integer', 'AIS_GNS_LAT_NOT_AVAILABLE'), + ('sw_lon', 'integer', 'AIS_GNS_LON_NOT_AVAILABLE'), + ('sw_lat', 'integer', 'AIS_GNS_LAT_NOT_AVAILABLE'), + ('addressed', 'boolean', 'false'), + ('band_a', 'boolean', 'false'), + ('band_b', 'boolean', 'false'), + ('zonesize', 'uinteger', '0'), + ), + }, ) + # 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 = \ - "\"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" + "\"channel_a\":%u,\"channel_b\":%u,"\ + "\"mode\":%u,\"power\":%u,"\ + "\"ne_lon\":%d,\"ne_lat\":%d,"\ + "\"sw_lon\":%d,\"sw_lat\":%d,"\ + "\"addressed\":%s,\"band_a\":%s,"\ + "\"band_b\":%s,\"zonesize\":\":%u}\r\n" # You should not need to modify anything below this liine. diff --git a/www/AIVDM.txt b/www/AIVDM.txt index 512926d8..d4d1c773 100644 --- a/www/AIVDM.txt +++ b/www/AIVDM.txt @@ -1234,6 +1234,10 @@ Field Len Description Member Units See <> for details on the meaning of these fields. +Note that the 'not available' values for longitudesc and latitudes +match the short ones used in message 17, nit the long ones used in the +common navigation block and elsewhere. + === Type 24: Class B CS Static Data Report === Equivalent of a Type 5 message for ships using Class B equipment. A -- cgit v1.2.1