se.kth.android.FrameWork.SynchronizedTime.java Source code

Java tutorial

Introduction

Here is the source code for se.kth.android.FrameWork.SynchronizedTime.java

Source

/* Copyright KTH Royal Institute of Technology, Martin Ohlsson, Per Zetterberg
* This software is provided  as is. It is free to use for non-commercial purposes.
* For commercial purposes please contact Peter Hndel (peter.handel@ee.kth.se)
* for a license. For non-commercial use, we appreciate citations of our work,
* please contact, Per Zetterberg (per.zetterberg@ee.kth.se), 
* for how information on how to cite. */

package se.kth.android.FrameWork;

import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.SocketException;

import org.apache.commons.net.ntp.NTPUDPClient;
import org.apache.commons.net.ntp.TimeInfo;
import org.apache.commons.net.ntp.TimeStamp;

//import se.kth.android.StudentCode.StudentCode;

public class SynchronizedTime {
    static final int NONTPO = 10000;
    int numO = 0;

    public long startMillisLocal;
    public long startNanosLocal;
    long startNanoTimeLocal = 0;
    public long startNtpTimeNetwork = 0;
    private boolean active = false;

    String ntpServer = null;
    NTPUDPClient client;

    Thread st = null;

    void Init(String ntpServer) {
        startMillisLocal = System.currentTimeMillis();
        startNanosLocal = System.nanoTime();
        this.ntpServer = ntpServer;
        startNanoTimeLocal = TimeStamp.getCurrentTime(startMillisLocal, startNanosLocal).ntpValue();

        client = new NTPUDPClient(startMillisLocal, startNanosLocal);

        client.setDefaultTimeout(10000);
    }

    public long startTime = 0;
    private BufferedOutputStream logFile;

    void Start() {
        active = true;

        st = new Thread(new Runnable() {
            synchronized public void run() {
                while (true) {
                    try {
                        if (active)
                            Sync();
                        wait(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        st.start();

        try {
            logFile = new BufferedOutputStream(new FileOutputStream("/sdcard/sync.csv"), 65536 * 16);

            String s = "C;" + startMillisLocal + ";" + startNanosLocal + "\n";
            logFile.write(s.getBytes());
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    void Stop() {
        active = false;
        st.stop();
        if (logFile != null)
            try {
                logFile.flush();
                logFile.close();
                logFile = null;
            } catch (IOException e) {
                e.printStackTrace();
            }
    }

    long shortestDelay = Long.MAX_VALUE;
    public TimeInfo info;

    class NTPOffsets {
        public NTPOffsets(long delayValue, long offsetValue, long returnTime) {
            delay = delayValue;
            offset = offsetValue;
            returnT = returnTime;
        }

        long delay;
        long offset;
        long returnT;
    }

    NTPOffsets ntpoffsets[] = new NTPOffsets[NONTPO];

    public class Parameters {
        public long start;
        public long drift;
    }

    public static void fit(NTPOffsets ntpoffsets[], Parameters p) {
        double sx = 0.0, sy = 0.0, sxx = 0.0, sxy = 0.0;//, del;

        //s = x.length;
        for (int i = 0; i < NONTPO; i++) {
            if (ntpoffsets[i] != null) {
                sx += ntpoffsets[i].returnT;
                sy += ntpoffsets[i].offset;
                sxx += ntpoffsets[i].returnT * ntpoffsets[i].returnT;
                sxy += ntpoffsets[i].returnT * ntpoffsets[i].offset;
            }
        }

        //del = - sx*sx;

        // Intercept
        double s1 = sxy / sx;
        double s2 = -sxx * sy / (sx * sx);
        double start = s1 + s2;
        p.start = (long) start;
        // Slope
        double d1 = sy / sx;
        double drift = d1;
        p.drift = (long) drift;

        // Errors  (sd**2) on the:
        // intercept
        // = sxx/del;
        // and slope
        // = s/del;

    } // fit

    public Parameters p = null;
    long offsetValue = 0;
    long delayValue = 0;
    long returnTime = 0;

    void Sync() {
        try {
            InetAddress hostAddr = InetAddress.getByName(ntpServer);

            try {
                client.open();
            } catch (SocketException e1) {
                e1.printStackTrace();
            }

            info = client.getTime(hostAddr);
            info.computeDetails();

            String s = "S;" + info.getMessage().getOriginateTimeStamp().ntpValue() + ";"
                    + info.getMessage().getReceiveTimeStamp().ntpValue() + ";"
                    + info.getMessage().getTransmitTimeStamp().ntpValue() + ";" + info.getReturnTime() + "\n";
            logFile.write(s.getBytes());

            // Values in nanoseconds
            if (returnTime == 0) {
                offsetValue = info.getOffset();
            }
            //
            //offsetValue =info.getOffset();
            delayValue = info.getDelay();//TimeStamp.fromNtpToNanos(info.getDelay());
            returnTime = info.getReturnTime();//TimeStamp.fromNtpToNanos(info.getReturnTime())-startNanoTimeLocal;

            if (offsetValue == 0)
                return;

            if (delayValue < shortestDelay * 3) {
                //offsetValue = (offsetValue*9 + info.getOffset())/10;//TimeStamp.fromNtpToNanos(info.getOffset());
                offsetValue = info.getOffset();//(offsetValue*9 + info.getOffset())/10;//TimeStamp.fromNtpToNanos(info.getOffset());
                for (int i = 1; i < NONTPO; i++) {
                    ntpoffsets[i - 1] = ntpoffsets[i];
                }
                ntpoffsets[NONTPO - 1] = new NTPOffsets(delayValue, offsetValue, returnTime);
            }

            p = new Parameters();

            //fit(ntpoffsets,p);

        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    long nowNetworkTimeNanos() {
        // Get local time in nanoseconds
        long now_ntp_fractional = TimeStamp.getCurrentTime(startMillisLocal, startNanosLocal).ntpValue();

        if (p != null) // Correct the time from network 
        {
            now_ntp_fractional = (now_ntp_fractional - startNanoTimeLocal) * p.drift + p.start;
        }

        long now_seconds = now_ntp_fractional / 0x100000000L;
        long now_fraction = now_ntp_fractional & 0xFFFFFFFF;
        long now_nanos = now_fraction * 1000000000L / 0x100000000L;
        long now_time_nanos = now_seconds * 1000000000L + now_nanos;

        return now_time_nanos;
    }

}