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: w7500-paho-mqtt openHAB_mqtt_W7500 kakaoIoTchatbot w7500-RFID-mqtt
Fork of WIZnetInterface by
Revision 16:c830d2e7e0f5, committed 2015-06-24
- Comitter:
- eunkyoungkim
- Date:
- Wed Jun 24 02:27:46 2015 +0000
- Parent:
- 15:24a9f2df2145
- Commit message:
- Add SNTP Client
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket/NTPClient.cpp Wed Jun 24 02:27:46 2015 +0000
@@ -0,0 +1,163 @@
+/* NTPClient.cpp */
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+//Debug is disabled by default
+#if 0
+//Enable debug
+#define __DEBUG__
+#include <cstdio>
+#define DBG(x, ...) std::printf("[NTPClient : DBG]"x"\r\n", ##__VA_ARGS__);
+#define WARN(x, ...) std::printf("[NTPClient : WARN]"x"\r\n", ##__VA_ARGS__);
+#define ERR(x, ...) std::printf("[NTPClient : ERR]"x"\r\n", ##__VA_ARGS__);
+
+#else
+//Disable debug
+#define DBG(x, ...)
+#define WARN(x, ...)
+#define ERR(x, ...)
+
+#endif
+
+#include "NTPClient.h"
+
+#include "UDPSocket.h"
+
+#include "mbed.h" //time() and set_time()
+
+#define NTP_PORT 123
+#define NTP_CLIENT_PORT 0 //Random port
+#define NTP_TIMESTAMP_DELTA 2208988800ull //Diff btw a UNIX timestamp (Starting Jan, 1st 1970) and a NTP timestamp (Starting Jan, 1st 1900)
+
+NTPClient::NTPClient() : m_sock()
+{
+
+
+}
+
+NTPResult NTPClient::setTime(const char* host, uint16_t port, uint32_t timeout)
+{
+#ifdef __DEBUG__
+ time_t ctTime;
+ ctTime = time(NULL);
+ DBG("Time is set to (UTC): %s", ctime(&ctTime));
+#endif
+
+ //Create & bind socket
+ DBG("Binding socket");
+ m_sock.bind(0); //Bind to a random port
+
+ m_sock.set_blocking(false, timeout); //Set not blocking
+
+ struct NTPPacket pkt;
+
+ //Now ping the server and wait for response
+ DBG("Ping");
+ //Prepare NTP Packet:
+ pkt.li = 0; //Leap Indicator : No warning
+ pkt.vn = 4; //Version Number : 4
+ pkt.mode = 3; //Client mode
+ pkt.stratum = 0; //Not relevant here
+ pkt.poll = 0; //Not significant as well
+ pkt.precision = 0; //Neither this one is
+
+ pkt.rootDelay = 0; //Or this one
+ pkt.rootDispersion = 0; //Or that one
+ pkt.refId = 0; //...
+
+ pkt.refTm_s = 0;
+ pkt.origTm_s = 0;
+ pkt.rxTm_s = 0;
+ pkt.txTm_s = htonl( NTP_TIMESTAMP_DELTA + time(NULL) ); //WARN: We are in LE format, network byte order is BE
+
+ pkt.refTm_f = pkt.origTm_f = pkt.rxTm_f = pkt.txTm_f = 0;
+
+ Endpoint outEndpoint;
+
+ if( outEndpoint.set_address(host, port) < 0)
+ {
+ m_sock.close();
+ return NTP_DNS;
+ }
+
+ //Set timeout, non-blocking and wait using select
+ int ret = m_sock.sendTo( outEndpoint, (char*)&pkt, sizeof(NTPPacket) );
+ if (ret < 0 )
+ {
+ ERR("Could not send packet");
+ m_sock.close();
+ return NTP_CONN;
+ }
+
+ //Read response
+ Endpoint inEndpoint;
+
+ DBG("Pong");
+ do
+ {
+ ret = m_sock.receiveFrom( inEndpoint, (char*)&pkt, sizeof(NTPPacket) ); //FIXME need a DNS Resolver to actually compare the incoming address with the DNS name
+ if(ret < 0)
+ {
+ ERR("Could not receive packet");
+ m_sock.close();
+ return NTP_CONN;
+ }
+ } while( strcmp(outEndpoint.get_address(), inEndpoint.get_address()) != 0 );
+
+ if(ret < sizeof(NTPPacket)) //TODO: Accept chunks
+ {
+ ERR("Receive packet size does not match");
+ m_sock.close();
+ return NTP_PRTCL;
+ }
+
+ if( pkt.stratum == 0) //Kiss of death message : Not good !
+ {
+ ERR("Kissed to death!");
+ m_sock.close();
+ return NTP_PRTCL;
+ }
+
+ //Correct Endianness
+ pkt.refTm_s = ntohl( pkt.refTm_s );
+ pkt.refTm_f = ntohl( pkt.refTm_f );
+ pkt.origTm_s = ntohl( pkt.origTm_s );
+ pkt.origTm_f = ntohl( pkt.origTm_f );
+ pkt.rxTm_s = ntohl( pkt.rxTm_s );
+ pkt.rxTm_f = ntohl( pkt.rxTm_f );
+ pkt.txTm_s = ntohl( pkt.txTm_s );
+ pkt.txTm_f = ntohl( pkt.txTm_f );
+
+ //Compute offset, see RFC 4330 p.13
+ uint32_t destTm_s = (NTP_TIMESTAMP_DELTA + time(NULL));
+ int64_t offset = ( (int64_t)( pkt.rxTm_s - pkt.origTm_s ) + (int64_t) ( pkt.txTm_s - destTm_s ) ) / 2; //Avoid overflow
+ DBG("Sent @%ul", pkt.txTm_s);
+ DBG("Offset: %lld", offset);
+ //Set time accordingly
+ set_time( time(NULL) + offset );
+
+#ifdef __DEBUG__
+ ctTime = time(NULL);
+ DBG("Time is now (UTC): %s", ctime(&ctTime));
+#endif
+
+ m_sock.close();
+
+ return NTP_OK;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket/NTPClient.h Wed Jun 24 02:27:46 2015 +0000
@@ -0,0 +1,111 @@
+/* NTPClient.h */
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** \file
+NTP Client header file
+*/
+
+#ifndef NTPCLIENT_H_
+#define NTPCLIENT_H_
+
+#include <cstdint>
+
+using std::uint8_t;
+using std::uint16_t;
+using std::uint32_t;
+
+#include "UDPSocket.h"
+
+#define NTP_DEFAULT_PORT 123
+#define NTP_DEFAULT_TIMEOUT 4000
+
+///NTP client results
+enum NTPResult
+{
+ NTP_DNS, ///<Could not resolve name
+ NTP_PRTCL, ///<Protocol error
+ NTP_TIMEOUT, ///<Connection timeout
+ NTP_CONN, ///<Connection error
+ NTP_OK = 0, ///<Success
+};
+
+/** NTP Client to update the mbed's RTC using a remote time server
+*
+*/
+class NTPClient
+{
+public:
+ /**
+ Instantiate the NTP client
+ */
+ NTPClient();
+
+ /**Get current time (blocking)
+ Update the time using the server host
+ Blocks until completion
+ @param host NTP server IPv4 address or hostname (will be resolved via DNS)
+ @param port port to use; defaults to 123
+ @param timeout waiting timeout in ms (osWaitForever for blocking function, not recommended)
+ @return 0 on success, NTP error code (<0) on failure
+ */
+ NTPResult setTime(const char* host, uint16_t port = NTP_DEFAULT_PORT, uint32_t timeout = NTP_DEFAULT_TIMEOUT); //Blocking
+
+private:
+ struct NTPPacket //See RFC 4330 for Simple NTP
+ {
+ //WARN: We are in LE! Network is BE!
+ //LSb first
+ unsigned mode : 3;
+ unsigned vn : 3;
+ unsigned li : 2;
+
+ uint8_t stratum;
+ uint8_t poll;
+ uint8_t precision;
+ //32 bits header
+
+ uint32_t rootDelay;
+ uint32_t rootDispersion;
+ uint32_t refId;
+
+ uint32_t refTm_s;
+ uint32_t refTm_f;
+ uint32_t origTm_s;
+ uint32_t origTm_f;
+ uint32_t rxTm_s;
+ uint32_t rxTm_f;
+ uint32_t txTm_s;
+ uint32_t txTm_f;
+ } __attribute__ ((packed));
+
+ UDPSocket m_sock;
+
+};
+typedef struct _datetime
+{
+ uint16_t yy;
+ uint8_t mo;
+ uint8_t dd;
+ uint8_t hh;
+ uint8_t mm;
+ uint8_t ss;
+} datetime;
+
+
+#endif /* NTPCLIENT_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket/SNTPClient.cpp Wed Jun 24 02:27:46 2015 +0000
@@ -0,0 +1,428 @@
+#include "SNTPClient.h"
+
+#define MAX_TRY_WRITE 20
+#define MAX_TRY_READ 10
+
+//Debug is disabled by default
+#ifdef _SNTP_DEBUG_
+#define DBG(x, ...) std::printf("[SNTPClient : DBG]"x"\r\n", ##__VA_ARGS__);
+#define WARN(x, ...) std::printf("[SNTPClient : WARN]"x"\r\n", ##__VA_ARGS__);
+#define ERR(x, ...) std::printf("[SNTPClient : ERR]"x"\r\n", ##__VA_ARGS__);
+#else
+#define DBG(x, ...)
+#define WARN(x, ...)
+#define ERR(x, ...)
+#endif
+
+#define INFO(x, ...) printf("[SNTPClient : INFO]"x"\r\n", ##__VA_ARGS__);
+
+SNTPClient::SNTPClient(char * url, uint8_t time_zone) {
+ memcpy(host, url, strlen(url));
+ host[strlen(url)] = '\0';
+ port = ntp_port;
+ socket.set_blocking(false, 3000);
+
+ tz = time_zone;
+}
+
+bool SNTPClient::connect() {
+ socket.init();
+ socket.bind(0);
+ if(sntp_server.set_address(host, port) < 0)
+ return false;
+
+ uint32_t ip = str_to_ip(sntp_server.get_address());
+ NTPformat.dstaddr[0] = (uint8_t)(ip >> 24);
+ NTPformat.dstaddr[1] = (uint8_t)(ip >> 16);
+ NTPformat.dstaddr[2] = (uint8_t)(ip >> 8);
+ NTPformat.dstaddr[3] = (uint8_t)(ip >> 0);
+ DBG("NTP Server: %s\r\n", sntp_server.get_address());
+
+ uint8_t Flag;
+ NTPformat.leap = 0; /* leap indicator */
+ NTPformat.version = 4; /* version number */
+ NTPformat.mode = 3; /* mode */
+ NTPformat.stratum = 0; /* stratum */
+ NTPformat.poll = 0; /* poll interval */
+ NTPformat.precision = 0; /* precision */
+ NTPformat.rootdelay = 0; /* root delay */
+ NTPformat.rootdisp = 0; /* root dispersion */
+ NTPformat.refid = 0; /* reference ID */
+ NTPformat.reftime = 0; /* reference time */
+ NTPformat.org = 0; /* origin timestamp */
+ NTPformat.rec = 0; /* receive timestamp */
+ NTPformat.xmt = 1; /* transmit timestamp */
+
+ Flag = (NTPformat.leap<<6)+(NTPformat.version<<3)+NTPformat.mode; //one byte Flag
+ memcpy(ntpmessage,(void const*)(&Flag),1);
+
+ return true;
+}
+
+bool SNTPClient::getTime(datetime *time) {
+ uint16_t startindex = 40; //last 8-byte of data_buf[size is 48 byte] is xmt, so the startindex should be 40
+
+ socket.sendTo(sntp_server, (char *)ntpmessage, sizeof(ntpmessage));
+
+ char in_buffer[MAX_SNTP_BUF_SIZE];
+ int n = socket.receiveFrom(sntp_server, in_buffer, sizeof(in_buffer));
+
+ if(n <= 0)
+ return false;
+
+ get_seconds_from_ntp_server((uint8_t *)in_buffer,startindex);
+
+ time->yy = Nowdatetime.yy;
+ time->mo = Nowdatetime.mo;
+ time->dd = Nowdatetime.dd;
+ time->hh = Nowdatetime.hh;
+ time->mm = Nowdatetime.mm;
+ time->ss = Nowdatetime.ss;
+
+ return true;
+}
+
+bool SNTPClient::close() {
+ int ret = socket.close();
+ if (ret < 0) {
+ ERR("Could not close");
+ return false;
+ }
+ return true;
+}
+
+char* SNTPClient::getHost() {
+ return host;
+}
+
+/*
+00)UTC-12:00 Baker Island, Howland Island (both uninhabited)
+01) UTC-11:00 American Samoa, Samoa
+02) UTC-10:00 (Summer)French Polynesia (most), United States (Aleutian Islands, Hawaii)
+03) UTC-09:30 Marquesas Islands
+04) UTC-09:00 Gambier Islands;(Summer)United States (most of Alaska)
+05) UTC-08:00 (Summer)Canada (most of British Columbia), Mexico (Baja California)
+06) UTC-08:00 United States (California, most of Nevada, most of Oregon, Washington (state))
+07) UTC-07:00 Mexico (Sonora), United States (Arizona); (Summer)Canada (Alberta)
+08) UTC-07:00 Mexico (Chihuahua), United States (Colorado)
+09) UTC-06:00 Costa Rica, El Salvador, Ecuador (Galapagos Islands), Guatemala, Honduras
+10) UTC-06:00 Mexico (most), Nicaragua;(Summer)Canada (Manitoba, Saskatchewan), United States (Illinois, most of Texas)
+11) UTC-05:00 Colombia, Cuba, Ecuador (continental), Haiti, Jamaica, Panama, Peru
+12) UTC-05:00 (Summer)Canada (most of Ontario, most of Quebec)
+13) UTC-05:00 United States (most of Florida, Georgia, Massachusetts, most of Michigan, New York, North Carolina, Ohio, Washington D.C.)
+14) UTC-04:30 Venezuela
+15) UTC-04:00 Bolivia, Brazil (Amazonas), Chile (continental), Dominican Republic, Canada (Nova Scotia), Paraguay,
+16) UTC-04:00 Puerto Rico, Trinidad and Tobago
+17) UTC-03:30 Canada (Newfoundland)
+18) UTC-03:00 Argentina; (Summer) Brazil (Brasilia, Rio de Janeiro, Sao Paulo), most of Greenland, Uruguay
+19) UTC-02:00 Brazil (Fernando de Noronha), South Georgia and the South Sandwich Islands
+20) UTC-01:00 Portugal (Azores), Cape Verde
+21) UTC±00:00 Cote d'Ivoire, Faroe Islands, Ghana, Iceland, Senegal; (Summer) Ireland, Portugal (continental and Madeira)
+22) UTC±00:00 Spain (Canary Islands), Morocco, United Kingdom
+23) UTC+01:00 Angola, Cameroon, Nigeria, Tunisia; (Summer)Albania, Algeria, Austria, Belgium, Bosnia and Herzegovina,
+24) UTC+01:00 Spain (continental), Croatia, Czech Republic, Denmark, Germany, Hungary, Italy, Kinshasa, Kosovo,
+25) UTC+01:00 Macedonia, France (metropolitan), the Netherlands, Norway, Poland, Serbia, Slovakia, Slovenia, Sweden, Switzerland
+26) UTC+02:00 Libya, Egypt, Malawi, Mozambique, South Africa, Zambia, Zimbabwe, (Summer)Bulgaria, Cyprus, Estonia,
+27) UTC+02:00 Finland, Greece, Israel, Jordan, Latvia, Lebanon, Lithuania, Moldova, Palestine, Romania, Syria, Turkey, Ukraine
+28) UTC+03:00 Belarus, Djibouti, Eritrea, Ethiopia, Iraq, Kenya, Madagascar, Russia (Kaliningrad Oblast), Saudi Arabia,
+29) UTC+03:00 South Sudan, Sudan, Somalia, South Sudan, Tanzania, Uganda, Yemen
+30) UTC+03:30 (Summer)Iran
+31) UTC+04:00 Armenia, Azerbaijan, Georgia, Mauritius, Oman, Russia (European), Seychelles, United Arab Emirates
+32) UTC+04:30 Afghanistan
+33) UTC+05:00 Kazakhstan (West), Maldives, Pakistan, Uzbekistan
+34) UTC+05:30 India, Sri Lanka
+35) UTC+05:45 Nepal
+36) UTC+06:00 Kazakhstan (most), Bangladesh, Russia (Ural: Sverdlovsk Oblast, Chelyabinsk Oblast)
+37) UTC+06:30 Cocos Islands, Myanmar
+38) UTC+07:00 Jakarta, Russia (Novosibirsk Oblast), Thailand, Vietnam
+39) UTC+08:00 China, Hong Kong, Russia (Krasnoyarsk Krai), Malaysia, Philippines, Singapore, Taiwan, most of Mongolia, Western Australia
+40) UTC+09:00 Korea, East Timor, Russia (Irkutsk Oblast), Japan
+41) UTC+09:30 Australia (Northern Territory);(Summer)Australia (South Australia))
+42) UTC+10:00 Russia (Zabaykalsky Krai); (Summer)Australia (New South Wales, Queensland, Tasmania, Victoria)
+43) UTC+10:30 Lord Howe Island
+44) UTC+11:00 New Caledonia, Russia (Primorsky Krai), Solomon Islands
+45) UTC+11:30 Norfolk Island
+46) UTC+12:00 Fiji, Russia (Kamchatka Krai);(Summer)New Zealand
+47) UTC+12:45 (Summer)New Zealand
+48) UTC+13:00 Tonga
+49) UTC+14:00 Kiribati (Line Islands)
+*/
+void SNTPClient::get_seconds_from_ntp_server(uint8_t *buf, uint16_t idx)
+{
+ tstamp seconds = 0;
+ uint8_t i=0;
+ for (i = 0; i < 4; i++)
+ {
+ seconds = (seconds << 8) | buf[idx + i];
+ }
+ switch (tz) // Time Zone
+ {
+ case 0:
+ seconds -= 12*3600;
+ break;
+ case 1:
+ seconds -= 11*3600;
+ break;
+ case 2:
+ seconds -= 10*3600;
+ break;
+ case 3:
+ seconds -= (9*3600+30*60);
+ break;
+ case 4:
+ seconds -= 9*3600;
+ break;
+ case 5:
+ case 6:
+ seconds -= 8*3600;
+ break;
+ case 7:
+ case 8:
+ seconds -= 7*3600;
+ break;
+ case 9:
+ case 10:
+ seconds -= 6*3600;
+ break;
+ case 11:
+ case 12:
+ case 13:
+ seconds -= 5*3600;
+ break;
+ case 14:
+ seconds -= (4*3600+30*60);
+ break;
+ case 15:
+ case 16:
+ seconds -= 4*3600;
+ break;
+ case 17:
+ seconds -= (3*3600+30*60);
+ break;
+ case 18:
+ seconds -= 3*3600;
+ break;
+ case 19:
+ seconds -= 2*3600;
+ break;
+ case 20:
+ seconds -= 1*3600;
+ break;
+ case 21: //?
+ case 22:
+ break;
+ case 23:
+ case 24:
+ case 25:
+ seconds += 1*3600;
+ break;
+ case 26:
+ case 27:
+ seconds += 2*3600;
+ break;
+ case 28:
+ case 29:
+ seconds += 3*3600;
+ break;
+ case 30:
+ seconds += (3*3600+30*60);
+ break;
+ case 31:
+ seconds += 4*3600;
+ break;
+ case 32:
+ seconds += (4*3600+30*60);
+ break;
+ case 33:
+ seconds += 5*3600;
+ break;
+ case 34:
+ seconds += (5*3600+30*60);
+ break;
+ case 35:
+ seconds += (5*3600+45*60);
+ break;
+ case 36:
+ seconds += 6*3600;
+ break;
+ case 37:
+ seconds += (6*3600+30*60);
+ break;
+ case 38:
+ seconds += 7*3600;
+ break;
+ case 39:
+ seconds += 8*3600;
+ break;
+ case 40:
+ seconds += 9*3600;
+ break;
+ case 41:
+ seconds += (9*3600+30*60);
+ break;
+ case 42:
+ seconds += 10*3600;
+ break;
+ case 43:
+ seconds += (10*3600+30*60);
+ break;
+ case 44:
+ seconds += 11*3600;
+ break;
+ case 45:
+ seconds += (11*3600+30*60);
+ break;
+ case 46:
+ seconds += 12*3600;
+ break;
+ case 47:
+ seconds += (12*3600+45*60);
+ break;
+ case 48:
+ seconds += 13*3600;
+ break;
+ case 49:
+ seconds += 14*3600;
+ break;
+
+ }
+
+ //calculation for date
+ calcdatetime(seconds);
+}
+
+void SNTPClient::calcdatetime(tstamp seconds)
+{
+ uint8_t yf=0;
+ tstamp n=0,d=0,total_d=0,rz=0;
+ uint16_t y=0,r=0,yr=0;
+ signed long long yd=0;
+
+ n = seconds;
+ total_d = seconds/(SECS_PERDAY);
+ d=0;
+ uint32_t p_year_total_sec=SECS_PERDAY*365;
+ uint32_t r_year_total_sec=SECS_PERDAY*366;
+ while(n>=p_year_total_sec)
+ {
+ if((EPOCH+r)%400==0 || ((EPOCH+r)%100!=0 && (EPOCH+r)%4==0))
+ {
+ n = n -(r_year_total_sec);
+ d = d + 366;
+ }
+ else
+ {
+ n = n - (p_year_total_sec);
+ d = d + 365;
+ }
+ r+=1;
+ y+=1;
+
+ }
+
+ y += EPOCH;
+
+ Nowdatetime.yy = y;
+
+ yd=0;
+ yd = total_d - d;
+
+ yf=1;
+ while(yd>=28)
+ {
+
+ if(yf==1 || yf==3 || yf==5 || yf==7 || yf==8 || yf==10 || yf==12)
+ {
+ yd -= 31;
+ if(yd<0)break;
+ rz += 31;
+ }
+
+ if (yf==2)
+ {
+ if (y%400==0 || (y%100!=0 && y%4==0))
+ {
+ yd -= 29;
+ if(yd<0)break;
+ rz += 29;
+ }
+ else
+ {
+ yd -= 28;
+ if(yd<0)break;
+ rz += 28;
+ }
+ }
+ if(yf==4 || yf==6 || yf==9 || yf==11 )
+ {
+ yd -= 30;
+ if(yd<0)break;
+ rz += 30;
+ }
+ yf += 1;
+
+ }
+ Nowdatetime.mo=yf;
+ yr = total_d-d-rz;
+
+ yr += 1;
+
+ Nowdatetime.dd=yr;
+
+ //calculation for time
+ seconds = seconds%SECS_PERDAY;
+ Nowdatetime.hh = seconds/3600;
+ Nowdatetime.mm = (seconds%3600)/60;
+ Nowdatetime.ss = (seconds%3600)%60;
+
+}
+
+tstamp SNTPClient::changedatetime_to_seconds(void)
+{
+ tstamp seconds=0;
+ uint32_t total_day=0;
+ uint16_t i=0,run_year_cnt=0,l=0;
+
+ l = Nowdatetime.yy;//low
+
+
+ for(i=EPOCH;i<l;i++)
+ {
+ if((i%400==0) || ((i%100!=0) && (i%4==0)))
+ {
+ run_year_cnt += 1;
+ }
+ }
+
+ total_day=(l-EPOCH-run_year_cnt)*365+run_year_cnt*366;
+
+ for(i=1;i<=Nowdatetime.mo;i++)
+ {
+ if(i==5 || i==7 || i==10 || i==12)
+ {
+ total_day += 30;
+ }
+ if (i==3)
+ {
+ if (l%400==0 && l%100!=0 && l%4==0)
+ {
+ total_day += 29;
+ }
+ else
+ {
+ total_day += 28;
+ }
+ }
+ if(i==2 || i==4 || i==6 || i==8 || i==9 || i==11)
+ {
+ total_day += 31;
+ }
+ }
+
+ seconds = (total_day+Nowdatetime.dd-1)*24*3600;
+ seconds += Nowdatetime.ss;//seconds
+ seconds += Nowdatetime.mm*60;//minute
+ seconds += Nowdatetime.hh*3600;//hour
+
+ return seconds;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket/SNTPClient.h Wed Jun 24 02:27:46 2015 +0000
@@ -0,0 +1,180 @@
+/**
+* @author Raphael Kwon
+*
+* @section LICENSE
+*
+* Copyright (c) 2014 WIZnet Co., Ltd.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+*
+* @section DESCRIPTION
+* Simple Network Time Protocol Client
+*
+*/
+
+#ifndef SNTPCLIENT_H
+#define SNTPCLIENT_H
+
+#include "mbed.h"
+#include "UDPSocket.h"
+
+/*
+ * @brief Define it for Debug & Monitor DNS processing.
+ * @note
+ */
+//#define _SNTP_DEBUG_
+
+#define MAX_SNTP_BUF_SIZE sizeof(ntpformat) ///< maximum size of DNS buffer. */
+#define ntp_port 123 //ntp server port number
+#define SECS_PERDAY 86400UL // seconds in a day = 60*60*24
+#define UTC_ADJ_HRS 9 // SEOUL : GMT+9
+#define EPOCH 1900 // NTP start year
+
+/* for ntpclient */
+typedef signed char s_char;
+typedef unsigned long long tstamp;
+typedef unsigned int tdist;
+
+typedef struct _ntpformat
+{
+ uint8_t dstaddr[4]; /* destination (local) address */
+ char version; /* version number */
+ char leap; /* leap indicator */
+ char mode; /* mode */
+ char stratum; /* stratum */
+ char poll; /* poll interval */
+ s_char precision; /* precision */
+ tdist rootdelay; /* root delay */
+ tdist rootdisp; /* root dispersion */
+ char refid; /* reference ID */
+ tstamp reftime; /* reference time */
+ tstamp org; /* origin timestamp */
+ tstamp rec; /* receive timestamp */
+ tstamp xmt; /* transmit timestamp */
+} ntpformat;
+typedef struct _datetime
+{
+ int yy;
+ int mo;
+ int dd;
+ int hh;
+ int mm;
+ int ss;
+} datetime;
+/*
+typedef struct _datetime
+{
+ uint16_t yy;
+ uint8_t mo;
+ uint8_t dd;
+ uint8_t hh;
+ uint8_t mm;
+ uint8_t ss;
+} datetime;
+*/
+/** SNTPClient client Class.
+ *
+ * Example (ethernet network):
+ * @code
+ * #include "mbed.h"
+ * #include "EthernetInterface.h"
+ * #include "SNTPClient.h"
+ *
+ * int main() {
+ * EthernetInterface eth;
+ * eth.init(); //Use DHCP
+ * eth.connect();
+ * printf("IP Address is %s\n\r", eth.getIPAddress());
+ *
+ * SNTPClient ws("ws://sockets.mbed.org:443/ws/demo/rw");
+ * ws.connect();
+ *
+ * while (1) {
+ * int res = ws.send("SNTPClient Hello World!");
+ *
+ * if (ws.read(recv)) {
+ * printf("rcv: %s\r\n", recv);
+ * }
+ *
+ * wait(0.1);
+ * }
+ * }
+ * @endcode
+ */
+
+
+class SNTPClient
+{
+ public:
+ /**
+ * Constructor
+ *
+ * @param url The SNTPClient host
+ */
+ SNTPClient(char * url, uint8_t time_zone);
+
+ /**
+ * Connect to the SNTPClient url
+ *
+ *@return true if the connection is established, false otherwise
+ */
+ bool connect();
+
+ /**
+ * Read a SNTPClient message
+ *
+ * @param message pointer to the string to be read (null if drop frame)
+ *
+ * @return true if a SNTPClient frame has been read
+ */
+ bool getTime(datetime *time);
+
+ /**
+ * Close the SNTPClient connection
+ *
+ * @return true if the connection has been closed, false otherwise
+ */
+ bool close();
+
+ /*
+ * Accessor: get host from the SNTPClient url
+ *
+ * @return host
+ */
+ char* getHost();
+
+ private:
+
+ uint16_t port;
+ char host[32];
+
+ UDPSocket socket;
+ Endpoint sntp_server;
+
+ ntpformat NTPformat;
+ datetime Nowdatetime;
+ uint8_t ntpmessage[48];
+ uint8_t tz; // Time Zone
+
+ void get_seconds_from_ntp_server(uint8_t *buf, uint16_t idx);
+ tstamp changedatetime_to_seconds(void);
+ void calcdatetime(tstamp seconds);
+};
+
+#endif
