diff --git a/examples/ConnectionHandlerDemo/ConnectionHandlerDemo.ino b/examples/ConnectionHandlerDemo/ConnectionHandlerDemo.ino index b106eed6..4c364a51 100644 --- a/examples/ConnectionHandlerDemo/ConnectionHandlerDemo.ino +++ b/examples/ConnectionHandlerDemo/ConnectionHandlerDemo.ino @@ -14,13 +14,26 @@ * If using a MKR NB1500 you'll need a NBConnectionHandler object as follows * * NBConnectionHandler conMan(SECRET_PIN); + * + * If using a Portenta + Ethernet shield you'll need a EthernetConnectionHandler object as follows: + * + * DHCP mode + * EthernetConnectionHandler conMan(); + * + * Manual configuration + * EthernetConnectionHandler conMan(SECRET_IP, SECRET_DNS, SECRET_GATEWAY, SECRET_NETMASK); + * + * Manual configuration will fallback on DHCP mode if SECRET_IP is invalid or equal to INADDR_NONE. + * */ #include "arduino_secrets.h" #include -#if defined(BOARD_HAS_WIFI) +#if defined(BOARD_HAS_ETHERNET) +EthernetConnectionHandler conMan(SECRET_IP, SECRET_DNS, SECRET_GATEWAY, SECRET_NETMASK); +#elif defined(BOARD_HAS_WIFI) WiFiConnectionHandler conMan(SECRET_SSID, SECRET_PASS); #elif defined(BOARD_HAS_GSM) GSMConnectionHandler conMan(SECRET_APN, SECRET_PIN, SECRET_GSM_USER, SECRET_GSM_PASS); diff --git a/examples/ConnectionHandlerDemo/arduino_secrets.h b/examples/ConnectionHandlerDemo/arduino_secrets.h index 0a2a2fe6..5836270e 100644 --- a/examples/ConnectionHandlerDemo/arduino_secrets.h +++ b/examples/ConnectionHandlerDemo/arduino_secrets.h @@ -8,3 +8,8 @@ const char SECRET_GSM_PASS[] = "GSM PASSWORD"; const char SECRET_APP_EUI[] = "APP_EUI"; const char SECRET_APP_KEY[] = "APP_KEY"; + +const char SECRET_IP[] = "IP ADDRESS"; +const char SECRET_DNS[] = "DNS ADDRESS"; +const char SECRET_GATEWAY[] = "GATEWAY ADDRESS"; +const char SECRET_NETMASK[] = "NETWORK MASK"; diff --git a/keywords.txt b/keywords.txt index 8d9e9434..4ac67251 100644 --- a/keywords.txt +++ b/keywords.txt @@ -10,6 +10,7 @@ WiFiConnectionHandler KEYWORD1 GSMConnectionHandler KEYWORD1 NBConnectionHandler KEYWORD1 LoRaConnectionHandler KEYWORD1 +EthernetConnectionHandler KEYWORD1 #################################################### # Methods and Functions (KEYWORD2) diff --git a/src/Arduino_ConnectionHandler.cpp b/src/Arduino_ConnectionHandler.cpp index 943fa1d9..ab83fa08 100644 --- a/src/Arduino_ConnectionHandler.cpp +++ b/src/Arduino_ConnectionHandler.cpp @@ -25,8 +25,9 @@ CONSTRUCTOR/DESTRUCTOR ******************************************************************************/ -ConnectionHandler::ConnectionHandler(bool const keep_alive) +ConnectionHandler::ConnectionHandler(bool const keep_alive, NetworkAdapter interface) : _keep_alive{keep_alive} +, _interface{interface} , _lastConnectionTickTime{millis()} , _current_net_connection_state{NetworkConnectionState::INIT} { diff --git a/src/Arduino_ConnectionHandler.h b/src/Arduino_ConnectionHandler.h index cc70f5fe..9a5d6961 100644 --- a/src/Arduino_ConnectionHandler.h +++ b/src/Arduino_ConnectionHandler.h @@ -43,7 +43,21 @@ #define WIFI_FIRMWARE_VERSION_REQUIRED WIFI_FIRMWARE_LATEST_VERSION #endif -#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_NICLA_VISION) +#if defined(ARDUINO_PORTENTA_H7_M7) + #include + #include + #include + #include + + #define BOARD_HAS_WIFI + #define BOARD_HAS_ETHERNET + #define BOARD_HAS_PORTENTA_VISION_SHIELD_ETHERNET + #define NETWORK_HARDWARE_ERROR WL_NO_SHIELD + #define NETWORK_IDLE_STATUS WL_IDLE_STATUS + #define NETWORK_CONNECTED WL_CONNECTED +#endif + +#if defined(ARDUINO_NICLA_VISION) #include #include @@ -124,6 +138,14 @@ enum class NetworkConnectionEvent { ERROR }; +enum class NetworkAdapter { + WIFI, + ETHERNET, + NB, + GSM, + LORA +}; + typedef void (*OnNetworkEventCallback)(); /****************************************************************************** @@ -148,12 +170,12 @@ static unsigned int const CHECK_INTERVAL_TABLE[] = class ConnectionHandler { public: - ConnectionHandler(bool const keep_alive); + ConnectionHandler(bool const keep_alive, NetworkAdapter interface); NetworkConnectionState check(); - #if defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined(BOARD_HAS_NB) + #if defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined(BOARD_HAS_NB) || defined(BOARD_HAS_ETHERNET) virtual unsigned long getTime() = 0; virtual Client &getClient() = 0; virtual UDP &getUDP() = 0; @@ -169,6 +191,10 @@ class ConnectionHandler { return _current_net_connection_state; } + NetworkAdapter getInterface() { + return _interface; + } + void connect(); void disconnect(); @@ -180,6 +206,7 @@ class ConnectionHandler { protected: bool _keep_alive; + NetworkAdapter _interface; virtual NetworkConnectionState update_handleInit () = 0; virtual NetworkConnectionState update_handleConnecting () = 0; @@ -207,4 +234,8 @@ class ConnectionHandler { #include "Arduino_LoRaConnectionHandler.h" #endif +#if defined(BOARD_HAS_ETHERNET) + #include "Arduino_EthernetConnectionHandler.h" +#endif + #endif /* CONNECTION_HANDLER_H_ */ diff --git a/src/Arduino_EthernetConnectionHandler.cpp b/src/Arduino_EthernetConnectionHandler.cpp new file mode 100644 index 00000000..0753eb23 --- /dev/null +++ b/src/Arduino_EthernetConnectionHandler.cpp @@ -0,0 +1,129 @@ +/* + This file is part of ArduinoIoTCloud. + Copyright 2020 ARDUINO SA (http://www.arduino.cc/) + This software is released under the GNU General Public License version 3, + which covers the main part of arduino-cli. + The terms of this license can be found at: + https://www.gnu.org/licenses/gpl-3.0.en.html + You can be released from the requirements of the above licenses by purchasing + a commercial license. Buying such a license is mandatory if you want to modify or + otherwise use the software for commercial activities involving the Arduino + software without disclosing the source code of your own applications. To purchase + a commercial license, send an email to license@arduino.cc. +*/ + +/****************************************************************************** + INCLUDE + ******************************************************************************/ + +#include "Arduino_EthernetConnectionHandler.h" + +#ifdef BOARD_HAS_ETHERNET /* Only compile if the board has ethernet */ + +/****************************************************************************** + CTOR/DTOR + ******************************************************************************/ + +EthernetConnectionHandler::EthernetConnectionHandler(bool const keep_alive) +: ConnectionHandler{keep_alive, NetworkAdapter::ETHERNET} +,_ip{INADDR_NONE} +,_dns{INADDR_NONE} +,_gateway{INADDR_NONE} +,_netmask{INADDR_NONE} +{ + +} + +EthernetConnectionHandler::EthernetConnectionHandler(const IPAddress ip, const IPAddress dns, const IPAddress gateway, const IPAddress netmask, bool const keep_alive) +: ConnectionHandler{keep_alive, NetworkAdapter::ETHERNET} +,_ip{ip} +,_dns{dns} +,_gateway{gateway} +,_netmask{netmask} +{ + +} + +EthernetConnectionHandler::EthernetConnectionHandler(const char * ip, const char * dns, const char * gateway, const char * netmask, bool const keep_alive) +: ConnectionHandler{keep_alive, NetworkAdapter::ETHERNET} +,_ip{INADDR_NONE} +,_dns{INADDR_NONE} +,_gateway{INADDR_NONE} +,_netmask{INADDR_NONE} +{ + if(!_ip.fromString(ip)) { + _ip = INADDR_NONE; + } + if(!_dns.fromString(dns)) { + _dns = INADDR_NONE; + } + if(!_gateway.fromString(gateway)) { + _gateway = INADDR_NONE; + } + if(!_netmask.fromString(netmask)) { + _netmask = INADDR_NONE; + } +} + +/****************************************************************************** + PROTECTED MEMBER FUNCTIONS + ******************************************************************************/ + +NetworkConnectionState EthernetConnectionHandler::update_handleInit() +{ + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Debug.print(DBG_ERROR, F("Error, ethernet shield was not found.")); + return NetworkConnectionState::ERROR; + } + return NetworkConnectionState::CONNECTING; +} + +NetworkConnectionState EthernetConnectionHandler::update_handleConnecting() +{ + if (_ip != INADDR_NONE) { + if (Ethernet.begin(nullptr, _ip, _dns, _gateway, _netmask, 15000, 4000) == 0) { + Debug.print(DBG_ERROR, F("Failed to configure Ethernet, check cable connection")); + return NetworkConnectionState::CONNECTING; + } + } else { + if (Ethernet.begin(nullptr, 15000, 4000) == 0) { + Debug.print(DBG_ERROR, F("Waiting Ethernet configuration from DHCP server, check cable connection")); + return NetworkConnectionState::CONNECTING; + } + } + + return NetworkConnectionState::CONNECTED; +} + +NetworkConnectionState EthernetConnectionHandler::update_handleConnected() +{ + if (Ethernet.linkStatus() == LinkOFF) { + Debug.print(DBG_ERROR, F("Ethernet link OFF, connection lost.")); + if (_keep_alive) + { + Debug.print(DBG_ERROR, F("Attempting reconnection")); + } + return NetworkConnectionState::DISCONNECTED; + } + return NetworkConnectionState::CONNECTED; +} + +NetworkConnectionState EthernetConnectionHandler::update_handleDisconnecting() +{ + Ethernet.disconnect(); + return NetworkConnectionState::DISCONNECTED; +} + +NetworkConnectionState EthernetConnectionHandler::update_handleDisconnected() +{ + if (_keep_alive) + { + return NetworkConnectionState::INIT; + } + else + { + return NetworkConnectionState::CLOSED; + } +} + +#endif /* #ifdef BOARD_HAS_ETHERNET */ diff --git a/src/Arduino_EthernetConnectionHandler.h b/src/Arduino_EthernetConnectionHandler.h new file mode 100644 index 00000000..bac7bf45 --- /dev/null +++ b/src/Arduino_EthernetConnectionHandler.h @@ -0,0 +1,66 @@ +/* + This file is part of ArduinoIoTCloud. + Copyright 2020 ARDUINO SA (http://www.arduino.cc/) + This software is released under the GNU General Public License version 3, + which covers the main part of arduino-cli. + The terms of this license can be found at: + https://www.gnu.org/licenses/gpl-3.0.en.html + You can be released from the requirements of the above licenses by purchasing + a commercial license. Buying such a license is mandatory if you want to modify or + otherwise use the software for commercial activities involving the Arduino + software without disclosing the source code of your own applications. To purchase + a commercial license, send an email to license@arduino.cc. +*/ + +#ifndef ARDUINO_ETHERNET_CONNECTION_HANDLER_H_ +#define ARDUINO_ETHERNET_CONNECTION_HANDLER_H_ + +/****************************************************************************** + INCLUDE + ******************************************************************************/ + +#include "Arduino_ConnectionHandler.h" + +#ifdef BOARD_HAS_ETHERNET /* Only compile if the board has ethernet */ + +/****************************************************************************** + CLASS DECLARATION + ******************************************************************************/ + +class EthernetConnectionHandler : public ConnectionHandler +{ + public: + + EthernetConnectionHandler(bool const keep_alive = true); + EthernetConnectionHandler(const IPAddress ip, const IPAddress dns, const IPAddress gateway, const IPAddress netmask, bool const keep_alive = true); + EthernetConnectionHandler(const char * ip, const char * dns, const char * gateway, const char * netmask, bool const keep_alive = true); + + + virtual unsigned long getTime() override { return 0; } + virtual Client & getClient() override{ return _eth_client; } + virtual UDP & getUDP() override { return _eth_udp; } + + + protected: + + virtual NetworkConnectionState update_handleInit () override; + virtual NetworkConnectionState update_handleConnecting () override; + virtual NetworkConnectionState update_handleConnected () override; + virtual NetworkConnectionState update_handleDisconnecting() override; + virtual NetworkConnectionState update_handleDisconnected () override; + + private: + + IPAddress _ip; + IPAddress _dns; + IPAddress _gateway; + IPAddress _netmask; + + EthernetUDP _eth_udp; + EthernetClient _eth_client; + +}; + +#endif /* #ifdef BOARD_HAS_ETHERNET */ + +#endif /* ARDUINO_ETHERNET_CONNECTION_HANDLER_H_ */ diff --git a/src/Arduino_GSMConnectionHandler.cpp b/src/Arduino_GSMConnectionHandler.cpp index 3bf8b908..e57a7201 100644 --- a/src/Arduino_GSMConnectionHandler.cpp +++ b/src/Arduino_GSMConnectionHandler.cpp @@ -47,7 +47,7 @@ __attribute__((weak)) void mkr_gsm_feed_watchdog() ******************************************************************************/ GSMConnectionHandler::GSMConnectionHandler(const char * pin, const char * apn, const char * login, const char * pass, bool const keep_alive) -: ConnectionHandler{keep_alive} +: ConnectionHandler{keep_alive, NetworkAdapter::GSM} , _pin(pin) , _apn(apn) , _login(login) diff --git a/src/Arduino_LoRaConnectionHandler.cpp b/src/Arduino_LoRaConnectionHandler.cpp index e34092b0..886c7e3f 100644 --- a/src/Arduino_LoRaConnectionHandler.cpp +++ b/src/Arduino_LoRaConnectionHandler.cpp @@ -44,7 +44,7 @@ typedef enum CTOR/DTOR ******************************************************************************/ LoRaConnectionHandler::LoRaConnectionHandler(char const * appeui, char const * appkey, _lora_band const band, char const * channelMask, _lora_class const device_class) -: ConnectionHandler{false} +: ConnectionHandler{false, NetworkAdapter::LORA} , _appeui(appeui) , _appkey(appkey) , _band(band) diff --git a/src/Arduino_NBConnectionHandler.cpp b/src/Arduino_NBConnectionHandler.cpp index 8c747edf..ae74a238 100644 --- a/src/Arduino_NBConnectionHandler.cpp +++ b/src/Arduino_NBConnectionHandler.cpp @@ -57,7 +57,7 @@ NBConnectionHandler::NBConnectionHandler(char const * pin, char const * apn, boo } NBConnectionHandler::NBConnectionHandler(char const * pin, char const * apn, char const * login, char const * pass, bool const keep_alive) -: ConnectionHandler{keep_alive} +: ConnectionHandler{keep_alive, NetworkAdapter::NB} , _pin(pin) , _apn(apn) , _login(login) diff --git a/src/Arduino_WiFiConnectionHandler.cpp b/src/Arduino_WiFiConnectionHandler.cpp index 45a23b99..eb897450 100644 --- a/src/Arduino_WiFiConnectionHandler.cpp +++ b/src/Arduino_WiFiConnectionHandler.cpp @@ -28,7 +28,7 @@ ******************************************************************************/ WiFiConnectionHandler::WiFiConnectionHandler(char const * ssid, char const * pass, bool const keep_alive) -: ConnectionHandler{keep_alive} +: ConnectionHandler{keep_alive, NetworkAdapter::WIFI} , _ssid{ssid} , _pass{pass} {