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

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

minor changes

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