Simple sample that demonstrates reading the FXOS8700CQ accelerometer, convert the data to JSON and send to an Azure IoT Hub.

Dependencies:   azure_umqtt_c iothub_mqtt_transport mbed-rtos mbed wolfSSL Socket lwip-eth lwip-sys lwip

Committer:
markrad
Date:
Tue Apr 25 01:33:13 2017 +0000
Revision:
7:2564d95cbf81
Fix bug in NTP library. Clean up code some.

Who changed what in which revision?

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