Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: oldheating gps motorhome heating
udp/ntp/ntpserver.c@138:5ff0c7069300, 2019-04-07 (annotated)
- Committer:
- andrewboyson
- Date:
- Sun Apr 07 18:36:42 2019 +0000
- Revision:
- 138:5ff0c7069300
- Parent:
- 134:3aa1bc602b19
Removed all __packed structs
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| andrewboyson | 113:904b40231907 | 1 | #include <stdint.h> |
| andrewboyson | 134:3aa1bc602b19 | 2 | #include <stdlib.h> |
| andrewboyson | 113:904b40231907 | 3 | |
| andrewboyson | 113:904b40231907 | 4 | #include "clk.h" |
| andrewboyson | 113:904b40231907 | 5 | #include "clkgov.h" |
| andrewboyson | 113:904b40231907 | 6 | #include "clktime.h" |
| andrewboyson | 113:904b40231907 | 7 | #include "clkutc.h" |
| andrewboyson | 124:6e558721ec1c | 8 | #include "ntptimestamp.h" |
| andrewboyson | 113:904b40231907 | 9 | #include "ntp.h" |
| andrewboyson | 138:5ff0c7069300 | 10 | #include "ntphdr.h" |
| andrewboyson | 113:904b40231907 | 11 | #include "action.h" |
| andrewboyson | 113:904b40231907 | 12 | #include "log.h" |
| andrewboyson | 113:904b40231907 | 13 | #include "net.h" |
| andrewboyson | 113:904b40231907 | 14 | |
| andrewboyson | 113:904b40231907 | 15 | #define LI_PRIOR_NOTICE_SECONDS 10LL * 24 * 60 * 60 |
| andrewboyson | 113:904b40231907 | 16 | |
| andrewboyson | 113:904b40231907 | 17 | bool NtpServerEnable = false; |
| andrewboyson | 113:904b40231907 | 18 | |
| andrewboyson | 113:904b40231907 | 19 | char* NtpServerName = ""; |
| andrewboyson | 113:904b40231907 | 20 | |
| andrewboyson | 113:904b40231907 | 21 | static int getPrecision() |
| andrewboyson | 113:904b40231907 | 22 | { |
| andrewboyson | 113:904b40231907 | 23 | /* |
| andrewboyson | 113:904b40231907 | 24 | The Precision field is set to reflect the maximum reading error of the local clock. |
| andrewboyson | 113:904b40231907 | 25 | For all practical cases it is computed as the negative of the number of significant bits |
| andrewboyson | 113:904b40231907 | 26 | to the right of the decimal point in the NTP timestamp format. |
| andrewboyson | 113:904b40231907 | 27 | While that could be CLK_TIME_ONE_SECOND_SHIFT I think that would be the resolution not the precision |
| andrewboyson | 113:904b40231907 | 28 | I therefore assume I can count on the clock to be good to about a microsecond or 2^-20 |
| andrewboyson | 113:904b40231907 | 29 | */ |
| andrewboyson | 113:904b40231907 | 30 | return -20; |
| andrewboyson | 113:904b40231907 | 31 | } |
| andrewboyson | 113:904b40231907 | 32 | static int getLi() |
| andrewboyson | 113:904b40231907 | 33 | { |
| andrewboyson | 113:904b40231907 | 34 | if (!ClkTimeIsSet() ) return 3; //Alarm condition; clock is not synchronised |
| andrewboyson | 113:904b40231907 | 35 | if (!ClkUtcGetNextLeapEnable()) return 0; //No warning |
| andrewboyson | 113:904b40231907 | 36 | |
| andrewboyson | 125:8c84daac38ab | 37 | clktime nowTime = ClkUtcFromTai(ClkNowTai()); //Use the less costly time this scan |
| andrewboyson | 125:8c84daac38ab | 38 | clktime liPriorNotice = LI_PRIOR_NOTICE_SECONDS << CLK_TIME_ONE_SECOND_SHIFT; |
| andrewboyson | 113:904b40231907 | 39 | |
| andrewboyson | 113:904b40231907 | 40 | if (nowTime > ClkUtcGetNextEpoch() - liPriorNotice) |
| andrewboyson | 113:904b40231907 | 41 | { |
| andrewboyson | 113:904b40231907 | 42 | if (ClkUtcGetNextLeapForward()) return 1; //Last minute has 61 seconds |
| andrewboyson | 113:904b40231907 | 43 | else return 2; //Last minute has 59 seconds |
| andrewboyson | 113:904b40231907 | 44 | } |
| andrewboyson | 113:904b40231907 | 45 | else |
| andrewboyson | 113:904b40231907 | 46 | { |
| andrewboyson | 113:904b40231907 | 47 | return 0; //No warning |
| andrewboyson | 113:904b40231907 | 48 | } |
| andrewboyson | 113:904b40231907 | 49 | } |
| andrewboyson | 113:904b40231907 | 50 | |
| andrewboyson | 113:904b40231907 | 51 | static int getStratum() |
| andrewboyson | 113:904b40231907 | 52 | { |
| andrewboyson | 113:904b40231907 | 53 | if (ClkTimeIsSet()) return 1; |
| andrewboyson | 113:904b40231907 | 54 | else return 0; |
| andrewboyson | 113:904b40231907 | 55 | } |
| andrewboyson | 113:904b40231907 | 56 | static char* getIdent() |
| andrewboyson | 113:904b40231907 | 57 | { |
| andrewboyson | 113:904b40231907 | 58 | if (!ClkTimeIsSet() ) return "INIT"; |
| andrewboyson | 113:904b40231907 | 59 | if (!ClkGovIsSynced()) return "LOCL"; |
| andrewboyson | 113:904b40231907 | 60 | return NtpServerName; |
| andrewboyson | 113:904b40231907 | 61 | } |
| andrewboyson | 113:904b40231907 | 62 | static uint64_t getRefNtp() |
| andrewboyson | 113:904b40231907 | 63 | { |
| andrewboyson | 124:6e558721ec1c | 64 | return NtpTimeStampFromClkTime(ClkRefTai()); |
| andrewboyson | 113:904b40231907 | 65 | } |
| andrewboyson | 138:5ff0c7069300 | 66 | int NtpServerRequest(void (*traceback)(void), char* pPacketRx, char* pPacketTx) |
| andrewboyson | 113:904b40231907 | 67 | { |
| andrewboyson | 113:904b40231907 | 68 | if (!NtpServerEnable) return DO_NOTHING; |
| andrewboyson | 113:904b40231907 | 69 | |
| andrewboyson | 113:904b40231907 | 70 | if (NtpTrace) |
| andrewboyson | 113:904b40231907 | 71 | { |
| andrewboyson | 113:904b40231907 | 72 | if (NetTraceNewLine) Log("\r\n"); |
| andrewboyson | 113:904b40231907 | 73 | LogTimeF("NTP received request\r\n"); |
| andrewboyson | 113:904b40231907 | 74 | if (NetTraceStack) traceback(); |
| andrewboyson | 138:5ff0c7069300 | 75 | NtpLogHeader(pPacketRx); |
| andrewboyson | 113:904b40231907 | 76 | } |
| andrewboyson | 134:3aa1bc602b19 | 77 | |
| andrewboyson | 113:904b40231907 | 78 | uint64_t refNtp = getRefNtp(); |
| andrewboyson | 125:8c84daac38ab | 79 | uint64_t nowNtp = NtpTimeStampFromClkTime(ClkTimeGet()); //use the costly time at this instant |
| andrewboyson | 113:904b40231907 | 80 | int stratum = getStratum(); |
| andrewboyson | 113:904b40231907 | 81 | char* ident = getIdent(); |
| andrewboyson | 113:904b40231907 | 82 | int li = getLi(); |
| andrewboyson | 113:904b40231907 | 83 | int precision = getPrecision(); |
| andrewboyson | 113:904b40231907 | 84 | |
| andrewboyson | 138:5ff0c7069300 | 85 | NtpHdrSetMode (pPacketTx, NTP_SERVER); |
| andrewboyson | 138:5ff0c7069300 | 86 | NtpHdrSetVersion (pPacketTx, NtpHdrGetVersion(pPacketRx)); |
| andrewboyson | 138:5ff0c7069300 | 87 | NtpHdrSetLI (pPacketTx, li); |
| andrewboyson | 138:5ff0c7069300 | 88 | NtpHdrSetStratum (pPacketTx, stratum); |
| andrewboyson | 138:5ff0c7069300 | 89 | NtpHdrSetPoll (pPacketTx, NtpHdrGetPoll(pPacketRx)); |
| andrewboyson | 138:5ff0c7069300 | 90 | NtpHdrSetPrecision (pPacketTx, precision); |
| andrewboyson | 138:5ff0c7069300 | 91 | NtpHdrSetRootDelay (pPacketTx, 0); |
| andrewboyson | 138:5ff0c7069300 | 92 | NtpHdrSetDispersion (pPacketTx, 0); |
| andrewboyson | 138:5ff0c7069300 | 93 | char* p = NtpHdrPtrRefIdentifier(pPacketTx); |
| andrewboyson | 138:5ff0c7069300 | 94 | *p++ = ident[0]; //For stratum 1 (reference clock), this is a four-octet, left-justified, zero-padded ASCII string. |
| andrewboyson | 138:5ff0c7069300 | 95 | *p++ = ident[1]; |
| andrewboyson | 138:5ff0c7069300 | 96 | *p++ = ident[2]; |
| andrewboyson | 138:5ff0c7069300 | 97 | *p = ident[3]; |
| andrewboyson | 138:5ff0c7069300 | 98 | NtpHdrSetRefTimeStamp(pPacketTx, refNtp); |
| andrewboyson | 138:5ff0c7069300 | 99 | NtpHdrSetOriTimeStamp(pPacketTx, NtpHdrGetTraTimeStamp(pPacketRx)); |
| andrewboyson | 138:5ff0c7069300 | 100 | NtpHdrSetRecTimeStamp(pPacketTx, nowNtp); |
| andrewboyson | 138:5ff0c7069300 | 101 | NtpHdrSetTraTimeStamp(pPacketTx, nowNtp); |
| andrewboyson | 113:904b40231907 | 102 | |
| andrewboyson | 138:5ff0c7069300 | 103 | if (NtpTrace) NtpLogHeader(pPacketTx); |
| andrewboyson | 113:904b40231907 | 104 | return UNICAST; |
| andrewboyson | 113:904b40231907 | 105 | } |
| andrewboyson | 113:904b40231907 | 106 |