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

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

intial imprort for igs ssr encoding and decoding

  • Property svn:executable set to *
File size: 34.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
20static uint32_t CRC24(long size, const unsigned char *buf) {
21 uint32_t crc = 0;
22 int i;
23
24 while (size--) {
25 crc ^= (*buf++) << (16);
26 for (i = 0; i < 8; i++)
27 {
28 crc <<= 1;
29 if (crc & 0x1000000)
30 crc ^= 0x01864cfb;
31 }
32 }
33 return crc;
34}
35
36/* NOTE: These defines are interlinked with below functions and directly modify
37 the values. This may not be optimized in terms of final program code size but
38 should be optimized in terms of speed.
39
40 modified variables are:
41 - everything defined in STARTDATA (only use ressize outside of the defines,
42 others are private)
43 - buffer
44 - size
45 */
46
47#ifndef NOENCODE
48#define STOREBITS \
49 while(numbits >= 8) { \
50 if(!size) return 0; \
51 *(buffer++) = bitbuffer>>(numbits-8); \
52 numbits -= 8; \
53 ++ressize; \
54 --size; \
55 }
56
57#define ADDBITS(a, b) { \
58 bitbuffer = (bitbuffer<<(a))|((b)&((1<<a)-1)); \
59 numbits += (a); \
60 STOREBITS \
61 }
62
63#define STARTDATA \
64 size_t ressize=0; \
65 char *blockstart; \
66 int numbits; \
67 uint64_t bitbuffer=0;
68
69#define INITBLOCK \
70 numbits = 0; \
71 blockstart = buffer; \
72 ADDBITS(8, 0xD3) \
73 ADDBITS(6, 0) \
74 ADDBITS(10, 0)
75
76#define ENDBLOCK \
77 if(numbits) { ADDBITS((8-numbits), 0) } { \
78 int len = buffer-blockstart-3; \
79 blockstart[1] |= len>>8; \
80 blockstart[2] = len; \
81 if(len > 1023) \
82 return 0; \
83 len = CRC24(len+3, (const unsigned char *) blockstart); \
84 ADDBITS(24, len) \
85 }
86
87#define SCALEADDBITS(a, b, c) ADDBITS(a, (int64_t)(c > 0 ? b*c+0.5 : b*c-0.5))
88
89#define MPI 3.141592653589793
90
91/* GNSS macros - Header part */
92#define T_RTCM_MESSAGE_NUMBER(a) ADDBITS(12, a) /* DF002 */
93#define T_IGS_SSR_VERSION(a) ADDBITS( 3, a) /* IDF001 */
94#define T_IGS_MESSAGE_NUMBER(a) ADDBITS( 8, a) /* IDF002 */
95#define T_SSR_EPOCH_TIME(a) ADDBITS(20, a) /* IDF003 */
96#define T_SSR_UPDATE_INTERVAL(a) ADDBITS( 4, a) /* DF391, IDF004 */
97#define T_MULTIPLE_MESSAGE_INDICATOR(a) ADDBITS( 1, a) /* DF388, IDF005 */
98#define T_SSR_IOD(a) ADDBITS( 4, a) /* DF413, IDF007 */
99#define T_SSR_PROVIDER_ID(a) ADDBITS(16, a) /* DF414, IDF008 */
100#define T_SSR_SOLUTION_ID(a) ADDBITS( 4, a) /* DF415, IDF009 */
101#define T_SATELLITE_REFERENCE_DATUM(a) ADDBITS( 1, a) /* DF375, IDF006 */
102#define T_NO_OF_SATELLITES(a) ADDBITS( 6, a) /* DF387, IDF010 */
103
104/* GNSS macros - Satellite specific part */
105#define T_GNSS_SATELLITE_ID(a) ADDBITS( 6, a) /* IDF011 */
106#define T_GNSS_IOD(a) ADDBITS( 8, a) /* IDF012 */
107
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
545#define G_CODE_BIAS(a) GETFLOATSIGN(a, 14, 1/100.0) /* DF383, IDF025 */
546#define G_YAW_ANGLE(a) GETFLOAT (a, 9, MPI/256.0) /* DF480, IDF026 */
547#define G_YAW_RATE(a) GETFLOATSIGN(a, 8, MPI/8192.0) /* DF481, IDF027 */
548#define G_PHASE_BIAS(a) GETFLOATSIGN(a, 20, 1/10000.) /* DF482, IDF028 */
549
550#define G_INTEGER_INDICATOR(a) GETBITS(a, 1) /* DF483, IDF029 */
551#define G_WIDE_LANE_INDICATOR(a) GETBITS(a, 2) /* DF484, IDF030 */
552#define G_DISCONTINUITY_COUNTER(a) GETBITS(a, 4) /* DF485, IDF031 */
553#define G_DISPERSIVE_BIAS_INDICATOR(a) GETBITS(a, 1) /* DF486, IDF032 */
554#define G_MW_CONSISTENCY_INDICATOR(a) GETBITS(a, 1) /* DF487, IDF033 */
555
556#define G_SSR_URA(a) {int temp; GETBITS(temp, 6) \
557 (a) = URAToValue(temp);} /* DF389, IDF034 */
558
559/* Ionosphere */
560#define G_NO_IONO_LAYERS(a) {unsigned int temp; GETBITS(temp, 2) a = temp+1;} /* DF472, IDF035 */
561#define G_IONO_HEIGHT(a) GETFLOAT(a, 8 , 10000.0) /* DF473, IDF036 */
562#define G_IONO_DEGREE(a) {unsigned int temp; GETBITS(temp, 4) a = temp+1;} /* DF474, IDF037 */
563#define G_IONO_ORDER(a) {unsigned int temp; GETBITS(temp, 4) a = temp+1;} /* DF475, IDF038 */
564#define G_IONO_COEFF_C(a) GETFLOATSIGN(a, 16,1/200.0) /* DF476, IDF039 */
565#define G_IONO_COEFF_S(a) GETFLOATSIGN(a, 16,1/200.0) /* DF477, IDF040 */
566#define G_VTEC_QUALITY_INDICATOR(a) GETFLOAT(a, 9, 1/20.0) /* DF478, IDF041 */
567
568
569enum GCOB_RETURN GetSSR(struct ClockOrbit *co, struct CodeBias *b,struct VTEC *v,
570 struct PhaseBias *pb, const char *buffer, size_t size, int *bytesused) {
571 int mmi = 0, h, rs;
572 unsigned int type, pos, i, j, s, nums, id;
573 size_t sizeofrtcmblock;
574 const char *blockstart = buffer;
575 DECODESTART
576
577 if (size < 7)
578 return GCOBR_SHORTBUFFER;
579
580#ifdef DEBUG
581 fprintf(stderr, "GetClockOrbitBias START: size %d, numbits %d\n",size, numbits);
582#endif
583
584 G_HEADER(h)
585 G_RESERVEDH(rs)
586 G_SIZE(sizeofrtcmblock);
587
588 if ((unsigned char) h != 0xD3 || rs)
589 return GCOBR_UNKNOWNDATA;
590 if (size < sizeofrtcmblock + 3) /* 3 header bytes already removed */
591 return GCOBR_MESSAGEEXCEEDSBUFFER;
592 if (CRC24(sizeofrtcmblock + 3, (const unsigned char *) blockstart) !=
593 (uint32_t) ((((unsigned char) buffer[sizeofrtcmblock]) << 16) |
594 (((unsigned char) buffer[sizeofrtcmblock + 1]) << 8) |
595 (((unsigned char) buffer[sizeofrtcmblock + 2]))))
596 return GCOBR_CRCMISMATCH;
597 size = sizeofrtcmblock; /* reduce size, so overflows are detected */
598
599 SKIPBITS(12) // G_RTCM_MESSAGE_NUMBER(a)
600 SKIPBITS( 3) // G_IGS_SSR_VERSION(a)
601 G_IGS_MESSAGE_NUMBER(type)
602#ifdef DEBUG
603 fprintf(stderr, "type %d size %d\n",type,sizeofrtcmblock);
604#endif
605 if (bytesused)
606 *bytesused = sizeofrtcmblock + 6;
607
608 if (type == VTEC_BASE) {
609 unsigned int l, o, d;
610 if (!v)
611 return GCOBR_NOVTECPARAMETER;
612 memset(v, 0, sizeof(*v));
613 G_SSR_EPOCH_TIME(v->EpochTime)
614 G_SSR_UPDATE_INTERVAL(v->UpdateInterval)
615 G_MULTIPLE_MESSAGE_INDICATOR(mmi)
616 G_SSR_IOD(v->SSRIOD)
617 G_SSR_PROVIDER_ID(v->SSRProviderID)
618 G_SSR_SOLUTION_ID(v->SSRSolutionID)
619 G_VTEC_QUALITY_INDICATOR(v->Quality)
620 G_NO_IONO_LAYERS(v->NumLayers)
621 for (l = 0; l < v->NumLayers; ++l) {
622 G_IONO_HEIGHT(v->Layers[l].Height)
623 G_IONO_DEGREE(v->Layers[l].Degree)
624 G_IONO_ORDER(v->Layers[l].Order)
625 for (o = 0; o <= v->Layers[l].Order; ++o) {
626 for (d = o; d <= v->Layers[l].Degree; ++d) {
627 G_IONO_COEFF_C(v->Layers[l].Cosinus[d][o])
628 }
629 }
630 for (o = 1; o <= v->Layers[l].Order; ++o) {
631 for (d = o; d <= v->Layers[l].Degree; ++d) {
632 G_IONO_COEFF_S(v->Layers[l].Sinus[d][o])
633 }
634 }
635 }
636#ifdef DEBUG
637 for(type = 0; type < (int)size && (unsigned char)buffer[type] != 0xD3; ++type)
638 numbits += 8;
639 fprintf(stderr, "numbits left %d\n",numbits);
640#endif
641 return mmi ? GCOBR_MESSAGEFOLLOWS : GCOBR_OK;
642 }
643
644
645
646 for (s = CLOCKORBIT_SATNUM; s-- > 0;) {
647 if (type == corbase[s] + s) {
648 if (!pb)
649 return GCOBR_NOPHASEBIASPARAMETER;
650 pb->messageType = type;
651 G_SSR_EPOCH_TIME_CHECK(pb->EpochTime[s], pb->NumberOfSat[s])
652 G_SSR_UPDATE_INTERVAL(pb->UpdateInterval)
653 G_MULTIPLE_MESSAGE_INDICATOR(mmi)
654 G_SSR_IOD(pb->SSRIOD)
655 G_SSR_PROVIDER_ID(pb->SSRProviderID)
656 G_SSR_SOLUTION_ID(pb->SSRSolutionID)
657 G_DISPERSIVE_BIAS_INDICATOR(pb->DispersiveBiasConsistencyIndicator)
658 G_MW_CONSISTENCY_INDICATOR(pb->MWConsistencyIndicator)
659 G_NO_OF_SATELLITES(nums)
660 for (i = 0; i < nums; ++i) {
661 G_GNSS_SATELLITE_ID(id)
662 for (pos = satoffset[s];
663 pos < satoffset[s] + pb->NumberOfSat[s] && pb->Sat[pos].ID != id;
664 ++pos)
665 ;
666 if (pos >= satoffset[s + 1])
667 return GCOBR_DATAMISMATCH;
668 else if (pos == pb->NumberOfSat[s] + satoffset[s])
669 ++pb->NumberOfSat[s];
670 pb->Sat[pos].ID = id;
671 G_NO_OF_BIASES(pb->Sat[pos].NumberOfPhaseBiases)
672 G_YAW_ANGLE(pb->Sat[pos].YawAngle)
673 G_YAW_RATE(pb->Sat[pos].YawRate)
674 for (j = 0; j < pb->Sat[pos].NumberOfPhaseBiases; ++j) {
675 G_GNSS_SIGNAL_IDENTIFIER(pb->Sat[pos].Biases[j].Type)
676 G_INTEGER_INDICATOR(pb->Sat[pos].Biases[j].SignalIntegerIndicator)
677 G_WIDE_LANE_INDICATOR(pb->Sat[pos].Biases[j].SignalsWideLaneIntegerIndicator)
678 G_DISCONTINUITY_COUNTER(pb->Sat[pos].Biases[j].SignalDiscontinuityCounter)
679 G_PHASE_BIAS(pb->Sat[pos].Biases[j].Bias)
680 }
681 }
682#ifdef DEBUG
683 for(type = 0; type < (int)size && (unsigned char)buffer[type] != 0xD3; ++type)
684 numbits += 8;
685 fprintf(stderr, "numbits left %d\n",numbits);
686#endif
687 return mmi ? GCOBR_MESSAGEFOLLOWS : GCOBR_OK;
688 }
689 else if (type >= corbase[s]) {
690 switch (type - corbase[s]) {
691 case COBOFS_ORBIT:
692 if (!co)
693 return GCOBR_NOCLOCKORBITPARAMETER;
694 co->messageType = type;
695 G_SSR_EPOCH_TIME_CHECK(co->EpochTime[s], co->NumberOfSat[s])
696 G_SSR_UPDATE_INTERVAL(co->UpdateInterval)
697 G_MULTIPLE_MESSAGE_INDICATOR(mmi)
698 G_SSR_IOD(co->SSRIOD)
699 G_SSR_PROVIDER_ID(co->SSRProviderID)
700 G_SSR_SOLUTION_ID(co->SSRSolutionID)
701 G_SATELLITE_REFERENCE_DATUM(co->SatRefDatum)
702 G_NO_OF_SATELLITES(nums)
703 co->Supplied[COBOFS_ORBIT] |= 1;
704#ifdef DEBUG
705 fprintf(stderr, "epochtime %d ui %d mmi %d sats %d/%d rd %d\n",co->EpochTime[s],
706 co->UpdateInterval,mmi,co->NumberOfSat[s],nums, co->SatRefDatum);
707#endif
708 for (i = 0; i < nums; ++i) {
709 G_GNSS_SATELLITE_ID(id)
710 for (pos = satoffset[s];
711 pos < satoffset[s] + co->NumberOfSat[s] && co->Sat[pos].ID != id;
712 ++pos)
713 ;
714 if (pos >= satoffset[s + 1])
715 return GCOBR_DATAMISMATCH;
716 else if (pos == co->NumberOfSat[s] + satoffset[s])
717 ++co->NumberOfSat[s];
718 co->Sat[pos].ID = id;
719 G_GNSS_IOD(co->Sat[pos].IOD)
720 G_DELTA_RADIAL(co->Sat[pos].Orbit.DeltaRadial)
721 G_DELTA_ALONG_TRACK(co->Sat[pos].Orbit.DeltaAlongTrack)
722 G_DELTA_CROSS_TRACK(co->Sat[pos].Orbit.DeltaCrossTrack)
723 G_DELTA_DOT_RADIAL(co->Sat[pos].Orbit.DotDeltaRadial)
724 G_DELTA_DOT_ALONG_TRACK(co->Sat[pos].Orbit.DotDeltaAlongTrack)
725 G_DELTA_DOT_CROSS_TRACK(co->Sat[pos].Orbit.DotDeltaCrossTrack)
726#ifdef DEBUG
727 fprintf(stderr, "id %2d iod %3d dr %8.3f da %8.3f dc %8.3f dr %8.3f da %8.3f dc %8.3f\n",
728 co->Sat[pos].ID,co->Sat[pos].IOD,co->Sat[pos].Orbit.DeltaRadial,
729 co->Sat[pos].Orbit.DeltaAlongTrack,co->Sat[pos].Orbit.DeltaCrossTrack,
730 co->Sat[pos].Orbit.DotDeltaRadial,
731 co->Sat[pos].Orbit.DotDeltaAlongTrack,
732 co->Sat[pos].Orbit.DotDeltaCrossTrack);
733#endif
734 }
735 break;
736 case COBOFS_CLOCK:
737 if (!co)
738 return GCOBR_NOCLOCKORBITPARAMETER;
739 co->messageType = type;
740 G_SSR_EPOCH_TIME_CHECK(co->EpochTime[s], co->NumberOfSat[s])
741 G_SSR_UPDATE_INTERVAL(co->UpdateInterval)
742 G_MULTIPLE_MESSAGE_INDICATOR(mmi)
743 G_SSR_IOD(co->SSRIOD)
744 G_SSR_PROVIDER_ID(co->SSRProviderID)
745 G_SSR_SOLUTION_ID(co->SSRSolutionID)
746 G_NO_OF_SATELLITES(nums)
747 co->Supplied[COBOFS_CLOCK] |= 1;
748#ifdef DEBUG
749 fprintf(stderr, "epochtime %d ui %d mmi %d sats %d/%d\n",co->EpochTime[s],
750 co->UpdateInterval,mmi,co->NumberOfSat[s],nums);
751#endif
752 for (i = 0; i < nums; ++i) {
753 G_GNSS_SATELLITE_ID(id)
754 for (pos = satoffset[s];
755 pos < satoffset[s] + co->NumberOfSat[s] && co->Sat[pos].ID != id;
756 ++pos)
757 ;
758 if (pos >= satoffset[s + 1])
759 return GCOBR_DATAMISMATCH;
760 else if (pos == co->NumberOfSat[s] + satoffset[s])
761 ++co->NumberOfSat[s];
762 co->Sat[pos].ID = id;
763 G_DELTA_CLOCK_C0(co->Sat[pos].Clock.DeltaA0)
764 G_DELTA_CLOCK_C1(co->Sat[pos].Clock.DeltaA1)
765 G_DELTA_CLOCK_C2(co->Sat[pos].Clock.DeltaA2)
766#ifdef DEBUG
767 fprintf(stderr, "id %2d c0 %8.3f c1 %8.3f c2 %8.3f\n",
768 co->Sat[pos].ID, co->Sat[pos].Clock.DeltaA0, co->Sat[pos].Clock.DeltaA1,
769 co->Sat[pos].Clock.DeltaA2);
770#endif
771 }
772 break;
773 case COBOFS_COMBINED:
774 if (!co)
775 return GCOBR_NOCLOCKORBITPARAMETER;
776 co->messageType = type;
777 G_SSR_EPOCH_TIME_CHECK(co->EpochTime[s], co->NumberOfSat[s])
778 G_SSR_UPDATE_INTERVAL(co->UpdateInterval)
779 G_MULTIPLE_MESSAGE_INDICATOR(mmi)
780 G_SSR_IOD(co->SSRIOD)
781 G_SSR_PROVIDER_ID(co->SSRProviderID)
782 G_SSR_SOLUTION_ID(co->SSRSolutionID)
783 G_SATELLITE_REFERENCE_DATUM(co->SatRefDatum)
784 G_NO_OF_SATELLITES(nums)
785 co->Supplied[COBOFS_ORBIT] |= 1;
786 co->Supplied[COBOFS_CLOCK] |= 1;
787 for (i = 0; i < nums; ++i) {
788 G_GNSS_SATELLITE_ID(id)
789 for (pos = satoffset[s];
790 pos < satoffset[s] + co->NumberOfSat[s] && co->Sat[pos].ID != id;
791 ++pos)
792 ;
793 if (pos >= satoffset[s + 1])
794 return GCOBR_DATAMISMATCH;
795 else if (pos == co->NumberOfSat[s] + satoffset[s])
796 ++co->NumberOfSat[s];
797 co->Sat[pos].ID = id;
798 G_GNSS_IOD(co->Sat[pos].IOD)
799 G_DELTA_RADIAL(co->Sat[pos].Orbit.DeltaRadial)
800 G_DELTA_ALONG_TRACK(co->Sat[pos].Orbit.DeltaAlongTrack)
801 G_DELTA_CROSS_TRACK(co->Sat[pos].Orbit.DeltaCrossTrack)
802 G_DELTA_DOT_RADIAL(co->Sat[pos].Orbit.DotDeltaRadial)
803 G_DELTA_DOT_ALONG_TRACK(co->Sat[pos].Orbit.DotDeltaAlongTrack)
804 G_DELTA_DOT_CROSS_TRACK(co->Sat[pos].Orbit.DotDeltaCrossTrack)
805 G_DELTA_CLOCK_C0(co->Sat[pos].Clock.DeltaA0)
806 G_DELTA_CLOCK_C1(co->Sat[pos].Clock.DeltaA1)
807 G_DELTA_CLOCK_C2(co->Sat[pos].Clock.DeltaA2)
808 }
809 break;
810 case COBOFS_URA:
811 if (!co)
812 return GCOBR_NOCLOCKORBITPARAMETER;
813 co->messageType = type;
814 G_SSR_EPOCH_TIME_CHECK(co->EpochTime[s], co->NumberOfSat[s])
815 G_SSR_UPDATE_INTERVAL(co->UpdateInterval)
816 G_MULTIPLE_MESSAGE_INDICATOR(mmi)
817 G_SSR_IOD(co->SSRIOD)
818 G_SSR_PROVIDER_ID(co->SSRProviderID)
819 G_SSR_SOLUTION_ID(co->SSRSolutionID)
820 G_NO_OF_SATELLITES(nums)
821 co->Supplied[COBOFS_URA] |= 1;
822 for (i = 0; i < nums; ++i) {
823 G_GNSS_SATELLITE_ID(id)
824 for (pos = satoffset[s];
825 pos < satoffset[s] + co->NumberOfSat[s] && co->Sat[pos].ID != id;
826 ++pos)
827 ;
828 if (pos >= satoffset[s + 1])
829 return GCOBR_DATAMISMATCH;
830 else if (pos == co->NumberOfSat[s] + satoffset[s])
831 ++co->NumberOfSat[s];
832 co->Sat[pos].ID = id;
833 G_SSR_URA(co->Sat[pos].UserRangeAccuracy)
834 }
835 break;
836 case COBOFS_HR:
837 if (!co)
838 return GCOBR_NOCLOCKORBITPARAMETER;
839 co->messageType = type;
840 G_SSR_EPOCH_TIME_CHECK(co->EpochTime[s], co->NumberOfSat[s])
841 G_SSR_UPDATE_INTERVAL(co->UpdateInterval)
842 G_MULTIPLE_MESSAGE_INDICATOR(mmi)
843 G_SSR_IOD(co->SSRIOD)
844 G_SSR_PROVIDER_ID(co->SSRProviderID)
845 G_SSR_SOLUTION_ID(co->SSRSolutionID)
846 G_NO_OF_SATELLITES(nums)
847 co->Supplied[COBOFS_HR] |= 1;
848 for (i = 0; i < nums; ++i) {
849 G_GNSS_SATELLITE_ID(id)
850 for (pos = satoffset[s];
851 pos < satoffset[s] + co->NumberOfSat[s] && co->Sat[pos].ID != id;
852 ++pos)
853 ;
854 if (pos >= satoffset[s + 1])
855 return GCOBR_DATAMISMATCH;
856 else if (pos == co->NumberOfSat[s] + satoffset[s])
857 ++co->NumberOfSat[s];
858 co->Sat[pos].ID = id;
859 G_HR_CLOCK_CORRECTION(co->Sat[pos].hrclock)
860 }
861 break;
862 case COBOFS_CBIAS:
863 if (!b)
864 return GCOBR_NOCODEBIASPARAMETER;
865 b->messageType = type;
866 G_SSR_EPOCH_TIME_CHECK(b->EpochTime[s], b->NumberOfSat[s])
867 G_SSR_UPDATE_INTERVAL(b->UpdateInterval)
868 G_MULTIPLE_MESSAGE_INDICATOR(mmi)
869 G_SSR_IOD(b->SSRIOD)
870 G_SSR_PROVIDER_ID(b->SSRProviderID)
871 G_SSR_SOLUTION_ID(b->SSRSolutionID)
872 G_NO_OF_SATELLITES(nums)
873 for (i = 0; i < nums; ++i) {
874 G_GNSS_SATELLITE_ID(id)
875 for (pos = satoffset[s];
876 pos < satoffset[s] + b->NumberOfSat[s] && b->Sat[pos].ID != id;
877 ++pos)
878 ;
879 if (pos >= satoffset[s + 1])
880 return GCOBR_DATAMISMATCH;
881 else if (pos == b->NumberOfSat[s] + satoffset[s])
882 ++b->NumberOfSat[s];
883 b->Sat[pos].ID = id;
884 G_NO_OF_BIASES(b->Sat[pos].NumberOfCodeBiases)
885 for (j = 0; j < b->Sat[pos].NumberOfCodeBiases; ++j) {
886 G_GNSS_SIGNAL_IDENTIFIER(b->Sat[pos].Biases[j].Type)
887 G_CODE_BIAS(b->Sat[pos].Biases[j].Bias)
888 }
889 }
890 break;
891 default:
892 continue;
893 }
894#ifdef DEBUG
895 for(type = 0; type < (int)size && (unsigned char)buffer[type] != 0xD3; ++type)
896 numbits += 8;
897 fprintf(stderr, "numbits left %d\n",numbits);
898#endif
899 return mmi ? GCOBR_MESSAGEFOLLOWS : GCOBR_OK;
900 }
901 }
902 return GCOBR_UNKNOWNTYPE;
903}
904#endif /* NODECODE */
905
906
907
Note: See TracBrowser for help on using the repository browser.