Webserver coming along. Some tidying. For some reason there is a
big delay on closing the connection when there is a second partly-full buffer of data sent to the browser after a completely full one.
This commit is contained in:
parent
7d3016a7f3
commit
6686e23f4d
4 changed files with 186 additions and 135 deletions
128
Platform.cpp
128
Platform.cpp
|
@ -681,6 +681,10 @@ void Platform::Spin()
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//*************************************************************************************************
|
||||||
|
|
||||||
|
// Serial/USB class
|
||||||
|
|
||||||
Line::Line()
|
Line::Line()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -693,47 +697,70 @@ void Line::Init()
|
||||||
while (!SerialUSB.available());
|
while (!SerialUSB.available());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//***************************************************************************************************
|
||||||
|
|
||||||
|
// Network/Ethernet class
|
||||||
|
|
||||||
|
// C calls to interface with LWIP (http://savannah.nongnu.org/projects/lwip/)
|
||||||
|
// These are implemented in, and called from, a modified version of httpd.c
|
||||||
|
// in the network directory.
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
|
|
||||||
static char* hdat = 0;
|
// Transmit data to the Network
|
||||||
static int hlen = 0;
|
|
||||||
//static float nwtime = 100000.0;
|
|
||||||
|
|
||||||
void SetNetworkDataToSend(char* data, int length);
|
void SetNetworkDataToSend(char* data, int length);
|
||||||
|
|
||||||
|
// Close the connection
|
||||||
|
|
||||||
void CloseConnection();
|
void CloseConnection();
|
||||||
|
|
||||||
void NWSetNetworkDataToSend(char* data, int length)
|
// Called to put out a message via the RepRap firmware.
|
||||||
{
|
|
||||||
hdat = data;
|
|
||||||
hlen = length;
|
|
||||||
// nwtime = reprap.GetPlatform()->Time() + 3.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RepRapNetworkMessage(char* s)
|
void RepRapNetworkMessage(char* s)
|
||||||
{
|
{
|
||||||
reprap.GetPlatform()->Message(HOST_MESSAGE, s);
|
reprap.GetPlatform()->Message(HOST_MESSAGE, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called to push data into the RepRap firmware.
|
||||||
|
|
||||||
void RepRapNetworkReceiveInput(char* ip, int length)
|
void RepRapNetworkReceiveInput(char* ip, int length)
|
||||||
{
|
{
|
||||||
reprap.GetPlatform()->GetNetwork()->ReceiveInput(ip, length);
|
reprap.GetPlatform()->GetNetwork()->ReceiveInput(ip, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called when transmission of outgoing data is complete to allow
|
||||||
|
// the RepRap firmware to write more.
|
||||||
|
|
||||||
void RepRapNetworkAllowWriting()
|
void RepRapNetworkAllowWriting()
|
||||||
{
|
{
|
||||||
reprap.GetPlatform()->GetNetwork()->SetWriteEnable(true);
|
reprap.GetPlatform()->GetNetwork()->SetWriteEnable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called by the RepRap firmware to transmit data, if there is
|
||||||
|
// any to send.
|
||||||
|
|
||||||
void SendDataFromRepRapNetwork()
|
void SendDataFromRepRapNetwork()
|
||||||
{
|
{
|
||||||
if(!reprap.GetPlatform()->GetNetwork()->DataToSendAvailable())
|
if(!reprap.GetPlatform()->GetNetwork()->DataToSendAvailable())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Stop the generation of more data.
|
||||||
|
|
||||||
reprap.GetPlatform()->GetNetwork()->SetWriteEnable(false);
|
reprap.GetPlatform()->GetNetwork()->SetWriteEnable(false);
|
||||||
|
|
||||||
|
// Find where the data is.
|
||||||
|
|
||||||
char* data = reprap.GetPlatform()->GetNetwork()->OutputBuffer();
|
char* data = reprap.GetPlatform()->GetNetwork()->OutputBuffer();
|
||||||
int length = reprap.GetPlatform()->GetNetwork()->OutputBufferLength();
|
int length = reprap.GetPlatform()->GetNetwork()->OutputBufferLength();
|
||||||
|
|
||||||
|
// Send it.
|
||||||
|
|
||||||
SetNetworkDataToSend(data, length);
|
SetNetworkDataToSend(data, length);
|
||||||
|
|
||||||
|
// Prepare to write more, when writing is re-enabled.
|
||||||
|
|
||||||
reprap.GetPlatform()->GetNetwork()->ClearWriteBuffer();
|
reprap.GetPlatform()->GetNetwork()->ClearWriteBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -746,36 +773,47 @@ Network::Network()
|
||||||
ethPinsInit();
|
ethPinsInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Network::Init()
|
// Reset the network to its disconnected and ready state.
|
||||||
|
|
||||||
|
void Network::Reset()
|
||||||
{
|
{
|
||||||
alternateInput = NULL;
|
|
||||||
alternateOutput = NULL;
|
|
||||||
init_ethernet();
|
|
||||||
inputPointer = 0;
|
inputPointer = 0;
|
||||||
inputLength = -1;
|
inputLength = -1;
|
||||||
outputPointer = 0;
|
outputPointer = 0;
|
||||||
outputLength = -1;
|
outputLength = -1;
|
||||||
writeEnabled = true;
|
writeEnabled = true;
|
||||||
|
status = nothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for CloseConnectionAndFreeBuffer
|
void Network::Init()
|
||||||
|
{
|
||||||
//static void FreeBuffer();
|
alternateInput = NULL;
|
||||||
|
alternateOutput = NULL;
|
||||||
|
init_ethernet();
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
void Network::Spin()
|
void Network::Spin()
|
||||||
{
|
{
|
||||||
// Finish reading any data that's been received.
|
// Finish reading any data that's been received.
|
||||||
|
|
||||||
if(inputPointer < inputLength)
|
if(inputPointer < inputLength)
|
||||||
{
|
|
||||||
//reprap.GetWebserver()->Spin(); // Is this sensible?
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
ethernet_task();
|
||||||
|
|
||||||
|
// Send any data that's available
|
||||||
|
|
||||||
SendDataFromRepRapNetwork();
|
SendDataFromRepRapNetwork();
|
||||||
|
|
||||||
|
// Poll the network, and update its timers.
|
||||||
|
|
||||||
ethernet_task();
|
ethernet_task();
|
||||||
|
|
||||||
|
// If we've finished generating data, queue up the
|
||||||
|
// last bytes recorded (which may not fill the
|
||||||
|
// buffer) to send.
|
||||||
|
|
||||||
if(!reprap.GetWebserver()->WebserverIsWriting())
|
if(!reprap.GetWebserver()->WebserverIsWriting())
|
||||||
{
|
{
|
||||||
if(outputPointer > 0)
|
if(outputPointer > 0)
|
||||||
|
@ -784,33 +822,15 @@ void Network::Spin()
|
||||||
outputPointer = 0;
|
outputPointer = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if(reprap.GetPlatform()->Time() > nwtime && hdat != 0)
|
|
||||||
// {
|
|
||||||
// SetNetworkDataToSend(hdat, hlen);
|
|
||||||
// hdat = 0;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Network::ReceiveInput(char* ip, int length)
|
void Network::ReceiveInput(char* ip, int length)
|
||||||
{
|
{
|
||||||
if(length > STRING_LENGTH)
|
status = clientLive;
|
||||||
{
|
inputBuffer = ip;
|
||||||
reprap.GetPlatform()->Message(HOST_MESSAGE, "Network input buffer overflow.\n");
|
inputLength = length;
|
||||||
inputLength = STRING_LENGTH;
|
|
||||||
} else
|
|
||||||
inputLength = length;
|
|
||||||
for(int i = 0; i < inputLength; i++)
|
|
||||||
{
|
|
||||||
inputBuffer[i] = ip[i];
|
|
||||||
//SerialUSB.print(inputBuffer[i]);
|
|
||||||
}
|
|
||||||
// inputBuffer = ip;
|
|
||||||
// inputLength = length;
|
|
||||||
inputPointer = 0;
|
inputPointer = 0;
|
||||||
//while(Status() != nothing)
|
|
||||||
// reprap.GetWebserver()->Spin(); // Nasty...
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -834,6 +854,8 @@ void Network::ClearWriteBuffer()
|
||||||
|
|
||||||
void Network::Write(char b)
|
void Network::Write(char b)
|
||||||
{
|
{
|
||||||
|
// Check for horrible things...
|
||||||
|
|
||||||
if(!writeEnabled)
|
if(!writeEnabled)
|
||||||
{
|
{
|
||||||
reprap.GetPlatform()->Message(HOST_MESSAGE, "Network::Write(char b) - Attempt to write when disabled.\n");
|
reprap.GetPlatform()->Message(HOST_MESSAGE, "Network::Write(char b) - Attempt to write when disabled.\n");
|
||||||
|
@ -855,9 +877,13 @@ void Network::Write(char b)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add the byte to the buffer
|
||||||
|
|
||||||
outputBuffer[outputPointer] = b;
|
outputBuffer[outputPointer] = b;
|
||||||
outputPointer++;
|
outputPointer++;
|
||||||
|
|
||||||
|
// Buffer full? If so, flag it to send.
|
||||||
|
|
||||||
if(outputPointer >= STRING_LENGTH - 5) // 5 is for safety
|
if(outputPointer >= STRING_LENGTH - 5) // 5 is for safety
|
||||||
{
|
{
|
||||||
outputLength = outputPointer;
|
outputLength = outputPointer;
|
||||||
|
@ -866,6 +892,9 @@ void Network::Write(char b)
|
||||||
outputLength = -1;
|
outputLength = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If outputLength has been set, there's some data ready
|
||||||
|
// to send.
|
||||||
|
|
||||||
bool Network::DataToSendAvailable()
|
bool Network::DataToSendAvailable()
|
||||||
{
|
{
|
||||||
return (outputLength > 0);
|
return (outputLength > 0);
|
||||||
|
@ -879,6 +908,9 @@ bool Network::CanWrite()
|
||||||
void Network::SetWriteEnable(bool enable)
|
void Network::SetWriteEnable(bool enable)
|
||||||
{
|
{
|
||||||
writeEnabled = enable;
|
writeEnabled = enable;
|
||||||
|
|
||||||
|
// Reset the write buffer if needs be.
|
||||||
|
|
||||||
if(writeEnabled && outputLength > 0)
|
if(writeEnabled && outputLength > 0)
|
||||||
{
|
{
|
||||||
outputLength = -1;
|
outputLength = -1;
|
||||||
|
@ -886,6 +918,11 @@ void Network::SetWriteEnable(bool enable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is not called for data, only for internally-
|
||||||
|
// generated short strings at the start of a transmission,
|
||||||
|
// so it should never overflow the buffer (which is checked
|
||||||
|
// anyway).
|
||||||
|
|
||||||
void Network::Write(char* s)
|
void Network::Write(char* s)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -909,19 +946,14 @@ bool Network::Read(char& b)
|
||||||
void Network::Close()
|
void Network::Close()
|
||||||
{
|
{
|
||||||
CloseConnection();
|
CloseConnection();
|
||||||
// if (client)
|
Reset();
|
||||||
// {
|
|
||||||
// client.stop();
|
|
||||||
// //Serial.println("client disconnected");
|
|
||||||
// } else
|
|
||||||
// reprap.GetPlatform()->Message(HOST_MESSAGE, "Attempt to disconnect non-existent client.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t Network::Status()
|
int8_t Network::Status()
|
||||||
{
|
{
|
||||||
if(inputPointer >= inputLength)
|
if(inputPointer >= inputLength)
|
||||||
return nothing;
|
return status;
|
||||||
return clientConnected | byteAvailable;
|
return status | clientConnected | byteAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -252,12 +252,16 @@ protected:
|
||||||
Network();
|
Network();
|
||||||
void Init();
|
void Init();
|
||||||
void Spin();
|
void Spin();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char inputBuffer[STRING_LENGTH];
|
|
||||||
|
void Reset();
|
||||||
|
char* inputBuffer;
|
||||||
char outputBuffer[STRING_LENGTH];
|
char outputBuffer[STRING_LENGTH];
|
||||||
int inputPointer, inputLength;
|
int inputPointer, inputLength;
|
||||||
int outputPointer, outputLength;
|
int outputPointer, outputLength;
|
||||||
bool writeEnabled;
|
bool writeEnabled;
|
||||||
|
int8_t status;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This class handles serial I/O - typically via USB
|
// This class handles serial I/O - typically via USB
|
||||||
|
|
|
@ -636,12 +636,14 @@ void Webserver::Spin()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (platform->GetNetwork()->Status() & clientLive)
|
if (platform->GetNetwork()->Status() & clientLive)
|
||||||
{
|
{
|
||||||
if(needToCloseClient)
|
if(needToCloseClient)
|
||||||
{
|
{
|
||||||
if(platform->Time() - clientCloseTime < CLIENT_CLOSE_DELAY || !platform->GetNetwork()->CanWrite())
|
if(platform->Time() - clientCloseTime < CLIENT_CLOSE_DELAY || !platform->GetNetwork()->CanWrite())
|
||||||
return;
|
return;
|
||||||
|
//if(!platform->GetNetwork()->CanWrite())
|
||||||
|
// return;
|
||||||
needToCloseClient = false;
|
needToCloseClient = false;
|
||||||
platform->GetNetwork()->Close();
|
platform->GetNetwork()->Close();
|
||||||
}
|
}
|
||||||
|
|
183
network/httpd.c
183
network/httpd.c
|
@ -30,6 +30,17 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Heavily modified by Adrian
|
||||||
|
*
|
||||||
|
* RepRapPro Ltd
|
||||||
|
* http://reprappro.com
|
||||||
|
*
|
||||||
|
* 2 October 2013
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
//#include "lwipopts.h"
|
//#include "lwipopts.h"
|
||||||
//#if defined(HTTP_RAW_USED)
|
//#if defined(HTTP_RAW_USED)
|
||||||
//
|
//
|
||||||
|
@ -50,20 +61,31 @@
|
||||||
#include "lwip/src/include/lwip/tcp.h"
|
#include "lwip/src/include/lwip/tcp.h"
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
|
|
||||||
void RepRapNetworkReceiveInput(char* ip, int length);
|
|
||||||
void RepRapNetworkMessage(char* s);
|
|
||||||
void RepRapNetworkAllowWriting();
|
|
||||||
//void NWSetNetworkDataToSend(char* data, int length);
|
|
||||||
|
|
||||||
struct http_state {
|
struct http_state {
|
||||||
char *file;
|
char *file;
|
||||||
u16_t left;
|
u16_t left;
|
||||||
u8_t retries;
|
u8_t retries;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Prototypes for the RepRap functions in Platform.cpp that we
|
||||||
|
// need to call.
|
||||||
|
|
||||||
|
void RepRapNetworkReceiveInput(char* ip, int length);
|
||||||
|
void RepRapNetworkMessage(char* s);
|
||||||
|
void RepRapNetworkAllowWriting();
|
||||||
|
|
||||||
|
// Static storage for pointers that need to be saved when we go
|
||||||
|
// out to the RepRap firmware for when it calls back in again.
|
||||||
|
// Note that this means that the code is not reentrant, but in
|
||||||
|
// our context it doesn't need to be.
|
||||||
|
|
||||||
static struct tcp_pcb* activePcb;
|
static struct tcp_pcb* activePcb;
|
||||||
static struct tcp_pcb* pcbToClose = 0;
|
static struct tcp_pcb* pcbToClose = 0;
|
||||||
static struct http_state* activeHttpState;
|
static struct http_state* activeHttpState;
|
||||||
|
static struct pbuf* pbufToFree = 0;
|
||||||
|
static struct tcp_pcb* sendingPcb = 0;
|
||||||
|
static int initCount = 0;
|
||||||
|
bool alreadySending = false;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
|
@ -78,33 +100,38 @@ conn_err(void *arg, err_t err)
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// Added to allow RepRap to close the connection.
|
||||||
|
|
||||||
void CloseConnection()
|
void CloseConnection()
|
||||||
{
|
{
|
||||||
RepRapNetworkMessage("CloseConnection() called.\n");
|
|
||||||
if(pcbToClose == 0)
|
if(pcbToClose == 0)
|
||||||
return;
|
return;
|
||||||
RepRapNetworkMessage("Got a pcb.\n");
|
RepRapNetworkMessage("CloseConnection() called.\n");
|
||||||
|
tcp_arg(pcbToClose, NULL);
|
||||||
tcp_arg(pcbToClose, NULL);
|
tcp_sent(pcbToClose, NULL);
|
||||||
tcp_sent(pcbToClose, NULL);
|
tcp_recv(pcbToClose, NULL);
|
||||||
tcp_recv(pcbToClose, NULL);
|
//mem_free(hs);
|
||||||
//mem_free(hs);
|
tcp_close(pcbToClose);
|
||||||
tcp_close(pcbToClose);
|
pcbToClose = 0;
|
||||||
pcbToClose = 0;
|
alreadySending = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// httpd.c's close function, slightly mashed...
|
||||||
|
|
||||||
static void
|
static void
|
||||||
close_conn(struct tcp_pcb *pcb, struct http_state *hs)
|
close_conn(struct tcp_pcb *pcb, struct http_state *hs)
|
||||||
{
|
{
|
||||||
RepRapNetworkMessage("Internal close_conn called.\n");
|
RepRapNetworkMessage("Internal close_conn called.\n");
|
||||||
// CloseConnection();
|
|
||||||
tcp_arg(pcb, NULL);
|
tcp_arg(pcb, NULL);
|
||||||
tcp_sent(pcb, NULL);
|
tcp_sent(pcb, NULL);
|
||||||
tcp_recv(pcb, NULL);
|
tcp_recv(pcb, NULL);
|
||||||
//mem_free(hs);
|
//mem_free(hs);
|
||||||
tcp_close(pcb);
|
tcp_close(pcb);
|
||||||
|
alreadySending = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char scratch[40];
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
send_data(struct tcp_pcb *pcb, struct http_state *hs)
|
send_data(struct tcp_pcb *pcb, struct http_state *hs)
|
||||||
|
@ -120,6 +147,11 @@ send_data(struct tcp_pcb *pcb, struct http_state *hs)
|
||||||
len = hs->left;
|
len = hs->left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RepRapNetworkMessage("Sending ");
|
||||||
|
sprintf(scratch, "%d", len);
|
||||||
|
RepRapNetworkMessage(scratch);
|
||||||
|
RepRapNetworkMessage("..");
|
||||||
|
|
||||||
do {
|
do {
|
||||||
err = tcp_write(pcb, hs->file, len, 0);
|
err = tcp_write(pcb, hs->file, len, 0);
|
||||||
if (err == ERR_MEM) {
|
if (err == ERR_MEM) {
|
||||||
|
@ -158,25 +190,33 @@ http_poll(void *arg, struct tcp_pcb *pcb)
|
||||||
|
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
static err_t
|
static err_t
|
||||||
http_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
|
http_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
|
||||||
{
|
{
|
||||||
struct http_state *hs;
|
struct http_state *hs;
|
||||||
|
|
||||||
//RepRapNetworkAllowWriting();
|
|
||||||
|
|
||||||
LWIP_UNUSED_ARG(len);
|
LWIP_UNUSED_ARG(len);
|
||||||
|
|
||||||
hs = arg;
|
hs = arg;
|
||||||
|
|
||||||
hs->retries = 0;
|
hs->retries = 0;
|
||||||
|
|
||||||
if (hs->left > 0) {
|
RepRapNetworkMessage("..sent\n");
|
||||||
|
|
||||||
|
if (hs->left > 0)
|
||||||
|
{
|
||||||
send_data(pcb, hs);
|
send_data(pcb, hs);
|
||||||
} else {
|
} else
|
||||||
|
{
|
||||||
|
// See if there is more to send, and remember the
|
||||||
|
// pcb for when the connection is closed.
|
||||||
|
// TODO - possible memory leak?
|
||||||
RepRapNetworkAllowWriting();
|
RepRapNetworkAllowWriting();
|
||||||
|
sendingPcb = pcb;
|
||||||
pcbToClose = pcb;
|
pcbToClose = pcb;
|
||||||
|
tcp_sent(pcb, http_sent);
|
||||||
//close_conn(pcb, hs);
|
//close_conn(pcb, hs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,8 +224,10 @@ http_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
static struct pbuf* pbufToFree = 0;
|
// ReoRap calls this with data to send.
|
||||||
static struct tcp_pcb* sendingPcb = 0;
|
// It has the side effect of freeing the input buffer
|
||||||
|
// that prompted the transmission, as that must now have been fully read.
|
||||||
|
// If RepRap ignores input, is this another potential memory leak?
|
||||||
|
|
||||||
void SetNetworkDataToSend(char* data, int length)
|
void SetNetworkDataToSend(char* data, int length)
|
||||||
{
|
{
|
||||||
|
@ -202,76 +244,45 @@ void SetNetworkDataToSend(char* data, int length)
|
||||||
|
|
||||||
send_data(sendingPcb, activeHttpState);
|
send_data(sendingPcb, activeHttpState);
|
||||||
|
|
||||||
|
if(alreadySending)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Tell TCP that we wish be to informed of data that has been
|
/* Tell TCP that we wish be to informed of data that has been
|
||||||
successfully sent by a call to the http_sent() function. */
|
successfully sent by a call to the http_sent() function. */
|
||||||
|
|
||||||
|
|
||||||
tcp_sent(sendingPcb, http_sent);
|
tcp_sent(sendingPcb, http_sent);
|
||||||
|
|
||||||
|
alreadySending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static err_t
|
static err_t
|
||||||
http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
|
http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char *data;
|
char *data;
|
||||||
//struct fs_file file;
|
|
||||||
//struct http_state *hs;
|
|
||||||
|
|
||||||
//hs = arg;
|
if (err == ERR_OK && p != NULL)
|
||||||
|
{
|
||||||
|
/* Inform TCP that we have taken the data. */
|
||||||
|
tcp_recved(pcb, p->tot_len);
|
||||||
|
|
||||||
if (err == ERR_OK && p != NULL) {
|
if (activeHttpState->file == NULL)
|
||||||
|
{
|
||||||
|
data = p->payload;
|
||||||
|
RepRapNetworkReceiveInput(data, p->len);
|
||||||
|
pbufToFree = p;
|
||||||
|
sendingPcb = pcb;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
pbuf_free(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Inform TCP that we have taken the data. */
|
if (err == ERR_OK && p == NULL) {
|
||||||
tcp_recved(pcb, p->tot_len);
|
close_conn(pcb, activeHttpState);
|
||||||
|
}
|
||||||
if (activeHttpState->file == NULL) {
|
return ERR_OK;
|
||||||
data = p->payload;
|
|
||||||
|
|
||||||
RepRapNetworkReceiveInput(data, p->len);
|
|
||||||
|
|
||||||
// if (strncmp(data, "GET ", 4) == 0) {
|
|
||||||
// for(i = 0; i < 40; i++) {
|
|
||||||
// if (((char *)data + 4)[i] == ' ' ||
|
|
||||||
// ((char *)data + 4)[i] == '\r' ||
|
|
||||||
// ((char *)data + 4)[i] == '\n') {
|
|
||||||
// ((char *)data + 4)[i] = 0;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (*(char *)(data + 4) == '/' &&
|
|
||||||
// *(char *)(data + 5) == 0) {
|
|
||||||
// fs_open("/index.html", &file);
|
|
||||||
// } else if (!fs_open((char *)data + 4, &file)) {
|
|
||||||
// fs_open("/404.html", &file);
|
|
||||||
// }
|
|
||||||
|
|
||||||
pbufToFree = p;
|
|
||||||
sendingPcb = pcb;
|
|
||||||
|
|
||||||
//NWSetNetworkDataToSend(file.data, file.len);
|
|
||||||
|
|
||||||
// activeHttpState->file = file.data;
|
|
||||||
// activeHttpState->left = file.len;
|
|
||||||
// /* printf("data %p len %ld\n", hs->file, hs->left);*/
|
|
||||||
//
|
|
||||||
// pbuf_free(pbufToFree);
|
|
||||||
//
|
|
||||||
// send_data(sendingPcb, activeHttpState);
|
|
||||||
//
|
|
||||||
// /* Tell TCP that we wish be to informed of data that has been
|
|
||||||
// successfully sent by a call to the http_sent() function. */
|
|
||||||
// tcp_sent(sendingPcb, http_sent);
|
|
||||||
// } else {
|
|
||||||
// pbuf_free(p);
|
|
||||||
// close_conn(pcb, activeHttpState);
|
|
||||||
// }
|
|
||||||
} else {
|
|
||||||
pbuf_free(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err == ERR_OK && p == NULL) {
|
|
||||||
close_conn(pcb, activeHttpState);
|
|
||||||
}
|
|
||||||
return ERR_OK;
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
static err_t
|
static err_t
|
||||||
|
@ -284,9 +295,7 @@ http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
|
||||||
|
|
||||||
tcp_setprio(pcb, TCP_PRIO_MIN);
|
tcp_setprio(pcb, TCP_PRIO_MIN);
|
||||||
|
|
||||||
/* Allocate memory for the structure that holds the state of the
|
// Ignore arg; we know it must be our static activeHttpState
|
||||||
connection. */
|
|
||||||
//hs = (struct http_state *)mem_malloc(sizeof(struct http_state));
|
|
||||||
|
|
||||||
hs = activeHttpState;
|
hs = activeHttpState;
|
||||||
|
|
||||||
|
@ -315,11 +324,15 @@ http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
// This function is called once at the start.
|
// This function (is)x should be called only once at the start.
|
||||||
|
|
||||||
void
|
void
|
||||||
httpd_init(void)
|
httpd_init(void)
|
||||||
{
|
{
|
||||||
|
initCount++;
|
||||||
|
if(initCount > 1)
|
||||||
|
RepRapNetworkMessage("httpd_init() called more than once.\n");
|
||||||
|
|
||||||
activeHttpState = (struct http_state *)mem_malloc(sizeof(struct http_state));
|
activeHttpState = (struct http_state *)mem_malloc(sizeof(struct http_state));
|
||||||
activePcb = tcp_new();
|
activePcb = tcp_new();
|
||||||
tcp_bind(activePcb, IP_ADDR_ANY, 80);
|
tcp_bind(activePcb, IP_ADDR_ANY, 80);
|
||||||
|
|
Reference in a new issue