NDEVR
API Documentation
NtpClient.h
1#pragma once
2#include <NDEVR/ItemDownloader.h>
3#include <NDEVR/String.h>
4#include <cassert>
5
6#include <memory>
7
8#include <QtCore/QObject>
9#include <QtNetwork/QHostAddress>
10#include <QtNetwork/QUdpSocket>
11#include <QHostInfo>
12#include <NDEVR/NtpPacketFlags.h>
13#include <NDEVR/NtpTimestamp.h>
14#include <NDEVR/NtpPacket.h>
15#include <NDEVR/NtpMode.h>
16#include <NDEVR/NtpReply.h>
17namespace NDEVR
18{
25 class NtpClient : public TimeRequest
26 {
27 Q_OBJECT;
28 public:
35 NtpClient(const StringView& host, uint02 bind_port, uint02 remote_port)
36 {
37 QHostInfo::lookupHost(host.getAs<QString>(), [this, bind_port, remote_port](const QHostInfo& host)
38 {
39 if (host.error() != QHostInfo::NoError)
40 {
41 emit errorOccurredSignal(0);
42 return;
43 }
44 QList<QHostAddress> addresses = host.addresses();
45 if(addresses.size() > 0)
46 {
47 if (bind(QHostAddress::Any, bind_port))
48 sendRequest(addresses[0], remote_port);
49 else if (bind(QHostAddress::Any, bind_port + 1))
50 sendRequest(addresses[0], remote_port);
51 else if (bind(QHostAddress::Any, bind_port + 2))
52 sendRequest(addresses[0], remote_port);
53 else
54 emit errorOccurredSignal(0);
55 }
56 else
57 {
58 emit errorOccurredSignal(0);
59 }
60 });
61 }
62
65 virtual ~NtpClient() {}
66
72 bool bind(const QHostAddress& bindAddress = QHostAddress::Any, quint16 bindPort = 0)
73 {
74 m_socket.reset(new QUdpSocket(this));
75 if (!m_socket->bind(bindAddress, bindPort))
76 return false;
77
78 connect(m_socket.get(), &QUdpSocket::readyRead, this, &NtpClient::readPendingDatagrams);
79 connect(m_socket.get(), &QUdpSocket::errorOccurred, this, [this]
80 {
81 emit errorOccurredSignal(0);
82 });
83 return true;
84 }
85
93 bool sendRequest(const String& address, quint16 port)
94 {
95 return sendRequest(QHostAddress(address.getAs<QString>()), port);
96
97 }
98
104 bool sendRequest(const QHostAddress& address, quint16 port)
105 {
106 assert(m_socket->state() == QAbstractSocket::BoundState); // Call bind() first.
107 NtpPacket packet;
108 memset(&packet, 0, sizeof(packet));
110 packet.flags.versionNumber = 4;
112 if (m_socket->writeDatagram(reinterpret_cast<const char*>(&packet), sizeof(packet), address, port) < 0)
113 return false;
114
115 return true;
116 }
117
121 const QUdpSocket* socket() const {
122 return m_socket.get();
123 }
124
125 Q_SIGNALS:
133 void replyReceived(const QHostAddress& address, quint16 port, const NtpReply& reply);
134
135 private Q_SLOTS:
139 void readPendingDatagrams()
140 {
141 while (m_socket->hasPendingDatagrams()) {
142 NtpFullPacket packet;
143 memset(&packet, 0, sizeof(packet));
144
145 QHostAddress address;
146 quint16 port;
147 if (m_socket->readDatagram(reinterpret_cast<char*>(&packet), sizeof(packet), &address, &port) < cast<qint64>(sizeof(NtpPacket)))
148 continue;
149
150 m_reply = NtpReply(packet, Time::SystemTime());
151 emit replyReceived(address, port, NtpReply(packet, Time::SystemTime()));
152 emit finishedSignal();
153 }
154 }
159 virtual Time serverTime() const override
160 {
161 return m_reply.originTime();
162 }
163
167 virtual Time rxTime() const override
168 {
169 return m_reply.destinationTime();
170 }
171
175 virtual Time txTime() const override
176 {
177 return m_reply.transmitTime();
178 }
179 private:
180 NtpReply m_reply;
181 std::unique_ptr<QUdpSocket> m_socket;
182 };
183}
virtual ~NtpClient()
Virtual destructor.
Definition NtpClient.h:65
bool bind(const QHostAddress &bindAddress=QHostAddress::Any, quint16 bindPort=0)
Definition NtpClient.h:72
virtual Time txTime() const override
Returns the transmit time from the NTP reply.
Definition NtpClient.h:175
virtual Time serverTime() const override
Returns the server time from the NTP reply origin timestamp.
Definition NtpClient.h:159
NtpClient(const StringView &host, uint02 bind_port, uint02 remote_port)
Constructs an NTP client and initiates a time request.
Definition NtpClient.h:35
virtual Time rxTime() const override
Returns the receive time from the NTP reply destination timestamp.
Definition NtpClient.h:167
bool sendRequest(const QHostAddress &address, quint16 port)
Sends an NTP request to the specified address and port.
Definition NtpClient.h:104
const QUdpSocket * socket() const
Returns the underlying UDP socket used for NTP communication.
Definition NtpClient.h:121
void replyReceived(const QHostAddress &address, quint16 port, const NtpReply &reply)
This signal is emitted whenever NTP reply is received.
bool sendRequest(const String &address, quint16 port)
Sends NTP request.
Definition NtpClient.h:93
Represents a parsed NTP reply received from an NTP server.
Definition NtpReply.h:17
The core String View class for the NDEVR API.
Definition StringView.h:58
t_type getAs() const
Converts a string into an object.
Definition StringView.h:125
The core String class for the NDEVR API.
Definition String.h:95
decltype(auto) getAs() const
Converts a string into an object.
Definition String.h:188
A request to get the time from the network.
void finishedSignal()
Emitted when the time request has finished.
Represents a timestamp with utilities for manipulation and conversion.
Definition Time.h:62
static Time SystemTime()
Retrieves the current system time which is a combination of std::chrono::steady_clock to ensure smoot...
The primary namespace for the NDEVR SDK.
uint16_t uint02
-Defines an alias representing a 2 byte, unsigned integer -Can represent exact integer values 0 throu...
@ ClientMode
Client.
Definition NtpEnums.h:24
constexpr t_to cast(const Angle< t_from > &value)
Casts an Angle from one backing type to another.
Definition Angle.h:408
Full NTP packet combining mandatory fields and optional authentication.
Definition NtpPacket.h:80
unsigned char versionNumber
Version number of the protocol (3 or 4).
Definition NtpPacket.h:16
unsigned char mode
Mode.
Definition NtpPacket.h:13
Mandatory part of an NTP packet, containing all required fields.
Definition NtpPacket.h:29
NtpPacketFlags flags
Flags.
Definition NtpPacket.h:31
NtpTimestamp transmitTimestamp
The time at which the reply departed the server for client.
Definition NtpPacket.h:61
A 64-bit NTP timestamp with seconds and fractional parts since Jan 1, 1900.