Skip to content

Commit 3737d7b

Browse files
authored
Merge pull request #26 from arduino-libraries/conhdl-clean-up
Clean-up of connection handler for better maintainability.
2 parents 9f42a6c + bf2b5b0 commit 3737d7b

14 files changed

+535
-736
lines changed

.github/workflows/compile-examples.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ jobs:
55
runs-on: ubuntu-latest
66

77
env:
8-
LIBRARIES: Arduino_DebugUtils WiFi101 WiFiNINA MKRGSM MKRNB
8+
LIBRARIES: Arduino_DebugUtils WiFi101 WiFiNINA MKRGSM MKRNB MKRWAN
99
strategy:
1010
matrix:
1111
fqbn: [
@@ -14,6 +14,8 @@ jobs:
1414
"arduino:samd:nano_33_iot",
1515
"arduino:samd:mkrgsm1400",
1616
"arduino:samd:mkrnb1500",
17+
"arduino:samd:mkrwan1300",
18+
"arduino:samd:mkrwan1310",
1719
'"esp8266:esp8266:huzzah" "https://arduino.esp8266.com/stable/package_esp8266com_index.json"'
1820
]
1921

examples/ConnectionHandlerDemo/ConnectionHandlerDemo.ino

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ WiFiConnectionHandler conMan(SECRET_SSID, SECRET_PASS);
2626
GSMConnectionHandler conMan(SECRET_APN, SECRET_PIN, SECRET_GSM_USER, SECRET_GSM_PASS);
2727
#elif defined(BOARD_HAS_NB)
2828
NBConnectionHandler conMan(SECRET_PIN);
29+
#elif defined(BOARD_HAS_LORA)
30+
LoRaConnectionHandler conMan(SECRET_APP_EUI, SECRET_APP_KEY);
2931
#endif
3032

3133
void setup() {
@@ -35,10 +37,9 @@ void setup() {
3537

3638
setDebugMessageLevel(DBG_INFO);
3739

38-
/* Register a function to be called upon connection to a network */
39-
conMan.addConnectCallback(onNetworkConnect);
40-
/* Register a function to be called upon disconnection from a network */
41-
conMan.addDisconnectCallback(onNetworkDisconnect);
40+
conMan.addCallback(NetworkConnectionEvent::CONNECTED, onNetworkConnect);
41+
conMan.addCallback(NetworkConnectionEvent::DISCONNECTED, onNetworkDisconnect);
42+
conMan.addCallback(NetworkConnectionEvent::ERROR, onNetworkError);
4243
}
4344

4445
void loop() {
@@ -54,10 +55,14 @@ void loop() {
5455
conMan.check();
5556
}
5657

57-
void onNetworkConnect(void *_arg) {
58+
void onNetworkConnect() {
5859
Serial.println(">>>> CONNECTED to network");
5960
}
6061

61-
void onNetworkDisconnect(void *_arg) {
62+
void onNetworkDisconnect() {
6263
Serial.println(">>>> DISCONNECTED from network");
6364
}
65+
66+
void onNetworkError() {
67+
Serial.println(">>>> ERROR");
68+
}

examples/ConnectionHandlerDemo/arduino_secrets.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@ const char SECRET_PASS[] = "NETWORK PASSWORD";
44
const char SECRET_APN[] = "MOBILE PROVIDER APN ADDRESS";
55
const char SECRET_PIN[] = "0000";
66
const char SECRET_GSM_USER[] = "GSM USERNAME";
7-
const char SECRET_GSM_PASS[] = "GSM PASSWORD";
7+
const char SECRET_GSM_PASS[] = "GSM PASSWORD";
8+
9+
const char SECRET_APP_EUI[] = "APP_EUI";
10+
const char SECRET_APP_KEY[] = "APP_KEY";

keywords.txt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,24 @@
55
####################################################
66
# Datatypes (KEYWORD1)
77
####################################################
8-
Client KEYWORD1
98
ConnectionHandler KEYWORD1
109
WiFiConnectionHandler KEYWORD1
1110
GSMConnectionHandler KEYWORD1
1211
NBConnectionHandler KEYWORD1
13-
EthernetConnectionHandler KEYWORD1
12+
LoRaConnectionHandler KEYWORD1
1413

1514
####################################################
1615
# Methods and Functions (KEYWORD2)
1716
####################################################
1817

1918
ConnectionHandler KEYWORD2
20-
begin KEYWORD2
19+
check KEYWORD2
20+
connect KEYWORD2
21+
disconnect KEYWORD2
22+
addCallback KEYWORD2
23+
getTime KEYWORD2
24+
getClient KEYWORD2
25+
getUDP KEYWORD2
2126

2227
####################################################
2328
# Constants (LITERAL1)

src/Arduino_ConnectionHandler.cpp

Lines changed: 85 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,95 @@
2121

2222
#include "Arduino_ConnectionHandler.h"
2323

24+
/******************************************************************************
25+
CONSTRUCTOR/DESTRUCTOR
26+
******************************************************************************/
27+
28+
ConnectionHandler::ConnectionHandler(bool const keep_alive)
29+
: _keep_alive{keep_alive}
30+
, _current_net_connection_state{NetworkConnectionState::INIT}
31+
, _lastConnectionTickTime{millis()}
32+
{
33+
34+
}
35+
2436
/******************************************************************************
2537
PUBLIC MEMBER FUNCTIONS
2638
******************************************************************************/
2739

28-
void ConnectionHandler::addCallback(NetworkConnectionEvent const event, OnNetworkEventCallback callback) {
29-
switch (event) {
30-
case NetworkConnectionEvent::CONNECTED: _on_connect_event_callback = callback; break;
31-
case NetworkConnectionEvent::DISCONNECTED: _on_disconnect_event_callback = callback; break;
32-
case NetworkConnectionEvent::ERROR: _on_error_event_callback = callback; break;
33-
case NetworkConnectionEvent::INIT: ; break;
34-
case NetworkConnectionEvent::CONNECTING: ; break;
35-
case NetworkConnectionEvent::DISCONNECTING: ; break;
36-
case NetworkConnectionEvent::CLOSED: ; break;
40+
NetworkConnectionState ConnectionHandler::check()
41+
{
42+
unsigned long const now = millis();
43+
unsigned int const connectionTickTimeInterval = CHECK_INTERVAL_TABLE[static_cast<unsigned int>(_current_net_connection_state)];
44+
45+
if((now - _lastConnectionTickTime) > connectionTickTimeInterval)
46+
{
47+
_lastConnectionTickTime = now;
48+
NetworkConnectionState next_net_connection_state = _current_net_connection_state;
49+
50+
/* While the state machine is implemented here, the concrete implementation of the
51+
* states is done in the derived connection handlers.
52+
*/
53+
switch (_current_net_connection_state)
54+
{
55+
case NetworkConnectionState::INIT: next_net_connection_state = update_handleInit (); break;
56+
case NetworkConnectionState::CONNECTING: next_net_connection_state = update_handleConnecting (); break;
57+
case NetworkConnectionState::CONNECTED: next_net_connection_state = update_handleConnected (); break;
58+
case NetworkConnectionState::DISCONNECTING: next_net_connection_state = update_handleDisconnecting(); break;
59+
case NetworkConnectionState::DISCONNECTED: next_net_connection_state = update_handleDisconnected (); break;
60+
case NetworkConnectionState::ERROR: break;
61+
case NetworkConnectionState::CLOSED: break;
62+
}
63+
64+
/* Here we are determining whether a state transition from one state to the next has
65+
* occurred - and if it has, we call eventually registered callbacks.
66+
*/
67+
if(next_net_connection_state != _current_net_connection_state)
68+
{
69+
/* Check the next state to determine the kind of state conversion which has occurred (and call the appropriate callback) */
70+
if(next_net_connection_state == NetworkConnectionState::CONNECTED)
71+
{
72+
if(_on_connect_event_callback) _on_connect_event_callback();
73+
}
74+
if(next_net_connection_state == NetworkConnectionState::DISCONNECTED)
75+
{
76+
if(_on_disconnect_event_callback) _on_disconnect_event_callback();
77+
}
78+
if(next_net_connection_state == NetworkConnectionState::ERROR)
79+
{
80+
if(_on_error_event_callback) _on_error_event_callback();
81+
}
82+
83+
/* Assign new state to the member variable holding the state */
84+
_current_net_connection_state = next_net_connection_state;
85+
}
86+
}
87+
88+
return _current_net_connection_state;
89+
}
90+
91+
void ConnectionHandler::connect()
92+
{
93+
if (_current_net_connection_state != NetworkConnectionState::INIT && _current_net_connection_state != NetworkConnectionState::CONNECTING)
94+
{
95+
_keep_alive = true;
96+
_current_net_connection_state = NetworkConnectionState::INIT;
97+
}
98+
}
99+
100+
void ConnectionHandler::disconnect()
101+
{
102+
_keep_alive = false;
103+
_current_net_connection_state = NetworkConnectionState::DISCONNECTING;
104+
}
105+
106+
void ConnectionHandler::addCallback(NetworkConnectionEvent const event, OnNetworkEventCallback callback)
107+
{
108+
switch (event)
109+
{
110+
case NetworkConnectionEvent::CONNECTED: _on_connect_event_callback = callback; break;
111+
case NetworkConnectionEvent::DISCONNECTED: _on_disconnect_event_callback = callback; break;
112+
case NetworkConnectionEvent::ERROR: _on_error_event_callback = callback; break;
37113
}
38114
}
39115

@@ -46,10 +122,3 @@ void ConnectionHandler::addDisconnectCallback(OnNetworkEventCallback callback) {
46122
void ConnectionHandler::addErrorCallback(OnNetworkEventCallback callback) {
47123
_on_error_event_callback = callback;
48124
}
49-
50-
void ConnectionHandler::execNetworkEventCallback(OnNetworkEventCallback & callback, void * callback_arg) {
51-
if (callback) {
52-
(*callback)(callback_arg);
53-
}
54-
}
55-

src/Arduino_ConnectionHandler.h

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -113,31 +113,50 @@
113113
TYPEDEFS
114114
******************************************************************************/
115115

116-
enum class NetworkConnectionState {
117-
INIT,
118-
CONNECTING,
116+
enum class NetworkConnectionState : unsigned int {
117+
INIT = 0,
118+
CONNECTING = 1,
119+
CONNECTED = 2,
120+
DISCONNECTING = 3,
121+
DISCONNECTED = 4,
122+
CLOSED = 5,
123+
ERROR = 6
124+
};
125+
126+
enum class NetworkConnectionEvent {
119127
CONNECTED,
120-
GETTIME,
121-
DISCONNECTING,
122128
DISCONNECTED,
123-
CLOSED,
124129
ERROR
125130
};
126131

127-
enum class NetworkConnectionEvent {
128-
INIT, CONNECTING, CONNECTED, DISCONNECTING, DISCONNECTED, CLOSED, ERROR
129-
};
132+
typedef void (*OnNetworkEventCallback)();
130133

131-
typedef void (*OnNetworkEventCallback)(void * /* arg */);
134+
/******************************************************************************
135+
CONSTANTS
136+
******************************************************************************/
137+
138+
static unsigned int const CHECK_INTERVAL_TABLE[] =
139+
{
140+
/* INIT */ 100,
141+
/* CONNECTING */ 500,
142+
/* CONNECTED */ 10000,
143+
/* DISCONNECTING */ 100,
144+
/* DISCONNECTED */ 1000,
145+
/* CLOSED */ 1000,
146+
/* ERROR */ 1000
147+
};
132148

133149
/******************************************************************************
134150
CLASS DECLARATION
135151
******************************************************************************/
136152

137153
class ConnectionHandler {
138154
public:
139-
virtual void init() = 0;
140-
virtual NetworkConnectionState check() = 0;
155+
156+
ConnectionHandler(bool const keep_alive);
157+
158+
159+
NetworkConnectionState check();
141160

142161
#if defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined(BOARD_HAS_NB)
143162
virtual unsigned long getTime() = 0;
@@ -151,26 +170,36 @@ class ConnectionHandler {
151170
virtual bool available() = 0;
152171
#endif
153172

154-
virtual NetworkConnectionState getStatus() __attribute__((deprecated)) {
155-
return netConnectionState;
173+
NetworkConnectionState getStatus() __attribute__((deprecated)) {
174+
return _current_net_connection_state;
156175
}
157-
virtual void connect() = 0;
158-
virtual void disconnect() = 0;
176+
177+
void connect();
178+
void disconnect();
179+
159180
void addCallback(NetworkConnectionEvent const event, OnNetworkEventCallback callback);
160-
void addConnectCallback(OnNetworkEventCallback callback);
161-
void addDisconnectCallback(OnNetworkEventCallback callback);
162-
void addErrorCallback(OnNetworkEventCallback callback);
181+
void addConnectCallback(OnNetworkEventCallback callback) __attribute__((deprecated));
182+
void addDisconnectCallback(OnNetworkEventCallback callback) __attribute__((deprecated));
183+
void addErrorCallback(OnNetworkEventCallback callback) __attribute__((deprecated));
163184

164185
protected:
165-
OnNetworkEventCallback _on_connect_event_callback = NULL,
166-
_on_disconnect_event_callback = NULL,
167-
_on_error_event_callback = NULL;
168186

169-
unsigned long lastValidTimestamp = 0; /* UNUSED */
170-
NetworkConnectionState netConnectionState = NetworkConnectionState::INIT;
187+
bool _keep_alive;
171188

172-
static void execNetworkEventCallback(OnNetworkEventCallback & callback, void * callback_arg);
189+
virtual NetworkConnectionState update_handleInit () = 0;
190+
virtual NetworkConnectionState update_handleConnecting () = 0;
191+
virtual NetworkConnectionState update_handleConnected () = 0;
192+
virtual NetworkConnectionState update_handleDisconnecting() = 0;
193+
virtual NetworkConnectionState update_handleDisconnected () = 0;
173194

195+
196+
private:
197+
198+
unsigned long _lastConnectionTickTime;
199+
NetworkConnectionState _current_net_connection_state;
200+
OnNetworkEventCallback _on_connect_event_callback = NULL,
201+
_on_disconnect_event_callback = NULL,
202+
_on_error_event_callback = NULL;
174203
};
175204

176205
#if defined(BOARD_HAS_WIFI)

0 commit comments

Comments
 (0)