A stack which works with or without an Mbed os library. Provides IPv4 or IPv6 with a full 1500 byte buffer.
Dependents: oldheating gps motorhome heating
udp/ntp.cpp@17:e475ab861365, 2017-06-26 (annotated)
- Committer:
- andrewboyson
- Date:
- Mon Jun 26 10:03:48 2017 +0000
- Revision:
- 17:e475ab861365
- Parent:
- 10:f0854784e960
- Child:
- 19:43c70b424fc1
Made the NTP server stand alone by providing links which a user needs to plumb into a clock.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
andrewboyson | 1:5f70c361db20 | 1 | #include "mbed.h" |
andrewboyson | 4:31fa7d50722c | 2 | #include "log.h" |
andrewboyson | 1:5f70c361db20 | 3 | #include "net.h" |
andrewboyson | 7:b794780e33b4 | 4 | #include "udp.h" |
andrewboyson | 0:faa09bd4e6bf | 5 | |
andrewboyson | 0:faa09bd4e6bf | 6 | #define HEADER_SIZE 48 |
andrewboyson | 0:faa09bd4e6bf | 7 | |
andrewboyson | 0:faa09bd4e6bf | 8 | #define ERA_BASE 0 |
andrewboyson | 0:faa09bd4e6bf | 9 | #define ERA_PIVOT 2016 |
andrewboyson | 0:faa09bd4e6bf | 10 | |
andrewboyson | 0:faa09bd4e6bf | 11 | #define CLIENT 3 |
andrewboyson | 0:faa09bd4e6bf | 12 | #define SERVER 4 |
andrewboyson | 0:faa09bd4e6bf | 13 | |
andrewboyson | 17:e475ab861365 | 14 | int64_t (*NtpGetClockRefFunction) (); |
andrewboyson | 17:e475ab861365 | 15 | int64_t (*NtpGetClockNowFunction) (); |
andrewboyson | 17:e475ab861365 | 16 | int (*NtpGetClockStratumFunction)(); |
andrewboyson | 17:e475ab861365 | 17 | char* (*NtpGetClockIdentFunction) (); |
andrewboyson | 17:e475ab861365 | 18 | bool NtpEnableServer = false; |
andrewboyson | 17:e475ab861365 | 19 | |
andrewboyson | 0:faa09bd4e6bf | 20 | __packed struct header { |
andrewboyson | 0:faa09bd4e6bf | 21 | unsigned Mode : 3; |
andrewboyson | 0:faa09bd4e6bf | 22 | unsigned VN : 3; |
andrewboyson | 0:faa09bd4e6bf | 23 | unsigned LI : 2; |
andrewboyson | 0:faa09bd4e6bf | 24 | uint8_t Stratum; |
andrewboyson | 0:faa09bd4e6bf | 25 | int8_t Poll; |
andrewboyson | 0:faa09bd4e6bf | 26 | int8_t Precision; |
andrewboyson | 0:faa09bd4e6bf | 27 | uint32_t RootDelay; |
andrewboyson | 0:faa09bd4e6bf | 28 | uint32_t Dispersion; |
andrewboyson | 0:faa09bd4e6bf | 29 | char RefIdentifier[4]; |
andrewboyson | 0:faa09bd4e6bf | 30 | |
andrewboyson | 0:faa09bd4e6bf | 31 | uint64_t RefTimeStamp; |
andrewboyson | 0:faa09bd4e6bf | 32 | uint64_t OriTimeStamp; |
andrewboyson | 0:faa09bd4e6bf | 33 | uint64_t RecTimeStamp; |
andrewboyson | 0:faa09bd4e6bf | 34 | uint64_t TraTimeStamp; |
andrewboyson | 0:faa09bd4e6bf | 35 | }; |
andrewboyson | 1:5f70c361db20 | 36 | uint64_t makeNtpTimeStamp(int64_t ns) |
andrewboyson | 1:5f70c361db20 | 37 | { |
andrewboyson | 1:5f70c361db20 | 38 | uint64_t timestamp = ns << 2; |
andrewboyson | 1:5f70c361db20 | 39 | timestamp /= 1000; timestamp <<= 10; |
andrewboyson | 1:5f70c361db20 | 40 | timestamp /= 1000; timestamp <<= 10; |
andrewboyson | 1:5f70c361db20 | 41 | timestamp /= 1000; timestamp <<= 10; |
andrewboyson | 0:faa09bd4e6bf | 42 | |
andrewboyson | 1:5f70c361db20 | 43 | timestamp += 2208988800ULL << 32; |
andrewboyson | 0:faa09bd4e6bf | 44 | |
andrewboyson | 1:5f70c361db20 | 45 | return NetToHost64(timestamp); |
andrewboyson | 0:faa09bd4e6bf | 46 | } |
andrewboyson | 7:b794780e33b4 | 47 | int NtpHandleRequest(int* pSize, void * pPacket) |
andrewboyson | 0:faa09bd4e6bf | 48 | { |
andrewboyson | 17:e475ab861365 | 49 | if (!NtpEnableServer) return DO_NOTHING; |
andrewboyson | 17:e475ab861365 | 50 | |
andrewboyson | 17:e475ab861365 | 51 | if (!NtpGetClockRefFunction || !NtpGetClockNowFunction || !NtpGetClockStratumFunction || !NtpGetClockIdentFunction) |
andrewboyson | 17:e475ab861365 | 52 | { |
andrewboyson | 17:e475ab861365 | 53 | LogTimeF("NtpHandleRequest - NTP server is enabled but has not been plumbed into a clock\r\n"); |
andrewboyson | 17:e475ab861365 | 54 | return DO_NOTHING; |
andrewboyson | 17:e475ab861365 | 55 | } |
andrewboyson | 17:e475ab861365 | 56 | |
andrewboyson | 9:91dae5300a4d | 57 | if (*pSize < HEADER_SIZE) return DO_NOTHING; |
andrewboyson | 0:faa09bd4e6bf | 58 | |
andrewboyson | 0:faa09bd4e6bf | 59 | struct header* pHeader = (struct header*)pPacket; |
andrewboyson | 0:faa09bd4e6bf | 60 | |
andrewboyson | 17:e475ab861365 | 61 | int64_t refNs = NtpGetClockRefFunction(); |
andrewboyson | 17:e475ab861365 | 62 | int64_t nowNs = NtpGetClockNowFunction(); |
andrewboyson | 17:e475ab861365 | 63 | int stratum = NtpGetClockStratumFunction(); |
andrewboyson | 17:e475ab861365 | 64 | char* ident = NtpGetClockIdentFunction(); |
andrewboyson | 17:e475ab861365 | 65 | |
andrewboyson | 0:faa09bd4e6bf | 66 | switch (pHeader->Mode) |
andrewboyson | 0:faa09bd4e6bf | 67 | { |
andrewboyson | 0:faa09bd4e6bf | 68 | case CLIENT: |
andrewboyson | 0:faa09bd4e6bf | 69 | pHeader->Mode = SERVER; |
andrewboyson | 0:faa09bd4e6bf | 70 | pHeader->LI = 0; |
andrewboyson | 17:e475ab861365 | 71 | pHeader->Stratum = stratum; |
andrewboyson | 0:faa09bd4e6bf | 72 | pHeader->Poll = 0; |
andrewboyson | 0:faa09bd4e6bf | 73 | pHeader->Precision = 0; |
andrewboyson | 0:faa09bd4e6bf | 74 | pHeader->RootDelay = 0; |
andrewboyson | 0:faa09bd4e6bf | 75 | pHeader->Dispersion = 0; |
andrewboyson | 17:e475ab861365 | 76 | pHeader->RefIdentifier[0] = ident[0]; //For stratum 1 (reference clock), this is a four-octet, left-justified, zero-padded ASCII string. |
andrewboyson | 17:e475ab861365 | 77 | pHeader->RefIdentifier[1] = ident[1]; |
andrewboyson | 17:e475ab861365 | 78 | pHeader->RefIdentifier[2] = ident[2]; |
andrewboyson | 17:e475ab861365 | 79 | pHeader->RefIdentifier[3] = ident[3]; |
andrewboyson | 0:faa09bd4e6bf | 80 | |
andrewboyson | 17:e475ab861365 | 81 | pHeader->RefTimeStamp = makeNtpTimeStamp(refNs); |
andrewboyson | 0:faa09bd4e6bf | 82 | pHeader->OriTimeStamp = pHeader->TraTimeStamp; |
andrewboyson | 17:e475ab861365 | 83 | pHeader->RecTimeStamp = makeNtpTimeStamp(nowNs); |
andrewboyson | 17:e475ab861365 | 84 | pHeader->TraTimeStamp = makeNtpTimeStamp(nowNs); |
andrewboyson | 7:b794780e33b4 | 85 | *pSize = HEADER_SIZE; |
andrewboyson | 9:91dae5300a4d | 86 | return UNICAST; |
andrewboyson | 0:faa09bd4e6bf | 87 | default: |
andrewboyson | 4:31fa7d50722c | 88 | LogTimeF("\r\nNTP packet unknown\r\n"); |
andrewboyson | 4:31fa7d50722c | 89 | LogTimeF("Mode %d\r\n", pHeader->Mode); |
andrewboyson | 4:31fa7d50722c | 90 | LogTimeF("Version %d\r\n", pHeader->VN); |
andrewboyson | 4:31fa7d50722c | 91 | LogTimeF("Stratum %d\r\n", pHeader->Stratum); |
andrewboyson | 4:31fa7d50722c | 92 | LogTimeF("Reference %4s\r\n", pHeader->RefIdentifier); |
andrewboyson | 0:faa09bd4e6bf | 93 | } |
andrewboyson | 9:91dae5300a4d | 94 | return DO_NOTHING; |
andrewboyson | 0:faa09bd4e6bf | 95 | } |