summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Gagneraud <cgagneraud@techworks.ie>2012-06-05 14:12:10 +0100
committerChristian Gagneraud <chris@techworks.ie>2012-06-05 15:58:02 +0100
commit6b8f80981f791bdd0e1f35ea6fd40d04d5f01924 (patch)
tree7ea085a586d66cf1637dac5b3e5b495312929c44
parent0e8d0f6367a25c773021b9b3a73b7ce8cb953af7 (diff)
downloadgpsd-6b8f80981f791bdd0e1f35ea6fd40d04d5f01924.tar.gz
[AIS] Do scaling/offset operations only in json dump
splint and check pass.
-rw-r--r--driver_ais.c30
-rw-r--r--gps.h56
-rw-r--r--gpsd_json.c60
-rw-r--r--gpsdecode.c2
-rw-r--r--jsongen.py.in12
-rw-r--r--test/sample.aivdm.chk6
-rw-r--r--test/synthetic-ais.json4
-rw-r--r--www/AIVDM.txt73
8 files changed, 125 insertions, 118 deletions
diff --git a/driver_ais.c b/driver_ais.c
index 992063a3..385a448c 100644
--- a/driver_ais.c
+++ b/driver_ais.c
@@ -26,15 +26,6 @@
* Parse the data from the device
*/
-#define DAC1FID11_AIRTEMP_OFFSET 600
-#define DAC1FID11_DEWPOINT_OFFSET 200
-#define DAC1FID11_PRESSURE_OFFSET -800
-#define DAC1FID11_LEVEL_OFFSET 100
-#define DAC1FID11_WATERTEMP_OFFSET 100
-
-#define DAC1FID31_PRESSURE_OFFSET -799
-#define DAC1FID31_LEVEL_OFFSET 1000
-
static void from_sixbit(char *bitvec, uint start, int count, char *to)
{
/*@ +type @*/
@@ -408,17 +399,13 @@ bool ais_binary_decode(struct ais_t *ais,
ais->type8.dac1fid11.wgust = UBITS(128, 7);
ais->type8.dac1fid11.wdir = UBITS(135, 9);
ais->type8.dac1fid11.wgustdir = UBITS(144, 9);
- ais->type8.dac1fid11.airtemp = UBITS(153, 11)
- - DAC1FID11_AIRTEMP_OFFSET;
+ ais->type8.dac1fid11.airtemp = UBITS(153, 11);
ais->type8.dac1fid11.humidity = UBITS(164, 7);
- ais->type8.dac1fid11.dewpoint = UBITS(171, 10)
- - DAC1FID11_DEWPOINT_OFFSET;
- ais->type8.dac1fid11.pressure = UBITS(181, 9)
- - DAC1FID11_PRESSURE_OFFSET;
+ ais->type8.dac1fid11.dewpoint = UBITS(171, 10);
+ ais->type8.dac1fid11.pressure = UBITS(181, 9);
ais->type8.dac1fid11.pressuretend = UBITS(190, 2);
ais->type8.dac1fid11.visibility = UBITS(192, 8);
- ais->type8.dac1fid11.waterlevel = UBITS(200, 9)
- - DAC1FID11_LEVEL_OFFSET;
+ ais->type8.dac1fid11.waterlevel = UBITS(200, 9);
ais->type8.dac1fid11.leveltrend = UBITS(209, 2);
ais->type8.dac1fid11.cspeed = UBITS(211, 8);
ais->type8.dac1fid11.cdir = UBITS(219, 9);
@@ -435,8 +422,7 @@ bool ais_binary_decode(struct ais_t *ais,
ais->type8.dac1fid11.swellperiod = UBITS(303, 6);
ais->type8.dac1fid11.swelldir = UBITS(309, 9);
ais->type8.dac1fid11.seastate = UBITS(318, 4);
- ais->type8.dac1fid11.watertemp = UBITS(322, 10)
- - DAC1FID11_WATERTEMP_OFFSET;
+ ais->type8.dac1fid11.watertemp = UBITS(322, 10);
ais->type8.dac1fid11.preciptype = UBITS(332, 3);
ais->type8.dac1fid11.salinity = UBITS(335, 9);
ais->type8.dac1fid11.ice = UBITS(344, 2);
@@ -554,13 +540,11 @@ bool ais_binary_decode(struct ais_t *ais,
ais->type8.dac1fid31.airtemp = SBITS(154, 11);
ais->type8.dac1fid31.humidity = UBITS(165, 7);
ais->type8.dac1fid31.dewpoint = SBITS(172, 10);
- ais->type8.dac1fid31.pressure = UBITS(182, 9)
- - DAC1FID31_PRESSURE_OFFSET;
+ ais->type8.dac1fid31.pressure = UBITS(182, 9);
ais->type8.dac1fid31.pressuretend = UBITS(191, 2);
ais->type8.dac1fid31.visgreater = UBITS(193, 1);
ais->type8.dac1fid31.visibility = UBITS(194, 7);
- ais->type8.dac1fid31.waterlevel = UBITS(201, 12)
- - DAC1FID31_LEVEL_OFFSET;
+ ais->type8.dac1fid31.waterlevel = UBITS(201, 12);
ais->type8.dac1fid31.leveltrend = UBITS(213, 2);
ais->type8.dac1fid31.cspeed = UBITS(215, 8);
ais->type8.dac1fid31.cdir = UBITS(223, 9);
diff --git a/gps.h b/gps.h
index 09439ff3..966a2fee 100644
--- a/gps.h
+++ b/gps.h
@@ -1124,9 +1124,9 @@ struct ais_t
struct {
#define DAC1FID11_LATLON_SCALE 1000
int lon; /* longitude in minutes * .001 */
-#define DAC1FID11_LON_NOT_AVAILABLE 0x1FFFFFF
- int lat; /* longitude in minutes * .001 */
-#define DAC1FID11_LAT_NOT_AVAILABLE 0xFFFFFF
+#define DAC1FID11_LON_NOT_AVAILABLE 0xFFFFFF
+ int lat; /* latitude in minutes * .001 */
+#define DAC1FID11_LAT_NOT_AVAILABLE 0x7FFFFF
unsigned int day; /* UTC day */
unsigned int hour; /* UTC hour */
unsigned int minute; /* UTC minute */
@@ -1136,24 +1136,33 @@ struct ais_t
unsigned int wdir; /* wind direction */
unsigned int wgustdir; /* wind gust direction */
#define DAC1FID11_WDIR_NOT_AVAILABLE 511
- int airtemp; /* temperature, units 0.1C */
-#define DAC1FID11_AIRTEMP_NOT_AVAILABLE 1447
+ unsigned int airtemp; /* temperature, units 0.1C */
+#define DAC1FID11_AIRTEMP_NOT_AVAILABLE 2047
+#define DAC1FID11_AIRTEMP_OFFSET 600
+#define DAC1FID11_AIRTEMP_SCALE 10.0
unsigned int humidity; /* relative humidity, % */
#define DAC1FID11_HUMIDITY_NOT_AVAILABLE 127
- int dewpoint; /* dew point, units 0.1C */
-#define DAC1FID11_DEWPOINT_NOT_AVAILABLE 823
+ unsigned int dewpoint; /* dew point, units 0.1C */
+#define DAC1FID11_DEWPOINT_NOT_AVAILABLE 1023
+#define DAC1FID11_DEWPOINT_OFFSET 200
+#define DAC1FID11_DEWPOINT_SCALE 10.0
unsigned int pressure; /* air pressure, hpa */
-#define DAC1FID11_PRESSURE_NOT_AVAILABLE 1311
+#define DAC1FID11_PRESSURE_NOT_AVAILABLE 511
+#define DAC1FID11_PRESSURE_OFFSET -800
unsigned int pressuretend; /* tendency */
#define DAC1FID11_PRESSURETREND_NOT_AVAILABLE 3
unsigned int visibility; /* units 0.1 nautical miles */
#define DAC1FID11_VISIBILITY_NOT_AVAILABLE 255
- int waterlevel; /* decimeters */
-#define DAC1FID11_WATERLEVEL_NOT_AVAILABLE 411
+#define DAC1FID11_VISIBILITY_SCALE 10.0
+ unsigned int waterlevel; /* decimeters */
+#define DAC1FID11_WATERLEVEL_NOT_AVAILABLE 511
+#define DAC1FID11_WATERLEVEL_OFFSET 100
+#define DAC1FID11_WATERLEVEL_SCALE 10.0
unsigned int leveltrend; /* water level trend code */
-#define DAC1FID11_LEVELTREND_NOT_AVAILABLE 3
+#define DAC1FID11_WATERLEVELTREND_NOT_AVAILABLE 3
unsigned int cspeed; /* surface current speed in deciknots */
#define DAC1FID11_CSPEED_NOT_AVAILABLE 255
+#define DAC1FID11_CSPEED_SCALE 10.0
unsigned int cdir; /* surface current dir., degrees */
#define DAC1FID11_CDIR_NOT_AVAILABLE 511
unsigned int cspeed2; /* current speed in deciknots */
@@ -1165,6 +1174,7 @@ struct ais_t
unsigned int cdepth3; /* measurement depth, m */
unsigned int waveheight; /* in decimeters */
#define DAC1FID11_WAVEHEIGHT_NOT_AVAILABLE 255
+#define DAC1FID11_WAVEHEIGHT_SCALE 10.0
unsigned int waveperiod; /* in seconds */
#define DAC1FID11_WAVEPERIOD_NOT_AVAILABLE 63
unsigned int wavedir; /* direction in degrees */
@@ -1174,12 +1184,15 @@ struct ais_t
unsigned int swelldir; /* direction in degrees */
unsigned int seastate; /* Beaufort scale, 0-12 */
#define DAC1FID11_SEASTATE_NOT_AVAILABLE 15
- int watertemp; /* units 0.1deg Celsius */
-#define DAC1FID11_WATERTEMP_NOT_AVAILABLE 923
+ unsigned int watertemp; /* units 0.1deg Celsius */
+#define DAC1FID11_WATERTEMP_NOT_AVAILABLE 1023
+#define DAC1FID11_WATERTEMP_OFFSET 100
+#define DAC1FID11_WATERTEMP_SCALE 10.0
unsigned int preciptype; /* 0-7, enumerated */
#define DAC1FID11_PRECIPTYPE_NOT_AVAILABLE 7
unsigned int salinity; /* units of 0.1ppt */
#define DAC1FID11_SALINITY_NOT_AVAILABLE 511
+#define DAC1FID11_SALINITY_SCALE 10.0
unsigned int ice; /* is there sea ice? */
#define DAC1FID11_ICE_NOT_AVAILABLE 3
} dac1fid11;
@@ -1270,34 +1283,43 @@ struct ais_t
#define DAC1FID31_DIR_NOT_AVAILABLE 360
int airtemp; /* temperature, units 0.1C */
#define DAC1FID31_AIRTEMP_NOT_AVAILABLE -1024
+#define DAC1FID31_AIRTEMP_SCALE 10.0
unsigned int humidity; /* relative humidity, % */
#define DAC1FID31_HUMIDITY_NOT_AVAILABLE 101
int dewpoint; /* dew point, units 0.1C */
#define DAC1FID31_DEWPOINT_NOT_AVAILABLE 501
+#define DAC1FID31_DEWPOINT_SCALE 10.0
unsigned int pressure; /* air pressure, hpa */
#define DAC1FID31_PRESSURE_NOT_AVAILABLE 511
#define DAC1FID31_PRESSURE_HIGH 402
+#define DAC1FID31_PRESSURE_OFFSET -799
unsigned int pressuretend; /* tendency */
#define DAC1FID31_PRESSURETEND_NOT_AVAILABLE 3
bool visgreater; /* visibility greater than */
unsigned int visibility; /* units 0.1 nautical miles */
#define DAC1FID31_VISIBILITY_NOT_AVAILABLE 127
- int waterlevel; /* decimeters or cm */
+#define DAC1FID31_VISIBILITY_SCALE 10.0
+ int waterlevel; /* cm */
#define DAC1FID31_WATERLEVEL_NOT_AVAILABLE 4001
+#define DAC1FID31_WATERLEVEL_OFFSET 1000
+#define DAC1FID31_WATERLEVEL_SCALE 100.0
unsigned int leveltrend; /* water level trend code */
-#define DAC1FID31_LEVELTREND_NOT_AVAILABLE 3
+#define DAC1FID31_WATERLEVELTREND_NOT_AVAILABLE 3
unsigned int cspeed; /* current speed in deciknots */
#define DAC1FID31_CSPEED_NOT_AVAILABLE 255
+#define DAC1FID31_CSPEED_SCALE 10.0
unsigned int cdir; /* current dir., degrees */
unsigned int cspeed2; /* current speed in deciknots */
unsigned int cdir2; /* current dir., degrees */
unsigned int cdepth2; /* measurement depth, 0.1m */
#define DAC1FID31_CDEPTH_NOT_AVAILABLE 301
+#define DAC1FID31_CDEPTH_SCALE 10.0
unsigned int cspeed3; /* current speed in deciknots */
unsigned int cdir3; /* current dir., degrees */
unsigned int cdepth3; /* measurement depth, 0.1m */
unsigned int waveheight; /* in decimeters */
#define DAC1FID31_HEIGHT_NOT_AVAILABLE 31
+#define DAC1FID31_HEIGHT_SCALE 10.0
unsigned int waveperiod; /* in seconds */
#define DAC1FID31_PERIOD_NOT_AVAILABLE 63
unsigned int wavedir; /* direction in degrees */
@@ -1308,10 +1330,12 @@ struct ais_t
#define DAC1FID31_SEASTATE_NOT_AVAILABLE 15
int watertemp; /* units 0.1deg Celsius */
#define DAC1FID31_WATERTEMP_NOT_AVAILABLE 601
+#define DAC1FID31_WATERTEMP_SCALE 10.0
unsigned int preciptype; /* 0-7, enumerated */
#define DAC1FID31_PRECIPTYPE_NOT_AVAILABLE 7
- unsigned int salinity; /* units of 0.1% */
+ unsigned int salinity; /* units of 0.1 permil (ca. PSU) */
#define DAC1FID31_SALINITY_NOT_AVAILABLE 510
+#define DAC1FID31_SALINITY_SCALE 10.0
unsigned int ice; /* is there sea ice? */
#define DAC1FID31_ICE_NOT_AVAILABLE 3
} dac1fid31;
diff --git a/gpsd_json.c b/gpsd_json.c
index cdbc13a2..c5a00849 100644
--- a/gpsd_json.c
+++ b/gpsd_json.c
@@ -2118,7 +2118,7 @@ void json_aivdm_dump(const struct ais_t *ais,
if (ais->type8.dac == 1) {
const char *trends[] = {
"steady",
- "increasing"
+ "increasing",
"decreasing",
"N/A",
};
@@ -2169,13 +2169,13 @@ void json_aivdm_dump(const struct ais_t *ais,
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
"\"airtemp\":%.1f,\"dewpoint\":%.1f,"
"\"pressure\":%u,\"pressuretend\":\"%s\",",
- ais->type8.dac1fid11.airtemp * 0.1,
- ais->type8.dac1fid11.dewpoint * 0.1,
- ais->type8.dac1fid11.pressure,
+ (ais->type8.dac1fid11.airtemp - DAC1FID11_AIRTEMP_OFFSET) / DAC1FID11_AIRTEMP_SCALE,
+ (ais->type8.dac1fid11.dewpoint - DAC1FID11_DEWPOINT_OFFSET) / DAC1FID11_DEWPOINT_SCALE,
+ ais->type8.dac1fid11.pressure - DAC1FID11_PRESSURE_OFFSET,
trends[ais->type8.dac1fid11.pressuretend]);
else
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
- "\"airtemp\":%d,\"dewpoint\":%d,"
+ "\"airtemp\":%u,\"dewpoint\":%u,"
"\"pressure\":%u,\"pressuretend\":%u,",
ais->type8.dac1fid11.airtemp,
ais->type8.dac1fid11.dewpoint,
@@ -2185,19 +2185,19 @@ void json_aivdm_dump(const struct ais_t *ais,
if (scaled)
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
"\"visibility\":%.1f,",
- ais->type8.dac1fid11.visibility * 0.1);
+ ais->type8.dac1fid11.visibility / DAC1FID11_VISIBILITY_SCALE);
else
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
"\"visibility\":%u,",
ais->type8.dac1fid11.visibility);
if (!scaled)
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
- "\"waterlevel\":%d,",
+ "\"waterlevel\":%u,",
ais->type8.dac1fid11.waterlevel);
else
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
"\"waterlevel\":%.1f,",
- ais->type8.dac1fid11.waterlevel * 0.1);
+ (ais->type8.dac1fid11.waterlevel - DAC1FID11_WATERLEVEL_OFFSET) / DAC1FID11_WATERLEVEL_SCALE);
if (scaled) {
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
@@ -2208,26 +2208,26 @@ void json_aivdm_dump(const struct ais_t *ais,
"\"waveheight\":%.1f,\"waveperiod\":%u,\"wavedir\":%u,"
"\"swellheight\":%.1f,\"swellperiod\":%u,\"swelldir\":%u,"
"\"seastate\":%u,\"watertemp\":%.1f,"
- "\"preciptype\":%s,\"salinity\":%.1f,\"ice\":%s",
+ "\"preciptype\":\"%s\",\"salinity\":%.1f,\"ice\":\"%s\"",
trends[ais->type8.dac1fid11.leveltrend],
- ais->type8.dac1fid11.cspeed * 0.1,
+ ais->type8.dac1fid11.cspeed / DAC1FID11_CSPEED_SCALE,
ais->type8.dac1fid11.cdir,
- ais->type8.dac1fid11.cspeed2 * 0.1,
+ ais->type8.dac1fid11.cspeed2 / DAC1FID11_CSPEED_SCALE,
ais->type8.dac1fid11.cdir2,
ais->type8.dac1fid11.cdepth2,
- ais->type8.dac1fid11.cspeed3 * 0.1,
+ ais->type8.dac1fid11.cspeed3 / DAC1FID11_CSPEED_SCALE,
ais->type8.dac1fid11.cdir3,
ais->type8.dac1fid11.cdepth3,
- ais->type8.dac1fid11.waveheight * 0.1,
+ ais->type8.dac1fid11.waveheight / DAC1FID11_WAVEHEIGHT_SCALE,
ais->type8.dac1fid11.waveperiod,
ais->type8.dac1fid11.wavedir,
- ais->type8.dac1fid11.swellheight * 0.1,
+ ais->type8.dac1fid11.swellheight / DAC1FID11_WAVEHEIGHT_SCALE,
ais->type8.dac1fid11.swellperiod,
ais->type8.dac1fid11.swelldir,
ais->type8.dac1fid11.seastate,
- ais->type8.dac1fid11.watertemp * 0.1,
+ (ais->type8.dac1fid11.watertemp - DAC1FID11_WATERTEMP_OFFSET) / DAC1FID11_WATERTEMP_SCALE,
preciptypes[ais->type8.dac1fid11.preciptype],
- ais->type8.dac1fid11.salinity * 0.1,
+ ais->type8.dac1fid11.salinity / DAC1FID11_SALINITY_SCALE,
ice[ais->type8.dac1fid11.ice]);
} else
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
@@ -2237,7 +2237,7 @@ void json_aivdm_dump(const struct ais_t *ais,
"\"cspeed3\":%u,\"cdir3\":%u,\"cdepth3\":%u,"
"\"waveheight\":%u,\"waveperiod\":%u,\"wavedir\":%u,"
"\"swellheight\":%u,\"swellperiod\":%u,\"swelldir\":%u,"
- "\"seastate\":%u,\"watertemp\":%d,"
+ "\"seastate\":%u,\"watertemp\":%u,"
"\"preciptype\":%u,\"salinity\":%u,\"ice\":%u",
ais->type8.dac1fid11.leveltrend,
ais->type8.dac1fid11.cspeed,
@@ -2451,12 +2451,12 @@ void json_aivdm_dump(const struct ais_t *ais,
ais->type8.dac1fid31.humidity);
if (scaled)
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
- "\"airtemp\":%1f,\"dewpoint\":%1f,"
+ "\"airtemp\":%.1f,\"dewpoint\":%.1f,"
"\"pressure\":%u,\"pressuretend\":\"%s\","
"\"visgreater\":%s,",
- ais->type8.dac1fid31.airtemp * 0.1,
- ais->type8.dac1fid31.dewpoint * 0.1,
- ais->type8.dac1fid31.pressure,
+ ais->type8.dac1fid31.airtemp / DAC1FID31_AIRTEMP_SCALE,
+ ais->type8.dac1fid31.dewpoint / DAC1FID31_DEWPOINT_SCALE,
+ ais->type8.dac1fid31.pressure - DAC1FID31_PRESSURE_OFFSET,
trends[ais->type8.dac1fid31.pressuretend],
JSON_BOOL(ais->type8.dac1fid31.visgreater));
else
@@ -2473,7 +2473,7 @@ void json_aivdm_dump(const struct ais_t *ais,
if (scaled)
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
"\"visibility\":%.1f,",
- ais->type8.dac1fid31.visibility * 0.1);
+ ais->type8.dac1fid31.visibility / DAC1FID31_VISIBILITY_SCALE);
else
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
"\"visibility\":%u,",
@@ -2485,7 +2485,7 @@ void json_aivdm_dump(const struct ais_t *ais,
else
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
"\"waterlevel\":%.1f,",
- ais->type8.dac1fid31.waterlevel * 0.01);
+ (ais->type8.dac1fid31.waterlevel - DAC1FID31_WATERLEVEL_OFFSET) / DAC1FID31_WATERLEVEL_SCALE);
if (scaled) {
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
@@ -2498,24 +2498,24 @@ void json_aivdm_dump(const struct ais_t *ais,
"\"seastate\":%u,\"watertemp\":%.1f,"
"\"preciptype\":\"%s\",\"salinity\":%.1f,\"ice\":\"%s\"",
trends[ais->type8.dac1fid31.leveltrend],
- ais->type8.dac1fid31.cspeed * 0.1,
+ ais->type8.dac1fid31.cspeed / DAC1FID31_CSPEED_SCALE,
ais->type8.dac1fid31.cdir,
- ais->type8.dac1fid31.cspeed2 * 0.1,
+ ais->type8.dac1fid31.cspeed2 / DAC1FID31_CSPEED_SCALE,
ais->type8.dac1fid31.cdir2,
ais->type8.dac1fid31.cdepth2,
- ais->type8.dac1fid31.cspeed3 * 0.1,
+ ais->type8.dac1fid31.cspeed3 / DAC1FID31_CSPEED_SCALE,
ais->type8.dac1fid31.cdir3,
ais->type8.dac1fid31.cdepth3,
- ais->type8.dac1fid31.waveheight * 0.1,
+ ais->type8.dac1fid31.waveheight / DAC1FID31_HEIGHT_SCALE,
ais->type8.dac1fid31.waveperiod,
ais->type8.dac1fid31.wavedir,
- ais->type8.dac1fid31.swellheight * 0.1,
+ ais->type8.dac1fid31.swellheight / DAC1FID31_HEIGHT_SCALE,
ais->type8.dac1fid31.swellperiod,
ais->type8.dac1fid31.swelldir,
ais->type8.dac1fid31.seastate,
- ais->type8.dac1fid31.watertemp * 0.1,
+ ais->type8.dac1fid31.watertemp / DAC1FID31_WATERTEMP_SCALE,
preciptypes[ais->type8.dac1fid31.preciptype],
- ais->type8.dac1fid31.salinity * 0.1,
+ ais->type8.dac1fid31.salinity / DAC1FID31_SALINITY_SCALE,
ice[ais->type8.dac1fid31.ice]);
} else
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
diff --git a/gpsdecode.c b/gpsdecode.c
index 0198a66c..3ade9b8c 100644
--- a/gpsdecode.c
+++ b/gpsdecode.c
@@ -155,7 +155,7 @@ static void aivdm_csv_dump(struct ais_t *ais, char *buf, size_t buflen)
switch(ais->type8.fid) {
case 11: /* IMO236 - Met/Hydro message */
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
- "|%d|%d|%02uT%02u:%02uZ|%u|%u|%u|%u|%d|%u|%d|%u|%u|%u|%d|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%d|%u|%u|%u",
+ "|%d|%d|%02uT%02u:%02uZ|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u|%u",
ais->type8.dac1fid11.lon,
ais->type8.dac1fid11.lat,
ais->type8.dac1fid11.day,
diff --git a/jsongen.py.in b/jsongen.py.in
index 7c85b3c5..cf785291 100644
--- a/jsongen.py.in
+++ b/jsongen.py.in
@@ -305,14 +305,14 @@ ais_specs = (
('wgust', 'uinteger', 'DAC1FID11_WSPEED_NOT_AVAILABLE'),
('wdir', 'uinteger', 'DAC1FID11_WDIR_NOT_AVAILABLE'),
('wgustdir', 'uinteger', 'DAC1FID11_WDIR_NOT_AVAILABLE'),
- ('airtemp', 'integer', 'DAC1FID11_AIRTEMP_NOT_AVAILABLE'),
+ ('airtemp', 'uinteger', 'DAC1FID11_AIRTEMP_NOT_AVAILABLE'),
('humidity', 'uinteger', 'DAC1FID11_HUMIDITY_NOT_AVAILABLE'),
- ('dewpoint', 'integer', 'DAC1FID11_DEWPOINT_NOT_AVAILABLE'),
+ ('dewpoint', 'uinteger', 'DAC1FID11_DEWPOINT_NOT_AVAILABLE'),
('pressure', 'uinteger', 'DAC1FID11_PRESSURE_NOT_AVAILABLE'),
('pressuretend', 'uinteger', 'DAC1FID11_PRESSURETREND_NOT_AVAILABLE'),
('visibility', 'uinteger', 'DAC1FID11_VISIBILITY_NOT_AVAILABLE'),
- ('waterlevel', 'integer', 'DAC1FID11_WATERLEVEL_NOT_AVAILABLE'),
- ('leveltrend', 'uinteger', 'DAC1FID11_LEVELTREND_NOT_AVAILABLE'),
+ ('waterlevel', 'uinteger', 'DAC1FID11_WATERLEVEL_NOT_AVAILABLE'),
+ ('leveltrend', 'uinteger', 'DAC1FID11_WATERLEVELTREND_NOT_AVAILABLE'),
('cspeed', 'uinteger', 'DAC1FID11_CSPEED_NOT_AVAILABLE'),
('cdir', 'uinteger', 'DAC1FID11_CDIR_NOT_AVAILABLE'),
('cspeed2', 'uinteger', 'DAC1FID11_CSPEED_NOT_AVAILABLE'),
@@ -328,7 +328,7 @@ ais_specs = (
('swellperiod', 'uinteger', 'DAC1FID11_WAVEPERIOD_NOT_AVAILABLE'),
('swelldir', 'uinteger', 'DAC1FID11_WAVEDIR_NOT_AVAILABLE'),
('seastate', 'uinteger', 'DAC1FID11_SEASTATE_NOT_AVAILABLE'),
- ('watertemp', 'integer', 'DAC1FID11_WATERTEMP_NOT_AVAILABLE'),
+ ('watertemp', 'uinteger', 'DAC1FID11_WATERTEMP_NOT_AVAILABLE'),
('preciptype', 'uinteger', 'DAC1FID11_PRECIPTYPE_NOT_AVAILABLE'),
('salinity', 'uinteger', 'DAC1FID11_SALINITY_NOT_AVAILABLE'),
('ice', 'uinteger', 'DAC1FID11_ICE_NOT_AVAILABLE'),
@@ -455,7 +455,7 @@ ais_specs = (
('visgreater', 'boolean', 'false'),
('visibility', 'uinteger', 'DAC1FID31_VISIBILITY_NOT_AVAILABLE'),
('waterlevel', 'uinteger', 'DAC1FID31_WATERLEVEL_NOT_AVAILABLE'),
- ('leveltrend', 'uinteger', 'DAC1FID31_LEVELTREND_NOT_AVAILABLE'),
+ ('leveltrend', 'uinteger', 'DAC1FID31_WATERLEVELTREND_NOT_AVAILABLE'),
('cspeed', 'uinteger', 'DAC1FID31_CSPEED_NOT_AVAILABLE'),
('cdir', 'uinteger', 'DAC1FID31_DIR_NOT_AVAILABLE'),
('cspeed2', 'uinteger', 'DAC1FID31_CSPEED_NOT_AVAILABLE'),
diff --git a/test/sample.aivdm.chk b/test/sample.aivdm.chk
index 6b6adfd8..3b698060 100644
--- a/test/sample.aivdm.chk
+++ b/test/sample.aivdm.chk
@@ -12,9 +12,9 @@
7|2|537411077|43101326|717096664|76161024|0
8|0|366999712|366|56|256:3a53dbb7be4a773137f87d7b0445f040dea05d93f593783194ae9b9d9dbe05fb
8|0|999999999|366|56|256:eb0d4f917a035b2dfca3d4739381735c18ebbe754936f66850037dcacd9538b8
-8|0|992509977|1|11|-368039|3197693|18T17:15Z|3|6|12|15|142|50|123|1024|2|153|-84|1|103|256|104|257|10|126|203|20|42|35|25|23|48|124|3|123|6|53|0
-8|0|992509977|1|11|-368037|3197689|18T17:45Z|127|127|511|511|1447|127|823|1311|3|255|411|3|255|511|255|511|31|255|511|31|255|63|511|255|63|511|15|923|7|511|3
-8|0|992509977|1|31|-368044|3197696|29T23:24Z|127|127|360|360|-1024|101|501|1310|3|127|3001|3|255|360|255|360|31|255|360|31|255|63|360|255|63|360|13|501|7|510|3
+8|0|992509977|1|11|-368039|3197693|18T17:15Z|3|6|12|15|742|50|323|224|2|153|16|1|103|256|104|257|10|126|203|20|42|35|25|23|48|124|3|223|6|53|0
+8|0|992509977|1|11|-368037|3197689|18T17:45Z|127|127|511|511|2047|127|1023|511|3|255|511|3|255|511|255|511|31|255|511|31|255|63|511|255|63|511|15|1023|7|511|3
+8|0|992509977|1|31|-368044|3197696|29T23:24Z|127|127|360|360|-1024|101|501|511|3|127|4001|3|255|360|255|360|31|255|360|31|255|63|360|255|63|360|13|501|7|510|3
9|0|111265591|15|0|0|7128960|34667073|0|28|0x0|0|0|0x6015
10|0|366814480|366832740
10|0|440882000|366972000
diff --git a/test/synthetic-ais.json b/test/synthetic-ais.json
index 3622a2a6..32edcd29 100644
--- a/test/synthetic-ais.json
+++ b/test/synthetic-ais.json
@@ -19,8 +19,8 @@
{"class":"AIS","type":7,"repeat":2,"mmsi":537411077,"scaled":false,"mmsi1":43101326,"mmsi2":717096664,"mmsi3":76161024,"mmsi4":0}
{"class":"AIS","type":8,"repeat":0,"mmsi":366999712,"scaled":false,"dac":366,"fid":22,"data":"256:3a53dbb7be4a773137f87d7b0445f040dea05d93f593783194ae9b9d9dbe05fb"}
{"class":"AIS","type":8,"repeat":0,"mmsi":366999655,"scaled":false,"dac":366,"fid":22,"data":"256:631d1d6b32f735f03494870d9e13addaf3f373435347ab94628f1498868051c3"}
-{"class":"AIS","type":8,"repeat":0,"mmsi":992509977,"scaled":false,"dac":1,"fid":11,"lat":3197693,"lon":-368039,"timestamp":"18T17:15Z","wspeed":3,"wgust":6,"wdir":12,"wgustdir":15,"humidity":50,"airtemp":142,"dewpoint":123,"pressure":1024,"pressuretend":2,"visibility":153,"waterlevel":-84,"leveltrend":1,"cspeed":103,"cdir":256,"cspeed2":104,"cdir2":257,"cdepth2":10,"cspeed3":126,"cdir3":203,"cdepth3":20,"waveheight":42,"waveperiod":35,"wavedir":25,"swellheight":23,"swellperiod":48,"swelldir":124,"seastate":3,"watertemp":123,"preciptype":6,"salinity":53,"ice":0}
-{"class":"AIS","type":8,"repeat":0,"mmsi":992509977,"scaled":false,"dac":1,"fid":11,"lat":3197689,"lon":-368037,"timestamp":"18T17:45Z","wspeed":127,"wgust":127,"wdir":511,"wgustdir":511,"humidity":127,"airtemp":1447,"dewpoint":823,"pressure":1311,"pressuretend":3,"visibility":255,"waterlevel":411,"leveltrend":3,"cspeed":255,"cdir":511,"cspeed2":255,"cdir2":511,"cdepth2":31,"cspeed3":255,"cdir3":511,"cdepth3":31,"waveheight":255,"waveperiod":63,"wavedir":511,"swellheight":255,"swellperiod":63,"swelldir":511,"seastate":15,"watertemp":923,"preciptype":7,"salinity":511,"ice":3}
+{"class":"AIS","device":"stdin","type":8,"repeat":0,"mmsi":992509977,"scaled":false,"dac":1,"fid":11,"lat":3197689,"lon":-368037,"timestamp":"18T17:45Z","wspeed":127,"wgust":127,"wdir":511,"wgustdir":511,"humidity":127,"airtemp":2047,"dewpoint":1023,"pressure":511,"pressuretend":3,"visibility":255,"waterlevel":511,"leveltrend":3,"cspeed":255,"cdir":511,"cspeed2":255,"cdir2":511,"cdepth2":31,"cspeed3":255,"cdir3":511,"cdepth3":31,"waveheight":255,"waveperiod":63,"wavedir":511,"swellheight":255,"swellperiod":63,"swelldir":511,"seastate":15,"watertemp":1023,"preciptype":7,"salinity":511,"ice":3}
+{"class":"AIS","device":"stdin","type":8,"repeat":0,"mmsi":992509977,"scaled":false,"dac":1,"fid":31,"lat":3197696,"lon":-368044,"accuracy":false,"timestamp":"29T23:24Z","wspeed":127,"wgust":127,"wdir":360,"wgustdir":360,"humidity":101,"airtemp":-1024,"dewpoint":501,"pressure":511,"pressuretend":3,"visgreater":false,"visibility":127,"waterlevel":4001,"leveltrend":3,"cspeed":255,"cdir":360,"cspeed2":255,"cdir2":360,"cdepth2":31,"cspeed3":255,"cdir3":360,"cdepth3":31,"waveheight":255,"waveperiod":63,"wavedir":360,"swellheight":255,"swellperiod":63,"swelldir":360,"seastate":13,"watertemp":501,"preciptype":7,"salinity":510,"ice":3}
{"class":"AIS","device":"stdin","type":8,"repeat":0,"mmsi":992509977,"scaled":false,"dac":1,"fid":31,"lat":3197696,"lon":-368044,"accuracy":false,"timestamp":"29T23:24Z","wspeed":127,"wgust":127,"wdir":360,"wgustdir":360,"humidity":101,"airtemp":-1024,"dewpoint":501,"pressure":1311,"pressuretend":3,"visgreater":false,"visibility":127,"waterlevel":3001,"leveltrend":3,"cspeed":255,"cdir":360,"cspeed2":255,"cdir2":360,"cdepth2":31,"cspeed3":255,"cdir3":360,"cdepth3":31,"waveheight":255,"waveperiod":63,"wavedir":360,"swellheight":255,"swellperiod":63,"swelldir":360,"seastate":13,"watertemp":501,"preciptype":7,"salinity":510,"ice":3}
{"class":"AIS","type":9,"repeat":0,"mmsi":111265591,"scaled":false,"alt":15,"speed":0,"accuracy":false,"lon":7128960,"lat":34667073,"course":0,"second":28,"regional":0,"dte":0,"raim":false,"radio":24597}
{"class":"AIS","type":10,"repeat":0,"mmsi":366814480,"scaled":false,"dest_mmsi":366832740}
diff --git a/www/AIVDM.txt b/www/AIVDM.txt
index a58b7322..9bf9b54b 100644
--- a/www/AIVDM.txt
+++ b/www/AIVDM.txt
@@ -1871,100 +1871,99 @@ broadcast of this message of 12 minutes.
|40-49 | 10 |DAC |dac |u|DAC = 001
|50-55 | 6 |FID |fid |u|FID = 11
|56-79 | 24 |Latitude |lat |I3|Unit = minutes * 0.001,
- 91000 = N/A (default),
+ 0x7FFFFF = N/A (default),
E positive, W negative.
|80-104 | 25 |Longitude |lon |I3|Unit = minutes * 0.001,
- 181000 = N/A (default),
+ 0xFFFFFF = N/A (default),
N positive, S negative.
-|105-109 | 5 |Day (UTC) |day |u|1-31, 0=N/A (default)
-|110-114 | 5 |Hour (UTC) |hour |u|0-23, >=24=N/A (default)
-|115-120 | 6 |Minute (UTC) |minute |u|0-59, >=60=N/A (default)
+|105-109 | 5 |Day (UTC) |day |u|1-31, 31=N/A (default)
+|110-114 | 5 |Hour (UTC) |hour |u|0-23, 31=N/A (default)
+|115-120 | 6 |Minute (UTC) |minute |u|0-59, 63=N/A (default)
|121-127 | 7 |Average Wind Speed |wspeed |u|10-min avg wind speed, knots,
127 = N/A (default).
|128-134 | 7 |Gust Speed |wgust |u|10-min max wind speed, knots,
127 = N/A (default).
|135-143 | 9 |Wind Direction |wdir |u|0-359, degrees fom true north
- >=360 = N/A (default)
+ 511 = N/A (default)
|144-152 | 9 |Wind Gust Direction|wgustdir |u|0-359, degrees fom true north
- >=360 = N/A (default)
+ 511 = N/A (default)
|153-163 | 11 |Air Temperature |temperature |u|Dry bulb temp: 0.1 deg C
-60.0 to +60.0,
- -1024 = N/A (default),
- else -60deg after scaling.
+ 2047 = N/A (default),
|164-170 | 7 |Relative Humidity |humidity |u|0-100%, units of 1%,
127 = N/A (default).
|171-180 | 10 |Dew Point |dewpoint |u|-20.0 to +50.0: 0.1 deg C,
1023 = N/A (default),
- else -20.0deg after scaling.
|181-189 | 9 |Air Pressure |pressure |u|800-1200hPa: units 1hPa,
- 402 = pressure >= 1201 hPa,
- 403 - N/A (default).
- else add 400 to value.
+ 511 = N/A (default).
|190-191 | 2 |Pressure Tendency |pressuretend|e|0 = steady,
1 = decreasing,
2 = increasing,
3 - N/A (default).
|192-199 | 8 |Horiz. Visibility |visibility |U1|0-25.0, units of 0.1nm
- >= 250 = N/A (default)
+ 255 = N/A (default)
|200-208 | 9 |Water Level |waterlevel |U1|-10.0 to +30.0 in 0.1m,
- 1923 = N/A (default).
- else -10m after scaling.
+ 511 = N/A (default).
|209-210 | 2 |Water Level Trend |leveltrend |e|0 = steady,
1 = decreasing,
2 = increasing,
3 - N/A (default).
|211-218 | 8 |Surface Current Speed |cspeed |U1|0.0-25.0 knots: units 0.1 knot
|219-227 | 9 |Surface Current Direction |cdir |u|0-359: deg from true north,
- >=360 = N/A (default)
+ 511 = N/A (default)
|228-235 | 8 |Current Speed #2 |cspeed2 |U1|0.0-25.0 in units of 0.1 knot,
- >=251 = N/A (default).
+ 255 = N/A (default).
|236-244 | 9 |Current Direction #2 |cdir2 |u|0-359: deg. fom true north,
- >=360 = N/A (default)
+ 511 = N/A (default)
|245-249 | 5 |Measurement Depth #2 |cdepth2 |U1|0-30m down: units 0.1m,
31 = N/A (default).
|250-257 | 8 |Current Speed #3 |cspeed3 |U1|0.0-25.0: units of 0.1 knot,
- >=251 = N/A (default).
+ 255 = N/A (default).
|258-266 | 9 |Current Direction #3 |cdir3 |u|0-359: degrees fom true north,
- >=360 = N/A (default).
+ 511 = N/A (default).
|267-271 | 5 |Measurement Depth #3 |cdepth3 |U1|0-30m down: units 0.1m,
31 = N/A (default).
|272-279 | 8 |Wave height |waveheight|U1|0-25m: units of 0.1m,
- >=251 = N/A (default).
+ 255 = N/A (default).
|280-285 | 6 |Wave period |waveperiod|u|Seconds 0-60:
- >= 61 = N/A (default).
+ 63 = N/A (default).
|286-294 | 9 |Wave direction |wavedir |u|0-359: deg. fom true north,
- >=360 = N/A (default).
+ 511 = N/A (default).
|295-302 | 8 |Swell height |swellheight|U1|0-25m: units of 0.1m
- >=251 = N/A (default).
+ 255 = N/A (default).
|303-308 | 6 |Swell period |swellperiod|u|Seconds 0-60:
- >= 61 = N/A (default).
+ 63 = N/A (default).
|309-317 | 9 |Swell direction |swelldir |u|0-359: deg. fom true north,
- >=360 = N/A (default).
+ 511 = N/A (default).
|318-321 | 4 |Sea state |seastate |e|See "Beaufort Scale"
|322-331 | 10 |Water Temperature |watertemp |U1|-10.0 to 50.0: units 0.1 C,
- >=601 = N/A (default).
- else -10.0m after scaling.
+ 1023 = N/A (default).
|332-334 | 3 |Precipitation |preciptype |e|See "Precipitation Types"
|335-343 | 9 |Salinity |salinity |U1|0.0-50.0%: units 0.1%,
- >=500 = N/A (default)
-|344-345 | 2 |Ice |ice |b|Yes/No
+ 511 = N/A (default)
+|344-345 | 2 |Ice |ice |e| 0 = No
+ 1 = Yes
+ 2 = (reserved for future use)
+ 3 = not available = default
|346-351 | 6 |Spare | |x|Not used
|==============================================================================
<<IMO236>> says "If there is no data available, default value to be
transmitted is the highest available binary value for that particular
-data field." and no defaults are explicitly specified. However, the
-replacement FID=31 message has default values which do not obey this
-rule. It would be good practice for a decoder to treat any
-out-of-bounds value as N/A; the N/A formulas in the table above
-reflect this.
+data field.", the above table reflects that.
+The day, hour and minute have to be considered not available when all
+three are set to their individual "N/A" value.
+For the latitude and the longitude, the highest positive value is used,
+as the highest available binary value for a signed integer is -1, which
+would forbid the -0.001/-0.001 position.
+The replacement FID=31 message has different default values that remove any ambiguities.
<<IMO236>> gives the length of this message as 352, but lists only 336
payload bits.
Water level is deviation from local chart datum and includes tide.
-The waveheight field is labeled as "Significant" in <<IMO238>>,
+The waveheight field is labeled as "Significant" in <<IMO236>>,
for whatever that means.
The seastate field has a note in <<IMO236>> reading "(manual input?)"?