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