coreSNTP v1.0.0
Client library for synchronizing device time with internet time using Simple Network Time Protocol (SNTP)
core_sntp_serializer.h File Reference

API for serializing SNTP request packets and, and de-serializing SNTP response packets. This API layer adheres to the SNTPv4 specification defined in RFC 4330. More...

#include <stdint.h>
#include <stddef.h>

Go to the source code of this file.

Data Structures

struct  SntpTimestamp_t
 Structure representing an SNTP timestamp. More...
 
struct  SntpResponseData_t
 Structure representing data parsed from an SNTP response from server as well as data of arithmetic calculations derived from the response. More...
 

Macros

#define SNTP_PACKET_BASE_SIZE   ( 48U )
 The base packet size of request and response of the (S)NTP protocol. More...
 
#define SNTP_FRACTION_VALUE_PER_MICROSECOND   ( 4295U )
 Number of SNTP timestamp fractions in 1 microsecond. More...
 
#define SNTP_TIME_AT_UNIX_EPOCH_SECS   ( 2208988800U )
 The seconds part of SNTP time at the UNIX epoch time, which represents an offset of 70 years (in seconds) between SNTP epoch and UNIX epoch time. SNTP uses 1st Jan 1900 UTC as the epoch time, whereas UNIX standard uses 1st Jan 1970 UTC as the epoch time, thereby, causing an offset of 70 years between them. More...
 
#define SNTP_TIME_AT_LARGEST_UNIX_TIME_SECS   ( 61505151U )
 The seconds value of SNTP timestamp for the largest UNIX time when using signed 32-bit integer for seconds. The largest time representable with a 32-bit signed integer in UNIX time is 19 Jan 2038 3h 14m 7s UTC. However, as the SNTP time overflows at 7 Feb 2036 6h 28m 16s UTC, therefore, the SNTP time for the largest UNIX time represents the time duration between the 2 timestamps. More...
 
#define UNIX_TIME_SECS_AT_SNTP_ERA_1_SMALLEST_TIME   ( 2085978496U )
 The UNIX time (in seconds) at the smallest SNTP time in era 1, i.e. UNIX time at 7 Feb 2036 6:28:16 UTC/. More...
 
#define SNTP_KISS_OF_DEATH_CODE_LENGTH   ( 4U )
 The fixed-length of any Kiss-o'-Death message ASCII code sent in an SNTP server response. More...
 
#define SNTP_KISS_OF_DEATH_CODE_NONE   ( 0U )
 The value for the SntpResponseData_t.rejectedResponseCode member when that the server response packet does not contain a Kiss-o'-Death message, and therefore, does not have a "kiss code". The server sends a "kiss-code" only when it rejects an SNTP request with a Kiss-o'-Death message.
 

Enumerations

enum  SntpStatus_t {
  SntpSuccess , SntpErrorBadParameter , SntpRejectedResponse , SntpRejectedResponseChangeServer ,
  SntpRejectedResponseRetryWithBackoff , SntpRejectedResponseOtherCode , SntpErrorBufferTooSmall , SntpInvalidResponse ,
  SntpZeroPollInterval , SntpErrorTimeNotSupported , SntpErrorDnsFailure , SntpErrorNetworkFailure ,
  SntpServerNotAuthenticated , SntpErrorAuthFailure , SntpErrorSendTimeout , SntpErrorResponseTimeout ,
  SntpNoResponseReceived , SntpErrorContextNotInitialized
}
 Enumeration of status codes that can be returned by the coreSNTP Library API. More...
 
enum  SntpLeapSecondInfo_t { NoLeapSecond = 0x00 , LastMinuteHas61Seconds = 0x01 , LastMinuteHas59Seconds = 0x02 , AlarmServerNotSynchronized = 0x03 }
 Enumeration for leap second information that an SNTP server can send its response to a time request. An SNTP server sends information about whether there is an upcoming leap second adjustment in the last day of the current month. More...
 

Functions

SntpStatus_t Sntp_SerializeRequest (SntpTimestamp_t *pRequestTime, uint32_t randomNumber, void *pBuffer, size_t bufferSize)
 Serializes an SNTP request packet to use for querying a time server. More...
 
SntpStatus_t Sntp_DeserializeResponse (const SntpTimestamp_t *pRequestTime, const SntpTimestamp_t *pResponseRxTime, const void *pResponseBuffer, size_t bufferSize, SntpResponseData_t *pParsedResponse)
 De-serializes an SNTP packet received from a server as a response to a SNTP request. More...
 
SntpStatus_t Sntp_CalculatePollInterval (uint16_t clockFreqTolerance, uint16_t desiredAccuracy, uint32_t *pPollInterval)
 Utility to calculate the poll interval of sending periodic time queries to servers to achieve a desired system clock accuracy for a given frequency tolerance of the system clock. More...
 
SntpStatus_t Sntp_ConvertToUnixTime (const SntpTimestamp_t *pSntpTime, uint32_t *pUnixTimeSecs, uint32_t *pUnixTimeMicrosecs)
 Utility to convert SNTP timestamp (that uses 1st Jan 1900 as the epoch) to UNIX timestamp (that uses 1st Jan 1970 as the epoch). More...
 

Detailed Description

API for serializing SNTP request packets and, and de-serializing SNTP response packets. This API layer adheres to the SNTPv4 specification defined in RFC 4330.

Function Documentation

◆ Sntp_SerializeRequest()

SntpStatus_t Sntp_SerializeRequest ( SntpTimestamp_t pRequestTime,
uint32_t  randomNumber,
void *  pBuffer,
size_t  bufferSize 
)

Serializes an SNTP request packet to use for querying a time server.

This function will fill only SNTP_PACKET_BASE_SIZE bytes of data in the passed buffer.

Parameters
[in,out]pRequestTimeThe current time of the system, expressed as time since the SNTP epoch (i.e. 0h of 1st Jan 1900 ). This time will be serialized in the SNTP request packet. The function will use this parameter to return the timestamp serialized in the SNTP request. To protect against attacks spoofing server responses, the timestamp MUST NOT be zero in value.
[in]randomNumberA random number (generated by a True Random Generator) for use in the SNTP request packet to protect against replay attacks as suggested by SNTPv4 specification. For more information, refer to RFC 4330 Section 3.
[out]pBufferThe buffer that will be populated with the serialized SNTP request packet.
[in]bufferSizeThe size of the pBuffer buffer. It should be at least SNTP_PACKET_BASE_SIZE bytes in size.
Note
It is recommended to use a True Random Generator (TRNG) to generate the random number.
The application MUST save the pRequestTime value for de-serializing the server response with Sntp_DeserializeResponse API.
Returns
This function returns one of the following:

◆ Sntp_DeserializeResponse()

SntpStatus_t Sntp_DeserializeResponse ( const SntpTimestamp_t pRequestTime,
const SntpTimestamp_t pResponseRxTime,
const void *  pResponseBuffer,
size_t  bufferSize,
SntpResponseData_t pParsedResponse 
)

De-serializes an SNTP packet received from a server as a response to a SNTP request.

This function will parse only the SNTP_PACKET_BASE_SIZE bytes of data in the passed buffer.

Note
If the server has sent a Kiss-o'-Death message to reject the associated time request, the API function will return the appropriate return code and, also, provide the ASCII code (of fixed length, SNTP_KISS_OF_DEATH_CODE_LENGTH bytes) in the SntpResponseData_t.rejectedResponseCode member of pParsedResponse parameter, parsed from the response packet. The application SHOULD respect the server rejection and take appropriate action based on the rejection code. If the server response represents an accepted SNTP client request, then the API function will set the SntpResponseData_t.rejectedResponseCode member of pParsedResponse parameter to SNTP_KISS_OF_DEATH_CODE_NONE.
If the server has positively responded with its clock time, then this API function will calculate the clock-offset. For the clock-offset to be correctly calculated, the system clock MUST be within ~68 years (or 2^31 seconds) of the server time mentioned. This function supports clock-offset calculation when server and client timestamps are in adjacent NTP eras, with one system is in NTP era 0 (i.e. before 7 Feb 2036 6h:28m:14s UTC) and another system in NTP era 1 (on or after 7 Feb 2036 6h:28m:14s UTC).
In the special case when the server and client times are exactly 2^31 seconds apart, the library ASSUMES that the server time is ahead of the client time, and returns the positive clock-offset value of INT32_MAX seconds.
Parameters
[in]pRequestTimeThe system time used in the SNTP request packet that is associated with the server response. This MUST be the same as the time returned by the Sntp_SerializeRequest API. To protect against attacks spoofing server responses, this timestamp MUST NOT be zero in value.
[in]pResponseRxTimeThe time of the system, expressed as time since the SNTP epoch (i.e. 0h of 1st Jan 1900 ), at receiving SNTP response from server. This time will be used to calculate system clock offset relative to server.
[in]pResponseBufferThe buffer containing the SNTP response from the server.
[in]bufferSizeThe size of the pResponseBuffer containing the SNTP response. It MUST be at least SNTP_PACKET_BASE_SIZE bytes long for a valid SNTP response.
[out]pParsedResponseThe information parsed from the SNTP response packet. If possible to calculate without overflow, it also contains the system clock offset relative to the server time.
Returns
This function returns one of the following:

◆ Sntp_CalculatePollInterval()

SntpStatus_t Sntp_CalculatePollInterval ( uint16_t  clockFreqTolerance,
uint16_t  desiredAccuracy,
uint32_t *  pPollInterval 
)

Utility to calculate the poll interval of sending periodic time queries to servers to achieve a desired system clock accuracy for a given frequency tolerance of the system clock.

For example, from the SNTPv4 specification, "if the frequency tolerance is 200 parts per million (PPM) and the required accuracy is one minute, the maximum timeout is about 3.5 days". In this example, the system clock frequency tolerance is 200 PPM and the desired accuracy is 60000 milliseconds (or 1 minute) for which this API function will return the maximum poll interval value as 2^18 seconds (or ~3 days).

Note
The poll interval returned is a power of 2, which is the standard way to represent the value. According to the SNTPv4 specification Best Practices, an SNTP client SHOULD NOT have a poll interval less than 15 seconds. https://tools.ietf.org/html/rfc4330#section-10. This API function DOES NOT support poll interval calculation less than 1 second.
Parameters
[in]clockFreqToleranceThe frequency tolerance of system clock in parts per million (PPM) units. This parameter MUST be non-zero.
[in]desiredAccuracyThe acceptable maximum drift, in milliseconds, for the system clock. The maximum value (0xFFFF) represents ~1 minute of desired clock accuracy. This parameter MUST be non-zero.
[out]pPollIntervalThis is filled with the poll interval, in seconds calculated as the closest power of 2 value that will achieve either the exact desired or higher clock accuracy desiredAccuracy, for the given clock frequency tolerance, clockFreqTolerance.
Returns
Returns one of the following:

◆ Sntp_ConvertToUnixTime()

SntpStatus_t Sntp_ConvertToUnixTime ( const SntpTimestamp_t pSntpTime,
uint32_t *  pUnixTimeSecs,
uint32_t *  pUnixTimeMicrosecs 
)

Utility to convert SNTP timestamp (that uses 1st Jan 1900 as the epoch) to UNIX timestamp (that uses 1st Jan 1970 as the epoch).

Note
This function can ONLY handle conversions of SNTP timestamps that lie in the range from 1st Jan 1970 0h 0m 0s, the UNIX epoch time, to 19th Jan 2038 3h 14m 7s, the maximum UNIX time that can be represented in a signed 32 bit integer. (The limitation is to support systems that use signed 32-bit integer to represent the seconds part of the UNIX time.)
This function supports overflow of the SNTP timestamp (from the 7 Feb 2036 6h 28m 16s time, i.e. SNTP era 1) by treating the timestamps with seconds part in the range [0, 61,505,152] seconds where the upper limit represents the UNIX overflow time (i.e. 19 Jan 2038 3h 14m 7s) for systems that use signed 32-bit integer to represent time.
Parameters
[in]pSntpTimeThe SNTP timestamp to convert to UNIX time.
[out]pUnixTimeSecsThis will be filled with the seconds part of the UNIX time equivalent of the SNTP time, pSntpTime.
[out]pUnixTimeMicrosecsThis will be filled with the microseconds part of the UNIX time equivalent of the SNTP time, pSntpTime.
Returns
Returns one of the following: