summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Gagneraud <chgans@gna.org>2012-05-23 00:27:04 +0100
committerChristian Gagneraud <cgagneraud@techworks.ie>2012-05-23 21:36:34 +0100
commitf2ba497b7ebe1158bb2e0088ad828c45600938ee (patch)
tree5abb21afc08b3465844c628639923840ceea9a04
parent6041bdbf72c9b92d50b5bad8a7e7ced9ef65678f (diff)
downloadgpsd-f2ba497b7ebe1158bb2e0088ad828c45600938ee.tar.gz
[AIS] Add UK/ROI AtoN monitoring data message handling
-rw-r--r--ais_json.c6
-rwxr-xr-xdevtools/ais.py31
-rw-r--r--driver_ais.c20
-rw-r--r--gps.h11
-rw-r--r--gpsd_json.c68
-rw-r--r--gpsdecode.c33
-rw-r--r--jsongen.py.in16
7 files changed, 177 insertions, 8 deletions
diff --git a/ais_json.c b/ais_json.c
index 1b041b4c..7bc50daa 100644
--- a/ais_json.c
+++ b/ais_json.c
@@ -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);
diff --git a/gps.h b/gps.h
index b74ea29b..6a4920c8 100644
--- a/gps.h
+++ b/gps.h
@@ -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",