Network Time Protocol

From Nutwiki
Revision as of 17:02, 27 October 2016 by Harald (Talk | contribs) (1 revision imported)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Description

This example demonstrates how to retrieve the current time from an NTP server.

Source Code

<source lang="c">

  1. include <dev/board.h>
  2. include <dev/debug.h>
  1. include <sys/timer.h>
  1. include <arpa/inet.h>
  2. include <net/route.h>
  3. include <pro/dhcp.h>
  4. include <pro/sntp.h>
  1. include <stdlib.h>
  2. include <stdio.h>
  3. include <io.h>
  4. include <string.h>
  5. include <time.h>

int main(void) {

   unsigned long baud = 115200;
   time_t ntp_time = 0;
   tm *ntp_datetime;
   uint32_t timeserver = 0;
   NutRegisterDevice(&DEV_DEBUG, 0, 0);
   freopen(DEV_DEBUG_NAME, "w", stdout);
   _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
   NutRegisterDevice(&DEV_ETHER, 0, 0);
   if (NutDhcpIfConfig(DEV_ETHER_NAME, 0, 60000)) {
       puts("Error: Cannot configure network.");
   }
   puts("NTP example\n");
   /* Timezone for Germany is GMT-1, so we need to subtract 1 hour = 60*60 seconds */
   _timezone = -1 * 60 * 60;
   /* Retrieve time from the "pool.ntp.org" server. This is a free NTP server. */
   puts("Retrieving time from pool.ntp.org...");
   timeserver = inet_addr("213.203.238.86");
   for (;;) {
       if (NutSNTPGetTime(&timeserver, &ntp_time) == 0) {
           break;
       } else {
           NutSleep(1000);
           puts("Failed to retrieve time. Retrying...");
       }
   }
   puts("Done.\n");
   ntp_datetime = localtime(&ntp_time);
   printf("NTP time is: %02d:%02d:%02d\n", ntp_datetime->tm_hour, ntp_datetime->tm_min, ntp_datetime->tm_sec);
   for (;;);

} </source>

Details

<source lang="c"> time_t ntp_time = 0; tm *ntp_datetime; uint32_t timeserver = 0;

NutRegisterDevice(&DEV_DEBUG, 0, 0);

freopen(DEV_DEBUG_NAME, "w", stdout); _ioctl(_fileno(stdout), UART_SETSPEED, &baud);

NutRegisterDevice(&DEV_ETHER, 0, 0); if (NutDhcpIfConfig(DEV_ETHER_NAME, 0, 60000)) {

   puts("Error: Cannot configure network.");

}

puts("NTP example\n"); </source>

First we need to set up the debug device to output to the terminal and configure the network. We also declare 2 time variables (one for epoch time and one struct to hold detailed human-readable information about the time we retrieve).

<source lang="c"> /* Timezone for Germany is GMT-1, so we need to subtract 1 hour = 60*60 seconds */ _timezone = -1 * 60 * 60; </source>

The global variable _timezone allows us to set the timezone we're currently in. This is pretty cool since we don't need to bother with adjusting the time to our timezone after setting this. Central Europe has the UTC timezone -1, if you live in a different area in the world you might want to adjust this to meet your timezone.

<source lang="c"> /* Retrieve time from the "pool.ntp.org" server. This is a free NTP server. */ puts("Retrieving time from pool.ntp.org...");

timeserver = inet_addr("213.203.238.86"); </source>

Since the time retrieval will take a moment, we output a message to show we're about to get the time and fill our timeserver variable with the IP address of the timeserver. If this server does not work for you, ping pool.ntp.org to retrieve a working IP for your location. The one provided should work though.

<source lang="c"> for (;;) {

   if (NutSNTPGetTime(&timeserver, &ntp_time) == 0) {
       break;
   } else {
       NutSleep(1000);
       puts("Failed to retrieve time. Retrying...");
   }

} puts("Done.\n"); </source>

This endless loop repeats until we get a time from the timeserver. In a real application you'd have some more error checking but we'll just assume our server is reachable for the sake of simplicity.

The NutSNTPGetTime call takes two arguments: The IP address of the server we want to get the time from and the variable we want to store the time into. The stored time will be in Epoch format, meaning: Seconds passed since January 1, 1970. That's not easily readable so we'll convert it into a datetime format in a moment.

In case the NutSNTPGetTime call returns something different than 0 we didn't get a time from the server. Wait a second, notify the user and then try again.

<source lang="c"> ntp_datetime = localtime(&ntp_time);

printf("NTP time is: %02d:%02d:%02d\n", ntp_datetime->tm_hour, ntp_datetime->tm_min, ntp_datetime->tm_sec); </source> Now we convert the time into a datetime format using the localtime function. This saves us the hassle of manually calculating date and time from the number we recieved. We then output the current time to the terminal.

Output

<source lang="text"> NTP example

Retrieving time from pool.ntp.org... Done.

NTP time is: 16:11:17 </source>

See also