Implementation of the Serializer API of the coreSNTP library. More...
#include <string.h>
#include <stdbool.h>
#include <assert.h>
#include "core_sntp_serializer.h"
#include "core_sntp_config_defaults.h"
Data Structures | |
struct | SntpPacket_t |
Structure representing an SNTP packet header. For more information on SNTP packet format, refer to RFC 4330 Section 4. More... | |
Macros | |
#define | SNTP_VERSION ( 4U ) |
The version of SNTP supported by the coreSNTP library by complying with the SNTPv4 specification defined in RFC 4330. | |
#define | SNTP_MODE_BITS_MASK ( 0x07U ) |
The bit mask for the "Mode" information in the first byte of an SNTP packet. The "Mode" field occupies bits 0-2 of the byte. | |
#define | SNTP_MODE_CLIENT ( 3U ) |
The value indicating a "client" in the "Mode" field of an SNTP packet. | |
#define | SNTP_MODE_SERVER ( 4U ) |
The value indicating a "server" in the "Mode" field of an SNTP packet. | |
#define | SNTP_LEAP_INDICATOR_LSB_POSITION ( 6 ) |
The position of the least significant bit of the "Leap Indicator" field in first byte of an SNTP packet. The "Leap Indicator" field occupies bits 6-7 of the byte. | |
#define | SNTP_KISS_OF_DEATH_STRATUM ( 0U ) |
Value of Stratum field in SNTP packet representing a Kiss-o'-Death message from server. | |
#define | SNTP_VERSION_LSB_POSITION ( 3 ) |
The position of least significant bit of the "Version" information in the first byte of an SNTP packet. "Version" field occupies bits 3-5 of the byte. | |
#define | KOD_CODE_DENY_UINT_VALUE ( 0x44454e59U ) |
The integer value of the Kiss-o'-Death ASCII code, "DENY", used for comparison with data in an SNTP response. | |
#define | KOD_CODE_RSTR_UINT_VALUE ( 0x52535452U ) |
The integer value of the Kiss-o'-Death ASCII code, "RSTR", used for comparison with data in an SNTP response. | |
#define | KOD_CODE_RATE_UINT_VALUE ( 0x52415445U ) |
The integer value of the Kiss-o'-Death ASCII code, "RATE", used for comparison with data in an SNTP response. | |
#define | CLOCK_OFFSET_MAX_TIME_DIFFERENCE ( ( ( ( int64_t ) INT32_MAX + 1 ) * 1000 ) ) |
Macro to represent exactly half of the total number of seconds in an NTP era. As 32 bits are used to represent the "seconds" part of an SNTP timestamp, the half of the total range of seconds in an NTP era is 2^31 seconds, which represents ~68 years. | |
#define | TOTAL_MILLISECONDS_IN_NTP_ERA ( ( ( int64_t ) UINT32_MAX + 1 ) * 1000 ) |
Macro to represent the total number of milliseconds that are represented in an NTP era period. This macro represents a duration of ~136 years. | |
Functions | |
static void | fillWordMemoryInNetworkOrder (uint32_t *pWordMemory, uint32_t data) |
Utility macro to fill 32-bit integer in word-sized memory in network byte (or Big Endian) order. | |
static uint32_t | readWordFromNetworkByteOrderMemory (const uint32_t *ptr) |
Utility macro to generate a 32-bit integer from memory containing integer in network (or Big Endian) byte order. | |
static int64_t | absoluteOf (int64_t value) |
Utility to return absolute (or positively signed) value of an signed 64 bit integer. | |
static bool | isZeroTimestamp (const SntpTimestamp_t *pTime) |
Utility to determine whether a timestamp represents a zero timestamp value. | |
static uint32_t | fractionsToMs (uint32_t fractions) |
Utility to convert the "fractions" part of an SNTP timestamp to milliseconds duration of time. | |
static int64_t | safeTimeDifference (const SntpTimestamp_t *pServerTime, const SntpTimestamp_t *pClientTime) |
Utility to safely calculate difference between server and client timestamps and return the difference in the resolution of milliseconds as a signed 64 bit integer. The calculated value represents the effective subtraction as ( serverTimeSec - clientTimeSec ). | |
static void | calculateClockOffset (const SntpTimestamp_t *pClientTxTime, const SntpTimestamp_t *pServerRxTime, const SntpTimestamp_t *pServerTxTime, const SntpTimestamp_t *pClientRxTime, int64_t *pClockOffset) |
Utility to calculate clock offset of system relative to the server using the on-wire protocol specified in the NTPv4 specification. For more information on on-wire protocol, refer to RFC 5905 Section 8. | |
static SntpStatus_t | parseValidSntpResponse (const SntpPacket_t *pResponsePacket, const SntpTimestamp_t *pRequestTxTime, const SntpTimestamp_t *pResponseRxTime, SntpResponseData_t *pParsedResponse) |
Parse a SNTP response packet by determining whether it is a rejected or accepted response to an SNTP request, and accordingly, populate the pParsedResponse parameter with the parsed data. | |
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. | |
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. | |
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. | |
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). | |
Implementation of the Serializer API of the coreSNTP library.
#define SNTP_MODE_BITS_MASK ( 0x07U ) |
The bit mask for the "Mode" information in the first byte of an SNTP packet. The "Mode" field occupies bits 0-2 of the byte.
#define SNTP_MODE_CLIENT ( 3U ) |
The value indicating a "client" in the "Mode" field of an SNTP packet.
#define SNTP_MODE_SERVER ( 4U ) |
The value indicating a "server" in the "Mode" field of an SNTP packet.
#define SNTP_LEAP_INDICATOR_LSB_POSITION ( 6 ) |
The position of the least significant bit of the "Leap Indicator" field in first byte of an SNTP packet. The "Leap Indicator" field occupies bits 6-7 of the byte.
#define SNTP_VERSION_LSB_POSITION ( 3 ) |
The position of least significant bit of the "Version" information in the first byte of an SNTP packet. "Version" field occupies bits 3-5 of the byte.
#define KOD_CODE_DENY_UINT_VALUE ( 0x44454e59U ) |
The integer value of the Kiss-o'-Death ASCII code, "DENY", used for comparison with data in an SNTP response.
#define KOD_CODE_RSTR_UINT_VALUE ( 0x52535452U ) |
The integer value of the Kiss-o'-Death ASCII code, "RSTR", used for comparison with data in an SNTP response.
#define KOD_CODE_RATE_UINT_VALUE ( 0x52415445U ) |
The integer value of the Kiss-o'-Death ASCII code, "RATE", used for comparison with data in an SNTP response.
#define CLOCK_OFFSET_MAX_TIME_DIFFERENCE ( ( ( ( int64_t ) INT32_MAX + 1 ) * 1000 ) ) |
Macro to represent exactly half of the total number of seconds in an NTP era. As 32 bits are used to represent the "seconds" part of an SNTP timestamp, the half of the total range of seconds in an NTP era is 2^31 seconds, which represents ~68 years.
#define TOTAL_MILLISECONDS_IN_NTP_ERA ( ( ( int64_t ) UINT32_MAX + 1 ) * 1000 ) |
Macro to represent the total number of milliseconds that are represented in an NTP era period. This macro represents a duration of ~136 years.
|
static |
Utility macro to fill 32-bit integer in word-sized memory in network byte (or Big Endian) order.
[out] | pWordMemory | Pointer to the word-sized memory in which the 32-bit integer will be filled. |
[in] | data | The 32-bit integer to fill in the wordMemory in network byte order. |
|
static |
Utility macro to generate a 32-bit integer from memory containing integer in network (or Big Endian) byte order.
[in] | ptr | Pointer to the memory containing 32-bit integer in network byte order. |
|
static |
Utility to return absolute (or positively signed) value of an signed 64 bit integer.
[in] | value | The integer to return the absolute value of. |
value
.
|
static |
Utility to determine whether a timestamp represents a zero timestamp value.
[in] | pTime | The timestamp whose value is to be inspected for zero value. |
true
if the timestamp is zero; otherwise false
.
|
static |
Utility to convert the "fractions" part of an SNTP timestamp to milliseconds duration of time.
[in] | fractions | The fractions value. |
fractions
value.
|
static |
Utility to safely calculate difference between server and client timestamps and return the difference in the resolution of milliseconds as a signed 64 bit integer. The calculated value represents the effective subtraction as ( serverTimeSec
- clientTimeSec
).
[in] | pServerTime | The server timestamp. |
[in] | pClientTime | The client timestamp. |
|
static |
Utility to calculate clock offset of system relative to the server using the on-wire protocol specified in the NTPv4 specification. For more information on on-wire protocol, refer to RFC 5905 Section 8.
T2 T3 --------------------------------- <----- *SNTP/NTP server* /\ \ / \ Request* / \ *Response* / \/ --------------------------------- <----- *SNTP client* T1 T4The four most recent timestamps, T1 through T4, are used to compute the clock offset of SNTP client relative to the server where:
T1 = Client Request Transmit Time T2 = Server Receive Time (of client request) T3 = Server Response Transmit Time T4 = Client Receive Time (of server response)
Clock Offset = T(NTP/SNTP server) - T(SNTP client)
2
[in] | pClientTxTime | The system time of sending the SNTP request. This is the same as "T1" in the above diagram. |
[in] | pServerRxTime | The server time of receiving the SNTP request packet from the client. This is the same as "T2" in the above diagram. |
[in] | pServerTxTime | The server time of sending the SNTP response packet. This is the same as "T3" in the above diagram. |
[in] | pClientRxTime | The system time of receiving the SNTP response from the server. This is the same as "T4" in the above diagram. |
[out] | pClockOffset | This will be filled with the calculated offset value of the system clock relative to the server time with the assumption that the system clock is within 68 years of server time. |
|
static |
Parse a SNTP response packet by determining whether it is a rejected or accepted response to an SNTP request, and accordingly, populate the pParsedResponse
parameter with the parsed data.
[in] | pResponsePacket | The SNTP response packet from server to parse. |
[in] | pRequestTxTime | The system time (in SNTP timestamp format) of sending the SNTP request to server. |
[in] | pResponseRxTime | The system time (in SNTP timestamp format) of receiving the SNTP response from server. |
[out] | pParsedResponse | The parameter that will be populated with data parsed from the response packet, pResponsePacket . |
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.
[in,out] | pRequestTime | The 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] | randomNumber | A 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] | pBuffer | The buffer that will be populated with the serialized SNTP request packet. |
[in] | bufferSize | The size of the pBuffer buffer. It should be at least SNTP_PACKET_BASE_SIZE bytes in size. |
pRequestTime
value for de-serializing the server response with Sntp_DeserializeResponse API.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.
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.[in] | pRequestTime | The 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] | pResponseRxTime | The 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] | pResponseBuffer | The buffer containing the SNTP response from the server. |
[in] | bufferSize | The 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] | pParsedResponse | The 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. |
pParsedResponse
parameter. 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).
[in] | clockFreqTolerance | The frequency tolerance of system clock in parts per million (PPM) units. This parameter MUST be non-zero. |
[in] | desiredAccuracy | The 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] | pPollInterval | This 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 . |
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).
[in] | pSntpTime | The SNTP timestamp to convert to UNIX time. |
[out] | pUnixTimeSecs | This will be filled with the seconds part of the UNIX time equivalent of the SNTP time, pSntpTime . |
[out] | pUnixTimeMicrosecs | This will be filled with the microseconds part of the UNIX time equivalent of the SNTP time, pSntpTime . |