Coverage Report

Created: 2024-02-25 06:36

/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
#ifdef SOCKET_EXPORT_ENABLE
21
#include <math.h>
22
#include <stdbool.h>
23
24
#include "../include/gpsd.h"
25
#include "../include/gps_json.h"
26
#include "../include/strfuncs.h"
27
#include "../include/timespec.h"
28
29
int json_device_read(const char *buf,
30
                     struct devconfig_t *dev,
31
                     const char **endptr)
32
0
{
33
    // initialized to shut up clang
34
0
    double d_cycle = 0.0, d_mincycle = 0.0;
35
36
    // *INDENT-OFF*
37
0
    const struct json_attr_t json_attrs_device[] = {
38
0
        {"class",      t_check,      .dflt.check = "DEVICE"},
39
40
0
        {"path",       t_string,     .addr.string  = dev->path,
41
0
                                        .len = sizeof(dev->path)},
42
        // odd, device->gpsdata.online is sent, but put in dev->activated?
43
0
        {"activated",  t_time,       .addr.ts = &dev->activated,
44
0
                                        .dflt.ts = {0, 0}},
45
0
        {"flags",      t_integer,    .addr.integer = &dev->flags},
46
0
        {"driver",     t_string,     .addr.string  = dev->driver,
47
0
                                        .len = sizeof(dev->driver)},
48
0
        {"sernum",     t_string,     .addr.string  = dev->sernum,
49
0
                                        .len = sizeof(dev->sernum)},
50
0
        {"subtype",    t_string,     .addr.string  = dev->subtype,
51
0
                                        .len = sizeof(dev->subtype)},
52
0
        {"subtype1",   t_string,     .addr.string  = dev->subtype1,
53
0
                                        .len = sizeof(dev->subtype1)},
54
0
        {"hexdata",    t_string,     .addr.string  = dev->hexdata,
55
0
                                        .len = sizeof(dev->hexdata)},
56
0
        {"native",     t_integer,    .addr.integer = &dev->driver_mode,
57
0
                                        .dflt.integer = DEVDEFAULT_NATIVE},
58
0
        {"bps",        t_uinteger,   .addr.uinteger = &dev->baudrate,
59
0
                                        .dflt.uinteger = DEVDEFAULT_BPS},
60
0
        {"parity",     t_character,  .addr.character = &dev->parity,
61
0
                                        .dflt.character = DEVDEFAULT_PARITY},
62
0
        {"stopbits",   t_uinteger,   .addr.uinteger = &dev->stopbits,
63
0
                                        .dflt.uinteger = DEVDEFAULT_STOPBITS},
64
0
        {"cycle",      t_real,       .addr.real = &d_cycle,
65
0
                                        .dflt.real = NAN},
66
0
        {"mincycle",   t_real,       .addr.real = &d_mincycle,
67
0
                                        .dflt.real = NAN},
68
        // ignore unknown keys, for cross-version compatibility
69
0
        {"", t_ignore},
70
0
        {NULL},
71
0
    };
72
    // *INDENT-ON*
73
0
    int status;
74
75
0
    status = json_read_object(buf, json_attrs_device, endptr);
76
0
    if (0 != status) {
77
0
        return status;
78
0
    }
79
80
0
    if (0 == isfinite(d_cycle)) {
81
0
        dev->cycle.tv_sec = 0;
82
0
        dev->cycle.tv_nsec = 0;
83
0
    } else {
84
0
        DTOTS(&dev->cycle, d_cycle);
85
0
    }
86
0
    if (0 == isfinite(d_mincycle)) {
87
0
        dev->mincycle.tv_sec = 0;
88
0
        dev->mincycle.tv_nsec = 0;
89
0
    } else {
90
0
        DTOTS(&dev->mincycle, d_mincycle);
91
0
    }
92
93
0
    return 0;
94
0
}
95
96
int json_watch_read(const char *buf,
97
                    struct gps_policy_t *ccp,
98
                    const char **endptr)
99
0
{
100
    // *INDENT-OFF*
101
0
    struct json_attr_t chanconfig_attrs[] = {
102
0
        {"class",          t_check,    .dflt.check = "WATCH"},
103
104
0
        {"device",         t_string,   .addr.string = ccp->devpath,
105
0
                                          .len = sizeof(ccp->devpath)},
106
0
        {"enable",         t_boolean,  .addr.boolean = &ccp->watcher,
107
0
                                          .dflt.boolean = true},
108
0
        {"json",           t_boolean,  .addr.boolean = &ccp->json,
109
0
                                          .nodefault = true},
110
0
        {"nmea",           t_boolean,  .addr.boolean = &ccp->nmea,
111
0
                                          .nodefault = true},
112
0
        {"pps",            t_boolean,  .addr.boolean = &ccp->pps},
113
0
        {"raw",            t_integer,  .addr.integer = &ccp->raw,
114
0
                                          .nodefault = true},
115
0
        {"remote",         t_string,   .addr.string = ccp->remote,
116
0
                                          .len = sizeof(ccp->remote)},
117
0
        {"scaled",         t_boolean,  .addr.boolean = &ccp->scaled},
118
0
        {"split24",        t_boolean,  .addr.boolean = &ccp->split24},
119
0
        {"timing",         t_boolean,  .addr.boolean = &ccp->timing},
120
        // ignore unknown keys, for cross-version compatibility
121
0
        {"", t_ignore},
122
0
        {NULL},
123
0
    };
124
    // *INDENT-ON*
125
0
    int status;
126
127
0
    status = json_read_object(buf, chanconfig_attrs, endptr);
128
0
    return status;
129
0
}
130
131
/* Translate a gps_policy_t to a WATCH string (outbuf)
132
 * return outbuf
133
 */
134
char *json_policy_to_watch(struct gps_policy_t *ccp,
135
                           char *outbuf, size_t outbuf_len)
136
0
{
137
0
    char *str;
138
139
0
    snprintf(outbuf, outbuf_len, "?WATCH={\"device\":\"%s\"", ccp->devpath);
140
141
0
    str = ccp->watcher ? ",\"enable\":true" : ",\"enable\":false";
142
0
    (void)strlcat(outbuf, str, outbuf_len);
143
144
0
    str = ccp->json ? ",\"json\":true" : ",\"json\":false";
145
0
    (void)strlcat(outbuf, str, outbuf_len);
146
147
0
    str = ccp->nmea ? ",\"nmea\":true" : ",\"nmea\":false";
148
0
    (void)strlcat(outbuf, str, outbuf_len);
149
150
0
    str = ccp->pps ? ",\"pps\":true" : ",\"pps\":false";
151
0
    (void)strlcat(outbuf, str, outbuf_len);
152
153
0
    str_appendf(outbuf, outbuf_len, ",\"raw\":%u", ccp->raw);
154
155
0
    if ('\0' != ccp->remote[0]) {
156
0
        str_appendf(outbuf, outbuf_len, ",\"remote\":%s", ccp->remote);
157
0
    }
158
159
0
    str = ccp->scaled ? ",\"scaled\":true" : ",\"scaled\":false";
160
0
    (void)strlcat(outbuf, str, outbuf_len);
161
162
0
    str = ccp->split24 ? ",\"split24\":true" : ",\"split24\":false";
163
0
    (void)strlcat(outbuf, str, outbuf_len);
164
165
0
    str = ccp->timing ? ",\"timing\":true}\r\n" : ",\"timing\":false}\r\n";
166
0
    (void)strlcat(outbuf, str, outbuf_len);
167
168
0
    return outbuf;
169
0
}
170
171
#endif  // SOCKET_EXPORT_ENABLE
172
173
// vim: set expandtab shiftwidth=4