void Network::Write(char b) { // Check for horrible things... if(!writeEnabled) { reprap.GetPlatform()->Message(HOST_MESSAGE, "Network::Write(char b) - Attempt to write when disabled.\n"); return; } if(outputPointer >= STRING_LENGTH) { reprap.GetPlatform()->Message(HOST_MESSAGE, "Network::Write(char b) - Output buffer overflow! \n"); return; } // Add the byte to the buffer outputBuffer[outputPointer] = b; outputPointer++; // Buffer full? If so, send it. if(outputPointer >= STRING_LENGTH - 5) // 5 is for safety { SetWriteEnable(false); // Stop further writing from Webserver until the network tells us that this has gone RepRapNetworkSendOutput(outputBuffer, outputPointer, netRingGetPointer->Pbuf(), netRingGetPointer->Pcb(), netRingGetPointer->Hs()); outputPointer = 0; } }
void Network::Close() { if(Status() && clientLive) { if(outputPointer > 0) { SetWriteEnable(false); RepRapNetworkSendOutput(outputBuffer, outputPointer, netRingGetPointer->Pbuf(), netRingGetPointer->Pcb(), netRingGetPointer->Hs()); outputPointer = 0; closePending = true; return; } RepRapNetworkSendOutput((char*)NULL, 0, netRingGetPointer->Pbuf(), netRingGetPointer->Pcb(), netRingGetPointer->Hs()); netRingGetPointer->Free(); netRingGetPointer = netRingGetPointer->Next(); //reprap.GetPlatform()->Message(HOST_MESSAGE, "Network - output sent and closed.\n"); } else reprap.GetPlatform()->Message(HOST_MESSAGE, "Network::Close() - Attempt to close a closed connection!\n"); closePending = false; status = nothing; //Reset(); }
// Send some data or close this connection if we can, returning true if we can free up this object bool RequestState::Send() { if (LostConnection()) { if (fileBeingSent != NULL) { fileBeingSent->Close(); fileBeingSent = NULL; } return true; } if (hs->SendInProgress()) { return false; } if (sentDataOutstanding != 0) { float timeNow = reprap.GetPlatform()->Time(); if (timeNow - lastWriteTime > writeTimeout) { debugPrintf("Timing out connection hs=%08x\n", (unsigned int)hs); HttpState *locHs = hs; // take a copy because our hs field is about to get cleared reprap.GetNetwork()->ConnectionClosing(locHs); tcp_pcb *pcb = locHs->pcb; tcp_arg(pcb, NULL); tcp_sent(pcb, NULL); tcp_recv(pcb, NULL); tcp_poll(pcb, NULL, 4); tcp_abort(pcb); mem_free(locHs); return false; // this RS will be freed next time round } } if (sentDataOutstanding >= ARRAY_SIZE(outputBuffer)/2) { return false; // don't send until at least half the output buffer is free } if (fileBeingSent != NULL) { unsigned int outputLimit = (sentDataOutstanding == 0) ? ARRAY_SIZE(outputBuffer) : min<unsigned int>(unsentPointer + ARRAY_SIZE(outputBuffer)/2, ARRAY_SIZE(outputBuffer)); while (outputPointer < outputLimit) { bool ok = fileBeingSent->Read(outputBuffer[outputPointer]); if (!ok) { fileBeingSent->Close(); fileBeingSent = NULL; break; } ++outputPointer; } } if (outputPointer == unsentPointer) { // We have no data to send. fileBeingSent must already be NULL here. if (!persistConnection && !closeRequested && nextWrite == NULL) { tcp_close(hs->pcb); closeRequested = true; // Don't release this RS yet, the write buffer may still be needed to do send retries return false; } if (sentDataOutstanding != 0) { return false; } // We've finished with this RS if (closeRequested) { // debugPrintf("Closing connection hs=%08x\n", (unsigned int)hs); HttpState *locHs = hs; // take a copy because our hs field is about to get cleared reprap.GetNetwork()->ConnectionClosing(locHs); tcp_pcb *pcb = locHs->pcb; tcp_arg(pcb, NULL); tcp_sent(pcb, NULL); tcp_recv(pcb, NULL); tcp_poll(pcb, NULL, 4); mem_free(locHs); } return true; } else { sentDataOutstanding += (outputPointer - unsentPointer); RepRapNetworkSendOutput(outputBuffer + unsentPointer, outputPointer - unsentPointer, hs); unsentPointer = (outputPointer == ARRAY_SIZE(outputBuffer)) ? 0 : outputPointer; outputPointer = unsentPointer; lastWriteTime = reprap.GetPlatform()->Time(); return false; } }