messing with NTP and other stuff

phil [2003-01-31 16:53:40]
messing with NTP and other stuff
Filename
meet-j/server/channels/IPv4Channel.java
meet-j/server/channels/IPv4Channel.java~
meet-j/server/channels/UDPChannel_1.java~
meet-j/server/clocks/LamportClock.java~
meet-j/server/clocks/MEETClock.java
meet-j/server/clocks/MEETClock.java~
meet-j/server/clocks/NTPMessage.java
meet-j/server/clocks/NTPMessage.java~
meet-j/server/clocks/NTPTSRaw32.java~
meet-j/server/clocks/NTPTSRaw64.java~
meet-j/server/clocks/NTPTimeStamp.java~
meet-j/server/clocks/NTPTimeStamp32.java
meet-j/server/clocks/NTPTimeStamp32.java~
meet-j/server/clocks/NTPTimeStamp64.java
meet-j/server/clocks/NTPTimeStamp64.java~
meet-j/server/clocks/NTPTimeStamp64_1.java~
meet-j/server/clocks/NTPTimeStampRaw.java~
meet-j/server/clocks/SNTPClock.java
meet-j/server/clocks/SNTPClock.java~
meet-j/server/clocks/test.java
meet-j/server/clocks/test.java~
meet-j/server/types/IEvent.java
meet-j/server/types/IEvent.java~
diff --git a/meet-j/server/channels/IPv4Channel.java b/meet-j/server/channels/IPv4Channel.java
new file mode 100644
index 0000000..c86c806
--- /dev/null
+++ b/meet-j/server/channels/IPv4Channel.java
@@ -0,0 +1,75 @@
+/*
+ * IPv4Channel.java
+ *
+ * Created on July 22, 2002, 5:03 PM
+ */
+
+package psl.meet.server.channels;
+
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.nio.channels.spi.*;
+import java.net.*;
+import java.util.*;
+
+import org.apache.log4j.Logger;
+
+import psl.meet.server.core.*;
+/**
+ *
+ * @author  phil
+ */
+public class IPv4Channel implements IModule {
+
+    private static final String myClass = IPv4Channel.class.toString();
+    static Logger logger = Logger.getLogger(IPv4Channel.class);
+
+    Selector selector = null;
+
+    /** Creates a new instance of IPv4Channel */
+    public IPv4Channel() {
+        try {
+            selector = SelectorProvider.provider().openSelector();
+        } catch (IOException ioe) {
+            logger.error(myClass + ": couldn't get default selector", ioe);
+        }
+    }
+
+
+
+    /**
+     * returns an integer representing the status of the manager itself
+     * @return success code
+     *
+     */
+    public int getStatus() {
+        return MEET_STATUS_OK;
+    }
+
+    /** identify this module
+     * @return title of this module
+     */
+    public String getName() {
+        return "IPv4Channel";
+    }
+
+    /**
+     * tell a module to become active
+     * @return success code
+     * @throws MEETException Internal error
+     */
+    public int start() throws MEETException {
+        return MEET_SUCCESS;
+    }
+
+    /**
+     * tell a module to halt processing
+     * @return success code
+     * @throws MEETException Internal error
+     */
+    public int stop() throws MEETException {
+        return MEET_SUCCESS;
+    }
+
+}
diff --git a/meet-j/server/channels/IPv4Channel.java~ b/meet-j/server/channels/IPv4Channel.java~
new file mode 100644
index 0000000..54c4c30
--- /dev/null
+++ b/meet-j/server/channels/IPv4Channel.java~
@@ -0,0 +1,82 @@
+/*
+ * UDPChannel.java
+ *
+ * Created on July 22, 2002, 5:03 PM
+ */
+
+package psl.meet.server.channels;
+
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.nio.channels.spi.*;
+import java.net.*;
+import java.util.*;
+
+import org.apache.log4j.Logger;
+
+import psl.meet.server.core.*;
+/**
+ *
+ * @author  phil
+ */
+public class IPv4Channel implements IModule {
+
+    private static final int DEFAULT_PORT = 0xEEEE;
+    private static final String myClass = "UDPChannel";
+    static Logger logger = Logger.getLogger(UDPChannel.class);
+
+    Selector selector = null;
+
+    /** Creates a new instance of UDPChannel */
+    public IPv4Channel() {
+        try {
+            selector = SelectorProvider.provider().openSelector();
+        } catch (IOException ioe) {
+            logger.error(myClass + ": couldn't get default selector", ioe);
+        }
+    }
+
+    public int setListenPort(int port) {
+        if (port == 0) {
+            port = DEFAULT_PORT;
+        }
+
+        return MEET_SUCCESS;
+    }
+
+    /**
+     * returns an integer representing the status of the manager itself
+     * @return success code
+     *
+     */
+    public int getStatus() {
+        return MEET_STATUS_OK;
+    }
+
+    /** identify this module
+     * @return title of this module
+     */
+    public String getName() {
+        return "UDPChannel";
+    }
+
+    /**
+     * tell a module to become active
+     * @return success code
+     * @throws MEETException Internal error
+     */
+    public int start() throws MEETException {
+        return MEET_SUCCESS;
+    }
+
+    /**
+     * tell a module to halt processing
+     * @return success code
+     * @throws MEETException Internal error
+     */
+    public int stop() throws MEETException {
+        return MEET_SUCCESS;
+    }
+
+}
diff --git a/meet-j/server/channels/UDPChannel_1.java~ b/meet-j/server/channels/UDPChannel_1.java~
new file mode 100644
index 0000000..c19d162
--- /dev/null
+++ b/meet-j/server/channels/UDPChannel_1.java~
@@ -0,0 +1,82 @@
+/*
+ * UDPChannel.java
+ *
+ * Created on July 22, 2002, 5:03 PM
+ */
+
+package psl.meet.server.channels;
+
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.nio.channels.spi.*;
+import java.net.*;
+import java.util.*;
+
+import org.apache.log4j.Logger;
+
+import psl.meet.server.core.*;
+/**
+ *
+ * @author  phil
+ */
+public class UDPChannel implements IModule {
+
+    private static final int DEFAULT_PORT = 0xEEEE;
+    private static final String myClass = "UDPChannel";
+    static Logger logger = Logger.getLogger(UDPChannel.class);
+
+    Selector selector = null;
+
+    /** Creates a new instance of UDPChannel */
+    public UDPChannel() {
+        try {
+            selector = SelectorProvider.provider().openSelector();
+        } catch (IOException ioe) {
+            logger.error(myClass + ": couldn't get default selector", ioe);
+        }
+    }
+
+    public int setListenPort(int port) {
+        if (port == 0) {
+            port = DEFAULT_PORT;
+        }
+
+        return MEET_SUCCESS;
+    }
+
+    /**
+     * returns an integer representing the status of the manager itself
+     * @return success code
+     *
+     */
+    public int getStatus() {
+        return MEET_STATUS_OK;
+    }
+
+    /** identify this module
+     * @return title of this module
+     */
+    public String getName() {
+        return "UDPChannel";
+    }
+
+    /**
+     * tell a module to become active
+     * @return success code
+     * @throws MEETException Internal error
+     */
+    public int start() throws MEETException {
+        return MEET_SUCCESS;
+    }
+
+    /**
+     * tell a module to halt processing
+     * @return success code
+     * @throws MEETException Internal error
+     */
+    public int stop() throws MEETException {
+        return MEET_SUCCESS;
+    }
+
+}
diff --git a/meet-j/server/clocks/LamportClock.java~ b/meet-j/server/clocks/LamportClock.java~
new file mode 100644
index 0000000..64a8289
--- /dev/null
+++ b/meet-j/server/clocks/LamportClock.java~
@@ -0,0 +1,147 @@
+/*
+ * LamportClock.java
+ *
+ * Created on October 31, 2002, 1:04 PM
+ */
+
+import java.util.Timer;
+import java.util.TimerTask;
+import java.lang.Math;
+
+/**
+ *
+ * @author  mkuba
+ */
+public class LamportClock implements MEETClock {
+
+    private long clock;
+    private int INTERVAL;
+
+    /**
+     * Creates a new instance of LamportClock
+     */
+    public LamportClock() {
+        clock = 0;
+	INTERVAL = 5;
+
+        Timer t = new Timer();
+
+        // update the Lamport clock by default every 5 ms
+        t.scheduleAtFixedRate(new updateTask(),0,INTERVAL);
+
+    }
+
+    /**
+     * constructor with user-defined interval, in ms
+     */
+    public LamportClock(int i) {
+	clock = 0;
+	INTERVAL = i;
+
+	Timer t = new Timer();
+	t.scheduleAtFixedRate(new updateTask(),0,INTERVAL);
+    }
+
+    /**
+     * return Lamport timestamp
+     * this is from the MEETClock interface
+     */
+    public long getTime() {
+	return getLamport();
+    }
+
+    /**
+     * return clock name
+     * this is from the MEETClock interface
+     */
+    public String getClockName() {
+	return "LamportClock";
+    }
+
+    /**
+     * return Lamport timestamp
+     */
+    public long getLamport() {
+        return clock;
+    }
+
+
+    /**
+     * synchronize the Lamport clock
+     */
+    public void setLamport(long time) {
+        if (time > clock) {
+            clock = time + 1;
+        } else {
+        }
+    }
+
+    /**
+     * for the Timer class
+     */
+    class updateTask extends TimerTask {
+        public void run() {
+            clock++;
+            //DEBUG
+            //System.out.println("Clock = " + clock);
+        }
+    }
+
+
+    /**
+     * test program
+     */
+    public static void main(String args[]) throws Exception {
+
+	// if invalid # of arguments
+	if (args.length < 2) {
+	    System.out.println("Usage: java LamportClock <tick size> <network multiplier>");
+	    System.out.println("\tWhere <tick size> is the tick size of the Lamport Clock");
+	    System.out.println("\tand <network multiplier> is how slow the network is compared to the tick size (i.e. 5 times slower, etc)");
+	    System.exit(0);
+	}
+
+	// set up the interval and network delay
+	int interval = Integer.parseInt(args[0]);
+	float multiplier = Float.parseFloat(args[1]);
+
+	// clock 1
+        LamportClock l1 = new LamportClock(interval);
+	l1.setLamport(2000);
+
+	// clock 2
+        LamportClock l2 = new LamportClock(interval);
+	l2.setLamport(1000);
+
+	// clock 3
+        LamportClock l3 = new LamportClock(interval);
+
+	System.out.println("Larry\tCurly\tMoe");
+	System.out.println(l1.getLamport() + "\t" + l2.getLamport() + "\t" + l3.getLamport());
+
+	// keep updating the clocks, simulating a network
+	while (true) {
+	    Thread.sleep(Math.min(interval*50,1000));
+
+	    long x = l2.getLamport();
+	    Thread.sleep((int)(multiplier*interval));
+	    l1.setLamport(x);
+	    l2.setLamport(x);
+
+	    long y = l1.getLamport();
+	    Thread.sleep((int)(multiplier*interval));
+	    l2.setLamport(y);
+	    l3.setLamport(y);
+
+	    long z = l3.getLamport();
+	    Thread.sleep((int)(multiplier * interval));
+	    l1.setLamport(z);
+	    l2.setLamport(z);
+
+	    // print clock information
+	    System.out.println(l1.getLamport() + "\t" + l2.getLamport() + "\t" + l3.getLamport());
+
+	}
+    }
+
+}
diff --git a/meet-j/server/clocks/MEETClock.java b/meet-j/server/clocks/MEETClock.java
index 06843a0..d3a8d37 100644
--- a/meet-j/server/clocks/MEETClock.java
+++ b/meet-j/server/clocks/MEETClock.java
@@ -1,6 +1,6 @@
 package psl.meet.server.clocks;

-public interface MEETClock {
+public interface MEETClock extends Runnable {

     public String getClockName();

diff --git a/meet-j/server/clocks/MEETClock.java~ b/meet-j/server/clocks/MEETClock.java~
new file mode 100644
index 0000000..06843a0
--- /dev/null
+++ b/meet-j/server/clocks/MEETClock.java~
@@ -0,0 +1,9 @@
+package psl.meet.server.clocks;
+
+public interface MEETClock {
+
+    public String getClockName();
+
+    public long getTime();
+
+}
diff --git a/meet-j/server/clocks/NTPMessage.java b/meet-j/server/clocks/NTPMessage.java
new file mode 100644
index 0000000..215d886
--- /dev/null
+++ b/meet-j/server/clocks/NTPMessage.java
@@ -0,0 +1,527 @@
+/*
+ * NTPTimeStamp.java
+ *
+ * Created on December 6, 2002, 1:41 AM
+ */
+package psl.meet.server.clocks;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.io.IOException;
+import java.nio.*;
+
+/**
+ * Class representing an NTP timestamp as presented in
+ * RFC2030 SNTPv4 for IPv4, IPv6 and OSI.
+ *
+ *                      1                   2                   3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |LI | VN  |Mode |    Stratum    |     Poll      |   Precision   |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                          Root Delay                           |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                       Root Dispersion                         |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     Reference Identifier                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                                                               |
+ * |                   Reference Timestamp (64)                    |
+ * |                                                               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                                                               |
+ * |                   Originate Timestamp (64)                    |
+ * |                                                               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                                                               |
+ * |                    Receive Timestamp (64)                     |
+ * |                                                               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                                                               |
+ * |                    Transmit Timestamp (64)                    |
+ * |                                                               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                 Key Identifier (optional) (32)                |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                                                               |
+ * |                                                               |
+ * |                 Message Digest (optional) (128)               |
+ * |                                                               |
+ * |                                                               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *
+ * @author mkuba, phil
+ *
+ * Not sure which is faster - need to test:
+ * - individual buffer for each item: scatter then parse
+ * - one big buffer: read and parse as I go
+ *
+ * note: many comments quoted from RFC 2030
+ */
+
+public class NTPMessage {
+
+  public final static boolean DEBUG = true;
+  // system offset, seconds between 1970 and 1900
+  // phil: or 2208902400L?
+  private final long OFFSET = 2208988800L;
+
+
+  private boolean initialized = false;
+
+  // with associated byte array, if any
+  // private boolean synchronized = false;
+
+  // basic packet data structure
+
+  /** bits 0-1 unsigned.
+   * RFC2030: Leap Indicator (LI): This is a two-bit code warning of an
+   * impending leap second to be inserted/deleted in the last minute of the
+   * current day, with bit 0 and bit 1, respectively.
+   */
+  private byte _leapIndicator = 0;
+  public static final String []  leapToString = {
+    "no warning",
+    "last minute has 61 seconds",
+    "last minute has 59 seconds",
+    "alarm condition (clock not synchronized)"
+  };
+
+  /** bits 2-4 unsigned.
+   * RFC2030: Version Number (VN): This is a three-bit integer indicating the
+   * NTP/SNTP version number. The version number is 3 for Version 3 (IPv4
+   * only) and 4 for Version 4 (IPv4, IPv6 and OSI). If necessary to
+   * distinguish between IPv4, IPv6 and OSI, the encapsulating context
+   * must be inspected.
+   */
+  private byte _version = 0;
+  public byte getVersion() {return _version;};
+
+  /** bits 5-7  unsigned.
+   * RFC2030: In unicast and anycast modes, the client sets this field to 3
+   * (client) in the request and the server sets it to 4 (server) in the
+   * reply. In multicast mode, the server sets this field to 5
+   * (broadcast).
+   */
+  private byte _mode = 0;
+  public static final String [] modeToString = {
+    "reserved",
+    "symmetric active",
+    "symmetric passive",
+    "client",
+    "server",
+    "broadcast",
+    "reserved for NTP control message",
+    "reserved for private use"
+  };
+
+  /** bits 8-15 unsigned.
+   * RFC2030: Stratum: This is a eight-bit unsigned integer indicating the stratum
+   * level of the local clock, with values defined as follows:
+   *
+   * Stratum  Meaning
+   * ----------------------------------------------
+   * 0        unspecified or unavailable
+   * 1        primary reference (e.g., radio clock)
+   * 2-15     secondary reference (via NTP or SNTP)
+   * 16-255   reserved
+   *
+   */
+  private short _stratum = 0;
+
+  /** bits 16-23, signed.
+   * RFC2030: Poll Interval: This is an eight-bit signed integer indicating the
+   * maximum interval between successive messages, in seconds to the
+   * nearest power of two. The values that can appear in this field
+   * presently range from 4 (16 s) to 14 (16284 s); however, most
+   * applications use only the sub-range 6 (64 s) to 10 (1024 s).
+   */
+  private byte _pollInterval = 0;
+
+  /**
+   * bits 24-31, signed.
+   * RFC2030: Precision: This is an eight-bit signed integer indicating the
+   * precision of the local clock, in seconds to the nearest power of two.
+   * The values that normally appear in this field range from -6 for
+   * mains-frequency clocks to -20 for microsecond clocks found in some
+   * workstations.
+   */
+  private byte _precision = 0;
+
+  /** bytes 4-7.
+   * RFC2030: Root Delay: This is a 32-bit signed fixed-point number indicating the
+   * total roundtrip delay to the primary reference source, in seconds
+   * with fraction point between bits 15 and 16. Note that this variable
+   * can take on both positive and negative values, depending on the
+   * relative time and frequency offsets. The values that normally appear
+   * in this field range from negative values of a few milliseconds to
+   * positive values of several hundred milliseconds.
+   */
+  private NTPTimeStamp32 _rootDelay = null;
+
+  /** bytes 8-11.
+   * RFC2030: Root Dispersion: This is a 32-bit unsigned fixed-point number
+   * indicating the nominal error relative to the primary reference
+   * source, in seconds with fraction point between bits 15 and 16. The
+   * values that normally appear in this field range from 0 to several
+   * hundred milliseconds.
+   */
+  private NTPTimeStamp32 _rootDispersion = null;
+
+  /** bytes 12-15.
+   * RFC2030: Reference Identifier: This is a 32-bit bitstring identifying the
+   * particular reference source. In the case of NTP Version 3 or Version
+   * 4 stratum-0 (unspecified) or stratum-1 (primary) servers, this is a
+   * four-character ASCII string, left justified and zero padded to 32
+   * bits. In NTP Version 3 secondary servers, this is the 32-bit IPv4
+   * address of the reference source. In NTP Version 4 secondary servers,
+   * this is the low order 32 bits of the latest transmit timestamp of the
+   * reference source. NTP primary (stratum 1) servers should set this
+   * field to a code identifying the external reference source according
+   * to the following list. If the external reference is one of those
+   * listed, the associated code should be used. Codes for sources not
+   * listed can be contrived as appropriate.
+   */
+  private long _referenceIdentifier = 0L;
+  private static HashMap _referenceIdentifierToString = new HashMap();
+  // ah yes, the static block
+  static {
+    _referenceIdentifierToString.put(
+    "LOCL", "uncalibrated local clock used as a primary reference for" +
+    "a subnet without external means of synchronization");
+
+    _referenceIdentifierToString.put(
+    "PPS", "atomic clock or other pulse-per-second source" +
+    "individually calibrated to national standards");
+    _referenceIdentifierToString.put(
+    "ACTS", "NIST dialup modem service");
+    _referenceIdentifierToString.put(
+    "USNO", "USNO modem service");
+    _referenceIdentifierToString.put(
+    "PTB", "PTB (Germany) modem service");
+    _referenceIdentifierToString.put(
+    "TDF", "Allouis (France) Radio 164 kHz");
+    _referenceIdentifierToString.put(
+    "DCF", "Mainflingen (Germany) Radio 77.5 kHz");
+    _referenceIdentifierToString.put(
+    "MSF", "Rugby (UK) Radio 60 kHz");
+    _referenceIdentifierToString.put(
+    "WWV", "Ft. Collins (US) Radio 2.5, 5, 10, 15, 20 MHz");
+    _referenceIdentifierToString.put(
+    "WWVB", "Boulder (US) Radio 60 kHz");
+    _referenceIdentifierToString.put(
+    "WWVH", "Kaui Hawaii (US) Radio 2.5, 5, 10, 15 MHz");
+    _referenceIdentifierToString.put(
+    "CHU", "Ottawa (Canada) Radio 3330, 7335, 14670 kHz");
+    _referenceIdentifierToString.put(
+    "LORC", "LORAN-C radionavigation system");
+    _referenceIdentifierToString.put(
+    "OMEG", "OMEGA radionavigation system");
+    _referenceIdentifierToString.put(
+    "GPS", "Global Positioning Service");
+    _referenceIdentifierToString.put(
+    "GOES", "Geostationary Orbit Environment Satellite");
+  }
+
+  /** bytes 16-23.
+   * RFC2030: Reference Timestamp: This is the time at which the local clock was
+   * last set or corrected, in 64-bit timestamp format.
+   */
+  private NTPTimeStamp64 _referenceTS = null;
+
+  /** bytes 24-31.
+   *
+   * RFC2030: Originate Timestamp: This is the time at which the request departed
+   * the client for the server, in 64-bit timestamp format.
+   */
+  private NTPTimeStamp64 _originateTS = null;
+
+  /** bytes 32-39.
+   * RFC2030: Receive Timestamp: This is the time at which the request arrived at
+   * the server, in 64-bit timestamp format.
+   */
+  private NTPTimeStamp64 _receiveTS = null;
+
+  /** bytes 40-47.
+   * RFC2030: Transmit Timestamp: This is the time at which the reply departed the
+   * server for the client, in 64-bit timestamp format.
+   */
+  private NTPTimeStamp64 _transmitTS = null;
+
+  /** bytes 128-147 (4 for key ident, 16 for digest)
+   * RFC2030: Authenticator (optional): When the NTP authentication scheme is
+   * implemented, the Key Identifier and Message Digest fields contain the
+   * message authentication code (MAC) information defined in Appendix C
+   * of RFC-1305.
+   */
+  private byte[] _keyIdent = null;
+  private byte[] _messageDigest = null;
+
+  /**  for reading from byte array.
+   * initialized on first use
+   */
+  private ByteBuffer _bytes = null;
+
+  private NTPMessage() {}
+
+  public NTPMessage(ByteBuffer input) throws IOException {
+    if (input == null) {
+      throw new IOException("NTPMessage(BB): null input");
+    }
+    if (input.remaining() < 48) {
+      throw new IOException("NTPMessage(BB): invalid input length " +
+      input.remaining());
+    }
+
+    if (_bytes != input) {
+      _bytes = input;
+    } else {
+      _bytes.rewind();
+    }
+
+      // parse the bytes to get a long
+      if (_bytes == null) {
+        throw new IOException("NTPTSRaw64 ctor: dis uninitialized");
+      }
+
+      int _header = _bytes.getInt();
+      _precision = (byte)(_header & 0xFF);
+      _pollInterval = (byte)((_header >> 8) & 0xFF);
+       _stratum = (short)((_header >> 16) & 0xFF);
+      _mode = (byte)((_header >> 24) & 0x07);
+      _version = (byte)((_header >> 27) & 0x07);
+      _leapIndicator = (byte)((_header >> 30) & 0x03);
+
+      _rootDelay = new NTPTimeStamp32(_bytes);
+      _rootDispersion = new NTPTimeStamp32(_bytes);
+      _referenceIdentifier = ((long) _bytes.getInt()) & 0xFFFFFFFFL;
+
+      _referenceTS = new NTPTimeStamp64(_bytes);
+      _originateTS = new NTPTimeStamp64(_bytes);
+      _receiveTS = new NTPTimeStamp64(_bytes);
+      _transmitTS = new NTPTimeStamp64(_bytes);
+
+      // ignoring auth stuff for now
+    }
+
+    public long calcDelay(NTPTimeStamp64 destTS) {
+      long T1s = _originateTS._secs;  long T1f = _originateTS._frac;
+      long T2s = _receiveTS._secs;  long T2f = _receiveTS._frac;
+      long T3s = _transmitTS._secs;  long T3f = _transmitTS._frac;
+      long T4s = destTS._secs;  long T4f = destTS._frac;
+      long resultS = ((T4s - T1s) - (T2s - T3s)); // / 2 * 1000
+      long resultF = ((T4f - T1f) - (T2f - T3f));
+      //TODO: the below is wrong
+      long result = (resultS * 1000L) + resultF;
+      if (DEBUG) {
+        System.out.println("calcDelay T1 T2 T3 T4: " + T1 + " " + T2 + " " +
+          T3 + " " + T4 + " -> " + result);
+      }
+      return (long)(result * 1000.0);
+    }
+
+    public long calcOffset(NTPTimeStamp64 destTS) {
+      double T1 = _originateTS.toDelta();
+      double T2 = _receiveTS.toDelta();
+      double T3 = _transmitTS.toDelta();
+      double T4 = destTS.toDelta();
+      double result = ((T2 - T1) + (T3 - T4)) / 2.0;
+      if (DEBUG) {
+        System.out.println("calcOffset T1 T2 T3 T4: " + T1 + " " + T2 + " " +
+          T3 + " " + T4 + " -> " + result);
+      }
+      return (long)(result * 1000.0);
+    }
+
+
+    public String toString() {
+      return
+      "leapIndicator = " + _leapIndicator + "\n" +
+      "version =       " + _version + "\n" +
+      "mode =          " + _mode + "\n" +
+      "stratum =       " + _stratum + "\n" +
+      "pollInterval =  " + _pollInterval + "\n" +
+      "precision =     " + _precision + "\n" +
+
+      "rootDelay =           " + _rootDelay + "\n" +
+      "rootDispersion =      " + _rootDispersion + "\n" +
+      "referenceIdentifier = " + _referenceIdentifier + "\n" +
+
+      "referenceTS = " + _referenceTS.toFull() + "\n" +
+      "originateTS = " + _originateTS.toFull() + "\n" +
+      "receiveTS =   " + _receiveTS.toFull() + "\n" +
+      "transmitTS =  " + _transmitTS.toFull();
+
+    }
+
+    /**
+     * take the seconds, return
+     * 8 bytes in NTP Timestamp format
+     * for use in Tx and Rx of NTP info
+     */
+  /*
+  public byte[] getBytes() {
+
+    BigInteger bar = BigInteger.valueOf(secs);
+    byte[] b1 = bar.toByteArray();
+
+
+    if (b1.length > 4) {
+      for (int i=0; i<4; i++) {
+        b1[i] = b1[i+1];
+      }
+    }
+
+    BitSet bs = doubleToFixedPoint(fracsecs);
+    byte[] b2 = toByteArray(bs);
+
+    byte[] output = new byte[8];
+
+    for (int i=0; i< 4; i++) {
+      output[i] = b1[i];
+      output[i+4] = b2[i];
+    }
+
+    return output;
+
+  }
+   */
+
+    /**
+     * Returns a bitset containing the values in bytes.
+     * The byte-ordering of bytes must be big-endian which means
+     * the most significant bit is in element 0.
+     */
+  /*
+  public static BitSet fromByteArray(byte[] bytes) {
+    BitSet bits = new BitSet(32);
+
+    for (int i=0; i<4; i++) {
+      for (int j=0; j<8; j++) {
+        if ((bytes[4-i-1] & (1 << j)) > 0) {
+          bits.set(8*i + j);
+        }
+      }
+    }
+
+    return bits;
+  }
+   */
+
+    /**
+     * BitSet -> ByteArray
+     */
+  /*
+  private static byte[] toByteArray(BitSet bits) {
+    byte[] bytes = new byte[4];
+
+    for (int i=0; i<4; i++) {
+      for (int j=0; j<8; j++) {
+        if (bits.get(8*i + j)) {
+          bytes[4-(i)-1] |= 1 << j;
+        }
+      }
+    }
+
+    return bytes;
+  }
+   */
+
+    /**
+     * DEBUG method
+     */
+    private static void printByteArray(byte[] b) {
+      for (int i=0; i<b.length; i++) {
+        System.out.print(b[i] + " ");
+        if (i % 8 == 7) System.out.print("\n");
+      }
+    }
+
+
+    /**
+     * bytes to a floating point
+     */
+  /*
+  private static float bytesToFloat(byte[] b) {
+
+    float output = 0;
+
+    BitSet bs = fromByteArray(b);
+
+    for (int i=0; i<32; i++) {
+      if (bs.get(i)) {
+        output += Math.pow(2,i-32);
+      }
+    }
+
+    return output;
+
+  }
+   */
+
+    /**
+     * floating point to fixed point
+     */
+  /*
+  private static BitSet doubleToFixedPoint(double foo) {
+
+    BitSet output = new BitSet(32);
+
+    foo = foo % 1;
+    int idx = 0;
+
+    while (idx < 32) {
+      if (foo >= 0.5) {
+        output.set(31-idx);
+      }
+      idx++;
+      foo = foo * 10;
+      foo = foo % 1;
+    }
+
+    return output;
+
+  }
+   */
+
+    /**
+     * test program
+     */
+    public static void main(String args[]) throws Exception {
+    /*
+    Date nowDate = new Date();
+    System.out.println("Date:");
+    System.out.println(nowDate.getTime());
+
+    System.out.println("Test default constructor");
+    NTPTimeStamp now = new NTPTimeStamp();
+    printByteArray(now.getBytes());
+    System.out.println(now.getLong());
+
+    System.out.println("Test byte[] constructor");
+
+    byte[] b = new byte[8];
+    b[0] = -125;
+    b[1] = -86;
+    b[2] = 56;
+    b[3] = 48;
+    b[4] = -128;
+    b[5] = 0;
+    b[6] = 0;
+    b[7] = 0;
+    NTPTimeStamp byteTest = new NTPTimeStamp(b);
+    printByteArray(byteTest.getBytes());
+    System.out.println(byteTest.getLong());
+
+    System.out.println("Test long constructor");
+
+    long BigOffset = 2208970800000L;
+    NTPTimeStamp longTest = new NTPTimeStamp(BigOffset,-5);
+    printByteArray(longTest.getBytes());
+    System.out.println(longTest.getLong());
+     */
+    }
+
+
+  }
diff --git a/meet-j/server/clocks/NTPMessage.java~ b/meet-j/server/clocks/NTPMessage.java~
new file mode 100644
index 0000000..9c62a55
--- /dev/null
+++ b/meet-j/server/clocks/NTPMessage.java~
@@ -0,0 +1,526 @@
+/*
+ * NTPTimeStamp.java
+ *
+ * Created on December 6, 2002, 1:41 AM
+ */
+package psl.meet.server.clocks;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.io.IOException;
+import java.nio.*;
+
+/**
+ * Class representing an NTP timestamp as presented in
+ * RFC2030 SNTPv4 for IPv4, IPv6 and OSI.
+ *
+ *                      1                   2                   3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |LI | VN  |Mode |    Stratum    |     Poll      |   Precision   |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                          Root Delay                           |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                       Root Dispersion                         |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     Reference Identifier                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                                                               |
+ * |                   Reference Timestamp (64)                    |
+ * |                                                               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                                                               |
+ * |                   Originate Timestamp (64)                    |
+ * |                                                               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                                                               |
+ * |                    Receive Timestamp (64)                     |
+ * |                                                               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                                                               |
+ * |                    Transmit Timestamp (64)                    |
+ * |                                                               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                 Key Identifier (optional) (32)                |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                                                               |
+ * |                                                               |
+ * |                 Message Digest (optional) (128)               |
+ * |                                                               |
+ * |                                                               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *
+ * @author mkuba, phil
+ *
+ * Not sure which is faster - need to test:
+ * - individual buffer for each item: scatter then parse
+ * - one big buffer: read and parse as I go
+ *
+ * note: many comments quoted from RFC 2030
+ */
+
+public class NTPMessage {
+
+  public final static boolean DEBUG = true;
+  // system offset, seconds between 1970 and 1900
+  // phil: or 2208902400L?
+  private final long OFFSET = 2208988800L;
+
+
+  private boolean initialized = false;
+
+  // with associated byte array, if any
+  // private boolean synchronized = false;
+
+  // basic packet data structure
+
+  /** bits 0-1 unsigned.
+   * RFC2030: Leap Indicator (LI): This is a two-bit code warning of an
+   * impending leap second to be inserted/deleted in the last minute of the
+   * current day, with bit 0 and bit 1, respectively.
+   */
+  private byte _leapIndicator = 0;
+  public static final String []  leapToString = {
+    "no warning",
+    "last minute has 61 seconds",
+    "last minute has 59 seconds",
+    "alarm condition (clock not synchronized)"
+  };
+
+  /** bits 2-4 unsigned.
+   * RFC2030: Version Number (VN): This is a three-bit integer indicating the
+   * NTP/SNTP version number. The version number is 3 for Version 3 (IPv4
+   * only) and 4 for Version 4 (IPv4, IPv6 and OSI). If necessary to
+   * distinguish between IPv4, IPv6 and OSI, the encapsulating context
+   * must be inspected.
+   */
+  private byte _version = 0;
+  public byte getVersion() {return _version;};
+
+  /** bits 5-7  unsigned.
+   * RFC2030: In unicast and anycast modes, the client sets this field to 3
+   * (client) in the request and the server sets it to 4 (server) in the
+   * reply. In multicast mode, the server sets this field to 5
+   * (broadcast).
+   */
+  private byte _mode = 0;
+  public static final String [] modeToString = {
+    "reserved",
+    "symmetric active",
+    "symmetric passive",
+    "client",
+    "server",
+    "broadcast",
+    "reserved for NTP control message",
+    "reserved for private use"
+  };
+
+  /** bits 8-15 unsigned.
+   * RFC2030: Stratum: This is a eight-bit unsigned integer indicating the stratum
+   * level of the local clock, with values defined as follows:
+   *
+   * Stratum  Meaning
+   * ----------------------------------------------
+   * 0        unspecified or unavailable
+   * 1        primary reference (e.g., radio clock)
+   * 2-15     secondary reference (via NTP or SNTP)
+   * 16-255   reserved
+   *
+   */
+  private short _stratum = 0;
+
+  /** bits 16-23, signed.
+   * RFC2030: Poll Interval: This is an eight-bit signed integer indicating the
+   * maximum interval between successive messages, in seconds to the
+   * nearest power of two. The values that can appear in this field
+   * presently range from 4 (16 s) to 14 (16284 s); however, most
+   * applications use only the sub-range 6 (64 s) to 10 (1024 s).
+   */
+  private byte _pollInterval = 0;
+
+  /**
+   * bits 24-31, signed.
+   * RFC2030: Precision: This is an eight-bit signed integer indicating the
+   * precision of the local clock, in seconds to the nearest power of two.
+   * The values that normally appear in this field range from -6 for
+   * mains-frequency clocks to -20 for microsecond clocks found in some
+   * workstations.
+   */
+  private byte _precision = 0;
+
+  /** bytes 4-7.
+   * RFC2030: Root Delay: This is a 32-bit signed fixed-point number indicating the
+   * total roundtrip delay to the primary reference source, in seconds
+   * with fraction point between bits 15 and 16. Note that this variable
+   * can take on both positive and negative values, depending on the
+   * relative time and frequency offsets. The values that normally appear
+   * in this field range from negative values of a few milliseconds to
+   * positive values of several hundred milliseconds.
+   */
+  private NTPTimeStamp32 _rootDelay = null;
+
+  /** bytes 8-11.
+   * RFC2030: Root Dispersion: This is a 32-bit unsigned fixed-point number
+   * indicating the nominal error relative to the primary reference
+   * source, in seconds with fraction point between bits 15 and 16. The
+   * values that normally appear in this field range from 0 to several
+   * hundred milliseconds.
+   */
+  private NTPTimeStamp32 _rootDispersion = null;
+
+  /** bytes 12-15.
+   * RFC2030: Reference Identifier: This is a 32-bit bitstring identifying the
+   * particular reference source. In the case of NTP Version 3 or Version
+   * 4 stratum-0 (unspecified) or stratum-1 (primary) servers, this is a
+   * four-character ASCII string, left justified and zero padded to 32
+   * bits. In NTP Version 3 secondary servers, this is the 32-bit IPv4
+   * address of the reference source. In NTP Version 4 secondary servers,
+   * this is the low order 32 bits of the latest transmit timestamp of the
+   * reference source. NTP primary (stratum 1) servers should set this
+   * field to a code identifying the external reference source according
+   * to the following list. If the external reference is one of those
+   * listed, the associated code should be used. Codes for sources not
+   * listed can be contrived as appropriate.
+   */
+  private long _referenceIdentifier = 0L;
+  private static HashMap _referenceIdentifierToString = new HashMap();
+  // ah yes, the static block
+  static {
+    _referenceIdentifierToString.put(
+    "LOCL", "uncalibrated local clock used as a primary reference for" +
+    "a subnet without external means of synchronization");
+
+    _referenceIdentifierToString.put(
+    "PPS", "atomic clock or other pulse-per-second source" +
+    "individually calibrated to national standards");
+    _referenceIdentifierToString.put(
+    "ACTS", "NIST dialup modem service");
+    _referenceIdentifierToString.put(
+    "USNO", "USNO modem service");
+    _referenceIdentifierToString.put(
+    "PTB", "PTB (Germany) modem service");
+    _referenceIdentifierToString.put(
+    "TDF", "Allouis (France) Radio 164 kHz");
+    _referenceIdentifierToString.put(
+    "DCF", "Mainflingen (Germany) Radio 77.5 kHz");
+    _referenceIdentifierToString.put(
+    "MSF", "Rugby (UK) Radio 60 kHz");
+    _referenceIdentifierToString.put(
+    "WWV", "Ft. Collins (US) Radio 2.5, 5, 10, 15, 20 MHz");
+    _referenceIdentifierToString.put(
+    "WWVB", "Boulder (US) Radio 60 kHz");
+    _referenceIdentifierToString.put(
+    "WWVH", "Kaui Hawaii (US) Radio 2.5, 5, 10, 15 MHz");
+    _referenceIdentifierToString.put(
+    "CHU", "Ottawa (Canada) Radio 3330, 7335, 14670 kHz");
+    _referenceIdentifierToString.put(
+    "LORC", "LORAN-C radionavigation system");
+    _referenceIdentifierToString.put(
+    "OMEG", "OMEGA radionavigation system");
+    _referenceIdentifierToString.put(
+    "GPS", "Global Positioning Service");
+    _referenceIdentifierToString.put(
+    "GOES", "Geostationary Orbit Environment Satellite");
+  }
+
+  /** bytes 16-23.
+   * RFC2030: Reference Timestamp: This is the time at which the local clock was
+   * last set or corrected, in 64-bit timestamp format.
+   */
+  private NTPTimeStamp64 _referenceTS = null;
+
+  /** bytes 24-31.
+   *
+   * RFC2030: Originate Timestamp: This is the time at which the request departed
+   * the client for the server, in 64-bit timestamp format.
+   */
+  private NTPTimeStamp64 _originateTS = null;
+
+  /** bytes 32-39.
+   * RFC2030: Receive Timestamp: This is the time at which the request arrived at
+   * the server, in 64-bit timestamp format.
+   */
+  private NTPTimeStamp64 _receiveTS = null;
+
+  /** bytes 40-47.
+   * RFC2030: Transmit Timestamp: This is the time at which the reply departed the
+   * server for the client, in 64-bit timestamp format.
+   */
+  private NTPTimeStamp64 _transmitTS = null;
+
+  /** bytes 128-147 (4 for key ident, 16 for digest)
+   * RFC2030: Authenticator (optional): When the NTP authentication scheme is
+   * implemented, the Key Identifier and Message Digest fields contain the
+   * message authentication code (MAC) information defined in Appendix C
+   * of RFC-1305.
+   */
+  private byte[] _keyIdent = null;
+  private byte[] _messageDigest = null;
+
+  /**  for reading from byte array.
+   * initialized on first use
+   */
+  private ByteBuffer _bytes = null;
+
+  private NTPMessage() {}
+
+  public NTPMessage(ByteBuffer input) throws IOException {
+    if (input == null) {
+      throw new IOException("NTPMessage(BB): null input");
+    }
+    if (input.remaining() < 48) {
+      throw new IOException("NTPMessage(BB): invalid input length " +
+      input.remaining());
+    }
+
+    if (_bytes != input) {
+      _bytes = input;
+    } else {
+      _bytes.rewind();
+    }
+
+      // parse the bytes to get a long
+      if (_bytes == null) {
+        throw new IOException("NTPTSRaw64 ctor: dis uninitialized");
+      }
+
+      int _header = _bytes.getInt();
+      _precision = (byte)(_header & 0xFF);
+      _pollInterval = (byte)((_header >> 8) & 0xFF);
+       _stratum = (short)((_header >> 16) & 0xFF);
+      _mode = (byte)((_header >> 24) & 0x07);
+      _version = (byte)((_header >> 27) & 0x07);
+      _leapIndicator = (byte)((_header >> 30) & 0x03);
+
+      _rootDelay = new NTPTimeStamp32(_bytes);
+      _rootDispersion = new NTPTimeStamp32(_bytes);
+      _referenceIdentifier = ((long) _bytes.getInt()) & 0xFFFFFFFFL;
+
+      _referenceTS = new NTPTimeStamp64(_bytes);
+      _originateTS = new NTPTimeStamp64(_bytes);
+      _receiveTS = new NTPTimeStamp64(_bytes);
+      _transmitTS = new NTPTimeStamp64(_bytes);
+
+      // ignoring auth stuff for now
+    }
+
+    public long calcDelay(NTPTimeStamp64 destTS) {
+      long T1s = _originateTS._secs;  long T1f = _originateTS._frac;
+      long T2s = _receiveTS._secs;  long T2f = _receiveTS._frac;
+      long T3s = _transmitTS._secs;  long T3f = _transmitTS._frac;
+      long T4s = destTS._secs;  long T4f = destTS._frac;
+      long resultS = ((T4s - T1s) - (T2s - T3s)); // / 2 * 1000
+      long resultF = ((T4f - T1f) - (T2f - T3f));
+      long result = (resultS * 1000L) +
+      if (DEBUG) {
+        System.out.println("calcDelay T1 T2 T3 T4: " + T1 + " " + T2 + " " +
+          T3 + " " + T4 + " -> " + result);
+      }
+      return (long)(result * 1000.0);
+    }
+
+    public long calcOffset(NTPTimeStamp64 destTS) {
+      double T1 = _originateTS.toDelta();
+      double T2 = _receiveTS.toDelta();
+      double T3 = _transmitTS.toDelta();
+      double T4 = destTS.toDelta();
+      double result = ((T2 - T1) + (T3 - T4)) / 2.0;
+      if (DEBUG) {
+        System.out.println("calcOffset T1 T2 T3 T4: " + T1 + " " + T2 + " " +
+          T3 + " " + T4 + " -> " + result);
+      }
+      return (long)(result * 1000.0);
+    }
+
+
+    public String toString() {
+      return
+      "leapIndicator = " + _leapIndicator + "\n" +
+      "version =       " + _version + "\n" +
+      "mode =          " + _mode + "\n" +
+      "stratum =       " + _stratum + "\n" +
+      "pollInterval =  " + _pollInterval + "\n" +
+      "precision =     " + _precision + "\n" +
+
+      "rootDelay =           " + _rootDelay + "\n" +
+      "rootDispersion =      " + _rootDispersion + "\n" +
+      "referenceIdentifier = " + _referenceIdentifier + "\n" +
+
+      "referenceTS = " + _referenceTS.toFull() + "\n" +
+      "originateTS = " + _originateTS.toFull() + "\n" +
+      "receiveTS =   " + _receiveTS.toFull() + "\n" +
+      "transmitTS =  " + _transmitTS.toFull();
+
+    }
+
+    /**
+     * take the seconds, return
+     * 8 bytes in NTP Timestamp format
+     * for use in Tx and Rx of NTP info
+     */
+  /*
+  public byte[] getBytes() {
+
+    BigInteger bar = BigInteger.valueOf(secs);
+    byte[] b1 = bar.toByteArray();
+
+
+    if (b1.length > 4) {
+      for (int i=0; i<4; i++) {
+        b1[i] = b1[i+1];
+      }
+    }
+
+    BitSet bs = doubleToFixedPoint(fracsecs);
+    byte[] b2 = toByteArray(bs);
+
+    byte[] output = new byte[8];
+
+    for (int i=0; i< 4; i++) {
+      output[i] = b1[i];
+      output[i+4] = b2[i];
+    }
+
+    return output;
+
+  }
+   */
+
+    /**
+     * Returns a bitset containing the values in bytes.
+     * The byte-ordering of bytes must be big-endian which means
+     * the most significant bit is in element 0.
+     */
+  /*
+  public static BitSet fromByteArray(byte[] bytes) {
+    BitSet bits = new BitSet(32);
+
+    for (int i=0; i<4; i++) {
+      for (int j=0; j<8; j++) {
+        if ((bytes[4-i-1] & (1 << j)) > 0) {
+          bits.set(8*i + j);
+        }
+      }
+    }
+
+    return bits;
+  }
+   */
+
+    /**
+     * BitSet -> ByteArray
+     */
+  /*
+  private static byte[] toByteArray(BitSet bits) {
+    byte[] bytes = new byte[4];
+
+    for (int i=0; i<4; i++) {
+      for (int j=0; j<8; j++) {
+        if (bits.get(8*i + j)) {
+          bytes[4-(i)-1] |= 1 << j;
+        }
+      }
+    }
+
+    return bytes;
+  }
+   */
+
+    /**
+     * DEBUG method
+     */
+    private static void printByteArray(byte[] b) {
+      for (int i=0; i<b.length; i++) {
+        System.out.print(b[i] + " ");
+        if (i % 8 == 7) System.out.print("\n");
+      }
+    }
+
+
+    /**
+     * bytes to a floating point
+     */
+  /*
+  private static float bytesToFloat(byte[] b) {
+
+    float output = 0;
+
+    BitSet bs = fromByteArray(b);
+
+    for (int i=0; i<32; i++) {
+      if (bs.get(i)) {
+        output += Math.pow(2,i-32);
+      }
+    }
+
+    return output;
+
+  }
+   */
+
+    /**
+     * floating point to fixed point
+     */
+  /*
+  private static BitSet doubleToFixedPoint(double foo) {
+
+    BitSet output = new BitSet(32);
+
+    foo = foo % 1;
+    int idx = 0;
+
+    while (idx < 32) {
+      if (foo >= 0.5) {
+        output.set(31-idx);
+      }
+      idx++;
+      foo = foo * 10;
+      foo = foo % 1;
+    }
+
+    return output;
+
+  }
+   */
+
+    /**
+     * test program
+     */
+    public static void main(String args[]) throws Exception {
+    /*
+    Date nowDate = new Date();
+    System.out.println("Date:");
+    System.out.println(nowDate.getTime());
+
+    System.out.println("Test default constructor");
+    NTPTimeStamp now = new NTPTimeStamp();
+    printByteArray(now.getBytes());
+    System.out.println(now.getLong());
+
+    System.out.println("Test byte[] constructor");
+
+    byte[] b = new byte[8];
+    b[0] = -125;
+    b[1] = -86;
+    b[2] = 56;
+    b[3] = 48;
+    b[4] = -128;
+    b[5] = 0;
+    b[6] = 0;
+    b[7] = 0;
+    NTPTimeStamp byteTest = new NTPTimeStamp(b);
+    printByteArray(byteTest.getBytes());
+    System.out.println(byteTest.getLong());
+
+    System.out.println("Test long constructor");
+
+    long BigOffset = 2208970800000L;
+    NTPTimeStamp longTest = new NTPTimeStamp(BigOffset,-5);
+    printByteArray(longTest.getBytes());
+    System.out.println(longTest.getLong());
+     */
+    }
+
+
+  }
diff --git a/meet-j/server/clocks/NTPTSRaw32.java~ b/meet-j/server/clocks/NTPTSRaw32.java~
new file mode 100644
index 0000000..045eaeb
--- /dev/null
+++ b/meet-j/server/clocks/NTPTSRaw32.java~
@@ -0,0 +1,16 @@
+/*
+ * NTPTimeStamp.java
+ *
+ * Created on December 6, 2002, 1:41 AM
+ */
+package psl.meet.server.clocks;
+
+import java.util.Date;
+import java.lang.Math;
+
+/**
+ *
+ * @author phil
+ */
+
+public class NTPTimeStamp32 {}
diff --git a/meet-j/server/clocks/NTPTSRaw64.java~ b/meet-j/server/clocks/NTPTSRaw64.java~
new file mode 100644
index 0000000..8dd300a
--- /dev/null
+++ b/meet-j/server/clocks/NTPTSRaw64.java~
@@ -0,0 +1,73 @@
+/*
+ * NTPTimeStamp64.java
+ *
+ * Created on December 24, 2002, 5:37 AM
+ */
+
+package psl.meet.server.clocks;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+
+/**
+ *
+ * @author  phil
+ */
+public class NTPTSRaw64 {
+
+    /**  for reading from byte array.
+   initialized on first use
+   */
+  private DataInputStream _dis = null;
+
+  /**  for writing to byte array.
+   initialized on first use
+   */
+  private DataOutputStream _dos = null;
+
+  /**  holds byte array.
+   initialized on first use
+   */
+  private byte [] _bytearray;
+
+
+    /**
+   * create an NTPTimeStamp given 8 bytes in the NTP Timestamp format
+   */
+  public NTPTSRaw64(byte[] b) {
+
+    // parse the bytes to get a long
+    if (_dis == null) {
+      _dis = new DataInputStream(new ByteArrayInputStream(b));
+    }
+
+    secs = ((long) _dis.readInt()) & 0xFFFFFFFFL;
+
+
+        /* Phil says: can't be right:
+        byte[] d = new byte[4];
+
+        for (int i=0; i<4; i++) {
+            d[i] = b[i+4];
+        }
+
+        // parse last four bytes
+        fracsecs = bytesToFloat(d);
+         */
+    c[1] = b[4];
+    c[2] = b[5];
+    c[3] = b[6];
+    c[4] = b[7];
+    bigint = new BigInteger(c);
+
+    final long tmp = 1L << 32;
+    final double intscale = (double) tmp;
+
+    fracsecs = (float) (bigint.doubleValue() / intscale);
+
+    System.out.println("got " + secs + " + " + fracsecs);
+
+  }
+
+}
diff --git a/meet-j/server/clocks/NTPTimeStamp.java~ b/meet-j/server/clocks/NTPTimeStamp.java~
new file mode 100644
index 0000000..2d9fa99
--- /dev/null
+++ b/meet-j/server/clocks/NTPTimeStamp.java~
@@ -0,0 +1,565 @@
+/*
+ * NTPTimeStamp.java
+ *
+ * Created on December 6, 2002, 1:41 AM
+ */
+package psl.meet.server.clocks;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.util.BitSet;
+import java.util.Date;
+import java.lang.Math;
+import java.util.HashMap;
+
+
+/**
+ * Class representing an NTP timestamp as presented in
+ * RFC2030 SNTPv4 for IPv4, IPv6 and OSI.
+ *
+ *                      1                   2                   3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |LI | VN  |Mode |    Stratum    |     Poll      |   Precision   |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                          Root Delay                           |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                       Root Dispersion                         |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                     Reference Identifier                      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                                                               |
+ * |                   Reference Timestamp (64)                    |
+ * |                                                               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                                                               |
+ * |                   Originate Timestamp (64)                    |
+ * |                                                               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                                                               |
+ * |                    Receive Timestamp (64)                     |
+ * |                                                               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                                                               |
+ * |                    Transmit Timestamp (64)                    |
+ * |                                                               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                 Key Identifier (optional) (32)                |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                                                               |
+ * |                                                               |
+ * |                 Message Digest (optional) (128)               |
+ * |                                                               |
+ * |                                                               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *
+ * @author mkuba, phil
+ * note: many comments quoted from RFC 2030
+ */
+
+public class NTPTimeStamp {
+
+  // system offset, seconds between 1970 and 1900
+  // phil: or 2208902400L?
+  private final long OFFSET = 2208970800L;
+
+  private boolean initialized = false;
+
+  // with associated byte array, if any
+  // private boolean synchronized = false;
+
+  // basic packet data structure
+
+  /** bits 0-1 unsigned.
+   * RFC2030: Leap Indicator (LI): This is a two-bit code warning of an
+   * impending leap second to be inserted/deleted in the last minute of the
+   * current day, with bit 0 and bit 1, respectively.
+   */
+  private byte _leapIndicator = 0;
+  public static final String []  leapToString = {
+    "no warning",
+    "last minute has 61 seconds",
+    "last minute has 59 seconds",
+    "alarm condition (clock not synchronized)"
+  };
+
+  /** bits 2-4 unsigned.
+   * RFC2030: Version Number (VN): This is a three-bit integer indicating the
+   * NTP/SNTP version number. The version number is 3 for Version 3 (IPv4
+   * only) and 4 for Version 4 (IPv4, IPv6 and OSI). If necessary to
+   * distinguish between IPv4, IPv6 and OSI, the encapsulating context
+   * must be inspected.
+   */
+  private byte _version = 0;
+
+  /** bits 5-7  unsigned.
+   * RFC2030: In unicast and anycast modes, the client sets this field to 3
+   * (client) in the request and the server sets it to 4 (server) in the
+   * reply. In multicast mode, the server sets this field to 5
+   * (broadcast).
+   */
+  private byte _mode = 0;
+  public static final String [] modeToString = {
+    "reserved",
+    "symmetric active",
+    "symmetric passive",
+    "client",
+    "server",
+    "broadcast",
+    "reserved for NTP control message",
+    "reserved for private use"
+  };
+
+  /** bits 8-15 unsigned.
+   * RFC2030: Stratum: This is a eight-bit unsigned integer indicating the stratum
+   * level of the local clock, with values defined as follows:
+   *
+   * Stratum  Meaning
+   * ----------------------------------------------
+   * 0        unspecified or unavailable
+   * 1        primary reference (e.g., radio clock)
+   * 2-15     secondary reference (via NTP or SNTP)
+   * 16-255   reserved
+   *
+   */
+  private short _stratum = 0;
+
+  /** bits 16-23, signed.
+   * RFC2030: Poll Interval: This is an eight-bit signed integer indicating the
+   * maximum interval between successive messages, in seconds to the
+   * nearest power of two. The values that can appear in this field
+   * presently range from 4 (16 s) to 14 (16284 s); however, most
+   * applications use only the sub-range 6 (64 s) to 10 (1024 s).
+   */
+  private byte _pollInterval = 0;
+
+  /**
+   * bits 24-31, signed.
+   * RFC2030: Precision: This is an eight-bit signed integer indicating the
+   * precision of the local clock, in seconds to the nearest power of two.
+   * The values that normally appear in this field range from -6 for
+   * mains-frequency clocks to -20 for microsecond clocks found in some
+   * workstations.
+   */
+  private byte _precision = 0;
+
+  /** bytes 4-7.
+   * RFC2030: Root Delay: This is a 32-bit signed fixed-point number indicating the
+   * total roundtrip delay to the primary reference source, in seconds
+   * with fraction point between bits 15 and 16. Note that this variable
+   * can take on both positive and negative values, depending on the
+   * relative time and frequency offsets. The values that normally appear
+   * in this field range from negative values of a few milliseconds to
+   * positive values of several hundred milliseconds.
+   */
+  private NTPTSRaw32 _rootDelay = null;
+
+  /** bytes 8-11.
+   * RFC2030: Root Dispersion: This is a 32-bit unsigned fixed-point number
+   * indicating the nominal error relative to the primary reference
+   * source, in seconds with fraction point between bits 15 and 16. The
+   * values that normally appear in this field range from 0 to several
+   * hundred milliseconds.
+   */
+  private NTPTSRaw32 _rootDispersion = null;
+
+  /** bytes 12-15.
+   * RFC2030: Reference Identifier: This is a 32-bit bitstring identifying the
+   * particular reference source. In the case of NTP Version 3 or Version
+   * 4 stratum-0 (unspecified) or stratum-1 (primary) servers, this is a
+   * four-character ASCII string, left justified and zero padded to 32
+   * bits. In NTP Version 3 secondary servers, this is the 32-bit IPv4
+   * address of the reference source. In NTP Version 4 secondary servers,
+   * this is the low order 32 bits of the latest transmit timestamp of the
+   * reference source. NTP primary (stratum 1) servers should set this
+   * field to a code identifying the external reference source according
+   * to the following list. If the external reference is one of those
+   * listed, the associated code should be used. Codes for sources not
+   * listed can be contrived as appropriate.
+   */
+  private long _referenceIdentifier = 0L;
+  private static HashMap _referenceIdentifierToString = new HashMap();
+  // ah yes, the static block
+  static {
+    _referenceIdentifierToString.put(
+    "LOCL", "uncalibrated local clock used as a primary reference for" +
+    "a subnet without external means of synchronization");
+
+    _referenceIdentifierToString.put(
+    "PPS", "atomic clock or other pulse-per-second source" +
+    "individually calibrated to national standards");
+    _referenceIdentifierToString.put(
+    "ACTS", "NIST dialup modem service");
+    _referenceIdentifierToString.put(
+    "USNO", "USNO modem service");
+    _referenceIdentifierToString.put(
+    "PTB", "PTB (Germany) modem service");
+    _referenceIdentifierToString.put(
+    "TDF", "Allouis (France) Radio 164 kHz");
+    _referenceIdentifierToString.put(
+    "DCF", "Mainflingen (Germany) Radio 77.5 kHz");
+    _referenceIdentifierToString.put(
+    "MSF", "Rugby (UK) Radio 60 kHz");
+    _referenceIdentifierToString.put(
+    "WWV", "Ft. Collins (US) Radio 2.5, 5, 10, 15, 20 MHz");
+    _referenceIdentifierToString.put(
+    "WWVB", "Boulder (US) Radio 60 kHz");
+    _referenceIdentifierToString.put(
+    "WWVH", "Kaui Hawaii (US) Radio 2.5, 5, 10, 15 MHz");
+    _referenceIdentifierToString.put(
+    "CHU", "Ottawa (Canada) Radio 3330, 7335, 14670 kHz");
+    _referenceIdentifierToString.put(
+    "LORC", "LORAN-C radionavigation system");
+    _referenceIdentifierToString.put(
+    "OMEG", "OMEGA radionavigation system");
+    _referenceIdentifierToString.put(
+    "GPS", "Global Positioning Service");
+    _referenceIdentifierToString.put(
+    "GOES", "Geostationary Orbit Environment Satellite");
+  }
+
+  /** bytes 16-31.
+   * RFC2030: Reference Timestamp: This is the time at which the local clock was
+   * last set or corrected, in 64-bit timestamp format.
+   */
+  private NTPTSRaw64 _referenceTS = null;
+
+  /** bytes 32-63.
+   *
+   * RFC2030: Originate Timestamp: This is the time at which the request departed
+   * the client for the server, in 64-bit timestamp format.
+   */
+  private NTPTSRaw64 _originateTS = null;
+
+  /** bytes 64-95.
+   * RFC2030: Receive Timestamp: This is the time at which the request arrived at
+   * the server, in 64-bit timestamp format.
+   */
+  private NTPTSRaw64 _receiveTS = null;
+
+  /** bytes 96-127.
+   * RFC2030: Transmit Timestamp: This is the time at which the reply departed the
+   * server for the client, in 64-bit timestamp format.
+   */
+  private NTPTSRaw64 _transmitTS = null;
+
+  /** bytes 128-147 (4 for key ident, 16 for digest)
+   * RFC2030: Authenticator (optional): When the NTP authentication scheme is
+   * implemented, the Key Identifier and Message Digest fields contain the
+   * message authentication code (MAC) information defined in Appendix C
+   * of RFC-1305.
+   */
+  private byte[] _keyIdent = null;
+  private byte[] _messageDigest = null;
+
+  // seconds since Jan 1 1900 00:00:00 UT
+  private long secs;
+
+  // fraction of a second
+  private double fracsecs;
+
+  /**  for reading from byte array.
+   initialized on first use
+   */
+  private DataInputStream _dis = null;
+
+  /**  for writing to byte array.
+   initialized on first use
+   */
+  private DataOutputStream _dos = null;
+
+  /**  holds byte array.
+   initialized on first use
+   */
+  private byte [] _bytearray;
+
+  /**
+   * create a new NTPTimeStamp
+   */
+  public NTPTimeStamp() {
+    Date now = new Date();
+    secs = (long)(now.getTime() / 1000) + OFFSET;
+
+    // parse into fracsecs
+    float foo = (float)(now.getTime() % 1000);
+    fracsecs = foo / 1000.0f;
+  }
+
+
+  /**
+   * create a new NTPTimeStamp, where
+   * system clock is set to a non-UT timezone
+   */
+  public NTPTimeStamp(int tz) {
+    Date now = new Date();
+    secs = (long)(now.getTime() / 1000) + OFFSET;
+    secs -= tz*3600;
+
+    // parse into fracsecs
+    float foo = (float)(now.getTime() % 1000);
+    fracsecs = foo / 1000.0f;
+
+  }
+
+
+  /**
+   * create an NTPTimeStamp for a given timestamp and timezone
+   * time == milliseconds since 1970
+   */
+  public NTPTimeStamp(long time, int tz) {
+    secs = (long)(time / 1000) + OFFSET - (tz*3600);
+    float foo = (float)(time % 1000);
+    fracsecs = foo / 1000.0f;
+  }
+
+  /**
+   * create an NTPTimeStamp for a given Date object and timezone
+   */
+  public NTPTimeStamp(Date now, int tz) {
+    long time = now.getTime();
+    secs = (long)(time / 1000) + OFFSET - (tz*3600);
+
+    float foo = (float)(time % 1000);
+    fracsecs = foo / 1000.0f;
+  }
+
+
+  /**
+   * create an NTPTimeStamp given 8 bytes in the NTP Timestamp format
+   */
+  public NTPTimeStamp(byte[] b) {
+
+    // parse the bytes to get a long
+    if (_dis == null) {
+      _dis = new DataInputStream(new ByteArrayInputStream(b));
+    }
+
+    secs = (long) dis.readInt();
+    byte[] c = new byte[5];
+    c[0] = 0;
+    c[1] = b[0];
+    c[2] = b[1];
+    c[3] = b[2];
+    c[4] = b[3];
+
+    BigInteger bigint = new BigInteger(c);
+    secs = bigint.longValue();
+
+        /* Phil says: can't be right:
+        byte[] d = new byte[4];
+
+        for (int i=0; i<4; i++) {
+            d[i] = b[i+4];
+        }
+
+        // parse last four bytes
+        fracsecs = bytesToFloat(d);
+         */
+    c[1] = b[4];
+    c[2] = b[5];
+    c[3] = b[6];
+    c[4] = b[7];
+    bigint = new BigInteger(c);
+
+    final long tmp = 1L << 32;
+    final double intscale = (double) tmp;
+
+    fracsecs = (float) (bigint.doubleValue() / intscale);
+
+    System.out.println("got " + secs + " + " + fracsecs);
+
+  }
+
+  /**
+   * return number of seconds since 1900
+   */
+  public long getSecs() {
+    return secs;
+  }
+
+
+  /**
+   * return fraction of second
+   */
+  public double getFracSecs() {
+    return fracsecs;
+  }
+
+
+  /**
+   * return milliseconds since 1900
+   */
+  public long getLong() {
+    long foo = (long)(1000.0 * fracsecs);
+
+    //System.out.println("secs = " + secs);
+    //System.out.println("fracsecs = " + fracsecs);
+
+    return (1000*secs + foo);
+  }
+
+  /**
+   * take the seconds, return
+   * 8 bytes in NTP Timestamp format
+   * for use in Tx and Rx of NTP info
+   */
+  public byte[] getBytes() {
+
+    BigInteger bar = BigInteger.valueOf(secs);
+    byte[] b1 = bar.toByteArray();
+
+
+    if (b1.length > 4) {
+      for (int i=0; i<4; i++) {
+        b1[i] = b1[i+1];
+      }
+    }
+
+    BitSet bs = doubleToFixedPoint(fracsecs);
+    byte[] b2 = toByteArray(bs);
+
+    byte[] output = new byte[8];
+
+    for (int i=0; i< 4; i++) {
+      output[i] = b1[i];
+      output[i+4] = b2[i];
+    }
+
+    return output;
+
+  }
+
+
+  /**
+   * Returns a bitset containing the values in bytes.
+   * The byte-ordering of bytes must be big-endian which means
+   * the most significant bit is in element 0.
+   */
+  public static BitSet fromByteArray(byte[] bytes) {
+    BitSet bits = new BitSet(32);
+
+    for (int i=0; i<4; i++) {
+      for (int j=0; j<8; j++) {
+        if ((bytes[4-i-1] & (1 << j)) > 0) {
+          bits.set(8*i + j);
+        }
+      }
+    }
+
+    return bits;
+  }
+
+
+  /**
+   * BitSet -> ByteArray
+   */
+  private static byte[] toByteArray(BitSet bits) {
+    byte[] bytes = new byte[4];
+
+    for (int i=0; i<4; i++) {
+      for (int j=0; j<8; j++) {
+        if (bits.get(8*i + j)) {
+          bytes[4-(i)-1] |= 1 << j;
+        }
+      }
+    }
+
+    return bytes;
+  }
+
+
+  /**
+   * DEBUG method
+   */
+  private static void printByteArray(byte[] b) {
+    for (int i=0; i<b.length; i++) {
+      System.out.print(b[i] + " ");
+      if (i % 8 == 7) System.out.print("\n");
+    }
+  }
+
+
+  /**
+   * bytes to a floating point
+   */
+  private static float bytesToFloat(byte[] b) {
+
+    float output = 0;
+
+    BitSet bs = fromByteArray(b);
+
+    for (int i=0; i<32; i++) {
+      if (bs.get(i)) {
+        output += Math.pow(2,i-32);
+      }
+    }
+
+    return output;
+
+  }
+
+  /**
+   * floating point to fixed point
+   */
+  private static BitSet doubleToFixedPoint(double foo) {
+
+    BitSet output = new BitSet(32);
+
+    foo = foo % 1;
+    int idx = 0;
+
+    while (idx < 32) {
+      if (foo >= 0.5) {
+        output.set(31-idx);
+      }
+      idx++;
+      foo = foo * 10;
+      foo = foo % 1;
+    }
+
+    return output;
+
+  }
+
+  /**
+   * test program
+   */
+  public static void main(String args[]) throws Exception {
+
+    Date nowDate = new Date();
+    System.out.println("Date:");
+    System.out.println(nowDate.getTime());
+
+    System.out.println("Test default constructor");
+    NTPTimeStamp now = new NTPTimeStamp();
+    printByteArray(now.getBytes());
+    System.out.println(now.getLong());
+
+    System.out.println("Test byte[] constructor");
+
+    byte[] b = new byte[8];
+    b[0] = -125;
+    b[1] = -86;
+    b[2] = 56;
+    b[3] = 48;
+    b[4] = -128;
+    b[5] = 0;
+    b[6] = 0;
+    b[7] = 0;
+    NTPTimeStamp byteTest = new NTPTimeStamp(b);
+    printByteArray(byteTest.getBytes());
+    System.out.println(byteTest.getLong());
+
+    System.out.println("Test long constructor");
+
+    long BigOffset = 2208970800000L;
+    NTPTimeStamp longTest = new NTPTimeStamp(BigOffset,-5);
+    printByteArray(longTest.getBytes());
+    System.out.println(longTest.getLong());
+
+  }
+
+
+}
diff --git a/meet-j/server/clocks/NTPTimeStamp32.java b/meet-j/server/clocks/NTPTimeStamp32.java
new file mode 100644
index 0000000..2666008
--- /dev/null
+++ b/meet-j/server/clocks/NTPTimeStamp32.java
@@ -0,0 +1,92 @@
+/*
+ * NTPTimeStamp64.java
+ *
+ * Created on December 24, 2002, 5:37 AM
+ */
+
+package psl.meet.server.clocks;
+
+import java.nio.*;
+import java.io.IOException;
+import java.text.*;
+import java.text.DecimalFormat.*;
+import java.text.NumberFormat.Field;
+
+
+/**
+ *
+ * @author  phil
+ */
+public class NTPTimeStamp32 {
+
+
+  private final static double SCALE = (double) (65535.0);
+  private final static DecimalFormat fmt = new DecimalFormat(".00000");
+  private final static FieldPosition fpDecSep =
+  new FieldPosition(java.text.NumberFormat.Field.DECIMAL_SEPARATOR);
+  private int _secs = 0;
+  private int _frac = 0;
+  private double _fracDouble = 0.0;
+
+
+  /**
+   * create an NTPTimeStamp given a DataInputStream
+   *positioned right before the NTP packet bytes
+   */
+  public NTPTimeStamp32(ByteBuffer bb) throws IOException {
+
+    // parse the bytes to get a long
+    if (bb == null) {
+      throw new IOException("NTPTimeStamp32 ctor: bb uninitialized");
+    }
+    if (bb.remaining() < 4) {
+      throw new IOException("NTPTimeStamp32 ctor: bb remain < 4");
+    }
+
+    _secs = ((int) bb.getShort()) & 0xFFFF;  // force unsigned
+
+
+    _frac = ((int) bb.getShort()) & 0xFFFF;  // force unsigned
+    _fracDouble = _frac / SCALE;
+    System.out.println("_secs, _frac = " + Integer.toHexString(_secs) +
+    ", " + Integer.toHexString(_frac));
+
+  }
+
+  public String toString() {
+    StringBuffer sb = new StringBuffer(10);
+    fmt.format(_fracDouble, sb, fpDecSep);
+    // return ("" + _secs + "--" + sb);
+    return ("" + _secs + sb);
+  }
+
+  public static void main(String args[]) {
+    byte [] test1 = {
+      0x01, 0x00, 0x00, 0x01,
+    };
+    byte [] test2 = {
+      0x7F, 0x00, 0x7F, 0x00,
+    };
+    byte [] test3 = {
+      0x01, 0x00, 0x7F, 0x00,
+    };
+    ByteBuffer bb1 = ByteBuffer.wrap(test1);
+    ByteBuffer bb2 = ByteBuffer.wrap(test2);
+    ByteBuffer bb3 = ByteBuffer.wrap(test3);
+
+    NTPTimeStamp32 ntp1 = null;
+    NTPTimeStamp32 ntp2 = null;
+    NTPTimeStamp32 ntp3 = null;
+
+    try {
+      ntp1 = new NTPTimeStamp32(bb1);
+      ntp2 = new NTPTimeStamp32(bb2);
+      ntp3 = new NTPTimeStamp32(bb3);
+    } catch (IOException ioe) {
+      ioe.printStackTrace();
+    }
+    System.out.println("test1 = " + ntp1);
+    System.out.println("test2 = " + ntp2);
+    System.out.println("test3 = " + ntp3);
+  }
+}
diff --git a/meet-j/server/clocks/NTPTimeStamp32.java~ b/meet-j/server/clocks/NTPTimeStamp32.java~
new file mode 100644
index 0000000..8acd83b
--- /dev/null
+++ b/meet-j/server/clocks/NTPTimeStamp32.java~
@@ -0,0 +1,90 @@
+/*
+ * NTPTimeStamp64.java
+ *
+ * Created on December 24, 2002, 5:37 AM
+ */
+
+package psl.meet.server.clocks;
+
+import java.nio.*;
+import java.io.IOException;
+import java.text.*;
+import java.text.DecimalFormat.*;
+import java.text.NumberFormat.Field;
+
+
+/**
+ *
+ * @author  phil
+ */
+public class NTPTimeStamp32 {
+
+
+  private final static double SCALE = (double) (65535.0);
+  private final static DecimalFormat fmt = new DecimalFormat(".00000");
+  private final static FieldPosition fpDecSep =
+  new FieldPosition(java.text.NumberFormat.Field.DECIMAL_SEPARATOR);
+  private int _secs = 0;
+  private int _frac = 0;
+  private double _fracDouble = 0.0;
+
+
+  /**
+   * create an NTPTimeStamp given a DataInputStream
+   *positioned right before the NTP packet bytes
+   */
+  public NTPTimeStamp32(ByteBuffer bb) throws IOException {
+
+    // parse the bytes to get a long
+    if (bb == null) {
+      throw new IOException("NTPTimeStamp32 ctor: bb uninitialized");
+    }
+
+    _secs = ((int) bb.getShort()) & 0xFFFF;  // force unsigned
+
+    // max of unsigned long
+
+    _frac = ((int) bb.getShort()) & 0xFFFF;  // force unsigned
+    _fracDouble = _frac / SCALE;
+    System.out.println("_secs, _frac = " + Integer.toHexString(_secs) +
+    ", " + Integer.toHexString(_frac));
+
+  }
+
+  public String toString() {
+    StringBuffer sb = new StringBuffer(10);
+    fmt.format(_fracDouble, sb, fpDecSep);
+    // return ("" + _secs + "--" + sb);
+    return ("" + _secs + sb);
+  }
+
+  public static void main(String args[]) {
+    byte [] test1 = {
+      0x01, 0x00, 0x00, 0x01,
+    };
+    byte [] test2 = {
+      0x7F, 0x00, 0x7F, 0x00,
+    };
+    byte [] test3 = {
+      0x01, 0x00, 0x7F, 0x00,
+    };
+    ByteBuffer bb1 = ByteBuffer.wrap(test1);
+    ByteBuffer bb2 = ByteBuffer.wrap(test2);
+    ByteBuffer bb3 = ByteBuffer.wrap(test3);
+
+    NTPTimeStamp32 ntp1 = null;
+    NTPTimeStamp32 ntp2 = null;
+    NTPTimeStamp32 ntp3 = null;
+
+    try {
+      ntp1 = new NTPTimeStamp32(bb1);
+      ntp2 = new NTPTimeStamp32(bb2);
+      ntp3 = new NTPTimeStamp32(bb3);
+    } catch (IOException ioe) {
+      ioe.printStackTrace();
+    }
+    System.out.println("test1 = " + ntp1);
+    System.out.println("test2 = " + ntp2);
+    System.out.println("test3 = " + ntp3);
+  }
+}
diff --git a/meet-j/server/clocks/NTPTimeStamp64.java b/meet-j/server/clocks/NTPTimeStamp64.java
new file mode 100644
index 0000000..3c1afee
--- /dev/null
+++ b/meet-j/server/clocks/NTPTimeStamp64.java
@@ -0,0 +1,152 @@
+/*
+ * NTPTimeStamp64.java
+ *
+ * Created on December 24, 2002, 5:37 AM
+ */
+
+package psl.meet.server.clocks;
+
+import java.nio.*;
+import java.io.IOException;
+import java.text.*;
+import java.text.DecimalFormat.*;
+import java.text.NumberFormat.Field;
+import java.util.Date;
+
+/**
+ *
+ * @author  phil
+ */
+public class NTPTimeStamp64 {
+
+
+  private final static boolean DEBUG = true;
+  private final static double SCALE = (double) (4294967295.0);
+  /** seconds since 1-1-1900 minus seconds since 1-1-1970, in ms */
+  private final static long EPOCH_DIFF = 2208988800L ;
+  private final static long OFFSET = EPOCH_DIFF * 1000L;
+  private final static long DEFLATOR= (System.currentTimeMillis() / 1000L) + EPOCH_DIFF;
+  private final static DecimalFormat fmt = new DecimalFormat(".0#############");
+  private final static FieldPosition fpDecSep =
+  new FieldPosition(java.text.NumberFormat.Field.DECIMAL_SEPARATOR);
+  // allow direct access within package
+   long _secs = 0;
+   long _frac = 0;
+  private double _fracDouble = 0.0;
+
+  /** get current time as long in NTP format. */
+  static long currentNTP(long localOffset) {
+    long curr = System.currentTimeMillis() + OFFSET + localOffset;
+    // this integer represents milliseconds.  Need to move the
+    // decimal point between seconds and fraction to pos 31/32
+    long secs = curr / 1000L;
+    double dFrac = (curr % 1000L) / 1000.0;
+    long lfrac = (long) (dFrac * SCALE);
+    return (secs << 32) | (lfrac & 0xFFFFFFFFL);
+    //TODO: standard recommends filling low-end bits with random data.
+
+  }
+
+  Date toDate() {
+    long millisecs = (long)((_secs * 1000) + (_fracDouble * 1000) - OFFSET);
+    return new Date(millisecs);
+  }
+
+  public String toFull(){
+    return toDate().toString() + " (" + toString() + ")";
+  }
+
+  /** create an NTPTimeStamp64 object from an appropriately formatted long. */
+  public NTPTimeStamp64(long raw) {
+    _secs = (raw >> 32)& 0xFFFFFFFFL;  // force unsigned
+
+    _frac = raw & 0xFFFFFFFFL;  // force unsigned
+    _fracDouble = _frac / SCALE;
+    System.out.println("raw ctor: _secs, _frac = " + Long.toHexString(_secs) +
+    ", " + Long.toHexString(_frac));
+  }
+
+  /**
+   * create an NTPTimeStamp given a DataInputStream
+   *positioned right before the NTP packet bytes
+   */
+  public NTPTimeStamp64(ByteBuffer bb) throws IOException {
+
+    if (bb == null) {
+      throw new IOException("NTPTimeStamp64 ctor: bb uninitialized");
+    }
+    if (bb.remaining() < 8) {
+      throw new IOException("NTPTimeStamp64 ctor: bb remain of " +
+        bb.remaining() + " < 8");
+    }
+
+    _secs = ((long) bb.getInt()) & 0xFFFFFFFFL;  // force unsigned
+
+    // max of unsigned long
+
+    _frac = ((long) bb.getInt()) & 0xFFFFFFFFL;  // force unsigned
+    _fracDouble = _frac / SCALE;
+    System.out.println("Buffer ctor: _secs, _frac = " + Long.toHexString(_secs) +
+    ", " + Long.toHexString(_frac));
+
+  }
+
+  public String toString() {
+
+    StringBuffer sb = new StringBuffer(10);
+    fmt.format(_fracDouble, sb, fpDecSep);
+    // return ("" + _secs + "--" + sb);
+    return ("" + _secs + sb);
+  }
+
+  public long toLong() {
+    return ( (_secs << 32) | (_frac & 0xFFFFFFFFL) );
+  }
+
+  public double toDelta() {
+    /*
+     if (DEBUG) System.out.println("toDelta: _secs: " +
+      _secs + ", DEFLATOR: " +
+      DEFLATOR + ", _frac:" + _fracDouble);
+     */
+    return ((double)(_secs)) + _fracDouble;
+  }
+
+  public static long spanToMillis(long src) {
+    NTPTimeStamp64 ts = new NTPTimeStamp64(src);
+    return (long) ( (ts._secs * 1000) + (ts._fracDouble * 1000.0) );
+  }
+
+  public static void main(String args[]) {
+    byte [] test1 = {
+      0x00, 0x00, 0x00, 0x01,
+      0x00, 0x00, 0x00, 0x01
+    };
+    byte [] test2 = {
+      0x0F, 0x00, 0x00, 0x00,
+      0x0F, 0x00, 0x00, 0x00
+    };
+    byte [] test3 = {
+      0x7F, 0x00, 0x00, 0x01,
+      0x7F, 0x00, 0x00, 0x00
+    };
+    ByteBuffer bb1 = ByteBuffer.wrap(test1);
+    ByteBuffer bb2 = ByteBuffer.wrap(test2);
+    ByteBuffer bb3 = ByteBuffer.wrap(test3);
+
+    NTPTimeStamp64 ntp1 = null;
+    NTPTimeStamp64 ntp2 = null;
+    NTPTimeStamp64 ntp3 = null;
+
+    try {
+      ntp1 = new NTPTimeStamp64(bb1);
+      ntp2 = new NTPTimeStamp64(bb2);
+      ntp3 = new NTPTimeStamp64(bb3);
+    } catch (IOException ioe) {
+      ioe.printStackTrace();
+    }
+    System.out.println("test1 = " + ntp1);
+    System.out.println("test2 = " + ntp2);
+    System.out.println("test3 = " + ntp3);
+  }
+}
diff --git a/meet-j/server/clocks/NTPTimeStamp64.java~ b/meet-j/server/clocks/NTPTimeStamp64.java~
new file mode 100644
index 0000000..c3375eb
--- /dev/null
+++ b/meet-j/server/clocks/NTPTimeStamp64.java~
@@ -0,0 +1,151 @@
+/*
+ * NTPTimeStamp64.java
+ *
+ * Created on December 24, 2002, 5:37 AM
+ */
+
+package psl.meet.server.clocks;
+
+import java.nio.*;
+import java.io.IOException;
+import java.text.*;
+import java.text.DecimalFormat.*;
+import java.text.NumberFormat.Field;
+import java.util.Date;
+
+/**
+ *
+ * @author  phil
+ */
+public class NTPTimeStamp64 {
+
+
+  private final static boolean DEBUG = true;
+  private final static double SCALE = (double) (4294967295.0);
+  /** seconds since 1-1-1900 minus seconds since 1-1-1970, in ms */
+  private final static long EPOCH_DIFF = 2208988800L ;
+  private final static long OFFSET = EPOCH_DIFF * 1000L;
+  private final static long DEFLATOR= (System.currentTimeMillis() / 1000L) + EPOCH_DIFF;
+  private final static DecimalFormat fmt = new DecimalFormat(".0#############");
+  private final static FieldPosition fpDecSep =
+  new FieldPosition(java.text.NumberFormat.Field.DECIMAL_SEPARATOR);
+  private long _secs = 0;
+  private long _frac = 0;
+  private double _fracDouble = 0.0;
+
+  /** get current time as long in NTP format. */
+  static long currentNTP(long localOffset) {
+    long curr = System.currentTimeMillis() + OFFSET + localOffset;
+    // this integer represents milliseconds.  Need to move the
+    // decimal point between seconds and fraction to pos 31/32
+    long secs = curr / 1000L;
+    double dFrac = (curr % 1000L) / 1000.0;
+    long lfrac = (long) (dFrac * SCALE);
+    return (secs << 32) | (lfrac & 0xFFFFFFFFL);
+    //TODO: standard recommends filling low-end bits with random data.
+
+  }
+
+  Date toDate() {
+    long millisecs = (long)((_secs * 1000) + (_fracDouble * 1000) - OFFSET);
+    return new Date(millisecs);
+  }
+
+  public String toFull(){
+    return toDate().toString() + " (" + toString() + ")";
+  }
+
+  /** create an NTPTimeStamp64 object from an appropriately formatted long. */
+  public NTPTimeStamp64(long raw) {
+    _secs = (raw >> 32)& 0xFFFFFFFFL;  // force unsigned
+
+    _frac = raw & 0xFFFFFFFFL;  // force unsigned
+    _fracDouble = _frac / SCALE;
+    System.out.println("raw ctor: _secs, _frac = " + Long.toHexString(_secs) +
+    ", " + Long.toHexString(_frac));
+  }
+
+  /**
+   * create an NTPTimeStamp given a DataInputStream
+   *positioned right before the NTP packet bytes
+   */
+  public NTPTimeStamp64(ByteBuffer bb) throws IOException {
+
+    if (bb == null) {
+      throw new IOException("NTPTimeStamp64 ctor: bb uninitialized");
+    }
+    if (bb.remaining() < 8) {
+      throw new IOException("NTPTimeStamp64 ctor: bb remain of " +
+        bb.remaining() + " < 8");
+    }
+
+    _secs = ((long) bb.getInt()) & 0xFFFFFFFFL;  // force unsigned
+
+    // max of unsigned long
+
+    _frac = ((long) bb.getInt()) & 0xFFFFFFFFL;  // force unsigned
+    _fracDouble = _frac / SCALE;
+    System.out.println("Buffer ctor: _secs, _frac = " + Long.toHexString(_secs) +
+    ", " + Long.toHexString(_frac));
+
+  }
+
+  public String toString() {
+
+    StringBuffer sb = new StringBuffer(10);
+    fmt.format(_fracDouble, sb, fpDecSep);
+    // return ("" + _secs + "--" + sb);
+    return ("" + _secs + sb);
+  }
+
+  public long toLong() {
+    return ( (_secs << 32) | (_frac & 0xFFFFFFFFL) );
+  }
+
+  public double toDelta() {
+    /*
+     if (DEBUG) System.out.println("toDelta: _secs: " +
+      _secs + ", DEFLATOR: " +
+      DEFLATOR + ", _frac:" + _fracDouble);
+     */
+    return ((double)(_secs)) + _fracDouble;
+  }
+
+  public static long spanToMillis(long src) {
+    NTPTimeStamp64 ts = new NTPTimeStamp64(src);
+    return (long) ( (ts._secs * 1000) + (ts._fracDouble * 1000.0) );
+  }
+
+  public static void main(String args[]) {
+    byte [] test1 = {
+      0x00, 0x00, 0x00, 0x01,
+      0x00, 0x00, 0x00, 0x01
+    };
+    byte [] test2 = {
+      0x0F, 0x00, 0x00, 0x00,
+      0x0F, 0x00, 0x00, 0x00
+    };
+    byte [] test3 = {
+      0x7F, 0x00, 0x00, 0x01,
+      0x7F, 0x00, 0x00, 0x00
+    };
+    ByteBuffer bb1 = ByteBuffer.wrap(test1);
+    ByteBuffer bb2 = ByteBuffer.wrap(test2);
+    ByteBuffer bb3 = ByteBuffer.wrap(test3);
+
+    NTPTimeStamp64 ntp1 = null;
+    NTPTimeStamp64 ntp2 = null;
+    NTPTimeStamp64 ntp3 = null;
+
+    try {
+      ntp1 = new NTPTimeStamp64(bb1);
+      ntp2 = new NTPTimeStamp64(bb2);
+      ntp3 = new NTPTimeStamp64(bb3);
+    } catch (IOException ioe) {
+      ioe.printStackTrace();
+    }
+    System.out.println("test1 = " + ntp1);
+    System.out.println("test2 = " + ntp2);
+    System.out.println("test3 = " + ntp3);
+  }
+}
diff --git a/meet-j/server/clocks/NTPTimeStamp64_1.java~ b/meet-j/server/clocks/NTPTimeStamp64_1.java~
new file mode 100644
index 0000000..55a597f
--- /dev/null
+++ b/meet-j/server/clocks/NTPTimeStamp64_1.java~
@@ -0,0 +1,94 @@
+/*
+ * NTPTimeStamp64.java
+ *
+ * Created on December 24, 2002, 5:37 AM
+ */
+
+package psl.meet.server.clocks;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.text.*;
+import java.text.DecimalFormat.*;
+import java.text.NumberFormat.Field;
+
+
+/**
+ *
+ * @author  phil
+ */
+public class NTPTimeStamp64 {
+
+
+  final static double SCALE = (double) (4294967296.0);
+  final static DecimalFormat fmt = new DecimalFormat(".000000000");
+  final static FieldPosition fpDecSep =
+  new FieldPosition(java.text.NumberFormat.Field.DECIMAL_SEPARATOR);
+  private long _secs = 0;
+  private long _frac = 0;
+  private double _fracDouble = 0.0;
+
+
+  /**
+   * create an NTPTimeStamp given a DataInputStream
+   *positioned right before the NTP packet bytes
+   */
+  public NTPTimeStamp64(DataInputStream dis) throws IOException {
+
+    // parse the bytes to get a long
+    if (dis == null) {
+      throw new IOException("NTPTSRaw64 ctor: dis uninitialized");
+    }
+
+    _secs = ((long) dis.readInt()) & 0xFFFFFFFFL;  // force unsigned
+
+    // max of unsigned long
+
+    _frac = ((long) dis.readInt()) & 0xFFFFFFFFL;  // force unsigned
+    _fracDouble = _frac / SCALE;
+    System.out.println("_secs, _frac = " + Long.toHexString(_secs) +
+    ", " + Long.toHexString(_frac));
+
+  }
+
+  public String toString() {
+    StringBuffer sb = new StringBuffer(10);
+    fmt.format(_fracDouble, sb, fpDecSep);
+    // return ("" + _secs + "--" + sb);
+    return ("" + _secs + sb);
+  }
+
+  public static void main(String args[]) {
+    byte [] test1 = {
+      0x00, 0x00, 0x00, 0x01,
+      0x00, 0x00, 0x00, 0x01
+    };
+    byte [] test2 = {
+      0x0F, 0x00, 0x00, 0x00,
+      0x0F, 0x00, 0x00, 0x00
+    };
+    byte [] test3 = {
+      0x7F, 0x00, 0x00, 0x01,
+      0x7F, 0x00, 0x00, 0x00
+    };
+    java.io.ByteArrayInputStream bais1 = new java.io.ByteArrayInputStream(test1);
+    java.io.ByteArrayInputStream bais2 = new java.io.ByteArrayInputStream(test2);
+    java.io.ByteArrayInputStream bais3 = new java.io.ByteArrayInputStream(test3);
+
+    NTPTimeStamp64 ntp1 = null;
+    NTPTimeStamp64 ntp2 = null;
+    NTPTimeStamp64 ntp3 = null;
+
+    try {
+      ntp1 = new NTPTimeStamp64(new DataInputStream(bais1));
+      ntp2 = new NTPTimeStamp64(new DataInputStream(bais2));
+      ntp3 = new NTPTimeStamp64(new DataInputStream(bais3));
+    } catch (IOException ioe) {
+      ioe.printStackTrace();
+    }
+    System.out.println("test1 = " + ntp1);
+    System.out.println("test2 = " + ntp2);
+    System.out.println("test3 = " + ntp3);
+  }
+}
diff --git a/meet-j/server/clocks/NTPTimeStampRaw.java~ b/meet-j/server/clocks/NTPTimeStampRaw.java~
new file mode 100644
index 0000000..e1c2c8e
--- /dev/null
+++ b/meet-j/server/clocks/NTPTimeStampRaw.java~
@@ -0,0 +1,3 @@
+package psl.meet.server.clocks;
+
+
diff --git a/meet-j/server/clocks/SNTPClock.java b/meet-j/server/clocks/SNTPClock.java
index 916b74b..76aa94b 100644
--- a/meet-j/server/clocks/SNTPClock.java
+++ b/meet-j/server/clocks/SNTPClock.java
@@ -8,9 +8,13 @@ package psl.meet.server.clocks;

 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
-import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.nio.*;
+import java.nio.channels.*;
+import java.io.IOException;
 import java.util.Date;
-import java.util.BitSet;
+
+import psl.meet.server.clocks.NTPTimeStamp64;


 /**
@@ -18,291 +22,286 @@ import java.util.BitSet;
  * @author  mkuba
  */
 public class SNTPClock implements MEETClock {
-
-    // print debug statements
-    final boolean DEBUG = false;
+
+  // print debug statements
+  final static boolean DEBUG = true;
+
+  // multicast or unicast client, unused for now
+  boolean multiCastMode;
+
+  // offset from the system clock, this is updated
+  // instead of actual system clock
+  // (keep away from native methods for now)
+  private long _offset;
+
+  // roundtrip delay in communicating with NTP server
+  private long _delay;
+
+  // automatically update clock at certain intervals
+  // unused for now
+  private long updateInterval;
+
+  // NTP Server to use
+  private String _server = "localhost";
+  private int _port = 123;
+
+  // offset from UT, in hours
+  private int timezone = 0;
+
+  private DatagramChannel dgc = null;
+
+
+  /** Creates a new instance of SNTPClock */
+  public SNTPClock() {
+    updateInterval = -1;
+    _delay = 0;
+    _offset = 0;
+    try {
+      dgc = DatagramChannel.open();
+    } catch (IOException ioe) {ioe.printStackTrace();}
+  }
+
+  /**
+   * creates a new SNTPClock
+   */
+  public SNTPClock(String srvr, int p, long updateint) {
+    _server = srvr;
+    _port = p;
+    updateInterval = updateint;
+    _delay = 0;
+    _offset = 0;
+    try {
+      dgc = DatagramChannel.open();
+    } catch (IOException ioe) {ioe.printStackTrace();}
+  }
+
+  /**
+   * set what timezone we are in
+   */
+  public void setTimezone(int tz) {
+    timezone = tz;
+  }
+
+  /**
+   * set which NTP server to use
+   */
+  public void setSource(String srvr, int p) {
+    _server = srvr;
+    _port = p;
+  }
+
+  /**
+   * set the update interval
+   */
+  public void setUpdateInterval(long ui) {
+    updateInterval = ui;
+  }
+
+  /**
+   * return the clock name
+   * from MEETClock interface
+   */
+  public String getClockName() {
+    return "SNTPClock";
+  }
+
+  /**
+   * return # of milliseconds since Jan 1 1900, 00:00:00 UT
+   */
+  public long getTime() {
+    // NTPTimeStamp now = new NTPTimeStamp(timezone);
+    // return now + offset;
+    return System.currentTimeMillis() + _offset;
+  }
+
+  /**
+   * get the offset from the reference clock
+   * in number of milliseconds
+   */
+  public long getOffset() {
+    return _offset;
+  }
+
+  /**
+   * get the calculated network delay
+   */
+  public long getDelay() {
+    return _delay;
+  }
+
+
+  /**
+   * send bytes to NTP Server
+   *
+   */
+  public void getNTP() throws Exception {

-    // multicast or unicast client, unused for now
-    boolean multiCastMode;
-
-    // offset from the system clock, this is updated
-    // instead of actual system clock
-    // (keep away from native methods for now)
-    private long offset;
-
-    // roundtrip delay in communicating with NTP server
-    private long delay;
-
-    // automatically update clock at certain intervals
-    // unused for now
-    private long updateInterval;
-
-    // NTP Server to use
-    private String server;
-    private int port;
-
-    // offset from UT, in hours
-    private int timezone;
-
-
-    /** Creates a new instance of SNTPClock */
-    public SNTPClock() {
-	server = "";
-	port = 0;
-	timezone = 0;
-	updateInterval = -1;
-	delay = 0;
-	offset = 0;
-    }
-
-    /**
-     * creates a new SNTPClock
-     */
-    public SNTPClock(String srvr, int p, int tz, long updateint) {
-	server = srvr;
-	port = p;
-	timezone = tz;
-	updateInterval = updateint;
-	delay = 0;
-	offset = 0;
-    }
-
-    /**
-     * set what timezone we are in
-     */
-    public void setTimezone(int tz) {
-	timezone = tz;
+    // create socket to server
+    InetSocketAddress remote = new InetSocketAddress(_server, _port);
+    DatagramSocket s = dgc.socket();
+    if (!s.isBound()) {
+      s.bind(null);
     }
-
-    /**
-     * set which NTP server to use
-     */
-    public void setSource(String srvr, int p) {
-	server = srvr;
-	port = p;
-    }
-
-    /**
-     * set the update interval
-     */
-    public void setUpdateInterval(long ui) {
-	updateInterval = ui;
+    if (!dgc.isConnected()) {
+      dgc.connect(remote);
+      dgc.configureBlocking(false);
     }
-
-    /**
-     * return the clock name
-     * from MEETClock interface
-     */
-    public String getClockName() {
-	return "SNTPClock";
+
+    // create packet
+    ByteBuffer bbOut = ByteBuffer.allocate(48);
+    bbOut.order(ByteOrder.BIG_ENDIAN);
+    bbOut.clear();
+    // mode = 3, version = 3, LI = 0
+    bbOut.put(0, (byte) 35);
+    // rfc2030: put our current time in Transmit field
+    long now = NTPTimeStamp64.currentNTP(_offset);
+    if (DEBUG) {
+      NTPTimeStamp64 nowTS = new NTPTimeStamp64(now);
+      System.out.println("calced current time as " + nowTS.toFull());
     }
-
-    /**
-     * return # of milliseconds since Jan 1 1900, 00:00:00 UT
-     */
-    public long getTime() {
-	NTPTimeStamp now = new NTPTimeStamp(timezone);
-	return now.getLong() + offset;
+    bbOut.putLong(40, now);
+    bbOut.rewind();
+    NTPMessage ntpOut = new NTPMessage(bbOut);
+    System.out.println("preparing to send NTP query:" + ntpOut);
+    bbOut.rewind();
+
+
+   // send packet
+    if (DEBUG) System.out.println("Attempting to send packet to " + remote);
+    dgc.send(bbOut, remote);
+    if (DEBUG) System.out.println("Packet sent\n");
+
+    // create receiving packet
+    ByteBuffer bbIn = ByteBuffer.allocate(48);
+    bbIn.order(ByteOrder.BIG_ENDIAN);
+    bbIn.clear();
+    InetSocketAddress rcvAddr = (InetSocketAddress) dgc.receive(bbIn);
+    if (rcvAddr == null) {
+      System.out.println("got null packet");
+      return;
     }
-
-    /**
-     * get the offset from the reference clock
-     * in number of milliseconds
-     */
-    public long getOffset() {
-	return offset;
+    NTPTimeStamp64 T4 = new NTPTimeStamp64(NTPTimeStamp64.currentNTP(_offset));
+
+    bbIn.rewind();
+    if (DEBUG) System.out.println("Received packet from " + rcvAddr);
+    System.out.println("buffer remaining:" + bbIn.remaining());
+    /*
+     byte ba[] = bbIn.array();
+    System.out.println("backing array is:");
+    for (int i=0; i<48; i+=4) {
+      for (int j=0; j<4; ++j) {
+        System.out.print(ba[i+j] + "  ");
+      }
+      System.out.print('\n');
     }
-
-    /**
-     * get the calculated network delay
      */
-    public long getDelay() {
-	return delay;
+    NTPMessage ntpIn = new NTPMessage(bbIn);
+    System.out.println("parsed message is:\n" + ntpIn);
+    if (ntpIn.getVersion() < 3) {
+      return;
     }
-
-    /**
-     * synchronize with NTP server
-     */
-    public void sync() throws Exception {
-	byte[] b = this.createSNTPRequest();
-	this.send(b);
+
+    _delay = ntpIn.calcDelay(T4);
+    _offset = ntpIn.calcOffset(T4);
+    // parse Timestamps from received packet
+
+    // delay and offset, as defined in RFC 2030
+
+    //_delay = ( (T4 - T1) - (T2 - T3) );
+
+    // _offset = (long)(( (T2 - T1) + (T3 - T4) ) / 2);
+
+
+
+    //DEBUG
+    if (DEBUG) {
+      // System.out.println("T1-4 = " + T1 +", "+T2+", "+T3+", "+T4);
+      System.out.println("delay, offset = " + _delay + ", " + _offset);
     }
-
-
+
+  }
+
+
+  /**
+   * receive NTP information (unused)
+   */
+  public void receive() throws Exception {
+
     /**
-     * send bytes to NTP Server
+     * //create empty packet
+     * byte[] data = new byte[40];
+     * DatagramPacket packet = new DatagramPacket(data,40);
      *
+     * // create socket
+     * DatagramSocket socket = new DatagramSocket(123);
+     *
+     * // wait for socket
+     *
+     * System.out.println("waiting for packet\n");
+     * socket.receive(packet);
+     *
+     * // print out what was received
+     * String msg = new String(packet.getData());
+     *
+     * System.out.println("received: ");
+     * printByteArray(packet.getData());
      */
-    public void send(byte[] data) throws Exception {
-
-        // create socket to server
-        InetAddress address = InetAddress.getByName(server);
-
-        DatagramSocket socket = new DatagramSocket();
-	socket.connect(address,port);
-
-        // create packet
-        DatagramPacket packet = new DatagramPacket(data,data.length,address,port);
-
-
-        // send packet
-        if (DEBUG) System.out.println("Attempting to send packet to " + socket.getInetAddress() + " (" + socket.getPort()  + ")\n");
-
-        socket.send(packet);
-
-        if (DEBUG) System.out.println("Packet sent\n");
-
-	// create receiving packet
-	byte[] rx = new byte[48];
-	packet = new DatagramPacket(rx,48);
-
-	//socket.disconnect();
-	//socket.close();
-
-
-	// receive packet
-        socket.receive(packet);
-
-	// calculate timestamp for time packet was received
-	// this is occasionally not correct, probably because
-	// of java instruction reordering
-        NTPTimeStamp T4 = new NTPTimeStamp(timezone);
-
-
-	// parse Timestamps from received packet
-
-	byte[] t1 = new byte[8];
-	for (int i=0; i<8; i++) {
-	    t1[i] = rx[24+i];
-	}
-	NTPTimeStamp T1 = new NTPTimeStamp(t1);
-
-	byte[] t2 = new byte[8];
-	for (int i=0; i<8; i++) {
-	    t2[i] = rx[32+i];
-	}
-	NTPTimeStamp T2 = new NTPTimeStamp(t2);
-
-	byte[] t3 = new byte[8];
-	for (int i=0; i<8; i++) {
-	    t3[i] = rx[40+i];
-	}
-	NTPTimeStamp T3 = new NTPTimeStamp(t3);
-
-
-	// delay and offset, as defined in RFC 2030
-
-	delay = ( (T4.getLong() - T1.getLong()) - (T2.getLong() - T3.getLong()) );
-
-	offset = (long)(( (T2.getLong() - T1.getLong()) + (T3.getLong() - T4.getLong()) ) / 2);
-
-
-
-	//DEBUG
-	if (DEBUG) {
-	    System.out.println("T1 = " + T1.getLong());
-	    System.out.println("T2 = " + T2.getLong());
-	    System.out.println("T3 = " + T3.getLong());
-	    System.out.println("T4 = " + T4.getLong());
-
-	    System.out.println("delay = " + delay);
-	    System.out.println("offset = " + offset);
-	}
-
-    }
-
-
-    /**
-     * receive NTP information (unused)
-     */
-    public void receive() throws Exception {
-
-        /**
-        //create empty packet
-        byte[] data = new byte[40];
-        DatagramPacket packet = new DatagramPacket(data,40);
-
-        // create socket
-        DatagramSocket socket = new DatagramSocket(123);
-
-        // wait for socket
-
-        System.out.println("waiting for packet\n");
-        socket.receive(packet);
-
-        // print out what was received
-        String msg = new String(packet.getData());
-
-        System.out.println("received: ");
-        printByteArray(packet.getData());
-	*/
-    }
-
-
-    /**
-     * create a valid NTP Request
-     */
-    public byte[] createSNTPRequest() {
-
-	NTPTimeStamp ntptime = new NTPTimeStamp(timezone);
-	byte[] time = ntptime.getBytes();
-
-	byte[] output = new byte[48];
-
-	for (int i=0; i < output.length; i++) {
-	    output[i] = 0;
-	}
-
-	// just the bytes we need to fill in, hardcoded
-	// every request has the same first 4 bytes
-	output[0] = 35;
-	output[1] = 3;
-	output[2] = 10;
-	output[3] = -15;
-
-	for (int i=0; i < 8; i++) {
-	    output[40+i] = time[i];
-	}
-
-	return output;
-
+  }
+
+
+
+
+  // DEBUG
+  public static void printByteArray(byte[] b) {
+    for (int i=0; i<b.length; i++) {
+      System.out.print(b[i] + " ");
+      if (i % 8 == 7) System.out.print("\n");
     }
-
+  }
+
+
+  /**
+   * test program
+   */
+  public static void main(String args[]) throws Exception {

-    // DEBUG
-    public static void printByteArray(byte[] b) {
-        for (int i=0; i<b.length; i++) {
-            System.out.print(b[i] + " ");
-	    if (i % 8 == 7) System.out.print("\n");
-        }
+    if (args.length < 2) {
+      System.out.println("Usage: java SNTPClock <ntp server> <port>");
+      System.exit(0);
     }

-
-    /**
-     * test program
-     */
-    public static void main(String args[]) throws Exception {
-
-	if (args.length < 2) {
-	    System.out.println("Usage: java SNTPClock <ntp server> <port>");
-	    System.exit(0);
-	}
-
-	SNTPClock sc = new SNTPClock(args[0], Integer.parseInt(args[1]), -5, 0);
-
-	long oldOffset = 0;
-
-	System.out.println("offset\t\tdelta");
-
-	while (true) {
-	    sc.sync();
-	    Thread.sleep(2000);
-
-	    System.out.println(sc.getOffset() + "\t\t" + (sc.getOffset() - oldOffset));
-	    oldOffset = sc.getOffset();
-
-	}
-
+    SNTPClock sc = new SNTPClock(args[0], Integer.parseInt(args[1]), 0);
+
+    long oldOffset = 0;
+
+    System.out.println("time\t\toffset\t\tdelta");
+
+    while (true) {
+      if (DEBUG) System.out.println("about to sc.getNTP()");
+      sc.getNTP();
+
+      System.out.println(new Date(sc.getTime()) + "\t\t" +
+        sc.getOffset() + "\t\t" + (sc.getOffset() - oldOffset));
+      oldOffset = sc.getOffset();
+
+      Thread.sleep(5000);
+
     }

+  }
+
+  /** When an object implementing interface <code>Runnable</code> is used
+   * to create a thread, starting the thread causes the object's
+   * <code>run</code> method to be called in that separately executing
+   * thread.
+   * <p>
+   * The general contract of the method <code>run</code> is that it may
+   * take any action whatsoever.
+   *
+   * @see     java.lang.Thread#run()
+   *
+   */
+  public void run() {
+  }
+
 }
diff --git a/meet-j/server/clocks/SNTPClock.java~ b/meet-j/server/clocks/SNTPClock.java~
new file mode 100644
index 0000000..2dcd97f
--- /dev/null
+++ b/meet-j/server/clocks/SNTPClock.java~
@@ -0,0 +1,307 @@
+/*
+ * SNTPClock.java
+ *
+ * Created on November 7, 2002, 8:34 PM
+ */
+
+package psl.meet.server.clocks;
+
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetSocketAddress;
+import java.nio.*;
+import java.nio.channels.*;
+import java.io.IOException;
+import java.util.Date;
+
+import psl.meet.server.clocks.NTPTimeStamp64;
+
+
+/**
+ *
+ * @author  mkuba
+ */
+public class SNTPClock implements MEETClock {
+
+  // print debug statements
+  final static boolean DEBUG = true;
+
+  // multicast or unicast client, unused for now
+  boolean multiCastMode;
+
+  // offset from the system clock, this is updated
+  // instead of actual system clock
+  // (keep away from native methods for now)
+  private long _offset;
+
+  // roundtrip delay in communicating with NTP server
+  private long _delay;
+
+  // automatically update clock at certain intervals
+  // unused for now
+  private long updateInterval;
+
+  // NTP Server to use
+  private String _server = "localhost";
+  private int _port = 123;
+
+  // offset from UT, in hours
+  private int timezone = 0;
+
+  private DatagramChannel dgc = null;
+
+
+  /** Creates a new instance of SNTPClock */
+  public SNTPClock() {
+    updateInterval = -1;
+    _delay = 0;
+    _offset = 0;
+    try {
+      dgc = DatagramChannel.open();
+    } catch (IOException ioe) {ioe.printStackTrace();}
+  }
+
+  /**
+   * creates a new SNTPClock
+   */
+  public SNTPClock(String srvr, int p, long updateint) {
+    _server = srvr;
+    _port = p;
+    updateInterval = updateint;
+    _delay = 0;
+    _offset = 0;
+    try {
+      dgc = DatagramChannel.open();
+    } catch (IOException ioe) {ioe.printStackTrace();}
+  }
+
+  /**
+   * set what timezone we are in
+   */
+  public void setTimezone(int tz) {
+    timezone = tz;
+  }
+
+  /**
+   * set which NTP server to use
+   */
+  public void setSource(String srvr, int p) {
+    _server = srvr;
+    _port = p;
+  }
+
+  /**
+   * set the update interval
+   */
+  public void setUpdateInterval(long ui) {
+    updateInterval = ui;
+  }
+
+  /**
+   * return the clock name
+   * from MEETClock interface
+   */
+  public String getClockName() {
+    return "SNTPClock";
+  }
+
+  /**
+   * return # of milliseconds since Jan 1 1900, 00:00:00 UT
+   */
+  public long getTime() {
+    // NTPTimeStamp now = new NTPTimeStamp(timezone);
+    // return now + offset;
+    return System.currentTimeMillis() + _offset;
+  }
+
+  /**
+   * get the offset from the reference clock
+   * in number of milliseconds
+   */
+  public long getOffset() {
+    return _offset;
+  }
+
+  /**
+   * get the calculated network delay
+   */
+  public long getDelay() {
+    return _delay;
+  }
+
+
+  /**
+   * send bytes to NTP Server
+   *
+   */
+  public void getNTP() throws Exception {
+
+    // create socket to server
+    InetSocketAddress remote = new InetSocketAddress(_server, _port);
+    DatagramSocket s = dgc.socket();
+    if (!s.isBound()) {
+      s.bind(null);
+    }
+    if (!dgc.isConnected()) {
+      dgc.connect(remote);
+      dgc.configureBlocking(false);
+    }
+
+    // create packet
+    ByteBuffer bbOut = ByteBuffer.allocate(48);
+    bbOut.order(ByteOrder.BIG_ENDIAN);
+    bbOut.clear();
+    // mode = 3, version = 3, LI = 0
+    bbOut.put(0, (byte) 35);
+    // rfc2030: put our current time in Transmit field
+    long now = NTPTimeStamp64.currentNTP(_offset);
+    if (DEBUG) {
+      NTPTimeStamp64 nowTS = new NTPTimeStamp64(now);
+      System.out.println("calced current time as " + nowTS.toFull());
+    }
+    bbOut.putLong(40, now);
+    bbOut.rewind();
+    NTPMessage ntpOut = new NTPMessage(bbOut);
+    System.out.println("preparing to send NTP query:" + ntpOut);
+    bbOut.rewind();
+
+
+   // send packet
+    if (DEBUG) System.out.println("Attempting to send packet to " + remote);
+    dgc.send(bbOut, remote);
+    if (DEBUG) System.out.println("Packet sent\n");
+
+    // create receiving packet
+    ByteBuffer bbIn = ByteBuffer.allocate(48);
+    bbIn.order(ByteOrder.BIG_ENDIAN);
+    bbIn.clear();
+    InetSocketAddress rcvAddr = (InetSocketAddress) dgc.receive(bbIn);
+    if (rcvAddr == null) {
+      System.out.println("got null packet");
+      return;
+    }
+    NTPTimeStamp64 T4 = new NTPTimeStamp64(NTPTimeStamp64.currentNTP(_offset));
+
+    bbIn.rewind();
+    if (DEBUG) System.out.println("Received packet from " + rcvAddr);
+    System.out.println("buffer remaining:" + bbIn.remaining());
+    /*
+     byte ba[] = bbIn.array();
+    System.out.println("backing array is:");
+    for (int i=0; i<48; i+=4) {
+      for (int j=0; j<4; ++j) {
+        System.out.print(ba[i+j] + "  ");
+      }
+      System.out.print('\n');
+    }
+     */
+    NTPMessage ntpIn = new NTPMessage(bbIn);
+    System.out.println("parsed message is:\n" + ntpIn);
+    if (ntpIn.getVersion() < 3) {
+      return;
+    }
+
+    _delay = ntpIn.calcDelay(T4);
+    _offset = ntpIn.calcOffset(T4);
+    // parse Timestamps from received packet
+
+    // delay and offset, as defined in RFC 2030
+
+    //_delay = ( (T4 - T1) - (T2 - T3) );
+
+    // _offset = (long)(( (T2 - T1) + (T3 - T4) ) / 2);
+
+
+
+    //DEBUG
+    if (DEBUG) {
+      // System.out.println("T1-4 = " + T1 +", "+T2+", "+T3+", "+T4);
+      System.out.println("delay, offset = " + _delay + ", " + _offset);
+    }
+
+  }
+
+
+  /**
+   * receive NTP information (unused)
+   */
+  public void receive() throws Exception {
+
+    /**
+     * //create empty packet
+     * byte[] data = new byte[40];
+     * DatagramPacket packet = new DatagramPacket(data,40);
+     *
+     * // create socket
+     * DatagramSocket socket = new DatagramSocket(123);
+     *
+     * // wait for socket
+     *
+     * System.out.println("waiting for packet\n");
+     * socket.receive(packet);
+     *
+     * // print out what was received
+     * String msg = new String(packet.getData());
+     *
+     * System.out.println("received: ");
+     * printByteArray(packet.getData());
+     */
+  }
+
+
+
+
+  // DEBUG
+  public static void printByteArray(byte[] b) {
+    for (int i=0; i<b.length; i++) {
+      System.out.print(b[i] + " ");
+      if (i % 8 == 7) System.out.print("\n");
+    }
+  }
+
+
+  /**
+   * test program
+   */
+  public static void main(String args[]) throws Exception {
+
+    if (args.length < 2) {
+      System.out.println("Usage: java SNTPClock <ntp server> <port>");
+      System.exit(0);
+    }
+
+    SNTPClock sc = new SNTPClock(args[0], Integer.parseInt(args[1]), 0);
+
+    long oldOffset = 0;
+
+    System.out.println("time\t\toffset\t\tdelta");
+
+    while (true) {
+      if (DEBUG) System.out.println("about to sc.getNTP()");
+      sc.getNTP();
+
+      System.out.println(sc.getTime() + "\t\t" +
+        sc.getOffset() + "\t\t" + (sc.getOffset() - oldOffset));
+      oldOffset = sc.getOffset();
+
+      Thread.sleep(5000);
+
+    }
+
+  }
+
+  /** When an object implementing interface <code>Runnable</code> is used
+   * to create a thread, starting the thread causes the object's
+   * <code>run</code> method to be called in that separately executing
+   * thread.
+   * <p>
+   * The general contract of the method <code>run</code> is that it may
+   * take any action whatsoever.
+   *
+   * @see     java.lang.Thread#run()
+   *
+   */
+  public void run() {
+  }
+
+}
diff --git a/meet-j/server/clocks/test.java b/meet-j/server/clocks/test.java
new file mode 100644
index 0000000..b80bb4a
--- /dev/null
+++ b/meet-j/server/clocks/test.java
@@ -0,0 +1,43 @@
+/*
+ * test.java
+ *
+ * Created on December 24, 2002, 10:27 AM
+ */
+
+package psl.meet.server.clocks;
+
+/**
+ *
+ * @author  phil
+ */
+public class test {
+
+  /** Creates a new instance of test */
+  public test() {
+  }
+
+  static long DateToMjd(int y, int m, int d) {
+    return
+    367 * y
+    - 7 * (y + (m + 9) / 12) / 4
+    - 3 * ((y + (m - 9) / 7) / 100 + 1) / 4
+    + 275 * m / 9
+    + d
+    + 1721028L
+    - 2400000L;
+  }
+
+/*
+ * Calculate number of seconds since 1-Jan-1900.
+ * - Ignores UTC leap seconds.
+ */
+
+  static long SecondsSince1900(int y, int m, int d) {
+    long Days = DateToMjd(y, m, d) - DateToMjd(1900, 1, 1);
+    return Days * 86400L;
+  }
+
+  public static void main(String args[]) {
+    System.out.println(SecondsSince1900(1970,1,1));
+  }
+}
\ No newline at end of file
diff --git a/meet-j/server/clocks/test.java~ b/meet-j/server/clocks/test.java~
new file mode 100644
index 0000000..119bd23
--- /dev/null
+++ b/meet-j/server/clocks/test.java~
@@ -0,0 +1,19 @@
+/*
+ * test.java
+ *
+ * Created on December 24, 2002, 10:27 AM
+ */
+
+package psl.meet.server.clocks;
+
+/**
+ *
+ * @author  phil
+ */
+public class test {
+
+  /** Creates a new instance of test */
+  public test() {
+  }
+
+}
diff --git a/meet-j/server/types/IEvent.java b/meet-j/server/types/IEvent.java
index 939cedb..dd7feaa 100644
--- a/meet-j/server/types/IEvent.java
+++ b/meet-j/server/types/IEvent.java
@@ -62,6 +62,15 @@ public interface IEvent {
     public static final int MEET_PRIMITIVE_CHAR32   = 102;

     // 4 byte secs since 1 Jan 1970 GMT, 4 bytes fraction
-    public static final int MEET_PRIMITIVE_TSTAMP   = 200;
+    public static final int MEET_PRIMITIVE_TSTAMP   = 200;
+
+    // char string (no length, no null term)
+    public static final int MEET_PRIMITIVE_RSTRING  = 300;
+
+    // char string (null terminated)
+    public static final int MEET_PRIMITIVE_CSTRING  = 301;
+
+    // char string (prefixed with length byte)
+    public static final int MEET_PRIMITIVE_PSTRING  = 302;

 }
diff --git a/meet-j/server/types/IEvent.java~ b/meet-j/server/types/IEvent.java~
new file mode 100644
index 0000000..939cedb
--- /dev/null
+++ b/meet-j/server/types/IEvent.java~
@@ -0,0 +1,67 @@
+/*
+ * IEvent.java
+ *
+ * Created on August 5, 2002, 11:42 AM
+ */
+
+package psl.meet.server.types;
+
+/**
+ *
+ * @author  phil
+ */
+public interface IEvent {
+
+    // first byte is filter.  Should always have 0xEE
+    // weirdly, cast is needed for hex byte constants, but not decimal
+    public static final byte MEET_MAGIC = (byte) 0xEE;
+
+    // second byte gives top level event type
+    // 0 means content based routing (CBR)
+    public static final byte MEET_ETYPE_CBR         = 0;
+
+    // 1-63 reserved for system
+    // name refers to the manager that will probably be interested
+    public static final byte MEET_ETYPE_CORE        = 1;
+    public static final byte MEET_ETYPE_CACHE       = 2;
+    public static final byte MEET_ETYPE_CHANNEL     = 3;
+    public static final byte MEET_ETYPE_CLOCK       = 4;
+    public static final byte MEET_ETYPE_CONNECTION  = 5;
+    public static final byte MEET_ETYPE_EXECUTIVE   = 6;
+    public static final byte MEET_ETYPE_MONITOR     = 7;
+    public static final byte MEET_ETYPE_ROUTER      = 8;
+    public static final byte MEET_ETYPE_SCHEDULER   = 9;
+    public static final byte MEET_ETYPE_STORE       = 10;
+    public static final byte MEET_ETYPE_TYPE        = 11;
+    public static final byte MEET_ETYPE_USER        = 127;
+
+    public static final int MEET_TYPE_ATTVAL_SET    = 0;
+    public static final int MEET_TYPE_ATTVAL_LIST   = 10;
+    public static final int MEET_TYPE_XML_SCHEMA    = 20;
+    public static final int MEET_TYPE_JAVA          = 30;
+    public static final int MEET_TYPE_CLR           = 40;
+    // unadvertised bag of attvals
+    public static final int MEET_TYPE_SIENA         = 50;
+
+    public static final int MEET_PRIMITIVE_INT8     = 0;
+    public static final int MEET_PRIMITIVE_INT16    = 1;
+    public static final int MEET_PRIMITIVE_INT32    = 2;
+    public static final int MEET_PRIMITIVE_INT64    = 3;
+
+    public static final int MEET_PRIMITIVE_UINT8    = 10;
+    public static final int MEET_PRIMITIVE_UINT16   = 11;
+    public static final int MEET_PRIMITIVE_UINT32   = 12;
+    public static final int MEET_PRIMITIVE_UINT64   = 13;
+
+
+    public static final int MEET_PRIMITIVE_FLOAT32  = 20;
+    public static final int MEET_PRIMITIVE_FLOAT64  = 21;
+
+    public static final int MEET_PRIMITIVE_CHAR     = 100;
+    public static final int MEET_PRIMITIVE_CHAR16   = 101;
+    public static final int MEET_PRIMITIVE_CHAR32   = 102;
+
+    // 4 byte secs since 1 Jan 1970 GMT, 4 bytes fraction
+    public static final int MEET_PRIMITIVE_TSTAMP   = 200;
+
+}