This repository has been archived on 2025-02-01. You can view files and clone it, but cannot push or open issues or pull requests.
reprapfirmware-dc42/Network.h
David Crocker b30e6ad4e1 Version 0.78p
Fixed bug that caused the cooling fan PWM frequency to be 165kHz. It is
now 25kHz.
Fan RPM is now included in the web interface status response (thanks
zpl).
Many more error messages are now reported to the web interface as well
as the USB interface.
Interrupt-driven network timer task to better cope with slow SD card
writes (thanks zpl)
Module SamNonDuePin is now used for all digital and PWM pin I/O.
2014-08-29 21:38:14 +01:00

192 lines
5.5 KiB
C++

/****************************************************************************************************
RepRapFirmware - Network: RepRapPro Ormerod with Duet controller
Separated out from Platform.h by dc42
****************************************************************************************************/
#ifndef NETWORK_H
#define NETWORK_H
#include <cctype>
#include <cstring>
#include <malloc.h>
#include <cstdlib>
#include <climits>
#include "lwipopts.h"
// This class handles the network - typically an Ethernet.
// The size of the TCP output buffer is critical to getting fast load times in the browser.
// If this value is less than the TCP MSS, then Chrome under Windows will delay ack messages by about 120ms,
// which results in very slow page loading. Any value higher than that will cause the TCP packet to be split
// into multiple transmissions, which avoids this behaviour. Using a value of twice the MSS is most efficient because
// each TCP packet will be full.
// Currently we set the MSS (in file network/lwipopts.h) to 1432 which matches the value used by most versions of Windows
// and therefore avoids additional memory use and fragmentation.
const unsigned int tcpOutputBufferCount = MEMP_NUM_TCP_PCB - 1; // number of send buffers
const unsigned int tcpOutputBufferSize = 2 * 1432; // size of each send buffer
#define IP_ADDRESS {192, 168, 1, 10} // Need some sort of default...
#define NET_MASK {255, 255, 255, 0}
#define GATE_WAY {192, 168, 1, 1}
/****************************************************************************************************/
struct tcp_pcb;
struct pbuf;
class RequestState;
class SendBuffer;
// ConnectionState structure that we use to track TCP connections. This could be combined with class RequestState.
struct ConnectionState
{
tcp_pcb *pcb; // connection PCB
RequestState *sendingRs; // RequestState that is currently sending via this connection
const char *file; // pointer to data to send
uint16_t left; // amount of data to send
uint8_t retries; // number of retries left
// Methods
bool SendInProgress() const { return left > 0; }
uint16_t GetLocalPort() const;
};
// Assign a status to each RequestState
enum RequestStatus
{
connected,
dataReceiving,
dataSending,
disconnected
};
// Start with a class to hold input and output from the network that needs to be responded to.
class RequestState
{
public:
friend class Network;
RequestState(RequestState* n);
void Set(pbuf *p, ConnectionState* c, RequestStatus s);
bool Read(char& b);
bool ReadBuffer(char *&buffer, unsigned int &len);
void SentPacketAcknowledged(unsigned int len);
void Write(char b);
bool Write(const char* s);
void Printf(const char *fmt, ...);
bool Send();
void SetConnectionLost();
bool LostConnection() const { return cs == NULL; }
bool IsReady() const { return cs != NULL && cs->sendingRs == NULL; }
ConnectionState *GetConnection() const { return cs; }
uint16_t GetLocalPort() const;
RequestStatus GetStatus() const { return status; }
private:
void Close();
void FreePbuf();
ConnectionState* cs;
RequestState* volatile next; // next RequestState in the list we are in
RequestState* nextWrite; // next RequestState queued to write to this cs
pbuf *pb; // linked list of incoming packet buffers
unsigned int bufferLength; // total length of the packet buffer
unsigned int inputPointer; // amount of data already taken from the first packet buffer
unsigned int sentDataOutstanding; // amount of TCP data we have sent that has not been acknowledged
SendBuffer *sendBuffer;
char *outputBuffer;
unsigned int unsentPointer;
unsigned int outputPointer;
FileStore *fileBeingSent;
RequestStatus status;
float lastWriteTime;
bool persistConnection;
bool closeRequested;
};
class SendBuffer
{
public:
friend class Network;
friend class RequestState;
SendBuffer(SendBuffer *n);
private:
char tcpOutputBuffer[tcpOutputBufferSize];
SendBuffer* volatile next;
};
// The main network class that drives the network.
class Network
{
public:
friend class RequestState;
void ReceiveInput(pbuf *pb, ConnectionState *cs);
void SentPacketAcknowledged(ConnectionState *cs, unsigned int len);
void ConnectionAccepted(ConnectionState *cs);
void ConnectionClosed(ConnectionState* cs);
void ConnectionClosedGracefully(ConnectionState *cs);
RequestState *GetRequest(const ConnectionState *cs = NULL);
void SendAndClose(FileStore *f, bool keepConnectionOpen = false);
void CloseRequest();
void RepeatRequest();
void OpenDataPort(uint16_t port);
bool CloseDataPort();
void SaveDataConnection();
void SaveFTPConnection();
void SaveTelnetConnection();
bool CanMakeRequest();
bool MakeDataRequest();
bool MakeFTPRequest();
bool MakeTelnetRequest(unsigned int dataLength);
Network();
void Init();
void Spin();
void Interrupt();
bool InLwip() const;
void ReadPacket();
private:
void AppendTransaction(RequestState* volatile * list, RequestState *r);
void PrependTransaction(RequestState* volatile * list, RequestState *r);
bool AllocateSendBuffer(SendBuffer *&buffer);
void FreeSendBuffer(SendBuffer *buffer);
bool MakeRequest(unsigned int requiredSpace, ConnectionState *cs);
RequestState * volatile freeTransactions;
RequestState * volatile readyTransactions;
RequestState * volatile writingTransactions;
enum { NetworkInactive, NetworkInitializing, NetworkActive } state;
bool volatile readingData;
ConnectionState *dataCs;
ConnectionState *ftpCs;
ConnectionState *telnetCs;
SendBuffer * volatile sendBuffer;
};
#endif