Skip to content

Commit 687b9f3

Browse files
committed
NTP working
1 parent 23a471c commit 687b9f3

File tree

1 file changed

+164
-140
lines changed

1 file changed

+164
-140
lines changed

Firmware/RTK_Everywhere/NTP.ino

Lines changed: 164 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ void menuNTP()
113113
systemPrint("5) Reference ID: ");
114114
systemPrintln(settings.ntpReferenceId);
115115

116+
systemPrint("6) NTP Port: ");
117+
systemPrintln(settings.ethernetNtpPort);
118+
116119
systemPrintln("x) Exit");
117120

118121
byte incoming = getUserInputCharacterNumber();
@@ -168,6 +171,15 @@ void menuNTP()
168171
else
169172
systemPrintln("Error: invalid Reference ID");
170173
}
174+
else if (incoming == 6)
175+
{
176+
systemPrint("Enter new NTP port: ");
177+
long newVal = getUserInputNumber();
178+
if ((newVal >= 0) && (newVal <= 65535))
179+
settings.ethernetNtpPort = newVal;
180+
else
181+
systemPrintln("Error: port number out of range");
182+
}
171183
else if (incoming == 'x')
172184
break;
173185
else if (incoming == INPUT_RESPONSE_GETCHARACTERNUMBER_EMPTY)
@@ -484,15 +496,14 @@ bool ntpProcessOneRequest(bool process, const timeval *recTv, const timeval *syn
484496
if (ntpDiag != nullptr)
485497
*ntpDiag = 0; // Clear any existing diagnostics
486498

487-
gettimeofday((timeval *)&ethernetNtpTv, nullptr); // Record the possible time of the NTP request
488-
489-
int packetDataSize = 0;
499+
ntpServer->parsePacket();
490500

491-
if (ntpServer->available() > 0)
492-
packetDataSize = ntpServer->parsePacket();
501+
int packetDataSize = ntpServer->available();
493502

494-
if (packetDataSize >= NTPpacket::NTPpacketSize)
503+
if (packetDataSize > 0)
495504
{
505+
gettimeofday((timeval *)&ethernetNtpTv, nullptr); // Record the possible time of the NTP request
506+
496507
IPAddress remoteIP = ntpServer->remoteIP();
497508
uint16_t remotePort = ntpServer->remotePort();
498509

@@ -502,149 +513,161 @@ bool ntpProcessOneRequest(bool process, const timeval *recTv, const timeval *syn
502513
remoteIP[1], remoteIP[2], remoteIP[3], remotePort);
503514
}
504515

505-
// Read the NTP packet
506-
NTPpacket packet;
516+
if (packetDataSize >= NTPpacket::NTPpacketSize)
517+
{
518+
// Read the NTP packet
519+
NTPpacket packet;
507520

508-
ntpServer->read((char *)&packet.packet, NTPpacket::NTPpacketSize); // Copy the NTP data into our packet
521+
ntpServer->read((char *)&packet.packet, NTPpacket::NTPpacketSize); // Copy the NTP data into our packet
509522

510-
// If process is false, return now
511-
if (!process)
512-
{
513-
char tmpbuf[128];
514-
snprintf(tmpbuf, sizeof(tmpbuf),
515-
"NTP request ignored. Time has not been synchronized - or not in NTP mode.\r\n");
516-
strlcat(ntpDiag, tmpbuf, ntpDiagSize);
517-
return false;
518-
}
523+
// If process is false, return now
524+
if (!process)
525+
{
526+
char tmpbuf[128];
527+
snprintf(tmpbuf, sizeof(tmpbuf),
528+
"NTP request ignored. Time has not been synchronized - or not in NTP mode.\r\n");
529+
strlcat(ntpDiag, tmpbuf, ntpDiagSize);
530+
return false;
531+
}
519532

520-
packet.extract(); // Extract the raw data into fields
521-
522-
packet.LI(packet.defaultLeapInd); // Clear the leap second adjustment. TODO: set this correctly using
523-
// getLeapSecondEvent from the GNSS
524-
packet.VN(packet.defaultVersion); // Set the version number
525-
packet.mode(packet.defaultMode); // Set the mode
526-
packet.stratum = packet.defaultStratum; // Set the stratum
527-
packet.pollExponent = settings.ntpPollExponent; // Set the poll interval
528-
packet.precision = settings.ntpPrecision; // Set the precision
529-
packet.rootDelay = packet.convertMicrosToSecsAndFraction(settings.ntpRootDelay); // Set the Root Delay
530-
packet.rootDispersion =
531-
packet.convertMicrosToSecsAndFraction(settings.ntpRootDispersion); // Set the Root Dispersion
532-
for (uint8_t i = 0; i < packet.referenceIdLen; i++)
533-
packet.referenceId[i] = settings.ntpReferenceId[i]; // Set the reference Id
534-
535-
// REF: http://support.ntp.org/bin/view/Support/DraftRfc2030
536-
// '.. the client sets the Transmit Timestamp field in the request
537-
// to the time of day according to the client clock in NTP timestamp format.'
538-
// '.. The server copies this field to the originate timestamp in the reply and
539-
// sets the Receive Timestamp and Transmit Timestamp fields to the time of day
540-
// according to the server clock in NTP timestamp format.'
541-
542-
// Important note: the NTP Era started January 1st 1900.
543-
// tv will contain the time based on the Unix epoch (January 1st 1970)
544-
// We need to adjust...
545-
546-
// First, add the client transmit timestamp to our diagnostics
547-
if (ntpDiag != nullptr)
548-
{
549-
char tmpbuf[128];
550-
snprintf(tmpbuf, sizeof(tmpbuf), "Originate Timestamp (Client Transmit): %u.%06u\r\n",
551-
packet.transmitTimestampSeconds, packet.convertFractionToMicros(packet.transmitTimestampFraction));
552-
strlcat(ntpDiag, tmpbuf, ntpDiagSize);
553-
}
533+
packet.extract(); // Extract the raw data into fields
534+
535+
packet.LI(packet.defaultLeapInd); // Clear the leap second adjustment. TODO: set this correctly using
536+
// getLeapSecondEvent from the GNSS
537+
packet.VN(packet.defaultVersion); // Set the version number
538+
packet.mode(packet.defaultMode); // Set the mode
539+
packet.stratum = packet.defaultStratum; // Set the stratum
540+
packet.pollExponent = settings.ntpPollExponent; // Set the poll interval
541+
packet.precision = settings.ntpPrecision; // Set the precision
542+
packet.rootDelay = packet.convertMicrosToSecsAndFraction(settings.ntpRootDelay); // Set the Root Delay
543+
packet.rootDispersion =
544+
packet.convertMicrosToSecsAndFraction(settings.ntpRootDispersion); // Set the Root Dispersion
545+
for (uint8_t i = 0; i < packet.referenceIdLen; i++)
546+
packet.referenceId[i] = settings.ntpReferenceId[i]; // Set the reference Id
547+
548+
// REF: http://support.ntp.org/bin/view/Support/DraftRfc2030
549+
// '.. the client sets the Transmit Timestamp field in the request
550+
// to the time of day according to the client clock in NTP timestamp format.'
551+
// '.. The server copies this field to the originate timestamp in the reply and
552+
// sets the Receive Timestamp and Transmit Timestamp fields to the time of day
553+
// according to the server clock in NTP timestamp format.'
554+
555+
// Important note: the NTP Era started January 1st 1900.
556+
// tv will contain the time based on the Unix epoch (January 1st 1970)
557+
// We need to adjust...
558+
559+
// First, add the client transmit timestamp to our diagnostics
560+
if (ntpDiag != nullptr)
561+
{
562+
char tmpbuf[128];
563+
snprintf(tmpbuf, sizeof(tmpbuf), "Originate Timestamp (Client Transmit): %u.%06u\r\n",
564+
packet.transmitTimestampSeconds, packet.convertFractionToMicros(packet.transmitTimestampFraction));
565+
strlcat(ntpDiag, tmpbuf, ntpDiagSize);
566+
}
554567

555-
// Copy the client transmit timestamp into the originate timestamp
556-
packet.originateTimestampSeconds = packet.transmitTimestampSeconds;
557-
packet.originateTimestampFraction = packet.transmitTimestampFraction;
568+
// Copy the client transmit timestamp into the originate timestamp
569+
packet.originateTimestampSeconds = packet.transmitTimestampSeconds;
570+
packet.originateTimestampFraction = packet.transmitTimestampFraction;
558571

559-
// Set the receive timestamp to the time we received the packet (logged by the W5500 interrupt)
560-
uint32_t recUnixSeconds = recTv->tv_sec;
561-
recUnixSeconds -= settings.timeZoneSeconds; // Subtract the time zone offset to convert recTv to Unix time
562-
recUnixSeconds -= settings.timeZoneMinutes * 60;
563-
recUnixSeconds -= settings.timeZoneHours * 60 * 60;
564-
packet.receiveTimestampSeconds = packet.convertUnixSecondsToNTP(recUnixSeconds); // Unix -> NTP
565-
packet.receiveTimestampFraction = packet.convertMicrosToFraction(recTv->tv_usec); // Micros to 1/2^32
572+
// Set the receive timestamp to the time we received the packet (logged by the W5500 interrupt)
573+
uint32_t recUnixSeconds = recTv->tv_sec;
574+
recUnixSeconds -= settings.timeZoneSeconds; // Subtract the time zone offset to convert recTv to Unix time
575+
recUnixSeconds -= settings.timeZoneMinutes * 60;
576+
recUnixSeconds -= settings.timeZoneHours * 60 * 60;
577+
packet.receiveTimestampSeconds = packet.convertUnixSecondsToNTP(recUnixSeconds); // Unix -> NTP
578+
packet.receiveTimestampFraction = packet.convertMicrosToFraction(recTv->tv_usec); // Micros to 1/2^32
566579

567-
// Add the receive timestamp to the diagnostics
568-
if (ntpDiag != nullptr)
569-
{
570-
char tmpbuf[128];
571-
snprintf(tmpbuf, sizeof(tmpbuf), "Received Timestamp: %u.%06u\r\n",
572-
packet.receiveTimestampSeconds, packet.convertFractionToMicros(packet.receiveTimestampFraction));
573-
strlcat(ntpDiag, tmpbuf, ntpDiagSize);
574-
}
580+
// Add the receive timestamp to the diagnostics
581+
if (ntpDiag != nullptr)
582+
{
583+
char tmpbuf[128];
584+
snprintf(tmpbuf, sizeof(tmpbuf), "Received Timestamp: %u.%06u\r\n",
585+
packet.receiveTimestampSeconds, packet.convertFractionToMicros(packet.receiveTimestampFraction));
586+
strlcat(ntpDiag, tmpbuf, ntpDiagSize);
587+
}
575588

576-
// Add when our clock was last sync'd
577-
uint32_t syncUnixSeconds = syncTv->tv_sec;
578-
syncUnixSeconds -= settings.timeZoneSeconds; // Subtract the time zone offset to convert recTv to Unix time
579-
syncUnixSeconds -= settings.timeZoneMinutes * 60;
580-
syncUnixSeconds -= settings.timeZoneHours * 60 * 60;
581-
packet.referenceTimestampSeconds = packet.convertUnixSecondsToNTP(syncUnixSeconds); // Unix -> NTP
582-
packet.referenceTimestampFraction = packet.convertMicrosToFraction(syncTv->tv_usec); // Micros to 1/2^32
589+
// Add when our clock was last sync'd
590+
uint32_t syncUnixSeconds = syncTv->tv_sec;
591+
syncUnixSeconds -= settings.timeZoneSeconds; // Subtract the time zone offset to convert recTv to Unix time
592+
syncUnixSeconds -= settings.timeZoneMinutes * 60;
593+
syncUnixSeconds -= settings.timeZoneHours * 60 * 60;
594+
packet.referenceTimestampSeconds = packet.convertUnixSecondsToNTP(syncUnixSeconds); // Unix -> NTP
595+
packet.referenceTimestampFraction = packet.convertMicrosToFraction(syncTv->tv_usec); // Micros to 1/2^32
583596

584-
// Add that to the diagnostics
585-
if (ntpDiag != nullptr)
586-
{
597+
// Add that to the diagnostics
598+
if (ntpDiag != nullptr)
599+
{
600+
char tmpbuf[128];
601+
snprintf(tmpbuf, sizeof(tmpbuf), "Reference Timestamp (Last Sync): %u.%06u\r\n",
602+
packet.referenceTimestampSeconds,
603+
packet.convertFractionToMicros(packet.referenceTimestampFraction));
604+
strlcat(ntpDiag, tmpbuf, ntpDiagSize);
605+
}
606+
607+
// Add the transmit time - i.e. now!
608+
timeval txTime;
609+
gettimeofday(&txTime, nullptr);
610+
uint32_t nowUnixSeconds = txTime.tv_sec;
611+
nowUnixSeconds -= settings.timeZoneSeconds; // Subtract the time zone offset to convert recTv to Unix time
612+
nowUnixSeconds -= settings.timeZoneMinutes * 60;
613+
nowUnixSeconds -= settings.timeZoneHours * 60 * 60;
614+
packet.transmitTimestampSeconds = packet.convertUnixSecondsToNTP(nowUnixSeconds); // Unix -> NTP
615+
packet.transmitTimestampFraction = packet.convertMicrosToFraction(txTime.tv_usec); // Micros to 1/2^32
616+
617+
packet.insert(); // Copy the data fields back into the buffer
618+
619+
// Now transmit the response to the client.
620+
ntpServer->beginPacket(remoteIP, remotePort);
621+
ntpServer->write(packet.packet, NTPpacket::NTPpacketSize);
622+
int result = ntpServer->endPacket();
623+
processed = true;
624+
625+
// Add our server transmit time to the diagnostics
626+
if (ntpDiag != nullptr)
627+
{
628+
char tmpbuf[128];
629+
snprintf(tmpbuf, sizeof(tmpbuf), "Transmit Timestamp: %u.%06u\r\n",
630+
packet.transmitTimestampSeconds, packet.convertFractionToMicros(packet.transmitTimestampFraction));
631+
strlcat(ntpDiag, tmpbuf, ntpDiagSize);
632+
}
633+
634+
/*
635+
// Add the socketSendUDP result to the diagnostics
636+
if (ntpDiag != nullptr)
637+
{
587638
char tmpbuf[128];
588-
snprintf(tmpbuf, sizeof(tmpbuf), "Reference Timestamp (Last Sync): %u.%06u\r\n",
589-
packet.referenceTimestampSeconds,
590-
packet.convertFractionToMicros(packet.referenceTimestampFraction));
639+
snprintf(tmpbuf, sizeof(tmpbuf), "socketSendUDP result: %d\r\n", result);
591640
strlcat(ntpDiag, tmpbuf, ntpDiagSize);
592-
}
641+
}
642+
*/
593643

594-
// Add the transmit time - i.e. now!
595-
timeval txTime;
596-
gettimeofday(&txTime, nullptr);
597-
uint32_t nowUnixSeconds = txTime.tv_sec;
598-
nowUnixSeconds -= settings.timeZoneSeconds; // Subtract the time zone offset to convert recTv to Unix time
599-
nowUnixSeconds -= settings.timeZoneMinutes * 60;
600-
nowUnixSeconds -= settings.timeZoneHours * 60 * 60;
601-
packet.transmitTimestampSeconds = packet.convertUnixSecondsToNTP(nowUnixSeconds); // Unix -> NTP
602-
packet.transmitTimestampFraction = packet.convertMicrosToFraction(txTime.tv_usec); // Micros to 1/2^32
603-
604-
packet.insert(); // Copy the data fields back into the buffer
605-
606-
// Now transmit the response to the client.
607-
ntpServer->beginPacket(remoteIP, remotePort);
608-
ntpServer->write(packet.packet, NTPpacket::NTPpacketSize);
609-
// int result = ntpServer->endPacket();
610-
processed = true;
611-
612-
// Add our server transmit time to the diagnostics
613-
if (ntpDiag != nullptr)
614-
{
644+
/*
645+
// Add the packet to the diagnostics
646+
if (ntpDiag != nullptr)
647+
{
615648
char tmpbuf[128];
616-
snprintf(tmpbuf, sizeof(tmpbuf), "Transmit Timestamp: %u.%06u\r\n",
617-
packet.transmitTimestampSeconds, packet.convertFractionToMicros(packet.transmitTimestampFraction));
649+
snprintf(tmpbuf, sizeof(tmpbuf), "Packet: ");
618650
strlcat(ntpDiag, tmpbuf, ntpDiagSize);
651+
for (int i = 0; i < NTPpacket::NTPpacketSize; i++)
652+
{
653+
snprintf(tmpbuf, sizeof(tmpbuf), "%02X ", packet.packet[i]);
654+
strlcat(ntpDiag, tmpbuf, ntpDiagSize);
655+
}
656+
snprintf(tmpbuf, sizeof(tmpbuf), "\r\n");
657+
strlcat(ntpDiag, tmpbuf, ntpDiagSize);
658+
}
659+
*/
619660
}
620-
621-
/*
622-
// Add the socketSendUDP result to the diagnostics
623-
if (ntpDiag != nullptr)
624-
{
625-
char tmpbuf[128];
626-
snprintf(tmpbuf, sizeof(tmpbuf), "socketSendUDP result: %d\r\n", result);
627-
strlcat(ntpDiag, tmpbuf, ntpDiagSize);
628-
}
629-
*/
630-
631-
/*
632-
// Add the packet to the diagnostics
633-
if (ntpDiag != nullptr)
634-
{
635-
char tmpbuf[128];
636-
snprintf(tmpbuf, sizeof(tmpbuf), "Packet: ");
637-
strlcat(ntpDiag, tmpbuf, ntpDiagSize);
638-
for (int i = 0; i < NTPpacket::NTPpacketSize; i++)
639-
{
640-
snprintf(tmpbuf, sizeof(tmpbuf), "%02X ", packet.packet[i]);
661+
else
662+
{
663+
char tmpbuf[64];
664+
snprintf(tmpbuf, sizeof(tmpbuf), "Invalid size: %d\r\n", packetDataSize);
641665
strlcat(ntpDiag, tmpbuf, ntpDiagSize);
642-
}
643-
snprintf(tmpbuf, sizeof(tmpbuf), "\r\n");
644-
strlcat(ntpDiag, tmpbuf, ntpDiagSize);
645-
}
646-
*/
666+
}
647667
}
668+
669+
ntpServer->clear();
670+
648671
return processed;
649672
}
650673

@@ -872,15 +895,16 @@ void ntpServerUpdate()
872895
// Check for new NTP requests - if the time has been sync'd
873896
bool processed = ntpProcessOneRequest(systemState == STATE_NTPSERVER_SYNC, (const timeval *)&ethernetNtpTv,
874897
(const timeval *)&gnssSyncTv, ntpDiag, sizeof(ntpDiag));
875-
if (processed)
898+
899+
// Print the diagnostics - if enabled
900+
if ((settings.debugNtp || PERIODIC_DISPLAY(PD_NTP_SERVER_DATA)) && (strlen(ntpDiag) > 0) && (!inMainMenu))
876901
{
877-
// Print the diagnostics - if enabled
878-
if ((settings.debugNtp || PERIODIC_DISPLAY(PD_NTP_SERVER_DATA)) && (!inMainMenu))
879-
{
880-
PERIODIC_CLEAR(PD_NTP_SERVER_DATA);
881-
systemPrint(ntpDiag);
882-
}
902+
PERIODIC_CLEAR(PD_NTP_SERVER_DATA);
903+
systemPrint(ntpDiag);
904+
}
883905

906+
if (processed)
907+
{
884908
// Log the NTP request to file - if enabled
885909
if (settings.enableNTPFile)
886910
{

0 commit comments

Comments
 (0)