mbed Weather Platform firmware http://mbed.org/users/okini3939/notebook/mbed-weather-platform-firmware/
Dependencies: ChaNFSSD EthernetNetIf I2CLEDDisp Agentbed ChaNFSUSB ILinterpreter mbed BMP085 WeatherMeters ConfigFile ChaNFS I2CLCD
TinyNet/TinySNTP.cpp@7:f7c98d836f81, 2012-03-15 (annotated)
- Committer:
- okini3939
- Date:
- Thu Mar 15 02:42:39 2012 +0000
- Revision:
- 7:f7c98d836f81
- Parent:
- 3:058292da2cee
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
okini3939 | 2:a3e5edf84f74 | 1 | /* |
okini3939 | 2:a3e5edf84f74 | 2 | * mbed Tiny SNTP(NTP) Client |
okini3939 | 2:a3e5edf84f74 | 3 | * Copyright (c) 2011 Hiroshi Suga |
okini3939 | 2:a3e5edf84f74 | 4 | * Released under the MIT License: http://mbed.org/license/mit |
okini3939 | 2:a3e5edf84f74 | 5 | */ |
okini3939 | 2:a3e5edf84f74 | 6 | |
okini3939 | 2:a3e5edf84f74 | 7 | /** @file |
okini3939 | 2:a3e5edf84f74 | 8 | * @brief Tiny DNS Resolver |
okini3939 | 2:a3e5edf84f74 | 9 | */ |
okini3939 | 2:a3e5edf84f74 | 10 | |
okini3939 | 2:a3e5edf84f74 | 11 | #include "mbed.h" |
okini3939 | 2:a3e5edf84f74 | 12 | #include "EthernetNetIf.h" |
okini3939 | 2:a3e5edf84f74 | 13 | #include "UDPSocket.h" |
okini3939 | 2:a3e5edf84f74 | 14 | #include "DNSRequest.h" |
okini3939 | 2:a3e5edf84f74 | 15 | #include "TinySNTP.h" |
okini3939 | 2:a3e5edf84f74 | 16 | |
okini3939 | 2:a3e5edf84f74 | 17 | // host to network short |
okini3939 | 2:a3e5edf84f74 | 18 | #define htons( x ) ( (( (x) << 8 ) & 0xFF00) | (( (x) >> 8 ) & 0x00FF) ) |
okini3939 | 2:a3e5edf84f74 | 19 | #define ntohs( x ) htons(x) |
okini3939 | 2:a3e5edf84f74 | 20 | // host to network long |
okini3939 | 2:a3e5edf84f74 | 21 | #define htonl( x ) ( (( (x) << 24 ) & 0xFF000000) \ |
okini3939 | 2:a3e5edf84f74 | 22 | | (( (x) << 8 ) & 0x00FF0000) \ |
okini3939 | 2:a3e5edf84f74 | 23 | | (( (x) >> 8 ) & 0x0000FF00) \ |
okini3939 | 2:a3e5edf84f74 | 24 | | (( (x) >> 24 ) & 0x000000FF) ) |
okini3939 | 2:a3e5edf84f74 | 25 | #define ntohl( x ) htonl(x) |
okini3939 | 2:a3e5edf84f74 | 26 | |
okini3939 | 2:a3e5edf84f74 | 27 | static UDPSocket *sntp; |
okini3939 | 2:a3e5edf84f74 | 28 | static volatile unsigned long sntptime; |
okini3939 | 2:a3e5edf84f74 | 29 | extern EthernetNetIf eth; |
okini3939 | 2:a3e5edf84f74 | 30 | |
okini3939 | 2:a3e5edf84f74 | 31 | int createSntpRequest (char *buf) { |
okini3939 | 2:a3e5edf84f74 | 32 | struct SNTPPacket *sntp; |
okini3939 | 2:a3e5edf84f74 | 33 | |
okini3939 | 2:a3e5edf84f74 | 34 | sntp = (struct SNTPPacket *)buf; |
okini3939 | 2:a3e5edf84f74 | 35 | memset(sntp, 0, sizeof(struct SNTPPacket)); |
okini3939 | 2:a3e5edf84f74 | 36 | sntp->info = 0x1b; // Ver.3, client |
okini3939 | 2:a3e5edf84f74 | 37 | sntp->txTm_s = htonl(NTP_TIMESTAMP_DELTA + time(NULL)); |
okini3939 | 2:a3e5edf84f74 | 38 | |
okini3939 | 2:a3e5edf84f74 | 39 | return sizeof(struct SNTPPacket); |
okini3939 | 2:a3e5edf84f74 | 40 | } |
okini3939 | 2:a3e5edf84f74 | 41 | |
okini3939 | 2:a3e5edf84f74 | 42 | int getSntpResponse (const char *buf, uint32_t *tim) { |
okini3939 | 2:a3e5edf84f74 | 43 | struct SNTPPacket *sntp; |
okini3939 | 7:f7c98d836f81 | 44 | // uint32_t now; |
okini3939 | 2:a3e5edf84f74 | 45 | // long int delay, offset; |
okini3939 | 2:a3e5edf84f74 | 46 | |
okini3939 | 2:a3e5edf84f74 | 47 | sntp = (struct SNTPPacket *)buf; |
okini3939 | 2:a3e5edf84f74 | 48 | if ((sntp->info & 0x3f) == 0x1c || (sntp->info & 0x3f) == 0x24) { |
okini3939 | 2:a3e5edf84f74 | 49 | // Ver.3or4, Server |
okini3939 | 2:a3e5edf84f74 | 50 | |
okini3939 | 7:f7c98d836f81 | 51 | /* |
okini3939 | 2:a3e5edf84f74 | 52 | now = htonl(NTP_TIMESTAMP_DELTA + time(NULL)); |
okini3939 | 2:a3e5edf84f74 | 53 | delay = (now - sntp->origTm_s) - (sntp->rxTm_s - sntp->txTm_s); |
okini3939 | 2:a3e5edf84f74 | 54 | offset = ((sntp->rxTm_s - sntp->origTm_s) + (sntp->txTm_s - now)); |
okini3939 | 2:a3e5edf84f74 | 55 | |
okini3939 | 2:a3e5edf84f74 | 56 | *tim = ntohl(sntp->txTm_s) - NTP_TIMESTAMP_DELTA + (delay / 2); |
okini3939 | 2:a3e5edf84f74 | 57 | */ |
okini3939 | 2:a3e5edf84f74 | 58 | *tim = ntohl(sntp->txTm_s) - NTP_TIMESTAMP_DELTA; |
okini3939 | 2:a3e5edf84f74 | 59 | #ifdef DEBUG |
okini3939 | 2:a3e5edf84f74 | 60 | printf("now %08x\r\n", ntohl(now)); |
okini3939 | 2:a3e5edf84f74 | 61 | printf("ref %08x\r\n", ntohl(sntp->refTm_s)); |
okini3939 | 2:a3e5edf84f74 | 62 | printf("orig %08x\r\n", ntohl(sntp->origTm_s)); |
okini3939 | 2:a3e5edf84f74 | 63 | printf("rx %08x\r\n", ntohl(sntp->rxTm_s)); |
okini3939 | 2:a3e5edf84f74 | 64 | printf("tx %08x\r\n", ntohl(sntp->txTm_s)); |
okini3939 | 2:a3e5edf84f74 | 65 | // printf("delay %d / offset %d\r\n", delay, offset); |
okini3939 | 2:a3e5edf84f74 | 66 | #endif |
okini3939 | 2:a3e5edf84f74 | 67 | return 0; |
okini3939 | 2:a3e5edf84f74 | 68 | } |
okini3939 | 2:a3e5edf84f74 | 69 | |
okini3939 | 2:a3e5edf84f74 | 70 | return -1; |
okini3939 | 2:a3e5edf84f74 | 71 | } |
okini3939 | 2:a3e5edf84f74 | 72 | |
okini3939 | 2:a3e5edf84f74 | 73 | void isr_sntp (UDPSocketEvent e) { |
okini3939 | 7:f7c98d836f81 | 74 | char buf[200]; |
okini3939 | 2:a3e5edf84f74 | 75 | Host dsthost; |
okini3939 | 2:a3e5edf84f74 | 76 | int len; |
okini3939 | 2:a3e5edf84f74 | 77 | |
okini3939 | 2:a3e5edf84f74 | 78 | if (e == UDPSOCKET_READABLE) { |
okini3939 | 2:a3e5edf84f74 | 79 | // recv responce; |
okini3939 | 2:a3e5edf84f74 | 80 | len = sntp->recvfrom(buf, sizeof(buf), &dsthost); |
okini3939 | 2:a3e5edf84f74 | 81 | #ifdef DEBUG |
okini3939 | 2:a3e5edf84f74 | 82 | for (int i = 0; i < len; i ++) { |
okini3939 | 2:a3e5edf84f74 | 83 | printf(" %02x", (unsigned char)buf[i]); |
okini3939 | 2:a3e5edf84f74 | 84 | } |
okini3939 | 2:a3e5edf84f74 | 85 | puts("\r"); |
okini3939 | 2:a3e5edf84f74 | 86 | #endif |
okini3939 | 7:f7c98d836f81 | 87 | if (len >= sizeof(struct SNTPPacket) && ! sntptime) { |
okini3939 | 2:a3e5edf84f74 | 88 | getSntpResponse(buf, (uint32_t*)&sntptime); |
okini3939 | 2:a3e5edf84f74 | 89 | } |
okini3939 | 2:a3e5edf84f74 | 90 | } |
okini3939 | 2:a3e5edf84f74 | 91 | } |
okini3939 | 2:a3e5edf84f74 | 92 | |
okini3939 | 2:a3e5edf84f74 | 93 | int ntpdate (const char* name, uint32_t *tim) { |
okini3939 | 3:058292da2cee | 94 | // UDPSocketErr err; |
okini3939 | 2:a3e5edf84f74 | 95 | Host sntphost; |
okini3939 | 2:a3e5edf84f74 | 96 | char buf[100]; |
okini3939 | 2:a3e5edf84f74 | 97 | int i, len; |
okini3939 | 2:a3e5edf84f74 | 98 | DNSRequest dns; |
okini3939 | 2:a3e5edf84f74 | 99 | DNSRequestErr dnsErr; |
okini3939 | 2:a3e5edf84f74 | 100 | |
okini3939 | 2:a3e5edf84f74 | 101 | sntptime = 0; |
okini3939 | 2:a3e5edf84f74 | 102 | sntp = new UDPSocket; |
okini3939 | 2:a3e5edf84f74 | 103 | sntp->setOnEvent(isr_sntp); |
okini3939 | 2:a3e5edf84f74 | 104 | |
okini3939 | 2:a3e5edf84f74 | 105 | // send request |
okini3939 | 2:a3e5edf84f74 | 106 | sntphost.setName(name); |
okini3939 | 2:a3e5edf84f74 | 107 | sntphost.setPort(NTP_PORT); |
okini3939 | 2:a3e5edf84f74 | 108 | dnsErr = dns.resolve(&sntphost); |
okini3939 | 2:a3e5edf84f74 | 109 | if (dnsErr != DNS_OK) goto exit; |
okini3939 | 2:a3e5edf84f74 | 110 | len = createSntpRequest(buf); |
okini3939 | 2:a3e5edf84f74 | 111 | #ifdef DEBUG |
okini3939 | 2:a3e5edf84f74 | 112 | for (int i = 0; i < len; i ++) { |
okini3939 | 2:a3e5edf84f74 | 113 | printf(" %02x", (unsigned char)buf[i]); |
okini3939 | 2:a3e5edf84f74 | 114 | } |
okini3939 | 2:a3e5edf84f74 | 115 | puts("\r"); |
okini3939 | 2:a3e5edf84f74 | 116 | #endif |
okini3939 | 2:a3e5edf84f74 | 117 | sntp->sendto(buf, len, &sntphost); |
okini3939 | 2:a3e5edf84f74 | 118 | |
okini3939 | 2:a3e5edf84f74 | 119 | // wait responce |
okini3939 | 2:a3e5edf84f74 | 120 | for (i = 0; i < NTP_TIMEOUT / 10; i ++) { |
okini3939 | 2:a3e5edf84f74 | 121 | if (sntptime) { |
okini3939 | 2:a3e5edf84f74 | 122 | *tim = sntptime; |
okini3939 | 7:f7c98d836f81 | 123 | Net::poll(); |
okini3939 | 7:f7c98d836f81 | 124 | wait_ms(10); |
okini3939 | 7:f7c98d836f81 | 125 | Net::poll(); |
okini3939 | 2:a3e5edf84f74 | 126 | break; |
okini3939 | 2:a3e5edf84f74 | 127 | } |
okini3939 | 2:a3e5edf84f74 | 128 | if (i % 500 == 499) { |
okini3939 | 2:a3e5edf84f74 | 129 | sntp->sendto(buf, len, &sntphost); |
okini3939 | 2:a3e5edf84f74 | 130 | } |
okini3939 | 2:a3e5edf84f74 | 131 | Net::poll(); |
okini3939 | 2:a3e5edf84f74 | 132 | wait_ms(10); |
okini3939 | 2:a3e5edf84f74 | 133 | } |
okini3939 | 2:a3e5edf84f74 | 134 | |
okini3939 | 2:a3e5edf84f74 | 135 | exit: |
okini3939 | 2:a3e5edf84f74 | 136 | sntp->resetOnEvent(); |
okini3939 | 7:f7c98d836f81 | 137 | sntp->close(); |
okini3939 | 2:a3e5edf84f74 | 138 | delete sntp; |
okini3939 | 2:a3e5edf84f74 | 139 | |
okini3939 | 2:a3e5edf84f74 | 140 | return sntptime ? 0 : -1; |
okini3939 | 2:a3e5edf84f74 | 141 | } |