Coverage Report

Created: 2026-08-13 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gpsd/gpsd-3.27.6~dev/libgps/rtcm3_json.c
Line
Count
Source
1
/****************************************************************************
2
3
NAME
4
   rtcm3_json.c - deserialize RTCM3 JSON
5
6
DESCRIPTION
7
   This module uses the generic JSON parser to get data from RTCM3
8
representations to libgps structures.
9
10
PERMISSIONS
11
   This file is Copyright by the GPSD project
12
   SPDX-License-Identifier: BSD-2-clause
13
14
***************************************************************************/
15
16
#include "../include/gpsd_config.h"  // must be before all includes
17
18
#include <math.h>
19
#include <stddef.h>
20
#include <stdio.h>
21
#include <string.h>
22
23
#include "../include/gpsd.h"
24
#include "../include/gps_json.h"
25
26
int json_rtcm3_read(const char *buf,
27
                    char *path, size_t pathlen, struct rtcm3_t *rtcm3,
28
                    const char **endptr)
29
142
{
30
    // why static??
31
142
    static char *stringptrs[NITEMS(rtcm3->rtcmtypes.data)];
32
142
    static char stringstore[sizeof(rtcm3->rtcmtypes.data) * 2];
33
142
    static unsigned stringcount;
34
35
// *INDENT-OFF*
36
142
#define RTCM3_HEADER \
37
1.42k
        {"class",          t_check,    .dflt.check = "RTCM3"}, \
38
1.42k
        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
39
1.42k
        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
40
1.42k
        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
41
42
142
    int status = 0;
43
142
    unsigned satcount = 0;
44
45
3.69k
#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
46
142
    const struct json_attr_t rtcm1001_satellite[] = {
47
142
        {"ident",     t_uinteger, RTCM3FIELD(1001, ident)},
48
142
        {"ind",       t_uinteger, RTCM3FIELD(1001, L1.indicator)},
49
142
        {"prange",    t_real,     RTCM3FIELD(1001, L1.pseudorange)},
50
142
        {"delta",     t_real,     RTCM3FIELD(1001, L1.rangediff)},
51
142
        {"lockt",     t_uinteger, RTCM3FIELD(1001, L1.locktime)},
52
142
        {NULL},
53
142
    };
54
55
142
    const struct json_attr_t rtcm1002_satellite[] = {
56
142
        {"ident",     t_uinteger, RTCM3FIELD(1002, ident)},
57
142
        {"ind",       t_uinteger, RTCM3FIELD(1002, L1.indicator)},
58
142
        {"prange",    t_real,     RTCM3FIELD(1002, L1.pseudorange)},
59
142
        {"delta",     t_real,     RTCM3FIELD(1002, L1.rangediff)},
60
142
        {"lockt",     t_uinteger, RTCM3FIELD(1002, L1.locktime)},
61
142
        {"amb",       t_uinteger, RTCM3FIELD(1002, L1.ambiguity)},
62
142
        {"CNR",       t_real,     RTCM3FIELD(1002, L1.CNR)},
63
142
        {NULL},
64
142
    };
65
66
142
    const struct json_attr_t rtcm1009_satellite[] = {
67
142
        {"ident",     t_uinteger, RTCM3FIELD(1009, ident)},
68
142
        {"ind",       t_uinteger, RTCM3FIELD(1009, L1.indicator)},
69
142
        {"channel",   t_uinteger, RTCM3FIELD(1009, L1.channel)},
70
142
        {"prange",    t_real,     RTCM3FIELD(1009, L1.pseudorange)},
71
142
        {"delta",     t_real,     RTCM3FIELD(1009, L1.rangediff)},
72
142
        {"lockt",     t_uinteger, RTCM3FIELD(1009, L1.locktime)},
73
142
        {NULL},
74
142
    };
75
76
142
    const struct json_attr_t rtcm1010_satellite[] = {
77
142
        {"ident",     t_uinteger, RTCM3FIELD(1010, ident)},
78
142
        {"ind",       t_uinteger, RTCM3FIELD(1010, L1.indicator)},
79
142
        {"channel",   t_uinteger, RTCM3FIELD(1010, L1.channel)},
80
142
        {"prange",    t_real,     RTCM3FIELD(1010, L1.pseudorange)},
81
142
        {"delta",     t_real,     RTCM3FIELD(1010, L1.rangediff)},
82
142
        {"lockt",     t_uinteger, RTCM3FIELD(1010, L1.locktime)},
83
142
        {"amb",       t_uinteger, RTCM3FIELD(1010, L1.ambiguity)},
84
142
        {"CNR",       t_real,     RTCM3FIELD(1010, L1.CNR)},
85
142
        {NULL},
86
142
    };
87
142
#undef RTCM3FIELD
88
89
710
#define R1001   &rtcm3->rtcmtypes.rtcm3_1001.header
90
142
    const struct json_attr_t json_rtcm1001[] = {
91
142
        RTCM3_HEADER
92
142
        {"station_id", t_uinteger, .addr.uinteger = R1001.station_id},
93
142
        {"tow",        t_uinteger, .addr.uinteger = (unsigned int *)R1001.tow},
94
142
        {"sync",       t_boolean,  .addr.boolean = R1001.sync},
95
142
        {"smoothing",  t_boolean,  .addr.boolean = R1001.smoothing},
96
142
        {"interval",   t_uinteger, .addr.uinteger = R1001.interval},
97
142
        {"satellites", t_array,
98
142
         STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1001.rtk_data,
99
142
         rtcm1001_satellite, &satcount)},
100
142
        {NULL},
101
142
    };
102
142
#undef R1001
103
104
710
#define R1002   &rtcm3->rtcmtypes.rtcm3_1002.header
105
142
    const struct json_attr_t json_rtcm1002[] = {
106
142
        RTCM3_HEADER
107
142
        {"station_id", t_uinteger, .addr.uinteger = R1002.station_id},
108
142
        {"tow",        t_uinteger, .addr.uinteger = (unsigned int *)R1002.tow},
109
142
        {"sync",       t_boolean,  .addr.boolean = R1002.sync},
110
142
        {"smoothing",  t_boolean,  .addr.boolean = R1002.smoothing},
111
142
        {"interval",   t_uinteger, .addr.uinteger = R1002.interval},
112
142
        {"satellites", t_array,
113
142
         STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1002.rtk_data,
114
142
         rtcm1002_satellite, &satcount)},
115
142
        {NULL},
116
142
    };
117
142
#undef R1002
118
119
568
#define R1007   rtcm3->rtcmtypes.rtcm3_1007
120
142
    const struct json_attr_t json_rtcm1007[] = {
121
142
        RTCM3_HEADER
122
142
        {"station_id", t_uinteger, .addr.uinteger = &R1007.station_id},
123
142
        {"desc",       t_string,   .addr.string = R1007.descriptor,
124
142
                                         .len = sizeof(R1007.descriptor)},
125
142
        {"setup_id",   t_uinteger, .addr.uinteger = &R1007.setup_id},
126
142
        {NULL},
127
142
    };
128
142
#undef R1002
129
130
852
#define R1008   rtcm3->rtcmtypes.rtcm3_1008
131
142
    const struct json_attr_t json_rtcm1008[] = {
132
142
        RTCM3_HEADER
133
142
        {"station_id", t_uinteger, .addr.uinteger = &R1008.station_id},
134
142
        {"desc",       t_string,   .addr.string = R1008.descriptor,
135
142
                                         .len = sizeof(R1008.descriptor)},
136
142
        {"setup_id",   t_uinteger, .addr.uinteger = &R1008.setup_id},
137
142
        {"serial",     t_string,   .addr.string = R1008.serial,
138
142
                                         .len = sizeof(R1008.serial)},
139
142
        {NULL},
140
142
    };
141
142
#undef R1008
142
143
710
#define R1009   &rtcm3->rtcmtypes.rtcm3_1009.header
144
142
    const struct json_attr_t json_rtcm1009[] = {
145
142
        RTCM3_HEADER
146
142
        {"station_id", t_uinteger, .addr.uinteger = R1009.station_id},
147
142
        {"tow",        t_uinteger, .addr.uinteger = (unsigned int *)R1009.tow},
148
142
        {"sync",       t_boolean,  .addr.boolean = R1009.sync},
149
142
        {"smoothing",  t_boolean,  .addr.boolean = R1009.smoothing},
150
142
        {"interval",   t_uinteger, .addr.uinteger = R1009.interval},
151
142
        {"satellites", t_array,
152
142
         STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1009.rtk_data,
153
142
         rtcm1009_satellite, &satcount)},
154
142
        {NULL},
155
142
    };
156
142
#undef R1010
157
158
710
#define R1010   &rtcm3->rtcmtypes.rtcm3_1010.header
159
142
    const struct json_attr_t json_rtcm1010[] = {
160
142
        RTCM3_HEADER
161
142
        {"station_id", t_uinteger, .addr.uinteger = R1010.station_id},
162
142
        {"tow",        t_uinteger, .addr.uinteger = (unsigned int *)R1010.tow},
163
142
        {"sync",       t_boolean,  .addr.boolean = R1010.sync},
164
142
        {"smoothing",  t_boolean,  .addr.boolean = R1010.smoothing},
165
142
        {"interval",   t_uinteger, .addr.uinteger = R1010.interval},
166
142
        {"satellites", t_array,
167
142
         STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1010.rtk_data,
168
142
         rtcm1010_satellite, &satcount)},
169
142
        {NULL},
170
142
    };
171
142
#undef R1010
172
173
1.13k
#define R1014   &rtcm3->rtcmtypes.rtcm3_1014
174
142
    const struct json_attr_t json_rtcm1014[] = {
175
142
        RTCM3_HEADER
176
142
        {"netid",      t_uinteger, .addr.uinteger = R1014.network_id},
177
142
        {"subnetid",   t_uinteger, .addr.uinteger = R1014.subnetwork_id},
178
142
        {"statcount",  t_uinteger, .addr.uinteger = R1014.stationcount},
179
142
        {"master",     t_uinteger, .addr.uinteger = R1014.master_id},
180
142
        {"aux",        t_uinteger, .addr.uinteger = R1014.aux_id},
181
142
        {"lat",        t_real,     .addr.real = R1014.d_lat},
182
142
        {"lon",        t_real,     .addr.real = R1014.d_lon},
183
142
        {"alt",        t_real,     .addr.real = R1014.d_alt},
184
142
        {NULL},
185
142
    };
186
142
#undef R1014
187
188
1.42k
#define R1033   rtcm3->rtcmtypes.rtcm3_1033
189
142
    const struct json_attr_t json_rtcm1033[] = {
190
142
        RTCM3_HEADER
191
142
        {"station_id", t_uinteger, .addr.uinteger = &R1033.station_id},
192
142
        {"desc",       t_string,   .addr.string = R1033.descriptor,
193
142
                                         .len = sizeof(R1033.descriptor)},
194
142
        {"setup_id",   t_uinteger, .addr.uinteger = &R1033.setup_id},
195
142
        {"serial",     t_string,   .addr.string = R1033.serial,
196
142
                                         .len = sizeof(R1033.serial)},
197
142
        {"receiver",   t_string,   .addr.string = R1033.receiver,
198
142
                                         .len = sizeof(R1033.receiver)},
199
142
        {"firmware",   t_string,   .addr.string = R1033.firmware,
200
142
                                         .len = sizeof(R1033.firmware)},
201
142
        {NULL},
202
142
    };
203
142
#undef R1033
204
205
994
#define R1230   rtcm3->rtcmtypes.rtcm3_1230
206
142
    const struct json_attr_t json_rtcm1230[] = {
207
142
        RTCM3_HEADER
208
142
        {"station_id", t_uinteger, .addr.uinteger = &R1230.station_id},
209
142
        {"ind",        t_ubyte,    .addr.ubyte = &R1230.bias_indicator},
210
142
        {"sm",         t_ubyte,    .addr.ubyte = &R1230.signals_mask},
211
142
        {"l1_ca",      t_integer,  .addr.integer = &R1230.l1_ca_bias,
212
142
                                   .dflt.integer = 0},
213
142
        {"l1p",        t_integer,  .addr.integer = &R1230.l1_p_bias,
214
142
                                   .dflt.integer = 0},
215
142
        {"l2ca",       t_integer,  .addr.integer = &R1230.l2_ca_bias,
216
142
                                   .dflt.integer = 0},
217
142
        {"l2p",        t_integer,  .addr.integer = &R1230.l2_p_bias,
218
142
                                   .dflt.integer = 0},
219
142
        {NULL},
220
142
    };
221
142
#undef R1033
222
223
142
    const struct json_attr_t json_rtcm3_fallback[] = {
224
142
        RTCM3_HEADER
225
142
        {"data", t_array, .addr.array.element_type = t_string,
226
142
                          .addr.array.arr.strings.ptrs = stringptrs,
227
142
                          .addr.array.arr.strings.store = stringstore,
228
142
                         .addr.array.arr.strings.storelen = sizeof(stringstore),
229
142
                          .addr.array.count = &stringcount,
230
142
                          .addr.array.maxlen = NITEMS(stringptrs)},
231
        // ignore unknown keys
232
142
        {"", t_ignore},
233
234
142
        {NULL},
235
142
    };
236
237
142
#undef RTCM3_HEADER
238
// *INDENT-ON*
239
240
142
    memset(rtcm3, '\0', sizeof(struct rtcm3_t));
241
242
142
    if (strstr(buf, "\"type\":1001,") != NULL) {
243
5
        status = json_read_object(buf, json_rtcm1001, endptr);
244
5
        if (0 == status) {
245
1
            rtcm3->rtcmtypes.rtcm3_1001.header.satcount =
246
1
                (unsigned short)satcount;
247
1
        }
248
137
    } else if (NULL != strstr(buf, "\"type\":1002,")) {
249
6
        status = json_read_object(buf, json_rtcm1002, endptr);
250
6
        if (0 == status) {
251
1
            rtcm3->rtcmtypes.rtcm3_1002.header.satcount =
252
1
               (unsigned short)satcount;
253
1
        }
254
131
    } else if (NULL != strstr(buf, "\"type\":1007,")) {
255
2
        status = json_read_object(buf, json_rtcm1007, endptr);
256
129
    } else if (NULL != strstr(buf, "\"type\":1008,")) {
257
1
        status = json_read_object(buf, json_rtcm1008, endptr);
258
128
    } else if (NULL != strstr(buf, "\"type\":1009,")) {
259
1
        status = json_read_object(buf, json_rtcm1009, endptr);
260
127
    } else if (NULL != strstr(buf, "\"type\":1010,")) {
261
1
        status = json_read_object(buf, json_rtcm1010, endptr);
262
126
    } else if (NULL != strstr(buf, "\"type\":1014,")) {
263
1
        status = json_read_object(buf, json_rtcm1014, endptr);
264
125
    } else if (NULL != strstr(buf, "\"type\":1033,")) {
265
1
        status = json_read_object(buf, json_rtcm1033, endptr);
266
124
    } else if (NULL != strstr(buf, "\"type\":1230,")) {
267
22
        status = json_read_object(buf, json_rtcm1230, endptr);
268
102
    } else {
269
        // a type we don't decode yet, grabe just the header.
270
102
        unsigned n;
271
102
        status = json_read_object(buf, json_rtcm3_fallback, endptr);
272
70.8k
        for (n = 0; n < NITEMS(rtcm3->rtcmtypes.data); n++) {
273
70.7k
            if (n >= stringcount) {
274
69.0k
                rtcm3->rtcmtypes.data[n] = '\0';
275
69.0k
            } else {
276
1.73k
                unsigned int u;
277
1.73k
                int fldcount = sscanf(stringptrs[n], "0x%02x\n", &u);
278
1.73k
                if (fldcount != 1) {
279
33
                    return JSON_ERR_MISC;
280
33
                } // else
281
1.70k
                rtcm3->rtcmtypes.data[n] = (char)u;
282
1.70k
            }
283
70.7k
        }
284
102
    }
285
109
    return status;
286
142
}
287
288
// rtcm3_json.c ends here
289
// vim: set expandtab shiftwidth=4