Skip to content

Encapsulate provision of time within one single object #92

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 4 additions & 21 deletions src/ArduinoIoTCloudTCP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,14 @@

#ifdef HAS_TCP
#include <ArduinoIoTCloudTCP.h>
#include "utility/time/TimeService.h"
#ifdef BOARD_HAS_ECCX08
#include "utility/ECCX08Cert.h"
#include "utility/BearSSLTrustAnchor.h"
#include <ArduinoECCX08.h>
#endif

#ifdef ARDUINO_ARCH_SAMD
#include <RTCZero.h>
RTCZero rtc;
#endif
TimeService time_service;

#ifdef BOARD_HAS_ECCX08
const static int keySlot = 0;
Expand All @@ -41,20 +39,7 @@ const static int CONNECT_FAILURE = 0;
const static int CONNECT_FAILURE_SUBSCRIBE = -1;

static unsigned long getTime() {
if (!ArduinoCloud.getConnection()) {
return 0;
}
TcpIpConnectionHandler * connection = ArduinoCloud.getConnection();
unsigned long time = connection->getTime();
Debug.print(DBG_DEBUG, "NTP time: %lu", time);
if (!NTPUtils::isTimeValid(time)) {
Debug.print(DBG_ERROR, "Bogus NTP time from API, fallback to UDP method");
time = NTPUtils(connection->getUDP()).getTime();
}
#ifdef ARDUINO_ARCH_SAMD
rtc.setEpoch(time);
#endif
return time;
return time_service.getTime();
}

ArduinoIoTCloudTCP::ArduinoIoTCloudTCP():
Expand Down Expand Up @@ -92,9 +77,7 @@ int ArduinoIoTCloudTCP::begin(TcpIpConnectionHandler & connection, String broker
_connection = &connection;
_brokerAddress = brokerAddress;
_brokerPort = brokerPort;
#ifdef ARDUINO_ARCH_SAMD
rtc.begin();
#endif
time_service.begin(&connection);
return begin(_connection->getClient(), _brokerAddress, _brokerPort);
}

Expand Down
2 changes: 0 additions & 2 deletions src/ArduinoIoTCloudTCP.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@

#include <ArduinoMqttClient.h>

#include "utility/NTPUtils.h"


static char const DEFAULT_BROKER_ADDRESS_SECURE_AUTH[] = "mqtts-sa.iot.arduino.cc";
static uint16_t const DEFAULT_BROKER_PORT_SECURE_AUTH = 8883;
Expand Down
83 changes: 0 additions & 83 deletions src/utility/NTPUtils.cpp

This file was deleted.

23 changes: 0 additions & 23 deletions src/utility/NTPUtils.h

This file was deleted.

86 changes: 86 additions & 0 deletions src/utility/time/NTPUtils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
This file is part of ArduinoIoTCloud.

Copyright 2020 ARDUINO SA (http://www.arduino.cc/)

This software is released under the GNU General Public License version 3,
which covers the main part of arduino-cli.
The terms of this license can be found at:
https://www.gnu.org/licenses/gpl-3.0.en.html

You can be released from the requirements of the above licenses by purchasing
a commercial license. Buying such a license is mandatory if you want to modify or
otherwise use the software for commercial activities involving the Arduino
software without disclosing the source code of your own applications. To purchase
a commercial license, send an email to [email protected].
*/

/**************************************************************************************
* INCLUDE
**************************************************************************************/

#include "../../ArduinoIoTCloud_Defines.h"
#ifndef HAS_LORA

#include "NTPUtils.h"

#include <Arduino.h>

/**************************************************************************************
* PUBLIC MEMBER FUNCTIONS
**************************************************************************************/

unsigned long NTPUtils::getTime(UDP & udp)
{
udp.begin(NTP_LOCAL_PORT);

sendNTPpacket(udp);

bool is_timeout = false;
unsigned long const start = millis();
do
{
is_timeout = (millis() - start) >= NTP_TIMEOUT_MS;
} while(!is_timeout && !udp.parsePacket());

if(is_timeout) {
udp.stop();
return 0;
}

uint8_t ntp_packet_buf[NTP_PACKET_SIZE];
udp.read(ntp_packet_buf, NTP_PACKET_SIZE);
udp.stop();

unsigned long const highWord = word(ntp_packet_buf[40], ntp_packet_buf[41]);
unsigned long const lowWord = word(ntp_packet_buf[42], ntp_packet_buf[43]);
unsigned long const secsSince1900 = highWord << 16 | lowWord;
unsigned long const seventyYears = 2208988800UL;
unsigned long const epoch = secsSince1900 - seventyYears;

return epoch;
}

/**************************************************************************************
* PRIVATE MEMBER FUNCTIONS
**************************************************************************************/

void NTPUtils::sendNTPpacket(UDP & udp)
{
uint8_t ntp_packet_buf[NTP_PACKET_SIZE] = {0};

ntp_packet_buf[0] = 0b11100011;
ntp_packet_buf[1] = 0;
ntp_packet_buf[2] = 6;
ntp_packet_buf[3] = 0xEC;
ntp_packet_buf[12] = 49;
ntp_packet_buf[13] = 0x4E;
ntp_packet_buf[14] = 49;
ntp_packet_buf[15] = 52;

udp.beginPacket(NTP_TIME_SERVER, NTP_TIME_SERVER_PORT);
udp.write(ntp_packet_buf, NTP_PACKET_SIZE);
udp.endPacket();
}

#endif /* #ifndef HAS_LORA */
59 changes: 59 additions & 0 deletions src/utility/time/NTPUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
This file is part of ArduinoIoTCloud.

Copyright 2020 ARDUINO SA (http://www.arduino.cc/)

This software is released under the GNU General Public License version 3,
which covers the main part of arduino-cli.
The terms of this license can be found at:
https://www.gnu.org/licenses/gpl-3.0.en.html

You can be released from the requirements of the above licenses by purchasing
a commercial license. Buying such a license is mandatory if you want to modify or
otherwise use the software for commercial activities involving the Arduino
software without disclosing the source code of your own applications. To purchase
a commercial license, send an email to [email protected].
*/

#ifndef __NTP_UTILS__
#define __NTP_UTILS__

#include "../../ArduinoIoTCloud_Defines.h"
#ifndef HAS_LORA

/*
This Utility Class is derived from the example code found here https://www.arduino.cc/en/Tutorial/UdpNTPClient
For more information on NTP (Network Time Protocol) you can refer to this Wikipedia article https://en.wikipedia.org/wiki/Network_Time_Protocol
*/

/**************************************************************************************
* INCLUDE
**************************************************************************************/

#include <Udp.h>

/**************************************************************************************
* CLASS DECLARATION
**************************************************************************************/

class NTPUtils
{
public:

static unsigned long getTime(UDP & udp);

private:

static size_t const NTP_PACKET_SIZE = 48;
static int const NTP_TIME_SERVER_PORT = 123;
static int const NTP_LOCAL_PORT = 8888;
static unsigned long const NTP_TIMEOUT_MS = 1000;
static char constexpr * NTP_TIME_SERVER = "time.arduino.cc";

static void sendNTPpacket(UDP & udp);

};

#endif /* #ifndef HAS_LORA */

#endif
Loading