Home→Forums→MonoBrick EV3 Firmware→Updating date and time with ntp?
- This topic has 2 replies, 2 voices, and was last updated 9 years, 7 months ago by Anders Søborg.
Viewing 3 posts - 1 through 3 (of 3 total)
-
AuthorPosts
-
March 21, 2015 at 21:24 #5329
Kristofer JaxneParticipantI wonder if its possible somehow to update the internal time with correct UTC using some ntp server? I can’t find any services in the Linux software so I don’t know how to solve it. I have seen examples for how to let a C# program do the job, but its little to complex when Linux should have support for automatic update. Have anyone get it working?
March 22, 2015 at 16:36 #5333
Kristofer JaxneParticipantI found solutions to this problem so I can show how I did.
First I create a new class with the needed methods.
using System; using MonoBrickFirmware; using System.Threading; using System.Diagnostics; using System.Net; using System.Net.Sockets; using MonoBrickFirmware.Display; public class Linux { public Linux () { } public void SendCommand (string file, string arguments) { Process proc = new Process (); proc.StartInfo.FileName = file; proc.StartInfo.Arguments = arguments; proc.StartInfo.UseShellExecute = false; proc.StartInfo.RedirectStandardError = true; proc.StartInfo.RedirectStandardInput = true; proc.StartInfo.RedirectStandardOutput = true; proc.Start(); var output = proc.StandardOutput.ReadToEnd (); LcdConsole.WriteLine("stdout: {0}", output); } public DateTime GetNetworkTime() { try { //default Windows time server const string ntpServer = "time.windows.com"; // NTP message size - 16 bytes of the digest (RFC 2030) var ntpData = new byte[48]; //Setting the Leap Indicator, Version Number and Mode values ntpData[0] = 0x1B; //LI = 0 (no warning), VN = 3 (IPv4 only), Mode = 3 (Client Mode) var addresses = Dns.GetHostEntry(ntpServer).AddressList; //The UDP port number assigned to NTP is 123 var ipEndPoint = new IPEndPoint(addresses[0], 123); //NTP uses UDP var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); socket.Connect(ipEndPoint); //Stops code hang if NTP is blocked socket.ReceiveTimeout = 3000; socket.Send(ntpData); socket.Receive(ntpData); socket.Close(); //Offset to get to the "Transmit Timestamp" field (time at which the reply //departed the server for the client, in 64-bit timestamp format." const byte serverReplyTime = 40; //Get the seconds part ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime); //Get the seconds fraction ulong fractPart = BitConverter.ToUInt32(ntpData, serverReplyTime + 4); //Convert From big-endian to little-endian intPart = SwapEndianness(intPart); fractPart = SwapEndianness(fractPart); var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L); //**UTC** time var networkDateTime = (new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddMilliseconds((long)milliseconds); networkDateTime = networkDateTime.AddHours(2); // Local time Sweden summer time = UTC + 2 return networkDateTime.ToLocalTime(); } catch { DateTime time = new DateTime (1900, 01, 01); return time; } } private static uint SwapEndianness(ulong x) { return (uint) (((x & 0x000000ff) << 24) + ((x & 0x0000ff00) << 8) + ((x & 0x00ff0000) >> 8) + ((x & 0xff000000) >> 24)); } }
I use the methods in the class like this:
Linux linux = new Linux (); DateTime servertime = new DateTime(); for (int i = 0; i < 5; i++) { servertime = linux.GetNetworkTime (); Thread.Sleep (500); if (servertime.Year != 1900) break; } if (servertime.Year == 1900) LcdConsole.WriteLine ("Failed to get time"); else LcdConsole.WriteLine (servertime.ToString ("yyyy-MM-dd HH:mm:ss")); linux.SendCommand ("date", "\"" + servertime.ToString ("yyyy-MM-dd HH:mm:ss") + "\""); linux.SendCommand ("hwclock", "-w -l");
March 24, 2015 at 21:19 #5335
Anders SøborgKeymasterHi there
Nice job. Thanks a lot for sharing. I guess that a lot of other people will benefit from this.
/Anders
-
AuthorPosts
Viewing 3 posts - 1 through 3 (of 3 total)
You must be logged in to reply to this topic.
Follow