summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2013-09-15 11:47:33 -0400
committerEric S. Raymond <esr@thyrsus.com>2013-09-15 11:47:33 -0400
commit795a00d7598541e59d36eb865cc14eedf1d0f628 (patch)
tree65b9a1b202c4fdac127200b8b2a1d0d5305a5014
parent205add74159c5056972932e31ce873e73477dcc8 (diff)
downloadgpsd-795a00d7598541e59d36eb865cc14eedf1d0f628.tar.gz
Extract ITU-R 1371-4 model and serial fields from AIS Type24 messages.
In ITU-R 1371-4, there are new model and serial fields carved out of the right-hand end of vendorid, which is reduced from 7 chars to 3. It is not clear in which minor revision this change took place. To cope with older AIS implementations, unpack the trailing bits *both* ways; truly revision-4-conformant implementations will have up to four characters of trailing garbage on the vendorid, and older implementations will have garbafe in the model and serial fields. This commit also reverts the change to copy only 20 characters rather than 21 when analyzing the name field in a type21. There's some mystery about why this didn't break the rgression tests sooner.
-rw-r--r--NEWS1
-rw-r--r--driver_ais.c15
-rw-r--r--gps.h6
-rw-r--r--gpsd_json.c4
-rw-r--r--gpsdecode.c8
-rw-r--r--jsongen.py.in2
-rw-r--r--www/AIVDM.txt4
7 files changed, 34 insertions, 6 deletions
diff --git a/NEWS b/NEWS
index 2976d882..b94a9cc2 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@
Minor fix to AIVDM unpacking of Type 123 radio field.
Longer maximum path names (required an object library version bump.
New split24 option supports passing through AIS type 24 message halves.
+ ITU-R 1371-4 model and serial fields are extracted from AIS Type 24s.
* Wed 1 May 2013 Eric S. Raymond <esr@snark.thyrsus.com> - 3.9
Note to packagers: this is an urgent release that fixes a possible
diff --git a/driver_ais.c b/driver_ais.c
index 38edc843..4c753520 100644
--- a/driver_ais.c
+++ b/driver_ais.c
@@ -784,7 +784,7 @@ bool ais_binary_decode(struct ais_t *ais,
}
ais->type21.aid_type = UBITS(38, 5);
from_sixbit((unsigned char *)bits,
- 43, 20, ais->type21.name);
+ 43, 21, ais->type21.name);
if (strlen(ais->type21.name) == 20 && bitlen > 272)
from_sixbit((unsigned char *)bits,
272, (bitlen - 272)/6,
@@ -883,7 +883,20 @@ bool ais_binary_decode(struct ais_t *ais,
return false;
}
ais->type24.shiptype = UBITS(40, 8);
+ /*
+ * In ITU-R 1371-4, there are new model and serial fields
+ * carved out of the right-hand end of vendorid, which is
+ * reduced from 7 chars to 3. It is not clear in which
+ * minor revision this change took place. To cope with
+ * older AIS implementations, unpack the trailing bits
+ * *both* ways; truly revision-4-conformant implementations
+ * will have up to four characters of trailing garbage on
+ * the vendorid, and older implementations will have
+ * garbafe in the model and serial fields.
+ */
UCHARS(48, ais->type24.vendorid);
+ ais->type24.model = UBITS(66, 4);
+ ais->type24.serial = UBITS(70, 20);
UCHARS(90, ais->type24.callsign);
if (AIS_AUXILIARY_MMSI(ais->mmsi)) {
ais->type24.mothership_mmsi = UBITS(132, 30);
diff --git a/gps.h b/gps.h
index 80e93539..5c908b7e 100644
--- a/gps.h
+++ b/gps.h
@@ -36,7 +36,9 @@ extern "C" {
* 5.0 - MAXCHANNELS bumped from 20 to 32 for GLONASS (Mar 2011, release 2.96)
* gps_open() becomes reentrant, what gps_open_r() used to be.
* gps_poll() removed in favor of gps_read(). The raw hook is gone.
- * 5.1 - GPS_PATH_MAX uses system PATH_MAX; split24 flag added.
+ * 5.1 - GPS_PATH_MAX uses system PATH_MAX; split24 flag added. New
+ * model and serial members in part B of AIS type 24, conforming
+ * with ITU-R 1371-4.
*/
#define GPSD_API_MAJOR_VERSION 5 /* bump on incompatible changes */
#define GPSD_API_MINOR_VERSION 1 /* bump on compatible changes */
@@ -1652,6 +1654,8 @@ struct ais_t
} part;
unsigned int shiptype; /* ship type code */
char vendorid[8]; /* vendor ID */
+ unsigned int model; /* unit model code */
+ unsigned int serial; /* serial number */
char callsign[8]; /* callsign */
union {
unsigned int mothership_mmsi; /* MMSI of main vessel */
diff --git a/gpsd_json.c b/gpsd_json.c
index babbc1ac..b060fad6 100644
--- a/gpsd_json.c
+++ b/gpsd_json.c
@@ -2986,9 +2986,11 @@ void json_aivdm_dump(const struct ais_t *ais,
"\"shiptype\":%u,", ais->type24.shiptype);
}
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
- "\"vendorid\":\"%s\",\"callsign\":\"%s\",",
+ "\"vendorid\":\"%s\",\"model\":%u,\"serial\":%u,\"callsign\":\"%s\",",
json_stringify(buf1, sizeof(buf1),
ais->type24.vendorid),
+ ais->type24.model,
+ ais->type24.serial,
json_stringify(buf2, sizeof(buf2),
ais->type24.callsign));
if (AIS_AUXILIARY_MMSI(ais->mmsi)) {
diff --git a/gpsdecode.c b/gpsdecode.c
index 0ed7ef50..25b1d002 100644
--- a/gpsdecode.c
+++ b/gpsdecode.c
@@ -429,7 +429,13 @@ static void aivdm_csv_dump(struct ais_t *ais, char *buf, size_t buflen)
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
"%u|", ais->type24.shiptype);
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
- "%s|%s|", ais->type24.vendorid, ais->type24.callsign);
+ "%s|", ais->type24.vendorid);
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "%u|", ais->type24.model);
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "%u|", ais->type24.serial);
+ (void)snprintf(buf + strlen(buf), buflen - strlen(buf),
+ "%s|", ais->type24.callsign);
if (AIS_AUXILIARY_MMSI(ais->mmsi)) {
(void)snprintf(buf + strlen(buf), buflen - strlen(buf),
"%u", ais->type24.mothership_mmsi);
diff --git a/jsongen.py.in b/jsongen.py.in
index 82d165d3..74fa23a4 100644
--- a/jsongen.py.in
+++ b/jsongen.py.in
@@ -717,6 +717,8 @@ ais_specs = (
('shipname', 'string', None), # Part A
('shiptype', 'uinteger', '0'), # Part B
('vendorid', 'string', None), # Part B
+ ('model', 'uinteger', '0'), # Part B
+ ('serial', 'uinteger', '0'), # Part B
('callsign', 'string', None), # Part B
('mothership_mmsi', 'uinteger', '0'), # Part B
('dim.to_bow', 'uinteger', '0'), # Part B
diff --git a/www/AIVDM.txt b/www/AIVDM.txt
index d3afcc63..758692a6 100644
--- a/www/AIVDM.txt
+++ b/www/AIVDM.txt
@@ -3955,7 +3955,7 @@ is thanks to Kurt Schwehr.
|40-159 |120 | Vessel Name | shipname |t|(Part A) 20 sixbit chars
|160-167 | 8 | Spare | |x|(Part A) Not used
|40-47 | 8 | Ship Type | shiptype |e|(Part B) See "Ship Types"
-|48-65 | 18 | Manufacturer ID | manufacturer |t|(Part B) 3 six-bit chars
+|48-65 | 18 | Vendor ID | vendorid |t|(Part B) 3 six-bit chars
|66-69 | 4 | Unit Model Code | model |u|(Part B)
|70-89 | 20 | Serial Number | serial |u|(Part B)
|90-131 | 42 | Call Sign | callsign |t|(Part B) As in Message Type 5
@@ -3974,7 +3974,7 @@ as a Part B; values 2 and 3 are not allowed.
Bits 48-89 are as described in ITU-R 1371-4. In some earlier versions
this was one sixbit-encoded 42-bit string field, the the name of the
AIS equipment vendor. It is not clear that field practice has caught
-up with this incompatible change; as of version 3.9, GPSD still treats
+up with this incompatible change. As of version 3.9, GPSD still treats
this as a single string field named 'vendorid'.
Interpretation of the 30 bits 132-162 in Part B is variable. If the