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
- Committer:
- okini3939
- Date:
- 2011-08-24
- Revision:
- 2:a3e5edf84f74
- Child:
- 3:058292da2cee
File content as of revision 2:a3e5edf84f74:
/* * mbed Tiny SNTP(NTP) Client * Copyright (c) 2011 Hiroshi Suga * Released under the MIT License: http://mbed.org/license/mit */ /** @file * @brief Tiny DNS Resolver */ #include "mbed.h" #include "EthernetNetIf.h" #include "UDPSocket.h" #include "DNSRequest.h" #include "TinySNTP.h" // host to network short #define htons( x ) ( (( (x) << 8 ) & 0xFF00) | (( (x) >> 8 ) & 0x00FF) ) #define ntohs( x ) htons(x) // host to network long #define htonl( x ) ( (( (x) << 24 ) & 0xFF000000) \ | (( (x) << 8 ) & 0x00FF0000) \ | (( (x) >> 8 ) & 0x0000FF00) \ | (( (x) >> 24 ) & 0x000000FF) ) #define ntohl( x ) htonl(x) static UDPSocket *sntp; static volatile unsigned long sntptime; extern EthernetNetIf eth; int createSntpRequest (char *buf) { struct SNTPPacket *sntp; sntp = (struct SNTPPacket *)buf; memset(sntp, 0, sizeof(struct SNTPPacket)); sntp->info = 0x1b; // Ver.3, client sntp->txTm_s = htonl(NTP_TIMESTAMP_DELTA + time(NULL)); return sizeof(struct SNTPPacket); } int getSntpResponse (const char *buf, uint32_t *tim) { struct SNTPPacket *sntp; uint32_t now; // long int delay, offset; sntp = (struct SNTPPacket *)buf; if ((sntp->info & 0x3f) == 0x1c || (sntp->info & 0x3f) == 0x24) { // Ver.3or4, Server now = htonl(NTP_TIMESTAMP_DELTA + time(NULL)); /* delay = (now - sntp->origTm_s) - (sntp->rxTm_s - sntp->txTm_s); offset = ((sntp->rxTm_s - sntp->origTm_s) + (sntp->txTm_s - now)); *tim = ntohl(sntp->txTm_s) - NTP_TIMESTAMP_DELTA + (delay / 2); */ *tim = ntohl(sntp->txTm_s) - NTP_TIMESTAMP_DELTA; #ifdef DEBUG printf("now %08x\r\n", ntohl(now)); printf("ref %08x\r\n", ntohl(sntp->refTm_s)); printf("orig %08x\r\n", ntohl(sntp->origTm_s)); printf("rx %08x\r\n", ntohl(sntp->rxTm_s)); printf("tx %08x\r\n", ntohl(sntp->txTm_s)); // printf("delay %d / offset %d\r\n", delay, offset); #endif return 0; } return -1; } void isr_sntp (UDPSocketEvent e) { char buf[100]; Host dsthost; int len; if (e == UDPSOCKET_READABLE) { // recv responce; len = sntp->recvfrom(buf, sizeof(buf), &dsthost); #ifdef DEBUG for (int i = 0; i < len; i ++) { printf(" %02x", (unsigned char)buf[i]); } puts("\r"); #endif if (len >= sizeof(struct SNTPPacket)) { getSntpResponse(buf, (uint32_t*)&sntptime); } } } int ntpdate (const char* name, uint32_t *tim) { UDPSocketErr err; Host sntphost; char buf[100]; int i, len; DNSRequest dns; DNSRequestErr dnsErr; sntptime = 0; sntp = new UDPSocket; sntp->setOnEvent(isr_sntp); // send request sntphost.setName(name); sntphost.setPort(NTP_PORT); dnsErr = dns.resolve(&sntphost); if (dnsErr != DNS_OK) goto exit; len = createSntpRequest(buf); #ifdef DEBUG for (int i = 0; i < len; i ++) { printf(" %02x", (unsigned char)buf[i]); } puts("\r"); #endif sntp->sendto(buf, len, &sntphost); // wait responce for (i = 0; i < NTP_TIMEOUT / 10; i ++) { if (sntptime) { *tim = sntptime; break; } if (i % 500 == 499) { sntp->sendto(buf, len, &sntphost); } Net::poll(); wait_ms(10); } exit: sntp->resetOnEvent(); delete sntp; return sntptime ? 0 : -1; }