Coverage Report

Created: 2025-11-09 06:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gpsd/gpsd-3.26.2~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
120
{
30
120
    static char *stringptrs[NITEMS(rtcm3->rtcmtypes.data)];
31
120
    static char stringstore[sizeof(rtcm3->rtcmtypes.data) * 2];
32
120
    static int stringcount;
33
34
// *INDENT-OFF*
35
120
#define RTCM3_HEADER \
36
1.20k
        {"class",          t_check,    .dflt.check = "RTCM3"}, \
37
1.20k
        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
38
1.20k
        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
39
1.20k
        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
40
41
120
    int status = 0, satcount = 0;
42
43
3.12k
#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
44
120
    const struct json_attr_t rtcm1001_satellite[] = {
45
120
        {"ident",     t_uinteger, RTCM3FIELD(1001, ident)},
46
120
        {"ind",       t_uinteger, RTCM3FIELD(1001, L1.indicator)},
47
120
        {"prange",    t_real,     RTCM3FIELD(1001, L1.pseudorange)},
48
120
        {"delta",     t_real,     RTCM3FIELD(1001, L1.rangediff)},
49
120
        {"lockt",     t_uinteger, RTCM3FIELD(1001, L1.locktime)},
50
120
        {NULL},
51
120
    };
52
53
120
    const struct json_attr_t rtcm1002_satellite[] = {
54
120
        {"ident",     t_uinteger, RTCM3FIELD(1002, ident)},
55
120
        {"ind",       t_uinteger, RTCM3FIELD(1002, L1.indicator)},
56
120
        {"prange",    t_real,     RTCM3FIELD(1002, L1.pseudorange)},
57
120
        {"delta",     t_real,     RTCM3FIELD(1002, L1.rangediff)},
58
120
        {"lockt",     t_uinteger, RTCM3FIELD(1002, L1.locktime)},
59
120
        {"amb",       t_uinteger, RTCM3FIELD(1002, L1.ambiguity)},
60
120
        {"CNR",       t_real,     RTCM3FIELD(1002, L1.CNR)},
61
120
        {NULL},
62
120
    };
63
64
120
    const struct json_attr_t rtcm1009_satellite[] = {
65
120
        {"ident",     t_uinteger, RTCM3FIELD(1009, ident)},
66
120
        {"ind",       t_uinteger, RTCM3FIELD(1009, L1.indicator)},
67
120
        {"channel",   t_uinteger, RTCM3FIELD(1009, L1.channel)},
68
120
        {"prange",    t_real,     RTCM3FIELD(1009, L1.pseudorange)},
69
120
        {"delta",     t_real,     RTCM3FIELD(1009, L1.rangediff)},
70
120
        {"lockt",     t_uinteger, RTCM3FIELD(1009, L1.locktime)},
71
120
        {NULL},
72
120
    };
73
74
120
    const struct json_attr_t rtcm1010_satellite[] = {
75
120
        {"ident",     t_uinteger, RTCM3FIELD(1010, ident)},
76
120
        {"ind",       t_uinteger, RTCM3FIELD(1010, L1.indicator)},
77
120
        {"channel",   t_uinteger, RTCM3FIELD(1010, L1.channel)},
78
120
        {"prange",    t_real,     RTCM3FIELD(1010, L1.pseudorange)},
79
120
        {"delta",     t_real,     RTCM3FIELD(1010, L1.rangediff)},
80
120
        {"lockt",     t_uinteger, RTCM3FIELD(1010, L1.locktime)},
81
120
        {"amb",       t_uinteger, RTCM3FIELD(1010, L1.ambiguity)},
82
120
        {"CNR",       t_real,     RTCM3FIELD(1010, L1.CNR)},
83
120
        {NULL},
84
120
    };
85
120
#undef RTCM3FIELD
86
87
600
#define R1001   &rtcm3->rtcmtypes.rtcm3_1001.header
88
120
    const struct json_attr_t json_rtcm1001[] = {
89
120
        RTCM3_HEADER
90
120
        {"station_id", t_uinteger, .addr.uinteger = R1001.station_id},
91
120
        {"tow",        t_uinteger, .addr.uinteger = (unsigned int *)R1001.tow},
92
120
        {"sync",       t_boolean,  .addr.boolean = R1001.sync},
93
120
        {"smoothing",  t_boolean,  .addr.boolean = R1001.smoothing},
94
120
        {"interval",   t_uinteger, .addr.uinteger = R1001.interval},
95
120
        {"satellites", t_array,
96
120
         STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1001.rtk_data,
97
120
         rtcm1001_satellite, &satcount)},
98
120
        {NULL},
99
120
    };
100
120
#undef R1001
101
102
600
#define R1002   &rtcm3->rtcmtypes.rtcm3_1002.header
103
120
    const struct json_attr_t json_rtcm1002[] = {
104
120
        RTCM3_HEADER
105
120
        {"station_id", t_uinteger, .addr.uinteger = R1002.station_id},
106
120
        {"tow",        t_uinteger, .addr.uinteger = (unsigned int *)R1002.tow},
107
120
        {"sync",       t_boolean,  .addr.boolean = R1002.sync},
108
120
        {"smoothing",  t_boolean,  .addr.boolean = R1002.smoothing},
109
120
        {"interval",   t_uinteger, .addr.uinteger = R1002.interval},
110
120
        {"satellites", t_array,
111
120
         STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1002.rtk_data,
112
120
         rtcm1002_satellite, &satcount)},
113
120
        {NULL},
114
120
    };
115
120
#undef R1002
116
117
480
#define R1007   rtcm3->rtcmtypes.rtcm3_1007
118
120
    const struct json_attr_t json_rtcm1007[] = {
119
120
        RTCM3_HEADER
120
120
        {"station_id", t_uinteger, .addr.uinteger = &R1007.station_id},
121
120
        {"desc",       t_string,   .addr.string = R1007.descriptor,
122
120
                                         .len = sizeof(R1007.descriptor)},
123
120
        {"setup_id",   t_uinteger, .addr.uinteger = &R1007.setup_id},
124
120
        {NULL},
125
120
    };
126
120
#undef R1002
127
128
720
#define R1008   rtcm3->rtcmtypes.rtcm3_1008
129
120
    const struct json_attr_t json_rtcm1008[] = {
130
120
        RTCM3_HEADER
131
120
        {"station_id", t_uinteger, .addr.uinteger = &R1008.station_id},
132
120
        {"desc",       t_string,   .addr.string = R1008.descriptor,
133
120
                                         .len = sizeof(R1008.descriptor)},
134
120
        {"setup_id",   t_uinteger, .addr.uinteger = &R1008.setup_id},
135
120
        {"serial",     t_string,   .addr.string = R1008.serial,
136
120
                                         .len = sizeof(R1008.serial)},
137
120
        {NULL},
138
120
    };
139
120
#undef R1008
140
141
600
#define R1009   &rtcm3->rtcmtypes.rtcm3_1009.header
142
120
    const struct json_attr_t json_rtcm1009[] = {
143
120
        RTCM3_HEADER
144
120
        {"station_id", t_uinteger, .addr.uinteger = R1009.station_id},
145
120
        {"tow",        t_uinteger, .addr.uinteger = (unsigned int *)R1009.tow},
146
120
        {"sync",       t_boolean,  .addr.boolean = R1009.sync},
147
120
        {"smoothing",  t_boolean,  .addr.boolean = R1009.smoothing},
148
120
        {"interval",   t_uinteger, .addr.uinteger = R1009.interval},
149
120
        {"satellites", t_array,
150
120
         STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1009.rtk_data,
151
120
         rtcm1009_satellite, &satcount)},
152
120
        {NULL},
153
120
    };
154
120
#undef R1010
155
156
600
#define R1010   &rtcm3->rtcmtypes.rtcm3_1010.header
157
120
    const struct json_attr_t json_rtcm1010[] = {
158
120
        RTCM3_HEADER
159
120
        {"station_id", t_uinteger, .addr.uinteger = R1010.station_id},
160
120
        {"tow",        t_uinteger, .addr.uinteger = (unsigned int *)R1010.tow},
161
120
        {"sync",       t_boolean,  .addr.boolean = R1010.sync},
162
120
        {"smoothing",  t_boolean,  .addr.boolean = R1010.smoothing},
163
120
        {"interval",   t_uinteger, .addr.uinteger = R1010.interval},
164
120
        {"satellites", t_array,
165
120
         STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1010.rtk_data,
166
120
         rtcm1010_satellite, &satcount)},
167
120
        {NULL},
168
120
    };
169
120
#undef R1010
170
171
960
#define R1014   &rtcm3->rtcmtypes.rtcm3_1014
172
120
    const struct json_attr_t json_rtcm1014[] = {
173
120
        RTCM3_HEADER
174
120
        {"netid",      t_uinteger, .addr.uinteger = R1014.network_id},
175
120
        {"subnetid",   t_uinteger, .addr.uinteger = R1014.subnetwork_id},
176
120
        {"statcount",  t_uinteger, .addr.uinteger = R1014.stationcount},
177
120
        {"master",     t_uinteger, .addr.uinteger = R1014.master_id},
178
120
        {"aux",        t_uinteger, .addr.uinteger = R1014.aux_id},
179
120
        {"lat",        t_real,     .addr.real = R1014.d_lat},
180
120
        {"lon",        t_real,     .addr.real = R1014.d_lon},
181
120
        {"alt",        t_real,     .addr.real = R1014.d_alt},
182
120
        {NULL},
183
120
    };
184
120
#undef R1014
185
186
1.20k
#define R1033   rtcm3->rtcmtypes.rtcm3_1033
187
120
    const struct json_attr_t json_rtcm1033[] = {
188
120
        RTCM3_HEADER
189
120
        {"station_id", t_uinteger, .addr.uinteger = &R1033.station_id},
190
120
        {"desc",       t_string,   .addr.string = R1033.descriptor,
191
120
                                         .len = sizeof(R1033.descriptor)},
192
120
        {"setup_id",   t_uinteger, .addr.uinteger = &R1033.setup_id},
193
120
        {"serial",     t_string,   .addr.string = R1033.serial,
194
120
                                         .len = sizeof(R1033.serial)},
195
120
        {"receiver",   t_string,   .addr.string = R1033.receiver,
196
120
                                         .len = sizeof(R1033.receiver)},
197
120
        {"firmware",   t_string,   .addr.string = R1033.firmware,
198
120
                                         .len = sizeof(R1033.firmware)},
199
120
        {NULL},
200
120
    };
201
120
#undef R1033
202
203
840
#define R1230   rtcm3->rtcmtypes.rtcm3_1230
204
120
    const struct json_attr_t json_rtcm1230[] = {
205
120
        RTCM3_HEADER
206
120
        {"station_id", t_uinteger, .addr.uinteger = &R1230.station_id},
207
120
        {"bi",         t_ubyte,    .addr.ubyte = &R1230.bias_indicator},
208
120
        {"sm",         t_ubyte,    .addr.ubyte = &R1230.signals_mask},
209
120
        {"l1ca",       t_integer,  .addr.integer = &R1230.l1_ca_bias,
210
120
                                   .dflt.integer = 0},
211
120
        {"l1p",        t_integer,  .addr.integer = &R1230.l1_p_bias,
212
120
                                   .dflt.integer = 0},
213
120
        {"l2ca",       t_integer,  .addr.integer = &R1230.l2_ca_bias,
214
120
                                   .dflt.integer = 0},
215
120
        {"l2p",        t_integer,  .addr.integer = &R1230.l2_p_bias,
216
120
                                   .dflt.integer = 0},
217
120
        {NULL},
218
120
    };
219
120
#undef R1033
220
221
120
    const struct json_attr_t json_rtcm3_fallback[] = {
222
120
        RTCM3_HEADER
223
120
        {"data", t_array, .addr.array.element_type = t_string,
224
120
                          .addr.array.arr.strings.ptrs = stringptrs,
225
120
                          .addr.array.arr.strings.store = stringstore,
226
120
                         .addr.array.arr.strings.storelen = sizeof(stringstore),
227
120
                          .addr.array.count = &stringcount,
228
120
                          .addr.array.maxlen = NITEMS(stringptrs)},
229
120
        {NULL},
230
120
    };
231
232
120
#undef RTCM3_HEADER
233
// *INDENT-ON*
234
235
120
    memset(rtcm3, '\0', sizeof(struct rtcm3_t));
236
237
120
    if (strstr(buf, "\"type\":1001,") != NULL) {
238
2
        status = json_read_object(buf, json_rtcm1001, endptr);
239
2
        if (status == 0)
240
1
            rtcm3->rtcmtypes.rtcm3_1001.header.satcount =
241
1
                (unsigned short)satcount;
242
118
    } else if (strstr(buf, "\"type\":1002,") != NULL) {
243
3
        status = json_read_object(buf, json_rtcm1002, endptr);
244
3
        if (status == 0)
245
1
            rtcm3->rtcmtypes.rtcm3_1002.header.satcount =
246
1
               (unsigned short)satcount;
247
115
    } else if (strstr(buf, "\"type\":1007,") != NULL) {
248
1
        status = json_read_object(buf, json_rtcm1007, endptr);
249
114
    } else if (strstr(buf, "\"type\":1008,") != NULL) {
250
1
        status = json_read_object(buf, json_rtcm1008, endptr);
251
113
    } else if (strstr(buf, "\"type\":1009,") != NULL) {
252
1
        status = json_read_object(buf, json_rtcm1009, endptr);
253
112
    } else if (strstr(buf, "\"type\":1010,") != NULL) {
254
1
        status = json_read_object(buf, json_rtcm1010, endptr);
255
111
    } else if (strstr(buf, "\"type\":1014,") != NULL) {
256
1
        status = json_read_object(buf, json_rtcm1014, endptr);
257
110
    } else if (strstr(buf, "\"type\":1033,") != NULL) {
258
1
        status = json_read_object(buf, json_rtcm1033, endptr);
259
109
    } else if (strstr(buf, "\"type\":1230,") != NULL) {
260
22
        status = json_read_object(buf, json_rtcm1230, endptr);
261
87
    } else {
262
87
        int n;
263
87
        status = json_read_object(buf, json_rtcm3_fallback, endptr);
264
46.7k
        for (n = 0; n < NITEMS(rtcm3->rtcmtypes.data); n++) {
265
46.6k
            if (n >= stringcount) {
266
44.9k
                rtcm3->rtcmtypes.data[n] = '\0';
267
44.9k
            } else {
268
1.76k
                unsigned int u;
269
1.76k
                int fldcount = sscanf(stringptrs[n], "0x%02x\n", &u);
270
1.76k
                if (fldcount != 1)
271
42
                    return JSON_ERR_MISC;
272
1.72k
                else
273
1.72k
                    rtcm3->rtcmtypes.data[n] = (char)u;
274
1.76k
            }
275
46.6k
        }
276
87
    }
277
78
    return status;
278
120
}
279
280
// rtcm3_json.c ends here
281
// vim: set expandtab shiftwidth=4