diff options
author | Christian Gagneraud <chgans@gna.org> | 2012-05-23 00:27:04 +0100 |
---|---|---|
committer | Christian Gagneraud <cgagneraud@techworks.ie> | 2012-05-23 21:36:34 +0100 |
commit | f2ba497b7ebe1158bb2e0088ad828c45600938ee (patch) | |
tree | 5abb21afc08b3465844c628639923840ceea9a04 | |
parent | 6041bdbf72c9b92d50b5bad8a7e7ced9ef65678f (diff) | |
download | gpsd-f2ba497b7ebe1158bb2e0088ad828c45600938ee.tar.gz |
[AIS] Add UK/ROI AtoN monitoring data message handling
-rw-r--r-- | ais_json.c | 6 | ||||
-rwxr-xr-x | devtools/ais.py | 31 | ||||
-rw-r--r-- | driver_ais.c | 20 | ||||
-rw-r--r-- | gps.h | 11 | ||||
-rw-r--r-- | gpsd_json.c | 68 | ||||
-rw-r--r-- | gpsdecode.c | 33 | ||||
-rw-r--r-- | jsongen.py.in | 16 |
7 files changed, 177 insertions, 8 deletions
@@ -216,6 +216,12 @@ int json_ais_read(const char *buf, imo = true; } } + else if (strstr(buf, "\"dac\":235,") != NULL || strstr(buf, "\"dac\":250,") != NULL) { + if (strstr(buf, "\"fid\":10,") != NULL) { + status = json_read_object(buf, json_ais6_fid10, endptr); + imo = true; + } + } if (!imo) { status = json_read_object(buf, json_ais6, endptr); if (status == 0) diff --git a/devtools/ais.py b/devtools/ais.py index 5869a111..d8dd25c7 100755 --- a/devtools/ais.py +++ b/devtools/ais.py @@ -306,6 +306,35 @@ type5 = ( spare(1), ) +type6_dac_or_fid_unknown = ( + bitfield("data", 920, 'raw', None, "Data"), + ) + +type6_dispatch = {} +type6_dispatch[0] = type6_dac_or_fid_unknown + +# DAC 235 and 250 (UK, Rep. of Ireland) +type6_dac235_dispatch = {} +type6_dac235_dispatch[0] = type6_dac_or_fid_unknown + +type6_dac235_fid10 = ( + bitfield("ana_int", 10, 'unsigned', None, "Supply voltage"), + bitfield("ana_ext1", 10, 'unsigned', None, "Analogue (Ext#1)"), + bitfield("ana_ext2", 10, 'unsigned', None, "Analogue (Ext#2)"), + bitfield("racon", 2, 'unsigned', None, "RACON status"), + bitfield("light", 2, 'unsigned', None, "Light status"), + bitfield("health", 1, 'unsigned', None, "Health"), + bitfield("stat_ext", 8, 'unsigned', None, "Status (ext)"), + bitfield("off_pos", 1, 'unsigned', None, "Position status"), +) +type6_dac235_dispatch[10] = type6_dac235_fid10 + +type6_dac235 = ( + dispatch("fid", type6_dac235_dispatch, lambda m: m if m in type6_dac235_dispatch else 0), + ) +type6_dispatch[235] = type6_dac235 +type6_dispatch[250] = type6_dac235 + type6 = ( bitfield("seqno", 2, 'unsigned', None, "Sequence Number"), bitfield("dest_mmsi", 30, 'unsigned', None, "Destination MMSI"), @@ -313,7 +342,7 @@ type6 = ( spare(1), bitfield("dac", 10, 'unsigned', 0, "DAC"), bitfield("fid", 6, 'unsigned', 0, "Functional ID"), - bitfield("data", 920, 'raw', None, "Data"), + dispatch("dac", type6_dispatch, lambda m: m if m in type6_dispatch else 0), ) type7 = ( diff --git a/driver_ais.c b/driver_ais.c index 44ee7ef4..68e8e698 100644 --- a/driver_ais.c +++ b/driver_ais.c @@ -178,7 +178,25 @@ bool ais_binary_decode(struct ais_t *ais, ais->type6.fid = UBITS(82, 6); ais->type6.bitcount = bitlen - 88; imo = false; - if (ais->type6.dac == 1) + /* UK and Republic Of Ireland */ + if (ais->type6.dac == 235 || ais->type6.dac == 250) { + switch (ais->type6.fid) { + case 10: /* GLA - AtoN monitoring data */ + ais->type6.dac235fid10.ana_int = UBITS(88, 10); + ais->type6.dac235fid10.ana_ext1 = UBITS(98, 10); + ais->type6.dac235fid10.ana_ext2 = UBITS(108, 10); + ais->type6.dac235fid10.racon = UBITS(118, 2); + ais->type6.dac235fid10.light = UBITS(120, 2); + ais->type6.dac235fid10.alarm = UBITS(122, 1); + ais->type6.dac235fid10.stat_ext = UBITS(123, 8); + ais->type6.dac235fid10.off_pos = UBITS(131, 1); + /* skip 4 bits */ + imo = true; + } + break; + } + /* International */ + else if (ais->type6.dac == 1) switch (ais->type6.fid) { case 12: /* IMO236 - Dangerous cargo indication */ UCHARS(88, ais->type6.dac1fid12.lastport); @@ -965,6 +965,17 @@ struct ais_t size_t bitcount; /* bit count of the data */ union { char bitdata[(AIS_TYPE6_BINARY_MAX + 7) / 8]; + /* GLA - AtoN monitoring data (UK/ROI) */ + struct { + unsigned int ana_int; /* Analogue (internal) */ + unsigned int ana_ext1; /* Analogue (external #1) */ + unsigned int ana_ext2; /* Analogue (external #2) */ + unsigned int racon; /* RACON status */ + unsigned int light; /* Light status */ + bool alarm; /* Health alarm*/ + unsigned int stat_ext; /* Status bits (external) */ + bool off_pos; /* Off position status */ + } dac235fid10; /* IMO236 - Dangerous Cargo Indication */ struct { char lastport[5+1]; /* Last Port Of Call */ diff --git a/gpsd_json.c b/gpsd_json.c index 7e8c89e3..2093f1b5 100644 --- a/gpsd_json.c +++ b/gpsd_json.c @@ -1627,6 +1627,20 @@ void json_aivdm_dump(const struct ais_t *ais, "other", }; + static const char *racon_status[] = { + "No RACON installed", + "RACON not monitored", + "RACON operational", + "RACON ERROR" + }; + + static const char *light_status[] = { + "No light or no monitoring", + "Light ON" + "Light OFF" + "Light ERROR" + }; + (void)snprintf(buf, buflen, "{\"class\":\"AIS\","); if (device != NULL && device[0] != '\0') (void)snprintf(buf + strlen(buf), buflen - strlen(buf), @@ -1807,7 +1821,59 @@ void json_aivdm_dump(const struct ais_t *ais, ais->type6.dac, ais->type6.fid); imo = false; - if (ais->type6.dac == 1) + + if (ais->type6.dac == 235 || ais->type6.dac == 250) { + switch (ais->type6.fid) { + case 10: /* GLA - AtoN monitoring data */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"off_pos\":%s,\"alarm\":%s," + "\"stat_ext\":%u,", + JSON_BOOL(ais->type6.dac235fid10.off_pos), + JSON_BOOL(ais->type6.dac235fid10.alarm), + ais->type6.dac235fid10.stat_ext); + if (scaled && ais->type6.dac235fid10.ana_int != 0) + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"ana_int\":%.2f,", + ais->type6.dac235fid10.ana_int); + else + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"ana_int\":%u,", + ais->type6.dac235fid10.ana_int); + if (scaled && ais->type6.dac235fid10.ana_ext1 != 0) + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"ana_ext1\":%.2f,", + ais->type6.dac235fid10.ana_ext1); + else + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"ana_ext1\":%u,", + ais->type6.dac235fid10.ana_ext1); + if (scaled && ais->type6.dac235fid10.ana_ext2 != 0) + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"ana_ext2\":%.2f,", + ais->type6.dac235fid10.ana_ext2); + else + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"ana_ext2\":%u,", + ais->type6.dac235fid10.ana_ext2); + + if (scaled) + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"racon\":%u,\"light\":%u", + racon_status[ais->type6.dac235fid10.racon], + light_status[ais->type6.dac235fid10.light]); + else + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "\"racon\":%u,\"light\":%u", + ais->type6.dac235fid10.racon, + ais->type6.dac235fid10.light); + if (buf[strlen(buf) - 1] == ',') + buf[strlen(buf)-1] = '\0'; + (void)strlcat(buf, "}\r\n", buflen); + imo = true; + break; + } + } + else if (ais->type6.dac == 1) switch (ais->type6.fid) { case 12: /* IMO236 -Dangerous cargo indication */ /* some fields have beem merged to an ISO8601 partial date */ diff --git a/gpsdecode.c b/gpsdecode.c index 60060b72..cc257161 100644 --- a/gpsdecode.c +++ b/gpsdecode.c @@ -105,15 +105,38 @@ static void aivdm_csv_dump(struct ais_t *ais, char *buf, size_t buflen) break; case 6: /* Binary Message */ (void)snprintf(buf + strlen(buf), buflen - strlen(buf), - "%u|%u|%u|%u|%u|%zd:%s", + "%u|%u|%u|%u|%u", ais->type6.seqno, ais->type6.dest_mmsi, (uint) 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); + switch(ais->type6.dac) { + case 235: /* UK */ + case 250: /* Rep. Of Ireland */ + switch(ais->type6.fid) { + case 10: /* GLA - AtoN monitoring */ + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "|%u|%u|%u|%u|%u|%u|%u|%u", + ais->type6.dac235fid10.ana_int, + ais->type6.dac235fid10.ana_ext1, + ais->type6.dac235fid10.ana_ext2, + ais->type6.dac235fid10.racon, + ais->type6.dac235fid10.light, + ais->type6.dac235fid10.alarm, + ais->type6.dac235fid10.stat_ext, + ais->type6.dac235fid10.off_pos); + imo = true; + break; + } + break; + } + if (!imo) + (void)snprintf(buf + strlen(buf), buflen - strlen(buf), + "|%zd:%s", + ais->type6.bitcount, + gpsd_hexdump(ais->type6.bitdata, + (ais->type6.bitcount + 7) / 8)); break; case 7: /* Binary Acknowledge */ case 13: /* Safety Related Acknowledge */ diff --git a/jsongen.py.in b/jsongen.py.in index 86e21696..64751ff2 100644 --- a/jsongen.py.in +++ b/jsongen.py.in @@ -95,6 +95,22 @@ ais_specs = ( "stringbuffered":("data",), }, { + "initname" : "json_ais6_fid10", + "headers": ("AIS_HEADER", "AIS_TYPE6",), + "structname": "ais->type6.dac235fid10", + "fieldmap":( + # fieldname type default + ('ana_int', 'uinteger', '0'), + ('ana_ext1', 'uinteger', '0'), + ('ana_ext2', 'uinteger', '0'), + ('racon', 'uinteger', '0'), + ('light', 'uinteger', '0'), + ('alarm', 'boolean', 'false'), + ('stat_ext', 'uinteger', '0'), + ('off_pos', 'boolean', 'false'), + ), + }, + { "initname" : "json_ais6_fid12", "headers": ("AIS_HEADER","AIS_TYPE6",), "structname": "ais->type6.dac1fid12", |