File upload + other improvements

Added new request code rr_data for file uploading, and made other
changes to improve file upload speed.
Implemented S parameter to M208 command, to allow the negative limits of
axes to be set. Also reports current limits of no X/Y/Z parameter.
Reduced max reported free buffer size to 950 bytes to avoid problems
with file upload from Windows 8.1.
This commit is contained in:
David Crocker 2014-05-18 20:57:14 +01:00
parent 5fe612dd79
commit 75829fcaad
13 changed files with 219 additions and 167 deletions

View file

@ -24,8 +24,8 @@ Licence: GPL
#define CONFIGURATION_H
#define NAME "RepRapFirmware"
#define VERSION "0.59a-dc42"
#define DATE "2014-05-14"
#define VERSION "0.59b-dc42"
#define DATE "2014-05-16"
#define LAST_AUTHOR "dc42"
// Other firmware that we might switch to be compatible with.

View file

@ -97,7 +97,7 @@ void GCodes::Reset()
gFeedRate = platform->MaxFeedrate(Z_AXIS); // Typically the slowest
speedFactor = 1.0/60.0; // default is just to convert from mm/minute to mm/second
extrusionFactor = 1.0;
writingWebFile = false;
}
void GCodes::doFilePrint(GCodeBuffer* gb)
@ -167,21 +167,32 @@ void GCodes::Spin()
do
{
char b = webserver->ReadGCode();
if (webGCode->Put(b))
if (webGCode->WritingFileDirectory() == platform->GetWebDir())
{
// we have a complete gcode
if (webGCode->WritingFileDirectory() != NULL)
if (b == 0)
{
WriteGCodeToFile(webGCode);
b = '\n'; // webserver replaces newline by null
}
else
WriteHTMLToFile(b, webGCode);
}
else
{
if (webGCode->Put(b))
{
webGCode->SetFinished(ActOnGcode(webGCode));
// we have a complete gcode
if (webGCode->WritingFileDirectory() != NULL)
{
WriteGCodeToFile(webGCode);
}
else
{
webGCode->SetFinished(ActOnGcode(webGCode));
}
break; // stop after receiving a complete gcode in case we haven't finished processing it
}
break; // stop after receiving a complete gcode in case we haven't finished processing it
}
++i;
} while (i < 16 && webserver->GCodeAvailable());
} while (i < 50 && webserver->GCodeAvailable());
platform->ClassReport("GCodes", longWait);
return;
}
@ -343,13 +354,13 @@ void GCodes::LoadMoveBufferFromGCode(GCodeBuffer *gb, bool doingG92, bool applyL
}
if (applyLimits && i < 2 && axisIsHomed[i] && !doingG92) // limit X and Y moves unless doing G92
{
if (moveArg < 0.0)
if (moveArg < platform->AxisMinimum(i))
{
moveArg = 0.0;
moveArg = platform->AxisMinimum(i);
}
else if (moveArg > platform->AxisLength(i))
else if (moveArg > platform->AxisMaximum(i))
{
moveArg = platform->AxisLength(i);
moveArg = platform->AxisMaximum(i);
}
}
moveBuffer[i] = moveArg;
@ -723,7 +734,7 @@ bool GCodes::DoSingleZProbeAtPoint()
return false;
case 2: // Probe the bed
moveToDo[Z_AXIS] = -2.0 * platform->AxisLength(Z_AXIS);
moveToDo[Z_AXIS] = -2.0 * platform->AxisMaximum(Z_AXIS);
activeDrive[Z_AXIS] = true;
moveToDo[DRIVES] = platform->HomeFeedRate(Z_AXIS);
activeDrive[DRIVES] = true;
@ -771,7 +782,7 @@ bool GCodes::DoSingleZProbe()
return false;
case 1:
moveToDo[Z_AXIS] = -1.1 * platform->AxisLength(Z_AXIS);
moveToDo[Z_AXIS] = -1.1 * platform->AxisTotalLength(Z_AXIS);
activeDrive[Z_AXIS] = true;
moveToDo[DRIVES] = platform->HomeFeedRate(Z_AXIS);
activeDrive[DRIVES] = true;
@ -980,16 +991,20 @@ bool GCodes::OpenFileToWrite(const char* directory, const char* fileName, GCodeB
void GCodes::WriteHTMLToFile(char b, GCodeBuffer *gb)
{
char reply[1];
reply[0] = 0;
if (fileBeingWritten == NULL)
{
platform->Message(HOST_MESSAGE, "Attempt to write to a null file.\n");
return;
}
fileBeingWritten->Write(b);
if (eofStringCounter != 0 && b != eofString[eofStringCounter])
{
for (size_t i = 0; i < eofStringCounter; ++i)
{
fileBeingWritten->Write(eofString[i]);
}
eofStringCounter = 0;
}
if (b == eofString[eofStringCounter])
{
@ -999,22 +1014,19 @@ void GCodes::WriteHTMLToFile(char b, GCodeBuffer *gb)
fileBeingWritten->Close();
fileBeingWritten = NULL;
gb->SetWritingFileDirectory(NULL);
char* r = reply;
if (platform->Emulating() == marlin)
r = "Done saving file.";
const char* r = (platform->Emulating() == marlin) ? "Done saving file." : "";
HandleReply(false, gb == serialGCode, r, 'M', 560, false);
return;
}
}
else
eofStringCounter = 0;
{
fileBeingWritten->Write(b);
}
}
void GCodes::WriteGCodeToFile(GCodeBuffer *gb)
{
char reply[1];
reply[0] = 0;
if (fileBeingWritten == NULL)
{
platform->Message(HOST_MESSAGE, "Attempt to write to a null file.\n");
@ -1030,9 +1042,7 @@ void GCodes::WriteGCodeToFile(GCodeBuffer *gb)
fileBeingWritten->Close();
fileBeingWritten = NULL;
gb->SetWritingFileDirectory(NULL);
char* r = reply;
if (platform->Emulating() == marlin)
r = "Done saving file.";
const char* r = (platform->Emulating() == marlin) ? "Done saving file." : "";
HandleReply(false, gb == serialGCode, r, 'M', 29, false);
return;
}
@ -1055,7 +1065,7 @@ void GCodes::WriteGCodeToFile(GCodeBuffer *gb)
fileBeingWritten->Write(gb->Buffer());
fileBeingWritten->Write('\n');
HandleReply(false, gb == serialGCode, reply, 'G', 1, false);
HandleReply(false, gb == serialGCode, "", 'G', 1, false);
}
// Set up a file to print, but don't print it yet.
@ -1726,9 +1736,9 @@ bool GCodes::HandleMcode(GCodeBuffer* gb)
reprap.GetMove()->SetStepHypotenuse();
if (!seen)
{
snprintf(reply, STRING_LENGTH, "Steps/mm: X: %d, Y: %d, Z: %d, E: %d",
(int) platform->DriveStepsPerUnit(X_AXIS), (int) platform->DriveStepsPerUnit(Y_AXIS),
(int) platform->DriveStepsPerUnit(Z_AXIS), (int) platform->DriveStepsPerUnit(AXES)); // FIXME - needs to do multiple extruders
snprintf(reply, STRING_LENGTH, "Steps/mm: X:%f, Y:%f, Z:%f, E:%f",
platform->DriveStepsPerUnit(X_AXIS), platform->DriveStepsPerUnit(Y_AXIS),
platform->DriveStepsPerUnit(Z_AXIS), platform->DriveStepsPerUnit(AXES)); // FIXME - needs to do multiple extruders
}
}
break;
@ -1910,13 +1920,43 @@ bool GCodes::HandleMcode(GCodeBuffer* gb)
result = OffsetAxes(gb);
break;
case 208: // Set maximum axis lengths
for (int8_t axis = 0; axis < AXES; axis++)
case 208: // Set maximum axis lengths. If there is an S parameter with value 1 then we set the min value, alse we set the max value.
{
if (gb->Seen(gCodeLetters[axis]))
bool setMin;
if (gb->Seen('S'))
{
float value = gb->GetFValue() * distanceScale;
platform->SetAxisLength(axis, value);
setMin = (gb->GetIValue() == 1);
}
else
{
setMin = false;
}
bool setSomething = false;
for (int8_t axis = 0; axis < AXES; axis++)
{
if (gb->Seen(gCodeLetters[axis]))
{
float value = gb->GetFValue() * distanceScale;
if (setMin)
{
platform->SetAxisMinimum(axis, value);
}
else
{
platform->SetAxisMaximum(axis, value);
}
setSomething = true;
}
}
if (!setSomething)
{
snprintf(reply, STRING_LENGTH, "X:%.1f Y:%.1f Z:%.1f",
(setMin) ? platform->AxisMinimum(X_AXIS) : platform->AxisMaximum(X_AXIS),
(setMin) ? platform->AxisMinimum(Y_AXIS) : platform->AxisMaximum(Y_AXIS),
(setMin) ? platform->AxisMinimum(Z_AXIS) : platform->AxisMaximum(Z_AXIS)
);
}
}
break;
@ -2042,7 +2082,7 @@ bool GCodes::HandleMcode(GCodeBuffer* gb)
}
break;
case 559: // Upload config.g
case 559: // Upload config.g or another gcode file to put in the sys directory
{
const char* str;
if (gb->Seen('P'))
@ -2066,12 +2106,21 @@ bool GCodes::HandleMcode(GCodeBuffer* gb)
}
break;
case 560: // Upload reprap.htm
case 560: // Upload reprap.htm or another web interface file
{
const char* str = INDEX_PAGE;
const char* str;
if (gb->Seen('P'))
{
str = gb->GetString();
}
else
{
str = INDEX_PAGE;
}
bool ok = OpenFileToWrite(platform->GetWebDir(), str, gb);
if (ok)
{
writingWebFile = true;
snprintf(reply, STRING_LENGTH, "Writing to file: %s", str);
}
else
@ -2227,7 +2276,9 @@ bool GCodeBuffer::Put(char c)
gcodeBuffer[gcodePointer] = c;
if (c == ';')
{
inComment = true;
}
if (c == '\n' || !c)
{
@ -2308,11 +2359,12 @@ bool GCodeBuffer::Put(char c)
bool GCodeBuffer::Seen(char c)
{
readPointer = 0;
while (gcodeBuffer[readPointer])
for (;;)
{
if (gcodeBuffer[readPointer] == c)
return true;
readPointer++;
char b = gcodeBuffer[readPointer];
if (b == 0 || b == ';') break;
if (b == c) return true;
++readPointer;
}
readPointer = -1;
return false;

View file

@ -238,6 +238,7 @@ class GCodes
bool coolingInverted;
float speedFactor; // speed factor, including the conversion from mm/min to mm/sec, normally 1/60
float extrusionFactor; // extrusion factor, normally 1.0
bool writingWebFile;
};
//*****************************************************************************************************

View file

@ -112,13 +112,13 @@ void Move::Init()
for(uint8_t point = 0; point < NUMBER_OF_PROBE_POINTS; point++)
{
xBedProbePoints[point] = (0.3 + 0.6*(float)(point%2))*platform->AxisLength(X_AXIS);
yBedProbePoints[point] = (0.0 + 0.9*(float)(point/2))*platform->AxisLength(Y_AXIS);
xBedProbePoints[point] = (0.3 + 0.6*(float)(point%2))*platform->AxisMaximum(X_AXIS);
yBedProbePoints[point] = (0.0 + 0.9*(float)(point/2))*platform->AxisMaximum(Y_AXIS);
zBedProbePoints[point] = 0.0;
probePointSet[point] = unset;
}
xRectangle = 1.0/(0.8*platform->AxisLength(X_AXIS));
xRectangle = 1.0/(0.8*platform->AxisMaximum(X_AXIS));
yRectangle = xRectangle;
secondDegreeCompensation = false;

6
Move.h
View file

@ -540,7 +540,7 @@ inline float Move::SecondDegreeTransformZ(float x, float y) const
inline void Move::HitLowStop(int8_t drive, LookAhead* la, DDA* hitDDA)
{
float hitPoint = 0.0;
float hitPoint = platform->AxisMinimum(drive);
if(drive == Z_AXIS)
{
if(zProbing)
@ -558,7 +558,7 @@ inline void Move::HitLowStop(int8_t drive, LookAhead* la, DDA* hitDDA)
// Z axis has not yet been homed, so treat this probe as a homing command
la->SetDriveCoordinateAndZeroEndSpeed(platform->ZProbeStopHeight(), drive);
gCodes->SetAxisIsHomed(drive);
lastZHit = 0.0;
lastZHit = hitPoint;
}
return;
} else
@ -578,7 +578,7 @@ inline void Move::HitLowStop(int8_t drive, LookAhead* la, DDA* hitDDA)
inline void Move::HitHighStop(int8_t drive, LookAhead* la, DDA* hitDDA)
{
la->SetDriveCoordinateAndZeroEndSpeed(platform->AxisLength(drive), drive);
la->SetDriveCoordinateAndZeroEndSpeed(platform->AxisMaximum(drive), drive);
gCodes->SetAxisIsHomed(drive);
}

View file

@ -397,6 +397,8 @@ void Network::Spin()
AppendTransaction(&freeTransactions, r);
}
}
ethernet_task(); // call this again (attempt to speed up file uploading)
}
else if (establish_ethernet_link())
{
@ -406,48 +408,6 @@ void Network::Spin()
}
}
bool Network::HaveData() const
{
return active && readyTransactions != NULL;
}
bool Network::Read(char& b)
{
if (readyTransactions != NULL)
{
return readyTransactions->Read(b);
}
return false;
}
void Network::Write(char b)
{
if (readyTransactions != NULL)
{
readyTransactions->Write(b);
}
}
void Network::Write(const char* s)
{
if (readyTransactions != NULL)
{
readyTransactions->Write(s);
}
}
// Write formatted data to the output buffer
void Network::Printf(const char* fmt, ...)
{
if (readyTransactions != NULL)
{
va_list p;
va_start(p, fmt);
readyTransactions->Vprintf(fmt, p);
va_end(p);
}
}
void Network::SentPacketAcknowledged(HttpState *hs)
{
RequestState *r = FindHs(&writingTransactions, hs);
@ -584,20 +544,6 @@ void RequestState::Set(const char* d, int l, void* pc, HttpState* h)
fileBeingSent = NULL;
}
// Webserver calls this to read bytes that have come in from the network
bool RequestState::Read(char& b)
{
if (LostConnection() || inputPointer >= inputLength)
{
return false;
}
b = inputData[inputPointer];
inputPointer++;
return true;
}
// Webserver calls this to write bytes that need to go out to the network
void RequestState::Write(char b)
@ -630,17 +576,20 @@ void RequestState::Write(const char* s)
}
// Write formatted data to the output buffer
void RequestState::Vprintf(const char* fmt, va_list v)
void RequestState::Printf(const char* fmt, ...)
{
va_list p;
va_start(p, fmt);
int spaceLeft = ARRAY_SIZE(outputBuffer) - outputPointer;
if (spaceLeft > 0)
{
int len = vsnprintf(&outputBuffer[outputPointer], spaceLeft, fmt, v);
int len = vsnprintf(&outputBuffer[outputPointer], spaceLeft, fmt, p);
if (len > 0)
{
outputPointer += min(len, spaceLeft);
}
}
va_end(p);
}
// Send some data if we can, returning true if all data has been sent

View file

@ -58,14 +58,13 @@ class RequestState
public:
friend class Network;
protected:
RequestState(RequestState* n);
void Set(const char* d, int l, void* pc, HttpState* h);
bool Read(char& b);
void SentPacketAcknowledged();
void Write(char b);
void Write(const char* s);
void Vprintf(const char *fmt, va_list v);
void Printf(const char *fmt, ...);
void Close();
bool TrySendData();
void SetConnectionLost();
@ -100,10 +99,7 @@ public:
void ConnectionError(HttpState* h);
bool Active() const;
bool LinkIsUp();
bool Read(char& b);
void Write(char b);
void Write(const char* s);
void Printf(const char *fmt, ...);
RequestState *GetRequest() const { return readyTransactions; }
void SendAndClose(FileStore *f);
bool HaveData() const;
@ -123,4 +119,18 @@ private:
bool active;
};
// Webserver calls this to read bytes that have come in from the network.
// Inlined to improve upload speed.
inline bool RequestState::Read(char& b)
{
if (LostConnection() || inputPointer >= inputLength)
{
return false;
}
b = inputData[inputPointer++];
return true;
}
#endif

View file

@ -190,7 +190,8 @@ void Platform::Init()
// AXES
axisLengths = AXIS_LENGTHS;
axisMaxima = AXIS_MAXIMA;
axisMinima = AXIS_MINIMA;
homeFeedrates = HOME_FEEDRATES;
headOffsets = HEAD_OFFSETS;

View file

@ -103,7 +103,8 @@ const unsigned int numZProbeReadingsAveraged = 8; // we average this number of r
// AXES
#define AXIS_LENGTHS {220, 200, 200} // mm
#define AXIS_MAXIMA {220, 200, 200} // mm
#define AXIS_MINIMA {0, 0, 0} // mm
#define HOME_FEEDRATES {50.0, 50.0, 1.0} // mm/sec
#define HEAD_OFFSETS {0.0, 0.0, 0.0}
@ -567,11 +568,11 @@ public:
float HomeFeedRate(int8_t axis) const;
void SetHomeFeedRate(int8_t axis, float value);
EndStopHit Stopped(int8_t drive);
float AxisLength(int8_t axis) const;
void SetAxisLength(int8_t axis, float value);
#if 0 // not used
bool HighStopButNotLow(int8_t axis) const;
#endif
float AxisMaximum(int8_t axis) const;
void SetAxisMaximum(int8_t axis, float value);
float AxisMinimum(int8_t axis) const;
void SetAxisMinimum(int8_t axis, float value);
float AxisTotalLength(int8_t axis) const;
// Z probe
@ -669,7 +670,8 @@ private:
void UpdateNetworkAddress(byte dst[4], const byte src[4]);
void WriteNvData();
float axisLengths[AXES];
float axisMaxima[AXES];
float axisMinima[AXES];
float homeFeedrates[AXES];
float headOffsets[AXES]; // FIXME - needs a 2D array
@ -798,14 +800,29 @@ inline void Platform::SetHomeFeedRate(int8_t axis, float value)
homeFeedrates[axis] = value;
}
inline float Platform::AxisLength(int8_t axis) const
inline float Platform::AxisMaximum(int8_t axis) const
{
return axisLengths[axis];
return axisMaxima[axis];
}
inline void Platform::SetAxisLength(int8_t axis, float value)
inline void Platform::SetAxisMaximum(int8_t axis, float value)
{
axisLengths[axis] = value;
axisMaxima[axis] = value;
}
inline float Platform::AxisMinimum(int8_t axis) const
{
return axisMinima[axis];
}
inline void Platform::SetAxisMinimum(int8_t axis, float value)
{
axisMinima[axis] = value;
}
inline float Platform::AxisTotalLength(int8_t axis) const
{
return axisMaxima[axis] - axisMinima[axis];
}
inline float Platform::MaxFeedrate(int8_t drive) const

Binary file not shown.

View file

@ -229,6 +229,10 @@ void RepRap::Spin()
ticksInSpinState = 0;
webserver->Spin();
++spinState;
ticksInSpinState = 0;
network->Spin();
++spinState;
ticksInSpinState = 0;
gCodes->Spin();

View file

@ -133,6 +133,32 @@ void Webserver::LoadGcodeBuffer(const char* gc)
}
}
// Process a received string of file upload data
// For now we just copy the data to our large buffer, bypassing the usual checks for specific gcodes.
// Eventually, the file writing code will be moved here.
void Webserver::LoadFileData(const char* data, size_t len)
{
if (len > GetGcodeBufferSpace())
{
platform->Message(HOST_MESSAGE, "Webserver: GCode buffer overflow.\n");
HandleReply("Webserver: GCode buffer overflow", true);
}
else
{
size_t remaining = gcodeBufLength - gcodeWriteIndex;
if (len <= remaining)
{
memcpy(&gcodeBuffer[gcodeWriteIndex], data, len);
}
else
{
memcpy(&gcodeBuffer[gcodeWriteIndex], data, remaining);
memcpy(gcodeBuffer, data + remaining, len - remaining);
}
gcodeWriteIndex = (gcodeWriteIndex + len) % gcodeBufLength;
}
}
// Process a null-terminated gcode
// We intercept four G/M Codes so we can deal with file manipulation and emergencies. That
// way things don't get out of sync, and - as a file name can contain
@ -197,29 +223,7 @@ void Webserver::ProcessGcode(const char* gc)
break;
default:
{
// Copy the gcode to the buffer
size_t len = strlen(gc) + 1; // number of characters to copy
if (len > GetGcodeBufferSpace())
{
platform->Message(HOST_MESSAGE, "Webserver: GCode buffer overflow.\n");
HandleReply("Webserver: GCode buffer overflow", true);
}
else
{
size_t remaining = gcodeBufLength - gcodeWriteIndex;
if (len <= remaining)
{
memcpy(&gcodeBuffer[gcodeWriteIndex], gc, len);
}
else
{
memcpy(&gcodeBuffer[gcodeWriteIndex], gc, remaining);
memcpy(gcodeBuffer, gc + remaining, len - remaining);
}
gcodeWriteIndex = (gcodeWriteIndex + len) % gcodeBufLength;
}
}
LoadFileData(gc, strlen(gc) + 1);
break;
}
}
@ -254,7 +258,8 @@ void Webserver::SendFile(const char* nameOfFileToSend)
}
Network *net = reprap.GetNetwork();
net->Write("HTTP/1.1 200 OK\n");
RequestState *req = net->GetRequest();
req->Write("HTTP/1.1 200 OK\n");
const char* contentType;
bool zip = false;
@ -291,24 +296,24 @@ void Webserver::SendFile(const char* nameOfFileToSend)
{
contentType = "application/octet-stream";
}
net->Printf("Content-Type: %s\n", contentType);
req->Printf("Content-Type: %s\n", contentType);
if (doingJsonResponse)
{
net->Printf("Content-Length: %u\n", strlen(jsonResponse));
req->Printf("Content-Length: %u\n", strlen(jsonResponse));
}
else if (zip && fileToSend != NULL)
{
net->Write("Content-Encoding: gzip\n");
net->Printf("Content-Length: %lu", fileToSend->Length());
req->Write("Content-Encoding: gzip\n");
req->Printf("Content-Length: %lu", fileToSend->Length());
}
net->Write("Connection: close\n");
net->Write('\n');
req->Write("Connection: close\n");
req->Write('\n');
if (doingJsonResponse)
{
net->Write(jsonResponse);
req->Write(jsonResponse);
}
net->SendAndClose(fileToSend);
}
@ -361,7 +366,15 @@ void Webserver::GetJsonResponse(const char* request)
if (StringStartsWith(request, "gcode") && StringStartsWith(clientQualifier, "gcode="))
{
LoadGcodeBuffer(&clientQualifier[6]);
LoadGcodeBuffer(clientQualifier + 6);
snprintf(jsonResponse, ARRAY_UPB(jsonResponse), "{\"buff\":%u}", GetReportedGcodeBufferSpace());
JsonReport(true, request);
return;
}
if (StringStartsWith(request, "data") && StringStartsWith(clientQualifier, "data="))
{
LoadFileData(clientQualifier + 5, strlen(clientQualifier + 5));
snprintf(jsonResponse, ARRAY_UPB(jsonResponse), "{\"buff\":%u}", GetReportedGcodeBufferSpace());
JsonReport(true, request);
return;
@ -413,7 +426,7 @@ void Webserver::GetJsonResponse(const char* request)
char ch = '[';
for (int8_t drive = 0; drive < AXES; drive++)
{
sncatf(jsonResponse, ARRAY_UPB(jsonResponse), "%c\"%.1f\"", ch, platform->AxisLength(drive));
sncatf(jsonResponse, ARRAY_UPB(jsonResponse), "%c\"%.1f\"", ch, platform->AxisTotalLength(drive));
ch = ',';
}
strncat(jsonResponse, "]}", ARRAY_UPB(jsonResponse));
@ -656,7 +669,9 @@ void Webserver::ParseClientLine()
postSeen = false;
getSeen = true;
if (!clientRequest[0])
{
strncpy(clientRequest, INDEX_PAGE, ARRAY_SIZE(clientRequest));
}
return;
}
@ -802,12 +817,14 @@ void Webserver::Spin()
return;
Network *net = reprap.GetNetwork();
if (net->HaveData())
RequestState *req = net->GetRequest();
if (req != NULL)
{
for (uint8_t i = 0; i < 16; ++i)
// To achieve a high upload speed, we try to process a complete request here
for (;;)
{
char c;
bool ok = net->Read(c);
bool ok = req->Read(c);
if (!ok)
{

View file

@ -38,7 +38,7 @@ const unsigned int postLength = 1400; // max amount of POST data we can accept
const unsigned int webInputLength = 1400; // max size of web interface requests and related stuff
const unsigned int gcodeBufLength = 2048; // size of our gcode ring buffer, ideally a power of 2
const unsigned int minReportedFreeBuf = 100; // the minimum free buffer we report if not zero
const unsigned int maxReportedFreeBuf = 1024; // the max we own up to having free, to avoid overlong messages
const unsigned int maxReportedFreeBuf = 950; // the max we own up to having free, to avoid overlong messages. 1024 is too long for Chrome/Windows 8.1.
const unsigned int jsopnReplyLength = 1200; // size of buffer used to hold JSON reply
class Webserver
@ -65,6 +65,7 @@ class Webserver
void ParseQualifier();
void CheckPassword();
void LoadGcodeBuffer(const char* gc);
void LoadFileData(const char* data, size_t len);
bool PrintHeadString();
bool PrintLinkTable();
void GetGCodeList();
@ -96,7 +97,7 @@ class Webserver
bool getSeen;
bool clientLineIsBlank;
char clientLine[webInputLength];
char clientLine[webInputLength + 2];
char clientRequest[webInputLength];
char clientQualifier[webInputLength];
char jsonResponse[jsopnReplyLength];