Skip to content

Commit f4f5586

Browse files
committed
- initial commit
Still battling a weird behaviour on ESP12/32 which prevents some connections to be established successfully at start. Works when manually initiated. Investigating
1 parent 639fe91 commit f4f5586

File tree

9 files changed

+762
-1
lines changed

9 files changed

+762
-1
lines changed

Arduino_ConnectionHandler.h

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/*
2+
This file is part of ArduinoIoTCloud.
3+
4+
Copyright 2019 ARDUINO SA (http://www.arduino.cc/)
5+
6+
This software is released under the GNU General Public License version 3,
7+
which covers the main part of arduino-cli.
8+
The terms of this license can be found at:
9+
https://www.gnu.org/licenses/gpl-3.0.en.html
10+
11+
You can be released from the requirements of the above licenses by purchasing
12+
a commercial license. Buying such a license is mandatory if you want to modify or
13+
otherwise use the software for commercial activities involving the Arduino
14+
software without disclosing the source code of your own applications. To purchase
15+
a commercial license, send an email to [email protected].
16+
*/
17+
18+
#ifndef ARDUINO_CONNECTION_HANDLER_H_
19+
#define ARDUINO_CONNECTION_HANDLER_H_
20+
21+
/******************************************************************************
22+
INCLUDES
23+
******************************************************************************/
24+
25+
#include <Client.h>
26+
#include <Udp.h>
27+
28+
//#include "NTPUtils.h"
29+
#include "DebugUtils.h"
30+
31+
/******************************************************************************
32+
TYPEDEFS
33+
******************************************************************************/
34+
35+
enum class NetworkConnectionState {
36+
INIT,
37+
CONNECTING,
38+
CONNECTED,
39+
GETTIME,
40+
DISCONNECTING,
41+
DISCONNECTED,
42+
CLOSED,
43+
ERROR
44+
};
45+
46+
enum class NetworkConnectionEvent {
47+
INIT, CONNECTING, CONNECTED, DISCONNECTING, DISCONNECTED, CLOSED, ERROR
48+
};
49+
50+
typedef void (*OnNetworkEventCallback)(void * /* arg */);
51+
52+
/******************************************************************************
53+
CLASS DECLARATION
54+
******************************************************************************/
55+
56+
class Arduino_ConnectionHandler {
57+
public:
58+
virtual void init() = 0;
59+
virtual void check() = 0;
60+
virtual void update() = 0;
61+
virtual unsigned long getTime() = 0;
62+
virtual Client &getClient();
63+
virtual UDP &getUDP();
64+
65+
virtual NetworkConnectionState getStatus() {
66+
return netConnectionState;
67+
}
68+
virtual void connect();
69+
virtual void disconnect();
70+
virtual void addCallback(NetworkConnectionEvent const event, OnNetworkEventCallback callback);
71+
72+
73+
private:
74+
OnNetworkEventCallback _on_connect_event_callback,
75+
_on_disconnect_event_callback,
76+
_on_error_event_callback;
77+
78+
protected:
79+
80+
unsigned long lastValidTimestamp = 0; /* UNUSED */
81+
NetworkConnectionState netConnectionState = NetworkConnectionState::DISCONNECTED;
82+
83+
};
84+
85+
#ifdef ARDUINO_SAMD_MKR1000
86+
#include <WiFi101.h>
87+
#include <WiFiUdp.h>
88+
89+
#define BOARD_HAS_WIFI
90+
#define NETWORK_HARDWARE_ERROR WL_NO_SHIELD
91+
#define NETWORK_IDLE_STATUS WL_IDLE_STATUS
92+
#define NETWORK_CONNECTED WL_CONNECTED
93+
#define WIFI_FIRMWARE_VERSION_REQUIRED WIFI_FIRMWARE_REQUIRED
94+
#endif
95+
96+
#if defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_NANO_33_IOT)
97+
#include <WiFiNINA.h>
98+
#include <WiFiUdp.h>
99+
100+
#define BOARD_HAS_WIFI
101+
#define NETWORK_HARDWARE_ERROR WL_NO_MODULE
102+
#define NETWORK_IDLE_STATUS WL_IDLE_STATUS
103+
#define NETWORK_CONNECTED WL_CONNECTED
104+
#define WIFI_FIRMWARE_VERSION_REQUIRED WIFI_FIRMWARE_LATEST_VERSION
105+
#endif
106+
107+
#ifdef ARDUINO_SAMD_MKRGSM1400
108+
#include <MKRGSM.h>
109+
#define BOARD_HAS_GSM
110+
#define NETWORK_HARDWARE_ERROR GPRS_PING_ERROR
111+
#define NETWORK_IDLE_STATUS GSM3_NetworkStatus_t::IDLE
112+
#define NETWORK_CONNECTED GSM3_NetworkStatus_t::GPRS_READY
113+
#endif
114+
115+
#if defined(ARDUINO_ESP8266_ESP12) || defined(ARDUINO_ARCH_ESP32)
116+
#ifdef ARDUINO_ESP8266_ESP12
117+
#include <ESP8266WiFi.h>
118+
119+
#else
120+
#include <WiFi.h>
121+
#endif
122+
123+
#include <WiFiUdp.h>
124+
#define BOARD_HAS_WIFI
125+
#define GETTIME_MISSING
126+
#define NETWORK_HARDWARE_ERROR WL_NO_SHIELD
127+
#define NETWORK_IDLE_STATUS WL_IDLE_STATUS
128+
#define NETWORK_CONNECTED WL_CONNECTED
129+
#define WIFI_FIRMWARE_VERSION_REQUIRED WIFI_FIRMWARE_REQUIRED
130+
#endif
131+
132+
#endif /* CONNECTION_HANDLER_H_ */

Arduino_WiFiConnectionHandler.cpp

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
/*
2+
This file is part of ArduinoIoTCloud.
3+
4+
Copyright 2019 ARDUINO SA (http://www.arduino.cc/)
5+
6+
This software is released under the GNU General Public License version 3,
7+
which covers the main part of arduino-cli.
8+
The terms of this license can be found at:
9+
https://www.gnu.org/licenses/gpl-3.0.en.html
10+
11+
You can be released from the requirements of the above licenses by purchasing
12+
a commercial license. Buying such a license is mandatory if you want to modify or
13+
otherwise use the software for commercial activities involving the Arduino
14+
software without disclosing the source code of your own applications. To purchase
15+
a commercial license, send an email to [email protected].
16+
*/
17+
18+
/******************************************************************************
19+
INCLUDE
20+
******************************************************************************/
21+
22+
#include "Arduino_WiFiConnectionHandler.h"
23+
24+
#ifdef BOARD_HAS_WIFI /* Only compile if the board has WiFi */
25+
26+
/******************************************************************************
27+
CONSTANTS
28+
******************************************************************************/
29+
30+
static const unsigned long NETWORK_CONNECTION_INTERVAL = 30000; /* NOT USED */
31+
32+
/******************************************************************************
33+
CTOR/DTOR
34+
******************************************************************************/
35+
36+
Arduino_WiFiConnectionHandler::Arduino_WiFiConnectionHandler(const char *_ssid, const char *_pass, bool _keepAlive) :
37+
ssid(_ssid),
38+
pass(_pass),
39+
lastConnectionTickTime(millis()),
40+
connectionTickTimeInterval(CHECK_INTERVAL_IDLE),
41+
keepAlive(_keepAlive),
42+
_on_connect_event_callback(NULL),
43+
_on_disconnect_event_callback(NULL),
44+
_on_error_event_callback(NULL){
45+
}
46+
47+
/******************************************************************************
48+
PUBLIC MEMBER FUNCTIONS
49+
******************************************************************************/
50+
51+
void Arduino_WiFiConnectionHandler::init() {
52+
}
53+
54+
void Arduino_WiFiConnectionHandler::addCallback(NetworkConnectionEvent const event, OnNetworkEventCallback callback){
55+
switch (event) {
56+
case NetworkConnectionEvent::CONNECTED: _on_connect_event_callback = callback; break;
57+
case NetworkConnectionEvent::DISCONNECTED: _on_disconnect_event_callback = callback; break;
58+
case NetworkConnectionEvent::ERROR: _on_error_event_callback = callback; break;
59+
}
60+
}
61+
62+
void Arduino_WiFiConnectionHandler::execNetworkEventCallback(OnNetworkEventCallback & callback, void * callback_arg){
63+
if(callback){
64+
(*callback)(callback_arg);
65+
}
66+
}
67+
68+
unsigned long Arduino_WiFiConnectionHandler::getTime() {
69+
#ifdef GETTIME_MISSING
70+
return 0;
71+
#else
72+
return WiFi.getTime();
73+
#endif
74+
}
75+
76+
void Arduino_WiFiConnectionHandler::update() {
77+
78+
unsigned long const now = millis();
79+
int networkStatus = 0;
80+
if (now - lastConnectionTickTime > connectionTickTimeInterval) { /* time bracket */
81+
82+
switch (netConnectionState) {
83+
case NetworkConnectionState::INIT: {
84+
debugMessage(DebugLevel::Verbose, "::INIT");
85+
#if !defined(ARDUINO_ESP8266_ESP12) && !defined(ARDUINO_ARCH_ESP32)
86+
networkStatus = WiFi.status();
87+
88+
debugMessage(DebugLevel::Info, "WiFi.status(): %d", networkStatus);
89+
if (networkStatus == NETWORK_HARDWARE_ERROR) {
90+
// NO FURTHER ACTION WILL FOLLOW THIS
91+
changeConnectionState(NetworkConnectionState::ERROR);
92+
lastConnectionTickTime = now;
93+
return;
94+
}
95+
debugMessage(DebugLevel::Error, "Current WiFi Firmware: %s", WiFi.firmwareVersion());
96+
if (WiFi.firmwareVersion() < WIFI_FIRMWARE_VERSION_REQUIRED) {
97+
debugMessage(DebugLevel::Error, "Latest WiFi Firmware: %s", WIFI_FIRMWARE_VERSION_REQUIRED);
98+
debugMessage(DebugLevel::Error, "Please update to the latest version for best performance.");
99+
delay(5000);
100+
}
101+
#else
102+
debugMessage(DebugLevel::Error, "WiFi status ESP: %d", WiFi.status());
103+
WiFi.disconnect();
104+
networkStatus = WiFi.begin(ssid, pass);
105+
#endif
106+
107+
changeConnectionState(NetworkConnectionState::CONNECTING);
108+
}
109+
break;
110+
case NetworkConnectionState::CONNECTING: {
111+
debugMessage(DebugLevel::Verbose, "::CONNECTING");
112+
networkStatus = WiFi.status();
113+
114+
#if !defined(ARDUINO_ESP8266_ESP12) && !defined(ARDUINO_ARCH_ESP32)
115+
116+
if (networkStatus != WL_CONNECTED) {
117+
networkStatus = WiFi.begin(ssid, pass);
118+
}
119+
120+
#else
121+
122+
networkStatus = WiFi.status();
123+
124+
#endif
125+
126+
debugMessage(DebugLevel::Verbose, "WiFi.status(): %d", networkStatus);
127+
if (networkStatus != NETWORK_CONNECTED) {
128+
debugMessage(DebugLevel::Error, "Connection to \"%s\" failed", ssid);
129+
debugMessage(DebugLevel::Info, "Retrying in \"%d\" milliseconds", connectionTickTimeInterval);
130+
131+
return;
132+
} else {
133+
debugMessage(DebugLevel::Info, "Connected to \"%s\"", ssid);
134+
changeConnectionState(NetworkConnectionState::CONNECTED);
135+
return;
136+
}
137+
}
138+
break;
139+
case NetworkConnectionState::CONNECTED: {
140+
141+
networkStatus = WiFi.status();
142+
debugMessage(DebugLevel::Verbose, "WiFi.status(): %d", networkStatus);
143+
if (networkStatus != WL_CONNECTED) {
144+
changeConnectionState(NetworkConnectionState::DISCONNECTED);
145+
return;
146+
}
147+
debugMessage(DebugLevel::Verbose, "Connected to \"%s\"", ssid);
148+
}
149+
break;
150+
case NetworkConnectionState::GETTIME: {
151+
152+
}
153+
break;
154+
case NetworkConnectionState::DISCONNECTING: {
155+
if (networkStatus != WL_CONNECTED) {
156+
changeConnectionState(NetworkConnectionState::DISCONNECTED);
157+
}
158+
}
159+
break;
160+
case NetworkConnectionState::DISCONNECTED: {
161+
#if !defined(ARDUINO_ESP8266_ESP12) && !defined(ARDUINO_ARCH_ESP32)
162+
WiFi.end();
163+
#endif
164+
if (keepAlive) {
165+
changeConnectionState(NetworkConnectionState::INIT);
166+
}else{
167+
changeConnectionState(NetworkConnectionState::CLOSED);
168+
}
169+
170+
}
171+
break;
172+
case NetworkConnectionState::ERROR: {
173+
174+
}
175+
break;
176+
case NetworkConnectionState::CLOSED: {
177+
178+
}
179+
break;
180+
}
181+
lastConnectionTickTime = now;
182+
183+
} /* time bracket */
184+
}
185+
186+
/******************************************************************************
187+
PRIVATE MEMBER FUNCTIONS
188+
******************************************************************************/
189+
190+
void Arduino_WiFiConnectionHandler::changeConnectionState(NetworkConnectionState _newState) {
191+
if(_newState == netConnectionState) return;
192+
int newInterval = CHECK_INTERVAL_INIT;
193+
switch (_newState) {
194+
case NetworkConnectionState::INIT: {
195+
debugMessage(DebugLevel::Verbose, "CHANGING STATE TO ::INIT");
196+
newInterval = CHECK_INTERVAL_INIT;
197+
}
198+
break;
199+
case NetworkConnectionState::CONNECTING: {
200+
debugMessage(DebugLevel::Info, "Connecting to \"%s\"", ssid);
201+
newInterval = CHECK_INTERVAL_CONNECTING;
202+
}
203+
break;
204+
case NetworkConnectionState::CONNECTED: {
205+
execNetworkEventCallback(_on_connect_event_callback,0);
206+
newInterval = CHECK_INTERVAL_CONNECTED;
207+
}
208+
break;
209+
case NetworkConnectionState::GETTIME: {
210+
}
211+
break;
212+
case NetworkConnectionState::DISCONNECTING: {
213+
debugMessage(DebugLevel::Verbose, "Disconnecting from \"%s\"", ssid);
214+
WiFi.disconnect();
215+
}
216+
break;
217+
case NetworkConnectionState::DISCONNECTED: {
218+
execNetworkEventCallback(_on_disconnect_event_callback,0);
219+
debugMessage(DebugLevel::Verbose, "WiFi.status(): %d", WiFi.status());
220+
221+
debugMessage(DebugLevel::Error, "Connection to \"%s\" lost.", ssid);
222+
debugMessage(DebugLevel::Error, "Attempting reconnection");
223+
newInterval = CHECK_INTERVAL_DISCONNECTED;
224+
}
225+
break;
226+
case NetworkConnectionState::CLOSED: {
227+
228+
#if !defined(ARDUINO_ESP8266_ESP12) && !defined(ARDUINO_ARCH_ESP32)
229+
WiFi.end();
230+
#endif
231+
232+
debugMessage(DebugLevel::Verbose, "Connection to \"%s\" closed", ssid);
233+
}
234+
break;
235+
case NetworkConnectionState::ERROR: {
236+
execNetworkEventCallback(_on_error_event_callback,0);
237+
debugMessage(DebugLevel::Error, "WiFi Hardware failure.\nMake sure you are using a WiFi enabled board/shield.");
238+
debugMessage(DebugLevel::Error, "Then reset and retry.");
239+
}
240+
break;
241+
}
242+
connectionTickTimeInterval = newInterval;
243+
lastConnectionTickTime = millis();
244+
netConnectionState = _newState;
245+
connectionStateChanged(netConnectionState);
246+
}
247+
248+
void Arduino_WiFiConnectionHandler::connect() {
249+
if(netConnectionState == NetworkConnectionState::INIT || netConnectionState == NetworkConnectionState::CONNECTING){
250+
return;
251+
}
252+
keepAlive = true;
253+
changeConnectionState(NetworkConnectionState::INIT);
254+
255+
}
256+
void Arduino_WiFiConnectionHandler::disconnect() {
257+
//WiFi.end();
258+
259+
changeConnectionState(NetworkConnectionState::DISCONNECTING);
260+
keepAlive = false;
261+
}
262+
#endif /* #ifdef BOARD_HAS_WIFI */

0 commit comments

Comments
 (0)