Wish SPSntp-Library

Filippo

Expert
Licensed User
Hi,

a chance to import the library SPSntp?
 

Filippo

Expert
Licensed User
I can not do it, but I think it can not be that hard to implement this feature.
B4X:
Dim sntp As SntpTime
Dim ticks As Long
sntp.NtpServerName = "0.de.pool.ntp.org"  ' only needed if you don't want to use the default server "0.us.pool.ntp.org"
sntp.TimeOut = 10000 ' only needed if you don't want to use the default timeout value of 30000 milliseconds (30 seconds)
ticks = sntp.getGmtNtpTime
 

Filippo

Expert
Licensed User
Hi,

I'm trying with this Code, the time from a time server to pick up, but it does not work, I can not connect.
What am I doing wrong?

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public App As Application
    Public NavControl As NavigationController
    Private Page1 As Page

    Private HD As HUD
    Private lblClock As Label
   
    Dim AStreams As AsyncStreams
    Dim Socket1 As Socket
End Sub

Private Sub Application_Start (Nav As NavigationController)
    NavControl = Nav
    Page1.Initialize("Page1")
    Page1.Title = "Page 1"
    Page1.RootPanel.Color = Colors.White
    Page1.RootPanel.LoadLayout("1")
    NavControl.ShowPage(Page1)
   
    Socket1.Initialize("Socket1")
    Socket1.Connect("0.us.pool.ntp.org", 123, 10000)
End Sub

Private Sub Page1_Resize(Width As Int, Height As Int)
   
End Sub

Private Sub Application_Background
   
End Sub

Sub Socket1_Connected (Successful As Boolean)
    Log("Successful=" & Successful)
    If Successful Then
        AStreams.InitializePrefix(Socket1.InputStream, False, Socket1.OutputStream, "AStreams")
    End If
End Sub

Sub AStreams_NewData (Buffer() As Byte)
    Dim msg As String
    msg = BytesToString(Buffer, 0, Buffer.Length, "UTF8")
    HD.ToastMessageShow(msg, False)
    Log(msg)
End Sub
 

Filippo

Expert
Licensed User
Hi all,
I am now getting a bit further, but I get the time from the time server without hundredths of a second.
Has someone like you get the hundredths of a second?

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
  Public App As Application
   Public NavControl As NavigationController
   Private Page1 As Page

   Private HD As HUD
   Private lblClock As Label
   
   Dim AStreams As AsyncStreams
   Dim Socket1 As Socket
   Private TextView1 As TextView
   Private timer1 As Timer
   Private lngTimer As Long
End Sub

Private Sub Application_Start (Nav As NavigationController)
    NavControl = Nav
    Page1.Initialize("Page1")
    Page1.Title = "Page 1"
    Page1.RootPanel.Color = Colors.White
    Page1.RootPanel.LoadLayout("1")
    NavControl.ShowPage(Page1)

   timer1.Initialize("timer1", 20)
   timer1.Enabled = True
  
  '"xxxxx yy-mm-dd hh:mm:ss xx x x  xx.x UTC(NIST) *"
    DateTime.DateFormat = "yy-MM-dd"
    DateTime.TimeFormat = "hh:mm:ss"
    Socket1.Initialize("Socket1")
    Socket1.Connect("0.us.pool.ntp.org", 13, 10000)
End Sub

Private Sub Page1_Resize(Width As Int, Height As Int)
  
End Sub

Private Sub Application_Background
  
End Sub

Sub Socket1_Connected (Successful As Boolean)
  Log("Successful=" & Successful)
  If Successful Then
     AStreams.Initialize(Socket1.InputStream, Socket1.OutputStream, "AStreams")
   Else
     Socket1.Close
   End If
End Sub

Sub AStreams_NewData (Buffer() As Byte)
  Dim msg As String
  msg = BytesToString(Buffer, 0, Buffer.Length, "UTF8")
'  HD.ToastMessageShow(msg, False)
   TextView1.Text = TextView1.Text & msg & CRLF
   Dim str() As String
   str = Regex.Split(" ",msg)
   Dim ticks As Long = DateTime.DateTimeParse(str(1), str(2))
   lngTimer = DateTime.Now - (DateTime.TimeZoneOffset * DateTime.TicksPerHour) - ticks
  Log(msg)
   Log("ticks  =" & ticks)
   Log("DateTime.Now=" & DateTime.Now)
   Log("lngTimer  =" & lngTimer)
  Socket1.Close
End Sub
   
Sub AStreams_Error
'  HD.ToastMessageShow(LastException.Description, True)
  Log(LastException.Description)
End Sub

Sub timer1_Tick
   lblClock.Text = DateTime.time(DateTime.Now - lngTimer)
End Sub
 

Filippo

Expert
Licensed User

Filippo

Expert
Licensed User
Hi,

I now extraiert from the Library SPSntp the Java file.
Is it possible from this Java file an iOS-Classe create?

B4X:
package anywheresoftware.b4a.specci48.spsntp;

import android.os.SystemClock;
import android.util.Log;
import anywheresoftware.b4a.BA;
import anywheresoftware.b4a.BA.ActivityObject;
import anywheresoftware.b4a.BA.ShortName;
import anywheresoftware.b4a.BA.Version;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

@BA.ActivityObject
@BA.ShortName("SPSntp")
@BA.Version(1.03F)
public class SPSntp
{
  private static String mNtpServerName = "0.us.pool.ntp.org";

  private static int mTimeOut = 30000;
  private static long mNtpTime;
  private static long mNtpTimeReference;
  private static long mRoundTripTime;

  private static class SntpClient
  {
    private static final String TAG = "SntpClient";
    private static final int ORIGINATE_TIME_OFFSET = 24;
    private static final int RECEIVE_TIME_OFFSET = 32;
    private static final int TRANSMIT_TIME_OFFSET = 40;
    private static final int NTP_PACKET_SIZE = 48;
    private static final int NTP_PORT = 123;
    private static final int NTP_MODE_CLIENT = 3;
    private static final int NTP_VERSION = 3;
    private static final long OFFSET_1900_TO_1970 = 2208988800L;

    public boolean requestTime(String host, int timeout)
    {
      try
      {
        DatagramSocket socket = new DatagramSocket();
        socket.setSoTimeout(timeout);
        InetAddress address = InetAddress.getByName(host);
        byte[] buffer = new byte[48];
        DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, 123);

        buffer[0] = 27;

        long requestTime = System.currentTimeMillis();
        long requestTicks = SystemClock.elapsedRealtime();
        writeTimeStamp(buffer, 40, requestTime);

        socket.send(request);

        DatagramPacket response = new DatagramPacket(buffer, buffer.length);
        socket.receive(response);
        long responseTicks = SystemClock.elapsedRealtime();
        long responseTime = requestTime + responseTicks - requestTicks;
        socket.close();

        long originateTime = readTimeStamp(buffer, 24);
        long receiveTime = readTimeStamp(buffer, 32);
        long transmitTime = readTimeStamp(buffer, 40);
        long roundTripTime = responseTicks - requestTicks - (transmitTime - receiveTime);

        long clockOffset = (receiveTime - originateTime + transmitTime - responseTime) / 2L;

        SPSntp.mNtpTime = responseTime + clockOffset;
        SPSntp.mNtpTimeReference = responseTicks;
        SPSntp.mRoundTripTime = roundTripTime;
      }
      catch (Exception e) {
        Log.d("SntpClient", "request time failed: " + e);

        return false;
      }

      return true;
    }

    private long read32(byte[] buffer, int offset)
    {
      byte b0 = buffer[offset];
      byte b1 = buffer[(offset + 1)];
      byte b2 = buffer[(offset + 2)];
      byte b3 = buffer[(offset + 3)];

      int i0 = (b0 & 0x80) == 128 ? (b0 & 0x7F) + 128 : b0;
      int i1 = (b1 & 0x80) == 128 ? (b1 & 0x7F) + 128 : b1;
      int i2 = (b2 & 0x80) == 128 ? (b2 & 0x7F) + 128 : b2;
      int i3 = (b3 & 0x80) == 128 ? (b3 & 0x7F) + 128 : b3;

      return (i0 << 24) + (i1 << 16) + (i2 << 8) + i3;
    }

    public long readTimeStamp(byte[] buffer, int offset)
    {
      long seconds = read32(buffer, offset);
      long fraction = read32(buffer, offset + 4);
      return (seconds - 2208988800L) * 1000L + fraction * 1000L / 4294967296L;
    }

    private void writeTimeStamp(byte[] buffer, int offset, long time)
    {
      long seconds = time / 1000L;
      long milliseconds = time - seconds * 1000L;
      seconds += 2208988800L;

      buffer[(offset++)] = (byte)(int)(seconds >> 24);
      buffer[(offset++)] = (byte)(int)(seconds >> 16);
      buffer[(offset++)] = (byte)(int)(seconds >> 8);
      buffer[(offset++)] = (byte)(int)(seconds >> 0);

      long fraction = milliseconds * 4294967296L / 1000L;

      buffer[(offset++)] = (byte)(int)(fraction >> 24);
      buffer[(offset++)] = (byte)(int)(fraction >> 16);
      buffer[(offset++)] = (byte)(int)(fraction >> 8);

      buffer[(offset++)] = (byte)(int)(Math.random() * 255.0D);
    }
  }

  @BA.ActivityObject
  @BA.ShortName("SntpTime")
  public static class SntpTime
  {
    public long getGmtNtpTime(BA ba)
    {
      SPSntp.SntpClient client = new SPSntp.SntpClient(null);

      SPSntp.mNtpTime = Long.valueOf(-1L).longValue();
      SPSntp.mNtpTimeReference = Long.valueOf(-1L).longValue();
      SPSntp.mRoundTripTime = Long.valueOf(-1L).longValue();
      try {
        client.requestTime(SPSntp.mNtpServerName, SPSntp.mTimeOut);
      }
      catch (Exception localException)
      {
      }

      return SPSntp.mNtpTime;
    }

    public long getNtpTimeReference()
    {
      return SPSntp.mNtpTimeReference;
    }

    public long getRoundTripTime()
    {
      return SPSntp.mRoundTripTime;
    }

    public void setNtpServerName(String ntpServerName)
    {
      SPSntp.mNtpServerName = ntpServerName;
    }

    public void setTimeOut(int timeOut)
    {
      SPSntp.mTimeOut = timeOut;
    }
  }
}
 
Top