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