summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--driver_aivdm.c52
-rw-r--r--gps.h6
-rw-r--r--gpsd_json.c66
-rw-r--r--gpsdecode.c28
-rw-r--r--json.h2
-rwxr-xr-xjsongen.py111
-rw-r--r--www/AIVDM.txt4
7 files changed, 176 insertions, 93 deletions
diff --git a/driver_aivdm.c b/driver_aivdm.c
index 7a5b1089..825b6300 100644
--- a/driver_aivdm.c
+++ b/driver_aivdm.c
@@ -148,30 +148,30 @@ bool aivdm_decode(char *buf, size_t buflen, struct aivdm_context_t *ais_context)
case 1: /* Position Report */
case 2:
case 3:
- ais->type123.status = UBITS(38, 4);
- ais->type123.turn = SBITS(42, 8);
- ais->type123.speed = UBITS(50, 10);
- ais->type123.accuracy = (bool)UBITS(60, 1);
- ais->type123.lon = SBITS(61, 28);
- ais->type123.lat = SBITS(89, 27);
- ais->type123.course = UBITS(116, 12);
- ais->type123.heading = UBITS(128, 9);
- ais->type123.second = UBITS(137, 6);
- ais->type123.maneuver = UBITS(143, 2);
- //ais->type123.spare = UBITS(145, 3);
- ais->type123.raim = UBITS(148, 1)!=0;
- ais->type123.radio = UBITS(149, 20);
+ ais->type1.status = UBITS(38, 4);
+ ais->type1.turn = SBITS(42, 8);
+ ais->type1.speed = UBITS(50, 10);
+ ais->type1.accuracy = (bool)UBITS(60, 1);
+ ais->type1.lon = SBITS(61, 28);
+ ais->type1.lat = SBITS(89, 27);
+ ais->type1.course = UBITS(116, 12);
+ ais->type1.heading = UBITS(128, 9);
+ ais->type1.second = UBITS(137, 6);
+ ais->type1.maneuver = UBITS(143, 2);
+ //ais->type1.spare = UBITS(145, 3);
+ ais->type1.raim = UBITS(148, 1)!=0;
+ ais->type1.radio = UBITS(149, 20);
gpsd_report(LOG_INF,
"Nav=%d TURN=%d SPEED=%d Q=%d Lon=%d Lat=%d COURSE=%d TH=%d Sec=%d\n",
- ais->type123.status,
- ais->type123.turn,
- ais->type123.speed,
- (uint)ais->type123.accuracy,
- ais->type123.lon,
- ais->type123.lat,
- ais->type123.course,
- ais->type123.heading,
- ais->type123.second);
+ ais->type1.status,
+ ais->type1.turn,
+ ais->type1.speed,
+ (uint)ais->type1.accuracy,
+ ais->type1.lon,
+ ais->type1.lat,
+ ais->type1.course,
+ ais->type1.heading,
+ ais->type1.second);
break;
case 4: /* Base Station Report */
case 11: /* UTC/Date Response */
@@ -232,7 +232,7 @@ bool aivdm_decode(char *buf, size_t buflen, struct aivdm_context_t *ais_context)
ais->type6.dest_mmsi = UBITS(40, 30);
ais->type6.retransmit = (bool)UBITS(70, 1);
//ais->type6.spare = UBITS(71, 1);
- ais->type6.application_id = UBITS(72, 16);
+ ais->type6.app_id = UBITS(72, 16);
ais->type6.bitcount = ais_context->bitlen - 88;
(void)memcpy(ais->type6.bitdata,
(char *)ais_context->bits+11,
@@ -240,7 +240,7 @@ bool aivdm_decode(char *buf, size_t buflen, struct aivdm_context_t *ais_context)
gpsd_report(LOG_INF, "seqno=%d, dest=%u, id=%u, cnt=%u\n",
ais->type6.seqno,
ais->type6.dest_mmsi,
- ais->type6.application_id,
+ ais->type6.app_id,
ais->type6.bitcount);
break;
case 7: /* Binary acknowledge */
@@ -253,13 +253,13 @@ bool aivdm_decode(char *buf, size_t buflen, struct aivdm_context_t *ais_context)
break;
case 8: /* Binary Broadcast Message */
//ais->type8.spare = UBITS(38, 2);
- ais->type8.application_id = UBITS(40, 16);
+ ais->type8.app_id = UBITS(40, 16);
ais->type8.bitcount = ais_context->bitlen - 56;
(void)memcpy(ais->type8.bitdata,
(char *)ais_context->bits+7,
(ais->type8.bitcount + 7) / 8);
gpsd_report(LOG_INF, "id=%u, cnt=%u\n",
- ais->type8.application_id,
+ ais->type8.app_id,
ais->type8.bitcount);
break;
case 9: /* Standard SAR Aircraft Position Report */
diff --git a/gps.h b/gps.h
index 412c65cb..becc2ea2 100644
--- a/gps.h
+++ b/gps.h
@@ -508,7 +508,7 @@ struct ais_t
//uint spare; spare bits */
bool raim; /* RAIM flag */
uint radio; /* radio status bits */
- } type123;
+ } type1;
/* Type 4 - Base Station Report & Type 11 - UTC and Date Response */
struct {
uint year; /* UTC year */
@@ -558,7 +558,7 @@ struct ais_t
uint dest_mmsi; /* destination MMSI */
bool retransmit; /* retransmit flag */
//uint spare; spare bit(s) */
- uint application_id; /* Application ID */
+ uint app_id; /* Application ID */
#define AIS_TYPE6_BINARY_MAX 920 /* 920 bits */
uint bitcount; /* bit count of the data */
char bitdata[(AIS_TYPE6_BINARY_MAX + 7) / 8];
@@ -570,7 +570,7 @@ struct ais_t
/* Type 8 - Broadcast Binary Message */
struct {
//uint spare; spare bit(s) */
- uint application_id; /* Application ID */
+ uint app_id; /* Application ID */
#define AIS_TYPE8_BINARY_MAX 952 /* 952 bits */
uint bitcount; /* bit count of the data */
char bitdata[(AIS_TYPE8_BINARY_MAX + 7) / 8];
diff --git a/gpsd_json.c b/gpsd_json.c
index 7eea3670..24462a03 100644
--- a/gpsd_json.c
+++ b/gpsd_json.c
@@ -632,64 +632,64 @@ void aivdm_json_dump(struct ais_t *ais, bool scaled, char *buf, size_t buflen)
* Express turn as nan if not available,
* "fastleft"/"fastright" for fast turns.
*/
- if (ais->type123.turn == -128)
+ if (ais->type1.turn == -128)
(void) strlcpy(turnlegend, "nan", sizeof(turnlegend));
- else if (ais->type123.turn == -127)
+ else if (ais->type1.turn == -127)
(void) strlcpy(turnlegend, "fastleft", sizeof(turnlegend));
- else if (ais->type123.turn == 127)
+ else if (ais->type1.turn == 127)
(void) strlcpy(turnlegend, "fastright", sizeof(turnlegend));
else
(void)snprintf(turnlegend, sizeof(turnlegend),
"%.0f",
- ais->type123.turn * ais->type123.turn / 4.733);
+ ais->type1.turn * ais->type1.turn / 4.733);
/*
* Express speed as nan if not available,
* "fast" for fast movers.
*/
- if (ais->type123.speed == AIS_SPEED_NOT_AVAILABLE)
+ if (ais->type1.speed == AIS_SPEED_NOT_AVAILABLE)
(void) strlcpy(speedlegend, "nan", sizeof(speedlegend));
- else if (ais->type123.speed == AIS_SPEED_FAST_MOVER)
+ else if (ais->type1.speed == AIS_SPEED_FAST_MOVER)
(void) strlcpy(speedlegend, "fast", sizeof(speedlegend));
else
(void)snprintf(speedlegend, sizeof(speedlegend),
- "%.1f", ais->type123.speed / 10.0);
+ "%.1f", ais->type1.speed / 10.0);
(void)snprintf(buf+strlen(buf), buflen-strlen(buf),
"\"status\":\"%s\",\"turn\":%s,\"speed\":%s,"
"\"accuracy\":%s,\"lon\":%.4f,\"lat\":%.4f,"
"\"course\":%u,\"heading\":%d,\"second\":%u,"
"\"maneuver\":%d,\"raim\":%s,\"radio\":%d}\r\n",
- nav_legends[ais->type123.status],
+ nav_legends[ais->type1.status],
turnlegend,
speedlegend,
- JSON_BOOL(ais->type123.accuracy),
- ais->type123.lon / AIS_LATLON_SCALE,
- ais->type123.lat / AIS_LATLON_SCALE,
- ais->type123.course,
- ais->type123.heading,
- ais->type123.second,
- ais->type123.maneuver,
- JSON_BOOL(ais->type123.raim),
- ais->type123.radio);
+ JSON_BOOL(ais->type1.accuracy),
+ ais->type1.lon / AIS_LATLON_SCALE,
+ ais->type1.lat / AIS_LATLON_SCALE,
+ ais->type1.course,
+ ais->type1.heading,
+ ais->type1.second,
+ ais->type1.maneuver,
+ JSON_BOOL(ais->type1.raim),
+ ais->type1.radio);
} else {
(void)snprintf(buf+strlen(buf), buflen-strlen(buf),
"\"status\":%u,\"turn\":%d,\"speed\":%u,"
"\"accuracy\":%s,\"lon\":%d,\"lat\":%d,"
"\"course\":%u,\"heading\":%d,\"second\":%u,"
"\"maneuver\":%d,\"raim\":%s,\"radio\":%d}\r\n",
- ais->type123.status,
- ais->type123.turn,
- ais->type123.speed,
- JSON_BOOL(ais->type123.accuracy),
- ais->type123.lon,
- ais->type123.lat,
- ais->type123.course,
- ais->type123.heading,
- ais->type123.second,
- ais->type123.maneuver,
- JSON_BOOL(ais->type123.raim),
- ais->type123.radio);
+ ais->type1.status,
+ ais->type1.turn,
+ ais->type1.speed,
+ JSON_BOOL(ais->type1.accuracy),
+ ais->type1.lon,
+ ais->type1.lat,
+ ais->type1.course,
+ ais->type1.heading,
+ ais->type1.second,
+ ais->type1.maneuver,
+ JSON_BOOL(ais->type1.raim),
+ ais->type1.radio);
}
break;
case 4: /* Base Station Report */
@@ -788,12 +788,12 @@ void aivdm_json_dump(struct ais_t *ais, bool scaled, char *buf, size_t buflen)
case 6: /* Binary Message */
(void)snprintf(buf+strlen(buf), buflen-strlen(buf),
"\"seqno\":%u,\"dest_mmsi\":%u,"
- "\"retransmit\":%u,\"application_id\":%u,"
+ "\"retransmit\":%u,\"app_id\":%u,"
"\"data\":\"%u:%s\"}\r\n",
ais->type6.seqno,
ais->type6.dest_mmsi,
ais->type6.retransmit,
- ais->type6.application_id,
+ ais->type6.app_id,
ais->type6.bitcount,
gpsd_hexdump(ais->type6.bitdata,
(ais->type6.bitcount+7)/8));
@@ -808,8 +808,8 @@ void aivdm_json_dump(struct ais_t *ais, bool scaled, char *buf, size_t buflen)
break;
case 8: /* Binary Broadcast Message */
(void)snprintf(buf+strlen(buf), buflen-strlen(buf),
- "\"appid\":%u,\"data\":\"%u:%s\"}\r\n",
- ais->type8.application_id,
+ "\"app_id\":%u,\"data\":\"%u:%s\"}\r\n",
+ ais->type8.app_id,
ais->type8.bitcount,
gpsd_hexdump(ais->type8.bitdata,
(ais->type8.bitcount+7)/8));
diff --git a/gpsdecode.c b/gpsdecode.c
index bdebafd4..2f4054dd 100644
--- a/gpsdecode.c
+++ b/gpsdecode.c
@@ -49,18 +49,18 @@ static void aivdm_csv_dump(struct ais_t *ais, char *buf, size_t buflen)
case 3:
(void)snprintf(buf+strlen(buf), buflen-strlen(buf),
"%u,%d,%u,%u,%d,%d,%u,%d,%u,0x%x,%d,0x%x",
- ais->type123.status,
- ais->type123.turn,
- ais->type123.speed,
- (uint)ais->type123.accuracy,
- ais->type123.lon,
- ais->type123.lat,
- ais->type123.course,
- ais->type123.heading,
- ais->type123.second,
- ais->type123.maneuver,
- ais->type123.raim,
- ais->type123.radio);
+ ais->type1.status,
+ ais->type1.turn,
+ ais->type1.speed,
+ (uint)ais->type1.accuracy,
+ ais->type1.lon,
+ ais->type1.lat,
+ ais->type1.course,
+ ais->type1.heading,
+ ais->type1.second,
+ ais->type1.maneuver,
+ ais->type1.raim,
+ ais->type1.radio);
break;
case 4: /* Base Station Report */
case 11: /* UTC/Date Response */
@@ -106,7 +106,7 @@ static void aivdm_csv_dump(struct ais_t *ais, char *buf, size_t buflen)
ais->type6.seqno,
ais->type6.dest_mmsi,
ais->type6.retransmit,
- ais->type6.application_id,
+ ais->type6.app_id,
ais->type6.bitcount,
gpsd_hexdump(ais->type6.bitdata,
(ais->type6.bitcount+7)/8));
@@ -122,7 +122,7 @@ static void aivdm_csv_dump(struct ais_t *ais, char *buf, size_t buflen)
case 8: /* Binary Broadcast Message */
(void)snprintf(buf+strlen(buf), buflen-strlen(buf),
"%u,%u:%s",
- ais->type8.application_id,
+ ais->type8.app_id,
ais->type8.bitcount,
gpsd_hexdump(ais->type8.bitdata,
(ais->type8.bitcount+7)/8));
diff --git a/json.h b/json.h
index 115dbb20..e5d456bc 100644
--- a/json.h
+++ b/json.h
@@ -58,7 +58,7 @@ struct json_attr_t {
};
#define JSON_ATTR_MAX 31 /* max chars in JSON attribute name */
-#define JSON_VAL_MAX 63 /* max chars in JSON value part */
+#define JSON_VAL_MAX 120 /* max chars in JSON value part */
int json_read_object(const char *, const struct json_attr_t *, const char **);
int json_read_array(const char *, const struct json_array_t *, const char **);
diff --git a/jsongen.py b/jsongen.py
index 044112d2..9c7cca16 100755
--- a/jsongen.py
+++ b/jsongen.py
@@ -57,7 +57,7 @@ ais_specs = (
"header": "\tAIS_HEADER,",
"structname": "ais->type5",
"fieldmap":(
- # fieldname type default
+ # fieldname type default
('imo', 'uinteger', '0'),
('ais_version', 'uinteger', '0'),
('callsign', 'string', None),
@@ -75,28 +75,112 @@ ais_specs = (
),
"stringbuffered":("eta",),
},
+ {
+ "initname" : "json_ais6",
+ "header": "\tAIS_HEADER,",
+ "structname": "ais->type6",
+ "fieldmap":(
+ # fieldname type default
+ ('seqno', 'uinteger', '0'),
+ ('dest_mmsi', 'uinteger', '0'),
+ ('retransmit', 'uinteger', '0'),
+ ('app_id', 'uinteger', '0'),
+ ('data', 'string', None),
+ ),
+ "stringbuffered":("data",),
+ },
+ {
+ "initname" : "json_ais7",
+ "header": "\tAIS_HEADER,",
+ "structname": "ais->type7",
+ "fieldmap":(
+ # fieldname type default
+ ('mmsi1', 'uinteger', '0'),
+ ('mmsi2', 'uinteger', '0'),
+ ('mmsi3', 'uinteger', '0'),
+ ('mmsi4', 'uinteger', '0'),
+ ),
+ },
+ {
+ "initname" : "json_ais8",
+ "header": "\tAIS_HEADER,",
+ "structname": "ais->type8",
+ "fieldmap":(
+ # fieldname type default
+ ('app_id', 'uinteger', '0'),
+ ('data', 'string', None),
+ ),
+ "stringbuffered":("data",),
+ },
+ {
+ "initname" : "json_ais9",
+ "header": "\tAIS_HEADER,",
+ "structname": "ais->type9",
+ "fieldmap":(
+ # fieldname type default
+ ('alt', 'uinteger', 'AIS_ALT_NOT_AVAILABLE'),
+ ('speed', 'uinteger', 'AIS_SPEED_NOT_AVAILABLE'),
+ ('accuracy', 'boolean', 'false'),
+ ('lon', 'real', 'AIS_LON_NOT_AVAILABLE'),
+ ('lat', 'real', 'AIS_LAT_NOT_AVAILABLE'),
+ ('course', 'real', 'AIS_COURSE_NOT_AVAILABLE'),
+ ('second', 'uinteger', 'AIS_SEC_NOT_AVAILABLE'),
+ ('regional', 'integer', '0'),
+ ('dte', 'uinteger', '1'),
+ ('raim', 'boolean', 'false'),
+ ('radio', 'integer', '0'),
+ ),
+ },
+ {
+ "initname" : "json_ais10",
+ "header": "\tAIS_HEADER,",
+ "structname": "ais->type10",
+ "fieldmap":(
+ # fieldname type default
+ ('dest_mmsi', 'uinteger', '0'),
+ ),
+ },
+ {
+ "initname" : "json_ais12",
+ "header": "\tAIS_HEADER,",
+ "structname": "ais->type12",
+ "fieldmap":(
+ # fieldname type default
+ ('seq', 'uinteger', '0'),
+ ('dst', 'uinteger', '0'),
+ ('rexmit', 'uinteger', '0'),
+ ('text', 'string', None),
+ ),
+ },
+ {
+ "initname" : "json_ais13",
+ "header": "\tAIS_HEADER,",
+ "structname": "ais->type13",
+ "fieldmap":(
+ # fieldname type default
+ ('mmsi1', 'uinteger', '0'),
+ ('mmsi2', 'uinteger', '0'),
+ ('mmsi3', 'uinteger', '0'),
+ ('mmsi4', 'uinteger', '0'),
+ ),
+ },
)
-# Map shared field names to data types
-overrides = {
- "raim":"boolean",
- "accuracy":"boolean",
- }
-
# Give this global the string spec you need to convert with -g
-# We do it this mildly odd way only becaue passing Python multiline
+# We do it this mildly odd way only because passing Python multiline
# string literals on the command line is inconvenient.
stringspec = \
- "\"seqno\":%u,\"dest_mmsi\":%u,"\
- "\"retransmit\":%u,\"application_id\":%u,"\
- "\"data\":\"%u:%s\"}\r\n"
+ "\"mmsi1\":%u,\"mmsi2\":%u,\"mmsi3\":%u,\"mmsi4\":%u}\r\n"
# You should not need to modify anything below this liine.
def generate(spec):
+ outboard = []
for (attr, itype, default) in spec["fieldmap"]:
if attr in spec.get("stringbuffered", []):
- print " char %s[JSON_VAL_MAX+1];" % attr
+ if attr not in outboard:
+ print " char %s[JSON_VAL_MAX+1];" % attr
+ outboard.append(attr)
print " const struct json_attr_t %s[] = {" % spec["initname"]
if "header" in spec:
print spec["header"]
@@ -130,6 +214,7 @@ def string_to_specifier(strspec):
"d": "integer",
"u": "uinteger",
"f": "real",
+ "s": "boolean", # Only booleans print as unquoted strings
"\"": "string",
}
dftmap = {
@@ -153,8 +238,6 @@ def string_to_specifier(strspec):
attr = attr[1:]
if attr[-1] == '"':
attr = attr[:-1]
- if attr in overrides:
- itype = overrides[attr]
dflt = dftmap[itype]
if dflt is not None:
dflt = `dflt`
diff --git a/www/AIVDM.txt b/www/AIVDM.txt
index 62e6fb59..4cbcf16c 100644
--- a/www/AIVDM.txt
+++ b/www/AIVDM.txt
@@ -711,7 +711,7 @@ Field Len Description Member Units
70 1 Retransmit flag retransmit 0 = no retransmission (default)
1 = retransmitted
71 1 Spare Not used
-72-87 16 Application ID application_id Unsigned integer
+72-87 16 Application ID app_id Unsigned integer
88 920 Data data Binary data
Field may be shorter than 920 bits.
-------------------------------------------------------------------------------
@@ -753,7 +753,7 @@ Field Len Description Member Units
6-7 2 Repeat Indicator repeat As in Common Navigation Block
8-37 30 Source MMSI mmsi Unsigned integer: 9 digits
38-39 2 Spare Not used
-40-55 16 Application ID application_id Unsigned integer
+40-55 16 Application ID app_id Unsigned integer
56 952 Data data Binary data
Field may be shorter than 952 bits.
-------------------------------------------------------------------------------