summaryrefslogtreecommitdiff
path: root/third_party/ptpd-1.1.0/src/arith.c
blob: a258a9e89831509eb6c7b61e5a6a23ae67255aae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/**
 * @file   arith.c
 * @date   Tue Jul 20 16:12:51 2010
 * 
 * @brief  Time format conversion routines and additional math functions.
 * 
 * 
 */

#include "ptpd.h"

/* from annex C of the spec */
UInteger32 
crc_algorithm(Octet * buf, Integer16 length)
{
	Integer16 i;
	UInteger8 data;
	UInteger32 polynomial = 0xedb88320, crc = 0xffffffff;

	while (length-- > 0) {
		data = *(UInteger8 *) (buf++);

		for (i = 0; i < 8; i++) {
			if ((crc ^ data) & 1) {
				crc = (crc >> 1);
				crc ^= polynomial;
			} else {
				crc = (crc >> 1);
			}
			data >>= 1;
		}
	}

	return crc ^ 0xffffffff;
}

UInteger32 
sum(Octet * buf, Integer16 length)
{
	UInteger32 sum = 0;

	while (length-- > 0)
		sum += *(UInteger8 *) (buf++);

	return sum;
}

void 
fromInternalTime(TimeInternal * internal, TimeRepresentation * external, Boolean halfEpoch)
{
	external->seconds = labs(internal->seconds) + halfEpoch * INT_MAX;

	if (internal->seconds < 0 || internal->nanoseconds < 0) {
		external->nanoseconds = labs(internal->nanoseconds) | ~INT_MAX;
	} else {
		external->nanoseconds = labs(internal->nanoseconds);
	}

	DBGV("fromInternalTime: %10ds %11dns -> %10us %11dns\n",
	    internal->seconds, internal->nanoseconds,
	    external->seconds, external->nanoseconds);
}

void 
toInternalTime(TimeInternal * internal, TimeRepresentation * external, Boolean * halfEpoch)
{
	*halfEpoch = external->seconds / INT_MAX;

	if (external->nanoseconds & ~INT_MAX) {
		internal->seconds = -(external->seconds % INT_MAX);
		internal->nanoseconds = -(external->nanoseconds & INT_MAX);
	} else {
		internal->seconds = external->seconds % INT_MAX;
		internal->nanoseconds = external->nanoseconds;
	}

	DBGV("toInternalTime: %10ds %11dns <- %10us %11dns\n",
	    internal->seconds, internal->nanoseconds,
	    external->seconds, external->nanoseconds);
}

void 
normalizeTime(TimeInternal * r)
{
	r->seconds += r->nanoseconds / 1000000000;
	r->nanoseconds -= r->nanoseconds / 1000000000 * 1000000000;

	if (r->seconds > 0 && r->nanoseconds < 0) {
		r->seconds -= 1;
		r->nanoseconds += 1000000000;
	} else if (r->seconds < 0 && r->nanoseconds > 0) {
		r->seconds += 1;
		r->nanoseconds -= 1000000000;
	}
}

void 
addTime(TimeInternal * r, TimeInternal * x, TimeInternal * y)
{
	r->seconds = x->seconds + y->seconds;
	r->nanoseconds = x->nanoseconds + y->nanoseconds;

	normalizeTime(r);
}

void 
subTime(TimeInternal * r, TimeInternal * x, TimeInternal * y)
{
	r->seconds = x->seconds - y->seconds;
	r->nanoseconds = x->nanoseconds - y->nanoseconds;

	normalizeTime(r);
}