Coverage Report

Created: 2025-07-09 06:54

/src/gpsd/gpsd-3.26.2~dev/drivers/driver_rtcm3.c
Line
Count
Source (jump to first uncovered line)
1
/*****************************************************************************
2
3
This is a decoder for RTCM-104 3.x, a serial protocol used for
4
broadcasting pseudorange corrections from differential-GPS reference
5
stations.  The applicable specification is RTCM 10403.1: RTCM Paper
6
177-2006-SC104-STD.  This obsolesces the earlier RTCM-104 2.x
7
specifications. The specification document is proprietary; ordering
8
instructions are accessible from <http://www.rtcm.org/>
9
under "Publications".
10
11
Unike the RTCM 2.x protocol, RTCM3.x does not use the strange
12
sliding-bit-window IS-GPS-200 protocol as a transport layer, but is a
13
self-contained byte-oriented packet protocol.  Packet recognition is
14
handled in the GPSD packet-getter state machine; this code is
15
concerned with unpacking the packets into well-behaved C structures,
16
coping with odd field lengths and fields that may overlap byte
17
boundaries.  These report structures live in gps.h.
18
19
Note that the unpacking this module does is probably useful only for
20
RTCM reporting and diagnostic tools.  It is not necessary when
21
passing RTCM corrections to a GPS, which normally should just be
22
passed an entire correction packet for processing by their internal
23
firmware.
24
25
Decodes of the following types have been verified: 1004, 1005, 1006,
26
1008, 1012, 1013, 1029. There is good reason to believe the 1007 code
27
is correct, as it's identical to 1008 up to where it ends.
28
29
The 1033 decode was arrived at by looking at an rtcminspect dump and noting
30
that it carries an information superset of the 1008.  There are additional
31
Receiver and Firmware fields we're not certain to decode without access
32
to an RTCM3 standard at revision 4 or later, but the guess in the code
33
has been observed to correctly analyze a message with a nonempty Receiver
34
field.
35
36
This file is Copyright 2010 by the GPSD project
37
SPDX-License-Identifier: BSD-2-clause
38
39
*****************************************************************************/
40
41
#include "../include/gpsd_config.h"  // must be before all includes
42
43
#include <string.h>
44
45
#include "../include/gpsd.h"
46
#include "../include/bits.h"
47
48
// scaling constants for RTCM3 real number types
49
0
#define GPS_PSEUDORANGE_RESOLUTION      0.02    // DF011
50
0
#define PSEUDORANGE_DIFF_RESOLUTION     0.0005  // DF012, DF042
51
0
#define CARRIER_NOISE_RATIO_UNITS       0.25    // DF015, DF045, DF050
52
0
#define ANTENNA_POSITION_RESOLUTION     0.0001  // DF025, DF026, DF027
53
0
#define GLONASS_PSEUDORANGE_RESOLUTION  0.02    // DF041
54
0
#define ANTENNA_DEGREE_RESOLUTION       25e-6   // DF062
55
#define GPS_EPOCH_TIME_RESOLUTION       0.1     // DF065
56
// DF069, DF070, DF192, DF193, DF194, DF195
57
0
#define PHASE_CORRECTION_RESOLUTION     0.5
58
// DF156, DF157, DF158, DF166, DF167, DF168, DF169, DF196, DF197
59
0
#define TRANSLATION_MM_RESOLUTION       0.001
60
0
#define VALIDITY_RESOLUTION             2.0     // DF152, DF153, DF154, DF155
61
0
#define SCALE_PPM_RESOLUTION            1e-5    // DF162
62
0
#define ROTATION_ARCSEC_RESOLUTION      2e-5    // DF159, DF160, DF161
63
// DF171, DF172, DF176, DF177, DF178, DF179, DF183, DF184, DF185, DF186
64
0
#define PROJ_ORIGIN_RESOLUTION          11e-9
65
0
#define DEG_ARCSEC_RESOLUTION           3600
66
0
#define CM_RESOLUTION                   0.01    // DF198
67
0
#define RES_ARCSEC_RESOLUTION           3e-5    // DF199, DF200
68
69
// Other magic values
70
0
#define GPS_INVALID_PSEUDORANGE         0x80000 // DF012, DF018
71
0
#define GLONASS_INVALID_RANGEINCR       0x2000  // DF047
72
0
#define GLONASS_CHANNEL_BASE            7       // DF040
73
74
// Large case statements make GNU indent very confused
75
// *INDENT-OFF*
76
77
/* good source on message types:
78
 * https://software.rtcm-ntrip.org/export/HEAD/ntrip/trunk/BNC/src/bnchelp.html
79
 * Also look in the BNC source
80
 * and look at the tklib source: http://www.rtklib.com/
81
 */
82
83
0
#define ugrab(width)    (bitcount += width, ubits(buf, \
84
0
                         bitcount - width, width, false))
85
0
#define sgrab(width)    (bitcount += width, sbits(buf,  \
86
0
                         bitcount - width, width, false))
87
88
/* decode 1015/1016/1017 header
89
 * they share a common header
90
 * TODO: rtklib has C code for these.
91
 *
92
 * Return: false if decoded
93
 *         true if runt
94
 */
95
static bool rtcm3_101567(const struct gps_context_t *context,
96
                         struct rtcm3_t *rtcm, const unsigned char *buf)
97
0
{
98
0
    int bitcount = 36;  // 8 preamble, 6 zero, 10 length, 12 type
99
100
0
    if (22 > rtcm->length) {
101
        // need 76 bits, 9.5 bytes
102
0
        rtcm->length = 0;          // set to zero to prevent JSON decode
103
0
        GPSD_LOG(LOG_WARN, &context->errout,
104
0
                 "RTCM3: rtcm3_101567_msm() type %d runt length %d ",
105
0
                 rtcm->type, rtcm->length);
106
0
        return true;
107
0
    }
108
109
    // 1015, 1016, and 1017 all use the 1015 struct
110
0
    rtcm->rtcmtypes.rtcm3_1015.header.network_id = (unsigned)ugrab(12);
111
0
    rtcm->rtcmtypes.rtcm3_1015.header.subnetwork_id = (unsigned )ugrab(4);
112
0
    rtcm->rtcmtypes.rtcm3_1015.header.tow = ugrab(23);
113
0
    rtcm->rtcmtypes.rtcm3_1015.header.multimesg = (bool)ugrab(1);
114
0
    rtcm->rtcmtypes.rtcm3_1015.header.master_id = (unsigned)ugrab(12);
115
0
    rtcm->rtcmtypes.rtcm3_1015.header.aux_id = (unsigned)ugrab(12);
116
0
    rtcm->rtcmtypes.rtcm3_1015.header.satcount = (unsigned char)ugrab(4);
117
118
0
    GPSD_LOG(LOG_PROG, &context->errout, "RTCM3: rtcm3_10567(%u) "
119
0
             "network_id %u subnetwork_id %u tow %lu multimesg %u "
120
0
             "master_id %u aux_id %u satcount %u",
121
0
             rtcm->type,
122
0
             rtcm->rtcmtypes.rtcm3_1015.header.network_id,
123
0
             rtcm->rtcmtypes.rtcm3_1015.header.subnetwork_id,
124
0
             rtcm->rtcmtypes.rtcm3_1015.header.tow,
125
0
             rtcm->rtcmtypes.rtcm3_1015.header.multimesg,
126
0
             rtcm->rtcmtypes.rtcm3_1015.header.master_id,
127
0
             rtcm->rtcmtypes.rtcm3_1015.header.aux_id,
128
0
             rtcm->rtcmtypes.rtcm3_1015.header.satcount);
129
0
    return false;
130
0
}
131
132
/* decode 4076 header
133
 * IGS State Space Representation (SSR) Format
134
 * www.igs.org
135
 * https://files.igs.org/pub/data/format/igs_ssr_v1.pdf
136
 *
137
 * Return: false if decoded
138
 *         true if runt or undecoded
139
 */
140
static bool rtcm3_4076(const struct gps_context_t *context,
141
                         struct rtcm3_t *rtcm, const unsigned char *buf)
142
0
{
143
0
    int bitcount = 36;         // 8 preamble, 6 zero, 10 length, 12 type
144
145
0
    if (22 > rtcm->length) {
146
        // need 76 bits, 9.5 bytes
147
0
        rtcm->length = 0;          // set to zero to prevent JSON decode
148
0
        GPSD_LOG(LOG_WARN, &context->errout,
149
0
                 "RTCM3: rtcm3_4076() type %d runt length %d ",
150
0
                 rtcm->type, rtcm->length);
151
0
        return true;
152
0
    }
153
154
0
    rtcm->rtcmtypes.rtcm3_4076.ssr_vers = ugrab(3);
155
0
    rtcm->rtcmtypes.rtcm3_4076.igs_num = ugrab(8);
156
0
    rtcm->rtcmtypes.rtcm3_4076.ssr_epoch = ugrab(20);
157
0
    rtcm->rtcmtypes.rtcm3_4076.ssr_update = ugrab(4);
158
0
    rtcm->rtcmtypes.rtcm3_4076.ssr_mmi = ugrab(1);
159
0
    rtcm->rtcmtypes.rtcm3_4076.ssr_iod = ugrab(4);
160
0
    rtcm->rtcmtypes.rtcm3_4076.ssr_provider = ugrab(16);
161
0
    rtcm->rtcmtypes.rtcm3_4076.ssr_solution = ugrab(4);
162
163
0
    GPSD_LOG(LOG_PROG, &context->errout,
164
0
             "RTCM3: rtcm3_4076 ver %u igs_num %u Epoch %u update %u mmi %u "
165
0
             "IOD %u Provider %u Solution %u\n",
166
0
             rtcm->rtcmtypes.rtcm3_4076.ssr_vers,
167
0
             rtcm->rtcmtypes.rtcm3_4076.igs_num,
168
0
             rtcm->rtcmtypes.rtcm3_4076.ssr_epoch,
169
0
             rtcm->rtcmtypes.rtcm3_4076.ssr_update,
170
0
             rtcm->rtcmtypes.rtcm3_4076.ssr_mmi,
171
0
             rtcm->rtcmtypes.rtcm3_4076.ssr_iod,
172
0
             rtcm->rtcmtypes.rtcm3_4076.ssr_provider,
173
0
             rtcm->rtcmtypes.rtcm3_4076.ssr_solution);
174
0
    return true;
175
0
}
176
177
/* decode MSM header
178
 * MSM1 to MSM7 share a common header
179
 * TODO: rtklib has C code for these.
180
 *
181
 * Return: false if decoded
182
 *         true if runt, or error
183
 */
184
static bool rtcm3_decode_msm(const struct gps_context_t *context,
185
                             struct rtcm3_t *rtcm, const unsigned char *buf)
186
0
{
187
0
    int bitcount = 36;  // 8 preamble, 6 zero, 10 length, 12 type
188
0
    unsigned n_sig = 0, n_sat = 0, n_cell = 0;
189
0
    uint64_t sat_mask;
190
0
    uint32_t sig_mask;
191
0
    unsigned i;
192
193
0
    if (22 > rtcm->length) {
194
        // need 169 bits, 21.125 bytes
195
0
        rtcm->length = 0;          // set to zero to prevent JSON decode
196
0
        GPSD_LOG(LOG_WARN, &context->errout,
197
0
                 "RTCM3: rtcm3_decode_msm() type %d runt length %d ",
198
0
                 rtcm->type, rtcm->length);
199
0
        return true;
200
0
    }
201
202
0
    rtcm->rtcmtypes.rtcm3_msm.station_id = ugrab(12);
203
0
    rtcm->rtcmtypes.rtcm3_msm.tow = ugrab(30);
204
0
    rtcm->rtcmtypes.rtcm3_msm.sync = ugrab(1);
205
0
    rtcm->rtcmtypes.rtcm3_msm.IODS = ugrab(3);
206
0
    bitcount += 7;             // skip 7 reserved bits, DF001
207
0
    rtcm->rtcmtypes.rtcm3_msm.steering = ugrab(2);
208
0
    rtcm->rtcmtypes.rtcm3_msm.ext_clk = ugrab(2);
209
0
    rtcm->rtcmtypes.rtcm3_msm.smoothing = ugrab(1);
210
0
    rtcm->rtcmtypes.rtcm3_msm.interval = ugrab(3);
211
    // FIXME: rtcm->rtcmtypes.rtcm3_msm.sat_mask = ugrab(64);
212
    // ugrab(56) is max, can't do 64, so stack it
213
0
    rtcm->rtcmtypes.rtcm3_msm.sat_mask = ugrab(32) << 32;
214
0
    rtcm->rtcmtypes.rtcm3_msm.sat_mask |= ugrab(32);
215
0
    rtcm->rtcmtypes.rtcm3_msm.sig_mask = ugrab(32);
216
217
    // count satellites
218
0
    sat_mask = rtcm->rtcmtypes.rtcm3_msm.sat_mask;
219
0
    while (sat_mask) {
220
0
        n_sat += sat_mask & 1;
221
0
        sat_mask >>= 1;
222
0
    }
223
    // count signals
224
0
    sig_mask = rtcm->rtcmtypes.rtcm3_msm.sig_mask;
225
0
    while (sig_mask) {
226
0
        n_sig += sig_mask & 1;
227
0
        sig_mask >>= 1;
228
0
    }
229
    // determine cells
230
0
    n_cell = n_sat * n_sig;
231
0
    rtcm->rtcmtypes.rtcm3_msm.n_sat = n_sat;
232
0
    rtcm->rtcmtypes.rtcm3_msm.n_sig = n_sig;
233
0
    rtcm->rtcmtypes.rtcm3_msm.n_cell = n_cell;
234
235
0
    if (0 == n_sat ||
236
0
        64 < n_cell) {
237
0
        GPSD_LOG(LOG_WARN, &context->errout,
238
0
                 "RTCM3: rtcm3_decode_msm(%u) interval %u  sat_mask x%llx "
239
0
                 "sig_mask x%x invalid n_cell %u\n",
240
0
                 rtcm->type,
241
0
                 rtcm->rtcmtypes.rtcm3_msm.interval,
242
0
                 (unsigned long long)rtcm->rtcmtypes.rtcm3_msm.sat_mask,
243
0
                 rtcm->rtcmtypes.rtcm3_msm.sig_mask,
244
0
                 n_cell);
245
0
        return false;
246
0
    }
247
248
    // cell_mask is variable length!  ugrab() width max is 56
249
0
    if (56 >= n_cell) {
250
0
        rtcm->rtcmtypes.rtcm3_msm.cell_mask = ugrab(n_cell);
251
0
    } else {
252
        // 57 to 64, breaks ugrab(), workaround it...
253
0
        rtcm->rtcmtypes.rtcm3_msm.cell_mask = ugrab(56);
254
0
        rtcm->rtcmtypes.rtcm3_msm.cell_mask <<= n_cell - 56;
255
0
        rtcm->rtcmtypes.rtcm3_msm.cell_mask |= ugrab(n_cell - 56);
256
0
    }
257
258
    // Decode Satellite Data
259
260
    // Decode DF397 (MSM 4-7)
261
0
    if (4 == rtcm->rtcmtypes.rtcm3_msm.msm ||
262
0
        5 == rtcm->rtcmtypes.rtcm3_msm.msm ||
263
0
        6 == rtcm->rtcmtypes.rtcm3_msm.msm ||
264
0
        7 == rtcm->rtcmtypes.rtcm3_msm.msm) {
265
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_msm.n_sat; i++) {
266
0
            rtcm->rtcmtypes.rtcm3_msm.sat[i].rr_ms = ugrab(8);
267
0
        }
268
0
    }
269
270
    // Decode Extended Info (MSM 5+7)
271
0
    if (5 == rtcm->rtcmtypes.rtcm3_msm.msm ||
272
0
        7 == rtcm->rtcmtypes.rtcm3_msm.msm) {
273
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_msm.n_sat; i++) {
274
0
            rtcm->rtcmtypes.rtcm3_msm.sat[i].ext_info = ugrab(4);
275
0
        }
276
0
    }
277
278
    // Decode DF398 (MSM 1-7)
279
0
    for (i = 0; i < rtcm->rtcmtypes.rtcm3_msm.n_sat; i++) {
280
0
        rtcm->rtcmtypes.rtcm3_msm.sat[i].rr_m1 = ugrab(10);
281
0
    };
282
283
    // Decode DF399 (MSM 5+7)
284
0
    if (5 == rtcm->rtcmtypes.rtcm3_msm.msm ||
285
0
        7 == rtcm->rtcmtypes.rtcm3_msm.msm) {
286
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_msm.n_sat; i++) {
287
0
            rtcm->rtcmtypes.rtcm3_msm.sat[i].rates_rphr = ugrab(14);
288
0
        }
289
0
    }
290
291
    // Decode Signal Data
292
293
    // Decode DF400 (MSM 1,3,4,5) resp. DF405 (MSM 6+7)
294
0
    if (1 == rtcm->rtcmtypes.rtcm3_msm.msm ||
295
0
        3 == rtcm->rtcmtypes.rtcm3_msm.msm ||
296
0
        4 == rtcm->rtcmtypes.rtcm3_msm.msm ||
297
0
        5 == rtcm->rtcmtypes.rtcm3_msm.msm) {
298
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_msm.n_cell; i++) {
299
0
            rtcm->rtcmtypes.rtcm3_msm.sig[i].pseudo_r = sgrab(15);
300
0
        }
301
0
    } else if (6 == rtcm->rtcmtypes.rtcm3_msm.msm ||
302
0
               7 == rtcm->rtcmtypes.rtcm3_msm.msm) {
303
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_msm.n_cell; i++) {
304
0
            rtcm->rtcmtypes.rtcm3_msm.sig[i].pseudo_r = sgrab(20);
305
0
        }
306
0
    }
307
308
    // Decode DF401 (MSM 2,3,4,5) resp. DF406 (MSM 6+7)
309
0
    if (2 == rtcm->rtcmtypes.rtcm3_msm.msm ||
310
0
        3 == rtcm->rtcmtypes.rtcm3_msm.msm ||
311
0
        4 == rtcm->rtcmtypes.rtcm3_msm.msm ||
312
0
        5 == rtcm->rtcmtypes.rtcm3_msm.msm) {
313
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_msm.n_cell; i++) {
314
0
            rtcm->rtcmtypes.rtcm3_msm.sig[i].phase_r = sgrab(22);
315
0
        }
316
0
    } else if (6 == rtcm->rtcmtypes.rtcm3_msm.msm ||
317
0
               7 == rtcm->rtcmtypes.rtcm3_msm.msm) {
318
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_msm.n_cell; i++) {
319
0
            rtcm->rtcmtypes.rtcm3_msm.sig[i].phase_r = sgrab(24);
320
0
        }
321
0
    }
322
323
    // Decode DF402 (MSM 2,3,4,5) resp. DF407 (MSM 6+7)
324
0
    if (2 == rtcm->rtcmtypes.rtcm3_msm.msm ||
325
0
        3 == rtcm->rtcmtypes.rtcm3_msm.msm ||
326
0
        4 == rtcm->rtcmtypes.rtcm3_msm.msm ||
327
0
        5 == rtcm->rtcmtypes.rtcm3_msm.msm) {
328
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_msm.n_cell; i++) {
329
0
            rtcm->rtcmtypes.rtcm3_msm.sig[i].lti = ugrab(4);
330
0
        }
331
0
    } else if (6 == rtcm->rtcmtypes.rtcm3_msm.msm ||
332
0
               7 == rtcm->rtcmtypes.rtcm3_msm.msm) {
333
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_msm.n_cell; i++) {
334
0
            rtcm->rtcmtypes.rtcm3_msm.sig[i].lti = ugrab(10);
335
0
        }
336
0
    }
337
338
    // Decode DF420 (MSM 2-7)
339
0
    if (2 == rtcm->rtcmtypes.rtcm3_msm.msm ||
340
0
        3 == rtcm->rtcmtypes.rtcm3_msm.msm ||
341
0
        4 == rtcm->rtcmtypes.rtcm3_msm.msm ||
342
0
        5 == rtcm->rtcmtypes.rtcm3_msm.msm ||
343
0
        6 == rtcm->rtcmtypes.rtcm3_msm.msm ||
344
0
        7 == rtcm->rtcmtypes.rtcm3_msm.msm) {
345
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_msm.n_cell; i++) {
346
0
            rtcm->rtcmtypes.rtcm3_msm.sig[i].half_amb = ugrab(1);
347
0
        }
348
0
    }
349
350
    // Decode DF403 (MSM 4+5) resp. DF408 (MSM 6+7)
351
0
    if (4 == rtcm->rtcmtypes.rtcm3_msm.msm ||
352
0
        5 == rtcm->rtcmtypes.rtcm3_msm.msm) {
353
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_msm.n_cell; i++) {
354
0
            rtcm->rtcmtypes.rtcm3_msm.sig[i].cnr = ugrab(6);
355
0
        }
356
0
    } else if (6 == rtcm->rtcmtypes.rtcm3_msm.msm ||
357
0
               7 == rtcm->rtcmtypes.rtcm3_msm.msm) {
358
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_msm.n_cell; i++) {
359
0
            rtcm->rtcmtypes.rtcm3_msm.sig[i].cnr = ugrab(10);
360
0
        }
361
0
    }
362
363
    // Decode DF404 (MSM 5+7)
364
0
    if (5 == rtcm->rtcmtypes.rtcm3_msm.msm ||
365
0
        7 == rtcm->rtcmtypes.rtcm3_msm.msm) {
366
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_msm.n_cell; i++) {
367
0
            rtcm->rtcmtypes.rtcm3_msm.sig[i].cnr = sgrab(15);
368
0
        }
369
0
    }
370
371
    // tow is %llu for 32-bit compatibility
372
0
    GPSD_LOG(LOG_PROG, &context->errout, "RTCM3: rtcm3_decode_msm(%u) "
373
0
             "gnssid %u MSM%u id %u tow %llu sync %u IODS %u "
374
0
             "steering %u ext_clk %u smoothing %u interval %u "
375
0
             "sat_mask x%llx sig_mask x%lx cell_mask %llx\n",
376
0
             rtcm->type,
377
0
             rtcm->rtcmtypes.rtcm3_msm.gnssid,
378
0
             rtcm->rtcmtypes.rtcm3_msm.msm,
379
0
             rtcm->rtcmtypes.rtcm3_msm.station_id,
380
0
             (unsigned long long)rtcm->rtcmtypes.rtcm3_msm.tow,
381
0
             rtcm->rtcmtypes.rtcm3_msm.sync,
382
0
             rtcm->rtcmtypes.rtcm3_msm.IODS,
383
0
             rtcm->rtcmtypes.rtcm3_msm.steering,
384
0
             rtcm->rtcmtypes.rtcm3_msm.ext_clk,
385
0
             rtcm->rtcmtypes.rtcm3_msm.smoothing,
386
0
             rtcm->rtcmtypes.rtcm3_msm.interval,
387
0
             (long long unsigned)rtcm->rtcmtypes.rtcm3_msm.sat_mask,
388
0
             (long unsigned)rtcm->rtcmtypes.rtcm3_msm.sig_mask,
389
0
             (long long unsigned)rtcm->rtcmtypes.rtcm3_msm.cell_mask);
390
0
    return false;
391
0
}
392
393
/* break out the raw bits into the scaled report-structure fields
394
 *
395
 * Return: void
396
 */
397
void rtcm3_unpack(const struct gps_context_t *context,
398
                  struct rtcm3_t *rtcm, const unsigned char *buf)
399
0
{
400
0
    unsigned n, n2, n3, n4;
401
0
    int bitcount = 0;
402
0
    unsigned i;
403
0
    signed long temp;
404
0
    bool unknown = true;               // we don't know how to decode
405
0
    const char *msg_name = "Unknown";  // we know the name
406
0
    unsigned preamble, mbz;            // preamble 0xd3, and must be zero
407
408
0
#define GPS_PSEUDORANGE(fld, len) \
409
0
    {temp = (unsigned long)ugrab(len);          \
410
0
    if (temp == GPS_INVALID_PSEUDORANGE) {      \
411
0
        fld.pseudorange = 0;                    \
412
0
    } else {                                    \
413
0
        fld.pseudorange = temp * GPS_PSEUDORANGE_RESOLUTION;} \
414
0
    }
415
0
#define RANGEDIFF(fld, len) \
416
0
    temp = (long)sgrab(len);                    \
417
0
    if (temp == GPS_INVALID_PSEUDORANGE) {      \
418
0
        fld.rangediff = 0;                      \
419
0
    } else {                                    \
420
0
        fld.rangediff = temp * PSEUDORANGE_DIFF_RESOLUTION; \
421
0
    }
422
423
0
    memset(rtcm, 0, sizeof(struct rtcm3_t));
424
425
    // check preamble and zero bits
426
0
    preamble = ugrab(8);
427
0
    mbz = ugrab(6);
428
0
    if (0xD3 != preamble ||
429
0
        0 != mbz) {
430
0
        GPSD_LOG(LOG_WARN, &context->errout,
431
0
                 "RTCM3: invalid preamble x%2x or mbz x%x\n",
432
0
                 preamble, mbz);
433
0
    }
434
435
0
    rtcm->length = (unsigned)ugrab(10);
436
0
    if (2 > rtcm->length) {
437
        // ignore zero payload messages, they do not evan have type
438
        // need 2 bytes just to read 10 bit type.
439
0
        GPSD_LOG(LOG_PROG, &context->errout,
440
0
                 "RTCM3: bad payload length %d bitcount %d\n",
441
0
                 rtcm->length, bitcount);
442
0
        return;
443
0
    }
444
0
    rtcm->type = (unsigned)ugrab(12);
445
446
0
    GPSD_LOG(LOG_IO, &context->errout,
447
0
             "RTCM3: type %d payload length %d bitcount %d\n",
448
0
             rtcm->type, rtcm->length, bitcount);
449
450
    // RTCM3 message type numbers start at 1001
451
0
    switch (rtcm->type) {
452
0
    case 1001:
453
0
        msg_name = "GPS Basic RTK, L1 Only";
454
0
        rtcm->rtcmtypes.rtcm3_1001.header.station_id = (unsigned)ugrab(12);
455
0
        rtcm->rtcmtypes.rtcm3_1001.header.tow = ugrab(30);
456
0
        rtcm->rtcmtypes.rtcm3_1001.header.sync = (bool)ugrab(1);
457
0
        rtcm->rtcmtypes.rtcm3_1001.header.satcount = (unsigned short)ugrab(5);
458
0
        rtcm->rtcmtypes.rtcm3_1001.header.smoothing = (bool)ugrab(1);
459
0
        rtcm->rtcmtypes.rtcm3_1001.header.interval = (unsigned short)ugrab(3);
460
0
#define R1001 rtcm->rtcmtypes.rtcm3_1001.rtk_data[i]
461
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_1001.header.satcount; i++) {
462
0
            R1001.ident = (unsigned short)ugrab(6);
463
0
            R1001.L1.indicator = (unsigned char)ugrab(1);
464
0
            GPS_PSEUDORANGE(R1001.L1, 24);
465
0
            RANGEDIFF(R1001.L1, 20);
466
0
            R1001.L1.locktime = (unsigned char)sgrab(7);
467
0
        }
468
0
#undef R1001
469
0
        unknown = false;
470
0
        break;
471
472
0
    case 1002:
473
0
        msg_name = "GPS Extended RTK, L1 Only";
474
0
        rtcm->rtcmtypes.rtcm3_1002.header.station_id = (unsigned)ugrab(12);
475
0
        rtcm->rtcmtypes.rtcm3_1002.header.tow = ugrab(30);
476
0
        rtcm->rtcmtypes.rtcm3_1002.header.sync = (bool)ugrab(1);
477
0
        rtcm->rtcmtypes.rtcm3_1002.header.satcount = (unsigned short)ugrab(5);
478
0
        rtcm->rtcmtypes.rtcm3_1002.header.smoothing = (bool)ugrab(1);
479
0
        rtcm->rtcmtypes.rtcm3_1002.header.interval = (unsigned short)ugrab(3);
480
0
#define R1002 rtcm->rtcmtypes.rtcm3_1002.rtk_data[i]
481
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_1002.header.satcount; i++) {
482
0
            R1002.ident = (unsigned short)ugrab(6);
483
0
            R1002.L1.indicator = (unsigned char)ugrab(1);
484
0
            GPS_PSEUDORANGE(R1002.L1, 24);
485
0
            RANGEDIFF(R1002.L1, 20);
486
0
            R1002.L1.locktime = (unsigned char)sgrab(7);
487
0
            R1002.L1.ambiguity = (unsigned char)ugrab(8);
488
0
            R1002.L1.CNR = (ugrab(8)) * CARRIER_NOISE_RATIO_UNITS;
489
0
        }
490
0
#undef R1002
491
0
        unknown = false;
492
0
        break;
493
494
0
    case 1003:
495
0
        msg_name = "GPS Basic RTK, L1 & L2";
496
0
        rtcm->rtcmtypes.rtcm3_1003.header.station_id = (unsigned)ugrab(12);
497
0
        rtcm->rtcmtypes.rtcm3_1003.header.tow = ugrab(30);
498
0
        rtcm->rtcmtypes.rtcm3_1003.header.sync = (bool)ugrab(1);
499
0
        rtcm->rtcmtypes.rtcm3_1003.header.satcount = (unsigned short)ugrab(5);
500
0
        rtcm->rtcmtypes.rtcm3_1003.header.smoothing = (bool)ugrab(1);
501
0
        rtcm->rtcmtypes.rtcm3_1003.header.interval = (unsigned short)ugrab(3);
502
0
#define R1003 rtcm->rtcmtypes.rtcm3_1003.rtk_data[i]
503
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_1003.header.satcount; i++) {
504
0
            R1003.ident = (unsigned short)ugrab(6);
505
0
            R1003.L1.indicator = (unsigned char)ugrab(1);
506
0
            GPS_PSEUDORANGE(R1003.L1, 24);
507
0
            RANGEDIFF(R1003.L1, 20);
508
0
            R1003.L1.locktime = (unsigned char)sgrab(7);
509
0
            R1003.L2.indicator = (unsigned char)ugrab(2);
510
0
            GPS_PSEUDORANGE(R1003.L2, 24);
511
0
            temp = (long)sgrab(20);
512
0
            if (temp == GPS_INVALID_PSEUDORANGE) {
513
0
                R1003.L2.rangediff = 0;
514
0
            } else {
515
0
                R1003.L2.rangediff = temp * PSEUDORANGE_DIFF_RESOLUTION;
516
0
            }
517
0
            R1003.L2.locktime = (unsigned char)sgrab(7);
518
0
        }
519
0
#undef R1003
520
0
        unknown = false;
521
0
        break;
522
523
0
    case 1004:
524
0
        msg_name = "GPS Extended RTK, L1 & L2";
525
0
        rtcm->rtcmtypes.rtcm3_1004.header.station_id = (unsigned)ugrab(12);
526
0
        rtcm->rtcmtypes.rtcm3_1004.header.tow = ugrab(30);
527
0
        rtcm->rtcmtypes.rtcm3_1004.header.sync = (bool)ugrab(1);
528
0
        rtcm->rtcmtypes.rtcm3_1004.header.satcount = (unsigned short)ugrab(5);
529
0
        rtcm->rtcmtypes.rtcm3_1004.header.smoothing = (bool)ugrab(1);
530
0
        rtcm->rtcmtypes.rtcm3_1004.header.interval = (unsigned short)ugrab(3);
531
0
#define R1004 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i]
532
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_1004.header.satcount; i++) {
533
0
            R1004.ident = (unsigned short)ugrab(6);
534
0
            R1004.L1.indicator = (bool)ugrab(1);
535
0
            GPS_PSEUDORANGE(R1004.L1, 24);
536
0
            RANGEDIFF(R1004.L1, 20);
537
0
            R1004.L1.locktime = (unsigned char)sgrab(7);
538
0
            R1004.L1.ambiguity = (unsigned char)ugrab(8);
539
0
            R1004.L1.CNR = ugrab(8) * CARRIER_NOISE_RATIO_UNITS;
540
0
            R1004.L2.indicator = (unsigned char)ugrab(2);
541
0
            GPS_PSEUDORANGE(R1004.L2, 14);
542
0
            RANGEDIFF(R1004.L2, 20);
543
0
            R1004.L2.locktime = (unsigned char)sgrab(7);
544
0
            R1004.L2.CNR = ugrab(8) * CARRIER_NOISE_RATIO_UNITS;
545
0
        }
546
0
#undef R1004
547
0
        unknown = false;
548
0
        break;
549
550
0
    case 1005:
551
0
        msg_name = "Stationary Antenna Reference Point, No Height Information";
552
        // 19 bytes
553
0
#define R1005 rtcm->rtcmtypes.rtcm3_1005
554
0
        R1005.station_id = (unsigned short)ugrab(12);
555
0
        ugrab(6);               // reserved
556
0
        R1005.system = ugrab(3);
557
0
        R1005.reference_station = (bool)ugrab(1);
558
0
        R1005.ecef_x = sgrab(38) * ANTENNA_POSITION_RESOLUTION;
559
0
        R1005.single_receiver = ugrab(1);
560
0
        ugrab(1);
561
0
        R1005.ecef_y = sgrab(38) * ANTENNA_POSITION_RESOLUTION;
562
0
        ugrab(2);
563
0
        R1005.ecef_z = sgrab(38) * ANTENNA_POSITION_RESOLUTION;
564
0
#undef R1005
565
0
        unknown = false;
566
0
        break;
567
568
0
    case 1006:
569
0
        msg_name = "Stationary Antenna Reference Point, w/ Height Info";
570
        // 21 bytes
571
0
#define R1006 rtcm->rtcmtypes.rtcm3_1006
572
0
        R1006.station_id = (unsigned short)ugrab(12);
573
0
        (void)ugrab(6);         // reserved
574
0
        R1006.system = ugrab(3);
575
0
        R1006.reference_station = (bool)ugrab(1);
576
0
        R1006.ecef_x = sgrab(38) * ANTENNA_POSITION_RESOLUTION;
577
0
        R1006.single_receiver = ugrab(1);
578
0
        ugrab(1);
579
0
        R1006.ecef_y = sgrab(38) * ANTENNA_POSITION_RESOLUTION;
580
0
        ugrab(2);
581
0
        R1006.ecef_z = sgrab(38) * ANTENNA_POSITION_RESOLUTION;
582
0
        R1006.height = ugrab(16) * ANTENNA_POSITION_RESOLUTION;
583
0
#undef R1006
584
0
        unknown = false;
585
0
        break;
586
587
0
    case 1007:
588
0
        msg_name = "Antenna Description";
589
        // 5 to 36 bytes
590
0
        rtcm->rtcmtypes.rtcm3_1007.station_id = (unsigned short)ugrab(12);
591
0
        n = (unsigned long)ugrab(8);
592
0
        (void)memcpy(rtcm->rtcmtypes.rtcm3_1007.descriptor, buf + 7, n);
593
0
        rtcm->rtcmtypes.rtcm3_1007.descriptor[n] = '\0';
594
0
        bitcount += 8 * n;
595
0
        rtcm->rtcmtypes.rtcm3_1007.setup_id = ugrab(8);
596
0
        unknown = false;
597
0
        break;
598
599
0
    case 1008:
600
0
        msg_name = "Antenna Description & Serial Number";
601
        // 6 to 68 bytes
602
0
        rtcm->rtcmtypes.rtcm3_1008.station_id = (unsigned short)ugrab(12);
603
0
        n = (unsigned long)ugrab(8);
604
0
        (void)memcpy(rtcm->rtcmtypes.rtcm3_1008.descriptor, buf + 7, n);
605
0
        rtcm->rtcmtypes.rtcm3_1008.descriptor[n] = '\0';
606
0
        bitcount += 8 * n;
607
0
        rtcm->rtcmtypes.rtcm3_1008.setup_id = ugrab(8);
608
0
        n2 = (unsigned long)ugrab(8);
609
0
        (void)memcpy(rtcm->rtcmtypes.rtcm3_1008.serial, buf + 9 + n, n2);
610
0
        rtcm->rtcmtypes.rtcm3_1008.serial[n2] = '\0';
611
        // bitcount += 8 * n2;
612
0
        unknown = false;
613
0
        break;
614
615
0
    case 1009:
616
0
        msg_name = "GLONASS Basic RTK, L1 Only";
617
0
        rtcm->rtcmtypes.rtcm3_1009.header.station_id =
618
0
            (unsigned short)ugrab(12);
619
0
        rtcm->rtcmtypes.rtcm3_1009.header.tow = ugrab(27);
620
0
        rtcm->rtcmtypes.rtcm3_1009.header.sync = (bool)ugrab(1);
621
0
        rtcm->rtcmtypes.rtcm3_1009.header.satcount = (unsigned short)ugrab(5);
622
0
        rtcm->rtcmtypes.rtcm3_1009.header.smoothing = (bool)ugrab(1);
623
0
        rtcm->rtcmtypes.rtcm3_1009.header.interval = (unsigned short)ugrab(3);
624
0
#define R1009 rtcm->rtcmtypes.rtcm3_1009.rtk_data[i]
625
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_1009.header.satcount; i++) {
626
0
            R1009.ident = (unsigned short)ugrab(6);
627
0
            R1009.L1.indicator = (bool)ugrab(1);
628
0
            R1009.L1.channel = (short)ugrab(5) - GLONASS_CHANNEL_BASE;
629
0
            R1009.L1.pseudorange = ugrab(25) * GLONASS_PSEUDORANGE_RESOLUTION;
630
0
            RANGEDIFF(R1009.L1, 20);
631
0
            R1009.L1.locktime = (unsigned char)sgrab(7);
632
0
        }
633
0
#undef R1009
634
0
        unknown = false;
635
0
        break;
636
637
0
    case 1010:
638
0
        msg_name = "GLONASS Extended RTK, L1 Only";
639
0
        rtcm->rtcmtypes.rtcm3_1010.header.station_id =
640
0
            (unsigned short)ugrab(12);
641
0
        rtcm->rtcmtypes.rtcm3_1010.header.tow = ugrab(27);
642
0
        rtcm->rtcmtypes.rtcm3_1010.header.sync = (bool)ugrab(1);
643
0
        rtcm->rtcmtypes.rtcm3_1010.header.satcount = (unsigned short)ugrab(5);
644
0
        rtcm->rtcmtypes.rtcm3_1010.header.smoothing = (bool)ugrab(1);
645
0
        rtcm->rtcmtypes.rtcm3_1010.header.interval = (unsigned short)ugrab(3);
646
0
#define R1010 rtcm->rtcmtypes.rtcm3_1010.rtk_data[i]
647
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_1010.header.satcount; i++) {
648
0
            R1010.ident = (unsigned short)ugrab(6);
649
0
            R1010.L1.indicator = (bool)ugrab(1);
650
0
            R1010.L1.channel = (short)ugrab(5) - GLONASS_CHANNEL_BASE;
651
0
            R1010.L1.pseudorange = ugrab(25) * GLONASS_PSEUDORANGE_RESOLUTION;
652
0
            RANGEDIFF(R1010.L1, 20);
653
0
            R1010.L1.locktime = (unsigned char)sgrab(7);
654
0
            R1010.L1.ambiguity = (unsigned char)ugrab(7);
655
0
            R1010.L1.CNR = ugrab(8) * CARRIER_NOISE_RATIO_UNITS;
656
0
        }
657
0
#undef R1010
658
0
        unknown = false;
659
0
        break;
660
661
0
    case 1011:
662
0
        msg_name = "GLONASS Basic RTK, L1 & L2";
663
0
        rtcm->rtcmtypes.rtcm3_1011.header.station_id =
664
0
            (unsigned short)ugrab(12);
665
0
        rtcm->rtcmtypes.rtcm3_1011.header.tow = ugrab(27);
666
0
        rtcm->rtcmtypes.rtcm3_1011.header.sync = (bool)ugrab(1);
667
0
        rtcm->rtcmtypes.rtcm3_1011.header.satcount = (unsigned short)ugrab(5);
668
0
        rtcm->rtcmtypes.rtcm3_1011.header.smoothing = (bool)ugrab(1);
669
0
        rtcm->rtcmtypes.rtcm3_1011.header.interval = (unsigned short)ugrab(3);
670
0
#define R1011 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i]
671
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_1011.header.satcount; i++) {
672
0
            R1011.ident = (unsigned short)ugrab(6);
673
0
            R1011.L1.indicator = (bool)ugrab(1);
674
0
            R1011.L1.channel = (short)ugrab(5) - GLONASS_CHANNEL_BASE;
675
0
            R1011.L1.pseudorange = ugrab(25) * GLONASS_PSEUDORANGE_RESOLUTION;
676
0
            RANGEDIFF(R1011.L1, 20);
677
0
            R1011.L1.locktime = (unsigned char)sgrab(7);
678
0
            R1011.L1.ambiguity = (unsigned char)ugrab(7);
679
0
            R1011.L1.CNR = ugrab(8) * CARRIER_NOISE_RATIO_UNITS;
680
0
            R1011.L2.indicator = (bool)ugrab(1);
681
0
            R1011.L2.channel = (short)ugrab(5) - GLONASS_CHANNEL_BASE;
682
0
            R1011.L2.pseudorange = ugrab(25) * GLONASS_PSEUDORANGE_RESOLUTION;
683
0
            RANGEDIFF(R1011.L2, 20);
684
0
            R1011.L2.locktime = (unsigned char)sgrab(7);
685
0
            R1011.L2.ambiguity = (unsigned char)ugrab(7);
686
0
            R1011.L2.CNR = ugrab(8) * CARRIER_NOISE_RATIO_UNITS;
687
0
        }
688
0
#undef R1011
689
0
        unknown = false;
690
0
        break;
691
692
0
    case 1012:
693
0
        msg_name = "GLONASS Extended RTK, L1 & L2";
694
0
        rtcm->rtcmtypes.rtcm3_1012.header.station_id =
695
0
            (unsigned short)ugrab(12);
696
0
        rtcm->rtcmtypes.rtcm3_1012.header.tow = ugrab(27);
697
0
        rtcm->rtcmtypes.rtcm3_1012.header.sync = (bool)ugrab(1);
698
0
        rtcm->rtcmtypes.rtcm3_1012.header.satcount = (unsigned short)ugrab(5);
699
0
        rtcm->rtcmtypes.rtcm3_1012.header.smoothing = (bool)ugrab(1);
700
0
        rtcm->rtcmtypes.rtcm3_1012.header.interval = (unsigned short)ugrab(3);
701
0
#define R1012 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i]
702
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_1012.header.satcount; i++) {
703
0
            unsigned rangeincr;
704
705
0
            R1012.ident = (unsigned short)ugrab(6);
706
0
            R1012.L1.indicator = (bool)ugrab(1);
707
0
            R1012.L1.channel = (short)ugrab(5) - GLONASS_CHANNEL_BASE;
708
0
            R1012.L1.pseudorange = ugrab(25) * GLONASS_PSEUDORANGE_RESOLUTION;
709
0
            RANGEDIFF(R1012.L1, 20);
710
0
            R1012.L1.locktime = (unsigned char)ugrab(7);
711
0
            R1012.L1.ambiguity = (unsigned char)ugrab(7);
712
0
            R1012.L1.CNR = (unsigned char)ugrab(8) * CARRIER_NOISE_RATIO_UNITS;
713
0
            R1012.L2.indicator = (bool)ugrab(2);
714
0
            rangeincr = ugrab(14);
715
0
            if (rangeincr == GLONASS_INVALID_RANGEINCR) {
716
0
                R1012.L2.pseudorange = 0;
717
0
            } else {
718
0
                R1012.L2.pseudorange = (rangeincr *
719
0
                                        GLONASS_PSEUDORANGE_RESOLUTION);
720
0
            }
721
0
            RANGEDIFF(R1012.L2, 20);
722
0
            R1012.L2.locktime = (unsigned char)sgrab(7);
723
0
            R1012.L2.CNR = (unsigned char)ugrab(8) * CARRIER_NOISE_RATIO_UNITS;
724
0
        }
725
0
#undef R1012
726
0
        unknown = false;
727
0
        break;
728
729
0
    case 1013:
730
0
        msg_name = "System Parameters";
731
0
        rtcm->rtcmtypes.rtcm3_1013.station_id = (unsigned short)ugrab(12);
732
0
        rtcm->rtcmtypes.rtcm3_1013.mjd = (unsigned short)ugrab(16);
733
0
        rtcm->rtcmtypes.rtcm3_1013.sod = (unsigned short)ugrab(17);
734
0
        rtcm->rtcmtypes.rtcm3_1013.ncount = (unsigned long)ugrab(5);
735
0
        rtcm->rtcmtypes.rtcm3_1013.leapsecs = (unsigned char)ugrab(8);
736
0
#define R1013 rtcm->rtcmtypes.rtcm3_1013.announcements[i]
737
0
        for (i = 0; i < rtcm->rtcmtypes.rtcm3_1013.ncount; i++) {
738
0
            R1013.id = (unsigned short)ugrab(12);
739
0
            R1013.sync = (bool)ugrab(1);
740
0
            R1013.interval = (unsigned short)ugrab(16);
741
0
        }
742
0
#undef R1013
743
0
        unknown = false;
744
0
        break;
745
746
0
    case 1014:
747
0
        msg_name = "Network Auxiliary Station Data";
748
        // coordinate difference between one Aux station and master station
749
0
        rtcm->rtcmtypes.rtcm3_1014.network_id = (int)ugrab(8);
750
0
        rtcm->rtcmtypes.rtcm3_1014.subnetwork_id = (int)ugrab(4);
751
0
        rtcm->rtcmtypes.rtcm3_1014.stationcount = (char)ugrab(5);
752
0
        rtcm->rtcmtypes.rtcm3_1014.master_id = (int)ugrab(12);
753
0
        rtcm->rtcmtypes.rtcm3_1014.aux_id = (int)ugrab(12);
754
0
        rtcm->rtcmtypes.rtcm3_1014.d_lat =
755
0
            (unsigned short)ugrab(20) * ANTENNA_DEGREE_RESOLUTION;
756
0
        rtcm->rtcmtypes.rtcm3_1014.d_lon =
757
0
            (unsigned short)ugrab(21) * ANTENNA_DEGREE_RESOLUTION;
758
0
        rtcm->rtcmtypes.rtcm3_1014.d_alt = (unsigned short)ugrab(23) / 1000;
759
0
        unknown = false;
760
0
        break;
761
762
0
    case 1015:
763
        /* RTCM 3.1
764
         * GPS Ionospheric Correction Differences for all satellites
765
         * between the master station and one auxiliary station
766
         * 9 bytes minimum
767
         */
768
0
        unknown = rtcm3_101567(context, rtcm, buf);
769
0
        msg_name = "GPS Ionospheric Correction Differences";
770
0
        break;
771
772
0
    case 1016:
773
        /* RTCM 3.1
774
         * GPS Geometric Correction Differences for all satellites between
775
         * the master station and one auxiliary station.
776
         * 9 bytes minimum
777
         */
778
0
        unknown = rtcm3_101567(context, rtcm, buf);
779
0
        msg_name = "GPS Geometric Correction Differences";
780
0
        break;
781
782
0
    case 1017:
783
        /* RTCM 3.1
784
         * GPS Combined Geometric and Ionospheric Correction Differences
785
         * for all satellites between one Aux station and the master station
786
         * (same content as both types 1015 and 1016 together, but less size)
787
         * 9 bytes minimum
788
         */
789
0
        unknown = rtcm3_101567(context, rtcm, buf);
790
0
        msg_name = "GPS Combined Geometric and Ionospheric "
791
0
                       "Correction Differences";
792
0
        break;
793
794
0
    case 1018:
795
        /* RTCM 3.1
796
         * Reserved for alternative Ionospheric Correction Difference Message
797
         */
798
0
        msg_name = "Reserved for alternative Ionospheric Correction "
799
0
                       "Differences";
800
0
        break;
801
802
0
    case 1019:
803
        /* RTCM 3.1 - 1020
804
         * GPS Ephemeris
805
         * 62 bytes
806
         */
807
        // TODO: rtklib has C code for this one.
808
0
        msg_name = "GPS Ephemeris";
809
0
        break;
810
811
0
    case 1020:
812
        /* RTCM 3.1 - 1020
813
         * GLONASS Ephemeris
814
         * 45 bytes
815
         */
816
        // TODO: rtklib has C code for this one.
817
0
        msg_name = "GLO Ephemeris";
818
0
        break;
819
820
0
    case 1021:
821
        /* RTCM 3.1
822
         * Helmert / Abridged Molodenski Transformation parameters
823
         */
824
0
        msg_name = "Helmert / Abridged Molodenski Transformation "
825
0
                       "parameters";
826
        // Set Source-Name
827
0
        n = (unsigned)ugrab(5);
828
0
        if ((sizeof(rtcm->rtcmtypes.rtcm3_1021.src_name) -1) <= n) {
829
            // paranoia
830
0
            n = sizeof(rtcm->rtcmtypes.rtcm3_1021.src_name) - 1;
831
0
        }
832
0
        for (i = 0; i < n; i++) {
833
0
            rtcm->rtcmtypes.rtcm3_1021.src_name[i] = (char)ugrab(8);
834
0
        }
835
0
        rtcm->rtcmtypes.rtcm3_1021.src_name[n] = '\0';
836
        // Set Target-Name
837
0
        n2 = (unsigned)ugrab(5);
838
0
        if ((sizeof(rtcm->rtcmtypes.rtcm3_1021.tar_name) - 1) <= n2) {
839
            // paranoia
840
0
            n2 = sizeof(rtcm->rtcmtypes.rtcm3_1021.tar_name) - 1;
841
0
        }
842
0
        for (i = 0; i < n2; i++) {
843
0
            rtcm->rtcmtypes.rtcm3_1021.tar_name[i] = (char)ugrab(8);
844
0
        }
845
0
        rtcm->rtcmtypes.rtcm3_1021.tar_name[n2] = '\0';
846
0
        rtcm->rtcmtypes.rtcm3_1021.sys_id_num = (unsigned)ugrab(8);
847
0
#define R1021 rtcm->rtcmtypes.rtcm3_1021.ut_tr_msg_id[i]
848
0
        for (i = 0; i < RTCM3_DF148_SIZE; i++) {
849
0
            R1021 = (bool)ugrab(1);
850
0
        }
851
0
#undef R1021
852
0
        rtcm->rtcmtypes.rtcm3_1021.plate_number = (unsigned)ugrab(5);
853
0
        rtcm->rtcmtypes.rtcm3_1021.computation_id = (unsigned)ugrab(4);
854
0
        rtcm->rtcmtypes.rtcm3_1021.height_id = (unsigned)ugrab(2);
855
0
        rtcm->rtcmtypes.rtcm3_1021.lat_origin = sgrab(19) *
856
0
            VALIDITY_RESOLUTION / DEG_ARCSEC_RESOLUTION;
857
0
        rtcm->rtcmtypes.rtcm3_1021.lon_origin = sgrab(20) *
858
0
            VALIDITY_RESOLUTION / DEG_ARCSEC_RESOLUTION;
859
0
        rtcm->rtcmtypes.rtcm3_1021.lat_extension = sgrab(14) *
860
0
            VALIDITY_RESOLUTION / DEG_ARCSEC_RESOLUTION;
861
0
        rtcm->rtcmtypes.rtcm3_1021.lon_extension = sgrab(14) *
862
0
            VALIDITY_RESOLUTION / DEG_ARCSEC_RESOLUTION;
863
0
        rtcm->rtcmtypes.rtcm3_1021.x_trans = sgrab(23) *
864
0
            TRANSLATION_MM_RESOLUTION;
865
0
        rtcm->rtcmtypes.rtcm3_1021.y_trans = sgrab(23) *
866
0
            TRANSLATION_MM_RESOLUTION;
867
0
        rtcm->rtcmtypes.rtcm3_1021.z_trans = sgrab(23) *
868
0
            TRANSLATION_MM_RESOLUTION;
869
0
        rtcm->rtcmtypes.rtcm3_1021.x_rot = sgrab(32) *
870
0
            ROTATION_ARCSEC_RESOLUTION / DEG_ARCSEC_RESOLUTION;
871
0
        rtcm->rtcmtypes.rtcm3_1021.y_rot = sgrab(32) *
872
0
            ROTATION_ARCSEC_RESOLUTION / DEG_ARCSEC_RESOLUTION;
873
0
        rtcm->rtcmtypes.rtcm3_1021.z_rot = sgrab(32) *
874
0
            ROTATION_ARCSEC_RESOLUTION / DEG_ARCSEC_RESOLUTION;
875
0
        rtcm->rtcmtypes.rtcm3_1021.ds = sgrab(25) * SCALE_PPM_RESOLUTION;
876
0
        rtcm->rtcmtypes.rtcm3_1021.add_as = sgrab(24) *
877
0
            TRANSLATION_MM_RESOLUTION;
878
0
        rtcm->rtcmtypes.rtcm3_1021.add_bs = sgrab(25) *
879
0
            TRANSLATION_MM_RESOLUTION;
880
0
        rtcm->rtcmtypes.rtcm3_1021.add_at = sgrab(24) *
881
0
            TRANSLATION_MM_RESOLUTION;
882
0
        rtcm->rtcmtypes.rtcm3_1021.add_bt = sgrab(25) *
883
0
            TRANSLATION_MM_RESOLUTION;
884
0
        rtcm->rtcmtypes.rtcm3_1021.quality_hori = (unsigned)ugrab(3);
885
0
        rtcm->rtcmtypes.rtcm3_1021.quality_vert = (unsigned)ugrab(3);
886
887
0
        unknown = false;
888
0
        break;
889
890
0
    case 1022:
891
        /* RTCM 3.1
892
         * Molodenski-Badekas transformation parameters
893
         */
894
0
        msg_name = "Molodenski-Badekas transformation parameters";
895
0
        break;
896
897
0
    case 1023:
898
        /* RTCM 3.1
899
         * Residuals Ellipsoidal Grid Representation
900
         */
901
0
        msg_name = "Residuals Ellipsoidal Grid Representation";
902
0
        rtcm->rtcmtypes.rtcm3_1023.sys_id_num = (unsigned)ugrab(8);
903
0
        rtcm->rtcmtypes.rtcm3_1023.shift_id_hori = (bool)ugrab(1);
904
0
        rtcm->rtcmtypes.rtcm3_1023.shift_id_vert = (bool)ugrab(1);
905
0
        rtcm->rtcmtypes.rtcm3_1023.lat_origin = sgrab(21) *
906
0
            PHASE_CORRECTION_RESOLUTION / DEG_ARCSEC_RESOLUTION;
907
0
        rtcm->rtcmtypes.rtcm3_1023.lon_origin = sgrab(22) *
908
0
            PHASE_CORRECTION_RESOLUTION / DEG_ARCSEC_RESOLUTION;
909
0
        rtcm->rtcmtypes.rtcm3_1023.lat_extension = (unsigned)ugrab(12) *
910
0
            PHASE_CORRECTION_RESOLUTION / DEG_ARCSEC_RESOLUTION;
911
0
        rtcm->rtcmtypes.rtcm3_1023.lon_extension = (unsigned)ugrab(12) *
912
0
            PHASE_CORRECTION_RESOLUTION / DEG_ARCSEC_RESOLUTION;
913
0
        rtcm->rtcmtypes.rtcm3_1023.lat_mean = sgrab(8) *
914
0
            TRANSLATION_MM_RESOLUTION;
915
0
        rtcm->rtcmtypes.rtcm3_1023.lon_mean = sgrab(8) *
916
0
            TRANSLATION_MM_RESOLUTION;
917
0
        rtcm->rtcmtypes.rtcm3_1023.hgt_mean = sgrab(15) * CM_RESOLUTION;
918
0
#define R1023 rtcm->rtcmtypes.rtcm3_1023.residuals[i]
919
0
        for (i = 0; i < RTCM3_GRID_SIZE; i++) {
920
0
            R1023.lat_res = sgrab(9) * RES_ARCSEC_RESOLUTION;
921
0
            R1023.lon_res = sgrab(9) * RES_ARCSEC_RESOLUTION;
922
0
            R1023.hgt_res = sgrab(9) * TRANSLATION_MM_RESOLUTION;
923
0
        }
924
0
#undef R1023
925
0
        rtcm->rtcmtypes.rtcm3_1023.interp_meth_id_hori = (unsigned)ugrab(2);
926
0
        rtcm->rtcmtypes.rtcm3_1023.interp_meth_id_vert = (unsigned)ugrab(2);
927
0
        rtcm->rtcmtypes.rtcm3_1023.grd_qual_id_hori = (unsigned)ugrab(3);
928
0
        rtcm->rtcmtypes.rtcm3_1023.grd_qual_id_vert = (unsigned)ugrab(3);
929
0
        rtcm->rtcmtypes.rtcm3_1023.mjd = (unsigned short)ugrab(16);
930
0
        unknown = false;
931
0
        break;
932
933
0
    case 1024:
934
        /* RTCM 3.1
935
         * Residuals Plane Grid Representation
936
         */
937
0
        msg_name = "Residuals Plane Grid Representation";
938
0
        break;
939
940
0
    case 1025:
941
        /* RTCM 3.1
942
         * Projection Parameters, Projection Types other than LCC2SP
943
         */
944
0
        msg_name = "Projection Parameters, Projection Types other "
945
0
                       "than LCC2SP";
946
0
        rtcm->rtcmtypes.rtcm3_1025.sys_id_num = (unsigned short)ugrab(8);
947
0
        rtcm->rtcmtypes.rtcm3_1025.projection_type = (unsigned short)ugrab(6);
948
0
        rtcm->rtcmtypes.rtcm3_1025.lat_origin = sgrab(34) *
949
0
            PROJ_ORIGIN_RESOLUTION;
950
0
        rtcm->rtcmtypes.rtcm3_1025.lon_origin = sgrab(35) *
951
0
            PROJ_ORIGIN_RESOLUTION;
952
0
        rtcm->rtcmtypes.rtcm3_1025.add_sno = (unsigned)ugrab(30) *
953
0
            SCALE_PPM_RESOLUTION;
954
0
        rtcm->rtcmtypes.rtcm3_1025.false_east = (unsigned)ugrab(36) *
955
0
            TRANSLATION_MM_RESOLUTION;
956
0
        rtcm->rtcmtypes.rtcm3_1025.false_north = ugrab(35) *
957
0
            TRANSLATION_MM_RESOLUTION;
958
0
        unknown = false;
959
0
        break;
960
961
0
    case 1026:
962
        /* RTCM 3.1
963
         * Projection Parameters, Projection Type LCC2SP
964
         * (Lambert Conic Conformal)
965
         */
966
0
        msg_name = "Projection Parameters, Projection Type LCC2SP";
967
0
        break;
968
969
0
    case 1027:
970
        /* RTCM 3.1
971
         * Projection Parameters, Projection Type OM (Oblique Mercator)
972
         */
973
0
        msg_name = "Projection Parameters, Projection Type OM";
974
0
        break;
975
976
0
    case 1028:
977
        /* RTCM 3.1
978
         * Reserved for global to plate fixed transformation
979
         */
980
0
        msg_name = "Reserved, Global to Plate Transformation";
981
0
        break;
982
983
0
    case 1029:
984
0
        msg_name = "Text in UTF8 format";
985
        /* 9 bytes minimum
986
         * (max. 127 multibyte characters and max. 255 bytes)
987
         */
988
0
        rtcm->rtcmtypes.rtcm3_1029.station_id = (unsigned short)ugrab(12);
989
0
        rtcm->rtcmtypes.rtcm3_1029.mjd = (unsigned short)ugrab(16);
990
0
        rtcm->rtcmtypes.rtcm3_1029.sod = (unsigned short)ugrab(17);
991
0
        rtcm->rtcmtypes.rtcm3_1029.len = (unsigned long)ugrab(7);
992
0
        rtcm->rtcmtypes.rtcm3_1029.unicode_units = (size_t)ugrab(8);
993
0
        (void)memcpy(rtcm->rtcmtypes.rtcm3_1029.text,
994
0
                     buf + 12, rtcm->rtcmtypes.rtcm3_1029.unicode_units);
995
0
        unknown = false;
996
0
        break;
997
998
0
    case 1030:
999
        /* RTCM 3.1
1000
         * GPS Network RTK Residual Message
1001
         */
1002
0
        msg_name = "GPS Network RTK Residual";
1003
0
        break;
1004
1005
0
    case 1031:
1006
        /* RTCM 3.1
1007
         * GLONASS Network RTK Residual Message
1008
         */
1009
0
        msg_name = "GLONASS Network RTK Residual";
1010
0
        break;
1011
1012
0
    case 1032:
1013
        /* RTCM 3.1
1014
         * Physical Reference Station Position message
1015
         */
1016
0
        msg_name = "Physical Reference Station Position";
1017
0
        break;
1018
1019
0
    case 1033:                  // see note in header
1020
0
        msg_name ="Receiver and Antenna Descriptor";
1021
        /* Type1033 is a combined Message Types 1007 and 1008
1022
         * and hence contains antenna descriptor and serial number
1023
         * as well as receiver descriptor and serial number.
1024
         */
1025
        // TODO: rtklib has C code for this one.
1026
0
        rtcm->rtcmtypes.rtcm3_1033.station_id = (unsigned short)ugrab(12);
1027
0
        n = (unsigned long)ugrab(8);
1028
0
        (void)memcpy(rtcm->rtcmtypes.rtcm3_1033.descriptor, buf + 7, n);
1029
0
        rtcm->rtcmtypes.rtcm3_1033.descriptor[n] = '\0';
1030
0
        bitcount += 8 * n;
1031
0
        rtcm->rtcmtypes.rtcm3_1033.setup_id = ugrab(8);
1032
0
        n2 = (unsigned long)ugrab(8);
1033
0
        (void)memcpy(rtcm->rtcmtypes.rtcm3_1033.serial, buf + 9 + n, n2);
1034
0
        rtcm->rtcmtypes.rtcm3_1033.serial[n2] = '\0';
1035
0
        bitcount += 8 * n2;
1036
0
        n3 = (unsigned long)ugrab(8);
1037
0
        (void)memcpy(rtcm->rtcmtypes.rtcm3_1033.receiver, buf + 10+n+n2, n3);
1038
0
        rtcm->rtcmtypes.rtcm3_1033.receiver[n3] = '\0';
1039
0
        bitcount += 8 * n3;
1040
0
        n4 = (unsigned long)ugrab(8);
1041
0
        (void)memcpy(rtcm->rtcmtypes.rtcm3_1033.firmware, buf + 11+n+n2+n3, n3);
1042
0
        rtcm->rtcmtypes.rtcm3_1033.firmware[n4] = '\0';
1043
        // bitcount += 8 * n4;
1044
        // TODO: next is receiver serial number
1045
0
        unknown = false;
1046
0
        break;
1047
1048
0
    case 1034:
1049
        /* RTCM 3.2
1050
         * GPS Network FKP Gradient Message
1051
         */
1052
0
        msg_name = "GPS Network FKP Gradient";
1053
0
        break;
1054
1055
0
    case 1035:
1056
        /* RTCM 3.2
1057
         * GLONASS Network FKP Gradient Message
1058
         */
1059
0
        msg_name = "GLO Network FKP Gradient";
1060
0
        break;
1061
1062
0
    case 1037:
1063
        /* RTCM 3.2
1064
         * GLONASS Ionospheric Correction Differences
1065
         */
1066
0
        msg_name = "GLO Ionospheric Correction Differences";
1067
0
        break;
1068
1069
0
    case 1038:
1070
        /* RTCM 3.2
1071
         * GLONASS Geometric Correction Differences
1072
         */
1073
0
        msg_name = "GLO Geometric Correction Differences";
1074
0
        break;
1075
1076
0
    case 1039:
1077
        /* RTCM 3.2
1078
         * GLONASS Combined Geometric and Ionospheric Correction Differences
1079
         */
1080
0
        msg_name = "GLONASS Combined Geometric and Ionospheric "
1081
0
                       "Correction Differences";
1082
0
        break;
1083
1084
0
    case 1042:
1085
        /* RTCM 3.x - 1043
1086
         * BeiDou Ephemeris
1087
         * length ?
1088
         */
1089
0
        msg_name = "BD Ephemeris";
1090
0
        break;
1091
1092
0
    case 1043:
1093
        /* RTCM 3.x - 1043
1094
         * SBAS Ephemeris
1095
         * length 29
1096
         */
1097
0
        msg_name = "SBAS Ephemeris";
1098
0
        break;
1099
1100
0
    case 1044:
1101
        /* RTCM 3.x - 1044
1102
         * QZSS ephemeris
1103
         * length 61
1104
         */
1105
        // TODO: rtklib has C code for this one.
1106
0
        msg_name = "QZSS Ephemeris";
1107
0
        break;
1108
1109
0
    case 1045:
1110
        /* RTCM 3.2 - 1045
1111
         * Galileo F/NAV Ephemeris Data
1112
         * 64 bytes
1113
         */
1114
        // TODO: rtklib has C code for this one.
1115
0
        msg_name = "GAL F/NAV Ephemeris Data";
1116
0
        break;
1117
1118
0
    case 1046:
1119
        /* RTCM 3.x - 1046
1120
         * Galileo I/NAV Ephemeris Data
1121
         * length 63
1122
         */
1123
        // TODO: rtklib has C code for this one.
1124
0
        msg_name = "GAL I/NAV Ephemeris Data";
1125
0
        break;
1126
1127
0
    case 1057:
1128
        /* RTCM 3.2
1129
         * SSR GPS Orbit Correction
1130
         */
1131
0
        msg_name = "SSR GPS Orbit Correction";
1132
0
        break;
1133
1134
0
    case 1058:
1135
        /* RTCM 3.2
1136
         * SSR GPS Clock Correction
1137
         */
1138
0
        msg_name = "SSR GPS Clock Correction";
1139
0
        break;
1140
1141
0
    case 1059:
1142
        /* RTCM 3.2
1143
         * SSR GPS Code Bias
1144
         */
1145
0
        msg_name = "SSR GPS Code Bias";
1146
0
        break;
1147
1148
0
    case 1060:
1149
        /* RTCM 3.2
1150
         * SSR GPS Combined Orbit and Clock Correction
1151
         */
1152
0
        msg_name = "SSR GPS Combined Orbit and Clock Correction";
1153
0
        break;
1154
1155
0
    case 1061:
1156
        /* RTCM 3.2
1157
         * SSR GPS URA
1158
         */
1159
0
        msg_name = "SSR GPS URA";
1160
0
        break;
1161
1162
0
    case 1062:
1163
        /* RTCM 3.2
1164
         * SSR GPS High Rate Clock Correction
1165
         */
1166
0
        msg_name = "SSR GPS High Rate Clock Correction";
1167
0
        break;
1168
1169
0
    case 1063:
1170
        /* RTCM 3.2
1171
         * SSR GLO Orbit Correction
1172
         */
1173
0
        msg_name = "SSR GLO Orbit Correction";
1174
0
        break;
1175
1176
0
    case 1064:
1177
        /* RTCM 3.2
1178
         * SSR GLO Clock Correction
1179
         */
1180
0
        msg_name = "SSR GLO Clock Correction";
1181
0
        break;
1182
1183
0
    case 1065:
1184
        /* RTCM 3.2
1185
         * SSR GLO Code Correction
1186
         */
1187
0
        msg_name = "SSR GLO ode Correction";
1188
0
        break;
1189
1190
0
    case 1066:
1191
        /* RTCM 3.2
1192
         * SSR GLO Combined Orbit and Clock Correction
1193
         */
1194
0
        msg_name = "SSR GLO Combined Orbit and Clock Correction";
1195
0
        break;
1196
1197
0
    case 1067:
1198
        /* RTCM 3.2
1199
         * SSR GLO URA
1200
         */
1201
0
        msg_name = "SSR GLO URA";
1202
0
        break;
1203
1204
0
    case 1068:
1205
        /* RTCM 3.2
1206
         * SSR GPS High Rate Clock Correction
1207
         */
1208
0
        msg_name = "SSR GLO High Rate Clock Correction";
1209
0
        break;
1210
1211
0
    case 1070:
1212
        /* RTCM 3.x
1213
         * Reserved for MSM
1214
         */
1215
0
        msg_name = "Reserved for MSM";
1216
0
        break;
1217
1218
0
    case 1071:
1219
        // RTCM 3.2
1220
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GPS;
1221
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 1;
1222
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1223
0
        msg_name = "GPS MSM 1";
1224
0
        break;
1225
1226
0
    case 1072:
1227
        // RTCM 3.2
1228
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GPS;
1229
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 2;
1230
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1231
0
        msg_name = "GPS MSM 2";
1232
0
        break;
1233
1234
0
    case 1073:
1235
        /* RTCM 3.2
1236
         * GPS Multi Signal Message 3
1237
         */
1238
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GPS;
1239
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 3;
1240
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1241
0
        msg_name = "GPS MSM 3";
1242
0
        break;
1243
1244
0
    case 1074:
1245
        /* RTCM 3.2
1246
         * GPS Multi Signal Message 4
1247
         */
1248
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GPS;
1249
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 4;
1250
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1251
0
        msg_name = "GPS MSM 4";
1252
0
        break;
1253
1254
0
    case 1075:
1255
        /* RTCM 3.2
1256
         * GPS Multi Signal Message 5
1257
         */
1258
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GPS;
1259
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 5;
1260
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1261
0
        msg_name = "GPS MSM 5";
1262
0
        break;
1263
1264
0
    case 1076:
1265
        /* RTCM 3.2
1266
         * GPS Multi Signal Message 6
1267
         */
1268
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GPS;
1269
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 6;
1270
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1271
0
        msg_name = "GPS MSM 6";
1272
0
        break;
1273
1274
0
    case 1077:
1275
        /* RTCM 3.2 - 1077
1276
         * GPS Multi Signal Message 7
1277
         * Full GPS pseudo-ranges, carrier phases, Doppler and
1278
         * signal strength (high resolution)
1279
         * min length 438
1280
         */
1281
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GPS;
1282
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 7;
1283
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1284
0
        msg_name = "GPS MSM7";
1285
0
        break;
1286
1287
0
    case 1078:
1288
        /* RTCM 3.x
1289
         * Reserved for MSM
1290
         */
1291
0
        msg_name = "Reserved for MSM";
1292
0
        break;
1293
1294
0
    case 1079:
1295
        /* RTCM 3.x
1296
         * Reserved for MSM
1297
         */
1298
0
        msg_name = "Reserved for MSM";
1299
0
        break;
1300
1301
0
    case 1080:
1302
        /* RTCM 3.x
1303
         * Reserved for MSM
1304
         */
1305
0
        msg_name = "Reserved for MSM";
1306
0
        break;
1307
1308
0
    case 1081:
1309
        /* RTCM 3.2
1310
         * GLONASS Multi Signal Message 1
1311
         */
1312
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GLO;
1313
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 1;
1314
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1315
0
        msg_name = "GLO MSM 1";
1316
0
        break;
1317
1318
0
    case 1082:
1319
        /* RTCM 3.2
1320
         * GLONASS Multi Signal Message 2
1321
         */
1322
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GLO;
1323
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 2;
1324
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1325
0
        msg_name = "GLO MSM 2";
1326
0
        break;
1327
1328
0
    case 1083:
1329
        /* RTCM 3.2
1330
         * GLONASS Multi Signal Message 4
1331
         */
1332
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GLO;
1333
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 3;
1334
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1335
0
        msg_name = "GLO MSM 3";
1336
0
        break;
1337
1338
0
    case 1084:
1339
        /* RTCM 3.2
1340
         * GLONASS Multi Signal Message 4
1341
         */
1342
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GLO;
1343
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 4;
1344
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1345
0
        msg_name = "GLO MSM 4";
1346
0
        break;
1347
1348
0
    case 1085:
1349
        /* RTCM 3.2
1350
         * GLONASS Multi Signal Message 5
1351
         */
1352
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GLO;
1353
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 5;
1354
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1355
0
        msg_name = "GLO MSM 5";
1356
0
        break;
1357
1358
0
    case 1086:
1359
        /* RTCM 3.2
1360
         * GLONASS Multi Signal Message 6
1361
         */
1362
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GLO;
1363
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 6;
1364
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1365
0
        msg_name = "GLO MSM 6";
1366
0
        break;
1367
1368
0
    case 1087:
1369
        /* RTCM 3.2 - 1087
1370
         * GLONASS Multi Signal Message 7
1371
         * Full GLONASS pseudo-ranges, carrier phases, Doppler and
1372
         * signal strength (high resolution)
1373
         * length 417 or 427
1374
         */
1375
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GLO;
1376
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 7;
1377
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1378
0
        msg_name = "GLO MSM 7";
1379
0
        break;
1380
1381
0
    case 1088:
1382
        /* RTCM 3.x
1383
         * Reserved for MSM
1384
         */
1385
0
        msg_name = "Reserved for MSM";
1386
0
        break;
1387
1388
0
    case 1089:
1389
        /* RTCM 3.x
1390
         * Reserved for MSM
1391
         */
1392
0
        msg_name = "Reserved for MSM";
1393
0
        break;
1394
1395
0
    case 1090:
1396
        /* RTCM 3.x
1397
         * Reserved for MSM
1398
         */
1399
0
        msg_name = "Reserved for MSM";
1400
0
        break;
1401
1402
0
    case 1091:
1403
        /* RTCM 3.2
1404
         * Galileo Multi Signal Message 1
1405
         */
1406
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GAL;
1407
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 1;
1408
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1409
0
        msg_name = "GAL MSM 1";
1410
0
        break;
1411
1412
0
    case 1092:
1413
        /* RTCM 3.2
1414
         * Galileo Multi Signal Message 2
1415
         */
1416
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GAL;
1417
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 2;
1418
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1419
0
        msg_name = "GAL MSM 2";
1420
0
        break;
1421
1422
0
    case 1093:
1423
        /* RTCM 3.2
1424
         * Galileo Multi Signal Message 3
1425
         */
1426
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GAL;
1427
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 3;
1428
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1429
0
        msg_name = "GAL MSM 3";
1430
0
        break;
1431
1432
0
    case 1094:
1433
        /* RTCM 3.2
1434
         * Galileo Multi Signal Message 4
1435
         */
1436
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GAL;
1437
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 4;
1438
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1439
0
        msg_name = "GAL MSM 4";
1440
0
        break;
1441
1442
0
    case 1095:
1443
        /* RTCM 3.2
1444
         * Galileo Multi Signal Message 5
1445
         */
1446
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GAL;
1447
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 5;
1448
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1449
0
        msg_name = "GAL MSM 5";
1450
0
        break;
1451
1452
0
    case 1096:
1453
        /* RTCM 3.2
1454
         * Galileo Multi Signal Message 6
1455
         */
1456
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GAL;
1457
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 6;
1458
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1459
0
        msg_name = "GAL MSM 6";
1460
0
        break;
1461
1462
0
    case 1097:
1463
        /* RTCM 3.2 - 1097
1464
         * Galileo Multi Signal Message 7
1465
         * Full Galileo pseudo-ranges, carrier phases, Doppler and
1466
         * signal strength (high resolution)
1467
         * length 96
1468
         */
1469
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_GAL;
1470
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 7;
1471
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1472
0
        msg_name = "GAL MSM 7";
1473
0
        break;
1474
1475
0
    case 1098:
1476
        /* RTCM 3.x
1477
         * Reserved for MSM
1478
         */
1479
0
        msg_name = "Reserved for MSM";
1480
0
        break;
1481
1482
0
    case 1099:
1483
        /* RTCM 3.x
1484
         * Reserved for MSM
1485
         */
1486
0
        msg_name = "Reserved for MSM";
1487
0
        break;
1488
1489
0
    case 1100:
1490
        /* RTCM 3.x
1491
         * Reserved for MSM
1492
         */
1493
0
        msg_name = "Reserved for MSM";
1494
0
        break;
1495
1496
0
    case 1101:
1497
        /* RTCM 3.3
1498
         * SBAS Multi Signal Message 1
1499
         */
1500
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_SBAS;
1501
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 1;
1502
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1503
0
        msg_name = "SBAS MSM 1";
1504
0
        break;
1505
1506
0
    case 1102:
1507
        /* RTCM 3.3
1508
         * SBAS Multi Signal Message 2
1509
         */
1510
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_SBAS;
1511
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 2;
1512
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1513
0
        msg_name = "SBAS MSM 2";
1514
0
        break;
1515
1516
0
    case 1103:
1517
        /* RTCM 3.3
1518
         * SBAS Multi Signal Message 3
1519
         */
1520
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_SBAS;
1521
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 3;
1522
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1523
0
        msg_name = "SBAS MSM 3";
1524
0
        break;
1525
1526
0
    case 1104:
1527
        /* RTCM 3.3
1528
         * SBAS Multi Signal Message 4
1529
         */
1530
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_SBAS;
1531
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 4;
1532
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1533
0
        msg_name = "SBAS MSM 4";
1534
0
        break;
1535
1536
0
    case 1105:
1537
        /* RTCM 3.3
1538
         * SBAS Multi Signal Message 5
1539
         */
1540
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_SBAS;
1541
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 5;
1542
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1543
0
        msg_name = "SBAS MSM 5";
1544
0
        break;
1545
1546
0
    case 1106:
1547
        /* RTCM 3.3
1548
         * SBAS Multi Signal Message 6
1549
         */
1550
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_SBAS;
1551
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 6;
1552
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1553
0
        msg_name = "SBAS MSM 6";
1554
0
        break;
1555
1556
0
    case 1107:
1557
        /* RTCM 3.3 - 1107
1558
         * 'Multiple Signal Message
1559
         * Full SBAS pseudo-ranges, carrier phases, Doppler and
1560
         * signal strength (high resolution)
1561
         * length 96
1562
         */
1563
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_SBAS;
1564
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 7;
1565
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1566
0
        msg_name = "SBAS MSM 7";
1567
0
        break;
1568
1569
0
    case 1108:
1570
        /* RTCM 3.x
1571
         * Reserved for MSM
1572
         */
1573
0
        msg_name = "Reserved for MSM";
1574
0
        break;
1575
1576
0
    case 1109:
1577
        /* RTCM 3.x
1578
         * Reserved for MSM
1579
         */
1580
0
        msg_name = "Reserved for MSM";
1581
0
        break;
1582
1583
0
    case 1110:
1584
        /* RTCM 3.x
1585
         * Reserved for MSM
1586
         */
1587
0
        msg_name = "Reserved for MSM";
1588
0
        break;
1589
1590
0
    case 1111:
1591
        /* RTCM 3.3
1592
         * QZSS Multi Signal Message 1
1593
         */
1594
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_QZSS;
1595
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 1;
1596
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1597
0
        msg_name = "QZSS MSM 1";
1598
0
        break;
1599
1600
0
    case 1112:
1601
        /* RTCM 3.3
1602
         * QZSS Multi Signal Message 2
1603
         */
1604
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_QZSS;
1605
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 2;
1606
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1607
0
        msg_name = "QZSS MSM 2";
1608
0
        break;
1609
1610
0
    case 1113:
1611
        /* RTCM 3.3
1612
         * QZSS Multi Signal Message 3
1613
         */
1614
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_QZSS;
1615
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 3;
1616
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1617
0
        msg_name = "QZSS MSM 3";
1618
0
        break;
1619
1620
0
    case 1114:
1621
        /* RTCM 3.3
1622
         * QZSS Multi Signal Message 4
1623
         */
1624
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_QZSS;
1625
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 4;
1626
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1627
0
        msg_name = "QZSS MSM 4";
1628
0
        break;
1629
1630
0
    case 1115:
1631
        /* RTCM 3.3
1632
         * QZSS Multi Signal Message 5
1633
         */
1634
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_QZSS;
1635
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 5;
1636
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1637
0
        msg_name = "QZSS MSM 5";
1638
0
        break;
1639
1640
0
    case 1116:
1641
        /* RTCM 3.3
1642
         * QZSS Multi Signal Message 6
1643
         */
1644
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_QZSS;
1645
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 6;
1646
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1647
0
        msg_name = "QZSS MSM 6";
1648
0
        break;
1649
1650
0
    case 1117:
1651
        /* RTCM 3.3
1652
         * QZSS Multi Signal Message 7
1653
         */
1654
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_QZSS;
1655
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 7;
1656
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1657
0
        msg_name = "QZSS MSM 7";
1658
0
        break;
1659
1660
0
    case 1118:
1661
        /* RTCM 3.x
1662
         * Reserved for MSM
1663
         */
1664
0
        msg_name = "Reserved for MSM";
1665
0
        break;
1666
1667
0
    case 1119:
1668
        /* RTCM 3.x
1669
         * Reserved for MSM
1670
         */
1671
0
        msg_name = "Reserved for MSM";
1672
0
        break;
1673
1674
0
    case 1120:
1675
        /* RTCM 3.x
1676
         * Reserved for MSM
1677
         */
1678
0
        msg_name = "Reserved for MSM";
1679
0
        break;
1680
1681
0
    case 1121:
1682
        /* RTCM 3.2 A.1
1683
         * BD Multi Signal Message 1
1684
         */
1685
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_BD;
1686
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 1;
1687
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1688
0
        msg_name = "BD MSM 1";
1689
0
        break;
1690
1691
0
    case 1122:
1692
        /* RTCM 3.2 A.1
1693
         * BD Multi Signal Message 2
1694
         */
1695
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_BD;
1696
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 2;
1697
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1698
0
        msg_name = "BD MSM 2";
1699
0
        break;
1700
1701
0
    case 1123:
1702
        /* RTCM 3.2 A.1
1703
         * BD Multi Signal Message 3
1704
         */
1705
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_BD;
1706
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 3;
1707
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1708
0
        msg_name = "BD MSM 3";
1709
0
        break;
1710
1711
0
    case 1124:
1712
        /* RTCM 3.2 A.1
1713
         * BD Multi Signal Message 4
1714
         */
1715
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_BD;
1716
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 4;
1717
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1718
0
        msg_name = "BD MSM 4";
1719
0
        break;
1720
1721
0
    case 1125:
1722
        /* RTCM 3.2 A.1
1723
         * BeiDou Multi Signal Message 5
1724
         */
1725
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_BD;
1726
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 5;
1727
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1728
0
        msg_name = "BD MSM 5";
1729
0
        break;
1730
1731
0
    case 1126:
1732
        /* RTCM 3.2 A.1
1733
         * BeiDou Multi Signal Message 6
1734
         */
1735
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_BD;
1736
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 6;
1737
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1738
0
        msg_name = "BD MSM 6";
1739
0
        break;
1740
1741
0
    case 1127:
1742
        /* RTCM 3.2 A.1
1743
         * BeiDou Multi Signal Message 7
1744
         */
1745
0
        rtcm->rtcmtypes.rtcm3_msm.gnssid = GNSSID_BD;
1746
0
        rtcm->rtcmtypes.rtcm3_msm.msm = 7;
1747
0
        unknown = rtcm3_decode_msm(context, rtcm, buf);
1748
0
        msg_name = "BD MSM 7";
1749
0
        break;
1750
1751
0
    case 1128:
1752
        /* RTCM 3.x
1753
         * Reserved for MSM
1754
         */
1755
0
        msg_name = "Reserved for MSM";
1756
0
        break;
1757
1758
0
    case 1229:
1759
        /* RTCM 3.x
1760
         * Reserved for MSM
1761
         */
1762
0
        msg_name = "Reserved for MSM";
1763
0
        break;
1764
1765
0
    case 1230:
1766
        /* RTCM 3.2
1767
         * GLONASS L1 and L2, C/A and P, Code-Phase Biases.
1768
         */
1769
0
        msg_name = "GLO L1 and L2 Code-Phase Biases";
1770
0
        unknown = false;
1771
0
        rtcm->rtcmtypes.rtcm3_1230.station_id = (unsigned short)ugrab(12);
1772
0
        rtcm->rtcmtypes.rtcm3_1230.bias_indicator = (unsigned char)ugrab(1);
1773
0
        (void)ugrab(1);         // reserved
1774
0
        rtcm->rtcmtypes.rtcm3_1230.signals_mask = (unsigned char)ugrab(3);
1775
        // actual mask order is undocumented...
1776
0
        if (1 & rtcm->rtcmtypes.rtcm3_1230.signals_mask) {
1777
0
            rtcm->rtcmtypes.rtcm3_1230.l1_ca_bias = ugrab(16);
1778
0
        }
1779
0
        if (2 & rtcm->rtcmtypes.rtcm3_1230.signals_mask) {
1780
0
            rtcm->rtcmtypes.rtcm3_1230.l1_p_bias = ugrab(16);
1781
0
        }
1782
0
        if (4 & rtcm->rtcmtypes.rtcm3_1230.signals_mask) {
1783
0
            rtcm->rtcmtypes.rtcm3_1230.l2_ca_bias = ugrab(16);
1784
0
        }
1785
0
        if (8 & rtcm->rtcmtypes.rtcm3_1230.signals_mask) {
1786
0
            rtcm->rtcmtypes.rtcm3_1230.l2_p_bias = ugrab(16);
1787
0
        }
1788
0
        break;
1789
1790
    // Message Types 4001 — 4060 Are Reserved
1791
1792
0
    case 4062:
1793
        /* RTCM 3.3
1794
         * Geely Proprietary
1795
         */
1796
0
        msg_name = "Geely Proprietary";
1797
0
        break;
1798
1799
0
    case 4063:
1800
        /* RTCM 3.3
1801
         * CHC Navigation (CHCNAV) Proprietary
1802
         */
1803
0
        msg_name = "CHC Navigation (CHCNAV) Proprietary";
1804
0
        break;
1805
1806
0
    case 4064:
1807
        /* RTCM 3.3
1808
         * NTLab Proprietary
1809
         */
1810
0
        msg_name = "NTLab Proprietary";
1811
0
        break;
1812
1813
0
    case 4065:
1814
        /* RTCM 3.3
1815
         * Allystar Technology (Shenzhen) Co. Ltd. Proprietary
1816
         *
1817
         * sub-id:
1818
         *    0    Reference stations PVT, requires MSM7.
1819
         *    1    Navigation PVT Solyution
1820
         *    2    Attitude Determination (multi antenna)
1821
         *    0x0a Raw Sensor measurements.
1822
         */
1823
0
        msg_name = "Allystar Technology (Shenzhen) Co. Ltd. Proprietary";
1824
0
        break;
1825
1826
0
    case 4066:
1827
        /* RTCM 3.3
1828
         * Lantmateriet Proprietary
1829
         */
1830
0
        msg_name = "Lantmateriet Proprietary";
1831
0
        break;
1832
1833
0
    case 4067:
1834
        /* RTCM 3.x
1835
         * China Transport telecommunications & Information Center Proprietary
1836
         */
1837
0
        msg_name = "China Transport telecommunications & Information "
1838
0
                       "Center Proprietary";
1839
0
        break;
1840
1841
0
    case 4068:
1842
        /* RTCM 3.3
1843
         * Qianxun Location Networks Co. Ltd Proprietary
1844
         */
1845
0
        msg_name = "Qianxun Location Networks Co. Ltd Proprietary";
1846
0
        break;
1847
1848
0
    case 4069:
1849
        /* RTCM 3.3
1850
         * VERIPOS Ltd Proprietary
1851
         */
1852
0
        msg_name = "VERIPOS Ltd Proprietary";
1853
0
        break;
1854
1855
0
    case 4070:
1856
        /* RTCM 3.3
1857
         * Wuhan MengXin Technology
1858
         */
1859
0
        msg_name = "Wuhan MengXin Technology Proprietary";
1860
0
        break;
1861
1862
0
    case 4071:
1863
        /* RTCM 3.3
1864
         * Wuhan Navigation and LBS
1865
         */
1866
0
        msg_name = "Wuhan Navigation and LBS Proprietary";
1867
0
        break;
1868
1869
0
    case 4072:
1870
        /* RTCM 3.x
1871
         * u-blox Proprietary
1872
         * Mitsubishi Electric Corp Proprietary
1873
         * 4072.0 Reference station PVT (u-blox proprietary)
1874
         * 4072.1 Additional reference station information (u-blox proprietary)
1875
         */
1876
0
        msg_name = "u-blox Proprietary";
1877
0
        break;
1878
1879
0
    case 4073:
1880
        /* RTCM 3.x
1881
         * Unicore Communications Proprietary
1882
         */
1883
0
        msg_name = "Alberding GmbH Proprietary";
1884
0
        break;
1885
1886
0
    case 4075:
1887
        /* RTCM 3.x
1888
         * Alberding GmbH Proprietary
1889
         */
1890
0
        msg_name = "Alberding GmbH Proprietary";
1891
0
        break;
1892
1893
0
    case 4076:
1894
        /* RTCM 3.x
1895
         * International GNSS Service Proprietary, www.igs.org
1896
         */
1897
0
        msg_name = "International GNSS Service Proprietary";
1898
0
        unknown = rtcm3_4076(context, rtcm, buf);
1899
0
        break;
1900
1901
0
    case 4077:
1902
        /* RTCM 3.x
1903
         * Hemisphere GNSS Proprietary
1904
         */
1905
0
        msg_name = "Hemisphere GNSS Proprietary";
1906
0
        break;
1907
1908
0
    case 4078:
1909
        /* RTCM 3.x
1910
         * ComNav Technology Proprietary
1911
         */
1912
0
        msg_name = "ComNav Technology Proprietary";
1913
0
        break;
1914
1915
0
    case 4079:
1916
        /* RTCM 3.x
1917
         * SubCarrier Systems Corp Proprietary
1918
         */
1919
0
        msg_name = "SubCarrier Systems Corp Proprietary";
1920
0
        break;
1921
1922
0
    case 4080:
1923
        /* RTCM 3.x
1924
         * NavCom Technology, Inc.
1925
         */
1926
0
        msg_name = "NavCom Technology, Inc.";
1927
0
        break;
1928
1929
0
    case 4081:
1930
        /* RTCM 3.x
1931
         * Seoul National Universtiry GNSS Lab Proprietary
1932
         */
1933
0
        msg_name = "Seoul National Universtiry GNSS Lab Proprietery";
1934
0
        break;
1935
1936
0
    case 4082:
1937
        /* RTCM 3.x
1938
         * Cooperative Research Centre for Spatial Information Proprietary
1939
         */
1940
0
        msg_name = "Cooperative Research Centre for Spatial Information "
1941
0
                       "Proprietary";
1942
0
        break;
1943
1944
0
    case 4083:
1945
        /* RTCM 3.x
1946
         * German Aerospace Center Proprietary
1947
         */
1948
0
        msg_name = "German Aerospace Center Proprietary";
1949
0
        break;
1950
1951
0
    case 4084:
1952
        /* RTCM 3.x
1953
         * Geodetics Inc Proprietary
1954
         */
1955
0
        msg_name = "Geodetics Inc Proprietary";
1956
0
        break;
1957
1958
0
    case 4085:
1959
        /* RTCM 3.x
1960
         * European GNSS Supervisory Authority Proprietary
1961
         */
1962
0
        msg_name = "European GNSS Supervisory Authority Proprietary";
1963
0
        break;
1964
1965
0
    case 4086:
1966
        /* RTCM 3.x
1967
         * InPosition GmbH Proprietary
1968
         */
1969
0
        msg_name = "InPosition GmbH Proprietary";
1970
0
        break;
1971
1972
0
    case 4087:
1973
        /* RTCM 3.x
1974
         * Fugro Proprietary
1975
         */
1976
0
        msg_name = "Fugro Proprietary";
1977
0
        break;
1978
1979
0
    case 4088:
1980
        /* RTCM 3.x
1981
         * IfEN GmbH Proprietary
1982
         */
1983
0
        msg_name = "IfEN GmbH Proprietary";
1984
0
        break;
1985
1986
0
    case 4089:
1987
        /* RTCM 3.x
1988
         * Septentrio Satellite Navigation Proprietary
1989
         */
1990
0
        msg_name = "Septentrio Satellite Navigation Proprietary";
1991
0
        break;
1992
1993
0
    case 4090:
1994
        /* RTCM 3.x
1995
         * Geo++ Proprietary
1996
         */
1997
0
        msg_name = "Geo++ Proprietary";
1998
0
        break;
1999
2000
0
    case 4091:
2001
        /* RTCM 3.x
2002
         * Topcon Positioning Systems Proprietary
2003
         */
2004
0
        msg_name = "Topcon Positioning Systems Proprietary";
2005
0
        break;
2006
2007
0
    case 4092:
2008
        /* RTCM 3.x
2009
         * Leica Geosystems Proprietary
2010
         */
2011
0
        msg_name = "Leica Geosystems Proprietary";
2012
0
        break;
2013
2014
0
    case 4093:
2015
        /* RTCM 3.x
2016
         * NovAtel Proprietary
2017
         */
2018
0
        msg_name = "NovAtel Pr.orietary";
2019
0
        break;
2020
2021
0
    case 4094:
2022
        /* RTCM 3.x
2023
         * Trimble Proprietary
2024
         */
2025
0
        msg_name = "Trimble Proprietary";
2026
0
        break;
2027
2028
0
    case 4095:
2029
        /* RTCM 3.x
2030
         * Ashtech/Magellan Proprietary
2031
         */
2032
0
        msg_name = "Ashtech/Magellan Proprietary";
2033
0
        break;
2034
2035
0
    default:
2036
0
        break;
2037
0
    }
2038
0
#undef RANGEDIFF
2039
0
#undef GPS_PSEUDORANGE
2040
0
#undef sgrab
2041
0
#undef ugrab
2042
0
    if (unknown) {
2043
        /*
2044
         * Leader bytes, message length, and checksum won't be copied.
2045
         * The first 12 bits of the copied payload will be the type field.
2046
         */
2047
0
        memcpy(rtcm->rtcmtypes.data, buf + 3, rtcm->length);
2048
0
        GPSD_LOG(LOG_PROG, &context->errout,
2049
0
                 "RTCM3: %d (%s) Undecoded, length %d\n",
2050
0
                 rtcm->type, msg_name, rtcm->length);
2051
0
    } else {
2052
0
        GPSD_LOG(LOG_PROG, &context->errout,
2053
0
                 "RTCM3: %d (%s) length %d\n",
2054
0
                 rtcm->type, msg_name, rtcm->length);
2055
0
    }
2056
0
}
2057
2058
// *INDENT-ON*
2059
2060
// vim: set expandtab shiftwidth=4