diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2009-08-18 04:36:31 +0000 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2009-08-18 04:36:31 +0000 |
commit | 2b221b92cecbabcc39ef6d932ebd979e221b3251 (patch) | |
tree | 853e8876c01cc3adbe2bbcf920246ea5626357fa /gpsd_json.c | |
parent | e73b127df2fa7d22f21302ecb83dd901e37d3b6c (diff) | |
download | gpsd-2b221b92cecbabcc39ef6d932ebd979e221b3251.tar.gz |
Major step towards GPSD-NG support in the client library.
Diffstat (limited to 'gpsd_json.c')
-rw-r--r-- | gpsd_json.c | 229 |
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 */ |