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

Committer:
andrewboyson
Date:
Sun Mar 12 13:56:08 2017 +0000
Revision:
7:b794780e33b4
Parent:
4:31fa7d50722c
Child:
9:91dae5300a4d
Added IPv6 support which is partially working

Who changed what in which revision?

UserRevisionLine numberNew 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 1:5f70c361db20 4 #include "clock.h"
andrewboyson 1:5f70c361db20 5 #include "sync.h"
andrewboyson 7:b794780e33b4 6 #include "udp.h"
andrewboyson 0:faa09bd4e6bf 7
andrewboyson 0:faa09bd4e6bf 8 #define HEADER_SIZE 48
andrewboyson 0:faa09bd4e6bf 9
andrewboyson 0:faa09bd4e6bf 10 #define ERA_BASE 0
andrewboyson 0:faa09bd4e6bf 11 #define ERA_PIVOT 2016
andrewboyson 0:faa09bd4e6bf 12
andrewboyson 0:faa09bd4e6bf 13 #define CLIENT 3
andrewboyson 0:faa09bd4e6bf 14 #define SERVER 4
andrewboyson 0:faa09bd4e6bf 15
andrewboyson 0:faa09bd4e6bf 16 __packed struct header {
andrewboyson 0:faa09bd4e6bf 17 unsigned Mode : 3;
andrewboyson 0:faa09bd4e6bf 18 unsigned VN : 3;
andrewboyson 0:faa09bd4e6bf 19 unsigned LI : 2;
andrewboyson 0:faa09bd4e6bf 20 uint8_t Stratum;
andrewboyson 0:faa09bd4e6bf 21 int8_t Poll;
andrewboyson 0:faa09bd4e6bf 22 int8_t Precision;
andrewboyson 0:faa09bd4e6bf 23 uint32_t RootDelay;
andrewboyson 0:faa09bd4e6bf 24 uint32_t Dispersion;
andrewboyson 0:faa09bd4e6bf 25 char RefIdentifier[4];
andrewboyson 0:faa09bd4e6bf 26
andrewboyson 0:faa09bd4e6bf 27 uint64_t RefTimeStamp;
andrewboyson 0:faa09bd4e6bf 28 uint64_t OriTimeStamp;
andrewboyson 0:faa09bd4e6bf 29 uint64_t RecTimeStamp;
andrewboyson 0:faa09bd4e6bf 30 uint64_t TraTimeStamp;
andrewboyson 0:faa09bd4e6bf 31 };
andrewboyson 1:5f70c361db20 32 uint64_t makeNtpTimeStamp(int64_t ns)
andrewboyson 1:5f70c361db20 33 {
andrewboyson 1:5f70c361db20 34 uint64_t timestamp = ns << 2;
andrewboyson 1:5f70c361db20 35 timestamp /= 1000; timestamp <<= 10;
andrewboyson 1:5f70c361db20 36 timestamp /= 1000; timestamp <<= 10;
andrewboyson 1:5f70c361db20 37 timestamp /= 1000; timestamp <<= 10;
andrewboyson 0:faa09bd4e6bf 38
andrewboyson 1:5f70c361db20 39 timestamp += 2208988800ULL << 32;
andrewboyson 0:faa09bd4e6bf 40
andrewboyson 1:5f70c361db20 41 return NetToHost64(timestamp);
andrewboyson 0:faa09bd4e6bf 42 }
andrewboyson 7:b794780e33b4 43 int NtpHandleRequest(int* pSize, void * pPacket)
andrewboyson 0:faa09bd4e6bf 44 {
andrewboyson 7:b794780e33b4 45 if (*pSize < HEADER_SIZE) return UDP_DO_NOTHING;
andrewboyson 0:faa09bd4e6bf 46
andrewboyson 0:faa09bd4e6bf 47 struct header* pHeader = (struct header*)pPacket;
andrewboyson 0:faa09bd4e6bf 48
andrewboyson 0:faa09bd4e6bf 49 switch (pHeader->Mode)
andrewboyson 0:faa09bd4e6bf 50 {
andrewboyson 0:faa09bd4e6bf 51 case CLIENT:
andrewboyson 0:faa09bd4e6bf 52 pHeader->Mode = SERVER;
andrewboyson 0:faa09bd4e6bf 53 pHeader->LI = 0;
andrewboyson 1:5f70c361db20 54 if (ClockStartNs) pHeader->Stratum = 1;
andrewboyson 0:faa09bd4e6bf 55 else pHeader->Stratum = 0;
andrewboyson 0:faa09bd4e6bf 56 pHeader->Poll = 0;
andrewboyson 0:faa09bd4e6bf 57 pHeader->Precision = 0;
andrewboyson 0:faa09bd4e6bf 58 pHeader->RootDelay = 0;
andrewboyson 0:faa09bd4e6bf 59 pHeader->Dispersion = 0;
andrewboyson 1:5f70c361db20 60 char* pRef;
andrewboyson 1:5f70c361db20 61 if (ClockStartNs)
andrewboyson 0:faa09bd4e6bf 62 {
andrewboyson 1:5f70c361db20 63 if (SyncedRate && SyncedTime) pRef = "GPS";
andrewboyson 1:5f70c361db20 64 else pRef = "LOCL";
andrewboyson 0:faa09bd4e6bf 65 }
andrewboyson 0:faa09bd4e6bf 66 else
andrewboyson 0:faa09bd4e6bf 67 {
andrewboyson 1:5f70c361db20 68 pRef = "INIT";
andrewboyson 0:faa09bd4e6bf 69 }
andrewboyson 1:5f70c361db20 70 pHeader->RefIdentifier[0] = pRef[0]; //For stratum 1 (reference clock), this is a four-octet, left-justified, zero-padded ASCII string.
andrewboyson 1:5f70c361db20 71 pHeader->RefIdentifier[1] = pRef[1];
andrewboyson 1:5f70c361db20 72 pHeader->RefIdentifier[2] = pRef[2];
andrewboyson 1:5f70c361db20 73 pHeader->RefIdentifier[3] = pRef[3];
andrewboyson 0:faa09bd4e6bf 74
andrewboyson 1:5f70c361db20 75 pHeader->RefTimeStamp = makeNtpTimeStamp(ClockStartNs);
andrewboyson 0:faa09bd4e6bf 76 pHeader->OriTimeStamp = pHeader->TraTimeStamp;
andrewboyson 1:5f70c361db20 77 pHeader->RecTimeStamp = makeNtpTimeStamp(ClockGetNs());
andrewboyson 1:5f70c361db20 78 pHeader->TraTimeStamp = makeNtpTimeStamp(ClockGetNs());
andrewboyson 7:b794780e33b4 79 *pSize = HEADER_SIZE;
andrewboyson 7:b794780e33b4 80 return UDP_UNICAST_PACKET;
andrewboyson 0:faa09bd4e6bf 81 default:
andrewboyson 4:31fa7d50722c 82 LogTimeF("\r\nNTP packet unknown\r\n");
andrewboyson 4:31fa7d50722c 83 LogTimeF("Mode %d\r\n", pHeader->Mode);
andrewboyson 4:31fa7d50722c 84 LogTimeF("Version %d\r\n", pHeader->VN);
andrewboyson 4:31fa7d50722c 85 LogTimeF("Stratum %d\r\n", pHeader->Stratum);
andrewboyson 4:31fa7d50722c 86 LogTimeF("Reference %4s\r\n", pHeader->RefIdentifier);
andrewboyson 0:faa09bd4e6bf 87 }
andrewboyson 7:b794780e33b4 88 return UDP_DO_NOTHING;
andrewboyson 0:faa09bd4e6bf 89 }