summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2011-04-17 23:22:00 -0400
committerEric S. Raymond <esr@thyrsus.com>2011-04-17 23:22:00 -0400
commit6112f61c34622b38a19bb76135810be21ac46d2b (patch)
treeae551c78b17d1db4e001dcb46db9b33a4f8ca3fb
parentce3fd68a14b2c01bdfd3c26257e1b7eb2d0bbf63 (diff)
downloadgpsd-6112f61c34622b38a19bb76135810be21ac46d2b.tar.gz
First cut at interpreting IMO special message formats.
Untested. All normal regression tests pass.
-rw-r--r--ais_json.c37
-rw-r--r--driver_aivdm.c40
-rw-r--r--gps.h32
-rw-r--r--gpsd_json.c242
-rw-r--r--jsongen.py.in82
-rw-r--r--www/AIVDM.txt42
6 files changed, 405 insertions, 70 deletions
diff --git a/ais_json.c b/ais_json.c
index 29e1628c..79b06abc 100644
--- a/ais_json.c
+++ b/ais_json.c
@@ -58,6 +58,7 @@ int json_ais_read(const char *buf,
memset(ais, '\0', sizeof(struct ais_t));
+ /*@-usedef@*/
if (strstr(buf, "\"type\":1,") != NULL
|| strstr(buf, "\"type\":2,") != NULL
|| strstr(buf, "\"type\":3,") != NULL) {
@@ -92,18 +93,36 @@ int json_ais_read(const char *buf,
&ais->type5.hour, &ais->type5.minute);
}
} else if (strstr(buf, "\"type\":6,") != NULL) {
- status = json_read_object(buf, json_ais6, endptr);
- if (status == 0)
- lenhex_unpack(data, &ais->type6.bitcount,
- ais->type6.bitdata, sizeof(ais->type6.bitdata));
+ bool imo = false;
+ if (strstr(buf, "\"fid\":16,") != NULL) {
+ status = json_read_object(buf, json_ais6_fid16, endptr);
+ imo = true;
+ }
+ else if (strstr(buf, "\"fid\":32,") != NULL || strstr(buf, "\"fid\":14,") != NULL) {
+ status = json_read_object(buf, json_ais6_fid32, endptr);
+ imo = true;
+ }
+ if (!imo) {
+ status = json_read_object(buf, json_ais6, endptr);
+ if (status == 0)
+ lenhex_unpack(data, &ais->type6.bitcount,
+ ais->type6.bitdata, sizeof(ais->type6.bitdata));
+ }
} else if (strstr(buf, "\"type\":7,") != NULL
|| strstr(buf, "\"type\":13,") != NULL) {
status = json_read_object(buf, json_ais7, endptr);
} else if (strstr(buf, "\"type\":8,") != NULL) {
- status = json_read_object(buf, json_ais8, endptr);
- if (status == 0)
- lenhex_unpack(data, &ais->type8.bitcount,
- ais->type8.bitdata, sizeof(ais->type8.bitdata));
+ bool imo = false;
+ if (strstr(buf, "\"fid\":31,") != NULL || strstr(buf, "\"fid\":11,") != NULL) {
+ status = json_read_object(buf, json_ais8_fid31, endptr);
+ imo = true;
+ }
+ if (!imo) {
+ status = json_read_object(buf, json_ais8, endptr);
+ if (status == 0)
+ lenhex_unpack(data, &ais->type8.bitcount,
+ ais->type8.bitdata, sizeof(ais->type8.bitdata));
+ }
} else if (strstr(buf, "\"type\":9,") != NULL) {
status = json_read_object(buf, json_ais9, endptr);
} else if (strstr(buf, "\"type\":10,") != NULL) {
@@ -148,8 +167,8 @@ int json_ais_read(const char *buf,
*endptr = NULL;
return JSON_ERR_MISC;
}
- /*@+compdef +nullstate@*/
return status;
+ /*@+compdef +usedef +nullstate@*/
}
#endif /* SOCKET_EXPORT_ENABLE */
diff --git a/driver_aivdm.c b/driver_aivdm.c
index 41b8ff04..a3580808 100644
--- a/driver_aivdm.c
+++ b/driver_aivdm.c
@@ -443,7 +443,7 @@ bool aivdm_decode(const char *buf, size_t buflen,
ais->type8.dac1fid31.wgust = UBITS(128, 7);
ais->type8.dac1fid31.wdir = UBITS(135, 9);
ais->type8.dac1fid31.wgustdir = UBITS(144, 9);
- ais->type8.dac1fid31.temperature = SBITS(153, 11)
+ ais->type8.dac1fid31.airtemp = SBITS(153, 11)
- DAC1FID31_AIRTEMP_OFFSET;
ais->type8.dac1fid31.humidity = UBITS(164, 7);
ais->type8.dac1fid31.dewpoint = UBITS(171, 10)
@@ -451,19 +451,18 @@ bool aivdm_decode(const char *buf, size_t buflen,
ais->type8.dac1fid31.pressure = UBITS(181, 9)
- DAC1FID31_PRESSURE_OFFSET;
ais->type8.dac1fid31.pressuretend = UBITS(190, 2);
- ais->type8.dac1fid31.visgreater = false;
ais->type8.dac1fid31.visibility = UBITS(192, 8);
ais->type8.dac1fid31.waterlevel = UBITS(200, 9)
- DAC1FID11_LEVEL_OFFSET;
ais->type8.dac1fid31.leveltrend = UBITS(209, 2);
- ais->type8.dac1fid31.curspeed = UBITS(211, 8);
- ais->type8.dac1fid31.curdir = UBITS(219, 9);
- ais->type8.dac1fid31.curspeed2 = UBITS(228, 8);
- ais->type8.dac1fid31.curdir2 = UBITS(236, 9);
- ais->type8.dac1fid31.curdepth2 = UBITS(245, 5);
- ais->type8.dac1fid31.curspeed3 = UBITS(250, 8);
- ais->type8.dac1fid31.curdir3 = UBITS(258, 9);
- ais->type8.dac1fid31.curdepth3 = UBITS(267, 5);
+ ais->type8.dac1fid31.cspeed = UBITS(211, 8);
+ ais->type8.dac1fid31.cdir = UBITS(219, 9);
+ ais->type8.dac1fid31.cspeed2 = UBITS(228, 8);
+ ais->type8.dac1fid31.cdir2 = UBITS(236, 9);
+ ais->type8.dac1fid31.cdepth2 = UBITS(245, 5);
+ ais->type8.dac1fid31.cspeed3 = UBITS(250, 8);
+ ais->type8.dac1fid31.cdir3 = UBITS(258, 9);
+ ais->type8.dac1fid31.cdepth3 = UBITS(267, 5);
ais->type8.dac1fid31.waveheight = UBITS(272, 8);
ais->type8.dac1fid31.waveperiod = UBITS(280, 6);
ais->type8.dac1fid31.wavedir = UBITS(286, 9);
@@ -515,7 +514,7 @@ bool aivdm_decode(const char *buf, size_t buflen,
ais->type8.dac1fid31.wgust = UBITS(129, 7);
ais->type8.dac1fid31.wdir = UBITS(136, 9);
ais->type8.dac1fid31.wgustdir = UBITS(145, 9);
- ais->type8.dac1fid31.temperature = SBITS(154, 11)
+ ais->type8.dac1fid31.airtemp = SBITS(154, 11)
- DAC1FID31_AIRTEMP_OFFSET;
ais->type8.dac1fid31.humidity = UBITS(165, 7);
ais->type8.dac1fid31.dewpoint = UBITS(172, 10)
@@ -523,19 +522,18 @@ bool aivdm_decode(const char *buf, size_t buflen,
ais->type8.dac1fid31.pressure = UBITS(182, 9)
- DAC1FID31_PRESSURE_OFFSET;
ais->type8.dac1fid31.pressuretend = UBITS(191, 2);
- ais->type8.dac1fid31.visgreater = UBITS(193, 1);
- ais->type8.dac1fid31.visibility = UBITS(194, 6);
+ ais->type8.dac1fid31.visibility = UBITS(193, 7);
ais->type8.dac1fid31.waterlevel = UBITS(200, 12)
- DAC1FID31_LEVEL_OFFSET;
ais->type8.dac1fid31.leveltrend = UBITS(213, 2);
- ais->type8.dac1fid31.curspeed = UBITS(215, 8);
- ais->type8.dac1fid31.curdir = UBITS(223, 9);
- ais->type8.dac1fid31.curspeed2 = UBITS(232, 8);
- ais->type8.dac1fid31.curdir2 = UBITS(240, 9);
- ais->type8.dac1fid31.curdepth2 = UBITS(249, 5);
- ais->type8.dac1fid31.curspeed3 = UBITS(254, 8);
- ais->type8.dac1fid31.curdir3 = UBITS(262, 9);
- ais->type8.dac1fid31.curdepth3 = UBITS(271, 5);
+ ais->type8.dac1fid31.cspeed = UBITS(215, 8);
+ ais->type8.dac1fid31.cdir = UBITS(223, 9);
+ ais->type8.dac1fid31.cspeed2 = UBITS(232, 8);
+ ais->type8.dac1fid31.cdir2 = UBITS(240, 9);
+ ais->type8.dac1fid31.cdepth2 = UBITS(249, 5);
+ ais->type8.dac1fid31.cspeed3 = UBITS(254, 8);
+ ais->type8.dac1fid31.cdir3 = UBITS(262, 9);
+ ais->type8.dac1fid31.cdepth3 = UBITS(271, 5);
ais->type8.dac1fid31.waveheight = UBITS(276, 8);
ais->type8.dac1fid31.waveperiod = UBITS(284, 6);
ais->type8.dac1fid31.wavedir = UBITS(290, 9);
diff --git a/gps.h b/gps.h
index 2a284c41..9f502a1d 100644
--- a/gps.h
+++ b/gps.h
@@ -982,7 +982,7 @@ struct ais_t
unsigned int wdir; /* wind direction */
unsigned int wgustdir; /* wind gust direction */
#define DAC1FID31_DIR_NOT_AVAILABLE 360
- int temperature; /* temperature, units 0.1C */
+ int airtemp; /* temperature, units 0.1C */
#define DAC1FID31_AIRTEMP_NOT_AVAILABLE -1084
unsigned int humidity; /* relative humidity, % */
#define DAC1FID31_HUMIDITY_NOT_AVAILABLE 101
@@ -992,31 +992,39 @@ struct ais_t
#define DAC1FID31_PRESSURE_NOT_AVAILABLE 511
#define DAC1FID31_PRESSURE_HIGH 402
unsigned int pressuretend; /* tendency */
- bool visgreater; /* vis. > than following */
+#define DAC1FID31_PRESSURETREND_NOT_AVAILABLE 3
unsigned int visibility; /* units 0.1 nautical miles */
#define DAC1FID31_VISIBILITY_NOT_AVAILABLE 127
- unsigned int waterlevel; /* decimeters or cm */
+ int waterlevel; /* decimeters or cm */
#define DAC1FID11_WATERLEVEL_NOT_AVAILABLE 4001
#define DAC1FID31_WATERLEVEL_NOT_AVAILABLE 40001
unsigned int leveltrend; /* water level trend code */
- unsigned int curspeed; /* current speed in deciknots */
- unsigned int curdir; /* current dir., degrees */
- unsigned int curspeed2; /* current speed in deciknots */
- unsigned int curdir2; /* current dir., degrees */
- unsigned int curdepth2; /* measurement depth, 0.1m */
- unsigned int curspeed3; /* current speed in deciknots */
- unsigned int curdir3; /* current dir., degrees */
- unsigned int curdepth3; /* measurement depth, 0.1m */
+#define DAC1FID31_LEVELTREND_NOT_AVAILABLE 3
+ unsigned int cspeed; /* current speed in deciknots */
+#define DAC1FID31_CSPEED_NOT_AVAILABLE 255
+ 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
+ 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
unsigned int waveperiod; /* in seconds */
+#define DAC1FID31_PERIOD_NOT_AVAILABLE 63
unsigned int wavedir; /* direction in degrees */
unsigned int swellheight; /* in decimeters */
unsigned int swellperiod; /* in seconds */
unsigned int swelldir; /* direction in degrees */
unsigned int seastate; /* Beaufort scale, 0-12 */
+#define DAC1FID31_SEASTATE_NOT_AVAILABLE 15
int watertemp; /* units 0.1deg Celsius */
- unsigned char preciptype; /* 0-7, enumerated */
+#define DAC1FID31_PRECIPTYPE_NOT_AVAILABLE 7
+ unsigned int preciptype; /* 0-7, enumerated */
unsigned int salinity; /* units of 0.1% */
+#define DAC1FID31_SALINITY_NOT_AVAILABLE 510
bool ice; /* is there sea ice? */
} dac1fid31;
};
diff --git a/gpsd_json.c b/gpsd_json.c
index bf6c094a..75a2725e 100644
--- a/gpsd_json.c
+++ b/gpsd_json.c
@@ -1344,6 +1344,7 @@ void json_aivdm_dump(const struct ais_t *ais,
char buf1[JSON_VAL_MAX * 2 + 1];
char buf2[JSON_VAL_MAX * 2 + 1];
char buf3[JSON_VAL_MAX * 2 + 1];
+ bool imo;
static char *nav_legends[] = {
"Under way using engine",
@@ -1709,16 +1710,74 @@ void json_aivdm_dump(const struct ais_t *ais,
case 6: /* Binary Message */
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
"\"seqno\":%u,\"dest_mmsi\":%u,"
- "\"retransmit\":%s,\"dac\":%u,\"fid\":%u,"
- "\"data\":\"%zd:%s\"}\r\n",
+ "\"retransmit\":%s,\"dac\":%u,\"fid\":%u,",
ais->type6.seqno,
ais->type6.dest_mmsi,
JSON_BOOL(ais->type6.retransmit),
ais->type6.dac,
- ais->type6.fid,
- ais->type6.bitcount,
- gpsd_hexdump(ais->type6.bitdata,
- (ais->type6.bitcount + 7) / 8));
+ ais->type6.fid);
+ imo = false;
+ if (ais->type6.dac == 1)
+ switch (ais->type6.fid) {
+ case 12: /* IMO236 -Dangerous cargo indication */
+ break;
+ case 14: /* IMO236 - Tidal window */
+ case 32: /* IMO289 - Tidal Window */
+ if (scaled)
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "\"month\":%u,\"day\":%u,"
+ "\"lon\":%.4f,\"lat\":%.4f,"
+ "\"from_hour\":%u,\"from_min\":%u,"
+ "\"to_hour\":%u,\"to_min\":%u,"
+ "\"cdir\":%u,\"cspeed\":%.1f,",
+ ais->type6.dac1fid32.month,
+ ais->type6.dac1fid32.day,
+ ais->type6.dac1fid32.lon * 0.01,
+ ais->type6.dac1fid32.lat * 0.01,
+ ais->type6.dac1fid32.from_hour,
+ ais->type6.dac1fid32.from_min,
+ ais->type6.dac1fid32.to_hour,
+ ais->type6.dac1fid32.to_min,
+ ais->type6.dac1fid32.cdir,
+ ais->type6.dac1fid32.cspeed * 0.1);
+ else
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "\"month\":%u,\"day\":%u,"
+ "\"lon\":%d,\"lat\":%.d,"
+ "\"from_hour\":%u,\"from_min\":%u,"
+ "\"to_hour\":%u,\"to_min\":%u,"
+ "\"cdir\":%u,\"cspeed\":%u,",
+ ais->type6.dac1fid32.month,
+ ais->type6.dac1fid32.day,
+ ais->type6.dac1fid32.lon,
+ ais->type6.dac1fid32.lat,
+ ais->type6.dac1fid32.from_hour,
+ ais->type6.dac1fid32.from_min,
+ ais->type6.dac1fid32.to_hour,
+ ais->type6.dac1fid32.to_min,
+ ais->type6.dac1fid32.cdir,
+ ais->type6.dac1fid32.cspeed);
+ break;
+ case 16: /* IMO236 - Number of persons on board */
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "\"persons\":%u", ais->type6.dac1fid16.persons);
+ imo = true;
+ break;
+ case 18: /* IMO289 - Clearance time to enter port */
+ break;
+ case 25: /* IMO289 = Dangerous cargo indication */
+ break;
+ case 28: /* IMO289 - Route info - addressed */
+ break;
+ case 30: /* IMO289 - Text description - addressed */
+ break;
+ }
+ if (!imo)
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "\"data\":\"%zd:%s\"}\r\n",
+ ais->type6.bitcount,
+ gpsd_hexdump(ais->type6.bitdata,
+ (ais->type6.bitcount + 7) / 8));
break;
case 7: /* Binary Acknowledge */
case 13: /* Safety Related Acknowledge */
@@ -1728,13 +1787,172 @@ void json_aivdm_dump(const struct ais_t *ais,
ais->type7.mmsi2, ais->type7.mmsi3, ais->type7.mmsi4);
break;
case 8: /* Binary Broadcast Message */
+ imo = false;
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
- "\"dac\":%u,\"fid\":%u,\"data\":\"%zd:%s\"}\r\n",
- ais->type8.dac,
- ais->type8.fid,
- ais->type8.bitcount,
- gpsd_hexdump(ais->type8.bitdata,
- (ais->type8.bitcount + 7) / 8));
+ "\"dac\":%u,\"fid\":%u,",ais->type8.dac,ais->type8.fid);
+ if (ais->type8.dac == 1)
+ switch (ais->type8.fid) {
+ case 11: /* IMO236 - Meteorological/Hydrological data */
+ case 31: /* IMO289 - Meteorological/Hydrological data */
+ /* layout is almost identical to FID=31 from IMO289 */
+ if (scaled)
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "\"lat\":%.4f,\"lat\":%.4f,",
+ ais->type8.dac1fid31.lat / AIS_LATLON_SCALE,
+ ais->type8.dac1fid31.lon / AIS_LATLON_SCALE);
+ else
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "\"lat\":%d,\"lat\":%d,",
+ ais->type8.dac1fid31.lat,
+ ais->type8.dac1fid31.lon);
+ if (ais->type8.fid == 31)
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "\"accuracy\":%s,",
+ JSON_BOOL(ais->type8.dac1fid31.accuracy));
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "\"day\":%u,\"hour\":%u,\"minute\":%u,"
+ "\"wapeed\":%u,\"wgust\":%u,\"wdir\":%u,"
+ "\"wgustdir\":%u,\"humidity\":%u",
+ ais->type8.dac1fid31.day,
+ ais->type8.dac1fid31.hour,
+ ais->type8.dac1fid31.minute,
+ ais->type8.dac1fid31.wspeed,
+ ais->type8.dac1fid31.wgust,
+ ais->type8.dac1fid31.wdir,
+ ais->type8.dac1fid31.wgustdir,
+ ais->type8.dac1fid31.humidity);
+ if (scaled)
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "\"airtemp\":%1f,\"dewpoint\":%1f,",
+ ais->type8.dac1fid31.airtemp * 0.1,
+ ais->type8.dac1fid31.dewpoint * 0.1);
+ else
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "\"airtemp\":%d,\"dewpoint\":%d,",
+ ais->type8.dac1fid31.airtemp,
+ ais->type8.dac1fid31.dewpoint);
+
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "\"pressure\":%u,\"pressuretend\":%u,",
+ ais->type8.dac1fid31.pressure,
+ ais->type8.dac1fid31.pressuretend);
+ if (scaled)
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "\"visibility\":%1f,",
+ ais->type8.dac1fid31.visibility * 0.1);
+ else
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "\"visibility\":%u,:",
+ ais->type8.dac1fid31.visibility);
+ if (!scaled)
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "\"waterlevel\":%d,",
+ ais->type8.dac1fid31.waterlevel);
+ else if (ais->type8.fid == 31)
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "\"waterlevel\":%.1f,:",
+ ais->type8.dac1fid31.waterlevel * 0.01);
+ else
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "\"waterlevel\":%.1f,:",
+ ais->type8.dac1fid31.waterlevel * 0.1);
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "\"leveltrend\":%u,",
+ ais->type8.dac1fid31.leveltrend);
+
+ if (scaled)
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "\"cspeed\":%.1f,\"cdir\":%u"
+ "\"cspeed2\":%.1f,\"cdir2\":%u,\"cdepth2\":%u,"
+ "\"cspeed3\":%.1f,\"cdir3\":%u,\"cdepth3\":%u,"
+ "\"waveheight\":%.1f,\"waveperiod\":%u,\"wavedir\":%u,"
+ "\"swellheight\":%.1f,\"swellperiod\":%u,\"swelldir\":%u,"
+ "\"seastate\":%u,\"watertemp\":%.1f,"
+ "\"preciptype\":%u,\"salinity\":%.1f,\"ice\":%s",
+ ais->type8.dac1fid31.cspeed * 0.1,
+ ais->type8.dac1fid31.cdir,
+ ais->type8.dac1fid31.cspeed2 * 0.1,
+ ais->type8.dac1fid31.cdir2,
+ ais->type8.dac1fid31.cdepth2,
+ ais->type8.dac1fid31.cspeed3 * 0.1,
+ ais->type8.dac1fid31.cdir3,
+ ais->type8.dac1fid31.cdepth3,
+ ais->type8.dac1fid31.waveheight * 0.1,
+ ais->type8.dac1fid31.waveperiod,
+ ais->type8.dac1fid31.wavedir,
+ ais->type8.dac1fid31.swellheight * 0.1,
+ ais->type8.dac1fid31.swellperiod,
+ ais->type8.dac1fid31.swelldir,
+ ais->type8.dac1fid31.seastate,
+ ais->type8.dac1fid31.watertemp * 0.1,
+ ais->type8.dac1fid31.preciptype,
+ ais->type8.dac1fid31.salinity * 0.1,
+ JSON_BOOL(ais->type8.dac1fid31.ice));
+ else
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "\"cspeed\":%u,\"cdir\":%u"
+ "\"cspeed2\":%u,\"cdir2\":%u,\"cdepth2\":%u,"
+ "\"cspeed3\":%u,\"cdir3\":%u,\"cdepth3\":%u,"
+ "\"waveheight\":%u,\"waveperiod\":%u,\"wavedir\":%u,"
+ "\"swellheight\":%u,\"swellperiod\":%u,\"swelldir\":%u,"
+ "\"seastate\":%u,\"watertemp\":%d,"
+ "\"preciptype\":%u,\"salinity\":%u,\"ice\":%s",
+ ais->type8.dac1fid31.cspeed,
+ ais->type8.dac1fid31.cdir,
+ ais->type8.dac1fid31.cspeed2,
+ ais->type8.dac1fid31.cdir2,
+ ais->type8.dac1fid31.cdepth2,
+ ais->type8.dac1fid31.cspeed3,
+ ais->type8.dac1fid31.cdir3,
+ ais->type8.dac1fid31.cdepth3,
+ ais->type8.dac1fid31.waveheight,
+ ais->type8.dac1fid31.waveperiod,
+ ais->type8.dac1fid31.wavedir,
+ ais->type8.dac1fid31.swellheight,
+ ais->type8.dac1fid31.swellperiod,
+ ais->type8.dac1fid31.swelldir,
+ ais->type8.dac1fid31.seastate,
+ ais->type8.dac1fid31.watertemp,
+ ais->type8.dac1fid31.preciptype,
+ ais->type8.dac1fid31.salinity,
+ JSON_BOOL(ais->type8.dac1fid31.ice));
+ imo = true;
+ break;
+ case 13: /* IMO236 - Fairway closed */
+ break;
+ case 15: /* IMO236 - Extended ship and voyage */
+ break;
+ case 17: /* IMO289 - VTS-generated/synthetic targets */
+ break;
+ case 19: /* IMO289 - Marine Traffic Signal */
+ break;
+ case 20: /* IMO289 - Berthing Data */
+ break;
+ case 21: /* IMO289 - Weather obs. report from ship */
+ break;
+ case 22: /* IMO289 - Area notice - broadcast */
+ break;
+ case 23: /* IMO289 - Area notice - addressed */
+ break;
+ case 24: /* IMO289 - Extended ship static & voyage-related data */
+ break;
+ case 25: /* IMO289 - Dangerous Cargo Indication */
+ break;
+ case 27: /* IMO289 - Route information - broadcast */
+ break;
+ case 29: /* IMO289 - Text Description - broadcast */
+ break;
+ case 30: /* IMO289 - Text Description - addressed */
+ break;
+ case 32: /* Tidal Window */
+ break;
+ }
+ if (!imo)
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "\"data\":\"%zd:%s\"}\r\n",
+ ais->type8.bitcount,
+ gpsd_hexdump(ais->type8.bitdata,
+ (ais->type8.bitcount + 7) / 8));
break;
case 9: /* Standard SAR Aircraft Position Report */
if (scaled) {
diff --git a/jsongen.py.in b/jsongen.py.in
index 17aceed4..bc379f27 100644
--- a/jsongen.py.in
+++ b/jsongen.py.in
@@ -95,6 +95,43 @@ ais_specs = (
"stringbuffered":("data",),
},
{
+ "initname" : "json_ais6_fid16",
+ "header": "\tAIS_HEADER,",
+ "structname": "ais->type6",
+ "fieldmap":(
+ # fieldname type default
+ ('seqno', 'uinteger', '0'),
+ ('dest_mmsi', 'uinteger', '0'),
+ ('retransmit', 'boolean', 'false'),
+ ('dac', 'uinteger', '0'),
+ ('fid', 'uinteger', '0'),
+ ('dac1fid16.persons', 'uinteger', '0'),
+ ),
+ },
+ {
+ "initname" : "json_ais6_fid32",
+ "header": "\tAIS_HEADER,",
+ "structname": "ais->type6",
+ "fieldmap":(
+ # fieldname type default
+ ('seqno', 'uinteger', '0'),
+ ('dest_mmsi', 'uinteger', '0'),
+ ('retransmit', 'boolean', 'false'),
+ ('dac', 'uinteger', '0'),
+ ('fid', 'uinteger', '0'),
+ ('dac1fid32.month', 'uinteger', '0'),
+ ('dac1fid32.day', 'uinteger', '0'),
+ ('dac1fid32.lon', 'integer', '0'),
+ ('dac1fid32.lat', 'integer', '0'),
+ ('dac1fid32.from_hour', 'uinteger', 'AIS_HOUR_NOT_AVAILABLE'),
+ ('dac1fid32.from_min', 'uinteger', 'AIS_MINUTE_NOT_AVAILABLE'),
+ ('dac1fid32.to_hour', 'uinteger', 'AIS_HOUR_NOT_AVAILABLE'),
+ ('dac1fid32.to_min', 'uinteger', 'AIS_MINUTE_NOT_AVAILABLE'),
+ ('dac1fid32.cdir', 'uinteger', '0'),
+ ('dac1fid32.cspeed', 'uinteger', '0'),
+ ),
+ },
+ {
"initname" : "json_ais7",
"header": "\tAIS_HEADER,",
"structname": "ais->type7",
@@ -119,6 +156,51 @@ ais_specs = (
"stringbuffered":("data",),
},
{
+ "initname" : "json_ais8_fid31",
+ "header": "\tAIS_HEADER,",
+ "structname": "ais->type8",
+ "fieldmap":(
+ # fieldname type default
+ ('dac', 'uinteger', '0'),
+ ('fid', 'uinteger', '0'),
+ ('dac1fid31.lon', 'integer', 'DAC1FID31_LON_NOT_AVAILABLE'),
+ ('dac1fid31.lat', 'integer', 'DAC1FID31_LAT_NOT_AVAILABLE'),
+ ('dac1fid31.accuracy', 'boolean', 'false'),
+ ('dac1fid31.day', 'uinteger', 'AIS_DAY_NOT_AVAILABLE'),
+ ('dac1fid31.hour', 'uinteger', 'AIS_HOUR_NOT_AVAILABLE'),
+ ('dac1fid31.minute', 'uinteger', 'AIS_MINUTE_NOT_AVAILABLE'),
+ ('dac1fid31.wspeed', 'uinteger', 'DAC1FID31_WIND_NOT_AVAILABLE'),
+ ('dac1fid31.wgust ', 'uinteger', 'DAC1FID31_WIND_NOT_AVAILABLE'),
+ ('dac1fid31.wdir', 'uinteger', 'DAC1FID31_DIR_NOT_AVAILABLE'),
+ ('dac1fid31.wgustdir', 'uinteger', 'DAC1FID31_DIR_NOT_AVAILABLE'),
+ ('dac1fid31.airtemp', 'integer', 'DAC1FID31_AIRTEMP_NOT_AVAILABLE'),
+ ('dac1fid31.pressure', 'uinteger', 'DAC1FID31_PRESSURE_NOT_AVAILABLE'),
+ ('dac1fid31.pressuretend', 'uinteger', 'DAC1FID31_PRESSURETREND_NOT_AVAILABLE'),
+ ('dac1fid31.visibility', 'uinteger', 'DAC1FID31_VISIBILITY_NOT_AVAILABLE'),
+ ('dac1fid31.waterlevel', 'integer', 'DAC1FID31_WATERLEVEL_NOT_AVAILABLE'),
+ ('dac1fid31.leveltrend', 'uinteger', 'DAC1FID31_LEVELTREND_NOT_AVAILABLE'),
+ ('dac1fid31.cspeed', 'uinteger', 'DAC1FID31_CSPEED_NOT_AVAILABLE'),
+ ('dac1fid31.cdir', 'uinteger', 'DAC1FID31_DIR_NOT_AVAILABLE'),
+ ('dac1fid31.cspeed2', 'uinteger', 'DAC1FID31_CSPEED_NOT_AVAILABLE'),
+ ('dac1fid31.cdir2', 'uinteger', 'DAC1FID31_DIR_NOT_AVAILABLE'),
+ ('dac1fid31.cdepth2', 'uinteger', 'DAC1FID31_CDEPTH_NOT_AVAILABLE'),
+ ('dac1fid31.cspeed3', 'uinteger', 'DAC1FID31_CSPEED_NOT_AVAILABLE'),
+ ('dac1fid31.cdir3', 'uinteger', 'DAC1FID31_DIR_NOT_AVAILABLE'),
+ ('dac1fid31.cdepth3', 'uinteger', 'DAC1FID31_CDEPTH_NOT_AVAILABLE'),
+ ('dac1fid31.waveheight', 'uinteger', 'DAC1FID31_HEIGHT_NOT_AVAILABLE'),
+ ('dac1fid31.waveperiod', 'uinteger', 'DAC1FID31_PERIOD_NOT_AVAILABLE'),
+ ('dac1fid31.wavedir', 'uinteger', 'DAC1FID31_DIR_NOT_AVAILABLE'),
+ ('dac1fid31.swellheight', 'uinteger', 'DAC1FID31_HEIGHT_NOT_AVAILABLE'),
+ ('dac1fid31.swellperiod', 'uinteger', 'DAC1FID31_PERIOD_NOT_AVAILABLE'),
+ ('dac1fid31.swelldir', 'uinteger', 'DAC1FID31_DIR_NOT_AVAILABLE'),
+ ('dac1fid31.seastate', 'uinteger', 'DAC1FID31_SEASTATE_NOT_AVAILABLE'),
+ ('dac1fid31.preciptype', 'uinteger', 'DAC1FID31_PRECIPTYPE_NOT_AVAILABLE'),
+ ('dac1fid31.salinity', 'uinteger', 'DAC1FID31_SALINITY_NOT_AVAILABLE'),
+ ('dac1fid31.ice', 'boolean', 'false'),
+ ),
+ "stringbuffered":("data",),
+ },
+ {
"initname" : "json_ais9",
"header": "\tAIS_HEADER,",
"structname": "ais->type9",
diff --git a/www/AIVDM.txt b/www/AIVDM.txt
index 7e2ee803..d70f0c25 100644
--- a/www/AIVDM.txt
+++ b/www/AIVDM.txt
@@ -1,6 +1,6 @@
= AIVDM/AIVDO protocol decoding =
Eric S. Raymond <esr@thyrsus.com>
-v1.30, Apr 2011
+v1.31, Apr 2011
This document is mastered in asciidoc format. If you are reading it in HTML,
you can find the original at http://gpsd.berlios.de/AIVDM.txt[]
@@ -1480,6 +1480,7 @@ broadcast of this message of 12 minutes.
|190-191 | 2 |Pressure Tendency |pressuretend|0 = steady
| | | | |1 = decreasing
| | | | |2 = increasing
+| | | | |3 - N/A (default)
|192-199 | 8 |Horiz. Visibility |visibility |0-25.0, units of 0.1nm
| | | | |>= 250 = N/A (default)
|200-208 | 9 |Water Level |waterlevel |-10.0 to +30.0 in 0.1m
@@ -1488,18 +1489,19 @@ broadcast of this message of 12 minutes.
|209-210 | 2 |Water Level Trend |leveltrend |0 = steady
| | | | |1 = decreasing
| | | | |2 = increasing
-|211-218 | 8 |Surface Current Speed |curspeed |0.0-25.0 knots, units 0.1 knot
-|219-227 | 9 |Surface Current Direction |curdir |0-359, degrees fom true north
+| | | | |3 - N/A (default)
+|211-218 | 8 |Surface Current Speed |cspeed |0.0-25.0 knots, units 0.1 knot
+|219-227 | 9 |Surface Current Direction |cdir |0-359, degrees fom true north
| | | | |>=360 = N/A (default)
-|228-235 | 8 |Current Speed #2 |curspeed2 |0.0-25.0 knots, units 0.1 knot
+|228-235 | 8 |Current Speed #2 |cspeed2 |0.0-25.0 knots, units 0.1 knot
| | | | |>=251 = N/A (default)
-|236-244 | 9 |Current Direction #2 |curdir2 |0-359, degrees fom true north
+|236-244 | 9 |Current Direction #2 |cdir2 |0-359, degrees fom true north
| | | | |>=360 = N/A (default)
-|245-249 | 5 |Measurement Depth #2 |curdepth2 |0-30m down, units 0.1m
+|245-249 | 5 |Measurement Depth #2 |cdepth2 |0-30m down, units 0.1m
| | | | |31 = N/A (default)
-|250-257 | 8 |Current Speed #3 |curspeed3 |0.0-25.0 knots, units 0.1 knot
+|250-257 | 8 |Current Speed #3 |cspeed3 |0.0-25.0 knots, units 0.1 knot
| | | | |>=251 = N/A (default)
-|258-266 | 9 |Current Direction #3 |curdir3 |0-359, degrees fom true north
+|258-266 | 9 |Current Direction #3 |cdir3 |0-359, degrees fom true north
| | | | |>=360 = N/A (default)
|267-271 | 5 |Measurement Depth #3 |curdepth3 |0-30m down, units 0.1m
| | | | |31 = N/A (default)
@@ -2244,6 +2246,7 @@ decimeters), and (c) end padding changes from 6 to 10 bits.
|191-192 | 2 |Pressure Tendency |pressuretend|0 = steady
| | | | |1 = decreasing
| | | | |2 = increasing
+| | | | |3 - N/A (default)
|193-200 | 8 |Horiz. Visibility |visibility |0.1 nautical miles
|201-212 | 12 |Water Level |waterlevel |-10.0 to +30.0 in 0.01m
| | | | |Subtract 10.0m after scaling
@@ -2251,23 +2254,26 @@ decimeters), and (c) end padding changes from 6 to 10 bits.
|213-214 | 2 |Water Level Trend |leveltrend |0 = steady
| | | | |1 = decreasing
| | | | |2 = increasing
-|215-222 | 8 |Surface Current Speed |curspeed |0.0-25.0, units 0.1 knot
+| | | | |3 - N/A (default)
+|215-222 | 8 |Surface Current Speed |cspeed |0.0-25.0, units 0.1 knot
| | | | |251 = speed >= 25.1 knots
| | | | |255 N/A (default)
-|223-231 | 9 |Surface Current Direction |curdir |0-359, deg. fom true north
+|223-231 | 9 |Surface Current Direction |cdir |0-359, deg. fom true north
| | | | |360 = N/A (default)
-|232-239 | 8 |Current Speed #2 |curspeed2 |0.0-25.0 knots, units 0.1 knot
+|232-239 | 8 |Current Speed #2 |cspeed2 |0.0-25.0 knots, units 0.1 knot
| | | | |251 = speed >= 25.1 knots
| | | | |255 N/A (default)
-|240-248 | 9 |Current Direction #2 |curdir2 |0-359, degrees fom true north
+|240-248 | 9 |Current Direction #2 |cdir2 |0-359, degrees fom true north
| | | | |360 = N/A (default)
-|249-253 | 5 |Measurement Depth #2 |curdepth2 |0-30m down, units 0.1m
-|254-261 | 8 |Current Speed #3 |curspeed3 |0.0-25.0 knots, units 0.1 knot
+|249-253 | 5 |Measurement Depth #2 |cdepth2 |0-30m down, units 0.1m
+| | | | |31 = N/A (default)
+|254-261 | 8 |Current Speed #3 |cspeed3 |0.0-25.0 knots, units 0.1 knot
| | | | |251 = speed >= 25.1 knots
| | | | |255 N/A (default)
-|262-270 | 9 |Current Direction #3 |curdir3 |0-359, degrees fom true north
+|262-270 | 9 |Current Direction #3 |cdir3 |0-359, degrees fom true north
| | | | |360 = N/A (default)
-|271-275 | 5 |Measurement Depth #3 |curdepth3 |0-30m down, units 0.1m
+|271-275 | 5 |Measurement Depth #3 |cdepth3 |0-30m down, units 0.1m
+| | | | |31 = N/A (default)
|276-283 | 8 |Wave height |waveheight|0-25m, units 0.1m
| | | | |251 = height >= 25.1m
| | | | |255 N/A (default)
@@ -3507,3 +3513,7 @@ types 6 and 8.
Version 1.30 was revised because M.1371-4 is now a free download.
Also, we describe "pilot plugs" and AIS message type 27. We get
much more explicit about defaults in IMO236 and IMO289 messages.
+
+Version 1.31 shortened some C names in the Meterological/Hydrological
+messages and fixed typos.
+