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

Last change on this file since 8972 was 8972, checked in by stuerze, 2 months ago

minor changes regarding igs ssr decoding

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