diff --git a/EthernetInterface.cpp b/EthernetInterface.cpp index f691f45..ddd762c 100644 --- a/EthernetInterface.cpp +++ b/EthernetInterface.cpp @@ -36,7 +36,16 @@ EthernetInterface * EthernetInterface::singleton=NULL; void EthernetInterface::setup() { singleton=new EthernetInterface(); - if (!singleton->connected) singleton=NULL; + + DIAG(F("Ethernet begin OK.")); + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + DIAG(F("Ethernet shield not found")); + + delete singleton; + singleton=NULL; + + return; + } }; @@ -60,38 +69,18 @@ EthernetInterface::EthernetInterface() DIAG(F("Ethernet.begin FAILED")); return; } - #endif - DIAG(F("begin OK.")); - if (Ethernet.hardwareStatus() == EthernetNoHardware) { - DIAG(F("Ethernet shield not found")); - return; - } - - unsigned long startmilli = millis(); - while ((millis() - startmilli) < 5500) // Loop to give time to check for cable connection - { - if (Ethernet.linkStatus() == LinkON) - break; - DIAG(F("Ethernet waiting for link (1sec) ")); - delay(1000); - } + #endif +} - if (Ethernet.linkStatus() == LinkOFF) { - DIAG(F("Ethernet cable not connected")); - return; - } - - connected=true; - - IPAddress ip = Ethernet.localIP(); // reassign the obtained ip address - - server = new EthernetServer(IP_PORT); // Ethernet Server listening on default port IP_PORT - server->begin(); - - LCD(4,F("IP: %d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]); - LCD(5,F("Port:%d"), IP_PORT); - - outboundRing=new RingStream(OUTBOUND_RING_SIZE); +/** + * @brief Cleanup any resources + * + * @return none + */ +EthernetInterface::~EthernetInterface() +{ + delete server; + delete outboundRing; } /** @@ -99,8 +88,9 @@ EthernetInterface::EthernetInterface() * */ void EthernetInterface::loop() -{ - if (!singleton) return; +{ + if(!singleton || (!singleton->checkLink())) + return; switch (Ethernet.maintain()) { @@ -125,6 +115,60 @@ void EthernetInterface::loop() } +/** + * @brief Checks ethernet link cable status and detects when it connects / disconnects + * + * @return true when cable is connected, false otherwise + */ +bool EthernetInterface::checkLink() +{ + if (Ethernet.linkStatus() == LinkON) + { + //if we are not connected yet, setup a new server + if(!connected) + { + DIAG(F("Ethernet cable connected")); + + connected=true; + + IPAddress ip = Ethernet.localIP(); // reassign the obtained ip address + + server = new EthernetServer(IP_PORT); // Ethernet Server listening on default port IP_PORT + server->begin(); + + LCD(4,F("IP: %d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]); + LCD(5,F("Port:%d"), IP_PORT); + + // + //only create a outboundRing it none exists, this may happen if the cable gets disconnected and connected again + if(!outboundRing) + outboundRing=new RingStream(OUTBOUND_RING_SIZE); + } + + return true; + } + else if(connected) + { + DIAG(F("Ethernet cable disconnected")); + connected=false; + + //clean up any client + for (byte socket = 0; socket < MAX_SOCK_NUM; socket++) + { + if(clients[socket].connected()) + clients[socket].stop(); + } + + /* tear down server */ + delete server; + server = nullptr; + + LCD(4,F("IP: None")); + } + + return false; +} + void EthernetInterface::loop2() { // get client from the server diff --git a/EthernetInterface.h b/EthernetInterface.h index 2a94ac6..ce5bbd9 100644 --- a/EthernetInterface.h +++ b/EthernetInterface.h @@ -59,11 +59,15 @@ class EthernetInterface { static EthernetInterface * singleton; bool connected; EthernetInterface(); + ~EthernetInterface(); void loop2(); - EthernetServer * server; + + bool checkLink(); + + EthernetServer * server = nullptr; EthernetClient clients[MAX_SOCK_NUM]; // accept up to MAX_SOCK_NUM client connections at the same time; This depends on the chipset used on the Shield uint8_t buffer[MAX_ETH_BUFFER+1]; // buffer used by TCP for the recv - RingStream * outboundRing; + RingStream * outboundRing = nullptr; };