diff --git a/examples/Server/Server.ino b/examples/Server/Server.ino index 76a4080..be97177 100644 --- a/examples/Server/Server.ino +++ b/examples/Server/Server.ino @@ -11,7 +11,8 @@ byte ip[] = {192, 168, 254, 254}; // IP-адрес сервер uint8_t gateway[] = {192, 168, 0, 1}; // Шлюз uint8_t subnet[] = {255, 255, 0, 0}; // Маска подсети -EthernetMaketServer server(SERVER_PORT); // Создаем сервер на указанном порту +// EthernetMaketServer server(SERVER_PORT); // Создаем сервер на указанном порту +W5500Server server(0, SERVER_PORT); unsigned long previousMillis = 0; // Время последней отправки const long interval = 1750; // Интервал отправки данных (1.75 секунды) @@ -28,6 +29,7 @@ void serverHandler(EthernetClient client) Serial.print("sock: "); Serial.println(client.getSocketNumber()); processReceivedData(buf, len); + // // Обработка каждого 4-байтового пакета // for (int i = 0; i < len; i += 4) @@ -51,7 +53,6 @@ void serverHandler(EthernetClient client) void setup() { Serial.begin(115200); - // Инициализация SPI и Ethernet SPI.begin(); pinMode(W5500_CS_PIN, OUTPUT); @@ -59,13 +60,15 @@ void setup() digitalWrite(W5500_CS_PIN, HIGH); // Инициализация Ethernet + w5500.softReset(); Ethernet.setCsPin(W5500_CS_PIN); // Установка пина CS для W5500 Ethernet.init(); Ethernet.begin(mac, ip, subnet, gateway, gateway); // Запуск сервера server.begin(); - server.setServerHandler(serverHandler); + server.enableCloseOnTimeout(false); + // server.setServerHandler(serverHandler); Serial.print("Server is running at "); Serial.println(Ethernet.localIP()); } @@ -75,6 +78,23 @@ void loop() server.tick(); uint32_t currentMillis = millis(); + if(Serial.available()){ + uint8_t in = Serial.read(); + switch (in) + { + case 's': + // server.printSocketsState(); + printSocketsState(); + break; + case 'b': + // server.begin(7); + break; + + default: + break; + } + } + if (currentMillis - ttt > 75) { digitalToggle(PC13); @@ -123,3 +143,35 @@ volatile void sendResponse(EthernetClient &client, uint32_t packetCount) } Serial.println(); } + +void printSocketsState(){ + // if(s.length() > 0) + // Serial.println(s); + for (int i = 0; i < MAX_SOCK_NUM; i++) { + uint8_t s = w5500.readSnSR(i); + String state = ""; + switch (s) { + case 0x00: state = "CLOSED"; break; + case 0x13: state = "INIT"; break; + case 0x14: state = "LISTEN"; break; + case 0x15: state = "SYNSENT"; break; + case 0x16: state = "SYNRECV"; break; + case 0x17: state = "ESTABLISHED"; break; + case 0x18: state = "FIN_WAIT"; break; + case 0x1A: state = "CLOSING"; break; + case 0x1B: state = "TIME_WAIT"; break; + case 0x1C: state = "CLOSE_WAIT"; break; + case 0x1D: state = "LAST_ACK"; break; + case 0x22: state = "UDP"; break; + case 0x32: state = "IPRAW"; break; + case 0x42: state = "MACRAW"; break; + case 0x5F: state = "PPPOE"; break; + default: state = "UNKNOWN"; break; + } + delay(1); + Serial.print("SOCK <- "); + Serial.print(i); + Serial.print(" State: "); + Serial.println(state); + } +} \ No newline at end of file diff --git a/src/EthernetOverride/Server.cpp b/src/EthernetOverride/Server.cpp deleted file mode 100644 index c57708e..0000000 --- a/src/EthernetOverride/Server.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#include "Server.h" -#include "utility/w5500.h" -#include "utility/socket.h" - -void EthernetMaketServer::setServerHandler(std::function handler) -{ - serverHandler = handler; -} - -void EthernetMaketServer::resetServerHandler() -{ - serverHandler = [](EthernetMaketClient sclient) {}; -} - -// EthernetMaketClient EthernetMaketServer::available(int sock) -// { -// accept(sock); -// EthernetClient client(sock); -// if (EthernetClass::_server_port[sock] == _port && -// (client.status() == SnSR::ESTABLISHED || -// client.status() == SnSR::CLOSE_WAIT)) -// { -// if (client.available()) -// { -// return std::move(EthernetMaketClient(client)); -// } -// } -// return std::move(EthernetMaketClient(MAX_SOCK_NUM)); -// } - -// void EthernetMaketServer::accept(int sock) -// { -// int listening = 0; -// EthernetClient client(sock); - -// if (EthernetClass::_server_port[sock] == _port) -// { -// if (client.status() == SnSR::LISTEN) -// { -// listening = 1; -// } -// else if (client.status() == SnSR::CLOSE_WAIT && !client.available()) -// { -// Serial.println("HARD STOP"); -// client.stop(); -// } -// } - -// if (!listening) -// { -// // begin(); -// begin(sock); // added -// } -// } - -// void EthernetMaketServer::begin(int sock) -// { -// EthernetClient client(sock); -// if (client.status() == SnSR::CLOSED) -// { -// socket(sock, SnMR::TCP, _port, 0); -// listen(sock); -// EthernetClass::_server_port[sock] = _port; -// serverSocket = sock; -// return; -// } -// // Serial.println(F("EthernetMaketServer::begin() FAIL")); -// } - -// void EthernetMaketServer::begin() -// { -// for (int sock = 0; sock < MAX_SOCK_NUM; sock++) { -// EthernetClient client(sock); -// if (client.status() == SnSR::CLOSED) { -// socket(sock, SnMR::TCP, _port, 0); -// listen(sock); -// EthernetClass::_server_port[sock] = _port; -// serverSocket = sock; -// break; -// } -// } -// // Serial.println(F("EthernetMaketServer::begin() FAIL")); -// } -uint8_t buf[256]; -void EthernetMaketServer::tick() -{ - // for (int sock = 0; sock < MAX_SOCK_NUM; sock++) - { - EthernetClient sclient = available(/* serverSocket */); - size_t dataSize; - if (sclient.connected() && (dataSize = sclient.available()) > 0) - { - // Serial.println("Receive!"); - - // memset(buf,0x00,sizeof(buf)); - // sclient.read(buf, sizeof(buf)); - - // Serial.print("Received data: "); - // for (int i = 0; i < dataSize; i++) - // { - // Serial.print(buf[i], HEX); - // Serial.print(" "); - // } - // Serial.println("\n"); - - // sclient.activityUpdate(); - serverHandler(EthernetMaketClient(sclient)); - } - - - - - // if (!wasConnected && sclient.connected()) - // { - // wasConnected = true; - // Serial.println("Client connected"); - // } - - // if (wasConnected && !sclient.connected()) - // { - // wasConnected = false; - // sclient.stop(); - // // begin(serverSocket); - // Serial.println("Client disconnected"); - // } - // // Закрытие соединения по таймеру неактивности - // if (sclient.connected() && (millis() - lastActivityTime > timeout)) - // { - // Serial.println("Connection closed due to inactivity"); - // sclient.close(); - // // begin(serverSocket); - // } - } - // sclient.tick_(); -} diff --git a/src/EthernetOverride/Server.cpp0 b/src/EthernetOverride/Server.cpp0 new file mode 100644 index 0000000..4ec8779 --- /dev/null +++ b/src/EthernetOverride/Server.cpp0 @@ -0,0 +1,176 @@ +#include "Server.h" +#include "utility/w5500.h" +#include "utility/socket.h" + +EthernetMaketServer::EthernetMaketServer(uint16_t port): port(port){}; + +void EthernetMaketServer::setServerHandler(std::function handler) +{ + serverHandler = handler; +} + +void EthernetMaketServer::resetServerHandler() +{ + serverHandler = [](EthernetMaketClient sclient) {}; +} + +EthernetMaketClient EthernetMaketServer::available(int sock) +{ + accept(sock); + EthernetClient client(6); + if (EthernetClass::_server_port[sock] == port && + (client.status() == SnSR::ESTABLISHED || + client.status() == SnSR::CLOSE_WAIT)) + { + if (client.available()) + { + return std::move(EthernetMaketClient(client)); + } + } + return std::move(EthernetMaketClient(MAX_SOCK_NUM)); +} + +void EthernetMaketServer::accept(int sock) +{ + int listening = 0; + EthernetClient client(sock); + + if (EthernetClass::_server_port[sock] == port) + { + if (client.status() == SnSR::LISTEN) + { + listening = 1; + } + else if (client.status() == SnSR::CLOSE_WAIT && !client.available()) + { + Serial.println("HARD STOP"); + client.stop(); + } + } + + if (!listening) + { + // begin(); + + // begin(sock); // added + } +} + +void EthernetMaketServer::begin(int sock) +{ + EthernetClient client(sock); + if (client.status() == SnSR::CLOSED) + { + socket(sock, SnMR::TCP, port, 0); + listen(sock); + EthernetClass::_server_port[sock] = port; + serverSocket = sock; + return; + } + // Serial.println(F("EthernetMaketServer::begin() FAIL")); +} + +void EthernetMaketServer::tick() +{ + + switch (serverStatus) + { + // case CLOSED: + // begin(??); + // break; + + // case LISTEN: + // begin(??); + // break; + + default: + break; + } + + + + + + // for (int sock = 0; sock < MAX_SOCK_NUM; sock++) + // { + + EthernetClient sclient = available(7); + size_t dataSize; + if (sclient.connected() && (dataSize = sclient.available()) > 0) + { + // Serial.println("Receive!"); + + // memset(buf,0x00,sizeof(buf)); + // sclient.read(buf, sizeof(buf)); + + // Serial.print("Received data: "); + // for (int i = 0; i < dataSize; i++) + // { + // Serial.print(buf[i], HEX); + // Serial.print(" "); + // } + // Serial.println("\n"); + + // sclient.activityUpdate(); + printSocketsState("sclient.available()"); + serverHandler(EthernetMaketClient(sclient)); + } + + + + + // if (!wasConnected && sclient.connected()) + // { + // wasConnected = true; + // Serial.println("Client connected"); + // } + + // if (wasConnected && !sclient.connected()) + // { + // wasConnected = false; + // sclient.stop(); + // // begin(serverSocket); + // Serial.println("Client disconnected"); + // } + // // Закрытие соединения по таймеру неактивности + // if (sclient.connected() && (millis() - lastActivityTime > timeout)) + // { + // Serial.println("Connection closed due to inactivity"); + // sclient.close(); + // // begin(serverSocket); + // } + // } + // sclient.tick_(); +} + +void EthernetMaketServer::printSocketsState(String s){ + if(s.length() > 0) + Serial.println(s); + for (int i = 0; i < MAX_SOCK_NUM; i++) { + uint8_t s = w5500.readSnSR(i); + String state = ""; + switch (s) { + case 0x00: state = "CLOSED"; break; + case 0x13: state = "INIT"; break; + case 0x14: state = "LISTEN"; break; + case 0x15: state = "SYNSENT"; break; + case 0x16: state = "SYNRECV"; break; + case 0x17: state = "ESTABLISHED"; break; + case 0x18: state = "FIN_WAIT"; break; + case 0x1A: state = "CLOSING"; break; + case 0x1B: state = "TIME_WAIT"; break; + case 0x1C: state = "CLOSE_WAIT"; break; + case 0x1D: state = "LAST_ACK"; break; + case 0x22: state = "UDP"; break; + case 0x32: state = "IPRAW"; break; + case 0x42: state = "MACRAW"; break; + case 0x5F: state = "PPPOE"; break; + default: state = "UNKNOWN"; break; + } + + Serial.print("SOCK <- "); + Serial.print(i); + Serial.print(" State: "); + Serial.println(state); + } +} diff --git a/src/EthernetOverride/Server.h b/src/EthernetOverride/Server.h index 4869075..5201f20 100644 --- a/src/EthernetOverride/Server.h +++ b/src/EthernetOverride/Server.h @@ -1,30 +1,219 @@ -#ifndef __MAKET_SERVER_H__ -#define __MAKET_SERVER_H__ - +#ifndef __SERVER_H__ +#define __SERVER_H__ #include "../util/config.h" -#include "TCP.h" -#include -class EthernetMaketClient; -class EthernetMaketServer : public EthernetServer -{ -private: - // EthernetClient available(); - // void accept(int sock); - std::function serverHandler = [](EthernetMaketClient sclient) {}; - SOCKET serverSocket = MAX_SOCK_NUM; - - bool wasConnected; - // EthernetMaketClient sclient; +#include "utility/socket.h" +#include "utility/w5500.h" +class IServerCallbacks { public: - using EthernetServer::EthernetServer; - // EthernetMaketClient available(int sock); - - void setServerHandler(std::function handler); - void resetServerHandler(); - // void begin() override; - // void begin(int sock); - void tick(); + virtual void onClosed() = 0; + virtual void onListen() = 0; + virtual void onEstablished() = 0; + virtual void onCloseWait() = 0; + virtual void onInit() = 0; + virtual void onSynSent() = 0; + virtual void onSynRecv() = 0; + virtual void onFinWait() = 0; + virtual void onClosing() = 0; + virtual void onTimeWait() = 0; + virtual void onLastAck() = 0; }; -#endif // __MAKET_SERVER_H__ +class W5500Server : public IServerCallbacks { +private: + SOCKET socketId; // Номер сокета, используемого сервером + uint16_t port; // Порт, на котором сервер слушает + uint16_t timeout; // Таймаут ожидания (мс) + uint8_t maxRetries; // Количество попыток отправки + + bool closeOnTimeout; // Флаг отключения по таймауту + unsigned long lastActivityTime; // Время последней активности + uint32_t inactivityTimeout; // Таймаут неактивности (мс) + + uint8_t lastStatus; // Последний статус сокета + +public: + W5500Server(SOCKET socketId, uint16_t port, uint16_t timeout = 2000, uint8_t maxRetries = 3, uint32_t inactivityTimeout = 500) + : socketId(socketId), port(port), timeout(timeout), maxRetries(maxRetries), closeOnTimeout(true), inactivityTimeout(inactivityTimeout), lastStatus(0) { + lastActivityTime = millis(); + } + + void begin() { + // Настройка сокета + socket(socketId, SnMR::TCP, port, 0); + setRetransmissionParams(timeout, maxRetries); + listen(socketId); + } + + void tick() { + uint8_t currentStatus = w5500.readSnSR(socketId); + + if (currentStatus != lastStatus) { + lastStatus = currentStatus; + switch (currentStatus) { + case SnSR::CLOSED: + onClosed(); + break; + + case SnSR::LISTEN: + onListen(); + break; + + case SnSR::ESTABLISHED: + onEstablished(); + break; + + case SnSR::CLOSE_WAIT: + onCloseWait(); + break; + + case SnSR::INIT: + onInit(); + break; + + case SnSR::SYNSENT: + onSynSent(); + break; + + case SnSR::SYNRECV: + onSynRecv(); + break; + + case SnSR::FIN_WAIT: + onFinWait(); + break; + + case SnSR::CLOSING: + onClosing(); + break; + + case SnSR::TIME_WAIT: + onTimeWait(); + break; + + case SnSR::LAST_ACK: + onLastAck(); + break; + + default: + break; + } + } + + if (closeOnTimeout && currentStatus == SnSR::ESTABLISHED && millis() - lastActivityTime > inactivityTimeout) { + // Закрываем соединение по таймауту неактивности + Serial.println("Connection closed due to inactivity"); + disconnect(socketId); + close(socketId); + return; + } + + if (currentStatus == SnSR::ESTABLISHED) { + handleClient(); + } + } + + void setInactivityTimeout(uint32_t timeout) { + inactivityTimeout = timeout; + } + + void enableCloseOnTimeout(bool enable) { + closeOnTimeout = enable; + } + + // Реализация интерфейса IServerCallbacks + void onClosed() override { + Serial.println("STAT = CLOSED\n"); + begin(); + } + + void onListen() override { + Serial.println("STAT = LISTEN"); + } + + void onEstablished() override { + Serial.println("STAT = ESTABLISHED"); + lastActivityTime = millis(); // Сбрасываем таймер + } + + void onCloseWait() override { + Serial.println("STAT = CLOSE_WAIT"); + disconnect(socketId); + close(socketId); + } + + void onInit() override { + Serial.println("STAT = INIT"); + } + + void onSynSent() override { + Serial.println("STAT = SYNSENT"); + } + + void onSynRecv() override { + Serial.println("STAT = SYNRECV"); + } + + void onFinWait() override { + Serial.println("STAT = FIN_WAIT"); + } + + void onClosing() override { + Serial.println("STAT = CLOSING"); + } + + void onTimeWait() override { + Serial.println("STAT = TIME_WAIT"); + } + + void onLastAck() override { + Serial.println("STAT = LAST_ACK"); + } + +private: + void handleClient() { + // Проверяем, есть ли данные для чтения + uint16_t size = w5500.getRXReceivedSize(socketId); + if (size > 0) { + lastActivityTime = millis(); // Сбрасываем таймер по активности + + uint8_t buffer[size]; + recv(socketId, buffer, size); + + // Вывод данных в шестнадцатеричном формате + Serial.println("Received (hex):"); + for (uint16_t i = 0; i < size; i++) { + Serial.print(buffer[i], HEX); + Serial.print(" "); + if ((i + 1) % 8 == 0) Serial.print(" "); // Разделение каждые 8 байт + if ((i + 1) % 16 == 0) Serial.println(); // Разделение на строки по 16 байт + } + Serial.println(); + + // Отправка ответа (если требуется) + const char *response = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nHello, Client!"; + sendData((uint8_t *)response, strlen(response)); + lastActivityTime = millis(); // Сбрасываем таймер по активности + } + } + + void sendData(uint8_t *data, uint16_t size) { + while (size > 0) { + uint16_t freeSpace = w5500.getTXFreeSize(socketId); + if (freeSpace > 0) { + uint16_t chunk = size < freeSpace ? size : freeSpace; + send(socketId, data, chunk); + data += chunk; + size -= chunk; + lastActivityTime = millis(); // Сбрасываем таймер по активности + } + } + } + + void setRetransmissionParams(uint16_t timeout, uint8_t retries) { + w5500.setRetransmissionTime(timeout); + w5500.setRetransmissionCount(retries); + } +}; + +#endif // __SERVER_H__ diff --git a/src/EthernetOverride/Server0.h b/src/EthernetOverride/Server0.h new file mode 100644 index 0000000..2e7346b --- /dev/null +++ b/src/EthernetOverride/Server0.h @@ -0,0 +1,36 @@ +#ifndef __MAKET_SERVER_H__ +#define __MAKET_SERVER_H__ + +#include "../util/config.h" +#include "TCP.h" +#include +class EthernetMaketClient; +class EthernetMaketServer /* : public EthernetServer */ +{ + +protected: + uint16_t port; + void accept(int sock); + std::function serverHandler = [](EthernetMaketClient sclient) {}; + SOCKET serverSocket = MAX_SOCK_NUM; + + // bool wasConnected; + // EthernetMaketClient sclient; + +public: + // using EthernetServer::EthernetServer; + + EthernetMaketServer(uint16_t); + + EthernetMaketClient available(int sock); + + void setServerHandler(std::function handler); + void resetServerHandler(); + // void begin() override; + void begin(int sock); + void tick(); + + void printSocketsState(String s = ""); +}; + +#endif // __MAKET_SERVER_H__ diff --git a/src/EthernetOverride/TCP.cpp b/src/EthernetOverride/TCP.cpp index ed7bfed..f95491e 100644 --- a/src/EthernetOverride/TCP.cpp +++ b/src/EthernetOverride/TCP.cpp @@ -227,12 +227,12 @@ void EthernetMaketClient::tick_(){ } // Закрытие соединения по таймеру неактивности - if (connected() && (millis() - lastActivityTime > timeout)) - { - Serial.println("Connection closed due to inactivity"); - connectStatus = CONNECT_STOP_START; - goto switchLabel; - } + // if (connected() && (millis() - lastActivityTime > timeout)) + // { + // Serial.println("Connection closed due to inactivity"); + // connectStatus = CONNECT_STOP_START; + // goto switchLabel; + // } break; case CONNECT_STOP_START: