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