I am wanting to build a private LAN which needs all devices and controllers on the LAN to have a syncronised timestamp - the LAN does not have access to the Internet. All devices and controllers I am using are configurable, but not all programmable, and allow one to reference an NTP server to get a syncronised timestamp.
An Arduino with Ethernet shield is going to be the master controller / web server and I wish to also make this a virtual NTP web-server so that all I need to do is reference the Arduino IP address (e.g. 192.168.1.##) on the external client devices, which allows one to enter the NTP IP reference. The objective is to use a RTC with Arduino and then create a relative timestamp as the core objective is for all devices to be synchronised rather than knowing what time of day it is. The complex part is that the only way I can do this is through NTP server protocol.
I am now looking for some guidance on how to do this. The UdpNtpClient give clues, but I am having to do everything in reverse. How would one go about this.
For example: UdpNtpClient says -- NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message. What format must this message be in so that other devices will recognise this format and process it correctly.
The URL reference Network Time Protocol - Wikipedia makes reference to Simple Network Time Protocol (SNTP) and says that the timestamp is 64-bits, consisting of consist of a 32-bit part for seconds and a 32-bit part for fractional seconds. The UdpNtpClient sendNTPpacket routine then initialises all NTP fields with given values and then sends a packet requesting a timestamp. Will I expect the same formats from all other devices.
For example one idea is to use two Arduino's for testing -- one using the UdpNtpClient and another being the virtual time server to see how to respond back. The aim is to communicate NTP requests via port 123.
Maybe someone has done this already. Otherwise looking for advice on how to tackle programming challenge as documentation about standard is a difficult read.
Thanks for the quick response. Yes the idea is to write a simple NTP server so that other devices on the LAN can get a timestamp using a NTP poll request.
Thanks for link to github's ntp-arduino. Using a GPS shield attached to an Arduino Ethernet shield would certainly be a nice enhancement to just using an RTC. I had a look at the code and couldn't quite see how the NTP fits in, unless all that is required is to have a header such as the reference made in "main.cpp" -- i.e. "Jystic NTP Server v0.1"; together with a response to client NTP time request of time in millis.
I'm now looking at RFC 5905 for reference (Network Time Protocol Version 4). So to be compatible with this standard the Arduino webserver will be regarded as the "primary server" which is synchronized to the reference clock (in my case RTC or future case GPS). There are three NTP protocol variants: symmetric, client/server and broadcast. Not sure what this means. My hope is that most clients will always "pull" synchronized time from the Arduino web server but if one is expected to "broadcast" time across the LAN then this might get tricky. Document makes clear "All NTP time values are represented in twos-complement format,with
bits numbered in big-endian fashion from zero starting at the left, or high-order, position." It notes 3 time formats however: 128-bit dateformat, 64-bit
timestamp format and a 32-bit short format. Hence there must be a parameter that defines what the client wants. LOOKING AT UdPNtpClient: IS THIS packetBuffer[0] = 0b11100011; // LI, Version, Mode. There are other settings used, not sure what these are.
RFC 5905 also says the NTP packet is a UDP datagram and that the packet header has 12words followed by optional extension fields and an optional message authentication code consisting of the Key Identifier field and Message Digest field. I also see that this document includes 40 odd pages of code skeleton. Has anyone converted this into a useful library... nothing found on the net as yet.
Oops, sorry, I see that was a red herring. No other easy pickings in plain sight after a bit more searching, either.
Faced with this problem, I'd start looking for C reference implementations of the NTP protocol and see how much you can slim down a fibbing timeserver.
Here, for example, is a client implementation in C; maybe you can deduce what to feed it to make it happy: ntpclient
You know, on further reflection, if the software part of that approach turns out to be too costly, it's really easy to set up a little off-the-shelf linux box with a GPS as a real ntp time source. If you have any PC workstations or servers on your LAN already, you could host a server there without even adding a box.
This will be much easier if you use SNTP. I haven't looked at any NTP protocol libraries for Arduino, but if you find one I'd expect to find that it includes all the protocol handling you need to be an SNTP or NTP client or server, since the protocol is essentially symmetrical. All you need to do is provide a local clock source which is reasonably consistent, and respond to NTP requests.
Thanks for the tip about using SNTP rather than NTP. This really helped. I've now found a useful link that helped me understand the difference: Wrytestuff Benefit Support Portal
As this article notes "The SNTP protocol is best suited to synchronizing computers at the extremities". This is what I'm after... I'm trying to find the simplest cleanest way forward as the "true" time is not all that important at the moment.
Did a quick search online and found this C source code reference: sntp.c - sanos source
Will trawl through and see what this is like.
Otherwise, the same site (first link) also includes a write-up on how to build an NTP server Wrytestuff Benefit Support Portal. for those who wish to use GPS and Linux box.