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>2018-02-12 21:08:19 +0300
committerDavid Crocker <dcrocker@eschertech.com>2018-02-12 21:08:19 +0300
commit99c2896a3e64ca76d67dda59b61ca9a8b5c6856a (patch)
treeb7f4d70a50b3167dac04c6a5d778918448982a54 /src
parent5fa6a17b4678b54c17dff37b8717cfac15446c7c (diff)
Combined DuetWiFi and DuetEthernet builds
Diffstat (limited to 'src')
-rw-r--r--src/Duet/Network.cpp11
-rw-r--r--src/Duet/Network.h3
-rw-r--r--src/DuetNG/Pins_DuetNG.h39
-rw-r--r--src/GCodes/GCodes2.cpp25
-rw-r--r--src/Network2/ESP8266/Network.cpp1692
-rw-r--r--src/Network2/ESP8266/Network.h180
-rw-r--r--src/Network2/ESP8266/Socket.cpp337
-rw-r--r--src/Network2/ESP8266/Socket.h63
-rw-r--r--src/Network2/ESP8266/WifiFirmwareUploader.cpp766
-rw-r--r--src/Network2/ESP8266/WifiFirmwareUploader.h99
-rw-r--r--src/Network2/FirmwareUpdater.cpp79
-rw-r--r--src/Network2/FirmwareUpdater.h21
-rw-r--r--src/Network2/FtpResponder.cpp911
-rw-r--r--src/Network2/FtpResponder.h56
-rw-r--r--src/Network2/HttpResponder.cpp1277
-rw-r--r--src/Network2/HttpResponder.h119
-rw-r--r--src/Network2/NetworkBuffer.cpp139
-rw-r--r--src/Network2/NetworkBuffer.h94
-rw-r--r--src/Network2/NetworkDefs.h45
-rw-r--r--src/Network2/NetworkResponder.cpp272
-rw-r--r--src/Network2/NetworkResponder.h105
-rw-r--r--src/Network2/TelnetResponder.cpp299
-rw-r--r--src/Network2/TelnetResponder.h37
-rw-r--r--src/Network2/W5500/Network.cpp555
-rw-r--r--src/Network2/W5500/Network.h119
-rw-r--r--src/Network2/W5500/Socket.cpp320
-rw-r--r--src/Network2/W5500/Socket.h67
-rw-r--r--src/Network2/W5500/Wiznet/.gitattributes22
-rw-r--r--src/Network2/W5500/Wiznet/.gitignore43
-rw-r--r--src/Network2/W5500/Wiznet/Ethernet/Socket_APIs_V3.0.3.chmbin1435546 -> 0 bytes
-rw-r--r--src/Network2/W5500/Wiznet/Ethernet/W5500/w5500.cpp177
-rw-r--r--src/Network2/W5500/Wiznet/Ethernet/W5500/w5500.h2299
-rw-r--r--src/Network2/W5500/Wiznet/Ethernet/WizSpi.cpp434
-rw-r--r--src/Network2/W5500/Wiznet/Ethernet/WizSpi.h26
-rw-r--r--src/Network2/W5500/Wiznet/Ethernet/socketlib.cpp745
-rw-r--r--src/Network2/W5500/Wiznet/Ethernet/socketlib.h487
-rw-r--r--src/Network2/W5500/Wiznet/Ethernet/wizchip_conf.cpp457
-rw-r--r--src/Network2/W5500/Wiznet/Ethernet/wizchip_conf.h422
-rw-r--r--src/Network2/W5500/Wiznet/Internet/DHCP/dhcp.cpp1004
-rw-r--r--src/Network2/W5500/Wiznet/Internet/DHCP/dhcp.h144
-rw-r--r--src/Network2/W5500/Wiznet/README.md54
-rw-r--r--src/Networking/ESP8266WiFi/WiFiInterface.cpp41
-rw-r--r--src/Networking/ESP8266WiFi/WiFiInterface.h5
-rw-r--r--src/Networking/FirmwareUpdater.cpp44
-rw-r--r--src/Networking/LwipEthernet/LwipEthernetInterface.cpp19
-rw-r--r--src/Networking/LwipEthernet/LwipEthernetInterface.h15
-rw-r--r--src/Networking/Network.cpp42
-rw-r--r--src/Networking/Network.h3
-rw-r--r--src/Networking/NetworkBuffer.h6
-rw-r--r--src/Networking/NetworkInterface.h2
-rw-r--r--src/Networking/W5500Ethernet/W5500Interface.cpp16
-rw-r--r--src/Networking/W5500Ethernet/W5500Interface.h12
-rw-r--r--src/Platform.cpp94
-rw-r--r--src/Platform.h28
-rw-r--r--src/RADDS/Network.h4
-rw-r--r--src/RepRap.cpp18
-rw-r--r--src/SAME70_TEST/Pins_SAME70_TEST.h8
-rw-r--r--src/Version.h2
58 files changed, 238 insertions, 14165 deletions
diff --git a/src/Duet/Network.cpp b/src/Duet/Network.cpp
index a0b7eaf6..7d20cedb 100644
--- a/src/Duet/Network.cpp
+++ b/src/Duet/Network.cpp
@@ -279,6 +279,7 @@ void Network::Init()
}
strcpy(hostname, DEFAULT_HOSTNAME);
+ memcpy(macAddress, platform.GetDefaultMacAddress(), sizeof(macAddress));
webserver = new Webserver(&platform, this);
webserver->Init();
@@ -817,6 +818,14 @@ void Network::SetHostname(const char *name)
}
}
+void Network::SetMacAddress(unsigned int interface, const uint8_t mac[])
+{
+ for (size_t i = 0; i < 6; i++)
+ {
+ macAddress[i] = mac[i];
+ }
+}
+
GCodeResult Network::EnableInterface(unsigned int interface, int mode, const StringRef& ssid, const StringRef& reply)
{
if (mode != 0)
@@ -861,7 +870,7 @@ void Network::Start()
if (state == NotStarted)
{
// Allow the MAC address to be set only before LwIP is started...
- ethernet_configure_interface(platform.MACAddress(), hostname);
+ ethernet_configure_interface(macAddress, hostname);
init_ethernet();
netbios_init();
state = NetworkInactive;
diff --git a/src/Duet/Network.h b/src/Duet/Network.h
index cf0f5d6d..5c817943 100644
--- a/src/Duet/Network.h
+++ b/src/Duet/Network.h
@@ -75,6 +75,8 @@ public:
const uint8_t *GetIPAddress() const;
void SetEthernetIPAddress(const uint8_t ipAddress[], const uint8_t netmask[], const uint8_t gateway[]);
void SetHostname(const char *name);
+ void SetMacAddress(unsigned int interface, const uint8_t mac[]);
+ const uint8_t *GetMacAddress(unsigned int interface) const { return macAddress; }
bool IsWiFiInterface(unsigned int interface) const { return false; }
GCodeResult EnableInterface(unsigned int interface, int mode, const StringRef& ssid, const StringRef& reply); // enable or disable the network
@@ -146,6 +148,7 @@ private:
bool activated;
volatile bool resetCallback;
char hostname[16]; // Limit DHCP hostname to 15 characters + terminating 0
+ uint8_t macAddress[6];
ConnectionState * volatile dataCs;
ConnectionState * volatile ftpCs;
diff --git a/src/DuetNG/Pins_DuetNG.h b/src/DuetNG/Pins_DuetNG.h
index 6797d675..1975d530 100644
--- a/src/DuetNG/Pins_DuetNG.h
+++ b/src/DuetNG/Pins_DuetNG.h
@@ -1,36 +1,17 @@
#ifndef PINS_DUETNG_H__
#define PINS_DUETNG_H__
-#if defined(DUET_WIFI)
-
-# define FIRMWARE_NAME "RepRapFirmware for Duet WiFi"
+# define FIRMWARE_NAME "RepRapFirmware for Duet WiFi and Duet Ethernet"
# define DEFAULT_BOARD_TYPE BoardType::DuetWiFi_10
-constexpr size_t NumFirmwareUpdateModules = 4; // 3 modules, plus one for manual upload to WiFi module
+constexpr size_t NumFirmwareUpdateModules = 4; // 3 modules, plus one for manual upload to WiFi module (module 2 is now unused)
# 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"
-constexpr size_t NumFirmwareUpdateModules = 1; // 1 module
-
-#else
-# error Firmware name not defined
-#endif
// Features definition
#define HAS_LWIP_NETWORKING 0
-#if defined(DUET_ETHERNET)
-# define HAS_WIFI_NETWORKING 0
-# define HAS_W5500_NETWORKING 1
-#else
# define HAS_WIFI_NETWORKING 1
-# define HAS_W5500_NETWORKING 0
-#endif
+# define HAS_W5500_NETWORKING 1
#define HAS_CPU_TEMP_SENSOR 1
#define HAS_HIGH_SPEED_SD 1
@@ -192,23 +173,19 @@ constexpr int HighestLogicalPin = 135; // highest logical pin number on
constexpr uint32_t IAP_FLASH_START = 0x00470000;
constexpr uint32_t IAP_FLASH_END = 0x0047FFFF; // we allow a full 64K on the SAM4
-#if defined(DUET_WIFI)
-
-// Duet pin numbers to control the WiFi interface
+// Duet pin numbers to control the WiFi interface on the Duet WiFi
constexpr Pin EspResetPin = 100; // Low on this in holds the WiFi module in reset (ESP_RESET)
constexpr Pin EspEnablePin = 101; // High to enable the WiFi module, low to power it down (ESP_CH_PD)
-constexpr Pin EspTransferRequestPin = 95; // Input from the WiFi module indicating that it wants to transfer data (ESP GPIO0)
+constexpr Pin EspDataReadyPin = 95; // Input from the WiFi module indicating that it wants to transfer data (ESP GPIO0)
constexpr Pin SamTfrReadyPin = 94; // Output from the SAM to the WiFi module indicating we can accept a data transfer (ESP GPIO4 via 7474)
constexpr Pin SamCsPin = 11; // SPI NPCS pin, input from WiFi module
-#elif defined(DUET_ETHERNET)
-
-// Duet pin numbers to control the W5500 interface
+// Duet pin numbers to control the W5500 interface on the Duet Ethernet
constexpr Pin W5500ResetPin = 100; // Low on this in holds the W5500 module in reset (ESP_RESET)
+constexpr Pin W5500InterruptPin = 95; // W5500 interrupt output, active low
+constexpr Pin W5500ModuleSensePin = 5; // URXD1, tied to ground on the Ethernet module
constexpr Pin W5500SsPin = 11; // SPI NPCS pin, input from W5500 module
-#endif
-
// Timer allocation (no network timer on DuetNG)
// TC0 channel 0 is used for FAN2
// TC0 channel 1 is currently unused (may use it for a heater or a fan)
diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp
index 18e8ed82..3481fbbc 100644
--- a/src/GCodes/GCodes2.cpp
+++ b/src/GCodes/GCodes2.cpp
@@ -2540,24 +2540,27 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply)
break;
case 540: // Set/report MAC address
- if (gb.Seen('P'))
{
- uint8_t mac[6];
- if (gb.GetMacAddress(mac))
+ const unsigned int interface = (gb.Seen('I') ? gb.GetUIValue() : 0);
+ if (gb.Seen('P'))
{
- platform.SetMACAddress(mac);
+ uint8_t mac[6];
+ if (gb.GetMacAddress(mac))
+ {
+ reprap.GetNetwork().SetMacAddress(interface, mac);
+ }
+ else
+ {
+ reply.copy("Bad MAC address");
+ result = GCodeResult::error;
+ }
}
else
{
- reply.copy("Bad MAC address");
- result = GCodeResult::error;
+ const uint8_t * const mac = reprap.GetNetwork().GetMacAddress(interface);
+ reply.printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
}
- else
- {
- const uint8_t *mac = platform.MACAddress();
- reply.printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
- }
break;
case 550: // Set/report machine name
diff --git a/src/Network2/ESP8266/Network.cpp b/src/Network2/ESP8266/Network.cpp
deleted file mode 100644
index ea57fd40..00000000
--- a/src/Network2/ESP8266/Network.cpp
+++ /dev/null
@@ -1,1692 +0,0 @@
-/****************************************************************************************************
-
- RepRapFirmware network comms to ESP8266-based device
-
- ****************************************************************************************************/
-
-#include "Network.h"
-#include "ESP8266/WifiFirmwareUploader.h"
-#include "Platform.h"
-#include "GCodes/GCodeBuffer.h"
-#include "RepRap.h"
-#include "HttpResponder.h"
-#include "FtpResponder.h"
-#include "TelnetResponder.h"
-#include "Libraries/General/IP4String.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 1 // use general DMA controller
-
-#if USE_PDC
-#include "pdc/pdc.h"
-#endif
-
-#if USE_DMAC
-#include "dmac/dmac.h"
-#endif
-
-#include "matrix/matrix.h"
-
-const uint32_t WifiResponseTimeoutMillis = 200;
-const uint32_t WiFiWaitReadyMillis = 100;
-const uint32_t WiFiStartupMillis = 300;
-const uint32_t WiFiStableMillis = 100;
-
-const unsigned int MaxHttpConnections = 4;
-
-const Port DefaultPortNumbers[NumProtocols] = { DefaultHttpPort, DefaultFtpPort, DefaultTelnetPort };
-const char * const ProtocolNames[NumProtocols] = { "HTTP", "FTP", "TELNET" };
-
-// Forward declarations of static functions
-static void spi_dma_disable();
-static bool spi_dma_check_rx_complete();
-
-struct MessageBufferOut
-{
- MessageHeaderSamToEsp hdr;
- uint8_t data[MaxDataLength]; // data to send
-};
-
-struct MessageBufferIn
-{
- MessageHeaderEspToSam hdr;
- uint8_t data[MaxDataLength]; // data to send
-};
-
-static MessageBufferOut bufferOut;
-static MessageBufferIn bufferIn;
-static volatile bool transferPending = false;
-
-#if 0
-static void debugPrintBuffer(const char *msg, void *buf, size_t dataLength)
-{
- const size_t MaxDataToPrint = 20;
- const uint8_t * const data = reinterpret_cast<const uint8_t *>(buf);
- debugPrintf("%s %02x %02x %02x %02x %04x %04x %08x",
- msg,
- data[0], data[1], data[2], data[3],
- *reinterpret_cast<const uint16_t*>(data + 4), *reinterpret_cast<const uint16_t*>(data + 6),
- *reinterpret_cast<const uint32_t*>(data + 8));
- if (dataLength != 0)
- {
- debugPrintf(" ");
- for (size_t i = 0; i < min<size_t>(dataLength, MaxDataToPrint); ++i)
- {
- debugPrintf("%02x", data[i + 12]);
- }
- if (dataLength > MaxDataToPrint)
- {
- debugPrintf("...");
- }
- }
- debugPrintf("\n");
-}
-#endif
-
-static void EspTransferRequestIsr(CallbackParameter)
-{
- reprap.GetNetwork().EspRequestsTransfer();
-}
-
-static inline void EnableEspInterrupt()
-{
- attachInterrupt(EspTransferRequestPin, EspTransferRequestIsr, RISING, nullptr);
-}
-
-static inline void DisableEspInterrupt()
-{
- detachInterrupt(EspTransferRequestPin);
-}
-
-/*-----------------------------------------------------------------------------------*/
-// WiFi interface class
-
-Network::Network(Platform& p) : platform(p), nextResponderToPoll(nullptr), uploader(nullptr), currentSocket(0), ftpDataPort(0),
- state(NetworkState::disabled), requestedMode(WiFiState::disabled), currentMode(WiFiState::disabled), activated(false),
- espStatusChanged(false), spiTxUnderruns(0), spiRxOverruns(0), serialRunning(false)
-{
- for (size_t i = 0; i < NumProtocols; ++i)
- {
- portNumbers[i] = DefaultPortNumbers[i];
- protocolEnabled[i] = (i == HttpProtocol);
- }
-
- // Create the responders
- responders = telnetResponder = new TelnetResponder(nullptr);
- responders = ftpResponder = new FtpResponder(responders);
- for (unsigned int i = 0; i < NumHttpResponders; ++i)
- {
- responders = new HttpResponder(responders);
- }
-
- strcpy(actualSsid, "(unknown)");
- strcpy(wiFiServerVersion, "(unknown)");
-}
-
-void Network::Init()
-{
- // Make sure the ESP8266 is held in the reset state
- ResetWiFi();
- longWait = lastTickMillis = millis();
-
- NetworkBuffer::AllocateBuffers(NetworkBufferCount);
-
- SetIPAddress(DefaultIpAddress, DefaultNetMask, DefaultGateway);
- strcpy(hostname, HOSTNAME);
-
- for (size_t i = 0; i < NumTcpSockets; ++i)
- {
- sockets[i].Init(i);
- }
-
- uploader = new WifiFirmwareUploader(Serial1);
- currentSocket = 0;
-}
-
-void Network::EnableProtocol(int protocol, int port, int secure, const StringRef& reply)
-{
- if (secure != 0 && secure != -1)
- {
- reply.copy("Error: this firmware does not support TLS");
- }
- else if (protocol >= 0 && protocol < (int)NumProtocols)
- {
- const Port portToUse = (port < 0) ? DefaultPortNumbers[protocol] : port;
- if (portToUse != portNumbers[protocol] && state == NetworkState::active)
- {
- // We need to shut down and restart the protocol if it is active because the port number has changed
- ShutdownProtocol(protocol);
- protocolEnabled[protocol] = false;
- }
- portNumbers[protocol] = portToUse;
- if (!protocolEnabled[protocol])
- {
- protocolEnabled[protocol] = true;
- if (state == NetworkState::active)
- {
- StartProtocol(protocol);
- // mDNS announcement is done by the WiFi Server firmware
- }
- }
- ReportOneProtocol(protocol, reply);
- }
- else
- {
- reply.copy("Invalid protocol parameter");
- }
-}
-
-void Network::DisableProtocol(int protocol, const StringRef& reply)
-{
- if (protocol >= 0 && protocol < (int)NumProtocols)
- {
- if (state == NetworkState::active)
- {
- ShutdownProtocol(protocol);
- }
- protocolEnabled[protocol] = false;
- ReportOneProtocol(protocol, reply);
- }
- else
- {
- reply.copy("Invalid protocol parameter");
- }
-}
-
-void Network::StartProtocol(Protocol protocol)
-{
- switch(protocol)
- {
- case HttpProtocol:
- SendListenCommand(portNumbers[protocol], protocol, MaxHttpConnections);
- break;
-
- case FtpProtocol:
- SendListenCommand(portNumbers[protocol], protocol, 1);
- break;
-
- case TelnetProtocol:
- SendListenCommand(portNumbers[protocol], protocol, 1);
- break;
-
- default:
- break;
- }
-}
-
-void Network::ShutdownProtocol(Protocol protocol)
-{
- for (NetworkResponder* r = responders; r != nullptr; r = r->GetNext())
- {
- r->Terminate(protocol);
- }
- switch(protocol)
- {
- case HttpProtocol:
- StopListening(portNumbers[protocol]);
- TerminateSockets(portNumbers[protocol]);
- break;
-
- case FtpProtocol:
- StopListening(portNumbers[protocol]);
- TerminateSockets(portNumbers[protocol]);
- if (ftpDataPort != 0)
- {
- StopListening(ftpDataPort);
- TerminateSockets(ftpDataPort);
- }
- break;
-
- case TelnetProtocol:
- StopListening(portNumbers[protocol]);
- TerminateSockets(portNumbers[protocol]);
- break;
-
- default:
- break;
- }
-}
-
-// Report the protocols and ports in use
-void Network::ReportProtocols(const StringRef& reply) const
-{
- reply.Clear();
- for (size_t i = 0; i < NumProtocols; ++i)
- {
- if (i != 0)
- {
- reply.cat('\n');
- }
- ReportOneProtocol(i, reply);
- }
-}
-
-void Network::ReportOneProtocol(Protocol protocol, const StringRef& reply) const
-{
- if (protocolEnabled[protocol])
- {
- reply.catf("%s is enabled on port %u", ProtocolNames[protocol], portNumbers[protocol]);
- }
- else
- {
- reply.catf("%s is disabled", ProtocolNames[protocol]);
- }
-}
-
-// This is called at the end of config.g processing.
-// Start the network if it was enabled
-void Network::Activate()
-{
- if (!activated)
- {
- activated = true;
- if (requestedMode != WiFiState::disabled)
- {
- Start();
- }
- else
- {
- platform.Message(UsbMessage, "Network disabled.\n");
- }
- }
-}
-
-void Network::Exit()
-{
- Stop();
-}
-
-// Get the network state into the reply buffer, returning true if there is some sort of error
-bool Network::GetNetworkState(const StringRef& reply)
-{
- switch (state)
- {
- case NetworkState::disabled:
- reply.copy("WiFi module is disabled");
- break;
- case NetworkState::starting1:
- case NetworkState::starting2:
- reply.copy("WiFi module is being started");
- break;
- case NetworkState::changingMode:
- reply.copy("WiFi module is changing mode");
- break;
- case NetworkState::active:
- reply.copy("WiFi module is ");
- reply.cat(TranslateWiFiState(currentMode));
- if (currentMode == WiFiState::connected || currentMode == WiFiState::runningAsAccessPoint)
- {
- reply.catf("%s, IP address %s", actualSsid, IP4String(ipAddress).c_str());
- }
- break;
- default:
- reply.copy("Unknown network state");
- return true;
- break;
- }
- return false;
-}
-
-// Start up the ESP. We assume it is not already started.
-// ESP8266 boot modes:
-// GPIO0 GPIO2 GPIO15
-// 0 1 0 Firmware download from UART
-// 1 1 0 Normal boot from flash memory
-// 0 0 1 SD card boot (not used on Duet)
-void Network::Start()
-{
- // The ESP8266 is held in a reset state by a pulldown resistor until we enable it.
- // Make sure the ESP8266 is in the reset state
- pinMode(EspResetPin, OUTPUT_LOW);
-
- // Take the ESP8266 out of power down
- pinMode(EspEnablePin, OUTPUT_HIGH);
-
- // Set up our transfer request pin (GPIO4) as an output and set it low
- pinMode(SamTfrReadyPin, OUTPUT_LOW);
-
- // Set up our data ready pin (ESP GPIO0) as an output and set it high ready to boot the ESP from flash
- pinMode(EspTransferRequestPin, OUTPUT_HIGH);
-
- // GPIO2 also needs to be high to boot. It's connected to MISO on the SAM, so set the pullup resistor on that pin
- pinMode(APIN_SPI_MISO, INPUT_PULLUP);
-
- // Set our CS input (ESP GPIO15) low ready for booting the ESP. This also clears the transfer ready latch.
- pinMode(SamCsPin, OUTPUT_LOW);
-
- // Make sure it has time to reset - no idea how long it needs, but 20ms should be plenty
- delay(50);
-
- // Release the reset on the ESP8266
- StartWiFi();
-
- // Give it time to sample GPIO0 and GPIO15
- // GPIO0 has to be held high for sufficient time:
- // - 10ms is not enough
- // - 18ms after reset is released, an oscillating signal appears on GPIO0 for 55ms
- // - so 18ms is probably long enough. Use 50ms for safety.
- delay(50);
-
- // Relinquish control of our CS pin so that the ESP can take it over
- pinMode(SamCsPin, INPUT);
-
- // Set the data request pin to be an input
- pinMode(EspTransferRequestPin, INPUT_PULLUP);
-
- // The ESP takes about 300ms before it starts talking to us, so don't wait for it here, do that in Spin()
- spiTxUnderruns = spiRxOverruns = 0;
- reconnectCount = 0;
- transferAlreadyPendingCount = readyTimeoutCount = responseTimeoutCount = 0;
-
- lastTickMillis = millis();
- state = NetworkState::starting1;
-}
-
-// Stop the ESP
-void Network::Stop()
-{
- if (state != NetworkState::disabled)
- {
- digitalWrite(SamTfrReadyPin, LOW); // tell the ESP we can't receive
- digitalWrite(EspResetPin, LOW); // put the ESP back into reset
- DisableEspInterrupt(); // ignore IRQs from the transfer request pin
-
- NVIC_DisableIRQ(SPI_IRQn);
- spi_disable(SPI);
- spi_dma_check_rx_complete();
- spi_dma_disable();
-
- state = NetworkState::disabled;
- currentMode = WiFiState::disabled;
- }
-}
-
-void Network::Spin(bool full)
-{
- if (full)
- {
- // Main state machine.
- switch (state)
- {
- case NetworkState::starting1:
- {
- // The ESP toggles CS before it has finished starting up, so don't look at the CS signal too soon
- const uint32_t now = millis();
- if (now - lastTickMillis >= WiFiStartupMillis)
- {
- lastTickMillis = now;
- state = NetworkState::starting2;
- }
- }
- break;
-
- case NetworkState::starting2:
- {
- // See if the ESP8266 has kept its pins at their stable values for long enough
- const uint32_t now = millis();
- if (digitalRead(SamCsPin) && digitalRead(EspTransferRequestPin) && !digitalRead(APIN_SPI_SCK))
- {
- if (now - lastTickMillis >= WiFiStableMillis)
- {
- // Setup the SPI controller in slave mode and assign the CS pin to it
- platform.Message(NetworkInfoMessage, "WiFi module started\n");
- SetupSpi(); // set up the SPI subsystem
-
- // Read the status to get the WiFi server version
- Receiver<NetworkStatusResponse> status;
- const int32_t rc = SendCommand(NetworkCommand::networkGetStatus, 0, 0, nullptr, 0, status);
- if (rc > 0)
- {
- SafeStrncpy(wiFiServerVersion, status.Value().versionText, ARRAY_SIZE(wiFiServerVersion));
-
- // Set the hostname before anything else is done
- if (SendCommand(NetworkCommand::networkSetHostName, 0, 0, hostname, HostNameLength, nullptr, 0) != ResponseEmpty)
- {
- reprap.GetPlatform().Message(NetworkInfoMessage, "Error: Could not set WiFi hostname\n");
- }
-
- state = NetworkState::active;
- espStatusChanged = true; // make sure we fetch the current state and enable the ESP interrupt
- }
- else
- {
- // Something went wrong, maybe a bad firmware image was flashed
- // Disable the WiFi chip again in this case
- platform.MessageF(NetworkInfoMessage, "Error: Failed to initialise WiFi module, code %" PRIi32 "\n", rc);
- Stop();
- }
- }
- }
- else
- {
- lastTickMillis = now;
- }
- }
- break;
-
- case NetworkState::disabled:
- uploader->Spin();
- break;
-
- case NetworkState::active:
- if (espStatusChanged && digitalRead(EspTransferRequestPin))
- {
- if (reprap.Debug(moduleNetwork))
- {
- debugPrintf("ESP reported status change\n");
- }
- GetNewStatus();
- }
- else if ( currentMode != requestedMode
- && currentMode != WiFiState::connecting
- && currentMode != WiFiState::reconnecting
- && currentMode != WiFiState::autoReconnecting
- )
- {
- // Tell the wifi module to change mode
- int32_t rslt = ResponseUnknownError;
- if (currentMode != WiFiState::idle)
- {
- // We must set WiFi module back to idle before changing to the new state
- rslt = SendCommand(NetworkCommand::networkStop, 0, 0, nullptr, 0, nullptr, 0);
- }
- else if (requestedMode == WiFiState::connected)
- {
- rslt = SendCommand(NetworkCommand::networkStartClient, 0, 0, requestedSsid, SsidLength, nullptr, 0);
- }
- else if (requestedMode == WiFiState::runningAsAccessPoint)
- {
- rslt = SendCommand(NetworkCommand::networkStartAccessPoint, 0, 0, nullptr, 0, nullptr, 0);
- }
-
- if (rslt >= 0)
- {
- state = NetworkState::changingMode;
- }
- else
- {
- Stop();
- platform.MessageF(NetworkInfoMessage, "Failed to change WiFi mode (code %" PRIi32 ")\n", rslt);
- }
- }
- else if (currentMode == WiFiState::connected || currentMode == WiFiState::runningAsAccessPoint)
- {
- // Find the next socket to poll
- const size_t startingSocket = currentSocket;
- do
- {
- if (sockets[currentSocket].NeedsPolling())
- {
- break;
- }
- ++currentSocket;
- if (currentSocket == NumTcpSockets)
- {
- currentSocket = 0;
- }
- } while (currentSocket != startingSocket);
-
- // Either the current socket needs polling, or no sockets do but we must still poll one of them to get notified of any new connections
- sockets[currentSocket].Poll(full);
- ++currentSocket;
- if (currentSocket == NumTcpSockets)
- {
- currentSocket = 0;
- }
-
- // Poll the responders
- if (full)
- {
- NetworkResponder *nr = nextResponderToPoll;
- bool doneSomething = false;
- do
- {
- if (nr == nullptr)
- {
- nr = responders; // 'responders' can't be null at this point
- }
- doneSomething = nr->Spin();
- nr = nr->GetNext();
- } while (!doneSomething && nr != nextResponderToPoll);
- nextResponderToPoll = nr;
- }
- }
- break;
-
- case NetworkState::changingMode:
- if (espStatusChanged && digitalRead(EspTransferRequestPin))
- {
- GetNewStatus();
- if (currentMode != WiFiState::connecting)
- {
- requestedMode = currentMode; // don't keep repeating the request if it failed
- state = NetworkState::active;
- if (currentMode == WiFiState::connected || currentMode == WiFiState::runningAsAccessPoint)
- {
- // Get our IP address, this needs to be correct for FTP to work
- Receiver<NetworkStatusResponse> status;
- if (SendCommand(NetworkCommand::networkGetStatus, 0, 0, nullptr, 0, status) > 0)
- {
- uint32_t ip = status.Value().ipAddress;
- for (size_t i = 0; i < 4; ++i)
- {
- ipAddress[i] = (uint8_t)(ip & 255);
- ip >>= 8;
- }
- SafeStrncpy(actualSsid, status.Value().ssid, SsidLength);
- }
- InitSockets();
- reconnectCount = 0;
- platform.MessageF(NetworkInfoMessage, "Wifi module is %s%s, IP address %s\n",
- TranslateWiFiState(currentMode),
- actualSsid,
- IP4String(ipAddress).c_str());
- }
- else
- {
- platform.MessageF(NetworkInfoMessage, "Wifi module is %s\n", TranslateWiFiState(currentMode));
- }
- }
- }
- break;
-
- default:
- break;
- }
- }
-
- // Check for debug info received from the WiFi module
- if (serialRunning)
- {
- while (!debugPrintPending && Serial1.available() != 0)
- {
- const char c = (char)Serial1.read();
- if (c == '\n')
- {
- debugPrintPending = true;
- }
- else if (c != '\r')
- {
- const size_t len = debugMessageBuffer.cat(c);
- if (len == debugMessageBuffer.MaxLength())
- {
- debugPrintPending = true;
- }
- }
- }
- }
-
- if (full)
- {
- // Check for debug info received from the WiFi module
- if (debugPrintPending)
- {
- if (reprap.Debug(moduleWiFi))
- {
- debugPrintf("WiFi: %s\n", debugMessageBuffer.Pointer());
- }
- debugMessageBuffer.Clear();
- debugPrintPending = false;
- }
-
- platform.ClassReport(longWait);
- }
-}
-
-// Translate a ESP8266 reset reason to text
-const char* Network::TranslateEspResetReason(uint32_t reason)
-{
- // Mapping from known ESP reset codes to reasons
- static const char * const resetReasonTexts[] =
- {
- "Power on",
- "Hardware watchdog",
- "Exception",
- "Software watchdog",
- "Software restart",
- "Deep-sleep wakeup",
- "Turned on by main processor"
- };
-
- return (reason < sizeof(resetReasonTexts)/sizeof(resetReasonTexts[0]))
- ? resetReasonTexts[reason]
- : "Unknown";
-}
-
-const char* Network::TranslateNetworkState() const
-{
- switch (state)
- {
- case NetworkState::disabled: return "disabled";
- case NetworkState::starting1:
- case NetworkState::starting2: return "starting";
- case NetworkState::active: return "running";
- case NetworkState::changingMode: return "changing mode";
- default: return "unknown";
- }
-}
-
-void Network::Diagnostics(MessageType mtype)
-{
- platform.MessageF(mtype, "=== Network ===\nNetwork state is %s\n", TranslateNetworkState());
- platform.MessageF(mtype, "WiFi module is %s\n", TranslateWiFiState(currentMode));
- platform.MessageF(mtype, "Failed messages: pending %u, notready %u, noresp %u\n", transferAlreadyPendingCount, readyTimeoutCount, responseTimeoutCount);
-
-#if 0
- // The underrun/overrun counters don't work at present
- platform.MessageF(mtype, "SPI underruns %u, overruns %u\n", spiTxUnderruns, spiRxOverruns);
-#endif
-
- if (state != NetworkState::disabled && state != NetworkState::starting1 && state != NetworkState::starting2)
- {
- Receiver<NetworkStatusResponse> status;
- if (SendCommand(NetworkCommand::networkGetStatus, 0, 0, nullptr, 0, status) > 0)
- {
- NetworkStatusResponse& r = status.Value();
- r.versionText[ARRAY_UPB(r.versionText)] = 0;
- platform.MessageF(mtype, "WiFi firmware version %s\n", r.versionText);
- platform.MessageF(mtype, "WiFi MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",
- r.macAddress[0], r.macAddress[1], r.macAddress[2], r.macAddress[3], r.macAddress[4], r.macAddress[5]);
- platform.MessageF(mtype, "WiFi Vcc %.2f, reset reason %s\n", (double)((float)r.vcc/1024), TranslateEspResetReason(r.resetReason));
- platform.MessageF(mtype, "WiFi flash size %" PRIu32 ", free heap %" PRIu32 "\n", r.flashSize, r.freeHeap);
-
- if (currentMode == WiFiState::connected || currentMode == WiFiState::runningAsAccessPoint)
- {
- platform.MessageF(mtype, "WiFi IP address %s\n", IP4String(r.ipAddress).c_str());
- }
-
- if (currentMode == WiFiState::connected)
- {
- const char* const sleepMode = (r.sleepMode == 1) ? "none" : (r.sleepMode == 2) ? "light" : (r.sleepMode == 3) ? "modem" : "unknown";
- platform.MessageF(mtype, "WiFi signal strength %ddBm, reconnections %u, sleep mode %s\n", (int)r.rssi, reconnectCount, sleepMode);
- }
- else if (currentMode == WiFiState::runningAsAccessPoint)
- {
- platform.MessageF(mtype, "Connected clients %u\n", (unsigned int)r.numClients);
- }
- // status, ssid and hostName not displayed
-
- // Print LwIP stats and other values over the ESP's UART line
- if (SendCommand(NetworkCommand::diagnostics, 0, 0, nullptr, 0, nullptr, 0) != ResponseEmpty)
- {
- platform.Message(mtype, "Failed to request ESP stats\n");
- }
- }
- else
- {
- platform.Message(mtype, "Failed to get WiFi status\n");
- }
- }
- HttpResponder::CommonDiagnostics(mtype);
- platform.Message(mtype, "Socket states: ");
- for (size_t i = 0; i < NumTcpSockets; i++)
- {
- platform.MessageF(mtype, " %d", sockets[i].State());
- }
- platform.Message(mtype, "\nResponder states:");
- for (NetworkResponder *r = responders; r != nullptr; r = r->GetNext())
- {
- r->Diagnostics(mtype);
- }
- platform.Message(mtype, "\n");
-}
-
-// Enable or disable the network
-void Network::Enable(int mode, const StringRef& ssid, const StringRef& reply)
-{
- // Translate enable mode to desired WiFi mode
- const WiFiState modeRequested = (mode == 0) ? WiFiState::idle
- : (mode == 1) ? WiFiState::connected
- : (mode == 2) ? WiFiState::runningAsAccessPoint
- : WiFiState::disabled;
- if (modeRequested == WiFiState::connected)
- {
- memset(requestedSsid, 0, sizeof(requestedSsid));
- SafeStrncpy(requestedSsid, ssid.Pointer(), ARRAY_SIZE(requestedSsid));
- }
-
- if (activated)
- {
- if (modeRequested == WiFiState::disabled)
- {
- // Shut down WiFi module completely
- requestedMode = modeRequested;
- if (state != NetworkState::disabled)
- {
- Stop();
- platform.Message(GenericMessage, "WiFi module stopped\n");
- }
- }
- else
- {
- if (state == NetworkState::disabled)
- {
- requestedMode = modeRequested;
- Start();
- }
- else if (modeRequested == currentMode || (modeRequested == WiFiState::connected && currentMode == WiFiState::connecting))
- {
- // Nothing to do, but make sure the requested mode is correct
- requestedMode = modeRequested;
- }
- else if (currentMode != WiFiState::idle && modeRequested != WiFiState::idle)
- {
- reply.copy("Turn off the current WiFi mode before selecting a new one");
- }
- else
- {
- requestedMode = modeRequested;
- }
- }
- }
- else
- {
- requestedMode = modeRequested;
- }
-}
-
-int Network::EnableState() const
-{
- return (requestedMode == WiFiState::idle) ? 0
- : (requestedMode == WiFiState::connected) ? 1
- : (requestedMode == WiFiState::runningAsAccessPoint) ? 2
- : -1;
-}
-
-GCodeResult Network::HandleWiFiCode(int mcode, GCodeBuffer &gb, const StringRef& reply, OutputBuffer*& longReply)
-{
- switch (mcode)
- {
- case 587: // Add WiFi network or list remembered networks
- if (gb.Seen('S'))
- {
- WirelessConfigurationData config;
- memset(&config, 0, sizeof(config));
- String<ARRAY_SIZE(config.ssid)> ssid;
- bool ok = gb.GetQuotedString(ssid.GetRef());
- if (ok)
- {
- SafeStrncpy(config.ssid, ssid.c_str(), ARRAY_SIZE(config.ssid));
- String<ARRAY_SIZE(config.password)> password;
- ok = gb.Seen('P') && gb.GetQuotedString(password.GetRef());
- if (ok)
- {
- if (password.strlen() < 8 && password.strlen() != 0) // WPA2 passwords must be at least 8 characters
- {
- reply.copy("WiFi password must be at least 8 characters");
- return GCodeResult::error;
- }
- SafeStrncpy(config.password, password.c_str(), ARRAY_SIZE(config.password));
- }
- }
- if (ok && gb.Seen('I'))
- {
- gb.GetIPAddress(config.ip);
- }
- if (ok && gb.Seen('J'))
- {
- ok = gb.GetIPAddress(config.gateway);
- }
- if (ok && gb.Seen('K'))
- {
- ok = gb.GetIPAddress(config.netmask);
- }
- if (ok)
- {
- const int32_t rslt = SendCommand(NetworkCommand::networkAddSsid, 0, 0, &config, sizeof(config), nullptr, 0);
- if (rslt == ResponseEmpty)
- {
- return GCodeResult::ok;
- }
- else
- {
- reply.copy("Failed to add SSID to remembered list");
- }
- }
- else
- {
- reply.copy("Bad or missing parameter");
- }
- }
- else
- {
- // List remembered networks
- const size_t declaredBufferLength = (MaxRememberedNetworks + 1) * ReducedWirelessConfigurationDataSize; // enough for all the remembered SSID data
- uint32_t buffer[NumDwords(declaredBufferLength)];
- const int32_t rslt = SendCommand(NetworkCommand::networkRetrieveSsidData, 0, 0, nullptr, 0, buffer, declaredBufferLength);
- if (rslt >= 0)
- {
- size_t offset = ReducedWirelessConfigurationDataSize; // skip own SSID details
- while (offset + ReducedWirelessConfigurationDataSize <= (size_t)rslt)
- {
- WirelessConfigurationData* const wp = reinterpret_cast<WirelessConfigurationData *>(reinterpret_cast<char*>(buffer) + offset);
- if (wp->ssid[0] != 0)
- {
- if (longReply == nullptr)
- {
- if (!OutputBuffer::Allocate(longReply))
- {
- return GCodeResult::notFinished; // try again later
- }
- longReply->copy("Remembered networks:");
- }
- wp->ssid[ARRAY_UPB(wp->ssid)] = 0;
- longReply->catf("\n%s IP=%s GW=%s NM=%s", wp->ssid, IP4String(wp->ip).c_str(), IP4String(wp->gateway).c_str(), IP4String(wp->netmask).c_str());
- }
- offset += ReducedWirelessConfigurationDataSize;
- }
-
- if (longReply == nullptr)
- {
- reply.copy("No remembered networks");
- }
- return GCodeResult::ok;
- }
-
- reply.copy("Failed to retrieve network list");
- }
- return GCodeResult::error;
-
- case 588: // Forget WiFi network
- if (gb.Seen('S'))
- {
- String<SsidLength> ssidText;
- if (gb.GetQuotedString(ssidText.GetRef()))
- {
- if (strcmp(ssidText.c_str(), "*") == 0)
- {
- const int32_t rslt = SendCommand(NetworkCommand::networkFactoryReset, 0, 0, nullptr, 0, nullptr, 0);
- if (rslt == ResponseEmpty)
- {
- return GCodeResult::ok;
- }
-
- reply.copy("Failed to reset the WiFi module to factory settings");
- return GCodeResult::error;
- }
-
- uint32_t ssid32[NumDwords(SsidLength)]; // need a dword-aligned buffer for SendCommand
- memcpy(ssid32, ssidText.c_str(), SsidLength);
- const int32_t rslt = SendCommand(NetworkCommand::networkDeleteSsid, 0, 0, ssid32, SsidLength, nullptr, 0);
- if (rslt == ResponseEmpty)
- {
- return GCodeResult::ok;
- }
-
- reply.copy("Failed to remove SSID from remembered list");
- return GCodeResult::error;
- }
- }
-
- reply.copy("Bad or missing parameter");
- return GCodeResult::error;
-
- case 589: // Configure access point
- if (gb.Seen('S'))
- {
- // Configure access point parameters
- WirelessConfigurationData config;
- memset(&config, 0, sizeof(config));
- String<SsidLength> ssid;
- bool ok = gb.GetQuotedString(ssid.GetRef());
- if (ok)
- {
- if (strcmp(ssid.c_str(), "*") == 0)
- {
- // Delete the access point details
- memset(&config, 0xFF, sizeof(config));
- }
- else
- {
- SafeStrncpy(config.ssid, ssid.c_str(), ARRAY_SIZE(config.ssid));
- String<ARRAY_SIZE(config.password)> password;
- ok = gb.Seen('P') && gb.GetQuotedString(password.GetRef());
- if (ok)
- {
- SafeStrncpy(config.password, password.c_str(), ARRAY_SIZE(config.password));
- if (gb.Seen('I'))
- {
- ok = gb.GetIPAddress(config.ip);
- config.channel = (gb.Seen('C')) ? gb.GetIValue() : 0;
- }
- else
- {
- ok = false;
- }
- }
- }
- }
- if (ok)
- {
- const int32_t rslt = SendCommand(NetworkCommand::networkConfigureAccessPoint, 0, 0, &config, sizeof(config), nullptr, 0);
- if (rslt == ResponseEmpty)
- {
- return GCodeResult::ok;
- }
-
- reply.copy("Failed to configure access point parameters");
- }
- else
- {
- reply.copy("Bad or missing parameter");
- }
- }
- else
- {
- // Report access point parameters
- uint32_t buffer[NumDwords(ReducedWirelessConfigurationDataSize)];
- const int32_t rslt = SendCommand(NetworkCommand::networkRetrieveSsidData, 0, 0, nullptr, 0, buffer, ReducedWirelessConfigurationDataSize);
- if (rslt >= 0)
- {
- WirelessConfigurationData* const wp = reinterpret_cast<WirelessConfigurationData *>(buffer);
- if (wp->ssid[0] == 0)
- {
- reply.copy("Own SSID not configured");
- }
- else
- {
- wp->ssid[ARRAY_UPB(wp->ssid)] = 0;
- reply.printf("Own SSID: %s IP=%s GW=%s NM=%s", wp->ssid, IP4String(wp->ip).c_str(), IP4String(wp->gateway).c_str(), IP4String(wp->netmask).c_str());
- return GCodeResult::ok;
- }
- }
- else
- {
- reply.copy("Failed to retrieve own SSID data");
- }
- }
- return GCodeResult::error;
-
- default: // should not happen
- return GCodeResult::error;
- }
-}
-
-// Translate the wifi state to text.
-// The 'connected' and 'runningAsAccessPoint' states include a space at the end because the caller is expected to append the access point name.
-/*static*/ const char* Network::TranslateWiFiState(WiFiState w)
-{
- switch (w)
- {
- case WiFiState::disabled: return "disabled";
- case WiFiState::idle: return "idle";
- case WiFiState::connecting: return "trying to connect";
- case WiFiState::connected: return "connected to access point ";
- case WiFiState::runningAsAccessPoint: return "providing access point ";
- case WiFiState::autoReconnecting: return "auto-reconnecting";
- case WiFiState::reconnecting: return "reconnecting";
- default: return "in an unknown state";
- }
-}
-
-void Network::EspRequestsTransfer()
-{
- espStatusChanged = true;
- DisableEspInterrupt(); // don't allow more interrupts until we have acknowledged this one
-}
-
-void Network::SetIPAddress(const uint8_t p_ipAddress[], const uint8_t p_netmask[], const uint8_t p_gateway[])
-{
- memcpy(ipAddress, p_ipAddress, sizeof(ipAddress));
- memcpy(netmask, p_netmask, sizeof(netmask));
- memcpy(gateway, p_gateway, sizeof(gateway));
-}
-
-// Set the DHCP hostname. Removes all whitespaces and converts the name to lower-case.
-void Network::SetHostname(const char *name)
-{
- // Filter out illegal characters
- size_t i = 0;
- while (*name && i < ARRAY_UPB(hostname))
- {
- char c = *name++;
- if (c >= 'A' && c <= 'Z')
- {
- c += 'a' - 'A';
- }
-
- if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c == '-') || (c == '_'))
- {
- hostname[i++] = c;
- }
- }
-
- if (i != 0)
- {
- hostname[i] = 0;
- }
- else
- {
- strcpy(hostname, HOSTNAME);
- }
-
- // Update the hostname if possible
- if (state == NetworkState::active)
- {
- if (SendCommand(NetworkCommand::networkSetHostName, 0, 0, hostname, HostNameLength, nullptr, 0) != ResponseEmpty)
- {
- platform.Message(GenericMessage, "Error: Could not set WiFi hostname\n");
- }
- }
-}
-
-void Network::InitSockets()
-{
- for (size_t i = 0; i < NumProtocols; ++i)
- {
- if (protocolEnabled[i])
- {
- StartProtocol(i);
- }
- }
- currentSocket = 0;
-}
-
-void Network::TerminateSockets()
-{
- for (SocketNumber skt = 0; skt < NumTcpSockets; ++skt)
- {
- sockets[skt].Terminate();
- }
-}
-
-void Network::TerminateSockets(Port port)
-{
- for (SocketNumber skt = 0; skt < NumTcpSockets; ++skt)
- {
- if (sockets[skt].GetLocalPort() == port)
- {
- sockets[skt].Terminate();
- }
- }
-}
-
-// This is called to tell the network which sockets are active
-void Network::UpdateSocketStatus(uint16_t connectedSockets, uint16_t otherEndClosedSockets)
-{
- for (size_t i = 0; i < NumTcpSockets; ++i)
- {
- if (((connectedSockets | otherEndClosedSockets) & (1u << i)) != 0)
- {
- sockets[i].SetNeedsPolling();
- }
- }
-}
-
-// Find a responder to process a new connection
-bool Network::FindResponder(Socket *skt, Port localPort)
-{
- // Get the right protocol
- Protocol protocol;
- if (localPort == ftpDataPort)
- {
- protocol = FtpDataProtocol;
- }
- else
- {
- bool protocolFound = false;
- for (size_t i = 0; i < NumProtocols; ++i)
- {
- if (protocolEnabled[i] && portNumbers[i] == localPort)
- {
- protocol = i;
- protocolFound = true;
- break;
- }
- }
-
- if (!protocolFound)
- {
- // Protocol is disabled
- return false;
- }
- }
-
- // Try to find a responder to deal with this connection
- for (NetworkResponder *r = responders; r != nullptr; r = r->GetNext())
- {
- if (r->Accept(skt, protocol))
- {
- return true;
- }
- }
- return false;
-}
-
-// Open the FTP data port
-void Network::OpenDataPort(Port port)
-{
- ftpDataPort = port;
- SendListenCommand(ftpDataPort, FtpDataProtocol, 1);
-}
-
-// Close FTP data port and purge associated resources
-void Network::TerminateDataPort()
-{
- if (ftpDataPort != 0)
- {
- StopListening(ftpDataPort);
- for (SocketNumber skt = 0; skt < NumTcpSockets; ++skt)
- {
- if (sockets[skt].GetLocalPort() == ftpDataPort)
- {
- sockets[skt].TerminatePolitely();
- }
- }
- ftpDataPort = 0;
- }
-}
-
-void Network::DataPortClosing()
-{
- StopListening(ftpDataPort);
-}
-
-void Network::HandleHttpGCodeReply(const char *msg)
-{
- HttpResponder::HandleGCodeReply(msg);
-}
-
-void Network::HandleTelnetGCodeReply(const char *msg)
-{
- telnetResponder->HandleGCodeReply(msg);
-}
-
-void Network::HandleHttpGCodeReply(OutputBuffer *buf)
-{
- HttpResponder::HandleGCodeReply(buf);
-}
-
-void Network::HandleTelnetGCodeReply(OutputBuffer *buf)
-{
- telnetResponder->HandleGCodeReply(buf);
-}
-
-uint32_t Network::GetHttpReplySeq()
-{
- return HttpResponder::GetReplySeq();
-}
-
-#if USE_PDC
-static Pdc *spi_pdc;
-#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;
-
-#endif
-
-static inline void spi_rx_dma_enable()
-{
-#if USE_PDC
- pdc_enable_transfer(spi_pdc, PERIPH_PTCR_RXTEN);
-#endif
-
-#if USE_DMAC
- dmac_channel_enable(DMAC, CONF_SPI_DMAC_RX_CH);
-#endif
-}
-
-static inline void spi_tx_dma_enable()
-{
-#if USE_PDC
- pdc_enable_transfer(spi_pdc, PERIPH_PTCR_TXTEN);
-#endif
-
-#if USE_DMAC
- dmac_channel_enable(DMAC, CONF_SPI_DMAC_TX_CH);
-#endif
-}
-
-static inline void spi_rx_dma_disable()
-{
-#if USE_PDC
- pdc_disable_transfer(spi_pdc, PERIPH_PTCR_RXTDIS);
-#endif
-
-#if USE_DMAC
- dmac_channel_disable(DMAC, CONF_SPI_DMAC_RX_CH);
-#endif
-}
-
-static inline void spi_tx_dma_disable()
-{
-#if USE_PDC
- pdc_disable_transfer(spi_pdc, PERIPH_PTCR_TXTDIS);
-#endif
-
-#if USE_DMAC
- dmac_channel_disable(DMAC, CONF_SPI_DMAC_TX_CH);
-#endif
-}
-
-static void spi_dma_disable()
-{
- spi_tx_dma_disable();
- spi_rx_dma_disable();
-}
-
-static bool spi_dma_check_rx_complete()
-{
-#if USE_PDC
- return true;
-#endif
-
-#if USE_DMAC
- const 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;
-#endif
-}
-
-static void spi_tx_dma_setup(const void *buf, uint32_t transferLength)
-{
-#if USE_PDC
- pdc_packet_t pdc_spi_packet;
- pdc_spi_packet.ul_addr = reinterpret_cast<uint32_t>(buf);
- pdc_spi_packet.ul_size = transferLength;
- pdc_tx_init(spi_pdc, &pdc_spi_packet, NULL);
-#endif
-
-#if USE_DMAC
- 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, transferLength | 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);
-#endif
-}
-
-static void spi_rx_dma_setup(const void *buf, uint32_t transferLength)
-{
-#if USE_PDC
- pdc_packet_t pdc_spi_packet;
- pdc_spi_packet.ul_addr = reinterpret_cast<uint32_t>(buf);
- pdc_spi_packet.ul_size = transferLength;
- pdc_rx_init(spi_pdc, &pdc_spi_packet, NULL);
-#endif
-
-#if USE_DMAC
- 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, transferLength | 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
-}
-
-/**
- * \brief Set SPI slave transfer.
- */
-static void spi_slave_dma_setup(uint32_t dataOutSize, uint32_t dataInSize)
-{
-#if USE_PDC
- pdc_disable_transfer(spi_pdc, PERIPH_PTCR_TXTDIS | PERIPH_PTCR_RXTDIS);
- spi_rx_dma_setup(&bufferIn, dataInSize + sizeof(MessageHeaderEspToSam));
- spi_tx_dma_setup(&bufferOut, dataOutSize + sizeof(MessageHeaderSamToEsp));
- pdc_enable_transfer(spi_pdc, PERIPH_PTCR_TXTEN | PERIPH_PTCR_RXTEN);
-#endif
-
-#if USE_DMAC
- spi_dma_disable();
-
- spi_rx_dma_setup(&bufferIn, dataInSize + sizeof(MessageHeaderEspToSam));
- spi_rx_dma_enable();
- spi_tx_dma_setup(&bufferOut, dataOutSize + sizeof(MessageHeaderSamToEsp));
- spi_tx_dma_enable();
-#endif
-}
-
-// Set up the SPI system
-void Network::SetupSpi()
-{
-#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]);
- ConfigurePin(g_APinDescription[APIN_SPI_SS0]);
-
- pmc_enable_periph_clk(ID_SPI);
- spi_dma_disable();
- spi_reset(SPI); // this clears the transmit and receive registers and puts the SPI into slave mode
-
-#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)SPI->SPI_SR; // clear any pending interrupt
- SPI->SPI_IDR = SPI_IER_NSSR; // disable the interrupt
-
- NVIC_SetPriority(SPI_IRQn, NvicPrioritySpi);
- NVIC_EnableIRQ(SPI_IRQn);
-}
-
-// Send a command to the ESP and get the result
-int32_t Network::SendCommand(NetworkCommand cmd, SocketNumber socketNum, uint8_t flags, const void *dataOut, size_t dataOutLength, void* dataIn, size_t dataInLength)
-{
- if (state == NetworkState::disabled)
- {
- if (reprap.Debug(moduleNetwork))
- {
- debugPrintf("ResponseNetworkDisabled\n");
- }
- return ResponseNetworkDisabled;
- }
-
- if (transferPending)
- {
- if (reprap.Debug(moduleNetwork))
- {
- debugPrintf("ResponseBusy\n");
- }
- ++transferAlreadyPendingCount;
- return ResponseBusy;
- }
-
- // Wait for the ESP to be ready, with timeout
- {
- const uint32_t now = millis();
- while (!digitalRead(EspTransferRequestPin))
- {
- if (millis() - now > WiFiWaitReadyMillis)
- {
- if (reprap.Debug(moduleNetwork))
- {
- debugPrintf("ResponseBusy\n");
- }
- ++readyTimeoutCount;
- return ResponseBusy;
- }
- }
- }
-
- bufferOut.hdr.formatVersion = MyFormatVersion;
- bufferOut.hdr.command = cmd;
- bufferOut.hdr.socketNumber = socketNum;
- bufferOut.hdr.flags = flags;
- bufferOut.hdr.param32 = 0;
- bufferOut.hdr.dataLength = (uint16_t)dataOutLength;
- bufferOut.hdr.dataBufferAvailable = (uint16_t)dataInLength;
- if (dataOut != nullptr)
- {
- memcpy(bufferOut.data, dataOut, dataOutLength);
- }
- bufferIn.hdr.formatVersion = InvalidFormatVersion;
- transferPending = true;
-
- // DMA may have transferred an extra word to the SPI transmit data register. We need to clear this.
- // The only way I can find to do this is to issue a software reset to the SPI system.
- // Fortunately, this leaves the SPI system in slave mode.
- spi_reset(SPI);
- spi_set_bits_per_transfer(SPI, 0, SPI_CSR_BITS_8_BIT);
-
- // Set up the DMA controller
- spi_slave_dma_setup(dataOutLength, dataInLength);
- spi_enable(SPI);
-
- // Enable the end-of transfer interrupt
- (void)SPI->SPI_SR; // clear any pending interrupt
- SPI->SPI_IER = SPI_IER_NSSR; // enable the NSS rising interrupt
-
- // Tell the ESP that we are ready to accept data
- digitalWrite(SamTfrReadyPin, HIGH);
-
- // Wait for the DMA complete interrupt, with timeout
- {
- const uint32_t now = millis();
- while (transferPending || !spi_dma_check_rx_complete())
- {
- if (millis() - now > WifiResponseTimeoutMillis)
- {
- if (reprap.Debug(moduleNetwork))
- {
- debugPrintf("ResponseTimeout, pending=%d\n", (int)transferPending);
- }
- transferPending = false;
- spi_dma_disable();
- ++responseTimeoutCount;
- return ResponseTimeout;
- }
- }
- }
-
- // Look at the response
- int32_t response;
- if (bufferIn.hdr.formatVersion != MyFormatVersion)
- {
- response = ResponseBadReplyFormatVersion;
- }
- else
- {
- if ( (bufferIn.hdr.state == WiFiState::autoReconnecting || bufferIn.hdr.state == WiFiState::reconnecting)
- && currentMode != WiFiState::autoReconnecting && currentMode != WiFiState::reconnecting
- )
- {
- ++reconnectCount;
- }
- currentMode = bufferIn.hdr.state;
- response = bufferIn.hdr.response;
- if (response > 0 && dataIn != nullptr)
- {
- memcpy(dataIn, bufferIn.data, min<size_t>(dataInLength, (size_t)response));
- }
- }
-
- if (response < 0 && reprap.Debug(moduleNetwork))
- {
- debugPrintf("Network command %d socket %u returned error %" PRIi32 "\n", (int)cmd, socketNum, response);
- }
-
-#if 0
- //***TEMP debug
- if (cmd != NetworkCommand::connGetStatus)
- {
- debugPrintBuffer("Recv", &bufferIn, (dataIn == nullptr) ? 0 : (size_t)max<int>(0, response));
- }
-#endif
-
- return response;
-}
-
-void Network::SendListenCommand(Port port, Protocol protocol, unsigned int maxConnections)
-{
- ListenOrConnectData lcb;
- lcb.port = port;
- lcb.protocol = protocol;
- lcb.remoteIp = AnyIp;
- lcb.maxConnections = maxConnections;
- SendCommand(NetworkCommand::networkListen, 0, 0, &lcb, sizeof(lcb), nullptr, 0);
-}
-
-// Stop listening on a port
-void Network::StopListening(Port port)
-{
- SendListenCommand(port, AnyProtocol, 0);
-}
-
-// This is called when ESP is signalling to us that an error occurred or there was a state change
-void Network::GetNewStatus()
-{
- struct MessageResponse
- {
- char messageBuffer[100];
- };
- Receiver<MessageResponse> rcvr;
-
- espStatusChanged = false;
- EnableEspInterrupt();
-
- const int32_t rslt = SendCommand(NetworkCommand::networkGetLastError, 0, 0, nullptr, 0, rcvr);
- rcvr.Value().messageBuffer[ARRAY_UPB(rcvr.Value().messageBuffer)] = 0;
- if (rslt < 0)
- {
- platform.Message(NetworkInfoMessage, "Error retrieving WiFi status message\n");
- }
- else if (rslt > 0 && rcvr.Value().messageBuffer[0] != 0)
- {
- platform.MessageF(NetworkInfoMessage, "WiFi reported error: %s\n", rcvr.Value().messageBuffer);
- }
-}
-
-// SPI interrupt handler, called when NSS goes high
-void SPI_Handler()
-{
- reprap.GetNetwork().SpiInterrupt();
-}
-
-void Network::SpiInterrupt()
-{
- const uint32_t status = SPI->SPI_SR; // read status and clear interrupt
- SPI->SPI_IDR = SPI_IER_NSSR; // disable the interrupt
- if ((status & SPI_SR_NSSR) != 0)
- {
-#if USE_PDC
- pdc_disable_transfer(spi_pdc, PERIPH_PTCR_TXTDIS | PERIPH_PTCR_RXTDIS);
-#endif
-
-#if USE_DMAC
- spi_tx_dma_disable();
- dmac_channel_suspend(DMAC, CONF_SPI_DMAC_RX_CH); // suspend the receive channel, don't disable it because the FIFO needs to empty first
-#endif
- spi_disable(SPI);
- digitalWrite(SamTfrReadyPin, LOW);
- if ((status & SPI_SR_OVRES) != 0)
- {
- ++spiRxOverruns;
- }
- if ((status & SPI_SR_UNDES) != 0)
- {
- ++spiTxUnderruns;
- }
- transferPending = false;
- }
-}
-
-// Start the ESP
-void Network::StartWiFi()
-{
- digitalWrite(EspResetPin, HIGH);
- ConfigurePin(g_APinDescription[APINS_UART1]); // connect the pins to UART1
- Serial1.begin(WiFiBaudRate); // initialise the UART, to receive debug info
- debugMessageBuffer.Clear();
- serialRunning = true;
- debugPrintPending = false;
-}
-
-// Reset the ESP8266 and leave held in reset
-void Network::ResetWiFi()
-{
- pinMode(EspResetPin, OUTPUT_LOW); // assert ESP8266 /RESET
- pinMode(APIN_UART1_TXD, INPUT_PULLUP); // just enable pullups on TxD and RxD pins for now to avoid floating pins
- pinMode(APIN_UART1_RXD, INPUT_PULLUP);
- currentMode = WiFiState::disabled;
-
- if (serialRunning)
- {
- Serial1.end();
- serialRunning = false;
- }
-}
-
-// Reset the ESP8266 to take commands from the UART or from external input. The caller must wait for the reset to complete after calling this.
-// ESP8266 boot modes:
-// GPIO0 GPIO2 GPIO15
-// 0 1 0 Firmware download from UART
-// 1 1 0 Normal boot from flash memory
-// 0 0 1 SD card boot (not used in on Duet)
-void Network::ResetWiFiForUpload(bool external)
-{
- if (serialRunning)
- {
- Serial1.end();
- serialRunning = false;
- }
-
- // Make sure the ESP8266 is in the reset state
- pinMode(EspResetPin, OUTPUT_LOW);
-
- // Take the ESP8266 out of power down
- pinMode(EspEnablePin, OUTPUT_HIGH);
-
- // Set up our transfer request pin (GPIO4) as an output and set it low
- pinMode(SamTfrReadyPin, OUTPUT_LOW);
-
- // Set up our data ready pin (ESP GPIO0) as an output and set it low ready to boot the ESP from UART
- pinMode(EspTransferRequestPin, OUTPUT_LOW);
-
- // GPIO2 also needs to be high to boot up. It's connected to MISO on the SAM, so set the pullup resistor on that pin
- pinMode(APIN_SPI_MISO, INPUT_PULLUP);
-
- // Set our CS input (ESP GPIO15) low ready for booting the ESP. This also clears the transfer ready latch.
- pinMode(SamCsPin, OUTPUT_LOW);
-
- // Make sure it has time to reset - no idea how long it needs, but 50ms should be plenty
- delay(50);
-
- if (external)
- {
- pinMode(APIN_UART1_TXD, INPUT_PULLUP); // just enable pullups on TxD and RxD pins
- pinMode(APIN_UART1_RXD, INPUT_PULLUP);
- }
- else
- {
- ConfigurePin(g_APinDescription[APINS_UART1]); // connect the pins to UART1
- }
-
- // Release the reset on the ESP8266
- digitalWrite(EspResetPin, HIGH);
-}
-
-// End
diff --git a/src/Network2/ESP8266/Network.h b/src/Network2/ESP8266/Network.h
deleted file mode 100644
index 0639758b..00000000
--- a/src/Network2/ESP8266/Network.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/****************************************************************************************************
-
-RepRapFirmware - Network: RepRapPro Ormerod with Duet controller
-
-Separated out from Platform.h by dc42 and extended by chrishamm
-
-****************************************************************************************************/
-
-#ifndef NETWORK_H
-#define NETWORK_H
-
-#include "ESP8266/Socket.h"
-#include "NetworkDefs.h"
-#include "RepRapFirmware.h"
-#include "MessageType.h"
-#include "MessageFormats.h"
-#include "GCodes/GCodeResult.h"
-
-class NetworkResponder;
-class HttpResponder;
-class FtpResponder;
-class TelnetResponder;
-class WifiFirmwareUploader;
-
-const unsigned int NumHttpResponders = 4; // the number of concurrent HTTP requests we can process
-
-// Class to allow us to receive some data allowing for some extra bytes being stored by the DMAC
-template<class T> class Receiver
-{
-public:
- void *DmaPointer() { return &object; }
- size_t Size() const { return sizeof(T); }
- T& Value() { return object; }
-private:
- T object;
- uint32_t padding;
-};
-
-// The main network class that drives the network.
-class Network
-{
-public:
- friend class Socket;
-
- Network(Platform& p);
-
- void Init();
- void Activate();
- void Exit();
- void Spin(bool full);
- void Diagnostics(MessageType mtype);
- void Start();
- void Stop();
-
- void EnableProtocol(int protocol, int port, int secure, const StringRef& reply);
- void DisableProtocol(int protocol, const StringRef& reply);
- void ReportProtocols(const StringRef& reply) const;
-
- void Enable(int mode, const StringRef& ssid, const StringRef& reply); // enable or disable the network
- GCodeResult HandleWiFiCode(int mcode, GCodeBuffer& gb, const StringRef& reply, OutputBuffer*& longReply);
- bool GetNetworkState(const StringRef& reply);
- int EnableState() const;
-
- void SetHostname(const char *name);
-
- bool FindResponder(Socket *skt, Port localPort);
-
- const uint8_t *GetIPAddress() const { return ipAddress; }
- void OpenDataPort(Port port);
- void TerminateDataPort();
- void DataPortClosing();
-
- void HandleHttpGCodeReply(const char *msg);
- void HandleTelnetGCodeReply(const char *msg);
- void HandleHttpGCodeReply(OutputBuffer *buf);
- void HandleTelnetGCodeReply(OutputBuffer *buf);
- uint32_t GetHttpReplySeq();
-
- // The remaining functions are specific to the WiFi version
- WifiFirmwareUploader& GetWifiUploader() { return *uploader; }
-
- void StartWiFi();
- void ResetWiFi();
- void ResetWiFiForUpload(bool external);
-
- const char *GetWiFiServerVersion() const { return wiFiServerVersion; }
-
- const char* TranslateNetworkState() const;
- static const char* TranslateWiFiState(WiFiState w);
-
- void SpiInterrupt();
- void EspRequestsTransfer();
- void UpdateSocketStatus(uint16_t connectedSockets, uint16_t otherEndClosedSockets);
-
-private:
- enum class NetworkState
- {
- disabled, // WiFi module disabled
- starting1, // starting up
- starting2, // starting up
- active, // running, but not necessarily in the requested mode
- changingMode, // running and in the process of switching between modes
- };
-
- void InitSockets();
- void TerminateSockets();
- void TerminateSockets(Port port);
- void StopListening(Port port);
-
- void StartProtocol(Protocol protocol)
- pre(protocol < NumProtocols);
-
- void ShutdownProtocol(Protocol protocol)
- pre(protocol < NumProtocols);
-
- void ReportOneProtocol(Protocol protocol, const StringRef& reply) const
- pre(protocol < NumProtocols);
-
- void SetIPAddress(const uint8_t ipAddress[], const uint8_t netmask[], const uint8_t gateway[]);
-
- void SetupSpi();
-
- int32_t SendCommand(NetworkCommand cmd, SocketNumber socket, uint8_t flags, const void *dataOut, size_t dataOutLength, void* dataIn, size_t dataInLength);
-
- template<class T> int32_t SendCommand(NetworkCommand cmd, SocketNumber socket, uint8_t flags, const void *dataOut, size_t dataOutLength, Receiver<T>& recvr)
- {
- return SendCommand(cmd, socket, flags, dataOut, dataOutLength, recvr.DmaPointer(), recvr.Size());
- }
-
- void SendListenCommand(Port port, Protocol protocol, unsigned int maxConnections);
- void GetNewStatus();
-
- static const char* TranslateEspResetReason(uint32_t reason);
-
- Platform& platform;
- NetworkResponder *responders;
- NetworkResponder *nextResponderToPoll;
- FtpResponder *ftpResponder;
- TelnetResponder *telnetResponder;
- uint32_t longWait;
- uint32_t lastTickMillis;
-
- WifiFirmwareUploader *uploader;
-
- Socket sockets[NumTcpSockets];
- size_t currentSocket;
-
- Port portNumbers[NumProtocols]; // port number used for each protocol
- Port ftpDataPort;
- bool protocolEnabled[NumProtocols]; // whether each protocol is enabled
-
- NetworkState state;
- WiFiState requestedMode;
- WiFiState currentMode;
- bool activated;
- volatile bool espStatusChanged;
-
- uint8_t ipAddress[4];
- uint8_t netmask[4];
- uint8_t gateway[4];
- char hostname[16]; // Limit DHCP hostname to 15 characters + terminating 0
- char requestedSsid[SsidLength + 1];
- char actualSsid[SsidLength + 1];
-
- unsigned int spiTxUnderruns;
- unsigned int spiRxOverruns;
- unsigned int reconnectCount;
- unsigned int transferAlreadyPendingCount;
- unsigned int readyTimeoutCount;
- unsigned int responseTimeoutCount;
-
- char wiFiServerVersion[16];
-
- // For processing debug messages from the WiFi module
- bool serialRunning;
- bool debugPrintPending;
- String<100> debugMessageBuffer;
-};
-
-#endif
diff --git a/src/Network2/ESP8266/Socket.cpp b/src/Network2/ESP8266/Socket.cpp
deleted file mode 100644
index 7d9a1859..00000000
--- a/src/Network2/ESP8266/Socket.cpp
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * WiFiSocket.cpp
- *
- * Created on: 22 Apr 2017
- * Author: David
- */
-
-#include <Network2/ESP8266/Network.h>
-#include <Network2/ESP8266/Socket.h>
-#include "NetworkBuffer.h"
-#include "RepRap.h"
-
-const uint32_t FindResponderTimeout = 2000; // how long we wait for a responder to become available
-const unsigned int MaxBuffersPerSocket = 4;
-
-Socket::Socket() : localPort(0), receivedData(nullptr), state(SocketState::inactive), needsPolling(false)
-{
-}
-
-void Socket::Init(SocketNumber n)
-{
- socketNum = n;
- state = SocketState::inactive;
- txBufferSpace = 0;
-}
-
-// Close a connection when the last packet has been sent
-void Socket::Close()
-{
- if (state == SocketState::connected || state == SocketState::clientDisconnecting)
- {
- const int32_t reply = reprap.GetNetwork().SendCommand(NetworkCommand::connClose, socketNum, 0, nullptr, 0, nullptr, 0);
- if (reply == ResponseEmpty)
- {
- state = (state == SocketState::connected) ? SocketState::closing : SocketState::inactive;
- return;
- }
- }
-
- if (reprap.Debug(moduleNetwork))
- {
- debugPrintf("close failed, in wrong state or bad reply\n");
- }
- Terminate(); // something is not right, so terminate the socket for safety
-}
-
-// Terminate a connection immediately
-// We can call this after any sort of error on a socket as long as it is in use.
-void Socket::Terminate()
-{
- if (state != SocketState::inactive)
- {
- const int32_t reply = reprap.GetNetwork().SendCommand(NetworkCommand::connAbort, socketNum, 0, nullptr, 0, nullptr, 0);
- state = (reply != 0) ? SocketState::broken : SocketState::inactive;
- }
- DiscardReceivedData();
- txBufferSpace = 0;
-}
-
-// Called to terminate the connection unless it is already being closed
-void Socket::TerminatePolitely()
-{
- if (state != SocketState::clientDisconnecting && state != SocketState::closing)
- {
- Terminate();
- }
-}
-
-// Return true if there is or may soon be more data to read
-bool Socket::CanRead() const
-{
- return (state == SocketState::connected)
- || (state == SocketState::clientDisconnecting && receivedData != nullptr && receivedData->TotalRemaining() != 0);
-}
-
-// Return true if we can send data to this socket
-bool Socket::CanSend() const
-{
- return state == SocketState::connected;
-}
-
-// Read 1 character from the receive buffers, returning true if successful
-bool Socket::ReadChar(char& c)
-{
- if (receivedData != nullptr)
- {
- const bool ret = receivedData->ReadChar(c);
- if (receivedData->IsEmpty())
- {
- receivedData = receivedData->Release();
- }
- return ret;
- }
-
- c = 0;
- return false;
-}
-
-// Return a pointer to data in a buffer and a length available, and mark the data as taken
-bool Socket::ReadBuffer(const uint8_t *&buffer, size_t &len)
-{
- if (receivedData != nullptr)
- {
- len = receivedData->Remaining();
- buffer = receivedData->UnreadData();
- return true;
- }
-
- return false;
-}
-
-// Flag some data as taken from the receive buffers. We never take data from more than one buffer at a time.
-void Socket::Taken(size_t len)
-{
- if (receivedData != nullptr)
- {
- receivedData->Taken(len);
- if (receivedData->IsEmpty())
- {
- receivedData = receivedData->Release(); // discard empty buffer at head of chain
- }
- }
-}
-
-// Poll a socket to see if it needs to be serviced
-void Socket::Poll(bool full)
-{
- // Get the socket status
- Network& network = reprap.GetNetwork();
- Receiver<ConnStatusResponse> resp;
- const int32_t ret = network.SendCommand(NetworkCommand::connGetStatus, socketNum, 0, nullptr, 0, resp);
- if (ret != (int32_t)resp.Size())
- {
- // We can't do much here other than disable and restart wifi, or hope the next status call succeeds
- if (reprap.Debug(moduleNetwork))
- {
- debugPrintf("Bad recv status size\n");
- }
- return;
- }
-
- // As well as getting the status for the socket we asked about, we also received bitmaps of connected sockets.
- // Pass these to the Network module so that it can avoid polling idle sockets.
- network.UpdateSocketStatus(resp.Value().connectedSockets, resp.Value().otherEndClosedSockets);
-
- switch (resp.Value().state)
- {
- case ConnState::otherEndClosed:
- // Check for further incoming packets before this socket is finally closed.
- // This must be done to ensure that FTP uploads are not cut off.
- ReceiveData(resp.Value().bytesAvailable);
-
- if (state == SocketState::clientDisconnecting)
- {
- // We already got here before, so close the connection once and for all
- Close();
- break;
- }
- else if (state != SocketState::inactive)
- {
- state = SocketState::clientDisconnecting;
- if (reprap.Debug(moduleNetwork))
- {
- debugPrintf("Client disconnected on socket %u\n", socketNum);
- }
- break;
- }
- // We can get here if a client has sent very little data and then instantly closed
- // the connection, e.g. when an FTP client transferred very small files over the
- // data port. In such cases we must notify the responder about this transmission!
- // no break
-
- case ConnState::connected:
- if (full && state != SocketState::connected)
- {
- // It's a new connection
- if (reprap.Debug(moduleNetwork))
- {
- debugPrintf("New conn on socket %u for local port %u\n", socketNum, localPort);
- }
- localPort = resp.Value().localPort;
- remotePort = resp.Value().remotePort;
- remoteIp = resp.Value().remoteIp;
- DiscardReceivedData();
- if (state != SocketState::waitingForResponder)
- {
- whenConnected = millis();
- state = SocketState::waitingForResponder;
- }
- if (network.FindResponder(this, localPort))
- {
- state = (resp.Value().state == ConnState::connected) ? SocketState::connected : SocketState::clientDisconnecting;
- if (reprap.Debug(moduleNetwork))
- {
- debugPrintf("Found responder\n");
- }
- }
- else if (millis() - whenConnected >= FindResponderTimeout)
- {
- Terminate();
- if (reprap.Debug(moduleNetwork))
- {
- debugPrintf("No responder, new conn %u terminated\n", socketNum);
- }
- }
- }
-
- if (state == SocketState::connected)
- {
- txBufferSpace = resp.Value().writeBufferSpace;
- ReceiveData(resp.Value().bytesAvailable);
- }
- break;
-
- default:
- if (state == SocketState::connected || state == SocketState::waitingForResponder)
- {
- // Unexpected change of state
- if (state != SocketState::clientDisconnecting && reprap.Debug(moduleNetwork))
- {
- debugPrintf("Unexpected state change on socket %u\n", socketNum);
- }
- state = SocketState::broken;
- }
- else if (state == SocketState::closing)
- {
- // Socket closed
- state = SocketState::inactive;
- }
- break;
- }
-
- needsPolling = false;
-}
-
-// Try to receive more incoming data from the socket.
-void Socket::ReceiveData(uint16_t bytesAvailable)
-{
- if (bytesAvailable != 0)
- {
-// debugPrintf("%u available\n", bytesAvailable);
- // First see if we already have a buffer with enough room
- NetworkBuffer *const lastBuffer = NetworkBuffer::FindLast(receivedData);
- if (lastBuffer != nullptr && (bytesAvailable <= lastBuffer->SpaceLeft() || (lastBuffer->SpaceLeft() != 0 && NetworkBuffer::Count(receivedData) >= MaxBuffersPerSocket)))
- {
- // Read data into the existing buffer
- const size_t maxToRead = min<size_t>(lastBuffer->SpaceLeft(), MaxDataLength);
- const int32_t ret = reprap.GetNetwork().SendCommand(NetworkCommand::connRead, socketNum, 0, nullptr, 0, lastBuffer->UnwrittenData(), maxToRead);
- if (ret > 0 && (size_t)ret <= maxToRead)
- {
- lastBuffer->dataLength += (size_t)ret;
- if (reprap.Debug(moduleNetwork))
- {
- debugPrintf("Received %u bytes\n", (unsigned int)ret);
- }
- }
- }
- else if (NetworkBuffer::Count(receivedData) < MaxBuffersPerSocket)
- {
- NetworkBuffer * const buf = NetworkBuffer::Allocate();
- if (buf != nullptr)
- {
- const size_t maxToRead = min<size_t>(NetworkBuffer::bufferSize, MaxDataLength);
- const int32_t ret = reprap.GetNetwork().SendCommand(NetworkCommand::connRead, socketNum, 0, nullptr, 0, buf->Data(), maxToRead);
- if (ret > 0 && (size_t)ret <= maxToRead)
- {
- buf->dataLength = (size_t)ret;
- NetworkBuffer::AppendToList(&receivedData, buf);
- if (reprap.Debug(moduleNetwork))
- {
- debugPrintf("Received %u bytes\n", (unsigned int)ret);
- }
- }
- else
- {
- buf->Release();
- }
- }
-// else debugPrintf("no buffer\n");
- }
- }
-}
-
-// Discard any received data for this transaction
-void Socket::DiscardReceivedData()
-{
- while (receivedData != nullptr)
- {
- receivedData = receivedData->Release();
- }
-}
-
-// Send the data, returning the length buffered
-size_t Socket::Send(const uint8_t *data, size_t length)
-{
- if (state == SocketState::connected && txBufferSpace != 0)
- {
- const size_t lengthToSend = min<size_t>(length, min<size_t>(txBufferSpace, MaxDataLength));
- const int32_t reply = reprap.GetNetwork().SendCommand(NetworkCommand::connWrite, socketNum, 0, data, lengthToSend, nullptr, 0);
- if (reply >= 0 && (size_t)reply <= lengthToSend)
- {
- txBufferSpace -= (size_t)reply;
- return (size_t)reply;
- }
- if (reprap.Debug(moduleNetwork))
- {
- debugPrintf("Send failed, terminating\n");
- }
- state = SocketState::broken; // something is not right, terminate the socket soon
- }
- return 0;
-}
-
-// Tell the interface to send the outstanding data
-void Socket::Send()
-{
- if (state == SocketState::connected)
- {
- const int32_t reply = reprap.GetNetwork().SendCommand(NetworkCommand::connWrite, socketNum, MessageHeaderSamToEsp::FlagPush, nullptr, 0, nullptr, 0);
- if (reply < 0)
- {
- if (reprap.Debug(moduleNetwork))
- {
- debugPrintf("Send failed, terminating\n");
- }
- state = SocketState::broken; // something is not right, terminate the socket soon
- }
- }
-}
-
-// Return true if we need to poll this socket
-bool Socket::NeedsPolling() const
-{
- return state != SocketState::inactive || needsPolling;
-}
-
-// End
diff --git a/src/Network2/ESP8266/Socket.h b/src/Network2/ESP8266/Socket.h
deleted file mode 100644
index 47cbc780..00000000
--- a/src/Network2/ESP8266/Socket.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * WiFiSocket.h
- *
- * Created on: 22 Apr 2017
- * Author: David
- */
-
-#ifndef SRC_DUETNG_DUETWIFI_SOCKET_H_
-#define SRC_DUETNG_DUETWIFI_SOCKET_H_
-
-#include "RepRapFirmware.h"
-#include "NetworkDefs.h"
-
-class Socket
-{
-public:
- Socket();
- void Init(SocketNumber n);
- int State() const { return (int)state; } // used only for reporting debug info, hence the 'int' return
- void Poll(bool full);
- Port GetLocalPort() const { return localPort; }
- uint32_t GetRemoteIP() const { return remoteIp; }
- Port GetRemotePort() const { return remotePort; }
- void Close();
- void Terminate();
- void TerminatePolitely();
- bool ReadChar(char& c);
- bool ReadBuffer(const uint8_t *&buffer, size_t &len);
- void Taken(size_t len);
- bool CanRead() const;
- bool CanSend() const;
- size_t Send(const uint8_t *data, size_t length);
- void Send();
- void SetNeedsPolling() { needsPolling = true; }
- bool NeedsPolling() const;
-
-private:
- enum class SocketState : uint8_t
- {
- inactive,
- waitingForResponder,
- connected,
- clientDisconnecting,
- closing,
- broken
- };
-
- void ReInit();
- void ReceiveData(uint16_t bytesAvailable);
- void DiscardReceivedData();
-
- Port localPort, remotePort; // The local and remote ports
- Protocol protocol; // What protocol this socket is for
- uint32_t remoteIp; // The remote IP address
- NetworkBuffer *receivedData; // List of buffers holding received data
- uint32_t whenConnected;
- uint16_t txBufferSpace; // How much free transmit buffer space the WiFi mofule reported
- SocketNumber socketNum; // The WiFi socket number we are using
- SocketState state;
- bool needsPolling;
-};
-
-#endif /* SRC_DUETNG_DUETWIFI_SOCKET_H_ */
diff --git a/src/Network2/ESP8266/WifiFirmwareUploader.cpp b/src/Network2/ESP8266/WifiFirmwareUploader.cpp
deleted file mode 100644
index 40861f2c..00000000
--- a/src/Network2/ESP8266/WifiFirmwareUploader.cpp
+++ /dev/null
@@ -1,766 +0,0 @@
-/*
- * EspFirmwareUpload.cpp
- *
- * Created on: 15 Apr 2016
- * Author: David
- */
-
-#include "Network.h"
-#include "WifiFirmwareUploader.h"
-#include "Platform.h"
-#include "RepRap.h"
-#include "Storage/FileStore.h"
-
-// ESP8266 command codes
-const uint8_t ESP_FLASH_BEGIN = 0x02;
-const uint8_t ESP_FLASH_DATA = 0x03;
-const uint8_t ESP_FLASH_END = 0x04;
-const uint8_t ESP_MEM_BEGIN = 0x05;
-const uint8_t ESP_MEM_END = 0x06;
-const uint8_t ESP_MEM_DATA = 0x07;
-const uint8_t ESP_SYNC = 0x08;
-const uint8_t ESP_WRITE_REG = 0x09;
-const uint8_t ESP_READ_REG = 0x0a;
-
-// MAC address storage locations
-const uint32_t ESP_OTP_MAC0 = 0x3ff00050;
-const uint32_t ESP_OTP_MAC1 = 0x3ff00054;
-const uint32_t ESP_OTP_MAC2 = 0x3ff00058;
-const uint32_t ESP_OTP_MAC3 = 0x3ff0005c;
-
-const size_t EspFlashBlockSize = 0x0400; // 1K byte blocks
-
-const uint8_t ESP_IMAGE_MAGIC = 0xe9;
-const uint8_t ESP_CHECKSUM_MAGIC = 0xef;
-
-const uint32_t ESP_ERASE_CHIP_ADDR = 0x40004984; // &SPIEraseChip
-const uint32_t ESP_SEND_PACKET_ADDR = 0x40003c80; // &send_packet
-const uint32_t ESP_SPI_READ_ADDR = 0x40004b1c; // &SPIRead
-const uint32_t ESP_UNKNOWN_ADDR = 0x40001121; // not used
-const uint32_t ESP_USER_DATA_RAM_ADDR = 0x3ffe8000; // &user data ram
-const uint32_t ESP_IRAM_ADDR = 0x40100000; // instruction RAM
-const uint32_t ESP_FLASH_ADDR = 0x40200000; // address of start of Flash
-const uint32_t ESP_FLASH_READ_STUB_BEGIN = IRAM_ADDR + 0x18;
-
-// Messages corresponding to result codes, should make sense when followed by " error"
-const char * const resultMessages[] =
-{
- "no",
- "timeout",
- "comm write",
- "connect",
- "bad reply",
- "file read",
- "empty file",
- "response header",
- "slip frame",
- "slip state",
- "slip data"
-};
-
-// A note on baud rates.
-// The ESP8266 supports 921600, 460800, 230400, 115200, 74880 and some lower baud rates.
-// 921600b is not reliable because even though it sometimes succeeds in connecting, we get a bad response during uploading after a few blocks.
-// Probably our UART ISR cannot receive bytes fast enough, perhaps because of the latency of the system tick ISR.
-// 460800b doesn't always manage to connect, but if it does then uploading appears to be reliable.
-// 230400b always manages to connect.
-static const uint32_t uploadBaudRates[] = { 230400, 115200, 74880, 9600 };
-
-WifiFirmwareUploader::WifiFirmwareUploader(UARTClass& port)
- : uploadPort(port), uploadFile(nullptr), state(UploadState::idle)
-{
-}
-
-bool WifiFirmwareUploader::IsReady() const
-{
- return state == UploadState::idle;
-}
-
-void WifiFirmwareUploader::MessageF(const char *fmt, ...)
-{
- va_list vargs;
- va_start(vargs, fmt);
- reprap.GetPlatform().MessageF(FirmwareUpdateMessage, fmt, vargs);
- va_end(vargs);
-}
-
-void WifiFirmwareUploader::flushInput()
-{
- while (uploadPort.available() != 0)
- {
- (void)uploadPort.read();
- }
-}
-
-// Extract 1-4 bytes of a value in little-endian order from a buffer beginning at a specified offset
-uint32_t WifiFirmwareUploader::getData(unsigned byteCnt, const uint8_t *buf, int ofst)
-{
- uint32_t val = 0;
-
- if (buf && byteCnt)
- {
- unsigned int shiftCnt = 0;
- if (byteCnt > 4)
- byteCnt = 4;
- do
- {
- val |= (uint32_t)buf[ofst++] << shiftCnt;
- shiftCnt += 8;
- } while (--byteCnt);
- }
- return(val);
-}
-
-// Put 1-4 bytes of a value in little-endian order into a buffer beginning at a specified offset.
-void WifiFirmwareUploader::putData(uint32_t val, unsigned byteCnt, uint8_t *buf, int ofst)
-{
- if (buf && byteCnt)
- {
- if (byteCnt > 4)
- {
- byteCnt = 4;
- }
- do
- {
- buf[ofst++] = (uint8_t)(val & 0xff);
- val >>= 8;
- } while (--byteCnt);
- }
-}
-
-// Read a byte optionally performing SLIP decoding. The return values are:
-//
-// 2 - an escaped byte was read successfully
-// 1 - a non-escaped byte was read successfully
-// 0 - no data was available
-// -1 - the value 0xc0 was encountered (shouldn't happen)
-// -2 - a SLIP escape byte was found but the following byte wasn't available
-// -3 - a SLIP escape byte was followed by an invalid byte
-int WifiFirmwareUploader::ReadByte(uint8_t& data, bool slipDecode)
-{
- if (uploadPort.available() == 0)
- {
- return(0);
- }
-
- // at least one byte is available
- data = uploadPort.read();
- if (!slipDecode)
- {
- return(1);
- }
-
- if (data == 0xc0)
- {
- // this shouldn't happen
- return(-1);
- }
-
- // if not the SLIP escape, we're done
- if (data != 0xdb)
- {
- return(1);
- }
-
- // SLIP escape, check availability of subsequent byte
- if (uploadPort.available() == 0)
- {
- return(-2);
- }
-
- // process the escaped byte
- data = uploadPort.read();
- if (data == 0xdc)
- {
- data = 0xc0;
- return(2);
- }
-
- if (data == 0xdd)
- {
- data = 0xdb;
- return(2);
- }
- // invalid
- return(-3);
-}
-
-// When we write a sync packet, there must be no gaps between most of the characters.
-// So use this function, which does a block write to the UART buffer in the latest CoreNG.
-void WifiFirmwareUploader::writePacketRaw(const uint8_t *buf, size_t len)
-{
- uploadPort.write(buf, len);
-}
-
-// Write a byte to the serial port optionally SLIP encoding. Return the number of bytes actually written.
-inline void WifiFirmwareUploader::WriteByteRaw(uint8_t b)
-{
- uploadPort.write(b);
-}
-
-// Write a byte to the serial port optionally SLIP encoding. Return the number of bytes actually written.
-inline void WifiFirmwareUploader::WriteByteSlip(uint8_t b)
-{
- if (b == 0xC0)
- {
- WriteByteRaw(0xDB);
- WriteByteRaw(0xDC);
- }
- else if (b == 0xDB)
- {
- WriteByteRaw(0xDB);
- WriteByteRaw(0xDD);
- }
- else
- {
- uploadPort.write(b);
- }
-}
-
-// Wait for a data packet to be returned. If the body of the packet is
-// non-zero length, return an allocated buffer indirectly containing the
-// data and return the data length. Note that if the pointer for returning
-// the data buffer is NULL, the response is expected to be two bytes of zero.
-//
-// If an error occurs, return a negative value. Otherwise, return the number
-// of bytes in the response (or zero if the response was not the standard "two bytes of zero").
-WifiFirmwareUploader::EspUploadResult WifiFirmwareUploader::readPacket(uint8_t op, uint32_t *valp, size_t& bodyLen, uint32_t msTimeout)
-{
- enum class PacketState
- {
- begin = 0,
- header,
- body,
- end,
- done
- };
-
- const size_t headerLength = 8;
-
- uint32_t startTime = millis();
- uint8_t hdr[headerLength];
- uint16_t hdrIdx = 0;
- bodyLen = 0;
- uint16_t bodyIdx = 0;
- uint8_t respBuf[2];
-
- // wait for the response
- uint16_t needBytes = 1;
- PacketState state = PacketState::begin;
- while (state != PacketState::done)
- {
- uint8_t c;
- EspUploadResult stat;
-
- if (millis() - startTime > msTimeout)
- {
- return(EspUploadResult::timeout);
- }
-
- if (uploadPort.available() < needBytes)
- {
- // insufficient data available
- // preferably, return to Spin() here
- continue;
- }
-
- // sufficient bytes have been received for the current state, process them
- switch(state)
- {
- case PacketState::begin: // expecting frame start
- case PacketState::end: // expecting frame end
- c = uploadPort.read();
- if (c != 0xc0)
- {
- return EspUploadResult::slipFrame;
- }
- if (state == PacketState::begin)
- {
- state = PacketState::header;
- needBytes = 2;
- }
- else
- {
- state = PacketState::done;
- }
- break;
-
- case PacketState::header: // reading an 8-byte header
- case PacketState::body: // reading the response body
- {
- int rslt;
- // retrieve a byte with SLIP decoding
- rslt = ReadByte(c, true);
- if (rslt != 1 && rslt != 2)
- {
- // some error occurred
- stat = (rslt == 0 || rslt == -2) ? EspUploadResult::slipData : EspUploadResult::slipFrame;
- return stat;
- }
- else if (state == PacketState::header)
- {
- //store the header byte
- hdr[hdrIdx++] = c;
- if (hdrIdx >= headerLength)
- {
- // get the body length, prepare a buffer for it
- bodyLen = (uint16_t)getData(2, hdr, 2);
-
- // extract the value, if requested
- if (valp != nullptr)
- {
- *valp = getData(4, hdr, 4);
- }
-
- if (bodyLen != 0)
- {
- state = PacketState::body;
- }
- else
- {
- needBytes = 1;
- state = PacketState::end;
- }
- }
- }
- else
- {
- // Store the response body byte, check for completion
- if (bodyIdx < ARRAY_SIZE(respBuf))
- {
- respBuf[bodyIdx] = c;
- }
- ++bodyIdx;
- if (bodyIdx >= bodyLen)
- {
- needBytes = 1;
- state = PacketState::end;
- }
- }
- }
- break;
-
- default: // this shouldn't happen
- return EspUploadResult::slipState;
- }
- }
-
- // Extract elements from the header
- const uint8_t resp = (uint8_t)getData(1, hdr, 0);
- const uint8_t opRet = (uint8_t)getData(1, hdr, 1);
- // Sync packets often provoke a response with a zero opcode instead of ESP_SYNC
- if (resp != 0x01 || opRet != op)
- {
-//debugPrintf("resp %02x %02x\n", resp, opRet);
- return EspUploadResult::respHeader;
- }
-
- return EspUploadResult::success;
-}
-
-// Send a block of data performing SLIP encoding of the content.
-inline void WifiFirmwareUploader::writePacket(const uint8_t *data, size_t len)
-{
- while (len != 0)
- {
- WriteByteSlip(*data++);
- --len;
- }
-}
-
-// Send a packet to the serial port while performing SLIP framing. The packet data comprises a header and an optional data block.
-// A SLIP packet begins and ends with 0xc0. The data encapsulated has the bytes
-// 0xc0 and 0xdb replaced by the two-byte sequences {0xdb, 0xdc} and {0xdb, 0xdd} respectively.
-void WifiFirmwareUploader::writePacket(const uint8_t *hdr, size_t hdrLen, const uint8_t *data, size_t dataLen)
-{
- WriteByteRaw(0xc0); // send the packet start character
- writePacket(hdr, hdrLen); // send the header
- writePacket(data, dataLen); // send the data block
- WriteByteRaw(0xc0); // send the packet end character
-}
-
-// Send a packet to the serial port while performing SLIP framing. The packet data comprises a header and an optional data block.
-// This is like writePacket except that it does a fast block write for both the header and the main data with no SLIP encoding. Used to send sync commands.
-void WifiFirmwareUploader::writePacketRaw(const uint8_t *hdr, size_t hdrLen, const uint8_t *data, size_t dataLen)
-{
- WriteByteRaw(0xc0); // send the packet start character
- writePacketRaw(hdr, hdrLen); // send the header
- writePacketRaw(data, dataLen); // send the data block in raw mode
- WriteByteRaw(0xc0); // send the packet end character
-}
-
-// Send a command to the attached device together with the supplied data, if any.
-// The data is supplied via a list of one or more segments.
-void WifiFirmwareUploader::sendCommand(uint8_t op, uint32_t checkVal, const uint8_t *data, size_t dataLen)
-{
- // populate the header
- uint8_t hdr[8];
- putData(0, 1, hdr, 0);
- putData(op, 1, hdr, 1);
- putData(dataLen, 2, hdr, 2);
- putData(checkVal, 4, hdr, 4);
-
- // send the packet
- flushInput();
- if (op == ESP_SYNC)
- {
- writePacketRaw(hdr, sizeof(hdr), data, dataLen);
- }
- else
- {
- writePacket(hdr, sizeof(hdr), data, dataLen);
- }
-}
-
-// Send a command to the attached device together with the supplied data, if any, and get the response
-WifiFirmwareUploader::EspUploadResult WifiFirmwareUploader::doCommand(uint8_t op, const uint8_t *data, size_t dataLen, uint32_t checkVal, uint32_t *valp, uint32_t msTimeout)
-{
- sendCommand(op, checkVal, data, dataLen);
- size_t bodyLen;
- EspUploadResult stat = readPacket(op, valp, bodyLen, msTimeout);
- if (stat == EspUploadResult::success && bodyLen != 2)
- {
- stat = EspUploadResult::badReply;
- }
-
- return stat;
-}
-
-// Send a synchronising packet to the serial port in an attempt to induce
-// the ESP8266 to auto-baud lock on the baud rate.
-WifiFirmwareUploader::EspUploadResult WifiFirmwareUploader::Sync(uint16_t timeout)
-{
- uint8_t buf[36];
-
- // compose the data for the sync attempt
- memset(buf, 0x55, sizeof(buf));
- buf[0] = 0x07;
- buf[1] = 0x07;
- buf[2] = 0x12;
- buf[3] = 0x20;
-
- EspUploadResult stat = doCommand(ESP_SYNC, buf, sizeof(buf), 0, nullptr, timeout);
-
- // If we got a response other than sync, discard it and wait for a sync response. This happens at higher baud rates.
- for (int i = 0; i < 10 && stat == EspUploadResult::respHeader; ++i)
- {
- size_t bodyLen;
- stat = readPacket(ESP_SYNC, nullptr, bodyLen, timeout);
- }
-
- if (stat == EspUploadResult::success)
- {
- // Read and discard additional replies
- for (;;)
- {
- size_t bodyLen;
- EspUploadResult rc = readPacket(ESP_SYNC, nullptr, bodyLen, defaultTimeout);
- if (rc != EspUploadResult::success || bodyLen != 2)
- {
- break;
- }
- }
- }
-//DEBUG
-// else debugPrintf("stat=%d\n", (int)stat);
- return stat;
-}
-
-// Send a command to the device to begin the Flash process.
-WifiFirmwareUploader::EspUploadResult WifiFirmwareUploader::flashBegin(uint32_t addr, uint32_t size)
-{
- // determine the number of blocks represented by the size
- const uint32_t blkCnt = (size + EspFlashBlockSize - 1) / EspFlashBlockSize;
-
- // ensure that the address is on a block boundary
- addr &= ~(EspFlashBlockSize - 1);
-
- // begin the Flash process
- uint8_t buf[16];
- putData(size, 4, buf, 0);
- putData(blkCnt, 4, buf, 4);
- putData(EspFlashBlockSize, 4, buf, 8);
- putData(addr, 4, buf, 12);
-
- uint32_t timeout = (size != 0) ? eraseTimeout : defaultTimeout;
- return doCommand(ESP_FLASH_BEGIN, buf, sizeof(buf), 0, nullptr, timeout);
-}
-
-// Send a command to the device to terminate the Flash process
-WifiFirmwareUploader::EspUploadResult WifiFirmwareUploader::flashFinish(bool reboot)
-{
- uint8_t buf[4];
- putData(reboot ? 0 : 1, 4, buf, 0);
- return doCommand(ESP_FLASH_END, buf, sizeof(buf), 0, nullptr, defaultTimeout);
-}
-
-// Compute the checksum of a block of data
-uint16_t WifiFirmwareUploader::checksum(const uint8_t *data, uint16_t dataLen, uint16_t cksum)
-{
- if (data != NULL)
- {
- while (dataLen--)
- {
- cksum ^= (uint16_t)*data++;
- }
- }
- return(cksum);
-}
-
-WifiFirmwareUploader::EspUploadResult WifiFirmwareUploader::flashWriteBlock(uint16_t flashParmVal, uint16_t flashParmMask)
-{
- const uint32_t blkSize = EspFlashBlockSize;
-
- // Allocate a data buffer for the combined header and block data
- const uint16_t hdrOfst = 0;
- const uint16_t dataOfst = 16;
- const uint16_t blkBufSize = dataOfst + blkSize;
- uint32_t blkBuf32[blkBufSize/4];
- uint8_t * const blkBuf = reinterpret_cast<uint8_t*>(blkBuf32);
-
- // Prepare the header for the block
- putData(blkSize, 4, blkBuf, hdrOfst + 0);
- putData(uploadBlockNumber, 4, blkBuf, hdrOfst + 4);
- putData(0, 4, blkBuf, hdrOfst + 8);
- putData(0, 4, blkBuf, hdrOfst + 12);
-
- // Get the data for the block
- size_t cnt = uploadFile->Read(reinterpret_cast<char *>(blkBuf + dataOfst), blkSize);
- if (cnt != blkSize)
- {
- if (uploadFile->Position() == fileSize)
- {
- // partial last block, fill the remainder
- memset(blkBuf + dataOfst + cnt, 0xff, blkSize - cnt);
- }
- else
- {
- return EspUploadResult::fileRead;
- }
- }
-
- // Patch the flash parameters into the first block if it is loaded at address 0
- if (uploadBlockNumber == 0 && uploadAddress == 0 && blkBuf[dataOfst] == ESP_IMAGE_MAGIC && flashParmMask != 0)
- {
- // update the Flash parameters
- uint32_t flashParm = getData(2, blkBuf + dataOfst + 2, 0) & ~(uint32_t)flashParmMask;
- putData(flashParm | flashParmVal, 2, blkBuf + dataOfst + 2, 0);
- }
-
- // Calculate the block checksum
- uint16_t cksum = checksum(blkBuf + dataOfst, blkSize, ESP_CHECKSUM_MAGIC);
- EspUploadResult stat;
- for (int i = 0; i < 3; i++)
- {
- if ((stat = doCommand(ESP_FLASH_DATA, blkBuf, blkBufSize, cksum, nullptr, blockWriteTimeout)) == EspUploadResult::success)
- {
- break;
- }
- }
-
- return stat;
-}
-
-WifiFirmwareUploader::EspUploadResult WifiFirmwareUploader::DoErase(uint32_t address, uint32_t size)
-{
- const uint32_t sectorsPerBlock = 16;
- const uint32_t sectorSize = 4096;
- const uint32_t numSectors = (size + sectorSize - 1)/sectorSize;
- const uint32_t startSector = address/sectorSize;
- uint32_t headSectors = sectorsPerBlock - (startSector % sectorsPerBlock);
-
- if (numSectors < headSectors)
- {
- headSectors = numSectors;
- }
- const uint32_t eraseSize = (numSectors < 2 * headSectors)
- ? (numSectors + 1) / 2 * sectorSize
- : (numSectors - headSectors) * sectorSize;
-
- MessageF("Erasing %u bytes...\n", eraseSize);
- return flashBegin(uploadAddress, eraseSize);
-}
-
-void WifiFirmwareUploader::Spin()
-{
- switch (state)
- {
- case UploadState::resetting:
- if (connectAttemptNumber == ARRAY_SIZE(uploadBaudRates) * retriesPerBaudRate)
- {
- // Time to give up
- reprap.GetNetwork().ResetWiFi();
- uploadResult = EspUploadResult::connect;
- state = UploadState::done;
- }
- else
- {
- // Reset the serial port at the new baud rate. Also reset the ESP8266.
- const uint32_t baud = uploadBaudRates[connectAttemptNumber/retriesPerBaudRate];
- if (connectAttemptNumber % retriesPerBaudRate == 0)
- {
- // First attempt at this baud rate
- MessageF("Trying to connect at %u baud: ", baud);
- }
- uploadPort.begin(baud);
- uploadPort.setInterruptPriority(1); // we are going to move data at seriously high speeds
- reprap.GetNetwork().ResetWiFiForUpload(false);
- lastAttemptTime = lastResetTime = millis();
- state = UploadState::connecting;
- }
- break;
-
- case UploadState::connecting:
- if (millis() - lastAttemptTime >= connectAttemptInterval && millis() - lastResetTime >= resetDelay)
- {
- // Attempt to establish a connection to the ESP8266.
- EspUploadResult res = Sync(syncTimeout);
- lastAttemptTime = millis();
- if (res == EspUploadResult::success)
- {
- // Successful connection
-// MessageF(" success on attempt %d\n", (connectAttemptNumber % retriesPerBaudRate) + 1);
- MessageF(" success\n");
- state = UploadState::erasing1;
- }
- else
- {
- // This attempt failed
- ++connectAttemptNumber;
- if (connectAttemptNumber % retriesPerReset == 0)
- {
- if (connectAttemptNumber % retriesPerBaudRate == 0)
- {
- MessageF(" failed\n");
- }
- state = UploadState::resetting; // try a reset and a lower baud rate
- }
- }
- }
- break;
-
- case UploadState::erasing1:
- if (millis() - lastAttemptTime >= blockWriteInterval)
- {
- uploadResult = DoErase(systemParametersAddress, systemParametersSize);
- if (uploadResult == EspUploadResult::success)
- {
- state = UploadState::erasing2;
- }
- else
- {
- MessageF("Erase failed\n");
- state = UploadState::done;
- }
- }
- break;
-
- case UploadState::erasing2:
- if (millis() - lastAttemptTime >= blockWriteInterval)
- {
- uploadResult = DoErase(uploadAddress, fileSize);
- if (uploadResult == EspUploadResult::success)
- {
- MessageF("Uploading file...\n");
- uploadBlockNumber = 0;
- uploadNextPercentToReport = percentToReportIncrement;
- lastAttemptTime = millis();
- state = UploadState::uploading;
- }
- else
- {
- MessageF("Erase failed\n");
- state = UploadState::done;
- }
- }
- break;
-
- case UploadState::uploading:
- // The ESP needs several milliseconds to recover from one packet before it will accept another
- if (millis() - lastAttemptTime >= blockWriteInterval)
- {
- const uint32_t blkCnt = (fileSize + EspFlashBlockSize - 1) / EspFlashBlockSize;
- if (uploadBlockNumber < blkCnt)
- {
- uploadResult = flashWriteBlock(0, 0);
- lastAttemptTime = millis();
- if (uploadResult != EspUploadResult::success)
- {
- MessageF("Flash block upload failed\n");
- state = UploadState::done;
- }
- const unsigned int percentComplete = (100 * uploadBlockNumber)/blkCnt;
- ++uploadBlockNumber;
- if (percentComplete >= uploadNextPercentToReport)
- {
- MessageF("%u%% complete\n", percentComplete);
- uploadNextPercentToReport += percentToReportIncrement;
- }
- }
- else
- {
- state = UploadState::done;
- }
- }
- break;
-
- case UploadState::done:
- uploadFile->Close();
- uploadPort.end(); // disable the port, it has a high interrupt priority
- if (uploadResult == EspUploadResult::success)
- {
- reprap.GetPlatform().Message(FirmwareUpdateMessage, "Upload successful\n");
- if (restartModeOnCompletion == 1)
- {
- reprap.GetNetwork().Start();
- }
- else
- {
- reprap.GetNetwork().ResetWiFi();
- }
- }
- else
- {
- MessageF("Error: Installation failed due to %s error\n", resultMessages[(size_t)uploadResult]);
- // Not safe to restart the network
- reprap.GetNetwork().ResetWiFi();
- }
- state = UploadState::idle;
- break;
-
- default:
- break;
- }
-}
-
-// Try to upload the given file at the given address
-void WifiFirmwareUploader::SendUpdateFile(const char *file, const char *dir, uint32_t address)
-{
- Platform& platform = reprap.GetPlatform();
- uploadFile = platform.OpenFile(dir, file, OpenMode::read);
- if (uploadFile == nullptr)
- {
- MessageF("Failed to open file %s\n", file);
- return;
- }
-
- fileSize = uploadFile->Length();
- if (fileSize == 0)
- {
- uploadFile->Close();
- MessageF("Upload file is empty %s\n", file);
- return;
- }
-
- // Stop the network
- Network& network = reprap.GetNetwork();
- restartModeOnCompletion = network.EnableState();
- network.Stop();
-
- // Set up the state so that subsequent calls to Spin() will attempt the upload
- uploadAddress = address;
- connectAttemptNumber = 0;
- state = UploadState::resetting;
-}
-
-// End
diff --git a/src/Network2/ESP8266/WifiFirmwareUploader.h b/src/Network2/ESP8266/WifiFirmwareUploader.h
deleted file mode 100644
index 1fd4195b..00000000
--- a/src/Network2/ESP8266/WifiFirmwareUploader.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * EspFirmwareUpload.h
- *
- * Created on: 15 Apr 2016
- * Author: David
- */
-
-#ifndef SRC_DUETNG_WIFIFIRMWAREUPLOADER_H_
-#define SRC_DUETNG_WIFIFIRMWAREUPLOADER_H_
-
-#include "RepRapFirmware.h"
-
-class WifiFirmwareUploader
-{
-public:
- WifiFirmwareUploader(UARTClass& port);
- bool IsReady() const;
- void SendUpdateFile(const char *file, const char *dir, uint32_t address);
- void Spin();
-
- static const uint32_t FirmwareAddress = 0x00000000;
- static const uint32_t WebFilesAddress = 0x00100000;
-
-private:
- static const uint32_t defaultTimeout = 500; // default timeout in milliseconds
- static const uint32_t syncTimeout = 1000;
- static const unsigned int retriesPerBaudRate = 9;
- static const unsigned int retriesPerReset = 3;
- static const uint32_t connectAttemptInterval = 50;
- static const uint32_t resetDelay = 500;
- static const uint32_t blockWriteInterval = 15; // 15ms is long enough, 10ms is mostly too short
- static const uint32_t blockWriteTimeout = 200;
- static const uint32_t eraseTimeout = 15000; // increased from 12 to 15 seconds because Roland's board was timing out
- static const unsigned int percentToReportIncrement = 5; // how often we report % complete
- static const uint32_t systemParametersAddress = 0x3FE000; // the address of the system + user parameter area that needs to be cleared when changing SDK version
- static const uint32_t systemParametersSize = 0x2000; // the size of the system + user parameter area
-
- // Return codes - this list must be kept in step with the corresponding messages
- enum class EspUploadResult
- {
- success = 0,
- timeout,
- connect,
- badReply,
- fileRead,
- emptyFile,
- respHeader,
- slipFrame,
- slipState,
- slipData,
- };
-
- enum class UploadState
- {
- idle,
- resetting,
- connecting,
- erasing1,
- erasing2,
- uploading,
- done
- };
-
- void MessageF(const char *fmt, ...);
- uint32_t getData(unsigned byteCnt, const uint8_t *buf, int ofst);
- void putData(uint32_t val, unsigned byteCnt, uint8_t *buf, int ofst);
- int ReadByte(uint8_t& data, bool slipDecode);
- void WriteByteRaw(uint8_t b);
- void WriteByteSlip(uint8_t b);
- void flushInput();
- EspUploadResult readPacket(uint8_t op, uint32_t *valp, size_t& bodyLen, uint32_t msTimeout);
- void writePacket(const uint8_t *data, size_t len);
- void writePacketRaw(const uint8_t *buf, size_t len);
- void writePacket(const uint8_t *hdr, size_t hdrLen, const uint8_t *data, size_t dataLen);
- void writePacketRaw(const uint8_t *hdr, size_t hdrLen, const uint8_t *data, size_t dataLen);
- void sendCommand(uint8_t op, uint32_t checkVal, const uint8_t *data, size_t dataLen);
- EspUploadResult doCommand(uint8_t op, const uint8_t *data, size_t dataLen, uint32_t checkVal, uint32_t *valp, uint32_t msTimeout);
- EspUploadResult Sync(uint16_t timeout);
- EspUploadResult flashBegin(uint32_t addr, uint32_t size);
- EspUploadResult flashFinish(bool reboot);
- static uint16_t checksum(const uint8_t *data, uint16_t dataLen, uint16_t cksum);
- EspUploadResult flashWriteBlock(uint16_t flashParmVal, uint16_t flashParmMask);
- EspUploadResult DoErase(uint32_t address, uint32_t size);
-
- UARTClass& uploadPort;
- FileStore *uploadFile;
- FilePosition fileSize;
- uint32_t uploadAddress;
- uint32_t uploadBlockNumber;
- unsigned int uploadNextPercentToReport;
- unsigned int connectAttemptNumber;
- uint32_t lastAttemptTime;
- uint32_t lastResetTime;
- UploadState state;
- EspUploadResult uploadResult;
- int restartModeOnCompletion;
-};
-
-#endif /* SRC_DUETNG_WIFIFIRMWAREUPLOADER_H_ */
diff --git a/src/Network2/FirmwareUpdater.cpp b/src/Network2/FirmwareUpdater.cpp
deleted file mode 100644
index 324894db..00000000
--- a/src/Network2/FirmwareUpdater.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * FirmwareUpdater.cpp
- *
- * Created on: 21 May 2016
- * Author: David
- */
-
-#include "FirmwareUpdater.h"
-
-#include "RepRapFirmware.h"
-#include "Network.h"
-#include "Platform.h"
-#include "RepRap.h"
-
-#ifdef DUET_WIFI
-#include "WifiFirmwareUploader.h"
-#endif
-
-namespace FirmwareUpdater
-{
- const unsigned int WifiFirmwareModule = 1;
- const unsigned int WifiFilesModule = 2;
- const unsigned int WifiExternalFirmwareModule = 3;
-
- // Check that the prerequisites are satisfied.
- // Return true if yes, else print a message and return false.
- bool CheckFirmwareUpdatePrerequisites(uint8_t moduleMap, const StringRef& reply)
- {
-#ifdef DUET_WIFI
- if ((moduleMap & (1 << WifiExternalFirmwareModule)) != 0 && (moduleMap & ((1 << WifiFirmwareModule) | (1 << WifiFilesModule))) != 0)
- {
- reply.copy("Invalid combination of firmware update modules");
- return false;
- }
- if ((moduleMap & (1 << WifiFirmwareModule)) != 0 && !reprap.GetPlatform().GetMassStorage()->FileExists(SYS_DIR, WIFI_FIRMWARE_FILE))
- {
- reply.printf("File %s not found", WIFI_FIRMWARE_FILE);
- return false;
- }
- if ((moduleMap & (1 << WifiFilesModule)) != 0 && !reprap.GetPlatform().GetMassStorage()->FileExists(SYS_DIR, WIFI_WEB_FILE))
- {
- reply.printf("File %s not found", WIFI_WEB_FILE);
- return false;
- }
-#endif
- return true;
- }
-
- bool IsReady()
- {
-#ifdef DUET_WIFI
- return reprap.GetNetwork().GetWifiUploader().IsReady();
-#else
- return true;
-#endif
- }
-
- void UpdateModule(unsigned int module)
- {
-#ifdef DUET_WIFI
- switch(module)
- {
- case WifiExternalFirmwareModule:
- reprap.GetNetwork().ResetWiFiForUpload(true);
- break;
-
- case WifiFirmwareModule:
- reprap.GetNetwork().GetWifiUploader().SendUpdateFile(WIFI_FIRMWARE_FILE, SYS_DIR, WifiFirmwareUploader::FirmwareAddress);
- break;
-
- case WifiFilesModule:
- reprap.GetNetwork().GetWifiUploader().SendUpdateFile(WIFI_WEB_FILE, SYS_DIR, WifiFirmwareUploader::WebFilesAddress);
- break;
- }
-#endif
- }
-}
-
-// End
diff --git a/src/Network2/FirmwareUpdater.h b/src/Network2/FirmwareUpdater.h
deleted file mode 100644
index 82104e73..00000000
--- a/src/Network2/FirmwareUpdater.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * FirmwareUpdater.h
- *
- * Created on: 21 May 2016
- * Author: David
- */
-
-#ifndef SRC_DUETNG_FIRMWAREUPDATER_H_
-#define SRC_DUETNG_FIRMWAREUPDATER_H_
-
-#include <cstdint>
-#include "Libraries/General/StringRef.h"
-
-namespace FirmwareUpdater
-{
- bool CheckFirmwareUpdatePrerequisites(uint8_t moduleMap, const StringRef& reply);
- bool IsReady();
- void UpdateModule(unsigned int module);
-}
-
-#endif /* SRC_DUETNG_FIRMWAREUPDATER_H_ */
diff --git a/src/Network2/FtpResponder.cpp b/src/Network2/FtpResponder.cpp
deleted file mode 100644
index 82c01ac6..00000000
--- a/src/Network2/FtpResponder.cpp
+++ /dev/null
@@ -1,911 +0,0 @@
-/*
- * FtpResponder.cpp
- *
- * Created on: 15 Apr 2017
- * Authors: David and Christian
- */
-
-#include "FtpResponder.h"
-#include "Network.h"
-#include "Platform.h"
-
-FtpResponder::FtpResponder(NetworkResponder *n) : NetworkResponder(n), dataSocket(nullptr),
- passivePort(0), passivePortOpenTime(0), dataBuf(nullptr)
-{
- strcpy(fileToMove, "");
-}
-
-// Ask the responder to accept this connection, returns true if it did
-bool FtpResponder::Accept(Socket *s, Protocol protocol)
-{
- if (responderState == ResponderState::free && protocol == FtpProtocol)
- {
- // Make sure we can get an output buffer before we accept the connection, or we won't be able to reply
- if (outBuf != nullptr || OutputBuffer::Allocate(outBuf))
- {
- clientPointer = 0;
- skt = s;
- if (reprap.Debug(moduleWebserver))
- {
- debugPrintf("FTP connection accepted\n");
- }
-
- outBuf->copy("220 RepRapFirmware FTP server\r\n");
- Commit(ResponderState::authenticating);
- return true;
- }
- }
- else if (responderState == ResponderState::waitingForPasvPort && protocol == FtpDataProtocol && s->GetLocalPort() == passivePort)
- {
- dataSocket = s;
- responderState = ResponderState::pasvPortOpened;
-
- if (reprap.Debug(moduleWebserver))
- {
- debugPrintf("FTP data connection accepted\n");
- }
- return true;
- }
- return false;
-}
-
-// This is called to force termination if we implement the specified protocol
-void FtpResponder::Terminate(Protocol protocol)
-{
- if (responderState != ResponderState::free && (protocol == FtpProtocol || protocol == AnyProtocol))
- {
- ConnectionLost();
- }
-}
-
-// Do some work, returning true if we did anything significant
-bool FtpResponder::Spin()
-{
- switch (responderState)
- {
- case ResponderState::free:
- return false;
-
- case ResponderState::authenticating:
- case ResponderState::reading:
- return ReadData();
-
- case ResponderState::sending:
- SendData();
- return true;
-
- case ResponderState::waitingForPasvPort:
- if (millis() - passivePortOpenTime > ftpPasvPortTimeout && (outBuf != nullptr || OutputBuffer::Allocate(outBuf)))
- {
- outBuf->copy("425 Failed to establish connection.\r\n");
- Commit(ResponderState::reading);
-
- CloseDataPort();
- return true;
- }
- return false;
-
- case ResponderState::pasvPortOpened:
- if (dataBuf != nullptr || OutputBuffer::Allocate(dataBuf))
- {
- return ReadData();
- }
- return false;
-
- case ResponderState::uploading:
- DoUpload();
-
- if (!uploadError && skt->CanRead())
- {
- ReadData(); // check for incoming ABOR requests
- }
- return true;
-
- case ResponderState::sendingPasvData:
- SendPassiveData();
-
- if (!sendError && skt->CanRead())
- {
- ReadData(); // check for incoming ABOR requests
- }
- return true;
-
- case ResponderState::pasvTransferComplete:
- if (outBuf != nullptr || OutputBuffer::Allocate(outBuf))
- {
- // Is the main FTP connection still available?
- if (skt->CanSend())
- {
- // Yes - send a response
- if (uploadError || sendError)
- {
- outBuf->copy("526 Transfer failed!\r\n");
- }
- else
- {
- outBuf->copy("226 Transfer complete.\r\n");
- }
- Commit(ResponderState::reading);
-
- // Close the data port again
- CloseDataPort();
- }
- else
- {
- // No - reset our state
- ConnectionLost();
- }
-
- return true;
- }
- return false;
-
- default: // should not happen
- return false;
- }
-}
-
-void FtpResponder::Diagnostics(MessageType mt) const
-{
- GetPlatform().MessageF(mt, " FTP(%d)", (int)responderState);
-}
-
-// This must be called only for the main FTP port
-void FtpResponder::ConnectionLost()
-{
- CloseDataPort();
- NetworkResponder::ConnectionLost();
-}
-
-// Send our data over the main FTP port.
-// We send outBuf first and then outStack. fileBeingSent is reserved for the data port.
-void FtpResponder::SendData()
-{
- // Send our output buffer and output stack
- for(;;)
- {
- if (outBuf == nullptr)
- {
- outBuf = outStack->Pop();
- if (outBuf == nullptr)
- {
- break;
- }
- }
- const size_t bytesLeft = outBuf->BytesLeft();
- if (bytesLeft == 0)
- {
- outBuf = OutputBuffer::Release(outBuf);
- }
- else
- {
- const size_t sent = skt->Send(reinterpret_cast<const uint8_t *>(outBuf->UnreadData()), bytesLeft);
- if (sent == 0)
- {
- // Check whether the connection has been closed
- if (!skt->CanSend())
- {
- // The connection has been lost or the other end has closed it
- if (reprap.Debug(moduleWebserver))
- {
- debugPrintf("Can't send anymore\n");
- }
- ConnectionLost();
- }
- return;
- }
-
- outBuf->Taken(sent); // tell the output buffer how much data we have taken
- if (sent < bytesLeft)
- {
- return;
- }
- outBuf = OutputBuffer::Release(outBuf);
- }
- }
-
- // If we get here then there is nothing left to send
- skt->Send(); // tell the socket there is no more data
-
- // If we are going to free up this responder after sending, then we must close the connection
- if (stateAfterSending == ResponderState::free)
- {
- skt->Close();
- skt = nullptr;
- }
- responderState = stateAfterSending;
-}
-
-// Send our data over the passive FTP data port.
-// We send dataBuf first and then fileBeingSent.
-void FtpResponder::SendPassiveData()
-{
- // Send our output buffers
- while (dataBuf != nullptr)
- {
- const size_t bytesLeft = dataBuf->BytesLeft();
- if (bytesLeft == 0)
- {
- dataBuf = OutputBuffer::Release(dataBuf);
- }
- else
- {
- const size_t sent = dataSocket->Send(reinterpret_cast<const uint8_t *>(dataBuf->UnreadData()), bytesLeft);
- if (sent == 0)
- {
- // Check whether the connection has been closed
- if (!dataSocket->CanSend())
- {
- if (reprap.Debug(moduleWebserver))
- {
- debugPrintf("Can't send anymore over the data port\n");
- }
-
- sendError = true;
- dataSocket = nullptr;
- if (fileBeingSent != nullptr)
- {
- fileBeingSent->Close();
- fileBeingSent = nullptr;
- }
-
- responderState = ResponderState::pasvTransferComplete;
- }
- return;
- }
-
- // Tell the output buffer how much data we have taken
- dataBuf->Taken(sent);
- if (sent < bytesLeft)
- {
- return;
- }
- dataBuf = OutputBuffer::Release(dataBuf);
- }
- }
-
- // If we get here then there are no output buffers left to send
- // If we have a file to send, send it
- if (fileBeingSent != nullptr && fileBuffer == nullptr)
- {
- fileBuffer = NetworkBuffer::Allocate();
- if (fileBuffer == nullptr)
- {
- return; // no buffer available, try again later
- }
- }
-
- // If we have a file buffer here, we must be in the process of sending a file
- while (fileBuffer != nullptr)
- {
- if (fileBuffer->IsEmpty() && fileBeingSent != nullptr)
- {
- const int bytesRead = fileBuffer->ReadFromFile(fileBeingSent);
- if (bytesRead != (int)NetworkBuffer::bufferSize)
- {
- // We had a read error or we reached the end of the file
- fileBeingSent->Close();
- fileBeingSent = nullptr;
- }
- }
-
- if (fileBuffer->IsEmpty())
- {
- // Must have sent the whole file
- fileBuffer->Release();
- fileBuffer = nullptr;
- }
- else
- {
- const size_t remaining = fileBuffer->Remaining();
- const size_t sent = dataSocket->Send(fileBuffer->UnreadData(), remaining);
- if (sent == 0)
- {
- // Check whether the connection has been closed
- if (!dataSocket->CanSend())
- {
- if (reprap.Debug(moduleWebserver))
- {
- debugPrintf("Can't send anymore\n");
- }
-
- sendError = true;
- dataSocket = nullptr;
- if (fileBeingSent != nullptr)
- {
- fileBeingSent->Close();
- fileBeingSent = nullptr;
- }
- fileBuffer->Release();
- fileBuffer = nullptr;
-
- responderState = ResponderState::pasvTransferComplete;
- }
- return;
- }
-
- fileBuffer->Taken(sent);
- if (sent < remaining)
- {
- return;
- }
- }
- }
-
- // If we get here then there is nothing left to send. Close it as well
- dataSocket->Send(); // tell the socket there is no more data
- dataSocket->Close();
- dataSocket = nullptr;
-
- responderState = ResponderState::pasvTransferComplete;
-}
-
-// Write some more upload data
-void FtpResponder::DoUpload()
-{
- // Write incoming data to the file
- const uint8_t *buffer;
- size_t len;
- if (dataSocket->ReadBuffer(buffer, len))
- {
- if (reprap.Debug(moduleWebserver))
- {
- GetPlatform().MessageF(UsbMessage, "Writing %u bytes of upload data\n", len);
- }
-
- dataSocket->Taken(len);
- if (!fileBeingUploaded.Write(buffer, len))
- {
- uploadError = true;
- GetPlatform().Message(ErrorMessage, "Could not write upload data!\n");
- CancelUpload();
-
- responderState = ResponderState::pasvTransferComplete;
- return;
- }
- }
-
- // Upload has finished if the connection is closed
- if (!dataSocket->CanRead())
- {
- dataSocket = nullptr;
- responderState = ResponderState::pasvTransferComplete;
-
- FinishUpload(0, 0);
- }
-}
-
-// Try to read some data from the main FTP port and return true
-// if anything significant could be done
-bool FtpResponder::ReadData()
-{
- bool readSomething = false;
- char c;
- while (!haveCompleteLine && skt->ReadChar(c))
- {
- CharFromClient(c);
- readSomething = true;
- }
-
- if (!readSomething && !skt->CanRead())
- {
- ConnectionLost();
- return true;
- }
-
- if (haveCompleteLine && (outBuf != nullptr || OutputBuffer::Allocate(outBuf)))
- {
- ProcessLine();
- return true;
- }
- return readSomething;
-}
-
-// Keep track of incoming characters
-void FtpResponder::CharFromClient(char c)
-{
- switch (c)
- {
- case 0:
- break;
-
- case '\r':
- case '\n':
- if (clientPointer != 0)
- {
- // This line is complete
- clientMessage[clientPointer] = 0;
- haveCompleteLine = true;
- }
- break;
-
- default:
- clientMessage[clientPointer++] = c;
-
- // Make sure we don't overflow the line buffer
- if (clientPointer > ARRAY_UPB(clientMessage))
- {
- clientPointer = 0;
- GetPlatform().Message(UsbMessage, "Webserver: Buffer overflow in FTP server!\n");
- }
- break;
- }
-}
-
-// Process the next FTP command
-void FtpResponder::ProcessLine()
-{
- if (reprap.Debug(moduleWebserver))
- {
- debugPrintf("FTP request '%s' (state %d)\n", clientMessage, (int)responderState);
- }
-
- haveCompleteLine = false;
- clientPointer = 0;
-
- switch (responderState)
- {
- case ResponderState::authenticating:
- // don't check the user name
- if (StringStartsWith(clientMessage, "USER"))
- {
- outBuf->copy("331 Please specify the password.\r\n");
- Commit(ResponderState::authenticating);
- }
- // but check the password (if set)
- else if (StringStartsWith(clientMessage, "PASS"))
- {
- const char *password = GetParameter("PASS");
- if (reprap.NoPasswordSet() || reprap.CheckPassword(password))
- {
- strcpy(currentDirectory, "/");
-
- outBuf->copy("230 Login successful.\r\n");
- Commit(ResponderState::reading);
- }
- else
- {
- outBuf->copy("530 Login incorrect.\r\n");
- Commit();
- }
- }
- // end connection
- else if (StringEquals(clientMessage, "QUIT"))
- {
- outBuf->copy("221 Goodbye.\r\n");
- Commit();
- }
- // if it's different, send response 500 to indicate we don't know the code (might be AUTH or so)
- else
- {
- outBuf->copy("500 Unknown login command.\r\n");
- Commit(ResponderState::authenticating);
- }
- break;
-
- case ResponderState::reading:
- // get system type
- if (StringEquals(clientMessage, "SYST"))
- {
- outBuf->copy("215 UNIX Type: L8\r\n");
- Commit(ResponderState::reading);
- }
- // get features
- else if (StringEquals(clientMessage, "FEAT"))
- {
- outBuf->copy( "211-Features:\r\n"
- "PASV\r\n" // support PASV mode
- "211 End\r\n"
- );
- Commit(ResponderState::reading);
- }
- // get current dir
- else if (StringEquals(clientMessage, "PWD"))
- {
- outBuf->printf("257 \"%s\"\r\n", currentDirectory);
- Commit(ResponderState::reading);
- }
- // set current dir
- else if (StringStartsWith(clientMessage, "CWD"))
- {
- const char *directory = GetParameter("CWD");
- ChangeDirectory(directory);
- }
- // change to parent of current directory
- else if (StringEquals(clientMessage, "CDUP"))
- {
- ChangeDirectory("..");
- }
- // switch transfer mode (sends response, but doesn't have any effects)
- else if (StringStartsWith(clientMessage, "TYPE"))
- {
- const char *type = GetParameter("TYPE");
- if (StringEquals(type, "I"))
- {
- outBuf->copy("200 Switching to Binary mode.\r\n");
- }
- else if (StringEquals(type, "A"))
- {
- outBuf->copy("200 Switching to ASCII mode.\r\n");
- }
- else
- {
- outBuf->copy("500 Unknown command.\r\n");
- }
- Commit(ResponderState::reading);
- }
- // enter passive mode mode
- else if (StringEquals(clientMessage, "PASV"))
- {
- // reset error conditions
- uploadError = sendError = false;
-
- // open random port > 1023
- passivePort = random(1024, 65535);
- passivePortOpenTime = millis();
-
- GetNetwork().OpenDataPort(passivePort);
- if (reprap.Debug(moduleWebserver))
- {
- debugPrintf("FTP data port open at port %u\n", passivePort);
- }
-
- // send FTP response
- const uint8_t * const ipAddress = GetNetwork().GetIPAddress();
- outBuf->printf("227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n",
- ipAddress[0], ipAddress[1], ipAddress[2], ipAddress[3],
- passivePort / 256, passivePort % 256);
- Commit(ResponderState::waitingForPasvPort);
- }
- // PASV commands are not supported in this state
- else if (StringStartsWith(clientMessage, "LIST") || StringStartsWith(clientMessage, "RETR") || StringStartsWith(clientMessage, "STOR"))
- {
- outBuf->copy("425 Use PASV first.\r\n");
- Commit(ResponderState::reading);
- }
- // delete file
- else if (StringStartsWith(clientMessage, "DELE"))
- {
- const char *filename = GetParameter("DELE");
- if (GetPlatform().GetMassStorage()->Delete(currentDirectory, filename))
- {
- outBuf->copy("250 Delete operation successful.\r\n");
- }
- else
- {
- outBuf->copy("550 Delete operation failed.\r\n");
- }
- Commit(ResponderState::reading);
- }
- // delete directory
- else if (StringStartsWith(clientMessage, "RMD"))
- {
- const char *filename = GetParameter("RMD");
- if (GetPlatform().GetMassStorage()->Delete(currentDirectory, filename))
- {
- outBuf->copy("250 Remove directory operation successful.\r\n");
- }
- else
- {
- outBuf->copy("550 Remove directory operation failed.\r\n");
- }
- Commit(ResponderState::reading);
- }
- // make new directory
- else if (StringStartsWith(clientMessage, "MKD"))
- {
- const char *filename = GetParameter("MKD");
- const char *location = (filename[0] == '/')
- ? filename
- : GetPlatform().GetMassStorage()->CombineName(currentDirectory, filename);
-
- if (GetPlatform().GetMassStorage()->MakeDirectory(location))
- {
- outBuf->printf("257 \"%s\" created\r\n", location);
- }
- else
- {
- outBuf->copy("550 Create directory operation failed.\r\n");
- }
- Commit(ResponderState::reading);
- }
- // rename file or directory
- else if (StringStartsWith(clientMessage, "RNFR"))
- {
- const char *filename = GetParameter("RNFR");
- if (filename[0] != '/')
- {
- filename = GetPlatform().GetMassStorage()->CombineName(currentDirectory, filename);
- }
- SafeStrncpy(fileToMove, filename, ARRAY_SIZE(fileToMove));
-
- if (GetPlatform().GetMassStorage()->FileExists(fileToMove))
- {
- outBuf->copy("350 Ready to RNTO.\r\n");
- }
- else
- {
- outBuf->copy("550 Invalid file or directory.\r\n");
- }
- Commit(ResponderState::reading);
- }
- else if (StringStartsWith(clientMessage, "RNTO"))
- {
- const char *filename = GetParameter("RNTO");
- if (filename[0] != '/')
- {
- filename = GetPlatform().GetMassStorage()->CombineName(currentDirectory, filename);
- }
-
- if (GetPlatform().GetMassStorage()->Rename(fileToMove, filename))
- {
- outBuf->copy("250 Rename successful.\r\n");
- }
- else
- {
- outBuf->copy("500 Could not rename file or directory\r\n");
- }
- Commit(ResponderState::reading);
- }
- // no op
- else if (StringEquals(clientMessage, "NOOP"))
- {
- outBuf->copy("200 NOOP okay.\r\n");
- Commit(ResponderState::reading);
- }
- // end connection
- else if (StringEquals(clientMessage, "QUIT"))
- {
- outBuf->copy("221 Goodbye.\r\n");
- Commit();
- }
- // unknown
- else
- {
- outBuf->copy("500 Unknown command.\r\n");
- Commit(ResponderState::reading);
- }
- break;
-
- case ResponderState::pasvPortOpened:
- // list directory entries
- if (StringStartsWith(clientMessage, "LIST"))
- {
- // send announcement via ftp main port
- outBuf->copy("150 Here comes the directory listing.\r\n");
- Commit(ResponderState::sendingPasvData);
-
- // build directory listing, dataBuf is sent later in the Spin loop
- MassStorage * const massStorage = GetPlatform().GetMassStorage();
- FileInfo fileInfo;
- if (massStorage->FindFirst(currentDirectory, fileInfo))
- {
- do {
- // Example for a typical UNIX-like file list:
- // "drwxr-xr-x 2 ftp ftp 0 Apr 11 2013 bin\r\n"
- const char dirChar = (fileInfo.isDirectory) ? 'd' : '-';
- const struct tm * const timeInfo = gmtime(&fileInfo.lastModified);
- dataBuf->catf("%crw-rw-rw- 1 ftp ftp %13lu %s %02d %04d %s\r\n",
- dirChar, fileInfo.size, massStorage->GetMonthName(timeInfo->tm_mon + 1),
- timeInfo->tm_mday, timeInfo->tm_year + 1900, fileInfo.fileName);
- } while (massStorage->FindNext(fileInfo));
- }
- }
- // switch transfer mode (sends response, but doesn't have any effects)
- else if (StringStartsWith(clientMessage, "TYPE"))
- {
- const char *type = GetParameter("TYPE");
- if (StringEquals(type, "I"))
- {
- outBuf->copy("200 Switching to Binary mode.\r\n");
- }
- else if (StringEquals(type, "A"))
- {
- outBuf->copy("200 Switching to ASCII mode.\r\n");
- }
- else
- {
- outBuf->copy("500 Unknown command.\r\n");
- }
- Commit(ResponderState::pasvPortOpened);
- }
- // upload a file
- else if (StringStartsWith(clientMessage, "STOR"))
- {
- const char *filename = GetParameter("STOR");
- FileStore *file = GetPlatform().OpenFile(currentDirectory, filename, OpenMode::write);
- if (file != nullptr)
- {
- StartUpload(file, filename);
-
- outBuf->copy("150 OK to send data.\r\n");
- Commit(ResponderState::uploading);
- }
- else
- {
- outBuf->copy("550 Failed to open file.\r\n");
- Commit(ResponderState::reading);
- }
- }
- // download a file
- else if (StringStartsWith(clientMessage, "RETR"))
- {
- const char *filename = GetParameter("RETR");
- fileBeingSent = GetPlatform().OpenFile(currentDirectory, filename, OpenMode::read);
- if (fileBeingSent != nullptr)
- {
- outBuf->printf("150 Opening data connection for %s (%lu bytes).\r\n", filename, fileBeingSent->Length());
- Commit(ResponderState::sendingPasvData);
- }
- else
- {
- outBuf->copy("550 Failed to open file.\r\n");
- Commit(ResponderState::reading);
- }
- }
- // abort current operation
- else if (StringEquals(clientMessage, "ABOR"))
- {
- CloseDataPort();
-
- outBuf->copy("226 ABOR successful.\r\n");
- Commit(ResponderState::reading);
- }
- // end connection
- else if (StringEquals(clientMessage, "QUIT"))
- {
- CloseDataPort();
-
- outBuf->copy("221 Goodbye.\r\n");
- Commit();
- }
- // unknown command
- else
- {
- outBuf->copy("500 Unknown command.\r\n");
- Commit(ResponderState::pasvPortOpened);
- }
- break;
-
- case ResponderState::uploading:
- case ResponderState::sendingPasvData:
- // abort current transfer
- if (StringEquals(clientMessage, "ABOR"))
- {
- CancelUpload();
- CloseDataPort();
-
- outBuf->copy("226 ABOR successful.\r\n");
- Commit(ResponderState::reading);
- }
- // in theory we could add support for QUIT here but it's not worth the effort
- // unknown command
- else
- {
- outBuf->copy("500 Unknown command.\r\n");
- Commit(responderState);
- }
- break;
-
- default:
- // do nothing
- break;
- }
-}
-
-const char *FtpResponder::GetParameter(const char *after) const
-{
- const size_t commandLength = strlen(after);
- if (commandLength >= ftpMessageLength)
- {
- return "";
- }
-
- const char *result = clientMessage + strlen(after) + 1;
- while ((*result == '\t' || *result == ' ') && *result != 0)
- {
- ++result;
- }
- return result;
-}
-
-void FtpResponder::ChangeDirectory(const char *newDirectory)
-{
- char combinedPath[MaxFilenameLength];
- if (newDirectory[0] != 0)
- {
- // Prepare the new directory path
- if (newDirectory[0] == '/') // Absolute path
- {
- SafeStrncpy(combinedPath, newDirectory, ARRAY_SIZE(combinedPath));
- }
- else if (StringEquals(newDirectory, "."))
- {
- SafeStrncpy(combinedPath, currentDirectory, ARRAY_SIZE(combinedPath));
- }
- else if (StringEquals(newDirectory, "..")) // Go up
- {
- // Check if we're already at the root directory
- if (StringEquals(currentDirectory, "/"))
- {
- outBuf->copy("550 Failed to change directory.\r\n");
- Commit(responderState);
- return;
- }
-
- // No - find the parent directory
- SafeStrncpy(combinedPath, currentDirectory, ARRAY_SIZE(combinedPath));
- for(int i = strlen(combinedPath) - 2; i >= 0; i--)
- {
- if (combinedPath[i] == '/')
- {
- combinedPath[i + 1] = 0;
- break;
- }
- }
- }
- else // Go to child directory
- {
- SafeStrncpy(combinedPath, currentDirectory, ARRAY_SIZE(combinedPath));
- if (!StringEndsWith(combinedPath, "/") && strlen(combinedPath) > 1)
- {
- SafeStrncat(combinedPath, "/", ARRAY_SIZE(combinedPath));
- }
- SafeStrncat(combinedPath, newDirectory, ARRAY_SIZE(combinedPath));
- }
-
- // Make sure the new path does not end with a slash, else FatFs won't be able to see the directory
- if (StringEndsWith(combinedPath, "/") && strlen(combinedPath) > 1)
- {
- combinedPath[strlen(combinedPath) - 1] = 0;
- }
-
- // Verify the final path and change it if possible
- if (GetPlatform().GetMassStorage()->DirectoryExists(combinedPath))
- {
- SafeStrncpy(currentDirectory, combinedPath, ARRAY_SIZE(currentDirectory));
- outBuf->copy("250 Directory successfully changed.\r\n");
- Commit(responderState);
- }
- else
- {
- outBuf->copy("550 Failed to change directory.\r\n");
- Commit(responderState);
- }
- }
- else
- {
- outBuf->copy("550 Failed to change directory.\r\n");
- Commit(responderState);
- }
-}
-
-void FtpResponder::CloseDataPort()
-{
- if (reprap.Debug(moduleWebserver))
- {
- debugPrintf("FTP data port is being closed\n");
- }
-
- if (dataSocket != nullptr)
- {
- GetNetwork().DataPortClosing();
- dataSocket->Close(); // close it gracefully
- dataSocket = nullptr;
- }
- else
- {
- GetNetwork().TerminateDataPort(); // in case it has been partially set up
- }
-
- OutputBuffer::ReleaseAll(dataBuf);
- dataBuf = nullptr;
-
- if (fileBeingSent != nullptr)
- {
- fileBeingSent->Close();
- fileBeingSent = nullptr;
- }
-}
-
-// End
diff --git a/src/Network2/FtpResponder.h b/src/Network2/FtpResponder.h
deleted file mode 100644
index e98a1d50..00000000
--- a/src/Network2/FtpResponder.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * FtpResponder.h
- *
- * Created on: 14 Apr 2017
- * Authors: David and Christian
- */
-
-#ifndef SRC_DUETNG_DUETETHERNET_FTPRESPONDER_H_
-#define SRC_DUETNG_DUETETHERNET_FTPRESPONDER_H_
-
-#include "NetworkResponder.h"
-
-class FtpResponder : public NetworkResponder
-{
-public:
- FtpResponder(NetworkResponder *n);
- bool Spin() override; // do some work, returning true if we did anything significant
- bool Accept(Socket *s, Protocol protocol) override; // ask the responder to accept this connection, returns true if it did
- void Terminate(Protocol protocol) override; // terminate the responder if it is serving the specified protocol
-
- void Diagnostics(MessageType mtype) const override;
-
-protected:
- static const size_t ftpMessageLength = 128; // maximum line length for incoming FTP commands
- static const uint32_t ftpPasvPortTimeout = 10000; // maximum time to wait for an FTP data connection in milliseconds
-
- Socket *dataSocket;
- Port passivePort;
- uint32_t passivePortOpenTime;
- OutputBuffer *dataBuf;
-
- void ConnectionLost() override;
- void SendData() override;
-
- bool sendError;
- void SendPassiveData();
-
- void DoUpload();
-
- bool ReadData();
- void CharFromClient(char c);
- void ProcessLine();
- const char *GetParameter(const char *after) const; // return the parameter followed by whitespaces after a command
- void ChangeDirectory(const char *newDirectory);
-
- void CloseDataPort();
-
- bool haveCompleteLine;
- char clientMessage[ftpMessageLength];
- size_t clientPointer;
-
- char currentDirectory[MaxFilenameLength];
- char fileToMove[MaxFilenameLength];
-};
-
-#endif /* SRC_DUETNG_DUETETHERNET_FTPRESPONDER_H_ */
diff --git a/src/Network2/HttpResponder.cpp b/src/Network2/HttpResponder.cpp
deleted file mode 100644
index 16df8a4e..00000000
--- a/src/Network2/HttpResponder.cpp
+++ /dev/null
@@ -1,1277 +0,0 @@
-/*
- * HttpResponder.cpp
- *
- * Created on: 14 Apr 2017
- * Author: David
- */
-
-#include "HttpResponder.h"
-#include "GCodes/GCodes.h"
-#include "PrintMonitor.h"
-#include "Libraries/General/IP4String.h"
-
-#define KO_START "rr_"
-const size_t KoFirst = 3;
-
-const char* const overflowResponse = "overflow";
-const char* const badEscapeResponse = "bad escape";
-
-const uint32_t HttpReceiveTimeout = 2000;
-
-HttpResponder::HttpResponder(NetworkResponder *n) : NetworkResponder(n)
-{
-}
-
-// Ask the responder to accept this connection, returns true if it did
-bool HttpResponder::Accept(Socket *s, Protocol protocol)
-{
- if (responderState == ResponderState::free && protocol == HttpProtocol)
- {
- // Make sure we can get an output buffer before we accept the connection, or we won't be able to reply
- if (outBuf != nullptr || OutputBuffer::Allocate(outBuf))
- {
- responderState = ResponderState::reading;
- skt = s;
- timer = millis();
-
- // Reset the parse state variables
- clientPointer = 0;
- parseState = HttpParseState::doingCommandWord;
- numCommandWords = 0;
- numQualKeys = 0;
- numHeaderKeys = 0;
- commandWords[0] = clientMessage;
-
- if (reprap.Debug(moduleWebserver))
- {
- debugPrintf("HTTP connection accepted\n");
- }
- return true;
- }
- if (reprap.Debug(moduleWebserver))
- {
- debugPrintf("HTTP connection refused (no buffers)\n");
- }
- }
- return false;
-}
-
-// Do some work, returning true if we did anything significant
-bool HttpResponder::Spin()
-{
- switch (responderState)
- {
- case ResponderState::free:
- return false;
-
- case ResponderState::reading:
- {
- bool readSomething = false;
- char c;
- while (skt->ReadChar(c))
- {
- if (CharFromClient(c))
- {
- timer = millis(); // restart the timeout
- return true;
- }
- readSomething = true;
- }
-
- // Here when we were not able to read a character but we didn't receive a finished message
- if (readSomething)
- {
- timer = millis(); // restart the timeout
- return true;
- }
-
- if (!skt->CanRead() || millis() - timer >= HttpReceiveTimeout)
- {
- ConnectionLost();
- return true;
- }
-
- return false;
- }
-
- case ResponderState::gettingFileInfoLock:
- if (!fileInfoLock.Acquire(this))
- {
- return false;
- }
- responderState = ResponderState::gettingFileInfo;
- // no break
-
- case ResponderState::gettingFileInfo:
- if (SendFileInfo())
- {
- fileInfoLock.Release(this); // release the lock
- }
- return true;
-
- case ResponderState::uploading:
- DoUpload();
- return true;
-
- case ResponderState::sending:
- SendData();
- return true;
-
- default: // should not happen
- return false;
- }
-}
-
-// Process a character from the client
-// Rewritten as a state machine by dc42 to increase capability and speed, and reduce RAM requirement.
-// On entry:
-// There is space for at least 1 character in clientMessage.
-// On return:
-// If we return false:
-// We want more characters. There is space for at least 1 character in clientMessage.
-// If we return true:
-// We have processed the message and sent the reply. No more characters may be read from this message.
-// Whenever this calls ProcessMessage:
-// The first line has been split up into words. Variables numCommandWords and commandWords give the number of words we found
-// and the pointers to each word. The second word is treated specially. It is assumed to be a filename followed by an optional
-// qualifier comprising key/value pairs. Both may include %xx escapes, and the qualifier may include + to mean space. We store
-// a pointer to the filename without qualifier in commandWords[1]. We store the qualifier key/value pointers in array 'qualifiers'
-// and the number of them in numQualKeys.
-// The remaining lines have been parsed as header name/value pairs. Pointers to them are stored in array 'headers' and the number
-// of them in numHeaders.
-// If one of our arrays is about to overflow, or the message is not in a format we expect, then we call RejectMessage with an
-// appropriate error code and string.
-bool HttpResponder::CharFromClient(char c)
-{
- switch (parseState)
- {
- case HttpParseState::doingCommandWord:
- switch(c)
- {
- case '\n':
- clientMessage[clientPointer++] = 0;
- ++numCommandWords;
- numHeaderKeys = 0;
- headers[0].key = clientMessage + clientPointer;
- parseState = HttpParseState::doingHeaderKey;
- break;
- case '\r':
- break;
- case ' ':
- case '\t':
- clientMessage[clientPointer++] = 0;
- if (numCommandWords < MaxCommandWords)
- {
- ++numCommandWords;
- commandWords[numCommandWords] = clientMessage + clientPointer;
- if (numCommandWords == 1)
- {
- parseState = HttpParseState::doingFilename;
- }
- }
- else
- {
- RejectMessage("too many command words");
- return true;
- }
- break;
- default:
- clientMessage[clientPointer++] = c;
- break;
- }
- break;
-
- case HttpParseState::doingFilename:
- switch(c)
- {
- case '\n':
- clientMessage[clientPointer++] = 0;
- ++numCommandWords;
- numQualKeys = 0;
- numHeaderKeys = 0;
- headers[0].key = clientMessage + clientPointer;
- parseState = HttpParseState::doingHeaderKey;
- break;
- case '?':
- clientMessage[clientPointer++] = 0;
- ++numCommandWords;
- numQualKeys = 0;
- qualifiers[0].key = clientMessage + clientPointer;
- parseState = HttpParseState::doingQualifierKey;
- break;
- case '%':
- parseState = HttpParseState::doingFilenameEsc1;
- break;
- case '\r':
- break;
- case ' ':
- case '\t':
- clientMessage[clientPointer++] = 0;
- if (numCommandWords < MaxCommandWords)
- {
- ++numCommandWords;
- commandWords[numCommandWords] = clientMessage + clientPointer;
- parseState = HttpParseState::doingCommandWord;
- }
- else
- {
- RejectMessage("too many command words");
- return true;
- }
- break;
- default:
- clientMessage[clientPointer++] = c;
- break;
- }
- break;
-
- case HttpParseState::doingQualifierKey:
- switch(c)
- {
- case '=':
- clientMessage[clientPointer++] = 0;
- qualifiers[numQualKeys].value = clientMessage + clientPointer;
- ++numQualKeys;
- parseState = HttpParseState::doingQualifierValue;
- break;
- case '\n': // key with no value
- case ' ':
- case '\t':
- case '\r':
- case '%': // none of our keys needs escaping, so treat an escape within a key as an error
- case '&': // key with no value
- RejectMessage("bad qualifier key");
- return true;
- default:
- clientMessage[clientPointer++] = c;
- break;
- }
- break;
-
- case HttpParseState::doingQualifierValue:
- switch(c)
- {
- case '\n':
- clientMessage[clientPointer++] = 0;
- qualifiers[numQualKeys].key = clientMessage + clientPointer; // so that we can read the whole value even if it contains a null
- numHeaderKeys = 0;
- headers[0].key = clientMessage + clientPointer;
- parseState = HttpParseState::doingHeaderKey;
- break;
- case ' ':
- case '\t':
- clientMessage[clientPointer++] = 0;
- qualifiers[numQualKeys].key = clientMessage + clientPointer; // so that we can read the whole value even if it contains a null
- commandWords[numCommandWords] = clientMessage + clientPointer;
- parseState = HttpParseState::doingCommandWord;
- break;
- case '\r':
- break;
- case '%':
- parseState = HttpParseState::doingQualifierValueEsc1;
- break;
- case '&':
- // Another variable is coming
- clientMessage[clientPointer++] = 0;
- qualifiers[numQualKeys].key = clientMessage + clientPointer; // so that we can read the whole value even if it contains a null
- if (numQualKeys < MaxQualKeys)
- {
- parseState = HttpParseState::doingQualifierKey;
- }
- else
- {
- RejectMessage("too many keys in qualifier");
- return true;
- }
- break;
- case '+':
- clientMessage[clientPointer++] = ' ';
- break;
- default:
- clientMessage[clientPointer++] = c;
- break;
- }
- break;
-
- case HttpParseState::doingFilenameEsc1:
- case HttpParseState::doingQualifierValueEsc1:
- if (c >= '0' && c <= '9')
- {
- decodeChar = (c - '0') << 4;
- parseState = (HttpParseState)((int)parseState + 1);
- }
- else if (c >= 'A' && c <= 'F')
- {
- decodeChar = (c - ('A' - 10)) << 4;
- parseState = (HttpParseState)((int)parseState + 1);
- }
- else
- {
- RejectMessage(badEscapeResponse);
- return true;
- }
- break;
-
- case HttpParseState::doingFilenameEsc2:
- case HttpParseState::doingQualifierValueEsc2:
- if (c >= '0' && c <= '9')
- {
- clientMessage[clientPointer++] = decodeChar | (c - '0');
- parseState = (HttpParseState)((int)parseState - 2);
- }
- else if (c >= 'A' && c <= 'F')
- {
- clientMessage[clientPointer++] = decodeChar | (c - ('A' - 10));
- parseState = (HttpParseState)((int)parseState - 2);
- }
- else
- {
- RejectMessage(badEscapeResponse);
- return true;
- }
- break;
-
- case HttpParseState::doingHeaderKey:
- switch(c)
- {
- case '\n':
- if (clientMessage + clientPointer == headers[numHeaderKeys].key) // if the key hasn't started yet, then this is the blank line at the end
- {
- ProcessMessage();
- return true;
- }
- else
- {
- RejectMessage("unexpected newline");
- return true;
- }
- break;
- case '\r':
- break;
- case ':':
- if (numHeaderKeys == MaxHeaders - 1)
- {
- RejectMessage("too many header key-value pairs");
- return true;
- }
- clientMessage[clientPointer++] = 0;
- headers[numHeaderKeys].value = clientMessage + clientPointer;
- ++numHeaderKeys;
- parseState = HttpParseState::expectingHeaderValue;
- break;
- default:
- clientMessage[clientPointer++] = c;
- break;
- }
- break;
-
- case HttpParseState::expectingHeaderValue:
- if (c == ' ' || c == '\t')
- {
- break; // ignore spaces between header key and value
- }
- parseState = HttpParseState::doingHeaderValue;
- // no break
-
- case HttpParseState::doingHeaderValue:
- if (c == '\n')
- {
- parseState = HttpParseState::doingHeaderContinuation;
- }
- else if (c != '\r')
- {
- clientMessage[clientPointer++] = c;
- }
- break;
-
- case HttpParseState::doingHeaderContinuation:
- switch(c)
- {
- case ' ':
- case '\t':
- // It's a continuation of the previous value
- clientMessage[clientPointer++] = c;
- parseState = HttpParseState::doingHeaderValue;
- break;
- case '\n':
- // It's the blank line
- clientMessage[clientPointer] = 0;
- ProcessMessage();
- return true;
- case '\r':
- break;
- default:
- // It's a new key
- if (clientPointer + 3 <= ARRAY_SIZE(clientMessage))
- {
- clientMessage[clientPointer++] = 0;
- headers[numHeaderKeys].key = clientMessage + clientPointer;
- clientMessage[clientPointer++] = c;
- parseState = HttpParseState::doingHeaderKey;
- }
- else
- {
- RejectMessage(overflowResponse);
- return true;
- }
- break;
- }
- break;
-
- default:
- break;
- }
-
- if (clientPointer == ARRAY_SIZE(clientMessage))
- {
- RejectMessage(overflowResponse);
- return true;
- }
- return false;
-}
-
-// Get the Json response for this command.
-// 'value' is null-terminated, but we also pass its length in case it contains embedded nulls, which matters when uploading files.
-// Return true if we generated a json response to send, false if we didn't and changed the state instead
-bool HttpResponder::GetJsonResponse(const char* request, OutputBuffer *&response, bool& keepOpen)
-{
- keepOpen = false; // assume we don't want to persist the connection
- if (StringEquals(request, "connect") && GetKeyValue("password") != nullptr)
- {
- if (!CheckAuthenticated())
- {
- if (!reprap.CheckPassword(GetKeyValue("password")))
- {
- // Wrong password
- response->copy("{\"err\":1}");
- reprap.GetPlatform().MessageF(LogMessage, "HTTP client %s attempted login with incorrect password\n", IP4String(GetRemoteIP()).c_str());
- return true;
- }
- if (!Authenticate())
- {
- // No more HTTP sessions available
- response->copy("{\"err\":2}");
- reprap.GetPlatform().MessageF(LogMessage, "HTTP client %s attempted login but no more sessions available\n", IP4String(GetRemoteIP()).c_str());
- return true;
- }
- }
-
- // Client has been logged in
- response->printf("{\"err\":0,\"sessionTimeout\":%" PRIu32 ",\"boardType\":\"%s\"}", HttpSessionTimeout, GetPlatform().GetBoardString());
- reprap.GetPlatform().MessageF(LogMessage, "HTTP client %s login succeeded\n", IP4String(GetRemoteIP()).c_str());
-
- // See if we can update the current RTC date and time
- const char* const timeString = GetKeyValue("time");
- if (timeString != nullptr && !GetPlatform().IsDateTimeSet())
- {
- struct tm timeInfo;
- memset(&timeInfo, 0, sizeof(timeInfo));
- if (strptime(timeString, "%Y-%m-%dT%H:%M:%S", &timeInfo) != nullptr)
- {
- GetPlatform().SetDateTime(mktime(&timeInfo));
- }
- }
- }
- else if (!CheckAuthenticated())
- {
- RejectMessage("Not authorized", 500);
- return false;
- }
- else if (StringEquals(request, "disconnect"))
- {
- response->printf("{\"err\":%d}", (RemoveAuthentication()) ? 0 : 1);
- reprap.GetPlatform().MessageF(LogMessage, "HTTP client %s disconnected\n", IP4String(GetRemoteIP()).c_str());
- }
- else if (StringEquals(request, "status"))
- {
- int type = 0;
- if (GetKeyValue("type") != nullptr)
- {
- // New-style JSON status responses
- type = atoi(GetKeyValue("type"));
- if (type < 1 || type > 3)
- {
- type = 1;
- }
-
- OutputBuffer::Release(response);
- response = reprap.GetStatusResponse(type, ResponseSource::HTTP);
- }
- else
- {
- // Deprecated
- OutputBuffer::Release(response);
- response = reprap.GetLegacyStatusResponse(1, 0);
- }
- }
- else if (StringEquals(request, "gcode") && GetKeyValue("gcode") != nullptr)
- {
- RegularGCodeInput * const httpInput = reprap.GetGCodes().GetHTTPInput();
- httpInput->Put(HttpMessage, GetKeyValue("gcode"));
- response->printf("{\"buff\":%u}", httpInput->BufferSpaceLeft());
- }
- else if (StringEquals(request, "upload"))
- {
- response->printf("{\"err\":%d}", (uploadError) ? 1 : 0);
- }
- else if (StringEquals(request, "delete") && GetKeyValue("name") != nullptr)
- {
- const bool ok = GetPlatform().GetMassStorage()->Delete(FS_PREFIX, GetKeyValue("name"));
- response->printf("{\"err\":%d}", (ok) ? 0 : 1);
- }
- else if (StringEquals(request, "filelist") && GetKeyValue("dir") != nullptr)
- {
- OutputBuffer::Release(response);
- response = reprap.GetFilelistResponse(GetKeyValue("dir"));
- }
- else if (StringEquals(request, "files"))
- {
- const char* dir = GetKeyValue("dir");
- if (dir == nullptr)
- {
- dir = GetPlatform().GetGCodeDir();
- }
- const char* const flagDirsVal = GetKeyValue("flagDirs");
- const bool flagDirs = flagDirsVal != nullptr && atoi(flagDirsVal) == 1;
- OutputBuffer::Release(response);
- response = reprap.GetFilesResponse(dir, flagDirs);
- }
- else if (StringEquals(request, "fileinfo"))
- {
- const char* const nameVal = GetKeyValue("name");
- if (nameVal != nullptr)
- {
- // Regular rr_fileinfo?name=xxx call
- SafeStrncpy(filenameBeingProcessed, nameVal, ARRAY_SIZE(filenameBeingProcessed));
- }
- else
- {
- // Simple rr_fileinfo call to get info about the file being printed
- filenameBeingProcessed[0] = 0;
- }
- responderState = ResponderState::gettingFileInfoLock;
- return false;
- }
- else if (StringEquals(request, "move"))
- {
- const char* const oldVal = GetKeyValue("old");
- const char* const newVal = GetKeyValue("new");
- bool success = false;
- if (oldVal != nullptr && newVal != nullptr)
- {
- MassStorage * const ms = GetPlatform().GetMassStorage();
- if (StringEquals(GetKeyValue("deleteexisting"), "yes") && ms->FileExists(oldVal) && ms->FileExists(newVal))
- {
- ms->Delete(nullptr, newVal, true);
- }
- success = ms->Rename(oldVal, newVal);
- }
- response->printf("{\"err\":%d}", (success) ? 0 : 1);
- }
- else if (StringEquals(request, "mkdir"))
- {
- const char* const dirVal = GetKeyValue("dir");
- bool success = false;
- if (dirVal != nullptr)
- {
- success = GetPlatform().GetMassStorage()->MakeDirectory(dirVal);
- }
- response->printf("{\"err\":%d}", (success) ? 0 : 1);
- }
- else if (StringEquals(request, "config"))
- {
- OutputBuffer::Release(response);
- response = reprap.GetConfigResponse();
- }
- else
- {
- RejectMessage("Unknown request", 500);
- return false;
- }
- return true;
-}
-
-const char* HttpResponder::GetKeyValue(const char *key) const
-{
- for (size_t i = 0; i < numQualKeys; ++i)
- {
- if (StringEquals(qualifiers[i].key, key))
- {
- return qualifiers[i].value;
- }
- }
- return nullptr;
-}
-
-// Called to process a FileInfo request, which may take several calls
-// When we have finished, set the state back to free.
-bool HttpResponder::SendFileInfo()
-{
- OutputBuffer *jsonResponse = nullptr;
- const bool gotFileInfo = reprap.GetPrintMonitor().GetFileInfoResponse(filenameBeingProcessed, jsonResponse);
- if (gotFileInfo)
- {
- // Got it - send the response now
- outBuf->copy( "HTTP/1.1 200 OK\n"
- "Cache-Control: no-cache, no-store, must-revalidate\n"
- "Pragma: no-cache\n"
- "Expires: 0\n"
- "Access-Control-Allow-Origin: *\n"
- "Content-Type: application/json\n"
- );
- outBuf->catf("Content-Length: %u\n", (jsonResponse != nullptr) ? jsonResponse->Length() : 0);
- outBuf->cat("Connection: close\n\n");
- outBuf->Append(jsonResponse);
- Commit();
- }
- return gotFileInfo;
-}
-
-// Authenticate current IP and return true on success
-bool HttpResponder::Authenticate()
-{
- if (CheckAuthenticated())
- {
- return true;
- }
-
- if (numSessions < MaxHttpSessions)
- {
- sessions[numSessions].ip = GetRemoteIP();
- sessions[numSessions].lastQueryTime = millis();
- sessions[numSessions].isPostUploading = false;
- numSessions++;
- return true;
- }
- return false;
-}
-
-// Check and update the authentication
-bool HttpResponder::CheckAuthenticated()
-{
- const uint32_t remoteIP = GetRemoteIP();
- for (size_t i = 0; i < numSessions; i++)
- {
- if (sessions[i].ip == remoteIP)
- {
- sessions[i].lastQueryTime = millis();
- return true;
- }
- }
- return false;
-}
-
-bool HttpResponder::RemoveAuthentication()
-{
- const uint32_t remoteIP = skt->GetRemoteIP();
- for (size_t i = numSessions; i != 0; )
- {
- --i;
- if (sessions[i].ip == remoteIP)
- {
- if (sessions[i].isPostUploading)
- {
- // Don't allow sessions with active POST uploads to be removed
- return false;
- }
-
- for (size_t k = i + 1; k < numSessions; ++k)
- {
- memcpy(&sessions[k - 1], &sessions[k], sizeof(HttpSession));
- }
- numSessions--;
- return true;
- }
- }
- return false;
-}
-
-void HttpResponder::SendFile(const char* nameOfFileToSend, bool isWebFile)
-{
- FileStore *fileToSend = nullptr;
- bool zip = false;
-
- if (isWebFile)
- {
- if (nameOfFileToSend[0] == '/')
- {
- ++nameOfFileToSend; // all web files are relative to the /www folder, so remove the leading '/'
- if (nameOfFileToSend[0] == 0)
- {
- nameOfFileToSend = INDEX_PAGE_FILE;
- }
- }
-
- // Try to open a gzipped version of the file first
- if (!StringEndsWith(nameOfFileToSend, ".gz") && strlen(nameOfFileToSend) + 3 <= MaxFilenameLength)
- {
- String<MaxFilenameLength> nameBuf;
- nameBuf.copy(nameOfFileToSend);
- nameBuf.cat(".gz");
- fileToSend = GetPlatform().OpenFile(GetPlatform().GetWebDir(), nameBuf.c_str(), OpenMode::read);
- if (fileToSend != nullptr)
- {
- zip = true;
- }
- }
-
- // If that failed, try to open the normal version of the file
- if (fileToSend == nullptr)
- {
- fileToSend = GetPlatform().OpenFile(GetPlatform().GetWebDir(), nameOfFileToSend, OpenMode::read);
- }
-
- // If we still couldn't find the file and it was an HTML file, return the 404 error page
- if (fileToSend == nullptr && (StringEndsWith(nameOfFileToSend, ".html") || StringEndsWith(nameOfFileToSend, ".htm")))
- {
- nameOfFileToSend = FOUR04_PAGE_FILE;
- fileToSend = GetPlatform().OpenFile(GetPlatform().GetWebDir(), nameOfFileToSend, OpenMode::read);
- }
-
- if (fileToSend == nullptr)
- {
- RejectMessage("not found", 404);
- return;
- }
- fileBeingSent = fileToSend;
- }
- else
- {
- fileToSend = GetPlatform().OpenFile(FS_PREFIX, nameOfFileToSend, OpenMode::read);
- if (fileToSend == nullptr)
- {
- RejectMessage("not found", 404);
- return;
- }
- fileBeingSent = fileToSend;
- }
-
- outBuf->copy("HTTP/1.1 200 OK\n");
-
- // Don't cache files served by rr_download
- if (!isWebFile)
- {
- outBuf->cat( "Cache-Control: no-cache, no-store, must-revalidate\n"
- "Pragma: no-cache\n"
- "Expires: 0\n"
- "Access-Control-Allow-Origin: *\n"
- );
- }
-
- const char* contentType;
- if (StringEndsWith(nameOfFileToSend, ".png"))
- {
- contentType = "image/png";
- }
- else if (StringEndsWith(nameOfFileToSend, ".ico"))
- {
- contentType = "image/x-icon";
- }
- else if (StringEndsWith(nameOfFileToSend, ".js"))
- {
- contentType = "application/javascript";
- }
- else if (StringEndsWith(nameOfFileToSend, ".css"))
- {
- contentType = "text/css";
- }
- else if (StringEndsWith(nameOfFileToSend, ".htm") || StringEndsWith(nameOfFileToSend, ".html"))
- {
- contentType = "text/html";
- }
- else if (StringEndsWith(nameOfFileToSend, ".zip"))
- {
- contentType = "application/zip";
- zip = true;
- }
- else if (StringEndsWith(nameOfFileToSend, ".g") || StringEndsWith(nameOfFileToSend, ".gc") || StringEndsWith(nameOfFileToSend, ".gcode"))
- {
- contentType = "text/plain";
- }
- else
- {
- contentType = "application/octet-stream";
- }
- outBuf->catf("Content-Type: %s\n", contentType);
-
- if (zip && fileToSend != nullptr)
- {
- outBuf->cat("Content-Encoding: gzip\n");
- outBuf->catf("Content-Length: %lu\n", fileToSend->Length());
- }
-
- outBuf->cat("Connection: close\n\n");
- Commit();
-}
-
-void HttpResponder::SendGCodeReply()
-{
- // Do we need to keep the G-Code reply for other clients?
- bool clearReply = false;
- if (!gcodeReply->IsEmpty())
- {
- clientsServed++;
- if (clientsServed < numSessions)
- {
- // Yes - make sure the Network class doesn't discard its buffers yet
- // NB: This must happen here, because NetworkTransaction::Write() might already release OutputBuffers
- gcodeReply->IncreaseReferences(1);
- }
- else
- {
- // No - clean up again later
- clearReply = true;
- }
-
- if (reprap.Debug(moduleWebserver))
- {
- GetPlatform().MessageF(UsbMessage, "Sending G-Code reply to client %d of %d (length %u)\n", clientsServed, numSessions, gcodeReply->DataLength());
- }
- }
-
- // Send the whole G-Code reply as plain text to the client
- outBuf->copy( "HTTP/1.1 200 OK\n"
- "Cache-Control: no-cache, no-store, must-revalidate\n"
- "Pragma: no-cache\n"
- "Expires: 0\n"
- "Access-Control-Allow-Origin: *\n"
- "Content-Type: text/plain\n"
- );
- outBuf->catf("Content-Length: %u\n", gcodeReply->DataLength());
- outBuf->cat("Connection: close\n\n");
- outStack->Append(gcodeReply);
- Commit();
-
- // Possibly clean up the G-code reply once again
- if (clearReply)
- {
- gcodeReply->Clear();
- }
-}
-
-void HttpResponder::SendJsonResponse(const char* command)
-{
- // Try to authorise the user automatically to retain compatibility with the old web interface
- if (!CheckAuthenticated() && reprap.NoPasswordSet())
- {
- Authenticate();
- }
-
- // Update the authentication status and try handle "text/plain" requests here
- if (CheckAuthenticated())
- {
- if (StringEquals(command, "reply")) // rr_reply
- {
- SendGCodeReply();
- return;
- }
-
- if (StringEquals(command, "configfile")) // rr_configfile [DEPRECATED]
- {
- const char *configPath = GetPlatform().GetMassStorage()->CombineName(GetPlatform().GetSysDir(), GetPlatform().GetConfigFile());
- char fileName[MaxFilenameLength];
- SafeStrncpy(fileName, configPath, ARRAY_SIZE(fileName));
- SendFile(fileName, false);
- return;
- }
-
- if (StringEquals(command, "download"))
- {
- const char* const filename = GetKeyValue("name");
- if (filename != nullptr)
- {
- SendFile(filename, false);
- return;
- }
- }
- }
-
- // Try to process a request for JSON responses
- OutputBuffer *jsonResponse;
- if (!OutputBuffer::Allocate(jsonResponse))
- {
- // Reset the connection immediately if we cannot write any data. Should never happen.
- skt->Terminate();
- return;
- }
-
- bool mayKeepOpen;
- const bool gotResponse = GetJsonResponse(command, jsonResponse, mayKeepOpen);
- if (!gotResponse)
- {
- // Either this request was rejected, or it will take longer to process e.g. rr_fileinfo
- OutputBuffer::Release(jsonResponse);
- return;
- }
-
- // Send the JSON response
- bool keepOpen = false;
- if (mayKeepOpen)
- {
- // Check that the browser wants to persist the connection too
- for (size_t i = 0; i < numHeaderKeys; ++i)
- {
- if (StringEquals(headers[i].key, "Connection"))
- {
- // Comment out the following line to disable persistent connections
- keepOpen = StringEquals(headers[i].value, "keep-alive");
- break;
- }
- }
- }
-
- outBuf->copy( "HTTP/1.1 200 OK\n"
- "Cache-Control: no-cache, no-store, must-revalidate\n"
- "Pragma: no-cache\n"
- "Expires: 0\n"
- "Access-Control-Allow-Origin: *\n"
- "Content-Type: application/json\n"
- );
- outBuf->catf("Content-Length: %u\n", (jsonResponse != nullptr) ? jsonResponse->Length() : 0);
- outBuf->catf("Connection: %s\n\n", keepOpen ? "keep-alive" : "close");
- outBuf->Append(jsonResponse);
-
- Commit(keepOpen ? ResponderState::reading : ResponderState::free);
-}
-
-// Process the message received so far. We have reached the end of the headers.
-// Return true if the message is complete, false if we want to continue receiving data (i.e. postdata)
-void HttpResponder::ProcessMessage()
-{
- if (reprap.Debug(moduleWebserver))
- {
- GetPlatform().MessageF(UsbMessage, "HTTP req, command words {");
- for (size_t i = 0; i < numCommandWords; ++i)
- {
- GetPlatform().MessageF(UsbMessage, " %s", commandWords[i]);
- }
- GetPlatform().Message(UsbMessage, " }, parameters {");
-
- for (size_t i = 0; i < numQualKeys; ++i)
- {
- GetPlatform().MessageF(UsbMessage, " %s=%s", qualifiers[i].key, qualifiers[i].value);
- }
- GetPlatform().Message(UsbMessage, " }\n");
- }
-
- if (numCommandWords < 2)
- {
- RejectMessage("too few command words");
- return;
- }
-
- if (StringEquals(commandWords[0], "GET"))
- {
- if (StringStartsWith(commandWords[1], KO_START))
- {
- SendJsonResponse(commandWords[1] + KoFirst);
- }
- else if (commandWords[1][0] == '/' && StringStartsWith(commandWords[1] + 1, KO_START))
- {
- SendJsonResponse(commandWords[1] + 1 + KoFirst);
- }
- else
- {
- SendFile(commandWords[1], true);
- }
- return;
- }
-
- if (StringEquals(commandWords[0], "OPTIONS"))
- {
- outBuf->copy( "HTTP/1.1 200 OK\n"
- "Allow: OPTIONS, GET, POST\n"
- "Cache-Control: no-cache, no-store, must-revalidate\n"
- "Pragma: no-cache\n"
- "Expires: 0\n"
- "Access-Control-Allow-Origin: *\n"
- "Access-Control-Allow-Headers: Content-Type\n"
- "Content-Length: 0\n"
- "\n"
- );
- Commit();
- return;
- }
-
- if (CheckAuthenticated() && StringEquals(commandWords[0], "POST"))
- {
- const bool isUploadRequest = (StringEquals(commandWords[1], KO_START "upload"))
- || (commandWords[1][0] == '/' && StringEquals(commandWords[1] + 1, KO_START "upload"));
- if (isUploadRequest)
- {
- const char* const filename = GetKeyValue("name");
- if (filename != nullptr)
- {
- // See how many bytes we expect to read
- bool contentLengthFound = false;
- for (size_t i = 0; i < numHeaderKeys; i++)
- {
- if (StringEquals(headers[i].key, "Content-Length"))
- {
- postFileLength = atoi(headers[i].value);
- contentLengthFound = true;
- break;
- }
- }
-
- // Start POST file upload
- if (!contentLengthFound)
- {
- RejectMessage("invalid POST upload request");
- return;
- }
-
- // Start a new file upload
- FileStore *file = GetPlatform().OpenFile(FS_PREFIX, filename, OpenMode::write);
- if (file == nullptr)
- {
- RejectMessage("could not create file");
- return;
-
- }
- StartUpload(file, filename);
-
- // Try to get the last modified file date and time
- const char* const lastModifiedString = GetKeyValue("time");
- if (lastModifiedString != nullptr)
- {
- struct tm timeInfo;
- memset(&timeInfo, 0, sizeof(timeInfo));
- if (strptime(lastModifiedString, "%Y-%m-%dT%H:%M:%S", &timeInfo) != nullptr)
- {
- fileLastModified = mktime(&timeInfo);
- }
- else
- {
- fileLastModified = 0;
- }
- }
- else
- {
- fileLastModified = 0;
- }
-
- if (reprap.Debug(moduleWebserver))
- {
- GetPlatform().MessageF(UsbMessage, "Start uploading file %s length %lu\n", filename, postFileLength);
- }
- uploadedBytes = 0;
-
- // Keep track of the connection that is now uploading
- const uint32_t remoteIP = GetRemoteIP();
- const uint16_t remotePort = skt->GetRemotePort();
- for(size_t i = 0; i < numSessions; i++)
- {
- if (sessions[i].ip == remoteIP)
- {
- sessions[i].postPort = remotePort;
- sessions[i].isPostUploading = true;
- break;
- }
- }
- return;
- }
- }
- RejectMessage("only rr_upload is supported for POST requests");
- }
- else
- {
- RejectMessage("Unknown message type or not authenticated");
- }
-}
-
-// Reject the current message
-void HttpResponder::RejectMessage(const char* response, unsigned int code)
-{
- if (reprap.Debug(moduleWebserver))
- {
- GetPlatform().MessageF(UsbMessage, "Webserver: rejecting message with: %u %s\n", code, response);
- }
- outBuf->printf("HTTP/1.1 %u %s\nConnection: close\n\n", code, response);
- Commit();
-}
-
-// This function overrides the one in class NetworkResponder.
-// It tries to process a chunk of uploaded data and changes the state if finished.
-void HttpResponder::DoUpload()
-{
- const uint8_t *buffer;
- size_t len;
- if (skt->ReadBuffer(buffer, len))
- {
- skt->Taken(len);
- uploadedBytes += len;
-
- if (!fileBeingUploaded.Write(buffer, len))
- {
- uploadError = true;
- GetPlatform().Message(ErrorMessage, "Could not write upload data!\n");
- CancelUpload();
- SendJsonResponse("upload");
- return;
- }
- }
-
- // See if the upload has finished
- if (uploadedBytes >= postFileLength)
- {
- // Reset POST upload state for this client
- const uint32_t remoteIP = GetRemoteIP();
- for (size_t i = 0; i < numSessions; i++)
- {
- if (sessions[i].ip == remoteIP && sessions[i].isPostUploading)
- {
- sessions[i].isPostUploading = false;
- sessions[i].lastQueryTime = millis();
- break;
- }
- }
-
- FinishUpload(postFileLength, fileLastModified);
- SendJsonResponse("upload");
- return;
- }
- else if (!skt->CanRead())
- {
- // We cannot read any more, discard the transaction
- ConnectionLost();
- }
-}
-
-// This is called to force termination if we implement the specified protocol
-void HttpResponder::Terminate(Protocol protocol)
-{
- if (responderState != ResponderState::free && (protocol == HttpProtocol || protocol == AnyProtocol))
- {
- ConnectionLost();
- }
-}
-
-// This overrides the version in class NetworkResponder
-void HttpResponder::ConnectionLost()
-{
- fileInfoLock.Release(this);
- NetworkResponder::ConnectionLost();
-}
-
-// This overrides the version in class NetworkResponder
-void HttpResponder::CancelUpload()
-{
- if (skt != nullptr)
- {
- for (size_t i = 0; i < numSessions; i++)
- {
- if (sessions[i].ip == skt->GetRemoteIP() && sessions[i].isPostUploading)
- {
- sessions[i].isPostUploading = false;
- sessions[i].lastQueryTime = millis();
- break;
- }
- }
- }
- NetworkResponder::CancelUpload();
-}
-
-// This overrides the version in class NetworkResponder
-void HttpResponder::SendData()
-{
- NetworkResponder::SendData();
- if (responderState == ResponderState::reading)
- {
- timer = millis(); // restart the timer
- }
-}
-
-void HttpResponder::Diagnostics(MessageType mt) const
-{
- GetPlatform().MessageF(mt, " HTTP(%d)", (int)responderState);
-}
-
-/*static*/ void HttpResponder::HandleGCodeReply(const char *reply)
-{
- if (numSessions > 0)
- {
- OutputBuffer *buffer = gcodeReply->GetLastItem();
- if (buffer == nullptr || buffer->IsReferenced())
- {
- if (!OutputBuffer::Allocate(buffer))
- {
- // No more space available, stop here
- return;
- }
- gcodeReply->Push(buffer);
- }
-
- buffer->cat(reply);
- clientsServed = 0;
- seq++;
- }
-}
-
-/*static*/ void HttpResponder::HandleGCodeReply(OutputBuffer *reply)
-{
- if (reply != nullptr)
- {
- if (numSessions > 0)
- {
- // FIXME: This might cause G-code responses to be sent twice to fast HTTP clients, but
- // I (chrishamm) cannot think of a nicer way to deal with slow clients at the moment...
- gcodeReply->Push(reply);
- clientsServed = 0;
- seq++;
- }
- else
- {
- // Don't use buffers that may never get released...
- OutputBuffer::ReleaseAll(reply);
- }
- }
-}
-
-
-/*static*/ void HttpResponder::CheckSessions()
-{
- const uint32_t now = millis();
- for (size_t i = numSessions; i != 0; )
- {
- --i;
- if ((now - sessions[i].lastQueryTime) > HttpSessionTimeout)
- {
- // Check for timed out sessions
- for (size_t k = i + 1; k < numSessions; k++)
- {
- memcpy(&sessions[k - 1], &sessions[k], sizeof(HttpSession));
- }
- numSessions--;
- clientsServed++; // assume the disconnected client hasn't fetched the G-Code reply yet
- }
- }
-
- // If we cannot send the G-Code reply to anyone, we may free up some run-time space by dumping it
- if (numSessions == 0 || clientsServed >= numSessions)
- {
- while (!gcodeReply->IsEmpty())
- {
- OutputBuffer::ReleaseAll(gcodeReply->Pop());
- }
- clientsServed = 0;
- }
-}
-
-/*static*/ void HttpResponder::CommonDiagnostics(MessageType mtype)
-{
- GetPlatform().MessageF(mtype, "HTTP sessions: %u of %u\n", numSessions, MaxHttpSessions);
-}
-
-// Static data
-
-HttpResponder::HttpSession HttpResponder::sessions[MaxHttpSessions];
-unsigned int HttpResponder::numSessions = 0;
-unsigned int HttpResponder::clientsServed = 0;
-
-uint32_t HttpResponder::seq = 0;
-OutputStack *HttpResponder::gcodeReply = new OutputStack();
-
-NetworkResponderLock HttpResponder::fileInfoLock;
-
-// End
diff --git a/src/Network2/HttpResponder.h b/src/Network2/HttpResponder.h
deleted file mode 100644
index b2369d22..00000000
--- a/src/Network2/HttpResponder.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * HttpResponder.h
- *
- * Created on: 14 Apr 2017
- * Author: David
- */
-
-#ifndef SRC_DUETNG_DUETETHERNET_HTTPRESPONDER_H_
-#define SRC_DUETNG_DUETETHERNET_HTTPRESPONDER_H_
-
-#include "NetworkResponder.h"
-
-class HttpResponder : public NetworkResponder
-{
-public:
- HttpResponder(NetworkResponder *n);
- bool Spin() override; // do some work, returning true if we did anything significant
- bool Accept(Socket *s, Protocol protocol) override; // ask the responder to accept this connection, returns true if it did
- void Terminate(Protocol protocol) override; // terminate the responder if it is serving the specified protocol
- void Diagnostics(MessageType mtype) const override;
-
- static void HandleGCodeReply(const char *reply);
- static void HandleGCodeReply(OutputBuffer *reply);
- static uint32_t GetReplySeq() { return seq; }
- static void CheckSessions();
- static void CommonDiagnostics(MessageType mtype);
-
-protected:
- void ConnectionLost() override;
- void CancelUpload() override;
- void SendData() override;
-
-private:
- static const size_t MaxHttpSessions = 8; // maximum number of simultaneous HTTP sessions
- static const uint16_t WebMessageLength = TCP_MSS; // maximum length of the web message we accept after decoding
- static const size_t MaxCommandWords = 4; // max number of space-separated words in the command
- static const size_t MaxQualKeys = 5; // max number of key/value pairs in the qualifier
- static const size_t MaxHeaders = 30; // max number of key/value pairs in the headers
- static const uint32_t HttpSessionTimeout = 8000; // HTTP session timeout in milliseconds
-
- enum class HttpParseState
- {
- doingCommandWord, // receiving a word in the first line of the HTTP request
- doingFilename, // receiving the filename (second word in the command line)
- doingFilenameEsc1, // received '%' in the filename (e.g. we are being asked for a filename with spaces in it)
- doingFilenameEsc2, // received '%' and one hex digit in the filename
- doingQualifierKey, // receiving a key name in the HTTP request
- doingQualifierValue, // receiving a key value in the HTTP request
- doingQualifierValueEsc1, // received '%' in the qualifier
- doingQualifierValueEsc2, // received '%' and one hex digit in the qualifier
- doingHeaderKey, // receiving a header key
- expectingHeaderValue, // expecting a header value
- doingHeaderValue, // receiving a header value
- doingHeaderContinuation // received a newline after a header value
- };
-
- struct KeyValueIndices
- {
- const char* key;
- const char* value;
- };
-
- // HTTP sessions
- struct HttpSession
- {
- uint32_t ip;
- uint32_t lastQueryTime;
- bool isPostUploading;
- uint16_t postPort;
- };
-
- bool Authenticate();
- bool CheckAuthenticated();
- bool RemoveAuthentication();
-
- bool CharFromClient(char c);
- void SendFile(const char* nameOfFileToSend, bool isWebFile);
- void SendGCodeReply();
- void SendJsonResponse(const char* command);
- bool GetJsonResponse(const char* request, OutputBuffer *&response, bool& keepOpen);
- void ProcessMessage();
- void RejectMessage(const char* s, unsigned int code = 500);
- bool SendFileInfo();
-
- void DoUpload();
-
- const char* GetKeyValue(const char *key) const; // return the value of the specified key, or nullptr if not present
-
- HttpParseState parseState;
-
- // Buffers for processing HTTP input
- char clientMessage[WebMessageLength + 3]; // holds the command, qualifier, and headers
- size_t clientPointer; // current index into clientMessage
- char decodeChar; // the character we are decoding in a URL-encoded argument
-
- // Parser state
- const char* commandWords[MaxCommandWords];
- KeyValueIndices qualifiers[MaxQualKeys + 1]; // offsets into clientQualifier of the key/value pairs, the +1 is needed so that values can contain nulls
- KeyValueIndices headers[MaxHeaders]; // offsets into clientHeader of the key/value pairs
- size_t numCommandWords;
- size_t numQualKeys; // number of qualifier keys we have found, <= maxQualKeys
- size_t numHeaderKeys; // number of keys we have found, <= maxHeaders
-
- // rr_fileinfo requests
- char filenameBeingProcessed[MaxFilenameLength]; // The filename being processed (for rr_fileinfo)
-
- // Keeping track of HTTP sessions
- static HttpSession sessions[MaxHttpSessions];
- static unsigned int numSessions;
- static unsigned int clientsServed;
-
- // Responses from GCodes class
- static uint32_t seq; // Sequence number for G-Code replies
- static OutputStack *gcodeReply;
-
- static NetworkResponderLock fileInfoLock; // PrintMonitor::GetFileInfoResponse is single threaded at present, so use this to control access
-};
-
-#endif /* SRC_DUETNG_DUETETHERNET_HTTPRESPONDER_H_ */
diff --git a/src/Network2/NetworkBuffer.cpp b/src/Network2/NetworkBuffer.cpp
deleted file mode 100644
index 12d924d9..00000000
--- a/src/Network2/NetworkBuffer.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * NetworkBuffer.cpp
- *
- * Created on: 24 Dec 2016
- * Author: David
- */
-
-#include "NetworkBuffer.h"
-
-#include "Storage/FileStore.h"
-
-NetworkBuffer *NetworkBuffer::freelist = nullptr;
-
-NetworkBuffer::NetworkBuffer(NetworkBuffer *n) : next(n), dataLength(0), readPointer(0)
-{
-}
-
-// Release this buffer and return the next one in the chain
-NetworkBuffer *NetworkBuffer::Release()
-{
- NetworkBuffer *ret = next;
- next = freelist;
- freelist = this;
- return ret;
-}
-
-// Read 1 character, returning true if successful, false if no data left
-bool NetworkBuffer::ReadChar(char& b)
-{
- if (readPointer < dataLength)
- {
- b = Data()[readPointer++];
- return true;
- }
-
- b = 0;
- return false;
-}
-
-// Return the amount of data available, including continuation buffers
-size_t NetworkBuffer::TotalRemaining() const
-{
- const NetworkBuffer *b = this;
- size_t ret = 0;
- 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;
-}
-
-// Find the last buffer in a list
-/*static*/ NetworkBuffer *NetworkBuffer::FindLast(NetworkBuffer *list)
-{
- if (list != nullptr)
- {
- while (list->next != nullptr)
- {
- list = list->next;
- }
- }
- return list;
-}
-
-/*static*/ NetworkBuffer *NetworkBuffer::Allocate()
-{
- NetworkBuffer *ret = freelist;
- if (ret != nullptr)
- {
- freelist = ret->next;
- ret->next = nullptr;
- ret->dataLength = ret->readPointer = 0;
- }
- return ret;
-}
-
-/*static*/ void NetworkBuffer::AllocateBuffers(unsigned int number)
-{
- while (number != 0)
- {
- freelist = new NetworkBuffer(freelist);
- --number;
- }
-}
-
-// Count how many buffers there are in a chain
-/*static*/ unsigned int NetworkBuffer::Count(NetworkBuffer*& ptr)
-{
- unsigned int ret = 0;
- for (NetworkBuffer *n = ptr; n != nullptr; n = n->next)
- {
- ++ret;
- }
- return ret;
-}
-
-// End
diff --git a/src/Network2/NetworkBuffer.h b/src/Network2/NetworkBuffer.h
deleted file mode 100644
index 306e8a22..00000000
--- a/src/Network2/NetworkBuffer.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * NetworkBuffer.h
- *
- * Created on: 24 Dec 2016
- * Author: David
- */
-
-#ifndef SRC_DUETNG_DUETETHERNET_NETWORKBUFFER_H_
-#define SRC_DUETNG_DUETETHERNET_NETWORKBUFFER_H_
-
-#include "RepRapFirmware.h"
-#include "NetworkDefs.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
-{
-public:
- friend class Socket;
-
- // Release this buffer and return the next one in the chain
- NetworkBuffer *Release();
-
- // Read 1 character, returning true of successful, false if no data left
- bool ReadChar(char& b);
-
- const uint8_t* UnreadData() const { return Data() + readPointer; }
-
- // Return the amount of data available, not including continuation buffers
- size_t Remaining() const { return dataLength - readPointer; }
-
- // 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; }
-
- // Mark some data as taken
- void Taken(size_t amount) { readPointer += amount; }
-
- // Return the length available for writing
- size_t SpaceLeft() const { return bufferSize - dataLength; }
-
- // Return a pointer to the space available for writing
- uint8_t* UnwrittenData() { return Data() + 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);
-
- // Find the last buffer in a list
- static NetworkBuffer *FindLast(NetworkBuffer *list);
-
- // Allocate a buffer
- static NetworkBuffer *Allocate();
-
- // Alocate buffers and put them in the freelist
- static void AllocateBuffers(unsigned int number);
-
- // Count how many buffers there are in a chain
- static unsigned int Count(NetworkBuffer*& ptr);
-
- static const size_t bufferSize =
-#ifdef USE_3K_BUFFERS
- 3 * 1024;
-#else
- 2 * 1024;
-#endif
-
-private:
- NetworkBuffer(NetworkBuffer *n);
- uint8_t *Data() { return reinterpret_cast<uint8_t*>(data32); }
- const uint8_t *Data() const { return reinterpret_cast<const uint8_t*>(data32); }
-
- NetworkBuffer *next;
- size_t dataLength;
- size_t readPointer;
-#ifdef DUET_WIFI
- // When doing unaligned transfers on the WiFi interface, up to 3 extra bytes may be returned
- uint32_t data32[bufferSize/sizeof(uint32_t) + 1]; // 32-bit aligned buffer so we can do direct DMA
-#else
- uint32_t data32[bufferSize/sizeof(uint32_t)]; // 32-bit aligned buffer so we can do direct DMA
-#endif
- static NetworkBuffer *freelist;
-};
-
-#endif /* SRC_DUETNG_DUETETHERNET_NETWORKBUFFER_H_ */
diff --git a/src/Network2/NetworkDefs.h b/src/Network2/NetworkDefs.h
deleted file mode 100644
index e0182b5f..00000000
--- a/src/Network2/NetworkDefs.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * NetworkDefs.h
- *
- * Created on: 25 Dec 2016
- * Author: David
- */
-
-#ifndef SRC_DUETNG_DUETETHERNET_NETWORKDEFS_H_
-#define SRC_DUETNG_DUETETHERNET_NETWORKDEFS_H_
-
-#include <cstdint>
-#include <cstddef>
-
-class Socket;
-class NetworkBuffer;
-
-typedef uint8_t SocketNumber;
-
-typedef uint16_t Port;
-typedef uint8_t Protocol;
-
-#ifndef DUET_WIFI
-const uint8_t DefaultMacAddress[6] = { 0xBE, 0xEF, 0xDE, 0xAD, 0xFE, 0xED };
-#endif
-
-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 };
-
-const size_t NumProtocols = 3; // number of network protocols we support, not counting FtpDataProtocol or AnyProtocol
-const Protocol HttpProtocol = 0, FtpProtocol = 1, TelnetProtocol = 2, FtpDataProtocol = 3, AnyProtocol = 255;
-
-const Port DefaultHttpPort = 80;
-const Port DefaultFtpPort = 21;
-const Port DefaultTelnetPort = 23;
-
-const unsigned int TCP_MSS = 1460;
-
-const size_t NetworkBufferCount = 8; // number of 2K network buffers
-
-// Define the following to use 3K buffers on the W5500 for the HTTP sockets and smaller buffers for everything else
-// It doesn't seem to work, the chip keeps telling us that 1 byte is available.
-//#define USE_3K_BUFFERS 1
-
-#endif /* SRC_DUETNG_DUETETHERNET_NETWORKDEFS_H_ */
diff --git a/src/Network2/NetworkResponder.cpp b/src/Network2/NetworkResponder.cpp
deleted file mode 100644
index 6b84defb..00000000
--- a/src/Network2/NetworkResponder.cpp
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * NetworkResponder.cpp
- *
- * Created on: 14 Apr 2017
- * Author: David
- */
-
-#include "RepRapFirmware.h"
-#include "NetworkResponder.h"
-#include "Platform.h"
-#include "OutputMemory.h"
-
-// NetworkResponderLock members
-
-// Acquire a lock
-bool NetworkResponderLock::Acquire(const NetworkResponder *who)
-{
- if (owner == nullptr)
- {
- owner = who;
- return true;
- }
- if (owner == who)
- {
- return true;
- }
- return false;
-
-}
-
-// Release a lock
-void NetworkResponderLock::Release(const NetworkResponder *who)
-{
- if (owner == who)
- {
- owner = nullptr;
- }
-}
-
-// NetworkResponder members
-
-NetworkResponder::NetworkResponder(NetworkResponder *n)
- : next(n), responderState(ResponderState::free), skt(nullptr),
- outBuf(nullptr), outStack(new OutputStack), fileBeingSent(nullptr), fileBuffer(nullptr)
-{
-}
-
-// Send the contents of the output buffers
-void NetworkResponder::Commit(ResponderState nextState)
-{
- stateAfterSending = nextState;
- responderState = ResponderState::sending;
- if (reprap.Debug(moduleWebserver))
- {
- debugPrintf("Sending reply, file = %s\n", (fileBeingSent != nullptr) ? "yes" : "no");
- }
-}
-
-// Send our data.
-// We send outBuf first, then outStack, and finally fileBeingSent.
-void NetworkResponder::SendData()
-{
- // Send our output buffer and output stack
- for(;;)
- {
- if (outBuf == nullptr)
- {
- outBuf = outStack->Pop();
- if (outBuf == nullptr)
- {
- break;
- }
- }
- const size_t bytesLeft = outBuf->BytesLeft();
- if (bytesLeft == 0)
- {
- outBuf = OutputBuffer::Release(outBuf);
- }
- else
- {
- const size_t sent = skt->Send(reinterpret_cast<const uint8_t *>(outBuf->UnreadData()), bytesLeft);
- if (sent == 0)
- {
- // Check whether the connection has been closed
- if (!skt->CanSend())
- {
- // The connection has been lost or the other end has closed it
- if (reprap.Debug(moduleWebserver))
- {
- debugPrintf("Can't send anymore\n");
- }
- ConnectionLost();
- }
- return;
- }
-
- outBuf->Taken(sent); // tell the output buffer how much data we have taken
- if (sent < bytesLeft)
- {
- return;
- }
- outBuf = OutputBuffer::Release(outBuf);
- }
- }
-
- // If we get here then there are no output buffers left to send
- // If we have a file to send, send it
- if (fileBeingSent != nullptr && fileBuffer == nullptr)
- {
- fileBuffer = NetworkBuffer::Allocate();
- if (fileBuffer == nullptr)
- {
- return; // no buffer available, try again later
- }
- }
-
- // If we have a file buffer here, we must be in the process of sending a file
- while (fileBuffer != nullptr)
- {
- if (fileBuffer->IsEmpty() && fileBeingSent != nullptr)
- {
- const int bytesRead = fileBuffer->ReadFromFile(fileBeingSent);
- if (bytesRead != (int)NetworkBuffer::bufferSize)
- {
- // We had a read error or we reached the end of the file
- fileBeingSent->Close();
- fileBeingSent = nullptr;
- }
- }
-
- if (fileBuffer->IsEmpty())
- {
- // Must have sent the whole file
- fileBuffer->Release();
- fileBuffer = nullptr;
- }
- else
- {
- const size_t remaining = fileBuffer->Remaining();
- const size_t sent = skt->Send(fileBuffer->UnreadData(), remaining);
- if (sent == 0)
- {
- // Check whether the connection has been closed
- if (!skt->CanSend())
- {
- if (reprap.Debug(moduleWebserver))
- {
- debugPrintf("Can't send anymore\n");
- }
- ConnectionLost();
- }
- return;
- }
-
- fileBuffer->Taken(sent);
- if (sent < remaining)
- {
- return;
- }
- }
- }
-
- // If we get here then there is nothing left to send
- skt->Send(); // tell the socket there is no more data
-
- // If we are going to free up this responder after sending, then we must close the connection
- if (stateAfterSending == ResponderState::free)
- {
- skt->Close();
- skt = nullptr;
- }
- responderState = stateAfterSending;
-}
-
-// This is called when we lose a connection or when we are asked to terminate. Overridden in some derived classes.
-void NetworkResponder::ConnectionLost()
-{
- CancelUpload();
- OutputBuffer::ReleaseAll(outBuf);
- outBuf = nullptr;
- outStack->ReleaseAll();
-
- if (fileBeingSent != nullptr)
- {
- fileBeingSent->Close();
- fileBeingSent = nullptr;
- }
-
- if (fileBuffer != nullptr)
- {
- fileBuffer->Release();
- fileBuffer = nullptr;
- }
-
- if (skt != nullptr)
- {
- skt->Terminate();
- skt = nullptr;
- }
-
- responderState = ResponderState::free;
-}
-
-// Start writing to a new file
-void NetworkResponder::StartUpload(FileStore *file, const char *fileName)
-{
- fileBeingUploaded.Set(file);
- SafeStrncpy(filenameBeingUploaded, fileName, ARRAY_SIZE(filenameBeingUploaded));
- responderState = ResponderState::uploading;
- uploadError = false;
-}
-
-// If this responder has an upload in progress, cancel it
-void NetworkResponder::CancelUpload()
-{
- if (fileBeingUploaded.IsLive())
- {
- fileBeingUploaded.Close();
- if (filenameBeingUploaded[0] != 0)
- {
- GetPlatform().GetMassStorage()->Delete(FS_PREFIX, filenameBeingUploaded);
- }
- }
-}
-
-// Finish a file upload. Set variable uploadError if anything goes wrong.
-void NetworkResponder::FinishUpload(uint32_t fileLength, time_t fileLastModified)
-{
- // Flush remaining data for FSO
- if (!fileBeingUploaded.Flush())
- {
- uploadError = true;
- GetPlatform().Message(ErrorMessage, "Could not flush remaining data while finishing upload!\n");
- }
-
- // Check the file length is as expected
- if (fileLength != 0 && fileBeingUploaded.Length() != fileLength)
- {
- uploadError = true;
- GetPlatform().MessageF(ErrorMessage, "Uploaded file size is different (%lu vs. expected %lu bytes)!\n", fileBeingUploaded.Length(), fileLength);
- }
-
- // Close the file
- if (fileBeingUploaded.IsLive())
- {
- fileBeingUploaded.Close();
- }
-
- // Delete the file again if an error has occurred
- if (filenameBeingUploaded[0] != 0)
- {
- if (uploadError)
- {
- GetPlatform().GetMassStorage()->Delete(FS_PREFIX, filenameBeingUploaded);
- }
- else if (fileLastModified != 0)
- {
- // Update the file timestamp if it was specified
- (void)GetPlatform().GetMassStorage()->SetLastModifiedTime(nullptr, filenameBeingUploaded, fileLastModified);
- }
- }
-
- // Clean up again
- filenameBeingUploaded[0] = 0;
-}
-
-uint32_t NetworkResponder::GetRemoteIP() const
-{
- return (skt == nullptr) ? 0 : skt->GetRemoteIP();
-}
-
-// End
diff --git a/src/Network2/NetworkResponder.h b/src/Network2/NetworkResponder.h
deleted file mode 100644
index ea492524..00000000
--- a/src/Network2/NetworkResponder.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * NetworkResponder.h
- *
- * Created on: 14 Apr 2017
- * Author: David
- */
-
-#ifndef SRC_DUETNG_DUETETHERNET_NETWORKRESPONDER_H_
-#define SRC_DUETNG_DUETETHERNET_NETWORKRESPONDER_H_
-
-#include "RepRapFirmware.h"
-#include "RepRap.h"
-#include "NetworkDefs.h"
-#include "Socket.h"
-#include "Storage/FileData.h"
-#include "NetworkBuffer.h"
-
-// Forward declarations
-class NetworkResponder;
-
-// Class to implement a simple lock
-class NetworkResponderLock
-{
-public:
- NetworkResponderLock() : owner(nullptr) { }
-
- bool Acquire(const NetworkResponder *who);
- void Release(const NetworkResponder *who);
- bool IsOwnedBy(const NetworkResponder *who) const { return owner == who; }
-
-private:
- const NetworkResponder *owner;
-};
-
-// Network responder base class
-class NetworkResponder
-{
-public:
- NetworkResponder *GetNext() const { return next; }
- virtual bool Spin() = 0; // do some work, returning true if we did anything significant
- virtual bool Accept(Socket *s, Protocol protocol) = 0; // ask the responder to accept this connection, returns true if it did
- virtual void Terminate(Protocol protocol) = 0; // terminate the responder if it is serving the specified protocol
- virtual void Diagnostics(MessageType mtype) const = 0;
-
-protected:
- // States machine control. Not all derived classes use all states.
- enum class ResponderState
- {
- free = 0, // ready to be allocated
- reading, // ready to receive data
- sending, // sending data
- uploading, // uploading a file to SD card
-
- // HTTP responder additional states
- gettingFileInfoLock, // waiting to get the file info lock
- gettingFileInfo, // getting file info
-
- // FTP responder additional states
- waitingForPasvPort,
- pasvPortOpened,
- sendingPasvData,
- pasvTransferComplete,
-
- // Telnet responder additional states
- justConnected,
- authenticating
- };
-
- NetworkResponder(NetworkResponder *n);
-
- void Commit(ResponderState nextState = ResponderState::free);
- virtual void SendData();
- virtual void ConnectionLost();
-
- void StartUpload(FileStore *file, const char *fileName);
- void FinishUpload(uint32_t fileLength, time_t fileLastModified);
- virtual void CancelUpload();
-
- uint32_t GetRemoteIP() const;
-
- static Platform& GetPlatform() { return reprap.GetPlatform(); }
- static Network& GetNetwork() { return reprap.GetNetwork(); }
-
- // General state
- NetworkResponder *next; // next responder in the list
- ResponderState responderState; // the current state
- ResponderState stateAfterSending; // if we are sending, the state to enter when sending is complete
- Socket *skt;
- uint32_t timer; // a general purpose millisecond timer
-
- // Buffers for sending responses
- OutputBuffer *outBuf;
- OutputStack *outStack;
- FileStore *fileBeingSent;
- NetworkBuffer *fileBuffer;
-
- // File uploads
- FileData fileBeingUploaded;
- char filenameBeingUploaded[MaxFilenameLength];
- uint32_t postFileLength, uploadedBytes; // How many POST bytes do we expect and how many have already been written?
- time_t fileLastModified;
- bool uploadError;
-};
-
-#endif /* SRC_DUETNG_DUETETHERNET_NETWORKRESPONDER_H_ */
diff --git a/src/Network2/TelnetResponder.cpp b/src/Network2/TelnetResponder.cpp
deleted file mode 100644
index 13f570c4..00000000
--- a/src/Network2/TelnetResponder.cpp
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * TelnetResponder.cpp
- *
- * Created on: 15 Apr 2017
- * Author: David
- */
-
-#include "TelnetResponder.h"
-#include "OutputMemory.h"
-#include "GCodes/GCodes.h"
-#include "Platform.h"
-
-TelnetResponder::TelnetResponder(NetworkResponder *n) : NetworkResponder(n)
-{
-}
-
-// Ask the responder to accept this connection, returns true if it did
-bool TelnetResponder::Accept(Socket *s, Protocol protocol)
-{
- if (responderState == ResponderState::free && protocol == TelnetProtocol)
- {
- // Make sure we can get an output buffer before we accept the connection, or we won't be able to reply
- if (outBuf != nullptr || OutputBuffer::Allocate(outBuf))
- {
- skt = s;
- clientPointer = 0;
- responderState = ResponderState::justConnected;
- connectTime = millis();
- haveCompleteLine = false;
- if (reprap.Debug(moduleWebserver))
- {
- debugPrintf("Telnet connection accepted\n");
- }
- return true;
- }
- }
- return false;
-}
-
-// This is called to force termination if we implement the specified protocol
-void TelnetResponder::Terminate(Protocol protocol)
-{
- if (responderState != ResponderState::free && (protocol == TelnetProtocol || protocol == AnyProtocol))
- {
- ConnectionLost();
- }
-}
-
-// Do some work, returning true if we did anything significant
-bool TelnetResponder::Spin()
-{
- switch (responderState)
- {
- case ResponderState::free:
- default:
- return false;
-
- case ResponderState::justConnected:
- if (millis() - connectTime < TelnetSetupDuration)
- {
- // Discard the setup message
- char c;
- while (skt->ReadChar(c)) { }
- connectTime = 0;
- return true;
- }
-
- // Check whether we need a password to log in
- if (reprap.NoPasswordSet())
- {
- // Don't send a login prompt if no password is set, so we don't mess up Pronterface
- responderState = ResponderState::reading;
- }
- else
- {
- outBuf->copy( "RepRapFirmware Telnet interface\r\n\r\n"
- "Please enter your password:\r\n"
- "> "
- );
- Commit(ResponderState::authenticating);
- }
- return true;
-
- case ResponderState::authenticating:
- {
- bool readSomething = false;
- char c;
- while (!haveCompleteLine && skt->ReadChar(c))
- {
- CharFromClient(c);
- readSomething = true;
- }
-
- if (!readSomething && !skt->CanRead())
- {
- ConnectionLost();
- return true;
- }
-
- if (haveCompleteLine && (outBuf != nullptr || OutputBuffer::Allocate(outBuf)))
- {
- haveCompleteLine = false;
- clientPointer = 0;
- if (reprap.CheckPassword(clientMessage))
- {
- outBuf->copy("Log in successful!\r\n");
- Commit(ResponderState::reading);
- }
- else
- {
- outBuf->copy("Invalid password.\r\n> ");
- Commit(ResponderState::authenticating);
- }
- return true;
- }
- return readSomething;
- }
-
- case ResponderState::reading:
- if (outBuf != nullptr && outBuf->BytesLeft() != 0)
- {
- // We have a gcode reply to send
- Commit(ResponderState::reading);
- return true;
- }
- {
- bool readSomething = false;
- char c;
- while (!haveCompleteLine && skt->ReadChar(c))
- {
- CharFromClient(c);
- readSomething = true;
- }
-
- if (!readSomething && !skt->CanRead())
- {
- ConnectionLost();
- return true;
- }
-
- if (haveCompleteLine)
- {
- ProcessLine();
- return true;
- }
- return readSomething;
- }
-
- case ResponderState::sending:
- SendData();
- return true;
- }
-}
-
-// Process a character from the client, returning true if we have a complete line
-void TelnetResponder::CharFromClient(char c)
-{
- switch (c)
- {
- case 0:
- break;
-
- case '\b':
- // Allow backspace for pure Telnet clients like PuTTY
- if (clientPointer != 0)
- {
- clientPointer--;
- }
- break;
-
- case '\r':
- case '\n':
- if (clientPointer != 0)
- {
- // This line is complete
- clientMessage[clientPointer] = 0;
- haveCompleteLine = true;
- }
- break;
-
- default:
- clientMessage[clientPointer++] = c;
-
- // Make sure we don't overflow the line buffer
- if (clientPointer > ARRAY_UPB(clientMessage))
- {
- clientPointer = 0;
- GetPlatform().Message(UsbMessage, "Webserver: Buffer overflow in Telnet server!\n");
- }
- break;
- }
-}
-
-// Usually we should not try to send any data here, because that would purge the packet's
-// payload and mess with TCP streaming mode if Pronterface is used. However, under special
-// circumstances this must happen.
-void TelnetResponder::ProcessLine()
-{
- // Special commands for Telnet
- if (StringEquals(clientMessage, "exit") || StringEquals(clientMessage, "quit"))
- {
- if (outBuf != nullptr || OutputBuffer::Allocate(outBuf))
- {
- haveCompleteLine = false;
- clientPointer = 0;
-
- outBuf->copy("Goodbye.\r\n");
- Commit();
- }
- }
- else if (reprap.GetGCodes().GetTelnetInput()->BufferSpaceLeft() >= clientPointer + 1)
- {
- // All other codes are stored for the GCodes class
- RegularGCodeInput * const telnetInput = reprap.GetGCodes().GetTelnetInput();
- telnetInput->Put(TelnetMessage, clientMessage);
- haveCompleteLine = false;
- clientPointer = 0;
- }
-}
-
-void TelnetResponder::HandleGCodeReply(const char *reply)
-{
- if (reply != nullptr && (responderState == ResponderState::reading || responderState == ResponderState::sending))
- {
- // We need a valid OutputBuffer to start the conversion from NL to CRNL
- if (outBuf == nullptr)
- {
- if (!OutputBuffer::Allocate(outBuf))
- {
- // No more space available to store this reply, stop here
- return;
- }
- }
-
- // Write entire content to new output buffers, but this time with \r\n instead of \n
- while (*reply != 0)
- {
- if (*reply == '\n' && outBuf->cat('\r') == 0)
- {
- // No more space available, stop here
- return;
- }
- if (outBuf->cat(*reply) == 0)
- {
- // No more space available, stop here
- return;
- }
- reply++;
- }
- }
-}
-
-void TelnetResponder::HandleGCodeReply(OutputBuffer *reply)
-{
- if (reply != nullptr && (responderState == ResponderState::reading || responderState == ResponderState::sending))
- {
- // We need a valid OutputBuffer to start the conversion from NL to CRNL
- if (outBuf == nullptr)
- {
- if (!OutputBuffer::Allocate(outBuf))
- {
- OutputBuffer::Truncate(reply, OUTPUT_BUFFER_SIZE);
- if (!OutputBuffer::Allocate(outBuf))
- {
- // If we're really short on memory, release the G-Code reply instantly
- OutputBuffer::ReleaseAll(reply);
- return;
- }
- }
- }
-
- // Write entire content to new output buffers, but this time with \r\n instead of \n
- do {
- const char *data = reply->Data();
- for(size_t i = 0; i < reply->DataLength(); i++)
- {
- if (*data == '\n')
- {
- outBuf->cat('\r');
- }
- outBuf->cat(*data);
- data++;
- }
- reply = OutputBuffer::Release(reply);
- } while (reply != nullptr);
- }
- else
- {
- // Don't store buffers that may never get released...
- OutputBuffer::ReleaseAll(reply);
- }
-}
-
-void TelnetResponder::Diagnostics(MessageType mt) const
-{
- GetPlatform().MessageF(mt, " Telnet(%d)", (int)responderState);
-}
-
-// End
diff --git a/src/Network2/TelnetResponder.h b/src/Network2/TelnetResponder.h
deleted file mode 100644
index c4f4d9ef..00000000
--- a/src/Network2/TelnetResponder.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * TelnetResponder.h
- *
- * Created on: 14 Apr 2017
- * Author: David
- */
-
-#ifndef SRC_DUETNG_DUETETHERNET_TELNETRESPONDER_H_
-#define SRC_DUETNG_DUETETHERNET_TELNETRESPONDER_H_
-
-#include "NetworkResponder.h"
-
-class TelnetResponder : public NetworkResponder
-{
-public:
- TelnetResponder(NetworkResponder *n);
- bool Spin() override; // do some work, returning true if we did anything significant
- bool Accept(Socket *s, Protocol protocol) override; // ask the responder to accept this connection, returns true if it did
- void Terminate(Protocol protocol) override; // terminate the responder if it is serving the specified protocol
-
- void HandleGCodeReply(const char *reply);
- void HandleGCodeReply(OutputBuffer *reply);
- void Diagnostics(MessageType mtype) const override;
-
-private:
- void CharFromClient(char c);
- void ProcessLine();
-
- bool haveCompleteLine;
- char clientMessage[GCODE_LENGTH];
- size_t clientPointer;
- uint32_t connectTime;
-
- static const uint32_t TelnetSetupDuration = 4000; // ignore the first Telnet request within this duration (in ms)
-};
-
-#endif /* SRC_DUETNG_DUETETHERNET_TELNETRESPONDER_H_ */
diff --git a/src/Network2/W5500/Network.cpp b/src/Network2/W5500/Network.cpp
deleted file mode 100644
index 6cb6a0cc..00000000
--- a/src/Network2/W5500/Network.cpp
+++ /dev/null
@@ -1,555 +0,0 @@
-/*
- * Network.cpp
- *
- * Created on: 13 Dec 2016
- * Author: David
- */
-
-#include "Network.h"
-#include "Wiznet/Ethernet/wizchip_conf.h"
-#include "Wiznet/Internet/DHCP/dhcp.h"
-#include "NetworkBuffer.h"
-#include "Platform.h"
-#include "RepRap.h"
-#include "HttpResponder.h"
-#include "FtpResponder.h"
-#include "TelnetResponder.h"
-#include "Libraries/General/IP4String.h"
-
-const Port DefaultPortNumbers[NumProtocols] = { DefaultHttpPort, DefaultFtpPort, DefaultTelnetPort };
-const char * const ProtocolNames[NumProtocols] = { "HTTP", "FTP", "TELNET" };
-
-Network::Network(Platform& p)
- : platform(p), nextResponderToPoll(nullptr), lastTickMillis(0),
- state(NetworkState::disabled), activated(false)
-{
- for (size_t i = 0; i < NumProtocols; ++i)
- {
- portNumbers[i] = DefaultPortNumbers[i];
- protocolEnabled[i] = (i == HttpProtocol);
- }
-
- // Create the responders
- responders = telnetResponder = new TelnetResponder(nullptr);
- responders = ftpResponder = new FtpResponder(responders);
- for (unsigned int i = 0; i < NumHttpResponders; ++i)
- {
- responders = new HttpResponder(responders);
- }
-}
-
-void Network::Init()
-{
- // Ensure that the W5500 chip is in the reset state
- pinMode(W5500ResetPin, OUTPUT_LOW);
- longWait = millis();
- lastTickMillis = millis();
-
- NetworkBuffer::AllocateBuffers(NetworkBufferCount);
-
- SetIPAddress(DefaultIpAddress, DefaultNetMask, DefaultGateway);
- strcpy(hostname, HOSTNAME);
-}
-
-void Network::EnableProtocol(int protocol, int port, int secure, const StringRef& reply)
-{
- if (secure != 0 && secure != -1)
- {
- reply.copy("Error: this firmware does not support TLS");
- }
- else if (protocol >= 0 && protocol < (int)NumProtocols)
- {
- const Port portToUse = (port < 0) ? DefaultPortNumbers[protocol] : port;
- if (portToUse != portNumbers[protocol] && state == NetworkState::active)
- {
- // We need to shut down and restart the protocol if it is active because the port number has changed
- ShutdownProtocol(protocol);
- protocolEnabled[protocol] = false;
- }
- portNumbers[protocol] = portToUse;
- if (!protocolEnabled[protocol])
- {
- protocolEnabled[protocol] = true;
- if (state == NetworkState::active)
- {
- StartProtocol(protocol);
-#if 0 // mdns not implemented yet
- if (state == NetworkState::active)
- {
- DoMdnsAnnounce();
- }
-#endif
- }
- }
- ReportOneProtocol(protocol, reply);
- }
- else
- {
- reply.copy("Invalid protocol parameter");
- }
-}
-
-void Network::DisableProtocol(int protocol, const StringRef& reply)
-{
- if (protocol >= 0 && protocol < (int)NumProtocols)
- {
- if (state == NetworkState::active)
- {
- ShutdownProtocol(protocol);
- }
- protocolEnabled[protocol] = false;
- ReportOneProtocol(protocol, reply);
- }
- else
- {
- reply.copy("Invalid protocol parameter");
- }
-}
-
-void Network::StartProtocol(Protocol protocol)
-{
- switch(protocol)
- {
- case HttpProtocol:
- for (SocketNumber skt = 0; skt < NumHttpSockets; ++skt)
- {
- sockets[skt].Init(skt, portNumbers[protocol], protocol);
- }
- break;
-
- case FtpProtocol:
- sockets[FtpSocketNumber].Init(FtpSocketNumber, portNumbers[protocol], protocol);
- break;
-
- case TelnetProtocol:
- sockets[TelnetSocketNumber].Init(TelnetSocketNumber, portNumbers[protocol], protocol);
- break;
-
- default:
- break;
- }
-}
-
-void Network::ShutdownProtocol(Protocol protocol)
-{
- for (NetworkResponder* r = responders; r != nullptr; r = r->GetNext())
- {
- r->Terminate(protocol);
- }
-
- switch(protocol)
- {
- case HttpProtocol:
- for (SocketNumber skt = 0; skt < NumHttpSockets; ++skt)
- {
- sockets[skt].TerminateAndDisable();
- }
- break;
-
- case FtpProtocol:
- sockets[FtpSocketNumber].TerminateAndDisable();
- sockets[FtpDataSocketNumber].TerminateAndDisable();
- break;
-
- case TelnetProtocol:
- sockets[TelnetSocketNumber].TerminateAndDisable();
- break;
-
- default:
- break;
- }
-}
-
-// Report the protocols and ports in use
-void Network::ReportProtocols(const StringRef& reply) const
-{
- reply.Clear();
- for (size_t i = 0; i < NumProtocols; ++i)
- {
- if (i != 0)
- {
- reply.cat('\n');
- }
- ReportOneProtocol(i, reply);
- }
-}
-
-void Network::ReportOneProtocol(Protocol protocol, const StringRef& reply) const
-{
- if (protocolEnabled[protocol])
- {
- reply.catf("%s is enabled on port %u", ProtocolNames[protocol], portNumbers[protocol]);
- }
- else
- {
- reply.catf("%s is disabled", ProtocolNames[protocol]);
- }
-}
-
-// This is called at the end of config.g processing.
-// Start the network if it was enabled
-void Network::Activate()
-{
- if (!activated)
- {
- activated = true;
- if (state == NetworkState::enabled)
- {
- Start();
- }
- else
- {
- platform.Message(NetworkInfoMessage, "Network disabled.\n");
- }
- }
-}
-
-void Network::Exit()
-{
- Stop();
-}
-
-// Get the network state into the reply buffer, returning true if there is some sort of error
-bool Network::GetNetworkState(const StringRef& reply)
-{
- const uint8_t * const config_ip = platform.GetIPAddress();
- const int enableState = EnableState();
- reply.printf("Network is %s, configured IP address: %s, actual IP address: %s",
- (enableState == 0) ? "disabled" : "enabled",
- IP4String(config_ip).c_str(), IP4String(ipAddress).c_str());
- return false;
-}
-
-// Start up the network
-void Network::Start()
-{
- SetIPAddress(platform.GetIPAddress(), platform.NetMask(), platform.GateWay());
- pinMode(W5500ResetPin, OUTPUT_LOW);
- delayMicroseconds(550); // W550 reset pulse must be at least 500us long
- IoPort::WriteDigital(W5500ResetPin, HIGH); // raise /Reset pin
- delay(55); // W5500 needs 50ms to start up
-
-#ifdef USE_3K_BUFFERS
- static const uint8_t bufSizes[8] = { 3, 3, 3, 3, 1, 1, 1, 1 }; // 3K buffers for http, 1K for everything else (FTP will be slow)
-#else
- static const uint8_t bufSizes[8] = { 2, 2, 2, 2, 2, 2, 2, 2 }; // 2K buffers for everything
-#endif
-
- wizchip_init(bufSizes, bufSizes);
-
- setSHAR(platform.MACAddress());
- setSIPR(ipAddress);
- setGAR(gateway);
- setSUBR(netmask);
-
- state = NetworkState::establishingLink;
-}
-
-// Stop the network
-void Network::Stop()
-{
- if (state != NetworkState::disabled)
- {
- for (NetworkResponder *r = responders; r != nullptr; r = r->GetNext())
- {
- r->Terminate(AnyProtocol);
- }
- if (usingDhcp)
- {
- DHCP_stop();
- }
- digitalWrite(W5500ResetPin, LOW); // put the W5500 back into reset
- state = NetworkState::disabled;
- }
-}
-
-// 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)
- {
- case NetworkState::enabled:
- case NetworkState::disabled:
- default:
- // Nothing to do
- break;
-
- case NetworkState::establishingLink:
- if (full && wizphy_getphylink() == PHY_LINK_ON)
- {
- usingDhcp = (ipAddress[0] == 0 && ipAddress[1] == 0 && ipAddress[2] == 0 && ipAddress[3] == 0);
- if (usingDhcp)
- {
- // IP address is all zeros, so use DHCP
-// debugPrintf("Link established, getting IP address\n");
- DHCP_init(DhcpSocketNumber, hostname);
- lastTickMillis = millis();
- state = NetworkState::obtainingIP;
- }
- else
- {
-// debugPrintf("Link established, network running\n");
- state = NetworkState::connected;
- }
- }
- break;
-
- case NetworkState::obtainingIP:
- if (full)
- {
- if (wizphy_getphylink() == PHY_LINK_ON)
- {
- 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();
- state = NetworkState::connected;
- }
- }
- else
- {
-// debugPrintf("Lost phy link\n");
- DHCP_stop();
- TerminateSockets();
- state = NetworkState::establishingLink;
- }
- }
- break;
-
- case NetworkState::connected:
- if (full)
- {
- InitSockets();
- platform.MessageF(NetworkInfoMessage, "Network running, IP address = %s\n", IP4String(ipAddress).c_str());
- state = NetworkState::active;
- }
- break;
-
- case NetworkState::active:
- // Check that the link is still up
- if (wizphy_getphylink() == PHY_LINK_ON)
- {
- // Maintain DHCP
- if (full && usingDhcp)
- {
- const uint32_t now = millis();
- if (now - lastTickMillis >= 1000)
- {
- lastTickMillis += 1000;
- DHCP_time_handler();
- }
- const DhcpRunResult ret = DHCP_run();
- if (ret == DhcpRunResult::DHCP_IP_CHANGED)
- {
-// debugPrintf("IP address changed\n");
- getSIPR(ipAddress);
- }
- }
-
- // 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;
- }
-
- // Poll the responders
- if (full)
- {
- NetworkResponder *nr = nextResponderToPoll;
- bool doneSomething = false;
- do
- {
- if (nr == nullptr)
- {
- nr = responders; // 'responders' can't be null at this point
- }
- doneSomething = nr->Spin();
- nr = nr->GetNext();
- } while (!doneSomething && nr != nextResponderToPoll);
- nextResponderToPoll = nr;
- }
- }
- else if (full)
- {
-// debugPrintf("Lost phy link\n");
- if (usingDhcp)
- {
- DHCP_stop();
- }
- TerminateSockets();
- state = NetworkState::establishingLink;
- }
- break;
- }
-
- if (full)
- {
- platform.ClassReport(longWait);
- }
-}
-
-void Network::Diagnostics(MessageType mtype)
-{
- platform.MessageF(mtype, "=== Network ===\nState: %d\n", (int)state);
- HttpResponder::CommonDiagnostics(mtype);
- platform.Message(mtype, "Responder states:");
- for (NetworkResponder *r = responders; r != nullptr; r = r->GetNext())
- {
- r->Diagnostics(mtype);
- }
- platform.Message(mtype, "\n");
-}
-
-// Enable or disable the network
-void Network::Enable(int mode, const StringRef& reply)
-{
- if (!activated)
- {
- state = (mode == 0) ? NetworkState::disabled : NetworkState::enabled;
- }
- else if (mode == 0)
- {
- if (state != NetworkState::disabled)
- {
- Stop();
- platform.Message(NetworkInfoMessage, "Network stopped\n");
- }
-
- }
- else if (state == NetworkState::disabled)
- {
- state = NetworkState::enabled;
- Start();
- }
-}
-
-int Network::EnableState() const
-{
- return (state == NetworkState::disabled) ? 0 : 1;
-}
-
-void Network::SetIPAddress(const uint8_t p_ipAddress[], const uint8_t p_netmask[], const uint8_t p_gateway[])
-{
- memcpy(ipAddress, p_ipAddress, sizeof(ipAddress));
- memcpy(netmask, p_netmask, sizeof(netmask));
- memcpy(gateway, p_gateway, sizeof(gateway));
-}
-
-void Network::SetHostname(const char *name)
-{
- size_t i = 0;
- while (*name && i < ARRAY_UPB(hostname))
- {
- char c = *name++;
- if (c >= 'A' && c <= 'Z')
- {
- c += 'a' - 'A';
- }
-
- if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c == '-') || (c == '_'))
- {
- hostname[i++] = c;
- }
- }
-
- if (i != 0)
- {
- hostname[i] = 0;
- }
- else
- {
- strcpy(hostname, HOSTNAME);
- }
-}
-
-void Network::OpenDataPort(Port port)
-{
- sockets[FtpDataSocketNumber].Init(FtpDataSocketNumber, port, FtpDataProtocol);
-}
-
-// Close FTP data port and purge associated resources
-void Network::TerminateDataPort()
-{
- sockets[FtpDataSocketNumber].Terminate();
-}
-
-void Network::InitSockets()
-{
- for (size_t i = 0; i < NumProtocols; ++i)
- {
- if (protocolEnabled[i])
- {
- StartProtocol(i);
- }
- }
- nextSocketToPoll = 0;
-}
-
-// The following is called by the FTP responder to stop listening on the FTP data port
-// For the W5500 listening stop automatically when the port is terminated, so we don't need anything here
-void Network::DataPortClosing()
-{
- // nothing needed here
-}
-
-void Network::TerminateSockets()
-{
- for (SocketNumber skt = 0; skt < NumTcpSockets; ++skt)
- {
- sockets[skt].Terminate();
- }
-}
-
-// Find a responder to process a new connection
-bool Network::FindResponder(Socket *skt, Protocol protocol)
-{
- for (NetworkResponder *r = responders; r != nullptr; r = r->GetNext())
- {
- if (r->Accept(skt, protocol))
- {
- return true;
- }
- }
- return false;
-}
-
-void Network::HandleHttpGCodeReply(const char *msg)
-{
- HttpResponder::HandleGCodeReply(msg);
-}
-
-void Network::HandleTelnetGCodeReply(const char *msg)
-{
- telnetResponder->HandleGCodeReply(msg);
-}
-
-void Network::HandleHttpGCodeReply(OutputBuffer *buf)
-{
- HttpResponder::HandleGCodeReply(buf);
-}
-
-void Network::HandleTelnetGCodeReply(OutputBuffer *buf)
-{
- telnetResponder->HandleGCodeReply(buf);
-}
-
-uint32_t Network::GetHttpReplySeq()
-{
- return HttpResponder::GetReplySeq();
-}
-
-// End
diff --git a/src/Network2/W5500/Network.h b/src/Network2/W5500/Network.h
deleted file mode 100644
index cdf609c0..00000000
--- a/src/Network2/W5500/Network.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/****************************************************************************************************
-
-RepRapFirmware - Network: RepRapPro Ormerod with Duet controller
-
-Separated out from Platform.h by dc42 and extended by chrishamm
-
-****************************************************************************************************/
-
-#ifndef NETWORK_H
-#define NETWORK_H
-
-#include "Socket.h"
-#include "NetworkDefs.h"
-#include "MessageType.h"
-
-class NetworkResponder;
-class HttpResponder;
-class FtpResponder;
-class TelnetResponder;
-
-// We have 8 sockets available on the W5500.
-const size_t NumHttpSockets = 4; // sockets 0-3 are for HTTP
-const SocketNumber FtpSocketNumber = 4;
-const SocketNumber FtpDataSocketNumber = 5; // TODO can we allocate this dynamically when required, to allow more http sockets most of the time?
-const SocketNumber TelnetSocketNumber = 6;
-const size_t NumTcpSockets = 7;
-const SocketNumber DhcpSocketNumber = 7; // TODO can we allocate this dynamically when required, to allow more http sockets most of the time?
-
-const unsigned int NumHttpResponders = 4; // the number of concurrent HTTP requests we can process
-
-class Platform;
-
-// The main network class that drives the network.
-class Network
-{
-public:
- Network(Platform& p);
-
- void Init();
- void Activate();
- void Exit();
- void Spin(bool full);
- void Diagnostics(MessageType mtype);
- void Start();
- void Stop();
-
- void EnableProtocol(int protocol, int port, int secure, const StringRef& reply);
- void DisableProtocol(int protocol, const StringRef& reply);
- void ReportProtocols(const StringRef& reply) const;
-
- void Enable(int mode, const StringRef& reply); // enable or disable the network
- bool GetNetworkState(const StringRef& reply);
- int EnableState() const;
-
- void SetHostname(const char *name);
-
- bool FindResponder(Socket *skt, Protocol protocol);
-
- const uint8_t *GetIPAddress() const { return ipAddress; }
- void OpenDataPort(Port port);
- void TerminateDataPort();
- void DataPortClosing();
-
- void HandleHttpGCodeReply(const char *msg);
- void HandleTelnetGCodeReply(const char *msg);
- void HandleHttpGCodeReply(OutputBuffer *buf);
- void HandleTelnetGCodeReply(OutputBuffer *buf);
- uint32_t GetHttpReplySeq();
-
-private:
- enum class NetworkState
- {
- disabled, // Network disabled
- enabled, // Network enabled but not started yet
- establishingLink, // starting up, waiting for link
- obtainingIP, // link established, waiting for DHCP
- connected, // just established a connection
- active // network running
- };
-
- void InitSockets();
- void TerminateSockets();
-
- void StartProtocol(Protocol protocol)
- pre(protocol < NumProtocols);
-
- void ShutdownProtocol(Protocol protocol)
- pre(protocol < NumProtocols);
-
- void ReportOneProtocol(Protocol protocol, const StringRef& reply) const
- pre(protocol < NumProtocols);
-
- void SetIPAddress(const uint8_t p_ipAddress[], const uint8_t p_netmask[], const uint8_t p_gateway[]);
-
- Platform& platform;
- NetworkResponder *responders;
- NetworkResponder *nextResponderToPoll;
- FtpResponder *ftpResponder;
- TelnetResponder *telnetResponder;
- uint32_t longWait;
- uint32_t lastTickMillis;
-
- Socket sockets[NumTcpSockets];
- size_t nextSocketToPoll; // next TCP socket number to poll for read/write operations
-
- Port portNumbers[NumProtocols]; // port number used for each protocol
- bool protocolEnabled[NumProtocols]; // whether each protocol is enabled
-
- NetworkState state;
- bool activated;
- bool usingDhcp;
-
- uint8_t ipAddress[4];
- uint8_t netmask[4];
- uint8_t gateway[4];
- char hostname[16]; // Limit DHCP hostname to 15 characters + terminating 0
-};
-
-#endif
diff --git a/src/Network2/W5500/Socket.cpp b/src/Network2/W5500/Socket.cpp
deleted file mode 100644
index 8ff7bab8..00000000
--- a/src/Network2/W5500/Socket.cpp
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Socket.cpp
- *
- * Created on: 25 Dec 2016
- * Author: David
- */
-
-#include <Network2/W5500/Network.h>
-#include <Network2/W5500/Socket.h>
-#include <Network2/W5500/Wiznet/Ethernet/socketlib.h>
-#include "NetworkBuffer.h"
-#include "RepRap.h"
-
-//***************************************************************************************************
-// Socket class
-
-const uint32_t FindResponderTimeout = 2000; // how long we wait for a responder to become available
-const unsigned int MaxBuffersPerSocket = 4;
-
-Socket::Socket() : receivedData(nullptr), state(SocketState::disabled)
-{
-}
-
-// Initialise a TCP socket
-void Socket::Init(SocketNumber skt, Port serverPort, Protocol p)
-{
- socketNum = skt;
- localPort = serverPort;
- protocol = p;
- ReInit();
-}
-
-void Socket::TerminateAndDisable()
-{
- Terminate();
- state = SocketState::disabled;
-}
-
-void Socket::ReInit()
-{
- // Discard any received data
- while (receivedData != nullptr)
- {
- receivedData = receivedData->Release();
- }
-
- persistConnection = true;
- isTerminated = false;
- isSending = false;
- state = SocketState::inactive;
-
- // Re-initialise the socket on the W5500
- socket(socketNum, Sn_MR_TCP, localPort, 0x00);
-}
-
-// Close a connection when the last packet has been sent
-void Socket::Close()
-{
- if (state != SocketState::disabled && state != SocketState::inactive)
- {
- ExecCommand(socketNum, Sn_CR_DISCON);
- state = SocketState::closing;
- DiscardReceivedData();
- if (protocol == FtpDataProtocol)
- {
- localPort = 0; // don't re-listen automatically
- }
- }
-}
-
-// Terminate a connection immediately
-void Socket::Terminate()
-{
- if (state != SocketState::disabled)
- {
- disconnectNoWait(socketNum);
- isTerminated = true;
- state = SocketState::inactive;
- DiscardReceivedData();
- }
-}
-
-// Return true if there is or may soon be more data to read
-bool Socket::CanRead() const
-{
- return (state == SocketState::connected)
- || (state == SocketState::clientDisconnecting && receivedData != nullptr && receivedData->TotalRemaining() != 0);
-}
-
-bool Socket::CanSend() const
-{
- return state == SocketState::connected;
-}
-
-// Read 1 character from the receive buffers, returning true if successful
-bool Socket::ReadChar(char& c)
-{
- if (receivedData != nullptr)
- {
- const bool ret = receivedData->ReadChar(c);
- if (receivedData->IsEmpty())
- {
- receivedData = receivedData->Release();
- }
- return ret;
- }
-
- c = 0;
- return false;
-}
-
-// Return a pointer to data in a buffer and a length available
-bool Socket::ReadBuffer(const uint8_t *&buffer, size_t &len)
-{
- if (receivedData != nullptr)
- {
- len = receivedData->Remaining();
- buffer = receivedData->UnreadData();
- return true;
- }
-
- return false;
-}
-
-// Flag some data as taken from the receive buffers. We never take data from more than one buffer at a time.
-void Socket::Taken(size_t len)
-{
- if (receivedData != nullptr)
- {
- receivedData->Taken(len);
- if (receivedData->IsEmpty())
- {
- receivedData = receivedData->Release(); // discard empty buffer at head of chain
- }
- }
-}
-
-// Poll a socket to see if it needs to be serviced
-void Socket::Poll(bool full)
-{
- if (state != SocketState::disabled)
- {
- switch(getSn_SR(socketNum))
- {
- case SOCK_INIT:
- // 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
- {
- ExecCommand(socketNum, Sn_CR_LISTEN);
- state = SocketState::listening;
- }
- break;
-
- case SOCK_LISTEN: // Socket is listening but no client has connected to it yet
- break;
-
- case SOCK_ESTABLISHED: // A client is connected to this socket
- if (getSn_IR(socketNum) & Sn_IR_CON)
- {
- // New connection, so retrieve the sending IP address and port, and clear the interrupt
- getSn_DIPR(socketNum, reinterpret_cast<uint8_t*>(&remoteIPAddress));
- remotePort = getSn_DPORT(socketNum);
- setSn_IR(socketNum, Sn_IR_CON);
- whenConnected = millis();
- }
-
- if (full && state == SocketState::listening) // if it is a new connection
- {
- if (reprap.GetNetwork().FindResponder(this, protocol))
- {
- state = SocketState::connected;
- sendOutstanding = false;
- }
- else
- {
- if (millis() - whenConnected >= FindResponderTimeout)
- {
- Terminate();
- }
- }
- }
-
- if (state == SocketState::connected)
- {
- // See if the socket has received any data
- ReceiveData();
- }
- break;
-
- case SOCK_CLOSE_WAIT: // A client has asked to disconnect
- // Check for further incoming packets before this socket is finally closed.
- // This must be done to ensure that FTP uploads are not cut off.
- ReceiveData();
-
- state = SocketState::clientDisconnecting;
- break;
-
- case SOCK_CLOSED:
- ReInit();
- break;
-
- default:
- break;
- }
- }
-}
-
-// Try to receive more incoming data from the socket
-void Socket::ReceiveData()
-{
- const uint16_t len = getSn_RX_RSR(socketNum);
- if (len != 0)
- {
-// debugPrintf("%u available\n", len);
- NetworkBuffer * const lastBuffer = NetworkBuffer::FindLast(receivedData);
- if (lastBuffer != nullptr && (lastBuffer->SpaceLeft() >= len || (lastBuffer->SpaceLeft() != 0 && NetworkBuffer::Count(receivedData) >= MaxBuffersPerSocket)))
- {
- const size_t lengthToRead = min<size_t>((size_t)len, lastBuffer->SpaceLeft());
- wiz_recv_data(socketNum, lastBuffer->UnwrittenData(), (uint16_t)lengthToRead);
- lastBuffer->dataLength += lengthToRead;
- if (reprap.Debug(moduleNetwork))
- {
- debugPrintf("Received %u bytes\n", (unsigned int)lengthToRead);
- }
- }
- else if (NetworkBuffer::Count(receivedData) < MaxBuffersPerSocket)
- {
- NetworkBuffer * const buf = NetworkBuffer::Allocate();
- if (buf != nullptr)
- {
- wiz_recv_data(socketNum, buf->Data(), len);
- ExecCommand(socketNum, Sn_CR_RECV);
- buf->dataLength = (size_t)len;
- NetworkBuffer::AppendToList(&receivedData, buf);
- if (reprap.Debug(moduleNetwork))
- {
- debugPrintf("Received %u bytes\n", (unsigned int)len);
- }
- }
- }
-// else debugPrintf("no buffer\n");
- }
-}
-
-// Discard any received data for this transaction
-void Socket::DiscardReceivedData()
-{
- while (receivedData != nullptr)
- {
- receivedData = receivedData->Release();
- }
-}
-
-// Send the data, returning the length buffered
-size_t Socket::Send(const uint8_t *data, size_t length)
-{
- if (CanSend() && length != 0 && getSn_SR(socketNum) == SOCK_ESTABLISHED)
- {
- // Check for previous send complete
- 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
- state = SocketState::aborted;
- return 0; // and release buffers etc.
- }
- else
- {
- return 0; // last send is still in progress
- }
- }
-
- if (!sendOutstanding)
- {
- wizTxBufferLeft = getSn_TX_FSR(socketNum); // get free buffer space
- if (wizTxBufferLeft == 0)
- {
- return 0;
- }
- wizTxBufferPtr = getSn_TX_WR(socketNum);
- }
-
- if (length > wizTxBufferLeft)
- {
- length = wizTxBufferLeft;
- }
- wiz_send_data_at(socketNum, data, length, wizTxBufferPtr);
- wizTxBufferLeft -= length;
- wizTxBufferPtr += length;
- sendOutstanding = true;
- if (wizTxBufferLeft == 0)
- {
- Send();
- }
- return length;
- }
- return 0;
-}
-
-// Tell the interface to send the outstanding data
-void Socket::Send()
-{
- if (CanSend() && sendOutstanding)
- {
- setSn_TX_WR(socketNum, wizTxBufferPtr);
- ExecCommand(socketNum, Sn_CR_SEND);
- isSending = true;
- sendOutstanding = false;
- }
-}
-
-// End
diff --git a/src/Network2/W5500/Socket.h b/src/Network2/W5500/Socket.h
deleted file mode 100644
index 6d211e5e..00000000
--- a/src/Network2/W5500/Socket.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Socket.h
- *
- * Created on: 25 Dec 2016
- * Author: David
- */
-
-#ifndef SRC_DUETNG_DUETETHERNET_SOCKET_H_
-#define SRC_DUETNG_DUETETHERNET_SOCKET_H_
-
-#include "RepRapFirmware.h"
-#include "NetworkDefs.h"
-
-// Socket structure that we use to track TCP connections
-class Socket
-{
-public:
- Socket();
- void Init(SocketNumber s, Port serverPort, Protocol p);
- void TerminateAndDisable();
- void Poll(bool full);
- Port GetLocalPort() const { return localPort; }
- uint32_t GetRemoteIP() const { return remoteIPAddress; }
- Port GetRemotePort() const { return remotePort; }
- void Close();
- void Terminate();
- bool ReadChar(char& c);
- bool ReadBuffer(const uint8_t *&buffer, size_t &len);
- void Taken(size_t len);
- bool CanRead() const;
- bool CanSend() const;
- size_t Send(const uint8_t *data, size_t length);
- void Send();
-
-private:
- enum class SocketState : uint8_t
- {
- disabled,
- inactive,
- listening,
- connected,
- clientDisconnecting,
- closing,
- aborted
- };
-
- void ReInit();
- void ReceiveData();
- void DiscardReceivedData();
-
- Port localPort, remotePort; // The local and remote ports
- Protocol protocol; // What protocol this socket is for
- uint32_t remoteIPAddress; // The remote IP address
- NetworkBuffer *receivedData; // List of buffers holding received data
- //invariant(!receivedData->IsEmpty())
- uint32_t whenConnected;
- 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 sendOutstanding; // True if we have written data to the socket but not flushed it
- bool isSending; // True if we have written data to the W5500 to send and have not yet seen success or timeout
- uint16_t wizTxBufferPtr; // Current offset into the Wizchip send buffer, if sendOutstanding is true
- uint16_t wizTxBufferLeft; // Transmit buffer space left, if sendOutstanding is true
-};
-
-#endif /* SRC_DUETNG_DUETETHERNET_SOCKET_H_ */
diff --git a/src/Network2/W5500/Wiznet/.gitattributes b/src/Network2/W5500/Wiznet/.gitattributes
deleted file mode 100644
index 412eeda7..00000000
--- a/src/Network2/W5500/Wiznet/.gitattributes
+++ /dev/null
@@ -1,22 +0,0 @@
-# Auto detect text files and perform LF normalization
-* text=auto
-
-# Custom for Visual Studio
-*.cs diff=csharp
-*.sln merge=union
-*.csproj merge=union
-*.vbproj merge=union
-*.fsproj merge=union
-*.dbproj merge=union
-
-# Standard to msysgit
-*.doc diff=astextplain
-*.DOC diff=astextplain
-*.docx diff=astextplain
-*.DOCX diff=astextplain
-*.dot diff=astextplain
-*.DOT diff=astextplain
-*.pdf diff=astextplain
-*.PDF diff=astextplain
-*.rtf diff=astextplain
-*.RTF diff=astextplain
diff --git a/src/Network2/W5500/Wiznet/.gitignore b/src/Network2/W5500/Wiznet/.gitignore
deleted file mode 100644
index 58bcbf82..00000000
--- a/src/Network2/W5500/Wiznet/.gitignore
+++ /dev/null
@@ -1,43 +0,0 @@
-# Windows image file caches
-Thumbs.db
-ehthumbs.db
-
-# Folder config file
-Desktop.ini
-
-# Recycle Bin used on file shares
-$RECYCLE.BIN/
-
-# Windows Installer files
-*.cab
-*.msi
-*.msm
-*.msp
-
-# =========================
-# Operating System Files
-# =========================
-
-# OSX
-# =========================
-
-.DS_Store
-.AppleDouble
-.LSOverride
-
-# Icon must end with two \r
-Icon
-
-# Thumbnails
-._*
-
-# Files that might appear on external disk
-.Spotlight-V100
-.Trashes
-
-# Directories potentially created on remote AFP share
-.AppleDB
-.AppleDesktop
-Network Trash Folder
-Temporary Items
-.apdisk
diff --git a/src/Network2/W5500/Wiznet/Ethernet/Socket_APIs_V3.0.3.chm b/src/Network2/W5500/Wiznet/Ethernet/Socket_APIs_V3.0.3.chm
deleted file mode 100644
index 35ed5128..00000000
--- a/src/Network2/W5500/Wiznet/Ethernet/Socket_APIs_V3.0.3.chm
+++ /dev/null
Binary files differ
diff --git a/src/Network2/W5500/Wiznet/Ethernet/W5500/w5500.cpp b/src/Network2/W5500/Wiznet/Ethernet/W5500/w5500.cpp
deleted file mode 100644
index 4467605c..00000000
--- a/src/Network2/W5500/Wiznet/Ethernet/W5500/w5500.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-//*****************************************************************************
-//
-//! \file w5500.cpp
-//! \brief W5500 HAL Interface.
-//! \version 1.0.2
-//! \date 2013/10/21
-//! \par Revision history
-//! <2015/02/05> Notice
-//! The version history is not updated after this point.
-//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
-//! >> https://github.com/Wiznet/ioLibrary_Driver
-//! <2014/05/01> V1.0.2
-//! 1. Implicit type casting -> Explicit type casting. Refer to M20140501
-//! Fixed the problem on porting into under 32bit MCU
-//! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh
-//! Thank for your interesting and serious advices.
-//! <2013/12/20> V1.0.1
-//! 1. Remove warning
-//! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case _WIZCHIP_IO_MODE_SPI_FDM_
-//! for loop optimized(removed). refer to M20131220
-//! <2013/10/21> 1st Release
-//! \author MidnightCow
-//! \copyright
-//!
-//! Copyright (c) 2013, WIZnet Co., LTD.
-//! All rights reserved.
-//!
-//! Redistribution and use in source and binary forms, with or without
-//! modification, are permitted provided that the following conditions
-//! are met:
-//!
-//! * Redistributions of source code must retain the above copyright
-//! notice, this list of conditions and the following disclaimer.
-//! * Redistributions in binary form must reproduce the above copyright
-//! notice, this list of conditions and the following disclaimer in the
-//! documentation and/or other materials provided with the distribution.
-//! * Neither the name of the <ORGANIZATION> nor the names of its
-//! contributors may be used to endorse or promote products derived
-//! from this software without specific prior written permission.
-//!
-//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-//! THE POSSIBILITY OF SUCH DAMAGE.
-//
-//*****************************************************************************
-
-#include <Network2/W5500/Wiznet/Ethernet/W5500/w5500.h>
-#include <Network2/W5500/Wiznet/Ethernet/WizSpi.h>
-
-#define _W5500_SPI_VDM_OP_ 0x00
-#define _W5500_SPI_FDM_OP_LEN1_ 0x01
-#define _W5500_SPI_FDM_OP_LEN2_ 0x02
-#define _W5500_SPI_FDM_OP_LEN4_ 0x03
-
-////////////////////////////////////////////////////
-
-uint8_t WIZCHIP_READ(uint32_t AddrSel)
-{
- WizSpi::AssertSS();
- WizSpi::SendAddress(AddrSel | (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_));
- const uint8_t ret = WizSpi::ReadByte();
- WizSpi::ReleaseSS();
- return ret;
-}
-
-void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb )
-{
- WizSpi::AssertSS();
- WizSpi::SendAddress(AddrSel | (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_));
- WizSpi::WriteByte(wb);
- WizSpi::ReleaseSS();
-}
-
-void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
-{
- WizSpi::AssertSS();
- WizSpi::SendAddress(AddrSel | (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_));
- WizSpi::ReadBurst(pBuf, len);
- WizSpi::ReleaseSS();
-}
-
-void WIZCHIP_WRITE_BUF(uint32_t AddrSel, const uint8_t* pBuf, uint16_t len)
-{
- WizSpi::AssertSS();
- WizSpi::SendAddress(AddrSel | (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_));
- WizSpi::SendBurst(pBuf, len);
- WizSpi::ReleaseSS();
-}
-
-
-uint16_t getSn_TX_FSR(uint8_t sn)
-{
- uint16_t val = 0, val1 = 0;
- do
- {
- val1 = WIZCHIP_READ(Sn_TX_FSR(sn));
- val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
- if (val1 != 0)
- {
- val = WIZCHIP_READ(Sn_TX_FSR(sn));
- val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
- }
- } while (val != val1);
- return val;
-}
-
-uint16_t getSn_RX_RSR(uint8_t sn)
-{
- uint16_t val = 0, val1 = 0;
- do
- {
- val1 = WIZCHIP_READ(Sn_RX_RSR(sn));
- val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
- if (val1 != 0)
- {
- val = WIZCHIP_READ(Sn_RX_RSR(sn));
- val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
- }
- } while (val != val1);
- return val;
-}
-
-void wiz_send_data(uint8_t sn, const uint8_t *wizdata, uint16_t len)
-{
- if (len != 0)
- {
- uint16_t ptr = getSn_TX_WR(sn);
- 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);
- }
-}
-
-void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
-{
- if (len != 0)
- {
- uint16_t ptr = getSn_RX_RD(sn);
- const uint32_t addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3);
- WIZCHIP_READ_BUF(addrsel, wizdata, len);
- ptr += len;
-
- setSn_RX_RD(sn,ptr);
- }
-}
-
-
-void wiz_recv_ignore(uint8_t sn, uint16_t len)
-{
- uint16_t ptr = getSn_RX_RD(sn);
- ptr += len;
- setSn_RX_RD(sn,ptr);
-}
-
-// End
diff --git a/src/Network2/W5500/Wiznet/Ethernet/W5500/w5500.h b/src/Network2/W5500/Wiznet/Ethernet/W5500/w5500.h
deleted file mode 100644
index 723bd7bf..00000000
--- a/src/Network2/W5500/Wiznet/Ethernet/W5500/w5500.h
+++ /dev/null
@@ -1,2299 +0,0 @@
-//*****************************************************************************
-//
-//! \file w5500.h
-//! \brief W5500 HAL Header File.
-//! \version 1.0.0
-//! \date 2013/10/21
-//! \par Revision history
-//! <2015/02/05> Notice
-//! The version history is not updated after this point.
-//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
-//! >> https://github.com/Wiznet/ioLibrary_Driver
-//! <2013/10/21> 1st Release
-//! \author MidnightCow
-//! \copyright
-//!
-//! Copyright (c) 2013, WIZnet Co., LTD.
-//! All rights reserved.
-//!
-//! Redistribution and use in source and binary forms, with or without
-//! modification, are permitted provided that the following conditions
-//! are met:
-//!
-//! * Redistributions of source code must retain the above copyright
-//! notice, this list of conditions and the following disclaimer.
-//! * Redistributions in binary form must reproduce the above copyright
-//! notice, this list of conditions and the following disclaimer in the
-//! documentation and/or other materials provided with the distribution.
-//! * Neither the name of the <ORGANIZATION> nor the names of its
-//! contributors may be used to endorse or promote products derived
-//! from this software without specific prior written permission.
-//!
-//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-//! THE POSSIBILITY OF SUCH DAMAGE.
-//
-//*****************************************************************************
-
-//
-
-#ifndef _W5500_H_
-#define _W5500_H_
-
-#include <Network2/W5500/Wiznet/Ethernet/wizchip_conf.h>
-#include <cstdint>
-#include <cstddef>
-#include "spi/spi.h"
-
-// The following functions are defined in Network.cpp and used by this module
-extern void SpiAssertSS();
-extern void SpiReleaseSS();
-extern void SpiSendAddress(uint32_t);
-extern uint8_t SpiReadByte();
-extern void SpiSendByte(uint8_t b);
-extern spi_status_t SpiReadBurst(uint8_t* pBuf, size_t len);
-extern spi_status_t SpiSendBurst(const uint8_t* pBuf, size_t len);
-
-
-#define _W5500_IO_BASE_ 0x00000000
-
-#define _W5500_SPI_READ_ (0x00 << 2) //< SPI interface Read operation in Control Phase
-#define _W5500_SPI_WRITE_ (0x01 << 2) //< SPI interface Write operation in Control Phase
-
-#define WIZCHIP_CREG_BLOCK 0x00 //< Common register block
-#define WIZCHIP_SREG_BLOCK(N) (1+4*N) //< Socket N register block
-#define WIZCHIP_TXBUF_BLOCK(N) (2+4*N) //< Socket N Tx buffer address block
-#define WIZCHIP_RXBUF_BLOCK(N) (3+4*N) //< Socket N Rx buffer address block
-
-#define WIZCHIP_OFFSET_INC(ADDR, N) (ADDR + (N<<8)) //< Increase offset address
-
-
-///////////////////////////////////////
-// Definition For Legacy Chip Driver //
-///////////////////////////////////////
-#define IINCHIP_READ(ADDR) WIZCHIP_READ(ADDR) ///< The defined for legacy chip driver
-#define IINCHIP_WRITE(ADDR,VAL) WIZCHIP_WRITE(ADDR,VAL) ///< The defined for legacy chip driver
-#define IINCHIP_READ_BUF(ADDR,BUF,LEN) WIZCHIP_READ_BUF(ADDR,BUF,LEN) ///< The defined for legacy chip driver
-#define IINCHIP_WRITE_BUF(ADDR,BUF,LEN) WIZCHIP_WRITE(ADDR,BUF,LEN) ///< The defined for legacy chip driver
-
-//////////////////////////////
-//-------------------------- defgroup ---------------------------------
-/**
- * @defgroup W5500 W5500
- *
- * @brief WHIZCHIP register defines and I/O functions of @b W5500.
- *
- * - @ref WIZCHIP_register : @ref Common_register_group and @ref Socket_register_group
- * - @ref WIZCHIP_IO_Functions : @ref Basic_IO_function, @ref Common_register_access_function and @ref Socket_register_access_function
- */
-
-
-/**
- * @defgroup WIZCHIP_register WIZCHIP register
- * @ingroup W5500
- *
- * @brief WHIZCHIP register defines register group of @b W5500.
- *
- * - @ref Common_register_group : Common register group
- * - @ref Socket_register_group : \c SOCKET n register group
- */
-
-
-/**
- * @defgroup WIZCHIP_IO_Functions WIZCHIP I/O functions
- * @ingroup W5500
- *
- * @brief This supports the basic I/O functions for @ref WIZCHIP_register.
- *
- * - <b> Basic I/O function </b> \n
- * WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() \n\n
- *
- * - @ref Common_register_group <b>access functions</b> \n
- * -# @b Mode \n
- * getMR(), setMR()
- * -# @b Interrupt \n
- * getIR(), setIR(), getIMR(), setIMR(), getSIR(), setSIR(), getSIMR(), setSIMR(), getINTLEVEL(), setINTLEVEL()
- * -# <b> Network Information </b> \n
- * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), setSIPR()
- * -# @b Retransmission \n
- * getRCR(), setRCR(), getRTR(), setRTR()
- * -# @b PPPoE \n
- * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC(), getPSID(), setPSID(), getPHAR(), setPHAR(), getPMRU(), setPMRU()
- * -# <b> ICMP packet </b>\n
- * getUIPR(), getUPORTR()
- * -# @b etc. \n
- * getPHYCFGR(), setPHYCFGR(), getVERSIONR() \n\n
- *
- * - \ref Socket_register_group <b>access functions</b> \n
- * -# <b> SOCKET control</b> \n
- * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IMR(), setSn_IMR(), getSn_IR(), setSn_IR()
- * -# <b> SOCKET information</b> \n
- * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT()
- * getSn_MSSR(), setSn_MSSR()
- * -# <b> SOCKET communication </b> \n
- * getSn_RXBUF_SIZE(), setSn_RXBUF_SIZE(), getSn_TXBUF_SIZE(), setSn_TXBUF_SIZE() \n
- * getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n
- * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n
- * getSn_TX_FSR(), getSn_RX_RSR(), getSn_KPALVTR(), setSn_KPALVTR()
- * -# <b> IP header field </b> \n
- * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n
- * getSn_TTL(), setSn_TTL()
- */
-
-
-
-/**
- * @defgroup Common_register_group Common register
- * @ingroup WIZCHIP_register
- *
- * @brief Common register group\n
- * It set the basic for the networking\n
- * It set the configuration such as interrupt, network information, ICMP, etc.
- * @details
- * @sa MR : Mode register.
- * @sa GAR, SUBR, SHAR, SIPR
- * @sa INTLEVEL, IR, IMR, SIR, SIMR : Interrupt.
- * @sa _RTR_, _RCR_ : Data retransmission.
- * @sa PTIMER, PMAGIC, PHAR, PSID, PMRU : PPPoE.
- * @sa UIPR, UPORTR : ICMP message.
- * @sa PHYCFGR, VERSIONR : etc.
- */
-
-
-
-/**
- * @defgroup Socket_register_group Socket register
- * @ingroup WIZCHIP_register
- *
- * @brief Socket register group.\n
- * Socket register configures and control SOCKETn which is necessary to data communication.
- * @details
- * @sa Sn_MR, Sn_CR, Sn_IR, Sn_IMR : SOCKETn Control
- * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information
- * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_KPALVTR, Sn_FRAG : Internet protocol.
- * @sa Sn_RXBUF_SIZE, Sn_TXBUF_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, Sn_RX_RD, Sn_RX_WR : Data communication
- */
-
-
-
- /**
- * @defgroup Basic_IO_function Basic I/O function
- * @ingroup WIZCHIP_IO_Functions
- * @brief These are basic input/output functions to read values from register or write values to register.
- */
-
-/**
- * @defgroup Common_register_access_function Common register access functions
- * @ingroup WIZCHIP_IO_Functions
- * @brief These are functions to access <b>common registers</b>.
- */
-
-/**
- * @defgroup Socket_register_access_function Socket register access functions
- * @ingroup WIZCHIP_IO_Functions
- * @brief These are functions to access <b>socket registers</b>.
- */
-
-//------------------------------- defgroup end --------------------------------------------
-//----------------------------- W5500 Common Registers IOMAP -----------------------------
-/**
- * @ingroup Common_register_group
- * @brief Mode Register address(R/W)\n
- * @ref MR is used for S/W reset, ping block mode, PPPoE mode and etc.
- * @details Each bit of @ref MR defined as follows.
- * <table>
- * <tr> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr>
- * <tr> <td>RST</td> <td>Reserved</td> <td>WOL</td> <td>PB</td> <td>PPPoE</td> <td>Reserved</td> <td>FARP</td> <td>Reserved</td> </tr>
- * </table>
- * - \ref MR_RST : Reset
- * - \ref MR_WOL : Wake on LAN
- * - \ref MR_PB : Ping block
- * - \ref MR_PPPOE : PPPoE mode
- * - \ref MR_FARP : Force ARP mode
- */
-const uint32_t MR = _W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-/**
- * @ingroup Common_register_group
- * @brief Gateway IP Register address(R/W)
- * @details @ref GAR configures the default gateway address.
- */
- const uint32_t GAR = _W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-/**
- * @ingroup Common_register_group
- * @brief Subnet mask Register address(R/W)
- * @details @ref SUBR configures the subnet mask address.
- */
- const uint32_t SUBR = _W5500_IO_BASE_ + (0x0005 << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-/**
- * @ingroup Common_register_group
- * @brief Source MAC Register address(R/W)
- * @details @ref SHAR configures the source hardware address.
- */
- const uint32_t SHAR = _W5500_IO_BASE_ + (0x0009 << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-/**
- * @ingroup Common_register_group
- * @brief Source IP Register address(R/W)
- * @details @ref SIPR configures the source IP address.
- */
- const uint32_t SIPR = _W5500_IO_BASE_ + (0x000F << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-/**
- * @ingroup Common_register_group
- * @brief Set Interrupt low level timer register address(R/W)
- * @details @ref INTLEVEL configures the Interrupt Assert Time.
- */
- const uint32_t INTLEVEL = _W5500_IO_BASE_ + (0x0013 << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-/**
- * @ingroup Common_register_group
- * @brief Interrupt Register(R/W)
- * @details @ref IR indicates the interrupt status. Each bit of @ref IR will be still until the bit will be written to by the host.
- * If @ref IR is not equal to x00 INTn PIN is asserted to low until it is x00\n\n
- * Each bit of @ref IR defined as follows.
- * <table>
- * <tr> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr>
- * <tr> <td>CONFLICT</td> <td>UNREACH</td> <td>PPPoE</td> <td>MP</td> <td>Reserved</td> <td>Reserved</td> <td>Reserved</td> <td>Reserved</td> </tr>
- * </table>
- * - \ref IR_CONFLICT : IP conflict
- * - \ref IR_UNREACH : Destination unreachable
- * - \ref IR_PPPoE : PPPoE connection close
- * - \ref IR_MP : Magic packet
- */
- const uint32_t IR = _W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-/**
- * @ingroup Common_register_group
- * @brief Interrupt mask register(R/W)
- * @details @ref _IMR_ is used to mask interrupts. Each bit of @ref _IMR_ corresponds to each bit of @ref IR.
- * When a bit of @ref _IMR_ is and the corresponding bit of @ref IR is an interrupt will be issued. In other words,
- * if a bit of @ref _IMR_ is an interrupt will not be issued even if the corresponding bit of @ref IR is \n\n
- * Each bit of @ref _IMR_ defined as the following.
- * <table>
- * <tr> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr>
- * <tr> <td>IM_IR7</td> <td>IM_IR6</td> <td>IM_IR5</td> <td>IM_IR4</td> <td>Reserved</td> <td>Reserved</td> <td>Reserved</td> <td>Reserved</td> </tr>
- * </table>
- * - \ref IM_IR7 : IP Conflict Interrupt Mask
- * - \ref IM_IR6 : Destination unreachable Interrupt Mask
- * - \ref IM_IR5 : PPPoE Close Interrupt Mask
- * - \ref IM_IR4 : Magic Packet Interrupt Mask
- */
- const uint32_t _IMR_ = _W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-/**
- * @ingroup Common_register_group
- * @brief Socket Interrupt Register(R/W)
- * @details @ref SIR indicates the interrupt status of Socket.\n
- * Each bit of @ref SIR be still until @ref Sn_IR is cleared by the host.\n
- * If @ref Sn_IR is not equal to x00 the n-th bit of @ref SIR is and INTn PIN is asserted until @ref SIR is x00 */
- const uint32_t SIR = _W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-/**
- * @ingroup Common_register_group
- * @brief Socket Interrupt Mask Register(R/W)
- * @details Each bit of @ref SIMR corresponds to each bit of @ref SIR.
- * When a bit of @ref SIMR is and the corresponding bit of @ref SIR is Interrupt will be issued.
- * In other words, if a bit of @ref SIMR is an interrupt will be not issued even if the corresponding bit of @ref SIR is
- */
- const uint32_t SIMR = _W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-/**
- * @ingroup Common_register_group
- * @brief Timeout register address( 1 is 100us )(R/W)
- * @details @ref _RTR_ configures the retransmission timeout period. The unit of timeout period is 100us and the default of @ref _RTR_ is x07D0.
- * And so the default timeout period is 200ms(100us X 2000). During the time configured by @ref _RTR_, W5500 waits for the peer response
- * to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command).
- * If the peer does not respond within the @ref _RTR_ time, W5500 retransmits the packet or issues timeout.
- */
- const uint32_t _RTR_ = _W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-/**
- * @ingroup Common_register_group
- * @brief Retry count register(R/W)
- * @details @ref _RCR_ configures the number of time of retransmission.
- * When retransmission occurs as many as ref _RCR_+1 Timeout interrupt is issued (@ref Sn_IR_TIMEOUT = '1').
- */
- const uint32_t _RCR_ = _W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-/**
- * @ingroup Common_register_group
- * @brief PPP LCP Request Timer register in PPPoE mode(R/W)
- * @details @ref PTIMER configures the time for sending LCP echo request. The unit of time is 25ms.
- */
- const uint32_t PTIMER = _W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-/**
- * @ingroup Common_register_group
- * @brief PPP LCP Magic number register in PPPoE mode(R/W)
- * @details @ref PMAGIC configures the 4bytes magic number to be used in LCP negotiation.
- */
- const uint32_t PMAGIC = _W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-/**
- * @ingroup Common_register_group
- * @brief PPP Destination MAC Register address(R/W)
- * @details @ref PHAR configures the PPPoE server hardware address that is acquired during PPPoE connection process.
- */
- const uint32_t PHAR = _W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-/**
- * @ingroup Common_register_group
- * @brief PPP Session Identification Register(R/W)
- * @details @ref PSID configures the PPPoE sever session ID acquired during PPPoE connection process.
- */
- const uint32_t PSID = _W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-/**
- * @ingroup Common_register_group
- * @brief PPP Maximum Segment Size(MSS) register(R/W)
- * @details @ref PMRU configures the maximum receive unit of PPPoE.
- */
- const uint32_t PMRU = _W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-/**
- * @ingroup Common_register_group
- * @brief Unreachable IP register address in UDP mode(R)
- * @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number
- * which socket is not open and @ref IR_UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates
- * the destination IP address & port number respectively.
- */
- const uint32_t UIPR = _W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-/**
- * @ingroup Common_register_group
- * @brief Unreachable Port register address in UDP mode(R)
- * @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number
- * which socket is not open and @ref IR_UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR
- * indicates the destination IP address & port number respectively.
- */
- const uint32_t UPORTR = _W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-/**
- * @ingroup Common_register_group
- * @brief PHY Status Register(R/W)
- * @details @ref PHYCFGR configures PHY operation mode and resets PHY. In addition, @ref PHYCFGR indicates the status of PHY such as duplex, Speed, Link.
- */
- const uint32_t PHYCFGR = _W5500_IO_BASE_ + (0x002E << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-// Reserved (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_CREG_BLOCK << 3))
-// Reserved (_W5500_IO_BASE_ + (0x0030 << 8) + (WIZCHIP_CREG_BLOCK << 3))
-// Reserved (_W5500_IO_BASE_ + (0x0031 << 8) + (WIZCHIP_CREG_BLOCK << 3))
-// Reserved (_W5500_IO_BASE_ + (0x0032 << 8) + (WIZCHIP_CREG_BLOCK << 3))
-// Reserved (_W5500_IO_BASE_ + (0x0033 << 8) + (WIZCHIP_CREG_BLOCK << 3))
-// Reserved (_W5500_IO_BASE_ + (0x0034 << 8) + (WIZCHIP_CREG_BLOCK << 3))
-// Reserved (_W5500_IO_BASE_ + (0x0035 << 8) + (WIZCHIP_CREG_BLOCK << 3))
-// Reserved (_W5500_IO_BASE_ + (0x0036 << 8) + (WIZCHIP_CREG_BLOCK << 3))
-// Reserved (_W5500_IO_BASE_ + (0x0037 << 8) + (WIZCHIP_CREG_BLOCK << 3))
-// Reserved (_W5500_IO_BASE_ + (0x0038 << 8) + (WIZCHIP_CREG_BLOCK << 3))
-
-/**
- * @ingroup Common_register_group
- * @brief chip version register address(R)
- * @details @ref VERSIONR always indicates the W5500 version as @b 0x04.
- */
- const uint32_t VERSIONR = _W5500_IO_BASE_ + (0x0039 << 8) + (WIZCHIP_CREG_BLOCK << 3);
-
-
-//----------------------------- W5500 Socket Registers IOMAP -----------------------------
-/**
- * @ingroup Socket_register_group
- * @brief socket Mode register(R/W)
- * @details @ref Sn_MR configures the option or protocol type of Socket n.\n\n
- * Each bit of @ref Sn_MR defined as the following.
- * <table>
- * <tr> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr>
- * <tr> <td>MULTI/MFEN</td> <td>BCASTB</td> <td>ND/MC/MMB</td> <td>UCASTB/MIP6B</td> <td>Protocol[3]</td> <td>Protocol[2]</td> <td>Protocol[1]</td> <td>Protocol[0]</td> </tr>
- * </table>
- * - @ref Sn_MR_MULTI : Support UDP Multicasting
- * - @ref Sn_MR_BCASTB : Broadcast block <b>in UDP Multicasting</b>
- * - @ref Sn_MR_ND : No Delayed Ack(TCP) flag
- * - @ref Sn_MR_MC : IGMP version used <b>in UDP mulitcasting</b>
- * - @ref Sn_MR_MMB : Multicast Blocking <b>in @ref Sn_MR_MACRAW mode</b>
- * - @ref Sn_MR_UCASTB : Unicast Block <b>in UDP Multicating</b>
- * - @ref Sn_MR_MIP6B : IPv6 packet Blocking <b>in @ref Sn_MR_MACRAW mode</b>
- * - <b>Protocol</b>
- * <table>
- * <tr> <td><b>Protocol[3]</b></td> <td><b>Protocol[2]</b></td> <td><b>Protocol[1]</b></td> <td><b>Protocol[0]</b></td> <td>@b Meaning</td> </tr>
- * <tr> <td>0</td> <td>0</td> <td>0</td> <td>0</td> <td>Closed</td> </tr>
- * <tr> <td>0</td> <td>0</td> <td>0</td> <td>1</td> <td>TCP</td> </tr>
- * <tr> <td>0</td> <td>0</td> <td>1</td> <td>0</td> <td>UDP</td> </tr>
- * <tr> <td>0</td> <td>1</td> <td>0</td> <td>0</td> <td>MACRAW</td> </tr>
- * </table>
- * - @ref Sn_MR_MACRAW : MAC LAYER RAW SOCK \n
- * - @ref Sn_MR_UDP : UDP
- * - @ref Sn_MR_TCP : TCP
- * - @ref Sn_MR_CLOSE : Unused socket
- * @note MACRAW mode should be only used in Socket 0.
- */
- static inline uint32_t Sn_MR(uint8_t N)
- {
- return _W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
- }
-
-/**
- * @ingroup Socket_register_group
- * @brief Socket command register(R/W)
- * @details This is used to set the command for Socket n such as OPEN, CLOSE, CONNECT, LISTEN, SEND, and RECEIVE.\n
- * After W5500 accepts the command, the @ref Sn_CR register is automatically cleared to 0x00.
- * Even though @ref Sn_CR is cleared to 0x00, the command is still being processed.\n
- * To check whether the command is completed or not, please check the @ref Sn_IR or @ref Sn_SR.
- * - @ref Sn_CR_OPEN : Initialize or open socket.
- * - @ref Sn_CR_LISTEN : Wait connection request in TCP mode(<b>Server mode</b>)
- * - @ref Sn_CR_CONNECT : Send connection request in TCP mode(<b>Client mode</b>)
- * - @ref Sn_CR_DISCON : Send closing request in TCP mode.
- * - @ref Sn_CR_CLOSE : Close socket.
- * - @ref Sn_CR_SEND : Update TX buffer pointer and send data.
- * - @ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP process.
- * - @ref Sn_CR_SEND_KEEP : Send keep alive message.
- * - @ref Sn_CR_RECV : Update RX buffer pointer and receive data.
- */
- static inline uint32_t Sn_CR(uint8_t N)
- {
- return _W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
- }
-
-/**
- * @ingroup Socket_register_group
- * @brief Socket interrupt register(R)
- * @details @ref Sn_IR indicates the status of Socket Interrupt such as establishment, termination, receiving data, timeout).\n
- * When an interrupt occurs and the corresponding bit of @ref Sn_IMR is the corresponding bit of @ref Sn_IR becomes \n
- * In order to clear the @ref Sn_IR bit, the host should write the bit to \n
- * <table>
- * <tr> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr>
- * <tr> <td>Reserved</td> <td>Reserved</td> <td>Reserved</td> <td>SEND_OK</td> <td>TIMEOUT</td> <td>RECV</td> <td>DISCON</td> <td>CON</td> </tr>
- * </table>
- * - \ref Sn_IR_SENDOK : <b>SEND_OK Interrupt</b>
- * - \ref Sn_IR_TIMEOUT : <b>TIMEOUT Interrupt</b>
- * - \ref Sn_IR_RECV : <b>RECV Interrupt</b>
- * - \ref Sn_IR_DISCON : <b>DISCON Interrupt</b>
- * - \ref Sn_IR_CON : <b>CON Interrupt</b>
- */
- static inline uint32_t Sn_IR(uint8_t N)
- {
- return _W5500_IO_BASE_ + (0x0002 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
- }
-
-/**
- * @ingroup Socket_register_group
- * @brief Socket status register(R)
- * @details @ref Sn_SR indicates the status of Socket n.\n
- * The status of Socket n is changed by @ref Sn_CR or some special control packet as SYN, FIN packet in TCP.
- * @par Normal status
- * - @ref SOCK_CLOSED : Closed
- * - @ref SOCK_INIT : Initiate state
- * - @ref SOCK_LISTEN : Listen state
- * - @ref SOCK_ESTABLISHED : Success to connect
- * - @ref SOCK_CLOSE_WAIT : Closing state
- * - @ref SOCK_UDP : UDP socket
- * - @ref SOCK_MACRAW : MAC raw mode socket
- *@par Temporary status during changing the status of Socket n.
- * - @ref SOCK_SYNSENT : This indicates Socket n sent the connect-request packet (SYN packet) to a peer.
- * - @ref SOCK_SYNRECV : It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.
- * - @ref SOCK_FIN_WAIT : Connection state
- * - @ref SOCK_CLOSING : Closing state
- * - @ref SOCK_TIME_WAIT : Closing state
- * - @ref SOCK_LAST_ACK : Closing state
- */
- static inline uint32_t Sn_SR(uint8_t N)
- {
- return _W5500_IO_BASE_ + (0x0003 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
- }
-
-/**
- * @ingroup Socket_register_group
- * @brief source port register(R/W)
- * @details @ref Sn_PORT configures the source port number of Socket n.
- * It is valid when Socket n is used in TCP/UDP mode. It should be set before OPEN command is ordered.
- */
- static inline uint32_t Sn_PORT(uint8_t N)
- {
- return _W5500_IO_BASE_ + (0x0004 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
- }
-
-/**
- * @ingroup Socket_register_group
- * @brief Peer MAC register address(R/W)
- * @details @ref Sn_DHAR configures the destination hardware address of Socket n when using SEND_MAC command in UDP mode or
- * it indicates that it is acquired in ARP-process by CONNECT/SEND command.
- */
- static inline uint32_t Sn_DHAR(uint8_t N)
- {
- return _W5500_IO_BASE_ + (0x0006 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
- }
-
-/**
- * @ingroup Socket_register_group
- * @brief Peer IP register address(R/W)
- * @details @ref Sn_DIPR configures or indicates the destination IP address of Socket n. It is valid when Socket n is used in TCP/UDP mode.
- * In TCP client mode, it configures an IP address of TCP serverbefore CONNECT command.
- * In TCP server mode, it indicates an IP address of TCP clientafter successfully establishing connection.
- * In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command.
- */
- static inline uint32_t Sn_DIPR(uint8_t N)
- {
- return _W5500_IO_BASE_ + (0x000C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
- }
-
-/**
- * @ingroup Socket_register_group
- * @brief Peer port register address(R/W)
- * @details @ref Sn_DPORT configures or indicates the destination port number of Socket n. It is valid when Socket n is used in TCP/UDP mode.
- * In TCP clientmode, it configures the listen port number of TCP serverbefore CONNECT command.
- * In TCP Servermode, it indicates the port number of TCP client after successfully establishing connection.
- * In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command.
- */
- static inline uint32_t Sn_DPORT(uint8_t N)
- {
- return _W5500_IO_BASE_ + (0x0010 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
- }
-
-/**
- * @ingroup Socket_register_group
- * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W)
- * @details @ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) of Socket n.
- */
- static inline uint32_t Sn_MSSR(uint8_t N)
- {
- return _W5500_IO_BASE_ + (0x0012 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
- }
-
-// Reserved (_W5500_IO_BASE_ + (0x0014 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
-
-/**
- * @ingroup Socket_register_group
- * @brief IP Type of Service(TOS) Register(R/W)
- * @details @ref Sn_TOS configures the TOS(Type Of Service field in IP Header) of Socket n.
- * It is set before OPEN command.
- */
-static inline uint32_t Sn_TOS(uint8_t N)
-{
- return _W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
-}
-
-/**
- * @ingroup Socket_register_group
- * @brief IP Time to live(TTL) Register(R/W)
- * @details @ref Sn_TTL configures the TTL(Time To Live field in IP header) of Socket n.
- * It is set before OPEN command.
- */
-static inline uint32_t Sn_TTL(uint8_t N)
-{
- return _W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
-}
-
-// Reserved (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
-// Reserved (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
-// Reserved (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
-// Reserved (_W5500_IO_BASE_ + (0x001A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
-// Reserved (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
-// Reserved (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
-// Reserved (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
-
-/**
- * @ingroup Socket_register_group
- * @brief Receive memory size register(R/W)
- * @details @ref Sn_RXBUF_SIZE configures the RX buffer block size of Socket n.
- * Socket n RX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes.
- * If a different size is configured, the data cannot be normally received from a peer.
- * Although Socket n RX Buffer Block size is initially configured to 2Kbytes,
- * user can re-configure its size using @ref Sn_RXBUF_SIZE. The total sum of @ref Sn_RXBUF_SIZE can not be exceed 16Kbytes.
- * When exceeded, the data reception error is occurred.
- */
-static inline uint32_t Sn_RXBUF_SIZE(uint8_t N)
-{
- return _W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
-}
-
-/**
- * @ingroup Socket_register_group
- * @brief Transmit memory size register(R/W)
- * @details @ref Sn_TXBUF_SIZE configures the TX buffer block size of Socket n. Socket n TX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes.
- * If a different size is configured, the data can�t be normally transmitted to a peer.
- * Although Socket n TX Buffer Block size is initially configured to 2Kbytes,
- * user can be re-configure its size using @ref Sn_TXBUF_SIZE. The total sum of @ref Sn_TXBUF_SIZE can not be exceed 16Kbytes.
- * When exceeded, the data transmission error is occurred.
- */
-static inline uint32_t Sn_TXBUF_SIZE(uint8_t N)
-{
- return _W5500_IO_BASE_ + (0x001F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
-}
-
-/**
- * @ingroup Socket_register_group
- * @brief Transmit free memory size register(R)
- * @details @ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. It is initialized to the configured size by @ref Sn_TXBUF_SIZE.
- * Data bigger than @ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the bigger data overwrites the previous saved data not yet sent.
- * Therefore, check before saving the data to the Socket n TX Buffer, and if data is equal or smaller than its checked size,
- * transmit the data with SEND/SEND_MAC command after saving the data in Socket n TX buffer. But, if data is bigger than its checked size,
- * transmit the data after dividing into the checked size and saving in the Socket n TX buffer.
- */
-static inline uint32_t Sn_TX_FSR(uint8_t N)
-{
- return _W5500_IO_BASE_ + (0x0020 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
-}
-
-/**
- * @ingroup Socket_register_group
- * @brief Transmit memory read pointer register address(R)
- * @details @ref Sn_TX_RD is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with TCP.
- * After its initialization, it is auto-increased by SEND command.
- * SEND command transmits the saved data from the current @ref Sn_TX_RD to the @ref Sn_TX_WR in the Socket n TX Buffer.
- * After transmitting the saved data, the SEND command increases the @ref Sn_TX_RD as same as the @ref Sn_TX_WR.
- * If its increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs),
- * then the carry bit is ignored and will automatically update with the lower 16bits value.
- */
-static inline uint32_t Sn_TX_RD(uint8_t N)
-{
- return _W5500_IO_BASE_ + (0x0022 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
-}
-
-/**
- * @ingroup Socket_register_group
- * @brief Transmit memory write pointer register address(R/W)
- * @details @ref Sn_TX_WR is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with TCP.\n
- * It should be read or be updated like as follows.\n
- * 1. Read the starting address for saving the transmitting data.\n
- * 2. Save the transmitting data from the starting address of Socket n TX buffer.\n
- * 3. After saving the transmitting data, update @ref Sn_TX_WR to the increased value as many as transmitting data size.
- * If the increment value exceeds the maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs),
- * then the carry bit is ignored and will automatically update with the lower 16bits value.\n
- * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command
- */
-static inline uint32_t Sn_TX_WR(uint8_t N)
-{
- return _W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
-}
-
-/**
- * @ingroup Socket_register_group
- * @brief Received data size register(R)
- * @details @ref Sn_RX_RSR indicates the data size received and saved in Socket n RX Buffer.
- * @ref Sn_RX_RSR does not exceed the @ref Sn_RXBUF_SIZE and is calculated as the difference between
- * Socket n RX Write Pointer (@ref Sn_RX_WR)and Socket n RX Read Pointer (@ref Sn_RX_RD)
- */
-static inline uint32_t Sn_RX_RSR(uint8_t N)
-{
- return _W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
-}
-
-/**
- * @ingroup Socket_register_group
- * @brief Read point of Receive memory(R/W)
- * @details @ref Sn_RX_RD is initialized by OPEN command. Make sure to be read or updated as follows.\n
- * 1. Read the starting save address of the received data.\n
- * 2. Read data from the starting address of Socket n RX Buffer.\n
- * 3. After reading the received data, Update @ref Sn_RX_RD to the increased value as many as the reading size.
- * If the increment value exceeds the maximum value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs,
- * update with the lower 16bits value ignored the carry bit.\n
- * 4. Order RECV command is for notifying the updated @ref Sn_RX_RD to W5500.
- */
-static inline uint32_t Sn_RX_RD(uint8_t N)
-{
- return _W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
-}
-
-/**
- * @ingroup Socket_register_group
- * @brief Write point of Receive memory(R)
- * @details @ref Sn_RX_WR is initialized by OPEN command and it is auto-increased by the data reception.
- * If the increased value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs),
- * then the carry bit is ignored and will automatically update with the lower 16bits value.
- */
-static inline uint32_t Sn_RX_WR(uint8_t N)
-{
- return _W5500_IO_BASE_ + (0x002A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
-}
-
-/**
- * @ingroup Socket_register_group
- * @brief socket interrupt mask register(R)
- * @details @ref Sn_IMR masks the interrupt of Socket n.
- * Each bit corresponds to each bit of @ref Sn_IR. When a Socket n Interrupt is occurred and the corresponding bit of @ref Sn_IMR is
- * the corresponding bit of @ref Sn_IR becomes When both the corresponding bit of @ref Sn_IMR and @ref Sn_IR are and the n-th bit of @ref IR is
- * Host is interrupted by asserted INTn PIN to low.
- */
-static inline uint32_t Sn_IMR(uint8_t N)
-{
- return _W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
-}
-
-/**
- * @ingroup Socket_register_group
- * @brief Fragment field value in IP header register(R/W)
- * @details @ref Sn_FRAG configures the FRAG(Fragment field in IP header).
- */
- static inline uint32_t Sn_FRAG(uint8_t N)
- {
- return _W5500_IO_BASE_ + (0x002D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
- }
-
-/**
- * @ingroup Socket_register_group
- * @brief Keep Alive Timer register(R/W)
- * @details @ref Sn_KPALVTR configures the transmitting timer of �KEEP ALIVE(KA)packet of SOCKETn. It is valid only in TCP mode,
- * and ignored in other modes. The time unit is 5s.
- * KA packet is transmittable after @ref Sn_SR is changed to SOCK_ESTABLISHED and after the data is transmitted or received to/from a peer at least once.
- * In case of '@ref Sn_KPALVTR > 0', W5500 automatically transmits KA packet after time-period for checking the TCP connection (Auto-keepalive-process).
- * In case of '@ref Sn_KPALVTR = 0', Auto-keep-alive-process will not operate,
- * and KA packet can be transmitted by SEND_KEEP command by the host (Manual-keep-alive-process).
- * Manual-keep-alive-process is ignored in case of '@ref Sn_KPALVTR > 0'.
- */
-static inline uint32_t Sn_KPALVTR(uint8_t N)
-{
- return _W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
-}
-
-//#define Sn_TSR(N) (_W5500_IO_BASE_ + (0x0030 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
-
-
-//----------------------------- W5500 Register values -----------------------------
-
-/* MODE register values */
-/**
- * @brief Reset
- * @details If this bit is All internal registers will be initialized. It will be automatically cleared as after S/W reset.
- */
-const uint8_t MR_RST = 0x80;
-
-/**
- * @brief Wake on LAN
- * @details 0 : Disable WOL mode\n
- * 1 : Enable WOL mode\n
- * If WOL mode is enabled and the received magic packet over UDP has been normally processed, the Interrupt PIN (INTn) asserts to low.
- * When using WOL mode, the UDP Socket should be opened with any source port number. (Refer to Socket n Mode Register (@ref Sn_MR) for opening Socket.)
- * @note The magic packet over UDP supported by W5500 consists of 6 bytes synchronization stream (xFFFFFFFFFFFF and
- * 16 times Target MAC address stream in UDP payload. The options such like password are ignored. You can use any UDP source port number for WOL mode.
- */
-const uint8_t MR_WOL = 0x20;
-
-/**
- * @brief Ping block
- * @details 0 : Disable Ping block\n
- * 1 : Enable Ping block\n
- * If the bit is it blocks the response to a ping request.
- */
-const uint8_t MR_PB = 0x10;
-
-/**
- * @brief Enable PPPoE
- * @details 0 : DisablePPPoE mode\n
- * 1 : EnablePPPoE mode\n
- * If you use ADSL, this bit should be
- */
-const uint8_t MR_PPPOE = 0x08;
-
-/**
- * @brief Enable UDP_FORCE_ARP CHECHK
- * @details 0 : Disable Force ARP mode\n
- * 1 : Enable Force ARP mode\n
- * In Force ARP mode, It forces on sending ARP Request whenever data is sent.
- */
-const uint8_t MR_FARP = 0x02;
-
-/* IR register values */
-/**
- * @brief Check IP conflict.
- * @details Bit is set as when own source IP address is same with the sender IP address in the received ARP request.
- */
-const uint8_t IR_CONFLICT = 0x80;
-
-/**
- * @brief Get the destination unreachable message in UDP sending.
- * @details When receiving the ICMP (Destination port unreachable) packet, this bit is set as
- * When this bit is Destination Information such as IP address and Port number may be checked with the corresponding @ref UIPR & @ref UPORTR.
- */
-const uint8_t IR_UNREACH = 0x40;
-
-/**
- * @brief Get the PPPoE close message.
- * @details When PPPoE is disconnected during PPPoE mode, this bit is set.
- */
-const uint8_t IR_PPPoE = 0x20;
-
-/**
- * @brief Get the magic packet interrupt.
- * @details When WOL mode is enabled and receives the magic packet over UDP, this bit is set.
- */
-const uint8_t IR_MP = 0x10;
-
-
-/* PHYCFGR register value */
-const uint8_t PHYCFGR_RST = (uint8_t)~(1<<7); //< For PHY reset, must operate AND mask.
-const uint8_t PHYCFGR_OPMD = (1<<6); // Configre PHY with OPMDC value
-const uint8_t PHYCFGR_OPMDC_ALLA = (7<<3);
-const uint8_t PHYCFGR_OPMDC_PDOWN = (6<<3);
-const uint8_t PHYCFGR_OPMDC_NA = (5<<3);
-const uint8_t PHYCFGR_OPMDC_100FA = (4<<3);
-const uint8_t PHYCFGR_OPMDC_100F = (3<<3);
-const uint8_t PHYCFGR_OPMDC_100H = (2<<3);
-const uint8_t PHYCFGR_OPMDC_10F = (1<<3);
-const uint8_t PHYCFGR_OPMDC_10H = (0<<3);
-const uint8_t PHYCFGR_DPX_FULL = (1<<2);
-const uint8_t PHYCFGR_DPX_HALF = (0<<2);
-const uint8_t PHYCFGR_SPD_100 = (1<<1);
-const uint8_t PHYCFGR_SPD_10 = (0<<1);
-const uint8_t PHYCFGR_LNK_ON = (1<<0);
-const uint8_t PHYCFGR_LNK_OFF = (0<<0);
-
-/* IMR register values */
-/**
- * @brief IP Conflict Interrupt Mask.
- * @details 0: Disable IP Conflict Interrupt\n
- * 1: Enable IP Conflict Interrupt
- */
-const uint8_t IM_IR7 = 0x80;
-
-/**
- * @brief Destination unreachable Interrupt Mask.
- * @details 0: Disable Destination unreachable Interrupt\n
- * 1: Enable Destination unreachable Interrupt
- */
-const uint8_t IM_IR6 = 0x40;
-
-/**
- * @brief PPPoE Close Interrupt Mask.
- * @details 0: Disable PPPoE Close Interrupt\n
- * 1: Enable PPPoE Close Interrupt
- */
-const uint8_t IM_IR5 = 0x20;
-
-/**
- * @brief Magic Packet Interrupt Mask.
- * @details 0: Disable Magic Packet Interrupt\n
- * 1: Enable Magic Packet Interrupt
- */
-const uint8_t IM_IR4 = 0x10;
-
-/* Sn_MR Default values */
-/**
- * @brief Support UDP Multicasting
- * @details 0 : disable Multicasting\n
- * 1 : enable Multicasting\n
- * This bit is applied only during UDP mode(P[3:0] = 010.\n
- * To use multicasting, @ref Sn_DIPR & @ref Sn_DPORT should be respectively configured with the multicast group IP address & port number
- * before Socket n is opened by OPEN command of @ref Sn_CR.
- */
-const uint8_t Sn_MR_MULTI = 0x80;
-
-/**
- * @brief Broadcast block in UDP Multicasting.
- * @details 0 : disable Broadcast Blocking\n
- * 1 : enable Broadcast Blocking\n
- * This bit blocks to receive broadcasting packet during UDP mode(P[3:0] = 010.\m
- * In addition, This bit does when MACRAW mode(P[3:0] = 100
- */
-const uint8_t Sn_MR_BCASTB = 0x40;
-
-/**
- * @brief No Delayed Ack(TCP), Multicast flag
- * @details 0 : Disable No Delayed ACK option\n
- * 1 : Enable No Delayed ACK option\n
- * This bit is applied only during TCP mode (P[3:0] = 001.\n
- * When this bit is It sends the ACK packet without delay as soon as a Data packet is received from a peer.\n
- * When this bit is It sends the ACK packet after waiting for the timeout time configured by @ref _RTR_.
- */
-const uint8_t Sn_MR_ND = 0x20;
-
-/**
- * @brief Unicast Block in UDP Multicasting
- * @details 0 : disable Unicast Blocking\n
- * 1 : enable Unicast Blocking\n
- * This bit blocks receiving the unicast packet during UDP mode(P[3:0] = 010 and MULTI =
- */
-const uint8_t Sn_MR_UCASTB = 0x10;
-
-/**
- * @brief MAC LAYER RAW SOCK
- * @details This configures the protocol mode of Socket n.
- * @note MACRAW mode should be only used in Socket 0.
- */
-const uint8_t Sn_MR_MACRAW = 0x04;
-
-//#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */
-
-/**
- * @brief UDP
- * @details This configures the protocol mode of Socket n.
- */
-const uint8_t Sn_MR_UDP = 0x02;
-
-/**
- * @brief TCP
- * @details This configures the protocol mode of Socket n.
- */
-const uint8_t Sn_MR_TCP = 0x01;
-
-/**
- * @brief Unused socket
- * @details This configures the protocol mode of Socket n.
- */
-const uint8_t Sn_MR_CLOSE = 0x00;
-
-/* Sn_MR values used with Sn_MR_MACRAW */
-/**
- * @brief MAC filter enable in @ref Sn_MR_MACRAW mode
- * @details 0 : disable MAC Filtering\n
- * 1 : enable MAC Filtering\n
- * This bit is applied only during MACRAW mode(P[3:0] = 100.\n
- * When set as W5500 can only receive broadcasting packet or packet sent to itself.
- * When this bit is W5500 can receive all packets on Ethernet.
- * If user wants to implement Hybrid TCP/IP stack,
- * it is recommended that this bit is set as for reducing host overhead to process the all received packets.
- */
-const uint8_t Sn_MR_MFEN = Sn_MR_MULTI;
-
-/**
- * @brief Multicast Blocking in @ref Sn_MR_MACRAW mode
- * @details 0 : using IGMP version 2\n
- * 1 : using IGMP version 1\n
- * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI =
- * It configures the version for IGMP messages (Join/Leave/Report).
- */
-const uint8_t Sn_MR_MMB = Sn_MR_ND;
-
-/**
- * @brief IPv6 packet Blocking in @ref Sn_MR_MACRAW mode
- * @details 0 : disable IPv6 Blocking\n
- * 1 : enable IPv6 Blocking\n
- * This bit is applied only during MACRAW mode (P[3:0] = 100. It blocks to receiving the IPv6 packet.
- */
-const uint8_t Sn_MR_MIP6B = Sn_MR_UCASTB;
-
-/* Sn_MR value used with Sn_MR_UDP & Sn_MR_MULTI */
-/**
- * @brief IGMP version used in UDP mulitcasting
- * @details 0 : disable Multicast Blocking\n
- * 1 : enable Multicast Blocking\n
- * This bit is applied only when MACRAW mode(P[3:0] = 100. It blocks to receive the packet with multicast MAC address.
- */
-const uint8_t Sn_MR_MC = Sn_MR_ND;
-
-/* Sn_MR alternate values */
-/**
- * @brief For Berkeley Socket API
- */
-const uint8_t SOCK_STREAM = Sn_MR_TCP;
-
-/**
- * @brief For Berkeley Socket API
- */
-const uint8_t SOCK_DGRAM = Sn_MR_UDP;
-
-
-/* Sn_CR values */
-/**
- * @brief Initialize or open socket
- * @details Socket n is initialized and opened according to the protocol selected in Sn_MR(P3:P0).
- * The table below shows the value of @ref Sn_SR corresponding to @ref Sn_MR.\n
- * <table>
- * <tr> <td>\b Sn_MR (P[3:0])</td> <td>\b Sn_SR</td> </tr>
- * <tr> <td>Sn_MR_CLOSE (000)</td> <td></td> </tr>
- * <tr> <td>Sn_MR_TCP (001)</td> <td>SOCK_INIT (0x13)</td> </tr>
- * <tr> <td>Sn_MR_UDP (010)</td> <td>SOCK_UDP (0x22)</td> </tr>
- * <tr> <td>S0_MR_MACRAW (100)</td> <td>SOCK_MACRAW (0x02)</td> </tr>
- * </table>
- */
-const uint8_t Sn_CR_OPEN = 0x01;
-
-/**
- * @brief Wait connection request in TCP mode(Server mode)
- * @details This is valid only in TCP mode (\ref Sn_MR(P3:P0) = \ref Sn_MR_TCP).
- * In this mode, Socket n operates as a TCP serverand waits for connection-request (SYN packet) from any TCP client
- * The @ref Sn_SR changes the state from \ref SOCK_INIT to \ref SOCKET_LISTEN.
- * When a TCP clientconnection request is successfully established,
- * the @ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the @ref Sn_IR(0) becomes
- * But when a TCP clientconnection request is failed, @ref Sn_IR(3) becomes and the status of @ref Sn_SR changes to SOCK_CLOSED.
- */
-const uint8_t Sn_CR_LISTEN = 0x02;
-
-/**
- * @brief Send connection request in TCP mode(Client mode)
- * @details To connect, a connect-request (SYN packet) is sent to <b>TCP server</b>configured by @ref Sn_DIPR & Sn_DPORT(destination address & port).
- * If the connect-request is successful, the @ref Sn_SR is changed to @ref SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n
- * The connect-request fails in the following three cases.\n
- * 1. When a @b ARPTO occurs (@ref Sn_IR[3] = ) because destination hardware address is not acquired through the ARP-process.\n
- * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) = )\n
- * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, @ref Sn_SR is changed to @ref SOCK_CLOSED.
- * @note This is valid only in TCP mode and operates when Socket n acts as <b>TCP client</b>
- */
-const uint8_t Sn_CR_CONNECT = 0x04;
-
-/**
- * @brief Send closing request in TCP mode
- * @details Regardless of <b>TCP server</b>or <b>TCP client</b> the DISCON command processes the disconnect-process (b>Active close</b>or <b>Passive close</b>.\n
- * @par Active close
- * it transmits disconnect-request(FIN packet) to the connected peer\n
- * @par Passive close
- * When FIN packet is received from peer, a FIN packet is replied back to the peer.\n
- * @details When the disconnect-process is successful (that is, FIN/ACK packet is received successfully), @ref Sn_SR is changed to @ref SOCK_CLOSED.\n
- * Otherwise, TCPTO occurs (\ref Sn_IR(3)='1') and then @ref Sn_SR is changed to @ref SOCK_CLOSED.
- * @note Valid only in TCP mode.
- */
-const uint8_t Sn_CR_DISCON = 0x08;
-
-/**
- * @brief Close socket
- * @details Sn_SR is changed to @ref SOCK_CLOSED.
- */
-const uint8_t Sn_CR_CLOSE = 0x10;
-
-/**
- * @brief Update TX buffer pointer and send data
- * @details SEND transmits all the data in the Socket n TX buffer.\n
- * For more details, please refer to Socket n TX Free Size Register (@ref Sn_TX_FSR), Socket n,
- * TX Write Pointer Register(@ref Sn_TX_WR), and Socket n TX Read Pointer Register(@ref Sn_TX_RD).
- */
-const uint8_t Sn_CR_SEND = 0x20;
-
-/**
- * @brief Send data with MAC address, so without ARP process
- * @details The basic operation is same as SEND.\n
- * Normally SEND transmits data after destination hardware address is acquired by the automatic ARP-process(Address Resolution Protocol).\n
- * But SEND_MAC transmits data without the automatic ARP-process.\n
- * In this case, the destination hardware address is acquired from @ref Sn_DHAR configured by host, instead of APR-process.
- * @note Valid only in UDP mode.
- */
-const uint8_t Sn_CR_SEND_MAC = 0x21;
-
-/**
- * @brief Send keep alive message
- * @details It checks the connection status by sending 1byte keep-alive packet.\n
- * If the peer can not respond to the keep-alive packet during timeout time, the connection is terminated and the timeout interrupt will occur.
- * @note Valid only in TCP mode.
- */
-const uint8_t Sn_CR_SEND_KEEP = 0x22;
-
-/**
- * @brief Update RX buffer pointer and receive data
- * @details RECV completes the processing of the received data in Socket n RX Buffer by using a RX read pointer register (@ref Sn_RX_RD).\n
- * For more details, refer to Socket n RX Received Size Register (@ref Sn_RX_RSR), Socket n RX Write Pointer Register (@ref Sn_RX_WR),
- * and Socket n RX Read Pointer Register (@ref Sn_RX_RD).
- */
-const uint8_t Sn_CR_RECV = 0x40;
-
-/* Sn_IR values */
-/**
- * @brief SEND_OK Interrupt
- * @details This is issued when SEND command is completed.
- */
-const uint8_t Sn_IR_SENDOK = 0x10;
-
-/**
- * @brief TIMEOUT Interrupt
- * @details This is issued when ARPTO or TCPTO occurs.
- */
-const uint8_t Sn_IR_TIMEOUT = 0x08;
-
-/**
- * @brief RECV Interrupt
- * @details This is issued whenever data is received from a peer.
- */
-const uint8_t Sn_IR_RECV = 0x04;
-
-/**
- * @brief DISCON Interrupt
- * @details This is issued when FIN or FIN/ACK packet is received from a peer.
- */
-const uint8_t Sn_IR_DISCON = 0x02;
-
-/**
- * @brief CON Interrupt
- * @details This is issued one time when the connection with peer is successful and then @ref Sn_SR is changed to @ref SOCK_ESTABLISHED.
- */
-const uint8_t Sn_IR_CON = 0x01;
-
-/* Sn_SR values */
-/**
- * @brief Closed
- * @details This indicates that Socket n is released.\n
- * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to @ref SOCK_CLOSED regardless of previous status.
- */
-const uint8_t SOCK_CLOSED = 0x00;
-
-/**
- * @brief Initiate state
- * @details This indicates Socket n is opened with TCP mode.\n
- * It is changed to @ref SOCK_INIT when @ref Sn_MR(P[3:0]) = 001 and OPEN command is ordered.\n
- * After @ref SOCK_INIT, user can use LISTEN /CONNECT command.
- */
-const uint8_t SOCK_INIT = 0x13;
-
-/**
- * @brief Listen state
- * @details This indicates Socket n is operating as <b>TCP server</b>mode and waiting for connection-request (SYN packet) from a peer <b>TCP client</b>.\n
- * It will change to @ref SOCK_ESTALBLISHED when the connection-request is successfully accepted.\n
- * Otherwise it will change to @ref SOCK_CLOSED after TCPTO @ref Sn_IR(TIMEOUT) = '1') is occurred.
- */
-const uint8_t SOCK_LISTEN = 0x14;
-
-/**
- * @brief Connection state
- * @details This indicates Socket n sent the connect-request packet (SYN packet) to a peer.\n
- * It is temporarily shown when @ref Sn_SR is changed from @ref SOCK_INIT to @ref SOCK_ESTABLISHED by CONNECT command.\n
- * If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to @ref SOCK_ESTABLISHED.\n
- * Otherwise, it changes to @ref SOCK_CLOSED after TCPTO (@ref Sn_IR[TIMEOUT] = '1') is occurred.
- */
-const uint8_t SOCK_SYNSENT = 0x15;
-
-/**
- * @brief Connection state
- * @details It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.\n
- * If socket n sends the response (SYN/ACK packet) to the peer successfully, it changes to @ref SOCK_ESTABLISHED. \n
- * If not, it changes to @ref SOCK_CLOSED after timeout (@ref Sn_IR[TIMEOUT] = '1') is occurred.
- */
-const uint8_t SOCK_SYNRECV = 0x16;
-
-/**
- * @brief Success to connect
- * @details This indicates the status of the connection of Socket n.\n
- * It changes to @ref SOCK_ESTABLISHED when the <b>TCP SERVER</b>processed the SYN packet from the <b>TCP CLIENT</b>during @ref SOCK_LISTEN, or
- * when the CONNECT command is successful.\n
- * During @ref SOCK_ESTABLISHED, DATA packet can be transferred using SEND or RECV command.
- */
-const uint8_t SOCK_ESTABLISHED = 0x17;
-
-/**
- * @brief Closing state
- * @details These indicate Socket n is closing.\n
- * These are shown in disconnect-process such as active-close and passive-close.\n
- * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED.
- */
-const uint8_t SOCK_FIN_WAIT = 0x18;
-
-/**
- * @brief Closing state
- * @details These indicate Socket n is closing.\n
- * These are shown in disconnect-process such as active-close and passive-close.\n
- * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED.
- */
-const uint8_t SOCK_CLOSING = 0x1A;
-
-/**
- * @brief Closing state
- * @details These indicate Socket n is closing.\n
- * These are shown in disconnect-process such as active-close and passive-close.\n
- * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED.
- */
-const uint8_t SOCK_TIME_WAIT = 0x1B;
-
-/**
- * @brief Closing state
- * @details This indicates Socket n received the disconnect-request (FIN packet) from the connected peer.\n
- * This is half-closing status, and data can be transferred.\n
- * For full-closing, DISCON command is used. But For just-closing, CLOSE command is used.
- */
-const uint8_t SOCK_CLOSE_WAIT = 0x1C;
-
-/**
- * @brief Closing state
- * @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n
- * It changes to @ref SOCK_CLOSED when Socket n received the response successfully, or when timeout(@ref Sn_IR[TIMEOUT] = '1') is occurred.
- */
-const uint8_t SOCK_LAST_ACK = 0x1D;
-
-/**
- * @brief UDP socket
- * @details This indicates Socket n is opened in UDP mode(@ref Sn_MR(P[3:0]) = '010').\n
- * It changes to SOCK_UDP when @ref Sn_MR(P[3:0]) = '010' and @ref Sn_CR_OPEN command is ordered.\n
- * Unlike TCP mode, data can be transfered without the connection-process.
- */
-const uint8_t SOCK_UDP = 0x22;
-
-//#define SOCK_IPRAW 0x32 /**< IP raw mode socket */
-
-/**
- * @brief MAC raw mode socket
- * @details This indicates Socket 0 is opened in MACRAW mode (S0_MR(P[3:0]) = 100and is valid only in Socket 0.\n
- * It changes to SOCK_MACRAW when S0_MR(P[3:0] = 100and OPEN command is ordered.\n
- * Like UDP mode socket, MACRAW mode Socket 0 can transfer a MAC packet (Ethernet frame) without the connection-process.
- */
-const uint8_t SOCK_MACRAW = 0x42;
-
-//#define SOCK_PPPOE 0x5F
-
-/* IP PROTOCOL */
-#define IPPROTO_IP 0 //< Dummy for IP
-#define IPPROTO_ICMP 1 //< Control message protocol
-#define IPPROTO_IGMP 2 //< Internet group management protocol
-#define IPPROTO_GGP 3 //< Gateway^2 (deprecated)
-#define IPPROTO_TCP 6 //< TCP
-#define IPPROTO_PUP 12 //< PUP
-#define IPPROTO_UDP 17 //< UDP
-#define IPPROTO_IDP 22 //< XNS idp
-#define IPPROTO_ND 77 //< UNOFFICIAL net disk protocol
-#define IPPROTO_RAW 255 //< Raw IP packet
-
-
-/**
- * @brief Enter a critical section
- *
- * @details It is provided to protect your shared code which are executed without distribution. \n \n
- *
- * In non-OS environment, It can be just implemented by disabling whole interrupt.\n
- * In OS environment, You can replace it to critical section api supported by OS.
- *
- * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF()
- * \sa WIZCHIP_CRITICAL_EXIT()
- */
-static inline void WIZCHIP_CRITICAL_ENTER() {}
-
-/**
- * @brief Exit a critical section
- *
- * @details It is provided to protect your shared code which are executed without distribution. \n\n
- *
- * In non-OS environment, It can be just implemented by disabling whole interrupt. \n
- * In OS environment, You can replace it to critical section api supported by OS.
- *
- * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF()
- * @sa WIZCHIP_CRITICAL_ENTER()
- */
-static inline void WIZCHIP_CRITICAL_EXIT() { }
-
-
-////////////////////////
-// Basic I/O Function //
-////////////////////////
-
-/**
- * @ingroup Basic_IO_function
- * @brief It reads 1 byte value from a register.
- * @param AddrSel Register address
- * @return The value of register
- */
-uint8_t WIZCHIP_READ (uint32_t AddrSel);
-
-/**
- * @ingroup Basic_IO_function
- * @brief It writes 1 byte value to a register.
- * @param AddrSel Register address
- * @param wb Write data
- * @return void
- */
-void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb );
-
-/**
- * @ingroup Basic_IO_function
- * @brief It reads sequence data from registers.
- * @param AddrSel Register address
- * @param pBuf Pointer buffer to read data
- * @param len Data length
- */
-void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
-
-/**
- * @ingroup Basic_IO_function
- * @brief It writes sequence data to registers.
- * @param AddrSel Register address
- * @param pBuf Pointer buffer to write data
- * @param len Data length
- */
-void WIZCHIP_WRITE_BUF(uint32_t AddrSel, const uint8_t* pBuf, uint16_t len);
-
-/////////////////////////////////
-// Common Register I/O function //
-/////////////////////////////////
-/**
- * @ingroup Common_register_access_function
- * @brief Set Mode Register
- * @param (uint8_t)mr The value to be set.
- * @sa getMR()
- */
-static inline void setMR(uint8_t mr)
-{
- WIZCHIP_WRITE(MR, mr);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get Mode Register
- * @return uint8_t. The value of Mode register.
- * @sa setMR()
- */
-static inline uint8_t getMR()
-{
- return WIZCHIP_READ(MR);
-}
-
-
-/**
- * @ingroup Common_register_access_function
- * @brief Set gateway IP address
- * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be allocated 4 bytes.
- * @sa getGAR()
- */
-static inline void setGAR(const uint8_t *gar)
-{
- WIZCHIP_WRITE_BUF(GAR, gar, 4);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get gateway IP address
- * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be allocated 4 bytes.
- * @sa setGAR()
- */
-static inline void getGAR(uint8_t *gar)
-{
- WIZCHIP_READ_BUF(GAR, gar, 4);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Set subnet mask address
- * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should be allocated 4 bytes.
- * @sa getSUBR()
- */
-static inline void setSUBR(const uint8_t *subr)
-{
- WIZCHIP_WRITE_BUF(SUBR, subr, 4);
-}
-
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get subnet mask address
- * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should be allocated 4 bytes.
- * @sa setSUBR()
- */
-static inline void getSUBR(uint8_t* subr)
-{
- WIZCHIP_READ_BUF(SUBR, subr, 4);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Set local MAC address
- * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be allocated 6 bytes.
- * @sa getSHAR()
- */
-static inline void setSHAR(const uint8_t *shar)
-{
- WIZCHIP_WRITE_BUF(SHAR, shar, 6);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get local MAC address
- * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be allocated 6 bytes.
- * @sa setSHAR()
- */
-static inline void getSHAR(uint8_t *shar)
-{
- WIZCHIP_READ_BUF(SHAR, shar, 6);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Set local IP address
- * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be allocated 4 bytes.
- * @sa getSIPR()
- */
-static inline void setSIPR(const uint8_t *sipr)
-{
- WIZCHIP_WRITE_BUF(SIPR, sipr, 4);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get local IP address
- * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be allocated 4 bytes.
- * @sa setSIPR()
- */
-static inline void getSIPR(uint8_t *sipr)
-{
- WIZCHIP_READ_BUF(SIPR, sipr, 4);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Set INTLEVEL register
- * @param (uint16_t)intlevel Value to set @ref INTLEVEL register.
- * @sa getINTLEVEL()
- */
-static inline void setINTLEVEL(uint16_t intlevel)
-{
- WIZCHIP_WRITE(INTLEVEL, (uint8_t)(intlevel >> 8));
- WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(INTLEVEL,1), (uint8_t) intlevel);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get INTLEVEL register
- * @return uint16_t. Value of @ref INTLEVEL register.
- * @sa setINTLEVEL()
- */
-static inline uint16_t getINTLEVEL()
-{
- const uint8_t msb = WIZCHIP_READ(INTLEVEL);
- return ((uint16_t)msb << 8) | WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL, 1));
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Set @ref IR register
- * @param (uint8_t)ir Value to set @ref IR register.
- * @sa getIR()
- */
-static inline void setIR(uint8_t ir)
-{
- WIZCHIP_WRITE(IR, (ir & 0xF0));
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get @ref IR register
- * @return uint8_t. Value of @ref IR register.
- * @sa setIR()
- */
-static inline uint8_t getIR()
-{
- return WIZCHIP_READ(IR) & 0xF0;
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Set @ref _IMR_ register
- * @param (uint8_t)imr Value to set @ref _IMR_ register.
- * @sa getIMR()
- */
-static inline void setIMR(uint8_t imr)
-{
- WIZCHIP_WRITE(_IMR_, imr);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get @ref _IMR_ register
- * @return uint8_t. Value of @ref _IMR_ register.
- * @sa setIMR()
- */
-static inline uint8_t getIMR()
-{
- return WIZCHIP_READ(_IMR_);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Set @ref SIR register
- * @param (uint8_t)sir Value to set @ref SIR register.
- * @sa getSIR()
- */
-static inline void setSIR(uint8_t sir)
-{
- WIZCHIP_WRITE(SIR, sir);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get @ref SIR register
- * @return uint8_t. Value of @ref SIR register.
- * @sa setSIR()
- */
-static inline uint8_t getSIR()
-{
- return WIZCHIP_READ(SIR);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Set @ref SIMR register
- * @param (uint8_t)simr Value to set @ref SIMR register.
- * @sa getSIMR()
- */
-static inline void setSIMR(uint8_t simr)
-{
- WIZCHIP_WRITE(SIMR, simr);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get @ref SIMR register
- * @return uint8_t. Value of @ref SIMR register.
- * @sa setSIMR()
- */
-static inline uint8_t getSIMR()
-{
- return WIZCHIP_READ(SIMR);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Set @ref _RTR_ register
- * @param (uint16_t)rtr Value to set @ref _RTR_ register.
- * @sa getRTR()
- */
-static inline void setRTR(uint16_t rtr)
-{
- WIZCHIP_WRITE(_RTR_, (uint8_t)(rtr >> 8));
- WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_RTR_,1), (uint8_t) rtr);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get @ref _RTR_ register
- * @return uint16_t. Value of @ref _RTR_ register.
- * @sa setRTR()
- */
-static inline uint16_t getRTR()
-{
- const uint8_t msb = WIZCHIP_READ(_RTR_);
- return ((uint16_t)msb << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_, 1));
-}
-
-
-/**
- * @ingroup Common_register_access_function
- * @brief Set @ref _RCR_ register
- * @param (uint8_t)rcr Value to set @ref _RCR_ register.
- * @sa getRCR()
- */
-static inline void setRCR(uint8_t rcr)
-{
- WIZCHIP_WRITE(_RCR_, rcr);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get @ref _RCR_ register
- * @return uint8_t. Value of @ref _RCR_ register.
- * @sa setRCR()
- */
-static inline uint8_t getRCR()
-{
- return WIZCHIP_READ(_RCR_);
-}
-
-//================================================== test done ===========================================================
-
-/**
- * @ingroup Common_register_access_function
- * @brief Set @ref PTIMER register
- * @param (uint8_t)ptimer Value to set @ref PTIMER register.
- * @sa getPTIMER()
- */
-static inline void setPTIMER(uint8_t ptimer)
-{
- WIZCHIP_WRITE(PTIMER, ptimer);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get @ref PTIMER register
- * @return uint8_t. Value of @ref PTIMER register.
- * @sa setPTIMER()
- */
-static inline uint8_t getPTIMER()
-{
- return WIZCHIP_READ(PTIMER);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Set @ref PMAGIC register
- * @param (uint8_t)pmagic Value to set @ref PMAGIC register.
- * @sa getPMAGIC()
- */
-static inline void setPMAGIC(uint8_t pmagic)
-{
- WIZCHIP_WRITE(PMAGIC, pmagic);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get @ref PMAGIC register
- * @return uint8_t. Value of @ref PMAGIC register.
- * @sa setPMAGIC()
- */
-static inline uint8_t getPMAGIC()
-{
- return WIZCHIP_READ(PMAGIC);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Set @ref PHAR address
- * @param (uint8_t*)phar Pointer variable to set PPP destination MAC register address. It should be allocated 6 bytes.
- * @sa getPHAR()
- */
-static inline void setPHAR(const uint8_t *phar)
-{
- WIZCHIP_WRITE_BUF(PHAR, phar, 6);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get @ref PHAR address
- * @param (uint8_t*)phar Pointer variable to PPP destination MAC register address. It should be allocated 6 bytes.
- * @sa setPHAR()
- */
-static inline void getPHAR(uint8_t *phar)
-{
- WIZCHIP_READ_BUF(PHAR, phar, 6);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Set @ref PSID register
- * @param (uint16_t)psid Value to set @ref PSID register.
- * @sa getPSID()
- */
-static inline void setPSID(uint16_t psid)
-{
- WIZCHIP_WRITE(PSID, (uint8_t)(psid >> 8));
- WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PSID,1), (uint8_t) psid);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get @ref PSID register
- * @return uint16_t. Value of @ref PSID register.
- * @sa setPSID()
- */
-static inline uint16_t getPSID()
-{
- const uint8_t msb = WIZCHIP_READ(PSID);
- return ((uint16_t)msb << 8) | WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1));
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Set @ref PMRU register
- * @param (uint16_t)pmru Value to set @ref PMRU register.
- * @sa getPMRU()
- */
-static inline void setPMRU(uint16_t pmru)
-{
- WIZCHIP_WRITE(PMRU, (uint8_t)(pmru>>8));
- WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PMRU,1), (uint8_t) pmru);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get @ref PMRU register
- * @return uint16_t. Value of @ref PMRU register.
- * @sa setPMRU()
- */
-static inline uint16_t getPMRU()
-{
- const uint8_t msb = WIZCHIP_READ(PMRU);
- return ((uint16_t)msb << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU, 1));
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get unreachable IP address
- * @param (uint8_t*)uipr Pointer variable to get unreachable IP address. It should be allocated 4 bytes.
- */
-static inline void getUIPR(uint8_t *uipr)
-{
- WIZCHIP_READ_BUF(UIPR, uipr, 4);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get @ref UPORTR register
- * @return uint16_t. Value of @ref UPORTR register.
- */
-static inline uint16_t getUPORTR()
-{
- const uint8_t msb = WIZCHIP_READ(UPORTR);
- return ((uint16_t)msb << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR, 1));
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Set @ref PHYCFGR register
- * @param (uint8_t)phycfgr Value to set @ref PHYCFGR register.
- * @sa getPHYCFGR()
- */
-static inline void setPHYCFGR(uint8_t phycfgr)
-{
- WIZCHIP_WRITE(PHYCFGR, phycfgr);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get @ref PHYCFGR register
- * @return uint8_t. Value of @ref PHYCFGR register.
- * @sa setPHYCFGR()
- */
-static inline uint8_t getPHYCFGR()
-{
- return WIZCHIP_READ(PHYCFGR);
-}
-
-/**
- * @ingroup Common_register_access_function
- * @brief Get @ref VERSIONR register
- * @return uint8_t. Value of @ref VERSIONR register.
- */
-static inline uint8_t getVERSIONR()
-{
- return WIZCHIP_READ(VERSIONR);
-}
-
-/////////////////////////////////////
-
-///////////////////////////////////
-// Socket N register I/O function //
-///////////////////////////////////
-/**
- * @ingroup Socket_register_access_function
- * @brief Set @ref Sn_MR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param (uint8_t)mr Value to set @ref Sn_MR
- * @sa getSn_MR()
- */
-static inline void setSn_MR(uint8_t sn, uint8_t mr)
-{
- WIZCHIP_WRITE(Sn_MR(sn), mr);
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_MR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint8_t. Value of @ref Sn_MR.
- * @sa setSn_MR()
- */
-static inline uint8_t getSn_MR(uint8_t sn)
-{
- return WIZCHIP_READ(Sn_MR(sn));
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Set @ref Sn_CR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param (uint8_t)cr Value to set @ref Sn_CR
- * @sa getSn_CR()
- */
-static inline void setSn_CR(uint8_t sn, uint8_t cr)
-{
- WIZCHIP_WRITE(Sn_CR(sn), cr);
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_CR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint8_t. Value of @ref Sn_CR.
- * @sa setSn_CR()
- */
-static inline uint8_t getSn_CR(uint8_t sn)
-{
- return WIZCHIP_READ(Sn_CR(sn));
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Set @ref Sn_IR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param (uint8_t)ir Value to set @ref Sn_IR
- * @sa getSn_IR()
- */
-static inline void setSn_IR(uint8_t sn, uint8_t ir)
-{
- WIZCHIP_WRITE(Sn_IR(sn), (ir & 0x1F));
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_IR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint8_t. Value of @ref Sn_IR.
- * @sa setSn_IR()
- */
-static inline uint8_t getSn_IR(uint8_t sn)
-{
- return WIZCHIP_READ(Sn_IR(sn)) & 0x1F;
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Set @ref Sn_IMR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param (uint8_t)imr Value to set @ref Sn_IMR
- * @sa getSn_IMR()
- */
-static inline void setSn_IMR(uint8_t sn, uint8_t imr)
-{
- WIZCHIP_WRITE(Sn_IMR(sn), (imr & 0x1F));
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_IMR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint8_t. Value of @ref Sn_IMR.
- * @sa setSn_IMR()
- */
-static inline uint8_t getSn_IMR(uint8_t sn)
-{
- return WIZCHIP_READ(Sn_IMR(sn)) & 0x1F;
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_SR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint8_t. Value of @ref Sn_SR.
- */
-static inline uint8_t getSn_SR(uint8_t sn)
-{
- return WIZCHIP_READ(Sn_SR(sn));
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Set @ref Sn_PORT register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param (uint16_t)port Value to set @ref Sn_PORT.
- * @sa getSn_PORT()
- */
-static inline void setSn_PORT(uint8_t sn, uint16_t port)
-{
- WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8));
- WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn), 1), (uint8_t) port);
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_PORT register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint16_t. Value of @ref Sn_PORT.
- * @sa setSn_PORT()
- */
-static inline uint16_t getSn_PORT(uint8_t sn)
-{
- const uint8_t msb = WIZCHIP_READ(Sn_PORT(sn));
- return ((uint16_t)msb << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn), 1));
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Set @ref Sn_DHAR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware address. It should be allocated 6 bytes.
- * @sa getSn_DHAR()
- */
-static inline void setSn_DHAR(uint8_t sn, const uint8_t *dhar)
-{
- WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6);
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_MR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware address. It should be allocated 6 bytes.
- * @sa setSn_DHAR()
- */
-static inline void getSn_DHAR(uint8_t sn, uint8_t *dhar)
-{
- WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6);
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Set @ref Sn_DIPR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param (uint8_t*)dipr Pointer variable to set socket n destination IP address. It should be allocated 4 bytes.
- * @sa getSn_DIPR()
- */
-static inline void setSn_DIPR(uint8_t sn, const uint8_t *dipr)
-{
- WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4);
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_DIPR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes.
- * @sa setSn_DIPR()
- */
-static inline void getSn_DIPR(uint8_t sn, uint8_t *dipr)
-{
- WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4);
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Set @ref Sn_DPORT register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param (uint16_t)dport Value to set @ref Sn_DPORT
- * @sa getSn_DPORT()
- */
-static inline void setSn_DPORT(uint8_t sn, uint16_t dport)
-{
- WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t) (dport >> 8));
- WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn), 1), (uint8_t) dport);
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_DPORT register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint16_t. Value of @ref Sn_DPORT.
- * @sa setSn_DPORT()
- */
-static inline uint16_t getSn_DPORT(uint8_t sn)
-{
- const uint8_t msb = WIZCHIP_READ(Sn_DPORT(sn));
- return ((uint16_t)msb << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1));
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Set @ref Sn_MSSR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param (uint16_t)mss Value to set @ref Sn_MSSR
- * @sa setSn_MSSR()
- */
-static inline void setSn_MSSR(uint8_t sn, uint16_t mss)
-{
- WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss >> 8));
- WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn), 1), (uint8_t) mss);
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_MSSR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint16_t. Value of @ref Sn_MSSR.
- * @sa setSn_MSSR()
- */
-static inline uint16_t getSn_MSSR(uint8_t sn)
-{
- const uint8_t msb = WIZCHIP_READ(Sn_MSSR(sn));
- return ((uint16_t)msb << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn), 1));
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Set @ref Sn_TOS register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param (uint8_t)tos Value to set @ref Sn_TOS
- * @sa getSn_TOS()
- */
-static inline void setSn_TOS(uint8_t sn, uint8_t tos)
-{
- WIZCHIP_WRITE(Sn_TOS(sn), tos);
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_TOS register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint8_t. Value of Sn_TOS.
- * @sa setSn_TOS()
- */
-static inline uint8_t getSn_TOS(uint8_t sn)
-{
- return WIZCHIP_READ(Sn_TOS(sn));
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Set @ref Sn_TTL register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param (uint8_t)ttl Value to set @ref Sn_TTL
- * @sa getSn_TTL()
- */
-static inline void setSn_TTL(uint8_t sn, uint8_t ttl)
-{
- WIZCHIP_WRITE(Sn_TTL(sn), ttl);
-}
-
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_TTL register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint8_t. Value of @ref Sn_TTL.
- * @sa setSn_TTL()
- */
-static inline uint8_t getSn_TTL(uint8_t sn)
-{
- return WIZCHIP_READ(Sn_TTL(sn));
-}
-
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Set @ref Sn_RXBUF_SIZE register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param (uint8_t)rxbufsize Value to set @ref Sn_RXBUF_SIZE
- * @sa getSn_RXBUF_SIZE()
- */
-static inline void setSn_RXBUF_SIZE(uint8_t sn, uint8_t rxbufsize)
-{
- WIZCHIP_WRITE(Sn_RXBUF_SIZE(sn),rxbufsize);
-}
-
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_RXBUF_SIZE register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint8_t. Value of @ref Sn_RXBUF_SIZE.
- * @sa setSn_RXBUF_SIZE()
- */
-static inline uint8_t getSn_RXBUF_SIZE(uint8_t sn)
-{
- return WIZCHIP_READ(Sn_RXBUF_SIZE(sn));
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Set @ref Sn_TXBUF_SIZE register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param (uint8_t)txbufsize Value to set @ref Sn_TXBUF_SIZE
- * @sa getSn_TXBUF_SIZE()
- */
-static inline void setSn_TXBUF_SIZE(uint8_t sn, uint8_t txbufsize)
-{
- WIZCHIP_WRITE(Sn_TXBUF_SIZE(sn), txbufsize);
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_TXBUF_SIZE register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint8_t. Value of @ref Sn_TXBUF_SIZE.
- * @sa setSn_TXBUF_SIZE()
- */
-static inline uint8_t getSn_TXBUF_SIZE(uint8_t sn)
-{
- return WIZCHIP_READ(Sn_TXBUF_SIZE(sn));
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_TX_FSR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint16_t. Value of @ref Sn_TX_FSR.
- */
-uint16_t getSn_TX_FSR(uint8_t sn);
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_TX_RD register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint16_t. Value of @ref Sn_TX_RD.
- */
-static inline uint16_t getSn_TX_RD(uint8_t sn)
-{
- const uint8_t msb = WIZCHIP_READ(Sn_TX_RD(sn));
- return ((uint16_t)msb << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1));
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Set @ref Sn_TX_WR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param (uint16_t)txwr Value to set @ref Sn_TX_WR
- * @sa GetSn_TX_WR()
- */
-static inline void setSn_TX_WR(uint8_t sn, uint16_t txwr)
-{
- WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr >> 8));
- WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn), 1), (uint8_t) txwr);
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_TX_WR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint16_t. Value of @ref Sn_TX_WR.
- * @sa setSn_TX_WR()
- */
-static inline uint16_t getSn_TX_WR(uint8_t sn)
-{
- const uint8_t msb = WIZCHIP_READ(Sn_TX_WR(sn));
- return ((uint16_t)msb << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1));
-}
-
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_RX_RSR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint16_t. Value of @ref Sn_RX_RSR.
- */
-uint16_t getSn_RX_RSR(uint8_t sn);
-
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Set @ref Sn_RX_RD register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD
- * @sa getSn_RX_RD()
- */
-static inline void setSn_RX_RD(uint8_t sn, uint16_t rxrd)
-{
- WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd >> 8));
- WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1), (uint8_t) rxrd);
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_RX_RD register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint16_t. Value of @ref Sn_RX_RD.
- * @sa setSn_RX_RD()
- */
-static inline uint16_t getSn_RX_RD(uint8_t sn)
-{
- const uint8_t msb = WIZCHIP_READ(Sn_RX_RD(sn));
- return ((uint16_t)msb << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn), 1));
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_RX_WR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint16_t. Value of @ref Sn_RX_WR.
- */
-static inline uint16_t getSn_RX_WR(uint8_t sn)
-{
- const uint8_t msb = WIZCHIP_READ(Sn_RX_WR(sn));
- return ((uint16_t)msb << 8) | WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn), 1));
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Set @ref Sn_FRAG register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param (uint16_t)frag Value to set @ref Sn_FRAG
- * @sa getSn_FRAD()
- */
-static inline void setSn_FRAG(uint8_t sn, uint16_t frag)
-{
- WIZCHIP_WRITE(Sn_FRAG(sn), (uint8_t)(frag >> 8));
- WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1), (uint8_t) frag);
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_FRAG register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint16_t. Value of @ref Sn_FRAG.
- * @sa setSn_FRAG()
- */
-static inline uint16_t getSn_FRAG(uint8_t sn)
-{
- const uint8_t msb = WIZCHIP_READ(Sn_FRAG(sn));
- return ((uint16_t)msb << 8) | WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1));
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Set @ref Sn_KPALVTR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param (uint8_t)kpalvt Value to set @ref Sn_KPALVTR
- * @sa getSn_KPALVTR()
- */
-static inline void setSn_KPALVTR(uint8_t sn, uint8_t kpalvt)
-{
- WIZCHIP_WRITE(Sn_KPALVTR(sn), kpalvt);
-}
-
-/**
- * @ingroup Socket_register_access_function
- * @brief Get @ref Sn_KPALVTR register
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint8_t. Value of @ref Sn_KPALVTR.
- * @sa setSn_KPALVTR()
- */
-static inline uint8_t getSn_KPALVTR(uint8_t sn)
-{
- return WIZCHIP_READ(Sn_KPALVTR(sn));
-}
-
-//////////////////////////////////////
-
-/////////////////////////////////////
-// Sn_TXBUF & Sn_RXBUF IO function //
-/////////////////////////////////////
-/**
- * @brief Socket_register_access_function
- * @brief Gets the max buffer size of socket sn passed as parameter.
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint16_t. Value of Socket n RX max buffer size.
- */
-static inline uint16_t getSn_RxMAX(uint8_t sn)
-{
- return ((uint16_t)getSn_RXBUF_SIZE(sn)) << 10;
-}
-
-/**
- * @brief Socket_register_access_function
- * @brief Gets the max buffer size of socket sn passed as parameters.
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @return uint16_t. Value of Socket n TX max buffer size.
- */
-static inline uint16_t getSn_TxMAX(uint8_t sn)
-{
- return ((uint16_t)getSn_TXBUF_SIZE(sn)) << 10;
-}
-
-/**
- * @ingroup Basic_IO_function
- * @brief It copies data to internal TX memory
- *
- * @details This function reads the Tx write pointer register and after that,
- * it copies the <i>wizdata(pointer buffer)</i> of the length of <i>len(variable)</i> bytes to internal TX memory
- * and updates the Tx write pointer register.
- * This function is being called by send() and sendto() function also.
- *
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param wizdata Pointer buffer to write data
- * @param len Data length
- * @sa wiz_recv_data()
- */
-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
- *
- * @details This function read the Rx read pointer register and after that,
- * it copies the received data from internal RX memory
- * to <i>wizdata(pointer variable)</i> of the length of <i>len(variable)</i> bytes.
- * This function is being called by recv() also.
- *
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param wizdata Pointer buffer to read data
- * @param len Data length
- * @sa wiz_send_data()
- */
-void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len);
-
-/**
- * @ingroup Basic_IO_function
- * @brief It discard the received data in RX memory.
- * @details It discards the data of the length of <i>len(variable)</i> bytes in internal RX memory.
- * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
- * @param len Data length
- */
-void wiz_recv_ignore(uint8_t sn, uint16_t len);
-
-#endif // _W5500_H_
diff --git a/src/Network2/W5500/Wiznet/Ethernet/WizSpi.cpp b/src/Network2/W5500/Wiznet/Ethernet/WizSpi.cpp
deleted file mode 100644
index 9a695791..00000000
--- a/src/Network2/W5500/Wiznet/Ethernet/WizSpi.cpp
+++ /dev/null
@@ -1,434 +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 1 // use peripheral DMA controller
-#define USE_DMAC 0 // use general DMA controller
-
-#if USE_PDC
-#include "pdc/pdc.h"
-#endif
-
-#if USE_DMAC
-#include "dmac/dmac.h"
-#endif
-
-#include "matrix/matrix.h"
-
-// SPI data rate. I tried 60MHz and we got some data corruption when uploading files, so I reduced it to 40MHz.
-// 2018-01-11: We have now received one report of data corruption at 40MHz, so reduced this to 30MHz
-const uint32_t SpiClockFrequency = 30000000;
-const unsigned int SpiPeripheralChannelId = 0; // we use NPCS0 as the slave select signal
-
-// Functions called by the W5500 module to transfer data to/from the W5500 via SPI
-
-#if USE_PDC
-static Pdc *spi_pdc;
-
-static inline void spi_rx_dma_enable()
-{
- pdc_enable_transfer(spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN); // we have to transmit in order to receive
-}
-
-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 | PERIPH_PTCR_TXTDIS); // we have to transmit in order to receive
-}
-
-static inline void spi_tx_dma_disable()
-{
- pdc_disable_transfer(spi_pdc, PERIPH_PTCR_TXTDIS);
-}
-
-static bool spi_dma_check_rx_complete()
-{
- return pdc_read_rx_counter(spi_pdc) == 0;
-}
-
-static void spi_tx_dma_setup(const uint8_t *buf, uint32_t length)
-{
- pdc_packet_t pdc_spi_packet;
- pdc_spi_packet.ul_addr = reinterpret_cast<uint32_t>(buf);
- pdc_spi_packet.ul_size = length;
- pdc_tx_init(spi_pdc, &pdc_spi_packet, nullptr);
-}
-
-static void spi_rx_dma_setup(uint8_t *buf, uint32_t length)
-{
- pdc_packet_t pdc_spi_packet;
- pdc_spi_packet.ul_addr = reinterpret_cast<uint32_t>(buf);
- pdc_spi_packet.ul_size = length;
- pdc_rx_init(spi_pdc, &pdc_spi_packet, nullptr);
- pdc_tx_init(spi_pdc, &pdc_spi_packet, nullptr); // we have to transmit in order to receive
-}
-
-#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();
-}
-
-#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 receive 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]);
- pinMode(APIN_SPI_SS0, OUTPUT_HIGH); // use manual SS control
-
- 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 transmit buffer empty, returning true if timed out
- static inline bool waitForTxReady()
- {
- uint32_t timeout = SPI_TIMEOUT;
- while ((SPI->SPI_SR & SPI_SR_TDRE) == 0)
- {
- 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->SPI_SR & SPI_SR_TXEMPTY) == 0)
- {
- 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->SPI_SR & SPI_SR_RDRF) == 0)
- {
- 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(W5500SsPin, LOW);
- (void)SPI->SPI_RDR; // clear receive register
- }
-
- // Set the SS pin high again
- void ReleaseSS()
- {
- waitForTxEmpty();
- digitalWrite(W5500SsPin, HIGH);
- }
-
- // Send the 3-byte address and control bits. On return there may be data still being received.
- void SendAddress(uint32_t addr)
- {
- 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;
- }
- }
- }
- }
-
- // Read a single byte. Called after sending the 3-byte address.
- uint8_t ReadByte()
- {
- (void)SPI->SPI_RDR;
- if (!waitForTxEmpty())
- {
- while ((SPI->SPI_SR & SPI_SR_RDRF) != 0)
- {
- (void)SPI->SPI_RDR; // clear previous data
- }
- SPI->SPI_TDR = 0x000000FF;
- if (!waitForRxReady())
- {
- return (uint8_t)SPI->SPI_RDR;
- }
- }
- return 0;
- }
-
- // Write a single byte. Called after sending the address.
- void WriteByte(uint8_t b)
- {
- const uint32_t dOut = b;
- if (!waitForTxReady())
- {
- SPI->SPI_TDR = dOut;
- }
- }
-
- // Read some data
- spi_status_t ReadBurst(uint8_t* rx_data, size_t len)
- {
- if (len != 0)
- {
- if (waitForTxEmpty())
- {
- return SPI_ERROR_TIMEOUT;
- }
-
- while ((SPI->SPI_SR & SPI_SR_RDRF) != 0)
- {
- (void)SPI->SPI_RDR; // clear previous data
- }
-
-#if USE_PDC
- spi_rx_dma_setup(rx_data, len);
- spi_rx_dma_enable();
- while (pdc_read_tx_counter(spi_pdc) != 0) { }
- uint32_t timeout = SPI_TIMEOUT;
- while (!spi_dma_check_rx_complete() && timeout != 0)
- {
- --timeout;
- }
- spi_rx_dma_disable();
- if (timeout == 0)
- {
- return SPI_ERROR_TIMEOUT;
- }
-#else
- const uint32_t dOut = 0x000000FF;
- SPI->SPI_TDR = dOut; // send first byte
- while (--len != 0)
- {
- // Wait for receive data available and transmit buffer empty
- uint32_t timeout = SPI_TIMEOUT + 1;
- do
- {
- if (--timeout == 0)
- {
- return SPI_ERROR_TIMEOUT;
- }
- }
- while ((SPI->SPI_SR & (SPI_SR_RDRF | SPI_SR_TDRE)) != (SPI_SR_RDRF | SPI_SR_TDRE));
-
- const uint32_t din = SPI->SPI_RDR; // get data from receive register
- SPI->SPI_TDR = dOut; // write to transmit register immediately
- *rx_data++ = (uint8_t)din;
- }
-
- if (waitForRxReady())
- {
- return SPI_ERROR_TIMEOUT;
- }
-
- *rx_data++ = (uint8_t)SPI->SPI_RDR; // Get last byte from receive register
-#endif
- }
- return SPI_OK;
- }
-
- // Send some data
- spi_status_t SendBurst(const uint8_t* tx_data, size_t len)
- {
-#if USE_PDC
- spi_tx_dma_setup(tx_data, len);
- spi_tx_dma_enable();
- while (pdc_read_tx_counter(spi_pdc) != 0) { }
- spi_tx_dma_disable();
-#else
- for (uint32_t i = 0; i < len; ++i)
- {
- uint32_t dOut = (uint32_t)*tx_data++;
- if (waitForTxReady())
- {
- return SPI_ERROR_TIMEOUT;
- }
-
- SPI->SPI_TDR = dOut; // write to transmit register
- (void)SPI->SPI_RDR;
- }
-#endif
- return SPI_OK;
- }
-
-} // end namespace
-
-// End
diff --git a/src/Network2/W5500/Wiznet/Ethernet/WizSpi.h b/src/Network2/W5500/Wiznet/Ethernet/WizSpi.h
deleted file mode 100644
index eeea6be4..00000000
--- a/src/Network2/W5500/Wiznet/Ethernet/WizSpi.h
+++ /dev/null
@@ -1,26 +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/spi.h"
-
-namespace WizSpi
-{
- void Init();
- void Stop();
- void AssertSS();
- void ReleaseSS();
- void SendAddress(uint32_t addr);
- 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);
-}
-
-#endif /* SRC_DUETNG_DUETETHERNET_ETHERNET3_UTILITY_WIZSPI_H_ */
diff --git a/src/Network2/W5500/Wiznet/Ethernet/socketlib.cpp b/src/Network2/W5500/Wiznet/Ethernet/socketlib.cpp
deleted file mode 100644
index 1ca60309..00000000
--- a/src/Network2/W5500/Wiznet/Ethernet/socketlib.cpp
+++ /dev/null
@@ -1,745 +0,0 @@
-//*****************************************************************************
-//
-//! \file socket.c
-//! \brief SOCKET APIs Implements file.
-//! \details SOCKET APIs like as Berkeley Socket APIs.
-//! \version 1.0.3
-//! \date 2013/10/21
-//! \par Revision history
-//! <2015/02/05> Notice
-//! The version history is not updated after this point.
-//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
-//! >> https://github.com/Wiznet/ioLibrary_Driver
-//! <2014/05/01> V1.0.3. Refer to M20140501
-//! 1. Implicit type casting -> Explicit type casting.
-//! 2. replace 0x01 with PACK_REMAINED in recvfrom()
-//! 3. Validation a destination ip in connect() & sendto():
-//! It occurs a fatal error on converting unint32 address if uint8* addr parameter is not aligned by 4byte address.
-//! Copy 4 byte addr value into temporary uint32 variable and then compares it.
-//! <2013/12/20> V1.0.2 Refer to M20131220
-//! Remove Warning.
-//! <2013/11/04> V1.0.1 2nd Release. Refer to "20131104".
-//! In sendto(), Add to clear timeout interrupt status (Sn_IR_TIMEOUT)
-//! <2013/10/21> 1st Release
-//! \author MidnightCow
-//! \copyright
-//!
-//! Copyright (c) 2013, WIZnet Co., LTD.
-//! All rights reserved.
-//!
-//! Redistribution and use in source and binary forms, with or without
-//! modification, are permitted provided that the following conditions
-//! are met:
-//!
-//! * Redistributions of source code must retain the above copyright
-//! notice, this list of conditions and the following disclaimer.
-//! * Redistributions in binary form must reproduce the above copyright
-//! notice, this list of conditions and the following disclaimer in the
-//! documentation and/or other materials provided with the distribution.
-//! * Neither the name of the <ORGANIZATION> nor the names of its
-//! contributors may be used to endorse or promote products derived
-//! from this software without specific prior written permission.
-//!
-//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-//! THE POSSIBILITY OF SUCH DAMAGE.
-//
-//*****************************************************************************
-#include <Network2/W5500/Wiznet/Ethernet/socketlib.h>
-
-//#define _SOCKET_DEBUG_
-
-#ifdef _SOCKET_DEBUG_
-extern "C" void debugPrintf(const char *fmt, ...);
-extern "C" void delay(uint32_t);
-# define DEBUG_PRINTF(...) debugPrintf(__VA_ARGS__)
-#else
-# define DEBUG_PRINTF(_fmt, ...)
-#endif
-
-#define SOCK_ANY_PORT_NUM 0xC000
-
-static uint16_t sock_any_port = SOCK_ANY_PORT_NUM;
-static uint16_t sock_io_mode = 0;
-static uint16_t sock_is_sending = 0;
-
-static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,};
-
-uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,};
-
-#define CHECK_SOCKMODE(mode) \
- do{ \
- if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \
- }while(0); \
-
-#define CHECK_SOCKINIT() \
- do{ \
- if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \
- }while(0); \
-
-#define CHECK_SOCKDATA() \
- do{ \
- if(len == 0) return SOCKERR_DATALEN; \
- }while(0); \
-
-void ExecCommand(uint8_t sn, uint8_t cmd)
-{
- setSn_CR(sn, cmd);
- while(getSn_CR(sn) != 0) { }
-}
-
-int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
-{
- switch(protocol)
- {
- case Sn_MR_TCP:
- {
- uint32_t taddr;
- getSIPR((uint8_t*)&taddr);
- if (taddr == 0)
- {
- return SOCKERR_SOCKINIT;
- }
- }
- break;
-
- case Sn_MR_UDP:
- case Sn_MR_MACRAW:
- break;
-
- default:
- return SOCKERR_SOCKMODE;
- }
-
- if ((flag & 0x04) != 0)
- {
- return SOCKERR_SOCKFLAG;
- }
-
- if (flag != 0)
- {
- switch(protocol)
- {
- case Sn_MR_TCP:
- if ((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK)) == 0)
- {
- return SOCKERR_SOCKFLAG;
- }
- break;
- case Sn_MR_UDP:
- if (flag & SF_IGMP_VER2)
- {
- if ((flag & SF_MULTI_ENABLE) == 0)
- {
- return SOCKERR_SOCKFLAG;
- }
- }
- if (flag & SF_UNI_BLOCK)
- {
- if ((flag & SF_MULTI_ENABLE) == 0)
- {
- return SOCKERR_SOCKFLAG;
- }
- }
- break;
- default:
- break;
- }
- }
- close(sn);
- setSn_MR(sn, (protocol | (flag & 0xF0)));
- if (port == 0)
- {
- port = sock_any_port++;
- if (sock_any_port == 0xFFF0)
- {
- sock_any_port = SOCK_ANY_PORT_NUM;
- }
- }
- setSn_PORT(sn,port);
- ExecCommand(sn, Sn_CR_OPEN);
-
- // release the previous sock_io_mode
- sock_io_mode &= ~(1 <<sn);
- sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn);
- sock_is_sending &= ~(1<<sn);
- sock_remained_size[sn] = 0;
- sock_pack_info[sn] = PACK_COMPLETED;
- while(getSn_SR(sn) == SOCK_CLOSED) { }
- return (int8_t)sn;
-}
-
-int8_t close(uint8_t sn)
-{
- ExecCommand(sn, Sn_CR_CLOSE);
-
- // Clear all interrupt of the socket
- setSn_IR(sn, 0xFF);
- // Release the sock_io_mode of socket n.
- sock_io_mode &= ~(1<<sn);
- sock_is_sending &= ~(1<<sn);
- sock_remained_size[sn] = 0;
- sock_pack_info[sn] = 0;
- while(getSn_SR(sn) != SOCK_CLOSED) { }
- return SOCK_OK;
-}
-
-int8_t listen(uint8_t sn)
-{
- CHECK_SOCKMODE(Sn_MR_TCP);
- CHECK_SOCKINIT();
- ExecCommand(sn, Sn_CR_LISTEN);
- while(getSn_SR(sn) != SOCK_LISTEN)
- {
- close(sn);
- return SOCKERR_SOCKCLOSED;
- }
- return SOCK_OK;
-}
-
-int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port)
-{
- CHECK_SOCKMODE(Sn_MR_TCP);
- CHECK_SOCKINIT();
- {
- uint32_t taddr = ((uint32_t)addr[0] & 0x000000FF);
- taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF);
- taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF);
- taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF);
- if (taddr == 0xFFFFFFFF || taddr == 0)
- {
- return SOCKERR_IPINVALID;
- }
- }
-
- if (port == 0)
- {
- return SOCKERR_PORTZERO;
- }
- setSn_DIPR(sn,addr);
- setSn_DPORT(sn,port);
- ExecCommand(sn, Sn_CR_CONNECT);
- if (sock_io_mode & (1<<sn))
- {
- return SOCK_BUSY;
- }
- while(getSn_SR(sn) != SOCK_ESTABLISHED)
- {
- if (getSn_IR(sn) & Sn_IR_TIMEOUT)
- {
- setSn_IR(sn, Sn_IR_TIMEOUT);
- return SOCKERR_TIMEOUT;
- }
-
- if (getSn_SR(sn) == SOCK_CLOSED)
- {
- return SOCKERR_SOCKCLOSED;
- }
- }
-
- return SOCK_OK;
-}
-
-int8_t disconnect(uint8_t sn)
-{
- CHECK_SOCKMODE(Sn_MR_TCP);
- ExecCommand(sn, Sn_CR_DISCON);
-
- sock_is_sending &= ~(1<<sn);
- if (sock_io_mode & (1<<sn))
- {
- return SOCK_BUSY;
- }
- while(getSn_SR(sn) != SOCK_CLOSED)
- {
- if (getSn_IR(sn) & Sn_IR_TIMEOUT)
- {
- close(sn);
- return SOCKERR_TIMEOUT;
- }
- }
- return SOCK_OK;
-}
-
-void disconnectNoWait(uint8_t sn)
-{
- ExecCommand(sn, Sn_CR_DISCON);
-}
-
-int32_t send(uint8_t sn, uint8_t * buf, uint16_t len)
-{
- CHECK_SOCKMODE(Sn_MR_TCP);
- CHECK_SOCKDATA();
- uint8_t tmp = getSn_SR(sn);
- if (tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT)
- {
- return SOCKERR_SOCKSTATUS;
- }
- if ( sock_is_sending & (1<<sn) )
- {
- tmp = getSn_IR(sn);
- if (tmp & Sn_IR_SENDOK)
- {
- setSn_IR(sn, Sn_IR_SENDOK);
- sock_is_sending &= ~(1<<sn);
- }
- else if(tmp & Sn_IR_TIMEOUT)
- {
- close(sn);
- return SOCKERR_TIMEOUT;
- }
- else
- {
- return SOCK_BUSY;
- }
- }
- uint16_t freesize = getSn_TxMAX(sn);
- if (len > freesize)
- {
- len = freesize; // check size not to exceed MAX size.
- }
- while(1)
- {
- freesize = getSn_TX_FSR(sn);
- tmp = getSn_SR(sn);
- if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT))
- {
- close(sn);
- return SOCKERR_SOCKSTATUS;
- }
- if ( (sock_io_mode & (1<<sn)) && (len > freesize) )
- {
- return SOCK_BUSY;
- }
- if (len <= freesize)
- {
- break;
- }
- DEBUG_PRINTF("Socket %u need %u free %u\n", sn, len, freesize);
- }
- wiz_send_data(sn, buf, len);
-
- ExecCommand(sn, Sn_CR_SEND);
- sock_is_sending |= (1 << sn);
- return (int32_t)len;
-}
-
-
-int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len)
-{
- CHECK_SOCKMODE(Sn_MR_TCP);
- CHECK_SOCKDATA();
-
- uint16_t recvsize = getSn_RxMAX(sn);
- if (recvsize < len)
- {
- len = recvsize;
- }
-
- while(1)
- {
- recvsize = getSn_RX_RSR(sn);
- const uint8_t tmp = getSn_SR(sn);
- if (tmp != SOCK_ESTABLISHED)
- {
- if (tmp == SOCK_CLOSE_WAIT)
- {
- if (recvsize != 0)
- {
- break;
- }
- else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn))
- {
- close(sn);
- return SOCKERR_SOCKSTATUS;
- }
- }
- else
- {
- close(sn);
- return SOCKERR_SOCKSTATUS;
- }
- }
- if ((sock_io_mode & (1<<sn)) && (recvsize == 0))
- {
- return SOCK_BUSY;
- }
- if (recvsize != 0)
- {
- break;
- }
- };
-
- if (recvsize < len)
- {
- len = recvsize;
- }
- wiz_recv_data(sn, buf, len);
- ExecCommand(sn, Sn_CR_RECV);
-
- return (int32_t)len;
-}
-
-int32_t sendto(uint8_t sn, const uint8_t * buf, uint16_t len, const uint8_t * addr, uint16_t port)
-{
- switch(getSn_MR(sn) & 0x0F)
- {
- case Sn_MR_UDP:
- case Sn_MR_MACRAW:
- break;
- default:
- return SOCKERR_SOCKMODE;
- }
-
- CHECK_SOCKDATA();
- uint32_t taddr = ((uint32_t)addr[0]) & 0x000000FF;
- taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF);
- taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF);
- taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF);
- if (taddr == 0)
- {
- return SOCKERR_IPINVALID;
- }
- if (port == 0)
- {
- return SOCKERR_PORTZERO;
- }
- const uint8_t tmp = getSn_SR(sn);
- if (tmp != SOCK_MACRAW && tmp != SOCK_UDP)
- {
- return SOCKERR_SOCKSTATUS;
- }
-
- setSn_DIPR(sn,addr);
- setSn_DPORT(sn,port);
- uint16_t freesize = getSn_TxMAX(sn);
- if (len > freesize)
- {
- len = freesize; // check size not to exceed MAX size.
- }
-
- while(1)
- {
- freesize = getSn_TX_FSR(sn);
- if (getSn_SR(sn) == SOCK_CLOSED)
- {
- return SOCKERR_SOCKCLOSED;
- }
- if ( (sock_io_mode & (1<<sn)) && (len > freesize) )
- {
- return SOCK_BUSY;
- }
- if (len <= freesize)
- {
- break;
- }
- DEBUG_PRINTF("Socket %u need %u free %u\n", sn, len, freesize);
- };
-
- wiz_send_data(sn, buf, len);
- ExecCommand(sn, Sn_CR_SEND);
-
- while(1)
- {
- const uint8_t tmp = getSn_IR(sn);
- if (tmp & Sn_IR_SENDOK)
- {
- setSn_IR(sn, Sn_IR_SENDOK);
- break;
- }
- else if(tmp & Sn_IR_TIMEOUT)
- {
- setSn_IR(sn, Sn_IR_TIMEOUT);
- return SOCKERR_TIMEOUT;
- }
- DEBUG_PRINTF("Socket %u waiting for send to complete, IR=%02x\n", sn, tmp);
-#ifdef _SOCKET_DEBUG_
- delay(10); // to avoid too many messages
-#endif
- }
- return (int32_t)len;
-}
-
-
-int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port)
-{
- const uint8_t mr = getSn_MR(sn);
- switch(mr & 0x0F)
- {
- case Sn_MR_UDP:
- case Sn_MR_MACRAW:
- break;
- default:
- return SOCKERR_SOCKMODE;
- }
-
- CHECK_SOCKDATA();
- uint16_t pack_len=0;
- if (sock_remained_size[sn] == 0)
- {
- while(1)
- {
- pack_len = getSn_RX_RSR(sn);
- if (getSn_SR(sn) == SOCK_CLOSED)
- {
- return SOCKERR_SOCKCLOSED;
- }
- if ( (sock_io_mode & (1<<sn)) && (pack_len == 0) )
- {
- return SOCK_BUSY;
- }
- if (pack_len != 0)
- {
- break;
- }
- }
- }
-
- switch (mr & 0x07)
- {
- case Sn_MR_UDP :
- if (sock_remained_size[sn] == 0)
- {
- uint8_t head[8];
- wiz_recv_data(sn, head, 8);
- ExecCommand(sn, Sn_CR_RECV);
-
- // Read peer's IP address, port number & packet length
- addr[0] = head[0];
- addr[1] = head[1];
- addr[2] = head[2];
- addr[3] = head[3];
- *port = head[4];
- *port = (*port << 8) + head[5];
- sock_remained_size[sn] = head[6];
- sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7];
- sock_pack_info[sn] = PACK_FIRST;
- }
- if (len < sock_remained_size[sn])
- {
- pack_len = len;
- }
- else
- {
- pack_len = sock_remained_size[sn];
- }
- len = pack_len;
- //
- // Need to packet length check (default 1472)
- //
- wiz_recv_data(sn, buf, pack_len); // data copy.
- break;
-
- case Sn_MR_MACRAW :
- if (sock_remained_size[sn] == 0)
- {
- uint8_t head[8];
- wiz_recv_data(sn, head, 2);
- ExecCommand(sn, Sn_CR_RECV);
-
- // Read peer's IP address, port number & packet length
- sock_remained_size[sn] = head[0];
- sock_remained_size[sn] = (sock_remained_size[sn] <<8) + head[1];
- if (sock_remained_size[sn] > 1514)
- {
- close(sn);
- return SOCKFATAL_PACKLEN;
- }
- sock_pack_info[sn] = PACK_FIRST;
- }
- if (len < sock_remained_size[sn])
- {
- pack_len = len;
- }
- else
- {
- pack_len = sock_remained_size[sn];
- }
- wiz_recv_data(sn,buf,pack_len);
- break;
-
- default:
- wiz_recv_ignore(sn, pack_len); // data copy.
- sock_remained_size[sn] = pack_len;
- break;
- }
- ExecCommand(sn, Sn_CR_RECV);
-
- sock_remained_size[sn] -= pack_len;
- if (sock_remained_size[sn] != 0)
- {
- sock_pack_info[sn] |= PACK_REMAINED;
- }
- else
- {
- sock_pack_info[sn] = PACK_COMPLETED;
- }
- return (int32_t)pack_len;
-}
-
-
-int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg)
-{
- switch(cstype)
- {
- case CS_SET_IOMODE:
- {
- const uint8_t tmp = *((uint8_t*)arg);
- if (tmp == SOCK_IO_NONBLOCK)
- {
- sock_io_mode |= (1<<sn);
- }
- else if (tmp == SOCK_IO_BLOCK)
- {
- sock_io_mode &= ~(1<<sn);
- }
- else
- {
- return SOCKERR_ARG;
- }
- }
- break;
- case CS_GET_IOMODE:
- *((uint8_t*)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001);
- break;
- case CS_GET_MAXTXBUF:
- *((uint16_t*)arg) = getSn_TxMAX(sn);
- break;
- case CS_GET_MAXRXBUF:
- *((uint16_t*)arg) = getSn_RxMAX(sn);
- break;
- case CS_CLR_INTERRUPT:
- if ((*(uint8_t*)arg) > SIK_ALL)
- {
- return SOCKERR_ARG;
- }
- setSn_IR(sn, *(uint8_t*)arg);
- break;
- case CS_GET_INTERRUPT:
- *((uint8_t*)arg) = getSn_IR(sn);
- break;
- case CS_SET_INTMASK:
- if ((*(uint8_t*)arg) > SIK_ALL)
- {
- return SOCKERR_ARG;
- }
- setSn_IMR(sn, *(uint8_t*)arg);
- break;
- case CS_GET_INTMASK:
- *((uint8_t*)arg) = getSn_IMR(sn);
- break;
- default:
- return SOCKERR_ARG;
- }
- return SOCK_OK;
-}
-
-int8_t setsockopt(uint8_t sn, sockopt_type sotype, void* arg)
-{
- switch(sotype)
- {
- case SO_TTL:
- setSn_TTL(sn,*(uint8_t*)arg);
- break;
- case SO_TOS:
- setSn_TOS(sn,*(uint8_t*)arg);
- break;
- case SO_MSS:
- setSn_MSSR(sn,*(uint16_t*)arg);
- break;
- case SO_DESTIP:
- setSn_DIPR(sn, (uint8_t*)arg);
- break;
- case SO_DESTPORT:
- setSn_DPORT(sn, *(uint16_t*)arg);
- break;
- case SO_KEEPALIVESEND:
- CHECK_SOCKMODE(Sn_MR_TCP);
- if (getSn_KPALVTR(sn) != 0)
- {
- return SOCKERR_SOCKOPT;
- }
- setSn_CR(sn, Sn_CR_SEND_KEEP);
- while(getSn_CR(sn) != 0)
- {
- if (getSn_IR(sn) & Sn_IR_TIMEOUT)
- {
- setSn_IR(sn, Sn_IR_TIMEOUT);
- return SOCKERR_TIMEOUT;
- }
- }
- break;
- case SO_KEEPALIVEAUTO:
- CHECK_SOCKMODE(Sn_MR_TCP);
- setSn_KPALVTR(sn,*(uint8_t*)arg);
- break;
- default:
- return SOCKERR_ARG;
- }
- return SOCK_OK;
-}
-
-int8_t getsockopt(uint8_t sn, sockopt_type sotype, void* arg)
-{
- switch(sotype)
- {
- case SO_FLAG:
- *(uint8_t*)arg = getSn_MR(sn) & 0xF0;
- break;
- case SO_TTL:
- *(uint8_t*) arg = getSn_TTL(sn);
- break;
- case SO_TOS:
- *(uint8_t*) arg = getSn_TOS(sn);
- break;
- case SO_MSS:
- *(uint8_t*) arg = getSn_MSSR(sn);
- break;
- case SO_DESTIP:
- getSn_DIPR(sn, (uint8_t*)arg);
- break;
- case SO_DESTPORT:
- *(uint16_t*) arg = getSn_DPORT(sn);
- break;
- case SO_KEEPALIVEAUTO:
- CHECK_SOCKMODE(Sn_MR_TCP);
- *(uint16_t*) arg = getSn_KPALVTR(sn);
- break;
- case SO_SENDBUF:
- *(uint16_t*) arg = getSn_TX_FSR(sn);
- break;
- case SO_RECVBUF:
- *(uint16_t*) arg = getSn_RX_RSR(sn);
- break;
- case SO_STATUS:
- *(uint8_t*) arg = getSn_SR(sn);
- break;
- case SO_REMAINSIZE:
- if (getSn_MR(sn) == Sn_MR_TCP)
- {
- *(uint16_t*)arg = getSn_RX_RSR(sn);
- }
- else
- {
- *(uint16_t*)arg = sock_remained_size[sn];
- }
- break;
- case SO_PACKINFO:
- CHECK_SOCKMODE(Sn_MR_TCP);
- *(uint8_t*)arg = sock_pack_info[sn];
- break;
- default:
- return SOCKERR_SOCKOPT;
- }
- return SOCK_OK;
-}
-
-// End
diff --git a/src/Network2/W5500/Wiznet/Ethernet/socketlib.h b/src/Network2/W5500/Wiznet/Ethernet/socketlib.h
deleted file mode 100644
index 623b768c..00000000
--- a/src/Network2/W5500/Wiznet/Ethernet/socketlib.h
+++ /dev/null
@@ -1,487 +0,0 @@
-//*****************************************************************************
-//
-//! \file socket.h
-//! \brief SOCKET APIs Header file.
-//! \details SOCKET APIs like as berkeley socket api.
-//! \version 1.0.2
-//! \date 2013/10/21
-//! \par Revision history
-//! <2015/02/05> Notice
-//! The version history is not updated after this point.
-//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
-//! >> https://github.com/Wiznet/ioLibrary_Driver
-//! <2014/05/01> V1.0.2. Refer to M20140501
-//! 1. Modify the comment : SO_REMAINED -> PACK_REMAINED
-//! 2. Add the comment as zero byte udp data reception in getsockopt().
-//! <2013/10/21> 1st Release
-//! \author MidnightCow
-//! \copyright
-//!
-//! Copyright (c) 2013, WIZnet Co., LTD.
-//! All rights reserved.
-//!
-//! Redistribution and use in source and binary forms, with or without
-//! modification, are permitted provided that the following conditions
-//! are met:
-//!
-//! * Redistributions of source code must retain the above copyright
-//! notice, this list of conditions and the following disclaimer.
-//! * Redistributions in binary form must reproduce the above copyright
-//! notice, this list of conditions and the following disclaimer in the
-//! documentation and/or other materials provided with the distribution.
-//! * Neither the name of the <ORGANIZATION> nor the names of its
-//! contributors may be used to endorse or promote products derived
-//! from this software without specific prior written permission.
-//!
-//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-//! THE POSSIBILITY OF SUCH DAMAGE.
-//
-//*****************************************************************************
-/**
- * @defgroup WIZnet_socket_APIs 1. WIZnet socket APIs
- * @brief WIZnet socket APIs are based on Berkeley socket APIs, thus it has much similar name and interface.
- * But there is a little bit of difference.
- * @details
- * <b> Comparison between WIZnet and Berkeley SOCKET APIs </b>
- * <table>
- * <tr> <td><b>API</b></td> <td><b>WIZnet</b></td> <td><b>Berkeley</b></td> </tr>
- * <tr> <td>socket()</td> <td>O</td> <td>O</td> </tr>
- * <tr> <td><b>bind()</b></td> <td>X</td> <td>O</td> </tr>
- * <tr> <td><b>listen()</b></td> <td>O</td> <td>O</td> </tr>
- * <tr> <td><b>connect()</b></td> <td>O</td> <td>O</td> </tr>
- * <tr> <td><b>accept()</b></td> <td>X</td> <td>O</td> </tr>
- * <tr> <td><b>recv()</b></td> <td>O</td> <td>O</td> </tr>
- * <tr> <td><b>send()</b></td> <td>O</td> <td>O</td> </tr>
- * <tr> <td><b>recvfrom()</b></td> <td>O</td> <td>O</td> </tr>
- * <tr> <td><b>sendto()</b></td> <td>O</td> <td>O</td> </tr>
- * <tr> <td><b>closesocket()</b></td> <td>O<br>close() & disconnect()</td> <td>O</td> </tr>
- * </table>
- * There are @b bind() and @b accept() functions in @b Berkeley SOCKET API but,
- * not in @b WIZnet SOCKET API. Because socket() of WIZnet is not only creating a SOCKET but also binding a local port number,
- * and listen() of WIZnet is not only listening to connection request from client but also accepting the connection request. \n
- * When you program "TCP SERVER" with Berkeley SOCKET API, you can use only one listen port.
- * When the listen SOCKET accepts a connection request from a client, it keeps listening.
- * After accepting the connection request, a new SOCKET is created and the new SOCKET is used in communication with the client. \n
- * Following figure shows network flow diagram by Berkeley SOCKET API.
- * @image html Berkeley_SOCKET.jpg "<Berkeley SOCKET API>"
- * But, When you program "TCP SERVER" with WIZnet SOCKET API, you can use as many as 8 listen SOCKET with same port number. \n
- * Because there's no accept() in WIZnet SOCKET APIs, when the listen SOCKET accepts a connection request from a client,
- * it is changed in order to communicate with the client.
- * And the changed SOCKET is not listening any more and is dedicated for communicating with the client. \n
- * If there're many listen SOCKET with same listen port number and a client requests a connection,
- * the SOCKET which has the smallest SOCKET number accepts the request and is changed as communication SOCKET. \n
- * Following figure shows network flow diagram by WIZnet SOCKET API.
- * @image html WIZnet_SOCKET.jpg "<WIZnet SOCKET API>"
- */
-#ifndef _SOCKET_H_
-#define _SOCKET_H_
-
-#include <Network2/W5500/Wiznet/Ethernet/wizchip_conf.h>
-
-#define SOCKET uint8_t ///< SOCKET type define for legacy driver
-
-#define SOCK_OK 1 ///< Result is OK about socket process.
-#define SOCK_BUSY 0 ///< Socket is busy on processing the operation. Valid only Non-block IO Mode.
-#define SOCK_FATAL -1000 ///< Result is fatal error about socket process.
-
-#define SOCK_ERROR 0
-#define SOCKERR_SOCKNUM (SOCK_ERROR - 1) ///< Invalid socket number
-#define SOCKERR_SOCKOPT (SOCK_ERROR - 2) ///< Invalid socket option
-#define SOCKERR_SOCKINIT (SOCK_ERROR - 3) ///< Socket is not initialized or SIPR is Zero IP address when Sn_MR_TCP
-#define SOCKERR_SOCKCLOSED (SOCK_ERROR - 4) ///< Socket unexpectedly closed.
-#define SOCKERR_SOCKMODE (SOCK_ERROR - 5) ///< Invalid socket mode for socket operation.
-#define SOCKERR_SOCKFLAG (SOCK_ERROR - 6) ///< Invalid socket flag
-#define SOCKERR_SOCKSTATUS (SOCK_ERROR - 7) ///< Invalid socket status for socket operation.
-#define SOCKERR_ARG (SOCK_ERROR - 10) ///< Invalid argument.
-#define SOCKERR_PORTZERO (SOCK_ERROR - 11) ///< Port number is zero
-#define SOCKERR_IPINVALID (SOCK_ERROR - 12) ///< Invalid IP address
-#define SOCKERR_TIMEOUT (SOCK_ERROR - 13) ///< Timeout occurred
-#define SOCKERR_DATALEN (SOCK_ERROR - 14) ///< Data length is zero or greater than buffer max size.
-#define SOCKERR_BUFFER (SOCK_ERROR - 15) ///< Socket buffer is not enough for data communication.
-
-#define SOCKFATAL_PACKLEN (SOCK_FATAL - 1) ///< Invalid packet length. Fatal Error.
-
-/*
- * SOCKET FLAG
- */
-#define SF_ETHER_OWN (Sn_MR_MFEN) ///< In @ref Sn_MR_MACRAW, Receive only the packet as broadcast, multicast and own packet
-#define SF_IGMP_VER2 (Sn_MR_MC) ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE, Select IGMP version 2.
-#define SF_TCP_NODELAY (Sn_MR_ND) ///< In @ref Sn_MR_TCP, Use to nodelayed ack.
-#define SF_MULTI_ENABLE (Sn_MR_MULTI) ///< In @ref Sn_MR_UDP, Enable multicast mode.
-
-#if _WIZCHIP_ == 5500
- #define SF_BROAD_BLOCK (Sn_MR_BCASTB) ///< In @ref Sn_MR_UDP or @ref Sn_MR_MACRAW, Block broadcast packet. Valid only in W5500
- #define SF_MULTI_BLOCK (Sn_MR_MMB) ///< In @ref Sn_MR_MACRAW, Block multicast packet. Valid only in W5500
- #define SF_IPv6_BLOCK (Sn_MR_MIP6B) ///< In @ref Sn_MR_MACRAW, Block IPv6 packet. Valid only in W5500
- #define SF_UNI_BLOCK (Sn_MR_UCASTB) ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE. Valid only in W5500
-#endif
-
-//A201505 : For W5300
-#if _WIZCHIP_ == 5300
- #define SF_TCP_ALIGN 0x02 ///< Valid only \ref Sn_MR_TCP and W5300, refer to \ref Sn_MR_ALIGN
-#endif
-
-#define SF_IO_NONBLOCK 0x01 ///< Socket nonblock io mode. It used parameter in \ref socket().
-
-/*
- * UDP & MACRAW Packet Infomation
- */
-#define PACK_FIRST 0x80 ///< In Non-TCP packet, It indicates to start receiving a packet. (When W5300, This flag can be applied)
-#define PACK_REMAINED 0x01 ///< In Non-TCP packet, It indicates to remain a packet to be received. (When W5300, This flag can be applied)
-#define PACK_COMPLETED 0x00 ///< In Non-TCP packet, It indicates to complete to receive a packet. (When W5300, This flag can be applied)
-//A20150601 : For Integrating with W5300
-#define PACK_FIFOBYTE 0x02 ///< Valid only W5300, It indicate to have read already the Sn_RX_FIFOR.
-//
-
-/**
- * @ingroup WIZnet_socket_APIs
- * @brief Open a socket.
- * @details Initializes the socket with 'sn' passed as parameter and open.
- *
- * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
- * @param protocol Protocol type to operate such as TCP, UDP and MACRAW.
- * @param port Port number to be bined.
- * @param flag Socket flags as \ref SF_ETHER_OWN, \ref SF_IGMP_VER2, \ref SF_TCP_NODELAY, \ref SF_MULTI_ENABLE, \ref SF_IO_NONBLOCK and so on.\n
- * Valid flags only in W5500 : @ref SF_BROAD_BLOCK, @ref SF_MULTI_BLOCK, @ref SF_IPv6_BLOCK, and @ref SF_UNI_BLOCK.
- * @sa Sn_MR
- *
- * @return @b Success : The socket number @b 'sn' passed as parameter\n
- * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n
- * @ref SOCKERR_SOCKMODE - Not support socket mode as TCP, UDP, and so on. \n
- * @ref SOCKERR_SOCKFLAG - Invaild socket flag.
- */
-int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag);
-
-/**
- * @ingroup WIZnet_socket_APIs
- * @brief Close a socket.
- * @details It closes the socket with @b'sn' passed as parameter.
- *
- * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
- *
- * @return @b Success : @ref SOCK_OK \n
- * @b Fail : @ref SOCKERR_SOCKNUM - Invalid socket number
- */
-int8_t close(uint8_t sn);
-
-/**
- * @ingroup WIZnet_socket_APIs
- * @brief Listen to a connection request from a client.
- * @details It is listening to a connection request from a client.
- * If connection request is accepted successfully, the connection is established. Socket sn is used in passive(server) mode.
- *
- * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
- * @return @b Success : @ref SOCK_OK \n
- * @b Fail :\n @ref SOCKERR_SOCKINIT - Socket is not initialized \n
- * @ref SOCKERR_SOCKCLOSED - Socket closed unexpectedly.
- */
-int8_t listen(uint8_t sn);
-
-/**
- * @ingroup WIZnet_socket_APIs
- * @brief Try to connect a server.
- * @details It requests connection to the server with destination IP address and port number passed as parameter.\n
- * @note It is valid only in TCP client mode.
- * In block io mode, it does not return until connection is completed.
- * In Non-block io mode, it return @ref SOCK_BUSY immediately.
- *
- * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
- * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes.
- * @param port Destination port number.
- *
- * @return @b Success : @ref SOCK_OK \n
- * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n
- * @ref SOCKERR_SOCKMODE - Invalid socket mode\n
- * @ref SOCKERR_SOCKINIT - Socket is not initialized\n
- * @ref SOCKERR_IPINVALID - Wrong server IP address\n
- * @ref SOCKERR_PORTZERO - Server port zero\n
- * @ref SOCKERR_TIMEOUT - Timeout occurred during request connection\n
- * @ref SOCK_BUSY - In non-block io mode, it returned immediately\n
- */
-int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port);
-
-/**
- * @ingroup WIZnet_socket_APIs
- * @brief Try to disconnect a connection socket.
- * @details It sends request message to disconnect the TCP socket 'sn' passed as parameter to the server or client.
- * @note It is valid only in TCP server or client mode. \n
- * In block io mode, it does not return until disconnection is completed. \n
- * In Non-block io mode, it return @ref SOCK_BUSY immediately. \n
-
- * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
- * @return @b Success : @ref SOCK_OK \n
- * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n
- * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
- * @ref SOCKERR_TIMEOUT - Timeout occurred \n
- * @ref SOCK_BUSY - Socket is busy.
- */
-int8_t disconnect(uint8_t sn);
-
-void disconnectNoWait(uint8_t sn);
-
-/**
- * @ingroup WIZnet_socket_APIs
- * @brief Send data to the connected peer in TCP socket.
- * @details It is used to send outgoing data to the connected socket.
- * @note It is valid only in TCP server or client mode. It can't send data greater than socket buffer size. \n
- * In block io mode, It doesn't return until data send is completed - socket buffer size is greater than data. \n
- * In non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is not enough. \n
- * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
- * @param buf Pointer buffer containing data to be sent.
- * @param len The byte length of data in buf.
- * @return @b Success : The sent data size \n
- * @b Fail : \n @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n
- * @ref SOCKERR_TIMEOUT - Timeout occurred \n
- * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
- * @ref SOCKERR_SOCKNUM - Invalid socket number \n
- * @ref SOCKERR_DATALEN - zero data length \n
- * @ref SOCK_BUSY - Socket is busy.
- */
-int32_t send(uint8_t sn, uint8_t * buf, uint16_t len);
-
-/**
- * @ingroup WIZnet_socket_APIs
- * @brief Receive data from the connected peer.
- * @details It is used to read incoming data from the connected socket.\n
- * It waits for data as much as the application wants to receive.
- * @note It is valid only in TCP server or client mode. It can't receive data greater than socket buffer size. \n
- * In block io mode, it doesn't return until data reception is completed - data is filled as <I>len</I> in socket buffer. \n
- * In non-block io mode, it return @ref SOCK_BUSY immediately when <I>len</I> is greater than data size in socket buffer. \n
- *
- * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
- * @param buf Pointer buffer to read incoming data.
- * @param len The max data length of data in buf.
- * @return @b Success : The real received data size \n
- * @b Fail :\n
- * @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n
- * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
- * @ref SOCKERR_SOCKNUM - Invalid socket number \n
- * @ref SOCKERR_DATALEN - zero data length \n
- * @ref SOCK_BUSY - Socket is busy.
- */
-int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len);
-
-/**
- * @ingroup WIZnet_socket_APIs
- * @brief Sends datagram to the peer with destination IP address and port number passed as parameter.
- * @details It sends datagram of UDP or MACRAW to the peer with destination IP address and port number passed as parameter.\n
- * Even if the connectionless socket has been previously connected to a specific address,
- * the address and port number parameters override the destination address for that particular datagram only.
- * @note In block io mode, It doesn't return until data send is completed - socket buffer size is greater than <I>len</I>.
- * In non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is not enough.
- *
- * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
- * @param buf Pointer buffer to send outgoing data.
- * @param len The byte length of data in buf.
- * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes.
- * @param port Destination port number.
- *
- * @return @b Success : The sent data size \n
- * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n
- * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
- * @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n
- * @ref SOCKERR_DATALEN - zero data length \n
- * @ref SOCKERR_IPINVALID - Wrong server IP address\n
- * @ref SOCKERR_PORTZERO - Server port zero\n
- * @ref SOCKERR_SOCKCLOSED - Socket unexpectedly closed \n
- * @ref SOCKERR_TIMEOUT - Timeout occurred \n
- * @ref SOCK_BUSY - Socket is busy.
- */
-int32_t sendto(uint8_t sn, const uint8_t * buf, uint16_t len, const uint8_t * addr, uint16_t port);
-
-/**
- * @ingroup WIZnet_socket_APIs
- * @brief Receive datagram of UDP or MACRAW
- * @details This function is an application I/F function which is used to receive the data in other then TCP mode. \n
- * This function is used to receive UDP and MAC_RAW mode, and handle the header as well.
- * This function can divide to received the packet data.
- * On the MACRAW SOCKET, the addr and port parameters are ignored.
- * @note In block io mode, it doesn't return until data reception is completed - data is filled as <I>len</I> in socket buffer
- * In non-block io mode, it return @ref SOCK_BUSY immediately when <I>len</I> is greater than data size in socket buffer.
- *
- * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
- * @param buf Pointer buffer to read incoming data.
- * @param len The max data length of data in buf.
- * When the received packet size <= len, receives data as packet sized.
- * When others, receives data as len.
- * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes.
- * It is valid only when the first call recvfrom for receiving the packet.
- * When it is valid, @ref packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo).
- * @param port Pointer variable of destination port number.
- * It is valid only when the first call recvform for receiving the packet.
-* When it is valid, @ref packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo).
- *
- * @return @b Success : This function return real received data size for success.\n
- * @b Fail : @ref SOCKERR_DATALEN - zero data length \n
- * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
- * @ref SOCKERR_SOCKNUM - Invalid socket number \n
- * @ref SOCKBUSY - Socket is busy.
- */
-int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port);
-
-
-/////////////////////////////
-// SOCKET CONTROL & OPTION //
-/////////////////////////////
-#define SOCK_IO_BLOCK 0 ///< Socket Block IO Mode in @ref setsockopt().
-#define SOCK_IO_NONBLOCK 1 ///< Socket Non-block IO Mode in @ref setsockopt().
-
-/**
- * @defgroup DATA_TYPE DATA TYPE
- */
-
-/**
- * @ingroup DATA_TYPE
- * @brief The kind of Socket Interrupt.
- * @sa Sn_IR, Sn_IMR, setSn_IR(), getSn_IR(), setSn_IMR(), getSn_IMR()
- */
-typedef enum
-{
- SIK_CONNECTED = (1 << 0), ///< connected
- SIK_DISCONNECTED = (1 << 1), ///< disconnected
- SIK_RECEIVED = (1 << 2), ///< data received
- SIK_TIMEOUT = (1 << 3), ///< timeout occurred
- SIK_SENT = (1 << 4), ///< send ok
- //M20150410 : Remove the comma of last member
- //SIK_ALL = 0x1F, ///< all interrupt
- SIK_ALL = 0x1F ///< all interrupt
-}sockint_kind;
-
-/**
- * @ingroup DATA_TYPE
- * @brief The type of @ref ctlsocket().
- */
-typedef enum
-{
- CS_SET_IOMODE, ///< set socket IO mode with @ref SOCK_IO_BLOCK or @ref SOCK_IO_NONBLOCK
- CS_GET_IOMODE, ///< get socket IO mode
- CS_GET_MAXTXBUF, ///< get the size of socket buffer allocated in TX memory
- CS_GET_MAXRXBUF, ///< get the size of socket buffer allocated in RX memory
- CS_CLR_INTERRUPT, ///< clear the interrupt of socket with @ref sockint_kind
- CS_GET_INTERRUPT, ///< get the socket interrupt. refer to @ref sockint_kind
-#if _WIZCHIP_ > 5100
- CS_SET_INTMASK, ///< set the interrupt mask of socket with @ref sockint_kind, Not supported in W5100
- CS_GET_INTMASK ///< get the masked interrupt of socket. refer to @ref sockint_kind, Not supported in W5100
-#endif
-}ctlsock_type;
-
-
-/**
- * @ingroup DATA_TYPE
- * @brief The type of socket option in @ref setsockopt() or @ref getsockopt()
- */
-typedef enum
-{
- SO_FLAG, ///< Valid only in getsockopt(), For set flag of socket refer to <I>flag</I> in @ref socket().
- SO_TTL, ///< Set TTL. @ref Sn_TTL ( @ref setSn_TTL(), @ref getSn_TTL() )
- SO_TOS, ///< Set TOS. @ref Sn_TOS ( @ref setSn_TOS(), @ref getSn_TOS() )
- SO_MSS, ///< Set MSS. @ref Sn_MSSR ( @ref setSn_MSSR(), @ref getSn_MSSR() )
- SO_DESTIP, ///< Set the destination IP address. @ref Sn_DIPR ( @ref setSn_DIPR(), @ref getSn_DIPR() )
- SO_DESTPORT, ///< Set the destination Port number. @ref Sn_DPORT ( @ref setSn_DPORT(), @ref getSn_DPORT() )
-#if _WIZCHIP_ != 5100
- SO_KEEPALIVESEND, ///< Valid only in setsockopt. Manually send keep-alive packet in TCP mode, Not supported in W5100
- #if _WIZCHIP_ > 5200
- SO_KEEPALIVEAUTO, ///< Set/Get keep-alive auto transmission timer in TCP mode, Not supported in W5100, W5200
- #endif
-#endif
- SO_SENDBUF, ///< Valid only in getsockopt. Get the free data size of Socekt TX buffer. @ref Sn_TX_FSR, @ref getSn_TX_FSR()
- SO_RECVBUF, ///< Valid only in getsockopt. Get the received data size in socket RX buffer. @ref Sn_RX_RSR, @ref getSn_RX_RSR()
- SO_STATUS, ///< Valid only in getsockopt. Get the socket status. @ref Sn_SR, @ref getSn_SR()
- SO_REMAINSIZE, ///< Valid only in getsockopt. Get the remained packet size in other then TCP mode.
- SO_PACKINFO ///< Valid only in getsockopt. Get the packet information as @ref PACK_FIRST, @ref PACK_REMAINED, and @ref PACK_COMPLETED in other then TCP mode.
-}sockopt_type;
-
-/**
- * @ingroup WIZnet_socket_APIs
- * @brief Control socket.
- * @details Control IO mode, Interrupt & Mask of socket and get the socket buffer information.
- * Refer to @ref ctlsock_type.
- * @param sn socket number
- * @param cstype type of control socket. refer to @ref ctlsock_type.
- * @param arg Data type and value is determined according to @ref ctlsock_type. \n
- * <table>
- * <tr> <td> @b cstype </td> <td> @b data type</td><td>@b value</td></tr>
- * <tr> <td> @ref CS_SET_IOMODE \n @ref CS_GET_IOMODE </td> <td> uint8_t </td><td>@ref SOCK_IO_BLOCK @ref SOCK_IO_NONBLOCK</td></tr>
- * <tr> <td> @ref CS_GET_MAXTXBUF \n @ref CS_GET_MAXRXBUF </td> <td> uint16_t </td><td> 0 ~ 16K </td></tr>
- * <tr> <td> @ref CS_CLR_INTERRUPT \n @ref CS_GET_INTERRUPT \n @ref CS_SET_INTMASK \n @ref CS_GET_INTMASK </td> <td> @ref sockint_kind </td><td> @ref SIK_CONNECTED, etc. </td></tr>
- * </table>
- * @return @b Success @ref SOCK_OK \n
- * @b fail @ref SOCKERR_ARG - Invalid argument\n
- */
-int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg);
-
-/**
- * @ingroup WIZnet_socket_APIs
- * @brief set socket options
- * @details Set socket option like as TTL, MSS, TOS, and so on. Refer to @ref sockopt_type.
- *
- * @param sn socket number
- * @param sotype socket option type. refer to @ref sockopt_type
- * @param arg Data type and value is determined according to <I>sotype</I>. \n
- * <table>
- * <tr> <td> @b sotype </td> <td> @b data type</td><td>@b value</td></tr>
- * <tr> <td> @ref SO_TTL </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr>
- * <tr> <td> @ref SO_TOS </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr>
- * <tr> <td> @ref SO_MSS </td> <td> uint16_t </td><td> 0 ~ 65535 </td> </tr>
- * <tr> <td> @ref SO_DESTIP </td> <td> uint8_t[4] </td><td> </td></tr>
- * <tr> <td> @ref SO_DESTPORT </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr>
- * <tr> <td> @ref SO_KEEPALIVESEND </td> <td> null </td><td> null </td></tr>
- * <tr> <td> @ref SO_KEEPALIVEAUTO </td> <td> uint8_t </td><td> 0 ~ 255 </td></tr>
- * </table>
- * @return
- * - @b Success : @ref SOCK_OK \n
- * - @b Fail
- * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n
- * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n
- * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n
- * - @ref SOCKERR_TIMEOUT - Timeout occurred when sending keep-alive packet \n
- */
-int8_t setsockopt(uint8_t sn, sockopt_type sotype, void* arg);
-
-/**
- * @ingroup WIZnet_socket_APIs
- * @brief get socket options
- * @details Get socket option like as FLAG, TTL, MSS, and so on. Refer to @ref sockopt_type
- * @param sn socket number
- * @param sotype socket option type. refer to @ref sockopt_type
- * @param arg Data type and value is determined according to <I>sotype</I>. \n
- * <table>
- * <tr> <td> @b sotype </td> <td>@b data type</td><td>@b value</td></tr>
- * <tr> <td> @ref SO_FLAG </td> <td> uint8_t </td><td> @ref SF_ETHER_OWN, etc... </td> </tr>
- * <tr> <td> @ref SO_TOS </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr>
- * <tr> <td> @ref SO_MSS </td> <td> uint16_t </td><td> 0 ~ 65535 </td> </tr>
- * <tr> <td> @ref SO_DESTIP </td> <td> uint8_t[4] </td><td> </td></tr>
- * <tr> <td> @ref SO_DESTPORT </td> <td> uint16_t </td><td> </td></tr>
- * <tr> <td> @ref SO_KEEPALIVEAUTO </td> <td> uint8_t </td><td> 0 ~ 255 </td></tr>
- * <tr> <td> @ref SO_SENDBUF </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr>
- * <tr> <td> @ref SO_RECVBUF </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr>
- * <tr> <td> @ref SO_STATUS </td> <td> uint8_t </td><td> @ref SOCK_ESTABLISHED, etc.. </td></tr>
- * <tr> <td> @ref SO_REMAINSIZE </td> <td> uint16_t </td><td> 0~ 65535 </td></tr>
- * <tr> <td> @ref SO_PACKINFO </td> <td> uint8_t </td><td> @ref PACK_FIRST, etc... </td></tr>
- * </table>
- * @return
- * - @b Success : @ref SOCK_OK \n
- * - @b Fail
- * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n
- * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n
- * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n
- * @note
- * The option as PACK_REMAINED and SO_PACKINFO is valid only in NON-TCP mode and after call @ref recvfrom(). \n
- * When SO_PACKINFO value is PACK_FIRST and the return value of recvfrom() is zero,
- * This means the zero byte UDP data(UDP Header only) received.
- */
-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/Network2/W5500/Wiznet/Ethernet/wizchip_conf.cpp b/src/Network2/W5500/Wiznet/Ethernet/wizchip_conf.cpp
deleted file mode 100644
index 1bf27419..00000000
--- a/src/Network2/W5500/Wiznet/Ethernet/wizchip_conf.cpp
+++ /dev/null
@@ -1,457 +0,0 @@
-//****************************************************************************/
-//!
-//! \file wizchip_conf.c
-//! \brief WIZCHIP Config Header File.
-//! \version 1.0.1
-//! \date 2013/10/21
-//! \par Revision history
-//! <2015/02/05> Notice
-//! The version history is not updated after this point.
-//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
-//! >> https://github.com/Wiznet/ioLibrary_Driver
-//! <2014/05/01> V1.0.1 Refer to M20140501
-//! 1. Explicit type casting in wizchip_bus_readdata() & wizchip_bus_writedata()
-// Issued by Mathias ClauBen.
-//! uint32_t type converts into ptrdiff_t first. And then recoverting it into uint8_t*
-//! For remove the warning when pointer type size is not 32bit.
-//! If ptrdiff_t doesn't support in your complier, You should must replace ptrdiff_t into your suitable pointer type.
-//! <2013/10/21> 1st Release
-//! \author MidnightCow
-//! \copyright
-//!
-//! Copyright (c) 2013, WIZnet Co., LTD.
-//! All rights reserved.
-//!
-//! Redistribution and use in source and binary forms, with or without
-//! modification, are permitted provided that the following conditions
-//! are met:
-//!
-//! * Redistributions of source code must retain the above copyright
-//! notice, this list of conditions and the following disclaimer.
-//! * Redistributions in binary form must reproduce the above copyright
-//! notice, this list of conditions and the following disclaimer in the
-//! documentation and/or other materials provided with the distribution.
-//! * Neither the name of the <ORGANIZATION> nor the names of its
-//! contributors may be used to endorse or promote products derived
-//! from this software without specific prior written permission.
-//!
-//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-//! THE POSSIBILITY OF SUCH DAMAGE.
-//
-//*****************************************************************************/
-//A20140501 : for use the type - ptrdiff_t
-
-#include <Network2/W5500/Wiznet/Ethernet/wizchip_conf.h>
-#include <Network2/W5500/Wiznet/Ethernet/WizSpi.h>
-#include <cstddef>
-#include <cstring>
-
-/**
- * @\ref WIZCHIP instance data
- */
-
-static uint8_t _DNS_[4]; // DNS server ip address
-static dhcp_mode _DHCP_; // DHCP mode
-static const char WizchipId[6] = "w5500";
-
-int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg)
-{
- switch(cwtype)
- {
- case CW_RESET_WIZCHIP:
- wizchip_sw_reset();
- break;
- case CW_INIT_WIZCHIP:
- {
- uint8_t* ptmp[2] = {0,0};
- if (arg != 0)
- {
- ptmp[0] = (uint8_t*)arg;
- ptmp[1] = ptmp[0] + _WIZCHIP_SOCK_NUM_;
- }
- return wizchip_init(ptmp[0], ptmp[1]);
- }
- case CW_CLR_INTERRUPT:
- wizchip_clrinterrupt(*((intr_kind*)arg));
- break;
- case CW_GET_INTERRUPT:
- *((intr_kind*)arg) = wizchip_getinterrupt();
- break;
- case CW_SET_INTRMASK:
- wizchip_setinterruptmask(*((intr_kind*)arg));
- break;
- case CW_GET_INTRMASK:
- *((intr_kind*)arg) = wizchip_getinterruptmask();
- break;
- case CW_SET_INTRTIME:
- setINTLEVEL(*(uint16_t*)arg);
- break;
- case CW_GET_INTRTIME:
- *(uint16_t*)arg = getINTLEVEL();
- break;
- case CW_GET_ID:
- memcpy(arg, WizchipId, sizeof(WizchipId));
- break;
- case CW_RESET_PHY:
- wizphy_reset();
- break;
- case CW_SET_PHYCONF:
- wizphy_setphyconf((wiz_PhyConf*)arg);
- break;
- case CW_GET_PHYCONF:
- wizphy_getphyconf((wiz_PhyConf*)arg);
- break;
- case CW_GET_PHYSTATUS:
- break;
- case CW_SET_PHYPOWMODE:
- return wizphy_setphypmode(*(uint8_t*)arg);
- case CW_GET_PHYPOWMODE:
- {
- uint8_t tmp = wizphy_getphypmode();
- if ((int8_t)tmp == -1)
- {
- return -1;
- }
- *(uint8_t*)arg = tmp;
- }
- break;
- case CW_GET_PHYLINK:
- {
- uint8_t tmp = wizphy_getphylink();
- if ((int8_t)tmp == -1)
- {
- return -1;
- }
- *(uint8_t*)arg = tmp;
- }
- break;
- default:
- return -1;
- }
- return 0;
-}
-
-
-int8_t ctlnetwork(ctlnetwork_type cntype, void* arg)
-{
- switch(cntype)
- {
- case CN_SET_NETINFO:
- wizchip_setnetinfo((wiz_NetInfo*)arg);
- break;
- case CN_GET_NETINFO:
- wizchip_getnetinfo((wiz_NetInfo*)arg);
- break;
- case CN_SET_NETMODE:
- return wizchip_setnetmode(*(netmode_type*)arg);
- case CN_GET_NETMODE:
- *(netmode_type*)arg = wizchip_getnetmode();
- break;
- case CN_SET_TIMEOUT:
- wizchip_settimeout((wiz_NetTimeout*)arg);
- break;
- case CN_GET_TIMEOUT:
- wizchip_gettimeout((wiz_NetTimeout*)arg);
- break;
- default:
- return -1;
- }
- return 0;
-}
-
-void wizchip_sw_reset(void)
-{
- uint8_t gw[4], sn[4], sip[4];
- uint8_t mac[6];
- getSHAR(mac);
- getGAR(gw); getSUBR(sn); getSIPR(sip);
- setMR(MR_RST);
- getMR(); // for delay
- setSHAR(mac);
- setGAR(gw);
- setSUBR(sn);
- setSIPR(sip);
-}
-
-int8_t wizchip_init(const uint8_t* txsize, const uint8_t* rxsize)
-{
- WizSpi::Init();
- wizchip_sw_reset();
- if (txsize != nullptr)
- {
- int8_t tmp = 0;
- for (uint8_t i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
- {
- tmp += txsize[i];
- if (tmp > 16)
- {
- return -1;
- }
- }
- for (uint8_t i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
- {
- setSn_TXBUF_SIZE(i, txsize[i]);
- }
- }
- if (rxsize != nullptr)
- {
- int8_t tmp = 0;
- for (uint8_t i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
- {
- tmp += rxsize[i];
- if (tmp > 16)
- {
- return -1;
- }
- }
-
- for (uint8_t i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
- {
- setSn_RXBUF_SIZE(i, rxsize[i]);
- }
- }
- return 0;
-}
-
-void wizchip_clrinterrupt(intr_kind intr)
-{
- setIR((uint8_t)intr);
- setSIR((uint8_t)((uint16_t)intr >> 8));
-}
-
-intr_kind wizchip_getinterrupt(void)
-{
- const uint8_t ir = getIR();
- const uint8_t sir = getSIR();
- const uint16_t ret = ((uint16_t)sir << 8) | ir;
- return (intr_kind)ret;
-}
-
-void wizchip_setinterruptmask(intr_kind intr)
-{
- setIMR((uint8_t)intr);
- setSIMR((uint8_t)((uint16_t)intr >> 8));
-}
-
-intr_kind wizchip_getinterruptmask(void)
-{
- const uint8_t imr = getIMR();
- const uint8_t simr = getSIMR();
- const uint16_t ret = ((uint16_t)simr << 8) | imr;
- return (intr_kind)ret;
-}
-
-int8_t wizphy_getphylink(void)
-{
- return (getPHYCFGR() & PHYCFGR_LNK_ON) ? PHY_LINK_ON : PHY_LINK_OFF;
-}
-
-int8_t wizphy_getphypmode(void)
-{
- return (getPHYCFGR() & PHYCFGR_OPMDC_PDOWN) ? PHY_POWER_DOWN : PHY_POWER_NORM;
-}
-
-void wizphy_reset(void)
-{
- uint8_t tmp = getPHYCFGR();
- tmp &= PHYCFGR_RST;
- setPHYCFGR(tmp);
- tmp = getPHYCFGR();
- tmp |= ~PHYCFGR_RST;
- setPHYCFGR(tmp);
-}
-
-void wizphy_setphyconf(wiz_PhyConf* phyconf)
-{
- uint8_t tmp = 0;
- if (phyconf->by == PHY_CONFBY_SW)
- {
- tmp |= PHYCFGR_OPMD;
- }
- else
- {
- tmp &= ~PHYCFGR_OPMD;
- }
- if (phyconf->mode == PHY_MODE_AUTONEGO)
- {
- tmp |= PHYCFGR_OPMDC_ALLA;
- }
- else
- {
- if (phyconf->duplex == PHY_DUPLEX_FULL)
- {
- if (phyconf->speed == PHY_SPEED_100)
- {
- tmp |= PHYCFGR_OPMDC_100F;
- }
- else
- {
- tmp |= PHYCFGR_OPMDC_10F;
- }
- }
- else
- {
- if (phyconf->speed == PHY_SPEED_100)
- {
- tmp |= PHYCFGR_OPMDC_100H;
- }
- else
- {
- tmp |= PHYCFGR_OPMDC_10H;
- }
- }
- }
- setPHYCFGR(tmp);
- wizphy_reset();
-}
-
-void wizphy_getphyconf(wiz_PhyConf* phyconf)
-{
- const uint8_t tmp = getPHYCFGR();
- phyconf->by = (tmp & PHYCFGR_OPMD) ? PHY_CONFBY_SW : PHY_CONFBY_HW;
- switch(tmp & PHYCFGR_OPMDC_ALLA)
- {
- case PHYCFGR_OPMDC_ALLA:
- case PHYCFGR_OPMDC_100FA:
- phyconf->mode = PHY_MODE_AUTONEGO;
- break;
- default:
- phyconf->mode = PHY_MODE_MANUAL;
- break;
- }
-
- switch(tmp & PHYCFGR_OPMDC_ALLA)
- {
- case PHYCFGR_OPMDC_100FA:
- case PHYCFGR_OPMDC_100F:
- case PHYCFGR_OPMDC_100H:
- phyconf->speed = PHY_SPEED_100;
- break;
- default:
- phyconf->speed = PHY_SPEED_10;
- break;
- }
-
- switch(tmp & PHYCFGR_OPMDC_ALLA)
- {
- case PHYCFGR_OPMDC_100FA:
- case PHYCFGR_OPMDC_100F:
- case PHYCFGR_OPMDC_10F:
- phyconf->duplex = PHY_DUPLEX_FULL;
- break;
- default:
- phyconf->duplex = PHY_DUPLEX_HALF;
- break;
- }
-}
-
-void wizphy_getphystat(wiz_PhyConf* phyconf)
-{
- const uint8_t tmp = getPHYCFGR();
- phyconf->duplex = (tmp & PHYCFGR_DPX_FULL) ? PHY_DUPLEX_FULL : PHY_DUPLEX_HALF;
- phyconf->speed = (tmp & PHYCFGR_SPD_100) ? PHY_SPEED_100 : PHY_SPEED_10;
-}
-
-int8_t wizphy_setphypmode(uint8_t pmode)
-{
- uint8_t tmp = getPHYCFGR();
- if ((tmp & PHYCFGR_OPMD)== 0)
- {
- return -1;
- }
- tmp &= ~PHYCFGR_OPMDC_ALLA;
- if (pmode == PHY_POWER_DOWN)
- {
- tmp |= PHYCFGR_OPMDC_PDOWN;
- }
- else
- {
- tmp |= PHYCFGR_OPMDC_ALLA;
- }
- setPHYCFGR(tmp);
- wizphy_reset();
-
- tmp = getPHYCFGR();
- if (pmode == PHY_POWER_DOWN)
- {
- if (tmp & PHYCFGR_OPMDC_PDOWN)
- {
- return 0;
- }
- }
- else
- {
- if (tmp & PHYCFGR_OPMDC_ALLA)
- {
- return 0;
- }
- }
- return -1;
-}
-
-
-void wizchip_setnetinfo(wiz_NetInfo* pnetinfo)
-{
- setSHAR(pnetinfo->mac);
- setGAR(pnetinfo->gw);
- setSUBR(pnetinfo->sn);
- setSIPR(pnetinfo->ip);
- _DNS_[0] = pnetinfo->dns[0];
- _DNS_[1] = pnetinfo->dns[1];
- _DNS_[2] = pnetinfo->dns[2];
- _DNS_[3] = pnetinfo->dns[3];
- _DHCP_ = pnetinfo->dhcp;
-}
-
-void wizchip_getnetinfo(wiz_NetInfo* pnetinfo)
-{
- getSHAR(pnetinfo->mac);
- getGAR(pnetinfo->gw);
- getSUBR(pnetinfo->sn);
- getSIPR(pnetinfo->ip);
- pnetinfo->dns[0]= _DNS_[0];
- pnetinfo->dns[1]= _DNS_[1];
- pnetinfo->dns[2]= _DNS_[2];
- pnetinfo->dns[3]= _DNS_[3];
- pnetinfo->dhcp = _DHCP_;
-}
-
-int8_t wizchip_setnetmode(netmode_type netmode)
-{
- if (netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK | NM_FORCEARP))
- {
- return -1;
- }
- uint8_t tmp = getMR();
- tmp |= (uint8_t)netmode;
- setMR(tmp);
- return 0;
-}
-
-netmode_type wizchip_getnetmode(void)
-{
- return (netmode_type) getMR();
-}
-
-void wizchip_settimeout(wiz_NetTimeout* nettime)
-{
- setRCR(nettime->retry_cnt);
- setRTR(nettime->time_100us);
-}
-
-void wizchip_gettimeout(wiz_NetTimeout* nettime)
-{
- nettime->retry_cnt = getRCR();
- nettime->time_100us = getRTR();
-}
-
-// End
diff --git a/src/Network2/W5500/Wiznet/Ethernet/wizchip_conf.h b/src/Network2/W5500/Wiznet/Ethernet/wizchip_conf.h
deleted file mode 100644
index a69fbe47..00000000
--- a/src/Network2/W5500/Wiznet/Ethernet/wizchip_conf.h
+++ /dev/null
@@ -1,422 +0,0 @@
-//*****************************************************************************
-//
-//! \file wizchip_conf.h
-//! \brief WIZCHIP Config Header File.
-//! \version 1.0.0
-//! \date 2013/10/21
-//! \par Revision history
-//! <2015/02/05> Notice
-//! The version history is not updated after this point.
-//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
-//! >> https://github.com/Wiznet/ioLibrary_Driver
-//! <2013/10/21> 1st Release
-//! \author MidnightCow
-//! \copyright
-//!
-//! Copyright (c) 2013, WIZnet Co., LTD.
-//! All rights reserved.
-//!
-//! Redistribution and use in source and binary forms, with or without
-//! modification, are permitted provided that the following conditions
-//! are met:
-//!
-//! * Redistributions of source code must retain the above copyright
-//! notice, this list of conditions and the following disclaimer.
-//! * Redistributions in binary form must reproduce the above copyright
-//! notice, this list of conditions and the following disclaimer in the
-//! documentation and/or other materials provided with the distribution.
-//! * Neither the name of the <ORGANIZATION> nor the names of its
-//! contributors may be used to endorse or promote products derived
-//! from this software without specific prior written permission.
-//!
-//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-//! THE POSSIBILITY OF SUCH DAMAGE.
-//
-//*****************************************************************************
-
-/**
- * @defgroup extra_functions 2. WIZnet Extra Functions
- *
- * @brief These functions is optional function. It could be replaced at WIZCHIP I/O function because they were made by WIZCHIP I/O functions.
- * @details There are functions of configuring WIZCHIP, network, interrupt, phy, network information and timer. \n
- *
- */
-
-#ifndef _WIZCHIP_CONF_H_
-#define _WIZCHIP_CONF_H_
-
-#include <stdint.h>
-/**
- * @brief Select WIZCHIP.
- * @todo You should select one, \b 5100, \b 5200, \b 5300, \b 5500 or etc. \n\n
- * ex> <code> #define \_WIZCHIP_ 5500 </code>
- */
-#ifndef _WIZCHIP_
-# define _WIZCHIP_ 5500 // 5100, 5200, 5300, 5500
-#endif
-
-#define _WIZCHIP_IO_MODE_NONE_ 0x0000
-#define _WIZCHIP_IO_MODE_BUS_ 0x0100 /**< Bus interface mode */
-#define _WIZCHIP_IO_MODE_SPI_ 0x0200 /**< SPI interface mode */
-//#define _WIZCHIP_IO_MODE_IIC_ 0x0400
-//#define _WIZCHIP_IO_MODE_SDIO_ 0x0800
-
-#define _WIZCHIP_IO_MODE_BUS_DIR_ (_WIZCHIP_IO_MODE_BUS_ + 1) /**< BUS interface mode for direct */
-#define _WIZCHIP_IO_MODE_BUS_INDIR_ (_WIZCHIP_IO_MODE_BUS_ + 2) /**< BUS interface mode for indirect */
-
-#define _WIZCHIP_IO_MODE_SPI_VDM_ (_WIZCHIP_IO_MODE_SPI_ + 1) /**< SPI interface mode for variable length data*/
-#define _WIZCHIP_IO_MODE_SPI_FDM_ (_WIZCHIP_IO_MODE_SPI_ + 2) /**< SPI interface mode for fixed length data mode*/
-
-
-#define _WIZCHIP_ID_ "W5500"
-
-/**
- * @brief Define interface mode. \n
- * @todo Should select interface mode as chip.
- * - @ref \_WIZCHIP_IO_MODE_SPI_ \n
- * -@ref \_WIZCHIP_IO_MODE_SPI_VDM_ : Valid only in @ref \_WIZCHIP_ == 5500 \n
- * -@ref \_WIZCHIP_IO_MODE_SPI_FDM_ : Valid only in @ref \_WIZCHIP_ == 5500 \n
- * - @ref \_WIZCHIP_IO_MODE_BUS_ \n
- * - @ref \_WIZCHIP_IO_MODE_BUS_DIR_ \n
- * - @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ \n
- * - Others will be defined in future. \n\n
- * ex> <code> #define \_WIZCHIP_IO_MODE_ \_WIZCHIP_IO_MODE_SPI_VDM_ </code>
- *
- */
-#ifndef _WIZCHIP_IO_MODE_
- //#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_FDM_
- #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_VDM_
-#endif
-
-typedef uint8_t iodata_t;
-
-#include <Network2/W5500/Wiznet/Ethernet/W5500/w5500.h>
-
-#ifndef _WIZCHIP_IO_MODE_
- #error "Undefined _WIZCHIP_IO_MODE_. You should define it !!!"
-#endif
-
-/**
- * @brief Define I/O base address when BUS IF mode.
- * @todo Should re-define it to fit your system when BUS IF Mode (@ref \_WIZCHIP_IO_MODE_BUS_,
- * @ref \_WIZCHIP_IO_MODE_BUS_DIR_, @ref \_WIZCHIP_IO_MODE_BUS_INDIR_). \n\n
- * ex> <code> #define \_WIZCHIP_IO_BASE_ 0x00008000 </code>
- */
-#ifndef _WIZCHIP_IO_BASE_
-# define _WIZCHIP_IO_BASE_ 0x00000000 // 0x8000
-#endif
-
-#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_
- #ifndef _WIZCHIP_IO_BASE_
- #error "You should be define _WIZCHIP_IO_BASE to fit your system memory map."
- #endif
-#endif
-
-#define _WIZCHIP_SOCK_NUM_ 8 ///< The count of independent socket of @b WIZCHIP
-
-
-/********************************************************
-* WIZCHIP BASIC IF functions for SPI, SDIO, I2C , ETC.
-*********************************************************/
-
-/**
- * @ingroup DATA_TYPE
- * WIZCHIP control type enumeration used in @ref ctlwizchip().
- */
-enum ctlwizchip_type
-{
- CW_RESET_WIZCHIP, ///< Resets WIZCHIP by softly
- CW_INIT_WIZCHIP, ///< Initializes to WIZCHIP with SOCKET buffer size 2 or 1 dimension array typed uint8_t.
- CW_GET_INTERRUPT, ///< Get Interrupt status of WIZCHIP
- CW_CLR_INTERRUPT, ///< Clears interrupt
- CW_SET_INTRMASK, ///< Masks interrupt
- CW_GET_INTRMASK, ///< Get interrupt mask
- CW_SET_INTRTIME, ///< Set interval time between the current and next interrupt.
- CW_GET_INTRTIME, ///< Set interval time between the current and next interrupt.
- CW_GET_ID, ///< Gets WIZCHIP name.
-
- CW_RESET_PHY, ///< Resets internal PHY. Valid Only W5500
- CW_SET_PHYCONF, ///< When PHY configured by internal register, PHY operation mode (Manual/Auto, 10/100, Half/Full). Valid Only W5000
- CW_GET_PHYCONF, ///< Get PHY operation mode in internal register. Valid Only W5500
- CW_GET_PHYSTATUS, ///< Get real PHY status on operating. Valid Only W5500
- CW_SET_PHYPOWMODE, ///< Set PHY power mode as normal and down when PHYSTATUS.OPMD == 1. Valid Only W5500
- CW_GET_PHYPOWMODE, ///< Get PHY Power mode as down or normal, Valid Only W5100, W5200
- CW_GET_PHYLINK ///< Get PHY Link status, Valid Only W5100, W5200
-};
-
-/**
- * @ingroup DATA_TYPE
- * Network control type enumration used in @ref ctlnetwork().
- */
-enum ctlnetwork_type
-{
- CN_SET_NETINFO, ///< Set Network with @ref wiz_NetInfo
- CN_GET_NETINFO, ///< Get Network with @ref wiz_NetInfo
- CN_SET_NETMODE, ///< Set network mode as WOL, PPPoE, Ping Block, and Force ARP mode
- CN_GET_NETMODE, ///< Get network mode as WOL, PPPoE, Ping Block, and Force ARP mode
- CN_SET_TIMEOUT, ///< Set network timeout as retry count and time.
- CN_GET_TIMEOUT, ///< Get network timeout as retry count and time.
-};
-
-/**
- * @ingroup DATA_TYPE
- * Interrupt kind when CW_SET_INTRRUPT, CW_GET_INTERRUPT, CW_SET_INTRMASK
- * and CW_GET_INTRMASK is used in @ref ctlnetwork().
- * It can be used with OR operation.
- */
-enum intr_kind
-{
- IK_WOL = (1 << 4), ///< Wake On Lan by receiving the magic packet. Valid in W500.
-
- IK_PPPOE_TERMINATED = (1 << 5), ///< PPPoE Disconnected
-
- IK_DEST_UNREACH = (1 << 6), ///< Destination IP & Port Unreachable, No use in W5200
-
- IK_IP_CONFLICT = (1 << 7), ///< IP conflict occurred
-
- IK_SOCK_0 = (1 << 8), ///< Socket 0 interrupt
- IK_SOCK_1 = (1 << 9), ///< Socket 1 interrupt
- IK_SOCK_2 = (1 << 10), ///< Socket 2 interrupt
- IK_SOCK_3 = (1 << 11), ///< Socket 3 interrupt
- IK_SOCK_4 = (1 << 12), ///< Socket 4 interrupt, No use in 5100
- IK_SOCK_5 = (1 << 13), ///< Socket 5 interrupt, No use in 5100
- IK_SOCK_6 = (1 << 14), ///< Socket 6 interrupt, No use in 5100
- IK_SOCK_7 = (1 << 15), ///< Socket 7 interrupt, No use in 5100
-
- IK_SOCK_ALL = (0xFF << 8) ///< All Socket interrupt
-};
-
-#define PHY_CONFBY_HW 0 ///< Configured PHY operation mode by HW pin
-#define PHY_CONFBY_SW 1 ///< Configured PHY operation mode by SW register
-#define PHY_MODE_MANUAL 0 ///< Configured PHY operation mode with user setting.
-#define PHY_MODE_AUTONEGO 1 ///< Configured PHY operation mode with auto-negotiation
-#define PHY_SPEED_10 0 ///< Link Speed 10
-#define PHY_SPEED_100 1 ///< Link Speed 100
-#define PHY_DUPLEX_HALF 0 ///< Link Half-Duplex
-#define PHY_DUPLEX_FULL 1 ///< Link Full-Duplex
-#define PHY_LINK_OFF 0 ///< Link Off
-#define PHY_LINK_ON 1 ///< Link On
-#define PHY_POWER_NORM 0 ///< PHY power normal mode
-#define PHY_POWER_DOWN 1 ///< PHY power down mode
-
-
-/**
- * @ingroup DATA_TYPE
- * It configures PHY configuration when CW_SET PHYCONF or CW_GET_PHYCONF in W5500,
- * and it indicates the real PHY status configured by HW or SW in all WIZCHIP. \n
- * Valid only in W5500.
- */
-struct wiz_PhyConf
-{
- uint8_t by; ///< set by @ref PHY_CONFBY_HW or @ref PHY_CONFBY_SW
- uint8_t mode; ///< set by @ref PHY_MODE_MANUAL or @ref PHY_MODE_AUTONEGO
- uint8_t speed; ///< set by @ref PHY_SPEED_10 or @ref PHY_SPEED_100
- uint8_t duplex; ///< set by @ref PHY_DUPLEX_HALF @ref PHY_DUPLEX_FULL
- //uint8_t power; ///< set by @ref PHY_POWER_NORM or @ref PHY_POWER_DOWN
- //uint8_t link; ///< Valid only in CW_GET_PHYSTATUS. set by @ref PHY_LINK_ON or PHY_DUPLEX_OFF
-};
-
-/**
- * @ingroup DATA_TYPE
- * It used in setting dhcp_mode of @ref wiz_NetInfo.
- */
-enum dhcp_mode
-{
- NETINFO_STATIC = 1, ///< Static IP configuration by manually.
- NETINFO_DHCP ///< Dynamic IP configruation from a DHCP sever
-};
-
-/**
- * @ingroup DATA_TYPE
- * Network Information for WIZCHIP
- */
-struct wiz_NetInfo
-{
- uint8_t mac[6]; ///< Source Mac Address
- uint8_t ip[4]; ///< Source IP Address
- uint8_t sn[4]; ///< Subnet Mask
- uint8_t gw[4]; ///< Gateway IP Address
- uint8_t dns[4]; ///< DNS server IP Address
- dhcp_mode dhcp; ///< 1 - Static, 2 - DHCP
-};
-
-/**
- * @ingroup DATA_TYPE
- * Network mode
- */
-enum netmode_type
-{
- NM_FORCEARP = (1<<1), ///< Force to APP send whenever udp data is sent. Valid only in W5500
- NM_WAKEONLAN = (1<<5), ///< Wake On Lan
- NM_PINGBLOCK = (1<<4), ///< Block ping-request
- NM_PPPOE = (1<<3), ///< PPPoE mode
-};
-
-/**
- * @ingroup DATA_TYPE
- * Used in CN_SET_TIMEOUT or CN_GET_TIMEOUT of @ref ctlwizchip() for timeout configruation.
- */
-struct wiz_NetTimeout
-{
- uint8_t retry_cnt; ///< retry count
- uint16_t time_100us; ///< time unit 100us
-};
-
-
-/**
- * @ingroup extra_functions
- * @brief Controls to the WIZCHIP.
- * @details Resets WIZCHIP & internal PHY, Configures PHY mode, Monitor PHY(Link,Speed,Half/Full/Auto),
- * controls interrupt & mask and so on.
- * @param cwtype : Decides to the control type
- * @param arg : arg type is dependent on cwtype.
- * @return 0 : Success \n
- * -1 : Fail because of invalid \ref ctlwizchip_type or unsupported \ref ctlwizchip_type in WIZCHIP
- */
-int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg);
-
-/**
- * @ingroup extra_functions
- * @brief Controls to network.
- * @details Controls to network environment, mode, timeout and so on.
- * @param cntype : Input. Decides to the control type
- * @param arg : Inout. arg type is dependent on cntype.
- * @return -1 : Fail because of invalid \ref ctlnetwork_type or unsupported \ref ctlnetwork_type in WIZCHIP \n
- * 0 : Success
- */
-int8_t ctlnetwork(ctlnetwork_type cntype, void* arg);
-
-
-/*
- * The following functions are implemented for internal use.
- * but You can call these functions for code size reduction instead of ctlwizchip() and ctlnetwork().
- */
-
-/**
- * @ingroup extra_functions
- * @brief Reset WIZCHIP by softly.
- */
-void wizchip_sw_reset(void);
-
-/**
- * @ingroup extra_functions
- * @brief Initializes WIZCHIP with socket buffer size
- * @param txsize Socket tx buffer sizes. If null, initialized the default size 2KB.
- * @param rxsize Socket rx buffer sizes. If null, initialized the default size 2KB.
- * @return 0 : succcess \n
- * -1 : fail. Invalid buffer size
- */
-int8_t wizchip_init(const uint8_t* txsize, const uint8_t* rxsize);
-
-/**
- * @ingroup extra_functions
- * @brief Clear Interrupt of WIZCHIP.
- * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t.
- */
-void wizchip_clrinterrupt(intr_kind intr);
-
-/**
- * @ingroup extra_functions
- * @brief Get Interrupt of WIZCHIP.
- * @return @ref intr_kind value operated OR. It can type-cast to uint16_t.
- */
-intr_kind wizchip_getinterrupt(void);
-
-/**
- * @ingroup extra_functions
- * @brief Mask or Unmask Interrupt of WIZCHIP.
- * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t.
- */
-void wizchip_setinterruptmask(intr_kind intr);
-
-/**
- * @ingroup extra_functions
- * @brief Get Interrupt mask of WIZCHIP.
- * @return : The operated OR vaule of @ref intr_kind. It can type-cast to uint16_t.
- */
-intr_kind wizchip_getinterruptmask(void);
-
-int8_t wizphy_getphylink(void); ///< get the link status of phy in WIZCHIP. No use in W5100
-int8_t wizphy_getphypmode(void); ///< get the power mode of PHY in WIZCHIP. No use in W5100
-
-void wizphy_reset(void); ///< Reset phy. Valid only in W5500
-
-/**
- * @ingroup extra_functions
- * @brief Set the phy information for WIZCHIP without power mode
- * @param phyconf : @ref wiz_PhyConf
- */
-void wizphy_setphyconf(wiz_PhyConf* phyconf);
- /**
- * @ingroup extra_functions
- * @brief Get phy configuration information.
- * @param phyconf : @ref wiz_PhyConf
- */
-void wizphy_getphyconf(wiz_PhyConf* phyconf);
- /**
- * @ingroup extra_functions
- * @brief Get phy status.
- * @param phyconf : @ref wiz_PhyConf
- */
-void wizphy_getphystat(wiz_PhyConf* phyconf);
- /**
- * @ingroup extra_functions
- * @brief set the power mode of phy inside WIZCHIP. Refer to @ref PHYCFGR in W5500, @ref PHYSTATUS in W5200
- * @param pmode Settig value of power down mode.
- */
-int8_t wizphy_setphypmode(uint8_t pmode);
-
-/**
-* @ingroup extra_functions
- * @brief Set the network information for WIZCHIP
- * @param pnetinfo : @ref wizNetInfo
- */
-void wizchip_setnetinfo(wiz_NetInfo* pnetinfo);
-
-/**
- * @ingroup extra_functions
- * @brief Get the network information for WIZCHIP
- * @param pnetinfo : @ref wizNetInfo
- */
-void wizchip_getnetinfo(wiz_NetInfo* pnetinfo);
-
-/**
- * @ingroup extra_functions
- * @brief Set the network mode such WOL, PPPoE, Ping Block, and etc.
- * @param pnetinfo Value of network mode. Refer to @ref netmode_type.
- */
-int8_t wizchip_setnetmode(netmode_type netmode);
-
-/**
- * @ingroup extra_functions
- * @brief Get the network mode such WOL, PPPoE, Ping Block, and etc.
- * @return Value of network mode. Refer to @ref netmode_type.
- */
-netmode_type wizchip_getnetmode(void);
-
-/**
- * @ingroup extra_functions
- * @brief Set retry time value(@ref _RTR_) and retry count(@ref _RCR_).
- * @details @ref _RTR_ configures the retransmission timeout period and @ref _RCR_ configures the number of time of retransmission.
- * @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref wiz_NetTimeout.
- */
-void wizchip_settimeout(wiz_NetTimeout* nettime);
-
-/**
- * @ingroup extra_functions
- * @brief Get retry time value(@ref _RTR_) and retry count(@ref _RCR_).
- * @details @ref _RTR_ configures the retransmission timeout period and @ref _RCR_ configures the number of time of retransmission.
- * @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref wiz_NetTimeout.
- */
-void wizchip_gettimeout(wiz_NetTimeout* nettime);
-
-#endif // _WIZCHIP_CONF_H_
diff --git a/src/Network2/W5500/Wiznet/Internet/DHCP/dhcp.cpp b/src/Network2/W5500/Wiznet/Internet/DHCP/dhcp.cpp
deleted file mode 100644
index e8de7ae9..00000000
--- a/src/Network2/W5500/Wiznet/Internet/DHCP/dhcp.cpp
+++ /dev/null
@@ -1,1004 +0,0 @@
-//*****************************************************************************
-//
-//! \file dhcp.c
-//! \brief DHCP APIs implement file.
-//! \details Processig DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE.
-//! \version 1.1.0
-//! \date 2013/11/18
-//! \par Revision history
-//! <2013/11/18> 1st Release
-//! <2012/12/20> V1.1.0
-//! 1. Optimize code
-//! 2. Add reg_dhcp_cbfunc()
-//! 3. Add DHCP_stop()
-//! 4. Integrate check_DHCP_state() & DHCP_run() to DHCP_run()
-//! 5. Don't care system endian
-//! 6. Add comments
-//! <2012/12/26> V1.1.1
-//! 1. Modify variable declaration: dhcp_tick_1s is declared volatile for code optimization
-//! \author Eric Jung & MidnightCow
-//! \copyright
-//!
-//! Copyright (c) 2013, WIZnet Co., LTD.
-//! All rights reserved.
-//!
-//! Redistribution and use in source and binary forms, with or without
-//! modification, are permitted provided that the following conditions
-//! are met:
-//!
-//! * Redistributions of source code must retain the above copyright
-//! notice, this list of conditions and the following disclaimer.
-//! * Redistributions in binary form must reproduce the above copyright
-//! notice, this list of conditions and the following disclaimer in the
-//! documentation and/or other materials provided with the distribution.
-//! * Neither the name of the <ORGANIZATION> nor the names of its
-//! contributors may be used to endorse or promote products derived
-//! from this software without specific prior written permission.
-//!
-//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-//! THE POSSIBILITY OF SUCH DAMAGE.
-//
-//*****************************************************************************
-
-#include <Network2/W5500/Wiznet/Ethernet/socketlib.h>
-#include <Network2/W5500/Wiznet/Internet/DHCP/dhcp.h>
-#include <cstring>
-
-/* If you want to display debug & processing message, Define _DHCP_DEBUG_ in dhcp.h */
-
-//#define _DHCP_DEBUG_
-
-#ifdef _DHCP_DEBUG_
-extern "C" void debugPrintf(const char *fmt, ...);
-# define DEBUG_PRINTF(...) debugPrintf(__VA_ARGS__)
-#else
-# define DEBUG_PRINTF(_fmt, ...)
-#endif
-
-/* DHCP state machine. */
-#define STATE_DHCP_INIT 0 ///< Initialize
-#define STATE_DHCP_DISCOVER 1 ///< send DISCOVER and wait OFFER
-#define STATE_DHCP_REQUEST 2 ///< send REQEUST and wait ACK or NACK
-#define STATE_DHCP_LEASED 3 ///< ReceiveD ACK and IP leased
-#define STATE_DHCP_REREQUEST 4 ///< send REQUEST for maintaining leased IP
-#define STATE_DHCP_RELEASE 5 ///< No use
-#define STATE_DHCP_STOP 6 ///< Stop processing DHCP
-
-#define DHCP_FLAGSBROADCAST 0x8000 ///< The broadcast value of flags in @ref RIP_MSG
-#define DHCP_FLAGSUNICAST 0x0000 ///< The unicast value of flags in @ref RIP_MSG
-
-/* DHCP message OP code */
-#define DHCP_BOOTREQUEST 1 ///< Request Message used in op of @ref RIP_MSG
-#define DHCP_BOOTREPLY 2 ///< Reply Message used i op of @ref RIP_MSG
-
-/* DHCP message type */
-#define DHCP_DISCOVER 1 ///< DISCOVER message in OPT of @ref RIP_MSG
-#define DHCP_OFFER 2 ///< OFFER message in OPT of @ref RIP_MSG
-#define DHCP_REQUEST 3 ///< REQUEST message in OPT of @ref RIP_MSG
-#define DHCP_DECLINE 4 ///< DECLINE message in OPT of @ref RIP_MSG
-#define DHCP_ACK 5 ///< ACK message in OPT of @ref RIP_MSG
-#define DHCP_NAK 6 ///< NACK message in OPT of @ref RIP_MSG
-#define DHCP_RELEASE 7 ///< RELEASE message in OPT of @ref RIP_MSG. No use
-#define DHCP_INFORM 8 ///< INFORM message in OPT of @ref RIP_MSG. No use
-
-#define DHCP_HTYPE10MB 1 ///< Used in type of @ref RIP_MSG
-#define DHCP_HTYPE100MB 2 ///< Used in type of @ref RIP_MSG
-
-#define DHCP_HLENETHERNET 6 ///< Used in hlen of @ref RIP_MSG
-#define DHCP_HOPS 0 ///< Used in hops of @ref RIP_MSG
-#define DHCP_SECS 0 ///< Used in secs of @ref RIP_MSG
-
-#define INFINITE_LEASETIME 0xffffffff ///< Infinite lease time
-
-#define OPT_SIZE 312 /// Max OPT size of @ref RIP_MSG
-#define RIP_MSG_SIZE (236+OPT_SIZE) /// Max size of @ref RIP_MSG
-
-/*
- * @brief DHCP option and value (cf. RFC1533)
- */
-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
-};
-
-/*
- * @brief DHCP message format
- */
-typedef struct {
- uint8_t op; ///< @ref DHCP_BOOTREQUEST or @ref DHCP_BOOTREPLY
- uint8_t htype; ///< @ref DHCP_HTYPE10MB or @ref DHCP_HTYPE100MB
- uint8_t hlen; ///< @ref DHCP_HLENETHERNET
- uint8_t hops; ///< @ref DHCP_HOPS
- uint32_t xid; ///< @ref DHCP_XID This increase one every DHCP transaction.
- uint16_t secs; ///< @ref DHCP_SECS
- uint16_t flags; ///< @ref DHCP_FLAGSBROADCAST or @ref DHCP_FLAGSUNICAST
- uint8_t ciaddr[4]; ///< @ref Request IP to DHCP sever
- uint8_t yiaddr[4]; ///< @ref Offered IP from DHCP server
- uint8_t siaddr[4]; ///< No use
- uint8_t giaddr[4]; ///< No use
- uint8_t chaddr[16]; ///< DHCP client 6bytes MAC address. Others is filled to zero
- uint8_t sname[64]; ///< No use
- uint8_t file[128]; ///< No use
- uint8_t OPT[OPT_SIZE]; ///< Option
-} RIP_MSG;
-
-
-
-uint8_t DHCP_SOCKET; // Socket number for DHCP
-
-uint8_t DHCP_SIP[4]; // DHCP Server IP address
-
-// Network information from DHCP Server
-uint8_t OLD_allocated_ip[4] = {0, }; // Previous IP address
-uint8_t DHCP_allocated_ip[4] = {0, }; // IP address from DHCP
-uint8_t DHCP_allocated_gw[4] = {0, }; // Gateway address from DHCP
-uint8_t DHCP_allocated_sn[4] = {0, }; // Subnet mask from DHCP
-uint8_t DHCP_allocated_dns[4] = {0, }; // DNS address from DHCP
-
-
-int8_t dhcp_state = STATE_DHCP_INIT; // DHCP state
-int8_t dhcp_retry_count = 0;
-
-uint32_t dhcp_lease_time = INFINITE_LEASETIME;
-volatile uint32_t dhcp_tick_1s = 0; // unit 1 second
-uint32_t dhcp_tick_next = DHCP_WAIT_TIME ;
-
-uint32_t DHCP_XID; // Any number
-
-static RIP_MSG dhcpMessageBuffer;
-RIP_MSG* const pDHCPMSG = &dhcpMessageBuffer; // Buffer pointer for DHCP processing
-
-char HOST_NAME[16] = DCHP_HOST_NAME;
-uint8_t DHCP_CHADDR[6]; // DHCP Client MAC address.
-
-/* The default callback function */
-void default_ip_assign(void);
-void default_ip_update(void);
-void default_ip_conflict(void);
-
-/* Callback handler */
-void (*dhcp_ip_assign)(void) = default_ip_assign; /* handler to be called when the IP address from DHCP server is first assigned */
-void (*dhcp_ip_update)(void) = default_ip_update; /* handler to be called when the IP address from DHCP server is updated */
-void (*dhcp_ip_conflict)(void) = default_ip_conflict; /* handler to be called when the IP address from DHCP server is conflict */
-
-void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void));
-
-
-/* send DISCOVER message to DHCP server */
-void send_DHCP_DISCOVER(void);
-
-/* send REQEUST message to DHCP server */
-void send_DHCP_REQUEST(void);
-
-/* send DECLINE message to DHCP server */
-void send_DHCP_DECLINE(void);
-
-/* IP conflict check by sending ARP-request to leased IP and wait ARP-response. */
-bool check_DHCP_leasedIP(void);
-
-/* check the timeout in DHCP process */
-DhcpRunResult check_DHCP_timeout(void);
-
-/* Initialize to timeout process. */
-void reset_DHCP_timeout(void);
-
-/* Parse message as OFFER and ACK and NACK from DHCP server.*/
-int8_t parseDHCPMSG(void);
-
-/* The default handler of ip assign first */
-void default_ip_assign(void)
-{
- setSIPR(DHCP_allocated_ip);
- setSUBR(DHCP_allocated_sn);
- setGAR (DHCP_allocated_gw);
-}
-
-/* The default handler of ip chaged */
-void default_ip_update(void)
-{
- /* WIZchip Software Reset */
- setMR(MR_RST);
- getMR(); // for delay
- default_ip_assign();
- setSHAR(DHCP_CHADDR);
-}
-
-/* The default handler of ip chaged */
-void default_ip_conflict(void)
-{
- // WIZchip Software Reset
- setMR(MR_RST);
- getMR(); // for delay
- setSHAR(DHCP_CHADDR);
-}
-
-/* register the call back func. */
-void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void))
-{
- dhcp_ip_assign = default_ip_assign;
- dhcp_ip_update = default_ip_update;
- dhcp_ip_conflict = default_ip_conflict;
- if(ip_assign) { dhcp_ip_assign = ip_assign; }
- if(ip_update) { dhcp_ip_update = ip_update; }
- if(ip_conflict) { dhcp_ip_conflict = ip_conflict; }
-}
-
-/* make the common DHCP message */
-void makeDHCPMSG(void)
-{
- uint8_t bk_mac[6];
- getSHAR(bk_mac);
- pDHCPMSG->op = DHCP_BOOTREQUEST;
- pDHCPMSG->htype = DHCP_HTYPE10MB;
- pDHCPMSG->hlen = DHCP_HLENETHERNET;
- pDHCPMSG->hops = DHCP_HOPS;
- uint8_t* ptmp = (uint8_t*)(&pDHCPMSG->xid);
- *(ptmp+0) = (uint8_t)((DHCP_XID & 0xFF000000) >> 24);
- *(ptmp+1) = (uint8_t)((DHCP_XID & 0x00FF0000) >> 16);
- *(ptmp+2) = (uint8_t)((DHCP_XID & 0x0000FF00) >> 8);
- *(ptmp+3) = (uint8_t)((DHCP_XID & 0x000000FF) >> 0);
- pDHCPMSG->secs = DHCP_SECS;
- ptmp = (uint8_t*)(&pDHCPMSG->flags);
- *(ptmp+0) = (uint8_t)((DHCP_FLAGSBROADCAST & 0xFF00) >> 8);
- *(ptmp+1) = (uint8_t)((DHCP_FLAGSBROADCAST & 0x00FF) >> 0);
-
- pDHCPMSG->ciaddr[0] = 0;
- pDHCPMSG->ciaddr[1] = 0;
- pDHCPMSG->ciaddr[2] = 0;
- pDHCPMSG->ciaddr[3] = 0;
-
- pDHCPMSG->yiaddr[0] = 0;
- pDHCPMSG->yiaddr[1] = 0;
- pDHCPMSG->yiaddr[2] = 0;
- pDHCPMSG->yiaddr[3] = 0;
-
- pDHCPMSG->siaddr[0] = 0;
- pDHCPMSG->siaddr[1] = 0;
- pDHCPMSG->siaddr[2] = 0;
- pDHCPMSG->siaddr[3] = 0;
-
- pDHCPMSG->giaddr[0] = 0;
- pDHCPMSG->giaddr[1] = 0;
- pDHCPMSG->giaddr[2] = 0;
- pDHCPMSG->giaddr[3] = 0;
-
- pDHCPMSG->chaddr[0] = DHCP_CHADDR[0];
- pDHCPMSG->chaddr[1] = DHCP_CHADDR[1];
- pDHCPMSG->chaddr[2] = DHCP_CHADDR[2];
- pDHCPMSG->chaddr[3] = DHCP_CHADDR[3];
- pDHCPMSG->chaddr[4] = DHCP_CHADDR[4];
- pDHCPMSG->chaddr[5] = DHCP_CHADDR[5];
-
- for (size_t i = 6; i < 16; i++)
- {
- pDHCPMSG->chaddr[i] = 0;
- }
- for (size_t i = 0; i < 64; i++)
- {
- pDHCPMSG->sname[i] = 0;
- }
- for (size_t i = 0; i < 128; i++)
- {
- pDHCPMSG->file[i] = 0;
- }
-
- // MAGIC_COOKIE
- pDHCPMSG->OPT[0] = (uint8_t)((MAGIC_COOKIE & 0xFF000000) >> 24);
- pDHCPMSG->OPT[1] = (uint8_t)((MAGIC_COOKIE & 0x00FF0000) >> 16);
- pDHCPMSG->OPT[2] = (uint8_t)((MAGIC_COOKIE & 0x0000FF00) >> 8);
- pDHCPMSG->OPT[3] = (uint8_t) (MAGIC_COOKIE & 0x000000FF) >> 0;
-}
-
-/* SEND DHCP DISCOVER */
-void send_DHCP_DISCOVER(void)
-{
- makeDHCPMSG();
-
- size_t k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG()
-
- // Option Request Param
- pDHCPMSG->OPT[k++] = dhcpMessageType;
- pDHCPMSG->OPT[k++] = 0x01;
- pDHCPMSG->OPT[k++] = DHCP_DISCOVER;
-
- // Client identifier
- pDHCPMSG->OPT[k++] = dhcpClientIdentifier;
- pDHCPMSG->OPT[k++] = 0x07;
- pDHCPMSG->OPT[k++] = 0x01;
- pDHCPMSG->OPT[k++] = DHCP_CHADDR[0];
- pDHCPMSG->OPT[k++] = DHCP_CHADDR[1];
- pDHCPMSG->OPT[k++] = DHCP_CHADDR[2];
- pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
- pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
- pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
-
- // host name
- pDHCPMSG->OPT[k++] = hostName;
- pDHCPMSG->OPT[k++] = 0; // fill zero length of hostname
- size_t i;
- for (i = 0 ; HOST_NAME[i] != 0; i++)
- {
- pDHCPMSG->OPT[k++] = HOST_NAME[i];
- }
- pDHCPMSG->OPT[k - (i+1)] = i; // length of hostname
- pDHCPMSG->OPT[k++] = dhcpParamRequest;
- pDHCPMSG->OPT[k++] = 0x06; // length of request
- pDHCPMSG->OPT[k++] = subnetMask;
- pDHCPMSG->OPT[k++] = routersOnSubnet;
- pDHCPMSG->OPT[k++] = dns;
- pDHCPMSG->OPT[k++] = domainName;
- pDHCPMSG->OPT[k++] = dhcpT1value;
- pDHCPMSG->OPT[k++] = dhcpT2value;
- pDHCPMSG->OPT[k++] = endOption;
-
- for (i = k; i < OPT_SIZE; i++)
- {
- pDHCPMSG->OPT[i] = 0;
- }
-
- // send broadcasting packet
- uint8_t ip[4];
- ip[0] = 255;
- ip[1] = 255;
- ip[2] = 255;
- ip[3] = 255;
-
- DEBUG_PRINTF("> Send DHCP_DISCOVER\n");
-
- sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT);
- DEBUG_PRINTF("Sent\n");
-}
-
-/* SEND DHCP REQUEST */
-void send_DHCP_REQUEST(void)
-{
-
- makeDHCPMSG();
-
- uint8_t ip[4];
- if (dhcp_state == STATE_DHCP_LEASED || dhcp_state == STATE_DHCP_REREQUEST)
- {
- *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8);
- *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF);
- pDHCPMSG->ciaddr[0] = DHCP_allocated_ip[0];
- pDHCPMSG->ciaddr[1] = DHCP_allocated_ip[1];
- pDHCPMSG->ciaddr[2] = DHCP_allocated_ip[2];
- pDHCPMSG->ciaddr[3] = DHCP_allocated_ip[3];
- ip[0] = DHCP_SIP[0];
- ip[1] = DHCP_SIP[1];
- ip[2] = DHCP_SIP[2];
- ip[3] = DHCP_SIP[3];
- }
- else
- {
- ip[0] = 255;
- ip[1] = 255;
- ip[2] = 255;
- ip[3] = 255;
- }
-
- size_t k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG()
-
- // Option Request Param.
- pDHCPMSG->OPT[k++] = dhcpMessageType;
- pDHCPMSG->OPT[k++] = 0x01;
- pDHCPMSG->OPT[k++] = DHCP_REQUEST;
-
- pDHCPMSG->OPT[k++] = dhcpClientIdentifier;
- pDHCPMSG->OPT[k++] = 0x07;
- pDHCPMSG->OPT[k++] = 0x01;
- pDHCPMSG->OPT[k++] = DHCP_CHADDR[0];
- pDHCPMSG->OPT[k++] = DHCP_CHADDR[1];
- pDHCPMSG->OPT[k++] = DHCP_CHADDR[2];
- pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
- pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
- pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
-
- if (ip[3] == 255) // if(dchp_state == STATE_DHCP_LEASED || dchp_state == DHCP_REREQUEST_STATE)
- {
- pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr;
- pDHCPMSG->OPT[k++] = 0x04;
- pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0];
- pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1];
- pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2];
- pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3];
-
- pDHCPMSG->OPT[k++] = dhcpServerIdentifier;
- pDHCPMSG->OPT[k++] = 0x04;
- pDHCPMSG->OPT[k++] = DHCP_SIP[0];
- pDHCPMSG->OPT[k++] = DHCP_SIP[1];
- pDHCPMSG->OPT[k++] = DHCP_SIP[2];
- pDHCPMSG->OPT[k++] = DHCP_SIP[3];
- }
-
- // host name
- pDHCPMSG->OPT[k++] = hostName;
- pDHCPMSG->OPT[k++] = 0; // length of hostname
- size_t i;
- for (i = 0 ; HOST_NAME[i] != 0; i++)
- {
- pDHCPMSG->OPT[k++] = HOST_NAME[i];
- }
- pDHCPMSG->OPT[k - (i+1)] = i; // length of hostname
- pDHCPMSG->OPT[k++] = dhcpParamRequest;
- pDHCPMSG->OPT[k++] = 0x08;
- pDHCPMSG->OPT[k++] = subnetMask;
- pDHCPMSG->OPT[k++] = routersOnSubnet;
- pDHCPMSG->OPT[k++] = dns;
- pDHCPMSG->OPT[k++] = domainName;
- pDHCPMSG->OPT[k++] = dhcpT1value;
- pDHCPMSG->OPT[k++] = dhcpT2value;
- pDHCPMSG->OPT[k++] = performRouterDiscovery;
- pDHCPMSG->OPT[k++] = staticRoute;
- pDHCPMSG->OPT[k++] = endOption;
-
- for (size_t i = k; i < OPT_SIZE; i++)
- {
- pDHCPMSG->OPT[i] = 0;
- }
-
- DEBUG_PRINTF("> Send DHCP_REQUEST\n");
-
- sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT);
-}
-
-/* SEND DHCP DHCPDECLINE */
-void send_DHCP_DECLINE(void)
-{
- makeDHCPMSG();
-
- size_t k = 4; // beacaue MAGIC_COOKIE already made by makeDHCPMSG()
-
- *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8);
- *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF);
-
- // Option Request Param.
- pDHCPMSG->OPT[k++] = dhcpMessageType;
- pDHCPMSG->OPT[k++] = 0x01;
- pDHCPMSG->OPT[k++] = DHCP_DECLINE;
-
- pDHCPMSG->OPT[k++] = dhcpClientIdentifier;
- pDHCPMSG->OPT[k++] = 0x07;
- pDHCPMSG->OPT[k++] = 0x01;
- pDHCPMSG->OPT[k++] = DHCP_CHADDR[0];
- pDHCPMSG->OPT[k++] = DHCP_CHADDR[1];
- pDHCPMSG->OPT[k++] = DHCP_CHADDR[2];
- pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
- pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
- pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
-
- pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr;
- pDHCPMSG->OPT[k++] = 0x04;
- pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0];
- pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1];
- pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2];
- pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3];
-
- pDHCPMSG->OPT[k++] = dhcpServerIdentifier;
- pDHCPMSG->OPT[k++] = 0x04;
- pDHCPMSG->OPT[k++] = DHCP_SIP[0];
- pDHCPMSG->OPT[k++] = DHCP_SIP[1];
- pDHCPMSG->OPT[k++] = DHCP_SIP[2];
- pDHCPMSG->OPT[k++] = DHCP_SIP[3];
-
- pDHCPMSG->OPT[k++] = endOption;
-
- for (size_t i = k; i < OPT_SIZE; i++)
- {
- pDHCPMSG->OPT[i] = 0;
- }
-
- //send broadcasting packet
- uint8_t ip[4];
- ip[0] = 0xFF;
- ip[1] = 0xFF;
- ip[2] = 0xFF;
- ip[3] = 0xFF;
-
- DEBUG_PRINTF("\n> Send DHCP_DECLINE\n");
-
- sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT);
-}
-
-/* PARSE REPLY pDHCPMSG */
-int8_t parseDHCPMSG(void)
-{
- uint8_t type = 0;
- uint16_t len;
- if ((len = getSn_RX_RSR(DHCP_SOCKET)) > 0)
- {
- if (len > sizeof(RIP_MSG))
- {
- len = sizeof(RIP_MSG);
- }
-
- uint8_t svr_addr[6];
- uint16_t svr_port;
- len = recvfrom(DHCP_SOCKET, (uint8_t *)pDHCPMSG, len, svr_addr, &svr_port);
-
- DEBUG_PRINTF("DHCP message : %d.%d.%d.%d(%d) %d received. \n", svr_addr[0], svr_addr[1], svr_addr[2], svr_addr[3],svr_port, len);
-
- if (svr_port == DHCP_SERVER_PORT)
- {
- // compare mac address
- if ( (pDHCPMSG->chaddr[0] == DHCP_CHADDR[0]) && (pDHCPMSG->chaddr[1] == DHCP_CHADDR[1])
- && (pDHCPMSG->chaddr[2] == DHCP_CHADDR[2]) && (pDHCPMSG->chaddr[3] == DHCP_CHADDR[3])
- && (pDHCPMSG->chaddr[4] == DHCP_CHADDR[4]) && (pDHCPMSG->chaddr[5] == DHCP_CHADDR[5])
- )
- {
- const uint8_t *p = (uint8_t *)(&pDHCPMSG->op);
- p = p + 240; // 240 = sizeof(RIP_MSG) + MAGIC_COOKIE size in RIP_MSG.opt - sizeof(RIP_MSG.opt)
- const uint8_t * const e = p + (len - 240);
-
- while (p < e)
- {
- switch (*p )
- {
- case endOption :
- p = e; // for break while(p < e)
- break;
- case padOption :
- p++;
- break;
- case dhcpMessageType :
- p++;
- p++;
- type = *p++;
- break;
- case subnetMask :
- p++;
- p++;
- DHCP_allocated_sn[0] = *p++;
- DHCP_allocated_sn[1] = *p++;
- DHCP_allocated_sn[2] = *p++;
- DHCP_allocated_sn[3] = *p++;
- break;
- case routersOnSubnet :
- {
- p++;
- const uint8_t opt_len = *p++;
- DHCP_allocated_gw[0] = *p++;
- DHCP_allocated_gw[1] = *p++;
- DHCP_allocated_gw[2] = *p++;
- DHCP_allocated_gw[3] = *p++;
- p = p + (opt_len - 4);
- }
- break;
- case dns :
- {
- p++;
- const uint8_t opt_len = *p++;
- DHCP_allocated_dns[0] = *p++;
- DHCP_allocated_dns[1] = *p++;
- DHCP_allocated_dns[2] = *p++;
- DHCP_allocated_dns[3] = *p++;
- p = p + (opt_len - 4);
- }
- break;
- case dhcpIPaddrLeaseTime :
- {
- p++;
- p++;
- dhcp_lease_time = *p++;
- dhcp_lease_time = (dhcp_lease_time << 8) + *p++;
- dhcp_lease_time = (dhcp_lease_time << 8) + *p++;
- dhcp_lease_time = (dhcp_lease_time << 8) + *p++;
-#if 0 //#ifdef _DHCP_DEBUG_
- dhcp_lease_time = 10;
-#endif
- }
- break;
- case dhcpServerIdentifier :
- {
- p++;
- p++;
- DHCP_SIP[0] = *p++;
- DHCP_SIP[1] = *p++;
- DHCP_SIP[2] = *p++;
- DHCP_SIP[3] = *p++;
- }
- break;
-
- default :
- {
- p++;
- const uint8_t opt_len = *p++;
- p += opt_len;
- }
- break;
- } // switch
- } // while
- } // if
- } // if
- } // if
- return type;
-}
-
-DhcpRunResult DHCP_run(void)
-{
- if (dhcp_state == STATE_DHCP_STOP)
- {
- return DhcpRunResult::DHCP_STOPPED;
- }
-
- if (getSn_SR(DHCP_SOCKET) != SOCK_UDP)
- {
- socket(DHCP_SOCKET, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00);
- }
-
- DhcpRunResult ret = DhcpRunResult::DHCP_RUNNING;
- const uint8_t type = parseDHCPMSG();
-
- switch (dhcp_state)
- {
- case STATE_DHCP_INIT:
- DHCP_allocated_ip[0] = 0;
- DHCP_allocated_ip[1] = 0;
- DHCP_allocated_ip[2] = 0;
- DHCP_allocated_ip[3] = 0;
- send_DHCP_DISCOVER();
- dhcp_state = STATE_DHCP_DISCOVER;
- break;
-
- case STATE_DHCP_DISCOVER:
- if (type == DHCP_OFFER)
- {
- DEBUG_PRINTF("> Receive DHCP_OFFER\n");
- DHCP_allocated_ip[0] = pDHCPMSG->yiaddr[0];
- DHCP_allocated_ip[1] = pDHCPMSG->yiaddr[1];
- DHCP_allocated_ip[2] = pDHCPMSG->yiaddr[2];
- DHCP_allocated_ip[3] = pDHCPMSG->yiaddr[3];
-
- send_DHCP_REQUEST();
- dhcp_state = STATE_DHCP_REQUEST;
- }
- else
- {
- ret = check_DHCP_timeout();
- }
- break;
-
- case STATE_DHCP_REQUEST :
- if (type == DHCP_ACK)
- {
- DEBUG_PRINTF("> Receive DHCP_ACK\n");
- if (check_DHCP_leasedIP())
- {
- // Network info assignment from DHCP
- dhcp_ip_assign();
- reset_DHCP_timeout();
- dhcp_state = STATE_DHCP_LEASED;
- ret = DhcpRunResult::DHCP_IP_ASSIGN;
- }
- else
- {
- // IP address conflict occurred
- reset_DHCP_timeout();
- dhcp_ip_conflict();
- dhcp_state = STATE_DHCP_INIT;
- }
- }
- else if (type == DHCP_NAK)
- {
- DEBUG_PRINTF("> Receive DHCP_NACK\n");
- reset_DHCP_timeout();
- dhcp_state = STATE_DHCP_DISCOVER;
- }
- else
- {
- ret = check_DHCP_timeout();
- }
- break;
-
- case STATE_DHCP_LEASED :
- ret = DhcpRunResult::DHCP_IP_LEASED;
- if ((dhcp_lease_time != INFINITE_LEASETIME) && ((dhcp_lease_time/2) < dhcp_tick_1s))
- {
- DEBUG_PRINTF("> Maintains the IP address \n");
- OLD_allocated_ip[0] = DHCP_allocated_ip[0];
- OLD_allocated_ip[1] = DHCP_allocated_ip[1];
- OLD_allocated_ip[2] = DHCP_allocated_ip[2];
- OLD_allocated_ip[3] = DHCP_allocated_ip[3];
-
- DHCP_XID++;
-
- send_DHCP_REQUEST();
- reset_DHCP_timeout();
- dhcp_state = STATE_DHCP_REREQUEST;
- }
- break;
-
- case STATE_DHCP_REREQUEST :
- ret = DhcpRunResult::DHCP_IP_LEASED;
- if (type == DHCP_ACK)
- {
- dhcp_retry_count = 0;
- if (OLD_allocated_ip[0] != DHCP_allocated_ip[0] ||
- OLD_allocated_ip[1] != DHCP_allocated_ip[1] ||
- OLD_allocated_ip[2] != DHCP_allocated_ip[2] ||
- OLD_allocated_ip[3] != DHCP_allocated_ip[3])
- {
- ret = DhcpRunResult::DHCP_IP_CHANGED;
- dhcp_ip_update();
- DEBUG_PRINTF(">IP changed.\n");
- }
- else
- {
- DEBUG_PRINTF(">IP is continued.\n");
- }
- reset_DHCP_timeout();
- dhcp_state = STATE_DHCP_LEASED;
- }
- else if (type == DHCP_NAK)
- {
- DEBUG_PRINTF("> Receive DHCP_NACK, Failed to maintain ip\n");
- reset_DHCP_timeout();
- dhcp_state = STATE_DHCP_DISCOVER;
- }
- else
- {
- ret = check_DHCP_timeout();
- }
- break;
-
- default :
- break;
- }
-
- return ret;
-}
-
-void DHCP_stop(void)
-{
- close(DHCP_SOCKET);
- dhcp_state = STATE_DHCP_STOP;
-}
-
-DhcpRunResult check_DHCP_timeout(void)
-{
- DhcpRunResult ret = DhcpRunResult::DHCP_RUNNING;
-
- if (dhcp_retry_count < MAX_DHCP_RETRY)
- {
- if (dhcp_tick_next < dhcp_tick_1s)
- {
- switch ( dhcp_state )
- {
- case STATE_DHCP_DISCOVER :
- DEBUG_PRINTF("<<timeout>> state : STATE_DHCP_DISCOVER\n");
- send_DHCP_DISCOVER();
- break;
-
- case STATE_DHCP_REQUEST :
- DEBUG_PRINTF("<<timeout>> state : STATE_DHCP_REQUEST\n");
-
- send_DHCP_REQUEST();
- break;
-
- case STATE_DHCP_REREQUEST :
- DEBUG_PRINTF("<<timeout>> state : STATE_DHCP_REREQUEST\n");
-
- send_DHCP_REQUEST();
- break;
-
- default :
- break;
- }
-
- dhcp_tick_1s = 0;
- dhcp_tick_next = dhcp_tick_1s + DHCP_WAIT_TIME;
- dhcp_retry_count++;
- }
- }
- else
- { // exceeded retry count
- switch(dhcp_state)
- {
- case STATE_DHCP_DISCOVER:
- dhcp_state = STATE_DHCP_INIT;
- ret = DhcpRunResult::DHCP_FAILED;
- break;
- case STATE_DHCP_REQUEST:
- case STATE_DHCP_REREQUEST:
- send_DHCP_DISCOVER();
- dhcp_state = STATE_DHCP_DISCOVER;
- break;
- default :
- break;
- }
- reset_DHCP_timeout();
- }
- return ret;
-}
-
-bool check_DHCP_leasedIP(void)
-{
- uint8_t tmp;
- int32_t ret;
-
- //WIZchip RCR value changed for ARP Timeout count control
- tmp = getRCR();
- setRCR(0x03);
-
- // IP conflict detection : ARP request - ARP reply
- // Broadcasting ARP Request for check the IP conflict using UDP sendto() function
- // TODO the following takes 620ms to time out - hanging for this long isn't very nice
- ret = sendto(DHCP_SOCKET, (const uint8_t *)"CHECK_IP_CONFLICT", 17, DHCP_allocated_ip, 5000);
-
- // RCR value restore
- setRCR(tmp);
-
- if (ret == SOCKERR_TIMEOUT)
- {
- // UDP send Timeout occurred : allocated IP address is unique, DHCP Success
- DEBUG_PRINTF("\n> Check leased IP - OK\n");
- return true;
- }
- else
- {
- // Received ARP reply or etc : IP address conflict occur, DHCP Failed
- send_DHCP_DECLINE();
-
- ret = dhcp_tick_1s;
- //TODO can't tolerate a 1 to 2 second wait here
- while((dhcp_tick_1s - ret) < 2) { } // wait for 1s over; wait to complete to send DECLINE message;
-
- return false;
- }
-}
-
-void DHCP_init(uint8_t s, const char *hname)
-{
- strncpy(HOST_NAME, hname, sizeof(HOST_NAME));
- HOST_NAME[sizeof(HOST_NAME) - 1] = 0;
-
- uint8_t zeroip[4] = {0,0,0,0};
- getSHAR(DHCP_CHADDR);
- DEBUG_PRINTF("MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", DHCP_CHADDR[0], DHCP_CHADDR[1], DHCP_CHADDR[2], DHCP_CHADDR[3], DHCP_CHADDR[4], DHCP_CHADDR[5]);
-
- if ((DHCP_CHADDR[0] | DHCP_CHADDR[1] | DHCP_CHADDR[2] | DHCP_CHADDR[3] | DHCP_CHADDR[4] | DHCP_CHADDR[5]) == 0x00)
- {
- // assing temporary mac address, you should be set SHAR before call this function.
- DHCP_CHADDR[0] = 0x00;
- DHCP_CHADDR[1] = 0x08;
- DHCP_CHADDR[2] = 0xdc;
- DHCP_CHADDR[3] = 0x00;
- DHCP_CHADDR[4] = 0x00;
- DHCP_CHADDR[5] = 0x00;
- setSHAR(DHCP_CHADDR);
- }
-
- DHCP_SOCKET = s; // SOCK_DHCP
- DHCP_XID = 0x12345678;
-
- // WIZchip Netinfo Clear
- setSIPR(zeroip);
- setSIPR(zeroip);
- setGAR(zeroip);
-
- reset_DHCP_timeout();
- dhcp_state = STATE_DHCP_INIT;
-}
-
-/* Rset the DHCP timeout count and retry count. */
-void reset_DHCP_timeout(void)
-{
- dhcp_tick_1s = 0;
- dhcp_tick_next = DHCP_WAIT_TIME;
- dhcp_retry_count = 0;
-}
-
-void DHCP_time_handler(void)
-{
- dhcp_tick_1s++;
-}
-
-void getIPfromDHCP(uint8_t* ip)
-{
- ip[0] = DHCP_allocated_ip[0];
- ip[1] = DHCP_allocated_ip[1];
- ip[2] = DHCP_allocated_ip[2];
- ip[3] = DHCP_allocated_ip[3];
-}
-
-void getGWfromDHCP(uint8_t* ip)
-{
- ip[0] =DHCP_allocated_gw[0];
- ip[1] =DHCP_allocated_gw[1];
- ip[2] =DHCP_allocated_gw[2];
- ip[3] =DHCP_allocated_gw[3];
-}
-
-void getSNfromDHCP(uint8_t* ip)
-{
- ip[0] = DHCP_allocated_sn[0];
- ip[1] = DHCP_allocated_sn[1];
- ip[2] = DHCP_allocated_sn[2];
- ip[3] = DHCP_allocated_sn[3];
-}
-
-void getDNSfromDHCP(uint8_t* ip)
-{
- ip[0] = DHCP_allocated_dns[0];
- ip[1] = DHCP_allocated_dns[1];
- ip[2] = DHCP_allocated_dns[2];
- ip[3] = DHCP_allocated_dns[3];
-}
-
-uint32_t getDHCPLeasetime(void)
-{
- return dhcp_lease_time;
-}
-
-// End
diff --git a/src/Network2/W5500/Wiznet/Internet/DHCP/dhcp.h b/src/Network2/W5500/Wiznet/Internet/DHCP/dhcp.h
deleted file mode 100644
index 4f238b6e..00000000
--- a/src/Network2/W5500/Wiznet/Internet/DHCP/dhcp.h
+++ /dev/null
@@ -1,144 +0,0 @@
-//*****************************************************************************
-//
-//! \file dhcp.h
-//! \brief DHCP APIs Header file.
-//! \details Processig DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE.
-//! \version 1.1.0
-//! \date 2013/11/18
-//! \par Revision history
-//! <2013/11/18> 1st Release
-//! <2012/12/20> V1.1.0
-//! 1. Move unreferenced DEFINE to dhcp.c
-//! <2012/12/26> V1.1.1
-//! \author Eric Jung & MidnightCow
-//! \copyright
-//!
-//! Copyright (c) 2013, WIZnet Co., LTD.
-//! All rights reserved.
-//!
-//! Redistribution and use in source and binary forms, with or without
-//! modification, are permitted provided that the following conditions
-//! are met:
-//!
-//! * Redistributions of source code must retain the above copyright
-//! notice, this list of conditions and the following disclaimer.
-//! * Redistributions in binary form must reproduce the above copyright
-//! notice, this list of conditions and the following disclaimer in the
-//! documentation and/or other materials provided with the distribution.
-//! * Neither the name of the <ORGANIZATION> nor the names of its
-//! contributors may be used to endorse or promote products derived
-//! from this software without specific prior written permission.
-//!
-//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-//! THE POSSIBILITY OF SUCH DAMAGE.
-//
-//*****************************************************************************
-#ifndef _DHCP_H_
-#define _DHCP_H_
-
-/* Retry to processing DHCP */
-#define MAX_DHCP_RETRY 2 ///< Maxium retry count
-#define DHCP_WAIT_TIME 10 ///< Wait Time 10s
-
-
-/* UDP port numbers for DHCP */
-#define DHCP_SERVER_PORT 67 ///< DHCP server port number
-#define DHCP_CLIENT_PORT 68 ///< DHCP client port number
-
-
-#define MAGIC_COOKIE 0x63825363 ///< Any number. You can be modified it any number
-
-#define DCHP_HOST_NAME "DuetEthernet"
-
-/*
- * @brief return value of @ref DHCP_run()
- */
-enum class DhcpRunResult : uint8_t
-{
- DHCP_FAILED = 0, ///< Processing Fail
- DHCP_RUNNING, ///< Processing DHCP protocol
- DHCP_IP_ASSIGN, ///< First Occupy IP from DHPC server (if cbfunc == null, act as default default_ip_assign)
- DHCP_IP_CHANGED, ///< Change IP address by new ip from DHCP (if cbfunc == null, act as default default_ip_update)
- DHCP_IP_LEASED, ///< Stand by
- DHCP_STOPPED ///< Stop processing DHCP protocol
-};
-
-/*
- * @brief DHCP client initialization (outside of the main loop)
- * @param s - socket number
- * @param hname - null-terminated host name string
- */
-void DHCP_init(uint8_t s, const char *hname);
-
-/*
- * @brief DHCP 1s Tick Timer handler
- * @note SHOULD BE register to your system 1s Tick timer handler
- */
-void DHCP_time_handler(void);
-
-/*
- * @brief Register call back function
- * @param ip_assign - callback func when IP is assigned from DHCP server first
- * @param ip_update - callback func when IP is changed
- * @prarm ip_conflict - callback func when the assigned IP is conflict with others.
- */
-void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void));
-
-/*
- * @brief DHCP client in the main loop
- * @return The value is as the follow \n
- * @ref DHCP_FAILED \n
- * @ref DHCP_RUNNING \n
- * @ref DHCP_IP_ASSIGN \n
- * @ref DHCP_IP_CHANGED \n
- * @ref DHCP_IP_LEASED \n
- * @ref DHCP_STOPPED \n
- *
- * @note This function is always called by you main task.
- */
-DhcpRunResult DHCP_run(void);
-
-/*
- * @brief Stop DHCP processing
- * @note If you want to restart. call DHCP_init() and DHCP_run()
- */
-void DHCP_stop(void);
-
-/* Get Network information assigned from DHCP server */
-/*
- * @brief Get IP address
- * @param ip - IP address to be returned
- */
-void getIPfromDHCP(uint8_t* ip);
-/*
- * @brief Get Gateway address
- * @param ip - Gateway address to be returned
- */
-void getGWfromDHCP(uint8_t* ip);
-/*
- * @brief Get Subnet mask value
- * @param ip - Subnet mask to be returned
- */
-void getSNfromDHCP(uint8_t* ip);
-/*
- * @brief Get DNS address
- * @param ip - DNS address to be returned
- */
-void getDNSfromDHCP(uint8_t* ip);
-
-/*
- * @brief Get the leased time by DHCP sever
- * @return unit 1s
- */
-uint32_t getDHCPLeasetime(void);
-
-#endif /* _DHCP_H_ */
diff --git a/src/Network2/W5500/Wiznet/README.md b/src/Network2/W5500/Wiznet/README.md
deleted file mode 100644
index 656a263b..00000000
--- a/src/Network2/W5500/Wiznet/README.md
+++ /dev/null
@@ -1,54 +0,0 @@
-#ioLibrary Driver
-The ioLibrary means “Internet Offload Library” for WIZnet chip. It includes drivers and application protocols.
-The driver (ioLibrary) can be used for the application design of WIZnet TCP/IP chips as [W5500](http://wizwiki.net/wiki/doku.php?id=products:w5500:start), W5300, W5200 and W5100.
-
-##ioLibrary
-This driver provides the Berkeley Socket type APIs.
-- Directory Structure
-<!-- ioLibrary pic -->
-![ioLibrary](http://wizwiki.net/wiki/lib/exe/fetch.php?media=products:w5500:iolibrary_bsd.jpg "ioLibrary")
-
-- Ethernet : SOCKET APIs like BSD & WIZCHIP([W5500](http://wizwiki.net/wiki/doku.php?id=products:w5500:start) / W5300 / W5200 / W5100) Driver
-- Internet :
- - DHCP client
- - DNS client
- - FTP client
- - FTP server
- - SNMP agent/trap
- - SNTP client
- - TFTP client
- - HTTP server
- - MQTT Client
- - Others will be added.
-
-## How to add an ioLibrary in project through github site.
- - Example, refer to https://www.youtube.com/watch?v=mt815RBGdsA
- - [ioLibrary Doxygen doument](https://github.com/Wiznet/ioLibrary_Driver/blob/master/Ethernet/SOCKET_APIs_V2.0.chm) : Refer to **TODO** in this document
- - Define what chip is used in **wizchip_conf.h**
- - Define what Host I/F mode is used in **wizchip_conf.h**
-
-## Revision History
- * ioLibrary V3.1.0 Released : 05, Dec, 2016
- * Internet application protocol add to MQTT Client (using paho MQTT 3.11)
- * ioLibrary V3.0.3 Released : 03, May, 2016
- * In W5300, Fixed some compile errors in close(). Refer to M20160503
- * In close(), replace socket() with some command sequences.
- * ioLibrary V3.0.2 Released : 26, April, 2016
- * Applied the erratum #1 in close() of socket.c (Refer to A20160426)
- * ioLibrary V3.0.1 Released : 15, July, 2015
- * Bug fixed : In W5100, Fixed CS control problem in read/write buffer with SPI. Refer to M20150715.
- * ioLibrary V3.0 Released : 01, June, 2015
- * Add to W5300
- * Typing Error in comments
- * Refer to 20150601 in sources.
-
- * Type casting error Fixed : 09, April. 2015
- In socket.c, send() : Refer to M20150409
-
- * ioLibrary V2.0 released : April. 2015
- * Added to W5100, W5200
- * Correct to some typing error
- * Fixed the warning of type casting.
-
- * Last release : Nov. 2014
-
diff --git a/src/Networking/ESP8266WiFi/WiFiInterface.cpp b/src/Networking/ESP8266WiFi/WiFiInterface.cpp
index 14ba2f4d..564637d2 100644
--- a/src/Networking/ESP8266WiFi/WiFiInterface.cpp
+++ b/src/Networking/ESP8266WiFi/WiFiInterface.cpp
@@ -21,7 +21,7 @@ static_assert(SsidLength == SsidBufferLength, "SSID lengths in NetworkDefs.h and
// Define exactly one of the following as 1, the other as zero
-#if defined(DUET_WIFI)
+#if defined(DUET_NG)
// 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
@@ -121,12 +121,12 @@ static void EspTransferRequestIsr(CallbackParameter)
static inline void EnableEspInterrupt()
{
- attachInterrupt(EspTransferRequestPin, EspTransferRequestIsr, RISING, nullptr);
+ attachInterrupt(EspDataReadyPin, EspTransferRequestIsr, RISING, nullptr);
}
static inline void DisableEspInterrupt()
{
- detachInterrupt(EspTransferRequestPin);
+ detachInterrupt(EspDataReadyPin);
}
/*-----------------------------------------------------------------------------------*/
@@ -162,7 +162,7 @@ void WiFiInterface::Init()
SetIPAddress(DefaultIpAddress, DefaultNetMask, DefaultGateway);
- for (size_t i = 0; i < NumTcpSockets; ++i)
+ for (size_t i = 0; i < NumWiFiTcpSockets; ++i)
{
sockets[i]->Init(i);
}
@@ -389,7 +389,7 @@ void WiFiInterface::Start()
pinMode(SamTfrReadyPin, OUTPUT_LOW);
// Set up our data ready pin (ESP GPIO0) as an output and set it high ready to boot the ESP from flash
- pinMode(EspTransferRequestPin, OUTPUT_HIGH);
+ pinMode(EspDataReadyPin, OUTPUT_HIGH);
// GPIO2 also needs to be high to boot. It's connected to MISO on the SAM, so set the pullup resistor on that pin
pinMode(APIN_SPI_MISO, INPUT_PULLUP);
@@ -414,7 +414,7 @@ void WiFiInterface::Start()
pinMode(SamCsPin, INPUT);
// Set the data request pin to be an input
- pinMode(EspTransferRequestPin, INPUT_PULLUP);
+ pinMode(EspDataReadyPin, INPUT_PULLUP);
// The ESP takes about 300ms before it starts talking to us, so don't wait for it here, do that in Spin()
spiTxUnderruns = spiRxOverruns = 0;
@@ -472,7 +472,7 @@ void WiFiInterface::Spin(bool full)
{
// See if the ESP8266 has kept its pins at their stable values for long enough
const uint32_t now = millis();
- if (digitalRead(SamCsPin) && digitalRead(EspTransferRequestPin) && !digitalRead(APIN_SPI_SCK))
+ if (digitalRead(SamCsPin) && digitalRead(EspDataReadyPin) && !digitalRead(APIN_SPI_SCK))
{
if (now - lastTickMillis >= WiFiStableMillis)
{
@@ -522,7 +522,7 @@ void WiFiInterface::Spin(bool full)
case NetworkState::active:
if (full)
{
- if (espStatusChanged && digitalRead(EspTransferRequestPin))
+ if (espStatusChanged && digitalRead(EspDataReadyPin))
{
if (reprap.Debug(moduleNetwork))
{
@@ -573,7 +573,7 @@ void WiFiInterface::Spin(bool full)
break;
}
++currentSocket;
- if (currentSocket == NumTcpSockets)
+ if (currentSocket == NumWiFiTcpSockets)
{
currentSocket = 0;
}
@@ -582,7 +582,7 @@ void WiFiInterface::Spin(bool full)
// Either the current socket needs polling, or no sockets do but we must still poll one of them to get notified of any new connections
sockets[currentSocket]->Poll(full);
++currentSocket;
- if (currentSocket == NumTcpSockets)
+ if (currentSocket == NumWiFiTcpSockets)
{
currentSocket = 0;
}
@@ -607,7 +607,7 @@ void WiFiInterface::Spin(bool full)
break;
case NetworkState::changingMode:
- if (full && espStatusChanged && digitalRead(EspTransferRequestPin))
+ if (full && espStatusChanged && digitalRead(EspDataReadyPin))
{
GetNewStatus();
if (currentMode != WiFiState::connecting)
@@ -771,7 +771,7 @@ void WiFiInterface::Diagnostics(MessageType mtype)
}
}
platform.Message(mtype, "Socket states:");
- for (size_t i = 0; i < NumTcpSockets; i++)
+ for (size_t i = 0; i < NumWiFiTcpSockets; i++)
{
platform.MessageF(mtype, " %d", sockets[i]->State());
}
@@ -1093,6 +1093,15 @@ void WiFiInterface::UpdateHostname(const char *hostname)
}
}
+void WiFiInterface::SetMacAddress(const uint8_t mac[])
+{
+ for (size_t i = 0; i < 6; i++)
+ {
+ macAddress[i] = mac[i];
+ }
+ // TODO actually update the mac address on the wifi module. For now we don't support this.
+}
+
void WiFiInterface::InitSockets()
{
for (size_t i = 0; i < NumProtocols; ++i)
@@ -1107,7 +1116,7 @@ void WiFiInterface::InitSockets()
void WiFiInterface::TerminateSockets()
{
- for (SocketNumber skt = 0; skt < NumTcpSockets; ++skt)
+ for (SocketNumber skt = 0; skt < NumWiFiTcpSockets; ++skt)
{
sockets[skt]->Terminate();
}
@@ -1127,7 +1136,7 @@ void WiFiInterface::TerminateSockets(Port port)
// This is called to tell the network which sockets are active
void WiFiInterface::UpdateSocketStatus(uint16_t connectedSockets, uint16_t otherEndClosedSockets)
{
- for (size_t i = 0; i < NumTcpSockets; ++i)
+ for (size_t i = 0; i < NumWiFiTcpSockets; ++i)
{
if (((connectedSockets | otherEndClosedSockets) & (1u << i)) != 0)
{
@@ -1538,7 +1547,7 @@ int32_t WiFiInterface::SendCommand(NetworkCommand cmd, SocketNumber socketNum, u
// Wait for the ESP to be ready, with timeout
{
const uint32_t now = millis();
- while (!digitalRead(EspTransferRequestPin))
+ while (!digitalRead(EspDataReadyPin))
{
if (millis() - now > WiFiWaitReadyMillis)
{
@@ -1777,7 +1786,7 @@ void WiFiInterface::ResetWiFiForUpload(bool external)
pinMode(SamTfrReadyPin, OUTPUT_LOW);
// Set up our data ready pin (ESP GPIO0) as an output and set it low ready to boot the ESP from UART
- pinMode(EspTransferRequestPin, OUTPUT_LOW);
+ pinMode(EspDataReadyPin, OUTPUT_LOW);
// GPIO2 also needs to be high to boot up. It's connected to MISO on the SAM, so set the pullup resistor on that pin
pinMode(APIN_SPI_MISO, INPUT_PULLUP);
diff --git a/src/Networking/ESP8266WiFi/WiFiInterface.h b/src/Networking/ESP8266WiFi/WiFiInterface.h
index 9d4f54fa..35561f7c 100644
--- a/src/Networking/ESP8266WiFi/WiFiInterface.h
+++ b/src/Networking/ESP8266WiFi/WiFiInterface.h
@@ -60,6 +60,8 @@ public:
void UpdateHostname(const char *hostname) override;
const uint8_t *GetIPAddress() const override { return ipAddress; }
void SetIPAddress(const uint8_t ipAddress[], const uint8_t netmask[], const uint8_t gateway[]) override;
+ void SetMacAddress(const uint8_t mac[]) override;
+ const uint8_t *GetMacAddress() const override { return macAddress; }
void OpenDataPort(Port port) override;
void TerminateDataPort() override;
@@ -123,7 +125,7 @@ private:
WifiFirmwareUploader *uploader;
- WiFiSocket *sockets[NumTcpSockets];
+ WiFiSocket *sockets[NumWiFiTcpSockets];
size_t currentSocket;
Port portNumbers[NumProtocols]; // port number used for each protocol
@@ -140,6 +142,7 @@ private:
uint8_t ipAddress[4];
uint8_t netmask[4];
uint8_t gateway[4];
+ uint8_t macAddress[6];
char requestedSsid[SsidLength + 1];
char actualSsid[SsidLength + 1];
diff --git a/src/Networking/FirmwareUpdater.cpp b/src/Networking/FirmwareUpdater.cpp
index 3ee6bf97..ad8697cc 100644
--- a/src/Networking/FirmwareUpdater.cpp
+++ b/src/Networking/FirmwareUpdater.cpp
@@ -19,7 +19,7 @@
namespace FirmwareUpdater
{
const unsigned int WifiFirmwareModule = 1;
- const unsigned int WifiFilesModule = 2;
+ // Module 2 used to be the DWC binary file but is no longer used
const unsigned int WifiExternalFirmwareModule = 3;
// Check that the prerequisites are satisfied.
@@ -27,7 +27,7 @@ namespace FirmwareUpdater
bool CheckFirmwareUpdatePrerequisites(uint8_t moduleMap, const StringRef& reply)
{
#if HAS_WIFI_NETWORKING
- if ((moduleMap & (1 << WifiExternalFirmwareModule)) != 0 && (moduleMap & ((1 << WifiFirmwareModule) | (1 << WifiFilesModule))) != 0)
+ if ((moduleMap & (1 << WifiExternalFirmwareModule)) != 0 && (moduleMap & (1 << WifiFirmwareModule)) != 0)
{
reply.copy("Invalid combination of firmware update modules");
return false;
@@ -37,11 +37,6 @@ namespace FirmwareUpdater
reply.printf("File %s not found", WIFI_FIRMWARE_FILE);
return false;
}
- if ((moduleMap & (1 << WifiFilesModule)) != 0 && !reprap.GetPlatform().GetMassStorage()->FileExists(SYS_DIR, WIFI_WEB_FILE))
- {
- reply.printf("File %s not found", WIFI_WEB_FILE);
- return false;
- }
#endif
return true;
}
@@ -59,32 +54,29 @@ namespace FirmwareUpdater
void UpdateModule(unsigned int module)
{
#if HAS_WIFI_NETWORKING
- switch(module)
+# ifdef DUET_NG
+ if (reprap.GetPlatform().IsDuetWiFi())
{
- case WifiExternalFirmwareModule:
- reprap.GetNetwork().ResetWiFiForUpload(true);
- break;
-
- case WifiFirmwareModule:
+# endif
+ switch(module)
{
- WifiFirmwareUploader * const uploader = reprap.GetNetwork().GetWifiUploader();
- if (uploader != nullptr)
- {
- uploader->SendUpdateFile(WIFI_FIRMWARE_FILE, SYS_DIR, WifiFirmwareUploader::FirmwareAddress);
- }
- }
- break;
+ case WifiExternalFirmwareModule:
+ reprap.GetNetwork().ResetWiFiForUpload(true);
+ break;
- case WifiFilesModule:
- {
- WifiFirmwareUploader * const uploader = reprap.GetNetwork().GetWifiUploader();
- if (uploader != nullptr)
+ case WifiFirmwareModule:
{
- uploader->SendUpdateFile(WIFI_WEB_FILE, SYS_DIR, WifiFirmwareUploader::WebFilesAddress);
+ WifiFirmwareUploader * const uploader = reprap.GetNetwork().GetWifiUploader();
+ if (uploader != nullptr)
+ {
+ uploader->SendUpdateFile(WIFI_FIRMWARE_FILE, SYS_DIR, WifiFirmwareUploader::FirmwareAddress);
+ }
}
+ break;
}
- break;
+# ifdef DUET_NG
}
+# endif
#endif
}
}
diff --git a/src/Networking/LwipEthernet/LwipEthernetInterface.cpp b/src/Networking/LwipEthernet/LwipEthernetInterface.cpp
index 2e9034b3..9d129ecd 100644
--- a/src/Networking/LwipEthernet/LwipEthernetInterface.cpp
+++ b/src/Networking/LwipEthernet/LwipEthernetInterface.cpp
@@ -145,6 +145,8 @@ void LwipEthernetInterface::Init()
{
listeningPcbs[i] = nullptr;
}
+
+ memcpy(macAddress, platform.GetDefaultMacAddress(), sizeof(macAddress));
}
GCodeResult LwipEthernetInterface::EnableProtocol(NetworkProtocol protocol, int port, int secure, const StringRef& reply)
@@ -344,7 +346,7 @@ void LwipEthernetInterface::Start()
const char *hostname = reprap.GetNetwork().GetHostname();
// Allow the MAC address to be set only before LwIP is started...
- ethernet_configure_interface(platform.MACAddress(), hostname);
+ ethernet_configure_interface(platform.GetDefaultMacAddress(), hostname);
init_ethernet(DefaultIpAddress, DefaultNetMask, DefaultGateway);
// Initialise mDNS subsystem
@@ -542,16 +544,6 @@ int LwipEthernetInterface::EnableState() const
return (state == NetworkState::disabled) ? 0 : 1;
}
-bool LwipEthernetInterface::Lock()
-{
- return LockLWIP();
-}
-
-void LwipEthernetInterface::Unlock()
-{
- UnlockLWIP();
-}
-
bool LwipEthernetInterface::InNetworkStack() const
{
return lwipLocked;
@@ -622,6 +614,11 @@ void LwipEthernetInterface::UpdateHostname(const char *hostname)
}
}
+void LwipEthernetInterface::SetMacAddress(const uint8_t mac[])
+{
+ memcpy(macAddress, mac, sizeof(macAddress));
+}
+
void LwipEthernetInterface::OpenDataPort(Port port)
{
if (listeningPcbs[NumProtocols] != nullptr)
diff --git a/src/Networking/LwipEthernet/LwipEthernetInterface.h b/src/Networking/LwipEthernet/LwipEthernetInterface.h
index 4ffbb69b..c816e573 100644
--- a/src/Networking/LwipEthernet/LwipEthernetInterface.h
+++ b/src/Networking/LwipEthernet/LwipEthernetInterface.h
@@ -44,14 +44,6 @@ public:
GCodeResult DisableProtocol(NetworkProtocol protocol, const StringRef& reply) override;
GCodeResult ReportProtocols(const StringRef& reply) const override;
- // LwIP interfaces
- void ResetCallback();
- bool Lock();
- void Unlock();
-
- bool ConnectionEstablished(tcp_pcb *pcb);
-
- // Global settings
GCodeResult GetNetworkState(const StringRef& reply) override;
int EnableState() const override;
bool InNetworkStack() const override;
@@ -60,6 +52,11 @@ public:
void UpdateHostname(const char *hostname) override;
const uint8_t *GetIPAddress() const override;
void SetIPAddress(const uint8_t p_ipAddress[], const uint8_t p_netmask[], const uint8_t p_gateway[]) override;
+ void SetMacAddress(const uint8_t mac[]) override;
+ const uint8_t *GetMacAddress() const override { return macAddress; }
+
+ // LwIP interfaces
+ bool ConnectionEstablished(tcp_pcb *pcb);
void OpenDataPort(Port port) override;
void TerminateDataPort() override;
@@ -104,6 +101,8 @@ private:
bool activated;
bool initialised;
bool usingDhcp;
+
+ uint8_t macAddress[6];
};
#endif
diff --git a/src/Networking/Network.cpp b/src/Networking/Network.cpp
index 8a1637d5..3dd42c52 100644
--- a/src/Networking/Network.cpp
+++ b/src/Networking/Network.cpp
@@ -35,18 +35,24 @@
Network::Network(Platform& p) : platform(p), responders(nullptr), nextResponderToPoll(nullptr)
{
- // Create the network modules
-
#if defined(SAME70_TEST_BOARD)
interfaces[0] = new LwipEthernetInterface(p);
interfaces[1] = new WiFiInterface(p);
-#elif defined(DUET_WIFI)
- interfaces[0] = new WiFiInterface(p);
-#elif defined(DUET_ETHERNET) || defined(DUET_M)
+#elif defined(DUET_NG)
+ interfaces[0] = nullptr; // we set this up in Init()
+#elif defined(DUET_M)
interfaces[0] = new W5500Interface(p);
#else
# error Unknown board
#endif
+}
+
+// Note that Platform::Init() must be called before this to that Platform::IsDuetWiFi() returns the correct value
+void Network::Init()
+{
+#if defined(DUET_NG)
+ interfaces[0] = (platform.IsDuetWiFi()) ? static_cast<NetworkInterface*>(new WiFiInterface(platform)) : static_cast<NetworkInterface*>(new W5500Interface(platform));
+#endif
// Create the responders
for (size_t i = 0; i < NumTelnetResponders; ++i)
@@ -61,11 +67,7 @@ Network::Network(Platform& p) : platform(p), responders(nullptr), nextResponderT
{
responders = new HttpResponder(responders);
}
-}
-void Network::Init()
-{
- longWait = millis();
strcpy(hostname, DEFAULT_HOSTNAME);
NetworkBuffer::AllocateBuffers(NetworkBufferCount);
@@ -74,6 +76,8 @@ void Network::Init()
{
iface->Init();
}
+
+ longWait = millis();
}
GCodeResult Network::EnableProtocol(unsigned int interface, NetworkProtocol protocol, int port, int secure, const StringRef& reply)
@@ -161,7 +165,7 @@ const char* Network::GetWiFiServerVersion() const
}
#endif
- return "(not defined)";
+ return "no WiFi interface";
}
WifiFirmwareUploader *Network::GetWifiUploader() const
@@ -374,6 +378,24 @@ void Network::SetHostname(const char *name)
}
}
+// Net the MAC address. Pass -1 as the interface number to set the default MAC address for interfaces that don't have one.
+void Network::SetMacAddress(unsigned int interface, const uint8_t mac[])
+{
+ if (interface < NumNetworkInterfaces)
+ {
+ interfaces[interface]->SetMacAddress(mac);
+ }
+}
+
+const uint8_t *Network::GetMacAddress(unsigned int interface) const
+{
+ if (interface >= NumNetworkInterfaces)
+ {
+ interface = 0;
+ }
+ return interfaces[interface]->GetMacAddress();
+}
+
// Find a responder to process a new connection
bool Network::FindResponder(Socket *skt, NetworkProtocol protocol)
{
diff --git a/src/Networking/Network.h b/src/Networking/Network.h
index c90be5bd..6cd2d268 100644
--- a/src/Networking/Network.h
+++ b/src/Networking/Network.h
@@ -66,9 +66,10 @@ public:
int EnableState(unsigned int interface) const;
void SetEthernetIPAddress(const uint8_t p_ipAddress[], const uint8_t p_netmask[], const uint8_t p_gateway[]);
-
const char *GetHostname() const { return hostname; }
void SetHostname(const char *name);
+ void SetMacAddress(unsigned int interface, const uint8_t mac[]);
+ const uint8_t *GetMacAddress(unsigned int interface) const;
bool FindResponder(Socket *skt, NetworkProtocol protocol);
diff --git a/src/Networking/NetworkBuffer.h b/src/Networking/NetworkBuffer.h
index a15306be..feb4162c 100644
--- a/src/Networking/NetworkBuffer.h
+++ b/src/Networking/NetworkBuffer.h
@@ -86,12 +86,8 @@ private:
NetworkBuffer *next;
size_t dataLength;
size_t readPointer;
-#ifdef DUET_WIFI
- // When doing unaligned transfers on the WiFi interface, up to 3 extra bytes may be returned
+ // When doing unaligned transfers on the WiFi interface, up to 3 extra bytes may be returned, hence the +1 in the following
uint32_t data32[bufferSize/sizeof(uint32_t) + 1]; // 32-bit aligned buffer so we can do direct DMA
-#else
- uint32_t data32[bufferSize/sizeof(uint32_t)]; // 32-bit aligned buffer so we can do direct DMA
-#endif
static NetworkBuffer *freelist;
};
diff --git a/src/Networking/NetworkInterface.h b/src/Networking/NetworkInterface.h
index 451b2edd..a292d34b 100644
--- a/src/Networking/NetworkInterface.h
+++ b/src/Networking/NetworkInterface.h
@@ -35,6 +35,8 @@ public:
virtual const uint8_t *GetIPAddress() const = 0;
virtual void SetIPAddress(const uint8_t p_ipAddress[], const uint8_t p_netmask[], const uint8_t p_gateway[]) = 0;
+ virtual void SetMacAddress(const uint8_t mac[]) = 0;
+ virtual const uint8_t *GetMacAddress() const = 0;
virtual void UpdateHostname(const char *hostname) = 0;
diff --git a/src/Networking/W5500Ethernet/W5500Interface.cpp b/src/Networking/W5500Ethernet/W5500Interface.cpp
index 511cc824..27cf6185 100644
--- a/src/Networking/W5500Ethernet/W5500Interface.cpp
+++ b/src/Networking/W5500Ethernet/W5500Interface.cpp
@@ -40,6 +40,7 @@ void W5500Interface::Init()
lastTickMillis = millis();
SetIPAddress(DefaultIpAddress, DefaultNetMask, DefaultGateway);
+ memcpy(macAddress, platform.GetDefaultMacAddress(), sizeof(macAddress));
}
GCodeResult W5500Interface::EnableProtocol(NetworkProtocol protocol, int port, int secure, const StringRef& reply)
@@ -209,6 +210,15 @@ GCodeResult W5500Interface::GetNetworkState(const StringRef& reply)
return GCodeResult::ok;
}
+// Update the MAC address
+void W5500Interface::SetMacAddress(const uint8_t mac[])
+{
+ for (size_t i = 0; i < 6; i++)
+ {
+ macAddress[i] = mac[i];
+ }
+}
+
// Start up the network
void W5500Interface::Start()
{
@@ -226,7 +236,7 @@ void W5500Interface::Start()
wizchip_init(bufSizes, bufSizes);
- setSHAR(platform.MACAddress());
+ setSHAR(macAddress);
setSIPR(ipAddress);
setGAR(gateway);
setSUBR(netmask);
@@ -346,7 +356,7 @@ void W5500Interface::Spin(bool full)
// Move on to the next TCP socket for next time
++nextSocketToPoll;
- if (nextSocketToPoll == NumTcpSockets)
+ if (nextSocketToPoll == NumW5500TcpSockets)
{
nextSocketToPoll = 0;
}
@@ -439,7 +449,7 @@ void W5500Interface::DataPortClosing()
void W5500Interface::TerminateSockets()
{
- for (SocketNumber skt = 0; skt < NumTcpSockets; ++skt)
+ for (SocketNumber skt = 0; skt < NumW5500TcpSockets; ++skt)
{
sockets[skt]->Terminate();
}
diff --git a/src/Networking/W5500Ethernet/W5500Interface.h b/src/Networking/W5500Ethernet/W5500Interface.h
index cde7014d..69fa1433 100644
--- a/src/Networking/W5500Ethernet/W5500Interface.h
+++ b/src/Networking/W5500Ethernet/W5500Interface.h
@@ -24,7 +24,7 @@ const size_t NumHttpSockets = 4; // sockets 0-3 are for HTTP
const SocketNumber FtpSocketNumber = 4;
const SocketNumber FtpDataSocketNumber = 5; // TODO can we allocate this dynamically when required, to allow more http sockets most of the time?
const SocketNumber TelnetSocketNumber = 6;
-const size_t NumTcpSockets = 7;
+const size_t NumW5500TcpSockets = 7;
const SocketNumber DhcpSocketNumber = 7; // TODO can we allocate this dynamically when required, to allow more http sockets most of the time?
class Platform;
@@ -51,11 +51,13 @@ public:
GCodeResult GetNetworkState(const StringRef& reply) override;
int EnableState() const override;
bool InNetworkStack() const override { return false; }
- bool IsWiFiInterface() const override { return true; }
+ bool IsWiFiInterface() const override { return false; }
void UpdateHostname(const char *name) override { }
-
const uint8_t *GetIPAddress() const override { return ipAddress; }
+ void SetMacAddress(const uint8_t mac[]) override;
+ const uint8_t *GetMacAddress() const override { return macAddress; }
+
void OpenDataPort(Port port) override;
void TerminateDataPort() override;
void DataPortClosing() override;
@@ -84,11 +86,10 @@ private:
pre(protocol < NumProtocols);
void SetIPAddress(const uint8_t p_ipAddress[], const uint8_t p_netmask[], const uint8_t p_gateway[]);
-
Platform& platform;
uint32_t lastTickMillis;
- W5500Socket *sockets[NumTcpSockets];
+ W5500Socket *sockets[NumW5500TcpSockets];
size_t nextSocketToPoll; // next TCP socket number to poll for read/write operations
Port portNumbers[NumProtocols]; // port number used for each protocol
@@ -101,6 +102,7 @@ private:
uint8_t ipAddress[4];
uint8_t netmask[4];
uint8_t gateway[4];
+ uint8_t macAddress[6];
};
#endif
diff --git a/src/Platform.cpp b/src/Platform.cpp
index e116c335..28c014f2 100644
--- a/src/Platform.cpp
+++ b/src/Platform.cpp
@@ -352,6 +352,7 @@ Platform::Platform() :
//*******************************************************************************************************************
+// Initialise the Platform. Note: this is the first module to be initialised, so don't call other modules from here!
void Platform::Init()
{
// Deal with power first
@@ -385,14 +386,15 @@ void Platform::Init()
#endif
compatibility = marlin; // default to Marlin because the common host programs expect the "OK" response to commands
+
+ // File management
+ massStorage->Init();
+
ARRAY_INIT(ipAddress, DefaultIpAddress);
ARRAY_INIT(netMask, DefaultNetMask);
ARRAY_INIT(gateWay, DefaultGateway);
-#if defined(DUET_NG) && defined(DUET_WIFI)
- // The WiFi module has a unique MAC address, so we don't need a default
- memset(macAddress, 0xFF, sizeof(macAddress));
-#elif (defined(DUET_NG) && defined(DUET_ETHERNET)) || (defined(__SAME70Q21__))
+#if defined(DUET_NG) || defined(SAME70_TEST_BOARD)
// On the Duet Ethernet and SAM E70, use the unique chip ID as most of the MAC address.
// The unique ID is 128 bits long whereas the whole MAC address is only 48 bits,
// so we can't guarantee that each Duet will get a unique MAC address this way.
@@ -401,33 +403,27 @@ void Platform::Init()
memset(idBuf, 0, sizeof(idBuf));
DisableCache();
cpu_irq_disable();
- uint32_t rc = flash_read_unique_id(idBuf, 4);
+ const uint32_t rc = flash_read_unique_id(idBuf, 4);
cpu_irq_enable();
EnableCache();
if (rc == 0)
{
- memset(macAddress, 0, sizeof(macAddress));
- macAddress[0] = 0xBE; // use a fixed first byte with the locally-administered bit set
+ memset(defaultMacAddress, 0, sizeof(defaultMacAddress));
+ defaultMacAddress[0] = 0xBE; // use a fixed first byte with the locally-administered bit set
const uint8_t * const idBytes = reinterpret_cast<const uint8_t *>(idBuf);
for (size_t i = 0; i < 15; ++i)
{
- macAddress[(i % 5) + 1] ^= idBytes[i];
+ defaultMacAddress[(i % 5) + 1] ^= idBytes[i];
}
}
else
{
- ARRAY_INIT(macAddress, DefaultMacAddress);
+ ARRAY_INIT(defaultMacAddress, DefaultMacAddress);
}
}
-#else
- // Set the default MAC address. The user must change it manually if using more than one Duet 06 or 085 on a network.
- ARRAY_INIT(macAddress, DefaultMacAddress);
-#endif
-
- // File management
- massStorage->Init();
+#elif defined(DUET_06_085)
+ ARRAY_INIT(defaultMacAddress, DefaultMacAddress);
-#if defined(DUET_06_085)
// Motor current setting on Duet 0.6 and 0.8.5
InitI2c();
mcpExpansion.setMCP4461Address(0x2E); // not required for mcpDuet, as this uses the default address
@@ -436,19 +432,20 @@ void Platform::Init()
maxStepperDigipotVoltage = MAX_STEPPER_DIGIPOT_VOLTAGE;
stepperDacVoltageRange = STEPPER_DAC_VOLTAGE_RANGE;
stepperDacVoltageOffset = STEPPER_DAC_VOLTAGE_OFFSET;
-#endif
-
-#if defined(__ALLIGATOR__)
+#elif defined(__ALLIGATOR__)
pinMode(EthernetPhyResetPin, INPUT); // Init Ethernet Phy Reset Pin
+
// Alligator Init DAC for motor current vref
ARRAY_INIT(spiDacCS, SPI_DAC_CS);
dacAlligator.Init(spiDacCS[0]);
dacPiggy.Init(spiDacCS[1]);
// Get macaddress from EUI48 eeprom
eui48MacAddress.Init(Eui48csPin);
- if(! eui48MacAddress.getEUI48(macAddress)) {
- ARRAY_INIT(macAddress, DefaultMacAddress);
+ if (!eui48MacAddress.getEUI48(defaultMacAddress))
+ {
+ ARRAY_INIT(defaultMacAddress, DefaultMacAddress);
}
+
Microstepping::Init(); // Init Motor FAULT detect Pin
pinMode(ExpansionVoltageLevelPin, ExpansionVoltageLevel==3 ? OUTPUT_LOW : OUTPUT_HIGH); // Init Expansion Voltage Level Pin
pinMode(MotorFaultDetectPin,INPUT); // Init Motor FAULT detect Pin
@@ -3423,14 +3420,6 @@ void Platform::InitFans()
}
}
-void Platform::SetMACAddress(uint8_t mac[])
-{
- for (size_t i = 0; i < 6; i++)
- {
- macAddress[i] = mac[i];
- }
-}
-
void Platform::SetEndStopConfiguration(size_t axis, EndStopPosition esPos, EndStopInputType inputType)
{
endStopPos[axis] = esPos;
@@ -3920,9 +3909,13 @@ void Platform::SetBoardType(BoardType bt)
{
if (bt == BoardType::Auto)
{
-#if defined(__SAME70Q21__)
- board = BoardType::SAME70_TEST;
+#if defined(SAME70_TEST_BOARD)
+ board = BoardType::SamE70TestBoard;
#elif defined(DUET_NG)
+ // Get ready to test whether the Ethernet module is present, so that we avoid additional delays
+ pinMode(EspResetPin, OUTPUT_LOW); // reset the WiFi module or the W5500. We assume that this forces the ESP8266 UART output pin to high impedance.
+ pinMode(W5500ModuleSensePin, INPUT_PULLUP); // set our UART receive pin to be an input pin and enable the pullup
+
// Set up the VSSA sense pin. Older Duet WiFis don't have it connected, so we enable the pulldown resistor to keep it inactive.
pinMode(VssaSensePin, INPUT_PULLUP);
delayMicroseconds(10);
@@ -3936,11 +3929,15 @@ void Platform::SetBoardType(BoardType bt)
pinMode(VssaSensePin, INPUT);
}
-# if defined(DUET_WIFI)
- board = (vssaSenseWorking) ? BoardType::DuetWiFi_102 : BoardType::DuetWiFi_10;
-# elif defined(DUET_ETHERNET)
- board = (vssaSenseWorking) ? BoardType::DuetEthernet_102 : BoardType::DuetEthernet_10;
-# endif
+ // Test whether the Ethernet module is present
+ if (digitalRead(W5500ModuleSensePin)) // the Ethernet module has this pin grounded
+ {
+ board = (vssaSenseWorking) ? BoardType::DuetWiFi_102 : BoardType::DuetWiFi_10;
+ }
+ else
+ {
+ board = (vssaSenseWorking) ? BoardType::DuetEthernet_102 : BoardType::DuetEthernet_10;
+ }
#elif defined(DUET_M)
board = BoardType::DuetM_10;
#elif defined(DUET_06_085)
@@ -3949,6 +3946,7 @@ void Platform::SetBoardType(BoardType bt)
// So we enable the pullup (value 100K-150K) on pin 67 and read it, expecting a LOW on a 0.8.5 board and a HIGH on a 0.6 board.
// This may fail if anyone connects a load to the DAC0 pin on a Duet 0.6, hence we implement board selection in M115 as well.
pinMode(Dac0DigitalPin, INPUT_PULLUP);
+ delayMicroseconds(10);
board = (digitalRead(Dac0DigitalPin)) ? BoardType::Duet_06 : BoardType::Duet_085;
pinMode(Dac0DigitalPin, INPUT); // turn pullup off
#elif defined(__RADDS__)
@@ -3976,12 +3974,11 @@ const char* Platform::GetElectronicsString() const
{
switch (board)
{
-#if defined(__SAME70Q21__)
- case BoardType::SAME70_TEST: return "SAM E70 prototype 1";
-#elif defined(DUET_NG) && defined(DUET_WIFI)
+#if defined(SAME70_TEST_BOARD)
+ case BoardType::SamE70TestBoard: return "SAM E70 prototype 1";
+#elif defined(DUET_NG)
case BoardType::DuetWiFi_10: return "Duet WiFi 1.0 or 1.01";
case BoardType::DuetWiFi_102: return "Duet WiFi 1.02 or later";
-#elif defined(DUET_NG) && defined(DUET_ETHERNET)
case BoardType::DuetEthernet_10: return "Duet Ethernet 1.0 or 1.01";
case BoardType::DuetEthernet_102: return "Duet Ethernet 1.02 or later";
#elif defined(DUET_M)
@@ -4006,12 +4003,11 @@ const char* Platform::GetBoardString() const
{
switch (board)
{
-#if defined(__SAME70Q21__)
- case BoardType::SAME70_TEST: return "same70prototype1";
-#elif defined(DUET_NG) && defined(DUET_WIFI)
+#if defined(SAME70_TEST_BOARD)
+ case BoardType::SamE70TestBoard: return "same70prototype1";
+#elif defined(DUET_NG)
case BoardType::DuetWiFi_10: return "duetwifi10";
case BoardType::DuetWiFi_102: return "duetwifi102";
-#elif defined(DUET_NG) && defined(DUET_ETHERNET)
case BoardType::DuetEthernet_10: return "duetethernet10";
case BoardType::DuetEthernet_102: return "duetethernet102";
#elif defined(DUET_M)
@@ -4031,6 +4027,14 @@ const char* Platform::GetBoardString() const
}
}
+#ifdef DUET_NG
+// Return true if this is a Duet WiFi, false if it is a Duet Ethernet
+bool Platform::IsDuetWiFi() const
+{
+ return board == BoardType::DuetWiFi_10 || board == BoardType::DuetWiFi_102;
+}
+#endif
+
// User I/O and servo support
bool Platform::GetFirmwarePin(LogicalPin logicalPin, PinAccess access, Pin& firmwarePin, bool& invert)
{
diff --git a/src/Platform.h b/src/Platform.h
index 2ff3bb6e..0bb9c64e 100644
--- a/src/Platform.h
+++ b/src/Platform.h
@@ -111,14 +111,13 @@ constexpr uint32_t maxPidSpinDelay = 5000; // Maximum elapsed time in millisec
enum class BoardType : uint8_t
{
Auto = 0,
-#if defined(__SAME70Q21__)
- SAME70_TEST = 1
-#elif defined(DUET_NG) && defined(DUET_WIFI)
+#if defined(SAME70_TEST_BOARD)
+ SamE70TestBoard = 1
+#elif defined(DUET_NG)
DuetWiFi_10 = 1,
- DuetWiFi_102 = 2
-#elif defined(DUET_NG) && defined(DUET_ETHERNET)
- DuetEthernet_10 = 1,
- DuetEthernet_102 = 2
+ DuetWiFi_102 = 2,
+ DuetEthernet_10 = 3,
+ DuetEthernet_102 = 4
#elif defined(DUET_M)
DuetM_10 = 1,
#elif defined(DUET_06_085)
@@ -330,6 +329,12 @@ public:
const char* GetElectronicsString() const;
const char* GetBoardString() const;
+#ifdef DUET_NG
+ bool IsDuetWiFi() const;
+#endif
+
+ const uint8_t *GetDefaultMacAddress() const { return defaultMacAddress; }
+
// Timing
static uint32_t GetInterruptClocks() __attribute__ ((hot)); // Get the interrupt clock count
static uint32_t GetInterruptClocksInterruptsDisabled() __attribute__ ((hot)); // Get the interrupt clock count, when we know already that interrupts are disabled
@@ -358,8 +363,6 @@ public:
const uint8_t* NetMask() const;
void SetGateWay(uint8_t gw[]);
const uint8_t* GateWay() const;
- void SetMACAddress(uint8_t mac[]);
- const uint8_t* MACAddress() const;
void SetBaudRate(size_t chan, uint32_t br);
uint32_t GetBaudRate(size_t chan) const;
void SetCommsProperties(size_t chan, uint32_t cp);
@@ -694,7 +697,7 @@ private:
byte ipAddress[4];
byte netMask[4];
byte gateWay[4];
- uint8_t macAddress[6];
+ uint8_t defaultMacAddress[6];
Compatibility compatibility;
BoardType board;
@@ -1117,11 +1120,6 @@ inline const uint8_t* Platform::GateWay() const
return gateWay;
}
-inline const uint8_t* Platform::MACAddress() const
-{
- return macAddress;
-}
-
inline float Platform::GetPressureAdvance(size_t extruder) const
{
return (extruder < MaxExtruders) ? pressureAdvance[extruder] : 0.0;
diff --git a/src/RADDS/Network.h b/src/RADDS/Network.h
index b8aae90c..88c9771a 100644
--- a/src/RADDS/Network.h
+++ b/src/RADDS/Network.h
@@ -5,10 +5,10 @@
#include "MessageType.h"
#include "GCodes/GCodeResult.h"
-const uint8_t DefaultMacAddress[6] = { 0, 0, 0, 0, 0, 0 };
const uint8_t DefaultIpAddress[4] = { 0, 0, 0, 0 };
const uint8_t DefaultNetMask[4] = { 0, 0, 0, 0 };
const uint8_t DefaultGateway[4] = { 0, 0, 0, 0 };
+const uint8_t macAddress[6] = { 0, 0, 0, 0, 0, 0 };
const size_t SsidBufferLength = 32; // maximum characters in an SSID
@@ -32,6 +32,8 @@ public:
GCodeResult GetNetworkState(unsigned int interface, const StringRef& reply);
void SetEthernetIPAddress(const uint8_t p_ipAddress[], const uint8_t p_netmask[], const uint8_t p_gateway[]) { }
+ void SetMacAddress(unsigned int interface, const uint8_t mac[]) { }
+ const uint8_t *GetMacAddress(unsigned int interface) const { return macAddress; }
void SetHostname(const char *name) const { }
bool IsWiFiInterface(unsigned int interface) const { return false; }
diff --git a/src/RepRap.cpp b/src/RepRap.cpp
index 8340fe17..e3773711 100644
--- a/src/RepRap.cpp
+++ b/src/RepRap.cpp
@@ -94,7 +94,6 @@ RepRap::RepRap() : toolList(nullptr), currentTool(nullptr), lastWarningMillis(0)
printMonitor = new PrintMonitor(*platform, *gCodes);
SetPassword(DEFAULT_PASSWORD);
- SetName(DEFAULT_MACHINE_NAME);
message[0] = 0;
}
@@ -102,8 +101,9 @@ void RepRap::Init()
{
// All of the following init functions must execute reasonably quickly before the watchdog times us out
platform->Init();
- gCodes->Init();
network->Init();
+ SetName(DEFAULT_MACHINE_NAME); // network must be initialised before calling this because it calls SetHostName
+ gCodes->Init();
move->Init();
heat->Init();
#if SUPPORT_ROLAND
@@ -119,7 +119,7 @@ void RepRap::Init()
#if SUPPORT_12864_LCD
display->Init();
#endif
- active = true; // must do this before we start the network, else the watchdog may time out
+ active = true; // must do this before we start the network, else the watchdog may time out
platform->MessageF(UsbMessage, "%s Version %s dated %s\n", FIRMWARE_NAME, VERSION, DATE);
@@ -1234,9 +1234,19 @@ OutputBuffer *RepRap::GetConfigResponse()
#endif
response->catf("\",\"firmwareName\":\"%s\"", FIRMWARE_NAME);
response->catf(",\"firmwareVersion\":\"%s\"", VERSION);
+
#if HAS_WIFI_NETWORKING
- response->catf(",\"dwsVersion\":\"%s\"", network->GetWiFiServerVersion());
+ // If we have WiFi networking, send the WiFi module firmware version
+# ifdef DUET_NG
+ if (platform->IsDuetWiFi())
+ {
+# endif
+ response->catf(",\"dwsVersion\":\"%s\"", network->GetWiFiServerVersion());
+# ifdef DUET_NG
+ }
+# endif
#endif
+
response->catf(",\"firmwareDate\":\"%s\"", DATE);
// Motor idle parameters
diff --git a/src/SAME70_TEST/Pins_SAME70_TEST.h b/src/SAME70_TEST/Pins_SAME70_TEST.h
index 6c8f2b6b..ae46f694 100644
--- a/src/SAME70_TEST/Pins_SAME70_TEST.h
+++ b/src/SAME70_TEST/Pins_SAME70_TEST.h
@@ -1,9 +1,9 @@
#ifndef PINS_SAME70_H__
#define PINS_SAME70_H__
-# define FIRMWARE_NAME "RepRapFirmware for SAME70"
-# define DEFAULT_BOARD_TYPE BoardType::SAME70_TEST
-const size_t NumFirmwareUpdateModules = 4; // 3 modules, plus one for manual upload to WiFi module
+# define FIRMWARE_NAME "RepRapFirmware for SAME70"
+# define DEFAULT_BOARD_TYPE BoardType::SamE70TestBoard
+const size_t NumFirmwareUpdateModules = 4; // 3 modules, plus one for manual upload to WiFi module (module 2 not used)
# define IAP_FIRMWARE_FILE "SAME70Firmware.bin"
# define WIFI_FIRMWARE_FILE "DuetWiFiServer.bin"
# define WIFI_WEB_FILE "DuetWebControl.bin"
@@ -160,7 +160,7 @@ constexpr uint32_t IAP_FLASH_END = 0x0047FFFF; // we allow a full 64K on the SA
// Duet pin numbers to control the WiFi interface
constexpr Pin EspResetPin = 19; // Low on this in holds the WiFi module in reset (ESP_RESET)
constexpr Pin EspEnablePin = 48; // High to enable the WiFi module, low to power it down (ESP_CH_PD)
-constexpr Pin EspTransferRequestPin = 12; // Input from the WiFi module indicating that it wants to transfer data (ESP GPIO0)
+constexpr Pin EspDataReadyPin = 12; // Input from the WiFi module indicating that it wants to transfer data (ESP GPIO0)
constexpr Pin SamTfrReadyPin = 36; // Output from the SAM to the WiFi module indicating we can accept a data transfer (ESP GPIO4 via 7474)
constexpr Pin SamCsPin = 20; // SPI NPCS pin, input from WiFi module
diff --git a/src/Version.h b/src/Version.h
index 8a7eaed2..4554357a 100644
--- a/src/Version.h
+++ b/src/Version.h
@@ -13,7 +13,7 @@
#endif
#ifndef DATE
-# define DATE "2018-02-10 build 1"
+# define DATE "2018-02-12 build 1"
#endif
#define AUTHORS "reprappro, dc42, chrishamm, t3p3, dnewman"