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 (c) 2013-2018 by the GPSD project
12 SPDX-License-Identifier: BSD-2-clause
13
14 ***************************************************************************/
15
16 #include "gpsd_config.h" /* must be before all includes */
17
18 #include <stdio.h>
19 #include <math.h>
20 #include <string.h>
21 #include <stddef.h>
22
23 #include "gpsd.h"
24
25 #ifdef SOCKET_EXPORT_ENABLE
26 #include "gps_json.h"
27
json_rtcm3_read(const char * buf,char * path,size_t pathlen,struct rtcm3_t * rtcm3,const char ** endptr)28 int json_rtcm3_read(const char *buf,
29 char *path, size_t pathlen, struct rtcm3_t *rtcm3,
30 const char **endptr)
31 {
32 static char *stringptrs[NITEMS(rtcm3->rtcmtypes.data)];
33 static char stringstore[sizeof(rtcm3->rtcmtypes.data) * 2];
34 static int stringcount;
35
36 /* *INDENT-OFF* */
37 #define RTCM3_HEADER \
38 {"class", t_check, .dflt.check = "RTCM3"}, \
39 {"type", t_uinteger, .addr.uinteger = &rtcm3->type}, \
40 {"device", t_string, .addr.string = path, .len = pathlen}, \
41 {"length", t_uinteger, .addr.uinteger = &rtcm3->length},
42
43 int status = 0, satcount = 0;
44
45 #define RTCM3FIELD(type, fld) STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
46 const struct json_attr_t rtcm1001_satellite[] = {
47 {"ident", t_uinteger, RTCM3FIELD(1001, ident)},
48 {"ind", t_uinteger, RTCM3FIELD(1001, L1.indicator)},
49 {"prange", t_real, RTCM3FIELD(1001, L1.pseudorange)},
50 {"delta", t_real, RTCM3FIELD(1001, L1.rangediff)},
51 {"lockt", t_uinteger, RTCM3FIELD(1001, L1.locktime)},
52 {NULL},
53 };
54
55 const struct json_attr_t rtcm1002_satellite[] = {
56 {"ident", t_uinteger, RTCM3FIELD(1002, ident)},
57 {"ind", t_uinteger, RTCM3FIELD(1002, L1.indicator)},
58 {"prange", t_real, RTCM3FIELD(1002, L1.pseudorange)},
59 {"delta", t_real, RTCM3FIELD(1002, L1.rangediff)},
60 {"lockt", t_uinteger, RTCM3FIELD(1002, L1.locktime)},
61 {"amb", t_uinteger, RTCM3FIELD(1002, L1.ambiguity)},
62 {"CNR", t_real, RTCM3FIELD(1002, L1.CNR)},
63 {NULL},
64 };
65
66 const struct json_attr_t rtcm1009_satellite[] = {
67 {"ident", t_uinteger, RTCM3FIELD(1009, ident)},
68 {"ind", t_uinteger, RTCM3FIELD(1009, L1.indicator)},
69 {"channel", t_uinteger, RTCM3FIELD(1009, L1.channel)},
70 {"prange", t_real, RTCM3FIELD(1009, L1.pseudorange)},
71 {"delta", t_real, RTCM3FIELD(1009, L1.rangediff)},
72 {"lockt", t_uinteger, RTCM3FIELD(1009, L1.locktime)},
73 {NULL},
74 };
75
76 const struct json_attr_t rtcm1010_satellite[] = {
77 {"ident", t_uinteger, RTCM3FIELD(1010, ident)},
78 {"ind", t_uinteger, RTCM3FIELD(1010, L1.indicator)},
79 {"channel", t_uinteger, RTCM3FIELD(1010, L1.channel)},
80 {"prange", t_real, RTCM3FIELD(1010, L1.pseudorange)},
81 {"delta", t_real, RTCM3FIELD(1010, L1.rangediff)},
82 {"lockt", t_uinteger, RTCM3FIELD(1010, L1.locktime)},
83 {"amb", t_uinteger, RTCM3FIELD(1010, L1.ambiguity)},
84 {"CNR", t_real, RTCM3FIELD(1010, L1.CNR)},
85 {NULL},
86 };
87 #undef RTCM3FIELD
88
89 #define R1001 &rtcm3->rtcmtypes.rtcm3_1001.header
90 const struct json_attr_t json_rtcm1001[] = {
91 RTCM3_HEADER
92 {"station_id", t_uinteger, .addr.uinteger = R1001.station_id},
93 {"tow", t_uinteger, .addr.uinteger = (unsigned int *)R1001.tow},
94 {"sync", t_boolean, .addr.boolean = R1001.sync},
95 {"smoothing", t_boolean, .addr.boolean = R1001.smoothing},
96 {"interval", t_uinteger, .addr.uinteger = R1001.interval},
97 {"satellites", t_array, STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1001.rtk_data,
98 rtcm1001_satellite, &satcount)},
99 {NULL},
100 };
101 #undef R1001
102
103 #define R1002 &rtcm3->rtcmtypes.rtcm3_1002.header
104 const struct json_attr_t json_rtcm1002[] = {
105 RTCM3_HEADER
106 {"station_id", t_uinteger, .addr.uinteger = R1002.station_id},
107 {"tow", t_uinteger, .addr.uinteger = (unsigned int *)R1002.tow},
108 {"sync", t_boolean, .addr.boolean = R1002.sync},
109 {"smoothing", t_boolean, .addr.boolean = R1002.smoothing},
110 {"interval", t_uinteger, .addr.uinteger = R1002.interval},
111 {"satellites", t_array, STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1002.rtk_data,
112 rtcm1002_satellite, &satcount)},
113 {NULL},
114 };
115 #undef R1002
116
117 #define R1007 rtcm3->rtcmtypes.rtcm3_1007
118 const struct json_attr_t json_rtcm1007[] = {
119 RTCM3_HEADER
120 {"station_id", t_uinteger, .addr.uinteger = &R1007.station_id},
121 {"desc", t_string, .addr.string = R1007.descriptor,
122 .len = sizeof(R1007.descriptor)},
123 {"setup_id", t_uinteger, .addr.uinteger = &R1007.setup_id},
124 {NULL},
125 };
126 #undef R1002
127
128 #define R1008 rtcm3->rtcmtypes.rtcm3_1008
129 const struct json_attr_t json_rtcm1008[] = {
130 RTCM3_HEADER
131 {"station_id", t_uinteger, .addr.uinteger = &R1008.station_id},
132 {"desc", t_string, .addr.string = R1008.descriptor,
133 .len = sizeof(R1008.descriptor)},
134 {"setup_id", t_uinteger, .addr.uinteger = &R1008.setup_id},
135 {"serial", t_string, .addr.string = R1008.serial,
136 .len = sizeof(R1008.serial)},
137 {NULL},
138 };
139 #undef R1008
140
141 #define R1009 &rtcm3->rtcmtypes.rtcm3_1009.header
142 const struct json_attr_t json_rtcm1009[] = {
143 RTCM3_HEADER
144 {"station_id", t_uinteger, .addr.uinteger = R1009.station_id},
145 {"tow", t_uinteger, .addr.uinteger = (unsigned int *)R1009.tow},
146 {"sync", t_boolean, .addr.boolean = R1009.sync},
147 {"smoothing", t_boolean, .addr.boolean = R1009.smoothing},
148 {"interval", t_uinteger, .addr.uinteger = R1009.interval},
149 {"satellites", t_array, STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1009.rtk_data,
150 rtcm1009_satellite, &satcount)},
151 {NULL},
152 };
153 #undef R1010
154
155 #define R1010 &rtcm3->rtcmtypes.rtcm3_1010.header
156 const struct json_attr_t json_rtcm1010[] = {
157 RTCM3_HEADER
158 {"station_id", t_uinteger, .addr.uinteger = R1010.station_id},
159 {"tow", t_uinteger, .addr.uinteger = (unsigned int *)R1010.tow},
160 {"sync", t_boolean, .addr.boolean = R1010.sync},
161 {"smoothing", t_boolean, .addr.boolean = R1010.smoothing},
162 {"interval", t_uinteger, .addr.uinteger = R1010.interval},
163 {"satellites", t_array, STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1010.rtk_data,
164 rtcm1010_satellite, &satcount)},
165 {NULL},
166 };
167 #undef R1010
168
169 #define R1014 &rtcm3->rtcmtypes.rtcm3_1014
170 const struct json_attr_t json_rtcm1014[] = {
171 RTCM3_HEADER
172 {"netid", t_uinteger, .addr.uinteger = R1014.network_id},
173 {"subnetid", t_uinteger, .addr.uinteger = R1014.subnetwork_id},
174 {"statcount", t_uinteger, .addr.uinteger = R1014.stationcount},
175 {"master", t_uinteger, .addr.uinteger = R1014.master_id},
176 {"aux", t_uinteger, .addr.uinteger = R1014.aux_id},
177 {"lat", t_real, .addr.real = R1014.d_lat},
178 {"lon", t_real, .addr.real = R1014.d_lon},
179 {"alt", t_real, .addr.real = R1014.d_alt},
180 {NULL},
181 };
182 #undef R1014
183
184 #define R1033 rtcm3->rtcmtypes.rtcm3_1033
185 const struct json_attr_t json_rtcm1033[] = {
186 RTCM3_HEADER
187 {"station_id", t_uinteger, .addr.uinteger = &R1033.station_id},
188 {"desc", t_string, .addr.string = R1033.descriptor,
189 .len = sizeof(R1033.descriptor)},
190 {"setup_id", t_uinteger, .addr.uinteger = &R1033.setup_id},
191 {"serial", t_string, .addr.string = R1033.serial,
192 .len = sizeof(R1033.serial)},
193 {"receiver", t_string, .addr.string = R1033.receiver,
194 .len = sizeof(R1033.receiver)},
195 {"firmware", t_string, .addr.string = R1033.firmware,
196 .len = sizeof(R1033.firmware)},
197 {NULL},
198 };
199 #undef R1033
200
201 const struct json_attr_t json_rtcm3_fallback[] = {
202 RTCM3_HEADER
203 {"data", t_array, .addr.array.element_type = t_string,
204 .addr.array.arr.strings.ptrs = stringptrs,
205 .addr.array.arr.strings.store = stringstore,
206 .addr.array.arr.strings.storelen = sizeof(stringstore),
207 .addr.array.count = &stringcount,
208 .addr.array.maxlen = NITEMS(stringptrs)},
209 {NULL},
210 };
211
212 #undef RTCM3_HEADER
213 /* *INDENT-ON* */
214
215 memset(rtcm3, '\0', sizeof(struct rtcm3_t));
216
217 if (strstr(buf, "\"type\":1001,") != NULL) {
218 status = json_read_object(buf, json_rtcm1001, endptr);
219 if (status == 0)
220 rtcm3->rtcmtypes.rtcm3_1001.header.satcount = (unsigned short)satcount;
221 } else if (strstr(buf, "\"type\":1002,") != NULL) {
222 status = json_read_object(buf, json_rtcm1002, endptr);
223 if (status == 0)
224 rtcm3->rtcmtypes.rtcm3_1002.header.satcount = (unsigned short)satcount;
225 } else if (strstr(buf, "\"type\":1007,") != NULL) {
226 status = json_read_object(buf, json_rtcm1007, endptr);
227 } else if (strstr(buf, "\"type\":1008,") != NULL) {
228 status = json_read_object(buf, json_rtcm1008, endptr);
229 } else if (strstr(buf, "\"type\":1009,") != NULL) {
230 status = json_read_object(buf, json_rtcm1009, endptr);
231 } else if (strstr(buf, "\"type\":1010,") != NULL) {
232 status = json_read_object(buf, json_rtcm1010, endptr);
233 } else if (strstr(buf, "\"type\":1014,") != NULL) {
234 status = json_read_object(buf, json_rtcm1014, endptr);
235 } else if (strstr(buf, "\"type\":1033,") != NULL) {
236 status = json_read_object(buf, json_rtcm1033, endptr);
237 } else {
238 int n;
239 status = json_read_object(buf, json_rtcm3_fallback, endptr);
240 for (n = 0; n < NITEMS(rtcm3->rtcmtypes.data); n++) {
241 if (n >= stringcount) {
242 rtcm3->rtcmtypes.data[n] = '\0';
243 } else {
244 unsigned int u;
245 int fldcount = sscanf(stringptrs[n], "0x%02x\n", &u);
246 if (fldcount != 1)
247 return JSON_ERR_MISC;
248 else
249 rtcm3->rtcmtypes.data[n] = (char)u;
250 }
251 }
252 }
253 return status;
254 }
255 #endif /* SOCKET_EXPORT_ENABLE */
256
257 /* rtcm3_json.c ends here */
258