source: ntrip/trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit_igs.c@ 8972

Last change on this file since 8972 was 8972, checked in by stuerze, 4 years ago

minor changes regarding igs ssr decoding

  • Property svn:executable set to *
File size: 38.9 KB
Line 
1/* Programheader
2
3 Name: clock_orbit_igs.c
4 Project: RTCM3
5 Version: $Id: clock_orbit_igs.c 8963 2020-06-29 12:46:25Z stuerze $
6 Authors: Andrea Stürze
7 Description: state space approach: IGS
8 */
9
10#include <math.h>
11#include <stdio.h>
12#include <string.h>
13#ifndef sparc
14#include <stdint.h>
15#else
16#include <sys/types.h>
17#endif
18#include <clock_orbit_igs.h>
19
20
21static uint32_t CRC24(long size, const unsigned char *buf) {
22 uint32_t crc = 0;
23 int i;
24
25 while (size--) {
26 crc ^= (*buf++) << (16);
27 for (i = 0; i < 8; i++)
28 {
29 crc <<= 1;
30 if (crc & 0x1000000)
31 crc ^= 0x01864cfb;
32 }
33 }
34 return crc;
35}
36
37/* NOTE: These defines are interlinked with below functions and directly modify
38 the values. This may not be optimized in terms of final program code size but
39 should be optimized in terms of speed.
40
41 modified variables are:
42 - everything defined in STARTDATA (only use ressize outside of the defines,
43 others are private)
44 - buffer
45 - size
46 */
47
48#ifndef NOENCODE
49#define STOREBITS \
50 while(numbits >= 8) { \
51 if(!size) return 0; \
52 *(buffer++) = bitbuffer>>(numbits-8); \
53 numbits -= 8; \
54 ++ressize; \
55 --size; \
56 }
57
58#define ADDBITS(a, b) { \
59 bitbuffer = (bitbuffer<<(a))|((b)&((1<<a)-1)); \
60 numbits += (a); \
61 STOREBITS \
62 }
63
64#define STARTDATA \
65 size_t ressize=0; \
66 char *blockstart; \
67 int numbits; \
68 uint64_t bitbuffer=0;
69
70#define INITBLOCK \
71 numbits = 0; \
72 blockstart = buffer; \
73 ADDBITS(8, 0xD3) \
74 ADDBITS(6, 0) \
75 ADDBITS(10, 0)
76
77#define ENDBLOCK \
78 if(numbits) { ADDBITS((8-numbits), 0) } { \
79 int len = buffer-blockstart-3; \
80 blockstart[1] |= len>>8; \
81 blockstart[2] = len; \
82 if(len > 1023) \
83 return 0; \
84 len = CRC24(len+3, (const unsigned char *) blockstart); \
85 ADDBITS(24, len) \
86 }
87
88#define SCALEADDBITS(a, b, c) ADDBITS(a, (int64_t)(c > 0 ? b*c+0.5 : b*c-0.5))
89
90#define MPI 3.141592653589793
91
92/* GNSS macros - Header part */
93#define T_RTCM_MESSAGE_NUMBER(a) ADDBITS(12, a) /* DF002 */
94#define T_IGS_SSR_VERSION(a) ADDBITS( 3, a) /* IDF001 */
95#define T_IGS_MESSAGE_NUMBER(a) ADDBITS( 8, a) /* IDF002 */
96#define T_SSR_EPOCH_TIME(a) ADDBITS(20, a) /* IDF003 */
97#define T_SSR_UPDATE_INTERVAL(a) ADDBITS( 4, a) /* DF391, IDF004 */
98#define T_MULTIPLE_MESSAGE_INDICATOR(a) ADDBITS( 1, a) /* DF388, IDF005 */
99#define T_SSR_IOD(a) ADDBITS( 4, a) /* DF413, IDF007 */
100#define T_SSR_PROVIDER_ID(a) ADDBITS(16, a) /* DF414, IDF008 */
101#define T_SSR_SOLUTION_ID(a) ADDBITS( 4, a) /* DF415, IDF009 */
102#define T_SATELLITE_REFERENCE_DATUM(a) ADDBITS( 1, a) /* DF375, IDF006 */
103#define T_NO_OF_SATELLITES(a) ADDBITS( 6, a) /* DF387, IDF010 */
104
105/* GNSS macros - Satellite specific part */
106#define T_GNSS_SATELLITE_ID(a) ADDBITS( 6, a) /* IDF011 */
107#define T_GNSS_IOD(a) ADDBITS( 8, a) /* IDF012 */
108
109#define T_DELTA_RADIAL(a) SCALEADDBITS(22, 10000.0, a) /* DF365, IDF013 */
110#define T_DELTA_ALONG_TRACK(a) SCALEADDBITS(20, 2500.0, a) /* DF366, IDF014 */
111#define T_DELTA_CROSS_TRACK(a) SCALEADDBITS(20, 2500.0, a) /* DF367, IDF015 */
112#define T_DELTA_DOT_RADIAL(a) SCALEADDBITS(21, 1000000.0, a) /* DF368, IDF016 */
113#define T_DELTA_DOT_ALONG_TRACK(a) SCALEADDBITS(19, 250000.0, a) /* DF369, IDF017 */
114#define T_DELTA_DOT_CROSS_TRACK(a) SCALEADDBITS(19, 250000.0, a) /* DF370, IDF018 */
115
116#define T_DELTA_CLOCK_C0(a) SCALEADDBITS(22, 10000.0, a) /* DF376, IDF019 */
117#define T_DELTA_CLOCK_C1(a) SCALEADDBITS(21, 1000000.0, a) /* DF377, IDF020 */
118#define T_DELTA_CLOCK_C2(a) SCALEADDBITS(27, 50000000.0, a) /* DF378, IDF021 */
119#define T_HR_CLOCK_CORRECTION(a) SCALEADDBITS(22, 10000.0, a) /* DF390, IDF022 */
120
121#define T_NO_OF_BIASES(a) ADDBITS(5, a) /* IDF023 */
122#define T_GNSS_SIGNAL_IDENTIFIER(a) ADDBITS(5, a) /* IDF024 */
123#define T_CODE_BIAS(a) SCALEADDBITS(14, 100.0, a) /* DF383, IDF025 */
124#define T_YAW_ANGLE(a) SCALEADDBITS( 9, 256.0/MPI, a) /* DF480, IDF026 */
125#define T_YAW_RATE(a) SCALEADDBITS( 8, 8192.0/MPI, a) /* DF481, IDF027 */
126#define T_PHASE_BIAS(a) SCALEADDBITS(20, 10000.0, a) /* DF482, IDF028 */
127
128/* Phase specific part of GNSS phase bias message */
129#define T_INTEGER_INDICATOR(a) ADDBITS( 1, a) /* DF483, IDF029 */
130#define T_WIDE_LANE_INDICATOR(a) ADDBITS( 2, a) /* DF484, IDF030 */
131#define T_DISCONTINUITY_COUNTER(a) ADDBITS( 4, a) /* DF485, IDF031 */
132#define T_DISPERSIVE_BIAS_INDICATOR(a) ADDBITS( 1, a) /* DF486, IDF032 */
133#define T_MW_CONSISTENCY_INDICATOR(a) ADDBITS( 1, a) /* DF487, IDF033 */
134
135#define T_SSR_URA(a) ADDBITS( 6, a) /* DF389, IDF034 */
136
137/* Ionosphere */
138#define T_NO_IONO_LAYERS(a) ADDBITS( 2, a-1) /* DF472, IDF035 */
139#define T_IONO_HEIGHT(a) SCALEADDBITS( 8, 1/10000.0, a) /* DF473, IDF036 */
140#define T_IONO_DEGREE(a) ADDBITS( 4, a-1) /* DF474, IDF037 */
141#define T_IONO_ORDER(a) ADDBITS( 4, a-1) /* DF475, IDF038 */
142#define T_IONO_COEFF_C(a) SCALEADDBITS(16, 200.0, a) /* DF476, IDF039 */
143#define T_IONO_COEFF_S(a) SCALEADDBITS(16, 200.0, a) /* DF477, IDF040 */
144#define T_VTEC_QUALITY_INDICATOR(a) SCALEADDBITS( 9, 20.0, a) /* DF478, IDF041 */
145
146static double URAToValue(int ura) {
147 int urac, urav;
148 urac = ura >> 3;
149 urav = ura & 7;
150 if (!ura)
151 return 0;
152 else if (ura == 63)
153 return SSR_MAXURA;
154 return (pow(3, urac) * (1.0 + urav / 4.0) - 1.0) / 1000.0;
155}
156
157static int ValueToURA(double val) {
158 int ura;
159 if (!val)
160 return 0;
161 else if (val > 5.4665)
162 return 63;
163 for (ura = 1; ura < 63 && val > URAToValue(ura); ++ura)
164 ;
165 return ura;
166}
167
168static const enum ClockOrbitType corbase[CLOCKORBIT_SATNUM] = {
169 (int) COBBASE_GPS,
170 (int) COBBASE_GLONASS,
171 (int) COBBASE_GALILEO,
172 (int) COBBASE_QZSS,
173 (int) COBBASE_SBAS,
174 (int) COBBASE_BDS
175};
176
177static const enum COR_OFFSETS satoffset[CLOCKORBIT_SATNUM + 1] = {
178 CLOCKORBIT_OFFSETGPS,
179 CLOCKORBIT_OFFSETGLONASS,
180 CLOCKORBIT_OFFSETGALILEO,
181 CLOCKORBIT_OFFSETQZSS,
182 CLOCKORBIT_OFFSETSBAS,
183 CLOCKORBIT_OFFSETBDS,
184 CLOCKORBIT_COUNTSAT
185};
186
187size_t MakeClockOrbit(const struct ClockOrbit *co, enum ClockOrbitType type,
188 int moremessagesfollow, char *buffer, size_t size) {
189 unsigned int status[CLOCKORBIT_SATNUM][COBOFS_NUM], i, s;
190
191 memset(status, 0, sizeof(status));
192
193 STARTDATA
194
195 for (s = 0; s < CLOCKORBIT_SATNUM; ++s) {
196 for (i = 0; i < COBOFS_NUM; ++i) {
197 if (co->NumberOfSat[s] && (type == COTYPE_AUTO || type == corbase[s] + i) &&
198 (co->Supplied[i] || (i <= COBOFS_CLOCK && co->Supplied[COBOFS_COMBINED]) ||
199 (i == COBOFS_COMBINED && co->Supplied[COBOFS_ORBIT] && co->Supplied[COBOFS_CLOCK]))) {
200 status[s][i] = 1;
201 if (i == COBOFS_COMBINED) {
202 status[s][COBOFS_ORBIT] = status[s][COBOFS_CLOCK] = 0;
203 } /* disable single blocks for combined type */
204 } /* check for data */
205 } /* iterate over sub-types */
206 } /* iterate over satellite systems */
207
208 for (s = 0; s < CLOCKORBIT_SATNUM; ++s) {
209 if (status[s][COBOFS_ORBIT]) {
210 INITBLOCK
211 T_RTCM_MESSAGE_NUMBER(RTCM_MESSAGE_NUMBER_IGS)
212 T_IGS_SSR_VERSION(IGS_SSR_VERSION)
213 T_IGS_MESSAGE_NUMBER(corbase[s] + COBOFS_ORBIT)
214 T_SSR_EPOCH_TIME(co->EpochTime[s])
215 T_SSR_UPDATE_INTERVAL(co->UpdateInterval)
216 T_MULTIPLE_MESSAGE_INDICATOR(moremessagesfollow ? 1 : 0)
217 T_SSR_IOD(co->SSRIOD)
218 T_SSR_PROVIDER_ID(co->SSRProviderID)
219 T_SSR_SOLUTION_ID(co->SSRSolutionID)
220 T_SATELLITE_REFERENCE_DATUM(co->SatRefDatum)
221 T_NO_OF_SATELLITES(co->NumberOfSat[s])
222 for (i = satoffset[s]; i < satoffset[s] + co->NumberOfSat[s]; ++i) {
223 T_GNSS_SATELLITE_ID(co->Sat[i].ID)
224 T_GNSS_IOD(co->Sat[i].IOD)
225 T_DELTA_RADIAL(co->Sat[i].Orbit.DeltaRadial)
226 T_DELTA_ALONG_TRACK(co->Sat[i].Orbit.DeltaAlongTrack)
227 T_DELTA_CROSS_TRACK(co->Sat[i].Orbit.DeltaCrossTrack)
228 T_DELTA_DOT_RADIAL(co->Sat[i].Orbit.DotDeltaRadial)
229 T_DELTA_DOT_ALONG_TRACK(co->Sat[i].Orbit.DotDeltaAlongTrack)
230 T_DELTA_DOT_CROSS_TRACK(co->Sat[i].Orbit.DotDeltaCrossTrack)
231 }
232 ENDBLOCK
233 }
234 if (status[s][COBOFS_CLOCK]) {
235 INITBLOCK
236 T_RTCM_MESSAGE_NUMBER(RTCM_MESSAGE_NUMBER_IGS)
237 T_IGS_SSR_VERSION(IGS_SSR_VERSION)
238 T_IGS_MESSAGE_NUMBER(corbase[s] + COBOFS_CLOCK)
239 T_SSR_EPOCH_TIME(co->EpochTime[s])
240 T_SSR_UPDATE_INTERVAL(co->UpdateInterval)
241 T_MULTIPLE_MESSAGE_INDICATOR(moremessagesfollow ? 1 : 0)
242 T_SSR_IOD(co->SSRIOD)
243 T_SSR_PROVIDER_ID(co->SSRProviderID)
244 T_SSR_SOLUTION_ID(co->SSRSolutionID)
245 T_NO_OF_SATELLITES(co->NumberOfSat[s])
246 for (i = satoffset[s]; i < satoffset[s] + co->NumberOfSat[s]; ++i) {
247 T_GNSS_SATELLITE_ID(co->Sat[i].ID)
248 T_DELTA_CLOCK_C0(co->Sat[i].Clock.DeltaA0)
249 T_DELTA_CLOCK_C1(co->Sat[i].Clock.DeltaA1)
250 T_DELTA_CLOCK_C2(co->Sat[i].Clock.DeltaA2)
251 }
252 ENDBLOCK
253 }
254 if (status[s][COBOFS_COMBINED]) {
255#ifdef SPLITBLOCK
256 int nums = co->NumberOfSat[s];
257 int left, start = satoffset[s];
258 if(nums > 28) {/* split block when more than 28 sats */
259 left = nums - 28;
260 nums = 28;
261 }
262 else {
263 left = 0;
264 }
265 while(nums) {
266#endif
267 INITBLOCK
268 T_RTCM_MESSAGE_NUMBER(RTCM_MESSAGE_NUMBER_IGS)
269 T_IGS_SSR_VERSION(IGS_SSR_VERSION)
270 T_IGS_MESSAGE_NUMBER(corbase[s] + COBOFS_COMBINED)
271 T_SSR_EPOCH_TIME(co->EpochTime[s])
272 T_SSR_UPDATE_INTERVAL(co->UpdateInterval)
273#ifdef SPLITBLOCK
274 T_MULTIPLE_MESSAGE_INDICATOR((moremessagesfollow || left) ? 1 : 0)
275#else
276 T_MULTIPLE_MESSAGE_INDICATOR(moremessagesfollow ? 1 : 0)
277#endif
278 T_SSR_IOD(co->SSRIOD)
279 T_SSR_PROVIDER_ID(co->SSRProviderID)
280 T_SSR_SOLUTION_ID(co->SSRSolutionID)
281 T_SATELLITE_REFERENCE_DATUM(co->SatRefDatum)
282#ifdef SPLITBLOCK
283 T_NO_OF_SATELLITES(nums)
284 for(i = start; i < start+nums; ++i) {
285#else
286 T_NO_OF_SATELLITES(co->NumberOfSat[s])
287 for (i = satoffset[s]; i < satoffset[s] + co->NumberOfSat[s]; ++i) {
288#endif
289 T_GNSS_SATELLITE_ID(co->Sat[i].ID)
290 T_GNSS_IOD(co->Sat[i].IOD)
291 T_DELTA_RADIAL(co->Sat[i].Orbit.DeltaRadial)
292 T_DELTA_ALONG_TRACK(co->Sat[i].Orbit.DeltaAlongTrack)
293 T_DELTA_CROSS_TRACK(co->Sat[i].Orbit.DeltaCrossTrack)
294 T_DELTA_DOT_RADIAL(co->Sat[i].Orbit.DotDeltaRadial)
295 T_DELTA_DOT_ALONG_TRACK(co->Sat[i].Orbit.DotDeltaAlongTrack)
296 T_DELTA_DOT_CROSS_TRACK(co->Sat[i].Orbit.DotDeltaCrossTrack)
297 T_DELTA_CLOCK_C0(co->Sat[i].Clock.DeltaA0)
298 T_DELTA_CLOCK_C1(co->Sat[i].Clock.DeltaA1)
299 T_DELTA_CLOCK_C2(co->Sat[i].Clock.DeltaA2)
300 }
301 ENDBLOCK
302#ifdef SPLITBLOCK
303 start += nums;
304 nums = left;
305 left = 0;
306 }
307#endif
308 }
309 if (status[s][COBOFS_HR]) {
310 INITBLOCK
311 T_RTCM_MESSAGE_NUMBER(RTCM_MESSAGE_NUMBER_IGS)
312 T_IGS_SSR_VERSION(IGS_SSR_VERSION)
313 T_IGS_MESSAGE_NUMBER(corbase[s] + COBOFS_HR)
314 T_SSR_EPOCH_TIME(co->EpochTime[s])
315 T_SSR_UPDATE_INTERVAL(co->UpdateInterval)
316 T_MULTIPLE_MESSAGE_INDICATOR(moremessagesfollow ? 1 : 0)
317 T_SSR_IOD(co->SSRIOD)
318 T_SSR_PROVIDER_ID(co->SSRProviderID)
319 T_SSR_SOLUTION_ID(co->SSRSolutionID)
320 T_NO_OF_SATELLITES(co->NumberOfSat[s])
321 for (i = satoffset[s]; i < satoffset[s] + co->NumberOfSat[s]; ++i) {
322 T_GNSS_SATELLITE_ID(co->Sat[i].ID)
323 T_HR_CLOCK_CORRECTION(co->Sat[i].hrclock)
324 }
325 ENDBLOCK
326 }
327 if (status[s][COBOFS_URA]) {
328 INITBLOCK
329 T_RTCM_MESSAGE_NUMBER(RTCM_MESSAGE_NUMBER_IGS)
330 T_IGS_SSR_VERSION(IGS_SSR_VERSION)
331 T_IGS_MESSAGE_NUMBER(corbase[s] + COBOFS_URA)
332 T_SSR_EPOCH_TIME(co->EpochTime[s])
333 T_SSR_UPDATE_INTERVAL(co->UpdateInterval)
334 T_MULTIPLE_MESSAGE_INDICATOR(moremessagesfollow ? 1 : 0)
335 T_SSR_IOD(co->SSRIOD)
336 T_SSR_PROVIDER_ID(co->SSRProviderID)
337 T_SSR_SOLUTION_ID(co->SSRSolutionID)
338 T_NO_OF_SATELLITES(co->NumberOfSat[s])
339 for (i = satoffset[s]; i < satoffset[s] + co->NumberOfSat[s]; ++i) {
340 T_GNSS_SATELLITE_ID(co->Sat[i].ID)
341 T_SSR_URA(ValueToURA(co->Sat[i].UserRangeAccuracy))
342 }
343 ENDBLOCK
344 }
345 }
346 return ressize;
347}
348
349size_t MakeCodeBias(const struct CodeBias *b, enum CodeBiasType type,
350 int moremessagesfollow, char *buffer, size_t size) {
351 unsigned int s, i, j;
352
353 STARTDATA
354
355 for (s = 0; s < CLOCKORBIT_SATNUM; ++s) {
356 if (b->NumberOfSat[s] && (type == CBTYPE_AUTO || type == corbase[s] + COBOFS_CBIAS)) {
357 INITBLOCK
358 T_RTCM_MESSAGE_NUMBER(RTCM_MESSAGE_NUMBER_IGS)
359 T_IGS_SSR_VERSION(IGS_SSR_VERSION)
360 T_IGS_MESSAGE_NUMBER(corbase[s] + COBOFS_CBIAS)
361 T_SSR_EPOCH_TIME(b->EpochTime[s])
362 T_SSR_UPDATE_INTERVAL(b->UpdateInterval)
363 T_MULTIPLE_MESSAGE_INDICATOR(moremessagesfollow ? 1 : 0)
364 T_SSR_IOD(b->SSRIOD)
365 T_SSR_PROVIDER_ID(b->SSRProviderID)
366 T_SSR_SOLUTION_ID(b->SSRSolutionID)
367 T_NO_OF_SATELLITES(b->NumberOfSat[s])
368 for (i = satoffset[s]; i < satoffset[s] + b->NumberOfSat[s]; ++i) {
369 T_GNSS_SATELLITE_ID(b->Sat[i].ID)
370 T_NO_OF_BIASES(b->Sat[i].NumberOfCodeBiases)
371 for (j = 0; j < b->Sat[i].NumberOfCodeBiases; ++j) {
372 T_GNSS_SIGNAL_IDENTIFIER(b->Sat[i].Biases[j].Type)
373 T_CODE_BIAS(b->Sat[i].Biases[j].Bias)
374 }
375 }
376 ENDBLOCK
377 }
378 }
379 return ressize;
380}
381
382size_t MakePhaseBias(const struct PhaseBias *b, enum PhaseBiasType type,
383 int moremessagesfollow, char *buffer, size_t size) {
384 unsigned int s, i, j;
385
386 STARTDATA
387
388 for (s = 0; s < CLOCKORBIT_SATNUM; ++s) {
389 if (b->NumberOfSat[s] && (type == PBTYPE_AUTO || type == corbase[s] + COBOFS_PBIAS)) {
390 INITBLOCK
391 T_RTCM_MESSAGE_NUMBER(RTCM_MESSAGE_NUMBER_IGS)
392 T_IGS_SSR_VERSION(IGS_SSR_VERSION)
393 T_IGS_MESSAGE_NUMBER(corbase[s] + COBOFS_PBIAS)
394 T_SSR_EPOCH_TIME(b->EpochTime[s])
395 T_SSR_UPDATE_INTERVAL(b->UpdateInterval)
396 T_MULTIPLE_MESSAGE_INDICATOR(moremessagesfollow ? 1 : 0)
397 T_SSR_IOD(b->SSRIOD)
398 T_SSR_PROVIDER_ID(b->SSRProviderID)
399 T_SSR_SOLUTION_ID(b->SSRSolutionID)
400 T_DISPERSIVE_BIAS_INDICATOR(b->DispersiveBiasConsistencyIndicator ? 1 : 0)
401 T_MW_CONSISTENCY_INDICATOR(b->MWConsistencyIndicator ? 1 : 0)
402 T_NO_OF_SATELLITES(b->NumberOfSat[s])
403 for (i = satoffset[s]; i < satoffset[s] + b->NumberOfSat[s]; ++i) {
404 T_GNSS_SATELLITE_ID(b->Sat[i].ID)
405 T_NO_OF_BIASES(b->Sat[i].NumberOfPhaseBiases)
406 T_YAW_ANGLE(b->Sat[i].YawAngle)
407 T_YAW_RATE(b->Sat[i].YawRate)
408 for (j = 0; j < b->Sat[i].NumberOfPhaseBiases; ++j) {
409 T_GNSS_SIGNAL_IDENTIFIER(b->Sat[i].Biases[j].Type)
410 T_INTEGER_INDICATOR(b->Sat[i].Biases[j].SignalIntegerIndicator ? 1 : 0)
411 T_WIDE_LANE_INDICATOR(b->Sat[i].Biases[j].SignalsWideLaneIntegerIndicator)
412 T_DISCONTINUITY_COUNTER(b->Sat[i].Biases[j].SignalDiscontinuityCounter)
413 T_PHASE_BIAS(b->Sat[i].Biases[j].Bias)
414 }
415 }
416 ENDBLOCK
417 }
418 }
419 return ressize;
420}
421
422size_t MakeVTEC(const struct VTEC *v, int moremessagesfollow, char *buffer, size_t size) {
423 unsigned int l, o, d;
424
425 STARTDATA
426 INITBLOCK
427
428 T_RTCM_MESSAGE_NUMBER(RTCM_MESSAGE_NUMBER_IGS)
429 T_IGS_SSR_VERSION(IGS_SSR_VERSION)
430 T_IGS_MESSAGE_NUMBER(VTEC_BASE)
431 T_SSR_EPOCH_TIME(v->EpochTime)
432 T_SSR_UPDATE_INTERVAL(v->UpdateInterval)
433 T_MULTIPLE_MESSAGE_INDICATOR(moremessagesfollow ? 1 : 0)
434 T_SSR_IOD(v->SSRIOD)
435 T_SSR_PROVIDER_ID(v->SSRProviderID)
436 T_SSR_SOLUTION_ID(v->SSRSolutionID)
437 T_VTEC_QUALITY_INDICATOR(v->Quality)
438 T_NO_IONO_LAYERS(v->NumLayers)
439 for (l = 0; l < v->NumLayers; ++l) {
440 T_IONO_HEIGHT(v->Layers[l].Height)
441 T_IONO_DEGREE(v->Layers[l].Degree)
442 T_IONO_ORDER(v->Layers[l].Order)
443 for (o = 0; o <= v->Layers[l].Order; ++o) {
444 for (d = o; d <= v->Layers[l].Degree; ++d) {
445 T_IONO_COEFF_C(v->Layers[l].Cosinus[d][o])
446 }
447 }
448 for (o = 1; o <= v->Layers[l].Order; ++o) {
449 for (d = o; d <= v->Layers[l].Degree; ++d) {
450 T_IONO_COEFF_S(v->Layers[l].Sinus[d][o])
451 }
452 }
453 }
454 ENDBLOCK
455 return ressize;
456}
457#endif /* NOENCODE */
458
459#ifndef NODECODE
460
461#define DECODESTART \
462 int numbits=0; \
463 uint64_t bitbuffer=0;
464
465#define LOADBITS(a) { \
466 while((a) > numbits) { \
467 if(!size--) return GCOBR_SHORTMESSAGE; \
468 bitbuffer = (bitbuffer<<8)|((unsigned char)*(buffer++)); \
469 numbits += 8; \
470 } \
471}
472
473/* extract bits from data stream
474 b = variable to store result, a = number of bits */
475#define GETBITS(b, a) { \
476 LOADBITS(a) \
477 b = (bitbuffer<<(64-numbits))>>(64-(a)); \
478 numbits -= (a); \
479}
480
481/* extract bits from data stream
482 b = variable to store result, a = number of bits */
483#define GETBITSFACTOR(b, a, c) { \
484 LOADBITS(a) \
485 b = ((bitbuffer<<(64-numbits))>>(64-(a)))*(c); \
486 numbits -= (a); \
487}
488
489/* extract signed floating value from data stream
490 b = variable to store result, a = number of bits */
491#define GETFLOATSIGN(b, a, c) { \
492 LOADBITS(a) \
493 b = ((double)(((int64_t)(bitbuffer<<(64-numbits)))>>(64-(a))))*(c); \
494 numbits -= (a); \
495}
496
497/* extract floating value from data stream
498 b = variable to store result, a = number of bits, c = scale factor */
499#define GETFLOAT(b, a, c) { \
500 LOADBITS(a) \
501 b = ((double)((bitbuffer<<(sizeof(bitbuffer)*8-numbits))>>(sizeof(bitbuffer)*8-(a))))*(c); \
502 numbits -= (a); \
503}
504
505#define SKIPBITS(b) { LOADBITS(b) numbits -= (b); }
506
507/* GPS macros also used for other systems when matching! */
508#define G_HEADER(a) GETBITS(a, 8)
509#define G_RESERVEDH(a) GETBITS(a, 6)
510#define G_SIZE(a) GETBITS(a, 10)
511
512/* GNSS macros - Header part */
513#define G_RTCM_MESSAGE_NUMBER(a) GETBITS(a, 12) /* DF002 */
514#define G_IGS_SSR_VERSION(a) GETBITS(a, 3) /* IDF001 */
515#define G_IGS_MESSAGE_NUMBER(a) GETBITS(a, 8) /* IDF002 */
516#define G_SSR_EPOCH_TIME(a) GETBITS(a, 20) /* IDF003 */
517#define G_SSR_EPOCH_TIME_CHECK(a, b) {unsigned int temp; GETBITS(temp, 20) \
518 if(b && a != temp) return GCOBR_TIMEMISMATCH; a = temp;}
519#define G_SSR_UPDATE_INTERVAL(a) GETBITS(a, 4) /* DF391, IDF004 */
520#define G_MULTIPLE_MESSAGE_INDICATOR(a) GETBITS(a, 1) /* DF388, IDF005 */
521#define G_SSR_IOD(a) GETBITS(a, 4) /* DF413, IDF007 */
522#define G_SSR_PROVIDER_ID(a) GETBITS(a, 16) /* DF414, IDF008 */
523#define G_SSR_SOLUTION_ID(a) GETBITS(a, 4) /* DF415, IDF009 */
524#define G_SATELLITE_REFERENCE_DATUM(a) GETBITS(a, 1) /* DF375, IDF006 */
525#define G_NO_OF_SATELLITES(a) GETBITS(a, 6) /* DF387, IDF010 */
526
527/* GNSS macros - Satellite specific part */
528#define G_GNSS_SATELLITE_ID(a) GETBITS(a, 6) /* IDF011 */
529#define G_GNSS_IOD(a) GETBITS(a, 8) /* IDF012 */
530
531#define G_DELTA_RADIAL(a) GETFLOATSIGN(a, 22, 1/10000.0) /* DF365, IDF013 */
532#define G_DELTA_ALONG_TRACK(a) GETFLOATSIGN(a, 20, 1/2500.0) /* DF366, IDF014 */
533#define G_DELTA_CROSS_TRACK(a) GETFLOATSIGN(a, 20, 1/2500.0) /* DF367, IDF015 */
534#define G_DELTA_DOT_RADIAL(a) GETFLOATSIGN(a, 21, 1/1000000.0) /* DF368, IDF016 */
535#define G_DELTA_DOT_ALONG_TRACK(a) GETFLOATSIGN(a, 19, 1/250000.0) /* DF369, IDF017 */
536#define G_DELTA_DOT_CROSS_TRACK(a) GETFLOATSIGN(a, 19, 1/250000.0) /* DF370, IDF018 */
537
538#define G_DELTA_CLOCK_C0(a) GETFLOATSIGN(a, 22, 1/10000.0) /* DF376, IDF019 */
539#define G_DELTA_CLOCK_C1(a) GETFLOATSIGN(a, 21, 1/1000000.0) /* DF377, IDF020 */
540#define G_DELTA_CLOCK_C2(a) GETFLOATSIGN(a, 27, 1/50000000.0) /* DF378, IDF021 */
541#define G_HR_CLOCK_CORRECTION(a) GETFLOATSIGN(a, 22, 1/10000.0) /* DF390, IDF022 */
542
543#define G_NO_OF_BIASES(a) GETBITS(a, 5) /* IDF023 */
544#define G_GNSS_SIGNAL_IDENTIFIER(a) GETBITS(a, 5) /* IDF024 */
545
546#define G_CODE_BIAS(a) GETFLOATSIGN(a, 14, 1/100.0) /* DF383, IDF025 */
547#define G_YAW_ANGLE(a) GETFLOAT (a, 9, MPI/256.0) /* DF480, IDF026 */
548#define G_YAW_RATE(a) GETFLOATSIGN(a, 8, MPI/8192.0) /* DF481, IDF027 */
549#define G_PHASE_BIAS(a) GETFLOATSIGN(a, 20, 1/10000.) /* DF482, IDF028 */
550
551#define G_INTEGER_INDICATOR(a) GETBITS(a, 1) /* DF483, IDF029 */
552#define G_WIDE_LANE_INDICATOR(a) GETBITS(a, 2) /* DF484, IDF030 */
553#define G_DISCONTINUITY_COUNTER(a) GETBITS(a, 4) /* DF485, IDF031 */
554#define G_DISPERSIVE_BIAS_INDICATOR(a) GETBITS(a, 1) /* DF486, IDF032 */
555#define G_MW_CONSISTENCY_INDICATOR(a) GETBITS(a, 1) /* DF487, IDF033 */
556
557#define G_SSR_URA(a) {int temp; GETBITS(temp, 6) \
558 (a) = URAToValue(temp);} /* DF389, IDF034 */
559
560/* Ionosphere */
561#define G_NO_IONO_LAYERS(a) {unsigned int temp; GETBITS(temp, 2) a = temp+1;} /* DF472, IDF035 */
562#define G_IONO_HEIGHT(a) GETFLOAT(a, 8 , 10000.0) /* DF473, IDF036 */
563#define G_IONO_DEGREE(a) {unsigned int temp; GETBITS(temp, 4) a = temp+1;} /* DF474, IDF037 */
564#define G_IONO_ORDER(a) {unsigned int temp; GETBITS(temp, 4) a = temp+1;} /* DF475, IDF038 */
565#define G_IONO_COEFF_C(a) GETFLOATSIGN(a, 16,1/200.0) /* DF476, IDF039 */
566#define G_IONO_COEFF_S(a) GETFLOATSIGN(a, 16,1/200.0) /* DF477, IDF040 */
567#define G_VTEC_QUALITY_INDICATOR(a) GETFLOAT(a, 9, 1/20.0) /* DF478, IDF041 */
568
569
570enum GCOB_RETURN GetSSR(struct ClockOrbit *co, struct CodeBias *b,struct VTEC *v,
571 struct PhaseBias *pb, const char *buffer, size_t size, int *bytesused) {
572 int mmi = 0, h, rs;
573 unsigned int type, pos, i, j, s, nums, id, version;
574 size_t sizeofrtcmblock;
575 const char *blockstart = buffer;
576 DECODESTART
577
578 if (size < 7)
579 return GCOBR_SHORTBUFFER;
580
581#ifdef BNC_DEBUG
582 fprintf(stderr, "GetSSR START: size %d, numbits %d\n",(int)size, numbits);
583#endif
584
585 G_HEADER(h)
586 G_RESERVEDH(rs)
587 G_SIZE(sizeofrtcmblock);
588
589 if ((unsigned char) h != 0xD3 || rs)
590 return GCOBR_UNKNOWNDATA;
591 if (size < sizeofrtcmblock + 3) /* 3 header bytes already removed */
592 return GCOBR_MESSAGEEXCEEDSBUFFER;
593 if (CRC24(sizeofrtcmblock + 3, (const unsigned char *) blockstart) !=
594 (uint32_t) ((((unsigned char) buffer[sizeofrtcmblock]) << 16) |
595 (((unsigned char) buffer[sizeofrtcmblock + 1]) << 8) |
596 (((unsigned char) buffer[sizeofrtcmblock + 2]))))
597 return GCOBR_CRCMISMATCH;
598 size = sizeofrtcmblock; /* reduce size, so overflows are detected */
599
600 G_RTCM_MESSAGE_NUMBER(type)
601 G_IGS_SSR_VERSION(version)
602#ifdef BNC_DEBUG
603 fprintf(stderr, "rtcmType %d igsVersion %d ",type, version);
604#endif
605 G_IGS_MESSAGE_NUMBER(type)
606#ifdef BNC_DEBUG
607 fprintf(stderr, "igsType IM%d size %d\n",type,(int)sizeofrtcmblock);
608#endif
609 if (bytesused)
610 *bytesused = sizeofrtcmblock + 6;
611
612 if (type == VTEC_BASE) {
613 unsigned int l, o, d;
614 if (!v)
615 return GCOBR_NOVTECPARAMETER;
616 memset(v, 0, sizeof(*v));
617 G_SSR_EPOCH_TIME(v->EpochTime)
618 G_SSR_UPDATE_INTERVAL(v->UpdateInterval)
619 G_MULTIPLE_MESSAGE_INDICATOR(mmi)
620 G_SSR_IOD(v->SSRIOD)
621 G_SSR_PROVIDER_ID(v->SSRProviderID)
622 G_SSR_SOLUTION_ID(v->SSRSolutionID)
623 G_VTEC_QUALITY_INDICATOR(v->Quality)
624 G_NO_IONO_LAYERS(v->NumLayers)
625#ifdef BNC_DEBUG
626 fprintf(stderr, "epochTime %d ui %d mmi %d ssrIod %d providerId %d solId %d vtecQ %8.3f numLay %d \n",
627 v->EpochTime, v->UpdateInterval, mmi,
628 v->SSRIOD, v->SSRProviderID, v->SSRSolutionID, v->Quality, v->NumLayers);
629#endif
630 for (l = 0; l < v->NumLayers; ++l) {
631 G_IONO_HEIGHT(v->Layers[l].Height)
632 G_IONO_DEGREE(v->Layers[l].Degree)
633 G_IONO_ORDER(v->Layers[l].Order)
634#ifdef BNC_DEBUG
635 fprintf(stderr, "h %8.3f deg %d ord %d \n",
636 v->Layers[l].Height, v->Layers[l].Degree, v->Layers[l].Order);
637#endif
638 for (o = 0; o <= v->Layers[l].Order; ++o) {
639 for (d = o; d <= v->Layers[l].Degree; ++d) {
640 G_IONO_COEFF_C(v->Layers[l].Cosinus[d][o])
641#ifdef BNC_DEBUG
642 fprintf(stderr, "C[%d][%d] %8.3f \n",
643 d, o, v->Layers[l].Cosinus[d][o]);
644#endif
645 }
646 }
647 for (o = 1; o <= v->Layers[l].Order; ++o) {
648 for (d = o; d <= v->Layers[l].Degree; ++d) {
649 G_IONO_COEFF_S(v->Layers[l].Sinus[d][o])
650#ifdef BNC_DEBUG
651 fprintf(stderr, "S[%d][%d] %8.3f \n",
652 d, o, v->Layers[l].Sinus[d][o]);
653#endif
654 }
655 }
656 }
657#ifdef BNC_DEBUG
658 for(type = 0; type < (unsigned int)size && (unsigned char)buffer[type] != 0xD3; ++type)
659 numbits += 8;
660 fprintf(stderr, "numbits left %d\n",numbits);
661#endif
662 return mmi ? GCOBR_MESSAGEFOLLOWS : GCOBR_OK;
663 }
664
665 for (s = CLOCKORBIT_SATNUM; s-- > 0;) {
666 if (type >= corbase[s]) {
667 switch (type - corbase[s]) {
668 case COBOFS_ORBIT:
669 if (!co)
670 return GCOBR_NOCLOCKORBITPARAMETER;
671 co->messageType = type;
672 G_SSR_EPOCH_TIME_CHECK(co->EpochTime[s], co->NumberOfSat[s])
673 G_SSR_UPDATE_INTERVAL(co->UpdateInterval)
674 G_MULTIPLE_MESSAGE_INDICATOR(mmi)
675 G_SSR_IOD(co->SSRIOD)
676 G_SSR_PROVIDER_ID(co->SSRProviderID)
677 G_SSR_SOLUTION_ID(co->SSRSolutionID)
678 G_SATELLITE_REFERENCE_DATUM(co->SatRefDatum)
679 G_NO_OF_SATELLITES(nums)
680 co->Supplied[COBOFS_ORBIT] |= 1;
681#ifdef BNC_DEBUG
682 fprintf(stderr, "epochTime %d ui %d mmi %d sats %d/%d rd %d ssrIod %d providerId %d solId %d\n",
683 co->EpochTime[s], co->UpdateInterval,mmi,co->NumberOfSat[s],nums,
684 co->SatRefDatum, co->SSRIOD, co->SSRProviderID, co->SSRSolutionID);
685#endif
686 for (i = 0; i < nums; ++i) {
687 G_GNSS_SATELLITE_ID(id)
688 for (pos = satoffset[s];
689 pos < satoffset[s] + co->NumberOfSat[s] && co->Sat[pos].ID != id;
690 ++pos)
691 ;
692 if (pos >= satoffset[s + 1])
693 return GCOBR_DATAMISMATCH;
694 else if (pos == co->NumberOfSat[s] + satoffset[s])
695 ++co->NumberOfSat[s];
696 co->Sat[pos].ID = id;
697 G_GNSS_IOD(co->Sat[pos].IOD)
698 G_DELTA_RADIAL(co->Sat[pos].Orbit.DeltaRadial)
699 G_DELTA_ALONG_TRACK(co->Sat[pos].Orbit.DeltaAlongTrack)
700 G_DELTA_CROSS_TRACK(co->Sat[pos].Orbit.DeltaCrossTrack)
701 G_DELTA_DOT_RADIAL(co->Sat[pos].Orbit.DotDeltaRadial)
702 G_DELTA_DOT_ALONG_TRACK(co->Sat[pos].Orbit.DotDeltaAlongTrack)
703 G_DELTA_DOT_CROSS_TRACK(co->Sat[pos].Orbit.DotDeltaCrossTrack)
704#ifdef BNC_DEBUG
705 fprintf(stderr, "id %2d iod %3d dr %8.4f da %8.4f dc %8.4f dr %8.3f da %8.3f dc %8.3f\n",
706 co->Sat[pos].ID,co->Sat[pos].IOD,co->Sat[pos].Orbit.DeltaRadial,
707 co->Sat[pos].Orbit.DeltaAlongTrack,co->Sat[pos].Orbit.DeltaCrossTrack,
708 co->Sat[pos].Orbit.DotDeltaRadial,
709 co->Sat[pos].Orbit.DotDeltaAlongTrack,
710 co->Sat[pos].Orbit.DotDeltaCrossTrack);
711#endif
712 }
713 break;
714 case COBOFS_CLOCK:
715 if (!co)
716 return GCOBR_NOCLOCKORBITPARAMETER;
717 co->messageType = type;
718 G_SSR_EPOCH_TIME_CHECK(co->EpochTime[s], co->NumberOfSat[s])
719 G_SSR_UPDATE_INTERVAL(co->UpdateInterval)
720 G_MULTIPLE_MESSAGE_INDICATOR(mmi)
721 G_SSR_IOD(co->SSRIOD)
722 G_SSR_PROVIDER_ID(co->SSRProviderID)
723 G_SSR_SOLUTION_ID(co->SSRSolutionID)
724 G_NO_OF_SATELLITES(nums)
725 co->Supplied[COBOFS_CLOCK] |= 1;
726#ifdef BNC_DEBUG
727 fprintf(stderr, "epochTime %d ui %d mmi %d sats %d/%d ssrIod %d providerId %d solId %d\n",
728 co->EpochTime[s], co->UpdateInterval,mmi,co->NumberOfSat[s],nums,
729 co->SSRIOD, co->SSRProviderID, co->SSRSolutionID);
730#endif
731 for (i = 0; i < nums; ++i) {
732 G_GNSS_SATELLITE_ID(id)
733 for (pos = satoffset[s];
734 pos < satoffset[s] + co->NumberOfSat[s] && co->Sat[pos].ID != id;
735 ++pos)
736 ;
737 if (pos >= satoffset[s + 1])
738 return GCOBR_DATAMISMATCH;
739 else if (pos == co->NumberOfSat[s] + satoffset[s])
740 ++co->NumberOfSat[s];
741 co->Sat[pos].ID = id;
742 G_DELTA_CLOCK_C0(co->Sat[pos].Clock.DeltaA0)
743 G_DELTA_CLOCK_C1(co->Sat[pos].Clock.DeltaA1)
744 G_DELTA_CLOCK_C2(co->Sat[pos].Clock.DeltaA2)
745#ifdef BNC_DEBUG
746 fprintf(stderr, "id %2d c0 %8.3f c1 %8.3f c2 %8.3f\n",
747 co->Sat[pos].ID, co->Sat[pos].Clock.DeltaA0, co->Sat[pos].Clock.DeltaA1,
748 co->Sat[pos].Clock.DeltaA2);
749#endif
750 }
751 break;
752 case COBOFS_COMBINED:
753 if (!co)
754 return GCOBR_NOCLOCKORBITPARAMETER;
755 co->messageType = type;
756 G_SSR_EPOCH_TIME_CHECK(co->EpochTime[s], co->NumberOfSat[s])
757 G_SSR_UPDATE_INTERVAL(co->UpdateInterval)
758 G_MULTIPLE_MESSAGE_INDICATOR(mmi)
759 G_SSR_IOD(co->SSRIOD)
760 G_SSR_PROVIDER_ID(co->SSRProviderID)
761 G_SSR_SOLUTION_ID(co->SSRSolutionID)
762 G_SATELLITE_REFERENCE_DATUM(co->SatRefDatum)
763 G_NO_OF_SATELLITES(nums)
764 co->Supplied[COBOFS_ORBIT] |= 1;
765 co->Supplied[COBOFS_CLOCK] |= 1;
766#ifdef BNC_DEBUG
767 fprintf(stderr, "epochTime %d ui %d mmi %d sats %d/%d rd %d ssrIod %d providerId %d solId %d\n",
768 co->EpochTime[s], co->UpdateInterval,mmi,co->NumberOfSat[s],nums,
769 co->SatRefDatum, co->SSRIOD, co->SSRProviderID, co->SSRSolutionID);
770#endif
771 for (i = 0; i < nums; ++i) {
772 G_GNSS_SATELLITE_ID(id)
773 for (pos = satoffset[s];
774 pos < satoffset[s] + co->NumberOfSat[s] && co->Sat[pos].ID != id;
775 ++pos)
776 ;
777 if (pos >= satoffset[s + 1])
778 return GCOBR_DATAMISMATCH;
779 else if (pos == co->NumberOfSat[s] + satoffset[s])
780 ++co->NumberOfSat[s];
781 co->Sat[pos].ID = id;
782 G_GNSS_IOD(co->Sat[pos].IOD)
783 G_DELTA_RADIAL(co->Sat[pos].Orbit.DeltaRadial)
784 G_DELTA_ALONG_TRACK(co->Sat[pos].Orbit.DeltaAlongTrack)
785 G_DELTA_CROSS_TRACK(co->Sat[pos].Orbit.DeltaCrossTrack)
786 G_DELTA_DOT_RADIAL(co->Sat[pos].Orbit.DotDeltaRadial)
787 G_DELTA_DOT_ALONG_TRACK(co->Sat[pos].Orbit.DotDeltaAlongTrack)
788 G_DELTA_DOT_CROSS_TRACK(co->Sat[pos].Orbit.DotDeltaCrossTrack)
789 G_DELTA_CLOCK_C0(co->Sat[pos].Clock.DeltaA0)
790 G_DELTA_CLOCK_C1(co->Sat[pos].Clock.DeltaA1)
791 G_DELTA_CLOCK_C2(co->Sat[pos].Clock.DeltaA2)
792#ifdef BNC_DEBUG
793 fprintf(stderr, "id %2d iod %3d dr %8.4f da %8.4f dc %8.4f dr %8.3f da %8.3f dc %8.3f c0 %8.3f c1 %8.3f c2 %8.3f\n",
794 co->Sat[pos].ID,co->Sat[pos].IOD,co->Sat[pos].Orbit.DeltaRadial,
795 co->Sat[pos].Orbit.DeltaAlongTrack,co->Sat[pos].Orbit.DeltaCrossTrack,
796 co->Sat[pos].Orbit.DotDeltaRadial, co->Sat[pos].Orbit.DotDeltaAlongTrack,
797 co->Sat[pos].Orbit.DotDeltaCrossTrack,
798 co->Sat[pos].Clock.DeltaA0, co->Sat[pos].Clock.DeltaA1, co->Sat[pos].Clock.DeltaA2);
799#endif
800 }
801 break;
802 case COBOFS_URA:
803 if (!co)
804 return GCOBR_NOCLOCKORBITPARAMETER;
805 co->messageType = type;
806 G_SSR_EPOCH_TIME_CHECK(co->EpochTime[s], co->NumberOfSat[s])
807 G_SSR_UPDATE_INTERVAL(co->UpdateInterval)
808 G_MULTIPLE_MESSAGE_INDICATOR(mmi)
809 G_SSR_IOD(co->SSRIOD)
810 G_SSR_PROVIDER_ID(co->SSRProviderID)
811 G_SSR_SOLUTION_ID(co->SSRSolutionID)
812 G_NO_OF_SATELLITES(nums)
813 co->Supplied[COBOFS_URA] |= 1;
814#ifdef BNC_DEBUG
815 fprintf(stderr, "epochTime %d ui %d mmi %d sats %d/%d ssrIod %d providerId %d solId %d\n",
816 co->EpochTime[s], co->UpdateInterval,mmi,co->NumberOfSat[s],nums,
817 co->SSRIOD, co->SSRProviderID, co->SSRSolutionID);
818#endif
819 for (i = 0; i < nums; ++i) {
820 G_GNSS_SATELLITE_ID(id)
821 for (pos = satoffset[s];
822 pos < satoffset[s] + co->NumberOfSat[s] && co->Sat[pos].ID != id;
823 ++pos)
824 ;
825 if (pos >= satoffset[s + 1])
826 return GCOBR_DATAMISMATCH;
827 else if (pos == co->NumberOfSat[s] + satoffset[s])
828 ++co->NumberOfSat[s];
829 co->Sat[pos].ID = id;
830 G_SSR_URA(co->Sat[pos].UserRangeAccuracy)
831#ifdef BNC_DEBUG
832 fprintf(stderr, "id %2d ura %8.3f \n",
833 co->Sat[pos].ID, co->Sat[pos].UserRangeAccuracy);
834#endif
835 }
836 break;
837 case COBOFS_HR:
838 if (!co)
839 return GCOBR_NOCLOCKORBITPARAMETER;
840 co->messageType = type;
841 G_SSR_EPOCH_TIME_CHECK(co->EpochTime[s], co->NumberOfSat[s])
842 G_SSR_UPDATE_INTERVAL(co->UpdateInterval)
843 G_MULTIPLE_MESSAGE_INDICATOR(mmi)
844 G_SSR_IOD(co->SSRIOD)
845 G_SSR_PROVIDER_ID(co->SSRProviderID)
846 G_SSR_SOLUTION_ID(co->SSRSolutionID)
847 G_NO_OF_SATELLITES(nums)
848 co->Supplied[COBOFS_HR] |= 1;
849#ifdef BNC_DEBUG
850 fprintf(stderr, "epochTime %d ui %d mmi %d sats %d/%d ssrIod %d providerId %d solId %d\n",
851 co->EpochTime[s], co->UpdateInterval,mmi,co->NumberOfSat[s],nums,
852 co->SSRIOD, co->SSRProviderID, co->SSRSolutionID);
853#endif
854 for (i = 0; i < nums; ++i) {
855 G_GNSS_SATELLITE_ID(id)
856 for (pos = satoffset[s];
857 pos < satoffset[s] + co->NumberOfSat[s] && co->Sat[pos].ID != id;
858 ++pos)
859 ;
860 if (pos >= satoffset[s + 1])
861 return GCOBR_DATAMISMATCH;
862 else if (pos == co->NumberOfSat[s] + satoffset[s])
863 ++co->NumberOfSat[s];
864 co->Sat[pos].ID = id;
865 G_HR_CLOCK_CORRECTION(co->Sat[pos].hrclock)
866#ifdef BNC_DEBUG
867 fprintf(stderr, "id %2d hrClock %8.3f \n",
868 co->Sat[pos].ID, co->Sat[pos].hrclock);
869#endif
870 }
871 break;
872 case COBOFS_CBIAS:
873 if (!b)
874 return GCOBR_NOCODEBIASPARAMETER;
875 b->messageType = type;
876 G_SSR_EPOCH_TIME_CHECK(b->EpochTime[s], b->NumberOfSat[s])
877 G_SSR_UPDATE_INTERVAL(b->UpdateInterval)
878 G_MULTIPLE_MESSAGE_INDICATOR(mmi)
879 G_SSR_IOD(b->SSRIOD)
880 G_SSR_PROVIDER_ID(b->SSRProviderID)
881 G_SSR_SOLUTION_ID(b->SSRSolutionID)
882 G_NO_OF_SATELLITES(nums)
883#ifdef BNC_DEBUG
884 fprintf(stderr, "epochTime %d ui %d mmi %d sats %d/%d ssrIod %d providerId %d solId %d\n",
885 b->EpochTime[s], b->UpdateInterval,mmi,b->NumberOfSat[s],nums,
886 b->SSRIOD, b->SSRProviderID, b->SSRSolutionID);
887#endif
888 for (i = 0; i < nums; ++i) {
889 G_GNSS_SATELLITE_ID(id)
890 for (pos = satoffset[s];
891 pos < satoffset[s] + b->NumberOfSat[s] && b->Sat[pos].ID != id;
892 ++pos)
893 ;
894 if (pos >= satoffset[s + 1])
895 return GCOBR_DATAMISMATCH;
896 else if (pos == b->NumberOfSat[s] + satoffset[s])
897 ++b->NumberOfSat[s];
898 b->Sat[pos].ID = id;
899 G_NO_OF_BIASES(b->Sat[pos].NumberOfCodeBiases)
900#ifdef BNC_DEBUG
901 fprintf(stderr, "id %2d #%d ",
902 b->Sat[pos].ID, b->Sat[pos].NumberOfCodeBiases);
903#endif
904 for (j = 0; j < b->Sat[pos].NumberOfCodeBiases; ++j) {
905 G_GNSS_SIGNAL_IDENTIFIER(b->Sat[pos].Biases[j].Type)
906 G_CODE_BIAS(b->Sat[pos].Biases[j].Bias)
907#ifdef BNC_DEBUG
908 fprintf(stderr, "t%d b %8.2f ",
909 b->Sat[pos].Biases[j].Type, b->Sat[pos].Biases[j].Bias);
910#endif
911 }
912#ifdef BNC_DEBUG
913 fprintf(stderr, "\n");
914#endif
915 }
916 break;
917 case COBOFS_PBIAS:
918 if (!pb)
919 return GCOBR_NOPHASEBIASPARAMETER;
920 pb->messageType = type;
921 G_SSR_EPOCH_TIME_CHECK(pb->EpochTime[s], pb->NumberOfSat[s])
922 G_SSR_UPDATE_INTERVAL(pb->UpdateInterval)
923 G_MULTIPLE_MESSAGE_INDICATOR(mmi)
924 G_SSR_IOD(pb->SSRIOD)
925 G_SSR_PROVIDER_ID(pb->SSRProviderID)
926 G_SSR_SOLUTION_ID(pb->SSRSolutionID)
927 G_DISPERSIVE_BIAS_INDICATOR(pb->DispersiveBiasConsistencyIndicator)
928 G_MW_CONSISTENCY_INDICATOR(pb->MWConsistencyIndicator)
929 G_NO_OF_SATELLITES(nums)
930#ifdef BNC_DEBUG
931 fprintf(stderr, "epochTime %d ui %d mmi %d sats %d/%d ssrIod %d providerId %d solId %d dispInd %d mwInd %d\n",
932 pb->EpochTime[s], pb->UpdateInterval,mmi,pb->NumberOfSat[s],nums,
933 pb->SSRIOD, pb->SSRProviderID, pb->SSRSolutionID,
934 pb->DispersiveBiasConsistencyIndicator, pb->MWConsistencyIndicator);
935#endif
936 for (i = 0; i < nums; ++i) {
937 G_GNSS_SATELLITE_ID(id)
938 for (pos = satoffset[s];
939 pos < satoffset[s] + pb->NumberOfSat[s] && pb->Sat[pos].ID != id;
940 ++pos)
941 ;
942 if (pos >= satoffset[s + 1])
943 return GCOBR_DATAMISMATCH;
944 else if (pos == pb->NumberOfSat[s] + satoffset[s])
945 ++pb->NumberOfSat[s];
946 pb->Sat[pos].ID = id;
947 G_NO_OF_BIASES(pb->Sat[pos].NumberOfPhaseBiases)
948 G_YAW_ANGLE(pb->Sat[pos].YawAngle)
949 G_YAW_RATE(pb->Sat[pos].YawRate)
950#ifdef BNC_DEBUG
951 fprintf(stderr, "id %2d #%d y %8.3f yr %8.3f ",
952 pb->Sat[pos].ID, pb->Sat[pos].NumberOfPhaseBiases,
953 pb->Sat[pos].YawAngle, pb->Sat[pos].YawRate);
954#endif
955 for (j = 0; j < pb->Sat[pos].NumberOfPhaseBiases; ++j) {
956 G_GNSS_SIGNAL_IDENTIFIER(pb->Sat[pos].Biases[j].Type)
957 G_INTEGER_INDICATOR(pb->Sat[pos].Biases[j].SignalIntegerIndicator)
958 G_WIDE_LANE_INDICATOR(pb->Sat[pos].Biases[j].SignalsWideLaneIntegerIndicator)
959 G_DISCONTINUITY_COUNTER(pb->Sat[pos].Biases[j].SignalDiscontinuityCounter)
960 G_PHASE_BIAS(pb->Sat[pos].Biases[j].Bias)
961#ifdef BNC_DEBUG
962 fprintf(stderr, "t%d int %d wl %d disc %d b %8.4f ",
963 pb->Sat[pos].Biases[j].Type,
964 pb->Sat[pos].Biases[j].SignalIntegerIndicator,
965 pb->Sat[pos].Biases[j].SignalsWideLaneIntegerIndicator,
966 pb->Sat[pos].Biases[j].SignalDiscontinuityCounter,
967 pb->Sat[pos].Biases[j].Bias);
968#endif
969 }
970#ifdef BNC_DEBUG
971 fprintf(stderr, "\n");
972#endif
973 }
974 break;
975 default:
976 continue;
977 }
978#ifdef BNC_DEBUG
979 for(type = 0; type < (unsigned int)size && (unsigned char)buffer[type] != 0xD3; ++type)
980 numbits += 8;
981 fprintf(stderr, "numbits left %d\n",numbits);
982#endif
983 return mmi ? GCOBR_MESSAGEFOLLOWS : GCOBR_OK;
984 }
985 }
986 return GCOBR_UNKNOWNTYPE;
987}
988#endif /* NODECODE */
989
990
991
Note: See TracBrowser for help on using the repository browser.