xref: /netbsd-src/external/bsd/ntp/dist/libntp/refidsmear.c (revision cdfa2a7ef92791ba9db70a584a1d904730e6fb46)
1 /*	$NetBSD: refidsmear.c,v 1.2 2020/05/25 20:47:24 christos Exp $	*/
2 
3 #include <config.h>
4 
5 #include <ntp.h>
6 #include <ntp_fp.h>
7 #include <refidsmear.h>
8 
9 /*
10  * we want to test a refid format of:
11  * 254.x.y.x
12  *
13  * where x.y.z are 24 bits containing 2 (signed) integer bits
14  * and 22 fractional bits.
15  *
16  */
17 
18 
19 l_fp
convertRefIDToLFP(uint32_t r)20 convertRefIDToLFP(uint32_t r)
21 {
22 	l_fp temp;
23 
24 	r = ntohl(r);
25 
26 	// printf("%03d %08x: ", (r >> 24) & 0xFF, (r & 0x00FFFFFF) );
27 
28 	temp.l_uf = (r << 10);	/* 22 fractional bits */
29 
30 	temp.l_ui = (r >> 22) & 0x3;
31 	temp.l_ui |= ~(temp.l_ui & 2) + 1;
32 
33 	return temp;
34 }
35 
36 
37 uint32_t
convertLFPToRefID(l_fp num)38 convertLFPToRefID(l_fp num)
39 {
40 	uint32_t temp;
41 
42 	/* round the input with the highest bit to shift out from the
43 	 * fraction, then keep just two bits from the integral part.
44 	 *
45 	 * TODO: check for overflows; should we clamp/saturate or just
46 	 * complain?
47 	 */
48 	L_ADDUF(&num, 0x200);
49 	num.l_ui &= 3;
50 
51 	/* combine integral and fractional part to 24 bits */
52 	temp  = (num.l_ui << 22) | (num.l_uf >> 10);
53 
54 	/* put in the leading 254.0.0.0 */
55 	temp |= UINT32_C(0xFE000000);
56 
57 	// printf("%03d %08x: ", (temp >> 24) & 0xFF, (temp & 0x00FFFFFF) );
58 
59 	return htonl(temp);
60 }
61