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, 2 months 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.