summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2013-05-01 11:23:06 -0400
committerEric S. Raymond <esr@thyrsus.com>2013-05-01 11:23:06 -0400
commit5432551d3e90f7c4827b795e7d1048581d4cb46e (patch)
tree3040d131351534bd27c9e5430469399133f6bab3
parent8108a76644d3053bdb4e7c4a87359d65e262af81 (diff)
downloadgpsd-5432551d3e90f7c4827b795e7d1048581d4cb46e.tar.gz
Start on support for unpacking RTCM3 JSON.
Only the 1001 sentence so far, with two fields missing. Not usable for production yet, but gets infrastructure in place.
-rw-r--r--SConstruct3
-rw-r--r--gps_json.h2
-rw-r--r--libgps_json.c11
-rw-r--r--rtcm3_json.c114
4 files changed, 129 insertions, 1 deletions
diff --git a/SConstruct b/SConstruct
index 0e07a034..b0af78fd 100644
--- a/SConstruct
+++ b/SConstruct
@@ -699,6 +699,7 @@ libgps_sources = [
"libgps_sock.c",
"netlib.c",
"rtcm2_json.c",
+ "rtcm3_json.c",
"shared_json.c",
"strl.c",
]
@@ -859,7 +860,7 @@ if qt_env:
# infamous "Two environments with different actions were specified
# for the same target" error.
for src in libgps_sources:
- if src not in ('ais_json.c','json.c','libgps_json.c','rtcm2_json.c','shared_json.c'):
+ if src not in ('ais_json.c','json.c','libgps_json.c','rtcm2_json.c','rtcm3_json.c','shared_json.c'):
compile_with = qt_env['CXX']
compile_flags = qt_flags
else:
diff --git a/gps_json.h b/gps_json.h
index 3a071827..15eb0394 100644
--- a/gps_json.h
+++ b/gps_json.h
@@ -35,6 +35,8 @@ void json_aivdm_dump(const struct ais_t *, /*@null@*/const char *, bool,
/*@out@*/char *, size_t);
int json_rtcm2_read(const char *, char *, size_t, struct rtcm2_t *,
/*@null@*/const char **);
+int json_rtcm3_read(const char *, char *, size_t, struct rtcm3_t *,
+ /*@null@*/const char **);
int json_ais_read(const char *, char *, size_t, struct ais_t *,
/*@null@*/const char **);
int libgps_json_unpack(const char *, struct gps_data_t *,
diff --git a/libgps_json.c b/libgps_json.c
index 09141f76..8ffa3434 100644
--- a/libgps_json.c
+++ b/libgps_json.c
@@ -452,6 +452,17 @@ int libgps_json_unpack(const char *buf,
}
return status;
#endif /* RTCM104V2_ENABLE */
+#ifdef RTCM104V3_ENABLE
+ } else if (STARTSWITH(classtag, "\"class\":\"RTCM3\"")) {
+ status = json_rtcm3_read(buf,
+ gpsdata->dev.path, sizeof(gpsdata->dev.path),
+ &gpsdata->rtcm3, end);
+ if (status == 0) {
+ gpsdata->set &= ~UNION_SET;
+ gpsdata->set |= RTCM3_SET;
+ }
+ return status;
+#endif /* RTCM104V3_ENABLE */
#ifdef AIVDM_ENABLE
} else if (STARTSWITH(classtag, "\"class\":\"AIS\"")) {
status = json_ais_read(buf,
diff --git a/rtcm3_json.c b/rtcm3_json.c
new file mode 100644
index 00000000..70cd3279
--- /dev/null
+++ b/rtcm3_json.c
@@ -0,0 +1,114 @@
+/****************************************************************************
+
+NAME
+ rtcm3_json.c - deserialize RTCM3 JSON
+
+DESCRIPTION
+ This module uses the generic JSON parser to get data from RTCM3
+representations to libgps structures.
+
+PERMISSIONS
+ This file is Copyright (c) 2013 by the GPSD project
+ BSD terms apply: see the file COPYING in the distribution root for details.
+
+***************************************************************************/
+
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <stddef.h>
+
+#include "gpsd.h"
+
+#ifdef SOCKET_EXPORT_ENABLE
+#include "gps_json.h"
+
+int json_rtcm3_read(const char *buf,
+ char *path, size_t pathlen, struct rtcm3_t *rtcm3,
+ /*@null@*/ const char **endptr)
+{
+
+ static char *stringptrs[NITEMS(rtcm3->rtcmtypes.data)];
+ static char stringstore[sizeof(rtcm3->rtcmtypes.data) * 2];
+ static int stringcount;
+
+/* *INDENT-OFF* */
+#define RTCM3_HEADER \
+ {"class", t_check, .dflt.check = "RTCM3"}, \
+ {"type", t_uinteger, .addr.uinteger = &rtcm3->type}, \
+ {"device", t_string, .addr.string = path, \
+ .len = pathlen}, \
+ {"length", t_uinteger, .addr.uinteger = &rtcm3->length},
+
+ int status = 0, satcount = 0;
+
+ /*@ -fullinitblock @*/
+ const struct json_attr_t rtcm1001_satellite[] = {
+ {"ident", t_uinteger, STRUCTOBJECT(struct rtcm3_1001_t, ident)},
+ {"ind", t_uinteger, STRUCTOBJECT(struct rtcm3_1001_t, L1.indicator)},
+ {"prange", t_real, STRUCTOBJECT(struct rtcm3_1001_t, L1.pseudorange)},
+ {"delta", t_real, STRUCTOBJECT(struct rtcm3_1001_t, L1.rangediff)},
+
+ {"lockt", t_uinteger, STRUCTOBJECT(struct rtcm3_1001_t, L1.locktime)},
+ {NULL},
+ };
+ /*@-type@*//* STRUCTARRAY confuses splint */
+#define R1001 &rtcm3->rtcmtypes.rtcm3_1001.header
+ const struct json_attr_t json_rtcm1001[] = {
+ RTCM3_HEADER
+ //{"station_id", t_uinteger, .addr.uinteger = R1001.station_id}, \
+ {"tow", t_uinteger, .addr.uinteger = R1001.tow}, \
+ {"sync", t_boolean, .addr.boolean = R1001.sync},
+ {"smoothing", t_boolean, .addr.boolean = R1001.smoothing},
+ //{"interval", t_uinteger, .addr.uinteger = R1001.interval},
+ {"satellites", t_array, STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1001.rtk_data,
+ rtcm1001_satellite, &satcount)},
+ {NULL},
+ };
+#undef R1001
+ /*@+type@*/
+
+ /*@-type@*//* complex union array initislizations confuses splint */
+ const struct json_attr_t json_rtcm3_fallback[] = {
+ RTCM3_HEADER
+ {"data", t_array, .addr.array.element_type = t_string,
+ .addr.array.arr.strings.ptrs = stringptrs,
+ .addr.array.arr.strings.store = stringstore,
+ .addr.array.arr.strings.storelen = sizeof(stringstore),
+ .addr.array.count = &stringcount,
+ .addr.array.maxlen = NITEMS(stringptrs)},
+ {NULL},
+ };
+ /*@+type@*/
+ /*@ +fullinitblock @*/
+
+#undef RTCM3_HEADER
+/* *INDENT-ON* */
+
+ memset(rtcm3, '\0', sizeof(struct rtcm3_t));
+
+ if (strstr(buf, "\"type\":1001,") != NULL) {
+ status = json_read_object(buf, json_rtcm1001, endptr);
+ if (status == 0)
+ rtcm3->rtcmtypes.rtcm3_1003.header.satcount = (unsigned)satcount;
+ } else {
+ int n;
+ status = json_read_object(buf, json_rtcm3_fallback, endptr);
+ for (n = 0; n < NITEMS(rtcm3->rtcmtypes.data); n++) {
+ if (n >= stringcount) {
+ rtcm3->rtcmtypes.data[n] = 0;
+ } else {
+ unsigned int u;
+ int fldcount = sscanf(stringptrs[n], "0x%02x\n", &u);
+ if (fldcount != 1)
+ return JSON_ERR_MISC;
+ else
+ rtcm3->rtcmtypes.data[n] = (unsigned char)u;
+ }
+ }
+ }
+ return status;
+}
+#endif /* SOCKET_EXPORT_ENABLE */
+
+/* rtcm3_json.c ends here */