1
- "use strict" ;
1
+ import { PacketStruct } from "./PacketStruct" ;
2
+ import { NtpPacket } from "./NtpPacket" ;
2
3
3
- /**
4
- * @typedef {Object } NTPPacket
5
- * @property {int } leapIndicator
6
- * @property {int } version
7
- * @property {int } mode
8
- * @property {int } stratum
9
- * @property {int } poll
10
- * @property {int } precision
11
- * @property {Date } rootDelay
12
- * @property {Date } rootDispersion
13
- * @property {String } referenceId
14
- * @property {Date } referenceTimestamp
15
- * @property {Date } originTimestamp
16
- * @property {Date } receiveTimestamp
17
- * @property {Date } transmitTimestamp
18
- */
19
-
20
- export default class NtpPacketParser {
4
+ export class NtpPacketParser {
21
5
/**
22
6
* Returns the structure of the UDP packet for parsing
23
- * @returns {Object }
24
7
*/
25
- static get packetStruct ( ) {
8
+ private static get packetStruct ( ) {
26
9
return [
27
- { name : "leapIndicator" , bits : 2 } ,
28
- { name : "version" , bits : 3 } ,
29
- { name : "mode" , bits : 3 } ,
30
- { name : "stratum" , bits : 8 } ,
31
- { name : "poll" , bits : 8 } ,
32
- { name : "precision" , bits : 8 } ,
10
+ { name : "leapIndicator" , bits : 2 } as PacketStruct < "leapIndicator" > ,
11
+ { name : "version" , bits : 3 } as PacketStruct < "version" > ,
12
+ { name : "mode" , bits : 3 } as PacketStruct < "mode" > ,
13
+ { name : "stratum" , bits : 8 } as PacketStruct < "stratum" > ,
14
+ { name : "poll" , bits : 8 } as PacketStruct < "poll" > ,
15
+ { name : "precision" , bits : 8 } as PacketStruct < "precision" > ,
33
16
{
34
17
name : "rootDelay" ,
35
18
bits : 32 ,
36
19
converter : NtpPacketParser . _fromNtpTimestamp
37
- } ,
20
+ } as PacketStruct < "rootDelay" > ,
38
21
{
39
22
name : "rootDispersion" ,
40
23
bits : 32 ,
41
24
converter : NtpPacketParser . _fromNtpTimestamp
42
- } ,
25
+ } as PacketStruct < "rootDispersion" > ,
43
26
{
44
27
name : "referenceId" ,
45
28
bits : 32 ,
46
- converter : ( v , s ) => this . _ntpIdentifier ( s . stratum , v )
47
- } ,
29
+ converter : ( value , packet ) => this . _ntpIdentifier ( packet . stratum , value )
30
+ } as PacketStruct < "referenceId" > ,
48
31
{
49
32
name : "referenceTimestamp" ,
50
33
bits : 64 ,
51
34
converter : NtpPacketParser . _fromNtpTimestamp
52
- } ,
35
+ } as PacketStruct < "referenceTimestamp" > ,
53
36
{
54
37
name : "originTimestamp" ,
55
38
bits : 64 ,
56
39
converter : NtpPacketParser . _fromNtpTimestamp
57
- } ,
40
+ } as PacketStruct < "originTimestamp" > ,
58
41
{
59
42
name : "receiveTimestamp" ,
60
43
bits : 64 ,
61
44
converter : NtpPacketParser . _fromNtpTimestamp
62
- } ,
45
+ } as PacketStruct < "receiveTimestamp" > ,
63
46
{
64
47
name : "transmitTimestamp" ,
65
48
bits : 64 ,
66
49
converter : NtpPacketParser . _fromNtpTimestamp
67
- }
50
+ } as PacketStruct < "transmitTimestamp" >
68
51
] ;
69
52
}
70
53
71
54
/**
72
55
* Returns the selected bits in binary notation
73
- * @param msg
74
- * @param {int } start
75
- * @param {int } length
76
- * @returns {string } Bits in binary notation
77
- * @private
78
56
*/
79
- static _getBits ( msg , start , length ) {
57
+ private static _getBits ( msg : Buffer , start : number , length : number ) : string {
80
58
let bits = "" ;
81
59
const pad = "00000000" ;
82
60
@@ -90,12 +68,9 @@ export default class NtpPacketParser {
90
68
91
69
/**
92
70
* Converts a NTP identifier from binary notation to ASCII
93
- * @param {int } stratum
94
- * @param {String } value Bits in binary notation
95
- * @returns {string }
96
- * @private
71
+ * @param {string } value Bits in binary notation
97
72
*/
98
- static _ntpIdentifier ( stratum , value ) {
73
+ private static _ntpIdentifier ( stratum : number , value : string ) : string {
99
74
if ( stratum != 1 ) {
100
75
return parseInt ( value , 2 ) . toString ( ) ;
101
76
}
@@ -115,11 +90,9 @@ export default class NtpPacketParser {
115
90
116
91
/**
117
92
* Converts a NTP timestamp from binary notation to a Date object
118
- * @param {String } value Bits in binary notation
119
- * @returns {Date }
120
- * @private
93
+ * @param {string } value Bits in binary notation
121
94
*/
122
- static _fromNtpTimestamp ( value ) {
95
+ public static _fromNtpTimestamp ( value : string ) : Date {
123
96
if ( value . length % 2 !== 0 ) {
124
97
throw new Error (
125
98
"Invalid timestamp format, expected even number of characters"
@@ -135,25 +108,26 @@ export default class NtpPacketParser {
135
108
}
136
109
137
110
/**
138
- * Parses an UDP packet buffer and returns a NTPPacket struct
139
- * @param {Buffer } udpPacket
140
- * @returns {NTPPacket }
111
+ * Parses an UDP packet buffer and returns a NtpPacket struct
141
112
*/
142
- static parse ( udpPacket ) {
143
- let data = [ ] ;
144
- NtpPacketParser . packetStruct . forEach ( item => {
145
- data [ item . name ] = undefined ;
146
- } ) ;
147
-
113
+ public static parse ( udpPacket : Buffer ) : Partial < NtpPacket > {
114
+ let data : Partial < NtpPacket > = { } ;
148
115
let offset = 0 ;
149
- NtpPacketParser . packetStruct . forEach ( item => {
150
- data [ item . name ] = NtpPacketParser . _getBits ( udpPacket , offset , item . bits ) ;
151
- if ( item . converter ) {
152
- data [ item . name ] = item . converter ( data [ item . name ] , data ) ;
116
+
117
+ NtpPacketParser . packetStruct . forEach ( struct => {
118
+ const baseRepresentation = NtpPacketParser . _getBits (
119
+ udpPacket ,
120
+ offset ,
121
+ struct . bits
122
+ ) ;
123
+ if ( struct . converter ) {
124
+ // @ts -ignore
125
+ data [ struct . name ] = struct . converter ( baseRepresentation , data ) ;
153
126
} else {
154
- data [ item . name ] = parseInt ( data [ item . name ] , 2 ) ;
127
+ // @ts -ignore
128
+ data [ struct . name ] = parseInt ( baseRepresentation , 2 ) ;
155
129
}
156
- offset += item . bits ;
130
+ offset += struct . bits ;
157
131
} ) ;
158
132
159
133
return data ;
0 commit comments