Skip to content

Commit 0786d7a

Browse files
authored
Merge pull request #136 from andreagilardoni/connectionhandler-settings
GenericConnectionhandler redesign of internal structures
2 parents 432961a + 2760757 commit 0786d7a

23 files changed

+808
-173
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/* SECRET_ fields are in `arduino_secrets.h` (included below)
2+
*
3+
* If using a WiFi board (Arduino MKR1000, MKR WiFi 1010, Nano 33 IoT, UNO
4+
* WiFi Rev 2 or ESP8266/32), create a WiFiConnectionHandler object by adding
5+
* Network Name (SECRET_WIFI_SSID) and password (SECRET_WIFI_PASS) in the
6+
* arduino_secrets.h file (or Secrets tab in Create Web Editor).
7+
*
8+
* WiFiConnectionHandler conMan(SECRET_WIFI_SSID, SECRET_WIFI_PASS);
9+
*
10+
* If using a MKR GSM 1400 or other GSM boards supporting the same API you'll
11+
* need a GSMConnectionHandler object as follows
12+
*
13+
* GSMConnectionHandler conMan(SECRET_PIN, SECRET_APN, SECRET_GSM_USER, SECRET_GSM_PASS);
14+
*
15+
* If using a MKR NB1500 you'll need a NBConnectionHandler object as follows
16+
*
17+
* NBConnectionHandler conMan(SECRET_PIN);
18+
*
19+
* If using a Portenta + Ethernet shield you'll need a EthernetConnectionHandler object as follows:
20+
*
21+
* DHCP mode
22+
* EthernetConnectionHandler conMan;
23+
*
24+
* Manual configuration
25+
* EthernetConnectionHandler conMan(SECRET_IP, SECRET_DNS, SECRET_GATEWAY, SECRET_NETMASK);
26+
*
27+
* Manual configuration will fallback on DHCP mode if SECRET_IP is invalid or equal to INADDR_NONE.
28+
*
29+
*/
30+
31+
#include <GenericConnectionHandler.h>
32+
33+
#include "arduino_secrets.h"
34+
35+
#define CONN_TOGGLE_MS 60000
36+
37+
#if !(defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined(BOARD_HAS_LORA) || \
38+
defined(BOARD_HAS_NB) || defined(BOARD_HAS_ETHERNET) || defined(BOARD_HAS_CATM1_NBIOT))
39+
#error "Please check Arduino Connection Handler supported boards list: https://github.com/arduino-libraries/Arduino_ConnectionHandler/blob/master/README.md"
40+
#endif
41+
42+
GenericConnectionHandler conMan;
43+
44+
45+
bool attemptConnect = false;
46+
uint32_t lastConnToggleMs = 0;
47+
48+
void setup() {
49+
/* Initialize serial debug port and wait up to 5 seconds for port to open */
50+
Serial.begin(9600);
51+
for(unsigned long const serialBeginTime = millis(); !Serial && (millis() - serialBeginTime <= 5000); ) { }
52+
53+
#ifndef __AVR__
54+
/* Set the debug message level:
55+
* - DBG_ERROR: Only show error messages
56+
* - DBG_WARNING: Show warning and error messages
57+
* - DBG_INFO: Show info, warning, and error messages
58+
* - DBG_DEBUG: Show debug, info, warning, and error messages
59+
* - DBG_VERBOSE: Show all messages
60+
*/
61+
setDebugMessageLevel(DBG_INFO);
62+
#endif
63+
64+
models::NetworkSetting setting = models::settingsDefault(NetworkAdapter::WIFI);
65+
66+
strcpy(setting.wifi.ssid, SECRET_WIFI_SSID);
67+
strcpy(setting.wifi.pwd, SECRET_WIFI_PASS);
68+
69+
/* Add callbacks to the ConnectionHandler object to get notified of network
70+
* connection events. */
71+
conMan.addCallback(NetworkConnectionEvent::CONNECTED, onNetworkConnect);
72+
conMan.addCallback(NetworkConnectionEvent::DISCONNECTED, onNetworkDisconnect);
73+
conMan.addCallback(NetworkConnectionEvent::ERROR, onNetworkError);
74+
75+
conMan.updateSetting(setting);
76+
Serial.print("Network Adapter Interface: ");
77+
switch (conMan.getInterface()) {
78+
case NetworkAdapter::WIFI:
79+
Serial.println("Wi-Fi");
80+
break;
81+
case NetworkAdapter::ETHERNET:
82+
Serial.println("Ethernet");
83+
break;
84+
case NetworkAdapter::NB:
85+
Serial.println("Narrowband");
86+
break;
87+
case NetworkAdapter::GSM:
88+
Serial.println("GSM");
89+
break;
90+
case NetworkAdapter::LORA:
91+
Serial.println("LoRa");
92+
break;
93+
case NetworkAdapter::CATM1:
94+
Serial.println("Category M1");
95+
break;
96+
case NetworkAdapter::CELL:
97+
Serial.println("Cellular");
98+
break;
99+
default:
100+
Serial.println("Unknown");
101+
break;
102+
}
103+
}
104+
105+
void loop() {
106+
/* Toggle the connection every `CONN_TOGGLE_MS` milliseconds */
107+
if ((millis() - lastConnToggleMs) > CONN_TOGGLE_MS) {
108+
Serial.println("Toggling connection...");
109+
if (attemptConnect) {
110+
conMan.connect();
111+
} else {
112+
conMan.disconnect();
113+
}
114+
attemptConnect = !attemptConnect;
115+
lastConnToggleMs = millis();
116+
}
117+
118+
/* The following code keeps on running connection workflows on our
119+
* ConnectionHandler object, hence allowing reconnection in case of failure
120+
* and notification of connect/disconnect event if enabled (see
121+
* addConnectCallback/addDisconnectCallback) NOTE: any use of delay() within
122+
* the loop or methods called from it will delay the execution of .update(),
123+
* which might not guarantee the correct functioning of the ConnectionHandler
124+
* object.
125+
*/
126+
conMan.check();
127+
}
128+
129+
void onNetworkConnect() {
130+
Serial.println(">>>> CONNECTED to network");
131+
}
132+
133+
void onNetworkDisconnect() {
134+
Serial.println(">>>> DISCONNECTED from network");
135+
}
136+
137+
void onNetworkError() {
138+
Serial.println(">>>> ERROR");
139+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Required for WiFiConnectionHandler
2+
const char SECRET_WIFI_SSID[] = "SSID";
3+
const char SECRET_WIFI_PASS[] = "PASSWORD";
4+
5+
// Required for GSMConnectionHandler
6+
const char SECRET_APN[] = "MOBILE PROVIDER APN ADDRESS";
7+
const char SECRET_PIN[] = "0000"; // Required for NBConnectionHandler
8+
const char SECRET_GSM_USER[] = "GSM USERNAME";
9+
const char SECRET_GSM_PASS[] = "GSM PASSWORD";
10+
11+
// Required for LoRaConnectionHandler
12+
const char SECRET_APP_EUI[] = "APP_EUI";
13+
const char SECRET_APP_KEY[] = "APP_KEY";
14+
15+
// Required for EthernetConnectionHandler (without DHCP mode)
16+
const char SECRET_IP[] = "IP ADDRESS";
17+
const char SECRET_DNS[] = "DNS ADDRESS";
18+
const char SECRET_GATEWAY[] = "GATEWAY ADDRESS";
19+
const char SECRET_NETMASK[] = "NETWORK MASK";

src/CatM1ConnectionHandler.cpp

+20-9
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,21 @@
2828
CTOR/DTOR
2929
******************************************************************************/
3030

31-
CatM1ConnectionHandler::CatM1ConnectionHandler(const char * pin, const char * apn, const char * login, const char * pass, RadioAccessTechnologyType rat, uint32_t band, bool const keep_alive)
31+
CatM1ConnectionHandler::CatM1ConnectionHandler()
32+
: ConnectionHandler(true, NetworkAdapter::CATM1) { }
33+
34+
CatM1ConnectionHandler::CatM1ConnectionHandler(
35+
const char * pin, const char * apn, const char * login, const char * pass,
36+
RadioAccessTechnologyType rat, uint32_t band, bool const keep_alive)
3237
: ConnectionHandler{keep_alive, NetworkAdapter::CATM1}
33-
, _pin(pin)
34-
, _apn(apn)
35-
, _login(login)
36-
, _pass(pass)
37-
, _rat(rat)
38-
, _band(band)
3938
{
40-
39+
_settings.type = NetworkAdapter::CATM1;
40+
strncpy(_settings.catm1.pin, pin, sizeof(_settings.catm1.pin)-1);
41+
strncpy(_settings.catm1.apn, apn, sizeof(_settings.catm1.apn)-1);
42+
strncpy(_settings.catm1.login, login, sizeof(_settings.catm1.login)-1);
43+
strncpy(_settings.catm1.pass, pass, sizeof(_settings.catm1.pass)-1);
44+
_settings.catm1.rat = static_cast<uint8_t>(rat);
45+
_settings.catm1.band = band;
4146
}
4247

4348
/******************************************************************************
@@ -64,7 +69,13 @@ NetworkConnectionState CatM1ConnectionHandler::update_handleInit()
6469

6570
NetworkConnectionState CatM1ConnectionHandler::update_handleConnecting()
6671
{
67-
if(!GSM.begin(_pin, _apn, _login, _pass, _rat, _band))
72+
if(!GSM.begin(
73+
_settings.catm1.pin,
74+
_settings.catm1.apn,
75+
_settings.catm1.login,
76+
_settings.catm1.pass,
77+
static_cast<RadioAccessTechnologyType>(_settings.catm1.rat) ,
78+
_settings.catm1.band))
6879
{
6980
Debug.print(DBG_ERROR, F("The board was not able to register to the network..."));
7081
return NetworkConnectionState::ERROR;

src/CatM1ConnectionHandler.h

+1-8
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class CatM1ConnectionHandler : public ConnectionHandler
4040
{
4141
public:
4242

43+
CatM1ConnectionHandler();
4344
CatM1ConnectionHandler(const char * pin, const char * apn, const char * login, const char * pass, RadioAccessTechnologyType rat = CATM1, uint32_t band = BAND_3 | BAND_20 | BAND_19, bool const keep_alive = true);
4445

4546

@@ -59,14 +60,6 @@ class CatM1ConnectionHandler : public ConnectionHandler
5960

6061
private:
6162

62-
const char * _pin;
63-
const char * _apn;
64-
const char * _login;
65-
const char * _pass;
66-
67-
RadioAccessTechnologyType _rat;
68-
uint32_t _band;
69-
7063
GSMUDP _gsm_udp;
7164
GSMClient _gsm_client;
7265
};

src/CellularConnectionHandler.cpp

+9-6
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,17 @@
2121
/******************************************************************************
2222
CTOR/DTOR
2323
******************************************************************************/
24+
CellularConnectionHandler::CellularConnectionHandler()
25+
: ConnectionHandler(true, NetworkAdapter::CELL) {}
2426

2527
CellularConnectionHandler::CellularConnectionHandler(const char * pin, const char * apn, const char * login, const char * pass, bool const keep_alive)
2628
: ConnectionHandler{keep_alive, NetworkAdapter::CELL}
27-
, _pin(pin)
28-
, _apn(apn)
29-
, _login(login)
30-
, _pass(pass)
3129
{
30+
_settings.type = NetworkAdapter::CELL;
31+
strncpy(_settings.cell.pin, pin, sizeof(_settings.cell.pin)-1);
32+
strncpy(_settings.cell.apn, apn, sizeof(_settings.cell.apn)-1);
33+
strncpy(_settings.cell.login, login, sizeof(_settings.cell.login)-1);
34+
strncpy(_settings.cell.pass, pass, sizeof(_settings.cell.pass)-1);
3235

3336
}
3437

@@ -55,7 +58,7 @@ NetworkConnectionState CellularConnectionHandler::update_handleInit()
5558
{
5659
_cellular.begin();
5760
_cellular.setDebugStream(Serial);
58-
if (String(_pin).length() > 0 && !_cellular.unlockSIM(_pin)) {
61+
if (strlen(_settings.cell.pin) > 0 && !_cellular.unlockSIM(_settings.cell.pin)) {
5962
Debug.print(DBG_ERROR, F("SIM not present or wrong PIN"));
6063
return NetworkConnectionState::ERROR;
6164
}
@@ -64,7 +67,7 @@ NetworkConnectionState CellularConnectionHandler::update_handleInit()
6467

6568
NetworkConnectionState CellularConnectionHandler::update_handleConnecting()
6669
{
67-
if (!_cellular.connect(_apn, _login, _pass)) {
70+
if (!_cellular.connect(String(_settings.cell.apn), String(_settings.cell.login), String(_settings.cell.pass))) {
6871
Debug.print(DBG_ERROR, F("The board was not able to register to the network..."));
6972
return NetworkConnectionState::ERROR;
7073
}

src/CellularConnectionHandler.h

+1-6
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
class CellularConnectionHandler : public ConnectionHandler
3434
{
3535
public:
36-
36+
CellularConnectionHandler();
3737
CellularConnectionHandler(const char * pin, const char * apn, const char * login, const char * pass, bool const keep_alive = true);
3838

3939

@@ -53,11 +53,6 @@ class CellularConnectionHandler : public ConnectionHandler
5353

5454
private:
5555

56-
const char * _pin;
57-
const char * _apn;
58-
const char * _login;
59-
const char * _pass;
60-
6156
ArduinoCellular _cellular;
6257
TinyGsmClient _gsm_client = _cellular.getNetworkClient();
6358
};

src/ConnectionHandlerDefinitions.h

+1
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ enum class NetworkConnectionEvent {
174174
};
175175

176176
enum class NetworkAdapter {
177+
NONE,
177178
WIFI,
178179
ETHERNET,
179180
NB,

src/ConnectionHandlerInterface.cpp

+51-31
Original file line numberDiff line numberDiff line change
@@ -46,49 +46,69 @@ NetworkConnectionState ConnectionHandler::check()
4646
if((now - _lastConnectionTickTime) > connectionTickTimeInterval)
4747
{
4848
_lastConnectionTickTime = now;
49-
NetworkConnectionState next_net_connection_state = _current_net_connection_state;
5049

51-
/* While the state machine is implemented here, the concrete implementation of the
52-
* states is done in the derived connection handlers.
53-
*/
54-
switch (_current_net_connection_state)
55-
{
56-
case NetworkConnectionState::INIT: next_net_connection_state = update_handleInit (); break;
57-
case NetworkConnectionState::CONNECTING: next_net_connection_state = update_handleConnecting (); break;
58-
case NetworkConnectionState::CONNECTED: next_net_connection_state = update_handleConnected (); break;
59-
case NetworkConnectionState::DISCONNECTING: next_net_connection_state = update_handleDisconnecting(); break;
60-
case NetworkConnectionState::DISCONNECTED: next_net_connection_state = update_handleDisconnected (); break;
61-
case NetworkConnectionState::ERROR: break;
62-
case NetworkConnectionState::CLOSED: break;
63-
}
50+
NetworkConnectionState old_net_connection_state = _current_net_connection_state;
51+
NetworkConnectionState next_net_connection_state = updateConnectionState();
6452

6553
/* Here we are determining whether a state transition from one state to the next has
6654
* occurred - and if it has, we call eventually registered callbacks.
6755
*/
68-
if(next_net_connection_state != _current_net_connection_state)
69-
{
70-
/* Check the next state to determine the kind of state conversion which has occurred (and call the appropriate callback) */
71-
if(next_net_connection_state == NetworkConnectionState::CONNECTED)
72-
{
73-
if(_on_connect_event_callback) _on_connect_event_callback();
74-
}
75-
if(next_net_connection_state == NetworkConnectionState::DISCONNECTED)
76-
{
77-
if(_on_disconnect_event_callback) _on_disconnect_event_callback();
78-
}
79-
if(next_net_connection_state == NetworkConnectionState::ERROR)
80-
{
81-
if(_on_error_event_callback) _on_error_event_callback();
82-
}
83-
84-
/* Assign new state to the member variable holding the state */
56+
57+
if(old_net_connection_state != next_net_connection_state) {
58+
updateCallback(next_net_connection_state);
59+
60+
/* It may happen that the local _current_net_connection_state
61+
* is not updated by the updateConnectionState() call. This is the case for GenericConnection handler
62+
* where the call of updateConnectionState() is replaced by the inner ConnectionHandler call
63+
* that updates its state, but not the outer one. For this reason it is required to perform this call twice
64+
*/
8565
_current_net_connection_state = next_net_connection_state;
8666
}
8767
}
8868

8969
return _current_net_connection_state;
9070
}
9171

72+
NetworkConnectionState ConnectionHandler::updateConnectionState() {
73+
NetworkConnectionState next_net_connection_state = _current_net_connection_state;
74+
75+
/* While the state machine is implemented here, the concrete implementation of the
76+
* states is done in the derived connection handlers.
77+
*/
78+
switch (_current_net_connection_state)
79+
{
80+
case NetworkConnectionState::INIT: next_net_connection_state = update_handleInit (); break;
81+
case NetworkConnectionState::CONNECTING: next_net_connection_state = update_handleConnecting (); break;
82+
case NetworkConnectionState::CONNECTED: next_net_connection_state = update_handleConnected (); break;
83+
case NetworkConnectionState::DISCONNECTING: next_net_connection_state = update_handleDisconnecting(); break;
84+
case NetworkConnectionState::DISCONNECTED: next_net_connection_state = update_handleDisconnected (); break;
85+
case NetworkConnectionState::ERROR: break;
86+
case NetworkConnectionState::CLOSED: break;
87+
}
88+
89+
/* Assign new state to the member variable holding the state */
90+
_current_net_connection_state = next_net_connection_state;
91+
92+
return next_net_connection_state;
93+
}
94+
95+
void ConnectionHandler::updateCallback(NetworkConnectionState next_net_connection_state) {
96+
97+
/* Check the next state to determine the kind of state conversion which has occurred (and call the appropriate callback) */
98+
if(next_net_connection_state == NetworkConnectionState::CONNECTED)
99+
{
100+
if(_on_connect_event_callback) _on_connect_event_callback();
101+
}
102+
if(next_net_connection_state == NetworkConnectionState::DISCONNECTED)
103+
{
104+
if(_on_disconnect_event_callback) _on_disconnect_event_callback();
105+
}
106+
if(next_net_connection_state == NetworkConnectionState::ERROR)
107+
{
108+
if(_on_error_event_callback) _on_error_event_callback();
109+
}
110+
}
111+
92112
void ConnectionHandler::connect()
93113
{
94114
if (_current_net_connection_state != NetworkConnectionState::INIT && _current_net_connection_state != NetworkConnectionState::CONNECTING)

0 commit comments

Comments
 (0)