Skip to content

Clean-up of connection handler for better maintainability. #26

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 54 commits into from
Mar 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
5f421cf
Marking 'addConnectCallback', 'addDisconnectCallback' and 'addErrorCa…
aentinger Mar 9, 2020
a040439
Make function pointer containing connection handler event callbacks p…
aentinger Mar 9, 2020
fc61661
Removing unused member variable 'lastValidTimestamp'
aentinger Mar 9, 2020
07d54b5
Removing typedef no longer required due to merging https://github.com…
aentinger Mar 9, 2020
2aa54e1
Using table instead of individual constants for determining the check…
aentinger Mar 9, 2020
ed81414
Rearranging member variables to provide an identical code look and fe…
aentinger Mar 9, 2020
66263ba
Eliminating unused method WiFiConnectionHandler::init since it's func…
aentinger Mar 9, 2020
1ddba2b
Adding keyword override to allow the determine to compiler if the met…
aentinger Mar 9, 2020
617c08f
Move functionality of init() into update_handleInit() which also perf…
aentinger Mar 10, 2020
07c2ccf
Extracting functionality of state CONNECTING into function handle_upd…
aentinger Mar 10, 2020
8e2af82
Extracting functionality of state CONNECTED into function handle_upda…
aentinger Mar 10, 2020
5c56b61
Extracting functionality of state DISCONNECTING into function handle_…
aentinger Mar 10, 2020
148945f
Extracting functionality of state DISCONNECTED into function handle_u…
aentinger Mar 10, 2020
96f6bab
Restructuring member variables and adding missing states to state mac…
aentinger Mar 10, 2020
96f4763
Moving functionality concerning a disconnection into function disconnect
aentinger Mar 10, 2020
346666a
Restructuring connect function
aentinger Mar 10, 2020
a202e6e
Eliminating changeConnectionState
aentinger Mar 10, 2020
483885b
Using lookup table for timeouts similiar to the WiFi connection handler
aentinger Mar 10, 2020
9d3f6b4
Adding keyword override to allow compiler check if really a base clas…
aentinger Mar 10, 2020
77a1378
Rename _udp to _gsm_udp
aentinger Mar 10, 2020
ccd6b87
Fixing formatting/braces for better readability
aentinger Mar 10, 2020
6051c20
Removing unused function init
aentinger Mar 10, 2020
74208bd
Deleting function getTime which is not necessary for the LoRa_Connect…
aentinger Mar 10, 2020
5ea1655
Deleting initalisation of netConnectionState to NetworkConnectionStat…
aentinger Mar 10, 2020
1419ec3
Fixing up member variables
aentinger Mar 10, 2020
80ab4d8
Cleanup connect/disconnect methods
aentinger Mar 10, 2020
be76df6
Using table for check interval times instead of member variable
aentinger Mar 10, 2020
37f9228
Major simplification of existing code
aentinger Mar 10, 2020
11f936f
Adding keyword override to allow compiler check if really a base clas…
aentinger Mar 10, 2020
ffaa0f1
Deleting all debug statements with verbose debug output - development…
aentinger Mar 10, 2020
a39cd77
Prefixing member variable netConnectionState with '_' to mark it as a…
aentinger Mar 10, 2020
7b7f0fb
Fixing formatting
aentinger Mar 10, 2020
fb87b3b
Removing callback arg since it is anyway always 0 and was never used
aentinger Mar 10, 2020
7bb1b55
Restructuring member variables
aentinger Mar 10, 2020
ff99572
Adding keyword override to allow compiler check if really a base clas…
aentinger Mar 10, 2020
7e7121d
Restructuring connect/disconnect
aentinger Mar 10, 2020
7b4b50a
Using table for check interval times instead of member variable
aentinger Mar 10, 2020
da5e079
Fixing braces for easier reading
aentinger Mar 10, 2020
45635e5
Deleting code which is problematic because the execution of the if tr…
aentinger Mar 12, 2020
76e9c34
Extract direct implementation of switch/case into small functions
aentinger Mar 12, 2020
af63002
Moving _gsm.shutdown() call out of disconnect function which will all…
aentinger Mar 12, 2020
920cc4a
Moving implementation of connect/disconnect into base class Arduino_C…
aentinger Mar 12, 2020
e7ae47c
Removing no longer necessary keyword virtual
aentinger Mar 12, 2020
8172a1d
Move retrieval of time for ESP8266 out of update_handleGetTime since …
aentinger Mar 12, 2020
c1292ff
Remove NetworkConnectionState::GETTIME and share check interval table…
aentinger Mar 12, 2020
bc378d5
Employing the template method pattern to only implement the state mac…
aentinger Mar 12, 2020
1d5589b
Deleting comment
aentinger Mar 12, 2020
8f2118b
Turning _netConnectionState private so that derived classes can't acc…
aentinger Mar 12, 2020
6503c26
Deleting those NetworkConnectionEvent states for which one anyway can…
aentinger Mar 12, 2020
6499bdf
Renaming _netConnectionState to _current_net_connection_state
aentinger Mar 12, 2020
3a82983
Adding callback in case of network error to example file
aentinger Mar 12, 2020
821180d
Perform callbacks in case of state transitions in base class now
aentinger Mar 12, 2020
28fb13e
Enable CI compilation for MKRWAN1300/1310
aentinger Mar 12, 2020
bf2b5b0
Fixing keywords
aentinger Mar 16, 2020
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
4 changes: 3 additions & 1 deletion .github/workflows/compile-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ jobs:
runs-on: ubuntu-latest

env:
LIBRARIES: Arduino_DebugUtils WiFi101 WiFiNINA MKRGSM MKRNB
LIBRARIES: Arduino_DebugUtils WiFi101 WiFiNINA MKRGSM MKRNB MKRWAN
strategy:
matrix:
fqbn: [
Expand All @@ -14,6 +14,8 @@ jobs:
"arduino:samd:nano_33_iot",
"arduino:samd:mkrgsm1400",
"arduino:samd:mkrnb1500",
"arduino:samd:mkrwan1300",
"arduino:samd:mkrwan1310",
'"esp8266:esp8266:huzzah" "https://arduino.esp8266.com/stable/package_esp8266com_index.json"'
]

Expand Down
17 changes: 11 additions & 6 deletions examples/ConnectionHandlerDemo/ConnectionHandlerDemo.ino
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ WiFiConnectionHandler conMan(SECRET_SSID, SECRET_PASS);
GSMConnectionHandler conMan(SECRET_APN, SECRET_PIN, SECRET_GSM_USER, SECRET_GSM_PASS);
#elif defined(BOARD_HAS_NB)
NBConnectionHandler conMan(SECRET_PIN);
#elif defined(BOARD_HAS_LORA)
LoRaConnectionHandler conMan(SECRET_APP_EUI, SECRET_APP_KEY);
#endif

void setup() {
Expand All @@ -35,10 +37,9 @@ void setup() {

setDebugMessageLevel(DBG_INFO);

/* Register a function to be called upon connection to a network */
conMan.addConnectCallback(onNetworkConnect);
/* Register a function to be called upon disconnection from a network */
conMan.addDisconnectCallback(onNetworkDisconnect);
conMan.addCallback(NetworkConnectionEvent::CONNECTED, onNetworkConnect);
conMan.addCallback(NetworkConnectionEvent::DISCONNECTED, onNetworkDisconnect);
conMan.addCallback(NetworkConnectionEvent::ERROR, onNetworkError);
}

void loop() {
Expand All @@ -54,10 +55,14 @@ void loop() {
conMan.check();
}

void onNetworkConnect(void *_arg) {
void onNetworkConnect() {
Serial.println(">>>> CONNECTED to network");
}

void onNetworkDisconnect(void *_arg) {
void onNetworkDisconnect() {
Serial.println(">>>> DISCONNECTED from network");
}

void onNetworkError() {
Serial.println(">>>> ERROR");
}
5 changes: 4 additions & 1 deletion examples/ConnectionHandlerDemo/arduino_secrets.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ const char SECRET_PASS[] = "NETWORK PASSWORD";
const char SECRET_APN[] = "MOBILE PROVIDER APN ADDRESS";
const char SECRET_PIN[] = "0000";
const char SECRET_GSM_USER[] = "GSM USERNAME";
const char SECRET_GSM_PASS[] = "GSM PASSWORD";
const char SECRET_GSM_PASS[] = "GSM PASSWORD";

const char SECRET_APP_EUI[] = "APP_EUI";
const char SECRET_APP_KEY[] = "APP_KEY";
11 changes: 8 additions & 3 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,24 @@
####################################################
# Datatypes (KEYWORD1)
####################################################
Client KEYWORD1
ConnectionHandler KEYWORD1
WiFiConnectionHandler KEYWORD1
GSMConnectionHandler KEYWORD1
NBConnectionHandler KEYWORD1
EthernetConnectionHandler KEYWORD1
LoRaConnectionHandler KEYWORD1

####################################################
# Methods and Functions (KEYWORD2)
####################################################

ConnectionHandler KEYWORD2
begin KEYWORD2
check KEYWORD2
connect KEYWORD2
disconnect KEYWORD2
addCallback KEYWORD2
getTime KEYWORD2
getClient KEYWORD2
getUDP KEYWORD2

####################################################
# Constants (LITERAL1)
Expand Down
101 changes: 85 additions & 16 deletions src/Arduino_ConnectionHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,95 @@

#include "Arduino_ConnectionHandler.h"

/******************************************************************************
CONSTRUCTOR/DESTRUCTOR
******************************************************************************/

ConnectionHandler::ConnectionHandler(bool const keep_alive)
: _keep_alive{keep_alive}
, _current_net_connection_state{NetworkConnectionState::INIT}
, _lastConnectionTickTime{millis()}
{

}

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

void ConnectionHandler::addCallback(NetworkConnectionEvent const event, OnNetworkEventCallback callback) {
switch (event) {
case NetworkConnectionEvent::CONNECTED: _on_connect_event_callback = callback; break;
case NetworkConnectionEvent::DISCONNECTED: _on_disconnect_event_callback = callback; break;
case NetworkConnectionEvent::ERROR: _on_error_event_callback = callback; break;
case NetworkConnectionEvent::INIT: ; break;
case NetworkConnectionEvent::CONNECTING: ; break;
case NetworkConnectionEvent::DISCONNECTING: ; break;
case NetworkConnectionEvent::CLOSED: ; break;
NetworkConnectionState ConnectionHandler::check()
{
unsigned long const now = millis();
unsigned int const connectionTickTimeInterval = CHECK_INTERVAL_TABLE[static_cast<unsigned int>(_current_net_connection_state)];

if((now - _lastConnectionTickTime) > connectionTickTimeInterval)
{
_lastConnectionTickTime = now;
NetworkConnectionState next_net_connection_state = _current_net_connection_state;

/* While the state machine is implemented here, the concrete implementation of the
* states is done in the derived connection handlers.
*/
switch (_current_net_connection_state)
{
case NetworkConnectionState::INIT: next_net_connection_state = update_handleInit (); break;
case NetworkConnectionState::CONNECTING: next_net_connection_state = update_handleConnecting (); break;
case NetworkConnectionState::CONNECTED: next_net_connection_state = update_handleConnected (); break;
case NetworkConnectionState::DISCONNECTING: next_net_connection_state = update_handleDisconnecting(); break;
case NetworkConnectionState::DISCONNECTED: next_net_connection_state = update_handleDisconnected (); break;
case NetworkConnectionState::ERROR: break;
case NetworkConnectionState::CLOSED: break;
}

/* Here we are determining whether a state transition from one state to the next has
* occurred - and if it has, we call eventually registered callbacks.
*/
if(next_net_connection_state != _current_net_connection_state)
{
/* Check the next state to determine the kind of state conversion which has occurred (and call the appropriate callback) */
if(next_net_connection_state == NetworkConnectionState::CONNECTED)
{
if(_on_connect_event_callback) _on_connect_event_callback();
}
if(next_net_connection_state == NetworkConnectionState::DISCONNECTED)
{
if(_on_disconnect_event_callback) _on_disconnect_event_callback();
}
if(next_net_connection_state == NetworkConnectionState::ERROR)
{
if(_on_error_event_callback) _on_error_event_callback();
}

/* Assign new state to the member variable holding the state */
_current_net_connection_state = next_net_connection_state;
}
}

return _current_net_connection_state;
}

void ConnectionHandler::connect()
{
if (_current_net_connection_state != NetworkConnectionState::INIT && _current_net_connection_state != NetworkConnectionState::CONNECTING)
{
_keep_alive = true;
_current_net_connection_state = NetworkConnectionState::INIT;
}
}

void ConnectionHandler::disconnect()
{
_keep_alive = false;
_current_net_connection_state = NetworkConnectionState::DISCONNECTING;
}

void ConnectionHandler::addCallback(NetworkConnectionEvent const event, OnNetworkEventCallback callback)
{
switch (event)
{
case NetworkConnectionEvent::CONNECTED: _on_connect_event_callback = callback; break;
case NetworkConnectionEvent::DISCONNECTED: _on_disconnect_event_callback = callback; break;
case NetworkConnectionEvent::ERROR: _on_error_event_callback = callback; break;
}
}

Expand All @@ -46,10 +122,3 @@ void ConnectionHandler::addDisconnectCallback(OnNetworkEventCallback callback) {
void ConnectionHandler::addErrorCallback(OnNetworkEventCallback callback) {
_on_error_event_callback = callback;
}

void ConnectionHandler::execNetworkEventCallback(OnNetworkEventCallback & callback, void * callback_arg) {
if (callback) {
(*callback)(callback_arg);
}
}

79 changes: 54 additions & 25 deletions src/Arduino_ConnectionHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,31 +113,50 @@
TYPEDEFS
******************************************************************************/

enum class NetworkConnectionState {
INIT,
CONNECTING,
enum class NetworkConnectionState : unsigned int {
INIT = 0,
CONNECTING = 1,
CONNECTED = 2,
DISCONNECTING = 3,
DISCONNECTED = 4,
CLOSED = 5,
ERROR = 6
};

enum class NetworkConnectionEvent {
CONNECTED,
GETTIME,
DISCONNECTING,
DISCONNECTED,
CLOSED,
ERROR
};

enum class NetworkConnectionEvent {
INIT, CONNECTING, CONNECTED, DISCONNECTING, DISCONNECTED, CLOSED, ERROR
};
typedef void (*OnNetworkEventCallback)();

typedef void (*OnNetworkEventCallback)(void * /* arg */);
/******************************************************************************
CONSTANTS
******************************************************************************/

static unsigned int const CHECK_INTERVAL_TABLE[] =
{
/* INIT */ 100,
/* CONNECTING */ 500,
/* CONNECTED */ 10000,
/* DISCONNECTING */ 100,
/* DISCONNECTED */ 1000,
/* CLOSED */ 1000,
/* ERROR */ 1000
};

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

class ConnectionHandler {
public:
virtual void init() = 0;
virtual NetworkConnectionState check() = 0;

ConnectionHandler(bool const keep_alive);


NetworkConnectionState check();

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

virtual NetworkConnectionState getStatus() __attribute__((deprecated)) {
return netConnectionState;
NetworkConnectionState getStatus() __attribute__((deprecated)) {
return _current_net_connection_state;
}
virtual void connect() = 0;
virtual void disconnect() = 0;

void connect();
void disconnect();

void addCallback(NetworkConnectionEvent const event, OnNetworkEventCallback callback);
void addConnectCallback(OnNetworkEventCallback callback);
void addDisconnectCallback(OnNetworkEventCallback callback);
void addErrorCallback(OnNetworkEventCallback callback);
void addConnectCallback(OnNetworkEventCallback callback) __attribute__((deprecated));
void addDisconnectCallback(OnNetworkEventCallback callback) __attribute__((deprecated));
void addErrorCallback(OnNetworkEventCallback callback) __attribute__((deprecated));

protected:
OnNetworkEventCallback _on_connect_event_callback = NULL,
_on_disconnect_event_callback = NULL,
_on_error_event_callback = NULL;

unsigned long lastValidTimestamp = 0; /* UNUSED */
NetworkConnectionState netConnectionState = NetworkConnectionState::INIT;
bool _keep_alive;

static void execNetworkEventCallback(OnNetworkEventCallback & callback, void * callback_arg);
virtual NetworkConnectionState update_handleInit () = 0;
virtual NetworkConnectionState update_handleConnecting () = 0;
virtual NetworkConnectionState update_handleConnected () = 0;
virtual NetworkConnectionState update_handleDisconnecting() = 0;
virtual NetworkConnectionState update_handleDisconnected () = 0;


private:

unsigned long _lastConnectionTickTime;
NetworkConnectionState _current_net_connection_state;
OnNetworkEventCallback _on_connect_event_callback = NULL,
_on_disconnect_event_callback = NULL,
_on_error_event_callback = NULL;
};

#if defined(BOARD_HAS_WIFI)
Expand Down
Loading