fork from simple sample of mqtt

Dependencies:   azure_c_shared_utility azure_umqtt_c iothub_client iothub_mqtt_transport serializer wolfSSL

Fork of simplesample_mqtt by Azure IoT

Committer:
lrh
Date:
Tue Feb 07 07:56:36 2017 +0000
Revision:
32:27328e208674
test1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lrh 32:27328e208674 1 /* NTPClient.cpp */
lrh 32:27328e208674 2 /* Copyright (C) 2012 mbed.org, MIT License
lrh 32:27328e208674 3 *
lrh 32:27328e208674 4 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
lrh 32:27328e208674 5 * and associated documentation files (the "Software"), to deal in the Software without restriction,
lrh 32:27328e208674 6 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
lrh 32:27328e208674 7 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
lrh 32:27328e208674 8 * furnished to do so, subject to the following conditions:
lrh 32:27328e208674 9 *
lrh 32:27328e208674 10 * The above copyright notice and this permission notice shall be included in all copies or
lrh 32:27328e208674 11 * substantial portions of the Software.
lrh 32:27328e208674 12 *
lrh 32:27328e208674 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
lrh 32:27328e208674 14 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
lrh 32:27328e208674 15 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
lrh 32:27328e208674 16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
lrh 32:27328e208674 17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
lrh 32:27328e208674 18 */
lrh 32:27328e208674 19
lrh 32:27328e208674 20 //Debug is disabled by default
lrh 32:27328e208674 21 #if 1
lrh 32:27328e208674 22 //Enable debug
lrh 32:27328e208674 23 #define __DEBUG__
lrh 32:27328e208674 24 #include <cstdio>
lrh 32:27328e208674 25 #define DBG(x, ...) std::printf("[NTPClient : DBG]"x"\r\n", ##__VA_ARGS__);
lrh 32:27328e208674 26 #define WARN(x, ...) std::printf("[NTPClient : WARN]"x"\r\n", ##__VA_ARGS__);
lrh 32:27328e208674 27 #define ERR(x, ...) std::printf("[NTPClient : ERR]"x"\r\n", ##__VA_ARGS__);
lrh 32:27328e208674 28
lrh 32:27328e208674 29 #else
lrh 32:27328e208674 30 //Disable debug
lrh 32:27328e208674 31 #define DBG(x, ...)
lrh 32:27328e208674 32 #define WARN(x, ...)
lrh 32:27328e208674 33 #define ERR(x, ...)
lrh 32:27328e208674 34
lrh 32:27328e208674 35 #endif
lrh 32:27328e208674 36
lrh 32:27328e208674 37 #include "NTPClient.h"
lrh 32:27328e208674 38 #include "UDPSocket.h"
lrh 32:27328e208674 39 #include "EthernetInterface.h"
lrh 32:27328e208674 40 #include "mbed.h" //time() and set_time()
lrh 32:27328e208674 41
lrh 32:27328e208674 42 #define NTP_PORT 123
lrh 32:27328e208674 43 #define NTP_CLIENT_PORT 0 //Random port
lrh 32:27328e208674 44 #define NTP_TIMESTAMP_DELTA 2208988800ull //Diff btw a UNIX timestamp (Starting Jan, 1st 1970) and a NTP timestamp (Starting Jan, 1st 1900)
lrh 32:27328e208674 45
lrh 32:27328e208674 46 NTPClient::NTPClient()
lrh 32:27328e208674 47 {
lrh 32:27328e208674 48
lrh 32:27328e208674 49 }
lrh 32:27328e208674 50
lrh 32:27328e208674 51 NTPResult NTPClient::setTime(const char* host, uint16_t port, uint32_t timeout)
lrh 32:27328e208674 52 {
lrh 32:27328e208674 53
lrh 32:27328e208674 54 DBG("start to create socket");
lrh 32:27328e208674 55 EthernetInterface eth;
lrh 32:27328e208674 56 eth.connect();
lrh 32:27328e208674 57 if(m_sock.open(&eth)!=0)
lrh 32:27328e208674 58 {
lrh 32:27328e208674 59 DBG("unable to create socket");;
lrh 32:27328e208674 60 }
lrh 32:27328e208674 61
lrh 32:27328e208674 62 #ifdef __DEBUG__
lrh 32:27328e208674 63 time_t ctTime;
lrh 32:27328e208674 64 ctTime = time(NULL);
lrh 32:27328e208674 65 DBG("Time is set to (UTC): %s", ctime(&ctTime));
lrh 32:27328e208674 66 #endif
lrh 32:27328e208674 67
lrh 32:27328e208674 68 //Create & bind socket
lrh 32:27328e208674 69 DBG("Binding socket");
lrh 32:27328e208674 70
lrh 32:27328e208674 71 m_sock.set_blocking(false);
lrh 32:27328e208674 72 m_sock.set_timeout(timeout);
lrh 32:27328e208674 73
lrh 32:27328e208674 74 struct NTPPacket pkt;
lrh 32:27328e208674 75 SocketAddress sendAddress(host,port);
lrh 32:27328e208674 76 if(eth.gethostbyname(host, &sendAddress)!= 0)
lrh 32:27328e208674 77 {
lrh 32:27328e208674 78 printf("UNABLE TO GET THE HOST");
lrh 32:27328e208674 79 m_sock.close();
lrh 32:27328e208674 80 return NTP_DNS;
lrh 32:27328e208674 81 }
lrh 32:27328e208674 82
lrh 32:27328e208674 83 const char *ip = sendAddress.get_ip_address();
lrh 32:27328e208674 84 printf("IP address is: %s\n", ip ? ip : "No IP");
lrh 32:27328e208674 85
lrh 32:27328e208674 86 //Now ping the server and wait for response
lrh 32:27328e208674 87 DBG("Ping");
lrh 32:27328e208674 88 //Prepare NTP Packet:
lrh 32:27328e208674 89 pkt.li = 0; //Leap Indicator : No warning
lrh 32:27328e208674 90 pkt.vn = 4; //Version Number : 4
lrh 32:27328e208674 91 pkt.mode = 3; //Client mode
lrh 32:27328e208674 92 pkt.stratum = 0; //Not relevant here
lrh 32:27328e208674 93 pkt.poll = 0; //Not significant as well
lrh 32:27328e208674 94 pkt.precision = 0; //Neither this one is
lrh 32:27328e208674 95
lrh 32:27328e208674 96 pkt.rootDelay = 0; //Or this one
lrh 32:27328e208674 97 pkt.rootDispersion = 0; //Or that one
lrh 32:27328e208674 98 pkt.refId = 0; //...
lrh 32:27328e208674 99
lrh 32:27328e208674 100 pkt.refTm_s = 0;
lrh 32:27328e208674 101 pkt.origTm_s = 0;
lrh 32:27328e208674 102 pkt.rxTm_s = 0;
lrh 32:27328e208674 103 pkt.txTm_s = htonl( NTP_TIMESTAMP_DELTA + time(NULL) ); //WARN: We are in LE format, network byte order is BE
lrh 32:27328e208674 104
lrh 32:27328e208674 105 pkt.refTm_f = pkt.origTm_f = pkt.rxTm_f = pkt.txTm_f = 0;
lrh 32:27328e208674 106
lrh 32:27328e208674 107
lrh 32:27328e208674 108
lrh 32:27328e208674 109 //Set timeout, non-blocking and wait using select
lrh 32:27328e208674 110 int ret = m_sock.sendto( sendAddress, (char*)&pkt, sizeof(NTPPacket) );
lrh 32:27328e208674 111 if (ret < 0 )
lrh 32:27328e208674 112 {
lrh 32:27328e208674 113 ERR("Could not send packet");
lrh 32:27328e208674 114 m_sock.close();
lrh 32:27328e208674 115 return NTP_CONN;
lrh 32:27328e208674 116 }
lrh 32:27328e208674 117
lrh 32:27328e208674 118 DBG("Pong");
lrh 32:27328e208674 119 //Read response
lrh 32:27328e208674 120 SocketAddress recvAddress;
lrh 32:27328e208674 121 recvAddress.set_ip_address(sendAddress.get_ip_address());
lrh 32:27328e208674 122 recvAddress.set_port(port);
lrh 32:27328e208674 123
lrh 32:27328e208674 124 //do
lrh 32:27328e208674 125 //{
lrh 32:27328e208674 126 ret = m_sock.recvfrom( &recvAddress, (char*)&pkt, sizeof(NTPPacket) ); //FIXME need a DNS Resolver to actually compare the incoming address with the DNS name
lrh 32:27328e208674 127 if(ret < 0)
lrh 32:27328e208674 128 {
lrh 32:27328e208674 129 ERR("Could not receive packet");
lrh 32:27328e208674 130 m_sock.close();
lrh 32:27328e208674 131 return NTP_CONN;
lrh 32:27328e208674 132 }
lrh 32:27328e208674 133 //} while( strcmp(sendAddress.get_ip_address(), recvAddress.get_ip_address()) != 0 );
lrh 32:27328e208674 134
lrh 32:27328e208674 135 if(ret < sizeof(NTPPacket)) //TODO: Accept chunks
lrh 32:27328e208674 136 {
lrh 32:27328e208674 137 ERR("Receive packet size does not match");
lrh 32:27328e208674 138 m_sock.close();
lrh 32:27328e208674 139 return NTP_PRTCL;
lrh 32:27328e208674 140 }
lrh 32:27328e208674 141
lrh 32:27328e208674 142 if( pkt.stratum == 0) //Kiss of death message : Not good !
lrh 32:27328e208674 143 {
lrh 32:27328e208674 144 ERR("Kissed to death!");
lrh 32:27328e208674 145 m_sock.close();
lrh 32:27328e208674 146 return NTP_PRTCL;
lrh 32:27328e208674 147 }
lrh 32:27328e208674 148
lrh 32:27328e208674 149 //Correct Endianness
lrh 32:27328e208674 150 pkt.refTm_s = ntohl( pkt.refTm_s );
lrh 32:27328e208674 151 pkt.refTm_f = ntohl( pkt.refTm_f );
lrh 32:27328e208674 152 pkt.origTm_s = ntohl( pkt.origTm_s );
lrh 32:27328e208674 153 pkt.origTm_f = ntohl( pkt.origTm_f );
lrh 32:27328e208674 154 pkt.rxTm_s = ntohl( pkt.rxTm_s );
lrh 32:27328e208674 155 pkt.rxTm_f = ntohl( pkt.rxTm_f );
lrh 32:27328e208674 156 pkt.txTm_s = ntohl( pkt.txTm_s );
lrh 32:27328e208674 157 pkt.txTm_f = ntohl( pkt.txTm_f );
lrh 32:27328e208674 158
lrh 32:27328e208674 159 //Compute offset, see RFC 4330 p.13
lrh 32:27328e208674 160 uint32_t destTm_s = (NTP_TIMESTAMP_DELTA + time(NULL));
lrh 32:27328e208674 161 int64_t offset = ( (int64_t)( pkt.rxTm_s - pkt.origTm_s ) + (int64_t) ( pkt.txTm_s - destTm_s ) ) / 2; //Avoid overflow
lrh 32:27328e208674 162 DBG("Sent @%ul", pkt.txTm_s);
lrh 32:27328e208674 163 DBG("Offset: %lld", offset);
lrh 32:27328e208674 164 //Set time accordingly
lrh 32:27328e208674 165 set_time( time(NULL) + offset );
lrh 32:27328e208674 166
lrh 32:27328e208674 167 #ifdef __DEBUG__
lrh 32:27328e208674 168 ctTime = time(NULL);
lrh 32:27328e208674 169 DBG("Time is now (UTC): %s", ctime(&ctTime));
lrh 32:27328e208674 170 #endif
lrh 32:27328e208674 171
lrh 32:27328e208674 172 m_sock.close();
lrh 32:27328e208674 173
lrh 32:27328e208674 174 return NTP_OK;
lrh 32:27328e208674 175 }
lrh 32:27328e208674 176