diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2011-04-17 23:22:00 -0400 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2011-04-17 23:22:00 -0400 |
commit | 6112f61c34622b38a19bb76135810be21ac46d2b (patch) | |
tree | ae551c78b17d1db4e001dcb46db9b33a4f8ca3fb | |
parent | ce3fd68a14b2c01bdfd3c26257e1b7eb2d0bbf63 (diff) | |
download | gpsd-6112f61c34622b38a19bb76135810be21ac46d2b.tar.gz |
First cut at interpreting IMO special message formats.
Untested. All normal regression tests pass.
-rw-r--r-- | ais_json.c | 37 | ||||
-rw-r--r-- | driver_aivdm.c | 40 | ||||
-rw-r--r-- | gps.h | 32 | ||||
-rw-r--r-- | gpsd_json.c | 242 | ||||
-rw-r--r-- | jsongen.py.in | 82 | ||||
-rw-r--r-- | www/AIVDM.txt | 42 |
6 files changed, 405 insertions, 70 deletions
@@ -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); @@ -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. + |