Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Crocker <dcrocker@eschertech.com>2016-12-29 17:10:53 +0300
committerDavid Crocker <dcrocker@eschertech.com>2016-12-29 17:11:08 +0300
commitc5e6d7179c5894cb0fcb56a018033080776cab5e (patch)
treea4e84e86c17f97e689ba025ca98b159d154a8f2a /src
parent13f914ad7dd10e9c1fc9a0899e79ff609098a550 (diff)
DuetEthernet support + minor changes
Diffstat (limited to 'src')
-rw-r--r--src/Configuration.h5
-rw-r--r--src/Duet/Network.cpp164
-rw-r--r--src/Duet/Network.h14
-rw-r--r--src/Duet/NetworkDefs.h8
-rw-r--r--src/Duet/NetworkTransaction.cpp4
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Client.h45
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Dhcp.cpp520
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Dhcp.h179
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Dns.cpp422
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Dns.h41
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Ethernet3.cpp194
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Ethernet3.h62
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/EthernetClient.cpp167
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/EthernetClient.h39
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/EthernetServer.cpp91
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/EthernetServer.h22
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/EthernetUdp3.cpp271
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/EthernetUdp3.h106
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/README.md54
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Server.h30
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Twitter.cpp74
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Twitter.h35
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Udp.h88
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/utility/WizSpi.cpp425
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/utility/WizSpi.h24
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/utility/socket.cpp413
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/utility/socket.h48
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/utility/util.h42
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/utility/w5500.cpp153
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/utility/w5500.h443
-rw-r--r--src/DuetNG/DuetEthernet/Network.cpp307
-rw-r--r--src/DuetNG/DuetEthernet/Network.h46
-rw-r--r--src/DuetNG/DuetEthernet/NetworkBuffer.cpp61
-rw-r--r--src/DuetNG/DuetEthernet/NetworkBuffer.h26
-rw-r--r--src/DuetNG/DuetEthernet/NetworkDefs.h12
-rw-r--r--src/DuetNG/DuetEthernet/NetworkTransaction.cpp460
-rw-r--r--src/DuetNG/DuetEthernet/NetworkTransaction.h35
-rw-r--r--src/DuetNG/DuetEthernet/Socket.cpp203
-rw-r--r--src/DuetNG/DuetEthernet/Socket.h24
-rw-r--r--src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.cpp26
-rw-r--r--src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.h3
-rw-r--r--src/DuetNG/DuetEthernet/Wiznet/Ethernet/WizSpi.cpp92
-rw-r--r--src/DuetNG/DuetEthernet/Wiznet/Ethernet/WizSpi.h3
-rw-r--r--src/DuetNG/DuetEthernet/Wiznet/Ethernet/socketlib.cpp3
-rw-r--r--src/DuetNG/DuetEthernet/Wiznet/Ethernet/socketlib.h3
-rw-r--r--src/DuetNG/DuetWiFi/Network.cpp26
-rw-r--r--src/DuetNG/DuetWiFi/Network.h2
-rw-r--r--src/DuetNG/Pins_DuetNG.h22
-rw-r--r--src/GCodes/GCodeBuffer.cpp1
-rw-r--r--src/GCodes/GCodeMachineState.cpp2
-rw-r--r--src/GCodes/GCodes.cpp17
-rw-r--r--src/GCodes/GCodes2.cpp10
-rw-r--r--src/Platform.cpp12
-rw-r--r--src/Platform.h4
-rw-r--r--src/RADDS/Network.h2
-rw-r--r--src/Reprap.cpp18
-rw-r--r--src/Version.h2
-rw-r--r--src/Webserver/Webserver.cpp46
58 files changed, 839 insertions, 4812 deletions
diff --git a/src/Configuration.h b/src/Configuration.h
index a2475a36..06186fdb 100644
--- a/src/Configuration.h
+++ b/src/Configuration.h
@@ -165,7 +165,10 @@ const size_t RESERVED_OUTPUT_BUFFERS = 2; // Number of reserved output buffers
// Move system
-const float DEFAULT_FEEDRATE = 3000.0; // The initial requested feed rate after resetting the printer
+const float DefaultFeedrate = 3000.0; // The initial requested feed rate after resetting the printer, in mm/min
+const float DefaultRetractSpeed = 1000.0; // The default firmware retraction and un-retraction speed, in mm
+const float DefaultRetractLength = 1.0;
+
const float DEFAULT_IDLE_TIMEOUT = 30.0; // Seconds
const float DEFAULT_IDLE_CURRENT_FACTOR = 0.3; // Proportion of normal motor current that we use for idle hold
diff --git a/src/Duet/Network.cpp b/src/Duet/Network.cpp
index 90cbeb35..bba5ffa4 100644
--- a/src/Duet/Network.cpp
+++ b/src/Duet/Network.cpp
@@ -109,7 +109,7 @@ uint16_t sendingWindowSize, sentDataOutstanding;
uint8_t sendingRetries;
err_t writeResult, outputResult;
-static uint16_t httpPort = DefaultHttpPort;
+static Port httpPort = DefaultHttpPort;
/*-----------------------------------------------------------------------------------*/
@@ -296,6 +296,10 @@ Network::Network(Platform* p) :
state(NetworkInactive), isEnabled(true), resetCallback(false),
dataCs(nullptr), ftpCs(nullptr), telnetCs(nullptr), freeConnections(nullptr)
{
+}
+
+void Network::Init()
+{
for (size_t i = 0; i < NETWORK_TRANSACTION_COUNT; i++)
{
freeTransactions = new NetworkTransaction(freeTransactions);
@@ -309,10 +313,6 @@ Network::Network(Platform* p) :
}
strcpy(hostname, HOSTNAME);
-}
-
-void Network::Init()
-{
init_ethernet();
httpd_init();
@@ -323,98 +323,96 @@ void Network::Init()
longWait = platform->Time();
}
-void Network::Spin()
+void Network::Spin(bool full)
{
- // Basically we can't do anything if we can't interact with LWIP
-
- if (!LockLWIP())
- {
- platform->ClassReport(longWait);
- return;
- }
-
- if (state == NetworkObtainingIP || state == NetworkActive)
+ if (LockLWIP()) // basically we can't do anything if we can't interact with LWIP
{
- // Is the link still up?
- if (!ethernet_link_established())
- {
- state = NetworkEstablishingLink;
- UnlockLWIP();
-
- platform->ClassReport(longWait);
- return;
- }
-
- // See if we can read any packets. They may include DHCP responses too
- ethernet_task();
- if (resetCallback)
- {
- resetCallback = false;
- ethernet_set_rx_callback(&ethernet_rx_callback);
- }
-
- // Have we obtained a valid IP address yet?
- if (state == NetworkObtainingIP)
+ if (state == NetworkObtainingIP || state == NetworkActive)
{
- const uint8_t *ip = ethernet_get_ipaddress();
- if (ip[0] != 0 && ip[1] != 0 && ip[2] != 0 && ip[3] != 0)
+ // Is the link still up?
+ if (!ethernet_link_established())
{
- // Yes - we're good to go now
- state = NetworkActive;
+ state = NetworkEstablishingLink;
+ UnlockLWIP();
- // Send mDNS announcement so that some routers can perform hostname mapping
- // if ths board is connected via a non-IGMP capable WiFi bridge (like the TP-Link WR701N)
- mdns_announce();
+ platform->ClassReport(longWait);
+ return;
}
- }
- // See if we can send anything
- NetworkTransaction *transaction = writingTransactions;
- if (transaction != nullptr && sendingConnection == nullptr)
- {
- if (transaction->next != nullptr)
+ // See if we can read any packets. They may include DHCP responses too
+ ethernet_task();
+ if (resetCallback)
{
- // Data is supposed to be sent and the last packet has been acknowledged.
- // Rotate the transactions so every client is served even while multiple files are sent
- NetworkTransaction *next = transaction->next;
- writingTransactions = next;
- AppendTransaction(&writingTransactions, transaction);
- transaction = next;
+ resetCallback = false;
+ ethernet_set_rx_callback(&ethernet_rx_callback);
}
- if (transaction->Send())
+ // Have we obtained a valid IP address yet?
+ if (state == NetworkObtainingIP)
{
- // This transaction can be released, do this here
- writingTransactions = transaction->next;
- PrependTransaction(&freeTransactions, transaction);
+ const uint8_t *ip = ethernet_get_ipaddress();
+ if (ip[0] != 0 && ip[1] != 0 && ip[2] != 0 && ip[3] != 0)
+ {
+ // Yes - we're good to go now
+ state = NetworkActive;
- // If there is more data to write on this connection, do it sometime soon
- NetworkTransaction *nextWrite = transaction->nextWrite;
- if (nextWrite != nullptr)
+ // Send mDNS announcement so that some routers can perform hostname mapping
+ // if ths board is connected via a non-IGMP capable WiFi bridge (like the TP-Link WR701N)
+ mdns_announce();
+ }
+ }
+
+ // See if we can send anything - only if full spin i.e. not in the middle of file i/o
+ if (full)
+ {
+ NetworkTransaction *transaction = writingTransactions;
+ if (transaction != nullptr && sendingConnection == nullptr)
{
- PrependTransaction(&writingTransactions, nextWrite);
+ if (transaction->next != nullptr)
+ {
+ // Data is supposed to be sent and the last packet has been acknowledged.
+ // Rotate the transactions so every client is served even while multiple files are sent
+ NetworkTransaction *next = transaction->next;
+ writingTransactions = next;
+ AppendTransaction(&writingTransactions, transaction);
+ transaction = next;
+ }
+
+ if (transaction->Send())
+ {
+ // This transaction can be released, do this here
+ writingTransactions = transaction->next;
+ PrependTransaction(&freeTransactions, transaction);
+
+ // If there is more data to write on this connection, do it sometime soon
+ NetworkTransaction *nextWrite = transaction->nextWrite;
+ if (nextWrite != nullptr)
+ {
+ PrependTransaction(&writingTransactions, nextWrite);
+ }
+ }
}
}
}
- }
- else if (state == NetworkEstablishingLink && ethernet_establish_link())
- {
- if (!ethernetStarted)
+ else if (state == NetworkEstablishingLink && ethernet_establish_link())
{
- start_ethernet(platform->GetIPAddress(), platform->NetMask(), platform->GateWay(), &ethernet_status_callback);
- ethernetStarted = true;
+ if (!ethernetStarted)
+ {
+ start_ethernet(platform->GetIPAddress(), platform->NetMask(), platform->GateWay(), &ethernet_status_callback);
+ ethernetStarted = true;
- // Initialise this one here, because it requires a configured IGMP network interface
- mdns_responder_init(mdns_services, ARRAY_SIZE(mdns_services), mdns_txt_records);
- }
- else
- {
- ethernet_set_configuration(platform->GetIPAddress(), platform->NetMask(), platform->GateWay());
+ // Initialise this one here, because it requires a configured IGMP network interface
+ mdns_responder_init(mdns_services, ARRAY_SIZE(mdns_services), mdns_txt_records);
+ }
+ else
+ {
+ ethernet_set_configuration(platform->GetIPAddress(), platform->NetMask(), platform->GateWay());
+ }
+ state = NetworkObtainingIP;
}
- state = NetworkObtainingIP;
- }
- UnlockLWIP();
+ UnlockLWIP();
+ }
platform->ClassReport(longWait);
}
@@ -800,7 +798,7 @@ void Network::PrependTransaction(NetworkTransaction* volatile* list, NetworkTran
*list = r;
}
-void Network::OpenDataPort(uint16_t port)
+void Network::OpenDataPort(Port port)
{
closingDataPort = false;
tcp_pcb* pcb = tcp_new();
@@ -809,17 +807,17 @@ void Network::OpenDataPort(uint16_t port)
tcp_accept(ftp_pasv_pcb, conn_accept);
}
-uint16_t Network::GetDataPort() const
+Port Network::GetDataPort() const
{
return (closingDataPort || (ftp_pasv_pcb == nullptr) ? 0 : ftp_pasv_pcb->local_port);
}
-uint16_t Network::GetHttpPort() const
+Port Network::GetHttpPort() const
{
return httpPort;
}
-void Network::SetHttpPort(uint16_t port)
+void Network::SetHttpPort(Port port)
{
if (port != httpPort)
{
@@ -932,8 +930,8 @@ bool Network::AcquireTransaction(ConnectionState *cs)
return true;
}
-/*static*/ uint16_t Network::GetLocalPort(Connection conn) { return conn->GetLocalPort(); }
-/*static*/ uint16_t Network::GetRemotePort(Connection conn) { return conn->GetRemotePort(); }
+/*static*/ Port Network::GetLocalPort(Connection conn) { return conn->GetLocalPort(); }
+/*static*/ Port Network::GetRemotePort(Connection conn) { return conn->GetRemotePort(); }
/*static*/ uint32_t Network::GetRemoteIP(Connection conn) { return conn->GetRemoteIP(); }
/*static*/ bool Network::IsConnected(Connection conn) { return conn->IsConnected(); }
/*static*/ bool Network::IsTerminated(Connection conn) { return conn->IsTerminated(); }
diff --git a/src/Duet/Network.h b/src/Duet/Network.h
index f31ccdd2..1c10844b 100644
--- a/src/Duet/Network.h
+++ b/src/Duet/Network.h
@@ -50,7 +50,7 @@ public:
Network(Platform* p);
void Init();
void Exit() {}
- void Spin();
+ void Spin(bool full);
void Interrupt();
void Diagnostics(MessageType mtype);
@@ -80,12 +80,12 @@ public:
NetworkTransaction *GetTransaction(const ConnectionState *cs = nullptr);
- void OpenDataPort(uint16_t port);
- uint16_t GetDataPort() const;
+ void OpenDataPort(Port port);
+ Port GetDataPort() const;
void CloseDataPort();
- void SetHttpPort(uint16_t port);
- uint16_t GetHttpPort() const;
+ void SetHttpPort(Port port);
+ Port GetHttpPort() const;
void SaveDataConnection();
void SaveFTPConnection();
@@ -95,8 +95,8 @@ public:
bool AcquireDataTransaction();
bool AcquireTelnetTransaction();
- static uint16_t GetLocalPort(Connection conn);
- static uint16_t GetRemotePort(Connection conn);
+ static Port GetLocalPort(Connection conn);
+ static Port GetRemotePort(Connection conn);
static uint32_t GetRemoteIP(Connection conn);
static bool IsConnected(Connection conn);
static bool IsTerminated(Connection conn);
diff --git a/src/Duet/NetworkDefs.h b/src/Duet/NetworkDefs.h
index 81f2d593..ff0c95a3 100644
--- a/src/Duet/NetworkDefs.h
+++ b/src/Duet/NetworkDefs.h
@@ -1,12 +1,12 @@
/*
- * NetworkCommon.h
+ * NetworkDefs.h
*
* Created on: 25 Dec 2016
* Author: David
*/
-#ifndef SRC_DUETNG_DUETETHERNET_NETWORKCOMMON_H_
-#define SRC_DUETNG_DUETETHERNET_NETWORKCOMMON_H_
+#ifndef SRC_DUETNG_DUETETHERNET_NETWORKDEFS_H_
+#define SRC_DUETNG_DUETETHERNET_NETWORKDEFS_H_
#include <cstdint>
@@ -35,4 +35,4 @@ const Port TELNET_PORT = 23;
// MSS is defined in lwip
#include "Lwip/lwipopts.h"
-#endif /* SRC_DUETNG_DUETETHERNET_NETWORKCOMMON_H_ */
+#endif /* SRC_DUETNG_DUETETHERNET_NETWORKDEFS_H_ */
diff --git a/src/Duet/NetworkTransaction.cpp b/src/Duet/NetworkTransaction.cpp
index 5c870f8a..fddcff09 100644
--- a/src/Duet/NetworkTransaction.cpp
+++ b/src/Duet/NetworkTransaction.cpp
@@ -603,12 +603,12 @@ uint32_t NetworkTransaction::GetRemoteIP() const
return (cs != nullptr) ? cs->GetRemoteIP() : 0;
}
-uint16_t NetworkTransaction::GetRemotePort() const
+Port NetworkTransaction::GetRemotePort() const
{
return (cs != nullptr) ? cs->GetRemotePort() : 0;
}
-uint16_t NetworkTransaction::GetLocalPort() const
+Port NetworkTransaction::GetLocalPort() const
{
return (cs != nullptr) ? cs->GetLocalPort() : 0;
}
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Client.h b/src/DuetNG/DuetEthernet/Ethernet3/Client.h
deleted file mode 100644
index b8e5d935..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/Client.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- Client.h - Base class that provides Client
- Copyright (c) 2011 Adrian McEwen. All right reserved.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#ifndef client_h
-#define client_h
-#include "Print.h"
-#include "Stream.h"
-#include "IPAddress.h"
-
-class Client : public Stream {
-
-public:
- virtual int connect(IPAddress ip, uint16_t port) =0;
- virtual int connect(const char *host, uint16_t port) =0;
- virtual size_t write(uint8_t) =0;
- virtual size_t write(const uint8_t *buf, size_t size) =0;
- virtual int available() = 0;
- virtual int read() = 0;
- virtual int read(uint8_t *buf, size_t size) = 0;
- virtual int peek() = 0;
- virtual void flush() = 0;
- virtual void stop() = 0;
- virtual uint8_t connected() = 0;
- virtual operator bool() = 0;
-protected:
- uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
-};
-
-#endif
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Dhcp.cpp b/src/DuetNG/DuetEthernet/Ethernet3/Dhcp.cpp
deleted file mode 100644
index 8b4cc219..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/Dhcp.cpp
+++ /dev/null
@@ -1,520 +0,0 @@
-// DHCP Library v0.3 - April 25, 2009
-// Author: Jordan Terrell - blog.jordanterrell.com
-
-#include "utility/w5500.h"
-
-#include <cstring>
-#include <cstdlib>
-#include "Dhcp.h"
-#include "Core.h"
-#include "utility/util.h"
-
-extern "C" void debugPrintf(const char *fmt, ...);
-
-int DhcpClass::beginWithDHCP(const uint8_t *mac, unsigned long timeout, unsigned long responseTimeout)
-{
- _dhcpLeaseTime=0;
- _dhcpT1=0;
- _dhcpT2=0;
- _lastCheck=0;
- _timeout = timeout;
- _responseTimeout = responseTimeout;
-
- reset_DHCP_lease();
- memcpy(_dhcpMacAddr, mac, sizeof(_dhcpMacAddr));
- _dhcp_state = STATE_DHCP_START;
- return request_DHCP_lease();
-}
-
-void DhcpClass::reset_DHCP_lease(){
- // zero out _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp
- memset(_dhcpLocalIp, 0, sizeof(_dhcpLocalIp));
- memset(_dhcpSubnetMask, 0, sizeof(_dhcpSubnetMask));
- memset(_dhcpGatewayIp, 0, sizeof(_dhcpGatewayIp));
- memset(_dhcpDhcpServerIp, 0, sizeof(_dhcpDhcpServerIp));
- memset(_dhcpDnsServerIp, 0, sizeof(_dhcpDnsServerIp));
-}
-
-//return:0 on error, 1 if request is sent and response is received
-int DhcpClass::request_DHCP_lease()
-{
- // Pick an initial transaction ID
- _dhcpTransactionId = random(1UL, 2000UL);
- _dhcpInitialTransactionId = _dhcpTransactionId;
-
- _dhcpUdpSocket.stop();
- if (_dhcpUdpSocket.begin(DHCP_CLIENT_PORT) == 0)
- {
- return 0; // Couldn't get a socket
- }
-
- presend_DHCP();
-
- const unsigned long startTime = millis();
- bool hadError = false;
- while(_dhcp_state != STATE_DHCP_LEASED && !hadError && (millis() - startTime) < _timeout)
- {
-#if 1
- {
- uint8_t tmp = w5500.readPHYCFGR();
- uint8_t version = w5500.readVERSIONR();
- uint8_t macBuf[6];
- w5500.readSHAR(macBuf);
- debugPrintf("Phy %02x ver %02x Mac %02x:%02x:%02x:%02x:%02x:%02x\n",
- tmp, version, macBuf[0], macBuf[1], macBuf[2], macBuf[3], macBuf[4], macBuf[5]);
- }
-#endif
- switch (_dhcp_state)
- {
- case STATE_DHCP_START:
- debugPrintf("DHCP_START\n");
- _dhcpTransactionId++;
- send_DHCP_MESSAGE(DHCP_DISCOVER, ((millis() - startTime) / 1000));
- _dhcp_state = STATE_DHCP_DISCOVER;
- break;
-
- case STATE_DHCP_DISCOVER:
- {
- debugPrintf("DHCP_DISCOVER\n");
- uint32_t respId;
- const uint8_t messageType = parseDHCPResponse(_responseTimeout, respId);
- if (messageType == DHCP_OFFER)
- {
- // We'll use the transaction ID that the offer came with, rather than the one we were up to
- _dhcpTransactionId = respId;
- send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime) / 1000));
- _dhcp_state = STATE_DHCP_REQUEST;
- }
- else if (messageType == 255)
- {
- _dhcp_state = STATE_DHCP_START;
-// hadError = true;
- }
- }
- break;
-
- case STATE_DHCP_REQUEST:
- {
- debugPrintf("DHCP_REQUEST\n");
- uint32_t respId;
- const uint8_t messageType = parseDHCPResponse(_responseTimeout, respId);
- if (messageType == DHCP_ACK)
- {
- _dhcp_state = STATE_DHCP_LEASED;
- debugPrintf("DHCP_LEASED\n");
- //use default lease time if we didn't get it
- if (_dhcpLeaseTime == 0)
- {
- _dhcpLeaseTime = DEFAULT_LEASE;
- }
- //calculate T1 & T2 if we didn't get it
- if (_dhcpT1 == 0)
- {
- //T1 should be 50% of _dhcpLeaseTime
- _dhcpT1 = _dhcpLeaseTime >> 1;
- }
- if (_dhcpT2 == 0)
- {
- //T2 should be 87.5% (7/8ths) of _dhcpLeaseTime
- _dhcpT2 = _dhcpT1 << 1;
- }
- _renewInSec = _dhcpT1;
- _rebindInSec = _dhcpT2;
- }
- else if (messageType == DHCP_NAK)
- {
- _dhcp_state = STATE_DHCP_START;
- }
- else if (messageType == 255)
- {
- _dhcp_state = STATE_DHCP_START;
-// hadError = true;
- }
- }
- break;
-
- case STATE_DHCP_REREQUEST:
- debugPrintf("DHCP_REREQUEST\n");
- _dhcpTransactionId++;
- send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime)/1000));
- _dhcp_state = STATE_DHCP_REQUEST;
- break;
-
- default:
- debugPrintf("Bad DHCP state\n");
- _dhcp_state = STATE_DHCP_START;
- hadError = true;
- }
- }
-
- // We're done with the socket now
- _dhcpUdpSocket.stop();
- _dhcpTransactionId++;
-
- return (_dhcp_state == STATE_DHCP_LEASED) ? 1 : 0;
-}
-
-void DhcpClass::presend_DHCP()
-{
-}
-
-void DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed)
-{
- uint8_t buffer[32];
- memset(buffer, 0, 32);
- IPAddress dest_addr( 255, 255, 255, 255 ); // Broadcast address
-
- if (-1 == _dhcpUdpSocket.beginPacket(dest_addr, DHCP_SERVER_PORT))
- {
- // FIXME Need to return errors
- debugPrintf("Begin packet failed\n");
- return;
- }
-
- buffer[0] = DHCP_BOOTREQUEST; // op
- buffer[1] = DHCP_HTYPE10MB; // htype
- buffer[2] = DHCP_HLENETHERNET; // hlen
- buffer[3] = DHCP_HOPS; // hops
-
- // xid
- unsigned long xid = htonl(_dhcpTransactionId);
- memcpy(buffer + 4, &(xid), 4);
-
- // 8, 9 - seconds elapsed
- buffer[8] = ((secondsElapsed & 0xff00) >> 8);
- buffer[9] = (secondsElapsed & 0x00ff);
-
- // flags
- unsigned short flags = htons(DHCP_FLAGSBROADCAST);
- memcpy(buffer + 10, &(flags), 2);
-
- // ciaddr: already zeroed
- // yiaddr: already zeroed
- // siaddr: already zeroed
- // giaddr: already zeroed
-
- //put data in w5500 transmit buffer
- _dhcpUdpSocket.write(buffer, 28);
-
- memset(buffer, 0, 32); // clear local buffer
-
- memcpy(buffer, _dhcpMacAddr, 6); // chaddr
-
- //put data in w5500 transmit buffer
- _dhcpUdpSocket.write(buffer, 16);
-
- memset(buffer, 0, 32); // clear local buffer
-
- // leave zeroed out for sname && file
- // put in w5500 transmit buffer x 6 (192 bytes)
-
- for (int i = 0; i < 6; i++)
- {
- _dhcpUdpSocket.write(buffer, 32);
- }
-
- // OPT - Magic Cookie
- buffer[0] = (uint8_t)((MAGIC_COOKIE >> 24)& 0xFF);
- buffer[1] = (uint8_t)((MAGIC_COOKIE >> 16)& 0xFF);
- buffer[2] = (uint8_t)((MAGIC_COOKIE >> 8)& 0xFF);
- buffer[3] = (uint8_t)(MAGIC_COOKIE& 0xFF);
-
- // OPT - message type
- buffer[4] = dhcpMessageType;
- buffer[5] = 0x01;
- buffer[6] = messageType; //DHCP_REQUEST;
-
- // OPT - client identifier
- buffer[7] = dhcpClientIdentifier;
- buffer[8] = 0x07;
- buffer[9] = 0x01;
- memcpy(buffer + 10, _dhcpMacAddr, 6);
-
- // OPT - host name
- buffer[16] = hostName;
- buffer[17] = strlen(HOST_NAME) + 6; // length of hostname + last 3 bytes of mac address
- strcpy((char*)&(buffer[18]), HOST_NAME);
-
- printByte((char*)&(buffer[24]), _dhcpMacAddr[3]);
- printByte((char*)&(buffer[26]), _dhcpMacAddr[4]);
- printByte((char*)&(buffer[28]), _dhcpMacAddr[5]);
-
- //put data in w5500 transmit buffer
- _dhcpUdpSocket.write(buffer, 30);
-
- if(messageType == DHCP_REQUEST)
- {
- buffer[0] = dhcpRequestedIPaddr;
- buffer[1] = 0x04;
- buffer[2] = _dhcpLocalIp[0];
- buffer[3] = _dhcpLocalIp[1];
- buffer[4] = _dhcpLocalIp[2];
- buffer[5] = _dhcpLocalIp[3];
-
- buffer[6] = dhcpServerIdentifier;
- buffer[7] = 0x04;
- buffer[8] = _dhcpDhcpServerIp[0];
- buffer[9] = _dhcpDhcpServerIp[1];
- buffer[10] = _dhcpDhcpServerIp[2];
- buffer[11] = _dhcpDhcpServerIp[3];
-
- //put data in w5500 transmit buffer
- _dhcpUdpSocket.write(buffer, 12);
- }
-
- buffer[0] = dhcpParamRequest;
- buffer[1] = 0x06;
- buffer[2] = subnetMask;
- buffer[3] = routersOnSubnet;
- buffer[4] = dns;
- buffer[5] = domainName;
- buffer[6] = dhcpT1value;
- buffer[7] = dhcpT2value;
- buffer[8] = endOption;
-
- //put data in w5500 transmit buffer
- _dhcpUdpSocket.write(buffer, 9);
-
- _dhcpUdpSocket.endPacket();
-}
-
-uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId)
-{
- uint8_t type = 0;
- uint8_t opt_len = 0;
-
- const unsigned long startTime = millis();
-
- while(_dhcpUdpSocket.parsePacket() <= 0)
- {
- if ((millis() - startTime) > responseTimeout)
- {
- debugPrintf("Response timed out\n");
- return 255;
- }
- delay(50);
- }
-
- // start reading in the packet
- RIP_MSG_FIXED fixedMsg;
- _dhcpUdpSocket.read((uint8_t*)&fixedMsg, sizeof(RIP_MSG_FIXED));
-
- if (fixedMsg.op == DHCP_BOOTREPLY && _dhcpUdpSocket.remotePort() == DHCP_SERVER_PORT)
- {
- transactionId = ntohl(fixedMsg.xid);
- if(memcmp(fixedMsg.chaddr, _dhcpMacAddr, 6) != 0 || (transactionId < _dhcpInitialTransactionId) || (transactionId > _dhcpTransactionId))
- {
- // Need to read the rest of the packet here regardless
- _dhcpUdpSocket.flush();
- return 0;
- }
-
- memcpy(_dhcpLocalIp, fixedMsg.yiaddr, 4);
-
- // Skip to the option part
- // Doing this a byte at a time so we don't have to put a big buffer
- // on the stack (as we don't have lots of memory lying around)
- for (int i =0; i < (240 - (int)sizeof(RIP_MSG_FIXED)); i++)
- {
- _dhcpUdpSocket.read(); // we don't care about the returned byte
- }
-
- while (_dhcpUdpSocket.available() > 0)
- {
- switch (_dhcpUdpSocket.read())
- {
- case endOption :
-
- break;
-
- case padOption :
-
- break;
-
- case dhcpMessageType :
-
- opt_len = _dhcpUdpSocket.read();
- type = _dhcpUdpSocket.read();
- break;
-
- case subnetMask :
-
- opt_len = _dhcpUdpSocket.read();
- _dhcpUdpSocket.read(_dhcpSubnetMask, 4);
- break;
-
- case routersOnSubnet :
-
- opt_len = _dhcpUdpSocket.read();
- _dhcpUdpSocket.read(_dhcpGatewayIp, 4);
- for (int i = 0; i < opt_len-4; i++)
- {
- _dhcpUdpSocket.read();
- }
- break;
-
- case dns :
-
- opt_len = _dhcpUdpSocket.read();
- _dhcpUdpSocket.read(_dhcpDnsServerIp, 4);
- for (int i = 0; i < opt_len-4; i++)
- {
- _dhcpUdpSocket.read();
- }
- break;
-
- case dhcpServerIdentifier :
-
- opt_len = _dhcpUdpSocket.read();
- if(((_dhcpDhcpServerIp[0] == 0) && (_dhcpDhcpServerIp[1] == 0) && (_dhcpDhcpServerIp[2] == 0) && (_dhcpDhcpServerIp[3] == 0)) || (IPAddress(_dhcpDhcpServerIp) == _dhcpUdpSocket.remoteIP()))
- {
- _dhcpUdpSocket.read(_dhcpDhcpServerIp, sizeof(_dhcpDhcpServerIp));
- }
- else
- {
- // Skip over the rest of this option
- while (opt_len--)
- {
- _dhcpUdpSocket.read();
- }
- }
- break;
-
- case dhcpT1value :
-
- opt_len = _dhcpUdpSocket.read();
- _dhcpUdpSocket.read((uint8_t*)&_dhcpT1, sizeof(_dhcpT1));
- _dhcpT1 = ntohl(_dhcpT1);
- break;
-
- case dhcpT2value :
-
- opt_len = _dhcpUdpSocket.read();
- _dhcpUdpSocket.read((uint8_t*)&_dhcpT2, sizeof(_dhcpT2));
- _dhcpT2 = ntohl(_dhcpT2);
- break;
-
- case dhcpIPaddrLeaseTime :
-
- opt_len = _dhcpUdpSocket.read();
- _dhcpUdpSocket.read((uint8_t*)&_dhcpLeaseTime, sizeof(_dhcpLeaseTime));
- _dhcpLeaseTime = ntohl(_dhcpLeaseTime);
- _renewInSec = _dhcpLeaseTime;
- break;
-
- default :
-
- opt_len = _dhcpUdpSocket.read();
- // Skip over the rest of this option
- while (opt_len--)
- {
- _dhcpUdpSocket.read();
- }
- break;
- }
- }
- }
-
- // Need to skip to end of the packet regardless here
- _dhcpUdpSocket.flush();
-
- return type;
-}
-
-
-/*
- returns:
- 0/DHCP_CHECK_NONE: nothing happened
- 1/DHCP_CHECK_RENEW_FAIL: renew failed
- 2/DHCP_CHECK_RENEW_OK: renew success
- 3/DHCP_CHECK_REBIND_FAIL: rebind fail
- 4/DHCP_CHECK_REBIND_OK: rebind success
-*/
-int DhcpClass::checkLease(){
- //this uses a signed / unsigned trick to deal with millis overflow
- unsigned long now = millis();
- signed long snow = (long)now;
- int rc=DHCP_CHECK_NONE;
- if (_lastCheck != 0){
- signed long factor;
- //calc how many ms past the timeout we are
- factor = snow - (long)_secTimeout;
- //if on or passed the timeout, reduce the counters
- if ( factor >= 0 ){
- //next timeout should be now plus 1000 ms minus parts of second in factor
- _secTimeout = snow + 1000 - factor % 1000;
- //how many seconds late are we, minimum 1
- factor = factor / 1000 +1;
-
- //reduce the counters by that mouch
- //if we can assume that the cycle time (factor) is fairly constant
- //and if the remainder is less than cycle time * 2
- //do it early instead of late
- if(_renewInSec < factor*2 )
- _renewInSec = 0;
- else
- _renewInSec -= factor;
-
- if(_rebindInSec < factor*2 )
- _rebindInSec = 0;
- else
- _rebindInSec -= factor;
- }
-
- //if we have a lease but should renew, do it
- if (_dhcp_state == STATE_DHCP_LEASED && _renewInSec <=0){
- _dhcp_state = STATE_DHCP_REREQUEST;
- rc = 1 + request_DHCP_lease();
- }
-
- //if we have a lease or is renewing but should bind, do it
- if( (_dhcp_state == STATE_DHCP_LEASED || _dhcp_state == STATE_DHCP_START) && _rebindInSec <=0){
- //this should basically restart completely
- _dhcp_state = STATE_DHCP_START;
- reset_DHCP_lease();
- rc = 3 + request_DHCP_lease();
- }
- }
- else{
- _secTimeout = snow + 1000;
- }
-
- _lastCheck = now;
- return rc;
-}
-
-IPAddress DhcpClass::getLocalIp()
-{
- return IPAddress(_dhcpLocalIp);
-}
-
-IPAddress DhcpClass::getSubnetMask()
-{
- return IPAddress(_dhcpSubnetMask);
-}
-
-IPAddress DhcpClass::getGatewayIp()
-{
- return IPAddress(_dhcpGatewayIp);
-}
-
-IPAddress DhcpClass::getDhcpServerIp()
-{
- return IPAddress(_dhcpDhcpServerIp);
-}
-
-IPAddress DhcpClass::getDnsServerIp()
-{
- return IPAddress(_dhcpDnsServerIp);
-}
-
-void DhcpClass::printByte(char * buf, uint8_t n ) {
- char *str = &buf[1];
- buf[0]='0';
- do {
- unsigned long m = n;
- n /= 16;
- char c = m - 16 * n;
- *str-- = c < 10 ? c + '0' : c + 'A' - 10;
- } while(n);
-}
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Dhcp.h b/src/DuetNG/DuetEthernet/Ethernet3/Dhcp.h
deleted file mode 100644
index 8deebdd8..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/Dhcp.h
+++ /dev/null
@@ -1,179 +0,0 @@
-// DHCP Library v0.3 - April 25, 2009
-// Author: Jordan Terrell - blog.jordanterrell.com
-
-#ifndef Dhcp_h
-#define Dhcp_h
-
-#include "EthernetUdp3.h"
-
-/* DHCP state machine. */
-#define STATE_DHCP_START 0
-#define STATE_DHCP_DISCOVER 1
-#define STATE_DHCP_REQUEST 2
-#define STATE_DHCP_LEASED 3
-#define STATE_DHCP_REREQUEST 4
-#define STATE_DHCP_RELEASE 5
-
-#define DHCP_FLAGSBROADCAST 0x8000
-
-/* UDP port numbers for DHCP */
-#define DHCP_SERVER_PORT 67 /* from server to client */
-#define DHCP_CLIENT_PORT 68 /* from client to server */
-
-/* DHCP message OP code */
-#define DHCP_BOOTREQUEST 1
-#define DHCP_BOOTREPLY 2
-
-/* DHCP message type */
-#define DHCP_DISCOVER 1
-#define DHCP_OFFER 2
-#define DHCP_REQUEST 3
-#define DHCP_DECLINE 4
-#define DHCP_ACK 5
-#define DHCP_NAK 6
-#define DHCP_RELEASE 7
-#define DHCP_INFORM 8
-
-#define DHCP_HTYPE10MB 1
-#define DHCP_HTYPE100MB 2
-
-#define DHCP_HLENETHERNET 6
-#define DHCP_HOPS 0
-#define DHCP_SECS 0
-
-#define MAGIC_COOKIE 0x63825363
-#define MAX_DHCP_OPT 16
-
-#define HOST_NAME "WIZnet"
-#define DEFAULT_LEASE (900) //default lease time in seconds
-
-#define DHCP_CHECK_NONE (0)
-#define DHCP_CHECK_RENEW_FAIL (1)
-#define DHCP_CHECK_RENEW_OK (2)
-#define DHCP_CHECK_REBIND_FAIL (3)
-#define DHCP_CHECK_REBIND_OK (4)
-
-enum
-{
- padOption = 0,
- subnetMask = 1,
- timerOffset = 2,
- routersOnSubnet = 3,
- /* timeServer = 4,
- nameServer = 5,*/
- dns = 6,
- /*logServer = 7,
- cookieServer = 8,
- lprServer = 9,
- impressServer = 10,
- resourceLocationServer = 11,*/
- hostName = 12,
- /*bootFileSize = 13,
- meritDumpFile = 14,*/
- domainName = 15,
- /*swapServer = 16,
- rootPath = 17,
- extentionsPath = 18,
- IPforwarding = 19,
- nonLocalSourceRouting = 20,
- policyFilter = 21,
- maxDgramReasmSize = 22,
- defaultIPTTL = 23,
- pathMTUagingTimeout = 24,
- pathMTUplateauTable = 25,
- ifMTU = 26,
- allSubnetsLocal = 27,
- broadcastAddr = 28,
- performMaskDiscovery = 29,
- maskSupplier = 30,
- performRouterDiscovery = 31,
- routerSolicitationAddr = 32,
- staticRoute = 33,
- trailerEncapsulation = 34,
- arpCacheTimeout = 35,
- ethernetEncapsulation = 36,
- tcpDefaultTTL = 37,
- tcpKeepaliveInterval = 38,
- tcpKeepaliveGarbage = 39,
- nisDomainName = 40,
- nisServers = 41,
- ntpServers = 42,
- vendorSpecificInfo = 43,
- netBIOSnameServer = 44,
- netBIOSdgramDistServer = 45,
- netBIOSnodeType = 46,
- netBIOSscope = 47,
- xFontServer = 48,
- xDisplayManager = 49,*/
- dhcpRequestedIPaddr = 50,
- dhcpIPaddrLeaseTime = 51,
- /*dhcpOptionOverload = 52,*/
- dhcpMessageType = 53,
- dhcpServerIdentifier = 54,
- dhcpParamRequest = 55,
- /*dhcpMsg = 56,
- dhcpMaxMsgSize = 57,*/
- dhcpT1value = 58,
- dhcpT2value = 59,
- /*dhcpClassIdentifier = 60,*/
- dhcpClientIdentifier = 61,
- endOption = 255
-};
-
-typedef struct _RIP_MSG_FIXED
-{
- uint8_t op;
- uint8_t htype;
- uint8_t hlen;
- uint8_t hops;
- uint32_t xid;
- uint16_t secs;
- uint16_t flags;
- uint8_t ciaddr[4];
- uint8_t yiaddr[4];
- uint8_t siaddr[4];
- uint8_t giaddr[4];
- uint8_t chaddr[6];
-}RIP_MSG_FIXED;
-
-class DhcpClass
-{
-private:
- uint32_t _dhcpInitialTransactionId;
- uint32_t _dhcpTransactionId;
- uint8_t _dhcpMacAddr[6];
- uint8_t _dhcpLocalIp[4];
- uint8_t _dhcpSubnetMask[4];
- uint8_t _dhcpGatewayIp[4];
- uint8_t _dhcpDhcpServerIp[4];
- uint8_t _dhcpDnsServerIp[4];
- uint32_t _dhcpLeaseTime;
- uint32_t _dhcpT1, _dhcpT2;
- signed long _renewInSec;
- signed long _rebindInSec;
- signed long _lastCheck;
- unsigned long _timeout;
- unsigned long _responseTimeout;
- unsigned long _secTimeout;
- uint8_t _dhcp_state;
- EthernetUDP _dhcpUdpSocket;
-
- int request_DHCP_lease();
- void reset_DHCP_lease();
- void presend_DHCP();
- void send_DHCP_MESSAGE(uint8_t, uint16_t);
- void printByte(char *, uint8_t);
-
- uint8_t parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId);
-public:
- IPAddress getLocalIp();
- IPAddress getSubnetMask();
- IPAddress getGatewayIp();
- IPAddress getDhcpServerIp();
- IPAddress getDnsServerIp();
-
- int beginWithDHCP(const uint8_t *macAddress, unsigned long timeout, unsigned long responseTimeout);
- int checkLease();
-};
-
-#endif
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Dns.cpp b/src/DuetNG/DuetEthernet/Ethernet3/Dns.cpp
deleted file mode 100644
index d55fad8b..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/Dns.cpp
+++ /dev/null
@@ -1,422 +0,0 @@
-// Arduino DNS client for WizNet5100-based Ethernet shield
-// (c) Copyright 2009-2010 MCQN Ltd.
-// Released under Apache License, version 2.0
-
-#include "utility/w5500.h"
-#include "EthernetUdp3.h"
-#include "utility/util.h"
-
-#include "Dns.h"
-#include <cstring>
-#include "Core.h"
-
-
-#define SOCKET_NONE 255
-// Various flags and header field values for a DNS message
-#define UDP_HEADER_SIZE 8
-#define DNS_HEADER_SIZE 12
-#define TTL_SIZE 4
-#define QUERY_FLAG (0)
-#define RESPONSE_FLAG (1<<15)
-#define QUERY_RESPONSE_MASK (1<<15)
-#define OPCODE_STANDARD_QUERY (0)
-#define OPCODE_INVERSE_QUERY (1<<11)
-#define OPCODE_STATUS_REQUEST (2<<11)
-#define OPCODE_MASK (15<<11)
-#define AUTHORITATIVE_FLAG (1<<10)
-#define TRUNCATION_FLAG (1<<9)
-#define RECURSION_DESIRED_FLAG (1<<8)
-#define RECURSION_AVAILABLE_FLAG (1<<7)
-#define RESP_NO_ERROR (0)
-#define RESP_FORMAT_ERROR (1)
-#define RESP_SERVER_FAILURE (2)
-#define RESP_NAME_ERROR (3)
-#define RESP_NOT_IMPLEMENTED (4)
-#define RESP_REFUSED (5)
-#define RESP_MASK (15)
-#define TYPE_A (0x0001)
-#define CLASS_IN (0x0001)
-#define LABEL_COMPRESSION_MASK (0xC0)
-// Port number that DNS servers listen on
-#define DNS_PORT 53
-
-// Possible return codes from ProcessResponse
-#define SUCCESS 1
-#define TIMED_OUT -1
-#define INVALID_SERVER -2
-#define TRUNCATED -3
-#define INVALID_RESPONSE -4
-
-void DNSClient::begin(const IPAddress& aDNSServer)
-{
- iDNSServer = aDNSServer;
- iRequestId = 0;
-}
-
-
-int DNSClient::inet_aton(const char* aIPAddrString, IPAddress& aResult)
-{
- // See if we've been given a valid IP address
- const char* p =aIPAddrString;
- while (*p &&
- ( (*p == '.') || (*p >= '0') || (*p <= '9') ))
- {
- p++;
- }
-
- if (*p == '\0')
- {
- // It's looking promising, we haven't found any invalid characters
- p = aIPAddrString;
- int segment =0;
- int segmentValue =0;
- while (*p && (segment < 4))
- {
- if (*p == '.')
- {
- // We've reached the end of a segment
- if (segmentValue > 255)
- {
- // You can't have IP address segments that don't fit in a byte
- return 0;
- }
- else
- {
- aResult[segment] = (byte)segmentValue;
- segment++;
- segmentValue = 0;
- }
- }
- else
- {
- // Next digit
- segmentValue = (segmentValue*10)+(*p - '0');
- }
- p++;
- }
- // We've reached the end of address, but there'll still be the last
- // segment to deal with
- if ((segmentValue > 255) || (segment > 3))
- {
- // You can't have IP address segments that don't fit in a byte,
- // or more than four segments
- return 0;
- }
- else
- {
- aResult[segment] = (byte)segmentValue;
- return 1;
- }
- }
- else
- {
- return 0;
- }
-}
-
-int DNSClient::getHostByName(const char* aHostname, IPAddress& aResult)
-{
- int ret =0;
-
- // See if it's a numeric IP address
- if (inet_aton(aHostname, aResult))
- {
- // It is, our work here is done
- return 1;
- }
-
- // Check we've got a valid DNS server to use
- if (iDNSServer == INADDR_NONE)
- {
- return INVALID_SERVER;
- }
-
- // Find a socket to use
- if (iUdp.begin(1024+(millis() & 0xF)) == 1)
- {
- // Try up to three times
- int retries = 0;
-// while ((retries < 3) && (ret <= 0))
- {
- // Send DNS request
- ret = iUdp.beginPacket(iDNSServer, DNS_PORT);
- if (ret != 0)
- {
- // Now output the request data
- ret = BuildRequest(aHostname);
- if (ret != 0)
- {
- // And finally send the request
- ret = iUdp.endPacket();
- if (ret != 0)
- {
- // Now wait for a response
- int wait_retries = 0;
- ret = TIMED_OUT;
- while ((wait_retries < 3) && (ret == TIMED_OUT))
- {
- ret = ProcessResponse(5000, aResult);
- wait_retries++;
- }
- }
- }
- }
- retries++;
- }
-
- // We're done with the socket now
- iUdp.stop();
- }
-
- return ret;
-}
-
-uint16_t DNSClient::BuildRequest(const char* aName)
-{
- // Build header
- // 1 1 1 1 1 1
- // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- // | ID |
- // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- // |QR| Opcode |AA|TC|RD|RA| Z | RCODE |
- // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- // | QDCOUNT |
- // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- // | ANCOUNT |
- // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- // | NSCOUNT |
- // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- // | ARCOUNT |
- // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- // As we only support one request at a time at present, we can simplify
- // some of this header
- iRequestId = millis(); // generate a random ID
- uint16_t twoByteBuffer;
-
- // FIXME We should also check that there's enough space available to write to, rather
- // FIXME than assume there's enough space (as the code does at present)
- iUdp.write((uint8_t*)&iRequestId, sizeof(iRequestId));
-
- twoByteBuffer = htons((uint16_t)(QUERY_FLAG | OPCODE_STANDARD_QUERY | RECURSION_DESIRED_FLAG));
- iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
-
- twoByteBuffer = htons(1); // One question record
- iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
-
- twoByteBuffer = 0; // Zero answer records
- iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
-
- iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
- // and zero additional records
- iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
-
- // Build question
- const char* start =aName;
- const char* end =start;
- uint8_t len;
- // Run through the name being requested
- while (*end)
- {
- // Find out how long this section of the name is
- end = start;
- while (*end && (*end != '.') )
- {
- end++;
- }
-
- if (end-start > 0)
- {
- // Write out the size of this section
- len = end-start;
- iUdp.write(&len, sizeof(len));
- // And then write out the section
- iUdp.write((uint8_t*)start, end-start);
- }
- start = end+1;
- }
-
- // We've got to the end of the question name, so
- // terminate it with a zero-length section
- len = 0;
- iUdp.write(&len, sizeof(len));
- // Finally the type and class of question
- twoByteBuffer = htons(TYPE_A);
- iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
-
- twoByteBuffer = htons(CLASS_IN); // Internet class of question
- iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
- // Success! Everything buffered okay
- return 1;
-}
-
-
-uint16_t DNSClient::ProcessResponse(uint16_t aTimeout, IPAddress& aAddress)
-{
- uint32_t startTime = millis();
-
- // Wait for a response packet
- while(iUdp.parsePacket() <= 0)
- {
- if((millis() - startTime) > aTimeout)
- return TIMED_OUT;
- delay(50);
- }
-
- // We've had a reply!
- // Read the UDP header
- uint8_t header[DNS_HEADER_SIZE]; // Enough space to reuse for the DNS header
- // Check that it's a response from the right server and the right port
- if ( (iDNSServer != iUdp.remoteIP()) ||
- (iUdp.remotePort() != DNS_PORT) )
- {
- // It's not from who we expected
- return INVALID_SERVER;
- }
-
- // Read through the rest of the response
- if (iUdp.available() < DNS_HEADER_SIZE)
- {
- return TRUNCATED;
- }
- iUdp.read(header, DNS_HEADER_SIZE);
-
- uint16_t header_flags = get16nb(&header[2]);
- // Check that it's a response to this request
- if ( ( iRequestId != get16(&header[0]) ) ||
- ((header_flags & QUERY_RESPONSE_MASK) != (uint16_t)RESPONSE_FLAG) )
- {
- // Mark the entire packet as read
- iUdp.flush();
- return INVALID_RESPONSE;
- }
- // Check for any errors in the response (or in our request)
- // although we don't do anything to get round these
- if ( (header_flags & TRUNCATION_FLAG) || (header_flags & RESP_MASK) )
- {
- // Mark the entire packet as read
- iUdp.flush();
- return -5; //INVALID_RESPONSE;
- }
-
- // And make sure we've got (at least) one answer
- uint16_t answerCount = get16nb(&header[6]);
- if (answerCount == 0 )
- {
- // Mark the entire packet as read
- iUdp.flush();
- return -6; //INVALID_RESPONSE;
- }
-
- // Skip over any questions
- for (uint16_t i = 0; i < get16nb(&header[4]); i++)
- {
- // Skip over the name
- uint8_t len;
- do
- {
- iUdp.read(&len, sizeof(len));
- if (len > 0)
- {
- // Don't need to actually read the data out for the string, just
- // advance ptr to beyond it
- while(len--)
- {
- iUdp.read(); // we don't care about the returned byte
- }
- }
- } while (len != 0);
-
- // Now jump over the type and class
- for (int i =0; i < 4; i++)
- {
- iUdp.read(); // we don't care about the returned byte
- }
- }
-
- // Now we're up to the bit we're interested in, the answer
- // There might be more than one answer (although we'll just use the first
- // type A answer) and some authority and additional resource records but
- // we're going to ignore all of them.
-
- for (uint16_t i =0; i < answerCount; i++)
- {
- // Skip the name
- uint8_t len;
- do
- {
- iUdp.read(&len, sizeof(len));
- if ((len & LABEL_COMPRESSION_MASK) == 0)
- {
- // It's just a normal label
- if (len > 0)
- {
- // And it's got a length
- // Don't need to actually read the data out for the string,
- // just advance ptr to beyond it
- while(len--)
- {
- iUdp.read(); // we don't care about the returned byte
- }
- }
- }
- else
- {
- // This is a pointer to a somewhere else in the message for the
- // rest of the name. We don't care about the name, and RFC1035
- // says that a name is either a sequence of labels ended with a
- // 0 length octet or a pointer or a sequence of labels ending in
- // a pointer. Either way, when we get here we're at the end of
- // the name
- // Skip over the pointer
- iUdp.read(); // we don't care about the returned byte
- // And set len so that we drop out of the name loop
- len = 0;
- }
- } while (len != 0);
-
- // Check the type and class
- uint16_t answerType;
- uint16_t answerClass;
- iUdp.read((uint8_t*)&answerType, sizeof(answerType));
- iUdp.read((uint8_t*)&answerClass, sizeof(answerClass));
-
- // Ignore the Time-To-Live as we don't do any caching
- for (int i =0; i < TTL_SIZE; i++)
- {
- iUdp.read(); // we don't care about the returned byte
- }
-
- // And read out the length of this answer
- // Don't need header_flags anymore, so we can reuse it here
- iUdp.read((uint8_t*)&header_flags, sizeof(header_flags));
-
- if ( (htons(answerType) == TYPE_A) && (htons(answerClass) == CLASS_IN) )
- {
- if (htons(header_flags) != 4)
- {
- // It's a weird size
- // Mark the entire packet as read
- iUdp.flush();
- return -9;//INVALID_RESPONSE;
- }
- iUdp.read(aAddress.raw_address(), 4);
- return SUCCESS;
- }
- else
- {
- // This isn't an answer type we're after, move onto the next one
- for (uint16_t i =0; i < htons(header_flags); i++)
- {
- iUdp.read(); // we don't care about the returned byte
- }
- }
- }
-
- // Mark the entire packet as read
- iUdp.flush();
-
- // If we get here then we haven't found an answer
- return -10;//INVALID_RESPONSE;
-}
-
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Dns.h b/src/DuetNG/DuetEthernet/Ethernet3/Dns.h
deleted file mode 100644
index 481c5c40..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/Dns.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Arduino DNS client for WizNet5100-based Ethernet shield
-// (c) Copyright 2009-2010 MCQN Ltd.
-// Released under Apache License, version 2.0
-
-#ifndef DNSClient_h
-#define DNSClient_h
-
-#include <EthernetUdp3.h>
-
-class DNSClient
-{
-public:
- // ctor
- void begin(const IPAddress& aDNSServer);
-
- /** Convert a numeric IP address string into a four-byte IP address.
- @param aIPAddrString IP address to convert
- @param aResult IPAddress structure to store the returned IP address
- @result 1 if aIPAddrString was successfully converted to an IP address,
- else error code
- */
- int inet_aton(const char *aIPAddrString, IPAddress& aResult);
-
- /** Resolve the given hostname to an IP address.
- @param aHostname Name to be resolved
- @param aResult IPAddress structure to store the returned IP address
- @result 1 if aIPAddrString was successfully converted to an IP address,
- else error code
- */
- int getHostByName(const char* aHostname, IPAddress& aResult);
-
-protected:
- uint16_t BuildRequest(const char* aName);
- uint16_t ProcessResponse(uint16_t aTimeout, IPAddress& aAddress);
-
- IPAddress iDNSServer;
- uint16_t iRequestId;
- EthernetUDP iUdp;
-};
-
-#endif
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Ethernet3.cpp b/src/DuetNG/DuetEthernet/Ethernet3/Ethernet3.cpp
deleted file mode 100644
index d8a2b9c7..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/Ethernet3.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- modified 12 Aug 2013
- by Soohwan Kim (suhwan@wiznet.co.kr)
-
-- 10 Apr. 2015
- Added support for Arduino Ethernet Shield 2
- by Arduino.org team
-
- */
-
-#include "Ethernet3.h"
-#include "Dhcp.h"
-
-#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
-
-// XXX: don't make assumptions about the value of MAX_SOCK_NUM.
-uint8_t EthernetClass::_state[MAX_SOCK_NUM] = { 0, };
-uint16_t EthernetClass::_server_port[MAX_SOCK_NUM] = { 0, };
-
-
-int EthernetClass::begin(const uint8_t *mac_address, unsigned long timeout, unsigned long responseTimeout)
-{
- if (_dhcp == nullptr)
- {
- _dhcp = new DhcpClass();
- }
-
- // Initialise the basic info
- w5500.init();
- w5500.setMACAddress(mac_address);
- w5500.setIPAddress(IPAddress(0,0,0,0).raw_address());
-
- // Now try to get our config info from a DHCP server
- const int ret = _dhcp->beginWithDHCP(mac_address, timeout, responseTimeout);
- if (ret == 1)
- {
- // We've successfully found a DHCP server and got our configuration info, so set things accordingly
- w5500.setIPAddress(_dhcp->getLocalIp().raw_address());
- w5500.setGatewayIp(_dhcp->getGatewayIp().raw_address());
- w5500.setSubnetMask(_dhcp->getSubnetMask().raw_address());
- _dnsServerAddress = _dhcp->getDnsServerIp();
- }
-
- return ret;
-}
-
-void EthernetClass::begin(const uint8_t *mac_address, IPAddress local_ip)
-{
- IPAddress subnet(255, 255, 255, 0);
- begin(mac_address, local_ip, subnet);
-}
-
-void EthernetClass::begin(const uint8_t *mac_address, IPAddress local_ip, IPAddress subnet)
-{
- // Assume the gateway will be the machine on the same network as the local IP
- // but with last octet being '1'
- IPAddress gateway = local_ip;
- gateway[3] = 1;
- begin(mac_address, local_ip, subnet, gateway);
-}
-
-void EthernetClass::begin(const uint8_t *mac_address, IPAddress local_ip, IPAddress subnet, IPAddress gateway)
-{
- // Assume the DNS server will be the machine on the same network as the local IP
- // but with last octet being '1'
- IPAddress dns_server = local_ip;
- dns_server[3] = 1;
- begin(mac_address, local_ip, subnet, gateway, dns_server);
-}
-
-void EthernetClass::begin(const uint8_t *mac, IPAddress local_ip, IPAddress subnet, IPAddress gateway, IPAddress dns_server)
-{
- w5500.init();
- w5500.setMACAddress(mac);
- w5500.setIPAddress(local_ip.raw_address());
- w5500.setGatewayIp(gateway.raw_address());
- w5500.setSubnetMask(subnet.raw_address());
- _dnsServerAddress = dns_server;
-}
-
-void EthernetClass::stop()
-{
- w5500.stop();
-}
-
-int EthernetClass::maintain(){
- int rc = DHCP_CHECK_NONE;
- if(_dhcp != NULL){
- //we have a pointer to dhcp, use it
- rc = _dhcp->checkLease();
- switch ( rc ){
- case DHCP_CHECK_NONE:
- //nothing done
- break;
- case DHCP_CHECK_RENEW_OK:
- case DHCP_CHECK_REBIND_OK:
- //we might have got a new IP.
- w5500.setIPAddress(_dhcp->getLocalIp().raw_address());
- w5500.setGatewayIp(_dhcp->getGatewayIp().raw_address());
- w5500.setSubnetMask(_dhcp->getSubnetMask().raw_address());
- _dnsServerAddress = _dhcp->getDnsServerIp();
- break;
- default:
- //this is actually a error, it will retry though
- break;
- }
- }
- return rc;
-}
-
-uint8_t EthernetClass::phyState() {
- return w5500.getPHYCFGR();
- }
-
-uint8_t EthernetClass::link() {
- return bitRead(w5500.getPHYCFGR(), 0);
- }
-
-const char* EthernetClass::linkReport() {
- if(bitRead(w5500.getPHYCFGR(), 0) == 1) return "LINK";
- else return "NO LINK";
- }
-
-uint8_t EthernetClass::speed() {
- if(bitRead(w5500.getPHYCFGR(), 0) == 1) {
- if(bitRead(w5500.getPHYCFGR(), 1) == 1) return 100;
- if(bitRead(w5500.getPHYCFGR(), 1) == 0) return 10;
- }
- return 0;
- }
-
-const char* EthernetClass::speedReport() {
- if(bitRead(w5500.getPHYCFGR(), 0) == 1) {
- if(bitRead(w5500.getPHYCFGR(), 1) == 1) return "100 MB";
- if(bitRead(w5500.getPHYCFGR(), 1) == 0) return "10 MB";
- }
- return "NO LINK";
- }
-
-uint8_t EthernetClass::duplex() {
- if(bitRead(w5500.getPHYCFGR(), 0) == 1) {
- if(bitRead(w5500.getPHYCFGR(), 2) == 1) return 2;
- if(bitRead(w5500.getPHYCFGR(), 2) == 0) return 1;
- }
- return 0;
- }
-
-const char* EthernetClass::duplexReport() {
- if(bitRead(w5500.getPHYCFGR(), 0) == 1) {
- if(bitRead(w5500.getPHYCFGR(), 2) == 1) return "FULL DUPLEX";
- if(bitRead(w5500.getPHYCFGR(), 2) == 0) return "HALF DUPLEX";
- }
- return "NO LINK";
- }
-
-void EthernetClass::macAddress(uint8_t mac[]) {
- w5500.getMACAddress(mac);
- }
-
-const char* EthernetClass::macAddressReport() {
- uint8_t mac[6];
- static char str[18];
- w5500.getMACAddress(mac);
- sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
- return str;
- }
-
-IPAddress EthernetClass::localIP()
-{
- IPAddress ret;
- w5500.getIPAddress(ret.raw_address());
- return ret;
-}
-
-IPAddress EthernetClass::subnetMask()
-{
- IPAddress ret;
- w5500.getSubnetMask(ret.raw_address());
- return ret;
-}
-
-IPAddress EthernetClass::gatewayIP()
-{
- IPAddress ret;
- w5500.getGatewayIp(ret.raw_address());
- return ret;
-}
-
-IPAddress EthernetClass::dnsServerIP()
-{
- return _dnsServerAddress;
-}
-
-EthernetClass Ethernet;
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Ethernet3.h b/src/DuetNG/DuetEthernet/Ethernet3/Ethernet3.h
deleted file mode 100644
index 0e176c1b..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/Ethernet3.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- modified 12 Aug 2013
- by Soohwan Kim (suhwan@wiznet.co.kr)
-
- - 10 Apr. 2015
- Added support for Arduino Ethernet Shield 2
- by Arduino.org team
-
- */
-#ifndef ethernet3_h
-#define ethernet3_h
-
-#include <inttypes.h>
-#include "utility/w5500.h"
-#include "IPAddress.h"
-#include "EthernetClient.h"
-#include "EthernetServer.h"
-#include "Dhcp.h"
-
-
-class EthernetClass {
-private:
- IPAddress _dnsServerAddress;
- DhcpClass* _dhcp;
-public:
- static uint8_t _state[MAX_SOCK_NUM];
- static uint16_t _server_port[MAX_SOCK_NUM];
-
- // Initialize the Ethernet shield to use the provided MAC address and gain the rest of the configuration through DHCP.
- // Returns 0 if the DHCP configuration failed, and 1 if it succeeded
- int begin(const uint8_t *mac_address, unsigned long timeout, unsigned long responseTimeout);
- void begin(const uint8_t *mac_address, IPAddress local_ip);
- void begin(const uint8_t *mac_address, IPAddress local_ip, IPAddress subnet);
- void begin(const uint8_t *mac_address, IPAddress local_ip, IPAddress subnet, IPAddress gateway);
- void begin(const uint8_t *mac_address, IPAddress local_ip, IPAddress subnet, IPAddress gateway, IPAddress dns_server);
-
- int maintain();
-
- void stop();
-
- uint8_t phyState(); // returns the PHYCFGR
- uint8_t link(); // returns the linkstate, 1 = linked, 0 = no link
- const char* linkReport(); // returns the linkstate as a string
- uint8_t speed(); // returns speed in MB/s
- const char* speedReport(); // returns speed as a string
- uint8_t duplex(); // returns duplex mode 0 = no link, 1 = Half Duplex, 2 = Full Duplex
- const char* duplexReport(); // returns duplex mode as a string
-
- void macAddress(uint8_t mac[]); // get the MAC Address
- const char* macAddressReport(); // returns the the MAC Address as a string
- IPAddress localIP();
- IPAddress subnetMask();
- IPAddress gatewayIP();
- IPAddress dnsServerIP();
-
- friend class EthernetClient;
- friend class EthernetServer;
-};
-
-extern EthernetClass Ethernet;
-
-#endif
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/EthernetClient.cpp b/src/DuetNG/DuetEthernet/Ethernet3/EthernetClient.cpp
deleted file mode 100644
index 2cb38e60..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/EthernetClient.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-#include "utility/w5500.h"
-#include "utility/socket.h"
-
-#include "cstring"
-
-
-#include "Core.h"
-
-#include "Ethernet3.h"
-#include "EthernetClient.h"
-#include "EthernetServer.h"
-#include "Dns.h"
-
-uint16_t EthernetClient::_srcport = 1024;
-
-EthernetClient::EthernetClient() : _sock(MAX_SOCK_NUM) {
-}
-
-EthernetClient::EthernetClient(uint8_t sock) : _sock(sock) {
-}
-
-int EthernetClient::connect(const char* host, uint16_t port) {
- // Look up the host first
- int ret = 0;
- DNSClient dns;
- IPAddress remote_addr;
-
- dns.begin(Ethernet.dnsServerIP());
- ret = dns.getHostByName(host, remote_addr);
- if (ret == 1) {
- return connect(remote_addr, port);
- } else {
- return ret;
- }
-}
-
-int EthernetClient::connect(IPAddress ip, uint16_t port) {
- if (_sock != MAX_SOCK_NUM)
- return 0;
-
- for (int i = 0; i < MAX_SOCK_NUM; i++) {
- uint8_t s = w5500.readSnSR(i);
- if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT || s == SnSR::CLOSE_WAIT) {
- _sock = i;
- break;
- }
- }
-
- if (_sock == MAX_SOCK_NUM)
- return 0;
-
- _srcport++;
- if (_srcport == 0) _srcport = 1024;
- socket(_sock, SnMR::TCP, _srcport, 0);
-
- if (!::connect(_sock, rawIPAddress(ip), port)) {
- _sock = MAX_SOCK_NUM;
- return 0;
- }
-
- while (status() != SnSR::ESTABLISHED) {
- delay(1);
- if (status() == SnSR::CLOSED) {
- _sock = MAX_SOCK_NUM;
- return 0;
- }
- }
-
- return 1;
-}
-
-size_t EthernetClient::write(uint8_t b) {
- return write(&b, 1);
-}
-
-size_t EthernetClient::write(const uint8_t *buf, size_t size) {
- if (_sock == MAX_SOCK_NUM) {
- setWriteError();
- return 0;
- }
- if (!send(_sock, buf, size)) {
- setWriteError();
- return 0;
- }
- return size;
-}
-
-int EthernetClient::available() {
- if (_sock != MAX_SOCK_NUM)
- return w5500.getRXReceivedSize(_sock);
- return 0;
-}
-
-int EthernetClient::read() {
- uint8_t b;
- if ( recv(_sock, &b, 1) > 0 )
- {
- // recv worked
- return b;
- }
- else
- {
- // No data available
- return -1;
- }
-}
-
-int EthernetClient::read(uint8_t *buf, size_t size) {
- return recv(_sock, buf, size);
-}
-
-int EthernetClient::peek() {
- uint8_t b;
- // Unlike recv, peek doesn't check to see if there's any data available, so we must
- if (!available())
- return -1;
- ::peek(_sock, &b);
- return b;
-}
-
-void EthernetClient::flush() {
- ::flush(_sock);
-}
-
-void EthernetClient::stop() {
- if (_sock == MAX_SOCK_NUM)
- return;
-
- // attempt to close the connection gracefully (send a FIN to other side)
- disconnect(_sock);
- unsigned long start = millis();
-
- // wait a second for the connection to close
- while (status() != SnSR::CLOSED && millis() - start < 1000)
- delay(1);
-
- // if it hasn't closed, close it forcefully
- if (status() != SnSR::CLOSED)
- close(_sock);
-
- EthernetClass::_server_port[_sock] = 0;
- _sock = MAX_SOCK_NUM;
-}
-
-uint8_t EthernetClient::connected() {
- if (_sock == MAX_SOCK_NUM) return 0;
-
- uint8_t s = status();
- return !(s == SnSR::LISTEN || s == SnSR::CLOSED || s == SnSR::FIN_WAIT ||
- (s == SnSR::CLOSE_WAIT && !available()));
-}
-
-uint8_t EthernetClient::status() {
- if (_sock == MAX_SOCK_NUM) return SnSR::CLOSED;
- return w5500.readSnSR(_sock);
-}
-
-// the next function allows us to use the client returned by
-// EthernetServer::available() as the condition in an if-statement.
-
-EthernetClient::operator bool() {
- return _sock != MAX_SOCK_NUM;
-}
-
-bool EthernetClient::operator==(const EthernetClient& rhs) {
- return _sock == rhs._sock && _sock != MAX_SOCK_NUM && rhs._sock != MAX_SOCK_NUM;
-}
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/EthernetClient.h b/src/DuetNG/DuetEthernet/Ethernet3/EthernetClient.h
deleted file mode 100644
index 8612e5c1..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/EthernetClient.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef ethernetclient_h
-#define ethernetclient_h
-#include "Core.h"
-#include "Print.h"
-#include "Client.h"
-#include "IPAddress.h"
-
-class EthernetClient : public Client {
-
-public:
- EthernetClient();
- EthernetClient(uint8_t sock);
-
- uint8_t status();
- virtual int connect(IPAddress ip, uint16_t port);
- virtual int connect(const char *host, uint16_t port);
- virtual size_t write(uint8_t);
- virtual size_t write(const uint8_t *buf, size_t size);
- virtual int available();
- virtual int read();
- virtual int read(uint8_t *buf, size_t size);
- virtual int peek();
- virtual void flush();
- virtual void stop();
- virtual uint8_t connected();
- virtual operator bool();
- virtual bool operator==(const EthernetClient&);
- virtual bool operator!=(const EthernetClient& rhs) { return !this->operator==(rhs); };
-
- friend class EthernetServer;
-
- using Print::write;
-
-private:
- static uint16_t _srcport;
- uint8_t _sock;
-};
-
-#endif
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/EthernetServer.cpp b/src/DuetNG/DuetEthernet/Ethernet3/EthernetServer.cpp
deleted file mode 100644
index 406f0b3f..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/EthernetServer.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-#include "utility/w5500.h"
-#include "utility/socket.h"
-extern "C" {
-#include "string.h"
-}
-
-#include "Ethernet3.h"
-#include "EthernetClient.h"
-#include "EthernetServer.h"
-
-EthernetServer::EthernetServer(uint16_t port)
-{
- _port = port;
-}
-
-void EthernetServer::begin()
-{
- for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
- EthernetClient client(sock);
- if (client.status() == SnSR::CLOSED) {
- socket(sock, SnMR::TCP, _port, 0);
- listen(sock);
- EthernetClass::_server_port[sock] = _port;
- break;
- }
- }
-}
-
-void EthernetServer::accept()
-{
- int listening = 0;
-
- for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
- EthernetClient client(sock);
-
- if (EthernetClass::_server_port[sock] == _port) {
- if (client.status() == SnSR::LISTEN) {
- listening = 1;
- }
- else if (client.status() == SnSR::CLOSE_WAIT && !client.available()) {
- client.stop();
- }
- }
- }
-
- if (!listening) {
- begin();
- }
-}
-
-EthernetClient EthernetServer::available()
-{
- accept();
-
- for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
- EthernetClient client(sock);
- if (EthernetClass::_server_port[sock] == _port &&
- (client.status() == SnSR::ESTABLISHED ||
- client.status() == SnSR::CLOSE_WAIT)) {
- if (client.available()) {
- // XXX: don't always pick the lowest numbered socket.
- return client;
- }
- }
- }
-
- return EthernetClient(MAX_SOCK_NUM);
-}
-
-size_t EthernetServer::write(uint8_t b)
-{
- return write(&b, 1);
-}
-
-size_t EthernetServer::write(const uint8_t *buffer, size_t size)
-{
- size_t n = 0;
-
- accept();
-
- for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
- EthernetClient client(sock);
-
- if (EthernetClass::_server_port[sock] == _port &&
- client.status() == SnSR::ESTABLISHED) {
- n += client.write(buffer, size);
- }
- }
-
- return n;
-}
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/EthernetServer.h b/src/DuetNG/DuetEthernet/Ethernet3/EthernetServer.h
deleted file mode 100644
index 86ccafe9..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/EthernetServer.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef ethernetserver_h
-#define ethernetserver_h
-
-#include "Server.h"
-
-class EthernetClient;
-
-class EthernetServer :
-public Server {
-private:
- uint16_t _port;
- void accept();
-public:
- EthernetServer(uint16_t);
- EthernetClient available();
- virtual void begin();
- virtual size_t write(uint8_t);
- virtual size_t write(const uint8_t *buf, size_t size);
- using Print::write;
-};
-
-#endif
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/EthernetUdp3.cpp b/src/DuetNG/DuetEthernet/Ethernet3/EthernetUdp3.cpp
deleted file mode 100644
index a8ad13ee..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/EthernetUdp3.cpp
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Udp.cpp: Library to send/receive UDP packets with the Arduino ethernet shield.
- * This version only offers minimal wrapping of socket.c/socket.h
- * Drop Udp.h/.cpp into the Ethernet library directory at hardware/libraries/Ethernet/
- *
- * MIT License:
- * Copyright (c) 2008 Bjoern Hartmann
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- * bjoern@cs.stanford.edu 12/30/2008
- *
- * - 10 Apr. 2015
- * Added support for Arduino Ethernet Shield 2
- * by Arduino.org team
- */
-
-#include "utility/w5500.h"
-#include "utility/socket.h"
-#include "Ethernet3.h"
-#include "Udp.h"
-#include "Dns.h"
-
-#undef UDP
-
-/* Constructor */
-EthernetUDP::EthernetUDP() : _sock(MAX_SOCK_NUM) {}
-
-/* Start EthernetUDP socket, listening at local port PORT */
-uint8_t EthernetUDP::begin(uint16_t port)
-{
- if (_sock != MAX_SOCK_NUM)
- {
- return 0;
- }
-
- for (int i = 0; i < MAX_SOCK_NUM; i++)
- {
- uint8_t s = w5500.readSnSR(i);
- if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT)
- {
- _sock = i;
- break;
- }
- }
-
- if (_sock == MAX_SOCK_NUM)
- {
- return 0;
- }
-
- _port = port;
- _remaining = 0;
- socket(_sock, SnMR::UDP, _port, 0);
-
- return 1;
-}
-
-/* return number of bytes available in the current packet,
- will return zero if parsePacket hasn't been called yet */
-int EthernetUDP::available()
-{
- return _remaining;
-}
-
-/* Release any resources being used by this EthernetUDP instance */
-void EthernetUDP::stop()
-{
- if (_sock == MAX_SOCK_NUM)
- {
- return;
- }
-
- close(_sock);
-
- EthernetClass::_server_port[_sock] = 0;
- _sock = MAX_SOCK_NUM;
-}
-
-int EthernetUDP::beginPacket(const char *host, uint16_t port)
-{
- // Look up the host first
- DNSClient dns;
- IPAddress remote_addr;
-
- dns.begin(Ethernet.dnsServerIP());
- const int ret = dns.getHostByName(host, remote_addr);
- if (ret == 1)
- {
- return beginPacket(remote_addr, port);
- }
- else
- {
- return ret;
- }
-}
-
-int EthernetUDP::beginPacket(IPAddress ip, uint16_t port)
-{
- _offset = 0;
- return startUDP(_sock, rawIPAddress(ip), port);
-}
-
-int EthernetUDP::endPacket()
-{
- return sendUDP(_sock);
-}
-
-size_t EthernetUDP::write(uint8_t byte)
-{
- return write(&byte, 1);
-}
-
-size_t EthernetUDP::write(const uint8_t *buffer, size_t size)
-{
- uint16_t bytes_written = bufferData(_sock, _offset, buffer, size);
- _offset += bytes_written;
- return bytes_written;
-}
-
-int EthernetUDP::parsePacket()
-{
- // discard any remaining bytes in the last packet
- flush();
-
- if (w5500.getRXReceivedSize(_sock) > 0)
- {
- //HACK - hand-parse the UDP packet using TCP recv method
- uint8_t tmpBuf[8];
- //read 8 header bytes and get IP and port from it
- int ret = recv(_sock, tmpBuf, 8);
- if (ret > 0)
- {
- _remoteIP = tmpBuf;
- _remotePort = tmpBuf[4];
- _remotePort = (_remotePort << 8) + tmpBuf[5];
- _remaining = tmpBuf[6];
- _remaining = (_remaining << 8) + tmpBuf[7];
-
- // When we get here, any remaining bytes are the data
- ret = _remaining;
- }
- return ret;
- }
- // There aren't any packets available
- return 0;
-}
-
-int EthernetUDP::read()
-{
- uint8_t byte;
-
- if ((_remaining > 0) && (recv(_sock, &byte, 1) > 0))
- {
- // We read things without any problems
- _remaining--;
- return byte;
- }
-
- // If we get here, there's no data available
- return -1;
-}
-
-int EthernetUDP::read(unsigned char* buffer, size_t len)
-{
- if (_remaining > 0)
- {
- int got;
- if (_remaining <= len)
- {
- // data should fit in the buffer
- got = recv(_sock, buffer, _remaining);
- }
- else
- {
- // too much data for the buffer,
- // grab as much as will fit
- got = recv(_sock, buffer, len);
- }
-
- if (got > 0)
- {
- _remaining -= got;
- return got;
- }
- }
-
- // If we get here, there's no data available or recv failed
- return -1;
-}
-
-int EthernetUDP::peek()
-{
- uint8_t b;
- // Unlike recv, peek doesn't check to see if there's any data available, so we must.
- // If the user hasn't called parsePacket yet then return nothing otherwise they
- // may get the UDP header
- if (!_remaining)
- {
- return -1;
- }
- ::peek(_sock, &b);
- return b;
-}
-
-void EthernetUDP::flush()
-{
- // could this fail (loop endlessly) if _remaining > 0 and recv in read fails?
- // should only occur if recv fails after telling us the data is there, lets
- // hope the w5500 always behaves :)
- while (_remaining)
- {
- read();
- }
-}
-
-/* Start EthernetUDP socket, listening at local port PORT */
-uint8_t EthernetUDP::beginMulticast(IPAddress ip, uint16_t port)
-{
- if (_sock != MAX_SOCK_NUM)
- {
- return 0;
- }
-
- for (int i = 0; i < MAX_SOCK_NUM; i++)
- {
- const uint8_t s = w5500.readSnSR(i);
- if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT)
- {
- _sock = i;
- break;
- }
- }
-
- if (_sock == MAX_SOCK_NUM)
- {
- return 0;
- }
-
- // Calculate MAC address from Multicast IP Address
- byte mac[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0x00 };
-
- mac[3] = ip[1] & 0x7F;
- mac[4] = ip[2];
- mac[5] = ip[3];
-
- w5500.writeSnDIPR(_sock, rawIPAddress(ip)); //239.255.0.1
- w5500.writeSnDPORT(_sock, port);
- w5500.writeSnDHAR(_sock,mac);
-
- _remaining = 0;
- socket(_sock, SnMR::UDP, port, SnMR::MULTI);
- return 1;
-}
-
-// End
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/EthernetUdp3.h b/src/DuetNG/DuetEthernet/Ethernet3/EthernetUdp3.h
deleted file mode 100644
index 41676bb8..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/EthernetUdp3.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Udp.cpp: Library to send/receive UDP packets with the Arduino ethernet shield.
- * This version only offers minimal wrapping of socket.c/socket.h
- * Drop Udp.h/.cpp into the Ethernet library directory at hardware/libraries/Ethernet/
- *
- * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
- * 1) UDP does not guarantee the order in which assembled UDP packets are received. This
- * might not happen often in practice, but in larger network topologies, a UDP
- * packet can be received out of sequence.
- * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
- * aware of it. Again, this may not be a concern in practice on small local networks.
- * For more information, see http://www.cafeaulait.org/course/week12/35.html
- *
- * MIT License:
- * Copyright (c) 2008 Bjoern Hartmann
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- * bjoern@cs.stanford.edu 12/30/2008
- *
- * - 10 Apr. 2015
- * Added support for Arduino Ethernet Shield 2
- * by Arduino.org team
- *
- */
-
-
-#ifndef ethernetudp3_h
-#define ethernetudp3_h
-
-#include <Udp.h>
-
-#define UDP_TX_PACKET_MAX_SIZE 24
-
-class EthernetUDP : public UdpStream {
-private:
- uint8_t _sock; // socket ID for Wiz5100
- uint16_t _port; // local port to listen on
- IPAddress _remoteIP; // remote IP address for the incoming packet whilst it's being processed
- uint16_t _remotePort; // remote port for the incoming packet whilst it's being processed
- uint16_t _offset; // offset into the packet being sent
- uint16_t _remaining; // remaining bytes of incoming packet yet to be processed
-
-public:
- EthernetUDP(); // Constructor
- virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
- virtual uint8_t beginMulticast(IPAddress, uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
- virtual void stop(); // Finish with the UDP socket
-
- // Sending UDP packets
-
- // Start building up a packet to send to the remote host specific in ip and port
- // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
- virtual int beginPacket(IPAddress ip, uint16_t port);
- // Start building up a packet to send to the remote host specific in host and port
- // Returns 1 if successful, 0 if there was a problem resolving the hostname or port
- virtual int beginPacket(const char *host, uint16_t port);
- // Finish off this packet and send it
- // Returns 1 if the packet was sent successfully, 0 if there was an error
- virtual int endPacket();
- // Write a single byte into the packet
- virtual size_t write(uint8_t);
- // Write size bytes from buffer into the packet
- virtual size_t write(const uint8_t *buffer, size_t size);
-
- using Print::write;
-
- // Start processing the next available incoming packet
- // Returns the size of the packet in bytes, or 0 if no packets are available
- virtual int parsePacket();
- // Number of bytes remaining in the current packet
- virtual int available();
- // Read a single byte from the current packet
- virtual int read();
- // Read up to len bytes from the current packet and place them into buffer
- // Returns the number of bytes read, or 0 if none are available
- virtual int read(unsigned char* buffer, size_t len);
- // Read up to len characters from the current packet and place them into buffer
- // Returns the number of characters read, or 0 if none are available
- virtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); };
- // Return the next byte from the current packet without moving on to the next byte
- virtual int peek();
- virtual void flush(); // Finish reading the current packet
-
- // Return the IP address of the host who sent the current incoming packet
- virtual IPAddress remoteIP() { return _remoteIP; };
- // Return the port of the host who sent the current incoming packet
- virtual uint16_t remotePort() { return _remotePort; };
-};
-
-#endif
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/README.md b/src/DuetNG/DuetEthernet/Ethernet3/README.md
deleted file mode 100644
index 37c06aa8..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/README.md
+++ /dev/null
@@ -1,54 +0,0 @@
-# Ethernet3
-Ethernet library for Arduino and Ethernetshield2 / WIZ550io / WIZ850io with Wiznet W5500 chip
-based on the Ethernet2 library of arduino.org
-
-added some new functionalities
-
-you need to include
-
- #include <Ethernet3.h> // instead Ethernet.h
- #include <EthernetUdp3.h> // instead EthernetUdp.h for UDP functionality
-
-###- New init procedure **!!!**
-
-the init of the Ethernetinterface changed, the ordner is now:
-
-*mac, ip, subnet, gateway, dns* instead *mac, ip, dns, gateway, subnet*,
-which is more logical
-
- Ethernet.begin(mac, ip, subnet, gateway, dns);
-
-###- Multicast support
-
-multicast for udp added
-
- EthernetUdp udp
- upd.beginMulticast(multicastIP, port);
-
-###- PHY support
-
-added some function to read the PHYCFGR in Ethernet3
-
- uint8_t phyState(); // returns the PHYCFGR
- uint8_t link(); // returns the linkstate, 1 = linked, 0 = no link
- const char* linkReport(); // returns the linkstate as a string
- uint8_t speed(); // returns speed in MB/s
- const char* speedReport(); // returns speed as a string
- uint8_t duplex(); // returns duplex mode 0 = no link, 1 = Half Duplex, 2 = Full Duplex
- const char* duplexReport(); // returns duplex mode as a string
-
-example
-
- Serial.println(Ethernet.linkReport());
-
-###- MAC address
-
-added some function to read the MAC address in Ethernet3, this is helpfull when you use Wiznet boards like WIZ550io with build in MAC address
-
- void macAddress(uint8_t mac[]); // get the MAC Address
- const char* macAddressReport(); // returns the the MAC Address as a string
-
-example
-
- uint8_t mac[6]; // array for mac address
- Ethernet.macAddress(mac);
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Server.h b/src/DuetNG/DuetEthernet/Ethernet3/Server.h
deleted file mode 100644
index 69e3e39f..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/Server.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- Server.h - Base class that provides Server
- Copyright (c) 2011 Adrian McEwen. All right reserved.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#ifndef server_h
-#define server_h
-
-#include "Print.h"
-
-class Server : public Print {
-public:
- virtual void begin() =0;
-};
-
-#endif
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Twitter.cpp b/src/DuetNG/DuetEthernet/Ethernet3/Twitter.cpp
deleted file mode 100644
index 7d1b9a9c..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/Twitter.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- Twitter.cpp - Arduino library to Post messages to Twitter using OAuth.
- Copyright (c) NeoCat 2010-2011. All right reserved.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-// ver1.2 - Use <string.h>
-// ver1.3 - Support IDE 1.0
-
-#include <cstring>
-#include "Twitter.h"
-
-#define LIB_DOMAIN "arduino-tweet.appspot.com"
-
-Twitter::Twitter(const char *token) : token(token)
-{
-}
-
-bool Twitter::doPost(const char *msg)
-{
- parseStatus = 0;
- statusCode = 0;
- if (client.connect(LIB_DOMAIN, 80)) {
- client.println("POST http://" LIB_DOMAIN "/update HTTP/1.0");
- client.print("Content-Length: ");
- client.println(strlen(msg)+strlen(token)+14);
- client.println();
- client.print("token=");
- client.print(token);
- client.print("&status=");
- client.println(msg);
- } else {
- return false;
- }
- return true;
-}
-
-bool Twitter::checkStatus(Print *debug)
-{
- if (!client.connected()) {
- if (debug)
- while(client.available())
- debug->print((char)client.read());
- client.flush();
- client.stop();
- return false;
- }
- if (!client.available())
- return true;
- char c = client.read();
- if (debug)
- debug->print(c);
- switch(parseStatus) {
- case 0:
- if (c == ' ') parseStatus++; break; // skip "HTTP/1.1 "
- case 1:
- if (c >= '0' && c <= '9') {
- statusCode *= 10;
- statusCode += c - '0';
- } else {
- parseStatus++;
- }
- }
- return true;
-}
-
-int Twitter::wait(Print *debug)
-{
- while (checkStatus(debug));
- return statusCode;
-}
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Twitter.h b/src/DuetNG/DuetEthernet/Ethernet3/Twitter.h
deleted file mode 100644
index 80c5673b..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/Twitter.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- Twitter.cpp - Arduino library to Post messages to Twitter using OAuth.
- Copyright (c) NeoCat 2010-2011. All right reserved.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-// ver1.2 - Use <Udp.h> to support IDE 0019 or later
-// ver1.3 - Support IDE 1.0
-
-#ifndef TWITTER_H
-#define TWITTER_H
-
-#include <inttypes.h>
-#include <Ethernet3.h>
-
-class Twitter
-{
-private:
- uint8_t parseStatus;
- int statusCode;
- const char *token;
- EthernetClient client;
-public:
- Twitter(const char *user_and_passwd);
-
- bool doPost(const char *msg);
- bool checkStatus(Print *debug = NULL);
- int wait(Print *debug = NULL);
- int status(void) { return statusCode; }
-};
-
-#endif //TWITTER_H
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Udp.h b/src/DuetNG/DuetEthernet/Ethernet3/Udp.h
deleted file mode 100644
index 04207c71..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/Udp.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Udp.cpp: Library to send/receive UDP packets.
- *
- * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
- * 1) UDP does not guarantee the order in which assembled UDP packets are received. This
- * might not happen often in practice, but in larger network topologies, a UDP
- * packet can be received out of sequence.
- * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
- * aware of it. Again, this may not be a concern in practice on small local networks.
- * For more information, see http://www.cafeaulait.org/course/week12/35.html
- *
- * MIT License:
- * Copyright (c) 2008 Bjoern Hartmann
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- * bjoern@cs.stanford.edu 12/30/2008
- */
-
-#ifndef udp_h
-#define udp_h
-
-#include <Stream.h>
-#include <IPAddress.h>
-
-class UdpStream : public Stream {
-
-public:
- virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
- virtual void stop() =0; // Finish with the UDP socket
-
- // Sending UDP packets
-
- // Start building up a packet to send to the remote host specific in ip and port
- // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
- virtual int beginPacket(IPAddress ip, uint16_t port) =0;
- // Start building up a packet to send to the remote host specific in host and port
- // Returns 1 if successful, 0 if there was a problem resolving the hostname or port
- virtual int beginPacket(const char *host, uint16_t port) =0;
- // Finish off this packet and send it
- // Returns 1 if the packet was sent successfully, 0 if there was an error
- virtual int endPacket() =0;
- // Write a single byte into the packet
- virtual size_t write(uint8_t) =0;
- // Write size bytes from buffer into the packet
- virtual size_t write(const uint8_t *buffer, size_t size) =0;
-
- // Start processing the next available incoming packet
- // Returns the size of the packet in bytes, or 0 if no packets are available
- virtual int parsePacket() =0;
- // Number of bytes remaining in the current packet
- virtual int available() =0;
- // Read a single byte from the current packet
- virtual int read() =0;
- // Read up to len bytes from the current packet and place them into buffer
- // Returns the number of bytes read, or 0 if none are available
- virtual int read(unsigned char* buffer, size_t len) =0;
- // Read up to len characters from the current packet and place them into buffer
- // Returns the number of characters read, or 0 if none are available
- virtual int read(char* buffer, size_t len) =0;
- // Return the next byte from the current packet without moving on to the next byte
- virtual int peek() =0;
- virtual void flush() =0; // Finish reading the current packet
-
- // Return the IP address of the host who sent the current incoming packet
- virtual IPAddress remoteIP() =0;
- // Return the port of the host who sent the current incoming packet
- virtual uint16_t remotePort() =0;
-protected:
- uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
-};
-
-#endif
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/utility/WizSpi.cpp b/src/DuetNG/DuetEthernet/Ethernet3/utility/WizSpi.cpp
deleted file mode 100644
index 076017f9..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/utility/WizSpi.cpp
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * WizSpi.cpp
- *
- * Created on: 16 Dec 2016
- * Author: David
- */
-
-#include "WizSpi.h"
-#include "variant.h"
-#include "Pins.h"
-
-// Define exactly one of the following as 1, the other as zero
-// The PDC seems to be too slow to work reliably without getting transmit underruns, so we use the DMAC now.
-#define USE_PDC 0 // use peripheral DMA controller
-#define USE_DMAC 0 // use general DMA controller
-
-#if USE_PDC
-#include "pdc.h"
-#endif
-
-#if USE_DMAC
-#include "dmac.h"
-#endif
-
-#include "matrix.h"
-
-// Functions called by the W5500 module to transfer data to/from the W5500 via SPI
-const uint32_t SpiClockFrequency = 10000000; // use 10MHz for now, increase it later
-const unsigned int SpiPeripheralChannelId = 0; // we use NPCS0 as the slave select signal
-
-#if USE_PDC
-static Pdc *spi_pdc;
-static inline void spi_rx_dma_enable()
-{
- pdc_enable_transfer(spi_pdc, PERIPH_PTCR_RXTEN);
-}
-
-static inline void spi_tx_dma_enable()
-{
- pdc_enable_transfer(spi_pdc, PERIPH_PTCR_TXTEN);
-}
-
-static inline void spi_rx_dma_disable()
-{
- pdc_disable_transfer(spi_pdc, PERIPH_PTCR_RXTDIS);
-}
-
-static inline void spi_tx_dma_disable()
-{
- pdc_disable_transfer(spi_pdc, PERIPH_PTCR_TXTDIS);
-}
-
-static bool spi_dma_check_rx_complete()
-{
- return true;
-}
-
-static void spi_tx_dma_setup(const TransactionBuffer *buf, uint32_t maxTransmitLength)
-{
- pdc_packet_t pdc_spi_packet;
- pdc_spi_packet.ul_addr = reinterpret_cast<uint32_t>(buf);
- pdc_spi_packet.ul_size = buf->PacketLength() * 4; // need length in bytes
- pdc_tx_init(spi_pdc, &pdc_spi_packet, NULL);
-}
-
-static void spi_rx_dma_setup(const TransactionBuffer *buf)
-{
- pdc_packet_t pdc_spi_packet;
- pdc_spi_packet.ul_addr = reinterpret_cast<uint32_t>(buf);
- pdc_spi_packet.ul_size = TransactionBuffer::MaxReceiveBytes;
- pdc_rx_init(spi_pdc, &pdc_spi_packet, NULL);
-}
-
-#endif
-
-#if USE_DMAC
-
-// Our choice of DMA channels to use
-const uint32_t CONF_SPI_DMAC_TX_CH = 1;
-const uint32_t CONF_SPI_DMAC_RX_CH = 2;
-
-// Hardware IDs of the SPI transmit and receive DMA interfaces. See atsam datasheet.
-const uint32_t DMA_HW_ID_SPI_TX = 1;
-const uint32_t DMA_HW_ID_SPI_RX = 2;
-
-static inline void spi_rx_dma_enable()
-{
- dmac_channel_enable(DMAC, CONF_SPI_DMAC_RX_CH);
-}
-
-static inline void spi_tx_dma_enable()
-{
- dmac_channel_enable(DMAC, CONF_SPI_DMAC_TX_CH);
-}
-
-static inline void spi_rx_dma_disable()
-{
- dmac_channel_disable(DMAC, CONF_SPI_DMAC_RX_CH);
-}
-
-static inline void spi_tx_dma_disable()
-{
- dmac_channel_disable(DMAC, CONF_SPI_DMAC_TX_CH);
-}
-
-static bool spi_dma_check_rx_complete()
-{
- uint32_t status = DMAC->DMAC_CHSR;
- if ( ((status & (DMAC_CHSR_ENA0 << CONF_SPI_DMAC_RX_CH)) == 0) // controller is not enabled, perhaps because it finished a full buffer transfer
- || ((status & (DMAC_CHSR_EMPT0 << CONF_SPI_DMAC_RX_CH)) != 0) // controller is enabled, probably suspended, and the FIFO is empty
- )
- {
- // Disable the channel.
- // We also need to set the resume bit, otherwise it remains suspended when we re-enable it.
- DMAC->DMAC_CHDR = (DMAC_CHDR_DIS0 << CONF_SPI_DMAC_RX_CH) | (DMAC_CHDR_RES0 << CONF_SPI_DMAC_RX_CH);
- return true;
- }
- return false;
-}
-
-static void spi_tx_dma_setup(const TransactionBuffer *buf, uint32_t maxTransmitLength)
-{
- DMAC->DMAC_EBCISR; // clear any pending interrupts
-
- dmac_channel_set_source_addr(DMAC, CONF_SPI_DMAC_TX_CH, reinterpret_cast<uint32_t>(buf));
- dmac_channel_set_destination_addr(DMAC, CONF_SPI_DMAC_TX_CH, reinterpret_cast<uint32_t>(& SPI->SPI_TDR));
- dmac_channel_set_descriptor_addr(DMAC, CONF_SPI_DMAC_TX_CH, 0);
- dmac_channel_set_ctrlA(DMAC, CONF_SPI_DMAC_TX_CH, maxTransmitLength | DMAC_CTRLA_SRC_WIDTH_WORD | DMAC_CTRLA_DST_WIDTH_BYTE);
- dmac_channel_set_ctrlB(DMAC, CONF_SPI_DMAC_TX_CH,
- DMAC_CTRLB_SRC_DSCR | DMAC_CTRLB_DST_DSCR | DMAC_CTRLB_FC_MEM2PER_DMA_FC | DMAC_CTRLB_SRC_INCR_INCREMENTING | DMAC_CTRLB_DST_INCR_FIXED);
-}
-
-static void spi_rx_dma_setup(const TransactionBuffer *buf)
-{
- DMAC->DMAC_EBCISR; // clear any pending interrupts
-
- dmac_channel_set_source_addr(DMAC, CONF_SPI_DMAC_RX_CH, reinterpret_cast<uint32_t>(& SPI->SPI_RDR));
- dmac_channel_set_destination_addr(DMAC, CONF_SPI_DMAC_RX_CH, reinterpret_cast<uint32_t>(buf));
- dmac_channel_set_descriptor_addr(DMAC, CONF_SPI_DMAC_RX_CH, 0);
-// dmac_channel_set_ctrlA(DMAC, CONF_SPI_DMAC_RX_CH, TransactionBuffer::MaxTransferBytes | DMAC_CTRLA_SRC_WIDTH_BYTE | DMAC_CTRLA_DST_WIDTH_WORD);
- dmac_channel_set_ctrlB(DMAC, CONF_SPI_DMAC_RX_CH,
- DMAC_CTRLB_SRC_DSCR | DMAC_CTRLB_DST_DSCR | DMAC_CTRLB_FC_PER2MEM_DMA_FC | DMAC_CTRLB_SRC_INCR_FIXED | DMAC_CTRLB_DST_INCR_INCREMENTING);
-}
-
-#endif
-
-#if USE_PDC || USE_DMAC
-
-static void spi_dma_disable()
-{
- spi_tx_dma_disable();
- spi_rx_dma_disable();
-}
-
-#if 0
-/**
- * \brief Set SPI slave transfer.
- */
-static void spi_slave_dma_setup(bool dataToSend, bool allowReceive)
-{
-#if USE_PDC
- pdc_disable_transfer(spi_pdc, PERIPH_PTCR_TXTDIS | PERIPH_PTCR_RXTDIS);
-
- TransactionBuffer *outBufPointer = (dataToSend) ? &outBuffer : reinterpret_cast<TransactionBuffer*>(&dummyOutBuffer);
- spi_tx_dma_setup(outBufPointer);
- if (allowReceive)
- {
- outBufPointer->SetDataTaken();
- spi_rx_dma_setup(&inBuffer);
- pdc_enable_transfer(spi_pdc, PERIPH_PTCR_TXTEN | PERIPH_PTCR_RXTEN);
- }
- else
- {
- outBufPointer->ClearDataTaken();
- pdc_enable_transfer(spi_pdc, PERIPH_PTCR_TXTEN);
- }
-#endif
-
-#if USE_DMAC
- spi_dma_disable();
-
- TransactionBuffer *outBufPointer = (dataToSend) ? &outBuffer : reinterpret_cast<TransactionBuffer*>(&dummyOutBuffer);
- if (allowReceive)
- {
- spi_rx_dma_setup(&inBuffer);
- spi_rx_dma_enable();
-// outBufPointer->SetDataTaken();
- }
- else
- {
-// outBufPointer->ClearDataTaken();
- }
-
-// spi_tx_dma_setup(outBufPointer, (dataToSend) ? TransactionBuffer::MaxTransferBytes : 4 * TransactionBuffer::headerDwords);
- spi_tx_dma_enable();
-#endif
-}
-#endif
-
-#endif
-
-namespace WizSpi
-{
- // Initialise the SPI interface
- void Init()
- {
- #if USE_PDC
- spi_pdc = spi_get_pdc_base(SPI);
- // The PDCs are masters 2 and 3 and the SRAM is slave 0. Give the PDCs the highest priority.
- matrix_set_master_burst_type(0, MATRIX_ULBT_8_BEAT_BURST);
- matrix_set_slave_default_master_type(0, MATRIX_DEFMSTR_LAST_DEFAULT_MASTER);
- matrix_set_slave_priority(0, (3 << MATRIX_PRAS0_M2PR_Pos) | (3 << MATRIX_PRAS0_M3PR_Pos));
- matrix_set_slave_slot_cycle(0, 8);
- #endif
-
- #if USE_DMAC
- pmc_enable_periph_clk(ID_DMAC);
- dmac_init(DMAC);
- dmac_set_priority_mode(DMAC, DMAC_PRIORITY_ROUND_ROBIN);
- dmac_enable(DMAC);
- // The DMAC is master 4 and the SRAM is slave 0. Give the DMAC the highest priority.
- matrix_set_slave_default_master_type(0, MATRIX_DEFMSTR_LAST_DEFAULT_MASTER);
- matrix_set_slave_priority(0, (3 << MATRIX_PRAS0_M4PR_Pos));
- // Set the slave slot cycle limit.
- // If we leave it at the default value of 511 clock cycles, we get transmit underruns due to the HSMCI using the bus for too long.
- // A value of 8 seems to work. I haven't tried other values yet.
- matrix_set_slave_slot_cycle(0, 8);
- #endif
-
- // Set up the SPI pins
- ConfigurePin(g_APinDescription[APIN_SPI_SCK]);
- ConfigurePin(g_APinDescription[APIN_SPI_MOSI]);
- ConfigurePin(g_APinDescription[APIN_SPI_MISO]);
-#if 1
- pinMode(APIN_SPI_SS0, OUTPUT_HIGH); // use manual SS control for now
-#else
- ConfigurePin(g_APinDescription[APIN_SPI_SS0]);
-#endif
-
- pmc_enable_periph_clk(ID_SPI);
-
-#if USE_PDC || USE_DMAC
- spi_dma_disable();
-#endif
-
- spi_reset(SPI); // this clears the transmit and receive registers and puts the SPI into slave mode
- SPI->SPI_MR = SPI_MR_MSTR // master mode
- | SPI_MR_MODFDIS // disable fault detection
- | SPI_MR_PCS(SpiPeripheralChannelId); // fixed peripheral select
-
- // Set SPI mode, clock frequency, CS active after transfer, delay between transfers
- const uint16_t baud_div = (uint16_t)spi_calc_baudrate_div(SpiClockFrequency, SystemCoreClock);
- const uint32_t csr = SPI_CSR_SCBR(baud_div) // Baud rate
- | SPI_CSR_BITS_8_BIT // Transfer bit width
- | SPI_CSR_DLYBCT(0) // Transfer delay
- | SPI_CSR_CSAAT // Keep CS low after transfer in case we are slow in writing the next byte
- | SPI_CSR_NCPHA; // Data is captured on the leading edge of the clock (SPI mode 0)
- SPI->SPI_CSR[SpiPeripheralChannelId] = csr;
- spi_enable(SPI);
-
-#if USE_DMAC
- // Configure DMA RX channel
- dmac_channel_set_configuration(DMAC, CONF_SPI_DMAC_RX_CH,
- DMAC_CFG_SRC_PER(DMA_HW_ID_SPI_RX) | DMAC_CFG_SRC_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ASAP_CFG);
-
- // Configure DMA TX channel
- dmac_channel_set_configuration(DMAC, CONF_SPI_DMAC_TX_CH,
- DMAC_CFG_DST_PER(DMA_HW_ID_SPI_TX) | DMAC_CFG_DST_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ASAP_CFG);
-#endif
- }
-
- void Stop()
- {
- NVIC_DisableIRQ(SPI_IRQn);
- spi_disable(SPI);
-#if USE_PDC || USE_DMA
- spi_dma_check_rx_complete();
- spi_dma_disable();
-#endif
- }
-
- // Wait for transmitter ready returning true if timed out
- static inline bool waitForTxReady()
- {
- uint32_t timeout = SPI_TIMEOUT;
- while (!spi_is_tx_ready(SPI))
- {
- if (--timeout == 0)
- {
- return true;
- }
- }
- return false;
- }
-
- // Wait for transmitter empty returning true if timed out
- static inline bool waitForTxEmpty()
- {
- uint32_t timeout = SPI_TIMEOUT;
- while (!spi_is_tx_empty(SPI))
- {
- if (!timeout--)
- {
- return true;
- }
- }
- return false;
- }
-
- // Wait for receive data available returning true if timed out
- static inline bool waitForRxReady()
- {
- uint32_t timeout = SPI_TIMEOUT;
- while (!spi_is_rx_ready(SPI))
- {
- if (--timeout == 0)
- {
- return true;
- }
- }
- return false;
- }
-
- // Set the SS pin low to address the W5500
- void AssertSS()
- {
- spi_set_peripheral_chip_select_value(SPI, spi_get_pcs(SpiPeripheralChannelId));
- digitalWrite(SamCsPin, LOW);
- }
-
- // Set the SS pin high again
- void ReleaseSS()
- {
- waitForTxEmpty();
- digitalWrite(SamCsPin, HIGH);
- }
-
- //TODO return type, error returns
- uint8_t ExchangeByte(uint8_t b, bool isLast)
- {
- if (waitForTxReady())
- {
- return SPI_ERROR_TIMEOUT;
- }
-
- // Write to transmit register
- uint32_t dOut = b;
- if (isLast)
- {
- dOut |= SPI_TDR_LASTXFER;
- }
- SPI->SPI_TDR = dOut;
-
- // Wait for receive register
- if (waitForRxReady())
- {
- return SPI_ERROR_TIMEOUT;
- }
-
- // Get data from receive register
- return (uint8_t)SPI->SPI_RDR;
- }
-
- spi_status_t ReadBurst(uint8_t* rx_data, size_t len)
- {
- for (size_t i = 0; i < len; ++i)
- {
- uint32_t dOut = 0x000000FF;
- if (waitForTxReady())
- {
- return SPI_ERROR_TIMEOUT;
- }
-
- // Write to transmit register
- if (i + 1 == len)
- {
- dOut |= SPI_TDR_LASTXFER;
- }
- SPI->SPI_TDR = dOut;
-
- // Wait for receive register
- if (waitForRxReady())
- {
- return SPI_ERROR_TIMEOUT;
- }
-
- // Get data from receive register
- *rx_data++ = (uint8_t)SPI->SPI_RDR;
- }
-
- return SPI_OK;
- }
-
- spi_status_t SendBurst(const uint8_t* tx_data, size_t len)
- {
- for (uint32_t i = 0; i < len; ++i)
- {
- uint32_t dOut = (uint32_t)*tx_data++;
- if (waitForTxReady())
- {
- return SPI_ERROR_TIMEOUT;
- }
-
- // Write to transmit register
- if (i + 1 == len)
- {
- dOut |= SPI_TDR_LASTXFER;
- }
- SPI->SPI_TDR = dOut;
- // Wait for receive register
- if (waitForRxReady())
- {
- return SPI_ERROR_TIMEOUT;
- }
-
- // Get data from receive register
- (void)SPI->SPI_RDR;
- }
-
- return SPI_OK;
- }
-
-} // end namespace
-
-// End
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/utility/WizSpi.h b/src/DuetNG/DuetEthernet/Ethernet3/utility/WizSpi.h
deleted file mode 100644
index 214c668f..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/utility/WizSpi.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Spi.h
- *
- * Created on: 16 Dec 2016
- * Author: David
- */
-
-#ifndef SRC_DUETNG_DUETETHERNET_ETHERNET3_UTILITY_WIZSPI_H_
-#define SRC_DUETNG_DUETETHERNET_ETHERNET3_UTILITY_WIZSPI_H_
-
-#include "spi.h"
-
-namespace WizSpi
-{
- void Init();
- void Stop();
- void AssertSS();
- void ReleaseSS();
- uint8_t ExchangeByte(uint8_t b, bool isLast);
- spi_status_t ReadBurst(uint8_t* rx_data, size_t len);
- spi_status_t SendBurst(const uint8_t* tx_data, size_t len);
-}
-
-#endif /* SRC_DUETNG_DUETETHERNET_ETHERNET3_UTILITY_WIZSPI_H_ */
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/utility/socket.cpp b/src/DuetNG/DuetEthernet/Ethernet3/utility/socket.cpp
deleted file mode 100644
index 75f7a993..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/utility/socket.cpp
+++ /dev/null
@@ -1,413 +0,0 @@
- /*
- * - 10 Apr. 2015
- * Added support for Arduino Ethernet Shield 2
- * by Arduino.org team
- */
-
-#include "utility/w5500.h"
-#include "utility/socket.h"
-
-static uint16_t local_port;
-
-/**
- * @brief This Socket function initialize the channel in perticular mode, and set the port and wait for w5500 done it.
- * @return 1 for success else 0.
- */
-uint8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag)
-{
- if ((protocol == SnMR::TCP) || (protocol == SnMR::UDP) || (protocol == SnMR::IPRAW) || (protocol == SnMR::MACRAW) || (protocol == SnMR::PPPOE))
- {
- close(s);
- w5500.writeSnMR(s, protocol | flag);
- if (port != 0) {
- w5500.writeSnPORT(s, port);
- }
- else {
- local_port++; // if don't set the source port, set local_port number.
- w5500.writeSnPORT(s, local_port);
- }
-
- w5500.execCmdSn(s, Sock_OPEN);
-
- return 1;
- }
-
- return 0;
-}
-
-
-/**
- * @brief This function close the socket and parameter is "s" which represent the socket number
- */
-void close(SOCKET s)
-{
- w5500.execCmdSn(s, Sock_CLOSE);
- w5500.writeSnIR(s, 0xFF);
-}
-
-
-/**
- * @brief This function established the connection for the channel in passive (server) mode. This function waits for the request from the peer.
- * @return 1 for success else 0.
- */
-uint8_t listen(SOCKET s)
-{
- if (w5500.readSnSR(s) != SnSR::INIT)
- return 0;
- w5500.execCmdSn(s, Sock_LISTEN);
- return 1;
-}
-
-
-/**
- * @brief This function established the connection for the channel in Active (client) mode.
- * This function waits for the untill the connection is established.
- *
- * @return 1 for success else 0.
- */
-uint8_t connect(SOCKET s, uint8_t * addr, uint16_t port)
-{
- if
- (
- ((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
- ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
- (port == 0x00)
- )
- return 0;
-
- // set destination IP
- w5500.writeSnDIPR(s, addr);
- w5500.writeSnDPORT(s, port);
- w5500.execCmdSn(s, Sock_CONNECT);
-
- return 1;
-}
-
-
-
-/**
- * @brief This function used for disconnect the socket and parameter is "s" which represent the socket number
- * @return 1 for success else 0.
- */
-void disconnect(SOCKET s)
-{
- w5500.execCmdSn(s, Sock_DISCON);
-}
-
-
-/**
- * @brief This function used to send the data in TCP mode
- * @return 1 for success else 0.
- */
-uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len)
-{
- uint8_t status=0;
- uint16_t ret=0;
- uint16_t freesize=0;
-
- if (len > w5500.SSIZE)
- ret = w5500.SSIZE; // check size not to exceed MAX size.
- else
- ret = len;
-
- // if freebuf is available, start.
- do
- {
- freesize = w5500.getTXFreeSize(s);
- status = w5500.readSnSR(s);
- if ((status != SnSR::ESTABLISHED) && (status != SnSR::CLOSE_WAIT))
- {
- ret = 0;
- break;
- }
- }
- while (freesize < ret);
-
- // copy data
- w5500.send_data_processing(s, (uint8_t *)buf, ret);
- w5500.execCmdSn(s, Sock_SEND);
-
- /* +2008.01 bj */
- while ( (w5500.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK )
- {
- /* m2008.01 [bj] : reduce code */
- if ( w5500.readSnSR(s) == SnSR::CLOSED )
- {
- close(s);
- return 0;
- }
- }
- /* +2008.01 bj */
- w5500.writeSnIR(s, SnIR::SEND_OK);
- return ret;
-}
-
-
-/**
- * @brief This function is an application I/F function which is used to receive the data in TCP mode.
- * It continues to wait for data as much as the application wants to receive.
- *
- * @return received data size for success else -1.
- */
-int16_t recv(SOCKET s, uint8_t *buf, int16_t len)
-{
- // Check how much data is available
- int16_t ret = w5500.getRXReceivedSize(s);
- if ( ret == 0 )
- {
- // No data available.
- uint8_t status = w5500.readSnSR(s);
- if ( status == SnSR::LISTEN || status == SnSR::CLOSED || status == SnSR::CLOSE_WAIT )
- {
- // The remote end has closed its side of the connection, so this is the eof state
- ret = 0;
- }
- else
- {
- // The connection is still up, but there's no data waiting to be read
- ret = -1;
- }
- }
- else if (ret > len)
- {
- ret = len;
- }
-
- if ( ret > 0 )
- {
- w5500.recv_data_processing(s, buf, ret);
- w5500.execCmdSn(s, Sock_RECV);
- }
- return ret;
-}
-
-
-/**
- * @brief Returns the first byte in the receive queue (no checking)
- *
- * @return
- */
-uint16_t peek(SOCKET s, uint8_t *buf)
-{
- w5500.recv_data_processing(s, buf, 1, 1);
-
- return 1;
-}
-
-
-/**
- * @brief This function is an application I/F function which is used to send the data for other then TCP mode.
- * Unlike TCP transmission, The peer's destination address and the port is needed.
- *
- * @return This function return send data size for success else -1.
- */
-uint16_t sendto(SOCKET s, const uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t port)
-{
- uint16_t ret=0;
-
- if (len > w5500.SSIZE) ret = w5500.SSIZE; // check size not to exceed MAX size.
- else ret = len;
-
- if
- (
- ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
- ((port == 0x00)) ||(ret == 0)
- )
- {
- /* +2008.01 [bj] : added return value */
- ret = 0;
- }
- else
- {
- w5500.writeSnDIPR(s, addr);
- w5500.writeSnDPORT(s, port);
-
- // copy data
- w5500.send_data_processing(s, (uint8_t *)buf, ret);
- w5500.execCmdSn(s, Sock_SEND);
-
- /* +2008.01 bj */
- while ( (w5500.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK )
- {
- if (w5500.readSnIR(s) & SnIR::TIMEOUT)
- {
- /* +2008.01 [bj]: clear interrupt */
- w5500.writeSnIR(s, (SnIR::SEND_OK | SnIR::TIMEOUT)); /* clear SEND_OK & TIMEOUT */
- return 0;
- }
- }
-
- /* +2008.01 bj */
- w5500.writeSnIR(s, SnIR::SEND_OK);
- }
- return ret;
-}
-
-
-/**
- * @brief This function is an application I/F function which is used to receive the data in other then
- * TCP mode. This function is used to receive UDP, IP_RAW and MAC_RAW mode, and handle the header as well.
- *
- * @return This function return received data size for success else -1.
- */
-uint16_t recvfrom(SOCKET s, uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t *port)
-{
- uint8_t head[8];
- uint16_t data_len=0;
- uint16_t ptr=0;
-
- if ( len > 0 )
- {
- ptr = w5500.readSnRX_RD(s);
- switch (w5500.readSnMR(s) & 0x07)
- {
- case SnMR::UDP :
- w5500.read_data(s, ptr, head, 0x08);
- ptr += 8;
- // read peer's IP address, port number.
- addr[0] = head[0];
- addr[1] = head[1];
- addr[2] = head[2];
- addr[3] = head[3];
- *port = head[4];
- *port = (*port << 8) + head[5];
- data_len = head[6];
- data_len = (data_len << 8) + head[7];
-
- w5500.read_data(s, ptr, buf, data_len); // data copy.
- ptr += data_len;
-
- w5500.writeSnRX_RD(s, ptr);
- break;
-
- case SnMR::IPRAW :
- w5500.read_data(s, ptr, head, 0x06);
- ptr += 6;
-
- addr[0] = head[0];
- addr[1] = head[1];
- addr[2] = head[2];
- addr[3] = head[3];
- data_len = head[4];
- data_len = (data_len << 8) + head[5];
-
- w5500.read_data(s, ptr, buf, data_len); // data copy.
- ptr += data_len;
-
- w5500.writeSnRX_RD(s, ptr);
- break;
-
- case SnMR::MACRAW:
- w5500.read_data(s, ptr, head, 2);
- ptr+=2;
- data_len = head[0];
- data_len = (data_len<<8) + head[1] - 2;
-
- w5500.read_data(s, ptr, buf, data_len);
- ptr += data_len;
- w5500.writeSnRX_RD(s, ptr);
- break;
-
- default :
- break;
- }
- w5500.execCmdSn(s, Sock_RECV);
- }
- return data_len;
-}
-
-/**
- * @brief Wait for buffered transmission to complete.
- */
-void flush(SOCKET s) {
- // TODO
-}
-
-uint16_t igmpsend(SOCKET s, const uint8_t * buf, uint16_t len)
-{
- //uint8_t status=0;
- uint16_t ret=0;
-
- if (len > w5500.SSIZE)
- ret = w5500.SSIZE; // check size not to exceed MAX size.
- else
- ret = len;
-
- if (ret == 0)
- return 0;
-
- w5500.send_data_processing(s, (uint8_t *)buf, ret);
- w5500.execCmdSn(s, Sock_SEND);
-
- while ( (w5500.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK )
- {
- //status = w5500.readSnSR(s);
- (void)w5500.readSnSR(s);
- if (w5500.readSnIR(s) & SnIR::TIMEOUT)
- {
- /* in case of igmp, if send fails, then socket closed */
- /* if you want change, remove this code. */
- close(s);
- return 0;
- }
- }
-
- w5500.writeSnIR(s, SnIR::SEND_OK);
- return ret;
-}
-
-uint16_t bufferData(SOCKET s, uint16_t offset, const uint8_t* buf, uint16_t len)
-{
- uint16_t ret =0;
- if (len > w5500.getTXFreeSize(s))
- {
- ret = w5500.getTXFreeSize(s); // check size not to exceed MAX size.
- }
- else
- {
- ret = len;
- }
- w5500.send_data_processing_offset(s, offset, buf, ret);
- return ret;
-}
-
-int startUDP(SOCKET s, uint8_t* addr, uint16_t port)
-{
- if
- (
- ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
- ((port == 0x00))
- )
- {
- return 0;
- }
- else
- {
- w5500.writeSnDIPR(s, addr);
- w5500.writeSnDPORT(s, port);
- return 1;
- }
-}
-
-int sendUDP(SOCKET s)
-{
- w5500.execCmdSn(s, Sock_SEND);
-
- /* +2008.01 bj */
- while ( (w5500.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK )
- {
- if (w5500.readSnIR(s) & SnIR::TIMEOUT)
- {
- /* +2008.01 [bj]: clear interrupt */
- w5500.writeSnIR(s, (SnIR::SEND_OK|SnIR::TIMEOUT));
- return 0;
- }
- }
-
- /* +2008.01 bj */
- w5500.writeSnIR(s, SnIR::SEND_OK);
-
- /* Sent ok */
- return 1;
-}
-
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/utility/socket.h b/src/DuetNG/DuetEthernet/Ethernet3/utility/socket.h
deleted file mode 100644
index 903280c0..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/utility/socket.h
+++ /dev/null
@@ -1,48 +0,0 @@
- /*
- * - 10 Apr. 2015
- * Added support for Arduino Ethernet Shield 2
- * by Arduino.org team
- */
-
-#ifndef _SOCKET_H_
-#define _SOCKET_H_
-
-#include "utility/w5500.h"
-
-extern uint8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag); // Opens a socket(TCP or UDP or IP_RAW mode)
-extern void close(SOCKET s); // Close socket
-extern uint8_t connect(SOCKET s, uint8_t * addr, uint16_t port); // Establish TCP connection (Active connection)
-extern void disconnect(SOCKET s); // disconnect the connection
-extern uint8_t listen(SOCKET s); // Establish TCP connection (Passive connection)
-extern uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len); // Send data (TCP)
-extern int16_t recv(SOCKET s, uint8_t * buf, int16_t len); // Receive data (TCP)
-extern uint16_t peek(SOCKET s, uint8_t *buf);
-extern uint16_t sendto(SOCKET s, const uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port); // Send data (UDP/IP RAW)
-extern uint16_t recvfrom(SOCKET s, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port); // Receive data (UDP/IP RAW)
-extern void flush(SOCKET s); // Wait for transmission to complete
-
-extern uint16_t igmpsend(SOCKET s, const uint8_t * buf, uint16_t len);
-
-// Functions to allow buffered UDP send (i.e. where the UDP datagram is built up over a
-// number of calls before being sent
-/*
- @brief This function sets up a UDP datagram, the data for which will be provided by one
- or more calls to bufferData and then finally sent with sendUDP.
- @return 1 if the datagram was successfully set up, or 0 if there was an error
-*/
-extern int startUDP(SOCKET s, uint8_t* addr, uint16_t port);
-/*
- @brief This function copies up to len bytes of data from buf into a UDP datagram to be
- sent later by sendUDP. Allows datagrams to be built up from a series of bufferData calls.
- @return Number of bytes successfully buffered
-*/
-uint16_t bufferData(SOCKET s, uint16_t offset, const uint8_t* buf, uint16_t len);
-/*
- @brief Send a UDP datagram built up from a sequence of startUDP followed by one or more
- calls to bufferData.
- @return 1 if the datagram was successfully sent, or 0 if there was an error
-*/
-int sendUDP(SOCKET s);
-
-#endif
-/* _SOCKET_H_ */
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/utility/util.h b/src/DuetNG/DuetEthernet/Ethernet3/utility/util.h
deleted file mode 100644
index 8a254408..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/utility/util.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef UTIL_H
-#define UTIL_H
-
-static inline uint16_t htons(uint16_t x)
-{
- return (x << 8) | ((x >> 8) & 0xFF);
-}
-
-#define ntohs(x) htons(x)
-
-#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \
- ((x)<< 8 & 0x00FF0000UL) | \
- ((x)>> 8 & 0x0000FF00UL) | \
- ((x)>>24 & 0x000000FFUL) )
-#define ntohl(x) htonl(x)
-
-// Get a 16 bit word in network byte order from a buffer
-static inline uint16_t get16nb(const uint8_t *buf)
-{
- return ((uint16_t)buf[0] << 8) | buf[1];
-}
-
-// Get a 32 bit word in network byte order from a buffer
-static inline uint16_t get32nb(const uint8_t *buf)
-{
- return ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) | ((uint32_t)buf[2] << 8) | buf[3];
-}
-
-// Get a 16 bit word in native byte order from a buffer
-static inline uint16_t get16(const uint8_t *buf)
-{
- return ((uint16_t)buf[1] << 8) | buf[0];
-}
-
-// Put a 16-bit word in native byte order in a buffer
-static inline void put16(uint8_t *buf, uint16_t n)
-{
- buf[0] = (uint8_t)n;
- buf[1] = (uint8_t)(n >> 8);
-}
-
-#endif
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/utility/w5500.cpp b/src/DuetNG/DuetEthernet/Ethernet3/utility/w5500.cpp
deleted file mode 100644
index 553f9ee5..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/utility/w5500.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2010 by WIZnet <support@wiznet.co.kr>
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of either the GNU General Public License version 2
- * or the GNU Lesser General Public License version 2.1, both as
- * published by the Free Software Foundation.
- *
- * - 10 Apr. 2015
- * Added support for Arduino Ethernet Shield 2
- * by Arduino.org team
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "Core.h"
-
-#include "utility/w5500.h"
-#include "utility/WizSpi.h"
-
-// W5500 controller instance
-W5500Class w5500;
-
-
-void W5500Class::init(void)
-{
- WizSpi::Init();
-
- for (int i=0; i<MAX_SOCK_NUM; i++)
- {
- const uint8_t cntl_byte = (0x0C + (i<<5));
- write( 0x1E, cntl_byte, 2); //0x1E - Sn_RXBUF_SIZE
- write( 0x1F, cntl_byte, 2); //0x1F - Sn_TXBUF_SIZE
- }
-}
-
-void W5500Class::stop()
-{
- WizSpi::Stop();
-}
-
-uint16_t W5500Class::getTXFreeSize(SOCKET s)
-{
- uint16_t val=0, val1=0;
- do {
- val1 = readSnTX_FSR(s);
- if (val1 != 0)
- val = readSnTX_FSR(s);
- }
- while (val != val1);
- return val;
-}
-
-uint16_t W5500Class::getRXReceivedSize(SOCKET s)
-{
- uint16_t val=0,val1=0;
- do {
- val1 = readSnRX_RSR(s);
- if (val1 != 0)
- val = readSnRX_RSR(s);
- }
- while (val != val1);
- return val;
-}
-
-void W5500Class::send_data_processing(SOCKET s, const uint8_t *data, uint16_t len)
-{
- // This is same as having no offset in a call to send_data_processing_offset
- send_data_processing_offset(s, 0, data, len);
-}
-
-void W5500Class::send_data_processing_offset(SOCKET s, uint16_t data_offset, const uint8_t *data, uint16_t len)
-{
- uint16_t ptr = readSnTX_WR(s);
- uint8_t cntl_byte = (0x14+(s<<5));
- ptr += data_offset;
- write(ptr, cntl_byte, data, len);
- ptr += len;
- writeSnTX_WR(s, ptr);
-
-}
-
-void W5500Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek)
-{
- uint16_t ptr = readSnRX_RD(s);
-
- read_data(s, ptr, data, len);
- if (!peek)
- {
- ptr += len;
- writeSnRX_RD(s, ptr);
- }
-}
-
-void W5500Class::read_data(SOCKET s, volatile uint16_t src, volatile uint8_t *dst, uint16_t len)
-{
- uint8_t cntl_byte = (0x18+(s<<5));
- read((uint16_t)src , cntl_byte, (uint8_t *)dst, len);
-}
-
-uint8_t W5500Class::write(uint16_t _addr, uint8_t _cb, uint8_t _data)
-{
- WizSpi::AssertSS();
- WizSpi::ExchangeByte(_addr >> 8, false);
- WizSpi::ExchangeByte(_addr & 0xFF, false);
- WizSpi::ExchangeByte(_cb, false);
- WizSpi::ExchangeByte(_data, true);
- WizSpi::ReleaseSS();
- return 1;
-}
-
-uint16_t W5500Class::write(uint16_t _addr, uint8_t _cb, const uint8_t *_buf, uint16_t _len)
-{
- WizSpi::AssertSS();
- WizSpi::ExchangeByte(_addr >> 8, false);
- WizSpi::ExchangeByte(_addr & 0xFF, false);
- WizSpi::ExchangeByte(_cb, false);
- WizSpi::SendBurst(_buf, _len);
- WizSpi::ReleaseSS();
- return _len;
-}
-
-uint8_t W5500Class::read(uint16_t _addr, uint8_t _cb)
-{
- WizSpi::AssertSS();
- WizSpi::ExchangeByte(_addr >> 8, false);
- WizSpi::ExchangeByte(_addr & 0xFF, false);
- WizSpi::ExchangeByte(_cb, false);
- const uint8_t _data = WizSpi::ExchangeByte(0, true);
- WizSpi::ReleaseSS();
- return _data;
-}
-
-uint16_t W5500Class::read(uint16_t _addr, uint8_t _cb, uint8_t *_buf, uint16_t _len)
-{
- WizSpi::AssertSS();
- WizSpi::ExchangeByte(_addr >> 8, false);
- WizSpi::ExchangeByte(_addr & 0xFF, false);
- WizSpi::ExchangeByte(_cb, false);
- WizSpi::ReadBurst(_buf, _len);
- WizSpi::ReleaseSS();
- return _len;
-}
-
-void W5500Class::execCmdSn(SOCKET s, SockCMD _cmd) {
- // Send command to socket
- writeSnCR(s, _cmd);
- // Wait for command to complete
- while (readSnCR(s))
- ;
-}
-
-// End
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/utility/w5500.h b/src/DuetNG/DuetEthernet/Ethernet3/utility/w5500.h
deleted file mode 100644
index 418da9a8..00000000
--- a/src/DuetNG/DuetEthernet/Ethernet3/utility/w5500.h
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
-* Copyright (c) 2010 by WIZnet <support@wiznet.co.kr>
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of either the GNU General Public License version 2
- * or the GNU Lesser General Public License version 2.1, both as
- * published by the Free Software Foundation.
- *
- * - 10 Apr. 2015
- * Added support for Arduino Ethernet Shield 2
- * by Arduino.org team
- */
-
-#ifndef W5500_H_INCLUDED
-#define W5500_H_INCLUDED
-
-#include <cstdint>
-
-// The SAM4E header files define UDP as a macro for accessing the USB Device Port, which clashes with UDP in this module. So un-define it.
-#undef UDP
-
-#define MAX_SOCK_NUM 8
-
-typedef uint8_t SOCKET;
-/*
-class MR {
-public:
- static const uint8_t RST = 0x80;
- static const uint8_t PB = 0x10;
- static const uint8_t PPPOE = 0x08;
- static const uint8_t LB = 0x04;
- static const uint8_t AI = 0x02;
- static const uint8_t IND = 0x01;
-};
-*/
-/*
-class IR {
-public:
- static const uint8_t CONFLICT = 0x80;
- static const uint8_t UNREACH = 0x40;
- static const uint8_t PPPoE = 0x20;
- static const uint8_t SOCK0 = 0x01;
- static const uint8_t SOCK1 = 0x02;
- static const uint8_t SOCK2 = 0x04;
- static const uint8_t SOCK3 = 0x08;
- static inline uint8_t SOCK(SOCKET ch) { return (0x01 << ch); };
-};
-*/
-
-class SnMR {
-public:
- static const uint8_t CLOSE = 0x00;
- static const uint8_t TCP = 0x01;
- static const uint8_t UDP = 0x02;
- static const uint8_t IPRAW = 0x03;
- static const uint8_t MACRAW = 0x04;
- static const uint8_t PPPOE = 0x05;
- static const uint8_t ND = 0x20;
- static const uint8_t MULTI = 0x80;
-};
-
-enum SockCMD {
- Sock_OPEN = 0x01,
- Sock_LISTEN = 0x02,
- Sock_CONNECT = 0x04,
- Sock_DISCON = 0x08,
- Sock_CLOSE = 0x10,
- Sock_SEND = 0x20,
- Sock_SEND_MAC = 0x21,
- Sock_SEND_KEEP = 0x22,
- Sock_RECV = 0x40
-};
-
-/*class SnCmd {
-public:
- static const uint8_t OPEN = 0x01;
- static const uint8_t LISTEN = 0x02;
- static const uint8_t CONNECT = 0x04;
- static const uint8_t DISCON = 0x08;
- static const uint8_t CLOSE = 0x10;
- static const uint8_t SEND = 0x20;
- static const uint8_t SEND_MAC = 0x21;
- static const uint8_t SEND_KEEP = 0x22;
- static const uint8_t RECV = 0x40;
-};
-*/
-
-class SnIR {
-public:
- static const uint8_t SEND_OK = 0x10;
- static const uint8_t TIMEOUT = 0x08;
- static const uint8_t RECV = 0x04;
- static const uint8_t DISCON = 0x02;
- static const uint8_t CON = 0x01;
-};
-
-class SnSR {
-public:
- static const uint8_t CLOSED = 0x00;
- static const uint8_t INIT = 0x13;
- static const uint8_t LISTEN = 0x14;
- static const uint8_t SYNSENT = 0x15;
- static const uint8_t SYNRECV = 0x16;
- static const uint8_t ESTABLISHED = 0x17;
- static const uint8_t FIN_WAIT = 0x18;
- static const uint8_t CLOSING = 0x1A;
- static const uint8_t TIME_WAIT = 0x1B;
- static const uint8_t CLOSE_WAIT = 0x1C;
- static const uint8_t LAST_ACK = 0x1D;
- static const uint8_t UDP = 0x22;
- static const uint8_t IPRAW = 0x32;
- static const uint8_t MACRAW = 0x42;
- static const uint8_t PPPOE = 0x5F;
-};
-
-class IPPROTO {
-public:
- static const uint8_t IP = 0;
- static const uint8_t ICMP = 1;
- static const uint8_t IGMP = 2;
- static const uint8_t GGP = 3;
- static const uint8_t TCP = 6;
- static const uint8_t PUP = 12;
- static const uint8_t UDP = 17;
- static const uint8_t IDP = 22;
- static const uint8_t ND = 77;
- static const uint8_t RAW = 255;
-};
-
-class W5500Class {
-
-public:
- void init();
-
- void stop();
-
- /**
- * @brief This function is being used for copy the data form Receive buffer of the chip to application buffer.
- *
- * It calculate the actual physical address where one has to read
- * the data from Receive buffer. Here also take care of the condition while it exceed
- * the Rx memory uper-bound of socket.
- */
- void read_data(SOCKET s, volatile uint16_t src, volatile uint8_t * dst, uint16_t len);
-
- /**
- * @brief This function is being called by send() and sendto() function also.
- *
- * This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer
- * register. User should read upper byte first and lower byte later to get proper value.
- */
- void send_data_processing(SOCKET s, const uint8_t *data, uint16_t len);
- /**
- * @brief A copy of send_data_processing that uses the provided ptr for the
- * write offset. Only needed for the "streaming" UDP API, where
- * a single UDP packet is built up over a number of calls to
- * send_data_processing_ptr, because TX_WR doesn't seem to get updated
- * correctly in those scenarios
- * @param ptr value to use in place of TX_WR. If 0, then the value is read
- * in from TX_WR
- * @return New value for ptr, to be used in the next call
- */
- // FIXME Update documentation
- void send_data_processing_offset(SOCKET s, uint16_t data_offset, const uint8_t *data, uint16_t len);
-
- /**
- * @brief This function is being called by recv() also.
- *
- * This function read the Rx read pointer register
- * and after copy the data from receive buffer update the Rx write pointer register.
- * User should read upper byte first and lower byte later to get proper value.
- */
- void recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek = 0);
-
- inline void setGatewayIp(const uint8_t *_addr);
- inline void getGatewayIp(uint8_t *_addr);
-
- inline void setSubnetMask(const uint8_t *_addr);
- inline void getSubnetMask(uint8_t *_addr);
-
- inline void setMACAddress(const uint8_t * addr);
- inline void getMACAddress(uint8_t * addr);
-
- inline void setIPAddress(const uint8_t * addr);
- inline void getIPAddress(uint8_t * addr);
-
- inline void setRetransmissionTime(uint16_t timeout);
- inline void setRetransmissionCount(uint8_t _retry);
-
- inline void setPHYCFGR(uint8_t _val);
- inline uint8_t getPHYCFGR();
-
- void execCmdSn(SOCKET s, SockCMD _cmd);
-
- uint16_t getTXFreeSize(SOCKET s);
- uint16_t getRXReceivedSize(SOCKET s);
-
-
- // W5500 Registers
- // ---------------
-private:
- static uint8_t write(uint16_t _addr, uint8_t _cb, uint8_t _data);
- static uint16_t write(uint16_t _addr, uint8_t _cb, const uint8_t *buf, uint16_t len);
- static uint8_t read(uint16_t _addr, uint8_t _cb );
- static uint16_t read(uint16_t _addr, uint8_t _cb, uint8_t *buf, uint16_t len);
-
-#define __GP_REGISTER8(name, address) \
- static inline void write##name(uint8_t _data) { \
- write(address, 0x04, _data); \
- } \
- static inline uint8_t read##name() { \
- return read(address, 0x00); \
- }
-#define __GP_REGISTER16(name, address) \
- static void write##name(uint16_t _data) { \
- write(address, 0x04, _data >> 8); \
- write(address+1, 0x04, _data & 0xFF); \
- } \
- static uint16_t read##name() { \
- uint16_t res = read(address, 0x00); \
- res = (res << 8) + read(address + 1, 0x00); \
- return res; \
- }
-#define __GP_REGISTER_N(name, address, size) \
- static uint16_t write##name(const uint8_t *_buff) { \
- return write(address, 0x04, _buff, size); \
- } \
- static uint16_t read##name(uint8_t *_buff) { \
- return read(address, 0x00, _buff, size); \
- }
-
-public:
- __GP_REGISTER8 (MR, 0x0000); // Mode
- __GP_REGISTER_N(GAR, 0x0001, 4); // Gateway IP address
- __GP_REGISTER_N(SUBR, 0x0005, 4); // Subnet mask address
- __GP_REGISTER_N(SHAR, 0x0009, 6); // Source MAC address
- __GP_REGISTER_N(SIPR, 0x000F, 4); // Source IP address
- __GP_REGISTER8 (IR, 0x0015); // Interrupt
- __GP_REGISTER8 (IMR, 0x0016); // Interrupt Mask
- __GP_REGISTER16(RTR, 0x0019); // Timeout address
- __GP_REGISTER8 (RCR, 0x001B); // Retry count
- __GP_REGISTER_N(UIPR, 0x0028, 4); // Unreachable IP address in UDP mode
- __GP_REGISTER16(UPORT, 0x002C); // Unreachable Port address in UDP mode
- __GP_REGISTER8 (PHYCFGR, 0x002E); // PHY Configuration register, default value: 0b 1011 1xxx
- __GP_REGISTER8 (VERSIONR, 0x0039); // Version register, should return 0x04
-
-
-#undef __GP_REGISTER8
-#undef __GP_REGISTER16
-#undef __GP_REGISTER_N
-
- // W5500 Socket registers
- // ----------------------
-private:
- static inline uint8_t readSn(SOCKET _s, uint16_t _addr);
- static inline uint8_t writeSn(SOCKET _s, uint16_t _addr, uint8_t _data);
- static inline uint16_t readSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t len);
- static inline uint16_t writeSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t len);
-
- //static const uint16_t CH_BASE = 0x0000;
- //static const uint16_t CH_SIZE = 0x0000;
-
-#define __SOCKET_REGISTER8(name, address) \
- static inline void write##name(SOCKET _s, uint8_t _data) { \
- writeSn(_s, address, _data); \
- } \
- static inline uint8_t read##name(SOCKET _s) { \
- return readSn(_s, address); \
- }
-#if defined(REL_GR_KURUMI) || defined(REL_GR_KURUMI_PROTOTYPE)
-#define __SOCKET_REGISTER16(name, address) \
- static void write##name(SOCKET _s, uint16_t _data) { \
- writeSn(_s, address, _data >> 8); \
- writeSn(_s, address+1, _data & 0xFF); \
- } \
- static uint16_t read##name(SOCKET _s) { \
- uint16_t res = readSn(_s, address); \
- uint16_t res2 = readSn(_s,address + 1); \
- res = res << 8; \
- res2 = res2 & 0xFF; \
- res = res | res2; \
- return res; \
- }
-#else
-#define __SOCKET_REGISTER16(name, address) \
- static void write##name(SOCKET _s, uint16_t _data) { \
- writeSn(_s, address, _data >> 8); \
- writeSn(_s, address+1, _data & 0xFF); \
- } \
- static uint16_t read##name(SOCKET _s) { \
- uint16_t res = readSn(_s, address); \
- res = (res << 8) + readSn(_s, address + 1); \
- return res; \
- }
-#endif
-#define __SOCKET_REGISTER_N(name, address, size) \
- static uint16_t write##name(SOCKET _s, uint8_t *_buff) { \
- return writeSn(_s, address, _buff, size); \
- } \
- static uint16_t read##name(SOCKET _s, uint8_t *_buff) { \
- return readSn(_s, address, _buff, size); \
- }
-
-public:
- __SOCKET_REGISTER8(SnMR, 0x0000) // Mode
- __SOCKET_REGISTER8(SnCR, 0x0001) // Command
- __SOCKET_REGISTER8(SnIR, 0x0002) // Interrupt
- __SOCKET_REGISTER8(SnSR, 0x0003) // Status
- __SOCKET_REGISTER16(SnPORT, 0x0004) // Source Port
- __SOCKET_REGISTER_N(SnDHAR, 0x0006, 6) // Destination Hardw Addr
- __SOCKET_REGISTER_N(SnDIPR, 0x000C, 4) // Destination IP Addr
- __SOCKET_REGISTER16(SnDPORT, 0x0010) // Destination Port
- __SOCKET_REGISTER16(SnMSSR, 0x0012) // Max Segment Size
- __SOCKET_REGISTER8(SnPROTO, 0x0014) // Protocol in IP RAW Mode
- __SOCKET_REGISTER8(SnTOS, 0x0015) // IP TOS
- __SOCKET_REGISTER8(SnTTL, 0x0016) // IP TTL
- __SOCKET_REGISTER16(SnTX_FSR, 0x0020) // TX Free Size
- __SOCKET_REGISTER16(SnTX_RD, 0x0022) // TX Read Pointer
- __SOCKET_REGISTER16(SnTX_WR, 0x0024) // TX Write Pointer
- __SOCKET_REGISTER16(SnRX_RSR, 0x0026) // RX Free Size
- __SOCKET_REGISTER16(SnRX_RD, 0x0028) // RX Read Pointer
- __SOCKET_REGISTER16(SnRX_WR, 0x002A) // RX Write Pointer (supported?)
-
-#undef __SOCKET_REGISTER8
-#undef __SOCKET_REGISTER16
-#undef __SOCKET_REGISTER_N
-
-
-private:
- static const uint8_t RST = 7; // Reset BIT
- static const int SOCKETS = 8;
-
-public:
- static const uint16_t SSIZE = 2048; // Max Tx buffer size
-private:
- static const uint16_t RSIZE = 2048; // Max Rx buffer size
-
-private:
-#if defined(ARDUINO_ARCH_AVR)
-#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284P__)
- inline static void initSS() { DDRB |= _BV(4); };
- inline static void setSS() { PORTB &= ~_BV(4); };
- inline static void resetSS() { PORTB |= _BV(4); };
-#elif defined(__AVR_ATmega32U4__)
- inline static void initSS() { DDRB |= _BV(6); };
- inline static void setSS() { PORTB &= ~_BV(6); };
- inline static void resetSS() { PORTB |= _BV(6); };
-#elif defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB162__)
- inline static void initSS() { DDRB |= _BV(0); };
- inline static void setSS() { PORTB &= ~_BV(0); };
- inline static void resetSS() { PORTB |= _BV(0); };
-#elif defined(REL_GR_KURUMI) || defined(REL_GR_KURUMI_PROTOTYPE)
- inline static void initSS() { pinMode(SS, OUTPUT);
- digitalWrite(SS, HIGH); };
- inline static void setSS() { digitalWrite(SS, LOW); };
- inline static void resetSS() { digitalWrite(SS, HIGH); };
-#else
- inline static void initSS() { DDRB |= _BV(2); };
- inline static void setSS() { PORTB &= ~_BV(2); };
- inline static void resetSS() { PORTB |= _BV(2); };
-#endif
-#elif defined(ARDUINO_ARCH_SAMD)
- inline static void initSS() { PORT->Group[g_APinDescription[10].ulPort].PINCFG[g_APinDescription[10].ulPin].reg&=~(uint8_t)(PORT_PINCFG_INEN) ;
- PORT->Group[g_APinDescription[10].ulPort].DIRSET.reg = (uint32_t)(1<<g_APinDescription[10].ulPin) ;
- PORT->Group[g_APinDescription[10].ulPort].PINCFG[g_APinDescription[10].ulPin].reg=(uint8_t)(PORT_PINCFG_PULLEN) ;
- PORT->Group[g_APinDescription[10].ulPort].OUTSET.reg = (1ul << g_APinDescription[10].ulPin) ; };
- inline static void setSS() { PORT->Group[g_APinDescription[10].ulPort].OUTCLR.reg = (1ul << g_APinDescription[10].ulPin) ; };
- inline static void resetSS() { PORT->Group[g_APinDescription[10].ulPort].OUTSET.reg = (1ul << g_APinDescription[10].ulPin) ; };
-#endif // ARDUINO_ARCH_AVR
-};
-
-extern W5500Class w5500;
-
-uint8_t W5500Class::readSn(SOCKET _s, uint16_t _addr) {
- uint8_t cntl_byte = (_s<<5)+0x08;
- return read(_addr, cntl_byte);
-}
-
-uint8_t W5500Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t _data) {
- uint8_t cntl_byte = (_s<<5)+0x0C;
- return write(_addr, cntl_byte, _data);
-}
-
-uint16_t W5500Class::readSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len) {
- uint8_t cntl_byte = (_s<<5)+0x08;
- return read(_addr, cntl_byte, _buf, _len );
-}
-
-uint16_t W5500Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len) {
- uint8_t cntl_byte = (_s<<5)+0x0C;
- return write(_addr, cntl_byte, _buf, _len);
-}
-
-void W5500Class::getGatewayIp(uint8_t *_addr) {
- readGAR(_addr);
-}
-
-void W5500Class::setGatewayIp(const uint8_t *_addr) {
- writeGAR(_addr);
-}
-
-void W5500Class::getSubnetMask(uint8_t *_addr) {
- readSUBR(_addr);
-}
-
-void W5500Class::setSubnetMask(const uint8_t *_addr) {
- writeSUBR(_addr);
-}
-
-void W5500Class::getMACAddress(uint8_t *_addr) {
- readSHAR(_addr);
-}
-
-void W5500Class::setMACAddress(const uint8_t *_addr) {
- writeSHAR(_addr);
-}
-
-void W5500Class::getIPAddress(uint8_t *_addr) {
- readSIPR(_addr);
-}
-
-void W5500Class::setIPAddress(const uint8_t *_addr) {
- writeSIPR(_addr);
-}
-
-void W5500Class::setRetransmissionTime(uint16_t _timeout) {
- writeRTR(_timeout);
-}
-
-void W5500Class::setRetransmissionCount(uint8_t _retry) {
- writeRCR(_retry);
-}
-
-void W5500Class::setPHYCFGR(uint8_t _val) {
- writePHYCFGR(_val);
-}
-
-uint8_t W5500Class::getPHYCFGR() {
-// readPHYCFGR();
- return read(0x002E, 0x00);
-}
-
-#endif
diff --git a/src/DuetNG/DuetEthernet/Network.cpp b/src/DuetNG/DuetEthernet/Network.cpp
index 4f742cb8..5f7bd72c 100644
--- a/src/DuetNG/DuetEthernet/Network.cpp
+++ b/src/DuetNG/DuetEthernet/Network.cpp
@@ -20,21 +20,23 @@ void Network::SetIPAddress(const uint8_t p_ipAddress[], const uint8_t p_netmask[
Network::Network(Platform* p)
: platform(p), lastTickMillis(0),
- freeTransactions(nullptr), readyTransactions(nullptr), writingTransactions(nullptr),
httpPort(DefaultHttpPort), state(NetworkState::disabled), activated(false)
{
- SetIPAddress(DefaultIpAddress, DefaultNetMask, DefaultGateway);
- strcpy(hostname, HOSTNAME);
}
void Network::Init()
{
- // Ensure that the chip is in the reset state
+ // Ensure that the W5500 chip is in the reset state
pinMode(EspResetPin, OUTPUT_LOW);
state = NetworkState::disabled;
longWait = platform->Time();
lastTickMillis = millis();
- InitSockets();
+
+ NetworkBuffer::AllocateBuffers(NetworkBufferCount);
+ NetworkTransaction::AllocateTransactions(NetworkTransactionCount);
+
+ SetIPAddress(DefaultIpAddress, DefaultNetMask, DefaultGateway);
+ strcpy(hostname, HOSTNAME);
}
// This is called at the end of config.g processing.
@@ -53,7 +55,8 @@ void Network::Exit()
Stop();
}
-void Network::Spin()
+// Main spin loop. If 'full' is true then we are being called from the main spin loop. If false then we are being called during HSMCI idle time.
+void Network::Spin(bool full)
{
switch(state)
{
@@ -63,9 +66,8 @@ void Network::Spin()
break;
case NetworkState::establishingLink:
- if (wizphy_getphylink() == PHY_LINK_ON)
+ if (full && wizphy_getphylink() == PHY_LINK_ON)
{
-
usingDhcp = (ipAddress[0] == 0 && ipAddress[1] == 0 && ipAddress[2] == 0 && ipAddress[3] == 0);
if (usingDhcp)
{
@@ -85,38 +87,44 @@ void Network::Spin()
break;
case NetworkState::obtainingIP:
- if (wizphy_getphylink() == PHY_LINK_ON)
+ if (full)
{
- const uint32_t now = millis();
- if (now - lastTickMillis >= 1000)
+ if (wizphy_getphylink() == PHY_LINK_ON)
{
- lastTickMillis += 1000;
- DHCP_time_handler();
+ const uint32_t now = millis();
+ if (now - lastTickMillis >= 1000)
+ {
+ lastTickMillis += 1000;
+ DHCP_time_handler();
+ }
+ const DhcpRunResult ret = DHCP_run();
+ if (ret == DhcpRunResult::DHCP_IP_ASSIGN)
+ {
+ debugPrintf("IP address obtained, network running\n");
+ getSIPR(ipAddress);
+ // Send mDNS announcement so that some routers can perform hostname mapping
+ // if this board is connected via a non-IGMP capable WiFi bridge (like the TP-Link WR701N)
+ //mdns_announce();
+ InitSockets();
+ state = NetworkState::active;
+ }
}
- const DhcpRunResult ret = DHCP_run();
- if (ret == DhcpRunResult::DHCP_IP_ASSIGN)
+ else
{
- debugPrintf("IP address obtained, network running\n");
- getSIPR(ipAddress);
- // Send mDNS announcement so that some routers can perform hostname mapping
- // if this board is connected via a non-IGMP capable WiFi bridge (like the TP-Link WR701N)
- //mdns_announce();
- InitSockets();
- state = NetworkState::active;
+ debugPrintf("Lost phy link\n");
+ DHCP_stop();
+ TerminateSockets();
+ state = NetworkState::establishingLink;
}
}
- else
- {
- DHCP_stop();
- TerminateSockets();
- state = NetworkState::establishingLink;
- }
break;
case NetworkState::active:
+ // Check that the link is still up
if (wizphy_getphylink() == PHY_LINK_ON)
{
- if (usingDhcp)
+ // Maintain DHCP
+ if (full && usingDhcp)
{
const uint32_t now = millis();
if (now - lastTickMillis >= 1000)
@@ -127,50 +135,28 @@ void Network::Spin()
const DhcpRunResult ret = DHCP_run();
if (ret == DhcpRunResult::DHCP_IP_CHANGED)
{
+ debugPrintf("IP address changed\n");
getSIPR(ipAddress);
}
}
- sockets[nextSocketToPoll].Poll();
+ // Poll the next TCP socket
+ sockets[nextSocketToPoll].Poll(full);
+
+ // Move on to the next TCP socket for next time
++nextSocketToPoll;
if (nextSocketToPoll == NumTcpSockets)
{
nextSocketToPoll = 0;
}
-#if 0
- // See if we can send anything
- NetworkTransaction *transaction = writingTransactions;
- if (transaction != nullptr /*&& sendingConnection == nullptr*/ )
- {
- if (transaction->GetNext() != nullptr)
- {
- // Data is supposed to be sent and the last packet has been acknowledged.
- // Rotate the transactions so every client is served even while multiple files are sent
- NetworkTransaction *next = transaction->GetNext();
- writingTransactions = next;
- AppendTransaction(&writingTransactions, transaction);
- transaction = next;
- }
-
- if (transaction->Send())
- {
- // This transaction can be released, do this here
- writingTransactions = transaction->GetNext();
- PrependTransaction(&freeTransactions, transaction);
-
- // If there is more data to write on this connection, do it sometime soon
- NetworkTransaction *nextWrite = transaction->GetNextWrite();
- if (nextWrite != nullptr)
- {
- PrependTransaction(&writingTransactions, nextWrite);
- }
- }
- }
-#endif
}
- else
+ else if (full)
{
- DHCP_stop();
+ debugPrintf("Lost phy link\n");
+ if (usingDhcp)
+ {
+ DHCP_stop();
+ }
TerminateSockets();
state = NetworkState::establishingLink;
}
@@ -236,7 +222,7 @@ void Network::Disable()
if (activated && state != NetworkState::disabled)
{
Stop();
- platform->Message(GENERIC_MESSAGE, "WiFi server stopped\n");
+ platform->Message(GENERIC_MESSAGE, "Network stopped\n");
}
}
@@ -289,180 +275,103 @@ void Network::SetHostname(const char *name)
bool Network::Lock()
{
- //TODO
return true;
}
void Network::Unlock()
{
- //TODO
}
bool Network::InLwip() const
{
- //TODO
return false;
}
// This is called by the web server to get the next networking transaction.
//
-// If cs is NULL, the transaction from the head of readyTransactions will be retrieved.
-// If cs is not NULL, the first transaction with the matching connection will be returned.
+// If conn is NoConnection, the transaction from the head of readyTransactions will be retrieved.
+// If conn is not NoConnection, the first transaction with the matching connection will be returned.
//
-// This method also ensures that the retrieved transaction is moved to the first item of
-// readyTransactions, so that a subsequent call with a NULL cs parameter will return exactly
-// the same instance.
+// This method also ensures that a subsequent call with a null connection parameter will return exactly the same instance.
NetworkTransaction *Network::GetTransaction(Connection conn)
{
-#if 1
- return nullptr;
-#else
- // See if there is any transaction at all
- NetworkTransaction *transaction = readyTransactions;
- if (transaction == nullptr)
- {
- return nullptr;
- }
-
- // If no specific connection is specified or if the first item already matches the
- // connection we are looking for, just return it
- if (cs == nullptr || transaction->GetConnection() == cs)
- {
- return transaction;
- }
-
- // We are looking for a specific transaction, but it's not the first item.
- // Search for it and move it to the head of readyTransactions
- NetworkTransaction *previous = transaction;
- for(NetworkTransaction *item = transaction->next; item != nullptr; item = item->next)
+ if (state == NetworkState::active)
{
- if (item->GetConnection() == cs)
+ if (conn != NoConnection)
{
- previous->next = item->next;
- item->next = readyTransactions;
- readyTransactions = item;
- return item;
+ NetworkTransaction *tr = conn->GetTransaction();
+ if (tr != nullptr && !tr->IsSending())
+ {
+ currentTransactionSocketNumber = conn->GetNumber();
+ return tr;
+ }
+ return nullptr;
}
- previous = item;
- }
-
- // We failed to find a valid transaction for the given connection
- return nullptr;
-#endif
-}
-void Network::AppendTransaction(NetworkTransaction* * list, NetworkTransaction *r)
-{
- r->next = nullptr;
- while (*list != nullptr)
- {
- list = &((*list)->next);
+ size_t socketNum = currentTransactionSocketNumber;
+ do
+ {
+ NetworkTransaction *tr = sockets[socketNum].GetTransaction();
+ if (tr != nullptr && !tr->IsSending())
+ {
+ currentTransactionSocketNumber = socketNum;
+ return tr;
+ }
+ ++socketNum;
+ if (socketNum == NumTcpSockets)
+ {
+ socketNum = 0;
+ }
+ } while (socketNum != currentTransactionSocketNumber);
}
- *list = r;
-}
-void Network::PrependTransaction(NetworkTransaction* * list, NetworkTransaction *r)
-{
- r->next = *list;
- *list = r;
+ return nullptr;
}
-void Network::OpenDataPort(uint16_t port)
+void Network::OpenDataPort(Port port)
{
- //TODO
-#if 0
- closingDataPort = false;
- tcp_pcb* pcb = tcp_new();
- tcp_bind(pcb, IP_ADDR_ANY, port);
- ftp_pasv_pcb = tcp_listen(pcb);
- tcp_accept(ftp_pasv_pcb, conn_accept);
-#endif
+ sockets[FtpSocketNumber].Init(FtpSocketNumber, port);
+ sockets[FtpSocketNumber].Poll(false);
}
-uint16_t Network::GetDataPort() const
+Port Network::GetDataPort() const
{
-#if 1
- return 0; //TODO
-#else
- return (closingDataPort || (ftp_pasv_pcb == nullptr) ? 0 : ftp_pasv_pcb->local_port);
-#endif
+ return sockets[FtpSocketNumber].GetLocalPort();
}
// Close FTP data port and purge associated PCB
void Network::CloseDataPort()
{
- //TODO
-#if 0
- // See if it's already being closed
- if (closingDataPort)
- {
- return;
- }
- closingDataPort = true;
-
- // Close remote connection of our data port or do it as soon as the last packet has been sent
- if (dataCs != nullptr)
- {
- NetworkTransaction *mySendingTransaction = dataCs->sendingTransaction;
- if (mySendingTransaction != nullptr)
- {
- mySendingTransaction->Close();
- return;
- }
- }
-
- // We can close it now, so do it here
- if (ftp_pasv_pcb != nullptr)
- {
- tcp_accept(ftp_pasv_pcb, nullptr);
- tcp_close(ftp_pasv_pcb);
- ftp_pasv_pcb = nullptr;
- }
- closingDataPort = false;
-#endif
-}
-
-// These methods keep track of our connections in case we need to send to one of them
-void Network::SaveDataConnection()
-{
-// dataCs = readyTransactions->cs->GetNumber();
+ sockets[FtpSocketNumber].Close();
}
-void Network::SaveFTPConnection()
+bool Network::AcquireFTPTransaction()
{
-// ftpCs = readyTransactions->cs->GetNumber();
+ return AcquireTransaction(FtpSocketNumber);
}
-void Network::SaveTelnetConnection()
+bool Network::AcquireDataTransaction()
{
-// telnetCs = readyTransactions->cs->GetNumber();
+ return AcquireTransaction(FtpDataSocketNumber);
}
-bool Network::AcquireFTPTransaction()
+bool Network::AcquireTelnetTransaction()
{
-#if 1
- return false; //TODO
-#else
- return AcquireTransaction(ftpCs);
-#endif
+ return AcquireTransaction(TelnetSocketNumber);
}
-bool Network::AcquireDataTransaction()
+bool Network::AcquireTransaction(SocketNumber skt)
{
-#if 1
- return false; //TODO
-#else
- return AcquireTransaction(dataCs);
-#endif
-}
+ if ( sockets[skt].GetTransaction() != nullptr
+ && sockets[skt].GetTransaction()->GetStatus() != TransactionStatus::sending
+ && sockets[skt].GetTransaction()->GetStatus() != TransactionStatus::finished
+ )
+ {
+ currentTransactionSocketNumber = skt;
+ return true;
+ }
-bool Network::AcquireTelnetTransaction()
-{
-#if 1
- return false; //TODO
-#else
- return AcquireTransaction(telnetCs);
-#endif
+ return false;
}
void Network::InitSockets()
@@ -474,7 +383,7 @@ void Network::InitSockets()
sockets[FtpSocketNumber].Init(FtpSocketNumber, FTP_PORT);
sockets[FtpDataSocketNumber].Init(FtpDataSocketNumber, 0); // FTP data port is allocated dynamically
sockets[TelnetSocketNumber].Init(TelnetSocketNumber, TELNET_PORT);
- nextSocketToProcess = nextSocketToPoll = 0;
+ nextSocketToPoll = currentTransactionSocketNumber = 0;
}
void Network::TerminateSockets()
@@ -483,11 +392,23 @@ void Network::TerminateSockets()
{
sockets[skt].Terminate();
}
+}
+void Network::Defer(NetworkTransaction *tr)
+{
+ const Socket *skt = tr->GetConnection();
+ if (skt != nullptr && skt->GetNumber() == currentTransactionSocketNumber)
+ {
+ ++currentTransactionSocketNumber;
+ if (currentTransactionSocketNumber == NumTcpSockets)
+ {
+ currentTransactionSocketNumber = 0;
+ }
+ }
}
-/*static*/ uint16_t Network::GetLocalPort(Connection conn) { return conn->GetLocalPort(); }
-/*static*/ uint16_t Network::GetRemotePort(Connection conn) { return conn->GetRemotePort(); }
+/*static*/ Port Network::GetLocalPort(Connection conn) { return conn->GetLocalPort(); }
+/*static*/ Port Network::GetRemotePort(Connection conn) { return conn->GetRemotePort(); }
/*static*/ uint32_t Network::GetRemoteIP(Connection conn) { return conn->GetRemoteIP(); }
/*static*/ bool Network::IsConnected(Connection conn) { return conn->IsConnected(); }
/*static*/ bool Network::IsTerminated(Connection conn) { return conn->IsTerminated(); }
diff --git a/src/DuetNG/DuetEthernet/Network.h b/src/DuetNG/DuetEthernet/Network.h
index d710205a..d6d38555 100644
--- a/src/DuetNG/DuetEthernet/Network.h
+++ b/src/DuetNG/DuetEthernet/Network.h
@@ -35,7 +35,7 @@ public:
void Init();
void Activate();
void Exit();
- void Spin();
+ void Spin(bool full);
void Diagnostics(MessageType mtype);
void Start();
void Stop();
@@ -48,8 +48,8 @@ public:
void Disable();
bool IsEnabled() const;
- void SetHttpPort(uint16_t port);
- uint16_t GetHttpPort() const;
+ void SetHttpPort(Port port);
+ Port GetHttpPort() const;
void SetHostname(const char *name);
@@ -57,20 +57,22 @@ public:
NetworkTransaction *GetTransaction(Connection conn = NoConnection);
- void OpenDataPort(uint16_t port);
- uint16_t GetDataPort() const;
+ void OpenDataPort(Port port);
+ Port GetDataPort() const;
void CloseDataPort();
- void SaveDataConnection();
- void SaveFTPConnection();
- void SaveTelnetConnection();
+ void SaveDataConnection() {}
+ void SaveFTPConnection() {}
+ void SaveTelnetConnection() {}
bool AcquireFTPTransaction();
bool AcquireDataTransaction();
bool AcquireTelnetTransaction();
- static uint16_t GetLocalPort(Connection conn);
- static uint16_t GetRemotePort(Connection conn);
+ void Defer(NetworkTransaction *tr);
+
+ static Port GetLocalPort(Connection conn);
+ static Port GetRemotePort(Connection conn);
static uint32_t GetRemoteIP(Connection conn);
static bool IsConnected(Connection conn);
static bool IsTerminated(Connection conn);
@@ -86,34 +88,28 @@ private:
active
};
- void AppendTransaction(NetworkTransaction* * list, NetworkTransaction *r);
- void PrependTransaction(NetworkTransaction* * list, NetworkTransaction *r);
- bool AcquireTransaction(Socket *cs);
+ bool AcquireTransaction(SocketNumber skt);
void InitSockets();
void TerminateSockets();
Platform *platform;
- float longWait;
- uint32_t lastTickMillis;
-
- Socket sockets[NumTcpSockets];
- size_t nextSocketToPoll; // next TCP socket number to poll for read/write operations
- size_t nextSocketToProcess; // next TCP socket number to process an incoming request from
+ float longWait;
+ uint32_t lastTickMillis;
- NetworkTransaction * freeTransactions;
- NetworkTransaction * readyTransactions;
- NetworkTransaction * writingTransactions;
+ Socket sockets[NumTcpSockets];
+ size_t nextSocketToPoll; // next TCP socket number to poll for read/write operations
+ size_t currentTransactionSocketNumber; // the socket number of the last transaction we passed to the web server
- uint16_t httpPort;
+ Port httpPort;
uint8_t ipAddress[4];
uint8_t netmask[4];
uint8_t gateway[4];
char hostname[16]; // Limit DHCP hostname to 15 characters + terminating 0
NetworkState state;
- bool activated;
- bool usingDhcp;
+ bool activated;
+ bool usingDhcp;
};
#endif
diff --git a/src/DuetNG/DuetEthernet/NetworkBuffer.cpp b/src/DuetNG/DuetEthernet/NetworkBuffer.cpp
index 8fad5241..9bd9697e 100644
--- a/src/DuetNG/DuetEthernet/NetworkBuffer.cpp
+++ b/src/DuetNG/DuetEthernet/NetworkBuffer.cpp
@@ -6,7 +6,8 @@
*/
#include "NetworkBuffer.h"
-#include <cstring>
+
+#include "Storage/FileStore.h"
NetworkBuffer *NetworkBuffer::freelist = nullptr;
@@ -28,7 +29,7 @@ bool NetworkBuffer::ReadChar(char& b)
{
if (readPointer < dataLength)
{
- b = data[readPointer++];
+ b = Data()[readPointer++];
return true;
}
@@ -36,16 +37,15 @@ bool NetworkBuffer::ReadChar(char& b)
return false;
}
-// Read some data, but not more than the amount in the first buffer
-size_t NetworkBuffer::ReadBuffer(uint8_t *buffer, size_t maxLen)
+const uint8_t* NetworkBuffer::TakeData(size_t &len)
{
- if (maxLen > Remaining())
+ const uint8_t* ret = Data() + readPointer;
+ if (len > dataLength - readPointer)
{
- maxLen = Remaining();
+ len = dataLength - readPointer;
}
- memcpy((void*)buffer, data + readPointer, maxLen);
- readPointer += maxLen;
- return maxLen;
+ readPointer += len;
+ return ret;
}
// Return the amount of data available, including continuation buffers
@@ -56,10 +56,52 @@ size_t NetworkBuffer::TotalRemaining() const
while (b != nullptr)
{
ret += b->Remaining();
+ b = b->next;
}
return ret;
}
+// Append some data, returning the amount appended
+size_t NetworkBuffer::AppendData(const uint8_t *source, size_t length)
+{
+ if (length > SpaceLeft())
+ {
+ length = SpaceLeft();
+ }
+ memcpy(Data() + dataLength, source, length);
+ dataLength += length;
+ return length;
+}
+
+// Read into the buffer from a file returning the number of bytes read
+int NetworkBuffer::ReadFromFile(FileStore *f)
+{
+ const int ret = f->Read(reinterpret_cast<char*>(data32), bufferSize);
+ dataLength = (ret > 0) ? (size_t)ret : 0;
+ readPointer = 0;
+ return ret;
+}
+
+// Clear this buffer and release any successors
+void NetworkBuffer::Empty()
+{
+ readPointer = dataLength = 0;
+ while (next != nullptr)
+ {
+ next = next->Release();
+ }
+}
+
+/*static*/ void NetworkBuffer::AppendToList(NetworkBuffer **list, NetworkBuffer *b)
+{
+ b->next = nullptr;
+ while (*list != nullptr)
+ {
+ list = &((*list)->next);
+ }
+ *list = b;
+}
+
/*static*/ NetworkBuffer *NetworkBuffer::Allocate()
{
NetworkBuffer *ret = freelist;
@@ -67,6 +109,7 @@ size_t NetworkBuffer::TotalRemaining() const
{
freelist = ret->next;
ret->next = nullptr;
+ ret->dataLength = ret->readPointer = 0;
}
return ret;
}
diff --git a/src/DuetNG/DuetEthernet/NetworkBuffer.h b/src/DuetNG/DuetEthernet/NetworkBuffer.h
index 9e20c4bd..63384d89 100644
--- a/src/DuetNG/DuetEthernet/NetworkBuffer.h
+++ b/src/DuetNG/DuetEthernet/NetworkBuffer.h
@@ -8,8 +8,7 @@
#ifndef SRC_DUETNG_DUETETHERNET_NETWORKBUFFER_H_
#define SRC_DUETNG_DUETETHERNET_NETWORKBUFFER_H_
-#include <cstdint>
-#include <cstddef>
+#include "RepRapFirmware.h"
// Network buffer class. These buffers are 2K long so that they can accept as much data as the W5500 can provide in one go.
class NetworkBuffer
@@ -24,7 +23,7 @@ public:
bool ReadChar(char& b);
// Read some data
- size_t ReadBuffer(uint8_t *buffer, size_t maxLen);
+ const uint8_t* TakeData(size_t &len);
// Return the amount of data available, not including continuation buffers
size_t Remaining() const { return dataLength - readPointer; }
@@ -32,21 +31,40 @@ public:
// Return the amount of data available, including continuation buffers
size_t TotalRemaining() const;
+ // Return true if there no data left to read
bool IsEmpty() const { return readPointer == dataLength; }
+ // Return the length available for writing
+ size_t SpaceLeft() const { return bufferSize - dataLength; }
+
+ // Append some data, returning the amount appended
+ size_t AppendData(const uint8_t *source, size_t length);
+
+ // Read into the buffer from a file
+ int ReadFromFile(FileStore *f);
+
+ // Clear this buffer and release any successors
+ void Empty();
+
+ // Append a buffer to a list
+ static void AppendToList(NetworkBuffer **list, NetworkBuffer *b);
+
+ // Allocate a buffer
static NetworkBuffer *Allocate();
+ // Alocate buffers and put them in the freelist
static void AllocateBuffers(unsigned int number);
static const size_t bufferSize = 2048;
private:
NetworkBuffer(NetworkBuffer *n);
+ uint8_t *Data() { return reinterpret_cast<uint8_t*>(data32); }
NetworkBuffer *next;
size_t dataLength;
size_t readPointer;
- uint8_t data[bufferSize];
+ uint32_t data32[bufferSize/sizeof(uint32_t)]; // 32-bit aligned buffer so we can do direct DMA
static NetworkBuffer *freelist;
};
diff --git a/src/DuetNG/DuetEthernet/NetworkDefs.h b/src/DuetNG/DuetEthernet/NetworkDefs.h
index a1225e63..66bc25c6 100644
--- a/src/DuetNG/DuetEthernet/NetworkDefs.h
+++ b/src/DuetNG/DuetEthernet/NetworkDefs.h
@@ -1,5 +1,5 @@
/*
- * NetworkCommon.h
+ * NetworkDefs.h
*
* Created on: 25 Dec 2016
* Author: David
@@ -8,6 +8,9 @@
#ifndef SRC_DUETNG_DUETETHERNET_NETWORKDEFS_H_
#define SRC_DUETNG_DUETETHERNET_NETWORKDEFS_H_
+#include <cstdint>
+#include <cstddef>
+
class NetworkTransaction;
class Socket;
class NetworkBuffer;
@@ -21,8 +24,8 @@ const SocketNumber NoSocket = 255;
typedef uint16_t Port;
-const uint8_t DefaultMacAddress[6] = { 0xBE, 0xEF, 0xDE, 0xAD, 0xFE, 0xED }; // Need some sort of default...
-const uint8_t DefaultIpAddress[4] = { 0, 0, 0, 0 }; // Need some sort of default...
+const uint8_t DefaultMacAddress[6] = { 0xBE, 0xEF, 0xDE, 0xAD, 0xFE, 0xED };
+const uint8_t DefaultIpAddress[4] = { 0, 0, 0, 0 };
const uint8_t DefaultNetMask[4] = { 255, 255, 255, 0 };
const uint8_t DefaultGateway[4] = { 0, 0, 0, 0 };
@@ -32,4 +35,7 @@ const Port TELNET_PORT = 23;
const unsigned int TCP_MSS = 1460;
+const size_t NetworkTransactionCount = 8; // number of NetworkTransactions to be used for network IO
+const size_t NetworkBufferCount = 12; // number of 2K network buffers
+
#endif /* SRC_DUETNG_DUETETHERNET_NETWORKDEFS_H_ */
diff --git a/src/DuetNG/DuetEthernet/NetworkTransaction.cpp b/src/DuetNG/DuetEthernet/NetworkTransaction.cpp
index 855c4c85..eeeb0e90 100644
--- a/src/DuetNG/DuetEthernet/NetworkTransaction.cpp
+++ b/src/DuetNG/DuetEthernet/NetworkTransaction.cpp
@@ -6,46 +6,47 @@
*/
#include "NetworkTransaction.h"
+
+#include "Network.h"
+#include "RepRap.h"
#include "Socket.h"
#include <cstdarg>
//***************************************************************************************************
// NetworkTransaction class
-NetworkTransaction::NetworkTransaction(NetworkTransaction *n) : next(n), status(released)
+NetworkTransaction *NetworkTransaction::freelist = nullptr;
+
+NetworkTransaction::NetworkTransaction(NetworkTransaction *n)
+ : next(n), fileBuffer(nullptr), sendBuffer(nullptr), sendStack(new OutputStack()), fileBeingSent(nullptr), status(TransactionStatus::released)
{
- sendStack = new OutputStack();
}
-#if 0
-void NetworkTransaction::Set(pbuf *p, ConnectionState *c, TransactionStatus s)
+void NetworkTransaction::Set(Socket *skt, TransactionStatus s)
{
- cs = c;
-// pb = readingPb = p;
+ cs = skt;
status = s;
-// inputPointer = 0;
- sendBuffer = nullptr;
- fileBeingSent = nullptr;
closeRequested = false;
- nextWrite = nullptr;
- dataAcknowledged = false;
}
-#endif
bool NetworkTransaction::HasMoreDataToRead() const
{
- //TODO
- return false;
+ return cs != nullptr && cs->HasMoreDataToRead();
}
bool NetworkTransaction::IsConnected() const
{
- return (cs != nullptr && cs->IsConnected());
+ return cs != nullptr && cs->IsConnected();
+}
+
+bool NetworkTransaction::IsSending() const
+{
+ return status == TransactionStatus::sending || status == TransactionStatus::finished;
}
bool NetworkTransaction::CanWrite() const
{
- return (IsConnected() && status != released);
+ return status != TransactionStatus::released && cs != nullptr && cs->CanWrite();
}
// Read one char from the NetworkTransaction
@@ -63,30 +64,7 @@ bool NetworkTransaction::Read(char& b)
// Read data from the NetworkTransaction and return true on success
bool NetworkTransaction::ReadBuffer(const char *&buffer, size_t &len)
{
-#if 1
- return false;
-#else
- if (readingPb == nullptr)
- {
- return false;
- }
-
- if (inputPointer >= readingPb->len)
- {
- readingPb = readingPb->next;
- inputPointer = 0;
- if (readingPb == nullptr)
- {
- return false;
- }
- }
-
- buffer = (const char*)readingPb->payload + inputPointer;
- len = readingPb->len - inputPointer;
- readingPb = readingPb->next;
- inputPointer = 0;
- return true;
-#endif
+ return cs != NoConnection && cs->ReadBuffer(buffer, len);
}
void NetworkTransaction::Write(char b)
@@ -182,211 +160,86 @@ void NetworkTransaction::SetFileToWrite(FileStore *file)
}
else if (file != nullptr)
{
+ debugPrintf("Want to write file but can't write\n");
file->Close();
}
}
-// Send exactly one TCP window of data and return true when this transaction can be released
-bool NetworkTransaction::Send()
+// Get some data to send up to the specified length, which must be nonzero.
+// A null return means there is nothing left to send or we couldn't allocate a buffer.
+// If there was nothing left to send then the status is changed to 'finished'.
+const uint8_t *NetworkTransaction::GetDataToSend(size_t& length)
{
-#if 1
- return true;
-#else
- // Free up this transaction if the connection is supposed to be closed
- if (closeRequested)
+ // Discard any empty output buffers
+ while (sendBuffer != nullptr && sendBuffer->BytesLeft() == 0)
{
- reprap.GetNetwork()->ConnectionClosed(cs, true); // This will release the transaction too
- return false;
+ sendBuffer = OutputBuffer::Release(sendBuffer);
+ if (sendBuffer == nullptr)
+ {
+ sendBuffer = sendStack->Pop();
+ }
}
- // Fill up the TCP window with some data chunks from our OutputBuffer instances
- size_t bytesBeingSent = 0, bytesLeftToSend = TCP_WND;
- while (sendBuffer != nullptr && bytesLeftToSend > 0)
+ // If we have an output buffer, send it
+ if (sendBuffer != nullptr)
{
- size_t copyLength = min<size_t>(bytesLeftToSend, sendBuffer->BytesLeft());
- memcpy(sendingWindow + bytesBeingSent, sendBuffer->Read(copyLength), copyLength);
- bytesBeingSent += copyLength;
- bytesLeftToSend -= copyLength;
-
- if (sendBuffer->BytesLeft() == 0)
+ if (length > sendBuffer->BytesLeft())
{
- sendBuffer = OutputBuffer::Release(sendBuffer);
- if (sendBuffer == nullptr)
- {
- sendBuffer = sendStack->Pop();
- }
+ length = sendBuffer->BytesLeft();
}
+ return reinterpret_cast<const uint8_t*>(sendBuffer->Read(length));
}
- // We also intend to send a file, so check if we can fill up the TCP window
- if (sendBuffer == nullptr && bytesLeftToSend != 0 && fileBeingSent != nullptr)
+ // If we have a file to send, send it
+ if (fileBeingSent != nullptr && fileBuffer == nullptr)
{
- // For HSMCI efficiency, read from the file in multiples of 4 bytes except at the end.
- // This ensures that the second and subsequent chunks can be DMA'd directly into sendingWindow.
- size_t bytesToRead = bytesLeftToSend & (~3);
- if (bytesToRead != 0)
+ fileBuffer = NetworkBuffer::Allocate();
+ if (fileBuffer == nullptr)
{
- int bytesRead = fileBeingSent->Read(sendingWindow + bytesBeingSent, bytesToRead);
- if (bytesRead > 0)
- {
- bytesBeingSent += bytesRead;
- }
+ return nullptr; // no buffer available
+ }
+ }
- if (bytesRead != (int)bytesToRead)
+ // If we have a file buffer here, we must be in the process of sending a file
+ if (fileBuffer != nullptr)
+ {
+ if (fileBuffer->IsEmpty() && fileBeingSent != nullptr)
+ {
+ const int bytesRead = fileBuffer->ReadFromFile(fileBeingSent);
+ if (bytesRead != (int)NetworkBuffer::bufferSize)
{
fileBeingSent->Close();
fileBeingSent = nullptr;
}
}
- }
- if (bytesBeingSent == 0)
- {
- // If we have no data to send, this connection can be closed next time
- if (!cs->persistConnection && nextWrite == nullptr)
+ if (!fileBuffer->IsEmpty())
{
- Close();
- return false;
+ if (length > fileBuffer->Remaining())
+ {
+ length = fileBuffer->Remaining();
+ }
+ return fileBuffer->TakeData(length);
}
- // We want to send data from another transaction as well, so only free up this one
- cs->sendingTransaction = nextWrite;
- return true;
- }
-
- // The TCP window has been filled up as much as possible, so send it now. There is no need to check
- // the available space in the SNDBUF queue, because we really write only one TCP window at once.
- writeResult = tcp_write(cs->pcb, sendingWindow, bytesBeingSent, 0);
- if (ERR_IS_FATAL(writeResult))
- {
- reprap.GetPlatform()->MessageF(HOST_MESSAGE, "Network: Failed to write data in Send (code %d)\n", writeResult);
- tcp_abort(cs->pcb);
- return false;
- }
-
- outputResult = tcp_output(cs->pcb);
- if (ERR_IS_FATAL(outputResult))
- {
- reprap.GetPlatform()->MessageF(HOST_MESSAGE, "Network: Failed to output data in Send (code %d)\n", outputResult);
- tcp_abort(cs->pcb);
- return false;
- }
-
- if (outputResult != ERR_OK && reprap.Debug(moduleNetwork))
- {
- reprap.GetPlatform()->MessageF(HOST_MESSAGE, "Network: tcp_output resulted in error code %d\n", outputResult);
+ fileBuffer->Release();
+ fileBuffer = nullptr;
}
- // Set LwIP callbacks for ACK and retransmission handling
- tcp_poll(cs->pcb, conn_poll, TCP_WRITE_TIMEOUT / TCP_SLOW_INTERVAL / TCP_MAX_SEND_RETRIES);
- tcp_sent(cs->pcb, conn_sent);
-
- // Set all values for the send process
- sendingConnection = cs;
- sendingRetries = 0;
- sendingWindowSize = sentDataOutstanding = bytesBeingSent;
- return false;
-#endif
+ status = TransactionStatus::finished;
+ return nullptr;
}
// This is called by the Webserver to send output data to a client. If keepConnectionAlive is set to false,
// the current connection will be terminated once everything has been sent.
void NetworkTransaction::Commit(bool keepConnectionAlive)
{
-#if 0
- // If the connection has been terminated (e.g. RST received while writing upload data), discard this transaction
- if (!IsConnected() || status == released)
- {
- Discard();
- return;
- }
-
- // Free buffer holding the incoming data and prepare some values for the sending process
- FreePbuf();
- cs->persistConnection = keepConnectionAlive;
- if (sendBuffer == nullptr)
- {
- sendBuffer = sendStack->Pop();
- }
- status = sending;
-
- // Unlink the item(s) from the list of ready transactions
- if (keepConnectionAlive)
- {
- // Our connection is still of interest, remove only this transaction from the list
- NetworkTransaction *previous = nullptr;
- for(NetworkTransaction *item = reprap.GetNetwork()->readyTransactions; item != nullptr; item = item->next)
- {
- if (item == this)
- {
- if (previous == nullptr)
- {
- reprap.GetNetwork()->readyTransactions = next;
- }
- else
- {
- previous->next = next;
- }
- break;
- }
- previous = item;
- }
- }
- else
- {
- // We will close this connection soon, stop receiving data from this PCB
- tcp_recv(cs->pcb, nullptr);
-
- // Also remove all ready transactions pointing to our ConnectionState
- NetworkTransaction *previous = nullptr, *item = reprap.GetNetwork()->readyTransactions;
- while (item != nullptr)
- {
- if (item->cs == cs)
- {
- if (item == this)
- {
- // Only unlink this item
- if (previous == nullptr)
- {
- reprap.GetNetwork()->readyTransactions = next;
- }
- else
- {
- previous->next = next;
- }
- item = next;
- }
- else
- {
- // Remove all others
- item->Discard();
- item = (previous == nullptr) ? reprap.GetNetwork()->readyTransactions : previous->next;
- }
- }
- else
- {
- previous = item;
- item = item->next;
- }
- }
- }
-
- // Enqueue this transaction, so it's sent in the right order
- NetworkTransaction *mySendingTransaction = cs->sendingTransaction;
- if (mySendingTransaction == nullptr)
+ closeAfterSending = !keepConnectionAlive;
+ status = TransactionStatus::sending;
+ if (closeAfterSending)
{
- cs->sendingTransaction = this;
- reprap.GetNetwork()->AppendTransaction(&reprap.GetNetwork()->writingTransactions, this);
+ cs->DiscardReceivedData();
}
- else
- {
- while (mySendingTransaction->nextWrite != nullptr)
- {
- mySendingTransaction = mySendingTransaction->nextWrite;
- }
- mySendingTransaction->nextWrite = this;
- }
-#endif
}
// Call this to perform some networking tasks while processing deferred requests,
@@ -397,141 +250,25 @@ void NetworkTransaction::Commit(bool keepConnectionAlive)
// This will ensure that zero-window packets are sent back to the client
// 2) ResetData: Reset the read pointers and acknowledge that the data has been processed
// 3) DiscardData: Free the processed data, acknowledge it and append this transaction as
-// an empty item again without payload (i.e. without pbufs)
+// an empty item again without payload
//
void NetworkTransaction::Defer(DeferralMode mode)
{
-#if 0
- if (mode == DeferralMode::ResetData)
- {
- // Reset the reading pointers and send an ACK
- inputPointer = 0;
- readingPb = pb;
- if (IsConnected() && pb != nullptr && !dataAcknowledged)
- {
- tcp_recved(cs->pcb, pb->tot_len);
- dataAcknowledged = true;
- }
- }
- else if (mode == DeferralMode::DiscardData)
+ if (mode == DeferralMode::DiscardData)
{
- // Discard the incoming data, because we don't need to process it any more
- FreePbuf();
+ cs->DiscardReceivedData(); // discard the incoming data, because we don't need to process it any more
}
- status = deferred;
-
- // Unlink this transaction from the list of ready transactions and append it again
- Network *network = reprap.GetNetwork();
- NetworkTransaction *item, *previous = nullptr;
- for(item = network->readyTransactions; item != nullptr; item = item->next)
- {
- if (item == this)
- {
- if (previous == nullptr)
- {
- network->readyTransactions = next;
- }
- else
- {
- previous->next = next;
- }
- break;
- }
- previous = item;
- }
- network->AppendTransaction(&network->readyTransactions, this);
-
- // Append all other transactions that are associated to this connection, so that the
- // Webserver gets a chance to deal with all connected clients even while multiple
- // deferred requests are present in the list.
- item = network->readyTransactions;
- previous = nullptr;
- while (item != this)
- {
- if (item->cs == cs)
- {
- NetworkTransaction *nextItem = item->next;
- if (previous == nullptr)
- {
- network->readyTransactions = item->next;
- network->AppendTransaction(&network->readyTransactions, item);
- }
- else
- {
- previous->next = item->next;
- network->AppendTransaction(&network->readyTransactions, item);
- }
- item = nextItem;
- }
- else
- {
- previous = item;
- item = item->next;
- }
- }
-#endif
+ status = TransactionStatus::deferred;
+ reprap.GetNetwork()->Defer(this);
}
-
// This method should be called if we don't want to send data to the client and if we
// don't want to interfere with the connection state. May also be called from ISR!
void NetworkTransaction::Discard()
{
-#if 0
- // Can we do anything?
- if (status == released)
- {
- // No - don't free up released items multiple times
- return;
- }
-
- // Free up some resources
- FreePbuf();
-
- if (fileBeingSent != nullptr)
- {
- fileBeingSent->Close();
- fileBeingSent = nullptr;
- }
-
- OutputBuffer::ReleaseAll(sendBuffer);
- sendStack->ReleaseAll();
-
- // Unlink this transactions from the list of ready transactions and free it. It is then appended to the list of
- // free transactions because we don't want to risk reusing it when the ethernet ISR processes incoming data
- NetworkTransaction *previous = nullptr;
- for(NetworkTransaction *item = reprap.GetNetwork()->readyTransactions; item != nullptr; item = item->next)
- {
- if (item == this)
- {
- if (previous == nullptr)
- {
- reprap.GetNetwork()->readyTransactions = next;
- }
- else
- {
- previous->next = next;
- }
- break;
- }
- previous = item;
- }
- reprap.GetNetwork()->AppendTransaction(&reprap.GetNetwork()->freeTransactions, this);
- bool callDisconnectHandler = (cs != nullptr && status == disconnected);
- status = released;
-
- // Call disconnect event if this transaction indicates a graceful disconnect and if the connection
- // still persists (may not be the case if a RST packet was received before)
- if (callDisconnectHandler)
- {
- if (reprap.Debug(moduleNetwork))
- {
- reprap.GetPlatform()->Message(HOST_MESSAGE, "Network: Discard() is handling a graceful disconnect\n");
- }
- reprap.GetNetwork()->ConnectionClosed(cs, false);
- }
-#endif
+ status = TransactionStatus::finished;
+ cs->ReleaseTransaction();
}
uint32_t NetworkTransaction::GetRemoteIP() const
@@ -539,23 +276,64 @@ uint32_t NetworkTransaction::GetRemoteIP() const
return (cs != nullptr) ? cs->GetRemoteIP() : 0;
}
-uint16_t NetworkTransaction::GetRemotePort() const
+Port NetworkTransaction::GetRemotePort() const
{
return (cs != nullptr) ? cs->GetRemotePort() : 0;
}
-uint16_t NetworkTransaction::GetLocalPort() const
+Port NetworkTransaction::GetLocalPort() const
{
return (cs != nullptr) ? cs->GetLocalPort() : 0;
}
-void NetworkTransaction::Close()
+// Create the specified number of buffers and put them on the freelist
+/*static*/ void NetworkTransaction::AllocateTransactions(unsigned int number)
+{
+ if (freelist == nullptr)
+ {
+ while (number != 0)
+ {
+ freelist = new NetworkTransaction(freelist);
+ --number;
+ }
+ }
+}
+
+// Allocate a buffer from the freelist
+/*static*/ NetworkTransaction *NetworkTransaction::Allocate()
{
-#if 0
- tcp_pcb *pcb = cs->pcb;
- tcp_recv(pcb, nullptr);
- closeRequested = true;
-#endif
+ NetworkTransaction *ret = freelist;
+ if (ret != nullptr)
+ {
+ freelist = ret->next;
+ ret->next = nullptr;
+ ret->fileBuffer = nullptr;
+ ret->fileBeingSent = nullptr;
+ }
+ return ret;
+}
+
+// Free resources and recycle this buffer
+NetworkTransaction *NetworkTransaction::Release()
+{
+ if (fileBuffer != nullptr)
+ {
+ fileBuffer->Release();
+ fileBuffer = nullptr;
+ }
+ if (fileBeingSent != nullptr)
+ {
+ fileBeingSent->Close();
+ fileBeingSent = nullptr;
+ }
+
+ OutputBuffer::ReleaseAll(sendBuffer);
+ sendStack->ReleaseAll();
+
+ NetworkTransaction *ret = next;
+ next = freelist;
+ freelist = this;
+ return ret;
}
// End
diff --git a/src/DuetNG/DuetEthernet/NetworkTransaction.h b/src/DuetNG/DuetEthernet/NetworkTransaction.h
index 93ddc725..0dd5c3cc 100644
--- a/src/DuetNG/DuetEthernet/NetworkTransaction.h
+++ b/src/DuetNG/DuetEthernet/NetworkTransaction.h
@@ -17,7 +17,7 @@
#include "NetworkBuffer.h"
// Assign a status to each NetworkTransaction
-enum TransactionStatus
+enum class TransactionStatus
{
released,
connected,
@@ -25,7 +25,8 @@ enum TransactionStatus
sending,
disconnected,
deferred,
- acquired
+ acquired,
+ finished
};
// How is a deferred request supposed to be handled?
@@ -41,14 +42,13 @@ enum class DeferralMode
class NetworkTransaction
{
public:
- friend class Network;
-
NetworkTransaction(NetworkTransaction* n);
-// void Set(pbuf *p, ConnectionState* c, TransactionStatus s);
+ void Set(Socket *skt, TransactionStatus s);
TransactionStatus GetStatus() const { return status; }
bool IsConnected() const;
+ bool IsSending() const;
- bool HasMoreDataToRead() const; // { return readingPb != nullptr; }
+ bool HasMoreDataToRead() const;
bool Read(char& b);
bool ReadBuffer(const char *&buffer, size_t &len);
void Write(char b);
@@ -65,30 +65,31 @@ public:
uint32_t GetRemoteIP() const;
Port GetRemotePort() const;
- bool Send();
+ const uint8_t *GetDataToSend(size_t& length);
void Commit(bool keepConnectionAlive);
void Defer(DeferralMode mode);
void Discard();
+ NetworkTransaction *Release();
- NetworkTransaction *GetNext() const { return next; }
- NetworkTransaction *GetNextWrite() const { return nextWrite; }
+ static void AllocateTransactions(unsigned int number);
+ static NetworkTransaction *Allocate();
private:
bool CanWrite() const;
- void Close();
- Socket* cs; // the network socket that this transaction cam from
+ static NetworkTransaction *freelist;
+
+ Socket* cs; // the network socket that this transaction came from
NetworkTransaction* next; // next NetworkTransaction in the list we are in
- NetworkTransaction* nextWrite; // next NetworkTransaction queued to write to assigned connection
-// NetworkBuffer *pb, *readingPb; // received packet queue and a pointer to the pbuf being read from
-// size_t inputPointer; // amount of data already taken from the first packet buffer
+ NetworkBuffer *fileBuffer; // buffer holding the file chunk we are writing
OutputBuffer *sendBuffer;
OutputStack *sendStack;
- FileStore * volatile fileBeingSent;
+ FileStore *fileBeingSent;
- /*volatile*/ TransactionStatus status;
- /*volatile*/ bool closeRequested, dataAcknowledged;
+ TransactionStatus status;
+ bool closeAfterSending;
+ bool closeRequested;
};
#endif /* SRC_DUETNG_DUETETHERNET_NETWORKTRANSACTION_H_ */
diff --git a/src/DuetNG/DuetEthernet/Socket.cpp b/src/DuetNG/DuetEthernet/Socket.cpp
index 7bfff537..9624c56e 100644
--- a/src/DuetNG/DuetEthernet/Socket.cpp
+++ b/src/DuetNG/DuetEthernet/Socket.cpp
@@ -6,14 +6,15 @@
*/
#include "Socket.h"
+
#include "NetworkTransaction.h"
#include "NetworkBuffer.h"
-#include <socketlib.h>
+#include "socketlib.h"
//***************************************************************************************************
// Socket class
-Socket::Socket() : receivedData(nullptr), sendingTransaction(nullptr)
+Socket::Socket() : currentTransaction(nullptr), receivedData(nullptr)
{
}
@@ -27,29 +28,41 @@ void Socket::Init(SocketNumber skt, Port serverPort)
void Socket::ReInit()
{
- // Discard any transactions that were queued to send
- NetworkTransaction *st;
- while ((st = sendingTransaction) != nullptr)
- {
- sendingTransaction = st->GetNext();
- st->Discard();
- }
-
// Discard any received data
while (receivedData != nullptr)
{
receivedData = receivedData->Release();
}
+ ReleaseTransaction();
persistConnection = true;
isTerminated = false;
+ isSending = false;
state = SocketState::inactive;
// Re-initialise the socket on the W5500
+//debugPrintf("About to initialise socket %u\n", socketNum);
socket(socketNum, Sn_MR_TCP, localPort, 0x00);
+//debugPrintf("Initialised socket %u\n", socketNum);
+}
+
+// Close a connection when the last packet has been sent
+void Socket::Close()
+{
+ disconnectNoWait(socketNum);
+}
+
+// Release the current transaction
+void Socket::ReleaseTransaction()
+{
+ if (currentTransaction != nullptr)
+ {
+ currentTransaction->Release();
+ currentTransaction = nullptr;
+ }
}
-// Terminate a connection
+// Terminate a connection immediately
void Socket::Terminate()
{
disconnectNoWait(socketNum);
@@ -59,17 +72,43 @@ void Socket::Terminate()
{
receivedData = receivedData->Release();
}
+ ReleaseTransaction();
}
// Test whether we have a connection on this socket
bool Socket::IsConnected() const
{
- return getSn_SR(socketNum) == SOCK_ESTABLISHED; //TODO is this right?
+ const uint8_t stat = getSn_SR(socketNum);
+ return stat == SOCK_ESTABLISHED || stat == SOCK_CLOSE_WAIT;
+}
+
+// Return true if there is or may soon be more data to read
+bool Socket::HasMoreDataToRead() const
+{
+ return (receivedData != nullptr && receivedData->TotalRemaining() != 0) // already have more data
+ || getSn_SR(socketNum) == SOCK_ESTABLISHED; // still fully connected, so we may receive more
+}
+
+bool Socket::CanWrite() const
+{
+ const uint8_t stat = getSn_SR(socketNum);
+ return stat == SOCK_ESTABLISHED || stat == SOCK_CLOSE_WAIT;
+}
+
+// Return true if we are in the sending phase
+bool Socket::IsSending() const
+{
+ return currentTransaction != nullptr && currentTransaction->IsSending();
}
// Read 1 character from the receive buffers, returning true if successful
bool Socket::ReadChar(char& c)
{
+ while (receivedData != nullptr && receivedData->IsEmpty())
+ {
+ receivedData = receivedData->Release(); // discard empty buffer at head of chain
+ }
+
if (receivedData == nullptr)
{
c = 0;
@@ -84,8 +123,27 @@ bool Socket::ReadChar(char& c)
return ret;
}
+// Return a pointer to data in a buffer and a length available, and mark the data as taken
+bool Socket::ReadBuffer(const char *&buffer, size_t &len)
+{
+ while (receivedData != nullptr && receivedData->IsEmpty())
+ {
+ receivedData = receivedData->Release(); // discard empty buffer at head of chain
+ }
+
+ if (receivedData == nullptr)
+ {
+ return false;
+ }
+
+ len = 2048; // initial value passed to TakeData is the maximum amount we will take
+ buffer = reinterpret_cast<const char*>(receivedData->TakeData(len));
+// debugPrintf("Taking %d bytes\n", len);
+ return true;
+}
+
// Poll a socket to see if it needs to be serviced
-void Socket::Poll()
+void Socket::Poll(bool full)
{
switch(getSn_SR(socketNum))
{
@@ -93,7 +151,7 @@ void Socket::Poll()
// Socket has been initialised but is not listening yet
if (localPort != 0) // localPort for the FTP data socket is 0 until we have decided what port number to use
{
- listen(socketNum);
+ ExecCommand(socketNum, Sn_CR_LISTEN);
}
break;
@@ -114,32 +172,57 @@ void Socket::Poll()
const uint16_t len = getSn_RX_RSR(socketNum);
if (len != 0)
{
+// debugPrintf("%u available\n", len);
// There is data available, so allocate a buffer
NetworkBuffer * const buf = NetworkBuffer::Allocate();
if (buf != nullptr)
{
- buf->dataLength = recv(socketNum, buf->data, min<size_t>(len, NetworkBuffer::bufferSize));
- buf->readPointer = 0;
- // Append the buffer to the list of receive buffers
- NetworkBuffer** bufp = &receivedData;
- while (*bufp != nullptr)
+ const int32_t ret = recv(socketNum, buf->Data(), min<size_t>(len, NetworkBuffer::bufferSize));
+// debugPrintf("ret %d\n", ret);
+ if (ret > 0)
+ {
+ buf->dataLength = (size_t)ret;
+ buf->readPointer = 0;
+ NetworkBuffer::AppendToList(&receivedData, buf);
+ }
+ else
{
- bufp = &((*bufp)->next);
+ buf->Release();
+// debugPrintf("Bad receive, code = %d\n", ret);
}
- *bufp = buf;
+ }
+ else debugPrintf("no buffer\n");
+ }
+
+ if (receivedData != nullptr && currentTransaction == nullptr)
+ {
+ currentTransaction = NetworkTransaction::Allocate();
+ if (currentTransaction != nullptr)
+ {
+ currentTransaction->Set(this, TransactionStatus::receiving);
}
}
}
- // See if we can send any data
- //TODO
+ // See if we can send any data.
+ // Currently we don't send if we are being called from hsmci because we don't want to risk releasing a buffer that we may be reading data into.
+ // We could use a buffer locking mechanism instead. However, the speed of sending is not critical, so we don't do that yet.
+ if (full && IsSending() && TrySendData())
+ {
+ ReleaseTransaction();
+ ExecCommand(socketNum, Sn_CR_DISCON);
+ }
break;
case SOCK_CLOSE_WAIT: // A client has asked to disconnect
#ifdef _HTTPSERVER_DEBUG_
printf("> HTTPSocket[%d] : ClOSE_WAIT\r\n", socketNum);
#endif
- disconnect(socketNum);
+ if (!IsSending() || TrySendData())
+ {
+ ReleaseTransaction();
+ ExecCommand(socketNum, Sn_CR_DISCON);
+ }
break;
case SOCK_CLOSED:
@@ -163,4 +246,76 @@ void Socket::Poll()
#endif
}
+// Try to send data, returning true if all data has been sent and we ought to close the socket
+// We have already checked that the socket is in the ESTABLISHED or CLOSE_WAIT state.
+bool Socket::TrySendData()
+{
+ if (isSending) // are we already sending?
+ {
+ const uint8_t tmp = getSn_IR(socketNum);
+ if (tmp & Sn_IR_SENDOK) // did the previous send complete?
+ {
+ setSn_IR(socketNum, Sn_IR_SENDOK); // if yes
+ isSending = false;
+ }
+ else if(tmp & Sn_IR_TIMEOUT) // did it time out?
+ {
+ isSending = false;
+ disconnectNoWait(socketNum); // if so, close the socket
+ return true; // and release buffers etc.
+ }
+ else
+ {
+ //debugPrintf("Waiting for data to be sent\n");
+ return false; // last send is still in progress
+ }
+ }
+
+ // Socket is free to send
+ if (currentTransaction->GetStatus() == TransactionStatus::finished)
+ {
+ return true;
+ }
+
+ size_t freesize = (size_t)getSn_TX_FSR(socketNum);
+ uint16_t ptr = getSn_TX_WR(socketNum);
+ bool sent = false;
+ while (freesize != 0)
+ {
+ size_t length = freesize;
+ const uint8_t *data = currentTransaction->GetDataToSend(length);
+ if (data == nullptr)
+ {
+ break; // no more data or can't allocate a file buffer
+ }
+ //debugPrintf("rp=%04x tp=%04x\n", getSn_TX_RD(socketNum), getSn_TX_WR(socketNum));
+ wiz_send_data_at(socketNum, data, length, ptr);
+ //debugPrintf("Wrote %u bytes of %u free, %02x %02x %02x\n", length, freesize, data[0], data[1], data[2]);
+ freesize -= length;
+ ptr += (uint16_t)length;
+ sent = true;
+ }
+ if (sent)
+ {
+ //debugPrintf("Sending data, rp=%04x tp=%04x\n", getSn_TX_RD(socketNum), getSn_TX_WR(socketNum));
+ ExecCommand(socketNum, Sn_CR_SEND);
+ isSending = true;
+ }
+ else if (currentTransaction->GetStatus() == TransactionStatus::finished)
+ {
+ return true; // there was no more data to send
+ }
+
+ return false;
+}
+
+// Discard any received data for this transaction
+void Socket::DiscardReceivedData()
+{
+ while (receivedData != nullptr)
+ {
+ receivedData = receivedData->Release();
+ }
+}
+
// End
diff --git a/src/DuetNG/DuetEthernet/Socket.h b/src/DuetNG/DuetEthernet/Socket.h
index 59f04906..7c6ef596 100644
--- a/src/DuetNG/DuetEthernet/Socket.h
+++ b/src/DuetNG/DuetEthernet/Socket.h
@@ -8,9 +8,8 @@
#ifndef SRC_DUETNG_DUETETHERNET_SOCKET_H_
#define SRC_DUETNG_DUETETHERNET_SOCKET_H_
-#include <NetworkDefs.h>
-#include <cstdint>
-#include <cstddef>
+#include "RepRapFirmware.h"
+#include "NetworkDefs.h"
// Socket structure that we use to track TCP connections
class Socket
@@ -18,15 +17,23 @@ class Socket
public:
Socket();
void Init(SocketNumber s, Port serverPort);
- void Poll();
+ void Poll(bool full);
Port GetLocalPort() const { return localPort; }
uint32_t GetRemoteIP() const { return remoteIPAddress; }
Port GetRemotePort() const { return remotePort; }
bool IsConnected() const;
bool IsTerminated() const { return isTerminated; }
+ void Close();
void Terminate();
SocketNumber GetNumber() const { return socketNum; }
+ NetworkTransaction *GetTransaction() const { return currentTransaction; }
bool ReadChar(char& c);
+ bool ReadBuffer(const char *&buffer, size_t &len);
+ bool HasMoreDataToRead() const;
+ void ReleaseTransaction();
+ bool IsPersistentConnection() const { return persistConnection; }
+ bool CanWrite() const;
+ void DiscardReceivedData();
private:
enum class SocketState : uint8_t
@@ -40,15 +47,20 @@ private:
};
void ReInit();
+ bool IsSending() const; // Return true if we are in the sending phase
+
+ bool TrySendData() // Try to send data, returning true if all data has been sent and we ought to close the socket
+ pre(IsSending());
Port localPort, remotePort; // The local and remote ports
uint32_t remoteIPAddress; // The remote IP address
- NetworkBuffer *receivedData; // Chain of buffers holding received data
- NetworkTransaction * /*volatile*/ sendingTransaction; // NetworkTransaction that is currently sending via this connection
+ NetworkTransaction *currentTransaction; // The transaction currently being processed on this socket
+ NetworkBuffer *receivedData; // List of buffers holding received data
bool persistConnection; // Do we expect this connection to stay alive?
bool isTerminated; // Will be true if the connection has gone down unexpectedly (TCP RST)
SocketNumber socketNum; // The W5500 socket number we are using
SocketState state;
+ bool isSending;
};
#endif /* SRC_DUETNG_DUETETHERNET_SOCKET_H_ */
diff --git a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.cpp b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.cpp
index 3fab829e..9c7b415e 100644
--- a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.cpp
+++ b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.cpp
@@ -66,7 +66,7 @@ uint8_t WIZCHIP_READ(uint32_t AddrSel)
{
WizSpi::AssertSS();
WizSpi::SendAddress(AddrSel | (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_));
- const uint8_t ret = WizSpi::ExchangeByte(0xFF, true);
+ const uint8_t ret = WizSpi::ReadByte();
WizSpi::ReleaseSS();
return ret;
}
@@ -75,7 +75,7 @@ void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb )
{
WizSpi::AssertSS();
WizSpi::SendAddress(AddrSel | (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_));
- WizSpi::ExchangeByte(wb, true);
+ WizSpi::WriteByte(wb);
WizSpi::ReleaseSS();
}
@@ -112,7 +112,6 @@ uint16_t getSn_TX_FSR(uint8_t sn)
return val;
}
-
uint16_t getSn_RX_RSR(uint8_t sn)
{
uint16_t val = 0, val1 = 0;
@@ -134,8 +133,23 @@ void wiz_send_data(uint8_t sn, const uint8_t *wizdata, uint16_t len)
if (len != 0)
{
uint16_t ptr = getSn_TX_WR(sn);
- uint32_t addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3);
- WIZCHIP_WRITE_BUF(addrsel,wizdata, len);
+ const uint32_t addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3);
+ WIZCHIP_WRITE_BUF(addrsel, wizdata, len);
+
+ ptr += len;
+ setSn_TX_WR(sn, ptr);
+ }
+}
+
+// Function wiz_send_data doesn't work properly when we send TCP/IP data in multiple chunks,
+// because the getSn_TX_WR call doesn't read back the incremented value after we wrote to it.
+// So use this instead.
+void wiz_send_data_at(uint8_t sn, const uint8_t *wizdata, uint16_t len, uint16_t ptr)
+{
+ if (len != 0)
+ {
+ const uint32_t addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3);
+ WIZCHIP_WRITE_BUF(addrsel, wizdata, len);
ptr += len;
setSn_TX_WR(sn,ptr);
@@ -147,7 +161,7 @@ void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
if (len != 0)
{
uint16_t ptr = getSn_RX_RD(sn);
- uint32_t addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3);
+ const uint32_t addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3);
WIZCHIP_READ_BUF(addrsel, wizdata, len);
ptr += len;
diff --git a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.h b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.h
index 495772ac..805a9811 100644
--- a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.h
+++ b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.h
@@ -2268,6 +2268,9 @@ static inline uint16_t getSn_TxMAX(uint8_t sn)
*/
void wiz_send_data(uint8_t sn, const uint8_t *wizdata, uint16_t len);
+// Alternative to wiz_send_data to work around an apparent bug
+void wiz_send_data_at(uint8_t sn, const uint8_t *wizdata, uint16_t len, uint16_t ptr);
+
/**
* @ingroup Basic_IO_function
* @brief It copies data to your buffer from internal RX memory
diff --git a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/WizSpi.cpp b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/WizSpi.cpp
index c32a14a5..70ebf1d4 100644
--- a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/WizSpi.cpp
+++ b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/WizSpi.cpp
@@ -25,7 +25,7 @@
#include "matrix.h"
// Functions called by the W5500 module to transfer data to/from the W5500 via SPI
-const uint32_t SpiClockFrequency = 10000000; // use 10MHz for now, increase it later
+const uint32_t SpiClockFrequency = 40000000;
const unsigned int SpiPeripheralChannelId = 0; // we use NPCS0 as the slave select signal
#if USE_PDC
@@ -283,7 +283,7 @@ namespace WizSpi
static inline bool waitForTxReady()
{
uint32_t timeout = SPI_TIMEOUT;
- while (!spi_is_tx_ready(SPI))
+ while ((SPI->SPI_SR & SPI_SR_TDRE) == 0)
{
if (--timeout == 0)
{
@@ -297,7 +297,7 @@ namespace WizSpi
static inline bool waitForTxEmpty()
{
uint32_t timeout = SPI_TIMEOUT;
- while (!spi_is_tx_empty(SPI))
+ while ((SPI->SPI_SR & SPI_SR_TXEMPTY) == 0)
{
if (!timeout--)
{
@@ -311,7 +311,7 @@ namespace WizSpi
static inline bool waitForRxReady()
{
uint32_t timeout = SPI_TIMEOUT;
- while (!spi_is_rx_ready(SPI))
+ while ((SPI->SPI_SR & SPI_SR_RDRF) == 0)
{
if (--timeout == 0)
{
@@ -326,6 +326,7 @@ namespace WizSpi
{
spi_set_peripheral_chip_select_value(SPI, spi_get_pcs(SpiPeripheralChannelId));
digitalWrite(SamCsPin, LOW);
+ (void)SPI->SPI_RDR; // clear receive register
}
// Set the SS pin high again
@@ -335,53 +336,79 @@ namespace WizSpi
digitalWrite(SamCsPin, HIGH);
}
+ // Send the 3-byte address and control bits. On return there may be data still being received.
void SendAddress(uint32_t addr)
{
- (void)ExchangeByte((uint8_t)(addr >> 16), false);
- (void)ExchangeByte((uint8_t)(addr >> 8), false);
- (void)ExchangeByte((uint8_t)addr, false);
+ uint32_t dout = (addr >> 16) & 0x000000FF;
+ if (!waitForTxReady())
+ {
+ SPI->SPI_TDR = dout;
+ (void)SPI->SPI_RDR;
+ dout = (addr >> 8) & 0x000000FF;
+ if (!waitForTxReady())
+ {
+ SPI->SPI_TDR = dout;
+ (void)SPI->SPI_RDR;
+ dout = addr & 0x000000FF;
+ if (!waitForTxReady())
+ {
+ SPI->SPI_TDR = dout;
+ (void)SPI->SPI_RDR;
+ }
+ }
+ }
}
- uint8_t ExchangeByte(uint8_t b, bool isLast)
+ // Read a single byte. Called after sending the 3-byte address.
+ uint8_t ReadByte()
{
- if (waitForTxReady())
+ (void)SPI->SPI_RDR;
+ if (!waitForTxEmpty())
{
- return 0;
+ while ((SPI->SPI_SR & SPI_SR_RDRF) != 0)
+ {
+ (void)SPI->SPI_RDR; // clear previous data
+ }
+ SPI->SPI_TDR = 0x000000FF | SPI_TDR_LASTXFER;
+ if (!waitForRxReady())
+ {
+ return (uint8_t)SPI->SPI_RDR;
+ }
}
+ return 0;
+ }
- // Write to transmit register
- uint32_t dOut = b;
- if (isLast)
+ // Write a single byte. Called after sending the address.
+ void WriteByte(uint8_t b)
+ {
+ const uint32_t dOut = b | SPI_TDR_LASTXFER;
+ if (!waitForTxReady())
{
- dOut |= SPI_TDR_LASTXFER;
+ SPI->SPI_TDR = dOut;
}
- SPI->SPI_TDR = dOut;
+ }
- // Wait for receive register
- if (waitForRxReady())
+ spi_status_t ReadBurst(uint8_t* rx_data, size_t len)
+ {
+ if (waitForTxEmpty())
{
- return 0;
+ return SPI_ERROR_TIMEOUT;
}
- // Get data from receive register
- return (uint8_t)SPI->SPI_RDR;
- }
+ while ((SPI->SPI_SR & SPI_SR_RDRF) != 0)
+ {
+ (void)SPI->SPI_RDR; // clear previous data
+ }
- spi_status_t ReadBurst(uint8_t* rx_data, size_t len)
- {
for (size_t i = 0; i < len; ++i)
{
- uint32_t dOut = 0x000000FF;
+ const uint32_t dOut = ((i + 1) == len) ? 0x000000FF | SPI_TDR_LASTXFER : 0x000000FF;
if (waitForTxReady())
{
return SPI_ERROR_TIMEOUT;
}
// Write to transmit register
- if (i + 1 == len)
- {
- dOut |= SPI_TDR_LASTXFER;
- }
SPI->SPI_TDR = dOut;
// Wait for receive register
@@ -402,16 +429,17 @@ namespace WizSpi
for (uint32_t i = 0; i < len; ++i)
{
uint32_t dOut = (uint32_t)*tx_data++;
+ if (i + 1 == len)
+ {
+ dOut |= SPI_TDR_LASTXFER;
+ }
+
if (waitForTxReady())
{
return SPI_ERROR_TIMEOUT;
}
// Write to transmit register
- if (i + 1 == len)
- {
- dOut |= SPI_TDR_LASTXFER;
- }
SPI->SPI_TDR = dOut;
// Wait for receive register
if (waitForRxReady())
diff --git a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/WizSpi.h b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/WizSpi.h
index 2829e168..21a5eadc 100644
--- a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/WizSpi.h
+++ b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/WizSpi.h
@@ -17,7 +17,8 @@ namespace WizSpi
void AssertSS();
void ReleaseSS();
void SendAddress(uint32_t addr);
- uint8_t ExchangeByte(uint8_t b, bool isLast);
+ uint8_t ReadByte();
+ void WriteByte(uint8_t b);
spi_status_t ReadBurst(uint8_t* rx_data, size_t len);
spi_status_t SendBurst(const uint8_t* tx_data, size_t len);
}
diff --git a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/socketlib.cpp b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/socketlib.cpp
index 0ad63a22..b1d60e4b 100644
--- a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/socketlib.cpp
+++ b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/socketlib.cpp
@@ -92,7 +92,7 @@ uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,};
if(len == 0) return SOCKERR_DATALEN; \
}while(0); \
-static void ExecCommand(uint8_t sn, uint8_t cmd)
+void ExecCommand(uint8_t sn, uint8_t cmd)
{
setSn_CR(sn, cmd);
while(getSn_CR(sn) != 0) { }
@@ -207,7 +207,6 @@ int8_t listen(uint8_t sn)
return SOCK_OK;
}
-
int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port)
{
CHECK_SOCKMODE(Sn_MR_TCP);
diff --git a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/socketlib.h b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/socketlib.h
index 5cd57c57..37f4bf42 100644
--- a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/socketlib.h
+++ b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/socketlib.h
@@ -481,4 +481,7 @@ int8_t setsockopt(uint8_t sn, sockopt_type sotype, void* arg);
*/
int8_t getsockopt(uint8_t sn, sockopt_type sotype, void* arg);
+// Execute a command
+void ExecCommand(uint8_t sn, uint8_t cmd);
+
#endif // _SOCKET_H_
diff --git a/src/DuetNG/DuetWiFi/Network.cpp b/src/DuetNG/DuetWiFi/Network.cpp
index 03e8f1d3..7127433f 100644
--- a/src/DuetNG/DuetWiFi/Network.cpp
+++ b/src/DuetNG/DuetWiFi/Network.cpp
@@ -165,7 +165,7 @@ void Network::Stop()
}
}
-void Network::Spin()
+void Network::Spin(bool full)
{
// static float lastTime = 0.0;
@@ -176,14 +176,17 @@ void Network::Spin()
switch (state)
{
case starting:
- // See if the ESP8266 has set CS high yet
- if (digitalRead(SamCsPin))
+ if (full)
{
- // Setup the SPI controller in slave mode and assign the CS pin to it
- platform->Message(HOST_MESSAGE, "WiFi server starting up\n");
- SetupSpi(); // set up the SPI subsystem
- state = idle;
- TryStartTransfer();
+ // See if the ESP8266 has set CS high yet
+ if (digitalRead(SamCsPin))
+ {
+ // Setup the SPI controller in slave mode and assign the CS pin to it
+ platform->Message(HOST_MESSAGE, "WiFi server starting up\n");
+ SetupSpi(); // set up the SPI subsystem
+ state = idle;
+ TryStartTransfer();
+ }
}
break;
@@ -242,7 +245,7 @@ void Network::Spin()
state = sending;
// no break
case sending:
- if (outBuffer.IsEmpty())
+ if (full && outBuffer.IsEmpty())
{
// See if we have more of the current response to send
if (responseBody != nullptr)
@@ -368,7 +371,10 @@ void Network::Spin()
break;
case disabled:
- uploader->Spin();
+ if (full)
+ {
+ uploader->Spin();
+ }
break;
default:
diff --git a/src/DuetNG/DuetWiFi/Network.h b/src/DuetNG/DuetWiFi/Network.h
index 3258c34a..66963776 100644
--- a/src/DuetNG/DuetWiFi/Network.h
+++ b/src/DuetNG/DuetWiFi/Network.h
@@ -49,7 +49,7 @@ public:
void Init();
void Activate();
void Exit();
- void Spin();
+ void Spin(bool full);
void SpiInterrupt();
void Diagnostics(MessageType mtype);
void Start();
diff --git a/src/DuetNG/Pins_DuetNG.h b/src/DuetNG/Pins_DuetNG.h
index b01c8099..8294ea12 100644
--- a/src/DuetNG/Pins_DuetNG.h
+++ b/src/DuetNG/Pins_DuetNG.h
@@ -2,23 +2,27 @@
#define PINS_DUETNG_H__
#if defined(DUET_WIFI)
+
# define FIRMWARE_NAME "RepRapFirmware for Duet WiFi"
+# define DEFAULT_BOARD_TYPE BoardType::DuetWiFi_10
+const size_t NumFirmwareUpdateModules = 4; // 3 modules, plus one for manual upload to WiFi module
+# define IAP_FIRMWARE_FILE "DuetWiFiFirmware.bin"
+# define WIFI_FIRMWARE_FILE "DuetWiFiServer.bin"
+# define WIFI_WEB_FILE "DuetWebControl.bin"
+
#elif defined(DUET_ETHERNET)
+
# define FIRMWARE_NAME "RepRapFirmware for Duet Ethernet"
+# define DEFAULT_BOARD_TYPE BoardType::DuetEthernet_10
+# define IAP_FIRMWARE_FILE "DuetEthernetFirmware.bin"
+const size_t NumFirmwareUpdateModules = 1; // 1 module
+
#else
# error Firmware name not defined
#endif
-const size_t NumFirmwareUpdateModules = 4; // 3 modules, plus one for manual upload to WiFi module
-#define IAP_UPDATE_FILE "iap4e.bin"
-#define IAP_FIRMWARE_FILE "DuetWiFiFirmware.bin"
-#define WIFI_FIRMWARE_FILE "DuetWiFiServer.bin"
-#define WIFI_WEB_FILE "DuetWebControl.bin"
-
-// Default board type
-#define DEFAULT_BOARD_TYPE BoardType::DuetWiFi_10
+#define IAP_UPDATE_FILE "iap4e.bin" // hoping eventually to use the same IAP file for both Duet WiFi and Duet Ethernet
-#define SUPPORT_ETHERNET 0 // set nonzero to support embedded web interface over Ethernet
#define SUPPORT_INKJET 0 // set nonzero to support inkjet control
#define SUPPORT_ROLAND 0 // set nonzero to support Roland mill
diff --git a/src/GCodes/GCodeBuffer.cpp b/src/GCodes/GCodeBuffer.cpp
index fcc8d3a1..1db905bb 100644
--- a/src/GCodes/GCodeBuffer.cpp
+++ b/src/GCodes/GCodeBuffer.cpp
@@ -401,6 +401,7 @@ bool GCodeBuffer::PushState()
ms->drivesRelative = machineState->drivesRelative;
ms->axesRelative = machineState->axesRelative;
ms->doingFileMacro = machineState->doingFileMacro;
+ ms->fileState.CopyFrom(machineState->fileState);
ms->lockedResources = machineState->lockedResources;
machineState = ms;
return true;
diff --git a/src/GCodes/GCodeMachineState.cpp b/src/GCodes/GCodeMachineState.cpp
index 55475680..e21cddfb 100644
--- a/src/GCodes/GCodeMachineState.cpp
+++ b/src/GCodes/GCodeMachineState.cpp
@@ -12,7 +12,7 @@ unsigned int GCodeMachineState::numAllocated = 0;
// Create a default initialised GCodeMachineState
GCodeMachineState::GCodeMachineState()
- : previous(nullptr), feedrate(DEFAULT_FEEDRATE/minutesToSeconds), fileState(), lockedResources(0), state(GCodeState::normal),
+ : previous(nullptr), feedrate(DefaultFeedrate * secondsToMinutes), fileState(), lockedResources(0), state(GCodeState::normal),
drivesRelative(false), axesRelative(false), doingFileMacro(false), runningM502(false)
{
}
diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp
index fe84e7f3..1023b08a 100644
--- a/src/GCodes/GCodes.cpp
+++ b/src/GCodes/GCodes.cpp
@@ -55,7 +55,7 @@ void GCodes::RestorePoint::Init()
{
moveCoords[i] = 0.0;
}
- feedRate = DEFAULT_FEEDRATE/minutesToSeconds;
+ feedRate = DefaultFeedrate/minutesToSeconds;
}
GCodes::GCodes(Platform* p, Webserver* w) :
@@ -107,8 +107,9 @@ void GCodes::Init()
}
lastDefaultFanSpeed = 0.0;
- retractLength = retractExtra = retractHop = 0.0;
- retractSpeed = unRetractSpeed = 600.0;
+ retractLength = retractExtra = DefaultRetractLength;
+ retractHop = 0.0;
+ retractSpeed = unRetractSpeed = DefaultRetractSpeed * secondsToMinutes;
isRetracted = false;
}
@@ -332,7 +333,7 @@ void GCodes::Spin()
{
moveBuffer.coords[drive] = 0.0;
}
- moveBuffer.feedRate = DEFAULT_FEEDRATE/minutesToSeconds; // ask for a good feed rate, we may have paused during a slow move
+ moveBuffer.feedRate = DefaultFeedrate/minutesToSeconds; // ask for a good feed rate, we may have paused during a slow move
moveBuffer.moveType = 0;
moveBuffer.endStopsToCheck = 0;
moveBuffer.usePressureAdvance = false;
@@ -926,7 +927,7 @@ bool GCodes::LockMovementAndWaitForStandstill(const GCodeBuffer& gb)
// Save (some of) the state of the machine for recovery in the future.
bool GCodes::Push(GCodeBuffer& gb)
{
- bool ok = gb.PushState();
+ const bool ok = gb.PushState();
if (!ok)
{
platform->Message(GENERIC_MESSAGE, "Push(): stack overflow!\n");
@@ -1488,7 +1489,7 @@ bool GCodes::OffsetAxes(GCodeBuffer& gb)
}
else
{
- cannedFeedRate = DEFAULT_FEEDRATE;
+ cannedFeedRate = DefaultFeedrate;
}
offSetSet = true;
@@ -3035,8 +3036,8 @@ bool GCodes::RetractFilament(GCodeBuffer& gb, bool retract)
// Set the feed rate. If there is any Z hop then we need to pass the Z speed, else we pass the extrusion speed.
const float speedToUse = (retract) ? retractSpeed : unRetractSpeed;
moveBuffer.feedRate = (retractHop == 0.0)
- ? speedToUse * secondsToMinutes
- : speedToUse * secondsToMinutes * retractHop/retractLength;
+ ? speedToUse
+ : speedToUse * retractHop/retractLength;
moveBuffer.coords[Z_AXIS] += (retract) ? retractHop : -retractHop;
const float lengthToUse = (retract) ? -retractLength : retractLength + retractExtra;
for (size_t i = 0; i < nDrives; ++i)
diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp
index cce862fe..e8a9131d 100644
--- a/src/GCodes/GCodes2.cpp
+++ b/src/GCodes/GCodes2.cpp
@@ -1603,19 +1603,19 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
retractLength = max<float>(gb.GetFValue(), 0.0);
seen = true;
}
- if (gb.Seen('R'))
+ if (gb.Seen('R')) // must do this one after 'S'
{
retractExtra = max<float>(gb.GetFValue(), -retractLength);
seen = true;
}
if (gb.Seen('F'))
{
- unRetractSpeed = retractSpeed = max<float>(gb.GetFValue(), 60.0);
+ unRetractSpeed = retractSpeed = max<float>(gb.GetFValue(), 60.0) * secondsToMinutes;
seen = true;
}
if (gb.Seen('T')) // must do this one after 'F'
{
- unRetractSpeed = max<float>(gb.GetFValue(), 60.0);
+ unRetractSpeed = max<float>(gb.GetFValue(), 60.0) * secondsToMinutes;
seen = true;
}
if (gb.Seen('Z'))
@@ -1625,8 +1625,8 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
}
if (!seen)
{
- reply.printf("Retraction settings: length %.2f/%.2fmm, speed %d/%dmm/min, Z hop %.2fmm",
- retractLength, retractLength + retractExtra, (int)retractSpeed, (int)unRetractSpeed, retractHop);
+ reply.printf("Retraction/un-retraction settings: length %.2f/%.2fmm, speed %d/%dmm/min, Z hop %.2fmm",
+ retractLength, retractLength + retractExtra, (int)(retractSpeed * minutesToSeconds), (int)(unRetractSpeed * minutesToSeconds), retractHop);
}
}
break;
diff --git a/src/Platform.cpp b/src/Platform.cpp
index 9f686279..3e9cd452 100644
--- a/src/Platform.cpp
+++ b/src/Platform.cpp
@@ -2550,8 +2550,10 @@ void Platform::SetBoardType(BoardType bt)
{
if (bt == BoardType::Auto)
{
-#ifdef DUET_NG
+#if defined(DUET_NG) && defined(DUET_WIFI)
board = BoardType::DuetWiFi_10;
+#elif defined(DUET_NG) && defined(DUET_ETHERNET)
+ board = BoardType::DuetEthernet_10;
#elif defined(__RADDS__)
board = BoardType::RADDS_15;
#else
@@ -2581,8 +2583,10 @@ const char* Platform::GetElectronicsString() const
{
switch (board)
{
-#ifdef DUET_NG
+#if defined(DUET_NG) && defined(DUET_WIFI)
case BoardType::DuetWiFi_10: return "Duet WiFi 1.0";
+#elif defined(DUET_NG) && defined(DUET_ETHERNET)
+ case BoardType::DuetEthernet_10: return "Duet Ethernet 1.0";
#elif defined(__RADDS__)
case BoardType::RADDS_15: return "RADDS 1.5";
#else
@@ -2599,8 +2603,10 @@ const char* Platform::GetBoardString() const
{
switch (board)
{
-#ifdef DUET_NG
+#if defined(DUET_NG) && defined(DUET_WIFI)
case BoardType::DuetWiFi_10: return "duetwifi10";
+#elif defined(DUET_NG) && defined(DUET_ETHERNET)
+ case BoardType::DuetEthernet_10: return "duetethernet10";
#elif defined(__RADDS__)
case BoardType::RADDS_15: return "radds15";
#else
diff --git a/src/Platform.h b/src/Platform.h
index cbbd4ec2..aec4f3d0 100644
--- a/src/Platform.h
+++ b/src/Platform.h
@@ -121,8 +121,10 @@ const size_t FILE_BUFFER_SIZE = 256;
enum class BoardType : uint8_t
{
Auto = 0,
-#ifdef DUET_NG
+#if defined(DUET_NG) && defined(DUET_WIFI)
DuetWiFi_10 = 1
+#elif defined(DUET_NG) && defined(DUET_ETHERNET)
+ DuetEthernet_10 = 1
#elif defined(__RADDS__)
RADDS_15 = 1
#else
diff --git a/src/RADDS/Network.h b/src/RADDS/Network.h
index 4f91e86e..32f5ce31 100644
--- a/src/RADDS/Network.h
+++ b/src/RADDS/Network.h
@@ -19,7 +19,7 @@ public:
void Disable() const { };
void Enable() const { };
void Exit() const { }
- void Spin() const { };
+ void Spin(bool full) const { };
void Interrupt() const { };
void Diagnostics(MessageType mtype) const { };
diff --git a/src/Reprap.cpp b/src/Reprap.cpp
index 6459c801..b758e9ab 100644
--- a/src/Reprap.cpp
+++ b/src/Reprap.cpp
@@ -10,6 +10,19 @@
#include "Webserver.h"
#include "Version.h"
+#ifndef __RADDS__
+# include "sam/drivers/hsmci/hsmci.h"
+#endif
+
+// Callback function from the hsmci driver, called while it is waiting for an SD card operation to complete
+extern "C" void hsmciIdle()
+{
+ if (reprap.GetSpinningModule() != moduleNetwork) // I don't think this should ever be false because the Network module doesn't do file access, but just in case...
+ {
+ reprap.GetNetwork()->Spin(false);
+ }
+}
+
// RepRap member functions.
// Do nothing more in the constructor; put what you want in RepRap:Init()
@@ -103,6 +116,9 @@ void RepRap::Init()
}
#endif
+#ifndef __RADDS__
+ hsmci_set_idle_func(hsmciIdle);
+#endif
platform->MessageF(HOST_MESSAGE, "%s is up and running.\n", FIRMWARE_NAME);
fastLoop = FLT_MAX;
slowLoop = 0.0;
@@ -132,7 +148,7 @@ void RepRap::Spin()
spinningModule = moduleNetwork;
ticksInSpinState = 0;
- network->Spin();
+ network->Spin(true);
spinningModule = moduleWebserver;
ticksInSpinState = 0;
diff --git a/src/Version.h b/src/Version.h
index 5f7a3706..98641268 100644
--- a/src/Version.h
+++ b/src/Version.h
@@ -13,7 +13,7 @@
#endif
#ifndef DATE
-# define DATE "2016-12-25"
+# define DATE "2016-12-29"
#endif
#define AUTHORS "reprappro, dc42, zpl, t3p3, dnewman"
diff --git a/src/Webserver/Webserver.cpp b/src/Webserver/Webserver.cpp
index 15d34e5e..72e62ca2 100644
--- a/src/Webserver/Webserver.cpp
+++ b/src/Webserver/Webserver.cpp
@@ -96,12 +96,7 @@
const char* overflowResponse = "overflow";
const char* badEscapeResponse = "bad escape";
-//********************************************************************************************
-//
//**************************** Generic Webserver implementation ******************************
-//
-//********************************************************************************************
-
// Constructor and initialisation
Webserver::Webserver(Platform* p, Network *n) : platform(p), network(n), webserverActive(false)
@@ -154,7 +149,7 @@ void Webserver::Spin()
{
// Take care of different protocol types here
ProtocolInterpreter *interpreter;
- uint16_t localPort = currentTransaction->GetLocalPort();
+ const uint16_t localPort = currentTransaction->GetLocalPort();
switch (localPort)
{
case FTP_PORT: /* FTP */
@@ -183,13 +178,13 @@ void Webserver::Spin()
const char *type;
switch (currentTransaction->GetStatus())
{
- case released: type = "released"; break;
- case connected: type = "connected"; break;
- case receiving: type = "receiving"; break;
- case sending: type = "sending"; break;
- case disconnected: type = "disconnected"; break;
- case deferred: type = "deferred"; break;
- case acquired: type = "acquired"; break;
+ case TransactionStatus::released: type = "released"; break;
+ case TransactionStatus::connected: type = "connected"; break;
+ case TransactionStatus::receiving: type = "receiving"; break;
+ case TransactionStatus::sending: type = "sending"; break;
+ case TransactionStatus::disconnected: type = "disconnected"; break;
+ case TransactionStatus::deferred: type = "deferred"; break;
+ case TransactionStatus::acquired: type = "acquired"; break;
default: type = "unknown"; break;
}
platform->MessageF(HOST_MESSAGE, "Incoming transaction: Type %s at local port %d (remote port %d)\n",
@@ -198,13 +193,13 @@ void Webserver::Spin()
// For protocols other than HTTP it is important to send a HELO message
TransactionStatus status = currentTransaction->GetStatus();
- if (status == connected)
+ if (status == TransactionStatus::connected)
{
interpreter->ConnectionEstablished();
}
// Graceful disconnects are handled here, because prior NetworkTransactions might still contain valid
// data. That's why it's a bad idea to close these connections immediately in the Network class.
- else if (status == disconnected)
+ else if (status == TransactionStatus::disconnected)
{
// This will call the disconnect events and effectively close the connection
currentTransaction->Discard();
@@ -561,7 +556,7 @@ void Webserver::HttpInterpreter::Spin()
// Verify HTTP sessions
const uint32_t now = millis();
- for(int i = numSessions - 1; i >= 0; i--)
+ for(int i = (int)numSessions - 1; i >= 0; i--)
{
if (sessions[i].isPostUploading)
{
@@ -624,10 +619,15 @@ void Webserver::HttpInterpreter::DoFastUpload()
{
network->Unlock();
// Write data in sector-aligned chunks. This also means that the buffer in fatfs is only used to hold the FAT.
- static const size_t writeBufLength = 2048; // use a multiple of the 512b sector size
+ // Buffer size must be a multiple of the 512b sector size.
+#ifdef DUET_NG
+ static const size_t writeBufLength = 4096;
+#else
+ static const size_t writeBufLength = 2048;
+#endif
static uint32_t writeBufStorage[writeBufLength/4]; // aligned buffer for file writes
static size_t writeBufIndex;
- char* const writeBuf = (char *)writeBufStorage;
+ char* const writeBuf = reinterpret_cast<char *>(writeBufStorage);
if (uploadedBytes == 0)
{
@@ -636,7 +636,7 @@ void Webserver::HttpInterpreter::DoFastUpload()
while (len != 0)
{
- size_t lengthToCopy = min<size_t>(writeBufLength - writeBufIndex, len);
+ const size_t lengthToCopy = min<size_t>(writeBufLength - writeBufIndex, len);
memcpy(writeBuf + writeBufIndex, buffer, lengthToCopy);
writeBufIndex += lengthToCopy;
uploadedBytes += lengthToCopy;
@@ -644,7 +644,7 @@ void Webserver::HttpInterpreter::DoFastUpload()
len -= lengthToCopy;
if (writeBufIndex == writeBufLength || uploadedBytes >= postFileLength)
{
- bool success = fileBeingUploaded.Write(writeBuf, writeBufIndex);
+ const bool success = fileBeingUploaded.Write(writeBuf, writeBufIndex);
writeBufIndex = 0;
if (!success)
{
@@ -923,7 +923,7 @@ void Webserver::HttpInterpreter::SendJsonResponse(const char* command)
// Check special cases of deferred requests (rr_fileinfo) and rejected messages
NetworkTransaction *transaction = webserver->currentTransaction;
- if (transaction->GetStatus() == deferred || transaction->GetStatus() == sending)
+ if (transaction->GetStatus() == TransactionStatus::deferred || transaction->GetStatus() == TransactionStatus::sending)
{
OutputBuffer::Release(jsonResponse);
return;
@@ -2638,14 +2638,14 @@ bool Webserver::TelnetInterpreter::CanParseData()
{
// Is this an acquired transaction using which we can send the G-code reply?
TransactionStatus status = webserver->currentTransaction->GetStatus();
- if (status == acquired)
+ if (status == TransactionStatus::acquired)
{
SendGCodeReply();
return false;
}
// Is this connection still live? Check that for deferred requests
- if (status == deferred && !webserver->currentTransaction->IsConnected())
+ if (status == TransactionStatus::deferred && !webserver->currentTransaction->IsConnected())
{
webserver->currentTransaction->Discard();
return false;