Coverage Report

Created: 2025-08-26 06:29

/src/gpsd/gpsd-3.26.2~dev/libgps/shared_json.c
Line
Count
Source (jump to first uncovered line)
1
/****************************************************************************
2
3
NAME
4
   shared_json.c - move data between in-core and JSON structures
5
6
DESCRIPTION
7
   This module uses the generic JSON parser to get data from JSON
8
representations to gps.h structures. These functions are used in both
9
the daemon and the client library.
10
11
PERMISSIONS
12
  Written by Eric S. Raymond, 2009
13
  This file is Copyright 2009 The GPSD project
14
  SPDX-License-Identifier: BSD-2-clause
15
16
***************************************************************************/
17
18
#include "../include/gpsd_config.h"  // must be before all includes
19
20
#include <math.h>
21
#include <stdbool.h>
22
23
#include "../include/gpsd.h"
24
#include "../include/gps_json.h"
25
#include "../include/strfuncs.h"
26
#include "../include/timespec.h"
27
28
int json_device_read(const char *buf,
29
                     struct devconfig_t *dev,
30
                     const char **endptr)
31
14
{
32
    // initialized to shut up clang
33
14
    double d_cycle = 0.0, d_mincycle = 0.0;
34
35
    // *INDENT-OFF*
36
14
    const struct json_attr_t json_attrs_device[] = {
37
14
        {"class",      t_check,      .dflt.check = "DEVICE"},
38
39
14
        {"path",       t_string,     .addr.string  = dev->path,
40
14
                                        .len = sizeof(dev->path)},
41
        // odd, device->gpsdata.online is sent, but put in dev->activated?
42
14
        {"activated",  t_time,       .addr.ts = &dev->activated,
43
14
                                        .dflt.ts = {0, 0}},
44
14
        {"flags",      t_integer,    .addr.integer = &dev->flags},
45
14
        {"driver",     t_string,     .addr.string  = dev->driver,
46
14
                                        .len = sizeof(dev->driver)},
47
14
        {"sernum",     t_string,     .addr.string  = dev->sernum,
48
14
                                        .len = sizeof(dev->sernum)},
49
14
        {"subtype",    t_string,     .addr.string  = dev->subtype,
50
14
                                        .len = sizeof(dev->subtype)},
51
14
        {"subtype1",   t_string,     .addr.string  = dev->subtype1,
52
14
                                        .len = sizeof(dev->subtype1)},
53
14
        {"hexdata",    t_string,     .addr.string  = dev->hexdata,
54
14
                                        .len = sizeof(dev->hexdata)},
55
14
        {"native",     t_integer,    .addr.integer = &dev->driver_mode,
56
14
                                        .dflt.integer = DEVDEFAULT_NATIVE},
57
14
        {"bps",        t_uinteger,   .addr.uinteger = &dev->baudrate,
58
14
                                        .dflt.uinteger = DEVDEFAULT_BPS},
59
14
        {"parity",     t_character,  .addr.character = &dev->parity,
60
14
                                        .dflt.character = DEVDEFAULT_PARITY},
61
14
        {"stopbits",   t_uinteger,   .addr.uinteger = &dev->stopbits,
62
14
                                        .dflt.uinteger = DEVDEFAULT_STOPBITS},
63
14
        {"cycle",      t_real,       .addr.real = &d_cycle,
64
14
                                        .dflt.real = NAN},
65
14
        {"mincycle",   t_real,       .addr.real = &d_mincycle,
66
14
                                        .dflt.real = NAN},
67
        // ignore unknown keys, for cross-version compatibility
68
14
        {"", t_ignore},
69
14
        {NULL},
70
14
    };
71
    // *INDENT-ON*
72
14
    int status;
73
74
14
    status = json_read_object(buf, json_attrs_device, endptr);
75
14
    if (0 != status) {
76
11
        return status;
77
11
    }
78
79
3
    if (0 == isfinite(d_cycle)) {
80
2
        dev->cycle.tv_sec = 0;
81
2
        dev->cycle.tv_nsec = 0;
82
2
    } else {
83
1
        DTOTS(&dev->cycle, d_cycle);
84
1
    }
85
3
    if (0 == isfinite(d_mincycle)) {
86
2
        dev->mincycle.tv_sec = 0;
87
2
        dev->mincycle.tv_nsec = 0;
88
2
    } else {
89
1
        DTOTS(&dev->mincycle, d_mincycle);
90
1
    }
91
92
3
    return 0;
93
14
}
94
95
int json_watch_read(const char *buf,
96
                    struct gps_policy_t *ccp,
97
                    const char **endptr)
98
56
{
99
    // *INDENT-OFF*
100
56
    struct json_attr_t chanconfig_attrs[] = {
101
56
        {"class",          t_check,    .dflt.check = "WATCH"},
102
103
56
        {"device",         t_string,   .addr.string = ccp->devpath,
104
56
                                          .len = sizeof(ccp->devpath)},
105
56
        {"enable",         t_boolean,  .addr.boolean = &ccp->watcher,
106
56
                                          .dflt.boolean = true},
107
56
        {"json",           t_boolean,  .addr.boolean = &ccp->json,
108
56
                                          .nodefault = true},
109
56
        {"nmea",           t_boolean,  .addr.boolean = &ccp->nmea,
110
56
                                          .nodefault = true},
111
56
        {"pps",            t_boolean,  .addr.boolean = &ccp->pps},
112
56
        {"raw",            t_integer,  .addr.integer = &ccp->raw,
113
56
                                          .nodefault = true},
114
56
        {"remote",         t_string,   .addr.string = ccp->remote,
115
56
                                          .len = sizeof(ccp->remote)},
116
56
        {"scaled",         t_boolean,  .addr.boolean = &ccp->scaled},
117
56
        {"split24",        t_boolean,  .addr.boolean = &ccp->split24},
118
56
        {"timing",         t_boolean,  .addr.boolean = &ccp->timing},
119
        // ignore unknown keys, for cross-version compatibility
120
56
        {"", t_ignore},
121
56
        {NULL},
122
56
    };
123
    // *INDENT-ON*
124
56
    int status;
125
126
56
    status = json_read_object(buf, chanconfig_attrs, endptr);
127
56
    return status;
128
56
}
129
130
/* Translate a gps_policy_t to a WATCH string (outbuf)
131
 * return outbuf
132
 */
133
char *json_policy_to_watch(struct gps_policy_t *ccp,
134
                           char *outbuf, size_t outbuf_len)
135
0
{
136
0
    char *str;
137
138
0
    snprintf(outbuf, outbuf_len, "?WATCH={\"device\":\"%s\"", ccp->devpath);
139
140
0
    str = ccp->watcher ? ",\"enable\":true" : ",\"enable\":false";
141
0
    (void)strlcat(outbuf, str, outbuf_len);
142
143
0
    str = ccp->json ? ",\"json\":true" : ",\"json\":false";
144
0
    (void)strlcat(outbuf, str, outbuf_len);
145
146
0
    str = ccp->nmea ? ",\"nmea\":true" : ",\"nmea\":false";
147
0
    (void)strlcat(outbuf, str, outbuf_len);
148
149
0
    str = ccp->pps ? ",\"pps\":true" : ",\"pps\":false";
150
0
    (void)strlcat(outbuf, str, outbuf_len);
151
152
0
    str_appendf(outbuf, outbuf_len, ",\"raw\":%u", ccp->raw);
153
154
0
    if ('\0' != ccp->remote[0]) {
155
0
        str_appendf(outbuf, outbuf_len, ",\"remote\":%s", ccp->remote);
156
0
    }
157
158
0
    str = ccp->scaled ? ",\"scaled\":true" : ",\"scaled\":false";
159
0
    (void)strlcat(outbuf, str, outbuf_len);
160
161
0
    str = ccp->split24 ? ",\"split24\":true" : ",\"split24\":false";
162
0
    (void)strlcat(outbuf, str, outbuf_len);
163
164
0
    str = ccp->timing ? ",\"timing\":true}\r\n" : ",\"timing\":false}\r\n";
165
0
    (void)strlcat(outbuf, str, outbuf_len);
166
167
0
    return outbuf;
168
0
}
169
170
// vim: set expandtab shiftwidth=4