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

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Crocker <dcrocker@eschertech.com>2016-03-30 15:29:13 +0300
committerDavid Crocker <dcrocker@eschertech.com>2016-03-30 15:29:13 +0300
commit818e14f98470c292d678aafbda5eefe5f5f60e21 (patch)
tree0bd7ff8716241329b8531f9473c94e1745ec905f /src
parent1356abd70713d99bee4e1fbb0e183edf6a6f5398 (diff)
Version 1.10+4
Updated with chrishamm's latest Network, Webserver and PrintMonitor module changes
Diffstat (limited to 'src')
-rw-r--r--src/Configuration.h2
-rw-r--r--src/Network.cpp65
-rw-r--r--src/Network.h4
-rw-r--r--src/PrintMonitor.cpp4
-rw-r--r--src/Webserver.cpp95
-rw-r--r--src/Webserver.h8
6 files changed, 98 insertions, 80 deletions
diff --git a/src/Configuration.h b/src/Configuration.h
index 3f9e4ce1..6aabd1d4 100644
--- a/src/Configuration.h
+++ b/src/Configuration.h
@@ -30,7 +30,7 @@ Licence: GPL
#endif
#ifndef VERSION
-#define VERSION "1.10+3"
+#define VERSION "1.10+4"
#endif
#ifndef DATE
diff --git a/src/Network.cpp b/src/Network.cpp
index 0e9154d8..51419ea4 100644
--- a/src/Network.cpp
+++ b/src/Network.cpp
@@ -124,9 +124,11 @@ void UnlockLWIP()
lwipLocked = false;
}
-// Callback functions for the EMAC driver
+// Callback functions for the EMAC driver and for LwIP
-// Callback to report when the link has gone up or down
+// Callback to report when the network interface has gone up or down.
+// Note that this is only a rough indicator and may not be called when
+// the IP address is changed on-the-fly!
static void ethernet_status_callback(struct netif *netif)
{
if (netif_is_up(netif))
@@ -134,10 +136,6 @@ static void ethernet_status_callback(struct netif *netif)
char ip[16];
ipaddr_ntoa_r(&(netif->ip_addr), ip, sizeof(ip));
reprap.GetPlatform()->MessageF(HOST_MESSAGE, "Network up, IP=%s\n", ip);
-
- // Do mDNS announcement here and not while the network is being initialised,
- // because the IP address may not be assigned at that time
- mdns_announce();
}
else
{
@@ -178,8 +176,6 @@ static void conn_err(void *arg, err_t err)
}
}
-/*-----------------------------------------------------------------------------------*/
-
static err_t conn_poll(void *arg, tcp_pcb *pcb)
{
ConnectionState *cs = (ConnectionState*)arg;
@@ -235,8 +231,6 @@ static err_t conn_poll(void *arg, tcp_pcb *pcb)
return ERR_OK;
}
-/*-----------------------------------------------------------------------------------*/
-
static err_t conn_sent(void *arg, tcp_pcb *pcb, u16_t len)
{
ConnectionState *cs = (ConnectionState*)arg;
@@ -259,8 +253,6 @@ static err_t conn_sent(void *arg, tcp_pcb *pcb, u16_t len)
return ERR_OK;
}
-/*-----------------------------------------------------------------------------------*/
-
static err_t conn_recv(void *arg, tcp_pcb *pcb, pbuf *p, err_t err)
{
ConnectionState *cs = (ConnectionState*)arg;
@@ -302,8 +294,6 @@ static err_t conn_recv(void *arg, tcp_pcb *pcb, pbuf *p, err_t err)
return ERR_OK;
}
-/*-----------------------------------------------------------------------------------*/
-
static err_t conn_accept(void *arg, tcp_pcb *pcb, err_t err)
{
LWIP_UNUSED_ARG(arg);
@@ -413,7 +403,7 @@ void Network::Spin()
return;
}
- if (state == NetworkActive)
+ if (state == NetworkObtainingIP || state == NetworkActive)
{
// Is the link still up?
if (!ethernet_link_established())
@@ -425,7 +415,7 @@ void Network::Spin()
return;
}
- // See if we can read any packets
+ // See if we can read any packets. They may include DHCP responses too
ethernet_task();
if (resetCallback)
{
@@ -433,6 +423,21 @@ void Network::Spin()
ethernet_set_rx_callback(&ethernet_rx_callback);
}
+ // Have we obtained a valid IP address yet?
+ if (state == NetworkObtainingIP)
+ {
+ const uint8_t *ip = ethernet_get_ipaddress();
+ if (ip[0] != 0 && ip[1] != 0 && ip[2] != 0 && ip[3] != 0)
+ {
+ // Yes - we're good to go now
+ state = NetworkActive;
+
+ // Send mDNS announcement so that some routers can perform hostname mapping
+ // if ths board is connected via a non-IGMP capable WiFi bridge (like the TP-Link WR701N)
+ mdns_announce();
+ }
+ }
+
// See if we can send anything
NetworkTransaction *transaction = writingTransactions;
if (transaction != nullptr && sendingConnection == nullptr)
@@ -476,7 +481,7 @@ void Network::Spin()
{
ethernet_set_configuration(platform->IPAddress(), platform->NetMask(), platform->GateWay());
}
- state = NetworkActive;
+ state = NetworkObtainingIP;
}
UnlockLWIP();
@@ -615,6 +620,7 @@ void Network::ConnectionClosed(ConnectionState* cs, bool closeConnection)
tcp_poll(pcb, nullptr, TCP_WRITE_TIMEOUT / TCP_SLOW_INTERVAL / TCP_MAX_SEND_RETRIES);
if (pcb != nullptr && closeConnection)
{
+ tcp_err(pcb, nullptr);
tcp_close(pcb);
}
cs->pcb = nullptr;
@@ -697,6 +703,7 @@ bool Network::ConnectionClosedGracefully(ConnectionState *cs)
tcp_sent(cs->pcb, nullptr);
tcp_recv(cs->pcb, nullptr);
tcp_poll(cs->pcb, nullptr, TCP_WRITE_TIMEOUT / TCP_SLOW_INTERVAL / TCP_MAX_SEND_RETRIES);
+ tcp_err(cs->pcb, nullptr);
tcp_close(cs->pcb);
cs->pcb = nullptr;
@@ -736,7 +743,7 @@ const uint8_t *Network::IPAddress() const
void Network::SetIPAddress(const uint8_t ipAddress[], const uint8_t netmask[], const uint8_t gateway[])
{
- if (state == NetworkActive)
+ if (state == NetworkObtainingIP || state == NetworkActive)
{
// This performs IP changes on-the-fly
ethernet_set_configuration(ipAddress, netmask, gateway);
@@ -878,22 +885,20 @@ uint16_t Network::GetHttpPort() const
void Network::SetHttpPort(uint16_t port)
{
- if (state == NetworkActive && port != httpPort)
+ if (port != httpPort)
{
- // Close old HTTP port
+ // Close the old HTTP PCB and create a new one
tcp_close(http_pcb);
+ httpPort = port;
+ httpd_init();
- // Create a new one for the new port
- tcp_pcb* pcb = tcp_new();
- tcp_bind(pcb, IP_ADDR_ANY, port);
- http_pcb = tcp_listen(pcb);
- tcp_accept(http_pcb, conn_accept);
-
- // Update mDNS services
+ // Update mDNS service
mdns_services[MDNS_HTTP_SERVICE_INDEX].port = port;
- mdns_announce();
+ if (state == NetworkActive)
+ {
+ mdns_announce();
+ }
}
- httpPort = port;
}
// Close FTP data port and purge associated PCB
@@ -1488,7 +1493,7 @@ void NetworkTransaction::Discard()
{
if (reprap.Debug(moduleNetwork))
{
- reprap.GetPlatform()->MessageF(HOST_MESSAGE, "Network: Discard() is handling a graceful disconnect for cs=%08x\n", (unsigned int)cs);
+ reprap.GetPlatform()->Message(HOST_MESSAGE, "Network: Discard() is handling a graceful disconnect\n");
}
reprap.GetNetwork()->ConnectionClosed(cs, false);
}
diff --git a/src/Network.h b/src/Network.h
index 9f80cb85..3cee3d45 100644
--- a/src/Network.h
+++ b/src/Network.h
@@ -15,6 +15,7 @@ Separated out from Platform.h by dc42 and extended by zpl
#include <climits>
#include "lwipopts.h"
+
#include "OutputMemory.h"
// This class handles the network - typically an Ethernet.
@@ -41,7 +42,6 @@ const uint16_t DEFAULT_HTTP_PORT = 80;
const uint16_t FTP_PORT = 21;
const uint16_t TELNET_PORT = 23;
-
/****************************************************************************************************/
struct tcp_pcb;
@@ -201,7 +201,7 @@ class Network
NetworkTransaction * volatile readyTransactions;
NetworkTransaction * volatile writingTransactions;
- enum { NetworkInactive, NetworkEstablishingLink, NetworkActive } state;
+ enum { NetworkInactive, NetworkEstablishingLink, NetworkObtainingIP, NetworkActive } state;
bool isEnabled;
volatile bool resetCallback;
char hostname[16]; // Limit DHCP hostname to 15 characters + terminating 0
diff --git a/src/PrintMonitor.cpp b/src/PrintMonitor.cpp
index 3d5f29f0..d1caa5d5 100644
--- a/src/PrintMonitor.cpp
+++ b/src/PrintMonitor.cpp
@@ -593,7 +593,7 @@ bool PrintMonitor::GetFileInfoResponse(const char *filename, OutputBuffer *&resp
if (filename != nullptr && filename[0] != 0)
{
GCodeFileInfo info;
- if (!GetFileInfo("0:/", filename, info))
+ if (!GetFileInfo(FS_PREFIX, filename, info))
{
// This may take a few runs...
return false;
@@ -681,7 +681,7 @@ void PrintMonitor::StopParsing(const char *filename)
{
if (parseState != notParsing && StringEquals(filenameBeingParsed, filename))
{
- if (!printingFileParsed)
+ if (filenameBeingPrinted[0] != 0 && !printingFileParsed)
{
// If this is the file we're parsing for internal purposes, don't bother with this request
return;
diff --git a/src/Webserver.cpp b/src/Webserver.cpp
index 02290b20..8106d2e7 100644
--- a/src/Webserver.cpp
+++ b/src/Webserver.cpp
@@ -89,7 +89,6 @@ const char* badEscapeResponse = "bad escape";
//********************************************************************************************
-
// Constructor and initialisation
Webserver::Webserver(Platform* p, Network *n) : platform(p), network(n), webserverActive(false)
{
@@ -103,6 +102,7 @@ void Webserver::Init()
// initialise the webserver class
longWait = platform->Time();
webserverActive = true;
+ readingConnection = nullptr;
// initialise all protocol handlers
httpInterpreter->ResetState();
@@ -110,7 +110,6 @@ void Webserver::Init()
telnetInterpreter->ResetState();
}
-
// Deal with input/output from/to the client (if any)
void Webserver::Spin()
{
@@ -136,7 +135,7 @@ void Webserver::Spin()
telnetInterpreter->Spin();
// See if we have new data to process
- currentTransaction = network->GetTransaction();
+ currentTransaction = network->GetTransaction(readingConnection);
if (currentTransaction != nullptr)
{
// Take care of different protocol types here
@@ -209,7 +208,8 @@ void Webserver::Spin()
// Process other messages (if we can)
else if (interpreter != httpInterpreter || httpInterpreter->IsReady())
{
- for(size_t i = 0; i < 500; i++)
+ readingConnection = currentTransaction->GetConnection();
+ for(size_t i = 0; i < TCP_MSS / 3; i++)
{
char c;
if (currentTransaction->Read(c))
@@ -218,20 +218,29 @@ void Webserver::Spin()
// calling either Commit(), Discard() or Defer()
if (interpreter->CharFromClient(c))
{
+ readingConnection = nullptr;
break;
}
}
else
{
- // We ran out of data before finding a complete request.
- // This happens when the incoming message length exceeds the TCP MSS.
- // Notify the current ProtocolInterpreter about this
+ // We ran out of data before finding a complete request. This happens when the incoming
+ // message length exceeds the TCP MSS. Notify the current ProtocolInterpreter about this,
+ // which will remove the current transaction too
interpreter->NoMoreDataAvailable();
+ readingConnection = nullptr;
break;
}
}
}
}
+ else if (readingConnection != nullptr)
+ {
+ // We failed to find a transaction for a reading connection.
+ // This should never happen, but if it does, terminate this connection instantly
+ platform->Message(HOST_MESSAGE, "Error: Transaction for reading connection not found\n");
+ readingConnection->Terminate();
+ }
network->Unlock(); // unlock LWIP again
}
platform->ClassReport(longWait);
@@ -364,6 +373,12 @@ void Webserver::ConnectionLost(const ConnectionState *cs)
platform->MessageF(HOST_MESSAGE, "ConnectionLost called for local port %d (remote port %d)\n", localPort, cs->GetRemotePort());
}
interpreter->ConnectionLost(cs);
+
+ // Don't process any more data from this connection if has gone down
+ if (readingConnection == cs)
+ {
+ readingConnection = nullptr;
+ }
}
@@ -405,6 +420,13 @@ void ProtocolInterpreter::ConnectionEstablished()
webserver->currentTransaction->Discard();
}
+void ProtocolInterpreter::NoMoreDataAvailable()
+{
+ // Request is not complete yet, but don't care. Interpreters that do not explicitly
+ // overwrite this method don't support more than one connected client anyway
+ webserver->currentTransaction->Discard();
+}
+
// Start writing to a new file
bool ProtocolInterpreter::StartUpload(FileStore *file, const char *fileName)
{
@@ -514,7 +536,7 @@ Webserver::HttpInterpreter::HttpInterpreter(Platform *p, Webserver *ws, Network
{
gcodeReadIndex = gcodeWriteIndex = 0;
gcodeReply = new OutputStack();
- processingDeferredRequest = false;
+ deferredRequestConnection = nullptr;
seq = 0;
}
@@ -877,11 +899,12 @@ bool Webserver::HttpInterpreter::IsReady()
}
// Are we still processing a deferred request?
- if (processingDeferredRequest && deferredRequestConnection == webserver->currentTransaction->GetConnection())
+ if (deferredRequestConnection == webserver->currentTransaction->GetConnection())
{
if (deferredRequestConnection->IsConnected())
{
- // Process more of this request
+ // Process more of this request. If it doesn't finish this time, it will be appended to the list
+ // of ready transactions again, which will ensure it can be processed later again
ProcessDeferredRequest();
}
else
@@ -997,9 +1020,9 @@ bool Webserver::HttpInterpreter::GetJsonResponse(const char* request, OutputBuff
}
else if (StringEquals(request, "fileinfo"))
{
- if (processingDeferredRequest)
+ if (deferredRequestConnection != nullptr)
{
- // Don't allow multiple requests to be processed at once
+ // Don't allow multiple deferred requests to be processed at once
webserver->currentTransaction->Defer(true);
}
else
@@ -1076,14 +1099,16 @@ void Webserver::HttpInterpreter::NoMoreDataAvailable()
void Webserver::HttpInterpreter::ConnectionLost(const ConnectionState *cs)
{
// Make sure deferred requests are cancelled
- if (processingDeferredRequest && deferredRequestConnection == cs)
+ if (deferredRequestConnection == cs)
{
- if (filenameBeingProcessed[0] != 0)
- {
- // Only stop the parsing process if the filename is valid
- reprap.GetPrintMonitor()->StopParsing(filenameBeingProcessed);
- }
- processingDeferredRequest = false;
+ reprap.GetPrintMonitor()->StopParsing(filenameBeingProcessed);
+ deferredRequestConnection = nullptr;
+ }
+
+ // If we couldn't read an entire request from a connection, reset our state here again
+ if (webserver->readingConnection == cs)
+ {
+ ResetState();
}
// Deal with aborted POST uploads. Note that we also check the remote port here,
@@ -1756,7 +1781,7 @@ void Webserver::HttpInterpreter::HandleGCodeReply(const char *reply)
void Webserver::HttpInterpreter::ProcessDeferredRequest()
{
OutputBuffer *jsonResponse = nullptr;
- bool doingDeferredRequest = processingDeferredRequest;
+ const ConnectionState *lastDeferredConnection = deferredRequestConnection;
// At the moment only file info requests are deferred.
// Parsing the file may take a while, so keep LwIP running while we're waiting
@@ -1765,13 +1790,14 @@ void Webserver::HttpInterpreter::ProcessDeferredRequest()
while (!network->Lock());
// Because LwIP was unlocked before, there is a chance that the ConnectionLost() call has already
- // stopped the file parsing. Check this special case
- NetworkTransaction *transaction = webserver->currentTransaction;
- if (doingDeferredRequest == processingDeferredRequest)
+ // stopped the file parsing. Check this special case here
+ if (lastDeferredConnection == deferredRequestConnection)
{
- processingDeferredRequest = !gotFileInfo;
+ NetworkTransaction *transaction = webserver->currentTransaction;
if (gotFileInfo)
{
+ deferredRequestConnection = nullptr;
+
// Got it - send the response now
transaction->Write("HTTP/1.1 200 OK\n");
transaction->Write("Cache-Control: no-cache, no-store, must-revalidate\n");
@@ -1790,9 +1816,13 @@ void Webserver::HttpInterpreter::ProcessDeferredRequest()
transaction->Defer(false);
}
}
+ else
+ {
+ // Clean up again if we cannot send the response at all
+ OutputBuffer::ReleaseAll(jsonResponse);
+ }
}
-
//********************************************************************************************
//
//************************* FTP interpreter for the Webserver class **************************
@@ -1954,12 +1984,6 @@ void Webserver::FtpInterpreter::ResetState()
state = idle;
}
-void Webserver::FtpInterpreter::NoMoreDataAvailable()
-{
- clientPointer = 0;
- SendReply(422, "Incomplete or too long request", true);
-}
-
bool Webserver::FtpInterpreter::DoingFastUpload() const
{
return (IsUploading() && webserver->currentTransaction->GetLocalPort() == network->GetDataPort());
@@ -2572,15 +2596,6 @@ void Webserver::TelnetInterpreter::ResetState()
clientPointer = 0;
}
-void Webserver::TelnetInterpreter::NoMoreDataAvailable()
-{
- clientPointer = 0;
-
- NetworkTransaction *transaction = webserver->currentTransaction;
- transaction->Write("Invalid or too long request\r\n");
- transaction->Commit(true);
-}
-
void Webserver::TelnetInterpreter::ProcessLine()
{
NetworkTransaction *transaction = network->GetTransaction();
diff --git a/src/Webserver.h b/src/Webserver.h
index 6f554c3b..3ec60303 100644
--- a/src/Webserver.h
+++ b/src/Webserver.h
@@ -85,7 +85,7 @@ class ProtocolInterpreter
virtual void ConnectionEstablished();
virtual void ConnectionLost(const ConnectionState *cs) { }
virtual bool CharFromClient(const char c) = 0;
- virtual void NoMoreDataAvailable() = 0;
+ virtual void NoMoreDataAvailable();
virtual bool DoingFastUpload() const;
virtual void DoFastUpload();
@@ -250,8 +250,7 @@ class Webserver
uint32_t postFileLength, uploadedBytes; // How many POST bytes do we expect and how many have already been written?
// Deferred requests (rr_fileinfo)
- bool processingDeferredRequest; // Are we processing a transaction multiple times to retrieve information?
- ConnectionState *deferredRequestConnection; // Which connection expects a response?
+ ConnectionState * volatile deferredRequestConnection; // Which connection expects a response for a deferred request?
char filenameBeingProcessed[FILENAME_LENGTH]; // The filename being processed (for rr_fileinfo)
void ProcessDeferredRequest();
@@ -268,7 +267,6 @@ class Webserver
void ConnectionEstablished() override;
void ConnectionLost(const ConnectionState *cs) override;
bool CharFromClient(const char c) override;
- void NoMoreDataAvailable() override;
void ResetState();
bool DoingFastUpload() const override;
@@ -314,7 +312,6 @@ class Webserver
void ConnectionEstablished() override;
void ConnectionLost(const ConnectionState *cs) override;
bool CharFromClient(const char c) override;
- void NoMoreDataAvailable() override;
void ResetState();
bool GCodeAvailable() const;
@@ -364,6 +361,7 @@ class Webserver
Network* network;
bool webserverActive;
NetworkTransaction *currentTransaction;
+ ConnectionState * volatile readingConnection;
float longWait;
};