Coverage Report

Created: 2025-03-14 06:43

/src/gpsd/gpsd-3.25.1~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
19
{
32
    // initialized to shut up clang
33
19
    double d_cycle = 0.0, d_mincycle = 0.0;
34
35
    // *INDENT-OFF*
36
19
    const struct json_attr_t json_attrs_device[] = {
37
19
        {"class",      t_check,      .dflt.check = "DEVICE"},
38
39
19
        {"path",       t_string,     .addr.string  = dev->path,
40
19
                                        .len = sizeof(dev->path)},
41
        // odd, device->gpsdata.online is sent, but put in dev->activated?
42
19
        {"activated",  t_time,       .addr.ts = &dev->activated,
43
19
                                        .dflt.ts = {0, 0}},
44
19
        {"flags",      t_integer,    .addr.integer = &dev->flags},
45
19
        {"driver",     t_string,     .addr.string  = dev->driver,
46
19
                                        .len = sizeof(dev->driver)},
47
19
        {"sernum",     t_string,     .addr.string  = dev->sernum,
48
19
                                        .len = sizeof(dev->sernum)},
49
19
        {"subtype",    t_string,     .addr.string  = dev->subtype,
50
19
                                        .len = sizeof(dev->subtype)},
51
19
        {"subtype1",   t_string,     .addr.string  = dev->subtype1,
52
19
                                        .len = sizeof(dev->subtype1)},
53
19
        {"hexdata",    t_string,     .addr.string  = dev->hexdata,
54
19
                                        .len = sizeof(dev->hexdata)},
55
19
        {"native",     t_integer,    .addr.integer = &dev->driver_mode,
56
19
                                        .dflt.integer = DEVDEFAULT_NATIVE},
57
19
        {"bps",        t_uinteger,   .addr.uinteger = &dev->baudrate,
58
19
                                        .dflt.uinteger = DEVDEFAULT_BPS},
59
19
        {"parity",     t_character,  .addr.character = &dev->parity,
60
19
                                        .dflt.character = DEVDEFAULT_PARITY},
61
19
        {"stopbits",   t_uinteger,   .addr.uinteger = &dev->stopbits,
62
19
                                        .dflt.uinteger = DEVDEFAULT_STOPBITS},
63
19
        {"cycle",      t_real,       .addr.real = &d_cycle,
64
19
                                        .dflt.real = NAN},
65
19
        {"mincycle",   t_real,       .addr.real = &d_mincycle,
66
19
                                        .dflt.real = NAN},
67
        // ignore unknown keys, for cross-version compatibility
68
19
        {"", t_ignore},
69
19
        {NULL},
70
19
    };
71
    // *INDENT-ON*
72
19
    int status;
73
74
19
    status = json_read_object(buf, json_attrs_device, endptr);
75
19
    if (0 != status) {
76
15
        return status;
77
15
    }
78
79
4
    if (0 == isfinite(d_cycle)) {
80
3
        dev->cycle.tv_sec = 0;
81
3
        dev->cycle.tv_nsec = 0;
82
3
    } else {
83
1
        DTOTS(&dev->cycle, d_cycle);
84
1
    }
85
4
    if (0 == isfinite(d_mincycle)) {
86
3
        dev->mincycle.tv_sec = 0;
87
3
        dev->mincycle.tv_nsec = 0;
88
3
    } else {
89
1
        DTOTS(&dev->mincycle, d_mincycle);
90
1
    }
91
92
4
    return 0;
93
19
}
94
95
int json_watch_read(const char *buf,
96
                    struct gps_policy_t *ccp,
97
                    const char **endptr)
98
52
{
99
    // *INDENT-OFF*
100
52
    struct json_attr_t chanconfig_attrs[] = {
101
52
        {"class",          t_check,    .dflt.check = "WATCH"},
102
103
52
        {"device",         t_string,   .addr.string = ccp->devpath,
104
52
                                          .len = sizeof(ccp->devpath)},
105
52
        {"enable",         t_boolean,  .addr.boolean = &ccp->watcher,
106
52
                                          .dflt.boolean = true},
107
52
        {"json",           t_boolean,  .addr.boolean = &ccp->json,
108
52
                                          .nodefault = true},
109
52
        {"nmea",           t_boolean,  .addr.boolean = &ccp->nmea,
110
52
                                          .nodefault = true},
111
52
        {"pps",            t_boolean,  .addr.boolean = &ccp->pps},
112
52
        {"raw",            t_integer,  .addr.integer = &ccp->raw,
113
52
                                          .nodefault = true},
114
52
        {"remote",         t_string,   .addr.string = ccp->remote,
115
52
                                          .len = sizeof(ccp->remote)},
116
52
        {"scaled",         t_boolean,  .addr.boolean = &ccp->scaled},
117
52
        {"split24",        t_boolean,  .addr.boolean = &ccp->split24},
118
52
        {"timing",         t_boolean,  .addr.boolean = &ccp->timing},
119
        // ignore unknown keys, for cross-version compatibility
120
52
        {"", t_ignore},
121
52
        {NULL},
122
52
    };
123
    // *INDENT-ON*
124
52
    int status;
125
126
52
    status = json_read_object(buf, chanconfig_attrs, endptr);
127
52
    return status;
128
52
}
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