summaryrefslogtreecommitdiff
path: root/gpsd_json.c
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2009-08-18 04:36:31 +0000
committerEric S. Raymond <esr@thyrsus.com>2009-08-18 04:36:31 +0000
commit2b221b92cecbabcc39ef6d932ebd979e221b3251 (patch)
tree853e8876c01cc3adbe2bbcf920246ea5626357fa /gpsd_json.c
parente73b127df2fa7d22f21302ecb83dd901e37d3b6c (diff)
downloadgpsd-2b221b92cecbabcc39ef6d932ebd979e221b3251.tar.gz
Major step towards GPSD-NG support in the client library.
Diffstat (limited to 'gpsd_json.c')
-rw-r--r--gpsd_json.c229
1 files changed, 229 insertions, 0 deletions
diff --git a/gpsd_json.c b/gpsd_json.c
new file mode 100644
index 00000000..aa99786d
--- /dev/null
+++ b/gpsd_json.c
@@ -0,0 +1,229 @@
+/****************************************************************************
+
+NAME
+ gpsd_json.c - move data between in-core and JSON structures
+
+DESCRIPTION
+ This module uses the generic JSON parser to get data from JSON
+representations to gpsd core strctures, and vice_versa.
+
+***************************************************************************/
+
+#include <math.h>
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "gpsd_config.h"
+#include "gpsd.h"
+#include "gps_json.h"
+
+void json_tpv_dump(struct gps_data_t *gpsdata, struct gps_fix_t *fixp,
+ char *reply, size_t replylen)
+{
+ assert(replylen > 2);
+ (void)strlcpy(reply, "{\"class\":\"TPV\",", replylen);
+ (void)snprintf(reply+strlen(reply),
+ replylen-strlen(reply),
+ "\"tag\":\"%s\",",
+ gpsdata->tag[0]!='\0' ? gpsdata->tag : "-");
+ (void)snprintf(reply+strlen(reply),
+ replylen-strlen(reply),
+ "\"device\":\"%s\",",
+ gpsdata->gps_device);
+ if (isnan(fixp->time)==0)
+ (void)snprintf(reply+strlen(reply),
+ replylen-strlen(reply),
+ "\"time\":%.3f,",
+ fixp->time);
+ if (isnan(fixp->ept)==0)
+ (void)snprintf(reply+strlen(reply),
+ replylen-strlen(reply),
+ "\"ept\":%.3f,",
+ fixp->ept);
+ if (isnan(fixp->latitude)==0)
+ (void)snprintf(reply+strlen(reply),
+ replylen-strlen(reply),
+ "\"lat\":%.9f,",
+ fixp->latitude);
+ if (isnan(fixp->longitude)==0)
+ (void)snprintf(reply+strlen(reply),
+ replylen-strlen(reply),
+ "\"lon\":%.9f,",
+ fixp->longitude);
+ if (isnan(fixp->altitude)==0)
+ (void)snprintf(reply+strlen(reply),
+ replylen-strlen(reply),
+ "\"alt\":%.3f,",
+ fixp->altitude);
+ if (isnan(fixp->eph)==0)
+ (void)snprintf(reply+strlen(reply),
+ replylen-strlen(reply),
+ "\"eph\":%.3f,",
+ fixp->eph);
+ if (isnan(fixp->epv)==0)
+ (void)snprintf(reply+strlen(reply),
+ replylen-strlen(reply),
+ "\"epv\":%.3f,",
+ fixp->epv);
+ if (isnan(fixp->track)==0)
+ (void)snprintf(reply+strlen(reply),
+ replylen-strlen(reply),
+ "\"track\":%.4f,",
+ fixp->track);
+ if (isnan(fixp->speed)==0)
+ (void)snprintf(reply+strlen(reply),
+ replylen-strlen(reply),
+ "\"speed\":%.3f,",
+ fixp->speed);
+ if (isnan(fixp->climb)==0)
+ (void)snprintf(reply+strlen(reply),
+ replylen-strlen(reply),
+ "\"climb\":%.3f,",
+ fixp->climb);
+ if (isnan(fixp->epd)==0)
+ (void)snprintf(reply+strlen(reply),
+ replylen-strlen(reply),
+ "\"epd\":%.4f,",
+ fixp->epd);
+ if (isnan(fixp->eps)==0)
+ (void)snprintf(reply+strlen(reply),
+ replylen-strlen(reply),
+ "\"eps\":%.2f,", fixp->eps);
+ if (isnan(fixp->epc)==0)
+ (void)snprintf(reply+strlen(reply),
+ replylen-strlen(reply),
+ "\"epc\":%.2f,", fixp->epc);
+ if (fixp->mode > 0)
+ (void)snprintf(reply+strlen(reply),
+ replylen-strlen(reply),
+ "\"mode\":%d,", fixp->mode);
+ if (reply[strlen(reply)-1] == ',')
+ reply[strlen(reply)-1] = '\0'; /* trim trailing comma */
+ (void)strlcat(reply, "}", sizeof(reply)-strlen(reply));
+}
+
+void json_sky_dump(struct gps_data_t *datap, char *reply, size_t replylen)
+{
+ int i, j, used, reported = 0;
+ assert(replylen > 2);
+ (void)strlcpy(reply, "{\"class\":\"SKY\",", replylen);
+ (void)snprintf(reply+strlen(reply),
+ replylen- strlen(reply),
+ "\"tag\":\"%s\",",
+ datap->tag[0]!='\0' ? datap->tag : "-");
+ (void)snprintf(reply+strlen(reply),
+ replylen-strlen(reply),
+ "\"device\":\"%s\",",
+ datap->gps_device);
+ if (isnan(datap->sentence_time)==0)
+ (void)snprintf(reply+strlen(reply),
+ replylen-strlen(reply),
+ "\"time\":%.3f ",
+ datap->sentence_time);
+ /* insurance against flaky drivers */
+ for (i = 0; i < datap->satellites; i++)
+ if (datap->PRN[i])
+ reported++;
+ (void)snprintf(reply+strlen(reply),
+ replylen-strlen(reply),
+ "\"reported\":%d,", reported);
+ if (reported) {
+ (void)strlcat(reply, "\"satellites\":[", replylen);
+ for (i = 0; i < reported; i++) {
+ used = 0;
+ for (j = 0; j < datap->satellites_used; j++)
+ if (datap->used[j] == datap->PRN[i]) {
+ used = 1;
+ break;
+ }
+ if (datap->PRN[i]) {
+ (void)snprintf(reply+strlen(reply),
+ replylen-strlen(reply),
+ "{\"PRN\":%d,\"el\":%d,\"az\":%d,\"ss\":%.0f,\"used\":%s},",
+ datap->PRN[i],
+ datap->elevation[i],datap->azimuth[i],
+ datap->ss[i],
+ used ? "true" : "false");
+ }
+ }
+ reply[strlen(reply)-1] = '\0'; /* trim trailing comma */
+ (void)strlcat(reply, "]", replylen-strlen(reply));
+ }
+ (void)strlcat(reply, "}", replylen-strlen(reply));
+ if (datap->satellites != reported)
+ gpsd_report(LOG_WARN,"Satellite count %d != PRN count %d\n",
+ datap->satellites, reported);
+}
+
+int json_watch_read(struct policy_t *ccp,
+ const char *buf, const char **endptr)
+{
+ int intcasoc;
+ struct json_attr_t chanconfig_attrs[] = {
+ {"raw", integer, .addr.integer = &ccp->raw,
+ .dflt.integer = -1},
+ {"buffer_policy", integer, .addr.integer = &intcasoc,
+ .dflt.integer = -1},
+ {"scaled", boolean, .addr.boolean = &ccp->scaled},
+ {NULL},
+ };
+ int status;
+
+ status = json_read_object(buf, chanconfig_attrs, 0, endptr);
+ if (status == 0) {
+ if (intcasoc != -1)
+ ccp->buffer_policy = intcasoc;
+ }
+ return status;
+}
+
+void json_watch_dump(struct policy_t *ccp, char *reply, size_t replylen)
+{
+ (void)snprintf(reply+strlen(reply), replylen-strlen(reply),
+ "{\"class\":\"WATCH\",\"raw\":%d,\"buffer_policy\":%d,\"scaled\":%s}",
+ ccp->raw,
+ ccp->buffer_policy,
+ ccp->scaled ? "true" : "false");
+}
+
+int json_configdev_read(struct devconfig_t *cdp, const char *buf, const char **endptr)
+{
+ struct json_attr_t devconfig_attrs[] = {
+ {"device", string, .addr.string.ptr=cdp->device,
+ .addr.string.len=sizeof(cdp->device)},
+ {"native", integer, .addr.integer = &cdp->native,
+ .dflt.integer = -1},
+ {"bps", integer, .addr.integer = &cdp->bps,
+ .dflt.integer = -1},
+ {"serialmode", string, .addr.string.ptr=cdp->serialmode,
+ .addr.string.len=sizeof(cdp->serialmode)},
+ {"cycle", real, .addr.real = &cdp->cycle,
+ .dflt.real = NAN},
+ {"mincycle", real, .addr.real = &cdp->mincycle,
+ .dflt.real = NAN},
+ {NULL},
+ };
+
+ return json_read_object(buf, devconfig_attrs, 0, endptr);
+}
+
+void json_configdev_dump(struct gps_device_t *devp, char *reply, size_t replylen)
+{
+ (void)snprintf(reply, replylen,
+ "{\"class\":\"CONFIGDEV\",\"device\":\"%s\",\"native\":%d,\"bps\":%d,\"serialmode\":\"%u%c%u\",\"cycle\":%2.2f",
+ devp->gpsdata.gps_device,
+ devp->gpsdata.driver_mode,
+ (int)gpsd_get_speed(&devp->ttyset),
+ 9 - devp->gpsdata.stopbits,
+ (int)devp->gpsdata.parity,
+ devp->gpsdata.stopbits,
+ devp->gpsdata.cycle);
+ if (devp->device_type->rate_switcher != NULL)
+ (void)snprintf(reply+strlen(reply), replylen-strlen(reply),
+ ",\"mincycle\":%2.2f",
+ devp->device_type->min_cycle);
+ (void)strlcat(reply, "}", replylen);
+}
+
+/* gpsd_json.c ends here */