1/*
2 * /src/NTP/REPOSITORY/ntp4-dev/libparse/data_mbg.c,v 4.8 2006/06/22 18:40:01 kardel RELEASE_20060622_A
3 *
4 * data_mbg.c,v 4.8 2006/06/22 18:40:01 kardel RELEASE_20060622_A
5 *
6 * $Created: Sun Jul 20 12:08:14 1997 $
7 *
8 * Copyright (c) 1997-2005 by Frank Kardel <kardel <AT> ntp.org>
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the author nor the names of its contributors
19 *    may be used to endorse or promote products derived from this software
20 *    without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 */
35
36#include <config.h>
37#ifdef PARSESTREAM
38#define NEED_BOPS
39#include "ntp_string.h"
40#else
41#include <stdio.h>
42#endif
43#include "ntp_types.h"
44#include "ntp_stdlib.h"
45#include "ntp_fp.h"
46#include "ntp_calendar.h"
47#include "mbg_gps166.h"
48#include "binio.h"
49#include "ieee754io.h"
50
51static void get_mbg_tzname (unsigned char **, char *);
52static void mbg_time_status_str (char **, unsigned int, int);
53
54#if 0				/* no actual floats on Meinberg binary interface */
55static offsets_t mbg_float  = { 1, 0, 3, 2, 0, 0, 0, 0 }; /* byte order for meinberg floats */
56#endif
57static offsets_t mbg_double = { 1, 0, 3, 2, 5, 4, 7, 6 }; /* byte order for meinberg doubles */
58static int32   rad2deg_i = 57;
59static u_int32 rad2deg_f = 0x4BB834C7; /* 57.2957795131 == 180/PI */
60
61void
62put_mbg_header(
63	unsigned char **bufpp,
64	GPS_MSG_HDR *headerp
65	)
66{
67  put_lsb_short(bufpp, headerp->cmd);
68  put_lsb_short(bufpp, headerp->len);
69  put_lsb_short(bufpp, headerp->data_csum);
70  put_lsb_short(bufpp, headerp->hdr_csum);
71}
72
73void
74get_mbg_sw_rev(
75	unsigned char **bufpp,
76	SW_REV *sw_revp
77	)
78{
79  sw_revp->code = get_lsb_uint16(bufpp);
80  memcpy(sw_revp->name, *bufpp, sizeof(sw_revp->name));
81  *bufpp += sizeof(sw_revp->name);
82}
83
84void
85get_mbg_ascii_msg(
86	unsigned char **bufpp,
87	ASCII_MSG *ascii_msgp
88	)
89{
90  ascii_msgp->csum  = (CSUM) get_lsb_short(bufpp);
91  ascii_msgp->valid = get_lsb_int16(bufpp);
92  memcpy(ascii_msgp->s, *bufpp, sizeof(ascii_msgp->s));
93  *bufpp += sizeof(ascii_msgp->s);
94}
95
96void
97get_mbg_svno(
98	unsigned char **bufpp,
99	SVNO *svnop
100	)
101{
102  *svnop = (SVNO) get_lsb_short(bufpp);
103}
104
105void
106get_mbg_health(
107	unsigned char **bufpp,
108	HEALTH *healthp
109	)
110{
111  *healthp = (HEALTH) get_lsb_short(bufpp);
112}
113
114void
115get_mbg_cfg(
116	unsigned char **bufpp,
117	CFG *cfgp
118	)
119{
120  *cfgp = (CFG) get_lsb_short(bufpp);
121}
122
123void
124get_mbg_tgps(
125	unsigned char **bufpp,
126	T_GPS *tgpsp
127	)
128{
129  tgpsp->wn = get_lsb_uint16(bufpp);
130  tgpsp->sec = get_lsb_long(bufpp);
131  tgpsp->tick = get_lsb_long(bufpp);
132}
133
134void
135get_mbg_tm(
136	unsigned char **buffpp,
137	TM_GPS *tmp
138	)
139{
140  tmp->year = get_lsb_int16(buffpp);
141  tmp->month = *(*buffpp)++;
142  tmp->mday = *(*buffpp)++;
143  tmp->yday = get_lsb_int16(buffpp);
144  tmp->wday = *(*buffpp)++;
145  tmp->hour = *(*buffpp)++;
146  tmp->min = *(*buffpp)++;
147  tmp->sec = *(*buffpp)++;
148  tmp->frac = get_lsb_long(buffpp);
149  tmp->offs_from_utc = get_lsb_long(buffpp);
150  tmp->status = get_lsb_uint16(buffpp);
151}
152
153void
154get_mbg_ttm(
155	unsigned char **buffpp,
156	TTM *ttmp
157	)
158{
159  ttmp->channel = get_lsb_int16(buffpp);
160  get_mbg_tgps(buffpp, &ttmp->t);
161  get_mbg_tm(buffpp, &ttmp->tm);
162}
163
164void
165get_mbg_synth(
166	unsigned char **buffpp,
167	SYNTH *synthp
168	)
169{
170  synthp->freq  = get_lsb_int16(buffpp);
171  synthp->range = get_lsb_int16(buffpp);
172  synthp->phase = get_lsb_int16(buffpp);
173}
174
175static void
176get_mbg_tzname(
177	unsigned char **buffpp,
178	char *tznamep
179	)
180{
181  strlcpy(tznamep, (char *)*buffpp, sizeof(TZ_NAME));
182  *buffpp += sizeof(TZ_NAME);
183}
184
185void
186get_mbg_tzdl(
187	unsigned char **buffpp,
188	TZDL *tzdlp
189	)
190{
191  tzdlp->offs = get_lsb_long(buffpp);
192  tzdlp->offs_dl = get_lsb_long(buffpp);
193  get_mbg_tm(buffpp, &tzdlp->tm_on);
194  get_mbg_tm(buffpp, &tzdlp->tm_off);
195  get_mbg_tzname(buffpp, (char *)tzdlp->name[0]);
196  get_mbg_tzname(buffpp, (char *)tzdlp->name[1]);
197}
198
199void
200get_mbg_antinfo(
201	unsigned char **buffpp,
202	ANT_INFO *antinfop
203	)
204{
205  antinfop->status = get_lsb_int16(buffpp);
206  get_mbg_tm(buffpp, &antinfop->tm_disconn);
207  get_mbg_tm(buffpp, &antinfop->tm_reconn);
208  antinfop->delta_t = get_lsb_long(buffpp);
209}
210
211static void
212mbg_time_status_str(
213	char **buffpp,
214	unsigned int status,
215	int size
216	)
217{
218	static struct state
219	{
220		int         flag;       /* bit flag */
221		const char *string;     /* bit name */
222	} states[] =
223		  {
224			  { TM_UTC,    "UTC CORR" },
225			  { TM_LOCAL,  "LOCAL TIME" },
226			  { TM_DL_ANN, "DST WARN" },
227			  { TM_DL_ENB, "DST" },
228			  { TM_LS_ANN, "LEAP WARN" },
229			  { TM_LS_ENB, "LEAP SEC" },
230			  { 0, "" }
231		  };
232
233	if (status)
234	{
235		char *start, *p;
236		struct state *s;
237
238		start = p = *buffpp;
239
240		for (s = states; s->flag; s++)
241		{
242			if (s->flag & status)
243			{
244				if (p != *buffpp)
245				{
246					strlcpy(p, ", ", size - (p - start));
247					p += 2;
248				}
249				strlcpy(p, s->string, size - (p - start));
250				p += strlen(p);
251			}
252		}
253		*buffpp = p;
254	}
255}
256
257void
258mbg_tm_str(
259	char **buffpp,
260	TM_GPS *tmp,
261	int size,
262	int print_status
263	)
264{
265	char *s = *buffpp;
266
267	snprintf(*buffpp, size, "%04d-%02d-%02d %02d:%02d:%02d.%07ld (%c%02d%02d) ",
268		 tmp->year, tmp->month, tmp->mday,
269		 tmp->hour, tmp->min, tmp->sec, (long) tmp->frac,
270		 (tmp->offs_from_utc < 0) ? '-' : '+',
271		 abs((int)tmp->offs_from_utc) / 3600,
272		 (abs((int)tmp->offs_from_utc) / 60) % 60);
273	*buffpp += strlen(*buffpp);
274
275	if (print_status)
276		mbg_time_status_str(buffpp, tmp->status, size - (*buffpp - s));
277}
278
279void
280mbg_tgps_str(
281	char **buffpp,
282	T_GPS *tgpsp,
283	int size
284	)
285{
286	snprintf(*buffpp, size, "week %d + %ld days + %ld.%07ld sec",
287		 tgpsp->wn, (long) tgpsp->sec / SECSPERDAY,
288		 (long) tgpsp->sec % SECSPERDAY, (long) tgpsp->tick);
289	*buffpp += strlen(*buffpp);
290}
291
292void
293get_mbg_cfgh(
294	unsigned char **buffpp,
295	CFGH *cfghp
296	)
297{
298  int i;
299
300  cfghp->csum = (CSUM) get_lsb_short(buffpp);
301  cfghp->valid = get_lsb_int16(buffpp);
302  get_mbg_tgps(buffpp, &cfghp->tot_51);
303  get_mbg_tgps(buffpp, &cfghp->tot_63);
304  get_mbg_tgps(buffpp, &cfghp->t0a);
305
306  for (i = 0; i < N_SVNO_GPS; i++)
307    {
308      get_mbg_cfg(buffpp, &cfghp->cfg[i]);
309    }
310
311  for (i = 0; i < N_SVNO_GPS; i++)
312    {
313      get_mbg_health(buffpp, &cfghp->health[i]);
314    }
315}
316
317void
318get_mbg_utc(
319	unsigned char **buffpp,
320	UTC *utcp
321	)
322{
323  utcp->csum  = (CSUM) get_lsb_short(buffpp);
324  utcp->valid = get_lsb_int16(buffpp);
325
326  get_mbg_tgps(buffpp, &utcp->t0t);
327
328  if (fetch_ieee754(buffpp, IEEE_DOUBLE, &utcp->A0, mbg_double) != IEEE_OK)
329    {
330      L_CLR(&utcp->A0);
331    }
332
333  if (fetch_ieee754(buffpp, IEEE_DOUBLE, &utcp->A1, mbg_double) != IEEE_OK)
334    {
335      L_CLR(&utcp->A1);
336    }
337
338  utcp->WNlsf      = get_lsb_uint16(buffpp);
339  utcp->DNt        = get_lsb_int16(buffpp);
340  utcp->delta_tls  = *(*buffpp)++;
341  utcp->delta_tlsf = *(*buffpp)++;
342}
343
344void
345get_mbg_lla(
346	unsigned char **buffpp,
347	LLA lla
348	)
349{
350  int i;
351
352  for (i = LAT; i <= ALT; i++)
353    {
354      if  (fetch_ieee754(buffpp, IEEE_DOUBLE, &lla[i], mbg_double) != IEEE_OK)
355	{
356	  L_CLR(&lla[i]);
357	}
358      else
359	if (i != ALT)
360	  {			/* convert to degrees (* 180/PI) */
361	    mfp_mul(&lla[i].l_i, &lla[i].l_uf, lla[i].l_i, lla[i].l_uf, rad2deg_i, rad2deg_f);
362	  }
363    }
364}
365
366void
367get_mbg_xyz(
368	unsigned char **buffpp,
369	XYZ xyz
370	)
371{
372  int i;
373
374  for (i = XP; i <= ZP; i++)
375    {
376      if  (fetch_ieee754(buffpp, IEEE_DOUBLE, &xyz[i], mbg_double) != IEEE_OK)
377	{
378	  L_CLR(&xyz[i]);
379	}
380    }
381}
382
383static void
384get_mbg_comparam(
385	unsigned char **buffpp,
386	COM_PARM *comparamp
387	)
388{
389  size_t i;
390
391  comparamp->baud_rate = get_lsb_long(buffpp);
392  for (i = 0; i < sizeof(comparamp->framing); i++)
393    {
394      comparamp->framing[i] = *(*buffpp)++;
395    }
396  comparamp->handshake = get_lsb_int16(buffpp);
397}
398
399void
400get_mbg_portparam(
401	unsigned char **buffpp,
402	PORT_PARM *portparamp
403	)
404{
405  int i;
406
407  for (i = 0; i < DEFAULT_N_COM; i++)
408    {
409      get_mbg_comparam(buffpp, &portparamp->com[i]);
410    }
411  for (i = 0; i < DEFAULT_N_COM; i++)
412    {
413      portparamp->mode[i] = *(*buffpp)++;
414    }
415}
416
417#define FETCH_DOUBLE(src, addr)							\
418	if  (fetch_ieee754(src, IEEE_DOUBLE, addr, mbg_double) != IEEE_OK)	\
419	{									\
420	  L_CLR(addr);								\
421	}
422
423void
424get_mbg_eph(
425	unsigned char ** buffpp,
426	EPH *ephp
427	)
428{
429  ephp->csum   = (CSUM) get_lsb_short(buffpp);
430  ephp->valid  = get_lsb_int16(buffpp);
431
432  ephp->health = (HEALTH) get_lsb_short(buffpp);
433  ephp->IODC   = (IOD) get_lsb_short(buffpp);
434  ephp->IODE2  = (IOD) get_lsb_short(buffpp);
435  ephp->IODE3  = (IOD) get_lsb_short(buffpp);
436
437  get_mbg_tgps(buffpp, &ephp->tt);
438  get_mbg_tgps(buffpp, &ephp->t0c);
439  get_mbg_tgps(buffpp, &ephp->t0e);
440
441  FETCH_DOUBLE(buffpp, &ephp->sqrt_A);
442  FETCH_DOUBLE(buffpp, &ephp->e);
443  FETCH_DOUBLE(buffpp, &ephp->M0);
444  FETCH_DOUBLE(buffpp, &ephp->omega);
445  FETCH_DOUBLE(buffpp, &ephp->OMEGA0);
446  FETCH_DOUBLE(buffpp, &ephp->OMEGADOT);
447  FETCH_DOUBLE(buffpp, &ephp->deltan);
448  FETCH_DOUBLE(buffpp, &ephp->i0);
449  FETCH_DOUBLE(buffpp, &ephp->idot);
450  FETCH_DOUBLE(buffpp, &ephp->crc);
451  FETCH_DOUBLE(buffpp, &ephp->crs);
452  FETCH_DOUBLE(buffpp, &ephp->cuc);
453  FETCH_DOUBLE(buffpp, &ephp->cus);
454  FETCH_DOUBLE(buffpp, &ephp->cic);
455  FETCH_DOUBLE(buffpp, &ephp->cis);
456
457  FETCH_DOUBLE(buffpp, &ephp->af0);
458  FETCH_DOUBLE(buffpp, &ephp->af1);
459  FETCH_DOUBLE(buffpp, &ephp->af2);
460  FETCH_DOUBLE(buffpp, &ephp->tgd);
461
462  ephp->URA = get_lsb_uint16(buffpp);
463
464  ephp->L2code = *(*buffpp)++;
465  ephp->L2flag = *(*buffpp)++;
466}
467
468void
469get_mbg_alm(
470	unsigned char **buffpp,
471	ALM *almp
472	)
473{
474  almp->csum   = (CSUM) get_lsb_short(buffpp);
475  almp->valid  = get_lsb_int16(buffpp);
476
477  almp->health = (HEALTH) get_lsb_short(buffpp);
478  get_mbg_tgps(buffpp, &almp->t0a);
479
480
481  FETCH_DOUBLE(buffpp, &almp->sqrt_A);
482  FETCH_DOUBLE(buffpp, &almp->e);
483
484  FETCH_DOUBLE(buffpp, &almp->M0);
485  FETCH_DOUBLE(buffpp, &almp->omega);
486  FETCH_DOUBLE(buffpp, &almp->OMEGA0);
487  FETCH_DOUBLE(buffpp, &almp->OMEGADOT);
488  FETCH_DOUBLE(buffpp, &almp->deltai);
489  FETCH_DOUBLE(buffpp, &almp->af0);
490  FETCH_DOUBLE(buffpp, &almp->af1);
491}
492
493void
494get_mbg_iono(
495	unsigned char **buffpp,
496	IONO *ionop
497	)
498{
499  ionop->csum   = (CSUM) get_lsb_short(buffpp);
500  ionop->valid  = get_lsb_int16(buffpp);
501
502  FETCH_DOUBLE(buffpp, &ionop->alpha_0);
503  FETCH_DOUBLE(buffpp, &ionop->alpha_1);
504  FETCH_DOUBLE(buffpp, &ionop->alpha_2);
505  FETCH_DOUBLE(buffpp, &ionop->alpha_3);
506
507  FETCH_DOUBLE(buffpp, &ionop->beta_0);
508  FETCH_DOUBLE(buffpp, &ionop->beta_1);
509  FETCH_DOUBLE(buffpp, &ionop->beta_2);
510  FETCH_DOUBLE(buffpp, &ionop->beta_3);
511}
512
513/*
514 * data_mbg.c,v
515 * Revision 4.8  2006/06/22 18:40:01  kardel
516 * clean up signedness (gcc 4)
517 *
518 * Revision 4.7  2005/10/07 22:11:10  kardel
519 * bounded buffer implementation
520 *
521 * Revision 4.6.2.1  2005/09/25 10:23:06  kardel
522 * support bounded buffers
523 *
524 * Revision 4.6  2005/04/16 17:32:10  kardel
525 * update copyright
526 *
527 * Revision 4.5  2004/11/14 15:29:41  kardel
528 * support PPSAPI, upgrade Copyright to Berkeley style
529 *
530 * Revision 4.3  1999/02/21 12:17:42  kardel
531 * 4.91f reconcilation
532 *
533 * Revision 4.2  1998/06/14 21:09:39  kardel
534 * Sun acc cleanup
535 *
536 * Revision 4.1  1998/05/24 08:02:06  kardel
537 * trimmed version log
538 *
539 * Revision 4.0  1998/04/10 19:45:33  kardel
540 * Start 4.0 release version numbering
541 */
542
543