Skip to content

Add GSM and Ethernet conn_manager + add fallback UDP based getTime() #31

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 23 commits into from
Feb 26, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
db14c67
GSM: implement full state machine
facchinm Feb 12, 2019
68d2c3c
GSM: add fallback getTime retrieve
facchinm Feb 12, 2019
1324ac6
Merge branch 'master' into gsm_proper_connmanager
facchinm Feb 13, 2019
19c688e
Create NTP util class to handle getTime() fallback
facchinm Feb 13, 2019
e0abeb8
Restructure GSM connection manager
facchinm Feb 13, 2019
75ddfcc
Automatically handle getTime fallback in IoTCloud class
facchinm Feb 13, 2019
da7179b
Add EthernetConnectionManager
facchinm Feb 13, 2019
e01a981
[EthConnectionManager] Make "now" const
aentinger Feb 18, 2019
4014095
- added link to NPT on Arduino Tutorial and WikiPedia
ubidefeo Feb 20, 2019
a243573
- refactor GSMConnectionManager
ubidefeo Feb 21, 2019
096022a
- cleanup
ubidefeo Feb 21, 2019
98efd08
- cleanup WiFi and GSM ConnectionManager
ubidefeo Feb 21, 2019
e905238
- whitespace cleanup
ubidefeo Feb 21, 2019
8646505
- more cleanup and minor refactoring
ubidefeo Feb 21, 2019
8eefcc0
- reworked sentence
ubidefeo Feb 21, 2019
e4e11e5
- extended example with GSM compatibility options
ubidefeo Feb 21, 2019
20cbb75
Applying suggestions by A. Catozzi upon internal review
ubidefeo Feb 22, 2019
7fc775b
- switch state cleanup in ArduinoIoTCloud
ubidefeo Feb 23, 2019
bff994e
Merge branch 'master' into gsm_proper_connmanager
ubidefeo Feb 23, 2019
ae7dae9
- applied per1234's suggestions on #31
ubidefeo Feb 24, 2019
f86f04f
- one more missing from per1234's list
ubidefeo Feb 24, 2019
961a71c
- implemented some of the changes requested by @ilcato on PR #37
ubidefeo Feb 25, 2019
fb161bd
- `ArduinoIoTConnectionStatus` cleanup as per @ilcato 's suggestion
ubidefeo Feb 25, 2019
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
7 changes: 6 additions & 1 deletion src/ArduinoIoTCloud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ static ConnectionManager *getTimeConnection = NULL;

static unsigned long getTime() {
if (!getTimeConnection) return 0;
return getTimeConnection->getTime();
unsigned long time = getTimeConnection->getTime();
if (!NTPUtils::isTimeValid(time)) {
debugMessage("Bogus NTP time from API, fallback to UDP method", 0);
time = NTPUtils(getTimeConnection->getUDP()).getTime();
}
return time;
}

ArduinoIoTCloudClass::ArduinoIoTCloudClass() :
Expand Down
3 changes: 3 additions & 0 deletions src/ConnectionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#endif

#include <Client.h>
#include <Udp.h>
#include "utility/NTPUtils.h"

enum NetworkConnectionState {
CONNECTION_STATE_INIT,
Expand All @@ -40,6 +42,7 @@ class ConnectionManager {
virtual void check() = 0;
virtual unsigned long getTime() = 0;
virtual Client &getClient();
virtual UDP &getUDP();

virtual NetworkConnectionState getStatus() { return netConnectionState; }

Expand Down
187 changes: 187 additions & 0 deletions src/EthernetConnectionManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
#include "ConnectionManager.h"

#include <Ethernet.h>
#define BOARD_HAS_ETHERNET

class EthConnectionManager : public ConnectionManager {
public:
EthConnectionManager(uint8_t *mac, int ss_pin);

virtual unsigned long getTime();
virtual void init();
virtual void check();
virtual Client &getClient() { return ethClient; };
virtual UDP &getUDP() { return udp; };

private:

void changeConnectionState(NetworkConnectionState _newState);
const int CHECK_INTERVAL_IDLE = 100;
const int CHECK_INTERVAL_INIT = 100;
const int CHECK_INTERVAL_CONNECTING = 500;
const int CHECK_INTERVAL_GETTIME = 100;
const int CHECK_INTERVAL_CONNECTED = 10000;
const int CHECK_INTERVAL_RETRYING = 5000;
const int CHECK_INTERVAL_DISCONNECTED = 1000;
const int CHECK_INTERVAL_ERROR = 500;

unsigned long lastConnectionTickTime, lastNetworkStep;
uint8_t* mac;
int ss_pin;
EthernetClient ethClient;
EthernetUDP udp;
int connectionTickTimeInterval;
};

#if !defined(BOARD_HAS_WIFI) && !defined(BOARD_HAS_GSM)
static const unsigned long NETWORK_CONNECTION_INTERVAL = 30000;
#endif

EthConnectionManager::EthConnectionManager(uint8_t *mac, int ss_pin = -1) :
mac(mac),
ss_pin(ss_pin),
lastConnectionTickTime(millis()),
connectionTickTimeInterval(CHECK_INTERVAL_IDLE) {
}

unsigned long EthConnectionManager::getTime() {
//handled by fallback manager
return lastValidTimestamp + 1;
}

void EthConnectionManager::init() {
}

void EthConnectionManager::changeConnectionState(NetworkConnectionState _newState) {
netConnectionState = _newState;
int newInterval = CHECK_INTERVAL_IDLE;
switch (_newState) {
case CONNECTION_STATE_INIT:
newInterval = CHECK_INTERVAL_INIT;
break;
case CONNECTION_STATE_CONNECTING:
newInterval = CHECK_INTERVAL_CONNECTING;
break;
case CONNECTION_STATE_GETTIME:
newInterval = CHECK_INTERVAL_GETTIME;
break;
case CONNECTION_STATE_CONNECTED:
newInterval = CHECK_INTERVAL_CONNECTED;
break;
case CONNECTION_STATE_DISCONNECTED:
newInterval = CHECK_INTERVAL_DISCONNECTED;

break;
}
connectionTickTimeInterval = newInterval;
lastConnectionTickTime = millis();
}

void EthConnectionManager::check() {
char msgBuffer[120];
unsigned long const now = millis();
int networkStatus = 0;
if (now - lastConnectionTickTime > connectionTickTimeInterval) {
switch (netConnectionState) {
case CONNECTION_STATE_INIT:
if (ss_pin == -1) {
networkStatus = Ethernet.begin(mac);
} else {
networkStatus = Ethernet.begin(mac, ss_pin);
}
networkStatus = Ethernet.hardwareStatus();
*msgBuffer = 0;
sprintf(msgBuffer, "Eth hardware status(): %d", networkStatus);
debugMessage(msgBuffer, 2);
if (networkStatus == EthernetNoHardware) {
debugMessage("No Ethernet chip connected", 0);
// don't continue:
changeConnectionState(CONNECTION_STATE_ERROR);
lastConnectionTickTime = now;
return;
}
networkStatus = Ethernet.linkStatus();
*msgBuffer = 0;
sprintf(msgBuffer, "Eth link status(): %d", networkStatus);
debugMessage(msgBuffer, 2);
if (networkStatus == LinkOFF) {
debugMessage("Failed to configure Ethernet via dhcp", 0);
// don't continue:
changeConnectionState(CONNECTION_STATE_ERROR);
lastConnectionTickTime = now;
return;
}
*msgBuffer = 0;
sprintf(msgBuffer, "Ethernet shield recognized: ID", Ethernet.hardwareStatus());
debugMessage(msgBuffer, 0);
changeConnectionState(CONNECTION_STATE_CONNECTING);
break;
case CONNECTION_STATE_CONNECTING:
*msgBuffer = 0;
sprintf(msgBuffer, "Connecting via dhcp");
debugMessage(msgBuffer, 2);
if (ss_pin == -1) {
networkStatus = Ethernet.begin(mac);
} else {
networkStatus = Ethernet.begin(mac, ss_pin);
}
*msgBuffer = 0;
sprintf(msgBuffer, "Ethernet.status(): %d", networkStatus);
debugMessage(msgBuffer, 2);
if (networkStatus == 0) {
*msgBuffer = 0;
sprintf(msgBuffer, "Connection failed");
debugMessage(msgBuffer, 0);

*msgBuffer = 0;
sprintf(msgBuffer, "Retrying in \"%d\" milliseconds", connectionTickTimeInterval);
debugMessage(msgBuffer, 2);
//changeConnectionState(CONNECTION_STATE_CONNECTING);
return;
} else {
*msgBuffer = 0;
sprintf(msgBuffer, "Connected!");
debugMessage(msgBuffer, 2);
changeConnectionState(CONNECTION_STATE_GETTIME);
return;
}
break;
case CONNECTION_STATE_GETTIME:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add an exit condition from the CONNECTION_STATE_GETTIME state in a similar way of the WiFiConnectionManager.

debugMessage("Acquiring Time from Network", 3);
unsigned long networkTime;
networkTime = getTime();
*msgBuffer = 0;
sprintf(msgBuffer, "Network Time: %u", networkTime);
debugMessage(msgBuffer, 3);
if(networkTime > lastValidTimestamp){
lastValidTimestamp = networkTime;
changeConnectionState(CONNECTION_STATE_CONNECTED);
}
break;
case CONNECTION_STATE_CONNECTED:
// keep testing connection
Ethernet.maintain();
networkStatus = Ethernet.linkStatus();
*msgBuffer = 0;
sprintf(msgBuffer, "Eth link status(): %d", networkStatus);
debugMessage(msgBuffer, 4);
if (networkStatus != LinkON) {
changeConnectionState(CONNECTION_STATE_DISCONNECTED);
return;
}
*msgBuffer = 0;
sprintf(msgBuffer, "Connected");
debugMessage(msgBuffer, 2);
break;
case CONNECTION_STATE_DISCONNECTED:
*msgBuffer = 0;
sprintf(msgBuffer, "Connection lost.");
debugMessage(msgBuffer, 0);
debugMessage("Attempting reconnection", 1);
changeConnectionState(CONNECTION_STATE_CONNECTING);
//wifiClient.stop();
break;
}
lastConnectionTickTime = now;
}
}
Loading