Author: erodriguez Date: Tue Jan 4 21:00:40 2005 New Revision: 124182 URL: http://svn.apache.org/viewcvs?view=rev&rev=124182 Log: Basic NTP service implementation, with inbound decoding only. Added: incubator/directory/ntp/trunk/core/src/java/org/apache/ntp/NtpException.java incubator/directory/ntp/trunk/core/src/java/org/apache/ntp/NtpService.java incubator/directory/ntp/trunk/core/src/java/org/apache/ntp/io/NtpMessageDecoder.java incubator/directory/ntp/trunk/core/src/java/org/apache/ntp/message/NtpTimeStamp.java (contents, props changed) incubator/directory/ntp/trunk/core/src/java/org/apache/ntp/service/NtpServiceImpl.java
Added: incubator/directory/ntp/trunk/core/src/java/org/apache/ntp/NtpException.java Url: http://svn.apache.org/viewcvs/incubator/directory/ntp/trunk/core/src/java/org/apache/ntp/NtpException.java?view=auto&rev=124182 ============================================================================== --- (empty file) +++ incubator/directory/ntp/trunk/core/src/java/org/apache/ntp/NtpException.java Tue Jan 4 21:00:40 2005 @@ -0,0 +1,28 @@ +/* + * Copyright 2005 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.ntp; + + +public class NtpException extends Exception +{ + public NtpException(String name) + { + super(name); + } +} + Added: incubator/directory/ntp/trunk/core/src/java/org/apache/ntp/NtpService.java Url: http://svn.apache.org/viewcvs/incubator/directory/ntp/trunk/core/src/java/org/apache/ntp/NtpService.java?view=auto&rev=124182 ============================================================================== --- (empty file) +++ incubator/directory/ntp/trunk/core/src/java/org/apache/ntp/NtpService.java Tue Jan 4 21:00:40 2005 @@ -0,0 +1,29 @@ +/* + * Copyright 2005 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.ntp; + +import org.apache.ntp.message.NtpMessage; + +/** + * NTP Protocol (RFC 2030) + */ +public interface NtpService +{ + public NtpMessage getReplyFor(NtpMessage request); +} + Added: incubator/directory/ntp/trunk/core/src/java/org/apache/ntp/io/NtpMessageDecoder.java Url: http://svn.apache.org/viewcvs/incubator/directory/ntp/trunk/core/src/java/org/apache/ntp/io/NtpMessageDecoder.java?view=auto&rev=124182 ============================================================================== --- (empty file) +++ incubator/directory/ntp/trunk/core/src/java/org/apache/ntp/io/NtpMessageDecoder.java Tue Jan 4 21:00:40 2005 @@ -0,0 +1,105 @@ +/* + * Copyright 2005 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.ntp.io; + +import java.nio.ByteBuffer; + +import org.apache.ntp.message.LeapIndicatorType; +import org.apache.ntp.message.ModeType; +import org.apache.ntp.message.NtpMessage; +import org.apache.ntp.message.NtpMessageModifier; +import org.apache.ntp.message.NtpTimeStamp; +import org.apache.ntp.message.ReferenceIdentifier; +import org.apache.ntp.message.StratumType; + + +public class NtpMessageDecoder +{ + public NtpMessage decode( ByteBuffer request ) + { + NtpMessageModifier modifier = new NtpMessageModifier(); + + byte header = request.get(); + modifier.setLeapIndicator( parseLeapIndicator( header ) ); + modifier.setVersionNumber( parseVersionNumber( header ) ); + modifier.setMode( parseMode( header ) ); + + modifier.setStratum( StratumType.getTypeByOrdinal( request.get() ) ); + + int pollInterval = (int)Math.round( Math.pow( 2, request.get() ) ); + modifier.setPollInterval( pollInterval ); + + double precision = 1000 * Math.pow( 2, request.get() ); + modifier.setPrecision( precision ); + + + modifier.setRootDelay( parseRootDelay( request ) ); + + modifier.setRootDispersion( parseRootDispersion( request ) ); + + byte[] nextFourBytes = new byte[ 4 ]; + request.get( nextFourBytes ); + modifier.setReferenceIdentifier( parseReferenceIdentifier( nextFourBytes ) ); + + + modifier.setReferenceTimestamp( new NtpTimeStamp( request ) ); + modifier.setOriginateTimestamp( new NtpTimeStamp( request ) ); + + byte[] unneededBytes = new byte[ 8 ]; + request.get( unneededBytes ); + modifier.setReceiveTimestamp( new NtpTimeStamp() ); + + modifier.setTransmitTimestamp( new NtpTimeStamp( request ) ); + + + return modifier.getNtpMessage(); + } + + private LeapIndicatorType parseLeapIndicator( byte header ) + { + return LeapIndicatorType.getTypeByOrdinal( ( header & 0xc0 ) >>> 6 ); + } + + private int parseVersionNumber( byte header ) + { + return ( header & 0x38 ) >>> 3; + } + + private ModeType parseMode( byte header ) + { + return ModeType.getTypeByOrdinal( header & 0x07 ); + } + + private ReferenceIdentifier parseReferenceIdentifier( byte[] bytes ) + { + return ReferenceIdentifier.getTypeByName( new String( bytes ) ); + } + + private double parseRootDelay( ByteBuffer bytes ) + { + int temp = 256 * ( 256 * ( 256 * bytes.get() + bytes.get() ) + bytes.get() ) + bytes.get(); + return 1000 * ( ( (double)temp ) / 0x10000 ); + } + + private double parseRootDispersion( ByteBuffer bytes ) + { + long temp = 256 * ( 256 * ( 256 * bytes.get() + bytes.get() ) + bytes.get() ) + bytes.get(); + return 1000 * ( ( (double)temp ) / 0x10000 ); + } +} + Added: incubator/directory/ntp/trunk/core/src/java/org/apache/ntp/message/NtpTimeStamp.java Url: http://svn.apache.org/viewcvs/incubator/directory/ntp/trunk/core/src/java/org/apache/ntp/message/NtpTimeStamp.java?view=auto&rev=124182 ============================================================================== --- (empty file) +++ incubator/directory/ntp/trunk/core/src/java/org/apache/ntp/message/NtpTimeStamp.java Tue Jan 4 21:00:40 2005 @@ -0,0 +1,121 @@ +/* + * Copyright 2005 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.ntp.message; + +import java.nio.ByteBuffer; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +/** + * NTP timestamps are represented as a 64-bit unsigned fixed-point number, + * in seconds relative to 0h on 1 January 1900. The integer part is in the + * first 32 bits and the fraction part in the last 32 bits. In the fraction + * part, the non-significant low order can be set to 0. + */ +public class NtpTimeStamp +{ + /** + * The number of milliseconds difference between the Java epoch and + * the NTP epoch ( January 1, 1900, 00:00:00 GMT ). + */ + private static final long NTP_EPOCH_DIFFERENCE = -2208988800000L; + + private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" ); + + private long seconds = 0; + private long fraction = 0; + + public NtpTimeStamp() + { + this( new Date() ); + } + + public NtpTimeStamp( Date date ) + { + long msSinceStartOfNtpEpoch = date.getTime() - NTP_EPOCH_DIFFERENCE; + + seconds = msSinceStartOfNtpEpoch / 1000; + fraction = ( ( msSinceStartOfNtpEpoch % 1000 ) * 0x100000000L ) / 1000; + } + + public NtpTimeStamp( ByteBuffer data ) + { + for ( int ii = 0; ii < 4; ii++ ) + { + seconds = 256 * seconds + makePositive( data.get() ); + } + + for ( int ii = 4; ii < 8; ii++ ) + { + fraction = 256 * fraction + makePositive( data.get() ); + } + } + + public void writeTo( ByteBuffer buffer ) + { + byte[] bytes = new byte[ 8 ]; + + long temp = seconds; + for ( int ii = 3; ii >= 0; ii-- ) + { + bytes[ ii ] = (byte)( temp % 256 ); + temp = temp / 256; + } + + temp = fraction; + for ( int ii = 7; ii >= 4; ii-- ) + { + bytes[ ii ] = (byte)( temp % 256 ); + temp = temp / 256; + } + + buffer.put( bytes ); + } + + public String toString() + { + long msSinceStartOfNtpEpoch = seconds * 1000 + ( fraction * 1000 ) / 0x100000000L; + Date date = new Date( msSinceStartOfNtpEpoch + NTP_EPOCH_DIFFERENCE ); + + SimpleDateFormat format = new SimpleDateFormat(); + format.setTimeZone( UTC_TIME_ZONE ); + format.applyPattern( "yyyy-MM-dd HH:mm:ss.SSS z" ); + + return "org.apache.ntp.message.NtpTimeStamp[ date = " + format.format( date ) + " ]"; + } + + public boolean equals( Object o ) + { + if ( this == o ) + return true; + if ( !( o instanceof NtpTimeStamp ) ) + return false; + + NtpTimeStamp that = (NtpTimeStamp) o; + return ( this.seconds == that.seconds ) + && ( this.fraction == that.fraction ); + } + + private int makePositive( byte b ) + { + int byteAsInt = b; + return ( byteAsInt < 0 ) ? 256 + byteAsInt : byteAsInt; + } +} + Added: incubator/directory/ntp/trunk/core/src/java/org/apache/ntp/service/NtpServiceImpl.java Url: http://svn.apache.org/viewcvs/incubator/directory/ntp/trunk/core/src/java/org/apache/ntp/service/NtpServiceImpl.java?view=auto&rev=124182 ============================================================================== --- (empty file) +++ incubator/directory/ntp/trunk/core/src/java/org/apache/ntp/service/NtpServiceImpl.java Tue Jan 4 21:00:40 2005 @@ -0,0 +1,56 @@ +/* + * Copyright 2005 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.ntp.service; + +import org.apache.ntp.NtpService; +import org.apache.ntp.message.LeapIndicatorType; +import org.apache.ntp.message.ModeType; +import org.apache.ntp.message.NtpMessage; +import org.apache.ntp.message.NtpMessageModifier; +import org.apache.ntp.message.NtpTimeStamp; +import org.apache.ntp.message.ReferenceIdentifier; +import org.apache.ntp.message.StratumType; + + +public class NtpServiceImpl implements NtpService +{ + public NtpMessage getReplyFor( NtpMessage request ) + { + NtpMessageModifier modifier = new NtpMessageModifier(); + + modifier.setLeapIndicator( LeapIndicatorType.NO_WARNING ); + modifier.setVersionNumber( 4 ); + modifier.setMode( ModeType.SERVER ); + modifier.setStratum( StratumType.SECONDARY_REFERENCE ); + modifier.setPollInterval( 64 ); + modifier.setPrecision( -20 ); + modifier.setRootDelay( 0 ); + modifier.setRootDispersion( 0 ); + modifier.setReferenceIdentifier( ReferenceIdentifier.LOCL ); + + NtpTimeStamp now = new NtpTimeStamp(); + + modifier.setReferenceTimestamp( now ); + modifier.setOriginateTimestamp( request.getTransmitTimestamp() ); + modifier.setReceiveTimestamp( request.getReceiveTimestamp() ); + modifier.setTransmitTimestamp( now ); + + return modifier.getNtpMessage(); + } +} +
