KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > net > ntp > TimeInfo


1 package org.apache.commons.net.ntp;
2 /*
3  * Copyright 2001-2005 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 import java.util.List JavaDoc;
19 import java.util.ArrayList JavaDoc;
20
21 /**
22  * Wrapper class to network time packet messages (NTP, etc) that computes
23  * related timing info and stats.
24  *
25  * @author Jason Mathews, MITRE Corp
26  *
27  * @version $Revision: 165675 $ $Date: 2005-05-02 15:09:55 -0500 (Mon, 02 May 2005) $
28  */

29 public class TimeInfo {
30
31     private NtpV3Packet _message;
32     private List JavaDoc _comments;
33     private Long JavaDoc _delay;
34     private Long JavaDoc _offset;
35
36     /**
37      * time at which time message packet was received by local machine
38      */

39     private long _returnTime;
40
41     /**
42      * flag indicating that the TimeInfo details was processed and delay/offset were computed
43      */

44     private boolean _detailsComputed;
45
46     /**
47      * Create TimeInfo object with raw packet message and destination time received.
48      *
49      * @param message NTP message packet
50      * @param returnTime destination receive time
51      * @throws IllegalArgumentException if message is null
52      */

53     public TimeInfo(NtpV3Packet message, long returnTime) {
54         this(message, returnTime, null, true);
55     }
56
57     /**
58      * Create TimeInfo object with raw packet message and destination time received.
59      *
60      * @param message NTP message packet
61      * @param returnTime destination receive time
62      * @param comments List of errors/warnings identified during processing
63      * @throws IllegalArgumentException if message is null
64      */

65     public TimeInfo(NtpV3Packet message, long returnTime, List JavaDoc comments)
66     {
67             this(message, returnTime, comments, true);
68     }
69
70     /**
71      * Create TimeInfo object with raw packet message and destination time received.
72      * Auto-computes details if computeDetails flag set otherwise this is delayed
73      * until computeDetails() is called. Delayed computation is for fast
74      * intialization when sub-millisecond timing is needed.
75      *
76      * @param msgPacket NTP message packet
77      * @param returnTime destination receive time
78      * @param doComputeDetails flag to pre-compute delay/offset values
79      * @throws IllegalArgumentException if message is null
80      */

81     public TimeInfo(NtpV3Packet msgPacket, long returnTime, boolean doComputeDetails)
82     {
83             this(msgPacket, returnTime, null, doComputeDetails);
84     }
85
86     /**
87      * Create TimeInfo object with raw packet message and destination time received.
88      * Auto-computes details if computeDetails flag set otherwise this is delayed
89      * until computeDetails() is called. Delayed computation is for fast
90      * intialization when sub-millisecond timing is needed.
91      *
92      * @param message NTP message packet
93      * @param returnTime destination receive time
94      * @param comments list of comments used to store errors/warnings with message
95      * @param doComputeDetails flag to pre-compute delay/offset values
96      * @throws IllegalArgumentException if message is null
97      */

98     public TimeInfo(NtpV3Packet message, long returnTime, List JavaDoc comments,
99                    boolean doComputeDetails)
100     {
101         if (message == null)
102             throw new IllegalArgumentException JavaDoc("message cannot be null");
103         this._returnTime = returnTime;
104         this._message = message;
105         this._comments = comments;
106         if (doComputeDetails)
107             computeDetails();
108     }
109
110     /**
111      * Add comment (error/warning) to list of comments associated
112      * with processing of NTP parameters. If comment list not create
113      * then one will be created.
114      *
115      * @param comment
116      */

117     public void addComment(String JavaDoc comment)
118     {
119         if (_comments == null) {
120             _comments = new ArrayList JavaDoc();
121         }
122         _comments.add(comment);
123     }
124
125     /**
126      * Compute and validate details of the NTP message packet. Computed
127      * fields include the offset and delay.
128      */

129     public void computeDetails()
130     {
131         if (_detailsComputed) {
132             return; // details already computed - do nothing
133
}
134         _detailsComputed = true;
135         if (_comments == null) {
136             _comments = new ArrayList JavaDoc();
137         }
138
139         TimeStamp origNtpTime = _message.getOriginateTimeStamp();
140         long origTime = origNtpTime.getTime();
141
142         // Receive Time is time request received by server (t2)
143
TimeStamp rcvNtpTime = _message.getReceiveTimeStamp();
144         long rcvTime = rcvNtpTime.getTime();
145
146         // Transmit time is time reply sent by server (t3)
147
TimeStamp xmitNtpTime = _message.getTransmitTimeStamp();
148         long xmitTime = xmitNtpTime.getTime();
149
150         /*
151          * Round-trip network delay and local clock offset (or time drift) is calculated
152          * according to this standard NTP equation:
153          *
154          * LocalClockOffset = ((ReceiveTimestamp - OriginateTimestamp) +
155          * (TransmitTimestamp - DestinationTimestamp)) / 2
156          *
157          * equations from RFC-1305 (NTPv3)
158          * roundtrip delay = (t4 - t1) - (t3 - t2)
159          * local clock offset = ((t2 - t1) + (t3 - t4)) / 2
160          *
161          * It takes into account network delays and assumes that they are symmetrical.
162          *
163          * Note the typo in SNTP RFCs 1769/2030 which state that the delay
164          * is (T4 - T1) - (T2 - T3) with the "T2" and "T3" switched.
165          */

166         if (origNtpTime.ntpValue() == 0)
167         {
168             // without originate time cannot determine when packet went out
169
// might be via a broadcast NTP packet...
170
if (xmitNtpTime.ntpValue() != 0)
171             {
172                 _offset = new Long JavaDoc(xmitTime - _returnTime);
173                 _comments.add("Error: zero orig time -- cannot compute delay");
174             } else
175                 _comments.add("Error: zero orig time -- cannot compute delay/offset");
176         } else if (rcvNtpTime.ntpValue() == 0 || xmitNtpTime.ntpValue() == 0)
177         {
178             _comments.add("Warning: zero rcvNtpTime or xmitNtpTime");
179             // assert destTime >= origTime since network delay cannot be negative
180
if (origTime > _returnTime)
181                 _comments.add("Error: OrigTime > DestRcvTime");
182             else
183             {
184                 // without receive or xmit time cannot figure out processing time
185
// so delay is simply the network travel time
186
_delay = new Long JavaDoc(_returnTime - origTime);
187             }
188             // TODO: is offset still valid if rcvNtpTime=0 || xmitNtpTime=0 ???
189
// Could always hash origNtpTime (sendTime) but if host doesn't set it
190
// then it's an malformed ntp host anyway and we don't care?
191
// If server is in broadcast mode then we never send out a query in first place...
192
if (rcvNtpTime.ntpValue() != 0)
193             {
194                 // xmitTime is 0 just use rcv time
195
_offset = new Long JavaDoc(rcvTime - origTime);
196             } else if (xmitNtpTime.ntpValue() != 0)
197             {
198                 // rcvTime is 0 just use xmitTime time
199
_offset = new Long JavaDoc(xmitTime - _returnTime);
200             }
201         } else
202         {
203              long delayValue = _returnTime - origTime;
204              // assert xmitTime >= rcvTime: difference typically < 1ms
205
if (xmitTime < rcvTime)
206              {
207                  // server cannot send out a packet before receiving it...
208
_comments.add("Error: xmitTime < rcvTime"); // time-travel not allowed
209
} else
210              {
211                  // subtract processing time from round-trip network delay
212
long delta = xmitTime - rcvTime;
213                  // in normal cases the processing delta is less than
214
// the total roundtrip network travel time.
215
if (delta <= delayValue)
216                  {
217                      delayValue -= delta; // delay = (t4 - t1) - (t3 - t2)
218
} else
219                  {
220                      // if delta - delayValue == 1 ms then it's a round-off error
221
// e.g. delay=3ms, processing=4ms
222
if (delta - delayValue == 1)
223                      {
224                          // delayValue == 0 -> local clock saw no tick change but destination clock did
225
if (delayValue != 0)
226                          {
227                              _comments.add("Info: processing time > total network time by 1 ms -> assume zero delay");
228                              delayValue = 0;
229                          }
230                      } else
231                          _comments.add("Warning: processing time > total network time");
232                  }
233              }
234              _delay = new Long JavaDoc(delayValue);
235             if (origTime > _returnTime) // assert destTime >= origTime
236
_comments.add("Error: OrigTime > DestRcvTime");
237
238             _offset = new Long JavaDoc(((rcvTime - origTime) + (xmitTime - _returnTime)) / 2);
239         }
240     }
241
242     /**
243      * Return list of comments (if any) during processing of NTP packet.
244      *
245      * @return List or null if not yet computed
246      */

247     public List JavaDoc getComments()
248     {
249         return _comments;
250     }
251
252     /**
253      * Get round-trip network delay. If null then could not compute the delay.
254      *
255      * @return Long or null if delay not available.
256      */

257     public Long JavaDoc getDelay()
258     {
259         return _delay;
260     }
261
262     /**
263      * Get clock offset needed to adjust local clock to match remote clock. If null then could not
264      * compute the offset.
265      *
266      * @return Long or null if offset not available.
267      */

268     public Long JavaDoc getOffset()
269     {
270         return _offset;
271     }
272
273     /**
274      * Returns NTP message packet.
275      *
276      * @return NTP message packet.
277      */

278     public NtpV3Packet getMessage()
279     {
280         return _message;
281     }
282
283     /**
284      * Returns time at which time message packet was received by local machine.
285      *
286      * @return packet return time.
287      */

288     public long getReturnTime()
289     {
290         return _returnTime;
291     }
292
293 }
294
Popular Tags