diff options
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | ais_json.c | 99 | ||||
-rw-r--r-- | driver_aivdm.c | 14 | ||||
-rw-r--r-- | gps.h | 2 | ||||
-rw-r--r-- | gps_json.h | 1 | ||||
-rw-r--r-- | libgps_json.c | 7 |
6 files changed, 117 insertions, 9 deletions
diff --git a/Makefile.am b/Makefile.am index 3a327e73..d2aeb527 100644 --- a/Makefile.am +++ b/Makefile.am @@ -134,6 +134,7 @@ libgps_la_LDFLAGS = -version-number 19:0:0 lib_LTLIBRARIES = libgps.la libgpsd_c_sources = \ + ais_json.c \ bits.c \ bsd-base64.c \ crc24q.c \ @@ -146,7 +147,6 @@ libgpsd_c_sources = \ json.c \ libgps.c \ libgps_json.c \ - rtcm2_json.c \ gpsdclient.c \ libgpsd_core.c \ net_dgpsip.c \ @@ -157,6 +157,7 @@ libgpsd_c_sources = \ ntpshm.c \ packet.c \ serial.c \ + rtcm2_json.c \ srecord.c \ strl.c \ subframe.c \ diff --git a/ais_json.c b/ais_json.c new file mode 100644 index 00000000..cd2b2db2 --- /dev/null +++ b/ais_json.c @@ -0,0 +1,99 @@ +/**************************************************************************** + +NAME + ais_json.c - deserialize AIS JSON + +DESCRIPTION + This module uses the generic JSON parser to get data from AIS +representations to libgps structures. + +***************************************************************************/ + +#include <math.h> +#include <assert.h> +#include <string.h> +#include <stddef.h> +#include <stdio.h> + +#include "gpsd_config.h" +#include "gpsd.h" +#include "gps_json.h" + +/* common fields in every AIS message */ + +int json_ais_read(const char *buf, + char *path, size_t pathlen, + struct ais_t *ais, + const char **endptr) +{ + +#define AIS_HEADER \ + {"class", check, .dflt.check = "AIS"}, \ + {"type", uinteger, .addr.uinteger = &ais->type}, \ + {"device", string, .addr.string = path, \ + .len = pathlen}, \ + {"repeat", uinteger, .addr.uinteger = &ais->repeat}, \ + {"mmsi", uinteger, .addr.uinteger = &ais->mmsi}, + + int status; + + const struct json_attr_t json_ais1[] = { + AIS_HEADER + {NULL}, + }; + + const struct json_attr_t json_ais4[] = { + AIS_HEADER + {NULL}, + }; + + const struct json_attr_t json_ais5[] = { + AIS_HEADER + {NULL}, + }; + + const struct json_attr_t json_ais6[] = { + AIS_HEADER + {NULL}, + }; + + const struct json_attr_t json_ais7[] = { + AIS_HEADER + {NULL}, + }; + + const struct json_attr_t json_ais8[] = { + AIS_HEADER + {NULL}, + }; + + const struct json_attr_t json_ais16[] = { + AIS_HEADER + {NULL}, + }; + +#undef AIS_HEADER + + memset(ais, '\0', sizeof(struct ais_t)); + + if (strstr(buf, "\"type\":1,")!=NULL || strstr(buf, "\"type\":2,")!=NULL || strstr(buf, "\"type\":3,")!=NULL) { + status = json_read_object(buf, json_ais1, endptr); + } else if (strstr(buf, "\"type\":4,") != NULL || strstr(buf, "\"type\":11,")!=NULL) { + status = json_read_object(buf, json_ais4, endptr); + } else if (strstr(buf, "\"type\":5,") != NULL) { + status = json_read_object(buf, json_ais5, endptr); + } else if (strstr(buf, "\"type\":6,") != NULL) { + status = json_read_object(buf, json_ais6, endptr); + } else if (strstr(buf, "\"type\":7,") != NULL) { + status = json_read_object(buf, json_ais7, endptr); + } else if (strstr(buf, "\"type\":8,") != NULL) { + status = json_read_object(buf, json_ais8, endptr); + } else if (strstr(buf, "\"type\":16,") != NULL) { + status = json_read_object(buf, json_ais16, endptr); + } else { + return JSON_ERR_MISC; + } + return status; +} + +/* ais_json.c ends here */ diff --git a/driver_aivdm.c b/driver_aivdm.c index 7eeac790..df4075f3 100644 --- a/driver_aivdm.c +++ b/driver_aivdm.c @@ -140,12 +140,12 @@ bool aivdm_decode(char *buf, size_t buflen, struct aivdm_context_t *ais_context) #define UBITS(s, l) ubits((char *)ais_context->bits, s, l) #define SBITS(s, l) sbits((char *)ais_context->bits, s, l) #define UCHARS(s, to) from_sixbit((char *)ais_context->bits, s, sizeof(to), to) - ais->msgtype = UBITS(0, 6); + ais->type = UBITS(0, 6); ais->repeat = UBITS(6, 2); ais->mmsi = UBITS(8, 30); gpsd_report(LOG_INF, "AIVDM message type %d, MMSI %09d:\n", - ais->msgtype, ais->mmsi); - switch (ais->msgtype) { + ais->type, ais->mmsi); + switch (ais->type) { case 1: /* Position Report */ case 2: case 3: @@ -497,7 +497,7 @@ bool aivdm_decode(char *buf, size_t buflen, struct aivdm_context_t *ais_context) break; default: gpsd_report(LOG_INF, "\n"); - gpsd_report(LOG_ERROR, "Unparsed AIVDM message type %d.\n",ais->msgtype); + gpsd_report(LOG_ERROR, "Unparsed AIVDM message type %d.\n",ais->type); break; } #undef UCHARS @@ -688,11 +688,11 @@ void aivdm_dump(struct ais_t *ais, bool scaled, bool json, char *buf, size_t buf #define NAVAIDTYPE_DISPLAY(n) (((n) < (sizeof(navaid_type_legends)/sizeof(navaid_type_legends[0]))) ? navaid_type_legends[n] : "INVALID NAVAID TYPE") if (json) - (void)snprintf(buf, buflen, "{\"class\":\"AIS\",\"type\":%u,\"repeat\":%u,\"mmsi\":\"%09u\",", ais->msgtype, ais->repeat, ais->mmsi); + (void)snprintf(buf, buflen, "{\"class\":\"AIS\",\"type\":%u,\"repeat\":%u,\"mmsi\":\"%09u\",", ais->type, ais->repeat, ais->mmsi); else - (void)snprintf(buf, buflen, "%u,%u,%09u,", ais->msgtype, ais->repeat, ais->mmsi); + (void)snprintf(buf, buflen, "%u,%u,%09u,", ais->type, ais->repeat, ais->mmsi); /*@ -formatconst @*/ - switch (ais->msgtype) { + switch (ais->type) { case 1: /* Position Report */ case 2: case 3: @@ -475,7 +475,7 @@ typedef /*@unsignedintegraltype@*/ unsigned int gps_mask_t; struct ais_t { - uint msgtype; /* message type */ + uint type; /* message type */ uint repeat; /* Repeat indicator */ uint mmsi; /* MMSI */ union { @@ -13,6 +13,7 @@ void json_sky_dump(struct gps_data_t *, char *, size_t); void json_device_dump(struct gps_device_t *, char *, size_t); void json_watch_dump(struct policy_t *, char *, size_t); int json_rtcm2_read(const char *, char *, size_t, struct rtcm2_t *, const char **); +int json_ais_read(const char *, char *, size_t, struct ais_t *, const char **); int libgps_json_unpack(const char *, struct gps_data_t *); /* gps_json.h ends here */ diff --git a/libgps_json.c b/libgps_json.c index 9382b3f7..f6c89ca7 100644 --- a/libgps_json.c +++ b/libgps_json.c @@ -262,6 +262,13 @@ int libgps_json_unpack(const char *buf, struct gps_data_t *gpsdata) if (status == 0) gpsdata->set |= RTCM2_SET; return status; + } else if (strstr(buf, "\"class\":\"AIS\"") != 0) { + status = json_ais_read(buf, + gpsdata->dev.path, sizeof(gpsdata->dev.path), + &gpsdata->rtcm2, NULL); + if (status == 0) + gpsdata->set |= AIS_SET; + return status; } else if (strstr(buf, "\"class\":\"ERROR\"") != 0) { return json_error_read(buf, gpsdata, NULL); } else |