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